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)
8 * Thomas Weidenmueller (w3seek@reactos.org)
11 /* INCLUDES ******************************************************************/
17 /* GLOBALS *******************************************************************/
19 GENERIC_MAPPING ObpTypeMapping
=
22 STANDARD_RIGHTS_WRITE
,
23 STANDARD_RIGHTS_EXECUTE
,
27 GENERIC_MAPPING ObpDirectoryMapping
=
29 STANDARD_RIGHTS_READ
| DIRECTORY_QUERY
|
31 STANDARD_RIGHTS_WRITE
| DIRECTORY_CREATE_SUBDIRECTORY
|
32 DIRECTORY_CREATE_OBJECT
,
33 STANDARD_RIGHTS_EXECUTE
| DIRECTORY_QUERY
|
38 GENERIC_MAPPING ObpSymbolicLinkMapping
=
40 STANDARD_RIGHTS_READ
| SYMBOLIC_LINK_QUERY
,
41 STANDARD_RIGHTS_WRITE
,
42 STANDARD_RIGHTS_EXECUTE
| SYMBOLIC_LINK_QUERY
,
43 SYMBOLIC_LINK_ALL_ACCESS
46 PDEVICE_MAP ObSystemDeviceMap
= NULL
;
47 ULONG ObpTraceLevel
= OB_HANDLE_DEBUG
| OB_REFERENCE_DEBUG
;
51 PsInitializeQuotaSystem(VOID
);
53 ULONG ObpInitializationPhase
;
55 /* PRIVATE FUNCTIONS *********************************************************/
64 PNPAGED_LOOKASIDE_LIST CurrentList
= NULL
;
66 /* Now allocate the per-processor lists */
67 for (i
= 0; i
< KeNumberProcessors
; i
++)
69 /* Get the PRCB for this CPU */
70 Prcb
= ((PKPCR
)(KPCR_BASE
+ i
* PAGE_SIZE
))->Prcb
;
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'));
80 ExInitializeNPagedLookasideList(CurrentList
,
84 sizeof(OBJECT_CREATE_INFORMATION
),
85 TAG('O', 'b', 'C', 'I'),
90 /* No list, use the static buffer */
91 CurrentList
= &ObpCiLookasideList
;
95 Prcb
->PPLookasideList
[LookasideCreateInfoList
].P
= &CurrentList
->L
;
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'));
105 ExInitializeNPagedLookasideList(CurrentList
,
110 TAG('O', 'b', 'N', 'M'),
115 /* No list, use the static buffer */
116 CurrentList
= &ObpNmLookasideList
;
120 Prcb
->PPLookasideList
[LookasideNameBufferList
].P
= &CurrentList
->L
;
131 OBJECT_ATTRIBUTES ObjectAttributes
;
133 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
134 OBP_LOOKUP_CONTEXT Context
;
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
;
143 /* Check if this is actually Phase 1 initialization */
144 if (ObpInitializationPhase
!= 0) goto ObPostPhase0
;
146 /* Initialize the OBJECT_CREATE_INFORMATION List */
147 ExInitializeNPagedLookasideList(&ObpCiLookasideList
,
151 sizeof(OBJECT_CREATE_INFORMATION
),
152 TAG('O', 'b', 'C', 'I'),
155 /* Set the captured UNICODE_STRING Object Name List */
156 ExInitializeNPagedLookasideList(&ObpNmLookasideList
,
161 TAG('O', 'b', 'N', 'M'),
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
;
170 /* Initialize the security descriptor cache */
173 /* Initialize the Default Event */
174 KeInitializeEvent(&ObpDefaultObject
, NotificationEvent
, TRUE
);
176 /* Setup default access for the system process */
177 PsGetCurrentProcess()->GrantedAccess
= PROCESS_ALL_ACCESS
;
178 PsGetCurrentThread()->GrantedAccess
= THREAD_ALL_ACCESS
;
180 /* Setup the Object Reaper */
181 ExInitializeWorkItem(&ObpReaperWorkItem
, ObpReapObject
, NULL
);
183 /* Initialize default Quota block */
184 PsInitializeQuotaSystem();
186 /* Create kernel handle table */
187 PsGetCurrentProcess()->ObjectTable
= ExCreateHandleTable(NULL
);
188 ObpKernelHandleTable
= PsGetCurrentProcess()->ObjectTable
;
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
);
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
);
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
);
222 /* Phase 0 initialization complete */
223 ObpInitializationPhase
++;
228 /* Re-initialize lookaside lists */
231 /* Initialize Object Types directory attributes */
232 RtlInitUnicodeString(&Name
, L
"\\");
233 InitializeObjectAttributes(&ObjectAttributes
,
235 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
237 SePublicDefaultUnrestrictedSd
);
239 /* Create the directory */
240 Status
= NtCreateDirectoryObject(&Handle
,
241 DIRECTORY_ALL_ACCESS
,
243 if (!NT_SUCCESS(Status
)) return FALSE
;
245 /* Get a handle to it */
246 Status
= ObReferenceObjectByHandle(Handle
,
250 (PVOID
*)&NameSpaceRoot
,
252 if (!NT_SUCCESS(Status
)) return FALSE
;
254 /* Close the extra handle */
255 Status
= NtClose(Handle
);
256 if (!NT_SUCCESS(Status
)) return FALSE
;
258 /* Initialize Object Types directory attributes */
259 RtlInitUnicodeString(&Name
, L
"\\ObjectTypes");
260 InitializeObjectAttributes(&ObjectAttributes
,
262 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
266 /* Create the directory */
267 Status
= NtCreateDirectoryObject(&Handle
,
268 DIRECTORY_ALL_ACCESS
,
270 if (!NT_SUCCESS(Status
)) return FALSE
;
272 /* Get a handle to it */
273 Status
= ObReferenceObjectByHandle(Handle
,
277 (PVOID
*)&ObpTypeDirectoryObject
,
279 if (!NT_SUCCESS(Status
)) return FALSE
;
281 /* Close the extra handle */
282 Status
= NtClose(Handle
);
283 if (!NT_SUCCESS(Status
)) return FALSE
;
285 /* Initialize lookup context */
286 ObpInitializeDirectoryLookup(&Context
);
289 ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject
, &Context
);
291 /* Loop the object types */
292 ListHead
= &ObTypeObjectType
->TypeList
;
293 NextEntry
= ListHead
->Flink
;
294 while (ListHead
!= NextEntry
)
296 /* Get the creator info from the list */
297 CreatorInfo
= CONTAINING_RECORD(NextEntry
,
298 OBJECT_HEADER_CREATOR_INFO
,
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
);
305 /* Make sure we have a name, and aren't inserted yet */
306 if ((NameInfo
) && !(NameInfo
->Directory
))
308 /* Do the initial lookup to setup the context */
309 if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject
,
311 OBJ_CASE_INSENSITIVE
,
315 /* Insert this object type */
316 ObpInsertEntryDirectory(ObpTypeDirectoryObject
,
322 /* Move to the next entry */
323 NextEntry
= NextEntry
->Flink
;
326 /* Cleanup after lookup */
327 ObpCleanupDirectoryLookup(&Context
);
329 /* Initialize DOS Devices Directory and related Symbolic Links */
330 Status
= ObpCreateDosDevicesDirectory();
331 if (!NT_SUCCESS(Status
)) return FALSE
;