Annotation of truecrypt/driver/ntvol.c, revision 1.1.1.2

1.1.1.2 ! root        1: /* Copyright (C) 2004 TrueCrypt Foundation
1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.