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

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

unix.superglobalmegacorp.com

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