|
|
1.1.1.2 ! root 1: /* Copyright (C) 2004 TrueCrypt Foundation 1.1 root 2: This product uses components written by Paul Le Roux <[email protected]> */ 3: 4: #include "TCdefs.h" 5: #include "crypto.h" 6: #include "fat.h" 7: 8: #include "apidrvr.h" 9: #include "ntdriver.h" 10: #include "ntvol.h" 11: #include "ntrawdv.h" 12: #include "ntfiledv.h" 13: #include "cache.h" 14: 15: #include <tchar.h> 16: #include <initguid.h> 17: #include <mountmgr.h> 18: #include <mountdev.h> 19: #include <ntddvol.h> 20: 21: /* Init section, which is thrown away as soon as DriverEntry returns */ 22: #pragma alloc_text(INIT,DriverEntry) 23: #pragma alloc_text(INIT,TCCreateRootDeviceObject) 24: 25: /* Sync. mutex for above password data */ 26: KMUTEX driverMutex; 27: 28: /* DriverEntry initialize's the dispatch addresses to be passed back to NT. 29: RUNS AT IRQL = PASSIVE_LEVEL(0) */ 30: NTSTATUS 31: DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 32: { 33: if (RegistryPath); /* Remove warning */ 34: 35: DriverObject->MajorFunction[IRP_MJ_CREATE] = TCDispatchQueueIRP; 36: DriverObject->MajorFunction[IRP_MJ_CLOSE] = TCDispatchQueueIRP; 37: DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TCDispatchQueueIRP; 38: DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = TCDispatchQueueIRP; 39: DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = TCDispatchQueueIRP; 40: DriverObject->MajorFunction[IRP_MJ_READ] = TCDispatchQueueIRP; 41: DriverObject->MajorFunction[IRP_MJ_WRITE] = TCDispatchQueueIRP; 42: DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TCDispatchQueueIRP; 43: 44: DriverObject->DriverUnload = TCUnloadDriver; 45: 46: KeInitializeMutex (&driverMutex, 1); 47: 48: return TCCreateRootDeviceObject (DriverObject); 49: } 50: 51: #ifdef _DEBUG 52: // Dumps a memory region to debug output 53: void DumpMem(unsigned char *mem, int len) 54: { 55: unsigned char str[20]; 56: unsigned char *m = mem; 57: int i,j; 58: 59: for (j=0;j<len/8;j++) 60: { 61: memset (str,0,sizeof str); 62: for (i=0;i<8;i++) 63: { 64: if (m[i] > ' ' && m[i] < '~') 65: str[i]=m[i]; 66: else 67: str[i]='.'; 68: } 69: 70: Dump ("0x%08x %02x %02x %02x %02x %02x %02x %02x %02x %s", 71: m, m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], str); 72: 73: m+=8; 74: } 75: } 76: #endif 77: 78: /* TCDispatchQueueIRP queues any IRP's so that they can be processed later 79: by the thread -- or in some cases handles them immediately! */ 80: NTSTATUS 81: TCDispatchQueueIRP (PDEVICE_OBJECT DeviceObject, PIRP Irp) 82: { 83: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension; 84: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 85: NTSTATUS ntStatus; 86: 87: #ifdef USE_KERNEL_MUTEX 88: if (Extension->bRootDevice == FALSE) 89: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode, 90: FALSE, NULL); 91: #endif 92: 93: #ifdef _DEBUG 94: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL) 95: Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x IoControlCode = %ls 0x%08x\n", 96: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction, 97: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode), 98: (int) irpSp->Parameters.DeviceIoControl.IoControlCode); 99: //else 100: // Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x\n", 101: // TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction); 102: #endif 103: 104: if (Extension->bRootDevice == FALSE) 105: { 106: if (irpSp->MajorFunction == IRP_MJ_READ || irpSp->MajorFunction == IRP_MJ_WRITE || 107: irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL) 108: { 109: if ((DeviceObject->Flags & DO_VERIFY_VOLUME)) 110: { 111: if (!(irpSp->Flags & SL_OVERRIDE_VERIFY_VOLUME)) 112: { 113: Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED; 114: Irp->IoStatus.Information = 0; 115: if (!NT_SUCCESS (Irp->IoStatus.Status) && 116: IoIsErrorUserInduced (Irp->IoStatus.Status)) 117: { 118: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject); 119: } 120: ntStatus = Irp->IoStatus.Status; 121: IoCompleteRequest (Irp, IO_NO_INCREMENT); 122: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 123: #ifdef USE_KERNEL_MUTEX 124: if (Extension->bRootDevice == FALSE) 125: KeReleaseMutex (&Extension->KernelMutex, FALSE); 126: #endif 127: return ntStatus; 128: } 129: else if (Extension->bShuttingDown == TRUE) 130: { 131: Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; 132: Irp->IoStatus.Information = 0; 133: if (!NT_SUCCESS (Irp->IoStatus.Status) && 134: IoIsErrorUserInduced (Irp->IoStatus.Status)) 135: { 136: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject); 137: } 138: ntStatus = Irp->IoStatus.Status; 139: IoCompleteRequest (Irp, IO_NO_INCREMENT); 140: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 141: #ifdef USE_KERNEL_MUTEX 142: if (Extension->bRootDevice == FALSE) 143: KeReleaseMutex (&Extension->KernelMutex, FALSE); 144: #endif 145: return ntStatus; 146: } 147: } 148: else if (Extension->bShuttingDown == TRUE) 149: { 150: if (DeviceObject->Vpb && DeviceObject->Vpb->Flags & VPB_MOUNTED) 151: { 152: Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE; 153: Irp->IoStatus.Information = 0; 154: if (!NT_SUCCESS (Irp->IoStatus.Status) && 155: IoIsErrorUserInduced (Irp->IoStatus.Status)) 156: { 157: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject); 158: } 159: DeviceObject->Flags |= DO_VERIFY_VOLUME; 160: } 161: else 162: { 163: Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; 164: Irp->IoStatus.Information = 0; 165: } 166: 167: ntStatus = Irp->IoStatus.Status; 168: IoCompleteRequest (Irp, IO_NO_INCREMENT); 169: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 170: #ifdef USE_KERNEL_MUTEX 171: if (Extension->bRootDevice == FALSE) 172: KeReleaseMutex (&Extension->KernelMutex, FALSE); 173: #endif 174: return ntStatus; 175: } 176: } 177: else if ((DeviceObject->Flags & DO_VERIFY_VOLUME)) 178: { /* If shutting down or media removed */ 179: if (Extension->bShuttingDown == TRUE) 180: { 181: Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED; 182: Irp->IoStatus.Information = 0; 183: if (!NT_SUCCESS (Irp->IoStatus.Status) && 184: IoIsErrorUserInduced (Irp->IoStatus.Status)) 185: { 186: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject); 187: } 188: ntStatus = Irp->IoStatus.Status; 189: IoCompleteRequest (Irp, IO_NO_INCREMENT); 190: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 191: #ifdef USE_KERNEL_MUTEX 192: if (Extension->bRootDevice == FALSE) 193: KeReleaseMutex (&Extension->KernelMutex, FALSE); 194: #endif 195: return ntStatus; 196: } 197: else 198: { 199: Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; 200: Irp->IoStatus.Information = 0; 201: ntStatus = Irp->IoStatus.Status; 202: IoCompleteRequest (Irp, IO_NO_INCREMENT); 203: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 204: #ifdef USE_KERNEL_MUTEX 205: if (Extension->bRootDevice == FALSE) 206: KeReleaseMutex (&Extension->KernelMutex, FALSE); 207: #endif 208: return ntStatus; 209: } 210: } 211: } 212: 213: switch (irpSp->MajorFunction) 214: { 215: case IRP_MJ_CLOSE: 216: case IRP_MJ_CREATE: 217: case IRP_MJ_CLEANUP: 218: #ifdef USE_KERNEL_MUTEX 219: if (Extension->bRootDevice == FALSE) 220: KeReleaseMutex (&Extension->KernelMutex, FALSE); 221: #endif 222: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 223: 224: case IRP_MJ_SHUTDOWN: 225: case IRP_MJ_FLUSH_BUFFERS: 226: case IRP_MJ_READ: 227: case IRP_MJ_WRITE: 228: case IRP_MJ_DEVICE_CONTROL: 229: if (Extension->bRootDevice == FALSE) 230: { 231: ASSERT (Extension->bShuttingDown == FALSE); 232: 233: IoMarkIrpPending (Irp); 234: 235: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL || 236: KeGetCurrentIrql ()== APC_LEVEL); 237: 238: ExInterlockedInsertTailList ( 239: &Extension->ListEntry, 240: &Irp->Tail.Overlay.ListEntry, 241: &Extension->ListSpinLock); 242: 243: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL || 244: KeGetCurrentIrql ()== APC_LEVEL); 245: 246: KeReleaseSemaphore ( 247: &Extension->RequestSemaphore, 248: (KPRIORITY) 0, 249: 1, 250: FALSE); 251: 252: //Dump ("TCDispatchQueueIRP STATUS_PENDING END\n"); 253: #ifdef USE_KERNEL_MUTEX 254: if (Extension->bRootDevice == FALSE) 255: KeReleaseMutex (&Extension->KernelMutex, FALSE); 256: #endif 257: return STATUS_PENDING; 258: } 259: else 260: { 261: if (irpSp->Parameters.DeviceIoControl.IoControlCode >= TC_FIRST_PRIVATE && 262: irpSp->Parameters.DeviceIoControl.IoControlCode <= TC_LAST_PRIVATE) 263: { 264: ntStatus = TCDeviceControl (DeviceObject, Extension, Irp); 265: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 266: #ifdef USE_KERNEL_MUTEX 267: if (Extension->bRootDevice == FALSE) 268: KeReleaseMutex (&Extension->KernelMutex, FALSE); 269: #endif 270: return ntStatus; 271: } 272: 273: if (irpSp->MajorFunction == IRP_MJ_FLUSH_BUFFERS || irpSp->MajorFunction == IRP_MJ_SHUTDOWN) 274: { 275: #ifdef USE_KERNEL_MUTEX 276: if (Extension->bRootDevice == FALSE) 277: KeReleaseMutex (&Extension->KernelMutex, FALSE); 278: #endif 279: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 280: } 281: } 282: 283: #ifdef USE_KERNEL_MUTEX 284: if (Extension->bRootDevice == FALSE) 285: KeReleaseMutex (&Extension->KernelMutex, FALSE); 286: #endif 287: 288: return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0); 289: } 290: 291: #ifdef _DEBUG 292: Dump ("ERROR: Unknown irpSp->MajorFunction in TCDispatchQueueIRP %ls 0x%08x END\n", 293: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction); 294: #endif 295: 296: #ifdef USE_KERNEL_MUTEX 297: if (Extension->bRootDevice == FALSE) 298: KeReleaseMutex (&Extension->KernelMutex, FALSE); 299: #endif 300: return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0); 301: } 302: 303: NTSTATUS 304: TCCreateRootDeviceObject (PDRIVER_OBJECT DriverObject) 305: { 306: UNICODE_STRING Win32NameString, ntUnicodeString; 307: WCHAR dosname[32], ntname[32]; 308: PDEVICE_OBJECT DeviceObject; 309: NTSTATUS ntStatus; 310: BOOL *bRootExtension; 311: 312: Dump ("TCCreateRootDeviceObject BEGIN\n"); 313: 314: wcscpy (dosname, (LPWSTR) DOS_ROOT_PREFIX); 315: wcscpy (ntname, (LPWSTR) NT_ROOT_PREFIX); 316: RtlInitUnicodeString (&ntUnicodeString, ntname); 317: RtlInitUnicodeString (&Win32NameString, dosname); 318: 319: Dump ("Creating root device nt=%ls dos=%ls\n", ntname, dosname); 320: 321: ntStatus = IoCreateDevice ( 322: DriverObject, /* Our Driver Object */ 323: sizeof (BOOL), /* Size of state information */ 324: &ntUnicodeString, /* Device name "\Device\Name" */ 325: FILE_DEVICE_DISK, /* Device type */ 326: 0, /* Device characteristics */ 327: FALSE, /* Exclusive device */ 328: &DeviceObject); /* Returned ptr to Device Object */ 329: 330: if (!NT_SUCCESS (ntStatus)) 331: { 332: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus); 333: return ntStatus;/* Failed to create DeviceObject */ 334: } 335: 336: DeviceObject->Flags |= DO_DIRECT_IO; 337: DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT; 338: 339: /* Setup the device extension */ 340: bRootExtension = (BOOL *) DeviceObject->DeviceExtension; 341: *bRootExtension = TRUE; 342: 343: /* The symlinks for mount devices are created from user-mode */ 344: ntStatus = IoCreateSymbolicLink (&Win32NameString, &ntUnicodeString); 345: if (!NT_SUCCESS (ntStatus)) 346: { 347: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus); 348: IoDeleteDevice (DeviceObject); 349: return ntStatus; 350: } 351: 352: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 353: Dump ("TCCreateRootDeviceObject STATUS_SUCCESS END\n"); 354: return STATUS_SUCCESS; 355: } 356: 357: NTSTATUS 358: TCCreateDeviceObject (PDRIVER_OBJECT DriverObject, 359: PDEVICE_OBJECT * ppDeviceObject, 360: int nDosDriveNo) 361: { 362: UNICODE_STRING Win32NameString, ntUnicodeString; 363: WCHAR dosname[32], ntname[32]; 364: PEXTENSION Extension; 365: NTSTATUS ntStatus; 366: 367: Dump ("TCCreateDeviceObject BEGIN\n"); 368: 369: TCGetDosNameFromNumber (dosname, nDosDriveNo); 370: TCGetNTNameFromNumber (ntname, nDosDriveNo); 371: RtlInitUnicodeString (&ntUnicodeString, ntname); 372: RtlInitUnicodeString (&Win32NameString, dosname); 373: 374: Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname); 375: 376: ntStatus = IoCreateDevice ( 377: DriverObject, /* Our Driver Object */ 378: sizeof (EXTENSION), /* Size of state information */ 379: &ntUnicodeString, /* Device name "\Device\Name" */ 380: FILE_DEVICE_DISK, /* Device type */ 381: 0, /* Device characteristics */ 382: FALSE, /* Exclusive device */ 383: ppDeviceObject); /* Returned ptr to Device Object */ 384: 385: if (!NT_SUCCESS (ntStatus)) 386: { 387: Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus); 388: return ntStatus;/* Failed to create DeviceObject */ 389: } 390: /* Initialize device object and extension. */ 391: 392: (*ppDeviceObject)->Flags |= DO_DIRECT_IO; 393: (*ppDeviceObject)->AlignmentRequirement = FILE_WORD_ALIGNMENT; 394: 395: /* Setup the device extension */ 396: Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension; 397: memset (Extension, 0, sizeof (EXTENSION)); 398: 399: Extension->lMagicNumber = 0xabfeacde; 400: Extension->nDosDriveNo = nDosDriveNo; 401: 402: KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE); 403: KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG); 404: #ifdef USE_KERNEL_MUTEX 405: KeInitializeMutex (&Extension->KernelMutex, 1); 406: #endif 407: KeInitializeSpinLock (&Extension->ListSpinLock); 408: InitializeListHead (&Extension->ListEntry); 409: 410: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 411: Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n"); 412: 413: return STATUS_SUCCESS; 414: } 415: 416: /* TCDeviceControl handles certain requests from NT, these are needed for NT 417: to recognize the drive, also this function handles our device specific 418: function codes, such as mount/unmount */ 419: NTSTATUS 420: TCDeviceControl (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp) 421: { 422: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 423: NTSTATUS ntStatus; 424: 425: #ifdef _DEBUG 426: Dump ("TCDeviceControl BEGIN IoControlCode = %ls 0x%08x\n", 427: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode), 428: irpSp->Parameters.DeviceIoControl.IoControlCode); 429: #endif 430: 431: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; /* Assume failure. */ 432: 433: /* Determine which I/O control code was specified. */ 434: switch (irpSp->Parameters.DeviceIoControl.IoControlCode) 435: { 436: 437: case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: 438: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_NAME)) 439: { 440: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME); 441: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 442: } 443: else 444: { 445: ULONG outLength; 446: UNICODE_STRING ntUnicodeString; 447: WCHAR ntName[64]; 448: PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer; 449: 450: Dump("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:"); 451: 452: TCGetNTNameFromNumber (ntName, Extension->nDosDriveNo); 453: RtlInitUnicodeString (&ntUnicodeString, ntName); 454: 455: outputBuffer->NameLength = ntUnicodeString.Length; 456: outLength = ntUnicodeString.Length + sizeof(USHORT); 457: 458: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) 459: { 460: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME); 461: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 462: 463: break; 464: } 465: 466: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length); 467: 468: Irp->IoStatus.Status = STATUS_SUCCESS; 469: Irp->IoStatus.Information = outLength; 470: 471: Dump ("name = %ls\n",ntName); 472: } 473: break; 474: 475: case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: 476: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_UNIQUE_ID)) 477: { 478: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID); 479: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 480: } 481: else 482: { 483: ULONG outLength; 484: UCHAR volId[128], tmp[] = { 0,0 }; 485: PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer; 486: 487: Dump("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:"); 488: 489: strcpy (volId, TC_UNIQUE_ID_PREFIX); 490: tmp[0] = 'A' + Extension->nDosDriveNo; 491: strcat (volId, tmp); 492: 493: outputBuffer->UniqueIdLength = (USHORT) strlen(volId); 494: outLength = strlen(volId) + sizeof(USHORT); 495: 496: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) 497: { 498: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID); 499: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 500: break; 501: } 502: 503: RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen(volId)); 504: 505: Irp->IoStatus.Status = STATUS_SUCCESS; 506: Irp->IoStatus.Information = outLength; 507: 508: Dump ("id = %s\n",volId); 509: } 510: break; 511: 512: case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME: 513: { 514: ULONG outLength; 515: UNICODE_STRING ntUnicodeString; 516: WCHAR ntName[64]; 517: PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer; 518: 519: Dump("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:"); 520: 521: TCGetDosNameFromNumber (ntName, Extension->nDosDriveNo); 522: RtlInitUnicodeString (&ntUnicodeString, ntName); 523: 524: outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length; 525: 526: outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE; 527: outputBuffer->NameLength = ntUnicodeString.Length; 528: 529: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) 530: { 531: Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME); 532: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 533: break; 534: } 535: 536: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length); 537: 538: Irp->IoStatus.Status = STATUS_SUCCESS; 539: Irp->IoStatus.Information = outLength; 540: 541: Dump ("link = %ls\n",ntName); 542: } 543: break; 544: 545: case IOCTL_DISK_GET_MEDIA_TYPES: 546: case IOCTL_DISK_GET_DRIVE_GEOMETRY: 547: /* Return the drive geometry for the disk. Note that we 548: return values which were made up to suit the disk size. */ 549: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 550: sizeof (DISK_GEOMETRY)) 551: { 552: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 553: Irp->IoStatus.Information = 0; 554: } 555: else 556: { 557: PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY) 558: Irp->AssociatedIrp.SystemBuffer; 559: 560: outputBuffer->MediaType = FixedMedia; 561: outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders; 562: outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder; 563: outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack; 564: outputBuffer->BytesPerSector = Extension->BytesPerSector; 565: Irp->IoStatus.Status = STATUS_SUCCESS; 566: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY); 567: } 568: break; 569: 570: case IOCTL_DISK_GET_PARTITION_INFO: 571: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 572: sizeof (PARTITION_INFORMATION)) 573: { 574: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 575: Irp->IoStatus.Information = 0; 576: } 577: else 578: { 579: PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION) 580: Irp->AssociatedIrp.SystemBuffer; 581: 582: outputBuffer->PartitionType = Extension->PartitionType; 583: outputBuffer->BootIndicator = FALSE; 584: outputBuffer->RecognizedPartition = TRUE; 585: outputBuffer->RewritePartition = FALSE; 586: outputBuffer->StartingOffset = RtlConvertUlongToLargeInteger (0); 587: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; 588: outputBuffer->HiddenSectors = 1L; 589: Irp->IoStatus.Status = STATUS_SUCCESS; 590: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION); 591: } 592: break; 593: 594: case IOCTL_DISK_GET_LENGTH_INFO: 595: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GET_LENGTH_INFORMATION)) 596: { 597: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 598: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION); 599: } 600: else 601: { 602: PGET_LENGTH_INFORMATION outputBuffer = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer; 603: 604: outputBuffer->Length.QuadPart = Extension->DiskLength; 605: Irp->IoStatus.Status = STATUS_SUCCESS; 606: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION); 607: } 608: break; 609: 610: case IOCTL_DISK_VERIFY: 611: { 612: PVERIFY_INFORMATION pVerifyInformation; 613: pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer; 614: irpSp->Parameters.Read.ByteOffset.LowPart = 615: pVerifyInformation->StartingOffset.LowPart; 616: irpSp->Parameters.Read.ByteOffset.HighPart = 617: pVerifyInformation->StartingOffset.HighPart; 618: irpSp->Parameters.Read.Length = pVerifyInformation->Length; 619: Irp->IoStatus.Status = STATUS_SUCCESS; 620: Irp->IoStatus.Information = pVerifyInformation->Length; 621: } 622: break; 623: 624: case IOCTL_DISK_CHECK_VERIFY: 625: { 626: Irp->IoStatus.Status = STATUS_SUCCESS; 627: Irp->IoStatus.Information = 0; 628: } 629: break; 630: 631: case IOCTL_DISK_IS_WRITABLE: 632: { 633: if (Extension->bReadOnly == TRUE) 634: Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED; 635: else 636: Irp->IoStatus.Status = STATUS_SUCCESS; 637: Irp->IoStatus.Information = 0; 638: 639: } 640: break; 641: 642: case DRIVER_VERSION: 643: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 4) 644: { 645: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 646: Irp->IoStatus.Information = 0; 647: } 648: else 649: { 650: LONG tmp = VERSION_NUM; 651: memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4); 652: Irp->IoStatus.Information = 4; 653: Irp->IoStatus.Status = STATUS_SUCCESS; 654: } 655: break; 656: 657: case OPEN_TEST: 658: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (OPEN_TEST_STRUCT)) 659: { 660: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 661: Irp->IoStatus.Information = 0; 662: } 663: else 664: { 665: OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 666: OBJECT_ATTRIBUTES ObjectAttributes; 667: HANDLE NtFileHandle; 668: UNICODE_STRING FullFileName; 669: IO_STATUS_BLOCK IoStatus; 670: 671: RtlInitUnicodeString (&FullFileName, opentest->wszFileName); 672: 673: InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE, 674: NULL, NULL); 675: 676: ntStatus = ZwCreateFile (&NtFileHandle, 677: SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none */ , 678: FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | 679: FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS, 680: NULL /* eabuffer */ , 0 /* ealength */ ); 681: 682: if (NT_SUCCESS (ntStatus)) 683: { 684: ZwClose (NtFileHandle); 685: Dump ("Open test on file %ls success.\n", opentest->wszFileName); 686: } 687: else 688: { 689: Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus); 690: } 691: 692: Irp->IoStatus.Information = 0; 693: Irp->IoStatus.Status = ntStatus; 694: } 695: break; 696: 697: case WIPE_CACHE: 698: KeWaitForMutexObject (&driverMutex, Executive, KernelMode, 699: FALSE, NULL); 700: 701: WipeCache (); 702: 703: KeReleaseMutex (&driverMutex, FALSE); 704: 705: Irp->IoStatus.Status = STATUS_SUCCESS; 706: Irp->IoStatus.Information = 0; 707: break; 708: 709: case CACHE_STATUS: 710: Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS; 711: Irp->IoStatus.Information = 0; 712: break; 713: 714: #ifdef DEBUG 715: case HALT_SYSTEM: 716: KeBugCheck ((ULONG) 0x5050); 717: break; 718: #endif 719: 720: case MOUNT_LIST: 721: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT)) 722: { 723: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 724: Irp->IoStatus.Information = 0; 725: } 726: else 727: { 728: MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 729: PDEVICE_OBJECT ListDevice; 730: 731: list->ulMountedDrives = 0; 732: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 733: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice) 734: { 735: 736: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 737: if (ListExtension->bRootDevice == FALSE) 738: { 739: list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo); 740: wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume); 741: list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength; 742: list->cipher[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->cipher; 743: } 744: } 745: 746: Irp->IoStatus.Status = STATUS_SUCCESS; 747: Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT); 748: } 749: break; 750: 751: case VOLUME_PROPERTIES: 752: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT)) 753: { 754: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 755: Irp->IoStatus.Information = 0; 756: } 757: else 758: { 759: VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 760: PDEVICE_OBJECT ListDevice; 761: 762: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 763: Irp->IoStatus.Information = 0; 764: 765: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 766: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice) 767: { 768: 769: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 770: if (ListExtension->bRootDevice == FALSE && ListExtension->nDosDriveNo == prop->driveNo) 771: { 772: wcscpy (prop->wszVolume, ListExtension->wszVolume); 773: prop->diskLength = ListExtension->DiskLength; 774: prop->cipher = ListExtension->cryptoInfo->cipher; 775: prop->pkcs5 = ListExtension->cryptoInfo->pkcs5; 776: prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations; 777: prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time; 778: prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time; 779: 780: Irp->IoStatus.Status = STATUS_SUCCESS; 781: Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT); 782: break; 783: } 784: } 785: } 786: break; 787: 788: case UNMOUNT_PENDING: 789: Extension->bShuttingDown = TRUE; 790: Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE; 791: Irp->IoStatus.Information = 0; 792: if (DeviceObject->Vpb && DeviceObject->Vpb->Flags & VPB_MOUNTED) 793: { 794: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject); 795: DeviceObject->Flags |= DO_VERIFY_VOLUME; 796: } 797: break; 798: 799: case UNMOUNT: 800: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT)) 801: { 802: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 803: Irp->IoStatus.Information = 0; 804: } 805: else 806: { 807: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 808: PDEVICE_OBJECT ListDevice; 809: 810: unmount->nReturnCode = ERR_DRIVE_NOT_FOUND; 811: 812: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 813: ListDevice != (PDEVICE_OBJECT) NULL; 814: ListDevice = ListDevice->NextDevice) 815: { 816: 817: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 818: 819: if (ListExtension->bRootDevice == FALSE) 820: { 821: if (unmount->nDosDriveNo == ListExtension->nDosDriveNo) 822: { 823: if (ListDevice->Vpb && ListDevice->Vpb->ReferenceCount == 0 && (ListDevice->Vpb->Flags & VPB_MOUNTED) == 0) 824: { 825: Dump ("Deleting DeviceObject with ref count %ld\n", ListDevice->ReferenceCount); 826: ListDevice->ReferenceCount = 0; 827: TCDeleteDeviceObject (ListDevice, (PEXTENSION) ListDevice->DeviceExtension); 828: unmount->nReturnCode = 0; 829: break; 830: } 831: else 832: { 833: unmount->nReturnCode = ERR_FILES_OPEN; 834: break; 835: } 836: } /* if the drive numbers are 837: equal */ 838: } /* if it's not the root device */ 839: } /* for all the device objects the driver 840: knows about */ 841: 842: Irp->IoStatus.Information = sizeof (unmount->nReturnCode); 843: Irp->IoStatus.Status = STATUS_SUCCESS; 844: } 845: break; 846: 847: 848: case MOUNT: 849: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT)) 850: { 851: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 852: Irp->IoStatus.Information = 0; 853: } 854: else 855: { 856: MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 857: ULONG *outputBuffer = (ULONG *) Irp->AssociatedIrp.SystemBuffer; 858: PDEVICE_OBJECT NewDeviceObject; 859: 860: /* Make sure the user is asking for a resonable 861: nDosDriveNo */ 862: if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25) 863: { 864: Dump ("Mount request looks valid\n"); 865: } 866: else 867: { 868: Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n"); 869: Irp->IoStatus.Information = sizeof (mount->nReturnCode); 870: Irp->IoStatus.Status = STATUS_SUCCESS; 871: mount->nReturnCode = ERR_BAD_DRIVE_LETTER; 872: break; 873: } 874: 875: ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject, 876: mount->nDosDriveNo); 877: if (!NT_SUCCESS (ntStatus)) 878: { 879: Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus); 880: Irp->IoStatus.Information = 0; 881: Irp->IoStatus.Status = ntStatus; 882: break; 883: } 884: else 885: { 886: PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension; 887: ntStatus = TCStartThread (NewDeviceObject, NewExtension, mount); 888: if (!NT_SUCCESS (ntStatus)) 889: { 890: Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus); 891: Irp->IoStatus.Information = 0; 892: Irp->IoStatus.Status = ntStatus; 893: TCDeleteDeviceObject (NewDeviceObject, NewExtension); 894: break; 895: } 896: else 897: { 898: if (mount->nReturnCode == 0) 899: { 900: Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode, 901: NewExtension->bReadOnly); 902: if (NewExtension->bReadOnly == TRUE) 903: NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE; 904: NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 905: } 906: else 907: { 908: Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode); 909: TCDeleteDeviceObject (NewDeviceObject, NewExtension); 910: } 911: Irp->IoStatus.Information = sizeof (mount->nReturnCode); 912: Irp->IoStatus.Status = STATUS_SUCCESS; 913: break; 914: } 915: } 916: } 917: break; 918: } 919: 920: /* Finish the I/O operation by simply completing the packet and 921: returning the same NTSTATUS as in the packet itself. */ 922: ntStatus = COMPLETE_IRP (DeviceObject, Irp, Irp->IoStatus.Status, Irp->IoStatus.Information); 923: Dump ("TCDeviceControl NTSTATUS = 0x%08x END\n", ntStatus); 924: return ntStatus; 925: } 926: 927: NTSTATUS 928: TCStartThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount) 929: { 930: PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK)); 931: HANDLE hThread; 932: NTSTATUS ntStatus; 933: 934: Dump ("Starting thread...\n"); 935: 936: if (pThreadBlock == NULL) 937: { 938: return STATUS_INSUFFICIENT_RESOURCES; 939: } 940: else 941: { 942: pThreadBlock->DeviceObject = DeviceObject; 943: pThreadBlock->mount = mount; 944: } 945: 946: Extension->bThreadShouldQuit = FALSE; 947: 948: ntStatus = PsCreateSystemThread (&hThread, 949: THREAD_ALL_ACCESS, 950: NULL, 951: NULL, 952: NULL, 953: TCThreadIRP, 954: pThreadBlock); 955: 956: if (!NT_SUCCESS (ntStatus)) 957: { 958: Dump ("PsCreateSystemThread Failed END\n"); 959: TCfree (pThreadBlock); 960: return ntStatus; 961: } 962: 963: ObReferenceObjectByHandle (hThread, 964: THREAD_ALL_ACCESS, 965: NULL, 966: KernelMode, 967: &Extension->peThread, 968: NULL); 969: ZwClose (hThread); 970: 971: Dump ("Waiting for thread to initialize...\n"); 972: 973: KeWaitForSingleObject (&Extension->keCreateEvent, 974: UserRequest, 975: UserMode, 976: FALSE, 977: NULL); 978: 979: Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus); 980: ntStatus = pThreadBlock->ntCreateStatus; 981: TCfree (pThreadBlock); 982: return ntStatus; 983: } 984: 985: void 986: TCStopThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) 987: { 988: NTSTATUS ntStatus; 989: 990: if (DeviceObject); /* Remove compiler warning */ 991: 992: Dump ("Signalling thread to quit...\n"); 993: 994: Extension->bThreadShouldQuit = TRUE; 995: 996: KeReleaseSemaphore (&Extension->RequestSemaphore, 997: 0, 998: 1, 999: TRUE); 1000: 1001: ntStatus = KeWaitForSingleObject (&Extension->peThread, 1002: UserRequest, 1003: UserMode, 1004: FALSE, 1005: NULL); 1006: if (ntStatus != STATUS_SUCCESS) 1007: Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n", 1008: ntStatus); 1009: 1010: ObDereferenceObject (&Extension->peThread); 1011: Extension->peThread = NULL; 1012: 1013: Dump ("Thread exited!\n"); 1014: } 1015: 1016: /* TCThreadIRP does all the work of processing IRP's, and dispatching them 1017: to either the ReadWrite function or the DeviceControl function */ 1018: VOID 1019: TCThreadIRP (PVOID Context) 1020: { 1021: PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context; 1022: PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject; 1023: PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject; 1024: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension; 1025: LARGE_INTEGER queueWait; 1026: BOOL bDevice; 1027: 1028: /* Set thread priority to lowest realtime level. */ 1029: 1030: KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY); 1031: 1032: queueWait.QuadPart = -WAIT_SECONDS (1); 1033: 1034: Dump ("Mount THREAD OPENING VOLUME BEGIN\n"); 1035: 1036: #ifdef USE_KERNEL_MUTEX 1037: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode, 1038: FALSE, NULL); 1039: #endif 1040: 1041: if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0) 1042: { 1043: wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\")); 1044: wcscat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume); 1045: bDevice = FALSE; 1046: } 1047: else 1048: { 1049: wcscpy (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume); 1050: bDevice = TRUE; 1051: } 1052: 1053: Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n", 1054: pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice); 1055: 1056: pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject, 1057: Extension, 1058: pThreadBlock->mount, 1059: pThreadBlock->wszMountVolume, 1060: bDevice); 1061: 1062: #ifdef USE_KERNEL_MUTEX 1063: KeReleaseMutex (&Extension->KernelMutex, FALSE); 1064: #endif 1065: 1066: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0) 1067: { 1068: KeSetEvent (&Extension->keCreateEvent, 0, FALSE); 1069: PsTerminateSystemThread (STATUS_SUCCESS); 1070: } 1071: else 1072: { 1073: KeSetEvent (&Extension->keCreateEvent, 0, FALSE); 1074: /* From this point on pThreadBlock cannot be used as it will 1075: have been released! */ 1076: pThreadBlock = NULL; 1077: } 1078: 1079: 1080: for (;;) 1081: { 1082: NTSTATUS ntStatus; 1083: 1084: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 1085: 1086: /* Wait for a request from the dispatch routines. */ 1087: ntStatus = KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore, 1088: Executive, KernelMode, FALSE, &queueWait); 1089: 1090: if (ntStatus != STATUS_TIMEOUT) 1091: { 1092: 1093: #ifdef USE_KERNEL_MUTEX 1094: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode, 1095: FALSE, NULL); 1096: #endif 1097: 1098: // Dump ("DRIVER THREAD PROCESSING DEVICEOBJECT 0x%08x \n", DeviceObject); 1099: 1100: for (;;) 1101: { 1102: PIO_STACK_LOCATION irpSp; 1103: PLIST_ENTRY request; 1104: PIRP Irp; 1105: 1106: request = ExInterlockedRemoveHeadList (&Extension->ListEntry, 1107: &Extension->ListSpinLock); 1108: if (request == NULL) 1109: break; 1110: 1111: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 1112: 1113: Irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry); 1114: irpSp = IoGetCurrentIrpStackLocation (Irp); 1115: 1116: switch (irpSp->MajorFunction) 1117: { 1118: case IRP_MJ_READ: 1119: case IRP_MJ_WRITE: 1120: TCReadWrite (DeviceObject, Extension, Irp); 1121: break; 1122: 1123: case IRP_MJ_FLUSH_BUFFERS: 1124: if (Extension->bRawDevice == FALSE) 1125: TCSendIRP_FileDevice (DeviceObject, Extension, NULL, Irp->Flags, IRP_MJ_FLUSH_BUFFERS, Irp); 1126: else 1127: { 1128: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 1129: } 1130: break; 1131: 1132: case IRP_MJ_SHUTDOWN: 1133: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 1134: break; 1135: 1136: case IRP_MJ_DEVICE_CONTROL: 1137: if (irpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_DISK_CHECK_VERIFY) 1138: TCDeviceControl (DeviceObject, Extension, Irp); 1139: else 1140: { 1141: if (Extension->bRawDevice == TRUE) 1142: TCSendIRP_RawDevice (DeviceObject, Extension, NULL, 0, IRP_MJ_DEVICE_CONTROL, Irp); 1143: else 1144: TCDeviceControl (DeviceObject, Extension, Irp); 1145: } 1146: break; 1147: } /* end of switch on 1148: irpSp->MajorFunction */ 1149: } /* for any remaining IRP's for this device */ 1150: 1151: #ifdef USE_KERNEL_MUTEX 1152: KeReleaseMutex (&Extension->KernelMutex, FALSE); 1153: #endif 1154: 1155: if (Extension->bThreadShouldQuit) 1156: { 1157: // Dump ("END PROCESSING DEVICEOBJECT THREAD ENDING 0x%08x Number = %d\n", 1158: // DeviceObject, Extension->nDosDriveNo); 1159: Dump ("Closing volume along with Thread!\n"); 1160: TCCloseVolume (DeviceObject, Extension); 1161: PsTerminateSystemThread (STATUS_SUCCESS); 1162: } 1163: //else 1164: //{ 1165: // Dump ("END PROCESSING DEVICEOBJECT 0x%08x Number = %d\n", 1166: // DeviceObject, Extension->nDosDriveNo); 1167: //} 1168: } 1169: 1170: } /* outermost for */ 1171: } 1172: 1173: void 1174: TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo) 1175: { 1176: WCHAR tmp[3] = 1177: {0, ':', 0}; 1178: int j = nDriveNo + (WCHAR) 'A'; 1179: 1180: tmp[0] = (short) j; 1181: wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX); 1182: wcsncat (ntname, tmp, 1); 1183: } 1184: 1185: void 1186: TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo) 1187: { 1188: WCHAR tmp[3] = 1189: {0, ':', 0}; 1190: int j = nDriveNo + (WCHAR) 'A'; 1191: 1192: tmp[0] = (short) j; 1193: wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX); 1194: wcscat (dosname, tmp); 1195: } 1196: 1197: #ifdef _DEBUG 1198: LPWSTR 1199: TCTranslateCode (ULONG ulCode) 1200: { 1201: if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) 1202: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY"); 1203: else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) 1204: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX"); 1205: else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME) 1206: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME"); 1207: else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME) 1208: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME"); 1209: else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID) 1210: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID"); 1211: else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY) 1212: return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY"); 1213: else if (ulCode == IOCTL_VOLUME_ONLINE) 1214: return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE"); 1215: else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED) 1216: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED"); 1217: else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED) 1218: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED"); 1219: else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS) 1220: return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS"); 1221: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED) 1222: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED"); 1223: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED) 1224: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED"); 1225: else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO) 1226: return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO"); 1227: else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER) 1228: return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER"); 1229: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO) 1230: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO"); 1231: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX) 1232: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX"); 1233: else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO) 1234: return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO"); 1235: else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT) 1236: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT"); 1237: else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX) 1238: return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX"); 1239: else if (ulCode == IOCTL_DISK_VERIFY) 1240: return (LPWSTR) _T ("IOCTL_DISK_VERIFY"); 1241: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS) 1242: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS"); 1243: else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS) 1244: return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS"); 1245: else if (ulCode == IOCTL_DISK_PERFORMANCE) 1246: return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE"); 1247: else if (ulCode == IOCTL_DISK_IS_WRITABLE) 1248: return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE"); 1249: else if (ulCode == IOCTL_DISK_LOGGING) 1250: return (LPWSTR) _T ("IOCTL_DISK_LOGGING"); 1251: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX) 1252: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX"); 1253: else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE) 1254: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE"); 1255: else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA) 1256: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA"); 1257: else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET) 1258: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET"); 1259: else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE) 1260: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE"); 1261: else if (ulCode == IOCTL_DISK_REQUEST_DATA) 1262: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA"); 1263: else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER) 1264: return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER"); 1265: else if (ulCode == SMART_GET_VERSION) 1266: return (LPWSTR) _T ("SMART_GET_VERSION"); 1267: else if (ulCode == SMART_SEND_DRIVE_COMMAND) 1268: return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND"); 1269: else if (ulCode == SMART_RCV_DRIVE_DATA) 1270: return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA"); 1271: else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY) 1272: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY"); 1273: else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY) 1274: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY"); 1275: else if (ulCode == IOCTL_DISK_CHECK_VERIFY) 1276: return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY"); 1277: else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL) 1278: return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL"); 1279: else if (ulCode == IOCTL_DISK_EJECT_MEDIA) 1280: return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA"); 1281: else if (ulCode == IOCTL_DISK_LOAD_MEDIA) 1282: return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA"); 1283: else if (ulCode == IOCTL_DISK_RESERVE) 1284: return (LPWSTR) _T ("IOCTL_DISK_RESERVE"); 1285: else if (ulCode == IOCTL_DISK_RELEASE) 1286: return (LPWSTR) _T ("IOCTL_DISK_RELEASE"); 1287: else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES) 1288: return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES"); 1289: else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES) 1290: return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES"); 1291: else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO) 1292: return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO"); 1293: else if (ulCode == IRP_MJ_READ) 1294: return (LPWSTR) _T ("IRP_MJ_READ"); 1295: else if (ulCode == IRP_MJ_WRITE) 1296: return (LPWSTR) _T ("IRP_MJ_WRITE"); 1297: else if (ulCode == IRP_MJ_CREATE) 1298: return (LPWSTR) _T ("IRP_MJ_CREATE"); 1299: else if (ulCode == IRP_MJ_CLOSE) 1300: return (LPWSTR) _T ("IRP_MJ_CLOSE"); 1301: else if (ulCode == IRP_MJ_CLEANUP) 1302: return (LPWSTR) _T ("IRP_MJ_CLEANUP"); 1303: else if (ulCode == IRP_MJ_FLUSH_BUFFERS) 1304: return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS"); 1305: else if (ulCode == IRP_MJ_SHUTDOWN) 1306: return (LPWSTR) _T ("IRP_MJ_SHUTDOWN"); 1307: else if (ulCode == IRP_MJ_DEVICE_CONTROL) 1308: return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL"); 1309: else if (ulCode == MOUNT) 1310: return (LPWSTR) _T ("MOUNT"); 1311: else if (ulCode == UNMOUNT) 1312: return (LPWSTR) _T ("UNMOUNT"); 1313: else if (ulCode == MOUNT_LIST) 1314: return (LPWSTR) _T ("MOUNT_LIST"); 1315: else if (ulCode == OPEN_TEST) 1316: return (LPWSTR) _T ("OPEN_TEST"); 1317: else if (ulCode == UNMOUNT_PENDING) 1318: return (LPWSTR) _T ("UNMOUNT_PENDING"); 1319: else 1320: { 1321: Dump("Unknown IOCTL recieved: DeviceType = 0x%x Function = 0x%x", (int)(ulCode>>16), (int)((ulCode&0x1FFF)>>2)); 1322: return (LPWSTR) _T ("UNKNOWN"); 1323: } 1324: } 1325: 1326: #endif 1327: 1328: PDEVICE_OBJECT 1329: TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) 1330: { 1331: PDEVICE_OBJECT OldDeviceObject = DeviceObject; 1332: UNICODE_STRING Win32NameString; 1333: WCHAR dosname[32]; 1334: NTSTATUS ntStatus; 1335: 1336: Dump ("TCDeleteDeviceObject BEGIN\n"); 1337: 1338: if (Extension->bRootDevice == TRUE) 1339: { 1340: RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX); 1341: } 1342: else 1343: { 1344: if (Extension->peThread != NULL) 1345: TCStopThread (DeviceObject, Extension); 1346: TCGetDosNameFromNumber (dosname, Extension->nDosDriveNo); 1347: RtlInitUnicodeString (&Win32NameString, dosname); 1348: } 1349: 1350: ntStatus = IoDeleteSymbolicLink (&Win32NameString); 1351: if (!NT_SUCCESS (ntStatus)) 1352: { 1353: Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus); 1354: } 1355: 1356: DeviceObject = DeviceObject->NextDevice; 1357: IoDeleteDevice (OldDeviceObject); 1358: 1359: Dump ("TCDeleteDeviceObject END\n"); 1360: return DeviceObject; 1361: } 1362: 1363: VOID 1364: TCUnloadDriver (PDRIVER_OBJECT DriverObject) 1365: { 1366: PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject; 1367: 1368: Dump ("TCUnloadDriver BEGIN\n"); 1369: 1370: /* Now walk the list of driver objects and get rid of them */ 1371: while (DeviceObject != (PDEVICE_OBJECT) NULL) 1372: { 1373: DeviceObject = TCDeleteDeviceObject (DeviceObject, 1374: (PEXTENSION) DeviceObject->DeviceExtension); 1375: } 1376: 1377: Dump ("TCUnloadDriver END\n"); 1378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.