1 ; SCCSID = @(#)macro.asm 1.2 85/07/11
2 TITLE
MACRO - Pathname
and macro related internal routines
11 ; GetCDSFromDrv written
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
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.
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.
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.
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.
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
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)
59 ; curdir_end DW ? ; end of assignment
61 ; curdir_netID EQU DWORD PTR curdir_ID
63 ; curdir_isnet EQU 1000000000000000B
64 ; curdir_inuse EQU 0100000000000000B
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
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
77 ; A: -> d: /path/ path/ text
79 ; A000 version 4.00 Jan. 1988
83 ; get the appropriate segment definitions
87 CODE SEGMENT BYTE PUBLIC 'CODE'
88 ASSUME
SS:DOSGroup
,CS:DOSGroup
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
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
114 BREAK <$AssignOper
-- Set up a
Macro>
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)
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,,,
140 ; Std Xenix style error return
142 procedure $AssignOper
,NEAR
143 ASSUME
DS:NOTHING
,ES:NOTHING
145 CMP AL,7 ; set in_use ? ;AN000;
146 JNZ chk08
; no ;AN000;
148 PUSH AX ; save al ;AN000;
149 MOV AL,DL ; AL= drive id ;AN000;
150 CALL GetCDSFromDrv
; ds:si -> cds ;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;
160 AND [SI.curdir_flags
],NOT curdir_inuse
; reset in_use ;AN000;
161 JMP SHORT okdone
; ;AN000;
163 MOV AX,error_invalid_drive
; error ;AN000;
164 JMP SHORT ASS_ERR
; ;AN000;
166 CMP AL,8 ; reset inuse ? ;AN000;
167 JZ srinuse
; yes ;AN000;
173 MOV AX,(multnet
SHL 8) OR 30
175 POP BX ; Don't zap error code in AX
186 Break <FIND_DPB
- Find a DPB
from a drive number
>
188 ; Inputs: AL has drive number A = 0
190 ; No DPB for this drive number
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
200 CMP AL,[SI.dpb_drive
]
202 LDS SI,[SI.dpb_next_dpb
]
210 Break <InitCDS
- set up an empty CDS
>
212 ; Inputs: ThisCDS points to CDS
213 ; AL has uppercase drive letter
214 ; Outputs: ThisCDS is now empty
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
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
231 MOV WORD PTR ES:[DI.curdir_text+2],AX ; NUL terminate
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
242 JC PRET ; OOOOPPPPPSSSS!!!!
243 MOV WORD PTR ES:[DI.curdir_devptr],SI
244 MOV WORD PTR ES:[DI.curdir_devptr+2],DS
252 Break <$UserOper - get/set current user ID (for net)>
255 ; $UserOper - retrieve or initiate a user id string. MSDOS will only
256 ; maintain this string and do no verifications.
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
270 Procedure $UserOper,NEAR
271 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
273 SUB AL,1 ; quick dispatch on 0,1
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
279 MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus
280 error error_Invalid_Function ; not 0,1,2,3
283 ; Transfer MYNAME to DS:DX
284 ; Set Return CX to MYNUM
285 PUSH DS ; switch registers
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
293 MOV SI,OFFSET DOSGroup:MyName ; point source to user string
298 XOR AX,AX ; 16th byte is 0
301 transfer sys_ret_ok ; no errors here
305 ; Transfer DS:DX to MYNAME
308 MOV SI,DX ; user space has source
310 MOV DI,OFFSET DOSGroup:MyName ; point dest to user string
311 INC [DiffNam] ; signal change
317 transfer PRINTER_GETSET_STRING
320 MOV AX,(multNET SHL 8) OR 31
332 Break <GetVisDrv - return visible drive>
335 ; GetVisDrv - correctly map non-spliced inuse drives
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
343 Procedure GetVisDrv,NEAR
344 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
345 CALL GetThisDrv ; get inuse drive
349 TEST [SI].curdir_flags,curdir_splice
351 retz ; if not spliced, return OK
352 MOV [DrvErr],error_invalid_drive ;IFS. ;AN000;
357 Break <Getthisdrv - map a drive designator (0=def, 1=A...)>
360 ; GetThisDrv - look through a set of macros and return the current drive and
363 ; Inputs: AL has drive identifier (1=A, 0=default)
365 ; Carry Set - invalid drive/macro
366 ; Carry Clear - AL has physical drive (0=A)
367 ; ThisCDS points to macro
368 ; Registers modified: AL
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
378 SaveReg <DS,SI> ; save world
379 mov [EXTERR_LOCUS],errLOC_Disk
380 TEST fSharing,-1 ; Logical or Physical?
381 JZ Not_SRVC ; Logical
383 MOV WORD PTR ThisCDS,OFFSET DOSGroup:DummyCDS
384 MOV WORD PTR ThisCDS+2,CS ; ThisCDS = &DummyCDS;
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
394 JC GetBerr2 ; Unassigned CDS -> return error already set
395 TEST [SI.curdir_flags],curdir_inuse ; Clears Carry
396 JNZ GetBye ; carry clear
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
402 MOV AL,error_invalid_drive ;AN000;;IFS. invalid FAT drive
404 MOV [DrvErr],AL ;AN000;;IFS. save this for IOCTL
405 mov [EXTERR_LOCUS],errLOC_UNK
407 GetBye: RestoreReg <SI,DS> ; restore world
411 Break <GetCDSFromDrv - convert a drive number to a CDS pointer>
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
418 ; Inputs: AL is physical unit # A=0...
419 ; Outputs: Carry Set if Bad Drive
423 ; Registers modified: DS,SI
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
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
442 EndProc GetCDSFromDrv