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.

622 lines
12 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. fileinfo.c
  5. Abstract:
  6. This module implements the get / set volume information routines for
  7. MSFS called by the dispatch driver.
  8. Setting volume information is currently unimplemented in MSFS.
  9. Author:
  10. Manny Weiser (mannyw) 31-Jan-1991
  11. Revision History:
  12. --*/
  13. #include "mailslot.h"
  14. //
  15. // The debug trace level
  16. //
  17. #define Dbg (DEBUG_TRACE_FILEINFO)
  18. //
  19. // Local procedure prototypes.
  20. //
  21. NTSTATUS
  22. MsCommonQueryVolumeInformation (
  23. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  24. IN PIRP Irp
  25. );
  26. NTSTATUS
  27. MsQueryAttributeInfo (
  28. IN PVCB Vcb,
  29. IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
  30. IN ULONG Length,
  31. OUT PULONG BytesWritten
  32. );
  33. NTSTATUS
  34. MsQueryFsVolumeInfo (
  35. IN PVCB Vcb,
  36. IN PFILE_FS_VOLUME_INFORMATION Buffer,
  37. IN ULONG Length,
  38. OUT PULONG BytesWritten
  39. );
  40. NTSTATUS
  41. MsQueryFsSizeInfo (
  42. IN PVCB Vcb,
  43. IN PFILE_FS_SIZE_INFORMATION Buffer,
  44. IN ULONG Length,
  45. OUT PULONG BytesWritten
  46. );
  47. NTSTATUS
  48. MsQueryFsFullSizeInfo (
  49. IN PVCB Vcb,
  50. IN PFILE_FS_FULL_SIZE_INFORMATION Buffer,
  51. IN ULONG Length,
  52. OUT PULONG BytesWritten
  53. );
  54. NTSTATUS
  55. MsQueryFsDeviceInfo (
  56. IN PVCB Vcb,
  57. IN PFILE_FS_DEVICE_INFORMATION Buffer,
  58. IN ULONG Length,
  59. OUT PULONG BytesWritten
  60. );
  61. #ifdef ALLOC_PRAGMA
  62. #pragma alloc_text( PAGE, MsCommonQueryVolumeInformation )
  63. #pragma alloc_text( PAGE, MsFsdQueryVolumeInformation )
  64. #pragma alloc_text( PAGE, MsQueryAttributeInfo )
  65. #pragma alloc_text( PAGE, MsQueryFsVolumeInfo )
  66. #pragma alloc_text( PAGE, MsQueryFsSizeInfo )
  67. #pragma alloc_text( PAGE, MsQueryFsDeviceInfo )
  68. #pragma alloc_text( PAGE, MsQueryFsFullSizeInfo )
  69. #endif
  70. NTSTATUS
  71. MsFsdQueryVolumeInformation (
  72. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  73. IN PIRP Irp
  74. )
  75. /*++
  76. Routine Description:
  77. This routine implements the FSD part of the NtQueryVolumeInformationFile
  78. API calls.
  79. Arguments:
  80. MsfsDeviceObject - Supplies a pointer to the device object to use.
  81. Irp - Supplies a pointer to the Irp to process.
  82. Return Value:
  83. NTSTATUS - The Fsd status for the Irp
  84. --*/
  85. {
  86. NTSTATUS status;
  87. PAGED_CODE();
  88. DebugTrace(+1, Dbg, "MsFsdQueryVolumeInformation\n", 0);
  89. //
  90. // Call the common query volume information routine.
  91. //
  92. FsRtlEnterFileSystem();
  93. status = MsCommonQueryVolumeInformation( MsfsDeviceObject, Irp );
  94. FsRtlExitFileSystem();
  95. //
  96. // Return to the caller.
  97. //
  98. DebugTrace(-1, Dbg, "MsFsdQueryVolumeInformation -> %08lx\n", status );
  99. return status;
  100. }
  101. NTSTATUS
  102. MsCommonQueryVolumeInformation (
  103. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  104. IN PIRP Irp
  105. )
  106. /*++
  107. Routine Description:
  108. This is the common routine for querying volume information.
  109. Arguments:
  110. MsfsDeviceObject - The device object to use.
  111. Irp - Supplies the Irp to process
  112. Return Value:
  113. NTSTATUS - the return status for the operation.
  114. --*/
  115. {
  116. PIO_STACK_LOCATION irpSp;
  117. NTSTATUS status;
  118. ULONG length;
  119. ULONG bytesWritten = 0;
  120. FS_INFORMATION_CLASS fsInformationClass;
  121. PVOID buffer;
  122. NODE_TYPE_CODE nodeTypeCode;
  123. PVCB vcb;
  124. PVOID fsContext, fsContext2;
  125. PAGED_CODE();
  126. //
  127. // Get the current stack location.
  128. //
  129. irpSp = IoGetCurrentIrpStackLocation( Irp );
  130. DebugTrace(+1, Dbg, "MsCommonQueryInformation...\n", 0);
  131. DebugTrace( 0, Dbg, " Irp = %08lx\n", (ULONG)Irp);
  132. DebugTrace( 0, Dbg, " ->Length = %08lx\n", irpSp->Parameters.QueryFile.Length);
  133. DebugTrace( 0, Dbg, " ->FsInformationClass = %08lx\n", irpSp->Parameters.QueryVolume.FsInformationClass);
  134. DebugTrace( 0, Dbg, " ->Buffer = %08lx\n", (ULONG)Irp->AssociatedIrp.SystemBuffer);
  135. //
  136. // Find out who are.
  137. //
  138. if ((nodeTypeCode = MsDecodeFileObject( irpSp->FileObject,
  139. &fsContext,
  140. &fsContext2 )) == NTC_UNDEFINED) {
  141. DebugTrace(0, Dbg, "Mailslot is disconnected from us\n", 0);
  142. MsCompleteRequest( Irp, STATUS_FILE_FORCED_CLOSED );
  143. status = STATUS_FILE_FORCED_CLOSED;
  144. DebugTrace(-1, Dbg, "MsCommonQueryInformation -> %08lx\n", status );
  145. return status;
  146. }
  147. //
  148. // Decide how to handle this request. A user can query information
  149. // on a VCB only.
  150. //
  151. switch (nodeTypeCode) {
  152. case MSFS_NTC_VCB:
  153. vcb = (PVCB)fsContext;
  154. break;
  155. case MSFS_NTC_ROOT_DCB :
  156. //
  157. // Explorer calls us like this. Ship from the root dir to the volume.
  158. //
  159. vcb = (PVCB) ((PROOT_DCB_CCB)fsContext2)->Vcb;
  160. MsReferenceVcb (vcb);
  161. MsDereferenceRootDcb ((PROOT_DCB) fsContext);
  162. break;
  163. default: // This is not a volume control block.
  164. DebugTrace(0, Dbg, "Node type code is not incorrect\n", 0);
  165. MsDereferenceNode( (PNODE_HEADER)fsContext );
  166. MsCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
  167. DebugTrace(-1,
  168. Dbg,
  169. "MsCommonQueryVolumeInformation -> STATUS_INVALID_PARAMETER\n",
  170. 0);
  171. return STATUS_INVALID_PARAMETER;
  172. }
  173. //
  174. // Make local copies of the input parameters.
  175. //
  176. length = irpSp->Parameters.QueryVolume.Length;
  177. fsInformationClass = irpSp->Parameters.QueryVolume.FsInformationClass;
  178. buffer = Irp->AssociatedIrp.SystemBuffer;
  179. //
  180. // Now acquire shared access to the VCB
  181. //
  182. MsAcquireSharedVcb( vcb );
  183. try {
  184. //
  185. // Decide how to handle the request.
  186. //
  187. switch (fsInformationClass) {
  188. case FileFsAttributeInformation:
  189. status = MsQueryAttributeInfo( vcb, buffer, length, &bytesWritten );
  190. break;
  191. case FileFsVolumeInformation:
  192. status = MsQueryFsVolumeInfo( vcb, buffer, length, &bytesWritten );
  193. break;
  194. case FileFsSizeInformation:
  195. status = MsQueryFsSizeInfo( vcb, buffer, length, &bytesWritten );
  196. break;
  197. case FileFsFullSizeInformation:
  198. status = MsQueryFsFullSizeInfo( vcb, buffer, length, &bytesWritten );
  199. break;
  200. case FileFsDeviceInformation:
  201. status = MsQueryFsDeviceInfo( vcb, buffer, length, &bytesWritten );
  202. break;
  203. default:
  204. status = STATUS_INVALID_PARAMETER;
  205. break;
  206. }
  207. } finally {
  208. MsReleaseVcb( vcb );
  209. MsDereferenceVcb( vcb );
  210. //
  211. // Set the information field to the number of bytes actually
  212. // filled in and then complete the request.
  213. //
  214. Irp->IoStatus.Information = bytesWritten;
  215. MsCompleteRequest( Irp, status );
  216. DebugTrace(-1, Dbg, "MsCommonQueryVolumeInformation -> %08lx\n", status );
  217. }
  218. return status;
  219. }
  220. NTSTATUS
  221. MsQueryAttributeInfo (
  222. IN PVCB Vcb,
  223. IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
  224. IN ULONG Length,
  225. OUT PULONG BytesWritten
  226. )
  227. /*++
  228. Routine Description:
  229. This routine performs the query fs attribute information operation.
  230. Arguments:
  231. Vcb - Supplies the VCB to query.
  232. Buffer - Supplies a pointer to the buffer where the information is
  233. to be returned.
  234. Length - Supplies the length of the buffer in bytes.
  235. BytesWritten - Returns the number of bytes written to the buffer.
  236. Return Value:
  237. NTSTATUS - The result of this query.
  238. --*/
  239. {
  240. NTSTATUS status;
  241. PAGED_CODE();
  242. DebugTrace(0, Dbg, "QueryFsAttributeInfo...\n", 0);
  243. //
  244. // See how many bytes of the file system name we can copy.
  245. //
  246. Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName[0] );
  247. if ( Length >= Vcb->FileSystemName.Length ) {
  248. status = STATUS_SUCCESS;
  249. *BytesWritten = Vcb->FileSystemName.Length;
  250. } else {
  251. status = STATUS_BUFFER_OVERFLOW;
  252. *BytesWritten = Length;
  253. }
  254. //
  255. // Fill in the attribute information.
  256. //
  257. Buffer->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
  258. Buffer->MaximumComponentNameLength = MAXIMUM_FILENAME_LENGTH;
  259. //
  260. // And copy over the file name and its length.
  261. //
  262. RtlCopyMemory (&Buffer->FileSystemName[0],
  263. &Vcb->FileSystemName.Buffer[0],
  264. *BytesWritten);
  265. Buffer->FileSystemNameLength = *BytesWritten;
  266. //
  267. // Now account for the fixed part of the structure
  268. //
  269. *BytesWritten += FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName[0] );
  270. return status;
  271. }
  272. NTSTATUS
  273. MsQueryFsVolumeInfo (
  274. IN PVCB Vcb,
  275. IN PFILE_FS_VOLUME_INFORMATION Buffer,
  276. IN ULONG Length,
  277. OUT PULONG BytesWritten
  278. )
  279. /*++
  280. Routine Description:
  281. This routine implements the query volume info call
  282. Arguments:
  283. Vcb - Supplies the VCB to query.
  284. Buffer - Supplies a pointer to the buffer where the information is
  285. to be returned.
  286. Length - Supplies the length of the buffer in bytes.
  287. BytesWritten - Returns the number of bytes written to the buffer.
  288. Return Value:
  289. NTSTATUS - The result of this query.
  290. --*/
  291. {
  292. ULONG BytesToCopy;
  293. NTSTATUS Status;
  294. Status = STATUS_SUCCESS;
  295. Buffer->VolumeCreationTime = Vcb->CreationTime;
  296. Buffer->VolumeSerialNumber = 0;
  297. Buffer->SupportsObjects = FALSE;
  298. Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] );
  299. //
  300. // Check if the buffer we're given is long enough
  301. //
  302. BytesToCopy = sizeof (MSFS_VOLUME_LABEL) - sizeof (WCHAR);
  303. if (Length < BytesToCopy) {
  304. BytesToCopy = Length;
  305. Status = STATUS_BUFFER_OVERFLOW;
  306. }
  307. //
  308. // Copy over what we can of the volume label, and adjust *Length
  309. //
  310. Buffer->VolumeLabelLength = BytesToCopy;
  311. if (BytesToCopy) {
  312. RtlCopyMemory( &Buffer->VolumeLabel[0],
  313. MSFS_VOLUME_LABEL,
  314. BytesToCopy );
  315. }
  316. *BytesWritten = FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] ) + BytesToCopy;
  317. //
  318. // Set our status and return to our caller
  319. //
  320. return Status;
  321. }
  322. NTSTATUS
  323. MsQueryFsSizeInfo (
  324. IN PVCB Vcb,
  325. IN PFILE_FS_SIZE_INFORMATION Buffer,
  326. IN ULONG Length,
  327. OUT PULONG BytesWritten
  328. )
  329. /*++
  330. Routine Description:
  331. This routine implements the query size info call
  332. Arguments:
  333. Vcb - Supplies the VCB to query.
  334. Buffer - Supplies a pointer to the buffer where the information is
  335. to be returned.
  336. Length - Supplies the length of the buffer in bytes.
  337. BytesWritten - Returns the number of bytes written to the buffer.
  338. Return Value:
  339. NTSTATUS - The result of this query.
  340. --*/
  341. {
  342. Buffer->TotalAllocationUnits.QuadPart = 0;
  343. Buffer->AvailableAllocationUnits.QuadPart = 0;
  344. Buffer->SectorsPerAllocationUnit = 0;
  345. Buffer->BytesPerSector = 0;
  346. *BytesWritten = sizeof( FILE_FS_SIZE_INFORMATION );
  347. //
  348. // Set our status and return to our caller
  349. //
  350. return STATUS_SUCCESS;
  351. }
  352. NTSTATUS
  353. MsQueryFsFullSizeInfo (
  354. IN PVCB Vcb,
  355. IN PFILE_FS_FULL_SIZE_INFORMATION Buffer,
  356. IN ULONG Length,
  357. OUT PULONG BytesWritten
  358. )
  359. /*++
  360. Routine Description:
  361. This routine implements the query full size info call
  362. Arguments:
  363. Vcb - Supplies the VCB to query.
  364. Buffer - Supplies a pointer to the buffer where the information is
  365. to be returned.
  366. Length - Supplies the length of the buffer in bytes.
  367. BytesWritten - Returns the number of bytes written to the buffer.
  368. Return Value:
  369. NTSTATUS - The result of this query.
  370. --*/
  371. {
  372. RtlZeroMemory( Buffer, sizeof(FILE_FS_FULL_SIZE_INFORMATION) );
  373. *BytesWritten = sizeof(FILE_FS_FULL_SIZE_INFORMATION);
  374. //
  375. // Set our status and return to our caller
  376. //
  377. return STATUS_SUCCESS;
  378. }
  379. NTSTATUS
  380. MsQueryFsDeviceInfo (
  381. IN PVCB Vcb,
  382. IN PFILE_FS_DEVICE_INFORMATION Buffer,
  383. IN ULONG Length,
  384. OUT PULONG BytesWritten
  385. )
  386. /*++
  387. Routine Description:
  388. This routine implements the query size info call
  389. Arguments:
  390. Vcb - Supplies the VCB to query.
  391. Buffer - Supplies a pointer to the buffer where the information is
  392. to be returned.
  393. Length - Supplies the length of the buffer in bytes.
  394. BytesWritten - Returns the number of bytes written to the buffer.
  395. Return Value:
  396. NTSTATUS - The result of this query.
  397. --*/
  398. {
  399. Buffer->Characteristics = 0;
  400. Buffer->DeviceType = FILE_DEVICE_MAILSLOT;
  401. //
  402. // Adjust the length variable
  403. //
  404. *BytesWritten = sizeof( FILE_FS_DEVICE_INFORMATION );
  405. //
  406. // And return success to our caller
  407. //
  408. return STATUS_SUCCESS;
  409. }