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.

200 lines
4.3 KiB

  1. #include "precomp.h"
  2. #include "fsdiag.h"
  3. DEBUG_FILEZONE(ZONE_T120_MSMCSTCP);
  4. #include <initguid.h>
  5. #include <datguids.h>
  6. #include <nmqos.h>
  7. #include <t120qos.h>
  8. /* T120qos.cpp
  9. *
  10. * Copyright (c) 1997 by Microsoft Corporation
  11. *
  12. * Abstract:
  13. *
  14. * Global Variables:
  15. *
  16. * g_pIQoS - Global interface pointer to QoS interface
  17. * g_dwLastQoSCB - timestamp of last QoS notification obtained via GetTickCount
  18. * g_dwSentSinceLastQoS - bytes sent since last QoS notification (or epoch)
  19. *
  20. */
  21. // IQOS interface pointer and resources request
  22. LPIQOS g_pIQoS = NULL;
  23. T120RRQ g_aRRq;
  24. // Global last QoS notification time stamp
  25. DWORD g_dwLastQoSCB = 0;
  26. DWORD g_dwSentSinceLastQoS = 0;
  27. BOOL g_fResourcesRequested = FALSE;
  28. // NOTE: Since connections through this transport typically
  29. // consist of a single socket connection, followed by
  30. // disconnection, followed by multiple connections, the
  31. // following heuristic count is used to prevent on-off-on
  32. // initialization of QoS at the time the first call is started.
  33. // It represents the minimum number of socket connections that
  34. // must be initiated (without an intervening disconnect of all
  35. // connected sockets) before QoS initialization takes place.
  36. #define MIN_CONNECTION_COUNT (DEFAULT_NUMBER_OF_PRIORITIES - 1)
  37. WORD g_wConnectionCount = 0;
  38. // extern from transprt.cpp to detect no connections
  39. ///// QOS related stuff ///////////////////////////////////
  40. HRESULT CALLBACK QosNotifyDataCB (
  41. LPRESOURCEREQUESTLIST lpResourceRequestList,
  42. DWORD_PTR dwThis)
  43. {
  44. HRESULT hr=NOERROR;
  45. LPRESOURCEREQUESTLIST prrl=lpResourceRequestList;
  46. int i;
  47. int iBWUsageId;
  48. for (i=0, iBWUsageId = -1L; i<(int)lpResourceRequestList->cRequests; i++) {
  49. if (lpResourceRequestList->aRequests[i].resourceID ==
  50. RESOURCE_OUTGOING_BANDWIDTH)
  51. iBWUsageId = i;
  52. }
  53. if (iBWUsageId != -1L) {
  54. QoSLock();
  55. // Calculate effective bits-per second rate:
  56. //
  57. // 1000 milliseconds per second
  58. // 8 bits per byte
  59. //
  60. int nEffRate = MulDiv ( g_dwSentSinceLastQoS, 1000 * 8,
  61. GetTickCount() - g_dwLastQoSCB );
  62. // Report bandwidth usage to QoS:
  63. //
  64. // Are we using less than the available bandwidth?
  65. if ( ( nEffRate ) <
  66. lpResourceRequestList->aRequests[iBWUsageId].nUnitsMin )
  67. {
  68. // Request our effective usage
  69. lpResourceRequestList->aRequests[iBWUsageId].nUnitsMin = nEffRate;
  70. }
  71. else
  72. {
  73. // Request everything by not modifying nUnitsMin
  74. ;
  75. }
  76. g_dwLastQoSCB = GetTickCount();
  77. g_dwSentSinceLastQoS = 0;
  78. QoSUnlock();
  79. }
  80. return hr;
  81. }
  82. VOID InitializeQoS( VOID )
  83. {
  84. DWORD dwRes;
  85. HRESULT hRet;
  86. // Already initialized?
  87. if ( g_fResourcesRequested )
  88. return;
  89. // If the number of connections has not reached the
  90. // trigger count, defer QoS initialization (see MIN_CONNECTION_COUNT
  91. // comment above)
  92. if ( g_wConnectionCount < MIN_CONNECTION_COUNT )
  93. {
  94. g_wConnectionCount++;
  95. return;
  96. }
  97. // Initialize QoS. If it fails, that's Ok, we'll do without it.
  98. // No need to set the resource ourselves, this now done by the UI
  99. if (NULL == g_pIQoS)
  100. {
  101. if (0 != (hRet = CoCreateInstance( CLSID_QoS,NULL,
  102. CLSCTX_INPROC_SERVER,
  103. IID_IQoS,
  104. (void **) &g_pIQoS)))
  105. {
  106. WARNING_OUT (("Unable to initalize QoS: %x", hRet));
  107. g_pIQoS = (LPIQOS)NULL;
  108. // Tolerate failure, operate w/o QoS
  109. return;
  110. }
  111. }
  112. // Initialize our request for bandwidth usage.
  113. g_aRRq.cResourceRequests = 1;
  114. g_aRRq.aResourceRequest[0].resourceID = RESOURCE_OUTGOING_BANDWIDTH;
  115. g_aRRq.aResourceRequest[0].nUnitsMin = 0;
  116. // Register with the QoS module. Even if this call fails,
  117. // that's Ok, we'll do without the QoS support
  118. dwRes = (HRESULT)g_pIQoS->RequestResources((GUID *)&MEDIA_TYPE_T120DATA,
  119. (LPRESOURCEREQUESTLIST)&g_aRRq, QosNotifyDataCB, NULL );
  120. if ( 0 == dwRes )
  121. {
  122. g_fResourcesRequested = TRUE;
  123. }
  124. }
  125. VOID DeInitializeQoS( VOID )
  126. {
  127. if (NULL != g_pIQoS)
  128. {
  129. if ( g_fResourcesRequested )
  130. {
  131. g_pIQoS->ReleaseResources((GUID *)&MEDIA_TYPE_T120DATA,
  132. (LPRESOURCEREQUESTLIST)&g_aRRq);
  133. g_fResourcesRequested = FALSE;
  134. }
  135. g_wConnectionCount = 0;
  136. g_pIQoS->Release();
  137. g_pIQoS = NULL;
  138. }
  139. }
  140. VOID MaybeReleaseQoSResources( VOID )
  141. {
  142. if (g_pSocketList->IsEmpty())
  143. {
  144. if (NULL != g_pIQoS)
  145. {
  146. if ( g_fResourcesRequested )
  147. {
  148. g_pIQoS->ReleaseResources((GUID *)&MEDIA_TYPE_T120DATA,
  149. (LPRESOURCEREQUESTLIST)&g_aRRq);
  150. g_fResourcesRequested = FALSE;
  151. }
  152. }
  153. g_wConnectionCount = 0;
  154. }
  155. }
  156.