Sync to trunk head(r38096)
[reactos.git] / reactos / ntoskrnl / include / internal / probe.h
1 #ifndef __INCLUDE_INTERNAL_PROBE_H
2 #define __INCLUDE_INTERNAL_PROBE_H
3
4 #include <reactos/probe.h>
5
6 static
7 __inline
8 NTSTATUS
9 DefaultSetInfoBufferCheck(ULONG Class,
10 const INFORMATION_CLASS_INFO *ClassList,
11 ULONG ClassListEntries,
12 PVOID Buffer,
13 ULONG BufferLength,
14 KPROCESSOR_MODE PreviousMode)
15 {
16 NTSTATUS Status = STATUS_SUCCESS;
17
18 if (Class < ClassListEntries)
19 {
20 if (!(ClassList[Class].Flags & ICIF_SET))
21 {
22 Status = STATUS_INVALID_INFO_CLASS;
23 }
24 else if (ClassList[Class].RequiredSizeSET > 0 &&
25 BufferLength != ClassList[Class].RequiredSizeSET)
26 {
27 if (!(ClassList[Class].Flags & ICIF_SET_SIZE_VARIABLE))
28 {
29 Status = STATUS_INFO_LENGTH_MISMATCH;
30 }
31 }
32
33 if (NT_SUCCESS(Status))
34 {
35 if (PreviousMode != KernelMode)
36 {
37 _SEH2_TRY
38 {
39 ProbeForRead(Buffer,
40 BufferLength,
41 ClassList[Class].AlignmentSET);
42 }
43 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
44 {
45 Status = _SEH2_GetExceptionCode();
46 }
47 _SEH2_END;
48 }
49 }
50 }
51 else
52 Status = STATUS_INVALID_INFO_CLASS;
53
54 return Status;
55 }
56
57 static
58 __inline
59 NTSTATUS
60 DefaultQueryInfoBufferCheck(ULONG Class,
61 const INFORMATION_CLASS_INFO *ClassList,
62 ULONG ClassListEntries,
63 PVOID Buffer,
64 ULONG BufferLength,
65 PULONG ReturnLength,
66 PULONG_PTR ReturnLengthLong,
67 KPROCESSOR_MODE PreviousMode)
68 {
69 NTSTATUS Status = STATUS_SUCCESS;
70
71 if (Class < ClassListEntries)
72 {
73 if (!(ClassList[Class].Flags & ICIF_QUERY))
74 {
75 Status = STATUS_INVALID_INFO_CLASS;
76 }
77 else if (ClassList[Class].RequiredSizeQUERY > 0 &&
78 BufferLength != ClassList[Class].RequiredSizeQUERY)
79 {
80 if (!(ClassList[Class].Flags & ICIF_QUERY_SIZE_VARIABLE))
81 {
82 Status = STATUS_INFO_LENGTH_MISMATCH;
83 }
84 }
85
86 if (NT_SUCCESS(Status))
87 {
88 if (PreviousMode != KernelMode)
89 {
90 _SEH2_TRY
91 {
92 if (Buffer != NULL)
93 {
94 ProbeForWrite(Buffer,
95 BufferLength,
96 ClassList[Class].AlignmentQUERY);
97 }
98
99 if (ReturnLength != NULL)
100 {
101 ProbeForWriteUlong(ReturnLength);
102 }
103 if (ReturnLengthLong != NULL)
104 {
105 ProbeForWrite(ReturnLengthLong, sizeof(ULONG_PTR), sizeof(ULONG_PTR));
106 }
107 }
108 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
109 {
110 Status = _SEH2_GetExceptionCode();
111 }
112 _SEH2_END;
113 }
114 }
115 }
116 else
117 Status = STATUS_INVALID_INFO_CLASS;
118
119 return Status;
120 }
121
122 #endif