1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
/*++
Copyright (c) 1989-2011 Microsoft Corporation
Module Name:
avscan.h
Abstract:
Header file which contains the structures, type definitions,
constants, global variables and function prototypes that are
only visible within the kernel. Mainly used by avscan module.
Environment:
Kernel mode
--*/
#ifndef __AVSCAN_H__
#define __AVSCAN_H__
#ifndef RTL_USE_AVL_TABLES
#define RTL_USE_AVL_TABLES
#endif // RTL_USE_AVL_TABLES
#define AV_VISTA (NTDDI_VERSION >= NTDDI_VISTA)
#include <fltKernel.h>
#include <dontuse.h>
#include <suppress.h>
#include "utility.h"
#include "context.h"
#include "scan.h"
#include "csvfs.h"
#include "avlib.h"
#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")
//
// Scan context.
//
// We chose to seperate scan context and section context to have one struct per concept.
// The I/O request thread does not need to know how scanner implement the scan, so
// that the I/O request thread has less coupling with scanner threads.
//
// You can also put all of fields of the scan context into a section context, and allocate
// section context at the place of allocation of scan context.
//
typedef struct _AV_SCAN_CONTEXT {
LONG RefCount;
PFLT_INSTANCE FilterInstance;
PFILE_OBJECT FileObject;
KEVENT ScanCompleteNotification;
LIST_ENTRY List;
PAV_SECTION_CONTEXT SectionContext;
LONGLONG ScanId;
ULONG ScanThreadId;
UCHAR IOMajorFunctionAtScan;
BOOLEAN IsFileInTxWriter;
BOOLEAN IoWaitOnScanCompleteNotificationAborted;
} AV_SCAN_CONTEXT, *PAV_SCAN_CONTEXT;
//
// The global variable
//
typedef struct _AV_SCANNER_GLOBAL_DATA {
//
// A counter for Scan Id
//
LONGLONG ScanIdCounter;
//
// The global FLT_FILTER pointer. Many API needs this, such as
// FltAllocateContext(...)
//
PFLT_FILTER Filter;
//
// Server-side communicate ports.
//
PFLT_PORT ScanServerPort;
PFLT_PORT AbortServerPort;
PFLT_PORT QueryServerPort;
//
// The scan client ports.
// These ports are assigned at AvConnectNotifyCallback and cleaned at AvDisconnectNotifyCallback
//
// ScanClientPort is the connection port regarding the scan message.
// AbortClientPort is the connection port regarding the abort message.
// QueryClient is the connection port regarding the query command.
//
PFLT_PORT ScanClientPort;
PFLT_PORT AbortClientPort;
PFLT_PORT QueryClientPort;
//
// Scan context list head.
// At AvMessageNotifyCallback, when user passes ScanCtxId, we
// have to check the validity of the id by checking this list.
//
LIST_ENTRY ScanCtxListHead;
//
// The lock that synchronizes the accesses of the scan context list above.
//
ERESOURCE ScanCtxListLock;
//
// Timeout for local file scans in milliseconds
//
LONGLONG LocalScanTimeout;
//
// Timeout for network file scans in milliseconds
//
LONGLONG NetworkScanTimeout;
#if DBG
//
// Field to control nature of debug output
//
ULONG DebugLevel;
#endif
//
// A flag that indicating that the filter is being unloaded.
//
BOOLEAN Unloading;
} AV_SCANNER_GLOBAL_DATA, *PAV_SCANNER_GLOBAL_DATA;
AV_SCANNER_GLOBAL_DATA Globals;
#if DBG
//
// Debugging level flags.
//
#define AVDBG_TRACE_ROUTINES 0x00000001
#define AVDBG_TRACE_OPERATION_STATUS 0x00000002
#define AVDBG_TRACE_DEBUG 0x00000004
#define AVDBG_TRACE_ERROR 0x00000008
#define AV_DBG_PRINT( _dbgLevel, _string ) \
if(FlagOn(Globals.DebugLevel,(_dbgLevel))) { \
DbgPrint _string; \
}
#else
#define AV_DBG_PRINT(_dbgLevel, _string) {NOTHING;}
#endif
FORCEINLINE
VOID
AvCancelFileOpen(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_ NTSTATUS Status
)
/*++
Routine Description:
This function cancel the file open. This is supposed to be called at post create if
the I/O is cancelled.
Arguments:
Data - Pointer to the filter callbackData that is passed to us.
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance, its associated volume and
file object.
Status - The status code to be returned for this IRP.
Return Value:
None.
--*/
{
FltCancelFileOpen( FltObjects->Instance, FltObjects->FileObject );
Data->IoStatus.Status = Status;
Data->IoStatus.Information = 0;
}
NTSTATUS
AvPrepareServerPort(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ AVSCAN_CONNECTION_TYPE ConnectionType
);
NTSTATUS
AvSendAbortToUser (
_In_ ULONG ScanThreadId,
_In_ LONGLONG ScanId
);
NTSTATUS
AvAllocateScanContext(
_In_ PFLT_INSTANCE Instance,
_In_ PFILE_OBJECT FileObject,
_Outptr_ PAV_SCAN_CONTEXT *ScanContext
);
NTSTATUS
AvReferenceScanContext(
_In_ PAV_SCAN_CONTEXT ScanContext
);
NTSTATUS
AvReleaseScanContext(
_In_ PAV_SCAN_CONTEXT ScanContext
);
//
// Fianlize function for scan context and section context.
// Wrapper functions of synchronization calling sequences.
// In the normal cases, the caller should call AvFinalizeScanAndSection
// when it finishes using it.
//
// Unless the caller wants to do things about section context inside scan context,
// then it should call AvFinalizeScanContext(), and followed by
// AvFinalizeSectionContext()
//
// These wrappers are designed to make the synchronization easier.
//
NTSTATUS
AvFinalizeScanAndSection (
_Inout_ PAV_SCAN_CONTEXT ScanContext
);
NTSTATUS
AvFinalizeSectionContext (
_Inout_ PAV_SECTION_CONTEXT SectionContext
);
VOID
AvFinalizeScanContext (
_Inout_ PAV_SCAN_CONTEXT ScanContext,
_Outptr_result_maybenull_ PAV_SECTION_CONTEXT *SectionContext
);
#endif
|