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.
 
 
 
 
 
 

353 lines
7.4 KiB

/*++
Copyright (c) 2000-2001 Microsoft Corporation
Module Name:
vststmsgclient.cxx
Abstract:
Implementation of test message classes for the client and holder of
shared methods and variables shared between client and server.
Brian Berkowitz [brianb] 05/22/2000
TBD:
Revision History:
Name Date Comments
brianb 05/22/2000 Created
ssteiner 06/07/2000 Split client and server portions into
two files. vststmsg.cxx contains
the server portion.
--*/
#include "stdafx.h"
#include "vststmsgclient.hxx"
void LogUnexpectedFailure(LPCWSTR wsz, ...);
VSTST_MSG_TYPE_TABLE g_msgTypes[VSTST_MT_MAXMSGTYPE];
void AddMessageType
(
VSTST_MSG_TYPE type,
UINT cbFixed,
UINT cVarPtr,
VSTST_MSG_PRIORITY priority,
VSTST_MSG_HANDLER pfnHandler,
VSTST_VARPTR_TYPE ptype1 = VSTST_VPT_UNDEFINED,
VSTST_VARPTR_TYPE ptype2 = VSTST_VPT_UNDEFINED,
VSTST_VARPTR_TYPE ptype3 = VSTST_VPT_UNDEFINED,
VSTST_VARPTR_TYPE ptype4 = VSTST_VPT_UNDEFINED,
VSTST_VARPTR_TYPE ptype5 = VSTST_VPT_UNDEFINED,
VSTST_VARPTR_TYPE ptype6 = VSTST_VPT_UNDEFINED,
VSTST_VARPTR_TYPE ptype7 = VSTST_VPT_UNDEFINED,
VSTST_VARPTR_TYPE ptype8 = VSTST_VPT_UNDEFINED
)
{
VSTST_MSG_TYPE_TABLE *pEntry = &g_msgTypes[type];
pEntry->cbFixed = cbFixed;
pEntry->cVarPtr = cVarPtr;
pEntry->priority = priority;
pEntry->pfnHandler = pfnHandler;
pEntry->pointerTypes[0] = (BYTE) ptype1;
pEntry->pointerTypes[1] = (BYTE) ptype2;
pEntry->pointerTypes[2] = (BYTE) ptype3;
pEntry->pointerTypes[3] = (BYTE) ptype4;
pEntry->pointerTypes[4] = (BYTE) ptype5;
pEntry->pointerTypes[5] = (BYTE) ptype6;
pEntry->pointerTypes[6] = (BYTE) ptype7;
pEntry->pointerTypes[7] = (BYTE) ptype8;
};
void InitMsgTypes()
{
AddMessageType
(
VSTST_MT_TEXT,
FIELD_OFFSET(VSTST_TEXTMSG, pch),
1,
VSTST_MP_QUEUED,
NULL, // Not needed by client, server will fill in
VSTST_VPT_ANSI
);
AddMessageType
(
VSTST_MT_IMMEDIATETEXT,
FIELD_OFFSET(VSTST_TEXTMSG, pch),
1,
VSTST_MP_IMMEDIATE,
NULL,
VSTST_VPT_ANSI
);
AddMessageType
(
VSTST_MT_FAILURE,
FIELD_OFFSET(VSTST_FAILUREMSG, szFailure),
1,
VSTST_MP_QUEUED,
NULL,
VSTST_VPT_ANSI
);
AddMessageType
(
VSTST_MT_OPERATIONFAILURE,
FIELD_OFFSET(VSTST_OPERATIONFAILUREMSG, szFailedOperation),
1,
VSTST_MP_QUEUED,
NULL,
VSTST_VPT_ANSI
);
AddMessageType
(
VSTST_MT_UNEXPECTEDEXCEPTION,
FIELD_OFFSET(VSTST_UNEXPECTEDEXCEPTIONMSG, szFailedRoutine),
1,
VSTST_MP_QUEUED,
NULL,
VSTST_VPT_ANSI
);
AddMessageType
(
VSTST_MT_SUCCESS,
FIELD_OFFSET(VSTST_SUCCESSMSG, szMsg),
1,
VSTST_MP_QUEUED,
NULL,
VSTST_VPT_ANSI
);
}
CVsTstClientMsg::CVsTstClientMsg() :
m_bcsInitialized(false),
m_rgbMsg(NULL),
m_hPipe(INVALID_HANDLE_VALUE),
m_bSkipWrites(false),
m_seqQueued(0),
m_seqImmediate(0)
{
}
CVsTstClientMsg::~CVsTstClientMsg()
{
delete m_rgbMsg;
if (m_bcsInitialized)
m_cs.Term();
if (m_hPipe != INVALID_HANDLE_VALUE)
CloseHandle(m_hPipe);
}
// initialize messaging to test controller
HRESULT CVsTstClientMsg::Init
(
LONGLONG processId,
UINT cbMaxMsg,
bool bIgnorePipeCreationFailure
)
{
m_processId = processId;
try
{
m_cs.Init();
m_bcsInitialized = true;
}
catch(...)
{
return E_UNEXPECTED;
}
m_hPipe = CreateFile
(
s_wszPipeName,
GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (m_hPipe == INVALID_HANDLE_VALUE)
{
if (bIgnorePipeCreationFailure)
m_bSkipWrites = true;
else
return HRESULT_FROM_WIN32(GetLastError());
}
else
{
m_cbMaxMsgLength = cbMaxMsg;
m_rgbMsg = new BYTE[cbMaxMsg];
if (m_rgbMsg == NULL)
{
CloseHandle(m_hPipe);
m_hPipe = INVALID_HANDLE_VALUE;
return E_OUTOFMEMORY;
}
}
return S_OK;
}
// send a message to the test controller
HRESULT CVsTstClientMsg::SendMessage(VSTST_MSG_TYPE type, void *pv)
{
m_cs.Lock();
VSTST_ASSERT(type < VSTST_MT_MAXMSGTYPE);
VSTST_MSG_TYPE_TABLE *pType = &g_msgTypes[type];
VSTST_MSG_HDR *phdr = (VSTST_MSG_HDR *) m_rgbMsg;
phdr->processId = m_processId;
phdr->type = type;
time(&phdr->time);
if (pType->priority == VSTST_MP_IMMEDIATE)
phdr->sequence = ++m_seqImmediate;
else
phdr->sequence = ++m_seqQueued;
BYTE *pbMsg = phdr->rgb;
size_t cbUsed = pType->cbFixed + FIELD_OFFSET(VSTST_MSG_HDR, rgb) +
pType->cVarPtr * sizeof(PVOID);
if (cbUsed >= m_cbMaxMsgLength)
{
m_cs.Unlock();
return HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
}
// copy in fixed portion of data structure
memcpy(pbMsg, pv, pType->cbFixed);
pbMsg += pType->cbFixed;
// reserve room for pointers
memset(pbMsg, 0, pType->cVarPtr * sizeof(PVOID));
pbMsg += pType->cVarPtr * sizeof(PVOID);
// walk and write out pointer data
VOID **ppv = (VOID **) ((BYTE *) pv + pType->cbFixed);
for(UINT iPtr = 0; iPtr < pType->cVarPtr; iPtr++, ppv++)
{
VSTST_VARPTR_TYPE type = (VSTST_VARPTR_TYPE) pType->pointerTypes[iPtr];
BYTE *pb = NULL;
size_t cb = 0;
switch(type)
{
default:
VSTST_ASSERT(FALSE);
break;
case VSTST_VPT_BYTE:
pb = *(BYTE **) ppv;
cb = *(UINT *) *pb;
break;
case VSTST_VPT_ANSI:
pb = *(BYTE **) ppv;
cb = strlen((char *) pb) + 1;
break;
case VSTST_VPT_UNICODE:
pb = *(BYTE **) ppv;
cb = (wcslen((WCHAR *) pb) + 1) * sizeof(WCHAR);
break;
}
// round up to alignment boundary
size_t cbAlign = (cb + sizeof(PVOID) - 1) & ~(sizeof(PVOID)-1);
// check for buffer overflow
if (cbAlign + cbUsed >= m_cbMaxMsgLength)
{
m_cs.Unlock();
return HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
}
memcpy(pbMsg, pb, cb);
// adjust pointer to alignment boundary
pb += cbAlign;
// adjust amount used
cbUsed += cbAlign;
}
phdr->cbMsg = cbUsed;
phdr->pmsgNext = NULL;
DWORD cbWritten;
if (!WriteFile(m_hPipe, m_rgbMsg, (UINT) cbUsed, &cbWritten, NULL) || cbUsed != cbWritten)
{
m_cs.Unlock();
return HRESULT_FROM_WIN32(GetLastError());
}
VSTST_ASSERT(cbUsed == cbWritten);
m_cs.Unlock();
return S_OK;
}
void CVsTstClientLogger::LogFailure(LPCSTR szFailure)
{
VSTST_ASSERT(m_pClient);
VSTST_FAILUREMSG msg;
msg.szFailure = szFailure;
m_pClient->SendMessage(VSTST_MT_FAILURE, &msg);
}
void CVsTstClientLogger::LogUnexpectedException(LPCSTR szRoutine)
{
VSTST_ASSERT(m_pClient);
VSTST_UNEXPECTEDEXCEPTIONMSG msg;
msg.szFailedRoutine = szRoutine;
m_pClient->SendMessage(VSTST_MT_UNEXPECTEDEXCEPTION, &msg);
}
void CVsTstClientLogger::ValidateResult(HRESULT hr, LPCSTR szOperation)
{
VSTST_ASSERT(m_pClient);
if (FAILED(hr))
{
VSTST_OPERATIONFAILUREMSG msg;
msg.hr = hr;
msg.szFailedOperation = szOperation;
m_pClient->SendMessage(VSTST_MT_OPERATIONFAILURE, &msg);
throw hr;
}
}
void CVsTstClientLogger::LogSuccess(LPCSTR sz)
{
VSTST_ASSERT(m_pClient);
VSTST_SUCCESSMSG msg;
msg.szMsg = sz;
m_pClient->SendMessage(VSTST_MT_SUCCESS, &msg);
}
void CVsTstClientLogger::LogMessage(LPCSTR sz)
{
VSTST_ASSERT(m_pClient);
VSTST_TEXTMSG msg;
msg.pch = sz;
m_pClient->SendMessage(VSTST_MT_TEXT, &msg);
}