Leaked source code of windows server 2003
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.

1001 lines
24 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // File: oleimpl.cxx
  4. //
  5. // Contents: This file contins the DLL entry points
  6. // LibMain
  7. // DllGetClassObject (Bindings key func)
  8. // CAdvBndCF (class factory)
  9. // CAdvBnd (actual class implementation)
  10. //
  11. // Classes: CAdvBndCF, CAdvBnd
  12. //
  13. //
  14. // History: 30-Nov-92 SarahJ Created
  15. // 31-Dec-93 ErikGav Chicago port
  16. //---------------------------------------------------------------------
  17. // Turn off ole Cairol IUnknown
  18. #include "headers.cxx"
  19. #pragma hdrstop
  20. #include <stdio.h>
  21. #include <stdarg.h>
  22. #include "wterm.h"
  23. #define IDM_DEBUG 0x100
  24. static const TCHAR *szAppName = TEXT("Test OLE Server");
  25. static const char *szFatalError = "OLESRV - Fatal Error";
  26. void MsgBox(char *pszMsg)
  27. {
  28. MessageBoxA(NULL, pszMsg, szFatalError, MB_OK);
  29. }
  30. void HrMsgBox(char *pszMsg, HRESULT hr)
  31. {
  32. char awcBuf[512];
  33. // Build string for output
  34. wsprintfA(awcBuf, "%s HRESULT = %lx", pszMsg, hr);
  35. // Display message box
  36. MessageBoxA(NULL, &awcBuf[0], szFatalError, MB_OK);
  37. }
  38. //+-------------------------------------------------------------------
  39. // Class: CTestServerApp
  40. //
  41. // Synopsis: Class that holds application-wide data and methods
  42. //
  43. // Methods: InitApp
  44. // CloseApp
  45. // GetEmbeddedFlag
  46. //
  47. // History: 17-Dec-92 DeanE Created
  48. //--------------------------------------------------------------------
  49. class FAR CTestServerApp
  50. {
  51. public:
  52. // Constructor/Destructor
  53. CTestServerApp();
  54. ~CTestServerApp();
  55. SCODE InitApp (LPSTR lpszCmdline);
  56. SCODE CloseApp (void);
  57. BOOL GetEmbeddedFlag (void);
  58. ULONG IncEmbeddedCount(void);
  59. ULONG DecEmbeddedCount(void);
  60. private:
  61. IClassFactory *_pteClassFactory;
  62. ULONG _cEmbeddedObjs; // Count of embedded objects this server
  63. // is controlling now
  64. DWORD _dwRegId; // OLE registration ID
  65. BOOL _fRegistered; // TRUE if srv was registered w/OLE
  66. BOOL _fEmbedded; // TRUE if OLE started us at the request
  67. // of an embedded obj in a container app
  68. };
  69. CTestServerApp tsaMain;
  70. HWND g_hMain;
  71. void ProcessCmdLine(LPSTR, BOOL *);
  72. //+--------------------------------------------------------------
  73. // Function: CTestServerApp::CTestServerApp
  74. //
  75. // Synopsis: Constructor - initialize members
  76. //
  77. // Parameters: None
  78. //
  79. // Returns: None
  80. //
  81. // History: 17-Dec-92 DeanE Created
  82. //---------------------------------------------------------------
  83. CTestServerApp::CTestServerApp()
  84. {
  85. _pteClassFactory = NULL;
  86. _dwRegId = 0;
  87. _fRegistered = FALSE;
  88. _fEmbedded = TRUE;
  89. _cEmbeddedObjs = 0;
  90. }
  91. //+--------------------------------------------------------------
  92. // Function: CTestServerApp::~CTestServerApp
  93. //
  94. // Synopsis: Insure pointers are free - note this is mainly for
  95. // error-checking.
  96. //
  97. // Parameters: None
  98. //
  99. // Returns: None
  100. //
  101. // History: 17-Dec-92 DeanE Created
  102. //---------------------------------------------------------------
  103. CTestServerApp::~CTestServerApp()
  104. {
  105. Win4Assert(_pteClassFactory == NULL &&
  106. "Class factory should have been released");
  107. }
  108. //+--------------------------------------------------------------
  109. // Function: CTestServerApp::InitApp
  110. //
  111. // Synopsis: Initialize this instance of the app.
  112. //
  113. // Parameters: [lpszCmdline] - Command line of the application.
  114. //
  115. // Returns: S_OK if everything was initialized, or an error if not.
  116. //
  117. // History: 17-Dec-92 DeanE Created
  118. //
  119. // Notes: If this does not return, the CloseApp method should
  120. // still be called for proper cleanup.
  121. //---------------------------------------------------------------
  122. SCODE CTestServerApp::InitApp(LPSTR lpszCmdline)
  123. {
  124. SCODE sc;
  125. // Check OLE version running
  126. // BUGBUG - NYI by OLE
  127. // Bail out if we are not running with an acceptable version of OLE
  128. // Process Command Line arguments
  129. ProcessCmdLine(lpszCmdline, &_fEmbedded);
  130. // Create the applications class factory - note that we have to free
  131. // at a later time
  132. _pteClassFactory = new CAdvBndCF();
  133. if (NULL == _pteClassFactory)
  134. {
  135. MsgBox("Class Object Creation Failed");
  136. return(E_ABORT);
  137. }
  138. // Register the class with OLE
  139. sc = CoRegisterClassObject(
  140. CLSID_AdvBnd,
  141. _pteClassFactory,
  142. CLSCTX_LOCAL_SERVER,
  143. REGCLS_MULTIPLEUSE,
  144. &_dwRegId);
  145. if (S_OK == sc)
  146. {
  147. _fRegistered = TRUE;
  148. }
  149. else
  150. {
  151. HrMsgBox("CoRegisterClassObject FAILED", sc);
  152. }
  153. return(sc);
  154. }
  155. //+--------------------------------------------------------------
  156. // Function: CTestServerApp::CloseApp
  157. //
  158. // Synopsis: Clean up resources this instance of the app is using.
  159. //
  160. // Parameters: None
  161. //
  162. // Returns: S_OK if everything was cleaned up, or an error if not.
  163. //
  164. // History: 17-Dec-92 DeanE Created
  165. //---------------------------------------------------------------
  166. SCODE CTestServerApp::CloseApp()
  167. {
  168. // Revoke the class object, if registered
  169. if (TRUE == _fRegistered)
  170. {
  171. CoRevokeClassObject(_dwRegId);
  172. }
  173. // Release this apps class factory, and insure the returned count is 0
  174. if (NULL != _pteClassFactory)
  175. {
  176. // NB: Workaround for ref count problem.
  177. #define HACK 1
  178. #if HACK
  179. _pteClassFactory->Release();
  180. _pteClassFactory = NULL;
  181. #else
  182. if (0 == _pteClassFactory->Release())
  183. {
  184. _pteClassFactory = NULL;
  185. }
  186. else
  187. {
  188. Win4Assert("Release on class factory returned positive ref count");
  189. // BUGBUG - Log error
  190. }
  191. #endif
  192. }
  193. return(S_OK);
  194. }
  195. //+--------------------------------------------------------------
  196. // Function: CTestServerApp::GetEmbeddedFlag
  197. //
  198. // Synopsis: Returns TRUE if app was started for an embedded object,
  199. // FALSE if standalone.
  200. //
  201. // Parameters: None
  202. //
  203. // Returns: BOOL (_fEmbedded)
  204. //
  205. // History: 17-Dec-92 DeanE Created
  206. //
  207. // Notes: BUGBUG - This should be an inline method
  208. //---------------------------------------------------------------
  209. CTestServerApp::GetEmbeddedFlag()
  210. {
  211. return(_fEmbedded);
  212. }
  213. //+--------------------------------------------------------------
  214. // Function: CTestServerApp::IncEmbeddedCount
  215. //
  216. // Synopsis: Increments the count of embedded objects the server
  217. // has open.
  218. //
  219. // Parameters: None
  220. //
  221. // Returns: ULONG (_cEmbeddedObjs)
  222. //
  223. // History: 17-Dec-92 DeanE Created
  224. //
  225. // Notes: BUGBUG - This should be an inline method
  226. //---------------------------------------------------------------
  227. ULONG CTestServerApp::IncEmbeddedCount()
  228. {
  229. return(++_cEmbeddedObjs);
  230. }
  231. //+--------------------------------------------------------------
  232. // Function: CTestServerApp::DecEmbeddedCount
  233. //
  234. // Synopsis: Decrements the count of embedded objects the server
  235. // has open. If 0 are left and we were running for an
  236. // embedded object(s), shut down.
  237. //
  238. // Parameters: None
  239. //
  240. // Returns: ULONG (_cEmbeddedObjs)
  241. //
  242. // History: 17-Dec-92 DeanE Created
  243. //
  244. // Notes: BUGBUG - This should be an inline method
  245. //---------------------------------------------------------------
  246. ULONG CTestServerApp::DecEmbeddedCount()
  247. {
  248. if ((0 == --_cEmbeddedObjs) && _fEmbedded)
  249. {
  250. // We are done so revoke our OLE stuff. We need to do this as
  251. // soon as we know that we are shutting down so that the window
  252. // for returning a bad class object is shut.
  253. CloseApp();
  254. // Tell window to die
  255. SendMessage(g_hMain, WM_USER, 0xFFFFFFFF, 0xFFFFFFFF);
  256. }
  257. return(_cEmbeddedObjs);
  258. }
  259. //+--------------------------------------------------------------
  260. // Function: ProcessCmdline
  261. //
  262. // Synopsis: Checks the cmd line parameters, in particular for
  263. // '/Embedding' or '-Embedding'.
  264. //
  265. // Parameters: [lpszCmdLine] - Command line buffer.
  266. // [pfEmbedded] - Flag should be set to true if we get
  267. // the '/Embedding' switch.
  268. //
  269. // Returns: void
  270. //
  271. // History: 25-Nov-92 DeanE Created
  272. //
  273. // Notes: Only two valid commandlines for this program:
  274. // (1) -Embedding when started by OLE or (2) Null
  275. // string if started from the command line.
  276. //---------------------------------------------------------------
  277. void ProcessCmdLine(LPSTR lpszCmdline, BOOL *pfEmbedded)
  278. {
  279. if (lpszCmdline[0] == 0)
  280. {
  281. *pfEmbedded = FALSE;
  282. return;
  283. }
  284. if (strcmp(lpszCmdline, "-Embedding") == 0)
  285. {
  286. *pfEmbedded = TRUE;
  287. return;
  288. }
  289. MsgBox("Received an invalid command line!");
  290. *pfEmbedded = FALSE;
  291. return;
  292. }
  293. void Display(TCHAR *pszFmt, ...)
  294. {
  295. va_list marker;
  296. TCHAR szBuffer[256];
  297. va_start(marker, pszFmt);
  298. #ifdef UNICODE
  299. int iLen = vswprintf(szBuffer, pszFmt, marker);
  300. #else
  301. int iLen = vsprintf(szBuffer, pszFmt, marker);
  302. #endif
  303. va_end(marker);
  304. // Display the message on terminal window
  305. SendMessage(g_hMain, WM_PRINT_LINE, iLen, (LONG) szBuffer);
  306. }
  307. //+-------------------------------------------------------------------------
  308. //
  309. // Function: ProcessMenu
  310. //
  311. // Synopsis: Gets called when a WM_COMMAND message received.
  312. //
  313. // Arguments: [hWindow] - handle for the window
  314. // [uiMessage] - message id
  315. // [wParam] - word parameter
  316. // [lParam] - long parameter
  317. //
  318. // Returns: DefWindowProc result
  319. //
  320. // History: 06-Aug-92 Ricksa Created
  321. //
  322. //--------------------------------------------------------------------------
  323. long ProcessMenu(HWND hWindow, UINT uiMessage, WPARAM wParam, LPARAM lParam,
  324. void *)
  325. {
  326. if ((uiMessage == WM_SYSCOMMAND) && (wParam == IDM_DEBUG))
  327. {
  328. // Request for a debug breakpoint!
  329. DebugBreak();
  330. }
  331. return (DefWindowProc(hWindow, uiMessage, wParam, lParam));
  332. }
  333. //+-------------------------------------------------------------------------
  334. //
  335. // Function: ProcessChar
  336. //
  337. // Synopsis: Gets called when a WM_CHAR message received.
  338. //
  339. // Arguments: [hWindow] - handle for the window
  340. // [uiMessage] - message id
  341. // [wParam] - word parameter
  342. // [lParam] - long parameter
  343. //
  344. // Returns: DefWindowProc result
  345. //
  346. // History: 06-Aug-92 Ricksa Created
  347. //
  348. //--------------------------------------------------------------------------
  349. long ProcessChar(HWND hWindow, UINT uiMessage, WPARAM wParam, LPARAM lParam,
  350. void *)
  351. {
  352. return (DefWindowProc(hWindow, uiMessage, wParam, lParam));
  353. }
  354. //+-------------------------------------------------------------------------
  355. //
  356. // Function: ProcessClose
  357. //
  358. // Synopsis: Gets called when a NC_DESTROY message received.
  359. //
  360. // Arguments: [hWindow] - handle for the window
  361. // [uiMessage] - message id
  362. // [wParam] - word parameter
  363. // [lParam] - long parameter
  364. //
  365. // Returns: DefWindowProc result
  366. //
  367. // History: 06-Aug-92 Ricksa Created
  368. //
  369. //--------------------------------------------------------------------------
  370. long ProcessClose(
  371. HWND hWindow,
  372. UINT uiMessage,
  373. WPARAM wParam,
  374. LPARAM lParam,
  375. void *pvCallBackData)
  376. {
  377. // Take default action with message
  378. return (DefWindowProc(hWindow, uiMessage, wParam, lParam));
  379. }
  380. //+-------------------------------------------------------------------
  381. //
  382. // Function: WinMain
  383. //
  384. // Synopsis: Entry point to DLL - does little else
  385. //
  386. // Arguments:
  387. //
  388. // Returns: TRUE
  389. //
  390. // History: 21-Nov-92 SarahJ Created
  391. //
  392. //--------------------------------------------------------------------
  393. int WINAPI WinMain(
  394. HINSTANCE hInstance,
  395. HINSTANCE hPrevInstance,
  396. char *lpszCmdLine,
  397. int nCmdShow)
  398. {
  399. // For windows message
  400. MSG msg;
  401. BOOL bRet;
  402. HRESULT hr;
  403. // Register the window class
  404. bRet = TermRegisterClass(hInstance, NULL, (LPTSTR) szAppName,
  405. (LPTSTR) MAKEINTRESOURCE(IDI_APPLICATION));
  406. if (!bRet)
  407. {
  408. MsgBox("TermRegisterClass FAILED");
  409. return 1;
  410. }
  411. // Create the server window
  412. bRet = TermCreateWindow(
  413. (LPTSTR) szAppName,
  414. (LPTSTR) szAppName,
  415. NULL,
  416. ProcessMenu,
  417. ProcessChar,
  418. ProcessClose,
  419. SW_SHOWMINIMIZED,
  420. &g_hMain,
  421. NULL);
  422. if (!bRet)
  423. {
  424. MsgBox("TermCreateWindow FAILED");
  425. return 1;
  426. }
  427. // Add debug option to system menu
  428. HMENU hmenu = GetSystemMenu(g_hMain, FALSE);
  429. AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
  430. AppendMenu(hmenu, MF_STRING | MF_ENABLED, IDM_DEBUG, TEXT("Debug"));
  431. // Look up the thread mode from the win.ini file.
  432. DWORD thread_mode;
  433. TCHAR buffer[80];
  434. int len;
  435. len = GetProfileString( TEXT("OleSrv"),
  436. TEXT("ThreadMode"),
  437. TEXT("MultiThreaded"),
  438. buffer,
  439. sizeof(buffer) / sizeof(TCHAR));
  440. if (lstrcmp(buffer, TEXT("ApartmentThreaded")) == 0)
  441. {
  442. thread_mode = COINIT_APARTMENTTHREADED;
  443. hr = CoInitialize(NULL);
  444. }
  445. else
  446. {
  447. #ifdef MULTI_THREADING
  448. thread_mode = COINIT_MULTITHREADED;
  449. hr = CoInitializeEx(NULL, thread_mode);
  450. #else
  451. hr = E_INVALIDARG;
  452. #endif
  453. }
  454. if (S_OK != hr)
  455. {
  456. HrMsgBox("CoInitialize FAILED", hr);
  457. return(1);
  458. }
  459. // Initialize Application
  460. if (S_OK != tsaMain.InitApp(lpszCmdLine))
  461. {
  462. tsaMain.CloseApp();
  463. return(1);
  464. }
  465. if (tsaMain.GetEmbeddedFlag())
  466. {
  467. // We're running as an embedded app
  468. // Don't show the main window unless we're instructed to do so
  469. // BUGBUG - In-place editing is NYI
  470. ShowWindow(g_hMain, SW_SHOWMINIMIZED);
  471. }
  472. else
  473. {
  474. // We are not running as an embedded app - show the main window
  475. ShowWindow(g_hMain, nCmdShow);
  476. }
  477. UpdateWindow(g_hMain);
  478. // message loop
  479. while (GetMessage(&msg, NULL, 0, 0))
  480. {
  481. TranslateMessage(&msg);
  482. DispatchMessage(&msg);
  483. }
  484. // If we get here, we initialized OLE so let's uninitialize it.
  485. CoUninitialize();
  486. return (msg.wParam); /* Returns the value from PostQuitMessage */
  487. }
  488. //+-------------------------------------------------------------------
  489. //
  490. // Class: CAdvBndCF
  491. //
  492. // Synopsis: Class Factory for CAdvBnd
  493. //
  494. // Interfaces: IUnknown - QueryInterface, AddRef, Release
  495. // IClassFactory - CreateInstance
  496. //
  497. // History: 21-Nov-92 SarahJ Created
  498. //
  499. //--------------------------------------------------------------------
  500. //+-------------------------------------------------------------------
  501. //
  502. // Member: CAdvBndCF::CAdvBndCF()
  503. //
  504. // Synopsis: The constructor for CAdvBnd.
  505. //
  506. // Arguments: None
  507. //
  508. // History: 21-Nov-92 SarahJ Created
  509. //
  510. //--------------------------------------------------------------------
  511. CAdvBndCF::CAdvBndCF() : _cRefs(1)
  512. {
  513. // Load the class object for the class to aggregate.
  514. HRESULT hresult = CoGetClassObject(CLSID_BasicBnd, CLSCTX_SERVER, NULL,
  515. IID_IClassFactory, (void **) &_xifac);
  516. return;
  517. }
  518. //+-------------------------------------------------------------------
  519. //
  520. // Member: CAdvBnd::~CAdvBndObj()
  521. //
  522. // Synopsis: The destructor for CAdvBnd.
  523. //
  524. // History: 21-Nov-92 SarahJ Created
  525. //
  526. //--------------------------------------------------------------------
  527. CAdvBndCF::~CAdvBndCF()
  528. {
  529. return;
  530. }
  531. //+-------------------------------------------------------------------
  532. //
  533. // Method: CAdvBndCF::QueryInterface
  534. //
  535. // Synopsis: Only IUnknown and IClassFactory supported
  536. //
  537. //--------------------------------------------------------------------
  538. STDMETHODIMP CAdvBndCF::QueryInterface(REFIID iid, void FAR * FAR * ppv)
  539. {
  540. if (GuidEqual(iid, IID_IUnknown)
  541. || GuidEqual(iid, IID_IClassFactory))
  542. {
  543. *ppv = (IUnknown *) this;
  544. AddRef();
  545. return S_OK;
  546. }
  547. else
  548. {
  549. *ppv = NULL;
  550. return E_NOINTERFACE;
  551. }
  552. }
  553. STDMETHODIMP_(ULONG) CAdvBndCF::AddRef(void)
  554. {
  555. return(++_cRefs);
  556. }
  557. STDMETHODIMP_(ULONG) CAdvBndCF::Release(void)
  558. {
  559. if (--_cRefs == 0)
  560. {
  561. delete this;
  562. return(0);
  563. }
  564. return _cRefs;
  565. }
  566. //+-------------------------------------------------------------------
  567. //
  568. // Method: CAdvBndCF::CreateInstance
  569. //
  570. // Synopsis: This is called by Binding process to create the
  571. // actual class object
  572. //
  573. //--------------------------------------------------------------------
  574. STDMETHODIMP CAdvBndCF::CreateInstance(
  575. IUnknown FAR* pUnkOuter,
  576. REFIID iidInterface,
  577. void FAR* FAR* ppv)
  578. {
  579. Display(TEXT("CAdvBndCF::CreateInstance called\n"));
  580. if (pUnkOuter != NULL)
  581. {
  582. return E_FAIL;
  583. }
  584. CAdvBnd * lpcBB = new FAR CAdvBnd((IClassFactory *) _xifac);
  585. if (lpcBB == NULL)
  586. {
  587. return E_OUTOFMEMORY;
  588. }
  589. HRESULT hresult = lpcBB->QueryInterface(iidInterface, ppv);
  590. lpcBB->Release();
  591. return hresult;
  592. }
  593. STDMETHODIMP CAdvBndCF::LockServer(BOOL fLock)
  594. {
  595. return E_FAIL;
  596. }
  597. //+-------------------------------------------------------------------
  598. //
  599. // Member: CAdvBnd::CAdvBnd()
  600. //
  601. // Synopsis: The constructor for CAdvBnd. I
  602. //
  603. // Arguments: None
  604. //
  605. // History: 21-Nov-92 SarahJ Created
  606. //
  607. //--------------------------------------------------------------------
  608. CAdvBnd::CAdvBnd(IClassFactory *pcfBase) : _xiunk(), _dwRegister(0), _cRefs(1)
  609. {
  610. HRESULT hresult = pcfBase->CreateInstance((IUnknown *) this, IID_IUnknown,
  611. (void **) &_xiunk);
  612. tsaMain.IncEmbeddedCount();
  613. return;
  614. }
  615. //+-------------------------------------------------------------------
  616. //
  617. // Member: CAdvBnd::~CAdvBndObj()
  618. //
  619. // Synopsis: The destructor for CAdvBnd.
  620. //
  621. // History: 21-Nov-92 SarahJ Created
  622. //
  623. //--------------------------------------------------------------------
  624. CAdvBnd::~CAdvBnd()
  625. {
  626. Display(TEXT("CAdvBndCF::~CAdvBnd called\n"));
  627. if (_dwRegister != 0)
  628. {
  629. // Get the running object table
  630. IRunningObjectTable *prot;
  631. HRESULT hresult = GetRunningObjectTable(0, &prot);
  632. if (hresult != S_OK)
  633. {
  634. HrMsgBox("CAdvBnd::~CAdvBnd GetRunningObjectTable failed", hresult);
  635. }
  636. else
  637. {
  638. hresult = prot->Revoke(_dwRegister);
  639. if (hresult != S_OK)
  640. {
  641. HrMsgBox("CAdvBnd::~CAdvBnd Revoke failed", hresult);
  642. }
  643. prot->Release();
  644. }
  645. }
  646. tsaMain.DecEmbeddedCount();
  647. return;
  648. }
  649. //+-------------------------------------------------------------------
  650. //
  651. // Member: CAdvBnd::QueryInterface
  652. //
  653. // Returns: SUCCESS_SUCCCESS
  654. //
  655. // History: 21-Nov-92 SarahJ Created
  656. //
  657. //--------------------------------------------------------------------
  658. STDMETHODIMP CAdvBnd::QueryInterface(REFIID iid, void ** ppunk)
  659. {
  660. Display(TEXT("CAdvBnd::QueryInterface called\n"));
  661. if (GuidEqual(iid, IID_IUnknown))
  662. {
  663. *ppunk = (IUnknown *) this;
  664. AddRef();
  665. return S_OK;
  666. }
  667. else if ((GuidEqual(iid, IID_IPersistFile))
  668. || (GuidEqual(iid, IID_IPersist)))
  669. {
  670. *ppunk = (IPersistFile *) this;
  671. AddRef();
  672. return S_OK;
  673. }
  674. return _xiunk->QueryInterface(iid, ppunk);
  675. }
  676. STDMETHODIMP_(ULONG) CAdvBnd::AddRef(void)
  677. {
  678. return ++_cRefs;
  679. }
  680. STDMETHODIMP_(ULONG) CAdvBnd::Release(void)
  681. {
  682. if (--_cRefs == 0)
  683. {
  684. delete this;
  685. return(0);
  686. }
  687. return _cRefs;
  688. }
  689. //+-------------------------------------------------------------------
  690. //
  691. // Member: CAdvBnd::Load
  692. //
  693. // Synopsis: IPeristFile interface - needed 'cause we bind with
  694. // file moniker and BindToObject insists on calling this
  695. //
  696. // History: 21-Nov-92 SarahJ Created
  697. //
  698. //--------------------------------------------------------------------
  699. STDMETHODIMP CAdvBnd::Load(LPCWSTR lpszFileName, DWORD grfMode)
  700. {
  701. Display(TEXT("CAdvBndCF::Load called\n"));
  702. // Forward call to delegated class
  703. IPersistFile *pipfile;
  704. HRESULT hresult = _xiunk->QueryInterface(IID_IPersistFile,
  705. (void **) &pipfile);
  706. hresult = pipfile->Load(lpszFileName, grfMode);
  707. pipfile->Release();
  708. if (FAILED(hresult))
  709. {
  710. // Make sure delegated too class liked what it got/
  711. // BUGBUG: Can't just forward hresults!
  712. return hresult;
  713. }
  714. // Create a file moniker
  715. IMoniker *pmk;
  716. hresult = CreateFileMoniker((LPWSTR)lpszFileName, &pmk);
  717. if (FAILED(hresult))
  718. {
  719. HrMsgBox("CAdvBnd::Load CreateFileMoniker failed", hresult);
  720. return hresult;
  721. }
  722. // Get the running object table
  723. IRunningObjectTable *prot;
  724. hresult = GetRunningObjectTable(0, &prot);
  725. if (FAILED(hresult))
  726. {
  727. HrMsgBox("CAdvBnd::Load GetRunningObjectTable failed", hresult);
  728. return hresult;
  729. }
  730. // Register in the running object table
  731. IUnknown *punk;
  732. QueryInterface(IID_IUnknown, (void **) &punk);
  733. hresult = prot->Register(0, punk, pmk, &_dwRegister);
  734. if (FAILED(hresult))
  735. {
  736. HrMsgBox("CAdvBnd::Load Register failed", hresult);
  737. return hresult;
  738. }
  739. // Set filetime to known value
  740. FILETIME filetime;
  741. memset(&filetime, 'B', sizeof(filetime));
  742. // Set time to some known value
  743. prot->NoteChangeTime(_dwRegister, &filetime);
  744. // Release uneeded objects
  745. pmk->Release();
  746. prot->Release();
  747. punk->Release();
  748. return S_OK;
  749. }
  750. //+-------------------------------------------------------------------
  751. //
  752. // Member: CAdvBnd::Save
  753. //
  754. // Synopsis: IPeristFile interface - save
  755. // does little but here for commentry
  756. //
  757. // History: 21-Nov-92 SarahJ Created
  758. //
  759. //--------------------------------------------------------------------
  760. STDMETHODIMP CAdvBnd::Save(LPCWSTR lpszFileName, BOOL fRemember)
  761. {
  762. Display(TEXT("CAdvBndCF::Save called\n"));
  763. // Forward call to delegated class
  764. IPersistFile *pipfile;
  765. HRESULT hresult = _xiunk->QueryInterface(IID_IPersistFile,
  766. (void **) &pipfile);
  767. hresult = pipfile->Save(lpszFileName, fRemember);
  768. pipfile->Release();
  769. return hresult;
  770. }
  771. //+-------------------------------------------------------------------
  772. //
  773. // Member: CAdvBnd::SaveCpmpleted
  774. // CAdvBnd::GetCurFile
  775. // CAdvBnd::IsDirty
  776. //
  777. // Synopsis: More IPeristFile interface methods
  778. //
  779. // History: 21-Nov-92 SarahJ Created
  780. //
  781. //--------------------------------------------------------------------
  782. STDMETHODIMP CAdvBnd::SaveCompleted(LPCWSTR lpszFileName)
  783. {
  784. Display(TEXT("CAdvBndCF::SaveCompleted called\n"));
  785. // Forward call to delegated class
  786. IPersistFile *pipfile;
  787. HRESULT hresult = _xiunk->QueryInterface(IID_IPersistFile,
  788. (void **) &pipfile);
  789. hresult = pipfile->SaveCompleted(lpszFileName);
  790. pipfile->Release();
  791. return hresult;
  792. }
  793. STDMETHODIMP CAdvBnd::GetCurFile(LPWSTR FAR *lpszFileName)
  794. {
  795. Display(TEXT("CAdvBndCF::GetCurFile called\n"));
  796. // Forward call to delegated class
  797. IPersistFile *pipfile;
  798. HRESULT hresult = _xiunk->QueryInterface(IID_IPersistFile,
  799. (void **) &pipfile);
  800. hresult = pipfile->GetCurFile(lpszFileName);
  801. pipfile->Release();
  802. return hresult;
  803. }
  804. STDMETHODIMP CAdvBnd::IsDirty()
  805. {
  806. Display(TEXT("CAdvBndCF::IsDirty called\n"));
  807. // Forward call to delegated class
  808. IPersistFile *pipfile;
  809. HRESULT hresult = _xiunk->QueryInterface(IID_IPersistFile,
  810. (void **) &pipfile);
  811. hresult = pipfile->IsDirty();
  812. pipfile->Release();
  813. return hresult;
  814. }
  815. //+-------------------------------------------------------------------
  816. //
  817. // Interface: IPersist
  818. //
  819. // Synopsis: IPersist interface methods
  820. // Need to return a valid class id here
  821. //
  822. // History: 21-Nov-92 SarahJ Created
  823. //
  824. STDMETHODIMP CAdvBnd::GetClassID(LPCLSID classid)
  825. {
  826. Display(TEXT("CAdvBndCF::GetClassID called\n"));
  827. *classid = CLSID_AdvBnd;
  828. return S_OK;
  829. }