ReactOS 0.4.15-dev-7934-g1dc8d80
verfysup.cpp
Go to the documentation of this file.
1
2// 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/*
26Routine 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.
31Arguments:
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) {
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 );
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"));
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
145Routine Description:
146 This routine performs the verify volume operation. It is responsible for
147 either completing of enqueuing the input Irp.
148
149Arguments:
150 Irp - Supplies the Irp to process
151
152Return Value:
153
154 NTSTATUS - The return status for the operation
155
156--*/
159 IN PIRP Irp
160 )
161{
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"));
209 }
210
211 if(UDFIsRawDevice(RC)) {
212 UDFPrint(("UDFVerifyVolume: STATUS_WRONG_VOLUME (2)\n"));
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 }
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
319skip_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"));
328 Vcb->SoftEjectReq = FALSE;
329 }
330 UDFClearFlag( Vpb->RealDevice->Flags, DO_VERIFY_VOLUME );
331
332try_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"));
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/*
458Routine 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
465Arguments:
466
467 Irp - The irp to send off after all is well and done.
468 Device - The real device needing verification.
469
470*/
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
610Routine 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
623Arguments:
624
625 Vcb - Vcb for the volume to try to dismount.
626
627*/
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
707Routine 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
717Arguments:
718
719 Vcb - Vcb for the volume to dismount.
720
721Return Value:
722
723 BOOLEAN - TRUE if we didn't delete the Vcb, FALSE otherwise.
724
725*/
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.
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
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"));
962wr_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
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
uint32 UDFIsBlockAllocated(IN void *_Vcb, IN uint32 Lba)
Definition: alloc.cpp:1164
LONG NTSTATUS
Definition: precomp.h:26
unsigned int uint32
Definition: types.h:32
_Inout_ PIRP _In_ PDEVICE_OBJECT DeviceToVerify
Definition: cdprocs.h:1409
#define try_return(S)
Definition: cdprocs.h:2179
#define CdrwMediaClassEx_IsRAM(MediaClassEx)
Definition: cdrw_usr.h:799
struct _VCB * PVCB
Definition: fatstruc.h:557
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
return Iosb
Definition: create.c:4402
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
VOID UDFReleaseVCB(PVCB Vcb)
Definition: misc.cpp:2137
NTSTATUS UDFWCacheErrorHandler(IN PVOID Context, IN PWCACHE_ERROR_CONTEXT ErrorInfo)
Definition: misc.cpp:2583
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
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
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
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define DbgAllocatePoolWithTag(a, b, c)
Definition: env_spec_w32.h:333
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define DbgFreePool
Definition: env_spec_w32.h:334
#define NonPagedPool
Definition: env_spec_w32.h:307
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1674
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
NTSTATUS UDFStartEjectWaiter(IN PVCB Vcb)
Definition: fscntrl.cpp:850
VOID UDFCleanupVCB(IN PVCB Vcb)
Definition: fscntrl.cpp:1428
VOID UDFCloseResidual(IN PVCB Vcb)
Definition: fscntrl.cpp:1349
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
_In_ ULONG Mode
Definition: hubbusif.h:303
#define NOTHING
Definition: input_list.c:10
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define ASSERT(a)
Definition: mode.c:44
OSSTATUS UDFGetDiskInfoAndVerify(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: mount.cpp:2983
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:98
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:877
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
#define BOOLEAN
Definition: pedump.c:73
#define Vcb
Definition: cdprocs.h:1415
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
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
OSSTATUS UDFGetDiskInfo(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: phys_lib.cpp:3050
VOID UDFStopEjectWaiter(PVCB Vcb)
Definition: phys_eject.cpp:673
OSSTATUS UDFTReadVerify(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T ReadBytes, IN uint32 Flags)
OSSTATUS UDFTWriteVerify(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T WrittenBytes, IN uint32 Flags)
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
OSSTATUS UDFVInit(IN PVCB Vcb)
Definition: remap.cpp:54
#define STATUS_SUCCESS
Definition: shellext.h:65
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@3999 VerifyVolume
ULONG WCacheFramesToKeepFree
Definition: udf_common.h:624
ULONG WCacheBlocksPerFrameSh
Definition: udf_common.h:623
ULONG WCacheMaxFrames
Definition: udf_common.h:621
ULONG WCacheMaxBlocks
Definition: udf_common.h:622
uint32 UDFFlags
Definition: udf_common.h:627
Definition: cdstruc.h:498
Definition: iotypes.h:189
CSHORT Type
Definition: iotypes.h:190
CSHORT Size
Definition: iotypes.h:191
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:194
ULONG ReferenceCount
Definition: iotypes.h:197
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:195
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_VCB_FLAGS_REMOVABLE_MEDIA
Definition: udf_common.h:468
#define UDF_VCB_FLAGS_VOLUME_LOCKED
Definition: udf_common.h:460
#define UDF_VCB_FLAGS_UNSAFE_IOCTL
Definition: udf_common.h:488
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
#define UDF_VCB_FLAGS_MEDIA_READ_ONLY
Definition: udf_common.h:481
#define UDF_VCB_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
#define UDF_VCB_FLAGS_MEDIA_LOCKED
Definition: udf_common.h:469
#define UDF_DATA_FLAGS_BEING_UNLOADED
Definition: udf_common.h:636
OSSTATUS UDFOpenRootFile__(IN PVCB Vcb, IN lb_addr *RootLoc, OUT PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2187
OSSTATUS UDFUpdateVAT(IN void *_Vcb, IN uint32 Lba, IN uint32 *RelocTab, IN uint32 BCount)
Definition: udf_info.cpp:5316
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
BOOLEAN UDFCompareFileInfo(IN PUDF_FILE_INFO f1, IN PUDF_FILE_INFO f2)
Definition: udf_info.cpp:4218
#define UDFNtAclSupported(Vcb)
Definition: udf_info.h:1040
#define VRS_ISO9660_FOUND
Definition: udf_rel.h:114
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MOUNT_ERR_THRESHOLD
Definition: udffs.h:62
#define UDFSetFlag(Flag, Value)
Definition: udffs.h:189
#define UDFRaiseStatus(IC, S)
Definition: udffs.h:312
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define UDFClearFlag(Flag, Value)
Definition: udffs.h:190
#define UDFNormalizeAndRaiseStatus(IC, S)
Definition: udffs.h:317
#define UDFIsRawDevice(RC)
Definition: udffs.h:322
#define UDFPrint(Args)
Definition: udffs.h:223
NTSTATUS UDFCompareVcb(IN PVCB OldVcb, IN PVCB NewVcb, IN BOOLEAN PhysicalOnly)
Definition: verfysup.cpp:849
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN _VcbAcquired)
Definition: verfysup.cpp:629
#define VCB_NE(x)
NTSTATUS UDFVerifyVcb(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb)
Definition: verfysup.cpp:37
NTSTATUS UDFPerformVerify(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT DeviceToVerify)
Definition: verfysup.cpp:472
BOOLEAN UDFDismountVcb(IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:727
NTSTATUS UDFVerifyVolume(IN PIRP Irp)
Definition: verfysup.cpp:158
VOID WCacheFlushAll__(IN PW_CACHE Cache, IN PVOID Context)
BOOLEAN WCacheIsInitialized__(IN PW_CACHE Cache)
VOID WCacheRelease__(IN PW_CACHE Cache)
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
OSSTATUS WCacheSetMode__(IN PW_CACHE Cache, IN ULONG Mode)
ULONG WCacheChFlags__(IN PW_CACHE Cache, IN ULONG SetFlags, IN ULONG ClrFlags)
#define WCACHE_MODE_R
Definition: wcache_lib.h:126
#define WCACHE_MODE_RW
Definition: wcache_lib.h:125
#define WCACHE_RO_BAD_BLOCKS
Definition: wcache_lib.h:195
#define WCACHE_CACHE_WHOLE_PACKET
Definition: wcache_lib.h:191
#define WCACHE_MODE_ROM
Definition: wcache_lib.h:124
#define WCACHE_MODE_RAM
Definition: wcache_lib.h:127
#define WCACHE_MARK_BAD_BLOCKS
Definition: wcache_lib.h:194
#define WCACHE_DO_NOT_COMPARE
Definition: wcache_lib.h:192
#define WCACHE_CHAINED_IO
Definition: wcache_lib.h:193
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
_In_ USHORT PacketSize
Definition: iofuncs.h:1058
struct _VPB * PVPB
#define IO_TYPE_VPB
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define SL_ALLOW_RAW_MOUNT
Definition: iotypes.h:1841
struct _VPB VPB
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define IO_REMOUNT
Definition: iotypes.h:544
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404