Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2319 lines
80 KiB

  1. TITLE LDOPEN - Open and Delete Pathname primitives
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc
  5. include tdb.inc
  6. include pdb.inc
  7. .list
  8. externFP AnsiUpper
  9. externFP Int21Handler
  10. externFP <lstrcpy>
  11. ifdef FE_SB
  12. externFP FarMyIsDBCSLeadByte
  13. externFP FarMyIsDBCSTrailByte
  14. endif
  15. ifdef WOW
  16. externFP GetDriveType
  17. endif
  18. ;** Equates for the Directory Table code
  19. DT_CURDIR EQU 1
  20. DT_WINDIR EQU 2
  21. ifndef WOW
  22. DT_SYSDIR EQU 3
  23. DT_APPDIR EQU 4
  24. MAX_SEARCH EQU 4
  25. else
  26. DT_SYS16DIR EQU 3
  27. DT_SYSDIR EQU 4
  28. DT_SYSWX86DIR EQU 5
  29. DT_APPDIR EQU 6
  30. MAX_SEARCH EQU 6
  31. endif
  32. DataBegin
  33. externB fInt21
  34. externB OutBuf
  35. externB szCannotFind1
  36. externB szCannotFind2
  37. externB szDiskCap
  38. externB LastDriveSwapped
  39. externB fNovell
  40. externB fBooting
  41. externW bufpos
  42. externW cBytesWinDir
  43. externW cBytesSysDir
  44. externW TopPDB
  45. externW curTDB
  46. externD lpWindowsDir
  47. externD lpSystemDir
  48. externD pSysProc
  49. externD pKeyProc
  50. externD pKeyProc1
  51. externD pSErrProc
  52. externW wMyOpenFileReent
  53. ;** These variables needed to implement the app dir searching
  54. externW loadTDB
  55. externW fLMDepth
  56. staticW myofint24,0
  57. ifdef WOW
  58. externD lpSystem16Dir
  59. externW cBytesSys16Dir
  60. externD lpSystemWx86Dir
  61. externW cBytesSysWx86Dir
  62. endif
  63. ;** Directory table for different search orders. Pgm Management-aware!!
  64. ; DIRTABLE struc holds pointers to previously searched paths so we don't
  65. ; repeat the path searches
  66. DIRTABLE STRUC
  67. dt_lpstr DD ?
  68. dt_wLen DW ?
  69. DIRTABLE ENDS
  70. dtDirTable LABEL DWORD
  71. public dtDirTable
  72. DB (SIZE DIRTABLE) * MAX_SEARCH DUP (0)
  73. ; These tables drive the search order loops, determining which paths
  74. ; to search in which order. The DOS/Novell path is always searched
  75. ; last.
  76. BootOrder LABEL BYTE
  77. DB DT_SYSDIR
  78. DB DT_WINDIR
  79. DB 0
  80. DefaultOrder LABEL BYTE
  81. DB DT_CURDIR
  82. DB DT_WINDIR
  83. ifdef WOW ; Search 16-bit system dir (\windir\system)
  84. DB DT_SYS16DIR
  85. endif
  86. DB DT_SYSDIR
  87. ifdef WOW ; Search Wx86 system dir (\windir\system32\Wx86)
  88. DB DT_SYSWX86DIR
  89. endif
  90. DB DT_APPDIR
  91. DB 0
  92. public BootOrder, DefaultOrder
  93. ;** Static variables
  94. szCurDir DB 128 DUP (0) ;Points to fully qualified current dir
  95. pCurDirName DW 0 ;Points to 8.3 filename
  96. wCurDirLen DW 0 ;Length of path minus 8.3 filename
  97. public pCurDirName, wCurDirLen, szCurDir
  98. ifdef WOW
  99. LastOFSearchEntry DW 0 ;Addr of last search table entry used
  100. ;for continuing the search.
  101. OFContinueSearch DW 0 ;1 means continue last search
  102. public LastOFSearchEntry, OFContinueSearch
  103. endif
  104. DataEnd
  105. sBegin CODE
  106. assumes CS,CODE
  107. assumes DS,NOTHING
  108. assumes ES,NOTHING
  109. externNP MyUpper
  110. externNP PathDrvDSDX
  111. externNP real_DOS
  112. ifdef FE_SB
  113. externNP MyIsDBCSLeadByte
  114. externNP MyIsDBCSTrailByte
  115. endif
  116. ; These constants are the same as the OF_* values, but are a single byte
  117. ; for efficiency
  118. fReOpen equ 10000000b
  119. fExist equ 01000000b
  120. fPrompt equ 00100000b
  121. fCreate equ 00010000b
  122. fCancel equ 00001000b
  123. fVerify equ 00000100b
  124. fSearch equ 00000100b
  125. fDelete equ 00000010b
  126. fParse equ 00000001b
  127. ;** Flags to InternalOpenFile
  128. IOF_SYSTEM EQU 1
  129. ;!!!!!! Everything from here to the next !!!!! rewritten Aug 2-5 1991 [jont]
  130. ;-----------------------------------------------------------------------;
  131. ; OpenFile
  132. ; ;
  133. ; OpenFile: Opens the given file (with LOTS of options) ;
  134. ; The search order is defined above in the data section and is ;
  135. ; table-driven. ;
  136. ; ;
  137. ; Arguments: ;
  138. ; ParmD lpstrSourceName ;
  139. ; ParmD lpOFStruct ;
  140. ; ParmW Command ;
  141. ; ;
  142. ; Returns: ;
  143. ; AX = file handle ;
  144. ; ;
  145. ; Error Returns: ;
  146. ; AX = error code ;
  147. ; ;
  148. ; Registers Preserved: ;
  149. ; DI,SI,DS ;
  150. ; ;
  151. ; Registers Destroyed: ;
  152. ; ;
  153. ; Calls: ;
  154. ; ;
  155. ; History: ;
  156. ; ;
  157. ; Mon Oct 12, 1987 09:06:05p -by- David N. Weise [davidw] ;
  158. ; Added this nifty coment block. ;
  159. ; ;
  160. ; August 5, 1991 -by- Jon Thomason [jont] ;
  161. ; Rewrote large sections. Made it table-driven to allow ;
  162. ; changing search paths. Made it return extended error codes ;
  163. ; for all file not found errors. Generally made it into a ;
  164. ; humanly-readable module. ;
  165. ; ;
  166. ;-----------------------------------------------------------------------;
  167. cProc IOpenFile, <PUBLIC,FAR>, <si,di,ds>
  168. parmD lpSrcFile ;String pointing to filename
  169. parmD lpOFStruct ;Points to OFSTRUCT
  170. parmW wFlags ;LowB is DOS flags, High is OF flags
  171. localD lpDestDir ;Points to dest dir in OFSTRUCT
  172. cBegin
  173. SetKernelDS
  174. ;** If the file is to be reopened, do it
  175. test BYTE PTR wFlags[1],fReopen ;Reopen file?
  176. jz IOF_NoReopen ;No
  177. les di,lpOFStruct ;Point to structure
  178. cCall ReOpenFile, <es,di,wFlags> ;Reopen the file
  179. jmp IOF_End ;Done
  180. IOF_NoReopen:
  181. ifdef WOW
  182. ; Reset LastOFSearchEntry if we're not continuing an earlier search
  183. cmp OFContinueSearch,0
  184. jne @F
  185. mov LastOFSearchEntry,0
  186. @@:
  187. endif
  188. ;** Get a pointer into the OFSTRUCT
  189. mov di,WORD PTR lpOFStruct[0] ;Point to structure
  190. lea di,[di].opFile ;Point to string
  191. mov WORD PTR lpDestDir[0],di ;Save in temp variable
  192. mov di,WORD PTR lpOFStruct[2] ;Get the selector
  193. mov WORD PTR lpDestDir[2],di
  194. ;** Parse the filename and prepare for searching
  195. mov bx,dataOFFSET szCurDir ;Point to dest string
  196. les si,lpSrcFile ;Point to source string
  197. if 0
  198. krDebugOut DEB_WARN,"WOW16 IOpenFile:Filename @ES:SI"
  199. endif
  200. cCall ParseFileName, <es,si,ds,bx,wFlags>
  201. ;** Check for error
  202. or ax,ax ;Error?
  203. jnz @F ;No
  204. mov ax,0 ;Flag that this is a parse error
  205. mov bx,dataOFFSET szCurDir ;pass lpSrcFile as error string
  206. cCall ErrorReturn, <lpOFStruct,ds,bx,lpSrcFile,wFlags,ax>
  207. jmp IOF_End ;Get out
  208. @@:
  209. ;** If they just wanted to parse, fill in the structure and return
  210. test BYTE PTR wFlags[1],fParse ;Parse only?
  211. jz @F ;No, skip this
  212. mov bx,dataOFFSET szCurDir ;Point to full pathname with DX:BX
  213. mov dx,ds
  214. xor ax,ax ;No file handle
  215. jmp IOF_DoCopy ;Mimic successful file open
  216. @@:
  217. ;** Save return values for future use
  218. mov pCurDirName,bx ;Points to 8.3 name
  219. mov wCurDirLen,cx ;Length of path portion
  220. ;** See if we should path search (flag returned in DX)
  221. or dx,dx
  222. jz IOF_InitSearch ;Do the search
  223. ;** Try to open the file without searching any other dirs
  224. les bx,lpDestDir ;Point to dest dir
  225. mov di,dataOFFSET dtDirTable ;Point to the start of the DirTable
  226. cCall GetPath, <DT_CURDIR,di,es,bx> ;Dest dir returned in ES:BX
  227. cCall OpenCall, <es,bx,wFlags> ;Try to open it
  228. jc @F
  229. jmp IOF_Success
  230. @@: jmp IOF_Error ;File found but problem opening
  231. ;** Point to the proper search order
  232. IOF_InitSearch:
  233. SetKernelDS
  234. ifdef WOW
  235. cmp OFContinueSearch,0
  236. je @F
  237. mov OFContinueSearch,0 ;consumed the flag, reset it
  238. mov si,LastOFSearchEntry
  239. or si,si ;Were we searching at all?
  240. jnz IOF_WereSearching ;Yes
  241. jmp short IOF_FileNotFound ;No searching, so give up now.
  242. IOF_WereSearching:
  243. cmp si,-1 ;Already tried SearchPath?
  244. jne IOF_RestartSearch ;No, pick up where we left off in order
  245. IOF_FileNotFound:
  246. mov ax,2 ;SearchPath found it last time, so
  247. jmp IOF_Error ;it won't find a different one this
  248. ;time, se we return File not found
  249. IOF_RestartSearch:
  250. inc si
  251. mov LastOFSearchEntry,si
  252. mov al,[si]
  253. cbw
  254. or al,al
  255. mov di,dataOFFSET dtDirTable;Point to the start of the DirTable
  256. jnz IOF_SearchLoop ;Pick up with next in search order
  257. jmp short IOF_SearchPath ;Restarting after last in search
  258. ;order, so try DOS/Novell path.
  259. @@:
  260. endif
  261. mov si,dataOFFSET DefaultOrder
  262. cmp fBooting,0 ;Booting?
  263. jz IOF_DoSearch ;No
  264. mov si,dataOFFSET BootOrder
  265. IOF_DoSearch:
  266. ifdef WOW
  267. mov LastOFSearchEntry,si
  268. endif
  269. mov al,[si] ;Get the first search code
  270. cbw
  271. mov di,dataOFFSET dtDirTable ;Point to the start of the DirTable
  272. ;** Loop through until we have no more directories to search or
  273. ;** until the file is found
  274. IOF_SearchLoop:
  275. ;** Get the path and filename for this index entry
  276. les bx,lpDestDir ;Point to dest dir
  277. cCall GetPath, <ax,di,es,bx> ;Returns pointer to dest dir in ES:BX
  278. or bx,bx ;Duplicate dir?
  279. jz IOF_Continue ;Yes, skip this
  280. ;** Try to open the file
  281. cCall OpenCall, <es,bx,wFlags> ;Try to open it
  282. jnc IOF_Success ;File was found
  283. cmp ax,3 ;Errors 3 or less mean file not found
  284. ja IOF_Error ;File found but problem opening
  285. ;** File not found, so try next path if any
  286. IOF_Continue:
  287. add di,SIZE DIRTABLE ;Bump to next DirTable entry
  288. inc si ;Bump to next code in list
  289. ifdef WOW
  290. mov LastOFSearchEntry,si
  291. endif
  292. mov al,[si] ;Get this code
  293. cbw ;Make it a WORD
  294. or al,al ;Done?
  295. jnz IOF_SearchLoop ;No
  296. ;** Try the DOS/Novell path next
  297. ifdef WOW
  298. IOF_SearchPath:
  299. xor si,si
  300. dec si
  301. mov LastOFSearchEntry,si
  302. endif
  303. les di,lpDestDir ;Point to the dest dir
  304. mov si,pCurDirName ;Point to the 8.3 name
  305. cCall SearchFullPath, <ds,si,es,di,wFlags>
  306. jc IOF_Error ;Not found here either
  307. ;** On SUCCESS, we come here. Delete the file and close if
  308. ;** necessary
  309. IOF_Success:
  310. mov bx,WORD PTR lpDestDir[0] ;Point to filename with DX:BX
  311. mov dx,WORD PTR lpDestDir[2]
  312. IOF_DoCopy:
  313. les si,lpOFStruct ;Point to OFSTRUCT
  314. cCall SuccessCleanup, <dx,bx,es,si,wFlags,ax> ;Finish up
  315. jmp SHORT IOF_End
  316. ;** On ERROR, complete the structure and return the error code
  317. IOF_Error:
  318. les si,lpOFStruct
  319. mov bx,dataOFFSET szCurDir ;Point to current dir
  320. cCall ErrorReturn, <es,si,ds,bx,ds,pCurDirName,wFlags,ax>
  321. IOF_End:
  322. cEnd
  323. ;---------------------------------------------------------------------------
  324. ; ReOpenFile
  325. ;
  326. ; Does a fast reopen of a file that has already been opened.
  327. ; Returns proper value in AX for return from OpenFile
  328. ;
  329. ; Trashes everything but si,di,ds
  330. ;
  331. ;---------------------------------------------------------------------------
  332. cProc ReOpenFile, <PUBLIC,NEAR>, <si,di,ds>
  333. parmD lpStruct ;LPOFSTRUCT parameter
  334. parmW wFlags ;OpenFile flags
  335. localW hFile
  336. cBegin
  337. ;** Set up for the reopen
  338. lds si,lpStruct ;Point to the OFSTRUCT
  339. lea dx,[si].opFile ;DS:DX -> path
  340. call PathDrvDSDX ;Make sure DRV letter is valid
  341. jc ROF_SetDrvErr
  342. ;** Set up for either an OPEN or a CREATE
  343. mov al,BYTE PTR wFlags[0] ;Get the access bits
  344. test BYTE PTR wFlags[1],fCreate ;Create file or open
  345. jnz ROF_CreateIt ;In create case, we just do it
  346. mov ah,3dh ;Open file call
  347. jmp SHORT @F
  348. ROF_CreateIt:
  349. mov ah,3ch ;Create file call
  350. @@: xor cx,cx ;Default file attributes
  351. call real_DOS ;Skip overhead of Int21Handler
  352. jnc ROF_10 ;Continue on no error
  353. jmp SHORT ROF_GetError ;Get out on error
  354. ROF_SetDrvErr:
  355. lds si,lpStruct ;Point to the OFSTRUCT
  356. mov [si].opXtra,ax ;In OFSTRUCT, this is the error code
  357. mov ax,-1 ;Error return
  358. jmp ROF_End ;Error
  359. ROF_10: mov bx,ax ;Get handle
  360. mov hFile,ax ;Save handle for later
  361. ifdef WOW
  362. xor cx,cx
  363. xor dx,dx
  364. push ds
  365. SetKernelDS ds
  366. cmp fLMdepth,cx ; Called From Loader ?
  367. pop ds
  368. UnSetKernelDS ds
  369. jnz @f ; Yes -> Ignore Date/Time
  370. endif
  371. mov ax,5700h ;Get time and date of file
  372. DOSCALL
  373. @@:
  374. mov ax,bx ;Put file handle back in ax
  375. test BYTE PTR wFlags[1],fVerify ;Should we test time/date?
  376. jz ROF_VerifyOK
  377. cmp [si].opDate,dx ;Same date as original?
  378. jnz ROF_ErrorClose ;No
  379. cmp [si].opTime,cx ;Same time as original?
  380. jnz ROF_ErrorClose ;No
  381. ROF_VerifyOK:
  382. mov es:[si].opTime,cx ;Save the date and time
  383. mov es:[si].opDate,dx
  384. ;** See if we were supposed to just get the name, or find file
  385. test BYTE PTR wFlags[1],fDelete or fExist
  386. jz ROF_Done ;Nope, we're done
  387. ;** If the user specified OF_DELETE, we don't want
  388. ;** the file open, so close it here.
  389. ;** NOTE: THIS CODE IS DUPLICATED IN FillOFStruct()!!!!
  390. mov bx,hFile ;Get handle
  391. mov ah,3Eh ;Close the file
  392. DOSCALL
  393. ;** See if we should delete the file
  394. test BYTE PTR wFlags[1],fDelete
  395. jz ROF_Done ;Nope, we're done
  396. smov ds,es ;DS:DX points to full pathname
  397. UnSetKernelDS
  398. lea dx,[si].opFile
  399. mov ah,41h ;Delete the file
  400. DOSCALL
  401. jnc ROF_Done ;Return the file handle for compat.
  402. ;** Get extended error always
  403. ROF_GetError:
  404. mov ah,59h ;See if there is an extended error
  405. xor bx,bx
  406. push bp ;GetExtendedError trashes regs
  407. push si
  408. push es
  409. DOSCALL
  410. pop es
  411. pop si
  412. pop bp
  413. mov [si].opXtra,ax ;In OFSTRUCT, this is the error code
  414. mov ax,-1 ;Error return
  415. jmp SHORT ROF_End
  416. ROF_ErrorClose:
  417. mov bx,hFile ;Get the file handle
  418. mov ah,3Eh ;Close the bogus file
  419. DOSCALL
  420. mov ax,-1 ;Error return value
  421. lds si,lpStruct ;Point to the OFSTRUCT
  422. mov [si].opXtra,0 ;Non-DOS error
  423. jmp SHORT ROF_End ;Get out
  424. ROF_Done:
  425. mov ax,hFile ;Proper return value for OpenFile
  426. ROF_End:
  427. cEnd
  428. ;----------------------------------------------------------------------------
  429. ; ParseFileName
  430. ;
  431. ; Prepares to do the various file searches by returning a pointer
  432. ; to the fully qualified path and to the "pure" filename
  433. ; (just the 8.3 name).
  434. ;
  435. ; Returns:
  436. ; AX = TRUE/FALSE function successful (if F, nothing else valid)
  437. ; BX points to start of 8.3 filename
  438. ; CX = Length of path portion of filename
  439. ; DX = TRUE/FALSE: Indicates whether path should be searched
  440. ;
  441. ;----------------------------------------------------------------------------
  442. cProc ParseFileName, <PUBLIC,NEAR>, <si,di,ds>
  443. parmD lpSrcName ;Passed in pathname
  444. parmD lpDestName ;String to receive pathname
  445. parmW wFlags ;Command WORD to OpenFile
  446. localW wPathLen ;Length of path portion of filename
  447. cBegin
  448. ;** Get the fully qualified pathname in lpDestName
  449. lds si,lpSrcName ;DS:SI points to source file
  450. les di,lpDestName ;ES:DI points to file buffer
  451. call ParseFile ;Form a complete name in buffer
  452. ; Returns dir len in CX when failing
  453. or ax,ax ;Successful?
  454. jz PFN_End ;No, get out
  455. mov wPathLen,dx ;Save length of path (no 8.3)
  456. ;** This section handles the fSearch flag. This flag is used to
  457. ;** do a path search even when we have a path in front of
  458. ;** the filename.
  459. test BYTE PTR wFlags[1],fSearch ;Do search even with path?
  460. jz PF_NoSearch ;No.
  461. xor di,di ;Indicate no slashes
  462. PF_NoSearch:
  463. ;** Convert the filename to OEM
  464. lds si,lpDestName ;Point to full path
  465. cCall MyAnsiToOem,<ds,si,ds,si>
  466. ;** Return arguments
  467. mov ax,1 ;Success
  468. mov bx,WORD PTR lpDestName[0] ;Get the offset of the string
  469. mov cx,wPathLen ;Length of path portion of name
  470. add bx,cx ;Point to start of string
  471. inc bx ;Skip slash
  472. mov dx,di ;Slashes/path search flag
  473. PFN_End:
  474. cEnd
  475. ;----------------------------------------------------------------------------
  476. ; GetPointer
  477. ;
  478. ; Given an index number, returns a pointer to the path associated
  479. ; with this index and its length
  480. ;
  481. ; Returns the lpstr in ES:BX, length in CX
  482. ;
  483. ; Depends on the order of the DT_* indices
  484. ; Depends on Kernel's DS being set, does not trash it
  485. ;
  486. ;----------------------------------------------------------------------------
  487. cProc GetPointer, <PUBLIC,NEAR>, <si,di>
  488. parmW wIndex ;Index is from search order table
  489. cBegin
  490. CheckKernelDS
  491. ReSetKernelDS
  492. ;** Decode the index numbers
  493. mov ax,wIndex ;Get the index
  494. dec ax ;DT_CURDIR?
  495. jz GT_CURDIR
  496. dec ax ;DT_WINDIR?
  497. jz GT_WINDIR
  498. ifndef WOW
  499. dec ax ;DT_SYSDIR?
  500. jz GT_SYSDIR
  501. else
  502. dec ax ;DT_SYS16DIR?
  503. jz GT_SYS16DIR
  504. dec ax ;DT_SYSDIR?
  505. jz GT_SYSDIR
  506. dec ax ;DT_SYSWX86DIR?
  507. jz GT_SYSWX86DIR
  508. endif
  509. ; Must be DT_APPDIR
  510. ;** Find the app's dir
  511. IF KDEBUG
  512. cmp fBooting,0 ;Booting?
  513. jz @F ;No, whew!
  514. int 1 ;No app dir during boot process
  515. int 1
  516. @@:
  517. ENDIF
  518. ;** Figure out if we should use curTDB or loadTDB. This is
  519. ;** determined by the number of times LoadModule has recursed.
  520. ;** We only use the loadTDB pointer if we're in LoadModule the
  521. ;** second time and the pointer is not zero. Otherwise, we
  522. ;** use the curTDB pointer. If we don't do this check, we
  523. ;** end up getting the path of the app calling LoadModule
  524. cmp fLMDepth,2 ;In LoadModule 2 times?
  525. jb GT_UseCurTDB ;Yes, use curTDB
  526. mov ax,LoadTDB ;Get loadTDB
  527. or ax,ax ;NULL?
  528. jnz GT_UseLoadTDB ;No, assume it's OK
  529. ;** Get a pointer to the path stored in the module database
  530. GT_UseCurTDB:
  531. mov ax,curTDB ;Get the TDB pointer
  532. GT_UseLoadTDB:
  533. mov es,ax ;Point with DS
  534. mov es,es:[TDB_pModule] ;Point to the module database
  535. ; BUGBUG ROM was always define (either 1 or 0) so this code always made
  536. ; it even in 9X sources
  537. ;
  538. ;IFDEF ROM
  539. ; if this is in ROM, then return 0 in CX
  540. ; makes no sense to get the app's dir, if app is in ROM
  541. test es:[ne_flags], NEMODINROM
  542. jz @f
  543. xor cx, cx
  544. jmp SHORT GT_Done
  545. @@:
  546. ;ENDIF
  547. mov di,es:[0ah] ;Points to EXE path string (sort of)
  548. ; (High word of CRC in exe hdr)
  549. ;** Copy the entire string into the buffer
  550. add di,8 ;Move past data garbage
  551. push di ;Save start of string
  552. cCall GetPureName ;ES:DI points just after the '\'
  553. dec di ;ES:DI points to '\'
  554. pop bx ;ES:BX points to start of string
  555. mov cx,di ;Compute length of path, not filename
  556. sub cx,bx ; (not including \)
  557. jmp SHORT GT_Done
  558. ;** Get the current directory pointer and length
  559. GT_CURDIR:
  560. smov es,ds ;ES:BX points to szCurDir
  561. mov bx,dataOFFSET szCurDir
  562. mov cx,wCurDirLen ;Get path length
  563. jmp SHORT GT_Done
  564. GT_WINDIR:
  565. les bx,lpWindowsDir ;Point to windir
  566. mov cx,cBytesWinDir
  567. jmp SHORT GT_Done
  568. GT_SYSDIR:
  569. les bx,lpSystemDir ;Point to sysdir
  570. mov cx,cBytesSysDir
  571. ifdef WOW
  572. jmp SHORT GT_Done
  573. GT_SYS16DIR:
  574. les bx,lpSystem16Dir ;Point to sys16dir
  575. mov cx,cBytesSys16Dir
  576. jmp SHORT GT_Done
  577. GT_SYSWX86DIR:
  578. les bx,lpSystemWx86Dir
  579. mov cx,cBytesSysWx86Dir
  580. ;jmp SHORT GT_Done
  581. endif ;WOW
  582. GT_Done:
  583. cEnd
  584. ;----------------------------------------------------------------------------
  585. ; GetPath
  586. ;
  587. ; Gets the path associated with the given index. The 8.3 filename
  588. ; is appended to the end of the path and this is copied into the
  589. ; destination directory. A pointer to this directory is returned
  590. ; in ES:BX or BX is NULL if the directory to be searched would be
  591. ; a duplicate.
  592. ;
  593. ; Assumes (and does not trash) kernel's DS
  594. ;
  595. ; Calls: GetPointer
  596. ;
  597. ;----------------------------------------------------------------------------
  598. cProc GetPath, <PUBLIC,NEAR>, <si,di>
  599. parmW wIndex ;Index from search order table
  600. parmW pDirTable ;Points to current DIRTABLE entry
  601. parmD lpDest ;Place to copy filename
  602. cBegin
  603. CheckKernelDS
  604. ;** Gets the pointer and length of the requested string
  605. cCall GetPointer, <wIndex> ;lpstr in ES:BX, len in CX
  606. ; BUGBUG ROM was always define (either 1 or 0) so this code always made
  607. ; it even in 9X sources
  608. ;
  609. ;IFDEF ROM
  610. or cx, cx ; if in ROM && APPDIR
  611. jnz @f
  612. xor bx, bx
  613. jmp SHORT GP_End
  614. @@:
  615. ;ENDIF
  616. ;** Save it in the table
  617. mov di,pDirTable ;Point to the table entry
  618. mov WORD PTR [di].dt_lpstr[0],bx
  619. mov WORD PTR [di].dt_lpstr[2],es
  620. mov [di].dt_wLen,cx
  621. ;** Check for duplicates
  622. mov si,bx ;Point to string with SI
  623. mov bx,dataOFFSET dtDirTable ;Point to the start of the table
  624. GP_Loop:
  625. cmp bx,di ;Checked everything before us yet?
  626. je GP_Done ;Yes
  627. ;** Compare the strings
  628. cmp cx,[bx].dt_wLen ;Compare lengths
  629. jne GP_Continue ;No dup here
  630. mov dx,cx ;Save len in DX
  631. push si
  632. push di
  633. push ds
  634. les di,ds:[di].dt_lpstr ;Point to the strings to be compared
  635. lds si,ds:[bx].dt_lpstr
  636. repe cmpsb ;Compare the strings
  637. pop ds
  638. pop di
  639. pop si
  640. or cx,cx ;At end of string?
  641. jz GP_FoundMatch ;Yes, we matched so ignore this string
  642. mov cx,dx ;Get len back in CX
  643. GP_Continue:
  644. add bx,SIZE DIRTABLE ;Bump to next table entry
  645. jmp GP_Loop
  646. GP_FoundMatch:
  647. mov WORD PTR [di].dt_lpstr[0],0 ;Null out this entry
  648. mov WORD PTR [di].dt_lpstr[2],0
  649. mov [di].dt_wLen,0
  650. xor bx,bx ;Return NULL
  651. jmp SHORT GP_End
  652. GP_Done:
  653. ;** Copy the string in
  654. push ds ;Save DS around this
  655. lds si,[di].dt_lpstr ;Return ES:BX pointing to string
  656. les di,lpDest ;Point to buffer to copy string to
  657. mov bx,di ;Point with BX to struct
  658. rep movsb ;Copy the strings
  659. pop ds ;Restore KERNEL's DS
  660. ;** Put a '\' only if needed
  661. IFDEF FE_SB
  662. push si
  663. push di
  664. mov si,word ptr lpDest[0] ;es:si -> string address
  665. dec di ;di points to the last valid byte
  666. call MyIsDBCSTrailByte ;the last byts a DBCS trailing byte?
  667. pop di
  668. pop si
  669. jnc GP_DoSlash ;yes, go ahead to append a '\'
  670. ;no, fall through
  671. ENDIF
  672. cmp BYTE PTR es:[di - 1],'\';Terminating slash?
  673. je GP_SkipSlash ;Yes
  674. cmp BYTE PTR es:[di - 1],'/';Terminating slash?
  675. je GP_SkipSlash ;Yes
  676. GP_DoSlash:
  677. mov al,'\' ;Get the slash
  678. stosb ; and write it
  679. GP_SkipSlash:
  680. ;** Copy the filename
  681. mov si,pCurDirName ;Point to the 8.3 filename
  682. call strcpyreg
  683. ;GP_83Loop:
  684. ; lodsb ;Get the char
  685. ; stosb ; and write it
  686. ; or al,al ;Done?
  687. ; jnz GP_83Loop ;Nope
  688. ;Returns ES:BX points to filename
  689. GP_End:
  690. cEnd
  691. ;----------------------------------------------------------------------------
  692. ; OpenCall
  693. ;
  694. ; Does the open/create file call. The file is either opened
  695. ; or created. The handle or the error code is returned.
  696. ; The extended error code is returned only if the error was not
  697. ; that the file or path was not found (errors 2 & 3).
  698. ; Carry is set on error.
  699. ;
  700. ;----------------------------------------------------------------------------
  701. cProc OpenCall, <PUBLIC,NEAR>, <si,di,ds>
  702. parmD lpString ;String to open
  703. parmW wFlags ;OpenFile flags
  704. localW wInt21AX ;Int 21 AX value
  705. cBegin
  706. ;** HACK to allow SearchPath to use this call.
  707. ;** If wFlags is -1, look for flags preset in AX
  708. cmp wFlags,-1 ;wFlags?
  709. jnz OC_Normal ;Yes, proceed normally
  710. mov wInt21AX,ax ;Save these flags
  711. jmp SHORT OC_10 ; and go on
  712. ;** Set up for either an OPEN or a CREATE
  713. OC_Normal:
  714. mov al,BYTE PTR wFlags[0] ;Get the access bits
  715. test BYTE PTR wFlags[1],fCreate ;Create file or open
  716. jnz OC_CreateIt ;In create case, we just do it
  717. mov ah,3dh ;Open file call
  718. mov wInt21AX,ax ;Save in temp var
  719. jmp SHORT OC_10
  720. OC_CreateIt:
  721. mov ah,3ch ;Create file call
  722. and al,3 ;Strip incompatbile share bits, etc.
  723. mov wInt21AX,ax ;Save it
  724. jmp SHORT OC_DoDOSCall ;Just do it in create case
  725. OC_10: SetKernelDS
  726. cmp fNovell,0 ;On Novell?
  727. je OC_DoDOSCall ;No, just do normal stuff
  728. ;** We do a Get Attribute call instead of trying to open the file
  729. ;** because doing a normal file open on Novell causes them
  730. ;** to search their entire path.
  731. lds dx,lpString ;Get the pathname
  732. mov ax,4300h ;Get file attributes
  733. DOSCALL ;Does the file exist?
  734. jc OC_NotThere ;No
  735. ;** Try to open the file here. In case of Novell, we already know
  736. ;** it's here, so now open it
  737. OC_DoDOSCall:
  738. xor cx,cx ;Normal files ONLY!!
  739. mov ax,wInt21AX ;Get function code + access flags
  740. lds dx,lpString ;Get the pathname
  741. DOSCALL ;Try to open the file
  742. jc OC_NotThere ;File can't be opened
  743. jmp SHORT OC_FileOpened ;Success
  744. OC_NotThere:
  745. cmp ax,3 ;Errors 2 & 3 are file not found
  746. jbe OC_NoExtError ;No extended error for file not found
  747. SetKernelDS
  748. cmp wMyOpenFileReent, 0 ;No ext err for MyOpenFile
  749. jnz OC_NoExtError
  750. mov ah,59h ;See if there is an extended error
  751. xor bx,bx
  752. push bp ;GetExtendedError trashes bp
  753. DOSCALL
  754. pop bp
  755. OC_NoExtError:
  756. stc ;Return error
  757. OC_FileOpened: ;CY must be clear here on success
  758. cEnd
  759. ;----------------------------------------------------------------------------
  760. ; SearchFullPath
  761. ;
  762. ; Searches the full DOS/Novell path for the file
  763. ;
  764. ; Returns the file handle on success or the error code on failure
  765. ; Carry set on error
  766. ;
  767. ;----------------------------------------------------------------------------
  768. cProc SearchFullPath, <PUBLIC,NEAR>, <si,di,ds>
  769. parmD lpSource ;8.3 filename
  770. parmD lpDest ;Place to copy pathname
  771. parmW wFlags ;OpenFile flags
  772. localW wInt21AX
  773. cBegin
  774. ;** Get the AX WORD for the DOS call
  775. mov al,BYTE PTR wFlags[0] ;Get the access bits
  776. test BYTE PTR wFlags[1],fCreate ;Create file or open?
  777. mov ah,3dh ;Default to open
  778. jz @F
  779. mov ah,3ch ;Create call
  780. @@: mov wInt21AX,ax ;Save it for later
  781. ;** Use SearchPath() to find the file for us
  782. push ds ;Save DS across this
  783. les di,lpDest ;Point to usable dest buffer
  784. lds si,lpSource ;Point to source string
  785. UnsetKernelDS
  786. cCall <FAR PTR SearchPath>,<ds,si,es,di,ax>
  787. pop ds
  788. ResetKernelDS
  789. cmp ax,-1
  790. jne SFP_FoundIt ;Found the file
  791. mov ax,bx ;Get error code from SearchPath
  792. cmp ax,3 ;Not found?
  793. ja SFP_Error ;Found but error
  794. ;** Now try the Novell path if it's there
  795. cmp fNovell,0 ;On Novell?
  796. je SFP_Error ;Nope. Nothing more to try so error
  797. lds dx,lpSource ;Point to 8.3 filename
  798. UnsetKernelDS
  799. xor cx,cx ;Normal file type
  800. mov ax,wInt21AX ;Get open or create call plus attrs
  801. DOSCALL ;Do it
  802. jc SFP_Error ;Didn't find it
  803. SFP_FoundIt:
  804. clc
  805. jmp SHORT SFP_End
  806. SFP_Error:
  807. stc
  808. SFP_End: ;Carry should be set/clear correctly
  809. cEnd
  810. ;----------------------------------------------------------------------------
  811. ; SuccessCleanup
  812. ;
  813. ; Builds the OFSTRUCT structure on a successful open.
  814. ; Closes and deletes file if requested.
  815. ;
  816. ;----------------------------------------------------------------------------
  817. cProc SuccessCleanup, <PUBLIC,NEAR>, <si,di,ds>
  818. parmD lpGoodPathName ;Successful path name
  819. parmD lpOFStruct ;OFSTRUCT param to OpenFile
  820. parmW wFlags ;OpenFile flags
  821. parmW hFile ;File handle
  822. cBegin
  823. ;** Compute the length of the string and OFSTRUCT
  824. les di,lpGoodPathName ;Point to the new pathname
  825. xor al,al ;Get a zero byte
  826. xor cx,cx ;Up to 64K
  827. dec cx
  828. repne scasb ;Search for the zero byte
  829. neg cx
  830. mov ax,cx ;Get a copy in AX
  831. add ax,(SIZE OPENSTRUC) - 3 ;Length of structure including string
  832. ;** Copy the successful pathname into the OFSTRUCT if necessary
  833. dec cx ;This now is string + zero byte len
  834. les di,lpOFStruct ;Point to dest buffer
  835. lea di,[di].opFile
  836. cmp di,WORD PTR lpGoodPathName[0] ;Offsets the same?
  837. jne FOF_DoCopy ;No, do it
  838. mov dx,es ;Compare sels
  839. cmp dx,WORD PTR lpGoodPathName[2] ;Same?
  840. je FOF_NoCopy ;Yes, no copy needed
  841. FOF_DoCopy:
  842. lds si,lpGoodPathName ;Point to successful path again
  843. UnSetKernelDS
  844. rep movsb ;Copy it
  845. FOF_NoCopy:
  846. ;** Fill out remainder of OFSTRUCT
  847. les si,lpOFStruct ;Point to OFSTRUCT with ES:SI
  848. lea di,[si].opFile ; and to the pathname with ES:DI
  849. mov es:[si].opXtra,0 ;Zero the error
  850. mov es:[si].opLen,al ;Save structure length
  851. call AreBooting ;AreBooting checks Int21 hooks inst
  852. mov ah,1 ;Always booting from hard drive
  853. jz FO_NoCheckDrive ;Int 21 hooks NOT installed yet
  854. mov al,es:[di] ;ES:DI points to string
  855. or al,20H ;Force it lowercase
  856. sub al,'a' ;Drive number, zero based
  857. cbw
  858. mov di,ax ;Drive number in DI
  859. call IsFloppy ;Returns floppy status in ZF
  860. mov ah,0 ;Zero in case it's a floppy
  861. jz FO_NoCheckDrive ;Must be a floppy disk
  862. inc ah ;Non-removable media
  863. FO_NoCheckDrive:
  864. mov es:[si].opDisk,ah ;Tell 'em the type of disk
  865. ;** Get the current file date and time
  866. mov bx,hFile ;Get file handle
  867. mov ax,5700h ;Get date and time
  868. ifdef WOW
  869. xor cx,cx
  870. xor dx,dx
  871. push ds
  872. SetKernelDS ds
  873. cmp fLMdepth,cx ; Called From Loader ?
  874. pop ds
  875. UnSetKernelDS ds
  876. jnz @f ; Yes -> Ignore Date/Time
  877. endif
  878. DOSCALL
  879. @@:
  880. mov es:[si].opTime,cx ;Save the date and time
  881. mov es:[si].opDate,dx
  882. ;** See if we were supposed to just get the name, or find file
  883. test BYTE PTR wFlags[1],fExist OR fDelete
  884. jz FO_Done ;Nope, we're done
  885. ;** If the user specified OF_EXIST or OF_DELETE, we don't want
  886. ;** the file open, so close it here
  887. ;** NOTE: THIS CODE IS DUPLICATED IN ReopenFile()!!!!
  888. mov bx,hFile ;Get the handle
  889. mov ah,3Eh ;Close the file
  890. DOSCALL
  891. ;We leave the bogus value in hFile
  892. ; for 3.0 compatibility
  893. ;** If OF_DELETE is set, we simply delete the file
  894. test BYTE PTR wFlags[1],fDelete
  895. jz FO_Done
  896. smov ds,es ;DS:DX points to full pathname
  897. UnSetKernelDS
  898. lea dx,[si].opFile
  899. mov ah,41h ;Delete the file
  900. DOSCALL
  901. mov ax,1 ;TRUE return value
  902. jnc FO_Done ;For 3.0 compatiblity
  903. mov ah,59h ;See if there is an extended error
  904. xor bx,bx
  905. push bp ;GetExtendedError trashes regs
  906. push si
  907. DOSCALL
  908. pop si
  909. pop bp
  910. mov [si].opXtra,ax ;In OFSTRUCT, this is the error code
  911. mov ax,-1 ;Error return
  912. jmp SHORT FO_END
  913. FO_Done:
  914. mov ax,hFile ;Proper return value for OpenFile
  915. FO_End:
  916. cEnd
  917. ;----------------------------------------------------------------------------
  918. ; ErrorReturn
  919. ;
  920. ; Fills in the return information for error conditions.
  921. ; Returns the proper return value for OpenFile
  922. ;
  923. ;----------------------------------------------------------------------------
  924. cProc ErrorReturn, <NEAR,PUBLIC>,<si,di,ds>
  925. parmD lpOFStruct ;OFSTRUCT given to OpenFile
  926. parmD lpPath ;Path returned, even when invalid
  927. parmD lpError ;Text for error box
  928. parmW wFlags ;OpenFile flags
  929. parmW wErrCode ;Error code already computed
  930. cBegin
  931. UnSetKernelDS
  932. cmp wErrCode,0 ;Parse error?
  933. jnz @F ;No
  934. mov wErrCode,2 ;Mimic "File not found" error
  935. jmp SHORT ER_ReturnError ;Never prompt on parse error
  936. @@: test BYTE PTR wFlags[1],fPrompt ;Should we do the dialog?
  937. jz ER_ReturnError ;No, return error code
  938. call AreBooting ;if we're still booting, don't prompt
  939. jz ER_ReturnError
  940. lds di,lpError
  941. cmp BYTE PTR ds:[di],0 ;Don't prompt with NULL string.
  942. je ER_ReturnError
  943. cCall Prompt, <ds,di> ;Prompt with error string.
  944. ER_ReturnError:
  945. SetKernelDS
  946. les si,lpOFStruct ;Point to structure again
  947. mov ax,wErrCode ;Get the error code
  948. mov es:[si].opXtra,ax ;In OFSTRUCT, this is the error code
  949. lea di,[si].opFile ;Point to dest string
  950. lds si,lpPath ;Point to the path
  951. call strcpyreg
  952. ;ER_Copy:
  953. ; lodsb ;Copy the sz string for PowerPoint
  954. ; stosb
  955. ; or al,al ;Done?
  956. ; jnz ER_Copy ;No
  957. UnSetKernelDS
  958. mov ax,-1
  959. cEnd
  960. ;!!!!!!!!!!!!!! Everything after this is old
  961. ;---------------------------------------------------------------------------
  962. ; AreBooting
  963. ;
  964. ; Check to see if DOS hook available
  965. ;
  966. ;---------------------------------------------------------------------------
  967. AreBooting PROC NEAR
  968. push ds
  969. SetKernelDS
  970. cmp fInt21,0
  971. pop ds
  972. UnSetKernelDS
  973. ret
  974. AreBooting ENDP
  975. ;---------------------------------------------------------------------------
  976. ; FarGetEnv
  977. ;
  978. ; Gets the correct environment, boot time or no
  979. ;
  980. ;---------------------------------------------------------------------------
  981. FarGetEnv PROC FAR
  982. SetKernelDS
  983. mov si,curTDB
  984. or si,si
  985. jz boot_time
  986. mov ds,si
  987. UnSetKernelDS
  988. mov ds,ds:[TDB_PDB]
  989. not_boot_time:
  990. mov ds,ds:[PDB_environ]
  991. xor si,si
  992. ret
  993. boot_time:
  994. ReSetKernelDS
  995. mov ds,TopPDB
  996. UnSetKernelDS
  997. jmps not_boot_time
  998. FarGetEnv ENDP
  999. ;-----------------------------------------------------------------------;
  1000. ; SearchPath ;
  1001. ; ;
  1002. ; Searches the PATH as defined in the environment for the given file. ;
  1003. ; ; ;
  1004. ; Arguments: ;
  1005. ; ParmD pName Pointer to name ;
  1006. ; ParmD pBuffer Pointer to temporary buffer ;
  1007. ; ParmW Attr AX paramter for DOS (Open, etc.) ;
  1008. ; ;
  1009. ; Returns: ;
  1010. ; AX != 0 ;
  1011. ; ;
  1012. ; Error Returns: ;
  1013. ; AX = -1, BX is error code ;
  1014. ; ;
  1015. ; Registers Preserved: ;
  1016. ; DS ;
  1017. ; ;
  1018. ; Registers Destroyed: ;
  1019. ; BX,CX,DX,DI,SI,ES ;
  1020. ; ;
  1021. ; Calls: ;
  1022. ; GetPureName ;
  1023. ; GetFarEnv ;
  1024. ; ;
  1025. ; History: ;
  1026. ; ;
  1027. ; Mon Oct 12, 1987 08:57:48p -by- David N. Weise [davidw] ;
  1028. ; Added this nifty comment block. ;
  1029. ;-----------------------------------------------------------------------;
  1030. cProc SearchPath,<PUBLIC,FAR>
  1031. ParmD pName ; Pointer to name
  1032. ParmD pBuffer ; Pointer to temporary buffer
  1033. ParmW Attr ; AX paramter for DOS (Open, etc.)
  1034. LocalD pPureName ; pointer to stripped name
  1035. cBegin
  1036. les di,pName
  1037. call GetPureName
  1038. mov pPureName.off,di
  1039. mov pPureName.sel,es
  1040. push cs
  1041. call near ptr FarGetEnv
  1042. mov bx, 3 ; preset error to "path not found"
  1043. spth2: cmp byte ptr [si],0 ; no more enviroment
  1044. jz spthNo
  1045. lodsw
  1046. cmp ax,'AP' ; Look for PATH=
  1047. jnz spth3
  1048. lodsw
  1049. cmp ax,'HT'
  1050. jnz spth3
  1051. lodsb
  1052. cmp al,'='
  1053. jz spth4
  1054. spth3: lodsb
  1055. or al,al
  1056. jnz spth3
  1057. jmp spth2
  1058. spth4: les di,pBuffer
  1059. spth5: lodsb
  1060. stosb
  1061. cmp al,";"
  1062. jz spth6
  1063. or al,al
  1064. jnz spth5
  1065. dec si
  1066. spth6: mov al,'\'
  1067. ifdef FE_SB
  1068. push si
  1069. push di
  1070. mov si,word ptr pBuffer ; buffer address
  1071. dec di ; point di to the byte before ';'
  1072. call MyIsDBCSTrailByte ; is it a DBCS trailing byte?
  1073. pop di
  1074. pop si
  1075. jnc spth6a ;yes, overwrite ';' with '\'
  1076. endif
  1077. cmp es:[di-2],al ; path terminated with '\'
  1078. jnz spth6a
  1079. dec di
  1080. spth6a: mov es:[di-1],al
  1081. push ds
  1082. push si
  1083. cCall MyAnsiToOem,<pPureName,es,di>
  1084. ;** Call the OpenCall function to search for the file. It calls
  1085. ;** the extended error function on failure
  1086. les si,pBuffer ;Point to buffer
  1087. mov ax,Attr ;Get the AX word here and flag
  1088. cCall OpenCall, <es,si,-1> ; OpenCall with -1
  1089. mov bx,ax ;Save the error code if any
  1090. pop si
  1091. pop ds
  1092. jnc spthYes
  1093. cmp byte ptr [si],0 ;At end of path?
  1094. jnz spth4
  1095. spthNo: mov ax,-1
  1096. ;** Bug 14960: If the last error code was path not found, the user
  1097. ;** has a bogus directory in their path. Since we were unable
  1098. ;** to find the file, return file not found instead of path not
  1099. ;** found. 2 November 1991 Clark R. Cyr
  1100. cmp bx, 3 ;Path Not Found?
  1101. jne spthYes
  1102. mov bx, 2 ;Make it File Not Found
  1103. spthYes:
  1104. cEnd
  1105. ; MyAnsiToOem
  1106. ; Used to do ANSI to OEM conversions. This function allows routines
  1107. ; here to call freely without worrying if the keyboard driver can
  1108. ; be called with this yet. At boot time, we can't call the
  1109. ; keyboard driver where these functions reside, so no translation
  1110. ; is done.
  1111. cProc MyAnsiToOem, <PUBLIC,NEAR>, <si,di,ds>
  1112. parmD pSrc
  1113. parmD pDst
  1114. cBegin
  1115. SetKernelDS
  1116. cmp pKeyProc.sel,0 ; is there a keyboard yet?
  1117. jnz mao1 ; Yes, so do translation
  1118. lds si, pSrc ; No, so just copy the strings
  1119. UnSetKernelDS
  1120. les di, pDst
  1121. call strcpyreg
  1122. ;mao0:
  1123. ; lodsb
  1124. ; stosb
  1125. ; or al, al
  1126. ; jnz mao0
  1127. jmps mao2
  1128. ; Not booting, we can call the
  1129. mao1: ; translation routine
  1130. ReSetKernelDS
  1131. cCall [pKeyProc],<pSrc,pDst> ; convert string from AnsiToOem
  1132. mao2:
  1133. cEnd
  1134. ; MyOemToAnsi
  1135. ; Matching function for MyAnsiToOem. See comments above
  1136. cProc MyOemToAnsi,<PUBLIC,NEAR>,<si,di,ds>
  1137. parmD pSrc
  1138. parmD pDst
  1139. cBegin
  1140. SetKernelDS
  1141. cmp pKeyProc.sel,0 ; is there a keyboard yet?
  1142. jnz moa1 ; Yes, do normal conversion
  1143. lds si, pSrc ; No, so just copy the string
  1144. UnSetKernelDS
  1145. les di, pDst
  1146. call strcpyreg
  1147. ;moa0:
  1148. ; lodsb
  1149. ; stosb
  1150. ; or al, al
  1151. ; jnz moa0
  1152. jmps moa2
  1153. moa1: ; Call the translation routine
  1154. ReSetKernelDS
  1155. cCall [pKeyProc1],<pSrc,pDst> ; convert string from AnsiToOem
  1156. moa2:
  1157. cEnd
  1158. ;---------------------------------------------------------------------
  1159. ;
  1160. ; Is Drive number in DI a floppy? A=0, etc. ZF = yes, it is a floppy
  1161. ;
  1162. public IsFloppy
  1163. IsFloppy:
  1164. ifdef WOW
  1165. push dx
  1166. cCall GetDriveType,<di>
  1167. pop dx
  1168. else
  1169. mov bx,1 ; 1 = Get Drive Info from InquireSystem
  1170. push es
  1171. push ds
  1172. SetKernelDS
  1173. cCall [pSysProc],<bx,di>
  1174. pop ds
  1175. UnSetKernelDS
  1176. pop es
  1177. endif
  1178. cmp al,2 ; 2 = removable media
  1179. ret
  1180. FarIsFloppy PROC FAR
  1181. call IsFloppy
  1182. ret
  1183. FarIsFloppy ENDP
  1184. ;----------------------------------------------------------------------------
  1185. ; Prompt
  1186. ;
  1187. ; Puts up the system error box telling the user the file can't be found
  1188. ;
  1189. ;----------------------------------------------------------------------------
  1190. cProc Prompt, <NEAR,PUBLIC>, <si,di,ds>
  1191. parmD lpstr
  1192. cBegin
  1193. SetKernelDS
  1194. mov ax,3 ;Assume CANCEL
  1195. cmp pSErrProc.sel,0 ;Is there a USER yet?
  1196. jz P_End ;No
  1197. ;** Format the string <szCannotFind1><lpstr><szCannotFind2>
  1198. push ds
  1199. pop es
  1200. mov di, dataOffset OutBuf ; ES:DI points to dest
  1201. mov si, dataOffset szCannotFind1
  1202. call strcpyreg
  1203. lds si, [lpstr]
  1204. mov al, byte ptr ds:[si]
  1205. UnSetKernelDS
  1206. mov es:[LastDriveSwapped], al
  1207. call strcpyreg
  1208. push es
  1209. pop ds
  1210. ReSetKernelDS
  1211. mov si, dataOffset szCannotFind2
  1212. call strcpyreg
  1213. ;** Prepare the dialog box
  1214. push ds ;In our DS
  1215. push dataOFFSET OutBuf ;Point to "Cannot find" string
  1216. push ds
  1217. push dataOffset szDiskCap ;Caption
  1218. push 0 ;No left button
  1219. push SEB_CLOSE + SEB_DEFBUTTON ;Button 1 style
  1220. push 0 ;No right button
  1221. call [pSErrProc] ;Put up the system error message
  1222. P_End:
  1223. xor ax,ax
  1224. cEnd
  1225. ;----------------------------------------------------------------------------
  1226. ; StartString
  1227. ;
  1228. ; Prepares the start of the string for the sys error box
  1229. ;
  1230. ; ES:BX is the pointer to the full pathname
  1231. ; DS:DX is the string "Can't find file X:"
  1232. ;
  1233. ;----------------------------------------------------------------------------
  1234. cProc strcpyreg, <NEAR,PUBLIC>
  1235. cBegin nogen
  1236. cld
  1237. @@: lodsb ; copy from DS:SI
  1238. stosb ; to ES:DI
  1239. or al, al
  1240. jnz @B ; including 0
  1241. dec di ; point to trailing 0
  1242. ret
  1243. cEnd nogen
  1244. ;cProc StartString, <NEAR,PUBLIC>
  1245. ;cBegin NOGEN
  1246. ; CheckKernelDS
  1247. ; ReSetKernelDS
  1248. ;
  1249. ; ;** Copy the first part of the string
  1250. ; cld
  1251. ; push es ;Save the parameter
  1252. ; push bx
  1253. ; mov dx,dataOffset szCannotFind1 ;Point to Can't Find string
  1254. ; call AppendFirst ;Put in OutBuf
  1255. ; pop bx
  1256. ; pop es
  1257. ;
  1258. ; ;** Save the drive letter for compatibility with ancient disk swaps
  1259. ; mov al,es:[bx] ;Get drive letter
  1260. ; mov [LastDriveSwapped],al ;Save it for GetLastDiskChange
  1261. ;
  1262. ; ;** Append the filename portion
  1263. ; smov ds,es
  1264. ; mov dx,bx
  1265. ; jmps Append
  1266. ;
  1267. ;cEnd NOGEN
  1268. ; AppendFirst & Append
  1269. ; Append ASCIIZ string to the static string OutBuf
  1270. ;
  1271. ; ENTRY: DS:DX points to a string to append to the static buffer
  1272. ;
  1273. ; AppendFirst clears the static string and appends the new string
  1274. ; as the first part of the string.
  1275. ; Append just appends the new string on the end of the current string.
  1276. cProc AppendFirst, <PUBLIC,NEAR>
  1277. cBegin NOGEN
  1278. CheckKernelDS
  1279. ReSetKernelDS
  1280. mov [BufPos],dataOffset OutBuf
  1281. UnSetKernelDS
  1282. ;Append:
  1283. push si ;Save some registers
  1284. push di
  1285. SetKernelDS es
  1286. mov di,[BufPos]
  1287. mov si,dx
  1288. call strcpyreg
  1289. ;ap1: lodsb
  1290. ; stosb
  1291. ; or al,al
  1292. ; jnz ap1
  1293. dec di
  1294. mov [BufPos],di
  1295. pop di
  1296. pop si
  1297. ret
  1298. cEnd NOGEN
  1299. UnSetKernelDS es
  1300. ; GetPureName
  1301. ; Strips the drive and directory portions of a pathname off.
  1302. ; ENTRY: ES:DI points to pathname
  1303. ; EXIT: ES:DI points to "pure" name in same string
  1304. cProc GetPureName, <NEAR,PUBLIC>
  1305. cBegin
  1306. ;** Do FE_SB version:
  1307. ;* It is not possible to search filename delimiter by backward
  1308. ;** search in case of FE_SB version, so we use forward search.
  1309. IFDEF FE_SB
  1310. mov bx,di
  1311. iup0:
  1312. mov al,es:[di]
  1313. test al,al ; end of string?
  1314. jz iup2 ; jump if so
  1315. inc di
  1316. cmp al,'\'
  1317. jz iup1
  1318. cmp al,'/'
  1319. jz iup1
  1320. cmp al,':'
  1321. jz iup1
  1322. call MyIsDBCSLeadByte ; see if char is DBC
  1323. jc iup0 ; jump if not a DBC
  1324. inc di ; skip to detemine 2nd byte of DBC
  1325. jmp iup0
  1326. iup1:
  1327. mov bx,di ; update purename candidate
  1328. jmp iup0
  1329. iup2:
  1330. mov di,bx ; di points purename pointer
  1331. ;** Do normal version:
  1332. ;** Here we can just back up until we find the proper char
  1333. ELSE
  1334. cld
  1335. xor al,al
  1336. mov cx,-1
  1337. mov bx,di
  1338. repne scasb
  1339. inc cx
  1340. inc cx
  1341. neg cx
  1342. iup0: cmp bx,di ; back to beginning of string?
  1343. jz iup1 ; yes, di points to name
  1344. mov al,es:[di-1] ; get next char
  1345. cmp al,'\' ; next char a '\'?
  1346. jz iup1 ; yes, di points to name
  1347. cmp al,'/' ; next char a '/'
  1348. jz iup1
  1349. cmp al,':' ; next char a ':'
  1350. jz iup1 ; yes, di points to name
  1351. dec di ; back up one
  1352. jmp iup0
  1353. iup1:
  1354. ENDIF
  1355. cEnd
  1356. ; ParseFile
  1357. ;
  1358. ; ENTRY: DS:SI points to unqualified pathname
  1359. ; ES:DI points to buffer to be used for qualified name
  1360. ; EXIT: Buffer previously pointed to by ES:DI now has full
  1361. ; unambiguous pathname
  1362. ; DX is length of path portion of entered pathname
  1363. ; AX is total length of pathname
  1364. ; DI is number of slashes
  1365. ; CX is length of path ON ERROR ONLY!!! (for PowerPoint)
  1366. LONG_UNC_NAMES equ 1
  1367. cProc ParseFile, <NEAR,PUBLIC>
  1368. localW cSlash ;Word ptr [bp][-2]
  1369. localW cchPath ;Word ptr [bp][-4]
  1370. localW fUNC ;Flag for UNC name (\\foo\bar)
  1371. if LONG_UNC_NAMES
  1372. localW fCountUNC ;Indicates we are parsing UNC name
  1373. else
  1374. localW fFirstUNC ;Indicates we are parsing UNC name
  1375. endif
  1376. cBegin
  1377. mov cSlash,0 ;Zero the local variables
  1378. mov cchPath,0
  1379. mov fUNC,0 ;Assume it's not UNC
  1380. cld
  1381. ;** If a drive is on the path, parse it. Otherwise, get the current
  1382. ;** drive.
  1383. cmp byte ptr ds:[si+1],':'
  1384. jne nodrive
  1385. lodsb
  1386. inc si
  1387. or al,20h ; convert to lower case
  1388. sub al,'a' ; convert to number
  1389. jb @F ;Not valid, so return error
  1390. cmp al,'z'-'a'
  1391. jbe gotdrive
  1392. @@: jmp gpFail2
  1393. nodrive:
  1394. mov ah,19h
  1395. DOSCALL
  1396. gotdrive:
  1397. mov dl,al
  1398. inc dl
  1399. add al,'A' ; convert to ascii
  1400. mov ah,':'
  1401. ;** If this is a UNC name, we don't want to copy the drive letter
  1402. ;** as it is legal but unnecessary for a full path
  1403. mov fUNC, 1
  1404. if LONG_UNC_NAMES
  1405. mov fCountUNC, 2
  1406. else
  1407. mov fFirstUNC, 1
  1408. endif
  1409. cmp WORD PTR ds:[si], '\\' ;Is this a UNC? (\\foo\bar)
  1410. je PF_DriveOK ;Yes, don't insert drive
  1411. cmp WORD PTR ds:[si], '//' ;Is this a UNC? (//foo/bar)
  1412. je PF_DriveOK ;Yes, don't insert drive
  1413. mov fUNC, 0 ;Nope, not UNC
  1414. if LONG_UNC_NAMES
  1415. mov fCountUNC, 0
  1416. else
  1417. mov fFirstUNC, 0
  1418. endif
  1419. stosw ;Write drive letter and colon
  1420. add cchPath,2 ;Add two chars to path len
  1421. PF_DriveOK:
  1422. push di ; Save beginning of path
  1423. ;** If we start with a slash, we have a qualified path here
  1424. ;* so we don't have to search to find the current path.
  1425. ;** Otherwise, we have to find where we are and make the path.
  1426. mov bx,'/' shl 8 + '\' ;Separator characters
  1427. mov al,ds:[si] ;Get first character
  1428. cmp al,bh ;If it's either one, we have a
  1429. je getpath0 ; full path, so don't search
  1430. cmp al,bl
  1431. je getpath0
  1432. mov al,bl ;Get a '\'
  1433. stosb ; and put in the buffer
  1434. inc cchPath ;Bump path count
  1435. mov cx,ds ;Prepare for DOS call: Save DS
  1436. xchg si,di ;DS:SI needs to point to buffer
  1437. mov ax,es
  1438. mov ds,ax
  1439. mov ah,47h ;DOS #47: Get Current Directory
  1440. DOSCALL
  1441. jnc @F
  1442. jmp gpfail
  1443. @@:
  1444. push cx ;DOS returns OEM characters
  1445. push bx ; so convert to ANSI
  1446. cCall MyOemToAnsi,<ds,si,ds,si>
  1447. pop bx
  1448. pop ds
  1449. xchg si,di ;Get pointer back
  1450. xor al,al
  1451. mov cx,-1
  1452. repnz scasb ;Find the end of the string
  1453. neg cx
  1454. dec cx ;Don't count the terminator
  1455. dec cx
  1456. add cchPath,cx ;Add into path count
  1457. dec di ;Don't leave DI past the zero byte
  1458. ifdef FE_SB ;Check for trailing slash, DBCS-style
  1459. push si
  1460. push di
  1461. mov si,di
  1462. sub si,cx ;es:si->string address
  1463. dec di ;es:di->last byte
  1464. call MyIsDBCSTrailByte ;is the last byte a DBCS trailing byte?
  1465. pop di
  1466. pop si
  1467. jnc loopGD3 ;yes, append a '\'
  1468. ;no, fall through
  1469. endif
  1470. mov al,es:[di-1] ;Check for trailing slash. Non-DBCS
  1471. cmp al,bh ;If there is one, we're done here
  1472. je getpath0
  1473. cmp al,bl
  1474. je getpath0
  1475. IFDEF FE_SB
  1476. loopGD3:
  1477. ENDIF
  1478. mov al,bl ;Put a trailing slash on
  1479. stosb
  1480. inc cchPath
  1481. ;** Parse the pathname the user gave us
  1482. getpath0:
  1483. PF_GetPath label NEAR
  1484. public PF_GetPath
  1485. xor cx,cx ;CL=# of chars, CH=# of '.'
  1486. mov dx,di ;DX points to start of user chars
  1487. gp0:
  1488. lodsb ;Get a character
  1489. cmp al,bl ;Slash?
  1490. je gp1 ;Yes
  1491. cmp al,bh
  1492. ifdef FE_SB
  1493. je gp1 ;Too far if DBCS enable....
  1494. jmp gp2
  1495. else
  1496. jne gp2 ;No, skip this
  1497. endif
  1498. gp1: ;Character is a slash
  1499. ;** If we have a UNC name, two slashes are OK
  1500. ;** (just at the start of the filename)
  1501. cmp cchPath, 0 ;Start of path?
  1502. jne PF_NotUNC ;No, even if UNC, not valid here
  1503. cmp fUNC, 0 ;UNC pathname?
  1504. je PF_NotUNC ;No, handle normally
  1505. stosb ;Store the first slash
  1506. lodsb ;Get the second slash
  1507. inc cchPath ;Another character in string
  1508. jmp SHORT gp1f ;Skip double slash failure
  1509. PF_NotUNC:
  1510. cmp ds:[si],bl ; if double slash, bad file name
  1511. jz gp1SkipSlash ; so we skip the extra slashes
  1512. cmp ds:[si],bh ; to be compatible with win32
  1513. jnz gp1DoneSlash ; MonkeyIsland bug 220764
  1514. gp1SkipSlash:
  1515. inc si
  1516. jmp SHORT PF_NotUNC ; check for more slashes
  1517. gp1DoneSlash:
  1518. if LONG_UNC_NAMES
  1519. dec fCountUNC ; Move to next portion of path
  1520. jns @f
  1521. mov fCountUNC,0
  1522. @@:
  1523. else
  1524. ;** When we get here, we will be on the first slash AFTER the
  1525. ;** UNC slashes: (\\foo\bar) (or any succeeding slash)
  1526. ;** ^
  1527. ;** So, we want clear the fFirstUNC flag so we don't allow
  1528. ;** more than 8 characters before a dot.
  1529. mov fFirstUNC, 0
  1530. endif
  1531. gp1f:
  1532. inc cSlash ; we found a slash
  1533. cmp cl,ch ; number of chars = number of '.'
  1534. jne gp1b ; nope....
  1535. or cx,cx
  1536. jnz gp001
  1537. ifdef FE_SB
  1538. jmp gp2b ; We need 16 bits branch
  1539. else
  1540. jmp SHORT gp2b
  1541. endif
  1542. gp001:
  1543. cmp cl,2 ; if more than 2 '.'
  1544. ja gpFail ; then we are bogus
  1545. dec di
  1546. ifdef FE_SB
  1547. dec cchPath ; adjust path string length
  1548. endif
  1549. dec cl
  1550. jz getpath0
  1551. ifdef FE_SB
  1552. dec di
  1553. dec di
  1554. mov dx, di
  1555. sub di, cchPath
  1556. add di, 4
  1557. cmp di, dx
  1558. jnc gpfail ; illegal path such as "c:.." or "c:\.."
  1559. mov cchPath, 3
  1560. gp1a:
  1561. xor cx, cx
  1562. gp1bb:
  1563. inc di
  1564. inc cx
  1565. mov al, es:[di]
  1566. cmp al, bl
  1567. jz gp1c
  1568. call MyIsDBCSLeadByte
  1569. jc gp1bb
  1570. inc di
  1571. inc cx
  1572. jmp gp1bb
  1573. gp1c:
  1574. cmp di, dx
  1575. jz gp1d
  1576. add cchPath, cx
  1577. jmp gp1a
  1578. gp1d:
  1579. sub di, cx
  1580. inc di ; new di points previous '\'+1
  1581. jmp getpath0
  1582. else
  1583. mov di,dx
  1584. gp1a:
  1585. dec di
  1586. mov al,es:[di-1]
  1587. cmp al,bl
  1588. je getpath0
  1589. cmp al,':'
  1590. jne gp1a
  1591. endif
  1592. gpfail:
  1593. pop ax
  1594. gpFail2:
  1595. xor ax,ax
  1596. jmp gpexit
  1597. gp1b:
  1598. mov al,bl
  1599. stosb
  1600. inc cchPath
  1601. jmp getpath0
  1602. gp2:
  1603. or al,al
  1604. jnz gp002
  1605. ifdef FE_SB
  1606. jmp gpx
  1607. else ; !FE_SB
  1608. jmp short gpx
  1609. endif ; !FE_SB
  1610. gp002:
  1611. cmp al,' '
  1612. jb gpFail
  1613. ja gp20
  1614. gp2x: lodsb ; if space encountered continue scanning...
  1615. or al,al ; if end of string, all ok
  1616. ifdef FE_SB
  1617. jnz gp2x_01
  1618. jmp gpx
  1619. gp2x_01:
  1620. else
  1621. jz gpx
  1622. endif
  1623. cmp al,' ' ; if space, keep looking...
  1624. jz gp2x
  1625. jmps gpFail ; otherwise error
  1626. gp20: cmp al,';'
  1627. jz gpFail
  1628. cmp al,':'
  1629. jz gpFail
  1630. cmp al,','
  1631. jz gpFail
  1632. cmp al,'|'
  1633. jz gpFail
  1634. cmp al,'+'
  1635. jz gpFail
  1636. cmp al,'<'
  1637. jz gpFail
  1638. cmp al,'>'
  1639. jz gpFail
  1640. cmp al,'"'
  1641. jz gpFail
  1642. cmp al,'['
  1643. jz gpFail
  1644. cmp al,']'
  1645. jz gpFail
  1646. cmp al,'='
  1647. jz gpFail
  1648. inc cl ; one more char
  1649. ifdef FE_SB
  1650. call MyIsDBCSLeadByte ; First byte of 2 byte character?
  1651. jc gp2a ; No, convert to upper case
  1652. stosb ; Yes, copy 1st byte
  1653. inc cchPath
  1654. lodsb ; Fetch second byte
  1655. inc cl
  1656. jmps gp2a1 ; with no case conversion
  1657. gp2a:
  1658. endif
  1659. call MyUpper
  1660. gp2a1:
  1661. cmp cchPath,127 ; DOS pathmax is 128, room for null.
  1662. ja gpFail
  1663. gp2b:
  1664. stosb
  1665. inc cchPath
  1666. cmp al,'.'
  1667. jne gp2c
  1668. inc ch
  1669. mov ah,cl
  1670. dec ah
  1671. gp2c:
  1672. if LONG_UNC_NAMES
  1673. ;** If this is a UNC name, don't bother checking lengths
  1674. cmp fCountUNC,0 ; Past \\foo\bar yet?
  1675. je PF_NotUNCPart
  1676. else
  1677. cmp fFirstUNC, 0 ;First UNC name?
  1678. je PF_NotFirstUNC ;Nope
  1679. or ch,ch ;'.' encountered yet?
  1680. jnz PF_NotFirstUNC ;Yes, treat like normal name
  1681. cmp cl, 11 ;11 chars allowed with no '.'
  1682. ja gpFv ;Too many
  1683. endif
  1684. jmp gp0 ;Ok
  1685. if LONG_UNC_NAMES
  1686. PF_NotUNCPart:
  1687. else
  1688. PF_NotFirstUNC:
  1689. endif
  1690. ;** Check other lengths
  1691. cmp ch,0 ; did we find a . yet?
  1692. jz gpT1 ; no, max count is 8
  1693. cmp cl,12 ; otherwise check for 12 chars
  1694. ja gpFv ; if more, no good
  1695. mov al,cl
  1696. sub al,ah
  1697. cmp al,3+1 ; more than 3 chars in extension?
  1698. ja gpFv
  1699. jmp gp0 ; continue
  1700. gpT1: cmp cl,8 ; did we find 8 chars between / and .
  1701. ja gpFv ; if more, we fail
  1702. jmp gp0
  1703. gpx:
  1704. ;** UNC names are invalid if they are SHORTER than the following:
  1705. ;** \\server\share\f
  1706. cmp fUNC,0 ;UNC name?
  1707. jz PF_EnoughSlashes ;No
  1708. cmp cSlash,3 ;We count \\ as one slash
  1709. jb gpFv ;Not enough, so fail it
  1710. PF_EnoughSlashes:
  1711. cmp ch,1
  1712. je gpx1
  1713. ja gpFv ; if more than 1 we fail
  1714. mov ah,cl ; No extension given
  1715. gpx1:
  1716. mov es:[di],al ; Zero terminate destination
  1717. xchg al,ah ; Get length of name in CX
  1718. or ax,ax
  1719. jnz gpx2
  1720. gpFv: jmp gpFail
  1721. gpx2:
  1722. cmp ax,8 ; but no more than 8
  1723. ja gpFv
  1724. pop ax
  1725. sub dx,ax ;Get length of path in DX
  1726. inc dx ;Add drive letter and :, less one
  1727. ;** Never a drive letter or colon for the UNC name case
  1728. cmp fUNC,0 ;UNC name?
  1729. jz @F ;Yes, don't do this
  1730. dec dx ;UNC names ALWAYS have >=3 slashes
  1731. dec dx
  1732. @@: mov ax,dx ;AX = length of entire path
  1733. xor ch,ch ;Clear high byte for 16 bit add
  1734. add ax,cx
  1735. cmp dx,1 ;If length is one, we have C:\ case
  1736. jne @F ;Nope
  1737. inc dx ;Bump it
  1738. @@:
  1739. gpexit:
  1740. mov di,cSlash ;DI retured as cSlash
  1741. cEnd
  1742. ;---------------------------------------------------------------
  1743. ;
  1744. ; Return the drive letter of last drive a disk was swapped in
  1745. ;
  1746. cProc GetLastDiskChange, <PUBLIC,FAR>
  1747. cBegin nogen
  1748. xor ax,ax
  1749. push ds
  1750. SetKernelDS
  1751. xchg al,[LastDriveSwapped]
  1752. pop ds
  1753. UnSetKernelDS
  1754. ret
  1755. cEnd nogen
  1756. assumes ds,nothing
  1757. assumes es,nothing
  1758. cProc MyOpenFile,<PUBLIC,FAR>,<si,di>
  1759. ParmD srcFile
  1760. ParmD dstFile
  1761. ParmW Command
  1762. cBegin
  1763. SetKernelDS
  1764. xor ax,ax
  1765. cmp [wMyOpenFileReent], ax ; Prevent reentering this procedure
  1766. jne myoffail
  1767. ifdef WOW
  1768. and Command, NOT OF_VERIFY ; Don't Bother with verify for internal
  1769. ; It slows us down
  1770. endif
  1771. mov es,[CurTDB]
  1772. mov ax,es:[TDB_ErrMode] ; Enable INT 24h processing
  1773. and es:[TDB_ErrMode],NOT 1
  1774. mov [myofint24],ax ; Save old INT 24h flag
  1775. mov [wMyOpenFileReent],1
  1776. cCall IOpenFile,<srcFile,dstFile,Command>
  1777. mov es,[CurTDB] ; Restore old INT 24h processing flag
  1778. mov dx,[myofint24]
  1779. mov es:[TDB_ErrMode],dx
  1780. mov [wMyOpenFileReent],0
  1781. jmps mof_ret
  1782. myoffail:
  1783. krDebugOut DEB_ERROR, "MyOpenFile not reentrant"
  1784. dec ax
  1785. mof_ret:
  1786. UnSetKernelDS
  1787. cEnd
  1788. sEnd CODE
  1789. sBegin MISCCODE
  1790. assumes CS,MISCCODE
  1791. assumes ds,nothing
  1792. assumes es,nothing
  1793. externNP MISCMapDStoDATA
  1794. externFP GetWindowsDirectory
  1795. cProc DeletePathname,<PUBLIC,FAR>
  1796. ; ParmD path
  1797. cBegin nogen
  1798. pop bx
  1799. pop cx
  1800. mov ax,4100h ; dos delete file function
  1801. push ax
  1802. push cx
  1803. push bx
  1804. errn$ OpenPathname
  1805. cEnd nogen
  1806. cProc OpenPathname,<PUBLIC,FAR>,<ds,si,di>
  1807. ParmD path
  1808. ParmW attr
  1809. LocalV Buffer,MaxFileLen
  1810. cBegin
  1811. mov ax,attr ; get attribute
  1812. or ah,ah ; function code already set...
  1813. jnz opn0 ; ...yes, otherwise...
  1814. mov ah,3dh ; ...default to open
  1815. opn0: mov di,ax
  1816. ; We don't use open test for existance, rather we use get
  1817. ; file attributes. This is because if we are using Novell
  1818. ; netware, opening a file causes Novell to execute its
  1819. ; own path searching logic, but we want our code to do it.
  1820. call MISCMapDStoDATA
  1821. ReSetKernelDS
  1822. cmp fNovell, 0
  1823. lds dx,path ; get pointer to pathname
  1824. UnSetKernelDS
  1825. je opnNoNovell
  1826. mov ax,4300h ; Get file attributes
  1827. DOSFCALL ; Does the file exist?
  1828. jc opnnov ; No, then dont do the operation
  1829. opnNoNovell:
  1830. mov ax,di ; Yes, restore operation to AX
  1831. DOSFCALL
  1832. jnc opn2
  1833. opnnov:
  1834. lea ax,Buffer
  1835. regptr dsdx,ds,dx
  1836. regptr ssax,ss,ax
  1837. cCall SearchPath,<dsdx,ssax,di>
  1838. opn2: mov bx,ax
  1839. cEnd
  1840. ;---------------------------------------------------------------
  1841. ;
  1842. ; Return the drive letter of a good disk to put a temp file on
  1843. ;
  1844. ;
  1845. cProc GetTempDrive,<PUBLIC,FAR>
  1846. ; ParmB Drive
  1847. cBegin nogen
  1848. mov bx,sp
  1849. push si
  1850. push di
  1851. mov ax,ss:[bx+4]
  1852. and al,not TF_FORCEDRIVE
  1853. jnz gtd1
  1854. mov ah,19h ; get the current disk
  1855. DOSFCALL
  1856. add al,'A'
  1857. gtd1: and al,01011111b ; convert to upper case (always a-z)
  1858. test byte ptr ss:[bx+4],TF_FORCEDRIVE ; Forcing drive letter?
  1859. jnz gtdz ; Yes, all done
  1860. sub al,'A' ; A: = 0, etc.
  1861. cbw
  1862. mov si,ax ; SI = drive to return if no hard disk
  1863. xor di,di ; start with drive A
  1864. gtd2: call FarIsFloppy ; while drive = floppy, keep looking
  1865. cmp al,3 ; did we find a hard disk?
  1866. mov dx,1 ; return we have a hard disk
  1867. jz gtdx ; yes, return it
  1868. inc di
  1869. cmp di,"Z"-"A"
  1870. jbe gtd2
  1871. xor dx,dx ; indicate its a floppy
  1872. mov di,si ; return default disk
  1873. gtdx: mov ax,di
  1874. add al,"A"
  1875. gtdz: mov ah,":"
  1876. pop di
  1877. pop si
  1878. ret 2
  1879. cEnd nogen
  1880. cProc hextoa,<PUBLIC,NEAR>
  1881. cBegin nogen
  1882. mov ah,al
  1883. mov cl,4
  1884. shr al,cl
  1885. and ah,0Fh
  1886. add ax,3030h
  1887. cmp al,39h
  1888. jbe hextoa1
  1889. add al,7
  1890. hextoa1:
  1891. cmp ah,39h
  1892. jbe hextoa2
  1893. add ah,7
  1894. hextoa2:
  1895. ret
  1896. cEnd nogen
  1897. ;---------------------------------------------------------------
  1898. ;
  1899. cProc IGetTempFileName,<PUBLIC,FAR>,<si,di>
  1900. parmW drive
  1901. parmD lpPrefix
  1902. parmW nUnique
  1903. parmD lpBuf
  1904. localW myUnique
  1905. localW mydx
  1906. localW mybuf
  1907. cBegin
  1908. sub sp, 128 ; local buffer for buiding lpBuf
  1909. mov di, sp
  1910. mov mybuf, sp ; save
  1911. cCall GetTempDrive,<drive>
  1912. mov mydx,dx
  1913. ;les di,lpBuf
  1914. smov es, ss
  1915. stosw ; AX = 'drive:'
  1916. mov ax,drive
  1917. test al,TF_FORCEDRIVE
  1918. jnz stmpForce
  1919. call FarGetEnv ; look for environ TEMP=
  1920. stmp2:
  1921. lodsw
  1922. or al,al ; no more enviroment
  1923. jz stmpNo
  1924. cmp ax,'ET' ; Look for TEMP=
  1925. jne stmp3
  1926. lodsw
  1927. cmp ax,'PM'
  1928. jne stmp3
  1929. lodsb
  1930. cmp al,'='
  1931. je stmpYes
  1932. stmp3: lodsb ; find end of string
  1933. or al,al
  1934. jnz stmp3
  1935. jmp stmp2
  1936. stmpYes:
  1937. ifdef FE_SB
  1938. mov al,[si]
  1939. mov ah,0
  1940. call FarMyIsDBCSLeadByte
  1941. jnc stmpnodrive
  1942. endif
  1943. cmp byte ptr [si+1],':' ; TEMP has drive?
  1944. jne stmpnodrive
  1945. dec di
  1946. dec di
  1947. stmpnodrive: ; copy path to ES:DI
  1948. lodsb
  1949. or al,al
  1950. jz stmpPath
  1951. stosb
  1952. jmp stmpnodrive
  1953. stmpForce:
  1954. mov al,'~'
  1955. stosb
  1956. jmps stmpNo1
  1957. stmpNo: ; ES:DI points to "drive:"
  1958. dec di
  1959. dec di
  1960. cCall GetWindowsDirectory, <esdi, 144>
  1961. add di, ax
  1962. stmpPath: ; ES:DI points to "drive:path"
  1963. mov ax,'~\'
  1964. cmp es:[di-1],al ; does it already end in \
  1965. jnz stmpNoF ; no, just store it
  1966. dec di ; override it
  1967. stmpNoF:
  1968. stosw
  1969. stmpNo1:
  1970. lds si,lpPrefix
  1971. mov cx,3
  1972. stmpPfx:
  1973. lodsb
  1974. or al,al
  1975. jz stmpPfx1
  1976. stosb
  1977. loop stmpPfx
  1978. stmpPfx1:
  1979. mov dx,nUnique
  1980. or dx,dx
  1981. jnz stmpNum
  1982. mov ah,2Ch
  1983. DOSFCALL
  1984. xor dx,cx
  1985. stmpNum:
  1986. mov myUnique,dx
  1987. jnz stmpNum1
  1988. inc dx ; Dont ever use 0 as the unique num.
  1989. jmp stmpNum
  1990. stmpNum1:
  1991. mov al,dh
  1992. call hextoa
  1993. stosw
  1994. mov al,dl
  1995. call hextoa
  1996. stosw
  1997. mov ax,'T.'
  1998. stosw
  1999. mov ax,'PM'
  2000. stosw
  2001. xor ax,ax
  2002. stosb
  2003. ; Don't call AnsiUpper on this string because it has OEM characters
  2004. ; in it (from the app and the temp environment variable).
  2005. cmp nUnique,0
  2006. jne stmpDone
  2007. ;lds dx,lpBuf
  2008. mov dx, mybuf
  2009. smov ds, ss
  2010. mov ax,5B00h
  2011. xor cx,cx
  2012. DOSFCALL
  2013. jnc stmpClose
  2014. cmp al,80 ; Did we fail because the file
  2015. jnz stmpfail ; already exists?
  2016. sub di,9
  2017. mov dx,myUnique
  2018. inc dx
  2019. jmp stmpNum
  2020. stmpClose:
  2021. mov bx,ax
  2022. mov ah,3Eh
  2023. DOSFCALL
  2024. jmps stmpdone
  2025. stmpfail:
  2026. xor ax,ax
  2027. mov myunique,ax
  2028. stmpdone:
  2029. mov di, mybuf ; robustness crap
  2030. smov es, ss ; bug #15493 ami pro
  2031. RegPtr esdi, es, di
  2032. cCall lstrcpy <lpBuf,esdi> ; now copy to user spc
  2033. mov ax,myunique
  2034. mov dx,mydx
  2035. add sp, 128
  2036. cEnd
  2037. ;-----------------------------------------------------------------------;
  2038. ; GetDriveType
  2039. ;
  2040. ; Entry:
  2041. ; parmW drive Disk Drive Information (Drive A = 0)
  2042. ;
  2043. ; Returns:
  2044. ; ax = 0 means the drive does not exist. if dx != 0 then the drive
  2045. ; maps to the drive in dx instead (A = 1) AND the drive is
  2046. ; REMOVEABLE.
  2047. ; ax = 1 means the drive does not exist. if dx != 0 then the drive
  2048. ; maps to the drive in dx instead (A = 1) AND the drive is
  2049. ; FIXED.
  2050. ; ax = 2 means the drive is removable media
  2051. ; ax = 3 means the drive is fixed media
  2052. ; ax = 4 means the drive is fixed media and remote
  2053. ;
  2054. ; Registers Destroyed:
  2055. ;
  2056. ; History:
  2057. ; Mon 16-Oct-1989 21:14:27 -by- David N. Weise [davidw]
  2058. ; Wrote it!
  2059. ;-----------------------------------------------------------------------;
  2060. assumes ds,nothing
  2061. assumes es,nothing
  2062. ifndef WOW - We thunk this API its too slow
  2063. cProc GetDriveType,<PUBLIC,FAR>
  2064. ; parmW drive
  2065. cBegin nogen
  2066. mov bx,sp
  2067. push ds
  2068. call MISCMapDStoDATA
  2069. ResetKernelDS
  2070. mov ax,1 ; 1 = Get Drive Info from InquireSystem
  2071. mov bx,ss:[bx+4]
  2072. cCall pSysProc,<ax,bx>
  2073. pop ds
  2074. ret 2
  2075. cEnd nogen
  2076. endif; WOW
  2077. sEnd MISCCODE
  2078. end