diff options
Diffstat (limited to 'v4.0/src/DOS/FILE.ASM')
| -rw-r--r-- | v4.0/src/DOS/FILE.ASM | 909 |
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 | ||
| 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 | \ No newline at end of file | ||