|
|
1.1 ! root 1: /* Copyright (C) 2004 TrueCrypt Team, truecrypt.org ! 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.