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