Copy i8042prt driver from 0.3.1 branch to 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 #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 VOID IoInit(VOID);
64 VOID IoInit2(BOOLEAN BootLog);
65 VOID NTAPI IoInit3(VOID);
66 BOOLEAN NTAPI ObInit(VOID);
67 VOID CmInitializeRegistry(VOID);
68 VOID NTAPI CmInitHives(BOOLEAN SetupBoot);
69 VOID CmInit2(PCHAR CommandLine);
70 VOID CmShutdownRegistry(VOID);
71 BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize);
72 BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize);
73 VOID KdInitSystem(ULONG Reserved, PLOADER_PARAMETER_BLOCK LoaderBlock);
74
75 /* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */
76 BOOLEAN FASTCALL
77 RtlpCreateUnicodeString(
78 IN OUT PUNICODE_STRING UniDest,
79 IN PCWSTR Source,
80 IN POOL_TYPE PoolType);
81
82 VOID
83 NTAPI
84 RtlpLogException(IN PEXCEPTION_RECORD ExceptionRecord,
85 IN PCONTEXT ContextRecord,
86 IN PVOID ContextData,
87 IN ULONG Size);
88
89 /* FIXME: Interlocked functions that need to be made into a public header */
90 #ifdef __GNUC__
91 FORCEINLINE
92 LONG
93 InterlockedAnd(IN OUT LONG volatile *Target,
94 IN LONG Set)
95 {
96 LONG i;
97 LONG j;
98
99 j = *Target;
100 do {
101 i = j;
102 j = InterlockedCompareExchange((PLONG)Target,
103 i & Set,
104 i);
105
106 } while (i != j);
107
108 return j;
109 }
110
111 FORCEINLINE
112 LONG
113 InterlockedOr(IN OUT LONG volatile *Target,
114 IN LONG Set)
115 {
116 LONG i;
117 LONG j;
118
119 j = *Target;
120 do {
121 i = j;
122 j = InterlockedCompareExchange((PLONG)Target,
123 i | Set,
124 i);
125
126 } while (i != j);
127
128 return j;
129 }
130 #endif
131
132 /*
133 * generic information class probing code
134 */
135
136 #define ICIF_QUERY 0x1
137 #define ICIF_SET 0x2
138 #define ICIF_QUERY_SIZE_VARIABLE 0x4
139 #define ICIF_SET_SIZE_VARIABLE 0x8
140 #define ICIF_SIZE_VARIABLE (ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE)
141
142 typedef struct _INFORMATION_CLASS_INFO
143 {
144 ULONG RequiredSizeQUERY;
145 ULONG RequiredSizeSET;
146 ULONG AlignmentSET;
147 ULONG AlignmentQUERY;
148 ULONG Flags;
149 } INFORMATION_CLASS_INFO, *PINFORMATION_CLASS_INFO;
150
151 #define ICI_SQ_SAME(Type, Alignment, Flags) \
152 { Type, Type, Alignment, Alignment, Flags }
153
154 #define ICI_SQ(TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags) \
155 { TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags }
156
157 //
158 // TEMPORARY
159 //
160 #define IQS_SAME(Type, Alignment, Flags) \
161 { sizeof(Type), sizeof(Type), sizeof(Alignment), sizeof(Alignment), Flags }
162
163 #define IQS(TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags) \
164 { sizeof(TypeQuery), sizeof(TypeSet), sizeof(AlignmentQuery), sizeof(AlignmentSet), Flags }
165
166 FORCEINLINE
167 NTSTATUS
168 DefaultSetInfoBufferCheck(ULONG Class,
169 const INFORMATION_CLASS_INFO *ClassList,
170 ULONG ClassListEntries,
171 PVOID Buffer,
172 ULONG BufferLength,
173 KPROCESSOR_MODE PreviousMode)
174 {
175 NTSTATUS Status = STATUS_SUCCESS;
176
177 if (Class >= 0 && Class < ClassListEntries)
178 {
179 if (!(ClassList[Class].Flags & ICIF_SET))
180 {
181 Status = STATUS_INVALID_INFO_CLASS;
182 }
183 else if (ClassList[Class].RequiredSizeSET > 0 &&
184 BufferLength != ClassList[Class].RequiredSizeSET)
185 {
186 if (!(ClassList[Class].Flags & ICIF_SET_SIZE_VARIABLE))
187 {
188 Status = STATUS_INFO_LENGTH_MISMATCH;
189 }
190 }
191
192 if (NT_SUCCESS(Status))
193 {
194 if (PreviousMode != KernelMode)
195 {
196 _SEH_TRY
197 {
198 ProbeForRead(Buffer,
199 BufferLength,
200 ClassList[Class].AlignmentSET);
201 }
202 _SEH_HANDLE
203 {
204 Status = _SEH_GetExceptionCode();
205 }
206 _SEH_END;
207 }
208 }
209 }
210 else
211 Status = STATUS_INVALID_INFO_CLASS;
212
213 return Status;
214 }
215
216 FORCEINLINE
217 NTSTATUS
218 DefaultQueryInfoBufferCheck(ULONG Class,
219 const INFORMATION_CLASS_INFO *ClassList,
220 ULONG ClassListEntries,
221 PVOID Buffer,
222 ULONG BufferLength,
223 PULONG ReturnLength,
224 KPROCESSOR_MODE PreviousMode)
225 {
226 NTSTATUS Status = STATUS_SUCCESS;
227
228 if (Class >= 0 && Class < ClassListEntries)
229 {
230 if (!(ClassList[Class].Flags & ICIF_QUERY))
231 {
232 Status = STATUS_INVALID_INFO_CLASS;
233 }
234 else if (ClassList[Class].RequiredSizeQUERY > 0 &&
235 BufferLength != ClassList[Class].RequiredSizeQUERY)
236 {
237 if (!(ClassList[Class].Flags & ICIF_QUERY_SIZE_VARIABLE))
238 {
239 Status = STATUS_INFO_LENGTH_MISMATCH;
240 }
241 }
242
243 if (NT_SUCCESS(Status))
244 {
245 if (PreviousMode != KernelMode)
246 {
247 _SEH_TRY
248 {
249 if (Buffer != NULL)
250 {
251 ProbeForWrite(Buffer,
252 BufferLength,
253 ClassList[Class].AlignmentQUERY);
254 }
255
256 if (ReturnLength != NULL)
257 {
258 ProbeForWriteUlong(ReturnLength);
259 }
260 }
261 _SEH_HANDLE
262 {
263 Status = _SEH_GetExceptionCode();
264 }
265 _SEH_END;
266 }
267 }
268 }
269 else
270 Status = STATUS_INVALID_INFO_CLASS;
271
272 return Status;
273 }
274
275 /*
276 * Use IsPointerOffset to test whether a pointer should be interpreted as an offset
277 * or as a pointer
278 */
279 #if defined(_X86_) || defined(_M_AMD64)
280
281 /* for x86 and x86-64 the MSB is 1 so we can simply test on that */
282 #define IsPointerOffset(Ptr) ((LONG_PTR)(Ptr) >= 0)
283
284 #elif defined(_IA64_)
285
286 /* on Itanium if the 24 most significant bits are set, we're not dealing with
287 offsets anymore. */
288 #define IsPointerOffset(Ptr) (((ULONG_PTR)(Ptr) & 0xFFFFFF0000000000ULL) == 0)
289
290 #else
291 #error IsPointerOffset() needs to be defined for this architecture
292 #endif
293
294 #endif
295
296 C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SystemCall) == 0x300);
297 C_ASSERT(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
298 C_ASSERT(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
299 C_ASSERT(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
300 C_ASSERT(FIELD_OFFSET(KTHREAD, NpxState) == KTHREAD_NPX_STATE);
301 C_ASSERT(FIELD_OFFSET(KTHREAD, ServiceTable) == KTHREAD_SERVICE_TABLE);
302 C_ASSERT(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
303 C_ASSERT(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
304 C_ASSERT(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
305 C_ASSERT(FIELD_OFFSET(KTHREAD, ApcState.Process) == KTHREAD_APCSTATE_PROCESS);
306 C_ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == KPROCESS_DIRECTORY_TABLE_BASE);
307 C_ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
308 C_ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
309 C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
310 C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
311 C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
312 //C_ASSERT(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
313 //C_ASSERT(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
314 C_ASSERT(FIELD_OFFSET(KPCR, IRR) == KPCR_IRR);
315 C_ASSERT(FIELD_OFFSET(KPCR, IDR) == KPCR_IDR);
316 C_ASSERT(FIELD_OFFSET(KPCR, Irql) == KPCR_IRQL);
317 C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);
318 C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
319 C_ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
320 C_ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
321 C_ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
322
323 #endif /* INCLUDE_INTERNAL_NTOSKRNL_H */