|
|
1.1 root 1: /* Copyright (C) 2004 TrueCrypt Team, truecrypt.org
2: This product uses components written by Paul Le Roux <[email protected]> */
3:
4: #include "TCdefs.h"
5: #include "crypto.h"
6: #include "fat.h"
7:
8: #include "apidrvr.h"
9: #include "ntdriver.h"
10: #include "ntvol.h"
11: #include "ntrawdv.h"
12: #include "ntfiledv.h"
13: #include "cache.h"
14:
15: #include <tchar.h>
16: #include <initguid.h>
17: #include <mountmgr.h>
18: #include <mountdev.h>
19: #include <ntddvol.h>
20:
21: /* Init section, which is thrown away as soon as DriverEntry returns */
22: #pragma alloc_text(INIT,DriverEntry)
23: #pragma alloc_text(INIT,TCCreateRootDeviceObject)
24:
25: /* Sync. mutex for above password data */
26: KMUTEX driverMutex;
27:
28: /* DriverEntry initialize's the dispatch addresses to be passed back to NT.
29: RUNS AT IRQL = PASSIVE_LEVEL(0) */
30: NTSTATUS
31: DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
32: {
33: if (RegistryPath); /* Remove warning */
34:
35: DriverObject->MajorFunction[IRP_MJ_CREATE] = TCDispatchQueueIRP;
36: DriverObject->MajorFunction[IRP_MJ_CLOSE] = TCDispatchQueueIRP;
37: DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TCDispatchQueueIRP;
38: DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = TCDispatchQueueIRP;
39: DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = TCDispatchQueueIRP;
40: DriverObject->MajorFunction[IRP_MJ_READ] = TCDispatchQueueIRP;
41: DriverObject->MajorFunction[IRP_MJ_WRITE] = TCDispatchQueueIRP;
42: DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TCDispatchQueueIRP;
43:
44: DriverObject->DriverUnload = TCUnloadDriver;
45:
46: KeInitializeMutex (&driverMutex, 1);
47:
48: return TCCreateRootDeviceObject (DriverObject);
49: }
50:
51: #ifdef _DEBUG
52: // Dumps a memory region to debug output
53: void DumpMem(unsigned char *mem, int len)
54: {
55: unsigned char str[20];
56: unsigned char *m = mem;
57: int i,j;
58:
59: for (j=0;j<len/8;j++)
60: {
61: memset (str,0,sizeof str);
62: for (i=0;i<8;i++)
63: {
64: if (m[i] > ' ' && m[i] < '~')
65: str[i]=m[i];
66: else
67: str[i]='.';
68: }
69:
70: Dump ("0x%08x %02x %02x %02x %02x %02x %02x %02x %02x %s",
71: m, m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], str);
72:
73: m+=8;
74: }
75: }
76: #endif
77:
78: /* TCDispatchQueueIRP queues any IRP's so that they can be processed later
79: by the thread -- or in some cases handles them immediately! */
80: NTSTATUS
81: TCDispatchQueueIRP (PDEVICE_OBJECT DeviceObject, PIRP Irp)
82: {
83: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
84: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
85: NTSTATUS ntStatus;
86:
87: #ifdef USE_KERNEL_MUTEX
88: if (Extension->bRootDevice == FALSE)
89: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
90: FALSE, NULL);
91: #endif
92:
93: #ifdef _DEBUG
94: if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
95: Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x IoControlCode = %ls 0x%08x\n",
96: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction,
97: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode),
98: (int) irpSp->Parameters.DeviceIoControl.IoControlCode);
99: //else
100: // Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x\n",
101: // TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction);
102: #endif
103:
104: if (Extension->bRootDevice == FALSE)
105: {
106: if (irpSp->MajorFunction == IRP_MJ_READ || irpSp->MajorFunction == IRP_MJ_WRITE ||
107: irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
108: {
109: if ((DeviceObject->Flags & DO_VERIFY_VOLUME))
110: {
111: if (!(irpSp->Flags & SL_OVERRIDE_VERIFY_VOLUME))
112: {
113: Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
114: Irp->IoStatus.Information = 0;
115: if (!NT_SUCCESS (Irp->IoStatus.Status) &&
116: IoIsErrorUserInduced (Irp->IoStatus.Status))
117: {
118: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
119: }
120: ntStatus = Irp->IoStatus.Status;
121: IoCompleteRequest (Irp, IO_NO_INCREMENT);
122: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
123: #ifdef USE_KERNEL_MUTEX
124: if (Extension->bRootDevice == FALSE)
125: KeReleaseMutex (&Extension->KernelMutex, FALSE);
126: #endif
127: return ntStatus;
128: }
129: else if (Extension->bShuttingDown == TRUE)
130: {
131: Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
132: Irp->IoStatus.Information = 0;
133: if (!NT_SUCCESS (Irp->IoStatus.Status) &&
134: IoIsErrorUserInduced (Irp->IoStatus.Status))
135: {
136: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
137: }
138: ntStatus = Irp->IoStatus.Status;
139: IoCompleteRequest (Irp, IO_NO_INCREMENT);
140: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
141: #ifdef USE_KERNEL_MUTEX
142: if (Extension->bRootDevice == FALSE)
143: KeReleaseMutex (&Extension->KernelMutex, FALSE);
144: #endif
145: return ntStatus;
146: }
147: }
148: else if (Extension->bShuttingDown == TRUE)
149: {
150: if (DeviceObject->Vpb && DeviceObject->Vpb->Flags & VPB_MOUNTED)
151: {
152: Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
153: Irp->IoStatus.Information = 0;
154: if (!NT_SUCCESS (Irp->IoStatus.Status) &&
155: IoIsErrorUserInduced (Irp->IoStatus.Status))
156: {
157: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
158: }
159: DeviceObject->Flags |= DO_VERIFY_VOLUME;
160: }
161: else
162: {
163: Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
164: Irp->IoStatus.Information = 0;
165: }
166:
167: ntStatus = Irp->IoStatus.Status;
168: IoCompleteRequest (Irp, IO_NO_INCREMENT);
169: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
170: #ifdef USE_KERNEL_MUTEX
171: if (Extension->bRootDevice == FALSE)
172: KeReleaseMutex (&Extension->KernelMutex, FALSE);
173: #endif
174: return ntStatus;
175: }
176: }
177: else if ((DeviceObject->Flags & DO_VERIFY_VOLUME))
178: { /* If shutting down or media removed */
179: if (Extension->bShuttingDown == TRUE)
180: {
181: Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
182: Irp->IoStatus.Information = 0;
183: if (!NT_SUCCESS (Irp->IoStatus.Status) &&
184: IoIsErrorUserInduced (Irp->IoStatus.Status))
185: {
186: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
187: }
188: ntStatus = Irp->IoStatus.Status;
189: IoCompleteRequest (Irp, IO_NO_INCREMENT);
190: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
191: #ifdef USE_KERNEL_MUTEX
192: if (Extension->bRootDevice == FALSE)
193: KeReleaseMutex (&Extension->KernelMutex, FALSE);
194: #endif
195: return ntStatus;
196: }
197: else
198: {
199: Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
200: Irp->IoStatus.Information = 0;
201: ntStatus = Irp->IoStatus.Status;
202: IoCompleteRequest (Irp, IO_NO_INCREMENT);
203: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
204: #ifdef USE_KERNEL_MUTEX
205: if (Extension->bRootDevice == FALSE)
206: KeReleaseMutex (&Extension->KernelMutex, FALSE);
207: #endif
208: return ntStatus;
209: }
210: }
211: }
212:
213: switch (irpSp->MajorFunction)
214: {
215: case IRP_MJ_CLOSE:
216: case IRP_MJ_CREATE:
217: case IRP_MJ_CLEANUP:
218: #ifdef USE_KERNEL_MUTEX
219: if (Extension->bRootDevice == FALSE)
220: KeReleaseMutex (&Extension->KernelMutex, FALSE);
221: #endif
222: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
223:
224: case IRP_MJ_SHUTDOWN:
225: case IRP_MJ_FLUSH_BUFFERS:
226: case IRP_MJ_READ:
227: case IRP_MJ_WRITE:
228: case IRP_MJ_DEVICE_CONTROL:
229: if (Extension->bRootDevice == FALSE)
230: {
231: ASSERT (Extension->bShuttingDown == FALSE);
232:
233: IoMarkIrpPending (Irp);
234:
235: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL ||
236: KeGetCurrentIrql ()== APC_LEVEL);
237:
238: ExInterlockedInsertTailList (
239: &Extension->ListEntry,
240: &Irp->Tail.Overlay.ListEntry,
241: &Extension->ListSpinLock);
242:
243: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL ||
244: KeGetCurrentIrql ()== APC_LEVEL);
245:
246: KeReleaseSemaphore (
247: &Extension->RequestSemaphore,
248: (KPRIORITY) 0,
249: 1,
250: FALSE);
251:
252: //Dump ("TCDispatchQueueIRP STATUS_PENDING END\n");
253: #ifdef USE_KERNEL_MUTEX
254: if (Extension->bRootDevice == FALSE)
255: KeReleaseMutex (&Extension->KernelMutex, FALSE);
256: #endif
257: return STATUS_PENDING;
258: }
259: else
260: {
261: if (irpSp->Parameters.DeviceIoControl.IoControlCode >= TC_FIRST_PRIVATE &&
262: irpSp->Parameters.DeviceIoControl.IoControlCode <= TC_LAST_PRIVATE)
263: {
264: ntStatus = TCDeviceControl (DeviceObject, Extension, Irp);
265: //Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
266: #ifdef USE_KERNEL_MUTEX
267: if (Extension->bRootDevice == FALSE)
268: KeReleaseMutex (&Extension->KernelMutex, FALSE);
269: #endif
270: return ntStatus;
271: }
272:
273: if (irpSp->MajorFunction == IRP_MJ_FLUSH_BUFFERS || irpSp->MajorFunction == IRP_MJ_SHUTDOWN)
274: {
275: #ifdef USE_KERNEL_MUTEX
276: if (Extension->bRootDevice == FALSE)
277: KeReleaseMutex (&Extension->KernelMutex, FALSE);
278: #endif
279: return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
280: }
281: }
282:
283: #ifdef USE_KERNEL_MUTEX
284: if (Extension->bRootDevice == FALSE)
285: KeReleaseMutex (&Extension->KernelMutex, FALSE);
286: #endif
287:
288: return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0);
289: }
290:
291: #ifdef _DEBUG
292: Dump ("ERROR: Unknown irpSp->MajorFunction in TCDispatchQueueIRP %ls 0x%08x END\n",
293: TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction);
294: #endif
295:
296: #ifdef USE_KERNEL_MUTEX
297: if (Extension->bRootDevice == FALSE)
298: KeReleaseMutex (&Extension->KernelMutex, FALSE);
299: #endif
300: return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0);
301: }
302:
303: NTSTATUS
304: TCCreateRootDeviceObject (PDRIVER_OBJECT DriverObject)
305: {
306: UNICODE_STRING Win32NameString, ntUnicodeString;
307: WCHAR dosname[32], ntname[32];
308: PDEVICE_OBJECT DeviceObject;
309: NTSTATUS ntStatus;
310: BOOL *bRootExtension;
311:
312: Dump ("TCCreateRootDeviceObject BEGIN\n");
313:
314: wcscpy (dosname, (LPWSTR) DOS_ROOT_PREFIX);
315: wcscpy (ntname, (LPWSTR) NT_ROOT_PREFIX);
316: RtlInitUnicodeString (&ntUnicodeString, ntname);
317: RtlInitUnicodeString (&Win32NameString, dosname);
318:
319: Dump ("Creating root device nt=%ls dos=%ls\n", ntname, dosname);
320:
321: ntStatus = IoCreateDevice (
322: DriverObject, /* Our Driver Object */
323: sizeof (BOOL), /* Size of state information */
324: &ntUnicodeString, /* Device name "\Device\Name" */
325: FILE_DEVICE_DISK, /* Device type */
326: 0, /* Device characteristics */
327: FALSE, /* Exclusive device */
328: &DeviceObject); /* Returned ptr to Device Object */
329:
330: if (!NT_SUCCESS (ntStatus))
331: {
332: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
333: return ntStatus;/* Failed to create DeviceObject */
334: }
335:
336: DeviceObject->Flags |= DO_DIRECT_IO;
337: DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
338:
339: /* Setup the device extension */
340: bRootExtension = (BOOL *) DeviceObject->DeviceExtension;
341: *bRootExtension = TRUE;
342:
343: /* The symlinks for mount devices are created from user-mode */
344: ntStatus = IoCreateSymbolicLink (&Win32NameString, &ntUnicodeString);
345: if (!NT_SUCCESS (ntStatus))
346: {
347: Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
348: IoDeleteDevice (DeviceObject);
349: return ntStatus;
350: }
351:
352: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
353: Dump ("TCCreateRootDeviceObject STATUS_SUCCESS END\n");
354: return STATUS_SUCCESS;
355: }
356:
357: NTSTATUS
358: TCCreateDeviceObject (PDRIVER_OBJECT DriverObject,
359: PDEVICE_OBJECT * ppDeviceObject,
360: int nDosDriveNo)
361: {
362: UNICODE_STRING Win32NameString, ntUnicodeString;
363: WCHAR dosname[32], ntname[32];
364: PEXTENSION Extension;
365: NTSTATUS ntStatus;
366:
367: Dump ("TCCreateDeviceObject BEGIN\n");
368:
369: TCGetDosNameFromNumber (dosname, nDosDriveNo);
370: TCGetNTNameFromNumber (ntname, nDosDriveNo);
371: RtlInitUnicodeString (&ntUnicodeString, ntname);
372: RtlInitUnicodeString (&Win32NameString, dosname);
373:
374: Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname);
375:
376: ntStatus = IoCreateDevice (
377: DriverObject, /* Our Driver Object */
378: sizeof (EXTENSION), /* Size of state information */
379: &ntUnicodeString, /* Device name "\Device\Name" */
380: FILE_DEVICE_DISK, /* Device type */
381: 0, /* Device characteristics */
382: FALSE, /* Exclusive device */
383: ppDeviceObject); /* Returned ptr to Device Object */
384:
385: if (!NT_SUCCESS (ntStatus))
386: {
387: Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
388: return ntStatus;/* Failed to create DeviceObject */
389: }
390: /* Initialize device object and extension. */
391:
392: (*ppDeviceObject)->Flags |= DO_DIRECT_IO;
393: (*ppDeviceObject)->AlignmentRequirement = FILE_WORD_ALIGNMENT;
394:
395: /* Setup the device extension */
396: Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension;
397: memset (Extension, 0, sizeof (EXTENSION));
398:
399: Extension->lMagicNumber = 0xabfeacde;
400: Extension->nDosDriveNo = nDosDriveNo;
401:
402: KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE);
403: KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG);
404: #ifdef USE_KERNEL_MUTEX
405: KeInitializeMutex (&Extension->KernelMutex, 1);
406: #endif
407: KeInitializeSpinLock (&Extension->ListSpinLock);
408: InitializeListHead (&Extension->ListEntry);
409:
410: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
411: Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n");
412:
413: return STATUS_SUCCESS;
414: }
415:
416: /* TCDeviceControl handles certain requests from NT, these are needed for NT
417: to recognize the drive, also this function handles our device specific
418: function codes, such as mount/unmount */
419: NTSTATUS
420: TCDeviceControl (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
421: {
422: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
423: NTSTATUS ntStatus;
424:
425: #ifdef _DEBUG
426: Dump ("TCDeviceControl BEGIN IoControlCode = %ls 0x%08x\n",
427: TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode),
428: irpSp->Parameters.DeviceIoControl.IoControlCode);
429: #endif
430:
431: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; /* Assume failure. */
432:
433: /* Determine which I/O control code was specified. */
434: switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
435: {
436:
437: case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
438: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_NAME))
439: {
440: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
441: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
442: }
443: else
444: {
445: ULONG outLength;
446: UNICODE_STRING ntUnicodeString;
447: WCHAR ntName[64];
448: PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer;
449:
450: Dump("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:");
451:
452: TCGetNTNameFromNumber (ntName, Extension->nDosDriveNo);
453: RtlInitUnicodeString (&ntUnicodeString, ntName);
454:
455: outputBuffer->NameLength = ntUnicodeString.Length;
456: outLength = ntUnicodeString.Length + sizeof(USHORT);
457:
458: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
459: {
460: Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
461: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
462:
463: break;
464: }
465:
466: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
467:
468: Irp->IoStatus.Status = STATUS_SUCCESS;
469: Irp->IoStatus.Information = outLength;
470:
471: Dump ("name = %ls\n",ntName);
472: }
473: break;
474:
475: case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
476: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_UNIQUE_ID))
477: {
478: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
479: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
480: }
481: else
482: {
483: ULONG outLength;
484: UCHAR volId[128], tmp[] = { 0,0 };
485: PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer;
486:
487: Dump("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:");
488:
489: strcpy (volId, TC_UNIQUE_ID_PREFIX);
490: tmp[0] = 'A' + Extension->nDosDriveNo;
491: strcat (volId, tmp);
492:
493: outputBuffer->UniqueIdLength = (USHORT) strlen(volId);
494: outLength = strlen(volId) + sizeof(USHORT);
495:
496: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
497: {
498: Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
499: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
500: break;
501: }
502:
503: RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen(volId));
504:
505: Irp->IoStatus.Status = STATUS_SUCCESS;
506: Irp->IoStatus.Information = outLength;
507:
508: Dump ("id = %s\n",volId);
509: }
510: break;
511:
512: case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
513: {
514: ULONG outLength;
515: UNICODE_STRING ntUnicodeString;
516: WCHAR ntName[64];
517: PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer;
518:
519: Dump("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:");
520:
521: TCGetDosNameFromNumber (ntName, Extension->nDosDriveNo);
522: RtlInitUnicodeString (&ntUnicodeString, ntName);
523:
524: outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length;
525:
526: outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE;
527: outputBuffer->NameLength = ntUnicodeString.Length;
528:
529: if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
530: {
531: Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME);
532: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
533: break;
534: }
535:
536: RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
537:
538: Irp->IoStatus.Status = STATUS_SUCCESS;
539: Irp->IoStatus.Information = outLength;
540:
541: Dump ("link = %ls\n",ntName);
542: }
543: break;
544:
545: case IOCTL_DISK_GET_MEDIA_TYPES:
546: case IOCTL_DISK_GET_DRIVE_GEOMETRY:
547: /* Return the drive geometry for the disk. Note that we
548: return values which were made up to suit the disk size. */
549: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
550: sizeof (DISK_GEOMETRY))
551: {
552: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
553: Irp->IoStatus.Information = 0;
554: }
555: else
556: {
557: PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY)
558: Irp->AssociatedIrp.SystemBuffer;
559:
560: outputBuffer->MediaType = FixedMedia;
561: outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders;
562: outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder;
563: outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack;
564: outputBuffer->BytesPerSector = Extension->BytesPerSector;
565: Irp->IoStatus.Status = STATUS_SUCCESS;
566: Irp->IoStatus.Information = sizeof (DISK_GEOMETRY);
567: }
568: break;
569:
570: case IOCTL_DISK_GET_PARTITION_INFO:
571: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
572: sizeof (PARTITION_INFORMATION))
573: {
574: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
575: Irp->IoStatus.Information = 0;
576: }
577: else
578: {
579: PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION)
580: Irp->AssociatedIrp.SystemBuffer;
581:
582: outputBuffer->PartitionType = Extension->PartitionType;
583: outputBuffer->BootIndicator = FALSE;
584: outputBuffer->RecognizedPartition = TRUE;
585: outputBuffer->RewritePartition = FALSE;
586: outputBuffer->StartingOffset = RtlConvertUlongToLargeInteger (0);
587: outputBuffer->PartitionLength.QuadPart= Extension->DiskLength;
588: outputBuffer->HiddenSectors = 1L;
589: Irp->IoStatus.Status = STATUS_SUCCESS;
590: Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION);
591: }
592: break;
593:
594: case IOCTL_DISK_GET_LENGTH_INFO:
595: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GET_LENGTH_INFORMATION))
596: {
597: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
598: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
599: }
600: else
601: {
602: PGET_LENGTH_INFORMATION outputBuffer = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
603:
604: outputBuffer->Length.QuadPart = Extension->DiskLength;
605: Irp->IoStatus.Status = STATUS_SUCCESS;
606: Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
607: }
608: break;
609:
610: case IOCTL_DISK_VERIFY:
611: {
612: PVERIFY_INFORMATION pVerifyInformation;
613: pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
614: irpSp->Parameters.Read.ByteOffset.LowPart =
615: pVerifyInformation->StartingOffset.LowPart;
616: irpSp->Parameters.Read.ByteOffset.HighPart =
617: pVerifyInformation->StartingOffset.HighPart;
618: irpSp->Parameters.Read.Length = pVerifyInformation->Length;
619: Irp->IoStatus.Status = STATUS_SUCCESS;
620: Irp->IoStatus.Information = pVerifyInformation->Length;
621: }
622: break;
623:
624: case IOCTL_DISK_CHECK_VERIFY:
625: {
626: Irp->IoStatus.Status = STATUS_SUCCESS;
627: Irp->IoStatus.Information = 0;
628: }
629: break;
630:
631: case IOCTL_DISK_IS_WRITABLE:
632: {
633: if (Extension->bReadOnly == TRUE)
634: Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
635: else
636: Irp->IoStatus.Status = STATUS_SUCCESS;
637: Irp->IoStatus.Information = 0;
638:
639: }
640: break;
641:
642: case DRIVER_VERSION:
643: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 4)
644: {
645: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
646: Irp->IoStatus.Information = 0;
647: }
648: else
649: {
650: LONG tmp = VERSION_NUM;
651: memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4);
652: Irp->IoStatus.Information = 4;
653: Irp->IoStatus.Status = STATUS_SUCCESS;
654: }
655: break;
656:
657: case OPEN_TEST:
658: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (OPEN_TEST_STRUCT))
659: {
660: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
661: Irp->IoStatus.Information = 0;
662: }
663: else
664: {
665: OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
666: OBJECT_ATTRIBUTES ObjectAttributes;
667: HANDLE NtFileHandle;
668: UNICODE_STRING FullFileName;
669: IO_STATUS_BLOCK IoStatus;
670:
671: RtlInitUnicodeString (&FullFileName, opentest->wszFileName);
672:
673: InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE,
674: NULL, NULL);
675:
676: ntStatus = ZwCreateFile (&NtFileHandle,
677: SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none */ ,
678: FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT |
679: FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS,
680: NULL /* eabuffer */ , 0 /* ealength */ );
681:
682: if (NT_SUCCESS (ntStatus))
683: {
684: ZwClose (NtFileHandle);
685: Dump ("Open test on file %ls success.\n", opentest->wszFileName);
686: }
687: else
688: {
689: Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus);
690: }
691:
692: Irp->IoStatus.Information = 0;
693: Irp->IoStatus.Status = ntStatus;
694: }
695: break;
696:
697: case WIPE_CACHE:
698: KeWaitForMutexObject (&driverMutex, Executive, KernelMode,
699: FALSE, NULL);
700:
701: WipeCache ();
702:
703: KeReleaseMutex (&driverMutex, FALSE);
704:
705: Irp->IoStatus.Status = STATUS_SUCCESS;
706: Irp->IoStatus.Information = 0;
707: break;
708:
709: case CACHE_STATUS:
710: Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS;
711: Irp->IoStatus.Information = 0;
712: break;
713:
714: #ifdef DEBUG
715: case HALT_SYSTEM:
716: KeBugCheck ((ULONG) 0x5050);
717: break;
718: #endif
719:
720: case MOUNT_LIST:
721: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT))
722: {
723: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
724: Irp->IoStatus.Information = 0;
725: }
726: else
727: {
728: MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
729: PDEVICE_OBJECT ListDevice;
730:
731: list->ulMountedDrives = 0;
732: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
733: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
734: {
735:
736: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
737: if (ListExtension->bRootDevice == FALSE)
738: {
739: list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo);
740: wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume);
741: list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength;
742: list->cipher[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->cipher;
743: }
744: }
745:
746: Irp->IoStatus.Status = STATUS_SUCCESS;
747: Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT);
748: }
749: break;
750:
751: case VOLUME_PROPERTIES:
752: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT))
753: {
754: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
755: Irp->IoStatus.Information = 0;
756: }
757: else
758: {
759: VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
760: PDEVICE_OBJECT ListDevice;
761:
762: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
763: Irp->IoStatus.Information = 0;
764:
765: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
766: ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
767: {
768:
769: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
770: if (ListExtension->bRootDevice == FALSE && ListExtension->nDosDriveNo == prop->driveNo)
771: {
772: wcscpy (prop->wszVolume, ListExtension->wszVolume);
773: prop->diskLength = ListExtension->DiskLength;
774: prop->cipher = ListExtension->cryptoInfo->cipher;
775: prop->pkcs5 = ListExtension->cryptoInfo->pkcs5;
776: prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations;
777: prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time;
778: prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time;
779:
780: Irp->IoStatus.Status = STATUS_SUCCESS;
781: Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT);
782: break;
783: }
784: }
785: }
786: break;
787:
788: case UNMOUNT_PENDING:
789: Extension->bShuttingDown = TRUE;
790: Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
791: Irp->IoStatus.Information = 0;
792: if (DeviceObject->Vpb && DeviceObject->Vpb->Flags & VPB_MOUNTED)
793: {
794: IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
795: DeviceObject->Flags |= DO_VERIFY_VOLUME;
796: }
797: break;
798:
799: case UNMOUNT:
800: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
801: {
802: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
803: Irp->IoStatus.Information = 0;
804: }
805: else
806: {
807: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
808: PDEVICE_OBJECT ListDevice;
809:
810: unmount->nReturnCode = ERR_DRIVE_NOT_FOUND;
811:
812: for (ListDevice = DeviceObject->DriverObject->DeviceObject;
813: ListDevice != (PDEVICE_OBJECT) NULL;
814: ListDevice = ListDevice->NextDevice)
815: {
816:
817: PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
818:
819: if (ListExtension->bRootDevice == FALSE)
820: {
821: if (unmount->nDosDriveNo == ListExtension->nDosDriveNo)
822: {
823: if (ListDevice->Vpb && ListDevice->Vpb->ReferenceCount == 0 && (ListDevice->Vpb->Flags & VPB_MOUNTED) == 0)
824: {
825: Dump ("Deleting DeviceObject with ref count %ld\n", ListDevice->ReferenceCount);
826: ListDevice->ReferenceCount = 0;
827: TCDeleteDeviceObject (ListDevice, (PEXTENSION) ListDevice->DeviceExtension);
828: unmount->nReturnCode = 0;
829: break;
830: }
831: else
832: {
833: unmount->nReturnCode = ERR_FILES_OPEN;
834: break;
835: }
836: } /* if the drive numbers are
837: equal */
838: } /* if it's not the root device */
839: } /* for all the device objects the driver
840: knows about */
841:
842: Irp->IoStatus.Information = sizeof (unmount->nReturnCode);
843: Irp->IoStatus.Status = STATUS_SUCCESS;
844: }
845: break;
846:
847:
848: case MOUNT:
849: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT))
850: {
851: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
852: Irp->IoStatus.Information = 0;
853: }
854: else
855: {
856: MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
857: ULONG *outputBuffer = (ULONG *) Irp->AssociatedIrp.SystemBuffer;
858: PDEVICE_OBJECT NewDeviceObject;
859:
860: /* Make sure the user is asking for a resonable
861: nDosDriveNo */
862: if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25)
863: {
864: Dump ("Mount request looks valid\n");
865: }
866: else
867: {
868: Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n");
869: Irp->IoStatus.Information = sizeof (mount->nReturnCode);
870: Irp->IoStatus.Status = STATUS_SUCCESS;
871: mount->nReturnCode = ERR_BAD_DRIVE_LETTER;
872: break;
873: }
874:
875: ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
876: mount->nDosDriveNo);
877: if (!NT_SUCCESS (ntStatus))
878: {
879: Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
880: Irp->IoStatus.Information = 0;
881: Irp->IoStatus.Status = ntStatus;
882: break;
883: }
884: else
885: {
886: PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension;
887: ntStatus = TCStartThread (NewDeviceObject, NewExtension, mount);
888: if (!NT_SUCCESS (ntStatus))
889: {
890: Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus);
891: Irp->IoStatus.Information = 0;
892: Irp->IoStatus.Status = ntStatus;
893: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
894: break;
895: }
896: else
897: {
898: if (mount->nReturnCode == 0)
899: {
900: Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode,
901: NewExtension->bReadOnly);
902: if (NewExtension->bReadOnly == TRUE)
903: NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
904: NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
905: }
906: else
907: {
908: Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode);
909: TCDeleteDeviceObject (NewDeviceObject, NewExtension);
910: }
911: Irp->IoStatus.Information = sizeof (mount->nReturnCode);
912: Irp->IoStatus.Status = STATUS_SUCCESS;
913: break;
914: }
915: }
916: }
917: break;
918: }
919:
920: /* Finish the I/O operation by simply completing the packet and
921: returning the same NTSTATUS as in the packet itself. */
922: ntStatus = COMPLETE_IRP (DeviceObject, Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
923: Dump ("TCDeviceControl NTSTATUS = 0x%08x END\n", ntStatus);
924: return ntStatus;
925: }
926:
927: NTSTATUS
928: TCStartThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount)
929: {
930: PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK));
931: HANDLE hThread;
932: NTSTATUS ntStatus;
933:
934: Dump ("Starting thread...\n");
935:
936: if (pThreadBlock == NULL)
937: {
938: return STATUS_INSUFFICIENT_RESOURCES;
939: }
940: else
941: {
942: pThreadBlock->DeviceObject = DeviceObject;
943: pThreadBlock->mount = mount;
944: }
945:
946: Extension->bThreadShouldQuit = FALSE;
947:
948: ntStatus = PsCreateSystemThread (&hThread,
949: THREAD_ALL_ACCESS,
950: NULL,
951: NULL,
952: NULL,
953: TCThreadIRP,
954: pThreadBlock);
955:
956: if (!NT_SUCCESS (ntStatus))
957: {
958: Dump ("PsCreateSystemThread Failed END\n");
959: TCfree (pThreadBlock);
960: return ntStatus;
961: }
962:
963: ObReferenceObjectByHandle (hThread,
964: THREAD_ALL_ACCESS,
965: NULL,
966: KernelMode,
967: &Extension->peThread,
968: NULL);
969: ZwClose (hThread);
970:
971: Dump ("Waiting for thread to initialize...\n");
972:
973: KeWaitForSingleObject (&Extension->keCreateEvent,
974: UserRequest,
975: UserMode,
976: FALSE,
977: NULL);
978:
979: Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus);
980: ntStatus = pThreadBlock->ntCreateStatus;
981: TCfree (pThreadBlock);
982: return ntStatus;
983: }
984:
985: void
986: TCStopThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
987: {
988: NTSTATUS ntStatus;
989:
990: if (DeviceObject); /* Remove compiler warning */
991:
992: Dump ("Signalling thread to quit...\n");
993:
994: Extension->bThreadShouldQuit = TRUE;
995:
996: KeReleaseSemaphore (&Extension->RequestSemaphore,
997: 0,
998: 1,
999: TRUE);
1000:
1001: ntStatus = KeWaitForSingleObject (&Extension->peThread,
1002: UserRequest,
1003: UserMode,
1004: FALSE,
1005: NULL);
1006: if (ntStatus != STATUS_SUCCESS)
1007: Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n",
1008: ntStatus);
1009:
1010: ObDereferenceObject (&Extension->peThread);
1011: Extension->peThread = NULL;
1012:
1013: Dump ("Thread exited!\n");
1014: }
1015:
1016: /* TCThreadIRP does all the work of processing IRP's, and dispatching them
1017: to either the ReadWrite function or the DeviceControl function */
1018: VOID
1019: TCThreadIRP (PVOID Context)
1020: {
1021: PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context;
1022: PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject;
1023: PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
1024: PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
1025: LARGE_INTEGER queueWait;
1026: BOOL bDevice;
1027:
1028: /* Set thread priority to lowest realtime level. */
1029:
1030: KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY);
1031:
1032: queueWait.QuadPart = -WAIT_SECONDS (1);
1033:
1034: Dump ("Mount THREAD OPENING VOLUME BEGIN\n");
1035:
1036: #ifdef USE_KERNEL_MUTEX
1037: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
1038: FALSE, NULL);
1039: #endif
1040:
1041: if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0)
1042: {
1043: wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\"));
1044: wcscat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume);
1045: bDevice = FALSE;
1046: }
1047: else
1048: {
1049: wcscpy (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume);
1050: bDevice = TRUE;
1051: }
1052:
1053: Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n",
1054: pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice);
1055:
1056: pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject,
1057: Extension,
1058: pThreadBlock->mount,
1059: pThreadBlock->wszMountVolume,
1060: bDevice);
1061:
1062: #ifdef USE_KERNEL_MUTEX
1063: KeReleaseMutex (&Extension->KernelMutex, FALSE);
1064: #endif
1065:
1066: if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0)
1067: {
1068: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1069: PsTerminateSystemThread (STATUS_SUCCESS);
1070: }
1071: else
1072: {
1073: KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1074: /* From this point on pThreadBlock cannot be used as it will
1075: have been released! */
1076: pThreadBlock = NULL;
1077: }
1078:
1079:
1080: for (;;)
1081: {
1082: NTSTATUS ntStatus;
1083:
1084: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1085:
1086: /* Wait for a request from the dispatch routines. */
1087: ntStatus = KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore,
1088: Executive, KernelMode, FALSE, &queueWait);
1089:
1090: if (ntStatus != STATUS_TIMEOUT)
1091: {
1092:
1093: #ifdef USE_KERNEL_MUTEX
1094: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
1095: FALSE, NULL);
1096: #endif
1097:
1098: // Dump ("DRIVER THREAD PROCESSING DEVICEOBJECT 0x%08x \n", DeviceObject);
1099:
1100: for (;;)
1101: {
1102: PIO_STACK_LOCATION irpSp;
1103: PLIST_ENTRY request;
1104: PIRP Irp;
1105:
1106: request = ExInterlockedRemoveHeadList (&Extension->ListEntry,
1107: &Extension->ListSpinLock);
1108: if (request == NULL)
1109: break;
1110:
1111: ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
1112:
1113: Irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry);
1114: irpSp = IoGetCurrentIrpStackLocation (Irp);
1115:
1116: switch (irpSp->MajorFunction)
1117: {
1118: case IRP_MJ_READ:
1119: case IRP_MJ_WRITE:
1120: TCReadWrite (DeviceObject, Extension, Irp);
1121: break;
1122:
1123: case IRP_MJ_FLUSH_BUFFERS:
1124: if (Extension->bRawDevice == FALSE)
1125: TCSendIRP_FileDevice (DeviceObject, Extension, NULL, Irp->Flags, IRP_MJ_FLUSH_BUFFERS, Irp);
1126: else
1127: {
1128: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
1129: }
1130: break;
1131:
1132: case IRP_MJ_SHUTDOWN:
1133: COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
1134: break;
1135:
1136: case IRP_MJ_DEVICE_CONTROL:
1137: if (irpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_DISK_CHECK_VERIFY)
1138: TCDeviceControl (DeviceObject, Extension, Irp);
1139: else
1140: {
1141: if (Extension->bRawDevice == TRUE)
1142: TCSendIRP_RawDevice (DeviceObject, Extension, NULL, 0, IRP_MJ_DEVICE_CONTROL, Irp);
1143: else
1144: TCDeviceControl (DeviceObject, Extension, Irp);
1145: }
1146: break;
1147: } /* end of switch on
1148: irpSp->MajorFunction */
1149: } /* for any remaining IRP's for this device */
1150:
1151: #ifdef USE_KERNEL_MUTEX
1152: KeReleaseMutex (&Extension->KernelMutex, FALSE);
1153: #endif
1154:
1155: if (Extension->bThreadShouldQuit)
1156: {
1157: // Dump ("END PROCESSING DEVICEOBJECT THREAD ENDING 0x%08x Number = %d\n",
1158: // DeviceObject, Extension->nDosDriveNo);
1159: Dump ("Closing volume along with Thread!\n");
1160: TCCloseVolume (DeviceObject, Extension);
1161: PsTerminateSystemThread (STATUS_SUCCESS);
1162: }
1163: //else
1164: //{
1165: // Dump ("END PROCESSING DEVICEOBJECT 0x%08x Number = %d\n",
1166: // DeviceObject, Extension->nDosDriveNo);
1167: //}
1168: }
1169:
1170: } /* outermost for */
1171: }
1172:
1173: void
1174: TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)
1175: {
1176: WCHAR tmp[3] =
1177: {0, ':', 0};
1178: int j = nDriveNo + (WCHAR) 'A';
1179:
1180: tmp[0] = (short) j;
1181: wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
1182: wcsncat (ntname, tmp, 1);
1183: }
1184:
1185: void
1186: TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo)
1187: {
1188: WCHAR tmp[3] =
1189: {0, ':', 0};
1190: int j = nDriveNo + (WCHAR) 'A';
1191:
1192: tmp[0] = (short) j;
1193: wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX);
1194: wcscat (dosname, tmp);
1195: }
1196:
1197: #ifdef _DEBUG
1198: LPWSTR
1199: TCTranslateCode (ULONG ulCode)
1200: {
1201: if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY)
1202: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY");
1203: else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)
1204: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX");
1205: else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME)
1206: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME");
1207: else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME)
1208: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME");
1209: else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID)
1210: return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID");
1211: else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY)
1212: return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY");
1213: else if (ulCode == IOCTL_VOLUME_ONLINE)
1214: return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE");
1215: else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED)
1216: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED");
1217: else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED)
1218: return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED");
1219: else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS)
1220: return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS");
1221: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED)
1222: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED");
1223: else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED)
1224: return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED");
1225: else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO)
1226: return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO");
1227: else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER)
1228: return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER");
1229: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO)
1230: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO");
1231: else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX)
1232: return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX");
1233: else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO)
1234: return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO");
1235: else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT)
1236: return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT");
1237: else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX)
1238: return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX");
1239: else if (ulCode == IOCTL_DISK_VERIFY)
1240: return (LPWSTR) _T ("IOCTL_DISK_VERIFY");
1241: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS)
1242: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS");
1243: else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS)
1244: return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS");
1245: else if (ulCode == IOCTL_DISK_PERFORMANCE)
1246: return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE");
1247: else if (ulCode == IOCTL_DISK_IS_WRITABLE)
1248: return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE");
1249: else if (ulCode == IOCTL_DISK_LOGGING)
1250: return (LPWSTR) _T ("IOCTL_DISK_LOGGING");
1251: else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX)
1252: return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX");
1253: else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE)
1254: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE");
1255: else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA)
1256: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA");
1257: else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET)
1258: return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET");
1259: else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE)
1260: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE");
1261: else if (ulCode == IOCTL_DISK_REQUEST_DATA)
1262: return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA");
1263: else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER)
1264: return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER");
1265: else if (ulCode == SMART_GET_VERSION)
1266: return (LPWSTR) _T ("SMART_GET_VERSION");
1267: else if (ulCode == SMART_SEND_DRIVE_COMMAND)
1268: return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND");
1269: else if (ulCode == SMART_RCV_DRIVE_DATA)
1270: return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA");
1271: else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY)
1272: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY");
1273: else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY)
1274: return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY");
1275: else if (ulCode == IOCTL_DISK_CHECK_VERIFY)
1276: return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY");
1277: else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL)
1278: return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL");
1279: else if (ulCode == IOCTL_DISK_EJECT_MEDIA)
1280: return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA");
1281: else if (ulCode == IOCTL_DISK_LOAD_MEDIA)
1282: return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA");
1283: else if (ulCode == IOCTL_DISK_RESERVE)
1284: return (LPWSTR) _T ("IOCTL_DISK_RESERVE");
1285: else if (ulCode == IOCTL_DISK_RELEASE)
1286: return (LPWSTR) _T ("IOCTL_DISK_RELEASE");
1287: else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES)
1288: return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES");
1289: else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES)
1290: return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES");
1291: else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO)
1292: return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO");
1293: else if (ulCode == IRP_MJ_READ)
1294: return (LPWSTR) _T ("IRP_MJ_READ");
1295: else if (ulCode == IRP_MJ_WRITE)
1296: return (LPWSTR) _T ("IRP_MJ_WRITE");
1297: else if (ulCode == IRP_MJ_CREATE)
1298: return (LPWSTR) _T ("IRP_MJ_CREATE");
1299: else if (ulCode == IRP_MJ_CLOSE)
1300: return (LPWSTR) _T ("IRP_MJ_CLOSE");
1301: else if (ulCode == IRP_MJ_CLEANUP)
1302: return (LPWSTR) _T ("IRP_MJ_CLEANUP");
1303: else if (ulCode == IRP_MJ_FLUSH_BUFFERS)
1304: return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS");
1305: else if (ulCode == IRP_MJ_SHUTDOWN)
1306: return (LPWSTR) _T ("IRP_MJ_SHUTDOWN");
1307: else if (ulCode == IRP_MJ_DEVICE_CONTROL)
1308: return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL");
1309: else if (ulCode == MOUNT)
1310: return (LPWSTR) _T ("MOUNT");
1311: else if (ulCode == UNMOUNT)
1312: return (LPWSTR) _T ("UNMOUNT");
1313: else if (ulCode == MOUNT_LIST)
1314: return (LPWSTR) _T ("MOUNT_LIST");
1315: else if (ulCode == OPEN_TEST)
1316: return (LPWSTR) _T ("OPEN_TEST");
1317: else if (ulCode == UNMOUNT_PENDING)
1318: return (LPWSTR) _T ("UNMOUNT_PENDING");
1319: else
1320: {
1321: Dump("Unknown IOCTL recieved: DeviceType = 0x%x Function = 0x%x", (int)(ulCode>>16), (int)((ulCode&0x1FFF)>>2));
1322: return (LPWSTR) _T ("UNKNOWN");
1323: }
1324: }
1325:
1326: #endif
1327:
1328: PDEVICE_OBJECT
1329: TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1330: {
1331: PDEVICE_OBJECT OldDeviceObject = DeviceObject;
1332: UNICODE_STRING Win32NameString;
1333: WCHAR dosname[32];
1334: NTSTATUS ntStatus;
1335:
1336: Dump ("TCDeleteDeviceObject BEGIN\n");
1337:
1338: if (Extension->bRootDevice == TRUE)
1339: {
1340: RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX);
1341: }
1342: else
1343: {
1344: if (Extension->peThread != NULL)
1345: TCStopThread (DeviceObject, Extension);
1346: TCGetDosNameFromNumber (dosname, Extension->nDosDriveNo);
1347: RtlInitUnicodeString (&Win32NameString, dosname);
1348: }
1349:
1350: ntStatus = IoDeleteSymbolicLink (&Win32NameString);
1351: if (!NT_SUCCESS (ntStatus))
1352: {
1353: Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus);
1354: }
1355:
1356: DeviceObject = DeviceObject->NextDevice;
1357: IoDeleteDevice (OldDeviceObject);
1358:
1359: Dump ("TCDeleteDeviceObject END\n");
1360: return DeviceObject;
1361: }
1362:
1363: VOID
1364: TCUnloadDriver (PDRIVER_OBJECT DriverObject)
1365: {
1366: PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
1367:
1368: Dump ("TCUnloadDriver BEGIN\n");
1369:
1370: /* Now walk the list of driver objects and get rid of them */
1371: while (DeviceObject != (PDEVICE_OBJECT) NULL)
1372: {
1373: DeviceObject = TCDeleteDeviceObject (DeviceObject,
1374: (PEXTENSION) DeviceObject->DeviceExtension);
1375: }
1376:
1377: Dump ("TCUnloadDriver END\n");
1378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.