|
|
1.1.1.10 root 1: /* 1.1.1.12! root 2: Legal Notice: Some portions of the source code contained in this file were ! 3: derived from the source code of Encryption for the Masses 2.02a, which is ! 4: Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License ! 5: Agreement for Encryption for the Masses'. Modifications and additions to ! 6: the original source code (contained in this file) and all other portions of ! 7: this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed ! 8: by the TrueCrypt License 2.4 the full text of which is contained in the ! 9: file License.txt included in TrueCrypt binary and source code distribution 1.1.1.10 root 10: packages. */ 1.1 root 11: 12: #include "TCdefs.h" 1.1.1.12! root 13: #include <ntddk.h> 1.1.1.6 root 14: #include "Crypto.h" 15: #include "Fat.h" 16: #include "Tests.h" 17: 18: #include "Apidrvr.h" 1.1.1.12! root 19: #include "EncryptedIoQueue.h" 1.1.1.6 root 20: #include "Ntdriver.h" 21: #include "Ntvol.h" 1.1.1.12! root 22: #include "DriveFilter.h" 1.1.1.6 root 23: #include "Cache.h" 1.1 root 24: 25: #include <tchar.h> 26: #include <initguid.h> 27: #include <mountmgr.h> 28: #include <mountdev.h> 29: #include <ntddvol.h> 30: 31: /* Init section, which is thrown away as soon as DriverEntry returns */ 32: #pragma alloc_text(INIT,DriverEntry) 33: #pragma alloc_text(INIT,TCCreateRootDeviceObject) 34: 1.1.1.6 root 35: KMUTEX driverMutex; /* Sync mutex for the entire driver */ 1.1.1.12! root 36: BOOL DriverShuttingDown = FALSE; 1.1.1.6 root 37: BOOL SelfTestsPassed; 38: int LastUniqueVolumeId; 1.1.1.10 root 39: ULONG OsMajorVersion; 1.1.1.11 root 40: BOOL ReferencedDeviceDeleted = FALSE; 1.1 root 41: 1.1.1.12! root 42: ! 43: NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 1.1 root 44: { 1.1.1.12! root 45: OBJECT_ATTRIBUTES regObjAttribs; ! 46: HANDLE regKeyHandle; ! 47: int i; ! 48: ! 49: SelfTestsPassed = AutoTestAlgorithms (); ! 50: ! 51: // Enable drive class filter and load boot arguments if driver is set to start at sytem boot ! 52: ! 53: InitializeObjectAttributes (®ObjAttribs, RegistryPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); ! 54: if (ZwOpenKey (®KeyHandle, KEY_READ, ®ObjAttribs) == STATUS_SUCCESS) ! 55: { ! 56: UNICODE_STRING valName; ! 57: ULONG size = 0; ! 58: ! 59: RtlInitUnicodeString (&valName, L"Start"); ! 60: if (ZwQueryValueKey (regKeyHandle, &valName, KeyValuePartialInformation, NULL, 0, &size) != STATUS_OBJECT_NAME_NOT_FOUND && size > 0) ! 61: { ! 62: PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION) TCalloc (size); ! 63: if (!pInfo) ! 64: { ! 65: ZwClose (regKeyHandle); ! 66: return STATUS_INSUFFICIENT_RESOURCES; ! 67: } ! 68: ! 69: if (ZwQueryValueKey (regKeyHandle, &valName, KeyValuePartialInformation, pInfo, size, &size) == STATUS_SUCCESS) ! 70: { ! 71: if (pInfo->Type == REG_DWORD && *((uint32 *) pInfo->Data) == SERVICE_BOOT_START) ! 72: { ! 73: if (!SelfTestsPassed) ! 74: TC_BUG_CHECK (STATUS_INVALID_PARAMETER); ! 75: ! 76: LoadBootArguments(); ! 77: DriverObject->DriverExtension->AddDevice = DriveFilterAddDevice; ! 78: } ! 79: } 1.1 root 80: 1.1.1.12! root 81: TCfree (pInfo); ! 82: } ! 83: ! 84: ZwClose (regKeyHandle); ! 85: } ! 86: ! 87: for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i) ! 88: { ! 89: DriverObject->MajorFunction[i] = TCDispatchQueueIRP; ! 90: } 1.1 root 91: 92: DriverObject->DriverUnload = TCUnloadDriver; 93: 94: KeInitializeMutex (&driverMutex, 1); 1.1.1.10 root 95: PsGetVersion (&OsMajorVersion, NULL, NULL, NULL); 1.1 root 96: 97: return TCCreateRootDeviceObject (DriverObject); 98: } 99: 1.1.1.12! root 100: 1.1 root 101: // Dumps a memory region to debug output 1.1.1.12! root 102: void DumpMemory (void *mem, int size) 1.1 root 103: { 104: unsigned char str[20]; 105: unsigned char *m = mem; 106: int i,j; 107: 1.1.1.12! root 108: for (j = 0; j < size / 8; j++) 1.1 root 109: { 110: memset (str,0,sizeof str); 1.1.1.12! root 111: for (i = 0; i < 8; i++) 1.1 root 112: { 1.1.1.12! root 113: if (m[i] > ' ' && m[i] <= '~') 1.1 root 114: str[i]=m[i]; 115: else 116: str[i]='.'; 117: } 118: 1.1.1.12! root 119: Dump ("0x%08p %02x %02x %02x %02x %02x %02x %02x %02x %s\n", 1.1 root 120: m, m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], str); 121: 122: m+=8; 123: } 124: } 1.1.1.12! root 125: 1.1 root 126: 127: /* TCDispatchQueueIRP queues any IRP's so that they can be processed later 128: by the thread -- or in some cases handles them immediately! */ 129: NTSTATUS 130: TCDispatchQueueIRP (PDEVICE_OBJECT DeviceObject, PIRP Irp) 131: { 132: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension; 133: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 134: NTSTATUS ntStatus; 135: 136: #ifdef _DEBUG 1.1.1.12! root 137: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL) ! 138: { ! 139: switch (irpSp->Parameters.DeviceIoControl.IoControlCode) ! 140: { ! 141: case TC_IOCTL_GET_MOUNTED_VOLUMES: ! 142: case TC_IOCTL_GET_PASSWORD_CACHE_STATUS: ! 143: case TC_IOCTL_OPEN_TEST: ! 144: case TC_IOCTL_GET_RESOLVED_SYMLINK: ! 145: case TC_IOCTL_GET_DRIVE_PARTITION_INFO: ! 146: case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES: ! 147: case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS: ! 148: break; ! 149: ! 150: default: ! 151: Dump ("%ls (%d 0x%x)\n", ! 152: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode), ! 153: (int) (irpSp->Parameters.DeviceIoControl.IoControlCode >> 16), ! 154: (int) ((irpSp->Parameters.DeviceIoControl.IoControlCode & 0x1FFF) >> 2)); ! 155: } 1.1.1.10 root 156: } 157: #ifdef EXTRA_INFO 158: else 159: Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x\n", 160: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction); 161: #endif 1.1 root 162: #endif 163: 1.1.1.12! root 164: // Drive filter IRP ! 165: if (!Extension->bRootDevice && Extension->IsDriveFilterDevice) ! 166: return DriveFilterDispatchIrp (DeviceObject, Irp); ! 167: 1.1.1.10 root 168: if (!Extension->bRootDevice && Extension->bShuttingDown 169: && (irpSp->MajorFunction == IRP_MJ_READ 170: || irpSp->MajorFunction == IRP_MJ_WRITE 171: || irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL 172: || irpSp->MajorFunction == IRP_MJ_FLUSH_BUFFERS)) 1.1 root 173: { 1.1.1.12! root 174: // Reject IRP if volume is being dismounted 1.1.1.11 root 175: Dump ("Device %d shutting down: STATUS_DEVICE_NOT_READY\n", Extension->nDosDriveNo); 1.1.1.12! root 176: 1.1.1.11 root 177: Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; 1.1.1.10 root 178: Irp->IoStatus.Information = 0; 1.1 root 179: 1.1.1.10 root 180: ntStatus = Irp->IoStatus.Status; 181: IoCompleteRequest (Irp, IO_NO_INCREMENT); 182: 183: return ntStatus; 1.1 root 184: } 185: 186: switch (irpSp->MajorFunction) 187: { 188: case IRP_MJ_CLOSE: 189: case IRP_MJ_CREATE: 190: case IRP_MJ_CLEANUP: 191: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 192: 193: case IRP_MJ_SHUTDOWN: 1.1.1.6 root 194: if (Extension->bRootDevice) 1.1.1.12! root 195: { ! 196: DriverShuttingDown = TRUE; ! 197: ! 198: if (IsBootEncryptionSetupInProgress()) ! 199: AbortBootEncryptionSetup(); ! 200: ! 201: UnmountAllDevices (DeviceObject, TRUE); ! 202: ! 203: // Boot drive can be safely dismounted only when IRP_MJ_POWER is received after IRP_MJ_SHUTDOWN ! 204: } 1.1.1.4 root 205: 206: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 207: 1.1 root 208: case IRP_MJ_FLUSH_BUFFERS: 209: case IRP_MJ_READ: 210: case IRP_MJ_WRITE: 211: case IRP_MJ_DEVICE_CONTROL: 212: if (Extension->bRootDevice == FALSE) 213: { 214: IoMarkIrpPending (Irp); 215: 216: ExInterlockedInsertTailList ( 217: &Extension->ListEntry, 218: &Irp->Tail.Overlay.ListEntry, 219: &Extension->ListSpinLock); 220: 221: KeReleaseSemaphore ( 222: &Extension->RequestSemaphore, 223: (KPRIORITY) 0, 224: 1, 225: FALSE); 226: 227: return STATUS_PENDING; 228: } 229: else 230: { 1.1.1.12! root 231: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL) ! 232: return ProcessMainDeviceControlIrp (DeviceObject, Extension, Irp); 1.1 root 233: } 234: 1.1.1.12! root 235: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_DEVICE_REQUEST, 0); 1.1 root 236: } 237: 238: #ifdef _DEBUG 239: Dump ("ERROR: Unknown irpSp->MajorFunction in TCDispatchQueueIRP %ls 0x%08x END\n", 240: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction); 241: #endif 242: 1.1.1.12! root 243: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_DEVICE_REQUEST, 0); 1.1 root 244: } 245: 246: NTSTATUS 247: TCCreateRootDeviceObject (PDRIVER_OBJECT DriverObject) 248: { 249: UNICODE_STRING Win32NameString, ntUnicodeString; 250: WCHAR dosname[32], ntname[32]; 251: PDEVICE_OBJECT DeviceObject; 252: NTSTATUS ntStatus; 253: BOOL *bRootExtension; 254: 255: Dump ("TCCreateRootDeviceObject BEGIN\n"); 256: 257: wcscpy (dosname, (LPWSTR) DOS_ROOT_PREFIX); 258: wcscpy (ntname, (LPWSTR) NT_ROOT_PREFIX); 259: RtlInitUnicodeString (&ntUnicodeString, ntname); 260: RtlInitUnicodeString (&Win32NameString, dosname); 261: 262: Dump ("Creating root device nt=%ls dos=%ls\n", ntname, dosname); 1.1.1.3 root 263: 1.1 root 264: ntStatus = IoCreateDevice ( 265: DriverObject, /* Our Driver Object */ 266: sizeof (BOOL), /* Size of state information */ 267: &ntUnicodeString, /* Device name "\Device\Name" */ 1.1.1.3 root 268: FILE_DEVICE_UNKNOWN, /* Device type */ 1.1 root 269: 0, /* Device characteristics */ 270: FALSE, /* Exclusive device */ 271: &DeviceObject); /* Returned ptr to Device Object */ 272: 273: if (!NT_SUCCESS (ntStatus)) 274: { 275: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus); 276: return ntStatus;/* Failed to create DeviceObject */ 277: } 278: 279: DeviceObject->Flags |= DO_DIRECT_IO; 280: DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT; 281: 282: /* Setup the device extension */ 283: bRootExtension = (BOOL *) DeviceObject->DeviceExtension; 284: *bRootExtension = TRUE; 285: 286: /* The symlinks for mount devices are created from user-mode */ 287: ntStatus = IoCreateSymbolicLink (&Win32NameString, &ntUnicodeString); 1.1.1.4 root 288: 1.1 root 289: if (!NT_SUCCESS (ntStatus)) 290: { 291: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus); 292: IoDeleteDevice (DeviceObject); 293: return ntStatus; 294: } 295: 1.1.1.4 root 296: IoRegisterShutdownNotification (DeviceObject); 297: 1.1 root 298: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 299: Dump ("TCCreateRootDeviceObject STATUS_SUCCESS END\n"); 300: return STATUS_SUCCESS; 301: } 302: 303: NTSTATUS 304: TCCreateDeviceObject (PDRIVER_OBJECT DriverObject, 305: PDEVICE_OBJECT * ppDeviceObject, 1.1.1.4 root 306: MOUNT_STRUCT * mount) 1.1 root 307: { 308: UNICODE_STRING Win32NameString, ntUnicodeString; 309: WCHAR dosname[32], ntname[32]; 310: PEXTENSION Extension; 311: NTSTATUS ntStatus; 1.1.1.4 root 312: ULONG devChars = 0; 1.1 root 313: 314: Dump ("TCCreateDeviceObject BEGIN\n"); 315: 1.1.1.4 root 316: TCGetDosNameFromNumber (dosname, mount->nDosDriveNo); 317: TCGetNTNameFromNumber (ntname, mount->nDosDriveNo); 1.1 root 318: RtlInitUnicodeString (&ntUnicodeString, ntname); 319: RtlInitUnicodeString (&Win32NameString, dosname); 320: 1.1.1.4 root 321: devChars = mount->bMountReadOnly ? FILE_READ_ONLY_DEVICE : 0; 322: devChars |= mount->bMountRemovable ? FILE_REMOVABLE_MEDIA : 0; 323: 1.1 root 324: Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname); 325: 326: ntStatus = IoCreateDevice ( 327: DriverObject, /* Our Driver Object */ 328: sizeof (EXTENSION), /* Size of state information */ 329: &ntUnicodeString, /* Device name "\Device\Name" */ 330: FILE_DEVICE_DISK, /* Device type */ 1.1.1.4 root 331: devChars, /* Device characteristics */ 1.1 root 332: FALSE, /* Exclusive device */ 333: ppDeviceObject); /* Returned ptr to Device Object */ 334: 335: if (!NT_SUCCESS (ntStatus)) 336: { 337: Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus); 338: return ntStatus;/* Failed to create DeviceObject */ 339: } 340: /* Initialize device object and extension. */ 341: 342: (*ppDeviceObject)->Flags |= DO_DIRECT_IO; 343: (*ppDeviceObject)->AlignmentRequirement = FILE_WORD_ALIGNMENT; 344: 345: /* Setup the device extension */ 346: Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension; 347: memset (Extension, 0, sizeof (EXTENSION)); 348: 349: Extension->lMagicNumber = 0xabfeacde; 1.1.1.4 root 350: Extension->nDosDriveNo = mount->nDosDriveNo; 351: Extension->bRemovable = mount->bMountRemovable; 1.1 root 352: 353: KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE); 354: KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG); 355: KeInitializeSpinLock (&Extension->ListSpinLock); 356: InitializeListHead (&Extension->ListEntry); 357: 358: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 359: Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n"); 360: 361: return STATUS_SUCCESS; 362: } 363: 1.1.1.5 root 364: 365: void DriverMutexWait () 366: { 367: KeWaitForMutexObject (&driverMutex, Executive, KernelMode, FALSE, NULL); 368: } 369: 370: 371: void DriverMutexRelease () 372: { 373: KeReleaseMutex (&driverMutex, FALSE); 374: } 375: 376: 1.1.1.12! root 377: NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp) 1.1 root 378: { 379: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 380: 381: switch (irpSp->Parameters.DeviceIoControl.IoControlCode) 382: { 383: 384: case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: 385: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_NAME)) 386: { 387: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME); 388: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 389: } 390: else 391: { 392: ULONG outLength; 393: UNICODE_STRING ntUnicodeString; 1.1.1.7 root 394: WCHAR ntName[256]; 1.1 root 395: PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer; 396: 397: TCGetNTNameFromNumber (ntName, Extension->nDosDriveNo); 398: RtlInitUnicodeString (&ntUnicodeString, ntName); 399: 400: outputBuffer->NameLength = ntUnicodeString.Length; 401: outLength = ntUnicodeString.Length + sizeof(USHORT); 402: 403: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) 404: { 405: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME); 406: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 407: 408: break; 409: } 410: 411: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length); 412: 413: Irp->IoStatus.Status = STATUS_SUCCESS; 414: Irp->IoStatus.Information = outLength; 415: 416: Dump ("name = %ls\n",ntName); 417: } 418: break; 419: 420: case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: 421: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_UNIQUE_ID)) 422: { 423: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID); 424: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 425: } 426: else 427: { 428: ULONG outLength; 429: UCHAR volId[128], tmp[] = { 0,0 }; 430: PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer; 431: 432: strcpy (volId, TC_UNIQUE_ID_PREFIX); 433: tmp[0] = 'A' + Extension->nDosDriveNo; 434: strcat (volId, tmp); 435: 1.1.1.6 root 436: outputBuffer->UniqueIdLength = (USHORT) strlen (volId); 437: outLength = strlen (volId) + sizeof(USHORT); 1.1 root 438: 439: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) 440: { 441: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID); 442: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 443: break; 444: } 445: 1.1.1.6 root 446: RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen (volId)); 1.1 root 447: 448: Irp->IoStatus.Status = STATUS_SUCCESS; 449: Irp->IoStatus.Information = outLength; 450: 451: Dump ("id = %s\n",volId); 452: } 453: break; 454: 455: case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME: 456: { 457: ULONG outLength; 458: UNICODE_STRING ntUnicodeString; 1.1.1.7 root 459: WCHAR ntName[256]; 1.1 root 460: PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer; 461: 462: TCGetDosNameFromNumber (ntName, Extension->nDosDriveNo); 463: RtlInitUnicodeString (&ntUnicodeString, ntName); 464: 465: outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length; 466: 467: outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE; 468: outputBuffer->NameLength = ntUnicodeString.Length; 469: 470: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) 471: { 472: Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME); 473: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 474: break; 475: } 476: 477: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length); 478: 479: Irp->IoStatus.Status = STATUS_SUCCESS; 480: Irp->IoStatus.Information = outLength; 481: 482: Dump ("link = %ls\n",ntName); 483: } 484: break; 485: 1.1.1.4 root 486: 1.1 root 487: case IOCTL_DISK_GET_MEDIA_TYPES: 488: case IOCTL_DISK_GET_DRIVE_GEOMETRY: 489: /* Return the drive geometry for the disk. Note that we 490: return values which were made up to suit the disk size. */ 491: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 492: sizeof (DISK_GEOMETRY)) 493: { 1.1.1.11 root 494: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1 root 495: Irp->IoStatus.Information = 0; 496: } 497: else 498: { 499: PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY) 500: Irp->AssociatedIrp.SystemBuffer; 501: 1.1.1.4 root 502: outputBuffer->MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia; 1.1 root 503: outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders; 504: outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder; 505: outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack; 506: outputBuffer->BytesPerSector = Extension->BytesPerSector; 507: Irp->IoStatus.Status = STATUS_SUCCESS; 508: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY); 509: } 510: break; 511: 512: case IOCTL_DISK_GET_PARTITION_INFO: 513: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 514: sizeof (PARTITION_INFORMATION)) 515: { 1.1.1.11 root 516: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1 root 517: Irp->IoStatus.Information = 0; 518: } 519: else 520: { 521: PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION) 522: Irp->AssociatedIrp.SystemBuffer; 523: 524: outputBuffer->PartitionType = Extension->PartitionType; 525: outputBuffer->BootIndicator = FALSE; 526: outputBuffer->RecognizedPartition = TRUE; 527: outputBuffer->RewritePartition = FALSE; 1.1.1.11 root 528: outputBuffer->StartingOffset.QuadPart = SECTOR_SIZE; 1.1 root 529: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; 1.1.1.11 root 530: outputBuffer->HiddenSectors = 0; 1.1 root 531: Irp->IoStatus.Status = STATUS_SUCCESS; 532: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION); 533: } 534: break; 1.1.1.10 root 535: 536: case IOCTL_DISK_GET_PARTITION_INFO_EX: 537: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (PARTITION_INFORMATION_EX)) 538: { 1.1.1.11 root 539: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1.1.10 root 540: Irp->IoStatus.Information = 0; 541: } 542: else 543: { 544: PPARTITION_INFORMATION_EX outputBuffer = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer; 545: 546: outputBuffer->PartitionStyle = PARTITION_STYLE_MBR; 547: outputBuffer->RewritePartition = FALSE; 1.1.1.11 root 548: outputBuffer->StartingOffset.QuadPart = SECTOR_SIZE; 1.1.1.10 root 549: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; 550: outputBuffer->Mbr.PartitionType = Extension->PartitionType; 551: outputBuffer->Mbr.BootIndicator = FALSE; 552: outputBuffer->Mbr.RecognizedPartition = TRUE; 1.1.1.11 root 553: outputBuffer->Mbr.HiddenSectors = 0; 1.1.1.10 root 554: Irp->IoStatus.Status = STATUS_SUCCESS; 555: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION_EX); 556: } 557: break; 558: 1.1.1.6 root 559: case IOCTL_DISK_GET_DRIVE_LAYOUT: 560: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 561: sizeof (DRIVE_LAYOUT_INFORMATION)) 562: { 1.1.1.11 root 563: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1.1.6 root 564: Irp->IoStatus.Information = 0; 565: } 566: else 567: { 568: PDRIVE_LAYOUT_INFORMATION outputBuffer = (PDRIVE_LAYOUT_INFORMATION) 569: Irp->AssociatedIrp.SystemBuffer; 570: 571: outputBuffer->PartitionCount = 1; 572: outputBuffer->Signature = 0; 573: 574: outputBuffer->PartitionEntry->PartitionType = Extension->PartitionType; 575: outputBuffer->PartitionEntry->BootIndicator = FALSE; 576: outputBuffer->PartitionEntry->RecognizedPartition = TRUE; 577: outputBuffer->PartitionEntry->RewritePartition = FALSE; 1.1.1.11 root 578: outputBuffer->PartitionEntry->StartingOffset.QuadPart = SECTOR_SIZE; 579: outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength; 580: outputBuffer->PartitionEntry->HiddenSectors = 0; 1.1.1.6 root 581: 582: Irp->IoStatus.Status = STATUS_SUCCESS; 583: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION); 584: } 585: break; 586: 1.1 root 587: case IOCTL_DISK_GET_LENGTH_INFO: 588: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GET_LENGTH_INFORMATION)) 589: { 590: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; 591: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION); 592: } 593: else 594: { 595: PGET_LENGTH_INFORMATION outputBuffer = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer; 596: 597: outputBuffer->Length.QuadPart = Extension->DiskLength; 598: Irp->IoStatus.Status = STATUS_SUCCESS; 599: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION); 600: } 601: break; 602: 603: case IOCTL_DISK_VERIFY: 604: { 605: PVERIFY_INFORMATION pVerifyInformation; 606: pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer; 607: irpSp->Parameters.Read.ByteOffset.LowPart = 608: pVerifyInformation->StartingOffset.LowPart; 609: irpSp->Parameters.Read.ByteOffset.HighPart = 610: pVerifyInformation->StartingOffset.HighPart; 611: irpSp->Parameters.Read.Length = pVerifyInformation->Length; 612: Irp->IoStatus.Status = STATUS_SUCCESS; 613: Irp->IoStatus.Information = pVerifyInformation->Length; 614: } 615: break; 616: 617: case IOCTL_DISK_CHECK_VERIFY: 1.1.1.6 root 618: case IOCTL_STORAGE_CHECK_VERIFY: 1.1 root 619: { 620: Irp->IoStatus.Status = STATUS_SUCCESS; 621: Irp->IoStatus.Information = 0; 622: } 623: break; 624: 625: case IOCTL_DISK_IS_WRITABLE: 626: { 1.1.1.6 root 627: if (Extension->bReadOnly) 1.1 root 628: Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED; 629: else 630: Irp->IoStatus.Status = STATUS_SUCCESS; 631: Irp->IoStatus.Information = 0; 632: 633: } 634: break; 635: 1.1.1.12! root 636: default: ! 637: return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); ! 638: } ! 639: ! 640: #ifdef DEBUG ! 641: if (!NT_SUCCESS (Irp->IoStatus.Status)) ! 642: Dump ("IOCTL error 0x%08x\n", Irp->IoStatus.Status); ! 643: #endif ! 644: ! 645: return TCCompleteDiskIrp (Irp, Irp->IoStatus.Status, Irp->IoStatus.Information); ! 646: } ! 647: 1.1.1.5 root 648: 1.1.1.12! root 649: NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp) ! 650: { ! 651: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); ! 652: NTSTATUS ntStatus; ! 653: ! 654: switch (irpSp->Parameters.DeviceIoControl.IoControlCode) ! 655: { ! 656: case TC_IOCTL_GET_DRIVER_VERSION: ! 657: case TC_IOCTL_LEGACY_GET_DRIVER_VERSION: 1.1.1.6 root 658: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (LONG)) 1.1 root 659: { 1.1.1.11 root 660: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1 root 661: Irp->IoStatus.Information = 0; 662: } 663: else 664: { 665: LONG tmp = VERSION_NUM; 666: memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4); 1.1.1.6 root 667: Irp->IoStatus.Information = sizeof (LONG); 1.1 root 668: Irp->IoStatus.Status = STATUS_SUCCESS; 669: } 670: break; 671: 1.1.1.12! root 672: case TC_IOCTL_GET_DEVICE_REFCOUNT: 1.1.1.6 root 673: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int)) 1.1 root 674: { 1.1.1.11 root 675: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1 root 676: Irp->IoStatus.Information = 0; 677: } 678: else 679: { 1.1.1.6 root 680: *(int *) Irp->AssociatedIrp.SystemBuffer = DeviceObject->ReferenceCount; 681: Irp->IoStatus.Information = sizeof (int); 682: Irp->IoStatus.Status = STATUS_SUCCESS; 683: } 684: break; 685: 1.1.1.12! root 686: case TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED: 1.1.1.11 root 687: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int)) 688: { 689: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 690: Irp->IoStatus.Information = 0; 691: } 692: else 693: { 694: *(int *) Irp->AssociatedIrp.SystemBuffer = ReferencedDeviceDeleted; 695: Irp->IoStatus.Information = sizeof (int); 696: Irp->IoStatus.Status = STATUS_SUCCESS; 697: } 698: break; 699: 1.1.1.12! root 700: case TC_IOCTL_IS_ANY_VOLUME_MOUNTED: ! 701: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int)) ! 702: { ! 703: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; ! 704: Irp->IoStatus.Information = 0; ! 705: } ! 706: else ! 707: { ! 708: PDEVICE_OBJECT ListDevice; ! 709: *(int *) Irp->AssociatedIrp.SystemBuffer = 0; ! 710: ! 711: for (ListDevice = DeviceObject->DriverObject->DeviceObject; ! 712: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice) ! 713: { ! 714: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; ! 715: if (!ListExtension->bRootDevice ! 716: && !ListExtension->IsDriveFilterDevice ! 717: && ListExtension->lMagicNumber == 0xabfeacde) ! 718: { ! 719: *(int *) Irp->AssociatedIrp.SystemBuffer = 1; ! 720: break; ! 721: } ! 722: } ! 723: ! 724: if (IsBootDriveMounted()) ! 725: *(int *) Irp->AssociatedIrp.SystemBuffer = 1; ! 726: ! 727: Irp->IoStatus.Information = sizeof (int); ! 728: Irp->IoStatus.Status = STATUS_SUCCESS; ! 729: } ! 730: break; ! 731: ! 732: case TC_IOCTL_OPEN_TEST: 1.1.1.6 root 733: { 1.1 root 734: OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 735: OBJECT_ATTRIBUTES ObjectAttributes; 736: HANDLE NtFileHandle; 737: UNICODE_STRING FullFileName; 738: IO_STATUS_BLOCK IoStatus; 739: 740: RtlInitUnicodeString (&FullFileName, opentest->wszFileName); 741: 742: InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE, 743: NULL, NULL); 744: 745: ntStatus = ZwCreateFile (&NtFileHandle, 746: SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none */ , 1.1.1.4 root 747: FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | 1.1 root 748: FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS, 749: NULL /* eabuffer */ , 0 /* ealength */ ); 750: 751: if (NT_SUCCESS (ntStatus)) 752: { 753: ZwClose (NtFileHandle); 754: Dump ("Open test on file %ls success.\n", opentest->wszFileName); 755: } 756: else 757: { 1.1.1.12! root 758: #if 0 1.1 root 759: Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus); 1.1.1.12! root 760: #endif 1.1 root 761: } 762: 763: Irp->IoStatus.Information = 0; 764: Irp->IoStatus.Status = ntStatus; 765: } 766: break; 767: 1.1.1.12! root 768: case TC_IOCTL_WIPE_PASSWORD_CACHE: 1.1.1.5 root 769: DriverMutexWait (); 1.1 root 770: WipeCache (); 1.1.1.5 root 771: DriverMutexRelease (); 1.1 root 772: 773: Irp->IoStatus.Status = STATUS_SUCCESS; 774: Irp->IoStatus.Information = 0; 775: break; 776: 1.1.1.12! root 777: case TC_IOCTL_GET_PASSWORD_CACHE_STATUS: 1.1 root 778: Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS; 779: Irp->IoStatus.Information = 0; 780: break; 781: 1.1.1.12! root 782: case TC_IOCTL_GET_MOUNTED_VOLUMES: 1.1.1.9 root 783: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT) 784: || !DeviceObject || !DeviceObject->DriverObject) 1.1 root 785: { 1.1.1.11 root 786: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1 root 787: Irp->IoStatus.Information = 0; 788: } 789: else 790: { 791: MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 792: PDEVICE_OBJECT ListDevice; 793: 1.1.1.5 root 794: DriverMutexWait (); 795: 1.1 root 796: list->ulMountedDrives = 0; 797: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 798: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice) 799: { 800: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 1.1.1.12! root 801: if (!ListExtension->bRootDevice ! 802: && !ListExtension->IsDriveFilterDevice ! 803: && !ListExtension->bShuttingDown ! 804: && ListExtension->lMagicNumber == 0xabfeacde) 1.1 root 805: { 806: list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo); 807: wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume); 808: list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength; 1.1.1.4 root 809: list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea; 1.1.1.6 root 810: if (ListExtension->cryptoInfo->hiddenVolume) 811: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_HIDDEN; // Hidden volume 812: else if (ListExtension->cryptoInfo->bHiddenVolProtectionAction) 813: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED; // Normal/outer volume (hidden volume protected AND write already prevented) 814: else if (ListExtension->cryptoInfo->bProtectHiddenVolume) 815: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER; // Normal/outer volume (hidden volume protected) 816: else 817: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_NORMAL; // Normal volume 1.1 root 818: } 819: } 820: 1.1.1.5 root 821: DriverMutexRelease (); 822: 1.1 root 823: Irp->IoStatus.Status = STATUS_SUCCESS; 824: Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT); 825: } 826: break; 827: 1.1.1.12! root 828: case TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES: ! 829: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (uint32)) ! 830: { ! 831: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; ! 832: Irp->IoStatus.Information = 0; ! 833: } ! 834: else ! 835: { ! 836: // Prevent the user from downgrading to versions lower than 5.0 by faking mounted volumes. ! 837: // The user could render the system unbootable by downgrading when boot encryption ! 838: // is active or being set up. ! 839: *(uint32 *) Irp->AssociatedIrp.SystemBuffer = 0xffffFFFF; ! 840: Irp->IoStatus.Status = STATUS_SUCCESS; ! 841: Irp->IoStatus.Information = irpSp->Parameters.DeviceIoControl.OutputBufferLength; ! 842: } ! 843: break; ! 844: ! 845: case TC_IOCTL_GET_VOLUME_PROPERTIES: 1.1.1.9 root 846: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT) 847: || !DeviceObject || !DeviceObject->DriverObject) 1.1 root 848: { 1.1.1.11 root 849: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1 root 850: Irp->IoStatus.Information = 0; 851: } 852: else 853: { 854: VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 855: PDEVICE_OBJECT ListDevice; 856: 857: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 858: Irp->IoStatus.Information = 0; 859: 1.1.1.5 root 860: DriverMutexWait (); 861: 1.1 root 862: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 863: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice) 864: { 865: 866: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 1.1.1.12! root 867: if (!ListExtension->bRootDevice ! 868: && !ListExtension->IsDriveFilterDevice 1.1.1.6 root 869: && !ListExtension->bShuttingDown 870: && ListExtension->nDosDriveNo == prop->driveNo) 1.1 root 871: { 1.1.1.6 root 872: prop->uniqueId = ListExtension->UniqueVolumeId; 1.1 root 873: wcscpy (prop->wszVolume, ListExtension->wszVolume); 874: prop->diskLength = ListExtension->DiskLength; 1.1.1.4 root 875: prop->ea = ListExtension->cryptoInfo->ea; 1.1.1.7 root 876: prop->mode = ListExtension->cryptoInfo->mode; 1.1 root 877: prop->pkcs5 = ListExtension->cryptoInfo->pkcs5; 878: prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations; 879: prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time; 880: prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time; 1.1.1.6 root 881: prop->readOnly = ListExtension->bReadOnly; 1.1.1.4 root 882: prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume; 1.1 root 883: 1.1.1.6 root 884: if (ListExtension->cryptoInfo->bProtectHiddenVolume) 885: prop->hiddenVolProtection = ListExtension->cryptoInfo->bHiddenVolProtectionAction ? HIDVOL_PROT_STATUS_ACTION_TAKEN : HIDVOL_PROT_STATUS_ACTIVE; 886: else 887: prop->hiddenVolProtection = HIDVOL_PROT_STATUS_NONE; 888: 1.1.1.12! root 889: prop->totalBytesRead = ListExtension->Queue.TotalBytesRead; ! 890: prop->totalBytesWritten = ListExtension->Queue.TotalBytesWritten; 1.1.1.6 root 891: 1.1 root 892: Irp->IoStatus.Status = STATUS_SUCCESS; 893: Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT); 894: break; 895: } 896: } 1.1.1.5 root 897: 898: DriverMutexRelease (); 1.1 root 899: } 900: break; 901: 1.1.1.12! root 902: case TC_IOCTL_GET_RESOLVED_SYMLINK: 1.1.1.6 root 903: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (RESOLVE_SYMLINK_STRUCT)) 1.1.1.4 root 904: { 1.1.1.11 root 905: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1.1.4 root 906: Irp->IoStatus.Information = 0; 907: } 908: else 1.1 root 909: { 1.1.1.4 root 910: RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 911: { 912: NTSTATUS ntStatus; 913: 914: ntStatus = SymbolicLinkToTarget (resolve->symLinkName, 915: resolve->targetName, 916: sizeof (resolve->targetName)); 917: 918: Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT); 919: Irp->IoStatus.Status = ntStatus; 920: } 921: 922: } 923: break; 924: 1.1.1.12! root 925: case TC_IOCTL_GET_DRIVE_PARTITION_INFO: 1.1.1.10 root 926: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (DISK_PARTITION_INFO_STRUCT)) 927: { 1.1.1.11 root 928: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1.1.10 root 929: Irp->IoStatus.Information = 0; 930: } 931: else 932: { 933: DISK_PARTITION_INFO_STRUCT *info = (DISK_PARTITION_INFO_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 934: { 935: PARTITION_INFORMATION_EX pi; 936: NTSTATUS ntStatus; 937: 938: ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi)); 939: if (NT_SUCCESS(ntStatus)) 940: { 941: memset (&info->partInfo, 0, sizeof (info->partInfo)); 942: 943: info->partInfo.PartitionLength = pi.PartitionLength; 944: info->partInfo.PartitionNumber = pi.PartitionNumber; 945: info->partInfo.StartingOffset = pi.StartingOffset; 946: 947: if (pi.PartitionStyle == PARTITION_STYLE_MBR) 948: info->partInfo.PartitionType = pi.Mbr.PartitionType; 1.1.1.12! root 949: ! 950: info->IsGPT = pi.PartitionStyle == PARTITION_STYLE_GPT; 1.1.1.10 root 951: } 952: else 953: { 954: // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX 955: ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &info->partInfo, sizeof (info->partInfo)); 1.1.1.12! root 956: info->IsGPT = FALSE; 1.1.1.10 root 957: } 958: 959: Irp->IoStatus.Information = sizeof (DISK_PARTITION_INFO_STRUCT); 960: Irp->IoStatus.Status = ntStatus; 961: } 962: 963: } 964: break; 965: 1.1.1.12! root 966: case TC_IOCTL_GET_DRIVE_GEOMETRY: 1.1.1.10 root 967: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (DISK_GEOMETRY_STRUCT)) 968: { 1.1.1.11 root 969: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1.1.10 root 970: Irp->IoStatus.Information = 0; 971: } 972: else 973: { 974: DISK_GEOMETRY_STRUCT *g = (DISK_GEOMETRY_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 975: { 976: NTSTATUS ntStatus; 977: 978: ntStatus = TCDeviceIoControl (g->deviceName, 979: IOCTL_DISK_GET_DRIVE_GEOMETRY, 980: NULL, 0, &g->diskGeometry, sizeof (g->diskGeometry)); 981: 982: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_STRUCT); 983: Irp->IoStatus.Status = ntStatus; 984: } 985: } 986: break; 987: 1.1.1.12! root 988: case TC_IOCTL_PROBE_REAL_DRIVE_SIZE: ! 989: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (ProbeRealDriveSizeRequest)) ! 990: { ! 991: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; ! 992: Irp->IoStatus.Information = 0; ! 993: } ! 994: else ! 995: { ! 996: ProbeRealDriveSizeRequest *request = (ProbeRealDriveSizeRequest *) Irp->AssociatedIrp.SystemBuffer; ! 997: NTSTATUS status; ! 998: UNICODE_STRING name; ! 999: PFILE_OBJECT fileObject; ! 1000: PDEVICE_OBJECT deviceObject; ! 1001: ! 1002: RtlInitUnicodeString (&name, request->DeviceName); ! 1003: status = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject); ! 1004: if (!NT_SUCCESS (status)) ! 1005: { ! 1006: Irp->IoStatus.Information = 0; ! 1007: Irp->IoStatus.Status = status; ! 1008: break; ! 1009: } ! 1010: ! 1011: status = ProbeRealDriveSize (deviceObject, &request->RealDriveSize); ! 1012: ObDereferenceObject (fileObject); ! 1013: ! 1014: if (!NT_SUCCESS (status)) ! 1015: { ! 1016: Irp->IoStatus.Information = 0; ! 1017: Irp->IoStatus.Status = status; ! 1018: } ! 1019: else ! 1020: { ! 1021: Irp->IoStatus.Information = sizeof (ProbeRealDriveSizeRequest); ! 1022: Irp->IoStatus.Status = status; ! 1023: } ! 1024: } ! 1025: break; ! 1026: ! 1027: case TC_IOCTL_MOUNT_VOLUME: 1.1.1.4 root 1028: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT)) 1029: { 1.1.1.11 root 1030: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1.1.4 root 1031: Irp->IoStatus.Information = 0; 1032: } 1033: else 1034: { 1035: MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 1036: 1.1.1.5 root 1037: DriverMutexWait (); 1.1.1.6 root 1038: 1039: Irp->IoStatus.Information = sizeof (MOUNT_STRUCT); 1.1.1.4 root 1040: Irp->IoStatus.Status = MountDevice (DeviceObject, mount); 1.1.1.5 root 1041: DriverMutexRelease (); 1.1.1.6 root 1042: 1043: burn (&mount->VolumePassword, sizeof (mount->VolumePassword)); 1044: burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword)); 1.1 root 1045: } 1046: break; 1047: 1.1.1.12! root 1048: case TC_IOCTL_DISMOUNT_VOLUME: 1.1.1.9 root 1049: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT) 1050: || !DeviceObject || !DeviceObject->DriverObject) 1.1 root 1051: { 1.1.1.11 root 1052: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1 root 1053: Irp->IoStatus.Information = 0; 1054: } 1055: else 1056: { 1057: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 1058: PDEVICE_OBJECT ListDevice; 1059: 1060: unmount->nReturnCode = ERR_DRIVE_NOT_FOUND; 1061: 1062: for (ListDevice = DeviceObject->DriverObject->DeviceObject; 1063: ListDevice != (PDEVICE_OBJECT) NULL; 1064: ListDevice = ListDevice->NextDevice) 1065: { 1066: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 1067: 1.1.1.12! root 1068: if (!ListExtension->bRootDevice ! 1069: && !ListExtension->IsDriveFilterDevice 1.1.1.6 root 1070: && !ListExtension->bShuttingDown 1.1.1.4 root 1071: && unmount->nDosDriveNo == ListExtension->nDosDriveNo) 1.1 root 1072: { 1.1.1.5 root 1073: DriverMutexWait (); 1.1.1.4 root 1074: unmount->nReturnCode = UnmountDevice (ListDevice, unmount->ignoreOpenFiles); 1.1.1.5 root 1075: DriverMutexRelease (); 1.1.1.4 root 1076: break; 1.1.1.8 root 1077: } 1.1.1.4 root 1078: } 1.1 root 1079: 1.1.1.4 root 1080: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT); 1.1 root 1081: Irp->IoStatus.Status = STATUS_SUCCESS; 1082: } 1083: break; 1084: 1.1.1.12! root 1085: case TC_IOCTL_DISMOUNT_ALL_VOLUMES: 1.1.1.4 root 1086: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT)) 1.1 root 1087: { 1.1.1.11 root 1088: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 1.1 root 1089: Irp->IoStatus.Information = 0; 1090: } 1091: else 1092: { 1.1.1.4 root 1093: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; 1.1 root 1094: 1.1.1.12! root 1095: unmount->nReturnCode = UnmountAllDevices (DeviceObject, unmount->ignoreOpenFiles); 1.1 root 1096: 1.1.1.4 root 1097: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT); 1098: Irp->IoStatus.Status = STATUS_SUCCESS; 1.1 root 1099: } 1100: break; 1101: 1.1.1.12! root 1102: case TC_IOCTL_BOOT_ENCRYPTION_SETUP: ! 1103: DriverMutexWait (); ! 1104: ! 1105: Irp->IoStatus.Status = StartBootEncryptionSetup (DeviceObject, Irp, irpSp); ! 1106: Irp->IoStatus.Information = 0; ! 1107: ! 1108: DriverMutexRelease (); ! 1109: break; ! 1110: ! 1111: case TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP: ! 1112: DriverMutexWait (); ! 1113: ! 1114: Irp->IoStatus.Status = AbortBootEncryptionSetup(); ! 1115: Irp->IoStatus.Information = 0; ! 1116: ! 1117: DriverMutexRelease (); ! 1118: break; ! 1119: ! 1120: case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS: ! 1121: DriverMutexWait (); ! 1122: GetBootEncryptionStatus (Irp, irpSp); ! 1123: DriverMutexRelease (); ! 1124: break; ! 1125: ! 1126: case TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT: ! 1127: Irp->IoStatus.Information = 0; ! 1128: Irp->IoStatus.Status = GetSetupResult(); ! 1129: break; ! 1130: ! 1131: case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES: ! 1132: DriverMutexWait (); ! 1133: GetBootDriveVolumeProperties (Irp, irpSp); ! 1134: DriverMutexRelease (); ! 1135: break; ! 1136: ! 1137: case TC_IOCTL_GET_BOOT_LOADER_VERSION: ! 1138: DriverMutexWait (); ! 1139: GetBootLoaderVersion (Irp, irpSp); ! 1140: DriverMutexRelease (); ! 1141: break; ! 1142: ! 1143: case TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER: ! 1144: DriverMutexWait (); ! 1145: ReopenBootVolumeHeader (Irp, irpSp); ! 1146: DriverMutexRelease (); ! 1147: break; ! 1148: ! 1149: default: ! 1150: return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); ! 1151: } 1.1.1.10 root 1152: 1.1.1.12! root 1153: 1.1.1.10 root 1154: #ifdef DEBUG 1.1.1.12! root 1155: if (!NT_SUCCESS (Irp->IoStatus.Status)) ! 1156: { ! 1157: switch (irpSp->Parameters.DeviceIoControl.IoControlCode) ! 1158: { ! 1159: case TC_IOCTL_GET_MOUNTED_VOLUMES: ! 1160: case TC_IOCTL_GET_PASSWORD_CACHE_STATUS: ! 1161: case TC_IOCTL_OPEN_TEST: ! 1162: case TC_IOCTL_GET_RESOLVED_SYMLINK: ! 1163: case TC_IOCTL_GET_DRIVE_PARTITION_INFO: ! 1164: case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES: ! 1165: case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS: ! 1166: break; ! 1167: ! 1168: default: ! 1169: Dump ("IOCTL error 0x%08x\n", Irp->IoStatus.Status); ! 1170: } ! 1171: } 1.1.1.10 root 1172: #endif 1.1.1.12! root 1173: ! 1174: return TCCompleteIrp (Irp, Irp->IoStatus.Status, Irp->IoStatus.Information); ! 1175: } ! 1176: ! 1177: ! 1178: NTSTATUS TCStartThread (PKSTART_ROUTINE threadProc, PVOID threadArg, PKTHREAD *kThread) ! 1179: { ! 1180: NTSTATUS status; ! 1181: HANDLE threadHandle; ! 1182: OBJECT_ATTRIBUTES threadObjAttributes; ! 1183: ! 1184: InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); ! 1185: ! 1186: status = PsCreateSystemThread (&threadHandle, THREAD_ALL_ACCESS, &threadObjAttributes, NULL, NULL, threadProc, threadArg); ! 1187: if (!NT_SUCCESS (status)) ! 1188: return status; ! 1189: ! 1190: status = ObReferenceObjectByHandle (threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID *) kThread, NULL); ! 1191: if (!NT_SUCCESS (status)) ! 1192: { ! 1193: ZwClose (threadHandle); ! 1194: *kThread = NULL; ! 1195: return status; ! 1196: } ! 1197: ! 1198: ZwClose (threadHandle); ! 1199: return STATUS_SUCCESS; ! 1200: } ! 1201: ! 1202: ! 1203: void TCStopThread (PKTHREAD kThread, PKEVENT wakeUpEvent) ! 1204: { ! 1205: if (wakeUpEvent) ! 1206: KeSetEvent (wakeUpEvent, 0, FALSE); ! 1207: ! 1208: KeWaitForSingleObject (kThread, Executive, KernelMode, FALSE, NULL); ! 1209: ObDereferenceObject (kThread); 1.1 root 1210: } 1211: 1.1.1.6 root 1212: 1.1 root 1213: NTSTATUS 1.1.1.12! root 1214: TCStartVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount) 1.1 root 1215: { 1216: PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK)); 1217: HANDLE hThread; 1218: NTSTATUS ntStatus; 1.1.1.6 root 1219: HANDLE process; 1.1.1.12! root 1220: OBJECT_ATTRIBUTES threadObjAttributes; 1.1 root 1221: 1222: Dump ("Starting thread...\n"); 1223: 1224: if (pThreadBlock == NULL) 1225: { 1226: return STATUS_INSUFFICIENT_RESOURCES; 1227: } 1228: else 1229: { 1230: pThreadBlock->DeviceObject = DeviceObject; 1231: pThreadBlock->mount = mount; 1232: } 1233: 1.1.1.6 root 1234: if (mount->bUserContext) 1235: { 1236: ntStatus = ObOpenObjectByPointer (IoGetCurrentProcess (), 0, NULL, 0, NULL, KernelMode, &process); 1237: if (!NT_SUCCESS (ntStatus)) 1238: { 1239: Dump ("ObOpenObjectByPointer Failed\n"); 1240: goto ret; 1241: } 1242: } 1243: else 1244: process = NULL; 1245: 1.1 root 1246: Extension->bThreadShouldQuit = FALSE; 1247: 1.1.1.12! root 1248: InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); ! 1249: 1.1 root 1250: ntStatus = PsCreateSystemThread (&hThread, 1251: THREAD_ALL_ACCESS, 1.1.1.12! root 1252: &threadObjAttributes, 1.1.1.6 root 1253: process, 1.1 root 1254: NULL, 1.1.1.12! root 1255: VolumeThreadProc, 1.1 root 1256: pThreadBlock); 1257: 1258: if (!NT_SUCCESS (ntStatus)) 1259: { 1260: Dump ("PsCreateSystemThread Failed END\n"); 1.1.1.6 root 1261: goto ret; 1.1 root 1262: } 1263: 1.1.1.12! root 1264: ntStatus = ObReferenceObjectByHandle (hThread, 1.1 root 1265: THREAD_ALL_ACCESS, 1266: NULL, 1267: KernelMode, 1268: &Extension->peThread, 1269: NULL); 1.1.1.12! root 1270: 1.1 root 1271: ZwClose (hThread); 1272: 1.1.1.12! root 1273: if (!NT_SUCCESS (ntStatus)) ! 1274: goto ret; ! 1275: 1.1 root 1276: Dump ("Waiting for thread to initialize...\n"); 1277: 1278: KeWaitForSingleObject (&Extension->keCreateEvent, 1.1.1.12! root 1279: Executive, ! 1280: KernelMode, 1.1 root 1281: FALSE, 1282: NULL); 1283: 1284: Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus); 1285: ntStatus = pThreadBlock->ntCreateStatus; 1.1.1.6 root 1286: 1287: ret: 1.1 root 1288: TCfree (pThreadBlock); 1289: return ntStatus; 1290: } 1291: 1292: void 1.1.1.12! root 1293: TCStopVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) 1.1 root 1294: { 1295: NTSTATUS ntStatus; 1296: 1297: if (DeviceObject); /* Remove compiler warning */ 1298: 1299: Dump ("Signalling thread to quit...\n"); 1300: 1301: Extension->bThreadShouldQuit = TRUE; 1302: 1303: KeReleaseSemaphore (&Extension->RequestSemaphore, 1304: 0, 1305: 1, 1306: TRUE); 1307: 1.1.1.4 root 1308: ntStatus = KeWaitForSingleObject (Extension->peThread, 1.1.1.12! root 1309: Executive, ! 1310: KernelMode, 1.1 root 1311: FALSE, 1312: NULL); 1313: if (ntStatus != STATUS_SUCCESS) 1314: Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n", 1315: ntStatus); 1316: 1.1.1.6 root 1317: ObDereferenceObject (Extension->peThread); 1.1 root 1318: Extension->peThread = NULL; 1319: 1320: Dump ("Thread exited!\n"); 1321: } 1322: 1.1.1.5 root 1323: 1324: // Suspend current thread for a number of milliseconds 1325: void TCSleep (int milliSeconds) 1326: { 1327: PKTIMER timer = (PKTIMER) TCalloc (sizeof (KTIMER)); 1328: LARGE_INTEGER duetime; 1329: 1330: duetime.QuadPart = (__int64) milliSeconds * -10000; 1331: KeInitializeTimerEx(timer, NotificationTimer); 1332: KeSetTimerEx(timer, duetime, 0, NULL); 1333: 1.1.1.12! root 1334: KeWaitForSingleObject (timer, Executive, KernelMode, FALSE, NULL); 1.1.1.5 root 1335: 1336: TCfree (timer); 1337: } 1338: 1339: 1.1.1.12! root 1340: /* VolumeThreadProc does all the work of processing IRP's, and dispatching them 1.1 root 1341: to either the ReadWrite function or the DeviceControl function */ 1342: VOID 1.1.1.12! root 1343: VolumeThreadProc (PVOID Context) 1.1 root 1344: { 1345: PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context; 1346: PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject; 1347: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension; 1348: LARGE_INTEGER queueWait; 1349: BOOL bDevice; 1350: 1351: /* Set thread priority to lowest realtime level. */ 1352: KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY); 1353: 1354: queueWait.QuadPart = -WAIT_SECONDS (1); 1355: 1356: Dump ("Mount THREAD OPENING VOLUME BEGIN\n"); 1357: 1358: if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0) 1359: { 1360: wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\")); 1.1.1.7 root 1361: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume, 1362: sizeof (pThreadBlock->wszMountVolume) / 2 - 5); 1.1 root 1363: bDevice = FALSE; 1364: } 1365: else 1366: { 1.1.1.8 root 1367: pThreadBlock->wszMountVolume[0] = 0; 1368: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume, 1.1.1.7 root 1369: sizeof (pThreadBlock->wszMountVolume) / 2 - 1); 1.1 root 1370: bDevice = TRUE; 1371: } 1372: 1373: Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n", 1374: pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice); 1375: 1376: pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject, 1.1.1.7 root 1377: Extension, 1378: pThreadBlock->mount, 1379: pThreadBlock->wszMountVolume, 1380: bDevice); 1.1 root 1381: 1382: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0) 1383: { 1384: KeSetEvent (&Extension->keCreateEvent, 0, FALSE); 1385: PsTerminateSystemThread (STATUS_SUCCESS); 1386: } 1.1.1.12! root 1387: ! 1388: // Start IO queue ! 1389: Extension->Queue.IsFilterDevice = FALSE; ! 1390: Extension->Queue.DeviceObject = DeviceObject; ! 1391: Extension->Queue.CryptoInfo = Extension->cryptoInfo; ! 1392: Extension->Queue.HostFileHandle = Extension->hDeviceFile; ! 1393: Extension->Queue.VirtualDeviceLength = Extension->DiskLength; ! 1394: ! 1395: pThreadBlock->ntCreateStatus = EncryptedIoQueueStart (&Extension->Queue); ! 1396: ! 1397: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus)) 1.1 root 1398: { 1.1.1.12! root 1399: TCCloseVolume (DeviceObject, Extension); ! 1400: ! 1401: pThreadBlock->mount->nReturnCode = ERR_OS_ERROR; 1.1 root 1402: KeSetEvent (&Extension->keCreateEvent, 0, FALSE); 1.1.1.12! root 1403: PsTerminateSystemThread (STATUS_SUCCESS); 1.1 root 1404: } 1405: 1.1.1.12! root 1406: KeSetEvent (&Extension->keCreateEvent, 0, FALSE); ! 1407: /* From this point on pThreadBlock cannot be used as it will have been released! */ ! 1408: pThreadBlock = NULL; ! 1409: 1.1 root 1410: for (;;) 1411: { 1412: NTSTATUS ntStatus; 1413: 1414: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 1415: 1416: /* Wait for a request from the dispatch routines. */ 1417: ntStatus = KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore, 1418: Executive, KernelMode, FALSE, &queueWait); 1419: 1420: if (ntStatus != STATUS_TIMEOUT) 1421: { 1422: for (;;) 1423: { 1424: PIO_STACK_LOCATION irpSp; 1425: PLIST_ENTRY request; 1426: PIRP Irp; 1427: 1428: request = ExInterlockedRemoveHeadList (&Extension->ListEntry, 1429: &Extension->ListSpinLock); 1430: if (request == NULL) 1431: break; 1432: 1433: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL); 1434: 1435: Irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry); 1436: irpSp = IoGetCurrentIrpStackLocation (Irp); 1437: 1438: switch (irpSp->MajorFunction) 1439: { 1440: case IRP_MJ_READ: 1441: case IRP_MJ_WRITE: 1.1.1.12! root 1442: ntStatus = EncryptedIoQueueAddIrp (&Extension->Queue, Irp); ! 1443: ! 1444: if (ntStatus != STATUS_PENDING) ! 1445: TCCompleteDiskIrp (Irp, ntStatus, 0); ! 1446: 1.1 root 1447: break; 1448: 1449: case IRP_MJ_FLUSH_BUFFERS: 1450: case IRP_MJ_SHUTDOWN: 1451: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0); 1452: break; 1453: 1454: case IRP_MJ_DEVICE_CONTROL: 1.1.1.12! root 1455: ProcessVolumeDeviceControlIrp (DeviceObject, Extension, Irp); 1.1 root 1456: break; 1.1.1.10 root 1457: } 1458: } 1.1 root 1459: 1460: if (Extension->bThreadShouldQuit) 1461: { 1462: Dump ("Closing volume along with Thread!\n"); 1.1.1.12! root 1463: ! 1464: EncryptedIoQueueStop (&Extension->Queue); ! 1465: 1.1 root 1466: TCCloseVolume (DeviceObject, Extension); 1467: PsTerminateSystemThread (STATUS_SUCCESS); 1468: } 1469: } 1.1.1.10 root 1470: } 1.1 root 1471: } 1472: 1473: void 1474: TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo) 1475: { 1476: WCHAR tmp[3] = 1477: {0, ':', 0}; 1478: int j = nDriveNo + (WCHAR) 'A'; 1479: 1480: tmp[0] = (short) j; 1481: wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX); 1482: wcsncat (ntname, tmp, 1); 1483: } 1484: 1485: void 1486: TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo) 1487: { 1488: WCHAR tmp[3] = 1489: {0, ':', 0}; 1490: int j = nDriveNo + (WCHAR) 'A'; 1491: 1492: tmp[0] = (short) j; 1493: wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX); 1494: wcscat (dosname, tmp); 1495: } 1496: 1497: #ifdef _DEBUG 1498: LPWSTR 1499: TCTranslateCode (ULONG ulCode) 1500: { 1.1.1.12! root 1501: switch (ulCode) ! 1502: { ! 1503: #define TC_CASE_RET_NAME(CODE) case CODE : return L###CODE ! 1504: ! 1505: TC_CASE_RET_NAME (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP); ! 1506: TC_CASE_RET_NAME (TC_IOCTL_BOOT_ENCRYPTION_SETUP); ! 1507: TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_ALL_VOLUMES); ! 1508: TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_VOLUME); ! 1509: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES); ! 1510: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT); ! 1511: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS); ! 1512: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_LOADER_VERSION); ! 1513: TC_CASE_RET_NAME (TC_IOCTL_GET_DEVICE_REFCOUNT); ! 1514: TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_GEOMETRY); ! 1515: TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_PARTITION_INFO); ! 1516: TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVER_VERSION); ! 1517: TC_CASE_RET_NAME (TC_IOCTL_GET_MOUNTED_VOLUMES); ! 1518: TC_CASE_RET_NAME (TC_IOCTL_GET_PASSWORD_CACHE_STATUS); ! 1519: TC_CASE_RET_NAME (TC_IOCTL_GET_RESOLVED_SYMLINK); ! 1520: TC_CASE_RET_NAME (TC_IOCTL_GET_VOLUME_PROPERTIES); ! 1521: TC_CASE_RET_NAME (TC_IOCTL_IS_ANY_VOLUME_MOUNTED); ! 1522: TC_CASE_RET_NAME (TC_IOCTL_MOUNT_VOLUME); ! 1523: TC_CASE_RET_NAME (TC_IOCTL_OPEN_TEST); ! 1524: TC_CASE_RET_NAME (TC_IOCTL_PROBE_REAL_DRIVE_SIZE); ! 1525: TC_CASE_RET_NAME (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER); ! 1526: TC_CASE_RET_NAME (TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED); ! 1527: TC_CASE_RET_NAME (TC_IOCTL_WIPE_PASSWORD_CACHE); ! 1528: ! 1529: #undef TC_CASE_RET_NAME ! 1530: } ! 1531: 1.1 root 1532: if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) 1533: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY"); 1534: else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) 1535: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX"); 1536: else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME) 1537: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME"); 1538: else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME) 1539: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME"); 1540: else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID) 1541: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID"); 1542: else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY) 1543: return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY"); 1544: else if (ulCode == IOCTL_VOLUME_ONLINE) 1545: return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE"); 1546: else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED) 1547: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED"); 1548: else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED) 1549: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED"); 1550: else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS) 1551: return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS"); 1552: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED) 1553: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED"); 1554: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED) 1555: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED"); 1556: else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO) 1557: return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO"); 1558: else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER) 1559: return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER"); 1560: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO) 1561: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO"); 1562: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX) 1563: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX"); 1564: else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO) 1565: return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO"); 1566: else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT) 1567: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT"); 1568: else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX) 1569: return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX"); 1570: else if (ulCode == IOCTL_DISK_VERIFY) 1571: return (LPWSTR) _T ("IOCTL_DISK_VERIFY"); 1572: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS) 1573: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS"); 1574: else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS) 1575: return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS"); 1576: else if (ulCode == IOCTL_DISK_PERFORMANCE) 1577: return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE"); 1578: else if (ulCode == IOCTL_DISK_IS_WRITABLE) 1579: return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE"); 1580: else if (ulCode == IOCTL_DISK_LOGGING) 1581: return (LPWSTR) _T ("IOCTL_DISK_LOGGING"); 1582: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX) 1583: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX"); 1584: else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE) 1585: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE"); 1586: else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA) 1587: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA"); 1588: else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET) 1589: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET"); 1590: else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE) 1591: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE"); 1592: else if (ulCode == IOCTL_DISK_REQUEST_DATA) 1593: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA"); 1594: else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER) 1595: return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER"); 1596: else if (ulCode == SMART_GET_VERSION) 1597: return (LPWSTR) _T ("SMART_GET_VERSION"); 1598: else if (ulCode == SMART_SEND_DRIVE_COMMAND) 1599: return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND"); 1600: else if (ulCode == SMART_RCV_DRIVE_DATA) 1601: return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA"); 1602: else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY) 1603: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY"); 1604: else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY) 1605: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY"); 1606: else if (ulCode == IOCTL_DISK_CHECK_VERIFY) 1607: return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY"); 1608: else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL) 1609: return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL"); 1610: else if (ulCode == IOCTL_DISK_EJECT_MEDIA) 1611: return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA"); 1612: else if (ulCode == IOCTL_DISK_LOAD_MEDIA) 1613: return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA"); 1614: else if (ulCode == IOCTL_DISK_RESERVE) 1615: return (LPWSTR) _T ("IOCTL_DISK_RESERVE"); 1616: else if (ulCode == IOCTL_DISK_RELEASE) 1617: return (LPWSTR) _T ("IOCTL_DISK_RELEASE"); 1618: else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES) 1619: return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES"); 1620: else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES) 1621: return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES"); 1622: else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO) 1623: return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO"); 1624: else if (ulCode == IRP_MJ_READ) 1625: return (LPWSTR) _T ("IRP_MJ_READ"); 1626: else if (ulCode == IRP_MJ_WRITE) 1627: return (LPWSTR) _T ("IRP_MJ_WRITE"); 1628: else if (ulCode == IRP_MJ_CREATE) 1629: return (LPWSTR) _T ("IRP_MJ_CREATE"); 1630: else if (ulCode == IRP_MJ_CLOSE) 1631: return (LPWSTR) _T ("IRP_MJ_CLOSE"); 1632: else if (ulCode == IRP_MJ_CLEANUP) 1633: return (LPWSTR) _T ("IRP_MJ_CLEANUP"); 1634: else if (ulCode == IRP_MJ_FLUSH_BUFFERS) 1635: return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS"); 1636: else if (ulCode == IRP_MJ_SHUTDOWN) 1637: return (LPWSTR) _T ("IRP_MJ_SHUTDOWN"); 1638: else if (ulCode == IRP_MJ_DEVICE_CONTROL) 1639: return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL"); 1640: else 1641: { 1.1.1.12! root 1642: return (LPWSTR) _T ("IOCTL"); 1.1 root 1643: } 1644: } 1645: 1646: #endif 1647: 1648: PDEVICE_OBJECT 1649: TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) 1650: { 1651: PDEVICE_OBJECT OldDeviceObject = DeviceObject; 1652: UNICODE_STRING Win32NameString; 1653: NTSTATUS ntStatus; 1654: 1655: Dump ("TCDeleteDeviceObject BEGIN\n"); 1656: 1.1.1.6 root 1657: if (Extension->bRootDevice) 1.1 root 1658: { 1659: RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX); 1.1.1.4 root 1660: ntStatus = IoDeleteSymbolicLink (&Win32NameString); 1661: if (!NT_SUCCESS (ntStatus)) 1662: Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus); 1.1 root 1663: } 1664: else 1665: { 1666: if (Extension->peThread != NULL) 1.1.1.12! root 1667: TCStopVolumeThread (DeviceObject, Extension); 1.1 root 1668: } 1669: 1.1.1.8 root 1670: if (DeviceObject != NULL) 1671: DeviceObject = DeviceObject->NextDevice; 1672: 1.1 root 1673: IoDeleteDevice (OldDeviceObject); 1674: 1675: Dump ("TCDeleteDeviceObject END\n"); 1676: return DeviceObject; 1677: } 1678: 1.1.1.4 root 1679: 1.1 root 1680: VOID 1681: TCUnloadDriver (PDRIVER_OBJECT DriverObject) 1682: { 1683: PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject; 1684: 1685: Dump ("TCUnloadDriver BEGIN\n"); 1686: 1.1.1.12! root 1687: UnmountAllDevices (DeviceObject, TRUE); 1.1.1.4 root 1688: 1.1 root 1689: /* Now walk the list of driver objects and get rid of them */ 1690: while (DeviceObject != (PDEVICE_OBJECT) NULL) 1691: { 1692: DeviceObject = TCDeleteDeviceObject (DeviceObject, 1693: (PEXTENSION) DeviceObject->DeviceExtension); 1694: } 1695: 1.1.1.11 root 1696: WipeCache (); 1697: 1.1.1.12! root 1698: if (IsBootDriveMounted()) ! 1699: TC_BUG_CHECK (STATUS_INVALID_DEVICE_STATE); ! 1700: 1.1 root 1701: Dump ("TCUnloadDriver END\n"); 1702: } 1.1.1.4 root 1703: 1704: 1705: NTSTATUS 1706: TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode, 1707: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize) 1708: { 1709: IO_STATUS_BLOCK ioStatusBlock; 1710: NTSTATUS ntStatus; 1711: PIRP irp; 1712: PFILE_OBJECT fileObject; 1713: PDEVICE_OBJECT deviceObject; 1714: KEVENT event; 1715: UNICODE_STRING name; 1716: 1717: RtlInitUnicodeString(&name, deviceName); 1.1.1.10 root 1718: ntStatus = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject); 1.1.1.4 root 1719: 1720: if (ntStatus != STATUS_SUCCESS) 1721: return ntStatus; 1722: 1723: KeInitializeEvent(&event, NotificationEvent, FALSE); 1724: 1725: irp = IoBuildDeviceIoControlRequest (IoControlCode, 1726: deviceObject, 1727: InputBuffer, InputBufferSize, 1728: OutputBuffer, OutputBufferSize, 1729: FALSE, 1730: &event, 1731: &ioStatusBlock); 1732: 1733: if (irp == NULL) 1734: { 1735: Dump ("IRP allocation failed\n"); 1.1.1.11 root 1736: ntStatus = STATUS_INSUFFICIENT_RESOURCES; 1737: goto ret; 1.1.1.4 root 1738: } 1739: 1740: ntStatus = IoCallDriver (deviceObject, irp); 1741: if (ntStatus == STATUS_PENDING) 1742: { 1.1.1.12! root 1743: KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL); 1.1.1.4 root 1744: ntStatus = ioStatusBlock.Status; 1745: } 1746: 1.1.1.11 root 1747: ret: 1748: ObDereferenceObject (fileObject); 1.1.1.4 root 1749: return ntStatus; 1750: } 1751: 1752: 1.1.1.12! root 1753: NTSTATUS SendDeviceIoControlRequest (PDEVICE_OBJECT deviceObject, ULONG ioControlCode, void *inputBuffer, int inputBufferSize, void *outputBuffer, int outputBufferSize) ! 1754: { ! 1755: IO_STATUS_BLOCK ioStatusBlock; ! 1756: NTSTATUS status; ! 1757: PIRP irp; ! 1758: KEVENT event; ! 1759: ! 1760: ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); ! 1761: ! 1762: KeInitializeEvent (&event, NotificationEvent, FALSE); ! 1763: ! 1764: irp = IoBuildDeviceIoControlRequest (ioControlCode, deviceObject, inputBuffer, inputBufferSize, ! 1765: outputBuffer, outputBufferSize, FALSE, &event, &ioStatusBlock); ! 1766: ! 1767: if (!irp) ! 1768: return STATUS_INSUFFICIENT_RESOURCES; ! 1769: ! 1770: ObReferenceObject (deviceObject); ! 1771: ! 1772: status = IoCallDriver (deviceObject, irp); ! 1773: if (status == STATUS_PENDING) ! 1774: { ! 1775: KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL); ! 1776: status = ioStatusBlock.Status; ! 1777: } ! 1778: ! 1779: ObDereferenceObject (deviceObject); ! 1780: return status; ! 1781: } ! 1782: ! 1783: ! 1784: NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize) ! 1785: { ! 1786: NTSTATUS status; ! 1787: LARGE_INTEGER sysLength; ! 1788: LARGE_INTEGER offset; ! 1789: byte *sectorBuffer = TCalloc (SECTOR_SIZE); ! 1790: ! 1791: if (!sectorBuffer) ! 1792: return STATUS_INSUFFICIENT_RESOURCES; ! 1793: ! 1794: status = SendDeviceIoControlRequest (driveDeviceObject, IOCTL_DISK_GET_LENGTH_INFO, ! 1795: NULL, 0, &sysLength, sizeof (sysLength)); ! 1796: ! 1797: if (!NT_SUCCESS (status)) ! 1798: { ! 1799: Dump ("Failed to get drive size - error %x\n", status); ! 1800: return status; ! 1801: } ! 1802: ! 1803: for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += SECTOR_SIZE) ! 1804: { ! 1805: status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, SECTOR_SIZE); ! 1806: if (!NT_SUCCESS (status)) ! 1807: { ! 1808: driveSize->QuadPart = offset.QuadPart; ! 1809: Dump ("Real drive size = %I64d\n", driveSize->QuadPart); ! 1810: TCfree (sectorBuffer); ! 1811: return STATUS_SUCCESS; ! 1812: } ! 1813: } ! 1814: } ! 1815: ! 1816: 1.1.1.4 root 1817: // Opens a mounted TC volume on filesystem level 1818: NTSTATUS 1819: TCOpenFsVolume (PEXTENSION Extension, PHANDLE volumeHandle, PFILE_OBJECT * fileObject) 1820: { 1821: NTSTATUS ntStatus; 1822: OBJECT_ATTRIBUTES objectAttributes; 1823: UNICODE_STRING fullFileName; 1824: IO_STATUS_BLOCK ioStatus; 1.1.1.7 root 1825: WCHAR volumeName[TC_MAX_PATH]; 1.1.1.4 root 1826: 1827: TCGetDosNameFromNumber (volumeName, Extension->nDosDriveNo); 1828: RtlInitUnicodeString (&fullFileName, volumeName); 1829: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); 1830: 1831: ntStatus = ZwCreateFile (volumeHandle, 1832: SYNCHRONIZE | GENERIC_READ, 1833: &objectAttributes, 1834: &ioStatus, 1835: NULL, 1836: FILE_ATTRIBUTE_NORMAL, 1837: FILE_SHARE_READ | FILE_SHARE_WRITE, 1838: FILE_OPEN, 1839: FILE_SYNCHRONOUS_IO_NONALERT, 1840: NULL, 1841: 0); 1842: 1843: Dump ("Volume %ls open NTSTATUS 0x%08x\n", volumeName, ntStatus); 1844: 1845: if (!NT_SUCCESS (ntStatus)) 1846: return ntStatus; 1847: 1848: ntStatus = ObReferenceObjectByHandle (*volumeHandle, 1849: FILE_READ_DATA, 1850: NULL, 1851: KernelMode, 1852: fileObject, 1853: NULL); 1854: 1855: Dump ("ObReferenceObjectByHandle NTSTATUS 0x%08x\n", ntStatus); 1856: 1857: if (!NT_SUCCESS (ntStatus)) 1858: { 1859: ZwClose(*volumeHandle); 1860: return ntStatus; 1861: } 1862: 1863: return ntStatus; 1864: } 1865: 1866: 1867: void 1868: TCCloseFsVolume (HANDLE volumeHandle, PFILE_OBJECT fileObject) 1869: { 1870: ObDereferenceObject (fileObject); 1871: ZwClose (volumeHandle); 1872: } 1873: 1874: 1.1.1.12! root 1875: static NTSTATUS TCReadWriteDevice (BOOL write, PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length) ! 1876: { ! 1877: NTSTATUS status; ! 1878: IO_STATUS_BLOCK ioStatusBlock; ! 1879: PIRP irp; ! 1880: KEVENT completionEvent; ! 1881: ! 1882: ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); ! 1883: ! 1884: KeInitializeEvent (&completionEvent, NotificationEvent, FALSE); ! 1885: irp = IoBuildSynchronousFsdRequest (write ? IRP_MJ_WRITE : IRP_MJ_READ, deviceObject, buffer, length, &offset, &completionEvent, &ioStatusBlock); ! 1886: if (!irp) ! 1887: return STATUS_INSUFFICIENT_RESOURCES; ! 1888: ! 1889: ObReferenceObject (deviceObject); ! 1890: status = IoCallDriver (deviceObject, irp); ! 1891: ! 1892: if (status == STATUS_PENDING) ! 1893: { ! 1894: status = KeWaitForSingleObject (&completionEvent, Executive, KernelMode, FALSE, NULL); ! 1895: if (NT_SUCCESS (status)) ! 1896: status = ioStatusBlock.Status; ! 1897: } ! 1898: ! 1899: ObDereferenceObject (deviceObject); ! 1900: return status; ! 1901: } ! 1902: ! 1903: ! 1904: NTSTATUS TCReadDevice (PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length) ! 1905: { ! 1906: return TCReadWriteDevice (FALSE, deviceObject, buffer, offset, length); ! 1907: } ! 1908: ! 1909: ! 1910: NTSTATUS TCWriteDevice (PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length) ! 1911: { ! 1912: return TCReadWriteDevice (TRUE, deviceObject, buffer, offset, length); ! 1913: } ! 1914: ! 1915: 1.1.1.4 root 1916: NTSTATUS 1917: TCFsctlCall (PFILE_OBJECT fileObject, LONG IoControlCode, 1918: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize) 1919: { 1920: IO_STATUS_BLOCK ioStatusBlock; 1921: NTSTATUS ntStatus; 1922: PIRP irp; 1923: KEVENT event; 1924: PIO_STACK_LOCATION stack; 1925: PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject); 1926: 1927: Dump ("IoGetRelatedDeviceObject = 0x%08x\n", deviceObject); 1928: 1929: KeInitializeEvent(&event, NotificationEvent, FALSE); 1930: 1931: irp = IoBuildDeviceIoControlRequest (IoControlCode, 1932: deviceObject, 1933: InputBuffer, InputBufferSize, 1934: OutputBuffer, OutputBufferSize, 1935: FALSE, 1936: &event, 1937: &ioStatusBlock); 1938: 1939: if (irp == NULL) 1940: { 1941: Dump ("IRP allocation failed\n"); 1942: return STATUS_INSUFFICIENT_RESOURCES; 1943: } 1944: 1945: stack = IoGetNextIrpStackLocation(irp); 1946: 1947: stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL; 1948: stack->MinorFunction = IRP_MN_USER_FS_REQUEST; 1949: stack->FileObject = fileObject; 1950: 1951: ntStatus = IoCallDriver (deviceObject, irp); 1952: if (ntStatus == STATUS_PENDING) 1953: { 1.1.1.12! root 1954: KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL); 1.1.1.4 root 1955: ntStatus = ioStatusBlock.Status; 1956: } 1957: 1958: return ntStatus; 1959: } 1960: 1961: 1962: NTSTATUS 1.1.1.6 root 1963: CreateDriveLink (int nDosDriveNo) 1964: { 1.1.1.7 root 1965: WCHAR dev[256], link[256]; 1.1.1.6 root 1966: UNICODE_STRING deviceName, symLink; 1967: NTSTATUS ntStatus; 1968: 1969: TCGetNTNameFromNumber (dev, nDosDriveNo); 1970: TCGetDosNameFromNumber (link, nDosDriveNo); 1971: 1972: RtlInitUnicodeString (&deviceName, dev); 1973: RtlInitUnicodeString (&symLink, link); 1974: 1975: ntStatus = IoCreateSymbolicLink (&symLink, &deviceName); 1976: Dump ("IoCreateSymbolicLink returned %X\n", ntStatus); 1977: return ntStatus; 1978: } 1979: 1980: 1981: NTSTATUS 1982: RemoveDriveLink (int nDosDriveNo) 1983: { 1.1.1.7 root 1984: WCHAR link[256]; 1.1.1.6 root 1985: UNICODE_STRING symLink; 1986: NTSTATUS ntStatus; 1987: 1988: TCGetDosNameFromNumber (link, nDosDriveNo); 1989: RtlInitUnicodeString (&symLink, link); 1990: 1991: ntStatus = IoDeleteSymbolicLink (&symLink); 1992: Dump ("IoDeleteSymbolicLink returned %X\n", ntStatus); 1993: return ntStatus; 1994: } 1995: 1996: 1997: NTSTATUS 1.1.1.4 root 1998: MountManagerMount (MOUNT_STRUCT *mount) 1999: { 2000: NTSTATUS ntStatus; 1.1.1.7 root 2001: WCHAR arrVolume[256]; 1.1.1.4 root 2002: char buf[200]; 2003: PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf; 2004: PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf; 2005: UNICODE_STRING symName, devName; 2006: 2007: TCGetNTNameFromNumber (arrVolume, mount->nDosDriveNo); 2008: in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2; 2009: wcscpy(in->DeviceName, arrVolume); 2010: 2011: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION, 2012: in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0); 2013: 2014: memset (buf, 0, sizeof buf); 2015: TCGetDosNameFromNumber ((PWSTR) &point[1], mount->nDosDriveNo); 2016: 2017: point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT); 2018: point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2; 2019: 2020: RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset)); 2021: 2022: point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength; 2023: TCGetNTNameFromNumber ((PWSTR) (buf + point->DeviceNameOffset), mount->nDosDriveNo); 2024: point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2; 2025: 2026: RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset)); 2027: 2028: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point, 2029: point->DeviceNameOffset + point->DeviceNameLength, 0, 0); 2030: 2031: return ntStatus; 2032: } 2033: 2034: 2035: NTSTATUS 2036: MountManagerUnmount (int nDosDriveNo) 2037: { 2038: NTSTATUS ntStatus; 1.1.1.7 root 2039: char buf[256], out[300]; 1.1.1.4 root 2040: PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf; 2041: 2042: memset (buf, 0, sizeof buf); 2043: 2044: TCGetDosNameFromNumber ((PWSTR) &in[1], nDosDriveNo); 2045: 2046: in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT); 2047: in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2; 2048: 2049: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS, 2050: in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out); 2051: 2052: Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus); 2053: 2054: return ntStatus; 2055: } 2056: 2057: 2058: NTSTATUS 2059: MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) 2060: { 2061: PDEVICE_OBJECT NewDeviceObject; 2062: NTSTATUS ntStatus; 2063: 1.1.1.6 root 2064: /* Make sure the user is asking for a reasonable 1.1.1.4 root 2065: nDosDriveNo */ 2066: if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25) 2067: { 2068: Dump ("Mount request looks valid\n"); 2069: } 2070: else 2071: { 2072: Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n"); 1.1.1.10 root 2073: mount->nReturnCode = ERR_DRIVE_NOT_FOUND; 2074: return ERR_DRIVE_NOT_FOUND; 1.1.1.4 root 2075: } 2076: 1.1.1.6 root 2077: if (!SelfTestsPassed) 2078: { 2079: mount->nReturnCode = ERR_SELF_TESTS_FAILED; 2080: return ERR_SELF_TESTS_FAILED; 2081: } 2082: 1.1.1.4 root 2083: ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject, 2084: mount); 2085: if (!NT_SUCCESS (ntStatus)) 2086: { 2087: Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus); 2088: return ntStatus; 2089: } 2090: else 2091: { 2092: PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension; 1.1.1.12! root 2093: ntStatus = TCStartVolumeThread (NewDeviceObject, NewExtension, mount); 1.1.1.4 root 2094: if (!NT_SUCCESS (ntStatus)) 2095: { 2096: Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus); 2097: TCDeleteDeviceObject (NewDeviceObject, NewExtension); 2098: return ntStatus; 2099: } 2100: else 2101: { 2102: if (mount->nReturnCode == 0) 2103: { 2104: Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode, 2105: NewExtension->bReadOnly); 1.1.1.6 root 2106: if (NewExtension->bReadOnly) 1.1.1.4 root 2107: NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE; 2108: NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 2109: 1.1.1.6 root 2110: NewExtension->UniqueVolumeId = LastUniqueVolumeId++; 2111: 1.1.1.4 root 2112: if (mount->bMountManager) 2113: MountManagerMount (mount); 2114: 1.1.1.6 root 2115: NewExtension->bMountManager = mount->bMountManager; 1.1.1.4 root 2116: 1.1.1.6 root 2117: // We create symbolic link even if mount manager is notified of 2118: // arriving volume as it apparently sometimes fails to create the link 2119: CreateDriveLink (mount->nDosDriveNo); 1.1.1.4 root 2120: } 2121: else 2122: { 2123: Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode); 2124: TCDeleteDeviceObject (NewDeviceObject, NewExtension); 2125: } 2126: 2127: return STATUS_SUCCESS; 2128: } 2129: } 2130: } 2131: 2132: NTSTATUS 2133: UnmountDevice (PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles) 2134: { 2135: PEXTENSION extension = deviceObject->DeviceExtension; 2136: NTSTATUS ntStatus; 2137: HANDLE volumeHandle; 2138: PFILE_OBJECT volumeFileObject; 2139: 1.1.1.8 root 2140: Dump ("UnmountDevice %d\n", extension->nDosDriveNo); 2141: 1.1.1.4 root 2142: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject); 2143: if (!NT_SUCCESS (ntStatus)) 1.1.1.6 root 2144: { 2145: // User may have deleted symbolic link 2146: CreateDriveLink (extension->nDosDriveNo); 2147: 2148: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject); 2149: } 2150: 1.1.1.8 root 2151: if (NT_SUCCESS (ntStatus)) 2152: { 2153: // Lock volume 2154: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0); 2155: Dump ("FSCTL_LOCK_VOLUME returned %X\n", ntStatus); 2156: 2157: if (!NT_SUCCESS (ntStatus) && !ignoreOpenFiles) 2158: { 2159: TCCloseFsVolume (volumeHandle, volumeFileObject); 2160: return ERR_FILES_OPEN; 2161: } 1.1.1.4 root 2162: 1.1.1.8 root 2163: // Dismount volume 2164: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0); 2165: Dump ("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus); 2166: } 2167: else 1.1.1.4 root 2168: { 1.1.1.8 root 2169: // Volume cannot be opened => force dismount if allowed 2170: if (!ignoreOpenFiles) 2171: return ERR_FILES_OPEN; 2172: else 2173: volumeHandle = NULL; 1.1.1.4 root 2174: } 2175: 2176: if (extension->bMountManager) 2177: MountManagerUnmount (extension->nDosDriveNo); 1.1.1.8 root 2178: 1.1.1.6 root 2179: // We always remove symbolic link as mount manager might fail to do so 2180: RemoveDriveLink (extension->nDosDriveNo); 1.1.1.4 root 2181: 1.1.1.10 root 2182: extension->bShuttingDown = TRUE; 2183: 1.1.1.8 root 2184: if (volumeHandle != NULL) 2185: TCCloseFsVolume (volumeHandle, volumeFileObject); 1.1.1.11 root 2186: 2187: if (deviceObject->ReferenceCount > 0) 2188: ReferencedDeviceDeleted = TRUE; 1.1.1.4 root 2189: 2190: Dump ("Deleting DeviceObject with ref count %ld\n", deviceObject->ReferenceCount); 2191: deviceObject->ReferenceCount = 0; 2192: TCDeleteDeviceObject (deviceObject, (PEXTENSION) deviceObject->DeviceExtension); 1.1.1.11 root 2193: 1.1.1.4 root 2194: return 0; 2195: } 2196: 2197: NTSTATUS 1.1.1.12! root 2198: UnmountAllDevices (PDEVICE_OBJECT DeviceObject, BOOL ignoreOpenFiles) 1.1.1.4 root 2199: { 2200: NTSTATUS status = 0; 2201: PDEVICE_OBJECT ListDevice; 2202: 2203: Dump ("Unmounting all volumes\n"); 2204: 1.1.1.9 root 2205: if (!DeviceObject || !DeviceObject->DriverObject) 2206: return STATUS_INVALID_PARAMETER; 2207: 1.1.1.5 root 2208: DriverMutexWait (); 2209: 1.1.1.10 root 2210: ListDevice = DeviceObject->DriverObject->DeviceObject; 2211: while (ListDevice != NULL) 1.1.1.4 root 2212: { 2213: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; 1.1.1.12! root 2214: if (!ListExtension->bRootDevice && !ListExtension->IsDriveFilterDevice && !ListExtension->bShuttingDown) 1.1.1.4 root 2215: { 1.1.1.12! root 2216: PDEVICE_OBJECT nextDevice = ListDevice->NextDevice; 1.1.1.10 root 2217: 1.1.1.12! root 2218: NTSTATUS ntStatus = UnmountDevice (ListDevice, ignoreOpenFiles); ! 2219: status = ntStatus == 0 ? status : ntStatus; 1.1.1.10 root 2220: 1.1.1.12! root 2221: ListDevice = nextDevice; ! 2222: continue; 1.1.1.4 root 2223: } 1.1.1.8 root 2224: 1.1.1.10 root 2225: ListDevice = ListDevice->NextDevice; 1.1.1.4 root 2226: } 2227: 1.1.1.5 root 2228: DriverMutexRelease (); 2229: 1.1.1.4 root 2230: return status; 2231: } 2232: 2233: // Resolves symbolic link name to its target name 2234: NTSTATUS 2235: SymbolicLinkToTarget (PWSTR symlinkName, PWSTR targetName, USHORT maxTargetNameLength) 2236: { 2237: NTSTATUS ntStatus; 2238: OBJECT_ATTRIBUTES objectAttributes; 2239: UNICODE_STRING fullFileName; 2240: HANDLE handle; 2241: 2242: RtlInitUnicodeString (&fullFileName, symlinkName); 2243: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); 2244: 2245: ntStatus = ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes); 2246: 2247: if (NT_SUCCESS (ntStatus)) 2248: { 2249: UNICODE_STRING target; 2250: target.Buffer = targetName; 2251: target.Length = 0; 2252: target.MaximumLength = maxTargetNameLength; 2253: memset (targetName, 0, maxTargetNameLength); 2254: 2255: ntStatus = ZwQuerySymbolicLinkObject (handle, &target, NULL); 2256: 2257: ZwClose (handle); 2258: } 2259: 2260: return ntStatus; 2261: } 1.1.1.6 root 2262: 2263: // Checks if two regions overlap (borders are parts of regions) 2264: BOOL RegionsOverlap (unsigned __int64 start1, unsigned __int64 end1, unsigned __int64 start2, unsigned __int64 end2) 2265: { 2266: return (start1 < start2) ? (end1 >= start2) : (start1 <= end2); 2267: } 1.1.1.12! root 2268: ! 2269: ! 2270: void GetIntersection (uint64 start1, uint32 length1, uint64 start2, uint64 end2, uint64 *intersectStart, uint32 *intersectLength) ! 2271: { ! 2272: uint64 end1 = start1 + length1 - 1; ! 2273: uint64 intersectEnd = (end1 <= end2) ? end1 : end2; ! 2274: ! 2275: *intersectStart = (start1 >= start2) ? start1 : start2; ! 2276: *intersectLength = (uint32) ((*intersectStart > intersectEnd) ? 0 : intersectEnd + 1 - *intersectStart); ! 2277: ! 2278: if (*intersectLength == 0) ! 2279: *intersectStart = start1; ! 2280: } ! 2281: ! 2282: ! 2283: BOOL IsAccessibleByUser (PUNICODE_STRING objectFileName, BOOL readOnly) ! 2284: { ! 2285: OBJECT_ATTRIBUTES fileObjAttributes; ! 2286: IO_STATUS_BLOCK ioStatusBlock; ! 2287: HANDLE fileHandle; ! 2288: NTSTATUS status; ! 2289: ! 2290: ASSERT (!IoIsSystemThread (PsGetCurrentThread())); ! 2291: ! 2292: InitializeObjectAttributes (&fileObjAttributes, objectFileName, OBJ_CASE_INSENSITIVE | OBJ_FORCE_ACCESS_CHECK, NULL, NULL); ! 2293: ! 2294: status = ZwCreateFile (&fileHandle, ! 2295: readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, ! 2296: &fileObjAttributes, ! 2297: &ioStatusBlock, ! 2298: NULL, ! 2299: FILE_ATTRIBUTE_NORMAL, ! 2300: FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, ! 2301: FILE_OPEN, ! 2302: FILE_SYNCHRONOUS_IO_NONALERT, ! 2303: NULL, ! 2304: 0); ! 2305: ! 2306: if (NT_SUCCESS (status)) ! 2307: { ! 2308: ZwClose (fileHandle); ! 2309: return TRUE; ! 2310: } ! 2311: ! 2312: return FALSE; ! 2313: } ! 2314: ! 2315: ! 2316: NTSTATUS TCCompleteIrp (PIRP irp, NTSTATUS status, ULONG_PTR information) ! 2317: { ! 2318: irp->IoStatus.Status = status; ! 2319: irp->IoStatus.Information = information; ! 2320: IoCompleteRequest (irp, IO_NO_INCREMENT); ! 2321: return status; ! 2322: } ! 2323: ! 2324: ! 2325: NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information) ! 2326: { ! 2327: irp->IoStatus.Status = status; ! 2328: irp->IoStatus.Information = information; ! 2329: IoCompleteRequest (irp, NT_SUCCESS (status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT); ! 2330: return status; ! 2331: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.