Annotation of truecrypt/driver/ntdriver.c, revision 1.1.1.16

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
                      6:  the original source code (contained in this file) and all other portions of
                      7:  this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
1.1.1.15  root        8:  by the TrueCrypt License 2.5 the full text of which is contained in the
1.1.1.12  root        9:  file License.txt included in TrueCrypt binary and source code distribution
1.1.1.10  root       10:  packages. */
1.1       root       11: 
                     12: #include "TCdefs.h"
1.1.1.12  root       13: #include <ntddk.h>
1.1.1.6   root       14: #include "Crypto.h"
                     15: #include "Fat.h"
                     16: #include "Tests.h"
                     17: 
                     18: #include "Apidrvr.h"
1.1.1.15  root       19: #include "Boot/Windows/BootDefs.h"
1.1.1.12  root       20: #include "EncryptedIoQueue.h"
1.1.1.15  root       21: #include "EncryptionThreadPool.h"
1.1.1.6   root       22: #include "Ntdriver.h"
                     23: #include "Ntvol.h"
1.1.1.12  root       24: #include "DriveFilter.h"
1.1.1.6   root       25: #include "Cache.h"
1.1.1.15  root       26: #include "Volumes.h"
                     27: #include "VolumeFilter.h"
1.1       root       28: 
                     29: #include <tchar.h>
                     30: #include <initguid.h>
                     31: #include <mountmgr.h>
                     32: #include <mountdev.h>
                     33: #include <ntddvol.h>
                     34: 
                     35: /* Init section, which is thrown away as soon as DriverEntry returns */
                     36: #pragma alloc_text(INIT,DriverEntry)
                     37: #pragma alloc_text(INIT,TCCreateRootDeviceObject)
                     38: 
1.1.1.14  root       39: PDRIVER_OBJECT TCDriverObject;
1.1.1.6   root       40: KMUTEX driverMutex;                    /* Sync mutex for the entire driver */
1.1.1.12  root       41: BOOL DriverShuttingDown = FALSE;
1.1.1.6   root       42: BOOL SelfTestsPassed;
                     43: int LastUniqueVolumeId;
1.1.1.10  root       44: ULONG OsMajorVersion;
1.1.1.14  root       45: ULONG OsMinorVersion;
1.1.1.11  root       46: BOOL ReferencedDeviceDeleted = FALSE;
1.1.1.14  root       47: BOOL TravelerMode = FALSE;
1.1.1.15  root       48: BOOL VolumeClassFilterRegistered = FALSE;
1.1       root       49: 
1.1.1.12  root       50: 
                     51: NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
1.1       root       52: {
1.1.1.15  root       53:        PKEY_VALUE_PARTIAL_INFORMATION startKeyValue;
1.1.1.12  root       54:        int i;
                     55: 
1.1.1.14  root       56:        TCDriverObject = DriverObject;
1.1.1.15  root       57:        KeInitializeMutex (&driverMutex, 0);
                     58: 
                     59:        EncryptionThreadPoolStart();
1.1.1.12  root       60:        SelfTestsPassed = AutoTestAlgorithms ();
1.1.1.14  root       61:        PsGetVersion (&OsMajorVersion, &OsMinorVersion, NULL, NULL);
1.1.1.12  root       62: 
1.1.1.15  root       63:        // Enable device class filters and load boot arguments if the driver is set to start at system boot
1.1.1.12  root       64:                
1.1.1.15  root       65:        if (NT_SUCCESS (TCReadRegistryKey (RegistryPath, L"Start", &startKeyValue)))
                     66:        {
                     67:                if (startKeyValue->Type == REG_DWORD && *((uint32 *) startKeyValue->Data) == SERVICE_BOOT_START)
1.1.1.12  root       68:                {
1.1.1.15  root       69:                        if (!SelfTestsPassed)
                     70:                                TC_BUG_CHECK (STATUS_INVALID_PARAMETER);
1.1.1.12  root       71: 
1.1.1.15  root       72:                        LoadBootArguments();
                     73:                        VolumeClassFilterRegistered = IsVolumeClassFilterRegistered();
1.1.1.12  root       74: 
1.1.1.15  root       75:                        DriverObject->DriverExtension->AddDevice = DriverAddDevice;
1.1.1.12  root       76:                }
                     77: 
1.1.1.15  root       78:                TCfree (startKeyValue);
1.1.1.12  root       79:        }
                     80: 
                     81:        for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
                     82:        {
                     83:                DriverObject->MajorFunction[i] = TCDispatchQueueIRP;
                     84:        }
1.1       root       85: 
                     86:        DriverObject->DriverUnload = TCUnloadDriver;
                     87:        return TCCreateRootDeviceObject (DriverObject);
                     88: }
                     89: 
1.1.1.12  root       90: 
1.1.1.15  root       91: NTSTATUS DriverAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo)
                     92: {
                     93:        BOOL volumeDevice = FALSE;
                     94:        Dump ("DriverAddDevice type=%x\n", pdo->DeviceType);
                     95: 
                     96:        if (!VolumeClassFilterRegistered && BootArgsValid && BootArgs.HiddenSystemPartitionStart == 0)
                     97:                return DriveFilterAddDevice (driverObject, pdo);
                     98: 
                     99:        if (pdo->Flags & DO_DEVICE_HAS_NAME)
                    100:        {
                    101:                char nameInfoBuffer[128];
                    102:                POBJECT_NAME_INFORMATION nameInfo = (POBJECT_NAME_INFORMATION) nameInfoBuffer;
                    103:                ULONG nameInfoSize;
                    104: 
                    105:                if (NT_SUCCESS (ObQueryNameString (pdo, nameInfo, sizeof (nameInfoBuffer), &nameInfoSize)))
                    106:                {
                    107:                        Dump ("Device name = %ws\n", nameInfo->Name.Buffer);
                    108: 
                    109:                        if (nameInfo->Name.Length >= 22 * sizeof (wchar_t)
                    110:                                && memcmp (nameInfo->Name.Buffer, L"\\Device\\HarddiskVolume", 22 * sizeof (wchar_t)) == 0)
                    111:                        {
                    112:                                volumeDevice = TRUE;
                    113:                        }
                    114: 
                    115:                        if (nameInfo->Name.Length >= 14 * sizeof (wchar_t)
                    116:                                && memcmp (nameInfo->Name.Buffer, L"\\Device\\Floppy", 14 * sizeof (wchar_t)) == 0)
                    117:                        {
                    118:                                volumeDevice = TRUE;
                    119:                        }
                    120:                }
                    121:        }
                    122: 
1.1.1.16! root      123:        if (volumeDevice)
        !           124:                return VolumeFilterAddDevice (driverObject, pdo);
1.1.1.15  root      125: 
1.1.1.16! root      126:        return DriveFilterAddDevice (driverObject, pdo);
1.1.1.15  root      127: }
                    128: 
                    129: 
1.1       root      130: // Dumps a memory region to debug output
1.1.1.12  root      131: void DumpMemory (void *mem, int size)
1.1       root      132: {
                    133:        unsigned char str[20];
                    134:        unsigned char *m = mem;
                    135:        int i,j;
                    136: 
1.1.1.12  root      137:        for (j = 0; j < size / 8; j++)
1.1       root      138:        {
                    139:                memset (str,0,sizeof str);
1.1.1.12  root      140:                for (i = 0; i < 8; i++) 
1.1       root      141:                {
1.1.1.12  root      142:                        if (m[i] > ' ' && m[i] <= '~')
1.1       root      143:                                str[i]=m[i];
                    144:                        else
                    145:                                str[i]='.';
                    146:                }
                    147: 
1.1.1.12  root      148:                Dump ("0x%08p  %02x %02x %02x %02x %02x %02x %02x %02x  %s\n",
1.1       root      149:                        m, m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], str);
                    150: 
                    151:                m+=8;
                    152:        }
                    153: }
1.1.1.12  root      154: 
1.1       root      155: 
                    156: /* TCDispatchQueueIRP queues any IRP's so that they can be processed later
                    157:    by the thread -- or in some cases handles them immediately! */
                    158: NTSTATUS
                    159: TCDispatchQueueIRP (PDEVICE_OBJECT DeviceObject, PIRP Irp)
                    160: {
                    161:        PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
                    162:        PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
                    163:        NTSTATUS ntStatus;
                    164: 
                    165: #ifdef _DEBUG
1.1.1.15  root      166:        if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL && Extension->IsVolumeDevice)
1.1.1.12  root      167:        {
                    168:                switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
                    169:                {
                    170:                case TC_IOCTL_GET_MOUNTED_VOLUMES:
                    171:                case TC_IOCTL_GET_PASSWORD_CACHE_STATUS:
1.1.1.14  root      172:                case TC_IOCTL_GET_TRAVELER_MODE_STATUS:
                    173:                case TC_IOCTL_SET_TRAVELER_MODE_STATUS:
1.1.1.12  root      174:                case TC_IOCTL_OPEN_TEST:
                    175:                case TC_IOCTL_GET_RESOLVED_SYMLINK:
                    176:                case TC_IOCTL_GET_DRIVE_PARTITION_INFO:
                    177:                case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
                    178:                case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
1.1.1.15  root      179:                case TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING:
1.1.1.12  root      180:                        break;
                    181: 
                    182:                default:
1.1.1.15  root      183:                        Dump ("%ls (0x%x %d)\n",
1.1.1.12  root      184:                                TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode),
                    185:                                (int) (irpSp->Parameters.DeviceIoControl.IoControlCode >> 16),
                    186:                                (int) ((irpSp->Parameters.DeviceIoControl.IoControlCode & 0x1FFF) >> 2));
                    187:                }
1.1.1.10  root      188:        }
1.1       root      189: #endif
                    190: 
1.1.1.15  root      191:        if (!Extension->bRootDevice)
1.1       root      192:        {
1.1.1.15  root      193:                // Drive filter IRP
                    194:                if (Extension->IsDriveFilterDevice)
                    195:                        return DriveFilterDispatchIrp (DeviceObject, Irp);
                    196: 
                    197:                // Volume filter IRP
                    198:                if (Extension->IsVolumeFilterDevice)
                    199:                        return VolumeFilterDispatchIrp (DeviceObject, Irp);
1.1       root      200:        }
                    201: 
                    202:        switch (irpSp->MajorFunction)
                    203:        {
                    204:        case IRP_MJ_CLOSE:
                    205:        case IRP_MJ_CREATE:
                    206:        case IRP_MJ_CLEANUP:
                    207:                return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
                    208: 
                    209:        case IRP_MJ_SHUTDOWN:
1.1.1.6   root      210:                if (Extension->bRootDevice)
1.1.1.12  root      211:                {
                    212:                        DriverShuttingDown = TRUE;
                    213: 
                    214:                        if (IsBootEncryptionSetupInProgress())
                    215:                                AbortBootEncryptionSetup();
                    216: 
1.1.1.15  root      217:                        UnmountAllDevices (NULL, DeviceObject, TRUE);
1.1.1.12  root      218: 
1.1.1.15  root      219:                        // Boot drive will be dismounted when IRP_MJ_POWER is received after IRP_MJ_SHUTDOWN
1.1.1.12  root      220:                }
1.1.1.4   root      221: 
                    222:                return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
                    223: 
1.1       root      224:        case IRP_MJ_FLUSH_BUFFERS:
                    225:        case IRP_MJ_READ:
                    226:        case IRP_MJ_WRITE:
                    227:        case IRP_MJ_DEVICE_CONTROL:
                    228: 
1.1.1.15  root      229:                if (Extension->bRootDevice)
1.1       root      230:                {
1.1.1.12  root      231:                        if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
                    232:                                return ProcessMainDeviceControlIrp (DeviceObject, Extension, Irp);
1.1.1.15  root      233:                        break;
1.1       root      234:                }
                    235: 
1.1.1.15  root      236:                if (Extension->bShuttingDown)
                    237:                {
                    238:                        Dump ("Device %d shutting down: STATUS_DEVICE_NOT_READY\n", Extension->nDosDriveNo);
                    239:                        return TCCompleteDiskIrp (Irp, STATUS_DEVICE_NOT_READY, 0);
                    240:                }
1.1       root      241: 
1.1.1.15  root      242:                if (Extension->bRemovable
                    243:                        && (DeviceObject->Flags & DO_VERIFY_VOLUME)
                    244:                        && !(irpSp->Flags & SL_OVERRIDE_VERIFY_VOLUME)
                    245:                        && irpSp->MajorFunction != IRP_MJ_FLUSH_BUFFERS)
                    246:                {
                    247:                        Dump ("Removable device %d has DO_VERIFY_VOLUME flag: STATUS_DEVICE_NOT_READY\n", Extension->nDosDriveNo);
                    248:                        return TCCompleteDiskIrp (Irp, STATUS_DEVICE_NOT_READY, 0);
                    249:                }
1.1       root      250: 
1.1.1.15  root      251:                switch (irpSp->MajorFunction)
                    252:                {
                    253:                case IRP_MJ_READ:
                    254:                case IRP_MJ_WRITE:
                    255:                        ntStatus = EncryptedIoQueueAddIrp (&Extension->Queue, Irp);
                    256: 
                    257:                        if (ntStatus != STATUS_PENDING)
                    258:                                TCCompleteDiskIrp (Irp, ntStatus, 0);
                    259: 
                    260:                        return ntStatus;
                    261: 
                    262:                case IRP_MJ_DEVICE_CONTROL:
                    263:                        IoMarkIrpPending (Irp);
                    264:                        
                    265:                        ExInterlockedInsertTailList (&Extension->ListEntry, &Irp->Tail.Overlay.ListEntry, &Extension->ListSpinLock);
                    266:                        KeReleaseSemaphore (&Extension->RequestSemaphore, IO_DISK_INCREMENT, 1, FALSE);
                    267:                        
                    268:                        return STATUS_PENDING;
                    269: 
                    270:                case IRP_MJ_FLUSH_BUFFERS:
                    271:                        return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0);
                    272:                }
                    273:        }
                    274: 
                    275:        return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
1.1       root      276: }
                    277: 
                    278: NTSTATUS
                    279: TCCreateRootDeviceObject (PDRIVER_OBJECT DriverObject)
                    280: {
                    281:        UNICODE_STRING Win32NameString, ntUnicodeString;
                    282:        WCHAR dosname[32], ntname[32];
                    283:        PDEVICE_OBJECT DeviceObject;
                    284:        NTSTATUS ntStatus;
                    285:        BOOL *bRootExtension;
                    286: 
                    287:        Dump ("TCCreateRootDeviceObject BEGIN\n");
1.1.1.15  root      288:        ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
1.1       root      289: 
                    290:        wcscpy (dosname, (LPWSTR) DOS_ROOT_PREFIX);
                    291:        wcscpy (ntname, (LPWSTR) NT_ROOT_PREFIX);
                    292:        RtlInitUnicodeString (&ntUnicodeString, ntname);
                    293:        RtlInitUnicodeString (&Win32NameString, dosname);
                    294: 
                    295:        Dump ("Creating root device nt=%ls dos=%ls\n", ntname, dosname);
1.1.1.3   root      296:        
1.1       root      297:        ntStatus = IoCreateDevice (
1.1.1.15  root      298:                                          DriverObject,
                    299:                                          sizeof (BOOL),
                    300:                                          &ntUnicodeString,
                    301:                                          FILE_DEVICE_UNKNOWN,
                    302:                                          FILE_DEVICE_SECURE_OPEN,
                    303:                                          FALSE,
                    304:                                          &DeviceObject);
1.1       root      305: 
                    306:        if (!NT_SUCCESS (ntStatus))
                    307:        {
                    308:                Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
                    309:                return ntStatus;/* Failed to create DeviceObject */
                    310:        }
                    311: 
                    312:        DeviceObject->Flags |= DO_DIRECT_IO;
                    313:        DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
                    314: 
                    315:        /* Setup the device extension */
                    316:        bRootExtension = (BOOL *) DeviceObject->DeviceExtension;
                    317:        *bRootExtension = TRUE;
                    318: 
                    319:        ntStatus = IoCreateSymbolicLink (&Win32NameString, &ntUnicodeString);
1.1.1.4   root      320: 
1.1       root      321:        if (!NT_SUCCESS (ntStatus))
                    322:        {
                    323:                Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
                    324:                IoDeleteDevice (DeviceObject);
                    325:                return ntStatus;
                    326:        }
                    327: 
1.1.1.4   root      328:        IoRegisterShutdownNotification (DeviceObject);
                    329: 
1.1       root      330:        Dump ("TCCreateRootDeviceObject STATUS_SUCCESS END\n");
                    331:        return STATUS_SUCCESS;
                    332: }
                    333: 
                    334: NTSTATUS
                    335: TCCreateDeviceObject (PDRIVER_OBJECT DriverObject,
                    336:                       PDEVICE_OBJECT * ppDeviceObject,
1.1.1.4   root      337:                       MOUNT_STRUCT * mount)
1.1       root      338: {
                    339:        UNICODE_STRING Win32NameString, ntUnicodeString;
                    340:        WCHAR dosname[32], ntname[32];
                    341:        PEXTENSION Extension;
                    342:        NTSTATUS ntStatus;
1.1.1.4   root      343:        ULONG devChars = 0;
1.1       root      344: 
                    345:        Dump ("TCCreateDeviceObject BEGIN\n");
1.1.1.15  root      346:        ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
1.1       root      347: 
1.1.1.4   root      348:        TCGetDosNameFromNumber (dosname, mount->nDosDriveNo);
                    349:        TCGetNTNameFromNumber (ntname, mount->nDosDriveNo);
1.1       root      350:        RtlInitUnicodeString (&ntUnicodeString, ntname);
                    351:        RtlInitUnicodeString (&Win32NameString, dosname);
                    352: 
1.1.1.15  root      353:        devChars = FILE_DEVICE_SECURE_OPEN;
                    354:        devChars |= mount->bMountReadOnly ? FILE_READ_ONLY_DEVICE : 0;
1.1.1.4   root      355:        devChars |= mount->bMountRemovable ? FILE_REMOVABLE_MEDIA : 0;
                    356: 
1.1       root      357:        Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname);
                    358: 
                    359:        ntStatus = IoCreateDevice (
                    360:                                          DriverObject,                 /* Our Driver Object */
                    361:                                          sizeof (EXTENSION),   /* Size of state information */
                    362:                                          &ntUnicodeString,             /* Device name "\Device\Name" */
                    363:                                          FILE_DEVICE_DISK,             /* Device type */
1.1.1.4   root      364:                                          devChars,                             /* Device characteristics */
1.1       root      365:                                          FALSE,                                /* Exclusive device */
                    366:                                          ppDeviceObject);              /* Returned ptr to Device Object */
                    367: 
                    368:        if (!NT_SUCCESS (ntStatus))
                    369:        {
                    370:                Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
                    371:                return ntStatus;/* Failed to create DeviceObject */
                    372:        }
                    373:        /* Initialize device object and extension. */
                    374: 
                    375:        (*ppDeviceObject)->Flags |= DO_DIRECT_IO;
1.1.1.15  root      376:        (*ppDeviceObject)->StackSize += 2;              // Reduce occurrence of NO_MORE_IRP_STACK_LOCATIONS bug check caused by buggy drivers
1.1       root      377: 
                    378:        /* Setup the device extension */
                    379:        Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension;
                    380:        memset (Extension, 0, sizeof (EXTENSION));
                    381: 
1.1.1.15  root      382:        Extension->IsVolumeDevice = TRUE;
1.1       root      383:        Extension->lMagicNumber = 0xabfeacde;
1.1.1.4   root      384:        Extension->nDosDriveNo = mount->nDosDriveNo;
                    385:        Extension->bRemovable = mount->bMountRemovable;
1.1       root      386: 
                    387:        KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE);
                    388:        KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG);
                    389:        KeInitializeSpinLock (&Extension->ListSpinLock);
                    390:        InitializeListHead (&Extension->ListEntry);
                    391: 
                    392:        Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n");
                    393: 
                    394:        return STATUS_SUCCESS;
                    395: }
                    396: 
1.1.1.5   root      397: 
                    398: void DriverMutexWait ()
                    399: {
                    400:        KeWaitForMutexObject (&driverMutex, Executive, KernelMode, FALSE, NULL);
                    401: }
                    402: 
                    403: 
                    404: void DriverMutexRelease ()
                    405: {
                    406:        KeReleaseMutex (&driverMutex, FALSE);
                    407: }
                    408: 
                    409: 
1.1.1.12  root      410: NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
1.1       root      411: {
                    412:        PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
                    413: 
                    414:        switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
                    415:        {
                    416: 
                    417:        case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
                    418:                if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_NAME))
                    419:                {
                    420:                        Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
                    421:                        Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
                    422:                }
                    423:                else
                    424:                {
                    425:                        ULONG outLength;
                    426:                        UNICODE_STRING ntUnicodeString;
1.1.1.7   root      427:                        WCHAR ntName[256];
1.1       root      428:                        PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer;
                    429: 
                    430:                        TCGetNTNameFromNumber (ntName, Extension->nDosDriveNo);
                    431:                        RtlInitUnicodeString (&ntUnicodeString, ntName);
                    432: 
                    433:                        outputBuffer->NameLength = ntUnicodeString.Length;
                    434:                        outLength = ntUnicodeString.Length + sizeof(USHORT);
                    435: 
                    436:                        if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
                    437:                        {
                    438:                                Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
                    439:                                Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
                    440: 
                    441:                                break;
                    442:                        }
                    443: 
                    444:                        RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
                    445: 
                    446:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    447:                        Irp->IoStatus.Information = outLength;
                    448: 
                    449:                        Dump ("name = %ls\n",ntName);
                    450:                }
                    451:                break;
                    452: 
                    453:        case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
                    454:                if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_UNIQUE_ID))
                    455:                {
                    456:                        Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
                    457:                        Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
                    458:                }
                    459:                else
                    460:                {
                    461:                        ULONG outLength;
                    462:                        UCHAR volId[128], tmp[] = { 0,0 };
                    463:                        PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer;
                    464: 
                    465:                        strcpy (volId, TC_UNIQUE_ID_PREFIX); 
                    466:                        tmp[0] = 'A' + Extension->nDosDriveNo;
                    467:                        strcat (volId, tmp);
                    468:                        
1.1.1.6   root      469:                        outputBuffer->UniqueIdLength = (USHORT) strlen (volId);
                    470:                        outLength = strlen (volId) + sizeof(USHORT);
1.1       root      471: 
                    472:                        if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
                    473:                        {
                    474:                                Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
                    475:                                Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
                    476:                                break;
                    477:                        }
                    478: 
1.1.1.6   root      479:                        RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen (volId));
1.1       root      480: 
                    481:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    482:                        Irp->IoStatus.Information = outLength;
                    483: 
                    484:                        Dump ("id = %s\n",volId);
                    485:                }
                    486:                break;
                    487: 
1.1.1.14  root      488:        case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
1.1       root      489:                {
                    490:                        ULONG outLength;
                    491:                        UNICODE_STRING ntUnicodeString;
1.1.1.7   root      492:                        WCHAR ntName[256];
1.1       root      493:                        PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer;
1.1.1.14  root      494: 
                    495:                        if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_SUGGESTED_LINK_NAME))
                    496:                        {
                    497:                                Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    498:                                Irp->IoStatus.Information = 0;
                    499:                                break; 
                    500:                        }
                    501: 
1.1       root      502:                        TCGetDosNameFromNumber (ntName, Extension->nDosDriveNo);
                    503:                        RtlInitUnicodeString (&ntUnicodeString, ntName);
                    504: 
                    505:                        outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length;
                    506: 
1.1.1.14  root      507:                        outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE;
                    508:                        outputBuffer->NameLength = ntUnicodeString.Length;
                    509: 
1.1       root      510:                        if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
                    511:                        {
                    512:                                Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME);
                    513:                                Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
                    514:                                break;
                    515:                        }
                    516: 
                    517:                        RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
                    518:                
                    519:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    520:                        Irp->IoStatus.Information = outLength;
                    521: 
                    522:                        Dump ("link = %ls\n",ntName);
                    523:                }
                    524:                break;
                    525: 
1.1.1.4   root      526: 
1.1       root      527:        case IOCTL_DISK_GET_MEDIA_TYPES:
                    528:        case IOCTL_DISK_GET_DRIVE_GEOMETRY:
                    529:                /* Return the drive geometry for the disk.  Note that we
                    530:                   return values which were made up to suit the disk size.  */
                    531:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
                    532:                    sizeof (DISK_GEOMETRY))
                    533:                {
1.1.1.11  root      534:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1       root      535:                        Irp->IoStatus.Information = 0;
                    536:                }
                    537:                else
                    538:                {
                    539:                        PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY)
                    540:                        Irp->AssociatedIrp.SystemBuffer;
                    541: 
1.1.1.4   root      542:                        outputBuffer->MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia;
1.1       root      543:                        outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders;
                    544:                        outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder;
                    545:                        outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack;
                    546:                        outputBuffer->BytesPerSector = Extension->BytesPerSector;
                    547:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    548:                        Irp->IoStatus.Information = sizeof (DISK_GEOMETRY);
                    549:                }
                    550:                break;
                    551: 
                    552:        case IOCTL_DISK_GET_PARTITION_INFO:
                    553:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
                    554:                    sizeof (PARTITION_INFORMATION))
                    555:                {
1.1.1.11  root      556:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1       root      557:                        Irp->IoStatus.Information = 0;
                    558:                }
                    559:                else
                    560:                {
                    561:                        PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION)
                    562:                        Irp->AssociatedIrp.SystemBuffer;
                    563: 
                    564:                        outputBuffer->PartitionType = Extension->PartitionType;
                    565:                        outputBuffer->BootIndicator = FALSE;
                    566:                        outputBuffer->RecognizedPartition = TRUE;
                    567:                        outputBuffer->RewritePartition = FALSE;
1.1.1.11  root      568:                        outputBuffer->StartingOffset.QuadPart = SECTOR_SIZE;
1.1       root      569:                        outputBuffer->PartitionLength.QuadPart= Extension->DiskLength;
1.1.1.11  root      570:                        outputBuffer->HiddenSectors = 0;
1.1       root      571:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    572:                        Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION);
                    573:                }
                    574:                break;
1.1.1.10  root      575: 
                    576:        case IOCTL_DISK_GET_PARTITION_INFO_EX:
                    577:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (PARTITION_INFORMATION_EX))
                    578:                {
1.1.1.11  root      579:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.10  root      580:                        Irp->IoStatus.Information = 0;
                    581:                }
                    582:                else
                    583:                {
                    584:                        PPARTITION_INFORMATION_EX outputBuffer = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer;
                    585: 
                    586:                        outputBuffer->PartitionStyle = PARTITION_STYLE_MBR;
                    587:                        outputBuffer->RewritePartition = FALSE;
1.1.1.11  root      588:                        outputBuffer->StartingOffset.QuadPart = SECTOR_SIZE;
1.1.1.10  root      589:                        outputBuffer->PartitionLength.QuadPart= Extension->DiskLength;
                    590:                        outputBuffer->Mbr.PartitionType = Extension->PartitionType;
                    591:                        outputBuffer->Mbr.BootIndicator = FALSE;
                    592:                        outputBuffer->Mbr.RecognizedPartition = TRUE;
1.1.1.11  root      593:                        outputBuffer->Mbr.HiddenSectors = 0;
1.1.1.10  root      594:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    595:                        Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION_EX);
                    596:                }
                    597:                break;
                    598: 
1.1.1.6   root      599:        case IOCTL_DISK_GET_DRIVE_LAYOUT:
                    600:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
                    601:                    sizeof (DRIVE_LAYOUT_INFORMATION))
                    602:                {
1.1.1.11  root      603:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.6   root      604:                        Irp->IoStatus.Information = 0;
                    605:                }
                    606:                else
                    607:                {
                    608:                        PDRIVE_LAYOUT_INFORMATION outputBuffer = (PDRIVE_LAYOUT_INFORMATION)
                    609:                        Irp->AssociatedIrp.SystemBuffer;
                    610: 
                    611:                        outputBuffer->PartitionCount = 1;
                    612:                        outputBuffer->Signature = 0;
                    613: 
                    614:                        outputBuffer->PartitionEntry->PartitionType = Extension->PartitionType;
                    615:                        outputBuffer->PartitionEntry->BootIndicator = FALSE;
                    616:                        outputBuffer->PartitionEntry->RecognizedPartition = TRUE;
                    617:                        outputBuffer->PartitionEntry->RewritePartition = FALSE;
1.1.1.11  root      618:                        outputBuffer->PartitionEntry->StartingOffset.QuadPart = SECTOR_SIZE;
                    619:                        outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength;
                    620:                        outputBuffer->PartitionEntry->HiddenSectors = 0;
1.1.1.6   root      621: 
                    622:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    623:                        Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION);
                    624:                }
                    625:                break;
                    626: 
1.1       root      627:        case IOCTL_DISK_GET_LENGTH_INFO:
                    628:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GET_LENGTH_INFORMATION))
                    629:                {
                    630:                        Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
                    631:                        Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
                    632:                }
                    633:                else
                    634:                {
                    635:                        PGET_LENGTH_INFORMATION outputBuffer = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
                    636: 
                    637:                        outputBuffer->Length.QuadPart = Extension->DiskLength;
                    638:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    639:                        Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
                    640:                }
                    641:                break;
                    642: 
                    643:        case IOCTL_DISK_VERIFY:
1.1.1.13  root      644:                if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof (PVERIFY_INFORMATION))
                    645:                {
                    646:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                    647:                        Irp->IoStatus.Information = 0;
                    648:                }
                    649:                else
1.1       root      650:                {
                    651:                        PVERIFY_INFORMATION pVerifyInformation;
                    652:                        pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
1.1.1.15  root      653: 
                    654:                        if (pVerifyInformation->StartingOffset.QuadPart + pVerifyInformation->Length > Extension->DiskLength)
                    655:                                Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    656:                        else
                    657:                        {
                    658:                                IO_STATUS_BLOCK ioStatus;
                    659:                                PVOID buffer = TCalloc (pVerifyInformation->Length);
                    660:                                
                    661:                                if (!buffer)
                    662:                                {
                    663:                                        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                    664:                                }
                    665:                                else
                    666:                                {
                    667:                                        LARGE_INTEGER offset = pVerifyInformation->StartingOffset;
                    668:                                        offset.QuadPart += Extension->cryptoInfo->hiddenVolume ? Extension->cryptoInfo->hiddenVolumeOffset : Extension->cryptoInfo->volDataAreaOffset;
                    669: 
                    670:                                        Irp->IoStatus.Status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, pVerifyInformation->Length, &offset, NULL);
                    671:                                        TCfree (buffer);
                    672: 
                    673:                                        if (NT_SUCCESS (Irp->IoStatus.Status) && ioStatus.Information != pVerifyInformation->Length)
                    674:                                                Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    675:                                }
                    676:                        }
                    677: 
1.1.1.13  root      678:                        Irp->IoStatus.Information = 0;
1.1       root      679:                }
                    680:                break;
                    681: 
                    682:        case IOCTL_DISK_CHECK_VERIFY:
1.1.1.6   root      683:        case IOCTL_STORAGE_CHECK_VERIFY:
1.1       root      684:                {
                    685:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    686:                        Irp->IoStatus.Information = 0;
1.1.1.15  root      687: 
                    688:                        if (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof (ULONG))
                    689:                        {
                    690:                                *((ULONG *) Irp->AssociatedIrp.SystemBuffer) = 0;
                    691:                                Irp->IoStatus.Information = sizeof (ULONG);
                    692:                        }
1.1       root      693:                }
                    694:                break;
                    695: 
                    696:        case IOCTL_DISK_IS_WRITABLE:
                    697:                {
1.1.1.6   root      698:                        if (Extension->bReadOnly)
1.1       root      699:                                Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
                    700:                        else
                    701:                                Irp->IoStatus.Status = STATUS_SUCCESS;
                    702:                        Irp->IoStatus.Information = 0;
                    703: 
                    704:                }
                    705:                break;
1.1.1.15  root      706:                
                    707:        case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS:
                    708:                // Vista's filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed.
                    709:                Irp->IoStatus.Status = OsMajorVersion >= 6 ? STATUS_SUCCESS : STATUS_INVALID_DEVICE_REQUEST;
                    710: 
                    711:                // No extent data can be returned as this is not a physical drive.
                    712:                Irp->IoStatus.Information = 0;
                    713:                break;
1.1       root      714: 
1.1.1.12  root      715:        default:
                    716:                return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
                    717:        }
1.1.1.15  root      718: 
1.1.1.12  root      719: #ifdef DEBUG
                    720:        if (!NT_SUCCESS (Irp->IoStatus.Status))
1.1.1.15  root      721:        {
                    722:                Dump ("IOCTL error 0x%08x (0x%x %d)\n",
                    723:                        Irp->IoStatus.Status,
                    724:                        (int) (irpSp->Parameters.DeviceIoControl.IoControlCode >> 16),
                    725:                        (int) ((irpSp->Parameters.DeviceIoControl.IoControlCode & 0x1FFF) >> 2));
                    726:        }
1.1.1.12  root      727: #endif
                    728: 
                    729:        return TCCompleteDiskIrp (Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
                    730: }
                    731: 
1.1.1.5   root      732: 
1.1.1.12  root      733: NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
                    734: {
                    735:        PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
                    736:        NTSTATUS ntStatus;
                    737: 
                    738:        switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
                    739:        {
                    740:        case TC_IOCTL_GET_DRIVER_VERSION:
                    741:        case TC_IOCTL_LEGACY_GET_DRIVER_VERSION:
1.1.1.6   root      742:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (LONG))
1.1       root      743:                {
1.1.1.11  root      744:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1       root      745:                        Irp->IoStatus.Information = 0;
                    746:                }
                    747:                else
                    748:                {
                    749:                        LONG tmp = VERSION_NUM;
                    750:                        memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4);
1.1.1.6   root      751:                        Irp->IoStatus.Information = sizeof (LONG);
1.1       root      752:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    753:                }
                    754:                break;
                    755: 
1.1.1.12  root      756:        case TC_IOCTL_GET_DEVICE_REFCOUNT:
1.1.1.6   root      757:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
1.1       root      758:                {
1.1.1.11  root      759:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1       root      760:                        Irp->IoStatus.Information = 0;
                    761:                }
                    762:                else
                    763:                {
1.1.1.6   root      764:                        *(int *) Irp->AssociatedIrp.SystemBuffer = DeviceObject->ReferenceCount;
                    765:                        Irp->IoStatus.Information = sizeof (int);
                    766:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    767:                }
                    768:                break;
                    769: 
1.1.1.12  root      770:        case TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED:
1.1.1.11  root      771:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
                    772:                {
                    773:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                    774:                        Irp->IoStatus.Information = 0;
                    775:                }
                    776:                else
                    777:                {
                    778:                        *(int *) Irp->AssociatedIrp.SystemBuffer = ReferencedDeviceDeleted;
                    779:                        Irp->IoStatus.Information = sizeof (int);
                    780:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    781:                }
                    782:                break;
                    783: 
1.1.1.12  root      784:        case TC_IOCTL_IS_ANY_VOLUME_MOUNTED:
                    785:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
                    786:                {
                    787:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                    788:                        Irp->IoStatus.Information = 0;
                    789:                }
                    790:                else
                    791:                {
                    792:                        PDEVICE_OBJECT ListDevice;
                    793:                        *(int *) Irp->AssociatedIrp.SystemBuffer = 0;
                    794: 
                    795:                        for (ListDevice = DeviceObject->DriverObject->DeviceObject;
                    796:                                ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
                    797:                        {
                    798:                                PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
                    799:                                if (!ListExtension->bRootDevice
1.1.1.15  root      800:                                        && ListExtension->IsVolumeDevice
1.1.1.12  root      801:                                        && ListExtension->lMagicNumber == 0xabfeacde)
                    802:                                {
                    803:                                        *(int *) Irp->AssociatedIrp.SystemBuffer = 1;
                    804:                                        break;
                    805:                                }
                    806:                        }
                    807: 
                    808:                        if (IsBootDriveMounted())
                    809:                                *(int *) Irp->AssociatedIrp.SystemBuffer = 1;
                    810: 
                    811:                        Irp->IoStatus.Information = sizeof (int);
                    812:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    813:                }
                    814:                break;
                    815: 
                    816:        case TC_IOCTL_OPEN_TEST:
1.1.1.6   root      817:                {
1.1       root      818:                        OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
                    819:                        OBJECT_ATTRIBUTES ObjectAttributes;
                    820:                        HANDLE NtFileHandle;
                    821:                        UNICODE_STRING FullFileName;
                    822:                        IO_STATUS_BLOCK IoStatus;
1.1.1.14  root      823:                        LARGE_INTEGER offset;
                    824:                        unsigned char readBuffer [SECTOR_SIZE];
                    825:                        NTSTATUS TCBootLoaderDetected = STATUS_NO_SUCH_DEVICE;  // STATUS_NO_SUCH_DEVICE is sent when the boot loader is not found (even if the device is found)
1.1       root      826: 
1.1.1.15  root      827:                        if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof (OPEN_TEST_STRUCT))
                    828:                        {
                    829:                                Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    830:                                Irp->IoStatus.Information = 0;
                    831:                                break;
                    832:                        }
                    833: 
                    834:                        EnsureNullTerminatedString (opentest->wszFileName, sizeof (opentest->wszFileName));
1.1       root      835:                        RtlInitUnicodeString (&FullFileName, opentest->wszFileName);
                    836: 
                    837:                        InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE,
                    838:                                                    NULL, NULL);
                    839: 
                    840:                        ntStatus = ZwCreateFile (&NtFileHandle,
                    841:                                                 SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none  */ ,
1.1.1.4   root      842:                                                 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT |
1.1       root      843:                        FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS,
                    844:                                  NULL /* eabuffer  */ , 0 /* ealength */ );
                    845: 
                    846:                        if (NT_SUCCESS (ntStatus))
                    847:                        {
1.1.1.14  root      848:                                if (opentest->bDetectTCBootLoader)
                    849:                                {
                    850:                                        // Determine if the first sector contains a portion of the TrueCrypt Boot Loader
                    851: 
                    852:                                        offset.QuadPart = 0;    // MBR
                    853: 
                    854:                                        ntStatus = ZwReadFile (NtFileHandle,
                    855:                                                NULL,
                    856:                                                NULL,
                    857:                                                NULL,
                    858:                                                &IoStatus,
                    859:                                                readBuffer,
                    860:                                                sizeof(readBuffer),
                    861:                                                &offset,
                    862:                                                NULL);
                    863: 
                    864:                                        if (NT_SUCCESS (ntStatus))
                    865:                                        {
                    866:                                                size_t i;
                    867: 
                    868:                                                // Search for the string "TrueCrypt"
                    869:                                                for (i = 0; i < sizeof (readBuffer) - strlen (TC_APP_NAME); ++i)
                    870:                                                {
                    871:                                                        if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
                    872:                                                        {
                    873:                                                                TCBootLoaderDetected = STATUS_SUCCESS;
                    874:                                                                break;
                    875:                                                        }
                    876:                                                }
                    877:                                        }
                    878:                                }
                    879: 
1.1       root      880:                                ZwClose (NtFileHandle);
                    881:                                Dump ("Open test on file %ls success.\n", opentest->wszFileName);
                    882:                        }
                    883:                        else
                    884:                        {
1.1.1.12  root      885: #if 0
1.1       root      886:                                Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus);
1.1.1.12  root      887: #endif
1.1       root      888:                        }
                    889: 
                    890:                        Irp->IoStatus.Information = 0;
1.1.1.14  root      891:                        Irp->IoStatus.Status = opentest->bDetectTCBootLoader ? TCBootLoaderDetected : ntStatus;
1.1       root      892:                }
                    893:                break;
                    894: 
1.1.1.15  root      895:        case TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG:
                    896:                {
                    897:                        GetSystemDriveConfigurationRequest *request = (GetSystemDriveConfigurationRequest *) Irp->AssociatedIrp.SystemBuffer;
                    898:                        OBJECT_ATTRIBUTES ObjectAttributes;
                    899:                        HANDLE NtFileHandle;
                    900:                        UNICODE_STRING FullFileName;
                    901:                        IO_STATUS_BLOCK IoStatus;
                    902:                        LARGE_INTEGER offset;
                    903:                        byte readBuffer [SECTOR_SIZE];
                    904: 
                    905:                        if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GetSystemDriveConfigurationRequest))
                    906:                        {
                    907:                                Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    908:                                Irp->IoStatus.Information = 0;
                    909:                                break;
                    910:                        }
                    911: 
                    912:                        EnsureNullTerminatedString (request->DevicePath, sizeof (request->DevicePath));
                    913:                        RtlInitUnicodeString (&FullFileName, request->DevicePath);
                    914: 
                    915:                        InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
                    916: 
                    917:                        ntStatus = ZwCreateFile (&NtFileHandle,
                    918:                                SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL,
                    919:                                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT |
                    920:                                FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS, NULL, 0);
                    921: 
                    922:                        if (NT_SUCCESS (ntStatus))
                    923:                        {
                    924:                                // Determine if the first sector contains a portion of the TrueCrypt Boot Loader
                    925:                                offset.QuadPart = 0;    // MBR
                    926: 
                    927:                                ntStatus = ZwReadFile (NtFileHandle,
                    928:                                        NULL,
                    929:                                        NULL,
                    930:                                        NULL,
                    931:                                        &IoStatus,
                    932:                                        readBuffer,
                    933:                                        sizeof(readBuffer),
                    934:                                        &offset,
                    935:                                        NULL);
                    936: 
                    937:                                if (NT_SUCCESS (ntStatus))
                    938:                                {
                    939:                                        size_t i;
                    940: 
                    941:                                        // Check for dynamic drive
                    942:                                        request->DriveIsDynamic = FALSE;
                    943: 
                    944:                                        if (readBuffer[510] == 0x55 && readBuffer[511] == 0xaa)
                    945:                                        {
                    946:                                                int i;
                    947:                                                for (i = 0; i < 4; ++i)
                    948:                                                {
                    949:                                                        if (readBuffer[446 + i * 16 + 4] == PARTITION_LDM)
                    950:                                                        {
                    951:                                                                request->DriveIsDynamic = TRUE;
                    952:                                                                break;
                    953:                                                        }
                    954:                                                }
                    955:                                        }
                    956: 
                    957:                                        // Search for the string "TrueCrypt"
                    958:                                        request->Configuration = 0;
                    959: 
                    960:                                        for (i = 0; i < sizeof (readBuffer) - strlen (TC_APP_NAME); ++i)
                    961:                                        {
                    962:                                                if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
                    963:                                                {
                    964:                                                        request->Configuration = readBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET];
                    965:                                                        break;
                    966:                                                }
                    967:                                        }
                    968: 
                    969:                                        Irp->IoStatus.Status = STATUS_SUCCESS;
                    970:                                        Irp->IoStatus.Information = sizeof (*request);
                    971:                                }
                    972:                                else
                    973:                                {
                    974:                                        Irp->IoStatus.Status = ntStatus;
                    975:                                        Irp->IoStatus.Information = 0;
                    976:                                }
                    977: 
                    978:                                ZwClose (NtFileHandle);
                    979: 
                    980:                        }
                    981:                        else
                    982:                        {
                    983:                                Irp->IoStatus.Status = ntStatus;
                    984:                                Irp->IoStatus.Information = 0;
                    985:                        }
                    986:                }
                    987:                break;
                    988: 
1.1.1.12  root      989:        case TC_IOCTL_WIPE_PASSWORD_CACHE:
1.1.1.5   root      990:                DriverMutexWait ();
1.1       root      991:                WipeCache ();
1.1.1.5   root      992:                DriverMutexRelease ();
1.1       root      993: 
                    994:                Irp->IoStatus.Status = STATUS_SUCCESS;
                    995:                Irp->IoStatus.Information = 0;
                    996:                break;
                    997: 
1.1.1.12  root      998:        case TC_IOCTL_GET_PASSWORD_CACHE_STATUS:
1.1       root      999:                Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS;
                   1000:                Irp->IoStatus.Information = 0;
                   1001:                break;
                   1002: 
1.1.1.14  root     1003:        case TC_IOCTL_SET_TRAVELER_MODE_STATUS:
                   1004:                if (!UserCanAccessDriveDevice())
                   1005:                {
                   1006:                        Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
                   1007:                        Irp->IoStatus.Information = 0;
                   1008:                }
                   1009:                else
                   1010:                {
                   1011:                        TravelerMode = TRUE;
                   1012:                        Dump ("Setting traveler mode\n");
                   1013:                }
                   1014:                break;
                   1015: 
                   1016:        case TC_IOCTL_GET_TRAVELER_MODE_STATUS:
                   1017:                Irp->IoStatus.Status = TravelerMode ? STATUS_SUCCESS : STATUS_PIPE_EMPTY;
                   1018:                Irp->IoStatus.Information = 0;
                   1019:                break;
                   1020: 
1.1.1.12  root     1021:        case TC_IOCTL_GET_MOUNTED_VOLUMES:
1.1.1.9   root     1022:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT)
                   1023:                        || !DeviceObject || !DeviceObject->DriverObject)
1.1       root     1024:                {
1.1.1.11  root     1025:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1       root     1026:                        Irp->IoStatus.Information = 0;
                   1027:                }
                   1028:                else
                   1029:                {
                   1030:                        MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
                   1031:                        PDEVICE_OBJECT ListDevice;
                   1032: 
1.1.1.5   root     1033:                        DriverMutexWait ();
                   1034: 
1.1       root     1035:                        list->ulMountedDrives = 0;
                   1036:                        for (ListDevice = DeviceObject->DriverObject->DeviceObject;
                   1037:                             ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
                   1038:                        {
                   1039:                                PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.12  root     1040:                                if (!ListExtension->bRootDevice
1.1.1.15  root     1041:                                        && ListExtension->IsVolumeDevice
1.1.1.12  root     1042:                                        && !ListExtension->bShuttingDown
                   1043:                                        && ListExtension->lMagicNumber == 0xabfeacde)
1.1       root     1044:                                {
                   1045:                                        list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo);
                   1046:                                        wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume);
                   1047:                                        list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength;
1.1.1.4   root     1048:                                        list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea;
1.1.1.6   root     1049:                                        if (ListExtension->cryptoInfo->hiddenVolume)
                   1050:                                                list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_HIDDEN;    // Hidden volume
                   1051:                                        else if (ListExtension->cryptoInfo->bHiddenVolProtectionAction)
                   1052:                                                list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED; // Normal/outer volume (hidden volume protected AND write already prevented)
                   1053:                                        else if (ListExtension->cryptoInfo->bProtectHiddenVolume)
                   1054:                                                list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER;     // Normal/outer volume (hidden volume protected)
                   1055:                                        else
                   1056:                                                list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_NORMAL;    // Normal volume
1.1       root     1057:                                }
                   1058:                        }
                   1059: 
1.1.1.5   root     1060:                        DriverMutexRelease ();
                   1061: 
1.1       root     1062:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                   1063:                        Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT);
                   1064:                }
                   1065:                break;
                   1066: 
1.1.1.12  root     1067:        case TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES:
                   1068:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (uint32))
                   1069:                {
                   1070:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                   1071:                        Irp->IoStatus.Information = 0;
                   1072:                }
                   1073:                else
                   1074:                {
                   1075:                        // Prevent the user from downgrading to versions lower than 5.0 by faking mounted volumes.
                   1076:                        // The user could render the system unbootable by downgrading when boot encryption
                   1077:                        // is active or being set up.
                   1078:                        *(uint32 *) Irp->AssociatedIrp.SystemBuffer = 0xffffFFFF;
                   1079:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                   1080:                        Irp->IoStatus.Information = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
                   1081:                }
                   1082:                break;
                   1083: 
                   1084:        case TC_IOCTL_GET_VOLUME_PROPERTIES:
1.1.1.9   root     1085:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT)
                   1086:                        || !DeviceObject || !DeviceObject->DriverObject)
1.1       root     1087:                {
1.1.1.11  root     1088:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1       root     1089:                        Irp->IoStatus.Information = 0;
                   1090:                }
                   1091:                else
                   1092:                {
                   1093:                        VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
                   1094:                        PDEVICE_OBJECT ListDevice;
                   1095: 
                   1096:                        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                   1097:                        Irp->IoStatus.Information = 0;
                   1098: 
1.1.1.5   root     1099:                        DriverMutexWait ();
                   1100: 
1.1       root     1101:                        for (ListDevice = DeviceObject->DriverObject->DeviceObject;
                   1102:                             ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
                   1103:                        {
                   1104: 
                   1105:                                PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.12  root     1106:                                if (!ListExtension->bRootDevice
1.1.1.15  root     1107:                                        && ListExtension->IsVolumeDevice
1.1.1.6   root     1108:                                        && !ListExtension->bShuttingDown
                   1109:                                        && ListExtension->nDosDriveNo == prop->driveNo)
1.1       root     1110:                                {
1.1.1.6   root     1111:                                        prop->uniqueId = ListExtension->UniqueVolumeId;
1.1       root     1112:                                        wcscpy (prop->wszVolume, ListExtension->wszVolume);
                   1113:                                        prop->diskLength = ListExtension->DiskLength;
1.1.1.4   root     1114:                                        prop->ea = ListExtension->cryptoInfo->ea;
1.1.1.7   root     1115:                                        prop->mode = ListExtension->cryptoInfo->mode;
1.1       root     1116:                                        prop->pkcs5 = ListExtension->cryptoInfo->pkcs5;
                   1117:                                        prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations;
                   1118:                                        prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time;
                   1119:                                        prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time;
1.1.1.6   root     1120:                                        prop->readOnly = ListExtension->bReadOnly;
1.1.1.4   root     1121:                                        prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume;
1.1       root     1122: 
1.1.1.6   root     1123:                                        if (ListExtension->cryptoInfo->bProtectHiddenVolume)
                   1124:                                                prop->hiddenVolProtection = ListExtension->cryptoInfo->bHiddenVolProtectionAction ? HIDVOL_PROT_STATUS_ACTION_TAKEN : HIDVOL_PROT_STATUS_ACTIVE;
                   1125:                                        else
                   1126:                                                prop->hiddenVolProtection = HIDVOL_PROT_STATUS_NONE;
                   1127: 
1.1.1.12  root     1128:                                        prop->totalBytesRead = ListExtension->Queue.TotalBytesRead;
                   1129:                                        prop->totalBytesWritten = ListExtension->Queue.TotalBytesWritten;
1.1.1.6   root     1130: 
1.1.1.15  root     1131:                                        prop->volFormatVersion = ListExtension->cryptoInfo->LegacyVolume ? TC_VOLUME_FORMAT_VERSION_PRE_6_0 : TC_VOLUME_FORMAT_VERSION;
                   1132: 
1.1       root     1133:                                        Irp->IoStatus.Status = STATUS_SUCCESS;
                   1134:                                        Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT);
                   1135:                                        break;
                   1136:                                }
                   1137:                        }
1.1.1.5   root     1138: 
                   1139:                        DriverMutexRelease ();
1.1       root     1140:                }
                   1141:                break;
                   1142: 
1.1.1.12  root     1143:        case TC_IOCTL_GET_RESOLVED_SYMLINK:
1.1.1.6   root     1144:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (RESOLVE_SYMLINK_STRUCT))
1.1.1.4   root     1145:                {
1.1.1.11  root     1146:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.4   root     1147:                        Irp->IoStatus.Information = 0;
                   1148:                }
                   1149:                else
1.1       root     1150:                {
1.1.1.4   root     1151:                        RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
                   1152:                        {
                   1153:                                NTSTATUS ntStatus;
                   1154: 
1.1.1.15  root     1155:                                EnsureNullTerminatedString (resolve->symLinkName, sizeof (resolve->symLinkName));
                   1156: 
1.1.1.4   root     1157:                                ntStatus = SymbolicLinkToTarget (resolve->symLinkName,
                   1158:                                        resolve->targetName,
                   1159:                                        sizeof (resolve->targetName));
                   1160: 
                   1161:                                Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT);
                   1162:                                Irp->IoStatus.Status = ntStatus;
                   1163:                        }
                   1164: 
                   1165:                }
                   1166:                break;
                   1167: 
1.1.1.12  root     1168:        case TC_IOCTL_GET_DRIVE_PARTITION_INFO:
1.1.1.10  root     1169:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (DISK_PARTITION_INFO_STRUCT))
                   1170:                {
1.1.1.11  root     1171:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.10  root     1172:                        Irp->IoStatus.Information = 0;
                   1173:                }
                   1174:                else
                   1175:                {
                   1176:                        DISK_PARTITION_INFO_STRUCT *info = (DISK_PARTITION_INFO_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
                   1177:                        {
                   1178:                                PARTITION_INFORMATION_EX pi;
                   1179:                                NTSTATUS ntStatus;
                   1180: 
1.1.1.15  root     1181:                                EnsureNullTerminatedString (info->deviceName, sizeof (info->deviceName));
                   1182: 
1.1.1.10  root     1183:                                ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi));
                   1184:                                if (NT_SUCCESS(ntStatus))
                   1185:                                {
                   1186:                                        memset (&info->partInfo, 0, sizeof (info->partInfo));
                   1187: 
                   1188:                                        info->partInfo.PartitionLength = pi.PartitionLength;
                   1189:                                        info->partInfo.PartitionNumber = pi.PartitionNumber;
                   1190:                                        info->partInfo.StartingOffset = pi.StartingOffset;
                   1191: 
                   1192:                                        if (pi.PartitionStyle == PARTITION_STYLE_MBR)
1.1.1.15  root     1193:                                        {
1.1.1.10  root     1194:                                                info->partInfo.PartitionType = pi.Mbr.PartitionType;
1.1.1.15  root     1195:                                                info->partInfo.BootIndicator = pi.Mbr.BootIndicator;
                   1196:                                        }
1.1.1.12  root     1197: 
                   1198:                                        info->IsGPT = pi.PartitionStyle == PARTITION_STYLE_GPT;
1.1.1.10  root     1199:                                }
                   1200:                                else
                   1201:                                {
                   1202:                                        // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX
                   1203:                                        ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &info->partInfo, sizeof (info->partInfo));
1.1.1.12  root     1204:                                        info->IsGPT = FALSE;
1.1.1.10  root     1205:                                }
                   1206: 
                   1207:                                Irp->IoStatus.Information = sizeof (DISK_PARTITION_INFO_STRUCT);
                   1208:                                Irp->IoStatus.Status = ntStatus;
                   1209:                        }
                   1210: 
                   1211:                }
                   1212:                break;
                   1213: 
1.1.1.12  root     1214:        case TC_IOCTL_GET_DRIVE_GEOMETRY:
1.1.1.10  root     1215:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (DISK_GEOMETRY_STRUCT))
                   1216:                {
1.1.1.11  root     1217:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.10  root     1218:                        Irp->IoStatus.Information = 0;
                   1219:                }
                   1220:                else
                   1221:                {
                   1222:                        DISK_GEOMETRY_STRUCT *g = (DISK_GEOMETRY_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
                   1223:                        {
                   1224:                                NTSTATUS ntStatus;
                   1225: 
1.1.1.15  root     1226:                                EnsureNullTerminatedString (g->deviceName, sizeof (g->deviceName));
                   1227: 
1.1.1.10  root     1228:                                ntStatus = TCDeviceIoControl (g->deviceName,
                   1229:                                        IOCTL_DISK_GET_DRIVE_GEOMETRY,
                   1230:                                        NULL, 0, &g->diskGeometry, sizeof (g->diskGeometry));
                   1231: 
                   1232:                                Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_STRUCT);
                   1233:                                Irp->IoStatus.Status = ntStatus;
                   1234:                        }
                   1235:                }
                   1236:                break;
                   1237: 
1.1.1.12  root     1238:        case TC_IOCTL_PROBE_REAL_DRIVE_SIZE:
                   1239:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (ProbeRealDriveSizeRequest))
                   1240:                {
                   1241:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                   1242:                        Irp->IoStatus.Information = 0;
                   1243:                }
                   1244:                else
                   1245:                {
                   1246:                        ProbeRealDriveSizeRequest *request = (ProbeRealDriveSizeRequest *) Irp->AssociatedIrp.SystemBuffer;
                   1247:                        NTSTATUS status;
                   1248:                        UNICODE_STRING name;
                   1249:                        PFILE_OBJECT fileObject;
                   1250:                        PDEVICE_OBJECT deviceObject;
                   1251: 
1.1.1.15  root     1252:                        EnsureNullTerminatedString (request->DeviceName, sizeof (request->DeviceName));
                   1253: 
1.1.1.12  root     1254:                        RtlInitUnicodeString (&name, request->DeviceName);
                   1255:                        status = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
                   1256:                        if (!NT_SUCCESS (status))
                   1257:                        {
                   1258:                                Irp->IoStatus.Information = 0;
                   1259:                                Irp->IoStatus.Status = status;
                   1260:                                break;
                   1261:                        }
                   1262: 
                   1263:                        status = ProbeRealDriveSize (deviceObject, &request->RealDriveSize);
                   1264:                        ObDereferenceObject (fileObject);
                   1265: 
1.1.1.14  root     1266:                        if (status == STATUS_TIMEOUT)
                   1267:                        {
                   1268:                                request->TimeOut = TRUE;
                   1269:                                Irp->IoStatus.Information = sizeof (ProbeRealDriveSizeRequest);
                   1270:                                Irp->IoStatus.Status = STATUS_SUCCESS;
                   1271:                        }
                   1272:                        else if (!NT_SUCCESS (status))
1.1.1.12  root     1273:                        {
                   1274:                                Irp->IoStatus.Information = 0;
                   1275:                                Irp->IoStatus.Status = status;
                   1276:                        }
                   1277:                        else
                   1278:                        {
1.1.1.14  root     1279:                                request->TimeOut = FALSE;
1.1.1.12  root     1280:                                Irp->IoStatus.Information = sizeof (ProbeRealDriveSizeRequest);
                   1281:                                Irp->IoStatus.Status = status;
                   1282:                        }
                   1283:                }
                   1284:                break;
                   1285: 
                   1286:        case TC_IOCTL_MOUNT_VOLUME:
1.1.1.4   root     1287:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT))
                   1288:                {
1.1.1.11  root     1289:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1.1.4   root     1290:                        Irp->IoStatus.Information = 0;
                   1291:                }
                   1292:                else
                   1293:                {
                   1294:                        MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
                   1295: 
1.1.1.15  root     1296:                        if (mount->VolumePassword.Length > MAX_PASSWORD)
                   1297:                        {
                   1298:                                Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                   1299:                                Irp->IoStatus.Information = 0;
                   1300:                                break;
                   1301:                        }
                   1302: 
                   1303:                        EnsureNullTerminatedString (mount->wszVolume, sizeof (mount->wszVolume));
                   1304: 
1.1.1.5   root     1305:                        DriverMutexWait ();
1.1.1.6   root     1306: 
                   1307:                        Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
1.1.1.4   root     1308:                        Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
1.1.1.5   root     1309:                        DriverMutexRelease ();
1.1.1.6   root     1310: 
                   1311:                        burn (&mount->VolumePassword, sizeof (mount->VolumePassword));
                   1312:                        burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword));
1.1       root     1313:                }
                   1314:                break;
                   1315: 
1.1.1.12  root     1316:        case TC_IOCTL_DISMOUNT_VOLUME:
1.1.1.9   root     1317:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT)
                   1318:                        || !DeviceObject || !DeviceObject->DriverObject)
1.1       root     1319:                {
1.1.1.11  root     1320:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1       root     1321:                        Irp->IoStatus.Information = 0;
                   1322:                }
                   1323:                else
                   1324:                {
                   1325:                        UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
                   1326:                        PDEVICE_OBJECT ListDevice;
                   1327: 
                   1328:                        unmount->nReturnCode = ERR_DRIVE_NOT_FOUND;
                   1329: 
                   1330:                        for (ListDevice = DeviceObject->DriverObject->DeviceObject;
                   1331:                             ListDevice != (PDEVICE_OBJECT) NULL;
                   1332:                             ListDevice = ListDevice->NextDevice)
                   1333:                        {
                   1334:                                PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
                   1335: 
1.1.1.12  root     1336:                                if (!ListExtension->bRootDevice
1.1.1.15  root     1337:                                        && ListExtension->IsVolumeDevice
1.1.1.6   root     1338:                                        && !ListExtension->bShuttingDown
1.1.1.4   root     1339:                                        && unmount->nDosDriveNo == ListExtension->nDosDriveNo)
1.1       root     1340:                                {
1.1.1.5   root     1341:                                        DriverMutexWait ();
1.1.1.15  root     1342:                                        unmount->nReturnCode = UnmountDevice (unmount, ListDevice, unmount->ignoreOpenFiles);
1.1.1.5   root     1343:                                        DriverMutexRelease ();
1.1.1.4   root     1344:                                        break;
1.1.1.8   root     1345:                                }
1.1.1.4   root     1346:                        }
1.1       root     1347: 
1.1.1.4   root     1348:                        Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
1.1       root     1349:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                   1350:                }
                   1351:                break;
                   1352: 
1.1.1.12  root     1353:        case TC_IOCTL_DISMOUNT_ALL_VOLUMES:
1.1.1.4   root     1354:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
1.1       root     1355:                {
1.1.1.11  root     1356:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
1.1       root     1357:                        Irp->IoStatus.Information = 0;
                   1358:                }
                   1359:                else
                   1360:                {
1.1.1.4   root     1361:                        UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
1.1       root     1362: 
1.1.1.15  root     1363:                        unmount->nReturnCode = UnmountAllDevices (unmount, DeviceObject, unmount->ignoreOpenFiles);
1.1       root     1364: 
1.1.1.4   root     1365:                        Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
                   1366:                        Irp->IoStatus.Status = STATUS_SUCCESS;
1.1       root     1367:                }
                   1368:                break;
                   1369: 
1.1.1.12  root     1370:        case TC_IOCTL_BOOT_ENCRYPTION_SETUP:
                   1371:                DriverMutexWait ();
                   1372:                
                   1373:                Irp->IoStatus.Status = StartBootEncryptionSetup (DeviceObject, Irp, irpSp);
                   1374:                Irp->IoStatus.Information = 0;
                   1375:                
                   1376:                DriverMutexRelease ();
                   1377:                break;
                   1378: 
                   1379:        case TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP:
                   1380:                DriverMutexWait ();
                   1381:                
                   1382:                Irp->IoStatus.Status = AbortBootEncryptionSetup();
                   1383:                Irp->IoStatus.Information = 0;
                   1384:                
                   1385:                DriverMutexRelease ();
                   1386:                break;
                   1387: 
                   1388:        case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
                   1389:                DriverMutexWait ();
                   1390:                GetBootEncryptionStatus (Irp, irpSp);
                   1391:                DriverMutexRelease ();
                   1392:                break;
                   1393: 
                   1394:        case TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT:
                   1395:                Irp->IoStatus.Information = 0;
                   1396:                Irp->IoStatus.Status = GetSetupResult();
                   1397:                break;
                   1398: 
                   1399:        case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
                   1400:                DriverMutexWait ();
                   1401:                GetBootDriveVolumeProperties (Irp, irpSp);
                   1402:                DriverMutexRelease ();
                   1403:                break;
                   1404: 
                   1405:        case TC_IOCTL_GET_BOOT_LOADER_VERSION:
                   1406:                DriverMutexWait ();
                   1407:                GetBootLoaderVersion (Irp, irpSp);
                   1408:                DriverMutexRelease ();
                   1409:                break;
                   1410: 
                   1411:        case TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER:
                   1412:                DriverMutexWait ();
                   1413:                ReopenBootVolumeHeader (Irp, irpSp);
                   1414:                DriverMutexRelease ();
                   1415:                break;
                   1416: 
1.1.1.14  root     1417:        case TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME:
                   1418:                DriverMutexWait ();
                   1419:                GetBootEncryptionAlgorithmName (Irp, irpSp);
                   1420:                DriverMutexRelease ();
                   1421:                break;
                   1422: 
1.1.1.15  root     1423:        case TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING:
                   1424:                if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
                   1425:                {
                   1426:                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                   1427:                        Irp->IoStatus.Information = 0;
                   1428:                }
                   1429:                else
                   1430:                {
                   1431:                        *(int *) Irp->AssociatedIrp.SystemBuffer = IsHiddenSystemRunning() ? 1 : 0;
                   1432:                        Irp->IoStatus.Information = sizeof (int);
                   1433:                        Irp->IoStatus.Status = STATUS_SUCCESS;
                   1434:                }
                   1435:                break;
                   1436: 
1.1.1.12  root     1437:        default:
                   1438:                return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
                   1439:        }
1.1.1.10  root     1440: 
1.1.1.12  root     1441:        
1.1.1.10  root     1442: #ifdef DEBUG
1.1.1.12  root     1443:        if (!NT_SUCCESS (Irp->IoStatus.Status))
                   1444:        {
                   1445:                switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
                   1446:                {
                   1447:                case TC_IOCTL_GET_MOUNTED_VOLUMES:
                   1448:                case TC_IOCTL_GET_PASSWORD_CACHE_STATUS:
1.1.1.14  root     1449:                case TC_IOCTL_GET_TRAVELER_MODE_STATUS:
                   1450:                case TC_IOCTL_SET_TRAVELER_MODE_STATUS:
1.1.1.12  root     1451:                case TC_IOCTL_OPEN_TEST:
                   1452:                case TC_IOCTL_GET_RESOLVED_SYMLINK:
                   1453:                case TC_IOCTL_GET_DRIVE_PARTITION_INFO:
                   1454:                case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
                   1455:                case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
1.1.1.15  root     1456:                case TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING:
1.1.1.12  root     1457:                        break;
                   1458: 
                   1459:                default:
                   1460:                        Dump ("IOCTL error 0x%08x\n", Irp->IoStatus.Status);
                   1461:                }
                   1462:        }
1.1.1.10  root     1463: #endif
1.1.1.12  root     1464: 
                   1465:        return TCCompleteIrp (Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
                   1466: }
                   1467: 
                   1468: 
                   1469: NTSTATUS TCStartThread (PKSTART_ROUTINE threadProc, PVOID threadArg, PKTHREAD *kThread)
                   1470: {
1.1.1.13  root     1471:        return TCStartThreadInProcess (threadProc, threadArg, kThread, NULL);
                   1472: }
                   1473: 
                   1474: 
                   1475: NTSTATUS TCStartThreadInProcess (PKSTART_ROUTINE threadProc, PVOID threadArg, PKTHREAD *kThread, PEPROCESS process)
                   1476: {
1.1.1.12  root     1477:        NTSTATUS status;
                   1478:        HANDLE threadHandle;
1.1.1.13  root     1479:        HANDLE processHandle = NULL;
1.1.1.12  root     1480:        OBJECT_ATTRIBUTES threadObjAttributes;
                   1481: 
1.1.1.13  root     1482:        if (process)
                   1483:        {
                   1484:                status = ObOpenObjectByPointer (process, OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &processHandle);
                   1485:                if (!NT_SUCCESS (status))
                   1486:                        return status;
                   1487:        }
                   1488: 
1.1.1.12  root     1489:        InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
                   1490:        
1.1.1.13  root     1491:        status = PsCreateSystemThread (&threadHandle, THREAD_ALL_ACCESS, &threadObjAttributes, processHandle, NULL, threadProc, threadArg);
1.1.1.12  root     1492:        if (!NT_SUCCESS (status))
                   1493:                return status;
                   1494: 
                   1495:        status = ObReferenceObjectByHandle (threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID *) kThread, NULL);
                   1496:        if (!NT_SUCCESS (status))
                   1497:        {
                   1498:                ZwClose (threadHandle);
                   1499:                *kThread = NULL;
                   1500:                return status;
                   1501:        }
                   1502: 
1.1.1.13  root     1503:        if (processHandle)
                   1504:                ZwClose (processHandle);
                   1505: 
1.1.1.12  root     1506:        ZwClose (threadHandle);
                   1507:        return STATUS_SUCCESS;
                   1508: }
                   1509: 
                   1510: 
                   1511: void TCStopThread (PKTHREAD kThread, PKEVENT wakeUpEvent)
                   1512: {
                   1513:        if (wakeUpEvent)
                   1514:                KeSetEvent (wakeUpEvent, 0, FALSE);
                   1515: 
                   1516:        KeWaitForSingleObject (kThread, Executive, KernelMode, FALSE, NULL);
                   1517:        ObDereferenceObject (kThread);
1.1       root     1518: }
                   1519: 
1.1.1.6   root     1520: 
1.1       root     1521: NTSTATUS
1.1.1.12  root     1522: TCStartVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount)
1.1       root     1523: {
                   1524:        PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK));
                   1525:        HANDLE hThread;
                   1526:        NTSTATUS ntStatus;
1.1.1.6   root     1527:        HANDLE process;
1.1.1.12  root     1528:        OBJECT_ATTRIBUTES threadObjAttributes;
1.1       root     1529: 
                   1530:        Dump ("Starting thread...\n");
                   1531: 
                   1532:        if (pThreadBlock == NULL)
                   1533:        {
                   1534:                return STATUS_INSUFFICIENT_RESOURCES;
                   1535:        }
                   1536:        else
                   1537:        {
                   1538:                pThreadBlock->DeviceObject = DeviceObject;
                   1539:                pThreadBlock->mount = mount;
                   1540:        }
                   1541: 
1.1.1.6   root     1542:        if (mount->bUserContext)
                   1543:        {
1.1.1.13  root     1544:                ntStatus = ObOpenObjectByPointer (IoGetCurrentProcess (), OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &process);
1.1.1.6   root     1545:                if (!NT_SUCCESS (ntStatus))
                   1546:                {
                   1547:                        Dump ("ObOpenObjectByPointer Failed\n");
                   1548:                        goto ret;
                   1549:                }
                   1550:        }
                   1551:        else
                   1552:                process = NULL;
                   1553: 
1.1       root     1554:        Extension->bThreadShouldQuit = FALSE;
                   1555: 
1.1.1.12  root     1556:        InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
                   1557: 
1.1       root     1558:        ntStatus = PsCreateSystemThread (&hThread,
                   1559:                                         THREAD_ALL_ACCESS,
1.1.1.12  root     1560:                                         &threadObjAttributes,
1.1.1.6   root     1561:                                         process,
1.1       root     1562:                                         NULL,
1.1.1.12  root     1563:                                         VolumeThreadProc,
1.1       root     1564:                                         pThreadBlock);
                   1565: 
1.1.1.13  root     1566:        if (process)
                   1567:                ZwClose (process);
                   1568: 
1.1       root     1569:        if (!NT_SUCCESS (ntStatus))
                   1570:        {
                   1571:                Dump ("PsCreateSystemThread Failed END\n");
1.1.1.6   root     1572:                goto ret;
1.1       root     1573:        }
                   1574: 
1.1.1.12  root     1575:        ntStatus = ObReferenceObjectByHandle (hThread,
1.1       root     1576:                                   THREAD_ALL_ACCESS,
                   1577:                                   NULL,
                   1578:                                   KernelMode,
                   1579:                                   &Extension->peThread,
                   1580:                                   NULL);
1.1.1.12  root     1581: 
1.1       root     1582:        ZwClose (hThread);
                   1583: 
1.1.1.12  root     1584:        if (!NT_SUCCESS (ntStatus))
                   1585:                goto ret;
                   1586: 
1.1       root     1587:        Dump ("Waiting for thread to initialize...\n");
                   1588: 
                   1589:        KeWaitForSingleObject (&Extension->keCreateEvent,
1.1.1.12  root     1590:                               Executive,
                   1591:                               KernelMode,
1.1       root     1592:                               FALSE,
                   1593:                               NULL);
                   1594: 
                   1595:        Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus);
                   1596:        ntStatus = pThreadBlock->ntCreateStatus;
1.1.1.6   root     1597: 
                   1598: ret:
1.1       root     1599:        TCfree (pThreadBlock);
                   1600:        return ntStatus;
                   1601: }
                   1602: 
                   1603: void
1.1.1.12  root     1604: TCStopVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
1.1       root     1605: {
                   1606:        NTSTATUS ntStatus;
                   1607: 
                   1608:        if (DeviceObject);      /* Remove compiler warning */
                   1609: 
                   1610:        Dump ("Signalling thread to quit...\n");
                   1611: 
                   1612:        Extension->bThreadShouldQuit = TRUE;
                   1613: 
                   1614:        KeReleaseSemaphore (&Extension->RequestSemaphore,
                   1615:                            0,
                   1616:                            1,
                   1617:                            TRUE);
                   1618: 
1.1.1.4   root     1619:        ntStatus = KeWaitForSingleObject (Extension->peThread,
1.1.1.12  root     1620:                                          Executive,
                   1621:                                          KernelMode,
1.1       root     1622:                                          FALSE,
                   1623:                                          NULL);
                   1624:        if (ntStatus != STATUS_SUCCESS)
                   1625:                Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n",
                   1626:                      ntStatus);
                   1627: 
1.1.1.6   root     1628:        ObDereferenceObject (Extension->peThread);
1.1       root     1629:        Extension->peThread = NULL;
                   1630: 
1.1.1.15  root     1631:        Dump ("Thread exited\n");
1.1       root     1632: }
                   1633: 
1.1.1.5   root     1634: 
                   1635: // Suspend current thread for a number of milliseconds
                   1636: void TCSleep (int milliSeconds)
                   1637: {
                   1638:        PKTIMER timer = (PKTIMER) TCalloc (sizeof (KTIMER));
                   1639:        LARGE_INTEGER duetime;
                   1640: 
1.1.1.14  root     1641:        if (!timer)
                   1642:                return;
                   1643: 
1.1.1.5   root     1644:        duetime.QuadPart = (__int64) milliSeconds * -10000;
                   1645:        KeInitializeTimerEx(timer, NotificationTimer);
                   1646:        KeSetTimerEx(timer, duetime, 0, NULL);
                   1647: 
1.1.1.12  root     1648:        KeWaitForSingleObject (timer, Executive, KernelMode, FALSE, NULL);
1.1.1.5   root     1649: 
                   1650:        TCfree (timer);
                   1651: }
                   1652: 
                   1653: 
1.1.1.12  root     1654: /* VolumeThreadProc does all the work of processing IRP's, and dispatching them
1.1       root     1655:    to either the ReadWrite function or the DeviceControl function */
                   1656: VOID
1.1.1.12  root     1657: VolumeThreadProc (PVOID Context)
1.1       root     1658: {
                   1659:        PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context;
                   1660:        PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject;
                   1661:        PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
                   1662:        BOOL bDevice;
                   1663: 
                   1664:        /* Set thread priority to lowest realtime level. */
                   1665:        KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY);
                   1666: 
                   1667:        Dump ("Mount THREAD OPENING VOLUME BEGIN\n");
                   1668: 
                   1669:        if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0)
                   1670:        {
                   1671:                wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\"));
1.1.1.7   root     1672:                wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
                   1673:                        sizeof (pThreadBlock->wszMountVolume) / 2 - 5);
1.1       root     1674:                bDevice = FALSE;
                   1675:        }
                   1676:        else
                   1677:        {
1.1.1.8   root     1678:                pThreadBlock->wszMountVolume[0] = 0;
                   1679:                wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
1.1.1.7   root     1680:                        sizeof (pThreadBlock->wszMountVolume) / 2 - 1);
1.1       root     1681:                bDevice = TRUE;
                   1682:        }
                   1683: 
                   1684:        Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n",
                   1685:              pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice);
                   1686: 
                   1687:        pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject,
1.1.1.7   root     1688:                Extension,
                   1689:                pThreadBlock->mount,
                   1690:                pThreadBlock->wszMountVolume,
                   1691:                bDevice);
1.1       root     1692: 
                   1693:        if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0)
                   1694:        {
                   1695:                KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
                   1696:                PsTerminateSystemThread (STATUS_SUCCESS);
                   1697:        }
1.1.1.12  root     1698: 
                   1699:        // Start IO queue
                   1700:        Extension->Queue.IsFilterDevice = FALSE;
                   1701:        Extension->Queue.DeviceObject = DeviceObject;
                   1702:        Extension->Queue.CryptoInfo = Extension->cryptoInfo;
                   1703:        Extension->Queue.HostFileHandle = Extension->hDeviceFile;
                   1704:        Extension->Queue.VirtualDeviceLength = Extension->DiskLength;
                   1705: 
1.1.1.13  root     1706:        pThreadBlock->ntCreateStatus = EncryptedIoQueueStart (&Extension->Queue, pThreadBlock->mount->bUserContext ? IoGetCurrentProcess() : NULL);
1.1.1.12  root     1707: 
                   1708:        if (!NT_SUCCESS (pThreadBlock->ntCreateStatus))
1.1       root     1709:        {
1.1.1.12  root     1710:                TCCloseVolume (DeviceObject, Extension);
                   1711: 
                   1712:                pThreadBlock->mount->nReturnCode = ERR_OS_ERROR;
1.1       root     1713:                KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
1.1.1.12  root     1714:                PsTerminateSystemThread (STATUS_SUCCESS);
1.1       root     1715:        }
                   1716: 
1.1.1.12  root     1717:        KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
                   1718:        /* From this point on pThreadBlock cannot be used as it will have been released! */
                   1719:        pThreadBlock = NULL;
                   1720: 
1.1       root     1721:        for (;;)
                   1722:        {
                   1723:                /* Wait for a request from the dispatch routines. */
1.1.1.15  root     1724:                KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore, Executive, KernelMode, FALSE, NULL);
1.1       root     1725: 
1.1.1.15  root     1726:                for (;;)
1.1       root     1727:                {
1.1.1.15  root     1728:                        PIO_STACK_LOCATION irpSp;
                   1729:                        PLIST_ENTRY request;
                   1730:                        PIRP irp;
1.1       root     1731: 
1.1.1.15  root     1732:                        request = ExInterlockedRemoveHeadList (&Extension->ListEntry, &Extension->ListSpinLock);
                   1733:                        if (request == NULL)
                   1734:                                break;
1.1       root     1735: 
1.1.1.15  root     1736:                        irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry);
                   1737:                        irpSp = IoGetCurrentIrpStackLocation (irp);
1.1       root     1738: 
1.1.1.15  root     1739:                        if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
                   1740:                                ProcessVolumeDeviceControlIrp (DeviceObject, Extension, irp);
                   1741:                        else
                   1742:                                ASSERT (FALSE);
                   1743:                }
1.1.1.12  root     1744: 
1.1.1.15  root     1745:                if (Extension->bThreadShouldQuit)
                   1746:                {
                   1747:                        Dump ("Closing volume\n");
                   1748:                        EncryptedIoQueueStop (&Extension->Queue);
1.1.1.12  root     1749: 
1.1.1.15  root     1750:                        TCCloseVolume (DeviceObject, Extension);
                   1751:                        PsTerminateSystemThread (STATUS_SUCCESS);
1.1       root     1752:                }
1.1.1.10  root     1753:        }
1.1       root     1754: }
                   1755: 
                   1756: void
                   1757: TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)
                   1758: {
                   1759:        WCHAR tmp[3] =
                   1760:        {0, ':', 0};
                   1761:        int j = nDriveNo + (WCHAR) 'A';
                   1762: 
                   1763:        tmp[0] = (short) j;
                   1764:        wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
                   1765:        wcsncat (ntname, tmp, 1);
                   1766: }
                   1767: 
                   1768: void
                   1769: TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo)
                   1770: {
                   1771:        WCHAR tmp[3] =
                   1772:        {0, ':', 0};
                   1773:        int j = nDriveNo + (WCHAR) 'A';
                   1774: 
                   1775:        tmp[0] = (short) j;
                   1776:        wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX);
                   1777:        wcscat (dosname, tmp);
                   1778: }
                   1779: 
                   1780: #ifdef _DEBUG
                   1781: LPWSTR
                   1782: TCTranslateCode (ULONG ulCode)
                   1783: {
1.1.1.12  root     1784:        switch (ulCode)
                   1785:        {
                   1786: #define TC_CASE_RET_NAME(CODE) case CODE : return L###CODE
                   1787: 
                   1788:                TC_CASE_RET_NAME (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
                   1789:                TC_CASE_RET_NAME (TC_IOCTL_BOOT_ENCRYPTION_SETUP);
                   1790:                TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_ALL_VOLUMES);
                   1791:                TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_VOLUME);
                   1792:                TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES);
1.1.1.14  root     1793:                TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME);
1.1.1.12  root     1794:                TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
                   1795:                TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS);
                   1796:                TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_LOADER_VERSION);
                   1797:                TC_CASE_RET_NAME (TC_IOCTL_GET_DEVICE_REFCOUNT);
                   1798:                TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_GEOMETRY);
                   1799:                TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_PARTITION_INFO);
                   1800:                TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVER_VERSION);
                   1801:                TC_CASE_RET_NAME (TC_IOCTL_GET_MOUNTED_VOLUMES);
                   1802:                TC_CASE_RET_NAME (TC_IOCTL_GET_PASSWORD_CACHE_STATUS);
1.1.1.15  root     1803:                TC_CASE_RET_NAME (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG);
1.1.1.14  root     1804:                TC_CASE_RET_NAME (TC_IOCTL_GET_TRAVELER_MODE_STATUS);
                   1805:                TC_CASE_RET_NAME (TC_IOCTL_SET_TRAVELER_MODE_STATUS);
1.1.1.12  root     1806:                TC_CASE_RET_NAME (TC_IOCTL_GET_RESOLVED_SYMLINK);
                   1807:                TC_CASE_RET_NAME (TC_IOCTL_GET_VOLUME_PROPERTIES);
1.1.1.15  root     1808:                TC_CASE_RET_NAME (TC_IOCTL_DISK_IS_WRITABLE);
1.1.1.12  root     1809:                TC_CASE_RET_NAME (TC_IOCTL_IS_ANY_VOLUME_MOUNTED);
1.1.1.15  root     1810:                TC_CASE_RET_NAME (TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING);
1.1.1.12  root     1811:                TC_CASE_RET_NAME (TC_IOCTL_MOUNT_VOLUME);
                   1812:                TC_CASE_RET_NAME (TC_IOCTL_OPEN_TEST);
                   1813:                TC_CASE_RET_NAME (TC_IOCTL_PROBE_REAL_DRIVE_SIZE);
                   1814:                TC_CASE_RET_NAME (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER);
                   1815:                TC_CASE_RET_NAME (TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED);
                   1816:                TC_CASE_RET_NAME (TC_IOCTL_WIPE_PASSWORD_CACHE);
                   1817: 
1.1.1.15  root     1818:                TC_CASE_RET_NAME (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS);
                   1819: 
1.1.1.12  root     1820: #undef TC_CASE_RET_NAME
                   1821:        }
                   1822: 
1.1       root     1823:        if (ulCode ==                    IOCTL_DISK_GET_DRIVE_GEOMETRY)
                   1824:                return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY");
                   1825:        else if (ulCode ==               IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)
                   1826:                return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX");
                   1827:        else if (ulCode ==               IOCTL_MOUNTDEV_QUERY_DEVICE_NAME)
                   1828:                return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME");
                   1829:        else if (ulCode ==               IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME)
                   1830:                return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME");
                   1831:        else if (ulCode ==               IOCTL_MOUNTDEV_QUERY_UNIQUE_ID)
                   1832:                return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID");
                   1833:        else if (ulCode ==               IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY)
                   1834:                return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY");
                   1835:        else if (ulCode ==               IOCTL_VOLUME_ONLINE)
                   1836:                return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE");
                   1837:        else if (ulCode ==               IOCTL_MOUNTDEV_LINK_CREATED)
                   1838:                return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED");
                   1839:        else if (ulCode ==               IOCTL_MOUNTDEV_LINK_DELETED)
                   1840:                return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED");
                   1841:        else if (ulCode ==               IOCTL_MOUNTMGR_QUERY_POINTS)
                   1842:                return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS");
                   1843:        else if (ulCode ==               IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED)
                   1844:                return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED");
                   1845:        else if (ulCode ==               IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED)
                   1846:                return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED");
                   1847:        else if (ulCode ==               IOCTL_DISK_GET_LENGTH_INFO)
                   1848:                return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO");
                   1849:        else if (ulCode ==               IOCTL_STORAGE_GET_DEVICE_NUMBER)
                   1850:                return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER");
                   1851:        else if (ulCode ==               IOCTL_DISK_GET_PARTITION_INFO)
                   1852:                return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO");
                   1853:        else if (ulCode ==               IOCTL_DISK_GET_PARTITION_INFO_EX)
                   1854:                return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX");
                   1855:        else if (ulCode ==               IOCTL_DISK_SET_PARTITION_INFO)
                   1856:                return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO");
                   1857:        else if (ulCode ==               IOCTL_DISK_GET_DRIVE_LAYOUT)
                   1858:                return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT");
                   1859:        else if (ulCode ==               IOCTL_DISK_SET_DRIVE_LAYOUT_EX)
                   1860:                return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX");
                   1861:        else if (ulCode ==               IOCTL_DISK_VERIFY)
                   1862:                return (LPWSTR) _T ("IOCTL_DISK_VERIFY");
                   1863:        else if (ulCode == IOCTL_DISK_FORMAT_TRACKS)
                   1864:                return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS");
                   1865:        else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS)
                   1866:                return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS");
                   1867:        else if (ulCode == IOCTL_DISK_PERFORMANCE)
                   1868:                return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE");
                   1869:        else if (ulCode == IOCTL_DISK_IS_WRITABLE)
                   1870:                return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE");
                   1871:        else if (ulCode == IOCTL_DISK_LOGGING)
                   1872:                return (LPWSTR) _T ("IOCTL_DISK_LOGGING");
                   1873:        else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX)
                   1874:                return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX");
                   1875:        else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE)
                   1876:                return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE");
                   1877:        else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA)
                   1878:                return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA");
                   1879:        else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET)
                   1880:                return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET");
                   1881:        else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE)
                   1882:                return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE");
                   1883:        else if (ulCode == IOCTL_DISK_REQUEST_DATA)
                   1884:                return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA");
                   1885:        else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER)
                   1886:                return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER");
                   1887:        else if (ulCode == SMART_GET_VERSION)
                   1888:                return (LPWSTR) _T ("SMART_GET_VERSION");
                   1889:        else if (ulCode == SMART_SEND_DRIVE_COMMAND)
                   1890:                return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND");
                   1891:        else if (ulCode == SMART_RCV_DRIVE_DATA)
                   1892:                return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA");
                   1893:        else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY)
                   1894:                return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY");
                   1895:        else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY)
                   1896:                return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY");
                   1897:        else if (ulCode == IOCTL_DISK_CHECK_VERIFY)
                   1898:                return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY");
                   1899:        else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL)
                   1900:                return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL");
                   1901:        else if (ulCode == IOCTL_DISK_EJECT_MEDIA)
                   1902:                return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA");
                   1903:        else if (ulCode == IOCTL_DISK_LOAD_MEDIA)
                   1904:                return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA");
                   1905:        else if (ulCode == IOCTL_DISK_RESERVE)
                   1906:                return (LPWSTR) _T ("IOCTL_DISK_RESERVE");
                   1907:        else if (ulCode == IOCTL_DISK_RELEASE)
                   1908:                return (LPWSTR) _T ("IOCTL_DISK_RELEASE");
                   1909:        else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES)
                   1910:                return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES");
                   1911:        else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES)
                   1912:                return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES");
                   1913:        else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO)
                   1914:                return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO");
                   1915:        else if (ulCode == IRP_MJ_READ)
                   1916:                return (LPWSTR) _T ("IRP_MJ_READ");
                   1917:        else if (ulCode == IRP_MJ_WRITE)
                   1918:                return (LPWSTR) _T ("IRP_MJ_WRITE");
                   1919:        else if (ulCode == IRP_MJ_CREATE)
                   1920:                return (LPWSTR) _T ("IRP_MJ_CREATE");
                   1921:        else if (ulCode == IRP_MJ_CLOSE)
                   1922:                return (LPWSTR) _T ("IRP_MJ_CLOSE");
                   1923:        else if (ulCode == IRP_MJ_CLEANUP)
                   1924:                return (LPWSTR) _T ("IRP_MJ_CLEANUP");
                   1925:        else if (ulCode == IRP_MJ_FLUSH_BUFFERS)
                   1926:                return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS");
                   1927:        else if (ulCode == IRP_MJ_SHUTDOWN)
                   1928:                return (LPWSTR) _T ("IRP_MJ_SHUTDOWN");
                   1929:        else if (ulCode == IRP_MJ_DEVICE_CONTROL)
                   1930:                return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL");
                   1931:        else
                   1932:        {
1.1.1.12  root     1933:                return (LPWSTR) _T ("IOCTL");
1.1       root     1934:        }
                   1935: }
                   1936: 
                   1937: #endif
                   1938: 
                   1939: PDEVICE_OBJECT
                   1940: TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
                   1941: {
                   1942:        PDEVICE_OBJECT OldDeviceObject = DeviceObject;
                   1943:        UNICODE_STRING Win32NameString;
                   1944:        NTSTATUS ntStatus;
                   1945: 
                   1946:        Dump ("TCDeleteDeviceObject BEGIN\n");
                   1947: 
1.1.1.6   root     1948:        if (Extension->bRootDevice)
1.1       root     1949:        {
                   1950:                RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX);
1.1.1.4   root     1951:                ntStatus = IoDeleteSymbolicLink (&Win32NameString);
                   1952:                if (!NT_SUCCESS (ntStatus))
                   1953:                        Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus);
1.1       root     1954:        }
                   1955:        else
                   1956:        {
                   1957:                if (Extension->peThread != NULL)
1.1.1.12  root     1958:                        TCStopVolumeThread (DeviceObject, Extension);
1.1.1.14  root     1959: 
                   1960:                if (DeviceObject->ReferenceCount > 0)
                   1961:                        ReferencedDeviceDeleted = TRUE;
                   1962:                        
                   1963:                // Forced dismount does not set reference count to zero even if all open handles are closed
                   1964:                Dump ("Deleting device with ref count %ld\n", DeviceObject->ReferenceCount);
                   1965:                DeviceObject->ReferenceCount = 0;
1.1       root     1966:        }
                   1967: 
1.1.1.8   root     1968:        if (DeviceObject != NULL)
                   1969:                DeviceObject = DeviceObject->NextDevice;
                   1970: 
1.1       root     1971:        IoDeleteDevice (OldDeviceObject);
                   1972: 
                   1973:        Dump ("TCDeleteDeviceObject END\n");
                   1974:        return DeviceObject;
                   1975: }
                   1976: 
1.1.1.4   root     1977: 
1.1       root     1978: VOID
                   1979: TCUnloadDriver (PDRIVER_OBJECT DriverObject)
                   1980: {
                   1981:        PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
                   1982: 
                   1983:        Dump ("TCUnloadDriver BEGIN\n");
                   1984: 
1.1.1.15  root     1985:        UnmountAllDevices (NULL, DeviceObject, TRUE);
1.1.1.4   root     1986: 
1.1       root     1987:        /* Now walk the list of driver objects and get rid of them */
                   1988:        while (DeviceObject != (PDEVICE_OBJECT) NULL)
                   1989:        {
                   1990:                DeviceObject = TCDeleteDeviceObject (DeviceObject,
                   1991:                                (PEXTENSION) DeviceObject->DeviceExtension);
                   1992:        }
                   1993: 
1.1.1.11  root     1994:        WipeCache ();   
                   1995: 
1.1.1.12  root     1996:        if (IsBootDriveMounted())
                   1997:                TC_BUG_CHECK (STATUS_INVALID_DEVICE_STATE);
                   1998: 
1.1.1.15  root     1999:        EncryptionThreadPoolStop();
                   2000: 
1.1       root     2001:        Dump ("TCUnloadDriver END\n");
                   2002: }
1.1.1.4   root     2003: 
                   2004: 
                   2005: NTSTATUS
                   2006: TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode,
                   2007:                                   void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
                   2008: {
                   2009:        IO_STATUS_BLOCK ioStatusBlock;
                   2010:        NTSTATUS ntStatus;
                   2011:        PIRP irp;
                   2012:        PFILE_OBJECT fileObject;
                   2013:        PDEVICE_OBJECT deviceObject;
                   2014:        KEVENT event;
                   2015:        UNICODE_STRING name;
                   2016: 
                   2017:        RtlInitUnicodeString(&name, deviceName);
1.1.1.10  root     2018:        ntStatus = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
1.1.1.4   root     2019: 
                   2020:        if (ntStatus != STATUS_SUCCESS)
                   2021:                return ntStatus;
                   2022: 
                   2023:        KeInitializeEvent(&event, NotificationEvent, FALSE);
                   2024: 
                   2025:        irp = IoBuildDeviceIoControlRequest (IoControlCode,
                   2026:                                             deviceObject,
                   2027:                                             InputBuffer, InputBufferSize,
                   2028:                                             OutputBuffer, OutputBufferSize,
                   2029:                                             FALSE,
                   2030:                                             &event,
                   2031:                                             &ioStatusBlock);
                   2032: 
                   2033:        if (irp == NULL)
                   2034:        {
                   2035:                Dump ("IRP allocation failed\n");
1.1.1.11  root     2036:                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                   2037:                goto ret;
1.1.1.4   root     2038:        }
                   2039: 
                   2040:        ntStatus = IoCallDriver (deviceObject, irp);
                   2041:        if (ntStatus == STATUS_PENDING)
                   2042:        {
1.1.1.12  root     2043:                KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
1.1.1.4   root     2044:                ntStatus = ioStatusBlock.Status;
                   2045:        }
                   2046: 
1.1.1.11  root     2047: ret:
                   2048:        ObDereferenceObject (fileObject);
1.1.1.4   root     2049:        return ntStatus;
                   2050: }
                   2051: 
                   2052: 
1.1.1.12  root     2053: NTSTATUS SendDeviceIoControlRequest (PDEVICE_OBJECT deviceObject, ULONG ioControlCode, void *inputBuffer, int inputBufferSize, void *outputBuffer, int outputBufferSize)
                   2054: {
                   2055:        IO_STATUS_BLOCK ioStatusBlock;
                   2056:        NTSTATUS status;
                   2057:        PIRP irp;
                   2058:        KEVENT event;
                   2059: 
1.1.1.15  root     2060:        ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
1.1.1.12  root     2061: 
                   2062:        KeInitializeEvent (&event, NotificationEvent, FALSE);
                   2063: 
                   2064:        irp = IoBuildDeviceIoControlRequest (ioControlCode, deviceObject, inputBuffer, inputBufferSize,
                   2065:                outputBuffer, outputBufferSize, FALSE, &event, &ioStatusBlock);
                   2066: 
                   2067:        if (!irp)
                   2068:                return STATUS_INSUFFICIENT_RESOURCES;
                   2069: 
                   2070:        ObReferenceObject (deviceObject);
                   2071: 
                   2072:        status = IoCallDriver (deviceObject, irp);
                   2073:        if (status == STATUS_PENDING)
                   2074:        {
                   2075:                KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
                   2076:                status = ioStatusBlock.Status;
                   2077:        }
                   2078: 
                   2079:        ObDereferenceObject (deviceObject);
                   2080:        return status;
                   2081: }
                   2082: 
                   2083: 
                   2084: NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize)
                   2085: {
                   2086:        NTSTATUS status;
                   2087:        LARGE_INTEGER sysLength;
                   2088:        LARGE_INTEGER offset;
1.1.1.15  root     2089:        byte *sectorBuffer;
1.1.1.14  root     2090:        ULONGLONG startTime;
1.1.1.12  root     2091: 
1.1.1.15  root     2092:        if (!UserCanAccessDriveDevice())
                   2093:                return STATUS_ACCESS_DENIED;
                   2094: 
                   2095:        sectorBuffer = TCalloc (SECTOR_SIZE);
1.1.1.12  root     2096:        if (!sectorBuffer)
                   2097:                return STATUS_INSUFFICIENT_RESOURCES;
                   2098: 
                   2099:        status = SendDeviceIoControlRequest (driveDeviceObject, IOCTL_DISK_GET_LENGTH_INFO,
                   2100:                NULL, 0, &sysLength, sizeof (sysLength));
                   2101: 
                   2102:        if (!NT_SUCCESS (status))
                   2103:        {
                   2104:                Dump ("Failed to get drive size - error %x\n", status);
1.1.1.14  root     2105:                TCfree (sectorBuffer);
1.1.1.12  root     2106:                return status;
                   2107:        }
                   2108: 
1.1.1.14  root     2109:        startTime = KeQueryInterruptTime ();
1.1.1.12  root     2110:        for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += SECTOR_SIZE)
                   2111:        {
                   2112:                status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, SECTOR_SIZE);
1.1.1.13  root     2113:                
1.1.1.15  root     2114:                if (NT_SUCCESS (status))
                   2115:                        status = TCWriteDevice (driveDeviceObject, sectorBuffer, offset, SECTOR_SIZE);
                   2116: 
1.1.1.14  root     2117:                if (!NT_SUCCESS (status))
1.1.1.12  root     2118:                {
                   2119:                        driveSize->QuadPart = offset.QuadPart;
1.1.1.15  root     2120:                        Dump ("Real drive size = %I64d bytes (%I64d hidden)\n", driveSize->QuadPart, driveSize->QuadPart - sysLength.QuadPart);
1.1.1.12  root     2121:                        TCfree (sectorBuffer);
                   2122:                        return STATUS_SUCCESS;
                   2123:                }
1.1.1.14  root     2124: 
                   2125:                if (KeQueryInterruptTime() - startTime > 3ULL * 60 * 1000 * 1000 * 10)
                   2126:                {
                   2127:                        // Abort if probing for more than 3 minutes
                   2128:                        driveSize->QuadPart = sysLength.QuadPart;
                   2129:                        TCfree (sectorBuffer);
                   2130:                        return STATUS_TIMEOUT;
                   2131:                }
1.1.1.12  root     2132:        }
                   2133: }
                   2134: 
                   2135: 
1.1.1.4   root     2136: // Opens a mounted TC volume on filesystem level
                   2137: NTSTATUS
                   2138: TCOpenFsVolume (PEXTENSION Extension, PHANDLE volumeHandle, PFILE_OBJECT * fileObject)
                   2139: {
                   2140:        NTSTATUS ntStatus;
                   2141:        OBJECT_ATTRIBUTES objectAttributes;
                   2142:        UNICODE_STRING fullFileName;
                   2143:        IO_STATUS_BLOCK ioStatus;
1.1.1.7   root     2144:        WCHAR volumeName[TC_MAX_PATH];
1.1.1.4   root     2145: 
                   2146:        TCGetDosNameFromNumber (volumeName, Extension->nDosDriveNo);
                   2147:        RtlInitUnicodeString (&fullFileName, volumeName);
                   2148:        InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
                   2149: 
                   2150:        ntStatus = ZwCreateFile (volumeHandle,
                   2151:                SYNCHRONIZE | GENERIC_READ,
                   2152:                &objectAttributes,
                   2153:                &ioStatus,
                   2154:                NULL,
                   2155:                FILE_ATTRIBUTE_NORMAL,
                   2156:                FILE_SHARE_READ | FILE_SHARE_WRITE,
                   2157:                FILE_OPEN,
                   2158:                FILE_SYNCHRONOUS_IO_NONALERT,
                   2159:                NULL,
                   2160:                0);
                   2161: 
                   2162:        Dump ("Volume %ls open NTSTATUS 0x%08x\n", volumeName, ntStatus);
                   2163: 
                   2164:        if (!NT_SUCCESS (ntStatus))
                   2165:                return ntStatus;
                   2166: 
                   2167:        ntStatus = ObReferenceObjectByHandle (*volumeHandle,
                   2168:                FILE_READ_DATA,
                   2169:                NULL,
                   2170:                KernelMode,
                   2171:                fileObject,
                   2172:                NULL);
                   2173: 
                   2174:        Dump ("ObReferenceObjectByHandle NTSTATUS 0x%08x\n", ntStatus);
                   2175: 
                   2176:        if (!NT_SUCCESS (ntStatus))
                   2177:        {
                   2178:                ZwClose(*volumeHandle);
                   2179:                return ntStatus;
                   2180:        }
                   2181: 
                   2182:        return ntStatus;
                   2183: }
                   2184: 
                   2185: 
                   2186: void
                   2187: TCCloseFsVolume (HANDLE volumeHandle, PFILE_OBJECT fileObject)
                   2188: {
                   2189:        ObDereferenceObject (fileObject);
                   2190:        ZwClose (volumeHandle);
                   2191: }
                   2192: 
                   2193: 
1.1.1.12  root     2194: static NTSTATUS TCReadWriteDevice (BOOL write, PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length)
                   2195: {
                   2196:        NTSTATUS status;
                   2197:        IO_STATUS_BLOCK ioStatusBlock;
                   2198:        PIRP irp;
                   2199:        KEVENT completionEvent;
                   2200: 
1.1.1.15  root     2201:        ASSERT (KeGetCurrentIrql() <= APC_LEVEL);
1.1.1.12  root     2202: 
                   2203:        KeInitializeEvent (&completionEvent, NotificationEvent, FALSE);
                   2204:        irp = IoBuildSynchronousFsdRequest (write ? IRP_MJ_WRITE : IRP_MJ_READ, deviceObject, buffer, length, &offset, &completionEvent, &ioStatusBlock);
                   2205:        if (!irp)
                   2206:                return STATUS_INSUFFICIENT_RESOURCES;
                   2207: 
                   2208:        ObReferenceObject (deviceObject);
                   2209:        status = IoCallDriver (deviceObject, irp);
                   2210: 
                   2211:        if (status == STATUS_PENDING)
                   2212:        {
                   2213:                status = KeWaitForSingleObject (&completionEvent, Executive, KernelMode, FALSE, NULL);
                   2214:                if (NT_SUCCESS (status))
                   2215:                        status = ioStatusBlock.Status;
                   2216:        }
                   2217: 
                   2218:        ObDereferenceObject (deviceObject);
                   2219:        return status;
                   2220: }
                   2221: 
                   2222: 
                   2223: NTSTATUS TCReadDevice (PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length)
                   2224: {
                   2225:        return TCReadWriteDevice (FALSE, deviceObject, buffer, offset, length);
                   2226: }
                   2227: 
                   2228: 
                   2229: NTSTATUS TCWriteDevice (PDEVICE_OBJECT deviceObject, PVOID buffer, LARGE_INTEGER offset, ULONG length)
                   2230: {
                   2231:        return TCReadWriteDevice (TRUE, deviceObject, buffer, offset, length);
                   2232: }
                   2233: 
                   2234: 
1.1.1.4   root     2235: NTSTATUS
                   2236: TCFsctlCall (PFILE_OBJECT fileObject, LONG IoControlCode,
                   2237:        void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
                   2238: {
                   2239:        IO_STATUS_BLOCK ioStatusBlock;
                   2240:        NTSTATUS ntStatus;
                   2241:        PIRP irp;
                   2242:        KEVENT event;
                   2243:        PIO_STACK_LOCATION stack;
                   2244:        PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject);
                   2245: 
                   2246:        KeInitializeEvent(&event, NotificationEvent, FALSE);
                   2247: 
                   2248:        irp = IoBuildDeviceIoControlRequest (IoControlCode,
                   2249:                                             deviceObject,
                   2250:                                             InputBuffer, InputBufferSize,
                   2251:                                             OutputBuffer, OutputBufferSize,
                   2252:                                             FALSE,
                   2253:                                             &event,
                   2254:                                             &ioStatusBlock);
                   2255: 
                   2256:        if (irp == NULL)
                   2257:                return STATUS_INSUFFICIENT_RESOURCES;
                   2258: 
                   2259:        stack = IoGetNextIrpStackLocation(irp);
                   2260:        
                   2261:        stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
                   2262:        stack->MinorFunction = IRP_MN_USER_FS_REQUEST;
                   2263:        stack->FileObject = fileObject;
                   2264: 
                   2265:        ntStatus = IoCallDriver (deviceObject, irp);
                   2266:        if (ntStatus == STATUS_PENDING)
                   2267:        {
1.1.1.12  root     2268:                KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
1.1.1.4   root     2269:                ntStatus = ioStatusBlock.Status;
                   2270:        }
                   2271: 
                   2272:        return ntStatus;
                   2273: }
                   2274: 
                   2275: 
                   2276: NTSTATUS
1.1.1.6   root     2277: CreateDriveLink (int nDosDriveNo)
                   2278: {
1.1.1.15  root     2279:        WCHAR dev[128], link[128];
1.1.1.6   root     2280:        UNICODE_STRING deviceName, symLink;
                   2281:        NTSTATUS ntStatus;
                   2282: 
                   2283:        TCGetNTNameFromNumber (dev, nDosDriveNo);
                   2284:        TCGetDosNameFromNumber (link, nDosDriveNo);
                   2285: 
                   2286:        RtlInitUnicodeString (&deviceName, dev);
                   2287:        RtlInitUnicodeString (&symLink, link);
                   2288: 
                   2289:        ntStatus = IoCreateSymbolicLink (&symLink, &deviceName);
                   2290:        Dump ("IoCreateSymbolicLink returned %X\n", ntStatus);
                   2291:        return ntStatus;
                   2292: }
                   2293: 
                   2294: 
                   2295: NTSTATUS
                   2296: RemoveDriveLink (int nDosDriveNo)
                   2297: {
1.1.1.7   root     2298:        WCHAR link[256];
1.1.1.6   root     2299:        UNICODE_STRING symLink;
                   2300:        NTSTATUS ntStatus;
                   2301: 
                   2302:        TCGetDosNameFromNumber (link, nDosDriveNo);
                   2303:        RtlInitUnicodeString (&symLink, link);
                   2304: 
                   2305:        ntStatus = IoDeleteSymbolicLink (&symLink);
                   2306:        Dump ("IoDeleteSymbolicLink returned %X\n", ntStatus);
                   2307:        return ntStatus;
                   2308: }
                   2309: 
                   2310: 
                   2311: NTSTATUS
1.1.1.4   root     2312: MountManagerMount (MOUNT_STRUCT *mount)
                   2313: {
                   2314:        NTSTATUS ntStatus; 
1.1.1.7   root     2315:        WCHAR arrVolume[256];
1.1.1.4   root     2316:        char buf[200];
                   2317:        PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf;
                   2318:        PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf;
                   2319:        UNICODE_STRING symName, devName;
                   2320: 
                   2321:        TCGetNTNameFromNumber (arrVolume, mount->nDosDriveNo);
                   2322:        in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2;
                   2323:        wcscpy(in->DeviceName, arrVolume);
                   2324: 
                   2325:        ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
                   2326:                in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0);
                   2327: 
                   2328:        memset (buf, 0, sizeof buf);
                   2329:        TCGetDosNameFromNumber ((PWSTR) &point[1], mount->nDosDriveNo);
                   2330: 
                   2331:        point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
                   2332:        point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;
                   2333: 
                   2334:        RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset));
                   2335: 
                   2336:        point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength;
                   2337:        TCGetNTNameFromNumber ((PWSTR) (buf + point->DeviceNameOffset), mount->nDosDriveNo);
                   2338:        point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2;
                   2339: 
                   2340:        RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset));
                   2341: 
                   2342:        ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point,
                   2343:                point->DeviceNameOffset + point->DeviceNameLength, 0, 0);
                   2344: 
                   2345:        return ntStatus;
                   2346: }
                   2347: 
                   2348: 
                   2349: NTSTATUS
                   2350: MountManagerUnmount (int nDosDriveNo)
                   2351: {
                   2352:        NTSTATUS ntStatus; 
1.1.1.7   root     2353:        char buf[256], out[300];
1.1.1.4   root     2354:        PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf;
                   2355: 
                   2356:        memset (buf, 0, sizeof buf);
                   2357: 
                   2358:        TCGetDosNameFromNumber ((PWSTR) &in[1], nDosDriveNo);
                   2359: 
                   2360:        in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
                   2361:        in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2;
                   2362: 
                   2363:        ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS,
                   2364:                in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out);
                   2365: 
                   2366:        Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus);
                   2367: 
                   2368:        return ntStatus;
                   2369: }
                   2370: 
                   2371: 
                   2372: NTSTATUS
                   2373: MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount)
                   2374: {
                   2375:        PDEVICE_OBJECT NewDeviceObject;
                   2376:        NTSTATUS ntStatus;
                   2377: 
1.1.1.6   root     2378:        /* Make sure the user is asking for a reasonable 
1.1.1.4   root     2379:        nDosDriveNo */
1.1.1.15  root     2380:        if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25 && IsDriveLetterAvailable (mount->nDosDriveNo))
1.1.1.4   root     2381:        {
                   2382:                Dump ("Mount request looks valid\n");
                   2383:        }
                   2384:        else
                   2385:        {
                   2386:                Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n");
1.1.1.10  root     2387:                mount->nReturnCode = ERR_DRIVE_NOT_FOUND;
                   2388:                return ERR_DRIVE_NOT_FOUND;
1.1.1.4   root     2389:        }
                   2390: 
1.1.1.6   root     2391:        if (!SelfTestsPassed)
                   2392:        {
                   2393:                mount->nReturnCode = ERR_SELF_TESTS_FAILED;
                   2394:                return ERR_SELF_TESTS_FAILED;
                   2395:        }
                   2396: 
1.1.1.4   root     2397:        ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
                   2398:                mount);
                   2399:        if (!NT_SUCCESS (ntStatus))
                   2400:        {
                   2401:                Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
                   2402:                return ntStatus;
                   2403:        }
                   2404:        else
                   2405:        {
                   2406:                PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension;
1.1.1.12  root     2407:                ntStatus = TCStartVolumeThread (NewDeviceObject, NewExtension, mount);
1.1.1.4   root     2408:                if (!NT_SUCCESS (ntStatus))
                   2409:                {
                   2410:                        Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus);
                   2411:                        TCDeleteDeviceObject (NewDeviceObject, NewExtension);
                   2412:                        return ntStatus;
                   2413:                }
                   2414:                else
                   2415:                {
                   2416:                        if (mount->nReturnCode == 0)
                   2417:                        {
                   2418:                                Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode,
                   2419:                                        NewExtension->bReadOnly);
1.1.1.6   root     2420:                                if (NewExtension->bReadOnly)
1.1.1.4   root     2421:                                        NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
                   2422:                                NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
                   2423: 
1.1.1.6   root     2424:                                NewExtension->UniqueVolumeId = LastUniqueVolumeId++;
                   2425: 
1.1.1.4   root     2426:                                if (mount->bMountManager)
                   2427:                                        MountManagerMount (mount);
                   2428: 
1.1.1.6   root     2429:                                NewExtension->bMountManager = mount->bMountManager;
1.1.1.4   root     2430: 
1.1.1.6   root     2431:                                // We create symbolic link even if mount manager is notified of
                   2432:                                // arriving volume as it apparently sometimes fails to create the link
                   2433:                                CreateDriveLink (mount->nDosDriveNo);
1.1.1.4   root     2434:                        }
                   2435:                        else
                   2436:                        {
                   2437:                                Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode);
                   2438:                                TCDeleteDeviceObject (NewDeviceObject, NewExtension);
                   2439:                        }
                   2440:                        
                   2441:                        return STATUS_SUCCESS;
                   2442:                }
                   2443:        }
                   2444: }
                   2445: 
                   2446: NTSTATUS
1.1.1.15  root     2447: UnmountDevice (UNMOUNT_STRUCT *unmountRequest, PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles)
1.1.1.4   root     2448: {
                   2449:        PEXTENSION extension = deviceObject->DeviceExtension;
                   2450:        NTSTATUS ntStatus;
                   2451:        HANDLE volumeHandle;
                   2452:        PFILE_OBJECT volumeFileObject;
                   2453: 
1.1.1.8   root     2454:        Dump ("UnmountDevice %d\n", extension->nDosDriveNo);
                   2455: 
1.1.1.4   root     2456:        ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
                   2457:        if (!NT_SUCCESS (ntStatus))
1.1.1.6   root     2458:        {
                   2459:                // User may have deleted symbolic link
                   2460:                CreateDriveLink (extension->nDosDriveNo);
                   2461: 
                   2462:                ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);
                   2463:        }
                   2464: 
1.1.1.8   root     2465:        if (NT_SUCCESS (ntStatus))
                   2466:        {
1.1.1.15  root     2467:                int dismountRetry;
                   2468: 
1.1.1.8   root     2469:                // Lock volume
                   2470:                ntStatus = TCFsctlCall (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
                   2471:                Dump ("FSCTL_LOCK_VOLUME returned %X\n", ntStatus);
                   2472: 
                   2473:                if (!NT_SUCCESS (ntStatus) && !ignoreOpenFiles)
                   2474:                {
                   2475:                        TCCloseFsVolume (volumeHandle, volumeFileObject);
                   2476:                        return ERR_FILES_OPEN;
                   2477:                }
1.1.1.4   root     2478: 
1.1.1.8   root     2479:                // Dismount volume
1.1.1.15  root     2480:                for (dismountRetry = 0; dismountRetry < 50; ++dismountRetry)
                   2481:                {
                   2482:                        ntStatus = TCFsctlCall (volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
                   2483:                        Dump ("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus);
                   2484: 
                   2485:                        if (NT_SUCCESS (ntStatus))
                   2486:                                break;
                   2487: 
                   2488:                        TCSleep (100);
                   2489:                }
1.1.1.8   root     2490:        }
                   2491:        else 
1.1.1.4   root     2492:        {
1.1.1.8   root     2493:                // Volume cannot be opened => force dismount if allowed
                   2494:                if (!ignoreOpenFiles)
                   2495:                        return ERR_FILES_OPEN;
                   2496:                else
                   2497:                        volumeHandle = NULL;
1.1.1.4   root     2498:        }
                   2499: 
                   2500:        if (extension->bMountManager)
                   2501:                MountManagerUnmount (extension->nDosDriveNo);
1.1.1.8   root     2502: 
1.1.1.6   root     2503:        // We always remove symbolic link as mount manager might fail to do so
                   2504:        RemoveDriveLink (extension->nDosDriveNo);
1.1.1.4   root     2505: 
1.1.1.10  root     2506:        extension->bShuttingDown = TRUE;
                   2507: 
1.1.1.8   root     2508:        if (volumeHandle != NULL)
                   2509:                TCCloseFsVolume (volumeHandle, volumeFileObject);
1.1.1.4   root     2510: 
1.1.1.15  root     2511:        if (unmountRequest)
                   2512:        {
                   2513:                PCRYPTO_INFO cryptoInfo = ((PEXTENSION) deviceObject->DeviceExtension)->cryptoInfo;
                   2514:                unmountRequest->HiddenVolumeProtectionTriggered = (cryptoInfo->bProtectHiddenVolume && cryptoInfo->bHiddenVolProtectionAction);
                   2515:        }
                   2516: 
1.1.1.4   root     2517:        TCDeleteDeviceObject (deviceObject, (PEXTENSION) deviceObject->DeviceExtension);
                   2518:        return 0;
                   2519: }
                   2520: 
                   2521: NTSTATUS
1.1.1.15  root     2522: UnmountAllDevices (UNMOUNT_STRUCT *unmountRequest, PDEVICE_OBJECT DeviceObject, BOOL ignoreOpenFiles)
1.1.1.4   root     2523: {
                   2524:        NTSTATUS status = 0;
                   2525:        PDEVICE_OBJECT ListDevice;
                   2526: 
                   2527:        Dump ("Unmounting all volumes\n");
                   2528: 
1.1.1.9   root     2529:        if (!DeviceObject || !DeviceObject->DriverObject)
                   2530:                return STATUS_INVALID_PARAMETER;
                   2531: 
1.1.1.5   root     2532:        DriverMutexWait ();
                   2533: 
1.1.1.10  root     2534:        ListDevice = DeviceObject->DriverObject->DeviceObject;
                   2535:        while (ListDevice != NULL)
1.1.1.4   root     2536:        {
                   2537:                PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
1.1.1.15  root     2538:                if (!ListExtension->bRootDevice && ListExtension->IsVolumeDevice && !ListExtension->bShuttingDown)
1.1.1.4   root     2539:                {
1.1.1.12  root     2540:                        PDEVICE_OBJECT nextDevice = ListDevice->NextDevice;
1.1.1.15  root     2541:                        NTSTATUS ntStatus;
                   2542: 
                   2543:                        if (unmountRequest)
                   2544:                                unmountRequest->nDosDriveNo = ListExtension->nDosDriveNo;
1.1.1.10  root     2545: 
1.1.1.15  root     2546:                        ntStatus = UnmountDevice (unmountRequest, ListDevice, ignoreOpenFiles);
1.1.1.12  root     2547:                        status = ntStatus == 0 ? status : ntStatus;
1.1.1.10  root     2548: 
1.1.1.15  root     2549:                        if (unmountRequest && unmountRequest->HiddenVolumeProtectionTriggered)
                   2550:                                break;
                   2551: 
1.1.1.12  root     2552:                        ListDevice = nextDevice;
                   2553:                        continue;
1.1.1.4   root     2554:                }
1.1.1.8   root     2555: 
1.1.1.10  root     2556:                ListDevice = ListDevice->NextDevice;
1.1.1.4   root     2557:        }
                   2558: 
1.1.1.5   root     2559:        DriverMutexRelease ();
1.1.1.4   root     2560:        return status;
                   2561: }
                   2562: 
                   2563: // Resolves symbolic link name to its target name
                   2564: NTSTATUS
                   2565: SymbolicLinkToTarget (PWSTR symlinkName, PWSTR targetName, USHORT maxTargetNameLength)
                   2566: {
                   2567:        NTSTATUS ntStatus;
                   2568:        OBJECT_ATTRIBUTES objectAttributes;
                   2569:        UNICODE_STRING fullFileName;
                   2570:        HANDLE handle;
                   2571: 
                   2572:        RtlInitUnicodeString (&fullFileName, symlinkName);
1.1.1.15  root     2573:        InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
1.1.1.4   root     2574: 
                   2575:        ntStatus = ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes);
                   2576: 
                   2577:        if (NT_SUCCESS (ntStatus))
                   2578:        {
                   2579:                UNICODE_STRING target;
                   2580:                target.Buffer = targetName;
                   2581:                target.Length = 0;
                   2582:                target.MaximumLength = maxTargetNameLength;
                   2583:                memset (targetName, 0, maxTargetNameLength);
                   2584: 
                   2585:                ntStatus = ZwQuerySymbolicLinkObject (handle, &target, NULL);
                   2586: 
                   2587:                ZwClose (handle);
                   2588:        }
                   2589: 
                   2590:        return ntStatus;
                   2591: }
1.1.1.6   root     2592: 
1.1.1.15  root     2593: 
1.1.1.6   root     2594: // Checks if two regions overlap (borders are parts of regions)
                   2595: BOOL RegionsOverlap (unsigned __int64 start1, unsigned __int64 end1, unsigned __int64 start2, unsigned __int64 end2)
                   2596: {
                   2597:        return (start1 < start2) ? (end1 >= start2) : (start1 <= end2);
                   2598: }
1.1.1.12  root     2599: 
                   2600: 
                   2601: void GetIntersection (uint64 start1, uint32 length1, uint64 start2, uint64 end2, uint64 *intersectStart, uint32 *intersectLength)
                   2602: {
                   2603:        uint64 end1 = start1 + length1 - 1;
                   2604:        uint64 intersectEnd = (end1 <= end2) ? end1 : end2;
                   2605:        
                   2606:        *intersectStart = (start1 >= start2) ? start1 : start2;
                   2607:        *intersectLength = (uint32) ((*intersectStart > intersectEnd) ? 0 : intersectEnd + 1 - *intersectStart);
                   2608:        
                   2609:        if (*intersectLength == 0)
                   2610:                *intersectStart = start1;
                   2611: }
                   2612: 
                   2613: 
                   2614: BOOL IsAccessibleByUser (PUNICODE_STRING objectFileName, BOOL readOnly)
                   2615: {
                   2616:        OBJECT_ATTRIBUTES fileObjAttributes;
                   2617:        IO_STATUS_BLOCK ioStatusBlock;
                   2618:        HANDLE fileHandle;
                   2619:        NTSTATUS status;
                   2620: 
                   2621:        ASSERT (!IoIsSystemThread (PsGetCurrentThread()));
                   2622: 
                   2623:        InitializeObjectAttributes (&fileObjAttributes, objectFileName, OBJ_CASE_INSENSITIVE | OBJ_FORCE_ACCESS_CHECK, NULL, NULL);
                   2624:        
                   2625:        status = ZwCreateFile (&fileHandle,
                   2626:                readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
                   2627:                &fileObjAttributes,
                   2628:                &ioStatusBlock,
                   2629:                NULL,
                   2630:                FILE_ATTRIBUTE_NORMAL,
                   2631:                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                   2632:                FILE_OPEN,
                   2633:                FILE_SYNCHRONOUS_IO_NONALERT,
                   2634:                NULL,
                   2635:                0);
                   2636: 
                   2637:        if (NT_SUCCESS (status))
                   2638:        {
                   2639:                ZwClose (fileHandle);
                   2640:                return TRUE;
                   2641:        }
                   2642: 
                   2643:        return FALSE;
                   2644: }
                   2645: 
                   2646: 
1.1.1.14  root     2647: BOOL UserCanAccessDriveDevice ()
                   2648: {
                   2649:        UNICODE_STRING name;
                   2650:        RtlInitUnicodeString (&name, L"\\Device\\MountPointManager");
                   2651: 
                   2652:        return IsAccessibleByUser (&name, FALSE);
                   2653: }
                   2654: 
                   2655: 
1.1.1.15  root     2656: BOOL IsDriveLetterAvailable (int nDosDriveNo)
                   2657: {
                   2658:        OBJECT_ATTRIBUTES objectAttributes;
                   2659:        UNICODE_STRING objectName;
                   2660:        WCHAR link[128];
                   2661:        HANDLE handle;
                   2662: 
                   2663:        TCGetDosNameFromNumber (link, nDosDriveNo);
                   2664:        RtlInitUnicodeString (&objectName, link);
                   2665:        InitializeObjectAttributes (&objectAttributes, &objectName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
                   2666: 
                   2667:        if (NT_SUCCESS (ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes)))
                   2668:        {
                   2669:                ZwClose (handle);
                   2670:                return FALSE;
                   2671:        }
                   2672: 
                   2673:        return TRUE;
                   2674: }
                   2675: 
                   2676: 
1.1.1.12  root     2677: NTSTATUS TCCompleteIrp (PIRP irp, NTSTATUS status, ULONG_PTR information)
                   2678: {
                   2679:        irp->IoStatus.Status = status;
                   2680:        irp->IoStatus.Information = information;
                   2681:        IoCompleteRequest (irp, IO_NO_INCREMENT);
                   2682:        return status;
                   2683: }
                   2684: 
                   2685: 
                   2686: NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information)
                   2687: {
                   2688:        irp->IoStatus.Status = status;
                   2689:        irp->IoStatus.Information = information;
                   2690:        IoCompleteRequest (irp, NT_SUCCESS (status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
                   2691:        return status;
                   2692: }
1.1.1.15  root     2693: 
                   2694: 
                   2695: size_t GetCpuCount ()
                   2696: {
                   2697:        KAFFINITY activeCpuMap = KeQueryActiveProcessors();
                   2698:        size_t mapSize = sizeof (activeCpuMap) * 8;
                   2699:        size_t cpuCount = 0;
                   2700: 
                   2701:        while (mapSize--)
                   2702:        {
                   2703:                if (activeCpuMap & 1)
                   2704:                        ++cpuCount;
                   2705: 
                   2706:                activeCpuMap >>= 1;
                   2707:        }
                   2708: 
                   2709:        if (cpuCount == 0)
                   2710:                return 1;
                   2711: 
                   2712:        return cpuCount;
                   2713: }
                   2714: 
                   2715: 
                   2716: void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes)
                   2717: {
                   2718:        ASSERT ((maxSizeInBytes & 1) == 0);
                   2719:        str[maxSizeInBytes / sizeof (wchar_t) - 1] = 0;
                   2720: }
                   2721: 
                   2722: 
                   2723: void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout)
                   2724: {
                   2725:        LARGE_INTEGER waitInterval;
                   2726:        waitInterval.QuadPart = retryDelay * -10000;
                   2727: 
                   2728:        ASSERT (KeGetCurrentIrql() <= APC_LEVEL);
                   2729:        ASSERT (retryDelay > 0 && retryDelay <= timeout);
                   2730: 
                   2731:        while (TRUE)
                   2732:        {
                   2733:                void *memory = TCalloc (size);
                   2734:                if (memory)
                   2735:                        return memory;
                   2736: 
                   2737:                timeout -= retryDelay;
                   2738:                if (timeout <= 0)
                   2739:                        break;
                   2740: 
                   2741:                KeDelayExecutionThread (KernelMode, FALSE, &waitInterval);
                   2742:        }
                   2743: 
                   2744:        return NULL;
                   2745: }
                   2746: 
                   2747: 
                   2748: NTSTATUS TCReadRegistryKey (PUNICODE_STRING keyPath, wchar_t *keyValueName, PKEY_VALUE_PARTIAL_INFORMATION *keyData)
                   2749: {
                   2750:        OBJECT_ATTRIBUTES regObjAttribs;
                   2751:        HANDLE regKeyHandle;
                   2752:        NTSTATUS status;
                   2753:        UNICODE_STRING valName;
                   2754:        ULONG size = 0;
                   2755:        ULONG resultSize;
                   2756: 
                   2757:        InitializeObjectAttributes (&regObjAttribs, keyPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
                   2758:        status = ZwOpenKey (&regKeyHandle, KEY_READ, &regObjAttribs);
                   2759:        if (!NT_SUCCESS (status))
                   2760:                return status;
                   2761: 
                   2762:        RtlInitUnicodeString (&valName, keyValueName);
                   2763:        status = ZwQueryValueKey (regKeyHandle, &valName, KeyValuePartialInformation, NULL, 0, &size);
                   2764:                
                   2765:        if (status != STATUS_SUCCESS && status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL)
                   2766:        {
                   2767:                ZwClose (regKeyHandle);
                   2768:                return status;
                   2769:        }
                   2770: 
                   2771:        if (size == 0)
                   2772:        {
                   2773:                ZwClose (regKeyHandle);
                   2774:                return STATUS_NO_DATA_DETECTED;
                   2775:        }
                   2776: 
                   2777:        *keyData = (PKEY_VALUE_PARTIAL_INFORMATION) TCalloc (size);
                   2778:        if (!*keyData)
                   2779:        {
                   2780:                ZwClose (regKeyHandle);
                   2781:                return STATUS_INSUFFICIENT_RESOURCES;
                   2782:        }
                   2783: 
                   2784:        status = ZwQueryValueKey (regKeyHandle, &valName, KeyValuePartialInformation, *keyData, size, &resultSize);
                   2785: 
                   2786:        ZwClose (regKeyHandle);
                   2787:        return status;
                   2788: }
                   2789: 
                   2790: 
                   2791: NTSTATUS TCWriteRegistryKey (PUNICODE_STRING keyPath, wchar_t *keyValueName, ULONG keyValueType, void *valueData, ULONG valueSize)
                   2792: {
                   2793:        OBJECT_ATTRIBUTES regObjAttribs;
                   2794:        HANDLE regKeyHandle;
                   2795:        NTSTATUS status;
                   2796:        UNICODE_STRING valName;
                   2797: 
                   2798:        InitializeObjectAttributes (&regObjAttribs, keyPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
                   2799:        status = ZwOpenKey (&regKeyHandle, KEY_READ | KEY_WRITE, &regObjAttribs);
                   2800:        if (!NT_SUCCESS (status))
                   2801:                return status;
                   2802: 
                   2803:        RtlInitUnicodeString (&valName, keyValueName);
                   2804: 
                   2805:        status = ZwSetValueKey (regKeyHandle, &valName, keyValueType, keyValueType, valueData, valueSize);
                   2806: 
                   2807:        ZwClose (regKeyHandle);
                   2808:        return status;
                   2809: }
                   2810: 
                   2811: 
                   2812: BOOL IsVolumeClassFilterRegistered ()
                   2813: {
                   2814:        UNICODE_STRING name;
                   2815:        NTSTATUS status;
                   2816:        BOOL registered = FALSE;
                   2817: 
                   2818:        PKEY_VALUE_PARTIAL_INFORMATION data;
                   2819: 
                   2820:        RtlInitUnicodeString (&name, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{71A27CDD-812A-11D0-BEC7-08002BE2092F}");
                   2821:        status = TCReadRegistryKey (&name, L"UpperFilters", &data);
                   2822: 
                   2823:        if (NT_SUCCESS (status))
                   2824:        {
                   2825:                if (data->Type == REG_MULTI_SZ && data->DataLength >= 9 * sizeof (wchar_t))
                   2826:                {
                   2827:                        // Search for the string "truecrypt"
                   2828:                        ULONG i;
                   2829:                        for (i = 0; i <= data->DataLength - 9 * sizeof (wchar_t); ++i)
                   2830:                        {
                   2831:                                if (memcmp (data->Data + i, L"truecrypt", 9 * sizeof (wchar_t)) == 0)
                   2832:                                {
                   2833:                                        Dump ("Volume class filter active\n");
                   2834:                                        registered = TRUE;
                   2835:                                        break;
                   2836:                                }
                   2837:                        }
                   2838:                }
                   2839: 
                   2840:                TCfree (data);
                   2841:        }
                   2842: 
                   2843:        return registered;
                   2844: }
                   2845: 
                   2846: 
                   2847: uint32 ReadRegistryConfigFlags ()
                   2848: {
                   2849:        PKEY_VALUE_PARTIAL_INFORMATION data;
                   2850:        UNICODE_STRING name;
                   2851:        NTSTATUS status;
                   2852:        uint32 flags = 0;
                   2853: 
                   2854:        RtlInitUnicodeString (&name, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\truecrypt");
                   2855:        status = TCReadRegistryKey (&name, TC_DRIVER_CONFIG_REG_VALUE_NAME, &data);
                   2856: 
                   2857:        if (NT_SUCCESS (status))
                   2858:        {
                   2859:                if (data->Type == REG_DWORD)
                   2860:                {
                   2861:                        flags = *(uint32 *) data->Data;
                   2862:                        Dump ("Configuration flags = 0x%x\n", flags);
                   2863:                }
                   2864: 
                   2865:                TCfree (data);
                   2866:        }
                   2867: 
                   2868:        return flags;
                   2869: }
                   2870: 
                   2871: 
                   2872: NTSTATUS WriteRegistryConfigFlags (uint32 flags)
                   2873: {
                   2874:        UNICODE_STRING name;
                   2875:        RtlInitUnicodeString (&name, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\truecrypt");
                   2876: 
                   2877:        return TCWriteRegistryKey (&name, TC_DRIVER_CONFIG_REG_VALUE_NAME, REG_DWORD, &flags, sizeof (flags));
                   2878: }

unix.superglobalmegacorp.com

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