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.
 
 
 
 
 
 

330 lines
16 KiB

/**MOD+**********************************************************************/
/* Module: cdint.cpp */
/* */
/* Purpose: Component Decoupler internal functions */
/* */
/* Copyright(C) Microsoft Corporation 1997-1999 */
/* */
/****************************************************************************/
#include <adcg.h>
extern "C" {
#define TRC_GROUP TRC_GROUP_CORE
#define TRC_FILE "acdint"
#include <atrcapi.h>
}
#include "cd.h"
#include "autil.h"
#include "wui.h"
/**PROC+*********************************************************************/
/* Name: CDAllocTransferBuffer */
/* */
/* Purpose: Allocates a transfer buffer of a given size to pass between */
/* components / threads. */
/* The function is thread safe. */
/* */
/* Returns: Pointer to allocated buffer. */
/* */
/* Params: IN dataLength - the size of buffer to be allocated. */
/* */
/* Operation: Several cached transfer buffers are maintained to avoid */
/* continual dynamic allocation/free operations. If the */
/* allocation request cannot be satisfied by the available */
/* cached buffers a dynamic memory allocation is made. */
/* */
/**PROC-*********************************************************************/
PCDTRANSFERBUFFER DCINTERNAL CCD::CDAllocTransferBuffer(DCUINT dataLength)
{
DCUINT i;
DCUINT transferBufferLength;
PCDTRANSFERBUFFER rc;
DC_BEGIN_FN("CDAllocTransferBuffer");
/************************************************************************/
/* Calculate the Transfer Buffer size (including header). */
/************************************************************************/
transferBufferLength = sizeof(CDTRANSFERBUFFERHDR) + dataLength;
if (transferBufferLength <= CD_CACHED_TRANSFER_BUFFER_SIZE)
{
TRC_DBG((TB, _T("Look in cache")));
/********************************************************************/
/* Search for a free cached Transfer Buffer. */
/* */
/* We need to do this in a thread-safe way, so we use an */
/* interlocked exchange on the "in use" flag. */
/********************************************************************/
for (i = 0; i < CD_NUM_CACHED_TRANSFER_BUFFERS; i++)
{
TRC_DBG((TB, _T("Look in cache %d"), i));
if (!_pUt->UT_InterlockedExchange(&(_CD.transferBufferInUse[i]), TRUE))
{
TRC_NRM((TB, _T("Using cached buffer(%u)"), i));
rc = (PCDTRANSFERBUFFER)&(_CD.transferBuffer[i]);
DC_QUIT;
}
}
}
/************************************************************************/
/* We can't use a cached Transfer Buffer, so we have to allocate one. */
/************************************************************************/
TRC_ALT((TB, _T("Dynamic buffer allocation: length(%d)"),
transferBufferLength));
rc = (PCDTRANSFERBUFFER)UT_Malloc(_pUt, transferBufferLength);
if (rc == NULL)
{
_pUi->UI_FatalError(DC_ERR_OUTOFMEMORY);
}
DC_EXIT_POINT:
DC_END_FN();
return(rc);
}
/**PROC+*********************************************************************/
/* Name: CDFreeTransferBuffer */
/* */
/* Purpose: Frees a Transfer Buffer allocated via a previous call to */
/* CDAllocTransferBuffer. */
/* */
/* Returns: Nothing. */
/* */
/* Params: IN pTransferBuffer - pointer to buffer to free */
/* */
/* Operation: Either frees the given cached Transfer Buffer, or frees the */
/* dynamically allocated memory. */
/* */
/**PROC-*********************************************************************/
DCVOID DCINTERNAL CCD::CDFreeTransferBuffer(PCDTRANSFERBUFFER pTransferBuffer)
{
DCUINT iTransferBuffer;
DC_BEGIN_FN("CDFreeTransferBuffer");
TRC_ASSERT((pTransferBuffer != NULL), (TB, _T("NULL pTransferBuffer")));
/************************************************************************/
/* Determine whether the supplied buffer is one of our cached buffers. */
/************************************************************************/
if ((pTransferBuffer >= (PCDTRANSFERBUFFER)&(_CD.transferBuffer[0])) &&
(pTransferBuffer <= (PCDTRANSFERBUFFER)
&(_CD.transferBuffer[CD_NUM_CACHED_TRANSFER_BUFFERS-1])))
{
iTransferBuffer = (DCUINT)
(((ULONG_PTR)pTransferBuffer) -
((ULONG_PTR)(PDCVOID)&(_CD.transferBuffer[0]))) /
sizeof(_CD.transferBuffer[0]);
TRC_ASSERT((pTransferBuffer == (PCDTRANSFERBUFFER)
&(_CD.transferBuffer[iTransferBuffer])),
(TB, _T("Invalid Transfer Buffer pointer(%p) expected(%p)"),
pTransferBuffer,
&(_CD.transferBuffer[iTransferBuffer])));
TRC_ASSERT((_CD.transferBufferInUse[iTransferBuffer]),
(TB, _T("Transfer buffer(%u) not in use"), iTransferBuffer));
_CD.transferBufferInUse[iTransferBuffer] = FALSE;
}
else
{
/********************************************************************/
/* This memory must be a dynamic allocation. */
/********************************************************************/
UT_Free(_pUt, pTransferBuffer);
}
DC_END_FN();
return;
}
/**PROC+*********************************************************************/
/* Name: CDStaticWndProc */
/* */
/* Purpose: Window Procedure for CD windows (Static version) */
/* */
/* Returns: Windows return code */
/* */
/* Params: IN hwnd - window handle */
/* IN message - message */
/* IN wParam - parameter */
/* IN lParam - parameter */
/* */
/**PROC-*********************************************************************/
LRESULT CALLBACK CCD::CDStaticWndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
CCD* pCD = (CCD*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(WM_CREATE == message)
{
//pull out the this pointer and stuff it in the window class
LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
pCD = (CCD*)lpcs->lpCreateParams;
SetWindowLongPtr( hwnd, GWLP_USERDATA, (LONG_PTR)pCD);
}
//
// Delegate the message to the appropriate instance
//
if(pCD)
{
return pCD->CDWndProc(hwnd, message, wParam, lParam);
}
else
{
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
/**PROC+*********************************************************************/
/* Name: CDWndProc */
/* */
/* Purpose: Window Procedure for CD windows */
/* */
/* Returns: Windows return code */
/* */
/* Params: IN hwnd - window handle */
/* IN message - message */
/* IN wParam - parameter */
/* IN lParam - parameter */
/* */
/**PROC-*********************************************************************/
LRESULT CALLBACK CCD::CDWndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
PCDTRANSFERBUFFER pTransferBuffer;
LRESULT rc = 0;
DC_BEGIN_FN("CDWndProc");
switch (message)
{
case CD_SIMPLE_NOTIFICATION_MSG:
{
PCD_SIMPLE_NOTIFICATION_FN pNotificationFn;
PDCVOID pInst;
ULONG_PTR msg;
#ifdef DC_DEBUG
/****************************************************************/
/* Trace is before decrement so that the point at which we're */
/* most likely to get pre-empted (TRC_GetBuffer) is before all */
/* references to the variable we're interested in. */
/****************************************************************/
TRC_NRM((TB, _T("Messages now pending: %ld"),
_CD.pendingMessageCount - 1));
_pUt->UT_InterlockedDecrement(&_CD.pendingMessageCount);
#endif
/****************************************************************/
/* Simple notification: */
/* lParam contains transfer buffer */
/* The transfer buffer contains no data payload, just the */
/* function pointer and object instance pointer. */
/* wParam contains message */
/****************************************************************/
pTransferBuffer = (PCDTRANSFERBUFFER)lParam;
pNotificationFn = pTransferBuffer->hdr.pSimpleNotificationFn;
pInst = pTransferBuffer->hdr.pInst;
msg = (ULONG_PTR) wParam;
TRC_ASSERT((pNotificationFn != NULL),
(TB, _T("NULL pNotificationFn")));
TRC_ASSERT((pInst != NULL), (TB, _T("NULL pInst")));
TRC_ASSERT((pTransferBuffer != NULL), (TB, _T("NULL pInst")));
TRC_NRM((TB, _T("Simple notification: pfn(%p) msg(%u)"),
pNotificationFn, msg));
/****************************************************************/
/* Call the function. */
/****************************************************************/
(*pNotificationFn)(pInst, msg);
/****************************************************************/
/* Release the memory allocated for this transfer buffer. */
/****************************************************************/
CDFreeTransferBuffer(pTransferBuffer);
}
break;
case CD_NOTIFICATION_MSG:
{
PCD_NOTIFICATION_FN pNotificationFn;
PDCVOID pData;
DCUINT dataLength;
PDCVOID pInst;
#ifdef DC_DEBUG
/****************************************************************/
/* Trace is before decrement so that the point at which we're */
/* most likely to get pre-empted (TRC_GetBuffer) is before all */
/* references to the variable we're interested in. */
/****************************************************************/
TRC_NRM((TB, _T("Messages now pending: %ld"),
_CD.pendingMessageCount - 1));
_pUt->UT_InterlockedDecrement(&_CD.pendingMessageCount);
#endif
/****************************************************************/
/* Notification: */
/* lParam contains pointer to CD transfer buffer */
/* wParam contains dataLength */
/****************************************************************/
pTransferBuffer = (PCDTRANSFERBUFFER)lParam;
pNotificationFn = pTransferBuffer->hdr.pNotificationFn;
dataLength = (DCUINT) wParam;
pData = &(pTransferBuffer->data[0]);
pInst = pTransferBuffer->hdr.pInst;
TRC_ASSERT((pNotificationFn != NULL),
(TB, _T("NULL pNotificationFn")));
TRC_ASSERT((pInst != NULL), (TB, _T("NULL pInst")));
TRC_NRM((TB, _T("Notification: pfn(%p) pData(%p) dataLength(%u)"),
pNotificationFn, pData, dataLength));
(*pNotificationFn)(pInst, pData, dataLength);
/****************************************************************/
/* Release the memory allocated for this transfer buffer. */
/****************************************************************/
CDFreeTransferBuffer(pTransferBuffer);
}
break;
default:
{
/****************************************************************/
/* Ignore other messages - pass to the default window handler. */
/****************************************************************/
TRC_DBG((TB, _T("Non-notification message %x"), message));
rc = DefWindowProc(hwnd, message, wParam, lParam);
}
break;
}
DC_END_FN();
return(rc);
} /* CDWndProc */