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