NTSTATUS SfWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PSfFILTER_DEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
PFILE_OBJECT FileObject = IrpSp->FileObject;
PFILE_CONTEXT FileContext;
PFILE_CONTEXT TempContext;
KEVENT WaitEvent;
PVOID WriteBuffer = NULL;
PVOID MyBuffer = NULL;
ULONG Length = 0;
PRC4_KEY CryptKey;
BOOLEAN EncryptOnWrite;
PAGED_CODE();
if (IS_MY_DEVICE_OBJECT(DeviceObject))
{
// We only care about volume filter device object, other create request will pass through
if (NULL == DevExt->StorageStackDeviceObject)
{
goto _ReturnAddress2;
}
// only IRP_NOCACHE, IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO will be processed
if (0 == (Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO)))
{
goto _ReturnAddress2;
}
// try to find opened entry in the table
TempContext = ExAllocateFromPagedLookasideList(&gFileContextLookasideList);
if (NULL == TempContext)
{
DbgPrint("[%s] [%u] ExAllocateFromPagedLookasideList() failed, memory exhausted!\n", __FILE__, __LINE__);
goto _ReturnAddress2;
}
TempContext->FsContext = FileObject->FsContext;
ExAcquireFastMutex(&DevExt->FsContextTableMutex);
FileContext = RtlLookupElementGenericTable(&DevExt->FsContextTable, TempContext);
ExReleaseFastMutex(&DevExt->FsContextTableMutex);
ExFreeToPagedLookasideList(&gFileContextLookasideList, TempContext);
if (NULL == FileContext) // not in the generic table, skip it
{
goto _ReturnAddress2;
}
if (IsFileNeedCrypt(DeviceObject, Irp, FileContext) == FALSE) // not in the specified directory
{
goto _ReturnAddress2;
}
// check decrypt flag when reading
KeWaitForSingleObject(&FileContext->Event, Executive, KernelMode, FALSE, NULL);
EncryptOnWrite = FileContext->EncryptOnWrite;
KeSetEvent(&FileContext->Event, IO_NO_INCREMENT, FALSE);
if (EncryptOnWrite == FALSE)
{
goto _ReturnAddress2;
}
Length = IrpSp->Parameters.Write.Length;
DbgPrint("[%s] [%u] Try to write %u bytes from 0x%08X of file %s! FO=0x%08X\n",
__FILE__, __LINE__, Length, IrpSp->Parameters.Write.ByteOffset.LowPart,
FileContext->FullName.RealName, FileObject);
// try encrypt data before write it
CryptKey = ExAllocateFromNPagedLookasideList(&gCryptKeyLookasideList);
if (NULL == CryptKey)
{
DbgPrint("[%s] [%u] ExAllocateFromNPagedLookasideList() failed, memory exhausted!\n", __FILE__, __LINE__);
Status = STATUS_INSUFFICIENT_RESOURCES;
goto _ReturnAddress1;
}
// allocate temporal buffer
MyBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, SfFS_POOL_TAG);
if (NULL == MyBuffer)
{
ExFreeToNPagedLookasideList(&gCryptKeyLookasideList, CryptKey);
DbgPrint("[%s] [%u] ExAllocatePoolWithTag() failed, memory exhausted!\n", __FILE__, __LINE__);
Status = STATUS_INSUFFICIENT_RESOURCES;
goto _ReturnAddress1;
}
WriteBuffer = (Irp->MdlAddress) ? MmGetSystemAddressForMdl(Irp->MdlAddress) : Irp->UserBuffer;
ASSERT(WriteBuffer);
memcpy(CryptKey, gpCryptKey, sizeof(RC4_KEY));
memcpy(MyBuffer, WriteBuffer, Length);
RC4(CryptKey, Length, (const PUCHAR)MyBuffer, (PUCHAR)WriteBuffer);
ExFreePoolWithTag(MyBuffer, SfFS_POOL_TAG);
ExFreeToNPagedLookasideList(&gCryptKeyLookasideList, CryptKey);
// Initialize an event to wait for the completion routine to occur
KeInitializeEvent(&WaitEvent, NotificationEvent, FALSE);
// Copy the stack and set our Completion routine
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, SfWriteCompletion, &WaitEvent, TRUE, TRUE, TRUE);
// Call the next driver in the stack.
Status = IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
// Wait for the completion routine to be called
if (STATUS_PENDING == Status)
{
ASSERT(STATUS_SUCCESS == KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL));
}
// Verify the IoCompleteRequest was called
ASSERT(KeReadStateEvent(&WaitEvent) != 0 || !NT_SUCCESS(Irp->IoStatus.Status));
// We don't care about failed requests
if (!NT_SUCCESS(Irp->IoStatus.Status) || Irp->IoStatus.Status == STATUS_REPARSE)
{
DbgPrint("[%s] [%u] Write %u bytes from 0x%08X of file %s failed!\n",
__FILE__, __LINE__, Irp->IoStatus.Information,
IrpSp->Parameters.Write.ByteOffset.LowPart, FileContext->FullName.RealName);
goto _ReturnAddress1;
}
DbgPrint("[%s] [%u] Write %u bytes from 0x%08X of file %s succeed! FO=0x%08X\n",
__FILE__, __LINE__, Irp->IoStatus.Information,
IrpSp->Parameters.Write.ByteOffset.LowPart, FileContext->FullName.RealName, FileObject);
_ReturnAddress1:
Status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
_ReturnAddress2: // Save the Status and continue processing the IRP
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
}
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
{
DbgPrint("[%s] [%u] I(%wZ) received a request for %s!\n",
__FILE__, __LINE__, &DEVICE_NAME, IRP_MJ_STRINGS[IrpSp->MajorFunction]);
// Reset the Status & information of IRP
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// Wrong device object, come here seems to be impossible
Irp->IoStatus.Status = STATUS_INVALID_HANDLE;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_HANDLE;
}
NTSTATUS SfWriteCompletion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PKEVENT Event = Context;
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(Irp);
ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject));
KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
透明加密驱动源代码
3星 · 超过75%的资源 需积分: 10 141 浏览量
2008-06-25
11:11:05
上传
评论 1
收藏 4KB RAR 举报
woainivc
- 粉丝: 0
- 资源: 3
最新资源
- 默写49个过程、查看工具与技术
- (资源包名是松下不必介意实际是台达)台达PLC例程源码污水处理(台达PLC+触摸屏程序)
- 开唛K歌(沫沫VIP会员版)无限唱_2.1.5_新稳定版.apk
- (资源包名是松下不必介意实际是台达)台达PLC例程源码台达与丹佛斯fc51modbus通信程序带注解
- (资源包名是松下不必介意实际是台达)台达PLC例程源码台达霓虹灯循环程序
- 多种液体自动混合系统.mwp
- (资源包名是松下不必介意实际是台达)台达PLC例程源码台达例程序
- (资源包名是松下不必介意实际是台达)台达PLC例程源码台达程序
- (资源包名是松下不必介意实际是台达)台达PLC例程源码台达PLC与英威腾变频器的通讯控制
- 微服务开发各种注册中心对比
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈