|
|
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.15 root 191: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL && 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.15 root 1277: if (mount->VolumePassword.Length > MAX_PASSWORD)
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.5 root 1290: DriverMutexRelease ();
1.1.1.6 root 1291:
1292: burn (&mount->VolumePassword, sizeof (mount->VolumePassword));
1293: burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword));
1.1 root 1294: }
1295: break;
1296:
1.1.1.12 root 1297: case TC_IOCTL_DISMOUNT_VOLUME:
1.1.1.17! root 1298: if (ValidateIOBufferSize (Irp, sizeof (UNMOUNT_STRUCT), ValidateInputOutput))
1.1 root 1299: {
1300: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1301: PDEVICE_OBJECT ListDevice;
1302:
1303: unmount->nReturnCode = ERR_DRIVE_NOT_FOUND;
1304:
1305: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
1306: ListDevice != (PDEVICE_OBJECT) NULL;
1307: ListDevice = ListDevice->NextDevice)
1308: {
1309: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1310:
1.1.1.12 root 1311: if (!ListExtension->bRootDevice
1.1.1.15 root 1312: && ListExtension->IsVolumeDevice
1.1.1.6 root 1313: && !ListExtension->bShuttingDown
1.1.1.17! root 1314: && unmount->nDosDriveNo == ListExtension->nDosDriveNo
! 1315: && IsVolumeAccessibleByCurrentUser (ListExtension))
1.1 root 1316: {
1.1.1.5 root 1317: DriverMutexWait ();
1.1.1.15 root 1318: unmount->nReturnCode = UnmountDevice (unmount, ListDevice, unmount->ignoreOpenFiles);
1.1.1.5 root 1319: DriverMutexRelease ();
1.1.1.4 root 1320: break;
1.1.1.8 root 1321: }
1.1.1.4 root 1322: }
1.1 root 1323:
1.1.1.4 root 1324: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
1.1 root 1325: Irp->IoStatus.Status = STATUS_SUCCESS;
1326: }
1327: break;
1328:
1.1.1.12 root 1329: case TC_IOCTL_DISMOUNT_ALL_VOLUMES:
1.1.1.17! root 1330: if (ValidateIOBufferSize (Irp, sizeof (UNMOUNT_STRUCT), ValidateInputOutput))
1.1 root 1331: {
1.1.1.4 root 1332: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1.1 root 1333:
1.1.1.15 root 1334: unmount->nReturnCode = UnmountAllDevices (unmount, DeviceObject, unmount->ignoreOpenFiles);
1.1 root 1335:
1.1.1.4 root 1336: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
1337: Irp->IoStatus.Status = STATUS_SUCCESS;
1.1 root 1338: }
1339: break;
1340:
1.1.1.12 root 1341: case TC_IOCTL_BOOT_ENCRYPTION_SETUP:
1342: DriverMutexWait ();
1343:
1344: Irp->IoStatus.Status = StartBootEncryptionSetup (DeviceObject, Irp, irpSp);
1345: Irp->IoStatus.Information = 0;
1346:
1347: DriverMutexRelease ();
1348: break;
1349:
1350: case TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP:
1351: DriverMutexWait ();
1352:
1353: Irp->IoStatus.Status = AbortBootEncryptionSetup();
1354: Irp->IoStatus.Information = 0;
1355:
1356: DriverMutexRelease ();
1357: break;
1358:
1359: case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
1360: DriverMutexWait ();
1361: GetBootEncryptionStatus (Irp, irpSp);
1362: DriverMutexRelease ();
1363: break;
1364:
1365: case TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT:
1366: Irp->IoStatus.Information = 0;
1367: Irp->IoStatus.Status = GetSetupResult();
1368: break;
1369:
1370: case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
1371: DriverMutexWait ();
1372: GetBootDriveVolumeProperties (Irp, irpSp);
1373: DriverMutexRelease ();
1374: break;
1375:
1376: case TC_IOCTL_GET_BOOT_LOADER_VERSION:
1377: DriverMutexWait ();
1378: GetBootLoaderVersion (Irp, irpSp);
1379: DriverMutexRelease ();
1380: break;
1381:
1382: case TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER:
1383: DriverMutexWait ();
1384: ReopenBootVolumeHeader (Irp, irpSp);
1385: DriverMutexRelease ();
1386: break;
1387:
1.1.1.14 root 1388: case TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME:
1389: DriverMutexWait ();
1390: GetBootEncryptionAlgorithmName (Irp, irpSp);
1391: DriverMutexRelease ();
1392: break;
1393:
1.1.1.15 root 1394: case TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING:
1.1.1.17! root 1395: if (ValidateIOBufferSize (Irp, sizeof (int), ValidateOutput))
1.1.1.15 root 1396: {
1397: *(int *) Irp->AssociatedIrp.SystemBuffer = IsHiddenSystemRunning() ? 1 : 0;
1398: Irp->IoStatus.Information = sizeof (int);
1399: Irp->IoStatus.Status = STATUS_SUCCESS;
1400: }
1401: break;
1402:
1.1.1.17! root 1403: case TC_IOCTL_START_DECOY_SYSTEM_WIPE:
! 1404: DriverMutexWait ();
! 1405:
! 1406: Irp->IoStatus.Status = StartDecoySystemWipe (DeviceObject, Irp, irpSp);
! 1407: Irp->IoStatus.Information = 0;
! 1408:
! 1409: DriverMutexRelease ();
! 1410: break;
! 1411:
! 1412: case TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE:
! 1413: DriverMutexWait ();
! 1414:
! 1415: Irp->IoStatus.Status = AbortDecoySystemWipe();
! 1416: Irp->IoStatus.Information = 0;
! 1417:
! 1418: DriverMutexRelease ();
! 1419: break;
! 1420:
! 1421: case TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT:
! 1422: Irp->IoStatus.Status = GetDecoySystemWipeResult();
! 1423: Irp->IoStatus.Information = 0;
! 1424: break;
! 1425:
! 1426: case TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS:
! 1427: DriverMutexWait ();
! 1428: GetDecoySystemWipeStatus (Irp, irpSp);
! 1429: DriverMutexRelease ();
! 1430: break;
! 1431:
! 1432: case TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR:
! 1433: Irp->IoStatus.Status = WriteBootDriveSector (Irp, irpSp);
! 1434: Irp->IoStatus.Information = 0;
! 1435: break;
! 1436:
1.1.1.12 root 1437: default:
1438: return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
1439: }
1.1.1.10 root 1440:
1.1.1.12 root 1441:
1.1.1.10 root 1442: #ifdef DEBUG
1.1.1.12 root 1443: if (!NT_SUCCESS (Irp->IoStatus.Status))
1444: {
1445: switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
1446: {
1447: case TC_IOCTL_GET_MOUNTED_VOLUMES:
1448: case TC_IOCTL_GET_PASSWORD_CACHE_STATUS:
1.1.1.14 root 1449: case TC_IOCTL_GET_TRAVELER_MODE_STATUS:
1450: case TC_IOCTL_SET_TRAVELER_MODE_STATUS:
1.1.1.12 root 1451: case TC_IOCTL_OPEN_TEST:
1452: case TC_IOCTL_GET_RESOLVED_SYMLINK:
1453: case TC_IOCTL_GET_DRIVE_PARTITION_INFO:
1454: case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
1455: case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
1.1.1.15 root 1456: case TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING:
1.1.1.12 root 1457: break;
1458:
1459: default:
1460: Dump ("IOCTL error 0x%08x\n", Irp->IoStatus.Status);
1461: }
1462: }
1.1.1.10 root 1463: #endif
1.1.1.12 root 1464:
1465: return TCCompleteIrp (Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
1466: }
1467:
1468:
1469: NTSTATUS TCStartThread (PKSTART_ROUTINE threadProc, PVOID threadArg, PKTHREAD *kThread)
1470: {
1.1.1.13 root 1471: return TCStartThreadInProcess (threadProc, threadArg, kThread, NULL);
1472: }
1473:
1474:
1475: NTSTATUS TCStartThreadInProcess (PKSTART_ROUTINE threadProc, PVOID threadArg, PKTHREAD *kThread, PEPROCESS process)
1476: {
1.1.1.12 root 1477: NTSTATUS status;
1478: HANDLE threadHandle;
1.1.1.13 root 1479: HANDLE processHandle = NULL;
1.1.1.12 root 1480: OBJECT_ATTRIBUTES threadObjAttributes;
1481:
1.1.1.13 root 1482: if (process)
1483: {
1484: status = ObOpenObjectByPointer (process, OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &processHandle);
1485: if (!NT_SUCCESS (status))
1486: return status;
1487: }
1488:
1.1.1.12 root 1489: InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
1490:
1.1.1.13 root 1491: status = PsCreateSystemThread (&threadHandle, THREAD_ALL_ACCESS, &threadObjAttributes, processHandle, NULL, threadProc, threadArg);
1.1.1.12 root 1492: if (!NT_SUCCESS (status))
1493: return status;
1494:
1495: status = ObReferenceObjectByHandle (threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID *) kThread, NULL);
1496: if (!NT_SUCCESS (status))
1497: {
1498: ZwClose (threadHandle);
1499: *kThread = NULL;
1500: return status;
1501: }
1502:
1.1.1.13 root 1503: if (processHandle)
1504: ZwClose (processHandle);
1505:
1.1.1.12 root 1506: ZwClose (threadHandle);
1507: return STATUS_SUCCESS;
1508: }
1509:
1510:
1511: void TCStopThread (PKTHREAD kThread, PKEVENT wakeUpEvent)
1512: {
1513: if (wakeUpEvent)
1514: KeSetEvent (wakeUpEvent, 0, FALSE);
1515:
1516: KeWaitForSingleObject (kThread, Executive, KernelMode, FALSE, NULL);
1517: ObDereferenceObject (kThread);
1.1 root 1518: }
1519:
1.1.1.6 root 1520:
1.1.1.17! root 1521: NTSTATUS TCStartVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount)
1.1 root 1522: {
1523: PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK));
1524: HANDLE hThread;
1525: NTSTATUS ntStatus;
1.1.1.12 root 1526: OBJECT_ATTRIBUTES threadObjAttributes;
1.1.1.17! root 1527: SECURITY_QUALITY_OF_SERVICE qos;
1.1 root 1528:
1529: Dump ("Starting thread...\n");
1530:
1531: if (pThreadBlock == NULL)
1532: {
1533: return STATUS_INSUFFICIENT_RESOURCES;
1534: }
1535: else
1536: {
1537: pThreadBlock->DeviceObject = DeviceObject;
1538: pThreadBlock->mount = mount;
1539: }
1540:
1.1.1.17! root 1541: qos.Length = sizeof (qos);
! 1542: qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
! 1543: qos.EffectiveOnly = FALSE;
! 1544: qos.ImpersonationLevel = SecurityImpersonation;
! 1545:
! 1546: ntStatus = SeCreateClientSecurity (PsGetCurrentThread(), &qos, FALSE, &Extension->SecurityClientContext);
! 1547: if (!NT_SUCCESS (ntStatus))
! 1548: goto ret;
! 1549:
! 1550: Extension->SecurityClientContextValid = TRUE;
1.1.1.6 root 1551:
1.1 root 1552: Extension->bThreadShouldQuit = FALSE;
1553:
1.1.1.12 root 1554: InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
1555:
1.1 root 1556: ntStatus = PsCreateSystemThread (&hThread,
1557: THREAD_ALL_ACCESS,
1.1.1.12 root 1558: &threadObjAttributes,
1.1.1.17! root 1559: NULL,
1.1 root 1560: NULL,
1.1.1.12 root 1561: VolumeThreadProc,
1.1 root 1562: pThreadBlock);
1563:
1564: if (!NT_SUCCESS (ntStatus))
1565: {
1566: Dump ("PsCreateSystemThread Failed END\n");
1.1.1.6 root 1567: goto ret;
1.1 root 1568: }
1569:
1.1.1.12 root 1570: ntStatus = ObReferenceObjectByHandle (hThread,
1.1 root 1571: THREAD_ALL_ACCESS,
1572: NULL,
1573: KernelMode,
1574: &Extension->peThread,
1575: NULL);
1.1.1.12 root 1576:
1.1 root 1577: ZwClose (hThread);
1578:
1.1.1.12 root 1579: if (!NT_SUCCESS (ntStatus))
1580: goto ret;
1581:
1.1 root 1582: Dump ("Waiting for thread to initialize...\n");
1583:
1584: KeWaitForSingleObject (&Extension->keCreateEvent,
1.1.1.12 root 1585: Executive,
1586: KernelMode,
1.1 root 1587: FALSE,
1588: NULL);
1589:
1590: Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus);
1591: ntStatus = pThreadBlock->ntCreateStatus;
1.1.1.6 root 1592:
1593: ret:
1.1 root 1594: TCfree (pThreadBlock);
1595: return ntStatus;
1596: }
1597:
1.1.1.17! root 1598: void TCStopVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1.1 root 1599: {
1600: NTSTATUS ntStatus;
1601:
1602: if (DeviceObject); /* Remove compiler warning */
1603:
1604: Dump ("Signalling thread to quit...\n");
1605:
1606: Extension->bThreadShouldQuit = TRUE;
1607:
1608: KeReleaseSemaphore (&Extension->RequestSemaphore,
1609: 0,
1610: 1,
1611: TRUE);
1612:
1.1.1.4 root 1613: ntStatus = KeWaitForSingleObject (Extension->peThread,
1.1.1.12 root 1614: Executive,
1615: KernelMode,
1.1 root 1616: FALSE,
1617: NULL);
1618: if (ntStatus != STATUS_SUCCESS)
1619: Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n",
1620: ntStatus);
1621:
1.1.1.6 root 1622: ObDereferenceObject (Extension->peThread);
1.1 root 1623: Extension->peThread = NULL;
1624:
1.1.1.15 root 1625: Dump ("Thread exited\n");
1.1 root 1626: }
1627:
1.1.1.5 root 1628:
1629: // Suspend current thread for a number of milliseconds
1630: void TCSleep (int milliSeconds)
1631: {
1632: PKTIMER timer = (PKTIMER) TCalloc (sizeof (KTIMER));
1633: LARGE_INTEGER duetime;
1634:
1.1.1.14 root 1635: if (!timer)
1636: return;
1637:
1.1.1.5 root 1638: duetime.QuadPart = (__int64) milliSeconds * -10000;
1639: KeInitializeTimerEx(timer, NotificationTimer);
1640: KeSetTimerEx(timer, duetime, 0, NULL);
1641:
1.1.1.12 root 1642: KeWaitForSingleObject (timer, Executive, KernelMode, FALSE, NULL);
1.1.1.5 root 1643:
1644: TCfree (timer);
1645: }
1646:
1647:
1.1.1.12 root 1648: /* VolumeThreadProc does all the work of processing IRP's, and dispatching them
1.1 root 1649: to either the ReadWrite function or the DeviceControl function */
1.1.1.17! root 1650: VOID VolumeThreadProc (PVOID Context)
1.1 root 1651: {
1652: PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context;
1653: PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject;
1654: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
1655: BOOL bDevice;
1656:
1657: /* Set thread priority to lowest realtime level. */
1658: KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY);
1659:
1660: Dump ("Mount THREAD OPENING VOLUME BEGIN\n");
1661:
1662: if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0)
1663: {
1664: wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\"));
1.1.1.7 root 1665: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
1666: sizeof (pThreadBlock->wszMountVolume) / 2 - 5);
1.1 root 1667: bDevice = FALSE;
1668: }
1669: else
1670: {
1.1.1.8 root 1671: pThreadBlock->wszMountVolume[0] = 0;
1672: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
1.1.1.7 root 1673: sizeof (pThreadBlock->wszMountVolume) / 2 - 1);
1.1 root 1674: bDevice = TRUE;
1675: }
1676:
1677: Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n",
1678: pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice);
1679:
1680: pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject,
1.1.1.7 root 1681: Extension,
1682: pThreadBlock->mount,
1683: pThreadBlock->wszMountVolume,
1684: bDevice);
1.1 root 1685:
1686: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0)
1687: {
1688: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1689: PsTerminateSystemThread (STATUS_SUCCESS);
1690: }
1.1.1.12 root 1691:
1692: // Start IO queue
1693: Extension->Queue.IsFilterDevice = FALSE;
1694: Extension->Queue.DeviceObject = DeviceObject;
1695: Extension->Queue.CryptoInfo = Extension->cryptoInfo;
1696: Extension->Queue.HostFileHandle = Extension->hDeviceFile;
1697: Extension->Queue.VirtualDeviceLength = Extension->DiskLength;
1698:
1.1.1.17! root 1699: if (Extension->SecurityClientContextValid)
! 1700: Extension->Queue.SecurityClientContext = &Extension->SecurityClientContext;
! 1701: else
! 1702: Extension->Queue.SecurityClientContext = NULL;
! 1703:
! 1704: pThreadBlock->ntCreateStatus = EncryptedIoQueueStart (&Extension->Queue);
1.1.1.12 root 1705:
1706: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus))
1.1 root 1707: {
1.1.1.12 root 1708: TCCloseVolume (DeviceObject, Extension);
1709:
1710: pThreadBlock->mount->nReturnCode = ERR_OS_ERROR;
1.1 root 1711: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1.1.1.12 root 1712: PsTerminateSystemThread (STATUS_SUCCESS);
1.1 root 1713: }
1714:
1.1.1.12 root 1715: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1716: /* From this point on pThreadBlock cannot be used as it will have been released! */
1717: pThreadBlock = NULL;
1718:
1.1 root 1719: for (;;)
1720: {
1721: /* Wait for a request from the dispatch routines. */
1.1.1.15 root 1722: KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore, Executive, KernelMode, FALSE, NULL);
1.1 root 1723:
1.1.1.15 root 1724: for (;;)
1.1 root 1725: {
1.1.1.15 root 1726: PIO_STACK_LOCATION irpSp;
1727: PLIST_ENTRY request;
1728: PIRP irp;
1.1 root 1729:
1.1.1.15 root 1730: request = ExInterlockedRemoveHeadList (&Extension->ListEntry, &Extension->ListSpinLock);
1731: if (request == NULL)
1732: break;
1.1 root 1733:
1.1.1.15 root 1734: irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry);
1735: irpSp = IoGetCurrentIrpStackLocation (irp);
1.1 root 1736:
1.1.1.15 root 1737: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
1738: ProcessVolumeDeviceControlIrp (DeviceObject, Extension, irp);
1739: else
1740: ASSERT (FALSE);
1741: }
1.1.1.12 root 1742:
1.1.1.15 root 1743: if (Extension->bThreadShouldQuit)
1744: {
1745: Dump ("Closing volume\n");
1746: EncryptedIoQueueStop (&Extension->Queue);
1.1.1.12 root 1747:
1.1.1.15 root 1748: TCCloseVolume (DeviceObject, Extension);
1749: PsTerminateSystemThread (STATUS_SUCCESS);
1.1 root 1750: }
1.1.1.10 root 1751: }
1.1 root 1752: }
1753:
1.1.1.17! root 1754: void TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)
1.1 root 1755: {
1756: WCHAR tmp[3] =
1757: {0, ':', 0};
1758: int j = nDriveNo + (WCHAR) 'A';
1759:
1760: tmp[0] = (short) j;
1761: wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
1762: wcsncat (ntname, tmp, 1);
1763: }
1764:
1.1.1.17! root 1765: void TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo)
1.1 root 1766: {
1767: WCHAR tmp[3] =
1768: {0, ':', 0};
1769: int j = nDriveNo + (WCHAR) 'A';
1770:
1771: tmp[0] = (short) j;
1772: wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX);
1773: wcscat (dosname, tmp);
1774: }
1775:
1776: #ifdef _DEBUG
1.1.1.17! root 1777: LPWSTR TCTranslateCode (ULONG ulCode)
1.1 root 1778: {
1.1.1.12 root 1779: switch (ulCode)
1780: {
1781: #define TC_CASE_RET_NAME(CODE) case CODE : return L###CODE
1782:
1783: TC_CASE_RET_NAME (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
1.1.1.17! root 1784: TC_CASE_RET_NAME (TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE);
1.1.1.12 root 1785: TC_CASE_RET_NAME (TC_IOCTL_BOOT_ENCRYPTION_SETUP);
1786: TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_ALL_VOLUMES);
1787: TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_VOLUME);
1788: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES);
1.1.1.14 root 1789: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME);
1.1.1.12 root 1790: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
1791: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS);
1792: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_LOADER_VERSION);
1.1.1.17! root 1793: TC_CASE_RET_NAME (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT);
! 1794: TC_CASE_RET_NAME (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS);
1.1.1.12 root 1795: TC_CASE_RET_NAME (TC_IOCTL_GET_DEVICE_REFCOUNT);
1796: TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_GEOMETRY);
1797: TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_PARTITION_INFO);
1798: TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVER_VERSION);
1799: TC_CASE_RET_NAME (TC_IOCTL_GET_MOUNTED_VOLUMES);
1800: TC_CASE_RET_NAME (TC_IOCTL_GET_PASSWORD_CACHE_STATUS);
1.1.1.15 root 1801: TC_CASE_RET_NAME (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG);
1.1.1.14 root 1802: TC_CASE_RET_NAME (TC_IOCTL_GET_TRAVELER_MODE_STATUS);
1803: TC_CASE_RET_NAME (TC_IOCTL_SET_TRAVELER_MODE_STATUS);
1.1.1.12 root 1804: TC_CASE_RET_NAME (TC_IOCTL_GET_RESOLVED_SYMLINK);
1805: TC_CASE_RET_NAME (TC_IOCTL_GET_VOLUME_PROPERTIES);
1.1.1.15 root 1806: TC_CASE_RET_NAME (TC_IOCTL_DISK_IS_WRITABLE);
1.1.1.12 root 1807: TC_CASE_RET_NAME (TC_IOCTL_IS_ANY_VOLUME_MOUNTED);
1.1.1.15 root 1808: TC_CASE_RET_NAME (TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING);
1.1.1.12 root 1809: TC_CASE_RET_NAME (TC_IOCTL_MOUNT_VOLUME);
1810: TC_CASE_RET_NAME (TC_IOCTL_OPEN_TEST);
1811: TC_CASE_RET_NAME (TC_IOCTL_PROBE_REAL_DRIVE_SIZE);
1812: TC_CASE_RET_NAME (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER);
1.1.1.17! root 1813: TC_CASE_RET_NAME (TC_IOCTL_START_DECOY_SYSTEM_WIPE);
1.1.1.12 root 1814: TC_CASE_RET_NAME (TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED);
1815: TC_CASE_RET_NAME (TC_IOCTL_WIPE_PASSWORD_CACHE);
1.1.1.17! root 1816: TC_CASE_RET_NAME (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR);
1.1.1.12 root 1817:
1.1.1.15 root 1818: TC_CASE_RET_NAME (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS);
1819:
1.1.1.12 root 1820: #undef TC_CASE_RET_NAME
1821: }
1822:
1.1 root 1823: if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY)
1824: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY");
1825: else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)
1826: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX");
1827: else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME)
1828: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME");
1829: else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME)
1830: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME");
1831: else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID)
1832: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID");
1833: else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY)
1834: return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY");
1835: else if (ulCode == IOCTL_VOLUME_ONLINE)
1836: return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE");
1837: else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED)
1838: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED");
1839: else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED)
1840: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED");
1841: else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS)
1842: return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS");
1843: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED)
1844: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED");
1845: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED)
1846: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED");
1847: else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO)
1848: return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO");
1849: else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER)
1850: return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER");
1851: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO)
1852: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO");
1853: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX)
1854: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX");
1855: else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO)
1856: return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO");
1857: else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT)
1858: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT");
1859: else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX)
1860: return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX");
1861: else if (ulCode == IOCTL_DISK_VERIFY)
1862: return (LPWSTR) _T ("IOCTL_DISK_VERIFY");
1863: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS)
1864: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS");
1865: else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS)
1866: return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS");
1867: else if (ulCode == IOCTL_DISK_PERFORMANCE)
1868: return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE");
1869: else if (ulCode == IOCTL_DISK_IS_WRITABLE)
1870: return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE");
1871: else if (ulCode == IOCTL_DISK_LOGGING)
1872: return (LPWSTR) _T ("IOCTL_DISK_LOGGING");
1873: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX)
1874: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX");
1875: else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE)
1876: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE");
1877: else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA)
1878: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA");
1879: else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET)
1880: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET");
1881: else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE)
1882: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE");
1883: else if (ulCode == IOCTL_DISK_REQUEST_DATA)
1884: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA");
1885: else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER)
1886: return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER");
1887: else if (ulCode == SMART_GET_VERSION)
1888: return (LPWSTR) _T ("SMART_GET_VERSION");
1889: else if (ulCode == SMART_SEND_DRIVE_COMMAND)
1890: return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND");
1891: else if (ulCode == SMART_RCV_DRIVE_DATA)
1892: return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA");
1893: else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY)
1894: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY");
1895: else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY)
1896: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY");
1897: else if (ulCode == IOCTL_DISK_CHECK_VERIFY)
1898: return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY");
1899: else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL)
1900: return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL");
1901: else if (ulCode == IOCTL_DISK_EJECT_MEDIA)
1902: return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA");
1903: else if (ulCode == IOCTL_DISK_LOAD_MEDIA)
1904: return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA");
1905: else if (ulCode == IOCTL_DISK_RESERVE)
1906: return (LPWSTR) _T ("IOCTL_DISK_RESERVE");
1907: else if (ulCode == IOCTL_DISK_RELEASE)
1908: return (LPWSTR) _T ("IOCTL_DISK_RELEASE");
1909: else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES)
1910: return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES");
1911: else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES)
1912: return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES");
1913: else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO)
1914: return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO");
1915: else if (ulCode == IRP_MJ_READ)
1916: return (LPWSTR) _T ("IRP_MJ_READ");
1917: else if (ulCode == IRP_MJ_WRITE)
1918: return (LPWSTR) _T ("IRP_MJ_WRITE");
1919: else if (ulCode == IRP_MJ_CREATE)
1920: return (LPWSTR) _T ("IRP_MJ_CREATE");
1921: else if (ulCode == IRP_MJ_CLOSE)
1922: return (LPWSTR) _T ("IRP_MJ_CLOSE");
1923: else if (ulCode == IRP_MJ_CLEANUP)
1924: return (LPWSTR) _T ("IRP_MJ_CLEANUP");
1925: else if (ulCode == IRP_MJ_FLUSH_BUFFERS)
1926: return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS");
1927: else if (ulCode == IRP_MJ_SHUTDOWN)
1928: return (LPWSTR) _T ("IRP_MJ_SHUTDOWN");
1929: else if (ulCode == IRP_MJ_DEVICE_CONTROL)
1930: return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL");
1931: else
1932: {
1.1.1.12 root 1933: return (LPWSTR) _T ("IOCTL");
1.1 root 1934: }
1935: }
1936:
1937: #endif
1938:
1.1.1.17! root 1939: PDEVICE_OBJECT TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1.1 root 1940: {
1941: PDEVICE_OBJECT OldDeviceObject = DeviceObject;
1942: UNICODE_STRING Win32NameString;
1943: NTSTATUS ntStatus;
1944:
1945: Dump ("TCDeleteDeviceObject BEGIN\n");
1946:
1.1.1.6 root 1947: if (Extension->bRootDevice)
1.1 root 1948: {
1949: RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX);
1.1.1.4 root 1950: ntStatus = IoDeleteSymbolicLink (&Win32NameString);
1951: if (!NT_SUCCESS (ntStatus))
1952: Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus);
1.1 root 1953: }
1954: else
1955: {
1956: if (Extension->peThread != NULL)
1.1.1.12 root 1957: TCStopVolumeThread (DeviceObject, Extension);
1.1.1.14 root 1958:
1.1.1.17! root 1959: if (Extension->UserSid)
! 1960: TCfree (Extension->UserSid);
! 1961:
! 1962: if (Extension->SecurityClientContextValid)
! 1963: {
! 1964: if (OsMajorVersion == 5 && OsMinorVersion == 0)
! 1965: {
! 1966: ObDereferenceObject (Extension->SecurityClientContext.ClientToken);
! 1967: }
! 1968: else
! 1969: {
! 1970: // Windows 2000 does not support PsDereferenceImpersonationToken() used by SeDeleteClientSecurity().
! 1971: // TODO: Use only SeDeleteClientSecurity() once support for Windows 2000 is dropped.
! 1972:
! 1973: VOID (*PsDereferenceImpersonationTokenD) (PACCESS_TOKEN ImpersonationToken);
! 1974: UNICODE_STRING name;
! 1975: RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken");
! 1976:
! 1977: PsDereferenceImpersonationTokenD = MmGetSystemRoutineAddress (&name);
! 1978: if (!PsDereferenceImpersonationTokenD)
! 1979: TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED);
! 1980:
! 1981: # define PsDereferencePrimaryToken
! 1982: # define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD
! 1983:
! 1984: SeDeleteClientSecurity (&Extension->SecurityClientContext);
! 1985:
! 1986: # undef PsDereferencePrimaryToken
! 1987: # undef PsDereferenceImpersonationToken
! 1988: }
! 1989: }
! 1990:
1.1.1.14 root 1991: if (DeviceObject->ReferenceCount > 0)
1992: ReferencedDeviceDeleted = TRUE;
1993:
1994: // Forced dismount does not set reference count to zero even if all open handles are closed
1995: Dump ("Deleting device with ref count %ld\n", DeviceObject->ReferenceCount);
1996: DeviceObject->ReferenceCount = 0;
1.1 root 1997: }
1998:
1.1.1.8 root 1999: if (DeviceObject != NULL)
2000: DeviceObject = DeviceObject->NextDevice;
2001:
1.1 root 2002: IoDeleteDevice (OldDeviceObject);
2003:
2004: Dump ("TCDeleteDeviceObject END\n");
2005: return DeviceObject;
2006: }
2007:
1.1.1.4 root 2008:
1.1.1.17! root 2009: VOID TCUnloadDriver (PDRIVER_OBJECT DriverObject)
1.1 root 2010: {
2011: PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
2012:
2013: Dump ("TCUnloadDriver BEGIN\n");
2014:
1.1.1.15 root 2015: UnmountAllDevices (NULL, DeviceObject, TRUE);
1.1.1.4 root 2016:
1.1 root 2017: /* Now walk the list of driver objects and get rid of them */
2018: while (DeviceObject != (PDEVICE_OBJECT) NULL)
2019: {
2020: DeviceObject = TCDeleteDeviceObject (DeviceObject,
2021: (PEXTENSION) DeviceObject->DeviceExtension);
2022: }
2023:
1.1.1.11 root 2024: WipeCache ();
2025:
1.1.1.12 root 2026: if (IsBootDriveMounted())
2027: TC_BUG_CHECK (STATUS_INVALID_DEVICE_STATE);
2028:
1.1.1.15 root 2029: EncryptionThreadPoolStop();
2030:
1.1 root 2031: Dump ("TCUnloadDriver END\n");
2032: }
1.1.1.4 root 2033:
2034:
1.1.1.17! root 2035: NTSTATUS TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode,
1.1.1.4 root 2036: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
2037: {
2038: IO_STATUS_BLOCK ioStatusBlock;
2039: NTSTATUS ntStatus;
2040: PIRP irp;
2041: PFILE_OBJECT fileObject;
2042: PDEVICE_OBJECT deviceObject;
2043: KEVENT event;
2044: UNICODE_STRING name;
2045:
2046: RtlInitUnicodeString(&name, deviceName);
1.1.1.10 root 2047: ntStatus = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
1.1.1.4 root 2048:
2049: if (ntStatus != STATUS_SUCCESS)
2050: return ntStatus;
2051:
2052: KeInitializeEvent(&event, NotificationEvent, FALSE);
2053:
2054: irp = IoBuildDeviceIoControlRequest (IoControlCode,
2055: deviceObject,
2056: InputBuffer, InputBufferSize,
2057: OutputBuffer, OutputBufferSize,
2058: FALSE,
2059: &event,
2060: &ioStatusBlock);
2061:
2062: if (irp == NULL)
2063: {
2064: Dump ("IRP allocation failed\n");
1.1.1.11 root 2065: ntStatus = STATUS_INSUFFICIENT_RESOURCES;
2066: goto ret;
1.1.1.4 root 2067: }
2068:
2069: ntStatus = IoCallDriver (deviceObject, irp);
2070: if (ntStatus == STATUS_PENDING)
2071: {
1.1.1.12 root 2072: KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
1.1.1.4 root 2073: ntStatus = ioStatusBlock.Status;
2074: }
2075:
1.1.1.11 root 2076: ret:
2077: ObDereferenceObject (fileObject);
1.1.1.4 root 2078: return ntStatus;
2079: }
2080:
2081:
1.1.1.12 root 2082: NTSTATUS SendDeviceIoControlRequest (PDEVICE_OBJECT deviceObject, ULONG ioControlCode, void *inputBuffer, int inputBufferSize, void *outputBuffer, int outputBufferSize)
2083: {
2084: IO_STATUS_BLOCK ioStatusBlock;
2085: NTSTATUS status;
2086: PIRP irp;
2087: KEVENT event;
2088:
1.1.1.15 root 2089: ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
1.1.1.12 root 2090:
2091: KeInitializeEvent (&event, NotificationEvent, FALSE);
2092:
2093: irp = IoBuildDeviceIoControlRequest (ioControlCode, deviceObject, inputBuffer, inputBufferSize,
2094: outputBuffer, outputBufferSize, FALSE, &event, &ioStatusBlock);
2095:
2096: if (!irp)
2097: return STATUS_INSUFFICIENT_RESOURCES;
2098:
2099: ObReferenceObject (deviceObject);
2100:
2101: status = IoCallDriver (deviceObject, irp);
2102: if (status == STATUS_PENDING)
2103: {
2104: KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
2105: status = ioStatusBlock.Status;
2106: }
2107:
2108: ObDereferenceObject (deviceObject);
2109: return status;
2110: }
2111:
2112:
2113: NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize)
2114: {
2115: NTSTATUS status;
2116: LARGE_INTEGER sysLength;
2117: LARGE_INTEGER offset;
1.1.1.15 root 2118: byte *sectorBuffer;
1.1.1.14 root 2119: ULONGLONG startTime;
1.1.1.12 root 2120:
1.1.1.15 root 2121: if (!UserCanAccessDriveDevice())
2122: return STATUS_ACCESS_DENIED;
2123:
2124: sectorBuffer = TCalloc (SECTOR_SIZE);
1.1.1.12 root 2125: if (!sectorBuffer)
2126: return STATUS_INSUFFICIENT_RESOURCES;
2127:
2128: status = SendDeviceIoControlRequest (driveDeviceObject, IOCTL_DISK_GET_LENGTH_INFO,
2129: NULL, 0, &sysLength, sizeof (sysLength));
2130:
2131: if (!NT_SUCCESS (status))
2132: {
2133: Dump ("Failed to get drive size - error %x\n", status);
1.1.1.14 root 2134: TCfree (sectorBuffer);
1.1.1.12 root 2135: return status;
2136: }
2137:
1.1.1.14 root 2138: startTime = KeQueryInterruptTime ();
1.1.1.12 root 2139: for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += SECTOR_SIZE)
2140: {
2141: status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, SECTOR_SIZE);
1.1.1.13 root 2142:
1.1.1.15 root 2143: if (NT_SUCCESS (status))
2144: status = TCWriteDevice (driveDeviceObject, sectorBuffer, offset, SECTOR_SIZE);
2145:
1.1.1.14 root 2146: if (!NT_SUCCESS (status))
1.1.1.12 root 2147: {
2148: driveSize->QuadPart = offset.QuadPart;
1.1.1.15 root 2149: Dump ("Real drive size = %I64d bytes (%I64d hidden)\n", driveSize->QuadPart, driveSize->QuadPart - sysLength.QuadPart);
1.1.1.12 root 2150: TCfree (sectorBuffer);
2151: return STATUS_SUCCESS;
2152: }
1.1.1.14 root 2153:
2154: if (KeQueryInterruptTime() - startTime > 3ULL * 60 * 1000 * 1000 * 10)
2155: {
2156: // Abort if probing for more than 3 minutes
2157: driveSize->QuadPart = sysLength.QuadPart;
2158: TCfree (sectorBuffer);
2159: return STATUS_TIMEOUT;
2160: }
1.1.1.12 root 2161: }
2162: }
2163:
2164:
1.1.1.4 root 2165: // Opens a mounted TC volume on filesystem level
1.1.1.17! root 2166: NTSTATUS TCOpenFsVolume (PEXTENSION Extension, PHANDLE volumeHandle, PFILE_OBJECT * fileObject)
1.1.1.4 root 2167: {
2168: NTSTATUS ntStatus;
2169: OBJECT_ATTRIBUTES objectAttributes;
2170: UNICODE_STRING fullFileName;
2171: IO_STATUS_BLOCK ioStatus;
1.1.1.7 root 2172: WCHAR volumeName[TC_MAX_PATH];
1.1.1.4 root 2173:
2174: TCGetDosNameFromNumber (volumeName, Extension->nDosDriveNo);
2175: RtlInitUnicodeString (&fullFileName, volumeName);
2176: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
2177:
2178: ntStatus = ZwCreateFile (volumeHandle,
2179: SYNCHRONIZE | GENERIC_READ,
2180: &objectAttributes,
2181: &ioStatus,
2182: NULL,
2183: FILE_ATTRIBUTE_NORMAL,
2184: FILE_SHARE_READ | FILE_SHARE_WRITE,
2185: FILE_OPEN,
2186: FILE_SYNCHRONOUS_IO_NONALERT,
2187: NULL,
2188: 0);
2189:
2190: Dump ("Volume %ls open NTSTATUS 0x%08x\n", volumeName, ntStatus);
2191:
2192: if (!NT_SUCCESS (ntStatus))
2193: return ntStatus;
2194:
2195: ntStatus = ObReferenceObjectByHandle (*volumeHandle,
2196: FILE_READ_DATA,
2197: NULL,
2198: KernelMode,
2199: fileObject,
2200: NULL);
2201:
2202: Dump ("ObReferenceObjectByHandle NTSTATUS 0x%08x\n", ntStatus);
2203:
2204: if (!NT_SUCCESS (ntStatus))
2205: {
2206: ZwClose(*volumeHandle);
2207: return ntStatus;
2208: }
2209:
2210: return ntStatus;
2211: }
2212:
2213:
1.1.1.17! root 2214: void TCCloseFsVolume (HANDLE volumeHandle, PFILE_OBJECT fileObject)
1.1.1.4 root 2215: {
2216: ObDereferenceObject (fileObject);
2217: ZwClose (volumeHandle);
2218: }
2219:
2220:
1.1.1.12 root 2221: static NTSTATUS TCReadWriteDevice (BOOL write, PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length)
2222: {
2223: NTSTATUS status;
2224: IO_STATUS_BLOCK ioStatusBlock;
2225: PIRP irp;
2226: KEVENT completionEvent;
2227:
1.1.1.15 root 2228: ASSERT (KeGetCurrentIrql() <= APC_LEVEL);
1.1.1.12 root 2229:
2230: KeInitializeEvent (&completionEvent, NotificationEvent, FALSE);
2231: irp = IoBuildSynchronousFsdRequest (write ? IRP_MJ_WRITE : IRP_MJ_READ, deviceObject, buffer, length, &offset, &completionEvent, &ioStatusBlock);
2232: if (!irp)
2233: return STATUS_INSUFFICIENT_RESOURCES;
2234:
2235: ObReferenceObject (deviceObject);
2236: status = IoCallDriver (deviceObject, irp);
2237:
2238: if (status == STATUS_PENDING)
2239: {
2240: status = KeWaitForSingleObject (&completionEvent, Executive, KernelMode, FALSE, NULL);
2241: if (NT_SUCCESS (status))
2242: status = ioStatusBlock.Status;
2243: }
2244:
2245: ObDereferenceObject (deviceObject);
2246: return status;
2247: }
2248:
2249:
2250: NTSTATUS TCReadDevice (PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length)
2251: {
2252: return TCReadWriteDevice (FALSE, deviceObject, buffer, offset, length);
2253: }
2254:
2255:
2256: NTSTATUS TCWriteDevice (PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length)
2257: {
2258: return TCReadWriteDevice (TRUE, deviceObject, buffer, offset, length);
2259: }
2260:
2261:
1.1.1.17! root 2262: NTSTATUS TCFsctlCall (PFILE_OBJECT fileObject, LONG IoControlCode,
1.1.1.4 root 2263: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
2264: {
2265: IO_STATUS_BLOCK ioStatusBlock;
2266: NTSTATUS ntStatus;
2267: PIRP irp;
2268: KEVENT event;
2269: PIO_STACK_LOCATION stack;
2270: PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject);
2271:
2272: KeInitializeEvent(&event, NotificationEvent, FALSE);
2273:
2274: irp = IoBuildDeviceIoControlRequest (IoControlCode,
2275: deviceObject,
2276: InputBuffer, InputBufferSize,
2277: OutputBuffer, OutputBufferSize,
2278: FALSE,
2279: &event,
2280: &ioStatusBlock);
2281:
2282: if (irp == NULL)
2283: return STATUS_INSUFFICIENT_RESOURCES;
2284:
2285: stack = IoGetNextIrpStackLocation(irp);
2286:
2287: stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
2288: stack->MinorFunction = IRP_MN_USER_FS_REQUEST;
2289: stack->FileObject = fileObject;
2290:
2291: ntStatus = IoCallDriver (deviceObject, irp);
2292: if (ntStatus == STATUS_PENDING)
2293: {
1.1.1.12 root 2294: KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
1.1.1.4 root 2295: ntStatus = ioStatusBlock.Status;
2296: }
2297:
2298: return ntStatus;
2299: }
2300:
2301:
1.1.1.17! root 2302: NTSTATUS CreateDriveLink (int nDosDriveNo)
1.1.1.6 root 2303: {
1.1.1.15 root 2304: WCHAR dev[128], link[128];
1.1.1.6 root 2305: UNICODE_STRING deviceName, symLink;
2306: NTSTATUS ntStatus;
2307:
2308: TCGetNTNameFromNumber (dev, nDosDriveNo);
2309: TCGetDosNameFromNumber (link, nDosDriveNo);
2310:
2311: RtlInitUnicodeString (&deviceName, dev);
2312: RtlInitUnicodeString (&symLink, link);
2313:
2314: ntStatus = IoCreateSymbolicLink (&symLink, &deviceName);
2315: Dump ("IoCreateSymbolicLink returned %X\n", ntStatus);
2316: return ntStatus;
2317: }
2318:
2319:
1.1.1.17! root 2320: NTSTATUS RemoveDriveLink (int nDosDriveNo)
1.1.1.6 root 2321: {
1.1.1.7 root 2322: WCHAR link[256];
1.1.1.6 root 2323: UNICODE_STRING symLink;
2324: NTSTATUS ntStatus;
2325:
2326: TCGetDosNameFromNumber (link, nDosDriveNo);
2327: RtlInitUnicodeString (&symLink, link);
2328:
2329: ntStatus = IoDeleteSymbolicLink (&symLink);
2330: Dump ("IoDeleteSymbolicLink returned %X\n", ntStatus);
2331: return ntStatus;
2332: }
2333:
2334:
1.1.1.17! root 2335: NTSTATUS MountManagerMount (MOUNT_STRUCT *mount)
1.1.1.4 root 2336: {
2337: NTSTATUS ntStatus;
1.1.1.7 root 2338: WCHAR arrVolume[256];
1.1.1.4 root 2339: char buf[200];
2340: PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf;
2341: PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf;
2342: UNICODE_STRING symName, devName;
2343:
2344: TCGetNTNameFromNumber (arrVolume, mount->nDosDriveNo);
2345: in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2;
2346: wcscpy(in->DeviceName, arrVolume);
2347:
2348: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
2349: in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0);
2350:
2351: memset (buf, 0, sizeof buf);
2352: TCGetDosNameFromNumber ((PWSTR) &point[1], mount->nDosDriveNo);
2353:
2354: point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
2355: point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;
2356:
2357: RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset));
2358:
2359: point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength;
2360: TCGetNTNameFromNumber ((PWSTR) (buf + point->DeviceNameOffset), mount->nDosDriveNo);
2361: point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2;
2362:
2363: RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset));
2364:
2365: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point,
2366: point->DeviceNameOffset + point->DeviceNameLength, 0, 0);
2367:
2368: return ntStatus;
2369: }
2370:
2371:
1.1.1.17! root 2372: NTSTATUS MountManagerUnmount (int nDosDriveNo)
1.1.1.4 root 2373: {
2374: NTSTATUS ntStatus;
1.1.1.7 root 2375: char buf[256], out[300];
1.1.1.4 root 2376: PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf;
2377:
2378: memset (buf, 0, sizeof buf);
2379:
2380: TCGetDosNameFromNumber ((PWSTR) &in[1], nDosDriveNo);
2381:
2382: in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
2383: in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2;
2384:
2385: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS,
2386: in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out);
2387:
2388: Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus);
2389:
2390: return ntStatus;
2391: }
2392:
2393:
1.1.1.17! root 2394: NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount)
1.1.1.4 root 2395: {
2396: PDEVICE_OBJECT NewDeviceObject;
2397: NTSTATUS ntStatus;
2398:
1.1.1.17! root 2399: // Make sure the user is asking for a reasonable nDosDriveNo
1.1.1.15 root 2400: if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25 && IsDriveLetterAvailable (mount->nDosDriveNo))
1.1.1.4 root 2401: {
2402: Dump ("Mount request looks valid\n");
2403: }
2404: else
2405: {
2406: Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n");
1.1.1.10 root 2407: mount->nReturnCode = ERR_DRIVE_NOT_FOUND;
2408: return ERR_DRIVE_NOT_FOUND;
1.1.1.4 root 2409: }
2410:
1.1.1.6 root 2411: if (!SelfTestsPassed)
2412: {
2413: mount->nReturnCode = ERR_SELF_TESTS_FAILED;
2414: return ERR_SELF_TESTS_FAILED;
2415: }
2416:
1.1.1.17! root 2417: ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject, mount);
! 2418:
1.1.1.4 root 2419: if (!NT_SUCCESS (ntStatus))
2420: {
2421: Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
2422: return ntStatus;
2423: }
2424: else
2425: {
2426: PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension;
1.1.1.17! root 2427: SECURITY_SUBJECT_CONTEXT subContext;
! 2428: PACCESS_TOKEN accessToken;
! 2429:
! 2430: SeCaptureSubjectContext (&subContext);
! 2431: accessToken = SeQuerySubjectContextToken (&subContext);
! 2432:
! 2433: if (!accessToken)
! 2434: {
! 2435: ntStatus = STATUS_INVALID_PARAMETER;
! 2436: }
! 2437: else
! 2438: {
! 2439: PTOKEN_USER tokenUser;
! 2440:
! 2441: ntStatus = SeQueryInformationToken (accessToken, TokenUser, &tokenUser);
! 2442: if (NT_SUCCESS (ntStatus))
! 2443: {
! 2444: ULONG sidLength = RtlLengthSid (tokenUser->User.Sid);
! 2445:
! 2446: NewExtension->UserSid = TCalloc (sidLength);
! 2447: if (!NewExtension->UserSid)
! 2448: ntStatus = STATUS_INSUFFICIENT_RESOURCES;
! 2449: else
! 2450: ntStatus = RtlCopySid (sidLength, NewExtension->UserSid, tokenUser->User.Sid);
! 2451: }
! 2452: }
! 2453:
! 2454: SeReleaseSubjectContext (&subContext);
! 2455:
! 2456: if (NT_SUCCESS (ntStatus))
! 2457: ntStatus = TCStartVolumeThread (NewDeviceObject, NewExtension, mount);
! 2458:
1.1.1.4 root 2459: if (!NT_SUCCESS (ntStatus))
2460: {
2461: Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus);
2462: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
2463: return ntStatus;
2464: }
2465: else
2466: {
2467: if (mount->nReturnCode == 0)
2468: {
1.1.1.17! root 2469: HANDLE volumeHandle;
! 2470: PFILE_OBJECT volumeFileObject;
! 2471:
! 2472: Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode, NewExtension->bReadOnly);
! 2473:
1.1.1.6 root 2474: if (NewExtension->bReadOnly)
1.1.1.4 root 2475: NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
1.1.1.17! root 2476:
1.1.1.4 root 2477: NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
2478:
1.1.1.6 root 2479: NewExtension->UniqueVolumeId = LastUniqueVolumeId++;
2480:
1.1.1.4 root 2481: if (mount->bMountManager)
2482: MountManagerMount (mount);
2483:
1.1.1.6 root 2484: NewExtension->bMountManager = mount->bMountManager;
1.1.1.4 root 2485:
1.1.1.6 root 2486: // We create symbolic link even if mount manager is notified of
2487: // arriving volume as it apparently sometimes fails to create the link
2488: CreateDriveLink (mount->nDosDriveNo);
1.1.1.17! root 2489:
! 2490: mount->FilesystemDirty = FALSE;
! 2491:
! 2492: if (NT_SUCCESS (TCOpenFsVolume (NewExtension, &volumeHandle, &volumeFileObject)))
! 2493: {
! 2494: __try
! 2495: {
! 2496: ULONG fsStatus;
! 2497:
! 2498: if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_IS_VOLUME_DIRTY, NULL, 0, &fsStatus, sizeof (fsStatus)))
! 2499: && (fsStatus & VOLUME_IS_DIRTY))
! 2500: {
! 2501: mount->FilesystemDirty = TRUE;
! 2502: }
! 2503: }
! 2504: __except (EXCEPTION_EXECUTE_HANDLER)
! 2505: {
! 2506: mount->FilesystemDirty = TRUE;
! 2507: }
! 2508:
! 2509: TCCloseFsVolume (volumeHandle, volumeFileObject);
! 2510: }
1.1.1.4 root 2511: }
2512: else
2513: {
2514: Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode);
2515: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
2516: }
2517:
2518: return STATUS_SUCCESS;
2519: }
2520: }
2521: }
2522:
1.1.1.17! root 2523: NTSTATUS UnmountDevice (UNMOUNT_STRUCT *unmountRequest, PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles)
1.1.1.4 root 2524: {
2525: PEXTENSION extension = deviceObject->DeviceExtension;
2526: NTSTATUS ntStatus;
2527: HANDLE volumeHandle;
2528: PFILE_OBJECT volumeFileObject;
2529:
1.1.1.8 root 2530: Dump ("UnmountDevice %d\n", extension->nDosDriveNo);
2531:
1.1.1.4 root 2532: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
2533: if (!NT_SUCCESS (ntStatus))
1.1.1.6 root 2534: {
2535: // User may have deleted symbolic link
2536: CreateDriveLink (extension->nDosDriveNo);
2537:
2538: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
2539: }
2540:
1.1.1.8 root 2541: if (NT_SUCCESS (ntStatus))
2542: {
1.1.1.15 root 2543: int dismountRetry;
2544:
1.1.1.8 root 2545: // Lock volume
2546: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
2547: Dump ("FSCTL_LOCK_VOLUME returned %X\n", ntStatus);
2548:
2549: if (!NT_SUCCESS (ntStatus) && !ignoreOpenFiles)
2550: {
2551: TCCloseFsVolume (volumeHandle, volumeFileObject);
2552: return ERR_FILES_OPEN;
2553: }
1.1.1.4 root 2554:
1.1.1.8 root 2555: // Dismount volume
1.1.1.15 root 2556: for (dismountRetry = 0; dismountRetry < 50; ++dismountRetry)
2557: {
2558: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
2559: Dump ("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus);
2560:
1.1.1.17! root 2561: if (NT_SUCCESS (ntStatus) || ntStatus == STATUS_VOLUME_DISMOUNTED)
1.1.1.15 root 2562: break;
2563:
2564: TCSleep (100);
2565: }
1.1.1.8 root 2566: }
2567: else
1.1.1.4 root 2568: {
1.1.1.8 root 2569: // Volume cannot be opened => force dismount if allowed
2570: if (!ignoreOpenFiles)
2571: return ERR_FILES_OPEN;
2572: else
2573: volumeHandle = NULL;
1.1.1.4 root 2574: }
2575:
2576: if (extension->bMountManager)
2577: MountManagerUnmount (extension->nDosDriveNo);
1.1.1.8 root 2578:
1.1.1.6 root 2579: // We always remove symbolic link as mount manager might fail to do so
2580: RemoveDriveLink (extension->nDosDriveNo);
1.1.1.4 root 2581:
1.1.1.10 root 2582: extension->bShuttingDown = TRUE;
2583:
1.1.1.8 root 2584: if (volumeHandle != NULL)
2585: TCCloseFsVolume (volumeHandle, volumeFileObject);
1.1.1.4 root 2586:
1.1.1.15 root 2587: if (unmountRequest)
2588: {
2589: PCRYPTO_INFO cryptoInfo = ((PEXTENSION) deviceObject->DeviceExtension)->cryptoInfo;
2590: unmountRequest->HiddenVolumeProtectionTriggered = (cryptoInfo->bProtectHiddenVolume && cryptoInfo->bHiddenVolProtectionAction);
2591: }
2592:
1.1.1.4 root 2593: TCDeleteDeviceObject (deviceObject, (PEXTENSION) deviceObject->DeviceExtension);
2594: return 0;
2595: }
2596:
1.1.1.17! root 2597: NTSTATUS UnmountAllDevices (UNMOUNT_STRUCT *unmountRequest, PDEVICE_OBJECT DeviceObject, BOOL ignoreOpenFiles)
1.1.1.4 root 2598: {
2599: NTSTATUS status = 0;
2600: PDEVICE_OBJECT ListDevice;
2601:
2602: Dump ("Unmounting all volumes\n");
2603:
1.1.1.17! root 2604: if (unmountRequest)
! 2605: unmountRequest->HiddenVolumeProtectionTriggered = FALSE;
! 2606:
1.1.1.9 root 2607: if (!DeviceObject || !DeviceObject->DriverObject)
2608: return STATUS_INVALID_PARAMETER;
2609:
1.1.1.5 root 2610: DriverMutexWait ();
2611:
1.1.1.10 root 2612: ListDevice = DeviceObject->DriverObject->DeviceObject;
2613: while (ListDevice != NULL)
1.1.1.4 root 2614: {
2615: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.17! root 2616: if (!ListExtension->bRootDevice && ListExtension->IsVolumeDevice && !ListExtension->bShuttingDown
! 2617: && IsVolumeAccessibleByCurrentUser (ListExtension))
1.1.1.4 root 2618: {
1.1.1.12 root 2619: PDEVICE_OBJECT nextDevice = ListDevice->NextDevice;
1.1.1.15 root 2620: NTSTATUS ntStatus;
2621:
2622: if (unmountRequest)
2623: unmountRequest->nDosDriveNo = ListExtension->nDosDriveNo;
1.1.1.10 root 2624:
1.1.1.15 root 2625: ntStatus = UnmountDevice (unmountRequest, ListDevice, ignoreOpenFiles);
1.1.1.12 root 2626: status = ntStatus == 0 ? status : ntStatus;
1.1.1.10 root 2627:
1.1.1.15 root 2628: if (unmountRequest && unmountRequest->HiddenVolumeProtectionTriggered)
2629: break;
2630:
1.1.1.12 root 2631: ListDevice = nextDevice;
2632: continue;
1.1.1.4 root 2633: }
1.1.1.8 root 2634:
1.1.1.10 root 2635: ListDevice = ListDevice->NextDevice;
1.1.1.4 root 2636: }
2637:
1.1.1.5 root 2638: DriverMutexRelease ();
1.1.1.4 root 2639: return status;
2640: }
2641:
2642: // Resolves symbolic link name to its target name
1.1.1.17! root 2643: NTSTATUS SymbolicLinkToTarget (PWSTR symlinkName, PWSTR targetName, USHORT maxTargetNameLength)
1.1.1.4 root 2644: {
2645: NTSTATUS ntStatus;
2646: OBJECT_ATTRIBUTES objectAttributes;
2647: UNICODE_STRING fullFileName;
2648: HANDLE handle;
2649:
2650: RtlInitUnicodeString (&fullFileName, symlinkName);
1.1.1.15 root 2651: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
1.1.1.4 root 2652:
2653: ntStatus = ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes);
2654:
2655: if (NT_SUCCESS (ntStatus))
2656: {
2657: UNICODE_STRING target;
2658: target.Buffer = targetName;
2659: target.Length = 0;
2660: target.MaximumLength = maxTargetNameLength;
2661: memset (targetName, 0, maxTargetNameLength);
2662:
2663: ntStatus = ZwQuerySymbolicLinkObject (handle, &target, NULL);
2664:
2665: ZwClose (handle);
2666: }
2667:
2668: return ntStatus;
2669: }
1.1.1.6 root 2670:
1.1.1.15 root 2671:
1.1.1.6 root 2672: // Checks if two regions overlap (borders are parts of regions)
2673: BOOL RegionsOverlap (unsigned __int64 start1, unsigned __int64 end1, unsigned __int64 start2, unsigned __int64 end2)
2674: {
2675: return (start1 < start2) ? (end1 >= start2) : (start1 <= end2);
2676: }
1.1.1.12 root 2677:
2678:
2679: void GetIntersection (uint64 start1, uint32 length1, uint64 start2, uint64 end2, uint64 *intersectStart, uint32 *intersectLength)
2680: {
2681: uint64 end1 = start1 + length1 - 1;
2682: uint64 intersectEnd = (end1 <= end2) ? end1 : end2;
2683:
2684: *intersectStart = (start1 >= start2) ? start1 : start2;
2685: *intersectLength = (uint32) ((*intersectStart > intersectEnd) ? 0 : intersectEnd + 1 - *intersectStart);
2686:
2687: if (*intersectLength == 0)
2688: *intersectStart = start1;
2689: }
2690:
2691:
2692: BOOL IsAccessibleByUser (PUNICODE_STRING objectFileName, BOOL readOnly)
2693: {
2694: OBJECT_ATTRIBUTES fileObjAttributes;
2695: IO_STATUS_BLOCK ioStatusBlock;
2696: HANDLE fileHandle;
2697: NTSTATUS status;
2698:
2699: ASSERT (!IoIsSystemThread (PsGetCurrentThread()));
2700:
2701: InitializeObjectAttributes (&fileObjAttributes, objectFileName, OBJ_CASE_INSENSITIVE | OBJ_FORCE_ACCESS_CHECK, NULL, NULL);
2702:
2703: status = ZwCreateFile (&fileHandle,
2704: readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
2705: &fileObjAttributes,
2706: &ioStatusBlock,
2707: NULL,
2708: FILE_ATTRIBUTE_NORMAL,
2709: FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
2710: FILE_OPEN,
2711: FILE_SYNCHRONOUS_IO_NONALERT,
2712: NULL,
2713: 0);
2714:
2715: if (NT_SUCCESS (status))
2716: {
2717: ZwClose (fileHandle);
2718: return TRUE;
2719: }
2720:
2721: return FALSE;
2722: }
2723:
2724:
1.1.1.14 root 2725: BOOL UserCanAccessDriveDevice ()
2726: {
2727: UNICODE_STRING name;
2728: RtlInitUnicodeString (&name, L"\\Device\\MountPointManager");
2729:
2730: return IsAccessibleByUser (&name, FALSE);
2731: }
2732:
2733:
1.1.1.15 root 2734: BOOL IsDriveLetterAvailable (int nDosDriveNo)
2735: {
2736: OBJECT_ATTRIBUTES objectAttributes;
2737: UNICODE_STRING objectName;
2738: WCHAR link[128];
2739: HANDLE handle;
2740:
2741: TCGetDosNameFromNumber (link, nDosDriveNo);
2742: RtlInitUnicodeString (&objectName, link);
2743: InitializeObjectAttributes (&objectAttributes, &objectName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
2744:
2745: if (NT_SUCCESS (ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes)))
2746: {
2747: ZwClose (handle);
2748: return FALSE;
2749: }
2750:
2751: return TRUE;
2752: }
2753:
2754:
1.1.1.12 root 2755: NTSTATUS TCCompleteIrp (PIRP irp, NTSTATUS status, ULONG_PTR information)
2756: {
2757: irp->IoStatus.Status = status;
2758: irp->IoStatus.Information = information;
2759: IoCompleteRequest (irp, IO_NO_INCREMENT);
2760: return status;
2761: }
2762:
2763:
2764: NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information)
2765: {
2766: irp->IoStatus.Status = status;
2767: irp->IoStatus.Information = information;
2768: IoCompleteRequest (irp, NT_SUCCESS (status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
2769: return status;
2770: }
1.1.1.15 root 2771:
2772:
2773: size_t GetCpuCount ()
2774: {
2775: KAFFINITY activeCpuMap = KeQueryActiveProcessors();
2776: size_t mapSize = sizeof (activeCpuMap) * 8;
2777: size_t cpuCount = 0;
2778:
2779: while (mapSize--)
2780: {
2781: if (activeCpuMap & 1)
2782: ++cpuCount;
2783:
2784: activeCpuMap >>= 1;
2785: }
2786:
2787: if (cpuCount == 0)
2788: return 1;
2789:
2790: return cpuCount;
2791: }
2792:
2793:
2794: void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes)
2795: {
2796: ASSERT ((maxSizeInBytes & 1) == 0);
2797: str[maxSizeInBytes / sizeof (wchar_t) - 1] = 0;
2798: }
2799:
2800:
2801: void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout)
2802: {
2803: LARGE_INTEGER waitInterval;
2804: waitInterval.QuadPart = retryDelay * -10000;
2805:
2806: ASSERT (KeGetCurrentIrql() <= APC_LEVEL);
2807: ASSERT (retryDelay > 0 && retryDelay <= timeout);
2808:
2809: while (TRUE)
2810: {
2811: void *memory = TCalloc (size);
2812: if (memory)
2813: return memory;
2814:
2815: timeout -= retryDelay;
2816: if (timeout <= 0)
2817: break;
2818:
2819: KeDelayExecutionThread (KernelMode, FALSE, &waitInterval);
2820: }
2821:
2822: return NULL;
2823: }
2824:
2825:
2826: NTSTATUS TCReadRegistryKey (PUNICODE_STRING keyPath, wchar_t *keyValueName, PKEY_VALUE_PARTIAL_INFORMATION *keyData)
2827: {
2828: OBJECT_ATTRIBUTES regObjAttribs;
2829: HANDLE regKeyHandle;
2830: NTSTATUS status;
2831: UNICODE_STRING valName;
2832: ULONG size = 0;
2833: ULONG resultSize;
2834:
2835: InitializeObjectAttributes (®ObjAttribs, keyPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
2836: status = ZwOpenKey (®KeyHandle, KEY_READ, ®ObjAttribs);
2837: if (!NT_SUCCESS (status))
2838: return status;
2839:
2840: RtlInitUnicodeString (&valName, keyValueName);
2841: status = ZwQueryValueKey (regKeyHandle, &valName, KeyValuePartialInformation, NULL, 0, &size);
2842:
2843: if (status != STATUS_SUCCESS && status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL)
2844: {
2845: ZwClose (regKeyHandle);
2846: return status;
2847: }
2848:
2849: if (size == 0)
2850: {
2851: ZwClose (regKeyHandle);
2852: return STATUS_NO_DATA_DETECTED;
2853: }
2854:
2855: *keyData = (PKEY_VALUE_PARTIAL_INFORMATION) TCalloc (size);
2856: if (!*keyData)
2857: {
2858: ZwClose (regKeyHandle);
2859: return STATUS_INSUFFICIENT_RESOURCES;
2860: }
2861:
2862: status = ZwQueryValueKey (regKeyHandle, &valName, KeyValuePartialInformation, *keyData, size, &resultSize);
2863:
2864: ZwClose (regKeyHandle);
2865: return status;
2866: }
2867:
2868:
2869: NTSTATUS TCWriteRegistryKey (PUNICODE_STRING keyPath, wchar_t *keyValueName, ULONG keyValueType, void *valueData, ULONG valueSize)
2870: {
2871: OBJECT_ATTRIBUTES regObjAttribs;
2872: HANDLE regKeyHandle;
2873: NTSTATUS status;
2874: UNICODE_STRING valName;
2875:
2876: InitializeObjectAttributes (®ObjAttribs, keyPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
2877: status = ZwOpenKey (®KeyHandle, KEY_READ | KEY_WRITE, ®ObjAttribs);
2878: if (!NT_SUCCESS (status))
2879: return status;
2880:
2881: RtlInitUnicodeString (&valName, keyValueName);
2882:
2883: status = ZwSetValueKey (regKeyHandle, &valName, keyValueType, keyValueType, valueData, valueSize);
2884:
2885: ZwClose (regKeyHandle);
2886: return status;
2887: }
2888:
2889:
2890: BOOL IsVolumeClassFilterRegistered ()
2891: {
2892: UNICODE_STRING name;
2893: NTSTATUS status;
2894: BOOL registered = FALSE;
2895:
2896: PKEY_VALUE_PARTIAL_INFORMATION data;
2897:
2898: RtlInitUnicodeString (&name, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{71A27CDD-812A-11D0-BEC7-08002BE2092F}");
2899: status = TCReadRegistryKey (&name, L"UpperFilters", &data);
2900:
2901: if (NT_SUCCESS (status))
2902: {
2903: if (data->Type == REG_MULTI_SZ && data->DataLength >= 9 * sizeof (wchar_t))
2904: {
2905: // Search for the string "truecrypt"
2906: ULONG i;
2907: for (i = 0; i <= data->DataLength - 9 * sizeof (wchar_t); ++i)
2908: {
2909: if (memcmp (data->Data + i, L"truecrypt", 9 * sizeof (wchar_t)) == 0)
2910: {
2911: Dump ("Volume class filter active\n");
2912: registered = TRUE;
2913: break;
2914: }
2915: }
2916: }
2917:
2918: TCfree (data);
2919: }
2920:
2921: return registered;
2922: }
2923:
2924:
2925: uint32 ReadRegistryConfigFlags ()
2926: {
2927: PKEY_VALUE_PARTIAL_INFORMATION data;
2928: UNICODE_STRING name;
2929: NTSTATUS status;
2930: uint32 flags = 0;
2931:
2932: RtlInitUnicodeString (&name, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\truecrypt");
2933: status = TCReadRegistryKey (&name, TC_DRIVER_CONFIG_REG_VALUE_NAME, &data);
2934:
2935: if (NT_SUCCESS (status))
2936: {
2937: if (data->Type == REG_DWORD)
2938: {
2939: flags = *(uint32 *) data->Data;
2940: Dump ("Configuration flags = 0x%x\n", flags);
1.1.1.17! root 2941:
! 2942: if (flags & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD)
! 2943: CacheBootPassword = TRUE;
1.1.1.15 root 2944: }
2945:
2946: TCfree (data);
2947: }
2948:
2949: return flags;
2950: }
2951:
2952:
2953: NTSTATUS WriteRegistryConfigFlags (uint32 flags)
2954: {
2955: UNICODE_STRING name;
2956: RtlInitUnicodeString (&name, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\truecrypt");
2957:
2958: return TCWriteRegistryKey (&name, TC_DRIVER_CONFIG_REG_VALUE_NAME, REG_DWORD, &flags, sizeof (flags));
2959: }
1.1.1.17! root 2960:
! 2961:
! 2962: NTSTATUS GetDeviceSectorSize (PDEVICE_OBJECT deviceObject, ULONG *bytesPerSector)
! 2963: {
! 2964: NTSTATUS status;
! 2965: DISK_GEOMETRY geometry;
! 2966:
! 2967: status = SendDeviceIoControlRequest (deviceObject, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof (geometry));
! 2968:
! 2969: if (!NT_SUCCESS (status))
! 2970: return status;
! 2971:
! 2972: *bytesPerSector = geometry.BytesPerSector;
! 2973: return STATUS_SUCCESS;
! 2974: }
! 2975:
! 2976:
! 2977: NTSTATUS ZeroUnreadableSectors (PDEVICE_OBJECT deviceObject, LARGE_INTEGER startOffset, ULONG size, uint64 *zeroedSectorCount)
! 2978: {
! 2979: NTSTATUS status;
! 2980: ULONG sectorSize;
! 2981: ULONG sectorCount;
! 2982: byte *sectorBuffer = NULL;
! 2983:
! 2984: *zeroedSectorCount = 0;
! 2985:
! 2986: status = GetDeviceSectorSize (deviceObject, §orSize);
! 2987: if (!NT_SUCCESS (status))
! 2988: return status;
! 2989:
! 2990: sectorBuffer = TCalloc (sectorSize);
! 2991: if (!sectorBuffer)
! 2992: return STATUS_INSUFFICIENT_RESOURCES;
! 2993:
! 2994: for (sectorCount = size / sectorSize; sectorCount > 0; --sectorCount, startOffset.QuadPart += sectorSize)
! 2995: {
! 2996: status = TCReadDevice (deviceObject, sectorBuffer, startOffset, sectorSize);
! 2997: if (!NT_SUCCESS (status))
! 2998: {
! 2999: Dump ("Zeroing sector at %I64d\n", startOffset.QuadPart);
! 3000: memset (sectorBuffer, 0, sectorSize);
! 3001:
! 3002: status = TCWriteDevice (deviceObject, sectorBuffer, startOffset, sectorSize);
! 3003: if (!NT_SUCCESS (status))
! 3004: goto err;
! 3005:
! 3006: ++(*zeroedSectorCount);
! 3007: }
! 3008: }
! 3009:
! 3010: status = STATUS_SUCCESS;
! 3011:
! 3012: err:
! 3013: if (sectorBuffer)
! 3014: TCfree (sectorBuffer);
! 3015:
! 3016: return status;
! 3017: }
! 3018:
! 3019:
! 3020: BOOL IsVolumeAccessibleByCurrentUser (PEXTENSION volumeDeviceExtension)
! 3021: {
! 3022: SECURITY_SUBJECT_CONTEXT subContext;
! 3023: PACCESS_TOKEN accessToken;
! 3024: PTOKEN_USER tokenUser;
! 3025: BOOL result = FALSE;
! 3026:
! 3027: if (IoIsSystemThread (PsGetCurrentThread()) || UserCanAccessDriveDevice() || !volumeDeviceExtension->UserSid)
! 3028: return TRUE;
! 3029:
! 3030: SeCaptureSubjectContext (&subContext);
! 3031: accessToken = SeQuerySubjectContextToken (&subContext);
! 3032:
! 3033: if (!accessToken)
! 3034: goto ret;
! 3035:
! 3036: if (SeTokenIsAdmin (accessToken))
! 3037: {
! 3038: result = TRUE;
! 3039: goto ret;
! 3040: }
! 3041:
! 3042: if (!NT_SUCCESS (SeQueryInformationToken (accessToken, TokenUser, &tokenUser)))
! 3043: goto ret;
! 3044:
! 3045: result = RtlEqualSid (volumeDeviceExtension->UserSid, tokenUser->User.Sid);
! 3046:
! 3047: ret:
! 3048: SeReleaseSubjectContext (&subContext);
! 3049: return result;
! 3050: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.