📄 eddrv.c
字号:
/******************************************************************************************************************************/
/*File system filter driver for on-the-fly encryption/decryption of files on USB drive.*/
/*26th Feb 2008*/
/******************************************************************************************************************************/
#include "ntddk.h"
#include "stdarg.h"
#include "stdio.h"
#include "ioctlcmd.h"
#include "EDDrv.h"
#include "EDDrvLib.h"
#ifdef DEVICE_TYPE_FROM_CTL_CODE
#undef DEVICE_TYPE_FROM_CTL_CODE
#endif
#include "winioctl.h"
#if DBG
#define DbgPrint(arg) DbgPrint arg
#else
#define DbgPrint(arg)
#endif
#define SYSNAME "System"
#define BUFFER_NEITHER_DIRECT 0
#define BUFFER_NEITHER_BUFFERED 1
#define BUFFER_NEITHER_NONE 2
BOOLEAN UserValid=FALSE;
BOOLEAN EDDrvFastIoCheckifPossible( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoRead( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoWrite( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoQueryBasicInfo( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait,
OUT PFILE_BASIC_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoQueryStandardInfo( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait,
OUT PFILE_STANDARD_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoLock( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key,
BOOLEAN FailImmediately, BOOLEAN ExclusiveLock,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoUnlockSingle( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoUnlockAll( IN PFILE_OBJECT FileObject, PEPROCESS ProcessId,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoUnlockAllByKey( IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoDeviceControl( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait,
IN PVOID InputBuffer, IN ULONG InputBufferLength,
OUT PVOID OutbufBuffer, IN ULONG OutputBufferLength, IN ULONG IoControlCode,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
VOID EDDrvFastIoAcquireFile( PFILE_OBJECT FileObject );
VOID EDDrvFastIoReleaseFile( PFILE_OBJECT FileObject );
VOID EDDrvFastIoDetachDevice( PDEVICE_OBJECT SourceDevice, PDEVICE_OBJECT TargetDevice );
BOOLEAN EDDrvFastIoQueryNetworkOpenInfo(IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait, OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer,
OUT struct _IO_STATUS_BLOCK *IoStatus, IN PDEVICE_OBJECT DeviceObject );
NTSTATUS EDDrvFastIoAcquireForModWrite( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER EndingOffset, OUT struct _ERESOURCE **ResourceToRelease,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoMdlRead( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN ULONG Length,
IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoMdlReadComplete( IN PFILE_OBJECT FileObject,
IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoPrepareMdlWrite( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey,
OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoMdlWriteComplete( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoReadCompressed( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN ULONG Length,
IN ULONG LockKey, OUT PVOID Buffer, OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus,
OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo,
IN ULONG CompressedDataInfoLength, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoWriteCompressed( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN ULONG Length,
IN ULONG LockKey, IN PVOID Buffer, OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus,
IN struct _COMPRESSED_DATA_INFO *CompressedDataInfo,
IN ULONG CompressedDataInfoLength, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoMdlReadCompleteCompressed( IN PFILE_OBJECT FileObject,
IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoMdlWriteCompleteCompressed( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN EDDrvFastIoQueryOpen( IN struct _IRP *Irp,
OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
IN PDEVICE_OBJECT DeviceObject );
NTSTATUS EDDrvFastIoReleaseForModWrite( IN PFILE_OBJECT FileObject,
IN struct _ERESOURCE *ResourceToRelease, IN PDEVICE_OBJECT DeviceObject );
NTSTATUS EDDrvFastIoAcquireForCcFlush( IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject );
NTSTATUS EDDrvFastIoReleaseForCcFlush( IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject );
PDEVICE_OBJECT ControlDevice;
PDRIVER_OBJECT EDDrvDriver;
BOOLEAN FilterOn = FALSE;
BOOLEAN UnloadInProgress = FALSE;
ULONG OutstandingIRPCount = 0;
KSPIN_LOCK CountMutex;
PDEVICE_OBJECT LDriveDevices[26];
int LDriveMap[26];
int LDriveGroup = 0;
PHASH_ENTRY HashTable[NUMHASH];
ERESOURCE HashResource;
PSTORE_BUF Store = NULL;
ULONG Sequence = 0;
FAST_MUTEX StoreMutex;
PHASH_ENTRY FreeHashList = NULL;
FAST_IO_DISPATCH FastIOHook = {
sizeof(FAST_IO_DISPATCH),
EDDrvFastIoCheckifPossible,
EDDrvFastIoRead,
EDDrvFastIoWrite,
EDDrvFastIoQueryBasicInfo,
EDDrvFastIoQueryStandardInfo,
EDDrvFastIoLock,
EDDrvFastIoUnlockSingle,
EDDrvFastIoUnlockAll,
EDDrvFastIoUnlockAllByKey,
EDDrvFastIoDeviceControl,
EDDrvFastIoAcquireFile,
EDDrvFastIoReleaseFile,
EDDrvFastIoDetachDevice,
EDDrvFastIoQueryNetworkOpenInfo,
EDDrvFastIoAcquireForModWrite,
EDDrvFastIoMdlRead,
EDDrvFastIoMdlReadComplete,
EDDrvFastIoPrepareMdlWrite,
EDDrvFastIoMdlWriteComplete,
EDDrvFastIoReadCompressed,
EDDrvFastIoWriteCompressed,
EDDrvFastIoMdlReadCompleteCompressed,
EDDrvFastIoMdlWriteCompleteCompressed,
EDDrvFastIoQueryOpen,
EDDrvFastIoReleaseForModWrite,
EDDrvFastIoAcquireForCcFlush,
EDDrvFastIoReleaseForCcFlush
};
__inline ULONG MyInterlockedIncrement( PULONG Number )
{
if( *NtBuildNumber < NT4FINAL )
{
return ExInterlockedAddUlong( Number, 1, &CountMutex );
}
else
{
return InterlockedIncrement( Number );
}
}
VOID EDDrvHashCleanup()
{
PHASH_ENTRY hashEntry, nextEntry;
ULONG i;
ExAcquireResourceExclusiveLite( &HashResource, TRUE );
for( i = 0; i < NUMHASH; i++ ) {
hashEntry = HashTable[i];
while( hashEntry ) {
nextEntry = hashEntry->Next;
ExFreePool( hashEntry->FullPathName );
ExFreePool( hashEntry );
hashEntry = nextEntry;
}
HashTable[i] = NULL;
}
hashEntry = FreeHashList;
while( hashEntry ) {
nextEntry = hashEntry->Next;
ExFreePool( hashEntry );
hashEntry = nextEntry;
}
FreeHashList = NULL;
ExReleaseResourceLite( &HashResource );
}
VOID EDDrvFreeHashEntry( PFILE_OBJECT fileObject )
{
PHASH_ENTRY hashEntry, prevEntry;
ExAcquireResourceExclusiveLite( &HashResource, TRUE );
hashEntry = HashTable[ HASHOBJECT( fileObject ) ];
prevEntry = NULL;
while( hashEntry && hashEntry->FileObject != fileObject ) {
prevEntry = hashEntry;
hashEntry = hashEntry->Next;
}
if( !hashEntry ) {
ExReleaseResourceLite( &HashResource );
return;
}
if( prevEntry ) {
prevEntry->Next = hashEntry->Next;
} else {
HashTable[ HASHOBJECT( fileObject )] = hashEntry->Next;
}
ExFreePool( hashEntry->FullPathName );
hashEntry->Next = FreeHashList;
FreeHashList = hashEntry;
ExReleaseResourceLite( &HashResource );
}
NTSTATUS EDDrvQueryFileNameComplete(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
*Irp->UserIosb = Irp->IoStatus;
if( !NT_SUCCESS(Irp->IoStatus.Status) )
{
}
KeSetEvent(Irp->UserEvent, 0, FALSE);
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
BOOLEAN EDDrvQueryFileName( PDEVICE_OBJECT DeviceObject,
PFILE_OBJECT FileObject,
PFILE_NAME_INFORMATION FileName, ULONG FileNameLength )
{
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION ioStackLocation;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!irp) {
return FALSE;
}
irp->AssociatedIrp.SystemBuffer = FileName;
irp->UserEvent = &event;
irp->UserIosb = &IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->RequestorMode = KernelMode;
irp->Flags = 0;
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
ioStackLocation->DeviceObject = DeviceObject;
ioStackLocation->FileObject = FileObject;
ioStackLocation->Parameters.QueryFile.Length = FileNameLength;
ioStackLocation->Parameters.QueryFile.FileInformationClass = FileNameInformation;
IoSetCompletionRoutine(irp, EDDrvQueryFileNameComplete, 0, TRUE, TRUE, TRUE);
(void) IoCallDriver(DeviceObject, irp);
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
return( NT_SUCCESS( IoStatusBlock.Status ));
}
VOID EDDrvGetFullPath( BOOLEAN createPath,
PFILE_OBJECT fileObject, PHOOK_EXTENSION hookExt,
PCHAR fullPathName )
{
ULONG pathLen, prefixLen;
PCHAR pathOffset;
PFILE_OBJECT relatedFileObject;
PHASH_ENTRY hashEntry, newEntry;
ANSI_STRING componentName;
PFILE_NAME_INFORMATION fileNameInfo;
UNICODE_STRING fullUniName;
if( !FilterOn || !hookExt || !fullPathName) {
fullPathName[0] = 0;
return;
}
ExAcquireResourceSharedLite( &HashResource, TRUE );
hashEntry = HashTable[ HASHOBJECT( fileObject ) ];
while( hashEntry && hashEntry->FileObject != fileObject ) {
hashEntry = hashEntry->Next;
}
if( hashEntry ) {
strcpy( fullPathName, hashEntry->FullPathName );
ExReleaseResourceLite( &HashResource );
return;
}
ExReleaseResourceLite( &HashResource );
if( !fileObject || !fileObject->FileName.Length || fileObject->FileName.Length > 2*MAXPATHLEN ) {
if( hookExt->Type == NPFS ) strcpy( fullPathName, NAMED_PIPE_PREFIX );
else if( hookExt->Type == MSFS ) strcpy( fullPathName, MAIL_SLOT_PREFIX );
else sprintf( fullPathName, "%C: DASD", hookExt->LogicalDrive );
return;
}
switch( hookExt->Type ) {
case NPFS: prefixLen = NAMED_PIPE_PREFIX_LENGTH;
break;
case MSFS: prefixLen = MAIL_SLOT_PREFIX_LENGTH;
break;
default: prefixLen = strlen("C:");
break;
}
if( createPath ) {
pathLen = fileObject->FileName.Length/2 + prefixLen;
relatedFileObject = fileObject->RelatedFileObject;
if( fileObject->FileName.Buffer[0] != L'\\' ) {
while( relatedFileObject ) {
if( pathLen + relatedFileObject->FileName.Length/2+1 >= MAXPATHLEN ) {
break;
}
pathLen += relatedFileObject->FileName.Length/2+1;
relatedFileObject = relatedFileObject->RelatedFileObject;
}
}
if( hookExt->Type == NPFS ) strcpy( fullPathName, NAMED_PIPE_PREFIX );
else if( hookExt->Type == MSFS ) strcpy( fullPathName, MAIL_SLOT_PREFIX );
else sprintf( fullPathName, "%C:", hookExt->LogicalDrive );
fullPathName[ pathLen ] = 0;
pathOffset = fullPathName + pathLen - fileObject->FileName.Length/2;
RtlUnicodeStringToAnsiString( &componentName, &fileObject->FileName, TRUE );
strncpy( pathOffset, componentName.Buffer, componentName.Length + 1 );
RtlFreeAnsiString( &componentName );
relatedFileObject = fileObject->RelatedFileObject;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -