|
|
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: #include "volumes.h"
8:
9: #include "apidrvr.h"
10: #include "ntdriver.h"
11: #include "ntvol.h"
12: #include "ntrawdv.h"
13: #include "ntfiledv.h"
14:
15: #include "cache.h"
16:
17: //#ifdef _DEBUG
18: //#define EXTRA_INFO 1
19: //#endif
20:
21: #pragma warning( disable : 4127 )
22:
23: #define FIRST_READ_SIZE SECTOR_SIZE*2
24:
25: NTSTATUS
26: TCOpenVolume (PDEVICE_OBJECT DeviceObject,
27: PEXTENSION Extension,
28: MOUNT_STRUCT * mount,
29: PWSTR pwszMountVolume,
30: BOOL bRawDevice)
31: {
32: struct msdos_boot_sector *boot_sector = NULL;
33: FILE_STANDARD_INFORMATION FileStandardInfo;
34: FILE_BASIC_INFORMATION FileBasicInfo;
35: OBJECT_ATTRIBUTES oaFileAttributes;
36: UNICODE_STRING FullFileName;
37: IO_STATUS_BLOCK IoStatusBlock;
38: LARGE_INTEGER lDiskLength;
39: char *readBuffer;
40: NTSTATUS ntStatus;
41:
42: Extension->pfoDeviceFile = NULL;
43: Extension->hDeviceFile = NULL;
44:
45: readBuffer = TCalloc (FIRST_READ_SIZE);
46: if (readBuffer == NULL)
47: {
48: ntStatus = STATUS_INSUFFICIENT_RESOURCES;
49: goto error;
50: }
51:
52: RtlInitUnicodeString (&FullFileName, pwszMountVolume);
53:
54: InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE,
55: NULL, NULL);
56:
57: ntStatus = ZwCreateFile (&Extension->hDeviceFile,
58: GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
59: &oaFileAttributes,
60: &IoStatusBlock,
61: NULL,
62: FILE_ATTRIBUTE_NORMAL |
63: FILE_ATTRIBUTE_SYSTEM,
64: 0,
65: FILE_OPEN,
66: FILE_WRITE_THROUGH |
67: FILE_NO_INTERMEDIATE_BUFFERING |
68: FILE_SYNCHRONOUS_IO_NONALERT,
69: NULL,
70: 0);
71:
72: /* 26-4-99 NT for some partitions returns this code, it is really a
73: access denied */
74: if (ntStatus == 0xc000001b)
75: {
76: ntStatus = STATUS_ACCESS_DENIED;
77: }
78:
79: if (ntStatus == STATUS_ACCESS_DENIED)
80: {
81: ntStatus = ZwCreateFile (&Extension->hDeviceFile,
82: GENERIC_READ | SYNCHRONIZE,
83: &oaFileAttributes,
84: &IoStatusBlock,
85: NULL,
86: FILE_ATTRIBUTE_NORMAL |
87: FILE_ATTRIBUTE_SYSTEM,
88: 0,
89: FILE_OPEN,
90: FILE_WRITE_THROUGH |
91: FILE_NO_INTERMEDIATE_BUFFERING |
92: FILE_SYNCHRONOUS_IO_NONALERT,
93: NULL,
94: 0);
95: Extension->bReadOnly = TRUE;
96: }
97: else
98: Extension->bReadOnly = FALSE;
99:
100: /* 26-4-99 NT for some partitions returns this code, it is really a
101: access denied */
102: if (ntStatus == 0xc000001b)
103: {
104: /* Partitions which return this code can still be opened with
105: FILE_SHARE_READ but this causes NT problems elsewhere in
106: particular if you do FILE_SHARE_READ NT will die later if
107: anyone even tries to open the partition (or file for that
108: matter...) */
109: ntStatus = STATUS_SHARING_VIOLATION;
110: }
111:
112: if (!NT_SUCCESS (ntStatus))
113: {
114: goto error;
115: }
116:
117: ntStatus = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL,
118: &IoStatusBlock, readBuffer, FIRST_READ_SIZE, NULL, NULL);
119:
120: if (!NT_SUCCESS (ntStatus))
121: {
122: Dump ("Read failed: NTSTATUS 0x%08x\n", ntStatus);
123: }
124: else if (IoStatusBlock.Information != FIRST_READ_SIZE)
125: {
126: Dump ("Read didn't read enough data in: %lu / %lu\n", IoStatusBlock.Information, FIRST_READ_SIZE);
127: ntStatus = STATUS_UNSUCCESSFUL;
128: }
129:
130: if (!NT_SUCCESS (ntStatus))
131: {
132: goto error;
133: }
134:
135:
136: KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE);
137:
138: if (bRawDevice == FALSE)
139: {
140: ntStatus = ZwQueryInformationFile (Extension->hDeviceFile,
141: &IoStatusBlock,
142: &FileBasicInfo,
143: sizeof (FileBasicInfo),
144: FileBasicInformation);
145:
146: if (NT_SUCCESS (ntStatus))
147: ntStatus = ZwQueryInformationFile (Extension->hDeviceFile,
148: &IoStatusBlock,
149: &FileStandardInfo,
150: sizeof (FileStandardInfo),
151: FileStandardInformation);
152:
153: if (!NT_SUCCESS (ntStatus))
154: {
155: Dump ("ZwQueryInformationFile failed while opening file: NTSTATUS 0x%08x\n",
156: ntStatus);
157: goto error;
158: }
159: else
160: lDiskLength.QuadPart = FileStandardInfo.EndOfFile.QuadPart;
161:
162: if (FileBasicInfo.FileAttributes & FILE_ATTRIBUTE_COMPRESSED)
163: {
164: Dump ("File \"%ls\" is marked as compressed - not supported!\n", pwszMountVolume);
165: mount->nReturnCode = ERR_COMPRESSION_NOT_SUPPORTED;
166: ntStatus = STATUS_SUCCESS;
167: goto error;
168: }
169:
170: ntStatus = ObReferenceObjectByHandle (Extension->hDeviceFile,
171: FILE_ALL_ACCESS,
172: *IoFileObjectType,
173: KernelMode,
174: &Extension->pfoDeviceFile,
175: 0);
176:
177: if (!NT_SUCCESS (ntStatus))
178: {
179: goto error;
180: }
181:
182: /* Get the FSD device for the file (probably either NTFS or
183: FAT) */
184: Extension->pFsdDevice = IoGetRelatedDeviceObject (Extension->pfoDeviceFile);
185:
186: DeviceObject->StackSize = (CCHAR) (Extension->pFsdDevice->StackSize + 1);
187:
188: }
189: else
190: {
191: DISK_GEOMETRY dg;
192:
193: ZwClose (Extension->hDeviceFile);
194: Extension->hDeviceFile = NULL;
195:
196: if (Extension->bReadOnly == TRUE)
197: ntStatus = IoGetDeviceObjectPointer (&FullFileName,
198: FILE_READ_DATA,
199: &Extension->pfoDeviceFile,
200: &Extension->pFsdDevice);
201: else
202: ntStatus = IoGetDeviceObjectPointer (&FullFileName,
203: FILE_ALL_ACCESS,
204: &Extension->pfoDeviceFile,
205: &Extension->pFsdDevice);
206:
207: if (!NT_SUCCESS (ntStatus))
208: {
209: goto error;
210: }
211:
212: DeviceObject->StackSize = (CCHAR) (Extension->pFsdDevice->StackSize + 1);
213:
214:
215: if (wcscmp (Extension->pFsdDevice->DriverObject->DriverName.Buffer, WIDE ("\\FileSystem\\RAW")) != 0)
216: {
217: /* FAT/NTFS "knows" about this device */
218: ntStatus = STATUS_SHARING_VIOLATION;
219: goto error;
220: }
221:
222: ntStatus = TCSendDeviceIoControlRequest (DeviceObject,
223: Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY,
224: (char *) &dg, sizeof (dg));
225:
226: if (!NT_SUCCESS (ntStatus))
227: {
228: goto error;
229: }
230:
231: if (dg.MediaType == FixedMedia)
232: {
233: PARTITION_INFORMATION pi;
234:
235: ntStatus = TCSendDeviceIoControlRequest (DeviceObject,
236: Extension, IOCTL_DISK_GET_PARTITION_INFO,
237: (char *) &pi, sizeof (pi));
238:
239: if (!NT_SUCCESS (ntStatus))
240: {
241: goto error;
242: }
243: else
244: lDiskLength.QuadPart = pi.PartitionLength.QuadPart;
245:
246: }
247: else
248: {
249: lDiskLength.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack *
250: dg.TracksPerCylinder * dg.BytesPerSector;
251: }
252:
253:
254: }
255:
256: if (lDiskLength.QuadPart < MIN_VOLUME_SIZE || lDiskLength.QuadPart > MAX_VOLUME_SIZE)
257: {
258: /* Volume too large or too small for us to handle... */
259: mount->nReturnCode = ERR_VOL_SIZE_WRONG;
260: ntStatus = STATUS_SUCCESS;
261: goto error;
262: }
263: else
264: Extension->DiskLength = lDiskLength.QuadPart;
265:
266: /* Attempt to recognize the volume */
267:
268: KeWaitForMutexObject (&driverMutex, Executive, KernelMode,
269: FALSE, NULL);
270:
271: mount->nReturnCode = VolumeReadHeaderCache (
272: mount->bCache,
273: readBuffer,
274: mount->szPassword,
275: strlen (mount->szPassword),
276: &Extension->cryptoInfo);
277:
278: KeReleaseMutex (&driverMutex, FALSE);
279:
280: if (mount->nReturnCode == 0)
281: {
282: /* Handle the volume setup for TC */
283:
284: boot_sector = (struct msdos_boot_sector *) (readBuffer + SECTOR_SIZE);
285:
286: /* It's in the volume file so we must decrypt it */
287: Extension->cryptoInfo->decrypt_sector ((ULONG *) boot_sector, 1, 1,
288: &Extension->cryptoInfo->ks[0],
289: Extension->cryptoInfo->iv,
290: Extension->cryptoInfo->cipher);
291:
292: /* There's one extra sector than there should be */
293: Extension->DiskLength -= SECTOR_SIZE;
294:
295: /* Volume setup end */
296:
297: //Extension->TracksPerCylinder = boot_sector->heads;
298: //Extension->SectorsPerTrack = boot_sector->secs_track;
299: //Extension->NumberOfCylinders = (ULONG) (Extension->DiskLength / Extension->BytesPerSector /
300: // Extension->SectorsPerTrack / Extension->TracksPerCylinder);
301: Extension->TracksPerCylinder = 1;
302: Extension->SectorsPerTrack = 1;
303: Extension->BytesPerSector = *((unsigned short *) boot_sector->sector_size);
304: Extension->NumberOfCylinders = Extension->DiskLength / Extension->BytesPerSector;
305:
306: Extension->PartitionType = (UCHAR) ((boot_sector->fs_type[4] == '6') ?
307: PARTITION_FAT_16 : PARTITION_FAT_12);
308: if(boot_sector->fs_type[3] == '3') Extension->PartitionType = (UCHAR) PARTITION_FAT32;
309:
310: Extension->bRawDevice = bRawDevice;
311:
312: if (wcslen (pwszMountVolume) < 64)
313: wcscpy (Extension->wszVolume, pwszMountVolume);
314: else
315: {
316: memcpy (Extension->wszVolume, pwszMountVolume, 60 * 2);
317: Extension->wszVolume[60] = (WCHAR) '.';
318: Extension->wszVolume[61] = (WCHAR) '.';
319: Extension->wszVolume[62] = (WCHAR) '.';
320: Extension->wszVolume[63] = (WCHAR) 0;
321: }
322:
323: Extension->mountTime = mount->time;
324:
325: TCfree (readBuffer);
326:
327: return STATUS_SUCCESS;
328: }
329:
330:
331: /* Failed due to some non-OS reason so we drop through and return NT
332: SUCCESS then nReturnCode is checked later in user-mode */
333:
334: if (mount->nReturnCode == ERR_OUTOFMEMORY)
335: ntStatus = STATUS_INSUFFICIENT_RESOURCES;
336: else
337: ntStatus = STATUS_SUCCESS;
338:
339: error:
340:
341: /* Close the hDeviceFile */
342: if (Extension->hDeviceFile != NULL)
343: ZwClose (Extension->hDeviceFile);
344:
345: /* The cryptoInfo pointer is deallocated if the readheader routines
346: fail so there is no need to deallocate here */
347:
348: /* Dereference the user-mode file object */
349: if (Extension->pfoDeviceFile != NULL)
350: ObDereferenceObject (Extension->pfoDeviceFile);
351:
352: /* Free the tmp IO buffer */
353: if (readBuffer != NULL)
354: TCfree (readBuffer);
355:
356: return ntStatus;
357: }
358:
359: void
360: TCCloseVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
361: {
362: if (DeviceObject); /* Remove compiler warning */
363:
364: if (Extension->hDeviceFile != NULL)
365: ZwClose (Extension->hDeviceFile);
366: ObDereferenceObject (Extension->pfoDeviceFile);
367: crypto_close (Extension->cryptoInfo);
368:
369: }
370:
371: /* This rountine can be called at any IRQL so we need to tread carefully. Not
372: even DbgPrint or KdPrint are called here as the kernel sometimes faults if
373: they are called at high IRQL */
374:
375: NTSTATUS
376: TCCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID pUserBuffer)
377: {
378: PIO_STACK_LOCATION irpSp;
379: PEXTENSION Extension;
380: NTSTATUS ntStatus;
381:
382: Extension = (PEXTENSION) DeviceObject->DeviceExtension;
383:
384: /* Check to make sure the DeviceObject passed in is actually ours! */
385: if (Extension->lMagicNumber != 0xabfeacde)
386: KeBugCheck ((ULONG) 0xabfeacde);
387:
388: ASSERT (Extension->nDosDriveNo >= 0 && Extension->nDosDriveNo <= 0x19);
389:
390: #ifdef USE_KERNEL_MUTEX
391: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
392: FALSE, NULL);
393: #endif
394:
395: #if EXTRA_INFO
396: Dump ("Completing IRP...BEGIN\n");
397: Dump ("COMPLETION USER BUFFER IS 0x%08x MDL ADDRESS IS 0x%08x\n", Irp->UserBuffer, Irp->MdlAddress);
398: Dump ("COMPLETION Irp->Tail.Overlay.OriginalFileObject = 0x%08x\n", Irp->Tail.Overlay.OriginalFileObject);
399: Dump ("Completing DeviceObject 0x%08x Irp 0x%08x\n", DeviceObject, Irp);
400: #endif
401:
402: /* Note: The Irp stack location we get back here is our one, we setup
403: the next stack location with a copy of this stack data in the send
404: function... here we always get back our own stack location, so
405: it's possible to use Read.Key to store extra pointers if needed. */
406: irpSp = IoGetCurrentIrpStackLocation (Irp);
407:
408: ntStatus = Irp->IoStatus.Status;
409:
410: if (ntStatus == STATUS_TOO_LATE)
411: KeBugCheck ((ULONG) 0x50ff);
412:
413: if (Irp->PendingReturned) /* From Windows NT File System
414: Internals */
415: IoMarkIrpPending (Irp);
416:
417: if (Extension->bRawDevice == FALSE)
418: {
419: /* Note: For some reason even though we used DIRECT_IO
420: sometimes the Irp's come back to use with MDLs !! if we
421: get an MDL here we need to free it up otherwise later when
422: we call IoFreeIrp the system will trap */
423:
424: PMDL pMdl, pNextMdl;
425:
426: pMdl = Irp->MdlAddress;
427:
428: while (pMdl != NULL)
429: {
430: pNextMdl = pMdl->Next;
431:
432: MmUnmapLockedPages (MmGetSystemAddressForMdlSafe (pMdl, HighPagePriority), pMdl);
433: MmUnlockPages (pMdl);
434: IoFreeMdl (pMdl);
435:
436: pMdl = pNextMdl;
437: }
438: }
439:
440: if (NT_SUCCESS (Irp->IoStatus.Status) && irpSp->MajorFunction == IRP_MJ_READ)
441: {
442: __int64 tmpOffset = irpSp->Parameters.Read.ByteOffset.QuadPart;
443: ULONG tmpLength = irpSp->Parameters.Read.Length;
444: PUCHAR CurrentAddress;
445:
446: if (Extension->bRawDevice == TRUE)
447: CurrentAddress = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority);
448: else
449: CurrentAddress = Irp->UserBuffer;
450:
451: if (tmpLength > 0)
452: {
453: /* Decrypt the data on read */
454: Extension->cryptoInfo->decrypt_sector ((ULONG *) CurrentAddress,
455: tmpOffset / SECTOR_SIZE,
456: tmpLength / SECTOR_SIZE,
457: &Extension->cryptoInfo->ks[0],
458: Extension->cryptoInfo->iv,
459: Extension->cryptoInfo->cipher);
460: }
461:
462: if (Extension->bRawDevice == FALSE)
463: {
464: PIRP OldIrp = (PIRP) pUserBuffer;
465: PUCHAR OriginalAddress;
466: CurrentAddress = Irp->UserBuffer;
467: OriginalAddress = MmGetSystemAddressForMdlSafe (OldIrp->MdlAddress, HighPagePriority);
468: memcpy (OriginalAddress, CurrentAddress, Irp->IoStatus.Information);
469: }
470:
471: }
472:
473: if (NT_SUCCESS (Irp->IoStatus.Status) && irpSp->MajorFunction == IRP_MJ_WRITE)
474: {
475: PUCHAR CurrentAddress;
476: PUCHAR OriginalAddress;
477:
478: if (Extension->bRawDevice == TRUE)
479: {
480: CurrentAddress = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority);
481: OriginalAddress = MmGetSystemAddressForMdlSafe ((PMDL) pUserBuffer, HighPagePriority);
482: }
483: else
484: {
485: PIRP OldIrp = (PIRP) pUserBuffer;
486: CurrentAddress = Irp->UserBuffer;
487: OriginalAddress = MmGetSystemAddressForMdlSafe (OldIrp->MdlAddress, HighPagePriority);
488: }
489:
490: //if (NT_SUCCESS (Irp->IoStatus.Status))
491: //{
492: // __int64 tmpOffset = irpSp->Parameters.Read.ByteOffset.QuadPart;
493: //}
494: }
495:
496: if (Extension->bRawDevice == TRUE && irpSp->MajorFunction == IRP_MJ_WRITE)
497: {
498: PUCHAR tmpBuffer = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority);
499: /* Free the temp buffer we allocated */
500: TCfree (tmpBuffer);
501: /* Free the Mdl we allocated */
502: IoFreeMdl (Irp->MdlAddress);
503: /* Reset the Irp */
504: Irp->MdlAddress = pUserBuffer;
505: }
506:
507: if (Extension->bRawDevice == TRUE && irpSp->MajorFunction == IRP_MJ_READ)
508: {
509: /* Nothing to do */
510: }
511:
512: #if EXTRA_INFO
513: Dump ("COMPLETION OLD USER BUFFER IS 0x%08x MDL ADDRESS IS 0x%08x\n", Irp->UserBuffer, Irp->MdlAddress);
514: Dump ("COMPLETION OLD Irp->Tail.Overlay.OriginalFileObject = 0x%08x\n", Irp->Tail.Overlay.OriginalFileObject);
515: Dump ("Completing IRP 0x%08x NTSTATUS 0x%08x information %lu END\n", (ULONG) irpSp->MajorFunction,
516: Irp->IoStatus.Status, Irp->IoStatus.Information);
517: #endif
518:
519: if (Extension->bRawDevice == FALSE)
520: {
521: PIRP OldIrp = (PIRP) pUserBuffer;
522: PVOID tmpBuffer = Irp->UserBuffer;
523: BOOL bFreeBuffer = irpSp->MajorFunction == IRP_MJ_WRITE || irpSp->MajorFunction == IRP_MJ_READ;
524:
525: OldIrp->IoStatus.Status = Irp->IoStatus.Status;
526: OldIrp->IoStatus.Information = Irp->IoStatus.Information;
527:
528: IoCompleteRequest (OldIrp, IO_DISK_INCREMENT);
529:
530: #if EXTRA_INFO
531: Dump ("About to free allocated IRP\n");
532: #endif
533:
534: Irp->UserBuffer = NULL;
535:
536: /* Free the allocated IRP. Note: This must be done before we
537: free tmpBuffer! */
538: IoFreeIrp (Irp);
539:
540: /* Note: From here on we cannot touch the Irp or irpSp */
541:
542: #if EXTRA_INFO
543: Dump ("Free allocated buffer = %d\n", bFreeBuffer);
544: #endif
545:
546: if (bFreeBuffer == TRUE)
547: TCfree (tmpBuffer);
548:
549: ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
550: }
551:
552: #ifdef USE_KERNEL_MUTEX
553: KeReleaseMutex (&Extension->KernelMutex, FALSE);
554: #endif
555:
556: return ntStatus;
557: }
558:
559: NTSTATUS
560: TCReadWrite (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
561: {
562: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
563: PUCHAR tmpBuffer = NULL;/* Remove compiler warning */
564: NTSTATUS ntStatus;
565:
566: // Dump ("TCReadWrite BEGIN\n");
567:
568: /* Check for invalid parameters. It is an error for the starting
569: offset + length to go past the end of the buffer, or for the
570: length to not be a proper multiple of the sector size. Others are
571: possible, but we don't check them since we trust the file system
572: and they aren't deadly. */
573: if (irpSp->Parameters.Read.ByteOffset.QuadPart + irpSp->Parameters.Read.Length > Extension->DiskLength
574: || (irpSp->Parameters.Read.Length & (Extension->BytesPerSector - 1)))
575: {
576: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_PARAMETER, 0);
577: }
578: else
579: {
580: if (irpSp->Parameters.Read.Length == 0)
581: {
582: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_PARAMETER, 0);
583: }
584: }
585:
586: #if EXTRA_INFO
587: Dump ("USER BUFFER IS 0x%08x MDL ADDRESS IS 0x%08x\n", Irp->UserBuffer, Irp->MdlAddress);
588: Dump ("Irp->Tail.Overlay.OriginalFileObject = 0x%08x\n", Irp->Tail.Overlay.OriginalFileObject);
589: Dump ("irpSp->FileObject = 0x%08x\n", irpSp->FileObject);
590:
591: if (Irp->Tail.Overlay.OriginalFileObject != NULL)
592: {
593: if (Irp->Tail.Overlay.OriginalFileObject->FileName.Length != 0)
594: Dump ("Irp->Tail.Overlay.OriginalFileObject = %ls\n", Irp->Tail.Overlay.OriginalFileObject->FileName.Buffer);
595: else
596: Dump ("Irp->Tail.Overlay.OriginalFileObject = %ls\n", WIDE ("null value"));
597:
598: }
599:
600: if (irpSp->FileObject != NULL)
601: {
602: if (irpSp->FileObject->FileName.Length != 0)
603: Dump ("irpSp->FileObject = %ls\n", irpSp->FileObject->FileName.Buffer);
604: else
605: Dump ("irpSp->FileObject = %ls\n", WIDE ("null value"));
606:
607: }
608: #endif
609:
610: if (Extension->bReadOnly == TRUE && irpSp->MajorFunction == IRP_MJ_WRITE)
611: return COMPLETE_IRP (DeviceObject, Irp, STATUS_MEDIA_WRITE_PROTECTED, 0);
612:
613: if (Extension->bRawDevice == FALSE || irpSp->MajorFunction == IRP_MJ_WRITE)
614: {
615: tmpBuffer = TCalloc (irpSp->Parameters.Read.Length);
616: if (tmpBuffer == NULL)
617: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
618: }
619:
620: if (irpSp->MajorFunction == IRP_MJ_READ)
621: {
622: // Dump ("Read: 0x%08x for %lu bytes...\n", irpSp->Parameters.Read.ByteOffset.LowPart,
623: // irpSp->Parameters.Read.Length);
624:
625: /* Fixup the parameters to handle this particular volume type */
626: irpSp->Parameters.Read.ByteOffset.QuadPart += SECTOR_SIZE;
627:
628: if (Extension->bRawDevice == TRUE)
629: ntStatus = TCSendIRP_RawDevice (DeviceObject, Extension,
630: NULL, IRP_READ_OPERATION | IRP_NOCACHE,
631: irpSp->MajorFunction,
632: Irp);
633: else
634: ntStatus = TCSendIRP_FileDevice (DeviceObject, Extension,
635: tmpBuffer, IRP_READ_OPERATION | IRP_NOCACHE,
636: irpSp->MajorFunction,
637: Irp);
638: }
639: else
640: {
641: PUCHAR CurrentAddress;
642:
643: // Dump ("Write: 0x%08x for %lu bytes...\n", irpSp->Parameters.Read.ByteOffset.LowPart,
644: // irpSp->Parameters.Read.Length);
645:
646: CurrentAddress = (PUCHAR) MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority);
647:
648: /* Fixup the parameters to handle this particular volume type */
649: irpSp->Parameters.Read.ByteOffset.QuadPart += SECTOR_SIZE;
650:
651: memcpy (tmpBuffer, CurrentAddress, irpSp->Parameters.Read.Length);
652:
653: /* Encrypt the data */
654: Extension->cryptoInfo->encrypt_sector ((ULONG *) tmpBuffer,
655: irpSp->Parameters.Read.ByteOffset.QuadPart / SECTOR_SIZE,
656: irpSp->Parameters.Read.Length / SECTOR_SIZE,
657: &Extension->cryptoInfo->ks[0],
658: Extension->cryptoInfo->iv,
659: Extension->cryptoInfo->cipher);
660:
661: if (Extension->bRawDevice == TRUE)
662: {
663: PMDL tmpBufferMdl = IoAllocateMdl (tmpBuffer, irpSp->Parameters.Read.Length, FALSE, FALSE, NULL);
664: PMDL pTrueMdl = Irp->MdlAddress;
665:
666: if (tmpBufferMdl == NULL)
667: {
668: TCfree (tmpBuffer);
669: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
670: }
671:
672: MmBuildMdlForNonPagedPool (tmpBufferMdl);
673:
674: Irp->MdlAddress = tmpBufferMdl;
675:
676: #if EXTRA_INFO
677: Dump ("NEW MDL ADDRESS IS 0x%08x UserBuffer = 0x%08x\n", Irp->MdlAddress, Irp->UserBuffer);
678: #endif
679:
680: ntStatus = TCSendIRP_RawDevice (DeviceObject, Extension,
681: pTrueMdl, IRP_WRITE_OPERATION | IRP_NOCACHE,
682: irpSp->MajorFunction,
683: Irp);
684: }
685: else
686: {
687: ntStatus = TCSendIRP_FileDevice (DeviceObject, Extension,
688: tmpBuffer, IRP_WRITE_OPERATION | IRP_NOCACHE,
689: irpSp->MajorFunction,
690: Irp);
691: }
692:
693: }
694:
695: // Dump ("TCReadWrite END\n");
696: return ntStatus;
697: }
698:
699: NTSTATUS
700: TCSendDeviceIoControlRequest (PDEVICE_OBJECT DeviceObject,
701: PEXTENSION Extension,
702: ULONG IoControlCode,
703: char *OutputBuffer,
704: int OutputBufferSize)
705: {
706: IO_STATUS_BLOCK IoStatusBlock;
707: NTSTATUS ntStatus;
708: PIRP Irp;
709:
710: if (DeviceObject); /* Remove compiler warning */
711:
712: KeClearEvent (&Extension->keVolumeEvent);
713:
714: Irp = IoBuildDeviceIoControlRequest (IoControlCode,
715: Extension->pFsdDevice,
716: NULL, 0,
717: OutputBuffer, OutputBufferSize,
718: FALSE,
719: &Extension->keVolumeEvent,
720: &IoStatusBlock);
721:
722: if (Irp == NULL)
723: {
724: Dump ("IRP allocation failed\n");
725: return STATUS_INSUFFICIENT_RESOURCES;
726: }
727:
728: ntStatus = IoCallDriver (Extension->pFsdDevice, Irp);
729: if (ntStatus == STATUS_PENDING)
730: {
731: KeWaitForSingleObject (&Extension->keVolumeEvent, UserRequest, UserMode, FALSE, NULL);
732: ntStatus = IoStatusBlock.Status;
733: }
734:
735: return ntStatus;
736: }
737:
738: NTSTATUS
739: COMPLETE_IRP (PDEVICE_OBJECT DeviceObject,
740: PIRP Irp,
741: NTSTATUS IrpStatus,
742: ULONG IrpInformation)
743: {
744: Irp->IoStatus.Status = IrpStatus;
745: Irp->IoStatus.Information = IrpInformation;
746:
747: if (DeviceObject); /* Remove compiler warning */
748:
749: #ifdef _DEBUG
750: if (!NT_SUCCESS (IrpStatus))
751: {
752: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
753: Dump ("COMPLETE_IRP FAILING IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction),
754: (ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus);
755: }
756: //else
757: //{
758: // PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
759: // Dump ("COMPLETE_IRP SUCCESS IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction),
760: // (ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus);
761: //}
762: #endif
763: IoCompleteRequest (Irp, IO_NO_INCREMENT);
764: return IrpStatus;
765: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.