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.

561 lines
16 KiB

  1. /*++
  2. Copyright (c) 1989 - 1999 Microsoft Corporation
  3. Module Name:
  4. fileinfo.c
  5. Abstract:
  6. This module implements the mini redirector call down routines pertaining to retrieval/
  7. update of file/directory/volume information.
  8. --*/
  9. #include "precomp.h"
  10. #pragma hdrstop
  11. #pragma warning(error:4101) // Unreferenced local variable
  12. //
  13. // The local debug trace level
  14. //
  15. #define Dbg (DEBUG_TRACE_FILEINFO)
  16. NTSTATUS
  17. NulMRxQueryDirectory(
  18. IN OUT PRX_CONTEXT RxContext
  19. )
  20. /*++
  21. Routine Description:
  22. This routine does a directory query. Only the NT-->NT path is implemented.
  23. Arguments:
  24. RxContext - the RDBSS context
  25. Return Value:
  26. NTSTATUS - The return status for the operation
  27. --*/
  28. {
  29. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  30. FILE_INFORMATION_CLASS FileInformationClass;
  31. PVOID Buffer;
  32. PULONG pLengthRemaining;
  33. ULONG CopySize;
  34. FileInformationClass = RxContext->Info.FileInformationClass;
  35. Buffer = RxContext->Info.Buffer;
  36. pLengthRemaining = &RxContext->Info.LengthRemaining;
  37. switch (FileInformationClass)
  38. {
  39. case FileDirectoryInformation:
  40. {
  41. PFILE_DIRECTORY_INFORMATION pDirInfo = (PFILE_DIRECTORY_INFORMATION) Buffer;
  42. CopySize = sizeof( FILE_DIRECTORY_INFORMATION );
  43. if ( *pLengthRemaining >= CopySize )
  44. {
  45. RtlZeroMemory( pDirInfo, CopySize );
  46. pDirInfo->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
  47. pDirInfo->FileNameLength = sizeof( WCHAR );
  48. pDirInfo->FileName[0] = L'.';
  49. *pLengthRemaining -= CopySize;
  50. Status = RxContext->QueryDirectory.InitialQuery ?
  51. STATUS_SUCCESS : STATUS_NO_MORE_FILES;
  52. }
  53. }
  54. break;
  55. case FileFullDirectoryInformation:
  56. {
  57. PFILE_FULL_DIR_INFORMATION pFullDirInfo = (PFILE_FULL_DIR_INFORMATION) Buffer;
  58. CopySize = sizeof( FILE_FULL_DIR_INFORMATION );
  59. if ( *pLengthRemaining >= CopySize )
  60. {
  61. RtlZeroMemory( pFullDirInfo, CopySize );
  62. pFullDirInfo->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
  63. pFullDirInfo->FileNameLength = sizeof( WCHAR );
  64. pFullDirInfo->FileName[0] = L'.';
  65. *pLengthRemaining -= CopySize;
  66. Status = RxContext->QueryDirectory.InitialQuery ?
  67. STATUS_SUCCESS : STATUS_NO_MORE_FILES;
  68. }
  69. }
  70. break;
  71. case FileBothDirectoryInformation:
  72. {
  73. PFILE_BOTH_DIR_INFORMATION pBothDirInfo = (PFILE_BOTH_DIR_INFORMATION) Buffer;
  74. CopySize = sizeof( FILE_BOTH_DIR_INFORMATION );
  75. if ( *pLengthRemaining >= CopySize )
  76. {
  77. RtlZeroMemory( pBothDirInfo, CopySize );
  78. pBothDirInfo->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
  79. pBothDirInfo->FileNameLength = sizeof( WCHAR );
  80. pBothDirInfo->FileName[0] = L'.';
  81. pBothDirInfo->ShortNameLength = sizeof( WCHAR );
  82. pBothDirInfo->ShortName[0] = L'.';
  83. *pLengthRemaining -= CopySize;
  84. Status = RxContext->QueryDirectory.InitialQuery ?
  85. STATUS_SUCCESS : STATUS_NO_MORE_FILES;
  86. }
  87. }
  88. break;
  89. case FileNamesInformation:
  90. {
  91. PFILE_NAMES_INFORMATION pNamesDirInfo = (PFILE_NAMES_INFORMATION) Buffer;
  92. CopySize = sizeof( FILE_NAMES_INFORMATION );
  93. if ( *pLengthRemaining >= CopySize )
  94. {
  95. RtlZeroMemory( pNamesDirInfo, CopySize );
  96. pNamesDirInfo->FileNameLength = sizeof( WCHAR );
  97. pNamesDirInfo->FileName[0] = L'.';
  98. *pLengthRemaining -= CopySize;
  99. Status = RxContext->QueryDirectory.InitialQuery ?
  100. STATUS_SUCCESS : STATUS_NO_MORE_FILES;
  101. }
  102. }
  103. break;
  104. default:
  105. RxDbgTrace( 0, Dbg, ("NulMRxQueryDirectory: Invalid FS information class\n"));
  106. Status = STATUS_INVALID_PARAMETER;
  107. break;
  108. }
  109. DbgPrint("NulMRxQueryDirectory \n");
  110. return(Status);
  111. }
  112. NTSTATUS
  113. NulMRxQueryVolumeInformation(
  114. IN OUT PRX_CONTEXT RxContext
  115. )
  116. /*++
  117. Routine Description:
  118. This routine queries the volume information
  119. Arguments:
  120. pRxContext - the RDBSS context
  121. FsInformationClass - the kind of Fs information desired.
  122. pBuffer - the buffer for copying the information
  123. pBufferLength - the buffer length ( set to buffer length on input and set
  124. to the remaining length on output)
  125. Return Value:
  126. NTSTATUS - The return status for the operation
  127. --*/
  128. {
  129. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  130. RxCaptureFcb;
  131. ULONG RemainingLength = RxContext->Info.LengthRemaining;
  132. FS_INFORMATION_CLASS FsInformationClass = RxContext->Info.FsInformationClass;
  133. PVOID OriginalBuffer = RxContext->Info.Buffer;
  134. UNICODE_STRING ustrVolume;
  135. ULONG BytesToCopy;
  136. RxTraceEnter("NulMRxQueryVolumeInformation");
  137. switch( FsInformationClass ) {
  138. case FileFsVolumeInformation:
  139. {
  140. PFILE_FS_VOLUME_INFORMATION pVolInfo = (PFILE_FS_VOLUME_INFORMATION) OriginalBuffer;
  141. if(RemainingLength < sizeof(FILE_FS_VOLUME_INFORMATION))
  142. {
  143. break;
  144. }
  145. RtlZeroMemory( pVolInfo, sizeof(FILE_FS_VOLUME_INFORMATION) );
  146. pVolInfo->VolumeCreationTime.QuadPart = 0;
  147. pVolInfo->VolumeSerialNumber = 0xBABAFACE;
  148. pVolInfo->SupportsObjects = FALSE;
  149. RtlInitUnicodeString( &ustrVolume, L"NULMRX" );
  150. RemainingLength -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]);
  151. if (RemainingLength >= (ULONG)ustrVolume.Length) {
  152. BytesToCopy = ustrVolume.Length;
  153. } else {
  154. BytesToCopy = RemainingLength;
  155. }
  156. RtlCopyMemory( &pVolInfo->VolumeLabel[0], (PVOID)ustrVolume.Buffer, BytesToCopy );
  157. RemainingLength -= BytesToCopy;
  158. pVolInfo->VolumeLabelLength = BytesToCopy;
  159. RxContext->Info.LengthRemaining = RemainingLength;
  160. Status = STATUS_SUCCESS;
  161. DbgPrint("FileFsVolumeInformation\n");
  162. }
  163. break;
  164. case FileFsLabelInformation:
  165. DbgPrint("FileFsLabelInformation\n");
  166. break;
  167. case FileFsSizeInformation:
  168. DbgPrint("FileFsSizeInformation\n");
  169. break;
  170. case FileFsDeviceInformation:
  171. DbgPrint("FileFsDeviceInformation\n");
  172. break;
  173. case FileFsAttributeInformation:
  174. {
  175. PFILE_FS_ATTRIBUTE_INFORMATION pAttribInfo =
  176. (PFILE_FS_ATTRIBUTE_INFORMATION) OriginalBuffer;
  177. if(RemainingLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION))
  178. {
  179. break;
  180. }
  181. RtlZeroMemory(pAttribInfo, sizeof(FILE_FS_ATTRIBUTE_INFORMATION));
  182. pAttribInfo->FileSystemAttributes = 0;
  183. pAttribInfo->MaximumComponentNameLength = 32;
  184. RemainingLength -= FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName[0]);
  185. RtlInitUnicodeString( &ustrVolume, L"SampleFS" );
  186. BytesToCopy = RemainingLength;
  187. if(RemainingLength >= ustrVolume.Length)
  188. {
  189. BytesToCopy = ustrVolume.Length;
  190. }
  191. pAttribInfo->FileSystemNameLength = BytesToCopy;
  192. RtlCopyMemory( pAttribInfo->FileSystemName, (PVOID)ustrVolume.Buffer, BytesToCopy );
  193. RemainingLength -= BytesToCopy;
  194. RxContext->Info.LengthRemaining = RemainingLength;
  195. Status = STATUS_SUCCESS;
  196. DbgPrint("FileFsAttributeInformation\n");
  197. }
  198. break;
  199. case FileFsControlInformation:
  200. DbgPrint("FileFsControlInformation\n");
  201. break;
  202. case FileFsFullSizeInformation:
  203. DbgPrint("FileFsFullSizeInformation\n");
  204. break;
  205. case FileFsObjectIdInformation:
  206. DbgPrint("FileFsObjectIdInformation\n");
  207. break;
  208. case FileFsMaximumInformation:
  209. DbgPrint("FileFsMaximumInformation\n");
  210. break;
  211. default:
  212. break;
  213. }
  214. RxTraceLeave(Status);
  215. return(Status);
  216. }
  217. NTSTATUS
  218. NulMRxSetVolumeInformation(
  219. IN OUT PRX_CONTEXT pRxContext
  220. )
  221. /*++
  222. Routine Description:
  223. This routine sets the volume information
  224. Arguments:
  225. pRxContext - the RDBSS context
  226. FsInformationClass - the kind of Fs information desired.
  227. pBuffer - the buffer for copying the information
  228. BufferLength - the buffer length
  229. Return Value:
  230. NTSTATUS - The return status for the operation
  231. --*/
  232. {
  233. NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
  234. DbgPrint("NulMRxSetVolumeInformation \n");
  235. return(Status);
  236. }
  237. NTSTATUS
  238. NulMRxQueryFileInformation(
  239. IN PRX_CONTEXT RxContext
  240. )
  241. /*++
  242. Routine Description:
  243. This routine does a query file info. Only the NT-->NT path is implemented.
  244. The NT-->NT path works by just remoting the call basically without further ado.
  245. Arguments:
  246. RxContext - the RDBSS context
  247. Return Value:
  248. NTSTATUS - The return status for the operation
  249. --*/
  250. {
  251. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  252. ULONG RemainingLength = RxContext->Info.LengthRemaining;
  253. RxCaptureFcb;
  254. FILE_INFORMATION_CLASS FunctionalityRequested =
  255. RxContext->Info.FileInformationClass;
  256. PFILE_STANDARD_INFORMATION pFileStdInfo =
  257. (PFILE_STANDARD_INFORMATION) RxContext->Info.Buffer;
  258. RxTraceEnter("NulMRxQueryFileInformation");
  259. switch( FunctionalityRequested ) {
  260. case FileBasicInformation:
  261. if(RemainingLength < sizeof(FILE_BASIC_INFORMATION)) {
  262. break;
  263. }
  264. RemainingLength -= sizeof(FILE_BASIC_INFORMATION);
  265. Status = STATUS_SUCCESS;
  266. break;
  267. case FileInternalInformation:
  268. if(RemainingLength < sizeof(FILE_INTERNAL_INFORMATION)) {
  269. break;
  270. }
  271. RemainingLength -= sizeof(FILE_INTERNAL_INFORMATION);
  272. Status = STATUS_SUCCESS;
  273. break;
  274. case FileEaInformation:
  275. if(RemainingLength < sizeof(FILE_EA_INFORMATION)) {
  276. break;
  277. }
  278. RemainingLength -= sizeof(FILE_EA_INFORMATION);
  279. Status = STATUS_SUCCESS;
  280. break;
  281. case FileStandardInformation:
  282. if(RemainingLength < sizeof(FILE_STANDARD_INFORMATION)) {
  283. break;
  284. }
  285. RxDbgTrace(0, Dbg, ("FileSize is %d AllocationSize is %d\n",
  286. pFileStdInfo->EndOfFile.LowPart,pFileStdInfo->AllocationSize.LowPart));
  287. //(RxContext->CurrentIrp)->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
  288. RemainingLength -= sizeof(FILE_STANDARD_INFORMATION);
  289. Status = STATUS_SUCCESS;
  290. break;
  291. default:
  292. break;
  293. }
  294. RxContext->Info.LengthRemaining = RemainingLength;
  295. RxTraceLeave(Status);
  296. return(Status);
  297. }
  298. NTSTATUS
  299. NulMRxSetFileInformation(
  300. IN PRX_CONTEXT RxContext
  301. )
  302. /*++
  303. Routine Description:
  304. This routine does a set file info. Only the NT-->NT path is implemented.
  305. The NT-->NT path works by just remoting the call basically without further ado.
  306. Arguments:
  307. RxContext - the RDBSS context
  308. Return Value:
  309. NTSTATUS - The return status for the operation
  310. --*/
  311. {
  312. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  313. RxCaptureFcb;
  314. ULONG BufferLength = RxContext->Info.Length;
  315. FILE_INFORMATION_CLASS FunctionalityRequested =
  316. RxContext->Info.FileInformationClass;
  317. PFILE_END_OF_FILE_INFORMATION pEndOfFileInfo =
  318. (PFILE_END_OF_FILE_INFORMATION) RxContext->Info.Buffer;
  319. LARGE_INTEGER NewAllocationSize;
  320. RxTraceEnter("NulMRxSetFileInformation");
  321. switch( FunctionalityRequested ) {
  322. case FileBasicInformation:
  323. RxDbgTrace(0, Dbg, ("FileBasicInformation\n"));
  324. if(BufferLength < sizeof(FILE_BASIC_INFORMATION))
  325. {
  326. break;
  327. }
  328. Status = STATUS_SUCCESS;
  329. break;
  330. case FileDispositionInformation:
  331. RxDbgTrace(0, Dbg, ("FileDispositionInformation\n"));
  332. if(BufferLength < sizeof(FILE_DISPOSITION_INFORMATION))
  333. {
  334. break;
  335. }
  336. Status = STATUS_SUCCESS;
  337. break;
  338. case FilePositionInformation:
  339. RxDbgTrace(0, Dbg, ("FilePositionInformation\n"));
  340. if(BufferLength < sizeof(FILE_POSITION_INFORMATION))
  341. {
  342. break;
  343. }
  344. Status = STATUS_SUCCESS;
  345. break;
  346. case FileAllocationInformation:
  347. RxDbgTrace(0, Dbg, ("FileAllocationInformation\n"));
  348. RxDbgTrace(0, Dbg, ("AllocSize is %d AllocSizeHigh is %d\n",
  349. pEndOfFileInfo->EndOfFile.LowPart,pEndOfFileInfo->EndOfFile.HighPart));
  350. if(BufferLength < sizeof(FILE_ALLOCATION_INFORMATION))
  351. {
  352. break;
  353. }
  354. Status = STATUS_SUCCESS;
  355. break;
  356. case FileEndOfFileInformation:
  357. RxDbgTrace(0, Dbg, ("FileSize is %d FileSizeHigh is %d\n",
  358. capFcb->Header.AllocationSize.LowPart,capFcb->Header.AllocationSize.HighPart));
  359. if(BufferLength < sizeof(FILE_END_OF_FILE_INFORMATION))
  360. {
  361. break;
  362. }
  363. if( pEndOfFileInfo->EndOfFile.QuadPart >
  364. capFcb->Header.AllocationSize.QuadPart ) {
  365. Status = NulMRxExtendFile(
  366. RxContext,
  367. &pEndOfFileInfo->EndOfFile,
  368. &NewAllocationSize
  369. );
  370. RxDbgTrace(0, Dbg, ("AllocSize is %d AllocSizeHigh is %d\n",
  371. NewAllocationSize.LowPart,NewAllocationSize.HighPart));
  372. //
  373. // Change the file allocation
  374. //
  375. capFcb->Header.AllocationSize.QuadPart = NewAllocationSize.QuadPart;
  376. } else {
  377. Status = NulMRxTruncateFile(
  378. RxContext,
  379. &pEndOfFileInfo->EndOfFile,
  380. &NewAllocationSize
  381. );
  382. }
  383. break;
  384. case FileRenameInformation:
  385. RxDbgTrace(0, Dbg, ("FileRenameInformation\n"));
  386. if(BufferLength < sizeof(FILE_RENAME_INFORMATION))
  387. {
  388. break;
  389. }
  390. Status = STATUS_SUCCESS;
  391. break;
  392. default:
  393. break;
  394. }
  395. RxTraceLeave(Status);
  396. return Status;
  397. }
  398. NTSTATUS
  399. NulMRxSetFileInformationAtCleanup(
  400. IN PRX_CONTEXT RxContext
  401. )
  402. /*++
  403. Routine Description:
  404. This routine sets the file information on cleanup. the old rdr just swallows this operation (i.e.
  405. it doesn't generate it). we are doing the same..........
  406. Arguments:
  407. pRxContext - the RDBSS context
  408. Return Value:
  409. NTSTATUS - The return status for the operation
  410. --*/
  411. {
  412. NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
  413. return(Status);
  414. }