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.

123 lines
4.0 KiB

  1. // @doc
  2. /**********************************************************************
  3. *
  4. * @module RemLock.c |
  5. *
  6. * Implements Remove Lock utilities for keeping track of the driver.
  7. *
  8. * History
  9. * ----------------------------------------------------------
  10. * Mitchell S. Dernis Original
  11. *
  12. * (c) 1986-1998 Microsoft Corporation. All right reserved.
  13. *
  14. * @topic RemLock |
  15. * This module was written to make the numerous increments and
  16. * and decrements of Outstanding IO easier to manage.
  17. * An increment and a decrment (even the final one), is reduced
  18. * to a one line function everywhere. Furthermore, this module
  19. * can have traceouts turned on independently just for testing
  20. * this aspect of the driver.<nl>
  21. * This is similar to the IoAcquireRemoveLock, except that
  22. * to the best of my knowledge is not available on Win98.
  23. *
  24. **********************************************************************/
  25. #define __DEBUG_MODULE_IN_USE__ GCK_REMLOCK_C
  26. #include <wdm.h>
  27. #include "debug.h"
  28. #include "RemLock.h"
  29. DECLARE_MODULE_DEBUG_LEVEL((DBG_WARN|DBG_ERROR|DBG_CRITICAL));
  30. //DECLARE_MODULE_DEBUG_LEVEL((DBG_ALL));
  31. #if (DBG==1)
  32. void GCK_InitRemoveLockChecked(PGCK_REMOVE_LOCK pRemoveLock, PCHAR pcInstanceID)
  33. {
  34. pRemoveLock->pcInstanceID = pcInstanceID;
  35. GCK_DBG_TRACE_PRINT(("Initializing remove lock \'%s\' to one.\n", pRemoveLock->pcInstanceID));
  36. pRemoveLock->lRemoveLock = 1;
  37. KeInitializeEvent(&pRemoveLock->RemoveLockEvent, SynchronizationEvent, FALSE);
  38. }
  39. #else
  40. void GCK_InitRemoveLockFree(PGCK_REMOVE_LOCK pRemoveLock)
  41. {
  42. pRemoveLock->lRemoveLock = 1;
  43. KeInitializeEvent(&pRemoveLock->RemoveLockEvent, SynchronizationEvent, FALSE);
  44. }
  45. #endif
  46. void GCK_IncRemoveLock(PGCK_REMOVE_LOCK pRemoveLock)
  47. {
  48. LONG lNewCount = InterlockedIncrement(&pRemoveLock->lRemoveLock);
  49. GCK_DBG_TRACE_PRINT(("\'%s\', Incremented Remove Lock to %d.\n", pRemoveLock->pcInstanceID, lNewCount));
  50. }
  51. void GCK_DecRemoveLock(PGCK_REMOVE_LOCK pRemoveLock)
  52. {
  53. LONG lNewCount = InterlockedDecrement(&pRemoveLock->lRemoveLock);
  54. if (0 >= lNewCount)
  55. {
  56. GCK_DBG_TRACE_PRINT(("\'%s\', Last IRP completed.\n", pRemoveLock->pcInstanceID));
  57. KeSetEvent (&pRemoveLock->RemoveLockEvent, IO_NO_INCREMENT, FALSE);
  58. }
  59. GCK_DBG_TRACE_PRINT(("\'%s\', Decremented Remove Lock to %d\n", pRemoveLock->pcInstanceID, lNewCount));
  60. }
  61. NTSTATUS GCK_DecRemoveLockAndWait(PGCK_REMOVE_LOCK pRemoveLock, PLARGE_INTEGER plgiWaitTime)
  62. {
  63. NTSTATUS NtStatus = STATUS_SUCCESS;
  64. LONG lNewCount = InterlockedDecrement(&pRemoveLock->lRemoveLock);
  65. if (0 < lNewCount)
  66. {
  67. GCK_DBG_TRACE_PRINT(("\'%s\', Decremented Remove Lock to %d, waiting for final unlock.\n",
  68. pRemoveLock->pcInstanceID,
  69. lNewCount));
  70. NtStatus = KeWaitForSingleObject (
  71. &pRemoveLock->RemoveLockEvent,
  72. Executive,
  73. KernelMode,
  74. FALSE,
  75. plgiWaitTime
  76. );
  77. }
  78. #if (DBG==1)
  79. if(STATUS_SUCCESS == NtStatus)
  80. {
  81. GCK_DBG_EXIT_PRINT(("\'%s\', GCK_DecRemoveLockAndWait exiting - Remove Lock went to zero.\n", pRemoveLock->pcInstanceID));
  82. }
  83. else
  84. {
  85. GCK_DBG_CRITICAL_PRINT(("\'%s\', Remove Lock is still %d, should be zero.\n", pRemoveLock->lRemoveLock));
  86. GCK_DBG_EXIT_PRINT(("\'%s\', GCK_DecRemoveLockAndWait exiting - timed out.\n", pRemoveLock->pcInstanceID));
  87. }
  88. #endif
  89. return NtStatus;
  90. }
  91. /*
  92. * Avoid bugchecks by requesting a failable mapping.
  93. * Error check that was added to calling functions is limited to
  94. * only avoiding partying on a NULL pointer. Correct functioning
  95. * is not expected.
  96. */
  97. PVOID GCK_GetSystemAddressForMdlSafe(PMDL MdlAddress)
  98. {
  99. PVOID buf = NULL;
  100. /*
  101. * Can't call MmGetSystemAddressForMdlSafe in a WDM driver,
  102. * so set the MDL_MAPPING_CAN_FAIL bit and check the result
  103. * of the mapping.
  104. */
  105. if (MdlAddress) {
  106. MdlAddress->MdlFlags |= MDL_MAPPING_CAN_FAIL;
  107. buf = MmGetSystemAddressForMdl(MdlAddress);
  108. MdlAddress->MdlFlags &= (~MDL_MAPPING_CAN_FAIL);
  109. }
  110. else {
  111. GCK_DBG_CRITICAL_PRINT(("MdlAddress passed into GetSystemAddress is NULL\n"));
  112. }
  113. return buf;
  114. }