Source code of Windows XP (NT5)
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.

664 lines
20 KiB

  1. /*
  2. * pmdos.c
  3. *
  4. * Copyright (c) 1991, Microsoft Corporation
  5. *
  6. * DESCRIPTION
  7. *
  8. * This file is for support of program manager under NT Windows.
  9. * This file is/was ported from pmdos.asm (program manager).
  10. * It was in x86 asm code, and now is in ansi C.
  11. * Some functions will be removed, due to they are only needed
  12. * by DOS Windows.
  13. *
  14. * MODIFICATION HISTORY
  15. * Initial Version: x/x/90 Author Unknown, since he didn't feel
  16. * like commenting the code...
  17. *
  18. * NT 32b Version: 1/9/91 Jeff Pack
  19. * Intitial port to begin.
  20. *
  21. * WARNING: since this is NOT for DOS, I'm making it soley 32bit aware.
  22. * Following functions not ported
  23. * IsRemovable() is in pmcomman.c (already ifdef'd in asm code)
  24. * IsRemote() is in pmcomman.c (ditto!)
  25. *
  26. */
  27. #ifndef ORGCODE
  28. #include <io.h>
  29. #include <string.h>
  30. #include <ctype.h>
  31. #endif
  32. #include "windows.h"
  33. #include <port1632.h>
  34. BOOL PathType(LPSTR);
  35. DWORD FileTime(HFILE);
  36. DWORD GetDOSErrorCode(VOID);
  37. int GetCurrentDrive(VOID);
  38. int w_GetCurrentDirectory(int, LPSTR);
  39. int w_SetCurrentDirectory(LPSTR);
  40. int DosDelete(LPSTR);
  41. LPSTR lmemmove(LPSTR, LPSTR, WORD);
  42. BOOL FAR PASCAL IsRemoteDrive(int);
  43. BOOL FAR PASCAL IsRemovableDrive(int);
  44. #define LOCALBUFFERSIZE 128
  45. /*** PathType -- Determines if string denotes a directory or not.
  46. *
  47. *
  48. *
  49. * BOOL PathType(LPSTR pszFileString)
  50. *
  51. * ENTRY - LPSTR pszFileString - pointer to string to use to determine if directory
  52. * or not.
  53. * window, with focus.
  54. * EXIT - int iReturnValue - 2 = is directory 1 = Is Not directory
  55. *
  56. * SYNOPSIS - This function takes a pointer to a string, calls OS to determine
  57. * if string is, or is not a directory.
  58. * WARNINGS - Cna't even see where this is called!
  59. * EFFECTS -
  60. *
  61. */
  62. BOOL PathType(LPSTR lpszFileString)
  63. {
  64. LPSTR lpszLocalBuffer; /*local buffer for AnsiToOem()*/
  65. DWORD dwReturnedAttributes;
  66. DWORD nBufferLength;
  67. nBufferLength = strlen(lpszFileString) + 1;
  68. /*alloc local, non-moveable, zero filled buffer*/
  69. lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength);
  70. if(lpszLocalBuffer == NULL){
  71. #if DBG
  72. OutputDebugString("<PathType> LocalAlloc FAILed\n");
  73. #endif /* DBG */
  74. return 0;
  75. }
  76. AnsiToOem(lpszFileString, lpszLocalBuffer);
  77. /*get attributes of filestring*/
  78. dwReturnedAttributes = GetFileAttributes(lpszLocalBuffer);
  79. if(dwReturnedAttributes == -1){
  80. #if DBG
  81. OutputDebugString("<PathType> - GetFileAttributes() FAILed!\n");
  82. #endif /* DBG */
  83. LocalFree(lpszLocalBuffer);
  84. return(0);
  85. }
  86. else{
  87. /*and with directory attribute*/
  88. dwReturnedAttributes = dwReturnedAttributes & FILE_ATTRIBUTE_DIRECTORY;
  89. switch(dwReturnedAttributes){
  90. case FILE_ATTRIBUTE_DIRECTORY:
  91. LocalFree(lpszLocalBuffer);
  92. return(2);
  93. break;
  94. default:
  95. LocalFree(lpszLocalBuffer);
  96. return(1);
  97. }
  98. }
  99. }
  100. /*** FileTime -- Gets time of last modification.
  101. *
  102. *
  103. *
  104. * DWORD FileTime(HFILE hFile)
  105. *
  106. * ENTRY - int hFile - file handle to access
  107. *
  108. * EXIT - LPWORD - which is gotten from lpTimeStamp = 0 (ERROR).
  109. * or lpTimeStamp != 0 (value of timestamp)
  110. *
  111. * SYNOPSIS - calls GetFileTime() to get timestamp. If error, then
  112. * lpTimeStamp = 0, else contains TimeStamp for file.
  113. * WARNINGS -
  114. * EFFECTS -
  115. *
  116. */
  117. DWORD FileTime(
  118. HFILE hFile)
  119. {
  120. BOOL bReturnCode;
  121. FILETIME CreationTime;
  122. FILETIME LastAccessTime;
  123. FILETIME LastWriteTime;
  124. WORD FatTime = 0;
  125. WORD FatDate;
  126. bReturnCode = GetFileTime(LongToHandle(hFile), &CreationTime, &LastAccessTime,
  127. &LastWriteTime);
  128. /*
  129. * Test return code
  130. */
  131. if (bReturnCode == FALSE) {
  132. return 0; /*set to zero, for error*/
  133. }
  134. /*
  135. * Now convert 64bit time to DOS 16bit time
  136. */
  137. FileTimeToDosDateTime( &LastWriteTime, &FatDate, &FatTime);
  138. return FatTime;
  139. }
  140. /*** IsReadOnly -- determines if file is readonly or not.
  141. *
  142. *
  143. *
  144. * BOOL IsReadOnly(LPSTR lpszFileString)
  145. *
  146. * ENTRY - LPSTR lpszFileString - file name to use
  147. *
  148. * EXIT - BOOL xxx - returns (0) = not readonly (1) = read only
  149. * or lpTimeStamp != 0 (value of timestamp)
  150. *
  151. * SYNOPSIS - calls GetAttributes, then tests if file is read only.
  152. * WARNINGS -
  153. * EFFECTS -
  154. *
  155. */
  156. BOOL IsReadOnly(LPSTR lpszFileString)
  157. {
  158. DWORD dwReturnedAttributes;
  159. LPSTR lpszLocalBuffer; /*local buffer for AnsiToOem()*/
  160. DWORD nBufferLength;
  161. nBufferLength = strlen(lpszFileString) + 1;
  162. /*alloc local, non-moveable, zero filled buffer*/
  163. lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength);
  164. if(lpszLocalBuffer == NULL){
  165. #if DBG
  166. OutputDebugString("<IsReadOnly> LocalAlloc FAILed\n");
  167. #endif /* DBG */
  168. return 0;
  169. }
  170. AnsiToOem(lpszFileString, lpszLocalBuffer);
  171. /*get attributes of filestring*/
  172. dwReturnedAttributes = GetFileAttributes(lpszLocalBuffer);
  173. if(dwReturnedAttributes == -1){
  174. #if DBG
  175. OutputDebugString("<IsReadOnly> - GetFileAttributes() FAILed!\n");
  176. #endif /* DBG */
  177. LocalFree(lpszLocalBuffer);
  178. return FALSE;
  179. } else {
  180. /*AND with read_only attribute*/
  181. dwReturnedAttributes = dwReturnedAttributes & FILE_ATTRIBUTE_READONLY;
  182. switch(dwReturnedAttributes){
  183. case FILE_ATTRIBUTE_READONLY:
  184. LocalFree(lpszLocalBuffer);
  185. return TRUE;
  186. break;
  187. default:
  188. LocalFree(lpszLocalBuffer);
  189. return FALSE;
  190. }
  191. }
  192. }
  193. /*** GetDOSErrorCode -- returns extended error code
  194. *
  195. *
  196. *
  197. * DWORD GetDOSErrorCode(VOID)
  198. *
  199. * ENTRY - VOID
  200. *
  201. * EXIT - DWORD - returned extended code.
  202. *
  203. * SYNOPSIS - calls GetLastError() to get error code from OS
  204. * WARNINGS -
  205. * EFFECTS -
  206. *
  207. */
  208. DWORD GetDOSErrorCode(VOID)
  209. {
  210. return( (int) GetLastError());
  211. /*BUG BUG, pmgseg.c uses this from _lcreat() to determine if returned
  212. 5 (access denied) or 13 (invalid_data). So this need be tested
  213. to see if win32 returns these.*/
  214. }
  215. /*** GetCurrentDrive -- get current drive number.
  216. *
  217. *
  218. *
  219. * int GetCurrentDrive(VOID)
  220. *
  221. * ENTRY - VOID
  222. *
  223. * EXIT - int CurrentDrive - drive number of current drive (0=a, etc).
  224. *
  225. * SYNOPSIS - calls GetCurrentDirectory, must parse returned string
  226. * for either drive letter, or UNC path. If UNC I gotta
  227. * somehow, covert UNC path to drive letter to drive number.
  228. * WARNINGS -
  229. * EFFECTS -
  230. *
  231. */
  232. int GetCurrentDrive(VOID)
  233. {
  234. /*BUG BUG, not DBCS aware!*/
  235. DWORD nBufferLength = LOCALBUFFERSIZE;
  236. DWORD dwReturnCode;
  237. LPSTR lpszLocalBuffer;
  238. int iDriveNumber;
  239. /*alloc local, non-moveable, zero filled buffer*/
  240. lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength);
  241. if(lpszLocalBuffer == NULL){
  242. #if DBG
  243. OutputDebugString("<GetCurrentDrive> LocalAlloc FAILed\n");
  244. #endif /* DBG */
  245. return 0;
  246. }
  247. GetCurDrive1:
  248. dwReturnCode = GetCurrentDirectory(nBufferLength, lpszLocalBuffer);
  249. /*failed for reason other than bufferlength too small*/
  250. if(dwReturnCode == 0){
  251. #if DBG
  252. OutputDebugString("<GetCurrentDrive> GetCurrentDirectory() FAILed\n");
  253. #endif /* DBG */
  254. return 0;
  255. }
  256. /*test for success, if dwReturnCode is > buffer, then need increase buffer*/
  257. if(dwReturnCode > nBufferLength){
  258. lpszLocalBuffer = LocalReAlloc(lpszLocalBuffer, nBufferLength + LOCALBUFFERSIZE, LMEM_ZEROINIT | LMEM_MOVEABLE);
  259. if(lpszLocalBuffer == NULL){
  260. #if DBG
  261. OutputDebugString("<GetCurrentDrive> LocalAlloc FAILed\n");
  262. #endif /* DBG */
  263. return 0;
  264. }
  265. else{
  266. nBufferLength += LOCALBUFFERSIZE;
  267. }
  268. goto GetCurDrive1;
  269. }
  270. /*finally lpszLocalBuffer has string containing current directory*/
  271. /* now must parse string for ":" or "\\" for drive letter or UNC*/
  272. /*if : then get drive letter, and convert to number a=0, b=1, etc.*/
  273. /*if \\ then gotta enumerate net drives, to learn what drive letter*/
  274. /*corresponds to that UNC path*/
  275. /*check for drive letter*/
  276. if(lpszLocalBuffer[1] == ':'){
  277. /*is drive letter, proceed*/
  278. if(isupper(lpszLocalBuffer[0])){
  279. iDriveNumber = lpszLocalBuffer[0] - 'A'; /*convert letter > number*/
  280. }
  281. else{
  282. iDriveNumber = lpszLocalBuffer[0] - 'a'; /*convert letter > number*/
  283. }
  284. }
  285. else{
  286. /*must be UNC path*/
  287. /*BUG BUG need write code to convert UNC path */
  288. #if DBG
  289. OutputDebugString("<GetCurrentDrive> Got UNC path, didnt expect, and no code!\n");
  290. #endif /* DBG */
  291. }
  292. LocalFree(lpszLocalBuffer);
  293. return(iDriveNumber);
  294. }
  295. /*** SetCurrentDrive -- set current drive.
  296. *
  297. *
  298. *
  299. * int SetCurrentDrive(int iDrive)
  300. *
  301. * ENTRY - int iDrive - drive number to set as current drive
  302. *
  303. * EXIT - int xxx - under DOS would have returned # of logical drives.
  304. * I can do this, but it's not used, if fact, no error
  305. * checks are done on this return value.
  306. *
  307. * SYNOPSIS - calls SetCurrentDirectory to set current drive.
  308. * WARNINGS - ALWAYS sets to root directory, since can't get cur dir
  309. * on other than current working drive.
  310. * EFFECTS -
  311. *
  312. */
  313. int SetCurrentDrive(int iDrive)
  314. {
  315. char cLocalBuffer[LOCALBUFFERSIZE] = "C:\\";
  316. char cDriveLetter;
  317. /*convert drive number (zero based) to letter*/
  318. cDriveLetter = (char) iDrive + (char)'A';
  319. cLocalBuffer[0] = cDriveLetter; /*set new drive in string*/
  320. if(!SetCurrentDirectory(cLocalBuffer)){
  321. /*call failed*/
  322. #if DBG
  323. OutputDebugString("<SetCurrentDrive> SetCurrentDirectory FAILed!\n");
  324. #endif /* DBG */
  325. return 0;
  326. }
  327. return(0);
  328. }
  329. /*** w_GetCurrentDirectory -- GetCurrent Working Directory
  330. *
  331. *
  332. *
  333. * int w_GetCurrentDirectory(int iDrive, LPSTR lpszCurrentDirectory)
  334. *
  335. * ENTRY - int iDrive - drive number to use as current drive.
  336. * LPSTR lpszCurrentDirectory - pointer to return data to.
  337. *
  338. * EXIT - int iReturnCode - returns (0) if success
  339. * LPSTR lpszCurrentDirectory - has curretn directory.
  340. *
  341. * SYNOPSIS - calls GetCurrentDirectory to get current directory.
  342. * the original asm code, checked idrive for zero, if so
  343. * then calls GetCurrentDrive. Under win32, is not neccessary,
  344. * since GetCUrrentDirectory() returns current drive.
  345. * Since it checks this, it means then that other than current
  346. * drive can be checked, yet win32 doesnt allow this, so I have to
  347. * code in a debug check, if iDrive != current drive.
  348. * WARNINGS - win32 doesn't allow multiple cur dirs across drives.
  349. * EFFECTS -
  350. *
  351. */
  352. int w_GetCurrentDirectory(int iDrive, LPSTR lpszCurrentDirectory)
  353. {
  354. /*first see if iDrive == 0, if so then only need call GetCurrentDirectory*/
  355. /*if non-zero, then could be current drive, OR another drive.*/
  356. /*THIS IS NOT ALLOWED!*/
  357. /*BUG BUG, not DBCS aware!*/
  358. DWORD nBufferLength = LOCALBUFFERSIZE;
  359. DWORD dwReturnCode;
  360. LPSTR lpszLocalBuffer;
  361. int iDriveNumber;
  362. /*alloc local, non-moveable, zero filled buffer*/
  363. lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength);
  364. if(lpszLocalBuffer == NULL){
  365. #if DBG
  366. OutputDebugString("<w_GetCurrentDirectory> LocalAlloc FAILed\n");
  367. #endif /* DBG */
  368. return(1);
  369. }
  370. GetCurDir1:
  371. dwReturnCode = GetCurrentDirectory(nBufferLength, lpszLocalBuffer);
  372. /*failed for reason other than bufferlength too small*/
  373. if(dwReturnCode == 0){
  374. #if DBG
  375. OutputDebugString("<w_GetCurrentDirectory> GetCurrentDirectory() FAILed\n");
  376. #endif /* DBG */
  377. LocalFree(lpszLocalBuffer);
  378. return(1);
  379. }
  380. /*test for success, if dwReturnCode is > buffer, then need increase buffer*/
  381. if(dwReturnCode > nBufferLength){
  382. lpszLocalBuffer = LocalReAlloc(lpszLocalBuffer, nBufferLength + LOCALBUFFERSIZE, LMEM_ZEROINIT | LMEM_MOVEABLE);
  383. if(lpszLocalBuffer == NULL){
  384. #if DBG
  385. OutputDebugString("<w_GetCurrentDirectory> LocalAlloc FAILed\n");
  386. #endif /* DBG */
  387. LocalFree(lpszLocalBuffer);
  388. return(1);
  389. }
  390. else{
  391. nBufferLength += LOCALBUFFERSIZE;
  392. }
  393. goto GetCurDir1;
  394. }
  395. /*now I have string that contains EITHER current drive in a drive letter*/
  396. /*or current drive by a UNC name*/
  397. /*BUG BUG UNC name check uncoded, since I have to go from UNC name to drive letter*/
  398. /*debug code, to make sure iDrive == current drive*/
  399. /*see if drive letter based string*/
  400. if(lpszLocalBuffer[1] == ':'){
  401. /*is Drive letter based!*/
  402. /*never know case of returned string from kernel*/
  403. if(isupper(lpszLocalBuffer[0])){
  404. iDriveNumber = lpszLocalBuffer[0] - 'A';
  405. }
  406. else{
  407. iDriveNumber = lpszLocalBuffer[0] - 'a';
  408. }
  409. /*DEBUG make sure that we are indeed setting a new drive */
  410. /* remember that iDrive == 0 means use current drive!*/
  411. if(iDrive == iDriveNumber || iDrive == 0){
  412. /*is current drive and drive letter based, set to after "x:\"*/
  413. strcpy(lpszCurrentDirectory, lpszLocalBuffer); /*copy directory to pointer*/
  414. }
  415. else{ /* is different drive, or not using current drive (== 0)*/
  416. SetCurrentDrive(iDriveNumber); /*set new drive "<iDrive>:\" */
  417. /*now that new drive/dir is set, return current dir*/
  418. /* BUG BUG, because setting drive, overides cur dir, I return*/
  419. /* "<newdrive>:\" */
  420. strcpy(lpszCurrentDirectory, "c:\\");
  421. lpszCurrentDirectory[0] = (char) (iDriveNumber + 'a'); /*set new drive*/
  422. }
  423. }
  424. else{
  425. /*is NOT drive letter based*/
  426. /* BUG BUG need write code to parse UNC, and return only the path*/
  427. /* BUG BUGalso need check to see if iDrive == UNC drive, so I gotta*/
  428. /* convert UNC path to drive, and compare*/
  429. #if DBG
  430. OutputDebugString("<w_GetCurrentDirectory> Took path for UNC, and no code!\n");
  431. #endif /* DBG */
  432. LocalFree(lpszLocalBuffer);
  433. return(1);
  434. }
  435. LocalFree(lpszLocalBuffer);
  436. return(0); /*success*/
  437. }
  438. /*** w_SetCurrentDirectory -- SetCurrent Working Directory and drive
  439. *
  440. * int w_SetCurrentDirectory(LPSTR lpszCurrentDirectory)
  441. *
  442. * ENTRY - LPSTR lpszCurrentDirectory - string to set current drive/dir to
  443. *
  444. * EXIT - int iReturnCode - returns (0) if success
  445. *
  446. * SYNOPSIS - calls SetCurrentDirectory to set current directory and drive.
  447. * WARNINGS -
  448. * EFFECTS -
  449. *
  450. */
  451. int w_SetCurrentDirectory(LPSTR lpszCurrentDirectory)
  452. {
  453. DWORD dwReturnCode;
  454. dwReturnCode = SetCurrentDirectory(lpszCurrentDirectory);
  455. if(dwReturnCode == 0){
  456. #if DBG
  457. OutputDebugString("<w_SetCurrentDirectory> SetCurrentDirectory FAILed!\n");
  458. #endif /* DBG */
  459. return(1);
  460. }
  461. return(0); /*success*/
  462. }
  463. /*** DosDelete -- Delete named file.
  464. *
  465. * int DosDelete(LPSTR lpszFileToDelete)
  466. *
  467. * ENTRY - LPSTR lpszFileToDelete - filename to delete.
  468. *
  469. * EXIT - int xxx - returns (0) if success
  470. *
  471. * SYNOPSIS - calls win32 DeleteFile.
  472. * WARNINGS -
  473. * EFFECTS -
  474. *
  475. */
  476. int DosDelete(LPSTR lpszFileToDelete)
  477. {
  478. BOOL bReturnCode;
  479. LPSTR lpszLocalBuffer; /*local buffer for AnsiToOem()*/
  480. DWORD nBufferLength;
  481. nBufferLength = strlen(lpszFileToDelete) + 1;
  482. /*alloc local, non-moveable, zero filled buffer*/
  483. lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength);
  484. if(lpszLocalBuffer == NULL){
  485. #if DBG
  486. OutputDebugString("<DosDelete> LocalAlloc FAILed\n");
  487. #endif /* DBG */
  488. return 1;
  489. }
  490. AnsiToOem(lpszFileToDelete, lpszLocalBuffer);
  491. bReturnCode = DeleteFile(lpszLocalBuffer);
  492. LocalFree(lpszLocalBuffer);
  493. if(bReturnCode){
  494. return(0);
  495. }
  496. else{
  497. return(1);
  498. }
  499. }
  500. /*** DosRename -- Rename file.
  501. *
  502. * int DosRename(LPSTR lpszOrgFileName, LPSTR lpszNewFileName)
  503. *
  504. * ENTRY - LPSTR lpszOrgFileName - origianl filename.
  505. * LPSTR lpszNewFileName - New filename.
  506. *
  507. * EXIT - int xxx - returns (0) if success
  508. *
  509. * SYNOPSIS - calls win32 MoveFile.
  510. * WARNINGS -
  511. * EFFECTS -
  512. *
  513. */
  514. int DosRename(LPSTR lpszOrgFileName, LPSTR lpszNewFileName)
  515. {
  516. BOOL bReturnCode;
  517. LPSTR lpszLocalBuffer; /*local buffer for AnsiToOem()*/
  518. LPSTR lpszLocalBuffer1; /*local buffer for AnsiToOem()*/
  519. DWORD nBufferLength;
  520. DWORD nBufferLength1;
  521. nBufferLength = strlen(lpszOrgFileName) + 1;
  522. nBufferLength1 = strlen(lpszNewFileName) + 1;
  523. /*alloc local, non-moveable, zero filled buffer*/
  524. lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength);
  525. if(lpszLocalBuffer == NULL){
  526. #if DBG
  527. OutputDebugString("<DosRename> LocalAlloc FAILed\n");
  528. #endif /* DBG */
  529. return 1;
  530. }
  531. lpszLocalBuffer1 = LocalAlloc(LMEM_ZEROINIT, nBufferLength1);
  532. if(lpszLocalBuffer1 == NULL){
  533. OutputDebugString("<DosRename> LocalAlloc FAILed\n");
  534. }
  535. AnsiToOem(lpszOrgFileName, lpszLocalBuffer);
  536. AnsiToOem(lpszNewFileName, lpszLocalBuffer1);
  537. /*rename file*/
  538. bReturnCode = MoveFile(lpszLocalBuffer, lpszLocalBuffer1);
  539. LocalFree(lpszLocalBuffer);
  540. LocalFree(lpszLocalBuffer1);
  541. if(bReturnCode){
  542. return(0);
  543. }
  544. else{
  545. return(1);
  546. }
  547. }
  548. /*** lmemmove -- move memory.
  549. *
  550. * LPSTR lmemmove(LPSTR lpszDst, LPSTR lpszSrc, WORD wCount)
  551. *
  552. * ENTRY - LPSTR lpszDst - destination
  553. * LPSTR lpszSrc - source
  554. * WORD wCount - number of chars to move.
  555. *
  556. * EXIT - LPSTR lpszDst - returns lpszDst.
  557. *
  558. * SYNOPSIS - calls c runtime. Done cause they hacked lmemove to asm.
  559. * WARNINGS -
  560. * EFFECTS -
  561. *
  562. */
  563. LPSTR lmemmove(LPSTR lpszDst, LPSTR lpszSrc, WORD wCount)
  564. {
  565. return(memmove(lpszDst, lpszSrc, wCount));
  566. }