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.

541 lines
13 KiB

  1. ;****************************************************************************
  2. ;* *
  3. ;* PMDOS.ASM - *
  4. ;* *
  5. ;* Low level DOS routines needed by the Program Manager. *
  6. ;* *
  7. ;****************************************************************************
  8. memS=1
  9. ?PLM=1
  10. ?WIN=1
  11. include cmacros.inc
  12. SelectDisk equ 0Eh
  13. FCBFindFirstFile equ 11h
  14. FCBFindNextFile equ 12h
  15. FCBDeleteFile equ 13h
  16. FCBRenameFile equ 17h
  17. GetCurrentDisk equ 19h
  18. SetDTAAddress equ 1Ah
  19. GetFileSize equ 23h
  20. GetDiskFreeSpace equ 36h
  21. CreateDir equ 39h
  22. RemoveDir equ 3Ah
  23. ChangeCurrentDir equ 3Bh
  24. CreateFile equ 3Ch
  25. DeleteFile equ 41h
  26. GetSetFileAttributes equ 43h
  27. GetCurrentDir equ 47h
  28. FindFirstFile equ 4Eh
  29. FindNextFile equ 4Fh
  30. RenameFile equ 56h
  31. externFP DOS3CALL
  32. externFP AnsiToOem
  33. ifdef DBCS
  34. externFP IsDBCSLeadByte
  35. endif
  36. ;=============================================================================
  37. createSeg _%SEGNAME, %SEGNAME, WORD, PUBLIC, CODE
  38. sBegin %SEGNAME
  39. assumes CS,%SEGNAME
  40. assumes DS,DATA
  41. cProc PathType, <FAR, PUBLIC>
  42. parmD lpFile
  43. localV szOEM, 128
  44. cBegin
  45. RegPtr lpszOEM, ss, bx
  46. lea bx, szOEM
  47. cCall AnsiToOem, <lpFile, lpszOEM>
  48. lea dx, szOEM
  49. mov ax, 4300h
  50. call DOS3CALL
  51. jnc id_noerror
  52. xor ax, ax
  53. jmp short id_exit
  54. id_noerror:
  55. and cx, 10h
  56. jnz id_dir
  57. mov ax, 1
  58. jmp short id_exit
  59. id_dir:
  60. mov ax, 2
  61. id_exit:
  62. cEnd
  63. ;*--------------------------------------------------------------------------*
  64. ;* *
  65. ;* FileTime*() - *
  66. ;* *
  67. ;*--------------------------------------------------------------------------*
  68. cProc FileTime, <FAR, PUBLIC>
  69. parmW hFile
  70. cBegin
  71. mov ax, 5700h
  72. mov bx, hFile
  73. cCall DOS3CALL
  74. jnc ft_ok
  75. sub ax, ax
  76. sub dx, dx
  77. jmp short ft_ex
  78. ft_ok:
  79. mov ax, cx
  80. ft_ex:
  81. cEnd
  82. ;*--------------------------------------------------------------------------*
  83. ;* *
  84. ;* IsReadOnly() - *
  85. ;* *
  86. ;*--------------------------------------------------------------------------*
  87. cProc IsReadOnly, <FAR, PUBLIC>
  88. parmD lpFile
  89. localV szOEM, 128
  90. cBegin
  91. RegPtr lpszOEM, ss, bx
  92. lea bx, szOEM
  93. cCall AnsiToOem,<lpFile,lpszOEM>
  94. mov ax, 4300h ; get attributes...
  95. lea dx, szOEM ; ...for given file...
  96. call DOS3CALL
  97. jc f_exit ; ax == 0 if error...
  98. and ax, 1 ; test RO bit
  99. jmp short t_exit ; true
  100. f_exit:
  101. xor ax, ax ; false
  102. t_exit:
  103. cEnd
  104. ;*--------------------------------------------------------------------------*
  105. ;* *
  106. ;* GetDOSErrorCode() - *
  107. ;* *
  108. ;*--------------------------------------------------------------------------*
  109. cProc GetDOSErrorCode, <FAR, PUBLIC>, <SI,DI>
  110. cBegin
  111. mov ah,59h ; Get DOS extended error
  112. sub bx,bx ; cause ray duncan says so
  113. push ds ; function trashes registers
  114. push bp ; so we gotta save 'em for cProc
  115. call DOS3CALL
  116. pop bp ; be nice to C
  117. pop ds ; get DS
  118. mov dl,bh ; class in byte 2
  119. mov dh,ch ; locus in byte 3 (skip the rec. action)
  120. cEnd
  121. ;*--------------------------------------------------------------------------*
  122. ;* *
  123. ;* GetCurrentDrive() - *
  124. ;* *
  125. ;*--------------------------------------------------------------------------*
  126. cProc GetCurrentDrive, <FAR, PUBLIC>
  127. cBegin
  128. mov ah,GetCurrentDisk
  129. call DOS3CALL
  130. sub ah,ah ; Zero out AH
  131. cEnd
  132. ;*--------------------------------------------------------------------------*
  133. ;* *
  134. ;* SetCurrentDrive() - *
  135. ;* *
  136. ;*--------------------------------------------------------------------------*
  137. ; Returns the number of drives in AX.
  138. cProc SetCurrentDrive, <FAR, PUBLIC>
  139. ParmW Drive
  140. cBegin
  141. mov dx,Drive
  142. mov ah,SelectDisk
  143. call DOS3CALL
  144. sub ah,ah ; Zero out AH
  145. cEnd
  146. ;*--------------------------------------------------------------------------*
  147. ;* *
  148. ;* GetCurrentDirectory() - *
  149. ;* *
  150. ;*--------------------------------------------------------------------------*
  151. cProc GetCurrentDirectory, <FAR, PUBLIC>, <SI, DI>
  152. parmW wDrive
  153. ParmD lpDest
  154. cBegin
  155. push ds ; Preserve DS
  156. mov ax,wDrive
  157. or al,al
  158. jnz GCDHaveDrive
  159. call GetCurrentDrive
  160. inc al ; Convert to logical drive number
  161. GCDHaveDrive:
  162. les di,lpDest ; ES:DI = lpDest
  163. push es
  164. pop ds ; DS:DI = lpDest
  165. cld
  166. mov dl,al ; DL = Logical Drive Number
  167. add al,'@' ; Convert to ASCII drive letter
  168. stosb
  169. mov al,':'
  170. stosb
  171. mov al,'\' ; Start string with a backslash
  172. stosb
  173. mov byte ptr es:[di],0 ; Null terminate in case of error
  174. mov si,di ; DS:SI = lpDest[1]
  175. mov ah,GetCurrentDir
  176. call DOS3CALL
  177. jc GCDExit ; Skip if error
  178. xor ax,ax ; Return FALSE if no error
  179. GCDExit:
  180. pop ds ; Restore DS
  181. cEnd
  182. ;*--------------------------------------------------------------------------*
  183. ;* *
  184. ;* SetCurrentDirectory() - *
  185. ;* *
  186. ;*--------------------------------------------------------------------------*
  187. cProc SetCurrentDirectory, <FAR, PUBLIC>, <DS, DI>
  188. ParmD lpDirName
  189. cBegin
  190. lds di,lpDirName ; DS:DI = lpDirName
  191. ; Is there a drive designator?
  192. ifdef DBCS
  193. mov al, byte ptr [di] ; fetch a first byte of path
  194. xor ah,ah
  195. cCall IsDBCSLeadByte, <ax>
  196. test ax,ax ; DBCS lead byte?
  197. jnz SCDNoDrive ; jump if so
  198. endif
  199. cmp byte ptr [di+1],':'
  200. jne SCDNoDrive ; Nope, continue
  201. mov al,byte ptr [di] ; Yup, change to that drive
  202. sub ah,ah
  203. and al, 0DFH ;Make drive letter upper case
  204. sub al,'A'
  205. push ax
  206. call SetCurrentDrive
  207. mov al,byte ptr [di+2] ; string just a drive letter and colon?
  208. cbw
  209. or ax,ax
  210. jz SCDExit ; Yup, just set the current drive and done
  211. SCDNoDrive:
  212. mov dx,di
  213. mov ah,ChangeCurrentDir
  214. call DOS3CALL
  215. jc SCDExit ; Skip on error
  216. xor ax,ax ; Return FALSE if successful
  217. SCDExit:
  218. cEnd
  219. if 0
  220. ;*--------------------------------------------------------------------------*
  221. ;* *
  222. ;* IsRemovableDrive() - *
  223. ;* *
  224. ;*--------------------------------------------------------------------------*
  225. cProc IsRemovableDrive, <FAR, PUBLIC>
  226. ParmW wDrive
  227. cBegin
  228. mov ax,4408h ; IOCTL: Check If Block Device Is Removable
  229. mov bx,wDrive
  230. inc bx
  231. call DOS3CALL
  232. and ax,1 ; Only test bit 0
  233. xor ax,1 ; Flip so 1 == Removable
  234. cEnd
  235. ;*--------------------------------------------------------------------------*
  236. ;* *
  237. ;* IsRemoteDrive() - *
  238. ;* *
  239. ;*--------------------------------------------------------------------------*
  240. cProc IsRemoteDrive, <FAR, PUBLIC>
  241. ParmW wDrive
  242. cBegin
  243. mov ax,4409h ; IOCTL: Check If Block Device Is Remote
  244. mov bx,wDrive
  245. inc bx
  246. call DOS3CALL
  247. xor ax,ax
  248. and dx,0001000000000000b ; Test bit 12
  249. jz IRDRet
  250. mov ax,1
  251. IRDRet:
  252. cEnd
  253. endif
  254. ;*--------------------------------------------------------------------------*
  255. ;* *
  256. ;* DosDelete() - *
  257. ;* *
  258. ;*--------------------------------------------------------------------------*
  259. %out assuming SS==DS
  260. cProc DosDelete, <FAR, PUBLIC>
  261. ParmD lpSource
  262. localV szOEM, 128
  263. cBegin
  264. RegPtr lpszOEM,ss,bx ; convert path to OEM chars
  265. lea bx, szOEM
  266. cCall AnsiToOem, <lpSource, lpszOEM>
  267. lea dx, szOEM
  268. mov ah,DeleteFile ;
  269. call DOS3CALL
  270. jc DDExit
  271. xor ax,ax ; Return 0 if successful
  272. DDExit:
  273. cEnd
  274. ;*--------------------------------------------------------------------------*
  275. ;* *
  276. ;* DosRename() - *
  277. ;* *
  278. ;*--------------------------------------------------------------------------*
  279. cProc DosRename, <FAR, PUBLIC>, <DI>
  280. ParmD lpSource
  281. ParmD lpDest
  282. localV szOEM1, 128
  283. localV szOEM2, 128
  284. cBegin
  285. RegPtr lpszOEM1, ss, bx
  286. lea bx, szOEM1
  287. cCall AnsiToOem, <lpSource, lpszOEM1>
  288. RegPtr lpszOEM2, ss, bx
  289. lea bx, szOEM2
  290. cCall AnsiToOem, <lpDest, lpszOEM2>
  291. lea dx, szOEM1
  292. lea di, szOEM2
  293. push ss
  294. pop es
  295. mov ah,RenameFile
  296. call DOS3CALL
  297. jc DRExit
  298. xor ax,ax ; Return 0 if successful
  299. DRExit:
  300. cEnd
  301. ; lmemmove() -
  302. ;
  303. ; Shamelessly heisted from the C5.1 runtime library, and modified to
  304. ; work in mixed model Windows programs!
  305. ;
  306. ;***
  307. ;memcpy.asm - contains memcpy and memmove routines
  308. ;
  309. ; Copyright (c) 1986-1988, Microsoft Corporation. All right reserved.
  310. ;
  311. ;Purpose:
  312. ; memmove() copies a source memory buffer to a destination memory buffer.
  313. ; This routine recognize overlapping buffers to avoid propogation.
  314. ;
  315. ; Algorithm:
  316. ;
  317. ; void * memmove(void * dst, void * src, size_t count)
  318. ; {
  319. ; void * ret = dst;
  320. ;
  321. ; if (dst <= src || dst >= (src + count)) {
  322. ; /*
  323. ; * Non-Overlapping Buffers
  324. ; * copy from lower addresses to higher addresses
  325. ; */
  326. ; while (count--)
  327. ; *dst++ = *src++;
  328. ; }
  329. ; else {
  330. ; /*
  331. ; * Overlapping Buffers
  332. ; * copy from higher addresses to lower addresses
  333. ; */
  334. ; dst += count - 1;
  335. ; src += count - 1;
  336. ;
  337. ; while (count--)
  338. ; *dst-- = *src--;
  339. ; }
  340. ;
  341. ; return(ret);
  342. ; }
  343. ;
  344. ;
  345. ;Entry:
  346. ; void *dst = pointer to destination buffer
  347. ; const void *src = pointer to source buffer
  348. ; size_t count = number of bytes to copy
  349. ;
  350. ;Exit:
  351. ; Returns a pointer to the destination buffer in DX:AX
  352. ;
  353. ;Uses:
  354. ; CX,DX,ES
  355. ;
  356. ;Exceptions:
  357. ;*******************************************************************************
  358. cProc lmemmove,<FAR,PUBLIC>,<si,di>
  359. parmD dst ; destination pointer
  360. parmD src ; source pointer
  361. parmW count ; number of bytes to copy
  362. cBegin
  363. push ds ; Preserve DS
  364. lds si,src ; DS:SI = src
  365. les di,dst ; ES:DI = dst
  366. mov ax,di ; save dst in AX for return value
  367. mov cx,count ; cx = number of bytes to move
  368. jcxz done ; if cx = 0 Then nothing to copy
  369. ;
  370. ; Check for overlapping buffers:
  371. ; If segments are different, assume no overlap
  372. ; Do normal (Upwards) Copy
  373. ; Else If (dst <= src) Or (dst >= src + Count) Then
  374. ; Do normal (Upwards) Copy
  375. ; Else
  376. ; Do Downwards Copy to avoid propogation
  377. ;
  378. mov ax,es ; compare the segments
  379. cmp ax,word ptr (src+2)
  380. jne CopyUp
  381. cmp di,si ; src <= dst ?
  382. jbe CopyUp
  383. mov ax,si
  384. add ax,cx
  385. cmp di,ax ; dst >= (src + count) ?
  386. jae CopyUp
  387. ;
  388. ; Copy Down to avoid propogation in overlapping buffers
  389. ;
  390. mov ax,di ; AX = return value (offset part)
  391. add si,cx
  392. add di,cx
  393. dec si ; DS:SI = src + count - 1
  394. dec di ; ES:DI = dst + count - 1
  395. std ; Set Direction Flag = Down
  396. rep movsb
  397. cld ; Set Direction Flag = Up
  398. jmp short done
  399. CopyUp:
  400. mov ax,di ; AX = return value (offset part)
  401. ;
  402. ; There are 4 situations as far as word alignment of "src" and "dst":
  403. ; 1. src and dst are both even (best case)
  404. ; 2. src is even and dst is odd
  405. ; 3. src is odd and dst is even
  406. ; 4. src and dst are both odd (worst case)
  407. ;
  408. ; Case #4 is much faster if a single byte is copied before the
  409. ; REP MOVSW instruction. Cases #2 and #3 are effectively unaffected
  410. ; by such an operation. To maximum the speed of this operation,
  411. ; only DST is checked for alignment. For cases #2 and #4, the first
  412. ; byte will be copied before the REP MOVSW.
  413. ;
  414. test al,1 ; fast check for dst being odd address
  415. jz move
  416. movsb ; move a byte to improve alignment
  417. dec cx
  418. ;
  419. ; Now the bulk of the copy is done using REP MOVSW. This is much
  420. ; faster than a REP MOVSB if the src and dst addresses are both
  421. ; word aligned and the processor has a 16-bit bus. Depending on
  422. ; the initial alignment and the size of the region moved, there
  423. ; may be an extra byte left over to be moved. This is handled
  424. ; by the REP MOVSB, which moves either 0 or 1 bytes.
  425. ;
  426. move:
  427. shr cx,1 ; Shift CX for count of words
  428. rep movsw ; CF set if one byte left over
  429. adc cx,cx ; CX = 1 or 0, depending on Carry Flag
  430. rep movsb ; possible final byte
  431. ;
  432. ; Return the "dst" address in AX/DX:AX
  433. ;
  434. done:
  435. pop ds ;restore ds
  436. mov dx,es ;segment part of dest address
  437. cEnd
  438. sEnd %SEGNAME
  439. end