summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filesys/miniFilter/MetadataManager/MetadataManagerInit.c124
-rw-r--r--filesys/miniFilter/MetadataManager/fmm.infbin5040 -> 7812 bytes
-rw-r--r--filesys/miniFilter/NameChanger/NameChanger.infbin5770 -> 8938 bytes
-rw-r--r--filesys/miniFilter/NameChanger/nc.c2
-rw-r--r--filesys/miniFilter/NameChanger/nc.h73
-rw-r--r--filesys/miniFilter/NameChanger/ncinit.c61
-rw-r--r--filesys/miniFilter/avscan/avscan.infbin5808 -> 9104 bytes
-rw-r--r--filesys/miniFilter/avscan/filter/avscan.c971
-rw-r--r--filesys/miniFilter/avscan/filter/avscan.vcxproj1
-rw-r--r--filesys/miniFilter/avscan/filter/avscan.vcxproj.Filters22
-rw-r--r--filesys/miniFilter/cancelSafe/cancelSafe.c64
-rw-r--r--filesys/miniFilter/cancelSafe/cancelSafe.infbin5532 -> 8548 bytes
-rw-r--r--filesys/miniFilter/cdo/CdoInit.c120
-rw-r--r--filesys/miniFilter/cdo/cdo.infbin5078 -> 7790 bytes
-rw-r--r--filesys/miniFilter/change/change.infbin5070 -> 7586 bytes
-rw-r--r--filesys/miniFilter/ctx/CtxInit.c98
-rw-r--r--filesys/miniFilter/ctx/ctx.infbin5004 -> 7776 bytes
-rw-r--r--filesys/miniFilter/delete/delete.infbin5156 -> 7760 bytes
-rw-r--r--filesys/miniFilter/minispy/filter/minispy.vcxproj1
-rw-r--r--filesys/miniFilter/minispy/filter/minispy.vcxproj.Filters10
-rw-r--r--filesys/miniFilter/minispy/minispy.infbin6688 -> 10090 bytes
-rw-r--r--filesys/miniFilter/nullFilter/nullFilter.infbin5014 -> 7608 bytes
-rw-r--r--filesys/miniFilter/passThrough/passThrough.infbin5220 -> 7866 bytes
-rw-r--r--filesys/miniFilter/scanner/filter/scanner.c66
-rw-r--r--filesys/miniFilter/scanner/filter/scanner.vcxproj1
-rw-r--r--filesys/miniFilter/scanner/filter/scanner.vcxproj.Filters10
-rw-r--r--filesys/miniFilter/scanner/scanner.infbin5562 -> 8382 bytes
-rw-r--r--filesys/miniFilter/simrep/simrep.c62
-rw-r--r--filesys/miniFilter/simrep/simrep.infbin6422 -> 9052 bytes
-rw-r--r--filesys/miniFilter/swapBuffers/swapBuffers.infbin5176 -> 7946 bytes
30 files changed, 1036 insertions, 650 deletions
diff --git a/filesys/miniFilter/MetadataManager/MetadataManagerInit.c b/filesys/miniFilter/MetadataManager/MetadataManagerInit.c
index 222159f7..d2824241 100644
--- a/filesys/miniFilter/MetadataManager/MetadataManagerInit.c
+++ b/filesys/miniFilter/MetadataManager/MetadataManagerInit.c
@@ -88,6 +88,7 @@ FmmInstanceTeardownComplete (
VOID
FmmInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -115,11 +116,11 @@ FmmInitializeDebugLevel (
//
// If we need to verify that the metadata file is indeed open whenever
-// a create suceeds on the volume, then we need to monitor all creates
+// a create suceeds on the volume, then we need to monitor all creates
// not just DASD creates.
-// If that is not the case, then we are better off telling filter manager
-// to show us only DASD creates. That way we can avoid the performance
+// If that is not the case, then we are better off telling filter manager
+// to show us only DASD creates. That way we can avoid the performance
// penalty of being called for all creates when we only have use for DASD
// creates.
//
@@ -241,7 +242,7 @@ Return Value:
//
// Default to NonPagedPoolNx for non paged pool allocations where supported.
//
-
+
ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
@@ -253,7 +254,7 @@ Return Value:
// Initialize global debug level
//
- FmmInitializeDebugLevel( RegistryPath );
+ FmmInitializeDebugLevel( DriverObject, RegistryPath );
#else
@@ -301,6 +302,7 @@ Return Value:
VOID
FmmInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -313,6 +315,9 @@ Routine Description:
Arguments:
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
RegistryPath - The path key passed to the driver during DriverEntry.
Return Value:
@@ -322,7 +327,8 @@ Return Value:
--*/
{
OBJECT_ATTRIBUTES attributes;
- HANDLE driverRegKey;
+ OSVERSIONINFOW versionInfo;
+ HANDLE driverRegKey = NULL;
NTSTATUS status;
ULONG resultLength;
UNICODE_STRING valueName;
@@ -330,48 +336,84 @@ Return Value:
Globals.DebugLevel = DEBUG_TRACE_ERROR;
+ RtlZeroMemory( &versionInfo, sizeof( versionInfo ) );
+
//
- // Open the desired registry key
+ // Determine the OS version being run.
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ versionInfo.dwOSVersionInfoSize = sizeof( versionInfo );
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ status = RtlGetVersion( &versionInfo );
- if (NT_SUCCESS( status )) {
+ if (!NT_SUCCESS( status )) {
+ goto cleanup;
+ }
+
+ //
+ // Open the desired registry key
+ //
+
+ if (versionInfo.dwBuildNumber >= 25900) {
//
- // Read the DebugFlags value from the registry.
+ // Open the Parameters key for the service.
//
- RtlInitUnicodeString( &valueName, L"DebugLevel" );
+ status = IoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &driverRegKey );
+
+ if (!NT_SUCCESS( status )) {
- status = ZwQueryValueKey( driverRegKey,
- &valueName,
- KeyValuePartialInformation,
- buffer,
- sizeof(buffer),
- &resultLength );
+ goto cleanup;
+ }
+ } else {
+ InitializeObjectAttributes( &attributes,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
- if (NT_SUCCESS( status )) {
+ status = ZwOpenKey( &driverRegKey,
+ KEY_READ,
+ &attributes );
- Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
}
-
- //
- // Close the registry entry
- //
-
- ZwClose( driverRegKey );
-
}
+ //
+ // Read the DebugFlags value from the registry.
+ //
+
+ RtlInitUnicodeString( &valueName, L"DebugLevel" );
+
+ status = ZwQueryValueKey( driverRegKey,
+ &valueName,
+ KeyValuePartialInformation,
+ buffer,
+ sizeof(buffer),
+ &resultLength );
+
+ if (NT_SUCCESS( status )) {
+
+ Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
+ }
+
+cleanup:
+
+ //
+ // Close the registry entry
+ //
+
+ if (driverRegKey != NULL) {
+ ZwClose( driverRegKey );
+ }
}
#endif
@@ -678,22 +720,22 @@ FmmInstanceSetupCleanup:
}
//
- // If this is an automatic attachment (mount, load, etc) and we are not
- // attaching to this volume because we do not support attaching to this
- // volume, then simply return STATUS_FLT_DO_NOT_ATTACH. If we return
- // anything else fltmgr logs an event log indicating failure to attach.
- // Since this failure to attach is not really an error, we do not want
+ // If this is an automatic attachment (mount, load, etc) and we are not
+ // attaching to this volume because we do not support attaching to this
+ // volume, then simply return STATUS_FLT_DO_NOT_ATTACH. If we return
+ // anything else fltmgr logs an event log indicating failure to attach.
+ // Since this failure to attach is not really an error, we do not want
// this failure to be logged as an error in the event log. For all other
// error codes besides the ones we consider "normal", if is ok for fltmgr
// to actually log the failure to attach.
//
- // If this is a manual attach attempt that we have failed then we want to
- // give the user a clear indication of why the attachment failed. Hence in
+ // If this is a manual attach attempt that we have failed then we want to
+ // give the user a clear indication of why the attachment failed. Hence in
// this case, we will not override the error status with STATUS_FLT_DO_NOT_ATTACH
// irrespective of the cause of the failure to attach
//
- if (status == STATUS_NOT_SUPPORTED &&
+ if (status == STATUS_NOT_SUPPORTED &&
!FlagOn( Flags, FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT )) {
status = STATUS_FLT_DO_NOT_ATTACH;
diff --git a/filesys/miniFilter/MetadataManager/fmm.inf b/filesys/miniFilter/MetadataManager/fmm.inf
index caf4bc8f..64d3723c 100644
--- a/filesys/miniFilter/MetadataManager/fmm.inf
+++ b/filesys/miniFilter/MetadataManager/fmm.inf
Binary files differ
diff --git a/filesys/miniFilter/NameChanger/NameChanger.inf b/filesys/miniFilter/NameChanger/NameChanger.inf
index 36b99019..d8660653 100644
--- a/filesys/miniFilter/NameChanger/NameChanger.inf
+++ b/filesys/miniFilter/NameChanger/NameChanger.inf
Binary files differ
diff --git a/filesys/miniFilter/NameChanger/nc.c b/filesys/miniFilter/NameChanger/nc.c
index 9bcdc094..c59742e5 100644
--- a/filesys/miniFilter/NameChanger/nc.c
+++ b/filesys/miniFilter/NameChanger/nc.c
@@ -988,7 +988,7 @@ Return Value:
NcCompatInit( );
- Status = NcInitializeMapping( RegistryPath );
+ Status = NcInitializeMapping( DriverObject, RegistryPath );
if (!NT_SUCCESS( Status )) {
return Status;
}
diff --git a/filesys/miniFilter/NameChanger/nc.h b/filesys/miniFilter/NameChanger/nc.h
index c2509faa..47d582b4 100644
--- a/filesys/miniFilter/NameChanger/nc.h
+++ b/filesys/miniFilter/NameChanger/nc.h
@@ -59,7 +59,7 @@
//
// Typedefs for dynamically imported routines
-//
+//
typedef
NTSTATUS
@@ -277,27 +277,27 @@ typedef struct _NC_DIR_NOT_IO_CACHE {
// Stores the state of the cache.
// If the pointer is NULL, there is nothing in cache.
//
-
+
NC_CACHE_ENTRY Cache;
//
// If ReadyToIssue is TRUE, then its safe to fire off the request.
//
-
+
BOOLEAN ReadyToIssue;
//
// Io is a pointer to the callback data.
// When ReadyToUse new io can be issued.
//
-
+
PFLT_CALLBACK_DATA Io;
//
// SystemBuffer is a pointer to a system buffer which will
// be used to issue the IO.
//
-
+
char * SystemBuffer;
ULONG SystemBufferLength;
@@ -479,7 +479,7 @@ extern NC_GLOBAL_DATA NcGlobalData;
//
// Function declarations
-//
+//
//
// The following functions exist in nchelper.c
@@ -487,18 +487,18 @@ extern NC_GLOBAL_DATA NcGlobalData;
_When_(Data == NULL, _Pre_satisfies_(FileObject != NULL && Instance != NULL))
_When_(FileObject == NULL || Instance == NULL, _Pre_satisfies_(Data != NULL))
-NTSTATUS
+NTSTATUS
NcGetFileNameInformation(
_In_opt_ PFLT_CALLBACK_DATA Data,
_In_opt_ PFILE_OBJECT FileObject,
_In_opt_ PFLT_INSTANCE Instance,
_In_ FLT_FILE_NAME_OPTIONS NameOptions,
- _Outptr_ PFLT_FILE_NAME_INFORMATION *FileNameInformation
+ _Outptr_ PFLT_FILE_NAME_INFORMATION *FileNameInformation
);
NTSTATUS
NcAllocateEResource(
- _Out_ PERESOURCE * OutputLock
+ _Out_ PERESOURCE * OutputLock
);
VOID
@@ -600,8 +600,9 @@ NcBuildMapping (
// The following functions exist in ncinit.c
//
-NTSTATUS
+NTSTATUS
NcInitializeMapping(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -642,7 +643,7 @@ NcParseFinalComponent (
//
NTSTATUS
-NcStreamHandleContextAllocAndAttach(
+NcStreamHandleContextAllocAndAttach(
_In_ PFLT_FILTER Filter,
_In_ PFLT_INSTANCE Instance,
_In_ PFILE_OBJECT FileObject,
@@ -709,7 +710,7 @@ NcDetermineStructureOffsets (
_In_ FILE_INFORMATION_CLASS Information
);
-VOID
+VOID
NcCalculateDirectoryNotificationOffsets (
PDIRECTORY_CONTROL_OFFSETS Offsets
);
@@ -762,7 +763,7 @@ NcSetNextEntryOffset (
_In_ CONST PDIRECTORY_CONTROL_OFFSETS Offsets,
_In_ BOOLEAN ForceLast);
-VOID
+VOID
NcSetFileName (
_In_ PVOID Entry,
_In_ PWSTR NewName,
@@ -771,7 +772,7 @@ NcSetFileName (
_In_ BOOLEAN ForceLast
);
-VOID
+VOID
NcSetShortName (
_In_ PVOID Entry,
_In_ PWSTR NewShortName,
@@ -800,7 +801,7 @@ NcEnumerateDirectorySetupInjection (
);
VOID
-NcEnumerateDirectoryReset (
+NcEnumerateDirectoryReset (
_Inout_ PNC_DIR_QRY_CONTEXT dirCtx
);
@@ -818,9 +819,9 @@ NcPopulateCacheEntry (
_Out_ PNC_CACHE_ENTRY Cache
);
-PNC_CACHE_ENTRY
-NcDirEnumSelectNextEntry (
- _Inout_ PNC_DIR_QRY_CONTEXT Context,
+PNC_CACHE_ENTRY
+NcDirEnumSelectNextEntry (
+ _Inout_ PNC_DIR_QRY_CONTEXT Context,
_In_ PDIRECTORY_CONTROL_OFFSETS Offsets,
_In_ BOOLEAN IgnoreCase
);
@@ -828,7 +829,7 @@ NcDirEnumSelectNextEntry (
BOOLEAN
NcSkipName (
_In_ PDIRECTORY_CONTROL_OFFSETS Offsets,
- _In_ PNC_DIR_QRY_CONTEXT Context,
+ _In_ PNC_DIR_QRY_CONTEXT Context,
_In_ NC_PATH_OVERLAP RealOverlap,
_In_ PNC_MAPPING Mapping,
_In_ BOOLEAN IgnoreCase
@@ -836,22 +837,22 @@ NcSkipName (
_Success_(*Copied)
ULONG
-NcCopyDirEnumEntry (
- _Out_ PVOID UserBuffer,
- _In_ ULONG UserOffset,
- _In_ ULONG UserSize,
+NcCopyDirEnumEntry (
+ _Out_ PVOID UserBuffer,
+ _In_ ULONG UserOffset,
+ _In_ ULONG UserSize,
_Inout_ PNC_CACHE_ENTRY Entry,
_In_ PDIRECTORY_CONTROL_OFFSETS Offsets,
- _Out_ PBOOLEAN Copied
+ _Out_ PBOOLEAN Copied
);
NTSTATUS
NcStreamHandleContextDirEnumCreate (
- _Out_ PNC_DIR_QRY_CONTEXT Context
+ _Out_ PNC_DIR_QRY_CONTEXT Context
);
NTSTATUS
-NcStreamHandleContextEnumSetup (
+NcStreamHandleContextEnumSetup (
_Inout_ PNC_DIR_QRY_CONTEXT DirContext,
_In_ PNC_INSTANCE_CONTEXT InstanceContext,
_In_ PDIRECTORY_CONTROL_OFFSETS Offsets,
@@ -861,9 +862,9 @@ NcStreamHandleContextEnumSetup (
_Out_ PBOOLEAN FirstUsage
);
-VOID
+VOID
NcStreamHandleContextEnumClose (
- _In_ PNC_DIR_QRY_CONTEXT DirContext
+ _In_ PNC_DIR_QRY_CONTEXT DirContext
);
//
@@ -885,19 +886,19 @@ NcPostNotifyDirectory (
_In_ FLT_POST_OPERATION_FLAGS Flags
);
-NTSTATUS
-NcStreamHandleContextNotCreate (
+NTSTATUS
+NcStreamHandleContextNotCreate (
_Out_ PNC_DIR_NOT_CONTEXT Context
);
-VOID
+VOID
NcStreamHandleContextNotCleanup(
- _In_ PNC_STREAM_HANDLE_CONTEXT HandleContext
+ _In_ PNC_STREAM_HANDLE_CONTEXT HandleContext
);
-VOID
+VOID
NcStreamHandleContextNotClose (
- _In_ PNC_DIR_NOT_CONTEXT DirContext
+ _In_ PNC_DIR_NOT_CONTEXT DirContext
);
//
@@ -970,10 +971,10 @@ NcPostEnumUsnData (
NTSTATUS
NcStreamHandleContextFindBySidCreate (
- _Out_ PNC_FIND_BY_SID_CONTEXT Context
+ _Out_ PNC_FIND_BY_SID_CONTEXT Context
);
-VOID
+VOID
NcStreamHandleContextFindBySidClose (
_In_ PNC_FIND_BY_SID_CONTEXT Context
);
diff --git a/filesys/miniFilter/NameChanger/ncinit.c b/filesys/miniFilter/NameChanger/ncinit.c
index d34dc0f0..e9b2d642 100644
--- a/filesys/miniFilter/NameChanger/ncinit.c
+++ b/filesys/miniFilter/NameChanger/ncinit.c
@@ -280,6 +280,7 @@ NcIs8DOT3Compatible (
NTSTATUS
NcInitializeMapping(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -292,6 +293,9 @@ Routine Descrition:
Arguments:
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
RegistryPath - The path key passed to the driver during DriverEntry.
Return Value:
@@ -301,6 +305,7 @@ Return Value:
--*/
{
NTSTATUS Status;
+ OSVERSIONINFOW versionInfo;
OBJECT_ATTRIBUTES Attributes;
HANDLE DriverRegKey = NULL;
UNICODE_STRING TempPath = EMPTY_UNICODE_STRING;
@@ -310,26 +315,62 @@ Return Value:
RtlZeroMemory( &NcGlobalData, sizeof( NcGlobalData ));
+ RtlZeroMemory( &versionInfo, sizeof( versionInfo ) );
+
//
- // Open the mapping registry key.
+ // Determine the OS version being run.
//
- InitializeObjectAttributes( &Attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ versionInfo.dwOSVersionInfoSize = sizeof( versionInfo );
- Status = ZwOpenKey( &DriverRegKey,
- KEY_READ,
- &Attributes );
+ Status = RtlGetVersion( &versionInfo );
if (!NT_SUCCESS( Status )) {
- FLT_ASSERT( DriverRegKey == NULL );
goto NcInitializeMappingCleanup;
}
+ //
+ // Open the desired registry key
+ //
+
+ if (versionInfo.dwBuildNumber >= 25900) {
+ //
+ // Open the Parameters key for the service.
+ //
+
+ Status = IoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &DriverRegKey );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto NcInitializeMappingCleanup;
+ }
+ } else {
+ //
+ // Open legacy registry key.
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ Status = ZwOpenKey( &DriverRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( Status )) {
+
+ FLT_ASSERT( DriverRegKey == NULL );
+ goto NcInitializeMappingCleanup;
+ }
+ }
+
Status = NcLoadRegistryString( DriverRegKey,
L"UserMapping",
&TempPath );
diff --git a/filesys/miniFilter/avscan/avscan.inf b/filesys/miniFilter/avscan/avscan.inf
index 26fb6c22..12fa79c7 100644
--- a/filesys/miniFilter/avscan/avscan.inf
+++ b/filesys/miniFilter/avscan/avscan.inf
Binary files differ
diff --git a/filesys/miniFilter/avscan/filter/avscan.c b/filesys/miniFilter/avscan/filter/avscan.c
index 82e1045c..821dd733 100644
--- a/filesys/miniFilter/avscan/filter/avscan.c
+++ b/filesys/miniFilter/avscan/filter/avscan.c
@@ -9,9 +9,9 @@ Module Name:
Abstract:
This is the main module of the avscan mini-filter driver.
- This filter demonstrates how to implement a transaction-aware
+ This filter demonstrates how to implement a transaction-aware
anti-virus filter.
-
+
Av prefix denotes "Anti-virus" module.
Environment:
@@ -22,7 +22,7 @@ Environment:
#include <initguid.h>
#include "avscan.h"
-
+
/*************************************************************************
Local Function Prototypes
*************************************************************************/
@@ -34,8 +34,9 @@ DriverEntry (
_In_ PUNICODE_STRING RegistryPath
);
-NTSTATUS
-AvSetConfiguration (
+NTSTATUS
+AvSetConfiguration (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -112,20 +113,20 @@ AvKtmNotificationCallback (
_In_ PFLT_CONTEXT TransactionContext,
_In_ ULONG TransactionNotification
);
-
+
NTSTATUS
AvScanAbortCallbackAsync (
_Unreferenced_parameter_ PFLT_INSTANCE Instance,
_In_ PFLT_CONTEXT Context,
_Unreferenced_parameter_ PFLT_CALLBACK_DATA Data
);
-
+
//
// Local routines
//
BOOLEAN
-AvOperationsModifyingFile (
+AvOperationsModifyingFile (
_In_ PFLT_CALLBACK_DATA Data
);
@@ -134,14 +135,14 @@ AvQueryTransactionOutcome(
_In_ PKTRANSACTION Transaction,
_Out_ PULONG TxOutcome
);
-
+
NTSTATUS
AvProcessPreviousTransaction (
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Inout_ PAV_STREAM_CONTEXT StreamContext
);
-
-NTSTATUS
+
+NTSTATUS
AvProcessTransactionOutcome (
_Inout_ PAV_TRANSACTION_CONTEXT TransactionContext,
_In_ ULONG TransactionOutcome
@@ -154,9 +155,9 @@ AvLoadFileStateFromCache (
_Out_ LONG volatile* State,
_Out_ PLONGLONG VolumeRevision,
_Out_ PLONGLONG CacheRevision,
- _Out_ PLONGLONG FileRevision
+ _Out_ PLONGLONG FileRevision
);
-
+
NTSTATUS
AvSyncCache (
_In_ PFLT_INSTANCE Instance,
@@ -168,12 +169,12 @@ AvIsPrefetchEcpPresent (
_In_ PFLT_FILTER Filter,
_In_ PFLT_CALLBACK_DATA Data
);
-
+
BOOLEAN
AvIsStreamAlternate (
_Inout_ PFLT_CALLBACK_DATA Data
);
-
+
NTSTATUS
AvScan (
_Inout_ PFLT_CALLBACK_DATA Data,
@@ -183,18 +184,18 @@ AvScan (
_In_ BOOLEAN IsInTxWriter,
_Inout_ PAV_STREAM_CONTEXT StreamContext
);
-
+
VOID
AvDoCancelScanAndRelease (
_In_ PAV_SCAN_CONTEXT ScanContext,
_In_ PAV_SECTION_CONTEXT SectionContext
);
-
+
NTSTATUS
-AvSendUnloadingToUser (
+AvSendUnloadingToUser (
VOID
- );
-
+ );
+
//
// Assign text sections for each routine.
//
@@ -225,7 +226,7 @@ AvSendUnloadingToUser (
#pragma alloc_text(PAGE, AvDoCancelScanAndRelease)
#pragma alloc_text(PAGE, AvSendAbortToUser)
#pragma alloc_text(PAGE, AvSendUnloadingToUser)
-#endif
+#endif
//
// operation registration
@@ -251,7 +252,7 @@ CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
0,
AvPreOperationCallback,
NULL },
-
+
{ IRP_MJ_FILE_SYSTEM_CONTROL,
0,
AvPreFsControl,
@@ -330,7 +331,7 @@ Return Value:
NTSTATUS status;
PAV_INSTANCE_CONTEXT instanceContext = NULL;
BOOLEAN isOnCsv = FALSE;
-
+
UNREFERENCED_PARAMETER( Flags );
PAGED_CODE();
@@ -348,13 +349,13 @@ Return Value:
}
//
- // Determine if the filter is attaching to the hidden NTFS volume
- // that corresponds to a CSV volume. If so do not attach. Note
- // that it would be feasible for the filter to attach to this
+ // Determine if the filter is attaching to the hidden NTFS volume
+ // that corresponds to a CSV volume. If so do not attach. Note
+ // that it would be feasible for the filter to attach to this
// volume as part of a distrubuted filter implementation but that
// is beyond the scope of this sample.
//
-
+
if (VolumeFilesystemType == FLT_FSTYPE_NTFS) {
isOnCsv = AvIsVolumeOnCsvDisk( FltObjects->Volume );
if (isOnCsv) {
@@ -362,7 +363,7 @@ Return Value:
return STATUS_FLT_DO_NOT_ATTACH;
}
}
-
+
status = FltAllocateContext( Globals.Filter,
FLT_INSTANCE_CONTEXT,
AV_INSTANCE_CONTEXT_SIZE,
@@ -373,46 +374,46 @@ Return Value:
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvInstanceSetup: allocate instance context failed. status = 0x%x\n", status) );
-
+
return STATUS_FLT_DO_NOT_ATTACH;
}
//
// Setup instance context
//
-
+
RtlZeroMemory(instanceContext, AV_INSTANCE_CONTEXT_SIZE);
instanceContext->Volume = FltObjects->Volume;
instanceContext->Instance = FltObjects->Instance;
instanceContext->VolumeFSType = VolumeFilesystemType;
instanceContext->IsOnCsvMDS = isOnCsv;
-
+
//
// There will be a file state cache table for each NTFS volume instance.
- // As for other file systems, file id is not unique, and thus we do
- // not have cache for other kinds of file systems. Since the cache
- // table is not mandatory to implement an anti-virus filter, we
+ // As for other file systems, file id is not unique, and thus we do
+ // not have cache for other kinds of file systems. Since the cache
+ // table is not mandatory to implement an anti-virus filter, we
// only have the volatile cache for NTFS, CSVFS and REFS.
//
- // It is worth mentioning that the table is potentially very large.
- // We use an AVL tree to improve insertion and query times. We do not
- // set an upper bound for the size of the tree which is not optimal.
+ // It is worth mentioning that the table is potentially very large.
+ // We use an AVL tree to improve insertion and query times. We do not
+ // set an upper bound for the size of the tree which is not optimal.
// Consider limiting the size of the tree for a production filter.
//
-
+
if (FS_SUPPORTS_FILE_STATE_CACHE( VolumeFilesystemType )) {
-
+
//
// Initialize file state cache in the instance context.
//
ExInitializeResourceLite( &instanceContext->Resource );
-
+
RtlInitializeGenericTable( &instanceContext->FileStateCacheTable,
AvCompareEntry,
AvAllocateGenericTableEntry,
AvFreeGenericTableEntry,
- NULL );
+ NULL );
}
status = FltSetInstanceContext( FltObjects->Instance,
@@ -435,22 +436,22 @@ Return Value:
}
//
- // Register this instance as a datascan filter. If this call
- // fails the underlying filesystem does not support using
+ // Register this instance as a datascan filter. If this call
+ // fails the underlying filesystem does not support using
// the filter manager datascan API. Currently only the
// the namedpipe and mailslot file systems are unsupported.
- //
-
+ //
+
status = FltRegisterForDataScan( FltObjects->Instance );
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvInstanceSetup: FltRegisterForDataScan failed. status = 0x%x\n", status) );
return STATUS_FLT_DO_NOT_ATTACH;
}
-
+
return STATUS_SUCCESS;
}
@@ -525,36 +526,36 @@ Return Value:
PLIST_ENTRY next;
PAV_SCAN_CONTEXT scanCtx = NULL;
PAV_INSTANCE_CONTEXT instanceContext = NULL;
-
+
UNREFERENCED_PARAMETER( Flags );
PAGED_CODE();
-
+
AV_DBG_PRINT( AVDBG_TRACE_DEBUG,
("[AV] AvInstanceTeardownStart: Entered\n") );
-
+
status = FltGetInstanceContext( FltObjects->Instance,
&instanceContext );
-
+
if (!NT_SUCCESS( status )) {
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvInstanceTeardownStart: FltGetInstanceContext failed. status = 0x%x\n", status) );
return;
}
-
+
//
// Search the scan context from the global list.
//
-
+
AvAcquireResourceExclusive( &Globals.ScanCtxListLock );
-
+
LIST_FOR_EACH_SAFE( scan, next, &Globals.ScanCtxListHead ) {
-
+
scanCtx = CONTAINING_RECORD( scan, AV_SCAN_CONTEXT, List );
-
+
if (scanCtx->FilterInstance != FltObjects->Instance) {
-
+
continue;
}
@@ -564,45 +565,45 @@ Return Value:
status = AvSendAbortToUser(scanCtx->ScanThreadId,
scanCtx->ScanId);
-
+
//
- // If we fail to send message to the user, then we
- // do the cancel and cleanup by ourself; otherwise,
- // the listening thread will call back to cleanup and
+ // If we fail to send message to the user, then we
+ // do the cancel and cleanup by ourself; otherwise,
+ // the listening thread will call back to cleanup and
// I/O request thred will tear down the scan context.
//
-
+
if (!NT_SUCCESS( status ) || status == STATUS_TIMEOUT) {
AvFinalizeScanAndSection(scanCtx);
}
}
-
+
AvReleaseResource( &Globals.ScanCtxListLock );
-
+
//
// Clean up the cache table if the volume supports one.
//
-
+
if (FS_SUPPORTS_FILE_STATE_CACHE( instanceContext->VolumeFSType )) {
PAV_GENERIC_TABLE_ENTRY entry = NULL;
AvAcquireResourceExclusive( &instanceContext->Resource );
-
+
while (!RtlIsGenericTableEmpty( &instanceContext->FileStateCacheTable ) ) {
entry = RtlGetElementGenericTable(&instanceContext->FileStateCacheTable, 0);
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
- ("[AV] AvInstanceTeardownStart: %I64x,%I64x requesting deletion, state:%d\n",
+ ("[AV] AvInstanceTeardownStart: %I64x,%I64x requesting deletion, state:%d\n",
entry->FileId.FileId64.UpperZeroes,
entry->FileId.FileId64.Value,
entry->InfectedState) );
RtlDeleteElementGenericTable(&instanceContext->FileStateCacheTable, entry);
}
-
+
AvReleaseResource( &instanceContext->Resource );
}
-
+
FltReleaseContext( instanceContext );
-
+
FltDeleteInstanceContext( FltObjects->Instance, NULL );
}
@@ -673,15 +674,13 @@ Return Value:
NTSTATUS status = STATUS_SUCCESS;
PSECURITY_DESCRIPTOR sd = NULL;
- UNREFERENCED_PARAMETER( RegistryPath );
-
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[AV] DriverEntry: Entered\n") );
//
// Set default global configuration
//
-
+
RtlZeroMemory( &Globals, sizeof(Globals) );
InitializeListHead( &Globals.ScanCtxListHead );
ExInitializeResourceLite( &Globals.ScanCtxListLock );
@@ -691,7 +690,7 @@ Return Value:
Globals.NetworkScanTimeout = 60000;
#if DBG
-
+
Globals.DebugLevel = 0xffffffff; // AVDBG_TRACE_ERROR | AVDBG_TRACE_DEBUG;
#endif
@@ -702,7 +701,7 @@ Return Value:
// Set the filter configuration based on registry keys
//
- status = AvSetConfiguration( RegistryPath );
+ status = AvSetConfiguration( DriverObject, RegistryPath );
if (!NT_SUCCESS( status )) {
@@ -710,7 +709,7 @@ Return Value:
("[AV]: DriverEntry: SetConfiguration FAILED. status = 0x%x\n", status) );
leave;
- }
+ }
//
// Register with FltMgr to tell it our callback routines
@@ -721,19 +720,19 @@ Return Value:
&Globals.Filter );
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] DriverEntry: FltRegisterFilter FAILED. status = 0x%x\n", status) );
leave;
}
-
+
//
// Builds a default security descriptor for use with FltCreateCommunicationPort.
//
-
+
status = FltBuildDefaultSecurityDescriptor( &sd,
FLT_PORT_ALL_ACCESS );
-
+
if (!NT_SUCCESS( status )) {
@@ -744,34 +743,34 @@ Return Value:
//
// Prepare ports between kernel and user.
//
-
+
status = AvPrepareServerPort( sd, AvConnectForScan );
-
+
if (!NT_SUCCESS( status )) {
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] DriverEntry: AvPrepareServerPort Scan Port FAILED. status = 0x%x\n", status) );
leave;
}
-
+
status = AvPrepareServerPort( sd, AvConnectForAbort );
-
+
if (!NT_SUCCESS( status )) {
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] DriverEntry: AvPrepareServerPort Abort Port FAILED. status = 0x%x\n", status) );
leave;
}
-
+
status = AvPrepareServerPort( sd, AvConnectForQuery );
-
+
if (!NT_SUCCESS( status )) {
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] DriverEntry: AvPrepareServerPort Query Port FAILED. status = 0x%x\n", status) );
leave;
}
-
+
//
// Start filtering i/o
//
@@ -784,16 +783,16 @@ Return Value:
("[AV] DriverEntry: FltStartFiltering FAILED. status = 0x%x\n", status) );
leave;
}
-
+
} finally {
-
+
if ( sd != NULL ) {
-
+
FltFreeSecurityDescriptor( sd );
}
-
+
if (!NT_SUCCESS( status ) ) {
-
+
if (NULL != Globals.ScanServerPort) {
FltCloseCommunicationPort( Globals.ScanServerPort );
@@ -807,13 +806,13 @@ Return Value:
FltCloseCommunicationPort( Globals.QueryServerPort );
}
if (NULL != Globals.Filter) {
-
+
FltUnregisterFilter( Globals.Filter );
Globals.Filter = NULL;
}
- ExDeleteResourceLite( &Globals.ScanCtxListLock );
- }
+ ExDeleteResourceLite( &Globals.ScanCtxListLock );
+ }
}
return status;
@@ -848,20 +847,20 @@ Return Value:
AV_DBG_PRINT( AVDBG_TRACE_DEBUG,
("[AV] AvUnload: Entered\n") );
-
+
//
// Traverse the scan context list, and cancel the scan if it exists.
//
-
+
AvAcquireResourceExclusive( &Globals.ScanCtxListLock );
Globals.Unloading = TRUE;
AvReleaseResource( &Globals.ScanCtxListLock );
-
+
//
- // This function will wait for the user to abort the outstanding scan and
- // close the section
+ // This function will wait for the user to abort the outstanding scan and
+ // close the section
//
-
+
AvSendUnloadingToUser();
FltCloseCommunicationPort( Globals.ScanServerPort );
@@ -872,7 +871,7 @@ Return Value:
Globals.QueryServerPort = NULL;
FltUnregisterFilter( Globals.Filter ); // This will typically trigger instance tear down.
Globals.Filter = NULL;
-
+
ExDeleteResourceLite( &Globals.ScanCtxListLock );
return STATUS_SUCCESS;
@@ -884,7 +883,7 @@ Return Value:
*************************************************************************/
BOOLEAN
-AvOperationsModifyingFile (
+AvOperationsModifyingFile (
_In_ PFLT_CALLBACK_DATA Data
)
/*++
@@ -905,14 +904,14 @@ Return Value:
--*/
{
PFLT_IO_PARAMETER_BLOCK iopb = Data->Iopb;
-
+
PAGED_CODE();
switch(iopb->MajorFunction) {
-
+
case IRP_MJ_WRITE:
return TRUE;
-
+
case IRP_MJ_FILE_SYSTEM_CONTROL:
switch ( iopb->Parameters.FileSystemControl.Common.FsControlCode ) {
case FSCTL_OFFLOAD_WRITE:
@@ -922,7 +921,7 @@ Return Value:
default: break;
}
break;
-
+
case IRP_MJ_SET_INFORMATION:
switch ( iopb->Parameters.SetFileInformation.FileInformationClass ) {
case FileEndOfFileInformation:
@@ -947,11 +946,11 @@ AvQueryTransactionOutcome(
Routine Description:
This is a helper function that qeury the KTM that how trasnaction was ended.
-
+
Arguments:
Transaction - Pointer to transaction object.
-
+
TxOutcome - Output. Specifies the type of transaction outcome.
Return Value:
@@ -962,9 +961,9 @@ Return Value:
HANDLE transactionHandle;
NTSTATUS status;
TRANSACTION_BASIC_INFORMATION txBasicInfo = {0};
-
+
PAGED_CODE();
-
+
status = ObOpenObjectByPointer( Transaction,
OBJ_KERNEL_HANDLE,
NULL,
@@ -972,9 +971,9 @@ Return Value:
*TmTransactionObjectType,
KernelMode,
&transactionHandle );
-
+
if (!NT_SUCCESS(status)) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvQueryTransactionOutcome: ObOpenObjectByPointer failed.\n") );
return status;
@@ -986,18 +985,18 @@ Return Value:
sizeof(TRANSACTION_BASIC_INFORMATION),
NULL );
if (!NT_SUCCESS(status)) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvQueryTransactionOutcome: ObOpenObjectByPointer failed.\n") );
goto Cleanup;
}
-
+
*TxOutcome = txBasicInfo.Outcome;
-
+
Cleanup:
ZwClose(transactionHandle);
-
+
return status;
}
@@ -1012,46 +1011,46 @@ AvPropagateFileState(
Routine Description:
An inline function that propagate the TxState to State in stream context.
-
+
Arguments:
StreamContext - The stream context to be propagated.
-
+
TransactionOutcome - TRANSACTION_OUTCOME enumeration indicating how transaction was ended.
-
+
Return Value:
None.
-
+
--*/
{
//
// Only when the transaction was committed will we propagate the state.
//
-
+
if (TransactionOutcome == TransactionOutcomeCommitted) {
-
+
AV_FILE_INFECTED_STATE oldTxState = InterlockedExchange( &StreamContext->TxState, AvFileModified );
switch (oldTxState) {
case AvFileModified:
case AvFileInfected:
case AvFileNotInfected:
-
+
//
// Propagate the file state from TxState to State.
//
-
+
InterlockedExchange( &StreamContext->State, oldTxState );
break;
case AvFileScanning:
-
+
//
// It is possible at KTM callback, file Tx state is still in scanning.
- // All we can do here is to be conservative, that is to assume that
+ // All we can do here is to be conservative, that is to assume that
// this commit did involve the modification of the file.
//
-
+
InterlockedExchange( &StreamContext->State, AvFileModified );
break;
default:
@@ -1059,15 +1058,15 @@ Return Value:
break;
}
}
-
+
//
// Either cleanup or commited, we need to reset TxState to be default state.
//
-
+
SET_FILE_TX_MODIFIED( StreamContext );
}
-NTSTATUS
+NTSTATUS
AvProcessTransactionOutcome (
_Inout_ PAV_TRANSACTION_CONTEXT TransactionContext,
_In_ ULONG TransactionOutcome
@@ -1076,21 +1075,21 @@ AvProcessTransactionOutcome (
Routine Description:
- This is a helper function that process transaction commitment or rollback
-
+ This is a helper function that process transaction commitment or rollback
+
Arguments:
TransactionContext - Pointer to the minifilter driver's transaction context
set at PostCreate.
-
+
TransactionOutcome - Specifies the type of notifications. Should be either
TransactionOutcomeCommitted or TransactionOutcomeAborted
Return Value:
- STATUS_SUCCESS - Returning this status value indicates that the minifilter
+ STATUS_SUCCESS - Returning this status value indicates that the minifilter
driver is finished with the transaction. This is a success code.
-
+
--*/
{
PLIST_ENTRY scan;
@@ -1099,7 +1098,7 @@ Return Value:
PAV_TRANSACTION_CONTEXT oldTxCtx = NULL;
PAGED_CODE();
-
+
//
// Tranversing the stream context list, and
// sync the TxState -> State.
@@ -1107,21 +1106,21 @@ Return Value:
// Either commit or rollback, we need to cleanup the list
// Tear down stream context list inside transactionContext
//
-
+
AvAcquireResourceExclusive( TransactionContext->Resource );
-
+
LIST_FOR_EACH_SAFE( scan, next, &TransactionContext->ScListHead ) {
-
+
streamContext = CONTAINING_RECORD( scan, AV_STREAM_CONTEXT, ListInTransaction );
oldTxCtx = InterlockedCompareExchangePointer( &streamContext->TxContext, NULL, TransactionContext );
if (oldTxCtx == TransactionContext) {
-
+
//
// The exchange pointer was successful
//
RemoveEntryList ( scan );
-
+
AV_DBG_PRINT( AVDBG_TRACE_DEBUG,
("[AV] AvProcessTransactionOutcome: Requesting deletion of entry in transaction context: %I64x,%I64x, modified: %d\n",
streamContext->FileId.FileId64.UpperZeroes,
@@ -1134,7 +1133,7 @@ Return Value:
}
SetFlag( TransactionContext->Flags, AV_TXCTX_LISTDRAINED );
AvReleaseResource( TransactionContext->Resource );
-
+
return STATUS_SUCCESS;
}
@@ -1145,20 +1144,20 @@ AvLoadFileStateFromCache (
_Out_ LONG volatile *State,
_Out_ PLONGLONG VolumeRevision,
_Out_ PLONGLONG CacheRevision,
- _Out_ PLONGLONG FileRevision
+ _Out_ PLONGLONG FileRevision
)
/*++
Routine Description:
- This routine lookups the file state in the cache table.
+ This routine lookups the file state in the cache table.
Arguments:
Instance - Opaque filter pointer for the caller. This parameter is required and cannot be NULL.
-
+
FileID - The ID to lookup in the cache
-
+
State - The cached state for the file
Return Value:
@@ -1171,7 +1170,7 @@ Return Value:
PAV_INSTANCE_CONTEXT instanceContext = NULL;
AV_GENERIC_TABLE_ENTRY query = {0};
PAV_GENERIC_TABLE_ENTRY entry = NULL;
-
+
PAGED_CODE();
//
@@ -1195,8 +1194,8 @@ Return Value:
goto Cleanup;
}
- RtlCopyMemory( &query.FileId, FileId, sizeof(query.FileId) );
-
+ RtlCopyMemory( &query.FileId, FileId, sizeof(query.FileId) );
+
AvAcquireResourceShared( &instanceContext->Resource );
entry = RtlLookupElementGenericTable( &instanceContext->FileStateCacheTable,
@@ -1234,9 +1233,9 @@ Routine Description:
Arguments:
Instance - Opaque filter pointer for the caller. This parameter is required and cannot be NULL.
-
+
StreamContext - The stream context of the target file.
-
+
Return Value:
Returns the final status of this operation.
@@ -1274,7 +1273,7 @@ Return Value:
}
//
- // If originally, we failed to get the file id,
+ // If originally, we failed to get the file id,
// then we do not cache it.
//
@@ -1286,7 +1285,7 @@ Return Value:
// If the file system is NTFS, CSVFS or REFS, overwrite the entry in the
// cache table if exists
//
-
+
RtlCopyMemory( &entry.FileId, &StreamContext->FileId, sizeof(entry.FileId) );
AvAcquireResourceExclusive( &instanceContext->Resource );
@@ -1302,9 +1301,9 @@ Return Value:
//
//
- // It is possible that after entering the following else-if
- // branch, thread A modifies the file, and before thread A
- // closes the handle, thread B opens the same file. This
+ // It is possible that after entering the following else-if
+ // branch, thread A modifies the file, and before thread A
+ // closes the handle, thread B opens the same file. This
// is fine because in such a case, the streamcontext exists
// AvLoadFileStateFromCache would return the state in stream
// context. Thus, thread B will need to scan the file.
@@ -1327,7 +1326,7 @@ Return Value:
Cleanup:
FltReleaseContext( instanceContext );
- return status;
+ return status;
}
BOOLEAN
@@ -1340,13 +1339,13 @@ AvIsPrefetchEcpPresent (
Routine Description:
This local function will return if this data stream is alternate or not.
- It by default returns FALSE if it fails to retrieve the name information
+ It by default returns FALSE if it fails to retrieve the name information
from the file system.
-
+
Arguments:
Data - Pointer to the filter callbackData that is passed to us.
-
+
Return Value:
TRUE - This data stream is alternate.
@@ -1357,13 +1356,13 @@ Return Value:
NTSTATUS status;
PECP_LIST ecpList;
PVOID ecpContext;
-
+
PAGED_CODE();
status = FltGetEcpListFromCallbackData( Filter, Data, &ecpList );
if (NT_SUCCESS(status) && (ecpList != NULL)) {
-
+
status = FltFindExtraCreateParameter( Filter,
ecpList,
&GUID_ECP_PREFETCH_OPEN,
@@ -1373,7 +1372,7 @@ Return Value:
if (NT_SUCCESS(status)) {
if (!FltIsEcpFromUserMode( Filter, ecpContext )) {
- return TRUE;
+ return TRUE;
}
}
}
@@ -1390,13 +1389,13 @@ AvIsStreamAlternate(
Routine Description:
This local function will return if this data stream is alternate or not.
- It by default returns FALSE if it fails to retrieve the name information
+ It by default returns FALSE if it fails to retrieve the name information
from the file system.
-
+
Arguments:
Data - Pointer to the filter callbackData that is passed to us.
-
+
Return Value:
TRUE - This data stream is alternate.
@@ -1409,32 +1408,32 @@ Return Value:
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
PAGED_CODE();
-
+
status = FltGetFileNameInformation( Data,
FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
&nameInfo );
-
+
if (!NT_SUCCESS(status)) {
-
+
goto Cleanup;
}
status = FltParseFileNameInformation( nameInfo );
if (!NT_SUCCESS(status)) {
-
+
goto Cleanup;
}
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
- ("[Av]: Dir: %wZ, FinalComponent: %wZ, Stream: %wZ, sLen: %d\n",
+ ("[Av]: Dir: %wZ, FinalComponent: %wZ, Stream: %wZ, sLen: %d\n",
nameInfo->ParentDir,
nameInfo->FinalComponent,
nameInfo->Stream,
nameInfo->Stream.Length) );
-
+
alternate = (nameInfo->Stream.Length > 0);
-
+
Cleanup:
if (nameInfo != NULL) {
@@ -1466,13 +1465,13 @@ Arguments:
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance, its associated volume and
file object.
-
+
ScanMode - Can either be AvUserMode or AvKernelMode.
-
+
IOMajorFunctionAtScan - Major function of an IRP.
-
+
StreamContext - The stream context of the target file.
-
+
Return Value:
Returns the final status of this operation.
@@ -1485,20 +1484,20 @@ Return Value:
LONGLONG fileSize;
FLT_VOLUME_PROPERTIES volumeProperties;
ULONG volumePropertiesLength;
-
+
PAGED_CODE();
-
+
//
// Skip the empty file.
//
-
+
status = AvGetFileSize( FltObjects->Instance,
- FltObjects->FileObject,
+ FltObjects->FileObject,
&fileSize );
- if (NT_SUCCESS( status ) &&
+ if (NT_SUCCESS( status ) &&
(0 == fileSize)) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[Av]: AvScan: Skip the EMPTY file.\n") );
@@ -1511,9 +1510,9 @@ Return Value:
// We could cause deadlocks if the thread were suspended once
// we have started scanning so enter a critical region.
//
-
+
FsRtlEnterFileSystem();
-
+
//
// Wait here for an existing scan on the stream to complete.
// We wait indefinitely since scans themselves will timeout.
@@ -1531,7 +1530,7 @@ Return Value:
//
if (IS_FILE_NEED_SCAN( StreamContext )){
-
+
if (ScanMode == AvUserMode) {
status = FltGetVolumeProperties( FltObjects->Volume,
@@ -1541,21 +1540,21 @@ Return Value:
if (!NT_SUCCESS(status)) {
volumeProperties.DeviceType = FILE_DEVICE_NETWORK;
}
-
+
//
- // If the scan mode is user mode, the section context will
+ // If the scan mode is user mode, the section context will
// be created as needed (at MessageNotification callback).
//
- // Setting the file state will be done at
+ // Setting the file state will be done at
// MessageNotification callback as well.
//
-
+
status = AvScanInUser( Data,
FltObjects,
IOMajorFunctionAtScan,
IsInTxWriter,
volumeProperties.DeviceType );
-
+
if (!NT_SUCCESS( status ) || status == STATUS_TIMEOUT) {
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
@@ -1564,37 +1563,37 @@ Return Value:
} else {
- status = AvScanInKernel( FltObjects,
+ status = AvScanInKernel( FltObjects,
IOMajorFunctionAtScan,
IsInTxWriter,
StreamContext );
-
+
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[AV] AvScan: failed to scan the file.\n") );
}
}
-
+
}
//
// Signal ScanSynchronizationEvent to release any con-current scan of the stream,
- //
- KeSetEvent( StreamContext->ScanSynchronizationEvent, 0, FALSE );
+ //
+ KeSetEvent( StreamContext->ScanSynchronizationEvent, 0, FALSE );
} else if (IOMajorFunctionAtScan == IRP_MJ_CREATE) {
//
- // I/O requesting thread if waiting on synchronization event is cancelled,
+ // I/O requesting thread if waiting on synchronization event is cancelled,
// we need to clean up the file object too.
//
AvCancelFileOpen(Data, FltObjects, status);
}
-
+
FsRtlExitFileSystem();
-
+
return status;
}
@@ -1612,7 +1611,7 @@ Routine Description:
Arguments:
ScanContext - The scan context.
-
+
SectionContext - The section context associated with the scan context.
Return Value:
@@ -1623,9 +1622,9 @@ Return Value:
{
NTSTATUS status;
PAV_STREAM_CONTEXT streamContext = NULL;
-
+
PAGED_CODE();
-
+
AvFinalizeSectionContext( SectionContext );
status = FltGetStreamContext( ScanContext->FilterInstance,
@@ -1633,21 +1632,21 @@ Return Value:
&streamContext );
if (NT_SUCCESS( status )) {
-
+
KeSetEvent( streamContext->ScanSynchronizationEvent, 0, FALSE );
FltReleaseContext( streamContext );
}
-
+
//
// Release I/O request thread.
//
-
+
KeSetEvent( &ScanContext->ScanCompleteNotification, 0, FALSE );
return;
}
NTSTATUS
-AvSendAbortToUser (
+AvSendAbortToUser (
_In_ ULONG ScanThreadId,
_In_ LONGLONG ScanId
)
@@ -1656,7 +1655,7 @@ AvSendAbortToUser (
Routine Description:
This routine sends an abortion message to the user scan thread.
- The cancel callback is asynchronous and thus we send which
+ The cancel callback is asynchronous and thus we send which
scan id to abort; otherwise the worker thread in the user
may abort the 'next' scan task.
@@ -1676,19 +1675,19 @@ Return Value:
ULONG replyLength = 0;
LARGE_INTEGER timeout = {0};
AV_SCANNER_NOTIFICATION notification = {0};
-
+
PAGED_CODE();
-
+
notification.Message = AvMsgAbortScanning;
notification.ScanThreadId = ScanThreadId;
notification.ScanId = ScanId;
-
+
timeout.QuadPart = -((LONGLONG)10) * (LONGLONG)1000 * (LONGLONG)1000; // 1s
-
+
//
// Tell the user-scanner to abort the scan.
//
-
+
status = FltSendMessage( Globals.Filter,
&Globals.AbortClientPort,
&notification,
@@ -1697,11 +1696,11 @@ Return Value:
&replyLength,
&timeout );
-
- if (!NT_SUCCESS( status ) ||
+
+ if (!NT_SUCCESS( status ) ||
(status == STATUS_TIMEOUT)) {
-
- if ((status != STATUS_PORT_DISCONNECTED) &&
+
+ if ((status != STATUS_PORT_DISCONNECTED) &&
(status != STATUS_TIMEOUT)) {
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
@@ -1714,7 +1713,7 @@ Return Value:
}
NTSTATUS
-AvSendUnloadingToUser (
+AvSendUnloadingToUser (
VOID
)
/*++
@@ -1737,19 +1736,19 @@ Return Value:
NTSTATUS status = STATUS_SUCCESS;
ULONG replyLength = sizeof(ULONG);
AV_SCANNER_NOTIFICATION notification = {0};
-
+
PAGED_CODE();
-
+
notification.Message = AvMsgFilterUnloading;
-
+
//
// Tell the user-scanner that we are unloading the filter.
// and waits for its reply.
//
-
+
AV_DBG_PRINT( AVDBG_TRACE_DEBUG,
("[Av]: AvSendUnloadingToUser: BEFORE...\n") );
-
+
status = FltSendMessage( Globals.Filter,
&Globals.AbortClientPort,
&notification,
@@ -1757,17 +1756,17 @@ Return Value:
&abortThreadId,
&replyLength,
NULL );
-
+
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[Av]: AvSendUnloadingToUser: Failed to FltSendMessage.\n, 0x%08x\n",
status) );
}
-
+
AV_DBG_PRINT( AVDBG_TRACE_DEBUG,
("[Av]: AvSendUnloadingToUser: After...\n") );
-
+
return status;
}
@@ -1785,8 +1784,8 @@ AvPreOperationCallback (
Routine Description:
- This routine is the registered callback routine for filtering
- the "write" operation, i.e. the operations that have potentials
+ This routine is the registered callback routine for filtering
+ the "write" operation, i.e. the operations that have potentials
to modify the file.
This is non-pageable because it could be called on the paging path
@@ -1799,7 +1798,7 @@ Arguments:
opaque handles to this filter, instance, its associated volume and
file object.
- CompletionContext - If this callback routine returns FLT_PREOP_SUCCESS_WITH_CALLBACK or
+ CompletionContext - If this callback routine returns FLT_PREOP_SUCCESS_WITH_CALLBACK or
FLT_PREOP_SYNCHRONIZE, this parameter is an optional context pointer to be passed to
the corresponding post-operation callback routine. Otherwise, it must be NULL.
@@ -1813,21 +1812,21 @@ Return Value:
PAV_STREAM_CONTEXT streamContext = NULL;
PAV_STREAMHANDLE_CONTEXT streamHandleContext = NULL;
ULONG flags;
-
+
UNREFERENCED_PARAMETER( CompletionContext );
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[AV] AvPreOperationCallback: Entered\n") );
if (!AvOperationsModifyingFile(Data)) {
-
+
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
//
// Skip prefetcher handles to avoid deadlocks
//
-
+
status = FltGetStreamHandleContext( FltObjects->Instance,
FltObjects->FileObject,
&streamHandleContext );
@@ -1836,20 +1835,20 @@ Return Value:
flags = streamHandleContext->Flags;
FltReleaseContext( streamHandleContext );
-
+
if (FlagOn( flags, AV_FLAG_PREFETCH )) {
return FLT_PREOP_SUCCESS_NO_CALLBACK;
- }
+ }
}
status = FltGetStreamContext( FltObjects->Instance,
FltObjects->FileObject,
&streamContext );
-
+
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
- ("[AV] AvPreOperationCallback: get stream context failed. rq: %d\n",
+ ("[AV] AvPreOperationCallback: get stream context failed. rq: %d\n",
Data->Iopb->MajorFunction) );
return FLT_PREOP_SUCCESS_NO_CALLBACK;
@@ -1858,10 +1857,10 @@ Return Value:
//
// If this operation is performed in a transacted writer view.
//
-
+
if ((streamContext->TxContext != NULL) &&
(FltObjects->Transaction != NULL)) {
-
+
#if DBG
PAV_TRANSACTION_CONTEXT transactionContext = NULL;
@@ -1870,32 +1869,32 @@ Return Value:
&transactionContext );
FLT_ASSERTMSG( "Transaction context should not fail, because it is supposed to be created at post create.\n", NT_SUCCESS( statusTx ));
- FLT_ASSERTMSG( "The file's TxCtx should be identical with the target TxCtx.\n",
+ FLT_ASSERTMSG( "The file's TxCtx should be identical with the target TxCtx.\n",
streamContext->TxContext == transactionContext);
if (NT_SUCCESS( statusTx )) {
FltReleaseContext( transactionContext );
}
-
+
#endif // DBG
-
+
//
- // Instead of updating State, we update TxState here,
+ // Instead of updating State, we update TxState here,
// because the file is part of a transaction writer
//
-
+
SET_FILE_TX_MODIFIED( streamContext );
-
+
} else {
-
+
//
// Consider an optimization for the case where another thread
// is already scanning the file as it is being modified here.
//
-
+
SET_FILE_MODIFIED( streamContext );
}
-
+
FltReleaseContext( streamContext );
return FLT_PREOP_SUCCESS_NO_CALLBACK;
@@ -1922,7 +1921,7 @@ Arguments:
opaque handles to this filter, instance, its associated volume and
file object.
- CompletionContext - If this callback routine returns FLT_PREOP_SUCCESS_WITH_CALLBACK or
+ CompletionContext - If this callback routine returns FLT_PREOP_SUCCESS_WITH_CALLBACK or
FLT_PREOP_SYNCHRONIZE, this parameter is an optional context pointer to be passed to
the corresponding post-operation callback routine. Otherwise, it must be NULL.
@@ -1934,15 +1933,15 @@ Return Value:
{
PAGED_CODE();
-
+
if (Data->Iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_TXFS_SAVEPOINT_INFORMATION ) {
-
- //
+
+ //
// We explicitly fail the request of save point here since we
// are deprecating savepoint support for the OS version targeted
- // for this filter.
+ // for this filter.
//
-
+
Data->IoStatus.Status = STATUS_NOT_SUPPORTED;
return FLT_PREOP_COMPLETE;
}
@@ -1960,7 +1959,7 @@ AvPreCreate (
Routine Description:
This routine is the pre-create completion routine.
-
+
Arguments:
@@ -1970,7 +1969,7 @@ Arguments:
opaque handles to this filter, instance, its associated volume and
file object.
- CompletionContext - If this callback routine returns FLT_PREOP_SUCCESS_WITH_CALLBACK or
+ CompletionContext - If this callback routine returns FLT_PREOP_SUCCESS_WITH_CALLBACK or
FLT_PREOP_SYNCHRONIZE, this parameter is an optional context pointer to be passed to
the corresponding post-operation callback routine. Otherwise, it must be NULL.
@@ -1985,33 +1984,33 @@ Return Value:
ULONG_PTR stackHigh;
PFILE_OBJECT FileObject = Data->Iopb->TargetFileObject;
AV_STREAMHANDLE_CONTEXT streamHandleContext;
-
-
+
+
PAGED_CODE();
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[AV] AvPreCreate: Entered\n") );
streamHandleContext.Flags = 0;
-
+
//
// Stack file objects are never scanned.
//
IoGetStackLimits( &stackLow, &stackHigh );
- if (((ULONG_PTR)FileObject > stackLow) &&
+ if (((ULONG_PTR)FileObject > stackLow) &&
((ULONG_PTR)FileObject < stackHigh)) {
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
-
+
//
// Directory opens don't need to be scanned.
//
if (FlagOn( Data->Iopb->Parameters.Create.Options, FILE_DIRECTORY_FILE )) {
-
+
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
@@ -2020,27 +2019,27 @@ Return Value:
//
if ( FlagOn( Data->Iopb->OperationFlags, SL_OPEN_TARGET_DIRECTORY )) {
-
+
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
-
+
//
// Skip paging files.
//
if (FlagOn( Data->Iopb->OperationFlags, SL_OPEN_PAGING_FILE )) {
-
+
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
//
- // Skip scanning DASD opens
+ // Skip scanning DASD opens
//
-
+
if (FlagOn( FltObjects->FileObject->Flags, FO_VOLUME_OPEN )) {
- return FLT_PREOP_SUCCESS_NO_CALLBACK;
- }
+ return FLT_PREOP_SUCCESS_NO_CALLBACK;
+ }
//
// Skip scanning any files being opened by CSVFS for its downlevel
@@ -2049,10 +2048,10 @@ Return Value:
//
if (AvIsCsvDlEcpPresent( FltObjects->Filter, Data ) ) {
- return FLT_PREOP_SUCCESS_NO_CALLBACK;
+ return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
-
+
//
// Flag prefetch handles so they can be skipped. Performing IO
// using a prefetch fileobject could lead to a deadlock.
@@ -2060,7 +2059,7 @@ Return Value:
if (AvIsPrefetchEcpPresent( FltObjects->Filter, Data )) {
- SetFlag( streamHandleContext.Flags, AV_FLAG_PREFETCH );
+ SetFlag( streamHandleContext.Flags, AV_FLAG_PREFETCH );
}
*CompletionContext = (PVOID)streamHandleContext.Flags;
@@ -2069,17 +2068,17 @@ Return Value:
// Perform any CSVFS pre create processing
//
AvPreCreateCsvfs( Data, FltObjects );
-
+
//
// return status can be safely ignored
//
-
+
//
- // Return FLT_PREOP_SYNCHRONIZE at PreCreate to ensure PostCreate
- // is in the same thread at passive level.
+ // Return FLT_PREOP_SYNCHRONIZE at PreCreate to ensure PostCreate
+ // is in the same thread at passive level.
// EResource can't be acquired at DPC.
//
-
+
return FLT_PREOP_SYNCHRONIZE;
}
@@ -2093,8 +2092,8 @@ AvProcessPreviousTransaction (
Routine Description:
- This routine is transaction related implementation, and is expected to be
- invoked at post-create. Note that this function will enlist the newly
+ This routine is transaction related implementation, and is expected to be
+ invoked at post-create. Note that this function will enlist the newly
allocated transaction context via FltEnlistInTransaction if it needs to.
Arguments:
@@ -2114,45 +2113,45 @@ Return Value:
NTSTATUS status = STATUS_SUCCESS;
PAV_TRANSACTION_CONTEXT oldTxCtx = NULL;
PAV_TRANSACTION_CONTEXT transactionContext = NULL;
-
+
PAGED_CODE();
- if (FltObjects->Transaction != NULL ) {
-
+ if (FltObjects->Transaction != NULL ) {
+
//
// Get transaction context
//
status = AvFindOrCreateTransactionContext( FltObjects,
&transactionContext );
-
+
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvProcessPreviousTransaction: AvFindOrCreateTransactionContext FAILED\n") );
transactionContext = NULL;
goto Cleanup;
}
-
+
//
// Enlist it if haven't.
//
-
+
if (! FlagOn(transactionContext->Flags, AV_TXCTX_ENLISTED) ) {
//
- // You can also consider to register TRANSACTION_NOTIFY_PREPARE,
+ // You can also consider to register TRANSACTION_NOTIFY_PREPARE,
// and scan the file at TRANSACTION_NOTIFY_PREPARE callback if it was modified.
//
-
+
status = FltEnlistInTransaction( FltObjects->Instance,
FltObjects->Transaction,
transactionContext,
TRANSACTION_NOTIFY_COMMIT_FINALIZE | TRANSACTION_NOTIFY_ROLLBACK );
-
+
if (!NT_SUCCESS( status ) &&
(status != STATUS_FLT_ALREADY_ENLISTED)) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvProcessPreviousTransaction: FltEnlistInTransaction FAILED!!!!\n") );
goto Cleanup;
@@ -2181,113 +2180,113 @@ Return Value:
// oldTxCtx : NULL
// transCtx : NULL
//
-
+
//
// Synchronize the replacement of StreamContext->TxContext with KTM callback.
//
-
+
oldTxCtx = InterlockedExchangePointer( &StreamContext->TxContext, transactionContext );
-
+
if (oldTxCtx != transactionContext) { // case 1,2,3
-
+
//
- // txOutcome is by default set as committed because we are conservative about
- // propagating the file state if AvQueryTransactionOutcome failed, it may cause
+ // txOutcome is by default set as committed because we are conservative about
+ // propagating the file state if AvQueryTransactionOutcome failed, it may cause
// redundant scan but will not overlook infected file anyway.
//
-
+
ULONG txOutcome = TransactionOutcomeCommitted;
if ( oldTxCtx == NULL ) { // case 1
-
+
// This file was not linked in a transaction context yet, and is about to.
//
// Increment TxContext's reference count because stream context has a reference to it.
//
-
+
FltReferenceContext ( transactionContext );
-
+
//
// Before insertion into the FcList in transaction context, we increment stream context's ref count
//
-
+
AvAcquireResourceExclusive( transactionContext->Resource );
-
+
if (!FlagOn(transactionContext->Flags, AV_TXCTX_LISTDRAINED)) {
-
+
FltReferenceContext ( StreamContext ); // Q
InsertTailList( &transactionContext->ScListHead,
&StreamContext->ListInTransaction );
}
-
+
AvReleaseResource( transactionContext->Resource );
-
+
goto Cleanup;
}
// case 2,3
-
+
//
- // We have to query transaction outcome in order to know how we
+ // We have to query transaction outcome in order to know how we
// can process the previously outstanding transaction context.
//
-
+
status = AvQueryTransactionOutcome( oldTxCtx->Transaction, &txOutcome );
-
+
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvProcessPreviousTransaction: AvQueryTransactionOutcome FAILED!!!!\n") );
-
+
//
- // We have exchanged the pointer anyway, if we cannot query its outcome,
+ // We have exchanged the pointer anyway, if we cannot query its outcome,
// we have to go through.
//
}
-
+
AvAcquireResourceExclusive( oldTxCtx->Resource );
RemoveEntryList ( &StreamContext->ListInTransaction );
AvReleaseResource( oldTxCtx->Resource );
-
+
AvPropagateFileState ( StreamContext, txOutcome );
-
+
if ( transactionContext ) { // case 3
-
+
FltReferenceContext( transactionContext );
-
+
AvAcquireResourceExclusive( transactionContext->Resource );
if (!FlagOn(transactionContext->Flags, AV_TXCTX_LISTDRAINED)) {
-
+
InsertTailList( &transactionContext->ScListHead,
&StreamContext->ListInTransaction );
} else {
-
+
FltReleaseContext( StreamContext );
}
-
+
AvReleaseResource( transactionContext->Resource );
-
+
} else { // case 2
-
+
FltReleaseContext ( StreamContext ); // Release reference count at Q
}
-
+
// case 2,3
-
+
FltReleaseContext( oldTxCtx ); // Release reference count in stream context originally.
-
+
}
-
+
//
// We don't care about case 4, 5.
//
-
+
Cleanup:
if (transactionContext) {
-
+
FltReleaseContext( transactionContext ); // Release the ref count grabbed at AvFindOrCreateTransactionContext(...)
}
@@ -2307,8 +2306,8 @@ Routine Description:
This routine is the post-create completion routine.
In this routine, stream context and/or transaction context shall be
created if not exits.
-
- Note that we only allocate and set the stream context to filter manager
+
+ Note that we only allocate and set the stream context to filter manager
at post create.
Arguments:
@@ -2332,7 +2331,7 @@ Return Value:
NTSTATUS status = Data->IoStatus.Status;
BOOLEAN isDir = FALSE;
BOOLEAN isTxWriter = FALSE;
-
+
PAV_STREAM_CONTEXT streamContext = NULL;
PAV_STREAM_CONTEXT oldStreamContext = NULL;
PAV_STREAMHANDLE_CONTEXT streamHandleContext = NULL;
@@ -2340,15 +2339,15 @@ Return Value:
BOOLEAN updateRevisionNumbers;
LONGLONG VolumeRevision, CacheRevision, FileRevision;
-
+
UNREFERENCED_PARAMETER( CompletionContext );
UNREFERENCED_PARAMETER( Flags );
-
+
PAGED_CODE();
-
+
if (!NT_SUCCESS( status ) ||
(status == STATUS_REPARSE)) {
-
+
//
// File Creation may fail.
//
@@ -2358,7 +2357,7 @@ Return Value:
return FLT_POSTOP_FINISHED_PROCESSING;
}
-
+
//
// After creation, skip it if it is directory.
//
@@ -2366,29 +2365,29 @@ Return Value:
status = FltIsDirectory( FltObjects->FileObject,
FltObjects->Instance,
&isDir );
-
+
//
// If FltIsDirectory failed, we do not know if it is a directoy,
// we let it go through because if it is a directory, it will fail
// at section creation anyway.
//
-
+
if ( NT_SUCCESS( status ) && isDir ) {
-
+
return FLT_POSTOP_FINISHED_PROCESSING;
}
//
// We skip the encrypted file open without FILE_WRITE_DATA and FILE_READ_DATA
- // This is because if application calls OpenEncryptedFileRaw(...) for backup,
- // it won't have to decrypt the file. In such case, if we scan it, we will hit
+ // This is because if application calls OpenEncryptedFileRaw(...) for backup,
+ // it won't have to decrypt the file. In such case, if we scan it, we will hit
// an assertion error in NTFS because it does not have the encryption context.
// Thus, we have to skip the encrypted file not open for read/write.
//
-
- if (!(FlagOn(desiredAccess, FILE_WRITE_DATA)) &&
+
+ if (!(FlagOn(desiredAccess, FILE_WRITE_DATA)) &&
!(FlagOn(desiredAccess, FILE_READ_DATA)) ) {
-
+
BOOLEAN encrypted = FALSE;
status = AvGetFileEncrypted( FltObjects->Instance,
FltObjects->FileObject,
@@ -2399,18 +2398,18 @@ Return Value:
("[AV] AvPostCreate: AvGetFileEncrypted FAILED!! \n0x%x\n", status) );
}
if (encrypted) {
-
+
return FLT_POSTOP_FINISHED_PROCESSING;
}
}
-
+
//
- // In this sample, we skip the alternate data stream. However, you may decide
+ // In this sample, we skip the alternate data stream. However, you may decide
// to scan it and modify accordingly.
//
-
+
if (AvIsStreamAlternate( Data )) {
-
+
return FLT_POSTOP_FINISHED_PROCESSING;
}
@@ -2422,20 +2421,20 @@ Return Value:
if (FlagOn((ULONG_PTR)CompletionContext, AV_FLAG_PREFETCH)) {
if (!FltSupportsStreamHandleContexts( FltObjects->FileObject )) {
-
+
return FLT_POSTOP_FINISHED_PROCESSING;
}
- status = AvCreateStreamHandleContext( FltObjects->Filter,
+ status = AvCreateStreamHandleContext( FltObjects->Filter,
&streamHandleContext );
if (!NT_SUCCESS(status)) {
-
- return FLT_POSTOP_FINISHED_PROCESSING;
+
+ return FLT_POSTOP_FINISHED_PROCESSING;
}
SetFlag( streamHandleContext->Flags, AV_FLAG_PREFETCH );
-
+
status = FltSetStreamHandleContext( FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
@@ -2445,84 +2444,84 @@ Return Value:
FltReleaseContext( streamHandleContext );
if (!NT_SUCCESS(status)) {
-
+
//
// Shouldn't find the handle already set
//
-
+
ASSERT( status != STATUS_FLT_CONTEXT_ALREADY_DEFINED );
}
- return FLT_POSTOP_FINISHED_PROCESSING;
+ return FLT_POSTOP_FINISHED_PROCESSING;
}
-
+
//
// Find or create a stream context
//
status = FltGetStreamContext( FltObjects->Instance,
FltObjects->FileObject,
- &streamContext );
+ &streamContext );
if (status == STATUS_NOT_FOUND) {
-
+
//
// Create a stream context
//
-
+
status = AvCreateStreamContext( FltObjects->Filter, &streamContext );
-
+
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[Av]: Failed to create stream context with status 0x%x. (FileObject = %p, Instance = %p)\n",
status,
FltObjects->FileObject,
FltObjects->Instance) );
-
+
return FLT_POSTOP_FINISHED_PROCESSING;
}
-
+
//
// Attempt to get the stream infected state from our cache
- //
-
+ //
+
status = AvGetFileId( FltObjects->Instance, FltObjects->FileObject, &streamContext->FileId );
-
+
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[Av]: Failed to get file id with status 0x%x. (FileObject = %p, Instance = %p)\n",
status,
FltObjects->FileObject,
FltObjects->Instance) );
-
+
//
// File id is optional and therefore should not affect the scan logic.
//
-
+
AV_SET_INVALID_FILE_REFERENCE( streamContext->FileId )
-
+
} else {
//
- // This function will load the file infected state from the
+ // This function will load the file infected state from the
// cache if the fileID is valid. Even if this function fails,
// we still have to move on because the cache is optional.
//
- AvLoadFileStateFromCache( FltObjects->Instance,
+ AvLoadFileStateFromCache( FltObjects->Instance,
&streamContext->FileId,
&streamContext->State,
&streamContext->VolumeRevision,
&streamContext->CacheRevision,
- &streamContext->FileRevision );
+ &streamContext->FileRevision );
}
-
+
//
// Set the new context we just allocated on the file object
//
-
+
status = FltSetStreamContext( FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
@@ -2537,7 +2536,7 @@ Return Value:
// Race condition. Someone has set a context after we queried it.
// Use the already set context instead
//
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[Av]: Race: Stream context already defined. Retaining old stream context %p (FileObject = %p, Instance = %p)\n",
oldStreamContext,
@@ -2558,50 +2557,50 @@ Return Value:
goto Cleanup;
}
}
-
+
} else if (!NT_SUCCESS(status)) {
//
// We will get here if stream contexts are not supported
//
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[Av]: Failed to get stream context with status 0x%x. (FileObject = %p, Instance = %p)\n",
status,
FltObjects->FileObject,
FltObjects->Instance) );
-
+
return FLT_POSTOP_FINISHED_PROCESSING;
}
-
+
//
// If successfully opened a file with the desired access matching
- // the "exclusive write" from a TxF point of view, we can guarantee that
- // if previous transaction context exists, it must have been comitted
+ // the "exclusive write" from a TxF point of view, we can guarantee that
+ // if previous transaction context exists, it must have been comitted
// or rollbacked.
//
-
+
if (FlagOn( Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess,
FILE_WRITE_DATA | FILE_APPEND_DATA |
DELETE | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA |
WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY ) ) {
-
+
//
// Either this file is opened in a transaction context or not,
// we need to process the previous transaction if it exists.
// AvProcessPreviousTransaction(...) handles these cases.
//
-
+
status = AvProcessPreviousTransaction ( FltObjects,
streamContext );
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvPostCreate: AvProcessTransaction FAILED!! \n") );
goto Cleanup;
}
-
+
isTxWriter = (FltObjects->Transaction != NULL);
}
@@ -2620,9 +2619,9 @@ Return Value:
//
-
+
if (IS_FILE_NEED_SCAN( streamContext )) {
-
+
status = AvScan( Data,
FltObjects,
AvUserMode,
@@ -2631,7 +2630,7 @@ Return Value:
streamContext );
if (!NT_SUCCESS( status ) ||
(STATUS_TIMEOUT == status)) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[AV] AvPostCreate: AvScan FAILED!! \n") );
@@ -2648,7 +2647,7 @@ Return Value:
streamContext->VolumeRevision = VolumeRevision;
streamContext->CacheRevision = CacheRevision;
streamContext->FileRevision = FileRevision;
-
+
AV_DBG_PRINT( AVDBG_TRACE_DEBUG,
("[Av]: AvPostCreate: RevisionNumbers updated to %I64x:%I64x:%I64x\n",
VolumeRevision,
@@ -2656,30 +2655,30 @@ Return Value:
FileRevision)
);
}
-
+
if (IS_FILE_INFECTED( streamContext )) {
-
+
//
// If the file is infected, deny the access.
//
AvCancelFileOpen(Data, FltObjects, STATUS_VIRUS_INFECTED);
//
- // If the scan timed-out or scan was failed, we let the create succeed,
+ // If the scan timed-out or scan was failed, we let the create succeed,
// and it may cause security hole;
//
// Alternatively, you can add a state called AvFileScanFailure or equivalent,
- // add a condition here and fail the create. This option will have better
- // protection from viruses, but the apps will see the failures due to a
+ // add a condition here and fail the create. This option will have better
+ // protection from viruses, but the apps will see the failures due to a
// lengthy scan or scan failure. It's a trade-off.
//
goto Cleanup;
}
-
+
Cleanup:
-
+
FltReleaseContext( streamContext );
-
+
return FLT_POSTOP_FINISHED_PROCESSING;
}
@@ -2694,7 +2693,7 @@ AvPreCleanup (
Routine Description:
Pre-cleanup callback. Make the stream context persistent in the volatile cache.
- If the file is transacted, it will be synced at KTM notification callback
+ If the file is transacted, it will be synced at KTM notification callback
if committed.
Arguments:
@@ -2705,7 +2704,7 @@ Arguments:
opaque handles to this filter, instance, its associated volume and
file object.
- CompletionContext - If this callback routine returns FLT_PREOP_SUCCESS_WITH_CALLBACK or
+ CompletionContext - If this callback routine returns FLT_PREOP_SUCCESS_WITH_CALLBACK or
FLT_PREOP_SYNCHRONIZE, this parameter is an optional context pointer to be passed to
the corresponding post-operation callback routine. Otherwise, it must be NULL.
@@ -2714,7 +2713,7 @@ Return Value:
The return value is the status of the operation.
--*/
-{
+{
NTSTATUS status;
BOOLEAN encrypted = FALSE;
PAV_STREAM_CONTEXT streamContext = NULL;
@@ -2724,15 +2723,15 @@ Return Value:
BOOLEAN updateRevisionNumbers;
LONGLONG VolumeRevision, CacheRevision, FileRevision;
-
+
UNREFERENCED_PARAMETER( CompletionContext );
-
+
PAGED_CODE();
//
// Skip scan on prefetcher handles to avoid deadlocks
//
-
+
status = FltGetStreamHandleContext( FltObjects->Instance,
FltObjects->FileObject,
&streamHandleContext );
@@ -2743,8 +2742,8 @@ Return Value:
//
// Because the Memory Manager can cache the file object
// and use it for other applications performing mapped I/O,
- // whenever a Cleanup operation is seen on a prefetcher
- // file object, that file object should no longer be
+ // whenever a Cleanup operation is seen on a prefetcher
+ // file object, that file object should no longer be
// considered prefetcher-opened.
//
@@ -2756,7 +2755,7 @@ Return Value:
NULL );
FltReleaseContext( streamHandleContext );
-
+
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
@@ -2769,7 +2768,7 @@ Return Value:
IoGetStackLimits( &stackLow, &stackHigh );
- if (((ULONG_PTR)FltObjects->FileObject > stackLow) &&
+ if (((ULONG_PTR)FltObjects->FileObject > stackLow) &&
((ULONG_PTR)FltObjects->FileObject < stackHigh)) {
return FLT_PREOP_SUCCESS_NO_CALLBACK;
@@ -2797,7 +2796,7 @@ Return Value:
FltObjects->FileObject,
&encrypted );
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvPreCleanup: AvGetFileEncrypted FAILED!! \n") );
@@ -2805,7 +2804,7 @@ Return Value:
}
if (encrypted) {
-
+
goto Cleanup;
}
@@ -2819,16 +2818,16 @@ Return Value:
//
// For applications, the typical calling sequence is, close the file handle
- // and commit/rollback the changes. We skip the scan here for
- // transacted writer because we do not know if the change will be
- // rollbacked or not. If it eventually commits, it will be scanned
- // at next create anyway. However, if it rollbacks, the scan here will
+ // and commit/rollback the changes. We skip the scan here for
+ // transacted writer because we do not know if the change will be
+ // rollbacked or not. If it eventually commits, it will be scanned
+ // at next create anyway. However, if it rollbacks, the scan here will
// be redundant.
//
- if ((streamContext->TxContext == NULL) &&
+ if ((streamContext->TxContext == NULL) &&
IS_FILE_MODIFIED( streamContext )) {
-
+
status = AvScan( Data,
FltObjects,
AvUserMode,
@@ -2837,7 +2836,7 @@ Return Value:
streamContext );
if (!NT_SUCCESS( status ) || STATUS_TIMEOUT == status) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[AV] AvPreCleanup: AvScan FAILED!! \n") );
@@ -2870,7 +2869,7 @@ Cleanup:
// We only insert the entry when the file is clean or infected.
//
- if (!IS_FILE_MODIFIED( streamContext ) ||
+ if (!IS_FILE_MODIFIED( streamContext ) ||
IS_FILE_INFECTED( streamContext )) {
if (!NT_SUCCESS ( AvSyncCache( FltObjects->Instance, streamContext ))) {
@@ -2897,7 +2896,7 @@ Routine Description:
The registered routine of type PFLT_TRANSACTION_NOTIFICATION_CALLBACK
in FLT_REGISTRATION structure.
-
+
Arguments:
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
@@ -2906,17 +2905,17 @@ Arguments:
TransactionContext - Pointer to the minifilter driver's transaction context
set at PostCreate.
-
- TransactionNotification - Specifies the type of notifications that the
+
+ TransactionNotification - Specifies the type of notifications that the
filter manager is sending to the minifilter driver.
Return Value:
- STATUS_SUCCESS - Returning this status value indicates that the minifilter
+ STATUS_SUCCESS - Returning this status value indicates that the minifilter
driver is finished with the transaction. This is a success code.
-
- STATUS_PENDING - Returning this status value indicates that the minifilter
- driver is not yet finished with the transaction. This is a success code.
+
+ STATUS_PENDING - Returning this status value indicates that the minifilter
+ driver is not yet finished with the transaction. This is a success code.
--*/
{
@@ -2925,20 +2924,20 @@ Return Value:
PAGED_CODE();
UNREFERENCED_PARAMETER( FltObjects );
-
+
FLT_ASSERTMSG("[AV] AvKtmNotificationCallback: The expected type of notifications registered at FltEnlistInTransaction(...).\n",
FlagOn( TransactionNotification,
(TRANSACTION_NOTIFY_COMMIT_FINALIZE | TRANSACTION_NOTIFY_ROLLBACK) ) );
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[AV] AvKtmNotificationCallback: Entered\n") );
-
+
if (NULL != transactionContext) {
if ( FlagOn( TransactionNotification, TRANSACTION_NOTIFY_COMMIT_FINALIZE ) ) {
-
+
return AvProcessTransactionOutcome( TransactionContext, TransactionOutcomeCommitted );
-
+
} else {
return AvProcessTransactionOutcome( TransactionContext, TransactionOutcomeAborted );
@@ -2959,8 +2958,8 @@ AvScanAbortCallbackAsync (
Routine Description:
This routine is the registered cancel callback function in FLT_REGISTRATION.
- It would be invoked by the file system if it decides to abort the scan.
- As its name suggests, this function is asynchrounous, so the caller is not
+ It would be invoked by the file system if it decides to abort the scan.
+ As its name suggests, this function is asynchrounous, so the caller is not
blocked.
Note: This routine may be called before FltCreateSectionForDataScan returns.
@@ -2971,9 +2970,9 @@ Routine Description:
Arguments:
Instance - Opaque filter pointer for the caller. This parameter is required and cannot be NULL.
-
+
Context - The section context.
-
+
Data - Pointer to the filter callbackData that is passed to us.
Return Value:
@@ -3003,34 +3002,35 @@ Return Value:
sectionCtx->CancelableOnConflictingIo) );
//
- // Send abort signal only when the scanning
+ // Send abort signal only when the scanning
// happens in cancelable context (such as pre-cleanup).
//
if (sectionCtx->CancelableOnConflictingIo) {
//
- // The only reason of scan context being NULL is that
+ // The only reason of scan context being NULL is that
// the section context is about to close anyway.
// Please see AvCloseSectionForDataScan(...)
//
scanCtx = InterlockedExchangePointer( &sectionCtx->ScanContext, NULL );
if (scanCtx == NULL) {
-
+
return STATUS_SUCCESS;
}
-
+
sectionCtx->Aborted = TRUE;
AvSendAbortToUser( scanCtx->ScanThreadId, scanCtx->ScanId );
-
+
}
return STATUS_SUCCESS;
}
-NTSTATUS
-AvSetConfiguration (
+NTSTATUS
+AvSetConfiguration (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -3041,6 +3041,9 @@ Routine Descrition:
Arguments:
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
RegistryPath - The path key passed to the driver during DriverEntry.
Return Value:
@@ -3051,33 +3054,71 @@ Return Value:
--*/
{
NTSTATUS status;
+ OSVERSIONINFOW versionInfo;
OBJECT_ATTRIBUTES attributes;
- HANDLE driverRegKey = NULL;
+ HANDLE settingsKey = NULL;
UNICODE_STRING valueName;
UCHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
PKEY_VALUE_PARTIAL_INFORMATION value = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
ULONG valueLength = sizeof(buffer);
ULONG resultLength;
+ RtlZeroMemory( &versionInfo, sizeof( versionInfo ) );
+
//
- // Open the SimRep registry key.
+ // Determine the OS version being run.
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ versionInfo.dwOSVersionInfoSize = sizeof( versionInfo );
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ status = RtlGetVersion( &versionInfo );
if (!NT_SUCCESS( status )) {
goto Cleanup;
}
+ //
+ // Open corresponding registry root.
+ // NOTE: Build number should match the INF file.
+ //
+
+ if (versionInfo.dwBuildNumber >= 25900) {
+ //
+ // Open the Parameters key for the service.
+ //
+
+ status = IoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &settingsKey );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto Cleanup;
+ }
+
+ } else {
+ //
+ // Open the legacy settings registry key.
+ //
+
+ InitializeObjectAttributes( &attributes,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ status = ZwOpenKey( &settingsKey,
+ KEY_READ,
+ &attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto Cleanup;
+ }
+ }
#if DBG
@@ -3086,8 +3127,8 @@ Return Value:
//
RtlInitUnicodeString( &valueName, L"DebugLevel" );
-
- status = ZwQueryValueKey( driverRegKey,
+
+ status = ZwQueryValueKey( settingsKey,
&valueName,
KeyValuePartialInformation,
value,
@@ -3107,16 +3148,16 @@ Return Value:
RtlInitUnicodeString( &valueName, L"LocalScanTimeout" );
- status = ZwQueryValueKey( driverRegKey,
+ status = ZwQueryValueKey( settingsKey,
&valueName,
KeyValuePartialInformation,
value,
- valueLength,
+ valueLength,
&resultLength );
if (NT_SUCCESS( status )) {
- Globals.LocalScanTimeout = (LONGLONG)(*(PULONG)value->Data);
+ Globals.LocalScanTimeout = (LONGLONG)(*(PULONG)value->Data);
}
//
@@ -3125,25 +3166,25 @@ Return Value:
RtlInitUnicodeString( &valueName, L"NetworkScanTimeout" );
- status = ZwQueryValueKey( driverRegKey,
+ status = ZwQueryValueKey( settingsKey,
&valueName,
KeyValuePartialInformation,
value,
- valueLength,
+ valueLength,
&resultLength );
if (NT_SUCCESS( status )) {
- Globals.NetworkScanTimeout = (LONGLONG)(*(PULONG)value->Data);
+ Globals.NetworkScanTimeout = (LONGLONG)(*(PULONG)value->Data);
}
status = STATUS_SUCCESS;
Cleanup:
- if (driverRegKey != NULL) {
+ if (settingsKey != NULL) {
- ZwClose( driverRegKey );
+ ZwClose( settingsKey );
}
return status;
diff --git a/filesys/miniFilter/avscan/filter/avscan.vcxproj b/filesys/miniFilter/avscan/filter/avscan.vcxproj
index 5552329c..2ce8ce29 100644
--- a/filesys/miniFilter/avscan/filter/avscan.vcxproj
+++ b/filesys/miniFilter/avscan/filter/avscan.vcxproj
@@ -188,6 +188,7 @@
<None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
<None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
<None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ <None Include="..\avscan.inf" />
</ItemGroup>
<ItemGroup>
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
diff --git a/filesys/miniFilter/avscan/filter/avscan.vcxproj.Filters b/filesys/miniFilter/avscan/filter/avscan.vcxproj.Filters
index 6254a245..f7f506ae 100644
--- a/filesys/miniFilter/avscan/filter/avscan.vcxproj.Filters
+++ b/filesys/miniFilter/avscan/filter/avscan.vcxproj.Filters
@@ -43,4 +43,26 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\avscan.inf">
+ <Filter>Driver Files</Filter>
+ </None>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/filesys/miniFilter/cancelSafe/cancelSafe.c b/filesys/miniFilter/cancelSafe/cancelSafe.c
index 4c9e7633..0e18247d 100644
--- a/filesys/miniFilter/cancelSafe/cancelSafe.c
+++ b/filesys/miniFilter/cancelSafe/cancelSafe.c
@@ -187,6 +187,7 @@ InstanceTeardownComplete (
NTSTATUS
SetConfiguration (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -394,7 +395,7 @@ Return Value:
// Modify the configuration based on values in the registry
//
- Status = SetConfiguration( RegistryPath );
+ Status = SetConfiguration( DriverObject, RegistryPath );
if (!NT_SUCCESS( Status )) {
@@ -459,6 +460,7 @@ DriverEntryCleanup:
NTSTATUS
SetConfiguration (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -470,6 +472,9 @@ Routine Description:
Arguments:
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
RegistryPath - The path key passed to the driver during DriverEntry.
Return Value:
@@ -480,6 +485,7 @@ Return Value:
--*/
{
NTSTATUS Status;
+ OSVERSIONINFOW versionInfo;
OBJECT_ATTRIBUTES Attributes;
HANDLE DriverRegKey = NULL;
UNICODE_STRING ValueName;
@@ -490,25 +496,62 @@ Return Value:
ULONG ResultLength;
ULONG Length;
+ RtlZeroMemory( &versionInfo, sizeof( versionInfo ) );
+
//
- // Open the driver registry key.
+ // Determine the OS version being run.
//
- InitializeObjectAttributes( &Attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ versionInfo.dwOSVersionInfoSize = sizeof( versionInfo );
- Status = ZwOpenKey( &DriverRegKey,
- KEY_READ,
- &Attributes );
+ Status = RtlGetVersion( &versionInfo );
if (!NT_SUCCESS( Status )) {
goto SetConfigurationCleanup;
}
+ //
+ // Open corresponding registry root.
+ // NOTE: Build number should match the INF file.
+ //
+
+ if (versionInfo.dwBuildNumber >= 25900) {
+ //
+ // Open the Parameters key for the service.
+ //
+
+ Status = IoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &DriverRegKey );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto SetConfigurationCleanup;
+ }
+ } else {
+ //
+ // Open the legacy driver registry key.
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ Status = ZwOpenKey( &DriverRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto SetConfigurationCleanup;
+ }
+ }
+
CloseHandle = TRUE;
//
@@ -534,7 +577,6 @@ Return Value:
// Query the queue time delay
//
-
RtlInitUnicodeString( &ValueName, CSQ_KEY_NAME_DELAY );
Status = ZwQueryValueKey( DriverRegKey,
diff --git a/filesys/miniFilter/cancelSafe/cancelSafe.inf b/filesys/miniFilter/cancelSafe/cancelSafe.inf
index d526b3dc..688fb3f5 100644
--- a/filesys/miniFilter/cancelSafe/cancelSafe.inf
+++ b/filesys/miniFilter/cancelSafe/cancelSafe.inf
Binary files differ
diff --git a/filesys/miniFilter/cdo/CdoInit.c b/filesys/miniFilter/cdo/CdoInit.c
index fa6e37aa..cef73e32 100644
--- a/filesys/miniFilter/cdo/CdoInit.c
+++ b/filesys/miniFilter/cdo/CdoInit.c
@@ -50,6 +50,7 @@ CdoInstanceSetup (
VOID
CdoInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -90,12 +91,12 @@ DriverEntry(
)
{
NTSTATUS status;
-
-
+
+
//
// This defines what we want to filter with FltMgr
//
-
+
CONST FLT_REGISTRATION filterRegistration = {
sizeof( FLT_REGISTRATION ), // Size
FLT_REGISTRATION_VERSION, // Version
@@ -109,22 +110,22 @@ DriverEntry(
NULL, // InstanceTeardownComplete
NULL,NULL // NameProvider callbacks
};
-
+
RtlZeroMemory( &Globals, sizeof( Globals ) );
#if DBG
-
+
//
// Initialize global debug level
//
- CdoInitializeDebugLevel( RegistryPath );
+ CdoInitializeDebugLevel( DriverObject, RegistryPath );
#else
UNREFERENCED_PARAMETER( RegistryPath );
-
+
#endif
DebugTrace( DEBUG_TRACE_LOAD_UNLOAD,
@@ -132,14 +133,14 @@ DriverEntry(
//
// Initialize the resource
- //
+ //
ExInitializeResourceLite( &Globals.Resource );
//
// Record the driver object
//
-
+
Globals.FilterDriverObject = DriverObject;
//
@@ -167,7 +168,7 @@ DriverEntry(
FltUnregisterFilter( Globals.Filter );
ExDeleteResourceLite( &Globals.Resource );
return status;
- }
+ }
//
// Start filtering i/o
@@ -190,20 +191,24 @@ DriverEntry(
VOID
CdoInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
- This routine tries to read the filter DebugLevel parameter from
+ This routine tries to read the filter DebugLevel parameter from
the registry. This value will be found in the registry location
indicated by the RegistryPath passed in.
Arguments:
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
RegistryPath - The path key passed to the driver during DriverEntry.
-
+
Return Value:
None.
@@ -211,7 +216,8 @@ Return Value:
--*/
{
OBJECT_ATTRIBUTES attributes;
- HANDLE driverRegKey;
+ OSVERSIONINFOW versionInfo;
+ HANDLE driverRegKey = NULL;
NTSTATUS status;
ULONG resultLength;
UNICODE_STRING valueName;
@@ -219,46 +225,84 @@ Return Value:
Globals.DebugLevel = DEBUG_TRACE_ERROR;
+ RtlZeroMemory( &versionInfo, sizeof( versionInfo ) );
+
//
- // Open the desired registry key
+ // Determine the OS version being run.
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ versionInfo.dwOSVersionInfoSize = sizeof( versionInfo );
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ status = RtlGetVersion( &versionInfo );
- if (NT_SUCCESS( status )) {
+ if (!NT_SUCCESS( status )) {
+ goto cleanup;
+ }
+
+ //
+ // Open the desired registry key
+ //
+
+ if (versionInfo.dwBuildNumber >= 25900) {
//
- // Read the DebugFlags value from the registry.
+ // Open the Parameters key for the service.
//
- RtlInitUnicodeString( &valueName, L"DebugLevel" );
-
- status = ZwQueryValueKey( driverRegKey,
- &valueName,
- KeyValuePartialInformation,
- buffer,
- sizeof(buffer),
- &resultLength );
+ status = IoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &driverRegKey );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+ } else {
+ InitializeObjectAttributes( &attributes,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ status = ZwOpenKey( &driverRegKey,
+ KEY_READ,
+ &attributes );
- if (NT_SUCCESS( status )) {
+ if (!NT_SUCCESS( status )) {
- Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
+ goto cleanup;
}
}
//
+ // Read the DebugFlags value from the registry.
+ //
+
+ RtlInitUnicodeString( &valueName, L"DebugLevel" );
+
+ status = ZwQueryValueKey( driverRegKey,
+ &valueName,
+ KeyValuePartialInformation,
+ buffer,
+ sizeof(buffer),
+ &resultLength );
+
+ if (NT_SUCCESS( status )) {
+
+ Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
+ }
+
+cleanup:
+
+ //
// Close the registry entry
//
- ZwClose( driverRegKey );
+ if (driverRegKey != NULL) {
+ ZwClose( driverRegKey );
+ }
}
#endif
@@ -274,7 +318,7 @@ Routine Description:
This is the unload routine for this filter driver. This is called
when the minifilter is about to be unloaded. We can fail this unload
- request if this is not a mandatory unloaded indicated by the Flags
+ request if this is not a mandatory unloaded indicated by the Flags
parameter.
Arguments:
@@ -299,7 +343,7 @@ Return Value:
// If the CDO is still referenced and the unload is not mandatry
// then fail the unload
//
-
+
CdoAcquireResourceShared( &Globals.Resource );
if (FlagOn( Globals.Flags, GLOBAL_DATA_F_CDO_OPEN_REF) &&
@@ -356,7 +400,7 @@ Arguments:
Return Value:
- STATUS_FLT_DO_NOT_ATTACH - do not attach because we do not want to
+ STATUS_FLT_DO_NOT_ATTACH - do not attach because we do not want to
attach to any volume
--*/
diff --git a/filesys/miniFilter/cdo/cdo.inf b/filesys/miniFilter/cdo/cdo.inf
index c51cae2c..51e3f32e 100644
--- a/filesys/miniFilter/cdo/cdo.inf
+++ b/filesys/miniFilter/cdo/cdo.inf
Binary files differ
diff --git a/filesys/miniFilter/change/change.inf b/filesys/miniFilter/change/change.inf
index 86a7b868..96b52bdc 100644
--- a/filesys/miniFilter/change/change.inf
+++ b/filesys/miniFilter/change/change.inf
Binary files differ
diff --git a/filesys/miniFilter/ctx/CtxInit.c b/filesys/miniFilter/ctx/CtxInit.c
index 2654b9f9..fbb2d99c 100644
--- a/filesys/miniFilter/ctx/CtxInit.c
+++ b/filesys/miniFilter/ctx/CtxInit.c
@@ -80,6 +80,7 @@ CtxInstanceTeardownComplete (
VOID
CtxInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -217,7 +218,7 @@ Return Value:
//
// Default to NonPagedPoolNx for non paged pool allocations where supported.
//
-
+
ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
RtlZeroMemory( &Globals, sizeof( Globals ) );
@@ -228,7 +229,7 @@ Return Value:
// Initialize global debug level
//
- CtxInitializeDebugLevel( RegistryPath );
+ CtxInitializeDebugLevel( DriverObject, RegistryPath );
#else
@@ -276,6 +277,7 @@ Return Value:
VOID
CtxInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -288,6 +290,9 @@ Routine Description:
Arguments:
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
RegistryPath - The path key passed to the driver during DriverEntry.
Return Value:
@@ -297,7 +302,8 @@ Return Value:
--*/
{
OBJECT_ATTRIBUTES attributes;
- HANDLE driverRegKey;
+ OSVERSIONINFOW versionInfo;
+ HANDLE driverRegKey = NULL;
NTSTATUS status;
ULONG resultLength;
UNICODE_STRING valueName;
@@ -305,48 +311,88 @@ Return Value:
Globals.DebugLevel = DEBUG_TRACE_ERROR;
+ RtlZeroMemory( &versionInfo, sizeof( versionInfo ) );
+
+ //
+ // Determine the OS version being run.
+ //
+
+ versionInfo.dwOSVersionInfoSize = sizeof( versionInfo );
+
+ status = RtlGetVersion( &versionInfo );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+
//
// Open the desired registry key
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ if (versionInfo.dwBuildNumber >= 25900) {
+ //
+ // Open the Parameters key for the service.
+ //
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ status = IoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &driverRegKey );
- if (NT_SUCCESS( status )) {
+ if (!NT_SUCCESS( status )) {
+ goto cleanup;
+ }
+ } else {
//
- // Read the DebugFlags value from the registry.
+ // Open legacy registry key.
//
- RtlInitUnicodeString( &valueName, L"DebugLevel" );
+ InitializeObjectAttributes( &attributes,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
- status = ZwQueryValueKey( driverRegKey,
- &valueName,
- KeyValuePartialInformation,
- buffer,
- sizeof(buffer),
- &resultLength );
+ status = ZwOpenKey( &driverRegKey,
+ KEY_READ,
+ &attributes );
- if (NT_SUCCESS( status )) {
+ if (!NT_SUCCESS( status )) {
- Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
+ goto cleanup;
}
+ }
- //
- // Close the registry entry
- //
+ //
+ // Read the DebugFlags value from the registry.
+ //
- ZwClose( driverRegKey );
+ RtlInitUnicodeString( &valueName, L"DebugLevel" );
+ status = ZwQueryValueKey( driverRegKey,
+ &valueName,
+ KeyValuePartialInformation,
+ buffer,
+ sizeof(buffer),
+ &resultLength );
+
+ if (NT_SUCCESS( status )) {
+
+ Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
}
+cleanup:
+
+ //
+ // Close the registry entry
+ //
+
+ if (driverRegKey != NULL) {
+ ZwClose( driverRegKey );
+ }
}
#endif
diff --git a/filesys/miniFilter/ctx/ctx.inf b/filesys/miniFilter/ctx/ctx.inf
index 39e935af..1f3a833e 100644
--- a/filesys/miniFilter/ctx/ctx.inf
+++ b/filesys/miniFilter/ctx/ctx.inf
Binary files differ
diff --git a/filesys/miniFilter/delete/delete.inf b/filesys/miniFilter/delete/delete.inf
index b9a572fe..55553269 100644
--- a/filesys/miniFilter/delete/delete.inf
+++ b/filesys/miniFilter/delete/delete.inf
Binary files differ
diff --git a/filesys/miniFilter/minispy/filter/minispy.vcxproj b/filesys/miniFilter/minispy/filter/minispy.vcxproj
index 04cec7fe..ce4cb737 100644
--- a/filesys/miniFilter/minispy/filter/minispy.vcxproj
+++ b/filesys/miniFilter/minispy/filter/minispy.vcxproj
@@ -196,6 +196,7 @@
<ItemGroup>
<Inf Exclude="@(Inf)" Include="*.inf" />
<FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <Inf Include="..\minispy.inf" />
</ItemGroup>
<ItemGroup>
<None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
diff --git a/filesys/miniFilter/minispy/filter/minispy.vcxproj.Filters b/filesys/miniFilter/minispy/filter/minispy.vcxproj.Filters
index e0184750..aaaa7c14 100644
--- a/filesys/miniFilter/minispy/filter/minispy.vcxproj.Filters
+++ b/filesys/miniFilter/minispy/filter/minispy.vcxproj.Filters
@@ -34,4 +34,14 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="..\minispy.inf">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/filesys/miniFilter/minispy/minispy.inf b/filesys/miniFilter/minispy/minispy.inf
index c210097c..ff9fe039 100644
--- a/filesys/miniFilter/minispy/minispy.inf
+++ b/filesys/miniFilter/minispy/minispy.inf
Binary files differ
diff --git a/filesys/miniFilter/nullFilter/nullFilter.inf b/filesys/miniFilter/nullFilter/nullFilter.inf
index 0e710e2d..394d9d8f 100644
--- a/filesys/miniFilter/nullFilter/nullFilter.inf
+++ b/filesys/miniFilter/nullFilter/nullFilter.inf
Binary files differ
diff --git a/filesys/miniFilter/passThrough/passThrough.inf b/filesys/miniFilter/passThrough/passThrough.inf
index 6db4d0d0..2ff9ffee 100644
--- a/filesys/miniFilter/passThrough/passThrough.inf
+++ b/filesys/miniFilter/passThrough/passThrough.inf
Binary files differ
diff --git a/filesys/miniFilter/scanner/filter/scanner.c b/filesys/miniFilter/scanner/filter/scanner.c
index 318941d1..7602b6a1 100644
--- a/filesys/miniFilter/scanner/filter/scanner.c
+++ b/filesys/miniFilter/scanner/filter/scanner.c
@@ -56,6 +56,7 @@ UNICODE_STRING ScannedExtensionDefault = RTL_CONSTANT_STRING( L"doc" );
NTSTATUS
ScannerInitializeScannedExtensions(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -242,7 +243,7 @@ Return Value:
// Obtain the extensions to scan from the registry
//
- status = ScannerInitializeScannedExtensions( RegistryPath );
+ status = ScannerInitializeScannedExtensions( DriverObject, RegistryPath );
if (!NT_SUCCESS( status )) {
@@ -314,6 +315,7 @@ Return Value:
NTSTATUS
ScannerInitializeScannedExtensions(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -325,6 +327,9 @@ Routine Descrition:
Arguments:
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
RegistryPath - The path key passed to the driver during DriverEntry.
Return Value:
@@ -336,6 +341,7 @@ Return Value:
{
NTSTATUS status;
OBJECT_ATTRIBUTES attributes;
+ OSVERSIONINFOW versionInfo;
HANDLE driverRegKey = NULL;
UNICODE_STRING valueName;
PKEY_VALUE_PARTIAL_INFORMATION valueBuffer = NULL;
@@ -351,25 +357,61 @@ Return Value:
ScannedExtensions = NULL;
ScannedExtensionCount = 0;
+ RtlZeroMemory( &versionInfo, sizeof( versionInfo ) );
+
//
- // Open the driver registry key.
+ // Determine the OS version being run.
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ versionInfo.dwOSVersionInfoSize = sizeof( versionInfo );
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ status = RtlGetVersion( &versionInfo );
if (!NT_SUCCESS( status )) {
goto ScannerInitializeScannedExtensionsCleanup;
}
+ //
+ // Open the desired registry key
+ //
+
+ if (versionInfo.dwBuildNumber >= 25900) {
+ //
+ // Open the Parameters key for the service.
+ //
+
+ status = IoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &driverRegKey );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto ScannerInitializeScannedExtensionsCleanup;
+ }
+ } else {
+ //
+ // Open legacy registry key.
+ //
+
+ InitializeObjectAttributes( &attributes,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ status = ZwOpenKey( &driverRegKey,
+ KEY_READ,
+ &attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto ScannerInitializeScannedExtensionsCleanup;
+ }
+ }
+
closeHandle = TRUE;
//
@@ -675,7 +717,7 @@ Return Value
return STATUS_SUCCESS;
}
-
+
VOID
ScannerPortDisconnect(
_In_opt_ PVOID ConnectionCookie
@@ -717,7 +759,7 @@ Return value
ScannerData.UserProcess = NULL;
}
-
+
NTSTATUS
ScannerUnload (
_In_ FLT_FILTER_UNLOAD_FLAGS Flags
diff --git a/filesys/miniFilter/scanner/filter/scanner.vcxproj b/filesys/miniFilter/scanner/filter/scanner.vcxproj
index a3eeebcb..04644758 100644
--- a/filesys/miniFilter/scanner/filter/scanner.vcxproj
+++ b/filesys/miniFilter/scanner/filter/scanner.vcxproj
@@ -190,6 +190,7 @@
<ItemGroup>
<Inf Exclude="@(Inf)" Include="*.inf" />
<FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <Inf Include="..\scanner.inf" />
</ItemGroup>
<ItemGroup>
<None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
diff --git a/filesys/miniFilter/scanner/filter/scanner.vcxproj.Filters b/filesys/miniFilter/scanner/filter/scanner.vcxproj.Filters
index 043528f2..fbf265f0 100644
--- a/filesys/miniFilter/scanner/filter/scanner.vcxproj.Filters
+++ b/filesys/miniFilter/scanner/filter/scanner.vcxproj.Filters
@@ -28,4 +28,14 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="..\scanner.inf">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/filesys/miniFilter/scanner/scanner.inf b/filesys/miniFilter/scanner/scanner.inf
index 762f5eec..94775cfc 100644
--- a/filesys/miniFilter/scanner/scanner.inf
+++ b/filesys/miniFilter/scanner/scanner.inf
Binary files differ
diff --git a/filesys/miniFilter/simrep/simrep.c b/filesys/miniFilter/simrep/simrep.c
index 4d377ecb..26bd1645 100644
--- a/filesys/miniFilter/simrep/simrep.c
+++ b/filesys/miniFilter/simrep/simrep.c
@@ -245,6 +245,7 @@ DriverEntry (
NTSTATUS
SimRepSetConfiguration(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -609,7 +610,7 @@ Return Value:
// Set the filter configuration based on registry keys
//
- status = SimRepSetConfiguration( RegistryPath );
+ status = SimRepSetConfiguration( DriverObject, RegistryPath );
DebugTrace( DEBUG_TRACE_LOAD_UNLOAD,
("[SimRep]: Driver being loaded\n") );
@@ -666,6 +667,7 @@ DriverEntryCleanup:
NTSTATUS
SimRepSetConfiguration(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -676,6 +678,9 @@ Routine Descrition:
Arguments:
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
RegistryPath - The path key passed to the driver during DriverEntry.
Return Value:
@@ -687,6 +692,7 @@ Return Value:
{
NTSTATUS status;
OBJECT_ATTRIBUTES attributes;
+ OSVERSIONINFOW versionInfo;
HANDLE driverRegKey = NULL;
UNICODE_STRING valueName;
UCHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
@@ -700,25 +706,61 @@ Return Value:
PAGED_CODE();
+ RtlZeroMemory( &versionInfo, sizeof( versionInfo ) );
+
//
- // Open the SimRep registry key.
+ // Determine the OS version being run.
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ versionInfo.dwOSVersionInfoSize = sizeof( versionInfo );
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ status = RtlGetVersion( &versionInfo );
if (!NT_SUCCESS( status )) {
goto SimRepSetConfigurationCleanup;
}
+ //
+ // Open the desired registry key
+ //
+
+ if (versionInfo.dwBuildNumber >= 25900) {
+ //
+ // Open the Parameters key for the service.
+ //
+
+ status = IoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &driverRegKey );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto SimRepSetConfigurationCleanup;
+ }
+ } else {
+ //
+ // Open legacy registry key.
+ //
+
+ InitializeObjectAttributes( &attributes,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ status = ZwOpenKey( &driverRegKey,
+ KEY_READ,
+ &attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto SimRepSetConfigurationCleanup;
+ }
+ }
+
#if DBG
diff --git a/filesys/miniFilter/simrep/simrep.inf b/filesys/miniFilter/simrep/simrep.inf
index 93632e33..16d08029 100644
--- a/filesys/miniFilter/simrep/simrep.inf
+++ b/filesys/miniFilter/simrep/simrep.inf
Binary files differ
diff --git a/filesys/miniFilter/swapBuffers/swapBuffers.inf b/filesys/miniFilter/swapBuffers/swapBuffers.inf
index ad88200e..664be4f3 100644
--- a/filesys/miniFilter/swapBuffers/swapBuffers.inf
+++ b/filesys/miniFilter/swapBuffers/swapBuffers.inf
Binary files differ