summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/FILE.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DOS/FILE.ASM')
-rw-r--r--v4.0/src/DOS/FILE.ASM909
1 files changed, 909 insertions, 0 deletions
diff --git a/v4.0/src/DOS/FILE.ASM b/v4.0/src/DOS/FILE.ASM
new file mode 100644
index 0000000..9fca034
--- /dev/null
+++ b/v4.0/src/DOS/FILE.ASM
@@ -0,0 +1,909 @@
1; SCCSID = @(#)file.asm 1.2 85/07/23
2; SCCSID = @(#)file.asm 1.2 85/07/23
3TITLE FILE - Pathname related system calls
4NAME 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;
31include dosseg.asm
32
33CODE SEGMENT BYTE PUBLIC 'CODE'
34 ASSUME SS:DOSGroup,CS:DOSGroup
35
36.xcref
37include dossym.inc
38include devsym.inc
39include fastopen.inc
40include EA.inc ;AN000;
41include version.inc
42.cref
43.list
44.sall
45
46 EXTRN DOS_OPEN:NEAR,DOS_CREATE:NEAR,DOS_Create_New:NEAR
47
48IF NOT IBMCOPYRIGHT
49 extrn Set_EXT_mode:near
50ENDIF
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;;
84if debug
85 I_need BugLev,WORD
86 I_need BugTyp,WORD
87include bugtyp.asm
88endif
89
90BREAK <$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
101Procedure $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
106Entry $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
111IF DBCS ;AN000;
112 MOV [Temp_Var],0 ;AN000;KK. set variable with 0
113ENDIF ;AN000;
114
115AccessFile:
116;
117; Grab a free SFT.
118;
119IF 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;
123novol: ;AN000;
124ENDIF ;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
138OpenFailJ:
139 JMP OpenFail ; there were free JFNs... try SFN
140SaveJFN:
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
161OpenCleanJ:
162 JMP OpenClean
163SetSearch:
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
175DoOper:
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;
184IF 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
196ENDIF
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;
210OpenOK:
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
225if installed
226 Call JShare + 12 * 4
227else
228 Call ShCol
229endif
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
235OpenE2: ;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;
244OpenClean:
245 fmt TypSysCall,LevLog,<"Return value from transpath $x\n">,<AX>
246 RestoreReg <bx> ; clean off stack
247OpenE:
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
253OpenFail:
254 STI
255 RestoreReg <CX> ; Clean stack
256OpenCritLeave:
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
263NORERR: ;AN000;
264
265;; File Tagging DOS 4.00
266 transfer Sys_Ret_Err ; no free, return error
267
268EndProc $Open
269
270BREAK <$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
281Procedure $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>
285IF DBCS ;AN000;
286 MOV [Temp_Var],CX ;AN000;KK. set variable with attribute ;AN000;
287ENDIF ;AN000;
288 SaveReg <CX> ; Save attributes on stack
289 MOV CX,OFFSET DOSGroup:DOS_Create; routine to call
290AccessSet:
291 mov SAttrib,attr_hidden+attr_system
292 JMP AccessFile ; use good ol' open
293EndProc $Creat
294
295BREAK <$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
324ChModGet:
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
330ChModSet:
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
335ChModErr:
336 mov al,error_path_not_found
337ChmodE:
338 Transfer SYS_RET_ERR
339EndProc $ChMod
340
341BREAK <$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
373NotFound:
374 MOV AL,error_path_not_found
375UnlinkE:
376 transfer Sys_Ret_Err ; bye
377EndProc $UnLink
378
379BREAK <$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
409epjc2: 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
427rnloop: ;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.
434rnerr: ;AN000;
435 ADD SP,4 ;AN000;;MS. pop thiscds
436 error error_current_directory ;AN000;;MS.
437dorn: ;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
448EndProc $Rename
449
450Break <$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>
469IF DBCS ;AN000;
470 MOV [Temp_Var],CX ;AN000;KK. set variable with attribute
471ENDIF ;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
475EndProc $CreateNewFile
476
477Break <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
487Procedure HexToAsciz,NEAR
488 mov cx,4 ; 4 digits in AX
489GetDigit:
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
499DoStore:
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
504EndProc HexToAsciz
505
506Break <$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>
523PUBLIC FILE001S,FILE001E
524FILE001S:
525 LocalVar EndPtr,DWORD
526 LocalVar FilPtr,DWORD
527 LocalVar Attr,WORD
528FILE001E:
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
543OKatts:
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;
554Kloop: ;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
566GOTEND: ;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.
571okok: ;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
579STOREPTH:
580 MOV AL,'\'
581 STOSB ; Add a path separator (and INC DI)
582SETENDPTR:
583 MOV EndPtrL,DI ; pointer to the tail
584CreateLoop:
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
600ASSUME 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
624SETTMPERR:
625 STC
626CreateDone:
627 Leave
628 JC CreateFail
629 transfer Sys_Ret_OK ; success!
630CreateFail:
631 transfer Sys_Ret_Err
632EndProc $CreateTempFile
633
634Break <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
646procedure SetAttrib,NEAR
647 assume ds:nothing,es:nothing
648 test fSharing,-1
649 jnz Set
650 mov cl,ch
651Set:
652 mov SAttrib,cl
653 return
654EndProc SetAttrib
655
656
657Break <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
679procedure $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
731ext_inval2: ;AN000;;EO.
732 error error_Invalid_Function ;AN000;EO.. invalid function
733ext_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
737error_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
741goopen2: ;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
746goopen: ;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
758ok_return2:
759 transfer SYS_RET_OK ;AN000;;EO.
760chknext:
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
774error_return2:
775 ret ;AN000;;EO. return with error
776 ;AN000;
777exist_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
782noserver:
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
787local_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
794do_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
804ext_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
808setXAttr:
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
831ok_return: ;AN000;
832 transfer SYS_RET_OK ;AN000;;EO.
833
834extexit2: ;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
845justopen: ;AN000;
846 invoke $close ;AN000;EO. pretend never happend
847reserror: ;AN000;
848 POP AX ;AN000;EO. retore error code from set XA
849 JMP SHORT extexit ;AN000;EO.
850
851
852ext_file_unfound: ;AN000;
853 MOV AX,error_file_not_found ;AN000;EO.
854 JMP SHORT extexit ;AN000;EO.
855ext_inval: ;AN000;
856 MOV AX,error_invalid_function;AN000;EO.
857extexit:
858 transfer SYS_RET_ERR ;AN000;EO.
859
860EndProc $Extended_Open ;AN000;
861
862
863Break <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
907CODE ENDS
908END
909 \ No newline at end of file