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.

868 lines
19 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. ////
  23. // file.c - file functions
  24. ////
  25. #include "winlocal.h"
  26. #include <stdlib.h>
  27. #include <io.h>
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include "file.h"
  31. #ifdef FILESUP
  32. #include "filesup.h"
  33. #endif
  34. #include "mem.h"
  35. #include "str.h"
  36. ////
  37. // private definitions
  38. ////
  39. // file control struct
  40. //
  41. typedef struct FIL
  42. {
  43. DWORD dwVersion;
  44. HINSTANCE hInst;
  45. HTASK hTask;
  46. #ifdef _WIN32
  47. HANDLE hf;
  48. #else
  49. HFILE hf;
  50. #endif
  51. BOOL fTaskOwned;
  52. LPBYTE lpabBuf;
  53. long iBuf;
  54. long cbBuf;
  55. } FIL, FAR *LPFIL;
  56. #define FILEREADLINE_BUFSIZ 4096
  57. #ifdef FILESUP
  58. static int cFileSupUsage = 0;
  59. static HWND hwndFileSup = NULL;
  60. #endif
  61. static TCHAR szFileName[_MAX_PATH];
  62. static struct _stat statbuf;
  63. static TCHAR szPath[_MAX_PATH];
  64. static TCHAR szDrive[_MAX_DRIVE];
  65. static TCHAR szDir[_MAX_DIR];
  66. static TCHAR szFname[_MAX_FNAME];
  67. static TCHAR szExt[_MAX_EXT];
  68. // helper functions
  69. //
  70. static LPFIL FileGetPtr(HFIL hFile);
  71. static HFIL FileGetHandle(LPFIL lpFile);
  72. #ifdef FILESUP
  73. static int FileSupUsage(int nDelta);
  74. static int FileSupInit(void);
  75. static int FileSupTerm(void);
  76. #endif
  77. ////
  78. // public functions
  79. ////
  80. // FileCreate - create a new file or truncate existing file
  81. // see _lcreate() documentation for behavior
  82. // <fTaskOwned> (i) who should own the new file handle?
  83. // TRUE calling task should own the file handle
  84. #ifdef FILESUP
  85. // FALSE filesup.exe should own the file handle
  86. #endif
  87. // returns file handle if success or NULL
  88. //
  89. HFIL DLLEXPORT WINAPI FileCreate(LPCTSTR lpszFilename, int fnAttribute, BOOL fTaskOwned)
  90. {
  91. BOOL fSuccess = TRUE;
  92. LPFIL lpFile;
  93. DWORD dwVersion = FILE_VERSION; // currently not supplied by caller
  94. HINSTANCE hInst = NULL; // currently not supplied by caller
  95. if (lpszFilename == NULL)
  96. fSuccess = FALSE;
  97. else if ((lpFile = (LPFIL) MemAlloc(NULL, sizeof(FIL), 0)) == NULL)
  98. fSuccess = FALSE;
  99. else
  100. {
  101. lpFile->dwVersion = dwVersion;
  102. lpFile->hInst = hInst;
  103. lpFile->hTask = GetCurrentTask();
  104. #ifdef _WIN32
  105. lpFile->hf = NULL;
  106. #else
  107. lpFile->hf = HFILE_ERROR;
  108. #endif
  109. #ifdef FILESUP
  110. lpFile->fTaskOwned = fTaskOwned;
  111. #else
  112. lpFile->fTaskOwned = TRUE;
  113. #endif
  114. lpFile->lpabBuf = NULL;
  115. lpFile->iBuf = -1L;
  116. lpFile->cbBuf = 0L;
  117. if (lpFile->fTaskOwned)
  118. {
  119. #ifdef _WIN32
  120. if ((lpFile->hf = CreateFile(lpszFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
  121. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | \
  122. ((fnAttribute & 1) ? FILE_ATTRIBUTE_READONLY : 0) | \
  123. ((fnAttribute & 2) ? FILE_ATTRIBUTE_HIDDEN : 0) | \
  124. ((fnAttribute & 4) ? FILE_ATTRIBUTE_SYSTEM : 0), NULL)) == NULL)
  125. #else
  126. if ((lpFile->hf = _lcreat(lpszFilename, fnAttribute)) == HFILE_ERROR)
  127. #endif
  128. fSuccess = FALSE;
  129. }
  130. #ifdef FILESUP
  131. else
  132. {
  133. if (FileSupUsage(+1) != 0)
  134. fSuccess = FALSE;
  135. else
  136. {
  137. FILECREATE fc;
  138. fc.lpszFilename = lpszFilename;
  139. fc.fnAttribute = fnAttribute;
  140. if (hwndFileSup == NULL)
  141. fSuccess = FALSE;
  142. else if ((lpFile->hf = (HFILE) SendMessage(hwndFileSup,
  143. WM_FILECREATE, 0, (LPARAM) (LPFILECREATE) &fc)) == HFILE_ERROR)
  144. fSuccess = FALSE;
  145. if (!fSuccess)
  146. FileSupUsage(-1);
  147. }
  148. }
  149. #endif
  150. }
  151. return fSuccess ? FileGetHandle(lpFile) : NULL;
  152. }
  153. // FileOpen - open an existing file
  154. // see _lopen() documentation for behavior
  155. // <fTaskOwned> (i) who should own the new file handle?
  156. // TRUE calling task should own the file handle
  157. #ifdef FILESUP
  158. // FALSE filesup.exe should own the file handle
  159. #endif
  160. // returns file handle if success or NULL
  161. //
  162. HFIL DLLEXPORT WINAPI FileOpen(LPCTSTR lpszFilename, int fnOpenMode, BOOL fTaskOwned)
  163. {
  164. BOOL fSuccess = TRUE;
  165. LPFIL lpFile;
  166. DWORD dwVersion = FILE_VERSION; // currently not supplied by caller
  167. HINSTANCE hInst = NULL; // currently not supplied by caller
  168. if (lpszFilename == NULL)
  169. fSuccess = FALSE;
  170. else if ((lpFile = (LPFIL) MemAlloc(NULL, sizeof(FIL), 0)) == NULL)
  171. fSuccess = FALSE;
  172. else
  173. {
  174. lpFile->dwVersion = dwVersion;
  175. lpFile->hInst = hInst;
  176. lpFile->hTask = GetCurrentTask();
  177. #ifdef _WIN32
  178. lpFile->hf = NULL;
  179. #else
  180. lpFile->hf = HFILE_ERROR;
  181. #endif
  182. #ifdef FILESUP
  183. lpFile->fTaskOwned = fTaskOwned;
  184. #else
  185. lpFile->fTaskOwned = TRUE;
  186. #endif
  187. lpFile->lpabBuf = NULL;
  188. lpFile->iBuf = -1L;
  189. lpFile->cbBuf = 0L;
  190. if (lpFile->fTaskOwned)
  191. {
  192. #ifdef _WIN32
  193. if ((lpFile->hf = CreateFile(lpszFilename,
  194. ((fnOpenMode & 3) ? 0 : GENERIC_READ) | \
  195. ((fnOpenMode & 1) ? GENERIC_WRITE : 0) | \
  196. ((fnOpenMode & 2) ? GENERIC_READ | GENERIC_WRITE : 0), \
  197. 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == NULL)
  198. #else
  199. if ((lpFile->hf = _lopen(lpszFilename, fnOpenMode)) == HFILE_ERROR)
  200. #endif
  201. fSuccess = FALSE;
  202. }
  203. #ifdef FILESUP
  204. else
  205. {
  206. if (FileSupUsage(+1) != 0)
  207. fSuccess = FALSE;
  208. else
  209. {
  210. FILEOPEN fo;
  211. fo.lpszFilename = lpszFilename;
  212. fo.fnOpenMode = fnOpenMode;
  213. if (hwndFileSup == NULL)
  214. fSuccess = FALSE;
  215. else if ((lpFile->hf = (HFILE) SendMessage(hwndFileSup,
  216. WM_FILEOPEN, 0, (LPARAM) (LPFILEOPEN) &fo)) == HFILE_ERROR)
  217. fSuccess = FALSE;
  218. if (!fSuccess)
  219. FileSupUsage(-1);
  220. }
  221. }
  222. #endif
  223. }
  224. return fSuccess ? FileGetHandle(lpFile) : NULL;
  225. }
  226. // FileSeek - reposition read/write pointer of an open file
  227. // see _llseek() documentation for behavior
  228. // returns new file position if success or -1
  229. //
  230. LONG DLLEXPORT WINAPI FileSeek(HFIL hFile, LONG lOffset, int nOrigin)
  231. {
  232. BOOL fSuccess = TRUE;
  233. LPFIL lpFile;
  234. //
  235. // We should initialize local variable
  236. //
  237. LONG lPos = 0;
  238. if ((lpFile = FileGetPtr(hFile)) == NULL)
  239. fSuccess = FALSE;
  240. else if (lpFile->fTaskOwned)
  241. {
  242. #ifdef _WIN32
  243. if ((lPos = SetFilePointer(lpFile->hf, lOffset, NULL, (DWORD) nOrigin)) == 0xFFFFFFFF)
  244. #else
  245. if ((lPos = _llseek(lpFile->hf, lOffset, nOrigin)) == HFILE_ERROR)
  246. #endif
  247. fSuccess = FALSE;
  248. }
  249. #ifdef FILESUP
  250. else
  251. {
  252. FILESEEK fs;
  253. fs.hf = lpFile->hf;
  254. fs.lOffset = lOffset;
  255. fs.nOrigin = nOrigin;
  256. if (hwndFileSup == NULL)
  257. fSuccess = FALSE;
  258. else if ((lPos = (LONG) SendMessage(hwndFileSup,
  259. WM_FILESEEK, 0, (LPARAM) (LPFILESEEK) &fs)) == -1L)
  260. fSuccess = FALSE;
  261. }
  262. #endif
  263. // don't use residual bytes in the input buffer
  264. //
  265. if (fSuccess)
  266. {
  267. lpFile->iBuf = -1L;
  268. lpFile->cbBuf = 0L;
  269. }
  270. return fSuccess ? lPos : -1L;
  271. }
  272. // FileRead - read data from an open file
  273. // see _lread() and _hread() documentation for behavior
  274. // returns number of bytes read if success or -1
  275. //
  276. long DLLEXPORT WINAPI FileRead(HFIL hFile, void _huge * hpvBuffer, long cbBuffer)
  277. {
  278. BOOL fSuccess = TRUE;
  279. LPFIL lpFile;
  280. //
  281. // We should initialize local variable
  282. //
  283. LONG lBytes = 0;
  284. if ((lpFile = FileGetPtr(hFile)) == NULL)
  285. fSuccess = FALSE;
  286. else if (lpFile->fTaskOwned)
  287. {
  288. #ifdef _WIN32
  289. if (!ReadFile(lpFile->hf, hpvBuffer, cbBuffer, &lBytes, NULL))
  290. {
  291. fSuccess = FALSE;
  292. lBytes = -1L;
  293. }
  294. #else
  295. if (cbBuffer < 0xFFFF)
  296. lBytes = _lread(lpFile->hf, hpvBuffer, (UINT) cbBuffer);
  297. else
  298. lBytes = _hread(lpFile->hf, hpvBuffer, cbBuffer);
  299. if (lBytes == HFILE_ERROR)
  300. fSuccess = FALSE;
  301. #endif
  302. }
  303. #ifdef FILESUP
  304. else
  305. {
  306. FILEREAD fr;
  307. fr.hf = lpFile->hf;
  308. fr.hpvBuffer = hpvBuffer;
  309. fr.cbBuffer = cbBuffer;
  310. if (hwndFileSup == NULL)
  311. fSuccess = FALSE;
  312. else if ((lBytes = (LONG) SendMessage(hwndFileSup,
  313. WM_FILEREAD, 0, (LPARAM) (LPFILEREAD) &fr)) == HFILE_ERROR)
  314. fSuccess = FALSE;
  315. }
  316. #endif
  317. return fSuccess ? lBytes : -1L;
  318. }
  319. // FileReadLine - read up through the next newline in an open file
  320. // returns number of bytes read if success or -1
  321. //
  322. // NOTE: use of this function causes subsequent input to be buffered
  323. // therefore, once you start using FileReadLine on a file,
  324. // don't go back to using FileRead unless you first call FileSeek
  325. //
  326. long DLLEXPORT WINAPI FileReadLine(HFIL hFile, void _huge * hpvBuffer, long cbBuffer)
  327. {
  328. BOOL fSuccess = TRUE;
  329. LPFIL lpFile;
  330. LONG lBytes;
  331. if ((lpFile = FileGetPtr(hFile)) == NULL)
  332. fSuccess = FALSE;
  333. // allocate buffer space if needed
  334. //
  335. else if (lpFile->lpabBuf == NULL &&
  336. (lpFile->lpabBuf = (LPBYTE) MemAlloc(NULL,
  337. FILEREADLINE_BUFSIZ * sizeof(TCHAR), 0)) == NULL)
  338. fSuccess = FALSE;
  339. else
  340. {
  341. char c;
  342. lBytes = 0;
  343. while (lBytes < cbBuffer)
  344. {
  345. // fill buffer if necessary
  346. //
  347. if (lpFile->iBuf < 0L || lpFile->iBuf >= lpFile->cbBuf)
  348. {
  349. if ((lpFile->cbBuf = FileRead(hFile,
  350. lpFile->lpabBuf, FILEREADLINE_BUFSIZ * sizeof(TCHAR))) <= 0)
  351. break;
  352. lpFile->iBuf = 0L;
  353. }
  354. // get next char from buffer, place it in out buffer
  355. //
  356. if ((c = lpFile->lpabBuf[lpFile->iBuf++]) != '\r')
  357. {
  358. *((LPBYTE) hpvBuffer)++ = c;
  359. ++lBytes;
  360. // reached end of line
  361. //
  362. if (c == '\n')
  363. break;
  364. }
  365. }
  366. // null terminate line
  367. //
  368. if (lBytes > 0)
  369. *((LPBYTE) hpvBuffer) = '\0';
  370. }
  371. return fSuccess ? lBytes : -1L;
  372. }
  373. // FileWrite - write data to an open file
  374. // see _lwrite() and _hwrite() documentation for behavior
  375. // returns number of bytes read if success or -1
  376. //
  377. long DLLEXPORT WINAPI FileWrite(HFIL hFile, const void _huge * hpvBuffer, long cbBuffer)
  378. {
  379. BOOL fSuccess = TRUE;
  380. LPFIL lpFile;
  381. //
  382. // We should initialize local variable
  383. //
  384. LONG lBytes = 0;
  385. if ((lpFile = FileGetPtr(hFile)) == NULL)
  386. fSuccess = FALSE;
  387. else if (lpFile->fTaskOwned)
  388. {
  389. #ifdef _WIN32
  390. if (!WriteFile(lpFile->hf, hpvBuffer, cbBuffer, &lBytes, NULL))
  391. {
  392. fSuccess = FALSE;
  393. lBytes = -1L;
  394. }
  395. #else
  396. if (cbBuffer < 0xFFFF)
  397. lBytes = _lwrite(lpFile->hf, hpvBuffer, (UINT) cbBuffer);
  398. else
  399. lBytes = _hwrite(lpFile->hf, hpvBuffer, cbBuffer);
  400. if (lBytes == HFILE_ERROR)
  401. fSuccess = FALSE;
  402. #endif
  403. }
  404. #ifdef FILESUP
  405. else
  406. {
  407. FILEWRITE fw;
  408. fw.hf = lpFile->hf;
  409. fw.hpvBuffer = hpvBuffer;
  410. fw.cbBuffer = cbBuffer;
  411. if (hwndFileSup == NULL)
  412. fSuccess = FALSE;
  413. else if ((lBytes = (LONG) SendMessage(hwndFileSup,
  414. WM_FILEWRITE, 0, (LPARAM) (LPFILEWRITE) &fw)) == HFILE_ERROR)
  415. fSuccess = FALSE;
  416. }
  417. #endif
  418. return fSuccess ? lBytes : -1L;
  419. }
  420. // FileClose - close an open file
  421. // see _lclose() documentation for behavior
  422. // returns 0 if success
  423. //
  424. int DLLEXPORT WINAPI FileClose(HFIL hFile)
  425. {
  426. BOOL fSuccess = TRUE;
  427. LPFIL lpFile;
  428. if ((lpFile = FileGetPtr(hFile)) == NULL)
  429. fSuccess = FALSE;
  430. else if (lpFile->fTaskOwned)
  431. {
  432. #ifdef _WIN32
  433. if (!CloseHandle(lpFile->hf))
  434. #else
  435. if (_lclose(lpFile->hf) == HFILE_ERROR)
  436. #endif
  437. fSuccess = FALSE;
  438. }
  439. #ifdef FILESUP
  440. else
  441. {
  442. FILECLOSE fc;
  443. HFILE ret;
  444. fc.hf = lpFile->hf;
  445. if (hwndFileSup == NULL)
  446. fSuccess = FALSE;
  447. else if ((ret = (HFILE) SendMessage(hwndFileSup,
  448. WM_FILECLOSE, 0, (LPARAM) (LPFILECLOSE) &fc)) == HFILE_ERROR)
  449. fSuccess = FALSE;
  450. else if (FileSupUsage(-1) != 0)
  451. fSuccess = FALSE;
  452. }
  453. #endif
  454. if (fSuccess)
  455. {
  456. if (lpFile->lpabBuf != NULL &&
  457. (lpFile->lpabBuf = MemFree(NULL, lpFile->lpabBuf)) != NULL)
  458. {
  459. fSuccess = FALSE;
  460. }
  461. if ((lpFile = MemFree(NULL, lpFile)) != NULL)
  462. fSuccess = FALSE;
  463. }
  464. return fSuccess ? 0 : -1;
  465. }
  466. #ifndef NOTRACE
  467. // FileExists - return TRUE if specified file exists
  468. // <lpszFileName> (i) file name
  469. // return TRUE or FALSE
  470. //
  471. BOOL DLLEXPORT WINAPI FileExists(LPCTSTR lpszFileName)
  472. {
  473. BOOL fSuccess = TRUE;
  474. #ifdef _WIN32
  475. if (!CloseHandle(CreateFile(lpszFileName,
  476. GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)))
  477. fSuccess = FALSE;
  478. #else
  479. // we need a near pointer so we can call _stat()
  480. //
  481. StrNCpy(szFileName, lpszFileName, SIZEOFARRAY(szFileName));
  482. // make sure path and file are valid
  483. //
  484. if (_stat(szFileName, &statbuf) != 0)
  485. fSuccess = FALSE;
  486. // make sure it is a regular file (i.e. not a directory)
  487. //
  488. else if ((statbuf.st_mode & _S_IFREG) == 0)
  489. fSuccess = FALSE;
  490. #endif
  491. return fSuccess;
  492. }
  493. // FileFullPath - parse file spec, construct full path
  494. // see _fullpath() documentation for behavior
  495. // return <lpszFullPath> if success or NULL
  496. //
  497. LPTSTR DLLEXPORT WINAPI FileFullPath(LPTSTR lpszPath, LPCTSTR lpszFileName, int sizPath)
  498. {
  499. BOOL fSuccess = TRUE;
  500. // we need near pointers so we can call _fullpath()
  501. //
  502. StrNCpy(szFileName, lpszFileName, SIZEOFARRAY(szFileName));
  503. StrNCpy(szPath, lpszPath, SIZEOFARRAY(szPath));
  504. if (_tfullpath(szPath, szFileName, SIZEOFARRAY(szPath)) == NULL)
  505. fSuccess = FALSE;
  506. else
  507. StrNCpy(lpszPath, szPath, sizPath);
  508. return fSuccess ? lpszPath : NULL;
  509. }
  510. // FileSplitPath - break a full path into its components
  511. // see _splitpath() documentation for behavior
  512. // return 0 if success
  513. //
  514. int DLLEXPORT WINAPI FileSplitPath(LPCTSTR lpszPath, LPTSTR lpszDrive, LPTSTR lpszDir, LPTSTR lpszFname, LPTSTR lpszExt)
  515. {
  516. BOOL fSuccess = TRUE;
  517. // we need near pointers so we can call _splitpath()
  518. //
  519. StrNCpy(szPath, lpszPath, SIZEOFARRAY(szPath));
  520. _tsplitpath(szPath, szDrive, szDir, szFname, szExt);
  521. if (lpszDrive != NULL)
  522. StrCpy(lpszDrive, szDrive);
  523. if (lpszDir != NULL)
  524. StrCpy(lpszDir, szDir);
  525. if (lpszFname != NULL)
  526. StrCpy(lpszFname, szFname);
  527. if (lpszExt != NULL)
  528. StrCpy(lpszExt, szExt);
  529. return fSuccess ? 0 : -1;
  530. }
  531. // FileMakePath - make a full path from specified components
  532. // see _makepath() documentation for behavior
  533. // return 0 if success
  534. //
  535. int DLLEXPORT WINAPI FileMakePath(LPTSTR lpszPath, LPCTSTR lpszDrive, LPCTSTR lpszDir, LPCTSTR lpszFname, LPCTSTR lpszExt)
  536. {
  537. BOOL fSuccess = TRUE;
  538. // we need near pointers so we can call _makepath()
  539. //
  540. *szDrive = '\0';
  541. if (lpszDrive != NULL)
  542. StrNCpy(szDrive, lpszDrive, SIZEOFARRAY(szDrive));
  543. *szDir = '\0';
  544. if (lpszDir != NULL)
  545. StrNCpy(szDir, lpszDir, SIZEOFARRAY(szDir));
  546. *szFname = '\0';
  547. if (lpszFname != NULL)
  548. StrNCpy(szFname, lpszFname, SIZEOFARRAY(szFname));
  549. *szExt = '\0';
  550. if (lpszExt != NULL)
  551. StrNCpy(szExt, lpszExt, SIZEOFARRAY(szExt));
  552. _tmakepath(szPath, szDrive, szDir, szFname, szExt);
  553. if (lpszPath != NULL)
  554. StrCpy(lpszPath, szPath);
  555. return fSuccess ? 0 : -1;
  556. }
  557. // FileRemove - delete specified file
  558. // see remove() documentation for behavior
  559. // return 0 if success
  560. //
  561. int DLLEXPORT WINAPI FileRemove(LPCTSTR lpszFileName)
  562. {
  563. BOOL fSuccess = TRUE;
  564. #ifdef _WIN32
  565. if (!DeleteFile(lpszFileName))
  566. fSuccess = FALSE;
  567. #else
  568. static TCHAR szFileName[_MAX_PATH];
  569. // we need a near pointer so we can call remove()
  570. //
  571. StrNCpy(szFileName, lpszFileName, SIZEOFARRAY(szFileName));
  572. if (remove(szFileName) != 0)
  573. fSuccess = FALSE;
  574. #endif
  575. return fSuccess ? 0 : -1;
  576. }
  577. // FileRename - rename specified file
  578. // see rename() documentation for behavior
  579. // return 0 if success
  580. //
  581. int DLLEXPORT WINAPI FileRename(LPCTSTR lpszOldName, LPCTSTR lpszNewName)
  582. {
  583. BOOL fSuccess = TRUE;
  584. if (_trename(lpszOldName, lpszNewName) != 0)
  585. fSuccess = FALSE;
  586. return fSuccess ? 0 : -1;
  587. }
  588. #endif
  589. // GetTempFileNameEx - create temporary file, extended version
  590. //
  591. // This function is similar to GetTempFileName(),
  592. // except that <lpPrefixString> is replaced by <lpExtensionString>
  593. // See Windows SDK documentation for description of original GetTempFileName()
  594. //
  595. UINT DLLEXPORT WINAPI GetTempFileNameEx(LPCTSTR lpPathName, LPCTSTR lpExtensionString,
  596. UINT uUnique, LPTSTR lpTempFileName)
  597. {
  598. UINT uRet;
  599. TCHAR szTempFileName[_MAX_PATH];
  600. // create temporary file
  601. //
  602. if ((uRet = GetTempFileName(lpPathName,
  603. TEXT("TMP"), uUnique, szTempFileName)) != 0)
  604. {
  605. LPTSTR lpsz;
  606. StrCpy(lpTempFileName, szTempFileName);
  607. if ((lpsz = StrRChr(lpTempFileName, '.')) == NULL)
  608. {
  609. // unable to locate extension in temporary file
  610. //
  611. FileRemove(szTempFileName);
  612. uRet = 0;
  613. }
  614. else
  615. {
  616. // use specified extension to alter file name
  617. //
  618. StrCpy(lpsz + 1, lpExtensionString);
  619. if (FileRename(szTempFileName, lpTempFileName) != 0)
  620. {
  621. // unable to rename temporary file
  622. //
  623. FileRemove(szTempFileName);
  624. uRet = 0;
  625. }
  626. }
  627. }
  628. return uRet;
  629. }
  630. ////
  631. // private functions
  632. ////
  633. // FileGetPtr - verify that file handle is valid,
  634. // <hFile> (i) handle returned by FileCreate or FileOpen
  635. // return corresponding file pointer (NULL if error)
  636. //
  637. static LPFIL FileGetPtr(HFIL hFile)
  638. {
  639. BOOL fSuccess = TRUE;
  640. LPFIL lpFile;
  641. if ((lpFile = (LPFIL) hFile) == NULL)
  642. fSuccess = FALSE;
  643. else if (IsBadWritePtr(lpFile, sizeof(FIL)))
  644. fSuccess = FALSE;
  645. #ifdef CHECKTASK
  646. // make sure current task owns the file handle if appropriate
  647. //
  648. else if (lpFile->fTaskOwned && lpFile->hTask != GetCurrentTask())
  649. fSuccess = FALSE;
  650. #endif
  651. return fSuccess ? lpFile : NULL;
  652. }
  653. // FileGetHandle - verify that file pointer is valid,
  654. // <lpFile> (i) pointer to FIL struct
  655. // return corresponding file handle (NULL if error)
  656. //
  657. static HFIL FileGetHandle(LPFIL lpFile)
  658. {
  659. BOOL fSuccess = TRUE;
  660. HFIL hFile;
  661. if ((hFile = (HFIL) lpFile) == NULL)
  662. fSuccess = FALSE;
  663. return fSuccess ? hFile : NULL;
  664. }
  665. #ifdef FILESUP
  666. // FileSupUsage - adjust filesup.exe usage count
  667. // <nDelta> (i) +1 to increment, -1 to decrement
  668. // return 0 if success
  669. //
  670. static int FileSupUsage(int nDelta)
  671. {
  672. BOOL fSuccess = TRUE;
  673. // increment usage count
  674. //
  675. if (nDelta == +1)
  676. {
  677. // execute filesup.exe if this is the first usage
  678. //
  679. if (cFileSupUsage == 0 && FileSupInit() != 0)
  680. fSuccess = FALSE;
  681. else
  682. ++cFileSupUsage;
  683. }
  684. // decrement usage count
  685. //
  686. else if (nDelta == -1)
  687. {
  688. // terminate filesup.exe if this is the last usage
  689. //
  690. if (cFileSupUsage == 1 && FileSupTerm() != 0)
  691. fSuccess = FALSE;
  692. else
  693. --cFileSupUsage;
  694. }
  695. return fSuccess ? 0 : -1;
  696. }
  697. // FileSupInit - execute filesup.exe and get its window handle
  698. // return 0 if success
  699. //
  700. static int FileSupInit(void)
  701. {
  702. BOOL fSuccess = TRUE;
  703. if ((hwndFileSup = FindWindow(FILESUP_CLASS, NULL)) != NULL)
  704. ; // filesup.exe already running
  705. else if (WinExec(FILESUP_EXE, SW_HIDE) < 32)
  706. fSuccess = FALSE;
  707. else if ((hwndFileSup = FindWindow(FILESUP_CLASS, NULL)) == NULL)
  708. fSuccess = FALSE;
  709. return fSuccess ? 0 : -1;
  710. }
  711. // FileSupTerm - terminate filesup.exe
  712. // return 0 if success
  713. //
  714. static int FileSupTerm(void)
  715. {
  716. BOOL fSuccess = TRUE;
  717. if (hwndFileSup != NULL)
  718. {
  719. // close the window, which also terminates filesup.exe
  720. //
  721. SendMessage(hwndFileSup, WM_CLOSE, 0, 0);
  722. hwndFileSup = NULL;
  723. }
  724. return fSuccess ? 0 : -1;
  725. }
  726. #endif