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