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.

245 lines
7.1 KiB

  1. /***************************************************************************
  2. *
  3. * Copyright (C) 2001 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dp8simsend.h
  6. *
  7. * Content: Header for send object class.
  8. *
  9. * History:
  10. * Date By Reason
  11. * ======== ======== =========
  12. * 04/23/01 VanceO Created.
  13. *
  14. ***************************************************************************/
  15. //=============================================================================
  16. // Defines
  17. //=============================================================================
  18. #define MAX_DATA_SIZE 1472 // prevent individual messages larger than one Ethernet frame - UDP headers
  19. //=============================================================================
  20. // Send object class
  21. //=============================================================================
  22. class CDP8SimSend
  23. {
  24. public:
  25. inline BOOL IsValidObject(void)
  26. {
  27. if ((this == NULL) || (IsBadWritePtr(this, sizeof(CDP8SimSend))))
  28. {
  29. return FALSE;
  30. }
  31. if (*((DWORD*) (&this->m_Sig)) != 0x534d4953) // 0x53 0x4d 0x49 0x53 = 'SMIS' = 'SIMS' in Intel order
  32. {
  33. return FALSE;
  34. }
  35. return TRUE;
  36. };
  37. static BOOL FPMAlloc(void* pvItem, void * pvContext)
  38. {
  39. CDP8SimSend * pDP8SimSend = (CDP8SimSend*) pvItem;
  40. pDP8SimSend->m_Sig[0] = 'S';
  41. pDP8SimSend->m_Sig[1] = 'I';
  42. pDP8SimSend->m_Sig[2] = 'M';
  43. pDP8SimSend->m_Sig[3] = 's'; // start with lower case so we can tell when it's in the pool or not
  44. pDP8SimSend->m_lRefCount = 0;
  45. pDP8SimSend->m_pDP8SimEndpoint = NULL;
  46. ZeroMemory(&pDP8SimSend->m_adpnbd, sizeof(pDP8SimSend->m_adpnbd));
  47. ZeroMemory(&pDP8SimSend->m_spsd, sizeof(pDP8SimSend->m_spsd));
  48. pDP8SimSend->m_dwLatencyAdded = 0;
  49. ZeroMemory(pDP8SimSend->m_abData, sizeof(pDP8SimSend->m_abData));
  50. return TRUE;
  51. }
  52. #undef DPF_MODNAME
  53. #define DPF_MODNAME "CDP8SimSend::FPMInitialize"
  54. static void FPMInitialize(void* pvItem, void * pvContext)
  55. {
  56. CDP8SimSend * pDP8SimSend = (CDP8SimSend*) pvItem;
  57. SPSENDDATA * pspsd = (SPSENDDATA*) pvContext;
  58. BYTE * pCurrent;
  59. DWORD dwTemp;
  60. pDP8SimSend->m_lRefCount++; // somebody is getting a pointer to this object
  61. DNASSERT(pDP8SimSend->m_lRefCount == 1);
  62. //
  63. // Reset the buffer descriptor array.
  64. //
  65. ZeroMemory(&pDP8SimSend->m_adpnbd, sizeof(pDP8SimSend->m_adpnbd));
  66. //pDP8SimSend->m_adpnbd[0].pBufferData = NULL;
  67. //pDP8SimSend->m_adpnbd[0].dwBufferSize = 0;
  68. pDP8SimSend->m_adpnbd[1].pBufferData = pDP8SimSend->m_abData;
  69. //pDP8SimSend->m_adpnbd[1].dwBufferSize = 0;
  70. //
  71. // Get an endpoint reference.
  72. //
  73. pDP8SimSend->m_pDP8SimEndpoint = (CDP8SimEndpoint*) pspsd->hEndpoint;
  74. DNASSERT(pDP8SimSend->m_pDP8SimEndpoint->IsValidObject());
  75. pDP8SimSend->m_pDP8SimEndpoint->AddRef();
  76. //
  77. // Copy the send data parameter block, modifying as necessary.
  78. //
  79. pDP8SimSend->m_spsd.hEndpoint = pDP8SimSend->m_pDP8SimEndpoint->GetRealSPEndpoint();
  80. pDP8SimSend->m_spsd.pBuffers = &(pDP8SimSend->m_adpnbd[1]); // leave the first buffer desc for the real SP to play with
  81. pDP8SimSend->m_spsd.dwBufferCount = 1;
  82. pDP8SimSend->m_spsd.dwFlags = pspsd->dwFlags;
  83. pDP8SimSend->m_spsd.pvContext = NULL; // this will be filled in later by SetSendDataBlockContext
  84. pDP8SimSend->m_spsd.hCommand = NULL; // this gets filled in by the real SP
  85. pDP8SimSend->m_spsd.dwCommandDescriptor = 0; // this gets filled in by the real SP
  86. //
  87. // Finally, copy the data into our contiguous local buffer.
  88. //
  89. pCurrent = pDP8SimSend->m_adpnbd[1].pBufferData;
  90. for(dwTemp = 0; dwTemp < pspsd->dwBufferCount; dwTemp++)
  91. {
  92. if ((pDP8SimSend->m_adpnbd[1].dwBufferSize + pspsd->pBuffers[dwTemp].dwBufferSize) > MAX_DATA_SIZE)
  93. {
  94. DPFX(DPFPREP, 0, "Data too large for single buffer!");
  95. DNASSERT(FALSE);
  96. }
  97. CopyMemory(pCurrent,
  98. pspsd->pBuffers[dwTemp].pBufferData,
  99. pspsd->pBuffers[dwTemp].dwBufferSize);
  100. pCurrent += pspsd->pBuffers[dwTemp].dwBufferSize;
  101. pDP8SimSend->m_adpnbd[1].dwBufferSize += pspsd->pBuffers[dwTemp].dwBufferSize;
  102. }
  103. //
  104. // Change the signature before handing it out.
  105. //
  106. pDP8SimSend->m_Sig[3] = 'S';
  107. }
  108. #undef DPF_MODNAME
  109. #define DPF_MODNAME "CDP8SimSend::FPMRelease"
  110. static void FPMRelease(void* pvItem)
  111. {
  112. CDP8SimSend * pDP8SimSend = (CDP8SimSend*) pvItem;
  113. DNASSERT(pDP8SimSend->m_lRefCount == 0);
  114. //
  115. // Release the endpoint reference.
  116. //
  117. DNASSERT(pDP8SimSend->m_pDP8SimEndpoint != NULL);
  118. pDP8SimSend->m_pDP8SimEndpoint->Release();
  119. pDP8SimSend->m_pDP8SimEndpoint = NULL;
  120. //
  121. // Change the signature before putting the object back in the pool.
  122. //
  123. pDP8SimSend->m_Sig[3] = 's';
  124. }
  125. #undef DPF_MODNAME
  126. #define DPF_MODNAME "CDP8SimSend::FPMDealloc"
  127. static void FPMDealloc(void* pvItem)
  128. {
  129. const CDP8SimSend * pDP8SimSend = (CDP8SimSend*) pvItem;
  130. DNASSERT(pDP8SimSend->m_lRefCount == 0);
  131. DNASSERT(pDP8SimSend->m_pDP8SimEndpoint == NULL);
  132. }
  133. #undef DPF_MODNAME
  134. #define DPF_MODNAME "CDP8SimSend::AddRef"
  135. inline void AddRef(void)
  136. {
  137. LONG lResult;
  138. lResult = InterlockedIncrement(&this->m_lRefCount);
  139. DNASSERT(lResult > 0);
  140. DPFX(DPFPREP, 9, "Send 0x%p refcount = %u.", this, lResult);
  141. };
  142. #undef DPF_MODNAME
  143. #define DPF_MODNAME "CDP8SimSend::Release"
  144. inline void Release(void)
  145. {
  146. LONG lResult;
  147. lResult = InterlockedDecrement(&this->m_lRefCount);
  148. DNASSERT(lResult >= 0);
  149. if (lResult == 0)
  150. {
  151. DPFX(DPFPREP, 9, "Send 0x%p refcount = 0, returning to pool.", this);
  152. //
  153. // Time to return this object to the pool.
  154. //
  155. g_FPOOLSend.Release(this);
  156. }
  157. else
  158. {
  159. DPFX(DPFPREP, 9, "Send 0x%p refcount = %u.", this, lResult);
  160. }
  161. };
  162. inline CDP8SimEndpoint * GetEndpoint(void) { return this->m_pDP8SimEndpoint; };
  163. inline DWORD GetMessageSize(void) const { return this->m_adpnbd[1].dwBufferSize; };
  164. inline SPSENDDATA * GetSendDataBlockPtr(void) { return (&this->m_spsd); };
  165. inline HANDLE GetSendDataBlockCommand(void) { return this->m_spsd.hCommand; };
  166. inline DWORD GetSendDataBlockCommandDescriptor(void) const { return this->m_spsd.dwCommandDescriptor; };
  167. inline DWORD GetLatencyAdded(void) const { return this->m_dwLatencyAdded; };
  168. inline void SetSendDataBlockContext(PVOID pvContext) { this->m_spsd.pvContext = pvContext; };
  169. inline void SetLatencyAdded(DWORD dwLatency) { this->m_dwLatencyAdded = dwLatency; };
  170. private:
  171. BYTE m_Sig[4]; // debugging signature ('SIMS')
  172. LONG m_lRefCount; // number of references for this object
  173. CDP8SimEndpoint * m_pDP8SimEndpoint; // pointer to destination endpoint
  174. DPN_BUFFER_DESC m_adpnbd[2]; // data buffer descriptor array, always leave an extra buffer for SP
  175. SPSENDDATA m_spsd; // send data parameter block
  176. DWORD m_dwLatencyAdded; // the latency added, saved for incrementing statistics on send completion
  177. BYTE m_abData[MAX_DATA_SIZE]; // data buffer
  178. };