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