2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ob/obinit.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
= 0;
51 PsInitializeQuotaSystem(VOID
);
53 ULONG ObpInitializationPhase
;
55 /* PRIVATE FUNCTIONS *********************************************************/
64 PGENERAL_LOOKASIDE 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
= KiProcessorBlock
[(int)i
];
72 /* Set the OBJECT_CREATE_INFORMATION List */
73 Prcb
->PPLookasideList
[LookasideCreateInfoList
].L
= &ObpCreateInfoLookasideList
;
74 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
75 sizeof(GENERAL_LOOKASIDE
),
80 ExInitializeSystemLookasideList(CurrentList
,
82 sizeof(OBJECT_CREATE_INFORMATION
),
85 &ExSystemLookasideListHead
);
89 /* No list, use the static buffer */
90 CurrentList
= &ObpCreateInfoLookasideList
;
94 Prcb
->PPLookasideList
[LookasideCreateInfoList
].P
= CurrentList
;
96 /* Set the captured UNICODE_STRING Object Name List */
97 Prcb
->PPLookasideList
[LookasideNameBufferList
].L
= &ObpNameBufferLookasideList
;
98 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
99 sizeof(GENERAL_LOOKASIDE
),
104 ExInitializeSystemLookasideList(CurrentList
,
109 &ExSystemLookasideListHead
);
113 /* No list, use the static buffer */
114 CurrentList
= &ObpNameBufferLookasideList
;
118 Prcb
->PPLookasideList
[LookasideNameBufferList
].P
= CurrentList
;
129 OBJECT_ATTRIBUTES ObjectAttributes
;
131 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
132 OBP_LOOKUP_CONTEXT Context
;
134 PKPRCB Prcb
= KeGetCurrentPrcb();
135 PLIST_ENTRY ListHead
, NextEntry
;
136 POBJECT_HEADER Header
;
137 POBJECT_HEADER_CREATOR_INFO CreatorInfo
;
138 POBJECT_HEADER_NAME_INFO NameInfo
;
141 /* Check if this is actually Phase 1 initialization */
142 if (ObpInitializationPhase
!= 0) goto ObPostPhase0
;
144 /* Initialize the OBJECT_CREATE_INFORMATION List */
145 ExInitializeSystemLookasideList(&ObpCreateInfoLookasideList
,
147 sizeof(OBJECT_CREATE_INFORMATION
),
150 &ExSystemLookasideListHead
);
152 /* Set the captured UNICODE_STRING Object Name List */
153 ExInitializeSystemLookasideList(&ObpNameBufferLookasideList
,
158 &ExSystemLookasideListHead
);
160 /* Temporarily setup both pointers to the shared list */
161 Prcb
->PPLookasideList
[LookasideCreateInfoList
].L
= &ObpCreateInfoLookasideList
;
162 Prcb
->PPLookasideList
[LookasideCreateInfoList
].P
= &ObpCreateInfoLookasideList
;
163 Prcb
->PPLookasideList
[LookasideNameBufferList
].L
= &ObpNameBufferLookasideList
;
164 Prcb
->PPLookasideList
[LookasideNameBufferList
].P
= &ObpNameBufferLookasideList
;
166 /* Initialize the security descriptor cache */
169 /* Initialize the Default Event */
170 KeInitializeEvent(&ObpDefaultObject
, NotificationEvent
, TRUE
);
172 /* Initialize the Dos Device Map mutex */
173 KeInitializeGuardedMutex(&ObpDeviceMapLock
);
175 /* Setup default access for the system process */
176 PsGetCurrentProcess()->GrantedAccess
= PROCESS_ALL_ACCESS
;
177 PsGetCurrentThread()->GrantedAccess
= THREAD_ALL_ACCESS
;
179 /* Setup the Object Reaper */
180 ExInitializeWorkItem(&ObpReaperWorkItem
, ObpReapObject
, NULL
);
182 /* Initialize default Quota block */
183 PsInitializeQuotaSystem();
185 /* Create kernel handle table */
186 PsGetCurrentProcess()->ObjectTable
= ExCreateHandleTable(NULL
);
187 ObpKernelHandleTable
= PsGetCurrentProcess()->ObjectTable
;
189 /* Create the Type Type */
190 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
191 RtlInitUnicodeString(&Name
, L
"Type");
192 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
193 ObjectTypeInitializer
.ValidAccessMask
= OBJECT_TYPE_ALL_ACCESS
;
194 ObjectTypeInitializer
.UseDefaultObject
= TRUE
;
195 ObjectTypeInitializer
.MaintainTypeList
= TRUE
;
196 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
197 ObjectTypeInitializer
.GenericMapping
= ObpTypeMapping
;
198 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(OBJECT_TYPE
);
199 ObjectTypeInitializer
.InvalidAttributes
= OBJ_OPENLINK
;
200 ObjectTypeInitializer
.DeleteProcedure
= ObpDeleteObjectType
;
201 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &ObpTypeObjectType
);
203 /* Create the Directory Type */
204 RtlInitUnicodeString(&Name
, L
"Directory");
205 ObjectTypeInitializer
.PoolType
= PagedPool
;
206 ObjectTypeInitializer
.ValidAccessMask
= DIRECTORY_ALL_ACCESS
;
207 ObjectTypeInitializer
.CaseInsensitive
= TRUE
;
208 ObjectTypeInitializer
.MaintainTypeList
= FALSE
;
209 ObjectTypeInitializer
.GenericMapping
= ObpDirectoryMapping
;
210 ObjectTypeInitializer
.DeleteProcedure
= NULL
;
211 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(OBJECT_DIRECTORY
);
212 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &ObDirectoryType
);
213 ObDirectoryType
->TypeInfo
.ValidAccessMask
&= ~SYNCHRONIZE
;
215 /* Create 'symbolic link' object type */
216 RtlInitUnicodeString(&Name
, L
"SymbolicLink");
217 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(OBJECT_SYMBOLIC_LINK
);
218 ObjectTypeInitializer
.GenericMapping
= ObpSymbolicLinkMapping
;
219 ObjectTypeInitializer
.ValidAccessMask
= SYMBOLIC_LINK_ALL_ACCESS
;
220 ObjectTypeInitializer
.ParseProcedure
= ObpParseSymbolicLink
;
221 ObjectTypeInitializer
.DeleteProcedure
= ObpDeleteSymbolicLink
;
222 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &ObSymbolicLinkType
);
223 ObSymbolicLinkType
->TypeInfo
.ValidAccessMask
&= ~SYNCHRONIZE
;
225 /* Phase 0 initialization complete */
226 ObpInitializationPhase
++;
231 /* Re-initialize lookaside lists */
234 /* Initialize Object Types directory attributes */
235 RtlInitUnicodeString(&Name
, L
"\\");
236 InitializeObjectAttributes(&ObjectAttributes
,
238 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
240 SePublicDefaultUnrestrictedSd
);
242 /* Create the directory */
243 Status
= NtCreateDirectoryObject(&Handle
,
244 DIRECTORY_ALL_ACCESS
,
246 if (!NT_SUCCESS(Status
)) return FALSE
;
248 /* Get a handle to it */
249 Status
= ObReferenceObjectByHandle(Handle
,
253 (PVOID
*)&ObpRootDirectoryObject
,
255 if (!NT_SUCCESS(Status
)) return FALSE
;
257 /* Close the extra handle */
258 Status
= NtClose(Handle
);
259 if (!NT_SUCCESS(Status
)) return FALSE
;
261 /* Initialize Object Types directory attributes */
262 RtlInitUnicodeString(&Name
, L
"\\KernelObjects");
263 InitializeObjectAttributes(&ObjectAttributes
,
265 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
269 /* Create the directory */
270 Status
= NtCreateDirectoryObject(&Handle
,
271 DIRECTORY_ALL_ACCESS
,
273 if (!NT_SUCCESS(Status
)) return FALSE
;
275 /* Close the extra handle */
276 Status
= NtClose(Handle
);
277 if (!NT_SUCCESS(Status
)) return FALSE
;
279 /* Initialize Object Types directory attributes */
280 RtlInitUnicodeString(&Name
, L
"\\ObjectTypes");
281 InitializeObjectAttributes(&ObjectAttributes
,
283 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
287 /* Create the directory */
288 Status
= NtCreateDirectoryObject(&Handle
,
289 DIRECTORY_ALL_ACCESS
,
291 if (!NT_SUCCESS(Status
)) return FALSE
;
293 /* Get a handle to it */
294 Status
= ObReferenceObjectByHandle(Handle
,
298 (PVOID
*)&ObpTypeDirectoryObject
,
300 if (!NT_SUCCESS(Status
)) return FALSE
;
302 /* Close the extra handle */
303 Status
= NtClose(Handle
);
304 if (!NT_SUCCESS(Status
)) return FALSE
;
306 /* Initialize lookup context */
307 ObpInitializeLookupContext(&Context
);
310 ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject
, &Context
);
312 /* Loop the object types */
313 ListHead
= &ObpTypeObjectType
->TypeList
;
314 NextEntry
= ListHead
->Flink
;
315 while (ListHead
!= NextEntry
)
317 /* Get the creator info from the list */
318 CreatorInfo
= CONTAINING_RECORD(NextEntry
,
319 OBJECT_HEADER_CREATOR_INFO
,
322 /* Recover the header and the name header from the creator info */
323 Header
= (POBJECT_HEADER
)(CreatorInfo
+ 1);
324 NameInfo
= OBJECT_HEADER_TO_NAME_INFO(Header
);
326 /* Make sure we have a name, and aren't inserted yet */
327 if ((NameInfo
) && !(NameInfo
->Directory
))
329 /* Do the initial lookup to setup the context */
330 if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject
,
332 OBJ_CASE_INSENSITIVE
,
336 /* Insert this object type */
337 ObpInsertEntryDirectory(ObpTypeDirectoryObject
,
343 /* Move to the next entry */
344 NextEntry
= NextEntry
->Flink
;
347 /* Cleanup after lookup */
348 ObpReleaseLookupContext(&Context
);
350 /* Initialize DOS Devices Directory and related Symbolic Links */
351 Status
= ObpCreateDosDevicesDirectory();
352 if (!NT_SUCCESS(Status
)) return FALSE
;