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