freeotfe.c

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

C
1,966
字号
)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PDIOC_MOUNT DIOCBuffer;
    PDEVICE_OBJECT tgtDeviceObj;
    ANSI_STRING tmpANSIDeviceName;
    PDEVICE_EXTENSION tgtDevExt;
    
    DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEIOCTL_Mount\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);
    *QueueDeviceObject = NULL;


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

    // Check size of INPUT buffer
    // Minimum check...
    // (Done first in order to ensure that we can later access length related
    // members for actual check)
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            (
             sizeof(DIOC_MOUNT) -
             sizeof(DIOCBuffer->MasterKey) - 
             sizeof(DIOCBuffer->VolumeIV) -
             sizeof(DIOCBuffer->MetaData) 
            )
       )
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect min: %d; got: %d)\n",
            (
             sizeof(DIOC_MOUNT) -
             sizeof(DIOCBuffer->MasterKey) - 
             sizeof(DIOCBuffer->VolumeIV) -
             sizeof(DIOCBuffer->MetaData) 
            ),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }
    DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Key length supplied is apparently: %d bits\n", DIOCBuffer->MasterKeyLength));
    DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("VolumeIV length supplied is apparently: %d bits\n", DIOCBuffer->VolumeIVLength));
    // Actual check...
    // Note: "/ 8" to convert bits to bytes
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            (
             sizeof(DIOC_MOUNT) + 
             (DIOCBuffer->MasterKeyLength / 8) - 
             sizeof(DIOCBuffer->MasterKey) +
             (DIOCBuffer->VolumeIVLength / 8) - 
             sizeof(DIOCBuffer->VolumeIV) + 
             (DIOCBuffer->MetaDataLength) - 
             sizeof(DIOCBuffer->MetaData)
            )
       )
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect actual: %d; got: %d)\n",
            (
             sizeof(DIOC_MOUNT) + 
             (DIOCBuffer->MasterKeyLength / 8) - 
             sizeof(DIOCBuffer->MasterKey) +
             (DIOCBuffer->VolumeIVLength / 8) - 
             sizeof(DIOCBuffer->VolumeIV) + 
             (DIOCBuffer->MetaDataLength) - 
             sizeof(DIOCBuffer->MetaData)
            ),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }

    // Request valid, process...

    // Locate the device on which the file is to be mounted...
    DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Locating disk device...\n"));
    status = GetNamedCharDevice(
                                DeviceObject->DriverObject,
                                (PCHAR)&DIOCBuffer->DiskDeviceName,
                                &tgtDeviceObj
                                );
                            
    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Unable to locate required disk device.\n"));
        status = STATUS_INVALID_PARAMETER;
        return status;
        }
    
    
    // Ensure that the device isn't already mounted...
    tgtDevExt = (PDEVICE_EXTENSION)tgtDeviceObj->DeviceExtension;
    if (tgtDevExt->Mounted)
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Cannot mount device; it's already mounted.\n"));
        status = STATUS_INVALID_PARAMETER;
        return status;
        }

        
    DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("About to flag that IRP should be queued for target device...\n"));

    *QueueDeviceObject = tgtDeviceObj;


    DEBUGOUTMAINDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFEIOCTL_Mount\n"));
    return status;
}


// =========================================================================
// Set raw data in the volume/keyfile
NTSTATUS
IOCTL_FreeOTFEIOCTL_SetRaw(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PDIOC_SET_RAW_DATA DIOCBuffer;
    
    
    DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEIOCTL_SetRaw\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);

    // Check size of INPUT buffer
    // Minimum check...
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            (
             sizeof(DIOC_SET_RAW_DATA) 
              - sizeof(DIOCBuffer->Data)
            )
        )
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect min: %d; got: %d)\n",
            (
             sizeof(DIOC_SET_RAW_DATA) 
              - sizeof(DIOCBuffer->Data)
            ),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }

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

    // Actual check...
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            (
             sizeof(DIOC_SET_RAW_DATA)
              - sizeof(DIOCBuffer->Data)
              + DIOCBuffer->DataLength
            )
        )
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect actual: %d; got: %d)\n",
            (
             sizeof(DIOC_SET_RAW_DATA)
              - sizeof(DIOCBuffer->Data)
              + DIOCBuffer->DataLength
            ),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }


    // Request valid, process...


    status = SetGetRawChar(
                TRUE,
                (PCHAR)&DIOCBuffer->Filename,
                DIOCBuffer->Offset,
                DIOCBuffer->DataLength,
                (FREEOTFEBYTE*)&DIOCBuffer->Data
                );
    Irp->IoStatus.Information = 0;


    DEBUGOUTMAINDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFEIOCTL_SetRaw\n"));
    return status;
}


// =========================================================================
// Get raw data from the volume/keyfile
NTSTATUS
IOCTL_FreeOTFEIOCTL_GetRaw(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PDIOC_GET_RAW_DATA_IN inDIOCBuffer;
    PDIOC_GET_RAW_DATA_OUT outDIOCBuffer;
    ULONG bytesWanted;
    
    
    DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEIOCTL_GetRaw\n"));

    irpSp = IoGetCurrentIrpStackLocation(Irp);

    // Check size of INPUT buffer
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(DIOC_GET_RAW_DATA_IN))
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect: %d; got: %d)\n",
            sizeof(DIOC_GET_RAW_DATA_IN),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }

    inDIOCBuffer = (PDIOC_GET_RAW_DATA_IN)Irp->AssociatedIrp.SystemBuffer;

    // Check size of OUTPUT buffer
    // Note: No minimum check; we just return the data
    // Actual check...
    if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
            (
             sizeof(DIOC_GET_RAW_DATA_OUT)
              - sizeof(outDIOCBuffer->Data)
              + inDIOCBuffer->DataLength  // Yes, this is correct
            )
        )
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect actual: %d; got: %d)\n",
            (
             sizeof(DIOC_GET_RAW_DATA_OUT)
              - sizeof(outDIOCBuffer->Data)
              + inDIOCBuffer->DataLength  // Yes, this is correct
            ),
            irpSp->Parameters.DeviceIoControl.OutputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }
        
    // Request valid, process...
    outDIOCBuffer = (PDIOC_GET_RAW_DATA_OUT)Irp->AssociatedIrp.SystemBuffer;


    // Preserve length of data wanted; the output will overwrite this
    bytesWanted = inDIOCBuffer->DataLength;

    status = SetGetRawChar(
                FALSE,
                (PCHAR)&inDIOCBuffer->Filename,
                inDIOCBuffer->Offset,
                inDIOCBuffer->DataLength,
                (FREEOTFEBYTE*)&outDIOCBuffer->Data
                );

    if (status == STATUS_SUCCESS)
        {
        Irp->IoStatus.Information = bytesWanted;
        }
    else
        {
        Irp->IoStatus.Information = 0;
        }
   

    DEBUGOUTMAINDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFEIOCTL_GetRaw\n"));
    return status;
}


// =========================================================================
// Write/Read raw data from volume
NTSTATUS
SetGetRawChar(
    IN     BOOLEAN DoWrite,
    IN     PCHAR Filename,
    IN     LARGE_INTEGER Offset,
    IN     ULONG DataLength,
    IN OUT FREEOTFEBYTE* Data
)
{
    NTSTATUS status;
    ANSI_STRING tmpANSIFilename;
    UNICODE_STRING tmpUNICODEFilename;
    
    
    DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("SetGetRawChar\n"));


    // Convert the ASCII filename into a UNICODE_STRING
    tmpANSIFilename.Length = (USHORT)strlen(Filename);
    tmpANSIFilename.MaximumLength = tmpANSIFilename.Length + 1;  
    tmpANSIFilename.Buffer = ExAllocatePool(
                                         NonPagedPool,
                                         tmpANSIFilename.MaximumLength
                                        );
    RtlZeroMemory(
                  tmpANSIFilename.Buffer,
                  tmpANSIFilename.MaximumLength
                 );
    RtlCopyMemory(
                  tmpANSIFilename.Buffer,
                  Filename,
                  tmpANSIFilename.Length
                 );

    status = RtlAnsiStringToUnicodeString(
                                          &tmpUNICODEFilename,
                                          &tmpANSIFilename,
                                          TRUE
                                         );
    if (!(NT_SUCCESS(status)))
        {
        ExFreePool(tmpANSIFilename.Buffer);
        }
    else
        {
        status = SetGetRawUnicode(
                    DoWrite,
                    &tmpUNICODEFilename,
                    Offset,
                    DataLength,
                    Data
                   ); 

        RtlFreeUnicodeString(&tmpUNICODEFilename);
        ExFreePool(tmpANSIFilename.Buffer);
        }

    DEBUGOUTMAINDRV(DEBUGLEV_EXIT, ("SetGetRawChar\n"));
    return status;
}


// =========================================================================
// Write/Read raw data from volume
NTSTATUS
SetGetRawUnicode(
    IN     BOOLEAN DoWrite,
    IN     PUNICODE_STRING Filename,
    IN     LARGE_INTEGER Offset,
    IN     ULONG DataLength,
    IN OUT FREEOTFEBYTE* Data
)
{
    NTSTATUS status;
    FILE_BASIC_INFORMATION FileAttributes;
    OBJECT_ATTRIBUTES fileObjAttribs;
    HANDLE fileHandle;
    IO_STATUS_BLOCK ioStatusBlock;
    BOOLEAN fileAttributesStored;
    FILE_BASIC_INFORMATION fileAttributes;
    ACCESS_MASK access;
    NTSTATUS tmpStatus;
    FILE_STANDARD_INFORMATION fileStdInfo;  
    PSECURITY_CLIENT_CONTEXT ClientContext;

    DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("SetGetRawUnicode\n"));

    
    if (DoWrite)
        {
        DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Write raw requested\n"));
        }
    else
        {
        DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Read raw requested\n"));
        }

    status = ClientSecurityCreate(&ClientContext);
    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Unable to create security client\n"));
        return status;
        }

    // Note: We allow intermediate buffering as "FILE_NO_INTERMEDIATE_BUFFERING"
    //       would require all offsets and read/writes to be a multiple of the
    //       sector size - reducing flexability
    status = FileOpen(
                      Filename,
                      ClientContext,
                      (!(DoWrite)),
                      TRUE,
                      &fileHandle,
                      &ioStatusBlock,
                      &fileAttributesStored,

⌨️ 快捷键说明

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