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.

741 lines
26 KiB

  1. #include "privcpp.h"
  2. HWND g_hTaskWnd;
  3. BOOL CALLBACK GetTaskWndProc(HWND hwnd, DWORD lParam);
  4. DWORD CALLBACK MainWaitOnChildThreadProc(void *lpv);
  5. typedef struct {
  6. CPackage_IOleObject *pObj;
  7. HANDLE h;
  8. } MAINWAITONCHILD;
  9. CPackage_IOleObject::CPackage_IOleObject(CPackage *pPackage) :
  10. _pPackage(pPackage)
  11. {
  12. ASSERT(_cRef == 0);
  13. }
  14. CPackage_IOleObject::~CPackage_IOleObject()
  15. {
  16. DebugMsg(DM_TRACE,"CPackage_IOleObject destroyed with ref count %d",_cRef);
  17. }
  18. //////////////////////////////////
  19. //
  20. // IUnknown Methods...
  21. //
  22. HRESULT CPackage_IOleObject::QueryInterface(REFIID iid, void ** ppv)
  23. {
  24. return _pPackage->QueryInterface(iid,ppv);
  25. }
  26. ULONG CPackage_IOleObject::AddRef(void)
  27. {
  28. _cRef++; // interface ref count for debugging
  29. return _pPackage->AddRef();
  30. }
  31. ULONG CPackage_IOleObject::Release(void)
  32. {
  33. _cRef--; // interface ref count for debugging
  34. return _pPackage->Release();
  35. }
  36. //////////////////////////////////
  37. //
  38. // IOleObject Methods...
  39. //
  40. HRESULT CPackage_IOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)
  41. {
  42. DebugMsg(DM_TRACE, "pack oo - SetClientSite() called.");
  43. if (!pClientSite)
  44. return E_POINTER;
  45. if (_pPackage->_pIOleClientSite != NULL)
  46. _pPackage->_pIOleClientSite->Release();
  47. _pPackage->_pIOleClientSite = pClientSite;
  48. _pPackage->_pIOleClientSite->AddRef();
  49. return S_OK;
  50. }
  51. HRESULT CPackage_IOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)
  52. {
  53. DebugMsg(DM_TRACE, "pack oo - GetClientSite() called.");
  54. if (ppClientSite == NULL)
  55. return E_INVALIDARG;
  56. // Be sure to AddRef the pointer we're giving away.
  57. *ppClientSite = _pPackage->_pIOleClientSite;
  58. _pPackage->_pIOleClientSite->AddRef();
  59. return S_OK;
  60. }
  61. HRESULT CPackage_IOleObject::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
  62. {
  63. DebugMsg(DM_TRACE, "pack oo - SetHostNames() called.");
  64. delete _pPackage->_lpszContainerApp;
  65. if (NULL != (_pPackage->_lpszContainerApp = new OLECHAR[lstrlenW(szContainerApp) + 1]))
  66. {
  67. lstrcpyW(_pPackage->_lpszContainerApp,szContainerApp);
  68. }
  69. delete _pPackage->_lpszContainerObj;
  70. if (NULL != (_pPackage->_lpszContainerObj = new OLECHAR[lstrlenW(szContainerObj) + 1]))
  71. {
  72. lstrcpyW(_pPackage->_lpszContainerObj,szContainerObj);
  73. }
  74. switch(_pPackage->_panetype) {
  75. case PEMBED:
  76. if (_pPackage->_pEmbed->poo)
  77. _pPackage->_pEmbed->poo->SetHostNames(szContainerApp,szContainerObj);
  78. break;
  79. case CMDLINK:
  80. // nothing to do...we're a link to a file, so we don't ever get
  81. // opened and need to be edited or some such thing.
  82. break;
  83. }
  84. return S_OK;
  85. }
  86. HRESULT CPackage_IOleObject::Close(DWORD dwSaveOption)
  87. {
  88. DebugMsg(DM_TRACE, "pack oo - Close() called.");
  89. switch (_pPackage->_panetype) {
  90. case PEMBED:
  91. if (_pPackage->_pEmbed == NULL)
  92. return S_OK;
  93. // tell the server to close, and release our pointer to it
  94. if (_pPackage->_pEmbed->poo) {
  95. _pPackage->_pEmbed->poo->Close(dwSaveOption);
  96. _pPackage->_pEmbed->poo->Unadvise(_pPackage->_dwCookie);
  97. _pPackage->_pEmbed->poo->Release();
  98. _pPackage->_pEmbed->poo = NULL;
  99. }
  100. break;
  101. case CMDLINK:
  102. // again, nothing to do...we shouldn't be getting close
  103. // messages since we're never activated through OLE.
  104. break;
  105. }
  106. if ((dwSaveOption != OLECLOSE_NOSAVE) && (_pPackage->_fIsDirty))
  107. {
  108. _pPackage->_pIOleClientSite->SaveObject();
  109. if (_pPackage->_pIOleAdviseHolder)
  110. _pPackage->_pIOleAdviseHolder->SendOnSave();
  111. }
  112. return S_OK;
  113. }
  114. HRESULT CPackage_IOleObject::SetMoniker(DWORD dwWhichMoniker, LPMONIKER pmk)
  115. {
  116. DebugMsg(DM_TRACE, "pack oo - SetMoniker() called.");
  117. // NOTE: Uninteresting for embeddings only.
  118. return (E_NOTIMPL);
  119. }
  120. HRESULT CPackage_IOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,
  121. LPMONIKER *ppmk)
  122. {
  123. DebugMsg(DM_TRACE, "pack oo - GetMoniker() called.");
  124. // NOTE: Unintersting for embeddings only.
  125. return (E_NOTIMPL);
  126. }
  127. HRESULT CPackage_IOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation,
  128. DWORD dwReserved)
  129. {
  130. DebugMsg(DM_TRACE, "pack oo - InitFromData() called.");
  131. // NOTE: This isn't supported at this time
  132. return (E_NOTIMPL);
  133. }
  134. HRESULT CPackage_IOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject)
  135. {
  136. DebugMsg(DM_TRACE, "pack oo - GetClipboardData() called.");
  137. if (ppDataObject == NULL)
  138. return E_INVALIDARG;
  139. *ppDataObject = _pPackage->_pIDataObject;
  140. AddRef();
  141. return S_OK;
  142. }
  143. HRESULT CPackage_IOleObject::DoVerb(LONG iVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite,
  144. LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
  145. {
  146. void *lpFileData = NULL;
  147. BOOL fError = TRUE;
  148. DWORD id;
  149. SHELLEXECUTEINFO sheinf = {sizeof(SHELLEXECUTEINFO)};
  150. DebugMsg(DM_TRACE, "pack oo - DoVerb() called.");
  151. DebugMsg(DM_TRACE, " iVerb==%d",iVerb);
  152. // We allow show, primary verb, edit, and context menu verbs on our packages...
  153. //
  154. if (iVerb < OLEIVERB_SHOW)
  155. return E_NOTIMPL;
  156. /////////////////////////////////////////////////////////////////
  157. // SHOW VERB
  158. /////////////////////////////////////////////////////////////////
  159. //
  160. if (iVerb == OLEIVERB_SHOW) {
  161. PACKAGER_INFO packInfo = {0};
  162. // Run the Wizard...
  163. PackWiz_CreateWizard(hwndParent, &packInfo);
  164. return _pPackage->InitFromPackInfo(&packInfo);
  165. }
  166. /////////////////////////////////////////////////////////////////
  167. // EDIT PACKAGE VERB
  168. /////////////////////////////////////////////////////////////////
  169. //
  170. else if (iVerb == OLEIVERB_EDITPACKAGE) {
  171. // Call the edit package dialog. Which dialog is ultimately called will
  172. // depend on whether we're a cmdline package or an embedded file
  173. // package.
  174. int idDlg;
  175. PACKAGER_INFO packInfo;
  176. int ret;
  177. lstrcpy(packInfo.szLabel,_pPackage->_lpic->szIconText);
  178. lstrcpy(packInfo.szIconPath,_pPackage->_lpic->szIconPath);
  179. packInfo.iIcon = _pPackage->_lpic->iDlgIcon;
  180. switch(_pPackage->_panetype) {
  181. case PEMBED:
  182. lstrcpy(packInfo.szFilename, _pPackage->_pEmbed->fd.cFileName);
  183. idDlg = IDD_EDITEMBEDPACKAGE;
  184. break;
  185. case CMDLINK:
  186. lstrcpy(packInfo.szFilename, _pPackage->_pCml->szCommandLine);
  187. idDlg = IDD_EDITCMDPACKAGE;
  188. break;
  189. }
  190. ret = PackWiz_EditPackage(hwndParent,idDlg, &packInfo);
  191. // If User cancells the edit package...just return.
  192. if (ret == -1)
  193. return S_OK;
  194. switch(_pPackage->_panetype) {
  195. case PEMBED:
  196. // if we have a tempfile, we'll want to delete it
  197. if (_pPackage->_pEmbed->pszTempName) {
  198. DeleteFile(_pPackage->_pEmbed->pszTempName);
  199. delete _pPackage->_pEmbed->pszTempName;
  200. _pPackage->_pEmbed->pszTempName = NULL;
  201. _pPackage->ReleaseContextMenu();
  202. }
  203. // fall through
  204. case CMDLINK:
  205. _pPackage->InitFromPackInfo(&packInfo);
  206. break;
  207. }
  208. return S_OK;
  209. }
  210. else if (iVerb == OLEIVERB_PRIMARY)
  211. {
  212. /////////////////////////////////////////////////////////////////
  213. // ACTIVATE CONTENTS VERB
  214. /////////////////////////////////////////////////////////////////
  215. // NOTE: This is kind of crazy looking code, partially because we have
  216. // to worry about two ways of launching things--ShellExecuteEx and
  217. // calling through OLE.
  218. //
  219. switch(_pPackage->_panetype)
  220. {
  221. case PEMBED:
  222. if (FAILED(_pPackage->CreateTempFile())) // will just return S_OK
  223. return E_FAIL; // if we have a temp file
  224. // if this is an OLE file then, activate through OLE
  225. //
  226. if (_pPackage->_pEmbed->fIsOleFile)
  227. {
  228. // If we've activated the server, then we can just pass this
  229. // call along to it.
  230. if (_pPackage->_pEmbed->poo)
  231. {
  232. return _pPackage->_pEmbed->poo->DoVerb(iVerb,lpmsg,
  233. pActiveSite,lindex, hwndParent, lprcPosRect);
  234. }
  235. // We don't want to use OleCreateFromFile since that can turn around and create a packaged object...
  236. CLSID clsid;
  237. HRESULT hr = GetClassFile(_pPackage->_pEmbed->pszTempName, &clsid);
  238. if (SUCCEEDED(hr))
  239. {
  240. IOleObject* poo;
  241. hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IOleObject, (void **)&poo);
  242. if (SUCCEEDED(hr))
  243. {
  244. hr = poo->Advise(_pPackage->_pIAdviseSink, &_pPackage->_dwCookie);
  245. if (SUCCEEDED(hr))
  246. {
  247. // NOTE: apparently we have to call
  248. // OleRun before we can get IPersistFile from some apps, namely
  249. // Word and Excel. If we don't call OleRun, they fail our QI
  250. // for IPersistfile.
  251. OleRun(poo);
  252. IPersistFile* ppf;
  253. hr = poo->QueryInterface(IID_IPersistFile, (void **)&ppf);
  254. if (SUCCEEDED(hr))
  255. {
  256. hr = ppf->Load(_pPackage->_pEmbed->pszTempName, STGM_READWRITE | STGM_SHARE_DENY_WRITE);
  257. if (SUCCEEDED(hr))
  258. {
  259. hr = poo->DoVerb(iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect);
  260. if (SUCCEEDED(hr))
  261. {
  262. poo->SetHostNames(_pPackage->_lpszContainerApp, _pPackage->_lpszContainerObj);
  263. if (!_pPackage->_fNoIOleClientSiteCalls)
  264. {
  265. _pPackage->_pIOleClientSite->ShowObject();
  266. _pPackage->_pIOleClientSite->OnShowWindow(TRUE);
  267. }
  268. _pPackage->_pEmbed->poo = poo; // save this so when we get a
  269. poo = NULL;
  270. }
  271. }
  272. ppf->Release();
  273. }
  274. if (FAILED(hr))
  275. poo->Unadvise(_pPackage->_dwCookie);
  276. }
  277. if (FAILED(hr))
  278. poo->Release();
  279. }
  280. }
  281. if (SUCCEEDED(hr))
  282. return hr;
  283. // We weren't an OLE file after all, change our state to reflect this
  284. _pPackage->_pEmbed->fIsOleFile = FALSE;
  285. _pPackage->_fIsDirty = TRUE;
  286. }
  287. // Try to execute the file
  288. _pPackage->_pEmbed->hTask = NULL;
  289. sheinf.fMask = SEE_MASK_NOCLOSEPROCESS;
  290. sheinf.lpFile = _pPackage->_pEmbed->pszTempName;
  291. sheinf.nShow = SW_SHOWNORMAL;
  292. if (ShellExecuteEx(&sheinf))
  293. {
  294. // if we get a valid process handle, we want to create a thread
  295. // to wait for the process to exit so we know when we can load
  296. // the tempfile back into memory.
  297. //
  298. if (sheinf.hProcess)
  299. {
  300. _pPackage->_pEmbed->hTask = sheinf.hProcess;
  301. MAINWAITONCHILD *pmwoc = new MAINWAITONCHILD;
  302. if (pmwoc)
  303. {
  304. pmwoc->pObj = this;
  305. pmwoc->h = sheinf.hProcess;
  306. if (CreateThread(NULL, 0, MainWaitOnChildThreadProc, pmwoc, 0, &id))
  307. fError = FALSE;
  308. else
  309. {
  310. CloseHandle(sheinf.hProcess);
  311. return E_FAIL;
  312. }
  313. }
  314. }
  315. // NOTE: there's not much we can do if the ShellExecute
  316. // succeeds and we don't get a valid handle back. we'll just
  317. // load from the temp file when we're asked to save and hope
  318. // for the best.
  319. }
  320. else // ShellExecuteEx failed!
  321. {
  322. return E_FAIL;
  323. }
  324. // show that the object is now active
  325. if (!fError && !_pPackage->_fNoIOleClientSiteCalls)
  326. {
  327. _pPackage->_pIOleClientSite->ShowObject();
  328. _pPackage->_pIOleClientSite->OnShowWindow(TRUE);
  329. }
  330. return fError ? E_FAIL : S_OK;
  331. case CMDLINK:
  332. {
  333. TCHAR szPath[MAX_PATH];
  334. TCHAR szArgs[CBCMDLINKMAX-MAX_PATH];
  335. lstrcpy(szPath, _pPackage->_pCml->szCommandLine);
  336. PathSeparateArgs(szPath, szArgs);
  337. sheinf.fMask = SEE_MASK_NOCLOSEPROCESS;
  338. sheinf.lpFile = szPath;
  339. sheinf.lpParameters = szArgs;
  340. sheinf.nShow = SW_SHOWNORMAL;
  341. // NOTE: This code is much nicer than ShellExec-ing an embedded
  342. // file. Here, we just need to ShellExec the command line and
  343. // the we're done. We don't need to know when that process
  344. // finishes or anything else.
  345. return ShellExecuteEx(&sheinf)? S_OK:E_FAIL;
  346. }
  347. break;
  348. case PACKAGE:
  349. {
  350. PACKAGER_INFO packInfo = {0};
  351. ASSERT(_pPackage->_pCml);
  352. lstrcpyn(packInfo.szFilename, _pPackage->_pCml->szCommandLine, ARRAYSIZE(packInfo.szFilename));
  353. // Run the Wizard...
  354. PackWiz_CreateWizard(hwndParent, &packInfo);
  355. return _pPackage->InitFromPackInfo(&packInfo);
  356. }
  357. break;
  358. }
  359. }
  360. else
  361. {
  362. // Let's see if it is a context menu verb:
  363. HRESULT hr;
  364. IContextMenu* pcm;
  365. if (SUCCEEDED(hr = _pPackage->GetContextMenu(&pcm)))
  366. {
  367. HMENU hmenu = CreatePopupMenu();
  368. if (NULL != hmenu)
  369. {
  370. if (SUCCEEDED(hr = pcm->QueryContextMenu(hmenu,
  371. 0,
  372. OLEIVERB_FIRST_CONTEXT,
  373. OLEIVERB_LAST_CONTEXT,
  374. CMF_NORMAL)))
  375. {
  376. MENUITEMINFO mii;
  377. mii.cbSize = sizeof(mii);
  378. mii.fMask = MIIM_ID;
  379. if (GetMenuItemInfo(hmenu, (UINT) (iVerb - OLEIVERB_FIRST_CONTEXT), TRUE, &mii))
  380. {
  381. if (PEMBED == _pPackage->_panetype)
  382. {
  383. // If we have an embedding, we have to make sure that
  384. // the temp file is created before we execute a command:
  385. hr =_pPackage->CreateTempFile();
  386. }
  387. if (SUCCEEDED(hr))
  388. {
  389. CMINVOKECOMMANDINFO ici;
  390. ici.cbSize = sizeof(ici);
  391. ici.fMask = 0;
  392. ici.hwnd = NULL;
  393. ici.lpVerb = (LPCSTR) IntToPtr(mii.wID - OLEIVERB_FIRST_CONTEXT);
  394. ici.lpParameters = NULL;
  395. ici.lpDirectory = NULL;
  396. ici.nShow = SW_SHOWNORMAL;
  397. // REVIEW: should we return OLEOBJ_S_CANNOT_DOVERB_NOW if this fails?
  398. hr = pcm->InvokeCommand(&ici);
  399. }
  400. }
  401. else
  402. {
  403. hr = OLEOBJ_S_CANNOT_DOVERB_NOW;
  404. }
  405. }
  406. DestroyMenu(hmenu);
  407. }
  408. else
  409. {
  410. hr = E_OUTOFMEMORY;
  411. }
  412. pcm->Release();
  413. }
  414. return hr;
  415. }
  416. return E_FAIL;
  417. }
  418. HRESULT CPackage_IOleObject::EnumVerbs(LPENUMOLEVERB *ppEnumOleVerb)
  419. {
  420. DebugMsg(DM_TRACE, "pack oo - EnumVerbs() called.");
  421. HRESULT hr;
  422. IContextMenu* pcm;
  423. // tell the package to release the cached context menu:
  424. _pPackage->ReleaseContextMenu();
  425. if (SUCCEEDED(hr = _pPackage->GetContextMenu(&pcm)))
  426. {
  427. HMENU hmenu = CreatePopupMenu();
  428. if (NULL != hmenu)
  429. {
  430. if (SUCCEEDED(hr = pcm->QueryContextMenu(hmenu,
  431. 0,
  432. OLEIVERB_FIRST_CONTEXT,
  433. OLEIVERB_LAST_CONTEXT,
  434. CMF_NORMAL)))
  435. {
  436. // FEATURE: remove problematic items by canonical names
  437. int nItems = GetMenuItemCount(hmenu);
  438. int cOleVerbs = 0;
  439. if (nItems > 0)
  440. {
  441. // NOTE: we allocate nItems, but we may not use all of them
  442. // FEATURE: add in menu items from the registry: "activate" & "edit"
  443. OLEVERB* pVerbs = new OLEVERB[nItems];
  444. if (NULL != pVerbs)
  445. {
  446. MENUITEMINFO mii;
  447. TCHAR szMenuName[MAX_PATH];
  448. mii.cbSize = sizeof(mii);
  449. mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE | MIIM_ID;
  450. for (int i = 0; i < nItems; i++)
  451. {
  452. mii.dwTypeData = szMenuName;
  453. mii.cch = ARRAYSIZE(szMenuName);
  454. // NOTE: use GetMenuState() to avoid converting flags:
  455. DWORD dwState = GetMenuState(hmenu, i, MF_BYPOSITION);
  456. if (0 == (dwState & (MF_BITMAP | MF_OWNERDRAW | MF_POPUP)))
  457. {
  458. if (GetMenuItemInfo(hmenu, i, TRUE, &mii) && (MFT_STRING == mii.fType))
  459. {
  460. TCHAR szVerb[MAX_PATH];
  461. if (FAILED(pcm->GetCommandString(mii.wID - OLEIVERB_FIRST_CONTEXT,
  462. GCS_VERB,
  463. NULL,
  464. (LPSTR) szVerb,
  465. ARRAYSIZE(szVerb))))
  466. {
  467. // Some commands don't have canonical names - just
  468. // set the verb string to empty
  469. szVerb[0] = TEXT('\0');
  470. }
  471. if ((0 != lstrcmp(szVerb, TEXT("cut"))) &&
  472. (0 != lstrcmp(szVerb, TEXT("delete"))))
  473. {
  474. // In the first design, the context menu ID was used as
  475. // the lVerb - however MFC apps only give us a range of
  476. // 16 ID's and context menu ID's are often over 100
  477. // (they aren't contiguous)
  478. // Instead, we use the menu position plus the verb offset
  479. pVerbs[cOleVerbs].lVerb = (LONG) OLEIVERB_FIRST_CONTEXT + i;
  480. int cchMenu = lstrlen(mii.dwTypeData) + 1;
  481. if (NULL != (pVerbs[cOleVerbs].lpszVerbName = new WCHAR[cchMenu]))
  482. {
  483. SHTCharToUnicode(mii.dwTypeData, pVerbs[cOleVerbs].lpszVerbName, cchMenu);
  484. }
  485. pVerbs[cOleVerbs].fuFlags = dwState;
  486. pVerbs[cOleVerbs].grfAttribs = OLEVERBATTRIB_ONCONTAINERMENU;
  487. DebugMsg(DM_TRACE, " Adding verb: id==%d,name=%s,verb=%s",mii.wID,mii.dwTypeData,szVerb);
  488. cOleVerbs++;
  489. }
  490. }
  491. }
  492. }
  493. if (SUCCEEDED(hr = _pPackage->InitVerbEnum(pVerbs, cOleVerbs)))
  494. {
  495. hr = _pPackage->QueryInterface(IID_IEnumOLEVERB, (void**) ppEnumOleVerb);
  496. }
  497. else
  498. {
  499. delete pVerbs;
  500. }
  501. }
  502. else
  503. {
  504. hr = E_OUTOFMEMORY;
  505. }
  506. }
  507. else
  508. {
  509. hr = OLEOBJ_E_NOVERBS;
  510. }
  511. }
  512. DestroyMenu(hmenu);
  513. }
  514. else
  515. {
  516. hr = E_OUTOFMEMORY;
  517. }
  518. pcm->Release();
  519. }
  520. return hr; // OleRegEnumVerbs(CLSID_CPackage, ppEnumOleVerb);
  521. }
  522. HRESULT CPackage_IOleObject::Update(void)
  523. {
  524. return S_OK;
  525. }
  526. HRESULT CPackage_IOleObject::IsUpToDate(void)
  527. {
  528. return S_OK;
  529. }
  530. HRESULT CPackage_IOleObject::GetUserClassID(LPCLSID pClsid)
  531. {
  532. *pClsid = CLSID_CPackage;
  533. return S_OK;
  534. }
  535. HRESULT CPackage_IOleObject::GetUserType(DWORD dwFromOfType, LPOLESTR *pszUserType)
  536. {
  537. return OleRegGetUserType(CLSID_CPackage, dwFromOfType, pszUserType);
  538. }
  539. HRESULT CPackage_IOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  540. {
  541. return E_FAIL;
  542. }
  543. HRESULT CPackage_IOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  544. {
  545. return _pPackage->_pIViewObject2->GetExtent(dwDrawAspect,-1,NULL,psizel);
  546. }
  547. HRESULT CPackage_IOleObject::Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection)
  548. {
  549. if (_pPackage->_pIOleAdviseHolder == NULL)
  550. {
  551. HRESULT hr = CreateOleAdviseHolder(&_pPackage->_pIOleAdviseHolder);
  552. if (FAILED(hr))
  553. return hr;
  554. }
  555. return _pPackage->_pIOleAdviseHolder->Advise(pAdvSink, pdwConnection);
  556. }
  557. HRESULT CPackage_IOleObject::Unadvise(DWORD dwConnection)
  558. {
  559. DebugMsg(DM_TRACE, "pack oo - Unadvise() called.");
  560. if (_pPackage->_pIOleAdviseHolder != NULL)
  561. return _pPackage->_pIOleAdviseHolder->Unadvise(dwConnection);
  562. return E_FAIL;
  563. }
  564. HRESULT CPackage_IOleObject::EnumAdvise(LPENUMSTATDATA *ppenumAdvise)
  565. {
  566. DebugMsg(DM_TRACE, "pack oo - EnumAdvise() called.");
  567. if (_pPackage->_pIOleAdviseHolder != NULL)
  568. return _pPackage->_pIOleAdviseHolder->EnumAdvise(ppenumAdvise);
  569. return E_FAIL;
  570. }
  571. HRESULT CPackage_IOleObject::GetMiscStatus(DWORD dwAspect, LPDWORD pdwStatus)
  572. {
  573. return OleRegGetMiscStatus(CLSID_CPackage, dwAspect, pdwStatus);
  574. }
  575. HRESULT CPackage_IOleObject::SetColorScheme(LPLOGPALETTE pLogpal)
  576. {
  577. return E_NOTIMPL;
  578. }
  579. DWORD CALLBACK MainWaitOnChildThreadProc(void *lpv)
  580. {
  581. INT ret;
  582. MAINWAITONCHILD *pmwoc = (MAINWAITONCHILD *)lpv;
  583. CPackage *pPack = pmwoc->pObj->_pPackage;
  584. DebugMsg(DM_TRACE, "pack oo - MainWaitOnChildThreadProc() called.");
  585. DebugMsg(DM_TRACE, " handle = %d",(DWORD_PTR)lpv);
  586. ret = WaitForSingleObject(pmwoc->h, INFINITE);
  587. DebugMsg(DM_TRACE,"WaitForSingObject exits...ret==%d",ret);
  588. if (ret == -1)
  589. DebugMsg(DM_TRACE,"GetLastError==%d",GetLastError());
  590. CloseHandle(pmwoc->h);
  591. // BUGBUG: NONE OF THE BELOW CALLS ARE THREAD-SAFE!!!
  592. // this will set our dirty flag...
  593. if (FAILED(pPack->EmbedInitFromFile(pPack->_pEmbed->pszTempName,FALSE)))
  594. {
  595. ShellMessageBox(g_hinst,
  596. NULL,
  597. MAKEINTRESOURCE(IDS_UPDATE_ERROR),
  598. MAKEINTRESOURCE(IDS_APP_TITLE),
  599. MB_ICONERROR | MB_TASKMODAL | MB_OK);
  600. }
  601. pPack->_pIOleClientSite->SaveObject();
  602. if (pPack->_pIOleAdviseHolder)
  603. {
  604. pPack->_pIOleAdviseHolder->SendOnSave();
  605. pPack->_pIOleAdviseHolder->SendOnClose();
  606. }
  607. if (pPack->_pIOleClientSite && !pPack->_fNoIOleClientSiteCalls)
  608. pPack->_pIOleClientSite->OnShowWindow(FALSE);
  609. pPack->_pEmbed->hTask = NULL;
  610. // NOTE: we should probably pop up some sort of message box here if we
  611. // can't reinit from the temp file.
  612. DebugMsg(DM_TRACE, " MainWaitOnChildThreadProc exiting.");
  613. delete pmwoc;
  614. return 0;
  615. }
  616. BOOL CALLBACK GetTaskWndProc(HWND hwnd, DWORD lParam)
  617. {
  618. DebugMsg(DM_TRACE, "pack oo - GetTaskWndProc() called.");
  619. if (IsWindowVisible(hwnd))
  620. {
  621. g_hTaskWnd = hwnd;
  622. return FALSE;
  623. }
  624. return TRUE;
  625. }