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