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.

291 lines
7.7 KiB

  1. /***
  2. *findfile.c - C find file functions
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Defines _findfirst(), _findnext(), and _findclose().
  8. *
  9. *Revision History:
  10. * 08-21-91 BWM Wrote Win32 versions.
  11. * 09-13-91 BWM Changed handle type to long.
  12. * 08-18-92 SKS Add a call to FileTimeToLocalFileTime
  13. * as a temporary fix until _dtoxtime takes UTC
  14. * 08-26-92 SKS creation and last access time should be same as the
  15. * last write time if ctime/atime are not available.
  16. * 01-08-93 SKS Remove change I made 8-26-92. Previous behavior
  17. * was deemed "by design" and preferable.
  18. * 03-30-93 GJF Replaced reference to _dtoxtime with __gmtotime_t. Also
  19. * made _timet_from_ft a static function.
  20. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  21. * 07-21-93 GJF Repaced use of _gmtotime_t by __loctotime_t.
  22. * 11-01-93 CFW Enable Unicode variant.
  23. * 12-28-94 GJF Added _[w]findfirsti64, _[w]findnexti64.
  24. * 09-25-95 GJF __loctotime_t now takes a DST flag, pass -1 in this
  25. * slot to indicate DST status is unknown.
  26. * 10-06-95 SKS Add "const" to "char *" in prototypes for *findfirst().
  27. * Prepend missing underscores to func names in comments.
  28. * 11-13-97 RKP Change longs to INT_PTR for 64 bit support.
  29. * 04-27-99 PML Change INT_PTR to intptr_t.
  30. *
  31. *******************************************************************************/
  32. #include <cruntime.h>
  33. #include <oscalls.h>
  34. #include <errno.h>
  35. #include <io.h>
  36. #include <time.h>
  37. #include <ctime.h>
  38. #include <string.h>
  39. #include <internal.h>
  40. #include <tchar.h>
  41. #ifndef _WIN32
  42. #error ERROR - ONLY WIN32 TARGET SUPPORTED!
  43. #endif
  44. time_t __cdecl __timet_from_ft(FILETIME * pft);
  45. /***
  46. *intptr_t _findfirst(wildspec, finddata) - Find first matching file
  47. *
  48. *Purpose:
  49. * Finds the first file matching a given wild card filespec and
  50. * returns data about the file.
  51. *
  52. *Entry:
  53. * char * wild - file spec optionally containing wild cards
  54. *
  55. * struct _finddata_t * finddata - structure to receive file data
  56. *
  57. *Exit:
  58. * Good return:
  59. * Unique handle identifying the group of files matching the spec
  60. *
  61. * Error return:
  62. * Returns -1 and errno is set to error value
  63. *
  64. *Exceptions:
  65. * None.
  66. *
  67. *******************************************************************************/
  68. #ifdef _USE_INT64
  69. intptr_t __cdecl _tfindfirsti64(
  70. const _TSCHAR * szWild,
  71. struct _tfinddatai64_t * pfd
  72. )
  73. #else /* ndef _USE_INT64 */
  74. intptr_t __cdecl _tfindfirst(
  75. const _TSCHAR * szWild,
  76. struct _tfinddata_t * pfd
  77. )
  78. #endif /* _USE_INT64 */
  79. {
  80. WIN32_FIND_DATA wfd;
  81. HANDLE hFile;
  82. DWORD err;
  83. if ((hFile = FindFirstFile(szWild, &wfd)) == INVALID_HANDLE_VALUE) {
  84. err = GetLastError();
  85. switch (err) {
  86. case ERROR_NO_MORE_FILES:
  87. case ERROR_FILE_NOT_FOUND:
  88. case ERROR_PATH_NOT_FOUND:
  89. errno = ENOENT;
  90. break;
  91. case ERROR_NOT_ENOUGH_MEMORY:
  92. errno = ENOMEM;
  93. break;
  94. default:
  95. errno = EINVAL;
  96. break;
  97. }
  98. return (-1);
  99. }
  100. pfd->attrib = (wfd.dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
  101. ? 0 : wfd.dwFileAttributes;
  102. pfd->time_create = __timet_from_ft(&wfd.ftCreationTime);
  103. pfd->time_access = __timet_from_ft(&wfd.ftLastAccessTime);
  104. pfd->time_write = __timet_from_ft(&wfd.ftLastWriteTime);
  105. #ifdef _USE_INT64
  106. pfd->size = ((__int64)(wfd.nFileSizeHigh)) * (0x100000000i64) +
  107. (__int64)(wfd.nFileSizeLow);
  108. #else /* ndef _USE_INT64 */
  109. pfd->size = wfd.nFileSizeLow;
  110. #endif /* ndef _USE_INT64 */
  111. _tcscpy(pfd->name, wfd.cFileName);
  112. return ((intptr_t)hFile);
  113. }
  114. /***
  115. *int _findnext(hfind, finddata) - Find next matching file
  116. *
  117. *Purpose:
  118. * Finds the next file matching a given wild card filespec and
  119. * returns data about the file.
  120. *
  121. *Entry:
  122. * hfind - handle from _findfirst
  123. *
  124. * struct _finddata_t * finddata - structure to receive file data
  125. *
  126. *Exit:
  127. * Good return:
  128. * 0 if file found
  129. * -1 if error or file not found
  130. * errno set
  131. *
  132. *Exceptions:
  133. * None.
  134. *
  135. *******************************************************************************/
  136. #ifdef _USE_INT64
  137. int __cdecl _tfindnexti64(intptr_t hFile, struct _tfinddatai64_t * pfd)
  138. #else /* ndef _USE_INT64 */
  139. int __cdecl _tfindnext(intptr_t hFile, struct _tfinddata_t * pfd)
  140. #endif /* _USE_INT64 */
  141. {
  142. WIN32_FIND_DATA wfd;
  143. DWORD err;
  144. if (!FindNextFile((HANDLE)hFile, &wfd)) {
  145. err = GetLastError();
  146. switch (err) {
  147. case ERROR_NO_MORE_FILES:
  148. case ERROR_FILE_NOT_FOUND:
  149. case ERROR_PATH_NOT_FOUND:
  150. errno = ENOENT;
  151. break;
  152. case ERROR_NOT_ENOUGH_MEMORY:
  153. errno = ENOMEM;
  154. break;
  155. default:
  156. errno = EINVAL;
  157. break;
  158. }
  159. return (-1);
  160. }
  161. pfd->attrib = (wfd.dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
  162. ? 0 : wfd.dwFileAttributes;
  163. pfd->time_create = __timet_from_ft(&wfd.ftCreationTime);
  164. pfd->time_access = __timet_from_ft(&wfd.ftLastAccessTime);
  165. pfd->time_write = __timet_from_ft(&wfd.ftLastWriteTime);
  166. #ifdef _USE_INT64
  167. pfd->size = ((__int64)(wfd.nFileSizeHigh)) * (0x100000000i64) +
  168. (__int64)(wfd.nFileSizeLow);
  169. #else /* ndef _USE_INT64 */
  170. pfd->size = wfd.nFileSizeLow;
  171. #endif /* ndef _USE_INT64 */
  172. _tcscpy(pfd->name, wfd.cFileName);
  173. return (0);
  174. }
  175. #if !defined(_UNICODE) && !defined(_USE_INT64)
  176. /***
  177. *int _findclose(hfind) - Release resources of find
  178. *
  179. *Purpose:
  180. * Releases resources of a group of files found by _findfirst and
  181. * _findnext
  182. *
  183. *Entry:
  184. * hfind - handle from _findfirst
  185. *
  186. *Exit:
  187. * Good return:
  188. * 0 if success
  189. * -1 if fail, errno set
  190. *
  191. *Exceptions:
  192. * None.
  193. *
  194. *******************************************************************************/
  195. int __cdecl _findclose(intptr_t hFile)
  196. {
  197. if (!FindClose((HANDLE)hFile)) {
  198. errno = EINVAL;
  199. return (-1);
  200. }
  201. return (0);
  202. }
  203. /***
  204. *time_t _fttotimet(ft) - convert Win32 file time to Xenix time
  205. *
  206. *Purpose:
  207. * converts a Win32 file time value to Xenix time_t
  208. *
  209. * Note: We cannot directly use the ft value. In Win32, the file times
  210. * returned by the API are ambiguous. In Windows NT, they are UTC. In
  211. * Win32S, and probably also Win32C, they are local time values. Thus,
  212. * the value in ft must be converted to a local time value (by an API)
  213. * before we can use it.
  214. *
  215. *Entry:
  216. * int yr, mo, dy - date
  217. * int hr, mn, sc - time
  218. *
  219. *Exit:
  220. * returns Xenix time value
  221. *
  222. *Exceptions:
  223. *
  224. *******************************************************************************/
  225. time_t __cdecl __timet_from_ft(FILETIME * pft)
  226. {
  227. SYSTEMTIME st;
  228. FILETIME lft;
  229. /* 0 FILETIME returns a -1 time_t */
  230. if (!pft->dwLowDateTime && !pft->dwHighDateTime) {
  231. return (-1L);
  232. }
  233. /*
  234. * Convert to a broken down local time value
  235. */
  236. if ( !FileTimeToLocalFileTime(pft, &lft) ||
  237. !FileTimeToSystemTime(&lft, &st) )
  238. {
  239. return (-1L);
  240. }
  241. return ( __loctotime_t(st.wYear,
  242. st.wMonth,
  243. st.wDay,
  244. st.wHour,
  245. st.wMinute,
  246. st.wSecond,
  247. -1) );
  248. }
  249. #endif