ReactOS  0.4.14-dev-41-g31d7680
stackovf.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/fsrtl/stackovf.c
5  * PURPOSE: Provides Stack Overflow support for File System Drivers
6  * PROGRAMMERS: Pierre Schweitzer (pierre@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* GLOBALS *******************************************************************/
16 
17 /* We have one queue for paging files, one queue for normal files
18  * Queue 0 is for non-paging files
19  * Queue 1 is for paging files
20  * Don't add new/change current queues unless you know what you do
21  * Most of the code relies on the fact that we have two queues in that order
22  */
23 #define FSRTLP_MAX_QUEUES 2
24 
26 {
27 
33 
37 
38 /* PRIVATE FUNCTIONS *********************************************************/
39 
40 /*
41  * @implemented
42  */
43 VOID
44 NTAPI
46 {
48 
50 
51  /* Put us as top IRP for current thread */
53  /* And call FsRtlSORoutine */
54  WorkItem->Routine(WorkItem->Context, WorkItem->Event);
55 
56  /* If we were using fallback workitem, don't free it, just reset event */
57  if (WorkItem == &StackOverflowFallback)
58  {
60  }
61  /* Otherwise, free the work item */
62  else
63  {
64  ExFreePoolWithTag(WorkItem, 'FSrs');
65  }
66 
67  /* Reset top level */
69 }
70 
71 /*
72  * @implemented
73  */
74 VOID
75 NTAPI
79  IN BOOLEAN IsPaging)
80 {
82 
83  /* Try to allocate a work item */
84  WorkItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(STACK_OVERFLOW_WORK_ITEM), 'FSrs');
85  if (WorkItem == NULL)
86  {
87  /* If we failed, and we are not a paging file, just raise an error */
88  if (!IsPaging)
89  {
91  }
92 
93  /* Otherwise, wait for fallback workitem to be available and use it */
95  WorkItem = &StackOverflowFallback;
96  }
97 
98  /* Initialize work item */
99  WorkItem->Context = Context;
100  WorkItem->Event = Event;
101  WorkItem->Routine = StackOverflowRoutine;
103 
104  /* And queue it in the appropriate queue (paging or not?) */
105  KeInsertQueue(&FsRtlWorkerQueues[IsPaging], &WorkItem->WorkItem.List);
106 }
107 
108 /*
109  * @implemented
110  */
111 VOID
112 NTAPI
114 {
115  KIRQL Irql;
117  PWORK_QUEUE_ITEM WorkItem;
118  ULONG_PTR QueueId = (ULONG_PTR)StartContext;
119 
120  /* Set our priority according to the queue we're dealing with */
122 
123  /* Loop for events */
124  for (;;)
125  {
126  /* Look for next event */
129 
130  /* Call its routine (here: FsRtlStackOverflowRead) */
131  WorkItem->WorkerRoutine(WorkItem->Parameter);
132 
133  /* Check we're still at passive level or bugcheck */
135  if (Irql != PASSIVE_LEVEL)
136  {
137  KeBugCheckEx(IRQL_NOT_LESS_OR_EQUAL, (ULONG_PTR)WorkItem->WorkerRoutine,
138  (ULONG_PTR)Irql, (ULONG_PTR)WorkItem->WorkerRoutine,
139  (ULONG_PTR)WorkItem);
140  }
141  }
142 }
143 
144 /*
145  * @implemented
146  */
147 INIT_FUNCTION
148 NTSTATUS
149 NTAPI
151 {
152  ULONG_PTR i;
154  HANDLE ThreadHandle;
156 
157  /* Initialize each queue we have */
158  for (i = 0; i < FSRTLP_MAX_QUEUES; ++i)
159  {
161  NULL,
162  0,
163  NULL,
164  NULL);
165 
166  /* Initialize the queue and its associated thread and pass it the queue ID */
169  0, 0, FsRtlWorkerThread, (PVOID)i);
170  if (!NT_SUCCESS(Status))
171  {
172  return Status;
173  }
174 
175  /* Don't leak handle */
176  ZwClose(ThreadHandle);
177  }
178 
179  /* Also initialize our fallback event, set it to ensure it's already usable */
181 
182  return Status;
183 }
184 
185 /* PUBLIC FUNCTIONS **********************************************************/
186 
187 /*++
188  * @name FsRtlPostPagingFileStackOverflow
189  * @implemented NT 5.2
190  *
191  * The FsRtlPostPagingFileStackOverflow routine
192  *
193  * @param Context
194  *
195  * @param Event
196  *
197  * @param StackOverflowRoutine
198  *
199  * @return
200  *
201  * @remarks None.
202  *
203  *--*/
204 VOID
205 NTAPI
207  IN PKEVENT Event,
209 {
211 }
212 
213 /*++
214  * @name FsRtlPostStackOverflow
215  * @implemented NT 5.2
216  *
217  * The FsRtlPostStackOverflow routine
218  *
219  * @param Context
220  *
221  * @param Event
222  *
223  * @param StackOverflowRoutine
224  *
225  * @return
226  *
227  * @remarks None.
228  *
229  *--*/
230 VOID
231 NTAPI
233  IN PKEVENT Event,
235 {
237 }
238 
239 /* EOF */
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
KEVENT StackOverflowFallbackSerialEvent
Definition: stackovf.c:34
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FSRTLP_MAX_QUEUES
Definition: stackovf.c:23
#define IN
Definition: typedefs.h:38
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LIST_ENTRY List
Definition: extypes.h:203
struct _Entry Entry
Definition: kefuncs.h:640
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
VOID NTAPI FsRtlWorkerThread(IN PVOID StartContext)
Definition: stackovf.c:113
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI FsRtlPostPagingFileStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:206
#define LOW_REALTIME_PRIORITY
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
volatile PVOID Parameter
Definition: extypes.h:205
_Out_ PKIRQL Irql
Definition: csq.h:179
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
struct _STACK_OVERFLOW_WORK_ITEM STACK_OVERFLOW_WORK_ITEM
struct _STACK_OVERFLOW_WORK_ITEM * PSTACK_OVERFLOW_WORK_ITEM
unsigned char BOOLEAN
VOID NTAPI FsRtlStackOverflowRead(IN PVOID Context)
Definition: stackovf.c:45
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
KQUEUE FsRtlWorkerQueues[FSRTLP_MAX_QUEUES]
Definition: stackovf.c:36
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
LIST_ENTRY List
Definition: psmgr.c:57
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI FsRtlPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:232
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
INIT_FUNCTION NTSTATUS NTAPI FsRtlInitializeWorkerThread(VOID)
Definition: stackovf.c:150
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
PLIST_ENTRY NTAPI KeRemoveQueue(IN PKQUEUE Queue, IN KPROCESSOR_MODE WaitMode, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: queue.c:238
PWORKER_THREAD_ROUTINE WorkerRoutine
Definition: extypes.h:204
PFSRTL_STACK_OVERFLOW_ROUTINE Routine
Definition: stackovf.c:29
Definition: typedefs.h:117
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
Status
Definition: gdiplustypes.h:24
VOID(NTAPI * PFSRTL_STACK_OVERFLOW_ROUTINE)(_In_ PVOID Context, _In_ PKEVENT Event)
Definition: fsrtltypes.h:105
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1327
STACK_OVERFLOW_WORK_ITEM StackOverflowFallback
Definition: stackovf.c:35
LONG NTAPI KeInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry)
Definition: queue.c:198
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
VOID NTAPI KeInitializeQueue(IN PKQUEUE Queue, IN ULONG Count OPTIONAL)
Definition: queue.c:148
WORK_QUEUE_ITEM WorkItem
Definition: stackovf.c:28
struct tagContext Context
Definition: acpixf.h:1024
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
VOID NTAPI FsRtlpPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine, IN BOOLEAN IsPaging)
Definition: stackovf.c:76
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_In_ PKEVENT _In_ PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine
Definition: fsrtlfuncs.h:817
base of all file and directory entries
Definition: entries.h:82
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107