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.

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