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