Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

476 lines
12 KiB

//+-------------------------------------------------------------------
//
// File: perfsrv.cxx
//
// Contents: This file contins the DLL entry points
// LibMain
// DllGetClassObject (Bindings key func)
// CPerfCF (class factory)
// CPerf (actual class implementation)
//
// Classes: CPerfCF, CPerf
//
//
// History: 30-Nov-92 SarahJ Created
//
//---------------------------------------------------------------------
// Turn off ole Cairol IUnknown
#define __IUNKNOWN_TMP__
#include <windows.h>
#include <ole2.h>
#include "perfsrv.hxx"
extern "C" {
#include <stdio.h>
#include <stdarg.h>
#include "wterm.h"
}
// These are Cairo symbols. Just define them here so I don't have to rip
// out or conditionally compile all references to them.
#define COINIT_MULTITHREADED 0
#define COINIT_SINGLETHREADED 1
#define IDM_DEBUG 0x100
// Count of objects we have instantiated. When we detect 0, we quit.
ULONG g_cUsage = 0;
const TCHAR *szAppName = L"Performance Server";
HWND g_hMain;
DWORD thread_mode = COINIT_SINGLETHREADED;
DWORD MainThread;
DWORD junk;
void Display(TCHAR *pszFmt, ...)
{
va_list marker;
TCHAR szBuffer[256];
va_start(marker, pszFmt);
int iLen = vswprintf(szBuffer, pszFmt, marker);
va_end(marker);
// Display the message on terminal window
SendMessage(g_hMain, WM_PRINT_LINE, iLen, (LONG) szBuffer);
}
//+-------------------------------------------------------------------------
//
// Function: ProcessMenu
//
// Synopsis: Gets called when a WM_COMMAND message received.
//
// Arguments: [hWindow] - handle for the window
// [uiMessage] - message id
// [wParam] - word parameter
// [lParam] - long parameter
//
// Returns: DefWindowProc result
//
// History: 06-Aug-92 Ricksa Created
//
//--------------------------------------------------------------------------
long ProcessMenu(HWND hWindow, UINT uiMessage, WPARAM wParam, LPARAM lParam,
void *)
{
if ((uiMessage == WM_SYSCOMMAND) && (wParam == IDM_DEBUG))
{
// Request for a debug breakpoint!
DebugBreak();
}
return (DefWindowProc(hWindow, uiMessage, wParam, lParam));
}
//+-------------------------------------------------------------------------
//
// Function: ProcessChar
//
// Synopsis: Gets called when a WM_CHAR message received.
//
// Arguments: [hWindow] - handle for the window
// [uiMessage] - message id
// [wParam] - word parameter
// [lParam] - long parameter
//
// Returns: DefWindowProc result
//
// History: 06-Aug-92 Ricksa Created
//
//--------------------------------------------------------------------------
long ProcessChar(HWND hWindow, UINT uiMessage, WPARAM wParam, LPARAM lParam,
void *)
{
return (DefWindowProc(hWindow, uiMessage, wParam, lParam));
}
//+-------------------------------------------------------------------------
//
// Function: ProcessClose
//
// Synopsis: Gets called when a NC_DESTROY message received.
//
// Arguments: [hWindow] - handle for the window
// [uiMessage] - message id
// [wParam] - word parameter
// [lParam] - long parameter
//
// Returns: DefWindowProc result
//
// History: 06-Aug-92 Ricksa Created
//
//--------------------------------------------------------------------------
long ProcessClose(
HWND hWindow,
UINT uiMessage,
WPARAM wParam,
LPARAM lParam,
void *pvCallBackData)
{
// Take default action with message
return (DefWindowProc(hWindow, uiMessage, wParam, lParam));
}
//+-------------------------------------------------------------------
//
// Function: WinMain
//
// Synopsis: Entry point to DLL - does little else
//
// Arguments:
//
// Returns: TRUE
//
// History: 21-Nov-92 SarahJ Created
//
//--------------------------------------------------------------------
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
char *lpCmdLine,
int nCmdShow)
{
// For windows message
MSG msg;
DWORD dwRegistration;
int len;
TCHAR buffer[80];
MainThread = GetCurrentThreadId();
// Look up the thread mode from the win.ini file.
#if 0
len = GetProfileString( L"My Section", L"ThreadMode", L"MultiThreaded", buffer,
sizeof(buffer) );
if (lstrcmp(buffer, L"SingleThreaded") == 0)
thread_mode = COINIT_SINGLETHREADED;
else if (lstrcmp(buffer, L"MultiThreaded") == 0)
thread_mode = COINIT_MULTITHREADED;
#endif
// Initialize the OLE libraries
OleInitialize(NULL);
// Create our class factory
CPerfCF *perf_cf = new CPerfCF();
// Register our class with OLE
CoRegisterClassObject(CLSID_IPerf, perf_cf, CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE, &dwRegistration);
// CoRegister bumps reference count so we don't have to!
perf_cf->Release();
// Register the window class
TermRegisterClass(hInstance, (LPTSTR) szAppName,
(LPTSTR) szAppName, (LPTSTR) (1));
// Create the server window
TermCreateWindow(
(LPTSTR) szAppName,
(LPTSTR) szAppName,
NULL,
ProcessMenu,
ProcessChar,
ProcessClose,
SW_SHOWNORMAL,
&g_hMain,
NULL);
// Add debug option to system menu
HMENU hmenu = GetSystemMenu(g_hMain, FALSE);
AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
AppendMenu(hmenu, MF_STRING | MF_ENABLED, IDM_DEBUG, L"Debug");
// Print the process id.
Display( L"Hi, I am %x.\n", GetCurrentProcessId() );
// Echo the mode.
if (thread_mode == COINIT_SINGLETHREADED)
Display(L"Server running in single threaded mode.\n");
else
Display(L"Server running in multithreaded mode.\n");
// Message processing loop
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
// Deregister out class - should release object as well
CoRevokeClassObject(dwRegistration);
// Tell OLE we are going away.
OleUninitialize();
return (msg.wParam); /* Returns the value from PostQuitMessage */
}
/***************************************************************************/
void CheckThread( TCHAR *name )
{
if (thread_mode == COINIT_SINGLETHREADED)
{
if (GetCurrentThreadId() != MainThread)
goto complain;
}
else
{
if (GetCurrentThreadId() == MainThread)
goto complain;
}
return;
complain:
Display( L"*********************************************************\n" );
Display( L"* *\n" );
Display( L"* Error *\n" );
Display( L"* *\n" );
Display( L"* Method called on wrong thread. *\n" );
Display( name );
Display( L"* *\n" );
Display( L"*********************************************************\n" );
}
/***************************************************************************/
STDMETHODIMP_(ULONG) CPerf::AddRef( THIS )
{
CheckThread(L"STDMETHODIMP_(ULONG) CPerf::AddRef( THIS )");
InterlockedIncrement( (long *) &ref_count );
return ref_count;
}
/***************************************************************************/
CPerf::CPerf()
{
ref_count = 1;
g_cUsage++;
}
/***************************************************************************/
CPerf::~CPerf()
{
if (--g_cUsage == 0)
{
SendMessage(g_hMain, WM_TERM_WND, 0, 0);
}
}
/***************************************************************************/
STDMETHODIMP CPerf::GetAnotherObject( IPerf **another )
{
CheckThread(L"STDMETHODIMP CPerf::GetAnotherObject( IPerf **another )");
*another = NULL;
CPerf *perf = new FAR CPerf();
if (perf == NULL)
{
return E_OUTOFMEMORY;
}
*another = perf;
return S_OK;
}
/***************************************************************************/
STDMETHODIMP CPerf::HResultCall()
{
CheckThread(L"STDMETHODIMP CPerf::HResultCall()");
return S_OK;
}
/***************************************************************************/
STDMETHODIMP CPerf::NullCall()
{
return S_OK;
}
/***************************************************************************/
STDMETHODIMP CPerf::PassMoniker( IMoniker *moniker )
{
HRESULT result;
IBindCtx *bindctx;
WCHAR *wide_name;
// Get a bind context.
result = CreateBindCtx( NULL, &bindctx );
if (FAILED(result))
{
Display( L"Could not create bind context: 0x%x\n", result );
return E_FAIL;
}
// Display name.
result = moniker->GetDisplayName( bindctx, NULL, &wide_name );
if (FAILED(result))
{
Display( L"Could not get display name: 0x%x\n", result );
return E_FAIL;
}
// Display the name.
Display( L"The moniker is called <%s>\n", wide_name );
// Free string.
CoTaskMemFree( wide_name );
// Release everything.
moniker->Release();
bindctx->Release();
return S_OK;
}
/***************************************************************************/
STDMETHODIMP CPerf::QueryInterface( THIS_ REFIID riid, LPVOID FAR* ppvObj)
{
CheckThread(L"STDMETHODIMP CPerf::QueryInterface( THIS_ REFIID riid, LPVOID FAR* ppvObj)" );
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_IPerf))
{
*ppvObj = (IUnknown *) this;
AddRef();
return S_OK;
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
}
/***************************************************************************/
STDMETHODIMP_(ULONG) CPerf::Release( THIS )
{
CheckThread(L"STDMETHODIMP_(ULONG) CPerf::Release( THIS )");
if (InterlockedDecrement( (long*) &ref_count ) == 0)
{
delete this;
return 0;
}
else
return ref_count;
}
/***************************************************************************/
STDMETHODIMP_(ULONG) CPerfCF::AddRef( THIS )
{
CheckThread(L"STDMETHODIMP_(ULONG) CPerfCF::AddRef( THIS )");
InterlockedIncrement( (long *) &ref_count );
return ref_count;
}
/***************************************************************************/
CPerfCF::CPerfCF()
{
ref_count = 1;
}
/***************************************************************************/
CPerfCF::~CPerfCF()
{
}
/***************************************************************************/
STDMETHODIMP CPerfCF::CreateInstance(
IUnknown FAR* pUnkOuter,
REFIID iidInterface,
void FAR* FAR* ppv)
{
CheckThread(L"STDMETHODIMP CPerfCF::CreateInstance(" );
Display(L"CPerfCF::CreateInstance called\n");
*ppv = NULL;
if (pUnkOuter != NULL)
{
return E_FAIL;
}
if (!IsEqualIID( iidInterface, IID_IPerf ))
return E_NOINTERFACE;
CPerf *perf = new FAR CPerf();
if (perf == NULL)
{
return E_OUTOFMEMORY;
}
*ppv = perf;
return S_OK;
}
/***************************************************************************/
STDMETHODIMP CPerfCF::LockServer(BOOL fLock)
{
CheckThread( L"STDMETHODIMP CPerfCF::LockServer(BOOL fLock)" );
return E_FAIL;
}
/***************************************************************************/
STDMETHODIMP CPerfCF::QueryInterface( THIS_ REFIID riid, LPVOID FAR* ppvObj)
{
CheckThread(L"STDMETHODIMP CPerfCF::QueryInterface( THIS_ REFIID riid, LPVOID FAR* ppvObj)");
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_IClassFactory))
{
*ppvObj = (IUnknown *) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
/***************************************************************************/
STDMETHODIMP_(ULONG) CPerfCF::Release( THIS )
{
CheckThread(L"STDMETHODIMP_(ULONG) CPerfCF::Release( THIS )");
if (InterlockedDecrement( (long*) &ref_count ) == 0)
{
delete this;
return 0;
}
else
return ref_count;
}