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.

309 lines
7.1 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: Block.c
  3. *
  4. * Purpose: Includes OleServerBlock(), OleServerUnblock() and related routines.
  5. *
  6. * Created: Dec. 1990.
  7. *
  8. * Copyright (c) 1990, 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * Srinik (../12/1990) Designed, coded
  12. *
  13. \***************************************************************************/
  14. #include "cmacs.h"
  15. #include "windows.h"
  16. #include "dde.h"
  17. #include "ole.h"
  18. #include "srvr.h"
  19. OLESTATUS FAR PASCAL OleBlockServer (lhsrvr)
  20. LHSERVER lhsrvr;
  21. {
  22. LPSRVR lpsrvr;
  23. if (!CheckServer (lpsrvr = (LPSRVR) lhsrvr))
  24. return OLE_ERROR_HANDLE;
  25. PROBE_BLOCK(lpsrvr);
  26. lpsrvr->bBlock = TRUE;
  27. return OLE_OK;
  28. }
  29. // On return from this routine, if *lpStatus is TRUE it means that more
  30. // messages are to be unblocked.
  31. OLESTATUS FAR PASCAL OleUnblockServer (lhsrvr, lpStatus)
  32. LHSERVER lhsrvr;
  33. BOOL FAR * lpStatus;
  34. {
  35. HANDLE hq;
  36. PQUE pq;
  37. LPSRVR lpsrvr;
  38. if (!CheckServer (lpsrvr = (LPSRVR) lhsrvr))
  39. return OLE_ERROR_HANDLE;
  40. PROBE_WRITE(lpStatus);
  41. *lpStatus = lpsrvr->bBlock;
  42. if (hq = lpsrvr->hqHead) {
  43. if (!(pq = (PQUE) LocalLock (hq)))
  44. return OLE_ERROR_MEMORY;
  45. lpsrvr->bBlockedMsg = TRUE;
  46. lpsrvr->hqHead = pq->hqNext;
  47. SendMessage (pq->hwnd, pq->msg, pq->wParam, pq->lParam);
  48. LocalUnlock (hq);
  49. LocalFree (hq);
  50. // Server could've got freed up as a result of the above SendMessage
  51. // Validate server handle before trying to access it.
  52. if (CheckServer (lpsrvr)) {
  53. lpsrvr->bBlockedMsg = FALSE;
  54. if (!lpsrvr->hqHead) {
  55. lpsrvr->hqTail = NULL;
  56. *lpStatus = lpsrvr->bBlock = FALSE;
  57. }
  58. }
  59. else {
  60. *lpStatus = FALSE;
  61. }
  62. }
  63. else {
  64. *lpStatus = lpsrvr->bBlock = FALSE;
  65. }
  66. return OLE_OK;
  67. }
  68. BOOL INTERNAL AddMessage (hwnd, msg, wParam, lParam, wType)
  69. HWND hwnd;
  70. unsigned msg;
  71. WORD wParam;
  72. LONG lParam;
  73. int wType;
  74. {
  75. LPSRVR lpsrvr;
  76. HANDLE hq = NULL;
  77. PQUE pq = NULL, pqTmp = NULL;
  78. BOOL bBlocked = TRUE;
  79. if ((msg <= WM_DDE_INITIATE) || (msg > WM_DDE_LAST))
  80. return FALSE;
  81. if (!(lpsrvr = (LPSRVR) GetWindowLong ((wType == WT_DOC) ? GetParent (hwnd) : hwnd, 0)))
  82. return FALSE;
  83. if (lpsrvr->bBlockedMsg || !lpsrvr->bBlock)
  84. return FALSE;
  85. #ifdef LATER
  86. if ((msg == WM_DDE_INITIATE) && (lpsrvr->useFlags == OLE_SERVER_MULTI))
  87. return TRUE;
  88. #endif
  89. // Create a queue node and fill up with data
  90. if (!(hq = LocalAlloc (LMEM_MOVEABLE, sizeof(QUE))))
  91. goto errRet;
  92. if (!(pq = (PQUE) LocalLock (hq)))
  93. goto errRet;
  94. pq->hwnd = hwnd;
  95. pq->msg = msg;
  96. pq->wParam = wParam;
  97. pq->lParam = lParam;
  98. pq->hqNext = NULL;
  99. LocalUnlock (hq);
  100. // Now we got a node that we can add to the queue
  101. if (!lpsrvr->hqHead) {
  102. // Queue is empty.
  103. #ifdef FIREWALLS
  104. ASSERT (!lpsrvr->hqTail, "Tail is unexpectedly non NULL")
  105. #endif
  106. lpsrvr->hqHead = lpsrvr->hqTail = hq;
  107. }
  108. else {
  109. if (!(pqTmp = (PQUE) LocalLock (lpsrvr->hqTail)))
  110. goto errRet;
  111. pqTmp->hqNext = hq;
  112. LocalUnlock(lpsrvr->hqTail);
  113. lpsrvr->hqTail = hq;
  114. }
  115. return TRUE;
  116. errRet:
  117. if (pq)
  118. LocalUnlock (hq);
  119. if (hq)
  120. LocalFree (hq);
  121. while (bBlocked && !OleUnblockServer ((LHSERVER) lpsrvr, &bBlocked))
  122. ;
  123. return FALSE;
  124. }
  125. // dispatches the queued message, till all the messages are posted
  126. // does yielding if necessary. if bPeek is true, may allow some of
  127. // incoming messages to get in.
  128. BOOL INTERNAL UnblockPostMsgs (hwnd, bPeek)
  129. HWND hwnd;
  130. BOOL bPeek;
  131. {
  132. HANDLE hq = NULL;
  133. PQUE pq = NULL;
  134. LPSRVR lpsrvr;
  135. HWND hwndTmp;
  136. // get the parent windows
  137. while (hwndTmp = GetParent (hwnd))
  138. hwnd = hwndTmp;
  139. lpsrvr = (LPSRVR) GetWindowLong (hwnd, 0);
  140. #ifdef FIREWALLS
  141. ASSERT (lpsrvr, "No server window handle in server window");
  142. ASSERT (lpsrvr->hqPostHead, "Unexpectedly blocked queue is empty");
  143. #endif
  144. while (hq = lpsrvr->hqPostHead) {
  145. if (!(pq = (PQUE) LocalLock (hq))) {
  146. #ifdef FIREWALLS
  147. ASSERT (FALSE, "Local lock failed for blocked messages");
  148. #endif
  149. break;
  150. }
  151. if (IsWindowValid (pq->hwnd)) {
  152. if (!PostMessage (pq->hwnd, pq->msg, pq->wParam, pq->lParam)) {
  153. LocalUnlock (hq);
  154. break;
  155. }
  156. }
  157. lpsrvr->hqPostHead = pq->hqNext;
  158. LocalUnlock (hq);
  159. LocalFree (hq);
  160. }
  161. if (!lpsrvr->hqPostHead)
  162. lpsrvr->hqPostTail = NULL;
  163. return TRUE;
  164. }
  165. // Moves a message which can not be posted to a server to
  166. // the internal queue. We use this when we have to enumerate
  167. // the properties. When we change the properties stuff to
  168. // some other form, this may not be necassry.
  169. BOOL INTERNAL BlockPostMsg (hwnd, msg, wParam, lParam)
  170. HWND hwnd;
  171. WORD msg;
  172. WORD wParam;
  173. LONG lParam;
  174. {
  175. LPSRVR lpsrvr;
  176. HANDLE hq = NULL;
  177. PQUE pq = NULL, pqTmp = NULL;
  178. HWND hwndTmp;
  179. HWND hwndParent;
  180. hwndParent = (HWND)wParam;
  181. // get the parent windows
  182. while (hwndTmp = GetParent ((HWND)hwndParent))
  183. hwndParent = hwndTmp;
  184. lpsrvr = (LPSRVR) GetWindowLong (hwndParent, 0);
  185. #ifdef FIREWALLS
  186. ASSERT (lpsrvr, "No server window handle in server window");
  187. #endif
  188. // Create a queue node and fill up with data
  189. if (!(hq = LocalAlloc (LMEM_MOVEABLE, sizeof(QUE))))
  190. goto errRet;
  191. if (!(pq = (PQUE) LocalLock (hq)))
  192. goto errRet;
  193. pq->hwnd = hwnd;
  194. pq->msg = msg;
  195. pq->wParam = wParam;
  196. pq->lParam = lParam;
  197. pq->hqNext = NULL;
  198. LocalUnlock (hq);
  199. // Now we got a node that we can add to the queue
  200. if (!lpsrvr->hqPostHead) {
  201. // Queue is empty.
  202. #ifdef FIREWALLS
  203. ASSERT (!lpsrvr->hqPostTail, "Tail is unexpectedly non NULL")
  204. #endif
  205. lpsrvr->hqPostHead = lpsrvr->hqPostTail = hq;
  206. // create a timer.
  207. if (!SetTimer (lpsrvr->hwnd, 1, 100, NULL))
  208. return FALSE;
  209. }
  210. else {
  211. if (!(pqTmp = (PQUE) LocalLock (lpsrvr->hqPostTail)))
  212. goto errRet;
  213. pqTmp->hqNext = hq;
  214. LocalUnlock(lpsrvr->hqPostTail);
  215. lpsrvr->hqPostTail = hq;
  216. }
  217. return TRUE;
  218. errRet:
  219. if (pq)
  220. LocalUnlock (hq);
  221. if (hq)
  222. LocalFree (hq);
  223. return FALSE;
  224. }
  225. BOOL INTERNAL IsBlockQueueEmpty (hwnd)
  226. HWND hwnd;
  227. {
  228. LPSRVR lpsrvr;
  229. HWND hwndTmp;
  230. // get the parent windows
  231. while (hwndTmp = GetParent ((HWND)hwnd))
  232. hwnd= hwndTmp;
  233. lpsrvr = (LPSRVR) GetWindowLong (hwnd, 0);
  234. return (!lpsrvr->hqPostHead);
  235. }