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.

244 lines
5.7 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation
  6. //
  7. // File: kpcore.cxx
  8. //
  9. // Contents: core routine for worker threads
  10. //
  11. // History: 10-Jul-2001 t-ryanj Created
  12. //
  13. //------------------------------------------------------------------------
  14. #include "kpcore.h"
  15. #include "kphttp.h"
  16. #include "kpkdc.h"
  17. VOID
  18. KpDispatchPerContext(
  19. PKPCONTEXT pContext,
  20. ULONG IocpBytes
  21. );
  22. //+-------------------------------------------------------------------------
  23. //
  24. // Function: KpThreadCore
  25. //
  26. // Synopsis: core routine for worker threads. handles requests as they
  27. // are posted to the completion port.
  28. //
  29. // Effects:
  30. //
  31. // Arguments: ignore - unused
  32. //
  33. // Requires:
  34. //
  35. // Returns: always 0
  36. //
  37. // Notes:
  38. //
  39. //
  40. //--------------------------------------------------------------------------
  41. DWORD WINAPI
  42. KpThreadCore(
  43. LPVOID pvContext
  44. )
  45. {
  46. KpDispatchPerContext((PKPCONTEXT)pvContext,
  47. 0 );
  48. return NO_ERROR;
  49. #if 0
  50. BOOL Terminate = FALSE;
  51. BOOL IocpSuccess;
  52. ULONG IocpBytes;
  53. ULONG_PTR IocpCompKey;
  54. LPOVERLAPPED lpOverlapped;
  55. //
  56. // Do it til we're done.
  57. //
  58. while( !Terminate )
  59. {
  60. //
  61. // Grab a job off the completion queue.
  62. //
  63. IocpSuccess = GetQueuedCompletionStatus( KpGlobalIocp,
  64. &IocpBytes,
  65. &IocpCompKey,
  66. &lpOverlapped,
  67. INFINITE );
  68. if( !IocpSuccess )
  69. {
  70. DebugLog( DEB_ERROR, "%s(%d): Error from GetQueuedCompletionStatus: 0x%x.\n", __FILE__, __LINE__, GetLastError() );
  71. continue;
  72. }
  73. //
  74. // Based on the completion key, do the right thing.
  75. //
  76. switch( IocpCompKey )
  77. {
  78. case KPCK_TERMINATE:
  79. Terminate = TRUE;
  80. break;
  81. case KPCK_HTTP_INITIAL:
  82. DebugLog( DEB_TRACE, "----==== New connection accepted ====----\n" );
  83. KpHttpRead( (LPEXTENSION_CONTROL_BLOCK)lpOverlapped );
  84. break;
  85. case KPCK_CHECK_CONTEXT:
  86. KpDispatchPerContext( KpGetContextFromOl( lpOverlapped ),
  87. IocpBytes );
  88. break;
  89. default:
  90. DebugLog( DEB_WARN, "%s(%d): Unhandled case: 0x%x.\n", __FILE__, __LINE__, IocpCompKey );
  91. DsysAssert( IocpCompKey == KPCK_TERMINATE ||
  92. IocpCompKey == KPCK_HTTP_INITIAL ||
  93. IocpCompKey == KPCK_CHECK_CONTEXT );
  94. break;
  95. }
  96. }
  97. return 0;
  98. #endif
  99. }
  100. VOID CALLBACK
  101. KpIoCompletionRoutine(
  102. DWORD dwErrorCode,
  103. DWORD dwBytes,
  104. LPOVERLAPPED lpOverlapped
  105. )
  106. {
  107. PKPCONTEXT pContext = NULL;
  108. if( lpOverlapped )
  109. {
  110. pContext = KpGetContextFromOl( lpOverlapped );
  111. }
  112. else
  113. {
  114. DebugLog( DEB_ERROR, "%s(%d): Null pointer for overlapped.\n", __FILE__, __LINE__ );
  115. goto Error;
  116. }
  117. if( dwErrorCode )
  118. {
  119. DebugLog( DEB_ERROR, "%s(%d): Error from I/O routine: 0x%x\n", __FILE__, __LINE__, dwErrorCode );
  120. goto Error;
  121. }
  122. KpDispatchPerContext( pContext,
  123. dwBytes );
  124. return;
  125. Error:
  126. if( pContext )
  127. KpReleaseContext( pContext );
  128. }
  129. //+-------------------------------------------------------------------------
  130. //
  131. // Function: KpDispatchPerContext
  132. //
  133. // Synopsis: Does the right things based on the status in the context.
  134. //
  135. // Effects:
  136. //
  137. // Arguments: pContext
  138. // IocpBytes - bytes reported to the iocp
  139. //
  140. // Requires:
  141. //
  142. // Returns:
  143. //
  144. // Notes:
  145. //
  146. //
  147. //--------------------------------------------------------------------------
  148. VOID
  149. KpDispatchPerContext(
  150. PKPCONTEXT pContext,
  151. ULONG IocpBytes
  152. )
  153. {
  154. //
  155. // Status is going to tell us what we just finished doing,
  156. // so we can pass the context into the next step.
  157. //
  158. switch( pContext->dwStatus )
  159. {
  160. case KP_HTTP_INITIAL:
  161. KpHttpRead(pContext);
  162. break;
  163. case KP_HTTP_READ:
  164. KpKdcWrite(pContext);
  165. break;
  166. case KP_KDC_WRITE:
  167. DebugLog( DEB_TRACE, "%s(%d): %d bytes written to KDC.\n", __FILE__, __LINE__, pContext->ol.InternalHigh );
  168. KpKdcRead(pContext);
  169. break;
  170. case KP_KDC_READ:
  171. DebugLog( DEB_PEDANTIC, "%s(%d): %d bytes read from KDC.\n", __FILE__, __LINE__, pContext->ol.InternalHigh );
  172. //
  173. // If we don't know how many bytes we're looking for yet,
  174. // figure it out.
  175. //
  176. if( pContext->bytesExpected == 0 &&
  177. !KpCalcLength(pContext) )
  178. {
  179. goto Error;
  180. }
  181. //
  182. // If we're done reading, start writing; otherwise, read some more.
  183. //
  184. if( KpKdcReadDone(pContext) )
  185. {
  186. DebugLog( DEB_TRACE, "%s(%d): %d total bytes read from KDC.\n", __FILE__, __LINE__, pContext->bytesReceived );
  187. KpHttpWrite(pContext);
  188. }
  189. else
  190. {
  191. KpKdcRead(pContext);
  192. }
  193. break;
  194. case KP_HTTP_WRITE:
  195. DebugLog( DEB_TRACE, "%s(%d): %d bytes written to http.\n", __FILE__, __LINE__, pContext->bytesReceived );
  196. KpReleaseContext( pContext );
  197. break;
  198. default:
  199. DebugLog( DEB_WARN, "%s(%d): Unhandled case: 0x%x.\n", __FILE__, __LINE__, pContext->dwStatus );
  200. DsysAssert( pContext->dwStatus == KP_HTTP_READ ||
  201. pContext->dwStatus == KP_KDC_WRITE ||
  202. pContext->dwStatus == KP_KDC_READ ||
  203. pContext->dwStatus == KP_HTTP_WRITE );
  204. goto Error;
  205. break;
  206. }
  207. return;
  208. Error:
  209. //
  210. // This is where we get when we're not sure what to do with the connection next, so
  211. // we'll just close the connection.
  212. //
  213. KpReleaseContext( pContext );
  214. }