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
);