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.

330 lines
16 KiB

  1. /**MOD+**********************************************************************/
  2. /* Module: cdint.cpp */
  3. /* */
  4. /* Purpose: Component Decoupler internal functions */
  5. /* */
  6. /* Copyright(C) Microsoft Corporation 1997-1999 */
  7. /* */
  8. /****************************************************************************/
  9. #include <adcg.h>
  10. extern "C" {
  11. #define TRC_GROUP TRC_GROUP_CORE
  12. #define TRC_FILE "acdint"
  13. #include <atrcapi.h>
  14. }
  15. #include "cd.h"
  16. #include "autil.h"
  17. #include "wui.h"
  18. /**PROC+*********************************************************************/
  19. /* Name: CDAllocTransferBuffer */
  20. /* */
  21. /* Purpose: Allocates a transfer buffer of a given size to pass between */
  22. /* components / threads. */
  23. /* The function is thread safe. */
  24. /* */
  25. /* Returns: Pointer to allocated buffer. */
  26. /* */
  27. /* Params: IN dataLength - the size of buffer to be allocated. */
  28. /* */
  29. /* Operation: Several cached transfer buffers are maintained to avoid */
  30. /* continual dynamic allocation/free operations. If the */
  31. /* allocation request cannot be satisfied by the available */
  32. /* cached buffers a dynamic memory allocation is made. */
  33. /* */
  34. /**PROC-*********************************************************************/
  35. PCDTRANSFERBUFFER DCINTERNAL CCD::CDAllocTransferBuffer(DCUINT dataLength)
  36. {
  37. DCUINT i;
  38. DCUINT transferBufferLength;
  39. PCDTRANSFERBUFFER rc;
  40. DC_BEGIN_FN("CDAllocTransferBuffer");
  41. /************************************************************************/
  42. /* Calculate the Transfer Buffer size (including header). */
  43. /************************************************************************/
  44. transferBufferLength = sizeof(CDTRANSFERBUFFERHDR) + dataLength;
  45. if (transferBufferLength <= CD_CACHED_TRANSFER_BUFFER_SIZE)
  46. {
  47. TRC_DBG((TB, _T("Look in cache")));
  48. /********************************************************************/
  49. /* Search for a free cached Transfer Buffer. */
  50. /* */
  51. /* We need to do this in a thread-safe way, so we use an */
  52. /* interlocked exchange on the "in use" flag. */
  53. /********************************************************************/
  54. for (i = 0; i < CD_NUM_CACHED_TRANSFER_BUFFERS; i++)
  55. {
  56. TRC_DBG((TB, _T("Look in cache %d"), i));
  57. if (!_pUt->UT_InterlockedExchange(&(_CD.transferBufferInUse[i]), TRUE))
  58. {
  59. TRC_NRM((TB, _T("Using cached buffer(%u)"), i));
  60. rc = (PCDTRANSFERBUFFER)&(_CD.transferBuffer[i]);
  61. DC_QUIT;
  62. }
  63. }
  64. }
  65. /************************************************************************/
  66. /* We can't use a cached Transfer Buffer, so we have to allocate one. */
  67. /************************************************************************/
  68. TRC_ALT((TB, _T("Dynamic buffer allocation: length(%d)"),
  69. transferBufferLength));
  70. rc = (PCDTRANSFERBUFFER)UT_Malloc(_pUt, transferBufferLength);
  71. if (rc == NULL)
  72. {
  73. _pUi->UI_FatalError(DC_ERR_OUTOFMEMORY);
  74. }
  75. DC_EXIT_POINT:
  76. DC_END_FN();
  77. return(rc);
  78. }
  79. /**PROC+*********************************************************************/
  80. /* Name: CDFreeTransferBuffer */
  81. /* */
  82. /* Purpose: Frees a Transfer Buffer allocated via a previous call to */
  83. /* CDAllocTransferBuffer. */
  84. /* */
  85. /* Returns: Nothing. */
  86. /* */
  87. /* Params: IN pTransferBuffer - pointer to buffer to free */
  88. /* */
  89. /* Operation: Either frees the given cached Transfer Buffer, or frees the */
  90. /* dynamically allocated memory. */
  91. /* */
  92. /**PROC-*********************************************************************/
  93. DCVOID DCINTERNAL CCD::CDFreeTransferBuffer(PCDTRANSFERBUFFER pTransferBuffer)
  94. {
  95. DCUINT iTransferBuffer;
  96. DC_BEGIN_FN("CDFreeTransferBuffer");
  97. TRC_ASSERT((pTransferBuffer != NULL), (TB, _T("NULL pTransferBuffer")));
  98. /************************************************************************/
  99. /* Determine whether the supplied buffer is one of our cached buffers. */
  100. /************************************************************************/
  101. if ((pTransferBuffer >= (PCDTRANSFERBUFFER)&(_CD.transferBuffer[0])) &&
  102. (pTransferBuffer <= (PCDTRANSFERBUFFER)
  103. &(_CD.transferBuffer[CD_NUM_CACHED_TRANSFER_BUFFERS-1])))
  104. {
  105. iTransferBuffer = (DCUINT)
  106. (((ULONG_PTR)pTransferBuffer) -
  107. ((ULONG_PTR)(PDCVOID)&(_CD.transferBuffer[0]))) /
  108. sizeof(_CD.transferBuffer[0]);
  109. TRC_ASSERT((pTransferBuffer == (PCDTRANSFERBUFFER)
  110. &(_CD.transferBuffer[iTransferBuffer])),
  111. (TB, _T("Invalid Transfer Buffer pointer(%p) expected(%p)"),
  112. pTransferBuffer,
  113. &(_CD.transferBuffer[iTransferBuffer])));
  114. TRC_ASSERT((_CD.transferBufferInUse[iTransferBuffer]),
  115. (TB, _T("Transfer buffer(%u) not in use"), iTransferBuffer));
  116. _CD.transferBufferInUse[iTransferBuffer] = FALSE;
  117. }
  118. else
  119. {
  120. /********************************************************************/
  121. /* This memory must be a dynamic allocation. */
  122. /********************************************************************/
  123. UT_Free(_pUt, pTransferBuffer);
  124. }
  125. DC_END_FN();
  126. return;
  127. }
  128. /**PROC+*********************************************************************/
  129. /* Name: CDStaticWndProc */
  130. /* */
  131. /* Purpose: Window Procedure for CD windows (Static version) */
  132. /* */
  133. /* Returns: Windows return code */
  134. /* */
  135. /* Params: IN hwnd - window handle */
  136. /* IN message - message */
  137. /* IN wParam - parameter */
  138. /* IN lParam - parameter */
  139. /* */
  140. /**PROC-*********************************************************************/
  141. LRESULT CALLBACK CCD::CDStaticWndProc(HWND hwnd,
  142. UINT message,
  143. WPARAM wParam,
  144. LPARAM lParam)
  145. {
  146. CCD* pCD = (CCD*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  147. if(WM_CREATE == message)
  148. {
  149. //pull out the this pointer and stuff it in the window class
  150. LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
  151. pCD = (CCD*)lpcs->lpCreateParams;
  152. SetWindowLongPtr( hwnd, GWLP_USERDATA, (LONG_PTR)pCD);
  153. }
  154. //
  155. // Delegate the message to the appropriate instance
  156. //
  157. if(pCD)
  158. {
  159. return pCD->CDWndProc(hwnd, message, wParam, lParam);
  160. }
  161. else
  162. {
  163. return DefWindowProc(hwnd, message, wParam, lParam);
  164. }
  165. }
  166. /**PROC+*********************************************************************/
  167. /* Name: CDWndProc */
  168. /* */
  169. /* Purpose: Window Procedure for CD windows */
  170. /* */
  171. /* Returns: Windows return code */
  172. /* */
  173. /* Params: IN hwnd - window handle */
  174. /* IN message - message */
  175. /* IN wParam - parameter */
  176. /* IN lParam - parameter */
  177. /* */
  178. /**PROC-*********************************************************************/
  179. LRESULT CALLBACK CCD::CDWndProc(HWND hwnd,
  180. UINT message,
  181. WPARAM wParam,
  182. LPARAM lParam)
  183. {
  184. PCDTRANSFERBUFFER pTransferBuffer;
  185. LRESULT rc = 0;
  186. DC_BEGIN_FN("CDWndProc");
  187. switch (message)
  188. {
  189. case CD_SIMPLE_NOTIFICATION_MSG:
  190. {
  191. PCD_SIMPLE_NOTIFICATION_FN pNotificationFn;
  192. PDCVOID pInst;
  193. ULONG_PTR msg;
  194. #ifdef DC_DEBUG
  195. /****************************************************************/
  196. /* Trace is before decrement so that the point at which we're */
  197. /* most likely to get pre-empted (TRC_GetBuffer) is before all */
  198. /* references to the variable we're interested in. */
  199. /****************************************************************/
  200. TRC_NRM((TB, _T("Messages now pending: %ld"),
  201. _CD.pendingMessageCount - 1));
  202. _pUt->UT_InterlockedDecrement(&_CD.pendingMessageCount);
  203. #endif
  204. /****************************************************************/
  205. /* Simple notification: */
  206. /* lParam contains transfer buffer */
  207. /* The transfer buffer contains no data payload, just the */
  208. /* function pointer and object instance pointer. */
  209. /* wParam contains message */
  210. /****************************************************************/
  211. pTransferBuffer = (PCDTRANSFERBUFFER)lParam;
  212. pNotificationFn = pTransferBuffer->hdr.pSimpleNotificationFn;
  213. pInst = pTransferBuffer->hdr.pInst;
  214. msg = (ULONG_PTR) wParam;
  215. TRC_ASSERT((pNotificationFn != NULL),
  216. (TB, _T("NULL pNotificationFn")));
  217. TRC_ASSERT((pInst != NULL), (TB, _T("NULL pInst")));
  218. TRC_ASSERT((pTransferBuffer != NULL), (TB, _T("NULL pInst")));
  219. TRC_NRM((TB, _T("Simple notification: pfn(%p) msg(%u)"),
  220. pNotificationFn, msg));
  221. /****************************************************************/
  222. /* Call the function. */
  223. /****************************************************************/
  224. (*pNotificationFn)(pInst, msg);
  225. /****************************************************************/
  226. /* Release the memory allocated for this transfer buffer. */
  227. /****************************************************************/
  228. CDFreeTransferBuffer(pTransferBuffer);
  229. }
  230. break;
  231. case CD_NOTIFICATION_MSG:
  232. {
  233. PCD_NOTIFICATION_FN pNotificationFn;
  234. PDCVOID pData;
  235. DCUINT dataLength;
  236. PDCVOID pInst;
  237. #ifdef DC_DEBUG
  238. /****************************************************************/
  239. /* Trace is before decrement so that the point at which we're */
  240. /* most likely to get pre-empted (TRC_GetBuffer) is before all */
  241. /* references to the variable we're interested in. */
  242. /****************************************************************/
  243. TRC_NRM((TB, _T("Messages now pending: %ld"),
  244. _CD.pendingMessageCount - 1));
  245. _pUt->UT_InterlockedDecrement(&_CD.pendingMessageCount);
  246. #endif
  247. /****************************************************************/
  248. /* Notification: */
  249. /* lParam contains pointer to CD transfer buffer */
  250. /* wParam contains dataLength */
  251. /****************************************************************/
  252. pTransferBuffer = (PCDTRANSFERBUFFER)lParam;
  253. pNotificationFn = pTransferBuffer->hdr.pNotificationFn;
  254. dataLength = (DCUINT) wParam;
  255. pData = &(pTransferBuffer->data[0]);
  256. pInst = pTransferBuffer->hdr.pInst;
  257. TRC_ASSERT((pNotificationFn != NULL),
  258. (TB, _T("NULL pNotificationFn")));
  259. TRC_ASSERT((pInst != NULL), (TB, _T("NULL pInst")));
  260. TRC_NRM((TB, _T("Notification: pfn(%p) pData(%p) dataLength(%u)"),
  261. pNotificationFn, pData, dataLength));
  262. (*pNotificationFn)(pInst, pData, dataLength);
  263. /****************************************************************/
  264. /* Release the memory allocated for this transfer buffer. */
  265. /****************************************************************/
  266. CDFreeTransferBuffer(pTransferBuffer);
  267. }
  268. break;
  269. default:
  270. {
  271. /****************************************************************/
  272. /* Ignore other messages - pass to the default window handler. */
  273. /****************************************************************/
  274. TRC_DBG((TB, _T("Non-notification message %x"), message));
  275. rc = DefWindowProc(hwnd, message, wParam, lParam);
  276. }
  277. break;
  278. }
  279. DC_END_FN();
  280. return(rc);
  281. } /* CDWndProc */