xref: /reactos/ntoskrnl/include/internal/probe.h (revision 171a9206)
1 #pragma once
2 
3 #include <reactos/probe.h>
4 
5 static
6 __inline
7 NTSTATUS
8 DefaultSetInfoBufferCheck(ULONG Class,
9                           const INFORMATION_CLASS_INFO *ClassList,
10                           ULONG ClassListEntries,
11                           PVOID Buffer,
12                           ULONG BufferLength,
13                           KPROCESSOR_MODE PreviousMode)
14 {
15     NTSTATUS Status = STATUS_SUCCESS;
16 
17     if (Class < ClassListEntries)
18     {
19         if (!(ClassList[Class].Flags & ICIF_SET))
20         {
21             Status = STATUS_INVALID_INFO_CLASS;
22         }
23         else if (ClassList[Class].RequiredSizeSET > 0 &&
24                  BufferLength != ClassList[Class].RequiredSizeSET)
25         {
26             if (!(ClassList[Class].Flags & ICIF_SET_SIZE_VARIABLE))
27             {
28                 Status = STATUS_INFO_LENGTH_MISMATCH;
29             }
30         }
31 
32         if (NT_SUCCESS(Status))
33         {
34             if (PreviousMode != KernelMode)
35             {
36                 _SEH2_TRY
37                 {
38                     ProbeForRead(Buffer,
39                                  BufferLength,
40                                  ClassList[Class].AlignmentSET);
41                 }
42                 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
43                 {
44                     Status = _SEH2_GetExceptionCode();
45                 }
46                 _SEH2_END;
47             }
48         }
49     }
50     else
51         Status = STATUS_INVALID_INFO_CLASS;
52 
53     return Status;
54 }
55 
56 static
57 __inline
58 NTSTATUS
59 DefaultQueryInfoBufferCheck(ULONG Class,
60                             const INFORMATION_CLASS_INFO *ClassList,
61                             ULONG ClassListEntries,
62                             PVOID Buffer,
63                             ULONG BufferLength,
64                             PULONG ReturnLength,
65                             PULONG_PTR ReturnLengthPtr,
66                             KPROCESSOR_MODE PreviousMode,
67                             BOOLEAN CompleteProbing)
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                         if (!CompleteProbing)
95                         {
96                             ProbeForRead(Buffer,
97                                          BufferLength,
98                                          ClassList[Class].AlignmentQUERY);
99                         }
100                         else
101                         {
102                             ProbeForWrite(Buffer,
103                                           BufferLength,
104                                           ClassList[Class].AlignmentQUERY);
105                         }
106                     }
107 
108                     if (ReturnLength != NULL)
109                     {
110                         ProbeForWriteUlong(ReturnLength);
111                     }
112                     if (ReturnLengthPtr != NULL)
113                     {
114                         ProbeForWrite(ReturnLengthPtr, sizeof(ULONG_PTR), sizeof(ULONG_PTR));
115                     }
116                 }
117                 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
118                 {
119                     Status = _SEH2_GetExceptionCode();
120                 }
121                 _SEH2_END;
122             }
123         }
124     }
125     else
126         Status = STATUS_INVALID_INFO_CLASS;
127 
128     return Status;
129 }
130