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