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?
41 IN HANDLE EventHandle OPTIONAL,
42 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
43 IN PVOID ApcContext OPTIONAL,
44 OUT PIO_STATUS_BLOCK UserIoStatusBlock,
45 IN PLARGE_INTEGER ByteOffset,
46 IN PLARGE_INTEGER Length,
48 IN BOOLEAN FailImmediatedly,
49 IN BOOLEAN ExclusiveLock
53 PFILE_OBJECT FileObject = NULL;
54 PLARGE_INTEGER LocalLength = NULL;
57 PIO_STACK_LOCATION StackPtr;
58 IO_STATUS_BLOCK LocalIoStatusBlock;
59 PIO_STATUS_BLOCK IoStatusBlock;
60 PDEVICE_OBJECT DeviceObject;
62 //FIXME: instead of this, use SEH when available?
63 if (!Length || !ByteOffset) {
64 Status = STATUS_INVALID_PARAMETER;
69 BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode!
70 It should ONLY fail if we desire an access that conflict with granted access!
72 Status = ObReferenceObjectByHandle(
74 FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
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 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
121 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
123 Irp->UserEvent = Event;
124 Irp->UserIosb = IoStatusBlock;
125 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
127 StackPtr = IoGetNextIrpStackLocation(Irp);
128 StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
129 StackPtr->MinorFunction = IRP_MN_LOCK;
130 StackPtr->DeviceObject = DeviceObject;
131 StackPtr->FileObject = FileObject;
133 if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
134 if (FailImmediatedly) StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
136 LocalLength = ExAllocatePoolWithTag(
138 sizeof(LARGE_INTEGER),
142 Status = STATUS_INSUFFICIENT_RESOURCES;
146 *LocalLength = *Length;
148 StackPtr->Parameters.LockControl.Length = LocalLength;
149 StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
150 StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
152 IoSetCompletionRoutine(
154 NtLockFileCompletionRoutine,
160 Status = IofCallDriver(DeviceObject, Irp);
162 if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) {
164 Status = KeWaitForSingleObject(
167 ExGetPreviousMode() ,
168 (FileObject->Flags & FO_ALERTABLE_IO) ? TRUE : FALSE,
172 if (Status != STATUS_WAIT_0) {
173 DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
175 FIXME: should do some special processing here if alertable wait
176 was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
178 return Status; //set status to something else?
181 Status = LocalIoStatusBlock.Status;
184 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
185 *UserIoStatusBlock = LocalIoStatusBlock;
191 if (LocalLength) ExFreePool(LocalLength);
192 if (Irp) IoFreeIrp(Irp);
193 if (Event) ObDereferenceObject(Event);
194 if (FileObject) ObDereferenceObject(FileObject);
206 IN HANDLE FileHandle,
207 OUT PIO_STATUS_BLOCK UserIoStatusBlock,
208 IN PLARGE_INTEGER ByteOffset,
209 IN PLARGE_INTEGER Length,
210 OUT PULONG Key OPTIONAL
214 PFILE_OBJECT FileObject = NULL;
215 PLARGE_INTEGER LocalLength = NULL;
217 PIO_STACK_LOCATION StackPtr;
218 IO_STATUS_BLOCK LocalIoStatusBlock;
219 PDEVICE_OBJECT DeviceObject;
221 //FIXME: instead of this, use SEH when available
222 if (!Length || !ByteOffset) {
223 Status = STATUS_INVALID_PARAMETER;
228 BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
229 It should ONLY fail if we desire an access that conflict with granted access!
231 Status = ObReferenceObjectByHandle(
233 FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
239 if (!NT_SUCCESS(Status)){
243 DeviceObject = IoGetRelatedDeviceObject(FileObject);
246 DeviceObject->StackSize,
251 Status = STATUS_INSUFFICIENT_RESOURCES;
255 Irp->UserIosb = &LocalIoStatusBlock;
256 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
258 StackPtr = IoGetNextIrpStackLocation(Irp);
259 StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
260 StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
261 StackPtr->DeviceObject = DeviceObject;
262 StackPtr->FileObject = FileObject;
264 LocalLength = ExAllocatePoolWithTag(
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 syncronious
281 Status = IofCallDriver(DeviceObject, Irp);
283 *UserIoStatusBlock = LocalIoStatusBlock;
285 ExFreePool(LocalLength);
291 if (LocalLength) ExFreePool(LocalLength);
292 if (Irp) IoFreeIrp(Irp);
293 if (FileObject) ObDereferenceObject(FileObject);