ReactOS  0.4.14-dev-317-g96040ec
verfysup.cpp
Go to the documentation of this file.
1 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
6 /*
7 
8  Module Name: VerfySup.cpp
9 
10  Abstract:
11 
12  This module implements the UDF verification routines.
13 
14  Environment:
15 
16  Kernel mode only
17 
18 */
19 
20 #include "udffs.h"
21 
22 // define the file specific bug-check id
23 #define UDF_BUG_CHECK_ID UDF_FILE_VERIFY_FS_CONTROL
24 
25 /*
26 Routine Description:
27  This routine checks that the current Vcb is valid and currently mounted
28  on the device. It will raise on an error condition.
29  We check whether the volume needs verification and the current state
30  of the Vcb.
31 Arguments:
32 
33  Vcb - This is the volume to verify.
34 */
35 
38  IN PtrUDFIrpContext IrpContext,
39  IN PVCB Vcb
40  )
41 {
44  ULONG MediaChangeCount = 0;
45  BOOLEAN Nop = TRUE;
46  BOOLEAN UnsafeIoctl = (Vcb->VCBFlags & UDF_VCB_FLAGS_UNSAFE_IOCTL) ? TRUE : FALSE;
47 
48  UDFPrint(("UDFVerifyVCB: Modified=%d\n", Vcb->Modified));
49  // Fail immediately if the volume is in the progress of being dismounted
50  // or has been marked invalid.
51  if (Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) {
52  return STATUS_FILE_INVALID;
53  }
54 
55  // If the media is removable and the verify volume flag in the
56  // device object is not set then we want to ping the device
57  // to see if it needs to be verified
58  if ( (Vcb->VCBFlags & UDF_VCB_FLAGS_REMOVABLE_MEDIA) &&
59  !(Vcb->Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) &&
60  (!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) || UnsafeIoctl) ) {
61  UDFPrint(("UDFVerifyVCB: UnsafeIoctl=%d, locked=%d\n", UnsafeIoctl, (Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) ? 0 : 1));
62  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_UNSAFE_IOCTL;
64  Vcb,
65  NULL,0,
66  &MediaChangeCount,sizeof(ULONG),
67  FALSE,&Iosb );
68 
69  // Be safe about the count in case the driver didn't fill it in
70  if (Iosb.Information != sizeof(ULONG)) MediaChangeCount = 0;
71  UDFPrint((" MediaChangeCount %d -> %d\n", Vcb->MediaChangeCount, MediaChangeCount));
72 
73  // If the volume is now an empty device, or we have receieved a
74  // bare STATUS_VERIFY_REQUIRED (various hardware conditions such
75  // as bus resets, etc., will trigger this in the drivers), or the
76  // media change count has moved since we last inspected the device,
77  // then mark the volume to be verified.
78 
79  if ( (RC == STATUS_VERIFY_REQUIRED) ||
80  (UDFIsRawDevice(RC) && (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) ||
81  (NT_SUCCESS(RC) && (Vcb->MediaChangeCount != MediaChangeCount)) ||
82  UnsafeIoctl) {
83 
84  UDFPrint((" set DO_VERIFY_VOLUME\n"));
85  Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
86 
87  // If the volume is not mounted and we got a media change count,
88  // update the Vcb so we do not trigger a verify again at this
89  // count value. If the verify->mount path detects that the media
90  // has actually changed and this Vcb is valid again, this will have
91  // done nothing. We are already synchronized since the caller has
92  // the Vcb.
93  if (!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) &&
94  NT_SUCCESS(RC) ) {
95  Vcb->MediaChangeCount = MediaChangeCount;
96  }
97 
98  } else if (!NT_SUCCESS(RC)) {
99 // Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
100  UDFPrint((" UDFNormalizeAndRaiseStatus(%x)\n", RC));
101  UDFNormalizeAndRaiseStatus(IrpContext,RC);
102  ASSERT(Nop);
103  }
104  }
105 
106  UDFPrint(("UDFVerifyVCB: Modified=%d\n", Vcb->Modified));
107  // The Vcb may be mounted but the underlying real device may need to be verified.
108  // If it does then we'll set the Iosb in the irp to be our real device
109  if (Vcb->Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) {
110 
111  UDFPrint((" DO_VERIFY_VOLUME -> IoSetHardErrorOrVerifyDevice()\n"));
112  IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
113  Vcb->Vpb->RealDevice );
114 
116  UDFPrint((" UDFRaiseStatus()\n"));
117  UDFRaiseStatus(IrpContext, RC);
118  ASSERT(Nop);
119  }
120 
121  UDFPrint(("UDFVerifyVCB: Modified=%d\n", Vcb->Modified));
122  if (!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
123  UDFPrint((" !UDF_VCB_FLAGS_VOLUME_MOUNTED -> IoSetHardErrorOrVerifyDevice()\n"));
124  Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
125  IoSetHardErrorOrVerifyDevice( IrpContext->Irp, Vcb->Vpb->RealDevice );
126  RC = STATUS_WRONG_VOLUME;
127  UDFPrint((" UDFRaiseStatus()\n"));
128  UDFRaiseStatus(IrpContext, RC);
129 // UDFRaiseStatus(IrpContext, STATUS_UNRECOGNIZED_VOLUME);
130  ASSERT(Nop);
131  }
132  if ((Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED)) {
133  UDFPrint((" UDF_VCB_FLAGS_BEING_DISMOUNTED\n"));
134  RC = STATUS_FILE_INVALID;
135  UDFRaiseStatus( IrpContext, RC );
136  ASSERT(Nop);
137  }
138  UDFPrint(("UDFVerifyVcb: RC = %x\n", RC));
139 
140  return RC;
141 } // end UDFVerifyVcb()
142 
143 /*
144 
145 Routine Description:
146  This routine performs the verify volume operation. It is responsible for
147  either completing of enqueuing the input Irp.
148 
149 Arguments:
150  Irp - Supplies the Irp to process
151 
152 Return Value:
153 
154  NTSTATUS - The return status for the operation
155 
156 --*/
157 NTSTATUS
159  IN PIRP Irp
160  )
161 {
163  PVPB Vpb = IrpSp->Parameters.VerifyVolume.Vpb;
164  PVCB Vcb = (PVCB)IrpSp->Parameters.VerifyVolume.DeviceObject->DeviceExtension;
165  PVCB NewVcb = NULL;
167  ULONG MediaChangeCount = 0;
168  NTSTATUS RC;
169  ULONG Mode;
170  BOOLEAN UnsafeIoctl = (Vcb->VCBFlags & UDF_VCB_FLAGS_UNSAFE_IOCTL) ? TRUE : FALSE;
171 
172  // Update the real device in the IrpContext from the Vpb. There was no available
173  // file object when the IrpContext was created.
174  // IrpContext->RealDevice = Vpb->RealDevice;
175  UDFPrint(("UDFVerifyVolume:\n"));
176 
177  // Acquire shared global access, the termination handler for the
178  // following try statement will free the access.
179 
180  UDFAcquireResourceShared(&(UDFGlobalData.GlobalDataResource),TRUE);
181  UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
182 
183  _SEH2_TRY {
184 
185  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
186  // Check if the real device still needs to be verified. If it doesn't
187  // then obviously someone beat us here and already did the work
188  // so complete the verify irp with success. Otherwise reenable
189  // the real device and get to work.
190  if( !(Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) &&
191  ((Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) && !UnsafeIoctl) ) {
192  UDFPrint(("UDFVerifyVolume: STATUS_SUCCESS (1)\n"));
194  }
195  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_UNSAFE_IOCTL;
196  // Verify that there is a disk here.
198  Vcb->TargetDeviceObject,
199  NULL,0,
200  &MediaChangeCount,sizeof(ULONG),
201  TRUE,&Iosb );
202 
203  if(!NT_SUCCESS( RC )) {
204  // If we will allow a raw mount then return WRONG_VOLUME to
205  // allow the volume to be mounted by raw.
207  UDFPrint(("UDFVerifyVolume: STATUS_WRONG_VOLUME (1)\n"));
208  RC = STATUS_WRONG_VOLUME;
209  }
210 
211  if(UDFIsRawDevice(RC)) {
212  UDFPrint(("UDFVerifyVolume: STATUS_WRONG_VOLUME (2)\n"));
213  RC = STATUS_WRONG_VOLUME;
214  }
215  try_return( RC );
216  }
217 
218  if(Iosb.Information != sizeof(ULONG)) {
219  // Be safe about the count in case the driver didn't fill it in
220  MediaChangeCount = 0;
221  }
222 
223  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
224  UDFPrint(("UDFVerifyVolume: MediaChangeCount=%x, Vcb->MediaChangeCount=%x, UnsafeIoctl=%x\n",
225  MediaChangeCount, Vcb->MediaChangeCount, UnsafeIoctl));
226  // Verify that the device actually saw a change. If the driver does not
227  // support the MCC, then we must verify the volume in any case.
228  if(MediaChangeCount == 0 ||
229  (Vcb->MediaChangeCount != MediaChangeCount) ||
230  UnsafeIoctl ) {
231 
232  UDFPrint(("UDFVerifyVolume: compare\n"));
233 
234  NewVcb = (PVCB)MyAllocatePool__(NonPagedPool,sizeof(VCB));
235  if(!NewVcb)
237  RtlZeroMemory(NewVcb,sizeof(VCB));
238 
239  NewVcb->TargetDeviceObject = Vcb->TargetDeviceObject;
240  NewVcb->Vpb = Vpb;
241 
242  // Set the removable media flag based on the real device's
243  // characteristics
244  if(Vpb->RealDevice->Characteristics & FILE_REMOVABLE_MEDIA) {
245  UDFSetFlag( NewVcb->VCBFlags, UDF_VCB_FLAGS_REMOVABLE_MEDIA );
246  }
247 
248  RC = UDFGetDiskInfo(NewVcb->TargetDeviceObject,NewVcb);
249  if(!NT_SUCCESS(RC)) try_return(RC);
250  // Prevent modification attempts durring Verify
251  NewVcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_READ_ONLY |
253  // Compare physical parameters (phase 1)
254  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
255  RC = UDFCompareVcb(Vcb,NewVcb, TRUE);
256  if(!NT_SUCCESS(RC)) try_return(RC);
257 
258  if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
259  Vcb->MountPhErrorCount > MOUNT_ERR_THRESHOLD ) {
260  UDFPrint(("UDFVerifyVolume: it was very BAD volume. Do not perform Logical check\n"));
261  goto skip_logical_check;
262  }
263  // Initialize internal cache
264  // in *** READ ONLY *** mode
266 
267  RC = WCacheInit__(&(NewVcb->FastCache),
270  NewVcb->WriteBlockSize,
271  5, NewVcb->BlockSizeBits,
273  0/*NewVcb->FirstLBA*/, NewVcb->LastPossibleLBA, Mode,
274  /*WCACHE_CACHE_WHOLE_PACKET*/ 0 |
275  (Vcb->DoNotCompareBeforeWrite ? WCACHE_DO_NOT_COMPARE : 0) |
276  WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS, // speed up mount on bad disks
279 #ifdef UDF_ASYNC_IO
280  UDFTWriteAsync, UDFTReadAsync,
281 #else //UDF_ASYNC_IO
282  NULL, NULL,
283 #endif //UDF_ASYNC_IO
286  if(!NT_SUCCESS(RC)) try_return(RC);
287 
288  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
289  RC = UDFGetDiskInfoAndVerify(NewVcb->TargetDeviceObject,NewVcb);
290  UDFPrint((" NewVcb->NSRDesc=%x\n", NewVcb->NSRDesc));
291  if(!NT_SUCCESS(RC)) {
292  if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
293  (NewVcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
294  !(NewVcb->NSRDesc & VRS_ISO9660_FOUND)) {
295  UDFPrint(("UDFVerifyVolume: both are RAW -> remount\n", Vcb->Modified));
296  RC = STATUS_SUCCESS;
297  goto skip_logical_check;
298  }
299  if(RC == STATUS_UNRECOGNIZED_VOLUME) {
301  }
302  try_return(RC);
303  }
304 
305  WCacheChFlags__(&(Vcb->FastCache),
306  WCACHE_CACHE_WHOLE_PACKET, // enable cache whole packet
307  WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS); // let user retry request on Bad Blocks
308 
309  NewVcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_MOUNTED;
310  // Compare logical parameters (phase 2)
311  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
312  RC = UDFCompareVcb(Vcb,NewVcb, FALSE);
313  if(!NT_SUCCESS(RC)) try_return(RC);
314  // We have unitialized WCache, so it is better to
315  // force MOUNT_VOLUME call
316  if(!WCacheIsInitialized__(&(Vcb->FastCache)))
318 
319 skip_logical_check:;
320 
321  }
322 
323  UDFPrint(("UDFVerifyVolume: compared\n"));
324  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
325  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED)) {
326  UDFPrint(("UDFVerifyVolume: set UDF_VCB_FLAGS_VOLUME_MOUNTED\n"));
327  Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_MOUNTED;
328  Vcb->SoftEjectReq = FALSE;
329  }
330  UDFClearFlag( Vpb->RealDevice->Flags, DO_VERIFY_VOLUME );
331 
332 try_exit: NOTHING;
333 
334  } _SEH2_FINALLY {
335 
336  // Update the media change count to note that we have verified the volume
337  // at this value
338  Vcb->MediaChangeCount = MediaChangeCount;
339 
340  // If we got the wrong volume, mark the Vcb as not mounted.
341  if(RC == STATUS_WRONG_VOLUME) {
342  UDFPrint(("UDFVerifyVolume: clear UDF_VCB_FLAGS_VOLUME_MOUNTED\n"));
343  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
344  Vcb->WriteSecurity = FALSE;
345 // ASSERT(!(Vcb->EjectWaiter));
346  if(Vcb->EjectWaiter) {
347  UDFReleaseResource(&(Vcb->VCBResource));
349  UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
350  }
351  } else
352  if(NT_SUCCESS(RC) &&
353  (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)){
354  BOOLEAN CacheInitialized = FALSE;
355  UDFPrint((" !!! VerifyVolume - QUICK REMOUNT !!!\n"));
356  // Initialize internal cache
357  CacheInitialized = WCacheIsInitialized__(&(Vcb->FastCache));
358  if(!CacheInitialized) {
360  RC = WCacheInit__(&(Vcb->FastCache),
361  Vcb->WCacheMaxFrames,
362  Vcb->WCacheMaxBlocks,
363  Vcb->WriteBlockSize,
364  5, Vcb->BlockSizeBits,
365  Vcb->WCacheBlocksPerFrameSh,
366  0/*Vcb->FirstLBA*/, Vcb->LastPossibleLBA, Mode,
367  /*WCACHE_CACHE_WHOLE_PACKET*/ 0 |
368  (Vcb->DoNotCompareBeforeWrite ? WCACHE_DO_NOT_COMPARE : 0) |
369  (Vcb->CacheChainedIo ? WCACHE_CHAINED_IO : 0),
370  Vcb->WCacheFramesToKeepFree,
371 // UDFTWrite, UDFTRead,
373 #ifdef UDF_ASYNC_IO
374  UDFTWriteAsync, UDFTReadAsync,
375 #else //UDF_ASYNC_IO
376  NULL, NULL,
377 #endif //UDF_ASYNC_IO
380  }
381  if(NT_SUCCESS(RC)) {
382  if(!Vcb->VerifyCtx.VInited) {
383  RC = UDFVInit(Vcb);
384  }
385  }
386  if(NT_SUCCESS(RC)) {
387 
388  if(!CacheInitialized) {
389  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY)) {
390  if(!Vcb->CDR_Mode) {
391  if((Vcb->TargetDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
392  CdrwMediaClassEx_IsRAM(Vcb->MediaClassEx)) {
393  UDFPrint(("UDFMountVolume: RAM mode\n"));
395  } else {
396  UDFPrint(("UDFMountVolume: RW mode\n"));
398  }
399  /* if(FsDeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) {
400  } else {
401  Vcb->WriteSecurity = TRUE;
402  }*/
403  } else {
405  }
406  }
407  WCacheSetMode__(&(Vcb->FastCache), Mode);
408 
409  WCacheChFlags__(&(Vcb->FastCache),
410  WCACHE_CACHE_WHOLE_PACKET, // enable cache whole packet
411  WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS); // let user retry request on Bad Blocks
412  }
413  // we can't record ACL on old format disks
414  if(!UDFNtAclSupported(Vcb)) {
415  Vcb->WriteSecurity = FALSE;
416  Vcb->UseExtendedFE = FALSE;
417  }
418  UDFPrint(("UDFVerifyVolume: try start EjectWaiter\n"));
419  RC = UDFStartEjectWaiter(Vcb);
420  if(!NT_SUCCESS(RC)) {
421  UDFPrint(("UDFVerifyVolume: start EjectWaiter failed\n"));
422  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
423  Vcb->WriteSecurity = FALSE;
424  }
425  }
426  }
427 
428  if(NewVcb) {
429  // Release internal cache
430  UDFPrint(("UDFVerifyVolume: delete NewVcb\n"));
431  WCacheFlushAll__(&(NewVcb->FastCache),NewVcb);
432  WCacheRelease__(&(NewVcb->FastCache));
433 
434  ASSERT(!(NewVcb->EjectWaiter));
435  // Waiter thread should be already stopped
436  // if MediaChangeCount have changed
437  ASSERT(!(Vcb->EjectWaiter));
438 
439  UDFCleanupVCB(NewVcb);
440  MyFreePool__(NewVcb);
441  }
442  UDFReleaseResource(&(Vcb->VCBResource));
443  UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
444  } _SEH2_END;
445 
446  // Complete the request if no exception.
447  Irp->IoStatus.Information = 0;
448 
449  Irp->IoStatus.Status = RC;
451 
452  UDFPrint(("UDFVerifyVolume: RC = %x\n", RC));
453 
454  return RC;
455 } // end UDFVerifyVolume ()
456 
457 /*
458 Routine Description:
459 
460  This routines performs an IoVerifyVolume operation and takes the
461  appropriate action. If the verify is successful then we send the originating
462  Irp off to an Ex Worker Thread. This routine is called from the exception handler.
463  No file system resources are held when this routine is called.
464 
465 Arguments:
466 
467  Irp - The irp to send off after all is well and done.
468  Device - The real device needing verification.
469 
470 */
471 NTSTATUS
473  IN PtrUDFIrpContext IrpContext,
474  IN PIRP Irp,
476  )
477 {
478 
479  PVCB Vcb;
482 
483  UDFPrint(("UDFPerformVerify:\n"));
484  if(!IrpContext) return STATUS_INVALID_PARAMETER;
485  if(!Irp) return STATUS_INVALID_PARAMETER;
486 
487  // Check if this Irp has a status of Verify required and if it does
488  // then call the I/O system to do a verify.
489  //
490  // Skip the IoVerifyVolume if this is a mount or verify request
491  // itself. Trying a recursive mount will cause a deadlock with
492  // the DeviceObject->DeviceLock.
493  if ((IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
494  ((IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) ||
495  (IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME))) {
496 
497  return UDFPostRequest(IrpContext, Irp);
498  }
499 
500  // Extract a pointer to the Vcb from the VolumeDeviceObject.
501  // Note that since we have specifically excluded mount,
502  // requests, we know that IrpSp->DeviceObject is indeed a
503  // volume device object.
504 
506 
508 
509  UDFPrint(("UDFPerformVerify: check\n"));
510  // Check if the volume still thinks it needs to be verified,
511  // if it doesn't then we can skip doing a verify because someone
512  // else beat us to it.
513  _SEH2_TRY {
514 
515  if (DeviceToVerify->Flags & DO_VERIFY_VOLUME) {
516 
517  // If the IopMount in IoVerifyVolume did something, and
518  // this is an absolute open, force a reparse.
520 
521  // Bug?
522 /* if (UDFIsRawDevice(RC)) {
523  RC = STATUS_WRONG_VOLUME;
524  }*/
525 
526  // If the verify operation completed it will return
527  // either STATUS_SUCCESS or STATUS_WRONG_VOLUME, exactly.
528  if (RC == STATUS_SUCCESS) {
529  IrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_EXCEPTION;
530  }
531  // If UDFVerifyVolume encountered an error during
532  // processing, it will return that error. If we got
533  // STATUS_WRONG_VOLUME from the verify, and our volume
534  // is now mounted, commute the status to STATUS_SUCCESS.
535  if ((RC == STATUS_WRONG_VOLUME) &&
536  (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
537  RC = STATUS_SUCCESS;
538  }
539 
540  // Do a quick unprotected check here. The routine will do
541  // a safe check. After here we can release the resource.
542  // Note that if the volume really went away, we will be taking
543  // the Reparse path.
544 
545  // If the device might need to go away then call our dismount routine.
546  if ( (!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) ||
547  (Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED)) &&
548  (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE) )
549  {
550  UDFPrint(("UDFPerformVerify: UDFCheckForDismount\n"));
551  UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
552  UDFCheckForDismount( IrpContext, Vcb, FALSE );
553  UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
554  }
555 
556  // If this is a create and the verify succeeded then complete the
557  // request with a REPARSE status.
558  if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
559  (IrpSp->FileObject->RelatedFileObject == NULL) &&
560  ((RC == STATUS_SUCCESS) || (RC == STATUS_WRONG_VOLUME)) ) {
561 
562  UDFPrint(("UDFPerformVerify: IO_REMOUNT\n"));
563 
564  Irp->IoStatus.Information = IO_REMOUNT;
565 
566  Irp->IoStatus.Status = STATUS_REPARSE;
568 
569  UDFReleaseIrpContext(IrpContext);
570 
571  RC = STATUS_REPARSE;
572  Irp = NULL;
573  IrpContext = NULL;
574 
575  // If there is still an error to process then call the Io system
576  // for a popup.
577  } else if ((Irp != NULL) && !NT_SUCCESS( RC )) {
578 
579  UDFPrint(("UDFPerformVerify: check IoIsErrorUserInduced\n"));
580  // Fill in the device object if required.
581  if (IoIsErrorUserInduced( RC ) ) {
583  }
584  UDFPrint(("UDFPerformVerify: UDFNormalizeAndRaiseStatus\n"));
585  UDFNormalizeAndRaiseStatus( IrpContext, RC );
586  }
587  }
588 
589  // If there is still an Irp, send it off to an Ex Worker thread.
590  if (IrpContext != NULL) {
591 
592  RC = UDFPostRequest( IrpContext, Irp );
593  }
594 
596  // We had some trouble trying to perform the verify or raised
597  // an error ourselves. So we'll abort the I/O request with
598  // the error status that we get back from the execption code.
599  RC = UDFExceptionHandler( IrpContext, Irp);
600  } _SEH2_END;
601 
602  UDFPrint(("UDFPerformVerify: RC = %x\n", RC));
603 
604  return RC;
605 
606 } // end UDFPerformVerify()
607 
608 /*
609 
610 Routine Description:
611 
612  This routine is called to check if a volume is ready for dismount. This
613  occurs when only file system references are left on the volume.
614 
615  If the dismount is not currently underway and the user reference count
616  has gone to zero then we can begin the dismount.
617 
618  If the dismount is in progress and there are no references left on the
619  volume (we check the Vpb for outstanding references as well to catch
620  any create calls dispatched to the file system) then we can delete
621  the Vcb.
622 
623 Arguments:
624 
625  Vcb - Vcb for the volume to try to dismount.
626 
627 */
628 BOOLEAN
630  IN PtrUDFIrpContext IrpContext,
631  IN PVCB Vcb,
632  IN BOOLEAN _VcbAcquired
633  )
634 {
635  BOOLEAN VcbPresent = TRUE;
636  KIRQL SavedIrql;
637  BOOLEAN VcbAcquired;
638  ULONG ResidualReferenceCount;
639 
640  UDFPrint(("UDFCheckForDismount:\n"));
641  if(!Vcb) return FALSE;
642 
643  // GlobalDataResource is already acquired
644  if(!_VcbAcquired) {
645  VcbAcquired = UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE/*FALSE*/ );
646  if(!VcbAcquired)
647  return TRUE;
648  } else {
649  VcbAcquired = TRUE;
650  }
651 
652  if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
653  (IrpContext->TargetDeviceObject == Vcb->TargetDeviceObject)) {
654 
655  ResidualReferenceCount = 2;
656 
657  } else {
658 
659  ResidualReferenceCount = 1;
660  }
661 
662  // If the dismount is not already underway then check if the
663  // user reference count has gone to zero. If so start the teardown
664  // on the Vcb.
665  if (!(Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED)) {
666  if (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE) {
667  VcbPresent = UDFDismountVcb(Vcb, VcbAcquired);
668  }
669  VcbAcquired = VcbAcquired && VcbPresent;
670 
671  // If the teardown is underway and there are absolutely no references
672  // remaining then delete the Vcb. References here include the
673  // references in the Vcb and Vpb.
674  } else if (!(Vcb->VCBOpenCount)) {
675 
676  IoAcquireVpbSpinLock( &SavedIrql );
677  // If there are no file objects and no reference counts in the
678  // Vpb we can delete the Vcb. Don't forget that we have the
679  // last reference in the Vpb.
680  if (Vcb->Vpb->ReferenceCount <= ResidualReferenceCount) {
681 
682  IoReleaseVpbSpinLock( SavedIrql );
683  if(VcbAcquired)
684  UDFReleaseResource(&(Vcb->VCBResource));
687  VcbAcquired =
688  VcbPresent = FALSE;
689 
690  } else {
691 
692  IoReleaseVpbSpinLock( SavedIrql );
693  }
694  }
695 
696  // Release any resources still acquired.
697  if (!_VcbAcquired && VcbAcquired) {
698  UDFReleaseResource(&(Vcb->VCBResource));
699  }
700 
701  return VcbPresent;
702 } // end UDFCheckForDismount()
703 
704 
705 /*
706 
707 Routine Description:
708 
709  This routine is called when all of the user references to a volume are
710  gone. We will initiate all of the teardown any system resources.
711 
712  If all of the references to this volume are gone at the end of this routine
713  then we will complete the teardown of this Vcb and mark the current Vpb
714  as not mounted. Otherwise we will allocated a new Vpb for this device
715  and keep the current Vpb attached to the Vcb.
716 
717 Arguments:
718 
719  Vcb - Vcb for the volume to dismount.
720 
721 Return Value:
722 
723  BOOLEAN - TRUE if we didn't delete the Vcb, FALSE otherwise.
724 
725 */
726 BOOLEAN
728  IN PVCB Vcb,
729  IN BOOLEAN VcbAcquired
730  )
731 {
732 
733  PVPB OldVpb;
734  PVPB NewVpb;
735  BOOLEAN VcbPresent = TRUE;
736  KIRQL SavedIrql;
737 
738  BOOLEAN FinalReference;
739 
740  UDFPrint(("UDFDismountVcb:\n"));
741  // We should only take this path once.
742  ASSERT( !(Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) );
743 
744  // Mark the Vcb as DismountInProgress.
745  Vcb->VCBFlags |= UDF_VCB_FLAGS_BEING_DISMOUNTED;
746 
747  // Allocate a new Vpb in case we will need it.
748  NewVpb = (PVPB)DbgAllocatePoolWithTag( NonPagedPool, sizeof( VPB ), 'bpvU' );
749  if(!NewVpb) {
750  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_BEING_DISMOUNTED;
751  return TRUE;
752  }
753 
754  RtlZeroMemory( NewVpb, sizeof(VPB) );
755 
756  OldVpb = Vcb->Vpb;
757 
758  // Remove the mount volume reference.
760  // the only residual reference is cleaned above
761 
762  // Acquire the Vpb spinlock to check for Vpb references.
763  IoAcquireVpbSpinLock(&SavedIrql);
764 
765  // Remember if this is the last reference on this Vcb. We incremented
766  // the count on the Vpb earlier so we get one last crack it. If our
767  // reference has gone to zero but the vpb reference count is greater
768  // than zero then the Io system will be responsible for deleting the
769  // Vpb.
770  FinalReference = (BOOLEAN)(OldVpb->ReferenceCount == 1);
771 
772  // There is a reference count in the Vpb and in the Vcb. We have
773  // incremented the reference count in the Vpb to make sure that
774  // we have last crack at it. If this is a failed mount then we
775  // want to return the Vpb to the IO system to use for the next
776  // mount request.
777  if (OldVpb->RealDevice->Vpb == OldVpb) {
778 
779  // If not the final reference then swap out the Vpb.
780  if (!FinalReference) {
781 
782  NewVpb->Type = IO_TYPE_VPB;
783  NewVpb->Size = sizeof( VPB );
784  NewVpb->RealDevice = OldVpb->RealDevice;
785 
786  NewVpb->RealDevice->Vpb = NewVpb;
787 
788  NewVpb = NULL;
789  IoReleaseVpbSpinLock(SavedIrql);
790  // We want to leave the Vpb for the IO system. Mark it
791  // as being not mounted. Go ahead and delete the Vcb as
792  // well.
793  } else {
794 
795  // Make sure to remove the last reference on the Vpb.
796 
797  OldVpb->ReferenceCount--;
798 
799  OldVpb->DeviceObject = NULL;
800  Vcb->Vpb->Flags &= ~VPB_MOUNTED;
801 
802  // Clear the Vpb flag so we know not to delete it.
803  Vcb->Vpb = NULL;
804 
805  IoReleaseVpbSpinLock(SavedIrql);
806  if(VcbAcquired)
807  UDFReleaseResource(&(Vcb->VCBResource));
810  VcbPresent = FALSE;
811  }
812 
813  // Someone has already swapped in a new Vpb. If this is the final reference
814  // then the file system is responsible for deleting the Vpb.
815  } else if (FinalReference) {
816 
817  // Make sure to remove the last reference on the Vpb.
818  OldVpb->ReferenceCount--;
819 
820  IoReleaseVpbSpinLock( SavedIrql );
821  if(VcbAcquired)
822  UDFReleaseResource(&(Vcb->VCBResource));
825  VcbPresent = FALSE;
826 
827  // The current Vpb is no longer the Vpb for the device (the IO system
828  // has already allocated a new one). We leave our reference in the
829  // Vpb and will be responsible for deleting it at a later time.
830  } else {
831 
832  OldVpb->DeviceObject = NULL;
833  Vcb->Vpb->Flags &= ~VPB_MOUNTED;
834 
835  IoReleaseVpbSpinLock( SavedIrql );
836  }
837 
838  // Deallocate the new Vpb if we don't need it.
839  if (NewVpb != NULL) {
840  DbgFreePool( NewVpb );
841  }
842 
843  // Let our caller know whether the Vcb is still present.
844  return VcbPresent;
845 } // end UDFDismountVcb()
846 
847 
848 NTSTATUS
850  IN PVCB OldVcb,
851  IN PVCB NewVcb,
852  IN BOOLEAN PhysicalOnly
853  )
854 {
855  NTSTATUS RC;
856  UDF_FILE_INFO RootFileInfo;
857  BOOLEAN SimpleLogicalCheck = FALSE;
858 
859  UDFPrint(("UDFCompareVcb:\n"));
861  UDFPrint((" WRONG_VOLUME\n"));
862  return STATUS_WRONG_VOLUME;
863  }
864 
865 #define VCB_NE(x) (OldVcb->x != NewVcb->x)
866 
867  // compare physical parameters
868  if(PhysicalOnly) {
869  UDFPrint((" PhysicalOnly\n"));
870  if(VCB_NE(FirstLBA) ||
871  VCB_NE(LastLBA) ||
872  VCB_NE(FirstTrackNum) ||
873  VCB_NE(LastTrackNum) ||
874  VCB_NE(NWA) ||
875  VCB_NE(LastPossibleLBA) ||
876  VCB_NE(PhSerialNumber) ||
877  VCB_NE(PhErasable) ||
878  VCB_NE(PhDiskType) ||
879  VCB_NE(MediaClassEx) ||
880 
881  /* We cannot compare these flags, because NewVcb is in unconditional ReadOnly */
882 
883  /*((OldVcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) != (NewVcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)) ||
884  ((OldVcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) != (NewVcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY)) ||*/
885 
887  // VCB_NE(xxx) ||
888  // VCB_NE(xxx) ||
889  VCB_NE(LastSession) ) {
890 
891  UDFPrint((" WRONG_VOLUME (2)\n"));
892  return STATUS_WRONG_VOLUME;
893  }
894  // Note, MRWStatus can change while media is mounted (stoppped/in-progress/complete)
895  // We can compare only (Vcb->MRWStatus == 0) values
896  if((OldVcb->MRWStatus == 0) != (NewVcb->MRWStatus == 0)) {
897  UDFPrint((" WRONG_VOLUME (4), missmatch MRW status\n"));
898  }
899  for(uint32 i=OldVcb->FirstTrackNum; i<=OldVcb->LastTrackNum; i++) {
900  if(VCB_NE(TrackMap[i].FirstLba) ||
901  VCB_NE(TrackMap[i].LastLba) ||
902  VCB_NE(TrackMap[i].PacketSize) ||
903  VCB_NE(TrackMap[i].TrackParam) ||
904  VCB_NE(TrackMap[i].DataParam) ||
905  VCB_NE(TrackMap[i].NWA_V) ) {
906  UDFPrint((" WRONG_VOLUME (3), missmatch trk %d\n", i));
907  return STATUS_WRONG_VOLUME;
908  }
909  }
910  UDFPrint((" Vcb compare Ok\n"));
911  return STATUS_SUCCESS;
912  }
913 
914  // Something is nasty!!! We perform verify for not flushed volume
915  // This should never happen, but some devices/buses and their drivers
916  // can lead us to such condition. For example with help of RESET.
917  // Now, we hope, that nobody changed media.
918  // We shall make simplified logical structure check
919  if(OldVcb->Modified) {
920  UDFPrint((" Vcb SIMPLE compare on !!!MODIFIED!!! volume\n"));
921  ASSERT(FALSE);
922  SimpleLogicalCheck = TRUE;
923  }
924 
925  // compare logical structure
926  if(!SimpleLogicalCheck && (OldVcb->InitVatCount != NewVcb->InitVatCount)) {
927  UDFPrint((" InitVatCount %d != %d \n", OldVcb->InitVatCount, NewVcb->InitVatCount));
928  return STATUS_WRONG_VOLUME;
929  }
930 
931  // Compare volume creation time
932  if(OldVcb->VolCreationTime != NewVcb->VolCreationTime) {
933  UDFPrint((" VolCreationTime %I64x != %I64x \n", OldVcb->VolCreationTime, NewVcb->VolCreationTime));
934  return STATUS_WRONG_VOLUME;
935  }
936  // Compare serial numbers
937  if(OldVcb->SerialNumber != NewVcb->SerialNumber) {
938  UDFPrint((" SerialNumber %x != %x \n", OldVcb->SerialNumber, NewVcb->SerialNumber));
939  return STATUS_WRONG_VOLUME;
940  }
941  // Compare volume idents
942  if(!SimpleLogicalCheck &&
943  RtlCompareUnicodeString(&(OldVcb->VolIdent),&(NewVcb->VolIdent),FALSE)) {
944  UDFPrint((" VolIdent missmatch \n"));
945  return STATUS_WRONG_VOLUME;
946  }
947  if(SimpleLogicalCheck) {
948  // do not touch RootDir. It can be partially recorded
949  UDFPrint((" SimpleLogicalCheck Ok\n"));
950  return STATUS_SUCCESS;
951  }
952 
953  RC = UDFOpenRootFile__(NewVcb, &(NewVcb->RootLbAddr), &RootFileInfo);
954  if(!NT_SUCCESS(RC)) {
955  UDFPrint((" Can't open root file, status %x\n", RC));
956  UDFCleanUpFile__(NewVcb, &RootFileInfo);
957  return STATUS_WRONG_VOLUME;
958  }
959  // perform exhaustive check
960  if(!(OldVcb->RootDirFCB)) {
961  UDFPrint((" !(OldVcb->RootDirFCB)\n"));
962 wr_vol:
963  UDFCloseFile__(NewVcb, &RootFileInfo);
964  UDFCleanUpFile__(NewVcb, &RootFileInfo);
965  return STATUS_WRONG_VOLUME;
966  }
967 
968  if(!UDFCompareFileInfo(&RootFileInfo, OldVcb->RootDirFCB->FileInfo)) {
969  UDFPrint((" !UDFCompareFileInfo\n"));
970  goto wr_vol;
971  }
972  UDFCloseFile__(NewVcb, &RootFileInfo);
973  UDFCleanUpFile__(NewVcb, &RootFileInfo);
974 
975  UDFPrint(("UDFCompareVcb: Ok\n"));
976  return STATUS_SUCCESS;
977 
978 #undef VCB_NE
979 
980 } // end UDFCompareVcb()
981 
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define UDF_VCB_FLAGS_MEDIA_READ_ONLY
Definition: udf_common.h:481
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
#define IN
Definition: typedefs.h:38
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
#define UDFPrint(Args)
Definition: udffs.h:225
#define WCACHE_CHAINED_IO
Definition: wcache_lib.h:193
#define TRUE
Definition: types.h:120
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
NTSTATUS NTAPI UDFPhSendIOCTL(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: env_spec.cpp:511
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID WCacheRelease__(IN PW_CACHE Cache)
NTSTATUS UDFStartEjectWaiter(IN PVCB Vcb)
Definition: fscntrl.cpp:850
_In_ ULONG Mode
Definition: hubbusif.h:303
#define DbgAllocatePoolWithTag(a, b, c)
Definition: env_spec_w32.h:333
_In_ PIRP Irp
Definition: csq.h:116
#define UDFSetFlag(Flag, Value)
Definition: udffs.h:191
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS UDFVerifyVcb(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb)
Definition: verfysup.cpp:37
unsigned int uint32
Definition: types.h:32
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
LONG NTSTATUS
Definition: precomp.h:26
#define UDFNormalizeAndRaiseStatus(IC, S)
Definition: udffs.h:319
ULONG WCacheBlocksPerFrameSh
Definition: udf_common.h:623
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define UDFNtAclSupported(Vcb)
Definition: udf_info.h:1040
#define WCACHE_RO_BAD_BLOCKS
Definition: wcache_lib.h:195
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
Definition: cdstruc.h:504
VOID UDFReleaseVCB(PVCB Vcb)
Definition: misc.cpp:2137
ULONG WCacheFramesToKeepFree
Definition: udf_common.h:624
#define UDF_DATA_FLAGS_BEING_UNLOADED
Definition: udf_common.h:636
#define WCACHE_MARK_BAD_BLOCKS
Definition: wcache_lib.h:194
OSSTATUS WCacheInit__(IN PW_CACHE Cache, IN ULONG MaxFrames, IN ULONG MaxBlocks, IN SIZE_T MaxBytesToRead, IN ULONG PacketSizeSh, IN ULONG BlockSizeSh, IN ULONG BlocksPerFrameSh, IN lba_t FirstLba, IN lba_t LastLba, IN ULONG Mode, IN ULONG Flags, IN ULONG FramesToKeepFree, IN PWRITE_BLOCK WriteProc, IN PREAD_BLOCK ReadProc, IN PWRITE_BLOCK_ASYNC WriteProcAsync, IN PREAD_BLOCK_ASYNC ReadProcAsync, IN PCHECK_BLOCK CheckUsedProc, IN PUPDATE_RELOC UpdateRelocProc, IN PWC_ERROR_HANDLER ErrorHandlerProc)
Definition: wcache_lib.cpp:116
#define STATUS_FILE_INVALID
Definition: ntstatus.h:374
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
OSSTATUS UDFGetDiskInfoAndVerify(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: mount.cpp:2983
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
BOOLEAN UDFDismountVcb(IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:727
#define UDF_VCB_FLAGS_REMOVABLE_MEDIA
Definition: udf_common.h:468
#define WCACHE_CACHE_WHOLE_PACKET
Definition: wcache_lib.h:191
#define UDFClearFlag(Flag, Value)
Definition: udffs.h:192
_SEH2_TRY
Definition: create.c:4250
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
NTSTATUS NTAPI UDFTSendIOCTL(IN ULONG IoControlCode, IN PVCB Vcb, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: env_spec.cpp:462
VOID WCacheFlushAll__(IN PW_CACHE Cache, IN PVOID Context)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4049
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BOOLEAN UDFCompareFileInfo(IN PUDF_FILE_INFO f1, IN PUDF_FILE_INFO f2)
Definition: udf_info.cpp:4218
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
NTSTATUS UDFVerifyVolume(IN PIRP Irp)
Definition: verfysup.cpp:158
#define UDF_VCB_FLAGS_UNSAFE_IOCTL
Definition: udf_common.h:488
ULONG WCacheChFlags__(IN PW_CACHE Cache, IN ULONG SetFlags, IN ULONG ClrFlags)
uint32 UDFIsBlockAllocated(IN void *_Vcb, IN uint32 Lba)
Definition: alloc.cpp:1164
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
ULONG ReferenceCount
Definition: iotypes.h:174
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
OSSTATUS UDFUpdateVAT(IN void *_Vcb, IN uint32 Lba, IN uint32 *RelocTab, IN uint32 BCount)
Definition: udf_info.cpp:5316
VOID UDFStopEjectWaiter(PVCB Vcb)
Definition: phys_eject.cpp:673
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
NTSTATUS UDFWCacheErrorHandler(IN PVOID Context, IN PWCACHE_ERROR_CONTEXT ErrorInfo)
Definition: misc.cpp:2583
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:171
OSSTATUS UDFTWrite(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T WrittenBytes, IN uint32 Flags)
Definition: phys_lib.cpp:453
#define UDFRaiseStatus(IC, S)
Definition: udffs.h:314
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
#define DbgFreePool
Definition: env_spec_w32.h:334
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
VOID UDFCloseResidual(IN PVCB Vcb)
Definition: fscntrl.cpp:1349
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4048
VOID UDFCleanupVCB(IN PVCB Vcb)
Definition: fscntrl.cpp:1428
#define UDF_VCB_FLAGS_MEDIA_LOCKED
Definition: udf_common.h:469
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define try_return(S)
Definition: cdprocs.h:2189
#define IRP_MJ_FILE_SYSTEM_CONTROL
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:172
#define Vcb
Definition: cdprocs.h:1425
#define MyFreePool__(addr)
Definition: mem_tools.h:152
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
#define SL_ALLOW_RAW_MOUNT
Definition: iotypes.h:1798
#define VCB_NE(x)
CSHORT Size
Definition: iotypes.h:168
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN _VcbAcquired)
Definition: verfysup.cpp:629
ULONG WCacheMaxBlocks
Definition: udf_common.h:622
#define VRS_ISO9660_FOUND
Definition: udf_rel.h:114
ULONG WCacheMaxFrames
Definition: udf_common.h:621
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
UDFData UDFGlobalData
Definition: udfinit.cpp:25
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define WCACHE_MODE_RAM
Definition: wcache_lib.h:127
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
#define IO_TYPE_VPB
OSSTATUS UDFTRead(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T ReadBytes, IN uint32 Flags)
Definition: phys_lib.cpp:596
struct _VPB VPB
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
#define UDF_VCB_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
_SEH2_END
Definition: create.c:4424
_In_ USHORT PacketSize
Definition: iofuncs.h:1056
uint32 UDFFlags
Definition: udf_common.h:627
OSSTATUS UDFTWriteVerify(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T WrittenBytes, IN uint32 Flags)
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_SEH2_FINALLY
Definition: create.c:4395
#define STATUS_REPARSE
Definition: ntstatus.h:83
BOOLEAN WCacheIsInitialized__(IN PW_CACHE Cache)
struct _VPB * PVPB
CSHORT Type
Definition: iotypes.h:167
#define WCACHE_MODE_R
Definition: wcache_lib.h:126
#define UDFIsRawDevice(RC)
Definition: udffs.h:324
#define WCACHE_DO_NOT_COMPARE
Definition: wcache_lib.h:192
#define WCACHE_MODE_ROM
Definition: wcache_lib.h:124
NTSTATUS UDFPerformVerify(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT DeviceToVerify)
Definition: verfysup.cpp:472
Definition: iotypes.h:166
#define BOOLEAN
Definition: pedump.c:73
#define MOUNT_ERR_THRESHOLD
Definition: udffs.h:62
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
OSSTATUS UDFTReadVerify(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T ReadBytes, IN uint32 Flags)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define IO_REMOUNT
Definition: iotypes.h:512
OSSTATUS UDFGetDiskInfo(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: phys_lib.cpp:3050
#define CdrwMediaClassEx_IsRAM(MediaClassEx)
Definition: cdrw_usr.h:799
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
OSSTATUS UDFVInit(IN PVCB Vcb)
Definition: remap.cpp:54
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1664
#define UDF_IRP_CONTEXT_EXCEPTION
Definition: struct.h:387
return STATUS_SUCCESS
Definition: btrfs.c:2938
OSSTATUS UDFOpenRootFile__(IN PVCB Vcb, IN lb_addr *RootLoc, OUT PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2187
#define VPB_MOUNTED
Definition: iotypes.h:1764
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:882
#define WCACHE_MODE_RW
Definition: wcache_lib.h:125
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1664
OSSTATUS WCacheSetMode__(IN PW_CACHE Cache, IN ULONG Mode)
_Inout_ PIRP _In_ PDEVICE_OBJECT DeviceToVerify
Definition: cdprocs.h:1417
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
#define UDF_VCB_FLAGS_VOLUME_LOCKED
Definition: udf_common.h:460
NTSTATUS UDFCompareVcb(IN PVCB OldVcb, IN PVCB NewVcb, IN BOOLEAN PhysicalOnly)
Definition: verfysup.cpp:849