2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/bug.c
5 * PURPOSE: Graceful system shutdown if a bug is detected
6 * PROGRAMMER: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
17 #include <internal/debug.h>
20 #define TAG_LOCK TAG('F','l','c','k')
22 /* FUNCTIONS *****************************************************************/
24 static NTSTATUS STDCALL
25 IopLockFileCompletionRoutine(
26 IN PDEVICE_OBJECT DeviceObject
,
32 return STATUS_SUCCESS
;
33 // FIXME: Should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED?
43 IN HANDLE EventHandle OPTIONAL
,
44 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
45 IN PVOID ApcContext OPTIONAL
,
46 OUT PIO_STATUS_BLOCK IoStatusBlock
,
47 IN PLARGE_INTEGER ByteOffset
,
48 IN PLARGE_INTEGER Length
,
50 IN BOOLEAN FailImmediatedly
,
51 IN BOOLEAN ExclusiveLock
54 PFILE_OBJECT FileObject
= NULL
;
55 PLARGE_INTEGER LocalLength
= NULL
;
58 PEXTENDED_IO_STACK_LOCATION StackPtr
;
59 PDEVICE_OBJECT DeviceObject
;
60 KPROCESSOR_MODE PreviousMode
;
63 // FIXME: instead of this, use SEH when available?
64 if (!Length
|| !ByteOffset
)
66 Status
= STATUS_INVALID_PARAMETER
;
70 PreviousMode
= ExGetPreviousMode();
72 Status
= ObReferenceObjectByHandle(FileHandle
,
78 if (!NT_SUCCESS(Status
))
83 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
85 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
89 Status
= STATUS_INSUFFICIENT_RESOURCES
;
93 if (EventHandle
!= NULL
&& !FailImmediatedly
)
95 Status
= ObReferenceObjectByHandle(EventHandle
,
101 if (!NT_SUCCESS(Status
))
108 Event
= &FileObject
->Event
;
112 /* Trigger FileObject/Event dereferencing */
113 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
115 Irp
->RequestorMode
= PreviousMode
;
116 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
117 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
119 Irp
->UserEvent
= Event
;
120 Irp
->UserIosb
= IoStatusBlock
;
121 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
123 StackPtr
= (PEXTENDED_IO_STACK_LOCATION
) IoGetNextIrpStackLocation(Irp
);
124 StackPtr
->MajorFunction
= IRP_MJ_LOCK_CONTROL
;
125 StackPtr
->MinorFunction
= IRP_MN_LOCK
;
126 StackPtr
->FileObject
= FileObject
;
129 StackPtr
->Flags
|= SL_EXCLUSIVE_LOCK
;
131 if (FailImmediatedly
)
132 StackPtr
->Flags
|= SL_FAIL_IMMEDIATELY
;
134 LocalLength
= ExAllocatePoolWithTag(NonPagedPool
,
135 sizeof(LARGE_INTEGER
),
139 Status
= STATUS_INSUFFICIENT_RESOURCES
;
143 *LocalLength
= *Length
;
145 StackPtr
->Parameters
.LockControl
.Length
= LocalLength
;
146 StackPtr
->Parameters
.LockControl
.ByteOffset
= *ByteOffset
;
147 StackPtr
->Parameters
.LockControl
.Key
= Key
? *Key
: 0;
149 IoSetCompletionRoutine(Irp
,
150 IopLockFileCompletionRoutine
,
156 /* Can't touch FileObject after IoCallDriver since it might be freed */
157 Status
= IofCallDriver(DeviceObject
, Irp
);
158 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
160 Status
= KeWaitForSingleObject(Event
,
163 FileObject
->Flags
& FO_ALERTABLE_IO
,
166 if (Status
!= STATUS_WAIT_0
)
168 DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
170 * FIXME: Should do some special processing here if alertable wait
171 * was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
173 return Status
; /* Set status to something else? */
176 Status
= IoStatusBlock
->Status
;
183 ExFreePool(LocalLength
);
189 ObDereferenceObject(Event
);
192 ObDereferenceObject(FileObject
);
204 IN HANDLE FileHandle
,
205 OUT PIO_STATUS_BLOCK IoStatusBlock
,
206 IN PLARGE_INTEGER ByteOffset
,
207 IN PLARGE_INTEGER Length
,
208 OUT PULONG Key OPTIONAL
211 PFILE_OBJECT FileObject
= NULL
;
212 PLARGE_INTEGER LocalLength
= NULL
;
214 PEXTENDED_IO_STACK_LOCATION StackPtr
;
215 PDEVICE_OBJECT DeviceObject
;
216 KPROCESSOR_MODE PreviousMode
;
219 // FIXME: instead of this, use SEH when available
220 if (!Length
|| !ByteOffset
)
222 Status
= STATUS_INVALID_PARAMETER
;
226 PreviousMode
= ExGetPreviousMode();
229 * BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
230 * It should ONLY fail if we desire an access that conflict with granted access!
232 Status
= ObReferenceObjectByHandle(FileHandle
,
233 0, //FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
238 if (!NT_SUCCESS(Status
))
243 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
245 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
249 Status
= STATUS_INSUFFICIENT_RESOURCES
;
253 /* Trigger FileObject/Event dereferencing */
254 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
255 Irp
->RequestorMode
= PreviousMode
;
256 Irp
->UserIosb
= IoStatusBlock
;
257 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
259 StackPtr
= (PEXTENDED_IO_STACK_LOCATION
) IoGetNextIrpStackLocation(Irp
);
260 StackPtr
->MajorFunction
= IRP_MJ_LOCK_CONTROL
;
261 StackPtr
->MinorFunction
= IRP_MN_UNLOCK_SINGLE
;
262 StackPtr
->DeviceObject
= DeviceObject
;
263 StackPtr
->FileObject
= FileObject
;
265 LocalLength
= ExAllocatePoolWithTag(NonPagedPool
,
266 sizeof(LARGE_INTEGER
),
270 Status
= STATUS_INSUFFICIENT_RESOURCES
;
274 *LocalLength
= *Length
;
276 StackPtr
->Parameters
.LockControl
.Length
= LocalLength
;
277 StackPtr
->Parameters
.LockControl
.ByteOffset
= *ByteOffset
;
278 StackPtr
->Parameters
.LockControl
.Key
= Key
? *Key
: 0;
280 /* Allways synchronous */
281 Status
= IofCallDriver(DeviceObject
, Irp
);
283 ExFreePool(LocalLength
);
289 ExFreePool(LocalLength
);
295 ObDereferenceObject(FileObject
);