- KdDebuggerNotPresent should be FALSE by default.
[reactos.git] / reactos / ntoskrnl / ob / obinit.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ob/init.c
5 * PURPOSE: Handles Object Manager Initialization and Shutdown
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Eric Kohl
8 * Thomas Weidenmueller (w3seek@reactos.org)
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16
17 /* GLOBALS *******************************************************************/
18
19 GENERIC_MAPPING ObpTypeMapping =
20 {
21 STANDARD_RIGHTS_READ,
22 STANDARD_RIGHTS_WRITE,
23 STANDARD_RIGHTS_EXECUTE,
24 0x000F0001
25 };
26
27 GENERIC_MAPPING ObpDirectoryMapping =
28 {
29 STANDARD_RIGHTS_READ | DIRECTORY_QUERY |
30 DIRECTORY_TRAVERSE,
31 STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY |
32 DIRECTORY_CREATE_OBJECT,
33 STANDARD_RIGHTS_EXECUTE | DIRECTORY_QUERY |
34 DIRECTORY_TRAVERSE,
35 DIRECTORY_ALL_ACCESS
36 };
37
38 GENERIC_MAPPING ObpSymbolicLinkMapping =
39 {
40 STANDARD_RIGHTS_READ | SYMBOLIC_LINK_QUERY,
41 STANDARD_RIGHTS_WRITE,
42 STANDARD_RIGHTS_EXECUTE | SYMBOLIC_LINK_QUERY,
43 SYMBOLIC_LINK_ALL_ACCESS
44 };
45
46 PDEVICE_MAP ObSystemDeviceMap = NULL;
47 ULONG ObpTraceLevel = OB_HANDLE_DEBUG | OB_REFERENCE_DEBUG;
48
49 VOID
50 NTAPI
51 PsInitializeQuotaSystem(VOID);
52
53 ULONG ObpInitializationPhase;
54
55 /* PRIVATE FUNCTIONS *********************************************************/
56
57 BOOLEAN
58 INIT_FUNCTION
59 NTAPI
60 ObInit2(VOID)
61 {
62 CCHAR i;
63 PKPRCB Prcb;
64 PNPAGED_LOOKASIDE_LIST CurrentList = NULL;
65
66 /* Now allocate the per-processor lists */
67 for (i = 0; i < KeNumberProcessors; i++)
68 {
69 /* Get the PRCB for this CPU */
70 Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb;
71
72 /* Set the OBJECT_CREATE_INFORMATION List */
73 Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCiLookasideList.L;
74 CurrentList = ExAllocatePoolWithTag(NonPagedPool,
75 sizeof(NPAGED_LOOKASIDE_LIST),
76 TAG('O', 'b', 'C', 'I'));
77 if (CurrentList)
78 {
79 /* Initialize it */
80 ExInitializeNPagedLookasideList(CurrentList,
81 NULL,
82 NULL,
83 0,
84 sizeof(OBJECT_CREATE_INFORMATION),
85 TAG('O', 'b', 'C', 'I'),
86 32);
87 }
88 else
89 {
90 /* No list, use the static buffer */
91 CurrentList = &ObpCiLookasideList;
92 }
93
94 /* Link it */
95 Prcb->PPLookasideList[LookasideCreateInfoList].P = &CurrentList->L;
96
97 /* Set the captured UNICODE_STRING Object Name List */
98 Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNmLookasideList.L;
99 CurrentList = ExAllocatePoolWithTag(NonPagedPool,
100 sizeof(NPAGED_LOOKASIDE_LIST),
101 TAG('O', 'b', 'N', 'M'));
102 if (CurrentList)
103 {
104 /* Initialize it */
105 ExInitializeNPagedLookasideList(CurrentList,
106 NULL,
107 NULL,
108 0,
109 248,
110 TAG('O', 'b', 'N', 'M'),
111 16);
112 }
113 else
114 {
115 /* No list, use the static buffer */
116 CurrentList = &ObpNmLookasideList;
117 }
118
119 /* Link it */
120 Prcb->PPLookasideList[LookasideNameBufferList].P = &CurrentList->L;
121 }
122
123 return TRUE;
124 }
125
126 BOOLEAN
127 INIT_FUNCTION
128 NTAPI
129 ObInit(VOID)
130 {
131 OBJECT_ATTRIBUTES ObjectAttributes;
132 UNICODE_STRING Name;
133 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
134 OBP_LOOKUP_CONTEXT Context;
135 HANDLE Handle;
136 PKPRCB Prcb = KeGetCurrentPrcb();
137 PLIST_ENTRY ListHead, NextEntry;
138 POBJECT_HEADER Header;
139 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
140 POBJECT_HEADER_NAME_INFO NameInfo;
141 NTSTATUS Status;
142
143 /* Check if this is actually Phase 1 initialization */
144 if (ObpInitializationPhase != 0) goto ObPostPhase0;
145
146 /* Initialize the OBJECT_CREATE_INFORMATION List */
147 ExInitializeNPagedLookasideList(&ObpCiLookasideList,
148 NULL,
149 NULL,
150 0,
151 sizeof(OBJECT_CREATE_INFORMATION),
152 TAG('O', 'b', 'C', 'I'),
153 32);
154
155 /* Set the captured UNICODE_STRING Object Name List */
156 ExInitializeNPagedLookasideList(&ObpNmLookasideList,
157 NULL,
158 NULL,
159 0,
160 248,
161 TAG('O', 'b', 'N', 'M'),
162 16);
163
164 /* Temporarily setup both pointers to the shared list */
165 Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCiLookasideList.L;
166 Prcb->PPLookasideList[LookasideCreateInfoList].P = &ObpCiLookasideList.L;
167 Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNmLookasideList.L;
168 Prcb->PPLookasideList[LookasideNameBufferList].P = &ObpNmLookasideList.L;
169
170 /* Initialize the security descriptor cache */
171 ObpInitSdCache();
172
173 /* Initialize the Default Event */
174 KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
175
176 /* Setup default access for the system process */
177 PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
178 PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;
179
180 /* Setup the Object Reaper */
181 ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);
182
183 /* Initialize default Quota block */
184 PsInitializeQuotaSystem();
185
186 /* Create kernel handle table */
187 PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable(NULL);
188 ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable;
189
190 /* Create the Type Type */
191 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
192 RtlInitUnicodeString(&Name, L"Type");
193 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
194 ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
195 ObjectTypeInitializer.UseDefaultObject = TRUE;
196 ObjectTypeInitializer.MaintainTypeList = TRUE;
197 ObjectTypeInitializer.PoolType = NonPagedPool;
198 ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
199 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
200 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
201 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObTypeObjectType);
202
203 /* Create the Directory Type */
204 RtlInitUnicodeString(&Name, L"Directory");
205 ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
206 ObjectTypeInitializer.UseDefaultObject = FALSE;
207 ObjectTypeInitializer.MaintainTypeList = FALSE;
208 ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
209 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
210 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObDirectoryType);
211
212 /* Create 'symbolic link' object type */
213 RtlInitUnicodeString(&Name, L"SymbolicLink");
214 ObjectTypeInitializer.DefaultNonPagedPoolCharge =
215 sizeof(OBJECT_SYMBOLIC_LINK);
216 ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
217 ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
218 ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
219 ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
220 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObSymbolicLinkType);
221
222 /* Phase 0 initialization complete */
223 ObpInitializationPhase++;
224 return TRUE;
225
226 ObPostPhase0:
227
228 /* Re-initialize lookaside lists */
229 ObInit2();
230
231 /* Initialize Object Types directory attributes */
232 RtlInitUnicodeString(&Name, L"\\");
233 InitializeObjectAttributes(&ObjectAttributes,
234 &Name,
235 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
236 NULL,
237 SePublicDefaultUnrestrictedSd);
238
239 /* Create the directory */
240 Status = NtCreateDirectoryObject(&Handle,
241 DIRECTORY_ALL_ACCESS,
242 &ObjectAttributes);
243 if (!NT_SUCCESS(Status)) return FALSE;
244
245 /* Get a handle to it */
246 Status = ObReferenceObjectByHandle(Handle,
247 0,
248 ObDirectoryType,
249 KernelMode,
250 (PVOID*)&NameSpaceRoot,
251 NULL);
252 if (!NT_SUCCESS(Status)) return FALSE;
253
254 /* Close the extra handle */
255 Status = NtClose(Handle);
256 if (!NT_SUCCESS(Status)) return FALSE;
257
258 /* Initialize Object Types directory attributes */
259 RtlInitUnicodeString(&Name, L"\\ObjectTypes");
260 InitializeObjectAttributes(&ObjectAttributes,
261 &Name,
262 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
263 NULL,
264 NULL);
265
266 /* Create the directory */
267 Status = NtCreateDirectoryObject(&Handle,
268 DIRECTORY_ALL_ACCESS,
269 &ObjectAttributes);
270 if (!NT_SUCCESS(Status)) return FALSE;
271
272 /* Get a handle to it */
273 Status = ObReferenceObjectByHandle(Handle,
274 0,
275 ObDirectoryType,
276 KernelMode,
277 (PVOID*)&ObpTypeDirectoryObject,
278 NULL);
279 if (!NT_SUCCESS(Status)) return FALSE;
280
281 /* Close the extra handle */
282 Status = NtClose(Handle);
283 if (!NT_SUCCESS(Status)) return FALSE;
284
285 /* Initialize lookup context */
286 ObpInitializeDirectoryLookup(&Context);
287
288 /* Lock it */
289 ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
290
291 /* Loop the object types */
292 ListHead = &ObTypeObjectType->TypeList;
293 NextEntry = ListHead->Flink;
294 while (ListHead != NextEntry)
295 {
296 /* Get the creator info from the list */
297 CreatorInfo = CONTAINING_RECORD(NextEntry,
298 OBJECT_HEADER_CREATOR_INFO,
299 TypeList);
300
301 /* Recover the header and the name header from the creator info */
302 Header = (POBJECT_HEADER)(CreatorInfo + 1);
303 NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);
304
305 /* Make sure we have a name, and aren't inserted yet */
306 if ((NameInfo) && !(NameInfo->Directory))
307 {
308 /* Do the initial lookup to setup the context */
309 if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
310 &NameInfo->Name,
311 OBJ_CASE_INSENSITIVE,
312 FALSE,
313 &Context))
314 {
315 /* Insert this object type */
316 ObpInsertEntryDirectory(ObpTypeDirectoryObject,
317 &Context,
318 Header);
319 }
320 }
321
322 /* Move to the next entry */
323 NextEntry = NextEntry->Flink;
324 }
325
326 /* Cleanup after lookup */
327 ObpCleanupDirectoryLookup(&Context);
328
329 /* Initialize DOS Devices Directory and related Symbolic Links */
330 Status = ObpCreateDosDevicesDirectory();
331 if (!NT_SUCCESS(Status)) return FALSE;
332 return TRUE;
333 }
334
335 /* EOF */