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.

155 lines
3.6 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. obvutil.c
  5. Abstract:
  6. This module implements various utilities required to do driver verification.
  7. Author:
  8. Adrian J. Oney (adriao) 20-Apr-1998
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. AdriaO 06/15/2000 - Separated out from ntos\io\flunkirp.c
  13. --*/
  14. #include "obp.h"
  15. #include "obvutil.h"
  16. //
  17. // When enabled, everything is locked down on demand...
  18. //
  19. #ifdef ALLOC_PRAGMA
  20. #pragma alloc_text(PAGEVRFY, ObvUtilStartObRefMonitoring)
  21. #pragma alloc_text(PAGEVRFY, ObvUtilStopObRefMonitoring)
  22. #endif
  23. LONG_PTR
  24. ObvUtilStartObRefMonitoring(
  25. IN PDEVICE_OBJECT DeviceObject
  26. )
  27. /*++
  28. Description:
  29. Determines if ObRef has not been called between a call to this
  30. function and a subsequent call to ObvUtilStopObRefMonitoring.
  31. Arguments:
  32. Device object to monitor.
  33. Return Value:
  34. A start skew time to pass into ObvUtilStopObRefMonitoring.
  35. N.B. - A reference count is taken by this API and released
  36. by ObvUtilStopObRefMonitoring. That reference is not
  37. counted among the noticed calls to ObRef.
  38. --*/
  39. {
  40. #if DBG
  41. POBJECT_HEADER ObjectHeader;
  42. POBJECT_HEADER_NAME_INFO NameInfo;
  43. LONG_PTR startSkew, pointerCount ;
  44. ObReferenceObject(DeviceObject) ;
  45. ObjectHeader = OBJECT_TO_OBJECT_HEADER(DeviceObject);
  46. NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
  47. ASSERT(NameInfo) ;
  48. //
  49. // We will always decrement DbgDereferenceCount prior to PointerCount,
  50. // so any race conditions will look like an increment occured, which
  51. // is an allowable misread...
  52. //
  53. do {
  54. pointerCount = ObjectHeader->PointerCount ;
  55. startSkew = pointerCount - NameInfo->DbgDereferenceCount ;
  56. } while(pointerCount != ObjectHeader->PointerCount) ;
  57. return startSkew ;
  58. #else
  59. UNREFERENCED_PARAMETER (DeviceObject);
  60. return 1;
  61. #endif
  62. }
  63. LONG_PTR
  64. ObvUtilStopObRefMonitoring(
  65. IN PDEVICE_OBJECT DeviceObject,
  66. IN LONG StartSkew
  67. )
  68. /*++
  69. Description:
  70. Determines if ObRef has not been called between a call to
  71. ObvUtilStartObRefMonitoring and a call to this API.
  72. In a race condition (say ObDereferenceObject is ran in-simo
  73. with this function), the return is gaurenteed to err on
  74. the side of a reference occuring.
  75. Arguments:
  76. Device Object and the skew returned by ObvUtilStartObRefMonitoring
  77. Return Value:
  78. Number of calls to ObRef that occured throughout the monitored timeframe.
  79. Note that the return could be positive even though the reference count
  80. actually dropped (ie, one ObRef and two ObDeref's).
  81. --*/
  82. {
  83. #if DBG
  84. POBJECT_HEADER ObjectHeader;
  85. POBJECT_HEADER_NAME_INFO NameInfo;
  86. LONG_PTR currentSkew, refDelta, pointerCount ;
  87. ObjectHeader = OBJECT_TO_OBJECT_HEADER(DeviceObject);
  88. NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
  89. ASSERT(NameInfo) ;
  90. //
  91. // We will always decrement DbgDereferenceCount prior to PointerCount,
  92. // so any race conditions will look like an increment occured, which
  93. // is an allowable misread...
  94. //
  95. do {
  96. pointerCount = ObjectHeader->PointerCount ;
  97. currentSkew = pointerCount - NameInfo->DbgDereferenceCount ;
  98. } while(pointerCount != ObjectHeader->PointerCount) ;
  99. refDelta = currentSkew - StartSkew ;
  100. ASSERT(refDelta>=0) ;
  101. ObDereferenceObject(DeviceObject) ;
  102. return refDelta ;
  103. #else
  104. UNREFERENCED_PARAMETER (DeviceObject);
  105. UNREFERENCED_PARAMETER (StartSkew);
  106. return 1;
  107. #endif
  108. }