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