[FFS]
[reactos.git] / reactos / drivers / filesystems / ffs / src / except.c
1 /*
2 * FFS File System Driver for Windows
3 *
4 * except.c
5 *
6 * 2004.5.6 ~
7 *
8 * Lee Jae-Hong, http://www.pyrasis.com
9 *
10 * See License.txt
11 *
12 */
13
14 #include "ntifs.h"
15 #include "ffsdrv.h"
16
17 /* Globals */
18
19 extern PFFS_GLOBAL FFSGlobal;
20
21
22 /* Definitions */
23
24 #ifdef ALLOC_PRAGMA
25 //#pragma alloc_text(PAGE, FFSExceptionFilter)
26 //#pragma alloc_text(PAGE, FFSExceptionHandler)
27 #endif
28
29
30 NTSTATUS
31 FFSExceptionFilter(
32 IN PFFS_IRP_CONTEXT IrpContext,
33 IN PEXCEPTION_POINTERS ExceptionPointer)
34 {
35 NTSTATUS Status, ExceptionCode;
36 PEXCEPTION_RECORD ExceptRecord;
37
38 ExceptRecord = ExceptionPointer->ExceptionRecord;
39
40 ExceptionCode = ExceptRecord->ExceptionCode;
41
42 FFSBreakPoint();
43
44 //
45 // Check IrpContext is valid or not
46 //
47
48 if (IrpContext)
49 {
50 if ((IrpContext->Identifier.Type != FFSICX) ||
51 (IrpContext->Identifier.Size != sizeof(FFS_IRP_CONTEXT)))
52 {
53 IrpContext = NULL;
54 }
55 }
56 else
57 {
58 if (FsRtlIsNtstatusExpected(ExceptionCode))
59 {
60 return EXCEPTION_EXECUTE_HANDLER;
61 }
62 else
63 {
64 FFSBugCheck(FFS_BUGCHK_EXCEPT, (ULONG_PTR)ExceptRecord,
65 (ULONG_PTR)ExceptionPointer->ContextRecord,
66 (ULONG_PTR)ExceptRecord->ExceptionAddress);
67 }
68 }
69
70 //
71 // For the purposes of processing this exception, let's mark this
72 // request as being able to wait, and neither write through nor on
73 // removable media if we aren't posting it.
74 //
75
76 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
77
78 if (FsRtlIsNtstatusExpected(ExceptionCode))
79 {
80 //
81 // If the exception is expected execute our handler
82 //
83
84 FFSPrint((DBG_ERROR, "FFSExceptionFilter: Catching exception %xh\n",
85 ExceptionCode));
86
87 Status = EXCEPTION_EXECUTE_HANDLER;
88
89 if (IrpContext)
90 {
91 IrpContext->ExceptionInProgress = TRUE;
92 IrpContext->ExceptionCode = ExceptionCode;
93 }
94 }
95 else
96 {
97 //
98 // Continue search for an higher level exception handler
99 //
100
101 FFSPrint((DBG_ERROR, "FFSExceptionFilter: Passing on exception %#x\n",
102 ExceptionCode));
103
104 Status = EXCEPTION_CONTINUE_SEARCH;
105
106 if (IrpContext)
107 {
108 FFSFreeIrpContext(IrpContext);
109 }
110 }
111
112 return Status;
113 }
114
115
116 NTSTATUS
117 FFSExceptionHandler(
118 IN PFFS_IRP_CONTEXT IrpContext)
119 {
120 NTSTATUS Status;
121
122 FFSBreakPoint();
123
124 if (IrpContext)
125 {
126 if ((IrpContext->Identifier.Type != FFSICX) ||
127 (IrpContext->Identifier.Size != sizeof(FFS_IRP_CONTEXT)))
128 {
129 FFSBreakPoint();
130 return STATUS_UNSUCCESSFUL;
131 }
132
133 Status = IrpContext->ExceptionCode;
134
135 if (IrpContext->Irp)
136 {
137 //
138 // Check if this error is a result of user actions
139 //
140
141 PIRP Irp = IrpContext->Irp;
142
143
144 if (IoIsErrorUserInduced(Status))
145 {
146 //
147 // Now we will generate a pop-up to user
148 //
149
150 PDEVICE_OBJECT RealDevice;
151 PVPB Vpb = NULL;
152 PETHREAD Thread;
153
154 if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
155 {
156 Vpb = IoGetCurrentIrpStackLocation(Irp)->FileObject->Vpb;
157 }
158
159 //
160 // Get the initial thread
161 //
162
163 Thread = Irp->Tail.Overlay.Thread;
164 RealDevice = IoGetDeviceToVerify(Thread);
165
166 if (RealDevice == NULL)
167 {
168 //
169 // Get current thread
170 //
171
172 Thread = PsGetCurrentThread();
173 RealDevice = IoGetDeviceToVerify(Thread);
174
175 ASSERT(RealDevice != NULL);
176 }
177
178 if (RealDevice != NULL)
179 {
180 //
181 // Now we pop-up the error dialog ...
182 //
183
184 IoMarkIrpPending(Irp);
185 IoRaiseHardError(Irp, Vpb, RealDevice);
186
187 IoSetDeviceToVerify(Thread, NULL);
188
189 Status = STATUS_PENDING;
190 goto errorout;
191 }
192 }
193
194 IrpContext->Irp->IoStatus.Status = Status;
195
196 FFSCompleteRequest(IrpContext->Irp, FALSE, IO_NO_INCREMENT);
197 }
198
199 errorout:
200
201 FFSFreeIrpContext(IrpContext);
202 }
203 else
204 {
205 Status = STATUS_INSUFFICIENT_RESOURCES;
206 }
207
208 return Status;
209 }
210