Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

720 lines
19 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. kdcd.c
  5. Abstract:
  6. Cluster Disk driver KD extension - based on Vert's skeleton
  7. Author:
  8. John Vert (jvert) 6-Aug-1992
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. PCHAR DiskStateTitles[] = {
  13. "Offline",
  14. "Online",
  15. " *** Failed *** ",
  16. " *** Stalled *** "
  17. };
  18. PCHAR BusTypeTitles[] = {
  19. "Root",
  20. "SCSI",
  21. "Unknown"
  22. };
  23. #define IRP_LIST_MAX 20
  24. //
  25. // globals
  26. //
  27. EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER, 0 };
  28. WINDBG_EXTENSION_APIS ExtensionApis;
  29. USHORT SavedMajorVersion;
  30. USHORT SavedMinorVersion;
  31. #define TrueOrFalse( _x ) ( _x ? "True" : "False" )
  32. /* forwards */
  33. BOOL
  34. ReadTargetMemory(
  35. PVOID TargetAddress,
  36. PVOID LocalBuffer,
  37. ULONG BytesToRead
  38. );
  39. __inline PCHAR
  40. ListInUse(
  41. PLIST_ENTRY,
  42. PLIST_ENTRY
  43. );
  44. __inline PCHAR
  45. TrueFalse(
  46. BOOLEAN Value
  47. );
  48. /* end forwards */
  49. DllInit(
  50. HANDLE hModule,
  51. DWORD dwReason,
  52. DWORD dwReserved
  53. )
  54. {
  55. switch (dwReason) {
  56. case DLL_THREAD_ATTACH:
  57. break;
  58. case DLL_THREAD_DETACH:
  59. break;
  60. case DLL_PROCESS_DETACH:
  61. break;
  62. case DLL_PROCESS_ATTACH:
  63. break;
  64. }
  65. return TRUE;
  66. }
  67. VOID
  68. WinDbgExtensionDllInit(
  69. PWINDBG_EXTENSION_APIS lpExtensionApis,
  70. USHORT MajorVersion,
  71. USHORT MinorVersion
  72. )
  73. {
  74. ExtensionApis = *lpExtensionApis;
  75. SavedMajorVersion = MajorVersion;
  76. SavedMinorVersion = MinorVersion;
  77. return;
  78. }
  79. DECLARE_API( cdversion )
  80. {
  81. #if DBG
  82. PCHAR DebuggerType = "Checked";
  83. #else
  84. PCHAR DebuggerType = "Free";
  85. #endif
  86. dprintf("%s Extension dll for Build %d debugging %s kernel for Build %d\n",
  87. DebuggerType,
  88. VER_PRODUCTBUILD,
  89. SavedMajorVersion == 0x0c ? "Checked" : "Free",
  90. SavedMinorVersion
  91. );
  92. }
  93. VOID
  94. CheckVersion(
  95. VOID
  96. )
  97. {
  98. #if DBG
  99. if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  100. dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n",
  101. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  102. }
  103. #else
  104. if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  105. dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
  106. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  107. }
  108. #endif
  109. }
  110. LPEXT_API_VERSION
  111. ExtensionApiVersion(
  112. VOID
  113. )
  114. {
  115. return &ApiVersion;
  116. }
  117. VOID
  118. Dump_DrvObj(
  119. IN PDRIVER_OBJECT DriverObject
  120. )
  121. /*
  122. * dump all the devobjs and devexts
  123. */
  124. {
  125. PCLUS_DEVICE_EXTENSION DevExtension;
  126. PDEVICE_OBJECT DeviceObject;
  127. PDEVICE_OBJECT TargetDevObject;
  128. DRIVER_OBJECT LocalDriverObject;
  129. DEVICE_OBJECT LocalDeviceObject;
  130. CLUS_DEVICE_EXTENSION LocalDevExtension;
  131. //
  132. // read memory from target machine
  133. //
  134. if ( !ReadTargetMemory((PVOID)DriverObject,
  135. (PVOID)&LocalDriverObject,
  136. sizeof(DRIVER_OBJECT))) {
  137. return;
  138. }
  139. dprintf( "DriverObject @ %08X\n", DriverObject );
  140. DeviceObject = LocalDriverObject.DeviceObject;
  141. while ( DeviceObject ) {
  142. if ( !ReadTargetMemory((PVOID)DeviceObject,
  143. (PVOID)&LocalDeviceObject,
  144. sizeof(DEVICE_OBJECT))) {
  145. return;
  146. }
  147. TargetDevObject = NULL;
  148. DevExtension = LocalDeviceObject.DeviceExtension;
  149. if ( DevExtension ) {
  150. if ( !ReadTargetMemory((PVOID)DevExtension,
  151. (PVOID)&LocalDevExtension,
  152. sizeof(CLUS_DEVICE_EXTENSION))) {
  153. return;
  154. }
  155. TargetDevObject = LocalDevExtension.TargetDeviceObject;
  156. }
  157. dprintf( " DevObj/DevExt/TargetDev: %08X, %08X, %08X\n",
  158. DeviceObject,
  159. DevExtension,
  160. TargetDevObject );
  161. DeviceObject = LocalDeviceObject.NextDevice;
  162. } // while
  163. return;
  164. } // Dump_DrvObj
  165. DECLARE_API( cddrvobj )
  166. /*
  167. * dump all the devobjs and devexts
  168. */
  169. {
  170. PDRIVER_OBJECT DriverObject;
  171. PCLUS_DEVICE_EXTENSION DevExtension;
  172. PDEVICE_OBJECT DeviceObject;
  173. PDEVICE_OBJECT TargetDevObject;
  174. DRIVER_OBJECT LocalDriverObject;
  175. DEVICE_OBJECT LocalDeviceObject;
  176. CLUS_DEVICE_EXTENSION LocalDevExtension;
  177. DriverObject = (PDRIVER_OBJECT)GetExpression( args );
  178. if ( !DriverObject ) {
  179. dprintf("bad string conversion (%s) \n", args );
  180. dprintf("try !object \\device\\clusdisk0 \n");
  181. return;
  182. }
  183. Dump_DrvObj( DriverObject );
  184. return;
  185. } // drvobj
  186. VOID
  187. Dump_DevExt(
  188. IN PCLUS_DEVICE_EXTENSION TargetExt
  189. )
  190. /*
  191. * dump the clusdisk extension structure
  192. */
  193. {
  194. CLUS_DEVICE_EXTENSION LocalExt;
  195. BOOL success;
  196. LONG BytesRead;
  197. WCHAR LocalDeviceName[512];
  198. //
  199. // read memory from target machine
  200. //
  201. if ( !ReadTargetMemory((PVOID)TargetExt,
  202. (PVOID)&LocalExt,
  203. sizeof(CLUS_DEVICE_EXTENSION))) {
  204. return;
  205. }
  206. dprintf( " Extension @ %08X\n", TargetExt );
  207. dprintf( " This extension's DevObj = %08X\n", LocalExt.DeviceObject );
  208. dprintf( " Target DevObj = %08X\n", LocalExt.TargetDeviceObject );
  209. dprintf( " Physical (Part0) DevObj = %08X", LocalExt.PhysicalDevice );
  210. if ( LocalExt.DeviceObject == LocalExt.PhysicalDevice ) {
  211. dprintf( " [ This device is the physical device ] \n" );
  212. } else {
  213. dprintf( " \n" );
  214. }
  215. dprintf( " Scsi Address = Port %u Path %u Target %u Lun %u\n",
  216. LocalExt.ScsiAddress.PortNumber,
  217. LocalExt.ScsiAddress.PathId,
  218. LocalExt.ScsiAddress.TargetId,
  219. LocalExt.ScsiAddress.Lun);
  220. dprintf( " Signature = %08X\n", LocalExt.Signature );
  221. dprintf( " Disk number = %08X (%u)\n", LocalExt.DiskNumber, LocalExt.DiskNumber );
  222. dprintf( " Disk State = %s **** \n", ( LocalExt.DiskState <= DiskStateMaximum ?
  223. DiskStateTitles[LocalExt.DiskState] :
  224. "Out of Range"));
  225. dprintf( " Reservation Timer = %08X\n", LocalExt.ReserveTimer );
  226. dprintf( " Last reserve time = %I64X\n", LocalExt.LastReserve );
  227. dprintf( " Event @ %08X\n", &TargetExt->Event );
  228. dprintf( " Cluster Bus Type = %s\n", (LocalExt.BusType <= UnknownBus ?
  229. BusTypeTitles[LocalExt.BusType] :
  230. "Out of Range"));
  231. dprintf( " Last Reserve Status = %08X\n", LocalExt.ReserveFailure );
  232. dprintf( " WaitingIoctls @ %08X\n", &TargetExt->WaitingIoctls );
  233. dprintf( " %s\n",
  234. ListInUse( &LocalExt.WaitingIoctls, (PLIST_ENTRY)&TargetExt->WaitingIoctls ));
  235. dprintf( " WorkItem @ %08X\n", &TargetExt->WorkItem );
  236. dprintf( " Perform Reserves = %s\n", TrueOrFalse( LocalExt.PerformReserves ));
  237. dprintf( " Timer Busy = %s\n", TrueOrFalse( LocalExt.TimerBusy ));
  238. dprintf( " AttachValid = %s\n", TrueOrFalse( LocalExt.AttachValid ));
  239. dprintf( " Detached = %s\n", TrueOrFalse( LocalExt.Detached ));
  240. dprintf( " Driver Object = %08X\n", LocalExt.DriverObject );
  241. dprintf( " Last Partition Number = %u\n", LocalExt.LastPartitionNumber );
  242. dprintf( " Disk Notification Entry = %08X\n", LocalExt.DiskNotificationEntry );
  243. dprintf( " Vol Notification Entry = %08X\n", LocalExt.VolumeNotificationEntry );
  244. dprintf( " Sector Size = %u\n", LocalExt.SectorSize );
  245. dprintf( " Arbitration Sector = %u\n", LocalExt.ArbitrationSector );
  246. dprintf( " Last Write Time (approx) = %I64X \n", LocalExt.LastWriteTime );
  247. dprintf( " VolumeHandles @ %08X \n", &TargetExt->VolumeHandles );
  248. dprintf( " RemoveLock @ %08X [use !remlock] \n", &TargetExt->RemoveLock );
  249. #if 0
  250. if ( ReadTargetMemory((PVOID)LocalExt.DeviceName,
  251. (PVOID)&LocalDeviceName,
  252. sizeof(LocalDeviceName))) {
  253. dprintf( " DeviceName = %ws\n", LocalDeviceName );
  254. } else {
  255. dprintf( " DeviceName @ %08X\n", LocalExt.DeviceName );
  256. }
  257. #endif
  258. dprintf( " Paging event @ %08X \n", &TargetExt->PagingPathCountEvent );
  259. dprintf( " Paging path count = %08X \n", LocalExt.PagingPathCount );
  260. dprintf( " Hibernation path count = %08X \n", LocalExt.HibernationPathCount );
  261. dprintf( " Dump path count = %08X \n", LocalExt.DumpPathCount );
  262. dprintf(" \n");
  263. return;
  264. }
  265. VOID
  266. Dump_All(
  267. IN PDRIVER_OBJECT DriverObject
  268. )
  269. /*
  270. * dump all the devobjs and devexts fully
  271. */
  272. {
  273. PCLUS_DEVICE_EXTENSION DevExtension;
  274. PDEVICE_OBJECT DeviceObject;
  275. PDEVICE_OBJECT TargetDevObject;
  276. DRIVER_OBJECT LocalDriverObject;
  277. DEVICE_OBJECT LocalDeviceObject;
  278. CLUS_DEVICE_EXTENSION LocalDevExtension;
  279. //
  280. // read memory from target machine
  281. //
  282. if ( !ReadTargetMemory((PVOID)DriverObject,
  283. (PVOID)&LocalDriverObject,
  284. sizeof(DRIVER_OBJECT))) {
  285. return;
  286. }
  287. dprintf( "DriverObject @ %08X\n\n", DriverObject );
  288. DeviceObject = LocalDriverObject.DeviceObject;
  289. while ( DeviceObject ) {
  290. if ( !ReadTargetMemory((PVOID)DeviceObject,
  291. (PVOID)&LocalDeviceObject,
  292. sizeof(DEVICE_OBJECT))) {
  293. return;
  294. }
  295. TargetDevObject = NULL;
  296. DevExtension = LocalDeviceObject.DeviceExtension;
  297. if ( DevExtension ) {
  298. if ( !ReadTargetMemory((PVOID)DevExtension,
  299. (PVOID)&LocalDevExtension,
  300. sizeof(CLUS_DEVICE_EXTENSION))) {
  301. return;
  302. }
  303. TargetDevObject = LocalDevExtension.TargetDeviceObject;
  304. }
  305. dprintf( "--- \n");
  306. dprintf( " DevObj/DevExt/TargetDev @ %08X, %08X, %08X\n",
  307. DeviceObject,
  308. DevExtension,
  309. TargetDevObject );
  310. if ( DevExtension ) {
  311. Dump_DevExt( DevExtension );
  312. }
  313. DeviceObject = LocalDeviceObject.NextDevice;
  314. } // while
  315. return;
  316. } // Dump_All
  317. DECLARE_API( cddevext )
  318. /*
  319. * dump the clusdisk extension structure
  320. */
  321. {
  322. PCLUS_DEVICE_EXTENSION TargetExt;
  323. CLUS_DEVICE_EXTENSION LocalExt;
  324. BOOL success;
  325. LONG BytesRead;
  326. WCHAR LocalDeviceName[512];
  327. //
  328. // get address of RGP symbol
  329. //
  330. TargetExt = (PCLUS_DEVICE_EXTENSION)GetExpression( args );
  331. if ( !TargetExt ) {
  332. dprintf("bad string conversion (%s) \n", args );
  333. return;
  334. }
  335. Dump_DevExt( TargetExt );
  336. return;
  337. }
  338. DECLARE_API( cddevobj )
  339. /*
  340. * dump the clusdisk extension structure for the specfied device object
  341. */
  342. {
  343. PDEVICE_OBJECT deviceAddr;
  344. DEVICE_OBJECT deviceObject;
  345. ULONG result;
  346. //
  347. // get address of RGP symbol
  348. //
  349. deviceAddr = (PDEVICE_OBJECT)GetExpression( args );
  350. if ( !deviceAddr ) {
  351. dprintf("bad string conversion (%s) \n", args );
  352. return;
  353. }
  354. if ((!ReadMemory( (ULONG_PTR)deviceAddr,
  355. &deviceObject,
  356. sizeof(deviceObject),
  357. &result)) || result < sizeof(deviceObject)) {
  358. return;
  359. }
  360. dprintf( "Device Object @ %08X \n", deviceAddr );
  361. dprintf( " Driver Object @ %08X\n", deviceObject.DriverObject );
  362. Dump_DevExt( deviceObject.DeviceExtension );
  363. return;
  364. }
  365. DECLARE_API( cddumpall )
  366. /*
  367. * dump all the devobjs and devexts
  368. */
  369. {
  370. PDEVICE_OBJECT deviceAddr;
  371. PDEVICE_OBJECT deviceObject;
  372. DEVICE_OBJECT localDeviceObject;
  373. ULONG result;
  374. //
  375. // Get clusdisk0 device object.
  376. //
  377. deviceAddr = (PDEVICE_OBJECT)GetExpression( "clusdisk!RootDeviceObject" );
  378. if ( !deviceAddr ) {
  379. dprintf( "Can't get \\device\\clusdisk0 expression \n" );
  380. return;
  381. }
  382. //
  383. // Get a copy of clusdisk0 device object.
  384. //
  385. if ((!ReadMemory( (ULONG_PTR) deviceAddr,
  386. &deviceObject,
  387. sizeof(deviceObject),
  388. &result)) || result < sizeof(deviceObject)) {
  389. dprintf( "Unable to read \\device\\clusdisk0 device object \n" );
  390. return;
  391. }
  392. dprintf( "ClusDisk0 DevObj @ %08X \n", deviceObject );
  393. if ((!ReadMemory( (ULONG_PTR) deviceObject,
  394. &localDeviceObject,
  395. sizeof(localDeviceObject),
  396. &result)) || result < sizeof(localDeviceObject)) {
  397. dprintf( "Unable to read \\device\\clusdisk0 device object \n" );
  398. return;
  399. }
  400. // dprintf( " Driver Object @ %08X \n", localDeviceObject.DriverObject );
  401. Dump_All( localDeviceObject.DriverObject );
  402. return;
  403. } // dumpall
  404. DECLARE_API( cddevlist )
  405. /*
  406. * run down the device list dumping out the contents
  407. */
  408. {
  409. PDEVICE_LIST_ENTRY targetDevList;
  410. PDEVICE_OBJECT deviceAddr;
  411. DEVICE_LIST_ENTRY localDevList;
  412. PDEVICE_OBJECT deviceObject;
  413. DEVICE_OBJECT localDeviceObject;
  414. ULONG result;
  415. targetDevList = (PDEVICE_LIST_ENTRY)GetExpression( "clusdisk!ClusDiskDeviceList" );
  416. if ( !targetDevList ) {
  417. dprintf("Can't convert clusdisk!ClusDiskDeviceList symbol\n");
  418. return;
  419. }
  420. //
  421. // Get clusdisk0 device object.
  422. deviceAddr = (PDEVICE_OBJECT)GetExpression( "clusdisk!RootDeviceObject" );
  423. if ( !deviceAddr ) {
  424. dprintf( "Can't get \\device\\clusdisk0 expression \n" );
  425. return;
  426. }
  427. //
  428. // Get a copy of clusdisk0 device object.
  429. //
  430. if ((!ReadMemory( (ULONG_PTR) deviceAddr,
  431. &deviceObject,
  432. sizeof(deviceObject),
  433. &result)) || result < sizeof(deviceObject)) {
  434. dprintf( "Unable to read \\device\\clusdisk0 device object \n" );
  435. return;
  436. }
  437. dprintf( "ClusDisk0 Device Object @ %08X \n", deviceObject );
  438. if ((!ReadMemory( (ULONG_PTR) deviceObject,
  439. &localDeviceObject,
  440. sizeof(localDeviceObject),
  441. &result)) || result < sizeof(localDeviceObject)) {
  442. dprintf( "Unable to read \\device\\clusdisk0 device object \n" );
  443. return;
  444. }
  445. dprintf( " Driver Object @ %08X \n", localDeviceObject.DriverObject );
  446. //
  447. // read head of device list's contents from other machine
  448. //
  449. if ( !ReadTargetMemory( targetDevList, &targetDevList, sizeof( PDEVICE_LIST_ENTRY ))) {
  450. dprintf("Can't get ClusDiskDeviceList data\n");
  451. return;
  452. }
  453. while ( targetDevList != NULL ) {
  454. if (CheckControlC()) {
  455. return;
  456. }
  457. //
  458. // read device list entry out of target's memory
  459. //
  460. if ( !ReadTargetMemory( targetDevList, &localDevList, sizeof( DEVICE_LIST_ENTRY ))) {
  461. dprintf("Problem reading device list at %x\n", targetDevList );
  462. return;
  463. }
  464. dprintf( "\nDeviceList @ %08X\n", targetDevList );
  465. #if 0 // Not needed...
  466. dprintf( " Next DeviceList @ %08X\n", localDevList.Next );
  467. #endif
  468. dprintf( " Signature = %08X\n", localDevList.Signature );
  469. dprintf( " DeviceObject = %08X\n", localDevList.DeviceObject );
  470. dprintf( " Attached = %s\n", TrueOrFalse( localDevList.Attached ));
  471. dprintf( " LettersAssigned = %s\n", TrueOrFalse( localDevList.LettersAssigned ));
  472. targetDevList = (PDEVICE_LIST_ENTRY)localDevList.Next;
  473. }
  474. dprintf("\n");
  475. } // devlist
  476. BOOL
  477. ReadTargetMemory(
  478. PVOID TargetAddress,
  479. PVOID LocalBuffer,
  480. ULONG BytesToRead
  481. )
  482. {
  483. BOOL success;
  484. ULONG BytesRead;
  485. success = ReadMemory((ULONG_PTR)TargetAddress, LocalBuffer, BytesToRead, &BytesRead);
  486. if (success) {
  487. if (BytesRead != BytesToRead) {
  488. dprintf("wrong byte count. expected=%d, read =%d\n", BytesToRead, BytesRead);
  489. }
  490. } else {
  491. dprintf("Problem reading memory at %08X for %u bytes\n",
  492. TargetAddress, BytesToRead);
  493. success = FALSE;
  494. }
  495. return success;
  496. }
  497. PCHAR
  498. ListInUse(
  499. PLIST_ENTRY ListToCheck,
  500. PLIST_ENTRY RealListAddress
  501. )
  502. /*
  503. * The Lists only hold IRPs!
  504. */
  505. {
  506. PIRP Irp;
  507. IRP LocalIrp;
  508. PLIST_ENTRY Next;
  509. USHORT irpCount = 0;
  510. if ( ListToCheck->Flink == RealListAddress ) {
  511. return( "(empty)" );
  512. } else {
  513. dprintf( "\n" );
  514. Next = ListToCheck->Flink;
  515. while ( Next != RealListAddress ) {
  516. Irp = CONTAINING_RECORD( Next,
  517. IRP,
  518. Tail.Overlay.ListEntry );
  519. if ( !ReadTargetMemory((PVOID)Irp,
  520. (PVOID)&LocalIrp,
  521. sizeof(IRP))) {
  522. dprintf( "Failed to read irp @ %08X \n", Irp );
  523. return("");
  524. }
  525. dprintf( " ++ IRP: %08X\n", Irp );
  526. Next = LocalIrp.Tail.Overlay.ListEntry.Flink;
  527. if ( irpCount++ > IRP_LIST_MAX ) {
  528. dprintf( " ++ Exceeded IRP max (possibly corrupt list) - stopping \n" );
  529. break;
  530. }
  531. }
  532. return ("");
  533. }
  534. }
  535. DECLARE_API( help )
  536. {
  537. dprintf("Clusdisk kd extensions\n\n");
  538. dprintf(" cddevlist - dump the clusdisk device list\n");
  539. dprintf(" cddevext <address> - dump a devobj's extension structure\n");
  540. dprintf(" cddrvobj <address> - dump the driver object\n");
  541. dprintf(" cddevobj <address> - dump the devobj's extension\n");
  542. dprintf(" cddumpall - dump all devobj extensions, given a drvobj address\n\n");
  543. return;
  544. }