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

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: }

unix.superglobalmegacorp.com

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