2025-04-27 07:49:33 -04:00

619 lines
14 KiB
C

/**************************************************************************\
* Module Name: perf.c
*
* performance timing calls
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* History:
* 12-Jun-1991 mikeke
*
\**************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include "usercli.h"
#include <string.h>
#include "ntcsrdll.h"
#include "csuser.h"
/**************************************************************************\
\**************************************************************************/
typedef CSR_QLPC_API_MSG *PCSRMSG;
typedef PDWORD (* PINSTUBFUNC)(PDWORD, PDWORD, PDWORD, PDWORD);
typedef void (* POUTSTUBFUNC)(PDWORD, PDWORD);
PDWORD Copy4(PDWORD psrc,PDWORD pdst,PDWORD pparam,PDWORD pmax);
PDWORD Copy5(PDWORD psrc,PDWORD pdst,PDWORD pparam,PDWORD pmax);
PDWORD CopySTR(PDWORD psrc,PDWORD pdst,PDWORD pparam,PDWORD pmax);
#if !defined(_MIPS_) && !defined(_PPC_)
void OutCopy4(
PDWORD psrc,
PDWORD pdst)
{
pdst[0] = psrc[0];
pdst[1] = psrc[1];
pdst[2] = psrc[2];
pdst[3] = psrc[3];
}
PDWORD Copy4(
PDWORD psrc,
PDWORD pdst,
PDWORD pparam,
PDWORD pmax)
{
if (pdst + 5 <= pmax) {
pdst[0] = psrc[0];
pdst[1] = psrc[1];
pdst[2] = psrc[2];
pdst[3] = psrc[3];
return pdst + 4;
}
return 0;
pparam;
}
PDWORD Copy5(
PDWORD psrc,
PDWORD pdst,
PDWORD pparam,
PDWORD pmax)
{
if (pdst + 5 <= pmax) {
pdst[0] = psrc[0];
pdst[1] = psrc[1];
pdst[2] = psrc[2];
pdst[3] = psrc[3];
pdst[4] = psrc[4];
return pdst + 5;
}
return 0;
pparam;
}
PDWORD Copy6(
PDWORD psrc,
PDWORD pdst,
PDWORD pparam,
PDWORD pmax)
{
if (pdst + 6 <= pmax) {
pdst[0] = psrc[0];
pdst[1] = psrc[1];
pdst[2] = psrc[2];
pdst[3] = psrc[3];
pdst[4] = psrc[4];
pdst[5] = psrc[5];
return pdst + 6;
}
return 0;
pparam;
}
PDWORD CopySTR(
PDWORD psrc,
PDWORD pdst,
PDWORD pparam,
PDWORD pmax)
{
PBYTE length = (PBYTE)psrc;
while (*length)
length++;
length = (length - (PBYTE)psrc + (PBYTE)pdst);
length = (PBYTE)(((DWORD)length +3 ) & ~3);
if (length <= (PBYTE)pmax) {
while ((PBYTE)pdst != (PBYTE)length) {
*pdst = *psrc;
pdst++;
psrc++;
}
return (PDWORD)length;
}
return 0;
pparam;
}
#endif
/**************************************************************************\
\**************************************************************************/
PDWORD AIDoClientInStuff(
PDWORD psrc,
PDWORD pbase,
PDWORD ptemplate,
PDWORD pmax);
VOID AIDoClientOutStuff(
PDWORD psrc,
PDWORD pbase,
PDWORD ptemplate);
PDWORD DoClientInStuff(
PDWORD psrc,
PDWORD pbase,
PDWORD ptemplate,
PDWORD pmax)
{
PDWORD pparam;
PDWORD param;
PDWORD pdst;
if (ptemplate[0]) {
pdst = ((PINSTUBFUNC)ptemplate[0])(psrc, pbase, NULL, pmax);
if (!pdst) {
return 0;
}
ptemplate++;
while (ptemplate[0]) {
pparam = (PDWORD)((PBYTE)pbase + ptemplate[1]);
param = (PDWORD)*pparam;
*pparam = (PBYTE)pdst - (PBYTE)pbase;
pdst = ((PINSTUBFUNC)ptemplate[0])(param, pdst, pparam, pmax);
if (!pdst) {
return 0;
}
ptemplate += 2;
}
}
}
VOID DoClientOutStuff(
PDWORD psrc,
PDWORD pdst,
PDWORD ptemplate)
{
PDWORD pparam;
while (ptemplate[0]) {
pparam = (PDWORD)((PBYTE)psrc + ptemplate[1]);
((POUTSTUBFUNC)ptemplate[0])(
(PDWORD)((PBYTE)psrc + *pparam),
*(PDWORD *)((PBYTE)pdst + ptemplate[1])
);
ptemplate += 2;
}
}
/**************************************************************************\
\**************************************************************************/
DWORD MakeCSCall(
DWORD findex,
PDWORD psrc,
PDWORD pInTemplate,
PDWORD pOutTemplate
)
{
PCSR_QLPC_TEB pteb = (PCSR_QLPC_TEB)NtCurrentTeb()->CsrQlpcTeb;
PCSR_QLPC_STACK pstack;
PCSRMSG pmsg;
ULONG retval;
PDWORD pbase;
PDWORD pdst;
PDWORD plast;
PDWORD pmax;
//
// connect to the server
//
if (pteb == NULL) {
pteb = CsrClientThreadConnect();
if (pteb == NULL) {
return 0;
}
}
pstack = pteb->MessageStack;
if (pstack->BatchCount) {
CsrClientSendMessage();
pbase = (PDWORD)((PBYTE)pstack + pstack->Base);
} else {
pbase = (PDWORD)((PBYTE)pstack + pstack->Current);
}
pmax = (PDWORD)((PBYTE)pstack + pstack->Limit);
pmsg = (PCSRMSG)(pbase+1);
//
// is there enough space left on the stack?
//
pdst = (PDWORD)(pmsg + 1);
if (pdst <= pmax) {
//
// copy the data to shared memory
//
if (pInTemplate) {
plast = DoClientInStuff(psrc, pdst, pInTemplate, pmax);
} else {
plast = pdst;
}
if (plast) {
//
// Make the call
//
pmsg->Length = (PBYTE)plast - (PBYTE)pmsg;
pmsg->ApiNumber = findex;
*pbase = pstack->Base;
pstack->Base = pstack->Current+4;
pstack->Current = (PBYTE)pdst - (PBYTE)pstack;
pstack->BatchCount = 1;
retval = CsrClientSendMessage();
pstack->Current = pstack->Base - 4;
pstack->Base = *pbase;
//
// Do any post call copies
//
if (pOutTemplate) {
DoClientOutStuff(pdst, psrc, pOutTemplate);
}
return retval;
}
}
//
// an error occured
//
return 0;
}
/**************************************************************************\
\**************************************************************************/
#if defined(_MIPS_) || defined(_PPC_)
DWORD AIMakeCSCall(
DWORD findex,
PDWORD psrc,
PDWORD pInTemplate,
PDWORD pOutTemplate
)
{
PCSR_QLPC_TEB pteb = (PCSR_QLPC_TEB)NtCurrentTeb()->CsrQlpcTeb;
PCSR_QLPC_STACK pstack;
PCSRMSG pmsg;
ULONG retval;
PDWORD pbase;
PDWORD pdst;
PDWORD plast;
PDWORD pmax;
//
// connect to the server
//
if (pteb == NULL) {
pteb = CsrClientThreadConnect();
if (pteb == NULL) {
return 0;
}
}
pstack = pteb->MessageStack;
if (pstack->BatchCount) {
CsrClientSendMessage();
pbase = (PDWORD)((PBYTE)pstack + pstack->Base);
} else {
pbase = (PDWORD)((PBYTE)pstack + pstack->Current);
}
pmax = (PDWORD)((PBYTE)pstack + pstack->Limit);
pmsg = (PCSRMSG)(pbase+1);
//
// is there enough space left on the stack?
//
if ((PDWORD)((PBYTE)pmsg + sizeof(PCSRMSG)) <= pmax) {
//
// copy the data to shared memory
//
pdst = (PDWORD)(pmsg + 1);
if (pInTemplate) {
plast = AIDoClientInStuff(psrc, pdst, pInTemplate, pmax);
} else {
plast = pdst;
}
if (plast) {
//
// Make the call
//
pmsg->Length = (PBYTE)plast - (PBYTE)pmsg;
pmsg->ApiNumber = findex;
*pbase = pstack->Base;
pstack->Base = pstack->Current+4;
pstack->Current = (PBYTE)pdst - (PBYTE)pstack;
pstack->BatchCount = 1;
retval = CsrClientSendMessage();
pstack->Current = pstack->Base - 4;
pstack->Base = *pbase;
//
// Do any post call copies
//
if (pOutTemplate) {
AIDoClientOutStuff(pdst, psrc, pOutTemplate);
}
return retval;
}
}
//
// an error occured
//
return 0;
}
#endif
/**************************************************************************\
\**************************************************************************/
#ifdef LATER
typedef struct _TESTMSG {
int a;
int b;
RECT *lprc;
int c;
LPSTR lpstr;
RECT rc;
} TESTMSG;
PDWORD CSInTestCall(
PDWORD psrc,
PDWORD pdst,
PDWORD pmax)
{
PDWORD pvar;
TESTMSG *pmsg;
TESTMSG *pparam;
if (pmax > pdst + sizeof(TESTMSG)) {
pmsg = (TESTMSG *)pdst;
pparam = (TESTMSG *)psrc;
pvar = (PDWORD)(pmsg + 1);
pmsg->a = pparam->a;
pmsg->b = pparam->b;
pmsg->c = pparam->c;
pmsg->lprc = (RECT *)(((PBYTE)&(pmsg->rc)) - (PBYTE)pmsg);
pmsg->rc = *(pparam->lprc);
pmsg->lpstr = (LPSTR)((PBYTE)pvar - (PBYTE)pmsg);
pvar = CopySTR((PDWORD)pparam->lpstr, pvar, NULL, pmax);
if (pvar) {
return (PDWORD)pvar;
}
}
return 0;
}
typedef struct _TESTMSG {
HWND hwnd;
int a;
int b;
int c;
int d;
int e;
} TESTMSG;
PDWORD CSInTestCall(
PDWORD psrc,
PDWORD pdst,
PDWORD pmax)
{
TESTMSG *pmsg;
TESTMSG *pparam;
if (pmax > pdst + sizeof(TESTMSG)) {
pmsg = (TESTMSG *)pdst;
pparam = (TESTMSG *)psrc;
pmsg->hwnd = pparam->hwnd;
pmsg->a = pparam->a;
pmsg->b = pparam->b;
pmsg->c = pparam->c;
pmsg->d = pparam->d;
pmsg->e = pparam->e;
return (PDWORD)(pmsg + 1);
}
return 0;
}
#endif
/**************************************************************************\
\**************************************************************************/
typedef PDWORD (* PCSINFUNC)(PDWORD, PDWORD, PDWORD);
typedef PDWORD (* PCSOUTFUNC)(PDWORD, PDWORD);
DWORD CSMakeCall(
DWORD findex,
PDWORD psrc,
PCSINFUNC pInFunc,
PCSOUTFUNC pOutFunc
)
{
PCSR_QLPC_TEB pteb = (PCSR_QLPC_TEB)NtCurrentTeb()->CsrQlpcTeb;
PCSR_QLPC_STACK pstack;
PCSRMSG pmsg;
ULONG retval;
PDWORD pbase;
PDWORD pdst;
PDWORD plast;
PDWORD pmax;
//
// connect to the server
//
if (pteb == NULL) {
pteb = CsrClientThreadConnect();
if (pteb == NULL) {
return 0;
}
}
pstack = pteb->MessageStack;
if (pstack->BatchCount) {
CsrClientSendMessage();
pbase = (PDWORD)((PBYTE)pstack + pstack->Base);
} else {
pbase = (PDWORD)((PBYTE)pstack + pstack->Current);
}
pmax = (PDWORD)((PBYTE)pstack + pstack->Limit);
pmsg = (PCSRMSG)(pbase+1);
//
// is there enough space left on the stack?
//
pdst = (PDWORD)(pmsg + 1);
if (pdst <= pmax) {
//
// copy the data to shared memory
//
if (pInFunc) {
plast = pInFunc(psrc, pdst, pmax);
} else {
plast = pdst;
}
if (plast) {
//
// Make the call
//
pmsg->Length = (PBYTE)plast - (PBYTE)pmsg;
pmsg->ApiNumber = findex;
*pbase = pstack->Base;
pstack->Base = pstack->Current+4;
pstack->Current = (PBYTE)pdst - (PBYTE)pstack;
pstack->BatchCount = 1;
retval = CsrClientSendMessage();
pstack->Current = pstack->Base - 4;
pstack->Base = *pbase;
//
// Do any post call copies
//
if (pOutFunc) {
pOutFunc(pdst, psrc);
}
return retval;
}
}
//
// an error occured
//
return 0;
}
/**************************************************************************\
\**************************************************************************/
// DWORD CTestCall(int a, int b, LPRECT lprc, int c, LPSTR lpstr)
#if 0
DWORD CTestCall(HWND hwnd, int a, int b, int c, int d, int e)
{
return CSMakeCall(
CSR_MAKE_API_NUMBER(4,FI_CTESTCALL),
(PDWORD)&hwnd,
CSInTestCall,
NULL);
}
#endif
/**************************************************************************\
\**************************************************************************/
/**************************************************************************\
\**************************************************************************/
/**************************************************************************\
\**************************************************************************/
#ifdef LATER
DWORD InTestCall[] = {
(DWORD)Copy5,
(DWORD)Copy4,
8,
(DWORD)CopySTR,
16,
0
};
#endif
DWORD InTestCall[] = {
(DWORD)Copy6,
0
};
DWORD ITestCall(HWND hwnd, int a, int b, int c, int d, int e)
{
return MakeCSCall(
CSR_MAKE_API_NUMBER(4,FI_CTESTCALL),
(PDWORD)&hwnd,
InTestCall,
NULL
);
}
DWORD AITestCall(HWND hwnd, int a, int b, int c, int d, int e)
{
#if defined(_MIPS_) || defined(_PPC_)
return AIMakeCSCall(
#else
return MakeCSCall(
#endif
CSR_MAKE_API_NUMBER(4,FI_CTESTCALL),
(PDWORD)&hwnd,
InTestCall,
NULL
);
}
/**************************************************************************\
\**************************************************************************/