ReactOS  0.4.14-dev-608-gd495a4f
util.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/io/iomgr/util.c
5  * PURPOSE: I/O Utility Functions
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Aleksey Bragin (aleksey@reactos.org)
8  * Daniel Zimmerman (netzimme@aim.com)
9  */
10 
11 /* INCLUDES *****************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
17 VOID
18 NTAPI
20  PULONG_PTR StackLimit);
21 
22 /* PRIVATE FUNCTIONS *********************************************************/
23 
25 NTAPI
28 {
29  /* Assume failure */
30  *DesiredAccess = 0;
31 
32  /* First check we really have a FileObject */
34  {
36  }
37 
38  /* Then compute desired access:
39  * Check if the handle has either FILE_WRITE_DATA or FILE_APPEND_DATA was
40  * granted. However, if this is a named pipe, make sure we don't ask for
41  * FILE_APPEND_DATA as it interferes with the FILE_CREATE_PIPE_INSTANCE
42  * access right!
43  */
45 
46  return STATUS_SUCCESS;
47 }
48 
49 /* FUNCTIONS *****************************************************************/
50 
51 /*
52  * @implemented
53  */
54 VOID
55 NTAPI
57 {
58  /* Just acquire the internal lock */
60 }
61 
62 /*
63  * @implemented
64  */
65 PVOID
66 NTAPI
68 {
69  /* Return the initial stack from the TCB */
70  return PsGetCurrentThread()->Tcb.InitialStack;
71 }
72 
73 /*
74  * @implemented
75  */
76 VOID
77 NTAPI
80 {
81  PKPRCB Prcb = KeGetCurrentPrcb();
82  ULONG_PTR DpcStack = (ULONG_PTR)(Prcb->DpcStack);
83  volatile ULONG_PTR StackAddress;
84 
85  /* Save our stack address so we always know it's valid */
86  StackAddress = (ULONG_PTR)(&StackAddress);
87 
88  /* Get stack values */
89  RtlpGetStackLimits(LowLimit, HighLimit);
90 
91  /* Check if we're outside the stack */
92  if ((StackAddress < *LowLimit) || (StackAddress > *HighLimit))
93  {
94  /* Check if we may be in a DPC */
96  {
97  /* Check if we really are in a DPC */
98  if ((Prcb->DpcRoutineActive) &&
99  (StackAddress <= DpcStack) &&
100  (StackAddress >= DpcStack - KERNEL_STACK_SIZE))
101  {
102  /* Use the DPC stack limits */
103  *HighLimit = DpcStack;
104  *LowLimit = DpcStack - KERNEL_STACK_SIZE;
105  }
106  }
107  }
108 }
109 
110 /*
111  * @implemented
112  */
113 BOOLEAN
114 NTAPI
116 {
117  /* Call the Ps Function */
118  return PsIsSystemThread(Thread);
119 }
120 
121 /*
122  * @implemented
123  */
124 BOOLEAN
125 NTAPI
128 {
129  /* Return support for WDM 1.30 (Windows Server 2003) */
130  if (MajorVersion <= 1 && MinorVersion <= 0x30) return TRUE;
131  return FALSE;
132 }
133 
134 /*
135  * @implemented
136  */
137 PEPROCESS
138 NTAPI
140 {
141  /* Return the current thread's process */
142  return (PEPROCESS)PsGetCurrentThread()->Tcb.ApcState.Process;
143 }
144 
145 /*
146  * @implemented
147  */
148 VOID
149 NTAPI
151 {
152  /* Release the internal lock */
154 }
155 
156 /*
157  * @implemented
158  */
159 PEPROCESS
160 NTAPI
162 {
163  /* Return the thread's process */
164  return Thread->ThreadsProcess;
165 }
166 
167 /*
168  * @implemented
169  */
170 NTSTATUS
171 NTAPI
174 {
175  PAGED_CODE();
176 
177  /* Map the generic mask */
180 
181  /* Fail if the access masks don't grant full access */
183  return STATUS_SUCCESS;
184 }
185 
186 /*
187  * @implemented
188  */
189 NTSTATUS
190 NTAPI
192  IN ULONG EaLength,
193  OUT PULONG ErrorOffset)
194 {
195  ULONG NextEntryOffset;
196  UCHAR EaNameLength;
197  ULONG ComputedLength;
199 
200  PAGED_CODE();
201 
202  /* We will browse all the entries */
203  for (Current = EaBuffer; ; Current = (PFILE_FULL_EA_INFORMATION)((ULONG_PTR)Current + NextEntryOffset))
204  {
205  /* Check that we have enough bits left for the current entry */
207  {
208  goto FailPath;
209  }
210 
211  EaNameLength = Current->EaNameLength;
212  ComputedLength = Current->EaValueLength + EaNameLength + FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) + 1;
213  /* Check that we have enough bits left for storing the name and its value */
214  if (EaLength < ComputedLength)
215  {
216  goto FailPath;
217  }
218 
219  /* Make sure the name is null terminated */
220  if (Current->EaName[EaNameLength] != ANSI_NULL)
221  {
222  goto FailPath;
223  }
224 
225  /* Get the next entry offset */
226  NextEntryOffset = Current->NextEntryOffset;
227  /* If it's 0, it's a termination case */
228  if (NextEntryOffset == 0)
229  {
230  /* If we don't overflow! */
231  if ((LONG)(EaLength - ComputedLength) < 0)
232  {
233  goto FailPath;
234  }
235 
236  break;
237  }
238 
239  /* Compare the next offset we computed with the provided one, they must match */
240  if (ALIGN_UP_BY(ComputedLength, sizeof(ULONG)) != NextEntryOffset)
241  {
242  goto FailPath;
243  }
244 
245  /* Check next entry offset value is positive */
246  if ((LONG)NextEntryOffset < 0)
247  {
248  goto FailPath;
249  }
250 
251  /* Compute the remaining bits */
252  EaLength -= NextEntryOffset;
253  /* We must have bits left */
254  if ((LONG)EaLength < 0)
255  {
256  goto FailPath;
257  }
258 
259  /* Move to the next entry */
260  }
261 
262  /* If we end here, everything went OK */
263  return STATUS_SUCCESS;
264 
265 FailPath:
266  /* If we end here, we failed, set failed offset */
267  *ErrorOffset = (ULONG_PTR)Current - (ULONG_PTR)EaBuffer;
269 }
270 
271 /*
272  * @unimplemented
273  */
274 NTSTATUS
275 NTAPI
277  IN UCHAR MajorFunction,
280  IN PVOID ExtraData OPTIONAL,
281  IN PVOID ExtraData2 OPTIONAL)
282 {
284  return STATUS_NOT_IMPLEMENTED;
285 }
286 
287 /*
288  * @unimplemented
289  */
290 NTSTATUS
291 NTAPI
294 {
296  return STATUS_NOT_IMPLEMENTED;
297 }
298 
299 /*
300  * @implemented
301  */
302 VOID
303 NTAPI
306 {
307  /* Set the pointer in the thread */
309 }
310 
311 /*
312  * @implemented
313  */
314 VOID
315 NTAPI
318 {
319  /* Ignore in case the IRP is not associated with any thread */
320  if (!Irp->Tail.Overlay.Thread)
321  {
322  DPRINT1("IoSetHardErrorOrVerifyDevice(0x%p, 0x%p): IRP has no thread, ignoring.\n",
323  Irp, DeviceObject);
324  return;
325  }
326 
327  /* Set the pointer in the IRP */
328  Irp->Tail.Overlay.Thread->DeviceToVerify = DeviceObject;
329 }
330 
331 /*
332  * @implemented
333  */
335 NTAPI
337 {
338  /* Return the pointer that was set with IoSetDeviceToVerify */
339  return Thread->DeviceToVerify;
340 }
341 
342 /*
343  * @unimplemented
344  */
345 NTSTATUS
346 NTAPI
348  IN ULONG Length,
349  IN BOOLEAN SetOperation)
350 {
352  return STATUS_NOT_IMPLEMENTED;
353 }
BOOLEAN NTAPI IoIsSystemThread(IN PETHREAD Thread)
Definition: util.c:115
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
NTSTATUS NTAPI IoCheckFunctionAccess(IN ACCESS_MASK GrantedAccess, IN UCHAR MajorFunction, IN UCHAR MinorFunction, IN ULONG IoControlCode, IN PVOID ExtraData OPTIONAL, IN PVOID ExtraData2 OPTIONAL)
Definition: util.c:276
#define IN
Definition: typedefs.h:38
_Out_ PULONG_PTR HighLimit
Definition: iofuncs.h:2837
NTSTATUS NTAPI IoValidateDeviceIoControlAccess(IN PIRP Irp, IN ULONG RequiredAccess)
Definition: util.c:292
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FS_INFORMATION_CLASS FsInformationClass
Definition: fltkernel.h:1329
ULONG MinorVersion
Definition: ros_glue.cpp:5
ULONG MajorVersion
Definition: ros_glue.cpp:4
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG IoControlCode
Definition: fltkernel.h:1383
Type
Definition: Type.h:6
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
struct _FILE_FULL_EA_INFORMATION * PFILE_FULL_EA_INFORMATION
_In_ PIRP Irp
Definition: csq.h:116
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG _In_opt_ PVOID EaBuffer
Definition: iofuncs.h:835
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
BOOLEAN NTAPI PsIsSystemThread(IN PETHREAD Thread)
Definition: thread.c:878
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
PDEVICE_OBJECT NTAPI IoGetDeviceToVerify(IN PETHREAD Thread)
Definition: util.c:336
#define FILE_APPEND_DATA
Definition: nt_native.h:634
_Out_ PKIRQL Irql
Definition: csq.h:179
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
UCHAR KIRQL
Definition: env_spec_w32.h:591
PEPROCESS NTAPI IoThreadToProcess(IN PETHREAD Thread)
Definition: util.c:161
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define ANSI_NULL
NTSTATUS NTAPI IoComputeDesiredAccessFileObject(IN PFILE_OBJECT FileObject, IN PACCESS_MASK DesiredAccess)
Definition: util.c:26
long LONG
Definition: pedump.c:60
#define FO_NAMED_PIPE
Definition: iotypes.h:1739
unsigned char BOOLEAN
NTSTATUS NTAPI IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: util.c:191
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define FILE_WRITE_DATA
Definition: nt_native.h:631
enum _FSINFOCLASS FS_INFORMATION_CLASS
PVOID NTAPI IoGetInitialStack(VOID)
Definition: util.c:67
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:259
PEPROCESS NTAPI IoGetCurrentProcess(VOID)
Definition: util.c:139
IN PVCB IN PDIRENT OUT PULONG EaLength
Definition: fatprocs.h:866
NTSTATUS NTAPI IoCheckDesiredAccess(IN OUT PACCESS_MASK DesiredAccess, IN ACCESS_MASK GrantedAccess)
Definition: util.c:172
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define KERNEL_STACK_SIZE
* PFILE_OBJECT
Definition: iotypes.h:1955
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR DpcRoutineActive
Definition: ketypes.h:688
_In_ ULONG RequiredAccess
Definition: iofuncs.h:2219
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
PDEVICE_OBJECT DeviceToVerify
Definition: pstypes.h:1077
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
_In_ UCHAR MinorFunction
Definition: pofuncs.h:42
VOID NTAPI RtlpGetStackLimits(PULONG_PTR StackBase, PULONG_PTR StackLimit)
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define STATUS_EA_LIST_INCONSISTENT
Definition: IoEaTest.cpp:21
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
PVOID DpcStack
Definition: ketypes.h:677
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
VOID NTAPI IoGetStackLimits(OUT PULONG_PTR LowLimit, OUT PULONG_PTR HighLimit)
Definition: util.c:78
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
ACCESS_MASK * PACCESS_MASK
Definition: nt_native.h:41
#define UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
#define ALIGN_UP_BY(size, align)
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:13
return STATUS_SUCCESS
Definition: btrfs.c:2938
ULONG ACCESS_MASK
Definition: nt_native.h:40
VOID NTAPI IoSetDeviceToVerify(IN PETHREAD Thread, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:304
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
NTSTATUS NTAPI IoCheckQuerySetVolumeInformation(IN FS_INFORMATION_CLASS FsInformationClass, IN ULONG Length, IN BOOLEAN SetOperation)
Definition: util.c:347
BOOLEAN NTAPI IoIsWdmVersionAvailable(IN UCHAR MajorVersion, IN UCHAR MinorVersion)
Definition: util.c:126
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68