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