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

//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation
//
// File: kpcore.cxx
//
// Contents: core routine for worker threads
//
// History: 10-Jul-2001 t-ryanj Created
//
//------------------------------------------------------------------------
#include "kpcore.h"
#include "kphttp.h"
#include "kpkdc.h"
VOID
KpDispatchPerContext(
PKPCONTEXT pContext,
ULONG IocpBytes
);
//+-------------------------------------------------------------------------
//
// Function: KpThreadCore
//
// Synopsis: core routine for worker threads. handles requests as they
// are posted to the completion port.
//
// Effects:
//
// Arguments: ignore - unused
//
// Requires:
//
// Returns: always 0
//
// Notes:
//
//
//--------------------------------------------------------------------------
DWORD WINAPI
KpThreadCore(
LPVOID pvContext
)
{
KpDispatchPerContext((PKPCONTEXT)pvContext,
0 );
return NO_ERROR;
#if 0
BOOL Terminate = FALSE;
BOOL IocpSuccess;
ULONG IocpBytes;
ULONG_PTR IocpCompKey;
LPOVERLAPPED lpOverlapped;
//
// Do it til we're done.
//
while( !Terminate )
{
//
// Grab a job off the completion queue.
//
IocpSuccess = GetQueuedCompletionStatus( KpGlobalIocp,
&IocpBytes,
&IocpCompKey,
&lpOverlapped,
INFINITE );
if( !IocpSuccess )
{
DebugLog( DEB_ERROR, "%s(%d): Error from GetQueuedCompletionStatus: 0x%x.\n", __FILE__, __LINE__, GetLastError() );
continue;
}
//
// Based on the completion key, do the right thing.
//
switch( IocpCompKey )
{
case KPCK_TERMINATE:
Terminate = TRUE;
break;
case KPCK_HTTP_INITIAL:
DebugLog( DEB_TRACE, "----==== New connection accepted ====----\n" );
KpHttpRead( (LPEXTENSION_CONTROL_BLOCK)lpOverlapped );
break;
case KPCK_CHECK_CONTEXT:
KpDispatchPerContext( KpGetContextFromOl( lpOverlapped ),
IocpBytes );
break;
default:
DebugLog( DEB_WARN, "%s(%d): Unhandled case: 0x%x.\n", __FILE__, __LINE__, IocpCompKey );
DsysAssert( IocpCompKey == KPCK_TERMINATE ||
IocpCompKey == KPCK_HTTP_INITIAL ||
IocpCompKey == KPCK_CHECK_CONTEXT );
break;
}
}
return 0;
#endif
}
VOID CALLBACK
KpIoCompletionRoutine(
DWORD dwErrorCode,
DWORD dwBytes,
LPOVERLAPPED lpOverlapped
)
{
PKPCONTEXT pContext = NULL;
if( lpOverlapped )
{
pContext = KpGetContextFromOl( lpOverlapped );
}
else
{
DebugLog( DEB_ERROR, "%s(%d): Null pointer for overlapped.\n", __FILE__, __LINE__ );
goto Error;
}
if( dwErrorCode )
{
DebugLog( DEB_ERROR, "%s(%d): Error from I/O routine: 0x%x\n", __FILE__, __LINE__, dwErrorCode );
goto Error;
}
KpDispatchPerContext( pContext,
dwBytes );
return;
Error:
if( pContext )
KpReleaseContext( pContext );
}
//+-------------------------------------------------------------------------
//
// Function: KpDispatchPerContext
//
// Synopsis: Does the right things based on the status in the context.
//
// Effects:
//
// Arguments: pContext
// IocpBytes - bytes reported to the iocp
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
VOID
KpDispatchPerContext(
PKPCONTEXT pContext,
ULONG IocpBytes
)
{
//
// Status is going to tell us what we just finished doing,
// so we can pass the context into the next step.
//
switch( pContext->dwStatus )
{
case KP_HTTP_INITIAL:
KpHttpRead(pContext);
break;
case KP_HTTP_READ:
KpKdcWrite(pContext);
break;
case KP_KDC_WRITE:
DebugLog( DEB_TRACE, "%s(%d): %d bytes written to KDC.\n", __FILE__, __LINE__, pContext->ol.InternalHigh );
KpKdcRead(pContext);
break;
case KP_KDC_READ:
DebugLog( DEB_PEDANTIC, "%s(%d): %d bytes read from KDC.\n", __FILE__, __LINE__, pContext->ol.InternalHigh );
//
// If we don't know how many bytes we're looking for yet,
// figure it out.
//
if( pContext->bytesExpected == 0 &&
!KpCalcLength(pContext) )
{
goto Error;
}
//
// If we're done reading, start writing; otherwise, read some more.
//
if( KpKdcReadDone(pContext) )
{
DebugLog( DEB_TRACE, "%s(%d): %d total bytes read from KDC.\n", __FILE__, __LINE__, pContext->bytesReceived );
KpHttpWrite(pContext);
}
else
{
KpKdcRead(pContext);
}
break;
case KP_HTTP_WRITE:
DebugLog( DEB_TRACE, "%s(%d): %d bytes written to http.\n", __FILE__, __LINE__, pContext->bytesReceived );
KpReleaseContext( pContext );
break;
default:
DebugLog( DEB_WARN, "%s(%d): Unhandled case: 0x%x.\n", __FILE__, __LINE__, pContext->dwStatus );
DsysAssert( pContext->dwStatus == KP_HTTP_READ ||
pContext->dwStatus == KP_KDC_WRITE ||
pContext->dwStatus == KP_KDC_READ ||
pContext->dwStatus == KP_HTTP_WRITE );
goto Error;
break;
}
return;
Error:
//
// This is where we get when we're not sure what to do with the connection next, so
// we'll just close the connection.
//
KpReleaseContext( pContext );
}