- Initialize the registry in one shot, and allow it to fail and do the associated...
[reactos.git] / reactos / ntoskrnl / include / internal / ntoskrnl.h
1 #ifndef __INCLUDE_INTERNAL_NTOSKRNL_H
2 #define __INCLUDE_INTERNAL_NTOSKRNL_H
3
4 /*
5 * Use these to place a function in a specific section of the executable
6 */
7 #define PLACE_IN_SECTION(s) __attribute__((section (s)))
8 #ifdef __GNUC__
9 #define INIT_FUNCTION PLACE_IN_SECTION("init")
10 #define PAGE_LOCKED_FUNCTION PLACE_IN_SECTION("pagelk")
11 #define PAGE_UNLOCKED_FUNCTION PLACE_IN_SECTION("pagepo")
12 #else
13 #define INIT_FUNCTION
14 #define PAGE_LOCKED_FUNCTION
15 #define PAGE_UNLOCKED_FUNCTION
16 #endif
17
18 #ifdef _NTOSKRNL_
19
20 #include "ke.h"
21 #include "i386/mm.h"
22 #include "i386/fpu.h"
23 #include "i386/v86m.h"
24 #include "ob.h"
25 #include "mm.h"
26 #include "ex.h"
27 #include "ps.h"
28 #include "cc.h"
29 #include "io.h"
30 #include "po.h"
31 #include "se.h"
32 #include "ldr.h"
33 #include "kd.h"
34 #include "fsrtl.h"
35 #include "lpc.h"
36 #include "rtl.h"
37 #ifdef KDBG
38 #include "../kdbg/kdb.h"
39 #endif
40 #include "dbgk.h"
41 #include "tag.h"
42 #include "test.h"
43 #include "inbv.h"
44 #include "vdm.h"
45
46 #include <pshpack1.h>
47 /*
48 * Defines a descriptor as it appears in the processor tables
49 */
50 typedef struct __DESCRIPTOR
51 {
52 ULONG a;
53 ULONG b;
54 } IDT_DESCRIPTOR, GDT_DESCRIPTOR;
55
56 #include <poppack.h>
57 //extern GDT_DESCRIPTOR KiGdt[256];
58
59 /*
60 * Initalization functions (called once by main())
61 */
62 VOID MmInitSystem(ULONG Phase, PLOADER_PARAMETER_BLOCK LoaderBlock, ULONG LastKernelAddress);
63 BOOLEAN NTAPI ObInit(VOID);
64 BOOLEAN NTAPI CmInitSystem1(VOID);
65 VOID CmShutdownRegistry(VOID);
66 BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize);
67 BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize);
68 BOOLEAN NTAPI KdInitSystem(ULONG Reserved, PLOADER_PARAMETER_BLOCK LoaderBlock);
69
70 /* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */
71 BOOLEAN FASTCALL
72 RtlpCreateUnicodeString(
73 IN OUT PUNICODE_STRING UniDest,
74 IN PCWSTR Source,
75 IN POOL_TYPE PoolType);
76
77 VOID
78 NTAPI
79 RtlpLogException(IN PEXCEPTION_RECORD ExceptionRecord,
80 IN PCONTEXT ContextRecord,
81 IN PVOID ContextData,
82 IN ULONG Size);
83
84 /* FIXME: Interlocked functions that need to be made into a public header */
85 #ifdef __GNUC__
86 FORCEINLINE
87 LONG
88 InterlockedAnd(IN OUT LONG volatile *Target,
89 IN LONG Set)
90 {
91 LONG i;
92 LONG j;
93
94 j = *Target;
95 do {
96 i = j;
97 j = InterlockedCompareExchange((PLONG)Target,
98 i & Set,
99 i);
100
101 } while (i != j);
102
103 return j;
104 }
105
106 FORCEINLINE
107 LONG
108 InterlockedOr(IN OUT LONG volatile *Target,
109 IN LONG Set)
110 {
111 LONG i;
112 LONG j;
113
114 j = *Target;
115 do {
116 i = j;
117 j = InterlockedCompareExchange((PLONG)Target,
118 i | Set,
119 i);
120
121 } while (i != j);
122
123 return j;
124 }
125 #endif
126
127 /*
128 * generic information class probing code
129 */
130
131 #define ICIF_QUERY 0x1
132 #define ICIF_SET 0x2
133 #define ICIF_QUERY_SIZE_VARIABLE 0x4
134 #define ICIF_SET_SIZE_VARIABLE 0x8
135 #define ICIF_SIZE_VARIABLE (ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE)
136
137 typedef struct _INFORMATION_CLASS_INFO
138 {
139 ULONG RequiredSizeQUERY;
140 ULONG RequiredSizeSET;
141 ULONG AlignmentSET;
142 ULONG AlignmentQUERY;
143 ULONG Flags;
144 } INFORMATION_CLASS_INFO, *PINFORMATION_CLASS_INFO;
145
146 #define ICI_SQ_SAME(Type, Alignment, Flags) \
147 { Type, Type, Alignment, Alignment, Flags }
148
149 #define ICI_SQ(TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags) \
150 { TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags }
151
152 //
153 // TEMPORARY
154 //
155 #define IQS_SAME(Type, Alignment, Flags) \
156 { sizeof(Type), sizeof(Type), sizeof(Alignment), sizeof(Alignment), Flags }
157
158 #define IQS(TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags) \
159 { sizeof(TypeQuery), sizeof(TypeSet), sizeof(AlignmentQuery), sizeof(AlignmentSet), Flags }
160
161 FORCEINLINE
162 NTSTATUS
163 DefaultSetInfoBufferCheck(ULONG Class,
164 const INFORMATION_CLASS_INFO *ClassList,
165 ULONG ClassListEntries,
166 PVOID Buffer,
167 ULONG BufferLength,
168 KPROCESSOR_MODE PreviousMode)
169 {
170 NTSTATUS Status = STATUS_SUCCESS;
171
172 if (Class >= 0 && Class < ClassListEntries)
173 {
174 if (!(ClassList[Class].Flags & ICIF_SET))
175 {
176 Status = STATUS_INVALID_INFO_CLASS;
177 }
178 else if (ClassList[Class].RequiredSizeSET > 0 &&
179 BufferLength != ClassList[Class].RequiredSizeSET)
180 {
181 if (!(ClassList[Class].Flags & ICIF_SET_SIZE_VARIABLE))
182 {
183 Status = STATUS_INFO_LENGTH_MISMATCH;
184 }
185 }
186
187 if (NT_SUCCESS(Status))
188 {
189 if (PreviousMode != KernelMode)
190 {
191 _SEH_TRY
192 {
193 ProbeForRead(Buffer,
194 BufferLength,
195 ClassList[Class].AlignmentSET);
196 }
197 _SEH_HANDLE
198 {
199 Status = _SEH_GetExceptionCode();
200 }
201 _SEH_END;
202 }
203 }
204 }
205 else
206 Status = STATUS_INVALID_INFO_CLASS;
207
208 return Status;
209 }
210
211 FORCEINLINE
212 NTSTATUS
213 DefaultQueryInfoBufferCheck(ULONG Class,
214 const INFORMATION_CLASS_INFO *ClassList,
215 ULONG ClassListEntries,
216 PVOID Buffer,
217 ULONG BufferLength,
218 PULONG ReturnLength,
219 KPROCESSOR_MODE PreviousMode)
220 {
221 NTSTATUS Status = STATUS_SUCCESS;
222
223 if (Class >= 0 && Class < ClassListEntries)
224 {
225 if (!(ClassList[Class].Flags & ICIF_QUERY))
226 {
227 Status = STATUS_INVALID_INFO_CLASS;
228 }
229 else if (ClassList[Class].RequiredSizeQUERY > 0 &&
230 BufferLength != ClassList[Class].RequiredSizeQUERY)
231 {
232 if (!(ClassList[Class].Flags & ICIF_QUERY_SIZE_VARIABLE))
233 {
234 Status = STATUS_INFO_LENGTH_MISMATCH;
235 }
236 }
237
238 if (NT_SUCCESS(Status))
239 {
240 if (PreviousMode != KernelMode)
241 {
242 _SEH_TRY
243 {
244 if (Buffer != NULL)
245 {
246 ProbeForWrite(Buffer,
247 BufferLength,
248 ClassList[Class].AlignmentQUERY);
249 }
250
251 if (ReturnLength != NULL)
252 {
253 ProbeForWriteUlong(ReturnLength);
254 }
255 }
256 _SEH_HANDLE
257 {
258 Status = _SEH_GetExceptionCode();
259 }
260 _SEH_END;
261 }
262 }
263 }
264 else
265 Status = STATUS_INVALID_INFO_CLASS;
266
267 return Status;
268 }
269
270 /*
271 * Use IsPointerOffset to test whether a pointer should be interpreted as an offset
272 * or as a pointer
273 */
274 #if defined(_X86_) || defined(_M_AMD64)
275
276 /* for x86 and x86-64 the MSB is 1 so we can simply test on that */
277 #define IsPointerOffset(Ptr) ((LONG_PTR)(Ptr) >= 0)
278
279 #elif defined(_IA64_)
280
281 /* on Itanium if the 24 most significant bits are set, we're not dealing with
282 offsets anymore. */
283 #define IsPointerOffset(Ptr) (((ULONG_PTR)(Ptr) & 0xFFFFFF0000000000ULL) == 0)
284
285 #else
286 #error IsPointerOffset() needs to be defined for this architecture
287 #endif
288
289 #endif
290
291 C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SystemCall) == 0x300);
292 C_ASSERT(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
293 C_ASSERT(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
294 C_ASSERT(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
295 C_ASSERT(FIELD_OFFSET(KTHREAD, NpxState) == KTHREAD_NPX_STATE);
296 C_ASSERT(FIELD_OFFSET(KTHREAD, ServiceTable) == KTHREAD_SERVICE_TABLE);
297 C_ASSERT(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
298 C_ASSERT(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
299 C_ASSERT(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
300 C_ASSERT(FIELD_OFFSET(KTHREAD, ApcState.Process) == KTHREAD_APCSTATE_PROCESS);
301 C_ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == KPROCESS_DIRECTORY_TABLE_BASE);
302 C_ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
303 C_ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
304 C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
305 C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
306 C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
307 //C_ASSERT(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
308 //C_ASSERT(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
309 C_ASSERT(FIELD_OFFSET(KPCR, IRR) == KPCR_IRR);
310 C_ASSERT(FIELD_OFFSET(KPCR, IDR) == KPCR_IDR);
311 C_ASSERT(FIELD_OFFSET(KPCR, Irql) == KPCR_IRQL);
312 C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);
313 C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
314 C_ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
315 C_ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
316 C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, DpcStack) == KPCR_PRCB_DPC_STACK);
317 C_ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
318
319 #endif /* INCLUDE_INTERNAL_NTOSKRNL_H */