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.

541 lines
18 KiB

  1. /******************************************************************
  2. *
  3. * The Plug In Server.
  4. *
  5. * HISTORY:
  6. * Created : 02/11/97
  7. * a-kirkh 4/2/97 Added call to SetInstance, RegisterPOVClass
  8. *
  9. *
  10. * SUMMARY:
  11. *
  12. ******************************************************************
  13. (c) Microsoft 1997 - All right reserved.
  14. ******************************************************************/
  15. #define INC_OLE2
  16. #pragma pack (8)
  17. #include "stdafx.h"
  18. #include <objbase.h>
  19. #include <initguid.h>
  20. #include <shlobj.h>
  21. #include "slang.h"
  22. #ifndef PPVOID
  23. typedef LPVOID* PPVOID;
  24. #endif
  25. #include <joycpl.h>
  26. #include "resource.h"
  27. #include "dicpl.h"
  28. #include "hsvrguid.h"
  29. #include "pov.h"
  30. #include <malloc.h>
  31. #include <afxconv.h>
  32. #define STR_LEN_128 128
  33. #define NUMPROPAGES 2
  34. DIGCPAGEINFO page_info[NUMPROPAGES];
  35. DIGCSHEETINFO sheet_info;
  36. /// These strings are also defined in RESRC1.H
  37. #define IDS_SHEET_CAPTION 9000
  38. #define IDS_PAGE_TITLE1 9001
  39. #define IDS_PAGE_TITLE2 9002
  40. LRESULT SetJoyInfo(UINT nID, LPCSTR szOEMKey);
  41. BOOL SetDialogItemText( HWND hdlg, UINT nctrl, UINT nstr );
  42. CString *pszCommonString=NULL;
  43. // %%% debug %%%
  44. LPJOYDATA pjd;
  45. JOYDATAPTR jdp;
  46. extern LPGLOBALVARS gpgv;
  47. extern BOOL fIsSideWinder;
  48. static HINSTANCE ghInstance;
  49. static LONG gcRefServerDll = 0; // Reference count for this DLL
  50. //const LPSTR device_name="Gaming Input Device (Generic)";
  51. USHORT gnID; // ID as sent from Client via SetID
  52. static HINSTANCE ghModLang;
  53. /*------------------------------------------------------------
  54. ** DllMain
  55. *
  56. * PARAMETERS :
  57. *
  58. * DESCRIPTION : Entry point into the Inprocess handler.
  59. * This implementation is a single thread,
  60. in process server.
  61. * RETURNS :
  62. * AUTHOR : Guru Datta Venkatarama
  63. * 02/12/97 12:21:17 (PST)
  64. *
  65. ------------------------------------------------------------*/
  66. int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  67. {
  68. switch( dwReason ) {
  69. case DLL_PROCESS_ATTACH:
  70. {
  71. ghModLang = hInstance;
  72. // save the DLL instance
  73. ghInstance = hInstance;
  74. SetResourceInstance(ghModLang);
  75. AfxSetResourceHandle(ghModLang);
  76. pszCommonString = new CString;
  77. USES_CONVERSION;
  78. char lpStr[STR_LEN_64];
  79. // Populate page info stuff!
  80. BYTE nIndex = NUMPROPAGES;
  81. do {
  82. nIndex--;
  83. page_info[nIndex].dwSize = sizeof(DIGCPAGEINFO);
  84. page_info[nIndex].lpwszPageTitle = new WCHAR[STR_LEN_128];
  85. ASSERT(page_info[nIndex].lpwszPageTitle);
  86. VERIFY(LoadString(ghModLang, IDS_PAGE_TITLE2-(nIndex^1), lpStr, STR_LEN_64));
  87. wcscpy(page_info[nIndex].lpwszPageTitle, A2W(lpStr));
  88. page_info[nIndex].fpPageProc = (nIndex) ? (DLGPROC)TestProc : (DLGPROC)JoystickDlg;
  89. page_info[nIndex].fProcFlag = FALSE;
  90. page_info[nIndex].fpPrePostProc = NULL;
  91. // if fIconFlag is TRUE, DON'T FORGET TO MALLOC YOUR MEMORY!!!
  92. page_info[nIndex].fIconFlag = FALSE;
  93. page_info[nIndex].lpwszPageIcon = NULL;
  94. page_info[nIndex].lpwszTemplate = (nIndex) ? (PWSTR)IDD_TEST : (PWSTR)IDD_SETTINGS ;
  95. page_info[nIndex].lParam = 0;
  96. page_info[nIndex].hInstance = ghModLang;
  97. }
  98. while( nIndex );
  99. // Populate Sheet Info stuff!
  100. sheet_info.dwSize = sizeof(DIGCSHEETINFO);
  101. sheet_info.nNumPages = NUMPROPAGES;
  102. VERIFY(LoadString(ghModLang, IDS_SHEET_CAPTION, lpStr, STR_LEN_64));
  103. sheet_info.lpwszSheetCaption = new WCHAR[STR_LEN_64];
  104. ASSERT(sheet_info.lpwszSheetCaption);
  105. wcscpy(sheet_info.lpwszSheetCaption, A2W(lpStr));
  106. // Don't forget to malloc your memory here if you ever need to have an Icon!
  107. sheet_info.fSheetIconFlag = FALSE;
  108. sheet_info.lpwszSheetIcon = NULL;
  109. RegisterPOVClass(ghModLang); //Added by JKH 3/31/97
  110. }
  111. break;
  112. case DLL_PROCESS_DETACH:
  113. // clean-up Page info
  114. for( BYTE nIndex = 0; nIndex < NUMPROPAGES; nIndex++ ) {
  115. if( page_info[nIndex].lpwszPageTitle ) {
  116. delete[] (page_info[nIndex].lpwszPageTitle);
  117. }
  118. // if fIconFlag is TRUE, DON'T FORGET TO FREE YOUR MEMORY!!!
  119. }
  120. // clean-up Sheet info
  121. if( sheet_info.lpwszSheetCaption )
  122. delete[] (sheet_info.lpwszSheetCaption);
  123. // dll about to be released from process
  124. // time to clean up all local work ( if any )
  125. if( pszCommonString )
  126. delete(pszCommonString);
  127. break;
  128. }
  129. return(TRUE);
  130. }
  131. /*------------------------------------------------------------ DllGetClassObject
  132. ** DllGetClassObject
  133. *
  134. * PARAMETERS : rclsid = Reference to class ID specifier
  135. riid = Reference to interface ID specifier
  136. ppv = Pointer to location to receive interface pointer
  137. *
  138. * DESCRIPTION : Here be the entry point of COM.
  139. DllGetClassObject is called by the Client socket to
  140. create a class factory object.
  141. This Class factory will support the generation of three different class
  142. Objects.
  143. *
  144. * RETURNS : HRESULT code signifying success or failure
  145. *
  146. * AUTHOR : Guru Datta Venkatarama
  147. * 01/29/97 14:22:02 (PST)
  148. *
  149. ------------------------------------------------------------*/
  150. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv)
  151. {
  152. // %%% debug %%% figure out this optimisation later.
  153. USHORT l_clsidtype=0;
  154. *ppv = NULL;
  155. // Make sure the class ID valid for the class factory. Otherwise, the class
  156. // factory of the object type specified by rclsid cannot be generated.
  157. // %%% debug %%% - seems like we cannot implement this check because
  158. // each server will have its own CLSID. so we need to hard code this for
  159. // every server
  160. if( !IsEqualCLSID (rclsid, CLSID_LegacyServer) ) {
  161. return(ResultFromScode (CLASS_E_CLASSNOTAVAILABLE));
  162. }
  163. // Make sure that the interface id that is being requested is a valid one i.e. IID_IClassFactory
  164. if( !IsEqualIID (riid, IID_IClassFactory) ) {
  165. return(ResultFromScode (E_NOINTERFACE));
  166. }
  167. // create a new class factory ... ( here we associate the CLSID to object of a type )
  168. CServerClassFactory *pClassFactory = new CServerClassFactory ();
  169. // Verify .. was the class factory created ?
  170. if( pClassFactory == NULL ) {
  171. // Nope ! Return an ERROR !
  172. return(ResultFromScode (E_OUTOFMEMORY));
  173. }
  174. // Get the interface pointer from QueryInterface and copy it to *ppv.
  175. // The required type of riid is automatically being passed in ....
  176. HRESULT hr = pClassFactory->QueryInterface (riid, ppv);
  177. pClassFactory->Release ();
  178. return(hr);
  179. }
  180. /*------------------------------------------------------------ DllCanUnloadNow
  181. ** DllCanUnloadNow
  182. *
  183. * PARAMETERS : None
  184. *
  185. * DESCRIPTION : DllCanUnloadNow is called by the shell to find out if the DLL can be
  186. * unloaded. The answer is yes if (and only if) the module reference count
  187. * stored in gcRefServerDll is 0.
  188. This Dll can be unloaded if and only if :
  189. a) All the in process servers that it "spawns" can be unloaded and
  190. b) Its own reference count is down to zero
  191. * RETURNS : HRESULT code equal to S_OK if the DLL can be unloaded, S_FALSE if not
  192. * AUTHOR : Guru Datta Venkatarama
  193. * 01/30/97 08:24:21 (PST)
  194. *
  195. ------------------------------------------------------------*/
  196. STDAPI DllCanUnloadNow(void)
  197. {
  198. // %%% debug %%% implement / verify complex condition for return value ( lock servers actually )
  199. return((gcRefServerDll == 0) ? S_OK : S_FALSE);
  200. }
  201. /*------------------------------------------------------------ CServerClassFactory::CServerClassFactory
  202. ** CServerClassFactory Member Functions
  203. *
  204. * DESCRIPTION : This is the implementation of the standard member functions of the
  205. Server's class factory.
  206. *
  207. * AUTHOR : Guru Datta Venkatarama
  208. * 01/30/97 08:30:18 (PST)
  209. *
  210. ------------------------------------------------------------*/
  211. // constructor ..
  212. CServerClassFactory::CServerClassFactory(void)
  213. {
  214. m_ServerCFactory_refcount = 0; // was 1;
  215. AddRef();
  216. // increment the dll refcount
  217. InterlockedIncrement(&gcRefServerDll);
  218. }
  219. // ----------------------------------------------------------- CServerClassFactory::~CServerClassFactory
  220. // destructor ..
  221. CServerClassFactory::~CServerClassFactory(void)
  222. {
  223. // decrement the dll refcount
  224. InterlockedDecrement(&gcRefServerDll);
  225. }
  226. // ----------------------------------------------------------- CServerClassFactory::QueryInterface
  227. STDMETHODIMP CServerClassFactory::QueryInterface(
  228. REFIID riid,
  229. PPVOID ppv)
  230. {
  231. // Reflexive Response - return our own base Interface class pointer cast appropriately
  232. if( IsEqualIID(riid, IID_IUnknown) ) {
  233. *ppv = (LPUNKNOWN) (LPCLASSFACTORY) this;
  234. } else {
  235. // Reflexive Response - return our own class pointer
  236. if( IsEqualIID(riid, IID_IClassFactory) ) {
  237. *ppv = (LPCLASSFACTORY) this;
  238. } else {
  239. // unsupported interface requested for
  240. *ppv = NULL;
  241. return(ResultFromScode (E_NOINTERFACE));
  242. }
  243. }
  244. // add reference count every time a pointer is provided
  245. AddRef();
  246. return(NOERROR);
  247. }
  248. // ----------------------------------------------------------- CServerClassFactory::AddRef
  249. STDMETHODIMP_(ULONG)CServerClassFactory::AddRef(void)
  250. {
  251. InterlockedIncrement((LPLONG)&m_ServerCFactory_refcount);
  252. return(m_ServerCFactory_refcount);
  253. }
  254. // ----------------------------------------------------------- CServerClassFactory::Release
  255. STDMETHODIMP_(ULONG)CServerClassFactory::Release(void)
  256. {
  257. InterlockedDecrement((LPLONG)&m_ServerCFactory_refcount);
  258. if( m_ServerCFactory_refcount == 0 ) {
  259. delete this;
  260. return(0);
  261. } else {
  262. return(m_ServerCFactory_refcount);
  263. }
  264. }
  265. // -----------------------------------------------------------
  266. /*------------------------------------------------------------ CServerClassFactory::CreateInstance
  267. ** CServerClassFactory::CreateInstance
  268. *
  269. * PARAMETERS : pUnkOuter = Pointer to controlling unknown
  270. * riid = Reference to interface ID specifier
  271. * ppvObj = Pointer to location to receive interface pointer
  272. * DESCRIPTION : CreateInstance is the class factory implementation.
  273. * It is called by the client to create the IServerCharacterstics interface
  274. * It is called by the members of the IServerCharacteristics interface
  275. * viz CreatePropertySheet and CreateDiagnostics to create the
  276. * appropriate interfaces for each.
  277. *
  278. * RETURNS : HRESULT code signifying success or failure
  279. *
  280. * AUTHOR : Guru Datta Venkatarama
  281. * 01/31/97 09:29:36 (PST)
  282. *
  283. ------------------------------------------------------------*/
  284. STDMETHODIMP CServerClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, PPVOID ppvObj)
  285. {
  286. *ppvObj = NULL;
  287. HRESULT hr=S_OK;
  288. // We don't support aggregation at this time!
  289. if( pUnkOuter != NULL )
  290. return(ResultFromScode(CLASS_E_NOAGGREGATION));
  291. // Instantiate a class factory object of the appropriate type and retrieve its pointer.
  292. if( IsEqualIID(riid, IID_IDIGameCntrlPropSheet) ) {
  293. LPCDIGAMECNTRLPROPSHEET pCServerProperty = new CDIGameCntrlPropSheet();
  294. if( pCServerProperty == NULL ) {
  295. return(ResultFromScode(E_OUTOFMEMORY));
  296. } else {
  297. // Get the interface pointer from QueryInterface and copy it to *ppvObj.
  298. hr = pCServerProperty->QueryInterface(riid, ppvObj);
  299. // add the reference and count to the parent in order to support "containment"
  300. // pCServerProperty->AddRef();
  301. // drop a refcount created by the constructor on the server property object
  302. pCServerProperty->Release ();
  303. }
  304. } else return(ResultFromScode (E_NOINTERFACE));
  305. return(hr);
  306. }
  307. /*------------------------------------------------------------ CServerClassFactory::LockServer
  308. ** CServerClassFactory::LockServer
  309. *
  310. * PARAMETERS :
  311. *
  312. * DESCRIPTION : LockServer increments or decrements the DLL's lock count.
  313. *
  314. * RETURNS :
  315. *
  316. * AUTHOR : Guru Datta Venkatarama
  317. * 01/31/97 18:40:17 (PST)
  318. * IMPLIMENTOR : Brycej 08/04/97
  319. *
  320. ------------------------------------------------------------*/
  321. STDMETHODIMP CServerClassFactory::LockServer(BOOL fLock)
  322. {
  323. HRESULT hRes = E_NOTIMPL;
  324. // increment/decrement based on fLock
  325. if( fLock ) {
  326. // increment the dll refcount
  327. InterlockedIncrement(&gcRefServerDll);
  328. } else {
  329. // decrement the dll refcount
  330. InterlockedDecrement(&gcRefServerDll);
  331. }
  332. // all done
  333. return(hRes);
  334. }
  335. // -----------------------------------------------------------
  336. //****************************************************************************************************
  337. //********************************* **********************************
  338. //****************************************************************************************************
  339. // ----------------------------------------------------------- CImpIServerProperty::CImpIServerProperty
  340. // constructor ..
  341. CDIGameCntrlPropSheet::CDIGameCntrlPropSheet(void)
  342. {
  343. m_cProperty_refcount = 0;
  344. AddRef();
  345. m_nID = -1;
  346. // increment the dll refcount
  347. InterlockedIncrement(&gcRefServerDll);
  348. }
  349. // ----------------------------------------------------------- CImpIServerProperty::~CImpIServerProperty
  350. // destructor ..
  351. CDIGameCntrlPropSheet::~CDIGameCntrlPropSheet(void)
  352. {
  353. // decrement the dll refcount
  354. InterlockedDecrement(&gcRefServerDll);
  355. }
  356. // ----------------------------------------------------------- CImpIServerProperty::QueryInterface
  357. STDMETHODIMP CDIGameCntrlPropSheet::QueryInterface(
  358. REFIID riid,
  359. PPVOID ppv)
  360. {
  361. // Reflexive Response - return our own base Interface class pointer cast appropriately
  362. if( IsEqualIID(riid, IID_IUnknown) ) {
  363. *ppv = (LPUNKNOWN) (LPCLASSFACTORY) this;
  364. } else {
  365. // Reflexive Response - return our own class pointer
  366. if( IsEqualIID(riid, IID_IDIGameCntrlPropSheet) ) {
  367. *ppv = (LPCLASSFACTORY) this;
  368. } else {
  369. // unsupported interface requested for
  370. *ppv = NULL;
  371. return(ResultFromScode (E_NOINTERFACE));
  372. }
  373. }
  374. // add reference count every time a pointer is provided
  375. AddRef();
  376. return(NOERROR);
  377. }
  378. // ----------------------------------------------------------- CImpIServerProperty::AddRef
  379. STDMETHODIMP_(ULONG)CDIGameCntrlPropSheet::AddRef(void)
  380. {
  381. // update and return our object's reference count
  382. InterlockedIncrement((LPLONG)&m_cProperty_refcount);
  383. return(m_cProperty_refcount);
  384. }
  385. // ----------------------------------------------------------- CImpIServerProperty::Release
  386. STDMETHODIMP_(ULONG)CDIGameCntrlPropSheet::Release(void)
  387. {
  388. // update and return our object's reference count
  389. InterlockedDecrement((LPLONG)&m_cProperty_refcount);
  390. if( m_cProperty_refcount == 0 ) {
  391. delete this;
  392. return(0);
  393. } else {
  394. return(m_cProperty_refcount);
  395. }
  396. }
  397. // ----------------------------------------------------------- CImpIServerProperty::ReportSheetStats
  398. STDMETHODIMP CDIGameCntrlPropSheet::GetSheetInfo(LPDIGCSHEETINFO *svrshtptr)
  399. {
  400. // pass the pointer back to the caller
  401. *svrshtptr =(LPDIGCSHEETINFO) &sheet_info;
  402. // return
  403. return(S_OK);
  404. }
  405. // ----------------------------------------------------------- CImpIServerProperty::ReportPageStats
  406. STDMETHODIMP CDIGameCntrlPropSheet::GetPageInfo(LPDIGCPAGEINFO * svrpagptr)
  407. {
  408. pjd = JoystickDataInit();
  409. if( pjd == NULL ) {
  410. *svrpagptr = NULL;
  411. return(E_FAIL);
  412. }
  413. jdp.pjd = pjd;
  414. page_info[0].lParam = (LPARAM) &jdp;
  415. // pass pages information report structure pointer back to the caller
  416. *svrpagptr = (LPDIGCPAGEINFO)page_info;
  417. // return
  418. return(S_OK);
  419. }
  420. STDMETHODIMP CDIGameCntrlPropSheet::SetID(USHORT nID)
  421. {
  422. gnID = m_nID = nID;
  423. return(S_OK);
  424. }
  425. /*
  426. // ----------------------------------------------------------
  427. BOOL SetDialogItemText( HWND hdlg, UINT nctrl, UINT nstr )
  428. {
  429. CString * pszDialogString= new CString;
  430. ASSERT(pszDialogString);
  431. if(pszDialogString)
  432. {
  433. pszDialogString->LoadString(nstr);
  434. SetDlgItemText( hdlg, nctrl, (LPCTSTR)*pszDialogString);
  435. if (pszDialogString)
  436. delete(pszDialogString);
  437. return(TRUE);
  438. }
  439. if (pszDialogString)
  440. delete (pszDialogString);
  441. return(FALSE);
  442. }
  443. */
  444. // ----------------------------------------------------------
  445. LRESULT SetJoyInfo(UINT nID, LPCSTR szOEMKey)
  446. {
  447. if( !strcmp(szOEMKey, "Microsoft SideWinder 3D Pro") )
  448. fIsSideWinder = 1;
  449. jdp.iJoyId = gnID;
  450. gpgv = &pjd->pgvlist[gnID];
  451. return(NOERROR);
  452. }
  453. // -------------------------------------------------------------------------------EOF