freeotfehashdriver.c

来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 1,396 行 · 第 1/4 页

C
1,396
字号

    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("FreeOTFE_MF_DispatchClose\n"));
    
    return STATUS_SUCCESS;
}


// =========================================================================
// Handle device control IRPs
NTSTATUS
FreeOTFE_MF_DispatchDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    PDEVICE_EXTENSION devExt;
    PIO_STACK_LOCATION irpSp;
    NTSTATUS status;
    PDEVICE_OBJECT queueDeviceObject = NULL;
    
    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("FreeOTFE_MF_DispatchDeviceControl\n"));
    
    
    devExt = DeviceObject->DeviceExtension;
    irpSp = IoGetCurrentIrpStackLocation(Irp);

    status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;


    switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
        {
        case IOCTL_FREEOTFEHASH_IDENTIFYDRIVER:
            {
            status = IOCTL_FreeOTFEHashIOCTL_IdentifyDriver(DeviceObject, Irp);
            break;
            }


        case IOCTL_FREEOTFEHASH_IDENTIFYSUPPORTED:
            {
            status = IOCTL_FreeOTFEHashIOCTL_IdentifySupported(DeviceObject, Irp);
            break;
            }


        case IOCTL_FREEOTFEHASH_HASHDATA:
            {
            queueDeviceObject = DeviceObject;
            break;
            }


        case IOCTL_FREEOTFEHASH_INTLDETAILS:
            {
            status = IOCTL_FreeOTFEHashIOCTL_IntlDetails(DeviceObject, Irp);
            break;
            }


        default:
            {
            DEBUGOUTHASHDRV(DEBUGLEV_WARN, ("IoControl code is UNRECOGNISED (%x).\n",
                        irpSp->Parameters.DeviceIoControl.IoControlCode));
            status = STATUS_NOT_IMPLEMENTED;
            }
        }
        
        
    // If we want to queue the IRP, this should have been flagged,
    // otherwise we complete the reqest
    if (queueDeviceObject != NULL)
        {
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Queuing IRP...\n"));
        status = QueueIRPToThread(queueDeviceObject, Irp);    

        // Check if the IRP was queued successfully...
        if (status == STATUS_PENDING)
            {
            // Note: IoCsqInsertIrp in QueueIRPToThread marks the IRP pending.
            DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Queued IRP.\n"));
            }
        else
            {
            Irp->IoStatus.Status = status;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Failed to queue IRP.\n"));
            }

        }
    else
        {
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Completing IRP...\n"));
        // If there was a failure, return nothing; this will be set as appropriate if there
        // is no problem
        if (!(NT_SUCCESS(status)))
            {
            Irp->IoStatus.Information = 0;
            }                
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));
        }

    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("FreeOTFE_MF_DispatchDeviceControl\n"));
    
    return status;
}



// =========================================================================
// IOCTL to obtain function pointers to encrypt, decrypt functions
// Technique as described in:            
// The NT Insider, Vol 7, Issue 1, Jan-Feb 2000
// Beyond IRPs: Driver to Driver Communications 
// http://www.osronline.com/article.cfm?id=177
NTSTATUS
IOCTL_FreeOTFEHashIOCTL_IntlDetails(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PDIOC_HASH_INTLDETAILS DIOCBuffer;

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEHashIOCTL_IntlDetails\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);


    // Check size of OUTPUT buffer
    if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof(DIOC_HASH_INTLDETAILS))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect: %d; got: %d)\n",
            sizeof(DIOC_HASH_INTLDETAILS),
            irpSp->Parameters.DeviceIoControl.OutputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }
        
    // Request valid, process...
    DIOCBuffer = (PDIOC_HASH_INTLDETAILS)Irp->AssociatedIrp.SystemBuffer;

    // Populate output buffer with with function pointers;
    DIOCBuffer->FnHash        = ImpHashHashData;
    DIOCBuffer->FnHashDetails = GetHashDetails;    

    Irp->IoStatus.Information = sizeof(DIOC_HASH_INTLDETAILS);
    status = STATUS_SUCCESS;


    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFEHashIOCTL_IntlDetails\n"));
    return status;
}


// =========================================================================
// IOCTL to get hash driver identification
NTSTATUS
IOCTL_FreeOTFEHashIOCTL_IdentifyDriver(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpSp;
    PDIOC_HASH_IDENTIFYDRIVER DIOCBuffer;
    PDEVICE_EXTENSION devExt;

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEHashIOCTL_IdentifyDriver\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);


    // Check size of OUTPUT buffer
    if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof(DIOC_HASH_IDENTIFYDRIVER))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect: %d; got: %d)\n",
            sizeof(DIOC_HASH_IDENTIFYDRIVER),
            irpSp->Parameters.DeviceIoControl.OutputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }
        
    // Request valid, process...
    devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

    DIOCBuffer = (PDIOC_HASH_IDENTIFYDRIVER)Irp->AssociatedIrp.SystemBuffer;

    // Populate output buffer
    DIOCBuffer->DriverGUID = devExt->DriverInfo.DriverGUID;
    RtlZeroMemory(DIOCBuffer->Title, sizeof(DIOCBuffer->Title));
    RtlCopyMemory(
                  DIOCBuffer->Title,
                  devExt->DriverInfo.DriverTitle,
                  strlen(devExt->DriverInfo.DriverTitle)
                 );
    DIOCBuffer->VersionID = devExt->DriverInfo.DriverVersionID;
    DIOCBuffer->CountHashes = devExt->DriverInfo.HashCount;


    Irp->IoStatus.Information = sizeof(DIOC_HASH_IDENTIFYDRIVER);


    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFEHashIOCTL_IdentifyDriver\n"));

    return status;
}


// =========================================================================
// IOCTL to get hashes supported
NTSTATUS
IOCTL_FreeOTFEHashIOCTL_IdentifySupported(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpSp;
    PDIOC_HASH_IDENTIFYSUPPORTED DIOCBuffer;
    PDEVICE_EXTENSION devExt;

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEHashIOCTL_IdentifySupported\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);

    DIOCBuffer = (PDIOC_HASH_IDENTIFYSUPPORTED)Irp->AssociatedIrp.SystemBuffer;

    // Check size of OUTPUT buffer
    if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof(DIOC_HASH_IDENTIFYSUPPORTED)-sizeof(DIOCBuffer->Hashes))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect min: %d; got: %d)\n",
            sizeof(DIOC_HASH_IDENTIFYSUPPORTED)-sizeof(DIOCBuffer->Hashes),
            irpSp->Parameters.DeviceIoControl.OutputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }

        
    // Setup the input parameter passed to ImpHashIdentifySupported, so that it's aware
    // of how large the array of hash details is
    DIOCBuffer->BufCount =
       (
         // The size of the buffer, less the array of hash details
         irpSp->Parameters.DeviceIoControl.OutputBufferLength - 
           (sizeof(DIOC_HASH_IDENTIFYSUPPORTED)-sizeof(DIOCBuffer->Hashes))
       ) /
       // Divide by the size of each hash details struct to give the array length
       sizeof(DIOCBuffer->Hashes);
       
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Request is sufficiently large to store %d hash details\n", DIOCBuffer->BufCount));

    devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

    if (DIOCBuffer->BufCount < devExt->DriverInfo.HashCount)
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("outBuffer not large enough to store enough (can store: %d, requires: )\n",
            DIOCBuffer->BufCount,
            devExt->DriverInfo.HashCount
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;
        }

    // Request valid, process...


    DIOCBuffer->BufCount = devExt->DriverInfo.HashCount;
    RtlCopyMemory(
                  &DIOCBuffer->Hashes[0],
                  devExt->DriverInfo.HashDetails,
                  (sizeof(HASH) * devExt->DriverInfo.HashCount)
                 );
    

    Irp->IoStatus.Information = sizeof(DIOC_HASH_IDENTIFYSUPPORTED)+(DIOCBuffer->BufCount * sizeof(DIOCBuffer->Hashes))-sizeof(DIOCBuffer->Hashes);


    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFEHashIOCTL_IdentifySupported\n"));

    return status;
}


// =========================================================================
// IOCTL to hash data
NTSTATUS
IOCTL_FreeOTFEHashIOCTL_Hash(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PDIOC_HASH_DATA_IN DIOCBufferIn;
    PDIOC_HASH_DATA_OUT DIOCBufferOut;
    unsigned char* tmpOutput;
    unsigned int tmpLengthBits;  // In *bits*
    int userBufferSizeBytes;  // In *bytes*

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEHashIOCTL_Hash\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);

    DIOCBufferIn = (PDIOC_HASH_DATA_IN)Irp->AssociatedIrp.SystemBuffer;
    DIOCBufferOut = (PDIOC_HASH_DATA_OUT)Irp->AssociatedIrp.SystemBuffer;

    // Check size of INPUT buffer
    // Minimum check...
    // (Done first in order to ensure that we can later access "length" parts
    // for actual check)
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(DIOC_HASH_DATA_IN)-sizeof(DIOCBufferIn->Data))            
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect min: %d; got: %d)\n",
            sizeof(DIOC_HASH_DATA_IN)-sizeof(DIOCBufferIn->Data),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }
    // Actual check...
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(DIOC_HASH_DATA_IN)+(DIOCBufferIn->DataLength/8)-sizeof(DIOCBufferIn->Data))            
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect actual: %d; got: %d)\n",
            sizeof(DIOC_HASH_DATA_IN)+(DIOCBufferIn->DataLength/8)-sizeof(DIOCBufferIn->Data),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }


    // Check size of OUTPUT buffer
    // Minimum check...
    // (Done first in order to ensure that we can later access "length" parts
    // for actual check)
    if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof(DIOC_HASH_DATA_OUT)-sizeof(DIOCBufferOut->Hash))

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?