freeotfecypherdriver.c

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

C
1,734
字号
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = FILE_OPENED;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DEBUGOUTCYPHERDRV(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;
    
    DEBUGOUTCYPHERDRV(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_FreeOTFECypher_IDENTIFYDRIVER:
            {
            status = IOCTL_FreeOTFECypherIOCTL_IdentifyDriver(DeviceObject, Irp);
            break;
            }


        case IOCTL_FreeOTFECypher_IDENTIFYSUPPORTED:
            {
            status = IOCTL_FreeOTFECypherIOCTL_IdentifySupported(DeviceObject, Irp);
            break;
            }


        case IOCTL_FreeOTFECypher_ENCRYPT:
        case IOCTL_FreeOTFECypher_DECRYPT:
            {
            queueDeviceObject = DeviceObject;
            break;
            }


        case IOCTL_FreeOTFECypher_INTLDETAILS:
            {
            status = IOCTL_FreeOTFECypherIOCTL_IntlDetails(DeviceObject, Irp);
            break;
            }


        default:
            {
            DEBUGOUTCYPHERDRV(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)
        {
        DEBUGOUTCYPHERDRV(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.
            DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Queued IRP.\n"));
            }
        else
            {
            Irp->IoStatus.Status = status;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("Failed to queue IRP.\n"));
            }

        }
    else
        {
        DEBUGOUTCYPHERDRV(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);
        DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("OK.\n"));
        }

    DEBUGOUTCYPHERDRV(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_FreeOTFECypherIOCTL_IntlDetails(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PDIOC_CYPHER_INTL_DETAILS DIOCBuffer;

    DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFECypherIOCTL_IntlDetails\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);


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

    // Populate output buffer with with function pointers;
    DIOCBuffer->FnEncrypt       = ImpCypherEncryptData;
    DIOCBuffer->FnDecrypt       = ImpCypherDecryptData;
    DIOCBuffer->FnCypherDetails = GetCypherDetails;
    

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


    DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFECypherIOCTL_IntlDetails\n"));
    return status;
}


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

    DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFECypherIOCTL_IdentifyDriver\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);


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

    DIOCBuffer = (PDIOC_CYPHER_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->CountCyphers = devExt->DriverInfo.CypherCount;


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


    DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFECypherIOCTL_IdentifyDriver\n"));
    return status;
}


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

    DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFECypherIOCTL_IdentifySupported\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);

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

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

        
    // Request valid, process...

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

    devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

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

    // Request valid, process...


    DIOCBuffer->BufCount = devExt->DriverInfo.CypherCount;
    RtlCopyMemory(
                  &DIOCBuffer->Cyphers[0],
                  devExt->DriverInfo.CypherDetails,
                  (sizeof(CYPHER) * devExt->DriverInfo.CypherCount)
                 );
    

    Irp->IoStatus.Information = sizeof(DIOC_CYPHER_IDENTIFYSUPPORTED)+(DIOCBuffer->BufCount * sizeof(DIOCBuffer->Cyphers))-sizeof(DIOCBuffer->Cyphers);


    DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFECypherIOCTL_IdentifySupported\n"));
    return status;
}


// =========================================================================
// 
NTSTATUS
IOCTL_FreeOTFECypherIOCTL_Encrypt(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PDIOC_CYPHER_DATA_IN DIOCBufferIn;
    PDIOC_CYPHER_DATA_OUT DIOCBufferOut;
    CYPHER CypherDetails;
    char* keyASCII;
    int keyASCIIBufferLen;
    int dataLength;
    char* tmpBuffer;
    unsigned char* ptrInKey;   // Pointer to where the key starts in the input buffer
    unsigned char* ptrInIV;    // Pointer to where the IV starts in the input buffer
    unsigned char* ptrInData;  // Pointer to where the data starts in the input buffer
    int i;

    DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFECypherIOCTL_Encrypt\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);

    DIOCBufferIn = (PDIOC_CYPHER_DATA_IN)Irp->AssociatedIrp.SystemBuffer;
    DIOCBufferOut = (PDIOC_CYPHER_DATA_OUT)Irp->AssociatedIrp.SystemBuffer;

    // Check size of INPUT buffer
    // Minimum check...
    // (Done first in order to ensure that we can later access DIOCBufferIn->Data
    // for actual check)
    if (
        irpSp->Parameters.DeviceIoControl.InputBufferLength <
            (
             sizeof(DIOC_CYPHER_DATA_IN)
              - sizeof(DIOCBufferIn->Key)
              - sizeof(DIOCBufferIn->IV)
              - sizeof(DIOCBufferIn->Data)
            )
       )
        {
        DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect min: %d; got: %d)\n",
            (
             sizeof(DIOC_CYPHER_DATA_IN)
              - sizeof(DIOCBufferIn->Key)
              - sizeof(DIOCBufferIn->IV)

⌨️ 快捷键说明

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