Windows NT 4.0 source code leak
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.

353 lines
6.8 KiB

4 years ago
  1. // CallBkQ.cpp -- Implementation for class CCallbackQueue
  2. #include "stdafx.h"
  3. #include "CallBkQ.h"
  4. #include "AbrtSrch.h"
  5. CCallbackQueue *CCallbackQueue::NewInputCallQueue (PFNQCallBack pfn, PVOID pv)
  6. {
  7. CCallbackQueue *pcbq= NULL;
  8. __try
  9. {
  10. pcbq= New CCallbackQueue();
  11. pcbq->Initial(pfn, pv, FALSE);
  12. }
  13. __finally
  14. {
  15. if (_abnormal_termination() && pcbq)
  16. {
  17. delete pcbq; pcbq= NULL;
  18. }
  19. }
  20. return pcbq;
  21. }
  22. CCallbackQueue *CCallbackQueue::NewOutputCallQueue(PFNQCallBack pfn, PVOID pv)
  23. {
  24. CCallbackQueue *pcbq= NULL;
  25. __try
  26. {
  27. pcbq= New CCallbackQueue();
  28. pcbq->Initial(pfn, pv, TRUE);
  29. }
  30. __finally
  31. {
  32. if (_abnormal_termination() && pcbq)
  33. {
  34. delete pcbq; pcbq= NULL;
  35. }
  36. }
  37. return pcbq;
  38. }
  39. void CCallbackQueue::Initial(PFNQCallBack pfn, PVOID pv, BOOL fOutput)
  40. {
  41. m_pfn = pfn;
  42. m_pvEnvironment = pv;
  43. Enable(fOutput);
  44. }
  45. const UINT *CCallbackQueue::RawNextDWordsIn(PUINT pcdw)
  46. {
  47. ASSERT(!Writable());
  48. CAbortSearch::CheckContinueState();
  49. m_pfn(m_pvEnvironment, RequestInput, &m_pdwLast, &m_cdwReserved, *pcdw);
  50. *pcdw= m_cdwReserved;
  51. return m_pdwLast;
  52. }
  53. BOOL CCallbackQueue::RawEmptyRing()
  54. {
  55. ASSERT(!Writable());
  56. BOOL fEmpty= m_cdwReserved;
  57. m_pfn(m_pvEnvironment, QueryForEmptyRing, &m_pdwLast, PUINT(&fEmpty), 0);
  58. return fEmpty;
  59. }
  60. UINT *CCallbackQueue::RawNextDWordsOut(PUINT pcdw)
  61. {
  62. ASSERT(Writable());
  63. CAbortSearch::CheckContinueState();
  64. m_pfn(m_pvEnvironment, RequestOutput, &m_pdwLast, &m_cdwReserved, *pcdw);
  65. *pcdw= m_cdwReserved;
  66. return m_pdwLast;
  67. }
  68. void CCallbackQueue::RawFlushOutput(BOOL fForceAll)
  69. {
  70. ASSERT(Writable());
  71. CAbortSearch::CheckContinueState();
  72. m_pfn(m_pvEnvironment, Flush, &m_pdwLast, &m_cdwReserved, fForceAll);
  73. }
  74. CDWInputQueue *CDWInputQueue::NewInputCallQueue (PFNPerDWordI pfn, PVOID pv)
  75. {
  76. CDWInputQueue *piq= NULL;
  77. __try
  78. {
  79. piq= New CDWInputQueue();
  80. piq->Initial(pfn, pv);
  81. }
  82. __finally
  83. {
  84. if (_abnormal_termination() && piq)
  85. {
  86. delete piq; piq= NULL;
  87. }
  88. }
  89. return piq;
  90. }
  91. CDWInputQueue::CDWInputQueue()
  92. {
  93. m_pvEnvironment = NULL;
  94. m_pfnI = NULL;
  95. m_fEndOfInput = FALSE;
  96. m_pdwLimit = m_adwBuffer;
  97. }
  98. void CDWInputQueue::Initial(PFNPerDWordI pfn, PVOID pv)
  99. {
  100. m_pfnI = pfn;
  101. m_pvEnvironment = pv;
  102. CCallbackQueue::Initial(CDWInputQueue::InputCallback, this);
  103. UINT cdwActive= CDW_BUFFER;
  104. if (pfn(pv, m_adwBuffer, &cdwActive)) m_fEndOfInput= TRUE;
  105. m_pdwLimit= m_adwBuffer + cdwActive;
  106. }
  107. void CDWInputQueue::InputCallback(PVOID pv, CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
  108. {
  109. ((CDWInputQueue *) pv)->Callback(cbt, ppdwLast, pcdwLast, cdwRequest);
  110. }
  111. void CDWInputQueue::Callback(CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
  112. {
  113. ASSERT(m_pfnI);
  114. PUINT pdw;
  115. UINT cdw;
  116. switch(cbt)
  117. {
  118. case RequestInput:
  119. pdw= *ppdwLast;
  120. if (!pdw) pdw= m_adwBuffer;
  121. pdw += *pcdwLast;
  122. if (!cdwRequest) { *ppdwLast= pdw; *pcdwLast= 0; return; }
  123. if (pdw == m_pdwLimit)
  124. {
  125. pdw= m_adwBuffer;
  126. if (m_fEndOfInput) { *ppdwLast= NULL; *pcdwLast= 0; return; }
  127. else
  128. {
  129. UINT cdwActive= CDW_BUFFER;
  130. CAbortSearch::CheckContinueState();
  131. if (m_pfnI(m_pvEnvironment, pdw, &cdwActive)) m_fEndOfInput= TRUE;
  132. if (cdwActive) m_pdwLimit= pdw + cdwActive;
  133. else { ASSERT(m_fEndOfInput); *ppdwLast= NULL; *pcdwLast= 0; return; }
  134. }
  135. }
  136. cdw= m_pdwLimit - pdw;
  137. *ppdwLast= pdw;
  138. *pcdwLast= (cdw > cdwRequest)? cdwRequest : cdw;
  139. return;
  140. case QueryForEmptyRing:
  141. pdw= *ppdwLast;
  142. if (!pdw) pdw= m_adwBuffer;
  143. pdw += *pcdwLast;
  144. if (pdw < m_pdwLimit) { *pcdwLast= FALSE; return; }
  145. if (m_fEndOfInput) { *pcdwLast= TRUE; return; }
  146. return;
  147. case RequestOutput:
  148. ASSERT(FALSE); // Shouldn't be called for output functions...
  149. return;
  150. case Flush:
  151. ASSERT(FALSE); // Shouldn't be called for output functions...
  152. return;
  153. case Disconnect:
  154. return; // Don't have any disconnect actions to perform
  155. default:
  156. ASSERT(FALSE); // Unknown transaction type
  157. return;
  158. }
  159. }
  160. CDWOutputQueue::CDWOutputQueue()
  161. {
  162. m_pvEnvironment = NULL;
  163. m_pfnO = NULL;
  164. }
  165. CDWOutputQueue::~CDWOutputQueue()
  166. {
  167. // FlushOutput(TRUE);
  168. // Disable();
  169. }
  170. void CDWOutputQueue::Initial(PFNPerDWordO pfn, PVOID pv)
  171. {
  172. m_pfnO = pfn;
  173. m_pvEnvironment = pv;
  174. CCallbackQueue::Initial(OutputCallback, this, TRUE);
  175. }
  176. CDWOutputQueue *CDWOutputQueue::NewOutputCallQueue(PFNPerDWordO pfn, PVOID pv)
  177. {
  178. CDWOutputQueue *poq= NULL;
  179. __try
  180. {
  181. poq= New CDWOutputQueue();
  182. poq->Initial(pfn, pv);
  183. }
  184. __finally
  185. {
  186. if (_abnormal_termination() && poq)
  187. {
  188. delete poq; poq= NULL;
  189. }
  190. }
  191. return poq;
  192. }
  193. void CDWOutputQueue::OutputCallback(PVOID pv, CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
  194. {
  195. ((CDWOutputQueue *) pv)->Callback(cbt, ppdwLast, pcdwLast, cdwRequest);
  196. }
  197. void CDWOutputQueue::Callback(CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
  198. {
  199. ASSERT(m_pfnO);
  200. PUINT pdw;
  201. UINT cdw;
  202. switch(cbt)
  203. {
  204. case RequestInput:
  205. ASSERT(FALSE); // Shouldn't get any input transactions;
  206. return;
  207. case QueryForEmptyRing:
  208. ASSERT(FALSE); // Shouldn't get any input transactions;
  209. return;
  210. case RequestOutput:
  211. pdw= *ppdwLast;
  212. if (!pdw) pdw= m_adwBuffer;
  213. pdw += *pcdwLast;
  214. cdw= CDW_BUFFER - (pdw - m_adwBuffer);
  215. if (!cdw)
  216. {
  217. CAbortSearch::CheckContinueState();
  218. m_pfnO(m_pvEnvironment, m_adwBuffer, CDW_BUFFER);
  219. pdw = m_adwBuffer;
  220. cdw = CDW_BUFFER;
  221. }
  222. if (cdw > cdwRequest) cdw= cdwRequest;
  223. *ppdwLast= pdw;
  224. *pcdwLast= cdw;
  225. return;
  226. case Flush:
  227. pdw= *ppdwLast;
  228. if (!pdw) pdw= m_adwBuffer;
  229. pdw += *pcdwLast;
  230. m_pfnO(m_pvEnvironment, m_adwBuffer, pdw - m_adwBuffer);
  231. *ppdwLast= m_adwBuffer;
  232. *pcdwLast= 0;
  233. return;
  234. case Disconnect:
  235. return; // Don't have any disconnect actions to perform
  236. default:
  237. ASSERT(FALSE); // Unknown transaction type
  238. return;
  239. }
  240. }