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