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

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / FILE.ASM
1 ; SCCSID = @(#)file.asm 1.2 85/07/23
2 ; SCCSID = @(#)file.asm 1.2 85/07/23
3 TITLE FILE - Pathname related system calls
4 NAME FILE
5
6 ;
7 ; Pathname related system calls. These will be passed direct text of the
8 ; pathname from the user. They will need to be passed through the macro
9 ; expander prior to being sent through the low-level stuff. I/O specs are
10 ; defined in DISPATCH. The system calls are:
11 ;
12 ; $Open written
13 ; $Creat written
14 ; $ChMod written
15 ; $Unlink written
16 ; $Rename written
17 ; $CreateTempFile written
18 ; $CreateNewFile written
19 ; $Extended_Open written DOS 4.00
20 ; GetIOParms written DOS 4.00
21 ;
22 ; Revision history:
23 ;
24 ; Created: MZ 4 April 1983
25 ; A000 version 4.00 Jan. 1988
26
27 .xlist
28 ;
29 ; get the appropriate segment definitions
30 ;
31 include dosseg.asm
32
33 CODE SEGMENT BYTE PUBLIC 'CODE'
34 ASSUME SS:DOSGroup,CS:DOSGroup
35
36 .xcref
37 include dossym.inc
38 include devsym.inc
39 include fastopen.inc
40 include EA.inc ;AN000;
41 include version.inc
42 .cref
43 .list
44 .sall
45
46 EXTRN DOS_OPEN:NEAR,DOS_CREATE:NEAR,DOS_Create_New:NEAR
47
48 IF NOT IBMCOPYRIGHT
49 extrn Set_EXT_mode:near
50 ENDIF
51
52 I_need WFP_Start,WORD ; pointer to beginning of expansion
53 I_Need ThisCDS,DWORD ; pointer to curdir in use
54 I_need ThisSft,DWORD ; SFT pointer for DOS_Open
55 I_need pJFN,DWORD ; temporary spot for pointer to JFN
56 I_need JFN,WORD ; word JFN for process
57 I_need SFN,WORD ; word SFN for process
58 I_Need OpenBuf,128 ; buffer for filename
59 I_Need RenBuf,128 ; buffer for filename in rename
60 I_need Sattrib,BYTE ; byte attribute to search for
61 I_need Ren_WFP,WORD ; pointer to real path
62 I_need cMeta,BYTE
63 I_need EXTERR,WORD ; extended error code
64 I_need EXTERR_LOCUS,BYTE ; Extended Error Locus
65 i_need JShare,DWORD ; share jump table
66 I_need fSharing,BYTE ; TRUE => via ServerDOSCall
67 I_need FastOpenTable,BYTE
68 I_need CPSWFLAG,BYTE ;AN000;FT. cpsw falg
69 I_need EXTOPEN_FLAG,WORD ;AN000;FT. extended file open flag
70 I_need EXTOPEN_ON,BYTE ;AN000;FT. extended open flag
71 I_need EXTOPEN_IO_MODE,WORD ;AN000;FT. IO mode
72 I_need XA_from,BYTE ;AN000;;FT. for get/set XA
73 I_need SAVE_ES,WORD ;AN000;;FT. for get/set XA
74 I_need SAVE_DI,WORD ;AN000;;FT. for get/set XA
75 I_need SAVE_DS,WORD ;AN000;;FT. for get/set XA
76 I_need SAVE_SI,WORD ;AN000;;FT. for get/set XA
77 I_need SAVE_DX,WORD ;AN000;;FT. for get/set XA
78 I_need SAVE_BX,WORD ;AN000;;FT. for get/set XA
79 I_need SAVE_CX,WORD ;AN000;;FT. for get/set XA
80 I_need NO_FILTER_DPATH,DWORD ;AN000;; pointer to original path of dest
81 I_need Temp_Var,WORD ;AN000;;
82 I_need DOS34_FLAG,WORD ;AN000;;
83 I_need Temp_Var2,WORD ;AN000;;
84 if debug
85 I_need BugLev,WORD
86 I_need BugTyp,WORD
87 include bugtyp.asm
88 endif
89
90 BREAK <$Open - open a file from a path string>
91
92 ;
93 ; $Open - given a path name in DS:DX and an open mode in AL, access the file
94 ; and return a handle
95 ; Inputs: DS:DX - pointer to asciz name
96 ; AL - open mode
97 ; Outputs: Carry Set - AX has error code for invalid open
98 ; Carry Clear - AX has per process handle number
99 ; Registers modified: most
100
101 Procedure $Open,NEAR
102 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
103 fmt TypSysCall,LevLog,<"Open\n">
104 fmt TypSysCall,LevArgs,<" Mode = $x file = '$S'\n">,<AX,DS,DX>
105 XOR AH,AH
106 Entry $Open2 ;AN000;
107 mov ch,attr_hidden+attr_system+attr_directory
108 call SetAttrib
109 MOV CX,OFFSET DOSGroup:DOS_Open ; address of routine to call
110 SaveReg <AX> ; Save mode on stack
111 IF DBCS ;AN000;
112 MOV [Temp_Var],0 ;AN000;KK. set variable with 0
113 ENDIF ;AN000;
114
115 AccessFile:
116 ;
117 ; Grab a free SFT.
118 ;
119 IF DBCS ;AN000;
120 TEST [Temp_Var],8 ;AN000;;KK. volume id bit set ;AN000;
121 JZ novol ;AN000;;KK. no ;AN000;
122 OR [DOS34_FLAG],DBCS_VOLID ;AN000;;KK. set bit for transpath ;AN000;
123 novol: ;AN000;
124 ENDIF ;AN000;
125 EnterCrit critSFT
126 invoke SFNFree ; get a free sfn
127 LeaveCrit critSFT
128 JC OpenFailJ ; oops, no free sft's
129 MOV SFN,BX ; save the SFN for later
130 fmt TypAccess,LevSFN,<"AccessFile setting SFN to $x\n">,<BX>
131 MOV WORD PTR [ThisSFT],DI ; save the SF offset
132 MOV WORD PTR [ThisSFT+2],ES ; save the SF segment
133 ;
134 ; Find a free area in the user's JFN table.
135 ;
136 invoke JFNFree ; get a free jfn
137 JNC SaveJFN
138 OpenFailJ:
139 JMP OpenFail ; there were free JFNs... try SFN
140 SaveJFN:
141 MOV WORD PTR [pJFN],DI ; save the jfn offset
142 MOV WORD PTR [pJFN+2],ES ; save the jfn segment
143 MOV [JFN],BX ; save the jfn itself
144 ;
145 ; We have been given an JFN. We lock it down to prevent other tasks from
146 ; reusing the same JFN.
147 ;
148 MOV BX,SFN
149 MOV ES:[DI],BL ; assign the JFN
150 MOV SI,DX ; get name in appropriate place
151 MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer
152 SaveReg <CX> ; save routine to call
153 invoke TransPath ; convert the path
154 RestoreReg <BX> ; restore routine to call
155 LDS SI,ThisSFT
156 ASSUME DS:NOTHING
157 JC OpenCleanJ ; no error, go and open file
158 CMP cMeta,-1
159 JZ SetSearch
160 MOV AL,error_file_not_found ; no meta chars allowed
161 OpenCleanJ:
162 JMP OpenClean
163 SetSearch:
164 RestoreReg <AX> ; Mode (Open), Attributes (Create)
165 ;
166 ; We need to get the new inheritance bits.
167 ;
168 xor cx,cx
169 CMP BX,OFFSET DOSGroup:DOS_OPEN
170 JNZ DoOper
171 TEST AL,sharing_no_inherit ; look for no inher
172 JZ DoOper
173 AND AL,07Fh ; mask off inherit bit
174 MOV CX,sf_no_inherit
175 DoOper:
176 MOV [SI].sf_mode,0 ; initialize mode field to 0
177 MOV [SI.SF_mft],0 ; clean out sharing info
178 ;
179 ;------------------------------------------------------------HKN 8/7/88
180 ; Check if this is an extended open. If so you must set the
181 ; modes in sf_mode. Call Set_EXT_mode to do all this. See
182 ; Set_EXT_mode in creat.asm
183 ;
184 IF NOT IBMCOPYRIGHT
185
186 push es ; set up es:di to point to SFT
187 push di
188 push ds
189 pop es
190 push si
191 pop di
192 call Set_EXT_mode
193 pop di
194 pop es
195
196 ENDIF
197
198 ;-----------------------------------------------------------------------
199
200 Context DS
201 SaveReg <CX>
202 CALL BX ; blam!
203 RestoreReg <CX>
204 LDS SI,ThisSFT
205 ASSUME DS:NOTHING
206 JC OpenE2 ;AN000;FT. chek extended open hooks first
207 ;
208 ; The SFT was successfully opened. Remove busy mark.
209 ;
210 OpenOK:
211 ASSUME DS:NOTHING
212 ; MOV AL,[SI].sf_attr_hi ;AN000;FT. save file type for EXEC
213 ; MOV BYTE PTR [Temp_Var2],AL ;AN000;FT.
214 MOV [SI].sf_ref_count,1
215 OR [SI].sf_flags,CX ; set no inherit bit if necessary
216 ;
217 ; If the open mode is 70, we scan the system for other SFT's with the same
218 ; contents. If we find one, then we can 'collapse' thissft onto the already
219 ; opened one. Otherwise we use this new one. We compare uid/pid/mode/mft
220 ;
221 ; Since this is only relevant on sharer systems, we stick this code into the
222 ; sharer.
223 ;
224 MOV AX,JFN
225 if installed
226 Call JShare + 12 * 4
227 else
228 Call ShCol
229 endif
230 fmt TypAccess,LevSFN,<"AccessFile setting SFN to -1\n">
231 MOV SFN,-1 ; clear out sfn pointer
232 fmt TypSysCall,LevLog,<"Open/CreateXX: return $x\n">,<AX>
233 transfer Sys_Ret_OK ; bye with no errors
234 ;Extended Open hooks check
235 OpenE2: ;AN000;;EO.
236 CMP AX,error_invalid_parameter ;AN000;;EO. IFS extended open ?
237 JNZ OpenE ;AN000;;EO. no.
238 JMP OpenCritLeave ;AN000;;EO. keep handle
239
240 ;Extended Open hooks check
241 ;
242 ; AL has error code. Stack has argument to dos_open/dos_create.
243 ;
244 OpenClean:
245 fmt TypSysCall,LevLog,<"Return value from transpath $x\n">,<AX>
246 RestoreReg <bx> ; clean off stack
247 OpenE:
248 MOV [SI.SF_Ref_Count],0 ; release SFT
249 LDS SI,pJFN
250 MOV BYTE PTR [SI],0FFh ; free the SFN...
251 JMP SHORT OpenCritLeave
252
253 OpenFail:
254 STI
255 RestoreReg <CX> ; Clean stack
256 OpenCritLeave:
257 MOV SFN,-1 ; remove mark.
258 fmt TypSysCall,LevLog,<"Open/CreateXX: error $x\n">,<AX>
259 ;; File Tagging DOS 4.00
260 CMP CS:[EXTERR],error_Code_Page_Mismatched ;AN000;;FT. code page mismatch
261 JNZ NORERR ;AN000;;FT. no
262 transfer From_GetSet ;AN000;;FT. yes
263 NORERR: ;AN000;
264
265 ;; File Tagging DOS 4.00
266 transfer Sys_Ret_Err ; no free, return error
267
268 EndProc $Open
269
270 BREAK <$Creat - create a brand-new file>
271
272 ;
273 ; $Creat - create the directory entry specified in DS:DX and give it the
274 ; initial attributes contained in CX
275 ; Inputs: DS:DX - ASCIZ path name
276 ; CX - initial attributes
277 ; Outputs: Carry set - AX has error code
278 ; Carry reset - AX has handle
279 ; Registers modified: all
280
281 Procedure $Creat,NEAR
282 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
283 fmt TypSysCall,LevLog,<"Create\n">
284 fmt TypSysCall,LevArgs,<" Att = $x file = '$S'\n">,<CX,DS,DX>
285 IF DBCS ;AN000;
286 MOV [Temp_Var],CX ;AN000;KK. set variable with attribute ;AN000;
287 ENDIF ;AN000;
288 SaveReg <CX> ; Save attributes on stack
289 MOV CX,OFFSET DOSGroup:DOS_Create; routine to call
290 AccessSet:
291 mov SAttrib,attr_hidden+attr_system
292 JMP AccessFile ; use good ol' open
293 EndProc $Creat
294
295 BREAK <$CHMOD - change file attributes>
296 ;
297 ; Assembler usage:
298 ; LDS DX, name
299 ; MOV CX, attributes
300 ; MOV AL,func (0=get, 1=set)
301 ; INT 21h
302 ; Error returns:
303 ; AX = error_path_not_found
304 ; AX = error_access_denied
305 ;
306
307 procedure $CHMOD,NEAR
308 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
309 MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer
310 SaveReg <AX,CX> ; save function and attributes
311 MOV SI,DX ; get things in appropriate places
312 invoke TransPathSet ; get correct path
313 RestoreReg <CX,AX> ; and get function and attrs back
314 JC ChModErr ; errors get mapped to path not found
315 Context DS ; set up for later possible calls
316 CMP cMeta,-1
317 JNZ ChModErr
318 MOV [SAttrib],attr_hidden+attr_system+attr_directory
319 SUB AL,1 ; fast way to discriminate
320 JB ChModGet ; 0 -> go get value
321 JZ ChModSet ; 1 -> go set value
322 MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus
323 error error_invalid_function ; bad value
324 ChModGet:
325 invoke Get_File_Info ; suck out the ol' info
326 JC ChModE ; error codes are already set for ret
327 invoke Get_User_stack ; point to user saved vaiables
328 MOV [SI.User_CX],AX ; return the attributes
329 transfer Sys_Ret_OK ; say sayonara
330 ChModSet:
331 MOV AX,CX ; get attrs in position
332 invoke Set_File_Attribute ; go set
333 JC ChModE ; errors are set
334 transfer Sys_Ret_OK
335 ChModErr:
336 mov al,error_path_not_found
337 ChmodE:
338 Transfer SYS_RET_ERR
339 EndProc $ChMod
340
341 BREAK <$UNLINK - delete a file entry>
342 ;
343 ; Assembler usage:
344 ; LDS DX, name
345 ; IF VIA SERVER DOS CALL
346 ; MOV CX,SEARCH_ATTRIB
347 ; MOV AH, Unlink
348 ; INT 21h
349 ;
350 ; Error returns:
351 ; AX = error_file_not_found
352 ; = error_access_denied
353 ;
354
355 procedure $UNLINK,NEAR
356 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
357 SaveReg <CX> ; Save possible CX input parm
358 MOV SI,DX ; Point at input string
359 MOV DI,OFFSET DOSGroup:OpenBuf ; temp spot for path
360 invoke TransPathSet ; go get normalized path
361 RestoreReg <CX>
362 JC ChModErr ; badly formed path
363 CMP cMeta,-1 ; meta chars?
364 JNZ NotFound
365 Context DS
366 mov ch,attr_hidden+attr_system ; unlink appropriate files
367 call SetAttrib
368 invoke DOS_Delete ; remove that file
369 JC UnlinkE ; error is there
370
371
372 transfer Sys_Ret_OK ; okey doksy
373 NotFound:
374 MOV AL,error_path_not_found
375 UnlinkE:
376 transfer Sys_Ret_Err ; bye
377 EndProc $UnLink
378
379 BREAK <$RENAME - move directory entries around>
380 ;
381 ; Assembler usage:
382 ; LDS DX, source
383 ; LES DI, dest
384 ; IF VIA SERVER DOS CALL
385 ; MOV CX,SEARCH_ATTRIB
386 ; MOV AH, Rename
387 ; INT 21h
388 ;
389 ; Error returns:
390 ; AX = error_file_not_found
391 ; = error_not_same_device
392 ; = error_access_denied
393
394 procedure $RENAME,NEAR
395 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
396 SaveReg <CX,DS,DX> ; save source and possible CX arg
397 PUSH ES
398 POP DS ; move dest to source
399 MOV SI,DI ; save for offsets
400 MOV DI,OFFSET DOSGroup:RenBuf
401
402 MOV WORD PTR [NO_FILTER_DPATH],SI ;AN000;;IFS. save them for IFS
403 MOV WORD PTR [NO_FILTER_DPATH+2],DS ;AN000;;IFS.
404
405 invoke TransPathSet ; munge the paths
406 PUSH WFP_Start ; get pointer
407 POP Ren_WFP ; stash it
408 RestoreReg <SI,DS,CX> ; get back source and possible CX arg
409 epjc2: JC ChModErr ; get old error
410 CMP cMeta,-1
411 JNZ NotFound
412 SaveReg <CX> ; Save possible CX arg
413 MOV DI,OFFSET DOSGroup:OpenBuf ; appropriate buffer
414 invoke TransPathSet ; wham
415 RestoreReg <CX>
416 JC EPJC2
417 Context DS
418 CMP cMeta,-1
419 JB NotFound
420
421 PUSH WORD PTR [THISCDS] ;AN000;;MS.save thiscds
422 PUSH WORD PTR [THISCDS+2] ;AN000;;MS.
423 MOV DI,OFFSET DOSGROUP:OpenBuf ;AN000;;MS.
424 PUSH SS ;AN000;;MS.
425 POP ES ;AN000;;MS.es:di-> source
426 XOR AL,AL ;AN000;;MS.scan all CDS
427 rnloop: ;AN000;
428 invoke GetCDSFromDrv ;AN000;;MS.
429 JC dorn ;AN000;;MS. end of CDS
430 invoke StrCmp ;AN000;;MS. current dir ?
431 JZ rnerr ;AN000;;MS. yes
432 INC AL ;AN000;;MS. next
433 JMP rnloop ;AN000;;MS.
434 rnerr: ;AN000;
435 ADD SP,4 ;AN000;;MS. pop thiscds
436 error error_current_directory ;AN000;;MS.
437 dorn: ;AN000;
438 POP WORD PTR SS:[THISCDS+2] ;AN000;;MS.
439 POP WORD PTR SS:[THISCDS] ;AN000;;MS.
440 Context DS
441 mov ch,attr_directory+attr_hidden+attr_system; rename appropriate files
442 call SetAttrib
443 invoke DOS_Rename ; do the deed
444 JC UnlinkE ; errors
445
446
447 transfer Sys_Ret_OK
448 EndProc $Rename
449
450 Break <$CreateNewFile - Create a new directory entry>
451
452 ;
453 ; CreateNew - Create a new directory entry. Return a file handle if there
454 ; was no previous directory entry, and fail if a directory entry with
455 ; the same name existed previously.
456 ;
457 ; Inputs: DS:DX point to an ASCIZ file name
458 ; CX contains default file attributes
459 ; Outputs: Carry Clear:
460 ; AX has file handle opened for read/write
461 ; Carry Set:
462 ; AX has error code
463 ; Registers modified: All
464
465 Procedure $CreateNewFile,NEAR
466 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
467 fmt TypSysCall,LevLog,<"CreateNew\n">
468 fmt TypSysCall,LevArgs,<" Att = $x file = '$S'\n">,<CX,DS,DX>
469 IF DBCS ;AN000;
470 MOV [Temp_Var],CX ;AN000;KK. set variable with attribute
471 ENDIF ;AN000;
472 SaveReg <CX> ; Save attributes on stack
473 MOV CX,OFFSET DOSGroup:DOS_Create_New ; routine to call
474 JMP AccessSet ; use good ol' open
475 EndProc $CreateNewFile
476
477 Break <HexToAsciz - convert a number to hex and store it in memory>
478
479 ;
480 ; HexToAsciz - used to convert register into a hex number.
481 ;
482 ; Inputs: AX contains the number
483 ; ES:DI point to destination
484 ; Outputs: ES:DI updated
485 ; Registers modified: DI,CX
486
487 Procedure HexToAsciz,NEAR
488 mov cx,4 ; 4 digits in AX
489 GetDigit:
490 SaveReg <CX> ; preserve count
491 mov cl,4
492 ROL AX,CL ; move leftmost nibble into rightmost
493 SaveReg <AX> ; preserve remainder of digits
494 AND AL,0Fh ; grab low nibble
495 ADD AL,'0' ; turn into digit
496 CMP AL,'9' ; bigger than 9
497 JBE DoStore ; no, stash it
498 ADD AL,'A'-'0'-10 ; convert into uppercase letter
499 DoStore:
500 STOSB ; drop in the character
501 RestoreReg <AX,CX> ; regain the number and count
502 loop GetDigit ; while there's more digits, go do 'em
503 return
504 EndProc HexToAsciz
505
506 Break <$CreateTempFile - create a unique name>
507
508 ;
509 ; $CreateTemp - given a directory, create a unique name in that directory.
510 ; Method used is to get the current time, convert to a name and attempt
511 ; a create new. Repeat until create new succeeds.
512 ;
513 ; Inputs: DS:DX point to a null terminated directory name.
514 ; CX contains default attributes
515 ; Outputs: Unique name is appended to DS:DX directory.
516 ; AX has handle
517 ; Registers modified: all
518
519 Procedure $CreateTempFile,NEAR
520 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
521 fmt TypSysCall,LevLog,<"CreateTmp\n">
522 fmt TypSysCall,LevArgs,<" Att = $x dir = '$S'\n">,<CX,DS,DX>
523 PUBLIC FILE001S,FILE001E
524 FILE001S:
525 LocalVar EndPtr,DWORD
526 LocalVar FilPtr,DWORD
527 LocalVar Attr,WORD
528 FILE001E:
529 Enter
530 TEST CX,NOT attr_changeable
531 JZ OKatts ; Ok if no non-changeable bits set
532 ;
533 ; We need this "hook" here to detect these cases (like user sets one both of
534 ; vol_id and dir bits) because of the structure of the or $CreateNewFile loop
535 ; below. The code loops on error_access_denied, but if one of the non
536 ; changeable attributes is specified, the loop COULD be infinite or WILL be
537 ; infinite because CreateNewFile will fail with access_denied always. Thus we
538 ; need to detect these cases before getting to the loop.
539 ;
540 MOV AX,error_access_denied
541 JMP SHORT SETTMPERR
542
543 OKatts:
544 MOV attr,CX ; save attribute
545 MOV FilPtrL,DX ; pointer to file
546 MOV FilPtrH,DS
547 MOV EndPtrH,DS ; seg pointer to end of dir
548 PUSH DS
549 POP ES ; destination for nul search
550 MOV DI,DX
551 MOV CX,DI
552 NEG CX ; number of bytes remaining in segment
553 IF DBCS ;AN000;
554 Kloop: ;AN000;; 2/13/KK
555 MOV AL, BYTE PTR ES:[DI] ;AN000;; 2/13/KK
556 INC DI ;AN000;; 2/13/KK
557 OR AL,AL ;AN000;; 2/13/KK
558 JZ GOTEND ;AN000;; 2/13/KK
559 invoke testkanj ;AN000;; 2/13/KK
560 jz Kloop ;AN000;; 2/13/KK
561 inc di ;AN000;; Skip over second kanji byte 2/13/KK
562 CMP BYTE PTR ES:[DI],0 ;AN000;; 2/13/KK
563 JZ STOREPTH ;AN000; When char before NUL is sec Kanji byte
564 ;AN000; do not look for path char. 2/13/KK
565 jmp Kloop ;AN000; 2/13/KK
566 GOTEND: ;AN000; 2/13/KK
567 ELSE ;AN000;
568 OR CX,CX ;AN000;MS. cx=0 ? ds:dx on segment boundary
569 JNZ okok ;AN000;MS. no
570 MOV CX,-1 ;AN000;MS.
571 okok: ;AN000;
572 XOR AX,AX ;AN000;
573 REPNZ SCASB ;AN000;
574 ENDIF ;AN000;
575 DEC DI ; point back to the null
576 MOV AL,ES:[DI-1] ; Get char before the NUL
577 invoke PathChrCmp ; Is it a path separator?
578 JZ SETENDPTR ; Yes
579 STOREPTH:
580 MOV AL,'\'
581 STOSB ; Add a path separator (and INC DI)
582 SETENDPTR:
583 MOV EndPtrL,DI ; pointer to the tail
584 CreateLoop:
585 Context DS ; let ReadTime see variables
586 SaveReg <BP>
587 invoke ReadTime ; go get time
588 RestoreReg <BP>
589 ;
590 ; Time is in CX:DX. Go drop it into the string.
591 ;
592 les di,EndPtr ; point to the string
593 mov ax,cx
594 call HexToAsciz ; store upper word
595 mov ax,dx
596 call HexToAsciz ; store lower word
597 xor al,al
598 STOSB ; nul terminate
599 LDS DX,FilPtr ; get name
600 ASSUME DS:NOTHING
601 MOV CX,Attr ; get attr
602 SaveReg <BP>
603 CALL $CreateNewFile ; try to create a new file
604 RestoreReg <BP>
605 JNC CreateDone ; failed, go try again
606 ;
607 ; The operation failed and the error has been mapped in AX. Grab the extended
608 ; error and figure out what to do.
609 ;
610 mov ax,ExtErr
611 cmp al,error_file_exists
612 jz CreateLoop ; file existed => try with new name
613 cmp al,error_access_denied
614 jz CreateLoop ; access denied (attr mismatch)
615
616 ; CMP AL,error_file_exists ; certain errors cause failure
617 ; JZ CreateLoop
618 ; CMP AL,error_access_denied
619 ; JNZ SETTMPERR ; Error out
620 ; CMP [EXTERR],error_cannot_make ; See if it's REALLY an att mismatch
621 ; JNZ CreateLoop ; It was, try again
622 ; MOV AL,error_cannot_make ; Return this "extended" error
623
624 SETTMPERR:
625 STC
626 CreateDone:
627 Leave
628 JC CreateFail
629 transfer Sys_Ret_OK ; success!
630 CreateFail:
631 transfer Sys_Ret_Err
632 EndProc $CreateTempFile
633
634 Break <SetAttrib - set the search attrib>
635
636 ;
637 ; SetAttrib will set the search attribute (SAttrib) either to the normal
638 ; (CH) or to the value in CL if the current system call is through
639 ; serverdoscall.
640 ;
641 ; Inputs: fSharing == FALSE => set sattrib to CH
642 ; fSharing == TRUE => set sattrib to CL
643 ; Outputs: none
644 ; Registers changed: CX
645
646 procedure SetAttrib,NEAR
647 assume ds:nothing,es:nothing
648 test fSharing,-1
649 jnz Set
650 mov cl,ch
651 Set:
652 mov SAttrib,cl
653 return
654 EndProc SetAttrib
655
656
657 Break <Extended_Open- Extended open the file>
658
659 ; Input: AL= 0 reserved AH=6CH
660 ; BX= mode
661 ; CL= create attribute CH=search attribute (from server)
662 ; DX= flag
663 ; DS:SI = file name
664 ; ES:DI = parm list
665 ; DD SET EA list (-1) null
666 ; DW n parameters
667 ; DB type (TTTTTTLL)
668 ; DW IOMODE
669 ; Function: Extended Open
670 ; Output: carry clear
671 ; AX= handle
672 ; CX=1 file opened
673 ; 2 file created/opened
674 ; 3 file replaced/opened
675 ; carry set: AX has error code
676 ;
677
678
679 procedure $Extended_Open,NEAR ;AN000;
680 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000;
681
682 MOV [XA_from],0 ;AN000;EO. init for set XA
683 MOV [EXTOPEN_FLAG],DX ;AN000;EO. save ext. open flag
684 MOV [EXTOPEN_IO_MODE],0 ;AN000;EO. initialize IO mode
685 TEST DX,reserved_bits_mask ;AN000;EO. reserved bits 0 ?
686 JNZ ext_inval2 ;AN000;EO. no
687 MOV AH,DL ;AN000;EO. make sure flag is right
688 CMP DL,0 ;AN000;EO. all fail ?
689 JZ ext_inval2 ;AN000;EO. yes, error
690 AND DL,exists_mask ;AN000;EO. get exists action byte
691 CMP DL,2 ;AN000;EO, > 02
692 JA ext_inval2 ;AN000;EO. yes ,error
693 AND AH,not_exists_mask ;AN000;EO. get no exists action byte
694 CMP AH,10H ;AN000;EO. > 10
695 JA ext_inval2 ;AN000;EO. yes error
696
697 ; CMP DI,-1 ;AN000;EO. null parm list
698 ; JZ no_parm ;AN000;EO. yes
699 ; ;AN000;EO
700 ; PUSH CX ;AN000;EO.
701 ; ;AN000;EO.
702 ; MOV CX,ES:[DI.EXT_NUM_OF_PARM];AN000;EO. get number of parms
703 ; OR CX,CX ;AN000;EO. 0 pamrs ?
704 ; JZ parmend ;AN000;EO. yes
705 ; PUSH SI ;AN000;EO.
706 ; PUSH DS ;AN000;EO.
707 ; MOV SI,DI ;AN000;EO.
708 ; ADD SI,size EXT_OPEN_PARM ;AN000;EO. position to 1st parm
709 ; PUSH ES ;AN000;EO.
710 ; POP DS ;AN000;EO. ds:si -> parm list
711 ; CALL GetIOParms ;AN000;EO.
712 ; POP DS ;AN000;EO.
713 ; POP SI ;AN000;EO.
714 ;parmend: ;AN000;EO
715 ; POP CX ;AN000;EO. restore CX
716 ;no_parm: ;AN000;EO.
717 MOV [SAVE_ES],ES ;AN000;EO. save API parms
718 MOV [SAVE_DI],DI ;AN000;EO.
719 PUSH [EXTOPEN_FLAG] ;AN000;EO.
720 POP [SAVE_DX] ;AN000;EO.
721 MOV [SAVE_CX],CX ;AN000;EO.
722 MOV [SAVE_BX],BX ;AN000;EO.
723 MOV [SAVE_DS],DS ;AN000;EO.
724 MOV [SAVE_SI],SI ;AN000;EO.
725 MOV DX,SI ;AN000;EO. ds:dx points to file name
726 MOV AX,BX ;AN000;EO. ax= mode
727
728 ; TEST [EXTOPEN_FLAG],no_code_page_check ;AN000;EO. check no code page
729 ; JNZ no_cdpg_chk ;AN000;;EO. no
730 JMP SHORT goopen2 ;AN000;;EO. do nromal
731 ext_inval2: ;AN000;;EO.
732 error error_Invalid_Function ;AN000;EO.. invalid function
733 ext_inval_parm: ;AN000;EO..
734 POP CX ;AN000;EO.. pop up satck
735 POP SI ;AN000;EO..
736 error error_Invalid_data ;AN000;EO.. invalid parms
737 error_return: ;AN000;EO.
738 ret ;AN000;EO.. return with error
739 ;no_cdpg_chk: EO.
740 ; MOV [CPSWFLAG],0 ;AN000;EO.. set CPSW flag off
741 goopen2: ;AN000;
742 TEST BX,int_24_error ;AN000;EO.. disable INT 24 error ?
743 JZ goopen ;AN000;EO.. no
744 OR [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;EO.. set bit to disable
745
746 goopen: ;AN000;
747 OR [EXTOPEN_ON],EXT_OPEN_ON ;AN000;EO.. set Extended Open active
748 AND [EXTOPEN_FLAG],0FFH ;AN000;EO.create new ?
749 CMP [EXTOPEN_FLAG],ext_exists_fail + ext_nexists_create ;AN000;FT.
750 JNZ chknext ;AN000;;EO. no
751 invoke $CreateNewFile ;AN000;;EO. yes
752 JC error_return ;AN000;;EO. error
753 CMP [EXTOPEN_ON],0 ;AN000;;EO. IFS does it
754 JZ ok_return2 ;AN000;;EO. yes
755 MOV [EXTOPEN_FLAG],action_created_opened ;AN000;EO. creted/opened
756 MOV [XA_from],By_Create ;AN000;;EO. for set xa
757 JMP setXAttr ;AN000;;EO. set XAs
758 ok_return2:
759 transfer SYS_RET_OK ;AN000;;EO.
760 chknext:
761 TEST [EXTOPEN_FLAG],ext_exists_open ;AN000;;EO. exists open
762 JNZ exist_open ;AN000;;EO. yes
763 invoke $Creat ;AN000;;EO. must be replace open
764 JC error_return ;AN000;;EO. return with error
765 CMP [EXTOPEN_ON],0 ;AN000;;EO. IFS does it
766 JZ ok_return2 ;AN000;;EO. yes
767 MOV [EXTOPEN_FLAG],action_created_opened ;AN000;EO. prsume create/open
768 MOV [XA_from],By_Create ;AN000;EO. for set xa
769 TEST [EXTOPEN_ON],ext_file_not_exists ;AN000;;EO. file not exists ?
770 JNZ setXAttr ;AN000;;EO. no
771 MOV [EXTOPEN_FLAG],action_replaced_opened ;AN000;;EO. replaced/opened
772 MOV [XA_from],0 ;AN000;EO. for set xa
773 JMP SHORT setXAttr ;AN000;;EO. set XAs
774 error_return2:
775 ret ;AN000;;EO. return with error
776 ;AN000;
777 exist_open: ;AN000;
778 test fSharing,-1 ;AN000;;EO. server doscall?
779 jz noserver ;AN000;;EO. no
780 MOV CL,CH ;AN000;;EO. cl=search attribute
781
782 noserver:
783 invoke $Open2 ;AN000;;EO. do open
784 JNC ext_ok ;AN000;;EO.
785 CMP [EXTOPEN_ON],0 ;AN000;;EO. error and IFS call
786 JZ error_return2 ;AN000;;EO. return with error
787 local_extopen:
788
789 CMP AX,error_file_not_found ;AN000;;EO. file not found error
790 JNZ error_return2 ;AN000;;EO. no,
791 TEST [EXTOPEN_FLAG],ext_nexists_create;AN000;;EO. want to fail
792 JNZ do_creat ;AN000;;EO. yes
793 JMP extexit ;AN000;;EO. yes
794 do_creat:
795 MOV [XA_from],By_Create ;AN000;;EO. for set xa
796 MOV CX,[SAVE_CX] ;AN000;;EO. get ds:dx for file name
797 LDS SI,DWORD PTR [SAVE_SI] ;AN000;;EO. cx = attribute
798 MOV DX,SI ;AN000;;EO.
799 invoke $Creat ;AN000;;EO. do create
800 JC extexit ;AN000;;EO. error
801 MOV [EXTOPEN_FLAG],action_created_opened ;AN000;;EO. is created/opened
802 JMP SHORT setXAttr ;AN000;;EO. set XAs
803
804 ext_ok:
805 CMP [EXTOPEN_ON],0 ;AN000;;EO. IFS call ?
806 JZ ok_return ;AN000;;EO. yes
807 MOV [EXTOPEN_FLAG],action_opened ;AN000;;EO. opened
808 setXAttr:
809 ; LES DI,DWORD PTR [SAVE_DI] ;AN000;EO.
810 PUSH AX ;AN000;;EO. save handle for final
811 ; MOV BX,AX ;AN000;;EO. bx= handle
812 ; MOV AX,04H ;AN000;;EO. set extended attr by handle
813 ; PUSH DS ;AN000;;EO. save file name addr
814 ; PUSH DX ;AN000;;EO.
815 ; CMP DI,-1 ;AN000;;EO. null parm list
816 ; JZ nosetea ;AN000;;EO. yes
817 ; CMP WORD PTR ES:[DI],-1 ;AN000;;EO. null set list
818 ; JZ nosetea ;AN000;;EO. yes
819 ; LES DI,DWORD PTR ES:[DI] ;AN000;;EO. es:di -> set list
820 ; invoke $File_times ;AN000;;EO.
821 ;nosetea: ;AN000; EO
822 ; POP DX ;AN000;;EO. restore file name addr
823 ; POP DS ;AN000;;EO.
824 ; JC extexit2 ;AN000;;EO.
825 invoke get_user_stack ;AN000;;EO.
826 MOV AX,[EXTOPEN_FLAG] ;AN000;;EO.
827 MOV [SI.USER_CX],AX ;AN000;;EO. set action code for cx
828 POP AX ;AN000;;EO.
829 MOV [SI.USER_AX],AX ;AN000;;EO. set handle for ax
830
831 ok_return: ;AN000;
832 transfer SYS_RET_OK ;AN000;;EO.
833
834 extexit2: ;AN000; ERROR RECOVERY
835
836 POP BX ;AN000;EO. close the handle
837 PUSH AX ;AN000;EO. save error code from set XA
838 CMP [EXTOPEN_FLAG],action_created_opened ;AN000;EO. from create
839 JNZ justopen ;AN000;EO.
840 LDS SI,DWORD PTR [SAVE_SI] ;AN000;EO. cx = attribute
841 LDS DX,DWORD PTR [SI] ;AN000;EO.
842 invoke $UNLINK ;AN000;EO. delete the file
843 JMP SHORT reserror ;AN000;EO.
844
845 justopen: ;AN000;
846 invoke $close ;AN000;EO. pretend never happend
847 reserror: ;AN000;
848 POP AX ;AN000;EO. retore error code from set XA
849 JMP SHORT extexit ;AN000;EO.
850
851
852 ext_file_unfound: ;AN000;
853 MOV AX,error_file_not_found ;AN000;EO.
854 JMP SHORT extexit ;AN000;EO.
855 ext_inval: ;AN000;
856 MOV AX,error_invalid_function;AN000;EO.
857 extexit:
858 transfer SYS_RET_ERR ;AN000;EO.
859
860 EndProc $Extended_Open ;AN000;
861
862
863 Break <GetIOParms - get IO parms form extended open parm list>
864
865 ;
866 ;
867 ; Inputs: DS:SI -> IO parm list
868 ; CX= number of parms
869 ; Function: get IO parms from parm list
870 ; Outputs: [EXT_IOMODE]= IO mode parm
871
872 ;procedure GetIOParms,NEAR
873 ; assume ds:nothing,es:nothing
874 ;
875 ; LODSB ; get parm type ;AN000;
876 ; CMP AL,0*100B+10B ; have IOMODE ;AN000;
877 ; JE SET_IOMODE ;AN000;
878 ; AND AL,00000011B ; decode it ;AN000;
879 ; JZ SKIP_ASCIIZ ;AN000;
880 ; DEC AL ;AN000;
881 ; JZ SKIP_LEN ;AN000;
882 ;; DEC AL ;AN000;
883 ; JZ SKIP_WORD ;AN000;
884 ;SKIP_DWORD: ; copy DWORD parm ;AN000;
885 ; LODSW ;AN000;
886 ;SKIP_WORD: ; copy WORD parm ;AN000;
887 ; LODSW ;AN000;
888 ; JMP SHORT NEXT_PARM ;AN000;
889 ;SET_IOMODE: ; copy IOMODE ;AN000;
890 ; LODSW ;AN000;
891 ; MOV [EXTOPEN_IO_MODE],AX ;AN000;
892 ; JMP SHORT NEXT_PARM ;AN000;
893 ;SKIP_LEN: ; copy LENGTH parm ;AN000;
894 ; LODSW ;AN000;
895 ; ADD SI,AX ;AN000;
896 ; JMP SHORT NEXT_PARM ;AN000;
897 ;SKIP_ASCIIZ: ; copy ASCIIZ parm ;AN000;
898 ; LODSB ;AN000;
899 ; OR AL,AL ;AN000;
900 ; JNE SKIP_ASCIIZ ;AN000;
901 ;NEXT_PARM: ;AN000;
902 ; LOOP GetIOParms ;AN000;
903 ; return ;AN000;
904 ;EndProc GetIOParms ;AN000;
905
906
907 CODE ENDS
908 END
909 \1a