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