470811a273b72c2afb6d9483d24c42f601cfe20d
[reactos.git] / reactos / drivers / filesystems / ext2 / src / init.c
1 /*
2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4 * FILE: init.c
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
7 * UPDATE HISTORY:
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include "ext2fs.h"
13
14 /* GLOBALS ***************************************************************/
15
16 PEXT2_GLOBAL Ext2Global = NULL;
17
18 /*
19 * Ext2Fsd version, building date/time
20 */
21
22 CHAR gVersion[] = EXT2FSD_VERSION;
23 CHAR gTime[] = __TIME__;
24 CHAR gDate[] = __DATE__;
25
26
27 /* DEFINITIONS ***********************************************************/
28
29 NTSTATUS NTAPI
30 DriverEntry(
31 IN PDRIVER_OBJECT DriverObject,
32 IN PUNICODE_STRING RegistryPath );
33
34 #ifdef ALLOC_PRAGMA
35 #pragma alloc_text(INIT, Ext2QueryGlobalParameters)
36 #pragma alloc_text(INIT, DriverEntry)
37 #if EXT2_UNLOAD
38 #pragma alloc_text(PAGE, DriverUnload)
39 #endif
40 #endif
41
42 /* FUNCTIONS ***************************************************************/
43
44 DECLARE_INIT(journal_init);
45 DECLARE_EXIT(journal_exit);
46
47 #if EXT2_UNLOAD
48
49 /*
50 * FUNCTION: Called by the system to unload the driver
51 * ARGUMENTS:
52 * DriverObject = object describing this driver
53 * RETURNS: None
54 */
55
56 VOID NTAPI
57 DriverUnload (IN PDRIVER_OBJECT DriverObject)
58 {
59
60 UNICODE_STRING DosDeviceName;
61
62 DEBUG(DL_FUN, ( "Ext2Fsd: Unloading routine.\n"));
63
64 /*
65 * stop reaper thread ...
66 */
67
68
69 /*
70 * removing memory allocations and objects
71 */
72
73 RtlInitUnicodeString(&DosDeviceName, DOS_DEVICE_NAME);
74 IoDeleteSymbolicLink(&DosDeviceName);
75
76 Ext2UnloadAllNls();
77
78 ExDeleteResourceLite(&Ext2Global->Resource);
79
80 ExDeleteNPagedLookasideList(&(Ext2Global->Ext2DentryLookasideList));
81 ExDeleteNPagedLookasideList(&(Ext2Global->Ext2ExtLookasideList));
82 ExDeleteNPagedLookasideList(&(Ext2Global->Ext2McbLookasideList));
83 ExDeleteNPagedLookasideList(&(Ext2Global->Ext2CcbLookasideList));
84 ExDeleteNPagedLookasideList(&(Ext2Global->Ext2FcbLookasideList));
85 ExDeleteNPagedLookasideList(&(Ext2Global->Ext2IrpContextLookasideList));
86
87 ObDereferenceObject(Ext2Global->DiskdevObject);
88 ObDereferenceObject(Ext2Global->CdromdevObject);
89
90 /* cleanup journal related caches */
91 UNLOAD_MODULE(journal_exit);
92
93 /* cleanup linux lib */
94 ext2_destroy_linux();
95
96 Ext2FreePool(Ext2Global, 'LG2E');
97 Ext2Global = NULL;
98 }
99
100 #endif
101
102 BOOLEAN
103 Ext2QueryGlobalParameters( IN PUNICODE_STRING RegistryPath)
104 {
105 NTSTATUS Status;
106 UNICODE_STRING ParameterPath;
107 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
108
109 ULONG WritingSupport = 0;
110 ULONG CheckingBitmap = 0;
111 ULONG Ext3ForceWriting = 0;
112 ULONG AutoMount = 0;
113
114 UNICODE_STRING UniName;
115 ANSI_STRING AnsiName;
116
117 WCHAR UniBuffer[CODEPAGE_MAXLEN];
118 USHORT Buffer[HIDINGPAT_LEN];
119
120 ParameterPath.Length = 0;
121
122 ParameterPath.MaximumLength =
123 RegistryPath->Length + sizeof(PARAMETERS_KEY) + sizeof(WCHAR);
124
125 ParameterPath.Buffer =
126 (PWSTR) Ext2AllocatePool(
127 PagedPool,
128 ParameterPath.MaximumLength,
129 'LG2E'
130 );
131
132 if (!ParameterPath.Buffer) {
133 DbgBreak();
134 DEBUG(DL_ERR, ( "Ex2QueryParameters: failed to allocate Parameters...\n"));
135 return FALSE;
136 }
137
138 RtlCopyUnicodeString(&ParameterPath, RegistryPath);
139 RtlAppendUnicodeToString(&ParameterPath, PARAMETERS_KEY);
140
141 /* querying value of WritingSupport */
142 RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
143
144 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
145 QueryTable[0].Name = WRITING_SUPPORT;
146 QueryTable[0].EntryContext = &WritingSupport;
147
148 Status = RtlQueryRegistryValues(
149 RTL_REGISTRY_ABSOLUTE,
150 ParameterPath.Buffer,
151 &QueryTable[0],
152 NULL,
153 NULL );
154
155 DEBUG(DL_ERR, ( "Ext2QueryParameters: WritingSupport=%xh\n", WritingSupport));
156
157 /* querying value of CheckingBitmap */
158 RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
159 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
160 QueryTable[0].Name = CHECKING_BITMAP;
161 QueryTable[0].EntryContext = &CheckingBitmap;
162
163 Status = RtlQueryRegistryValues(
164 RTL_REGISTRY_ABSOLUTE,
165 ParameterPath.Buffer,
166 &QueryTable[0],
167 NULL,
168 NULL );
169
170 DEBUG(DL_ERR, ( "Ext2QueryParameters: CheckingBitmap=%xh\n", CheckingBitmap));
171
172 /* querying value of Ext3ForceWriting */
173 RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
174 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
175 QueryTable[0].Name = EXT3_FORCEWRITING;
176 QueryTable[0].EntryContext = &Ext3ForceWriting;
177
178 Status = RtlQueryRegistryValues(
179 RTL_REGISTRY_ABSOLUTE,
180 ParameterPath.Buffer,
181 &QueryTable[0],
182 NULL,
183 NULL );
184
185 DEBUG(DL_ERR, ( "Ext2QueryParameters: Ext3ForceWriting=%xh\n", Ext3ForceWriting));
186
187
188 /* querying value of AutoMount */
189 RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
190
191 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
192 QueryTable[0].Name = AUTO_MOUNT;
193 QueryTable[0].EntryContext = &AutoMount;
194
195 Status = RtlQueryRegistryValues(
196 RTL_REGISTRY_ABSOLUTE,
197 ParameterPath.Buffer,
198 &QueryTable[0],
199 NULL,
200 NULL );
201
202 SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT);
203 if (NT_SUCCESS(Status) && AutoMount == 0) {
204 ClearLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT);
205 }
206
207 DEBUG(DL_ERR, ( "Ext2QueryParameters: AutoMount=%xh\n", AutoMount));
208
209 /* querying codepage */
210 RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
211 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
212 QueryTable[0].Name = CODEPAGE_NAME;
213 QueryTable[0].EntryContext = &(UniName);
214 UniName.MaximumLength = CODEPAGE_MAXLEN * sizeof(WCHAR);
215 UniName.Length = 0;
216 UniName.Buffer = (PWSTR)UniBuffer;
217
218 Status = RtlQueryRegistryValues(
219 RTL_REGISTRY_ABSOLUTE,
220 ParameterPath.Buffer,
221 &QueryTable[0],
222 NULL,
223 NULL );
224
225 if (NT_SUCCESS(Status)) {
226 DEBUG(DL_ERR, ( "Ext2QueryParameters: Ext2CodePage=%wZ\n", &UniName));
227 AnsiName.MaximumLength = CODEPAGE_MAXLEN;
228 AnsiName.Length = 0;
229 AnsiName.Buffer = &(Ext2Global->Codepage.AnsiName[0]);
230
231 Status = RtlUnicodeStringToAnsiString(
232 &AnsiName,
233 &UniName,
234 FALSE);
235
236 if (!NT_SUCCESS(Status)) {
237 DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong CodePage %wZ ...\n", &UniName));
238 RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8);
239 }
240 } else {
241 DEBUG(DL_ERR, ( "Ext2QueryParameters: CodePage not specified.\n"));
242 RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8);
243 }
244 Ext2Global->Codepage.AnsiName[CODEPAGE_MAXLEN - 1] = 0;
245
246 /* querying name hiding patterns: prefix*/
247 RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
248 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
249 QueryTable[0].Name = HIDING_PREFIX;
250 QueryTable[0].EntryContext = &(UniName);
251 UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR);
252 UniName.Length = 0;
253 UniName.Buffer = Buffer;
254
255 Status = RtlQueryRegistryValues(
256 RTL_REGISTRY_ABSOLUTE,
257 ParameterPath.Buffer,
258 &QueryTable[0],
259 NULL,
260 NULL );
261
262 if (NT_SUCCESS(Status)) {
263 DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingPrefix=%wZ\n", &UniName));
264 AnsiName.MaximumLength =HIDINGPAT_LEN;
265 AnsiName.Length = 0;
266 AnsiName.Buffer = &(Ext2Global->sHidingPrefix[0]);
267
268 Status = RtlUnicodeStringToAnsiString(
269 &AnsiName,
270 &UniName,
271 FALSE);
272 if (NT_SUCCESS(Status)) {
273 Ext2Global->bHidingPrefix = TRUE;
274 } else {
275 DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingPrefix ...\n"));
276 }
277 } else {
278 DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingPrefix not specified.\n"));
279 }
280 Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0;
281
282 /* querying name hiding patterns: suffix */
283 RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
284 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
285 QueryTable[0].Name = HIDING_SUFFIX;
286 QueryTable[0].EntryContext = &(UniName);
287 UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR);
288 UniName.Length = 0;
289 UniName.Buffer = Buffer;
290
291 Status = RtlQueryRegistryValues(
292 RTL_REGISTRY_ABSOLUTE,
293 ParameterPath.Buffer,
294 &QueryTable[0],
295 NULL,
296 NULL
297 );
298
299 if (NT_SUCCESS(Status)) {
300
301 DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingSuffix=%wZ\n", &UniName));
302 AnsiName.MaximumLength = HIDINGPAT_LEN;
303 AnsiName.Length = 0;
304 AnsiName.Buffer = &(Ext2Global->sHidingSuffix[0]);
305
306 Status = RtlUnicodeStringToAnsiString(
307 &AnsiName,
308 &UniName,
309 FALSE);
310 if (NT_SUCCESS(Status)) {
311 Ext2Global->bHidingSuffix = TRUE;
312 } else {
313 DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingSuffix ...\n"));
314 }
315 } else {
316 DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingSuffix not specified.\n"));
317 }
318 Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0;
319
320 {
321 if (WritingSupport) {
322 SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING);
323 } else {
324 ClearLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING);
325 }
326
327 if (CheckingBitmap) {
328 SetLongFlag(Ext2Global->Flags, EXT2_CHECKING_BITMAP);
329 } else {
330 ClearLongFlag(Ext2Global->Flags, EXT2_CHECKING_BITMAP);
331 }
332
333 if (Ext3ForceWriting) {
334 DEBUG(DL_WRN, ("Ext2Fsd -- Warning: Ext3ForceWriting enabled !!!\n"));
335
336 SetLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING);
337 SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING);
338 } else {
339 ClearLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING);
340 }
341 }
342
343 Ext2Global->RegistryPath.Buffer = ParameterPath.Buffer;
344 Ext2Global->RegistryPath.Length = 0;
345 Ext2Global->RegistryPath.MaximumLength = ParameterPath.MaximumLength;
346 RtlCopyUnicodeString(&Ext2Global->RegistryPath, RegistryPath);
347 RtlAppendUnicodeToString(&Ext2Global->RegistryPath, VOLUMES_KEY);
348
349 return TRUE;
350 }
351
352
353 #define NLS_OEM_LEAD_BYTE_INFO (*NlsOemLeadByteInfo)
354
355 #ifndef __REACTOS__
356 #define FsRtlIsLeadDbcsCharacter(DBCS_CHAR) ( \
357 (BOOLEAN)((UCHAR)(DBCS_CHAR) < 0x80 ? FALSE : \
358 (NLS_MB_CODE_PAGE_TAG && \
359 (NLS_OEM_LEAD_BYTE_INFO[(UCHAR)(DBCS_CHAR)] != 0))) \
360 )
361 #endif
362
363
364 /*
365 * NAME: DriverEntry
366 * FUNCTION: Called by the system to initalize the driver
367 *
368 * ARGUMENTS:
369 * DriverObject = object describing this driver
370 * RegistryPath = path to our configuration entries
371 * RETURNS: Success or failure
372 */
373 NTSTATUS NTAPI
374 DriverEntry (
375 IN PDRIVER_OBJECT DriverObject,
376 IN PUNICODE_STRING RegistryPath
377 )
378 {
379 PDEVICE_OBJECT DiskdevObject = NULL;
380 PDEVICE_OBJECT CdromdevObject = NULL;
381 UNICODE_STRING DeviceName;
382 UNICODE_STRING DosDeviceName;
383
384 PFAST_IO_DISPATCH FastIoDispatch;
385 PCACHE_MANAGER_CALLBACKS CacheManagerCallbacks;
386
387 LARGE_INTEGER Timeout;
388 NTSTATUS Status;
389
390 int rc = 0;
391 BOOLEAN linux_lib_inited = FALSE;
392 BOOLEAN journal_module_inited = FALSE;
393
394 /* Verify ERESOURCE alignment in structures */
395 ASSERT((FIELD_OFFSET(EXT2_GLOBAL, Resource) & 7) == 0);
396 ASSERT((FIELD_OFFSET(EXT2_VCB, MainResource) & 7) == 0);
397 ASSERT((FIELD_OFFSET(EXT2_VCB, PagingIoResource) & 7) == 0);
398 ASSERT((FIELD_OFFSET(EXT2_VCB, MetaLock) & 7) == 0);
399 ASSERT((FIELD_OFFSET(EXT2_VCB, McbLock) & 7) == 0);
400 ASSERT((FIELD_OFFSET(EXT2_FCBVCB, MainResource) & 7) == 0);
401 ASSERT((FIELD_OFFSET(EXT2_FCBVCB, PagingIoResource) & 7) == 0);
402 ASSERT((FIELD_OFFSET(EXT2_FCB, MainResource) & 7) == 0);
403 ASSERT((FIELD_OFFSET(EXT2_FCB, PagingIoResource) & 7) == 0);
404
405 /* Verity super block ... */
406 ASSERT(sizeof(EXT2_SUPER_BLOCK) == 1024);
407 ASSERT(FIELD_OFFSET(EXT2_SUPER_BLOCK, s_magic) == 56);
408
409 DbgPrint(
410 "Ext2Fsd --"
411 #ifdef _WIN2K_TARGET_
412 " Win2k --"
413 #endif
414 " Version "
415 EXT2FSD_VERSION
416 #if EXT2_DEBUG
417 " Checked"
418 #else
419 " Free"
420 #endif
421 " -- "
422 __DATE__ " "
423 __TIME__ ".\n");
424
425 DEBUG(DL_FUN, ( "Ext2 DriverEntry ...\n"));
426
427 /* initialize winlib structures */
428 if (ext2_init_linux()) {
429 Status = STATUS_INSUFFICIENT_RESOURCES;
430 goto errorout;
431 }
432 linux_lib_inited = TRUE;
433
434 /* initialize journal module structures */
435 LOAD_MODULE(journal_init);
436 if (rc != 0) {
437 Status = STATUS_INSUFFICIENT_RESOURCES;
438 goto errorout;
439 }
440 journal_module_inited = TRUE;
441
442 /* allocate memory for Ext2Global */
443 Ext2Global = Ext2AllocatePool(NonPagedPool, sizeof(EXT2_GLOBAL), 'LG2E');
444 if (!Ext2Global) {
445 Status = STATUS_INSUFFICIENT_RESOURCES;
446 goto errorout;
447 }
448
449 /* initialize Ext2Global */
450 RtlZeroMemory(Ext2Global, sizeof(EXT2_GLOBAL));
451 Ext2Global->Identifier.Type = EXT2FGD;
452 Ext2Global->Identifier.Size = sizeof(EXT2_GLOBAL);
453
454 InitializeListHead(&(Ext2Global->VcbList));
455 ExInitializeResourceLite(&(Ext2Global->Resource));
456
457 /* Reaper thread engine event */
458 KeInitializeEvent(&Ext2Global->Reaper.Engine,
459 SynchronizationEvent, FALSE);
460
461 /* query registry settings */
462 Ext2QueryGlobalParameters(RegistryPath);
463
464 /* create Ext2Fsd cdrom fs deivce */
465 RtlInitUnicodeString(&DeviceName, CDROM_NAME);
466 Status = IoCreateDevice(
467 DriverObject,
468 0,
469 &DeviceName,
470 FILE_DEVICE_CD_ROM_FILE_SYSTEM,
471 0,
472 FALSE,
473 &CdromdevObject );
474
475 if (!NT_SUCCESS(Status)) {
476 DEBUG(DL_ERR, ( "IoCreateDevice cdrom device object error.\n"));
477 goto errorout;
478 }
479
480 /* create Ext2Fsd disk fs deivce */
481 RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
482 Status = IoCreateDevice(
483 DriverObject,
484 0,
485 &DeviceName,
486 FILE_DEVICE_DISK_FILE_SYSTEM,
487 0,
488 FALSE,
489 &DiskdevObject );
490
491 if (!NT_SUCCESS(Status)) {
492 DEBUG(DL_ERR, ( "IoCreateDevice disk device object error.\n"));
493 goto errorout;
494 }
495
496 /* start resource reaper thread */
497 Status= Ext2StartReaperThread();
498 if (!NT_SUCCESS(Status)) {
499 goto errorout;
500 }
501 /* make sure Reaperthread is started */
502 Timeout.QuadPart = (LONGLONG)-10*1000*1000*10; /* 10 seconds */
503 Status = KeWaitForSingleObject(
504 &(Ext2Global->Reaper.Engine),
505 Executive,
506 KernelMode,
507 FALSE,
508 &Timeout
509 );
510 if (Status != STATUS_SUCCESS) {
511 Status = STATUS_INSUFFICIENT_RESOURCES;
512 goto errorout;
513 }
514
515 /* initializing */
516 Ext2Global->DiskdevObject = DiskdevObject;
517 Ext2Global->CdromdevObject = CdromdevObject;
518
519 DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2BuildRequest;
520 DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2BuildRequest;
521 DriverObject->MajorFunction[IRP_MJ_READ] = Ext2BuildRequest;
522 DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2BuildRequest;
523
524 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = Ext2BuildRequest;
525 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = Ext2BuildRequest;
526
527 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = Ext2BuildRequest;
528 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = Ext2BuildRequest;
529
530 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = Ext2BuildRequest;
531 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = Ext2BuildRequest;
532
533 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = Ext2BuildRequest;
534 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = Ext2BuildRequest;
535 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Ext2BuildRequest;
536 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = Ext2BuildRequest;
537
538 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Ext2BuildRequest;
539
540 #if (_WIN32_WINNT >= 0x0500)
541 DriverObject->MajorFunction[IRP_MJ_PNP] = Ext2BuildRequest;
542 #endif //(_WIN32_WINNT >= 0x0500)
543
544 #if EXT2_UNLOAD
545 DriverObject->DriverUnload = DriverUnload;
546 #else
547 DriverObject->DriverUnload = NULL;
548 #endif
549
550 //
551 // Initialize the fast I/O entry points
552 //
553
554 FastIoDispatch = &(Ext2Global->FastIoDispatch);
555
556 FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
557 FastIoDispatch->FastIoCheckIfPossible = Ext2FastIoCheckIfPossible;
558 FastIoDispatch->FastIoRead = Ext2FastIoRead;
559 FastIoDispatch->FastIoWrite = Ext2FastIoWrite;
560 FastIoDispatch->FastIoQueryBasicInfo = Ext2FastIoQueryBasicInfo;
561 FastIoDispatch->FastIoQueryStandardInfo = Ext2FastIoQueryStandardInfo;
562 FastIoDispatch->FastIoLock = Ext2FastIoLock;
563 FastIoDispatch->FastIoUnlockSingle = Ext2FastIoUnlockSingle;
564 FastIoDispatch->FastIoUnlockAll = Ext2FastIoUnlockAll;
565 FastIoDispatch->FastIoUnlockAllByKey = Ext2FastIoUnlockAllByKey;
566 FastIoDispatch->FastIoQueryNetworkOpenInfo = Ext2FastIoQueryNetworkOpenInfo;
567 FastIoDispatch->AcquireForModWrite = Ext2AcquireFileForModWrite;
568 FastIoDispatch->ReleaseForModWrite = Ext2ReleaseFileForModWrite;
569 FastIoDispatch->AcquireForCcFlush = Ext2AcquireFileForCcFlush;
570 FastIoDispatch->ReleaseForCcFlush = Ext2ReleaseFileForCcFlush;
571 FastIoDispatch->AcquireFileForNtCreateSection = Ext2AcquireForCreateSection;
572 FastIoDispatch->ReleaseFileForNtCreateSection = Ext2ReleaseForCreateSection;
573 DriverObject->FastIoDispatch = FastIoDispatch;
574
575 //
576 // initializing structure sizes for statistics
577 // 1 means flexible/not fixed for all allocations (for different volumes).
578 //
579 Ext2Global->PerfStat.Magic = EXT2_PERF_STAT_MAGIC;
580 Ext2Global->PerfStat.Version = EXT2_PERF_STAT_VER2;
581 Ext2Global->PerfStat.Length = sizeof(EXT2_PERF_STATISTICS_V2);
582
583 Ext2Global->PerfStat.Unit.Slot[PS_IRP_CONTEXT] = sizeof(EXT2_IRP_CONTEXT); /* 0 */
584 Ext2Global->PerfStat.Unit.Slot[PS_VCB] = sizeof(EXT2_VCB); /* 1 */
585 Ext2Global->PerfStat.Unit.Slot[PS_FCB] = sizeof(EXT2_FCB); /* 2 */
586 Ext2Global->PerfStat.Unit.Slot[PS_CCB] = sizeof(EXT2_CCB); /* 3 */
587 Ext2Global->PerfStat.Unit.Slot[PS_MCB] = sizeof(EXT2_MCB); /* 4 */
588 Ext2Global->PerfStat.Unit.Slot[PS_EXTENT] = sizeof(EXT2_EXTENT); /* 5 */
589 Ext2Global->PerfStat.Unit.Slot[PS_RW_CONTEXT] = sizeof(EXT2_RW_CONTEXT); /* 6 */
590 Ext2Global->PerfStat.Unit.Slot[PS_VPB] = sizeof(VPB); /* 7 */
591 Ext2Global->PerfStat.Unit.Slot[PS_FILE_NAME] = 1; /* 8 */
592 Ext2Global->PerfStat.Unit.Slot[PS_MCB_NAME] = 1; /* 9 */
593 Ext2Global->PerfStat.Unit.Slot[PS_INODE_NAME] = 1; /* a */
594 Ext2Global->PerfStat.Unit.Slot[PS_DIR_ENTRY] = sizeof(EXT2_DIR_ENTRY2); /* b */
595 Ext2Global->PerfStat.Unit.Slot[PS_DIR_PATTERN] = 1; /* c */
596 Ext2Global->PerfStat.Unit.Slot[PS_DISK_EVENT] = sizeof(KEVENT); /* d */
597 Ext2Global->PerfStat.Unit.Slot[PS_DISK_BUFFER] = 1; /* e */
598 Ext2Global->PerfStat.Unit.Slot[PS_BLOCK_DATA] = 1; /* f */
599 Ext2Global->PerfStat.Unit.Slot[PS_EXT2_INODE] = 1; /* 10 */
600 Ext2Global->PerfStat.Unit.Slot[PS_DENTRY] = sizeof(struct dentry); /* 11 */
601 Ext2Global->PerfStat.Unit.Slot[PS_BUFF_HEAD] = sizeof(struct buffer_head); /* 12 */
602
603 switch ( MmQuerySystemSize() ) {
604
605 case MmSmallSystem:
606
607 Ext2Global->MaxDepth = 64;
608 break;
609
610 case MmMediumSystem:
611
612 Ext2Global->MaxDepth = 128;
613 break;
614
615 case MmLargeSystem:
616
617 Ext2Global->MaxDepth = 256;
618 break;
619 }
620
621 //
622 // Initialize the Cache Manager callbacks
623 //
624
625 CacheManagerCallbacks = &(Ext2Global->CacheManagerCallbacks);
626 CacheManagerCallbacks->AcquireForLazyWrite = Ext2AcquireForLazyWrite;
627 CacheManagerCallbacks->ReleaseFromLazyWrite = Ext2ReleaseFromLazyWrite;
628 CacheManagerCallbacks->AcquireForReadAhead = Ext2AcquireForReadAhead;
629 CacheManagerCallbacks->ReleaseFromReadAhead = Ext2ReleaseFromReadAhead;
630
631 Ext2Global->CacheManagerNoOpCallbacks.AcquireForLazyWrite = Ext2NoOpAcquire;
632 Ext2Global->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = Ext2NoOpRelease;
633 Ext2Global->CacheManagerNoOpCallbacks.AcquireForReadAhead = Ext2NoOpAcquire;
634 Ext2Global->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = Ext2NoOpRelease;
635
636 //
637 // Initialize the global data
638 //
639
640 ExInitializeNPagedLookasideList( &(Ext2Global->Ext2IrpContextLookasideList),
641 NULL,
642 NULL,
643 0,
644 sizeof(EXT2_IRP_CONTEXT),
645 'PRIE',
646 0 );
647
648 ExInitializeNPagedLookasideList( &(Ext2Global->Ext2FcbLookasideList),
649 NULL,
650 NULL,
651 0,
652 sizeof(EXT2_FCB),
653 'BCFE',
654 0 );
655
656 ExInitializeNPagedLookasideList( &(Ext2Global->Ext2CcbLookasideList),
657 NULL,
658 NULL,
659 0,
660 sizeof(EXT2_CCB),
661 'BCCE',
662 0 );
663
664 ExInitializeNPagedLookasideList( &(Ext2Global->Ext2McbLookasideList),
665 NULL,
666 NULL,
667 0,
668 sizeof(EXT2_MCB),
669 'BCME',
670 0 );
671
672 ExInitializeNPagedLookasideList( &(Ext2Global->Ext2ExtLookasideList),
673 NULL,
674 NULL,
675 0,
676 sizeof(EXT2_EXTENT),
677 'STXE',
678 0 );
679
680 ExInitializeNPagedLookasideList( &(Ext2Global->Ext2DentryLookasideList),
681 NULL,
682 NULL,
683 0,
684 sizeof(struct dentry),
685 'TNED',
686 0 );
687
688 RtlInitUnicodeString(&DosDeviceName, DOS_DEVICE_NAME);
689 IoCreateSymbolicLink(&DosDeviceName, &DeviceName);
690
691 #if EXT2_DEBUG
692 ProcessNameOffset = Ext2GetProcessNameOffset();
693 #endif
694
695 Ext2LoadAllNls();
696
697 Ext2Global->Codepage.PageTable =
698 load_nls(Ext2Global->Codepage.AnsiName);
699
700 /* register file system devices for disk and cdrom */
701 IoRegisterFileSystem(DiskdevObject);
702 ObReferenceObject(DiskdevObject);
703
704 IoRegisterFileSystem(CdromdevObject);
705 ObReferenceObject(CdromdevObject);
706
707 errorout:
708
709 if (!NT_SUCCESS(Status)) {
710
711 /*
712 * stop reaper thread ...
713 */
714
715
716 /*
717 * cleanup resources ...
718 */
719
720 if (Ext2Global) {
721 ExDeleteResourceLite(&Ext2Global->Resource);
722 Ext2FreePool(Ext2Global, 'LG2E');
723 }
724
725 if (CdromdevObject) {
726 IoDeleteDevice(CdromdevObject);
727 }
728
729 if (DiskdevObject) {
730 IoDeleteDevice(DiskdevObject);
731 }
732
733 if (journal_module_inited) {
734 /* cleanup journal related caches */
735 UNLOAD_MODULE(journal_exit);
736 }
737
738 if (linux_lib_inited) {
739 /* cleanup linux lib */
740 ext2_destroy_linux();
741 }
742 }
743
744 return Status;
745 }