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.

329 lines
8.0 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. findfile.c
  5. Abstract:
  6. This module implements IMFindFirst/IMFindNext
  7. Author:
  8. Revision History:
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #define IMIRROR_DIR_ENUM_BUFFER_SIZE 4096
  13. ULONG
  14. IMConvertNT2Win32Error(
  15. IN NTSTATUS Status
  16. )
  17. /*++
  18. Routine Description:
  19. This API sets the "last error value" and the "last error string"
  20. based on the value of Status. For status codes that don't have
  21. a corresponding error string, the string is set to null.
  22. Arguments:
  23. Status - Supplies the status value to store as the last error value.
  24. Return Value:
  25. The corresponding Win32 error code that was stored in the
  26. "last error value" thread variable.
  27. --*/
  28. {
  29. ULONG dwErrorCode;
  30. dwErrorCode = RtlNtStatusToDosError( Status );
  31. SetLastError( dwErrorCode );
  32. return( dwErrorCode );
  33. }
  34. DWORD
  35. IMFindNextFile(
  36. PIMIRROR_THREAD_CONTEXT ThreadContext,
  37. HANDLE DirHandle,
  38. PFILE_FULL_DIR_INFORMATION *lpFindFileData
  39. )
  40. /*++
  41. ThreadContext - instance data for this enumeration
  42. DirHandle - handle of directory to query.
  43. lpFindFileData - On a successful find, this parameter returns information
  44. about the located file.
  45. Return Value:
  46. TRUE - The operation was successful.
  47. FALSE/NULL - The operation failed. Extended error status is available
  48. using GetLastError.
  49. --*/
  50. {
  51. IO_STATUS_BLOCK IoStatusBlock;
  52. NTSTATUS Status;
  53. if (ThreadContext->FindBufferNext != NULL) {
  54. *lpFindFileData = (PFILE_FULL_DIR_INFORMATION) ThreadContext->FindBufferNext;
  55. if ((*lpFindFileData)->NextEntryOffset > 0) {
  56. ThreadContext->FindBufferNext =
  57. (PVOID)(((PCHAR)*lpFindFileData ) + (*lpFindFileData)->NextEntryOffset );
  58. } else {
  59. ThreadContext->FindBufferNext = NULL;
  60. }
  61. return ERROR_SUCCESS;
  62. }
  63. ThreadContext->FindBufferNext = NULL;
  64. Status = NtQueryDirectoryFile(
  65. DirHandle,
  66. NULL,
  67. NULL,
  68. NULL,
  69. &IoStatusBlock,
  70. ThreadContext->FindBufferBase,
  71. ThreadContext->FindBufferLength,
  72. FileFullDirectoryInformation,
  73. FALSE, // return multiple entries
  74. NULL,
  75. FALSE // not a rescan
  76. );
  77. if (NT_SUCCESS( Status )) {
  78. *lpFindFileData = (PFILE_FULL_DIR_INFORMATION) ThreadContext->FindBufferBase;
  79. if ((*lpFindFileData)->NextEntryOffset > 0) {
  80. ThreadContext->FindBufferNext =
  81. (PVOID)(((PCHAR) *lpFindFileData ) + (*lpFindFileData)->NextEntryOffset );
  82. }
  83. return STATUS_SUCCESS;
  84. }
  85. *lpFindFileData = NULL;
  86. if (Status == STATUS_NO_MORE_FILES ||
  87. Status == STATUS_NO_SUCH_FILE ||
  88. Status == STATUS_OBJECT_NAME_NOT_FOUND) {
  89. return STATUS_SUCCESS;
  90. }
  91. return IMConvertNT2Win32Error( Status );
  92. }
  93. DWORD
  94. IMFindFirstFile(
  95. PIMIRROR_THREAD_CONTEXT ThreadContext,
  96. HANDLE DirHandle,
  97. PFILE_FULL_DIR_INFORMATION *lpFindFileData
  98. )
  99. /*++
  100. Routine Description:
  101. This returns all entries in a directory. This allocates a buffer if
  102. needed and sets up the variables in the ThreadContext to track the
  103. enumeration.
  104. Arguments:
  105. ThreadContext - instance data for this enumeration
  106. DirHandle - handle of directory to query.
  107. lpFindFileData - Supplies a pointer to a full dir info structure.
  108. This points into our buffer and should not be freed by the caller.
  109. No call is required to close this, but note that a thread context
  110. can only have a single enumeration going on at any time.
  111. Return Value:
  112. Win32 error. ERROR_SUCCESS is only successful case.
  113. --*/
  114. {
  115. IO_STATUS_BLOCK IoStatusBlock;
  116. NTSTATUS Status;
  117. UNICODE_STRING allFiles;
  118. if (ThreadContext->FindBufferBase == NULL) {
  119. ThreadContext->FindBufferBase = IMirrorAllocMem( IMIRROR_DIR_ENUM_BUFFER_SIZE );
  120. if (ThreadContext->FindBufferBase == NULL) {
  121. return STATUS_NO_MEMORY;
  122. }
  123. ThreadContext->FindBufferLength = IMIRROR_DIR_ENUM_BUFFER_SIZE;
  124. }
  125. RtlInitUnicodeString( &allFiles, L"*" );
  126. ThreadContext->FindBufferNext = NULL;
  127. Status = NtQueryDirectoryFile(
  128. DirHandle,
  129. NULL,
  130. NULL,
  131. NULL,
  132. &IoStatusBlock,
  133. ThreadContext->FindBufferBase,
  134. ThreadContext->FindBufferLength,
  135. FileFullDirectoryInformation,
  136. FALSE, // return multiple entries
  137. &allFiles,
  138. TRUE
  139. );
  140. if (NT_SUCCESS( Status )) {
  141. *lpFindFileData = (PFILE_FULL_DIR_INFORMATION) ThreadContext->FindBufferBase;
  142. if ((*lpFindFileData)->NextEntryOffset > 0) {
  143. ThreadContext->FindBufferNext =
  144. (PVOID)(((PCHAR) *lpFindFileData ) + (*lpFindFileData)->NextEntryOffset );
  145. }
  146. } else {
  147. *lpFindFileData = NULL;
  148. }
  149. return IMConvertNT2Win32Error( Status );
  150. }
  151. #if 0
  152. BOOL
  153. IMSetFileTime(
  154. HANDLE hFile,
  155. CONST FILETIME *lpCreationTime,
  156. CONST FILETIME *lpLastAccessTime,
  157. CONST FILETIME *lpLastWriteTime,
  158. CONST FILETIME *lpChangeTime
  159. )
  160. /*++
  161. Routine Description:
  162. Identical to SetFileTime Win32 api, expect this also allows to specify a new ChangeTime.
  163. Arguments:
  164. hFile - Supplies an open handle to a file whose modification date and
  165. times are to be written. The file handle must have been created
  166. with GENERIC_WRITE access to the file.
  167. lpCreationTime - An optional parameter, that if specified supplies
  168. the new creation time for the file. Some file system's do not
  169. support this time value, so this parameter may be ignored.
  170. lpLastAccessTime - An optional parameter, that if specified supplies
  171. the new last access time for the file. Some file system's do
  172. not support this time value, so this parameter may be ignored.
  173. lpLastWriteTime - An optional parameter, that if specified supplies
  174. the new last write time for the file. A file system must support
  175. this time value.
  176. lpChangeTime - An optional parameter, that if specified supplies
  177. the new change time for the file. A file system must support
  178. this time value.
  179. Return Value:
  180. TRUE - The operation was successful.
  181. FALSE/NULL - The operation failed. Extended error status is available
  182. using GetLastError.
  183. --*/
  184. {
  185. NTSTATUS Status;
  186. IO_STATUS_BLOCK IoStatusBlock;
  187. FILE_BASIC_INFORMATION BasicInfo;
  188. //
  189. // Zero all the time values we can set.
  190. //
  191. RtlZeroMemory(&BasicInfo,sizeof(BasicInfo));
  192. //
  193. // For each time value that is specified, copy it to the I/O system
  194. // record.
  195. //
  196. if (ARGUMENT_PRESENT( lpCreationTime )) {
  197. BasicInfo.CreationTime.LowPart = lpCreationTime->dwLowDateTime;
  198. BasicInfo.CreationTime.HighPart = lpCreationTime->dwHighDateTime;
  199. }
  200. if (ARGUMENT_PRESENT( lpLastAccessTime )) {
  201. BasicInfo.LastAccessTime.LowPart = lpLastAccessTime->dwLowDateTime;
  202. BasicInfo.LastAccessTime.HighPart = lpLastAccessTime->dwHighDateTime;
  203. }
  204. if (ARGUMENT_PRESENT( lpLastWriteTime )) {
  205. BasicInfo.LastWriteTime.LowPart = lpLastWriteTime->dwLowDateTime;
  206. BasicInfo.LastWriteTime.HighPart = lpLastWriteTime->dwHighDateTime;
  207. }
  208. if (ARGUMENT_PRESENT( lpChangeTime )) {
  209. BasicInfo.ChangeTime.LowPart = lpChangeTime->dwLowDateTime;
  210. BasicInfo.ChangeTime.HighPart = lpChangeTime->dwHighDateTime;
  211. }
  212. //
  213. // Set the requested times.
  214. //
  215. Status = NtSetInformationFile(
  216. hFile,
  217. &IoStatusBlock,
  218. &BasicInfo,
  219. sizeof(BasicInfo),
  220. FileBasicInformation
  221. );
  222. if ( NT_SUCCESS(Status) ) {
  223. return TRUE;
  224. } else {
  225. IMConvertNT2Win32Error(Status);
  226. return FALSE;
  227. }
  228. }
  229. #endif