ReactOS 0.4.16-dev-334-g4d9f67c
fscntrl.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: FsCntrl.cpp
9
10 Abstract:
11
12 Contains code to handle the "File System IOCTL" dispatch entry point.
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_FS_CONTROL
24
26
28
29/*
30 Function: UDFFSControl()
31
32 Description:
33 The I/O Manager will invoke this routine to handle a File System
34 Control request (this is IRP_MJ_FILE_SYSTEM_CONTROL dispatch point)
35
36*/
40 PDEVICE_OBJECT DeviceObject, // the logical volume device object
41 PIRP Irp // I/O Request Packet
42 )
43{
45 PtrUDFIrpContext PtrIrpContext;
46 BOOLEAN AreWeTopLevel = FALSE;
47
48 UDFPrint(("\nUDFFSControl: \n\n"));
49
52 ASSERT(Irp);
53
54 // set the top level context
55 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
56
57 _SEH2_TRY {
58
59 // get an IRP context structure and issue the request
60 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
61 if(PtrIrpContext) {
62 RC = UDFCommonFSControl(PtrIrpContext, Irp);
63 } else {
65 Irp->IoStatus.Status = RC;
66 Irp->IoStatus.Information = 0;
67 // complete the IRP
69 }
70
72
73 UDFPrintErr(("UDFFSControl: exception ***"));
74 RC = UDFExceptionHandler(PtrIrpContext, Irp);
75
77 } _SEH2_END;
78
79 if(AreWeTopLevel) {
81 }
82
84
85 return(RC);
86} // end UDFFSControl()
87
88/*
89 Function: UDFCommonFSControl()
90
91 Description:
92 The actual work is performed here.
93
94 Expected Interrupt Level (for execution) :
95 IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
96 to be deferred to a worker thread context)
97
98 Return Value: STATUS_SUCCESS/Error
99*/
100
102NTAPI
104 PtrUDFIrpContext PtrIrpContext,
105 PIRP Irp // I/O Request Packet
106 )
107{
110// PDEVICE_OBJECT PtrTargetDeviceObject = NULL;
111
112 UDFPrint(("\nUDFCommonFSControl\n\n"));
113// BrutePoint();
114
115 _SEH2_TRY {
116
118 ASSERT(IrpSp);
119
120 switch ((IrpSp)->MinorFunction)
121 {
123 UDFPrint((" UDFFSControl: UserFsReq request ....\n"));
124
125 RC = UDFUserFsCtrlRequest(PtrIrpContext,Irp);
126 break;
128
129 UDFPrint((" UDFFSControl: MOUNT_VOLUME request ....\n"));
130
131 RC = UDFMountVolume(PtrIrpContext,Irp);
132 break;
134
135 UDFPrint((" UDFFSControl: VERIFY_VOLUME request ....\n"));
136
137 RC = UDFVerifyVolume(Irp);
138 break;
139 default:
140 UDFPrintErr((" UDFFSControl: STATUS_INVALID_DEVICE_REQUEST MinorFunction %x\n", (IrpSp)->MinorFunction));
142
143 Irp->IoStatus.Status = RC;
144 Irp->IoStatus.Information = 0;
145 // complete the IRP
147 break;
148 }
149
150//try_exit: NOTHING;
151 } _SEH2_FINALLY {
153 // Free up the Irp Context
154 UDFPrint((" UDFCommonFSControl: finally\n"));
155 UDFReleaseIrpContext(PtrIrpContext);
156 } else {
157 UDFPrint((" UDFCommonFSControl: finally after exception ***\n"));
158 }
159 } _SEH2_END;
160
161 return(RC);
162} // end UDFCommonFSControl()
163
164/*
165Routine Description:
166 This is the common routine for implementing the user's requests made
167 through NtFsControlFile.
168
169Arguments:
170 Irp - Supplies the Irp being processed
171
172Return Value:
173 NTSTATUS - The return status for the operation
174
175*/
177NTAPI
179 PtrUDFIrpContext IrpContext,
180 PIRP Irp
181 )
182{
183 NTSTATUS RC;
185
186 // Case on the control code.
187 switch ( IrpSp->Parameters.FileSystemControl.FsControlCode ) {
188
197
198 UDFPrint(("UDFUserFsCtrlRequest: OPLOCKS\n"));
200
201 Irp->IoStatus.Information = 0;
202 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
203 break;
204/*
205 RC = UDFOplockRequest( IrpContext, Irp );
206 break;
207*/
209
210 RC = UDFInvalidateVolumes( IrpContext, Irp );
211 break;
212/*
213 case FSCTL_MOVE_FILE:
214
215 case FSCTL_QUERY_ALLOCATED_RANGES:
216 case FSCTL_SET_ZERO_DATA:
217 case FSCTL_SET_SPARSE:
218
219 case FSCTL_MARK_VOLUME_DIRTY:
220
221 RC = UDFDirtyVolume( IrpContext, Irp );
222 break;
223
224 */
226
227 RC = UDFIsVolumeDirty(IrpContext, Irp);
228 break;
229
231
232 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_ALLOW_EXTENDED_DASD_IO\n"));
233 // DASD i/o is always permitted
234 // So, no-op this call
235 RC = STATUS_SUCCESS;
236
237 Irp->IoStatus.Information = 0;
238 Irp->IoStatus.Status = STATUS_SUCCESS;
239 break;
240
242
243 RC = UDFDismountVolume( IrpContext, Irp );
244 break;
245
247
248 RC = UDFIsVolumeMounted( IrpContext, Irp );
249 break;
250
252
253 RC = UDFGetStatistics( IrpContext, Irp );
254 break;
255
257
258 RC = UDFLockVolume( IrpContext, Irp );
259 break;
260
262
263 RC = UDFUnlockVolume( IrpContext, Irp );
264 break;
265
267
268 RC = UDFIsPathnameValid( IrpContext, Irp );
269 break;
270
272
273 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_GET_VOLUME_BITMAP\n"));
274 RC = UDFGetVolumeBitmap( IrpContext, Irp );
275 break;
276
278
279 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_GET_RETRIEVAL_POINTERS\n"));
280 RC = UDFGetRetrievalPointers( IrpContext, Irp, 0 );
281 break;
282
283
284 // We don't support any of the known or unknown requests.
285 default:
286
287 UDFPrintErr(("UDFUserFsCtrlRequest: STATUS_INVALID_DEVICE_REQUEST for %x\n",
288 IrpSp->Parameters.FileSystemControl.FsControlCode));
290
291 Irp->IoStatus.Information = 0;
292 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
293 break;
294 }
295
297 return RC;
298
299} // end UDFUserFsCtrlRequest()
300
301
302/*
303Routine Description:
304 This is the common routine for implementing the mount requests
305
306Arguments:
307 Irp - Supplies the Irp being processed
308
309Return Value:
310 NTSTATUS - The return status for the operation
311
312*/
314NTAPI
316 IN PtrUDFIrpContext PtrIrpContext,
317 IN PIRP Irp
318 )
319{
320 NTSTATUS RC;
323 PFILTER_DEV_EXTENSION filterDevExt;
324 PDEVICE_OBJECT fsDeviceObject;
326 PVCB Vcb = NULL;
327// PVCB OldVcb = NULL;
328 PDEVICE_OBJECT VolDo = NULL;
330 ULONG MediaChangeCount = 0;
331 ULONG Characteristics;
332 DEVICE_TYPE FsDeviceType;
333 BOOLEAN RestoreDoVerify = FALSE;
334 BOOLEAN WrongMedia = FALSE;
337 ULONG Mode;
338 TEST_UNIT_READY_USER_OUT TestUnitReadyBuffer;
339 ULONG i;
340 LARGE_INTEGER delay;
341 BOOLEAN VcbAcquired = FALSE;
342 BOOLEAN DeviceNotTouched = TRUE;
344 int8* ioBuf = NULL;
345
346 ASSERT(IrpSp);
347 UDFPrint(("\n !!! UDFMountVolume\n"));
348// UDFPrint(("Build " VER_STR_PRODUCT "\n\n"));
349
350 fsDeviceObject = PtrIrpContext->TargetDeviceObject;
351 UDFPrint(("Mount on device object %x\n", fsDeviceObject));
352 filterDevExt = (PFILTER_DEV_EXTENSION)fsDeviceObject->DeviceExtension;
354 filterDevExt->NodeIdentifier.NodeSize == sizeof(FILTER_DEV_EXTENSION)) {
356 } else
358 filterDevExt->NodeIdentifier.NodeSize == sizeof(UDFFS_DEV_EXTENSION)) {
360 } else {
361 UDFPrintErr(("Invalid node type in FS or FILTER DeviceObject\n"));
362 ASSERT(FALSE);
363 }
364 // Get a pointer to the target physical/virtual device object.
366
367 if(((Characteristics = TargetDeviceObject->Characteristics) & FILE_FLOPPY_DISKETTE) ||
369 WrongMedia = TRUE;
370 } else {
371 RemovableMedia = (Characteristics & FILE_REMOVABLE_MEDIA) ? TRUE : FALSE;
372 if(TargetDeviceObject->DeviceType != FILE_DEVICE_CD_ROM) {
374 WrongMedia = TRUE;
375 }
376 }
377 if(TargetDeviceObject->DeviceType == FILE_DEVICE_CD_ROM) {
378 FsDeviceType = FILE_DEVICE_CD_ROM_FILE_SYSTEM;
379#ifdef UDF_HDD_SUPPORT
380 } else
381 if (TargetDeviceObject->DeviceType == FILE_DEVICE_DISK) {
382 if(RemovableMedia) {
384 WrongMedia = TRUE;
385 }
386 } else {
388 WrongMedia = TRUE;
389 }
390 }
391 FsDeviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
392#endif //UDF_HDD_SUPPORT
393 } else {
394 WrongMedia = TRUE;
395 }
396 }
397
398 // Acquire GlobalDataResource
399 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
400
401 _SEH2_TRY {
402
403 UDFScanForDismountedVcb(PtrIrpContext);
404
405 if(WrongMedia) try_return(RC = STATUS_UNRECOGNIZED_VOLUME);
406
407 if(RemovableMedia) {
408 UDFPrint(("UDFMountVolume: removable media\n"));
409 // just remember current MediaChangeCount
410 // or fail if No Media ....
411
412 // experimental CHECK_VERIFY, for fucking BENQ DVD_DD_1620
413
414 // Now we can get device state via GET_EVENT (if supported)
415 // or still one TEST_UNIT_READY command
418 NULL,0,
419 &MediaChangeCount,sizeof(ULONG),
420 FALSE,&Iosb );
421
422 // Send TEST_UNIT_READY comment
423 // This can spin-up or wake-up the device
425 delay.QuadPart = -15000000LL; // 1.5 sec
426 for(i=0; i<UDF_READY_MAX_RETRY; i++) {
427 // Use device default ready timeout
428 Mode = 0;
431 &Mode,sizeof(Mode),
432 &TestUnitReadyBuffer,sizeof(TEST_UNIT_READY_USER_OUT),
433 FALSE,NULL);
434 UDFPrint(("UDFMountVolume: TEST_UNIT_READY %x\n", RC));
435 if(!NT_SUCCESS(RC))
436 break;
437 if(TestUnitReadyBuffer.SenseKey == SCSI_SENSE_NOT_READY &&
438 TestUnitReadyBuffer.AdditionalSenseCode == SCSI_ADSENSE_LUN_NOT_READY &&
440 UDFPrint(("UDFMountVolume: retry\n"));
442 //delay.QuadPart -= 10000000LL; // 1.0 sec
443 } else {
444 break;
445 }
446 }
447 if(i) {
448 UDFPrint(("UDFMountVolume: additional delay 3 sec\n"));
449 delay.QuadPart = -30000000LL; // 3.0 sec
451 }
452 }
453
454 // Now we can get device state via GET_EVENT (if supported)
455 // or still one TEST_UNIT_READY command
458 NULL,0,
459 &MediaChangeCount,sizeof(ULONG),
460 FALSE,&Iosb );
461
462 if(RC == STATUS_IO_DEVICE_ERROR) {
463 UDFPrint(("UDFMountVolume: retry check verify\n"));
466 NULL,0,
467 &MediaChangeCount,sizeof(ULONG),
468 FALSE,&Iosb );
469 }
470
471 if(!NT_SUCCESS(RC) && (RC != STATUS_VERIFY_REQUIRED))
472 try_return(RC);
473
474 // Be safe about the count in case the driver didn't fill it in
475 if(Iosb.Information != sizeof(ULONG)) {
476 MediaChangeCount = 0;
477 }
478
479 if(FsDeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) {
480 // Check if device is busy before locking tray and performing
481 // further geomentry discovery. This is needed to avoid streaming
482 // loss during CD-R recording. Note, that some recording tools
483 // work with device via SPTI bypassing FS/Device driver layers.
484
485 ioBuf = (int8*)MyAllocatePool__(NonPagedPool,4096);
486 if(!ioBuf) {
488 }
490 ioBuf,sizeof(DISK_GEOMETRY),
491 ioBuf,sizeof(DISK_GEOMETRY),
492 FALSE, NULL );
493
494 if(RC == STATUS_DEVICE_NOT_READY) {
495 // probably, the device is really busy, may be by CD/DVD recording
496 UserPrint((" busy (*)\n"));
497 try_return(RC);
498 }
499 }
500
501 // lock media for now
502 if(!WrongMedia) {
503 ((PPREVENT_MEDIA_REMOVAL_USER_IN)(&MediaChangeCount))->PreventMediaRemoval = TRUE;
506 &MediaChangeCount,sizeof(PREVENT_MEDIA_REMOVAL_USER_IN),
507 NULL,0,
508 FALSE,NULL);
509 Locked = TRUE;
510 }
511
512 }
513 // Now before we can initialize the Vcb we need to set up the
514 // Get our device object and alignment requirement.
515 // Device extension == VCB
516 UDFPrint(("UDFMountVolume: create device\n"));
517 RC = IoCreateDevice( UDFGlobalData.DriverObject,
518 sizeof(VCB),
519 NULL,
520 FsDeviceType,
521 0,
522 FALSE,
523 &VolDo );
524
525 if(!NT_SUCCESS(RC)) try_return(RC);
526
527 // Our alignment requirement is the larger of the processor alignment requirement
528 // already in the volume device object and that in the DeviceObjectWeTalkTo
529 if(TargetDeviceObject->AlignmentRequirement > VolDo->AlignmentRequirement) {
530 VolDo->AlignmentRequirement = TargetDeviceObject->AlignmentRequirement;
531 }
532
533 VolDo->Flags &= ~DO_DEVICE_INITIALIZING;
534
535 // device object field in the VPB to point to our new volume device
536 // object.
537 Vpb->DeviceObject = (PDEVICE_OBJECT) VolDo;
538
539 // We must initialize the stack size in our device object before
540 // the following reads, because the I/O system has not done it yet.
541 ((PDEVICE_OBJECT)VolDo)->StackSize = (CCHAR) (TargetDeviceObject->StackSize + 1);
542
543 Vcb = (PVCB)VolDo->DeviceExtension;
544
545 // Initialize the Vcb. This routine will raise on an allocation
546 // failure.
548 if(!NT_SUCCESS(RC)) {
549 Vcb = NULL;
550 try_return(RC);
551 }
552
553 VolDo = NULL;
554 Vpb = NULL;
555
556 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE );
557 VcbAcquired = TRUE;
558
559 // Let's reference the Vpb to make sure we are the one to
560 // have the last dereference.
561 Vcb->Vpb->ReferenceCount ++;
562
563 Vcb->MediaChangeCount = MediaChangeCount;
564 Vcb->FsDeviceType = FsDeviceType;
565
566 // Clear the verify bit for the start of mount.
567 if(Vcb->Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) {
568 Vcb->Vpb->RealDevice->Flags &= ~DO_VERIFY_VOLUME;
569 RestoreDoVerify = TRUE;
570 }
571
572 DeviceNotTouched = FALSE;
574 if(!NT_SUCCESS(RC)) try_return(RC);
575
576 // **** Read registry settings ****
578
579 Vcb->MountPhErrorCount = 0;
580
581 // Initialize internal cache
583 RC = WCacheInit__(&(Vcb->FastCache),
584 Vcb->WCacheMaxFrames,
585 Vcb->WCacheMaxBlocks,
586 Vcb->WriteBlockSize,
587 5, Vcb->BlockSizeBits,
588 Vcb->WCacheBlocksPerFrameSh,
589 0/*Vcb->FirstLBA*/, Vcb->LastPossibleLBA, Mode,
590 0/*WCACHE_CACHE_WHOLE_PACKET*/ |
591 (Vcb->DoNotCompareBeforeWrite ? WCACHE_DO_NOT_COMPARE : 0) |
592 (Vcb->CacheChainedIo ? WCACHE_CHAINED_IO : 0) |
593 WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS, // this will be cleared after mount
594 Vcb->WCacheFramesToKeepFree,
595// UDFTWrite, UDFTRead,
597#ifdef UDF_ASYNC_IO
598 UDFTWriteAsync, UDFTReadAsync,
599#else //UDF_ASYNC_IO
600 NULL, NULL,
601#endif //UDF_ASYNC_IO
605 if(!NT_SUCCESS(RC)) try_return(RC);
606
607 RC = UDFVInit(Vcb);
608 if(!NT_SUCCESS(RC)) try_return(RC);
609
610 UDFAcquireResourceExclusive(&(Vcb->BitMapResource1),TRUE);
612 UDFReleaseResource(&(Vcb->BitMapResource1));
613
614 ASSERT(!Vcb->Modified);
615 WCacheChFlags__(&(Vcb->FastCache),
616 WCACHE_CACHE_WHOLE_PACKET, // enable cache whole packet
617 WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS); // let user retry request on Bad Blocks
618
619#ifdef UDF_READ_ONLY_BUILD
622#endif //UDF_READ_ONLY_BUILD
623
624 if(!NT_SUCCESS(RC)) {
625 UDFPrint(("UDFMountVolume: try raw mount\n"));
626 if(Vcb->NSRDesc & VRS_ISO9660_FOUND) {
627 UDFPrint(("UDFMountVolume: block raw mount due to ISO9660 presence\n"));
628 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_RAW_DISK;
629 try_return(RC);
630 }
631try_raw_mount:
632 UDFPrint(("UDFMountVolume: try raw mount (2)\n"));
633 if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
634
635 UDFPrint(("UDFMountVolume: trying raw mount...\n"));
636 Vcb->VolIdent.Length =
637 (Vcb->VolIdent.MaximumLength = sizeof(UDF_BLANK_VOLUME_LABEL)) - 2;
638 if(Vcb->VolIdent.Buffer)
639 MyFreePool__(Vcb->VolIdent.Buffer);
640 Vcb->VolIdent.Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, sizeof(UDF_BLANK_VOLUME_LABEL));
641 if(!Vcb->VolIdent.Buffer)
644
645 RC = UDFBlankMount(Vcb);
646 if(!NT_SUCCESS(RC)) try_return(RC);
647
648 } else {
649// Vcb->VCBFlags &= ~UDF_VCB_FLAGS_RAW_DISK;
650 try_return(RC);
651 }
652 } else {
653 Vcb->MountPhErrorCount = -1;
654#ifndef UDF_READ_ONLY_BUILD
655 // set cache mode according to media type
656 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY)) {
657 UDFPrint(("UDFMountVolume: writable volume\n"));
658 if(!Vcb->CDR_Mode) {
659 if((FsDeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) ||
660 CdrwMediaClassEx_IsRAM(Vcb->MediaClassEx)) {
661 UDFPrint(("UDFMountVolume: RAM mode\n"));
663 } else {
664 UDFPrint(("UDFMountVolume: RW mode\n"));
666 }
667/* if(FsDeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) {
668 } else {
669 Vcb->WriteSecurity = TRUE;
670 }*/
671 } else {
672 UDFPrint(("UDFMountVolume: R mode\n"));
674 }
675 // we can't record ACL on old format disks
676 if(!UDFNtAclSupported(Vcb)) {
677 UDFPrint(("UDFMountVolume: NO ACL and ExtFE support\n"));
678 Vcb->WriteSecurity = FALSE;
679 Vcb->UseExtendedFE = FALSE;
680 }
681 }
682 WCacheSetMode__(&(Vcb->FastCache), Mode);
683#endif //UDF_READ_ONLY_BUILD
684 // Complete mount operations: create root FCB
685 UDFAcquireResourceExclusive(&(Vcb->BitMapResource1),TRUE);
686 RC = UDFCompleteMount(Vcb);
687 UDFReleaseResource(&(Vcb->BitMapResource1));
688 if(!NT_SUCCESS(RC)) {
689 // We must have Vcb->VCBOpenCount = 1 for UDFBlankMount()
690 // Thus, we should not decrement it here
691 // Also, if we shall not perform BlankMount,
692 // but simply cleanup and return error, Vcb->VCBOpenCount
693 // will be decremented during cleanup. Thus anyway it must
694 // stay 1 unchanged here
695 //UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
697 Vcb->VCBOpenCount = 1;
698 if(FsDeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
699 Vcb->VCBFlags |= UDF_VCB_FLAGS_RAW_DISK;
700 goto try_raw_mount;
701 }
702 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_RAW_DISK;
703 }
704
705#ifndef UDF_READ_ONLY_BUILD
706 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY)) {
708 if(!NT_SUCCESS(RC)) try_return(RC);
709 } else {
710 UDFPrint(("UDFMountVolume: RO mount\n"));
712 }
713#endif //UDF_READ_ONLY_BUILD
714
715 Vcb->Vpb->SerialNumber = Vcb->PhSerialNumber;
716 Vcb->Vpb->VolumeLabelLength = Vcb->VolIdent.Length;
717 RtlCopyMemory( Vcb->Vpb->VolumeLabel,
718 Vcb->VolIdent.Buffer,
719 Vcb->VolIdent.Length );
720
722
723 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
724 Vcb->TotalAllocUnits = UDFGetTotalSpace(Vcb);
725 Vcb->FreeAllocUnits = UDFGetFreeSpace(Vcb);
726 // Register shutdown routine
727 if(!Vcb->ShutdownRegistered) {
728 UDFPrint(("UDFMountVolume: Register shutdown routine\n"));
729 IoRegisterShutdownNotification(Vcb->VCBDeviceObject);
730 Vcb->ShutdownRegistered = TRUE;
731 }
732
733 // unlock media
734 if(RemovableMedia) {
735 if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) {
736 UDFPrint(("UDFMountVolume: unlock media on RO volume\n"));
737 ((PPREVENT_MEDIA_REMOVAL_USER_IN)(&MediaChangeCount))->PreventMediaRemoval = FALSE;
740 &MediaChangeCount,sizeof(PREVENT_MEDIA_REMOVAL_USER_IN),
741 NULL,0,
742 FALSE,NULL);
744 UDFResetDeviceDriver(Vcb, Vcb->TargetDeviceObject, TRUE);
745 }
746 }
747
748 if (UDFGlobalData.MountEvent)
749 {
750 Vcb->IsVolumeJustMounted = TRUE;
751 KeSetEvent(UDFGlobalData.MountEvent, 0, FALSE);
752 }
753
754 // The new mount is complete.
755 UDFReleaseResource( &(Vcb->VCBResource) );
756 VcbAcquired = FALSE;
757 Vcb = NULL;
758
759 RC = STATUS_SUCCESS;
760
761try_exit: NOTHING;
762 } _SEH2_FINALLY {
763
764 UDFPrint(("UDFMountVolume: RC = %x\n", RC));
765
766 if(ioBuf) {
767 MyFreePool__(ioBuf);
768 }
769
770 if(!NT_SUCCESS(RC)) {
771
772 if(RemovableMedia && Locked) {
773 UDFPrint(("UDFMountVolume: unlock media\n"));
774 ((PPREVENT_MEDIA_REMOVAL_USER_IN)(&MediaChangeCount))->PreventMediaRemoval = FALSE;
777 &MediaChangeCount,sizeof(PREVENT_MEDIA_REMOVAL_USER_IN),
778 NULL,0,
779 FALSE,NULL);
780 }
781/* if((RC != STATUS_DEVICE_NOT_READY) &&
782 (RC != STATUS_NO_MEDIA_IN_DEVICE) ) {*/
783 // reset driver
784 if(!DeviceNotTouched &&
785 (!Vcb || (Vcb && (Vcb->VCBFlags & UDF_VCB_FLAGS_OUR_DEVICE_DRIVER)))) {
786 UDFPrint(("UDFMountVolume: reset driver\n"));
788 }
789
791 UDFPrint(("UDFMountVolume: status -> STATUS_UNRECOGNIZED_VOLUME\n"));
793 }
794
795 // If we didn't complete the mount then cleanup any remaining structures.
796 if(Vpb) {
797 Vpb->DeviceObject = NULL;
798 }
799
800 if(Vcb) {
801 // Restore the verify bit.
802 if(RestoreDoVerify) {
803 Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
804 }
805 // Make sure there is no Vcb since it could go away
806 if(Vcb->VCBOpenCount)
807 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
808 // This procedure will also delete the volume device object
809 if(UDFDismountVcb( Vcb, VcbAcquired )) {
810 UDFReleaseResource( &(Vcb->VCBResource) );
811 }
812 } else if(VolDo) {
813 IoDeleteDevice( VolDo );
814 }
815 }
816 // Release the global resource.
817 UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
818
819 if (CompleteIrp || NT_SUCCESS(RC)) {
821 // Set mount event
822
823 UDFPrint(("UDFMountVolume: complete req RC %x\n", RC));
825 // Complete the IRP.
826 Irp->IoStatus.Status = RC;
828 }
829 } else {
830 // Pass Irp to lower driver (CDFS)
831
832 // Get this driver out of the driver stack and get to the next driver as
833 // quickly as possible.
834 Irp->CurrentLocation++;
835 Irp->Tail.Overlay.CurrentStackLocation++;
836
837 // Now call the appropriate file system driver with the request.
838 RC = IoCallDriver( filterDevExt->lowerFSDeviceObject, Irp );
839
840 }
841
842 } _SEH2_END;
843
844 UDFPrint(("UDFMountVolume: final RC = %x\n", RC));
845 return RC;
846
847} // end UDFMountVolume()
848
851 IN PVCB Vcb
852 )
853{
854// NTSTATUS RC;
856 UDFPrint(("UDFStartEjectWaiter:\n"));
857
858 if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) {
859 UDFPrint((" UDF_VCB_FLAGS_MEDIA_READ_ONLY\n"));
860 }
861 if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) {
862 UDFPrint((" UDF_VCB_FLAGS_MEDIA_LOCKED\n"));
863 }
864 UDFPrint((" EjectWaiter=%x\n", Vcb->EjectWaiter));
865 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) &&
867 !(Vcb->EjectWaiter)) {
868
869 UDFPrint(("UDFStartEjectWaiter: check driver\n"));
870 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_OUR_DEVICE_DRIVER) &&
871 (Vcb->FsDeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)) {
872 // we don't know how to write without our device driver
874 UDFPrint((" not our driver, ignore\n"));
875 return STATUS_SUCCESS;
876 }
877 UDFPrint(("UDFStartEjectWaiter: check removable\n"));
878 if(Vcb->VCBFlags & UDF_VCB_FLAGS_REMOVABLE_MEDIA) {
879 // prevent media removal
880 UDFPrint(("UDFStartEjectWaiter: lock media\n"));
883 Vcb,
884 &Buff,sizeof(PREVENT_MEDIA_REMOVAL_USER_IN),
885 NULL,0,
886 FALSE,NULL );
887 Vcb->VCBFlags |= UDF_VCB_FLAGS_MEDIA_LOCKED;
888 }
889 UDFPrint(("UDFStartEjectWaiter: prepare to start\n"));
890 // initialize Eject Request waiter
892 if(!(Vcb->EjectWaiter)) return STATUS_INSUFFICIENT_RESOURCES;
893 KeInitializeEvent(&(Vcb->WaiterStopped), NotificationEvent, FALSE);
894 Vcb->EjectWaiter->Vcb = Vcb;
895 Vcb->EjectWaiter->SoftEjectReq = FALSE;
896 KeInitializeEvent(&(Vcb->EjectWaiter->StopReq), NotificationEvent, FALSE);
897// Vcb->EjectWaiter->StopReq = FALSE;
898 Vcb->EjectWaiter->WaiterStopped = &(Vcb->WaiterStopped);
899 // This can occure after unexpected media loss, when EjectRequestWaiter
900 // terminates automatically
903 ExInitializeWorkItem(&(Vcb->EjectWaiter->EjectReqWorkQueueItem), UDFEjectReqWaiter, Vcb->EjectWaiter);
904 UDFPrint(("UDFStartEjectWaiter: create thread\n"));
905 ExQueueWorkItem(&(Vcb->EjectWaiter->EjectReqWorkQueueItem), DelayedWorkQueue);
906 } else {
907 UDFPrint((" ignore\n"));
908 }
909 return STATUS_SUCCESS;
910} // end UDFStartEjectWaiter()
911
914 IN PVCB Vcb
915 )
916{
917 NTSTATUS RC;// = STATUS_SUCCESS;
919 PFSRTL_COMMON_FCB_HEADER PtrCommonFCBHeader = NULL;
920 UNICODE_STRING LocalPath;
921 PtrUDFObjectName RootName;
922 PtrUDFFCB RootFcb;
923
924 UDFPrint(("UDFCompleteMount:\n"));
925 Vcb->ZBuffer = (PCHAR)DbgAllocatePoolWithTag(NonPagedPool, max(Vcb->LBlockSize, PAGE_SIZE), 'zNWD');
926 if(!Vcb->ZBuffer) return STATUS_INSUFFICIENT_RESOURCES;
927 RtlZeroMemory(Vcb->ZBuffer, Vcb->LBlockSize);
928
929 UDFPrint(("UDFCompleteMount: alloc Root FCB\n"));
930 // Create the root index and reference it in the Vcb.
931 RootFcb =
932 Vcb->RootDirFCB = UDFAllocateFCB();
933 if(!RootFcb) return STATUS_INSUFFICIENT_RESOURCES;
934
935 UDFPrint(("UDFCompleteMount: alloc Root ObjName\n"));
936 // Allocate and set root FCB unique name
937 RootName = UDFAllocateObjectName();
938 if(!RootName) {
939 UDFCleanUpFCB(RootFcb);
940 Vcb->RootDirFCB = NULL;
942 }
944 if(!NT_SUCCESS(RC))
945 goto insuf_res_1;
946
948 if(!RootFcb->FileInfo) {
950insuf_res_1:
951 MyFreePool__(RootName->ObjectName.Buffer);
952 UDFReleaseObjectName(RootName);
953 UDFCleanUpFCB(RootFcb);
954 Vcb->RootDirFCB = NULL;
955 return RC;
956 }
957 UDFPrint(("UDFCompleteMount: open Root Dir\n"));
958 // Open Root Directory
959 RC = UDFOpenRootFile__( Vcb, &(Vcb->RootLbAddr), RootFcb->FileInfo );
960 if(!NT_SUCCESS(RC)) {
961insuf_res_2:
962 UDFCleanUpFile__(Vcb, RootFcb->FileInfo);
963 MyFreePool__(RootFcb->FileInfo);
964 goto insuf_res_1;
965 }
966 RootFcb->FileInfo->Fcb = RootFcb;
967
968 if(!(RootFcb->NTRequiredFCB = RootFcb->FileInfo->Dloc->CommonFcb)) {
969 UDFPrint(("UDFCompleteMount: alloc Root ObjName (2)\n"));
970 if(!(RootFcb->NTRequiredFCB =
973 goto insuf_res_2;
974 }
976 RootFcb->FileInfo->Dloc->CommonFcb = RootFcb->NTRequiredFCB;
977 }
978 UDFPrint(("UDFCompleteMount: init FCB\n"));
980 if(!NT_SUCCESS(RC)) {
981 // if we get here, no resources are inited
982 RootFcb->OpenHandleCount =
983 RootFcb->ReferenceCount =
984 RootFcb->NTRequiredFCB->CommonRefCount = 0;
985
986 UDFCleanUpFile__(Vcb, RootFcb->FileInfo);
987 MyFreePool__(RootFcb->FileInfo);
988 MyFreePool__(RootFcb->NTRequiredFCB);
989 UDFCleanUpFCB(RootFcb);
990 Vcb->RootDirFCB = NULL;
991 return RC;
992 }
993
994 // this is a part of UDF_RESIDUAL_REFERENCE
995 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
996 RootFcb->OpenHandleCount =
997 RootFcb->ReferenceCount =
998 RootFcb->NTRequiredFCB->CommonRefCount = 1;
999
1000 UDFGetFileXTime(RootFcb->FileInfo,
1001 &(RootFcb->NTRequiredFCB->CreationTime.QuadPart),
1003 &(RootFcb->NTRequiredFCB->ChangeTime.QuadPart),
1004 &(RootFcb->NTRequiredFCB->LastWriteTime.QuadPart) );
1005
1006 if(Vcb->SysStreamLbAddr.logicalBlockNum) {
1007 Vcb->SysSDirFileInfo = (PUDF_FILE_INFO)MyAllocatePool__(NonPagedPool,sizeof(UDF_FILE_INFO));
1008 if(!Vcb->SysSDirFileInfo) {
1010 goto unwind_1;
1011 }
1012 // Open System SDir Directory
1013 RC = UDFOpenRootFile__( Vcb, &(Vcb->SysStreamLbAddr), Vcb->SysSDirFileInfo );
1014 if(!NT_SUCCESS(RC)) {
1015 UDFCleanUpFile__(Vcb, Vcb->SysSDirFileInfo);
1016 MyFreePool__(Vcb->SysSDirFileInfo);
1017 Vcb->SysSDirFileInfo = NULL;
1018 goto unwind_1;
1019 } else {
1020 Vcb->SysSDirFileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_VERIFY;
1021 }
1022 }
1023
1024 // Open Unallocatable space stream
1025 // Generally, it should be placed in SystemStreamDirectory, but some
1026 // stupid apps think that RootDirectory is much better place.... :((
1028 if(NT_SUCCESS(RC)) {
1029 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, RootFcb->FileInfo, &(Vcb->NonAllocFileInfo), NULL);
1030 MyFreePool__(LocalPath.Buffer);
1031 }
1032 if(!NT_SUCCESS(RC) && (RC != STATUS_OBJECT_NAME_NOT_FOUND)) {
1033
1034//unwind_2:
1035 UDFCleanUpFile__(Vcb, Vcb->NonAllocFileInfo);
1036 Vcb->NonAllocFileInfo = NULL;
1037 // this was a part of UDF_RESIDUAL_REFERENCE
1038 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
1039unwind_1:
1040
1041 // UDFCloseResidual() will clean up everything
1042
1043 return RC;
1044 }
1045
1046 /* process Non-allocatable */
1047 if(NT_SUCCESS(RC)) {
1048 UDFMarkSpaceAsXXX(Vcb, Vcb->NonAllocFileInfo->Dloc, Vcb->NonAllocFileInfo->Dloc->DataLoc.Mapping, AS_USED); // used
1049 UDFDirIndex(UDFGetDirIndexByFileInfo(Vcb->NonAllocFileInfo), Vcb->NonAllocFileInfo->Index)->FI_Flags |= UDF_FI_FLAG_FI_INTERNAL;
1050 } else {
1051 /* try to read Non-allocatable from alternate locations */
1053 if(!NT_SUCCESS(RC)) {
1054 goto unwind_1;
1055 }
1056 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, RootFcb->FileInfo, &(Vcb->NonAllocFileInfo), NULL);
1057 MyFreePool__(LocalPath.Buffer);
1058 if(!NT_SUCCESS(RC) && (RC != STATUS_OBJECT_NAME_NOT_FOUND)) {
1059 goto unwind_1;
1060 }
1061 if(NT_SUCCESS(RC)) {
1062 UDFMarkSpaceAsXXX(Vcb, Vcb->NonAllocFileInfo->Dloc, Vcb->NonAllocFileInfo->Dloc->DataLoc.Mapping, AS_USED); // used
1063 UDFDirIndex(UDFGetDirIndexByFileInfo(Vcb->NonAllocFileInfo), Vcb->NonAllocFileInfo->Index)->FI_Flags |= UDF_FI_FLAG_FI_INTERNAL;
1064 } else
1065 if(Vcb->SysSDirFileInfo) {
1067 if(!NT_SUCCESS(RC)) {
1068 goto unwind_1;
1069 }
1070 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, Vcb->SysSDirFileInfo , &(Vcb->NonAllocFileInfo), NULL);
1071 MyFreePool__(LocalPath.Buffer);
1072 if(!NT_SUCCESS(RC) && (RC != STATUS_OBJECT_NAME_NOT_FOUND)) {
1073 goto unwind_1;
1074 }
1075 if(NT_SUCCESS(RC)) {
1076 UDFMarkSpaceAsXXX(Vcb, Vcb->NonAllocFileInfo->Dloc, Vcb->NonAllocFileInfo->Dloc->DataLoc.Mapping, AS_USED); // used
1077// UDFDirIndex(UDFGetDirIndexByFileInfo(Vcb->NonAllocFileInfo), Vcb->NonAllocFileInfo->Index)->FI_Flags |= UDF_FI_FLAG_FI_INTERNAL;
1078 } else {
1079 RC = STATUS_SUCCESS;
1080 }
1081 } else {
1082 RC = STATUS_SUCCESS;
1083 }
1084 }
1085
1086 /* Read SN UID mapping */
1087 if(Vcb->SysSDirFileInfo) {
1088 RC = MyInitUnicodeString(&LocalPath, UDF_SN_UID_MAPPING);
1089 if(!NT_SUCCESS(RC))
1090 goto unwind_3;
1091 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, Vcb->SysSDirFileInfo , &(Vcb->UniqueIDMapFileInfo), NULL);
1092 MyFreePool__(LocalPath.Buffer);
1093 if(!NT_SUCCESS(RC) && (RC != STATUS_OBJECT_NAME_NOT_FOUND)) {
1094unwind_3:
1095// UDFCloseFile__(Vcb, Vcb->NonAllocFileInfo);
1096// UDFCleanUpFile__(Vcb, Vcb->NonAllocFileInfo);
1097// if(Vcb->NonAllocFileInfo)
1098// MyFreePool__(Vcb->NonAllocFileInfo);
1099// Vcb->NonAllocFileInfo = NULL;
1100 goto unwind_1;
1101 } else {
1102 Vcb->UniqueIDMapFileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_VERIFY;
1103 }
1104 RC = STATUS_SUCCESS;
1105 }
1106
1107#define DWN_MAX_CFG_FILE_SIZE 0x10000
1108
1109 /* Read DWN config file from disk with disk-specific options */
1111 if(NT_SUCCESS(RC)) {
1112
1113 int8* buff;
1114 SIZE_T len;
1115 PUDF_FILE_INFO CfgFileInfo = NULL;
1116
1117 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, RootFcb->FileInfo, &CfgFileInfo, NULL);
1118 if(OS_SUCCESS(RC)) {
1119
1120 len = (ULONG)UDFGetFileSize(CfgFileInfo);
1121 if(len && len < DWN_MAX_CFG_FILE_SIZE) {
1123 if(buff) {
1124 RC = UDFReadFile__(Vcb, CfgFileInfo, 0, len, FALSE, buff, &len);
1125 if(OS_SUCCESS(RC)) {
1126 // parse config
1127 Vcb->Cfg = (PUCHAR)buff;
1128 Vcb->CfgLength = len;
1129 UDFReadRegKeys(Vcb, TRUE /*update*/, TRUE /*cfg*/);
1130 Vcb->Cfg = NULL;
1131 Vcb->CfgLength = 0;
1132 Vcb->CfgVersion = 0;
1133 }
1135 }
1136 }
1137
1138 UDFCloseFile__(Vcb, CfgFileInfo);
1139 }
1140 if(CfgFileInfo) {
1141 UDFCleanUpFile__(Vcb, CfgFileInfo);
1142 }
1143 MyFreePool__(LocalPath.Buffer);
1144 }
1145 RC = STATUS_SUCCESS;
1146
1147 // clear Modified flags. It was not real modify, just
1148 // bitmap construction
1149 Vcb->BitmapModified = FALSE;
1150 //Vcb->Modified = FALSE;
1153 // this is a part of UDF_RESIDUAL_REFERENCE
1154 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
1155
1156 NtReqFcb = RootFcb->NTRequiredFCB;
1157
1158 // Start initializing the fields contained in the CommonFCBHeader.
1159 PtrCommonFCBHeader = &(NtReqFcb->CommonFCBHeader);
1160
1161 // DisAllow fast-IO for now.
1162// PtrCommonFCBHeader->IsFastIoPossible = FastIoIsNotPossible;
1163 PtrCommonFCBHeader->IsFastIoPossible = FastIoIsPossible;
1164
1165 // Initialize the MainResource and PagingIoResource pointers in
1166 // the CommonFCBHeader structure to point to the ERESOURCE structures we
1167 // have allocated and already initialized above.
1168// PtrCommonFCBHeader->Resource = &(NtReqFcb->MainResource);
1169// PtrCommonFCBHeader->PagingIoResource = &(NtReqFcb->PagingIoResource);
1170
1171 // Initialize the file size values here.
1172 PtrCommonFCBHeader->AllocationSize.QuadPart = 0;
1173 PtrCommonFCBHeader->FileSize.QuadPart = 0;
1174
1175 // The following will disable ValidDataLength support.
1176// PtrCommonFCBHeader->ValidDataLength.QuadPart = 0x7FFFFFFFFFFFFFFFI64;
1177 PtrCommonFCBHeader->ValidDataLength.QuadPart = 0;
1178
1179 if(!NT_SUCCESS(RC))
1180 return RC;
1181 UDFAssignAcl(Vcb, NULL, RootFcb, NtReqFcb);
1182/*
1183 Vcb->CDBurnerVolumeValid = true;
1184
1185 len =
1186 Vcb->CDBurnerVolume.Length = 256;
1187 Vcb->CDBurnerVolume.MaximumLength = 256;
1188 Vcb->CDBurnerVolume.Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, 256);
1189 RC = RegTGetStringValue(NULL, REG_CD_BURNER_KEY_NAME, REG_CD_BURNER_VOLUME_NAME, Vcb->CDBurnerVolume.Buffer,
1190 len);
1191 Vcb->CDBurnerVolume.Length = (USHORT)(wcslen(Vcb->CDBurnerVolume.Buffer)*sizeof(WCHAR));
1192
1193 if(RC != STATUS_OBJECT_NAME_NOT_FOUND && !NT_SUCCESS(RC) )
1194 return RC;
1195
1196 if (NT_SUCCESS(RC)) {
1197 RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
1198 REG_CD_BURNER_KEY_NAME, REG_CD_BURNER_VOLUME_NAME,
1199 REG_SZ,L"",sizeof(L"")+1);
1200
1201 } else {
1202 Vcb->CDBurnerVolumeValid = false;
1203 RC = STATUS_SUCCESS;
1204 }
1205*/
1206 ASSERT(!Vcb->Modified);
1207
1208 return RC;
1209} // end UDFCompleteMount()
1210
1213 IN PVCB Vcb
1214 )
1215{
1216 NTSTATUS RC;// = STATUS_SUCCESS;
1218 PFSRTL_COMMON_FCB_HEADER PtrCommonFCBHeader = NULL;
1219 PtrUDFObjectName RootName;
1220 PtrUDFFCB RootFcb;
1221 PDIR_INDEX_HDR hDirNdx;
1222 PDIR_INDEX_ITEM DirNdx;
1223
1224 // Create the root index and reference it in the Vcb.
1225 RootFcb =
1226 Vcb->RootDirFCB = UDFAllocateFCB();
1227 if(!RootFcb) return STATUS_INSUFFICIENT_RESOURCES;
1228 RtlZeroMemory(RootFcb,sizeof(UDFFCB));
1229
1230 // Allocate and set root FCB unique name
1231 RootName = UDFAllocateObjectName();
1232 if(!RootName) {
1233//bl_unwind_2:
1234 UDFCleanUpFCB(RootFcb);
1235 Vcb->RootDirFCB = NULL;
1237 }
1239 if(!NT_SUCCESS(RC))
1240 goto bl_unwind_1;
1241
1243 RootFcb->NodeIdentifier.NodeSize = sizeof(UDFFCB);
1244
1246 if(!RootFcb->FileInfo) {
1247 MyFreePool__(RootName->ObjectName.Buffer);
1249bl_unwind_1:
1250 UDFReleaseObjectName(RootName);
1251 UDFCleanUpFCB(RootFcb);
1252 Vcb->RootDirFCB = NULL;
1253 return RC;
1254 }
1255 RtlZeroMemory(RootFcb->FileInfo, sizeof(UDF_FILE_INFO));
1256 if(!OS_SUCCESS(RC = UDFStoreDloc(Vcb, RootFcb->FileInfo, 1))) {
1257 MyFreePool__(RootFcb->FileInfo);
1258 RootFcb->FileInfo = NULL;
1259 MyFreePool__(RootName->ObjectName.Buffer);
1260 goto bl_unwind_1;
1261 }
1262 RootFcb->FileInfo->NextLinkedFile =
1263 RootFcb->FileInfo->PrevLinkedFile = RootFcb->FileInfo;
1264
1265 hDirNdx = UDFDirIndexAlloc(2);
1266 DirNdx = UDFDirIndex(hDirNdx,0);
1270 RtlInitUnicodeString(&DirNdx->FName, L".");
1271 DirNdx->FileInfo = RootFcb->FileInfo;
1272 DirNdx->FI_Flags |= UDFBuildHashEntry(Vcb, &(DirNdx->FName), &(DirNdx->hashes), HASH_ALL | HASH_KEEP_NAME);
1273
1274 DirNdx = UDFDirIndex(hDirNdx,1);
1276 if(Vcb->ShowBlankCd == 2) {
1278 }
1280 RtlInitUnicodeString(&DirNdx->FName, L"Blank.CD");
1281 DirNdx->FI_Flags |= UDFBuildHashEntry(Vcb, &(DirNdx->FName), &(DirNdx->hashes), HASH_ALL);
1282
1283 RootFcb->FileInfo->Dloc->DirIndex = hDirNdx;
1284 RootFcb->FileInfo->Fcb = RootFcb;
1285
1286 if(!(RootFcb->NTRequiredFCB = RootFcb->FileInfo->Dloc->CommonFcb)) {
1287 if(!(RootFcb->NTRequiredFCB =
1289 MyFreePool__(RootName->ObjectName.Buffer);
1290 UDFReleaseObjectName(RootName);
1291 UDFCleanUpFCB(RootFcb);
1292 Vcb->RootDirFCB = NULL;
1294 }
1296 RootFcb->FileInfo->Dloc->CommonFcb = RootFcb->NTRequiredFCB;
1297 }
1299 if(!NT_SUCCESS(RC)) {
1300 // if we get here, no resources are inited
1301 RootFcb->OpenHandleCount =
1302 RootFcb->ReferenceCount =
1303 RootFcb->NTRequiredFCB->CommonRefCount = 0;
1304
1305 UDFCleanUpFile__(Vcb, RootFcb->FileInfo);
1306 MyFreePool__(RootFcb->FileInfo);
1307 MyFreePool__(RootFcb->NTRequiredFCB);
1308 UDFCleanUpFCB(RootFcb);
1309 Vcb->RootDirFCB = NULL;
1310 return RC;
1311 }
1312
1313 // this is a part of UDF_RESIDUAL_REFERENCE
1314 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
1315 RootFcb->OpenHandleCount =
1316 RootFcb->ReferenceCount =
1317 RootFcb->NTRequiredFCB->CommonRefCount =
1318 RootFcb->FileInfo->RefCount =
1319 RootFcb->FileInfo->Dloc->LinkRefCount = 1;
1320
1321 // this is a part of UDF_RESIDUAL_REFERENCE
1322 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
1323
1324 NtReqFcb = RootFcb->NTRequiredFCB;
1325
1326 // Start initializing the fields contained in the CommonFCBHeader.
1327 PtrCommonFCBHeader = &(NtReqFcb->CommonFCBHeader);
1328
1329 // DisAllow fast-IO for now.
1330 PtrCommonFCBHeader->IsFastIoPossible = FastIoIsNotPossible;
1331
1332 // Initialize the MainResource and PagingIoResource pointers in
1333 // the CommonFCBHeader structure to point to the ERESOURCE structures we
1334 // have allocated and already initialized above.
1335 PtrCommonFCBHeader->Resource = &(NtReqFcb->MainResource);
1336 PtrCommonFCBHeader->PagingIoResource = &(NtReqFcb->PagingIoResource);
1337
1338 // Initialize the file size values here.
1339 PtrCommonFCBHeader->AllocationSize.QuadPart = 0;
1340 PtrCommonFCBHeader->FileSize.QuadPart = 0;
1341
1342 // The following will disable ValidDataLength support.
1343 PtrCommonFCBHeader->ValidDataLength.QuadPart = 0x7FFFFFFFFFFFFFFFLL;
1344
1345 return RC;
1346} // end UDFBlankMount()
1347
1348VOID
1350 IN PVCB Vcb
1351 )
1352{
1353 // Deinitialize Non-alloc file
1354 if(Vcb->VCBOpenCount)
1355 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
1356 UDFPrint(("UDFCloseResidual: NonAllocFileInfo %x\n", Vcb->NonAllocFileInfo));
1357 if(Vcb->NonAllocFileInfo) {
1358 UDFCloseFile__(Vcb,Vcb->NonAllocFileInfo);
1359 UDFCleanUpFile__(Vcb, Vcb->NonAllocFileInfo);
1360 MyFreePool__(Vcb->NonAllocFileInfo);
1361 Vcb->NonAllocFileInfo = NULL;
1362 }
1363 // Deinitialize Unique ID Mapping
1364 UDFPrint(("UDFCloseResidual: NonAllocFileInfo %x\n", Vcb->NonAllocFileInfo));
1365 if(Vcb->UniqueIDMapFileInfo) {
1366 UDFCloseFile__(Vcb,Vcb->UniqueIDMapFileInfo);
1367 UDFCleanUpFile__(Vcb, Vcb->UniqueIDMapFileInfo);
1368 MyFreePool__(Vcb->UniqueIDMapFileInfo);
1369 Vcb->UniqueIDMapFileInfo = NULL;
1370 }
1371 // Deinitialize VAT file
1372 UDFPrint(("UDFCloseResidual: VatFileInfo %x\n", Vcb->VatFileInfo));
1373 if(Vcb->VatFileInfo) {
1374 UDFCloseFile__(Vcb,Vcb->VatFileInfo);
1375 UDFCleanUpFile__(Vcb, Vcb->VatFileInfo);
1376 MyFreePool__(Vcb->VatFileInfo);
1377 Vcb->VatFileInfo = NULL;
1378 }
1379 // System StreamDir
1380 UDFPrint(("UDFCloseResidual: SysSDirFileInfo %x\n", Vcb->SysSDirFileInfo));
1381 if(Vcb->SysSDirFileInfo) {
1382 UDFCloseFile__(Vcb, Vcb->SysSDirFileInfo);
1383 UDFCleanUpFile__(Vcb, Vcb->SysSDirFileInfo);
1384 MyFreePool__(Vcb->SysSDirFileInfo);
1385 Vcb->SysSDirFileInfo = NULL;
1386 }
1387/* // Deinitialize root dir fcb
1388 if(Vcb->RootDirFCB) {
1389 UDFCloseFile__(Vcb,Vcb->RootDirFCB->FileInfo);
1390 UDFCleanUpFile__(Vcb, Vcb->RootDirFCB->FileInfo);
1391 MyFreePool__(Vcb->RootDirFCB->FileInfo);
1392 UDFCleanUpFCB(Vcb->RootDirFCB);
1393 // Remove root FCB reference in vcb
1394 if(Vcb->VCBOpenCount) Vcb->VCBOpenCount--;
1395 }
1396
1397 // Deinitialize Non-alloc file
1398 if(Vcb->VCBOpenCount) Vcb->VCBOpenCount--;
1399 if(Vcb->NonAllocFileInfo) {
1400 UDFCloseFile__(Vcb,Vcb->NonAllocFileInfo);
1401 // We must release VCB here !!!!
1402// UDFCleanUpFcbChain(Vcb, Vcb->NonAllocFileInfo, 1);
1403 Vcb->NonAllocFileInfo = NULL;
1404 }
1405 // Deinitialize VAT file
1406 if(Vcb->VatFileInfo) {
1407 UDFCloseFile__(Vcb,Vcb->VatFileInfo);
1408 // We must release VCB here !!!!
1409// UDFCleanUpFcbChain(Vcb, Vcb->VatFileInfo, 1);
1410 Vcb->VatFileInfo = NULL;
1411 }*/
1412
1413 // Deinitialize root dir fcb
1414 UDFPrint(("UDFCloseResidual: RootDirFCB %x\n", Vcb->RootDirFCB));
1415 if(Vcb->RootDirFCB) {
1416 UDFCloseFile__(Vcb,Vcb->RootDirFCB->FileInfo);
1417 if(Vcb->RootDirFCB->OpenHandleCount)
1418 Vcb->RootDirFCB->OpenHandleCount--;
1419 UDFCleanUpFcbChain(Vcb, Vcb->RootDirFCB->FileInfo, 1, TRUE);
1420 // Remove root FCB reference in vcb
1421 if(Vcb->VCBOpenCount)
1422 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
1423 Vcb->RootDirFCB = NULL;
1424 }
1425} // end UDFCloseResidual()
1426
1427VOID
1429 IN PVCB Vcb
1430 )
1431{
1432 _SEH2_TRY {
1436 BrutePoint();
1437 } _SEH2_END;
1438
1439 if(Vcb->ShutdownRegistered && Vcb->VCBDeviceObject) {
1440 IoUnregisterShutdownNotification(Vcb->VCBDeviceObject);
1441 Vcb->ShutdownRegistered = FALSE;
1442 }
1443
1444 MyFreeMemoryAndPointer(Vcb->Partitions);
1447 MyFreeMemoryAndPointer(Vcb->SparingTable);
1448
1449 if(Vcb->FSBM_Bitmap) {
1450 DbgFreePool(Vcb->FSBM_Bitmap);
1451 Vcb->FSBM_Bitmap = NULL;
1452 }
1453 if(Vcb->ZSBM_Bitmap) {
1454 DbgFreePool(Vcb->ZSBM_Bitmap);
1455 Vcb->ZSBM_Bitmap = NULL;
1456 }
1457 if(Vcb->BSBM_Bitmap) {
1458 DbgFreePool(Vcb->BSBM_Bitmap);
1459 Vcb->BSBM_Bitmap = NULL;
1460 }
1461#ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS
1462 if(Vcb->FSBM_Bitmap_owners) {
1463 DbgFreePool(Vcb->FSBM_Bitmap_owners);
1464 Vcb->FSBM_Bitmap_owners = NULL;
1465 }
1466#endif //UDF_TRACK_ONDISK_ALLOCATION_OWNERS
1467 if(Vcb->FSBM_OldBitmap) {
1468 DbgFreePool(Vcb->FSBM_OldBitmap);
1469 Vcb->FSBM_OldBitmap = NULL;
1470 }
1471
1472 MyFreeMemoryAndPointer(Vcb->Statistics);
1473 MyFreeMemoryAndPointer(Vcb->NTRequiredFCB);
1474 MyFreeMemoryAndPointer(Vcb->VolIdent.Buffer);
1475 MyFreeMemoryAndPointer(Vcb->TargetDevName.Buffer);
1476
1477 if(Vcb->ZBuffer) {
1478 DbgFreePool(Vcb->ZBuffer);
1479 Vcb->ZBuffer = NULL;
1480 }
1481
1482 if(Vcb->fZBuffer) {
1483 DbgFreePool(Vcb->fZBuffer);
1484 Vcb->fZBuffer = NULL;
1485 }
1486
1488 MyFreeMemoryAndPointer(Vcb->WParams);
1490 MyFreeMemoryAndPointer(Vcb->TrackMap);
1491
1492} // end UDFCleanupVCB()
1493
1494/*
1495
1496Routine Description:
1497
1498 This routine walks through the list of Vcb's looking for any which may
1499 now be deleted. They may have been left on the list because there were
1500 outstanding references.
1501
1502Arguments:
1503
1504Return Value:
1505
1506 None
1507
1508*/
1509VOID
1511 IN PtrUDFIrpContext IrpContext
1512 )
1513{
1514 PVCB Vcb;
1516
1517
1518 // Walk through all of the Vcb's attached to the global data.
1519 Link = UDFGlobalData.VCBQueue.Flink;
1520
1521 while (Link != &(UDFGlobalData.VCBQueue)) {
1522
1523 Vcb = CONTAINING_RECORD( Link, VCB, NextVCB );
1524
1525 // Move to the next link now since the current Vcb may be deleted.
1526 Link = Link->Flink;
1527
1528 // If dismount is already underway then check if this Vcb can
1529 // go away.
1530 if((Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) ||
1531 ((!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) && (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE))) {
1532
1533 UDFCheckForDismount( IrpContext, Vcb, FALSE );
1534 }
1535 }
1536
1537 return;
1538} // end UDFScanForDismountedVcb()
1539
1540/*
1541Routine Description:
1542 This routine determines if a volume is currently mounted.
1543
1544Arguments:
1545 Irp - Supplies the Irp to process
1546
1547Return Value:
1548 NTSTATUS - The return status for the operation
1549
1550*/
1553 IN PtrUDFIrpContext IrpContext,
1554 IN PIRP Irp
1555 )
1556{
1558
1559 PtrUDFFCB Fcb;
1560 PtrUDFCCB Ccb;
1561
1562 UDFPrint(("UDFIsVolumeMounted\n"));
1563
1564 Ccb = (PtrUDFCCB)IrpSp->FileObject->FsContext2;
1565 if(!Ccb) {
1566 UDFPrintErr((" !Ccb\n"));
1567 Irp->IoStatus.Information = 0;
1568 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1570 }
1571 Fcb = Ccb->Fcb;
1572
1573 if(Fcb &&
1574 !(Fcb->Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
1575 !(Fcb->Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED) ) {
1576
1577 // Disable PopUps, we want to return any error.
1578 IrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_FLAG_DISABLE_POPUPS;
1579
1580 // Verify the Vcb. This will raise in the error condition.
1581 UDFVerifyVcb( IrpContext, Fcb->Vcb );
1582 }
1583
1584 Irp->IoStatus.Information = 0;
1585 Irp->IoStatus.Status = STATUS_SUCCESS;
1586
1587 return STATUS_SUCCESS;
1588} // end UDFIsVolumeMounted()
1589
1590/*
1591 This routine returns the filesystem performance counters from the
1592 appropriate VCB.
1593
1594Arguments:
1595 Irp - Supplies the Irp to process
1596
1597Return Value:
1598 NTSTATUS - The return status for the operation
1599*/
1602 IN PtrUDFIrpContext IrpContext,
1603 IN PIRP Irp
1604 )
1605{
1608 PVCB Vcb;
1609
1612 ULONG StatsSize;
1614
1615 UDFPrint(("UDFGetStatistics\n"));
1616
1617 // Extract the buffer
1618 BufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
1619 // Get a pointer to the output buffer.
1620 Buffer = (PFILE_SYSTEM_STATISTICS)(Irp->AssociatedIrp.SystemBuffer);
1621
1622 // Make sure the buffer is big enough for at least the common part.
1623 if (BufferLength < sizeof(FILESYSTEM_STATISTICS)) {
1625 Irp->IoStatus.Information = 0;
1626 goto EO_stat;
1627 }
1628
1629 // Now see how many bytes we can copy.
1630 StatsSize = sizeof(FILE_SYSTEM_STATISTICS) * KeNumberProcessors;
1631 if (BufferLength < StatsSize) {
1634 } else {
1635 BytesToCopy = StatsSize;
1637 }
1638
1639 Vcb = (PVCB)(((PDEVICE_OBJECT)IrpSp->DeviceObject)->DeviceExtension);
1640 // Fill in the output buffer
1641 RtlCopyMemory( Buffer, Vcb->Statistics, BytesToCopy );
1642 Irp->IoStatus.Information = BytesToCopy;
1643EO_stat:
1644 Irp->IoStatus.Status = status;
1645
1646 return status;
1647} // end UDFGetStatistics()
1648
1649
1650/*
1651 This routine determines if pathname is valid path for UDF Filesystem
1652
1653Arguments:
1654 Irp - Supplies the Irp to process
1655
1656Return Value:
1657 NTSTATUS - The return status for the operation
1658*/
1661 IN PtrUDFIrpContext IrpContext,
1662 IN PIRP Irp
1663 )
1664{
1666 NTSTATUS RC;
1667 PPATHNAME_BUFFER PathnameBuffer;
1668 UNICODE_STRING PathName;
1669 UNICODE_STRING CurName;
1670 PWCHAR TmpBuffer;
1671
1672 UDFPrint(("UDFIsPathnameValid\n"));
1673
1674 // Extract the pathname
1675 PathnameBuffer = (PPATHNAME_BUFFER)Irp->AssociatedIrp.SystemBuffer;
1676 PathName.Buffer = PathnameBuffer->Name;
1677 PathName.Length = (USHORT)PathnameBuffer->PathNameLength;
1678
1679 _SEH2_TRY {
1680 // Check for an invalid buffer
1681 if (FIELD_OFFSET(PATHNAME_BUFFER, Name[0]) + PathnameBuffer->PathNameLength >
1682 IrpSp->Parameters.FileSystemControl.InputBufferLength) {
1684 }
1685 while (TRUE) {
1686 // get next path part...
1687 TmpBuffer = PathName.Buffer;
1688 PathName.Buffer = UDFDissectName(PathName.Buffer,&(CurName.Length) );
1689 PathName.Length -= (USHORT)((ULONG_PTR)(PathName.Buffer) - (ULONG_PTR)TmpBuffer);
1690 CurName.Buffer = PathName.Buffer - CurName.Length;
1691 CurName.Length *= sizeof(WCHAR);
1692 CurName.MaximumLength -= CurName.Length;
1693
1694 if (CurName.Length) {
1695 // check path fragment size
1696 if (CurName.Length > UDF_NAME_LEN*sizeof(WCHAR)) {
1698 }
1699 if (!UDFIsNameValid(&CurName, NULL, NULL)) {
1701 }
1702 } else {
1704 }
1705 }
1706try_exit: NOTHING;
1707 } _SEH2_FINALLY {
1708 Irp->IoStatus.Information = 0;
1709 Irp->IoStatus.Status = RC;
1710 } _SEH2_END;
1711
1712 return RC;
1713} // end UDFIsPathnameValid()
1714
1715/*
1716 This routine performs the lock volume operation. It is responsible for
1717 either completing of enqueuing the input Irp.
1718Arguments:
1719 Irp - Supplies the Irp to process
1720Return Value:
1721 NTSTATUS - The return status for the operation
1722*/
1725 IN PtrUDFIrpContext IrpContext,
1726 IN PIRP Irp,
1727 IN ULONG PID
1728 )
1729{
1730 NTSTATUS RC;
1731
1732 KIRQL SavedIrql;
1734
1735 PVCB Vcb;
1736 PtrUDFFCB Fcb;
1737 PtrUDFCCB Ccb;
1738 BOOLEAN VcbAcquired = FALSE;
1739
1740 UDFPrint(("UDFLockVolume: PID %x\n", PID));
1741
1742 // Decode the file object, the only type of opens we accept are
1743 // user volume opens.
1744 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
1745 if(!Ccb) {
1746 UDFPrintErr((" !Ccb\n"));
1747 Irp->IoStatus.Information = 0;
1748 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1750 }
1751 Fcb = Ccb->Fcb;
1752 Vcb = Fcb->Vcb;
1753
1754 // Check for volume open
1755 if (Vcb != (PVCB)Fcb || !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN)) {
1756 Irp->IoStatus.Information = 0;
1757 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1759 }
1760
1762
1763 _SEH2_TRY {
1764
1765 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK))
1766 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
1767#ifdef UDF_DELAYED_CLOSE
1769#endif //UDF_DELAYED_CLOSE
1770
1771 // Acquire exclusive access to the Vcb.
1772 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE );
1773 VcbAcquired = TRUE;
1774
1775 // Verify the Vcb.
1776 UDFVerifyVcb( IrpContext, Vcb );
1777
1778 // If the volume is already locked then complete with success if this file
1779 // object has the volume locked, fail otherwise.
1780/* if (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED) {
1781
1782 if (Vcb->VolumeLockFileObject == IrpSp->FileObject) {
1783 RC = STATUS_SUCCESS;
1784 } else {
1785 RC = STATUS_ACCESS_DENIED;
1786 }
1787 // If the open count for the volume is greater than 1 then this request
1788 // will fail.
1789 } else if (Vcb->VCBOpenCount > UDF_RESIDUAL_REFERENCE+1) {
1790 RC = STATUS_ACCESS_DENIED;
1791 // We will try to get rid of all of the user references. If there is only one
1792 // remaining after the purge then we can allow the volume to be locked.
1793 } else {
1794 // flush system cache
1795 UDFReleaseResource( &(Vcb->VCBResource) );
1796 VcbAcquired = FALSE;
1797 }*/
1798
1799 } _SEH2_FINALLY {
1800
1801 // Release the Vcb.
1802 if(VcbAcquired) {
1803 UDFReleaseResource( &(Vcb->VCBResource) );
1804 VcbAcquired = FALSE;
1805 }
1806 } _SEH2_END;
1807
1808 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE );
1809 VcbAcquired = TRUE;
1811 UDFReleaseResource( &(Vcb->VCBResource) );
1812 VcbAcquired = FALSE;
1813 // Check if the Vcb is already locked, or if the open file count
1814 // is greater than 1 (which implies that someone else also is
1815 // currently using the volume, or a file on the volume).
1816 IoAcquireVpbSpinLock( &SavedIrql );
1817
1818 if (!(Vcb->Vpb->Flags & VPB_LOCKED) &&
1819 (Vcb->VolumeLockPID == (ULONG)-1) &&
1820 (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE+1) &&
1821 (Vcb->Vpb->ReferenceCount == 2)) {
1822
1823 // Mark volume as locked
1824 if(PID == (ULONG)-1) {
1825 Vcb->Vpb->Flags |= VPB_LOCKED;
1826 }
1827 Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_LOCKED;
1828 Vcb->VolumeLockFileObject = IrpSp->FileObject;
1829 Vcb->VolumeLockPID = PID;
1830
1831 RC = STATUS_SUCCESS;
1832
1833 } else {
1834
1836 }
1837
1838 IoReleaseVpbSpinLock( SavedIrql );
1839
1840 if(!NT_SUCCESS(RC)) {
1842 }
1843
1844 // Complete the request if there haven't been any exceptions.
1845 Irp->IoStatus.Information = 0;
1846 Irp->IoStatus.Status = RC;
1847 return RC;
1848} // end UDFLockVolume()
1849
1850/*
1851 This routine performs the unlock volume operation. It is responsible for
1852 either completing of enqueuing the input Irp.
1853Arguments:
1854 Irp - Supplies the Irp to process
1855Return Value:
1856 NTSTATUS - The return status for the operation
1857*/
1860 IN PtrUDFIrpContext IrpContext,
1861 IN PIRP Irp,
1862 IN ULONG PID
1863 )
1864{
1866
1867 KIRQL SavedIrql;
1869
1870 PVCB Vcb;
1871 PtrUDFFCB Fcb;
1872 PtrUDFCCB Ccb;
1873
1874 UDFPrint(("UDFUnlockVolume: PID %x\n", PID));
1875
1876 // Decode the file object, the only type of opens we accept are
1877 // user volume opens.
1878 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
1879 if(!Ccb) {
1880 UDFPrintErr((" !Ccb\n"));
1881 Irp->IoStatus.Information = 0;
1882 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1884 }
1885 Fcb = Ccb->Fcb;
1886 Vcb = Fcb->Vcb;
1887
1888 // Check for volume open
1889 if(Vcb != (PVCB)Fcb || !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN)) {
1890 Irp->IoStatus.Information = 0;
1891 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1893 }
1894
1895 // Acquire exclusive access to the Vcb/Vpb.
1896 IoAcquireVpbSpinLock( &SavedIrql );
1897
1898 _SEH2_TRY {
1899
1900 // We won't check for a valid Vcb for this request. An unlock will always
1901 // succeed on a locked volume.
1902 if(Vcb->Vpb->Flags & VPB_LOCKED ||
1903 Vcb->VolumeLockPID == PID) {
1904 Vcb->Vpb->Flags &= ~VPB_LOCKED;
1905 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_LOCKED;
1906 Vcb->VolumeLockFileObject = NULL;
1907 Vcb->VolumeLockPID = -1;
1909 RC = STATUS_SUCCESS;
1910 } else {
1911 RC = STATUS_NOT_LOCKED;
1912 RC = STATUS_SUCCESS;
1914 }
1915
1916 } _SEH2_FINALLY {
1917 ;
1918 } _SEH2_END;
1919
1920 // Release all of our resources
1921 IoReleaseVpbSpinLock( SavedIrql );
1922
1923 // Complete the request if there haven't been any exceptions.
1924 Irp->IoStatus.Information = 0;
1925 Irp->IoStatus.Status = RC;
1926 return RC;
1927} // end UDFUnlockVolume()
1928
1929
1930/*
1931 This routine performs the dismount volume operation. It is responsible for
1932 either completing of enqueuing the input Irp. We only dismount a volume which
1933 has been locked. The intent here is that someone has locked the volume (they are the
1934 only remaining handle). We set the verify bit here and the user will close his handle.
1935 We will dismount a volume with no user's handles in the verify path.
1936Arguments:
1937 Irp - Supplies the Irp to process
1938Return Value:
1939 NTSTATUS - The return status for the operation
1940*/
1943 IN PtrUDFIrpContext IrpContext,
1944 IN PIRP Irp
1945 )
1946{
1947 NTSTATUS RC;
1948
1950
1951 PVCB Vcb;
1952 PtrUDFFCB Fcb;
1953 PtrUDFCCB Ccb;
1955 BOOLEAN VcbAcquired = FALSE;
1956
1957 UDFPrint(("\n ### UDFDismountVolume ###\n\n"));
1958
1959 // Decode the file object, the only type of opens we accept are
1960 // user volume opens.
1961 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
1962 if(!Ccb) {
1963 UDFPrintErr((" !Ccb\n"));
1964 Irp->IoStatus.Information = 0;
1965 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1967 }
1968 Fcb = Ccb->Fcb;
1969 Vcb = Fcb->Vcb;
1970
1971 // Check for volume open
1972 if(Vcb != (PVCB)Fcb || !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN)) {
1973 Irp->IoStatus.Information = 0;
1974 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1976 }
1977
1979
1980 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK))
1981 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
1982#ifdef UDF_DELAYED_CLOSE
1984#endif //UDF_DELAYED_CLOSE
1985
1986 // Acquire exclusive access to the Vcb.
1987 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE );
1988 VcbAcquired = TRUE;
1989
1990 _SEH2_TRY {
1991
1992 // Mark the volume as needs to be verified, but only do it if
1993 // the vcb is locked by this handle and the volume is currently mounted.
1994
1995 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
1996 // disable Eject Request Waiter if any
1997 UDFReleaseResource( &(Vcb->VCBResource) );
1998 VcbAcquired = FALSE;
1999
2001 RC = STATUS_SUCCESS;
2002 } else
2003 if(
2004 !(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED) ||
2005 (Vcb->VCBOpenCount > (UDF_RESIDUAL_REFERENCE+1))) {
2006
2007 RC = STATUS_NOT_LOCKED;
2008 } else
2009 if((Vcb->VolumeLockFileObject != IrpSp->FileObject)) {
2010
2012
2013 } else {
2014
2015 Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
2019 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
2020 Vcb->WriteSecurity = FALSE;
2021 // disable Eject Request Waiter if any
2022 UDFReleaseResource( &(Vcb->VCBResource) );
2023 VcbAcquired = FALSE;
2024
2026 RC = STATUS_SUCCESS;
2027 }
2028try_exit: NOTHING;
2029 } _SEH2_FINALLY {
2030 // Free memory
2031 if(Buf) MyFreePool__(Buf);
2032 // Release all of our resources
2033 if(VcbAcquired)
2034 UDFReleaseResource( &(Vcb->VCBResource) );
2035 } _SEH2_END;
2036
2037 if(!NT_SUCCESS(RC)) {
2039 }
2040
2041 // Complete the request if there haven't been any exceptions.
2042 Irp->IoStatus.Information = 0;
2043 Irp->IoStatus.Status = RC;
2044 return RC;
2045} // end UDFDismountVolume()
2046
2047/*
2048
2049 This routine returns the volume allocation bitmap.
2050
2051 Input = the STARTING_LCN_INPUT_BUFFER data structure is passed in
2052 through the input buffer.
2053 Output = the VOLUME_BITMAP_BUFFER data structure is returned through
2054 the output buffer.
2055
2056 We return as much as the user buffer allows starting the specified input
2057 LCN (trucated to a byte). If there is no input buffer, we start at zero.
2058
2059Arguments:
2060
2061 Irp - Supplies the Irp being processed.
2062
2063Return Value:
2064
2065 NTSTATUS - The return status for the operation.
2066
2067 */
2070 IN PtrUDFIrpContext IrpContext,
2071 IN PIRP Irp
2072 )
2073{
2074// NTSTATUS RC;
2075
2078
2079 PVCB Vcb;
2080 PtrUDFFCB Fcb;
2081 PtrUDFCCB Ccb;
2082
2083 UDFPrint(("UDFGetVolumeBitmap\n"));
2084
2086 ULONG TotalClusters;
2087 ULONG DesiredClusters;
2088 ULONG StartingCluster;
2091 LARGE_INTEGER StartingLcn;
2093 ULONG i, lim;
2094 PULONG FSBM;
2095// PULONG Dest;
2096 ULONG LSh;
2097
2098 // Decode the file object, the only type of opens we accept are
2099 // user volume opens.
2100 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
2101 if(!Ccb) {
2102 UDFPrintErr((" !Ccb\n"));
2103 Irp->IoStatus.Information = 0;
2104 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2106 }
2107 Fcb = Ccb->Fcb;
2108 Vcb = Fcb->Vcb;
2109
2112
2114 if(!OutputBuffer)
2116
2117 // Check for a minimum length on the input and output buffers.
2120
2122 Irp->IoStatus.Information = 0;
2123 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
2125 }
2126
2127 // Check if a starting cluster was specified.
2128 TotalClusters = Vcb->FSBM_BitCount;
2129 StartingLcn = ((PSTARTING_LCN_INPUT_BUFFER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer)->StartingLcn;
2130
2131 if (StartingLcn.HighPart || StartingLcn.LowPart >= TotalClusters) {
2132
2134 Irp->IoStatus.Information = 0;
2135 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2137
2138 } else {
2139
2140 StartingCluster = StartingLcn.LowPart & ~7;
2141 }
2142
2144 DesiredClusters = TotalClusters - StartingCluster;
2145
2146 if (OutputBufferLength < (DesiredClusters + 7) / 8) {
2147
2149// RC = STATUS_BUFFER_OVERFLOW;
2150
2151 } else {
2152
2153 BytesToCopy = (DesiredClusters + 7) / 8;
2154// RC = STATUS_SUCCESS;
2155 }
2156
2157 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE );
2158
2159 _SEH2_TRY {
2160
2161 // Fill in the fixed part of the output buffer
2162 OutputBuffer->StartingLcn.QuadPart = StartingCluster;
2163 OutputBuffer->BitmapSize.QuadPart = DesiredClusters;
2164
2165 RtlZeroMemory( &OutputBuffer->Buffer[0], BytesToCopy );
2166 lim = BytesToCopy * 8;
2167 FSBM = (PULONG)(Vcb->FSBM_Bitmap);
2168 LSh = Vcb->LB2B_Bits;
2169// Dest = (PULONG)(&OutputBuffer->Buffer[0]);
2170
2171 for(i=StartingCluster & ~7; i<lim; i++) {
2172 if(UDFGetFreeBit(FSBM, i<<LSh))
2173 UDFSetFreeBit(FSBM, i);
2174 }
2175
2177
2178 BrutePoint();
2179 UDFPrintErr(("UDFGetVolumeBitmap: Exception\n"));
2180// UDFUnlockCallersBuffer(IrpContext, Irp, OutputBuffer);
2181 BrutePoint();
2182// RC = UDFExceptionHandler(IrpContext, Irp);
2183 UDFReleaseResource(&(Vcb->VCBResource));
2185
2186 Irp->IoStatus.Information = 0;
2187 Irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER;
2189 } _SEH2_END;
2190
2191 UDFReleaseResource(&(Vcb->VCBResource));
2192
2194 Irp->IoStatus.Information = FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer) +
2196 Irp->IoStatus.Status = STATUS_SUCCESS;
2197
2198 return STATUS_SUCCESS;
2199
2200
2201} // end UDFGetVolumeBitmap()
2202
2203
2206 IN PtrUDFIrpContext IrpContext,
2207 IN PIRP Irp,
2208 IN ULONG Special
2209 )
2210{
2211 NTSTATUS RC;
2212
2215
2216 PVCB Vcb;
2217 PtrUDFFCB Fcb;
2218 PtrUDFCCB Ccb;
2220
2223
2226
2227 LARGE_INTEGER StartingVcn;
2229
2230 PEXTENT_MAP SubMapping = NULL;
2231 ULONG SubExtInfoSz;
2232 ULONG i;
2233 ULONG LBS;
2234 ULONG LBSh;
2235 ULONG L2BSh;
2236
2237 UDFPrint(("UDFGetRetrievalPointers\n"));
2238
2239 // Decode the file object, the only type of opens we accept are
2240 // user volume opens.
2241 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
2242 if(!Ccb) {
2243 UDFPrintErr((" !Ccb\n"));
2244 Irp->IoStatus.Information = 0;
2245 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2247 }
2248 Fcb = Ccb->Fcb;
2249 Vcb = Fcb->Vcb;
2250
2251 // Get the input and output buffer lengths and pointers.
2252 // Initialize some variables.
2255
2256 //OutputBuffer = (PRETRIEVAL_POINTERS_BUFFER)UDFGetCallersBuffer( IrpContext, Irp );
2257 if(Special) {
2258 OutputBuffer = (PRETRIEVAL_POINTERS_BUFFER)Irp->AssociatedIrp.SystemBuffer;
2259 } else {
2261 }
2263 if(!InputBuffer) {
2265 }
2266
2267 _SEH2_TRY {
2268
2269 Irp->IoStatus.Information = 0;
2270 // Check for a minimum length on the input and ouput buffers.
2273
2275 }
2276
2277 _SEH2_TRY {
2278
2279 if (Irp->RequestorMode != KernelMode) {
2282 sizeof(UCHAR) );
2284 }
2285 StartingVcn = InputBuffer->StartingVcn;
2286
2288
2290 RC = FsRtlIsNtstatusExpected(RC) ?
2292 try_return(RC);
2293 } _SEH2_END;
2294
2295 switch(Special) {
2296 case 0:
2297 FileInfo = Fcb->FileInfo;
2298 break;
2299 case 1:
2300 FileInfo = Vcb->NonAllocFileInfo;
2301 break;
2302 default:
2304 }
2305
2306 if(!FileInfo) {
2308 }
2309
2311
2312 LBS = Vcb->LBlockSize;
2313 LBSh = Vcb->LBlockSizeBits;
2314 L2BSh = Vcb->LB2B_Bits;
2315
2316 if (StartingVcn.HighPart ||
2317 StartingVcn.LowPart >= (ULONG)(AllocationSize >> LBSh)) {
2318
2320 }
2321
2322 SubExtInfoSz = (OutputBufferLength - FIELD_OFFSET(RETRIEVAL_POINTERS_BUFFER, Extents[0])) / (sizeof(LARGE_INTEGER)*2);
2323 // re-use AllocationSize as NextVcn
2324 RC = UDFReadFileLocation__(Vcb, FileInfo, StartingVcn.QuadPart << LBSh,
2325 &SubMapping, &SubExtInfoSz, &AllocationSize);
2326 if(!NT_SUCCESS(RC))
2327 try_return(RC);
2328
2329 OutputBuffer->ExtentCount = SubExtInfoSz;
2330 OutputBuffer->StartingVcn = StartingVcn;
2331 for(i=0; i<SubExtInfoSz; i++) {
2332 // assume, that
2333 // for not-allocated extents we have start Lba = -1
2334 // for not-recorded extents start Lba.LowPart contains real Lba, Lba.HighPart = 0x80000000
2335 // for recorded extents Lba.LowPart contains real Lba, Lba.HighPart = 0
2336 if(SubMapping[i].extLocation == LBA_NOT_ALLOCATED) {
2337 OutputBuffer->Extents[i].Lcn.QuadPart = (int64)(-1);
2338 } else
2339 if(SubMapping[i].extLocation & 0x80000000) {
2340 OutputBuffer->Extents[i].Lcn.LowPart = (SubMapping[i].extLocation & 0x7fffffff) >> L2BSh;
2341 OutputBuffer->Extents[i].Lcn.HighPart = 0x80000000;
2342 } else {
2343 OutputBuffer->Extents[i].Lcn.LowPart = SubMapping[i].extLocation >> L2BSh;
2344 OutputBuffer->Extents[i].Lcn.HighPart = 0;
2345 }
2346 // alignment for last sector
2347 SubMapping[i].extLength += LBS-1;
2348 StartingVcn.QuadPart += SubMapping[i].extLength >> LBSh;
2349 OutputBuffer->Extents[i].NextVcn = StartingVcn;
2350 }
2351
2352 Irp->IoStatus.Information = FIELD_OFFSET(RETRIEVAL_POINTERS_BUFFER, Extents[0]) + i * sizeof(LARGE_INTEGER) * 2;
2353
2354try_exit: NOTHING;
2355 } _SEH2_FINALLY {
2356
2357 if(SubMapping)
2358 MyFreePool__(SubMapping);
2359 Irp->IoStatus.Status = RC;
2360 } _SEH2_END;
2361
2362 return RC;
2363} // end UDFGetRetrievalPointers()
2364
2365
2368 IN PtrUDFIrpContext IrpContext,
2369 IN PIRP Irp
2370 )
2371{
2375
2376 PVCB Vcb;
2377 PtrUDFFCB Fcb;
2378 PtrUDFCCB Ccb;
2379
2380 UDFPrint(("UDFIsVolumeDirty\n"));
2381
2382 Irp->IoStatus.Information = 0;
2383
2384 if (Irp->AssociatedIrp.SystemBuffer != NULL) {
2385 VolumeState = (PULONG)(Irp->AssociatedIrp.SystemBuffer);
2386 } else if (Irp->MdlAddress != NULL) {
2388 } else {
2389 UDFPrintErr((" STATUS_INVALID_USER_BUFFER\n"));
2390 Irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER;
2392 }
2393
2394 if (IrpSp->Parameters.FileSystemControl.OutputBufferLength < sizeof(ULONG)) {
2395 UDFPrintErr((" STATUS_BUFFER_TOO_SMALL\n"));
2396 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
2398 }
2399
2400 (*VolumeState) = 0;
2401
2402 // Decode the file object, the only type of opens we accept are
2403 // user volume opens.
2404 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
2405 if(!Ccb) {
2406 UDFPrintErr((" !Ccb\n"));
2407 Irp->IoStatus.Information = 0;
2408 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2410 }
2411 Fcb = Ccb->Fcb;
2412 Vcb = Fcb->Vcb;
2413
2414 if(Vcb != (PVCB)Fcb || !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN)) {
2415 UDFPrintErr((" !Volume\n"));
2416 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2418 }
2419
2420 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
2421 UDFPrintErr((" !Mounted\n"));
2422 Irp->IoStatus.Status = STATUS_VOLUME_DISMOUNTED;
2424 }
2425
2426 if(Vcb->origIntegrityType == INTEGRITY_TYPE_OPEN) {
2427 UDFPrint((" Dirty\n"));
2428 (*VolumeState) |= VOLUME_IS_DIRTY;
2429 Irp->IoStatus.Information = sizeof(ULONG);
2430 } else {
2431 UDFPrint((" Clean\n"));
2432 }
2433 Irp->IoStatus.Status = STATUS_SUCCESS;
2434
2435 return STATUS_SUCCESS;
2436
2437} // end UDFIsVolumeDirty()
2438
2439
2442 IN PtrUDFIrpContext IrpContext,
2443 IN PIRP Irp
2444 )
2445{
2446 NTSTATUS RC;
2450
2451 UDFPrint(("UDFInvalidateVolumes\n"));
2452
2453 KIRQL SavedIrql;
2454
2455 LUID TcbPrivilege = {SE_TCB_PRIVILEGE, 0};
2456
2457 HANDLE Handle;
2458
2459 PVPB NewVpb;
2460 PVCB Vcb;
2461
2463
2464 PFILE_OBJECT FileToMarkBad;
2465 PDEVICE_OBJECT DeviceToMarkBad;
2466
2467 Irp->IoStatus.Information = 0;
2468
2469 // Check for the correct security access.
2470 // The caller must have the SeTcbPrivilege.
2474 !SeSinglePrivilegeCheck( TcbPrivilege, UserMode )) {
2475 UDFPrintErr(("UDFInvalidateVolumes: STATUS_PRIVILEGE_NOT_HELD\n"));
2476 Irp->IoStatus.Status = STATUS_PRIVILEGE_NOT_HELD;
2478 }
2479 // Try to get a pointer to the device object from the handle passed in.
2480 if (IrpSp->Parameters.FileSystemControl.InputBufferLength != sizeof( HANDLE )) {
2481 UDFPrintErr(("UDFInvalidateVolumes: STATUS_INVALID_PARAMETER\n"));
2482 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2484 }
2485
2486 Handle = *((PHANDLE) Irp->AssociatedIrp.SystemBuffer);
2487
2489 0,
2491 KernelMode,
2492 (PVOID*)&FileToMarkBad,
2493 NULL );
2494
2495 if (!NT_SUCCESS(RC)) {
2496 UDFPrintErr(("UDFInvalidateVolumes: can't get handle, RC=%x\n", RC));
2497 Irp->IoStatus.Status = RC;
2498 return RC;
2499 }
2500
2501 // We only needed the pointer, not a reference.
2502 ObDereferenceObject( FileToMarkBad );
2503
2504 // Grab the DeviceObject from the FileObject.
2505 DeviceToMarkBad = FileToMarkBad->DeviceObject;
2506
2507 // Create a new Vpb for this device so that any new opens will mount
2508 // a new volume.
2509 NewVpb = (PVPB)DbgAllocatePoolWithTag( NonPagedPool, sizeof( VPB ), 'bpvU' );
2510 if(!NewVpb) {
2511 UDFPrintErr(("UDFInvalidateVolumes: STATUS_INSUFFICIENT_RESOURCES\n"));
2512 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2514 }
2515 RtlZeroMemory( NewVpb, sizeof( VPB ) );
2516
2517 NewVpb->Type = IO_TYPE_VPB;
2518 NewVpb->Size = sizeof( VPB );
2519 NewVpb->RealDevice = DeviceToMarkBad;
2520 NewVpb->Flags = DeviceToMarkBad->Vpb->Flags & VPB_REMOVE_PENDING;
2521
2522 // Acquire GlobalDataResource
2523 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
2524
2525 // Nothing can go wrong now.
2526 IoAcquireVpbSpinLock( &SavedIrql );
2527 if (DeviceToMarkBad->Vpb->Flags & VPB_MOUNTED) {
2528 DeviceToMarkBad->Vpb = NewVpb;
2529 NewVpb = NULL;
2530 }
2531 ASSERT( DeviceToMarkBad->Vpb->DeviceObject == NULL );
2532 IoReleaseVpbSpinLock( SavedIrql );
2533
2534 if (NewVpb) {
2535 DbgFreePool( NewVpb );
2536 }
2537
2538 // Walk through all of the Vcb's attached to the global data.
2539 Link = UDFGlobalData.VCBQueue.Flink;
2540
2541 //ASSERT(FALSE);
2542
2543 while (Link != &(UDFGlobalData.VCBQueue)) {
2544 // Get 'next' Vcb
2545 Vcb = CONTAINING_RECORD( Link, VCB, NextVCB );
2546 // Move to the next link now since the current Vcb may be deleted.
2547 Link = Link->Flink;
2548
2549 // Acquire Vcb resource
2550 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
2551
2552 if (Vcb->Vpb->RealDevice == DeviceToMarkBad) {
2553
2554 if(!Buf) {
2556 if(!Buf) {
2557 UDFPrintErr(("UDFInvalidateVolumes: STATUS_INSUFFICIENT_RESOURCES (2)\n"));
2558 UDFReleaseResource(&(Vcb->VCBResource));
2559 MyFreePool__(NewVpb);
2560 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2562 }
2563 }
2564
2565#ifdef UDF_DELAYED_CLOSE
2566 UDFPrint((" UDFInvalidateVolumes: set UDF_VCB_FLAGS_NO_DELAYED_CLOSE\n"));
2568 UDFReleaseResource(&(Vcb->VCBResource));
2569#endif //UDF_DELAYED_CLOSE
2570
2571 if(Vcb->RootDirFCB && Vcb->RootDirFCB->FileInfo) {
2572 UDFPrint((" UDFInvalidateVolumes: UDFCloseAllSystemDelayedInDir\n"));
2573 RC = UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
2574 ASSERT(OS_SUCCESS(RC));
2575 }
2576#ifdef UDF_DELAYED_CLOSE
2577 UDFPrint((" UDFInvalidateVolumes: UDFCloseAllDelayed\n"));
2579 //ASSERT(OS_SUCCESS(RC));
2580#endif //UDF_DELAYED_CLOSE
2581
2582 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
2583
2585 UDFReleaseResource(&(Vcb->VCBResource));
2586
2588 UDFPrint(("UDFInvalidateVolumes: Vcb %x dismounted\n", Vcb));
2589 break;
2590 } else {
2591 UDFPrint(("UDFInvalidateVolumes: skip Vcb %x\n", Vcb));
2592 UDFReleaseResource(&(Vcb->VCBResource));
2593 }
2594
2595 }
2596 // Once we have processed all the mounted logical volumes, we can release
2597 // all acquired global resources and leave (in peace :-)
2598 UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
2599
2600 Irp->IoStatus.Status = STATUS_SUCCESS;
2601
2602 if(Buf) {
2603 UDFPrint(("UDFInvalidateVolumes: free buffer\n"));
2604 MyFreePool__(Buf);
2605 }
2606
2607 // drop volume completly
2608 UDFPrint(("UDFInvalidateVolumes: drop volume completly\n"));
2609 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
2610 UDFScanForDismountedVcb(IrpContext);
2611 UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
2612
2613 UDFPrint(("UDFInvalidateVolumes: done\n"));
2614 return STATUS_SUCCESS;
2615
2616} // end UDFInvalidateVolumes()
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
unsigned char BOOLEAN
VOID UDFGetFileXTime(IN PUDF_FILE_INFO FileInfo, OUT LONGLONG *CrtTime, OUT LONGLONG *AccTime, OUT LONGLONG *AttrTime, OUT LONGLONG *ChgTime)
int64 __fastcall UDFGetTotalSpace(IN PVCB Vcb)
Definition: alloc.cpp:1138
int64 __fastcall UDFGetFreeSpace(IN PVCB Vcb)
Definition: alloc.cpp:1105
uint32 UDFIsBlockAllocated(IN void *_Vcb, IN uint32 Lba)
Definition: alloc.cpp:1164
LONG NTSTATUS
Definition: precomp.h:26
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define try_return(S)
Definition: cdprocs.h:2179
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
struct _PREVENT_MEDIA_REMOVAL_USER_IN * PPREVENT_MEDIA_REMOVAL_USER_IN
#define CdrwMediaClassEx_IsRAM(MediaClassEx)
Definition: cdrw_usr.h:799
#define IOCTL_CDRW_TEST_UNIT_READY
Definition: cdrw_usr.h:101
struct _VCB * PVCB
Definition: fatstruc.h:557
Definition: bufpool.h:45
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
ULONG UDFCleanUpFcbChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: close.cpp:400
_In_ PIRP Irp
Definition: csq.h:116
OSSTATUS UDFStoreDloc(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN uint32 Lba)
Definition: dirtree.cpp:1240
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
void UDFReleaseDlocList(IN PVCB Vcb)
Definition: dirtree.cpp:1396
uint8 UDFBuildHashEntry(IN PVCB Vcb, IN PUNICODE_STRING Name, OUT PHASH_ENTRY hashes, IN uint8 Mask)
Definition: dirtree.cpp:429
#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:33
#define DEVICE_TYPE
Definition: guid.c:10
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
return Iosb
Definition: create.c:4402
char int8
Definition: platform.h:10
long long int64
Definition: platform.h:13
NTSTATUS UDFInitializeFCB(IN PtrUDFFCB PtrNewFcb, IN PVCB Vcb, IN PtrUDFObjectName PtrObjectName, IN ULONG Flags, IN PFILE_OBJECT FileObject)
Definition: create.cpp:2517
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
VOID UDFReadRegKeys(PVCB Vcb, BOOLEAN Update, BOOLEAN UseCfg)
Definition: misc.cpp:1780
VOID __fastcall UDFCleanUpFCB(PtrUDFFCB Fcb)
Definition: misc.cpp:908
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
ULONG UDFGetRegParameter(IN PVCB Vcb, IN PCWSTR Name, IN ULONG DefValue)
Definition: misc.cpp:1986
VOID __fastcall UDFReleaseObjectName(PtrUDFObjectName PtrObjectName)
Definition: misc.cpp:670
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
PtrUDFObjectName UDFAllocateObjectName(VOID)
Definition: misc.cpp:611
PtrUDFFCB UDFAllocateFCB(VOID)
Definition: misc.cpp:854
NTSTATUS UDFInitializeVCB(IN PDEVICE_OBJECT PtrVolumeDeviceObject, IN PDEVICE_OBJECT PtrTargetDeviceObject, IN PVPB PtrVPB)
Definition: misc.cpp:1411
VOID CompleteIrp(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: pnp.c:12
#define INTEGRITY_TYPE_OPEN
Definition: ecma_167.h:357
#define FILE_DIRECTORY
Definition: ecma_167.h:439
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 UDFNotifyVolumeEvent(FileObject, EventCode)
Definition: env_spec.h:114
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define UserPrint(x)
Definition: env_spec_w32.h:202
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define OS_SUCCESS(a)
Definition: env_spec_w32.h:56
#define DbgAllocatePoolWithTag(a, b, c)
Definition: env_spec_w32.h:333
NTSTATUS MyInitUnicodeString(IN PUNICODE_STRING Str1, IN PCWSTR Str2)
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define DbgFreePool
Definition: env_spec_w32.h:334
#define UDFInterlockedDecrement(addr)
Definition: env_spec_w32.h:677
#define NonPagedPool
Definition: env_spec_w32.h:307
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define BrutePoint()
Definition: env_spec_w32.h:504
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define NtReqFcb
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1675
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1676
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:323
IN PVCB IN FAT_VOLUME_STATE VolumeState
Definition: fatprocs.h:1999
FILE_SYSTEM_STATISTICS * PFILE_SYSTEM_STATISTICS
Definition: fatstruc.h:612
struct _FILE_SYSTEM_STATISTICS FILE_SYSTEM_STATISTICS
static unsigned char buff[32768]
Definition: fatten.c:17
VOID UDFReleaseFileIdCache(IN PVCB Vcb)
Definition: fileinfo.cpp:2456
ULONG UDFFlushLogicalVolume(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PVCB Vcb, IN ULONG FlushFlags)
Definition: flush.cpp:506
NTSTATUS UDFBlankMount(IN PVCB Vcb)
Definition: fscntrl.cpp:1212
NTSTATUS UDFIsPathnameValid(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:1660
NTSTATUS NTAPI UDFFSControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: fscntrl.cpp:39
NTSTATUS UDFUnlockVolume(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN ULONG PID)
Definition: fscntrl.cpp:1859
#define DWN_MAX_CFG_FILE_SIZE
NTSTATUS NTAPI UDFCommonFSControl(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: fscntrl.cpp:103
NTSTATUS UDFGetStatistics(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:1601
NTSTATUS UDFLockVolume(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN ULONG PID)
Definition: fscntrl.cpp:1724
NTSTATUS UDFIsVolumeMounted(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:1552
NTSTATUS NTAPI UDFUserFsCtrlRequest(PtrUDFIrpContext IrpContext, PIRP Irp)
Definition: fscntrl.cpp:178
VOID UDFScanForDismountedVcb(IN PtrUDFIrpContext IrpContext)
Definition: fscntrl.cpp:1510
NTSTATUS NTAPI UDFMountVolume(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:315
NTSTATUS UDFGetRetrievalPointers(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN ULONG Special)
Definition: fscntrl.cpp:2205
NTSTATUS UDFCompleteMount(IN PVCB Vcb)
Definition: fscntrl.cpp:913
NTSTATUS UDFIsVolumeDirty(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:2367
NTSTATUS UDFStartEjectWaiter(IN PVCB Vcb)
Definition: fscntrl.cpp:850
NTSTATUS UDFDismountVolume(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:1942
PDIR_INDEX_HDR UDFDirIndexAlloc(IN uint_di i)
Definition: dirtree.cpp:43
NTSTATUS UDFInvalidateVolumes(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:2441
VOID UDFCleanupVCB(IN PVCB Vcb)
Definition: fscntrl.cpp:1428
NTSTATUS UDFGetVolumeBitmap(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:2069
VOID UDFCloseResidual(IN PVCB Vcb)
Definition: fscntrl.cpp:1349
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
@ FastIoIsNotPossible
Definition: fsrtltypes.h:240
@ FastIoIsPossible
Definition: fsrtltypes.h:241
ULONG Handle
Definition: gdb_input.c:15
GLenum GLsizei len
Definition: glext.h:6722
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 EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define NOTHING
Definition: input_list.c:10
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
if(dx< 0)
Definition: linetemp.h:194
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define MyFreeMemoryAndPointer(ptr)
Definition: mem_tools.h:13
#define MyFreePool__(addr)
Definition: mem_tools.h:152
VOID UDFPreClrModified(IN PVCB Vcb)
Definition: misc_common.cpp:18
VOID UDFClrModified(IN PVCB Vcb)
Definition: misc_common.cpp:26
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define SE_TCB_PRIVILEGE
Definition: security.c:661
OSSTATUS UDFGetDiskInfoAndVerify(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: mount.cpp:2983
BOOLEAN __fastcall UDFIsNameValid(IN PUNICODE_STRING SearchPattern, OUT BOOLEAN *StreamOpen, OUT ULONG *SNameIndex)
Definition: namesup.cpp:92
PWCHAR __fastcall UDFDissectName(IN PWCHAR Buffer, OUT PUSHORT Length)
Definition: namesup.cpp:19
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
#define FSCTL_OPLOCK_BREAK_NOTIFY
Definition: nt_native.h:831
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FSCTL_OPLOCK_BREAK_ACKNOWLEDGE
Definition: nt_native.h:829
#define FSCTL_REQUEST_OPLOCK_LEVEL_1
Definition: nt_native.h:826
#define FSCTL_REQUEST_FILTER_OPLOCK
Definition: nt_native.h:849
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FSCTL_INVALIDATE_VOLUMES
Definition: nt_native.h:847
#define FSCTL_IS_PATHNAME_VALID
Definition: nt_native.h:837
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FSCTL_REQUEST_BATCH_OPLOCK
Definition: nt_native.h:828
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
#define FSCTL_FILESYSTEM_GET_STATISTICS
Definition: nt_native.h:850
#define FSCTL_OPBATCH_ACK_CLOSE_PENDING
Definition: nt_native.h:830
#define FSCTL_OPLOCK_BREAK_ACK_NO_2
Definition: nt_native.h:846
#define FSCTL_IS_VOLUME_MOUNTED
Definition: nt_native.h:836
#define FSCTL_REQUEST_OPLOCK_LEVEL_2
Definition: nt_native.h:827
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:73
@ RemovableMedia
Definition: ntdddisk.h:382
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:98
#define IOCTL_STORAGE_MEDIA_REMOVAL
Definition: ntddstor.h:104
@ NotificationEvent
#define FSRTL_VOLUME_UNLOCK
Definition: ntifs_ex.h:443
#define FSRTL_VOLUME_LOCK
Definition: ntifs_ex.h:441
#define FSRTL_VOLUME_DISMOUNT_FAILED
Definition: ntifs_ex.h:440
#define FSRTL_VOLUME_DISMOUNT
Definition: ntifs_ex.h:439
#define VOLUME_IS_DIRTY
Definition: ntifs_ex.h:330
#define FSRTL_VOLUME_MOUNT
Definition: ntifs_ex.h:444
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
#define FSRTL_VOLUME_LOCK_FAILED
Definition: ntifs_ex.h:442
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1694
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
VOID NTAPI IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1725
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:747
#define STATUS_NOT_LOCKED
Definition: ntstatus.h:279
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define UDF_FN_NON_ALLOCATABLE_2
Definition: osta_misc.h:322
#define UDF_FN_NON_ALLOCATABLE
Definition: osta_misc.h:321
#define UDF_SN_UID_MAPPING
Definition: osta_misc.h:330
#define UDF_SN_NON_ALLOCATABLE
Definition: osta_misc.h:331
#define UDF_NAME_LEN
Definition: osta_misc.h:314
unsigned short USHORT
Definition: pedump.c:61
#define Vcb
Definition: cdprocs.h:1415
OSSTATUS UDFGetDiskInfo(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: phys_lib.cpp:3050
OSSTATUS UDFResetDeviceDriver(IN PVCB Vcb, IN PDEVICE_OBJECT TargetDeviceObject, IN BOOLEAN Unlock)
Definition: phys_lib.cpp:4199
VOID NTAPI UDFEjectReqWaiter(IN PVOID Context)
OSSTATUS UDFDoDismountSequence(IN PVCB Vcb, IN PPREVENT_MEDIA_REMOVAL_USER_IN Buf, IN BOOLEAN Eject)
Definition: phys_eject.cpp:704
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)
NTSTATUS UDFVerifyVcb(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb)
Definition: verfysup.cpp:37
PVOID UDFGetCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:871
BOOLEAN UDFDismountVcb(IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:727
NTSTATUS UDFUnlockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVOID SystemBuffer)
Definition: read.cpp:1034
NTSTATUS UDFVerifyVolume(IN PIRP Irp)
Definition: verfysup.cpp:158
NTSTATUS UDFAssignAcl(IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb, IN PtrUDFNTRequiredFCB NtReqFcb)
Definition: secursup.cpp:706
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:629
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:53
struct STARTING_LCN_INPUT_BUFFER * PSTARTING_LCN_INPUT_BUFFER
struct VOLUME_BITMAP_BUFFER * PVOLUME_BITMAP_BUFFER
struct STARTING_VCN_INPUT_BUFFER * PSTARTING_VCN_INPUT_BUFFER
#define FSCTL_IS_VOLUME_DIRTY
Definition: winioctl.h:755
struct RETRIEVAL_POINTERS_BUFFER * PRETRIEVAL_POINTERS_BUFFER
#define FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:744
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:47
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:48
#define FSCTL_GET_VOLUME_BITMAP
Definition: winioctl.h:743
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:166
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define FSCTL_ALLOW_EXTENDED_DASD_IO
Definition: winioctl.h:124
OSSTATUS UDFVInit(IN PVCB Vcb)
Definition: remap.cpp:54
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define UDF_NODE_TYPE_FILTER_DEVOBJ
Definition: struct.h:64
struct _UDFFileControlBlock UDFFCB
struct _FILTER_DEV_EXTENSION * PFILTER_DEV_EXTENSION
#define UDF_CCB_VOLUME_OPEN
Definition: struct.h:166
struct _UDFEjectWaitContext * PUDFEjectWaitContext
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_FCB_ROOT_DIRECTORY
Definition: struct.h:304
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
#define UDF_IRP_CONTEXT_FLAG_DISABLE_POPUPS
Definition: struct.h:391
#define UDF_NODE_TYPE_UDFFS_DEVOBJ
Definition: struct.h:65
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
PVOID DeviceExtension
Definition: env_spec_w32.h:418
UNICODE_STRING FName
Definition: udf_rel.h:173
struct _UDF_FILE_INFO * FileInfo
Definition: udf_rel.h:204
uint8 FI_Flags
Definition: udf_rel.h:199
uint32 SysAttr
Definition: udf_rel.h:208
uint8 FileCharacteristics
Definition: udf_rel.h:182
HASH_ENTRY hashes
Definition: udf_rel.h:206
uint32 extLength
Definition: ecma_167.h:128
uint32 extLocation
Definition: ecma_167.h:129
PVCB Vcb
Definition: cdstruc.h:933
struct _FCB::@731::@734 Fcb
PDEVICE_OBJECT lowerFSDeviceObject
Definition: struct.h:350
UDFIdentifier NodeIdentifier
Definition: struct.h:348
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
union _IO_STACK_LOCATION::@1581 Parameters
struct _IO_STACK_LOCATION::@3980::@3995 FileSystemControl
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
struct _IO_STACK_LOCATION::@3980::@4000 MountVolume
Definition: typedefs.h:120
ULONG PathNameLength
Definition: iotypes.h:6229
WCHAR Name[1]
Definition: iotypes.h:6230
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_usr.h:681
uint32 UDFFlags
Definition: udf_common.h:627
PtrUDFNTRequiredFCB NTRequiredFCB
Definition: struct.h:255
uint32 OpenHandleCount
Definition: struct.h:282
uint32 ReferenceCount
Definition: struct.h:281
UDFIdentifier NodeIdentifier
Definition: struct.h:252
PUDF_FILE_INFO FileInfo
Definition: struct.h:257
uint32 NodeType
Definition: struct.h:75
uint32 NodeSize
Definition: struct.h:76
LARGE_INTEGER CreationTime
Definition: struct.h:210
LARGE_INTEGER LastWriteTime
Definition: struct.h:212
ULONG CommonRefCount
Definition: struct.h:218
LARGE_INTEGER LastAccessTime
Definition: struct.h:211
LARGE_INTEGER ChangeTime
Definition: struct.h:213
UNICODE_STRING ObjectName
Definition: struct.h:94
struct _UDFNTRequiredFCB * CommonFcb
Definition: udf_rel.h:255
uint32 LinkRefCount
Definition: udf_rel.h:306
PDIR_INDEX_HDR DirIndex
Definition: udf_rel.h:312
struct _UDF_FILE_INFO * PrevLinkedFile
Definition: udf_rel.h:409
PUDF_DATALOC_INFO Dloc
Definition: udf_rel.h:367
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
uint32 RefCount
Definition: udf_rel.h:399
struct _UDF_FILE_INFO * NextLinkedFile
Definition: udf_rel.h:408
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cdstruc.h:498
Definition: iotypes.h:189
CSHORT Type
Definition: iotypes.h:190
CSHORT Size
Definition: iotypes.h:191
USHORT Flags
Definition: iotypes.h:192
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:195
Definition: ps.c:97
#define max(a, b)
Definition: svc.c:63
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
union _LARGE_INTEGER LARGE_INTEGER
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char CCHAR
Definition: typedefs.h:51
#define UDF_VCB_FLAGS_STOP_WAITER_EVENT
Definition: udf_common.h:479
#define UDF_VCB_FLAGS_NO_DELAYED_CLOSE
Definition: udf_common.h:480
#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_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_OUR_DEVICE_DRIVER
Definition: udf_common.h:466
#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
int64 UDFGetFileSize(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1236
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
OSSTATUS UDFOpenFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN BOOLEAN NotDeleted, IN PUNICODE_STRING fn, IN PUDF_FILE_INFO DirInfo, OUT PUDF_FILE_INFO *_FileInfo, IN uint_di *IndexToOpen)
Definition: udf_info.cpp:2004
#define HASH_KEEP_NAME
Definition: udf_info.h:79
#define UDFGetFileAllocationSize(Vcb, FileInfo)
Definition: udf_info.h:797
#define AS_USED
Definition: udf_info.h:327
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
#define UDFNtAclSupported(Vcb)
Definition: udf_info.h:1040
#define UDFSetFreeBit(arr, bit)
Definition: udf_info.h:1201
__inline OSSTATUS UDFReadFileLocation__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, OUT PEXTENT_MAP *SubExtInfo, IN OUT uint32 *SubExtInfoSz, OUT int64 *NextOffset)
Definition: udf_info.h:683
#define UDFGetFreeBit(arr, bit)
Definition: udf_info.h:1199
__inline OSSTATUS UDFReadFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, OUT int8 *Buffer, OUT PSIZE_T ReadBytes)
Definition: udf_info.h:666
#define UDFMarkSpaceAsXXX(Vcb, FileInfo, Map, asXXX)
Definition: udf_info.h:322
#define HASH_ALL
Definition: udf_info.h:78
#define REG_MOUNT_ON_ZIP_NAME
Definition: udf_reg.h:248
#define REG_MOUNT_ON_HDD_NAME
Definition: udf_reg.h:245
#define REG_MOUNT_ON_CDONLY_NAME
Definition: udf_reg.h:242
#define UDF_WAIT_CD_SPINUP
Definition: udf_reg.h:227
#define UDF_ROOTDIR_NAME
Definition: udf_reg.h:48
#define UDF_BLANK_VOLUME_LABEL
Definition: udf_reg.h:93
#define LBA_NOT_ALLOCATED
Definition: udf_rel.h:427
#define UDF_READY_MAX_RETRY
Definition: udf_rel.h:504
uint32 uint_di
Definition: udf_rel.h:29
#define UDF_FI_FLAG_FI_INTERNAL
Given entry represents the file used for internal FS purposes & must be invisible.
Definition: udf_rel.h:221
#define EXTENT_FLAG_VERIFY
Definition: udf_rel.h:81
#define UDF_FI_FLAG_SYS_ATTR
Given entry of file list contains valid file attributes & times in NT-specific format.
Definition: udf_rel.h:219
#define VRS_ISO9660_FOUND
Definition: udf_rel.h:114
struct _UDF_FILE_INFO * PUDF_FILE_INFO
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_CRC_ERROR
Definition: udferr_usr.h:153
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define UDFQuadAlign(Value)
Definition: udffs.h:194
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define UDFPrintErr(Args)
Definition: udffs.h:227
#define UDFPrint(Args)
Definition: udffs.h:223
#define PEXTENDED_IO_STACK_LOCATION
Definition: udffs.h:119
#define UDF_CONFIG_STREAM_NAME_W
Definition: udfpubl.h:82
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
static int Link(const char **args)
Definition: vfdcmd.c:2414
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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1699
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190
#define VPB_MOUNTED
Definition: iotypes.h:1807
struct _VPB * PVPB
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IO_TYPE_VPB
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4403
struct _VPB VPB
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define VPB_LOCKED
Definition: iotypes.h:1808
struct _PATHNAME_BUFFER * PPATHNAME_BUFFER
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404
#define MmGetSystemAddressForMdl(Mdl)
#define ObDereferenceObject
Definition: obfuncs.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180