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.

509 lines
10 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. VolInfo.c
  5. Abstract:
  6. This module implements the volume information routines for Udfs called by
  7. the dispatch driver.
  8. // @@BEGIN_DDKSPLIT
  9. Author:
  10. Dan Lovinger [DanLo] 20-Jan-1997
  11. Revision History:
  12. // @@END_DDKSPLIT
  13. --*/
  14. #include "UdfProcs.h"
  15. //
  16. // The Bug check file id for this module
  17. //
  18. #define BugCheckFileId (UDFS_BUG_CHECK_VOLINFO)
  19. //
  20. // The local debug trace level
  21. //
  22. #define Dbg (UDFS_DEBUG_LEVEL_VOLINFO)
  23. //
  24. // Local support routines
  25. //
  26. NTSTATUS
  27. UdfQueryFsVolumeInfo (
  28. IN PIRP_CONTEXT IrpContext,
  29. IN PVCB Vcb,
  30. IN PFILE_FS_VOLUME_INFORMATION Buffer,
  31. IN OUT PULONG Length
  32. );
  33. NTSTATUS
  34. UdfQueryFsSizeInfo (
  35. IN PIRP_CONTEXT IrpContext,
  36. IN PVCB Vcb,
  37. IN PFILE_FS_SIZE_INFORMATION Buffer,
  38. IN OUT PULONG Length
  39. );
  40. NTSTATUS
  41. UdfQueryFsDeviceInfo (
  42. IN PIRP_CONTEXT IrpContext,
  43. IN PVCB Vcb,
  44. IN PFILE_FS_DEVICE_INFORMATION Buffer,
  45. IN OUT PULONG Length
  46. );
  47. NTSTATUS
  48. UdfQueryFsAttributeInfo (
  49. IN PIRP_CONTEXT IrpContext,
  50. IN PVCB Vcb,
  51. IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
  52. IN OUT PULONG Length
  53. );
  54. #ifdef ALLOC_PRAGMA
  55. #pragma alloc_text(PAGE, UdfCommonQueryVolInfo)
  56. #pragma alloc_text(PAGE, UdfQueryFsAttributeInfo)
  57. #pragma alloc_text(PAGE, UdfQueryFsDeviceInfo)
  58. #pragma alloc_text(PAGE, UdfQueryFsSizeInfo)
  59. #pragma alloc_text(PAGE, UdfQueryFsVolumeInfo)
  60. #endif
  61. NTSTATUS
  62. UdfCommonQueryVolInfo (
  63. IN PIRP_CONTEXT IrpContext,
  64. IN PIRP Irp
  65. )
  66. /*++
  67. Routine Description:
  68. This is the common routine for querying volume information called by both
  69. the fsd and fsp threads.
  70. Arguments:
  71. Irp - Supplies the Irp being processed
  72. Return Value:
  73. NTSTATUS - The return status for the operation
  74. --*/
  75. {
  76. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  77. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  78. ULONG Length;
  79. TYPE_OF_OPEN TypeOfOpen;
  80. PFCB Fcb;
  81. PCCB Ccb;
  82. PAGED_CODE();
  83. //
  84. // Reference our input parameters to make things easier
  85. //
  86. Length = IrpSp->Parameters.QueryVolume.Length;
  87. //
  88. // Decode the file object and fail if this an unopened file object.
  89. //
  90. TypeOfOpen = UdfDecodeFileObject( IrpSp->FileObject, &Fcb, &Ccb );
  91. if (TypeOfOpen == UnopenedFileObject) {
  92. UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
  93. return STATUS_INVALID_PARAMETER;
  94. }
  95. //
  96. // Acquire the Vcb for this volume.
  97. //
  98. UdfAcquireVcbShared( IrpContext, Fcb->Vcb, FALSE );
  99. //
  100. // Use a try-finally to facilitate cleanup.
  101. //
  102. try {
  103. //
  104. // Verify the Vcb.
  105. //
  106. UdfVerifyVcb( IrpContext, Fcb->Vcb );
  107. //
  108. // Based on the information class we'll do different actions. Each
  109. // of the procedures that we're calling fills up the output buffer
  110. // if possible and returns true if it successfully filled the buffer
  111. // and false if it couldn't wait for any I/O to complete.
  112. //
  113. switch (IrpSp->Parameters.QueryVolume.FsInformationClass) {
  114. case FileFsSizeInformation:
  115. Status = UdfQueryFsSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
  116. break;
  117. case FileFsVolumeInformation:
  118. Status = UdfQueryFsVolumeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
  119. break;
  120. case FileFsDeviceInformation:
  121. Status = UdfQueryFsDeviceInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
  122. break;
  123. case FileFsAttributeInformation:
  124. Status = UdfQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
  125. break;
  126. }
  127. //
  128. // Set the information field to the number of bytes actually filled in
  129. //
  130. Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
  131. } finally {
  132. //
  133. // Release the Vcb.
  134. //
  135. UdfReleaseVcb( IrpContext, Fcb->Vcb );
  136. }
  137. //
  138. // Complete the request if we didn't raise.
  139. //
  140. UdfCompleteRequest( IrpContext, Irp, Status );
  141. return Status;
  142. }
  143. //
  144. // Local support routine
  145. //
  146. NTSTATUS
  147. UdfQueryFsVolumeInfo (
  148. IN PIRP_CONTEXT IrpContext,
  149. IN PVCB Vcb,
  150. IN PFILE_FS_VOLUME_INFORMATION Buffer,
  151. IN OUT PULONG Length
  152. )
  153. /*++
  154. Routine Description:
  155. This routine implements the query volume info call
  156. Arguments:
  157. Vcb - Vcb for this volume.
  158. Buffer - Supplies a pointer to the output buffer where the information
  159. is to be returned
  160. Length - Supplies the length of the buffer in byte. This variable
  161. upon return recieves the remaining bytes free in the buffer
  162. Return Value:
  163. NTSTATUS - Returns the status for the query
  164. --*/
  165. {
  166. ULONG BytesToCopy;
  167. NTSTATUS Status = STATUS_SUCCESS;
  168. PAGED_CODE();
  169. //
  170. // Fill in the data from the Vcb.
  171. //
  172. Buffer->VolumeCreationTime = Vcb->VolumeDasdFcb->Timestamps.CreationTime;
  173. Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
  174. Buffer->SupportsObjects = FALSE;
  175. *Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] );
  176. //
  177. // Check if the buffer we're given is long enough
  178. //
  179. if (*Length >= (ULONG) Vcb->Vpb->VolumeLabelLength) {
  180. BytesToCopy = Vcb->Vpb->VolumeLabelLength;
  181. } else {
  182. BytesToCopy = *Length;
  183. Status = STATUS_BUFFER_OVERFLOW;
  184. }
  185. //
  186. // Copy over what we can of the volume label, and adjust *Length
  187. //
  188. Buffer->VolumeLabelLength = BytesToCopy;
  189. if (BytesToCopy) {
  190. RtlCopyMemory( &Buffer->VolumeLabel[0],
  191. &Vcb->Vpb->VolumeLabel[0],
  192. BytesToCopy );
  193. }
  194. *Length -= BytesToCopy;
  195. //
  196. // Set our status and return to our caller
  197. //
  198. return Status;
  199. }
  200. //
  201. // Local support routine
  202. //
  203. NTSTATUS
  204. UdfQueryFsSizeInfo (
  205. IN PIRP_CONTEXT IrpContext,
  206. IN PVCB Vcb,
  207. IN PFILE_FS_SIZE_INFORMATION Buffer,
  208. IN OUT PULONG Length
  209. )
  210. /*++
  211. Routine Description:
  212. This routine implements the query volume size call.
  213. Arguments:
  214. Vcb - Vcb for this volume.
  215. Buffer - Supplies a pointer to the output buffer where the information
  216. is to be returned
  217. Length - Supplies the length of the buffer in byte. This variable
  218. upon return recieves the remaining bytes free in the buffer
  219. Return Value:
  220. NTSTATUS - Returns the status for the query
  221. --*/
  222. {
  223. PAGED_CODE();
  224. //
  225. // Fill in the output buffer.
  226. //
  227. Buffer->TotalAllocationUnits.QuadPart = LlBlocksFromBytes( Vcb, Vcb->VolumeDasdFcb->AllocationSize.QuadPart );
  228. Buffer->AvailableAllocationUnits.QuadPart = 0;
  229. Buffer->SectorsPerAllocationUnit = SectorsFromBytes( Vcb, BlockSize( Vcb ));
  230. Buffer->BytesPerSector = SectorSize( Vcb );
  231. //
  232. // Adjust the length variable
  233. //
  234. *Length -= sizeof( FILE_FS_SIZE_INFORMATION );
  235. //
  236. // And return success to our caller
  237. //
  238. return STATUS_SUCCESS;
  239. }
  240. //
  241. // Local support routine
  242. //
  243. NTSTATUS
  244. UdfQueryFsDeviceInfo (
  245. IN PIRP_CONTEXT IrpContext,
  246. IN PVCB Vcb,
  247. IN PFILE_FS_DEVICE_INFORMATION Buffer,
  248. IN OUT PULONG Length
  249. )
  250. /*++
  251. Routine Description:
  252. This routine implements the query volume device call.
  253. Arguments:
  254. Vcb - Vcb for this volume.
  255. Buffer - Supplies a pointer to the output buffer where the information
  256. is to be returned
  257. Length - Supplies the length of the buffer in byte. This variable
  258. upon return recieves the remaining bytes free in the buffer
  259. Return Value:
  260. NTSTATUS - Returns the status for the query
  261. --*/
  262. {
  263. PAGED_CODE();
  264. //
  265. // Update the output buffer.
  266. //
  267. Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;
  268. Buffer->DeviceType = FILE_DEVICE_CD_ROM;
  269. //
  270. // Adjust the length variable
  271. //
  272. *Length -= sizeof( FILE_FS_DEVICE_INFORMATION );
  273. //
  274. // And return success to our caller
  275. //
  276. return STATUS_SUCCESS;
  277. }
  278. //
  279. // Local support routine
  280. //
  281. NTSTATUS
  282. UdfQueryFsAttributeInfo (
  283. IN PIRP_CONTEXT IrpContext,
  284. IN PVCB Vcb,
  285. IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
  286. IN OUT PULONG Length
  287. )
  288. /*++
  289. Routine Description:
  290. This routine implements the query volume attribute call.
  291. Arguments:
  292. Vcb - Vcb for this volume.
  293. Buffer - Supplies a pointer to the output buffer where the information
  294. is to be returned
  295. Length - Supplies the length of the buffer in byte. This variable
  296. upon return recieves the remaining bytes free in the buffer
  297. Return Value:
  298. NTSTATUS - Returns the status for the query
  299. --*/
  300. {
  301. ULONG BytesToCopy;
  302. NTSTATUS Status = STATUS_SUCCESS;
  303. PAGED_CODE();
  304. //
  305. // Fill out the fixed portion of the buffer.
  306. //
  307. Buffer->FileSystemAttributes = FILE_CASE_SENSITIVE_SEARCH |
  308. FILE_UNICODE_ON_DISK |
  309. FILE_READ_ONLY_VOLUME;
  310. Buffer->MaximumComponentNameLength = 255;
  311. *Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName );
  312. //
  313. // Make sure we can copy full unicode characters.
  314. //
  315. ClearFlag( *Length, 1 );
  316. //
  317. // Determine how much of the file system name will fit.
  318. //
  319. if (*Length >= 6) {
  320. BytesToCopy = 6;
  321. } else {
  322. BytesToCopy = *Length;
  323. Status = STATUS_BUFFER_OVERFLOW;
  324. }
  325. *Length -= BytesToCopy;
  326. //
  327. // Do the file system name. We explicitly share this designation with all
  328. // Microsoft implementations of the UDF filesystem - DO NOT CHANGE!
  329. //
  330. Buffer->FileSystemNameLength = BytesToCopy;
  331. RtlCopyMemory( &Buffer->FileSystemName[0], L"UDF", BytesToCopy );
  332. //
  333. // And return to our caller
  334. //
  335. return Status;
  336. }