summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzlockard <[email protected]>2023-10-04 11:09:29 -0700
committerGitHub <[email protected]>2023-10-04 11:09:29 -0700
commit06b33059b7cd04038a8d437cffc3cb1bf3c8a862 (patch)
tree5db9d50ffc7422fca37f55b4e397c29f7f429b29
parentc39cb207eb53bbb6196f398287c32d5d72fb9fa7 (diff)
parent7d62dd8d5b59819f53afe50c851967c9c69facc0 (diff)
Merge pull request #1013 from microsoft/fsfilters_version_updates
Fsfilters isolation updates
-rw-r--r--filesys/miniFilter/MetadataManager/MetadataManagerInit.c255
-rw-r--r--filesys/miniFilter/MetadataManager/fmm.infbin5040 -> 8292 bytes
-rw-r--r--filesys/miniFilter/NameChanger/NameChanger.infbin5770 -> 9004 bytes
-rw-r--r--filesys/miniFilter/NameChanger/nc.c2
-rw-r--r--filesys/miniFilter/NameChanger/nc.h73
-rw-r--r--filesys/miniFilter/NameChanger/ncinit.c183
-rw-r--r--filesys/miniFilter/avscan/avscan.infbin5808 -> 8968 bytes
-rw-r--r--filesys/miniFilter/avscan/filter/avscan.c1094
-rw-r--r--filesys/miniFilter/avscan/filter/avscan.vcxproj4
-rw-r--r--filesys/miniFilter/avscan/filter/avscan.vcxproj.Filters34
-rw-r--r--filesys/miniFilter/cancelSafe/cancelSafe.c197
-rw-r--r--filesys/miniFilter/cancelSafe/cancelSafe.infbin5532 -> 8792 bytes
-rw-r--r--filesys/miniFilter/cdo/CdoInit.c251
-rw-r--r--filesys/miniFilter/cdo/cdo.infbin5078 -> 8270 bytes
-rw-r--r--filesys/miniFilter/change/change.infbin5070 -> 7816 bytes
-rw-r--r--filesys/miniFilter/ctx/CtxInit.c229
-rw-r--r--filesys/miniFilter/ctx/ctx.infbin5004 -> 8252 bytes
-rw-r--r--filesys/miniFilter/delete/delete.infbin5156 -> 8084 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 -> 9920 bytes
-rw-r--r--filesys/miniFilter/nullFilter/nullFilter.infbin5014 -> 7928 bytes
-rw-r--r--filesys/miniFilter/passThrough/passThrough.infbin5220 -> 8116 bytes
-rw-r--r--filesys/miniFilter/scanner/filter/scanner.c194
-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 -> 8340 bytes
-rw-r--r--filesys/miniFilter/simrep/simrep.c186
-rw-r--r--filesys/miniFilter/simrep/simrep.infbin6422 -> 9280 bytes
-rw-r--r--filesys/miniFilter/swapBuffers/swapBuffers.infbin5176 -> 8270 bytes
30 files changed, 2036 insertions, 688 deletions
diff --git a/filesys/miniFilter/MetadataManager/MetadataManagerInit.c b/filesys/miniFilter/MetadataManager/MetadataManagerInit.c
index 222159f7..dbedd3a8 100644
--- a/filesys/miniFilter/MetadataManager/MetadataManagerInit.c
+++ b/filesys/miniFilter/MetadataManager/MetadataManagerInit.c
@@ -86,8 +86,31 @@ FmmInstanceTeardownComplete (
#if DBG
+typedef
+NTSTATUS
+(*PFN_IoOpenDriverRegistryKey) (
+ PDRIVER_OBJECT DriverObject,
+ DRIVER_REGKEY_TYPE RegKeyType,
+ ACCESS_MASK DesiredAccess,
+ ULONG Flags,
+ PHANDLE DriverRegKey
+ );
+
+PFN_IoOpenDriverRegistryKey
+FmmGetIoOpenDriverRegistryKey (
+ VOID
+ );
+
+NTSTATUS
+FmmOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ );
+
VOID
FmmInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -101,6 +124,8 @@ FmmInitializeDebugLevel (
#pragma alloc_text(INIT, DriverEntry)
#if DBG
+#pragma alloc_text(INIT, FmmGetIoOpenDriverRegistryKey)
+#pragma alloc_text(INIT, FmmOpenServiceParametersKey)
#pragma alloc_text(INIT, FmmInitializeDebugLevel)
#endif
@@ -115,11 +140,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 +266,7 @@ Return Value:
//
// Default to NonPagedPoolNx for non paged pool allocations where supported.
//
-
+
ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
@@ -253,7 +278,7 @@ Return Value:
// Initialize global debug level
//
- FmmInitializeDebugLevel( RegistryPath );
+ FmmInitializeDebugLevel( DriverObject, RegistryPath );
#else
@@ -299,8 +324,147 @@ Return Value:
#if DBG
+PFN_IoOpenDriverRegistryKey
+FmmGetIoOpenDriverRegistryKey (
+ VOID
+ )
+{
+ static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL;
+ UNICODE_STRING FunctionName = {0};
+
+ if (pIoOpenDriverRegistryKey == NULL) {
+
+ RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey");
+
+ pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName);
+ }
+
+ return pIoOpenDriverRegistryKey;
+}
+
+NTSTATUS
+FmmOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ )
+/*++
+
+Routine Description:
+
+ This routine opens the service parameters key, using the isolation-compliant
+ APIs when possible.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
+ RegistryPath - The path key passed to the driver during DriverEntry.
+
+ ServiceParametersKey - Returns a handle to the service parameters subkey.
+
+Return Value:
+
+ STATUS_SUCCESS if the function completes successfully. Otherwise a valid
+ NTSTATUS code is returned.
+
+--*/
+{
+ NTSTATUS status;
+ PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey;
+ UNICODE_STRING Subkey;
+ HANDLE ParametersKey = NULL;
+ HANDLE ServiceRegKey = NULL;
+ OBJECT_ATTRIBUTES Attributes;
+
+ //
+ // Open the parameters key to read values from the INF, using the API to
+ // open the key if possible
+ //
+
+ pIoOpenDriverRegistryKey = FmmGetIoOpenDriverRegistryKey();
+
+ if (pIoOpenDriverRegistryKey != NULL) {
+
+ //
+ // Open the parameters key using the API
+ //
+
+ status = pIoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &ParametersKey );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+
+ } else {
+
+ //
+ // Open specified service root key
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ ServiceRegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ status = ZwOpenKey( &ServiceRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+
+ //
+ // Open the parameters key relative to service key path
+ //
+
+ RtlInitUnicodeString( &Subkey, L"Parameters" );
+
+ InitializeObjectAttributes( &Attributes,
+ &Subkey,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ ServiceRegKey,
+ NULL );
+
+ status = ZwOpenKey( &ParametersKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+ }
+
+ //
+ // Return value to caller
+ //
+
+ *ServiceParametersKey = ParametersKey;
+
+cleanup:
+
+ if (ServiceRegKey != NULL) {
+
+ ZwClose( ServiceRegKey );
+ }
+
+ return status;
+
+}
+
VOID
FmmInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -313,6 +477,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:
@@ -321,8 +488,7 @@ Return Value:
--*/
{
- OBJECT_ATTRIBUTES attributes;
- HANDLE driverRegKey;
+ HANDLE driverRegKey = NULL;
NTSTATUS status;
ULONG resultLength;
UNICODE_STRING valueName;
@@ -331,47 +497,46 @@ Return Value:
Globals.DebugLevel = DEBUG_TRACE_ERROR;
//
- // Open the desired registry key
+ // Open service parameters key to query values from.
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ status = FmmOpenServiceParametersKey( DriverObject,
+ RegistryPath,
+ &driverRegKey );
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ if (!NT_SUCCESS( status )) {
- if (NT_SUCCESS( status )) {
+ driverRegKey = NULL;
+ goto cleanup;
+ }
- //
- // Read the DebugFlags value from the registry.
- //
+ //
+ // Read the DebugFlags value from the registry.
+ //
- RtlInitUnicodeString( &valueName, L"DebugLevel" );
+ RtlInitUnicodeString( &valueName, L"DebugLevel" );
- status = ZwQueryValueKey( driverRegKey,
- &valueName,
- KeyValuePartialInformation,
- buffer,
- sizeof(buffer),
- &resultLength );
+ status = ZwQueryValueKey( driverRegKey,
+ &valueName,
+ KeyValuePartialInformation,
+ buffer,
+ sizeof(buffer),
+ &resultLength );
- if (NT_SUCCESS( status )) {
+ if (NT_SUCCESS( status )) {
- Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
- }
-
- //
- // Close the registry entry
- //
-
- ZwClose( driverRegKey );
-
+ Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
}
+cleanup:
+
+ //
+ // Close the registry entry
+ //
+
+ if (driverRegKey != NULL) {
+ ZwClose( driverRegKey );
+ }
}
#endif
@@ -678,22 +843,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..ad231a8c 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..7c0b2364 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..7d125498 100644
--- a/filesys/miniFilter/NameChanger/ncinit.c
+++ b/filesys/miniFilter/NameChanger/ncinit.c
@@ -15,7 +15,31 @@ NcIs8DOT3Compatible (
_In_opt_ PUNICODE_STRING LongName
);
+typedef
+NTSTATUS
+(*PFN_IoOpenDriverRegistryKey) (
+ PDRIVER_OBJECT DriverObject,
+ DRIVER_REGKEY_TYPE RegKeyType,
+ ACCESS_MASK DesiredAccess,
+ ULONG Flags,
+ PHANDLE DriverRegKey
+ );
+
+PFN_IoOpenDriverRegistryKey
+NcGetIoOpenDriverRegistryKey (
+ VOID
+ );
+
+NTSTATUS
+NcOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ );
+
#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT, NcGetIoOpenDriverRegistryKey)
+#pragma alloc_text(INIT, NcOpenServiceParametersKey)
#pragma alloc_text(INIT, NcInitializeMapping)
#pragma alloc_text(INIT, NcLoadRegistryString)
#pragma alloc_text(INIT, NcIs8DOT3Compatible)
@@ -278,8 +302,147 @@ NcIs8DOT3Compatible (
}
+PFN_IoOpenDriverRegistryKey
+NcGetIoOpenDriverRegistryKey (
+ VOID
+ )
+{
+ static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL;
+ UNICODE_STRING FunctionName = {0};
+
+ if (pIoOpenDriverRegistryKey == NULL) {
+
+ RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey");
+
+ pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName);
+ }
+
+ return pIoOpenDriverRegistryKey;
+}
+
+NTSTATUS
+NcOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ )
+/*++
+
+Routine Description:
+
+ This routine opens the service parameters key, using the isolation-compliant
+ APIs when possible.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
+ RegistryPath - The path key passed to the driver during DriverEntry.
+
+ ServiceParametersKey - Returns a handle to the service parameters subkey.
+
+Return Value:
+
+ STATUS_SUCCESS if the function completes successfully. Otherwise a valid
+ NTSTATUS code is returned.
+
+--*/
+{
+ NTSTATUS status;
+ PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey;
+ UNICODE_STRING Subkey;
+ HANDLE ParametersKey = NULL;
+ HANDLE ServiceRegKey = NULL;
+ OBJECT_ATTRIBUTES Attributes;
+
+ //
+ // Open the parameters key to read values from the INF, using the API to
+ // open the key if possible
+ //
+
+ pIoOpenDriverRegistryKey = NcGetIoOpenDriverRegistryKey();
+
+ if (pIoOpenDriverRegistryKey != NULL) {
+
+ //
+ // Open the parameters key using the API
+ //
+
+ status = pIoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &ParametersKey );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+
+ } else {
+
+ //
+ // Open specified service root key
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ ServiceRegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ status = ZwOpenKey( &ServiceRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+
+ //
+ // Open the parameters key relative to service key path
+ //
+
+ RtlInitUnicodeString( &Subkey, L"Parameters" );
+
+ InitializeObjectAttributes( &Attributes,
+ &Subkey,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ ServiceRegKey,
+ NULL );
+
+ status = ZwOpenKey( &ParametersKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+ }
+
+ //
+ // Return value to caller
+ //
+
+ *ServiceParametersKey = ParametersKey;
+
+cleanup:
+
+ if (ServiceRegKey != NULL) {
+
+ ZwClose( ServiceRegKey );
+ }
+
+ return status;
+
+}
+
NTSTATUS
NcInitializeMapping(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -292,6 +455,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,7 +467,6 @@ Return Value:
--*/
{
NTSTATUS Status;
- OBJECT_ATTRIBUTES Attributes;
HANDLE DriverRegKey = NULL;
UNICODE_STRING TempPath = EMPTY_UNICODE_STRING;
USHORT Index;
@@ -311,22 +476,16 @@ Return Value:
RtlZeroMemory( &NcGlobalData, sizeof( NcGlobalData ));
//
- // Open the mapping registry key.
+ // Open service parameters key to query values from.
//
- InitializeObjectAttributes( &Attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
-
- Status = ZwOpenKey( &DriverRegKey,
- KEY_READ,
- &Attributes );
+ Status = NcOpenServiceParametersKey( DriverObject,
+ RegistryPath,
+ &DriverRegKey );
if (!NT_SUCCESS( Status )) {
- FLT_ASSERT( DriverRegKey == NULL );
+ DriverRegKey = NULL;
goto NcInitializeMappingCleanup;
}
diff --git a/filesys/miniFilter/avscan/avscan.inf b/filesys/miniFilter/avscan/avscan.inf
index 26fb6c22..27091ee3 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..3c96fd08 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,32 @@ DriverEntry (
_In_ PUNICODE_STRING RegistryPath
);
-NTSTATUS
-AvSetConfiguration (
+typedef
+NTSTATUS
+(*PFN_IoOpenDriverRegistryKey) (
+ PDRIVER_OBJECT DriverObject,
+ DRIVER_REGKEY_TYPE RegKeyType,
+ ACCESS_MASK DesiredAccess,
+ ULONG Flags,
+ PHANDLE DriverRegKey
+ );
+
+PFN_IoOpenDriverRegistryKey
+AvGetIoOpenDriverRegistryKey (
+ VOID
+ );
+
+NTSTATUS
+AvOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ );
+
+
+NTSTATUS
+AvSetConfiguration (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -112,20 +136,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 +158,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 +178,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 +192,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,24 +207,26 @@ 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.
//
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(INIT, AvGetIoOpenDriverRegistryKey)
+#pragma alloc_text(INIT, AvOpenServiceParametersKey)
#pragma alloc_text(INIT, AvSetConfiguration)
#pragma alloc_text(PAGE, AvUnload)
#pragma alloc_text(PAGE, AvInstanceQueryTeardown)
@@ -225,7 +251,7 @@ AvSendUnloadingToUser (
#pragma alloc_text(PAGE, AvDoCancelScanAndRelease)
#pragma alloc_text(PAGE, AvSendAbortToUser)
#pragma alloc_text(PAGE, AvSendUnloadingToUser)
-#endif
+#endif
//
// operation registration
@@ -251,7 +277,7 @@ CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
0,
AvPreOperationCallback,
NULL },
-
+
{ IRP_MJ_FILE_SYSTEM_CONTROL,
0,
AvPreFsControl,
@@ -330,7 +356,7 @@ Return Value:
NTSTATUS status;
PAV_INSTANCE_CONTEXT instanceContext = NULL;
BOOLEAN isOnCsv = FALSE;
-
+
UNREFERENCED_PARAMETER( Flags );
PAGED_CODE();
@@ -348,13 +374,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 +388,7 @@ Return Value:
return STATUS_FLT_DO_NOT_ATTACH;
}
}
-
+
status = FltAllocateContext( Globals.Filter,
FLT_INSTANCE_CONTEXT,
AV_INSTANCE_CONTEXT_SIZE,
@@ -373,46 +399,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 +461,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 +551,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 +590,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 +699,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 +715,7 @@ Return Value:
Globals.NetworkScanTimeout = 60000;
#if DBG
-
+
Globals.DebugLevel = 0xffffffff; // AVDBG_TRACE_ERROR | AVDBG_TRACE_DEBUG;
#endif
@@ -702,7 +726,7 @@ Return Value:
// Set the filter configuration based on registry keys
//
- status = AvSetConfiguration( RegistryPath );
+ status = AvSetConfiguration( DriverObject, RegistryPath );
if (!NT_SUCCESS( status )) {
@@ -710,7 +734,7 @@ Return Value:
("[AV]: DriverEntry: SetConfiguration FAILED. status = 0x%x\n", status) );
leave;
- }
+ }
//
// Register with FltMgr to tell it our callback routines
@@ -721,19 +745,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 +768,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 +808,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 +831,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 +872,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 +896,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 +908,7 @@ Return Value:
*************************************************************************/
BOOLEAN
-AvOperationsModifyingFile (
+AvOperationsModifyingFile (
_In_ PFLT_CALLBACK_DATA Data
)
/*++
@@ -905,14 +929,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 +946,7 @@ Return Value:
default: break;
}
break;
-
+
case IRP_MJ_SET_INFORMATION:
switch ( iopb->Parameters.SetFileInformation.FileInformationClass ) {
case FileEndOfFileInformation:
@@ -947,11 +971,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 +986,9 @@ Return Value:
HANDLE transactionHandle;
NTSTATUS status;
TRANSACTION_BASIC_INFORMATION txBasicInfo = {0};
-
+
PAGED_CODE();
-
+
status = ObOpenObjectByPointer( Transaction,
OBJ_KERNEL_HANDLE,
NULL,
@@ -972,9 +996,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 +1010,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 +1036,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 +1083,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 +1100,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 +1123,7 @@ Return Value:
PAV_TRANSACTION_CONTEXT oldTxCtx = NULL;
PAGED_CODE();
-
+
//
// Tranversing the stream context list, and
// sync the TxState -> State.
@@ -1107,21 +1131,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 +1158,7 @@ Return Value:
}
SetFlag( TransactionContext->Flags, AV_TXCTX_LISTDRAINED );
AvReleaseResource( TransactionContext->Resource );
-
+
return STATUS_SUCCESS;
}
@@ -1145,20 +1169,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 +1195,7 @@ Return Value:
PAV_INSTANCE_CONTEXT instanceContext = NULL;
AV_GENERIC_TABLE_ENTRY query = {0};
PAV_GENERIC_TABLE_ENTRY entry = NULL;
-
+
PAGED_CODE();
//
@@ -1195,8 +1219,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 +1258,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 +1298,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 +1310,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 +1326,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 +1351,7 @@ Return Value:
Cleanup:
FltReleaseContext( instanceContext );
- return status;
+ return status;
}
BOOLEAN
@@ -1340,13 +1364,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 +1381,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 +1397,7 @@ Return Value:
if (NT_SUCCESS(status)) {
if (!FltIsEcpFromUserMode( Filter, ecpContext )) {
- return TRUE;
+ return TRUE;
}
}
}
@@ -1390,13 +1414,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 +1433,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 +1490,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 +1509,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 +1535,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 +1555,7 @@ Return Value:
//
if (IS_FILE_NEED_SCAN( StreamContext )){
-
+
if (ScanMode == AvUserMode) {
status = FltGetVolumeProperties( FltObjects->Volume,
@@ -1541,21 +1565,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 +1588,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 +1636,7 @@ Routine Description:
Arguments:
ScanContext - The scan context.
-
+
SectionContext - The section context associated with the scan context.
Return Value:
@@ -1623,9 +1647,9 @@ Return Value:
{
NTSTATUS status;
PAV_STREAM_CONTEXT streamContext = NULL;
-
+
PAGED_CODE();
-
+
AvFinalizeSectionContext( SectionContext );
status = FltGetStreamContext( ScanContext->FilterInstance,
@@ -1633,21 +1657,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 +1680,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 +1700,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 +1721,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 +1738,7 @@ Return Value:
}
NTSTATUS
-AvSendUnloadingToUser (
+AvSendUnloadingToUser (
VOID
)
/*++
@@ -1737,19 +1761,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 +1781,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 +1809,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 +1823,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 +1837,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 +1860,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 +1882,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 +1894,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 +1946,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 +1958,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 +1984,7 @@ AvPreCreate (
Routine Description:
This routine is the pre-create completion routine.
-
+
Arguments:
@@ -1970,7 +1994,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 +2009,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 +2044,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 +2073,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 +2084,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 +2093,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 +2117,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 +2138,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 +2205,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 +2331,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 +2356,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 +2364,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 +2382,7 @@ Return Value:
return FLT_POSTOP_FINISHED_PROCESSING;
}
-
+
//
// After creation, skip it if it is directory.
//
@@ -2366,29 +2390,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 +2423,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 +2446,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 +2469,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 +2561,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 +2582,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 +2644,9 @@ Return Value:
//
-
+
if (IS_FILE_NEED_SCAN( streamContext )) {
-
+
status = AvScan( Data,
FltObjects,
AvUserMode,
@@ -2631,7 +2655,7 @@ Return Value:
streamContext );
if (!NT_SUCCESS( status ) ||
(STATUS_TIMEOUT == status)) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[AV] AvPostCreate: AvScan FAILED!! \n") );
@@ -2648,7 +2672,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 +2680,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 +2718,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 +2729,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 +2738,7 @@ Return Value:
The return value is the status of the operation.
--*/
-{
+{
NTSTATUS status;
BOOLEAN encrypted = FALSE;
PAV_STREAM_CONTEXT streamContext = NULL;
@@ -2724,15 +2748,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 +2767,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 +2780,7 @@ Return Value:
NULL );
FltReleaseContext( streamHandleContext );
-
+
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
@@ -2769,7 +2793,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 +2821,7 @@ Return Value:
FltObjects->FileObject,
&encrypted );
if (!NT_SUCCESS( status )) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ERROR,
("[AV] AvPreCleanup: AvGetFileEncrypted FAILED!! \n") );
@@ -2805,7 +2829,7 @@ Return Value:
}
if (encrypted) {
-
+
goto Cleanup;
}
@@ -2819,16 +2843,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 +2861,7 @@ Return Value:
streamContext );
if (!NT_SUCCESS( status ) || STATUS_TIMEOUT == status) {
-
+
AV_DBG_PRINT( AVDBG_TRACE_ROUTINES,
("[AV] AvPreCleanup: AvScan FAILED!! \n") );
@@ -2870,7 +2894,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 +2921,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 +2930,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 +2949,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 +2983,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 +2995,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 +3027,173 @@ 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 (
+PFN_IoOpenDriverRegistryKey
+AvGetIoOpenDriverRegistryKey (
+ VOID
+ )
+{
+ static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL;
+ UNICODE_STRING FunctionName = {0};
+
+ if (pIoOpenDriverRegistryKey == NULL) {
+
+ RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey");
+
+ pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName);
+ }
+
+ return pIoOpenDriverRegistryKey;
+}
+
+NTSTATUS
+AvOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ )
+/*++
+
+Routine Description:
+
+ This routine opens the service parameters key, using the isolation-compliant
+ APIs when possible.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
+ RegistryPath - The path key passed to the driver during DriverEntry.
+
+ ServiceParametersKey - Returns a handle to the service parameters subkey.
+
+Return Value:
+
+ STATUS_SUCCESS if the function completes successfully. Otherwise a valid
+ NTSTATUS code is returned.
+
+--*/
+{
+ NTSTATUS Status;
+ PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey;
+ UNICODE_STRING Subkey;
+ HANDLE ParametersKey = NULL;
+ HANDLE ServiceRegKey = NULL;
+ OBJECT_ATTRIBUTES Attributes;
+
+ //
+ // Open the parameters key to read values from the INF, using the API to
+ // open the key if possible
+ //
+
+ pIoOpenDriverRegistryKey = AvGetIoOpenDriverRegistryKey();
+
+ if (pIoOpenDriverRegistryKey != NULL) {
+
+ //
+ // Open the parameters key using the API
+ //
+
+ Status = pIoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &ParametersKey );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto OpenServiceParametersKeyCleanup;
+ }
+
+ } else {
+
+ //
+ // Open specified service root key
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ ServiceRegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ Status = ZwOpenKey( &ServiceRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto OpenServiceParametersKeyCleanup;
+ }
+
+ //
+ // Open the parameters key relative to service key path
+ //
+
+ RtlInitUnicodeString( &Subkey, L"Parameters" );
+
+ InitializeObjectAttributes( &Attributes,
+ &Subkey,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ ServiceRegKey,
+ NULL );
+
+ Status = ZwOpenKey( &ParametersKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto OpenServiceParametersKeyCleanup;
+ }
+ }
+
+ //
+ // Return value to caller
+ //
+
+ *ServiceParametersKey = ParametersKey;
+
+OpenServiceParametersKeyCleanup:
+
+ if (ServiceRegKey != NULL) {
+
+ ZwClose( ServiceRegKey );
+ }
+
+ return Status;
+
+}
+
+NTSTATUS
+AvSetConfiguration (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -3041,6 +3204,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,8 +3217,7 @@ Return Value:
--*/
{
NTSTATUS status;
- 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;
@@ -3060,25 +3225,18 @@ Return Value:
ULONG resultLength;
//
- // Open the SimRep registry key.
+ // Open service parameters key to query values from
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
-
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ status = AvOpenServiceParametersKey( DriverObject,
+ RegistryPath,
+ &settingsKey );
if (!NT_SUCCESS( status )) {
goto Cleanup;
}
-
#if DBG
//
@@ -3086,8 +3244,8 @@ Return Value:
//
RtlInitUnicodeString( &valueName, L"DebugLevel" );
-
- status = ZwQueryValueKey( driverRegKey,
+
+ status = ZwQueryValueKey( settingsKey,
&valueName,
KeyValuePartialInformation,
value,
@@ -3107,16 +3265,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 +3283,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..fa6122b5 100644
--- a/filesys/miniFilter/avscan/filter/avscan.vcxproj
+++ b/filesys/miniFilter/avscan/filter/avscan.vcxproj
@@ -188,6 +188,10 @@
<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" />
+ <Inf Include="..\avscan.inf">
+ <DeploymentContent>true</DeploymentContent>
+ <FileType>Document</FileType>
+ </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..399cecc7 100644
--- a/filesys/miniFilter/avscan/filter/avscan.vcxproj.Filters
+++ b/filesys/miniFilter/avscan/filter/avscan.vcxproj.Filters
@@ -43,4 +43,38 @@
<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>
+ <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>
+ <Inf Include="..\avscan.inf">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/filesys/miniFilter/cancelSafe/cancelSafe.c b/filesys/miniFilter/cancelSafe/cancelSafe.c
index 4c9e7633..9942a3d3 100644
--- a/filesys/miniFilter/cancelSafe/cancelSafe.c
+++ b/filesys/miniFilter/cancelSafe/cancelSafe.c
@@ -185,8 +185,31 @@ InstanceTeardownComplete (
_In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags
);
+typedef
+NTSTATUS
+(*PFN_IoOpenDriverRegistryKey) (
+ PDRIVER_OBJECT DriverObject,
+ DRIVER_REGKEY_TYPE RegKeyType,
+ ACCESS_MASK DesiredAccess,
+ ULONG Flags,
+ PHANDLE DriverRegKey
+ );
+
+PFN_IoOpenDriverRegistryKey
+GetIoOpenDriverRegistryKey (
+ VOID
+ );
+
+NTSTATUS
+OpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ );
+
NTSTATUS
SetConfiguration (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -269,6 +292,8 @@ PreReadEmptyQueueAndComplete(
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(INIT, GetIoOpenDriverRegistryKey)
+#pragma alloc_text(INIT, OpenServiceParametersKey)
#pragma alloc_text(INIT, SetConfiguration)
#pragma alloc_text(PAGE, Unload)
#pragma alloc_text(PAGE, FreeGlobals)
@@ -394,7 +419,7 @@ Return Value:
// Modify the configuration based on values in the registry
//
- Status = SetConfiguration( RegistryPath );
+ Status = SetConfiguration( DriverObject, RegistryPath );
if (!NT_SUCCESS( Status )) {
@@ -456,9 +481,147 @@ DriverEntryCleanup:
return Status;
}
+PFN_IoOpenDriverRegistryKey
+GetIoOpenDriverRegistryKey (
+ VOID
+ )
+{
+ static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL;
+ UNICODE_STRING FunctionName = {0};
+
+ if (pIoOpenDriverRegistryKey == NULL) {
+
+ RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey");
+
+ pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName);
+ }
+
+ return pIoOpenDriverRegistryKey;
+}
+
+NTSTATUS
+OpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ )
+/*++
+
+Routine Description:
+
+ This routine opens the service parameters key, using the isolation-compliant
+ APIs when possible.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
+ RegistryPath - The path key passed to the driver during DriverEntry.
+
+ ServiceParametersKey - Returns a handle to the service parameters subkey.
+
+Return Value:
+
+ STATUS_SUCCESS if the function completes successfully. Otherwise a valid
+ NTSTATUS code is returned.
+
+--*/
+{
+ NTSTATUS Status;
+ PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey;
+ UNICODE_STRING Subkey;
+ HANDLE ParametersKey = NULL;
+ HANDLE ServiceRegKey = NULL;
+ OBJECT_ATTRIBUTES Attributes;
+
+ //
+ // Open the parameters key to read values from the INF, using the API to
+ // open the key if possible.
+ //
+
+ pIoOpenDriverRegistryKey = GetIoOpenDriverRegistryKey();
+
+ if (pIoOpenDriverRegistryKey != NULL) {
+
+ //
+ // Open the parameters key using the API.
+ //
+
+ Status = pIoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &ParametersKey );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto OpenServiceParametersKeyCleanup;
+ }
+
+ } else {
+
+ //
+ // Open specified service root key.
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ ServiceRegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ Status = ZwOpenKey( &ServiceRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto OpenServiceParametersKeyCleanup;
+ }
+
+ //
+ // Open the parameters key relative to service key path.
+ //
+
+ RtlInitUnicodeString( &Subkey, L"Parameters" );
+
+ InitializeObjectAttributes( &Attributes,
+ &Subkey,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ ServiceRegKey,
+ NULL );
+
+ Status = ZwOpenKey( &ParametersKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto OpenServiceParametersKeyCleanup;
+ }
+ }
+
+ //
+ // Return value to caller.
+ //
+
+ *ServiceParametersKey = ParametersKey;
+
+OpenServiceParametersKeyCleanup:
+
+ if (ServiceRegKey != NULL) {
+
+ ZwClose( ServiceRegKey );
+ }
+
+ return Status;
+
+}
NTSTATUS
SetConfiguration (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -470,6 +633,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,10 +646,8 @@ Return Value:
--*/
{
NTSTATUS Status;
- OBJECT_ATTRIBUTES Attributes;
HANDLE DriverRegKey = NULL;
UNICODE_STRING ValueName;
- BOOLEAN CloseHandle = FALSE;
UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + CSQ_MAX_PATH_LENGTH * sizeof(WCHAR)];
PKEY_VALUE_PARTIAL_INFORMATION Value = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
ULONG ValueLength = sizeof(Buffer);
@@ -491,28 +655,21 @@ Return Value:
ULONG Length;
//
- // Open the driver registry key.
+ // Open service parameters key to query values from.
//
- InitializeObjectAttributes( &Attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
-
- Status = ZwOpenKey( &DriverRegKey,
- KEY_READ,
- &Attributes );
+ Status = OpenServiceParametersKey( DriverObject,
+ RegistryPath,
+ &DriverRegKey );
if (!NT_SUCCESS( Status )) {
+ DriverRegKey = NULL;
goto SetConfigurationCleanup;
}
- CloseHandle = TRUE;
-
//
- // Query the debug level
+ // Query the debug level.
//
RtlInitUnicodeString( &ValueName, CSQ_KEY_NAME_DEBUG_LEVEL );
@@ -529,12 +686,10 @@ Return Value:
Globals.DebugLevel = *(PULONG)(Value->Data);
}
-
//
- // Query the queue time delay
+ // Query the queue time delay.
//
-
RtlInitUnicodeString( &ValueName, CSQ_KEY_NAME_DELAY );
Status = ZwQueryValueKey( DriverRegKey,
@@ -557,7 +712,7 @@ Return Value:
}
//
- // Query the mapping path
+ // Query the mapping path.
//
RtlInitUnicodeString( &ValueName, CSQ_KEY_NAME_PATH );
@@ -632,7 +787,7 @@ Return Value:
SetConfigurationCleanup:
- if (CloseHandle) {
+ if (DriverRegKey != NULL) {
ZwClose( DriverRegKey );
}
diff --git a/filesys/miniFilter/cancelSafe/cancelSafe.inf b/filesys/miniFilter/cancelSafe/cancelSafe.inf
index d526b3dc..69d0ccf1 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..f913f6fb 100644
--- a/filesys/miniFilter/cdo/CdoInit.c
+++ b/filesys/miniFilter/cdo/CdoInit.c
@@ -48,8 +48,31 @@ CdoInstanceSetup (
#if DBG
+typedef
+NTSTATUS
+(*PFN_IoOpenDriverRegistryKey) (
+ PDRIVER_OBJECT DriverObject,
+ DRIVER_REGKEY_TYPE RegKeyType,
+ ACCESS_MASK DesiredAccess,
+ ULONG Flags,
+ PHANDLE DriverRegKey
+ );
+
+PFN_IoOpenDriverRegistryKey
+CdoGetIoOpenDriverRegistryKey (
+ VOID
+ );
+
+NTSTATUS
+CdoOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ );
+
VOID
CdoInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -75,6 +98,8 @@ CDO_GLOBAL_DATA Globals;
#pragma alloc_text(INIT, DriverEntry)
#if DBG
+#pragma alloc_text(INIT, CdoGetIoOpenDriverRegistryKey)
+#pragma alloc_text(INIT, CdoOpenServiceParametersKey)
#pragma alloc_text(INIT, CdoInitializeDebugLevel)
#endif
@@ -90,12 +115,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 +134,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 +157,14 @@ DriverEntry(
//
// Initialize the resource
- //
+ //
ExInitializeResourceLite( &Globals.Resource );
//
// Record the driver object
//
-
+
Globals.FilterDriverObject = DriverObject;
//
@@ -167,7 +192,7 @@ DriverEntry(
FltUnregisterFilter( Globals.Filter );
ExDeleteResourceLite( &Globals.Resource );
return status;
- }
+ }
//
// Start filtering i/o
@@ -188,30 +213,171 @@ DriverEntry(
#if DBG
+PFN_IoOpenDriverRegistryKey
+CdoGetIoOpenDriverRegistryKey (
+ VOID
+ )
+{
+ static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL;
+ UNICODE_STRING FunctionName = {0};
+
+ if (pIoOpenDriverRegistryKey == NULL) {
+
+ RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey");
+
+ pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName);
+ }
+
+ return pIoOpenDriverRegistryKey;
+}
+
+NTSTATUS
+CdoOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ )
+/*++
+
+Routine Description:
+
+ This routine opens the service parameters key, using the isolation-compliant
+ APIs when possible.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
+ RegistryPath - The path key passed to the driver during DriverEntry.
+
+ ServiceParametersKey - Returns a handle to the service parameters subkey.
+
+Return Value:
+
+ STATUS_SUCCESS if the function completes successfully. Otherwise a valid
+ NTSTATUS code is returned.
+
+--*/
+{
+ NTSTATUS Status;
+ PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey;
+ UNICODE_STRING Subkey;
+ HANDLE ParametersKey = NULL;
+ HANDLE ServiceRegKey = NULL;
+ OBJECT_ATTRIBUTES Attributes;
+
+ //
+ // Open the parameters key to read values from the INF, using the API to
+ // open the key if possible.
+ //
+
+ pIoOpenDriverRegistryKey = CdoGetIoOpenDriverRegistryKey();
+
+ if (pIoOpenDriverRegistryKey != NULL) {
+
+ //
+ // Open the parameters key using the API.
+ //
+
+ Status = pIoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &ParametersKey );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto cleanup;
+ }
+
+ } else {
+
+ //
+ // Open specified service root key.
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ ServiceRegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ Status = ZwOpenKey( &ServiceRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto cleanup;
+ }
+
+ //
+ // Open the parameters key relative to service key path.
+ //
+
+ RtlInitUnicodeString( &Subkey, L"Parameters" );
+
+ InitializeObjectAttributes( &Attributes,
+ &Subkey,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ ServiceRegKey,
+ NULL );
+
+ Status = ZwOpenKey( &ParametersKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( Status )) {
+
+ goto cleanup;
+ }
+ }
+
+ //
+ // Return value to caller.
+ //
+
+ *ServiceParametersKey = ParametersKey;
+
+cleanup:
+
+ if (ServiceRegKey != NULL) {
+
+ ZwClose( ServiceRegKey );
+ }
+
+ return Status;
+
+}
+
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.
--*/
{
- OBJECT_ATTRIBUTES attributes;
- HANDLE driverRegKey;
+ HANDLE driverRegKey = NULL;
NTSTATUS status;
ULONG resultLength;
UNICODE_STRING valueName;
@@ -220,45 +386,46 @@ Return Value:
Globals.DebugLevel = DEBUG_TRACE_ERROR;
//
- // Open the desired registry key
+ // Open service parameters key to query values from.
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ status = CdoOpenServiceParametersKey( DriverObject,
+ RegistryPath,
+ &driverRegKey );
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ if (!NT_SUCCESS( status )) {
- if (NT_SUCCESS( status )) {
+ driverRegKey = NULL;
+ goto cleanup;
+ }
- //
- // Read the DebugFlags value from the registry.
- //
+ //
+ // Read the DebugFlags value from the registry.
+ //
- RtlInitUnicodeString( &valueName, L"DebugLevel" );
-
- status = ZwQueryValueKey( driverRegKey,
- &valueName,
- KeyValuePartialInformation,
- buffer,
- sizeof(buffer),
- &resultLength );
+ RtlInitUnicodeString( &valueName, L"DebugLevel" );
- if (NT_SUCCESS( status )) {
+ status = ZwQueryValueKey( driverRegKey,
+ &valueName,
+ KeyValuePartialInformation,
+ buffer,
+ sizeof(buffer),
+ &resultLength );
- Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
- }
+ 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 +441,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 +466,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 +523,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..cdac24d9 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..e7da4250 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..e1e2576a 100644
--- a/filesys/miniFilter/ctx/CtxInit.c
+++ b/filesys/miniFilter/ctx/CtxInit.c
@@ -78,8 +78,31 @@ CtxInstanceTeardownComplete (
#if DBG
+typedef
+NTSTATUS
+(*PFN_IoOpenDriverRegistryKey) (
+ PDRIVER_OBJECT DriverObject,
+ DRIVER_REGKEY_TYPE RegKeyType,
+ ACCESS_MASK DesiredAccess,
+ ULONG Flags,
+ PHANDLE DriverRegKey
+ );
+
+PFN_IoOpenDriverRegistryKey
+CtxGetIoOpenDriverRegistryKey (
+ VOID
+ );
+
+NTSTATUS
+CtxOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ );
+
VOID
CtxInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -93,6 +116,8 @@ CtxInitializeDebugLevel (
#pragma alloc_text(INIT, DriverEntry)
#if DBG
+#pragma alloc_text(INIT, CtxGetIoOpenDriverRegistryKey)
+#pragma alloc_text(INIT, CtxOpenServiceParametersKey)
#pragma alloc_text(INIT, CtxInitializeDebugLevel)
#endif
@@ -217,7 +242,7 @@ Return Value:
//
// Default to NonPagedPoolNx for non paged pool allocations where supported.
//
-
+
ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
RtlZeroMemory( &Globals, sizeof( Globals ) );
@@ -228,7 +253,7 @@ Return Value:
// Initialize global debug level
//
- CtxInitializeDebugLevel( RegistryPath );
+ CtxInitializeDebugLevel( DriverObject, RegistryPath );
#else
@@ -274,8 +299,147 @@ Return Value:
#if DBG
+PFN_IoOpenDriverRegistryKey
+CtxGetIoOpenDriverRegistryKey (
+ VOID
+ )
+{
+ static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL;
+ UNICODE_STRING FunctionName = {0};
+
+ if (pIoOpenDriverRegistryKey == NULL) {
+
+ RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey");
+
+ pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName);
+ }
+
+ return pIoOpenDriverRegistryKey;
+}
+
+NTSTATUS
+CtxOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ )
+/*++
+
+Routine Description:
+
+ This routine opens the service parameters key, using the isolation-compliant
+ APIs when possible.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
+ RegistryPath - The path key passed to the driver during DriverEntry.
+
+ ServiceParametersKey - Returns a handle to the service parameters subkey.
+
+Return Value:
+
+ STATUS_SUCCESS if the function completes successfully. Otherwise a valid
+ NTSTATUS code is returned.
+
+--*/
+{
+ NTSTATUS status;
+ PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey;
+ UNICODE_STRING Subkey;
+ HANDLE ParametersKey = NULL;
+ HANDLE ServiceRegKey = NULL;
+ OBJECT_ATTRIBUTES Attributes;
+
+ //
+ // Open the parameters key to read values from the INF, using the API to
+ // open the key if possible
+ //
+
+ pIoOpenDriverRegistryKey = CtxGetIoOpenDriverRegistryKey();
+
+ if (pIoOpenDriverRegistryKey != NULL) {
+
+ //
+ // Open the parameters key using the API
+ //
+
+ status = pIoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &ParametersKey );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+
+ } else {
+
+ //
+ // Open specified service root key
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ ServiceRegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ status = ZwOpenKey( &ServiceRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+
+ //
+ // Open the parameters key relative to service key path
+ //
+
+ RtlInitUnicodeString( &Subkey, L"Parameters" );
+
+ InitializeObjectAttributes( &Attributes,
+ &Subkey,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ ServiceRegKey,
+ NULL );
+
+ status = ZwOpenKey( &ParametersKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto cleanup;
+ }
+ }
+
+ //
+ // Return value to caller
+ //
+
+ *ServiceParametersKey = ParametersKey;
+
+cleanup:
+
+ if (ServiceRegKey != NULL) {
+
+ ZwClose( ServiceRegKey );
+ }
+
+ return status;
+
+}
+
VOID
CtxInitializeDebugLevel (
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -288,6 +452,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:
@@ -296,8 +463,7 @@ Return Value:
--*/
{
- OBJECT_ATTRIBUTES attributes;
- HANDLE driverRegKey;
+ HANDLE driverRegKey = NULL;
NTSTATUS status;
ULONG resultLength;
UNICODE_STRING valueName;
@@ -306,47 +472,46 @@ Return Value:
Globals.DebugLevel = DEBUG_TRACE_ERROR;
//
- // Open the desired registry key
+ // Open service parameters key to query values from.
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
+ status = CtxOpenServiceParametersKey( DriverObject,
+ RegistryPath,
+ &driverRegKey );
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ if (!NT_SUCCESS( status )) {
- if (NT_SUCCESS( status )) {
+ driverRegKey = NULL;
+ goto cleanup;
+ }
- //
- // Read the DebugFlags value from the registry.
- //
+ //
+ // Read the DebugFlags value from the registry.
+ //
- RtlInitUnicodeString( &valueName, L"DebugLevel" );
+ RtlInitUnicodeString( &valueName, L"DebugLevel" );
- status = ZwQueryValueKey( driverRegKey,
- &valueName,
- KeyValuePartialInformation,
- buffer,
- sizeof(buffer),
- &resultLength );
+ status = ZwQueryValueKey( driverRegKey,
+ &valueName,
+ KeyValuePartialInformation,
+ buffer,
+ sizeof(buffer),
+ &resultLength );
- if (NT_SUCCESS( status )) {
+ if (NT_SUCCESS( status )) {
- Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
- }
+ Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data));
+ }
- //
- // Close the registry entry
- //
+cleanup:
- ZwClose( driverRegKey );
+ //
+ // 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..8edaf764 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..da348874 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..60eb8684 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..c04e9f06 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..129a2ab6 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..ec911f63 100644
--- a/filesys/miniFilter/scanner/filter/scanner.c
+++ b/filesys/miniFilter/scanner/filter/scanner.c
@@ -54,8 +54,31 @@ UNICODE_STRING ScannedExtensionDefault = RTL_CONSTANT_STRING( L"doc" );
// Function prototypes
//
+typedef
+NTSTATUS
+(*PFN_IoOpenDriverRegistryKey) (
+ PDRIVER_OBJECT DriverObject,
+ DRIVER_REGKEY_TYPE RegKeyType,
+ ACCESS_MASK DesiredAccess,
+ ULONG Flags,
+ PHANDLE DriverRegKey
+ );
+
+PFN_IoOpenDriverRegistryKey
+ScannerGetIoOpenDriverRegistryKey (
+ VOID
+ );
+
+NTSTATUS
+ScannerOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ );
+
NTSTATUS
ScannerInitializeScannedExtensions(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -105,6 +128,8 @@ ScannerpCheckExtension (
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
+ #pragma alloc_text(INIT, ScannerGetIoOpenDriverRegistryKey)
+ #pragma alloc_text(INIT, ScannerOpenServiceParametersKey)
#pragma alloc_text(INIT, ScannerInitializeScannedExtensions)
#pragma alloc_text(PAGE, ScannerInstanceSetup)
#pragma alloc_text(PAGE, ScannerPreCreate)
@@ -242,7 +267,7 @@ Return Value:
// Obtain the extensions to scan from the registry
//
- status = ScannerInitializeScannedExtensions( RegistryPath );
+ status = ScannerInitializeScannedExtensions( DriverObject, RegistryPath );
if (!NT_SUCCESS( status )) {
@@ -312,8 +337,147 @@ Return Value:
}
+PFN_IoOpenDriverRegistryKey
+ScannerGetIoOpenDriverRegistryKey (
+ VOID
+ )
+{
+ static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL;
+ UNICODE_STRING FunctionName = {0};
+
+ if (pIoOpenDriverRegistryKey == NULL) {
+
+ RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey");
+
+ pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName);
+ }
+
+ return pIoOpenDriverRegistryKey;
+}
+
+NTSTATUS
+ScannerOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ )
+/*++
+
+Routine Description:
+
+ This routine opens the service parameters key, using the isolation-compliant
+ APIs when possible.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
+ RegistryPath - The path key passed to the driver during DriverEntry.
+
+ ServiceParametersKey - Returns a handle to the service parameters subkey.
+
+Return Value:
+
+ STATUS_SUCCESS if the function completes successfully. Otherwise a valid
+ NTSTATUS code is returned.
+
+--*/
+{
+ NTSTATUS status;
+ PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey;
+ UNICODE_STRING Subkey;
+ HANDLE ParametersKey = NULL;
+ HANDLE ServiceRegKey = NULL;
+ OBJECT_ATTRIBUTES Attributes;
+
+ //
+ // Open the parameters key to read values from the INF, using the API to
+ // open the key if possible
+ //
+
+ pIoOpenDriverRegistryKey = ScannerGetIoOpenDriverRegistryKey();
+
+ if (pIoOpenDriverRegistryKey != NULL) {
+
+ //
+ // Open the parameters key using the API
+ //
+
+ status = pIoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &ParametersKey );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto ScannerOpenServiceParametersKeyCleanup;
+ }
+
+ } else {
+
+ //
+ // Open specified service root key
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ ServiceRegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ status = ZwOpenKey( &ServiceRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto ScannerOpenServiceParametersKeyCleanup;
+ }
+
+ //
+ // Open the parameters key relative to service key path
+ //
+
+ RtlInitUnicodeString( &Subkey, L"Parameters" );
+
+ InitializeObjectAttributes( &Attributes,
+ &Subkey,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ ServiceRegKey,
+ NULL );
+
+ status = ZwOpenKey( &ParametersKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto ScannerOpenServiceParametersKeyCleanup;
+ }
+ }
+
+ //
+ // Return value to caller
+ //
+
+ *ServiceParametersKey = ParametersKey;
+
+ScannerOpenServiceParametersKeyCleanup:
+
+ if (ServiceRegKey != NULL) {
+
+ ZwClose( ServiceRegKey );
+ }
+
+ return status;
+
+}
+
NTSTATUS
ScannerInitializeScannedExtensions(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -325,6 +489,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:
@@ -335,12 +502,10 @@ Return Value:
--*/
{
NTSTATUS status;
- OBJECT_ATTRIBUTES attributes;
HANDLE driverRegKey = NULL;
UNICODE_STRING valueName;
PKEY_VALUE_PARTIAL_INFORMATION valueBuffer = NULL;
ULONG valueLength = 0;
- BOOLEAN closeHandle = FALSE;
PWCHAR ch;
SIZE_T length;
ULONG count;
@@ -352,26 +517,19 @@ Return Value:
ScannedExtensionCount = 0;
//
- // Open the driver registry key.
+ // Open service parameters key to query values from.
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
-
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ status = ScannerOpenServiceParametersKey( DriverObject,
+ RegistryPath,
+ &driverRegKey );
if (!NT_SUCCESS( status )) {
+ driverRegKey = NULL;
goto ScannerInitializeScannedExtensionsCleanup;
}
- closeHandle = TRUE;
-
//
// Query the length of the reg value
//
@@ -480,7 +638,7 @@ ScannerInitializeScannedExtensionsCleanup:
valueBuffer = NULL;
}
- if (closeHandle) {
+ if (driverRegKey != NULL) {
ZwClose( driverRegKey );
}
@@ -675,7 +833,7 @@ Return Value
return STATUS_SUCCESS;
}
-
+
VOID
ScannerPortDisconnect(
_In_opt_ PVOID ConnectionCookie
@@ -717,7 +875,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..d7bf6256 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..f23dddd6 100644
--- a/filesys/miniFilter/simrep/simrep.c
+++ b/filesys/miniFilter/simrep/simrep.c
@@ -243,8 +243,31 @@ DriverEntry (
_In_ PUNICODE_STRING RegistryPath
);
+typedef
+NTSTATUS
+(*PFN_IoOpenDriverRegistryKey) (
+ PDRIVER_OBJECT DriverObject,
+ DRIVER_REGKEY_TYPE RegKeyType,
+ ACCESS_MASK DesiredAccess,
+ ULONG Flags,
+ PHANDLE DriverRegKey
+ );
+
+PFN_IoOpenDriverRegistryKey
+SimRepGetIoOpenDriverRegistryKey (
+ VOID
+ );
+
+NTSTATUS
+SimRepOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ );
+
NTSTATUS
SimRepSetConfiguration(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
@@ -506,6 +529,8 @@ SIMREP_GLOBAL_DATA Globals;
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(INIT, SimRepGetIoOpenDriverRegistryKey)
+#pragma alloc_text(INIT, SimRepOpenServiceParametersKey)
#pragma alloc_text(INIT, SimRepSetConfiguration)
#pragma alloc_text(PAGE, SimRepUnload)
#pragma alloc_text(PAGE, SimRepInstanceSetup)
@@ -609,7 +634,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") );
@@ -664,8 +689,147 @@ DriverEntryCleanup:
}
#pragma warning(pop)
+PFN_IoOpenDriverRegistryKey
+SimRepGetIoOpenDriverRegistryKey (
+ VOID
+ )
+{
+ static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL;
+ UNICODE_STRING FunctionName = {0};
+
+ if (pIoOpenDriverRegistryKey == NULL) {
+
+ RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey");
+
+ pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName);
+ }
+
+ return pIoOpenDriverRegistryKey;
+}
+
+NTSTATUS
+SimRepOpenServiceParametersKey (
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING ServiceRegistryPath,
+ _Out_ PHANDLE ServiceParametersKey
+ )
+/*++
+
+Routine Description:
+
+ This routine opens the service parameters key, using the isolation-compliant
+ APIs when possible.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system to
+ represent this driver.
+
+ RegistryPath - The path key passed to the driver during DriverEntry.
+
+ ServiceParametersKey - Returns a handle to the service parameters subkey.
+
+Return Value:
+
+ STATUS_SUCCESS if the function completes successfully. Otherwise a valid
+ NTSTATUS code is returned.
+
+--*/
+{
+ NTSTATUS status;
+ PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey;
+ UNICODE_STRING Subkey;
+ HANDLE ParametersKey = NULL;
+ HANDLE ServiceRegKey = NULL;
+ OBJECT_ATTRIBUTES Attributes;
+
+ //
+ // Open the parameters key to read values from the INF, using the API to
+ // open the key if possible
+ //
+
+ pIoOpenDriverRegistryKey = SimRepGetIoOpenDriverRegistryKey();
+
+ if (pIoOpenDriverRegistryKey != NULL) {
+
+ //
+ // Open the parameters key using the API
+ //
+
+ status = pIoOpenDriverRegistryKey( DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &ParametersKey );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto SimRepOpenServiceParametersKeyCleanup;
+ }
+
+ } else {
+
+ //
+ // Open specified service root key
+ //
+
+ InitializeObjectAttributes( &Attributes,
+ ServiceRegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL );
+
+ status = ZwOpenKey( &ServiceRegKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto SimRepOpenServiceParametersKeyCleanup;
+ }
+
+ //
+ // Open the parameters key relative to service key path
+ //
+
+ RtlInitUnicodeString( &Subkey, L"Parameters" );
+
+ InitializeObjectAttributes( &Attributes,
+ &Subkey,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ ServiceRegKey,
+ NULL );
+
+ status = ZwOpenKey( &ParametersKey,
+ KEY_READ,
+ &Attributes );
+
+ if (!NT_SUCCESS( status )) {
+
+ goto SimRepOpenServiceParametersKeyCleanup;
+ }
+ }
+
+ //
+ // Return value to caller
+ //
+
+ *ServiceParametersKey = ParametersKey;
+
+SimRepOpenServiceParametersKeyCleanup:
+
+ if (ServiceRegKey != NULL) {
+
+ ZwClose( ServiceRegKey );
+ }
+
+ return status;
+
+}
+
NTSTATUS
SimRepSetConfiguration(
+ _In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
@@ -676,6 +840,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:
@@ -686,7 +853,6 @@ Return Value:
--*/
{
NTSTATUS status;
- OBJECT_ATTRIBUTES attributes;
HANDLE driverRegKey = NULL;
UNICODE_STRING valueName;
UCHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
@@ -701,25 +867,19 @@ Return Value:
PAGED_CODE();
//
- // Open the SimRep registry key.
+ // Open service parameters key to query values from
//
- InitializeObjectAttributes( &attributes,
- RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
-
- status = ZwOpenKey( &driverRegKey,
- KEY_READ,
- &attributes );
+ status = SimRepOpenServiceParametersKey( DriverObject,
+ RegistryPath,
+ &driverRegKey );
if (!NT_SUCCESS( status )) {
+ driverRegKey = NULL;
goto SimRepSetConfigurationCleanup;
}
-
#if DBG
//
diff --git a/filesys/miniFilter/simrep/simrep.inf b/filesys/miniFilter/simrep/simrep.inf
index 93632e33..8eea42ce 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..0aab9452 100644
--- a/filesys/miniFilter/swapBuffers/swapBuffers.inf
+++ b/filesys/miniFilter/swapBuffers/swapBuffers.inf
Binary files differ