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