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

1.1.1.10  root        1: /*
1.1.1.12  root        2:  Legal Notice: Some portions of the source code contained in this file were
                      3:  derived from the source code of Encryption for the Masses 2.02a, which is
                      4:  Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
                      5:  Agreement for Encryption for the Masses'. Modifications and additions to
1.1.1.20  root        6:  the original source code (contained in this file) and all other portions
1.1.1.21  root        7:  of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
                      8:  and are governed by the TrueCrypt License 3.0 the full text of which is
1.1.1.20  root        9:  contained in the file License.txt included in TrueCrypt binary and source
                     10:  code distribution packages. */
1.1       root       11: 
                     12: #include "TCdefs.h"
1.1.1.15  root       13: #include <wchar.h>
1.1.1.6   root       14: #include "Crypto.h"
                     15: #include "Volumes.h"
1.1       root       16: 
1.1.1.6   root       17: #include "Apidrvr.h"
1.1.1.14  root       18: #include "DriveFilter.h"
1.1.1.6   root       19: #include "Ntdriver.h"
                     20: #include "Ntvol.h"
1.1.1.14  root       21: #include "VolumeFilter.h"
1.1       root       22: 
1.1.1.13  root       23: #include "Boot/Windows/BootCommon.h"
                     24: 
1.1.1.6   root       25: #include "Cache.h"
1.1       root       26: 
1.1.1.10  root       27: #if 0 && _DEBUG
                     28: #define EXTRA_INFO 1
                     29: #endif
1.1       root       30: 
                     31: #pragma warning( disable : 4127 )
                     32: 
1.1.1.14  root       33: volatile BOOL ProbingHostDeviceForWrite = FALSE;
                     34: 
                     35: 
1.1.1.15  root       36: NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
1.1       root       37:               PEXTENSION Extension,
1.1.1.6   root       38:               MOUNT_STRUCT *mount,
1.1       root       39:               PWSTR pwszMountVolume,
                     40:               BOOL bRawDevice)
                     41: {
                     42:        FILE_STANDARD_INFORMATION FileStandardInfo;
                     43:        FILE_BASIC_INFORMATION FileBasicInfo;
                     44:        OBJECT_ATTRIBUTES oaFileAttributes;
                     45:        UNICODE_STRING FullFileName;
                     46:        IO_STATUS_BLOCK IoStatusBlock;
1.1.1.6   root       47:        PCRYPTO_INFO cryptoInfoPtr = NULL;
                     48:        PCRYPTO_INFO tmpCryptoInfo = NULL;
1.1       root       49:        LARGE_INTEGER lDiskLength;
1.1.1.15  root       50:        __int64 partitionStartingOffset = 0;
1.1.1.6   root       51:        int volumeType;
1.1.1.4   root       52:        char *readBuffer = 0;
1.1.1.5   root       53:        NTSTATUS ntStatus = 0;
1.1.1.15  root       54:        BOOL forceAccessCheck = (!bRawDevice && !(OsMajorVersion == 5 &&OsMinorVersion == 0)); // Windows 2000 does not support OBJ_FORCE_ACCESS_CHECK attribute
1.1.1.21  root       55:        BOOL disableBuffering = TRUE;
1.1.1.22! root       56:        BOOL exclusiveAccess = mount->bExclusiveAccess;
1.1       root       57: 
                     58:        Extension->pfoDeviceFile = NULL;
                     59:        Extension->hDeviceFile = NULL;
1.1.1.6   root       60:        Extension->bTimeStampValid = FALSE;
1.1       root       61: 
1.1.1.4   root       62:        RtlInitUnicodeString (&FullFileName, pwszMountVolume);
1.1.1.21  root       63:        InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | (forceAccessCheck ? OBJ_FORCE_ACCESS_CHECK : 0) | OBJ_KERNEL_HANDLE, NULL, NULL);
1.1.1.4   root       64:        KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE);
                     65: 
1.1.1.15  root       66:        if (Extension->SecurityClientContextValid)
                     67:        {
                     68:                ntStatus = SeImpersonateClientEx (&Extension->SecurityClientContext, NULL);
                     69:                if (!NT_SUCCESS (ntStatus))
                     70:                        goto error;
                     71:        }
                     72: 
1.1.1.17  root       73:        mount->VolumeMountedReadOnlyAfterDeviceWriteProtected = FALSE;
                     74: 
1.1.1.4   root       75:        // If we are opening a device, query its size first
                     76:        if (bRawDevice)
1.1       root       77:        {
1.1.1.5   root       78:                PARTITION_INFORMATION pi;
1.1.1.10  root       79:                PARTITION_INFORMATION_EX pix;
1.1.1.15  root       80:                LARGE_INTEGER diskLengthInfo;
1.1.1.4   root       81:                DISK_GEOMETRY dg;
1.1       root       82: 
1.1.1.4   root       83:                ntStatus = IoGetDeviceObjectPointer (&FullFileName,
1.1.1.19  root       84:                        FILE_READ_DATA | FILE_READ_ATTRIBUTES,
1.1.1.4   root       85:                        &Extension->pfoDeviceFile,
                     86:                        &Extension->pFsdDevice);
                     87: 
                     88:                if (!NT_SUCCESS (ntStatus))
                     89:                        goto error;
                     90: 
1.1.1.21  root       91:                ntStatus = TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY, (char *) &dg, sizeof (dg));
                     92:                if (!NT_SUCCESS (ntStatus))
                     93:                        goto error;
                     94: 
                     95:                lDiskLength.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.BytesPerSector;
                     96:                Extension->HostBytesPerSector = dg.BytesPerSector;
1.1.1.4   root       97: 
1.1.1.10  root       98:                // Drive geometry is used only when IOCTL_DISK_GET_PARTITION_INFO fails
1.1.1.12  root       99:                if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO_EX, (char *) &pix, sizeof (pix))))
1.1.1.13  root      100:                {
1.1.1.10  root      101:                        lDiskLength.QuadPart = pix.PartitionLength.QuadPart;
1.1.1.13  root      102:                        partitionStartingOffset = pix.StartingOffset.QuadPart;
                    103:                }
1.1.1.10  root      104:                // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX
1.1.1.12  root      105:                else if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO, (char *) &pi, sizeof (pi))))
1.1.1.13  root      106:                {
1.1.1.10  root      107:                        lDiskLength.QuadPart = pi.PartitionLength.QuadPart;
1.1.1.13  root      108:                        partitionStartingOffset = pi.StartingOffset.QuadPart;
                    109:                }
1.1.1.15  root      110:                else if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_LENGTH_INFO, &diskLengthInfo, sizeof (diskLengthInfo))))
                    111:                {
                    112:                        lDiskLength = diskLengthInfo;
                    113:                }
1.1       root      114: 
1.1.1.14  root      115:                ProbingHostDeviceForWrite = TRUE;
                    116: 
                    117:                if (!mount->bMountReadOnly
                    118:                        && TCSendHostDeviceIoControlRequest (DeviceObject, Extension,
                    119:                                IsHiddenSystemRunning() ? TC_IOCTL_DISK_IS_WRITABLE : IOCTL_DISK_IS_WRITABLE, NULL, 0) == STATUS_MEDIA_WRITE_PROTECTED)
1.1.1.10  root      120:                {
                    121:                        mount->bMountReadOnly = TRUE;
                    122:                        DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
1.1.1.17  root      123:                        mount->VolumeMountedReadOnlyAfterDeviceWriteProtected = TRUE;
1.1.1.4   root      124:                }
1.1.1.14  root      125: 
                    126:                ProbingHostDeviceForWrite = FALSE;
1.1.1.22! root      127: 
        !           128:                // Some Windows tools (e.g. diskmgmt, diskpart, vssadmin) fail or experience timeouts when there is a raw device
        !           129:                // open for exclusive access. Therefore, exclusive access is used only for file-hosted volumes.
        !           130:                // Applications requiring a consistent device image need to acquire exclusive write access first. This is prevented
        !           131:                // when a device-hosted volume is mounted.
        !           132: 
        !           133:                exclusiveAccess = FALSE;
1.1.1.4   root      134:        }
1.1.1.21  root      135:        else
                    136:        {
                    137:                // Limit the maximum required buffer size
                    138:                if (mount->BytesPerSector > 128 * BYTES_PER_KB)
                    139:                {
                    140:                        ntStatus = STATUS_INVALID_PARAMETER;
                    141:                        goto error;
                    142:                }
1.1       root      143: 
1.1.1.21  root      144:                Extension->HostBytesPerSector = mount->BytesPerSector;
1.1.1.10  root      145: 
1.1.1.21  root      146:                if (Extension->HostBytesPerSector != TC_SECTOR_SIZE_FILE_HOSTED_VOLUME)
                    147:                        disableBuffering = FALSE;
                    148:        }
1.1.1.10  root      149: 
1.1.1.4   root      150:        // Open the volume hosting file/device
                    151:        if (!mount->bMountReadOnly)
                    152:        {
                    153:                ntStatus = ZwCreateFile (&Extension->hDeviceFile,
                    154:                        GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
                    155:                        &oaFileAttributes,
                    156:                        &IoStatusBlock,
                    157:                        NULL,
                    158:                        FILE_ATTRIBUTE_NORMAL |
                    159:                        FILE_ATTRIBUTE_SYSTEM,
1.1.1.22! root      160:                        exclusiveAccess ? 0 : FILE_SHARE_READ | FILE_SHARE_WRITE,
1.1.1.4   root      161:                        FILE_OPEN,
1.1.1.10  root      162:                        FILE_RANDOM_ACCESS |
1.1.1.4   root      163:                        FILE_WRITE_THROUGH |
1.1.1.21  root      164:                        (disableBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0) |
1.1.1.4   root      165:                        FILE_SYNCHRONOUS_IO_NONALERT,
                    166:                        NULL,
                    167:                        0);
                    168:        }
1.1       root      169: 
1.1.1.10  root      170:        /* 26-4-99 NT for some partitions returns this code, it is really a     access denied */
1.1       root      171:        if (ntStatus == 0xc000001b)
                    172:                ntStatus = STATUS_ACCESS_DENIED;
1.1.1.16  root      173: 
                    174:        mount->VolumeMountedReadOnlyAfterAccessDenied = FALSE;
                    175: 
1.1.1.4   root      176:        if (mount->bMountReadOnly || ntStatus == STATUS_ACCESS_DENIED)
1.1       root      177:        {
                    178:                ntStatus = ZwCreateFile (&Extension->hDeviceFile,
1.1.1.4   root      179:                        GENERIC_READ | SYNCHRONIZE,
                    180:                        &oaFileAttributes,
                    181:                        &IoStatusBlock,
                    182:                        NULL,
                    183:                        FILE_ATTRIBUTE_NORMAL |
                    184:                        FILE_ATTRIBUTE_SYSTEM,
1.1.1.22! root      185:                        exclusiveAccess ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE,
1.1.1.4   root      186:                        FILE_OPEN,
1.1.1.10  root      187:                        FILE_RANDOM_ACCESS |
1.1.1.4   root      188:                        FILE_WRITE_THROUGH |
1.1.1.21  root      189:                        (disableBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0) |
1.1.1.4   root      190:                        FILE_SYNCHRONOUS_IO_NONALERT,
                    191:                        NULL,
                    192:                        0);
1.1.1.11  root      193: 
1.1.1.16  root      194:                if (NT_SUCCESS (ntStatus) && !mount->bMountReadOnly)
                    195:                        mount->VolumeMountedReadOnlyAfterAccessDenied = TRUE;
                    196: 
1.1       root      197:                Extension->bReadOnly = TRUE;
1.1.1.11  root      198:                DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
1.1       root      199:        }
                    200:        else
                    201:                Extension->bReadOnly = FALSE;
                    202: 
                    203:        /* 26-4-99 NT for some partitions returns this code, it is really a
1.1.1.4   root      204:        access denied */
1.1       root      205:        if (ntStatus == 0xc000001b)
                    206:        {
                    207:                /* Partitions which return this code can still be opened with
1.1.1.4   root      208:                FILE_SHARE_READ but this causes NT problems elsewhere in
                    209:                particular if you do FILE_SHARE_READ NT will die later if
1.1.1.12  root      210:                anyone even tries to open the partition (or file for that
1.1.1.4   root      211:                matter...)  */
1.1       root      212:                ntStatus = STATUS_SHARING_VIOLATION;
                    213:        }
                    214: 
                    215:        if (!NT_SUCCESS (ntStatus))
                    216:        {
                    217:                goto error;
                    218:        }
                    219: 
1.1.1.4   root      220:        // If we have opened a file, query its size now
1.1       root      221:        if (bRawDevice == FALSE)
                    222:        {
                    223:                ntStatus = ZwQueryInformationFile (Extension->hDeviceFile,
1.1.1.4   root      224:                        &IoStatusBlock,
                    225:                        &FileBasicInfo,
                    226:                        sizeof (FileBasicInfo),
                    227:                        FileBasicInformation);
1.1       root      228: 
                    229:                if (NT_SUCCESS (ntStatus))
1.1.1.4   root      230:                {
1.1.1.6   root      231:                        if (mount->bPreserveTimestamp)
                    232:                        {
                    233:                                Extension->fileCreationTime = FileBasicInfo.CreationTime;
                    234:                                Extension->fileLastAccessTime = FileBasicInfo.LastAccessTime;
                    235:                                Extension->fileLastWriteTime = FileBasicInfo.LastWriteTime;
                    236:                                Extension->fileLastChangeTime = FileBasicInfo.ChangeTime;
                    237:                                Extension->bTimeStampValid = TRUE;
                    238:                        }
1.1.1.4   root      239: 
1.1       root      240:                        ntStatus = ZwQueryInformationFile (Extension->hDeviceFile,
1.1.1.4   root      241:                                &IoStatusBlock,
                    242:                                &FileStandardInfo,
                    243:                                sizeof (FileStandardInfo),
                    244:                                FileStandardInformation);
                    245:                }
1.1       root      246: 
                    247:                if (!NT_SUCCESS (ntStatus))
                    248:                {
                    249:                        Dump ("ZwQueryInformationFile failed while opening file: NTSTATUS 0x%08x\n",
1.1.1.4   root      250:                                ntStatus);
1.1       root      251:                        goto error;
                    252:                }
1.1.1.4   root      253: 
                    254:                lDiskLength.QuadPart = FileStandardInfo.EndOfFile.QuadPart;
1.1       root      255: 
                    256:                if (FileBasicInfo.FileAttributes & FILE_ATTRIBUTE_COMPRESSED)
                    257:                {
                    258:                        Dump ("File \"%ls\" is marked as compressed - not supported!\n", pwszMountVolume);
                    259:                        mount->nReturnCode = ERR_COMPRESSION_NOT_SUPPORTED;
                    260:                        ntStatus = STATUS_SUCCESS;
                    261:                        goto error;
                    262:                }
                    263: 
                    264:                ntStatus = ObReferenceObjectByHandle (Extension->hDeviceFile,
1.1.1.4   root      265:                        FILE_ALL_ACCESS,
                    266:                        *IoFileObjectType,
                    267:                        KernelMode,
                    268:                        &Extension->pfoDeviceFile,
                    269:                        0);
1.1       root      270: 
                    271:                if (!NT_SUCCESS (ntStatus))
                    272:                {
                    273:                        goto error;
                    274:                }
                    275: 
1.1.1.4   root      276:                /* Get the FSD device for the file (probably either NTFS or     FAT) */
1.1       root      277:                Extension->pFsdDevice = IoGetRelatedDeviceObject (Extension->pfoDeviceFile);
                    278:        }
1.1.1.15  root      279:        else
                    280:        {
                    281:                // Try to gain "raw" access to the partition in case there is a live filesystem on it (otherwise, 
                    282:                // the NTFS driver guards hidden sectors and prevents mounting using a backup header e.g. after the user 
                    283:                // accidentally quick-formats a dismounted partition-hosted TrueCrypt volume as NTFS).
                    284: 
                    285:                PFILE_OBJECT pfoTmpDeviceFile = NULL;
                    286: 
                    287:                if (NT_SUCCESS (ObReferenceObjectByHandle (Extension->hDeviceFile, FILE_ALL_ACCESS, *IoFileObjectType, KernelMode, &pfoTmpDeviceFile, NULL))
                    288:                        && pfoTmpDeviceFile != NULL)
                    289:                {
                    290:                        TCFsctlCall (pfoTmpDeviceFile, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0);
                    291:                        ObDereferenceObject (pfoTmpDeviceFile);
                    292:                }
                    293:        }
1.1       root      294: 
1.1.1.4   root      295:        // Check volume size
1.1.1.14  root      296:        if (lDiskLength.QuadPart < TC_MIN_VOLUME_SIZE_LEGACY || lDiskLength.QuadPart > TC_MAX_VOLUME_SIZE)
1.1.1.4   root      297:        {
                    298:                mount->nReturnCode = ERR_VOL_SIZE_WRONG;
                    299:                ntStatus = STATUS_SUCCESS;
                    300:                goto error;
                    301:        }
1.1.1.6   root      302: 
1.1.1.4   root      303:        Extension->DiskLength = lDiskLength.QuadPart;
1.1.1.17  root      304:        Extension->HostLength = lDiskLength.QuadPart;
1.1       root      305: 
1.1.1.21  root      306:        readBuffer = TCalloc (max (max (TC_VOLUME_HEADER_EFFECTIVE_SIZE, PAGE_SIZE), Extension->HostBytesPerSector));
1.1.1.4   root      307:        if (readBuffer == NULL)
                    308:        {
                    309:                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                    310:                goto error;
                    311:        }
1.1       root      312: 
1.1.1.6   root      313:        // Go through all volume types (e.g., normal, hidden)
1.1.1.14  root      314:        for (volumeType = TC_VOLUME_TYPE_NORMAL;
                    315:                volumeType < TC_VOLUME_TYPE_COUNT;
1.1.1.6   root      316:                volumeType++)   
1.1.1.4   root      317:        {
1.1.1.14  root      318:                Dump ("Trying to open volume type %d\n", volumeType);
                    319: 
1.1.1.13  root      320:                if (mount->bPartitionInInactiveSysEncScope
1.1.1.14  root      321:                        && volumeType == TC_VOLUME_TYPE_HIDDEN_LEGACY)
1.1.1.13  root      322:                        continue;               
                    323: 
1.1.1.6   root      324:                /* Read the volume header */
1.1       root      325: 
1.1.1.14  root      326:                if (!mount->bPartitionInInactiveSysEncScope
                    327:                        || (mount->bPartitionInInactiveSysEncScope && volumeType == TC_VOLUME_TYPE_HIDDEN))
1.1.1.13  root      328:                {
1.1.1.14  root      329:                        // Header of a volume that is not within the scope of system encryption, or
                    330:                        // header of a system hidden volume (containing a hidden OS)
                    331: 
                    332:                        LARGE_INTEGER headerOffset;
                    333: 
                    334:                        if (mount->UseBackupHeader && lDiskLength.QuadPart <= TC_TOTAL_VOLUME_HEADERS_SIZE)
                    335:                                continue;
                    336: 
                    337:                        switch (volumeType)
                    338:                        {
                    339:                        case TC_VOLUME_TYPE_NORMAL:
                    340:                                headerOffset.QuadPart = mount->UseBackupHeader ? lDiskLength.QuadPart - TC_VOLUME_HEADER_GROUP_SIZE : TC_VOLUME_HEADER_OFFSET;
                    341:                                break;
                    342: 
                    343:                        case TC_VOLUME_TYPE_HIDDEN:
                    344:                                if (lDiskLength.QuadPart <= TC_VOLUME_HEADER_GROUP_SIZE)
                    345:                                        continue;
                    346: 
                    347:                                headerOffset.QuadPart = mount->UseBackupHeader ? lDiskLength.QuadPart - TC_HIDDEN_VOLUME_HEADER_OFFSET : TC_HIDDEN_VOLUME_HEADER_OFFSET;
                    348:                                break;
                    349: 
                    350:                        case TC_VOLUME_TYPE_HIDDEN_LEGACY:
                    351:                                if (mount->UseBackupHeader)
                    352:                                        continue;
                    353: 
1.1.1.21  root      354:                                if (bRawDevice && Extension->HostBytesPerSector != TC_SECTOR_SIZE_LEGACY)
                    355:                                        continue;
                    356: 
1.1.1.14  root      357:                                headerOffset.QuadPart = lDiskLength.QuadPart - TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
                    358:                                break;
                    359:                        }
                    360: 
                    361:                        Dump ("Reading volume header at %I64d\n", headerOffset.QuadPart);
1.1.1.13  root      362: 
                    363:                        ntStatus = ZwReadFile (Extension->hDeviceFile,
1.1.1.6   root      364:                        NULL,
                    365:                        NULL,
                    366:                        NULL,
                    367:                        &IoStatusBlock,
                    368:                        readBuffer,
1.1.1.21  root      369:                        bRawDevice ? max (TC_VOLUME_HEADER_EFFECTIVE_SIZE, Extension->HostBytesPerSector) : TC_VOLUME_HEADER_EFFECTIVE_SIZE,
1.1.1.14  root      370:                        &headerOffset,
1.1.1.6   root      371:                        NULL);
1.1.1.13  root      372:                }
                    373:                else
                    374:                {
                    375:                        // Header of a partition that is within the scope of system encryption
                    376: 
                    377:                        WCHAR parentDrivePath [47+1] = {0};
                    378:                        HANDLE hParentDeviceFile = NULL;
                    379:                        UNICODE_STRING FullParentPath;
                    380:                        OBJECT_ATTRIBUTES oaParentFileAttributes;
                    381:                        LARGE_INTEGER parentKeyDataOffset;
                    382: 
                    383:                        _snwprintf (parentDrivePath,
                    384:                                sizeof (parentDrivePath) / sizeof (WCHAR) - 1,
                    385:                                WIDE ("\\Device\\Harddisk%d\\Partition0"),
                    386:                                mount->nPartitionInInactiveSysEncScopeDriveNo);
                    387: 
                    388:                        Dump ("Mounting partition within scope of system encryption (reading key data from: %ls)\n", parentDrivePath);
                    389: 
                    390:                        RtlInitUnicodeString (&FullParentPath, parentDrivePath);
1.1.1.21  root      391:                        InitializeObjectAttributes (&oaParentFileAttributes, &FullParentPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
1.1.1.13  root      392: 
                    393:                        ntStatus = ZwCreateFile (&hParentDeviceFile,
                    394:                                GENERIC_READ | SYNCHRONIZE,
                    395:                                &oaParentFileAttributes,
                    396:                                &IoStatusBlock,
                    397:                                NULL,
                    398:                                FILE_ATTRIBUTE_NORMAL |
                    399:                                FILE_ATTRIBUTE_SYSTEM,
                    400:                                FILE_SHARE_READ | FILE_SHARE_WRITE,
                    401:                                FILE_OPEN,
                    402:                                FILE_RANDOM_ACCESS |
                    403:                                FILE_WRITE_THROUGH |
1.1.1.21  root      404:                                FILE_NO_INTERMEDIATE_BUFFERING |
1.1.1.13  root      405:                                FILE_SYNCHRONOUS_IO_NONALERT,
                    406:                                NULL,
                    407:                                0);
                    408: 
                    409:                        if (!NT_SUCCESS (ntStatus))
                    410:                        {
                    411:                                if (hParentDeviceFile != NULL)
                    412:                                        ZwClose (hParentDeviceFile);
                    413: 
                    414:                                Dump ("Cannot open %ls\n", parentDrivePath);
                    415: 
                    416:                                goto error;
                    417:                        }
                    418: 
1.1.1.14  root      419:                        parentKeyDataOffset.QuadPart = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET;
1.1.1.13  root      420: 
                    421:                        ntStatus = ZwReadFile (hParentDeviceFile,
                    422:                                NULL,
                    423:                                NULL,
                    424:                                NULL,
                    425:                                &IoStatusBlock,
                    426:                                readBuffer,
1.1.1.21  root      427:                                max (TC_VOLUME_HEADER_EFFECTIVE_SIZE, Extension->HostBytesPerSector),
1.1.1.13  root      428:                                &parentKeyDataOffset,
                    429:                                NULL);
                    430: 
                    431:                        if (hParentDeviceFile != NULL)
                    432:                                ZwClose (hParentDeviceFile);
                    433:                }
1.1.1.6   root      434: 
1.1.1.15  root      435:                if (!NT_SUCCESS (ntStatus) && ntStatus != STATUS_END_OF_FILE)
1.1       root      436:                {
1.1.1.6   root      437:                        Dump ("Read failed: NTSTATUS 0x%08x\n", ntStatus);
1.1.1.14  root      438:                        goto error;
1.1       root      439:                }
                    440: 
1.1.1.21  root      441:                if (ntStatus == STATUS_END_OF_FILE || IoStatusBlock.Information < TC_VOLUME_HEADER_EFFECTIVE_SIZE)
1.1.1.6   root      442:                {
1.1.1.14  root      443:                        Dump ("Read didn't read enough data\n");
1.1.1.15  root      444: 
                    445:                        // If FSCTL_ALLOW_EXTENDED_DASD_IO failed and there is a live filesystem on the partition, then the
                    446:                        // filesystem driver may report EOF when we are reading hidden sectors (when the filesystem is 
                    447:                        // shorter than the partition). This can happen for example after the user quick-formats a dismounted
                    448:                        // partition-hosted TrueCrypt volume and then tries to mount the volume using the embedded backup header.
                    449:                        memset (readBuffer, 0, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
1.1.1.6   root      450:                }
1.1       root      451: 
1.1.1.6   root      452:                /* Attempt to recognize the volume (decrypt the header) */
1.1       root      453: 
1.1.1.15  root      454:                ReadVolumeHeaderRecoveryMode = mount->RecoveryMode;
                    455: 
1.1.1.14  root      456:                if ((volumeType == TC_VOLUME_TYPE_HIDDEN || volumeType == TC_VOLUME_TYPE_HIDDEN_LEGACY) && mount->bProtectHiddenVolume)
1.1.1.6   root      457:                {
1.1.1.15  root      458:                        mount->nReturnCode = ReadVolumeHeaderWCache (
1.1.1.14  root      459:                                FALSE,
1.1.1.6   root      460:                                mount->bCache,
                    461:                                readBuffer,
                    462:                                &mount->ProtectedHidVolPassword,
                    463:                                &tmpCryptoInfo);
                    464:                }
                    465:                else
                    466:                {
1.1.1.15  root      467:                        mount->nReturnCode = ReadVolumeHeaderWCache (
1.1.1.14  root      468:                                mount->bPartitionInInactiveSysEncScope && volumeType == TC_VOLUME_TYPE_NORMAL,
1.1.1.6   root      469:                                mount->bCache,
                    470:                                readBuffer,
                    471:                                &mount->VolumePassword,
                    472:                                &Extension->cryptoInfo);
                    473:                }
1.1.1.4   root      474: 
1.1.1.15  root      475:                ReadVolumeHeaderRecoveryMode = FALSE;
                    476: 
1.1.1.6   root      477:                if (mount->nReturnCode == 0 || mount->nReturnCode == ERR_CIPHER_INIT_WEAK_KEY)
                    478:                {
                    479:                        /* Volume header successfully decrypted */
1.1       root      480: 
1.1.1.14  root      481:                        Dump ("Volume header decrypted\n");
                    482:                        Dump ("Required program version = %x\n", (int) Extension->cryptoInfo->RequiredProgramVersion);
                    483:                        Dump ("Legacy volume = %d\n", (int) Extension->cryptoInfo->LegacyVolume);
                    484: 
                    485:                        if (IsHiddenSystemRunning() && !Extension->cryptoInfo->hiddenVolume)
                    486:                        {
                    487:                                Extension->bReadOnly = mount->bMountReadOnly = TRUE;
                    488:                                HiddenSysLeakProtectionCount++;
                    489:                        }
                    490: 
1.1.1.6   root      491:                        Extension->cryptoInfo->bProtectHiddenVolume = FALSE;
                    492:                        Extension->cryptoInfo->bHiddenVolProtectionAction = FALSE;
1.1       root      493: 
1.1.1.13  root      494:                        Extension->cryptoInfo->bPartitionInInactiveSysEncScope = mount->bPartitionInInactiveSysEncScope;
                    495: 
1.1.1.15  root      496:                        if (volumeType == TC_VOLUME_TYPE_NORMAL)
1.1.1.13  root      497:                        {
1.1.1.15  root      498:                                if (mount->bPartitionInInactiveSysEncScope)
1.1.1.13  root      499:                                {
1.1.1.15  root      500:                                        if (Extension->cryptoInfo->EncryptedAreaStart.Value > (unsigned __int64) partitionStartingOffset
                    501:                                                || Extension->cryptoInfo->EncryptedAreaStart.Value + Extension->cryptoInfo->VolumeSize.Value <= (unsigned __int64) partitionStartingOffset)
                    502:                                        {
                    503:                                                // The partition is not within the key scope of system encryption
                    504:                                                mount->nReturnCode = ERR_PASSWORD_WRONG;
                    505:                                                ntStatus = STATUS_SUCCESS;
                    506:                                                goto error;
                    507:                                        }
                    508: 
                    509:                                        if (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value)
                    510:                                        {
                    511:                                                // Partial encryption is not supported for volumes mounted as regular
                    512:                                                mount->nReturnCode = ERR_ENCRYPTION_NOT_COMPLETED;
                    513:                                                ntStatus = STATUS_SUCCESS;
                    514:                                                goto error;
                    515:                                        }
                    516:                                }
                    517:                                else if (Extension->cryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC)
                    518:                                {
                    519:                                        if (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value)
                    520:                                        {
                    521:                                                // Non-system in-place encryption process has not been completed on this volume
                    522:                                                mount->nReturnCode = ERR_NONSYS_INPLACE_ENC_INCOMPLETE;
                    523:                                                ntStatus = STATUS_SUCCESS;
                    524:                                                goto error;
                    525:                                        }
1.1.1.13  root      526:                                }
                    527:                        }
                    528: 
1.1.1.14  root      529:                        Extension->cryptoInfo->FirstDataUnitNo.Value = 0;
1.1       root      530: 
1.1.1.14  root      531:                        if (Extension->cryptoInfo->hiddenVolume && IsHiddenSystemRunning())
                    532:                        {
                    533:                                // Prevent mount of a hidden system partition if the system hosted on it is currently running
                    534:                                if (memcmp (Extension->cryptoInfo->master_keydata, GetSystemDriveCryptoInfo()->master_keydata, EAGetKeySize (Extension->cryptoInfo->ea)) == 0)
1.1.1.13  root      535:                                {
1.1.1.14  root      536:                                        mount->nReturnCode = ERR_VOL_ALREADY_MOUNTED;
                    537:                                        ntStatus = STATUS_SUCCESS;
                    538:                                        goto error;
1.1.1.13  root      539:                                }
1.1.1.14  root      540:                        }
                    541: 
                    542:                        switch (volumeType)
                    543:                        {
                    544:                        case TC_VOLUME_TYPE_NORMAL:
1.1.1.13  root      545: 
1.1.1.6   root      546:                                Extension->cryptoInfo->hiddenVolume = FALSE;
1.1.1.13  root      547: 
1.1.1.14  root      548:                                if (mount->bPartitionInInactiveSysEncScope)
                    549:                                {
                    550:                                        Extension->cryptoInfo->volDataAreaOffset = 0;
                    551:                                        Extension->DiskLength = lDiskLength.QuadPart;
                    552:                                        Extension->cryptoInfo->FirstDataUnitNo.Value = partitionStartingOffset / ENCRYPTION_DATA_UNIT_SIZE;
                    553:                                }
                    554:                                else if (Extension->cryptoInfo->LegacyVolume)
                    555:                                {
                    556:                                        Extension->cryptoInfo->volDataAreaOffset = TC_VOLUME_HEADER_SIZE_LEGACY;
                    557:                                        Extension->DiskLength = lDiskLength.QuadPart - TC_VOLUME_HEADER_SIZE_LEGACY;
                    558:                                }
                    559:                                else
                    560:                                {
                    561:                                        Extension->cryptoInfo->volDataAreaOffset = Extension->cryptoInfo->EncryptedAreaStart.Value;
                    562:                                        Extension->DiskLength = Extension->cryptoInfo->VolumeSize.Value;
                    563:                                }
1.1.1.6   root      564: 
                    565:                                break;
                    566: 
1.1.1.14  root      567:                        case TC_VOLUME_TYPE_HIDDEN:
                    568:                        case TC_VOLUME_TYPE_HIDDEN_LEGACY:
1.1.1.6   root      569: 
                    570:                                cryptoInfoPtr = mount->bProtectHiddenVolume ? tmpCryptoInfo : Extension->cryptoInfo;
                    571: 
1.1.1.14  root      572:                                if (volumeType == TC_VOLUME_TYPE_HIDDEN_LEGACY)
                    573:                                        Extension->cryptoInfo->hiddenVolumeOffset = lDiskLength.QuadPart - cryptoInfoPtr->hiddenVolumeSize - TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
                    574:                                else
                    575:                                        Extension->cryptoInfo->hiddenVolumeOffset = cryptoInfoPtr->EncryptedAreaStart.Value;
1.1.1.6   root      576: 
1.1.1.14  root      577:                                Dump ("Hidden volume offset = %I64d\n", Extension->cryptoInfo->hiddenVolumeOffset);
                    578:                                Dump ("Hidden volume size = %I64d\n", cryptoInfoPtr->hiddenVolumeSize);
                    579:                                Dump ("Hidden volume end = %I64d\n", Extension->cryptoInfo->hiddenVolumeOffset + cryptoInfoPtr->hiddenVolumeSize - 1);
1.1.1.6   root      580: 
                    581:                                // Validate the offset
1.1.1.12  root      582:                                if (Extension->cryptoInfo->hiddenVolumeOffset % ENCRYPTION_DATA_UNIT_SIZE != 0)
1.1.1.6   root      583:                                {
                    584:                                        mount->nReturnCode = ERR_VOL_SIZE_WRONG;
                    585:                                        ntStatus = STATUS_SUCCESS;
                    586:                                        goto error;
                    587:                                }
                    588: 
                    589:                                // If we are supposed to actually mount the hidden volume (not just to protect it)
                    590:                                if (!mount->bProtectHiddenVolume)       
                    591:                                {
                    592:                                        Extension->DiskLength = cryptoInfoPtr->hiddenVolumeSize;
                    593:                                        Extension->cryptoInfo->hiddenVolume = TRUE;
1.1.1.13  root      594:                                        Extension->cryptoInfo->volDataAreaOffset = Extension->cryptoInfo->hiddenVolumeOffset;
1.1.1.6   root      595:                                }
                    596:                                else
                    597:                                {
                    598:                                        // Hidden volume protection
                    599:                                        Extension->cryptoInfo->hiddenVolume = FALSE;
                    600:                                        Extension->cryptoInfo->bProtectHiddenVolume = TRUE;
1.1.1.14  root      601:                                        
                    602:                                        Extension->cryptoInfo->hiddenVolumeProtectedSize = tmpCryptoInfo->hiddenVolumeSize;
1.1.1.13  root      603: 
1.1.1.14  root      604:                                        if (volumeType == TC_VOLUME_TYPE_HIDDEN_LEGACY)
                    605:                                                Extension->cryptoInfo->hiddenVolumeProtectedSize += TC_VOLUME_HEADER_SIZE_LEGACY;
1.1.1.13  root      606: 
1.1.1.14  root      607:                                        Dump ("Hidden volume protection active: %I64d-%I64d (%I64d)\n", Extension->cryptoInfo->hiddenVolumeOffset, Extension->cryptoInfo->hiddenVolumeProtectedSize + Extension->cryptoInfo->hiddenVolumeOffset - 1, Extension->cryptoInfo->hiddenVolumeProtectedSize);
1.1.1.6   root      608:                                }
1.1.1.4   root      609: 
1.1.1.6   root      610:                                break;
                    611:                        }
1.1.1.4   root      612: 
1.1.1.14  root      613:                        Dump ("Volume data offset = %I64d\n", Extension->cryptoInfo->volDataAreaOffset);
                    614:                        Dump ("Volume data size = %I64d\n", Extension->DiskLength);
                    615:                        Dump ("Volume data end = %I64d\n", Extension->cryptoInfo->volDataAreaOffset + Extension->DiskLength - 1);
                    616: 
1.1.1.15  root      617:                        if (Extension->DiskLength == 0)
                    618:                        {
                    619:                                Dump ("Incorrect volume size\n");
                    620:                                continue;
                    621:                        }
                    622: 
1.1.1.6   root      623:                        // If this is a hidden volume, make sure we are supposed to actually
                    624:                        // mount it (i.e. not just to protect it)
1.1.1.14  root      625:                        if (volumeType == TC_VOLUME_TYPE_NORMAL || !mount->bProtectHiddenVolume)        
1.1.1.4   root      626:                        {
1.1.1.21  root      627:                                // Validate sector size
                    628:                                if (bRawDevice && Extension->cryptoInfo->SectorSize != Extension->HostBytesPerSector)
                    629:                                {
                    630:                                        mount->nReturnCode = ERR_PARAMETER_INCORRECT;
                    631:                                        ntStatus = STATUS_SUCCESS;
                    632:                                        goto error;
                    633:                                }
                    634: 
1.1.1.6   root      635:                                // Calculate virtual volume geometry
                    636:                                Extension->TracksPerCylinder = 1;
                    637:                                Extension->SectorsPerTrack = 1;
1.1.1.21  root      638:                                Extension->BytesPerSector = Extension->cryptoInfo->SectorSize;
                    639:                                Extension->NumberOfCylinders = Extension->DiskLength / Extension->BytesPerSector;
1.1.1.6   root      640:                                Extension->PartitionType = 0;
                    641: 
                    642:                                Extension->bRawDevice = bRawDevice;
1.1.1.7   root      643:                                
1.1.1.8   root      644:                                memset (Extension->wszVolume, 0, sizeof (Extension->wszVolume));
1.1.1.7   root      645:                                if (wcsstr (pwszMountVolume, WIDE ("\\??\\UNC\\")) == pwszMountVolume)
                    646:                                {
                    647:                                        /* UNC path */
                    648:                                        _snwprintf (Extension->wszVolume,
                    649:                                                sizeof (Extension->wszVolume) / sizeof (WCHAR) - 1,
                    650:                                                WIDE ("\\??\\\\%s"),
                    651:                                                pwszMountVolume + 7);
                    652:                                }
1.1.1.6   root      653:                                else
                    654:                                {
1.1.1.7   root      655:                                        wcsncpy (Extension->wszVolume, pwszMountVolume, sizeof (Extension->wszVolume) / sizeof (WCHAR) - 1);
1.1.1.6   root      656:                                }
1.1.1.4   root      657:                        }
                    658: 
1.1.1.6   root      659:                        // If we are to protect a hidden volume we cannot exit yet, for we must also
                    660:                        // decrypt the hidden volume header.
1.1.1.14  root      661:                        if (!(volumeType == TC_VOLUME_TYPE_NORMAL && mount->bProtectHiddenVolume))
1.1.1.4   root      662:                        {
1.1.1.6   root      663:                                TCfree (readBuffer);
1.1.1.4   root      664: 
1.1.1.6   root      665:                                if (tmpCryptoInfo != NULL)
1.1.1.14  root      666:                                {
1.1.1.6   root      667:                                        crypto_close (tmpCryptoInfo);
1.1.1.14  root      668:                                        tmpCryptoInfo = NULL;
                    669:                                }
1.1.1.6   root      670:                                
                    671:                                return STATUS_SUCCESS;
                    672:                        }
1.1.1.4   root      673:                }
1.1.1.14  root      674:                else if ((mount->bProtectHiddenVolume && volumeType == TC_VOLUME_TYPE_NORMAL)
1.1.1.6   root      675:                          || mount->nReturnCode != ERR_PASSWORD_WRONG)
1.1.1.4   root      676:                {
1.1.1.6   root      677:                         /* If we are not supposed to protect a hidden volume, the only error that is
                    678:                                tolerated is ERR_PASSWORD_WRONG (to allow mounting a possible hidden volume). 
1.1.1.4   root      679: 
1.1.1.6   root      680:                                If we _are_ supposed to protect a hidden volume, we do not tolerate any error
                    681:                                (both volume headers must be successfully decrypted). */
1.1       root      682: 
1.1.1.6   root      683:                        break;
1.1       root      684:                }
                    685:        }
                    686: 
                    687:        /* Failed due to some non-OS reason so we drop through and return NT
                    688:           SUCCESS then nReturnCode is checked later in user-mode */
                    689: 
                    690:        if (mount->nReturnCode == ERR_OUTOFMEMORY)
                    691:                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                    692:        else
                    693:                ntStatus = STATUS_SUCCESS;
                    694: 
1.1.1.4   root      695: error:
1.1.1.14  root      696:        if (mount->nReturnCode == ERR_SUCCESS)
                    697:                mount->nReturnCode = ERR_PASSWORD_WRONG;
                    698: 
                    699:        if (tmpCryptoInfo != NULL)
                    700:        {
                    701:                crypto_close (tmpCryptoInfo);
                    702:                tmpCryptoInfo = NULL;
                    703:        }
                    704: 
                    705:        if (Extension->cryptoInfo)
                    706:        {
                    707:                crypto_close (Extension->cryptoInfo);
                    708:                Extension->cryptoInfo = NULL;
                    709:        }
                    710: 
1.1.1.6   root      711:        if (Extension->bTimeStampValid)
1.1.1.4   root      712:        {
                    713:                RestoreTimeStamp (Extension);
                    714:        }
1.1       root      715: 
                    716:        /* Close the hDeviceFile */
                    717:        if (Extension->hDeviceFile != NULL)
                    718:                ZwClose (Extension->hDeviceFile);
                    719: 
                    720:        /* The cryptoInfo pointer is deallocated if the readheader routines
                    721:           fail so there is no need to deallocate here  */
                    722: 
                    723:        /* Dereference the user-mode file object */
                    724:        if (Extension->pfoDeviceFile != NULL)
                    725:                ObDereferenceObject (Extension->pfoDeviceFile);
                    726: 
1.1.1.4   root      727:        /* Free the tmp IO buffers */
1.1       root      728:        if (readBuffer != NULL)
                    729:                TCfree (readBuffer);
                    730: 
                    731:        return ntStatus;
                    732: }
                    733: 
1.1.1.14  root      734: void TCCloseVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1.1       root      735: {
                    736:        if (DeviceObject);      /* Remove compiler warning */
                    737: 
                    738:        if (Extension->hDeviceFile != NULL)
1.1.1.4   root      739:        {
1.1.1.6   root      740:                if (Extension->bRawDevice == FALSE
                    741:                        && Extension->bTimeStampValid)
1.1.1.4   root      742:                {
                    743:                        RestoreTimeStamp (Extension);
                    744:                }
1.1.1.6   root      745:                ZwClose (Extension->hDeviceFile);
1.1.1.4   root      746:        }
1.1       root      747:        ObDereferenceObject (Extension->pfoDeviceFile);
                    748:        crypto_close (Extension->cryptoInfo);
                    749: }
                    750: 
                    751: 
1.1.1.14  root      752: NTSTATUS TCSendHostDeviceIoControlRequest (PDEVICE_OBJECT DeviceObject,
1.1       root      753:                               PEXTENSION Extension,
                    754:                               ULONG IoControlCode,
1.1.1.15  root      755:                               void *OutputBuffer,
                    756:                               ULONG OutputBufferSize)
1.1       root      757: {
                    758:        IO_STATUS_BLOCK IoStatusBlock;
                    759:        NTSTATUS ntStatus;
                    760:        PIRP Irp;
                    761: 
                    762:        if (DeviceObject);      /* Remove compiler warning */
                    763: 
                    764:        KeClearEvent (&Extension->keVolumeEvent);
                    765: 
                    766:        Irp = IoBuildDeviceIoControlRequest (IoControlCode,
                    767:                                             Extension->pFsdDevice,
                    768:                                             NULL, 0,
                    769:                                             OutputBuffer, OutputBufferSize,
                    770:                                             FALSE,
                    771:                                             &Extension->keVolumeEvent,
                    772:                                             &IoStatusBlock);
                    773: 
                    774:        if (Irp == NULL)
                    775:        {
                    776:                Dump ("IRP allocation failed\n");
                    777:                return STATUS_INSUFFICIENT_RESOURCES;
                    778:        }
                    779: 
1.1.1.5   root      780:        // Disk device may be used by filesystem driver which needs file object
                    781:        IoGetNextIrpStackLocation (Irp) -> FileObject = Extension->pfoDeviceFile;
                    782: 
1.1       root      783:        ntStatus = IoCallDriver (Extension->pFsdDevice, Irp);
                    784:        if (ntStatus == STATUS_PENDING)
                    785:        {
1.1.1.12  root      786:                KeWaitForSingleObject (&Extension->keVolumeEvent, Executive, KernelMode, FALSE, NULL);
1.1       root      787:                ntStatus = IoStatusBlock.Status;
                    788:        }
                    789: 
                    790:        return ntStatus;
                    791: }
                    792: 
1.1.1.14  root      793: NTSTATUS COMPLETE_IRP (PDEVICE_OBJECT DeviceObject,
1.1       root      794:              PIRP Irp,
                    795:              NTSTATUS IrpStatus,
1.1.1.4   root      796:              ULONG_PTR IrpInformation)
1.1       root      797: {
                    798:        Irp->IoStatus.Status = IrpStatus;
                    799:        Irp->IoStatus.Information = IrpInformation;
                    800: 
                    801:        if (DeviceObject);      /* Remove compiler warning */
                    802: 
1.1.1.10  root      803: #if EXTRA_INFO
                    804:        if (!NT_SUCCESS (IrpStatus))
                    805:        {
                    806:                PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
                    807:                Dump ("COMPLETE_IRP FAILING IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction),
                    808:                      (ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus);
                    809:        }
                    810:        else
                    811:        {
                    812:                PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
                    813:                Dump ("COMPLETE_IRP SUCCESS IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction),
                    814:                      (ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus);
                    815:        }
1.1       root      816: #endif
                    817:        IoCompleteRequest (Irp, IO_NO_INCREMENT);
                    818:        return IrpStatus;
                    819: }
1.1.1.4   root      820: 
1.1.1.20  root      821: 
1.1.1.4   root      822: static void RestoreTimeStamp (PEXTENSION Extension)
                    823: {
                    824:        NTSTATUS ntStatus;
                    825:        FILE_BASIC_INFORMATION FileBasicInfo;
                    826:        IO_STATUS_BLOCK IoStatusBlock;
                    827: 
1.1.1.6   root      828:        if (Extension->hDeviceFile != NULL 
                    829:                && Extension->bRawDevice == FALSE 
                    830:                && Extension->bReadOnly == FALSE
                    831:                && Extension->bTimeStampValid)
1.1.1.4   root      832:        {
                    833:                ntStatus = ZwQueryInformationFile (Extension->hDeviceFile,
                    834:                        &IoStatusBlock,
                    835:                        &FileBasicInfo,
                    836:                        sizeof (FileBasicInfo),
                    837:                        FileBasicInformation); 
                    838: 
                    839:                if (!NT_SUCCESS (ntStatus))
                    840:                {
                    841:                        Dump ("ZwQueryInformationFile failed in RestoreTimeStamp: NTSTATUS 0x%08x\n",
                    842:                                ntStatus);
                    843:                }
                    844:                else
                    845:                {
                    846:                        FileBasicInfo.CreationTime = Extension->fileCreationTime;
                    847:                        FileBasicInfo.LastAccessTime = Extension->fileLastAccessTime;
                    848:                        FileBasicInfo.LastWriteTime = Extension->fileLastWriteTime;
                    849:                        FileBasicInfo.ChangeTime = Extension->fileLastChangeTime;
                    850: 
                    851:                        ntStatus = ZwSetInformationFile(
                    852:                                Extension->hDeviceFile,
                    853:                                &IoStatusBlock,
                    854:                                &FileBasicInfo,
                    855:                                sizeof (FileBasicInfo),
                    856:                                FileBasicInformation); 
                    857: 
                    858:                        if (!NT_SUCCESS (ntStatus))
                    859:                                Dump ("ZwSetInformationFile failed in RestoreTimeStamp: NTSTATUS 0x%08x\n",ntStatus);
                    860:                }
                    861:        }
                    862: }

unix.superglobalmegacorp.com

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