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