1 /*
2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4 * FILE: shutdown.c
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
7 * UPDATE HISTORY:
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include "ext2fs.h"
13
14 /* GLOBALS ***************************************************************/
15
16 extern PEXT2_GLOBAL Ext2Global;
17
18 /* DEFINITIONS *************************************************************/
19
20 #ifdef ALLOC_PRAGMA
21 #pragma alloc_text(PAGE, Ext2ShutDown)
22 #endif
23
24 NTSTATUS
Ext2ShutDown(IN PEXT2_IRP_CONTEXT IrpContext)25 Ext2ShutDown (IN PEXT2_IRP_CONTEXT IrpContext)
26 {
27 NTSTATUS Status;
28
29 PIRP Irp;
30
31 PEXT2_VCB Vcb;
32 PLIST_ENTRY ListEntry;
33
34 BOOLEAN GlobalResourceAcquired = FALSE;
35
36 _SEH2_TRY {
37
38 Status = STATUS_SUCCESS;
39
40 ASSERT(IrpContext);
41 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
42 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
43
44 Irp = IrpContext->Irp;
45
46 if (!ExAcquireResourceExclusiveLite(
47 &Ext2Global->Resource,
48 IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
49 Status = STATUS_PENDING;
50 _SEH2_LEAVE;
51 }
52
53 GlobalResourceAcquired = TRUE;
54
55 for (ListEntry = Ext2Global->VcbList.Flink;
56 ListEntry != &(Ext2Global->VcbList);
57 ListEntry = ListEntry->Flink ) {
58
59 Vcb = CONTAINING_RECORD(ListEntry, EXT2_VCB, Next);
60
61 if (ExAcquireResourceExclusiveLite(
62 &Vcb->MainResource,
63 TRUE )) {
64
65 if (IsMounted(Vcb)) {
66
67 /* update mount count */
68 Vcb->SuperBlock->s_mnt_count++;
69 if (Vcb->SuperBlock->s_mnt_count >
70 Vcb->SuperBlock->s_max_mnt_count ) {
71 Vcb->SuperBlock->s_mnt_count =
72 Vcb->SuperBlock->s_max_mnt_count;
73 }
74 Ext2SaveSuper(IrpContext, Vcb);
75
76 /* flush dirty cache for all files */
77 Status = Ext2FlushFiles(IrpContext, Vcb, TRUE);
78 if (!NT_SUCCESS(Status)) {
79 DbgBreak();
80 }
81
82 /* flush volume stream's cache to disk */
83 Status = Ext2FlushVolume(IrpContext, Vcb, TRUE);
84
85 if (!NT_SUCCESS(Status) && Status != STATUS_MEDIA_WRITE_PROTECTED) {
86 DbgBreak();
87 }
88
89 /* send shutdown request to underlying disk */
90 Ext2DiskShutDown(Vcb);
91 }
92
93 ExReleaseResourceLite(&Vcb->MainResource);
94 }
95 }
96
97 /*
98 IoUnregisterFileSystem(Ext2Global->DiskdevObject);
99 IoUnregisterFileSystem(Ext2Global->CdromdevObject);
100 */
101
102 } _SEH2_FINALLY {
103
104 if (GlobalResourceAcquired) {
105 ExReleaseResourceLite(&Ext2Global->Resource);
106 }
107
108 if (!IrpContext->ExceptionInProgress) {
109 if (Status == STATUS_PENDING) {
110 Ext2QueueRequest(IrpContext);
111 } else {
112 Ext2CompleteIrpContext(IrpContext, Status);
113 }
114 }
115 } _SEH2_END;
116
117 return Status;
118 }