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