1 /*++ 2 3 Copyright (c) 1997-2006 Microsoft Corporation 4 5 Module Name: 6 7 Shutdown.c 8 9 Abstract: 10 11 This module implements the shutdown routine for CDFS called by 12 the dispatch driver. 13 14 15 --*/ 16 17 #include "cdprocs.h" 18 19 // 20 // The Bug check file id for this module 21 // 22 23 #define BugCheckFileId (CDFS_BUG_CHECK_SHUTDOWN) 24 25 #ifdef ALLOC_PRAGMA 26 #pragma alloc_text(PAGE, CdCommonShutdown) 27 #endif 28 29 _Requires_lock_held_(_Global_critical_region_) 30 NTSTATUS 31 CdCommonShutdown ( 32 _Inout_ PIRP_CONTEXT IrpContext, 33 _Inout_ PIRP Irp 34 ) 35 36 /*++ 37 38 Routine Description: 39 40 This is the common routine for handling shutdown operation called 41 by both the fsd and fsp threads 42 43 Arguments: 44 45 Irp - Supplies the Irp to process 46 47 Return Value: 48 49 NTSTATUS - The return status for the operation 50 51 --*/ 52 53 { 54 KEVENT Event; 55 PLIST_ENTRY Links; 56 PVCB Vcb; 57 PIRP NewIrp; 58 IO_STATUS_BLOCK Iosb; 59 BOOLEAN VcbPresent; 60 NTSTATUS Status; 61 62 PAGED_CODE(); 63 64 // 65 // Make sure we don't get any pop-ups. 66 // 67 68 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS ); 69 70 // 71 // Initialize an event for doing calls down to 72 // our target device objects. 73 // 74 75 KeInitializeEvent( &Event, NotificationEvent, FALSE ); 76 77 // 78 // Indicate that shutdown has started. 79 // 80 81 SetFlag( CdData.Flags, CD_FLAGS_SHUTDOWN ); 82 83 // 84 // Get everyone else out of the way 85 // 86 87 CdAcquireCdData( IrpContext ); 88 89 // 90 // Now walk through all the mounted Vcb's and shutdown the target 91 // device objects. 92 // 93 94 Links = CdData.VcbQueue.Flink; 95 96 while (Links != &CdData.VcbQueue) { 97 98 Vcb = CONTAINING_RECORD( Links, VCB, VcbLinks ); 99 100 // 101 // Move to the next link now since the current Vcb may be deleted. 102 // 103 104 Links = Links->Flink; 105 106 // 107 // If we have already been called before for this volume 108 // (and yes this does happen), skip this volume as no writes 109 // have been allowed since the first shutdown. 110 // 111 112 if (FlagOn( Vcb->VcbState, VCB_STATE_SHUTDOWN ) || 113 (Vcb->VcbCondition != VcbMounted)) { 114 115 continue; 116 } 117 118 CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); 119 120 CdPurgeVolume( IrpContext, Vcb, FALSE ); 121 122 // 123 // Build an irp for this volume stack - our own irp is probably too small and 124 // each stack may have a different stack size. 125 // 126 127 NewIrp = IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN, 128 Vcb->TargetDeviceObject, 129 NULL, 130 0, 131 NULL, 132 &Event, 133 &Iosb ); 134 135 if (NewIrp != NULL) { 136 137 Status = IoCallDriver( Vcb->TargetDeviceObject, NewIrp ); 138 139 if (Status == STATUS_PENDING) { 140 141 (VOID)KeWaitForSingleObject( &Event, 142 Executive, 143 KernelMode, 144 FALSE, 145 NULL ); 146 } 147 148 KeClearEvent( &Event ); 149 } 150 151 SetFlag( Vcb->VcbState, VCB_STATE_SHUTDOWN ); 152 153 // 154 // Attempt to punch the volume down. 155 // 156 157 VcbPresent = CdCheckForDismount( IrpContext, Vcb, FALSE ); 158 159 if (VcbPresent) { 160 161 CdReleaseVcb( IrpContext, Vcb ); 162 } 163 } 164 165 166 CdReleaseCdData( IrpContext ); 167 168 IoUnregisterFileSystem( CdData.FileSystemDeviceObject ); 169 IoDeleteDevice( CdData.FileSystemDeviceObject ); 170 #ifdef __REACTOS__ 171 IoUnregisterFileSystem( CdData.HddFileSystemDeviceObject ); 172 IoDeleteDevice( CdData.HddFileSystemDeviceObject ); 173 #endif 174 175 CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 176 return STATUS_SUCCESS; 177 } 178 179 180