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