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