Source code of Windows XP (NT5)
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.

193 lines
3.5 KiB

  1. /*++
  2. Copyright (c) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. lock.c
  5. Abstract:
  6. Implements the !resource command.
  7. Author:
  8. Keith Moore (keithmo) 16-Jun-1999
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. //
  15. // Private types.
  16. //
  17. typedef struct _LOCK_OPTIONS
  18. {
  19. BOOLEAN Verbose;
  20. } LOCK_OPTIONS, *PLOCK_OPTIONS;
  21. //
  22. // Private prototypes.
  23. //
  24. BOOLEAN
  25. DumpResourceCallback(
  26. IN PLIST_ENTRY pRemoteListEntry,
  27. IN PVOID pContext
  28. );
  29. //
  30. // Public functions.
  31. //
  32. DECLARE_API( resource )
  33. /*++
  34. Routine Description:
  35. Dumps all resources.
  36. Arguments:
  37. None.
  38. Return Value:
  39. None.
  40. --*/
  41. {
  42. ULONG_PTR address;
  43. ULONG result;
  44. LOCK_OPTIONS options;
  45. SNAPSHOT_EXTENSION_DATA();
  46. if (!IsThisACheckedBuild() || !DBG)
  47. {
  48. dprintf( "resource: command valid on checked builds only!\n" );
  49. return;
  50. }
  51. #if DBG
  52. //
  53. // Process the arguments.
  54. //
  55. options.Verbose = FALSE;
  56. if (_strnicmp( args, "-v", 2 ) == 0)
  57. {
  58. options.Verbose = TRUE;
  59. }
  60. //
  61. // Snag the list head address.
  62. //
  63. address = GetExpression( "&http!g_DbgGlobalResourceListHead" );
  64. if (address == 0)
  65. {
  66. dprintf( "resource: cannot find http!g_DbgGlobalResourceListHead\n" );
  67. return;
  68. }
  69. EnumLinkedList(
  70. (PLIST_ENTRY)address,
  71. &DumpResourceCallback,
  72. &options
  73. );
  74. #endif
  75. } // resource
  76. //
  77. // Private functions.
  78. //
  79. BOOLEAN
  80. DumpResourceCallback(
  81. IN PLIST_ENTRY pRemoteListEntry,
  82. IN PVOID pContext
  83. )
  84. {
  85. #if DBG
  86. PLOCK_OPTIONS pOptions;
  87. UL_ERESOURCE localResource;
  88. PUL_ERESOURCE pRemoteResource;
  89. ULONG result;
  90. BOOLEAN lockHeld;
  91. CHAR resourceState[MAX_RESOURCE_STATE_LENGTH];
  92. pOptions = (PLOCK_OPTIONS)pContext;
  93. pRemoteResource = CONTAINING_RECORD(
  94. pRemoteListEntry,
  95. UL_ERESOURCE,
  96. GlobalResourceListEntry
  97. );
  98. if (!ReadMemory(
  99. (ULONG_PTR)pRemoteResource,
  100. &localResource,
  101. sizeof(localResource),
  102. &result
  103. ))
  104. {
  105. dprintf( "resource: cannot read UL_ERESOURCE @ %p\n", pRemoteResource );
  106. return FALSE;
  107. }
  108. lockHeld = localResource.Resource.ActiveCount != 0;
  109. if (pOptions->Verbose || lockHeld)
  110. {
  111. dprintf(
  112. "UL_ERESOURCE @ %p\n"
  113. " Resource @ %p (%s)\n"
  114. " GlobalResourceListEntry @ %p\n"
  115. " pExclusiveOwner = %p\n"
  116. " pPreviousOwner = %p\n"
  117. " ExclusiveCount = %lu\n"
  118. " SharedCount = %lu\n"
  119. " ReleaseCount = %lu\n"
  120. " ContentionCount = %lu\n"
  121. " ResourceName = %s\n"
  122. " OwnerTag = %08lx\n"
  123. "\n",
  124. pRemoteResource,
  125. REMOTE_OFFSET( pRemoteResource, UL_ERESOURCE, Resource ),
  126. BuildResourceState( &localResource, resourceState ),
  127. REMOTE_OFFSET( pRemoteResource, UL_ERESOURCE, GlobalResourceListEntry ),
  128. localResource.pExclusiveOwner,
  129. localResource.pPreviousOwner,
  130. localResource.ExclusiveCount,
  131. localResource.SharedCount,
  132. localResource.ReleaseCount,
  133. localResource.Resource.ContentionCount,
  134. localResource.ResourceName,
  135. localResource.OwnerTag
  136. );
  137. }
  138. #endif
  139. return TRUE;
  140. } // DumpResourceCallback