2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
10 /* INCLUDES *****************************************************************/
14 /* GLOBALS ***************************************************************/
16 PEXT2_GLOBAL Ext2Global
= NULL
;
19 * Ext2Fsd version, building date/time
21 CHAR gVersion
[] = EXT2FSD_VERSION
;
22 CHAR gTime
[] = __TIME__
;
23 CHAR gDate
[] = __DATE__
;
25 /* DEFINITIONS ***********************************************************/
29 IN PDRIVER_OBJECT DriverObject
,
30 IN PUNICODE_STRING RegistryPath
);
33 #pragma alloc_text(INIT, Ext2QueryGlobalParameters)
34 #pragma alloc_text(INIT, DriverEntry)
36 #pragma alloc_text(PAGE, DriverUnload)
40 /* FUNCTIONS ***************************************************************/
42 DECLARE_INIT(journal_init
);
43 DECLARE_EXIT(journal_exit
);
48 * FUNCTION: Called by the system to unload the driver
50 * DriverObject = object describing this driver
55 DriverUnload (IN PDRIVER_OBJECT DriverObject
)
58 UNICODE_STRING DosDeviceName
;
60 DEBUG(DL_FUN
, ( "Ext2Fsd: Unloading routine.\n"));
63 * stop reaper thread ...
68 * removing memory allocations and objects
71 RtlInitUnicodeString(&DosDeviceName
, DOS_DEVICE_NAME
);
72 IoDeleteSymbolicLink(&DosDeviceName
);
76 ExDeleteResourceLite(&Ext2Global
->Resource
);
78 ExDeleteNPagedLookasideList(&(Ext2Global
->Ext2DentryLookasideList
));
79 ExDeleteNPagedLookasideList(&(Ext2Global
->Ext2ExtLookasideList
));
80 ExDeleteNPagedLookasideList(&(Ext2Global
->Ext2McbLookasideList
));
81 ExDeleteNPagedLookasideList(&(Ext2Global
->Ext2CcbLookasideList
));
82 ExDeleteNPagedLookasideList(&(Ext2Global
->Ext2FcbLookasideList
));
83 ExDeleteNPagedLookasideList(&(Ext2Global
->Ext2IrpContextLookasideList
));
85 ObDereferenceObject(Ext2Global
->DiskdevObject
);
86 ObDereferenceObject(Ext2Global
->CdromdevObject
);
88 /* cleanup journal related caches */
89 UNLOAD_MODULE(journal_exit
);
91 /* cleanup linux lib */
94 Ext2FreePool(Ext2Global
, 'LG2E');
101 Ext2QueryGlobalParameters( IN PUNICODE_STRING RegistryPath
)
104 UNICODE_STRING ParameterPath
;
105 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
107 ULONG WritingSupport
= 0;
108 ULONG CheckingBitmap
= 0;
109 ULONG Ext3ForceWriting
= 0;
112 UNICODE_STRING UniName
;
113 ANSI_STRING AnsiName
;
115 WCHAR UniBuffer
[CODEPAGE_MAXLEN
];
116 USHORT Buffer
[HIDINGPAT_LEN
];
118 ParameterPath
.Length
= 0;
120 ParameterPath
.MaximumLength
=
121 RegistryPath
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(WCHAR
);
123 ParameterPath
.Buffer
=
124 (PWSTR
) Ext2AllocatePool(
126 ParameterPath
.MaximumLength
,
130 if (!ParameterPath
.Buffer
) {
132 DEBUG(DL_ERR
, ( "Ex2QueryParameters: failed to allocate Parameters...\n"));
136 RtlCopyUnicodeString(&ParameterPath
, RegistryPath
);
137 RtlAppendUnicodeToString(&ParameterPath
, PARAMETERS_KEY
);
139 /* querying value of WritingSupport */
140 RtlZeroMemory(&QueryTable
[0], sizeof(RTL_QUERY_REGISTRY_TABLE
) * 2);
142 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
143 QueryTable
[0].Name
= WRITING_SUPPORT
;
144 QueryTable
[0].EntryContext
= &WritingSupport
;
146 Status
= RtlQueryRegistryValues(
147 RTL_REGISTRY_ABSOLUTE
,
148 ParameterPath
.Buffer
,
153 DEBUG(DL_ERR
, ( "Ext2QueryParameters: WritingSupport=%xh\n", WritingSupport
));
155 /* querying value of CheckingBitmap */
156 RtlZeroMemory(&QueryTable
[0], sizeof(RTL_QUERY_REGISTRY_TABLE
) * 2);
157 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
158 QueryTable
[0].Name
= CHECKING_BITMAP
;
159 QueryTable
[0].EntryContext
= &CheckingBitmap
;
161 Status
= RtlQueryRegistryValues(
162 RTL_REGISTRY_ABSOLUTE
,
163 ParameterPath
.Buffer
,
168 DEBUG(DL_ERR
, ( "Ext2QueryParameters: CheckingBitmap=%xh\n", CheckingBitmap
));
170 /* querying value of Ext3ForceWriting */
171 RtlZeroMemory(&QueryTable
[0], sizeof(RTL_QUERY_REGISTRY_TABLE
) * 2);
172 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
173 QueryTable
[0].Name
= EXT3_FORCEWRITING
;
174 QueryTable
[0].EntryContext
= &Ext3ForceWriting
;
176 Status
= RtlQueryRegistryValues(
177 RTL_REGISTRY_ABSOLUTE
,
178 ParameterPath
.Buffer
,
183 DEBUG(DL_ERR
, ( "Ext2QueryParameters: Ext3ForceWriting=%xh\n", Ext3ForceWriting
));
186 /* querying value of AutoMount */
187 RtlZeroMemory(&QueryTable
[0], sizeof(RTL_QUERY_REGISTRY_TABLE
) * 2);
189 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
190 QueryTable
[0].Name
= AUTO_MOUNT
;
191 QueryTable
[0].EntryContext
= &AutoMount
;
193 Status
= RtlQueryRegistryValues(
194 RTL_REGISTRY_ABSOLUTE
,
195 ParameterPath
.Buffer
,
200 SetLongFlag(Ext2Global
->Flags
, EXT2_AUTO_MOUNT
);
201 if (NT_SUCCESS(Status
) && AutoMount
== 0) {
202 ClearLongFlag(Ext2Global
->Flags
, EXT2_AUTO_MOUNT
);
205 DEBUG(DL_ERR
, ( "Ext2QueryParameters: AutoMount=%xh\n", AutoMount
));
207 /* querying codepage */
208 RtlZeroMemory(&QueryTable
[0], sizeof(RTL_QUERY_REGISTRY_TABLE
) * 2);
209 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
210 QueryTable
[0].Name
= CODEPAGE_NAME
;
211 QueryTable
[0].EntryContext
= &(UniName
);
212 UniName
.MaximumLength
= CODEPAGE_MAXLEN
* sizeof(WCHAR
);
214 UniName
.Buffer
= (PWSTR
)UniBuffer
;
216 Status
= RtlQueryRegistryValues(
217 RTL_REGISTRY_ABSOLUTE
,
218 ParameterPath
.Buffer
,
223 if (NT_SUCCESS(Status
)) {
224 DEBUG(DL_ERR
, ( "Ext2QueryParameters: Ext2CodePage=%wZ\n", &UniName
));
225 AnsiName
.MaximumLength
= CODEPAGE_MAXLEN
;
227 AnsiName
.Buffer
= &(Ext2Global
->Codepage
.AnsiName
[0]);
229 Status
= RtlUnicodeStringToAnsiString(
234 if (!NT_SUCCESS(Status
)) {
235 DEBUG(DL_ERR
, ( "Ext2QueryParameters: Wrong CodePage %wZ ...\n", &UniName
));
236 RtlCopyMemory(&(Ext2Global
->Codepage
.AnsiName
[0]),"default\0", 8);
239 DEBUG(DL_ERR
, ( "Ext2QueryParameters: CodePage not specified.\n"));
240 RtlCopyMemory(&(Ext2Global
->Codepage
.AnsiName
[0]),"default\0", 8);
242 Ext2Global
->Codepage
.AnsiName
[CODEPAGE_MAXLEN
- 1] = 0;
244 /* querying name hiding patterns: prefix*/
245 RtlZeroMemory(&QueryTable
[0], sizeof(RTL_QUERY_REGISTRY_TABLE
) * 2);
246 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
247 QueryTable
[0].Name
= HIDING_PREFIX
;
248 QueryTable
[0].EntryContext
= &(UniName
);
249 UniName
.MaximumLength
= HIDINGPAT_LEN
* sizeof(WCHAR
);
251 UniName
.Buffer
= Buffer
;
253 Status
= RtlQueryRegistryValues(
254 RTL_REGISTRY_ABSOLUTE
,
255 ParameterPath
.Buffer
,
260 if (NT_SUCCESS(Status
)) {
261 DEBUG(DL_ERR
, ( "Ext2QueryParameters: HidingPrefix=%wZ\n", &UniName
));
262 AnsiName
.MaximumLength
=HIDINGPAT_LEN
;
264 AnsiName
.Buffer
= &(Ext2Global
->sHidingPrefix
[0]);
266 Status
= RtlUnicodeStringToAnsiString(
270 if (NT_SUCCESS(Status
)) {
271 Ext2Global
->bHidingPrefix
= TRUE
;
273 DEBUG(DL_ERR
, ( "Ext2QueryParameters: Wrong HidingPrefix ...\n"));
276 DEBUG(DL_ERR
, ( "Ext2QueryParameters: HidingPrefix not specified.\n"));
278 Ext2Global
->sHidingPrefix
[HIDINGPAT_LEN
- 1] = 0;
280 /* querying name hiding patterns: suffix */
281 RtlZeroMemory(&QueryTable
[0], sizeof(RTL_QUERY_REGISTRY_TABLE
) * 2);
282 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
283 QueryTable
[0].Name
= HIDING_SUFFIX
;
284 QueryTable
[0].EntryContext
= &(UniName
);
285 UniName
.MaximumLength
= HIDINGPAT_LEN
* sizeof(WCHAR
);
287 UniName
.Buffer
= Buffer
;
289 Status
= RtlQueryRegistryValues(
290 RTL_REGISTRY_ABSOLUTE
,
291 ParameterPath
.Buffer
,
297 if (NT_SUCCESS(Status
)) {
299 DEBUG(DL_ERR
, ( "Ext2QueryParameters: HidingSuffix=%wZ\n", &UniName
));
300 AnsiName
.MaximumLength
= HIDINGPAT_LEN
;
302 AnsiName
.Buffer
= &(Ext2Global
->sHidingSuffix
[0]);
304 Status
= RtlUnicodeStringToAnsiString(
308 if (NT_SUCCESS(Status
)) {
309 Ext2Global
->bHidingSuffix
= TRUE
;
311 DEBUG(DL_ERR
, ( "Ext2QueryParameters: Wrong HidingSuffix ...\n"));
314 DEBUG(DL_ERR
, ( "Ext2QueryParameters: HidingSuffix not specified.\n"));
316 Ext2Global
->sHidingPrefix
[HIDINGPAT_LEN
- 1] = 0;
319 if (WritingSupport
) {
320 SetLongFlag(Ext2Global
->Flags
, EXT2_SUPPORT_WRITING
);
322 ClearLongFlag(Ext2Global
->Flags
, EXT2_SUPPORT_WRITING
);
325 if (CheckingBitmap
) {
326 SetLongFlag(Ext2Global
->Flags
, EXT2_CHECKING_BITMAP
);
328 ClearLongFlag(Ext2Global
->Flags
, EXT2_CHECKING_BITMAP
);
331 if (Ext3ForceWriting
) {
332 DEBUG(DL_WRN
, ("Ext2Fsd -- Warning: Ext3ForceWriting enabled !!!\n"));
334 SetLongFlag(Ext2Global
->Flags
, EXT3_FORCE_WRITING
);
335 SetLongFlag(Ext2Global
->Flags
, EXT2_SUPPORT_WRITING
);
337 ClearLongFlag(Ext2Global
->Flags
, EXT3_FORCE_WRITING
);
341 Ext2Global
->RegistryPath
.Buffer
= ParameterPath
.Buffer
;
342 Ext2Global
->RegistryPath
.Length
= 0;
343 Ext2Global
->RegistryPath
.MaximumLength
= ParameterPath
.MaximumLength
;
344 RtlCopyUnicodeString(&Ext2Global
->RegistryPath
, RegistryPath
);
345 RtlAppendUnicodeToString(&Ext2Global
->RegistryPath
, VOLUMES_KEY
);
351 #define NLS_OEM_LEAD_BYTE_INFO (*NlsOemLeadByteInfo)
354 #define FsRtlIsLeadDbcsCharacter(DBCS_CHAR) ( \
355 (BOOLEAN)((UCHAR)(DBCS_CHAR) < 0x80 ? FALSE : \
356 (NLS_MB_CODE_PAGE_TAG && \
357 (NLS_OEM_LEAD_BYTE_INFO[(UCHAR)(DBCS_CHAR)] != 0))) \
364 * FUNCTION: Called by the system to initalize the driver
367 * DriverObject = object describing this driver
368 * RegistryPath = path to our configuration entries
369 * RETURNS: Success or failure
373 IN PDRIVER_OBJECT DriverObject
,
374 IN PUNICODE_STRING RegistryPath
377 PDEVICE_OBJECT DiskdevObject
= NULL
;
378 PDEVICE_OBJECT CdromdevObject
= NULL
;
379 UNICODE_STRING DeviceName
;
380 UNICODE_STRING DosDeviceName
;
382 PFAST_IO_DISPATCH FastIoDispatch
;
383 PCACHE_MANAGER_CALLBACKS CacheManagerCallbacks
;
385 LARGE_INTEGER Timeout
;
389 BOOLEAN linux_lib_inited
= FALSE
;
390 BOOLEAN journal_module_inited
= FALSE
;
392 /* Verify ERESOURCE alignment in structures */
393 ASSERT((FIELD_OFFSET(EXT2_GLOBAL
, Resource
) & 7) == 0);
394 ASSERT((FIELD_OFFSET(EXT2_VCB
, MainResource
) & 7) == 0);
395 ASSERT((FIELD_OFFSET(EXT2_VCB
, PagingIoResource
) & 7) == 0);
396 ASSERT((FIELD_OFFSET(EXT2_VCB
, MetaLock
) & 7) == 0);
397 ASSERT((FIELD_OFFSET(EXT2_VCB
, McbLock
) & 7) == 0);
398 ASSERT((FIELD_OFFSET(EXT2_FCBVCB
, MainResource
) & 7) == 0);
399 ASSERT((FIELD_OFFSET(EXT2_FCBVCB
, PagingIoResource
) & 7) == 0);
400 ASSERT((FIELD_OFFSET(EXT2_FCB
, MainResource
) & 7) == 0);
401 ASSERT((FIELD_OFFSET(EXT2_FCB
, PagingIoResource
) & 7) == 0);
403 /* Verity super block ... */
404 ASSERT(sizeof(EXT2_SUPER_BLOCK
) == 1024);
405 ASSERT(FIELD_OFFSET(EXT2_SUPER_BLOCK
, s_magic
) == 56);
409 #ifdef _WIN2K_TARGET_
423 DEBUG(DL_FUN
, ( "Ext2 DriverEntry ...\n"));
425 /* initialize winlib structures */
426 if (ext2_init_linux()) {
427 Status
= STATUS_INSUFFICIENT_RESOURCES
;
430 linux_lib_inited
= TRUE
;
432 /* initialize journal module structures */
433 LOAD_MODULE(journal_init
);
435 Status
= STATUS_INSUFFICIENT_RESOURCES
;
438 journal_module_inited
= TRUE
;
440 /* allocate memory for Ext2Global */
441 Ext2Global
= Ext2AllocatePool(NonPagedPool
, sizeof(EXT2_GLOBAL
), 'LG2E');
443 Status
= STATUS_INSUFFICIENT_RESOURCES
;
447 /* initialize Ext2Global */
448 RtlZeroMemory(Ext2Global
, sizeof(EXT2_GLOBAL
));
449 Ext2Global
->Identifier
.Type
= EXT2FGD
;
450 Ext2Global
->Identifier
.Size
= sizeof(EXT2_GLOBAL
);
452 InitializeListHead(&(Ext2Global
->VcbList
));
453 ExInitializeResourceLite(&(Ext2Global
->Resource
));
455 /* Reaper thread engine event */
456 KeInitializeEvent(&Ext2Global
->Reaper
.Engine
,
457 SynchronizationEvent
, FALSE
);
459 /* query registry settings */
460 Ext2QueryGlobalParameters(RegistryPath
);
462 /* create Ext2Fsd cdrom fs deivce */
463 RtlInitUnicodeString(&DeviceName
, CDROM_NAME
);
464 Status
= IoCreateDevice(
468 FILE_DEVICE_CD_ROM_FILE_SYSTEM
,
473 if (!NT_SUCCESS(Status
)) {
474 DEBUG(DL_ERR
, ( "IoCreateDevice cdrom device object error.\n"));
478 /* create Ext2Fsd disk fs deivce */
479 RtlInitUnicodeString(&DeviceName
, DEVICE_NAME
);
480 Status
= IoCreateDevice(
484 FILE_DEVICE_DISK_FILE_SYSTEM
,
489 if (!NT_SUCCESS(Status
)) {
490 DEBUG(DL_ERR
, ( "IoCreateDevice disk device object error.\n"));
494 /* start resource reaper thread */
495 Status
= Ext2StartReaperThread();
496 if (!NT_SUCCESS(Status
)) {
499 /* make sure Reaperthread is started */
500 Timeout
.QuadPart
= (LONGLONG
)-10*1000*1000*10; /* 10 seconds */
501 Status
= KeWaitForSingleObject(
502 &(Ext2Global
->Reaper
.Engine
),
508 if (Status
!= STATUS_SUCCESS
) {
509 Status
= STATUS_INSUFFICIENT_RESOURCES
;
514 Ext2Global
->DiskdevObject
= DiskdevObject
;
515 Ext2Global
->CdromdevObject
= CdromdevObject
;
517 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = Ext2BuildRequest
;
518 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = Ext2BuildRequest
;
519 DriverObject
->MajorFunction
[IRP_MJ_READ
] = Ext2BuildRequest
;
520 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = Ext2BuildRequest
;
522 DriverObject
->MajorFunction
[IRP_MJ_FLUSH_BUFFERS
] = Ext2BuildRequest
;
523 DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = Ext2BuildRequest
;
525 DriverObject
->MajorFunction
[IRP_MJ_QUERY_INFORMATION
] = Ext2BuildRequest
;
526 DriverObject
->MajorFunction
[IRP_MJ_SET_INFORMATION
] = Ext2BuildRequest
;
528 DriverObject
->MajorFunction
[IRP_MJ_QUERY_VOLUME_INFORMATION
] = Ext2BuildRequest
;
529 DriverObject
->MajorFunction
[IRP_MJ_SET_VOLUME_INFORMATION
] = Ext2BuildRequest
;
531 DriverObject
->MajorFunction
[IRP_MJ_DIRECTORY_CONTROL
] = Ext2BuildRequest
;
532 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = Ext2BuildRequest
;
533 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = Ext2BuildRequest
;
534 DriverObject
->MajorFunction
[IRP_MJ_LOCK_CONTROL
] = Ext2BuildRequest
;
536 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = Ext2BuildRequest
;
538 #if (_WIN32_WINNT >= 0x0500)
539 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = Ext2BuildRequest
;
540 #endif //(_WIN32_WINNT >= 0x0500)
543 DriverObject
->DriverUnload
= DriverUnload
;
545 DriverObject
->DriverUnload
= NULL
;
549 // Initialize the fast I/O entry points
552 FastIoDispatch
= &(Ext2Global
->FastIoDispatch
);
554 FastIoDispatch
->SizeOfFastIoDispatch
= sizeof(FAST_IO_DISPATCH
);
555 FastIoDispatch
->FastIoCheckIfPossible
= Ext2FastIoCheckIfPossible
;
556 FastIoDispatch
->FastIoRead
= Ext2FastIoRead
;
557 FastIoDispatch
->FastIoWrite
= Ext2FastIoWrite
;
558 FastIoDispatch
->FastIoQueryBasicInfo
= Ext2FastIoQueryBasicInfo
;
559 FastIoDispatch
->FastIoQueryStandardInfo
= Ext2FastIoQueryStandardInfo
;
560 FastIoDispatch
->FastIoLock
= Ext2FastIoLock
;
561 FastIoDispatch
->FastIoUnlockSingle
= Ext2FastIoUnlockSingle
;
562 FastIoDispatch
->FastIoUnlockAll
= Ext2FastIoUnlockAll
;
563 FastIoDispatch
->FastIoUnlockAllByKey
= Ext2FastIoUnlockAllByKey
;
564 FastIoDispatch
->FastIoQueryNetworkOpenInfo
= Ext2FastIoQueryNetworkOpenInfo
;
565 FastIoDispatch
->AcquireForModWrite
= Ext2AcquireFileForModWrite
;
566 FastIoDispatch
->ReleaseForModWrite
= Ext2ReleaseFileForModWrite
;
567 FastIoDispatch
->AcquireForCcFlush
= Ext2AcquireFileForCcFlush
;
568 FastIoDispatch
->ReleaseForCcFlush
= Ext2ReleaseFileForCcFlush
;
569 FastIoDispatch
->AcquireFileForNtCreateSection
= Ext2AcquireForCreateSection
;
570 FastIoDispatch
->ReleaseFileForNtCreateSection
= Ext2ReleaseForCreateSection
;
571 DriverObject
->FastIoDispatch
= FastIoDispatch
;
574 // initializing structure sizes for statistics
575 // 1 means flexible/not fixed for all allocations (for different volumes).
577 Ext2Global
->PerfStat
.Magic
= EXT2_PERF_STAT_MAGIC
;
578 Ext2Global
->PerfStat
.Version
= EXT2_PERF_STAT_VER2
;
579 Ext2Global
->PerfStat
.Length
= sizeof(EXT2_PERF_STATISTICS_V2
);
581 Ext2Global
->PerfStat
.Unit
.Slot
[PS_IRP_CONTEXT
] = sizeof(EXT2_IRP_CONTEXT
); /* 0 */
582 Ext2Global
->PerfStat
.Unit
.Slot
[PS_VCB
] = sizeof(EXT2_VCB
); /* 1 */
583 Ext2Global
->PerfStat
.Unit
.Slot
[PS_FCB
] = sizeof(EXT2_FCB
); /* 2 */
584 Ext2Global
->PerfStat
.Unit
.Slot
[PS_CCB
] = sizeof(EXT2_CCB
); /* 3 */
585 Ext2Global
->PerfStat
.Unit
.Slot
[PS_MCB
] = sizeof(EXT2_MCB
); /* 4 */
586 Ext2Global
->PerfStat
.Unit
.Slot
[PS_EXTENT
] = sizeof(EXT2_EXTENT
); /* 5 */
587 Ext2Global
->PerfStat
.Unit
.Slot
[PS_RW_CONTEXT
] = sizeof(EXT2_RW_CONTEXT
); /* 6 */
588 Ext2Global
->PerfStat
.Unit
.Slot
[PS_VPB
] = sizeof(VPB
); /* 7 */
589 Ext2Global
->PerfStat
.Unit
.Slot
[PS_FILE_NAME
] = 1; /* 8 */
590 Ext2Global
->PerfStat
.Unit
.Slot
[PS_MCB_NAME
] = 1; /* 9 */
591 Ext2Global
->PerfStat
.Unit
.Slot
[PS_INODE_NAME
] = 1; /* a */
592 Ext2Global
->PerfStat
.Unit
.Slot
[PS_DIR_ENTRY
] = sizeof(EXT2_DIR_ENTRY2
); /* b */
593 Ext2Global
->PerfStat
.Unit
.Slot
[PS_DIR_PATTERN
] = 1; /* c */
594 Ext2Global
->PerfStat
.Unit
.Slot
[PS_DISK_EVENT
] = sizeof(KEVENT
); /* d */
595 Ext2Global
->PerfStat
.Unit
.Slot
[PS_DISK_BUFFER
] = 1; /* e */
596 Ext2Global
->PerfStat
.Unit
.Slot
[PS_BLOCK_DATA
] = 1; /* f */
597 Ext2Global
->PerfStat
.Unit
.Slot
[PS_EXT2_INODE
] = 1; /* 10 */
598 Ext2Global
->PerfStat
.Unit
.Slot
[PS_DENTRY
] = sizeof(struct dentry
); /* 11 */
599 Ext2Global
->PerfStat
.Unit
.Slot
[PS_BUFF_HEAD
] = sizeof(struct buffer_head
); /* 12 */
601 switch ( MmQuerySystemSize() ) {
605 Ext2Global
->MaxDepth
= 64;
610 Ext2Global
->MaxDepth
= 128;
615 Ext2Global
->MaxDepth
= 256;
620 // Initialize the Cache Manager callbacks
623 CacheManagerCallbacks
= &(Ext2Global
->CacheManagerCallbacks
);
624 CacheManagerCallbacks
->AcquireForLazyWrite
= Ext2AcquireForLazyWrite
;
625 CacheManagerCallbacks
->ReleaseFromLazyWrite
= Ext2ReleaseFromLazyWrite
;
626 CacheManagerCallbacks
->AcquireForReadAhead
= Ext2AcquireForReadAhead
;
627 CacheManagerCallbacks
->ReleaseFromReadAhead
= Ext2ReleaseFromReadAhead
;
629 Ext2Global
->CacheManagerNoOpCallbacks
.AcquireForLazyWrite
= Ext2NoOpAcquire
;
630 Ext2Global
->CacheManagerNoOpCallbacks
.ReleaseFromLazyWrite
= Ext2NoOpRelease
;
631 Ext2Global
->CacheManagerNoOpCallbacks
.AcquireForReadAhead
= Ext2NoOpAcquire
;
632 Ext2Global
->CacheManagerNoOpCallbacks
.ReleaseFromReadAhead
= Ext2NoOpRelease
;
635 // Initialize the global data
638 ExInitializeNPagedLookasideList( &(Ext2Global
->Ext2IrpContextLookasideList
),
642 sizeof(EXT2_IRP_CONTEXT
),
646 ExInitializeNPagedLookasideList( &(Ext2Global
->Ext2FcbLookasideList
),
654 ExInitializeNPagedLookasideList( &(Ext2Global
->Ext2CcbLookasideList
),
662 ExInitializeNPagedLookasideList( &(Ext2Global
->Ext2McbLookasideList
),
670 ExInitializeNPagedLookasideList( &(Ext2Global
->Ext2ExtLookasideList
),
678 ExInitializeNPagedLookasideList( &(Ext2Global
->Ext2DentryLookasideList
),
682 sizeof(struct dentry
),
686 RtlInitUnicodeString(&DosDeviceName
, DOS_DEVICE_NAME
);
687 IoCreateSymbolicLink(&DosDeviceName
, &DeviceName
);
690 ProcessNameOffset
= Ext2GetProcessNameOffset();
695 Ext2Global
->Codepage
.PageTable
=
696 load_nls(Ext2Global
->Codepage
.AnsiName
);
698 /* register file system devices for disk and cdrom */
699 IoRegisterFileSystem(DiskdevObject
);
700 ObReferenceObject(DiskdevObject
);
702 IoRegisterFileSystem(CdromdevObject
);
703 ObReferenceObject(CdromdevObject
);
707 if (!NT_SUCCESS(Status
)) {
710 * stop reaper thread ...
715 * cleanup resources ...
719 ExDeleteResourceLite(&Ext2Global
->Resource
);
720 Ext2FreePool(Ext2Global
, 'LG2E');
723 if (CdromdevObject
) {
724 IoDeleteDevice(CdromdevObject
);
728 IoDeleteDevice(DiskdevObject
);
731 if (journal_module_inited
) {
732 /* cleanup journal related caches */
733 UNLOAD_MODULE(journal_exit
);
736 if (linux_lib_inited
) {
737 /* cleanup linux lib */
738 ext2_destroy_linux();