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;
63 //FIXME: instead of this, use SEH when available?
64 if (!Length || !ByteOffset) {
65 Status = STATUS_INVALID_PARAMETER;
69 Status = ObReferenceObjectByHandle(
77 if (!NT_SUCCESS(Status)){
81 DeviceObject = IoGetRelatedDeviceObject(FileObject);
84 DeviceObject->StackSize,
89 Status = STATUS_INSUFFICIENT_RESOURCES;
93 if (EventHandle != NULL && !FailImmediatedly) {
94 Status = ObReferenceObjectByHandle(
102 if (!NT_SUCCESS(Status)) {
108 Event = &FileObject->Event;
112 if ((FileObject->Flags & FO_SYNCHRONOUS_IO) || FailImmediatedly)
113 IoStatusBlock = &LocalIoStatusBlock;
115 IoStatusBlock = UserIoStatusBlock;
117 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
118 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
120 Irp->UserEvent = Event;
121 Irp->UserIosb = IoStatusBlock;
122 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
124 StackPtr = IoGetNextIrpStackLocation(Irp);
125 StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
126 StackPtr->MinorFunction = IRP_MN_LOCK;
127 StackPtr->FileObject = FileObject;
129 if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
130 if (FailImmediatedly) StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
132 LocalLength = ExAllocatePoolWithTag(
134 sizeof(LARGE_INTEGER),
138 Status = STATUS_INSUFFICIENT_RESOURCES;
142 *LocalLength = *Length;
144 StackPtr->Parameters.LockControl.Length = LocalLength;
145 StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
146 StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
148 IoSetCompletionRoutine(
150 NtLockFileCompletionRoutine,
156 //can't touch FileObject after IoCallDriver since it might be freed
157 FobFlags = FileObject->Flags;
158 Status = IofCallDriver(DeviceObject, Irp);
160 if (Status == STATUS_PENDING && (FobFlags & FO_SYNCHRONOUS_IO)) {
162 Status = KeWaitForSingleObject(
165 ExGetPreviousMode() ,
166 (FobFlags & FO_ALERTABLE_IO) ? TRUE : FALSE,
170 if (Status != STATUS_WAIT_0) {
171 DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
173 FIXME: should do some special processing here if alertable wait
174 was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
176 return Status; //set status to something else?
179 Status = LocalIoStatusBlock.Status;
182 if (FobFlags & FO_SYNCHRONOUS_IO)
183 *UserIoStatusBlock = LocalIoStatusBlock;
189 if (LocalLength) ExFreePool(LocalLength);
190 if (Irp) IoFreeIrp(Irp);
191 if (Event) ObDereferenceObject(Event);
192 if (FileObject) ObDereferenceObject(FileObject);
204 IN HANDLE FileHandle,
205 OUT PIO_STATUS_BLOCK UserIoStatusBlock,
206 IN PLARGE_INTEGER ByteOffset,
207 IN PLARGE_INTEGER Length,
208 OUT PULONG Key OPTIONAL
212 PFILE_OBJECT FileObject = NULL;
213 PLARGE_INTEGER LocalLength = NULL;
215 PIO_STACK_LOCATION StackPtr;
216 IO_STATUS_BLOCK LocalIoStatusBlock;
217 PDEVICE_OBJECT DeviceObject;
219 //FIXME: instead of this, use SEH when available
220 if (!Length || !ByteOffset) {
221 Status = STATUS_INVALID_PARAMETER;
226 BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
227 It should ONLY fail if we desire an access that conflict with granted access!
229 Status = ObReferenceObjectByHandle(
231 FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
237 if (!NT_SUCCESS(Status)){
241 DeviceObject = IoGetRelatedDeviceObject(FileObject);
244 DeviceObject->StackSize,
249 Status = STATUS_INSUFFICIENT_RESOURCES;
253 Irp->UserIosb = &LocalIoStatusBlock;
254 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
256 StackPtr = IoGetNextIrpStackLocation(Irp);
257 StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
258 StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
259 StackPtr->DeviceObject = DeviceObject;
260 StackPtr->FileObject = FileObject;
262 LocalLength = ExAllocatePoolWithTag(
264 sizeof(LARGE_INTEGER),
268 Status = STATUS_INSUFFICIENT_RESOURCES;
272 *LocalLength = *Length;
274 StackPtr->Parameters.LockControl.Length = LocalLength;
275 StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
276 StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
278 //allways syncronious
279 Status = IofCallDriver(DeviceObject, Irp);
281 *UserIoStatusBlock = LocalIoStatusBlock;
283 ExFreePool(LocalLength);
289 if (LocalLength) ExFreePool(LocalLength);
290 if (Irp) IoFreeIrp(Irp);
291 if (FileObject) ObDereferenceObject(FileObject);