|
|
1.1.1.10 root 1: /*
1.1.1.12 root 2: Legal Notice: Some portions of the source code contained in this file were
3: derived from the source code of Encryption for the Masses 2.02a, which is
4: Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
5: Agreement for Encryption for the Masses'. Modifications and additions to
6: the original source code (contained in this file) and all other portions of
7: this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
8: by the TrueCrypt License 2.4 the full text of which is contained in the
9: file License.txt included in TrueCrypt binary and source code distribution
1.1.1.10 root 10: packages. */
1.1 root 11:
12: #include "TCdefs.h"
1.1.1.12 root 13: #include <ntddk.h>
1.1.1.6 root 14: #include "Crypto.h"
15: #include "Fat.h"
16: #include "Tests.h"
17:
18: #include "Apidrvr.h"
1.1.1.12 root 19: #include "EncryptedIoQueue.h"
1.1.1.6 root 20: #include "Ntdriver.h"
21: #include "Ntvol.h"
1.1.1.12 root 22: #include "DriveFilter.h"
1.1.1.6 root 23: #include "Cache.h"
1.1 root 24:
25: #include <tchar.h>
26: #include <initguid.h>
27: #include <mountmgr.h>
28: #include <mountdev.h>
29: #include <ntddvol.h>
30:
31: /* Init section, which is thrown away as soon as DriverEntry returns */
32: #pragma alloc_text(INIT,DriverEntry)
33: #pragma alloc_text(INIT,TCCreateRootDeviceObject)
34:
1.1.1.14! root 35: PDRIVER_OBJECT TCDriverObject;
1.1.1.6 root 36: KMUTEX driverMutex; /* Sync mutex for the entire driver */
1.1.1.12 root 37: BOOL DriverShuttingDown = FALSE;
1.1.1.6 root 38: BOOL SelfTestsPassed;
39: int LastUniqueVolumeId;
1.1.1.10 root 40: ULONG OsMajorVersion;
1.1.1.14! root 41: ULONG OsMinorVersion;
1.1.1.11 root 42: BOOL ReferencedDeviceDeleted = FALSE;
1.1.1.14! root 43: BOOL TravelerMode = FALSE;
1.1 root 44:
1.1.1.12 root 45:
46: NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
1.1 root 47: {
1.1.1.12 root 48: OBJECT_ATTRIBUTES regObjAttribs;
49: HANDLE regKeyHandle;
50: int i;
51:
1.1.1.14! root 52: TCDriverObject = DriverObject;
1.1.1.12 root 53: SelfTestsPassed = AutoTestAlgorithms ();
1.1.1.14! root 54: PsGetVersion (&OsMajorVersion, &OsMinorVersion, NULL, NULL);
1.1.1.12 root 55:
1.1.1.14! root 56: // Enable drive class filter and load boot arguments if the driver is set to start at system boot
1.1.1.12 root 57:
58: InitializeObjectAttributes (®ObjAttribs, RegistryPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
59: if (ZwOpenKey (®KeyHandle, KEY_READ, ®ObjAttribs) == STATUS_SUCCESS)
60: {
61: UNICODE_STRING valName;
62: ULONG size = 0;
63:
64: RtlInitUnicodeString (&valName, L"Start");
65: if (ZwQueryValueKey (regKeyHandle, &valName, KeyValuePartialInformation, NULL, 0, &size) != STATUS_OBJECT_NAME_NOT_FOUND && size > 0)
66: {
67: PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION) TCalloc (size);
68: if (!pInfo)
69: {
70: ZwClose (regKeyHandle);
71: return STATUS_INSUFFICIENT_RESOURCES;
72: }
73:
74: if (ZwQueryValueKey (regKeyHandle, &valName, KeyValuePartialInformation, pInfo, size, &size) == STATUS_SUCCESS)
75: {
76: if (pInfo->Type == REG_DWORD && *((uint32 *) pInfo->Data) == SERVICE_BOOT_START)
77: {
78: if (!SelfTestsPassed)
79: TC_BUG_CHECK (STATUS_INVALID_PARAMETER);
80:
81: LoadBootArguments();
82: DriverObject->DriverExtension->AddDevice = DriveFilterAddDevice;
83: }
84: }
1.1 root 85:
1.1.1.12 root 86: TCfree (pInfo);
87: }
88:
89: ZwClose (regKeyHandle);
90: }
91:
92: for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
93: {
94: DriverObject->MajorFunction[i] = TCDispatchQueueIRP;
95: }
1.1 root 96:
97: DriverObject->DriverUnload = TCUnloadDriver;
98: KeInitializeMutex (&driverMutex, 1);
99:
100: return TCCreateRootDeviceObject (DriverObject);
101: }
102:
1.1.1.12 root 103:
1.1 root 104: // Dumps a memory region to debug output
1.1.1.12 root 105: void DumpMemory (void *mem, int size)
1.1 root 106: {
107: unsigned char str[20];
108: unsigned char *m = mem;
109: int i,j;
110:
1.1.1.12 root 111: for (j = 0; j < size / 8; j++)
1.1 root 112: {
113: memset (str,0,sizeof str);
1.1.1.12 root 114: for (i = 0; i < 8; i++)
1.1 root 115: {
1.1.1.12 root 116: if (m[i] > ' ' && m[i] <= '~')
1.1 root 117: str[i]=m[i];
118: else
119: str[i]='.';
120: }
121:
1.1.1.12 root 122: Dump ("0x%08p %02x %02x %02x %02x %02x %02x %02x %02x %s\n",
1.1 root 123: m, m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], str);
124:
125: m+=8;
126: }
127: }
1.1.1.12 root 128:
1.1 root 129:
130: /* TCDispatchQueueIRP queues any IRP's so that they can be processed later
131: by the thread -- or in some cases handles them immediately! */
132: NTSTATUS
133: TCDispatchQueueIRP (PDEVICE_OBJECT DeviceObject, PIRP Irp)
134: {
135: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
136: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
137: NTSTATUS ntStatus;
138:
139: #ifdef _DEBUG
1.1.1.12 root 140: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
141: {
142: switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
143: {
144: case TC_IOCTL_GET_MOUNTED_VOLUMES:
145: case TC_IOCTL_GET_PASSWORD_CACHE_STATUS:
1.1.1.14! root 146: case TC_IOCTL_GET_TRAVELER_MODE_STATUS:
! 147: case TC_IOCTL_SET_TRAVELER_MODE_STATUS:
1.1.1.12 root 148: case TC_IOCTL_OPEN_TEST:
149: case TC_IOCTL_GET_RESOLVED_SYMLINK:
150: case TC_IOCTL_GET_DRIVE_PARTITION_INFO:
151: case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
152: case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
153: break;
154:
155: default:
156: Dump ("%ls (%d 0x%x)\n",
157: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode),
158: (int) (irpSp->Parameters.DeviceIoControl.IoControlCode >> 16),
159: (int) ((irpSp->Parameters.DeviceIoControl.IoControlCode & 0x1FFF) >> 2));
160: }
1.1.1.10 root 161: }
162: #ifdef EXTRA_INFO
163: else
164: Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x\n",
165: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction);
166: #endif
1.1 root 167: #endif
168:
1.1.1.12 root 169: // Drive filter IRP
170: if (!Extension->bRootDevice && Extension->IsDriveFilterDevice)
171: return DriveFilterDispatchIrp (DeviceObject, Irp);
172:
1.1.1.10 root 173: if (!Extension->bRootDevice && Extension->bShuttingDown
174: && (irpSp->MajorFunction == IRP_MJ_READ
175: || irpSp->MajorFunction == IRP_MJ_WRITE
176: || irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL
177: || irpSp->MajorFunction == IRP_MJ_FLUSH_BUFFERS))
1.1 root 178: {
1.1.1.12 root 179: // Reject IRP if volume is being dismounted
1.1.1.11 root 180: Dump ("Device %d shutting down: STATUS_DEVICE_NOT_READY\n", Extension->nDosDriveNo);
1.1.1.12 root 181:
1.1.1.11 root 182: Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
1.1.1.10 root 183: Irp->IoStatus.Information = 0;
1.1 root 184:
1.1.1.10 root 185: ntStatus = Irp->IoStatus.Status;
186: IoCompleteRequest (Irp, IO_NO_INCREMENT);
187:
188: return ntStatus;
1.1 root 189: }
190:
191: switch (irpSp->MajorFunction)
192: {
193: case IRP_MJ_CLOSE:
194: case IRP_MJ_CREATE:
195: case IRP_MJ_CLEANUP:
196: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
197:
198: case IRP_MJ_SHUTDOWN:
1.1.1.6 root 199: if (Extension->bRootDevice)
1.1.1.12 root 200: {
201: DriverShuttingDown = TRUE;
202:
203: if (IsBootEncryptionSetupInProgress())
204: AbortBootEncryptionSetup();
205:
206: UnmountAllDevices (DeviceObject, TRUE);
207:
208: // Boot drive can be safely dismounted only when IRP_MJ_POWER is received after IRP_MJ_SHUTDOWN
209: }
1.1.1.4 root 210:
211: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
212:
1.1 root 213: case IRP_MJ_FLUSH_BUFFERS:
214: case IRP_MJ_READ:
215: case IRP_MJ_WRITE:
216: case IRP_MJ_DEVICE_CONTROL:
217: if (Extension->bRootDevice == FALSE)
218: {
219: IoMarkIrpPending (Irp);
220:
221: ExInterlockedInsertTailList (
222: &Extension->ListEntry,
223: &Irp->Tail.Overlay.ListEntry,
224: &Extension->ListSpinLock);
225:
226: KeReleaseSemaphore (
227: &Extension->RequestSemaphore,
228: (KPRIORITY) 0,
229: 1,
230: FALSE);
231:
232: return STATUS_PENDING;
233: }
234: else
235: {
1.1.1.12 root 236: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
237: return ProcessMainDeviceControlIrp (DeviceObject, Extension, Irp);
1.1 root 238: }
239:
1.1.1.12 root 240: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
1.1 root 241: }
242:
243: #ifdef _DEBUG
244: Dump ("ERROR: Unknown irpSp->MajorFunction in TCDispatchQueueIRP %ls 0x%08x END\n",
245: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction);
246: #endif
247:
1.1.1.12 root 248: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
1.1 root 249: }
250:
251: NTSTATUS
252: TCCreateRootDeviceObject (PDRIVER_OBJECT DriverObject)
253: {
254: UNICODE_STRING Win32NameString, ntUnicodeString;
255: WCHAR dosname[32], ntname[32];
256: PDEVICE_OBJECT DeviceObject;
257: NTSTATUS ntStatus;
258: BOOL *bRootExtension;
259:
260: Dump ("TCCreateRootDeviceObject BEGIN\n");
261:
262: wcscpy (dosname, (LPWSTR) DOS_ROOT_PREFIX);
263: wcscpy (ntname, (LPWSTR) NT_ROOT_PREFIX);
264: RtlInitUnicodeString (&ntUnicodeString, ntname);
265: RtlInitUnicodeString (&Win32NameString, dosname);
266:
267: Dump ("Creating root device nt=%ls dos=%ls\n", ntname, dosname);
1.1.1.3 root 268:
1.1 root 269: ntStatus = IoCreateDevice (
270: DriverObject, /* Our Driver Object */
271: sizeof (BOOL), /* Size of state information */
272: &ntUnicodeString, /* Device name "\Device\Name" */
1.1.1.3 root 273: FILE_DEVICE_UNKNOWN, /* Device type */
1.1 root 274: 0, /* Device characteristics */
275: FALSE, /* Exclusive device */
276: &DeviceObject); /* Returned ptr to Device Object */
277:
278: if (!NT_SUCCESS (ntStatus))
279: {
280: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
281: return ntStatus;/* Failed to create DeviceObject */
282: }
283:
284: DeviceObject->Flags |= DO_DIRECT_IO;
285: DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
286:
287: /* Setup the device extension */
288: bRootExtension = (BOOL *) DeviceObject->DeviceExtension;
289: *bRootExtension = TRUE;
290:
291: /* The symlinks for mount devices are created from user-mode */
292: ntStatus = IoCreateSymbolicLink (&Win32NameString, &ntUnicodeString);
1.1.1.4 root 293:
1.1 root 294: if (!NT_SUCCESS (ntStatus))
295: {
296: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
297: IoDeleteDevice (DeviceObject);
298: return ntStatus;
299: }
300:
1.1.1.4 root 301: IoRegisterShutdownNotification (DeviceObject);
302:
1.1 root 303: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
304: Dump ("TCCreateRootDeviceObject STATUS_SUCCESS END\n");
305: return STATUS_SUCCESS;
306: }
307:
308: NTSTATUS
309: TCCreateDeviceObject (PDRIVER_OBJECT DriverObject,
310: PDEVICE_OBJECT * ppDeviceObject,
1.1.1.4 root 311: MOUNT_STRUCT * mount)
1.1 root 312: {
313: UNICODE_STRING Win32NameString, ntUnicodeString;
314: WCHAR dosname[32], ntname[32];
315: PEXTENSION Extension;
316: NTSTATUS ntStatus;
1.1.1.4 root 317: ULONG devChars = 0;
1.1 root 318:
319: Dump ("TCCreateDeviceObject BEGIN\n");
320:
1.1.1.4 root 321: TCGetDosNameFromNumber (dosname, mount->nDosDriveNo);
322: TCGetNTNameFromNumber (ntname, mount->nDosDriveNo);
1.1 root 323: RtlInitUnicodeString (&ntUnicodeString, ntname);
324: RtlInitUnicodeString (&Win32NameString, dosname);
325:
1.1.1.4 root 326: devChars = mount->bMountReadOnly ? FILE_READ_ONLY_DEVICE : 0;
327: devChars |= mount->bMountRemovable ? FILE_REMOVABLE_MEDIA : 0;
328:
1.1 root 329: Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname);
330:
331: ntStatus = IoCreateDevice (
332: DriverObject, /* Our Driver Object */
333: sizeof (EXTENSION), /* Size of state information */
334: &ntUnicodeString, /* Device name "\Device\Name" */
335: FILE_DEVICE_DISK, /* Device type */
1.1.1.4 root 336: devChars, /* Device characteristics */
1.1 root 337: FALSE, /* Exclusive device */
338: ppDeviceObject); /* Returned ptr to Device Object */
339:
340: if (!NT_SUCCESS (ntStatus))
341: {
342: Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
343: return ntStatus;/* Failed to create DeviceObject */
344: }
345: /* Initialize device object and extension. */
346:
347: (*ppDeviceObject)->Flags |= DO_DIRECT_IO;
348: (*ppDeviceObject)->AlignmentRequirement = FILE_WORD_ALIGNMENT;
349:
350: /* Setup the device extension */
351: Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension;
352: memset (Extension, 0, sizeof (EXTENSION));
353:
354: Extension->lMagicNumber = 0xabfeacde;
1.1.1.4 root 355: Extension->nDosDriveNo = mount->nDosDriveNo;
356: Extension->bRemovable = mount->bMountRemovable;
1.1 root 357:
358: KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE);
359: KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG);
360: KeInitializeSpinLock (&Extension->ListSpinLock);
361: InitializeListHead (&Extension->ListEntry);
362:
363: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
364: Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n");
365:
366: return STATUS_SUCCESS;
367: }
368:
1.1.1.5 root 369:
370: void DriverMutexWait ()
371: {
372: KeWaitForMutexObject (&driverMutex, Executive, KernelMode, FALSE, NULL);
373: }
374:
375:
376: void DriverMutexRelease ()
377: {
378: KeReleaseMutex (&driverMutex, FALSE);
379: }
380:
381:
1.1.1.12 root 382: NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
1.1 root 383: {
384: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
385:
386: switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
387: {
388:
389: case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
390: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_NAME))
391: {
392: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
393: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
394: }
395: else
396: {
397: ULONG outLength;
398: UNICODE_STRING ntUnicodeString;
1.1.1.7 root 399: WCHAR ntName[256];
1.1 root 400: PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer;
401:
402: TCGetNTNameFromNumber (ntName, Extension->nDosDriveNo);
403: RtlInitUnicodeString (&ntUnicodeString, ntName);
404:
405: outputBuffer->NameLength = ntUnicodeString.Length;
406: outLength = ntUnicodeString.Length + sizeof(USHORT);
407:
408: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
409: {
410: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
411: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
412:
413: break;
414: }
415:
416: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
417:
418: Irp->IoStatus.Status = STATUS_SUCCESS;
419: Irp->IoStatus.Information = outLength;
420:
421: Dump ("name = %ls\n",ntName);
422: }
423: break;
424:
425: case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
426: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_UNIQUE_ID))
427: {
428: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
429: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
430: }
431: else
432: {
433: ULONG outLength;
434: UCHAR volId[128], tmp[] = { 0,0 };
435: PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer;
436:
437: strcpy (volId, TC_UNIQUE_ID_PREFIX);
438: tmp[0] = 'A' + Extension->nDosDriveNo;
439: strcat (volId, tmp);
440:
1.1.1.6 root 441: outputBuffer->UniqueIdLength = (USHORT) strlen (volId);
442: outLength = strlen (volId) + sizeof(USHORT);
1.1 root 443:
444: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
445: {
446: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
447: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
448: break;
449: }
450:
1.1.1.6 root 451: RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen (volId));
1.1 root 452:
453: Irp->IoStatus.Status = STATUS_SUCCESS;
454: Irp->IoStatus.Information = outLength;
455:
456: Dump ("id = %s\n",volId);
457: }
458: break;
459:
1.1.1.14! root 460: case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
1.1 root 461: {
462: ULONG outLength;
463: UNICODE_STRING ntUnicodeString;
1.1.1.7 root 464: WCHAR ntName[256];
1.1 root 465: PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer;
1.1.1.14! root 466:
! 467: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_SUGGESTED_LINK_NAME))
! 468: {
! 469: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
! 470: Irp->IoStatus.Information = 0;
! 471: break;
! 472: }
! 473:
1.1 root 474: TCGetDosNameFromNumber (ntName, Extension->nDosDriveNo);
475: RtlInitUnicodeString (&ntUnicodeString, ntName);
476:
477: outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length;
478:
1.1.1.14! root 479: outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE;
! 480: outputBuffer->NameLength = ntUnicodeString.Length;
! 481:
1.1 root 482: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
483: {
484: Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME);
485: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
486: break;
487: }
488:
489: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
490:
491: Irp->IoStatus.Status = STATUS_SUCCESS;
492: Irp->IoStatus.Information = outLength;
493:
494: Dump ("link = %ls\n",ntName);
495: }
496: break;
497:
1.1.1.4 root 498:
1.1 root 499: case IOCTL_DISK_GET_MEDIA_TYPES:
500: case IOCTL_DISK_GET_DRIVE_GEOMETRY:
501: /* Return the drive geometry for the disk. Note that we
502: return values which were made up to suit the disk size. */
503: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
504: sizeof (DISK_GEOMETRY))
505: {
1.1.1.11 root 506: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 507: Irp->IoStatus.Information = 0;
508: }
509: else
510: {
511: PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY)
512: Irp->AssociatedIrp.SystemBuffer;
513:
1.1.1.4 root 514: outputBuffer->MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia;
1.1 root 515: outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders;
516: outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder;
517: outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack;
518: outputBuffer->BytesPerSector = Extension->BytesPerSector;
519: Irp->IoStatus.Status = STATUS_SUCCESS;
520: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY);
521: }
522: break;
523:
524: case IOCTL_DISK_GET_PARTITION_INFO:
525: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
526: sizeof (PARTITION_INFORMATION))
527: {
1.1.1.11 root 528: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 529: Irp->IoStatus.Information = 0;
530: }
531: else
532: {
533: PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION)
534: Irp->AssociatedIrp.SystemBuffer;
535:
536: outputBuffer->PartitionType = Extension->PartitionType;
537: outputBuffer->BootIndicator = FALSE;
538: outputBuffer->RecognizedPartition = TRUE;
539: outputBuffer->RewritePartition = FALSE;
1.1.1.11 root 540: outputBuffer->StartingOffset.QuadPart = SECTOR_SIZE;
1.1 root 541: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength;
1.1.1.11 root 542: outputBuffer->HiddenSectors = 0;
1.1 root 543: Irp->IoStatus.Status = STATUS_SUCCESS;
544: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION);
545: }
546: break;
1.1.1.10 root 547:
548: case IOCTL_DISK_GET_PARTITION_INFO_EX:
549: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (PARTITION_INFORMATION_EX))
550: {
1.1.1.11 root 551: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.10 root 552: Irp->IoStatus.Information = 0;
553: }
554: else
555: {
556: PPARTITION_INFORMATION_EX outputBuffer = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer;
557:
558: outputBuffer->PartitionStyle = PARTITION_STYLE_MBR;
559: outputBuffer->RewritePartition = FALSE;
1.1.1.11 root 560: outputBuffer->StartingOffset.QuadPart = SECTOR_SIZE;
1.1.1.10 root 561: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength;
562: outputBuffer->Mbr.PartitionType = Extension->PartitionType;
563: outputBuffer->Mbr.BootIndicator = FALSE;
564: outputBuffer->Mbr.RecognizedPartition = TRUE;
1.1.1.11 root 565: outputBuffer->Mbr.HiddenSectors = 0;
1.1.1.10 root 566: Irp->IoStatus.Status = STATUS_SUCCESS;
567: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION_EX);
568: }
569: break;
570:
1.1.1.6 root 571: case IOCTL_DISK_GET_DRIVE_LAYOUT:
572: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
573: sizeof (DRIVE_LAYOUT_INFORMATION))
574: {
1.1.1.11 root 575: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.6 root 576: Irp->IoStatus.Information = 0;
577: }
578: else
579: {
580: PDRIVE_LAYOUT_INFORMATION outputBuffer = (PDRIVE_LAYOUT_INFORMATION)
581: Irp->AssociatedIrp.SystemBuffer;
582:
583: outputBuffer->PartitionCount = 1;
584: outputBuffer->Signature = 0;
585:
586: outputBuffer->PartitionEntry->PartitionType = Extension->PartitionType;
587: outputBuffer->PartitionEntry->BootIndicator = FALSE;
588: outputBuffer->PartitionEntry->RecognizedPartition = TRUE;
589: outputBuffer->PartitionEntry->RewritePartition = FALSE;
1.1.1.11 root 590: outputBuffer->PartitionEntry->StartingOffset.QuadPart = SECTOR_SIZE;
591: outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength;
592: outputBuffer->PartitionEntry->HiddenSectors = 0;
1.1.1.6 root 593:
594: Irp->IoStatus.Status = STATUS_SUCCESS;
595: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION);
596: }
597: break;
598:
1.1 root 599: case IOCTL_DISK_GET_LENGTH_INFO:
600: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GET_LENGTH_INFORMATION))
601: {
602: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
603: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
604: }
605: else
606: {
607: PGET_LENGTH_INFORMATION outputBuffer = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
608:
609: outputBuffer->Length.QuadPart = Extension->DiskLength;
610: Irp->IoStatus.Status = STATUS_SUCCESS;
611: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
612: }
613: break;
614:
615: case IOCTL_DISK_VERIFY:
1.1.1.13 root 616: if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof (PVERIFY_INFORMATION))
617: {
618: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
619: Irp->IoStatus.Information = 0;
620: }
621: else
1.1 root 622: {
623: PVERIFY_INFORMATION pVerifyInformation;
624: pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
625: irpSp->Parameters.Read.ByteOffset.LowPart =
626: pVerifyInformation->StartingOffset.LowPart;
627: irpSp->Parameters.Read.ByteOffset.HighPart =
628: pVerifyInformation->StartingOffset.HighPart;
629: irpSp->Parameters.Read.Length = pVerifyInformation->Length;
630: Irp->IoStatus.Status = STATUS_SUCCESS;
1.1.1.13 root 631: Irp->IoStatus.Information = 0;
1.1 root 632: }
633: break;
634:
635: case IOCTL_DISK_CHECK_VERIFY:
1.1.1.6 root 636: case IOCTL_STORAGE_CHECK_VERIFY:
1.1 root 637: {
638: Irp->IoStatus.Status = STATUS_SUCCESS;
639: Irp->IoStatus.Information = 0;
640: }
641: break;
642:
643: case IOCTL_DISK_IS_WRITABLE:
644: {
1.1.1.6 root 645: if (Extension->bReadOnly)
1.1 root 646: Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
647: else
648: Irp->IoStatus.Status = STATUS_SUCCESS;
649: Irp->IoStatus.Information = 0;
650:
651: }
652: break;
653:
1.1.1.12 root 654: default:
655: return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
656: }
657:
658: #ifdef DEBUG
659: if (!NT_SUCCESS (Irp->IoStatus.Status))
660: Dump ("IOCTL error 0x%08x\n", Irp->IoStatus.Status);
661: #endif
662:
663: return TCCompleteDiskIrp (Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
664: }
665:
1.1.1.5 root 666:
1.1.1.12 root 667: NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
668: {
669: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
670: NTSTATUS ntStatus;
671:
672: switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
673: {
674: case TC_IOCTL_GET_DRIVER_VERSION:
675: case TC_IOCTL_LEGACY_GET_DRIVER_VERSION:
1.1.1.6 root 676: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (LONG))
1.1 root 677: {
1.1.1.11 root 678: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 679: Irp->IoStatus.Information = 0;
680: }
681: else
682: {
683: LONG tmp = VERSION_NUM;
684: memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4);
1.1.1.6 root 685: Irp->IoStatus.Information = sizeof (LONG);
1.1 root 686: Irp->IoStatus.Status = STATUS_SUCCESS;
687: }
688: break;
689:
1.1.1.12 root 690: case TC_IOCTL_GET_DEVICE_REFCOUNT:
1.1.1.6 root 691: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
1.1 root 692: {
1.1.1.11 root 693: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 694: Irp->IoStatus.Information = 0;
695: }
696: else
697: {
1.1.1.6 root 698: *(int *) Irp->AssociatedIrp.SystemBuffer = DeviceObject->ReferenceCount;
699: Irp->IoStatus.Information = sizeof (int);
700: Irp->IoStatus.Status = STATUS_SUCCESS;
701: }
702: break;
703:
1.1.1.12 root 704: case TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED:
1.1.1.11 root 705: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
706: {
707: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
708: Irp->IoStatus.Information = 0;
709: }
710: else
711: {
712: *(int *) Irp->AssociatedIrp.SystemBuffer = ReferencedDeviceDeleted;
713: Irp->IoStatus.Information = sizeof (int);
714: Irp->IoStatus.Status = STATUS_SUCCESS;
715: }
716: break;
717:
1.1.1.12 root 718: case TC_IOCTL_IS_ANY_VOLUME_MOUNTED:
719: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
720: {
721: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
722: Irp->IoStatus.Information = 0;
723: }
724: else
725: {
726: PDEVICE_OBJECT ListDevice;
727: *(int *) Irp->AssociatedIrp.SystemBuffer = 0;
728:
729: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
730: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
731: {
732: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
733: if (!ListExtension->bRootDevice
734: && !ListExtension->IsDriveFilterDevice
735: && ListExtension->lMagicNumber == 0xabfeacde)
736: {
737: *(int *) Irp->AssociatedIrp.SystemBuffer = 1;
738: break;
739: }
740: }
741:
742: if (IsBootDriveMounted())
743: *(int *) Irp->AssociatedIrp.SystemBuffer = 1;
744:
745: Irp->IoStatus.Information = sizeof (int);
746: Irp->IoStatus.Status = STATUS_SUCCESS;
747: }
748: break;
749:
750: case TC_IOCTL_OPEN_TEST:
1.1.1.6 root 751: {
1.1 root 752: OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
753: OBJECT_ATTRIBUTES ObjectAttributes;
754: HANDLE NtFileHandle;
755: UNICODE_STRING FullFileName;
756: IO_STATUS_BLOCK IoStatus;
1.1.1.14! root 757: LARGE_INTEGER offset;
! 758: unsigned char readBuffer [SECTOR_SIZE];
! 759: NTSTATUS TCBootLoaderDetected = STATUS_NO_SUCH_DEVICE; // STATUS_NO_SUCH_DEVICE is sent when the boot loader is not found (even if the device is found)
1.1 root 760:
761: RtlInitUnicodeString (&FullFileName, opentest->wszFileName);
762:
763: InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE,
764: NULL, NULL);
765:
766: ntStatus = ZwCreateFile (&NtFileHandle,
767: SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none */ ,
1.1.1.4 root 768: FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT |
1.1 root 769: FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS,
770: NULL /* eabuffer */ , 0 /* ealength */ );
771:
772: if (NT_SUCCESS (ntStatus))
773: {
1.1.1.14! root 774: if (opentest->bDetectTCBootLoader)
! 775: {
! 776: // Determine if the first sector contains a portion of the TrueCrypt Boot Loader
! 777:
! 778: offset.QuadPart = 0; // MBR
! 779:
! 780: ntStatus = ZwReadFile (NtFileHandle,
! 781: NULL,
! 782: NULL,
! 783: NULL,
! 784: &IoStatus,
! 785: readBuffer,
! 786: sizeof(readBuffer),
! 787: &offset,
! 788: NULL);
! 789:
! 790: if (NT_SUCCESS (ntStatus))
! 791: {
! 792: size_t i;
! 793:
! 794: // Search for the string "TrueCrypt"
! 795: for (i = 0; i < sizeof (readBuffer) - strlen (TC_APP_NAME); ++i)
! 796: {
! 797: if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
! 798: {
! 799: TCBootLoaderDetected = STATUS_SUCCESS;
! 800: break;
! 801: }
! 802: }
! 803: }
! 804: }
! 805:
1.1 root 806: ZwClose (NtFileHandle);
807: Dump ("Open test on file %ls success.\n", opentest->wszFileName);
808: }
809: else
810: {
1.1.1.12 root 811: #if 0
1.1 root 812: Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus);
1.1.1.12 root 813: #endif
1.1 root 814: }
815:
816: Irp->IoStatus.Information = 0;
1.1.1.14! root 817: Irp->IoStatus.Status = opentest->bDetectTCBootLoader ? TCBootLoaderDetected : ntStatus;
1.1 root 818: }
819: break;
820:
1.1.1.12 root 821: case TC_IOCTL_WIPE_PASSWORD_CACHE:
1.1.1.5 root 822: DriverMutexWait ();
1.1 root 823: WipeCache ();
1.1.1.5 root 824: DriverMutexRelease ();
1.1 root 825:
826: Irp->IoStatus.Status = STATUS_SUCCESS;
827: Irp->IoStatus.Information = 0;
828: break;
829:
1.1.1.12 root 830: case TC_IOCTL_GET_PASSWORD_CACHE_STATUS:
1.1 root 831: Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS;
832: Irp->IoStatus.Information = 0;
833: break;
834:
1.1.1.14! root 835: case TC_IOCTL_SET_TRAVELER_MODE_STATUS:
! 836: if (!UserCanAccessDriveDevice())
! 837: {
! 838: Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
! 839: Irp->IoStatus.Information = 0;
! 840: }
! 841: else
! 842: {
! 843: TravelerMode = TRUE;
! 844: Dump ("Setting traveler mode\n");
! 845: }
! 846: break;
! 847:
! 848: case TC_IOCTL_GET_TRAVELER_MODE_STATUS:
! 849: Irp->IoStatus.Status = TravelerMode ? STATUS_SUCCESS : STATUS_PIPE_EMPTY;
! 850: Irp->IoStatus.Information = 0;
! 851: break;
! 852:
1.1.1.12 root 853: case TC_IOCTL_GET_MOUNTED_VOLUMES:
1.1.1.9 root 854: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT)
855: || !DeviceObject || !DeviceObject->DriverObject)
1.1 root 856: {
1.1.1.11 root 857: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 858: Irp->IoStatus.Information = 0;
859: }
860: else
861: {
862: MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
863: PDEVICE_OBJECT ListDevice;
864:
1.1.1.5 root 865: DriverMutexWait ();
866:
1.1 root 867: list->ulMountedDrives = 0;
868: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
869: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
870: {
871: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.12 root 872: if (!ListExtension->bRootDevice
873: && !ListExtension->IsDriveFilterDevice
874: && !ListExtension->bShuttingDown
875: && ListExtension->lMagicNumber == 0xabfeacde)
1.1 root 876: {
877: list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo);
878: wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume);
879: list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength;
1.1.1.4 root 880: list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea;
1.1.1.6 root 881: if (ListExtension->cryptoInfo->hiddenVolume)
882: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_HIDDEN; // Hidden volume
883: else if (ListExtension->cryptoInfo->bHiddenVolProtectionAction)
884: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED; // Normal/outer volume (hidden volume protected AND write already prevented)
885: else if (ListExtension->cryptoInfo->bProtectHiddenVolume)
886: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER; // Normal/outer volume (hidden volume protected)
887: else
888: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_NORMAL; // Normal volume
1.1 root 889: }
890: }
891:
1.1.1.5 root 892: DriverMutexRelease ();
893:
1.1 root 894: Irp->IoStatus.Status = STATUS_SUCCESS;
895: Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT);
896: }
897: break;
898:
1.1.1.12 root 899: case TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES:
900: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (uint32))
901: {
902: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
903: Irp->IoStatus.Information = 0;
904: }
905: else
906: {
907: // Prevent the user from downgrading to versions lower than 5.0 by faking mounted volumes.
908: // The user could render the system unbootable by downgrading when boot encryption
909: // is active or being set up.
910: *(uint32 *) Irp->AssociatedIrp.SystemBuffer = 0xffffFFFF;
911: Irp->IoStatus.Status = STATUS_SUCCESS;
912: Irp->IoStatus.Information = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
913: }
914: break;
915:
916: case TC_IOCTL_GET_VOLUME_PROPERTIES:
1.1.1.9 root 917: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT)
918: || !DeviceObject || !DeviceObject->DriverObject)
1.1 root 919: {
1.1.1.11 root 920: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 921: Irp->IoStatus.Information = 0;
922: }
923: else
924: {
925: VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
926: PDEVICE_OBJECT ListDevice;
927:
928: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
929: Irp->IoStatus.Information = 0;
930:
1.1.1.5 root 931: DriverMutexWait ();
932:
1.1 root 933: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
934: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
935: {
936:
937: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.12 root 938: if (!ListExtension->bRootDevice
939: && !ListExtension->IsDriveFilterDevice
1.1.1.6 root 940: && !ListExtension->bShuttingDown
941: && ListExtension->nDosDriveNo == prop->driveNo)
1.1 root 942: {
1.1.1.6 root 943: prop->uniqueId = ListExtension->UniqueVolumeId;
1.1 root 944: wcscpy (prop->wszVolume, ListExtension->wszVolume);
945: prop->diskLength = ListExtension->DiskLength;
1.1.1.4 root 946: prop->ea = ListExtension->cryptoInfo->ea;
1.1.1.7 root 947: prop->mode = ListExtension->cryptoInfo->mode;
1.1 root 948: prop->pkcs5 = ListExtension->cryptoInfo->pkcs5;
949: prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations;
950: prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time;
951: prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time;
1.1.1.6 root 952: prop->readOnly = ListExtension->bReadOnly;
1.1.1.4 root 953: prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume;
1.1 root 954:
1.1.1.6 root 955: if (ListExtension->cryptoInfo->bProtectHiddenVolume)
956: prop->hiddenVolProtection = ListExtension->cryptoInfo->bHiddenVolProtectionAction ? HIDVOL_PROT_STATUS_ACTION_TAKEN : HIDVOL_PROT_STATUS_ACTIVE;
957: else
958: prop->hiddenVolProtection = HIDVOL_PROT_STATUS_NONE;
959:
1.1.1.12 root 960: prop->totalBytesRead = ListExtension->Queue.TotalBytesRead;
961: prop->totalBytesWritten = ListExtension->Queue.TotalBytesWritten;
1.1.1.6 root 962:
1.1 root 963: Irp->IoStatus.Status = STATUS_SUCCESS;
964: Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT);
965: break;
966: }
967: }
1.1.1.5 root 968:
969: DriverMutexRelease ();
1.1 root 970: }
971: break;
972:
1.1.1.12 root 973: case TC_IOCTL_GET_RESOLVED_SYMLINK:
1.1.1.6 root 974: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (RESOLVE_SYMLINK_STRUCT))
1.1.1.4 root 975: {
1.1.1.11 root 976: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.4 root 977: Irp->IoStatus.Information = 0;
978: }
979: else
1.1 root 980: {
1.1.1.4 root 981: RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
982: {
983: NTSTATUS ntStatus;
984:
985: ntStatus = SymbolicLinkToTarget (resolve->symLinkName,
986: resolve->targetName,
987: sizeof (resolve->targetName));
988:
989: Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT);
990: Irp->IoStatus.Status = ntStatus;
991: }
992:
993: }
994: break;
995:
1.1.1.12 root 996: case TC_IOCTL_GET_DRIVE_PARTITION_INFO:
1.1.1.10 root 997: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (DISK_PARTITION_INFO_STRUCT))
998: {
1.1.1.11 root 999: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.10 root 1000: Irp->IoStatus.Information = 0;
1001: }
1002: else
1003: {
1004: DISK_PARTITION_INFO_STRUCT *info = (DISK_PARTITION_INFO_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1005: {
1006: PARTITION_INFORMATION_EX pi;
1007: NTSTATUS ntStatus;
1008:
1009: ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi));
1010: if (NT_SUCCESS(ntStatus))
1011: {
1012: memset (&info->partInfo, 0, sizeof (info->partInfo));
1013:
1014: info->partInfo.PartitionLength = pi.PartitionLength;
1015: info->partInfo.PartitionNumber = pi.PartitionNumber;
1016: info->partInfo.StartingOffset = pi.StartingOffset;
1017:
1018: if (pi.PartitionStyle == PARTITION_STYLE_MBR)
1019: info->partInfo.PartitionType = pi.Mbr.PartitionType;
1.1.1.12 root 1020:
1021: info->IsGPT = pi.PartitionStyle == PARTITION_STYLE_GPT;
1.1.1.10 root 1022: }
1023: else
1024: {
1025: // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX
1026: ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &info->partInfo, sizeof (info->partInfo));
1.1.1.12 root 1027: info->IsGPT = FALSE;
1.1.1.10 root 1028: }
1029:
1030: Irp->IoStatus.Information = sizeof (DISK_PARTITION_INFO_STRUCT);
1031: Irp->IoStatus.Status = ntStatus;
1032: }
1033:
1034: }
1035: break;
1036:
1.1.1.12 root 1037: case TC_IOCTL_GET_DRIVE_GEOMETRY:
1.1.1.10 root 1038: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (DISK_GEOMETRY_STRUCT))
1039: {
1.1.1.11 root 1040: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.10 root 1041: Irp->IoStatus.Information = 0;
1042: }
1043: else
1044: {
1045: DISK_GEOMETRY_STRUCT *g = (DISK_GEOMETRY_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1046: {
1047: NTSTATUS ntStatus;
1048:
1049: ntStatus = TCDeviceIoControl (g->deviceName,
1050: IOCTL_DISK_GET_DRIVE_GEOMETRY,
1051: NULL, 0, &g->diskGeometry, sizeof (g->diskGeometry));
1052:
1053: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_STRUCT);
1054: Irp->IoStatus.Status = ntStatus;
1055: }
1056: }
1057: break;
1058:
1.1.1.12 root 1059: case TC_IOCTL_PROBE_REAL_DRIVE_SIZE:
1060: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (ProbeRealDriveSizeRequest))
1061: {
1062: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1063: Irp->IoStatus.Information = 0;
1064: }
1065: else
1066: {
1067: ProbeRealDriveSizeRequest *request = (ProbeRealDriveSizeRequest *) Irp->AssociatedIrp.SystemBuffer;
1068: NTSTATUS status;
1069: UNICODE_STRING name;
1070: PFILE_OBJECT fileObject;
1071: PDEVICE_OBJECT deviceObject;
1072:
1073: RtlInitUnicodeString (&name, request->DeviceName);
1074: status = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
1075: if (!NT_SUCCESS (status))
1076: {
1077: Irp->IoStatus.Information = 0;
1078: Irp->IoStatus.Status = status;
1079: break;
1080: }
1081:
1082: status = ProbeRealDriveSize (deviceObject, &request->RealDriveSize);
1083: ObDereferenceObject (fileObject);
1084:
1.1.1.14! root 1085: if (status == STATUS_TIMEOUT)
! 1086: {
! 1087: request->TimeOut = TRUE;
! 1088: Irp->IoStatus.Information = sizeof (ProbeRealDriveSizeRequest);
! 1089: Irp->IoStatus.Status = STATUS_SUCCESS;
! 1090: }
! 1091: else if (!NT_SUCCESS (status))
1.1.1.12 root 1092: {
1093: Irp->IoStatus.Information = 0;
1094: Irp->IoStatus.Status = status;
1095: }
1096: else
1097: {
1.1.1.14! root 1098: request->TimeOut = FALSE;
1.1.1.12 root 1099: Irp->IoStatus.Information = sizeof (ProbeRealDriveSizeRequest);
1100: Irp->IoStatus.Status = status;
1101: }
1102: }
1103: break;
1104:
1105: case TC_IOCTL_MOUNT_VOLUME:
1.1.1.4 root 1106: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT))
1107: {
1.1.1.11 root 1108: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.4 root 1109: Irp->IoStatus.Information = 0;
1110: }
1111: else
1112: {
1113: MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1114:
1.1.1.5 root 1115: DriverMutexWait ();
1.1.1.6 root 1116:
1117: Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
1.1.1.4 root 1118: Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
1.1.1.5 root 1119: DriverMutexRelease ();
1.1.1.6 root 1120:
1121: burn (&mount->VolumePassword, sizeof (mount->VolumePassword));
1122: burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword));
1.1 root 1123: }
1124: break;
1125:
1.1.1.12 root 1126: case TC_IOCTL_DISMOUNT_VOLUME:
1.1.1.9 root 1127: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT)
1128: || !DeviceObject || !DeviceObject->DriverObject)
1.1 root 1129: {
1.1.1.11 root 1130: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 1131: Irp->IoStatus.Information = 0;
1132: }
1133: else
1134: {
1135: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1136: PDEVICE_OBJECT ListDevice;
1137:
1138: unmount->nReturnCode = ERR_DRIVE_NOT_FOUND;
1139:
1140: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
1141: ListDevice != (PDEVICE_OBJECT) NULL;
1142: ListDevice = ListDevice->NextDevice)
1143: {
1144: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1145:
1.1.1.12 root 1146: if (!ListExtension->bRootDevice
1147: && !ListExtension->IsDriveFilterDevice
1.1.1.6 root 1148: && !ListExtension->bShuttingDown
1.1.1.4 root 1149: && unmount->nDosDriveNo == ListExtension->nDosDriveNo)
1.1 root 1150: {
1.1.1.5 root 1151: DriverMutexWait ();
1.1.1.4 root 1152: unmount->nReturnCode = UnmountDevice (ListDevice, unmount->ignoreOpenFiles);
1.1.1.5 root 1153: DriverMutexRelease ();
1.1.1.4 root 1154: break;
1.1.1.8 root 1155: }
1.1.1.4 root 1156: }
1.1 root 1157:
1.1.1.4 root 1158: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
1.1 root 1159: Irp->IoStatus.Status = STATUS_SUCCESS;
1160: }
1161: break;
1162:
1.1.1.12 root 1163: case TC_IOCTL_DISMOUNT_ALL_VOLUMES:
1.1.1.4 root 1164: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
1.1 root 1165: {
1.1.1.11 root 1166: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 1167: Irp->IoStatus.Information = 0;
1168: }
1169: else
1170: {
1.1.1.4 root 1171: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1.1 root 1172:
1.1.1.12 root 1173: unmount->nReturnCode = UnmountAllDevices (DeviceObject, unmount->ignoreOpenFiles);
1.1 root 1174:
1.1.1.4 root 1175: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
1176: Irp->IoStatus.Status = STATUS_SUCCESS;
1.1 root 1177: }
1178: break;
1179:
1.1.1.12 root 1180: case TC_IOCTL_BOOT_ENCRYPTION_SETUP:
1181: DriverMutexWait ();
1182:
1183: Irp->IoStatus.Status = StartBootEncryptionSetup (DeviceObject, Irp, irpSp);
1184: Irp->IoStatus.Information = 0;
1185:
1186: DriverMutexRelease ();
1187: break;
1188:
1189: case TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP:
1190: DriverMutexWait ();
1191:
1192: Irp->IoStatus.Status = AbortBootEncryptionSetup();
1193: Irp->IoStatus.Information = 0;
1194:
1195: DriverMutexRelease ();
1196: break;
1197:
1198: case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
1199: DriverMutexWait ();
1200: GetBootEncryptionStatus (Irp, irpSp);
1201: DriverMutexRelease ();
1202: break;
1203:
1204: case TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT:
1205: Irp->IoStatus.Information = 0;
1206: Irp->IoStatus.Status = GetSetupResult();
1207: break;
1208:
1209: case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
1210: DriverMutexWait ();
1211: GetBootDriveVolumeProperties (Irp, irpSp);
1212: DriverMutexRelease ();
1213: break;
1214:
1215: case TC_IOCTL_GET_BOOT_LOADER_VERSION:
1216: DriverMutexWait ();
1217: GetBootLoaderVersion (Irp, irpSp);
1218: DriverMutexRelease ();
1219: break;
1220:
1221: case TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER:
1222: DriverMutexWait ();
1223: ReopenBootVolumeHeader (Irp, irpSp);
1224: DriverMutexRelease ();
1225: break;
1226:
1.1.1.14! root 1227: case TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME:
! 1228: DriverMutexWait ();
! 1229: GetBootEncryptionAlgorithmName (Irp, irpSp);
! 1230: DriverMutexRelease ();
! 1231: break;
! 1232:
1.1.1.12 root 1233: default:
1234: return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
1235: }
1.1.1.10 root 1236:
1.1.1.12 root 1237:
1.1.1.10 root 1238: #ifdef DEBUG
1.1.1.12 root 1239: if (!NT_SUCCESS (Irp->IoStatus.Status))
1240: {
1241: switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
1242: {
1243: case TC_IOCTL_GET_MOUNTED_VOLUMES:
1244: case TC_IOCTL_GET_PASSWORD_CACHE_STATUS:
1.1.1.14! root 1245: case TC_IOCTL_GET_TRAVELER_MODE_STATUS:
! 1246: case TC_IOCTL_SET_TRAVELER_MODE_STATUS:
1.1.1.12 root 1247: case TC_IOCTL_OPEN_TEST:
1248: case TC_IOCTL_GET_RESOLVED_SYMLINK:
1249: case TC_IOCTL_GET_DRIVE_PARTITION_INFO:
1250: case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
1251: case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
1252: break;
1253:
1254: default:
1255: Dump ("IOCTL error 0x%08x\n", Irp->IoStatus.Status);
1256: }
1257: }
1.1.1.10 root 1258: #endif
1.1.1.12 root 1259:
1260: return TCCompleteIrp (Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
1261: }
1262:
1263:
1264: NTSTATUS TCStartThread (PKSTART_ROUTINE threadProc, PVOID threadArg, PKTHREAD *kThread)
1265: {
1.1.1.13 root 1266: return TCStartThreadInProcess (threadProc, threadArg, kThread, NULL);
1267: }
1268:
1269:
1270: NTSTATUS TCStartThreadInProcess (PKSTART_ROUTINE threadProc, PVOID threadArg, PKTHREAD *kThread, PEPROCESS process)
1271: {
1.1.1.12 root 1272: NTSTATUS status;
1273: HANDLE threadHandle;
1.1.1.13 root 1274: HANDLE processHandle = NULL;
1.1.1.12 root 1275: OBJECT_ATTRIBUTES threadObjAttributes;
1276:
1.1.1.13 root 1277: if (process)
1278: {
1279: status = ObOpenObjectByPointer (process, OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &processHandle);
1280: if (!NT_SUCCESS (status))
1281: return status;
1282: }
1283:
1.1.1.12 root 1284: InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
1285:
1.1.1.13 root 1286: status = PsCreateSystemThread (&threadHandle, THREAD_ALL_ACCESS, &threadObjAttributes, processHandle, NULL, threadProc, threadArg);
1.1.1.12 root 1287: if (!NT_SUCCESS (status))
1288: return status;
1289:
1290: status = ObReferenceObjectByHandle (threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID *) kThread, NULL);
1291: if (!NT_SUCCESS (status))
1292: {
1293: ZwClose (threadHandle);
1294: *kThread = NULL;
1295: return status;
1296: }
1297:
1.1.1.13 root 1298: if (processHandle)
1299: ZwClose (processHandle);
1300:
1.1.1.12 root 1301: ZwClose (threadHandle);
1302: return STATUS_SUCCESS;
1303: }
1304:
1305:
1306: void TCStopThread (PKTHREAD kThread, PKEVENT wakeUpEvent)
1307: {
1308: if (wakeUpEvent)
1309: KeSetEvent (wakeUpEvent, 0, FALSE);
1310:
1311: KeWaitForSingleObject (kThread, Executive, KernelMode, FALSE, NULL);
1312: ObDereferenceObject (kThread);
1.1 root 1313: }
1314:
1.1.1.6 root 1315:
1.1 root 1316: NTSTATUS
1.1.1.12 root 1317: TCStartVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount)
1.1 root 1318: {
1319: PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK));
1320: HANDLE hThread;
1321: NTSTATUS ntStatus;
1.1.1.6 root 1322: HANDLE process;
1.1.1.12 root 1323: OBJECT_ATTRIBUTES threadObjAttributes;
1.1 root 1324:
1325: Dump ("Starting thread...\n");
1326:
1327: if (pThreadBlock == NULL)
1328: {
1329: return STATUS_INSUFFICIENT_RESOURCES;
1330: }
1331: else
1332: {
1333: pThreadBlock->DeviceObject = DeviceObject;
1334: pThreadBlock->mount = mount;
1335: }
1336:
1.1.1.6 root 1337: if (mount->bUserContext)
1338: {
1.1.1.13 root 1339: ntStatus = ObOpenObjectByPointer (IoGetCurrentProcess (), OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &process);
1.1.1.6 root 1340: if (!NT_SUCCESS (ntStatus))
1341: {
1342: Dump ("ObOpenObjectByPointer Failed\n");
1343: goto ret;
1344: }
1345: }
1346: else
1347: process = NULL;
1348:
1.1 root 1349: Extension->bThreadShouldQuit = FALSE;
1350:
1.1.1.12 root 1351: InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
1352:
1.1 root 1353: ntStatus = PsCreateSystemThread (&hThread,
1354: THREAD_ALL_ACCESS,
1.1.1.12 root 1355: &threadObjAttributes,
1.1.1.6 root 1356: process,
1.1 root 1357: NULL,
1.1.1.12 root 1358: VolumeThreadProc,
1.1 root 1359: pThreadBlock);
1360:
1.1.1.13 root 1361: if (process)
1362: ZwClose (process);
1363:
1.1 root 1364: if (!NT_SUCCESS (ntStatus))
1365: {
1366: Dump ("PsCreateSystemThread Failed END\n");
1.1.1.6 root 1367: goto ret;
1.1 root 1368: }
1369:
1.1.1.12 root 1370: ntStatus = ObReferenceObjectByHandle (hThread,
1.1 root 1371: THREAD_ALL_ACCESS,
1372: NULL,
1373: KernelMode,
1374: &Extension->peThread,
1375: NULL);
1.1.1.12 root 1376:
1.1 root 1377: ZwClose (hThread);
1378:
1.1.1.12 root 1379: if (!NT_SUCCESS (ntStatus))
1380: goto ret;
1381:
1.1 root 1382: Dump ("Waiting for thread to initialize...\n");
1383:
1384: KeWaitForSingleObject (&Extension->keCreateEvent,
1.1.1.12 root 1385: Executive,
1386: KernelMode,
1.1 root 1387: FALSE,
1388: NULL);
1389:
1390: Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus);
1391: ntStatus = pThreadBlock->ntCreateStatus;
1.1.1.6 root 1392:
1393: ret:
1.1 root 1394: TCfree (pThreadBlock);
1395: return ntStatus;
1396: }
1397:
1398: void
1.1.1.12 root 1399: TCStopVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1.1 root 1400: {
1401: NTSTATUS ntStatus;
1402:
1403: if (DeviceObject); /* Remove compiler warning */
1404:
1405: Dump ("Signalling thread to quit...\n");
1406:
1407: Extension->bThreadShouldQuit = TRUE;
1408:
1409: KeReleaseSemaphore (&Extension->RequestSemaphore,
1410: 0,
1411: 1,
1412: TRUE);
1413:
1.1.1.4 root 1414: ntStatus = KeWaitForSingleObject (Extension->peThread,
1.1.1.12 root 1415: Executive,
1416: KernelMode,
1.1 root 1417: FALSE,
1418: NULL);
1419: if (ntStatus != STATUS_SUCCESS)
1420: Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n",
1421: ntStatus);
1422:
1.1.1.6 root 1423: ObDereferenceObject (Extension->peThread);
1.1 root 1424: Extension->peThread = NULL;
1425:
1426: Dump ("Thread exited!\n");
1427: }
1428:
1.1.1.5 root 1429:
1430: // Suspend current thread for a number of milliseconds
1431: void TCSleep (int milliSeconds)
1432: {
1433: PKTIMER timer = (PKTIMER) TCalloc (sizeof (KTIMER));
1434: LARGE_INTEGER duetime;
1435:
1.1.1.14! root 1436: if (!timer)
! 1437: return;
! 1438:
1.1.1.5 root 1439: duetime.QuadPart = (__int64) milliSeconds * -10000;
1440: KeInitializeTimerEx(timer, NotificationTimer);
1441: KeSetTimerEx(timer, duetime, 0, NULL);
1442:
1.1.1.12 root 1443: KeWaitForSingleObject (timer, Executive, KernelMode, FALSE, NULL);
1.1.1.5 root 1444:
1445: TCfree (timer);
1446: }
1447:
1448:
1.1.1.12 root 1449: /* VolumeThreadProc does all the work of processing IRP's, and dispatching them
1.1 root 1450: to either the ReadWrite function or the DeviceControl function */
1451: VOID
1.1.1.12 root 1452: VolumeThreadProc (PVOID Context)
1.1 root 1453: {
1454: PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context;
1455: PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject;
1456: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
1457: LARGE_INTEGER queueWait;
1458: BOOL bDevice;
1459:
1460: /* Set thread priority to lowest realtime level. */
1461: KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY);
1462:
1463: queueWait.QuadPart = -WAIT_SECONDS (1);
1464:
1465: Dump ("Mount THREAD OPENING VOLUME BEGIN\n");
1466:
1467: if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0)
1468: {
1469: wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\"));
1.1.1.7 root 1470: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
1471: sizeof (pThreadBlock->wszMountVolume) / 2 - 5);
1.1 root 1472: bDevice = FALSE;
1473: }
1474: else
1475: {
1.1.1.8 root 1476: pThreadBlock->wszMountVolume[0] = 0;
1477: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
1.1.1.7 root 1478: sizeof (pThreadBlock->wszMountVolume) / 2 - 1);
1.1 root 1479: bDevice = TRUE;
1480: }
1481:
1482: Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n",
1483: pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice);
1484:
1485: pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject,
1.1.1.7 root 1486: Extension,
1487: pThreadBlock->mount,
1488: pThreadBlock->wszMountVolume,
1489: bDevice);
1.1 root 1490:
1491: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0)
1492: {
1493: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1494: PsTerminateSystemThread (STATUS_SUCCESS);
1495: }
1.1.1.12 root 1496:
1497: // Start IO queue
1498: Extension->Queue.IsFilterDevice = FALSE;
1499: Extension->Queue.DeviceObject = DeviceObject;
1500: Extension->Queue.CryptoInfo = Extension->cryptoInfo;
1501: Extension->Queue.HostFileHandle = Extension->hDeviceFile;
1502: Extension->Queue.VirtualDeviceLength = Extension->DiskLength;
1503:
1.1.1.13 root 1504: pThreadBlock->ntCreateStatus = EncryptedIoQueueStart (&Extension->Queue, pThreadBlock->mount->bUserContext ? IoGetCurrentProcess() : NULL);
1.1.1.12 root 1505:
1506: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus))
1.1 root 1507: {
1.1.1.12 root 1508: TCCloseVolume (DeviceObject, Extension);
1509:
1510: pThreadBlock->mount->nReturnCode = ERR_OS_ERROR;
1.1 root 1511: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1.1.1.12 root 1512: PsTerminateSystemThread (STATUS_SUCCESS);
1.1 root 1513: }
1514:
1.1.1.12 root 1515: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1516: /* From this point on pThreadBlock cannot be used as it will have been released! */
1517: pThreadBlock = NULL;
1518:
1.1 root 1519: for (;;)
1520: {
1521: NTSTATUS ntStatus;
1522:
1523: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1524:
1525: /* Wait for a request from the dispatch routines. */
1526: ntStatus = KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore,
1527: Executive, KernelMode, FALSE, &queueWait);
1528:
1529: if (ntStatus != STATUS_TIMEOUT)
1530: {
1531: for (;;)
1532: {
1533: PIO_STACK_LOCATION irpSp;
1534: PLIST_ENTRY request;
1535: PIRP Irp;
1536:
1537: request = ExInterlockedRemoveHeadList (&Extension->ListEntry,
1538: &Extension->ListSpinLock);
1539: if (request == NULL)
1540: break;
1541:
1542: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1543:
1544: Irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry);
1545: irpSp = IoGetCurrentIrpStackLocation (Irp);
1546:
1547: switch (irpSp->MajorFunction)
1548: {
1549: case IRP_MJ_READ:
1550: case IRP_MJ_WRITE:
1.1.1.12 root 1551: ntStatus = EncryptedIoQueueAddIrp (&Extension->Queue, Irp);
1552:
1553: if (ntStatus != STATUS_PENDING)
1554: TCCompleteDiskIrp (Irp, ntStatus, 0);
1555:
1.1 root 1556: break;
1557:
1558: case IRP_MJ_FLUSH_BUFFERS:
1559: case IRP_MJ_SHUTDOWN:
1560: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
1561: break;
1562:
1563: case IRP_MJ_DEVICE_CONTROL:
1.1.1.12 root 1564: ProcessVolumeDeviceControlIrp (DeviceObject, Extension, Irp);
1.1 root 1565: break;
1.1.1.10 root 1566: }
1567: }
1.1 root 1568:
1569: if (Extension->bThreadShouldQuit)
1570: {
1571: Dump ("Closing volume along with Thread!\n");
1.1.1.12 root 1572:
1573: EncryptedIoQueueStop (&Extension->Queue);
1574:
1.1 root 1575: TCCloseVolume (DeviceObject, Extension);
1576: PsTerminateSystemThread (STATUS_SUCCESS);
1577: }
1578: }
1.1.1.10 root 1579: }
1.1 root 1580: }
1581:
1582: void
1583: TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)
1584: {
1585: WCHAR tmp[3] =
1586: {0, ':', 0};
1587: int j = nDriveNo + (WCHAR) 'A';
1588:
1589: tmp[0] = (short) j;
1590: wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
1591: wcsncat (ntname, tmp, 1);
1592: }
1593:
1594: void
1595: TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo)
1596: {
1597: WCHAR tmp[3] =
1598: {0, ':', 0};
1599: int j = nDriveNo + (WCHAR) 'A';
1600:
1601: tmp[0] = (short) j;
1602: wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX);
1603: wcscat (dosname, tmp);
1604: }
1605:
1606: #ifdef _DEBUG
1607: LPWSTR
1608: TCTranslateCode (ULONG ulCode)
1609: {
1.1.1.12 root 1610: switch (ulCode)
1611: {
1612: #define TC_CASE_RET_NAME(CODE) case CODE : return L###CODE
1613:
1614: TC_CASE_RET_NAME (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
1615: TC_CASE_RET_NAME (TC_IOCTL_BOOT_ENCRYPTION_SETUP);
1616: TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_ALL_VOLUMES);
1617: TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_VOLUME);
1618: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES);
1.1.1.14! root 1619: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME);
1.1.1.12 root 1620: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
1621: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS);
1622: TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_LOADER_VERSION);
1623: TC_CASE_RET_NAME (TC_IOCTL_GET_DEVICE_REFCOUNT);
1624: TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_GEOMETRY);
1625: TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_PARTITION_INFO);
1626: TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVER_VERSION);
1627: TC_CASE_RET_NAME (TC_IOCTL_GET_MOUNTED_VOLUMES);
1628: TC_CASE_RET_NAME (TC_IOCTL_GET_PASSWORD_CACHE_STATUS);
1.1.1.14! root 1629: TC_CASE_RET_NAME (TC_IOCTL_GET_TRAVELER_MODE_STATUS);
! 1630: TC_CASE_RET_NAME (TC_IOCTL_SET_TRAVELER_MODE_STATUS);
1.1.1.12 root 1631: TC_CASE_RET_NAME (TC_IOCTL_GET_RESOLVED_SYMLINK);
1632: TC_CASE_RET_NAME (TC_IOCTL_GET_VOLUME_PROPERTIES);
1633: TC_CASE_RET_NAME (TC_IOCTL_IS_ANY_VOLUME_MOUNTED);
1634: TC_CASE_RET_NAME (TC_IOCTL_MOUNT_VOLUME);
1635: TC_CASE_RET_NAME (TC_IOCTL_OPEN_TEST);
1636: TC_CASE_RET_NAME (TC_IOCTL_PROBE_REAL_DRIVE_SIZE);
1637: TC_CASE_RET_NAME (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER);
1638: TC_CASE_RET_NAME (TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED);
1639: TC_CASE_RET_NAME (TC_IOCTL_WIPE_PASSWORD_CACHE);
1640:
1641: #undef TC_CASE_RET_NAME
1642: }
1643:
1.1 root 1644: if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY)
1645: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY");
1646: else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)
1647: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX");
1648: else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME)
1649: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME");
1650: else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME)
1651: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME");
1652: else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID)
1653: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID");
1654: else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY)
1655: return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY");
1656: else if (ulCode == IOCTL_VOLUME_ONLINE)
1657: return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE");
1658: else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED)
1659: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED");
1660: else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED)
1661: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED");
1662: else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS)
1663: return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS");
1664: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED)
1665: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED");
1666: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED)
1667: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED");
1668: else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO)
1669: return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO");
1670: else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER)
1671: return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER");
1672: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO)
1673: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO");
1674: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX)
1675: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX");
1676: else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO)
1677: return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO");
1678: else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT)
1679: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT");
1680: else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX)
1681: return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX");
1682: else if (ulCode == IOCTL_DISK_VERIFY)
1683: return (LPWSTR) _T ("IOCTL_DISK_VERIFY");
1684: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS)
1685: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS");
1686: else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS)
1687: return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS");
1688: else if (ulCode == IOCTL_DISK_PERFORMANCE)
1689: return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE");
1690: else if (ulCode == IOCTL_DISK_IS_WRITABLE)
1691: return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE");
1692: else if (ulCode == IOCTL_DISK_LOGGING)
1693: return (LPWSTR) _T ("IOCTL_DISK_LOGGING");
1694: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX)
1695: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX");
1696: else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE)
1697: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE");
1698: else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA)
1699: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA");
1700: else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET)
1701: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET");
1702: else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE)
1703: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE");
1704: else if (ulCode == IOCTL_DISK_REQUEST_DATA)
1705: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA");
1706: else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER)
1707: return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER");
1708: else if (ulCode == SMART_GET_VERSION)
1709: return (LPWSTR) _T ("SMART_GET_VERSION");
1710: else if (ulCode == SMART_SEND_DRIVE_COMMAND)
1711: return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND");
1712: else if (ulCode == SMART_RCV_DRIVE_DATA)
1713: return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA");
1714: else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY)
1715: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY");
1716: else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY)
1717: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY");
1718: else if (ulCode == IOCTL_DISK_CHECK_VERIFY)
1719: return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY");
1720: else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL)
1721: return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL");
1722: else if (ulCode == IOCTL_DISK_EJECT_MEDIA)
1723: return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA");
1724: else if (ulCode == IOCTL_DISK_LOAD_MEDIA)
1725: return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA");
1726: else if (ulCode == IOCTL_DISK_RESERVE)
1727: return (LPWSTR) _T ("IOCTL_DISK_RESERVE");
1728: else if (ulCode == IOCTL_DISK_RELEASE)
1729: return (LPWSTR) _T ("IOCTL_DISK_RELEASE");
1730: else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES)
1731: return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES");
1732: else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES)
1733: return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES");
1734: else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO)
1735: return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO");
1736: else if (ulCode == IRP_MJ_READ)
1737: return (LPWSTR) _T ("IRP_MJ_READ");
1738: else if (ulCode == IRP_MJ_WRITE)
1739: return (LPWSTR) _T ("IRP_MJ_WRITE");
1740: else if (ulCode == IRP_MJ_CREATE)
1741: return (LPWSTR) _T ("IRP_MJ_CREATE");
1742: else if (ulCode == IRP_MJ_CLOSE)
1743: return (LPWSTR) _T ("IRP_MJ_CLOSE");
1744: else if (ulCode == IRP_MJ_CLEANUP)
1745: return (LPWSTR) _T ("IRP_MJ_CLEANUP");
1746: else if (ulCode == IRP_MJ_FLUSH_BUFFERS)
1747: return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS");
1748: else if (ulCode == IRP_MJ_SHUTDOWN)
1749: return (LPWSTR) _T ("IRP_MJ_SHUTDOWN");
1750: else if (ulCode == IRP_MJ_DEVICE_CONTROL)
1751: return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL");
1752: else
1753: {
1.1.1.12 root 1754: return (LPWSTR) _T ("IOCTL");
1.1 root 1755: }
1756: }
1757:
1758: #endif
1759:
1760: PDEVICE_OBJECT
1761: TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1762: {
1763: PDEVICE_OBJECT OldDeviceObject = DeviceObject;
1764: UNICODE_STRING Win32NameString;
1765: NTSTATUS ntStatus;
1766:
1767: Dump ("TCDeleteDeviceObject BEGIN\n");
1768:
1.1.1.6 root 1769: if (Extension->bRootDevice)
1.1 root 1770: {
1771: RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX);
1.1.1.4 root 1772: ntStatus = IoDeleteSymbolicLink (&Win32NameString);
1773: if (!NT_SUCCESS (ntStatus))
1774: Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus);
1.1 root 1775: }
1776: else
1777: {
1778: if (Extension->peThread != NULL)
1.1.1.12 root 1779: TCStopVolumeThread (DeviceObject, Extension);
1.1.1.14! root 1780:
! 1781: if (DeviceObject->ReferenceCount > 0)
! 1782: ReferencedDeviceDeleted = TRUE;
! 1783:
! 1784: // Forced dismount does not set reference count to zero even if all open handles are closed
! 1785: Dump ("Deleting device with ref count %ld\n", DeviceObject->ReferenceCount);
! 1786: DeviceObject->ReferenceCount = 0;
1.1 root 1787: }
1788:
1.1.1.8 root 1789: if (DeviceObject != NULL)
1790: DeviceObject = DeviceObject->NextDevice;
1791:
1.1 root 1792: IoDeleteDevice (OldDeviceObject);
1793:
1794: Dump ("TCDeleteDeviceObject END\n");
1795: return DeviceObject;
1796: }
1797:
1.1.1.4 root 1798:
1.1 root 1799: VOID
1800: TCUnloadDriver (PDRIVER_OBJECT DriverObject)
1801: {
1802: PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
1803:
1804: Dump ("TCUnloadDriver BEGIN\n");
1805:
1.1.1.12 root 1806: UnmountAllDevices (DeviceObject, TRUE);
1.1.1.4 root 1807:
1.1 root 1808: /* Now walk the list of driver objects and get rid of them */
1809: while (DeviceObject != (PDEVICE_OBJECT) NULL)
1810: {
1811: DeviceObject = TCDeleteDeviceObject (DeviceObject,
1812: (PEXTENSION) DeviceObject->DeviceExtension);
1813: }
1814:
1.1.1.11 root 1815: WipeCache ();
1816:
1.1.1.12 root 1817: if (IsBootDriveMounted())
1818: TC_BUG_CHECK (STATUS_INVALID_DEVICE_STATE);
1819:
1.1 root 1820: Dump ("TCUnloadDriver END\n");
1821: }
1.1.1.4 root 1822:
1823:
1824: NTSTATUS
1825: TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode,
1826: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
1827: {
1828: IO_STATUS_BLOCK ioStatusBlock;
1829: NTSTATUS ntStatus;
1830: PIRP irp;
1831: PFILE_OBJECT fileObject;
1832: PDEVICE_OBJECT deviceObject;
1833: KEVENT event;
1834: UNICODE_STRING name;
1835:
1836: RtlInitUnicodeString(&name, deviceName);
1.1.1.10 root 1837: ntStatus = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
1.1.1.4 root 1838:
1839: if (ntStatus != STATUS_SUCCESS)
1840: return ntStatus;
1841:
1842: KeInitializeEvent(&event, NotificationEvent, FALSE);
1843:
1844: irp = IoBuildDeviceIoControlRequest (IoControlCode,
1845: deviceObject,
1846: InputBuffer, InputBufferSize,
1847: OutputBuffer, OutputBufferSize,
1848: FALSE,
1849: &event,
1850: &ioStatusBlock);
1851:
1852: if (irp == NULL)
1853: {
1854: Dump ("IRP allocation failed\n");
1.1.1.11 root 1855: ntStatus = STATUS_INSUFFICIENT_RESOURCES;
1856: goto ret;
1.1.1.4 root 1857: }
1858:
1859: ntStatus = IoCallDriver (deviceObject, irp);
1860: if (ntStatus == STATUS_PENDING)
1861: {
1.1.1.12 root 1862: KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
1.1.1.4 root 1863: ntStatus = ioStatusBlock.Status;
1864: }
1865:
1.1.1.11 root 1866: ret:
1867: ObDereferenceObject (fileObject);
1.1.1.4 root 1868: return ntStatus;
1869: }
1870:
1871:
1.1.1.12 root 1872: NTSTATUS SendDeviceIoControlRequest (PDEVICE_OBJECT deviceObject, ULONG ioControlCode, void *inputBuffer, int inputBufferSize, void *outputBuffer, int outputBufferSize)
1873: {
1874: IO_STATUS_BLOCK ioStatusBlock;
1875: NTSTATUS status;
1876: PIRP irp;
1877: KEVENT event;
1878:
1879: ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
1880:
1881: KeInitializeEvent (&event, NotificationEvent, FALSE);
1882:
1883: irp = IoBuildDeviceIoControlRequest (ioControlCode, deviceObject, inputBuffer, inputBufferSize,
1884: outputBuffer, outputBufferSize, FALSE, &event, &ioStatusBlock);
1885:
1886: if (!irp)
1887: return STATUS_INSUFFICIENT_RESOURCES;
1888:
1889: ObReferenceObject (deviceObject);
1890:
1891: status = IoCallDriver (deviceObject, irp);
1892: if (status == STATUS_PENDING)
1893: {
1894: KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
1895: status = ioStatusBlock.Status;
1896: }
1897:
1898: ObDereferenceObject (deviceObject);
1899: return status;
1900: }
1901:
1902:
1903: NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize)
1904: {
1905: NTSTATUS status;
1906: LARGE_INTEGER sysLength;
1907: LARGE_INTEGER offset;
1908: byte *sectorBuffer = TCalloc (SECTOR_SIZE);
1.1.1.14! root 1909: ULONGLONG startTime;
1.1.1.12 root 1910:
1911: if (!sectorBuffer)
1912: return STATUS_INSUFFICIENT_RESOURCES;
1913:
1914: status = SendDeviceIoControlRequest (driveDeviceObject, IOCTL_DISK_GET_LENGTH_INFO,
1915: NULL, 0, &sysLength, sizeof (sysLength));
1916:
1917: if (!NT_SUCCESS (status))
1918: {
1919: Dump ("Failed to get drive size - error %x\n", status);
1.1.1.14! root 1920: TCfree (sectorBuffer);
1.1.1.12 root 1921: return status;
1922: }
1923:
1.1.1.14! root 1924: startTime = KeQueryInterruptTime ();
1.1.1.12 root 1925: for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += SECTOR_SIZE)
1926: {
1927: status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, SECTOR_SIZE);
1.1.1.13 root 1928:
1.1.1.14! root 1929: if (!NT_SUCCESS (status))
1.1.1.12 root 1930: {
1931: driveSize->QuadPart = offset.QuadPart;
1932: Dump ("Real drive size = %I64d\n", driveSize->QuadPart);
1933: TCfree (sectorBuffer);
1934: return STATUS_SUCCESS;
1935: }
1.1.1.14! root 1936:
! 1937: if (KeQueryInterruptTime() - startTime > 3ULL * 60 * 1000 * 1000 * 10)
! 1938: {
! 1939: // Abort if probing for more than 3 minutes
! 1940: driveSize->QuadPart = sysLength.QuadPart;
! 1941: TCfree (sectorBuffer);
! 1942: return STATUS_TIMEOUT;
! 1943: }
1.1.1.12 root 1944: }
1945: }
1946:
1947:
1.1.1.4 root 1948: // Opens a mounted TC volume on filesystem level
1949: NTSTATUS
1950: TCOpenFsVolume (PEXTENSION Extension, PHANDLE volumeHandle, PFILE_OBJECT * fileObject)
1951: {
1952: NTSTATUS ntStatus;
1953: OBJECT_ATTRIBUTES objectAttributes;
1954: UNICODE_STRING fullFileName;
1955: IO_STATUS_BLOCK ioStatus;
1.1.1.7 root 1956: WCHAR volumeName[TC_MAX_PATH];
1.1.1.4 root 1957:
1958: TCGetDosNameFromNumber (volumeName, Extension->nDosDriveNo);
1959: RtlInitUnicodeString (&fullFileName, volumeName);
1960: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
1961:
1962: ntStatus = ZwCreateFile (volumeHandle,
1963: SYNCHRONIZE | GENERIC_READ,
1964: &objectAttributes,
1965: &ioStatus,
1966: NULL,
1967: FILE_ATTRIBUTE_NORMAL,
1968: FILE_SHARE_READ | FILE_SHARE_WRITE,
1969: FILE_OPEN,
1970: FILE_SYNCHRONOUS_IO_NONALERT,
1971: NULL,
1972: 0);
1973:
1974: Dump ("Volume %ls open NTSTATUS 0x%08x\n", volumeName, ntStatus);
1975:
1976: if (!NT_SUCCESS (ntStatus))
1977: return ntStatus;
1978:
1979: ntStatus = ObReferenceObjectByHandle (*volumeHandle,
1980: FILE_READ_DATA,
1981: NULL,
1982: KernelMode,
1983: fileObject,
1984: NULL);
1985:
1986: Dump ("ObReferenceObjectByHandle NTSTATUS 0x%08x\n", ntStatus);
1987:
1988: if (!NT_SUCCESS (ntStatus))
1989: {
1990: ZwClose(*volumeHandle);
1991: return ntStatus;
1992: }
1993:
1994: return ntStatus;
1995: }
1996:
1997:
1998: void
1999: TCCloseFsVolume (HANDLE volumeHandle, PFILE_OBJECT fileObject)
2000: {
2001: ObDereferenceObject (fileObject);
2002: ZwClose (volumeHandle);
2003: }
2004:
2005:
1.1.1.12 root 2006: static NTSTATUS TCReadWriteDevice (BOOL write, PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length)
2007: {
2008: NTSTATUS status;
2009: IO_STATUS_BLOCK ioStatusBlock;
2010: PIRP irp;
2011: KEVENT completionEvent;
2012:
2013: ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
2014:
2015: KeInitializeEvent (&completionEvent, NotificationEvent, FALSE);
2016: irp = IoBuildSynchronousFsdRequest (write ? IRP_MJ_WRITE : IRP_MJ_READ, deviceObject, buffer, length, &offset, &completionEvent, &ioStatusBlock);
2017: if (!irp)
2018: return STATUS_INSUFFICIENT_RESOURCES;
2019:
2020: ObReferenceObject (deviceObject);
2021: status = IoCallDriver (deviceObject, irp);
2022:
2023: if (status == STATUS_PENDING)
2024: {
2025: status = KeWaitForSingleObject (&completionEvent, Executive, KernelMode, FALSE, NULL);
2026: if (NT_SUCCESS (status))
2027: status = ioStatusBlock.Status;
2028: }
2029:
2030: ObDereferenceObject (deviceObject);
2031: return status;
2032: }
2033:
2034:
2035: NTSTATUS TCReadDevice (PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length)
2036: {
2037: return TCReadWriteDevice (FALSE, deviceObject, buffer, offset, length);
2038: }
2039:
2040:
2041: NTSTATUS TCWriteDevice (PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length)
2042: {
2043: return TCReadWriteDevice (TRUE, deviceObject, buffer, offset, length);
2044: }
2045:
2046:
1.1.1.4 root 2047: NTSTATUS
2048: TCFsctlCall (PFILE_OBJECT fileObject, LONG IoControlCode,
2049: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
2050: {
2051: IO_STATUS_BLOCK ioStatusBlock;
2052: NTSTATUS ntStatus;
2053: PIRP irp;
2054: KEVENT event;
2055: PIO_STACK_LOCATION stack;
2056: PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject);
2057:
2058: Dump ("IoGetRelatedDeviceObject = 0x%08x\n", deviceObject);
2059:
2060: KeInitializeEvent(&event, NotificationEvent, FALSE);
2061:
2062: irp = IoBuildDeviceIoControlRequest (IoControlCode,
2063: deviceObject,
2064: InputBuffer, InputBufferSize,
2065: OutputBuffer, OutputBufferSize,
2066: FALSE,
2067: &event,
2068: &ioStatusBlock);
2069:
2070: if (irp == NULL)
2071: {
2072: Dump ("IRP allocation failed\n");
2073: return STATUS_INSUFFICIENT_RESOURCES;
2074: }
2075:
2076: stack = IoGetNextIrpStackLocation(irp);
2077:
2078: stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
2079: stack->MinorFunction = IRP_MN_USER_FS_REQUEST;
2080: stack->FileObject = fileObject;
2081:
2082: ntStatus = IoCallDriver (deviceObject, irp);
2083: if (ntStatus == STATUS_PENDING)
2084: {
1.1.1.12 root 2085: KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
1.1.1.4 root 2086: ntStatus = ioStatusBlock.Status;
2087: }
2088:
2089: return ntStatus;
2090: }
2091:
2092:
2093: NTSTATUS
1.1.1.6 root 2094: CreateDriveLink (int nDosDriveNo)
2095: {
1.1.1.7 root 2096: WCHAR dev[256], link[256];
1.1.1.6 root 2097: UNICODE_STRING deviceName, symLink;
2098: NTSTATUS ntStatus;
2099:
2100: TCGetNTNameFromNumber (dev, nDosDriveNo);
2101: TCGetDosNameFromNumber (link, nDosDriveNo);
2102:
2103: RtlInitUnicodeString (&deviceName, dev);
2104: RtlInitUnicodeString (&symLink, link);
2105:
2106: ntStatus = IoCreateSymbolicLink (&symLink, &deviceName);
2107: Dump ("IoCreateSymbolicLink returned %X\n", ntStatus);
2108: return ntStatus;
2109: }
2110:
2111:
2112: NTSTATUS
2113: RemoveDriveLink (int nDosDriveNo)
2114: {
1.1.1.7 root 2115: WCHAR link[256];
1.1.1.6 root 2116: UNICODE_STRING symLink;
2117: NTSTATUS ntStatus;
2118:
2119: TCGetDosNameFromNumber (link, nDosDriveNo);
2120: RtlInitUnicodeString (&symLink, link);
2121:
2122: ntStatus = IoDeleteSymbolicLink (&symLink);
2123: Dump ("IoDeleteSymbolicLink returned %X\n", ntStatus);
2124: return ntStatus;
2125: }
2126:
2127:
2128: NTSTATUS
1.1.1.4 root 2129: MountManagerMount (MOUNT_STRUCT *mount)
2130: {
2131: NTSTATUS ntStatus;
1.1.1.7 root 2132: WCHAR arrVolume[256];
1.1.1.4 root 2133: char buf[200];
2134: PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf;
2135: PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf;
2136: UNICODE_STRING symName, devName;
2137:
2138: TCGetNTNameFromNumber (arrVolume, mount->nDosDriveNo);
2139: in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2;
2140: wcscpy(in->DeviceName, arrVolume);
2141:
2142: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
2143: in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0);
2144:
2145: memset (buf, 0, sizeof buf);
2146: TCGetDosNameFromNumber ((PWSTR) &point[1], mount->nDosDriveNo);
2147:
2148: point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
2149: point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;
2150:
2151: RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset));
2152:
2153: point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength;
2154: TCGetNTNameFromNumber ((PWSTR) (buf + point->DeviceNameOffset), mount->nDosDriveNo);
2155: point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2;
2156:
2157: RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset));
2158:
2159: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point,
2160: point->DeviceNameOffset + point->DeviceNameLength, 0, 0);
2161:
2162: return ntStatus;
2163: }
2164:
2165:
2166: NTSTATUS
2167: MountManagerUnmount (int nDosDriveNo)
2168: {
2169: NTSTATUS ntStatus;
1.1.1.7 root 2170: char buf[256], out[300];
1.1.1.4 root 2171: PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf;
2172:
2173: memset (buf, 0, sizeof buf);
2174:
2175: TCGetDosNameFromNumber ((PWSTR) &in[1], nDosDriveNo);
2176:
2177: in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
2178: in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2;
2179:
2180: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS,
2181: in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out);
2182:
2183: Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus);
2184:
2185: return ntStatus;
2186: }
2187:
2188:
2189: NTSTATUS
2190: MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount)
2191: {
2192: PDEVICE_OBJECT NewDeviceObject;
2193: NTSTATUS ntStatus;
2194:
1.1.1.6 root 2195: /* Make sure the user is asking for a reasonable
1.1.1.4 root 2196: nDosDriveNo */
2197: if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25)
2198: {
2199: Dump ("Mount request looks valid\n");
2200: }
2201: else
2202: {
2203: Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n");
1.1.1.10 root 2204: mount->nReturnCode = ERR_DRIVE_NOT_FOUND;
2205: return ERR_DRIVE_NOT_FOUND;
1.1.1.4 root 2206: }
2207:
1.1.1.6 root 2208: if (!SelfTestsPassed)
2209: {
2210: mount->nReturnCode = ERR_SELF_TESTS_FAILED;
2211: return ERR_SELF_TESTS_FAILED;
2212: }
2213:
1.1.1.4 root 2214: ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
2215: mount);
2216: if (!NT_SUCCESS (ntStatus))
2217: {
2218: Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
2219: return ntStatus;
2220: }
2221: else
2222: {
2223: PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension;
1.1.1.12 root 2224: ntStatus = TCStartVolumeThread (NewDeviceObject, NewExtension, mount);
1.1.1.4 root 2225: if (!NT_SUCCESS (ntStatus))
2226: {
2227: Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus);
2228: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
2229: return ntStatus;
2230: }
2231: else
2232: {
2233: if (mount->nReturnCode == 0)
2234: {
2235: Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode,
2236: NewExtension->bReadOnly);
1.1.1.6 root 2237: if (NewExtension->bReadOnly)
1.1.1.4 root 2238: NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
2239: NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
2240:
1.1.1.6 root 2241: NewExtension->UniqueVolumeId = LastUniqueVolumeId++;
2242:
1.1.1.4 root 2243: if (mount->bMountManager)
2244: MountManagerMount (mount);
2245:
1.1.1.6 root 2246: NewExtension->bMountManager = mount->bMountManager;
1.1.1.4 root 2247:
1.1.1.6 root 2248: // We create symbolic link even if mount manager is notified of
2249: // arriving volume as it apparently sometimes fails to create the link
2250: CreateDriveLink (mount->nDosDriveNo);
1.1.1.4 root 2251: }
2252: else
2253: {
2254: Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode);
2255: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
2256: }
2257:
2258: return STATUS_SUCCESS;
2259: }
2260: }
2261: }
2262:
2263: NTSTATUS
2264: UnmountDevice (PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles)
2265: {
2266: PEXTENSION extension = deviceObject->DeviceExtension;
2267: NTSTATUS ntStatus;
2268: HANDLE volumeHandle;
2269: PFILE_OBJECT volumeFileObject;
2270:
1.1.1.8 root 2271: Dump ("UnmountDevice %d\n", extension->nDosDriveNo);
2272:
1.1.1.4 root 2273: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
2274: if (!NT_SUCCESS (ntStatus))
1.1.1.6 root 2275: {
2276: // User may have deleted symbolic link
2277: CreateDriveLink (extension->nDosDriveNo);
2278:
2279: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
2280: }
2281:
1.1.1.8 root 2282: if (NT_SUCCESS (ntStatus))
2283: {
2284: // Lock volume
2285: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
2286: Dump ("FSCTL_LOCK_VOLUME returned %X\n", ntStatus);
2287:
2288: if (!NT_SUCCESS (ntStatus) && !ignoreOpenFiles)
2289: {
2290: TCCloseFsVolume (volumeHandle, volumeFileObject);
2291: return ERR_FILES_OPEN;
2292: }
1.1.1.4 root 2293:
1.1.1.8 root 2294: // Dismount volume
2295: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
2296: Dump ("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus);
2297: }
2298: else
1.1.1.4 root 2299: {
1.1.1.8 root 2300: // Volume cannot be opened => force dismount if allowed
2301: if (!ignoreOpenFiles)
2302: return ERR_FILES_OPEN;
2303: else
2304: volumeHandle = NULL;
1.1.1.4 root 2305: }
2306:
2307: if (extension->bMountManager)
2308: MountManagerUnmount (extension->nDosDriveNo);
1.1.1.8 root 2309:
1.1.1.6 root 2310: // We always remove symbolic link as mount manager might fail to do so
2311: RemoveDriveLink (extension->nDosDriveNo);
1.1.1.4 root 2312:
1.1.1.10 root 2313: extension->bShuttingDown = TRUE;
2314:
1.1.1.8 root 2315: if (volumeHandle != NULL)
2316: TCCloseFsVolume (volumeHandle, volumeFileObject);
1.1.1.4 root 2317:
2318: TCDeleteDeviceObject (deviceObject, (PEXTENSION) deviceObject->DeviceExtension);
2319: return 0;
2320: }
2321:
2322: NTSTATUS
1.1.1.12 root 2323: UnmountAllDevices (PDEVICE_OBJECT DeviceObject, BOOL ignoreOpenFiles)
1.1.1.4 root 2324: {
2325: NTSTATUS status = 0;
2326: PDEVICE_OBJECT ListDevice;
2327:
2328: Dump ("Unmounting all volumes\n");
2329:
1.1.1.9 root 2330: if (!DeviceObject || !DeviceObject->DriverObject)
2331: return STATUS_INVALID_PARAMETER;
2332:
1.1.1.5 root 2333: DriverMutexWait ();
2334:
1.1.1.10 root 2335: ListDevice = DeviceObject->DriverObject->DeviceObject;
2336: while (ListDevice != NULL)
1.1.1.4 root 2337: {
2338: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.12 root 2339: if (!ListExtension->bRootDevice && !ListExtension->IsDriveFilterDevice && !ListExtension->bShuttingDown)
1.1.1.4 root 2340: {
1.1.1.12 root 2341: PDEVICE_OBJECT nextDevice = ListDevice->NextDevice;
1.1.1.10 root 2342:
1.1.1.12 root 2343: NTSTATUS ntStatus = UnmountDevice (ListDevice, ignoreOpenFiles);
2344: status = ntStatus == 0 ? status : ntStatus;
1.1.1.10 root 2345:
1.1.1.12 root 2346: ListDevice = nextDevice;
2347: continue;
1.1.1.4 root 2348: }
1.1.1.8 root 2349:
1.1.1.10 root 2350: ListDevice = ListDevice->NextDevice;
1.1.1.4 root 2351: }
2352:
1.1.1.5 root 2353: DriverMutexRelease ();
2354:
1.1.1.4 root 2355: return status;
2356: }
2357:
2358: // Resolves symbolic link name to its target name
2359: NTSTATUS
2360: SymbolicLinkToTarget (PWSTR symlinkName, PWSTR targetName, USHORT maxTargetNameLength)
2361: {
2362: NTSTATUS ntStatus;
2363: OBJECT_ATTRIBUTES objectAttributes;
2364: UNICODE_STRING fullFileName;
2365: HANDLE handle;
2366:
2367: RtlInitUnicodeString (&fullFileName, symlinkName);
2368: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
2369:
2370: ntStatus = ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes);
2371:
2372: if (NT_SUCCESS (ntStatus))
2373: {
2374: UNICODE_STRING target;
2375: target.Buffer = targetName;
2376: target.Length = 0;
2377: target.MaximumLength = maxTargetNameLength;
2378: memset (targetName, 0, maxTargetNameLength);
2379:
2380: ntStatus = ZwQuerySymbolicLinkObject (handle, &target, NULL);
2381:
2382: ZwClose (handle);
2383: }
2384:
2385: return ntStatus;
2386: }
1.1.1.6 root 2387:
2388: // Checks if two regions overlap (borders are parts of regions)
2389: BOOL RegionsOverlap (unsigned __int64 start1, unsigned __int64 end1, unsigned __int64 start2, unsigned __int64 end2)
2390: {
2391: return (start1 < start2) ? (end1 >= start2) : (start1 <= end2);
2392: }
1.1.1.12 root 2393:
2394:
2395: void GetIntersection (uint64 start1, uint32 length1, uint64 start2, uint64 end2, uint64 *intersectStart, uint32 *intersectLength)
2396: {
2397: uint64 end1 = start1 + length1 - 1;
2398: uint64 intersectEnd = (end1 <= end2) ? end1 : end2;
2399:
2400: *intersectStart = (start1 >= start2) ? start1 : start2;
2401: *intersectLength = (uint32) ((*intersectStart > intersectEnd) ? 0 : intersectEnd + 1 - *intersectStart);
2402:
2403: if (*intersectLength == 0)
2404: *intersectStart = start1;
2405: }
2406:
2407:
2408: BOOL IsAccessibleByUser (PUNICODE_STRING objectFileName, BOOL readOnly)
2409: {
2410: OBJECT_ATTRIBUTES fileObjAttributes;
2411: IO_STATUS_BLOCK ioStatusBlock;
2412: HANDLE fileHandle;
2413: NTSTATUS status;
2414:
2415: ASSERT (!IoIsSystemThread (PsGetCurrentThread()));
2416:
2417: InitializeObjectAttributes (&fileObjAttributes, objectFileName, OBJ_CASE_INSENSITIVE | OBJ_FORCE_ACCESS_CHECK, NULL, NULL);
2418:
2419: status = ZwCreateFile (&fileHandle,
2420: readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
2421: &fileObjAttributes,
2422: &ioStatusBlock,
2423: NULL,
2424: FILE_ATTRIBUTE_NORMAL,
2425: FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
2426: FILE_OPEN,
2427: FILE_SYNCHRONOUS_IO_NONALERT,
2428: NULL,
2429: 0);
2430:
2431: if (NT_SUCCESS (status))
2432: {
2433: ZwClose (fileHandle);
2434: return TRUE;
2435: }
2436:
2437: return FALSE;
2438: }
2439:
2440:
1.1.1.14! root 2441: BOOL UserCanAccessDriveDevice ()
! 2442: {
! 2443: UNICODE_STRING name;
! 2444: RtlInitUnicodeString (&name, L"\\Device\\MountPointManager");
! 2445:
! 2446: return IsAccessibleByUser (&name, FALSE);
! 2447: }
! 2448:
! 2449:
1.1.1.12 root 2450: NTSTATUS TCCompleteIrp (PIRP irp, NTSTATUS status, ULONG_PTR information)
2451: {
2452: irp->IoStatus.Status = status;
2453: irp->IoStatus.Information = information;
2454: IoCompleteRequest (irp, IO_NO_INCREMENT);
2455: return status;
2456: }
2457:
2458:
2459: NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information)
2460: {
2461: irp->IoStatus.Status = status;
2462: irp->IoStatus.Information = information;
2463: IoCompleteRequest (irp, NT_SUCCESS (status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
2464: return status;
2465: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.