[SHELL32] SHChangeNotify: Use tree for CDirectoryList (#6784)
[reactos.git] / ntoskrnl / include / internal / probe.h
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 }