1c2c66affSColin Finck /*
2c2c66affSColin Finck * PROJECT: ReactOS Kernel
3c2c66affSColin Finck * LICENSE: GPL - See COPYING in the top level directory
4c2c66affSColin Finck * FILE: ntoskrnl/ob/obinit.c
5c2c66affSColin Finck * PURPOSE: Handles Object Manager Initialization and Shutdown
6c2c66affSColin Finck * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7c2c66affSColin Finck * Eric Kohl
8c2c66affSColin Finck * Thomas Weidenmueller (w3seek@reactos.org)
9c2c66affSColin Finck */
10c2c66affSColin Finck
11c2c66affSColin Finck /* INCLUDES ******************************************************************/
12c2c66affSColin Finck
13c2c66affSColin Finck #include <ntoskrnl.h>
14c2c66affSColin Finck #define NDEBUG
15c2c66affSColin Finck #include <debug.h>
16c2c66affSColin Finck
17c2c66affSColin Finck /* GLOBALS *******************************************************************/
18c2c66affSColin Finck
19c2c66affSColin Finck GENERIC_MAPPING ObpTypeMapping =
20c2c66affSColin Finck {
21c2c66affSColin Finck STANDARD_RIGHTS_READ,
22c2c66affSColin Finck STANDARD_RIGHTS_WRITE,
23c2c66affSColin Finck STANDARD_RIGHTS_EXECUTE,
24c2c66affSColin Finck 0x000F0001
25c2c66affSColin Finck };
26c2c66affSColin Finck
27c2c66affSColin Finck GENERIC_MAPPING ObpDirectoryMapping =
28c2c66affSColin Finck {
29c2c66affSColin Finck STANDARD_RIGHTS_READ | DIRECTORY_QUERY |
30c2c66affSColin Finck DIRECTORY_TRAVERSE,
31c2c66affSColin Finck STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY |
32c2c66affSColin Finck DIRECTORY_CREATE_OBJECT,
33c2c66affSColin Finck STANDARD_RIGHTS_EXECUTE | DIRECTORY_QUERY |
34c2c66affSColin Finck DIRECTORY_TRAVERSE,
35c2c66affSColin Finck DIRECTORY_ALL_ACCESS
36c2c66affSColin Finck };
37c2c66affSColin Finck
38c2c66affSColin Finck GENERIC_MAPPING ObpSymbolicLinkMapping =
39c2c66affSColin Finck {
40c2c66affSColin Finck STANDARD_RIGHTS_READ | SYMBOLIC_LINK_QUERY,
41c2c66affSColin Finck STANDARD_RIGHTS_WRITE,
42c2c66affSColin Finck STANDARD_RIGHTS_EXECUTE | SYMBOLIC_LINK_QUERY,
43c2c66affSColin Finck SYMBOLIC_LINK_ALL_ACCESS
44c2c66affSColin Finck };
45c2c66affSColin Finck
46c2c66affSColin Finck PDEVICE_MAP ObSystemDeviceMap = NULL;
47c2c66affSColin Finck ULONG ObpTraceLevel = 0;
48c2c66affSColin Finck
495c7ce447SVictor Perevertkin CODE_SEG("INIT")
50c2c66affSColin Finck VOID
51c2c66affSColin Finck NTAPI
52c2c66affSColin Finck PsInitializeQuotaSystem(VOID);
53c2c66affSColin Finck
54c2c66affSColin Finck ULONG ObpInitializationPhase;
55c2c66affSColin Finck
56a33a69b3SPierre Schweitzer ULONG ObpObjectSecurityMode = 0;
571c4e4459SPierre Schweitzer ULONG ObpProtectionMode = 0;
58a33a69b3SPierre Schweitzer
59c2c66affSColin Finck /* PRIVATE FUNCTIONS *********************************************************/
60c2c66affSColin Finck
61c2c66affSColin Finck static
625c7ce447SVictor Perevertkin CODE_SEG("INIT")
63c2c66affSColin Finck NTSTATUS
64c2c66affSColin Finck NTAPI
ObpCreateKernelObjectsSD(OUT PSECURITY_DESCRIPTOR * SecurityDescriptor)65c2c66affSColin Finck ObpCreateKernelObjectsSD(OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
66c2c66affSColin Finck {
67c2c66affSColin Finck PSECURITY_DESCRIPTOR Sd = NULL;
68c2c66affSColin Finck PACL Dacl;
69c2c66affSColin Finck ULONG AclSize, SdSize;
70c2c66affSColin Finck NTSTATUS Status;
71c2c66affSColin Finck
72c2c66affSColin Finck AclSize = sizeof(ACL) +
73c2c66affSColin Finck sizeof(ACE) + RtlLengthSid(SeWorldSid) +
74c2c66affSColin Finck sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid) +
75c2c66affSColin Finck sizeof(ACE) + RtlLengthSid(SeLocalSystemSid);
76c2c66affSColin Finck
77c2c66affSColin Finck SdSize = sizeof(SECURITY_DESCRIPTOR) + AclSize;
78c2c66affSColin Finck
79c2c66affSColin Finck /* Allocate the SD and ACL */
80c2c66affSColin Finck Sd = ExAllocatePoolWithTag(PagedPool, SdSize, TAG_SD);
81c2c66affSColin Finck if (Sd == NULL)
82c2c66affSColin Finck {
83c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
84c2c66affSColin Finck }
85c2c66affSColin Finck
86c2c66affSColin Finck /* Initialize the SD */
87c2c66affSColin Finck Status = RtlCreateSecurityDescriptor(Sd,
88c2c66affSColin Finck SECURITY_DESCRIPTOR_REVISION);
89c2c66affSColin Finck if (!NT_SUCCESS(Status))
90c2c66affSColin Finck goto done;
91c2c66affSColin Finck
92c2c66affSColin Finck Dacl = (PACL)((INT_PTR)Sd + sizeof(SECURITY_DESCRIPTOR));
93c2c66affSColin Finck
94c2c66affSColin Finck /* Initialize the DACL */
95c2c66affSColin Finck RtlCreateAcl(Dacl, AclSize, ACL_REVISION);
96c2c66affSColin Finck
97c2c66affSColin Finck /* Add the ACEs */
98c2c66affSColin Finck RtlAddAccessAllowedAce(Dacl,
99c2c66affSColin Finck ACL_REVISION,
100c2c66affSColin Finck GENERIC_READ,
101c2c66affSColin Finck SeWorldSid);
102c2c66affSColin Finck
103c2c66affSColin Finck RtlAddAccessAllowedAce(Dacl,
104c2c66affSColin Finck ACL_REVISION,
105c2c66affSColin Finck GENERIC_ALL,
106c2c66affSColin Finck SeAliasAdminsSid);
107c2c66affSColin Finck
108c2c66affSColin Finck RtlAddAccessAllowedAce(Dacl,
109c2c66affSColin Finck ACL_REVISION,
110c2c66affSColin Finck GENERIC_ALL,
111c2c66affSColin Finck SeLocalSystemSid);
112c2c66affSColin Finck
113c2c66affSColin Finck /* Attach the DACL to the SD */
114c2c66affSColin Finck Status = RtlSetDaclSecurityDescriptor(Sd,
115c2c66affSColin Finck TRUE,
116c2c66affSColin Finck Dacl,
117c2c66affSColin Finck FALSE);
118c2c66affSColin Finck if (!NT_SUCCESS(Status))
119c2c66affSColin Finck goto done;
120c2c66affSColin Finck
121c2c66affSColin Finck *SecurityDescriptor = Sd;
122c2c66affSColin Finck
123c2c66affSColin Finck done:
124c2c66affSColin Finck if (!NT_SUCCESS(Status))
125c2c66affSColin Finck {
126c2c66affSColin Finck if (Sd != NULL)
127c2c66affSColin Finck ExFreePoolWithTag(Sd, TAG_SD);
128c2c66affSColin Finck }
129c2c66affSColin Finck
130c2c66affSColin Finck return Status;
131c2c66affSColin Finck }
132c2c66affSColin Finck
1335c7ce447SVictor Perevertkin CODE_SEG("INIT")
134b20f8151SSerge Gautherie BOOLEAN
135c2c66affSColin Finck NTAPI
ObInit2(VOID)136c2c66affSColin Finck ObInit2(VOID)
137c2c66affSColin Finck {
138c2c66affSColin Finck CCHAR i;
139c2c66affSColin Finck PKPRCB Prcb;
140c2c66affSColin Finck PGENERAL_LOOKASIDE CurrentList = NULL;
141c2c66affSColin Finck
142c2c66affSColin Finck /* Now allocate the per-processor lists */
143c2c66affSColin Finck for (i = 0; i < KeNumberProcessors; i++)
144c2c66affSColin Finck {
145c2c66affSColin Finck /* Get the PRCB for this CPU */
146c2c66affSColin Finck Prcb = KiProcessorBlock[(int)i];
147c2c66affSColin Finck
148c2c66affSColin Finck /* Set the OBJECT_CREATE_INFORMATION List */
149c2c66affSColin Finck Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList;
150c2c66affSColin Finck CurrentList = ExAllocatePoolWithTag(NonPagedPool,
151c2c66affSColin Finck sizeof(GENERAL_LOOKASIDE),
152c2c66affSColin Finck 'ICbO');
153c2c66affSColin Finck if (CurrentList)
154c2c66affSColin Finck {
155c2c66affSColin Finck /* Initialize it */
156c2c66affSColin Finck ExInitializeSystemLookasideList(CurrentList,
157c2c66affSColin Finck NonPagedPool,
158c2c66affSColin Finck sizeof(OBJECT_CREATE_INFORMATION),
159c2c66affSColin Finck 'ICbO',
160c2c66affSColin Finck 32,
161c2c66affSColin Finck &ExSystemLookasideListHead);
162c2c66affSColin Finck }
163c2c66affSColin Finck else
164c2c66affSColin Finck {
165c2c66affSColin Finck /* No list, use the static buffer */
166c2c66affSColin Finck CurrentList = &ObpCreateInfoLookasideList;
167c2c66affSColin Finck }
168c2c66affSColin Finck
169c2c66affSColin Finck /* Link it */
170c2c66affSColin Finck Prcb->PPLookasideList[LookasideCreateInfoList].P = CurrentList;
171c2c66affSColin Finck
172c2c66affSColin Finck /* Set the captured UNICODE_STRING Object Name List */
173c2c66affSColin Finck Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList;
174c2c66affSColin Finck CurrentList = ExAllocatePoolWithTag(NonPagedPool,
175c2c66affSColin Finck sizeof(GENERAL_LOOKASIDE),
176c2c66affSColin Finck 'MNbO');
177c2c66affSColin Finck if (CurrentList)
178c2c66affSColin Finck {
179c2c66affSColin Finck /* Initialize it */
180c2c66affSColin Finck ExInitializeSystemLookasideList(CurrentList,
181c2c66affSColin Finck PagedPool,
182c2c66affSColin Finck 248,
183c2c66affSColin Finck 'MNbO',
184c2c66affSColin Finck 16,
185c2c66affSColin Finck &ExSystemLookasideListHead);
186c2c66affSColin Finck }
187c2c66affSColin Finck else
188c2c66affSColin Finck {
189c2c66affSColin Finck /* No list, use the static buffer */
190c2c66affSColin Finck CurrentList = &ObpNameBufferLookasideList;
191c2c66affSColin Finck }
192c2c66affSColin Finck
193c2c66affSColin Finck /* Link it */
194c2c66affSColin Finck Prcb->PPLookasideList[LookasideNameBufferList].P = CurrentList;
195c2c66affSColin Finck }
196c2c66affSColin Finck
197c2c66affSColin Finck return TRUE;
198c2c66affSColin Finck }
199c2c66affSColin Finck
2005c7ce447SVictor Perevertkin CODE_SEG("INIT")
201b20f8151SSerge Gautherie BOOLEAN
202c2c66affSColin Finck NTAPI
ObInitSystem(VOID)203c2c66affSColin Finck ObInitSystem(VOID)
204c2c66affSColin Finck {
205c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes;
206c2c66affSColin Finck UNICODE_STRING Name;
207c2c66affSColin Finck OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
208c2c66affSColin Finck OBP_LOOKUP_CONTEXT Context;
209c2c66affSColin Finck HANDLE Handle;
210c2c66affSColin Finck PKPRCB Prcb = KeGetCurrentPrcb();
211c2c66affSColin Finck PLIST_ENTRY ListHead, NextEntry;
212c2c66affSColin Finck POBJECT_HEADER Header;
213c2c66affSColin Finck POBJECT_HEADER_CREATOR_INFO CreatorInfo;
214c2c66affSColin Finck POBJECT_HEADER_NAME_INFO NameInfo;
215c2c66affSColin Finck PSECURITY_DESCRIPTOR KernelObjectsSD = NULL;
216c2c66affSColin Finck NTSTATUS Status;
217c2c66affSColin Finck
218c2c66affSColin Finck /* Check if this is actually Phase 1 initialization */
219c2c66affSColin Finck if (ObpInitializationPhase != 0) goto ObPostPhase0;
220c2c66affSColin Finck
221c2c66affSColin Finck /* Initialize the OBJECT_CREATE_INFORMATION List */
222c2c66affSColin Finck ExInitializeSystemLookasideList(&ObpCreateInfoLookasideList,
223c2c66affSColin Finck NonPagedPool,
224c2c66affSColin Finck sizeof(OBJECT_CREATE_INFORMATION),
225c2c66affSColin Finck 'ICbO',
226c2c66affSColin Finck 32,
227c2c66affSColin Finck &ExSystemLookasideListHead);
228c2c66affSColin Finck
229c2c66affSColin Finck /* Set the captured UNICODE_STRING Object Name List */
230c2c66affSColin Finck ExInitializeSystemLookasideList(&ObpNameBufferLookasideList,
231c2c66affSColin Finck PagedPool,
232c2c66affSColin Finck 248,
233c2c66affSColin Finck 'MNbO',
234c2c66affSColin Finck 16,
235c2c66affSColin Finck &ExSystemLookasideListHead);
236c2c66affSColin Finck
237c2c66affSColin Finck /* Temporarily setup both pointers to the shared list */
238c2c66affSColin Finck Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList;
239c2c66affSColin Finck Prcb->PPLookasideList[LookasideCreateInfoList].P = &ObpCreateInfoLookasideList;
240c2c66affSColin Finck Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList;
241c2c66affSColin Finck Prcb->PPLookasideList[LookasideNameBufferList].P = &ObpNameBufferLookasideList;
242c2c66affSColin Finck
243c2c66affSColin Finck /* Initialize the security descriptor cache */
244c2c66affSColin Finck ObpInitSdCache();
245c2c66affSColin Finck
246c2c66affSColin Finck /* Initialize the Default Event */
247c2c66affSColin Finck KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE);
248c2c66affSColin Finck
249c2c66affSColin Finck /* Initialize the Dos Device Map mutex */
250c2c66affSColin Finck KeInitializeGuardedMutex(&ObpDeviceMapLock);
251c2c66affSColin Finck
252c2c66affSColin Finck /* Setup default access for the system process */
253c2c66affSColin Finck PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
254c2c66affSColin Finck PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;
255c2c66affSColin Finck
256c2c66affSColin Finck /* Setup the Object Reaper */
257c2c66affSColin Finck ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);
258c2c66affSColin Finck
259c2c66affSColin Finck /* Initialize default Quota block */
260c2c66affSColin Finck PsInitializeQuotaSystem();
261c2c66affSColin Finck
262c2c66affSColin Finck /* Create kernel handle table */
263c2c66affSColin Finck PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable(NULL);
264c2c66affSColin Finck ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable;
265c2c66affSColin Finck
266c2c66affSColin Finck /* Create the Type Type */
267c2c66affSColin Finck RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
268c2c66affSColin Finck RtlInitUnicodeString(&Name, L"Type");
269c2c66affSColin Finck ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
270c2c66affSColin Finck ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
271c2c66affSColin Finck ObjectTypeInitializer.UseDefaultObject = TRUE;
272c2c66affSColin Finck ObjectTypeInitializer.MaintainTypeList = TRUE;
273c2c66affSColin Finck ObjectTypeInitializer.PoolType = NonPagedPool;
274c2c66affSColin Finck ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
275c2c66affSColin Finck ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
276c2c66affSColin Finck ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
277c2c66affSColin Finck ObjectTypeInitializer.DeleteProcedure = ObpDeleteObjectType;
278c2c66affSColin Finck ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpTypeObjectType);
279c2c66affSColin Finck
280c2c66affSColin Finck /* Create the Directory Type */
281c2c66affSColin Finck RtlInitUnicodeString(&Name, L"Directory");
282c2c66affSColin Finck ObjectTypeInitializer.PoolType = PagedPool;
283c2c66affSColin Finck ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
284c2c66affSColin Finck ObjectTypeInitializer.CaseInsensitive = TRUE;
285c2c66affSColin Finck ObjectTypeInitializer.MaintainTypeList = FALSE;
286c2c66affSColin Finck ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
287c2c66affSColin Finck ObjectTypeInitializer.DeleteProcedure = NULL;
288c2c66affSColin Finck ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
2892c909db2STimo Kreuzer ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpDirectoryObjectType);
2902c909db2STimo Kreuzer ObpDirectoryObjectType->TypeInfo.ValidAccessMask &= ~SYNCHRONIZE;
291c2c66affSColin Finck
292c2c66affSColin Finck /* Create 'symbolic link' object type */
293c2c66affSColin Finck RtlInitUnicodeString(&Name, L"SymbolicLink");
294c2c66affSColin Finck ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_SYMBOLIC_LINK);
295c2c66affSColin Finck ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
296c2c66affSColin Finck ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
297c2c66affSColin Finck ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
298c2c66affSColin Finck ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
2992c909db2STimo Kreuzer ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpSymbolicLinkObjectType);
3002c909db2STimo Kreuzer ObpSymbolicLinkObjectType->TypeInfo.ValidAccessMask &= ~SYNCHRONIZE;
301c2c66affSColin Finck
302c2c66affSColin Finck /* Phase 0 initialization complete */
303c2c66affSColin Finck ObpInitializationPhase++;
304c2c66affSColin Finck return TRUE;
305c2c66affSColin Finck
306c2c66affSColin Finck ObPostPhase0:
307c2c66affSColin Finck
308c2c66affSColin Finck /* Re-initialize lookaside lists */
309c2c66affSColin Finck ObInit2();
310c2c66affSColin Finck
311c2c66affSColin Finck /* Initialize Object Types directory attributes */
312c2c66affSColin Finck RtlInitUnicodeString(&Name, L"\\");
313c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes,
314c2c66affSColin Finck &Name,
315c2c66affSColin Finck OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
316c2c66affSColin Finck NULL,
317c2c66affSColin Finck SePublicDefaultUnrestrictedSd);
318c2c66affSColin Finck
319c2c66affSColin Finck /* Create the directory */
320c2c66affSColin Finck Status = NtCreateDirectoryObject(&Handle,
321c2c66affSColin Finck DIRECTORY_ALL_ACCESS,
322c2c66affSColin Finck &ObjectAttributes);
323c2c66affSColin Finck if (!NT_SUCCESS(Status)) return FALSE;
324c2c66affSColin Finck
325c2c66affSColin Finck /* Get a handle to it */
326c2c66affSColin Finck Status = ObReferenceObjectByHandle(Handle,
327c2c66affSColin Finck 0,
3282c909db2STimo Kreuzer ObpDirectoryObjectType,
329c2c66affSColin Finck KernelMode,
330c2c66affSColin Finck (PVOID*)&ObpRootDirectoryObject,
331c2c66affSColin Finck NULL);
332c2c66affSColin Finck if (!NT_SUCCESS(Status)) return FALSE;
333c2c66affSColin Finck
334c2c66affSColin Finck /* Close the extra handle */
335c2c66affSColin Finck Status = NtClose(Handle);
336c2c66affSColin Finck if (!NT_SUCCESS(Status)) return FALSE;
337c2c66affSColin Finck
338c2c66affSColin Finck /* Create a custom security descriptor for the KernelObjects directory */
339c2c66affSColin Finck Status = ObpCreateKernelObjectsSD(&KernelObjectsSD);
340c2c66affSColin Finck if (!NT_SUCCESS(Status))
341c2c66affSColin Finck return FALSE;
342c2c66affSColin Finck
343c2c66affSColin Finck /* Initialize the KernelObjects directory attributes */
344c2c66affSColin Finck RtlInitUnicodeString(&Name, L"\\KernelObjects");
345c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes,
346c2c66affSColin Finck &Name,
347c2c66affSColin Finck OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
348c2c66affSColin Finck NULL,
349c2c66affSColin Finck KernelObjectsSD);
350c2c66affSColin Finck
351c2c66affSColin Finck /* Create the directory */
352c2c66affSColin Finck Status = NtCreateDirectoryObject(&Handle,
353c2c66affSColin Finck DIRECTORY_ALL_ACCESS,
354c2c66affSColin Finck &ObjectAttributes);
355c2c66affSColin Finck ExFreePoolWithTag(KernelObjectsSD, TAG_SD);
356c2c66affSColin Finck if (!NT_SUCCESS(Status)) return FALSE;
357c2c66affSColin Finck
358c2c66affSColin Finck /* Close the extra handle */
359c2c66affSColin Finck Status = NtClose(Handle);
360c2c66affSColin Finck if (!NT_SUCCESS(Status)) return FALSE;
361c2c66affSColin Finck
362c2c66affSColin Finck /* Initialize ObjectTypes directory attributes */
363c2c66affSColin Finck RtlInitUnicodeString(&Name, L"\\ObjectTypes");
364c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes,
365c2c66affSColin Finck &Name,
366c2c66affSColin Finck OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
367c2c66affSColin Finck NULL,
368c2c66affSColin Finck NULL);
369c2c66affSColin Finck
370c2c66affSColin Finck /* Create the directory */
371c2c66affSColin Finck Status = NtCreateDirectoryObject(&Handle,
372c2c66affSColin Finck DIRECTORY_ALL_ACCESS,
373c2c66affSColin Finck &ObjectAttributes);
374c2c66affSColin Finck if (!NT_SUCCESS(Status)) return FALSE;
375c2c66affSColin Finck
376c2c66affSColin Finck /* Get a handle to it */
377c2c66affSColin Finck Status = ObReferenceObjectByHandle(Handle,
378c2c66affSColin Finck 0,
3792c909db2STimo Kreuzer ObpDirectoryObjectType,
380c2c66affSColin Finck KernelMode,
381c2c66affSColin Finck (PVOID*)&ObpTypeDirectoryObject,
382c2c66affSColin Finck NULL);
383c2c66affSColin Finck if (!NT_SUCCESS(Status)) return FALSE;
384c2c66affSColin Finck
385c2c66affSColin Finck /* Close the extra handle */
386c2c66affSColin Finck Status = NtClose(Handle);
387c2c66affSColin Finck if (!NT_SUCCESS(Status)) return FALSE;
388c2c66affSColin Finck
389*4c63ed5aSHermès Bélusca-Maïto /* Initialize the lookup context and lock it */
390c2c66affSColin Finck ObpInitializeLookupContext(&Context);
391*4c63ed5aSHermès Bélusca-Maïto ObpAcquireLookupContextLock(&Context, ObpTypeDirectoryObject);
392c2c66affSColin Finck
393c2c66affSColin Finck /* Loop the object types */
394c2c66affSColin Finck ListHead = &ObpTypeObjectType->TypeList;
395c2c66affSColin Finck NextEntry = ListHead->Flink;
396c2c66affSColin Finck while (ListHead != NextEntry)
397c2c66affSColin Finck {
398c2c66affSColin Finck /* Get the creator info from the list */
399c2c66affSColin Finck CreatorInfo = CONTAINING_RECORD(NextEntry,
400c2c66affSColin Finck OBJECT_HEADER_CREATOR_INFO,
401c2c66affSColin Finck TypeList);
402c2c66affSColin Finck
403c2c66affSColin Finck /* Recover the header and the name header from the creator info */
404c2c66affSColin Finck Header = (POBJECT_HEADER)(CreatorInfo + 1);
405c2c66affSColin Finck NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);
406c2c66affSColin Finck
407c2c66affSColin Finck /* Make sure we have a name, and aren't inserted yet */
408c2c66affSColin Finck if ((NameInfo) && !(NameInfo->Directory))
409c2c66affSColin Finck {
410c2c66affSColin Finck /* Do the initial lookup to setup the context */
411c2c66affSColin Finck if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
412c2c66affSColin Finck &NameInfo->Name,
413c2c66affSColin Finck OBJ_CASE_INSENSITIVE,
414c2c66affSColin Finck FALSE,
415c2c66affSColin Finck &Context))
416c2c66affSColin Finck {
417c2c66affSColin Finck /* Insert this object type */
418c2c66affSColin Finck ObpInsertEntryDirectory(ObpTypeDirectoryObject,
419c2c66affSColin Finck &Context,
420c2c66affSColin Finck Header);
421c2c66affSColin Finck }
422c2c66affSColin Finck }
423c2c66affSColin Finck
424c2c66affSColin Finck /* Move to the next entry */
425c2c66affSColin Finck NextEntry = NextEntry->Flink;
426c2c66affSColin Finck }
427c2c66affSColin Finck
428c2c66affSColin Finck /* Cleanup after lookup */
429c2c66affSColin Finck ObpReleaseLookupContext(&Context);
430c2c66affSColin Finck
431c2c66affSColin Finck /* Initialize DOS Devices Directory and related Symbolic Links */
432c2c66affSColin Finck Status = ObpCreateDosDevicesDirectory();
433c2c66affSColin Finck if (!NT_SUCCESS(Status)) return FALSE;
434c2c66affSColin Finck return TRUE;
435c2c66affSColin Finck }
436c2c66affSColin Finck
437c2c66affSColin Finck /* EOF */
438