ReactOS  0.4.15-dev-1033-gd7d716a
volinfo.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  VolInfo.c
8 
9 Abstract:
10 
11  This module implements the volume information routines for Cdfs called by
12  the dispatch driver.
13 
14 
15 --*/
16 
17 #include "cdprocs.h"
18 
19 //
20 // The Bug check file id for this module
21 //
22 
23 #define BugCheckFileId (CDFS_BUG_CHECK_VOLINFO)
24 
25 //
26 // Local support routines
27 //
28 
29 _Requires_lock_held_(_Global_critical_region_)
31 CdQueryFsVolumeInfo (
32  _In_ PIRP_CONTEXT IrpContext,
33  _In_ PVCB Vcb,
36  );
37 
40  _In_ PIRP_CONTEXT IrpContext,
41  _In_ PVCB Vcb,
44  );
45 
48  _In_ PIRP_CONTEXT IrpContext,
49  _In_ PVCB Vcb,
52  );
53 
56  _In_ PIRP_CONTEXT IrpContext,
57  _In_ PVCB Vcb,
60  );
61 
62 #ifdef __REACTOS__
63 #define PFILE_FS_SECTOR_SIZE_INFORMATION PVOID
64 #endif
65 
68  _In_ PIRP_CONTEXT IrpContext,
69  _In_ PVCB Vcb,
70  _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
72  );
73 
74 #ifdef ALLOC_PRAGMA
75 #pragma alloc_text(PAGE, CdCommonQueryVolInfo)
76 #pragma alloc_text(PAGE, CdQueryFsAttributeInfo)
77 #pragma alloc_text(PAGE, CdQueryFsDeviceInfo)
78 #pragma alloc_text(PAGE, CdQueryFsSizeInfo)
79 #pragma alloc_text(PAGE, CdQueryFsVolumeInfo)
80 #pragma alloc_text(PAGE, CdQueryFsSectorSizeInfo)
81 #endif
82 
83 
84 _Requires_lock_held_(_Global_critical_region_)
86 CdCommonQueryVolInfo (
87  _Inout_ PIRP_CONTEXT IrpContext,
89  )
90 
91 /*++
92 
93 Routine Description:
94 
95  This is the common routine for querying volume information called by both
96  the fsd and fsp threads.
97 
98 Arguments:
99 
100  Irp - Supplies the Irp being processed
101 
102 Return Value:
103 
104  NTSTATUS - The return status for the operation
105 
106 --*/
107 
108 {
111 
112  ULONG Length;
113 
115  PFCB Fcb;
116  PCCB Ccb;
117 
118  PAGED_CODE();
119 
120  //
121  // Reference our input parameters to make things easier
122  //
123 
124  Length = IrpSp->Parameters.QueryVolume.Length;
125 
126  //
127  // Decode the file object and fail if this an unopened file object.
128  //
129 
130  TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
131 
133 
136  }
137 
138  //
139  // Acquire the Vcb for this volume.
140  //
141 
142  CdAcquireVcbShared( IrpContext, Fcb->Vcb, FALSE );
143 
144  //
145  // Use a try-finally to facilitate cleanup.
146  //
147 
148  _SEH2_TRY {
149 
150  //
151  // Verify the Vcb.
152  //
153 
154  CdVerifyVcb( IrpContext, Fcb->Vcb );
155 
156  //
157  // Based on the information class we'll do different actions. Each
158  // of the procedures that we're calling fills up the output buffer
159  // if possible and returns true if it successfully filled the buffer
160  // and false if it couldn't wait for any I/O to complete.
161  //
162 
163 #ifdef __REACTOS__
164  RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, Length);
165 #endif // __REACTOS__
166 
167  switch (IrpSp->Parameters.QueryVolume.FsInformationClass) {
168 
170 
171  Status = CdQueryFsSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
172  break;
173 
175 
176  Status = CdQueryFsVolumeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
177  break;
178 
180 
181  Status = CdQueryFsDeviceInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
182  break;
183 
185 
186  Status = CdQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
187  break;
188 
189 #if (NTDDI_VERSION >= NTDDI_WIN8)
190  case FileFsSectorSizeInformation:
191 
192  Status = CdQueryFsSectorSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
193  break;
194 #endif
195 
196  /* ReactOS Change: GCC "enumeration value not handled in switch" */
197  default: break;
198  }
199 
200  //
201  // Set the information field to the number of bytes actually filled in
202  //
203 
204  Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
205 
206  } _SEH2_FINALLY {
207 
208  //
209  // Release the Vcb.
210  //
211 
212  CdReleaseVcb( IrpContext, Fcb->Vcb );
213  } _SEH2_END;
214 
215  //
216  // Complete the request if we didn't raise.
217  //
218 
219  CdCompleteRequest( IrpContext, Irp, Status );
220 
221  return Status;
222 }
223 
224 
225 //
226 // Local support routine
227 //
228 
229 _Requires_lock_held_(_Global_critical_region_)
230 NTSTATUS
231 CdQueryFsVolumeInfo (
232  _In_ PIRP_CONTEXT IrpContext,
233  _In_ PVCB Vcb,
236  )
237 
238 /*++
239 
240 Routine Description:
241 
242  This routine implements the query volume info call
243 
244 Arguments:
245 
246  Vcb - Vcb for this volume.
247 
248  Buffer - Supplies a pointer to the output buffer where the information
249  is to be returned
250 
251  Length - Supplies the length of the buffer in byte. This variable
252  upon return recieves the remaining bytes free in the buffer
253 
254 Return Value:
255 
256  NTSTATUS - Returns the status for the query
257 
258 --*/
259 
260 {
262 
264 
265  PAGED_CODE();
266 
267  UNREFERENCED_PARAMETER( IrpContext );
268 
269  //
270  // Fill in the data from the Vcb.
271  //
272 
273  Buffer->VolumeCreationTime = *((PLARGE_INTEGER) &Vcb->VolumeDasdFcb->CreationTime);
274  Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
275 
276  Buffer->SupportsObjects = FALSE;
277 
278  *Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] );
279 
280  //
281  // Check if the buffer we're given is long enough
282  //
283 
284  if (*Length >= (ULONG) Vcb->Vpb->VolumeLabelLength) {
285 
286  BytesToCopy = Vcb->Vpb->VolumeLabelLength;
287 
288  } else {
289 
290  BytesToCopy = *Length;
291 
293  }
294 
295  //
296  // Copy over what we can of the volume label, and adjust *Length
297  //
298 
299  Buffer->VolumeLabelLength = BytesToCopy;
300 
301  if (BytesToCopy) {
302 
303  RtlCopyMemory( &Buffer->VolumeLabel[0],
304  &Vcb->Vpb->VolumeLabel[0],
305  BytesToCopy );
306  }
307 
308  *Length -= BytesToCopy;
309 
310  //
311  // Set our status and return to our caller
312  //
313 
314  return Status;
315 }
316 
317 
318 //
319 // Local support routine
320 //
321 
322 NTSTATUS
324  _In_ PIRP_CONTEXT IrpContext,
325  _In_ PVCB Vcb,
328  )
329 
330 /*++
331 
332 Routine Description:
333 
334  This routine implements the query volume size call.
335 
336 Arguments:
337 
338  Vcb - Vcb for this volume.
339 
340  Buffer - Supplies a pointer to the output buffer where the information
341  is to be returned
342 
343  Length - Supplies the length of the buffer in byte. This variable
344  upon return recieves the remaining bytes free in the buffer
345 
346 Return Value:
347 
348  NTSTATUS - Returns the status for the query
349 
350 --*/
351 
352 {
353  PAGED_CODE();
354 
355  UNREFERENCED_PARAMETER( IrpContext );
356 
357  //
358  // Fill in the output buffer.
359  //
360 
361  Buffer->TotalAllocationUnits.QuadPart = LlSectorsFromBytes( Vcb->VolumeDasdFcb->AllocationSize.QuadPart );
362 
363  Buffer->AvailableAllocationUnits.QuadPart = 0;
364  Buffer->SectorsPerAllocationUnit = 1;
365  Buffer->BytesPerSector = SECTOR_SIZE;
366 
367  //
368  // Adjust the length variable
369  //
370 
371  *Length -= sizeof( FILE_FS_SIZE_INFORMATION );
372 
373  //
374  // And return success to our caller
375  //
376 
377  return STATUS_SUCCESS;
378 }
379 
380 
381 //
382 // Local support routine
383 //
384 
385 NTSTATUS
387  _In_ PIRP_CONTEXT IrpContext,
388  _In_ PVCB Vcb,
391  )
392 
393 /*++
394 
395 Routine Description:
396 
397  This routine implements the query volume device call.
398 
399 Arguments:
400 
401  Vcb - Vcb for this volume.
402 
403  Buffer - Supplies a pointer to the output buffer where the information
404  is to be returned
405 
406  Length - Supplies the length of the buffer in byte. This variable
407  upon return recieves the remaining bytes free in the buffer
408 
409 Return Value:
410 
411  NTSTATUS - Returns the status for the query
412 
413 --*/
414 
415 {
416  PAGED_CODE();
417 
418  UNREFERENCED_PARAMETER( IrpContext );
419 
420  //
421  // Update the output buffer.
422  //
423 
424  Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;
425 #ifndef __REACTOS__
426  Buffer->DeviceType = FILE_DEVICE_CD_ROM;
427 #else
428  Buffer->DeviceType = Vcb->TargetDeviceObject->DeviceType;
429 #endif
430 
431  //
432  // Adjust the length variable
433  //
434 
435  *Length -= sizeof( FILE_FS_DEVICE_INFORMATION );
436 
437  //
438  // And return success to our caller
439  //
440 
441  return STATUS_SUCCESS;
442 }
443 
444 
445 //
446 // Local support routine
447 //
448 
449 NTSTATUS
451  _In_ PIRP_CONTEXT IrpContext,
452  _In_ PVCB Vcb,
455  )
456 
457 /*++
458 
459 Routine Description:
460 
461  This routine implements the query volume attribute call.
462 
463 Arguments:
464 
465  Vcb - Vcb for this volume.
466 
467  Buffer - Supplies a pointer to the output buffer where the information
468  is to be returned
469 
470  Length - Supplies the length of the buffer in byte. This variable
471  upon return recieves the remaining bytes free in the buffer
472 
473 Return Value:
474 
475  NTSTATUS - Returns the status for the query
476 
477 --*/
478 
479 {
481 
483 
484  PAGED_CODE();
485 
487 
488  //
489  // Fill out the fixed portion of the buffer.
490  //
491 
492  Buffer->FileSystemAttributes = FILE_CASE_SENSITIVE_SEARCH |
495 
496  if (FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) {
497 
498  SetFlag( Buffer->FileSystemAttributes, FILE_UNICODE_ON_DISK );
499 
500  Buffer->MaximumComponentNameLength = 110;
501 
502  } else {
503 
504  Buffer->MaximumComponentNameLength = 221;
505  }
506 
507  *Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName );
508 
509  //
510  // Make sure we can copy full unicode characters.
511  //
512 
513  ClearFlag( *Length, 1 );
514 
515  //
516  // Determine how much of the file system name will fit.
517  //
518 
519  if (*Length >= 8) {
520 
521  BytesToCopy = 8;
522 
523  } else {
524 
525  BytesToCopy = *Length;
527  }
528 
529  *Length -= BytesToCopy;
530 
531  //
532  // Do the file system name.
533  //
534 
535  Buffer->FileSystemNameLength = BytesToCopy;
536 
537  RtlCopyMemory( &Buffer->FileSystemName[0], L"CDFS", BytesToCopy );
538 
539  //
540  // And return to our caller
541  //
542 
543  return Status;
544 }
545 
546 #if (NTDDI_VERSION >= NTDDI_WIN8)
547 
548 NTSTATUS
550  _In_ PIRP_CONTEXT IrpContext,
551  _In_ PVCB Vcb,
552  _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
554  )
555 
556 /*++
557 
558 Routine Description:
559 
560  This routine implements the query sector size information call
561  This operation will work on any handle and requires no privilege.
562 
563 Arguments:
564 
565  Vcb - Supplies the Vcb being queried
566 
567  Buffer - Supplies a pointer to the output buffer where the information
568  is to be returned
569 
570  Length - Supplies the length of the buffer in byte. This variable
571  upon return receives the remaining bytes free in the buffer
572 
573 Return Value:
574 
575  NTSTATUS - Returns the status for the query
576 
577 --*/
578 
579 {
581 
582  PAGED_CODE();
583  UNREFERENCED_PARAMETER( IrpContext );
584 
585  //
586  // Sufficient buffer size is guaranteed by the I/O manager or the
587  // originating kernel mode driver.
588  //
589 
590  ASSERT( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
591  _Analysis_assume_( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
592 
593  //
594  // Retrieve the sector size information
595  //
596 
597  Status = FsRtlGetSectorSizeInformation( Vcb->Vpb->RealDevice,
598  Buffer );
599 
600  //
601  // Adjust the length variable
602  //
603 
604  if (NT_SUCCESS( Status )) {
605 
606  *Length -= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION );
607  }
608 
609  return Status;
610 }
611 
612 #endif
613 
#define VCB_STATE_JOLIET
Definition: cdstruc.h:714
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CdAcquireVcbShared(IC, V, I)
Definition: cdprocs.h:982
NTSTATUS CdQueryFsSizeInfo(_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _Out_ PFILE_FS_SIZE_INFORMATION Buffer, _Inout_ PULONG Length)
Definition: volinfo.c:323
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
Definition: cdstruc.h:908
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: cdstruc.h:1073
LONG NTSTATUS
Definition: precomp.h:26
Definition: cdstruc.h:504
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3167
_SEH2_TRY
Definition: create.c:4226
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:588
#define FALSE
Definition: types.h:117
#define LlSectorsFromBytes(L)
Definition: cdprocs.h:1618
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
_Requires_lock_held_(_Global_critical_region_)
Definition: volinfo.c:29
#define _Out_writes_bytes_(size)
Definition: no_sal2.h:370
#define _Out_
Definition: no_sal2.h:323
Definition: bufpool.h:45
NTSTATUS CdQueryFsAttributeInfo(_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer, _Inout_ PULONG Length)
Definition: volinfo.c:450
#define FILE_UNICODE_ON_DISK
Definition: from_kernel.h:235
#define CdReleaseVcb(IC, V)
Definition: cdprocs.h:985
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS CdQueryFsDeviceInfo(_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _Out_ PFILE_FS_DEVICE_INFORMATION Buffer, _Inout_ PULONG Length)
Definition: volinfo.c:386
#define FILE_CASE_SENSITIVE_SEARCH
Definition: from_kernel.h:233
#define Vcb
Definition: cdprocs.h:1415
#define _Inout_
Definition: no_sal2.h:244
NTSTATUS CdQueryFsSectorSizeInfo(_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer, _Inout_ PULONG Length)
Definition: volinfo.c:549
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define FILE_SUPPORTS_OPEN_BY_FILE_ID
Definition: from_kernel.h:251
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
struct _FILE_FS_DEVICE_INFORMATION FILE_FS_DEVICE_INFORMATION
enum _TYPE_OF_OPEN TYPE_OF_OPEN
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:588
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
struct _FILE_FS_SIZE_INFORMATION FILE_FS_SIZE_INFORMATION
#define _In_
Definition: no_sal2.h:204
VOID CdVerifyVcb(_In_ PIRP_CONTEXT IrpContext, _Inout_ PVCB Vcb)
Definition: verfysup.c:411
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2820
_SEH2_END
Definition: create.c:4400
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_SEH2_FINALLY
Definition: create.c:4371
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PVCB Vcb
Definition: cdstruc.h:939
#define SECTOR_SIZE
Definition: fs.h:22
#define FILE_READ_ONLY_VOLUME
Definition: from_kernel.h:246
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
_In_ PFCB Fcb
Definition: cdprocs.h:159
return STATUS_SUCCESS
Definition: btrfs.c:3014
union _LARGE_INTEGER * PLARGE_INTEGER
Definition: file.c:85
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
#define PAGED_CODE()