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