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