]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/MACRO.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / MACRO.ASM
1 ; SCCSID = @(#)macro.asm 1.2 85/07/11
2 TITLE MACRO - Pathname and macro related internal routines
3 NAME MACRO
4 ;
5 ; $AssignOper written
6 ; FIND_DPB written
7 ; InitCDS written
8 ; $UserOper written
9 ; GetVisDrv written
10 ; GetThisDrv written
11 ; GetCDSFromDrv written
12 ;
13 ; Revision history:
14 ;
15 ; Created: MZ 4 April 1983
16 ; MZ 18 April 1983 Make TransFCB handle extended FCBs
17 ; AR 2 June 1983 Define/Delete macro for NET redir.
18 ; MZ 3 Nov 83 Fix InitCDS to reset length to 2
19 ; MZ 4 Nov 83 Fix NetAssign to use STRLEN only
20 ; MZ 18 Nov 83 Rewrite string processing for subtree
21 ; aliasing.
22 ;
23 ; MSDOS performs several types of name translation. First, we maintain for
24 ; each valid drive letter the text of the current directory on that drive.
25 ; For invalid drive letters, there is no current directory so we pretend to
26 ; be at the root. A current directory is either the raw local directory
27 ; (consisting of drive:\path) or a local network directory (consisting of
28 ; \\machine\path. There is a limit on the point to which a .. is allowed.
29 ;
30 ; Given a path, MSDOS will transform this into a real from-the-root path
31 ; without . or .. entries. Any component that is > 8.3 is truncated to
32 ; this and all * are expanded into ?'s.
33 ;
34 ; The second part of name translation involves subtree aliasing. A list of
35 ; subtree pairs is maintained by the external utility SUBST. The results of
36 ; the previous 'canonicalization' are then examined to see if any of the
37 ; subtree pairs is a prefix of the user path. If so, then this prefix is
38 ; replaced with the other subtree in the pair.
39 ;
40 ; A third part involves mapping this "real" path into a "physical" path. A
41 ; list of drive/subtree pairs are maintained by the external utility JOIN.
42 ; The output of the previous translation is examined to see if any of the
43 ; subtrees in this list are a prefix of the string. If so, then the prefix
44 ; is replaced by the appropriate drive letter. In this manner, we can
45 ; 'mount' one device under another.
46 ;
47 ; The final form of name translation involves the mapping of a user's
48 ; logical drive number into the internal physical drive. This is
49 ; accomplished by converting the drive number into letter:CON, performing
50 ; the above translation and then converting the character back into a drive
51 ; number.
52 ;
53 ; curdir_list STRUC
54 ; curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir
55 ; curdir_flags DW ? ; various flags
56 ; curdir_devptr DD ? ; local pointer to DPB or net device
57 ; curdir_ID DW ? ; cluster of current dir (net ID)
58 ; DW ?
59 ; curdir_end DW ? ; end of assignment
60 ; curdir_list ENDS
61 ; curdir_netID EQU DWORD PTR curdir_ID
62 ; ;Flag word masks
63 ; curdir_isnet EQU 1000000000000000B
64 ; curdir_inuse EQU 0100000000000000B
65 ;
66 ; There are two main entry points: TransPath and TransFCB. TransPath will
67 ; take a path and form the real text of the pathname with all . and ..
68 ; removed. TransFCB will translate an FCB into a path and then invoke
69 ; TransPath.
70 ;
71 ; Implementation note: CURDIR_End field points to the point in the text
72 ; string where the user may back up to via .. It is the location of a
73 ; separator character. For the root, it points at the leading /. For net
74 ; assignments it points at the end (nul) of the initial assignment:
75 ; A:/ \\foo\bar \\foo\bar\blech\bozo
76 ; ^ ^ ^
77 ; A: -> d: /path/ path/ text
78 ;
79 ; A000 version 4.00 Jan. 1988
80
81 .xlist
82 ;
83 ; get the appropriate segment definitions
84 ;
85 include dosseg.asm
86
87 CODE SEGMENT BYTE PUBLIC 'CODE'
88 ASSUME SS:DOSGroup,CS:DOSGroup
89
90 .xcref
91 INCLUDE DOSSYM.INC
92 INCLUDE DEVSYM.INC
93 .cref
94 .list
95 .sall
96
97 Installed = TRUE
98
99 I_need ThisCDS,DWORD ; pointer to CDS used
100 I_need CDSAddr,DWORD ; pointer to CDS table
101 I_need CDSCount,BYTE ; number of CDS entries
102 I_need CurDrv,BYTE ; current macro assignment (old
103 ; current drive)
104 I_need NUMIO,BYTE ; Number of physical drives
105 I_need fSharing,BYTE ; TRUE => no redirection allowed
106 I_need DummyCDS,80h ; buffer for dummy cds
107 I_need DIFFNAM,BYTE ; flag for MyName being set
108 I_need MYNAME,16 ; machine name
109 I_need MYNUM,WORD ; machine number
110 I_need DPBHEAD,DWORD ; beginning of DPB chain
111 I_need EXTERR_LOCUS,BYTE ; Extended Error Locus
112 I_need DrvErr,BYTE ; drive error
113
114 BREAK <$AssignOper -- Set up a Macro>
115
116 ; Inputs:
117 ; AL = 00 get assign mode (ReturnMode)
118 ; AL = 01 set assign mode (SetMode)
119 ; AL = 02 get attach list entry (GetAsgList)
120 ; AL = 03 Define Macro (attch start)
121 ; BL = Macro type
122 ; = 0 alias
123 ; = 1 file/device
124 ; = 2 drive
125 ; = 3 Char device -> network
126 ; = 4 File device -> network
127 ; DS:SI -> ASCIZ source name
128 ; ES:DI -> ASCIZ destination name
129 ; AL = 04 Cancel Macro
130 ; DS:SI -> ASCIZ source name
131 ; AL = 05 Modified get attach list entry
132 ; AL = 06 Get ifsfunc item
133 ; AL = 07 set in_use of a drive's CDS
134 ; DL = drive number, 0=default 0=A,,
135 ; AL = 08 reset in_use of a drive's CDS
136 ; DL = drive number, 0=A, 1=B,,,
137 ; Function:
138 ; Do macro stuff
139 ; Returns:
140 ; Std Xenix style error return
141
142 procedure $AssignOper,NEAR
143 ASSUME DS:NOTHING,ES:NOTHING
144
145 CMP AL,7 ; set in_use ? ;AN000;
146 JNZ chk08 ; no ;AN000;
147 srinuse: ;AN000;
148 PUSH AX ; save al ;AN000;
149 MOV AL,DL ; AL= drive id ;AN000;
150 CALL GetCDSFromDrv ; ds:si -> cds ;AN000;
151 POP AX ; ;AN000;
152 JC baddrv ; bad drive ;AN000;
153 CMP WORD PTR [SI.curdir_devptr],0 ; dpb ptr =0 ? ;AN000;
154 JZ baddrv ; no ;AN000;
155 CMP AL,7 ; set ? ;AN000;
156 JNZ resetdrv ; no ;AN000;
157 OR [SI.curdir_flags],curdir_inuse ; set in_use ;AN000;
158 JMP SHORT okdone ; ;AN000;
159 resetdrv: ;AN000;
160 AND [SI.curdir_flags],NOT curdir_inuse ; reset in_use ;AN000;
161 JMP SHORT okdone ; ;AN000;
162 baddrv: ;AN000;
163 MOV AX,error_invalid_drive ; error ;AN000;
164 JMP SHORT ASS_ERR ; ;AN000;
165 chk08: ;AN000;
166 CMP AL,8 ; reset inuse ? ;AN000;
167 JZ srinuse ; yes ;AN000;
168
169 IF NOT INSTALLED
170 transfer NET_ASSOPER
171 ELSE
172 PUSH AX
173 MOV AX,(multnet SHL 8) OR 30
174 INT 2FH
175 POP BX ; Don't zap error code in AX
176 JC ASS_ERR
177 okdone:
178 transfer SYS_RET_OK
179
180 ASS_ERR:
181 transfer SYS_RET_ERR
182 ENDIF
183
184 EndProc $AssignOper
185
186 Break <FIND_DPB - Find a DPB from a drive number>
187
188 ; Inputs: AL has drive number A = 0
189 ; Outputs: Carry Set
190 ; No DPB for this drive number
191 ; Carry Clear
192 ; DS:SI points to DPB for drive
193 ; registers modified: DS,SI
194 Procedure FIND_DPB,NEAR
195 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
196 LDS SI,[DPBHEAD]
197 DPB_LOOP:
198 CMP SI,-1
199 JZ NO_DPB
200 CMP AL,[SI.dpb_drive]
201 retz ; Carry clear
202 LDS SI,[SI.dpb_next_dpb]
203 JMP DPB_LOOP
204
205 NO_DPB:
206 STC
207 return
208 EndProc FIND_DPB
209
210 Break <InitCDS - set up an empty CDS>
211
212 ; Inputs: ThisCDS points to CDS
213 ; AL has uppercase drive letter
214 ; Outputs: ThisCDS is now empty
215 ; ES:DI point to CDS
216 ; Carry set if no DPB associated with drive
217 ; registers modified: AH,ES,DI
218 Procedure InitCDS,NEAR
219 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
220 MOV AH,':'
221 PUSH AX
222 SUB AL,"A"-1 ; A = 1
223 CMP [NUMIO],AL
224 POP AX
225 LES DI,[THISCDS]
226 MOV ES:[DI.curdir_flags],0 ; "free" CDS
227 JB RET_OK ; Drive does not map a physical drive
228 MOV WORD PTR ES:[DI.curdir_text],AX
229 PUSH AX
230 MOV AX,"\"
231 MOV WORD PTR ES:[DI.curdir_text+2],AX ; NUL terminate
232 POP AX
233 OR ES:[DI.curdir_flags],curdir_inuse
234 MOV ES:[DI.curdir_END],2 ; MZ 3 Nov 83
235 MOV ES:[DI.curdir_ID],0
236 MOV ES:[DI.curdir_ID+2],0
237 PUSH AX
238 PUSH DS
239 PUSH SI
240 SUB AL,"A" ; A = 0
241 invoke FIND_DPB
242 JC PRET ; OOOOPPPPPSSSS!!!!
243 MOV WORD PTR ES:[DI.curdir_devptr],SI
244 MOV WORD PTR ES:[DI.curdir_devptr+2],DS
245 PRET:
246 POP SI
247 POP DS
248 POP AX
249 RET_OK: return
250 EndProc InitCDS
251
252 Break <$UserOper - get/set current user ID (for net)>
253
254 ;
255 ; $UserOper - retrieve or initiate a user id string. MSDOS will only
256 ; maintain this string and do no verifications.
257 ;
258 ; Inputs: AL has function type (0-get 1-set 2-printer-set 3-printer-get
259 ; 4-printer-set-flags,5-printer-get-flags)
260 ; DS:DX is user string pointer (calls 1,2)
261 ; ES:DI is user buffer (call 3)
262 ; BX is assign index (calls 2,3,4,5)
263 ; CX is user number (call 1)
264 ; DX is flag word (call 4)
265 ; Outputs: If AL = 0 then the current user string is written to DS:DX
266 ; and user CX is set to the user number
267 ; If AL = 3 then CX bytes have been put at input ES:DI
268 ; If AL = 5 then DX is flag word
269
270 Procedure $UserOper,NEAR
271 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
272 PUSH AX
273 SUB AL,1 ; quick dispatch on 0,1
274 POP AX
275 JB UserGet ; return to user the string
276 JZ UserSet ; set the current user
277 CMP AL,5 ; test for 2,3,4 or 5
278 JBE UserPrint ; yep
279 MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus
280 error error_Invalid_Function ; not 0,1,2,3
281
282 UserGet:
283 ; Transfer MYNAME to DS:DX
284 ; Set Return CX to MYNUM
285 PUSH DS ; switch registers
286 POP ES
287 MOV DI,DX ; destination
288 MOV CX,[MYNUM] ; Get number
289 invoke get_user_stack
290 MOV [SI.User_CX],CX ; Set number return
291 Context DS ; point to DOSGroup
292 ASSUME DS:DOSGROUP
293 MOV SI,OFFSET DOSGroup:MyName ; point source to user string
294 UserMove:
295 ASSUME DS:NOTHING
296 MOV CX,15
297 REP MOVSB ; blam.
298 XOR AX,AX ; 16th byte is 0
299 STOSB
300 UserBye:
301 transfer sys_ret_ok ; no errors here
302
303 UserSet:
304 ASSUME DS:NOTHING
305 ; Transfer DS:DX to MYNAME
306 ; CX to MYNUM
307 MOV [MYNUM],CX
308 MOV SI,DX ; user space has source
309 Context ES
310 MOV DI,OFFSET DOSGroup:MyName ; point dest to user string
311 INC [DiffNam] ; signal change
312 JMP UserMove
313
314 UserPrint:
315 ASSUME ES:NOTHING
316 IF NOT Installed
317 transfer PRINTER_GETSET_STRING
318 ELSE
319 PUSH AX
320 MOV AX,(multNET SHL 8) OR 31
321 INT 2FH
322 POP DX ; Clean stack
323 JNC OKPA
324 transfer SYS_RET_ERR
325
326 OKPA:
327 transfer SYS_RET_OK
328 ENDIF
329
330 EndProc $UserOper
331
332 Break <GetVisDrv - return visible drive>
333
334 ;
335 ; GetVisDrv - correctly map non-spliced inuse drives
336 ;
337 ; Inputs: AL has drive identifier (0=default)
338 ; Outputs: Carry Set - invalid drive/macro
339 ; Carry Clear - AL has physical drive (0=A)
340 ; ThisCDS points to CDS
341 ; Registers modified: AL
342
343 Procedure GetVisDrv,NEAR
344 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
345 CALL GetThisDrv ; get inuse drive
346 retc
347 SaveReg <DS,SI>
348 LDS SI,ThisCDS
349 TEST [SI].curdir_flags,curdir_splice
350 RestoreReg <SI,DS>
351 retz ; if not spliced, return OK
352 MOV [DrvErr],error_invalid_drive ;IFS. ;AN000;
353 STC ; signal error
354 return
355 EndProc GetVisDrv
356
357 Break <Getthisdrv - map a drive designator (0=def, 1=A...)>
358
359 ;
360 ; GetThisDrv - look through a set of macros and return the current drive and
361 ; macro pointer
362 ;
363 ; Inputs: AL has drive identifier (1=A, 0=default)
364 ; Outputs:
365 ; Carry Set - invalid drive/macro
366 ; Carry Clear - AL has physical drive (0=A)
367 ; ThisCDS points to macro
368 ; Registers modified: AL
369
370 Procedure GetThisDrv,NEAR
371 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
372 OR AL,AL ; are we using default drive?
373 JNZ GetMap ; no, go get the CDS pointers
374 MOV AL,[CurDrv] ; get the current drive
375 INC AL ; Counteract next instruction
376 GetMap:
377 DEC AL ; 0 = A
378 SaveReg <DS,SI> ; save world
379 mov [EXTERR_LOCUS],errLOC_Disk
380 TEST fSharing,-1 ; Logical or Physical?
381 JZ Not_SRVC ; Logical
382 SaveReg <AX,ES,DI>
383 MOV WORD PTR ThisCDS,OFFSET DOSGroup:DummyCDS
384 MOV WORD PTR ThisCDS+2,CS ; ThisCDS = &DummyCDS;
385 ADD AL,'A'
386 CALL InitCDS ; InitCDS(c);
387 TEST ES:[DI.curdir_flags],curdir_inuse ; Clears carry
388 RestoreReg <DI,ES,AX>
389 JZ GetBerr ; Not a physical drive.
390 JMP SHORT GetBye ; carry clear
391
392 Not_SRVC:
393 invoke GetCDSFromDrv
394 JC GetBerr2 ; Unassigned CDS -> return error already set
395 TEST [SI.curdir_flags],curdir_inuse ; Clears Carry
396 JNZ GetBye ; carry clear
397 GetBerr:
398 MOV AL,error_not_DOS_disk ;AN000;IFS. Formatted IFS drive
399 CMP WORD PTR [SI.curdir_devptr],0 ;AN000;IFS. dpb ptr =0 ?
400 JNZ notfat ;AN000;IFS. no
401 GetBerr2:
402 MOV AL,error_invalid_drive ;AN000;;IFS. invalid FAT drive
403 notfat: ;AN000;
404 MOV [DrvErr],AL ;AN000;;IFS. save this for IOCTL
405 mov [EXTERR_LOCUS],errLOC_UNK
406 STC
407 GetBye: RestoreReg <SI,DS> ; restore world
408 return
409 EndProc GetThisDrv
410
411 Break <GetCDSFromDrv - convert a drive number to a CDS pointer>
412
413 ;
414 ; GetCDSFromDrv - given a physical drive number, convert it to a CDS
415 ; pointer, returning an error if the drive number is greater than the
416 ; number of CDS's
417 ;
418 ; Inputs: AL is physical unit # A=0...
419 ; Outputs: Carry Set if Bad Drive
420 ; Carry Clear
421 ; DS:SI -> CDS
422 ; [THISCDS] = DS:SI
423 ; Registers modified: DS,SI
424
425 Procedure GetCDSFromDrv,NEAR
426 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
427 CMP AL,[CDSCount] ; is this a valid designator
428 JB GetCDS ; yes, go get the macro
429 STC ; signal error
430 return ; bye
431 GetCDS:
432 SaveReg <BX,AX>
433 LDS SI,[CDSAddr] ; get pointer to table
434 MOV BL,SIZE CurDir_list ; size in convenient spot
435 MUL BL ; get net offset
436 ADD SI,AX ; convert to true pointer
437 MOV WORD PTR [ThisCDS],SI ; store convenient offset
438 MOV WORD PTR [ThisCDS+2],DS ; store convenient segment
439 RestoreReg <AX,BX>
440 CLC ; no error
441 return ; bye!
442 EndProc GetCDSFromDrv
443
444 CODE ends
445 END