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.
531 lines
13 KiB
531 lines
13 KiB
//
|
|
// Client.cpp - client implementation
|
|
//
|
|
#include "precomp.h"
|
|
#include "bidispl.h"
|
|
|
|
#define IS_ARG(c) (((c) == '-') || ((c) == '/'))
|
|
|
|
#ifndef MODULE
|
|
|
|
#define MODULE "BIDITEST:"
|
|
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
|
|
MODULE_DEBUG_INIT( DBG_ERROR | DBG_WARNING | DBG_TRACE | DBG_INFO , DBG_ERROR );
|
|
|
|
#else
|
|
|
|
MODULE_DEBUG_INIT( DBG_ERROR | DBG_WARNING, DBG_ERROR );
|
|
|
|
#endif
|
|
|
|
VOID DbgBreakPoint (VOID)
|
|
{
|
|
}
|
|
|
|
|
|
DWORD gdwCount;
|
|
IBidiRequest ** gpIRequestArray;
|
|
DWORD gdwContainerCount;
|
|
IBidiRequestContainer ** gpIRequestContainerArray;
|
|
DWORD gdwSplCount;
|
|
IBidiSpl ** gpIBidiSplArray;
|
|
DWORD gdwMainLoopCount;
|
|
DWORD gdwLoopCount;
|
|
LPWSTR gpPrinterName;
|
|
LONG gdwRef;
|
|
HANDLE ghEvent;
|
|
|
|
VOID
|
|
CreateRequest (DWORD dwCount)
|
|
{
|
|
HRESULT hr;
|
|
|
|
IBidiRequest * pIReq = NULL ;
|
|
typedef IBidiRequest * PIBidiRequest;
|
|
|
|
gdwCount = dwCount;
|
|
gpIRequestArray = new PIBidiRequest[gdwCount];
|
|
|
|
for (DWORD i = 0; i < gdwCount; i++) {
|
|
hr = ::CoCreateInstance(CLSID_BidiRequest,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IBidiRequest,
|
|
(void**)&pIReq) ;
|
|
gpIRequestArray [i] = pIReq;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
ReleaseRequest ()
|
|
{
|
|
for (DWORD i = 0; i < gdwCount; i++) {
|
|
DWORD dwRef = gpIRequestArray [i]->Release ();
|
|
|
|
SPLASSERT (dwRef == 0);
|
|
if (dwRef != 0) {
|
|
printf("ReleaseRequest: Ref count not zero!\n");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
CreateContainer (DWORD dwContainerCount)
|
|
{
|
|
HRESULT hr;
|
|
ULONG dwRef;
|
|
IBidiRequestContainer * pIReqContainer = NULL ;
|
|
typedef IBidiRequestContainer * PIBidiRequestContainer;
|
|
|
|
gdwContainerCount = dwContainerCount;
|
|
gpIRequestContainerArray = new PIBidiRequestContainer[dwContainerCount];
|
|
|
|
for (DWORD i = 0; i < dwContainerCount; i++) {
|
|
|
|
hr = ::CoCreateInstance(CLSID_BidiRequestContainer,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IBidiRequestContainer,
|
|
(void**)&pIReqContainer) ;
|
|
|
|
gpIRequestContainerArray [i] = pIReqContainer;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ReleaseContainer ()
|
|
{
|
|
for (DWORD i = 0; i < gdwContainerCount; i++) {
|
|
DWORD dwRef = gpIRequestContainerArray [i]->Release ();
|
|
|
|
SPLASSERT (dwRef == 0);
|
|
if (dwRef != 0) {
|
|
printf("ReleaseRequest: Ref count not zero!\n");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
CreateSpl (DWORD dwCount)
|
|
{
|
|
HRESULT hr;
|
|
ULONG dwRef;
|
|
IBidiSpl * pIBidiSpl = NULL ;
|
|
typedef IBidiSpl * PIBidiSpl;
|
|
|
|
gdwSplCount = dwCount;
|
|
gpIBidiSplArray = new PIBidiSpl[dwCount];
|
|
|
|
for (DWORD i = 0; i < dwCount; i++) {
|
|
|
|
hr = ::CoCreateInstance(CLSID_BidiSpl,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IBidiSpl,
|
|
(void**)&pIBidiSpl) ;
|
|
gpIBidiSplArray[i] = pIBidiSpl;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ReleaseSpl ()
|
|
{
|
|
for (DWORD i = 0; i < gdwSplCount; i++) {
|
|
|
|
DWORD dwRef = gpIBidiSplArray [i]->Release ();
|
|
|
|
SPLASSERT (dwRef == 0);
|
|
if (dwRef != 0) {
|
|
printf("ReleaseRequest: Ref count not zero!\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
FillInRequest (DWORD dwIndex)
|
|
{
|
|
IBidiRequest * pIReq = gpIRequestArray[dwIndex];
|
|
DWORD dwValidSize;
|
|
HRESULT hr;
|
|
BIDI_TYPE dwBidiType;
|
|
|
|
#define BIDI_SCHEMA_DUPLEX L"/Printer/Installableoption/Duplexunit"
|
|
#define BIDI_SCHEMA_MULTICHANNEL L"/Capability/MultiChannel"
|
|
#define BIDI_SCHEMA_VERSION L"/Communication/Version"
|
|
#define BIDI_SCHEMA_BIDIPROTOCOL L"/Communication/BidiProtocol"
|
|
#define BIDI_SCHEMA_INK_LEVEL L"/Printer/BlackInk1/Level"
|
|
#define BIDI_SCHEMA_ALERTS L"/Printer/Alerts"
|
|
|
|
static PWSTR pSchemaArray[] = {
|
|
BIDI_SCHEMA_DUPLEX,
|
|
BIDI_SCHEMA_MULTICHANNEL,
|
|
BIDI_SCHEMA_VERSION,
|
|
BIDI_SCHEMA_BIDIPROTOCOL,
|
|
BIDI_SCHEMA_INK_LEVEL,
|
|
BIDI_SCHEMA_ALERTS
|
|
};
|
|
|
|
if (pIReq) {
|
|
|
|
hr = pIReq->SetSchema (pSchemaArray[rand() %( sizeof (pSchemaArray) / sizeof (pSchemaArray[0]))]);
|
|
|
|
dwBidiType = (BIDI_TYPE) (rand() % 7);
|
|
switch (dwBidiType) {
|
|
case BIDI_NULL:
|
|
dwValidSize = 0;
|
|
break;
|
|
case BIDI_INT:
|
|
dwValidSize = sizeof (INT);
|
|
break;
|
|
case BIDI_FLOAT:
|
|
dwValidSize = sizeof (FLOAT);
|
|
break;
|
|
case BIDI_BOOL:
|
|
dwValidSize = sizeof (BOOL);
|
|
break;
|
|
default:
|
|
dwValidSize = rand () %(1024*1024);
|
|
break;
|
|
}
|
|
|
|
PBYTE pByte = new BYTE [dwValidSize];
|
|
|
|
hr = pIReq->SetInputData (dwBidiType, pByte, dwValidSize);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FillInContainer (DWORD dwIndex)
|
|
{
|
|
IBidiRequestContainer * pIReqContainer = gpIRequestContainerArray[dwIndex];
|
|
|
|
if (pIReqContainer) {
|
|
|
|
DWORD dwRequestCount = rand () % gdwCount;
|
|
for (DWORD i = 0; i < dwRequestCount; i++) {
|
|
HRESULT hr = pIReqContainer->AddRequest (gpIRequestArray[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
AccessRequest (IBidiRequest *pIRequest)
|
|
{
|
|
DWORD dwTotoal, i;
|
|
HRESULT hr, hResult;
|
|
LPWSTR pszSchema = NULL;
|
|
BYTE *pData = NULL;
|
|
DWORD uSize;
|
|
DWORD dwType;
|
|
DWORD dwTotal;
|
|
|
|
if (pIRequest) {
|
|
hr = pIRequest->GetResult (&hResult);
|
|
hr = pIRequest->GetEnumCount (&dwTotal);
|
|
|
|
for (i = 0; i < dwTotal; i++) {
|
|
hr = pIRequest->GetOutputData (i, &pszSchema, &dwType, &pData, &uSize);
|
|
|
|
if (pszSchema) {
|
|
CoTaskMemFree (pszSchema);
|
|
}
|
|
|
|
if (pData) {
|
|
CoTaskMemFree (pData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
AccessRequest (DWORD dwIndex)
|
|
{
|
|
IBidiRequest *pIRequest = gpIRequestArray[dwIndex];
|
|
|
|
AccessRequest (pIRequest);
|
|
|
|
}
|
|
|
|
VOID
|
|
AccessContainer (IBidiRequestContainer * pIReqContainer)
|
|
{
|
|
DWORD dwTotal;
|
|
|
|
DBGMSG (DBG_TRACE, ("Enter AccessContainer\n"));
|
|
|
|
if (pIReqContainer) {
|
|
|
|
HRESULT hr = pIReqContainer->GetRequestCount (&dwTotal);
|
|
|
|
if (dwTotal > 0) {
|
|
IEnumUnknown *pEnumIunk;
|
|
IEnumUnknown *pEnumIunk2;
|
|
hr = pIReqContainer->GetEnumObject (&pEnumIunk) ;
|
|
|
|
if (pEnumIunk) {
|
|
|
|
IUnknown ** pIunkArray;
|
|
|
|
if ((rand()%2) == 1) {
|
|
hr = pEnumIunk->Reset ();
|
|
}
|
|
else {
|
|
hr = pEnumIunk->Clone (&pEnumIunk2);
|
|
pEnumIunk->Release ();
|
|
pEnumIunk = pEnumIunk2;
|
|
}
|
|
|
|
DWORD dwEnumIndex = 0;
|
|
pIunkArray = new IUnknown* [dwTotal];
|
|
|
|
while (dwEnumIndex < dwTotal + 2) {
|
|
|
|
IUnknown *pIunk;
|
|
DWORD dwFetched;
|
|
|
|
DWORD dwEnumCount = rand() % (dwTotal + 1);
|
|
|
|
hr = pEnumIunk->Next (dwEnumCount, pIunkArray, &dwFetched);
|
|
|
|
if (SUCCEEDED (hr)) {
|
|
|
|
for (DWORD i = 0; i < dwFetched; i++) {
|
|
IBidiRequest *pIRequest = NULL;
|
|
|
|
hr = pIunkArray[i]->QueryInterface (IID_IBidiRequest, (void **) & pIRequest);
|
|
pIunkArray[i]->Release ();
|
|
AccessRequest (pIRequest);
|
|
pIRequest->Release ();
|
|
|
|
}
|
|
dwEnumIndex +=dwEnumCount;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
pEnumIunk->Release ();
|
|
delete [] pIunkArray;
|
|
}
|
|
}
|
|
}
|
|
DBGMSG (DBG_TRACE, ("Leave AccessContainer\n"));
|
|
}
|
|
|
|
VOID
|
|
AccessContainer (DWORD dwIndex)
|
|
{
|
|
IBidiRequestContainer * pIReqContainer = gpIRequestContainerArray[dwIndex];
|
|
|
|
AccessContainer (pIReqContainer);
|
|
|
|
}
|
|
|
|
VOID
|
|
AccessBidiSpl (IBidiSpl * pIBidiSpl, PWSTR pPrinterName, DWORD dwCount)
|
|
{
|
|
HRESULT hr;
|
|
ULONG dwRef;
|
|
IBidiRequestContainer *pIReqContainer;
|
|
|
|
// Test Open/Close
|
|
//hr = pIBidiSpl->BindDevice (L"No such Printer", 0);
|
|
|
|
hr = pIBidiSpl->BindDevice (pPrinterName, BIDI_ACCESS_USER);
|
|
|
|
for (DWORD i = 0; i < dwCount; i++) {
|
|
DWORD dwContainerIndex = rand() % gdwContainerCount;
|
|
|
|
DBGMSG (DBG_INFO, ("Before MultiSendRecv ... "));
|
|
hr = pIBidiSpl->MultiSendRecv (BIDI_ACTION_GET, gpIRequestContainerArray[dwContainerIndex]);
|
|
DBGMSG (DBG_INFO, ("MultiSendRecv hr=0x%x\n", hr))
|
|
AccessContainer (dwContainerIndex);
|
|
|
|
}
|
|
|
|
hr = pIBidiSpl->UnbindDevice ();
|
|
|
|
}
|
|
|
|
|
|
VOID StartTestThread (void)
|
|
{
|
|
DWORD i;
|
|
|
|
printf("New Thrread ..\n");
|
|
|
|
for (DWORD i = 0; i < gdwMainLoopCount; i++) {
|
|
DWORD dwSplIndex = rand () % (gdwSplCount - 1);
|
|
AccessBidiSpl (gpIBidiSplArray[dwSplIndex], gpPrinterName, rand()%gdwLoopCount);
|
|
}
|
|
|
|
DWORD dwRef = InterlockedDecrement (&gdwRef);
|
|
if (dwRef == 0) {
|
|
SetEvent (ghEvent);
|
|
}
|
|
|
|
printf("Quit Thrread (dwRef = %d)\n", dwRef);
|
|
}
|
|
|
|
VOID
|
|
StartTest (DWORD dwThreadCount)
|
|
{
|
|
for (DWORD i = 0; i < dwThreadCount; i++) {
|
|
CreateThread (NULL, 16*4096, (LPTHREAD_START_ROUTINE ) StartTestThread, NULL,NULL, NULL);
|
|
}
|
|
}
|
|
|
|
void usage()
|
|
{
|
|
printf("\n"
|
|
"usage: biditest [-p pname] [-t n] [-m n] [-l n] [-r n] [-c n] [-s n]\n"
|
|
"\n"
|
|
"where: -p printer name\n"
|
|
" -t Thread Number (default = 1) \n"
|
|
" -m Main loop count (default = 10)\n"
|
|
" -l Loop count (default = 10)\n"
|
|
" -r Request count (default = 100)\n"
|
|
" -c Container count (default = 100)\n"
|
|
" -s Spooler Bidi count (default = 10)\n"
|
|
);
|
|
exit (0);
|
|
}
|
|
|
|
extern "C"
|
|
INT
|
|
_cdecl
|
|
_tmain(
|
|
int argc,
|
|
TCHAR **argv)
|
|
{
|
|
DWORD dwReqCount = 100;
|
|
DWORD dwContainerCount = 100;
|
|
DWORD dwSplCount = 20;
|
|
DWORD dwMainLoopCount = 10;
|
|
DWORD dwLoopCount = 10;
|
|
WCHAR szName [] = L"Test";
|
|
PWSTR pPrinterName = szName;
|
|
DWORD dwThreadCount = 1;
|
|
|
|
HRESULT hr;
|
|
|
|
for (--argc, ++argv; argc; --argc, ++argv) {
|
|
|
|
if (IS_ARG(**argv)) {
|
|
switch (tolower(*++*argv)) {
|
|
case L'?':
|
|
usage();
|
|
break;
|
|
|
|
case L'p':
|
|
++argv;
|
|
--argc;
|
|
pPrinterName = *argv;
|
|
break;
|
|
|
|
case L't':
|
|
++argv;
|
|
--argc;
|
|
dwThreadCount = _ttol (*argv);
|
|
break;
|
|
|
|
case L'm':
|
|
++argv;
|
|
--argc;
|
|
dwMainLoopCount = _ttol (*argv);
|
|
break;
|
|
|
|
case L'l':
|
|
++argv;
|
|
--argc;
|
|
dwLoopCount = _ttol (*argv);
|
|
break;
|
|
|
|
case L'r':
|
|
++argv;
|
|
--argc;
|
|
dwReqCount = _ttol (*argv);
|
|
break;
|
|
|
|
case L'c':
|
|
++argv;
|
|
--argc;
|
|
dwContainerCount = _ttol (*argv);
|
|
break;
|
|
|
|
case L's':
|
|
++argv;
|
|
--argc;
|
|
dwSplCount = _ttol (*argv);
|
|
break;
|
|
|
|
default:
|
|
usage();
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
printf("Invalid Argument %s\n", *argv);
|
|
exit (1);
|
|
}
|
|
}
|
|
|
|
printf("Start Test ..\n");
|
|
hr = CoInitializeEx (NULL, COINIT_MULTITHREADED) ;
|
|
|
|
gdwMainLoopCount = dwMainLoopCount;
|
|
gdwLoopCount = dwLoopCount;
|
|
gpPrinterName = pPrinterName;
|
|
ghEvent = CreateEvent (NULL, NULL, FALSE, NULL);
|
|
|
|
for (;;) {
|
|
printf("Create Components ..\n");
|
|
CreateRequest (dwReqCount);
|
|
CreateContainer ( dwContainerCount);
|
|
CreateSpl (dwSplCount);
|
|
|
|
printf("Fill in data ..\n");
|
|
|
|
for (DWORD i = 0; i < dwReqCount; i++) {
|
|
FillInRequest (i);
|
|
}
|
|
|
|
for (i = 0; i < dwContainerCount; i++) {
|
|
FillInContainer (i);
|
|
}
|
|
|
|
printf("Test ..\n");
|
|
|
|
|
|
gdwRef = dwThreadCount;
|
|
|
|
StartTest (dwThreadCount);
|
|
|
|
WaitForSingleObject (ghEvent, INFINITE);
|
|
ResetEvent (ghEvent);
|
|
|
|
printf("Cleanup ..\n");
|
|
|
|
|
|
ReleaseSpl();
|
|
ReleaseContainer();
|
|
ReleaseRequest();
|
|
}
|
|
|
|
CoUninitialize() ;
|
|
printf("Test successfully finished!\n");
|
|
}
|
|
|
|
|