+TcIsThereDirtyData()
[captive.git] / src / TraceFS / TraceFS-W32 / TraceFS.c
1 /* $Id$\r
2  * Debugging tracer of IRPs and Cc* (Cache Manager) calls for W32\r
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>\r
4  * \r
5  * This program is free software; you can redistribute it and/or modify\r
6  * it under the terms of the GNU General Public License as published by\r
7  * the Free Software Foundation; exactly version 2 of June 1991 is required\r
8  * \r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  * \r
14  * You should have received a copy of the GNU General Public License\r
15  * along with this program; if not, write to the Free Software\r
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
17  */\r
18 \r
19 #include <ntddk.h>\r
20 \r
21 \r
22 #define CACHE_SIZE 0x200\r
23 \r
24 \r
25 #define G_N_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0]))\r
26 \r
27 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath);\r
28 \r
29 #ifdef ALLOC_PRAGMA\r
30 #pragma alloc_text (INIT, DriverEntry)\r
31 #endif\r
32 \r
33 /* Ke*Mutex() would be reentrant but it looked too unclear for me.\r
34  * Never ExAcquireFastMutex() two FAST_MUTEX once or one FAST_MUTEX twice.\r
35  * Use Ex*ResourceLite instead of Ex*FastMutex() as it would set IRQL to DPC\r
36  * and we cannot pass the execution to Cc*() in DPC.\r
37  * Ex*FastMutex() problem: IRP_MJ_SHUTDOWN: Assertion failure.\r
38  */\r
39 static ERESOURCE lock_resource;\r
40 static int lock_resource_count;\r
41 static PETHREAD lock_resource_CurrentThread;\r
42 \r
43 static void lock_init(void)\r
44 {\r
45         if (ExInitializeResourceLite(&lock_resource))\r
46                 KeBugCheck(0);\r
47         lock_resource_count=0;\r
48         lock_resource_CurrentThread=NULL;\r
49 }\r
50 \r
51 static void lock(void)\r
52 {\r
53         if (lock_resource_CurrentThread==PsGetCurrentThread()) {\r
54                 if (lock_resource_count<=0)\r
55                         KeBugCheck(0);\r
56                 lock_resource_count++;\r
57                 return;\r
58                 }\r
59         KeEnterCriticalRegion();\r
60         if (!ExAcquireResourceExclusiveLite(&lock_resource,TRUE))\r
61                 KeBugCheck(0);\r
62         KeLeaveCriticalRegion();\r
63         if (lock_resource_CurrentThread)\r
64                 KeBugCheck(0);\r
65         if (lock_resource_count)\r
66                 KeBugCheck(0);\r
67         lock_resource_CurrentThread=PsGetCurrentThread();\r
68         lock_resource_count++;\r
69 }\r
70 \r
71 /* We need to _fully_ release the lock if we are passing the control to\r
72  * callback functions. Single unlock() would free us from our current 'enter:'\r
73  * lock but another lock() from Cc*() function which called us would be held.\r
74  * FIXME: Enable of file compression still hangs in CcFlushCache().\r
75  */\r
76 static void lock_full(int n)\r
77 {\r
78         if (n<=0)\r
79                 KeBugCheck(0);\r
80         if (lock_resource_CurrentThread==PsGetCurrentThread())\r
81                 KeBugCheck(0);\r
82         KeEnterCriticalRegion();\r
83         if (!ExAcquireResourceExclusiveLite(&lock_resource,TRUE))\r
84                 KeBugCheck(0);\r
85         KeLeaveCriticalRegion();\r
86         if (lock_resource_CurrentThread)\r
87                 KeBugCheck(0);\r
88         if (lock_resource_count)\r
89                 KeBugCheck(0);\r
90         lock_resource_CurrentThread=PsGetCurrentThread();\r
91         lock_resource_count+=n;\r
92 }\r
93 \r
94 static void unlock(void)\r
95 {\r
96         if (lock_resource_CurrentThread!=PsGetCurrentThread())\r
97                 KeBugCheck(0);\r
98         if (lock_resource_count<=0)\r
99                 KeBugCheck(0);\r
100         if (--lock_resource_count)\r
101                 return;\r
102         lock_resource_CurrentThread=NULL;\r
103         KeEnterCriticalRegion();\r
104         ExReleaseResourceLite(&lock_resource);\r
105         KeLeaveCriticalRegion();\r
106 }\r
107 \r
108 static int unlock_full(void)\r
109 {\r
110 int r;\r
111 \r
112         if (lock_resource_CurrentThread!=PsGetCurrentThread())\r
113                 KeBugCheck(0);\r
114         if (lock_resource_count<=0)\r
115                 KeBugCheck(0);\r
116         r=lock_resource_count;\r
117         lock_resource_count=0;\r
118         lock_resource_CurrentThread=NULL;\r
119         KeEnterCriticalRegion();\r
120         ExReleaseResourceLite(&lock_resource);\r
121         KeLeaveCriticalRegion();\r
122         return r;\r
123 }\r
124 \r
125 #define DBGPREFIX "TraceFS(0x%08lX/0x%08lX): "\r
126 #define DBGARG PsGetCurrentProcess(),PsGetCurrentThread()\r
127 \r
128 static int dbgindent=0;\r
129 \r
130 /* DBGSINGLEENTER*() / DBGSINGLELEAVE*() are protected by lock()/unlock()\r
131  * to serialize the Cc*() function calls as otherwise the debug dumps\r
132  * chronology may not match the real core execution chronology inside.\r
133  */\r
134 \r
135 /* lock() will protect dbg_unicode_string() static buffer. */\r
136 #define DBGSINGLE6(fmt,arg1,arg2,arg3,arg4,arg5,arg6) \\r
137                 do { lock(); DbgPrint("%*s" DBGPREFIX fmt "\n",dbgindent,"",DBGARG,arg1,arg2,arg3,arg4,arg5,arg6); unlock(); } while (0)\r
138 #define DBGSINGLE5(fmt,arg1,arg2,arg3,arg4,arg5) DBGSINGLE6(fmt,arg1,arg2,arg3,arg4,arg5,0)\r
139 #define DBGSINGLE4(fmt,arg1,arg2,arg3,arg4)      DBGSINGLE5(fmt,arg1,arg2,arg3,arg4,0)\r
140 #define DBGSINGLE3(fmt,arg1,arg2,arg3)           DBGSINGLE4(fmt,arg1,arg2,arg3,0)\r
141 #define DBGSINGLE2(fmt,arg1,arg2)                DBGSINGLE3(fmt,arg1,arg2,0)\r
142 #define DBGSINGLE1(fmt,arg1)                     DBGSINGLE2(fmt,arg1,0)\r
143 #define DBGSINGLE0(fmt)                          DBGSINGLE1(fmt,0)\r
144 #define DBGSINGLEENTER6(fmt,arg1,arg2,arg3,arg4,arg5,arg6) \\r
145                 do { lock(); DBGSINGLE6("enter: " fmt,arg1,arg2,arg3,arg4,arg5,arg6); dbgindent++; } while (0)\r
146 #define DBGSINGLEENTER5(fmt,arg1,arg2,arg3,arg4,arg5) DBGSINGLEENTER6(fmt,arg1,arg2,arg3,arg4,arg5,0)\r
147 #define DBGSINGLEENTER4(fmt,arg1,arg2,arg3,arg4)      DBGSINGLEENTER5(fmt,arg1,arg2,arg3,arg4,0)\r
148 #define DBGSINGLEENTER3(fmt,arg1,arg2,arg3)           DBGSINGLEENTER4(fmt,arg1,arg2,arg3,0)\r
149 #define DBGSINGLEENTER2(fmt,arg1,arg2)                DBGSINGLEENTER3(fmt,arg1,arg2,0)\r
150 #define DBGSINGLEENTER1(fmt,arg1)                     DBGSINGLEENTER2(fmt,arg1,0)\r
151 #define DBGSINGLEENTER0(fmt)                          DBGSINGLEENTER1(fmt,0)\r
152 #define DBGSINGLELEAVE3(fmt,arg1,arg2,arg3) \\r
153                 do { dbgindent--; DBGSINGLE3("leave: " fmt,arg1,arg2,arg3); unlock(); } while (0)\r
154 #define DBGSINGLELEAVE2(fmt,arg1,arg2) DBGSINGLELEAVE3(fmt,arg1,arg2,0)\r
155 #define DBGSINGLELEAVE1(fmt,arg1)      DBGSINGLELEAVE2(fmt,arg1,0)\r
156 #define DBGSINGLELEAVE0(fmt)           DBGSINGLELEAVE1(fmt,0)\r
157 \r
158 \r
159 /* We cannot use DbgPrint("%wZ",...) as it must have IRQL PASSIVE_LEVEL which\r
160  * is not satisfied.\r
161  */\r
162 static const char *dbg_unicode_string(UNICODE_STRING *unicode_string)\r
163 {\r
164 static char buf[0x100];\r
165 char *d;\r
166 PWSTR s;\r
167 \r
168         if (!unicode_string || !unicode_string->Buffer)\r
169                 return "NULL";\r
170         d=buf;\r
171         *d++='\'';\r
172         for (s=unicode_string->Buffer;s<unicode_string->Buffer+(unicode_string->Length/2);s++) {\r
173                 if (d>=buf+sizeof(buf)-4)\r
174                         break;\r
175                 *d++=(char)*s;\r
176                 }\r
177         *d++='\'';\r
178         *d=0;\r
179         return buf;\r
180 }\r
181 \r
182 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)\r
183 {\r
184 NTSTATUS r;\r
185 DEVICE_OBJECT *device_object;\r
186 \r
187         lock_init();\r
188 \r
189         DBGSINGLEENTER1("DriverEntry: RegistryPath=%s",dbg_unicode_string(RegistryPath));\r
190         DBGSINGLE1("DriverEntry: %s","$Id$");\r
191         r=IoCreateDevice(\r
192                         DriverObject,   /* DriverObject */\r
193                         0,      /* DeviceExtensionSize */\r
194                         NULL,   /* DeviceName; optional */\r
195                         FILE_DEVICE_UNKNOWN,    /* DeviceType */\r
196                         0,      /* DeviceCharacteristics */\r
197                         FALSE,  /* Exclusive */\r
198                         &device_object);        /* DeviceObject */\r
199         DBGSINGLELEAVE1("DriverEntry: r=0x%lX",(long)r);\r
200         return r;\r
201 }\r
202 \r
203 static const char *const dump_irp_mj_FILE_SYSTEM_CONTROL_MinorFunction_names[]={\r
204                 "IRP_MN_USER_FS_REQUEST",\r
205                 "IRP_MN_MOUNT_VOLUME",\r
206                 "IRP_MN_VERIFY_VOLUME",\r
207                 "IRP_MN_LOAD_FILE_SYSTEM",\r
208                 "IRP_MN_KERNEL_CALL",\r
209                 };\r
210 \r
211 /* Compatibility with DDK; the structures match. */\r
212 #define FileSystemControl DeviceIoControl\r
213 #define FsControlCode IoControlCode\r
214 #ifndef FSCTL_REQUEST_BATCH_OPLOCK\r
215 #define FSCTL_REQUEST_BATCH_OPLOCK CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2,METHOD_BUFFERED,FILE_ANY_ACCESS)\r
216 #endif\r
217 #ifndef FSCTL_LOCK_VOLUME\r
218 #define FSCTL_LOCK_VOLUME          CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6,METHOD_BUFFERED,FILE_ANY_ACCESS)\r
219 #endif\r
220 #ifndef FSCTL_UNLOCK_VOLUME\r
221 #define FSCTL_UNLOCK_VOLUME        CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 7,METHOD_BUFFERED,FILE_ANY_ACCESS)\r
222 #endif\r
223 #ifndef FSCTL_DISMOUNT_VOLUME\r
224 #define FSCTL_DISMOUNT_VOLUME      CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8,METHOD_BUFFERED,FILE_ANY_ACCESS)\r
225 #endif\r
226 #ifndef FSCTL_MARK_VOLUME_DIRTY\r
227 #define FSCTL_MARK_VOLUME_DIRTY    CTL_CODE(FILE_DEVICE_FILE_SYSTEM,12,METHOD_BUFFERED,FILE_ANY_ACCESS)\r
228 #endif\r
229 #ifndef FSCTL_SET_COMPRESSION\r
230 #define FSCTL_SET_COMPRESSION      CTL_CODE(FILE_DEVICE_FILE_SYSTEM,16,METHOD_BUFFERED,FILE_READ_DATA|FILE_WRITE_DATA)\r
231 #endif\r
232 #ifndef FSCTL_INVALIDATE_VOLUMES\r
233 #define FSCTL_INVALIDATE_VOLUMES   CTL_CODE(FILE_DEVICE_FILE_SYSTEM,21,METHOD_BUFFERED,FILE_ANY_ACCESS)\r
234 #endif\r
235 #ifndef FSCTL_IS_VOLUME_DIRTY\r
236 #define FSCTL_IS_VOLUME_DIRTY      CTL_CODE(FILE_DEVICE_FILE_SYSTEM,30,METHOD_BUFFERED,FILE_ANY_ACCESS)\r
237 #endif\r
238 #ifndef FSCTL_FILE_PREFETCH\r
239 #define FSCTL_FILE_PREFETCH        CTL_CODE(FILE_DEVICE_FILE_SYSTEM,72,METHOD_BUFFERED,FILE_SPECIAL_ACCESS)\r
240 #endif\r
241 \r
242 static struct SectionObjectPointer {\r
243                 FILE_OBJECT *FileObject;\r
244                 PVOID SharedCacheMap;\r
245                 } SectionObjectPointer_cache[CACHE_SIZE];\r
246 static int SectionObjectPointer_cache_used=0;\r
247 \r
248 static struct SectionObjectPointer *SectionObjectPointer_set(FILE_OBJECT *FileObject)\r
249 {\r
250 struct SectionObjectPointer *sopp;\r
251 PVOID SharedCacheMap;\r
252 \r
253         if (!FileObject->SectionObjectPointer)\r
254                 return NULL;\r
255         if (!(SharedCacheMap=FileObject->SectionObjectPointer->SharedCacheMap))\r
256                 return NULL;\r
257         for (sopp=SectionObjectPointer_cache;sopp<SectionObjectPointer_cache+SectionObjectPointer_cache_used;sopp++) {\r
258                 if (sopp->FileObject==FileObject || sopp->SharedCacheMap==SharedCacheMap)\r
259                         break;\r
260                 }\r
261         if (sopp>=SectionObjectPointer_cache+G_N_ELEMENTS(SectionObjectPointer_cache))\r
262                 return NULL;\r
263         if (sopp==SectionObjectPointer_cache+SectionObjectPointer_cache_used)\r
264                 SectionObjectPointer_cache_used++;\r
265         sopp->FileObject=FileObject;\r
266         sopp->SharedCacheMap=SharedCacheMap;\r
267         return sopp;\r
268 }\r
269 \r
270 static FILE_OBJECT *SectionObjectPointer_find(SECTION_OBJECT_POINTERS *SectionObjectPointer)\r
271 {\r
272 struct SectionObjectPointer *sopp;\r
273 PVOID SharedCacheMap;\r
274 \r
275         if (!SectionObjectPointer)\r
276                 return NULL;\r
277         if (!(SharedCacheMap=SectionObjectPointer->SharedCacheMap))\r
278                 return NULL;\r
279         for (sopp=SectionObjectPointer_cache;sopp<SectionObjectPointer_cache+SectionObjectPointer_cache_used;sopp++) {\r
280                 if (sopp->SharedCacheMap==SharedCacheMap)\r
281                         return sopp->FileObject;\r
282                 }\r
283         return NULL;\r
284 }\r
285 \r
286 static void dump_FileObject(FILE_OBJECT *FileObject)\r
287 {\r
288         if (!FileObject) {\r
289                 DBGSINGLE0("FileObject=NULL");\r
290                 return;\r
291                 }\r
292         DBGSINGLE5("FileObject=0x%lX: FileName=%s,Flags=0x%lX,SectionObjectPointer=0x%lX,->SharedCacheMap=0x%lX",\r
293                         (long)FileObject,\r
294                         dbg_unicode_string(&FileObject->FileName),FileObject->Flags,\r
295                         (long)FileObject->SectionObjectPointer,\r
296                         (!FileObject->SectionObjectPointer ? -1 : (long)FileObject->SectionObjectPointer->SharedCacheMap));\r
297         SectionObjectPointer_set(FileObject);\r
298 }\r
299 \r
300 static FILE_OBJECT *dump_irp_mj(struct _DEVICE_OBJECT *DeviceObject,struct _IRP *Irp)\r
301 {\r
302 IO_STACK_LOCATION *IoStackLocation;\r
303 FILE_OBJECT *FileObject;\r
304 \r
305         if (!Irp) {\r
306                 DBGSINGLE0("Irp==NULL");\r
307                 return NULL;\r
308                 }\r
309         IoStackLocation=IoGetCurrentIrpStackLocation(Irp);\r
310         if (!IoStackLocation) {\r
311                 DBGSINGLE0("IoStackLocation==NULL");\r
312                 return NULL;\r
313                 }\r
314         FileObject=IoStackLocation->FileObject;\r
315         dump_FileObject(FileObject);\r
316         \r
317         switch (IoStackLocation->MajorFunction) {\r
318                 case IRP_MJ_READ:\r
319                         DBGSINGLE2("READ: ByteOffset=0x%lX,Length=0x%lX",\r
320                                         (long)IoStackLocation->Parameters.Read.ByteOffset.QuadPart,\r
321                                         IoStackLocation->Parameters.Read.Length);\r
322                         break;\r
323                 case IRP_MJ_WRITE:\r
324                         DBGSINGLE2("WRITE: ByteOffset=0x%lX,Length=0x%lX",\r
325                                         (long)IoStackLocation->Parameters.Write.ByteOffset.QuadPart,\r
326                                         IoStackLocation->Parameters.Write.Length);\r
327                         break;\r
328                 case IRP_MJ_FILE_SYSTEM_CONTROL:\r
329                         DBGSINGLE2("FILE_SYSTEM_CONTROL: MinorFunction=%s (%0x%X)",\r
330                                         ((1\r
331                                                                         && IoStackLocation->MinorFunction>=0\r
332                                                                         && IoStackLocation->MinorFunction<G_N_ELEMENTS(dump_irp_mj_FILE_SYSTEM_CONTROL_MinorFunction_names))\r
333                                                         ? dump_irp_mj_FILE_SYSTEM_CONTROL_MinorFunction_names[IoStackLocation->MinorFunction] : "???"),\r
334                                         IoStackLocation->MinorFunction);\r
335                         switch (IoStackLocation->MinorFunction) {\r
336                                 case IRP_MN_USER_FS_REQUEST: {\r
337 const char *FsControlCode_name;\r
338                                         switch (IoStackLocation->Parameters.FileSystemControl.FsControlCode) {\r
339                                                 case FSCTL_REQUEST_BATCH_OPLOCK: FsControlCode_name="FSCTL_REQUEST_BATCH_OPLOCK"; break;\r
340                                                 case FSCTL_LOCK_VOLUME:          FsControlCode_name="FSCTL_LOCK_VOLUME";          break;\r
341                                                 case FSCTL_UNLOCK_VOLUME:        FsControlCode_name="FSCTL_UNLOCK_VOLUME";        break;\r
342                                                 case FSCTL_DISMOUNT_VOLUME:      FsControlCode_name="FSCTL_DISMOUNT_VOLUME";      break;\r
343                                                 case FSCTL_MARK_VOLUME_DIRTY:    FsControlCode_name="FSCTL_MARK_VOLUME_DIRTY";    break;\r
344                                                 case FSCTL_SET_COMPRESSION:      FsControlCode_name="FSCTL_SET_COMPRESSION";      break;\r
345                                                 case FSCTL_INVALIDATE_VOLUMES:   FsControlCode_name="FSCTL_INVALIDATE_VOLUMES";   break;\r
346                                                 case FSCTL_IS_VOLUME_DIRTY:      FsControlCode_name="FSCTL_IS_VOLUME_DIRTY";      break;\r
347                                                 case FSCTL_FILE_PREFETCH:        FsControlCode_name="FSCTL_FILE_PREFETCH";        break;\r
348                                                 default:                         FsControlCode_name="???";                        break;\r
349                                                 }\r
350                                         DBGSINGLE2("USER_FS_REQUEST: FsControlCode=%s (0x%X)",FsControlCode_name,\r
351                                                         IoStackLocation->Parameters.FileSystemControl.FsControlCode);\r
352                                         } break;\r
353                                 }\r
354                 }\r
355 \r
356         return FileObject;\r
357 }\r
358 \r
359 #define TRACEFS_MAJORS \\r
360                 TRACEFS_MAJOR(IRP_MJ_CREATE) \\r
361                 TRACEFS_MAJOR(IRP_MJ_CREATE_NAMED_PIPE) \\r
362                 TRACEFS_MAJOR(IRP_MJ_CLOSE) \\r
363                 TRACEFS_MAJOR(IRP_MJ_READ) \\r
364                 TRACEFS_MAJOR(IRP_MJ_WRITE) \\r
365                 TRACEFS_MAJOR(IRP_MJ_QUERY_INFORMATION) \\r
366                 TRACEFS_MAJOR(IRP_MJ_SET_INFORMATION) \\r
367                 TRACEFS_MAJOR(IRP_MJ_QUERY_EA) \\r
368                 TRACEFS_MAJOR(IRP_MJ_SET_EA) \\r
369                 TRACEFS_MAJOR(IRP_MJ_FLUSH_BUFFERS) \\r
370                 TRACEFS_MAJOR(IRP_MJ_QUERY_VOLUME_INFORMATION) \\r
371                 TRACEFS_MAJOR(IRP_MJ_SET_VOLUME_INFORMATION) \\r
372                 TRACEFS_MAJOR(IRP_MJ_DIRECTORY_CONTROL) \\r
373                 TRACEFS_MAJOR(IRP_MJ_FILE_SYSTEM_CONTROL) \\r
374                 TRACEFS_MAJOR(IRP_MJ_DEVICE_CONTROL) \\r
375                 TRACEFS_MAJOR(IRP_MJ_INTERNAL_DEVICE_CONTROL) \\r
376                 TRACEFS_MAJOR(IRP_MJ_SHUTDOWN) \\r
377                 TRACEFS_MAJOR(IRP_MJ_LOCK_CONTROL) \\r
378                 TRACEFS_MAJOR(IRP_MJ_CLEANUP) \\r
379                 TRACEFS_MAJOR(IRP_MJ_CREATE_MAILSLOT) \\r
380                 TRACEFS_MAJOR(IRP_MJ_QUERY_SECURITY) \\r
381                 TRACEFS_MAJOR(IRP_MJ_SET_SECURITY) \\r
382                 TRACEFS_MAJOR(IRP_MJ_POWER) \\r
383                 TRACEFS_MAJOR(IRP_MJ_SYSTEM_CONTROL) \\r
384                 TRACEFS_MAJOR(IRP_MJ_DEVICE_CHANGE) \\r
385                 TRACEFS_MAJOR(IRP_MJ_QUERY_QUOTA) \\r
386                 TRACEFS_MAJOR(IRP_MJ_SET_QUOTA) \\r
387                 TRACEFS_MAJOR(IRP_MJ_PNP)\r
388 \r
389 \r
390 #define TRACEFS_MAJOR(irp_mj_name) \\r
391 static NTSTATUS (*tracefs_major_##irp_mj_name##_orig)(IN struct _DEVICE_OBJECT *DeviceObject,IN struct _IRP *Irp); \\r
392 static NTSTATUS tracefs_major_##irp_mj_name(IN struct _DEVICE_OBJECT *DeviceObject,IN struct _IRP *Irp) \\r
393 { \\r
394 NTSTATUS r; \\r
395 int locked; \\r
396 FILE_OBJECT *FileObject; \\r
397  \\r
398         DBGSINGLEENTER0( #irp_mj_name ); \\r
399         FileObject=dump_irp_mj(DeviceObject,Irp); \\r
400         /* Prevent deadlock during display of File Explorer directory listing. \\r
401          * Needed at least for IRP_MJ_DIRECTORY_CONTROL and IRP_MJ_CLOSE. \\r
402          */ \\r
403         locked=unlock_full(); \\r
404         r=(*tracefs_major_##irp_mj_name##_orig)(DeviceObject,Irp); \\r
405         lock_full(locked); \\r
406         /* Dump_irp_mj() would crash here even now IRP_MJ_READ; \\r
407          * Invalid FileObject address gets detected. \\r
408          */ \\r
409         dump_FileObject(FileObject); \\r
410         DBGSINGLELEAVE1( #irp_mj_name ": r=0x%lX",(long)r); \\r
411         return r; \\r
412 }\r
413 \r
414 TRACEFS_MAJORS\r
415 \r
416 #undef TRACEFS_MAJOR\r
417 \r
418 \r
419 VOID IoRegisterFileSystem(IN OUT PDEVICE_OBJECT DeviceObject);\r
420 VOID ToRegisterFileSystem(IN OUT PDEVICE_OBJECT DeviceObject)\r
421 {\r
422         DBGSINGLEENTER0("IoRegisterFileSystem");\r
423 \r
424 #define TRACEFS_MAJOR(irp_mj_name) do { \\r
425                 tracefs_major_##irp_mj_name##_orig=DeviceObject->DriverObject->MajorFunction[irp_mj_name]; \\r
426                 DeviceObject->DriverObject->MajorFunction[irp_mj_name]=tracefs_major_##irp_mj_name; \\r
427                 } while (0);\r
428 \r
429 TRACEFS_MAJORS\r
430 \r
431 #undef TRACEFS_MAJOR\r
432 \r
433         IoRegisterFileSystem(DeviceObject);\r
434         DBGSINGLELEAVE0("IoRegisterFileSystem");\r
435 }\r
436 \r
437 \r
438 static char PsCreateSystemThread_bogusthread;\r
439 \r
440 NTSTATUS TsCreateSystemThread(\r
441     OUT PHANDLE ThreadHandle,\r
442     IN ULONG DesiredAccess,\r
443     IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\r
444     IN HANDLE ProcessHandle OPTIONAL,\r
445     OUT PCLIENT_ID ClientId OPTIONAL,\r
446     IN PKSTART_ROUTINE StartRoutine,\r
447     IN PVOID StartContext\r
448     )\r
449 {\r
450         DBGSINGLEENTER1("PsCreateSystemThread: StartRoutine=0x%lX",(long)StartRoutine);\r
451         if (ThreadHandle)\r
452                 *ThreadHandle=(HANDLE)&PsCreateSystemThread_bogusthread;\r
453         DBGSINGLELEAVE0("PsCreateSystemThread");\r
454         return STATUS_SUCCESS;\r
455 }\r
456 \r
457 NTSTATUS\r
458 NTAPI\r
459 TwClose(\r
460     IN HANDLE Handle\r
461     )\r
462 {\r
463         DBGSINGLEENTER0("ZwClose");\r
464         if (Handle==(HANDLE)&PsCreateSystemThread_bogusthread) {\r
465                 DBGSINGLELEAVE0("ZwClose: bogusthread catched");\r
466                 return STATUS_SUCCESS;\r
467                 }\r
468         DBGSINGLELEAVE0("ZwClose: passed");\r
469         return ZwClose(Handle);\r
470 }\r
471 \r
472 \r
473 BOOLEAN\r
474 CcCanIWrite (\r
475     IN PFILE_OBJECT FileObject,\r
476     IN ULONG BytesToWrite,\r
477     IN BOOLEAN Wait,\r
478     IN BOOLEAN Retrying\r
479     );\r
480 BOOLEAN\r
481 TcCanIWrite (\r
482     IN PFILE_OBJECT FileObject,\r
483     IN ULONG BytesToWrite,\r
484     IN BOOLEAN Wait,\r
485     IN BOOLEAN Retrying\r
486     )\r
487 {\r
488 BOOLEAN r;\r
489 \r
490         DBGSINGLEENTER4("CcCanIWrite: FileObject=0x%lX,BytesToWrite=0x%lX,Wait=%d,Retrying=%d",\r
491                         (long)FileObject,BytesToWrite,Wait,Retrying);\r
492         dump_FileObject(FileObject);\r
493         r=CcCanIWrite (\r
494 FileObject,\r
495 BytesToWrite,\r
496 Wait,\r
497 Retrying\r
498     );\r
499         DBGSINGLELEAVE1("CcCanIWrite: r=%d",r);\r
500         return r;\r
501 }\r
502 \r
503 BOOLEAN\r
504 CcCopyRead (\r
505     IN PFILE_OBJECT FileObject,\r
506     IN PLARGE_INTEGER FileOffset,\r
507     IN ULONG Length,\r
508     IN BOOLEAN Wait,\r
509     OUT PVOID Buffer,\r
510     OUT PIO_STATUS_BLOCK IoStatus\r
511     );\r
512 BOOLEAN\r
513 TcCopyRead (\r
514     IN PFILE_OBJECT FileObject,\r
515     IN PLARGE_INTEGER FileOffset,\r
516     IN ULONG Length,\r
517     IN BOOLEAN Wait,\r
518     OUT PVOID Buffer,\r
519     OUT PIO_STATUS_BLOCK IoStatus\r
520     )\r
521 {\r
522 BOOLEAN r;\r
523 \r
524         DBGSINGLEENTER5("CcCopyRead: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Wait=%d,Buffer=0x%lX",\r
525                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Wait,(long)Buffer);\r
526         dump_FileObject(FileObject);\r
527         r=CcCopyRead (\r
528 FileObject,\r
529 FileOffset,\r
530 Length,\r
531 Wait,\r
532 Buffer,\r
533 IoStatus\r
534     );\r
535         DBGSINGLELEAVE3("CcCopyRead: r=%d,IoStatus->Status=0x%lX,IoStatus->Information=0x%lX",\r
536                         r,(!IoStatus ? -1 : (long)IoStatus->Status),(!IoStatus ? -1 : (long)IoStatus->Information));\r
537         return r;\r
538 }\r
539 \r
540 BOOLEAN\r
541 CcCopyWrite (\r
542     IN PFILE_OBJECT FileObject,\r
543     IN PLARGE_INTEGER FileOffset,\r
544     IN ULONG Length,\r
545     IN BOOLEAN Wait,\r
546     IN PVOID Buffer\r
547     );\r
548 BOOLEAN\r
549 TcCopyWrite (\r
550     IN PFILE_OBJECT FileObject,\r
551     IN PLARGE_INTEGER FileOffset,\r
552     IN ULONG Length,\r
553     IN BOOLEAN Wait,\r
554     IN PVOID Buffer\r
555     )\r
556 {\r
557 BOOLEAN r;\r
558 \r
559         DBGSINGLEENTER5("CcCopyWrite: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Wait=%d,Buffer=0x%lX",\r
560                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Wait,(long)Buffer);\r
561         dump_FileObject(FileObject);\r
562         r=CcCopyWrite (\r
563 FileObject,\r
564 FileOffset,\r
565 Length,\r
566 Wait,\r
567 Buffer\r
568     );\r
569         DBGSINGLELEAVE1("CcCopyWrite: r=%d",r);\r
570         return r;\r
571 }\r
572 \r
573 typedef\r
574 VOID (*PCC_POST_DEFERRED_WRITE) (\r
575     IN PVOID Context1,\r
576     IN PVOID Context2\r
577     );\r
578 VOID\r
579 CcDeferWrite (\r
580     IN PFILE_OBJECT FileObject,\r
581     IN PCC_POST_DEFERRED_WRITE PostRoutine,\r
582     IN PVOID Context1,\r
583     IN PVOID Context2,\r
584     IN ULONG BytesToWrite,\r
585     IN BOOLEAN Retrying\r
586     );\r
587 TcDeferWrite (\r
588     IN PFILE_OBJECT FileObject,\r
589     IN PCC_POST_DEFERRED_WRITE PostRoutine,\r
590     IN PVOID Context1,\r
591     IN PVOID Context2,\r
592     IN ULONG BytesToWrite,\r
593     IN BOOLEAN Retrying\r
594     )\r
595 {\r
596         DBGSINGLEENTER6("CcDeferWrite: FileObject=0x%lX,PostRoutine=0x%lX,Context1=0x%lX,Context2=0x%lX,"\r
597                                         "BytesToWrite=0x%lX,Retrying=%d",\r
598                         (long)FileObject,(long)PostRoutine,(long)Context1,(long)Context2,\r
599                                         BytesToWrite,Retrying);\r
600         dump_FileObject(FileObject);\r
601         CcDeferWrite (\r
602 FileObject,\r
603 PostRoutine,\r
604 Context1,\r
605 Context2,\r
606 BytesToWrite,\r
607 Retrying\r
608     );\r
609         DBGSINGLELEAVE0("CcDeferWrite");\r
610 }\r
611 \r
612 VOID\r
613 CcFastCopyRead (\r
614     IN PFILE_OBJECT FileObject,\r
615     IN ULONG FileOffset,\r
616     IN ULONG Length,\r
617     IN ULONG PageCount,\r
618     OUT PVOID Buffer,\r
619     OUT PIO_STATUS_BLOCK IoStatus\r
620     );\r
621 VOID\r
622 TcFastCopyRead (\r
623     IN PFILE_OBJECT FileObject,\r
624     IN ULONG FileOffset,\r
625     IN ULONG Length,\r
626     IN ULONG PageCount,\r
627     OUT PVOID Buffer,\r
628     OUT PIO_STATUS_BLOCK IoStatus\r
629     )\r
630 {\r
631         DBGSINGLEENTER5("CcFastCopyRead: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,PageCount=0x%lX,Buffer=0x%lX",\r
632                         (long)FileObject,FileOffset,Length,PageCount,(long)Buffer);\r
633         dump_FileObject(FileObject);\r
634         CcFastCopyRead (\r
635 FileObject,\r
636 FileOffset,\r
637 Length,\r
638 PageCount,\r
639 Buffer,\r
640 IoStatus\r
641     );\r
642         DBGSINGLELEAVE2("CcFastCopyRead: IoStatus->Status=0x%lX,IoStatus->Information=0x%lX",\r
643                         (!IoStatus ? -1 : (long)IoStatus->Status),(!IoStatus ? -1 : (long)IoStatus->Information));\r
644 }\r
645 \r
646 VOID\r
647 CcFastCopyWrite (\r
648     IN PFILE_OBJECT FileObject,\r
649     IN ULONG FileOffset,\r
650     IN ULONG Length,\r
651     IN PVOID Buffer\r
652     );\r
653 VOID\r
654 TcFastCopyWrite (\r
655     IN PFILE_OBJECT FileObject,\r
656     IN ULONG FileOffset,\r
657     IN ULONG Length,\r
658     IN PVOID Buffer\r
659     )\r
660 {\r
661         DBGSINGLEENTER4("CcFastCopyWrite: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Buffer=0x%lX",\r
662                         (long)FileObject,FileOffset,Length,(long)Buffer);\r
663         dump_FileObject(FileObject);\r
664         CcFastCopyWrite (\r
665 FileObject,\r
666 FileOffset,\r
667 Length,\r
668 Buffer\r
669     );\r
670         DBGSINGLELEAVE0("CcFastCopyWrite");\r
671 }\r
672 \r
673 VOID\r
674 CcFlushCache (\r
675     IN PSECTION_OBJECT_POINTERS SectionObjectPointer,\r
676     IN PLARGE_INTEGER FileOffset OPTIONAL,\r
677     IN ULONG Length,\r
678     OUT PIO_STATUS_BLOCK IoStatus OPTIONAL\r
679     );\r
680 VOID\r
681 TcFlushCache (\r
682     IN PSECTION_OBJECT_POINTERS SectionObjectPointer,\r
683     IN PLARGE_INTEGER FileOffset OPTIONAL,\r
684     IN ULONG Length,\r
685     OUT PIO_STATUS_BLOCK IoStatus OPTIONAL\r
686     )\r
687 {\r
688         DBGSINGLEENTER4("CcFlushCache: SectionObjectPointer=0x%lX,->SharedCacheMap=0x%lX,FileOffset=0x%lX,Length=0x%lX",\r
689                                 (long)SectionObjectPointer,\r
690                                 (!SectionObjectPointer ? -1 : (long)SectionObjectPointer->SharedCacheMap),\r
691                                 (!FileOffset ? -1 : (long)FileOffset->QuadPart),Length);\r
692         dump_FileObject(SectionObjectPointer_find(SectionObjectPointer));\r
693         CcFlushCache (\r
694 SectionObjectPointer,\r
695 FileOffset,\r
696 Length,\r
697 IoStatus\r
698     );\r
699         dump_FileObject(SectionObjectPointer_find(SectionObjectPointer));\r
700         DBGSINGLELEAVE2("CcFlushCache: IoStatus->Status=0x%lX,IoStatus->Information=0x%lX",\r
701                         (!IoStatus ? -1 : (long)IoStatus->Status),(!IoStatus ? -1 : (long)IoStatus->Information));\r
702 }\r
703 \r
704 typedef\r
705 VOID (*PDIRTY_PAGE_ROUTINE) (\r
706             IN PFILE_OBJECT FileObject,\r
707             IN PLARGE_INTEGER FileOffset,\r
708             IN ULONG Length,\r
709             IN PLARGE_INTEGER OldestLsn,\r
710             IN PLARGE_INTEGER NewestLsn,\r
711             IN PVOID Context1,\r
712             IN PVOID Context2\r
713             );\r
714 \r
715 static PDIRTY_PAGE_ROUTINE TcGetDirtyPages_DirtyPageRoutine_orig;\r
716 static BOOLEAN TcGetDirtyPages_DirtyPageRoutine_used=FALSE;\r
717 \r
718 static VOID TcGetDirtyPages_DirtyPageRoutine(IN PFILE_OBJECT FileObject,IN PLARGE_INTEGER FileOffset,IN ULONG Length,\r
719                 IN PLARGE_INTEGER OldestLsn,IN PLARGE_INTEGER NewestLsn,IN PVOID Context1,IN PVOID Context2)\r
720 {\r
721         DBGSINGLEENTER5("DirtyPageRoutine: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,"\r
722                                         "OldestLsn=0x%lX,NewestLsn=0x%lX,Context1,Context2",\r
723                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,\r
724                         (!OldestLsn ? -1 : (long)OldestLsn->QuadPart),(!NewestLsn ? -1 : (long)NewestLsn->QuadPart));\r
725         dump_FileObject(FileObject);\r
726         (*TcGetDirtyPages_DirtyPageRoutine_orig)(FileObject,FileOffset,Length,OldestLsn,NewestLsn,Context1,Context2);\r
727         DBGSINGLELEAVE0("DirtyPageRoutine");\r
728 }\r
729 \r
730 LARGE_INTEGER\r
731 CcGetDirtyPages (\r
732     IN PVOID LogHandle,\r
733     IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine,\r
734     IN PVOID Context1,\r
735     IN PVOID Context2\r
736     );\r
737 LARGE_INTEGER\r
738 TcGetDirtyPages (\r
739     IN PVOID LogHandle,\r
740     IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine,\r
741     IN PVOID Context1,\r
742     IN PVOID Context2\r
743     )\r
744 {\r
745 LARGE_INTEGER r;\r
746 \r
747         DBGSINGLEENTER4("CcGetDirtyPages: LogHandle=0x%lX,DirtyPageRoutine=0x%lX,Context1=0x%lX,Context2=0x%lX",\r
748                         (long)LogHandle,(long)DirtyPageRoutine,(long)Context1,(long)Context2);\r
749         if (TcGetDirtyPages_DirtyPageRoutine_used)\r
750                 DBGSINGLE0("CcGetDirtyPages: ERROR: TcGetDirtyPages_DirtyPageRoutine_used");\r
751         else {\r
752                 TcGetDirtyPages_DirtyPageRoutine_used=TRUE;\r
753                 TcGetDirtyPages_DirtyPageRoutine_orig=DirtyPageRoutine;\r
754                 DirtyPageRoutine=TcGetDirtyPages_DirtyPageRoutine;\r
755                 }\r
756         r=CcGetDirtyPages (\r
757 LogHandle,\r
758 DirtyPageRoutine,\r
759 Context1,\r
760 Context2\r
761     );\r
762         if (DirtyPageRoutine==TcGetDirtyPages_DirtyPageRoutine)\r
763                 TcGetDirtyPages_DirtyPageRoutine_used=FALSE;\r
764         DBGSINGLELEAVE1("CcGetDirtyPages: r=0x%lX",(long)r.QuadPart);\r
765         return r;\r
766 }\r
767 \r
768 typedef BOOLEAN (*PACQUIRE_FOR_LAZY_WRITE)(IN PVOID Context,IN BOOLEAN Wait);\r
769 typedef VOID (*PRELEASE_FROM_LAZY_WRITE)(IN PVOID Context);\r
770 typedef BOOLEAN (*PACQUIRE_FOR_READ_AHEAD)(IN PVOID Context,IN BOOLEAN Wait);\r
771 typedef VOID (*PRELEASE_FROM_READ_AHEAD)(IN PVOID Context);\r
772 typedef struct _CACHE_MANAGER_CALLBACKS {\r
773                 PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite;\r
774                 PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite;\r
775                 PACQUIRE_FOR_READ_AHEAD AcquireForReadAhead;\r
776                 PRELEASE_FROM_READ_AHEAD ReleaseFromReadAhead;\r
777                 } CACHE_MANAGER_CALLBACKS,*PCACHE_MANAGER_CALLBACKS;\r
778 \r
779 static struct Callbacks {\r
780         FILE_OBJECT *FileObject;\r
781         CACHE_MANAGER_CALLBACKS Callbacks;\r
782         PVOID LazyWriteContext;\r
783         } Callbacks_cache[CACHE_SIZE];\r
784 static int Callbacks_cache_used=0;\r
785 \r
786 static struct Callbacks *Callbacks_set(FILE_OBJECT *FileObject,CACHE_MANAGER_CALLBACKS *Callbacks,PVOID LazyWriteContext)\r
787 {\r
788 struct Callbacks *callbacksp;\r
789 \r
790         for (callbacksp=Callbacks_cache;callbacksp<Callbacks_cache+Callbacks_cache_used;callbacksp++) {\r
791                 if (callbacksp->FileObject==FileObject)\r
792                         break;\r
793                 }\r
794         if (callbacksp>=Callbacks_cache+G_N_ELEMENTS(Callbacks_cache))\r
795                 return NULL;\r
796         if (callbacksp==Callbacks_cache+Callbacks_cache_used)\r
797                 Callbacks_cache_used++;\r
798         callbacksp->FileObject=FileObject;\r
799         callbacksp->Callbacks=*Callbacks;\r
800         callbacksp->LazyWriteContext=LazyWriteContext;\r
801         return callbacksp;\r
802 }\r
803 \r
804 static BOOLEAN TcInitializeCacheMap_AcquireForLazyWrite(IN PVOID Context,IN BOOLEAN Wait)\r
805 {\r
806 struct Callbacks *callbacksp=Context;\r
807 BOOLEAN r;\r
808 int locked;\r
809 \r
810         DBGSINGLEENTER3("AcquireForLazyWrite: FileObject=0x%lX,Context=0x%lX,Wait=%d",\r
811                         (long)callbacksp->FileObject,(long)callbacksp->LazyWriteContext,Wait);\r
812         dump_FileObject(callbacksp->FileObject);\r
813         /* Prevent deadlock during File Explorer copy to our destination. */\r
814         locked=unlock_full();\r
815         r=(*callbacksp->Callbacks.AcquireForLazyWrite)(callbacksp->LazyWriteContext,Wait);\r
816         lock_full(locked);\r
817         DBGSINGLELEAVE1("AcquireForLazyWrite: r=%d",r);\r
818         return r;\r
819 }\r
820 \r
821 static VOID TcInitializeCacheMap_ReleaseFromLazyWrite(IN PVOID Context)\r
822 {\r
823 struct Callbacks *callbacksp=Context;\r
824 int locked;\r
825 \r
826         DBGSINGLEENTER2("ReleaseFromLazyWrite: FileObject=0x%lX,Context=0x%lX",\r
827                         (long)callbacksp->FileObject,(long)callbacksp->LazyWriteContext);\r
828         dump_FileObject(callbacksp->FileObject);\r
829         /* Prevent deadlock during File Explorer copy to our destination. */\r
830         locked=unlock_full();\r
831         (*callbacksp->Callbacks.ReleaseFromLazyWrite)(callbacksp->LazyWriteContext);\r
832         lock_full(locked);\r
833         DBGSINGLELEAVE0("ReleaseFromLazyWrite");\r
834 }\r
835 \r
836 static BOOLEAN TcInitializeCacheMap_AcquireForReadAhead(IN PVOID Context,IN BOOLEAN Wait)\r
837 {\r
838 struct Callbacks *callbacksp=Context;\r
839 BOOLEAN r;\r
840 int locked;\r
841 \r
842         DBGSINGLEENTER3("AcquireForReadAhead: FileObject=0x%lX,Context=0x%lX,Wait=%d",\r
843                         (long)callbacksp->FileObject,(long)callbacksp->LazyWriteContext,Wait);\r
844         dump_FileObject(callbacksp->FileObject);\r
845         /* Prevent deadlock during File Explorer copy to our destination. */\r
846         locked=unlock_full();\r
847         r=(*callbacksp->Callbacks.AcquireForReadAhead)(callbacksp->LazyWriteContext,Wait);\r
848         lock_full(locked);\r
849         DBGSINGLELEAVE1("AcquireForReadAhead: r=%d",r);\r
850         return r;\r
851 }\r
852 \r
853 static VOID TcInitializeCacheMap_ReleaseFromReadAhead(IN PVOID Context)\r
854 {\r
855 struct Callbacks *callbacksp=Context;\r
856 int locked;\r
857 \r
858         DBGSINGLEENTER2("ReleaseFromReadAhead: FileObject=0x%lX,Context=0x%lX",\r
859                         (long)callbacksp->FileObject,(long)callbacksp->LazyWriteContext);\r
860         dump_FileObject(callbacksp->FileObject);\r
861         /* Prevent deadlock during File Explorer copy to our destination. */\r
862         locked=unlock_full();\r
863         (*callbacksp->Callbacks.ReleaseFromReadAhead)(callbacksp->LazyWriteContext);\r
864         lock_full(locked);\r
865         DBGSINGLELEAVE0("ReleaseFromReadAhead");\r
866 }\r
867 \r
868 static CACHE_MANAGER_CALLBACKS TcInitializeCacheMap_Callbacks={\r
869                 TcInitializeCacheMap_AcquireForLazyWrite,\r
870                 TcInitializeCacheMap_ReleaseFromLazyWrite,\r
871                 TcInitializeCacheMap_AcquireForReadAhead,\r
872                 TcInitializeCacheMap_ReleaseFromReadAhead,\r
873                 };\r
874 \r
875 typedef struct _CC_FILE_SIZES {\r
876                 LARGE_INTEGER AllocationSize;\r
877                 LARGE_INTEGER FileSize;\r
878                 LARGE_INTEGER ValidDataLength;\r
879                 } CC_FILE_SIZES,*PCC_FILE_SIZES;\r
880 \r
881 VOID\r
882 CcInitializeCacheMap (\r
883     IN PFILE_OBJECT FileObject,\r
884     IN PCC_FILE_SIZES FileSizes,\r
885     IN BOOLEAN PinAccess,\r
886     IN PCACHE_MANAGER_CALLBACKS Callbacks,\r
887     IN PVOID LazyWriteContext\r
888     );\r
889 VOID\r
890 TcInitializeCacheMap (\r
891     IN PFILE_OBJECT FileObject,\r
892     IN PCC_FILE_SIZES FileSizes,\r
893     IN BOOLEAN PinAccess,\r
894     IN PCACHE_MANAGER_CALLBACKS Callbacks,\r
895     IN PVOID LazyWriteContext\r
896     )\r
897 {\r
898 struct Callbacks *callbacksp;\r
899 \r
900         DBGSINGLEENTER5("CcInitializeCacheMap: FileObject=0x%lX,"\r
901                                         "FileSizes,->AllocationSize=0x%lX,->FileSize=0x%lX,->ValidDataLength=0x%lX,"\r
902                                         "PinAccess=%d,Callbacks,LazyWriteContext",\r
903                         (long)FileObject,\r
904                                         (!FileSizes ? -1 : (long)FileSizes->AllocationSize.QuadPart),\r
905                                         (!FileSizes ? -1 : (long)FileSizes->FileSize.QuadPart),\r
906                                         (!FileSizes ? -1 : (long)FileSizes->ValidDataLength.QuadPart),\r
907                                         PinAccess);\r
908         dump_FileObject(FileObject);\r
909         if ((callbacksp=Callbacks_set(FileObject,Callbacks,LazyWriteContext))) {\r
910                 Callbacks=&TcInitializeCacheMap_Callbacks;\r
911                 LazyWriteContext=callbacksp;\r
912                 if (Callbacks->AcquireForLazyWrite !=TcInitializeCacheMap_AcquireForLazyWrite)\r
913                         DBGSINGLE1("CcInitializeCacheMap: ERROR: AcquireForLazyWrite =0x%lX",Callbacks->AcquireForLazyWrite);\r
914                 if (Callbacks->ReleaseFromLazyWrite!=TcInitializeCacheMap_ReleaseFromLazyWrite)\r
915                         DBGSINGLE1("CcInitializeCacheMap: ERROR: ReleaseFromLazyWrite=0x%lX",Callbacks->ReleaseFromLazyWrite);\r
916                 if (Callbacks->AcquireForReadAhead !=TcInitializeCacheMap_AcquireForReadAhead)\r
917                         DBGSINGLE1("CcInitializeCacheMap: ERROR: AcquireForReadAhead =0x%lX",Callbacks->AcquireForReadAhead);\r
918                 if (Callbacks->ReleaseFromReadAhead!=TcInitializeCacheMap_ReleaseFromReadAhead)\r
919                         DBGSINGLE1("CcInitializeCacheMap: ERROR: ReleaseFromReadAhead=0x%lX",Callbacks->ReleaseFromReadAhead);\r
920                 }\r
921         CcInitializeCacheMap (\r
922 FileObject,\r
923 FileSizes,\r
924 PinAccess,\r
925 Callbacks,\r
926 LazyWriteContext\r
927     );\r
928         dump_FileObject(FileObject);\r
929         DBGSINGLELEAVE0("CcInitializeCacheMap");\r
930 }\r
931 \r
932 BOOLEAN\r
933 CcMapData (\r
934     IN PFILE_OBJECT FileObject,\r
935     IN PLARGE_INTEGER FileOffset,\r
936     IN ULONG Length,\r
937     IN ULONG Flags,\r
938     OUT PVOID *Bcb,\r
939     OUT PVOID *Buffer\r
940     );\r
941 BOOLEAN\r
942 TcMapData (\r
943     IN PFILE_OBJECT FileObject,\r
944     IN PLARGE_INTEGER FileOffset,\r
945     IN ULONG Length,\r
946     IN ULONG Flags,\r
947     OUT PVOID *Bcb,\r
948     OUT PVOID *Buffer\r
949     )\r
950 {\r
951 BOOLEAN r;\r
952 \r
953         DBGSINGLEENTER4("CcMapData: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Flags=0x%lX",\r
954                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Flags);\r
955         dump_FileObject(FileObject);\r
956         r=CcMapData (\r
957 FileObject,\r
958 FileOffset,\r
959 Length,\r
960 Flags,\r
961 Bcb,\r
962 Buffer\r
963     );\r
964         DBGSINGLELEAVE3("CcMapData: r=%d,Bcb=0x%lX,Buffer=0x%lX",\r
965                         r,(!Bcb ? -1 : (long)*Bcb),(!Buffer ? -1 : (long)*Buffer));\r
966         return r;\r
967 }\r
968 \r
969 VOID\r
970 CcMdlRead (\r
971     IN PFILE_OBJECT FileObject,\r
972     IN PLARGE_INTEGER FileOffset,\r
973     IN ULONG Length,\r
974     OUT PMDL *MdlChain,\r
975     OUT PIO_STATUS_BLOCK IoStatus\r
976     );\r
977 VOID\r
978 TcMdlRead (\r
979     IN PFILE_OBJECT FileObject,\r
980     IN PLARGE_INTEGER FileOffset,\r
981     IN ULONG Length,\r
982     OUT PMDL *MdlChain,\r
983     OUT PIO_STATUS_BLOCK IoStatus\r
984     )\r
985 {\r
986         DBGSINGLEENTER3("CcMdlRead: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX",\r
987                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length);\r
988         dump_FileObject(FileObject);\r
989         CcMdlRead (\r
990 FileObject,\r
991 FileOffset,\r
992 Length,\r
993 MdlChain,\r
994 IoStatus\r
995     );\r
996         DBGSINGLELEAVE3("CcMdlRead: MdlChain=0x%lX,IoStatus->Status=0x%lX,IoStatus->Information=0x%lX",\r
997                         (!MdlChain ? -1 : (long)*MdlChain),\r
998                         (!IoStatus ? -1 : (long)IoStatus->Status),(!IoStatus ? -1 : (long)IoStatus->Information));\r
999 }\r
1000 \r
1001 VOID\r
1002 CcMdlReadComplete (\r
1003     IN PFILE_OBJECT FileObject,\r
1004     IN PMDL MdlChain\r
1005     );\r
1006 VOID\r
1007 TcMdlReadComplete (\r
1008     IN PFILE_OBJECT FileObject,\r
1009     IN PMDL MdlChain\r
1010     )\r
1011 {\r
1012         DBGSINGLEENTER2("CcMdlReadComplete: FileObject=0x%lX,MdlChain=0x%lX",\r
1013                         (long)FileObject,(long)MdlChain);\r
1014         dump_FileObject(FileObject);\r
1015         CcMdlReadComplete (\r
1016 FileObject,\r
1017 MdlChain\r
1018     );\r
1019         DBGSINGLELEAVE0("CcMdlReadComplete");\r
1020 }\r
1021 \r
1022 VOID\r
1023 CcMdlWriteAbort (\r
1024     IN PFILE_OBJECT FileObject,\r
1025     IN PMDL MdlChain\r
1026     );\r
1027 VOID\r
1028 TcMdlWriteAbort (\r
1029     IN PFILE_OBJECT FileObject,\r
1030     IN PMDL MdlChain\r
1031     )\r
1032 {\r
1033         DBGSINGLEENTER2("CcMdlWriteAbort: FileObject=0x%lX,MdlChain=0x%lX",\r
1034                         (long)FileObject,(long)MdlChain);\r
1035         dump_FileObject(FileObject);\r
1036         CcMdlWriteAbort (\r
1037 FileObject,\r
1038 MdlChain\r
1039     );\r
1040         DBGSINGLELEAVE0("CcMdlWriteAbort");\r
1041 }\r
1042 \r
1043 VOID\r
1044 CcMdlWriteComplete (\r
1045     IN PFILE_OBJECT FileObject,\r
1046     IN PLARGE_INTEGER FileOffset,\r
1047     IN PMDL MdlChain\r
1048     );\r
1049 VOID\r
1050 TcMdlWriteComplete (\r
1051     IN PFILE_OBJECT FileObject,\r
1052     IN PLARGE_INTEGER FileOffset,\r
1053     IN PMDL MdlChain\r
1054     )\r
1055 {\r
1056         DBGSINGLEENTER3("CcMdlWriteComplete: FileObject=0x%lX,FileOffset=0x%lX,MdlChain=0x%lX",\r
1057                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),(long)MdlChain);\r
1058         dump_FileObject(FileObject);\r
1059         CcMdlWriteComplete (\r
1060 FileObject,\r
1061 FileOffset,\r
1062 MdlChain\r
1063     );\r
1064         DBGSINGLELEAVE0("CcMdlWriteComplete");\r
1065 }\r
1066 \r
1067 BOOLEAN\r
1068 CcPinMappedData (\r
1069     IN PFILE_OBJECT FileObject,\r
1070     IN PLARGE_INTEGER FileOffset,\r
1071     IN ULONG Length,\r
1072     IN ULONG Flags,\r
1073     IN OUT PVOID *Bcb\r
1074     );\r
1075 BOOLEAN\r
1076 TcPinMappedData (\r
1077     IN PFILE_OBJECT FileObject,\r
1078     IN PLARGE_INTEGER FileOffset,\r
1079     IN ULONG Length,\r
1080     IN ULONG Flags,\r
1081     IN OUT PVOID *Bcb\r
1082     )\r
1083 {\r
1084 BOOLEAN r;\r
1085 \r
1086         DBGSINGLEENTER4("CcPinMappedData: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Flags=0x%lX",\r
1087                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Flags);\r
1088         dump_FileObject(FileObject);\r
1089         r=CcPinMappedData (\r
1090 FileObject,\r
1091 FileOffset,\r
1092 Length,\r
1093 Flags,\r
1094 Bcb\r
1095     );\r
1096         DBGSINGLELEAVE2("CcPinMappedData: r=%d,Bcb=0x%lX",\r
1097                         r,(!Bcb ? -1 : (long)*Bcb));\r
1098         return r;\r
1099 }\r
1100 \r
1101 BOOLEAN\r
1102 CcPinRead (\r
1103     IN PFILE_OBJECT FileObject,\r
1104     IN PLARGE_INTEGER FileOffset,\r
1105     IN ULONG Length,\r
1106     IN ULONG Flags,\r
1107     OUT PVOID *Bcb,\r
1108     OUT PVOID *Buffer\r
1109     );\r
1110 BOOLEAN\r
1111 TcPinRead (\r
1112     IN PFILE_OBJECT FileObject,\r
1113     IN PLARGE_INTEGER FileOffset,\r
1114     IN ULONG Length,\r
1115     IN ULONG Flags,\r
1116     OUT PVOID *Bcb,\r
1117     OUT PVOID *Buffer\r
1118     )\r
1119 {\r
1120 BOOLEAN r;\r
1121 \r
1122         DBGSINGLEENTER4("CcPinRead: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Flags=0x%lX",\r
1123                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Flags);\r
1124         dump_FileObject(FileObject);\r
1125         r=CcPinRead (\r
1126 FileObject,\r
1127 FileOffset,\r
1128 Length,\r
1129 Flags,\r
1130 Bcb,\r
1131 Buffer\r
1132     );\r
1133         DBGSINGLELEAVE3("CcPinRead: r=%d,Bcb=0x%lX,Buffer=0x%lX",\r
1134                         r,(!Bcb ? -1 : (long)*Bcb),(!Buffer ? -1 : (long)*Buffer));\r
1135         return r;\r
1136 }\r
1137 \r
1138 VOID\r
1139 CcPrepareMdlWrite (\r
1140     IN PFILE_OBJECT FileObject,\r
1141     IN PLARGE_INTEGER FileOffset,\r
1142     IN ULONG Length,\r
1143     OUT PMDL *MdlChain,\r
1144     OUT PIO_STATUS_BLOCK IoStatus\r
1145     );\r
1146 VOID\r
1147 TcPrepareMdlWrite (\r
1148     IN PFILE_OBJECT FileObject,\r
1149     IN PLARGE_INTEGER FileOffset,\r
1150     IN ULONG Length,\r
1151     OUT PMDL *MdlChain,\r
1152     OUT PIO_STATUS_BLOCK IoStatus\r
1153     )\r
1154 {\r
1155         DBGSINGLEENTER3("CcPrepareMdlWrite: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX",\r
1156                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length);\r
1157         dump_FileObject(FileObject);\r
1158         CcPrepareMdlWrite (\r
1159 FileObject,\r
1160 FileOffset,\r
1161 Length,\r
1162 MdlChain,\r
1163 IoStatus\r
1164     );\r
1165         DBGSINGLELEAVE3("CcPrepareMdlWrite: MdlChain=0x%lX,IoStatus->Status=0x%lX,IoStatus->Information=0x%lX",\r
1166                         (!MdlChain ? -1 : (long)*MdlChain),\r
1167                         (!IoStatus ? -1 : (long)IoStatus->Status),(!IoStatus ? -1 : (long)IoStatus->Information));\r
1168 }\r
1169 \r
1170 BOOLEAN\r
1171 CcPreparePinWrite (\r
1172     IN PFILE_OBJECT FileObject,\r
1173     IN PLARGE_INTEGER FileOffset,\r
1174     IN ULONG Length,\r
1175     IN BOOLEAN Zero,\r
1176     IN ULONG Flags,\r
1177     OUT PVOID *Bcb,\r
1178     OUT PVOID *Buffer\r
1179     );\r
1180 BOOLEAN\r
1181 TcPreparePinWrite (\r
1182     IN PFILE_OBJECT FileObject,\r
1183     IN PLARGE_INTEGER FileOffset,\r
1184     IN ULONG Length,\r
1185     IN BOOLEAN Zero,\r
1186     IN ULONG Flags,\r
1187     OUT PVOID *Bcb,\r
1188     OUT PVOID *Buffer\r
1189     )\r
1190 {\r
1191 BOOLEAN r;\r
1192 \r
1193         DBGSINGLEENTER5("CcPreparePinWrite: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Zero=%d,Flags=0x%lX",\r
1194                         (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Zero,Flags);\r
1195         dump_FileObject(FileObject);\r
1196         r=CcPreparePinWrite (\r
1197 FileObject,\r
1198 FileOffset,\r
1199 Length,\r
1200 Zero,\r
1201 Flags,\r
1202 Bcb,\r
1203 Buffer\r
1204     );\r
1205         DBGSINGLELEAVE3("CcPreparePinWrite: r=%d,Bcb=0x%lX,Buffer=0x%lX",\r
1206                         r,(!Bcb ? -1 : (long)*Bcb),(!Buffer ? -1 : (long)*Buffer));\r
1207         return r;\r
1208 }\r
1209 \r
1210 BOOLEAN\r
1211 CcPurgeCacheSection (\r
1212     IN PSECTION_OBJECT_POINTERS SectionObjectPointer,\r
1213     IN PLARGE_INTEGER FileOffset OPTIONAL,\r
1214     IN ULONG Length,\r
1215     IN BOOLEAN UninitializeCacheMaps\r
1216     );\r
1217 BOOLEAN\r
1218 TcPurgeCacheSection (\r
1219     IN PSECTION_OBJECT_POINTERS SectionObjectPointer,\r
1220     IN PLARGE_INTEGER FileOffset OPTIONAL,\r
1221     IN ULONG Length,\r
1222     IN BOOLEAN UninitializeCacheMaps\r
1223     )\r
1224 {\r
1225 BOOLEAN r;\r
1226 \r
1227         DBGSINGLEENTER5("CcPurgeCacheSection: SectionObjectPointer=0x%lX,->SharedCacheMap=0x%lX,FileOffset=0x%lX,Length=0x%lX,"\r
1228                                                 "UninitializeCacheMaps=%d",\r
1229                                 (long)SectionObjectPointer,\r
1230                                 (!SectionObjectPointer ? -1 : (long)SectionObjectPointer->SharedCacheMap),\r
1231                                 (!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,\r
1232                                                 UninitializeCacheMaps);\r
1233         dump_FileObject(SectionObjectPointer_find(SectionObjectPointer));\r
1234         r=CcPurgeCacheSection (\r
1235 SectionObjectPointer,\r
1236 FileOffset,\r
1237 Length,\r
1238 UninitializeCacheMaps\r
1239     );\r
1240         dump_FileObject(SectionObjectPointer_find(SectionObjectPointer));\r
1241         DBGSINGLELEAVE1("CcPurgeCacheSection: r=%d",r);\r
1242         return r;\r
1243 }\r
1244 \r
1245 PVOID\r
1246 CcRemapBcb (\r
1247     IN PVOID Bcb\r
1248     );\r
1249 PVOID\r
1250 TcRemapBcb (\r
1251     IN PVOID Bcb\r
1252     )\r
1253 {\r
1254 PVOID r;\r
1255 \r
1256         DBGSINGLEENTER1("CcRemapBcb: Bcb=0x%lX",(long)Bcb);\r
1257         r=CcRemapBcb (\r
1258 Bcb\r
1259     );\r
1260         DBGSINGLELEAVE1("CcRemapBcb: r=0x%lX",(long)r);\r
1261         return r;\r
1262 }\r
1263 \r
1264 VOID\r
1265 CcSetAdditionalCacheAttributes (\r
1266     IN PFILE_OBJECT FileObject,\r
1267     IN BOOLEAN DisableReadAhead,\r
1268     IN BOOLEAN DisableWriteBehind\r
1269     );\r
1270 VOID\r
1271 TcSetAdditionalCacheAttributes (\r
1272     IN PFILE_OBJECT FileObject,\r
1273     IN BOOLEAN DisableReadAhead,\r
1274     IN BOOLEAN DisableWriteBehind\r
1275     )\r
1276 {\r
1277         DBGSINGLEENTER3("CcSetAdditionalCacheAttributes: FileObject=0x%lX,DisableReadAhead=%d,DisableWriteBehind=%d",\r
1278                         (long)FileObject,DisableReadAhead,DisableWriteBehind);\r
1279         dump_FileObject(FileObject);\r
1280         CcSetAdditionalCacheAttributes (\r
1281 FileObject,\r
1282 DisableReadAhead,\r
1283 DisableWriteBehind\r
1284     );\r
1285         DBGSINGLELEAVE0("CcSetAdditionalCacheAttributes");\r
1286 }\r
1287 \r
1288 VOID\r
1289 CcSetBcbOwnerPointer (\r
1290     IN PVOID Bcb,\r
1291     IN PVOID OwnerPointer\r
1292     );\r
1293 VOID\r
1294 TcSetBcbOwnerPointer (\r
1295     IN PVOID Bcb,\r
1296     IN PVOID OwnerPointer\r
1297     )\r
1298 {\r
1299         DBGSINGLEENTER2("CcSetBcbOwnerPointer: Bcb=0x%lX,OwnerPointer=0x%lX",\r
1300                         (long)Bcb,(long)OwnerPointer);\r
1301         CcSetBcbOwnerPointer (\r
1302 Bcb,\r
1303 OwnerPointer\r
1304     );\r
1305         DBGSINGLELEAVE0("CcSetBcbOwnerPointer");\r
1306 }\r
1307 \r
1308 VOID\r
1309 CcSetDirtyPinnedData (\r
1310     IN PVOID BcbVoid,\r
1311     IN PLARGE_INTEGER Lsn OPTIONAL\r
1312     );\r
1313 VOID\r
1314 TcSetDirtyPinnedData (\r
1315     IN PVOID BcbVoid,\r
1316     IN PLARGE_INTEGER Lsn OPTIONAL\r
1317     )\r
1318 {\r
1319         DBGSINGLEENTER2("CcSetDirtyPinnedData: BcbVoid=0x%lX,Lsn=0x%lX",\r
1320                         (long)BcbVoid,(!Lsn ? -1 : (long)Lsn->QuadPart));\r
1321         CcSetDirtyPinnedData (\r
1322 BcbVoid,\r
1323 Lsn\r
1324     );\r
1325         DBGSINGLELEAVE0("CcSetDirtyPinnedData");\r
1326 }\r
1327 \r
1328 VOID\r
1329 CcSetFileSizes (\r
1330     IN PFILE_OBJECT FileObject,\r
1331     IN PCC_FILE_SIZES FileSizes\r
1332     );\r
1333 VOID\r
1334 TcSetFileSizes (\r
1335     IN PFILE_OBJECT FileObject,\r
1336     IN PCC_FILE_SIZES FileSizes\r
1337     )\r
1338 {\r
1339         DBGSINGLEENTER4("CcSetFileSizes: FileObject=0x%lX,"\r
1340                                         "FileSizes,->AllocationSize=0x%lX,->FileSize=0x%lX,->ValidDataLength=0x%lX",\r
1341                         (long)FileObject,\r
1342                                         (!FileSizes ? -1 : (long)FileSizes->AllocationSize.QuadPart),\r
1343                                         (!FileSizes ? -1 : (long)FileSizes->FileSize.QuadPart),\r
1344                                         (!FileSizes ? -1 : (long)FileSizes->ValidDataLength.QuadPart));\r
1345         dump_FileObject(FileObject);\r
1346         CcSetFileSizes (\r
1347 FileObject,\r
1348 FileSizes\r
1349     );\r
1350         DBGSINGLELEAVE0("CcSetFileSizes");\r
1351 }\r
1352 \r
1353 typedef VOID (*PFLUSH_TO_LSN)(IN PVOID LogHandle,IN LARGE_INTEGER Lsn);\r
1354 \r
1355 static struct LogHandle {\r
1356         PVOID LogHandle;\r
1357         PFLUSH_TO_LSN FlushToLsnRoutine;\r
1358         } LogHandle_cache[CACHE_SIZE];\r
1359 static int LogHandle_cache_used=0;\r
1360 \r
1361 static BOOLEAN LogHandle_set(PVOID LogHandle,PFLUSH_TO_LSN FlushToLsnRoutine)\r
1362 {\r
1363 struct LogHandle *loghandlep;\r
1364 \r
1365         for (loghandlep=LogHandle_cache;loghandlep<LogHandle_cache+LogHandle_cache_used;loghandlep++) {\r
1366                 if (loghandlep->LogHandle==LogHandle)\r
1367                         break;\r
1368                 }\r
1369         if (loghandlep>=LogHandle_cache+G_N_ELEMENTS(LogHandle_cache))\r
1370                 return FALSE;\r
1371         if (loghandlep==LogHandle_cache+LogHandle_cache_used)\r
1372                 LogHandle_cache_used++;\r
1373         loghandlep->LogHandle=LogHandle;\r
1374         loghandlep->FlushToLsnRoutine=FlushToLsnRoutine;\r
1375         return TRUE;\r
1376 }\r
1377 \r
1378 static PFLUSH_TO_LSN LogHandle_find(PVOID LogHandle)\r
1379 {\r
1380 struct LogHandle *loghandlep;\r
1381 \r
1382         for (loghandlep=LogHandle_cache;loghandlep<LogHandle_cache+LogHandle_cache_used;loghandlep++) {\r
1383                 if (loghandlep->LogHandle==LogHandle)\r
1384                         return loghandlep->FlushToLsnRoutine;\r
1385                 }\r
1386         return NULL;\r
1387 }\r
1388 \r
1389 static VOID TcSetLogHandleForFile_FlushToLsnRoutine(IN PVOID LogHandle,IN LARGE_INTEGER Lsn)\r
1390 {\r
1391 PFLUSH_TO_LSN FlushToLsnRoutine;\r
1392 int locked;\r
1393 \r
1394         DBGSINGLEENTER2("FlushToLsnRoutine: LogHandle=0x%lX,Lsn=0x%lX",\r
1395                         (long)LogHandle,(long)Lsn.QuadPart);\r
1396         /* Prevent deadlock during display of File Explorer directory listing. */\r
1397         locked=unlock_full();\r
1398         if ((FlushToLsnRoutine=LogHandle_find(LogHandle)))\r
1399                 (*FlushToLsnRoutine)(LogHandle,Lsn);\r
1400         lock_full(locked);\r
1401         DBGSINGLELEAVE0("FlushToLsnRoutine");\r
1402 }\r
1403 \r
1404 VOID\r
1405 CcSetLogHandleForFile (\r
1406     IN PFILE_OBJECT FileObject,\r
1407     IN PVOID LogHandle,\r
1408     IN PFLUSH_TO_LSN FlushToLsnRoutine\r
1409     );\r
1410 VOID\r
1411 TcSetLogHandleForFile (\r
1412     IN PFILE_OBJECT FileObject,\r
1413     IN PVOID LogHandle,\r
1414     IN PFLUSH_TO_LSN FlushToLsnRoutine\r
1415     )\r
1416 {\r
1417         DBGSINGLEENTER3("CcSetLogHandleForFile: FileObject=0x%lX,LogHandle=0x%lX,FlushToLsnRoutine=0x%lX",\r
1418                         (long)FileObject,(long)LogHandle,(long)FlushToLsnRoutine);\r
1419         dump_FileObject(FileObject);\r
1420         if (LogHandle_set(LogHandle,FlushToLsnRoutine))\r
1421                 FlushToLsnRoutine=TcSetLogHandleForFile_FlushToLsnRoutine;\r
1422         CcSetLogHandleForFile (\r
1423 FileObject,\r
1424 LogHandle,\r
1425 FlushToLsnRoutine\r
1426     );\r
1427         DBGSINGLELEAVE0("CcSetLogHandleForFile");\r
1428 }\r
1429 \r
1430 VOID\r
1431 CcSetReadAheadGranularity (\r
1432     IN PFILE_OBJECT FileObject,\r
1433     IN ULONG Granularity\r
1434     );\r
1435 VOID\r
1436 TcSetReadAheadGranularity (\r
1437     IN PFILE_OBJECT FileObject,\r
1438     IN ULONG Granularity\r
1439     )\r
1440 {\r
1441         DBGSINGLEENTER2("CcSetReadAheadGranularity: FileObject=0x%lX,Granularity=0x%lX",\r
1442                         (long)FileObject,Granularity);\r
1443         dump_FileObject(FileObject);\r
1444         CcSetReadAheadGranularity (\r
1445 FileObject,\r
1446 Granularity\r
1447     );\r
1448         DBGSINGLELEAVE0("CcSetReadAheadGranularity");\r
1449 }\r
1450 \r
1451 typedef struct _CACHE_UNINITIALIZE_EVENT {\r
1452         struct _CACHE_UNINITIALIZE_EVENT *Next;\r
1453         KEVENT Event;\r
1454         } CACHE_UNINITIALIZE_EVENT,*PCACHE_UNINITIALIZE_EVENT;\r
1455 \r
1456 BOOLEAN\r
1457 CcUninitializeCacheMap (\r
1458     IN PFILE_OBJECT FileObject,\r
1459     IN PLARGE_INTEGER TruncateSize OPTIONAL,\r
1460     IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL\r
1461     );\r
1462 BOOLEAN\r
1463 TcUninitializeCacheMap (\r
1464     IN PFILE_OBJECT FileObject,\r
1465     IN PLARGE_INTEGER TruncateSize OPTIONAL,\r
1466     IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL\r
1467     )\r
1468 {\r
1469 BOOLEAN r;\r
1470 \r
1471         DBGSINGLEENTER3("CcUninitializeCacheMap: FileObject=0x%lX,TruncateSize=0x%lX,UninitializeCompleteEvent=0x%lX",\r
1472                         (long)FileObject,(!TruncateSize ? -1 : (long)TruncateSize->QuadPart),(long)UninitializeCompleteEvent);\r
1473         dump_FileObject(FileObject);\r
1474         r=CcUninitializeCacheMap (\r
1475 FileObject,\r
1476 TruncateSize,\r
1477 UninitializeCompleteEvent\r
1478     );\r
1479         dump_FileObject(FileObject);\r
1480         DBGSINGLELEAVE1("CcUninitializeCacheMap: r=%d",r);\r
1481         return r;\r
1482 }\r
1483 \r
1484 VOID\r
1485 CcUnpinData (\r
1486     IN PVOID Bcb\r
1487     );\r
1488 VOID\r
1489 TcUnpinData (\r
1490     IN PVOID Bcb\r
1491     )\r
1492 {\r
1493         DBGSINGLEENTER1("CcUnpinData: Bcb=0x%lX",(long)Bcb);\r
1494         CcUnpinData (\r
1495 Bcb\r
1496     );\r
1497         DBGSINGLELEAVE0("CcUnpinData");\r
1498 }\r
1499 \r
1500 VOID\r
1501 CcUnpinDataForThread (\r
1502     IN PVOID Bcb,\r
1503     IN ERESOURCE_THREAD ResourceThreadId\r
1504     );\r
1505 VOID\r
1506 TcUnpinDataForThread (\r
1507     IN PVOID Bcb,\r
1508     IN ERESOURCE_THREAD ResourceThreadId\r
1509     )\r
1510 {\r
1511         DBGSINGLEENTER2("CcUnpinDataForThread: Bcb=0x%lX,ResourceThreadId=0x%lX",\r
1512                         (long)Bcb,(long)ResourceThreadId);\r
1513         CcUnpinDataForThread (\r
1514 Bcb,\r
1515 ResourceThreadId\r
1516     );\r
1517         DBGSINGLELEAVE0("CcUnpinDataForThread");\r
1518 }\r
1519 \r
1520 NTSTATUS\r
1521 CcWaitForCurrentLazyWriterActivity (\r
1522     VOID\r
1523     );\r
1524 NTSTATUS\r
1525 TcWaitForCurrentLazyWriterActivity (\r
1526     VOID\r
1527     )\r
1528 {\r
1529 NTSTATUS r;\r
1530 \r
1531         DBGSINGLEENTER0("CcWaitForCurrentLazyWriterActivity");\r
1532         r=CcWaitForCurrentLazyWriterActivity (\r
1533     );\r
1534         DBGSINGLELEAVE1("CcWaitForCurrentLazyWriterActivity: r=0x%lX",r);\r
1535         return r;\r
1536 }\r
1537 \r
1538 BOOLEAN\r
1539 CcZeroData (\r
1540     IN PFILE_OBJECT FileObject,\r
1541     IN PLARGE_INTEGER StartOffset,\r
1542     IN PLARGE_INTEGER EndOffset,\r
1543     IN BOOLEAN Wait\r
1544     );\r
1545 BOOLEAN\r
1546 TcZeroData (\r
1547     IN PFILE_OBJECT FileObject,\r
1548     IN PLARGE_INTEGER StartOffset,\r
1549     IN PLARGE_INTEGER EndOffset,\r
1550     IN BOOLEAN Wait\r
1551     )\r
1552 {\r
1553 BOOLEAN r;\r
1554 \r
1555         DBGSINGLEENTER4("CcZeroData: FileObject=0x%lX,StartOffset=0x%lX,EndOffset=0x%lX,Wait=%d",\r
1556                         (long)FileObject,\r
1557                         (!StartOffset ? -1 : (long)StartOffset->QuadPart),\r
1558                         (!EndOffset ? -1 : (long)EndOffset->QuadPart),\r
1559                         Wait);\r
1560         dump_FileObject(FileObject);\r
1561         r=CcZeroData (\r
1562 FileObject,\r
1563 StartOffset,\r
1564 EndOffset,\r
1565 Wait\r
1566     );\r
1567         DBGSINGLELEAVE1("CcZeroData: r=%d",r);\r
1568         return r;\r
1569 }\r