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.

939 lines
28 KiB

  1. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2. **
  3. ** FILE: MAINHANDLER.CPP
  4. ** DATE: 01/29/97
  5. ** PROJ: ATLAS
  6. ** PROG: Guru Datta Venkatarama
  7. ** COMMENTS: Common interface to gaming devices in-proc servers
  8. **
  9. ** DESCRIPTION:This is the generic handler that supports a standard
  10. ** protocol to support plug in servers to implement its
  11. ** property sheet and diagnostics interface
  12. **
  13. ** NOTE:
  14. **
  15. ** HISTORY:
  16. ** DATE WHO WHAT
  17. ** ---- --- ----
  18. ** 1/29/97 Guru CREATED
  19. ** 3/25/97 a-kirkh ADDED COMMENTS
  20. **
  21. **
  22. **
  23. ** Copyright (C) Microsoft 1997. All Rights Reserved.
  24. **
  25. **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  26. // %%% debug %%% check out the includes
  27. #define INC_OLE2
  28. #pragma pack (8)
  29. #include "stdafx.h"
  30. #include <objbase.h>
  31. #include <initguid.h>
  32. #include <shlobj.h>
  33. #include <assert.h>
  34. #ifndef _UNICODE
  35. #include <malloc.h> // needed for _alloca
  36. #include <afxconv.h>
  37. #endif
  38. #include "mainhand.h"
  39. #include "plugsrvr.h"
  40. // BEGINNING OF UNICODE CONVERSION UTILITY DEFINITIONS
  41. #ifndef USES_CONVERSION
  42. #ifndef _DEBUG
  43. #define USES_CONVERSION int _convert; _convert
  44. #else
  45. #define USES_CONVERSION int _convert = 0;
  46. #endif
  47. #endif // USES_CONVERSION
  48. #ifndef A2W
  49. #define A2W(lpa) (((LPCSTR)lpa == NULL) ? NULL : (_convert = (lstrlenA(lpa)+1), AfxA2WHelper((LPWSTR) alloca(_convert*2), lpa, _convert)))
  50. #endif // A2W
  51. #ifndef W2A
  52. #define W2A(lpw) (((LPCWSTR)lpw == NULL) ? NULL : ( _convert = (wcslen(lpw)+1)*2, AfxW2AHelper((LPSTR) alloca(_convert), lpw, _convert)))
  53. #endif // W2A
  54. // END OF UNICODE CONVERSION UTILITY DEFINITIONS
  55. static USHORT g_cServerLocks;
  56. static USHORT g_cComponents;
  57. /*------------------------------------------------------------
  58. ** DllMain
  59. *
  60. * DESCRIPTION : Entry point into the Inprocess handler.
  61. * Here is where it all begins !! This implementation
  62. * is a single thread, in process handler.
  63. *
  64. * AUTHOR : Guru Datta Venkatarama 01/29/97 11:13:49 (PST)
  65. * a-kirkh - Implemented reference counting
  66. ------------------------------------------------------------*/
  67. int APIENTRY DllMain(
  68. HINSTANCE hInstance,
  69. DWORD dwReason,
  70. LPVOID lpReserved)
  71. {
  72. switch (dwReason)
  73. {
  74. case DLL_PROCESS_ATTACH:
  75. break;
  76. case DLL_PROCESS_DETACH:
  77. break;
  78. }
  79. return 1;
  80. }
  81. /*------------------------------------------------------------
  82. * DllGetClassObject
  83. *
  84. * PARAMETERS : rclsid = Reference to class ID specifier
  85. * riid = Reference to interface ID specifier
  86. * ppv = Pointer to location to receive interface pointer
  87. *
  88. * DESCRIPTION : Here be the entry point of COM.
  89. * DllGetClassObject is called by the Client socket to
  90. * create a class factory object.
  91. * This Class factory will support the generation of three different class
  92. * Objects.
  93. *
  94. * RETURNS : HRESULT code signifying success or failure
  95. *
  96. * AUTHOR : Guru Datta Venkatarama 01/29/97 14:22:02 (PST)
  97. *
  98. ------------------------------------------------------------*/
  99. STDAPI DllGetClassObject(
  100. REFCLSID rclsid,
  101. REFIID riid,
  102. PPVOID ppv)
  103. {
  104. *ppv = NULL;
  105. if (!IsEqualIID (riid, IID_IClassFactory))
  106. {
  107. TRACE(TEXT("Mainhand.cpp: DllGetClassObject: Failed to find IID_IClassFactory!\n"));
  108. return ResultFromScode (E_NOINTERFACE);
  109. }
  110. CHandlerClassFactory *pClassFactory = new CHandlerClassFactory();
  111. ASSERT (pClassFactory);
  112. if (pClassFactory == NULL)
  113. {
  114. return ResultFromScode (E_OUTOFMEMORY);
  115. }
  116. // Get the interface pointer from QueryInterface and copy it to *ppv.
  117. // The required type of riid is automatically being passed in ....
  118. HRESULT hr = pClassFactory->QueryInterface (riid, ppv);
  119. if(SUCCEEDED(hr))
  120. pClassFactory->m_CLSID_whoamI = rclsid;
  121. return hr;
  122. }
  123. /*------------------------------------------------------------
  124. ** DllCanUnloadNow
  125. *
  126. * PARAMETERS : None
  127. *
  128. * DESCRIPTION : DllCanUnloadNow is called by the shell to find out if the DLL can be
  129. * unloaded. The answer is yes if (and only if) the module reference count
  130. * stored in g_cServerLocks and g_cComponents is 0.
  131. * This Dll can be unloaded if and only if :
  132. * a) All the in components that it "spawns" have been deleted and
  133. * b) There are no locks on any of the class factory interfaces
  134. * RETURNS : HRESULT code equal to S_OK if the DLL can be unloaded, S_FALSE if not
  135. * AUTHOR : Guru Datta Venkatarama 01/30/97 08:24:21 (PST)
  136. * a-kirkh - Implemented.
  137. *
  138. ------------------------------------------------------------*/
  139. STDAPI DllCanUnloadNow(void)
  140. {
  141. return ((!g_cComponents) && (!g_cServerLocks)) ? S_OK : S_FALSE;
  142. }
  143. /*------------------------------------------------------------
  144. * CHandlerClassFactory Member Functions
  145. *
  146. * DESCRIPTION : This is the implementation of the standard member functions of the
  147. * Handler's class factory.
  148. *
  149. * AUTHOR : Guru Datta Venkatarama 01/30/97 08:30:18 (PST)
  150. *
  151. ------------------------------------------------------------*/
  152. // constructor ..
  153. CHandlerClassFactory::CHandlerClassFactory(void):m_ClassFactory_refcount(0){}
  154. // -----------------------------------------------------------
  155. // destructor ..
  156. CHandlerClassFactory::~CHandlerClassFactory(void){/**/}
  157. // -----------------------------------------------------------
  158. STDMETHODIMP CHandlerClassFactory::QueryInterface(
  159. REFIID riid,
  160. PPVOID ppv)
  161. {
  162. if (IsEqualIID(riid, IID_IUnknown))
  163. {
  164. *ppv = (LPUNKNOWN) (LPCLASSFACTORY) this;
  165. // add reference count every time a pointer is provided
  166. AddRef();
  167. return NOERROR;
  168. }
  169. else
  170. {
  171. if (IsEqualIID(riid, IID_IClassFactory))
  172. {
  173. *ppv = (LPCLASSFACTORY) this;
  174. // add reference count every time a pointer is provided
  175. AddRef();
  176. return NOERROR;
  177. }
  178. else
  179. {
  180. // unsupported interface requested
  181. *ppv = NULL;
  182. TRACE(TEXT("Mainhand.cpp: QueryInterface: Failed to find IID_IClassFactory!\n"));
  183. return ResultFromScode (E_NOINTERFACE);
  184. }
  185. }
  186. }
  187. // -----------------------------------------------------------
  188. STDMETHODIMP_(ULONG)CHandlerClassFactory::AddRef(void)
  189. {
  190. // bump up the usage count
  191. InterlockedIncrement((LPLONG)&m_ClassFactory_refcount);
  192. return m_ClassFactory_refcount;
  193. }
  194. // -----------------------------------------------------------
  195. STDMETHODIMP_(ULONG)CHandlerClassFactory::Release(void)
  196. {
  197. InterlockedDecrement((LPLONG)&m_ClassFactory_refcount);
  198. if(m_ClassFactory_refcount > 0)
  199. {
  200. return (m_ClassFactory_refcount);
  201. }
  202. else
  203. {
  204. delete this;
  205. return 0;
  206. }
  207. }
  208. // -----------------------------------------------------------
  209. /*------------------------------------------------------------
  210. ** CHandlerClassFactory::CreateInstance
  211. *
  212. * PARAMETERS : pUnkOuter = Pointer to controlling unknown
  213. * riid = Reference to interface ID specifier
  214. * ppvObj = Pointer to location to receive interface pointer
  215. * DESCRIPTION : CreateInstance is the class factory implementation.
  216. * It is called by the client to create the IServerCharacterstics interface
  217. * It is called by the members of the IServerCharacteristics interface
  218. * viz CreatePropertySheet and CreateDiagnostics to create the
  219. * appropriate interfaces for each.
  220. *
  221. * RETURNS : HRESULT code signifying success or failure
  222. *
  223. * AUTHOR : Guru Datta Venkatarama 01/31/97 09:29:36 (PST)
  224. *
  225. ------------------------------------------------------------*/
  226. STDMETHODIMP CHandlerClassFactory::CreateInstance(
  227. LPUNKNOWN pUnkOuter,
  228. REFIID riid,
  229. PPVOID ppvObj)
  230. {
  231. *ppvObj = NULL;
  232. HRESULT hr=S_OK;
  233. //Cannot aggregate here
  234. if (pUnkOuter != NULL)
  235. {
  236. return ResultFromScode(CLASS_E_NOAGGREGATION);
  237. }
  238. CPluginHandler *pCPluginHandler = new CPluginHandler;
  239. ASSERT (pCPluginHandler);
  240. if (!pCPluginHandler) return E_OUTOFMEMORY;
  241. hr = pCPluginHandler->QueryInterface(riid, ppvObj);
  242. // Init the CLSID
  243. if(SUCCEEDED(hr))
  244. pCPluginHandler->m_CLSID_whoamI = m_CLSID_whoamI;
  245. return hr;
  246. }
  247. /*------------------------------------------------------------
  248. ** LockServer
  249. *
  250. * PARAMETERS :
  251. *
  252. * DESCRIPTION : LockServer increments or decrements the DLL's lock count.
  253. *
  254. * RETURNS :
  255. *
  256. * AUTHOR : Guru Datta Venkatarama 01/31/97 18:40:17 (PST)
  257. * a-kirkh - Implemented
  258. *
  259. ------------------------------------------------------------*/
  260. STDMETHODIMP CHandlerClassFactory::LockServer(BOOL fLock)
  261. {
  262. if(fLock)
  263. InterlockedIncrement((LPLONG)&g_cServerLocks);
  264. else
  265. InterlockedDecrement((LPLONG)&g_cServerLocks);
  266. return S_OK;
  267. }
  268. /*------------------------------------------------------------
  269. ** CPluginHandler Object member functions
  270. *
  271. * PARAMETERS :
  272. *
  273. * DESCRIPTION :
  274. *
  275. * RETURNS :
  276. *
  277. * AUTHOR : Guru Datta Venkatarama 02/03/97 10:55:34 (PST)
  278. * a-kirkh - cleaned up the ref-counting
  279. *
  280. ------------------------------------------------------------*/
  281. CPluginHandler::CPluginHandler(void)
  282. {
  283. InterlockedIncrement((LPLONG)&g_cComponents);
  284. m_pImpIServerProperty = NULL;
  285. m_cPluginHandler_refcount = 0;
  286. return;
  287. }
  288. // -----------------------------------------------------------
  289. CPluginHandler::~CPluginHandler(void)
  290. {
  291. InterlockedDecrement((LPLONG)&g_cComponents);
  292. return;
  293. }
  294. // -----------------------------------------------------------
  295. STDMETHODIMP CPluginHandler::QueryInterface(
  296. REFIID riid,
  297. PPVOID ppv)
  298. {
  299. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IServerCharacteristics))
  300. {
  301. *ppv = this;
  302. }
  303. else
  304. {
  305. *ppv = NULL;
  306. TRACE(TEXT("Mainhand.cpp: QueryInterface: riid is != IID_IUnknown || IID_IServerCharacteristics!\n"));
  307. return ResultFromScode (E_NOINTERFACE);
  308. }
  309. AddRef();
  310. return(S_OK);
  311. }
  312. // -----------------------------------------------------------CPluginHandler::AddRef
  313. STDMETHODIMP_(ULONG)CPluginHandler::AddRef(void)
  314. {
  315. // bump up the usage count
  316. InterlockedIncrement((LPLONG)&m_cPluginHandler_refcount);
  317. return(m_cPluginHandler_refcount);
  318. }
  319. // -----------------------------------------------------------CPluginHandler::Release
  320. STDMETHODIMP_(ULONG)CPluginHandler::Release(void)
  321. {
  322. InterlockedDecrement((LPLONG)&m_cPluginHandler_refcount);
  323. if(m_cPluginHandler_refcount > 0)
  324. {
  325. return(m_cPluginHandler_refcount);
  326. }
  327. else
  328. {
  329. delete this;
  330. return 0;
  331. }
  332. }
  333. /*------------------------------------------------------------CPluginHandler::Launch
  334. ** CPluginHandler::Launch
  335. *
  336. * PARAMETERS : hWnd - Handle to window of the client (Control Panel)
  337. * startpage - Page to start with
  338. * nID - Joystick ID that the device associated with this page is on!
  339. *
  340. * DESCRIPTION : Restricts the building of property pages to our supported method.
  341. *
  342. * RETURNS : Error standard COM error codes or our errors from E_ERROR_START to E_ERROR_STOP (defined in sstructs.h)
  343. *
  344. * AUTHOR : Guru Datta Venkatarama
  345. * 02/03/97 14:47:47 (PST)
  346. *
  347. ------------------------------------------------------------*/
  348. STDMETHODIMP CPluginHandler::Launch(HWND hWnd, USHORT startpage, USHORT nID)
  349. {
  350. LPDIGCPAGEINFO serverpage;
  351. LPDIGCSHEETINFO serversheet;
  352. LPPROPSHEETPAGE pspptr;
  353. UINT loop_index;
  354. LPCDIGAMECNTRLPROPSHEET propiface;
  355. HRESULT hr=S_OK;
  356. ASSERT (::IsWindow(hWnd));
  357. if (startpage > MAX_PAGES)
  358. return DIGCERR_STARTPAGETOOLARGE;
  359. // check to make certain that the server has the required interface
  360. // step A : do we have an interface to work with ?
  361. //
  362. if(!(propiface = GetServerPropIface()))
  363. {
  364. TRACE(TEXT("Mainhand.cpp: Launch: GetPropIface didn't find IID_IDIGameCntrlPropSheet!\n"));
  365. return ResultFromScode (E_NOINTERFACE);
  366. }
  367. // Step B. Use the interface ...
  368. // step 1 : get the property sheet info from the server
  369. if (FAILED(propiface->GetSheetInfo(&serversheet)))
  370. {
  371. TRACE(TEXT("GCHAND.DLL: MAINHAND.CPP: Launch: GetSheetInfo Failed!\n"));
  372. return E_FAIL;
  373. }
  374. if (serversheet->nNumPages > MAX_PAGES)
  375. {
  376. return DIGCERR_NUMPAGESTOOLARGE;
  377. }
  378. // step 2 : get the information for all the pages from the server
  379. if (FAILED(propiface->GetPageInfo(&serverpage)))
  380. {
  381. TRACE(TEXT("GCHAND.DLL: MAINHAND.CPP: Launch: GetPageInfo Failed!\n"));
  382. return E_FAIL;
  383. }
  384. /* BLJ: REMOVED 1/12/98
  385. // return for testing of interface!!!
  386. #ifdef _DEBUG
  387. USES_CONVERSION;
  388. // PAGE TRACE MESSAGES
  389. for(loop_index=0; loop_index < serversheet->nNumPages; loop_index++)
  390. {
  391. TRACE(TEXT("GetPageInfo: Page %d dwSize is %d, expected %d\n"), loop_index, serverpage[loop_index].dwSize, sizeof(DIGCPAGEINFO));
  392. #ifdef _UNICODE
  393. TRACE(TEXT("GetPageInfo: Page %d lpwszPageTitle (AFTER ANSI CONVERSION) is %s\n"), loop_index, serverpage[loop_index].lpwszPageTitle);
  394. #else
  395. TRACE(TEXT("GetPageInfo: Page %d lpwszPageTitle (AFTER ANSI CONVERSION) is %s\n"), loop_index, W2A(serverpage[loop_index].lpwszPageTitle));
  396. #endif
  397. if (serverpage[loop_index].fpPageProc)
  398. TRACE(TEXT("GetPageInfo: Page %d Has an assigned page proc!\n"), loop_index);
  399. else
  400. TRACE(TEXT("GetPageInfo: Page %d Has NO assigned page proc!\n"), loop_index);
  401. if (serverpage[loop_index].fProcFlag)
  402. {
  403. TRACE(TEXT("GetPageInfo: Page %d Has a PrePostPage proc and %s\n"), loop_index,
  404. (serverpage[loop_index].fpPrePostProc) ? "it is NOT NULL" : "it is NULL!");
  405. }
  406. else TRACE(TEXT("GetPageInfo: Page %d's PrePostPage proc flag is FALSE!\n"), loop_index);
  407. if (serverpage[loop_index].fIconFlag)
  408. {
  409. TRACE(TEXT("GetPageInfo: Page %d's fIconFlag flag is TRUE!\n"), loop_index);
  410. }
  411. else
  412. TRACE(TEXT("GetPageInfo: Page %d's fIconFlag flag is FALSE!\n"), loop_index);
  413. TRACE(TEXT("GetPageInfo: Page %d's lParam is %d\n"), loop_index, serverpage[loop_index].lParam);
  414. // TRACE(TEXT("GetPageInfo: Page %d's lpwszTemplate (AFTER ANSI CONVERSION) is %s\n"), loop_index, W2A(serverpage[loop_index].lpwszTemplate));
  415. TRACE(TEXT("GetPageInfo: Page %d's hInstance is %x\n"), loop_index, serverpage[loop_index].hInstance);
  416. }
  417. // SHEET TRACE MESSAGES!!!
  418. TRACE (TEXT("GetSheetInfo: dwSize %d, expected %d\n"), serversheet->dwSize, sizeof(DIGCSHEETINFO));
  419. TRACE (TEXT("GetSheetInfo: nNumPages %d\n"), serversheet->nNumPages);
  420. #ifdef _UNICODE
  421. TRACE (TEXT("GetSheetInfo: lpwszSheetCaption (AFTER CONVERSION TO ANSI) is %s\n"), serversheet->lpwszSheetCaption);
  422. #else
  423. TRACE (TEXT("GetSheetInfo: lpwszSheetCaption (AFTER CONVERSION TO ANSI) is %s\n"), W2A(serversheet->lpwszSheetCaption));
  424. #endif
  425. if (serversheet->fSheetIconFlag)
  426. {
  427. TRACE (TEXT("GetSheetInfo: fSheetInfoFlag is set to TRUE!\n"));
  428. // TRACE (TEXT("GetSheetInfo: lpwszSheetIcon (AFTER CONVERSION TO ANSI) is %s\n"), W2A(serversheet->lpwszSheetIcon));
  429. }
  430. else
  431. TRACE (TEXT("GetSheetInfo: fSheetInfoFlag is set to FALSE!\n"));
  432. #endif
  433. */
  434. // here's where we are sending the property sheet an ID describing the location of the installed device!
  435. hr = propiface->SetID(nID);
  436. ASSERT (SUCCEEDED(hr));
  437. // step 3 : construct the property pages structure
  438. // 3.1 allocate an array of PROPERTYSHEETPAGE for the number of pages required
  439. if(!(pspptr = (LPPROPSHEETPAGE) malloc(sizeof(PROPSHEETPAGE)*serversheet->nNumPages)))
  440. {
  441. return ResultFromScode (E_OUTOFMEMORY);
  442. }
  443. else
  444. {
  445. #ifndef _UNICODE
  446. USES_CONVERSION;
  447. #endif
  448. // 3.2 Now proceed to fill up each page
  449. for(loop_index=0;loop_index<serversheet->nNumPages;loop_index++)
  450. {
  451. // transfer data .. the size
  452. pspptr[loop_index].dwSize = sizeof(PROPSHEETPAGE);
  453. // transfer the lparam value
  454. pspptr[loop_index].lParam = serverpage[loop_index].lParam;
  455. // ---------- TITLING OF THE PAGE ----------------------------
  456. // set the basic flags
  457. pspptr[loop_index].dwFlags = 0;
  458. if (serverpage[loop_index].lpwszPageTitle)
  459. {
  460. pspptr[loop_index].dwFlags |= PSP_USETITLE;
  461. // Check to see if you are a String!!!
  462. if (HIWORD((INT_PTR)serverpage[loop_index].lpwszPageTitle))
  463. {
  464. #ifdef _UNICODE
  465. pspptr[loop_index].pszTitle = serverpage[loop_index].lpwszPageTitle;
  466. #else
  467. pspptr[loop_index].pszTitle = W2A(serverpage[loop_index].lpwszPageTitle);
  468. #endif
  469. }
  470. else pspptr[loop_index].pszTitle = (LPTSTR)serverpage[loop_index].lpwszPageTitle;
  471. }
  472. else
  473. {
  474. pspptr[loop_index].pszTitle = NULL;
  475. }
  476. /*
  477. if (!lstrlen(pspptr[loop_index].pszTitle))
  478. {
  479. return DIGCERR_NOTITLE;
  480. }
  481. */
  482. // if icon is required go ahead and add it.
  483. if(serverpage[loop_index].fIconFlag)
  484. {
  485. pspptr[loop_index].dwFlags |= PSP_USEICONID;
  486. // Check to see if you are an INT or a String!
  487. if (HIWORD((INT_PTR)serverpage[loop_index].lpwszPageIcon))
  488. {
  489. // You're a string!!!
  490. #ifdef _UNICODE
  491. pspptr[loop_index].pszIcon = serverpage[loop_index].lpwszPageIcon;
  492. #else
  493. pspptr[loop_index].pszIcon = W2A(serverpage[loop_index].lpwszPageIcon);
  494. #endif
  495. }
  496. else pspptr[loop_index].pszIcon = (LPCTSTR)(serverpage[loop_index].lpwszPageIcon);
  497. }
  498. // ---------- PROCEDURAL SUPPORT FOR THE PAGE ----------------
  499. // if a pre - post processing call back proc is required go ahead and add it
  500. if(serverpage[loop_index].fProcFlag)
  501. {
  502. if(serverpage[loop_index].fpPrePostProc)
  503. {
  504. pspptr[loop_index].dwFlags |= PSP_USECALLBACK;
  505. pspptr[loop_index].pfnCallback = (LPFNPSPCALLBACK) serverpage[loop_index].fpPrePostProc;
  506. }
  507. else
  508. {
  509. return DIGCERR_NOPREPOSTPROC;
  510. }
  511. }
  512. // and the essential "dialog" proc
  513. if(serverpage[loop_index].fpPageProc)
  514. {
  515. pspptr[loop_index].pfnDlgProc = serverpage[loop_index].fpPageProc;
  516. }
  517. else
  518. {
  519. return DIGCERR_NODLGPROC;
  520. }
  521. // ---------- INSTANCE & PARENTHOOD --------------------------
  522. pspptr[loop_index].hInstance = serverpage[loop_index].hInstance;
  523. pspptr[loop_index].pcRefParent = 0;
  524. // ---------- DIALOG TEMPLATE --------------------------------
  525. if (HIWORD((INT_PTR)serverpage[loop_index].lpwszTemplate))
  526. {
  527. #ifdef _UNICODE
  528. pspptr[loop_index].pszTemplate = serverpage[loop_index].lpwszTemplate;
  529. #else
  530. pspptr[loop_index].pszTemplate = W2A(serverpage[loop_index].lpwszTemplate);
  531. #endif
  532. }
  533. else
  534. {
  535. pspptr[loop_index].pszTemplate = (LPTSTR)serverpage[loop_index].lpwszTemplate;
  536. }
  537. // test to see if template will fit on the screen!
  538. }
  539. }
  540. // step 4 : construct the property sheet header
  541. // %%% debug %%% - strange stuff - not there in include file ! PSH_MULTILINETABS |
  542. LPPROPSHEETHEADER ppsh = new (PROPSHEETHEADER);
  543. ASSERT (ppsh);
  544. ZeroMemory(ppsh, sizeof(PROPSHEETHEADER));
  545. ppsh->dwSize = sizeof(PROPSHEETHEADER);
  546. ppsh->dwFlags = PSH_PROPSHEETPAGE;
  547. ppsh->hwndParent = hWnd;
  548. if (serversheet->fSheetIconFlag)
  549. {
  550. if (serversheet->lpwszSheetIcon)
  551. {
  552. // check to see if you are an INT or a WSTR
  553. if (HIWORD((INT_PTR)serversheet->lpwszSheetIcon))
  554. {
  555. // You are a string!
  556. #ifdef _UNICODE
  557. ppsh->pszIcon = serversheet->lpwszSheetIcon;
  558. #else
  559. USES_CONVERSION;
  560. ppsh->pszIcon = W2A(serversheet->lpwszSheetIcon);
  561. #endif
  562. }
  563. else ppsh->pszIcon = (LPTSTR)serversheet->lpwszSheetIcon;
  564. ppsh->dwFlags |= PSH_USEICONID;
  565. }
  566. else return DIGCERR_NOICON;
  567. }
  568. // do we have a sheet caption ?
  569. if (serversheet->lpwszSheetCaption)
  570. {
  571. // is the sheet caption provided physically existant ?
  572. if(wcslen(serversheet->lpwszSheetCaption))
  573. {
  574. #ifdef _UNICODE
  575. ppsh->pszCaption = serversheet->lpwszSheetCaption;
  576. #else
  577. USES_CONVERSION;
  578. ppsh->pszCaption = W2A(serversheet->lpwszSheetCaption);
  579. #endif
  580. ppsh->dwFlags |= PSH_PROPTITLE;
  581. }
  582. else
  583. {
  584. return DIGCERR_NOCAPTION;
  585. }
  586. }
  587. // test for user error!
  588. if (!serversheet->nNumPages)
  589. return DIGCERR_NUMPAGESZERO;
  590. // set the number of pages %%% debug %%% is this limit appropriate ?
  591. ppsh->nPages = serversheet->nNumPages;
  592. // ( and whilst at it ) : select the current page
  593. if (serversheet->nNumPages > startpage)
  594. ppsh->nStartPage = startpage;
  595. else
  596. return DIGCERR_STARTPAGETOOLARGE;
  597. // set the property pages inofrmation into the header
  598. ppsh->ppsp = (LPCPROPSHEETPAGE)pspptr;
  599. // and set the standard call back function for the property sheet
  600. ppsh->pfnCallback = NULL;
  601. // step 5 : launch modal property sheet dialog
  602. switch (PropertySheet(ppsh))
  603. {
  604. // In the event that the user wants to reboot...
  605. case ID_PSREBOOTSYSTEM:
  606. case ID_PSRESTARTWINDOWS:
  607. #ifdef _DEBUG
  608. TRACE(TEXT("GCHAND.DLL: PropertySheet returned a REBOOT request!\n"));
  609. #endif
  610. ExitWindowsEx(EWX_REBOOT, NULL);
  611. break;
  612. }
  613. if (ppsh)
  614. delete (ppsh);
  615. if (pspptr)
  616. free (pspptr);
  617. // step 6 : release all elements of the Property interface on the server
  618. propiface->Release();
  619. // step 7 : return success / failure code back to the caller
  620. return(hr);
  621. }
  622. /*------------------------------------------------------------CPluginHandler::GetReport
  623. ** CPluginHandler::GetReport
  624. *
  625. * PARAMETERS :
  626. *
  627. * DESCRIPTION : Provides the client with a report of the number of property pages that
  628. * this server supports and their names
  629. *
  630. * RETURNS :
  631. *
  632. * AUTHOR : Guru Datta Venkatarama 02/11/97 15:26:56 (PST)
  633. * a-kirkh - Added asserts
  634. *
  635. ------------------------------------------------------------*/
  636. STDMETHODIMP CPluginHandler::GetReport(LPDIGCSHEETINFO *pServerSheetData, LPDIGCPAGEINFO *pServerPageData)
  637. {
  638. // check out your parameters
  639. ASSERT (pServerSheetData);
  640. ASSERT (pServerPageData );
  641. LPCDIGAMECNTRLPROPSHEET pPropIFace = GetServerPropIface();
  642. ASSERT (pPropIFace);
  643. if(!pPropIFace)
  644. return ResultFromScode (E_NOINTERFACE);
  645. // A little temp pointer for error trapping...
  646. LPDIGCSHEETINFO pTmpSheet;
  647. // get the property sheet info from the server
  648. HRESULT hr = pPropIFace->GetSheetInfo(&pTmpSheet);
  649. ASSERT (SUCCEEDED(hr));
  650. #ifdef _DEBUG
  651. // SHEET TRACE MESSAGES!!!
  652. USES_CONVERSION;
  653. TRACE (TEXT("GetSheetInfo: dwSize %d, expected %d\n"), pTmpSheet->dwSize, sizeof(DIGCSHEETINFO));
  654. TRACE (TEXT("GetSheetInfo: nNumPages %d\n"), pTmpSheet->nNumPages);
  655. #ifdef _UNICODE
  656. TRACE (TEXT("GetSheetInfo: lpwszSheetCaption (AFTER CONVERSION TO ANSI) is %s\n"), pTmpSheet->lpwszSheetCaption);
  657. #else
  658. TRACE (TEXT("GetSheetInfo: lpwszSheetCaption (AFTER CONVERSION TO ANSI) is %s\n"), W2A(pTmpSheet->lpwszSheetCaption));
  659. #endif
  660. if (pTmpSheet->fSheetIconFlag)
  661. {
  662. TRACE (TEXT("GetSheetInfo: fSheetInfoFlag is set to TRUE!\n"));
  663. // Check to see if you are a string!
  664. if (HIWORD((INT_PTR)pTmpSheet->lpwszSheetIcon))
  665. #ifdef _UNICODE
  666. TRACE (TEXT("GetSheetInfo: lpwszSheetIcon (AFTER CONVERSION TO ANSI) is %s\n"), pTmpSheet->lpwszSheetIcon);
  667. #else
  668. TRACE (TEXT("GetSheetInfo: lpwszSheetIcon (AFTER CONVERSION TO ANSI) is %s\n"), W2A(pTmpSheet->lpwszSheetIcon));
  669. #endif
  670. else
  671. TRACE (TEXT("GetSheetInfo: lpwszSheetIcon id is %d\n"), pTmpSheet->lpwszSheetIcon);
  672. }
  673. else
  674. TRACE (TEXT("GetSheetInfo: fSheetInfoFlag is set to FALSE!\n"));
  675. #endif
  676. if (pTmpSheet->dwSize != sizeof(DIGCSHEETINFO))
  677. {
  678. TRACE (TEXT("MainHand: GetReport: Error - Call to GetSheetInfo returned an invalid dwSize parameter!\n"));
  679. // Just in case someone's not checking their return values...
  680. memset (pServerSheetData, 0, sizeof(DIGCSHEETINFO));
  681. pPropIFace->Release();
  682. return DIGCERR_INVALIDDWSIZE;
  683. }
  684. // A little temp pointer for error trapping...
  685. LPDIGCPAGEINFO pTmpPage;
  686. hr = pPropIFace->GetPageInfo (&pTmpPage);
  687. ASSERT (SUCCEEDED(hr));
  688. #ifdef _DEBUG
  689. // PAGE TRACE MESSAGES!!!
  690. for(BYTE loop_index=0; loop_index < pTmpSheet->nNumPages; loop_index++)
  691. {
  692. TRACE(TEXT("GetPageInfo: Page %d dwSize is %d, expected %d\n"), loop_index, pTmpPage[loop_index].dwSize, sizeof(DIGCPAGEINFO));
  693. #ifdef _UNICODE
  694. TRACE(TEXT("GetPageInfo: Page %d lpwszPageTitle (AFTER CONVERSION TO ANSI) is %s\n"), loop_index, pTmpPage[loop_index].lpwszPageTitle);
  695. #else
  696. TRACE(TEXT("GetPageInfo: Page %d lpwszPageTitle (AFTER CONVERSION TO ANSI) is %s\n"), loop_index, W2A(pTmpPage[loop_index].lpwszPageTitle));
  697. #endif
  698. if (pTmpPage[loop_index].fpPageProc)
  699. TRACE(TEXT("GetPageInfo: Page %d Has an assigned page proc!\n"), loop_index);
  700. else
  701. TRACE(TEXT("GetPageInfo: Page %d Has NO assigned page proc!\n"), loop_index);
  702. if (pTmpPage[loop_index].fProcFlag)
  703. {
  704. TRACE(TEXT("GetPageInfo: Page %d Has a PrePostPage proc and %s\n"), loop_index,
  705. (pTmpPage[loop_index].fpPrePostProc) ? "it is NOT NULL" : "it is NULL!");
  706. }
  707. else TRACE(TEXT("GetPageInfo: Page %d's PrePostPage proc flag is FALSE!\n"), loop_index);
  708. if (pTmpPage[loop_index].fIconFlag)
  709. {
  710. // Check to see if you are a string!
  711. if (HIWORD((INT_PTR)pTmpPage[loop_index].lpwszPageIcon))
  712. #ifdef _UNICODE
  713. TRACE (TEXT("GetSheetInfo: lpwszPageIcon #%d (AFTER CONVERSION TO ANSI) is %s\n"), loop_index, pTmpPage[loop_index].lpwszPageIcon);
  714. #else
  715. TRACE (TEXT("GetSheetInfo: lpwszPageIcon #%d (AFTER CONVERSION TO ANSI) is %s\n"), loop_index, W2A(pTmpPage[loop_index].lpwszPageIcon));
  716. #endif
  717. else
  718. TRACE (TEXT("GetSheetInfo: lpwszPageIcon #%d id is %d\n"), loop_index, pTmpSheet->lpwszSheetIcon);
  719. }
  720. else TRACE(TEXT("GetPageInfo: Page %d's fIconFlag flag is FALSE!\n"), loop_index);
  721. TRACE(TEXT("GetPageInfo: Page %d's lParam is %d\n"), loop_index, pTmpPage->lParam);
  722. // TRACE(TEXT("GetPageInfo: Page %d's lpwszTemplate (AFTER ANSI CONVERSION) is %s\n"), loop_index, W2A(pTmpPage[loop_index].lpwszTemplate));
  723. TRACE(TEXT("GetPageInfo: Page %d's hInstance is %d\n"), loop_index, pTmpPage->hInstance);
  724. }
  725. #endif
  726. for (BYTE nIndex = 0; nIndex < pTmpSheet->nNumPages; nIndex++)
  727. {
  728. if (pTmpPage[nIndex].dwSize != sizeof(DIGCPAGEINFO))
  729. {
  730. TRACE (TEXT("MainHand: GetReport: Error - Call to GetPageInfo returned an invalid dwSize parameter!\n"));
  731. // Just in case someone's not checking their return values...
  732. memset (pServerPageData, 0, sizeof(DIGCPAGEINFO));
  733. pPropIFace->Release();
  734. return DIGCERR_INVALIDDWSIZE;
  735. }
  736. }
  737. // Assign and return...
  738. *pServerSheetData = pTmpSheet;
  739. *pServerPageData = pTmpPage;
  740. pPropIFace->Release();
  741. return S_OK;
  742. }
  743. /*------------------------------------------------------------PropSheetCallback
  744. ** PropSheetCallback
  745. *
  746. * PARAMETERS :
  747. *
  748. * DESCRIPTION :
  749. *
  750. * RETURNS :
  751. *
  752. * AUTHOR : Guru Datta Venkatarama
  753. * 02/11/97 14:01:50 (PST)
  754. *
  755. ------------------------------------------------------------*/
  756. int CALLBACK PropSheetCallback(
  757. HWND hDlg,
  758. UINT uMsg,
  759. LPARAM lParam)
  760. {
  761. switch (uMsg)
  762. {
  763. case PSCB_INITIALIZED:
  764. break;
  765. case PSCB_PRECREATE:
  766. break;
  767. }
  768. return 0;
  769. }
  770. /*------------------------------------------------------------CPluginHandler::LoadServerInterface
  771. ************************************ PRIVATE TO THE CLASS ***************************************
  772. ** CPluginHandler::LoadServerInterface
  773. *
  774. * PARAMETERS :
  775. *
  776. * DESCRIPTION :
  777. *
  778. * RETURNS :
  779. *
  780. * AUTHOR : Guru Datta Venkatarama
  781. * 02/10/97 10:54:25 (PST)
  782. *
  783. ------------------------------------------------------------*/
  784. BOOL CPluginHandler::LoadServerInterface(REFIID interfaceId,PPVOID ppv)
  785. {
  786. IClassFactory* ppv_classfactory;
  787. if(SUCCEEDED(CoGetClassObject( m_CLSID_whoamI, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&ppv_classfactory)))
  788. {
  789. if(SUCCEEDED(ppv_classfactory->CreateInstance(NULL, interfaceId, ppv)))
  790. {
  791. ppv_classfactory->Release();
  792. return TRUE;
  793. }
  794. else
  795. {
  796. TRACE(TEXT("Mainhand.cpp: CreateInstance Failed!\n"));
  797. }
  798. // make sure the pointer is nulled
  799. *ppv = NULL;
  800. ppv_classfactory->Release();
  801. }
  802. else
  803. {
  804. TRACE(TEXT("Mainhand.cpp: LoadServerInterface Failed!\n"));
  805. }
  806. // Its time for the swarming herd of turtles
  807. return FALSE;
  808. }
  809. //*********************************************************************************************
  810. // -------------------------------------------------------------------EOF