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 + -
显示快捷键?