|
|
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
kdcd.c
Abstract:
Cluster Disk driver KD extension - based on Vert's skeleton
Author:
John Vert (jvert) 6-Aug-1992
Revision History:
--*/
#include "precomp.h"
PCHAR DiskStateTitles[] = { "Offline", "Online", " *** Failed *** ", " *** Stalled *** " };
PCHAR BusTypeTitles[] = { "Root", "SCSI", "Unknown" };
#define IRP_LIST_MAX 20
//
// globals
//
EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER, 0 }; WINDBG_EXTENSION_APIS ExtensionApis; USHORT SavedMajorVersion; USHORT SavedMinorVersion;
#define TrueOrFalse( _x ) ( _x ? "True" : "False" )
/* forwards */
BOOL ReadTargetMemory( PVOID TargetAddress, PVOID LocalBuffer, ULONG BytesToRead );
__inline PCHAR ListInUse( PLIST_ENTRY, PLIST_ENTRY );
__inline PCHAR TrueFalse( BOOLEAN Value );
/* end forwards */
DllInit( HANDLE hModule, DWORD dwReason, DWORD dwReserved ) { switch (dwReason) { case DLL_THREAD_ATTACH: break;
case DLL_THREAD_DETACH: break;
case DLL_PROCESS_DETACH: break;
case DLL_PROCESS_ATTACH: break; }
return TRUE; }
VOID WinDbgExtensionDllInit( PWINDBG_EXTENSION_APIS lpExtensionApis, USHORT MajorVersion, USHORT MinorVersion ) { ExtensionApis = *lpExtensionApis;
SavedMajorVersion = MajorVersion; SavedMinorVersion = MinorVersion;
return; }
DECLARE_API( cdversion ) { #if DBG
PCHAR DebuggerType = "Checked"; #else
PCHAR DebuggerType = "Free"; #endif
dprintf("%s Extension dll for Build %d debugging %s kernel for Build %d\n", DebuggerType, VER_PRODUCTBUILD, SavedMajorVersion == 0x0c ? "Checked" : "Free", SavedMinorVersion ); }
VOID CheckVersion( VOID ) { #if DBG
if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) { dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n", VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" ); } #else
if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) { dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n", VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" ); } #endif
}
LPEXT_API_VERSION ExtensionApiVersion( VOID ) { return &ApiVersion; }
VOID Dump_DrvObj( IN PDRIVER_OBJECT DriverObject ) /*
* dump all the devobjs and devexts */ { PCLUS_DEVICE_EXTENSION DevExtension; PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT TargetDevObject; DRIVER_OBJECT LocalDriverObject; DEVICE_OBJECT LocalDeviceObject; CLUS_DEVICE_EXTENSION LocalDevExtension;
//
// read memory from target machine
//
if ( !ReadTargetMemory((PVOID)DriverObject, (PVOID)&LocalDriverObject, sizeof(DRIVER_OBJECT))) { return; }
dprintf( "DriverObject @ %08X\n", DriverObject );
DeviceObject = LocalDriverObject.DeviceObject;
while ( DeviceObject ) { if ( !ReadTargetMemory((PVOID)DeviceObject, (PVOID)&LocalDeviceObject, sizeof(DEVICE_OBJECT))) { return; }
TargetDevObject = NULL; DevExtension = LocalDeviceObject.DeviceExtension;
if ( DevExtension ) { if ( !ReadTargetMemory((PVOID)DevExtension, (PVOID)&LocalDevExtension, sizeof(CLUS_DEVICE_EXTENSION))) { return; } TargetDevObject = LocalDevExtension.TargetDeviceObject; }
dprintf( " DevObj/DevExt/TargetDev: %08X, %08X, %08X\n", DeviceObject, DevExtension, TargetDevObject ); DeviceObject = LocalDeviceObject.NextDevice; } // while
return;
} // Dump_DrvObj
DECLARE_API( cddrvobj ) /*
* dump all the devobjs and devexts */ { PDRIVER_OBJECT DriverObject; PCLUS_DEVICE_EXTENSION DevExtension; PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT TargetDevObject; DRIVER_OBJECT LocalDriverObject; DEVICE_OBJECT LocalDeviceObject; CLUS_DEVICE_EXTENSION LocalDevExtension;
DriverObject = (PDRIVER_OBJECT)GetExpression( args );
if ( !DriverObject ) {
dprintf("bad string conversion (%s) \n", args ); dprintf("try !object \\device\\clusdisk0 \n"); return; }
Dump_DrvObj( DriverObject );
return;
} // drvobj
VOID Dump_DevExt( IN PCLUS_DEVICE_EXTENSION TargetExt ) /*
* dump the clusdisk extension structure */ { CLUS_DEVICE_EXTENSION LocalExt; BOOL success; LONG BytesRead; WCHAR LocalDeviceName[512];
//
// read memory from target machine
//
if ( !ReadTargetMemory((PVOID)TargetExt, (PVOID)&LocalExt, sizeof(CLUS_DEVICE_EXTENSION))) { return; }
dprintf( " Extension @ %08X\n", TargetExt ); dprintf( " This extension's DevObj = %08X\n", LocalExt.DeviceObject ); dprintf( " Target DevObj = %08X\n", LocalExt.TargetDeviceObject ); dprintf( " Physical (Part0) DevObj = %08X", LocalExt.PhysicalDevice ); if ( LocalExt.DeviceObject == LocalExt.PhysicalDevice ) { dprintf( " [ This device is the physical device ] \n" ); } else { dprintf( " \n" ); } dprintf( " Scsi Address = Port %u Path %u Target %u Lun %u\n", LocalExt.ScsiAddress.PortNumber, LocalExt.ScsiAddress.PathId, LocalExt.ScsiAddress.TargetId, LocalExt.ScsiAddress.Lun);
dprintf( " Signature = %08X\n", LocalExt.Signature ); dprintf( " Disk number = %08X (%u)\n", LocalExt.DiskNumber, LocalExt.DiskNumber );
dprintf( " Disk State = %s **** \n", ( LocalExt.DiskState <= DiskStateMaximum ? DiskStateTitles[LocalExt.DiskState] : "Out of Range"));
dprintf( " Reservation Timer = %08X\n", LocalExt.ReserveTimer ); dprintf( " Last reserve time = %I64X\n", LocalExt.LastReserve ); dprintf( " Event @ %08X\n", &TargetExt->Event ); dprintf( " Cluster Bus Type = %s\n", (LocalExt.BusType <= UnknownBus ? BusTypeTitles[LocalExt.BusType] : "Out of Range"));
dprintf( " Last Reserve Status = %08X\n", LocalExt.ReserveFailure ); dprintf( " HoldIO @ %08X \n", &TargetExt->HoldIO ); dprintf( " %s\n", ListInUse( &LocalExt.HoldIO, (PLIST_ENTRY)&TargetExt->HoldIO )); dprintf( " WaitingIoctls @ %08X\n", &TargetExt->WaitingIoctls ); dprintf( " %s\n", ListInUse( &LocalExt.WaitingIoctls, (PLIST_ENTRY)&TargetExt->WaitingIoctls ));
dprintf( " WorkItem @ %08X\n", &TargetExt->WorkItem );
dprintf( " Perform Reserves = %s\n", TrueOrFalse( LocalExt.PerformReserves )); dprintf( " Timer Busy = %s\n", TrueOrFalse( LocalExt.TimerBusy ));
dprintf( " AttachValid = %s\n", TrueOrFalse( LocalExt.AttachValid )); dprintf( " Detached = %s\n", TrueOrFalse( LocalExt.Detached ));
dprintf( " Driver Object = %08X\n", LocalExt.DriverObject );
dprintf( " Last Partition Number = %u\n", LocalExt.LastPartitionNumber ); dprintf( " Disk Notification Entry = %08X\n", LocalExt.DiskNotificationEntry ); dprintf( " Vol Notification Entry = %08X\n", LocalExt.VolumeNotificationEntry );
dprintf( " Sector Size = %u\n", LocalExt.SectorSize ); dprintf( " Arbitration Sector = %u\n", LocalExt.ArbitrationSector );
dprintf( " Last Write Time (approx) = %I64X \n", LocalExt.LastWriteTime ); dprintf( " VolumeHandles @ %08X \n", &TargetExt->VolumeHandles ); dprintf( " RemoveLock @ %08X [use !remlock] \n", &TargetExt->RemoveLock ); #if 0
if ( ReadTargetMemory((PVOID)LocalExt.DeviceName, (PVOID)&LocalDeviceName, sizeof(LocalDeviceName))) {
dprintf( " DeviceName = %ws\n", LocalDeviceName ); } else { dprintf( " DeviceName @ %08X\n", LocalExt.DeviceName ); } #endif
dprintf( " Paging event @ %08X \n", &TargetExt->PagingPathCountEvent ); dprintf( " Paging path count = %08X \n", LocalExt.PagingPathCount ); dprintf( " Hibernation path count = %08X \n", LocalExt.HibernationPathCount ); dprintf( " Dump path count = %08X \n", LocalExt.DumpPathCount );
dprintf( " ReclaimInProgress = %08X \n", LocalExt.ReclaimInProgress );
dprintf(" \n");
return; }
VOID Dump_All( IN PDRIVER_OBJECT DriverObject ) /*
* dump all the devobjs and devexts fully */ { PCLUS_DEVICE_EXTENSION DevExtension; PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT TargetDevObject; DRIVER_OBJECT LocalDriverObject; DEVICE_OBJECT LocalDeviceObject; CLUS_DEVICE_EXTENSION LocalDevExtension;
//
// read memory from target machine
//
if ( !ReadTargetMemory((PVOID)DriverObject, (PVOID)&LocalDriverObject, sizeof(DRIVER_OBJECT))) { return; }
dprintf( "DriverObject @ %08X\n\n", DriverObject );
DeviceObject = LocalDriverObject.DeviceObject;
while ( DeviceObject ) { if ( !ReadTargetMemory((PVOID)DeviceObject, (PVOID)&LocalDeviceObject, sizeof(DEVICE_OBJECT))) { return; }
TargetDevObject = NULL; DevExtension = LocalDeviceObject.DeviceExtension;
if ( DevExtension ) { if ( !ReadTargetMemory((PVOID)DevExtension, (PVOID)&LocalDevExtension, sizeof(CLUS_DEVICE_EXTENSION))) { return; } TargetDevObject = LocalDevExtension.TargetDeviceObject; }
dprintf( "--- \n"); dprintf( " DevObj/DevExt/TargetDev @ %08X, %08X, %08X\n", DeviceObject, DevExtension, TargetDevObject ); if ( DevExtension ) { Dump_DevExt( DevExtension ); } DeviceObject = LocalDeviceObject.NextDevice; } // while
return;
} // Dump_All
DECLARE_API( cddevext ) /*
* dump the clusdisk extension structure */ { PCLUS_DEVICE_EXTENSION TargetExt; CLUS_DEVICE_EXTENSION LocalExt; BOOL success; LONG BytesRead; WCHAR LocalDeviceName[512]; //
// get address of RGP symbol
//
TargetExt = (PCLUS_DEVICE_EXTENSION)GetExpression( args );
if ( !TargetExt ) {
dprintf("bad string conversion (%s) \n", args ); return; }
Dump_DevExt( TargetExt );
return; }
DECLARE_API( cddevobj ) /*
* dump the clusdisk extension structure for the specfied device object */ { PDEVICE_OBJECT deviceAddr; DEVICE_OBJECT deviceObject; ULONG result; //
// get address of RGP symbol
//
deviceAddr = (PDEVICE_OBJECT)GetExpression( args ); if ( !deviceAddr ) { dprintf("bad string conversion (%s) \n", args ); return; } if ((!ReadMemory( (ULONG_PTR)deviceAddr, &deviceObject, sizeof(deviceObject), &result)) || result < sizeof(deviceObject)) { return; }
dprintf( "Device Object @ %08X \n", deviceAddr ); dprintf( " Driver Object @ %08X\n", deviceObject.DriverObject ); Dump_DevExt( deviceObject.DeviceExtension );
return; }
DECLARE_API( cddumpall ) /*
* dump all the devobjs and devexts */ { PDEVICE_OBJECT deviceAddr; PDEVICE_OBJECT deviceObject; DEVICE_OBJECT localDeviceObject;
ULONG result;
//
// Get clusdisk0 device object.
//
deviceAddr = (PDEVICE_OBJECT)GetExpression( "clusdisk!RootDeviceObject" ); if ( !deviceAddr ) { dprintf( "Can't get \\device\\clusdisk0 expression \n" ); return; }
//
// Get a copy of clusdisk0 device object.
//
if ((!ReadMemory( (ULONG_PTR) deviceAddr, &deviceObject, sizeof(deviceObject), &result)) || result < sizeof(deviceObject)) { dprintf( "Unable to read \\device\\clusdisk0 device object \n" ); return; }
dprintf( "ClusDisk0 DevObj @ %08X \n", deviceObject ); if ((!ReadMemory( (ULONG_PTR) deviceObject, &localDeviceObject, sizeof(localDeviceObject), &result)) || result < sizeof(localDeviceObject)) { dprintf( "Unable to read \\device\\clusdisk0 device object \n" ); return; }
// dprintf( " Driver Object @ %08X \n", localDeviceObject.DriverObject );
Dump_All( localDeviceObject.DriverObject );
return;
} // dumpall
DECLARE_API( cddevlist ) /*
* run down the device list dumping out the contents */ { PDEVICE_LIST_ENTRY targetDevList;
PDEVICE_OBJECT deviceAddr; DEVICE_LIST_ENTRY localDevList; PDEVICE_OBJECT deviceObject; DEVICE_OBJECT localDeviceObject; ULONG result; targetDevList = (PDEVICE_LIST_ENTRY)GetExpression( "clusdisk!ClusDiskDeviceList" );
if ( !targetDevList ) {
dprintf("Can't convert clusdisk!ClusDiskDeviceList symbol\n"); return; }
//
// Get clusdisk0 device object.
deviceAddr = (PDEVICE_OBJECT)GetExpression( "clusdisk!RootDeviceObject" ); if ( !deviceAddr ) { dprintf( "Can't get \\device\\clusdisk0 expression \n" ); return; }
//
// Get a copy of clusdisk0 device object.
//
if ((!ReadMemory( (ULONG_PTR) deviceAddr, &deviceObject, sizeof(deviceObject), &result)) || result < sizeof(deviceObject)) { dprintf( "Unable to read \\device\\clusdisk0 device object \n" ); return; }
dprintf( "ClusDisk0 Device Object @ %08X \n", deviceObject ); if ((!ReadMemory( (ULONG_PTR) deviceObject, &localDeviceObject, sizeof(localDeviceObject), &result)) || result < sizeof(localDeviceObject)) { dprintf( "Unable to read \\device\\clusdisk0 device object \n" ); return; }
dprintf( " Driver Object @ %08X \n", localDeviceObject.DriverObject );
//
// read head of device list's contents from other machine
//
if ( !ReadTargetMemory( targetDevList, &targetDevList, sizeof( PDEVICE_LIST_ENTRY ))) {
dprintf("Can't get ClusDiskDeviceList data\n"); return; }
while ( targetDevList != NULL ) {
if (CheckControlC()) { return; }
//
// read device list entry out of target's memory
//
if ( !ReadTargetMemory( targetDevList, &localDevList, sizeof( DEVICE_LIST_ENTRY ))) {
dprintf("Problem reading device list at %x\n", targetDevList ); return;
}
dprintf( "\nDeviceList @ %08X\n", targetDevList );
#if 0 // Not needed...
dprintf( " Next DeviceList @ %08X\n", localDevList.Next ); #endif
dprintf( " Signature = %08X\n", localDevList.Signature ); dprintf( " DeviceObject = %08X\n", localDevList.DeviceObject );
dprintf( " Attached = %s\n", TrueOrFalse( localDevList.Attached )); dprintf( " LettersAssigned = %s\n", TrueOrFalse( localDevList.LettersAssigned )); targetDevList = (PDEVICE_LIST_ENTRY)localDevList.Next; }
dprintf("\n"); } // devlist
BOOL ReadTargetMemory( PVOID TargetAddress, PVOID LocalBuffer, ULONG BytesToRead ) { BOOL success; ULONG BytesRead;
success = ReadMemory((ULONG_PTR)TargetAddress, LocalBuffer, BytesToRead, &BytesRead);
if (success) {
if (BytesRead != BytesToRead) {
dprintf("wrong byte count. expected=%d, read =%d\n", BytesToRead, BytesRead); }
} else { dprintf("Problem reading memory at %08X for %u bytes\n", TargetAddress, BytesToRead);
success = FALSE; }
return success; }
PCHAR ListInUse( PLIST_ENTRY ListToCheck, PLIST_ENTRY RealListAddress ) /*
* The Lists only hold IRPs! */ { PIRP Irp; IRP LocalIrp; PLIST_ENTRY Next; USHORT irpCount = 0;
if ( ListToCheck->Flink == RealListAddress ) { return( "(empty)" ); } else { dprintf( "\n" ); Next = ListToCheck->Flink; while ( Next != RealListAddress ) { Irp = CONTAINING_RECORD( Next, IRP, Tail.Overlay.ListEntry ); if ( !ReadTargetMemory((PVOID)Irp, (PVOID)&LocalIrp, sizeof(IRP))) { dprintf( "Failed to read irp @ %08X \n", Irp ); return(""); } dprintf( " ++ IRP: %08X\n", Irp ); Next = LocalIrp.Tail.Overlay.ListEntry.Flink; if ( irpCount++ > IRP_LIST_MAX ) { dprintf( " ++ Exceeded IRP max (possibly corrupt list) - stopping \n" ); break; } } return (""); } }
DECLARE_API( help ) { dprintf("Clusdisk kd extensions\n\n"); dprintf(" cddevlist - dump the clusdisk device list\n"); dprintf(" cddevext <address> - dump a devobj's extension structure\n"); dprintf(" cddrvobj <address> - dump the driver object\n"); dprintf(" cddevobj <address> - dump the devobj's extension\n"); dprintf(" cddumpall - dump all devobj extensions, given a drvobj address\n\n");
return; }
|