|
|
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
3: additions to that source code contained in this file are Copyright (c) 2004
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:
29: /* Sync. mutex for above password data */
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:
437: /* TCDeviceControl handles certain requests from NT, these are needed for NT
1.1.1.4 ! root 438: to recognize the drive, also this function handles our device specific
1.1 root 439: function codes, such as mount/unmount */
440: NTSTATUS
441: TCDeviceControl (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
442: {
443: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
444: NTSTATUS ntStatus;
445:
446: #ifdef _DEBUG
447: Dump ("TCDeviceControl BEGIN IoControlCode = %ls 0x%08x\n",
448: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode),
449: irpSp->Parameters.DeviceIoControl.IoControlCode);
450: #endif
451:
452: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; /* Assume failure. */
453:
454: /* Determine which I/O control code was specified. */
455: switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
456: {
457:
458: case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
459: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_NAME))
460: {
461: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
462: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
463: }
464: else
465: {
466: ULONG outLength;
467: UNICODE_STRING ntUnicodeString;
468: WCHAR ntName[64];
469: PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer;
470:
471: Dump("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:");
472:
473: TCGetNTNameFromNumber (ntName, Extension->nDosDriveNo);
474: RtlInitUnicodeString (&ntUnicodeString, ntName);
475:
476: outputBuffer->NameLength = ntUnicodeString.Length;
477: outLength = ntUnicodeString.Length + sizeof(USHORT);
478:
479: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
480: {
481: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
482: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
483:
484: break;
485: }
486:
487: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
488:
489: Irp->IoStatus.Status = STATUS_SUCCESS;
490: Irp->IoStatus.Information = outLength;
491:
492: Dump ("name = %ls\n",ntName);
493: }
494: break;
495:
496: case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
497: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_UNIQUE_ID))
498: {
499: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
500: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
501: }
502: else
503: {
504: ULONG outLength;
505: UCHAR volId[128], tmp[] = { 0,0 };
506: PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer;
507:
508: Dump("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:");
509:
510: strcpy (volId, TC_UNIQUE_ID_PREFIX);
511: tmp[0] = 'A' + Extension->nDosDriveNo;
512: strcat (volId, tmp);
513:
514: outputBuffer->UniqueIdLength = (USHORT) strlen(volId);
515: outLength = strlen(volId) + sizeof(USHORT);
516:
517: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
518: {
519: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
520: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
521: break;
522: }
523:
524: RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen(volId));
525:
526: Irp->IoStatus.Status = STATUS_SUCCESS;
527: Irp->IoStatus.Information = outLength;
528:
529: Dump ("id = %s\n",volId);
530: }
531: break;
532:
533: case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
534: {
535: ULONG outLength;
536: UNICODE_STRING ntUnicodeString;
537: WCHAR ntName[64];
538: PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer;
539:
540: Dump("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:");
541:
542: TCGetDosNameFromNumber (ntName, Extension->nDosDriveNo);
543: RtlInitUnicodeString (&ntUnicodeString, ntName);
544:
545: outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length;
546:
547: outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE;
548: outputBuffer->NameLength = ntUnicodeString.Length;
549:
550: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
551: {
552: Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME);
553: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
554: break;
555: }
556:
557: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
558:
559: Irp->IoStatus.Status = STATUS_SUCCESS;
560: Irp->IoStatus.Information = outLength;
561:
562: Dump ("link = %ls\n",ntName);
563: }
564: break;
565:
1.1.1.4 ! root 566:
1.1 root 567: case IOCTL_DISK_GET_MEDIA_TYPES:
568: case IOCTL_DISK_GET_DRIVE_GEOMETRY:
569: /* Return the drive geometry for the disk. Note that we
570: return values which were made up to suit the disk size. */
571: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
572: sizeof (DISK_GEOMETRY))
573: {
574: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
575: Irp->IoStatus.Information = 0;
576: }
577: else
578: {
579: PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY)
580: Irp->AssociatedIrp.SystemBuffer;
581:
1.1.1.4 ! root 582: outputBuffer->MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia;
1.1 root 583: outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders;
584: outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder;
585: outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack;
586: outputBuffer->BytesPerSector = Extension->BytesPerSector;
587: Irp->IoStatus.Status = STATUS_SUCCESS;
588: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY);
589: }
590: break;
591:
592: case IOCTL_DISK_GET_PARTITION_INFO:
593: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
594: sizeof (PARTITION_INFORMATION))
595: {
596: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
597: Irp->IoStatus.Information = 0;
598: }
599: else
600: {
601: PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION)
602: Irp->AssociatedIrp.SystemBuffer;
603:
604: outputBuffer->PartitionType = Extension->PartitionType;
605: outputBuffer->BootIndicator = FALSE;
606: outputBuffer->RecognizedPartition = TRUE;
607: outputBuffer->RewritePartition = FALSE;
608: outputBuffer->StartingOffset = RtlConvertUlongToLargeInteger (0);
609: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength;
610: outputBuffer->HiddenSectors = 1L;
611: Irp->IoStatus.Status = STATUS_SUCCESS;
612: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION);
613: }
614: break;
615:
616: case IOCTL_DISK_GET_LENGTH_INFO:
617: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GET_LENGTH_INFORMATION))
618: {
619: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
620: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
621: }
622: else
623: {
624: PGET_LENGTH_INFORMATION outputBuffer = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
625:
626: outputBuffer->Length.QuadPart = Extension->DiskLength;
627: Irp->IoStatus.Status = STATUS_SUCCESS;
628: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
629: }
630: break;
631:
632: case IOCTL_DISK_VERIFY:
633: {
634: PVERIFY_INFORMATION pVerifyInformation;
635: pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
636: irpSp->Parameters.Read.ByteOffset.LowPart =
637: pVerifyInformation->StartingOffset.LowPart;
638: irpSp->Parameters.Read.ByteOffset.HighPart =
639: pVerifyInformation->StartingOffset.HighPart;
640: irpSp->Parameters.Read.Length = pVerifyInformation->Length;
641: Irp->IoStatus.Status = STATUS_SUCCESS;
642: Irp->IoStatus.Information = pVerifyInformation->Length;
643: }
644: break;
645:
646: case IOCTL_DISK_CHECK_VERIFY:
647: {
648: Irp->IoStatus.Status = STATUS_SUCCESS;
649: Irp->IoStatus.Information = 0;
650: }
651: break;
652:
653: case IOCTL_DISK_IS_WRITABLE:
654: {
655: if (Extension->bReadOnly == TRUE)
656: Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
657: else
658: Irp->IoStatus.Status = STATUS_SUCCESS;
659: Irp->IoStatus.Information = 0;
660:
661: }
662: break;
663:
664: case DRIVER_VERSION:
665: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 4)
666: {
667: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
668: Irp->IoStatus.Information = 0;
669: }
670: else
671: {
672: LONG tmp = VERSION_NUM;
673: memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4);
674: Irp->IoStatus.Information = 4;
675: Irp->IoStatus.Status = STATUS_SUCCESS;
676: }
677: break;
678:
679: case OPEN_TEST:
680: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (OPEN_TEST_STRUCT))
681: {
682: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
683: Irp->IoStatus.Information = 0;
684: }
685: else
686: {
687: OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
688: OBJECT_ATTRIBUTES ObjectAttributes;
689: HANDLE NtFileHandle;
690: UNICODE_STRING FullFileName;
691: IO_STATUS_BLOCK IoStatus;
692:
693: RtlInitUnicodeString (&FullFileName, opentest->wszFileName);
694:
695: InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE,
696: NULL, NULL);
697:
698: ntStatus = ZwCreateFile (&NtFileHandle,
699: SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none */ ,
1.1.1.4 ! root 700: FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT |
1.1 root 701: FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS,
702: NULL /* eabuffer */ , 0 /* ealength */ );
703:
704: if (NT_SUCCESS (ntStatus))
705: {
706: ZwClose (NtFileHandle);
707: Dump ("Open test on file %ls success.\n", opentest->wszFileName);
708: }
709: else
710: {
711: Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus);
712: }
713:
714: Irp->IoStatus.Information = 0;
715: Irp->IoStatus.Status = ntStatus;
716: }
717: break;
718:
719: case WIPE_CACHE:
720: KeWaitForMutexObject (&driverMutex, Executive, KernelMode,
721: FALSE, NULL);
722:
723: WipeCache ();
724:
725: KeReleaseMutex (&driverMutex, FALSE);
726:
727: Irp->IoStatus.Status = STATUS_SUCCESS;
728: Irp->IoStatus.Information = 0;
729: break;
730:
731: case CACHE_STATUS:
732: Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS;
733: Irp->IoStatus.Information = 0;
734: break;
735:
736: #ifdef DEBUG
737: case HALT_SYSTEM:
738: KeBugCheck ((ULONG) 0x5050);
739: break;
740: #endif
741:
742: case MOUNT_LIST:
743: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT))
744: {
745: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
746: Irp->IoStatus.Information = 0;
747: }
748: else
749: {
750: MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
751: PDEVICE_OBJECT ListDevice;
752:
753: list->ulMountedDrives = 0;
754: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
755: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
756: {
757:
758: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
759: if (ListExtension->bRootDevice == FALSE)
760: {
761: list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo);
762: wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume);
763: list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength;
1.1.1.4 ! root 764: list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea;
! 765: list->hiddenVol[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->hiddenVolume;
1.1 root 766: }
767: }
768:
769: Irp->IoStatus.Status = STATUS_SUCCESS;
770: Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT);
771: }
772: break;
773:
774: case VOLUME_PROPERTIES:
775: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT))
776: {
777: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
778: Irp->IoStatus.Information = 0;
779: }
780: else
781: {
782: VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
783: PDEVICE_OBJECT ListDevice;
784:
785: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
786: Irp->IoStatus.Information = 0;
787:
788: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
789: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
790: {
791:
792: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
793: if (ListExtension->bRootDevice == FALSE && ListExtension->nDosDriveNo == prop->driveNo)
794: {
795: wcscpy (prop->wszVolume, ListExtension->wszVolume);
796: prop->diskLength = ListExtension->DiskLength;
1.1.1.4 ! root 797: prop->ea = ListExtension->cryptoInfo->ea;
1.1 root 798: prop->pkcs5 = ListExtension->cryptoInfo->pkcs5;
799: prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations;
800: prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time;
801: prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time;
1.1.1.4 ! root 802: prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume;
1.1 root 803:
804: Irp->IoStatus.Status = STATUS_SUCCESS;
805: Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT);
806: break;
807: }
808: }
809: }
810: break;
811:
1.1.1.4 ! root 812: case RESOLVE_SYMLINK:
! 813: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT))
! 814: {
! 815: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
! 816: Irp->IoStatus.Information = 0;
! 817: }
! 818: else
1.1 root 819: {
1.1.1.4 ! root 820: RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
! 821: {
! 822: NTSTATUS ntStatus;
! 823:
! 824: ntStatus = SymbolicLinkToTarget (resolve->symLinkName,
! 825: resolve->targetName,
! 826: sizeof (resolve->targetName));
! 827:
! 828: Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT);
! 829: Irp->IoStatus.Status = ntStatus;
! 830: }
! 831:
! 832: }
! 833: break;
! 834:
! 835: case MOUNT:
! 836: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT))
! 837: {
! 838: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
! 839: Irp->IoStatus.Information = 0;
! 840: }
! 841: else
! 842: {
! 843: MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
! 844:
! 845: Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
! 846: Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
1.1 root 847: }
848: break;
849:
850: case UNMOUNT:
851: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
852: {
853: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
854: Irp->IoStatus.Information = 0;
855: }
856: else
857: {
858: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
859: PDEVICE_OBJECT ListDevice;
860:
861: unmount->nReturnCode = ERR_DRIVE_NOT_FOUND;
862:
863: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
864: ListDevice != (PDEVICE_OBJECT) NULL;
865: ListDevice = ListDevice->NextDevice)
866: {
867: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
868:
1.1.1.4 ! root 869: if (ListExtension->bRootDevice == FALSE
! 870: && unmount->nDosDriveNo == ListExtension->nDosDriveNo)
1.1 root 871: {
1.1.1.4 ! root 872: unmount->nReturnCode = UnmountDevice (ListDevice, unmount->ignoreOpenFiles);
! 873: break;
! 874: }
! 875: }
1.1 root 876:
1.1.1.4 ! root 877: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
1.1 root 878: Irp->IoStatus.Status = STATUS_SUCCESS;
879: }
880: break;
881:
1.1.1.4 ! root 882: case UNMOUNT_ALL:
! 883: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
1.1 root 884: {
885: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
886: Irp->IoStatus.Information = 0;
887: }
888: else
889: {
1.1.1.4 ! root 890: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1.1 root 891:
1.1.1.4 ! root 892: unmount->nReturnCode = UnmountAllDevices (DeviceObject, unmount->ignoreOpenFiles);
1.1 root 893:
1.1.1.4 ! root 894: Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
! 895: Irp->IoStatus.Status = STATUS_SUCCESS;
1.1 root 896: }
897: break;
898: }
899:
900: /* Finish the I/O operation by simply completing the packet and
901: returning the same NTSTATUS as in the packet itself. */
902: ntStatus = COMPLETE_IRP (DeviceObject, Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
903: Dump ("TCDeviceControl NTSTATUS = 0x%08x END\n", ntStatus);
904: return ntStatus;
905: }
906:
907: NTSTATUS
908: TCStartThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount)
909: {
910: PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK));
911: HANDLE hThread;
912: NTSTATUS ntStatus;
913:
914: Dump ("Starting thread...\n");
915:
916: if (pThreadBlock == NULL)
917: {
918: return STATUS_INSUFFICIENT_RESOURCES;
919: }
920: else
921: {
922: pThreadBlock->DeviceObject = DeviceObject;
923: pThreadBlock->mount = mount;
924: }
925:
926: Extension->bThreadShouldQuit = FALSE;
927:
928: ntStatus = PsCreateSystemThread (&hThread,
929: THREAD_ALL_ACCESS,
930: NULL,
931: NULL,
932: NULL,
933: TCThreadIRP,
934: pThreadBlock);
935:
936: if (!NT_SUCCESS (ntStatus))
937: {
938: Dump ("PsCreateSystemThread Failed END\n");
939: TCfree (pThreadBlock);
940: return ntStatus;
941: }
942:
943: ObReferenceObjectByHandle (hThread,
944: THREAD_ALL_ACCESS,
945: NULL,
946: KernelMode,
947: &Extension->peThread,
948: NULL);
949: ZwClose (hThread);
950:
951: Dump ("Waiting for thread to initialize...\n");
952:
953: KeWaitForSingleObject (&Extension->keCreateEvent,
954: UserRequest,
955: UserMode,
956: FALSE,
957: NULL);
958:
959: Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus);
960: ntStatus = pThreadBlock->ntCreateStatus;
961: TCfree (pThreadBlock);
962: return ntStatus;
963: }
964:
965: void
966: TCStopThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
967: {
968: NTSTATUS ntStatus;
969:
970: if (DeviceObject); /* Remove compiler warning */
971:
972: Dump ("Signalling thread to quit...\n");
973:
974: Extension->bThreadShouldQuit = TRUE;
975:
976: KeReleaseSemaphore (&Extension->RequestSemaphore,
977: 0,
978: 1,
979: TRUE);
980:
1.1.1.4 ! root 981: ntStatus = KeWaitForSingleObject (Extension->peThread,
1.1 root 982: UserRequest,
983: UserMode,
984: FALSE,
985: NULL);
986: if (ntStatus != STATUS_SUCCESS)
987: Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n",
988: ntStatus);
989:
990: ObDereferenceObject (&Extension->peThread);
991: Extension->peThread = NULL;
992:
993: Dump ("Thread exited!\n");
994: }
995:
996: /* TCThreadIRP does all the work of processing IRP's, and dispatching them
997: to either the ReadWrite function or the DeviceControl function */
998: VOID
999: TCThreadIRP (PVOID Context)
1000: {
1001: PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context;
1002: PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject;
1003: PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
1004: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
1005: LARGE_INTEGER queueWait;
1006: BOOL bDevice;
1007:
1008: /* Set thread priority to lowest realtime level. */
1009:
1010: KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY);
1011:
1012: queueWait.QuadPart = -WAIT_SECONDS (1);
1013:
1014: Dump ("Mount THREAD OPENING VOLUME BEGIN\n");
1015:
1016: #ifdef USE_KERNEL_MUTEX
1017: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
1018: FALSE, NULL);
1019: #endif
1020:
1021: if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0)
1022: {
1023: wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\"));
1024: wcscat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume);
1025: bDevice = FALSE;
1026: }
1027: else
1028: {
1029: wcscpy (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume);
1030: bDevice = TRUE;
1031: }
1032:
1033: Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n",
1034: pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice);
1035:
1036: pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject,
1037: Extension,
1038: pThreadBlock->mount,
1039: pThreadBlock->wszMountVolume,
1040: bDevice);
1041:
1042: #ifdef USE_KERNEL_MUTEX
1043: KeReleaseMutex (&Extension->KernelMutex, FALSE);
1044: #endif
1045:
1046: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0)
1047: {
1048: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1049: PsTerminateSystemThread (STATUS_SUCCESS);
1050: }
1051: else
1052: {
1053: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1054: /* From this point on pThreadBlock cannot be used as it will
1055: have been released! */
1056: pThreadBlock = NULL;
1057: }
1058:
1059:
1060: for (;;)
1061: {
1062: NTSTATUS ntStatus;
1063:
1064: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1065:
1066: /* Wait for a request from the dispatch routines. */
1067: ntStatus = KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore,
1068: Executive, KernelMode, FALSE, &queueWait);
1069:
1070: if (ntStatus != STATUS_TIMEOUT)
1071: {
1072:
1073: #ifdef USE_KERNEL_MUTEX
1074: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
1075: FALSE, NULL);
1076: #endif
1077:
1078: // Dump ("DRIVER THREAD PROCESSING DEVICEOBJECT 0x%08x \n", DeviceObject);
1079:
1080: for (;;)
1081: {
1082: PIO_STACK_LOCATION irpSp;
1083: PLIST_ENTRY request;
1084: PIRP Irp;
1085:
1086: request = ExInterlockedRemoveHeadList (&Extension->ListEntry,
1087: &Extension->ListSpinLock);
1088: if (request == NULL)
1089: break;
1090:
1091: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1092:
1093: Irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry);
1094: irpSp = IoGetCurrentIrpStackLocation (Irp);
1095:
1096: switch (irpSp->MajorFunction)
1097: {
1098: case IRP_MJ_READ:
1099: case IRP_MJ_WRITE:
1100: TCReadWrite (DeviceObject, Extension, Irp);
1101: break;
1102:
1103: case IRP_MJ_FLUSH_BUFFERS:
1104: if (Extension->bRawDevice == FALSE)
1105: TCSendIRP_FileDevice (DeviceObject, Extension, NULL, Irp->Flags, IRP_MJ_FLUSH_BUFFERS, Irp);
1106: else
1107: {
1108: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
1109: }
1110: break;
1111:
1112: case IRP_MJ_SHUTDOWN:
1113: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
1114: break;
1115:
1116: case IRP_MJ_DEVICE_CONTROL:
1117: if (irpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_DISK_CHECK_VERIFY)
1118: TCDeviceControl (DeviceObject, Extension, Irp);
1119: else
1120: {
1121: if (Extension->bRawDevice == TRUE)
1122: TCSendIRP_RawDevice (DeviceObject, Extension, NULL, 0, IRP_MJ_DEVICE_CONTROL, Irp);
1123: else
1124: TCDeviceControl (DeviceObject, Extension, Irp);
1125: }
1126: break;
1127: } /* end of switch on
1128: irpSp->MajorFunction */
1129: } /* for any remaining IRP's for this device */
1130:
1131: #ifdef USE_KERNEL_MUTEX
1132: KeReleaseMutex (&Extension->KernelMutex, FALSE);
1133: #endif
1134:
1135: if (Extension->bThreadShouldQuit)
1136: {
1137: // Dump ("END PROCESSING DEVICEOBJECT THREAD ENDING 0x%08x Number = %d\n",
1138: // DeviceObject, Extension->nDosDriveNo);
1139: Dump ("Closing volume along with Thread!\n");
1140: TCCloseVolume (DeviceObject, Extension);
1141: PsTerminateSystemThread (STATUS_SUCCESS);
1142: }
1143: //else
1144: //{
1145: // Dump ("END PROCESSING DEVICEOBJECT 0x%08x Number = %d\n",
1146: // DeviceObject, Extension->nDosDriveNo);
1147: //}
1148: }
1149:
1150: } /* outermost for */
1151: }
1152:
1153: void
1154: TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)
1155: {
1156: WCHAR tmp[3] =
1157: {0, ':', 0};
1158: int j = nDriveNo + (WCHAR) 'A';
1159:
1160: tmp[0] = (short) j;
1161: wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
1162: wcsncat (ntname, tmp, 1);
1163: }
1164:
1165: void
1166: TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo)
1167: {
1168: WCHAR tmp[3] =
1169: {0, ':', 0};
1170: int j = nDriveNo + (WCHAR) 'A';
1171:
1172: tmp[0] = (short) j;
1173: wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX);
1174: wcscat (dosname, tmp);
1175: }
1176:
1177: #ifdef _DEBUG
1178: LPWSTR
1179: TCTranslateCode (ULONG ulCode)
1180: {
1181: if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY)
1182: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY");
1183: else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)
1184: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX");
1185: else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME)
1186: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME");
1187: else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME)
1188: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME");
1189: else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID)
1190: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID");
1191: else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY)
1192: return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY");
1193: else if (ulCode == IOCTL_VOLUME_ONLINE)
1194: return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE");
1195: else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED)
1196: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED");
1197: else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED)
1198: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED");
1199: else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS)
1200: return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS");
1201: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED)
1202: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED");
1203: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED)
1204: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED");
1205: else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO)
1206: return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO");
1207: else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER)
1208: return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER");
1209: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO)
1210: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO");
1211: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX)
1212: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX");
1213: else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO)
1214: return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO");
1215: else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT)
1216: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT");
1217: else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX)
1218: return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX");
1219: else if (ulCode == IOCTL_DISK_VERIFY)
1220: return (LPWSTR) _T ("IOCTL_DISK_VERIFY");
1221: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS)
1222: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS");
1223: else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS)
1224: return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS");
1225: else if (ulCode == IOCTL_DISK_PERFORMANCE)
1226: return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE");
1227: else if (ulCode == IOCTL_DISK_IS_WRITABLE)
1228: return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE");
1229: else if (ulCode == IOCTL_DISK_LOGGING)
1230: return (LPWSTR) _T ("IOCTL_DISK_LOGGING");
1231: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX)
1232: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX");
1233: else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE)
1234: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE");
1235: else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA)
1236: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA");
1237: else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET)
1238: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET");
1239: else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE)
1240: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE");
1241: else if (ulCode == IOCTL_DISK_REQUEST_DATA)
1242: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA");
1243: else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER)
1244: return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER");
1245: else if (ulCode == SMART_GET_VERSION)
1246: return (LPWSTR) _T ("SMART_GET_VERSION");
1247: else if (ulCode == SMART_SEND_DRIVE_COMMAND)
1248: return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND");
1249: else if (ulCode == SMART_RCV_DRIVE_DATA)
1250: return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA");
1251: else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY)
1252: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY");
1253: else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY)
1254: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY");
1255: else if (ulCode == IOCTL_DISK_CHECK_VERIFY)
1256: return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY");
1257: else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL)
1258: return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL");
1259: else if (ulCode == IOCTL_DISK_EJECT_MEDIA)
1260: return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA");
1261: else if (ulCode == IOCTL_DISK_LOAD_MEDIA)
1262: return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA");
1263: else if (ulCode == IOCTL_DISK_RESERVE)
1264: return (LPWSTR) _T ("IOCTL_DISK_RESERVE");
1265: else if (ulCode == IOCTL_DISK_RELEASE)
1266: return (LPWSTR) _T ("IOCTL_DISK_RELEASE");
1267: else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES)
1268: return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES");
1269: else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES)
1270: return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES");
1271: else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO)
1272: return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO");
1273: else if (ulCode == IRP_MJ_READ)
1274: return (LPWSTR) _T ("IRP_MJ_READ");
1275: else if (ulCode == IRP_MJ_WRITE)
1276: return (LPWSTR) _T ("IRP_MJ_WRITE");
1277: else if (ulCode == IRP_MJ_CREATE)
1278: return (LPWSTR) _T ("IRP_MJ_CREATE");
1279: else if (ulCode == IRP_MJ_CLOSE)
1280: return (LPWSTR) _T ("IRP_MJ_CLOSE");
1281: else if (ulCode == IRP_MJ_CLEANUP)
1282: return (LPWSTR) _T ("IRP_MJ_CLEANUP");
1283: else if (ulCode == IRP_MJ_FLUSH_BUFFERS)
1284: return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS");
1285: else if (ulCode == IRP_MJ_SHUTDOWN)
1286: return (LPWSTR) _T ("IRP_MJ_SHUTDOWN");
1287: else if (ulCode == IRP_MJ_DEVICE_CONTROL)
1288: return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL");
1289: else if (ulCode == MOUNT)
1290: return (LPWSTR) _T ("MOUNT");
1291: else if (ulCode == UNMOUNT)
1292: return (LPWSTR) _T ("UNMOUNT");
1.1.1.4 ! root 1293: else if (ulCode == UNMOUNT_ALL)
! 1294: return (LPWSTR) _T ("UNMOUNT_ALL");
1.1 root 1295: else if (ulCode == MOUNT_LIST)
1296: return (LPWSTR) _T ("MOUNT_LIST");
1297: else if (ulCode == OPEN_TEST)
1298: return (LPWSTR) _T ("OPEN_TEST");
1299: else
1300: {
1.1.1.4 ! root 1301: Dump("Unknown IOCTL recieved: DeviceType = 0x%x Function = 0x%x\n", (int)(ulCode>>16), (int)((ulCode&0x1FFF)>>2));
1.1 root 1302: return (LPWSTR) _T ("UNKNOWN");
1303: }
1304: }
1305:
1306: #endif
1307:
1308: PDEVICE_OBJECT
1309: TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1310: {
1311: PDEVICE_OBJECT OldDeviceObject = DeviceObject;
1312: UNICODE_STRING Win32NameString;
1313: NTSTATUS ntStatus;
1314:
1315: Dump ("TCDeleteDeviceObject BEGIN\n");
1316:
1317: if (Extension->bRootDevice == TRUE)
1318: {
1319: RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX);
1.1.1.4 ! root 1320: ntStatus = IoDeleteSymbolicLink (&Win32NameString);
! 1321: if (!NT_SUCCESS (ntStatus))
! 1322: Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus);
1.1 root 1323: }
1324: else
1325: {
1326: if (Extension->peThread != NULL)
1327: TCStopThread (DeviceObject, Extension);
1328: }
1329:
1330: DeviceObject = DeviceObject->NextDevice;
1331: IoDeleteDevice (OldDeviceObject);
1332:
1333: Dump ("TCDeleteDeviceObject END\n");
1334: return DeviceObject;
1335: }
1336:
1.1.1.4 ! root 1337:
1.1 root 1338: VOID
1339: TCUnloadDriver (PDRIVER_OBJECT DriverObject)
1340: {
1341: PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
1342:
1343: Dump ("TCUnloadDriver BEGIN\n");
1344:
1.1.1.4 ! root 1345: UnmountAllDevices (DeviceObject, TRUE);
! 1346:
1.1 root 1347: /* Now walk the list of driver objects and get rid of them */
1348: while (DeviceObject != (PDEVICE_OBJECT) NULL)
1349: {
1350: DeviceObject = TCDeleteDeviceObject (DeviceObject,
1351: (PEXTENSION) DeviceObject->DeviceExtension);
1352: }
1353:
1354: Dump ("TCUnloadDriver END\n");
1355: }
1.1.1.4 ! root 1356:
! 1357:
! 1358: NTSTATUS
! 1359: TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode,
! 1360: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
! 1361: {
! 1362: IO_STATUS_BLOCK ioStatusBlock;
! 1363: NTSTATUS ntStatus;
! 1364: PIRP irp;
! 1365: PFILE_OBJECT fileObject;
! 1366: PDEVICE_OBJECT deviceObject;
! 1367: KEVENT event;
! 1368: UNICODE_STRING name;
! 1369:
! 1370: RtlInitUnicodeString(&name, deviceName);
! 1371: ntStatus = IoGetDeviceObjectPointer(&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
! 1372:
! 1373: if (ntStatus != STATUS_SUCCESS)
! 1374: return ntStatus;
! 1375:
! 1376: KeInitializeEvent(&event, NotificationEvent, FALSE);
! 1377:
! 1378: irp = IoBuildDeviceIoControlRequest (IoControlCode,
! 1379: deviceObject,
! 1380: InputBuffer, InputBufferSize,
! 1381: OutputBuffer, OutputBufferSize,
! 1382: FALSE,
! 1383: &event,
! 1384: &ioStatusBlock);
! 1385:
! 1386: if (irp == NULL)
! 1387: {
! 1388: Dump ("IRP allocation failed\n");
! 1389: return STATUS_INSUFFICIENT_RESOURCES;
! 1390: }
! 1391:
! 1392: ntStatus = IoCallDriver (deviceObject, irp);
! 1393: if (ntStatus == STATUS_PENDING)
! 1394: {
! 1395: KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL);
! 1396: ntStatus = ioStatusBlock.Status;
! 1397: }
! 1398:
! 1399: return ntStatus;
! 1400: }
! 1401:
! 1402:
! 1403: // Opens a mounted TC volume on filesystem level
! 1404: NTSTATUS
! 1405: TCOpenFsVolume (PEXTENSION Extension, PHANDLE volumeHandle, PFILE_OBJECT * fileObject)
! 1406: {
! 1407: NTSTATUS ntStatus;
! 1408: OBJECT_ATTRIBUTES objectAttributes;
! 1409: UNICODE_STRING fullFileName;
! 1410: IO_STATUS_BLOCK ioStatus;
! 1411: WCHAR volumeName[64];
! 1412:
! 1413: TCGetDosNameFromNumber (volumeName, Extension->nDosDriveNo);
! 1414: RtlInitUnicodeString (&fullFileName, volumeName);
! 1415: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
! 1416:
! 1417: ntStatus = ZwCreateFile (volumeHandle,
! 1418: SYNCHRONIZE | GENERIC_READ,
! 1419: &objectAttributes,
! 1420: &ioStatus,
! 1421: NULL,
! 1422: FILE_ATTRIBUTE_NORMAL,
! 1423: FILE_SHARE_READ | FILE_SHARE_WRITE,
! 1424: FILE_OPEN,
! 1425: FILE_SYNCHRONOUS_IO_NONALERT,
! 1426: NULL,
! 1427: 0);
! 1428:
! 1429: Dump ("Volume %ls open NTSTATUS 0x%08x\n", volumeName, ntStatus);
! 1430:
! 1431: if (!NT_SUCCESS (ntStatus))
! 1432: return ntStatus;
! 1433:
! 1434: ntStatus = ObReferenceObjectByHandle (*volumeHandle,
! 1435: FILE_READ_DATA,
! 1436: NULL,
! 1437: KernelMode,
! 1438: fileObject,
! 1439: NULL);
! 1440:
! 1441: Dump ("ObReferenceObjectByHandle NTSTATUS 0x%08x\n", ntStatus);
! 1442:
! 1443: if (!NT_SUCCESS (ntStatus))
! 1444: {
! 1445: ZwClose(*volumeHandle);
! 1446: return ntStatus;
! 1447: }
! 1448:
! 1449: return ntStatus;
! 1450: }
! 1451:
! 1452:
! 1453: void
! 1454: TCCloseFsVolume (HANDLE volumeHandle, PFILE_OBJECT fileObject)
! 1455: {
! 1456: ObDereferenceObject (fileObject);
! 1457: ZwClose (volumeHandle);
! 1458: }
! 1459:
! 1460:
! 1461: NTSTATUS
! 1462: TCFsctlCall (PFILE_OBJECT fileObject, LONG IoControlCode,
! 1463: void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
! 1464: {
! 1465: IO_STATUS_BLOCK ioStatusBlock;
! 1466: NTSTATUS ntStatus;
! 1467: PIRP irp;
! 1468: KEVENT event;
! 1469: PIO_STACK_LOCATION stack;
! 1470: PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject);
! 1471:
! 1472: Dump ("IoGetRelatedDeviceObject = 0x%08x\n", deviceObject);
! 1473:
! 1474: KeInitializeEvent(&event, NotificationEvent, FALSE);
! 1475:
! 1476: irp = IoBuildDeviceIoControlRequest (IoControlCode,
! 1477: deviceObject,
! 1478: InputBuffer, InputBufferSize,
! 1479: OutputBuffer, OutputBufferSize,
! 1480: FALSE,
! 1481: &event,
! 1482: &ioStatusBlock);
! 1483:
! 1484: if (irp == NULL)
! 1485: {
! 1486: Dump ("IRP allocation failed\n");
! 1487: return STATUS_INSUFFICIENT_RESOURCES;
! 1488: }
! 1489:
! 1490: stack = IoGetNextIrpStackLocation(irp);
! 1491:
! 1492: stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
! 1493: stack->MinorFunction = IRP_MN_USER_FS_REQUEST;
! 1494: stack->FileObject = fileObject;
! 1495:
! 1496: Dump("TCFsctlCall IoCallDriver\n");
! 1497:
! 1498: ntStatus = IoCallDriver (deviceObject, irp);
! 1499: if (ntStatus == STATUS_PENDING)
! 1500: {
! 1501: KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL);
! 1502: ntStatus = ioStatusBlock.Status;
! 1503: }
! 1504:
! 1505: return ntStatus;
! 1506: }
! 1507:
! 1508:
! 1509: NTSTATUS
! 1510: MountManagerMount (MOUNT_STRUCT *mount)
! 1511: {
! 1512: NTSTATUS ntStatus;
! 1513: WCHAR arrVolume[64];
! 1514: char buf[200];
! 1515: PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf;
! 1516: PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf;
! 1517: UNICODE_STRING symName, devName;
! 1518:
! 1519: TCGetNTNameFromNumber (arrVolume, mount->nDosDriveNo);
! 1520: in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2;
! 1521: wcscpy(in->DeviceName, arrVolume);
! 1522:
! 1523: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
! 1524: in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0);
! 1525:
! 1526: memset (buf, 0, sizeof buf);
! 1527: TCGetDosNameFromNumber ((PWSTR) &point[1], mount->nDosDriveNo);
! 1528:
! 1529: point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
! 1530: point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;
! 1531:
! 1532: RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset));
! 1533:
! 1534: point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength;
! 1535: TCGetNTNameFromNumber ((PWSTR) (buf + point->DeviceNameOffset), mount->nDosDriveNo);
! 1536: point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2;
! 1537:
! 1538: RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset));
! 1539:
! 1540: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point,
! 1541: point->DeviceNameOffset + point->DeviceNameLength, 0, 0);
! 1542:
! 1543: return ntStatus;
! 1544: }
! 1545:
! 1546:
! 1547: NTSTATUS
! 1548: MountManagerUnmount (int nDosDriveNo)
! 1549: {
! 1550: NTSTATUS ntStatus;
! 1551: WCHAR drive[] = {(WCHAR) nDosDriveNo + 'A', 0};
! 1552: char buf[64], out[300];
! 1553: PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf;
! 1554:
! 1555: memset (buf, 0, sizeof buf);
! 1556:
! 1557: TCGetDosNameFromNumber ((PWSTR) &in[1], nDosDriveNo);
! 1558:
! 1559: in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
! 1560: in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2;
! 1561:
! 1562: ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS,
! 1563: in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out);
! 1564:
! 1565: Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus);
! 1566:
! 1567: return ntStatus;
! 1568: }
! 1569:
! 1570:
! 1571: NTSTATUS
! 1572: MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount)
! 1573: {
! 1574: PDEVICE_OBJECT NewDeviceObject;
! 1575: NTSTATUS ntStatus;
! 1576:
! 1577: /* Make sure the user is asking for a resonable
! 1578: nDosDriveNo */
! 1579: if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25)
! 1580: {
! 1581: Dump ("Mount request looks valid\n");
! 1582: }
! 1583: else
! 1584: {
! 1585: Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n");
! 1586: return ERR_BAD_DRIVE_LETTER;
! 1587: }
! 1588:
! 1589: ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
! 1590: mount);
! 1591: if (!NT_SUCCESS (ntStatus))
! 1592: {
! 1593: Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
! 1594: return ntStatus;
! 1595: }
! 1596: else
! 1597: {
! 1598: PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension;
! 1599: ntStatus = TCStartThread (NewDeviceObject, NewExtension, mount);
! 1600: if (!NT_SUCCESS (ntStatus))
! 1601: {
! 1602: Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus);
! 1603: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
! 1604: return ntStatus;
! 1605: }
! 1606: else
! 1607: {
! 1608: if (mount->nReturnCode == 0)
! 1609: {
! 1610: Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode,
! 1611: NewExtension->bReadOnly);
! 1612: if (NewExtension->bReadOnly == TRUE)
! 1613: NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
! 1614: NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
! 1615:
! 1616: if (mount->bMountManager)
! 1617: {
! 1618: MountManagerMount (mount);
! 1619: NewExtension->bMountManager = TRUE;
! 1620: }
! 1621: else
! 1622: {
! 1623: WCHAR dev[64], link[64];
! 1624: UNICODE_STRING deviceName, symLink;
! 1625:
! 1626: TCGetNTNameFromNumber (dev, mount->nDosDriveNo);
! 1627: TCGetDosNameFromNumber (link, mount->nDosDriveNo);
! 1628:
! 1629: RtlInitUnicodeString (&deviceName, dev);
! 1630: RtlInitUnicodeString (&symLink, link);
! 1631:
! 1632: ntStatus = IoCreateSymbolicLink (&symLink, &deviceName);
! 1633: Dump ("IoCreateSymbolicLink returned %X\n", ntStatus);
! 1634: NewExtension->bMountManager = FALSE;
! 1635: }
! 1636: }
! 1637: else
! 1638: {
! 1639: Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode);
! 1640: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
! 1641: }
! 1642:
! 1643: return STATUS_SUCCESS;
! 1644: }
! 1645: }
! 1646: }
! 1647:
! 1648: NTSTATUS
! 1649: UnmountDevice (PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles)
! 1650: {
! 1651: PEXTENSION extension = deviceObject->DeviceExtension;
! 1652: NTSTATUS ntStatus;
! 1653: HANDLE volumeHandle;
! 1654: PFILE_OBJECT volumeFileObject;
! 1655:
! 1656: ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
! 1657:
! 1658: if (!NT_SUCCESS (ntStatus))
! 1659: return ERR_DRIVE_NOT_FOUND;
! 1660:
! 1661: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
! 1662: Dump ("FSCTL_LOCK_VOLUME returned %X\n", ntStatus);
! 1663:
! 1664: if (!NT_SUCCESS (ntStatus) && !ignoreOpenFiles)
! 1665: {
! 1666: TCCloseFsVolume (volumeHandle, volumeFileObject);
! 1667: return ERR_FILES_OPEN;
! 1668: }
! 1669:
! 1670: ntStatus = TCFsctlCall (volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
! 1671: Dump ("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus);
! 1672:
! 1673: extension->bShuttingDown = TRUE;
! 1674: if (deviceObject->Vpb && deviceObject->Vpb->Flags & VPB_MOUNTED)
! 1675: {
! 1676: deviceObject->Flags |= DO_VERIFY_VOLUME;
! 1677: }
! 1678:
! 1679: TCCloseFsVolume (volumeHandle, volumeFileObject);
! 1680:
! 1681: if (extension->bMountManager)
! 1682: {
! 1683: MountManagerUnmount (extension->nDosDriveNo);
! 1684: }
! 1685: else
! 1686: {
! 1687: WCHAR link[64];
! 1688: UNICODE_STRING symLink;
! 1689:
! 1690: TCGetDosNameFromNumber (link, extension->nDosDriveNo);
! 1691: RtlInitUnicodeString (&symLink, link);
! 1692:
! 1693: ntStatus = IoDeleteSymbolicLink (&symLink);
! 1694: Dump ("IoDeleteSymbolicLink returned %X\n", ntStatus);
! 1695: }
! 1696:
! 1697: Dump ("Deleting DeviceObject with ref count %ld\n", deviceObject->ReferenceCount);
! 1698: deviceObject->ReferenceCount = 0;
! 1699: TCDeleteDeviceObject (deviceObject, (PEXTENSION) deviceObject->DeviceExtension);
! 1700:
! 1701: return 0;
! 1702: }
! 1703:
! 1704: NTSTATUS
! 1705: UnmountAllDevices (PDEVICE_OBJECT DeviceObject, BOOL ignoreOpenFiles)
! 1706: {
! 1707: NTSTATUS status = 0;
! 1708: PDEVICE_OBJECT ListDevice;
! 1709:
! 1710: Dump ("Unmounting all volumes\n");
! 1711:
! 1712: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
! 1713: ListDevice != (PDEVICE_OBJECT) NULL;
! 1714: ListDevice = ListDevice->NextDevice)
! 1715: {
! 1716: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
! 1717: if (ListExtension->bRootDevice == FALSE)
! 1718: {
! 1719: NTSTATUS ntStatus = UnmountDevice (ListDevice, ignoreOpenFiles);
! 1720: status = ntStatus == 0 ? status : ntStatus;
! 1721: }
! 1722: }
! 1723:
! 1724: return status;
! 1725: }
! 1726:
! 1727: // Resolves symbolic link name to its target name
! 1728: NTSTATUS
! 1729: SymbolicLinkToTarget (PWSTR symlinkName, PWSTR targetName, USHORT maxTargetNameLength)
! 1730: {
! 1731: NTSTATUS ntStatus;
! 1732: OBJECT_ATTRIBUTES objectAttributes;
! 1733: UNICODE_STRING fullFileName;
! 1734: HANDLE handle;
! 1735:
! 1736: RtlInitUnicodeString (&fullFileName, symlinkName);
! 1737: InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
! 1738:
! 1739: ntStatus = ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes);
! 1740:
! 1741: if (NT_SUCCESS (ntStatus))
! 1742: {
! 1743: UNICODE_STRING target;
! 1744: target.Buffer = targetName;
! 1745: target.Length = 0;
! 1746: target.MaximumLength = maxTargetNameLength;
! 1747: memset (targetName, 0, maxTargetNameLength);
! 1748:
! 1749: ntStatus = ZwQuerySymbolicLinkObject (handle, &target, NULL);
! 1750:
! 1751: ZwClose (handle);
! 1752: }
! 1753:
! 1754: return ntStatus;
! 1755: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.