|
|
1.1.1.6 ! root 1: /* Legal Notice: The source code contained in this file has been derived from ! 2: the source code of Encryption for the Masses 2.02a, which is Copyright (c) ! 3: 1998-99 Paul Le Roux and which is covered by the 'License Agreement for ! 4: Encryption for the Masses'. Modifications and additions to that source code ! 5: contained in this file are Copyright (c) 2004-2005 TrueCrypt Foundation and ! 6: Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.0 ! 7: the full text of which is contained in the file License.txt included in ! 8: TrueCrypt binary and source code distribution archives. */ 1.1 root 9: 10: #include "TCdefs.h" 1.1.1.6 ! root 11: #include "Crypto.h" ! 12: #include "Fat.h" ! 13: #include "Tests.h" ! 14: ! 15: #include "Apidrvr.h" ! 16: #include "Ntdriver.h" ! 17: #include "Ntvol.h" ! 18: #include "Ntrawdv.h" ! 19: #include "Ntfiledv.h" ! 20: #include "Cache.h" 1.1 root 21: 22: #include <tchar.h> 23: #include <initguid.h> 24: #include <mountmgr.h> 25: #include <mountdev.h> 26: #include <ntddvol.h> 27: 28: /* Init section, which is thrown away as soon as DriverEntry returns */ 29: #pragma alloc_text(INIT,DriverEntry) 30: #pragma alloc_text(INIT,TCCreateRootDeviceObject) 31: 1.1.1.6 ! root 32: KMUTEX driverMutex; /* Sync mutex for the entire driver */ ! 33: BOOL SelfTestsPassed; ! 34: int LastUniqueVolumeId; 1.1 root 35: 36: /* DriverEntry initialize's the dispatch addresses to be passed back to NT. 37: RUNS AT IRQL = PASSIVE_LEVEL(0) */ 38: NTSTATUS 39: DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 40: { 41: if (RegistryPath); /* Remove warning */ 42: 43: DriverObject->MajorFunction[IRP_MJ_CREATE] = TCDispatchQueueIRP; 44: DriverObject->MajorFunction[IRP_MJ_CLOSE] = TCDispatchQueueIRP; 45: DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TCDispatchQueueIRP; 46: DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = TCDispatchQueueIRP; 47: DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = TCDispatchQueueIRP; 48: DriverObject->MajorFunction[IRP_MJ_READ] = TCDispatchQueueIRP; 49: DriverObject->MajorFunction[IRP_MJ_WRITE] = TCDispatchQueueIRP; 50: DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TCDispatchQueueIRP; 51: 52: DriverObject->DriverUnload = TCUnloadDriver; 53: 54: KeInitializeMutex (&driverMutex, 1); 55: 1.1.1.6 ! root 56: SelfTestsPassed = AutoTestAlgorithms (); ! 57: 1.1 root 58: return TCCreateRootDeviceObject (DriverObject); 59: } 60: 61: #ifdef _DEBUG 62: // Dumps a memory region to debug output 1.1.1.4 root 63: void DumpMem(void *mem, int len) 1.1 root 64: { 65: unsigned char str[20]; 66: unsigned char *m = mem; 67: int i,j; 68: 1.1.1.4 root 69: for (j=0; j<len/8; j++) 1.1 root 70: { 71: memset (str,0,sizeof str); 1.1.1.4 root 72: for (i=0; i<8; i++) 1.1 root 73: { 74: if (m[i] > ' ' && m[i] < '~') 75: str[i]=m[i]; 76: else 77: str[i]='.'; 78: } 79: 1.1.1.4 root 80: Dump ("0x%08x %02x %02x %02x %02x %02x %02x %02x %02x %s\n", 1.1 root 81: m, m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], str); 82: 83: m+=8; 84: } 85: } 86: #endif 87: 88: /* TCDispatchQueueIRP queues any IRP's so that they can be processed later 89: by the thread -- or in some cases handles them immediately! */ 90: NTSTATUS 91: TCDispatchQueueIRP (PDEVICE_OBJECT DeviceObject, PIRP Irp) 92: { 93: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension; 94: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 95: NTSTATUS ntStatus; 96: 97: #ifdef USE_KERNEL_MUTEX 98: if (Extension->bRootDevice == FALSE) 99: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode, 100: FALSE, NULL); 101: #endif 102: 103: #ifdef _DEBUG 104: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL) 105: Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x IoControlCode = %ls 0x%08x\n", 106: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction, 107: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode), 108: (int) irpSp->Parameters.DeviceIoControl.IoControlCode); 109: //else 110: // Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x\n", 111: // TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction); 112: #endif 113: 114: if (Extension->bRootDevice == FALSE) 115: { 116: if (irpSp->MajorFunction == IRP_MJ_READ || irpSp->MajorFunction == IRP_MJ_WRITE || 117: irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL) 118: { 119: if ((DeviceObject->Flags & DO_VERIFY_VOLUME)) 120: { 121: if (!(irpSp->Flags & SL_OVERRIDE_VERIFY_VOLUME)) 122: { 123: Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED; 124: Irp->IoStatus.Information = 0; 125: if (!NT_SUCCESS (Irp->IoStatus.Status) && 126: IoIsErrorUserInduced (Irp->IoStatus.Status)) 127: { 128: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject); 129: } 130: ntStatus = Irp->IoStatus.Status; 131: IoCompleteRequest (Irp, IO_NO_INCREMENT); 132: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 133: #ifdef USE_KERNEL_MUTEX 134: if (Extension->bRootDevice == FALSE) 135: KeReleaseMutex (&Extension->KernelMutex, FALSE); 136: #endif 137: return ntStatus; 138: } 1.1.1.6 ! root 139: else if (Extension->bShuttingDown) 1.1 root 140: { 141: Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; 142: Irp->IoStatus.Information = 0; 143: if (!NT_SUCCESS (Irp->IoStatus.Status) && 144: IoIsErrorUserInduced (Irp->IoStatus.Status)) 145: { 146: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject); 147: } 148: ntStatus = Irp->IoStatus.Status; 149: IoCompleteRequest (Irp, IO_NO_INCREMENT); 150: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 151: #ifdef USE_KERNEL_MUTEX 152: if (Extension->bRootDevice == FALSE) 153: KeReleaseMutex (&Extension->KernelMutex, FALSE); 154: #endif 155: return ntStatus; 156: } 157: } 1.1.1.6 ! root 158: else if (Extension->bShuttingDown) 1.1 root 159: { 160: if (DeviceObject->Vpb && DeviceObject->Vpb->Flags & VPB_MOUNTED) 161: { 162: Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE; 163: Irp->IoStatus.Information = 0; 164: if (!NT_SUCCESS (Irp->IoStatus.Status) && 165: IoIsErrorUserInduced (Irp->IoStatus.Status)) 166: { 167: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject); 168: } 169: DeviceObject->Flags |= DO_VERIFY_VOLUME; 170: } 171: else 172: { 173: Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; 174: Irp->IoStatus.Information = 0; 175: } 176: 177: ntStatus = Irp->IoStatus.Status; 178: IoCompleteRequest (Irp, IO_NO_INCREMENT); 179: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 180: #ifdef USE_KERNEL_MUTEX 181: if (Extension->bRootDevice == FALSE) 182: KeReleaseMutex (&Extension->KernelMutex, FALSE); 183: #endif 184: return ntStatus; 185: } 186: } 187: else if ((DeviceObject->Flags & DO_VERIFY_VOLUME)) 188: { /* If shutting down or media removed */ 1.1.1.6 ! root 189: if (Extension->bShuttingDown) 1.1 root 190: { 191: Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED; 192: Irp->IoStatus.Information = 0; 193: if (!NT_SUCCESS (Irp->IoStatus.Status) && 194: IoIsErrorUserInduced (Irp->IoStatus.Status)) 195: { 196: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject); 197: } 198: ntStatus = Irp->IoStatus.Status; 199: IoCompleteRequest (Irp, IO_NO_INCREMENT); 200: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 201: #ifdef USE_KERNEL_MUTEX 202: if (Extension->bRootDevice == FALSE) 203: KeReleaseMutex (&Extension->KernelMutex, FALSE); 204: #endif 205: return ntStatus; 206: } 207: else 208: { 209: Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; 210: Irp->IoStatus.Information = 0; 211: ntStatus = Irp->IoStatus.Status; 212: IoCompleteRequest (Irp, IO_NO_INCREMENT); 213: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 214: #ifdef USE_KERNEL_MUTEX 215: if (Extension->bRootDevice == FALSE) 216: KeReleaseMutex (&Extension->KernelMutex, FALSE); 217: #endif 218: return ntStatus; 219: } 220: } 221: } 222: 223: switch (irpSp->MajorFunction) 224: { 225: case IRP_MJ_CLOSE: 226: case IRP_MJ_CREATE: 227: case IRP_MJ_CLEANUP: 228: #ifdef USE_KERNEL_MUTEX 229: if (Extension->bRootDevice == FALSE) 230: KeReleaseMutex (&Extension->KernelMutex, FALSE); 231: #endif 232: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 233: 234: case IRP_MJ_SHUTDOWN: 1.1.1.4 root 235: #ifdef USE_KERNEL_MUTEX 236: if (Extension->bRootDevice == FALSE) 237: KeReleaseMutex (&Extension->KernelMutex, FALSE); 238: #endif 1.1.1.6 ! root 239: if (Extension->bRootDevice) 1.1.1.4 root 240: UnmountAllDevices (DeviceObject, TRUE); 241: 242: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 243: 1.1 root 244: case IRP_MJ_FLUSH_BUFFERS: 245: case IRP_MJ_READ: 246: case IRP_MJ_WRITE: 247: case IRP_MJ_DEVICE_CONTROL: 248: if (Extension->bRootDevice == FALSE) 249: { 250: ASSERT (Extension->bShuttingDown == FALSE); 251: 252: IoMarkIrpPending (Irp); 253: 254: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL || 255: KeGetCurrentIrql ()== APC_LEVEL); 256: 257: ExInterlockedInsertTailList ( 258: &Extension->ListEntry, 259: &Irp->Tail.Overlay.ListEntry, 260: &Extension->ListSpinLock); 261: 262: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL || 263: KeGetCurrentIrql ()== APC_LEVEL); 264: 265: KeReleaseSemaphore ( 266: &Extension->RequestSemaphore, 267: (KPRIORITY) 0, 268: 1, 269: FALSE); 270: 271: //Dump ("TCDispatchQueueIRP STATUS_PENDING END\n"); 272: #ifdef USE_KERNEL_MUTEX 273: if (Extension->bRootDevice == FALSE) 274: KeReleaseMutex (&Extension->KernelMutex, FALSE); 275: #endif 276: return STATUS_PENDING; 277: } 278: else 279: { 280: if (irpSp->Parameters.DeviceIoControl.IoControlCode >= TC_FIRST_PRIVATE && 281: irpSp->Parameters.DeviceIoControl.IoControlCode <= TC_LAST_PRIVATE) 282: { 283: ntStatus = TCDeviceControl (DeviceObject, Extension, Irp); 284: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus); 285: #ifdef USE_KERNEL_MUTEX 286: if (Extension->bRootDevice == FALSE) 287: KeReleaseMutex (&Extension->KernelMutex, FALSE); 288: #endif 289: return ntStatus; 290: } 291: 1.1.1.4 root 292: if (irpSp->MajorFunction == IRP_MJ_FLUSH_BUFFERS) 1.1 root 293: { 294: #ifdef USE_KERNEL_MUTEX 295: if (Extension->bRootDevice == FALSE) 296: KeReleaseMutex (&Extension->KernelMutex, FALSE); 297: #endif 298: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 299: } 300: } 301: 302: #ifdef USE_KERNEL_MUTEX 303: if (Extension->bRootDevice == FALSE) 304: KeReleaseMutex (&Extension->KernelMutex, FALSE); 305: #endif 306: 307: return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0); 308: } 309: 310: #ifdef _DEBUG 311: Dump ("ERROR: Unknown irpSp->MajorFunction in TCDispatchQueueIRP %ls 0x%08x END\n", 312: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction); 313: #endif 314: 315: #ifdef USE_KERNEL_MUTEX 316: if (Extension->bRootDevice == FALSE) 317: KeReleaseMutex (&Extension->KernelMutex, FALSE); 318: #endif 319: return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0); 320: } 321: 322: NTSTATUS 323: TCCreateRootDeviceObject (PDRIVER_OBJECT DriverObject) 324: { 325: UNICODE_STRING Win32NameString, ntUnicodeString; 326: WCHAR dosname[32], ntname[32]; 327: PDEVICE_OBJECT DeviceObject; 328: NTSTATUS ntStatus; 329: BOOL *bRootExtension; 330: 331: Dump ("TCCreateRootDeviceObject BEGIN\n"); 332: 333: wcscpy (dosname, (LPWSTR) DOS_ROOT_PREFIX); 334: wcscpy (ntname, (LPWSTR) NT_ROOT_PREFIX); 335: RtlInitUnicodeString (&ntUnicodeString, ntname); 336: RtlInitUnicodeString (&Win32NameString, dosname); 337: 338: Dump ("Creating root device nt=%ls dos=%ls\n", ntname, dosname); 1.1.1.3 root 339: 1.1 root 340: ntStatus = IoCreateDevice ( 341: DriverObject, /* Our Driver Object */ 342: sizeof (BOOL), /* Size of state information */ 343: &ntUnicodeString, /* Device name "\Device\Name" */ 1.1.1.3 root 344: FILE_DEVICE_UNKNOWN, /* Device type */ 1.1 root 345: 0, /* Device characteristics */ 346: FALSE, /* Exclusive device */ 347: &DeviceObject); /* Returned ptr to Device Object */ 348: 349: if (!NT_SUCCESS (ntStatus)) 350: { 351: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus); 352: return ntStatus;/* Failed to create DeviceObject */ 353: } 354: 355: DeviceObject->Flags |= DO_DIRECT_IO; 356: DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT; 357: 358: /* Setup the device extension */ 359: bRootExtension = (BOOL *) DeviceObject->DeviceExtension; 360: *bRootExtension = TRUE; 361: 362: /* The symlinks for mount devices are created from user-mode */ 363: ntStatus = IoCreateSymbolicLink (&Win32NameString, &ntUnicodeString); 1.1.1.4 root 364: 1.1 root 365: if (!NT_SUCCESS (ntStatus)) 366: { 367: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus); 368: IoDeleteDevice (DeviceObject); 369: return ntStatus; 370: } 371: 1.1.1.4 root 372: IoRegisterShutdownNotification (DeviceObject); 373: 1.1 root 374: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 375: Dump ("TCCreateRootDeviceObject STATUS_SUCCESS END\n"); 376: return STATUS_SUCCESS; 377: } 378: 379: NTSTATUS 380: TCCreateDeviceObject (PDRIVER_OBJECT DriverObject, 381: PDEVICE_OBJECT * ppDeviceObject, 1.1.1.4 root 382: MOUNT_STRUCT * mount) 1.1 root 383: { 384: UNICODE_STRING Win32NameString, ntUnicodeString; 385: WCHAR dosname[32], ntname[32]; 386: PEXTENSION Extension; 387: NTSTATUS ntStatus; 1.1.1.4 root 388: ULONG devChars = 0; 1.1 root 389: 390: Dump ("TCCreateDeviceObject BEGIN\n"); 391: 1.1.1.4 root 392: TCGetDosNameFromNumber (dosname, mount->nDosDriveNo); 393: TCGetNTNameFromNumber (ntname, mount->nDosDriveNo); 1.1 root 394: RtlInitUnicodeString (&ntUnicodeString, ntname); 395: RtlInitUnicodeString (&Win32NameString, dosname); 396: 1.1.1.4 root 397: devChars = mount->bMountReadOnly ? FILE_READ_ONLY_DEVICE : 0; 398: devChars |= mount->bMountRemovable ? FILE_REMOVABLE_MEDIA : 0; 399: 1.1 root 400: Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname); 401: 402: ntStatus = IoCreateDevice ( 403: DriverObject, /* Our Driver Object */ 404: sizeof (EXTENSION), /* Size of state information */ 405: &ntUnicodeString, /* Device name "\Device\Name" */ 406: FILE_DEVICE_DISK, /* Device type */ 1.1.1.4 root 407: devChars, /* Device characteristics */ 1.1 root 408: FALSE, /* Exclusive device */ 409: ppDeviceObject); /* Returned ptr to Device Object */ 410: 411: if (!NT_SUCCESS (ntStatus)) 412: { 413: Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus); 414: return ntStatus;/* Failed to create DeviceObject */ 415: } 416: /* Initialize device object and extension. */ 417: 418: (*ppDeviceObject)->Flags |= DO_DIRECT_IO; 419: (*ppDeviceObject)->AlignmentRequirement = FILE_WORD_ALIGNMENT; 420: 421: /* Setup the device extension */ 422: Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension; 423: memset (Extension, 0, sizeof (EXTENSION)); 424: 425: Extension->lMagicNumber = 0xabfeacde; 1.1.1.4 root 426: Extension->nDosDriveNo = mount->nDosDriveNo; 427: Extension->bRemovable = mount->bMountRemovable; 1.1 root 428: 429: KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE); 430: KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG); 431: #ifdef USE_KERNEL_MUTEX 432: KeInitializeMutex (&Extension->KernelMutex, 1); 433: #endif 434: KeInitializeSpinLock (&Extension->ListSpinLock); 435: InitializeListHead (&Extension->ListEntry); 436: 437: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 438: Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n"); 439: 440: return STATUS_SUCCESS; 441: } 442: 1.1.1.5 root 443: 444: void DriverMutexWait () 445: { 446: KeWaitForMutexObject (&driverMutex, Executive, KernelMode, FALSE, NULL); 447: } 448: 449: 450: void DriverMutexRelease () 451: { 452: KeReleaseMutex (&driverMutex, FALSE); 453: } 454: 455: 1.1 root 456: /* TCDeviceControl handles certain requests from NT, these are needed for NT 1.1.1.4 root 457: to recognize the drive, also this function handles our device specific 1.1 root 458: function codes, such as mount/unmount */ 459: NTSTATUS 460: TCDeviceControl (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp) 461: { 462: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 463: NTSTATUS ntStatus; 464: 465: #ifdef _DEBUG 466: Dump ("TCDeviceControl BEGIN IoControlCode = %ls 0x%08x\n", 467: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode), 468: irpSp->Parameters.DeviceIoControl.IoControlCode); 469: #endif 470: 471: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; /* Assume failure. */ 472: 473: /* Determine which I/O control code was specified. */ 474: switch (irpSp->Parameters.DeviceIoControl.IoControlCode) 475: { 476: 477: case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: 478: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_NAME)) 479: { 480: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME); 481: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 482: } 483: else 484: { 485: ULONG outLength; 486: UNICODE_STRING ntUnicodeString; 487: WCHAR ntName[64]; 488: PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer; 489: 490: Dump("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:"); 491: 492: TCGetNTNameFromNumber (ntName, Extension->nDosDriveNo); 493: RtlInitUnicodeString (&ntUnicodeString, ntName); 494: 495: outputBuffer->NameLength = ntUnicodeString.Length; 496: outLength = ntUnicodeString.Length + sizeof(USHORT); 497: 498: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) 499: { 500: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME); 501: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 502: 503: break; 504: } 505: 506: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length); 507: 508: Irp->IoStatus.Status = STATUS_SUCCESS; 509: Irp->IoStatus.Information = outLength; 510: 511: Dump ("name = %ls\n",ntName); 512: } 513: break; 514: 515: case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: 516: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_UNIQUE_ID)) 517: { 518: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID); 519: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 520: } 521: else 522: { 523: ULONG outLength; 524: UCHAR volId[128], tmp[] = { 0,0 }; 525: PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer; 526: 527: Dump("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:"); 528: 529: strcpy (volId, TC_UNIQUE_ID_PREFIX); 530: tmp[0] = 'A' + Extension->nDosDriveNo; 531: strcat (volId, tmp); 532: 1.1.1.6 ! root 533: outputBuffer->UniqueIdLength = (USHORT) strlen (volId); ! 534: outLength = strlen (volId) + sizeof(USHORT); 1.1 root 535: 536: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) 537: { 538: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID); 539: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 540: break; 541: } 542: 1.1.1.6 ! root 543: RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen (volId)); 1.1 root 544: 545: Irp->IoStatus.Status = STATUS_SUCCESS; 546: Irp->IoStatus.Information = outLength; 547: 548: Dump ("id = %s\n",volId); 549: } 550: break; 551: 552: case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME: 553: { 554: ULONG outLength; 555: UNICODE_STRING ntUnicodeString; 556: WCHAR ntName[64]; 557: PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer; 558: 559: Dump("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:"); 560: 561: TCGetDosNameFromNumber (ntName, Extension->nDosDriveNo); 562: RtlInitUnicodeString (&ntUnicodeString, ntName); 563: 564: outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length; 565: 566: outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE; 567: outputBuffer->NameLength = ntUnicodeString.Length; 568: 569: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) 570: { 571: Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME); 572: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 573: break; 574: } 575: 576: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length); 577: 578: Irp->IoStatus.Status = STATUS_SUCCESS; 579: Irp->IoStatus.Information = outLength; 580: 581: Dump ("link = %ls\n",ntName); 582: } 583: break; 584: 1.1.1.4 root 585: 1.1 root 586: case IOCTL_DISK_GET_MEDIA_TYPES: 587: case IOCTL_DISK_GET_DRIVE_GEOMETRY: 588: /* Return the drive geometry for the disk. Note that we 589: return values which were made up to suit the disk size. */ 590: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 591: sizeof (DISK_GEOMETRY)) 592: { 593: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 594: Irp->IoStatus.Information = 0; 595: } 596: else 597: { 598: PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY) 599: Irp->AssociatedIrp.SystemBuffer; 600: 1.1.1.4 root 601: outputBuffer->MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia; 1.1 root 602: outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders; 603: outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder; 604: outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack; 605: outputBuffer->BytesPerSector = Extension->BytesPerSector; 606: Irp->IoStatus.Status = STATUS_SUCCESS; 607: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY); 608: } 609: break; 610: 611: case IOCTL_DISK_GET_PARTITION_INFO: 612: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 613: sizeof (PARTITION_INFORMATION)) 614: { 615: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 616: Irp->IoStatus.Information = 0; 617: } 618: else 619: { 620: PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION) 621: Irp->AssociatedIrp.SystemBuffer; 622: 623: outputBuffer->PartitionType = Extension->PartitionType; 624: outputBuffer->BootIndicator = FALSE; 625: outputBuffer->RecognizedPartition = TRUE; 626: outputBuffer->RewritePartition = FALSE; 627: outputBuffer->StartingOffset = RtlConvertUlongToLargeInteger (0); 628: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; 629: outputBuffer->HiddenSectors = 1L; 630: Irp->IoStatus.Status = STATUS_SUCCESS; 631: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION); 632: } 633: break; 1.1.1.6 ! root 634: ! 635: case IOCTL_DISK_GET_DRIVE_LAYOUT: ! 636: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < ! 637: sizeof (DRIVE_LAYOUT_INFORMATION)) ! 638: { ! 639: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; ! 640: Irp->IoStatus.Information = 0; ! 641: } ! 642: else ! 643: { ! 644: PDRIVE_LAYOUT_INFORMATION outputBuffer = (PDRIVE_LAYOUT_INFORMATION) ! 645: Irp->AssociatedIrp.SystemBuffer; ! 646: ! 647: outputBuffer->PartitionCount = 1; ! 648: outputBuffer->Signature = 0; ! 649: ! 650: outputBuffer->PartitionEntry->PartitionType = Extension->PartitionType; ! 651: outputBuffer->PartitionEntry->BootIndicator = FALSE; ! 652: outputBuffer->PartitionEntry->RecognizedPartition = TRUE; ! 653: outputBuffer->PartitionEntry->RewritePartition = FALSE; ! 654: outputBuffer->PartitionEntry->StartingOffset = RtlConvertUlongToLargeInteger (0); ! 655: outputBuffer->PartitionEntry->PartitionLength.QuadPart= Extension->DiskLength; ! 656: outputBuffer->PartitionEntry->HiddenSectors = 1L; ! 657: ! 658: Irp->IoStatus.Status = STATUS_SUCCESS; ! 659: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION); ! 660: } ! 661: break; ! 662: 1.1 root 663: case IOCTL_DISK_GET_LENGTH_INFO: 664: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GET_LENGTH_INFORMATION)) 665: { 666: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 667: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION); 668: } 669: else 670: { 671: PGET_LENGTH_INFORMATION outputBuffer = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer; 672: 673: outputBuffer->Length.QuadPart = Extension->DiskLength; 674: Irp->IoStatus.Status = STATUS_SUCCESS; 675: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION); 676: } 677: break; 678: 679: case IOCTL_DISK_VERIFY: 680: { 681: PVERIFY_INFORMATION pVerifyInformation; 682: pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer; 683: irpSp->Parameters.Read.ByteOffset.LowPart = 684: pVerifyInformation->StartingOffset.LowPart; 685: irpSp->Parameters.Read.ByteOffset.HighPart = 686: pVerifyInformation->StartingOffset.HighPart; 687: irpSp->Parameters.Read.Length = pVerifyInformation->Length; 688: Irp->IoStatus.Status = STATUS_SUCCESS; 689: Irp->IoStatus.Information = pVerifyInformation->Length; 690: } 691: break; 692: 693: case IOCTL_DISK_CHECK_VERIFY: 1.1.1.6 ! root 694: case IOCTL_STORAGE_CHECK_VERIFY: 1.1 root 695: { 696: Irp->IoStatus.Status = STATUS_SUCCESS; 697: Irp->IoStatus.Information = 0; 698: } 699: break; 700: 701: case IOCTL_DISK_IS_WRITABLE: 702: { 1.1.1.6 ! root 703: if (Extension->bReadOnly) 1.1 root 704: Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED; 705: else 706: Irp->IoStatus.Status = STATUS_SUCCESS; 707: Irp->IoStatus.Information = 0; 708: 709: } 710: break; 711: 1.1.1.5 root 712: // Private IOCTLs 713: 1.1 root 714: case DRIVER_VERSION: 1.1.1.6 ! root 715: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (LONG)) 1.1 root 716: { 717: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 718: Irp->IoStatus.Information = 0; 719: } 720: else 721: { 722: LONG tmp = VERSION_NUM; 723: memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4); 1.1.1.6 ! root 724: Irp->IoStatus.Information = sizeof (LONG); 1.1 root 725: Irp->IoStatus.Status = STATUS_SUCCESS; 726: } 727: break; 728: 1.1.1.6 ! root 729: case DEVICE_REFCOUNT: ! 730: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int)) 1.1 root 731: { 732: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 733: Irp->IoStatus.Information = 0; 734: } 735: else 736: { 1.1.1.6 ! root 737: *(int *) Irp->AssociatedIrp.SystemBuffer = DeviceObject->ReferenceCount; ! 738: Irp->IoStatus.Information = sizeof (int); ! 739: Irp->IoStatus.Status = STATUS_SUCCESS; ! 740: } ! 741: break; ! 742: ! 743: case OPEN_TEST: ! 744: { 1.1 root 745: OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 746: OBJECT_ATTRIBUTES ObjectAttributes; 747: HANDLE NtFileHandle; 748: UNICODE_STRING FullFileName; 749: IO_STATUS_BLOCK IoStatus; 750: 751: RtlInitUnicodeString (&FullFileName, opentest->wszFileName); 752: 753: InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE, 754: NULL, NULL); 755: 756: ntStatus = ZwCreateFile (&NtFileHandle, 757: SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none */ , 1.1.1.4 root 758: FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | 1.1 root 759: FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS, 760: NULL /* eabuffer */ , 0 /* ealength */ ); 761: 762: if (NT_SUCCESS (ntStatus)) 763: { 764: ZwClose (NtFileHandle); 765: Dump ("Open test on file %ls success.\n", opentest->wszFileName); 766: } 767: else 768: { 769: Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus); 770: } 771: 772: Irp->IoStatus.Information = 0; 773: Irp->IoStatus.Status = ntStatus; 774: } 775: break; 776: 777: case WIPE_CACHE: 1.1.1.5 root 778: DriverMutexWait (); 1.1 root 779: WipeCache (); 1.1.1.5 root 780: DriverMutexRelease (); 1.1 root 781: 782: Irp->IoStatus.Status = STATUS_SUCCESS; 783: Irp->IoStatus.Information = 0; 784: break; 785: 786: case CACHE_STATUS: 787: Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS; 788: Irp->IoStatus.Information = 0; 789: break; 790: 791: #ifdef DEBUG 792: case HALT_SYSTEM: 793: KeBugCheck ((ULONG) 0x5050); 794: break; 795: #endif 796: 797: case MOUNT_LIST: 798: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT)) 799: { 800: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 801: Irp->IoStatus.Information = 0; 802: } 803: else 804: { 805: MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 806: PDEVICE_OBJECT ListDevice; 807: 1.1.1.5 root 808: DriverMutexWait (); 809: 1.1 root 810: list->ulMountedDrives = 0; 811: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 812: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice) 813: { 814: 815: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 1.1.1.6 ! root 816: if (ListExtension->lMagicNumber == 0xabfeacde ! 817: && ListExtension->bRootDevice == FALSE ! 818: && !ListExtension->bShuttingDown) 1.1 root 819: { 820: list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo); 821: wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume); 822: list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength; 1.1.1.4 root 823: list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea; 1.1.1.6 ! root 824: if (ListExtension->cryptoInfo->hiddenVolume) ! 825: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_HIDDEN; // Hidden volume ! 826: else if (ListExtension->cryptoInfo->bHiddenVolProtectionAction) ! 827: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED; // Normal/outer volume (hidden volume protected AND write already prevented) ! 828: else if (ListExtension->cryptoInfo->bProtectHiddenVolume) ! 829: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER; // Normal/outer volume (hidden volume protected) ! 830: else ! 831: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_NORMAL; // Normal volume 1.1 root 832: } 833: } 834: 1.1.1.5 root 835: DriverMutexRelease (); 836: 1.1 root 837: Irp->IoStatus.Status = STATUS_SUCCESS; 838: Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT); 839: } 840: break; 841: 842: case VOLUME_PROPERTIES: 843: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT)) 844: { 845: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 846: Irp->IoStatus.Information = 0; 847: } 848: else 849: { 850: VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 851: PDEVICE_OBJECT ListDevice; 852: 853: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 854: Irp->IoStatus.Information = 0; 855: 1.1.1.5 root 856: DriverMutexWait (); 857: 1.1 root 858: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 859: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice) 860: { 861: 862: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 1.1.1.6 ! root 863: if (ListExtension->bRootDevice == FALSE ! 864: && !ListExtension->bShuttingDown ! 865: && ListExtension->nDosDriveNo == prop->driveNo) 1.1 root 866: { 1.1.1.6 ! root 867: prop->uniqueId = ListExtension->UniqueVolumeId; 1.1 root 868: wcscpy (prop->wszVolume, ListExtension->wszVolume); 869: prop->diskLength = ListExtension->DiskLength; 1.1.1.4 root 870: prop->ea = ListExtension->cryptoInfo->ea; 1.1 root 871: prop->pkcs5 = ListExtension->cryptoInfo->pkcs5; 872: prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations; 873: prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time; 874: prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time; 1.1.1.6 ! root 875: prop->readOnly = ListExtension->bReadOnly; 1.1.1.4 root 876: prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume; 1.1 root 877: 1.1.1.6 ! root 878: if (ListExtension->cryptoInfo->bProtectHiddenVolume) ! 879: prop->hiddenVolProtection = ListExtension->cryptoInfo->bHiddenVolProtectionAction ? HIDVOL_PROT_STATUS_ACTION_TAKEN : HIDVOL_PROT_STATUS_ACTIVE; ! 880: else ! 881: prop->hiddenVolProtection = HIDVOL_PROT_STATUS_NONE; ! 882: ! 883: prop->totalBytesRead = ListExtension->TotalBytesRead; ! 884: prop->totalBytesWritten = ListExtension->TotalBytesWritten; ! 885: 1.1 root 886: Irp->IoStatus.Status = STATUS_SUCCESS; 887: Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT); 888: break; 889: } 890: } 1.1.1.5 root 891: 892: DriverMutexRelease (); 1.1 root 893: } 894: break; 895: 1.1.1.4 root 896: case RESOLVE_SYMLINK: 1.1.1.6 ! root 897: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (RESOLVE_SYMLINK_STRUCT)) 1.1.1.4 root 898: { 899: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 900: Irp->IoStatus.Information = 0; 901: } 902: else 1.1 root 903: { 1.1.1.4 root 904: RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 905: { 906: NTSTATUS ntStatus; 907: 908: ntStatus = SymbolicLinkToTarget (resolve->symLinkName, 909: resolve->targetName, 910: sizeof (resolve->targetName)); 911: 912: Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT); 913: Irp->IoStatus.Status = ntStatus; 914: } 915: 916: } 917: break; 918: 919: case MOUNT: 920: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT)) 921: { 922: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 923: Irp->IoStatus.Information = 0; 924: } 925: else 926: { 927: MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 928: 1.1.1.5 root 929: DriverMutexWait (); 1.1.1.6 ! root 930: ! 931: Irp->IoStatus.Information = sizeof (MOUNT_STRUCT); 1.1.1.4 root 932: Irp->IoStatus.Status = MountDevice (DeviceObject, mount); 1.1.1.5 root 933: DriverMutexRelease (); 1.1.1.6 ! root 934: ! 935: burn (&mount->VolumePassword, sizeof (mount->VolumePassword)); ! 936: burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword)); 1.1 root 937: } 938: break; 939: 940: case UNMOUNT: 941: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT)) 942: { 943: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 944: Irp->IoStatus.Information = 0; 945: } 946: else 947: { 948: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 949: PDEVICE_OBJECT ListDevice; 950: 951: unmount->nReturnCode = ERR_DRIVE_NOT_FOUND; 952: 953: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 954: ListDevice != (PDEVICE_OBJECT) NULL; 955: ListDevice = ListDevice->NextDevice) 956: { 957: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 958: 1.1.1.4 root 959: if (ListExtension->bRootDevice == FALSE 1.1.1.6 ! root 960: && !ListExtension->bShuttingDown 1.1.1.4 root 961: && unmount->nDosDriveNo == ListExtension->nDosDriveNo) 1.1 root 962: { 1.1.1.5 root 963: DriverMutexWait (); 1.1.1.4 root 964: unmount->nReturnCode = UnmountDevice (ListDevice, unmount->ignoreOpenFiles); 1.1.1.5 root 965: DriverMutexRelease (); 1.1.1.4 root 966: break; 967: } 968: } 1.1 root 969: 1.1.1.4 root 970: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT); 1.1 root 971: Irp->IoStatus.Status = STATUS_SUCCESS; 972: } 973: break; 974: 1.1.1.4 root 975: case UNMOUNT_ALL: 976: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT)) 1.1 root 977: { 978: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 979: Irp->IoStatus.Information = 0; 980: } 981: else 982: { 1.1.1.4 root 983: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 1.1 root 984: 1.1.1.4 root 985: unmount->nReturnCode = UnmountAllDevices (DeviceObject, unmount->ignoreOpenFiles); 1.1 root 986: 1.1.1.4 root 987: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT); 988: Irp->IoStatus.Status = STATUS_SUCCESS; 1.1 root 989: } 990: break; 991: } 992: 993: /* Finish the I/O operation by simply completing the packet and 994: returning the same NTSTATUS as in the packet itself. */ 995: ntStatus = COMPLETE_IRP (DeviceObject, Irp, Irp->IoStatus.Status, Irp->IoStatus.Information); 996: Dump ("TCDeviceControl NTSTATUS = 0x%08x END\n", ntStatus); 997: return ntStatus; 998: } 999: 1.1.1.6 ! root 1000: 1.1 root 1001: NTSTATUS 1002: TCStartThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount) 1003: { 1004: PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK)); 1005: HANDLE hThread; 1006: NTSTATUS ntStatus; 1.1.1.6 ! root 1007: HANDLE process; 1.1 root 1008: 1009: Dump ("Starting thread...\n"); 1010: 1011: if (pThreadBlock == NULL) 1012: { 1013: return STATUS_INSUFFICIENT_RESOURCES; 1014: } 1015: else 1016: { 1017: pThreadBlock->DeviceObject = DeviceObject; 1018: pThreadBlock->mount = mount; 1019: } 1020: 1.1.1.6 ! root 1021: if (mount->bUserContext) ! 1022: { ! 1023: ntStatus = ObOpenObjectByPointer (IoGetCurrentProcess (), 0, NULL, 0, NULL, KernelMode, &process); ! 1024: if (!NT_SUCCESS (ntStatus)) ! 1025: { ! 1026: Dump ("ObOpenObjectByPointer Failed\n"); ! 1027: goto ret; ! 1028: } ! 1029: } ! 1030: else ! 1031: process = NULL; ! 1032: 1.1 root 1033: Extension->bThreadShouldQuit = FALSE; 1034: 1035: ntStatus = PsCreateSystemThread (&hThread, 1036: THREAD_ALL_ACCESS, 1037: NULL, 1.1.1.6 ! root 1038: process, 1.1 root 1039: NULL, 1040: TCThreadIRP, 1041: pThreadBlock); 1042: 1043: if (!NT_SUCCESS (ntStatus)) 1044: { 1045: Dump ("PsCreateSystemThread Failed END\n"); 1.1.1.6 ! root 1046: goto ret; 1.1 root 1047: } 1048: 1049: ObReferenceObjectByHandle (hThread, 1050: THREAD_ALL_ACCESS, 1051: NULL, 1052: KernelMode, 1053: &Extension->peThread, 1054: NULL); 1055: ZwClose (hThread); 1056: 1057: Dump ("Waiting for thread to initialize...\n"); 1058: 1059: KeWaitForSingleObject (&Extension->keCreateEvent, 1060: UserRequest, 1061: UserMode, 1062: FALSE, 1063: NULL); 1064: 1065: Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus); 1066: ntStatus = pThreadBlock->ntCreateStatus; 1.1.1.6 ! root 1067: ! 1068: ret: 1.1 root 1069: TCfree (pThreadBlock); 1070: return ntStatus; 1071: } 1072: 1073: void 1074: TCStopThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) 1075: { 1076: NTSTATUS ntStatus; 1077: 1078: if (DeviceObject); /* Remove compiler warning */ 1079: 1080: Dump ("Signalling thread to quit...\n"); 1081: 1082: Extension->bThreadShouldQuit = TRUE; 1083: 1084: KeReleaseSemaphore (&Extension->RequestSemaphore, 1085: 0, 1086: 1, 1087: TRUE); 1088: 1.1.1.4 root 1089: ntStatus = KeWaitForSingleObject (Extension->peThread, 1.1 root 1090: UserRequest, 1091: UserMode, 1092: FALSE, 1093: NULL); 1094: if (ntStatus != STATUS_SUCCESS) 1095: Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n", 1096: ntStatus); 1097: 1.1.1.6 ! root 1098: ObDereferenceObject (Extension->peThread); 1.1 root 1099: Extension->peThread = NULL; 1100: 1101: Dump ("Thread exited!\n"); 1102: } 1103: 1.1.1.5 root 1104: 1105: // Suspend current thread for a number of milliseconds 1106: void TCSleep (int milliSeconds) 1107: { 1108: PKTIMER timer = (PKTIMER) TCalloc (sizeof (KTIMER)); 1109: LARGE_INTEGER duetime; 1110: 1111: duetime.QuadPart = (__int64) milliSeconds * -10000; 1112: KeInitializeTimerEx(timer, NotificationTimer); 1113: KeSetTimerEx(timer, duetime, 0, NULL); 1114: 1115: KeWaitForSingleObject (timer, UserRequest, UserMode, FALSE, NULL); 1116: 1117: TCfree (timer); 1118: } 1119: 1120: 1.1 root 1121: /* TCThreadIRP does all the work of processing IRP's, and dispatching them 1122: to either the ReadWrite function or the DeviceControl function */ 1123: VOID 1124: TCThreadIRP (PVOID Context) 1125: { 1126: PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context; 1127: PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject; 1128: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension; 1129: LARGE_INTEGER queueWait; 1130: BOOL bDevice; 1131: 1132: /* Set thread priority to lowest realtime level. */ 1133: 1134: KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY); 1135: 1136: queueWait.QuadPart = -WAIT_SECONDS (1); 1137: 1138: Dump ("Mount THREAD OPENING VOLUME BEGIN\n"); 1139: 1140: #ifdef USE_KERNEL_MUTEX 1141: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode, 1142: FALSE, NULL); 1143: #endif 1144: 1145: if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0) 1146: { 1147: wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\")); 1148: wcscat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume); 1149: bDevice = FALSE; 1150: } 1151: else 1152: { 1153: wcscpy (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume); 1154: bDevice = TRUE; 1155: } 1156: 1157: Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n", 1158: pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice); 1159: 1160: pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject, 1161: Extension, 1162: pThreadBlock->mount, 1163: pThreadBlock->wszMountVolume, 1164: bDevice); 1165: 1166: #ifdef USE_KERNEL_MUTEX 1167: KeReleaseMutex (&Extension->KernelMutex, FALSE); 1168: #endif 1169: 1170: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0) 1171: { 1172: KeSetEvent (&Extension->keCreateEvent, 0, FALSE); 1173: PsTerminateSystemThread (STATUS_SUCCESS); 1174: } 1175: else 1176: { 1177: KeSetEvent (&Extension->keCreateEvent, 0, FALSE); 1178: /* From this point on pThreadBlock cannot be used as it will 1179: have been released! */ 1180: pThreadBlock = NULL; 1181: } 1182: 1183: 1184: for (;;) 1185: { 1186: NTSTATUS ntStatus; 1187: 1188: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 1189: 1190: /* Wait for a request from the dispatch routines. */ 1191: ntStatus = KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore, 1192: Executive, KernelMode, FALSE, &queueWait); 1193: 1194: if (ntStatus != STATUS_TIMEOUT) 1195: { 1196: 1197: #ifdef USE_KERNEL_MUTEX 1198: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode, 1199: FALSE, NULL); 1200: #endif 1201: 1202: // Dump ("DRIVER THREAD PROCESSING DEVICEOBJECT 0x%08x \n", DeviceObject); 1203: 1204: for (;;) 1205: { 1206: PIO_STACK_LOCATION irpSp; 1207: PLIST_ENTRY request; 1208: PIRP Irp; 1209: 1210: request = ExInterlockedRemoveHeadList (&Extension->ListEntry, 1211: &Extension->ListSpinLock); 1212: if (request == NULL) 1213: break; 1214: 1215: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 1216: 1217: Irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry); 1218: irpSp = IoGetCurrentIrpStackLocation (Irp); 1219: 1220: switch (irpSp->MajorFunction) 1221: { 1222: case IRP_MJ_READ: 1223: case IRP_MJ_WRITE: 1224: TCReadWrite (DeviceObject, Extension, Irp); 1225: break; 1226: 1227: case IRP_MJ_FLUSH_BUFFERS: 1228: if (Extension->bRawDevice == FALSE) 1229: TCSendIRP_FileDevice (DeviceObject, Extension, NULL, Irp->Flags, IRP_MJ_FLUSH_BUFFERS, Irp); 1230: else 1231: { 1232: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 1233: } 1234: break; 1235: 1236: case IRP_MJ_SHUTDOWN: 1237: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 1238: break; 1239: 1240: case IRP_MJ_DEVICE_CONTROL: 1241: if (irpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_DISK_CHECK_VERIFY) 1242: TCDeviceControl (DeviceObject, Extension, Irp); 1243: else 1244: { 1.1.1.6 ! root 1245: if (Extension->bRawDevice) 1.1 root 1246: TCSendIRP_RawDevice (DeviceObject, Extension, NULL, 0, IRP_MJ_DEVICE_CONTROL, Irp); 1247: else 1248: TCDeviceControl (DeviceObject, Extension, Irp); 1249: } 1250: break; 1251: } /* end of switch on 1252: irpSp->MajorFunction */ 1253: } /* for any remaining IRP's for this device */ 1254: 1255: #ifdef USE_KERNEL_MUTEX 1256: KeReleaseMutex (&Extension->KernelMutex, FALSE); 1257: #endif 1258: 1259: if (Extension->bThreadShouldQuit) 1260: { 1261: // Dump ("END PROCESSING DEVICEOBJECT THREAD ENDING 0x%08x Number = %d\n", 1262: // DeviceObject, Extension->nDosDriveNo); 1263: Dump ("Closing volume along with Thread!\n"); 1264: TCCloseVolume (DeviceObject, Extension); 1265: PsTerminateSystemThread (STATUS_SUCCESS); 1266: } 1267: //else 1268: //{ 1269: // Dump ("END PROCESSING DEVICEOBJECT 0x%08x Number = %d\n", 1270: // DeviceObject, Extension->nDosDriveNo); 1271: //} 1272: } 1273: 1274: } /* outermost for */ 1275: } 1276: 1277: void 1278: TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo) 1279: { 1280: WCHAR tmp[3] = 1281: {0, ':', 0}; 1282: int j = nDriveNo + (WCHAR) 'A'; 1283: 1284: tmp[0] = (short) j; 1285: wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX); 1286: wcsncat (ntname, tmp, 1); 1287: } 1288: 1289: void 1290: TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo) 1291: { 1292: WCHAR tmp[3] = 1293: {0, ':', 0}; 1294: int j = nDriveNo + (WCHAR) 'A'; 1295: 1296: tmp[0] = (short) j; 1297: wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX); 1298: wcscat (dosname, tmp); 1299: } 1300: 1301: #ifdef _DEBUG 1302: LPWSTR 1303: TCTranslateCode (ULONG ulCode) 1304: { 1305: if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) 1306: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY"); 1307: else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) 1308: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX"); 1309: else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME) 1310: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME"); 1311: else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME) 1312: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME"); 1313: else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID) 1314: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID"); 1315: else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY) 1316: return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY"); 1317: else if (ulCode == IOCTL_VOLUME_ONLINE) 1318: return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE"); 1319: else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED) 1320: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED"); 1321: else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED) 1322: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED"); 1323: else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS) 1324: return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS"); 1325: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED) 1326: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED"); 1327: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED) 1328: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED"); 1329: else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO) 1330: return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO"); 1331: else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER) 1332: return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER"); 1333: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO) 1334: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO"); 1335: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX) 1336: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX"); 1337: else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO) 1338: return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO"); 1339: else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT) 1340: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT"); 1341: else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX) 1342: return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX"); 1343: else if (ulCode == IOCTL_DISK_VERIFY) 1344: return (LPWSTR) _T ("IOCTL_DISK_VERIFY"); 1345: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS) 1346: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS"); 1347: else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS) 1348: return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS"); 1349: else if (ulCode == IOCTL_DISK_PERFORMANCE) 1350: return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE"); 1351: else if (ulCode == IOCTL_DISK_IS_WRITABLE) 1352: return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE"); 1353: else if (ulCode == IOCTL_DISK_LOGGING) 1354: return (LPWSTR) _T ("IOCTL_DISK_LOGGING"); 1355: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX) 1356: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX"); 1357: else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE) 1358: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE"); 1359: else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA) 1360: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA"); 1361: else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET) 1362: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET"); 1363: else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE) 1364: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE"); 1365: else if (ulCode == IOCTL_DISK_REQUEST_DATA) 1366: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA"); 1367: else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER) 1368: return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER"); 1369: else if (ulCode == SMART_GET_VERSION) 1370: return (LPWSTR) _T ("SMART_GET_VERSION"); 1371: else if (ulCode == SMART_SEND_DRIVE_COMMAND) 1372: return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND"); 1373: else if (ulCode == SMART_RCV_DRIVE_DATA) 1374: return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA"); 1375: else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY) 1376: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY"); 1377: else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY) 1378: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY"); 1379: else if (ulCode == IOCTL_DISK_CHECK_VERIFY) 1380: return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY"); 1381: else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL) 1382: return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL"); 1383: else if (ulCode == IOCTL_DISK_EJECT_MEDIA) 1384: return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA"); 1385: else if (ulCode == IOCTL_DISK_LOAD_MEDIA) 1386: return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA"); 1387: else if (ulCode == IOCTL_DISK_RESERVE) 1388: return (LPWSTR) _T ("IOCTL_DISK_RESERVE"); 1389: else if (ulCode == IOCTL_DISK_RELEASE) 1390: return (LPWSTR) _T ("IOCTL_DISK_RELEASE"); 1391: else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES) 1392: return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES"); 1393: else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES) 1394: return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES"); 1395: else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO) 1396: return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO"); 1397: else if (ulCode == IRP_MJ_READ) 1398: return (LPWSTR) _T ("IRP_MJ_READ"); 1399: else if (ulCode == IRP_MJ_WRITE) 1400: return (LPWSTR) _T ("IRP_MJ_WRITE"); 1401: else if (ulCode == IRP_MJ_CREATE) 1402: return (LPWSTR) _T ("IRP_MJ_CREATE"); 1403: else if (ulCode == IRP_MJ_CLOSE) 1404: return (LPWSTR) _T ("IRP_MJ_CLOSE"); 1405: else if (ulCode == IRP_MJ_CLEANUP) 1406: return (LPWSTR) _T ("IRP_MJ_CLEANUP"); 1407: else if (ulCode == IRP_MJ_FLUSH_BUFFERS) 1408: return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS"); 1409: else if (ulCode == IRP_MJ_SHUTDOWN) 1410: return (LPWSTR) _T ("IRP_MJ_SHUTDOWN"); 1411: else if (ulCode == IRP_MJ_DEVICE_CONTROL) 1412: return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL"); 1413: else if (ulCode == MOUNT) 1414: return (LPWSTR) _T ("MOUNT"); 1415: else if (ulCode == UNMOUNT) 1416: return (LPWSTR) _T ("UNMOUNT"); 1.1.1.4 root 1417: else if (ulCode == UNMOUNT_ALL) 1418: return (LPWSTR) _T ("UNMOUNT_ALL"); 1.1 root 1419: else if (ulCode == MOUNT_LIST) 1420: return (LPWSTR) _T ("MOUNT_LIST"); 1421: else if (ulCode == OPEN_TEST) 1422: return (LPWSTR) _T ("OPEN_TEST"); 1.1.1.5 root 1423: else if (ulCode == VOLUME_PROPERTIES) 1424: return (LPWSTR) _T ("VOLUME_PROPERTIES"); 1425: else if (ulCode == DRIVER_VERSION) 1426: return (LPWSTR) _T ("DRIVER_VERSION"); 1427: else if (ulCode == CACHE_STATUS) 1428: return (LPWSTR) _T ("CACHE_STATUS"); 1429: else if (ulCode == WIPE_CACHE) 1430: return (LPWSTR) _T ("WIPE_CACHE"); 1431: else if (ulCode == RESOLVE_SYMLINK) 1432: return (LPWSTR) _T ("RESOLVE_SYMLINK"); 1.1 root 1433: else 1434: { 1.1.1.4 root 1435: Dump("Unknown IOCTL recieved: DeviceType = 0x%x Function = 0x%x\n", (int)(ulCode>>16), (int)((ulCode&0x1FFF)>>2)); 1.1 root 1436: return (LPWSTR) _T ("UNKNOWN"); 1437: } 1438: } 1439: 1440: #endif 1441: 1442: PDEVICE_OBJECT 1443: TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) 1444: { 1445: PDEVICE_OBJECT OldDeviceObject = DeviceObject; 1446: UNICODE_STRING Win32NameString; 1447: NTSTATUS ntStatus; 1448: 1449: Dump ("TCDeleteDeviceObject BEGIN\n"); 1450: 1.1.1.6 ! root 1451: if (Extension->bRootDevice) 1.1 root 1452: { 1453: RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX); 1.1.1.4 root 1454: ntStatus = IoDeleteSymbolicLink (&Win32NameString); 1455: if (!NT_SUCCESS (ntStatus)) 1456: Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus); 1.1 root 1457: } 1458: else 1459: { 1460: if (Extension->peThread != NULL) 1461: TCStopThread (DeviceObject, Extension); 1462: } 1463: 1464: DeviceObject = DeviceObject->NextDevice; 1465: IoDeleteDevice (OldDeviceObject); 1466: 1467: Dump ("TCDeleteDeviceObject END\n"); 1468: return DeviceObject; 1469: } 1470: 1.1.1.4 root 1471: 1.1 root 1472: VOID 1473: TCUnloadDriver (PDRIVER_OBJECT DriverObject) 1474: { 1475: PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject; 1476: 1477: Dump ("TCUnloadDriver BEGIN\n"); 1478: 1.1.1.4 root 1479: UnmountAllDevices (DeviceObject, TRUE); 1480: 1.1 root 1481: /* Now walk the list of driver objects and get rid of them */ 1482: while (DeviceObject != (PDEVICE_OBJECT) NULL) 1483: { 1484: DeviceObject = TCDeleteDeviceObject (DeviceObject, 1485: (PEXTENSION) DeviceObject->DeviceExtension); 1486: } 1487: 1488: Dump ("TCUnloadDriver END\n"); 1489: } 1.1.1.4 root 1490: 1491: 1492: NTSTATUS 1493: TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode, 1494: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize) 1495: { 1496: IO_STATUS_BLOCK ioStatusBlock; 1497: NTSTATUS ntStatus; 1498: PIRP irp; 1499: PFILE_OBJECT fileObject; 1500: PDEVICE_OBJECT deviceObject; 1501: KEVENT event; 1502: UNICODE_STRING name; 1503: 1504: RtlInitUnicodeString(&name, deviceName); 1505: ntStatus = IoGetDeviceObjectPointer(&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject); 1506: 1507: if (ntStatus != STATUS_SUCCESS) 1508: return ntStatus; 1509: 1510: KeInitializeEvent(&event, NotificationEvent, FALSE); 1511: 1512: irp = IoBuildDeviceIoControlRequest (IoControlCode, 1513: deviceObject, 1514: InputBuffer, InputBufferSize, 1515: OutputBuffer, OutputBufferSize, 1516: FALSE, 1517: &event, 1518: &ioStatusBlock); 1519: 1520: if (irp == NULL) 1521: { 1522: Dump ("IRP allocation failed\n"); 1523: return STATUS_INSUFFICIENT_RESOURCES; 1524: } 1525: 1526: ntStatus = IoCallDriver (deviceObject, irp); 1527: if (ntStatus == STATUS_PENDING) 1528: { 1529: KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL); 1530: ntStatus = ioStatusBlock.Status; 1531: } 1532: 1533: return ntStatus; 1534: } 1535: 1536: 1537: // Opens a mounted TC volume on filesystem level 1538: NTSTATUS 1539: TCOpenFsVolume (PEXTENSION Extension, PHANDLE volumeHandle, PFILE_OBJECT * fileObject) 1540: { 1541: NTSTATUS ntStatus; 1542: OBJECT_ATTRIBUTES objectAttributes; 1543: UNICODE_STRING fullFileName; 1544: IO_STATUS_BLOCK ioStatus; 1545: WCHAR volumeName[64]; 1546: 1547: TCGetDosNameFromNumber (volumeName, Extension->nDosDriveNo); 1548: RtlInitUnicodeString (&fullFileName, volumeName); 1549: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); 1550: 1551: ntStatus = ZwCreateFile (volumeHandle, 1552: SYNCHRONIZE | GENERIC_READ, 1553: &objectAttributes, 1554: &ioStatus, 1555: NULL, 1556: FILE_ATTRIBUTE_NORMAL, 1557: FILE_SHARE_READ | FILE_SHARE_WRITE, 1558: FILE_OPEN, 1559: FILE_SYNCHRONOUS_IO_NONALERT, 1560: NULL, 1561: 0); 1562: 1563: Dump ("Volume %ls open NTSTATUS 0x%08x\n", volumeName, ntStatus); 1564: 1565: if (!NT_SUCCESS (ntStatus)) 1566: return ntStatus; 1567: 1568: ntStatus = ObReferenceObjectByHandle (*volumeHandle, 1569: FILE_READ_DATA, 1570: NULL, 1571: KernelMode, 1572: fileObject, 1573: NULL); 1574: 1575: Dump ("ObReferenceObjectByHandle NTSTATUS 0x%08x\n", ntStatus); 1576: 1577: if (!NT_SUCCESS (ntStatus)) 1578: { 1579: ZwClose(*volumeHandle); 1580: return ntStatus; 1581: } 1582: 1583: return ntStatus; 1584: } 1585: 1586: 1587: void 1588: TCCloseFsVolume (HANDLE volumeHandle, PFILE_OBJECT fileObject) 1589: { 1590: ObDereferenceObject (fileObject); 1591: ZwClose (volumeHandle); 1592: } 1593: 1594: 1595: NTSTATUS 1596: TCFsctlCall (PFILE_OBJECT fileObject, LONG IoControlCode, 1597: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize) 1598: { 1599: IO_STATUS_BLOCK ioStatusBlock; 1600: NTSTATUS ntStatus; 1601: PIRP irp; 1602: KEVENT event; 1603: PIO_STACK_LOCATION stack; 1604: PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject); 1605: 1606: Dump ("IoGetRelatedDeviceObject = 0x%08x\n", deviceObject); 1607: 1608: KeInitializeEvent(&event, NotificationEvent, FALSE); 1609: 1610: irp = IoBuildDeviceIoControlRequest (IoControlCode, 1611: deviceObject, 1612: InputBuffer, InputBufferSize, 1613: OutputBuffer, OutputBufferSize, 1614: FALSE, 1615: &event, 1616: &ioStatusBlock); 1617: 1618: if (irp == NULL) 1619: { 1620: Dump ("IRP allocation failed\n"); 1621: return STATUS_INSUFFICIENT_RESOURCES; 1622: } 1623: 1624: stack = IoGetNextIrpStackLocation(irp); 1625: 1626: stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL; 1627: stack->MinorFunction = IRP_MN_USER_FS_REQUEST; 1628: stack->FileObject = fileObject; 1629: 1630: Dump("TCFsctlCall IoCallDriver\n"); 1631: 1632: ntStatus = IoCallDriver (deviceObject, irp); 1633: if (ntStatus == STATUS_PENDING) 1634: { 1635: KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL); 1636: ntStatus = ioStatusBlock.Status; 1637: } 1638: 1639: return ntStatus; 1640: } 1641: 1642: 1643: NTSTATUS 1.1.1.6 ! root 1644: CreateDriveLink (int nDosDriveNo) ! 1645: { ! 1646: WCHAR dev[64], link[64]; ! 1647: UNICODE_STRING deviceName, symLink; ! 1648: NTSTATUS ntStatus; ! 1649: ! 1650: TCGetNTNameFromNumber (dev, nDosDriveNo); ! 1651: TCGetDosNameFromNumber (link, nDosDriveNo); ! 1652: ! 1653: RtlInitUnicodeString (&deviceName, dev); ! 1654: RtlInitUnicodeString (&symLink, link); ! 1655: ! 1656: ntStatus = IoCreateSymbolicLink (&symLink, &deviceName); ! 1657: Dump ("IoCreateSymbolicLink returned %X\n", ntStatus); ! 1658: return ntStatus; ! 1659: } ! 1660: ! 1661: ! 1662: NTSTATUS ! 1663: RemoveDriveLink (int nDosDriveNo) ! 1664: { ! 1665: WCHAR link[64]; ! 1666: UNICODE_STRING symLink; ! 1667: NTSTATUS ntStatus; ! 1668: ! 1669: TCGetDosNameFromNumber (link, nDosDriveNo); ! 1670: RtlInitUnicodeString (&symLink, link); ! 1671: ! 1672: ntStatus = IoDeleteSymbolicLink (&symLink); ! 1673: Dump ("IoDeleteSymbolicLink returned %X\n", ntStatus); ! 1674: return ntStatus; ! 1675: } ! 1676: ! 1677: ! 1678: NTSTATUS 1.1.1.4 root 1679: MountManagerMount (MOUNT_STRUCT *mount) 1680: { 1681: NTSTATUS ntStatus; 1682: WCHAR arrVolume[64]; 1683: char buf[200]; 1684: PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf; 1685: PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf; 1686: UNICODE_STRING symName, devName; 1687: 1688: TCGetNTNameFromNumber (arrVolume, mount->nDosDriveNo); 1689: in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2; 1690: wcscpy(in->DeviceName, arrVolume); 1691: 1692: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION, 1693: in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0); 1694: 1695: memset (buf, 0, sizeof buf); 1696: TCGetDosNameFromNumber ((PWSTR) &point[1], mount->nDosDriveNo); 1697: 1698: point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT); 1699: point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2; 1700: 1701: RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset)); 1702: 1703: point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength; 1704: TCGetNTNameFromNumber ((PWSTR) (buf + point->DeviceNameOffset), mount->nDosDriveNo); 1705: point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2; 1706: 1707: RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset)); 1708: 1709: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point, 1710: point->DeviceNameOffset + point->DeviceNameLength, 0, 0); 1711: 1712: return ntStatus; 1713: } 1714: 1715: 1716: NTSTATUS 1717: MountManagerUnmount (int nDosDriveNo) 1718: { 1719: NTSTATUS ntStatus; 1720: char buf[64], out[300]; 1721: PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf; 1722: 1723: memset (buf, 0, sizeof buf); 1724: 1725: TCGetDosNameFromNumber ((PWSTR) &in[1], nDosDriveNo); 1726: 1727: in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT); 1728: in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2; 1729: 1730: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS, 1731: in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out); 1732: 1733: Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus); 1734: 1735: return ntStatus; 1736: } 1737: 1738: 1739: NTSTATUS 1740: MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) 1741: { 1742: PDEVICE_OBJECT NewDeviceObject; 1743: NTSTATUS ntStatus; 1744: 1.1.1.6 ! root 1745: /* Make sure the user is asking for a reasonable 1.1.1.4 root 1746: nDosDriveNo */ 1747: if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25) 1748: { 1749: Dump ("Mount request looks valid\n"); 1750: } 1751: else 1752: { 1753: Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n"); 1.1.1.6 ! root 1754: mount->nReturnCode = ERR_BAD_DRIVE_LETTER; 1.1.1.4 root 1755: return ERR_BAD_DRIVE_LETTER; 1756: } 1757: 1.1.1.6 ! root 1758: if (!SelfTestsPassed) ! 1759: { ! 1760: mount->nReturnCode = ERR_SELF_TESTS_FAILED; ! 1761: return ERR_SELF_TESTS_FAILED; ! 1762: } ! 1763: 1.1.1.4 root 1764: ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject, 1765: mount); 1766: if (!NT_SUCCESS (ntStatus)) 1767: { 1768: Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus); 1769: return ntStatus; 1770: } 1771: else 1772: { 1773: PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension; 1774: ntStatus = TCStartThread (NewDeviceObject, NewExtension, mount); 1775: if (!NT_SUCCESS (ntStatus)) 1776: { 1777: Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus); 1778: TCDeleteDeviceObject (NewDeviceObject, NewExtension); 1779: return ntStatus; 1780: } 1781: else 1782: { 1783: if (mount->nReturnCode == 0) 1784: { 1785: Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode, 1786: NewExtension->bReadOnly); 1.1.1.6 ! root 1787: if (NewExtension->bReadOnly) 1.1.1.4 root 1788: NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE; 1789: NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 1790: 1.1.1.6 ! root 1791: NewExtension->UniqueVolumeId = LastUniqueVolumeId++; ! 1792: 1.1.1.4 root 1793: if (mount->bMountManager) 1794: MountManagerMount (mount); 1795: 1.1.1.6 ! root 1796: NewExtension->bMountManager = mount->bMountManager; 1.1.1.4 root 1797: 1.1.1.6 ! root 1798: // We create symbolic link even if mount manager is notified of ! 1799: // arriving volume as it apparently sometimes fails to create the link ! 1800: CreateDriveLink (mount->nDosDriveNo); 1.1.1.4 root 1801: } 1802: else 1803: { 1804: Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode); 1805: TCDeleteDeviceObject (NewDeviceObject, NewExtension); 1806: } 1807: 1808: return STATUS_SUCCESS; 1809: } 1810: } 1811: } 1812: 1813: NTSTATUS 1814: UnmountDevice (PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles) 1815: { 1816: PEXTENSION extension = deviceObject->DeviceExtension; 1817: NTSTATUS ntStatus; 1818: HANDLE volumeHandle; 1819: PFILE_OBJECT volumeFileObject; 1820: 1821: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject); 1822: if (!NT_SUCCESS (ntStatus)) 1.1.1.6 ! root 1823: { ! 1824: // User may have deleted symbolic link ! 1825: CreateDriveLink (extension->nDosDriveNo); ! 1826: ! 1827: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject); 1.1.1.4 root 1828: 1.1.1.6 ! root 1829: if (!NT_SUCCESS (ntStatus)) ! 1830: return ntStatus; ! 1831: } ! 1832: ! 1833: // Lock volume 1.1.1.4 root 1834: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0); 1835: Dump ("FSCTL_LOCK_VOLUME returned %X\n", ntStatus); 1836: 1837: if (!NT_SUCCESS (ntStatus) && !ignoreOpenFiles) 1838: { 1839: TCCloseFsVolume (volumeHandle, volumeFileObject); 1840: return ERR_FILES_OPEN; 1841: } 1842: 1.1.1.6 ! root 1843: // Dismount volume 1.1.1.4 root 1844: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0); 1845: Dump ("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus); 1846: 1847: extension->bShuttingDown = TRUE; 1848: if (deviceObject->Vpb && deviceObject->Vpb->Flags & VPB_MOUNTED) 1849: { 1850: deviceObject->Flags |= DO_VERIFY_VOLUME; 1851: } 1852: 1853: if (extension->bMountManager) 1854: MountManagerUnmount (extension->nDosDriveNo); 1.1.1.6 ! root 1855: ! 1856: // We always remove symbolic link as mount manager might fail to do so ! 1857: RemoveDriveLink (extension->nDosDriveNo); 1.1.1.4 root 1858: 1.1.1.6 ! root 1859: TCCloseFsVolume (volumeHandle, volumeFileObject); 1.1.1.4 root 1860: 1861: Dump ("Deleting DeviceObject with ref count %ld\n", deviceObject->ReferenceCount); 1862: deviceObject->ReferenceCount = 0; 1863: TCDeleteDeviceObject (deviceObject, (PEXTENSION) deviceObject->DeviceExtension); 1864: return 0; 1865: } 1866: 1867: NTSTATUS 1868: UnmountAllDevices (PDEVICE_OBJECT DeviceObject, BOOL ignoreOpenFiles) 1869: { 1870: NTSTATUS status = 0; 1871: PDEVICE_OBJECT ListDevice; 1872: 1873: Dump ("Unmounting all volumes\n"); 1874: 1.1.1.5 root 1875: DriverMutexWait (); 1876: 1.1.1.4 root 1877: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 1878: ListDevice != (PDEVICE_OBJECT) NULL; 1879: ListDevice = ListDevice->NextDevice) 1880: { 1881: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 1.1.1.6 ! root 1882: if (ListExtension->bRootDevice == FALSE && !ListExtension->bShuttingDown) 1.1.1.4 root 1883: { 1884: NTSTATUS ntStatus = UnmountDevice (ListDevice, ignoreOpenFiles); 1885: status = ntStatus == 0 ? status : ntStatus; 1886: } 1887: } 1888: 1.1.1.5 root 1889: DriverMutexRelease (); 1890: 1.1.1.4 root 1891: return status; 1892: } 1893: 1894: // Resolves symbolic link name to its target name 1895: NTSTATUS 1896: SymbolicLinkToTarget (PWSTR symlinkName, PWSTR targetName, USHORT maxTargetNameLength) 1897: { 1898: NTSTATUS ntStatus; 1899: OBJECT_ATTRIBUTES objectAttributes; 1900: UNICODE_STRING fullFileName; 1901: HANDLE handle; 1902: 1903: RtlInitUnicodeString (&fullFileName, symlinkName); 1904: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); 1905: 1906: ntStatus = ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes); 1907: 1908: if (NT_SUCCESS (ntStatus)) 1909: { 1910: UNICODE_STRING target; 1911: target.Buffer = targetName; 1912: target.Length = 0; 1913: target.MaximumLength = maxTargetNameLength; 1914: memset (targetName, 0, maxTargetNameLength); 1915: 1916: ntStatus = ZwQuerySymbolicLinkObject (handle, &target, NULL); 1917: 1918: ZwClose (handle); 1919: } 1920: 1921: return ntStatus; 1922: } 1.1.1.6 ! root 1923: ! 1924: // Checks if two regions overlap (borders are parts of regions) ! 1925: BOOL RegionsOverlap (unsigned __int64 start1, unsigned __int64 end1, unsigned __int64 start2, unsigned __int64 end2) ! 1926: { ! 1927: return (start1 < start2) ? (end1 >= start2) : (start1 <= end2); ! 1928: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.