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.

2594 lines
68 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: LEDDE.C
  3. *
  4. * Purpose: ?????
  5. *
  6. * Created: 1990
  7. *
  8. * Copyright (c) 1990, 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * Raor, Srinik (../../1990,91) Designed and coded
  12. *
  13. \***************************************************************************/
  14. #include <windows.h>
  15. #include "dde.h"
  16. #include "dll.h"
  17. #define LN_FUDGE 16 // [],(), 3 * 3 (2 double quotes and comma)
  18. #define RUNITEM
  19. #define OLEVERB_CONNECT 0xFFFF
  20. // Definitions for sending the server sys command.
  21. char *srvrSysCmd[] = {"StdNewFromTemplate",
  22. "StdNewDocument",
  23. "StdEditDocument",
  24. "StdOpenDocument"
  25. };
  26. #define EMB_ID_INDEX 11 // index of ones digit in #00
  27. extern char embStr[];
  28. extern BOOL gbCreateInvisible;
  29. extern BOOL gbLaunchServer;
  30. extern ATOM aMSDraw;
  31. extern BOOL (FAR PASCAL *lpfnIsTask) (HANDLE);
  32. // !!! set error hints
  33. OLESTATUS FARINTERNAL LeDoVerb (lpobj, verb, fShow, fActivate)
  34. LPOBJECT_LE lpobj;
  35. WORD verb;
  36. BOOL fShow;
  37. BOOL fActivate;
  38. {
  39. PROBE_ASYNC (lpobj);
  40. PROBE_SVRCLOSING(lpobj);
  41. if (!QueryOpen(lpobj))
  42. return OLE_OK;
  43. lpobj->verb = verb;
  44. lpobj->fCmd = ACT_DOVERB;
  45. if (fActivate)
  46. lpobj->fCmd |= ACT_ACTIVATE;
  47. if (fShow)
  48. lpobj->fCmd |= ACT_SHOW;
  49. InitAsyncCmd (lpobj, OLE_RUN, DOCSHOW);
  50. return DocShow (lpobj);
  51. }
  52. OLESTATUS FARINTERNAL LeShow (lpobj, fActivate)
  53. LPOBJECT_LE lpobj;
  54. BOOL fActivate;
  55. {
  56. PROBE_ASYNC (lpobj);
  57. PROBE_SVRCLOSING(lpobj);
  58. if (!QueryOpen(lpobj))
  59. return OLE_OK;
  60. lpobj->fCmd = ACT_SHOW;
  61. InitAsyncCmd (lpobj, OLE_SHOW, DOCSHOW);
  62. return DocShow (lpobj);
  63. }
  64. // DocShow : If the server is connected, show the item
  65. // for editing. For embedded objects us NULL Item.
  66. OLESTATUS DocShow (lpobj)
  67. LPOBJECT_LE lpobj;
  68. {
  69. switch (lpobj->subRtn) {
  70. case 0:
  71. SendStdShow (lpobj);
  72. WAIT_FOR_ASYNC_MSG (lpobj);
  73. case 1:
  74. ProcessErr (lpobj);
  75. return EndAsyncCmd (lpobj);
  76. default:
  77. DEBUG_OUT ("Unexpected subroutine", 0);
  78. return OLE_ERROR_GENERIC;
  79. }
  80. }
  81. void SendStdShow (lpobj)
  82. LPOBJECT_LE lpobj;
  83. {
  84. WORD len;
  85. WORD size;
  86. LPSTR lpdata = NULL;
  87. HANDLE hdata = NULL;
  88. BOOL bShow;
  89. lpobj->subErr = OLE_OK;
  90. if (lpobj->verb == OLEVERB_CONNECT) {
  91. lpobj->verb = NULL;
  92. return;
  93. }
  94. if (!(lpobj->fCmd & (ACT_SHOW | ACT_DOVERB)))
  95. return;
  96. if (bShow = (!lpobj->bOleServer || !(lpobj->fCmd & ACT_DOVERB))) {
  97. // show is off, do not show the server.
  98. if (!(lpobj->fCmd & ACT_SHOW))
  99. return;
  100. SETERRHINT(lpobj, OLE_ERROR_SHOW);
  101. // and 18 "[StdShowItem(\"")for 5 extra for ",FALSE
  102. len = 18 + 7;
  103. } else {
  104. // 19 for the string [StdDoVerbItem(\"") and
  105. // 18 extra is for ",000,FALSE,FALSE
  106. SETERRHINT(lpobj, OLE_ERROR_DOVERB);
  107. len = 19 + 18;
  108. }
  109. len += GlobalGetAtomLen (lpobj->item);
  110. len += 4; // ")]" + NULL
  111. hdata = GlobalAlloc (GMEM_DDESHARE, size = len);
  112. if (hdata == NULL || (lpdata = (LPSTR)GlobalLock (hdata)) == NULL)
  113. goto errRtn;
  114. if (bShow)
  115. lstrcpy (lpdata, "[StdShowItem(\"");
  116. else
  117. lstrcpy (lpdata, "[StdDoVerbItem(\"");
  118. len = lstrlen (lpdata);
  119. if (lpobj->item)
  120. GlobalGetAtomName (lpobj->item , lpdata + len, size - len);
  121. if (!bShow) {
  122. lstrcat (lpdata, (LPSTR)"\",");
  123. // assume that the number of verbs are < 10
  124. len = lstrlen (lpdata);
  125. #ifdef FIREWALLS
  126. ASSERT ( (lpobj->verb & 0x000f) < 9 , "Verb value more than 9");
  127. #endif
  128. lpdata += len;
  129. *lpdata++ = (char)((lpobj->verb & 0x000f) + '0');
  130. *lpdata = 0;
  131. if (lpobj->fCmd & ACT_SHOW)
  132. lstrcat (lpdata, (LPSTR) ",TRUE");
  133. else
  134. lstrcat (lpdata, (LPSTR) ",FALSE");
  135. // StdVerbItem (item, verb, TRUE
  136. // add TRUE/FALSE constant for the activate
  137. if (!(lpobj->fCmd & ACT_ACTIVATE))
  138. lstrcat (lpdata, (LPSTR) ",TRUE)]");
  139. else
  140. lstrcat (lpdata, (LPSTR) ",FALSE)]");
  141. // [StdDoVerb ("item", verb, FALSE, FALSE)]
  142. } else
  143. lstrcat (lpdata, (LPSTR)"\")]");
  144. // apps like excel and wingraph do not suuport activate at
  145. // item level.
  146. GlobalUnlock (hdata);
  147. DocExecute (lpobj, hdata);
  148. return;
  149. errRtn:
  150. if (lpdata)
  151. GlobalUnlock (hdata);
  152. if (hdata)
  153. GlobalFree (hdata);
  154. lpobj->subErr = OLE_ERROR_MEMORY;
  155. return;
  156. }
  157. OLESTATUS FARINTERNAL LeQueryOpen (LPOBJECT_LE lpobj)
  158. {
  159. if (QueryOpen(lpobj))
  160. return OLE_OK;
  161. else
  162. return OLE_ERROR_NOT_OPEN;
  163. }
  164. BOOL INTERNAL QueryOpen (LPOBJECT_LE lpobj)
  165. {
  166. if (lpobj->pDocEdit && lpobj->pDocEdit->hClient) {
  167. if (IsServerValid (lpobj))
  168. return TRUE;
  169. // destroy the windows and pretend as if the server was never
  170. // connected.
  171. DestroyWindow (lpobj->pDocEdit->hClient);
  172. if (lpobj->pSysEdit && lpobj->pSysEdit->hClient)
  173. DestroyWindow (lpobj->pSysEdit->hClient);
  174. }
  175. return FALSE;
  176. }
  177. OLESTATUS FARINTERNAL LeActivate (lpobj, verb, fShow, fActivate, hWnd, lprc)
  178. LPOBJECT_LE lpobj;
  179. WORD verb;
  180. BOOL fShow;
  181. BOOL fActivate;
  182. HWND hWnd;
  183. LPRECT lprc;
  184. {
  185. lpobj->verb = verb;
  186. if (lpobj->head.ctype == CT_EMBEDDED)
  187. return EmbOpen (lpobj, fShow, fActivate, hWnd, lprc);
  188. #ifdef FIREWALLS
  189. ASSERT (lpobj->head.ctype == CT_LINK, "unknown object");
  190. #endif
  191. return LnkOpen (lpobj, fShow, fActivate, hWnd, lprc);
  192. }
  193. OLESTATUS FARINTERNAL LeUpdate (lpobj)
  194. LPOBJECT_LE lpobj;
  195. {
  196. if (lpobj->head.ctype == CT_EMBEDDED)
  197. return EmbUpdate (lpobj);
  198. #ifdef FIREWALLS
  199. ASSERT (lpobj->head.ctype == CT_LINK, "unknown object");
  200. #endif
  201. return LnkUpdate (lpobj);
  202. }
  203. OLESTATUS FARINTERNAL EmbOpen (lpobj, fShow, fActivate, hWnd, lprc)
  204. LPOBJECT_LE lpobj;
  205. BOOL fShow;
  206. BOOL fActivate;
  207. HWND hWnd;
  208. LPRECT lprc;
  209. {
  210. PROBE_ASYNC (lpobj);
  211. PROBE_SVRCLOSING(lpobj);
  212. if(QueryOpen (lpobj))
  213. return LeDoVerb (lpobj, lpobj->verb, fShow, fActivate);
  214. // show the window
  215. // advise for data only on close
  216. // and shut down the conv after the advises.
  217. lpobj->fCmd = LN_EMBACT | ACT_DOVERB | ACT_ADVISE | ACT_CLOSE;
  218. if (fActivate)
  219. lpobj->fCmd |= ACT_ACTIVATE;
  220. if (fShow)
  221. lpobj->fCmd |= ACT_SHOW;
  222. InitAsyncCmd (lpobj, OLE_ACTIVATE, EMBOPENUPDATE);
  223. return EmbOpenUpdate (lpobj);
  224. }
  225. /***************************** Public Function ****************************\
  226. * OLESTATUS FARINTERNAL EmbUpdate (lpobj)
  227. *
  228. * This function updates an EMB object. If the server is connected
  229. * simply send a request for the native as well as the display formats.
  230. * If the server is connected, then tries to start the conversationa and
  231. * get the data. If the conversation fails, then load the server and
  232. * start the conversation. The embeded objects may have links in it.
  233. *
  234. * Effects:
  235. *
  236. * History:
  237. * Wrote it.
  238. \***************************************************************************/
  239. OLESTATUS FARINTERNAL EmbUpdate (lpobj)
  240. LPOBJECT_LE lpobj;
  241. {
  242. // if we are loading the server, then definitly unload.
  243. // if the connection is established, then unload if it is
  244. // to be unloaded, when all the previous requests are satisfied.
  245. PROBE_ASYNC (lpobj);
  246. PROBE_SVRCLOSING(lpobj);
  247. lpobj->fCmd = LN_EMBACT | ACT_REQUEST | (QueryOpen(lpobj) ? 0 : ACT_UNLAUNCH);
  248. InitAsyncCmd (lpobj, OLE_UPDATE, EMBOPENUPDATE);
  249. return EmbOpenUpdate (lpobj);
  250. }
  251. OLESTATUS FARINTERNAL EmbOpenUpdate (lpobj)
  252. LPOBJECT_LE lpobj;
  253. {
  254. switch (lpobj->subRtn) {
  255. case 0:
  256. SKIP_TO (QueryOpen(lpobj), step6);
  257. SendSrvrMainCmd (lpobj, lpobj->lptemplate);
  258. lpobj->lptemplate = NULL;
  259. WAIT_FOR_ASYNC_MSG (lpobj);
  260. case 1:
  261. if (ProcessErr (lpobj))
  262. goto errRtn;
  263. // Init doc conversation should set the failure error
  264. if (!InitDocConv (lpobj, !POPUP_NETDLG))
  265. goto errRtn;
  266. // If there is no native data, do not do any poke.
  267. // creates will not have any poke data to start with
  268. SKIP_TO (!(lpobj->hnative), step6);
  269. PokeNativeData (lpobj);
  270. WAIT_FOR_ASYNC_MSG (lpobj);
  271. case 2:
  272. if (ProcessErr (lpobj))
  273. goto errRtn;
  274. // Now poke the hostnames etc stuff.
  275. PokeHostNames (lpobj);
  276. WAIT_FOR_ASYNC_MSG (lpobj);
  277. case 3:
  278. // do not worry about the poke hostname errors
  279. PokeTargetDeviceInfo (lpobj);
  280. WAIT_FOR_ASYNC_MSG (lpobj);
  281. case 4:
  282. PokeDocDimensions (lpobj);
  283. WAIT_FOR_ASYNC_MSG (lpobj);
  284. case 5:
  285. PokeColorScheme (lpobj);
  286. WAIT_FOR_ASYNC_MSG (lpobj);
  287. case 6:
  288. step6:
  289. // wingraph does not accept the doc dimensions
  290. // after sttedit.
  291. CLEAR_STEP_ERROR (lpobj);
  292. SETSTEP (lpobj, 6);
  293. STEP_NOP (lpobj);
  294. // step_nop simply increments the step numebr
  295. // merge the steps later on
  296. case 7:
  297. if (ProcessErr (lpobj))
  298. goto errRtn;
  299. SKIP_TO (!(lpobj->fCmd & ACT_ADVISE), step11);
  300. lpobj->optUpdate = oleupdate_onsave;
  301. lpobj->pDocEdit->nAdviseSave = 0;
  302. AdviseOn (lpobj, cfNative, aSave);
  303. WAIT_FOR_ASYNC_MSG (lpobj);
  304. case 8:
  305. // do not go for errors on /save. Some servers may not support
  306. // this.
  307. CLEAR_STEP_ERROR (lpobj);
  308. AdvisePict (lpobj, aSave);
  309. WAIT_FOR_ASYNC_MSG (lpobj);
  310. case 9:
  311. // do not worry about the error case for save. Ignore them
  312. CLEAR_STEP_ERROR (lpobj);
  313. lpobj->optUpdate = oleupdate_onclose;
  314. lpobj->pDocEdit->nAdviseClose = 0;
  315. AdviseOn (lpobj, cfNative, aClose);
  316. WAIT_FOR_ASYNC_MSG (lpobj);
  317. case 10:
  318. if (ProcessErr(lpobj))
  319. goto errRtn;
  320. AdvisePict (lpobj, aClose);
  321. WAIT_FOR_ASYNC_MSG (lpobj);
  322. case 11:
  323. step11:
  324. SETSTEP (lpobj, 11);
  325. if (ProcessErr(lpobj))
  326. goto errRtn;
  327. SKIP_TO (!(lpobj->fCmd & ACT_REQUEST), step13);
  328. // we don't want to send OLE_CHANGED when we get this data, if we
  329. // are going to request for picture data also.
  330. lpobj->pDocEdit->bCallLater = ((lpobj->lpobjPict) ? TRUE: FALSE);
  331. RequestOn (lpobj, cfNative);
  332. WAIT_FOR_ASYNC_MSG (lpobj);
  333. // If request pict fails, then native and pict are
  334. // not in sync.
  335. case 12:
  336. if (ProcessErr(lpobj))
  337. goto errRtn;
  338. lpobj->pDocEdit->bCallLater = FALSE;
  339. RequestPict (lpobj);
  340. WAIT_FOR_ASYNC_MSG (lpobj);
  341. case 13:
  342. step13:
  343. SETSTEP(lpobj, 13);
  344. if (ProcessErr(lpobj))
  345. goto errRtn;
  346. SendStdShow (lpobj);
  347. WAIT_FOR_ASYNC_MSG (lpobj);
  348. case 14:
  349. if (ProcessErr(lpobj))
  350. goto errRtn;
  351. SKIP_TO ((lpobj->fCmd & ACT_UNLAUNCH), step15);
  352. return EndAsyncCmd (lpobj);
  353. case 15:
  354. errRtn:
  355. step15:
  356. ProcessErr (lpobj);
  357. if ((lpobj->asyncCmd == OLE_UPDATE)
  358. && (!(lpobj->fCmd & ACT_UNLAUNCH)))
  359. return EndAsyncCmd (lpobj);
  360. // if we launched and error, unlaunch (send stdexit)
  361. NextAsyncCmd (lpobj, EMBLNKDELETE);
  362. lpobj->fCmd |= ACT_UNLAUNCH;
  363. EmbLnkDelete (lpobj);
  364. return lpobj->mainErr;
  365. default:
  366. DEBUG_OUT ("Unexpected subroutine", 0);
  367. return OLE_ERROR_GENERIC;
  368. }
  369. }
  370. OLESTATUS FARINTERNAL LnkOpen (lpobj, fShow, fActivate, hWnd, lprc)
  371. LPOBJECT_LE lpobj;
  372. BOOL fShow;
  373. BOOL fActivate;
  374. HWND hWnd;
  375. LPRECT lprc;
  376. {
  377. PROBE_ASYNC (lpobj);
  378. PROBE_SVRCLOSING(lpobj);
  379. if(QueryOpen (lpobj))
  380. return LeDoVerb (lpobj, lpobj->verb, fShow, fActivate);
  381. // Just end the system conversation. we are not unloading
  382. // this instance at all.
  383. lpobj->fCmd = LN_LNKACT | ACT_DOVERB;
  384. if (lpobj->optUpdate == oleupdate_always)
  385. lpobj->fCmd |= ACT_ADVISE | ACT_REQUEST;
  386. else if (lpobj->optUpdate == oleupdate_onsave)
  387. lpobj->fCmd |= ACT_ADVISE;
  388. if (fActivate)
  389. lpobj->fCmd |= ACT_ACTIVATE;
  390. if (fShow)
  391. lpobj->fCmd |= ACT_SHOW;
  392. InitAsyncCmd (lpobj, OLE_ACTIVATE, LNKOPENUPDATE);
  393. return LnkOpenUpdate (lpobj);
  394. }
  395. OLESTATUS FARINTERNAL LnkUpdate (lpobj)
  396. LPOBJECT_LE lpobj;
  397. {
  398. // if we are loading the server, then definitly unload.
  399. // if the connection is established, then unload if it is
  400. // to be unloaded, when all the previous requests are satisfied.
  401. PROBE_ASYNC (lpobj);
  402. PROBE_SVRCLOSING(lpobj);
  403. lpobj->fCmd = LN_LNKACT | ACT_REQUEST | (QueryOpen (lpobj) ? 0 : ACT_UNLAUNCH);
  404. InitAsyncCmd (lpobj, OLE_UPDATE, LNKOPENUPDATE);
  405. return LnkOpenUpdate (lpobj);
  406. }
  407. OLESTATUS FARINTERNAL LnkOpenUpdate (lpobj)
  408. LPOBJECT_LE lpobj;
  409. {
  410. switch (lpobj->subRtn) {
  411. case 0:
  412. SKIP_TO (QueryOpen(lpobj), step2);
  413. InitDocConv (lpobj, !POPUP_NETDLG);
  414. if (QueryOpen(lpobj)) {
  415. if (lpobj->app == aPackage)
  416. RemoveLinkStringFromTopic (lpobj);
  417. goto step2;
  418. }
  419. SendSrvrMainCmd (lpobj, NULL);
  420. WAIT_FOR_ASYNC_MSG (lpobj);
  421. case 1:
  422. if (ProcessErr (lpobj))
  423. goto errRtn;
  424. if (lpobj->app == aPackage)
  425. RemoveLinkStringFromTopic (lpobj);
  426. if (!InitDocConv (lpobj, POPUP_NETDLG)) {
  427. lpobj->subErr = OLE_ERROR_OPEN;
  428. goto errRtn;
  429. }
  430. case 2:
  431. step2:
  432. SETSTEP (lpobj, 2);
  433. PokeTargetDeviceInfo (lpobj);
  434. WAIT_FOR_ASYNC_MSG (lpobj);
  435. case 3:
  436. if (ProcessErr (lpobj))
  437. goto errRtn;
  438. SKIP_TO (!(lpobj->fCmd & ACT_ADVISE), step6);
  439. SKIP_TO (!(lpobj->fCmd & ACT_NATIVE), step4);
  440. AdviseOn (lpobj, cfNative, NULL);
  441. WAIT_FOR_ASYNC_MSG (lpobj);
  442. case 4:
  443. step4:
  444. SETSTEP (lpobj, 4);
  445. if (ProcessErr (lpobj))
  446. goto errRtn;
  447. AdvisePict (lpobj, NULL);
  448. WAIT_FOR_ASYNC_MSG (lpobj);
  449. case 5:
  450. if (ProcessErr (lpobj))
  451. goto errRtn;
  452. // Now send advise for renaming the documnet.
  453. AdviseOn (lpobj, cfBinary, aStdDocName);
  454. WAIT_FOR_ASYNC_MSG (lpobj);
  455. case 6:
  456. step6:
  457. // if name advise fails ignore it
  458. SETSTEP (lpobj, 6);
  459. CLEAR_STEP_ERROR (lpobj);
  460. SKIP_TO (!(lpobj->fCmd & ACT_REQUEST), step8);
  461. SKIP_TO (!(lpobj->fCmd & ACT_NATIVE), step7);
  462. // we don't want to send OLE_CHANGED when we get this data, if we
  463. // are going to request for picture data also.
  464. lpobj->pDocEdit->bCallLater = ((lpobj->lpobjPict) ? TRUE: FALSE);
  465. RequestOn (lpobj, cfNative);
  466. WAIT_FOR_ASYNC_MSG (lpobj);
  467. case 7:
  468. step7:
  469. SETSTEP (lpobj, 7);
  470. if (ProcessErr (lpobj))
  471. goto errRtn;
  472. lpobj->pDocEdit->bCallLater = FALSE;
  473. RequestPict (lpobj);
  474. WAIT_FOR_ASYNC_MSG (lpobj);
  475. case 8:
  476. step8:
  477. SETSTEP (lpobj, 8);
  478. if (ProcessErr (lpobj))
  479. goto errRtn;
  480. SKIP_TO (!(lpobj->fCmd & ACT_TERMDOC), step10);
  481. // terminate the document conversataion.
  482. TermDocConv (lpobj);
  483. WAIT_FOR_ASYNC_MSG (lpobj);
  484. case 9:
  485. if (ProcessErr (lpobj))
  486. goto errRtn;
  487. // delete the server edit block
  488. DeleteDocEdit (lpobj);
  489. SKIP_TO ((lpobj->fCmd & ACT_UNLAUNCH), step14);
  490. return EndAsyncCmd (lpobj);
  491. case 10:
  492. step10:
  493. SETSTEP (lpobj, 10);
  494. if (ProcessErr (lpobj))
  495. goto errRtn;
  496. SKIP_TO (!(lpobj->fCmd & ACT_TERMSRVR), step12);
  497. // terminate the server conversataion.
  498. TermSrvrConv (lpobj);
  499. WAIT_FOR_ASYNC_MSG (lpobj);
  500. case 11:
  501. if (ProcessErr (lpobj))
  502. goto errRtn;
  503. // delete the server edit block
  504. DeleteSrvrEdit (lpobj);
  505. return EndAsyncCmd (lpobj);
  506. case 12:
  507. step12:
  508. SETSTEP (lpobj, 12);
  509. if (ProcessErr (lpobj))
  510. goto errRtn;
  511. SendStdShow (lpobj);
  512. WAIT_FOR_ASYNC_MSG (lpobj);
  513. case 13:
  514. if (ProcessErr (lpobj))
  515. goto errRtn;
  516. SKIP_TO ((lpobj->fCmd & ACT_UNLAUNCH), step14);
  517. return EndAsyncCmd (lpobj);
  518. case 14:
  519. errRtn:
  520. step14:
  521. ProcessErr (lpobj);
  522. if ((lpobj->asyncCmd == OLE_UPDATE)
  523. && (!(lpobj->fCmd & ACT_UNLAUNCH)))
  524. return EndAsyncCmd (lpobj);
  525. // if we launched and error, unlaunch (send stdexit)
  526. NextAsyncCmd (lpobj, EMBLNKDELETE);
  527. lpobj->fCmd |= ACT_UNLAUNCH;
  528. EmbLnkDelete (lpobj);
  529. return lpobj->mainErr;
  530. default:
  531. DEBUG_OUT ("Unexpected subroutine", 0);
  532. return OLE_ERROR_GENERIC;
  533. }
  534. }
  535. OLESTATUS EmbLnkClose (lpobj)
  536. LPOBJECT_LE lpobj;
  537. {
  538. switch (lpobj->subRtn) {
  539. case 0:
  540. TermDocConv (lpobj);
  541. WAIT_FOR_ASYNC_MSG (lpobj);
  542. case 1:
  543. // delete the edit block
  544. DeleteDocEdit (lpobj);
  545. TermSrvrConv (lpobj);
  546. WAIT_FOR_ASYNC_MSG (lpobj);
  547. case 2:
  548. // Do not set any errors, just delete the object.
  549. // delete the server edit block
  550. DeleteSrvrEdit (lpobj);
  551. return EndAsyncCmd (lpobj);
  552. default:
  553. DEBUG_OUT ("Unexpected subroutine", 0);
  554. return OLE_ERROR_GENERIC;
  555. }
  556. }
  557. OLESTATUS FARINTERNAL LeClose (lpobj)
  558. LPOBJECT_LE lpobj;
  559. {
  560. PROBE_ASYNC (lpobj);
  561. if (IS_SVRCLOSING(lpobj))
  562. return OLE_OK;
  563. lpobj->fCmd = 0;
  564. if (lpobj->head.ctype == CT_EMBEDDED) {
  565. InitAsyncCmd (lpobj, OLE_CLOSE, EMBLNKDELETE);
  566. return EmbLnkDelete (lpobj);
  567. }
  568. else {
  569. InitAsyncCmd (lpobj, OLE_CLOSE, EMBLNKCLOSE);
  570. return EmbLnkClose (lpobj);
  571. }
  572. }
  573. OLESTATUS FARINTERNAL LeReconnect (lpobj)
  574. LPOBJECT_LE lpobj;
  575. {
  576. // check for the existing conversation.
  577. // if the client window is non-null, then
  578. // connection exits.
  579. if (lpobj->head.ctype != CT_LINK)
  580. return OLE_ERROR_NOT_LINK; // allow only for linked
  581. PROBE_ASYNC (lpobj);
  582. PROBE_SVRCLOSING(lpobj);
  583. if (QueryOpen (lpobj))
  584. return OLE_OK;
  585. // start just the conversation. Do not load
  586. // the app.
  587. if (!InitDocConv (lpobj, !POPUP_NETDLG))
  588. return OLE_OK; // document is not loaded , it is OK.
  589. lpobj->fCmd = LN_LNKACT;
  590. if (lpobj->optUpdate == oleupdate_always)
  591. lpobj->fCmd |= ACT_ADVISE | ACT_REQUEST;
  592. InitAsyncCmd (lpobj, OLE_RECONNECT, LNKOPENUPDATE);
  593. return LnkOpenUpdate (lpobj);
  594. }
  595. OLESTATUS INTERNAL PokeNativeData (lpobj)
  596. LPOBJECT_LE lpobj;
  597. {
  598. SETERRHINT(lpobj, OLE_ERROR_POKE_NATIVE);
  599. return SendPokeData (lpobj,
  600. lpobj->item,
  601. lpobj->hnative,
  602. cfNative);
  603. }
  604. BOOL INTERNAL PostMessageToServer (pedit, msg, lparam)
  605. PEDIT_DDE pedit;
  606. WORD msg;
  607. LONG lparam;
  608. {
  609. #ifdef FIREWALLS
  610. ASSERT (pedit, "Dde edit block is NULL");
  611. #endif
  612. // save the lparam and msg fpr possible reposting incase of error.
  613. // we are in abort state. no messages except for terminate.
  614. if (pedit->bAbort && msg != WM_DDE_TERMINATE)
  615. return FALSE;
  616. pedit->lParam = lparam;
  617. pedit->msg = msg;
  618. if (pedit->hClient && pedit->hServer) {
  619. while (TRUE){
  620. if (!IsWindowValid (pedit->hServer))
  621. return FALSE;
  622. if (PostMessage (pedit->hServer, msg, pedit->hClient, lparam) == FALSE)
  623. Yield ();
  624. else
  625. return TRUE;
  626. }
  627. }
  628. return FALSE;
  629. }
  630. OLESTATUS FARINTERNAL LeCreateFromTemplate (lpclient, lptemplate, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat)
  631. LPOLECLIENT lpclient;
  632. LPSTR lptemplate;
  633. LHCLIENTDOC lhclientdoc;
  634. LPSTR lpobjname;
  635. LPOLEOBJECT FAR * lplpoleobject;
  636. OLEOPT_RENDER optRender;
  637. OLECLIPFORMAT cfFormat;
  638. {
  639. char buf[MAX_STR];
  640. if (!MapExtToClass (lptemplate, (LPSTR)buf, MAX_STR))
  641. return OLE_ERROR_CLASS;
  642. return CreateFromClassOrTemplate (lpclient, (LPSTR) buf, lplpoleobject,
  643. optRender, cfFormat, LN_TEMPLATE, lptemplate,
  644. lhclientdoc, lpobjname);
  645. }
  646. OLESTATUS FARINTERNAL LeCreate (lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat)
  647. LPSTR lpclass;
  648. LPOLECLIENT lpclient;
  649. LHCLIENTDOC lhclientdoc;
  650. LPSTR lpobjname;
  651. LPOLEOBJECT FAR * lplpoleobject;
  652. OLEOPT_RENDER optRender;
  653. OLECLIPFORMAT cfFormat;
  654. {
  655. if (gbCreateInvisible) {
  656. // this is in fact a call for invisible create
  657. return LeCreateInvisible (lpclient, lpclass, lhclientdoc, lpobjname,
  658. lplpoleobject, optRender, cfFormat, gbLaunchServer);
  659. }
  660. return CreateFromClassOrTemplate (lpclient, lpclass, lplpoleobject,
  661. optRender, cfFormat, LN_NEW, NULL,
  662. lhclientdoc, lpobjname);
  663. }
  664. OLESTATUS FARINTERNAL CreateFromClassOrTemplate (lpclient, lpclass, lplpoleobject, optRender, cfFormat, lnType, lptemplate, lhclientdoc, lpobjname)
  665. LPOLECLIENT lpclient;
  666. LPSTR lpclass;
  667. LPOLEOBJECT FAR * lplpoleobject;
  668. OLEOPT_RENDER optRender;
  669. OLECLIPFORMAT cfFormat;
  670. WORD lnType;
  671. LPSTR lptemplate;
  672. LHCLIENTDOC lhclientdoc;
  673. LPSTR lpobjname;
  674. {
  675. OLESTATUS retval = OLE_ERROR_MEMORY;
  676. LPOBJECT_LE lpobj = NULL;
  677. ATOM aServer;
  678. char chVerb [2];
  679. if (!(aServer = GetAppAtom (lpclass)))
  680. return OLE_ERROR_CLASS;
  681. if(!(lpobj = LeCreateBlank (lhclientdoc, lpobjname, CT_EMBEDDED))) {
  682. GlobalDeleteAtom (aServer);
  683. goto errRtn;
  684. }
  685. // Now set the server.
  686. lpobj->head.lpclient = lpclient;
  687. lpobj->app = GlobalAddAtom (lpclass);
  688. SetEmbeddedTopic (lpobj);
  689. lpobj->item = NULL;
  690. lpobj->bOleServer = QueryVerb (lpobj, 0, (LPSTR)&chVerb, 2);
  691. lpobj->aServer = aServer;
  692. // launch the app and start the system conversation.
  693. if (!CreatePictObject (lhclientdoc, lpobjname, lpobj,
  694. optRender, cfFormat, lpclass))
  695. goto errRtn;
  696. // show the window. Advise for data and close on receiving data
  697. lpobj->fCmd = lnType | ACT_SHOW | ACT_ADVISE | ACT_CLOSE;
  698. InitAsyncCmd (lpobj, lptemplate? OLE_CREATEFROMTEMPLATE : OLE_CREATE, EMBOPENUPDATE);
  699. *lplpoleobject = (LPOLEOBJECT)lpobj;
  700. lpobj->lptemplate = lptemplate;
  701. if ((retval = EmbOpenUpdate (lpobj)) <= OLE_WAIT_FOR_RELEASE)
  702. return retval;
  703. // If there is error afterwards, then the client app should call
  704. // to delete the object.
  705. errRtn:
  706. // for error termination OleDelete will terminate any conversation
  707. // in action.
  708. if (lpobj) {
  709. // This oledelete will not result in asynchronous command.
  710. OleDelete ((LPOLEOBJECT)lpobj);
  711. *lplpoleobject = NULL;
  712. }
  713. return retval;
  714. }
  715. OLESTATUS FARINTERNAL CreateEmbLnkFromFile (lpclient, lpclass, lpfile, lpitem, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, objType)
  716. LPOLECLIENT lpclient;
  717. LPSTR lpclass;
  718. LPSTR lpfile;
  719. LPSTR lpitem;
  720. LHCLIENTDOC lhclientdoc;
  721. LPSTR lpobjname;
  722. LPOLEOBJECT FAR * lplpoleobject;
  723. OLEOPT_RENDER optRender;
  724. OLECLIPFORMAT cfFormat;
  725. LONG objType;
  726. {
  727. OLESTATUS retval = OLE_ERROR_MEMORY;
  728. LPOBJECT_LE lpobj = NULL;
  729. ATOM aServer;
  730. char buf[MAX_STR];
  731. OLE_RELEASE_METHOD releaseMethod;
  732. WORD wFlags = NULL;
  733. char chVerb[2];
  734. if (!lpclass && (lpclass = (LPSTR) buf)
  735. && !MapExtToClass (lpfile, (LPSTR)buf, MAX_STR))
  736. return OLE_ERROR_CLASS;
  737. if (!(aServer = GetAppAtom (lpclass)))
  738. return OLE_ERROR_CLASS;
  739. if (!(lpobj = LeCreateBlank (lhclientdoc, lpobjname, CT_LINK))) {
  740. GlobalDeleteAtom (aServer);
  741. goto errFileCreate;
  742. }
  743. lpobj->head.lpclient = lpclient;
  744. lpobj->app = GlobalAddAtom (lpclass);
  745. lpobj->topic = GlobalAddAtom (lpfile);
  746. lpobj->aServer = aServer;
  747. lpobj->bOleServer = QueryVerb (lpobj, 0, (LPSTR)&chVerb, 2);
  748. if ((retval = SetNetName (lpobj)) != OLE_OK)
  749. goto errFileCreate;
  750. if (lpitem)
  751. lpobj->item = GlobalAddAtom (lpitem);
  752. if (!CreatePictObject (lhclientdoc, lpobjname, lpobj,
  753. optRender, cfFormat, lpclass)) {
  754. retval = OLE_ERROR_MEMORY;
  755. goto errFileCreate;
  756. }
  757. *lplpoleobject = (LPOLEOBJECT) lpobj;
  758. if (objType == CT_EMBEDDED) {
  759. releaseMethod = OLE_CREATEFROMFILE;
  760. if ((optRender == olerender_format) && (cfFormat == cfNative))
  761. wFlags = 0;
  762. else
  763. wFlags = ACT_NATIVE;
  764. }
  765. else {
  766. // caller wants linked object to be created
  767. // if no presentation data is requested and the link is to the whole
  768. // file, then there is no need to launch the server.
  769. if ((optRender == olerender_none) && !lpobj->item)
  770. return FileExists (lpobj);
  771. // we want to establish hot link
  772. wFlags = ACT_ADVISE;
  773. releaseMethod = OLE_CREATELINKFROMFILE;
  774. }
  775. lpobj->fCmd = LN_LNKACT | ACT_REQUEST | ACT_UNLAUNCH | wFlags;
  776. InitAsyncCmd (lpobj, releaseMethod , LNKOPENUPDATE);
  777. if ((retval = LnkOpenUpdate (lpobj)) <= OLE_WAIT_FOR_RELEASE)
  778. return retval;
  779. // If there is error afterwards, then the client app should call
  780. // to delete the object.
  781. errFileCreate:
  782. if (lpobj) {
  783. // This oledelete will not result in asynchronous command.
  784. OleDelete ((LPOLEOBJECT)lpobj);
  785. *lplpoleobject = NULL;
  786. }
  787. return retval;
  788. }
  789. //////////////////////////////////////////////////////////////////////////////
  790. //
  791. // OLESTATUS FARINTERNAL LeCreateInvisible (lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, bActivate)
  792. //
  793. // Arguments:
  794. //
  795. // lpclient -
  796. // lpclass -
  797. // lhclientdoc -
  798. // lpobjname -
  799. // lplpoleobject -
  800. // optRender -
  801. // cfFormat -
  802. // fActivate -
  803. //
  804. // Returns:
  805. //
  806. // OLE_ERROR_CLASS -
  807. // OLE_OK -
  808. // EmbOpenUpdate (lpobj) -
  809. // retval -
  810. //
  811. // Effects:
  812. //
  813. //////////////////////////////////////////////////////////////////////////////
  814. OLESTATUS FARINTERNAL LeCreateInvisible (lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, fActivate)
  815. LPSTR lpclass;
  816. LPOLECLIENT lpclient;
  817. LHCLIENTDOC lhclientdoc;
  818. LPSTR lpobjname;
  819. LPOLEOBJECT FAR * lplpoleobject;
  820. OLEOPT_RENDER optRender;
  821. OLECLIPFORMAT cfFormat;
  822. BOOL fActivate;
  823. {
  824. OLESTATUS retval = OLE_ERROR_MEMORY;
  825. LPOBJECT_LE lpobj = NULL;
  826. ATOM aServer;
  827. char chVerb [2];
  828. if (!(aServer = GetAppAtom (lpclass)))
  829. return OLE_ERROR_CLASS;
  830. if(!(lpobj = LeCreateBlank (lhclientdoc, lpobjname, CT_EMBEDDED))) {
  831. GlobalDeleteAtom (aServer);
  832. goto errRtn;
  833. }
  834. // Now set the server.
  835. lpobj->head.lpclient = lpclient;
  836. lpobj->app = GlobalAddAtom (lpclass);
  837. lpobj->item = NULL;
  838. lpobj->bOleServer = QueryVerb (lpobj, 0, (LPSTR)&chVerb, 2);
  839. lpobj->aServer = aServer;
  840. lpobj->lptemplate = NULL;
  841. SetEmbeddedTopic (lpobj);
  842. if (!CreatePictObject (lhclientdoc, lpobjname, lpobj,
  843. optRender, cfFormat, lpclass))
  844. goto errRtn;
  845. *lplpoleobject = (LPOLEOBJECT)lpobj;
  846. if (!fActivate)
  847. return OLE_OK;
  848. // show the window. Advise for data and close on receiving data
  849. lpobj->fCmd = LN_NEW | ACT_ADVISE | ACT_CLOSE;
  850. InitAsyncCmd (lpobj, OLE_CREATEINVISIBLE, EMBOPENUPDATE);
  851. // launch the app and start the system conversation.
  852. if ((retval = EmbOpenUpdate (lpobj)) <= OLE_WAIT_FOR_RELEASE)
  853. return retval;
  854. // If there is error afterwards, then the client app should call
  855. // to delete the object.
  856. errRtn:
  857. // for error termination OleDelete will terminate any conversation
  858. // in action.
  859. if (lpobj) {
  860. // This oledelete will not result in asynchronous command.
  861. OleDelete ((LPOLEOBJECT)lpobj);
  862. *lplpoleobject = NULL;
  863. }
  864. return retval;
  865. }
  866. // LeSetUpdateOptions: sets the update options. If the server
  867. // is connectd then it unadvises for the current options and
  868. // advises for the new options.
  869. OLESTATUS FARINTERNAL LeSetUpdateOptions (lpobj, options)
  870. LPOBJECT_LE lpobj;
  871. OLEOPT_UPDATE options;
  872. {
  873. PROBE_OLDLINK (lpobj);
  874. PROBE_ASYNC (lpobj);
  875. //!!! make sure the options are within range.
  876. if (lpobj->head.ctype != CT_LINK)
  877. return (OLE_ERROR_OBJECT);
  878. if (options > oleupdate_oncall)
  879. return OLE_ERROR_OPTION;
  880. if (lpobj->optUpdate == options)
  881. return OLE_OK;
  882. if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj)) {
  883. lpobj->optUpdate = options;
  884. return OLE_OK;
  885. }
  886. lpobj->optNew = options;
  887. lpobj->fCmd = 0;
  888. InitAsyncCmd (lpobj, OLE_SETUPDATEOPTIONS, LNKSETUPDATEOPTIONS);
  889. return LnkSetUpdateOptions (lpobj);
  890. }
  891. OLESTATUS LnkSetUpdateOptions (lpobj)
  892. LPOBJECT_LE lpobj;
  893. {
  894. switch (lpobj->subRtn) {
  895. case 0:
  896. if (lpobj->optUpdate == oleupdate_oncall)
  897. goto step1;
  898. // If the server is active then unadvise for old
  899. // options.
  900. UnAdvisePict (lpobj);
  901. WAIT_FOR_ASYNC_MSG (lpobj);
  902. case 1:
  903. step1:
  904. SETSTEP (lpobj, 1);
  905. ProcessErr (lpobj);
  906. lpobj->optUpdate = lpobj->optNew;
  907. if (lpobj->optUpdate == oleupdate_oncall)
  908. goto step3;
  909. AdvisePict (lpobj, NULL);
  910. WAIT_FOR_ASYNC_MSG (lpobj);
  911. case 2:
  912. SETSTEP (lpobj, 2);
  913. if (ProcessErr (lpobj))
  914. goto errRtn;
  915. if (lpobj->optUpdate == oleupdate_onsave)
  916. goto step3;
  917. RequestPict (lpobj);
  918. WAIT_FOR_ASYNC_MSG (lpobj);
  919. case 3:
  920. errRtn:
  921. step3:
  922. ProcessErr (lpobj);
  923. return EndAsyncCmd (lpobj);
  924. default:
  925. DEBUG_OUT ("Unexpected subroutine", 0);
  926. return OLE_ERROR_GENERIC;
  927. }
  928. }
  929. //AdvisePict: Sends advise for pict data
  930. void INTERNAL AdvisePict (lpobj, aAdvItem)
  931. LPOBJECT_LE lpobj;
  932. ATOM aAdvItem;
  933. {
  934. int cftype;
  935. if (cftype = GetPictType (lpobj))
  936. AdviseOn (lpobj, cftype, aAdvItem);
  937. }
  938. //UnAdvisePict: Sends unadvise for pict data
  939. void INTERNAL UnAdvisePict (lpobj)
  940. LPOBJECT_LE lpobj;
  941. {
  942. int cftype;
  943. SETERRHINT (lpobj, OLE_ERROR_ADVISE_PICT);
  944. if (cftype = GetPictType (lpobj))
  945. UnAdviseOn (lpobj, cftype);
  946. }
  947. // GetPictType: Given the object, returns the pict type.
  948. int INTERNAL GetPictType (lpobj)
  949. LPOBJECT_LE lpobj;
  950. {
  951. if (lpobj->lpobjPict)
  952. return (int)(*lpobj->lpobjPict->lpvtbl->EnumFormats)
  953. (lpobj->lpobjPict, NULL);
  954. return NULL;
  955. }
  956. // AdviseOn : Sends advise for a given picture type
  957. // Send advise only if the advise options is not on call.
  958. void INTERNAL AdviseOn (lpobj, cftype, advItem)
  959. LPOBJECT_LE lpobj;
  960. int cftype;
  961. ATOM advItem;
  962. {
  963. HANDLE hopt = NULL;
  964. DDEADVISE FAR *lpopt = NULL;
  965. ATOM item = NULL;
  966. PEDIT_DDE pedit;
  967. OLESTATUS retval;
  968. if (cftype == (int)cfNative)
  969. SETERRHINT (lpobj, OLE_ERROR_ADVISE_NATIVE);
  970. else {
  971. if (cftype == (int)cfBinary)
  972. SETERRHINT (lpobj, OLE_ERROR_ADVISE_RENAME);
  973. else
  974. SETERRHINT (lpobj, OLE_ERROR_ADVISE_PICT);
  975. }
  976. if (lpobj->optUpdate == oleupdate_oncall)
  977. return;
  978. if(!(hopt = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, sizeof(DDEADVISE))))
  979. goto errRtn;
  980. retval = OLE_ERROR_MEMORY;
  981. if(!(lpopt = (DDEADVISE FAR *) GlobalLock (hopt)))
  982. goto errRtn;
  983. pedit = lpobj->pDocEdit;
  984. lpopt->fAckReq = TRUE;
  985. // get data always. Currently there is no way for the
  986. // deferred updates.
  987. lpopt->fDeferUpd = 0;
  988. lpopt->cfFormat = cftype;
  989. GlobalUnlock (hopt);
  990. pedit->hopt = hopt;
  991. if (advItem == aStdDocName)
  992. item = DuplicateAtom (advItem);
  993. else
  994. item = ExtendAtom (lpobj, lpobj->item);
  995. retval = OLE_ERROR_COMM;
  996. if (!PostMessageToServer(pedit, WM_DDE_ADVISE, MAKELONG (hopt, item)))
  997. goto errRtn;
  998. #ifdef FIREWALLS
  999. ASSERT (!pedit->bTerminating, "trying to post while termination")
  1000. ASSERT (pedit->awaitAck == NULL, "Trying to Post msg while waiting for ack")
  1001. #endif
  1002. pedit->awaitAck = AA_ADVISE;
  1003. lpobj->bAsync = TRUE;
  1004. if (advItem == aClose)
  1005. lpobj->pDocEdit->nAdviseClose++;
  1006. else if (advItem == aSave)
  1007. lpobj->pDocEdit->nAdviseSave++;
  1008. return;
  1009. errRtn:
  1010. if (item)
  1011. GlobalDeleteAtom (item);
  1012. if (lpopt)
  1013. GlobalUnlock (hopt);
  1014. if (hopt)
  1015. GlobalFree (hopt);
  1016. lpobj->subErr = retval;
  1017. return ;
  1018. }
  1019. //UnAdviseOn: Sends unadvise for an item.
  1020. void INTERNAL UnAdviseOn (lpobj, cftype)
  1021. LPOBJECT_LE lpobj;
  1022. int cftype;
  1023. {
  1024. ATOM item;
  1025. PEDIT_DDE pedit;
  1026. pedit = lpobj->pDocEdit;
  1027. item = ExtendAtom (lpobj, lpobj->item);
  1028. if (!PostMessageToServer(pedit, WM_DDE_UNADVISE, MAKELONG (NULL, item)))
  1029. lpobj->subErr = OLE_ERROR_COMM;
  1030. else {
  1031. #ifdef FIREWALLS
  1032. ASSERT (!pedit->bTerminating, "trying to post while termination")
  1033. ASSERT (pedit->awaitAck == NULL, "Trying to Post msg while waiting for ack")
  1034. #endif
  1035. lpobj->bAsync = TRUE;
  1036. pedit->awaitAck = AA_UNADVISE;
  1037. }
  1038. }
  1039. // RequestOn: Semd WM_DDE_REQUEST for the item of the
  1040. // for a given type;
  1041. void INTERNAL RequestOn (lpobj, cftype)
  1042. LPOBJECT_LE lpobj;
  1043. int cftype;
  1044. {
  1045. ATOM item = NULL;
  1046. PEDIT_DDE pedit;
  1047. OLESTATUS retval = OLE_ERROR_COMM;
  1048. if (cftype == (int)cfNative)
  1049. SETERRHINT (lpobj, OLE_ERROR_REQUEST_NATIVE);
  1050. else
  1051. SETERRHINT (lpobj, OLE_ERROR_REQUEST_PICT);
  1052. pedit = lpobj->pDocEdit;
  1053. item = DuplicateAtom (lpobj->item);
  1054. if (!PostMessageToServer (pedit, WM_DDE_REQUEST, MAKELONG (cftype, item)))
  1055. goto errRtn;
  1056. #ifdef FIREWALLS
  1057. ASSERT (!pedit->bTerminating, "trying to post while termination")
  1058. ASSERT (pedit->awaitAck == NULL, "Trying to Post msg while waiting for ack")
  1059. #endif
  1060. lpobj->bAsync = TRUE;
  1061. pedit->awaitAck = AA_REQUEST;
  1062. return;
  1063. errRtn:
  1064. if (item)
  1065. GlobalDeleteAtom (item);
  1066. return ;
  1067. }
  1068. //RequestPict: Sends request for apicture type.
  1069. void INTERNAL RequestPict (lpobj)
  1070. LPOBJECT_LE lpobj;
  1071. {
  1072. int cftype;
  1073. if (cftype = GetPictType (lpobj))
  1074. RequestOn (lpobj, cftype);
  1075. }
  1076. // LeSetHostNames: Sets the host names. If the server is connected
  1077. // send the host names to the server.
  1078. OLESTATUS FARINTERNAL LeSetHostNames (lpobj, lpclientName, lpdocName)
  1079. LPOBJECT_LE lpobj;
  1080. LPSTR lpclientName;
  1081. LPSTR lpdocName;
  1082. {
  1083. OLESTATUS retval = OLE_ERROR_MEMORY;
  1084. if (lpobj->head.ctype != CT_EMBEDDED)
  1085. return OLE_ERROR_OBJECT;
  1086. PROBE_ASYNC (lpobj);
  1087. if ((retval = SetHostNamesHandle (lpobj, lpclientName, lpdocName))
  1088. != OLE_OK)
  1089. return retval;
  1090. // If the server is connected poke the hostnames
  1091. InitAsyncCmd (lpobj, OLE_OTHER, NULL);
  1092. if ((retval = PokeHostNames (lpobj)) != OLE_WAIT_FOR_RELEASE)
  1093. CLEARASYNCCMD(lpobj);
  1094. return retval;
  1095. }
  1096. OLESTATUS FARINTERNAL LeSetTargetDevice (lpobj, hdata)
  1097. LPOBJECT_LE lpobj;
  1098. HANDLE hdata;
  1099. {
  1100. HANDLE hdup = NULL;
  1101. OLESTATUS retval;
  1102. PROBE_ASYNC (lpobj);
  1103. if (!hdata) {
  1104. // hdata == NULL means we should not make the target device sticky.
  1105. // This will give the flexibility to the client app. Note that this
  1106. // will not be effective till the next activation.
  1107. if (lpobj->htargetDevice) {
  1108. GlobalFree (lpobj->htargetDevice);
  1109. lpobj->htargetDevice = NULL;
  1110. }
  1111. return OLE_OK;
  1112. }
  1113. if(!(hdup = DuplicateGlobal (hdata, GMEM_MOVEABLE)))
  1114. return OLE_ERROR_MEMORY;
  1115. if (lpobj->htargetDevice)
  1116. GlobalFree (lpobj->htargetDevice);
  1117. lpobj->htargetDevice = hdup;
  1118. InitAsyncCmd (lpobj, OLE_OTHER, NULL);
  1119. if ((retval = PokeTargetDeviceInfo (lpobj)) != OLE_WAIT_FOR_RELEASE)
  1120. CLEARASYNCCMD(lpobj);
  1121. return retval;
  1122. }
  1123. OLESTATUS FARINTERNAL LeSetBounds(lpobj, lprcBounds)
  1124. LPOBJECT_LE lpobj;
  1125. LPRECT lprcBounds;
  1126. {
  1127. OLESTATUS retval = OLE_ERROR_MEMORY;
  1128. HANDLE hdata = NULL;
  1129. LPBOUNDSRECT lprc = NULL;
  1130. PROBE_ASYNC (lpobj);
  1131. if (lpobj->head.ctype != CT_EMBEDDED)
  1132. return OLE_ERROR_OBJECT;
  1133. if(!(hdata = GlobalAlloc (GMEM_MOVEABLE, (WORD)sizeof (BOUNDSRECT))))
  1134. return OLE_ERROR_MEMORY;
  1135. if (!(lprc = (LPBOUNDSRECT)GlobalLock (hdata)))
  1136. goto errrtn;
  1137. // Now set the data
  1138. lprc->defaultWidth = lprcBounds->right - lprcBounds->left;;
  1139. lprc->defaultHeight = -(lprcBounds->bottom - lprcBounds->top);
  1140. lprc->maxWidth = lprcBounds->right - lprcBounds->left;;
  1141. lprc->maxHeight = -(lprcBounds->bottom - lprcBounds->top);
  1142. GlobalUnlock (hdata);
  1143. if (lpobj->hdocDimensions)
  1144. GlobalFree (lpobj->hdocDimensions);
  1145. lpobj->hdocDimensions = hdata;
  1146. InitAsyncCmd (lpobj, OLE_OTHER, NULL);
  1147. if ((retval = PokeDocDimensions (lpobj)) != OLE_WAIT_FOR_RELEASE)
  1148. CLEARASYNCCMD(lpobj);
  1149. return retval;
  1150. errrtn:
  1151. if (lprc)
  1152. GlobalUnlock (hdata);
  1153. if (hdata)
  1154. GlobalFree (hdata);
  1155. return retval;
  1156. }
  1157. OLESTATUS FARINTERNAL LeSetData (lpobj, cfFormat, hData)
  1158. LPOBJECT_LE lpobj;
  1159. OLECLIPFORMAT cfFormat;
  1160. HANDLE hData;
  1161. {
  1162. OLESTATUS retVal = OLE_OK;
  1163. BOOL fKnown = FALSE;
  1164. PROBE_ASYNC (lpobj);
  1165. if ((cfFormat == cfObjectLink) || (cfFormat == cfOwnerLink))
  1166. return ChangeDocAndItem (lpobj, hData);
  1167. if (fKnown = (cfFormat && (cfFormat == ((WORD) GetPictType (lpobj))))) {
  1168. retVal = (*lpobj->lpobjPict->lpvtbl->ChangeData) (lpobj->lpobjPict,
  1169. hData, lpobj->head.lpclient, FALSE);
  1170. (*lpobj->lpobjPict->lpvtbl->GetData) (lpobj->lpobjPict,
  1171. cfFormat, &hData);
  1172. }
  1173. else if (fKnown = (cfFormat == cfNative)) {
  1174. retVal = LeChangeData (lpobj, hData, lpobj->head.lpclient, FALSE);
  1175. hData = lpobj->hnative;
  1176. }
  1177. if (retVal != OLE_OK)
  1178. return retVal;
  1179. if (fKnown)
  1180. ContextCallBack (lpobj, OLE_CHANGED);
  1181. if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj)) {
  1182. if (!fKnown)
  1183. return OLE_ERROR_NOT_OPEN;
  1184. return OLE_OK;
  1185. }
  1186. // except for the following formats all the other data will be copied
  1187. // into DDEPOKE block. So there is no need to duplicate the data of the
  1188. // other formats
  1189. if ((cfFormat == CF_METAFILEPICT) || (cfFormat == CF_BITMAP)
  1190. || (cfFormat == CF_DIB)) {
  1191. if (!(hData = DuplicateGDIdata (hData, cfFormat)))
  1192. return OLE_ERROR_MEMORY;
  1193. }
  1194. // *** The last parameter must be NULL, don't change it ***
  1195. InitAsyncCmd (lpobj, OLE_SETDATA, NULL);
  1196. if ((retVal = SendPokeData (lpobj, lpobj->item, hData, cfFormat))
  1197. != OLE_WAIT_FOR_RELEASE)
  1198. CLEARASYNCCMD(lpobj);
  1199. return retVal;
  1200. }
  1201. OLESTATUS FARINTERNAL LeSetColorScheme (lpobj, lplogpal)
  1202. LPOBJECT_LE lpobj;
  1203. LPLOGPALETTE lplogpal;
  1204. {
  1205. HANDLE hdup = NULL;
  1206. DWORD cblogpal;
  1207. OLESTATUS retval;
  1208. LPBYTE lptemp;
  1209. lptemp = (LPBYTE) lplogpal;
  1210. if (lpobj->head.ctype != CT_EMBEDDED)
  1211. return OLE_ERROR_OBJECT;
  1212. PROBE_ASYNC (lpobj);
  1213. if (!lplogpal) {
  1214. // lplogpal == NULL means we should not make color scheme sticky.
  1215. // This will give the flexibility to the client app. Note that this
  1216. // will not be effective till next activation.
  1217. if (lpobj->hlogpal) {
  1218. GlobalFree (lpobj->hlogpal);
  1219. lpobj->hlogpal = NULL;
  1220. }
  1221. return OLE_OK;
  1222. }
  1223. FARPROBE_READ(lptemp + (cblogpal = 2*sizeof(WORD)));
  1224. cblogpal += ((sizeof(PALETTEENTRY) * lplogpal->palNumEntries) -1);
  1225. if (!FarCheckPointer (lptemp + cblogpal, READ_ACCESS))
  1226. return OLE_ERROR_PALETTE;
  1227. if (!(hdup = CopyData ((LPSTR) lplogpal, cblogpal)))
  1228. return OLE_ERROR_MEMORY;
  1229. if (lpobj->hlogpal)
  1230. GlobalFree (lpobj->hlogpal);
  1231. lpobj->hlogpal = hdup;
  1232. InitAsyncCmd (lpobj, OLE_OTHER, NULL);
  1233. if ((retval = PokeColorScheme (lpobj)) != OLE_WAIT_FOR_RELEASE)
  1234. CLEARASYNCCMD(lpobj);
  1235. return retval;
  1236. }
  1237. //PokeHostNames: Pokes hostname data to the server
  1238. OLESTATUS INTERNAL PokeHostNames (lpobj)
  1239. LPOBJECT_LE lpobj;
  1240. {
  1241. OLESTATUS retVal = OLE_ERROR_MEMORY;
  1242. // if the server is connectd then poke the host names
  1243. if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj))
  1244. return OLE_OK;
  1245. if (!lpobj->hhostNames)
  1246. return OLE_OK;
  1247. aStdHostNames = GlobalAddAtom ("StdHostNames");
  1248. return SendPokeData (lpobj,aStdHostNames,lpobj->hhostNames,cfBinary);
  1249. }
  1250. OLESTATUS INTERNAL PokeTargetDeviceInfo (lpobj)
  1251. LPOBJECT_LE lpobj;
  1252. {
  1253. // if the server is connectd then poke the host names
  1254. if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj))
  1255. return OLE_OK;
  1256. if (!lpobj->htargetDevice)
  1257. return OLE_OK;
  1258. aStdTargetDevice = GlobalAddAtom ("StdTargetDevice");
  1259. return SendPokeData (lpobj, aStdTargetDevice,
  1260. lpobj->htargetDevice,
  1261. cfBinary);
  1262. }
  1263. OLESTATUS INTERNAL PokeDocDimensions (lpobj)
  1264. LPOBJECT_LE lpobj;
  1265. {
  1266. // if the server is connectd then poke the host names
  1267. if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj))
  1268. return OLE_OK;
  1269. if (!lpobj->hdocDimensions)
  1270. return OLE_OK;
  1271. aStdDocDimensions = GlobalAddAtom ("StdDocDimensions");
  1272. return SendPokeData (lpobj, aStdDocDimensions,
  1273. lpobj->hdocDimensions,
  1274. cfBinary);
  1275. }
  1276. OLESTATUS INTERNAL PokeColorScheme (lpobj)
  1277. LPOBJECT_LE lpobj;
  1278. {
  1279. // if the server is connected then poke the palette info
  1280. if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj))
  1281. return OLE_OK;
  1282. if (!lpobj->hlogpal)
  1283. return OLE_OK;
  1284. aStdColorScheme = GlobalAddAtom ("StdColorScheme");
  1285. return SendPokeData (lpobj, aStdColorScheme,
  1286. lpobj->hlogpal,
  1287. cfBinary);
  1288. }
  1289. OLESTATUS INTERNAL SendPokeData (lpobj, aItem, hdata, cfFormat)
  1290. LPOBJECT_LE lpobj;
  1291. ATOM aItem;
  1292. HANDLE hdata;
  1293. OLECLIPFORMAT cfFormat;
  1294. {
  1295. HANDLE hdde = NULL;
  1296. DDEPOKE FAR * lpdde = NULL;
  1297. LPSTR lpdst = NULL;
  1298. LPSTR lpsrc = NULL;
  1299. OLESTATUS retval = OLE_ERROR_MEMORY;
  1300. DWORD dwSize = NULL;
  1301. PEDIT_DDE pedit;
  1302. BOOL bGDIdata = FALSE;
  1303. pedit = lpobj->pDocEdit;
  1304. // If it is GDI data then we can stuff the handle into POKE block.
  1305. // Otherwise we have to copy the data into DDE data block. There
  1306. // is a special case with old MSDraw, that will be handled by
  1307. // the routine CanPutHandleInPokeBlock()
  1308. if (!(bGDIdata = CanPutHandleInPokeBlock (lpobj, cfFormat))) {
  1309. if (!(dwSize = GlobalSize (hdata)))
  1310. return OLE_ERROR_MEMORY;
  1311. if (!(lpsrc = (LPSTR) GlobalLock (hdata)))
  1312. return OLE_ERROR_MEMORY;
  1313. GlobalUnlock (hdata);
  1314. }
  1315. // Now allocate the DDE data block
  1316. if (!(hdde = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT,
  1317. (dwSize + sizeof(DDEPOKE) - sizeof(BYTE) + sizeof(HANDLE)))))
  1318. goto errRtn;
  1319. if (!(lpdde = (DDEPOKE FAR *)GlobalLock (hdde)))
  1320. goto errRtn;
  1321. GlobalUnlock (hdde);
  1322. // !!! We may want to set it TRUE, for performance reasons. But it
  1323. // will require some rework on the server side
  1324. lpdde->fRelease = 0;
  1325. lpdde->cfFormat = cfFormat;
  1326. if (bGDIdata)
  1327. *(LPHANDLE)lpdde->Value = hdata;
  1328. else {
  1329. lpdst = (LPSTR)lpdde->Value;
  1330. UtilMemCpy (lpdst, lpsrc, dwSize);
  1331. // For the CF_METAFILEPICT format, we would come here only if we are
  1332. // dealing with the old version of MSDraw. In that case we want to
  1333. // free the handle to METAFILEPICT strcuture, because we've already
  1334. // copied its contents to DDEPOKE structure.
  1335. // Note that that the old MSDraw expects the contents of METAFILEPICT
  1336. // structure to be part of DDEPOKE, rather than the handle to it.
  1337. if (cfFormat == CF_METAFILEPICT) {
  1338. GlobalFree (hdata);
  1339. hdata = NULL;
  1340. }
  1341. }
  1342. // *** From here onwards if there is an error call FreePokeData(), don't
  1343. // jump to errRtn
  1344. aItem = DuplicateAtom (aItem);
  1345. ASSERT(pedit->hData == NULL, "Poke data is not null");
  1346. pedit->hData = hdde;
  1347. if (!PostMessageToServer (pedit, WM_DDE_POKE, MAKELONG (hdde, aItem))) {
  1348. if (aItem)
  1349. GlobalDeleteAtom (aItem);
  1350. FreePokeData (lpobj, pedit);
  1351. return (lpobj->subErr = OLE_ERROR_COMM);
  1352. }
  1353. #ifdef FIREWALLS
  1354. ASSERT (!pedit->bTerminating, "trying to post while termination")
  1355. ASSERT (pedit->awaitAck == NULL, "Trying to Post msg while waiting for ack")
  1356. #endif
  1357. if (lpobj->asyncCmd == OLE_NONE)
  1358. lpobj->asyncCmd = OLE_OTHER;
  1359. lpobj->bAsync = TRUE;
  1360. pedit->awaitAck = AA_POKE;
  1361. // !!! after poke of the hostnames etc. we are not processing error.,
  1362. // Data is freed after the Poke is acknowledged. OLE_RELEASE will be sent
  1363. // to when ACK comes.
  1364. return OLE_WAIT_FOR_RELEASE;
  1365. errRtn:
  1366. if (hdata)
  1367. FreeGDIdata (hdata, cfFormat);
  1368. if (hdde)
  1369. GlobalFree (hdde);
  1370. pedit->hData = NULL;
  1371. return (lpobj->subErr = retval);
  1372. }
  1373. // FreePokeData: Frees the poked data.
  1374. void INTERNAL FreePokeData (lpobj, pedit)
  1375. LPOBJECT_LE lpobj;
  1376. PEDIT_DDE pedit;
  1377. {
  1378. DDEPOKE FAR * lpdde;
  1379. #ifdef FIREWALLS
  1380. ASSERT (pedit->hData, "Poke data handle is null");
  1381. #endif
  1382. if (lpdde = (DDEPOKE FAR *) GlobalLock (pedit->hData)) {
  1383. GlobalUnlock (pedit->hData);
  1384. // The old version of MSDraw expects the contents of METAFILEPICT
  1385. // structure to be part of DDEPOKE, rather than the handle to it.
  1386. if (!lpobj->bOleServer && (lpobj->app == aMSDraw)
  1387. && (lpdde->cfFormat == CF_METAFILEPICT)) {
  1388. DeleteMetaFile (((LPMETAFILEPICT) ((LPSTR) &lpdde->Value))->hMF);
  1389. }
  1390. else {
  1391. FreeGDIdata (*(LPHANDLE)lpdde->Value, lpdde->cfFormat);
  1392. }
  1393. }
  1394. GlobalFree (pedit->hData);
  1395. pedit->hData = NULL;
  1396. }
  1397. BOOL INTERNAL SendSrvrMainCmd (lpobj, lptemplate)
  1398. LPOBJECT_LE lpobj;
  1399. LPSTR lptemplate;
  1400. {
  1401. WORD size;
  1402. WORD len;
  1403. OLESTATUS retval;
  1404. int cmd;
  1405. HANDLE hInst = NULL;
  1406. LPSTR lpdata= NULL;
  1407. HANDLE hdata = NULL;
  1408. BOOL bLaunch = TRUE;
  1409. Puts("Launch App and Send Sys command");
  1410. #ifdef FIREWALLS
  1411. ASSERT (lpobj->aServer, "Serevr is NULL");
  1412. #endif
  1413. if (!lpobj->aServer) {
  1414. retval = OLE_ERROR_REGISTRATION;
  1415. goto errRtn;
  1416. }
  1417. if (!lpobj->bOldLink) {
  1418. bLaunch = !(lpobj->fCmd & ACT_NOLAUNCH);
  1419. cmd = lpobj->fCmd & LN_MASK;
  1420. }
  1421. if (cmd == LN_LNKACT) {
  1422. // take care of network based document
  1423. char cDrive = lpobj->cDrive;
  1424. if ((retval = CheckNetDrive (lpobj, POPUP_NETDLG)) != OLE_OK) {
  1425. lpobj->cDrive = cDrive;
  1426. goto errRtn;
  1427. }
  1428. if (cDrive != lpobj->cDrive)
  1429. ContextCallBack (lpobj, OLE_RENAMED);
  1430. }
  1431. if (!InitSrvrConv (lpobj, hInst)) {
  1432. if (!bLaunch)
  1433. goto errRtn;
  1434. if (!(hInst = LeLaunchApp (lpobj))) {
  1435. // We failed to launch the app. If it is a linked object, see
  1436. // whether the docname is valid for new servers. We wouldn't
  1437. // have given the doc name on the command line for the old
  1438. // servers. So, there is no point in checking for file existance
  1439. // in that case.
  1440. if (lpobj->bOleServer && (lpobj->bOldLink || (cmd == LN_LNKACT))){
  1441. if ((retval = FileExists (lpobj)) != OLE_OK)
  1442. goto errRtn;
  1443. }
  1444. retval = OLE_ERROR_LAUNCH;
  1445. goto errRtn;
  1446. }
  1447. if (lpobj->bOldLink)
  1448. return TRUE;
  1449. if (lpobj->bOleServer && (cmd == LN_LNKACT)) {
  1450. // We are not using any data blocks if the object is old link.
  1451. // we launched with docname, and don't have to establish system
  1452. // level and also we don't have to send exec strings.
  1453. // for non-ole servers like excel, we do want to connect at
  1454. // the system level, so that we can send "StdOpen". We also
  1455. // have to send "StdExit" for the server to exit in the
  1456. // invisible launch case.
  1457. return TRUE;
  1458. }
  1459. retval = OLE_ERROR_COMM;
  1460. if(!InitSrvrConv (lpobj, hInst))
  1461. goto errRtn;
  1462. #ifdef OLD
  1463. if (!lpobj->bOleServer && (cmd == LN_LNKACT))
  1464. return TRUE;
  1465. #endif
  1466. }
  1467. if (!lpobj->bOldLink) {
  1468. cmd = lpobj->fCmd & LN_MASK;
  1469. len = lstrlen (srvrSysCmd[cmd >> LN_SHIFT]);
  1470. // for template and new, add the class name also
  1471. if (cmd == LN_NEW || cmd == LN_TEMPLATE)
  1472. len += GlobalGetAtomLen (lpobj->app);
  1473. // Now add the document length.
  1474. len += GlobalGetAtomLen (lpobj->topic);
  1475. // add the length of the template name
  1476. if (lptemplate)
  1477. len += lstrlen (lptemplate);
  1478. // now add the fudge factor for the Quotes etc.
  1479. len += LN_FUDGE;
  1480. // allocate the buffer and set the command.
  1481. hdata = GlobalAlloc (GMEM_DDESHARE, size = len);
  1482. retval = OLE_ERROR_MEMORY;
  1483. SETERRHINT(lpobj, OLE_ERROR_MEMORY);
  1484. if (hdata == NULL || (lpdata = (LPSTR)GlobalLock (hdata)) == NULL)
  1485. goto errRtn;
  1486. }
  1487. lstrcpy (lpdata, (LPSTR)"["); // [
  1488. lstrcat (lpdata, srvrSysCmd[cmd >> LN_SHIFT]); // [Std....
  1489. lstrcat (lpdata, "(\""); // [std...("
  1490. if (cmd == LN_NEW || cmd == LN_TEMPLATE) {
  1491. len = lstrlen (lpdata);
  1492. GlobalGetAtomName (lpobj->app, (LPSTR)lpdata + len, size - len);
  1493. // [std...("class
  1494. lstrcat (lpdata, "\",\""); // [std...("class", "
  1495. }
  1496. len = lstrlen (lpdata);
  1497. // now get the topic name.
  1498. GlobalGetAtomName (lpobj->topic, lpdata + len, (WORD)size - len);
  1499. // [std...("class","doc
  1500. if (lptemplate) {
  1501. lstrcat (lpdata, "\",\""); // [std...("class","doc","
  1502. lstrcat (lpdata, lptemplate); // [std...("class","doc","temp
  1503. }
  1504. lstrcat (lpdata, "\")]"); // [std...("class","doc","temp")]
  1505. GlobalUnlock (hdata);
  1506. // !!!optimize with mapping.
  1507. SETERRHINT(lpobj, (OLE_ERROR_TEMPLATE + (cmd >> LN_SHIFT)));
  1508. return SrvrExecute (lpobj, hdata);
  1509. errRtn:
  1510. if (lpdata)
  1511. GlobalUnlock (hdata);
  1512. if (hdata)
  1513. GlobalFree (hdata);
  1514. lpobj->subErr = retval;
  1515. return FALSE;
  1516. }
  1517. // ExtendAtom: Create a new atom, which is the old one plus extension
  1518. ATOM INTERNAL ExtendAtom (lpobj, item)
  1519. LPOBJECT_LE lpobj;
  1520. ATOM item;
  1521. {
  1522. char buffer[MAX_ATOM+1];
  1523. LPSTR lpext;
  1524. Puts("ExtendAtom");
  1525. buffer[0] = 0;
  1526. if (item)
  1527. GlobalGetAtomName (item, buffer, MAX_ATOM);
  1528. switch (lpobj->optUpdate) {
  1529. case oleupdate_always:
  1530. lpext = (LPSTR)"";
  1531. break;
  1532. case oleupdate_onsave:
  1533. lpext = (LPSTR)"/Save";
  1534. break;
  1535. case oleupdate_onclose:
  1536. lpext = (LPSTR)"/Close";
  1537. break;
  1538. default:
  1539. ASSERT (FALSE, "on call options not expected here");
  1540. break;
  1541. }
  1542. lstrcat (buffer, lpext);
  1543. if (buffer[0])
  1544. return GlobalAddAtom (buffer);
  1545. else
  1546. return NULL;
  1547. }
  1548. BOOL INTERNAL CreatePictObject (lhclientdoc, lpobjname, lpobj, optRender, cfFormat, lpclass)
  1549. LHCLIENTDOC lhclientdoc;
  1550. LPSTR lpobjname;
  1551. LPOBJECT_LE lpobj;
  1552. OLEOPT_RENDER optRender;
  1553. OLECLIPFORMAT cfFormat;
  1554. LPSTR lpclass;
  1555. {
  1556. LPOLEOBJECT lpPictObj = NULL;
  1557. ATOM aClass;
  1558. lpobj->lpobjPict = NULL;
  1559. if (optRender == olerender_format) {
  1560. switch (cfFormat) {
  1561. case NULL:
  1562. return FALSE;
  1563. case CF_METAFILEPICT:
  1564. if (!(lpPictObj = (LPOLEOBJECT) MfCreateBlank (lhclientdoc,
  1565. lpobjname, CT_PICTURE)))
  1566. return FALSE;
  1567. break;
  1568. case CF_DIB:
  1569. if (!(lpPictObj = (LPOLEOBJECT) DibCreateBlank (lhclientdoc,
  1570. lpobjname, CT_PICTURE)))
  1571. return FALSE;
  1572. break;
  1573. case CF_BITMAP:
  1574. if (!(lpPictObj = (LPOLEOBJECT) BmCreateBlank (lhclientdoc,
  1575. lpobjname, CT_PICTURE)))
  1576. return FALSE;
  1577. break;
  1578. default:
  1579. aClass = GlobalAddAtom (lpclass);
  1580. if (!(lpPictObj = (LPOLEOBJECT) GenCreateBlank (lhclientdoc,
  1581. lpobjname, CT_PICTURE, aClass)))
  1582. return FALSE;
  1583. ((LPOBJECT_GEN)lpPictObj)->cfFormat = cfFormat;
  1584. break;
  1585. }
  1586. }
  1587. else if (optRender == olerender_draw) {
  1588. if (!(lpPictObj = (LPOLEOBJECT) MfCreateBlank (lhclientdoc,
  1589. lpobjname, CT_PICTURE)))
  1590. return FALSE;
  1591. #ifdef LATER
  1592. if (AdviseOn (lpobj, (cfFormat = CF_METAFILEPICT), NULL))
  1593. lpPictObj = (LPOLEOBJECT) MfCreateBlank (lhclientdoc,
  1594. lpobjname, CT_PICTURE);
  1595. // !!! for the time being take assume we need to get metafile.
  1596. else if (AdviseOn (lpobj, (cfFormat = CF_DIB), NULL))
  1597. lpPictObj = (LPOLEOBJECT) DibCreateBlank (lhclientdoc,
  1598. lpobjname, CT_PICTURE);
  1599. else if (AdviseOn (lpobj, (cfFormat = CF_BITMAP), NULL))
  1600. lpPictObj = (LPOLEOBJECT) BmCreateBlank (lhclientdoc,
  1601. lpobjname, CT_PICTURE);
  1602. else
  1603. goto errPict;
  1604. #endif
  1605. }
  1606. else
  1607. return (optRender == olerender_none);
  1608. if (lpobj->lpobjPict = lpPictObj)
  1609. lpobj->lpobjPict->lpParent = (LPOLEOBJECT) lpobj;
  1610. return TRUE;
  1611. }
  1612. OLESTATUS LnkChangeLnk (lpobj)
  1613. LPOBJECT_LE lpobj;
  1614. {
  1615. switch (lpobj->subRtn) {
  1616. case 0:
  1617. TermDocConv (lpobj);
  1618. WAIT_FOR_ASYNC_MSG (lpobj);
  1619. case 1:
  1620. // delete the edit block
  1621. DeleteDocEdit (lpobj);
  1622. TermSrvrConv (lpobj);
  1623. WAIT_FOR_ASYNC_MSG (lpobj);
  1624. case 2:
  1625. // Do not set any errors, just delete the object.
  1626. // delete the server edit block
  1627. DeleteSrvrEdit (lpobj);
  1628. // now try to activate the new link.
  1629. SKIP_TO (!InitDocConv (lpobj, !POPUP_NETDLG), step3);
  1630. lpobj->fCmd = LN_LNKACT | ACT_ADVISE | ACT_REQUEST;
  1631. InitAsyncCmd (lpobj, OLE_SETDATA, LNKOPENUPDATE);
  1632. return LnkOpenUpdate (lpobj);
  1633. case 3:
  1634. step3:
  1635. return EndAsyncCmd (lpobj);
  1636. default:
  1637. DEBUG_OUT ("Unexpected subroutine", 0);
  1638. return OLE_ERROR_GENERIC;
  1639. }
  1640. }
  1641. OLESTATUS INTERNAL ChangeDocAndItem (lpobj, hinfo)
  1642. LPOBJECT_LE lpobj;
  1643. HANDLE hinfo;
  1644. {
  1645. LPSTR lpinfo;
  1646. ATOM aNewTopic, aNewItem = NULL, aOldTopic;
  1647. OLESTATUS retVal = OLE_ERROR_BLANK;
  1648. PROBE_SVRCLOSING(lpobj);
  1649. if (!(lpinfo = GlobalLock (hinfo)))
  1650. return OLE_ERROR_MEMORY;
  1651. lpinfo += lstrlen (lpinfo) + 1;
  1652. aNewTopic = GlobalAddAtom (lpinfo);
  1653. lpinfo += lstrlen (lpinfo) + 1;
  1654. if (*lpinfo)
  1655. aNewItem = GlobalAddAtom (lpinfo);
  1656. if (!aNewTopic && (lpobj->head.ctype == CT_LINK))
  1657. goto errRtn;
  1658. aOldTopic = lpobj->topic;
  1659. lpobj->topic = aNewTopic;
  1660. if ((retVal = SetNetName (lpobj)) != OLE_OK) {
  1661. if (lpobj->topic)
  1662. GlobalDeleteAtom (lpobj->topic);
  1663. lpobj->topic = aOldTopic;
  1664. goto errRtn;
  1665. }
  1666. if (aOldTopic)
  1667. GlobalDeleteAtom (aOldTopic);
  1668. if (lpobj->item)
  1669. GlobalDeleteAtom (lpobj->item);
  1670. lpobj->item = aNewItem;
  1671. // As the atoms have already changed, lpobj->hLink becomes irrelevant.
  1672. if (lpobj->hLink) {
  1673. GlobalFree (lpobj->hLink);
  1674. lpobj->hLink = NULL;
  1675. }
  1676. GlobalUnlock(hinfo);
  1677. // Now disconnect the old link and try to connect to the new one.
  1678. lpobj->fCmd = 0;
  1679. InitAsyncCmd (lpobj, OLE_SETDATA, LNKCHANGELNK);
  1680. return LnkChangeLnk (lpobj);
  1681. errRtn:
  1682. if (aNewItem)
  1683. GlobalDeleteAtom (aNewItem);
  1684. GlobalUnlock (hinfo);
  1685. return retVal;
  1686. }
  1687. BOOL QueryUnlaunch (lpobj)
  1688. LPOBJECT_LE lpobj;
  1689. {
  1690. if (!(lpobj->fCmd & ACT_UNLAUNCH))
  1691. return FALSE;
  1692. // only if we loaded the app
  1693. if (lpobj->pSysEdit && lpobj->pSysEdit->hClient && lpobj->pSysEdit->hInst)
  1694. return TRUE;
  1695. return FALSE;
  1696. }
  1697. BOOL QueryClose (lpobj)
  1698. LPOBJECT_LE lpobj;
  1699. {
  1700. if (!((lpobj->fCmd & ACT_UNLAUNCH) ||
  1701. (lpobj->head.ctype == CT_EMBEDDED)))
  1702. return FALSE;
  1703. // only if we loaded the documnet
  1704. if (lpobj->pSysEdit && lpobj->pSysEdit->hClient)
  1705. return TRUE;
  1706. return FALSE;
  1707. }
  1708. OLESTATUS INTERNAL SetHostNamesHandle (lpobj, lpclientName, lpdocName)
  1709. LPOBJECT_LE lpobj;
  1710. LPSTR lpclientName;
  1711. LPSTR lpdocName;
  1712. {
  1713. WORD cbClient;
  1714. WORD size;
  1715. HANDLE hhostNames = NULL;
  1716. LPHOSTNAMES lphostNames = NULL;
  1717. LPSTR lpdata;
  1718. // 4 bytes is for the two offsets
  1719. size = (cbClient = lstrlen(lpclientName)+1) + (lstrlen(lpdocName)+1) + 4;
  1720. if ((hhostNames = GlobalAlloc (GMEM_MOVEABLE, (DWORD) size))
  1721. == NULL)
  1722. goto errRtn;
  1723. if ((lphostNames = (LPHOSTNAMES)GlobalLock (hhostNames)) == NULL)
  1724. goto errRtn;
  1725. lphostNames->clientNameOffset = 0;
  1726. lphostNames->documentNameOffset = cbClient;
  1727. lpdata = (LPSTR)lphostNames->data;
  1728. lstrcpy (lpdata, lpclientName);
  1729. lstrcpy (lpdata + cbClient, lpdocName);
  1730. if (lpobj->hhostNames)
  1731. GlobalFree ( lpobj->hhostNames);
  1732. GlobalUnlock (hhostNames);
  1733. lpobj->hhostNames = hhostNames;
  1734. return OLE_OK;
  1735. errRtn:
  1736. if (lphostNames)
  1737. GlobalUnlock (hhostNames);
  1738. if (hhostNames)
  1739. GlobalFree (hhostNames);
  1740. return OLE_ERROR_MEMORY;
  1741. }
  1742. #if 0
  1743. OLESTATUS FARINTERNAL LeAbort (lpobj)
  1744. LPOBJECT_LE lpobj;
  1745. {
  1746. BOOL bAbort = FALSE;
  1747. PEDIT_DDE pedit;
  1748. // check whether the any transaction pending for
  1749. // the document level.
  1750. // channel open
  1751. // any transaction pending.
  1752. // and we are not in terminate mode.
  1753. if ((pedit = lpobj->pDocEdit) && pedit->hServer &&
  1754. pedit->awaitAck && !pedit->bTerminating) {
  1755. pedit->bAbort = bAbort = TRUE;
  1756. // delete any data we need to delete. Ricght now
  1757. // we kill only the timer. We can not delete any
  1758. // since the server could potentially look at the data.
  1759. DeleteAbortData (lpobj, pedit);
  1760. }
  1761. if ((pedit = lpobj->pSysEdit) && pedit->hServer &&
  1762. pedit->awaitAck && !pedit->bTerminating) {
  1763. pedit->bAbort = bAbort = TRUE;
  1764. DeleteAbortData (lpobj, pedit);
  1765. }
  1766. if (!bAbort)
  1767. return OLE_OK;
  1768. // Now send the EndAsync
  1769. lpobj->mainErr = OLE_ERROR_ABORT;
  1770. EndAsyncCmd (lpobj);
  1771. return OLE_OK;
  1772. }
  1773. #endif
  1774. OLESTATUS FARINTERNAL ProbeAsync(lpobj)
  1775. LPOBJECT_LE lpobj;
  1776. {
  1777. if (lpobj->asyncCmd == OLE_NONE)
  1778. return OLE_OK;
  1779. if (!IsServerValid (lpobj)) {
  1780. // Now send the EndAsync
  1781. lpobj->mainErr = OLE_ERROR_TASK;
  1782. EndAsyncCmd (lpobj);
  1783. return OLE_OK;
  1784. }
  1785. return OLE_BUSY;
  1786. }
  1787. BOOL INTERNAL IsWindowValid (hwnd)
  1788. HWND hwnd;
  1789. {
  1790. #define TASK_OFFSET 0x00FA
  1791. LPSTR lptask;
  1792. HANDLE htask;
  1793. if (!IsWindow (hwnd))
  1794. return FALSE;
  1795. if (bWLO)
  1796. return TRUE;
  1797. // now get the task handle and find out it is valid.
  1798. htask = GetWindowTask (hwnd);
  1799. if ((wWinVer == 0x0003) || !lpfnIsTask) {
  1800. lptask = (LPSTR)(MAKELONG (TASK_OFFSET, htask));
  1801. if (!FarCheckPointer(lptask, READ_ACCESS))
  1802. return FALSE;
  1803. // now check for the signature bytes of task block in kernel
  1804. if (*lptask++ == 'T' && *lptask == 'D')
  1805. return TRUE;
  1806. }
  1807. else {
  1808. // From win31 onwards the API IsTask can be used for task validation
  1809. if ((*lpfnIsTask)(htask))
  1810. return TRUE;
  1811. }
  1812. return FALSE;
  1813. }
  1814. BOOL INTERNAL IsServerValid (lpobj)
  1815. LPOBJECT_LE lpobj;
  1816. {
  1817. MSG msg;
  1818. BOOL retval = FALSE;
  1819. if (lpobj->pDocEdit && lpobj->pDocEdit->hServer) {
  1820. retval = TRUE;
  1821. if (!IsWindowValid (lpobj->pDocEdit->hServer)) {
  1822. if (!PeekMessage ((LPMSG)&msg, lpobj->pDocEdit->hClient, WM_DDE_TERMINATE, WM_DDE_TERMINATE,
  1823. PM_NOREMOVE | PM_NOYIELD)){
  1824. #ifdef FIREWALLS
  1825. ASSERT (FALSE, "Server truely died");
  1826. #endif
  1827. return FALSE;
  1828. }
  1829. }
  1830. }
  1831. if (lpobj->pSysEdit && lpobj->pSysEdit->hServer) {
  1832. retval = TRUE;
  1833. if (!IsWindowValid (lpobj->pSysEdit->hServer)) {
  1834. if (!PeekMessage ((LPMSG)&msg, lpobj->pSysEdit->hClient, WM_DDE_TERMINATE, WM_DDE_TERMINATE,
  1835. PM_NOREMOVE | PM_NOYIELD)){
  1836. #ifdef FIREWALLS
  1837. ASSERT (FALSE, "Server truely died");
  1838. #endif
  1839. return FALSE;
  1840. }
  1841. }
  1842. }
  1843. return retval;
  1844. }
  1845. OLESTATUS FARINTERNAL LeExecute (lpobj, hCmds, wReserve)
  1846. LPOBJECT_LE lpobj;
  1847. HANDLE hCmds;
  1848. WORD wReserve;
  1849. {
  1850. // Assumes all the creates are in order
  1851. PROBE_CREATE_ASYNC(lpobj);
  1852. PROBE_SVRCLOSING(lpobj);
  1853. if (!(lpobj = (*lpobj->head.lpvtbl->QueryProtocol) (lpobj,
  1854. PROTOCOL_EXECUTE)))
  1855. return OLE_ERROR_PROTOCOL;
  1856. if (!QueryOpen (lpobj))
  1857. return OLE_ERROR_NOT_OPEN;
  1858. if (!(hCmds = DuplicateGlobal (hCmds, GMEM_MOVEABLE|GMEM_DDESHARE)))
  1859. return OLE_ERROR_MEMORY;
  1860. InitAsyncCmd (lpobj, OLE_OTHER, NULL);
  1861. SETERRHINT(lpobj, OLE_ERROR_COMMAND);
  1862. if (DocExecute(lpobj, hCmds))
  1863. return OLE_WAIT_FOR_RELEASE;
  1864. else
  1865. return OLE_ERROR_COMMAND;
  1866. }
  1867. void INTERNAL FreeGDIdata (hData, cfFormat)
  1868. HANDLE hData;
  1869. OLECLIPFORMAT cfFormat;
  1870. {
  1871. if (cfFormat == CF_METAFILEPICT) {
  1872. LPMETAFILEPICT lpMfp;
  1873. if (lpMfp = (LPMETAFILEPICT) GlobalLock (hData)) {
  1874. GlobalUnlock (hData);
  1875. DeleteMetaFile (lpMfp->hMF);
  1876. }
  1877. GlobalFree (hData);
  1878. }
  1879. else if (cfFormat == CF_BITMAP)
  1880. DeleteObject (hData);
  1881. else if (cfFormat == CF_DIB)
  1882. GlobalFree (hData);
  1883. }
  1884. // This routine figures out whether the handle to data block can be copied
  1885. // to DDEPOKE block rather than the contents of the handle
  1886. BOOL INTERNAL CanPutHandleInPokeBlock (lpobj, cfFormat)
  1887. LPOBJECT_LE lpobj;
  1888. OLECLIPFORMAT cfFormat;
  1889. {
  1890. if (cfFormat == CF_BITMAP || cfFormat == CF_DIB)
  1891. return TRUE;
  1892. if (cfFormat == CF_METAFILEPICT) {
  1893. // The old version of MSDraw expects the contents of METAFILEPICT
  1894. // structure to be part of DDEPOKE, rather than the handle to it.
  1895. if (!lpobj->bOleServer && lpobj->app == aMSDraw)
  1896. return FALSE;
  1897. return TRUE;
  1898. }
  1899. return FALSE;
  1900. }