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
.ValidAccessMask
= DIRECTORY_ALL_ACCESS
;
206 ObjectTypeInitializer
.CaseInsensitive
= TRUE
;
207 ObjectTypeInitializer
.MaintainTypeList
= FALSE
;
208 ObjectTypeInitializer
.GenericMapping
= ObpDirectoryMapping
;
209 ObjectTypeInitializer
.DeleteProcedure
= NULL
;
210 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(OBJECT_DIRECTORY
);
211 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &ObDirectoryType
);
213 /* Create 'symbolic link' object type */
214 RtlInitUnicodeString(&Name
, L
"SymbolicLink");
215 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= 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
*)&ObpRootDirectoryObject
,
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
"\\KernelObjects");
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 /* Close the extra handle */
273 Status
= NtClose(Handle
);
274 if (!NT_SUCCESS(Status
)) return FALSE
;
276 /* Initialize Object Types directory attributes */
277 RtlInitUnicodeString(&Name
, L
"\\ObjectTypes");
278 InitializeObjectAttributes(&ObjectAttributes
,
280 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
284 /* Create the directory */
285 Status
= NtCreateDirectoryObject(&Handle
,
286 DIRECTORY_ALL_ACCESS
,
288 if (!NT_SUCCESS(Status
)) return FALSE
;
290 /* Get a handle to it */
291 Status
= ObReferenceObjectByHandle(Handle
,
295 (PVOID
*)&ObpTypeDirectoryObject
,
297 if (!NT_SUCCESS(Status
)) return FALSE
;
299 /* Close the extra handle */
300 Status
= NtClose(Handle
);
301 if (!NT_SUCCESS(Status
)) return FALSE
;
303 /* Initialize lookup context */
304 ObpInitializeLookupContext(&Context
);
307 ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject
, &Context
);
309 /* Loop the object types */
310 ListHead
= &ObpTypeObjectType
->TypeList
;
311 NextEntry
= ListHead
->Flink
;
312 while (ListHead
!= NextEntry
)
314 /* Get the creator info from the list */
315 CreatorInfo
= CONTAINING_RECORD(NextEntry
,
316 OBJECT_HEADER_CREATOR_INFO
,
319 /* Recover the header and the name header from the creator info */
320 Header
= (POBJECT_HEADER
)(CreatorInfo
+ 1);
321 NameInfo
= OBJECT_HEADER_TO_NAME_INFO(Header
);
323 /* Make sure we have a name, and aren't inserted yet */
324 if ((NameInfo
) && !(NameInfo
->Directory
))
326 /* Do the initial lookup to setup the context */
327 if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject
,
329 OBJ_CASE_INSENSITIVE
,
333 /* Insert this object type */
334 ObpInsertEntryDirectory(ObpTypeDirectoryObject
,
340 /* Move to the next entry */
341 NextEntry
= NextEntry
->Flink
;
344 /* Cleanup after lookup */
345 ObpReleaseLookupContext(&Context
);
347 /* Initialize DOS Devices Directory and related Symbolic Links */
348 Status
= ObpCreateDosDevicesDirectory();
349 if (!NT_SUCCESS(Status
)) return FALSE
;