|
|
1.1.1.10 root 1: /*
2: Legal Notice: The source code contained in this file has been derived from
3: the source code of Encryption for the Masses 2.02a, which is Copyright (c)
4: Paul Le Roux and which is covered by the 'License Agreement for Encryption
5: for the Masses'. Modifications and additions to that source code contained
6: in this file are Copyright (c) TrueCrypt Foundation and are covered by the
1.1.1.11! root 7: TrueCrypt License 2.3 the full text of which is contained in the file
1.1.1.10 root 8: License.txt included in TrueCrypt binary and source code distribution
9: packages. */
1.1 root 10:
11: #include "TCdefs.h"
1.1.1.6 root 12: #include "Crypto.h"
13: #include "Fat.h"
14: #include "Tests.h"
15:
16: #include "Apidrvr.h"
17: #include "Ntdriver.h"
18: #include "Ntvol.h"
19: #include "Cache.h"
1.1 root 20:
21: #include <tchar.h>
22: #include <initguid.h>
23: #include <mountmgr.h>
24: #include <mountdev.h>
25: #include <ntddvol.h>
26:
27: /* Init section, which is thrown away as soon as DriverEntry returns */
28: #pragma alloc_text(INIT,DriverEntry)
29: #pragma alloc_text(INIT,TCCreateRootDeviceObject)
30:
1.1.1.6 root 31: KMUTEX driverMutex; /* Sync mutex for the entire driver */
32: BOOL SelfTestsPassed;
33: int LastUniqueVolumeId;
1.1.1.10 root 34: ULONG OsMajorVersion;
1.1.1.11! root 35: BOOL ReferencedDeviceDeleted = FALSE;
1.1 root 36:
37: /* DriverEntry initialize's the dispatch addresses to be passed back to NT.
38: RUNS AT IRQL = PASSIVE_LEVEL(0) */
39: NTSTATUS
40: DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
41: {
42: if (RegistryPath); /* Remove warning */
43:
44: DriverObject->MajorFunction[IRP_MJ_CREATE] = TCDispatchQueueIRP;
45: DriverObject->MajorFunction[IRP_MJ_CLOSE] = TCDispatchQueueIRP;
46: DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TCDispatchQueueIRP;
47: DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = TCDispatchQueueIRP;
48: DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = TCDispatchQueueIRP;
1.1.1.8 root 49: DriverObject->MajorFunction[IRP_MJ_PNP] = TCDispatchQueueIRP;
1.1 root 50: DriverObject->MajorFunction[IRP_MJ_READ] = TCDispatchQueueIRP;
51: DriverObject->MajorFunction[IRP_MJ_WRITE] = TCDispatchQueueIRP;
52: DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TCDispatchQueueIRP;
53:
54: DriverObject->DriverUnload = TCUnloadDriver;
55:
56: KeInitializeMutex (&driverMutex, 1);
1.1.1.10 root 57: PsGetVersion (&OsMajorVersion, NULL, NULL, NULL);
1.1 root 58:
1.1.1.6 root 59: SelfTestsPassed = AutoTestAlgorithms ();
60:
1.1 root 61: return TCCreateRootDeviceObject (DriverObject);
62: }
63:
64: #ifdef _DEBUG
65: // Dumps a memory region to debug output
1.1.1.4 root 66: void DumpMem(void *mem, int len)
1.1 root 67: {
68: unsigned char str[20];
69: unsigned char *m = mem;
70: int i,j;
71:
1.1.1.4 root 72: for (j=0; j<len/8; j++)
1.1 root 73: {
74: memset (str,0,sizeof str);
1.1.1.4 root 75: for (i=0; i<8; i++)
1.1 root 76: {
77: if (m[i] > ' ' && m[i] < '~')
78: str[i]=m[i];
79: else
80: str[i]='.';
81: }
82:
1.1.1.4 root 83: Dump ("0x%08x %02x %02x %02x %02x %02x %02x %02x %02x %s\n",
1.1 root 84: m, m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], str);
85:
86: m+=8;
87: }
88: }
89: #endif
90:
91: /* TCDispatchQueueIRP queues any IRP's so that they can be processed later
92: by the thread -- or in some cases handles them immediately! */
93: NTSTATUS
94: TCDispatchQueueIRP (PDEVICE_OBJECT DeviceObject, PIRP Irp)
95: {
96: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
97: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
98: NTSTATUS ntStatus;
99:
100: #ifdef _DEBUG
1.1.1.10 root 101: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL
102: && irpSp->Parameters.DeviceIoControl.IoControlCode != MOUNT_LIST
103: && irpSp->Parameters.DeviceIoControl.IoControlCode != CACHE_STATUS)
104: {
105: Dump ("TCDispatchQueueIRP: %ls 0x%08x\n",
1.1 root 106: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode),
107: (int) irpSp->Parameters.DeviceIoControl.IoControlCode);
1.1.1.10 root 108: }
109: #ifdef EXTRA_INFO
110: else
111: Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x\n",
112: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction);
113: #endif
1.1 root 114: #endif
115:
1.1.1.10 root 116: if (!Extension->bRootDevice && Extension->bShuttingDown
117: && (irpSp->MajorFunction == IRP_MJ_READ
118: || irpSp->MajorFunction == IRP_MJ_WRITE
119: || irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL
120: || irpSp->MajorFunction == IRP_MJ_FLUSH_BUFFERS))
1.1 root 121: {
1.1.1.11! root 122: Dump ("Device %d shutting down: STATUS_DEVICE_NOT_READY\n", Extension->nDosDriveNo);
! 123: Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
1.1.1.10 root 124: Irp->IoStatus.Information = 0;
1.1 root 125:
1.1.1.10 root 126: ntStatus = Irp->IoStatus.Status;
127: IoCompleteRequest (Irp, IO_NO_INCREMENT);
128:
129: return ntStatus;
1.1 root 130: }
131:
132: switch (irpSp->MajorFunction)
133: {
134: case IRP_MJ_CLOSE:
135: case IRP_MJ_CREATE:
136: case IRP_MJ_CLEANUP:
137: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
138:
139: case IRP_MJ_SHUTDOWN:
1.1.1.6 root 140: if (Extension->bRootDevice)
1.1.1.8 root 141: UnmountAllDevices (DeviceObject, TRUE, FALSE, TRUE);
1.1.1.4 root 142:
143: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
144:
1.1 root 145: case IRP_MJ_FLUSH_BUFFERS:
146: case IRP_MJ_READ:
147: case IRP_MJ_WRITE:
148: case IRP_MJ_DEVICE_CONTROL:
149: if (Extension->bRootDevice == FALSE)
150: {
151:
152: IoMarkIrpPending (Irp);
153:
154: ExInterlockedInsertTailList (
155: &Extension->ListEntry,
156: &Irp->Tail.Overlay.ListEntry,
157: &Extension->ListSpinLock);
158:
159: KeReleaseSemaphore (
160: &Extension->RequestSemaphore,
161: (KPRIORITY) 0,
162: 1,
163: FALSE);
164:
1.1.1.10 root 165: #if EXTRA_INFO
166: Dump ("TCDispatchQueueIRP STATUS_PENDING END\n");
1.1 root 167: #endif
1.1.1.10 root 168:
1.1 root 169: return STATUS_PENDING;
170: }
171: else
172: {
173: if (irpSp->Parameters.DeviceIoControl.IoControlCode >= TC_FIRST_PRIVATE &&
174: irpSp->Parameters.DeviceIoControl.IoControlCode <= TC_LAST_PRIVATE)
175: {
1.1.1.10 root 176: return TCDeviceControl (DeviceObject, Extension, Irp);
1.1 root 177: }
178:
1.1.1.4 root 179: if (irpSp->MajorFunction == IRP_MJ_FLUSH_BUFFERS)
1.1 root 180: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
181: }
182:
183: return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0);
1.1.1.8 root 184:
185: case IRP_MJ_PNP:
186: if (irpSp->MinorFunction == IRP_MN_DEVICE_USAGE_NOTIFICATION)
187: {
188: if (!Extension->bRootDevice && Extension->bSystemVolume)
189: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
190:
191: return COMPLETE_IRP (DeviceObject, Irp, STATUS_UNSUCCESSFUL, 0);
192: }
1.1 root 193: }
194:
195: #ifdef _DEBUG
196: Dump ("ERROR: Unknown irpSp->MajorFunction in TCDispatchQueueIRP %ls 0x%08x END\n",
197: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction);
198: #endif
199:
200: return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0);
201: }
202:
203: NTSTATUS
204: TCCreateRootDeviceObject (PDRIVER_OBJECT DriverObject)
205: {
206: UNICODE_STRING Win32NameString, ntUnicodeString;
207: WCHAR dosname[32], ntname[32];
208: PDEVICE_OBJECT DeviceObject;
209: NTSTATUS ntStatus;
210: BOOL *bRootExtension;
211:
212: Dump ("TCCreateRootDeviceObject BEGIN\n");
213:
214: wcscpy (dosname, (LPWSTR) DOS_ROOT_PREFIX);
215: wcscpy (ntname, (LPWSTR) NT_ROOT_PREFIX);
216: RtlInitUnicodeString (&ntUnicodeString, ntname);
217: RtlInitUnicodeString (&Win32NameString, dosname);
218:
219: Dump ("Creating root device nt=%ls dos=%ls\n", ntname, dosname);
1.1.1.3 root 220:
1.1 root 221: ntStatus = IoCreateDevice (
222: DriverObject, /* Our Driver Object */
223: sizeof (BOOL), /* Size of state information */
224: &ntUnicodeString, /* Device name "\Device\Name" */
1.1.1.3 root 225: FILE_DEVICE_UNKNOWN, /* Device type */
1.1 root 226: 0, /* Device characteristics */
227: FALSE, /* Exclusive device */
228: &DeviceObject); /* Returned ptr to Device Object */
229:
230: if (!NT_SUCCESS (ntStatus))
231: {
232: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
233: return ntStatus;/* Failed to create DeviceObject */
234: }
235:
236: DeviceObject->Flags |= DO_DIRECT_IO;
237: DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
238:
239: /* Setup the device extension */
240: bRootExtension = (BOOL *) DeviceObject->DeviceExtension;
241: *bRootExtension = TRUE;
242:
243: /* The symlinks for mount devices are created from user-mode */
244: ntStatus = IoCreateSymbolicLink (&Win32NameString, &ntUnicodeString);
1.1.1.4 root 245:
1.1 root 246: if (!NT_SUCCESS (ntStatus))
247: {
248: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
249: IoDeleteDevice (DeviceObject);
250: return ntStatus;
251: }
252:
1.1.1.4 root 253: IoRegisterShutdownNotification (DeviceObject);
254:
1.1 root 255: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
256: Dump ("TCCreateRootDeviceObject STATUS_SUCCESS END\n");
257: return STATUS_SUCCESS;
258: }
259:
260: NTSTATUS
261: TCCreateDeviceObject (PDRIVER_OBJECT DriverObject,
262: PDEVICE_OBJECT * ppDeviceObject,
1.1.1.4 root 263: MOUNT_STRUCT * mount)
1.1 root 264: {
265: UNICODE_STRING Win32NameString, ntUnicodeString;
266: WCHAR dosname[32], ntname[32];
267: PEXTENSION Extension;
268: NTSTATUS ntStatus;
1.1.1.4 root 269: ULONG devChars = 0;
1.1 root 270:
271: Dump ("TCCreateDeviceObject BEGIN\n");
272:
1.1.1.4 root 273: TCGetDosNameFromNumber (dosname, mount->nDosDriveNo);
274: TCGetNTNameFromNumber (ntname, mount->nDosDriveNo);
1.1 root 275: RtlInitUnicodeString (&ntUnicodeString, ntname);
276: RtlInitUnicodeString (&Win32NameString, dosname);
277:
1.1.1.4 root 278: devChars = mount->bMountReadOnly ? FILE_READ_ONLY_DEVICE : 0;
279: devChars |= mount->bMountRemovable ? FILE_REMOVABLE_MEDIA : 0;
280:
1.1 root 281: Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname);
282:
283: ntStatus = IoCreateDevice (
284: DriverObject, /* Our Driver Object */
285: sizeof (EXTENSION), /* Size of state information */
286: &ntUnicodeString, /* Device name "\Device\Name" */
287: FILE_DEVICE_DISK, /* Device type */
1.1.1.4 root 288: devChars, /* Device characteristics */
1.1 root 289: FALSE, /* Exclusive device */
290: ppDeviceObject); /* Returned ptr to Device Object */
291:
292: if (!NT_SUCCESS (ntStatus))
293: {
294: Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
295: return ntStatus;/* Failed to create DeviceObject */
296: }
297: /* Initialize device object and extension. */
298:
299: (*ppDeviceObject)->Flags |= DO_DIRECT_IO;
300: (*ppDeviceObject)->AlignmentRequirement = FILE_WORD_ALIGNMENT;
301:
302: /* Setup the device extension */
303: Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension;
304: memset (Extension, 0, sizeof (EXTENSION));
305:
306: Extension->lMagicNumber = 0xabfeacde;
1.1.1.4 root 307: Extension->nDosDriveNo = mount->nDosDriveNo;
308: Extension->bRemovable = mount->bMountRemovable;
1.1 root 309:
310: KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE);
311: KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG);
312: KeInitializeSpinLock (&Extension->ListSpinLock);
313: InitializeListHead (&Extension->ListEntry);
314:
315: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
316: Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n");
317:
318: return STATUS_SUCCESS;
319: }
320:
1.1.1.5 root 321:
322: void DriverMutexWait ()
323: {
324: KeWaitForMutexObject (&driverMutex, Executive, KernelMode, FALSE, NULL);
325: }
326:
327:
328: void DriverMutexRelease ()
329: {
330: KeReleaseMutex (&driverMutex, FALSE);
331: }
332:
333:
1.1 root 334: /* TCDeviceControl handles certain requests from NT, these are needed for NT
1.1.1.4 root 335: to recognize the drive, also this function handles our device specific
1.1 root 336: function codes, such as mount/unmount */
337: NTSTATUS
338: TCDeviceControl (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
339: {
340: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
341: NTSTATUS ntStatus;
342:
343: #ifdef _DEBUG
1.1.1.10 root 344: BOOL suppressDebug = FALSE;
345:
346: if (irpSp->Parameters.DeviceIoControl.IoControlCode == MOUNT_LIST
347: || irpSp->Parameters.DeviceIoControl.IoControlCode == CACHE_STATUS)
348: suppressDebug = TRUE;
1.1 root 349: #endif
350:
351: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; /* Assume failure. */
352:
353: /* Determine which I/O control code was specified. */
354: switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
355: {
356:
357: case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
358: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_NAME))
359: {
360: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
361: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
362: }
363: else
364: {
365: ULONG outLength;
366: UNICODE_STRING ntUnicodeString;
1.1.1.7 root 367: WCHAR ntName[256];
1.1 root 368: PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer;
369:
370: TCGetNTNameFromNumber (ntName, Extension->nDosDriveNo);
371: RtlInitUnicodeString (&ntUnicodeString, ntName);
372:
373: outputBuffer->NameLength = ntUnicodeString.Length;
374: outLength = ntUnicodeString.Length + sizeof(USHORT);
375:
376: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
377: {
378: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
379: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
380:
381: break;
382: }
383:
384: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
385:
386: Irp->IoStatus.Status = STATUS_SUCCESS;
387: Irp->IoStatus.Information = outLength;
388:
389: Dump ("name = %ls\n",ntName);
390: }
391: break;
392:
393: case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
394: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_UNIQUE_ID))
395: {
396: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
397: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
398: }
399: else
400: {
401: ULONG outLength;
402: UCHAR volId[128], tmp[] = { 0,0 };
403: PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer;
404:
405: strcpy (volId, TC_UNIQUE_ID_PREFIX);
406: tmp[0] = 'A' + Extension->nDosDriveNo;
407: strcat (volId, tmp);
408:
1.1.1.6 root 409: outputBuffer->UniqueIdLength = (USHORT) strlen (volId);
410: outLength = strlen (volId) + sizeof(USHORT);
1.1 root 411:
412: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
413: {
414: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
415: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
416: break;
417: }
418:
1.1.1.6 root 419: RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen (volId));
1.1 root 420:
421: Irp->IoStatus.Status = STATUS_SUCCESS;
422: Irp->IoStatus.Information = outLength;
423:
424: Dump ("id = %s\n",volId);
425: }
426: break;
427:
428: case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
429: {
430: ULONG outLength;
431: UNICODE_STRING ntUnicodeString;
1.1.1.7 root 432: WCHAR ntName[256];
1.1 root 433: PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer;
434:
435: TCGetDosNameFromNumber (ntName, Extension->nDosDriveNo);
436: RtlInitUnicodeString (&ntUnicodeString, ntName);
437:
438: outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length;
439:
440: outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE;
441: outputBuffer->NameLength = ntUnicodeString.Length;
442:
443: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
444: {
445: Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME);
446: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
447: break;
448: }
449:
450: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
451:
452: Irp->IoStatus.Status = STATUS_SUCCESS;
453: Irp->IoStatus.Information = outLength;
454:
455: Dump ("link = %ls\n",ntName);
456: }
457: break;
458:
1.1.1.4 root 459:
1.1 root 460: case IOCTL_DISK_GET_MEDIA_TYPES:
461: case IOCTL_DISK_GET_DRIVE_GEOMETRY:
462: /* Return the drive geometry for the disk. Note that we
463: return values which were made up to suit the disk size. */
464: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
465: sizeof (DISK_GEOMETRY))
466: {
1.1.1.11! root 467: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 468: Irp->IoStatus.Information = 0;
469: }
470: else
471: {
472: PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY)
473: Irp->AssociatedIrp.SystemBuffer;
474:
1.1.1.4 root 475: outputBuffer->MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia;
1.1 root 476: outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders;
477: outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder;
478: outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack;
479: outputBuffer->BytesPerSector = Extension->BytesPerSector;
480: Irp->IoStatus.Status = STATUS_SUCCESS;
481: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY);
482: }
483: break;
484:
485: case IOCTL_DISK_GET_PARTITION_INFO:
486: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
487: sizeof (PARTITION_INFORMATION))
488: {
1.1.1.11! root 489: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 490: Irp->IoStatus.Information = 0;
491: }
492: else
493: {
494: PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION)
495: Irp->AssociatedIrp.SystemBuffer;
496:
497: outputBuffer->PartitionType = Extension->PartitionType;
498: outputBuffer->BootIndicator = FALSE;
499: outputBuffer->RecognizedPartition = TRUE;
500: outputBuffer->RewritePartition = FALSE;
1.1.1.11! root 501: outputBuffer->StartingOffset.QuadPart = SECTOR_SIZE;
1.1 root 502: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength;
1.1.1.11! root 503: outputBuffer->HiddenSectors = 0;
1.1 root 504: Irp->IoStatus.Status = STATUS_SUCCESS;
505: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION);
506: }
507: break;
1.1.1.10 root 508:
509: case IOCTL_DISK_GET_PARTITION_INFO_EX:
510: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (PARTITION_INFORMATION_EX))
511: {
1.1.1.11! root 512: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.10 root 513: Irp->IoStatus.Information = 0;
514: }
515: else
516: {
517: PPARTITION_INFORMATION_EX outputBuffer = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer;
518:
519: outputBuffer->PartitionStyle = PARTITION_STYLE_MBR;
520: outputBuffer->RewritePartition = FALSE;
1.1.1.11! root 521: outputBuffer->StartingOffset.QuadPart = SECTOR_SIZE;
1.1.1.10 root 522: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength;
523: outputBuffer->Mbr.PartitionType = Extension->PartitionType;
524: outputBuffer->Mbr.BootIndicator = FALSE;
525: outputBuffer->Mbr.RecognizedPartition = TRUE;
1.1.1.11! root 526: outputBuffer->Mbr.HiddenSectors = 0;
1.1.1.10 root 527: Irp->IoStatus.Status = STATUS_SUCCESS;
528: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION_EX);
529: }
530: break;
531:
1.1.1.6 root 532: case IOCTL_DISK_GET_DRIVE_LAYOUT:
533: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
534: sizeof (DRIVE_LAYOUT_INFORMATION))
535: {
1.1.1.11! root 536: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.6 root 537: Irp->IoStatus.Information = 0;
538: }
539: else
540: {
541: PDRIVE_LAYOUT_INFORMATION outputBuffer = (PDRIVE_LAYOUT_INFORMATION)
542: Irp->AssociatedIrp.SystemBuffer;
543:
544: outputBuffer->PartitionCount = 1;
545: outputBuffer->Signature = 0;
546:
547: outputBuffer->PartitionEntry->PartitionType = Extension->PartitionType;
548: outputBuffer->PartitionEntry->BootIndicator = FALSE;
549: outputBuffer->PartitionEntry->RecognizedPartition = TRUE;
550: outputBuffer->PartitionEntry->RewritePartition = FALSE;
1.1.1.11! root 551: outputBuffer->PartitionEntry->StartingOffset.QuadPart = SECTOR_SIZE;
! 552: outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength;
! 553: outputBuffer->PartitionEntry->HiddenSectors = 0;
1.1.1.6 root 554:
555: Irp->IoStatus.Status = STATUS_SUCCESS;
556: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION);
557: }
558: break;
559:
1.1 root 560: case IOCTL_DISK_GET_LENGTH_INFO:
561: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GET_LENGTH_INFORMATION))
562: {
563: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
564: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
565: }
566: else
567: {
568: PGET_LENGTH_INFORMATION outputBuffer = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
569:
570: outputBuffer->Length.QuadPart = Extension->DiskLength;
571: Irp->IoStatus.Status = STATUS_SUCCESS;
572: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
573: }
574: break;
575:
576: case IOCTL_DISK_VERIFY:
577: {
578: PVERIFY_INFORMATION pVerifyInformation;
579: pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
580: irpSp->Parameters.Read.ByteOffset.LowPart =
581: pVerifyInformation->StartingOffset.LowPart;
582: irpSp->Parameters.Read.ByteOffset.HighPart =
583: pVerifyInformation->StartingOffset.HighPart;
584: irpSp->Parameters.Read.Length = pVerifyInformation->Length;
585: Irp->IoStatus.Status = STATUS_SUCCESS;
586: Irp->IoStatus.Information = pVerifyInformation->Length;
587: }
588: break;
589:
590: case IOCTL_DISK_CHECK_VERIFY:
1.1.1.6 root 591: case IOCTL_STORAGE_CHECK_VERIFY:
1.1 root 592: {
593: Irp->IoStatus.Status = STATUS_SUCCESS;
594: Irp->IoStatus.Information = 0;
595: }
596: break;
597:
598: case IOCTL_DISK_IS_WRITABLE:
599: {
1.1.1.6 root 600: if (Extension->bReadOnly)
1.1 root 601: Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
602: else
603: Irp->IoStatus.Status = STATUS_SUCCESS;
604: Irp->IoStatus.Information = 0;
605:
606: }
607: break;
608:
1.1.1.5 root 609: // Private IOCTLs
610:
1.1 root 611: case DRIVER_VERSION:
1.1.1.6 root 612: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (LONG))
1.1 root 613: {
1.1.1.11! root 614: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 615: Irp->IoStatus.Information = 0;
616: }
617: else
618: {
619: LONG tmp = VERSION_NUM;
620: memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4);
1.1.1.6 root 621: Irp->IoStatus.Information = sizeof (LONG);
1.1 root 622: Irp->IoStatus.Status = STATUS_SUCCESS;
623: }
624: break;
625:
1.1.1.6 root 626: case DEVICE_REFCOUNT:
627: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
1.1 root 628: {
1.1.1.11! root 629: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 630: Irp->IoStatus.Information = 0;
631: }
632: else
633: {
1.1.1.6 root 634: *(int *) Irp->AssociatedIrp.SystemBuffer = DeviceObject->ReferenceCount;
635: Irp->IoStatus.Information = sizeof (int);
636: Irp->IoStatus.Status = STATUS_SUCCESS;
637: }
638: break;
639:
1.1.1.11! root 640: case REFERENCED_DEV_DELETED:
! 641: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
! 642: {
! 643: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
! 644: Irp->IoStatus.Information = 0;
! 645: }
! 646: else
! 647: {
! 648: *(int *) Irp->AssociatedIrp.SystemBuffer = ReferencedDeviceDeleted;
! 649: Irp->IoStatus.Information = sizeof (int);
! 650: Irp->IoStatus.Status = STATUS_SUCCESS;
! 651: }
! 652: break;
! 653:
1.1.1.6 root 654: case OPEN_TEST:
655: {
1.1 root 656: OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
657: OBJECT_ATTRIBUTES ObjectAttributes;
658: HANDLE NtFileHandle;
659: UNICODE_STRING FullFileName;
660: IO_STATUS_BLOCK IoStatus;
661:
662: RtlInitUnicodeString (&FullFileName, opentest->wszFileName);
663:
664: InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE,
665: NULL, NULL);
666:
667: ntStatus = ZwCreateFile (&NtFileHandle,
668: SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none */ ,
1.1.1.4 root 669: FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT |
1.1 root 670: FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS,
671: NULL /* eabuffer */ , 0 /* ealength */ );
672:
673: if (NT_SUCCESS (ntStatus))
674: {
675: ZwClose (NtFileHandle);
676: Dump ("Open test on file %ls success.\n", opentest->wszFileName);
677: }
678: else
679: {
680: Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus);
681: }
682:
683: Irp->IoStatus.Information = 0;
684: Irp->IoStatus.Status = ntStatus;
685: }
686: break;
687:
688: case WIPE_CACHE:
1.1.1.5 root 689: DriverMutexWait ();
1.1 root 690: WipeCache ();
1.1.1.5 root 691: DriverMutexRelease ();
1.1 root 692:
693: Irp->IoStatus.Status = STATUS_SUCCESS;
694: Irp->IoStatus.Information = 0;
695: break;
696:
697: case CACHE_STATUS:
698: Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS;
699: Irp->IoStatus.Information = 0;
700: break;
701:
702: #ifdef DEBUG
703: case HALT_SYSTEM:
704: KeBugCheck ((ULONG) 0x5050);
705: break;
706: #endif
707:
708: case MOUNT_LIST:
1.1.1.11! root 709: case MOUNT_LIST_ALL:
1.1.1.9 root 710: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT)
711: || !DeviceObject || !DeviceObject->DriverObject)
1.1 root 712: {
1.1.1.11! root 713: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 714: Irp->IoStatus.Information = 0;
715: }
716: else
717: {
718: MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
719: PDEVICE_OBJECT ListDevice;
1.1.1.11! root 720: BOOL listAll = (irpSp->Parameters.DeviceIoControl.IoControlCode == MOUNT_LIST_ALL);
1.1 root 721:
1.1.1.5 root 722: DriverMutexWait ();
723:
1.1 root 724: list->ulMountedDrives = 0;
725: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
726: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
727: {
728: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.6 root 729: if (ListExtension->lMagicNumber == 0xabfeacde
730: && ListExtension->bRootDevice == FALSE
1.1.1.11! root 731: && (listAll || (!ListExtension->bSystemVolume && !ListExtension->bPersistentVolume))
1.1.1.6 root 732: && !ListExtension->bShuttingDown)
1.1 root 733: {
734: list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo);
735: wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume);
736: list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength;
1.1.1.4 root 737: list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea;
1.1.1.6 root 738: if (ListExtension->cryptoInfo->hiddenVolume)
739: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_HIDDEN; // Hidden volume
740: else if (ListExtension->cryptoInfo->bHiddenVolProtectionAction)
741: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED; // Normal/outer volume (hidden volume protected AND write already prevented)
742: else if (ListExtension->cryptoInfo->bProtectHiddenVolume)
743: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER; // Normal/outer volume (hidden volume protected)
744: else
745: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_NORMAL; // Normal volume
1.1 root 746: }
747: }
748:
1.1.1.5 root 749: DriverMutexRelease ();
750:
1.1 root 751: Irp->IoStatus.Status = STATUS_SUCCESS;
752: Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT);
753: }
754: break;
755:
756: case VOLUME_PROPERTIES:
1.1.1.9 root 757: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT)
758: || !DeviceObject || !DeviceObject->DriverObject)
1.1 root 759: {
1.1.1.11! root 760: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 761: Irp->IoStatus.Information = 0;
762: }
763: else
764: {
765: VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
766: PDEVICE_OBJECT ListDevice;
767:
768: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
769: Irp->IoStatus.Information = 0;
770:
1.1.1.5 root 771: DriverMutexWait ();
772:
1.1 root 773: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
774: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
775: {
776:
777: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.6 root 778: if (ListExtension->bRootDevice == FALSE
779: && !ListExtension->bShuttingDown
780: && ListExtension->nDosDriveNo == prop->driveNo)
1.1 root 781: {
1.1.1.6 root 782: prop->uniqueId = ListExtension->UniqueVolumeId;
1.1 root 783: wcscpy (prop->wszVolume, ListExtension->wszVolume);
784: prop->diskLength = ListExtension->DiskLength;
1.1.1.4 root 785: prop->ea = ListExtension->cryptoInfo->ea;
1.1.1.7 root 786: prop->mode = ListExtension->cryptoInfo->mode;
1.1 root 787: prop->pkcs5 = ListExtension->cryptoInfo->pkcs5;
788: prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations;
789: prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time;
790: prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time;
1.1.1.6 root 791: prop->readOnly = ListExtension->bReadOnly;
1.1.1.4 root 792: prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume;
1.1.1.8 root 793: prop->systemVolume = ListExtension->bSystemVolume;
794: prop->persistentVolume = ListExtension->bPersistentVolume;
1.1 root 795:
1.1.1.6 root 796: if (ListExtension->cryptoInfo->bProtectHiddenVolume)
797: prop->hiddenVolProtection = ListExtension->cryptoInfo->bHiddenVolProtectionAction ? HIDVOL_PROT_STATUS_ACTION_TAKEN : HIDVOL_PROT_STATUS_ACTIVE;
798: else
799: prop->hiddenVolProtection = HIDVOL_PROT_STATUS_NONE;
800:
801: prop->totalBytesRead = ListExtension->TotalBytesRead;
802: prop->totalBytesWritten = ListExtension->TotalBytesWritten;
803:
1.1 root 804: Irp->IoStatus.Status = STATUS_SUCCESS;
805: Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT);
806: break;
807: }
808: }
1.1.1.5 root 809:
810: DriverMutexRelease ();
1.1 root 811: }
812: break;
813:
1.1.1.4 root 814: case RESOLVE_SYMLINK:
1.1.1.6 root 815: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (RESOLVE_SYMLINK_STRUCT))
1.1.1.4 root 816: {
1.1.1.11! root 817: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.4 root 818: Irp->IoStatus.Information = 0;
819: }
820: else
1.1 root 821: {
1.1.1.4 root 822: RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
823: {
824: NTSTATUS ntStatus;
825:
826: ntStatus = SymbolicLinkToTarget (resolve->symLinkName,
827: resolve->targetName,
828: sizeof (resolve->targetName));
829:
830: Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT);
831: Irp->IoStatus.Status = ntStatus;
832: }
833:
834: }
835: break;
836:
1.1.1.10 root 837: case DISK_GET_PARTITION_INFO:
838: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (DISK_PARTITION_INFO_STRUCT))
839: {
1.1.1.11! root 840: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.10 root 841: Irp->IoStatus.Information = 0;
842: }
843: else
844: {
845: DISK_PARTITION_INFO_STRUCT *info = (DISK_PARTITION_INFO_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
846: {
847: PARTITION_INFORMATION_EX pi;
848: NTSTATUS ntStatus;
849:
850: ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi));
851: if (NT_SUCCESS(ntStatus))
852: {
853: memset (&info->partInfo, 0, sizeof (info->partInfo));
854:
855: info->partInfo.PartitionLength = pi.PartitionLength;
856: info->partInfo.PartitionNumber = pi.PartitionNumber;
857: info->partInfo.StartingOffset = pi.StartingOffset;
858:
859: if (pi.PartitionStyle == PARTITION_STYLE_MBR)
860: info->partInfo.PartitionType = pi.Mbr.PartitionType;
861: }
862: else
863: {
864: // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX
865: ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &info->partInfo, sizeof (info->partInfo));
866: }
867:
868: Irp->IoStatus.Information = sizeof (DISK_PARTITION_INFO_STRUCT);
869: Irp->IoStatus.Status = ntStatus;
870: }
871:
872: }
873: break;
874:
875: case DISK_GET_GEOMETRY:
876: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (DISK_GEOMETRY_STRUCT))
877: {
1.1.1.11! root 878: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.10 root 879: Irp->IoStatus.Information = 0;
880: }
881: else
882: {
883: DISK_GEOMETRY_STRUCT *g = (DISK_GEOMETRY_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
884: {
885: NTSTATUS ntStatus;
886:
887: ntStatus = TCDeviceIoControl (g->deviceName,
888: IOCTL_DISK_GET_DRIVE_GEOMETRY,
889: NULL, 0, &g->diskGeometry, sizeof (g->diskGeometry));
890:
891: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_STRUCT);
892: Irp->IoStatus.Status = ntStatus;
893: }
894: }
895: break;
896:
1.1.1.4 root 897: case MOUNT:
898: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT))
899: {
1.1.1.11! root 900: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.4 root 901: Irp->IoStatus.Information = 0;
902: }
903: else
904: {
905: MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
906:
1.1.1.5 root 907: DriverMutexWait ();
1.1.1.6 root 908:
909: Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
1.1.1.4 root 910: Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
1.1.1.5 root 911: DriverMutexRelease ();
1.1.1.6 root 912:
913: burn (&mount->VolumePassword, sizeof (mount->VolumePassword));
914: burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword));
1.1 root 915: }
916: break;
917:
918: case UNMOUNT:
1.1.1.9 root 919: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT)
920: || !DeviceObject || !DeviceObject->DriverObject)
1.1 root 921: {
1.1.1.11! root 922: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 923: Irp->IoStatus.Information = 0;
924: }
925: else
926: {
927: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
928: PDEVICE_OBJECT ListDevice;
929:
930: unmount->nReturnCode = ERR_DRIVE_NOT_FOUND;
931:
932: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
933: ListDevice != (PDEVICE_OBJECT) NULL;
934: ListDevice = ListDevice->NextDevice)
935: {
936: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
937:
1.1.1.4 root 938: if (ListExtension->bRootDevice == FALSE
1.1.1.6 root 939: && !ListExtension->bShuttingDown
1.1.1.4 root 940: && unmount->nDosDriveNo == ListExtension->nDosDriveNo)
1.1 root 941: {
1.1.1.5 root 942: DriverMutexWait ();
1.1.1.4 root 943: unmount->nReturnCode = UnmountDevice (ListDevice, unmount->ignoreOpenFiles);
1.1.1.5 root 944: DriverMutexRelease ();
1.1.1.4 root 945: break;
1.1.1.8 root 946: }
1.1.1.4 root 947: }
1.1 root 948:
1.1.1.4 root 949: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
1.1 root 950: Irp->IoStatus.Status = STATUS_SUCCESS;
951: }
952: break;
953:
1.1.1.4 root 954: case UNMOUNT_ALL:
955: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
1.1 root 956: {
1.1.1.11! root 957: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1 root 958: Irp->IoStatus.Information = 0;
959: }
960: else
961: {
1.1.1.4 root 962: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1.1 root 963:
1.1.1.8 root 964: unmount->nReturnCode = UnmountAllDevices (DeviceObject, unmount->ignoreOpenFiles, FALSE, FALSE);
1.1 root 965:
1.1.1.4 root 966: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
967: Irp->IoStatus.Status = STATUS_SUCCESS;
1.1 root 968: }
969: break;
970: }
971:
972: /* Finish the I/O operation by simply completing the packet and
973: returning the same NTSTATUS as in the packet itself. */
974: ntStatus = COMPLETE_IRP (DeviceObject, Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
1.1.1.10 root 975:
976: #ifdef DEBUG
977: if (!suppressDebug)
978: Dump ("TCDeviceControl END: 0x%08x\n", ntStatus);
979: #endif
1.1 root 980: return ntStatus;
981: }
982:
1.1.1.6 root 983:
1.1 root 984: NTSTATUS
985: TCStartThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount)
986: {
987: PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK));
988: HANDLE hThread;
989: NTSTATUS ntStatus;
1.1.1.6 root 990: HANDLE process;
1.1 root 991:
992: Dump ("Starting thread...\n");
993:
994: if (pThreadBlock == NULL)
995: {
996: return STATUS_INSUFFICIENT_RESOURCES;
997: }
998: else
999: {
1000: pThreadBlock->DeviceObject = DeviceObject;
1001: pThreadBlock->mount = mount;
1002: }
1003:
1.1.1.6 root 1004: if (mount->bUserContext)
1005: {
1006: ntStatus = ObOpenObjectByPointer (IoGetCurrentProcess (), 0, NULL, 0, NULL, KernelMode, &process);
1007: if (!NT_SUCCESS (ntStatus))
1008: {
1009: Dump ("ObOpenObjectByPointer Failed\n");
1010: goto ret;
1011: }
1012: }
1013: else
1014: process = NULL;
1015:
1.1.1.8 root 1016: Extension->bSystemVolume = mount->bSystemVolume;
1017: Extension->bPersistentVolume = mount->bPersistentVolume;
1018:
1.1 root 1019: Extension->bThreadShouldQuit = FALSE;
1020:
1021: ntStatus = PsCreateSystemThread (&hThread,
1022: THREAD_ALL_ACCESS,
1023: NULL,
1.1.1.6 root 1024: process,
1.1 root 1025: NULL,
1026: TCThreadIRP,
1027: pThreadBlock);
1028:
1029: if (!NT_SUCCESS (ntStatus))
1030: {
1031: Dump ("PsCreateSystemThread Failed END\n");
1.1.1.6 root 1032: goto ret;
1.1 root 1033: }
1034:
1035: ObReferenceObjectByHandle (hThread,
1036: THREAD_ALL_ACCESS,
1037: NULL,
1038: KernelMode,
1039: &Extension->peThread,
1040: NULL);
1041: ZwClose (hThread);
1042:
1043: Dump ("Waiting for thread to initialize...\n");
1044:
1045: KeWaitForSingleObject (&Extension->keCreateEvent,
1046: UserRequest,
1047: UserMode,
1048: FALSE,
1049: NULL);
1050:
1051: Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus);
1052: ntStatus = pThreadBlock->ntCreateStatus;
1.1.1.6 root 1053:
1054: ret:
1.1 root 1055: TCfree (pThreadBlock);
1056: return ntStatus;
1057: }
1058:
1059: void
1060: TCStopThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1061: {
1062: NTSTATUS ntStatus;
1063:
1064: if (DeviceObject); /* Remove compiler warning */
1065:
1066: Dump ("Signalling thread to quit...\n");
1067:
1068: Extension->bThreadShouldQuit = TRUE;
1069:
1070: KeReleaseSemaphore (&Extension->RequestSemaphore,
1071: 0,
1072: 1,
1073: TRUE);
1074:
1.1.1.4 root 1075: ntStatus = KeWaitForSingleObject (Extension->peThread,
1.1 root 1076: UserRequest,
1077: UserMode,
1078: FALSE,
1079: NULL);
1080: if (ntStatus != STATUS_SUCCESS)
1081: Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n",
1082: ntStatus);
1083:
1.1.1.6 root 1084: ObDereferenceObject (Extension->peThread);
1.1 root 1085: Extension->peThread = NULL;
1086:
1087: Dump ("Thread exited!\n");
1088: }
1089:
1.1.1.5 root 1090:
1091: // Suspend current thread for a number of milliseconds
1092: void TCSleep (int milliSeconds)
1093: {
1094: PKTIMER timer = (PKTIMER) TCalloc (sizeof (KTIMER));
1095: LARGE_INTEGER duetime;
1096:
1097: duetime.QuadPart = (__int64) milliSeconds * -10000;
1098: KeInitializeTimerEx(timer, NotificationTimer);
1099: KeSetTimerEx(timer, duetime, 0, NULL);
1100:
1101: KeWaitForSingleObject (timer, UserRequest, UserMode, FALSE, NULL);
1102:
1103: TCfree (timer);
1104: }
1105:
1106:
1.1 root 1107: /* TCThreadIRP does all the work of processing IRP's, and dispatching them
1108: to either the ReadWrite function or the DeviceControl function */
1109: VOID
1110: TCThreadIRP (PVOID Context)
1111: {
1112: PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context;
1113: PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject;
1114: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
1115: LARGE_INTEGER queueWait;
1116: BOOL bDevice;
1117:
1118: /* Set thread priority to lowest realtime level. */
1119: KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY);
1120:
1121: queueWait.QuadPart = -WAIT_SECONDS (1);
1122:
1123: Dump ("Mount THREAD OPENING VOLUME BEGIN\n");
1124:
1125: if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0)
1126: {
1127: wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\"));
1.1.1.7 root 1128: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
1129: sizeof (pThreadBlock->wszMountVolume) / 2 - 5);
1.1 root 1130: bDevice = FALSE;
1131: }
1132: else
1133: {
1.1.1.8 root 1134: pThreadBlock->wszMountVolume[0] = 0;
1135: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
1.1.1.7 root 1136: sizeof (pThreadBlock->wszMountVolume) / 2 - 1);
1.1 root 1137: bDevice = TRUE;
1138: }
1139:
1140: Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n",
1141: pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice);
1142:
1143: pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject,
1.1.1.7 root 1144: Extension,
1145: pThreadBlock->mount,
1146: pThreadBlock->wszMountVolume,
1147: bDevice);
1.1 root 1148:
1149: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0)
1150: {
1151: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1152: PsTerminateSystemThread (STATUS_SUCCESS);
1153: }
1154: else
1155: {
1156: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1.1.1.10 root 1157: /* From this point on pThreadBlock cannot be used as it will have been released! */
1.1 root 1158: pThreadBlock = NULL;
1159: }
1160:
1161: for (;;)
1162: {
1163: NTSTATUS ntStatus;
1164:
1165: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1166:
1167: /* Wait for a request from the dispatch routines. */
1168: ntStatus = KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore,
1169: Executive, KernelMode, FALSE, &queueWait);
1170:
1171: if (ntStatus != STATUS_TIMEOUT)
1172: {
1173: for (;;)
1174: {
1175: PIO_STACK_LOCATION irpSp;
1176: PLIST_ENTRY request;
1177: PIRP Irp;
1178:
1179: request = ExInterlockedRemoveHeadList (&Extension->ListEntry,
1180: &Extension->ListSpinLock);
1181: if (request == NULL)
1182: break;
1183:
1184: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1185:
1186: Irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry);
1187: irpSp = IoGetCurrentIrpStackLocation (Irp);
1188:
1189: switch (irpSp->MajorFunction)
1190: {
1191: case IRP_MJ_READ:
1192: case IRP_MJ_WRITE:
1193: TCReadWrite (DeviceObject, Extension, Irp);
1194: break;
1195:
1196: case IRP_MJ_FLUSH_BUFFERS:
1197: case IRP_MJ_SHUTDOWN:
1198: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
1199: break;
1200:
1201: case IRP_MJ_DEVICE_CONTROL:
1.1.1.10 root 1202: TCDeviceControl (DeviceObject, Extension, Irp);
1.1 root 1203: break;
1.1.1.10 root 1204: }
1205: }
1.1 root 1206:
1207: if (Extension->bThreadShouldQuit)
1208: {
1209: Dump ("Closing volume along with Thread!\n");
1210: TCCloseVolume (DeviceObject, Extension);
1211: PsTerminateSystemThread (STATUS_SUCCESS);
1212: }
1213: }
1.1.1.10 root 1214: }
1.1 root 1215: }
1216:
1217: void
1218: TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)
1219: {
1220: WCHAR tmp[3] =
1221: {0, ':', 0};
1222: int j = nDriveNo + (WCHAR) 'A';
1223:
1224: tmp[0] = (short) j;
1225: wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
1226: wcsncat (ntname, tmp, 1);
1227: }
1228:
1229: void
1230: TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo)
1231: {
1232: WCHAR tmp[3] =
1233: {0, ':', 0};
1234: int j = nDriveNo + (WCHAR) 'A';
1235:
1236: tmp[0] = (short) j;
1237: wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX);
1238: wcscat (dosname, tmp);
1239: }
1240:
1241: #ifdef _DEBUG
1242: LPWSTR
1243: TCTranslateCode (ULONG ulCode)
1244: {
1245: if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY)
1246: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY");
1247: else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)
1248: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX");
1249: else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME)
1250: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME");
1251: else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME)
1252: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME");
1253: else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID)
1254: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID");
1255: else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY)
1256: return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY");
1257: else if (ulCode == IOCTL_VOLUME_ONLINE)
1258: return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE");
1259: else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED)
1260: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED");
1261: else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED)
1262: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED");
1263: else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS)
1264: return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS");
1265: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED)
1266: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED");
1267: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED)
1268: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED");
1269: else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO)
1270: return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO");
1271: else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER)
1272: return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER");
1273: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO)
1274: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO");
1275: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX)
1276: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX");
1277: else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO)
1278: return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO");
1279: else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT)
1280: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT");
1281: else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX)
1282: return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX");
1283: else if (ulCode == IOCTL_DISK_VERIFY)
1284: return (LPWSTR) _T ("IOCTL_DISK_VERIFY");
1285: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS)
1286: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS");
1287: else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS)
1288: return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS");
1289: else if (ulCode == IOCTL_DISK_PERFORMANCE)
1290: return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE");
1291: else if (ulCode == IOCTL_DISK_IS_WRITABLE)
1292: return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE");
1293: else if (ulCode == IOCTL_DISK_LOGGING)
1294: return (LPWSTR) _T ("IOCTL_DISK_LOGGING");
1295: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX)
1296: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX");
1297: else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE)
1298: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE");
1299: else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA)
1300: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA");
1301: else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET)
1302: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET");
1303: else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE)
1304: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE");
1305: else if (ulCode == IOCTL_DISK_REQUEST_DATA)
1306: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA");
1307: else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER)
1308: return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER");
1309: else if (ulCode == SMART_GET_VERSION)
1310: return (LPWSTR) _T ("SMART_GET_VERSION");
1311: else if (ulCode == SMART_SEND_DRIVE_COMMAND)
1312: return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND");
1313: else if (ulCode == SMART_RCV_DRIVE_DATA)
1314: return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA");
1315: else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY)
1316: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY");
1317: else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY)
1318: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY");
1319: else if (ulCode == IOCTL_DISK_CHECK_VERIFY)
1320: return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY");
1321: else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL)
1322: return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL");
1323: else if (ulCode == IOCTL_DISK_EJECT_MEDIA)
1324: return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA");
1325: else if (ulCode == IOCTL_DISK_LOAD_MEDIA)
1326: return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA");
1327: else if (ulCode == IOCTL_DISK_RESERVE)
1328: return (LPWSTR) _T ("IOCTL_DISK_RESERVE");
1329: else if (ulCode == IOCTL_DISK_RELEASE)
1330: return (LPWSTR) _T ("IOCTL_DISK_RELEASE");
1331: else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES)
1332: return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES");
1333: else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES)
1334: return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES");
1335: else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO)
1336: return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO");
1337: else if (ulCode == IRP_MJ_READ)
1338: return (LPWSTR) _T ("IRP_MJ_READ");
1339: else if (ulCode == IRP_MJ_WRITE)
1340: return (LPWSTR) _T ("IRP_MJ_WRITE");
1341: else if (ulCode == IRP_MJ_CREATE)
1342: return (LPWSTR) _T ("IRP_MJ_CREATE");
1343: else if (ulCode == IRP_MJ_CLOSE)
1344: return (LPWSTR) _T ("IRP_MJ_CLOSE");
1345: else if (ulCode == IRP_MJ_CLEANUP)
1346: return (LPWSTR) _T ("IRP_MJ_CLEANUP");
1347: else if (ulCode == IRP_MJ_FLUSH_BUFFERS)
1348: return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS");
1349: else if (ulCode == IRP_MJ_SHUTDOWN)
1350: return (LPWSTR) _T ("IRP_MJ_SHUTDOWN");
1351: else if (ulCode == IRP_MJ_DEVICE_CONTROL)
1352: return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL");
1353: else if (ulCode == MOUNT)
1354: return (LPWSTR) _T ("MOUNT");
1355: else if (ulCode == UNMOUNT)
1356: return (LPWSTR) _T ("UNMOUNT");
1.1.1.4 root 1357: else if (ulCode == UNMOUNT_ALL)
1358: return (LPWSTR) _T ("UNMOUNT_ALL");
1.1 root 1359: else if (ulCode == MOUNT_LIST)
1360: return (LPWSTR) _T ("MOUNT_LIST");
1361: else if (ulCode == OPEN_TEST)
1362: return (LPWSTR) _T ("OPEN_TEST");
1.1.1.5 root 1363: else if (ulCode == VOLUME_PROPERTIES)
1364: return (LPWSTR) _T ("VOLUME_PROPERTIES");
1365: else if (ulCode == DRIVER_VERSION)
1366: return (LPWSTR) _T ("DRIVER_VERSION");
1367: else if (ulCode == CACHE_STATUS)
1368: return (LPWSTR) _T ("CACHE_STATUS");
1369: else if (ulCode == WIPE_CACHE)
1370: return (LPWSTR) _T ("WIPE_CACHE");
1371: else if (ulCode == RESOLVE_SYMLINK)
1372: return (LPWSTR) _T ("RESOLVE_SYMLINK");
1.1 root 1373: else
1374: {
1.1.1.4 root 1375: Dump("Unknown IOCTL recieved: DeviceType = 0x%x Function = 0x%x\n", (int)(ulCode>>16), (int)((ulCode&0x1FFF)>>2));
1.1 root 1376: return (LPWSTR) _T ("UNKNOWN");
1377: }
1378: }
1379:
1380: #endif
1381:
1382: PDEVICE_OBJECT
1383: TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1384: {
1385: PDEVICE_OBJECT OldDeviceObject = DeviceObject;
1386: UNICODE_STRING Win32NameString;
1387: NTSTATUS ntStatus;
1388:
1389: Dump ("TCDeleteDeviceObject BEGIN\n");
1390:
1.1.1.6 root 1391: if (Extension->bRootDevice)
1.1 root 1392: {
1393: RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX);
1.1.1.4 root 1394: ntStatus = IoDeleteSymbolicLink (&Win32NameString);
1395: if (!NT_SUCCESS (ntStatus))
1396: Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus);
1.1 root 1397: }
1398: else
1399: {
1400: if (Extension->peThread != NULL)
1401: TCStopThread (DeviceObject, Extension);
1402: }
1403:
1.1.1.8 root 1404: if (DeviceObject != NULL)
1405: DeviceObject = DeviceObject->NextDevice;
1406:
1.1 root 1407: IoDeleteDevice (OldDeviceObject);
1408:
1409: Dump ("TCDeleteDeviceObject END\n");
1410: return DeviceObject;
1411: }
1412:
1.1.1.4 root 1413:
1.1 root 1414: VOID
1415: TCUnloadDriver (PDRIVER_OBJECT DriverObject)
1416: {
1417: PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
1418:
1419: Dump ("TCUnloadDriver BEGIN\n");
1420:
1.1.1.8 root 1421: UnmountAllDevices (DeviceObject, TRUE, TRUE, TRUE);
1.1.1.4 root 1422:
1.1 root 1423: /* Now walk the list of driver objects and get rid of them */
1424: while (DeviceObject != (PDEVICE_OBJECT) NULL)
1425: {
1426: DeviceObject = TCDeleteDeviceObject (DeviceObject,
1427: (PEXTENSION) DeviceObject->DeviceExtension);
1428: }
1429:
1.1.1.11! root 1430: /* For extra security (as the OS clears relevant memory pages after driver unload, it should never really be necessary). */
! 1431: WipeCache ();
! 1432:
1.1 root 1433: Dump ("TCUnloadDriver END\n");
1434: }
1.1.1.4 root 1435:
1436:
1437: NTSTATUS
1438: TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode,
1439: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
1440: {
1441: IO_STATUS_BLOCK ioStatusBlock;
1442: NTSTATUS ntStatus;
1443: PIRP irp;
1444: PFILE_OBJECT fileObject;
1445: PDEVICE_OBJECT deviceObject;
1446: KEVENT event;
1447: UNICODE_STRING name;
1448:
1449: RtlInitUnicodeString(&name, deviceName);
1.1.1.10 root 1450: ntStatus = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
1.1.1.4 root 1451:
1452: if (ntStatus != STATUS_SUCCESS)
1453: return ntStatus;
1454:
1455: KeInitializeEvent(&event, NotificationEvent, FALSE);
1456:
1457: irp = IoBuildDeviceIoControlRequest (IoControlCode,
1458: deviceObject,
1459: InputBuffer, InputBufferSize,
1460: OutputBuffer, OutputBufferSize,
1461: FALSE,
1462: &event,
1463: &ioStatusBlock);
1464:
1465: if (irp == NULL)
1466: {
1467: Dump ("IRP allocation failed\n");
1.1.1.11! root 1468: ntStatus = STATUS_INSUFFICIENT_RESOURCES;
! 1469: goto ret;
1.1.1.4 root 1470: }
1471:
1472: ntStatus = IoCallDriver (deviceObject, irp);
1473: if (ntStatus == STATUS_PENDING)
1474: {
1475: KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL);
1476: ntStatus = ioStatusBlock.Status;
1477: }
1478:
1.1.1.11! root 1479: ret:
! 1480: ObDereferenceObject (fileObject);
1.1.1.4 root 1481: return ntStatus;
1482: }
1483:
1484:
1485: // Opens a mounted TC volume on filesystem level
1486: NTSTATUS
1487: TCOpenFsVolume (PEXTENSION Extension, PHANDLE volumeHandle, PFILE_OBJECT * fileObject)
1488: {
1489: NTSTATUS ntStatus;
1490: OBJECT_ATTRIBUTES objectAttributes;
1491: UNICODE_STRING fullFileName;
1492: IO_STATUS_BLOCK ioStatus;
1.1.1.7 root 1493: WCHAR volumeName[TC_MAX_PATH];
1.1.1.4 root 1494:
1495: TCGetDosNameFromNumber (volumeName, Extension->nDosDriveNo);
1496: RtlInitUnicodeString (&fullFileName, volumeName);
1497: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
1498:
1499: ntStatus = ZwCreateFile (volumeHandle,
1500: SYNCHRONIZE | GENERIC_READ,
1501: &objectAttributes,
1502: &ioStatus,
1503: NULL,
1504: FILE_ATTRIBUTE_NORMAL,
1505: FILE_SHARE_READ | FILE_SHARE_WRITE,
1506: FILE_OPEN,
1507: FILE_SYNCHRONOUS_IO_NONALERT,
1508: NULL,
1509: 0);
1510:
1511: Dump ("Volume %ls open NTSTATUS 0x%08x\n", volumeName, ntStatus);
1512:
1513: if (!NT_SUCCESS (ntStatus))
1514: return ntStatus;
1515:
1516: ntStatus = ObReferenceObjectByHandle (*volumeHandle,
1517: FILE_READ_DATA,
1518: NULL,
1519: KernelMode,
1520: fileObject,
1521: NULL);
1522:
1523: Dump ("ObReferenceObjectByHandle NTSTATUS 0x%08x\n", ntStatus);
1524:
1525: if (!NT_SUCCESS (ntStatus))
1526: {
1527: ZwClose(*volumeHandle);
1528: return ntStatus;
1529: }
1530:
1531: return ntStatus;
1532: }
1533:
1534:
1535: void
1536: TCCloseFsVolume (HANDLE volumeHandle, PFILE_OBJECT fileObject)
1537: {
1538: ObDereferenceObject (fileObject);
1539: ZwClose (volumeHandle);
1540: }
1541:
1542:
1543: NTSTATUS
1544: TCFsctlCall (PFILE_OBJECT fileObject, LONG IoControlCode,
1545: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
1546: {
1547: IO_STATUS_BLOCK ioStatusBlock;
1548: NTSTATUS ntStatus;
1549: PIRP irp;
1550: KEVENT event;
1551: PIO_STACK_LOCATION stack;
1552: PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject);
1553:
1554: Dump ("IoGetRelatedDeviceObject = 0x%08x\n", deviceObject);
1555:
1556: KeInitializeEvent(&event, NotificationEvent, FALSE);
1557:
1558: irp = IoBuildDeviceIoControlRequest (IoControlCode,
1559: deviceObject,
1560: InputBuffer, InputBufferSize,
1561: OutputBuffer, OutputBufferSize,
1562: FALSE,
1563: &event,
1564: &ioStatusBlock);
1565:
1566: if (irp == NULL)
1567: {
1568: Dump ("IRP allocation failed\n");
1569: return STATUS_INSUFFICIENT_RESOURCES;
1570: }
1571:
1572: stack = IoGetNextIrpStackLocation(irp);
1573:
1574: stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
1575: stack->MinorFunction = IRP_MN_USER_FS_REQUEST;
1576: stack->FileObject = fileObject;
1577:
1578: ntStatus = IoCallDriver (deviceObject, irp);
1579: if (ntStatus == STATUS_PENDING)
1580: {
1581: KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL);
1582: ntStatus = ioStatusBlock.Status;
1583: }
1584:
1585: return ntStatus;
1586: }
1587:
1588:
1589: NTSTATUS
1.1.1.6 root 1590: CreateDriveLink (int nDosDriveNo)
1591: {
1.1.1.7 root 1592: WCHAR dev[256], link[256];
1.1.1.6 root 1593: UNICODE_STRING deviceName, symLink;
1594: NTSTATUS ntStatus;
1595:
1596: TCGetNTNameFromNumber (dev, nDosDriveNo);
1597: TCGetDosNameFromNumber (link, nDosDriveNo);
1598:
1599: RtlInitUnicodeString (&deviceName, dev);
1600: RtlInitUnicodeString (&symLink, link);
1601:
1602: ntStatus = IoCreateSymbolicLink (&symLink, &deviceName);
1603: Dump ("IoCreateSymbolicLink returned %X\n", ntStatus);
1604: return ntStatus;
1605: }
1606:
1607:
1608: NTSTATUS
1609: RemoveDriveLink (int nDosDriveNo)
1610: {
1.1.1.7 root 1611: WCHAR link[256];
1.1.1.6 root 1612: UNICODE_STRING symLink;
1613: NTSTATUS ntStatus;
1614:
1615: TCGetDosNameFromNumber (link, nDosDriveNo);
1616: RtlInitUnicodeString (&symLink, link);
1617:
1618: ntStatus = IoDeleteSymbolicLink (&symLink);
1619: Dump ("IoDeleteSymbolicLink returned %X\n", ntStatus);
1620: return ntStatus;
1621: }
1622:
1623:
1624: NTSTATUS
1.1.1.4 root 1625: MountManagerMount (MOUNT_STRUCT *mount)
1626: {
1627: NTSTATUS ntStatus;
1.1.1.7 root 1628: WCHAR arrVolume[256];
1.1.1.4 root 1629: char buf[200];
1630: PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf;
1631: PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf;
1632: UNICODE_STRING symName, devName;
1633:
1634: TCGetNTNameFromNumber (arrVolume, mount->nDosDriveNo);
1635: in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2;
1636: wcscpy(in->DeviceName, arrVolume);
1637:
1638: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
1639: in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0);
1640:
1641: memset (buf, 0, sizeof buf);
1642: TCGetDosNameFromNumber ((PWSTR) &point[1], mount->nDosDriveNo);
1643:
1644: point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
1645: point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;
1646:
1647: RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset));
1648:
1649: point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength;
1650: TCGetNTNameFromNumber ((PWSTR) (buf + point->DeviceNameOffset), mount->nDosDriveNo);
1651: point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2;
1652:
1653: RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset));
1654:
1655: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point,
1656: point->DeviceNameOffset + point->DeviceNameLength, 0, 0);
1657:
1658: return ntStatus;
1659: }
1660:
1661:
1662: NTSTATUS
1663: MountManagerUnmount (int nDosDriveNo)
1664: {
1665: NTSTATUS ntStatus;
1.1.1.7 root 1666: char buf[256], out[300];
1.1.1.4 root 1667: PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf;
1668:
1669: memset (buf, 0, sizeof buf);
1670:
1671: TCGetDosNameFromNumber ((PWSTR) &in[1], nDosDriveNo);
1672:
1673: in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
1674: in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2;
1675:
1676: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS,
1677: in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out);
1678:
1679: Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus);
1680:
1681: return ntStatus;
1682: }
1683:
1684:
1685: NTSTATUS
1686: MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount)
1687: {
1688: PDEVICE_OBJECT NewDeviceObject;
1689: NTSTATUS ntStatus;
1690:
1.1.1.6 root 1691: /* Make sure the user is asking for a reasonable
1.1.1.4 root 1692: nDosDriveNo */
1693: if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25)
1694: {
1695: Dump ("Mount request looks valid\n");
1696: }
1697: else
1698: {
1699: Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n");
1.1.1.10 root 1700: mount->nReturnCode = ERR_DRIVE_NOT_FOUND;
1701: return ERR_DRIVE_NOT_FOUND;
1.1.1.4 root 1702: }
1703:
1.1.1.6 root 1704: if (!SelfTestsPassed)
1705: {
1706: mount->nReturnCode = ERR_SELF_TESTS_FAILED;
1707: return ERR_SELF_TESTS_FAILED;
1708: }
1709:
1.1.1.4 root 1710: ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
1711: mount);
1712: if (!NT_SUCCESS (ntStatus))
1713: {
1714: Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
1715: return ntStatus;
1716: }
1717: else
1718: {
1719: PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension;
1720: ntStatus = TCStartThread (NewDeviceObject, NewExtension, mount);
1721: if (!NT_SUCCESS (ntStatus))
1722: {
1723: Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus);
1724: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
1725: return ntStatus;
1726: }
1727: else
1728: {
1729: if (mount->nReturnCode == 0)
1730: {
1731: Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode,
1732: NewExtension->bReadOnly);
1.1.1.6 root 1733: if (NewExtension->bReadOnly)
1.1.1.4 root 1734: NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
1735: NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1736:
1.1.1.6 root 1737: NewExtension->UniqueVolumeId = LastUniqueVolumeId++;
1738:
1.1.1.4 root 1739: if (mount->bMountManager)
1740: MountManagerMount (mount);
1741:
1.1.1.6 root 1742: NewExtension->bMountManager = mount->bMountManager;
1.1.1.4 root 1743:
1.1.1.6 root 1744: // We create symbolic link even if mount manager is notified of
1745: // arriving volume as it apparently sometimes fails to create the link
1746: CreateDriveLink (mount->nDosDriveNo);
1.1.1.4 root 1747: }
1748: else
1749: {
1750: Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode);
1751: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
1752: }
1753:
1754: return STATUS_SUCCESS;
1755: }
1756: }
1757: }
1758:
1759: NTSTATUS
1760: UnmountDevice (PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles)
1761: {
1762: PEXTENSION extension = deviceObject->DeviceExtension;
1763: NTSTATUS ntStatus;
1764: HANDLE volumeHandle;
1765: PFILE_OBJECT volumeFileObject;
1766:
1.1.1.8 root 1767: Dump ("UnmountDevice %d\n", extension->nDosDriveNo);
1768:
1.1.1.4 root 1769: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
1770: if (!NT_SUCCESS (ntStatus))
1.1.1.6 root 1771: {
1772: // User may have deleted symbolic link
1773: CreateDriveLink (extension->nDosDriveNo);
1774:
1775: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
1776: }
1777:
1.1.1.8 root 1778: if (NT_SUCCESS (ntStatus))
1779: {
1780: // Lock volume
1781: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
1782: Dump ("FSCTL_LOCK_VOLUME returned %X\n", ntStatus);
1783:
1784: if (!NT_SUCCESS (ntStatus) && !ignoreOpenFiles)
1785: {
1786: TCCloseFsVolume (volumeHandle, volumeFileObject);
1787: return ERR_FILES_OPEN;
1788: }
1.1.1.4 root 1789:
1.1.1.8 root 1790: // Dismount volume
1791: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
1792: Dump ("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus);
1793: }
1794: else
1.1.1.4 root 1795: {
1.1.1.8 root 1796: // Volume cannot be opened => force dismount if allowed
1797: if (!ignoreOpenFiles)
1798: return ERR_FILES_OPEN;
1799: else
1800: volumeHandle = NULL;
1.1.1.4 root 1801: }
1802:
1803: if (extension->bMountManager)
1804: MountManagerUnmount (extension->nDosDriveNo);
1.1.1.8 root 1805:
1.1.1.6 root 1806: // We always remove symbolic link as mount manager might fail to do so
1807: RemoveDriveLink (extension->nDosDriveNo);
1.1.1.4 root 1808:
1.1.1.10 root 1809: extension->bShuttingDown = TRUE;
1810:
1.1.1.8 root 1811: if (volumeHandle != NULL)
1812: TCCloseFsVolume (volumeHandle, volumeFileObject);
1.1.1.11! root 1813:
! 1814: if (deviceObject->ReferenceCount > 0)
! 1815: ReferencedDeviceDeleted = TRUE;
1.1.1.4 root 1816:
1817: Dump ("Deleting DeviceObject with ref count %ld\n", deviceObject->ReferenceCount);
1818: deviceObject->ReferenceCount = 0;
1819: TCDeleteDeviceObject (deviceObject, (PEXTENSION) deviceObject->DeviceExtension);
1.1.1.11! root 1820:
1.1.1.4 root 1821: return 0;
1822: }
1823:
1824: NTSTATUS
1.1.1.8 root 1825: UnmountAllDevices (PDEVICE_OBJECT DeviceObject, BOOL ignoreOpenFiles, BOOL unmountSystem, BOOL unmountPersistent)
1.1.1.4 root 1826: {
1827: NTSTATUS status = 0;
1828: PDEVICE_OBJECT ListDevice;
1829:
1830: Dump ("Unmounting all volumes\n");
1831:
1.1.1.9 root 1832: if (!DeviceObject || !DeviceObject->DriverObject)
1833: return STATUS_INVALID_PARAMETER;
1834:
1.1.1.5 root 1835: DriverMutexWait ();
1836:
1.1.1.10 root 1837: ListDevice = DeviceObject->DriverObject->DeviceObject;
1838: while (ListDevice != NULL)
1.1.1.4 root 1839: {
1840: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.8 root 1841: if (ListExtension->bRootDevice == FALSE)
1.1.1.4 root 1842: {
1.1.1.8 root 1843: if (!ListExtension->bShuttingDown
1844: && (unmountSystem || !ListExtension->bSystemVolume)
1845: && (unmountPersistent || !ListExtension->bPersistentVolume))
1846: {
1.1.1.10 root 1847: PDEVICE_OBJECT nextDevice = ListDevice->NextDevice;
1848:
1.1.1.8 root 1849: NTSTATUS ntStatus = UnmountDevice (ListDevice, ignoreOpenFiles);
1850: status = ntStatus == 0 ? status : ntStatus;
1.1.1.10 root 1851:
1852: ListDevice = nextDevice;
1853: continue;
1.1.1.8 root 1854: }
1855: else if (unmountPersistent
1856: && ListExtension->bSystemVolume
1857: && !ListExtension->bShuttingDown)
1858: {
1859: // If the driver is shutting down, set system volumes to reject
1860: // all IO requests so that OS does not complain because of paging files
1861: Dump ("System volume %d shutdown\n", ListExtension->nDosDriveNo);
1862: ListExtension->bShuttingDown = TRUE;
1863: }
1.1.1.4 root 1864: }
1.1.1.8 root 1865:
1.1.1.10 root 1866: ListDevice = ListDevice->NextDevice;
1.1.1.4 root 1867: }
1868:
1.1.1.5 root 1869: DriverMutexRelease ();
1870:
1.1.1.4 root 1871: return status;
1872: }
1873:
1874: // Resolves symbolic link name to its target name
1875: NTSTATUS
1876: SymbolicLinkToTarget (PWSTR symlinkName, PWSTR targetName, USHORT maxTargetNameLength)
1877: {
1878: NTSTATUS ntStatus;
1879: OBJECT_ATTRIBUTES objectAttributes;
1880: UNICODE_STRING fullFileName;
1881: HANDLE handle;
1882:
1883: RtlInitUnicodeString (&fullFileName, symlinkName);
1884: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
1885:
1886: ntStatus = ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes);
1887:
1888: if (NT_SUCCESS (ntStatus))
1889: {
1890: UNICODE_STRING target;
1891: target.Buffer = targetName;
1892: target.Length = 0;
1893: target.MaximumLength = maxTargetNameLength;
1894: memset (targetName, 0, maxTargetNameLength);
1895:
1896: ntStatus = ZwQuerySymbolicLinkObject (handle, &target, NULL);
1897:
1898: ZwClose (handle);
1899: }
1900:
1901: return ntStatus;
1902: }
1.1.1.6 root 1903:
1904: // Checks if two regions overlap (borders are parts of regions)
1905: BOOL RegionsOverlap (unsigned __int64 start1, unsigned __int64 end1, unsigned __int64 start2, unsigned __int64 end2)
1906: {
1907: return (start1 < start2) ? (end1 >= start2) : (start1 <= end2);
1908: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.