#pragma alloc_text (INIT, DriverEntry)\r
#endif\r
\r
-static FAST_MUTEX lock_mutex;\r
+/* Ke*Mutex() would be reentrant but it looked too unclear for me.\r
+ * Never ExAcquireFastMutex() two FAST_MUTEX once or one FAST_MUTEX twice.\r
+ * Use Ex*ResourceLite instead of Ex*FastMutex() as it would set IRQL to DPC\r
+ * and we cannot pass the execution to Cc*() in DPC.\r
+ * Ex*FastMutex() problem: IRP_MJ_SHUTDOWN: Assertion failure.\r
+ */\r
+static ERESOURCE lock_resource;\r
+static int lock_resource_count;\r
+static PETHREAD lock_resource_CurrentThread;\r
\r
static void lock_init(void)\r
{\r
- ExInitializeFastMutex(&lock_mutex);\r
+ if (ExInitializeResourceLite(&lock_resource))\r
+ KeBugCheck(0);\r
+ lock_resource_count=0;\r
+ lock_resource_CurrentThread=NULL;\r
}\r
\r
static void lock(void)\r
{\r
- ExAcquireFastMutex(&lock_mutex);\r
+ if (lock_resource_CurrentThread==PsGetCurrentThread()) {\r
+ if (lock_resource_count<=0)\r
+ KeBugCheck(0);\r
+ lock_resource_count++;\r
+ return;\r
+ }\r
+ KeEnterCriticalRegion();\r
+ if (!ExAcquireResourceExclusiveLite(&lock_resource,TRUE))\r
+ KeBugCheck(0);\r
+ KeLeaveCriticalRegion();\r
+ if (lock_resource_CurrentThread)\r
+ KeBugCheck(0);\r
+ if (lock_resource_count!=0)\r
+ KeBugCheck(0);\r
+ lock_resource_CurrentThread=PsGetCurrentThread();\r
+ lock_resource_count++;\r
}\r
\r
static void unlock(void)\r
{\r
- ExReleaseFastMutex(&lock_mutex);\r
+ if (lock_resource_CurrentThread!=PsGetCurrentThread())\r
+ KeBugCheck(0);\r
+ if (lock_resource_count<=0)\r
+ KeBugCheck(0);\r
+ if (--lock_resource_count)\r
+ return;\r
+ lock_resource_CurrentThread=NULL;\r
+ KeEnterCriticalRegion();\r
+ ExReleaseResourceLite(&lock_resource);\r
+ KeLeaveCriticalRegion();\r
}\r
\r
#define DBGPREFIX "TraceFS(0x%08lX/0x%08lX): "\r
\r
static int dbgindent=0;\r
\r
+/* DBGSINGLEENTER*() / DBGSINGLELEAVE*() are protected by lock()/unlock()\r
+ * to serialize the Cc*() function calls as otherwise the debug dumps\r
+ * chronology may not match the real core execution chronology inside.\r
+ */\r
+\r
/* lock() will protect dbg_unicode_string() static buffer. */\r
#define DBGSINGLE6(fmt,arg1,arg2,arg3,arg4,arg5,arg6) \\r
do { lock(); DbgPrint("%*s" DBGPREFIX fmt "\n",dbgindent,"",DBGARG,arg1,arg2,arg3,arg4,arg5,arg6); unlock(); } while (0)\r
#define DBGSINGLE1(fmt,arg1) DBGSINGLE2(fmt,arg1,0)\r
#define DBGSINGLE0(fmt) DBGSINGLE1(fmt,0)\r
#define DBGSINGLEENTER6(fmt,arg1,arg2,arg3,arg4,arg5,arg6) \\r
- do { DBGSINGLE6("enter: " fmt,arg1,arg2,arg3,arg4,arg5,arg6); dbgindent++; } while (0)\r
+ do { lock(); DBGSINGLE6("enter: " fmt,arg1,arg2,arg3,arg4,arg5,arg6); dbgindent++; } while (0)\r
#define DBGSINGLEENTER5(fmt,arg1,arg2,arg3,arg4,arg5) DBGSINGLEENTER6(fmt,arg1,arg2,arg3,arg4,arg5,0)\r
#define DBGSINGLEENTER4(fmt,arg1,arg2,arg3,arg4) DBGSINGLEENTER5(fmt,arg1,arg2,arg3,arg4,0)\r
#define DBGSINGLEENTER3(fmt,arg1,arg2,arg3) DBGSINGLEENTER4(fmt,arg1,arg2,arg3,0)\r
#define DBGSINGLEENTER1(fmt,arg1) DBGSINGLEENTER2(fmt,arg1,0)\r
#define DBGSINGLEENTER0(fmt) DBGSINGLEENTER1(fmt,0)\r
#define DBGSINGLELEAVE3(fmt,arg1,arg2,arg3) \\r
- do { dbgindent--; DBGSINGLE3("leave: " fmt,arg1,arg2,arg3); } while (0)\r
+ do { dbgindent--; DBGSINGLE3("leave: " fmt,arg1,arg2,arg3); unlock(); } while (0)\r
#define DBGSINGLELEAVE2(fmt,arg1,arg2) DBGSINGLELEAVE3(fmt,arg1,arg2,0)\r
#define DBGSINGLELEAVE1(fmt,arg1) DBGSINGLELEAVE2(fmt,arg1,0)\r
#define DBGSINGLELEAVE0(fmt) DBGSINGLELEAVE1(fmt,0)\r
return r;\r
}\r
\r
-static const char *const irp_mj_dump_FILE_SYSTEM_CONTROL_MinorFunction_names[]={\r
+static const char *const dump_irp_mj_FILE_SYSTEM_CONTROL_MinorFunction_names[]={\r
"IRP_MN_USER_FS_REQUEST",\r
"IRP_MN_MOUNT_VOLUME",\r
"IRP_MN_VERIFY_VOLUME",\r
#define FSCTL_FILE_PREFETCH CTL_CODE(FILE_DEVICE_FILE_SYSTEM,72,METHOD_BUFFERED,FILE_SPECIAL_ACCESS)\r
#endif\r
\r
-static void irp_mj_dump(struct _DEVICE_OBJECT *DeviceObject,struct _IRP *Irp)\r
+static struct SectionObjectPointer {\r
+ FILE_OBJECT *FileObject;\r
+ PVOID SharedCacheMap;\r
+ } SectionObjectPointer_cache[CACHE_SIZE];\r
+static int SectionObjectPointer_cache_used=0;\r
+\r
+static struct SectionObjectPointer *SectionObjectPointer_set(FILE_OBJECT *FileObject)\r
+{\r
+struct SectionObjectPointer *sopp;\r
+PVOID SharedCacheMap;\r
+\r
+ if (!FileObject->SectionObjectPointer)\r
+ return NULL;\r
+ if (!(SharedCacheMap=FileObject->SectionObjectPointer->SharedCacheMap))\r
+ return NULL;\r
+ for (sopp=SectionObjectPointer_cache;sopp<SectionObjectPointer_cache+SectionObjectPointer_cache_used;sopp++) {\r
+ if (sopp->FileObject==FileObject || sopp->SharedCacheMap==SharedCacheMap)\r
+ break;\r
+ }\r
+ if (sopp>=SectionObjectPointer_cache+G_N_ELEMENTS(SectionObjectPointer_cache))\r
+ return NULL;\r
+ if (sopp==SectionObjectPointer_cache+SectionObjectPointer_cache_used)\r
+ SectionObjectPointer_cache_used++;\r
+ sopp->FileObject=FileObject;\r
+ sopp->SharedCacheMap=SharedCacheMap;\r
+ return sopp;\r
+}\r
+\r
+static FILE_OBJECT *SectionObjectPointer_find(SECTION_OBJECT_POINTERS *SectionObjectPointer)\r
+{\r
+struct SectionObjectPointer *sopp;\r
+PVOID SharedCacheMap;\r
+\r
+ if (!SectionObjectPointer)\r
+ return NULL;\r
+ if (!(SharedCacheMap=SectionObjectPointer->SharedCacheMap))\r
+ return NULL;\r
+ for (sopp=SectionObjectPointer_cache;sopp<SectionObjectPointer_cache+SectionObjectPointer_cache_used;sopp++) {\r
+ if (sopp->SharedCacheMap==SharedCacheMap)\r
+ return sopp->FileObject;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+static void dump_FileObject(FILE_OBJECT *FileObject)\r
+{\r
+ if (!FileObject) {\r
+ DBGSINGLE0("FileObject=NULL");\r
+ return;\r
+ }\r
+ DBGSINGLE4("FileObject=0x%lX: FileName=%s,Flags=0x%lX,SectionObjectPointer->SharedCacheMap=0x%lX",\r
+ (long)FileObject,\r
+ dbg_unicode_string(&FileObject->FileName),FileObject->Flags,\r
+ (!FileObject->SectionObjectPointer ? -1 : (long)FileObject->SectionObjectPointer->SharedCacheMap));\r
+ SectionObjectPointer_set(FileObject);\r
+}\r
+\r
+static void dump_irp_mj(struct _DEVICE_OBJECT *DeviceObject,struct _IRP *Irp)\r
{\r
IO_STACK_LOCATION *IoStackLocation;\r
-FILE_OBJECT *FileObject;\r
\r
if (!Irp) {\r
DBGSINGLE0("Irp==NULL");\r
DBGSINGLE0("IoStackLocation==NULL");\r
return;\r
}\r
- if (!(FileObject=IoStackLocation->FileObject))\r
- DBGSINGLE0("FileObject=NULL");\r
- else\r
- DBGSINGLE5("FileObject=0x%lX: FileName=%s,Flags=0x%lX,SectionObjectPointer=0x%lX,->SharedCacheMap=0x%lX",\r
- (long)FileObject,\r
- dbg_unicode_string(&FileObject->FileName),FileObject->Flags,\r
- (long)FileObject->SectionObjectPointer,\r
- (!FileObject->SectionObjectPointer ? -1 : (long)FileObject->SectionObjectPointer->SharedCacheMap));\r
+ dump_FileObject(IoStackLocation->FileObject);\r
+ \r
switch (IoStackLocation->MajorFunction) {\r
case IRP_MJ_READ:\r
DBGSINGLE2("READ: ByteOffset=0x%lX,Length=0x%lX",\r
DBGSINGLE2("FILE_SYSTEM_CONTROL: MinorFunction=%s (%d)",\r
((1\r
&& IoStackLocation->MinorFunction>=0\r
- && IoStackLocation->MinorFunction<G_N_ELEMENTS(irp_mj_dump_FILE_SYSTEM_CONTROL_MinorFunction_names))\r
- ? irp_mj_dump_FILE_SYSTEM_CONTROL_MinorFunction_names[IoStackLocation->MinorFunction] : "???"),\r
+ && IoStackLocation->MinorFunction<G_N_ELEMENTS(dump_irp_mj_FILE_SYSTEM_CONTROL_MinorFunction_names))\r
+ ? dump_irp_mj_FILE_SYSTEM_CONTROL_MinorFunction_names[IoStackLocation->MinorFunction] : "???"),\r
IoStackLocation->MinorFunction);\r
switch (IoStackLocation->MinorFunction) {\r
case IRP_MN_USER_FS_REQUEST: {\r
NTSTATUS r; \\r
\\r
DBGSINGLEENTER0( #irp_mj_name ); \\r
- irp_mj_dump(DeviceObject,Irp); \\r
+ dump_irp_mj(DeviceObject,Irp); \\r
r=(*tracefs_major_##irp_mj_name##_orig)(DeviceObject,Irp); \\r
DBGSINGLELEAVE1( #irp_mj_name ": r=0x%lX",(long)r); \\r
return r; \\r
\r
DBGSINGLEENTER4("CcCanIWrite: FileObject=0x%lX,BytesToWrite=0x%lX,Wait=%d,Retrying=%d",\r
(long)FileObject,BytesToWrite,Wait,Retrying);\r
+ dump_FileObject(FileObject);\r
r=CcCanIWrite (\r
FileObject,\r
BytesToWrite,\r
\r
DBGSINGLEENTER5("CcCopyRead: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Wait=%d,Buffer=0x%lX",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Wait,(long)Buffer);\r
+ dump_FileObject(FileObject);\r
r=CcCopyRead (\r
FileObject,\r
FileOffset,\r
\r
DBGSINGLEENTER5("CcCopyWrite: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Wait=%d,Buffer=0x%lX",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Wait,(long)Buffer);\r
+ dump_FileObject(FileObject);\r
r=CcCopyWrite (\r
FileObject,\r
FileOffset,\r
"BytesToWrite=0x%lX,Retrying=%d",\r
(long)FileObject,(long)PostRoutine,(long)Context1,(long)Context2,\r
BytesToWrite,Retrying);\r
+ dump_FileObject(FileObject);\r
CcDeferWrite (\r
FileObject,\r
PostRoutine,\r
{\r
DBGSINGLEENTER5("CcFastCopyRead: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,PageCount=0x%lX,Buffer=0x%lX",\r
(long)FileObject,FileOffset,Length,PageCount,(long)Buffer);\r
+ dump_FileObject(FileObject);\r
CcFastCopyRead (\r
FileObject,\r
FileOffset,\r
{\r
DBGSINGLEENTER4("CcFastCopyWrite: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Buffer=0x%lX",\r
(long)FileObject,FileOffset,Length,(long)Buffer);\r
+ dump_FileObject(FileObject);\r
CcFastCopyWrite (\r
FileObject,\r
FileOffset,\r
(long)SectionObjectPointer,\r
(!SectionObjectPointer ? -1 : (long)SectionObjectPointer->SharedCacheMap),\r
(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length);\r
+ dump_FileObject(SectionObjectPointer_find(SectionObjectPointer));\r
CcFlushCache (\r
SectionObjectPointer,\r
FileOffset,\r
Length,\r
IoStatus\r
);\r
+ dump_FileObject(SectionObjectPointer_find(SectionObjectPointer));\r
DBGSINGLELEAVE2("CcFlushCache: IoStatus->Status=0x%lX,IoStatus->Information=0x%lX",\r
(!IoStatus ? -1 : (long)IoStatus->Status),(!IoStatus ? -1 : (long)IoStatus->Information));\r
}\r
"OldestLsn=0x%lX,NewestLsn=0x%lX,Context1,Context2",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,\r
(!OldestLsn ? -1 : (long)OldestLsn->QuadPart),(!NewestLsn ? -1 : (long)NewestLsn->QuadPart));\r
+ dump_FileObject(FileObject);\r
(*TcGetDirtyPages_DirtyPageRoutine_orig)(FileObject,FileOffset,Length,OldestLsn,NewestLsn,Context1,Context2);\r
DBGSINGLELEAVE0("DirtyPageRoutine");\r
}\r
\r
DBGSINGLEENTER3("AcquireForLazyWrite: FileObject=0x%lX,Context=0x%lX,Wait=%d",\r
(long)callbacksp->FileObject,(long)callbacksp->LazyWriteContext,Wait);\r
+ dump_FileObject(callbacksp->FileObject);\r
r=(*callbacksp->Callbacks.AcquireForLazyWrite)(callbacksp->LazyWriteContext,Wait);\r
DBGSINGLELEAVE1("AcquireForLazyWrite: r=%d",r);\r
return r;\r
\r
DBGSINGLEENTER2("ReleaseFromLazyWrite: FileObject=0x%lX,Context=0x%lX",\r
(long)callbacksp->FileObject,(long)callbacksp->LazyWriteContext);\r
+ dump_FileObject(callbacksp->FileObject);\r
(*callbacksp->Callbacks.ReleaseFromLazyWrite)(callbacksp->LazyWriteContext);\r
DBGSINGLELEAVE0("ReleaseFromLazyWrite");\r
}\r
\r
DBGSINGLEENTER3("AcquireForReadAhead: FileObject=0x%lX,Context=0x%lX,Wait=%d",\r
(long)callbacksp->FileObject,(long)callbacksp->LazyWriteContext,Wait);\r
+ dump_FileObject(callbacksp->FileObject);\r
r=(*callbacksp->Callbacks.AcquireForReadAhead)(callbacksp->LazyWriteContext,Wait);\r
DBGSINGLELEAVE1("AcquireForReadAhead: r=%d",r);\r
return r;\r
\r
DBGSINGLEENTER2("ReleaseFromReadAhead: FileObject=0x%lX,Context=0x%lX",\r
(long)callbacksp->FileObject,(long)callbacksp->LazyWriteContext);\r
+ dump_FileObject(callbacksp->FileObject);\r
(*callbacksp->Callbacks.ReleaseFromReadAhead)(callbacksp->LazyWriteContext);\r
DBGSINGLELEAVE0("ReleaseFromReadAhead");\r
}\r
(!FileSizes ? -1 : (long)FileSizes->FileSize.QuadPart),\r
(!FileSizes ? -1 : (long)FileSizes->ValidDataLength.QuadPart),\r
PinAccess);\r
+ dump_FileObject(FileObject);\r
if ((callbacksp=Callbacks_set(FileObject,Callbacks,LazyWriteContext))) {\r
Callbacks=&TcInitializeCacheMap_Callbacks;\r
LazyWriteContext=callbacksp;\r
Callbacks,\r
LazyWriteContext\r
);\r
+ dump_FileObject(FileObject);\r
DBGSINGLELEAVE0("CcInitializeCacheMap");\r
}\r
\r
\r
DBGSINGLEENTER4("CcMapData: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Flags=0x%lX",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Flags);\r
+ dump_FileObject(FileObject);\r
r=CcMapData (\r
FileObject,\r
FileOffset,\r
{\r
DBGSINGLEENTER3("CcMdlRead: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length);\r
+ dump_FileObject(FileObject);\r
CcMdlRead (\r
FileObject,\r
FileOffset,\r
{\r
DBGSINGLEENTER2("CcMdlReadComplete: FileObject=0x%lX,MdlChain=0x%lX",\r
(long)FileObject,(long)MdlChain);\r
+ dump_FileObject(FileObject);\r
CcMdlReadComplete (\r
FileObject,\r
MdlChain\r
{\r
DBGSINGLEENTER2("CcMdlWriteAbort: FileObject=0x%lX,MdlChain=0x%lX",\r
(long)FileObject,(long)MdlChain);\r
+ dump_FileObject(FileObject);\r
CcMdlWriteAbort (\r
FileObject,\r
MdlChain\r
{\r
DBGSINGLEENTER3("CcMdlWriteComplete: FileObject=0x%lX,FileOffset=0x%lX,MdlChain=0x%lX",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),(long)MdlChain);\r
+ dump_FileObject(FileObject);\r
CcMdlWriteComplete (\r
FileObject,\r
FileOffset,\r
\r
DBGSINGLEENTER4("CcPinMappedData: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Flags=0x%lX",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Flags);\r
+ dump_FileObject(FileObject);\r
r=CcPinMappedData (\r
FileObject,\r
FileOffset,\r
\r
DBGSINGLEENTER4("CcPinRead: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Flags=0x%lX",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Flags);\r
+ dump_FileObject(FileObject);\r
r=CcPinRead (\r
FileObject,\r
FileOffset,\r
{\r
DBGSINGLEENTER3("CcPrepareMdlWrite: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length);\r
+ dump_FileObject(FileObject);\r
CcPrepareMdlWrite (\r
FileObject,\r
FileOffset,\r
\r
DBGSINGLEENTER5("CcPreparePinWrite: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Zero=%d,Flags=0x%lX",\r
(long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Zero,Flags);\r
+ dump_FileObject(FileObject);\r
r=CcPreparePinWrite (\r
FileObject,\r
FileOffset,\r
(!SectionObjectPointer ? -1 : (long)SectionObjectPointer->SharedCacheMap),\r
(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,\r
UninitializeCacheMaps);\r
+ dump_FileObject(SectionObjectPointer_find(SectionObjectPointer));\r
r=CcPurgeCacheSection (\r
SectionObjectPointer,\r
FileOffset,\r
Length,\r
UninitializeCacheMaps\r
);\r
+ dump_FileObject(SectionObjectPointer_find(SectionObjectPointer));\r
DBGSINGLELEAVE1("CcPurgeCacheSection: r=%d",r);\r
return r;\r
}\r
{\r
DBGSINGLEENTER3("CcSetAdditionalCacheAttributes: FileObject=0x%lX,DisableReadAhead=%d,DisableWriteBehind=%d",\r
(long)FileObject,DisableReadAhead,DisableWriteBehind);\r
+ dump_FileObject(FileObject);\r
CcSetAdditionalCacheAttributes (\r
FileObject,\r
DisableReadAhead,\r
(!FileSizes ? -1 : (long)FileSizes->AllocationSize.QuadPart),\r
(!FileSizes ? -1 : (long)FileSizes->FileSize.QuadPart),\r
(!FileSizes ? -1 : (long)FileSizes->ValidDataLength.QuadPart));\r
+ dump_FileObject(FileObject);\r
CcSetFileSizes (\r
FileObject,\r
FileSizes\r
{\r
DBGSINGLEENTER3("CcSetLogHandleForFile: FileObject=0x%lX,LogHandle=0x%lX,FlushToLsnRoutine=0x%lX",\r
(long)FileObject,(long)LogHandle,(long)FlushToLsnRoutine);\r
+ dump_FileObject(FileObject);\r
if (LogHandle_set(LogHandle,FlushToLsnRoutine))\r
FlushToLsnRoutine=TcSetLogHandleForFile_FlushToLsnRoutine;\r
CcSetLogHandleForFile (\r
{\r
DBGSINGLEENTER2("CcSetReadAheadGranularity: FileObject=0x%lX,Granularity=0x%lX",\r
(long)FileObject,Granularity);\r
+ dump_FileObject(FileObject);\r
CcSetReadAheadGranularity (\r
FileObject,\r
Granularity\r
\r
DBGSINGLEENTER3("CcUninitializeCacheMap: FileObject=0x%lX,TruncateSize=0x%lX,UninitializeCompleteEvent=0x%lX",\r
(long)FileObject,(!TruncateSize ? -1 : (long)TruncateSize->QuadPart),(long)UninitializeCompleteEvent);\r
+ dump_FileObject(FileObject);\r
r=CcUninitializeCacheMap (\r
FileObject,\r
TruncateSize,\r
UninitializeCompleteEvent\r
);\r
+ dump_FileObject(FileObject);\r
DBGSINGLELEAVE1("CcUninitializeCacheMap: r=%d",r);\r
return r;\r
}\r
(!StartOffset ? -1 : (long)StartOffset->QuadPart),\r
(!EndOffset ? -1 : (long)EndOffset->QuadPart),\r
Wait);\r
+ dump_FileObject(FileObject);\r
r=CcZeroData (\r
FileObject,\r
StartOffset,\r