├── .gitattributes ├── .gitignore ├── engine.sln └── engine ├── CallbackRoutines.h ├── cache.c ├── cache.h ├── cleanup.c ├── close.c ├── common.c ├── common.h ├── create.c ├── ctx.c ├── ctx.h ├── engine.c ├── engine.h ├── engine.inf ├── engine.rc ├── engine.vcxproj ├── engine.vcxproj.filters ├── file.c ├── file.h ├── instance.c ├── queryinfo.c ├── read.c ├── setinfo.c └── write.c /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | [Ss]tyle[Cc]op.* 182 | ~$* 183 | *~ 184 | *.dbmdl 185 | *.dbproj.schemaview 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # RIA/Silverlight projects 192 | Generated_Code/ 193 | 194 | # Backup & report files from converting an old project file 195 | # to a newer Visual Studio version. Backup files are not needed, 196 | # because we have git ;-) 197 | _UpgradeReport_Files/ 198 | Backup*/ 199 | UpgradeLog*.XML 200 | UpgradeLog*.htm 201 | 202 | # SQL Server files 203 | *.mdf 204 | *.ldf 205 | 206 | # Business Intelligence projects 207 | *.rdl.data 208 | *.bim.layout 209 | *.bim_*.settings 210 | 211 | # Microsoft Fakes 212 | FakesAssemblies/ 213 | 214 | # GhostDoc plugin setting file 215 | *.GhostDoc.xml 216 | 217 | # Node.js Tools for Visual Studio 218 | .ntvs_analysis.dat 219 | 220 | # Visual Studio 6 build log 221 | *.plg 222 | 223 | # Visual Studio 6 workspace options file 224 | *.opt 225 | 226 | # Visual Studio LightSwitch build output 227 | **/*.HTMLClient/GeneratedArtifacts 228 | **/*.DesktopClient/GeneratedArtifacts 229 | **/*.DesktopClient/ModelManifest.xml 230 | **/*.Server/GeneratedArtifacts 231 | **/*.Server/ModelManifest.xml 232 | _Pvt_Extensions 233 | 234 | # LightSwitch generated files 235 | GeneratedArtifacts/ 236 | ModelManifest.xml 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | 241 | # FAKE - F# Make 242 | .fake/ 243 | -------------------------------------------------------------------------------- /engine.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "engine", "engine\engine.vcxproj", "{12DC8A22-CF43-4F31-817B-16273F6523BA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|ARM.Build.0 = Debug|ARM 22 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|x64.ActiveCfg = Debug|x64 27 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|x64.Build.0 = Debug|x64 28 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|x64.Deploy.0 = Debug|x64 29 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|x86.ActiveCfg = Debug|Win32 30 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|x86.Build.0 = Debug|Win32 31 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Debug|x86.Deploy.0 = Debug|Win32 32 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|ARM.ActiveCfg = Release|ARM 33 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|ARM.Build.0 = Release|ARM 34 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|ARM.Deploy.0 = Release|ARM 35 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|ARM64.Build.0 = Release|ARM64 37 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|x64.ActiveCfg = Release|x64 39 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|x64.Build.0 = Release|x64 40 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|x64.Deploy.0 = Release|x64 41 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|x86.ActiveCfg = Release|Win32 42 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|x86.Build.0 = Release|Win32 43 | {12DC8A22-CF43-4F31-817B-16273F6523BA}.Release|x86.Deploy.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | EndGlobal 49 | -------------------------------------------------------------------------------- /engine/CallbackRoutines.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef _CALLBACK_ROUTINE_H 3 | #define _CALLBACK_ROUTINE_H 4 | 5 | #include "common.h" 6 | #include "ctx.h" 7 | #include "cache.h" 8 | #include "file.h" 9 | 10 | 11 | /************************************************************************* 12 | MiniFilter callback routines. 13 | *************************************************************************/ 14 | FLT_PREOP_CALLBACK_STATUS 15 | PreCreate( 16 | _Inout_ PFLT_CALLBACK_DATA Data, 17 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 18 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 19 | ); 20 | 21 | 22 | 23 | FLT_POSTOP_CALLBACK_STATUS 24 | PostCreate( 25 | _Inout_ PFLT_CALLBACK_DATA Data, 26 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 27 | _In_opt_ PVOID CompletionContext, 28 | _In_ FLT_POST_OPERATION_FLAGS Flags 29 | ); 30 | 31 | FLT_PREOP_CALLBACK_STATUS 32 | PreRead( 33 | _Inout_ PFLT_CALLBACK_DATA Data, 34 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 35 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 36 | ); 37 | 38 | 39 | FLT_POSTOP_CALLBACK_STATUS 40 | PostRead( 41 | _Inout_ PFLT_CALLBACK_DATA Data, 42 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 43 | _In_ PVOID CompletionContext, 44 | _In_ FLT_POST_OPERATION_FLAGS Flags 45 | ); 46 | 47 | FLT_POSTOP_CALLBACK_STATUS 48 | SwapPostReadBuffersWhenSafe( 49 | _Inout_ PFLT_CALLBACK_DATA Data, 50 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 51 | _In_ PVOID CompletionContext, 52 | _In_ FLT_POST_OPERATION_FLAGS Flags 53 | ); 54 | 55 | 56 | FLT_PREOP_CALLBACK_STATUS 57 | PreWrite( 58 | _Inout_ PFLT_CALLBACK_DATA Data, 59 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 60 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 61 | ); 62 | 63 | FLT_POSTOP_CALLBACK_STATUS 64 | PostWrite( 65 | _Inout_ PFLT_CALLBACK_DATA Data, 66 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 67 | _In_ PVOID CompletionContext, 68 | _In_ FLT_POST_OPERATION_FLAGS Flags 69 | ); 70 | 71 | FLT_PREOP_CALLBACK_STATUS 72 | PreCleanup( 73 | _Inout_ PFLT_CALLBACK_DATA Data, 74 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 75 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 76 | ); 77 | 78 | FLT_PREOP_CALLBACK_STATUS 79 | PreClose( 80 | _Inout_ PFLT_CALLBACK_DATA Data, 81 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 82 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 83 | ); 84 | 85 | FLT_PREOP_CALLBACK_STATUS 86 | PreQueryInfo( 87 | _Inout_ PFLT_CALLBACK_DATA Data, 88 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 89 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 90 | ); 91 | 92 | FLT_POSTOP_CALLBACK_STATUS 93 | PostQueryInfo( 94 | _Inout_ PFLT_CALLBACK_DATA Data, 95 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 96 | _In_ PVOID CompletionContext, 97 | _In_ FLT_POST_OPERATION_FLAGS Flags 98 | ); 99 | 100 | 101 | FLT_PREOP_CALLBACK_STATUS 102 | PreSetInfo( 103 | _Inout_ PFLT_CALLBACK_DATA Data, 104 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 105 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 106 | ); 107 | 108 | 109 | FLT_POSTOP_CALLBACK_STATUS 110 | PostSetInfo( 111 | _Inout_ PFLT_CALLBACK_DATA Data, 112 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 113 | _In_ PVOID CompletionContext, 114 | _In_ FLT_POST_OPERATION_FLAGS Flags 115 | ); 116 | 117 | 118 | 119 | 120 | #endif -------------------------------------------------------------------------------- /engine/cache.c: -------------------------------------------------------------------------------- 1 | #include "cache.h" 2 | 3 | 4 | void Cc_ClearFileCache(PFILE_OBJECT FileObject, BOOLEAN bIsFlushCache, PLARGE_INTEGER FileOffset, ULONG Length) 5 | { 6 | BOOLEAN PurgeRes; 7 | BOOLEAN ResourceAcquired = FALSE; 8 | BOOLEAN PagingIoResourceAcquired = FALSE; 9 | PFSRTL_COMMON_FCB_HEADER Fcb = NULL; 10 | LARGE_INTEGER Delay50Milliseconds = { (ULONG)(-50 * 1000 * 10), -1 }; 11 | IO_STATUS_BLOCK IoStatus = { 0 }; 12 | 13 | if ((FileObject == NULL)) 14 | { 15 | return; 16 | } 17 | 18 | Fcb = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; 19 | if (Fcb == NULL) 20 | { 21 | return; 22 | } 23 | 24 | Acquire: 25 | FsRtlEnterFileSystem(); 26 | 27 | if (Fcb->Resource) 28 | ResourceAcquired = ExAcquireResourceExclusiveLite(Fcb->Resource, TRUE); 29 | if (Fcb->PagingIoResource) 30 | PagingIoResourceAcquired = ExAcquireResourceExclusive(Fcb->PagingIoResource, FALSE); 31 | else 32 | PagingIoResourceAcquired = TRUE; 33 | if (!PagingIoResourceAcquired) 34 | { 35 | if (Fcb->Resource) ExReleaseResource(Fcb->Resource); 36 | FsRtlExitFileSystem(); 37 | KeDelayExecutionThread(KernelMode, FALSE, &Delay50Milliseconds); 38 | goto Acquire; 39 | } 40 | 41 | if (FileObject->SectionObjectPointer) 42 | { 43 | IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP); 44 | 45 | if (bIsFlushCache) 46 | { 47 | CcFlushCache(FileObject->SectionObjectPointer, FileOffset, Length, &IoStatus); 48 | } 49 | 50 | if (FileObject->SectionObjectPointer->ImageSectionObject) 51 | { 52 | MmFlushImageSection( 53 | FileObject->SectionObjectPointer, 54 | MmFlushForWrite 55 | ); 56 | } 57 | 58 | if (FileObject->SectionObjectPointer->DataSectionObject) 59 | { 60 | PurgeRes = CcPurgeCacheSection(FileObject->SectionObjectPointer, 61 | NULL, 62 | 0, 63 | FALSE); 64 | } 65 | 66 | IoSetTopLevelIrp(NULL); 67 | } 68 | 69 | if (Fcb->PagingIoResource) 70 | ExReleaseResourceLite(Fcb->PagingIoResource); 71 | if (Fcb->Resource) 72 | ExReleaseResourceLite(Fcb->Resource); 73 | 74 | FsRtlExitFileSystem(); 75 | } 76 | -------------------------------------------------------------------------------- /engine/cache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _CLEAR_CHCHE_H 4 | #define _CLEAR_CHCHE_H 5 | 6 | #include "common.h" 7 | 8 | 9 | 10 | 11 | VOID 12 | Cc_ClearFileCache( 13 | __in PFILE_OBJECT FileObject, 14 | __in BOOLEAN bIsFlushCache, 15 | __in PLARGE_INTEGER FileOffset, 16 | __in ULONG Length 17 | ); 18 | 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /engine/cleanup.c: -------------------------------------------------------------------------------- 1 | #include "CallbackRoutines.h" 2 | 3 | FLT_PREOP_CALLBACK_STATUS 4 | PreCleanup( 5 | _Inout_ PFLT_CALLBACK_DATA Data, 6 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 7 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 8 | ) 9 | { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /engine/close.c: -------------------------------------------------------------------------------- 1 | #include "CallbackRoutines.h" 2 | 3 | 4 | FLT_PREOP_CALLBACK_STATUS 5 | PreClose( 6 | _Inout_ PFLT_CALLBACK_DATA Data, 7 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 8 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 9 | ) 10 | { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /engine/common.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | 4 | ULONG_PTR OperationStatusCtx = 1; 5 | ULONG gTraceFlags = 0; 6 | 7 | PCHAR MonitoredProcess[MAXNUM] = { NULL }; 8 | UNICODE_STRING Ext[MAXNUM] = { 0 }; 9 | UNICODE_STRING MonitoredDirectory = { 0 }; 10 | 11 | ULONG g_curProcessNameOffset; 12 | 13 | // 14 | // initialize the above process and ext 15 | // 16 | VOID InitMonitorVariable() 17 | { 18 | MonitoredProcess[0] = "notepad.exe"; 19 | //MonitoredProcess[0] = "acad.exe"; 20 | //MonitoredProcess[1] = "WINWORD.EXE"; 21 | //MonitoredProcess[2] = "ugraf.exe"; 22 | //MonitoredProcess[3] = "explorer.exe"; 23 | //MonitoredProcess[4] = "System"; 24 | //MonitoredProcess[5] = "EXCEL.EXE"; 25 | /*MonitoredProcess[1] = "Connect.Service.ContentService.exe"; 26 | MonitoredProcess[2] = "AdAppMgr.exe"; 27 | MonitoredProcess[3] = "AdAppMgrSvc.exe"; 28 | MonitoredProcess[4] = "WSCommCntr4.exe"; 29 | */ 30 | RtlInitUnicodeString(Ext + 0, L"txt"); 31 | //RtlInitUnicodeString(Ext + 1, L"tmp"); 32 | /*RtlInitUnicodeString(Ext+2, L"dwg"); 33 | RtlInitUnicodeString(Ext+3, L"dwl2");*/ 34 | 35 | RtlInitUnicodeString(&MonitoredDirectory, L"\\Device\\HarddiskVolume1\\Test"); 36 | } 37 | 38 | 39 | BOOLEAN IsMonitoredProcess(PCHAR procName) 40 | { 41 | int i; 42 | for (i = 0; i < MAXNUM; i++) 43 | { 44 | if (MonitoredProcess[i] == NULL)continue; 45 | if (strncmp(MonitoredProcess[i], procName, strlen(procName)) == 0) 46 | { 47 | return TRUE; 48 | } 49 | } 50 | 51 | return FALSE; 52 | } 53 | 54 | 55 | BOOLEAN IsMonitoredFileExt(PUNICODE_STRING ext) 56 | { 57 | int i; 58 | for (i = 0; i < MAXNUM; i++) 59 | { 60 | if (Ext[i].Length == 0)continue; 61 | if (RtlCompareUnicodeString(&Ext[i], ext, TRUE) == 0) 62 | { 63 | return TRUE; 64 | } 65 | } 66 | 67 | return FALSE; 68 | } 69 | 70 | 71 | BOOLEAN IsMonitored(PCHAR procName, PUNICODE_STRING ext) 72 | { 73 | if (IsMonitoredProcess(procName) && IsMonitoredFileExt(ext)) 74 | { 75 | return TRUE; 76 | } 77 | 78 | return FALSE; 79 | } 80 | 81 | 82 | 83 | ULONG GetProcessNameOffset() 84 | { 85 | PEPROCESS curproc = NULL; 86 | int i = 0; 87 | 88 | curproc = PsGetCurrentProcess(); 89 | 90 | for (i = 0; i<3 * PAGE_SIZE; i++) 91 | { 92 | if (!strncmp("System", (PCHAR)curproc + i, strlen("System"))) 93 | { 94 | return i; 95 | } 96 | } 97 | 98 | return 0; 99 | } 100 | 101 | PCHAR GetProcessName() 102 | { 103 | PEPROCESS curproc = NULL; 104 | curproc = PsGetCurrentProcess(); 105 | 106 | if (curproc != NULL) 107 | { 108 | return (PCHAR)curproc + g_curProcessNameOffset; 109 | } 110 | 111 | return NULL; 112 | } 113 | 114 | INT UnicodeStringIndexOf(UNICODE_STRING *sour, UNICODE_STRING *val) 115 | { 116 | 117 | if ((sour->Length)<(val->Length)) 118 | { 119 | 120 | return -1; 121 | } 122 | 123 | int i; 124 | 125 | int sour_len = sour->Length / 2; 126 | int val_len = val->Length / 2; 127 | int len = sour_len - val_len + 1; 128 | 129 | /*DbgPrint("sour is %wZ and val is %wZ",sour,val); 130 | DbgPrint("sour_len is %d and val_len is %d and len is %d",sour_len,val_len,len);*/ 131 | for (i = 0; iBuffer[i + j]; 138 | WCHAR c2 = val->Buffer[j]; 139 | 140 | if (c1 != c2) 141 | { 142 | flag = FALSE; 143 | break; 144 | } 145 | } 146 | if (flag) 147 | { 148 | 149 | return i; 150 | } 151 | } 152 | return -1; 153 | } 154 | 155 | BOOLEAN IsMonitoredDirectory(PUNICODE_STRING path) 156 | { 157 | if (UnicodeStringIndexOf(path, &MonitoredDirectory) == -1) 158 | { 159 | return FALSE; 160 | } 161 | 162 | return TRUE; 163 | } -------------------------------------------------------------------------------- /engine/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _COMMON_H 4 | #define _COMMON_H 5 | 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers") 12 | 13 | extern ULONG_PTR OperationStatusCtx; 14 | extern ULONG gTraceFlags; 15 | 16 | // 17 | // define the number of monitored process 18 | // 19 | #define MAXNUM 10 20 | extern PCHAR MonitoredProcess[MAXNUM]; 21 | extern UNICODE_STRING Ext[MAXNUM]; 22 | extern UNICODE_STRING MonitoredDirectory; 23 | 24 | extern ULONG g_curProcessNameOffset; 25 | 26 | 27 | // 28 | // The pool tag 29 | // 30 | 31 | 32 | #define BUFFER_SWAP_TAG 'bdBS' 33 | #define CONTEXT_TAG 'xcBS' 34 | #define NAME_TAG 'mnBS' 35 | #define PRE_2_POST_TAG 'ppBS' 36 | 37 | #define STRING_TAG 'tSxC' 38 | #define RESOURCE_TAG 'cRxC' 39 | #define STREAM_CONTEXT_TAG 'cSxC' 40 | #define FILEFLAG_POOL_TAG 'CVXC' 41 | 42 | #define SECTOR_SIZE 0X200 43 | #define FILE_GUID_LENGTH 16 44 | #define HASH_SIZE 20 45 | #define MAX_PATH 260 46 | 47 | 48 | 49 | VOID InitMonitorVariable(); 50 | 51 | BOOLEAN IsMonitoredProcess(PCHAR procName); 52 | 53 | BOOLEAN IsMonitoredFileExt(PUNICODE_STRING ext); 54 | 55 | BOOLEAN IsMonitored(PCHAR procName, PUNICODE_STRING ext); 56 | 57 | BOOLEAN IsMonitoredDirectory(PUNICODE_STRING path); 58 | 59 | ULONG GetProcessNameOffset(); 60 | 61 | PCHAR GetProcessName(); 62 | 63 | 64 | 65 | 66 | 67 | #endif -------------------------------------------------------------------------------- /engine/create.c: -------------------------------------------------------------------------------- 1 | #include "CallbackRoutines.h" 2 | 3 | 4 | FLT_PREOP_CALLBACK_STATUS 5 | PreCreate( 6 | _Inout_ PFLT_CALLBACK_DATA Data, 7 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 8 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 9 | ) 10 | { 11 | UNREFERENCED_PARAMETER(Data); 12 | UNREFERENCED_PARAMETER(FltObjects); 13 | UNREFERENCED_PARAMETER(CompletionContext); 14 | 15 | return FLT_PREOP_SUCCESS_WITH_CALLBACK; 16 | } 17 | 18 | 19 | 20 | FLT_POSTOP_CALLBACK_STATUS 21 | PostCreate( 22 | _Inout_ PFLT_CALLBACK_DATA Data, 23 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 24 | _In_opt_ PVOID CompletionContext, 25 | _In_ FLT_POST_OPERATION_FLAGS Flags 26 | ) 27 | { 28 | NTSTATUS status; 29 | PFLT_FILE_NAME_INFORMATION pfNameInfo = NULL; 30 | PSTREAM_CONTEXT pStreamCtx = NULL; 31 | 32 | BOOLEAN bNewCreated = FALSE; 33 | KIRQL oldIrql; 34 | ULONG uAccess = Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess; 35 | 36 | LARGE_INTEGER liFileSize = { 0 }; 37 | LARGE_INTEGER liFileOffset = { 0 }; 38 | PFILE_FLAG pFileFlag = NULL; 39 | 40 | LARGE_INTEGER liByteOffset = { 0 }; 41 | ULONG uReadLen = 0; 42 | 43 | try 44 | { 45 | if (!NT_SUCCESS(Data->IoStatus.Status)) 46 | { 47 | leave; 48 | } 49 | 50 | // 51 | // if it's a directory, just fail the operation. 52 | // 53 | 54 | BOOLEAN isDir = FALSE; 55 | status = FltIsDirectory(FltObjects->FileObject, 56 | FltObjects->Instance, &isDir); 57 | if (!NT_SUCCESS(status) || isDir) 58 | { 59 | leave; 60 | } 61 | 62 | // 63 | // Get the process 64 | // 65 | 66 | PCHAR procName = GetProcessName(); 67 | if (!IsMonitoredProcess(procName)) 68 | { 69 | leave; 70 | } 71 | 72 | // 73 | // Get the file name 74 | // 75 | 76 | status = FltGetFileNameInformation( 77 | Data, 78 | FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, 79 | &pfNameInfo 80 | ); 81 | if (!NT_SUCCESS(status) || NULL == pfNameInfo) 82 | { 83 | leave; 84 | } 85 | status = FltParseFileNameInformation(pfNameInfo); 86 | if (!NT_SUCCESS(status)) 87 | { 88 | leave; 89 | } 90 | 91 | if (!IsMonitoredFileExt(&pfNameInfo->Extension)) 92 | { 93 | leave; 94 | } 95 | 96 | #if DBG 97 | KdPrint(("\nIRP_MJ_CREATE\n")); 98 | KdPrint((" Process Name: %s\n", procName)); 99 | KdPrint((" The File Name: %wZ\n", &(pfNameInfo->Name))); 100 | KdPrint((" The File Ext: %wZ\n", &(pfNameInfo->Extension))); 101 | KdPrint((" The Volume: %wZ\n", &(pfNameInfo->Volume))); 102 | #endif 103 | 104 | // 105 | // In case, there is data in system cache, once open then clear the cache 106 | // 107 | 108 | Cc_ClearFileCache(FltObjects->FileObject, TRUE, NULL, 0); 109 | 110 | // 111 | // Create or get stream context 112 | // 113 | 114 | status = Ctx_FindOrCreateStreamContext(Data, FltObjects, TRUE, &pStreamCtx, &bNewCreated); 115 | if (!NT_SUCCESS(status)) 116 | { 117 | leave; 118 | } 119 | 120 | status = Ctx_UpdateNameInStreamContext(&pfNameInfo->Name, pStreamCtx); 121 | if (!NT_SUCCESS(status)) 122 | { 123 | leave; 124 | } 125 | 126 | if (!bNewCreated) 127 | { 128 | #if DBG 129 | KdPrint((" The Stream Context Has already Created, Just Use it.")); 130 | #endif 131 | SC_LOCK(pStreamCtx, &oldIrql); 132 | 133 | pStreamCtx->uAccess = uAccess; 134 | 135 | SC_UNLOCK(pStreamCtx, oldIrql); 136 | leave; 137 | } 138 | 139 | // 140 | // The file first open, initialize the stream context 141 | // 142 | 143 | SC_LOCK(pStreamCtx, &oldIrql); 144 | 145 | RtlCopyMemory(pStreamCtx->wsVolumeName, pfNameInfo->Volume.Buffer, pfNameInfo->Volume.Length); 146 | pStreamCtx->bHasFileEncrypted = FALSE; 147 | pStreamCtx->bNeedDecryptOnRead = FALSE; 148 | pStreamCtx->bNeedEncryptOnWrite = TRUE; 149 | pStreamCtx->bHasWrittenData = FALSE; 150 | pStreamCtx->uAccess = uAccess; 151 | pStreamCtx->uTrailLength = FILE_FLAG_LENGTH; 152 | 153 | SC_UNLOCK(pStreamCtx, oldIrql); 154 | 155 | // 156 | // Get file size 157 | // 158 | 159 | status = File_GetFileStandardInfo(Data, FltObjects, NULL, &liFileSize, NULL); 160 | if (!NT_SUCCESS(status)) 161 | { 162 | leave; 163 | } 164 | 165 | SC_LOCK(pStreamCtx, &oldIrql); 166 | pStreamCtx->liFileSize = liFileSize; 167 | SC_UNLOCK(pStreamCtx, oldIrql); 168 | 169 | if ((0 == liFileSize.QuadPart) && (uAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA))) 170 | {//new created file with write or append access 171 | leave; 172 | } 173 | if ((0 == liFileSize.QuadPart) && !(uAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA))) 174 | {// file size is zero, but without write or append access 175 | leave; 176 | } 177 | 178 | //if file size is less than file flag length, the file is not encrypted yet but need to be encrypted 179 | if (liFileSize.QuadPart < FILE_FLAG_LENGTH) 180 | { 181 | leave; 182 | } 183 | 184 | // 185 | // hold the original bytesoffset 186 | // 187 | 188 | File_GetFileOffset(Data, FltObjects, &liFileOffset); 189 | 190 | pFileFlag = (PFILE_FLAG)ExAllocatePoolWithTag(NonPagedPool, FILE_FLAG_LENGTH, FILEFLAG_POOL_TAG); 191 | liByteOffset.QuadPart = liFileSize.QuadPart - FILE_FLAG_LENGTH; 192 | status = File_ReadWriteFile( 193 | IRP_MJ_READ, 194 | FltObjects->Instance, 195 | FltObjects->FileObject, 196 | &liByteOffset, 197 | FILE_FLAG_LENGTH, 198 | pFileFlag, 199 | &uReadLen, 200 | FLTFL_IO_OPERATION_NON_CACHED | FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET 201 | ); 202 | if (!NT_SUCCESS(status)) 203 | { 204 | leave; 205 | } 206 | 207 | File_SetFileOffset(Data, FltObjects, &liFileOffset); 208 | 209 | 210 | // 211 | // Compare guid 212 | // 213 | 214 | if (FILE_GUID_LENGTH != RtlCompareMemory(g_pFileFlag, pFileFlag, FILE_GUID_LENGTH)) 215 | {//not equal, so the file has not been encrypted yet. 216 | SC_LOCK(pStreamCtx, &oldIrql); 217 | pStreamCtx->liFileValidLength = liFileSize; //file is existing and has no tail, so filevalidlength equals filesize. 218 | SC_UNLOCK(pStreamCtx, oldIrql); 219 | 220 | #if DBG 221 | KdPrint((" The File Has Not Been Encrypted.")); 222 | #endif 223 | leave; 224 | } 225 | 226 | // 227 | // file has been encrypted, reset some fileds 228 | // 229 | 230 | SC_LOCK(pStreamCtx, &oldIrql); 231 | 232 | pStreamCtx->liFileValidLength.QuadPart = pFileFlag->llFileValidLength; 233 | pStreamCtx->bHasFileEncrypted = TRUE; 234 | pStreamCtx->bNeedDecryptOnRead = TRUE; 235 | pStreamCtx->bNeedEncryptOnWrite = TRUE; 236 | pStreamCtx->uTrailLength = FILE_FLAG_LENGTH; 237 | 238 | SC_UNLOCK(pStreamCtx, oldIrql); 239 | 240 | #if DBG 241 | KdPrint((" The File Has Already Been Encrypted.")); 242 | #endif 243 | 244 | } 245 | finally 246 | { 247 | // 248 | // This resources we don't need anymore, so 249 | // free all of them 250 | // 251 | 252 | if (NULL != pfNameInfo) 253 | { 254 | FltReleaseFileNameInformation(pfNameInfo); 255 | } 256 | 257 | if (NULL != pStreamCtx) 258 | { 259 | FltReleaseContext(pStreamCtx); 260 | } 261 | } 262 | 263 | 264 | return FLT_POSTOP_FINISHED_PROCESSING; 265 | } 266 | -------------------------------------------------------------------------------- /engine/ctx.c: -------------------------------------------------------------------------------- 1 | #include "ctx.h" 2 | 3 | NPAGED_LOOKASIDE_LIST Pre2PostContextList; 4 | 5 | 6 | static NTSTATUS iCtx_CreateStreamContext(PFLT_RELATED_OBJECTS FltObjects, PSTREAM_CONTEXT *StreamContext); 7 | 8 | VOID SC_iLOCK(PERESOURCE pResource) 9 | { 10 | try 11 | { 12 | ASSERT(KeGetCurrentIrql() <= APC_LEVEL); 13 | ASSERT(ExIsResourceAcquiredExclusiveLite(pResource) || !ExIsResourceAcquiredSharedLite(pResource)); 14 | 15 | KeEnterCriticalRegion(); 16 | (VOID)ExAcquireResourceExclusiveLite(pResource, TRUE); 17 | } 18 | finally 19 | { 20 | } 21 | } 22 | 23 | 24 | 25 | VOID SC_iUNLOCK(PERESOURCE pResource) 26 | { 27 | try 28 | { 29 | ASSERT(KeGetCurrentIrql() <= APC_LEVEL); 30 | ASSERT(ExIsResourceAcquiredExclusiveLite(pResource) || ExIsResourceAcquiredSharedLite(pResource)); 31 | 32 | ExReleaseResourceLite(pResource); 33 | KeLeaveCriticalRegion(); 34 | } 35 | finally 36 | { 37 | } 38 | } 39 | 40 | 41 | VOID SC_LOCK(PSTREAM_CONTEXT SC, PKIRQL OldIrql) 42 | { 43 | if (KeGetCurrentIrql() <= APC_LEVEL) 44 | { 45 | SC_iLOCK(SC->resource); 46 | } 47 | else 48 | { 49 | KeAcquireSpinLock(&SC->resource1, OldIrql); 50 | } 51 | } 52 | 53 | 54 | VOID SC_UNLOCK(PSTREAM_CONTEXT SC, KIRQL OldIrql) 55 | { 56 | if (KeGetCurrentIrql() <= APC_LEVEL) 57 | { 58 | SC_iUNLOCK(SC->resource); 59 | } 60 | else 61 | { 62 | KeReleaseSpinLock(&SC->resource1, OldIrql); 63 | } 64 | } 65 | 66 | 67 | 68 | NTSTATUS 69 | Ctx_FindOrCreateStreamContext( 70 | __in PFLT_CALLBACK_DATA Data, 71 | __in PFLT_RELATED_OBJECTS FltObjects, 72 | __in BOOLEAN CreateIfNotFound, 73 | __deref_out PSTREAM_CONTEXT *StreamContext, 74 | __out_opt BOOLEAN* ContextCreated 75 | ) 76 | { 77 | NTSTATUS status; 78 | PSTREAM_CONTEXT streamContext; 79 | PSTREAM_CONTEXT oldStreamContext; 80 | 81 | PAGED_CODE(); 82 | 83 | *StreamContext = NULL; 84 | if (ContextCreated != NULL) *ContextCreated = FALSE; 85 | 86 | // First try to get the stream context. 87 | status = FltGetStreamContext(Data->Iopb->TargetInstance, 88 | Data->Iopb->TargetFileObject, &streamContext); 89 | 90 | if (!NT_SUCCESS(status) && 91 | (status == STATUS_NOT_FOUND) && 92 | CreateIfNotFound) 93 | { 94 | status = iCtx_CreateStreamContext(FltObjects, &streamContext); 95 | if (!NT_SUCCESS(status)) 96 | return status; 97 | 98 | status = FltSetStreamContext(Data->Iopb->TargetInstance, 99 | Data->Iopb->TargetFileObject, 100 | FLT_SET_CONTEXT_KEEP_IF_EXISTS, 101 | streamContext, 102 | &oldStreamContext); 103 | 104 | if (!NT_SUCCESS(status)) 105 | { 106 | FltReleaseContext(streamContext); 107 | 108 | if (status != STATUS_FLT_CONTEXT_ALREADY_DEFINED) 109 | { 110 | // FltSetStreamContext failed for a reason other than the context already 111 | // existing on the stream. So the object now does not have any context set 112 | // on it. So we return failure to the caller. 113 | return status; 114 | } 115 | streamContext = oldStreamContext; 116 | status = STATUS_SUCCESS; 117 | } 118 | else 119 | { 120 | if (ContextCreated != NULL) *ContextCreated = TRUE; 121 | } 122 | } 123 | *StreamContext = streamContext; 124 | 125 | return status; 126 | 127 | } 128 | 129 | NTSTATUS 130 | Ctx_UpdateNameInStreamContext( 131 | __in PUNICODE_STRING DirectoryName, 132 | __inout PSTREAM_CONTEXT StreamContext 133 | ) 134 | { 135 | NTSTATUS status = STATUS_SUCCESS; 136 | 137 | PAGED_CODE(); 138 | 139 | //Free any existing name 140 | if (StreamContext->uniFileName.Buffer != NULL) 141 | { 142 | ExFreePoolWithTag(StreamContext->uniFileName.Buffer, STRING_TAG); 143 | 144 | StreamContext->uniFileName.Length = StreamContext->uniFileName.MaximumLength = 0; 145 | StreamContext->uniFileName.Buffer = NULL; 146 | } 147 | 148 | //Allocate and copy off the directory name 149 | StreamContext->uniFileName.MaximumLength = DirectoryName->Length; 150 | StreamContext->uniFileName.Buffer = ExAllocatePoolWithTag(PagedPool, 151 | StreamContext->uniFileName.MaximumLength, 152 | STRING_TAG); 153 | if (StreamContext->uniFileName.Buffer == NULL) 154 | { 155 | return STATUS_INSUFFICIENT_RESOURCES; 156 | } 157 | 158 | RtlCopyUnicodeString(&StreamContext->uniFileName, DirectoryName); 159 | 160 | return status; 161 | } 162 | 163 | NTSTATUS 164 | iCtx_CreateStreamContext( 165 | __in PFLT_RELATED_OBJECTS FltObjects, 166 | __deref_out PSTREAM_CONTEXT *StreamContext 167 | ) 168 | { 169 | NTSTATUS status; 170 | PSTREAM_CONTEXT streamContext; 171 | 172 | PAGED_CODE(); 173 | 174 | status = FltAllocateContext(FltObjects->Filter, 175 | FLT_STREAM_CONTEXT, 176 | sizeof(STREAM_CONTEXT), 177 | NonPagedPool, 178 | &streamContext); 179 | if (!NT_SUCCESS(status)) 180 | { 181 | return status; 182 | } 183 | 184 | // Initialize the newly created context 185 | RtlZeroMemory(streamContext, sizeof(STREAM_CONTEXT)); 186 | 187 | streamContext->resource = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERESOURCE), RESOURCE_TAG); 188 | if (streamContext->resource == NULL) 189 | { 190 | FltReleaseContext(streamContext); 191 | return STATUS_INSUFFICIENT_RESOURCES; 192 | } 193 | ExInitializeResourceLite(streamContext->resource); 194 | 195 | KeInitializeSpinLock(&streamContext->resource1); 196 | 197 | *StreamContext = streamContext; 198 | 199 | return STATUS_SUCCESS; 200 | } 201 | 202 | 203 | 204 | 205 | VOID CleanupStreamContext( 206 | _In_ PFLT_CONTEXT Context, 207 | _In_ FLT_CONTEXT_TYPE ContextType 208 | ) 209 | { 210 | PSTREAM_CONTEXT streamCtx = NULL; 211 | streamCtx = (PSTREAM_CONTEXT)Context; 212 | 213 | if (streamCtx->uniFileName.Buffer != NULL) 214 | { 215 | ExFreePoolWithTag(streamCtx->uniFileName.Buffer, STRING_TAG); 216 | 217 | streamCtx->uniFileName.Length = streamCtx->uniFileName.MaximumLength = 0; 218 | streamCtx->uniFileName.Buffer = NULL; 219 | } 220 | 221 | if (NULL != streamCtx->resource) 222 | { 223 | ExDeleteResourceLite(streamCtx->resource); 224 | ExFreePoolWithTag(streamCtx->resource, RESOURCE_TAG); 225 | } 226 | 227 | FltReleaseContext(streamCtx); 228 | } 229 | 230 | -------------------------------------------------------------------------------- /engine/ctx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _CONTEXT_H 4 | #define _CONTEXT_H 5 | 6 | #include "common.h" 7 | 8 | typedef struct _STREAM_CONTEXT 9 | { 10 | UNICODE_STRING uniFileName; 11 | 12 | WCHAR wsVolumeName[64]; 13 | 14 | LARGE_INTEGER liFileValidLength; 15 | 16 | LARGE_INTEGER liFileSize; 17 | 18 | ULONG uTrailLength; 19 | 20 | ULONG uAccess; 21 | 22 | BOOLEAN bHasFileEncrypted; //if file has been encrypted, if the file has the tail 23 | BOOLEAN bNeedEncryptOnWrite; 24 | BOOLEAN bNeedDecryptOnRead; 25 | BOOLEAN bHasWrittenData; 26 | 27 | 28 | PERESOURCE resource; 29 | 30 | KSPIN_LOCK resource1; 31 | 32 | }STREAM_CONTEXT, *PSTREAM_CONTEXT; 33 | 34 | 35 | typedef struct _PRE_2_POST_CONTEXT 36 | { 37 | PSTREAM_CONTEXT pStreamCtx; //carry the file information 38 | 39 | PVOID SwappedBuffer; 40 | 41 | }PRE_2_POST_CONTEXT, *PPRE_2_POST_CONTEXT; 42 | 43 | 44 | 45 | VOID SC_iLOCK(PERESOURCE pResource); 46 | VOID SC_iUNLOCK(PERESOURCE pResource); 47 | 48 | VOID 49 | SC_LOCK(PSTREAM_CONTEXT SC, PKIRQL OldIrql); 50 | 51 | VOID 52 | SC_UNLOCK(PSTREAM_CONTEXT SC, KIRQL OldIrql); 53 | 54 | 55 | 56 | NTSTATUS 57 | Ctx_FindOrCreateStreamContext( 58 | __in PFLT_CALLBACK_DATA Cbd, 59 | __in PFLT_RELATED_OBJECTS FltObjects, 60 | __in BOOLEAN CreateIfNotFound, 61 | __deref_out PSTREAM_CONTEXT *StreamContext, 62 | __out_opt BOOLEAN* ContextCreated 63 | ); 64 | 65 | NTSTATUS 66 | Ctx_UpdateNameInStreamContext( 67 | __in PUNICODE_STRING DirectoryName, 68 | __inout PSTREAM_CONTEXT StreamContext 69 | ); 70 | 71 | 72 | VOID CleanupStreamContext( 73 | _In_ PFLT_CONTEXT Context, 74 | _In_ FLT_CONTEXT_TYPE ContextType 75 | ); 76 | 77 | 78 | extern NPAGED_LOOKASIDE_LIST Pre2PostContextList; 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /engine/engine.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Module Name: 4 | 5 | engine.c 6 | 7 | Abstract: 8 | 9 | This is the main module of the engine miniFilter driver. 10 | 11 | Environment: 12 | 13 | Kernel mode 14 | 15 | --*/ 16 | 17 | #include "engine.h" 18 | 19 | PFLT_FILTER gFilterHandle; 20 | 21 | // 22 | // operation registration 23 | // 24 | 25 | CONST FLT_OPERATION_REGISTRATION Callbacks[] = { 26 | 27 | { 28 | IRP_MJ_CREATE, 29 | FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, 30 | PreCreate, 31 | PostCreate 32 | }, 33 | 34 | { 35 | IRP_MJ_CLEANUP, 36 | FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, 37 | PreCleanup, 38 | NULL 39 | }, 40 | 41 | //{ 42 | // IRP_MJ_CLOSE, 43 | // 0, 44 | // PreClose, 45 | // NULL 46 | //}, 47 | 48 | //{ 49 | // IRP_MJ_QUERY_INFORMATION, 50 | // 0, 51 | // PreQueryInfo, 52 | // PostQueryInfo 53 | //}, 54 | 55 | //{ 56 | // IRP_MJ_SET_INFORMATION, 57 | // 0, 58 | // PreSetInfo, 59 | // PostSetInfo 60 | //}, 61 | 62 | 63 | //{ 64 | // IRP_MJ_READ, 65 | // 0, 66 | // PreRead, 67 | // PostRead 68 | //}, 69 | 70 | //{ 71 | // IRP_MJ_WRITE, 72 | // 0, 73 | // PreWrite, 74 | // PostWrite 75 | //}, 76 | 77 | { IRP_MJ_OPERATION_END } 78 | }; 79 | 80 | // 81 | //Context definitions we currently care about 82 | // 83 | CONST FLT_CONTEXT_REGISTRATION ContextNotifications[] = { 84 | 85 | { 86 | FLT_STREAM_CONTEXT, 87 | 0, 88 | CleanupStreamContext, 89 | sizeof(STREAM_CONTEXT), 90 | CONTEXT_TAG 91 | }, 92 | 93 | 94 | { FLT_CONTEXT_END } 95 | }; 96 | 97 | // 98 | // This defines what we want to filter with FltMgr 99 | // 100 | 101 | CONST FLT_REGISTRATION FilterRegistration = { 102 | 103 | sizeof( FLT_REGISTRATION ), // Size 104 | FLT_REGISTRATION_VERSION, // Version 105 | 0, // Flags 106 | 107 | ContextNotifications, // Context 108 | Callbacks, // Operation callbacks 109 | 110 | engineUnload, // MiniFilterUnload 111 | 112 | engineInstanceSetup, // InstanceSetup 113 | engineInstanceQueryTeardown, // InstanceQueryTeardown 114 | engineInstanceTeardownStart, // InstanceTeardownStart 115 | engineInstanceTeardownComplete, // InstanceTeardownComplete 116 | 117 | NULL, // GenerateFileName 118 | NULL, // GenerateDestinationFileName 119 | NULL // NormalizeNameComponent 120 | 121 | }; 122 | 123 | 124 | 125 | 126 | 127 | /************************************************************************* 128 | MiniFilter initialization and unload routines. 129 | *************************************************************************/ 130 | 131 | NTSTATUS 132 | DriverEntry ( 133 | _In_ PDRIVER_OBJECT DriverObject, 134 | _In_ PUNICODE_STRING RegistryPath 135 | ) 136 | /*++ 137 | 138 | Routine Description: 139 | 140 | This is the initialization routine for this miniFilter driver. This 141 | registers with FltMgr and initializes all global data structures. 142 | 143 | Arguments: 144 | 145 | DriverObject - Pointer to driver object created by the system to 146 | represent this driver. 147 | 148 | RegistryPath - Unicode string identifying where the parameters for this 149 | driver are located in the registry. 150 | 151 | Return Value: 152 | 153 | Routine can return non success error codes. 154 | 155 | --*/ 156 | { 157 | NTSTATUS status; 158 | 159 | UNREFERENCED_PARAMETER( RegistryPath ); 160 | 161 | PT_DBG_PRINT( PTDBG_TRACE_ROUTINES, 162 | ("engine!DriverEntry: Entered\n") ); 163 | 164 | // 165 | // Initialize the variable 166 | // 167 | 168 | g_curProcessNameOffset = GetProcessNameOffset(); 169 | InitMonitorVariable(); 170 | #if DBG 171 | KdPrint((" Process Name: %d", g_curProcessNameOffset)); 172 | #endif 173 | 174 | File_InitFileFlag(); 175 | 176 | // 177 | // Register with FltMgr to tell it our callback routines 178 | // 179 | 180 | status = FltRegisterFilter( DriverObject, 181 | &FilterRegistration, 182 | &gFilterHandle ); 183 | 184 | FLT_ASSERT( NT_SUCCESS( status ) ); 185 | 186 | if (NT_SUCCESS( status )) { 187 | 188 | // 189 | // Start filtering i/o 190 | // 191 | 192 | status = FltStartFiltering( gFilterHandle ); 193 | 194 | if (!NT_SUCCESS( status )) { 195 | 196 | FltUnregisterFilter( gFilterHandle ); 197 | } 198 | } 199 | 200 | return status; 201 | } 202 | 203 | NTSTATUS 204 | engineUnload ( 205 | _In_ FLT_FILTER_UNLOAD_FLAGS Flags 206 | ) 207 | /*++ 208 | 209 | Routine Description: 210 | 211 | This is the unload routine for this miniFilter driver. This is called 212 | when the minifilter is about to be unloaded. We can fail this unload 213 | request if this is not a mandatory unload indicated by the Flags 214 | parameter. 215 | 216 | Arguments: 217 | 218 | Flags - Indicating if this is a mandatory unload. 219 | 220 | Return Value: 221 | 222 | Returns STATUS_SUCCESS. 223 | 224 | --*/ 225 | { 226 | UNREFERENCED_PARAMETER( Flags ); 227 | 228 | PAGED_CODE(); 229 | 230 | PT_DBG_PRINT( PTDBG_TRACE_ROUTINES, 231 | ("engine!engineUnload: Entered\n") ); 232 | 233 | FltUnregisterFilter( gFilterHandle ); 234 | File_UninitFileFlag(); 235 | 236 | return STATUS_SUCCESS; 237 | } 238 | 239 | -------------------------------------------------------------------------------- /engine/engine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef _ENGINE_H 3 | #define _ENGINE_H 4 | 5 | #include "common.h" 6 | #include "CallbackRoutines.h" 7 | 8 | #define PTDBG_TRACE_ROUTINES 0x00000001 9 | #define PTDBG_TRACE_OPERATION_STATUS 0x00000002 10 | 11 | #define PT_DBG_PRINT( _dbgLevel, _string ) \ 12 | (FlagOn(gTraceFlags,(_dbgLevel)) ? \ 13 | DbgPrint _string : \ 14 | ((int)0)) 15 | 16 | 17 | /************************************************************************* 18 | Prototypes 19 | *************************************************************************/ 20 | 21 | EXTERN_C_START 22 | 23 | DRIVER_INITIALIZE DriverEntry; 24 | NTSTATUS 25 | DriverEntry( 26 | _In_ PDRIVER_OBJECT DriverObject, 27 | _In_ PUNICODE_STRING RegistryPath 28 | ); 29 | 30 | NTSTATUS 31 | engineInstanceSetup( 32 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 33 | _In_ FLT_INSTANCE_SETUP_FLAGS Flags, 34 | _In_ DEVICE_TYPE VolumeDeviceType, 35 | _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType 36 | ); 37 | 38 | VOID 39 | engineInstanceTeardownStart( 40 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 41 | _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags 42 | ); 43 | 44 | VOID 45 | engineInstanceTeardownComplete( 46 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 47 | _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags 48 | ); 49 | 50 | NTSTATUS 51 | engineUnload( 52 | _In_ FLT_FILTER_UNLOAD_FLAGS Flags 53 | ); 54 | 55 | NTSTATUS 56 | engineInstanceQueryTeardown( 57 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 58 | _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags 59 | ); 60 | 61 | 62 | 63 | EXTERN_C_END 64 | 65 | // 66 | // Assign text sections for each routine. 67 | // 68 | 69 | #ifdef ALLOC_PRAGMA 70 | #pragma alloc_text(INIT, DriverEntry) 71 | #pragma alloc_text(PAGE, engineUnload) 72 | #pragma alloc_text(PAGE, engineInstanceQueryTeardown) 73 | #pragma alloc_text(PAGE, engineInstanceSetup) 74 | #pragma alloc_text(PAGE, engineInstanceTeardownStart) 75 | #pragma alloc_text(PAGE, engineInstanceTeardownComplete) 76 | #endif 77 | 78 | 79 | 80 | 81 | 82 | #endif 83 | 84 | 85 | -------------------------------------------------------------------------------- /engine/engine.inf: -------------------------------------------------------------------------------- 1 | ;;; 2 | ;;; engine 3 | ;;; 4 | 5 | [Version] 6 | Signature = "$Windows NT$" 7 | 8 | Class = "ActivityMonitor" ;This is determined by the work this filter driver does 9 | ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2} ;This value is determined by the Load Order Group value 10 | 11 | Provider = %ManufacturerName% 12 | DriverVer = 10/01/2017,3.0.0.0 13 | CatalogFile = engine.cat 14 | 15 | [DestinationDirs] 16 | DefaultDestDir = 12 17 | MiniFilter.DriverFiles = 12 ;%windir%\system32\drivers 18 | 19 | ;; 20 | ;; Default install sections 21 | ;; 22 | 23 | [DefaultInstall] 24 | OptionDesc = %ServiceDescription% 25 | CopyFiles = MiniFilter.DriverFiles 26 | 27 | [DefaultInstall.Services] 28 | AddService = %ServiceName%,,MiniFilter.Service 29 | 30 | ;; 31 | ;; Default uninstall sections 32 | ;; 33 | 34 | [DefaultUninstall] 35 | DelFiles = MiniFilter.DriverFiles 36 | 37 | [DefaultUninstall.Services] 38 | DelService = %ServiceName%,0x200 ;Ensure service is stopped before deleting 39 | 40 | ; 41 | ; Services Section 42 | ; 43 | 44 | [MiniFilter.Service] 45 | DisplayName = %ServiceName% 46 | Description = %ServiceDescription% 47 | ServiceBinary = %12%\%DriverName%.sys ;%windir%\system32\drivers\ 48 | Dependencies = "FltMgr" 49 | ServiceType = 2 ;SERVICE_FILE_SYSTEM_DRIVER 50 | StartType = 3 ;SERVICE_DEMAND_START 51 | ErrorControl = 1 ;SERVICE_ERROR_NORMAL 52 | 53 | LoadOrderGroup = "FSFilter Encryption" 54 | AddReg = MiniFilter.AddRegistry 55 | 56 | ; 57 | ; Registry Modifications 58 | ; 59 | 60 | [MiniFilter.AddRegistry] 61 | HKR,,"DebugFlags",0x00010001 ,0x0 62 | HKR,,"SupportedFeatures",0x00010001,0x3 63 | HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance% 64 | HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude% 65 | HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags% 66 | 67 | ; 68 | ; Copy Files 69 | ; 70 | 71 | [MiniFilter.DriverFiles] 72 | %DriverName%.sys 73 | 74 | [SourceDisksFiles] 75 | engine.sys = 1,, 76 | 77 | [SourceDisksNames] 78 | 1 = %DiskId1%,,, 79 | 80 | ;; 81 | ;; String Section 82 | ;; 83 | 84 | [Strings] 85 | ; TODO - Add your manufacturer 86 | ManufacturerName = "Hache" 87 | ServiceDescription = "engine Mini-Filter Driver" 88 | ServiceName = "engine" 89 | DriverName = "engine" 90 | DiskId1 = "engine Device Installation Disk" 91 | 92 | ;Instances specific information. 93 | DefaultInstance = "engine Instance" 94 | Instance1.Name = "engine Instance" 95 | 96 | Instance1.Altitude = "141000" 97 | Instance1.Flags = 0x0 ; Allow all attachments 98 | -------------------------------------------------------------------------------- /engine/engine.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #define VER_FILETYPE VFT_DRV 6 | #define VER_FILESUBTYPE VFT2_DRV_SYSTEM 7 | #define VER_FILEDESCRIPTION_STR "engine Filter Driver" 8 | #define VER_INTERNALNAME_STR "engine.sys" 9 | 10 | #include "common.ver" 11 | -------------------------------------------------------------------------------- /engine/engine.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {12DC8A22-CF43-4F31-817B-16273F6523BA} 56 | {f2f62967-0815-4fd7-9b86-6eedcac766eb} 57 | v4.5 58 | 12.0 59 | Debug 60 | Win32 61 | engine 62 | 63 | 64 | 65 | Windows10 66 | true 67 | WindowsKernelModeDriver10.0 68 | Driver 69 | WDM 70 | 71 | 72 | Windows10 73 | false 74 | WindowsKernelModeDriver10.0 75 | Driver 76 | WDM 77 | 78 | 79 | Windows10 80 | true 81 | WindowsKernelModeDriver10.0 82 | Driver 83 | WDM 84 | 85 | 86 | Windows10 87 | false 88 | WindowsKernelModeDriver10.0 89 | Driver 90 | WDM 91 | 92 | 93 | Windows10 94 | true 95 | WindowsKernelModeDriver10.0 96 | Driver 97 | WDM 98 | 99 | 100 | Windows10 101 | false 102 | WindowsKernelModeDriver10.0 103 | Driver 104 | WDM 105 | 106 | 107 | Windows10 108 | true 109 | WindowsKernelModeDriver10.0 110 | Driver 111 | WDM 112 | 113 | 114 | Windows10 115 | false 116 | WindowsKernelModeDriver10.0 117 | Driver 118 | WDM 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | DbgengKernelDebugger 130 | 131 | 132 | DbgengKernelDebugger 133 | 134 | 135 | DbgengKernelDebugger 136 | 137 | 138 | DbgengKernelDebugger 139 | 140 | 141 | DbgengKernelDebugger 142 | 143 | 144 | DbgengKernelDebugger 145 | 146 | 147 | DbgengKernelDebugger 148 | 149 | 150 | DbgengKernelDebugger 151 | 152 | 153 | 154 | fltmgr.lib;%(AdditionalDependencies) 155 | 156 | 157 | 158 | 159 | fltmgr.lib;%(AdditionalDependencies) 160 | 161 | 162 | 163 | 164 | fltmgr.lib;%(AdditionalDependencies) 165 | 166 | 167 | TurnOffAllWarnings 168 | 169 | 170 | 171 | 172 | fltmgr.lib;%(AdditionalDependencies) 173 | 174 | 175 | 176 | 177 | fltmgr.lib;%(AdditionalDependencies) 178 | 179 | 180 | 181 | 182 | fltmgr.lib;%(AdditionalDependencies) 183 | 184 | 185 | 186 | 187 | fltmgr.lib;%(AdditionalDependencies) 188 | 189 | 190 | 191 | 192 | fltmgr.lib;%(AdditionalDependencies) 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /engine/engine.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | Source Files 59 | 60 | 61 | Source Files 62 | 63 | 64 | Source Files 65 | 66 | 67 | 68 | 69 | Resource Files 70 | 71 | 72 | 73 | 74 | Header Files 75 | 76 | 77 | Header Files 78 | 79 | 80 | Header Files 81 | 82 | 83 | Header Files 84 | 85 | 86 | Header Files 87 | 88 | 89 | Header Files 90 | 91 | 92 | -------------------------------------------------------------------------------- /engine/file.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JokerMars/MiniEngine/18d773886738bdab52e8cb1d2bb2aead9ecc3607/engine/file.c -------------------------------------------------------------------------------- /engine/file.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _FILE_DEFINED_H 4 | #define _FILE_DEFINED_H 5 | 6 | #include "common.h" 7 | #include "ctx.h" 8 | 9 | #pragma pack(1) 10 | 11 | typedef struct _FILE_FLAG 12 | { 13 | UCHAR strFileFlagHeader[FILE_GUID_LENGTH]; 14 | 15 | UCHAR strFileKeyHash[HASH_SIZE]; 16 | 17 | LONGLONG llFileValidLength; 18 | 19 | UCHAR Reserved[SECTOR_SIZE - HASH_SIZE - FILE_GUID_LENGTH - 8]; 20 | 21 | }FILE_FLAG, *PFILE_FLAG; 22 | 23 | #pragma pack() 24 | 25 | #define FILE_FLAG_LENGTH sizeof(FILE_FLAG) 26 | 27 | 28 | NTSTATUS 29 | File_GetFileOffset( 30 | _In_ PFLT_CALLBACK_DATA Data, 31 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 32 | _Out_ PLARGE_INTEGER FileOffset 33 | ); 34 | 35 | NTSTATUS 36 | File_SetFileOffset( 37 | _In_ PFLT_CALLBACK_DATA Data, 38 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 39 | _In_ PLARGE_INTEGER FileOffset 40 | ); 41 | 42 | 43 | NTSTATUS 44 | File_GetFileSize( 45 | _In_ PFLT_CALLBACK_DATA Data, 46 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 47 | _Out_ PLARGE_INTEGER FileSize 48 | ); 49 | 50 | NTSTATUS 51 | File_SetFileSize( 52 | _In_ PFLT_CALLBACK_DATA Data, 53 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 54 | _In_ PLARGE_INTEGER FileSize 55 | ); 56 | 57 | NTSTATUS 58 | File_GetFileStandardInfo( 59 | _In_ PFLT_CALLBACK_DATA Data, 60 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 61 | _In_ PLARGE_INTEGER FileAllocationSize, 62 | _In_ PLARGE_INTEGER FileSize, 63 | _In_ PBOOLEAN isDirectory 64 | ); 65 | 66 | 67 | 68 | NTSTATUS 69 | File_ReadWriteFile( 70 | _In_ ULONG MajorFunction, 71 | _In_ PFLT_INSTANCE Instance, 72 | _In_ PFILE_OBJECT FileObject, 73 | _In_ PLARGE_INTEGER ByteOffset, 74 | _In_ ULONG Length, 75 | _In_ PVOID Buffer, 76 | _Out_ PULONG BytesReadWrite, 77 | _In_ FLT_IO_OPERATION_FLAGS FltFlags 78 | ); 79 | 80 | 81 | 82 | NTSTATUS 83 | File_WriteFileFlag( 84 | _In_ PFLT_CALLBACK_DATA Data, 85 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 86 | _In_ PFILE_OBJECT FileObject, 87 | _In_ PSTREAM_CONTEXT pStreamCtx 88 | ); 89 | 90 | 91 | NTSTATUS 92 | File_ReadFileFlag( 93 | _In_ PFLT_CALLBACK_DATA Data, 94 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 95 | _In_ PVOID Buffer 96 | ); 97 | 98 | 99 | NTSTATUS 100 | File_InitFileFlag(); 101 | 102 | NTSTATUS 103 | File_UninitFileFlag(); 104 | 105 | extern PFILE_FLAG g_pFileFlag; 106 | 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /engine/instance.c: -------------------------------------------------------------------------------- 1 | #include "engine.h" 2 | 3 | NTSTATUS 4 | engineInstanceSetup( 5 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 6 | _In_ FLT_INSTANCE_SETUP_FLAGS Flags, 7 | _In_ DEVICE_TYPE VolumeDeviceType, 8 | _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType 9 | ) 10 | /*++ 11 | 12 | Routine Description: 13 | 14 | This routine is called whenever a new instance is created on a volume. This 15 | gives us a chance to decide if we need to attach to this volume or not. 16 | 17 | If this routine is not defined in the registration structure, automatic 18 | instances are always created. 19 | 20 | Arguments: 21 | 22 | FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing 23 | opaque handles to this filter, instance and its associated volume. 24 | 25 | Flags - Flags describing the reason for this attach request. 26 | 27 | Return Value: 28 | 29 | STATUS_SUCCESS - attach 30 | STATUS_FLT_DO_NOT_ATTACH - do not attach 31 | 32 | --*/ 33 | { 34 | UNREFERENCED_PARAMETER(FltObjects); 35 | UNREFERENCED_PARAMETER(Flags); 36 | UNREFERENCED_PARAMETER(VolumeDeviceType); 37 | UNREFERENCED_PARAMETER(VolumeFilesystemType); 38 | 39 | PAGED_CODE(); 40 | 41 | PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, 42 | ("engine!engineInstanceSetup: Entered\n")); 43 | 44 | return STATUS_SUCCESS; 45 | } 46 | 47 | 48 | NTSTATUS 49 | engineInstanceQueryTeardown( 50 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 51 | _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags 52 | ) 53 | /*++ 54 | 55 | Routine Description: 56 | 57 | This is called when an instance is being manually deleted by a 58 | call to FltDetachVolume or FilterDetach thereby giving us a 59 | chance to fail that detach request. 60 | 61 | If this routine is not defined in the registration structure, explicit 62 | detach requests via FltDetachVolume or FilterDetach will always be 63 | failed. 64 | 65 | Arguments: 66 | 67 | FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing 68 | opaque handles to this filter, instance and its associated volume. 69 | 70 | Flags - Indicating where this detach request came from. 71 | 72 | Return Value: 73 | 74 | Returns the status of this operation. 75 | 76 | --*/ 77 | { 78 | UNREFERENCED_PARAMETER(FltObjects); 79 | UNREFERENCED_PARAMETER(Flags); 80 | 81 | PAGED_CODE(); 82 | 83 | PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, 84 | ("engine!engineInstanceQueryTeardown: Entered\n")); 85 | 86 | return STATUS_SUCCESS; 87 | } 88 | 89 | 90 | VOID 91 | engineInstanceTeardownStart( 92 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 93 | _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags 94 | ) 95 | /*++ 96 | 97 | Routine Description: 98 | 99 | This routine is called at the start of instance teardown. 100 | 101 | Arguments: 102 | 103 | FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing 104 | opaque handles to this filter, instance and its associated volume. 105 | 106 | Flags - Reason why this instance is being deleted. 107 | 108 | Return Value: 109 | 110 | None. 111 | 112 | --*/ 113 | { 114 | UNREFERENCED_PARAMETER(FltObjects); 115 | UNREFERENCED_PARAMETER(Flags); 116 | 117 | PAGED_CODE(); 118 | 119 | PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, 120 | ("engine!engineInstanceTeardownStart: Entered\n")); 121 | } 122 | 123 | 124 | VOID 125 | engineInstanceTeardownComplete( 126 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 127 | _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags 128 | ) 129 | /*++ 130 | 131 | Routine Description: 132 | 133 | This routine is called at the end of instance teardown. 134 | 135 | Arguments: 136 | 137 | FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing 138 | opaque handles to this filter, instance and its associated volume. 139 | 140 | Flags - Reason why this instance is being deleted. 141 | 142 | Return Value: 143 | 144 | None. 145 | 146 | --*/ 147 | { 148 | UNREFERENCED_PARAMETER(FltObjects); 149 | UNREFERENCED_PARAMETER(Flags); 150 | 151 | PAGED_CODE(); 152 | 153 | PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, 154 | ("engine!engineInstanceTeardownComplete: Entered\n")); 155 | } 156 | -------------------------------------------------------------------------------- /engine/queryinfo.c: -------------------------------------------------------------------------------- 1 | #include "CallbackRoutines.h" 2 | 3 | FLT_PREOP_CALLBACK_STATUS 4 | PreQueryInfo( 5 | _Inout_ PFLT_CALLBACK_DATA Data, 6 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 7 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 8 | ) 9 | { 10 | 11 | } 12 | 13 | FLT_POSTOP_CALLBACK_STATUS 14 | PostQueryInfo( 15 | _Inout_ PFLT_CALLBACK_DATA Data, 16 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 17 | _In_ PVOID CompletionContext, 18 | _In_ FLT_POST_OPERATION_FLAGS Flags 19 | ) 20 | { 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /engine/read.c: -------------------------------------------------------------------------------- 1 | #include "CallbackRoutines.h" 2 | 3 | 4 | FLT_PREOP_CALLBACK_STATUS 5 | PreRead( 6 | _Inout_ PFLT_CALLBACK_DATA Data, 7 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 8 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 9 | ) 10 | { 11 | 12 | } 13 | 14 | 15 | FLT_POSTOP_CALLBACK_STATUS 16 | PostRead( 17 | _Inout_ PFLT_CALLBACK_DATA Data, 18 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 19 | _In_ PVOID CompletionContext, 20 | _In_ FLT_POST_OPERATION_FLAGS Flags 21 | ) 22 | { 23 | 24 | } 25 | 26 | FLT_POSTOP_CALLBACK_STATUS 27 | SwapPostReadBuffersWhenSafe( 28 | _Inout_ PFLT_CALLBACK_DATA Data, 29 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 30 | _In_ PVOID CompletionContext, 31 | _In_ FLT_POST_OPERATION_FLAGS Flags 32 | ) 33 | { 34 | 35 | } -------------------------------------------------------------------------------- /engine/setinfo.c: -------------------------------------------------------------------------------- 1 | #include "CallbackRoutines.h" 2 | 3 | FLT_PREOP_CALLBACK_STATUS 4 | PreSetInfo( 5 | _Inout_ PFLT_CALLBACK_DATA Data, 6 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 7 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 8 | ) 9 | { 10 | 11 | } 12 | 13 | 14 | FLT_POSTOP_CALLBACK_STATUS 15 | PostSetInfo( 16 | _Inout_ PFLT_CALLBACK_DATA Data, 17 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 18 | _In_ PVOID CompletionContext, 19 | _In_ FLT_POST_OPERATION_FLAGS Flags 20 | ) 21 | { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /engine/write.c: -------------------------------------------------------------------------------- 1 | #include "CallbackRoutines.h" 2 | 3 | 4 | FLT_PREOP_CALLBACK_STATUS 5 | PreWrite( 6 | _Inout_ PFLT_CALLBACK_DATA Data, 7 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 8 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 9 | ) 10 | { 11 | 12 | } 13 | 14 | FLT_POSTOP_CALLBACK_STATUS 15 | PostWrite( 16 | _Inout_ PFLT_CALLBACK_DATA Data, 17 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 18 | _In_ PVOID CompletionContext, 19 | _In_ FLT_POST_OPERATION_FLAGS Flags 20 | ) 21 | { 22 | 23 | } 24 | --------------------------------------------------------------------------------