|
|
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.9 ! root 6: Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.1
1.1.1.6 root 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:
1.1.1.9 ! root 813: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT)
! 814: || !DeviceObject || !DeviceObject->DriverObject)
1.1 root 815: {
816: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
817: Irp->IoStatus.Information = 0;
818: }
819: else
820: {
821: MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
822: PDEVICE_OBJECT ListDevice;
823:
1.1.1.5 root 824: DriverMutexWait ();
825:
1.1 root 826: list->ulMountedDrives = 0;
827: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
828: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
829: {
830:
831: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.6 root 832: if (ListExtension->lMagicNumber == 0xabfeacde
833: && ListExtension->bRootDevice == FALSE
1.1.1.8 root 834: && !ListExtension->bSystemVolume
835: && !ListExtension->bPersistentVolume
1.1.1.6 root 836: && !ListExtension->bShuttingDown)
1.1 root 837: {
838: list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo);
839: wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume);
840: list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength;
1.1.1.4 root 841: list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea;
1.1.1.6 root 842: if (ListExtension->cryptoInfo->hiddenVolume)
843: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_HIDDEN; // Hidden volume
844: else if (ListExtension->cryptoInfo->bHiddenVolProtectionAction)
845: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED; // Normal/outer volume (hidden volume protected AND write already prevented)
846: else if (ListExtension->cryptoInfo->bProtectHiddenVolume)
847: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER; // Normal/outer volume (hidden volume protected)
848: else
849: list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_NORMAL; // Normal volume
1.1 root 850: }
851: }
852:
1.1.1.5 root 853: DriverMutexRelease ();
854:
1.1 root 855: Irp->IoStatus.Status = STATUS_SUCCESS;
856: Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT);
857: }
858: break;
859:
860: case VOLUME_PROPERTIES:
1.1.1.9 ! root 861: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT)
! 862: || !DeviceObject || !DeviceObject->DriverObject)
1.1 root 863: {
864: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
865: Irp->IoStatus.Information = 0;
866: }
867: else
868: {
869: VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
870: PDEVICE_OBJECT ListDevice;
871:
872: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
873: Irp->IoStatus.Information = 0;
874:
1.1.1.5 root 875: DriverMutexWait ();
876:
1.1 root 877: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
878: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
879: {
880:
881: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.6 root 882: if (ListExtension->bRootDevice == FALSE
883: && !ListExtension->bShuttingDown
884: && ListExtension->nDosDriveNo == prop->driveNo)
1.1 root 885: {
1.1.1.6 root 886: prop->uniqueId = ListExtension->UniqueVolumeId;
1.1 root 887: wcscpy (prop->wszVolume, ListExtension->wszVolume);
888: prop->diskLength = ListExtension->DiskLength;
1.1.1.4 root 889: prop->ea = ListExtension->cryptoInfo->ea;
1.1.1.7 root 890: prop->mode = ListExtension->cryptoInfo->mode;
1.1 root 891: prop->pkcs5 = ListExtension->cryptoInfo->pkcs5;
892: prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations;
893: prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time;
894: prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time;
1.1.1.6 root 895: prop->readOnly = ListExtension->bReadOnly;
1.1.1.4 root 896: prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume;
1.1.1.8 root 897: prop->systemVolume = ListExtension->bSystemVolume;
898: prop->persistentVolume = ListExtension->bPersistentVolume;
1.1 root 899:
1.1.1.6 root 900: if (ListExtension->cryptoInfo->bProtectHiddenVolume)
901: prop->hiddenVolProtection = ListExtension->cryptoInfo->bHiddenVolProtectionAction ? HIDVOL_PROT_STATUS_ACTION_TAKEN : HIDVOL_PROT_STATUS_ACTIVE;
902: else
903: prop->hiddenVolProtection = HIDVOL_PROT_STATUS_NONE;
904:
905: prop->totalBytesRead = ListExtension->TotalBytesRead;
906: prop->totalBytesWritten = ListExtension->TotalBytesWritten;
907:
1.1 root 908: Irp->IoStatus.Status = STATUS_SUCCESS;
909: Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT);
910: break;
911: }
912: }
1.1.1.5 root 913:
914: DriverMutexRelease ();
1.1 root 915: }
916: break;
917:
1.1.1.4 root 918: case RESOLVE_SYMLINK:
1.1.1.6 root 919: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (RESOLVE_SYMLINK_STRUCT))
1.1.1.4 root 920: {
921: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
922: Irp->IoStatus.Information = 0;
923: }
924: else
1.1 root 925: {
1.1.1.4 root 926: RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
927: {
928: NTSTATUS ntStatus;
929:
930: ntStatus = SymbolicLinkToTarget (resolve->symLinkName,
931: resolve->targetName,
932: sizeof (resolve->targetName));
933:
934: Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT);
935: Irp->IoStatus.Status = ntStatus;
936: }
937:
938: }
939: break;
940:
941: case MOUNT:
942: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT))
943: {
944: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
945: Irp->IoStatus.Information = 0;
946: }
947: else
948: {
949: MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
950:
1.1.1.5 root 951: DriverMutexWait ();
1.1.1.6 root 952:
953: Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
1.1.1.4 root 954: Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
1.1.1.5 root 955: DriverMutexRelease ();
1.1.1.6 root 956:
957: burn (&mount->VolumePassword, sizeof (mount->VolumePassword));
958: burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword));
1.1 root 959: }
960: break;
961:
962: case UNMOUNT:
1.1.1.9 ! root 963: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT)
! 964: || !DeviceObject || !DeviceObject->DriverObject)
1.1 root 965: {
966: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
967: Irp->IoStatus.Information = 0;
968: }
969: else
970: {
971: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
972: PDEVICE_OBJECT ListDevice;
973:
974: unmount->nReturnCode = ERR_DRIVE_NOT_FOUND;
975:
976: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
977: ListDevice != (PDEVICE_OBJECT) NULL;
978: ListDevice = ListDevice->NextDevice)
979: {
980: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
981:
1.1.1.4 root 982: if (ListExtension->bRootDevice == FALSE
1.1.1.6 root 983: && !ListExtension->bShuttingDown
1.1.1.4 root 984: && unmount->nDosDriveNo == ListExtension->nDosDriveNo)
1.1 root 985: {
1.1.1.5 root 986: DriverMutexWait ();
1.1.1.4 root 987: unmount->nReturnCode = UnmountDevice (ListDevice, unmount->ignoreOpenFiles);
1.1.1.5 root 988: DriverMutexRelease ();
1.1.1.4 root 989: break;
1.1.1.8 root 990: }
991:
992: if (ListDevice == NULL)
993: break;
1.1.1.4 root 994: }
1.1 root 995:
1.1.1.4 root 996: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
1.1 root 997: Irp->IoStatus.Status = STATUS_SUCCESS;
998: }
999: break;
1000:
1.1.1.4 root 1001: case UNMOUNT_ALL:
1002: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
1.1 root 1003: {
1004: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1005: Irp->IoStatus.Information = 0;
1006: }
1007: else
1008: {
1.1.1.4 root 1009: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1.1 root 1010:
1.1.1.8 root 1011: unmount->nReturnCode = UnmountAllDevices (DeviceObject, unmount->ignoreOpenFiles, FALSE, FALSE);
1.1 root 1012:
1.1.1.4 root 1013: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
1014: Irp->IoStatus.Status = STATUS_SUCCESS;
1.1 root 1015: }
1016: break;
1017: }
1018:
1019: /* Finish the I/O operation by simply completing the packet and
1020: returning the same NTSTATUS as in the packet itself. */
1021: ntStatus = COMPLETE_IRP (DeviceObject, Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
1022: Dump ("TCDeviceControl NTSTATUS = 0x%08x END\n", ntStatus);
1023: return ntStatus;
1024: }
1025:
1.1.1.6 root 1026:
1.1 root 1027: NTSTATUS
1028: TCStartThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount)
1029: {
1030: PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK));
1031: HANDLE hThread;
1032: NTSTATUS ntStatus;
1.1.1.6 root 1033: HANDLE process;
1.1 root 1034:
1035: Dump ("Starting thread...\n");
1036:
1037: if (pThreadBlock == NULL)
1038: {
1039: return STATUS_INSUFFICIENT_RESOURCES;
1040: }
1041: else
1042: {
1043: pThreadBlock->DeviceObject = DeviceObject;
1044: pThreadBlock->mount = mount;
1045: }
1046:
1.1.1.6 root 1047: if (mount->bUserContext)
1048: {
1049: ntStatus = ObOpenObjectByPointer (IoGetCurrentProcess (), 0, NULL, 0, NULL, KernelMode, &process);
1050: if (!NT_SUCCESS (ntStatus))
1051: {
1052: Dump ("ObOpenObjectByPointer Failed\n");
1053: goto ret;
1054: }
1055: }
1056: else
1057: process = NULL;
1058:
1.1.1.8 root 1059: Extension->bSystemVolume = mount->bSystemVolume;
1060: Extension->bPersistentVolume = mount->bPersistentVolume;
1061:
1.1 root 1062: Extension->bThreadShouldQuit = FALSE;
1063:
1064: ntStatus = PsCreateSystemThread (&hThread,
1065: THREAD_ALL_ACCESS,
1066: NULL,
1.1.1.6 root 1067: process,
1.1 root 1068: NULL,
1069: TCThreadIRP,
1070: pThreadBlock);
1071:
1072: if (!NT_SUCCESS (ntStatus))
1073: {
1074: Dump ("PsCreateSystemThread Failed END\n");
1.1.1.6 root 1075: goto ret;
1.1 root 1076: }
1077:
1078: ObReferenceObjectByHandle (hThread,
1079: THREAD_ALL_ACCESS,
1080: NULL,
1081: KernelMode,
1082: &Extension->peThread,
1083: NULL);
1084: ZwClose (hThread);
1085:
1086: Dump ("Waiting for thread to initialize...\n");
1087:
1088: KeWaitForSingleObject (&Extension->keCreateEvent,
1089: UserRequest,
1090: UserMode,
1091: FALSE,
1092: NULL);
1093:
1094: Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus);
1095: ntStatus = pThreadBlock->ntCreateStatus;
1.1.1.6 root 1096:
1097: ret:
1.1 root 1098: TCfree (pThreadBlock);
1099: return ntStatus;
1100: }
1101:
1102: void
1103: TCStopThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1104: {
1105: NTSTATUS ntStatus;
1106:
1107: if (DeviceObject); /* Remove compiler warning */
1108:
1109: Dump ("Signalling thread to quit...\n");
1110:
1111: Extension->bThreadShouldQuit = TRUE;
1112:
1113: KeReleaseSemaphore (&Extension->RequestSemaphore,
1114: 0,
1115: 1,
1116: TRUE);
1117:
1.1.1.4 root 1118: ntStatus = KeWaitForSingleObject (Extension->peThread,
1.1 root 1119: UserRequest,
1120: UserMode,
1121: FALSE,
1122: NULL);
1123: if (ntStatus != STATUS_SUCCESS)
1124: Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n",
1125: ntStatus);
1126:
1.1.1.6 root 1127: ObDereferenceObject (Extension->peThread);
1.1 root 1128: Extension->peThread = NULL;
1129:
1130: Dump ("Thread exited!\n");
1131: }
1132:
1.1.1.5 root 1133:
1134: // Suspend current thread for a number of milliseconds
1135: void TCSleep (int milliSeconds)
1136: {
1137: PKTIMER timer = (PKTIMER) TCalloc (sizeof (KTIMER));
1138: LARGE_INTEGER duetime;
1139:
1140: duetime.QuadPart = (__int64) milliSeconds * -10000;
1141: KeInitializeTimerEx(timer, NotificationTimer);
1142: KeSetTimerEx(timer, duetime, 0, NULL);
1143:
1144: KeWaitForSingleObject (timer, UserRequest, UserMode, FALSE, NULL);
1145:
1146: TCfree (timer);
1147: }
1148:
1149:
1.1 root 1150: /* TCThreadIRP does all the work of processing IRP's, and dispatching them
1151: to either the ReadWrite function or the DeviceControl function */
1152: VOID
1153: TCThreadIRP (PVOID Context)
1154: {
1155: PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context;
1156: PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject;
1157: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
1158: LARGE_INTEGER queueWait;
1159: BOOL bDevice;
1160:
1161: /* Set thread priority to lowest realtime level. */
1162:
1163: KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY);
1164:
1165: queueWait.QuadPart = -WAIT_SECONDS (1);
1166:
1167: Dump ("Mount THREAD OPENING VOLUME BEGIN\n");
1168:
1169: #ifdef USE_KERNEL_MUTEX
1170: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
1171: FALSE, NULL);
1172: #endif
1173:
1174: if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0)
1175: {
1176: wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\"));
1.1.1.7 root 1177: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
1178: sizeof (pThreadBlock->wszMountVolume) / 2 - 5);
1.1 root 1179: bDevice = FALSE;
1180: }
1181: else
1182: {
1.1.1.8 root 1183: pThreadBlock->wszMountVolume[0] = 0;
1184: wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
1.1.1.7 root 1185: sizeof (pThreadBlock->wszMountVolume) / 2 - 1);
1.1 root 1186: bDevice = TRUE;
1187: }
1188:
1189: Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n",
1190: pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice);
1191:
1192: pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject,
1.1.1.7 root 1193: Extension,
1194: pThreadBlock->mount,
1195: pThreadBlock->wszMountVolume,
1196: bDevice);
1.1 root 1197:
1198: #ifdef USE_KERNEL_MUTEX
1199: KeReleaseMutex (&Extension->KernelMutex, FALSE);
1200: #endif
1201:
1202: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0)
1203: {
1204: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1205: PsTerminateSystemThread (STATUS_SUCCESS);
1206: }
1207: else
1208: {
1209: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1210: /* From this point on pThreadBlock cannot be used as it will
1211: have been released! */
1212: pThreadBlock = NULL;
1213: }
1214:
1215:
1216: for (;;)
1217: {
1218: NTSTATUS ntStatus;
1219:
1220: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1221:
1222: /* Wait for a request from the dispatch routines. */
1223: ntStatus = KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore,
1224: Executive, KernelMode, FALSE, &queueWait);
1225:
1226: if (ntStatus != STATUS_TIMEOUT)
1227: {
1228:
1229: #ifdef USE_KERNEL_MUTEX
1230: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
1231: FALSE, NULL);
1232: #endif
1233:
1234: // Dump ("DRIVER THREAD PROCESSING DEVICEOBJECT 0x%08x \n", DeviceObject);
1235:
1236: for (;;)
1237: {
1238: PIO_STACK_LOCATION irpSp;
1239: PLIST_ENTRY request;
1240: PIRP Irp;
1241:
1242: request = ExInterlockedRemoveHeadList (&Extension->ListEntry,
1243: &Extension->ListSpinLock);
1244: if (request == NULL)
1245: break;
1246:
1247: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1248:
1249: Irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry);
1250: irpSp = IoGetCurrentIrpStackLocation (Irp);
1251:
1252: switch (irpSp->MajorFunction)
1253: {
1254: case IRP_MJ_READ:
1255: case IRP_MJ_WRITE:
1256: TCReadWrite (DeviceObject, Extension, Irp);
1257: break;
1258:
1259: case IRP_MJ_FLUSH_BUFFERS:
1260: if (Extension->bRawDevice == FALSE)
1261: TCSendIRP_FileDevice (DeviceObject, Extension, NULL, Irp->Flags, IRP_MJ_FLUSH_BUFFERS, Irp);
1262: else
1263: {
1264: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
1265: }
1266: break;
1267:
1268: case IRP_MJ_SHUTDOWN:
1269: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
1270: break;
1271:
1272: case IRP_MJ_DEVICE_CONTROL:
1273: if (irpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_DISK_CHECK_VERIFY)
1274: TCDeviceControl (DeviceObject, Extension, Irp);
1275: else
1276: {
1.1.1.6 root 1277: if (Extension->bRawDevice)
1.1 root 1278: TCSendIRP_RawDevice (DeviceObject, Extension, NULL, 0, IRP_MJ_DEVICE_CONTROL, Irp);
1279: else
1280: TCDeviceControl (DeviceObject, Extension, Irp);
1281: }
1282: break;
1283: } /* end of switch on
1284: irpSp->MajorFunction */
1285: } /* for any remaining IRP's for this device */
1286:
1287: #ifdef USE_KERNEL_MUTEX
1288: KeReleaseMutex (&Extension->KernelMutex, FALSE);
1289: #endif
1290:
1291: if (Extension->bThreadShouldQuit)
1292: {
1293: // Dump ("END PROCESSING DEVICEOBJECT THREAD ENDING 0x%08x Number = %d\n",
1294: // DeviceObject, Extension->nDosDriveNo);
1295: Dump ("Closing volume along with Thread!\n");
1296: TCCloseVolume (DeviceObject, Extension);
1297: PsTerminateSystemThread (STATUS_SUCCESS);
1298: }
1299: //else
1300: //{
1301: // Dump ("END PROCESSING DEVICEOBJECT 0x%08x Number = %d\n",
1302: // DeviceObject, Extension->nDosDriveNo);
1303: //}
1304: }
1305:
1306: } /* outermost for */
1307: }
1308:
1309: void
1310: TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)
1311: {
1312: WCHAR tmp[3] =
1313: {0, ':', 0};
1314: int j = nDriveNo + (WCHAR) 'A';
1315:
1316: tmp[0] = (short) j;
1317: wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
1318: wcsncat (ntname, tmp, 1);
1319: }
1320:
1321: void
1322: TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo)
1323: {
1324: WCHAR tmp[3] =
1325: {0, ':', 0};
1326: int j = nDriveNo + (WCHAR) 'A';
1327:
1328: tmp[0] = (short) j;
1329: wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX);
1330: wcscat (dosname, tmp);
1331: }
1332:
1333: #ifdef _DEBUG
1334: LPWSTR
1335: TCTranslateCode (ULONG ulCode)
1336: {
1337: if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY)
1338: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY");
1339: else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)
1340: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX");
1341: else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME)
1342: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME");
1343: else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME)
1344: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME");
1345: else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID)
1346: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID");
1347: else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY)
1348: return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY");
1349: else if (ulCode == IOCTL_VOLUME_ONLINE)
1350: return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE");
1351: else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED)
1352: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED");
1353: else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED)
1354: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED");
1355: else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS)
1356: return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS");
1357: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED)
1358: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED");
1359: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED)
1360: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED");
1361: else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO)
1362: return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO");
1363: else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER)
1364: return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER");
1365: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO)
1366: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO");
1367: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX)
1368: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX");
1369: else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO)
1370: return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO");
1371: else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT)
1372: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT");
1373: else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX)
1374: return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX");
1375: else if (ulCode == IOCTL_DISK_VERIFY)
1376: return (LPWSTR) _T ("IOCTL_DISK_VERIFY");
1377: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS)
1378: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS");
1379: else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS)
1380: return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS");
1381: else if (ulCode == IOCTL_DISK_PERFORMANCE)
1382: return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE");
1383: else if (ulCode == IOCTL_DISK_IS_WRITABLE)
1384: return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE");
1385: else if (ulCode == IOCTL_DISK_LOGGING)
1386: return (LPWSTR) _T ("IOCTL_DISK_LOGGING");
1387: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX)
1388: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX");
1389: else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE)
1390: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE");
1391: else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA)
1392: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA");
1393: else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET)
1394: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET");
1395: else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE)
1396: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE");
1397: else if (ulCode == IOCTL_DISK_REQUEST_DATA)
1398: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA");
1399: else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER)
1400: return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER");
1401: else if (ulCode == SMART_GET_VERSION)
1402: return (LPWSTR) _T ("SMART_GET_VERSION");
1403: else if (ulCode == SMART_SEND_DRIVE_COMMAND)
1404: return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND");
1405: else if (ulCode == SMART_RCV_DRIVE_DATA)
1406: return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA");
1407: else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY)
1408: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY");
1409: else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY)
1410: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY");
1411: else if (ulCode == IOCTL_DISK_CHECK_VERIFY)
1412: return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY");
1413: else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL)
1414: return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL");
1415: else if (ulCode == IOCTL_DISK_EJECT_MEDIA)
1416: return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA");
1417: else if (ulCode == IOCTL_DISK_LOAD_MEDIA)
1418: return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA");
1419: else if (ulCode == IOCTL_DISK_RESERVE)
1420: return (LPWSTR) _T ("IOCTL_DISK_RESERVE");
1421: else if (ulCode == IOCTL_DISK_RELEASE)
1422: return (LPWSTR) _T ("IOCTL_DISK_RELEASE");
1423: else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES)
1424: return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES");
1425: else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES)
1426: return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES");
1427: else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO)
1428: return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO");
1429: else if (ulCode == IRP_MJ_READ)
1430: return (LPWSTR) _T ("IRP_MJ_READ");
1431: else if (ulCode == IRP_MJ_WRITE)
1432: return (LPWSTR) _T ("IRP_MJ_WRITE");
1433: else if (ulCode == IRP_MJ_CREATE)
1434: return (LPWSTR) _T ("IRP_MJ_CREATE");
1435: else if (ulCode == IRP_MJ_CLOSE)
1436: return (LPWSTR) _T ("IRP_MJ_CLOSE");
1437: else if (ulCode == IRP_MJ_CLEANUP)
1438: return (LPWSTR) _T ("IRP_MJ_CLEANUP");
1439: else if (ulCode == IRP_MJ_FLUSH_BUFFERS)
1440: return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS");
1441: else if (ulCode == IRP_MJ_SHUTDOWN)
1442: return (LPWSTR) _T ("IRP_MJ_SHUTDOWN");
1443: else if (ulCode == IRP_MJ_DEVICE_CONTROL)
1444: return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL");
1445: else if (ulCode == MOUNT)
1446: return (LPWSTR) _T ("MOUNT");
1447: else if (ulCode == UNMOUNT)
1448: return (LPWSTR) _T ("UNMOUNT");
1.1.1.4 root 1449: else if (ulCode == UNMOUNT_ALL)
1450: return (LPWSTR) _T ("UNMOUNT_ALL");
1.1 root 1451: else if (ulCode == MOUNT_LIST)
1452: return (LPWSTR) _T ("MOUNT_LIST");
1453: else if (ulCode == OPEN_TEST)
1454: return (LPWSTR) _T ("OPEN_TEST");
1.1.1.5 root 1455: else if (ulCode == VOLUME_PROPERTIES)
1456: return (LPWSTR) _T ("VOLUME_PROPERTIES");
1457: else if (ulCode == DRIVER_VERSION)
1458: return (LPWSTR) _T ("DRIVER_VERSION");
1459: else if (ulCode == CACHE_STATUS)
1460: return (LPWSTR) _T ("CACHE_STATUS");
1461: else if (ulCode == WIPE_CACHE)
1462: return (LPWSTR) _T ("WIPE_CACHE");
1463: else if (ulCode == RESOLVE_SYMLINK)
1464: return (LPWSTR) _T ("RESOLVE_SYMLINK");
1.1 root 1465: else
1466: {
1.1.1.4 root 1467: Dump("Unknown IOCTL recieved: DeviceType = 0x%x Function = 0x%x\n", (int)(ulCode>>16), (int)((ulCode&0x1FFF)>>2));
1.1 root 1468: return (LPWSTR) _T ("UNKNOWN");
1469: }
1470: }
1471:
1472: #endif
1473:
1474: PDEVICE_OBJECT
1475: TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1476: {
1477: PDEVICE_OBJECT OldDeviceObject = DeviceObject;
1478: UNICODE_STRING Win32NameString;
1479: NTSTATUS ntStatus;
1480:
1481: Dump ("TCDeleteDeviceObject BEGIN\n");
1482:
1.1.1.6 root 1483: if (Extension->bRootDevice)
1.1 root 1484: {
1485: RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX);
1.1.1.4 root 1486: ntStatus = IoDeleteSymbolicLink (&Win32NameString);
1487: if (!NT_SUCCESS (ntStatus))
1488: Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus);
1.1 root 1489: }
1490: else
1491: {
1492: if (Extension->peThread != NULL)
1493: TCStopThread (DeviceObject, Extension);
1494: }
1495:
1.1.1.8 root 1496: if (DeviceObject != NULL)
1497: DeviceObject = DeviceObject->NextDevice;
1498:
1.1 root 1499: IoDeleteDevice (OldDeviceObject);
1500:
1501: Dump ("TCDeleteDeviceObject END\n");
1502: return DeviceObject;
1503: }
1504:
1.1.1.4 root 1505:
1.1 root 1506: VOID
1507: TCUnloadDriver (PDRIVER_OBJECT DriverObject)
1508: {
1509: PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
1510:
1511: Dump ("TCUnloadDriver BEGIN\n");
1512:
1.1.1.8 root 1513: UnmountAllDevices (DeviceObject, TRUE, TRUE, TRUE);
1.1.1.4 root 1514:
1.1 root 1515: /* Now walk the list of driver objects and get rid of them */
1516: while (DeviceObject != (PDEVICE_OBJECT) NULL)
1517: {
1518: DeviceObject = TCDeleteDeviceObject (DeviceObject,
1519: (PEXTENSION) DeviceObject->DeviceExtension);
1520: }
1521:
1522: Dump ("TCUnloadDriver END\n");
1523: }
1.1.1.4 root 1524:
1525:
1526: NTSTATUS
1527: TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode,
1528: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
1529: {
1530: IO_STATUS_BLOCK ioStatusBlock;
1531: NTSTATUS ntStatus;
1532: PIRP irp;
1533: PFILE_OBJECT fileObject;
1534: PDEVICE_OBJECT deviceObject;
1535: KEVENT event;
1536: UNICODE_STRING name;
1537:
1538: RtlInitUnicodeString(&name, deviceName);
1539: ntStatus = IoGetDeviceObjectPointer(&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
1540:
1541: if (ntStatus != STATUS_SUCCESS)
1542: return ntStatus;
1543:
1544: KeInitializeEvent(&event, NotificationEvent, FALSE);
1545:
1546: irp = IoBuildDeviceIoControlRequest (IoControlCode,
1547: deviceObject,
1548: InputBuffer, InputBufferSize,
1549: OutputBuffer, OutputBufferSize,
1550: FALSE,
1551: &event,
1552: &ioStatusBlock);
1553:
1554: if (irp == NULL)
1555: {
1556: Dump ("IRP allocation failed\n");
1557: return STATUS_INSUFFICIENT_RESOURCES;
1558: }
1559:
1560: ntStatus = IoCallDriver (deviceObject, irp);
1561: if (ntStatus == STATUS_PENDING)
1562: {
1563: KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL);
1564: ntStatus = ioStatusBlock.Status;
1565: }
1566:
1567: return ntStatus;
1568: }
1569:
1570:
1571: // Opens a mounted TC volume on filesystem level
1572: NTSTATUS
1573: TCOpenFsVolume (PEXTENSION Extension, PHANDLE volumeHandle, PFILE_OBJECT * fileObject)
1574: {
1575: NTSTATUS ntStatus;
1576: OBJECT_ATTRIBUTES objectAttributes;
1577: UNICODE_STRING fullFileName;
1578: IO_STATUS_BLOCK ioStatus;
1.1.1.7 root 1579: WCHAR volumeName[TC_MAX_PATH];
1.1.1.4 root 1580:
1581: TCGetDosNameFromNumber (volumeName, Extension->nDosDriveNo);
1582: RtlInitUnicodeString (&fullFileName, volumeName);
1583: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
1584:
1585: ntStatus = ZwCreateFile (volumeHandle,
1586: SYNCHRONIZE | GENERIC_READ,
1587: &objectAttributes,
1588: &ioStatus,
1589: NULL,
1590: FILE_ATTRIBUTE_NORMAL,
1591: FILE_SHARE_READ | FILE_SHARE_WRITE,
1592: FILE_OPEN,
1593: FILE_SYNCHRONOUS_IO_NONALERT,
1594: NULL,
1595: 0);
1596:
1597: Dump ("Volume %ls open NTSTATUS 0x%08x\n", volumeName, ntStatus);
1598:
1599: if (!NT_SUCCESS (ntStatus))
1600: return ntStatus;
1601:
1602: ntStatus = ObReferenceObjectByHandle (*volumeHandle,
1603: FILE_READ_DATA,
1604: NULL,
1605: KernelMode,
1606: fileObject,
1607: NULL);
1608:
1609: Dump ("ObReferenceObjectByHandle NTSTATUS 0x%08x\n", ntStatus);
1610:
1611: if (!NT_SUCCESS (ntStatus))
1612: {
1613: ZwClose(*volumeHandle);
1614: return ntStatus;
1615: }
1616:
1617: return ntStatus;
1618: }
1619:
1620:
1621: void
1622: TCCloseFsVolume (HANDLE volumeHandle, PFILE_OBJECT fileObject)
1623: {
1624: ObDereferenceObject (fileObject);
1625: ZwClose (volumeHandle);
1626: }
1627:
1628:
1629: NTSTATUS
1630: TCFsctlCall (PFILE_OBJECT fileObject, LONG IoControlCode,
1631: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
1632: {
1633: IO_STATUS_BLOCK ioStatusBlock;
1634: NTSTATUS ntStatus;
1635: PIRP irp;
1636: KEVENT event;
1637: PIO_STACK_LOCATION stack;
1638: PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject);
1639:
1640: Dump ("IoGetRelatedDeviceObject = 0x%08x\n", deviceObject);
1641:
1642: KeInitializeEvent(&event, NotificationEvent, FALSE);
1643:
1644: irp = IoBuildDeviceIoControlRequest (IoControlCode,
1645: deviceObject,
1646: InputBuffer, InputBufferSize,
1647: OutputBuffer, OutputBufferSize,
1648: FALSE,
1649: &event,
1650: &ioStatusBlock);
1651:
1652: if (irp == NULL)
1653: {
1654: Dump ("IRP allocation failed\n");
1655: return STATUS_INSUFFICIENT_RESOURCES;
1656: }
1657:
1658: stack = IoGetNextIrpStackLocation(irp);
1659:
1660: stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
1661: stack->MinorFunction = IRP_MN_USER_FS_REQUEST;
1662: stack->FileObject = fileObject;
1663:
1664: Dump("TCFsctlCall IoCallDriver\n");
1665:
1666: ntStatus = IoCallDriver (deviceObject, irp);
1667: if (ntStatus == STATUS_PENDING)
1668: {
1669: KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL);
1670: ntStatus = ioStatusBlock.Status;
1671: }
1672:
1673: return ntStatus;
1674: }
1675:
1676:
1677: NTSTATUS
1.1.1.6 root 1678: CreateDriveLink (int nDosDriveNo)
1679: {
1.1.1.7 root 1680: WCHAR dev[256], link[256];
1.1.1.6 root 1681: UNICODE_STRING deviceName, symLink;
1682: NTSTATUS ntStatus;
1683:
1684: TCGetNTNameFromNumber (dev, nDosDriveNo);
1685: TCGetDosNameFromNumber (link, nDosDriveNo);
1686:
1687: RtlInitUnicodeString (&deviceName, dev);
1688: RtlInitUnicodeString (&symLink, link);
1689:
1690: ntStatus = IoCreateSymbolicLink (&symLink, &deviceName);
1691: Dump ("IoCreateSymbolicLink returned %X\n", ntStatus);
1692: return ntStatus;
1693: }
1694:
1695:
1696: NTSTATUS
1697: RemoveDriveLink (int nDosDriveNo)
1698: {
1.1.1.7 root 1699: WCHAR link[256];
1.1.1.6 root 1700: UNICODE_STRING symLink;
1701: NTSTATUS ntStatus;
1702:
1703: TCGetDosNameFromNumber (link, nDosDriveNo);
1704: RtlInitUnicodeString (&symLink, link);
1705:
1706: ntStatus = IoDeleteSymbolicLink (&symLink);
1707: Dump ("IoDeleteSymbolicLink returned %X\n", ntStatus);
1708: return ntStatus;
1709: }
1710:
1711:
1712: NTSTATUS
1.1.1.4 root 1713: MountManagerMount (MOUNT_STRUCT *mount)
1714: {
1715: NTSTATUS ntStatus;
1.1.1.7 root 1716: WCHAR arrVolume[256];
1.1.1.4 root 1717: char buf[200];
1718: PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf;
1719: PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf;
1720: UNICODE_STRING symName, devName;
1721:
1722: TCGetNTNameFromNumber (arrVolume, mount->nDosDriveNo);
1723: in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2;
1724: wcscpy(in->DeviceName, arrVolume);
1725:
1726: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
1727: in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0);
1728:
1729: memset (buf, 0, sizeof buf);
1730: TCGetDosNameFromNumber ((PWSTR) &point[1], mount->nDosDriveNo);
1731:
1732: point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
1733: point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;
1734:
1735: RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset));
1736:
1737: point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength;
1738: TCGetNTNameFromNumber ((PWSTR) (buf + point->DeviceNameOffset), mount->nDosDriveNo);
1739: point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2;
1740:
1741: RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset));
1742:
1743: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point,
1744: point->DeviceNameOffset + point->DeviceNameLength, 0, 0);
1745:
1746: return ntStatus;
1747: }
1748:
1749:
1750: NTSTATUS
1751: MountManagerUnmount (int nDosDriveNo)
1752: {
1753: NTSTATUS ntStatus;
1.1.1.7 root 1754: char buf[256], out[300];
1.1.1.4 root 1755: PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf;
1756:
1757: memset (buf, 0, sizeof buf);
1758:
1759: TCGetDosNameFromNumber ((PWSTR) &in[1], nDosDriveNo);
1760:
1761: in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
1762: in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2;
1763:
1764: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS,
1765: in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out);
1766:
1767: Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus);
1768:
1769: return ntStatus;
1770: }
1771:
1772:
1773: NTSTATUS
1774: MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount)
1775: {
1776: PDEVICE_OBJECT NewDeviceObject;
1777: NTSTATUS ntStatus;
1778:
1.1.1.6 root 1779: /* Make sure the user is asking for a reasonable
1.1.1.4 root 1780: nDosDriveNo */
1781: if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25)
1782: {
1783: Dump ("Mount request looks valid\n");
1784: }
1785: else
1786: {
1787: Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n");
1.1.1.6 root 1788: mount->nReturnCode = ERR_BAD_DRIVE_LETTER;
1.1.1.4 root 1789: return ERR_BAD_DRIVE_LETTER;
1790: }
1791:
1.1.1.6 root 1792: if (!SelfTestsPassed)
1793: {
1794: mount->nReturnCode = ERR_SELF_TESTS_FAILED;
1795: return ERR_SELF_TESTS_FAILED;
1796: }
1797:
1.1.1.4 root 1798: ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
1799: mount);
1800: if (!NT_SUCCESS (ntStatus))
1801: {
1802: Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
1803: return ntStatus;
1804: }
1805: else
1806: {
1807: PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension;
1808: ntStatus = TCStartThread (NewDeviceObject, NewExtension, mount);
1809: if (!NT_SUCCESS (ntStatus))
1810: {
1811: Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus);
1812: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
1813: return ntStatus;
1814: }
1815: else
1816: {
1817: if (mount->nReturnCode == 0)
1818: {
1819: Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode,
1820: NewExtension->bReadOnly);
1.1.1.6 root 1821: if (NewExtension->bReadOnly)
1.1.1.4 root 1822: NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
1823: NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1824:
1.1.1.6 root 1825: NewExtension->UniqueVolumeId = LastUniqueVolumeId++;
1826:
1.1.1.4 root 1827: if (mount->bMountManager)
1828: MountManagerMount (mount);
1829:
1.1.1.6 root 1830: NewExtension->bMountManager = mount->bMountManager;
1.1.1.4 root 1831:
1.1.1.6 root 1832: // We create symbolic link even if mount manager is notified of
1833: // arriving volume as it apparently sometimes fails to create the link
1834: CreateDriveLink (mount->nDosDriveNo);
1.1.1.4 root 1835: }
1836: else
1837: {
1838: Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode);
1839: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
1840: }
1841:
1842: return STATUS_SUCCESS;
1843: }
1844: }
1845: }
1846:
1847: NTSTATUS
1848: UnmountDevice (PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles)
1849: {
1850: PEXTENSION extension = deviceObject->DeviceExtension;
1851: NTSTATUS ntStatus;
1852: HANDLE volumeHandle;
1853: PFILE_OBJECT volumeFileObject;
1854:
1.1.1.8 root 1855: Dump ("UnmountDevice %d\n", extension->nDosDriveNo);
1856:
1.1.1.4 root 1857: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
1858: if (!NT_SUCCESS (ntStatus))
1.1.1.6 root 1859: {
1860: // User may have deleted symbolic link
1861: CreateDriveLink (extension->nDosDriveNo);
1862:
1863: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
1864: }
1865:
1.1.1.8 root 1866: if (NT_SUCCESS (ntStatus))
1867: {
1868: // Lock volume
1869: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
1870: Dump ("FSCTL_LOCK_VOLUME returned %X\n", ntStatus);
1871:
1872: if (!NT_SUCCESS (ntStatus) && !ignoreOpenFiles)
1873: {
1874: TCCloseFsVolume (volumeHandle, volumeFileObject);
1875: return ERR_FILES_OPEN;
1876: }
1.1.1.4 root 1877:
1.1.1.8 root 1878: // Dismount volume
1879: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
1880: Dump ("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus);
1881: }
1882: else
1.1.1.4 root 1883: {
1.1.1.8 root 1884: // Volume cannot be opened => force dismount if allowed
1885: if (!ignoreOpenFiles)
1886: return ERR_FILES_OPEN;
1887: else
1888: volumeHandle = NULL;
1.1.1.4 root 1889: }
1890:
1891: extension->bShuttingDown = TRUE;
1892: if (deviceObject->Vpb && deviceObject->Vpb->Flags & VPB_MOUNTED)
1893: {
1894: deviceObject->Flags |= DO_VERIFY_VOLUME;
1895: }
1896:
1897: if (extension->bMountManager)
1898: MountManagerUnmount (extension->nDosDriveNo);
1.1.1.8 root 1899:
1.1.1.6 root 1900: // We always remove symbolic link as mount manager might fail to do so
1901: RemoveDriveLink (extension->nDosDriveNo);
1.1.1.4 root 1902:
1.1.1.8 root 1903: if (volumeHandle != NULL)
1904: TCCloseFsVolume (volumeHandle, volumeFileObject);
1.1.1.4 root 1905:
1906: Dump ("Deleting DeviceObject with ref count %ld\n", deviceObject->ReferenceCount);
1907: deviceObject->ReferenceCount = 0;
1908: TCDeleteDeviceObject (deviceObject, (PEXTENSION) deviceObject->DeviceExtension);
1909: return 0;
1910: }
1911:
1912: NTSTATUS
1.1.1.8 root 1913: UnmountAllDevices (PDEVICE_OBJECT DeviceObject, BOOL ignoreOpenFiles, BOOL unmountSystem, BOOL unmountPersistent)
1.1.1.4 root 1914: {
1915: NTSTATUS status = 0;
1916: PDEVICE_OBJECT ListDevice;
1917:
1918: Dump ("Unmounting all volumes\n");
1919:
1.1.1.9 ! root 1920: if (!DeviceObject || !DeviceObject->DriverObject)
! 1921: return STATUS_INVALID_PARAMETER;
! 1922:
1.1.1.5 root 1923: DriverMutexWait ();
1924:
1.1.1.4 root 1925: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
1926: ListDevice != (PDEVICE_OBJECT) NULL;
1927: ListDevice = ListDevice->NextDevice)
1928: {
1929: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.8 root 1930: if (ListExtension->bRootDevice == FALSE)
1.1.1.4 root 1931: {
1.1.1.8 root 1932: if (!ListExtension->bShuttingDown
1933: && (unmountSystem || !ListExtension->bSystemVolume)
1934: && (unmountPersistent || !ListExtension->bPersistentVolume))
1935: {
1936: NTSTATUS ntStatus = UnmountDevice (ListDevice, ignoreOpenFiles);
1937: status = ntStatus == 0 ? status : ntStatus;
1938: }
1939: else if (unmountPersistent
1940: && ListExtension->bSystemVolume
1941: && !ListExtension->bShuttingDown)
1942: {
1943: // If the driver is shutting down, set system volumes to reject
1944: // all IO requests so that OS does not complain because of paging files
1945: Dump ("System volume %d shutdown\n", ListExtension->nDosDriveNo);
1946: ListExtension->bShuttingDown = TRUE;
1947: }
1.1.1.4 root 1948: }
1.1.1.8 root 1949:
1950: if (ListDevice == NULL)
1951: break;
1.1.1.4 root 1952: }
1953:
1.1.1.5 root 1954: DriverMutexRelease ();
1955:
1.1.1.4 root 1956: return status;
1957: }
1958:
1959: // Resolves symbolic link name to its target name
1960: NTSTATUS
1961: SymbolicLinkToTarget (PWSTR symlinkName, PWSTR targetName, USHORT maxTargetNameLength)
1962: {
1963: NTSTATUS ntStatus;
1964: OBJECT_ATTRIBUTES objectAttributes;
1965: UNICODE_STRING fullFileName;
1966: HANDLE handle;
1967:
1968: RtlInitUnicodeString (&fullFileName, symlinkName);
1969: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
1970:
1971: ntStatus = ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes);
1972:
1973: if (NT_SUCCESS (ntStatus))
1974: {
1975: UNICODE_STRING target;
1976: target.Buffer = targetName;
1977: target.Length = 0;
1978: target.MaximumLength = maxTargetNameLength;
1979: memset (targetName, 0, maxTargetNameLength);
1980:
1981: ntStatus = ZwQuerySymbolicLinkObject (handle, &target, NULL);
1982:
1983: ZwClose (handle);
1984: }
1985:
1986: return ntStatus;
1987: }
1.1.1.6 root 1988:
1989: // Checks if two regions overlap (borders are parts of regions)
1990: BOOL RegionsOverlap (unsigned __int64 start1, unsigned __int64 end1, unsigned __int64 start2, unsigned __int64 end2)
1991: {
1992: return (start1 < start2) ? (end1 >= start2) : (start1 <= end2);
1993: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.