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