xref: /reactos/ntoskrnl/ob/obinit.c (revision 4c63ed5a)
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