542 lines
18 KiB
C++
542 lines
18 KiB
C++
/******************************************************************
|
|
*
|
|
* The Plug In Server.
|
|
*
|
|
* HISTORY:
|
|
* Created : 02/11/97
|
|
* a-kirkh 4/2/97 Added call to SetInstance, RegisterPOVClass
|
|
*
|
|
*
|
|
* SUMMARY:
|
|
*
|
|
******************************************************************
|
|
(c) Microsoft 1997 - All right reserved.
|
|
******************************************************************/
|
|
#define INC_OLE2
|
|
|
|
#pragma pack (8)
|
|
|
|
#include "stdafx.h"
|
|
#include <objbase.h>
|
|
#include <initguid.h>
|
|
#include <shlobj.h>
|
|
#include "slang.h"
|
|
|
|
#ifndef PPVOID
|
|
typedef LPVOID* PPVOID;
|
|
#endif
|
|
|
|
#include <joycpl.h>
|
|
|
|
#include "resource.h"
|
|
#include "dicpl.h"
|
|
#include "hsvrguid.h"
|
|
#include "pov.h"
|
|
#include <malloc.h>
|
|
#include <afxconv.h>
|
|
|
|
#define STR_LEN_128 128
|
|
#define NUMPROPAGES 2
|
|
|
|
|
|
DIGCPAGEINFO page_info[NUMPROPAGES];
|
|
DIGCSHEETINFO sheet_info;
|
|
|
|
/// These strings are also defined in RESRC1.H
|
|
#define IDS_SHEET_CAPTION 9000
|
|
#define IDS_PAGE_TITLE1 9001
|
|
#define IDS_PAGE_TITLE2 9002
|
|
|
|
|
|
LRESULT SetJoyInfo(UINT nID, LPCSTR szOEMKey);
|
|
|
|
BOOL SetDialogItemText( HWND hdlg, UINT nctrl, UINT nstr );
|
|
CString *pszCommonString=NULL;
|
|
|
|
// %%% debug %%%
|
|
LPJOYDATA pjd;
|
|
JOYDATAPTR jdp;
|
|
|
|
extern LPGLOBALVARS gpgv;
|
|
extern BOOL fIsSideWinder;
|
|
static HINSTANCE ghInstance;
|
|
|
|
static LONG gcRefServerDll = 0; // Reference count for this DLL
|
|
|
|
//const LPSTR device_name="Gaming Input Device (Generic)";
|
|
|
|
USHORT gnID; // ID as sent from Client via SetID
|
|
|
|
static HINSTANCE ghModLang;
|
|
|
|
/*------------------------------------------------------------
|
|
** DllMain
|
|
*
|
|
* PARAMETERS :
|
|
*
|
|
* DESCRIPTION : Entry point into the Inprocess handler.
|
|
* This implementation is a single thread,
|
|
in process server.
|
|
|
|
* RETURNS :
|
|
* AUTHOR : Guru Datta Venkatarama
|
|
* 02/12/97 12:21:17 (PST)
|
|
*
|
|
------------------------------------------------------------*/
|
|
int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
|
|
{
|
|
switch( dwReason ) {
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
{
|
|
ghModLang = hInstance;
|
|
// save the DLL instance
|
|
ghInstance = hInstance;
|
|
|
|
SetResourceInstance(ghModLang);
|
|
|
|
AfxSetResourceHandle(ghModLang);
|
|
pszCommonString = new CString;
|
|
|
|
USES_CONVERSION;
|
|
|
|
char lpStr[STR_LEN_64];
|
|
|
|
// Populate page info stuff!
|
|
BYTE nIndex = NUMPROPAGES;
|
|
do {
|
|
nIndex--;
|
|
page_info[nIndex].dwSize = sizeof(DIGCPAGEINFO);
|
|
|
|
page_info[nIndex].lpwszPageTitle = new WCHAR[STR_LEN_128];
|
|
ASSERT(page_info[nIndex].lpwszPageTitle);
|
|
|
|
VERIFY(LoadString(ghModLang, IDS_PAGE_TITLE2-(nIndex^1), lpStr, STR_LEN_64));
|
|
wcscpy(page_info[nIndex].lpwszPageTitle, A2W(lpStr));
|
|
|
|
page_info[nIndex].fpPageProc = (nIndex) ? (DLGPROC)TestProc : (DLGPROC)JoystickDlg;
|
|
page_info[nIndex].fProcFlag = FALSE;
|
|
page_info[nIndex].fpPrePostProc = NULL;
|
|
|
|
// if fIconFlag is TRUE, DON'T FORGET TO MALLOC YOUR MEMORY!!!
|
|
page_info[nIndex].fIconFlag = FALSE;
|
|
page_info[nIndex].lpwszPageIcon = NULL;
|
|
|
|
page_info[nIndex].lpwszTemplate = (nIndex) ? (PWSTR)IDD_TEST : (PWSTR)IDD_SETTINGS ;
|
|
page_info[nIndex].lParam = 0;
|
|
page_info[nIndex].hInstance = ghModLang;
|
|
}
|
|
while( nIndex );
|
|
|
|
|
|
// Populate Sheet Info stuff!
|
|
sheet_info.dwSize = sizeof(DIGCSHEETINFO);
|
|
sheet_info.nNumPages = NUMPROPAGES;
|
|
|
|
VERIFY(LoadString(ghModLang, IDS_SHEET_CAPTION, lpStr, STR_LEN_64));
|
|
sheet_info.lpwszSheetCaption = new WCHAR[STR_LEN_64];
|
|
ASSERT(sheet_info.lpwszSheetCaption);
|
|
wcscpy(sheet_info.lpwszSheetCaption, A2W(lpStr));
|
|
|
|
// Don't forget to malloc your memory here if you ever need to have an Icon!
|
|
sheet_info.fSheetIconFlag = FALSE;
|
|
sheet_info.lpwszSheetIcon = NULL;
|
|
|
|
|
|
RegisterPOVClass(ghModLang); //Added by JKH 3/31/97
|
|
}
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
// clean-up Page info
|
|
for( BYTE nIndex = 0; nIndex < NUMPROPAGES; nIndex++ ) {
|
|
if( page_info[nIndex].lpwszPageTitle ) {
|
|
delete[] (page_info[nIndex].lpwszPageTitle);
|
|
}
|
|
|
|
// if fIconFlag is TRUE, DON'T FORGET TO FREE YOUR MEMORY!!!
|
|
}
|
|
|
|
// clean-up Sheet info
|
|
if( sheet_info.lpwszSheetCaption )
|
|
delete[] (sheet_info.lpwszSheetCaption);
|
|
|
|
// dll about to be released from process
|
|
// time to clean up all local work ( if any )
|
|
if( pszCommonString )
|
|
delete(pszCommonString);
|
|
break;
|
|
}
|
|
return(TRUE);
|
|
}
|
|
/*------------------------------------------------------------ DllGetClassObject
|
|
|
|
** DllGetClassObject
|
|
*
|
|
* PARAMETERS : rclsid = Reference to class ID specifier
|
|
riid = Reference to interface ID specifier
|
|
ppv = Pointer to location to receive interface pointer
|
|
*
|
|
* DESCRIPTION : Here be the entry point of COM.
|
|
DllGetClassObject is called by the Client socket to
|
|
create a class factory object.
|
|
This Class factory will support the generation of three different class
|
|
Objects.
|
|
*
|
|
* RETURNS : HRESULT code signifying success or failure
|
|
*
|
|
* AUTHOR : Guru Datta Venkatarama
|
|
* 01/29/97 14:22:02 (PST)
|
|
*
|
|
------------------------------------------------------------*/
|
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv)
|
|
{
|
|
// %%% debug %%% figure out this optimisation later.
|
|
USHORT l_clsidtype=0;
|
|
|
|
*ppv = NULL;
|
|
|
|
// Make sure the class ID valid for the class factory. Otherwise, the class
|
|
// factory of the object type specified by rclsid cannot be generated.
|
|
// %%% debug %%% - seems like we cannot implement this check because
|
|
// each server will have its own CLSID. so we need to hard code this for
|
|
// every server
|
|
if( !IsEqualCLSID (rclsid, CLSID_LegacyServer) ) {
|
|
return(ResultFromScode (CLASS_E_CLASSNOTAVAILABLE));
|
|
}
|
|
// Make sure that the interface id that is being requested is a valid one i.e. IID_IClassFactory
|
|
if( !IsEqualIID (riid, IID_IClassFactory) ) {
|
|
return(ResultFromScode (E_NOINTERFACE));
|
|
}
|
|
|
|
// create a new class factory ... ( here we associate the CLSID to object of a type )
|
|
CServerClassFactory *pClassFactory = new CServerClassFactory ();
|
|
|
|
// Verify .. was the class factory created ?
|
|
if( pClassFactory == NULL ) {
|
|
// Nope ! Return an ERROR !
|
|
return(ResultFromScode (E_OUTOFMEMORY));
|
|
}
|
|
|
|
// Get the interface pointer from QueryInterface and copy it to *ppv.
|
|
// The required type of riid is automatically being passed in ....
|
|
HRESULT hr = pClassFactory->QueryInterface (riid, ppv);
|
|
|
|
pClassFactory->Release ();
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
/*------------------------------------------------------------ DllCanUnloadNow
|
|
** DllCanUnloadNow
|
|
*
|
|
* PARAMETERS : None
|
|
*
|
|
* DESCRIPTION : DllCanUnloadNow is called by the shell to find out if the DLL can be
|
|
* unloaded. The answer is yes if (and only if) the module reference count
|
|
* stored in gcRefServerDll is 0.
|
|
This Dll can be unloaded if and only if :
|
|
a) All the in process servers that it "spawns" can be unloaded and
|
|
b) Its own reference count is down to zero
|
|
* RETURNS : HRESULT code equal to S_OK if the DLL can be unloaded, S_FALSE if not
|
|
* AUTHOR : Guru Datta Venkatarama
|
|
* 01/30/97 08:24:21 (PST)
|
|
*
|
|
------------------------------------------------------------*/
|
|
STDAPI DllCanUnloadNow(void)
|
|
{
|
|
// %%% debug %%% implement / verify complex condition for return value ( lock servers actually )
|
|
return((gcRefServerDll == 0) ? S_OK : S_FALSE);
|
|
}
|
|
|
|
/*------------------------------------------------------------ CServerClassFactory::CServerClassFactory
|
|
** CServerClassFactory Member Functions
|
|
*
|
|
* DESCRIPTION : This is the implementation of the standard member functions of the
|
|
Server's class factory.
|
|
*
|
|
* AUTHOR : Guru Datta Venkatarama
|
|
* 01/30/97 08:30:18 (PST)
|
|
*
|
|
------------------------------------------------------------*/
|
|
// constructor ..
|
|
CServerClassFactory::CServerClassFactory(void)
|
|
{
|
|
m_ServerCFactory_refcount = 0; // was 1;
|
|
AddRef();
|
|
|
|
// increment the dll refcount
|
|
InterlockedIncrement(&gcRefServerDll);
|
|
}
|
|
// ----------------------------------------------------------- CServerClassFactory::~CServerClassFactory
|
|
// destructor ..
|
|
CServerClassFactory::~CServerClassFactory(void)
|
|
{
|
|
// decrement the dll refcount
|
|
InterlockedDecrement(&gcRefServerDll);
|
|
}
|
|
// ----------------------------------------------------------- CServerClassFactory::QueryInterface
|
|
STDMETHODIMP CServerClassFactory::QueryInterface(
|
|
REFIID riid,
|
|
PPVOID ppv)
|
|
{
|
|
// Reflexive Response - return our own base Interface class pointer cast appropriately
|
|
if( IsEqualIID(riid, IID_IUnknown) ) {
|
|
*ppv = (LPUNKNOWN) (LPCLASSFACTORY) this;
|
|
} else {
|
|
// Reflexive Response - return our own class pointer
|
|
if( IsEqualIID(riid, IID_IClassFactory) ) {
|
|
*ppv = (LPCLASSFACTORY) this;
|
|
} else {
|
|
// unsupported interface requested for
|
|
*ppv = NULL;
|
|
return(ResultFromScode (E_NOINTERFACE));
|
|
}
|
|
}
|
|
|
|
// add reference count every time a pointer is provided
|
|
AddRef();
|
|
|
|
return(NOERROR);
|
|
}
|
|
// ----------------------------------------------------------- CServerClassFactory::AddRef
|
|
STDMETHODIMP_(ULONG)CServerClassFactory::AddRef(void)
|
|
{
|
|
InterlockedIncrement((LPLONG)&m_ServerCFactory_refcount);
|
|
return(m_ServerCFactory_refcount);
|
|
}
|
|
// ----------------------------------------------------------- CServerClassFactory::Release
|
|
STDMETHODIMP_(ULONG)CServerClassFactory::Release(void)
|
|
{
|
|
InterlockedDecrement((LPLONG)&m_ServerCFactory_refcount);
|
|
|
|
if( m_ServerCFactory_refcount == 0 ) {
|
|
delete this;
|
|
return(0);
|
|
} else {
|
|
return(m_ServerCFactory_refcount);
|
|
}
|
|
}
|
|
// -----------------------------------------------------------
|
|
/*------------------------------------------------------------ CServerClassFactory::CreateInstance
|
|
** CServerClassFactory::CreateInstance
|
|
*
|
|
* PARAMETERS : pUnkOuter = Pointer to controlling unknown
|
|
* riid = Reference to interface ID specifier
|
|
* ppvObj = Pointer to location to receive interface pointer
|
|
* DESCRIPTION : CreateInstance is the class factory implementation.
|
|
* It is called by the client to create the IServerCharacterstics interface
|
|
* It is called by the members of the IServerCharacteristics interface
|
|
* viz CreatePropertySheet and CreateDiagnostics to create the
|
|
* appropriate interfaces for each.
|
|
*
|
|
* RETURNS : HRESULT code signifying success or failure
|
|
*
|
|
* AUTHOR : Guru Datta Venkatarama
|
|
* 01/31/97 09:29:36 (PST)
|
|
*
|
|
------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CServerClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, PPVOID ppvObj)
|
|
{
|
|
*ppvObj = NULL;
|
|
HRESULT hr=S_OK;
|
|
|
|
// We don't support aggregation at this time!
|
|
if( pUnkOuter != NULL )
|
|
return(ResultFromScode(CLASS_E_NOAGGREGATION));
|
|
|
|
// Instantiate a class factory object of the appropriate type and retrieve its pointer.
|
|
if( IsEqualIID(riid, IID_IDIGameCntrlPropSheet) ) {
|
|
LPCDIGAMECNTRLPROPSHEET pCServerProperty = new CDIGameCntrlPropSheet();
|
|
|
|
if( pCServerProperty == NULL ) {
|
|
return(ResultFromScode(E_OUTOFMEMORY));
|
|
} else {
|
|
// Get the interface pointer from QueryInterface and copy it to *ppvObj.
|
|
hr = pCServerProperty->QueryInterface(riid, ppvObj);
|
|
|
|
// add the reference and count to the parent in order to support "containment"
|
|
// pCServerProperty->AddRef();
|
|
|
|
// drop a refcount created by the constructor on the server property object
|
|
pCServerProperty->Release ();
|
|
}
|
|
} else return(ResultFromScode (E_NOINTERFACE));
|
|
|
|
return(hr);
|
|
}
|
|
/*------------------------------------------------------------ CServerClassFactory::LockServer
|
|
** CServerClassFactory::LockServer
|
|
*
|
|
* PARAMETERS :
|
|
*
|
|
* DESCRIPTION : LockServer increments or decrements the DLL's lock count.
|
|
*
|
|
* RETURNS :
|
|
*
|
|
* AUTHOR : Guru Datta Venkatarama
|
|
* 01/31/97 18:40:17 (PST)
|
|
* IMPLIMENTOR : Brycej 08/04/97
|
|
*
|
|
------------------------------------------------------------*/
|
|
STDMETHODIMP CServerClassFactory::LockServer(BOOL fLock)
|
|
{
|
|
HRESULT hRes = E_NOTIMPL;
|
|
|
|
// increment/decrement based on fLock
|
|
if( fLock ) {
|
|
// increment the dll refcount
|
|
InterlockedIncrement(&gcRefServerDll);
|
|
} else {
|
|
// decrement the dll refcount
|
|
InterlockedDecrement(&gcRefServerDll);
|
|
}
|
|
|
|
// all done
|
|
return(hRes);
|
|
}
|
|
// -----------------------------------------------------------
|
|
//****************************************************************************************************
|
|
//********************************* **********************************
|
|
//****************************************************************************************************
|
|
// ----------------------------------------------------------- CImpIServerProperty::CImpIServerProperty
|
|
// constructor ..
|
|
CDIGameCntrlPropSheet::CDIGameCntrlPropSheet(void)
|
|
{
|
|
m_cProperty_refcount = 0;
|
|
AddRef();
|
|
m_nID = -1;
|
|
|
|
// increment the dll refcount
|
|
InterlockedIncrement(&gcRefServerDll);
|
|
}
|
|
// ----------------------------------------------------------- CImpIServerProperty::~CImpIServerProperty
|
|
// destructor ..
|
|
CDIGameCntrlPropSheet::~CDIGameCntrlPropSheet(void)
|
|
{
|
|
// decrement the dll refcount
|
|
InterlockedDecrement(&gcRefServerDll);
|
|
}
|
|
// ----------------------------------------------------------- CImpIServerProperty::QueryInterface
|
|
STDMETHODIMP CDIGameCntrlPropSheet::QueryInterface(
|
|
REFIID riid,
|
|
PPVOID ppv)
|
|
{
|
|
// Reflexive Response - return our own base Interface class pointer cast appropriately
|
|
if( IsEqualIID(riid, IID_IUnknown) ) {
|
|
*ppv = (LPUNKNOWN) (LPCLASSFACTORY) this;
|
|
} else {
|
|
// Reflexive Response - return our own class pointer
|
|
if( IsEqualIID(riid, IID_IDIGameCntrlPropSheet) ) {
|
|
*ppv = (LPCLASSFACTORY) this;
|
|
} else {
|
|
// unsupported interface requested for
|
|
*ppv = NULL;
|
|
return(ResultFromScode (E_NOINTERFACE));
|
|
}
|
|
}
|
|
|
|
// add reference count every time a pointer is provided
|
|
AddRef();
|
|
return(NOERROR);
|
|
}
|
|
// ----------------------------------------------------------- CImpIServerProperty::AddRef
|
|
STDMETHODIMP_(ULONG)CDIGameCntrlPropSheet::AddRef(void)
|
|
{
|
|
// update and return our object's reference count
|
|
InterlockedIncrement((LPLONG)&m_cProperty_refcount);
|
|
|
|
return(m_cProperty_refcount);
|
|
}
|
|
// ----------------------------------------------------------- CImpIServerProperty::Release
|
|
STDMETHODIMP_(ULONG)CDIGameCntrlPropSheet::Release(void)
|
|
{
|
|
// update and return our object's reference count
|
|
InterlockedDecrement((LPLONG)&m_cProperty_refcount);
|
|
|
|
if( m_cProperty_refcount == 0 ) {
|
|
delete this;
|
|
return(0);
|
|
} else {
|
|
return(m_cProperty_refcount);
|
|
}
|
|
}
|
|
// ----------------------------------------------------------- CImpIServerProperty::ReportSheetStats
|
|
STDMETHODIMP CDIGameCntrlPropSheet::GetSheetInfo(LPDIGCSHEETINFO *svrshtptr)
|
|
{
|
|
// pass the pointer back to the caller
|
|
*svrshtptr =(LPDIGCSHEETINFO) &sheet_info;
|
|
|
|
// return
|
|
return(S_OK);
|
|
}
|
|
// ----------------------------------------------------------- CImpIServerProperty::ReportPageStats
|
|
STDMETHODIMP CDIGameCntrlPropSheet::GetPageInfo(LPDIGCPAGEINFO * svrpagptr)
|
|
{
|
|
pjd = JoystickDataInit();
|
|
|
|
if( pjd == NULL ) {
|
|
*svrpagptr = NULL;
|
|
return(E_FAIL);
|
|
}
|
|
|
|
jdp.pjd = pjd;
|
|
page_info[0].lParam = (LPARAM) &jdp;
|
|
|
|
// pass pages information report structure pointer back to the caller
|
|
*svrpagptr = (LPDIGCPAGEINFO)page_info;
|
|
|
|
// return
|
|
return(S_OK);
|
|
}
|
|
|
|
STDMETHODIMP CDIGameCntrlPropSheet::SetID(USHORT nID)
|
|
{
|
|
gnID = m_nID = nID;
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
/*
|
|
// ----------------------------------------------------------
|
|
BOOL SetDialogItemText( HWND hdlg, UINT nctrl, UINT nstr )
|
|
{
|
|
CString * pszDialogString= new CString;
|
|
|
|
ASSERT(pszDialogString);
|
|
|
|
if(pszDialogString)
|
|
{
|
|
pszDialogString->LoadString(nstr);
|
|
SetDlgItemText( hdlg, nctrl, (LPCTSTR)*pszDialogString);
|
|
|
|
if (pszDialogString)
|
|
delete(pszDialogString);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
if (pszDialogString)
|
|
delete (pszDialogString);
|
|
|
|
return(FALSE);
|
|
}
|
|
*/
|
|
|
|
// ----------------------------------------------------------
|
|
LRESULT SetJoyInfo(UINT nID, LPCSTR szOEMKey)
|
|
{
|
|
if( !strcmp(szOEMKey, "Microsoft SideWinder 3D Pro") )
|
|
fIsSideWinder = 1;
|
|
jdp.iJoyId = gnID;
|
|
gpgv = &pjd->pgvlist[gnID];
|
|
return(NOERROR);
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------EOF
|