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 /* Setup default access for the system process */
173 PsGetCurrentProcess()->GrantedAccess
= PROCESS_ALL_ACCESS
;
174 PsGetCurrentThread()->GrantedAccess
= THREAD_ALL_ACCESS
;
176 /* Setup the Object Reaper */
177 ExInitializeWorkItem(&ObpReaperWorkItem
, ObpReapObject
, NULL
);
179 /* Initialize default Quota block */
180 PsInitializeQuotaSystem();
182 /* Create kernel handle table */
183 PsGetCurrentProcess()->ObjectTable
= ExCreateHandleTable(NULL
);
184 ObpKernelHandleTable
= PsGetCurrentProcess()->ObjectTable
;
186 /* Create the Type Type */
187 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
188 RtlInitUnicodeString(&Name
, L
"Type");
189 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
190 ObjectTypeInitializer
.ValidAccessMask
= OBJECT_TYPE_ALL_ACCESS
;
191 ObjectTypeInitializer
.UseDefaultObject
= TRUE
;
192 ObjectTypeInitializer
.MaintainTypeList
= TRUE
;
193 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
194 ObjectTypeInitializer
.GenericMapping
= ObpTypeMapping
;
195 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(OBJECT_TYPE
);
196 ObjectTypeInitializer
.InvalidAttributes
= OBJ_OPENLINK
;
197 ObjectTypeInitializer
.DeleteProcedure
= ObpDeleteObjectType
;
198 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &ObpTypeObjectType
);
200 /* Create the Directory Type */
201 RtlInitUnicodeString(&Name
, L
"Directory");
202 ObjectTypeInitializer
.ValidAccessMask
= DIRECTORY_ALL_ACCESS
;
203 ObjectTypeInitializer
.CaseInsensitive
= TRUE
;
204 ObjectTypeInitializer
.MaintainTypeList
= FALSE
;
205 ObjectTypeInitializer
.GenericMapping
= ObpDirectoryMapping
;
206 ObjectTypeInitializer
.DeleteProcedure
= NULL
;
207 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(OBJECT_DIRECTORY
);
208 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &ObDirectoryType
);
210 /* Create 'symbolic link' object type */
211 RtlInitUnicodeString(&Name
, L
"SymbolicLink");
212 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(OBJECT_SYMBOLIC_LINK
);
213 ObjectTypeInitializer
.GenericMapping
= ObpSymbolicLinkMapping
;
214 ObjectTypeInitializer
.ValidAccessMask
= SYMBOLIC_LINK_ALL_ACCESS
;
215 ObjectTypeInitializer
.ParseProcedure
= ObpParseSymbolicLink
;
216 ObjectTypeInitializer
.DeleteProcedure
= ObpDeleteSymbolicLink
;
217 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &ObSymbolicLinkType
);
219 /* Phase 0 initialization complete */
220 ObpInitializationPhase
++;
225 /* Re-initialize lookaside lists */
228 /* Initialize Object Types directory attributes */
229 RtlInitUnicodeString(&Name
, L
"\\");
230 InitializeObjectAttributes(&ObjectAttributes
,
232 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
234 SePublicDefaultUnrestrictedSd
);
236 /* Create the directory */
237 Status
= NtCreateDirectoryObject(&Handle
,
238 DIRECTORY_ALL_ACCESS
,
240 if (!NT_SUCCESS(Status
)) return FALSE
;
242 /* Get a handle to it */
243 Status
= ObReferenceObjectByHandle(Handle
,
247 (PVOID
*)&ObpRootDirectoryObject
,
249 if (!NT_SUCCESS(Status
)) return FALSE
;
251 /* Close the extra handle */
252 Status
= NtClose(Handle
);
253 if (!NT_SUCCESS(Status
)) return FALSE
;
255 /* Initialize Object Types directory attributes */
256 RtlInitUnicodeString(&Name
, L
"\\KernelObjects");
257 InitializeObjectAttributes(&ObjectAttributes
,
259 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
263 /* Create the directory */
264 Status
= NtCreateDirectoryObject(&Handle
,
265 DIRECTORY_ALL_ACCESS
,
267 if (!NT_SUCCESS(Status
)) return FALSE
;
269 /* Close the extra handle */
270 Status
= NtClose(Handle
);
271 if (!NT_SUCCESS(Status
)) return FALSE
;
273 /* Initialize Object Types directory attributes */
274 RtlInitUnicodeString(&Name
, L
"\\ObjectTypes");
275 InitializeObjectAttributes(&ObjectAttributes
,
277 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
281 /* Create the directory */
282 Status
= NtCreateDirectoryObject(&Handle
,
283 DIRECTORY_ALL_ACCESS
,
285 if (!NT_SUCCESS(Status
)) return FALSE
;
287 /* Get a handle to it */
288 Status
= ObReferenceObjectByHandle(Handle
,
292 (PVOID
*)&ObpTypeDirectoryObject
,
294 if (!NT_SUCCESS(Status
)) return FALSE
;
296 /* Close the extra handle */
297 Status
= NtClose(Handle
);
298 if (!NT_SUCCESS(Status
)) return FALSE
;
300 /* Initialize lookup context */
301 ObpInitializeLookupContext(&Context
);
304 ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject
, &Context
);
306 /* Loop the object types */
307 ListHead
= &ObpTypeObjectType
->TypeList
;
308 NextEntry
= ListHead
->Flink
;
309 while (ListHead
!= NextEntry
)
311 /* Get the creator info from the list */
312 CreatorInfo
= CONTAINING_RECORD(NextEntry
,
313 OBJECT_HEADER_CREATOR_INFO
,
316 /* Recover the header and the name header from the creator info */
317 Header
= (POBJECT_HEADER
)(CreatorInfo
+ 1);
318 NameInfo
= OBJECT_HEADER_TO_NAME_INFO(Header
);
320 /* Make sure we have a name, and aren't inserted yet */
321 if ((NameInfo
) && !(NameInfo
->Directory
))
323 /* Do the initial lookup to setup the context */
324 if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject
,
326 OBJ_CASE_INSENSITIVE
,
330 /* Insert this object type */
331 ObpInsertEntryDirectory(ObpTypeDirectoryObject
,
337 /* Move to the next entry */
338 NextEntry
= NextEntry
->Flink
;
341 /* Cleanup after lookup */
342 ObpReleaseLookupContext(&Context
);
344 /* Initialize DOS Devices Directory and related Symbolic Links */
345 Status
= ObpCreateDosDevicesDirectory();
346 if (!NT_SUCCESS(Status
)) return FALSE
;