[CMAKE]
[reactos.git] / ntoskrnl / ob / obinit.c
1 /*
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)
7 * Eric Kohl
8 * Thomas Weidenmueller (w3seek@reactos.org)
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16
17 /* GLOBALS *******************************************************************/
18
19 GENERIC_MAPPING ObpTypeMapping =
20 {
21 STANDARD_RIGHTS_READ,
22 STANDARD_RIGHTS_WRITE,
23 STANDARD_RIGHTS_EXECUTE,
24 0x000F0001
25 };
26
27 GENERIC_MAPPING ObpDirectoryMapping =
28 {
29 STANDARD_RIGHTS_READ | DIRECTORY_QUERY |
30 DIRECTORY_TRAVERSE,
31 STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY |
32 DIRECTORY_CREATE_OBJECT,
33 STANDARD_RIGHTS_EXECUTE | DIRECTORY_QUERY |
34 DIRECTORY_TRAVERSE,
35 DIRECTORY_ALL_ACCESS
36 };
37
38 GENERIC_MAPPING ObpSymbolicLinkMapping =
39 {
40 STANDARD_RIGHTS_READ | SYMBOLIC_LINK_QUERY,
41 STANDARD_RIGHTS_WRITE,
42 STANDARD_RIGHTS_EXECUTE | SYMBOLIC_LINK_QUERY,
43 SYMBOLIC_LINK_ALL_ACCESS
44 };
45
46 PDEVICE_MAP ObSystemDeviceMap = NULL;
47 ULONG ObpTraceLevel = 0;
48
49 VOID
50 NTAPI
51 PsInitializeQuotaSystem(VOID);
52
53 ULONG ObpInitializationPhase;
54
55 /* PRIVATE FUNCTIONS *********************************************************/
56
57 BOOLEAN
58 INIT_FUNCTION
59 NTAPI
60 ObInit2(VOID)
61 {
62 CCHAR i;
63 PKPRCB Prcb;
64 PGENERAL_LOOKASIDE CurrentList = NULL;
65
66 /* Now allocate the per-processor lists */
67 for (i = 0; i < KeNumberProcessors; i++)
68 {
69 /* Get the PRCB for this CPU */
70 Prcb = KiProcessorBlock[(int)i];
71
72 /* Set the OBJECT_CREATE_INFORMATION List */
73 Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList;
74 CurrentList = ExAllocatePoolWithTag(NonPagedPool,
75 sizeof(GENERAL_LOOKASIDE),
76 'ICbO');
77 if (CurrentList)
78 {
79 /* Initialize it */
80 ExInitializeSystemLookasideList(CurrentList,
81 NonPagedPool,
82 sizeof(OBJECT_CREATE_INFORMATION),
83 'ICbO',
84 32,
85 &ExSystemLookasideListHead);
86 }
87 else
88 {
89 /* No list, use the static buffer */
90 CurrentList = &ObpCreateInfoLookasideList;
91 }
92
93 /* Link it */
94 Prcb->PPLookasideList[LookasideCreateInfoList].P = CurrentList;
95
96 /* Set the captured UNICODE_STRING Object Name List */
97 Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList;
98 CurrentList = ExAllocatePoolWithTag(NonPagedPool,
99 sizeof(GENERAL_LOOKASIDE),
100 'MNbO');
101 if (CurrentList)
102 {
103 /* Initialize it */
104 ExInitializeSystemLookasideList(CurrentList,
105 PagedPool,
106 248,
107 'MNbO',
108 16,
109 &ExSystemLookasideListHead);
110 }
111 else
112 {
113 /* No list, use the static buffer */
114 CurrentList = &ObpNameBufferLookasideList;
115 }
116
117 /* Link it */
118 Prcb->PPLookasideList[LookasideNameBufferList].P = CurrentList;
119 }
120
121 return TRUE;
122 }
123
124 BOOLEAN
125 INIT_FUNCTION
126 NTAPI
127 ObInitSystem(VOID)
128 {
129 OBJECT_ATTRIBUTES ObjectAttributes;
130 UNICODE_STRING Name;
131 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
132 OBP_LOOKUP_CONTEXT Context;
133 HANDLE Handle;
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;
139 NTSTATUS Status;
140
141 /* Check if this is actually Phase 1 initialization */
142 if (ObpInitializationPhase != 0) goto ObPostPhase0;
143
144 /* Initialize the OBJECT_CREATE_INFORMATION List */
145 ExInitializeSystemLookasideList(&ObpCreateInfoLookasideList,
146 NonPagedPool,
147 sizeof(OBJECT_CREATE_INFORMATION),
148 'ICbO',
149 32,
150 &ExSystemLookasideListHead);
151
152 /* Set the captured UNICODE_STRING Object Name List */
153 ExInitializeSystemLookasideList(&ObpNameBufferLookasideList,
154 PagedPool,
155 248,
156 'MNbO',
157 16,
158 &ExSystemLookasideListHead);
159
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;
165
166 /* Initialize the security descriptor cache */
167 ObpInitSdCache();
168
169 /* Initialize the Default Event */
170 KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE);
171
172 /* Setup default access for the system process */
173 PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
174 PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;
175
176 /* Setup the Object Reaper */
177 ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);
178
179 /* Initialize default Quota block */
180 PsInitializeQuotaSystem();
181
182 /* Create kernel handle table */
183 PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable(NULL);
184 ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable;
185
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);
199
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);
209
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);
218
219 /* Phase 0 initialization complete */
220 ObpInitializationPhase++;
221 return TRUE;
222
223 ObPostPhase0:
224
225 /* Re-initialize lookaside lists */
226 ObInit2();
227
228 /* Initialize Object Types directory attributes */
229 RtlInitUnicodeString(&Name, L"\\");
230 InitializeObjectAttributes(&ObjectAttributes,
231 &Name,
232 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
233 NULL,
234 SePublicDefaultUnrestrictedSd);
235
236 /* Create the directory */
237 Status = NtCreateDirectoryObject(&Handle,
238 DIRECTORY_ALL_ACCESS,
239 &ObjectAttributes);
240 if (!NT_SUCCESS(Status)) return FALSE;
241
242 /* Get a handle to it */
243 Status = ObReferenceObjectByHandle(Handle,
244 0,
245 ObDirectoryType,
246 KernelMode,
247 (PVOID*)&ObpRootDirectoryObject,
248 NULL);
249 if (!NT_SUCCESS(Status)) return FALSE;
250
251 /* Close the extra handle */
252 Status = NtClose(Handle);
253 if (!NT_SUCCESS(Status)) return FALSE;
254
255 /* Initialize Object Types directory attributes */
256 RtlInitUnicodeString(&Name, L"\\KernelObjects");
257 InitializeObjectAttributes(&ObjectAttributes,
258 &Name,
259 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
260 NULL,
261 NULL);
262
263 /* Create the directory */
264 Status = NtCreateDirectoryObject(&Handle,
265 DIRECTORY_ALL_ACCESS,
266 &ObjectAttributes);
267 if (!NT_SUCCESS(Status)) return FALSE;
268
269 /* Close the extra handle */
270 Status = NtClose(Handle);
271 if (!NT_SUCCESS(Status)) return FALSE;
272
273 /* Initialize Object Types directory attributes */
274 RtlInitUnicodeString(&Name, L"\\ObjectTypes");
275 InitializeObjectAttributes(&ObjectAttributes,
276 &Name,
277 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
278 NULL,
279 NULL);
280
281 /* Create the directory */
282 Status = NtCreateDirectoryObject(&Handle,
283 DIRECTORY_ALL_ACCESS,
284 &ObjectAttributes);
285 if (!NT_SUCCESS(Status)) return FALSE;
286
287 /* Get a handle to it */
288 Status = ObReferenceObjectByHandle(Handle,
289 0,
290 ObDirectoryType,
291 KernelMode,
292 (PVOID*)&ObpTypeDirectoryObject,
293 NULL);
294 if (!NT_SUCCESS(Status)) return FALSE;
295
296 /* Close the extra handle */
297 Status = NtClose(Handle);
298 if (!NT_SUCCESS(Status)) return FALSE;
299
300 /* Initialize lookup context */
301 ObpInitializeLookupContext(&Context);
302
303 /* Lock it */
304 ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
305
306 /* Loop the object types */
307 ListHead = &ObpTypeObjectType->TypeList;
308 NextEntry = ListHead->Flink;
309 while (ListHead != NextEntry)
310 {
311 /* Get the creator info from the list */
312 CreatorInfo = CONTAINING_RECORD(NextEntry,
313 OBJECT_HEADER_CREATOR_INFO,
314 TypeList);
315
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);
319
320 /* Make sure we have a name, and aren't inserted yet */
321 if ((NameInfo) && !(NameInfo->Directory))
322 {
323 /* Do the initial lookup to setup the context */
324 if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
325 &NameInfo->Name,
326 OBJ_CASE_INSENSITIVE,
327 FALSE,
328 &Context))
329 {
330 /* Insert this object type */
331 ObpInsertEntryDirectory(ObpTypeDirectoryObject,
332 &Context,
333 Header);
334 }
335 }
336
337 /* Move to the next entry */
338 NextEntry = NextEntry->Flink;
339 }
340
341 /* Cleanup after lookup */
342 ObpReleaseLookupContext(&Context);
343
344 /* Initialize DOS Devices Directory and related Symbolic Links */
345 Status = ObpCreateDosDevicesDirectory();
346 if (!NT_SUCCESS(Status)) return FALSE;
347 return TRUE;
348 }
349
350 /* EOF */