home *** CD-ROM | disk | FTP | other *** search
- // ===========================================================================
- // File: C O M P E R F . C P P
- #define PURPOSE "This is the reference performance sample for COM/DCOM run on local\n\
- and remote machines. This program is both a client and a server.\n\
- It launches as a client by default, registering its executable as a\n\
- server with COM and creating other instances of itself on a remote and\n\
- local machine to be servers. A single command-line argument is allowed\n\
- for a remote server name. Performance numbers in calls/sec are output\n\
- in tabular form. Tests COM and IDispatch method calls with two security\n\
- levels: default/min and full. Use DCOMCNFG to set default security to \n\
- Authn Lvl to NONE for best comparison. Parameter sizes are varied to see\n\
- effect on security levels(~4/50/4k bytes). Uses psoleperf.dll MIDL generated\n\
- proxy/stub implementation. Put pscomperf.dll in same dir as this exe on\n\
- all machines. Run exe on each machine to automatically register class code\n\
- and proxy/stub dll. You can then run on either machine and pass a remote\n\
- machine name (DNS or IP address) as single cmd-line parameter.\n\n"
-
- // Instructions:
- // Install on one or more machines as described above. Run on command-line as "comperf".
- // A single command-line argument is allowed for a remote server name. E.g.
- // "comperf MyComputer" or "comperf 123.44.44.234" using IP address.
- // This sample may be compiled as UNICODE or ANSI
- //
- // Copyright 1996 Microsoft Corporation. All Rights Reserved.
- // ===========================================================================
-
- // %%Includes: ---------------------------------------------------------------
- #define INC_OLE2
- #define STRICT
- #define LOOPS 2000 // default number of test function calls
- #include <windows.h>
- #include <initguid.h>
- #include <tchar.h>
- #include <stdio.h>
- #include "psperf.h" // MIDL generated header
-
- // %%Constants: --------------------------------------------------------------
- #define cServerThreads 3 // number support threads each server will generate
- #define dispidICOMPerformance_Test1 11
- #define dispidICOMPerformance_Test23 12
- #define szTitleServer TEXT("SERVER: COM Performance Sample")
- #define szTitleClient TEXT("COM Performance Sample")
- const LARGE_INTEGER bZero = {0,0};
-
- // %%IDispatch support
- PARAMDATA paramdata[2] = {{L"i", VT_I4},{L"bstr", VT_BSTR}};
- METHODDATA methoddata[2] = {{L"Test1", ¶mdata[0], 11, 3, CC_CDECL, 1, DISPATCH_METHOD, VT_I4},
- {L"Test23", ¶mdata[1], 12, 4, CC_CDECL, 1, DISPATCH_METHOD, VT_I4}};
- INTERFACEDATA interfacedata = { methoddata, 2 };
-
- // %%Guids: ------------------------------------------------------------------
- // {DDC68870-E08E-11cf-A535-00AA00615B03}
- DEFINE_GUID(CLSID_CTestCOMPerformance,0xddc68870,0xe08e,0x11cf,0xa5,0x35,0x0,0xaa,0x0,0x61,0x5b,0x3);
-
- // %%typedefs: --------------------------------------------------------------
- typedef HRESULT (WINAPI *LPFNREG)();
- typedef struct perf
- {
- TCHAR *szTest;
- float sec[3]; // time for all three methods in ICOMPerformance
- } PERF;
-
- // %%Globals: ----------------------------------------------------------------
- BOOL vfServer = FALSE; // is this instance a server or client?
- BOOL vfRemote = FALSE; // is there a remote server?
- HANDLE vrghThread[cServerThreads]; // worker thread handles
- DWORD vrgtid[cServerThreads]; // worker thread id's
- HANDLE vrghEvent[cServerThreads]; // creation event for each worker
- HANDLE vhEventCliDone;
- HANDLE vhEventServer; // creation-complete event for class-factory
- HANDLE vhEventCliStart;
- HANDLE hKillSvr; // shuts down the server
- UINT viNextThread; // next worker to create an object on
- UINT g_cObjectCount = 0;
- LPSTREAM vpstmMarshalling; // scratch stream used for cross-apt marshalling
- HRESULT vhrThreadStatus; // signals status to class-factory
-
- LPWSTR pszDesc1 = L"String is passed to Test methd of ICOMPerformance";
-
- PERF vrgperfloc[] = {
- { TEXT("COM FreeToApt"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("IDisp FreeToApt"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("COM FreeTo Free"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("IDispFreeToFree"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("COM AptToApt"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("IDispAptToApt"), {-1.0f,-1.0f,-1.0f}},
- { NULL, {-1.0f,-1.0f,-1.0f}} };
-
- PERF vrgperfrmt[] = {
- { TEXT("COM FreeToApt"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("IDisp FreeToApt"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("COM FreeTo Free"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("IDispFreeToFree"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("COM AptToApt"), {-1.0f,-1.0f,-1.0f}},
- { TEXT("IDispAptToApt"), {-1.0f,-1.0f,-1.0f}},
- { NULL, {-1.0f,-1.0f,-1.0f}} };
-
- // %%Prototypes: -------------------------------------------------------------
- LRESULT ServerThreadProc(LPARAM lParam);
- LRESULT ClientThreadProc(LPARAM lParam);
- BOOL FAutoRegister();
- void Message(LPTSTR szPrefix, HRESULT hr);
- void FPrintResults(void);
- BOOL AptFreeCOMTest(int cLoops);
- BOOL AptFreeAutoTest(int cLoops);
- BOOL FreeFreeCOMTest(int cLoops);
- BOOL FreeFreeAutoTest(int cLoops);
- BOOL DoTests(void);
- void Usage(void);
-
- typedef IClientSecurity *LPCLIENTSECURITY;
- typedef ICOMPerformance *LPCOMPERFORMANCE;
- LPCOMPERFORMANCE pCOMApt, pCOMFree, pCOMAptRmt, pCOMFreeRmt;
- LPDISPATCH pAutoApt, pAutoFree, pAutoAptRmt, pAutoFreeRmt;
-
- // %%Classes: ----------------------------------------------------------------
- // the class-factory object exists in the main application apartment/thread
- // and is used to create instances of the worker objects on worker threads.
- class CClassFactory : public IClassFactory
- {
- public:
- // IClassFactory
- STDMETHODIMP QueryInterface(REFIID iid, void **ppv);
- STDMETHODIMP_(ULONG) AddRef(void) { return m_cRef++; }
- STDMETHODIMP_(ULONG) Release(void) { if (--m_cRef == 0){ delete this; return 0; } return m_cRef;}
- STDMETHODIMP CreateInstance(LPUNKNOWN punkOuter, REFIID iid, void **ppv);
- STDMETHODIMP LockServer(BOOL fLock);
-
- CClassFactory() { m_cRef = 1; }
- private:
- ULONG m_cRef;
- };
-
- // this worker object is simple: it simply supports IUnknown. more interesting
- // interfaces can be readily added here and implemented for the worker.
- class CTestCOMPerformance : public ICOMPerformance , public IDispatch
- {
- public:
- // IUnknown
- STDMETHODIMP QueryInterface(REFIID iid, void **ppv);
- STDMETHODIMP_(ULONG) AddRef(void) { return m_cRef++; }
- STDMETHODIMP_(ULONG) Release(void);
-
- // ICOMPerformance
- STDMETHODIMP Test1(int l);
- STDMETHODIMP Test23(BSTR szDesc);
-
- // IDispatch
- STDMETHODIMP GetTypeInfoCount(unsigned int *pcti);
- STDMETHODIMP GetTypeInfo(unsigned int iti, LCID lcid, LPTYPEINFO *ppti);
- STDMETHODIMP GetIDsOfNames(REFIID riid, WCHAR * *rgszNames, unsigned int cNames, LCID lcid, DISPID *pdispid);
- STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags,
- DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexcepinfo, unsigned int *puArgErr);
-
- CTestCOMPerformance() { m_cRef = 1;}
- private:
- ULONG m_cRef;
- };
-
- class CTIMER
- {
- public:
- inline CTIMER() { memset(this, 0, sizeof(*this)); }
- inline void Start() { QueryPerformanceCounter(&m_sStart); }
- inline void Stop() { QueryPerformanceCounter(&m_sStop); }
- inline float OutputTime() { QueryPerformanceFrequency(&m_liFreq);
- return (float)(( m_sStop.LowPart - m_sStart.LowPart)/(float)m_liFreq.LowPart);}
- // data members
- LARGE_INTEGER m_sStart, m_sStop, m_liFreq;
- };
-
- // ---------------------------------------------------------------------------
- // %%Function: Message
- //
- // Formats and displays a message to the console.
- // ---------------------------------------------------------------------------
- void
- Message(LPTSTR szPrefix, HRESULT hr)
- {
- LPTSTR szMessage;
-
- if (hr == S_OK)
- {
- _tprintf(szPrefix);
- _tprintf(TEXT("\n"));
- return;
- }
-
- if (HRESULT_FACILITY(hr) == FACILITY_WINDOWS)
- hr = HRESULT_CODE(hr);
-
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- hr,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
- (LPTSTR)&szMessage,
- 0,
- NULL );
-
- _tprintf(TEXT("%s: %s(%lx)\n"), szPrefix, szMessage, hr);
- LocalFree(szMessage);
- } // Message
-
- // ---------------------------------------------------------------------------
- // %%Function: main
- // ---------------------------------------------------------------------------
- int __cdecl
- main(int argc, CHAR **argv)
- {
- HRESULT hr;
- int i;
- DWORD dwRegister = 0;
- COSERVERINFO csi, *pcsi=NULL;
- WCHAR wsz [MAX_PATH];
- CClassFactory *pcf = NULL;
- LPCLASSFACTORY pcflocal = NULL;
- LPCLASSFACTORY pcfrmt = NULL;
- LPCLIENTSECURITY pclntsec = NULL;
- TCHAR rgch[32];
-
- DWORD AuthnSvc, AuthzSvc, AuthnLvl, ImpLvl, Capabilities;
-
-
- if(!FAutoRegister())
- {
- exit(-1);
- }
- // parse command-line
- if (argc > 1)
- {
- // either started as server or passing in server name
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, argv[1], -1,
- wsz, MAX_PATH);
-
- // register the CTestCOMPerformance class in the registry so
- // that the client can create instances of the server
- if((!lstrcmpW(L"-?", wsz)) || (!lstrcmpW(L"/?", wsz)))
- {
- Usage();
- return 0;
- }
- if(!lstrcmpW(L"-Embedding", wsz))
- vfServer = TRUE;
- else
- {
- // allow a machine-name as the command-line argument
- csi.dwReserved1 = 0;
- csi.pAuthInfo = NULL;
- csi.dwReserved2 = 0;
- csi.pwszName = wsz;
- pcsi = &csi;
- vfRemote = TRUE;
- }
- }
- if(vfServer)
- Message(szTitleServer, S_OK);
- else
- Message(szTitleClient, S_OK);
-
- // initialize COM
- hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
- if (FAILED(hr))
- {
- Message(TEXT("CoInitializeEx"), hr);
- exit(hr);
- }
-
- // create an IStream to be used for marshalling interfaces
- hr = CreateStreamOnHGlobal(NULL, TRUE, &vpstmMarshalling);
- if (FAILED(hr))
- {
- Message(TEXT("CreateStreamOnHGlobal"), hr);
- goto LCleanup;
- }
-
- if (vfServer)
- {
- // create the threads and synchronization events
- // which the server will need
- for (i=0; i<cServerThreads; i++)
- {
- // create the thread suspended so its event can be
- // created using its thread-id and it will be able to
- // use it as soon as it runs
- vrghThread[i] = CreateThread(NULL,
- 0,
- (LPTHREAD_START_ROUTINE)&ServerThreadProc,
- 0,
- CREATE_SUSPENDED,
- &vrgtid[i]);
- if (vrghThread[i] == NULL)
- {
- hr = GetLastError();
- goto LCleanup;
- }
-
- // this event signals to a worker thread to create a new CTestCOMPerformance
- wsprintf(rgch, TEXT("Thread_%d"), vrgtid[i]);
- vrghEvent[i] = CreateEvent(NULL, FALSE, FALSE, rgch);
- if (vrghEvent[i] == NULL)
- {
- hr = GetLastError();
- goto LCleanup;
- }
- // now that the event is available, let the thread run
- ResumeThread(vrghThread[i]);
- }
- hKillSvr = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (hKillSvr == NULL)
- {
- hr = GetLastError();
- goto LCleanup;
- }
-
- // this signals the status of a worker threads creation after
- // receiving its create signal via vrghEvent[i]
- vhEventServer = CreateEvent(NULL, FALSE, FALSE, TEXT("Server"));
- if (vhEventServer == NULL)
- {
- hr = GetLastError();
- goto LCleanup;
- }
- pcf = new CClassFactory;
- if(pcf == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto LCleanup;
- }
-
- // register the class-factory with COM
- hr = CoRegisterClassObject(CLSID_CTestCOMPerformance,
- (IUnknown *)pcf,
- CLSCTX_LOCAL_SERVER,
- REGCLS_MULTIPLEUSE,
- &dwRegister);
- if (FAILED(hr))
- {
- Message(TEXT("CoRegisterClassObject"), hr);
- goto LCleanup;
- }
-
- Message(TEXT("Server waiting"), S_OK);
- WaitForSingleObject(hKillSvr, INFINITE);
- Sleep(7000); // allow time for last Release call processing
- delete pcf;
- pcf = NULL;
- }
-
- else // client case
- {
- pCOMApt = pCOMFree = pCOMAptRmt =pCOMFreeRmt = NULL;
- pAutoFree = pAutoFree = pAutoAptRmt = pAutoFreeRmt = NULL;
-
- // get local class factory
- hr = CoGetClassObject(CLSID_CTestCOMPerformance, CLSCTX_LOCAL_SERVER, NULL,
- IID_IClassFactory, (void**)&pcflocal);
- if(FAILED(hr))
- {
- Message(TEXT("CoGetClassObject:"), hr);
- goto LCleanup;
- }
- // apt-model obj
- hr = pcflocal->CreateInstance(NULL, IID_ICOMPerformance, (void**)&pCOMApt);
- if (FAILED(hr))
- {
- Message(TEXT("Create Local Apt Instance:"), hr);
- goto LCleanup;
- }
- hr = pCOMApt->QueryInterface(IID_IDispatch, (void**)&pAutoApt);
- if (FAILED(hr))
- {
- Message(TEXT("QI for pAutoApt:"), hr);
- goto LCleanup;
- }
- // get free-threaded obj
- hr = pcflocal->CreateInstance(NULL, IID_ICOMPerformance, (void**)&pCOMFree);
- if (FAILED(hr))
- {
- Message(TEXT("Create Local Free Instance"), hr);
- goto LCleanup;
- }
- hr = pCOMFree->QueryInterface(IID_IDispatch, (void**)&pAutoFree);
- if (FAILED(hr))
- {
- Message(TEXT("QI for pAutoFree"), hr);
- goto LCleanup;
- }
- hr = pcflocal->Release();
- pcflocal = NULL;
- if(vfRemote)
- {
- hr = CoGetClassObject(CLSID_CTestCOMPerformance, CLSCTX_REMOTE_SERVER, pcsi,
- IID_IClassFactory, (void**)&pcfrmt);
- if(FAILED(hr))
- {
- Message(TEXT("CoGetClassObject for remote CF"), hr);
- vfRemote = FALSE;
- goto LContinue;
- }
- // apt-model obj
- hr = pcfrmt->CreateInstance(NULL, IID_ICOMPerformance, (void**)&pCOMAptRmt);
- if (FAILED(hr))
- {
- Message(TEXT("Create Remote Instance"), hr);
- goto LCleanup;
- }
- hr = pCOMAptRmt->QueryInterface(IID_IDispatch, (void**)&pAutoAptRmt);
- if (FAILED(hr))
- {
- Message(TEXT("QI for pAutoAptFreeRmt"), hr);
- goto LCleanup;
- }
- // get free-threaded obj
- hr = pcfrmt->CreateInstance(NULL, IID_ICOMPerformance, (void**)&pCOMFreeRmt);
- if (FAILED(hr))
- {
- Message(TEXT("Create Remote Free Instance"), hr);
- goto LCleanup;
- }
- hr = pCOMFreeRmt->QueryInterface(IID_IDispatch, (void**)&pAutoFreeRmt);
- if (FAILED(hr))
- {
- Message(TEXT("QI for pAutoFreeFreeRmt"), hr);
- goto LCleanup;
- }
- hr = pcfrmt->Release();
- pcfrmt = NULL;
- }
- LContinue:
- // create apartment thread for client
- DWORD dwClienttid;
- // create the thread suspended so its event can be
- // created using its thread-id and it will be able to
- // use it as soon as it runs
- HANDLE hClientThread = CreateThread(NULL,
- 0,
- (LPTHREAD_START_ROUTINE)&ClientThreadProc,
- 0,
- CREATE_SUSPENDED,
- &dwClienttid);
- if (hClientThread == NULL)
- {
- hr = GetLastError();
- goto LCleanup;
- }
- wsprintf(rgch, TEXT("Thread_%d"), dwClienttid);
-
- vhEventCliStart = CreateEvent(NULL, FALSE, FALSE, rgch);
- if (vhEventCliStart == NULL)
- {
- hr = GetLastError();
- goto LCleanup;
- }
- vhEventCliDone = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (vhEventCliDone == NULL)
- {
- hr = GetLastError();
- goto LCleanup;
- }
- // Marshall local apt thread
- hr = vpstmMarshalling->Seek(bZero, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- throw hr;
- hr = CoMarshalInterface(vpstmMarshalling,
- IID_IUnknown,
- (ICOMPerformance*)pCOMApt,
- MSHCTX_INPROC,
- NULL,
- MSHLFLAGS_NORMAL);
- if (FAILED(hr))
- throw hr;
- // now that the event is available, let the thread run
- ResumeThread(hClientThread);
- SetEvent(vhEventCliStart);
- WaitForSingleObject(vhEventCliDone, INFINITE);
-
- if(vfRemote && NULL != pCOMAptRmt)
- {
- // Marshall local apt thread
- hr = vpstmMarshalling->Seek(bZero, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- throw hr;
- hr = CoMarshalInterface(vpstmMarshalling,
- IID_IUnknown,
- (ICOMPerformance*)pCOMAptRmt,
- MSHCTX_INPROC,
- NULL,
- MSHLFLAGS_NORMAL);
- if (FAILED(hr))
- throw hr;
- SetEvent(vhEventCliStart);
- WaitForSingleObject(vhEventCliDone, INFINITE);
- }
-
- // Test
- _tprintf(TEXT("Output in Calls per sec\n"));
- _tprintf(TEXT("DEF Sec:\t\tLOCAL\t\t\tREMOTE\n"));
- // Do all tests
- if(!DoTests())
- goto LCleanup;
- // Up security on proxies
- // Get current security
- hr = pCOMApt->QueryInterface(IID_IClientSecurity, (void**)&pclntsec);
- hr = pclntsec->QueryBlanket(pCOMApt, &AuthnSvc, &AuthzSvc, NULL, &AuthnLvl, &ImpLvl, NULL,
- &Capabilities);
-
- _tprintf(TEXT("Increasing local security from AuthnLvl:%d ImpLvl:%d\n"), AuthnLvl, ImpLvl);
-
- hr = pclntsec->SetBlanket(pCOMApt, AuthnSvc, AuthzSvc, NULL, 6,
- 4, NULL, Capabilities);
- hr = pclntsec->QueryBlanket(pCOMApt, &AuthnSvc, &AuthzSvc, NULL, &AuthnLvl, &ImpLvl, NULL,
- &Capabilities);
-
- _tprintf(TEXT("Local security is now AuthnLvl:%d ImpLvl:%d\n"), AuthnLvl, ImpLvl);
-
- pclntsec->Release();
- pclntsec = NULL;
- hr = pCOMFree->QueryInterface(IID_IClientSecurity, (void**)&pclntsec);
- hr = pclntsec->SetBlanket(pCOMFree, AuthnSvc, AuthzSvc, NULL, 6,
- 4, NULL, Capabilities);
- pclntsec->Release();
- pclntsec = NULL;
- hr = pAutoApt->QueryInterface(IID_IClientSecurity, (void**)&pclntsec);
- hr = pclntsec->SetBlanket(pAutoApt, AuthnSvc, AuthzSvc, NULL, 6,
- 4, NULL, Capabilities);
- pclntsec->Release();
- pclntsec = NULL;
- hr = pAutoFree->QueryInterface(IID_IClientSecurity, (void**)&pclntsec);
- hr = pclntsec->SetBlanket(pAutoFree, AuthnSvc, AuthzSvc, NULL, 6,
- 4, NULL, Capabilities);
- pclntsec->Release();
- pclntsec = NULL;
- if(vfRemote)
- {
- hr = pCOMAptRmt->QueryInterface(IID_IClientSecurity, (void**)&pclntsec);
- hr = pclntsec->QueryBlanket(pCOMAptRmt, &AuthnSvc, &AuthzSvc, NULL, &AuthnLvl, &ImpLvl, NULL,
- &Capabilities);
-
- _tprintf(TEXT("Increasing remote security from AuthnLvl:%d ImpLvl:%d\n"), AuthnLvl, ImpLvl);
-
- hr = pclntsec->SetBlanket(pCOMAptRmt, AuthnSvc, AuthzSvc, NULL, 6,
- 4, NULL, Capabilities);
-
- _tprintf(TEXT("Remote security is now AuthnLvl:%d ImpLvl:%d\n"), AuthnLvl, ImpLvl);
-
- pclntsec->Release();
- pclntsec = NULL;
- hr = pCOMFreeRmt->QueryInterface(IID_IClientSecurity, (void**)&pclntsec);
- hr = pclntsec->SetBlanket(pCOMFreeRmt, AuthnSvc, AuthzSvc, NULL, 6,
- 4, NULL, Capabilities);
- pclntsec->Release();
- pclntsec = NULL;
- hr = pAutoAptRmt->QueryInterface(IID_IClientSecurity, (void**)&pclntsec);
- hr = pclntsec->SetBlanket(pAutoAptRmt, AuthnSvc, AuthzSvc, NULL, 6,
- 4, NULL, Capabilities);
- pclntsec->Release();
- pclntsec = NULL;
- hr = pAutoFreeRmt->QueryInterface(IID_IClientSecurity, (void**)&pclntsec);
- hr = pclntsec->SetBlanket(pAutoFreeRmt, AuthnSvc, AuthzSvc, NULL, 6,
- 4, NULL, Capabilities);
- pclntsec->Release();
- pclntsec = NULL;
- }
- // Do all tests with FULL sec
- // Apt to Apt first
- // Marshall local apt thread
- hr = vpstmMarshalling->Seek(bZero, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- throw hr;
- hr = CoMarshalInterface(vpstmMarshalling,
- IID_IUnknown,
- (ICOMPerformance*)pCOMApt,
- MSHCTX_INPROC,
- NULL,
- MSHLFLAGS_NORMAL);
- if (FAILED(hr))
- throw hr;
- // now that the event is available, let the thread run
- ResumeThread(hClientThread);
- SetEvent(vhEventCliStart);
- WaitForSingleObject(vhEventCliDone, INFINITE);
-
- if(vfRemote && NULL != pCOMAptRmt)
- {
- // Marshall local apt thread
- hr = vpstmMarshalling->Seek(bZero, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- throw hr;
- hr = CoMarshalInterface(vpstmMarshalling,
- IID_IUnknown,
- (ICOMPerformance*)pCOMAptRmt,
- MSHCTX_INPROC,
- NULL,
- MSHLFLAGS_NORMAL);
- if (FAILED(hr))
- throw hr;
- SetEvent(vhEventCliStart);
- WaitForSingleObject(vhEventCliDone, INFINITE);
- }
- _tprintf(TEXT("Modified Sec:\t\tLOCAL\t\t\tREMOTE\n"));
- DoTests();
- }
- LCleanup:
- if (vpstmMarshalling != NULL)
- vpstmMarshalling->Release();
- if (vfServer)
- {
- // we explicitly don't clean up threads and events
- if (dwRegister != 0)
- CoRevokeClassObject(dwRegister);
- if(NULL != pcf)
- delete pcf;
- }
- else // client
- {
- // client case: release objects
- if(NULL != pcflocal)
- hr = pcflocal->Release();
- if(NULL != pcfrmt)
- hr = pcfrmt->Release();
- if(NULL != pCOMFree)
- hr = pCOMFree->Release();
- if(NULL != pAutoFree)
- hr = pAutoFree->Release();
- if(NULL != pCOMApt)
- hr = pCOMApt->Release();
- if(NULL != pAutoApt)
- hr = pAutoApt->Release();
- if(NULL != pCOMFreeRmt)
- hr = pCOMFreeRmt->Release();
- if(NULL != pAutoFreeRmt)
- hr = pAutoFreeRmt->Release();
- if(NULL != pCOMAptRmt)
- hr = pCOMAptRmt->Release();
- if(NULL != pAutoAptRmt)
- hr = pAutoAptRmt->Release();
- }
- CoUninitialize();
- return hr;
- } // main
-
- // ---------------------------------------------------------------------------
- // %%Function: FAutoRegister
- // Registers the CTestCOMPerformance class in the registry.
- // ---------------------------------------------------------------------------
- BOOL
- FAutoRegister()
- {
- static TCHAR szClassDesc[] = TEXT("COM Performance Sample");
- static TCHAR szCLSIDEntry[] = TEXT("CLSID\\{DDC68870-E08E-11cf-A535-00AA00615B03}");
- TCHAR szBuf[512];
- TCHAR szPath[512];
- HKEY hkeyT = NULL;
-
-
- HRESULT hr;
- LPFNREG lpfn = NULL;
- HINSTANCE hLib = NULL;
-
- // register class code
- if ((RegSetValue(HKEY_CLASSES_ROOT, szCLSIDEntry, REG_SZ, szClassDesc,
- lstrlen(szClassDesc)) != ERROR_SUCCESS) ||
- (RegCreateKey(HKEY_CLASSES_ROOT, szCLSIDEntry, &hkeyT)
- != ERROR_SUCCESS) ||
- !GetModuleFileName(NULL, szBuf, sizeof(szBuf)))
- return FALSE;
- lstrcpy(szPath, szBuf);
- if (RegSetValue(hkeyT, TEXT("LocalServer32"), REG_SZ, szBuf, lstrlen(szBuf))
- != ERROR_SUCCESS)
- goto LErrExit;
- RegCloseKey(hkeyT);
- hkeyT = NULL;
- // Register the ICOMPerformance MIDL-generated proxy-stub component
- hLib = LoadLibrary(TEXT("psperf.dll"));
- if (NULL == hLib)
- {
- goto LErrExit;
- }
- // Find entry point.
- lpfn = (LPFNREG)GetProcAddress(hLib, TEXT("DllRegisterServer"));
- if (lpfn == NULL)
- {
- //Message(_T("Couldn't find entry point in DLL"), S_OK); //unable to locate entry point
- goto LErrExit;
- }
- hr = (*lpfn)();
-
- FreeLibrary(hLib);
- if(SUCCEEDED(hr))
- return TRUE;
- LErrExit:
- if(NULL != hkeyT)
- RegCloseKey(hkeyT);
- return FALSE;
- } // FAutoRegister
-
- // ===========================================================================
- // C C L A S S F A C T O R Y
- // ===========================================================================
-
- // ---------------------------------------------------------------------------
- // %%Function: CClassFactory::QueryInterface
- // Returns a new reference of the specified iid-type to a CClassFactory.
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CClassFactory::QueryInterface(REFIID iid, void **ppv)
- {
- *ppv = NULL;
-
- if (iid == IID_IClassFactory || iid == IID_IUnknown)
- {
- *ppv = (IClassFactory *)this;
- }
- if (*ppv != NULL)
- {
- AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- } // CClassFactory::QueryInterface
-
- // ---------------------------------------------------------------------------
- // %%Function: CClassFactory::CreateInstance
- // Creates a new instance of a CTestCOMPerformance on the next worker thread.
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CClassFactory::CreateInstance(LPUNKNOWN punkOuter, REFIID iid, void **ppv)
- {
- LPUNKNOWN punk;
- HRESULT hr;
-
- *ppv = NULL;
- if (punkOuter != NULL)
- return CLASS_E_NOAGGREGATION;
-
- // trigger the worker thread that we want to create an object
- SetEvent(vrghEvent[viNextThread]);
-
- // now wait for the object to signal its completion
- WaitForSingleObject(vhEventServer, INFINITE);
-
- // once the worker thread signals completion, vhrThreadStatus
- // lets us know if the creation process was successful, and if
- // vpstmMarshalling creates a marshalled interface pointer
- if (FAILED(vhrThreadStatus))
- return vhrThreadStatus;
-
- // unmarshal an IUnknown from the scratch stream. if unmarshaling
- // fails, it takes care of releasing the object inside the marshal-data
- hr = vpstmMarshalling->Seek(bZero, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- return hr;
- hr = CoUnmarshalInterface(vpstmMarshalling, IID_IUnknown, (void **)&punk);
- if (FAILED(hr))
- return hr;
-
- // get a reference to the interface asked for
- hr = punk->QueryInterface(iid, ppv);
- punk->Release();
- ++g_cObjectCount;
- viNextThread++;
- // viNextThread %= cServerThreads;
-
- return hr;
- } // CClassFactory::CreateInstance
-
- STDMETHODIMP
- CClassFactory::LockServer(BOOL fLock)
- {
- // there's no need to support this for this sample
- return E_FAIL;
- } // CClassFactory::LockServer
-
-
- // ===========================================================================
- // C O B J E C T
- // ===========================================================================
-
- // ---------------------------------------------------------------------------
- // %%Function: ServerThreadProc
- // The worker thread function. Handles messages for objects of its thread/apt
- // and creates new objects.
- // ---------------------------------------------------------------------------
- LRESULT
- ServerThreadProc(LPARAM lParam)
- {
- HRESULT hr;
- MSG msg;
- int iThread;
-
- // figure out which thread this is: it needs its synchronization event
- for (iThread=0; iThread<cServerThreads; iThread++)
- {
- if (vrgtid[iThread] == GetCurrentThreadId())
- break;
- }
- if (iThread==cServerThreads)
- return E_UNEXPECTED;
-
- // initialize COM
- if((0 == iThread) || (2 == iThread))
- {
- hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- Message(TEXT("Apartment Thread"), hr);
- }
- else
- {
- hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
- Message(TEXT("Free-threaded Model"), hr);
- }
- if (FAILED(hr))
- {
- MessageBeep(0);
- return hr;
- }
-
- // apartment message/event loop
- // here worker message loops last forever. in situations without a
- // static number of worker threads, the loop could easily be terminated by
- // WM_QUITs sent from the main thread which might manage the worker thread
- // pool more carefully.
- while (TRUE)
- {
- DWORD dwWaitResult;
-
- // wait for any message sent or posted to this queue
- // or for one of the passed handles to become signaled
- dwWaitResult = MsgWaitForMultipleObjects(1, &vrghEvent[iThread],
- FALSE, INFINITE, QS_ALLINPUT);
-
- // result tells us the type of event we have:
- // a message or a signaled handle
-
- // if there are one or more messages in the queue ...
- if (dwWaitResult == (WAIT_OBJECT_0 + 1))
- {
- // dispatch all of the messages in this next loop
- // (here is where we'd check for WM_QUITs to end this
- // worker thread if we wanted to)
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- DispatchMessage(&msg);
- }
- else
- {
- // this thread was signaled to create a new object
- try
- {
- LPUNKNOWN punk;
-
- // create a new CTestCOMPerformance
- punk = (ICOMPerformance *)new CTestCOMPerformance;
- if (punk == NULL)
- throw E_OUTOFMEMORY;
-
- hr = vpstmMarshalling->Seek(bZero, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- throw hr;
- hr = CoMarshalInterface(vpstmMarshalling,
- IID_IUnknown,
- punk,
- MSHCTX_INPROC,
- NULL,
- MSHLFLAGS_NORMAL);
- if (FAILED(hr))
- throw hr;
-
- // punk is now referenced by its marshal-data in vpstmMarshalling.
- // we release our local reference here so the unmarshaller will
- // have the sole reference. a common mistake is to forget this
- // release and end up with orphaned objects in the server.
- punk->Release();
- vhrThreadStatus = S_OK;
- }
- catch (HRESULT hr)
- {
- vhrThreadStatus = hr;
- }
- SetEvent(vhEventServer);
- }
-
- }
-
- CoUninitialize();
- return msg.wParam;
- } // ServerThreadProc
-
- // ---------------------------------------------------------------------------
- // %%Function: ServerThreadProc
- // The worker thread function. Handles messages for objects of its thread/apt
- // and creates new objects.
- // ---------------------------------------------------------------------------
- LRESULT
- ClientThreadProc(LPARAM lParam)
- {
- HRESULT hr;
- MSG msg;
- UINT cCount = 0;
- hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if (FAILED(hr))
- {
- return hr;
- }
- while (TRUE)
- {
- DWORD dwWaitResult;
-
- // wait for any message sent or posted to this queue
- // or for one of the passed handles to become signaled
- dwWaitResult = MsgWaitForMultipleObjectsEx(1, &vhEventCliStart,
- INFINITE, QS_SENDMESSAGE, 0);
-
- // result tells us the type of event we have:
- // a message or a signaled handle
-
- // if there are one or more messages in the queue ...
- if (dwWaitResult == (WAIT_OBJECT_0 + 1))
- {
- // dispatch all of the messages in this next loop
- // (here is where we'd check for WM_QUITs to end this
- // worker thread if we wanted to)
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- DispatchMessage(&msg);
- }
- else
- {
- // this thread was signaled to test Apt to Apt
- try
- {
- //Message(TEXT("Testing Apt to Apt"), hr);
- LPUNKNOWN punk;
- LPDISPATCH pdisp;
- // unmarshal an IUnknown from the scratch stream. if unmarshaling
- // fails, it takes care of releasing the object inside the marshal-data
- hr = vpstmMarshalling->Seek(bZero, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- return hr;
- hr = CoUnmarshalInterface(vpstmMarshalling, IID_IUnknown, (void **)&punk);
- if (FAILED(hr))
- return hr;
- ICOMPerformance *pcomperf = NULL;
- // get a reference to ICOMPerformance and IDispatch interface
- hr = punk->QueryInterface(IID_ICOMPerformance, (void**)&pcomperf);
- hr = punk->QueryInterface(IID_IDispatch, (void**)&pdisp);
- LONG i, k;
- CTIMER tmElapsed;
- BSTR bstr1, bstr2;
- bstr1 = SysAllocString(pszDesc1);
- bstr2 = SysAllocStringByteLen((const char *)pszDesc1, 4096);
- // Test1
- tmElapsed.Start();
- for (i=0; i<LOOPS; i++)
- k = (LONG)pcomperf->Test1(i);
- tmElapsed.Stop();
- if(cCount && vfRemote)
- vrgperfrmt[4].sec[0] = tmElapsed.OutputTime();
- else
- vrgperfloc[4].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- for (i=0; i<LOOPS; i++)
- k = (LONG)pcomperf->Test23(bstr1);
- tmElapsed.Stop();
- if(cCount && vfRemote)
- vrgperfrmt[4].sec[1] = tmElapsed.OutputTime();
- else
- vrgperfloc[4].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- for (i=0; i<LOOPS; i++)
- k = (LONG)pcomperf->Test23(bstr2);
- tmElapsed.Stop();
- if(cCount && vfRemote)
- vrgperfrmt[4].sec[2] = tmElapsed.OutputTime();
- else
- vrgperfloc[4].sec[2] = tmElapsed.OutputTime();
- // Now IDispatch
- VARIANTARG rgvt[1];
- DISPPARAMS dispparams = { rgvt, NULL, 1, 0 };
- EXCEPINFO excepinfo;
-
- VARIANT vtResult;
- UINT argerr;
- // Test1
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<LOOPS; i++)
- {
- V_VT(&rgvt[0]) = VT_I4;
- V_I4(&rgvt[0]) = i;
- hr = pdisp->Invoke(dispidICOMPerformance_Test1, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- if(cCount && vfRemote)
- vrgperfrmt[5].sec[0] = tmElapsed.OutputTime();
- else
- vrgperfloc[5].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<LOOPS; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr1;
- hr = pdisp->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- if(cCount && vfRemote)
- vrgperfrmt[5].sec[1] = tmElapsed.OutputTime();
- else
- vrgperfloc[5].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<LOOPS; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr2;
- hr = pdisp->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- if(cCount && vfRemote)
- vrgperfrmt[5].sec[2] = tmElapsed.OutputTime();
- else
- vrgperfloc[5].sec[2] = tmElapsed.OutputTime();
- SysFreeString(bstr1);
- SysFreeString(bstr2);
- hr = pcomperf->Release();
- hr = pdisp->Release();
- hr = punk->Release();
-
- vhrThreadStatus = S_OK;
- }
- catch (HRESULT hr)
- {
- vhrThreadStatus = hr;
- }
- SetEvent(vhEventCliDone);
- if(cCount)
- --cCount;
- else
- ++cCount;
- }
- }
- CoUninitialize();
- return msg.wParam;
- } // ClientThreadProc
- // ---------------------------------------------------------------------------
- // %%Function: CTestCOMPerformance::QueryInterface
- // Returns a new reference of the specified iid-type to a CTestCOMPerformance.
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CTestCOMPerformance::QueryInterface(REFIID iid, void **ppv)
- {
- *ppv = NULL;
-
- if (iid == IID_IUnknown || iid == IID_ICOMPerformance)
- {
- *ppv = (ICOMPerformance *)this;
- }
- else if (iid == IID_IDispatch)
- *ppv = (IDispatch *)this;
- if (*ppv == NULL)
- {
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- } // CTestCOMPerformance::QueryInterface
-
- // ---------------------------------------------------------------------------
- // %%Function: CTestCOMPerformance::Release
- // Handles releases of references to a CTestCOMPerformance. Purpose here is to have code
- // which alters the global state which is displayed in the servers UI.
- // ---------------------------------------------------------------------------
- STDMETHODIMP_(ULONG)
- CTestCOMPerformance::Release(void)
- {
- if (--m_cRef == 0)
- {
- --g_cObjectCount;
- delete this;
- Message(TEXT("Object Deleted"), S_OK);
- if(g_cObjectCount == 0) SetEvent(hKillSvr);
- return 0;
- }
- return m_cRef;
- } // CTestCOMPerformance::Release
-
- // ---------------------------------------------------------------------------
- // %%Function: CTestCOMPerformance::GetTypeInfoCount
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CTestCOMPerformance::GetTypeInfoCount(UINT *pctInfo)
- {
- *pctInfo = 1;
- return S_OK;
- } // CTestCOMPerformance::GetTypeInfoCount
-
- // ---------------------------------------------------------------------------
- // %%Function: CTestCOMPerformance::GetTypeInfo
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CTestCOMPerformance::GetTypeInfo(unsigned int itInfo, LCID lcid, LPTYPEINFO *ppti)
- {
- HRESULT hr;
-
- if (ppti == NULL)
- return E_POINTER;
- hr = CreateDispTypeInfo( &interfacedata, 0, ppti);
- return hr;
- } // CTestCOMPerformance::GetTypeInfo
-
- // ---------------------------------------------------------------------------
- // %%Function: CTestCOMPerformance::GetIDsOfNames
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CTestCOMPerformance::GetIDsOfNames(REFIID riid, WCHAR * *rgszNames, unsigned int cNames, LCID lcid, DISPID *pdispid)
- {
- return E_NOTIMPL;
- } // CTestCOMPerformance::GetIDsOfNames
-
- // ---------------------------------------------------------------------------
- // %%Function: CTestCOMPerformance::Invoke
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CTestCOMPerformance::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult,
- EXCEPINFO *pexcepinfo, unsigned int *puArgErr)
- {
- LPTYPEINFO pti = NULL;
- HRESULT hr = GetTypeInfo(0, lcid, &pti);
- if(FAILED(hr))
- return hr;
-
- hr = pti->Invoke((ICOMPerformance*)this, dispidMember,
- wFlags, pdispparams, pvarResult,
- pexcepinfo, puArgErr);
- hr = pti->Release();
- return hr;
- } // CTestCOMPerformance::Invoke
-
-
- STDMETHODIMP
- CTestCOMPerformance::Test1(int l)
- {
- return S_OK;
- }
-
- STDMETHODIMP
- CTestCOMPerformance::Test23(BSTR bstr)
- {
- return S_OK;
- }
-
- // Tests
- BOOL
- AptFreeCOMTest(int cLoops)
- {
- LONG i, k;
- CTIMER tmElapsed;
- BSTR bstr1, bstr2;
- bstr1 = SysAllocString(pszDesc1);
- bstr2 = SysAllocStringByteLen((const char *)pszDesc1, 4096);
- // Local
- // Test1
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMApt->Test1(i);
- tmElapsed.Stop();
- vrgperfloc[0].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMApt->Test23(bstr1);
- tmElapsed.Stop();
- vrgperfloc[0].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMApt->Test23(bstr2);
- tmElapsed.Stop();
- vrgperfloc[0].sec[2] = tmElapsed.OutputTime();
-
- // Remote
- if(vfRemote)
- {
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMAptRmt->Test1(i);
- tmElapsed.Stop();
- vrgperfrmt[0].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMAptRmt->Test23(bstr1);
- tmElapsed.Stop();
- vrgperfrmt[0].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMAptRmt->Test23(bstr2);
- tmElapsed.Stop();
- vrgperfrmt[0].sec[2] = tmElapsed.OutputTime();
-
- }
- SysFreeString(bstr1);
- SysFreeString(bstr2);
- return TRUE;
- }
-
- BOOL
- AptFreeAutoTest(int cLoops)
- {
- HRESULT hr;
- static VARIANTARG rgvt[1];
- static DISPPARAMS dispparams = { rgvt, NULL, 1, 0 };
- static EXCEPINFO excepinfo;
- VARIANT vtResult;
- UINT argerr;
- LONG i, k;
- CTIMER tmElapsed;
- BSTR bstr1, bstr2;
- bstr1 = SysAllocString(pszDesc1);
- bstr2 = SysAllocStringByteLen((const char *)pszDesc1, 4096);
-
- // Test1
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_I4;
- V_I4(&rgvt[0]) = i;
- hr = pAutoApt->Invoke(dispidICOMPerformance_Test1, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfloc[1].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr1;
- hr = pAutoApt->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfloc[1].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr2;
- hr = pAutoApt->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfloc[1].sec[2] = tmElapsed.OutputTime();
- // Remote
- if(vfRemote)
- {
- // Test1
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_I4;
- V_I4(&rgvt[0]) = i;
- hr = pAutoAptRmt->Invoke(dispidICOMPerformance_Test1, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfrmt[1].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr1;
- hr = pAutoAptRmt->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfrmt[1].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr2;
- hr = pAutoAptRmt->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfrmt[1].sec[2] = tmElapsed.OutputTime();
- }
-
- SysFreeString(bstr1);
- SysFreeString(bstr2);
- return TRUE;
- }
-
- BOOL
- FreeFreeCOMTest(int cLoops)
- {
- LONG i, k;
- CTIMER tmElapsed;
- BSTR bstr1, bstr2;
- bstr1 = SysAllocString(pszDesc1);
- bstr2 = SysAllocStringByteLen((const char *)pszDesc1, 4096);
-
- // Test1
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMFree->Test1(i);
- tmElapsed.Stop();
- vrgperfloc[2].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMFree->Test23(bstr1);
- tmElapsed.Stop();
- vrgperfloc[2].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- {
- k = (LONG)pCOMFree->Test23(bstr2);
- }
- tmElapsed.Stop();
- vrgperfloc[2].sec[2] = tmElapsed.OutputTime();
-
- // Remote
- if(vfRemote)
- {
- // Test1
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMFreeRmt->Test1(i);
- tmElapsed.Stop();
- vrgperfrmt[2].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- k = (LONG)pCOMFreeRmt->Test23(bstr1);
- tmElapsed.Stop();
- vrgperfrmt[2].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- for (i=0; i<cLoops; i++)
- {
- k = (LONG)pCOMFreeRmt->Test23(bstr2);
- }
- tmElapsed.Stop();
- vrgperfrmt[2].sec[2] = tmElapsed.OutputTime();
- }
-
- SysFreeString(bstr1);
- SysFreeString(bstr2);
- return TRUE;
- }
-
- BOOL
- FreeFreeAutoTest(int cLoops)
- {
- HRESULT hr;
- static VARIANTARG rgvt[1];
- static DISPPARAMS dispparams = { rgvt, NULL, 1, 0 };
- static EXCEPINFO excepinfo;
- VARIANT vtResult;
- UINT argerr;
- LONG i, k;
- CTIMER tmElapsed;
- BSTR bstr1, bstr2;
- bstr1 = SysAllocString(pszDesc1);
- bstr2 = SysAllocStringByteLen((const char *)pszDesc1, 4096);
-
- // Local
- // Test1
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_I4;
- V_I4(&rgvt[0]) = i;
- hr = pAutoFree->Invoke(dispidICOMPerformance_Test1, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfloc[3].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr1;
- hr = pAutoFree->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfloc[3].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr2;
- hr = pAutoFree->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfloc[3].sec[2] = tmElapsed.OutputTime();
-
- // Remote
- if(vfRemote)
- {
- // Test1
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_I4;
- V_I4(&rgvt[0]) = i;
- hr = pAutoFreeRmt->Invoke(dispidICOMPerformance_Test1, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfrmt[3].sec[0] = tmElapsed.OutputTime();
- // Test2
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr1;
- hr = pAutoFreeRmt->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfrmt[3].sec[1] = tmElapsed.OutputTime();
- // Test3
- tmElapsed.Start();
- V_VT(&vtResult) = VT_HRESULT;
- for (i=0; i<cLoops; i++)
- {
- V_VT(&rgvt[0]) = VT_BSTR;
- V_BSTR(&rgvt[0]) = bstr2;
- hr = pAutoFreeRmt->Invoke(dispidICOMPerformance_Test23, IID_NULL, 0, DISPATCH_METHOD, &dispparams,
- &vtResult, &excepinfo, &argerr);
- k = V_I4(&vtResult);
- }
- tmElapsed.Stop();
- vrgperfrmt[3].sec[2] = tmElapsed.OutputTime();
- }
- SysFreeString(bstr1);
- SysFreeString(bstr2);
- return TRUE;
- }
-
- void
- FPrintResults()
- {
- _tprintf(TEXT("Data Size\t\t4\t50\t4k\t4\t50\t4k\n"));
- _tprintf(TEXT("%s\t\t"), vrgperfloc[0].szTest);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[0].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[0].sec[1]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[0].sec[2]);
- if(vfRemote)
- {
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[0].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[0].sec[1]);
- _tprintf(TEXT("%4.2f\n"), LOOPS/vrgperfrmt[0].sec[2]);
- }
- else
- {
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\n"));
- }
- _tprintf(TEXT("%s\t\t"), vrgperfloc[1].szTest);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[1].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[1].sec[1]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[1].sec[2]);
- if(vfRemote)
- {
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[1].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[1].sec[1]);
- _tprintf(TEXT("%4.2f\n"), LOOPS/vrgperfrmt[1].sec[2]);
- }
- else
- {
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\n"));
- }
- _tprintf(TEXT("%s\t\t"), vrgperfloc[2].szTest);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[2].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[2].sec[1]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[2].sec[2]);
- if(vfRemote)
- {
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[2].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[2].sec[1]);
- _tprintf(TEXT("%4.2f\n"), LOOPS/vrgperfrmt[2].sec[2]);
- }
- else
- {
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\n"));
- }
- _tprintf(TEXT("%s\t\t"), vrgperfloc[3].szTest);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[3].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[3].sec[1]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[3].sec[2]);
- if(vfRemote)
- {
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[3].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[3].sec[1]);
- _tprintf(TEXT("%4.2f\n"), LOOPS/vrgperfrmt[3].sec[2]);
- }
- else
- {
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\n"));
- }
- _tprintf(TEXT("%s\t\t"), vrgperfloc[4].szTest);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[4].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[4].sec[1]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[4].sec[2]);
- if(vfRemote)
- {
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[4].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[4].sec[1]);
- _tprintf(TEXT("%4.2f\n"), LOOPS/vrgperfrmt[4].sec[2]);
- }
- else
- {
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\n"));
- }
- _tprintf(TEXT("%s\t\t"), vrgperfloc[5].szTest);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[5].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[5].sec[1]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfloc[5].sec[2]);
- if(vfRemote)
- {
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[5].sec[0]);
- _tprintf(TEXT("%4.2f\t"), LOOPS/vrgperfrmt[5].sec[1]);
- _tprintf(TEXT("%4.2f\n"), LOOPS/vrgperfrmt[5].sec[2]);
- }
- else
- {
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\t"));
- _tprintf(TEXT("--\n"));
- }
-
-
- }
-
- BOOL
- DoTests(void)
- {
- if(!AptFreeCOMTest(LOOPS))
- return FALSE;
- if(!AptFreeAutoTest(LOOPS))
- return FALSE;
- if(!FreeFreeCOMTest(LOOPS))
- return FALSE;
- if(!FreeFreeAutoTest(LOOPS))
- return FALSE;
- FPrintResults();
- return TRUE;
- } // DoTests
-
- void Usage()
- {
- _tprintf(TEXT("Usage: COMPERF [machine name | IP address | /? | -?]\n\n"));
- _tprintf(TEXT("/?\t\t\tDisplays this help screen.\n"));
- _tprintf(TEXT("machine name\t\tName of remote machine.\n"));
- _tprintf(TEXT("IP address\t\tIP address of remote machine.\n\n"));
- _tprintf("%s", PURPOSE);
- }
-
- // EOF =======================================================================
-