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 *****************************************************************/
26 NtLockFileCompletionRoutine(
27 IN PDEVICE_OBJECT DeviceObject,
33 return STATUS_SUCCESS;
34 //FIXME: should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED?
44 IN HANDLE EventHandle OPTIONAL,
45 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
46 IN PVOID ApcContext OPTIONAL,
47 OUT PIO_STATUS_BLOCK UserIoStatusBlock,
48 IN PLARGE_INTEGER ByteOffset,
49 IN PLARGE_INTEGER Length,
51 IN BOOLEAN FailImmediatedly,
52 IN BOOLEAN ExclusiveLock
56 PFILE_OBJECT FileObject = NULL;
57 PLARGE_INTEGER LocalLength = NULL;
60 PEXTENDED_IO_STACK_LOCATION StackPtr;
61 IO_STATUS_BLOCK LocalIoStatusBlock;
62 PIO_STATUS_BLOCK IoStatusBlock;
63 PDEVICE_OBJECT DeviceObject;
66 //FIXME: instead of this, use SEH when available?
67 if (!Length || !ByteOffset) {
68 Status = STATUS_INVALID_PARAMETER;
72 Status = ObReferenceObjectByHandle(
80 if (!NT_SUCCESS(Status)){
84 DeviceObject = IoGetRelatedDeviceObject(FileObject);
87 DeviceObject->StackSize,
92 Status = STATUS_INSUFFICIENT_RESOURCES;
96 if (EventHandle != NULL && !FailImmediatedly) {
97 Status = ObReferenceObjectByHandle(
105 if (!NT_SUCCESS(Status)) {
111 Event = &FileObject->Event;
115 if ((FileObject->Flags & FO_SYNCHRONOUS_IO) || FailImmediatedly)
116 IoStatusBlock = &LocalIoStatusBlock;
118 IoStatusBlock = UserIoStatusBlock;
120 //trigger FileObject/Event dereferencing
121 Irp->Tail.Overlay.OriginalFileObject = FileObject;
123 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
124 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
126 Irp->UserEvent = Event;
127 Irp->UserIosb = IoStatusBlock;
128 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
130 StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
131 StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
132 StackPtr->MinorFunction = IRP_MN_LOCK;
133 StackPtr->FileObject = FileObject;
135 if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
136 if (FailImmediatedly) StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
138 LocalLength = ExAllocatePoolWithTag(
140 sizeof(LARGE_INTEGER),
144 Status = STATUS_INSUFFICIENT_RESOURCES;
148 *LocalLength = *Length;
150 StackPtr->Parameters.LockControl.Length = LocalLength;
151 StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
152 StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
154 IoSetCompletionRoutine(
156 NtLockFileCompletionRoutine,
162 //can't touch FileObject after IoCallDriver since it might be freed
163 FobFlags = FileObject->Flags;
164 Status = IofCallDriver(DeviceObject, Irp);
166 if (Status == STATUS_PENDING && (FobFlags & FO_SYNCHRONOUS_IO)) {
168 Status = KeWaitForSingleObject(
171 ExGetPreviousMode() ,
172 (FobFlags & FO_ALERTABLE_IO) ? TRUE : FALSE,
176 if (Status != STATUS_WAIT_0) {
177 DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
179 FIXME: should do some special processing here if alertable wait
180 was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
182 return Status; //set status to something else?
185 Status = LocalIoStatusBlock.Status;
188 if (FobFlags & FO_SYNCHRONOUS_IO)
189 *UserIoStatusBlock = LocalIoStatusBlock;
195 if (LocalLength) ExFreePool(LocalLength);
196 if (Irp) IoFreeIrp(Irp);
197 if (Event) ObDereferenceObject(Event);
198 if (FileObject) ObDereferenceObject(FileObject);
213 IN HANDLE FileHandle,
214 OUT PIO_STATUS_BLOCK UserIoStatusBlock,
215 IN PLARGE_INTEGER ByteOffset,
216 IN PLARGE_INTEGER Length,
217 OUT PULONG Key OPTIONAL
221 PFILE_OBJECT FileObject = NULL;
222 PLARGE_INTEGER LocalLength = NULL;
224 PEXTENDED_IO_STACK_LOCATION StackPtr;
225 IO_STATUS_BLOCK LocalIoStatusBlock;
226 PDEVICE_OBJECT DeviceObject;
228 //FIXME: instead of this, use SEH when available
229 if (!Length || !ByteOffset) {
230 Status = STATUS_INVALID_PARAMETER;
235 BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
236 It should ONLY fail if we desire an access that conflict with granted access!
238 Status = ObReferenceObjectByHandle(
240 FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
246 if (!NT_SUCCESS(Status)){
250 DeviceObject = IoGetRelatedDeviceObject(FileObject);
253 DeviceObject->StackSize,
258 Status = STATUS_INSUFFICIENT_RESOURCES;
262 //trigger FileObject/Event dereferencing
263 Irp->Tail.Overlay.OriginalFileObject = FileObject;
265 Irp->UserIosb = &LocalIoStatusBlock;
266 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
268 StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
269 StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
270 StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
271 StackPtr->DeviceObject = DeviceObject;
272 StackPtr->FileObject = FileObject;
274 LocalLength = ExAllocatePoolWithTag(
276 sizeof(LARGE_INTEGER),
280 Status = STATUS_INSUFFICIENT_RESOURCES;
284 *LocalLength = *Length;
286 StackPtr->Parameters.LockControl.Length = LocalLength;
287 StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
288 StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
290 //allways syncronious
291 Status = IofCallDriver(DeviceObject, Irp);
293 *UserIoStatusBlock = LocalIoStatusBlock;
295 ExFreePool(LocalLength);
301 if (LocalLength) ExFreePool(LocalLength);
302 if (Irp) IoFreeIrp(Irp);
303 if (FileObject) ObDereferenceObject(FileObject);