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.

688 lines
18 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: ole2lcl.cxx (16 bit target)
  7. //
  8. // Contents: OLE2 APIs implemented locally
  9. //
  10. // Functions:
  11. //
  12. // History: 17-Dec-93 Johann Posch (johannp) Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include <headers.cxx>
  16. #pragma hdrstop
  17. #include <limits.h>
  18. #include <ole2sp.h>
  19. #include <ole2ver.h>
  20. #include <valid.h>
  21. #include <ole2int.h>
  22. #include <call32.hxx>
  23. #include <apilist.hxx>
  24. DWORD gdwOleVersion = MAKELONG(OLE_STREAM_VERSION, OLE_PRODUCT_VERSION);
  25. //+---------------------------------------------------------------------------
  26. //
  27. // Function: OleGetMalloc, Local
  28. //
  29. //----------------------------------------------------------------------------
  30. STDAPI OleGetMalloc(DWORD dwContext, IMalloc FAR* FAR* ppMalloc)
  31. {
  32. return CoGetMalloc(dwContext, ppMalloc);
  33. }
  34. //+---------------------------------------------------------------------------
  35. //
  36. // Function: OleBuildVersion, Local
  37. //
  38. //----------------------------------------------------------------------------
  39. STDAPI_(DWORD) OleBuildVersion( VOID )
  40. {
  41. return CoBuildVersion();
  42. }
  43. //+---------------------------------------------------------------------------
  44. //
  45. // Function: OleDuplicateData, Local
  46. //
  47. // Synopsis: Duplicates the given data
  48. //
  49. // History: 11-Apr-94 DrewB Copied from various places in OLE2
  50. //
  51. //----------------------------------------------------------------------------
  52. FARINTERNAL_(HBITMAP) BmDuplicate
  53. (HBITMAP hold, DWORD FAR* lpdwSize, LPBITMAP lpBm)
  54. {
  55. HBITMAP hnew = NULL;
  56. HANDLE hMem;
  57. LPSTR lpMem;
  58. DWORD dwSize;
  59. BITMAP bm;
  60. SIZE extents;
  61. extents.cx = extents.cy = 0;
  62. GetObject (hold, sizeof(BITMAP), (LPSTR) &bm);
  63. dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) *
  64. ((DWORD) bm.bmPlanes);
  65. if (!(hMem = GlobalAlloc (GMEM_MOVEABLE, dwSize)))
  66. return NULL;
  67. if (!(lpMem = (LPSTR) GlobalLock (hMem)))
  68. goto errRtn;
  69. GlobalUnlock (hMem);
  70. GetBitmapBits (hold, dwSize, lpMem);
  71. if (hnew = CreateBitmap (bm.bmWidth, bm.bmHeight,
  72. bm.bmPlanes, bm.bmBitsPixel, NULL)) {
  73. if (!SetBitmapBits (hnew, dwSize, lpMem)) {
  74. DeleteObject (hnew);
  75. hnew = NULL;
  76. goto errRtn;
  77. }
  78. }
  79. if (lpdwSize)
  80. *lpdwSize = dwSize;
  81. if (lpBm)
  82. *lpBm = bm;
  83. if (GetBitmapDimensionEx(hold, &extents) && extents.cx && extents.cy)
  84. SetBitmapDimensionEx(hnew, extents.cx, extents.cy, NULL);
  85. errRtn:
  86. if (hMem)
  87. GlobalFree (hMem);
  88. return hnew;
  89. }
  90. FARINTERNAL_(HPALETTE) UtDupPalette
  91. (HPALETTE hpalette)
  92. {
  93. WORD cEntries = 0;
  94. HANDLE hLogPal = NULL;
  95. LPLOGPALETTE pLogPal = NULL;
  96. HPALETTE hpaletteNew = NULL;
  97. if (0==GetObject (hpalette, sizeof(cEntries), &cEntries))
  98. return NULL;
  99. if (NULL==(hLogPal = GlobalAlloc (GMEM_MOVEABLE, sizeof (LOGPALETTE) +
  100. cEntries * sizeof (PALETTEENTRY))))
  101. return NULL;
  102. if (NULL==(pLogPal = (LPLOGPALETTE) GlobalLock (hLogPal)))
  103. goto errRtn;
  104. if (0==GetPaletteEntries (hpalette, 0, cEntries, pLogPal->palPalEntry))
  105. goto errRtn;
  106. pLogPal->palVersion = 0x300;
  107. pLogPal->palNumEntries = cEntries;
  108. if (NULL==(hpaletteNew = CreatePalette (pLogPal)))
  109. goto errRtn;
  110. errRtn:
  111. if (pLogPal)
  112. GlobalUnlock (hLogPal);
  113. if (hLogPal)
  114. GlobalFree (hLogPal);
  115. AssertSz (hpaletteNew, "Warning: UtDupPalette Failed");
  116. return hpaletteNew;
  117. }
  118. FARINTERNAL_(HANDLE) UtDupGlobal (HANDLE hsrc, UINT uiFlags)
  119. {
  120. HANDLE hdst;
  121. DWORD dwSize;
  122. LPSTR lpdst = NULL;
  123. LPSTR lpsrc = NULL;
  124. if (!hsrc)
  125. return NULL;
  126. if (!(lpsrc = GlobalLock (hsrc)))
  127. return NULL;
  128. hdst = GlobalAlloc (uiFlags, (dwSize = GlobalSize(hsrc)));
  129. if (hdst == NULL || (lpdst = GlobalLock (hdst)) == NULL)
  130. goto errRtn;
  131. UtMemCpy (lpdst, lpsrc, dwSize);
  132. GlobalUnlock (hsrc);
  133. GlobalUnlock (hdst);
  134. return hdst;
  135. errRtn:
  136. if (hdst)
  137. GlobalFree (hdst);
  138. return NULL;
  139. }
  140. OLEAPI_(HANDLE) OleDuplicateData
  141. (HANDLE hSrc, CLIPFORMAT cfFormat, UINT uiFlags)
  142. {
  143. if (!hSrc)
  144. return NULL;
  145. if (cfFormat == CF_BITMAP)
  146. return (HANDLE) BmDuplicate ((HBITMAP)hSrc, NULL, NULL);
  147. if (cfFormat == CF_PALETTE)
  148. return (HANDLE) UtDupPalette ((HPALETTE)hSrc);
  149. if (uiFlags == NULL)
  150. uiFlags = GMEM_MOVEABLE;
  151. if (cfFormat == CF_METAFILEPICT) {
  152. HANDLE hDst;
  153. LPMETAFILEPICT lpmfpSrc;
  154. LPMETAFILEPICT lpmfpDst;
  155. if (!(lpmfpSrc = (LPMETAFILEPICT) GlobalLock (hSrc)))
  156. return NULL;
  157. if (!(hDst = UtDupGlobal (hSrc, uiFlags)))
  158. return NULL;
  159. if (!(lpmfpDst = (LPMETAFILEPICT) GlobalLock (hDst))) {
  160. GlobalFree (hDst);
  161. return NULL;
  162. }
  163. *lpmfpDst = *lpmfpSrc;
  164. lpmfpDst->hMF = CopyMetaFile (lpmfpSrc->hMF, NULL);
  165. GlobalUnlock (hSrc);
  166. GlobalUnlock (hDst);
  167. return hDst;
  168. } else {
  169. return UtDupGlobal (hSrc, uiFlags);
  170. }
  171. }
  172. //+---------------------------------------------------------------------------
  173. //
  174. // Function: SetBitOleStg, private
  175. //
  176. // Synopsis: Sets bit in ole stream; doc bit preserved even when stream
  177. // rewritten above; the value written is (old & mask) | value.
  178. //
  179. // Arguments: [pstg] - Storage
  180. // [mask] - Mask
  181. // [value] - Value
  182. //
  183. // Returns: Appropriate status code
  184. //
  185. // History: 11-Mar-94 DrewB Created
  186. //
  187. // Notes: Taken straight from OLE2 source
  188. //
  189. //----------------------------------------------------------------------------
  190. static INTERNAL SetBitOleStg(LPSTORAGE pstg, DWORD mask, DWORD value)
  191. {
  192. IStream FAR * pstm = NULL;
  193. HRESULT error;
  194. DWORD objflags = 0;
  195. LARGE_INTEGER large_integer;
  196. ULONG cbRead;
  197. VDATEIFACE( pstg );
  198. if (error = pstg->OpenStream(OLE_STREAM, NULL, STGM_SALL, 0, &pstm))
  199. {
  200. if (STG_E_FILENOTFOUND != GetScode(error))
  201. {
  202. goto errRtn;
  203. }
  204. if (error = pstg->CreateStream(OLE_STREAM, STGM_SALL, 0, 0, &pstm))
  205. {
  206. goto errRtn;
  207. }
  208. DWORD dwBuf[5];
  209. dwBuf[0] = gdwOleVersion;
  210. dwBuf[1] = objflags;
  211. dwBuf[2] = 0L;
  212. dwBuf[3] = 0L;
  213. dwBuf[4] = 0L;
  214. if ((error = pstm->Write(dwBuf, 5*sizeof(DWORD), NULL)) != NOERROR)
  215. {
  216. goto errRtn;
  217. }
  218. }
  219. // seek directly to word, read, modify, seek back and write.
  220. LISet32( large_integer, sizeof(DWORD) );
  221. if ((error = pstm->Seek(large_integer, STREAM_SEEK_SET, NULL)) != NOERROR)
  222. {
  223. goto errRtn;
  224. }
  225. if ((error = pstm->Read(&objflags, sizeof(objflags), &cbRead)) != NOERROR)
  226. {
  227. goto errRtn;
  228. }
  229. if (cbRead != sizeof(objflags))
  230. {
  231. goto errRtn;
  232. }
  233. objflags = (objflags & mask) | value;
  234. LISet32( large_integer, sizeof(DWORD) );
  235. if ((error = pstm->Seek(large_integer, STREAM_SEEK_SET, NULL)) != NOERROR)
  236. {
  237. goto errRtn;
  238. }
  239. error = pstm->Write(&objflags, sizeof(DWORD), NULL);
  240. errRtn:
  241. // close and return error code.
  242. if (pstm)
  243. {
  244. pstm->Release();
  245. }
  246. return error;
  247. }
  248. //+---------------------------------------------------------------------------
  249. //
  250. // Function: GetFlagsOleStg, private
  251. //
  252. // Synopsis: Return long word of flags from the ole stream
  253. //
  254. // Arguments: [pstg] - Storage
  255. // [lpobjflags] - Flags return
  256. //
  257. // Returns: Appropriate status code
  258. //
  259. // Modifies: [lpobjflags]
  260. //
  261. // History: 11-Mar-94 DrewB Created
  262. //
  263. // Notes: Taken straight from OLE2 source
  264. //
  265. //----------------------------------------------------------------------------
  266. static INTERNAL GetFlagsOleStg(LPSTORAGE pstg, LPDWORD lpobjflags)
  267. {
  268. IStream FAR * pstm = NULL;
  269. HRESULT error;
  270. LARGE_INTEGER large_integer;
  271. ULONG cbRead;
  272. VDATEIFACE( pstg );
  273. if ((error = pstg->OpenStream(OLE_STREAM, NULL,
  274. (STGM_READ | STGM_SHARE_EXCLUSIVE),
  275. 0, &pstm)) != NOERROR)
  276. {
  277. goto errRtn;
  278. }
  279. // seek directly to word, read, modify, seek back and write.
  280. LISet32( large_integer, sizeof(DWORD) );
  281. if ((error = pstm->Seek(large_integer, STREAM_SEEK_SET, NULL)) != NOERROR)
  282. {
  283. goto errRtn;
  284. }
  285. error = pstm->Read(lpobjflags, sizeof(*lpobjflags), &cbRead);
  286. if (SUCCEEDED(GetScode(error)) && cbRead != sizeof(*lpobjflags))
  287. {
  288. error = ResultFromScode(STG_E_READFAULT);
  289. }
  290. errRtn:
  291. // close and return error NOERROR (document)/S_FALSE (embedding);
  292. if (pstm)
  293. {
  294. pstm->Release();
  295. }
  296. return error == NOERROR ? NOERROR : ReportResult(0, S_FALSE, 0, 0);
  297. }
  298. //+---------------------------------------------------------------------------
  299. //
  300. // Function: GetDocumentBitStg, semi-private
  301. //
  302. // Synopsis: Get doc bit; return NOERROR if on; S_FALSE if off
  303. //
  304. // Arguments: [pStg] - Storage
  305. //
  306. // Returns: Appropriate status code
  307. //
  308. // History: 11-Mar-94 DrewB Created
  309. //
  310. // Notes: Taken straight from OLE2 source
  311. //
  312. //----------------------------------------------------------------------------
  313. STDAPI GetDocumentBitStg(LPSTORAGE pStg)
  314. {
  315. DWORD objflags;
  316. HRESULT error;
  317. if ((error = GetFlagsOleStg(pStg, &objflags)) != NOERROR)
  318. {
  319. return error;
  320. }
  321. return (objflags&OBJFLAGS_DOCUMENT) ? NOERROR : ResultFromScode(S_FALSE);
  322. }
  323. //+---------------------------------------------------------------------------
  324. //
  325. // Function: SetDocumentBitStg, semi-private
  326. //
  327. // Synopsis: Set doc bit according to fDocument
  328. //
  329. // Arguments: [pStg] - Storage
  330. // [fDocument] - Document flag
  331. //
  332. // Returns: Appropriate status code
  333. //
  334. // History: 11-Mar-94 DrewB Created
  335. //
  336. // Notes: Taken straight from OLE2 source
  337. //
  338. //----------------------------------------------------------------------------
  339. STDAPI SetDocumentBitStg(LPSTORAGE pStg, BOOL fDocument)
  340. {
  341. return SetBitOleStg(pStg, fDocument ? -1L : ~OBJFLAGS_DOCUMENT,
  342. fDocument ? OBJFLAGS_DOCUMENT : 0);
  343. }
  344. //+---------------------------------------------------------------------------
  345. //
  346. // Function: ReleaseStgMedium, public
  347. //
  348. // History: 18-Mar-94 Taken straight from OLE2 source
  349. //
  350. //----------------------------------------------------------------------------
  351. STDAPI_(void) ReleaseStgMedium(LPSTGMEDIUM pMedium)
  352. {
  353. if (pMedium)
  354. {
  355. //VDATEPTRIN rejects NULL
  356. VOID_VDATEPTRIN( pMedium, STGMEDIUM );
  357. BOOL fPunkRel = pMedium->pUnkForRelease != NULL;
  358. switch (pMedium->tymed)
  359. {
  360. case TYMED_HGLOBAL:
  361. if (pMedium->hGlobal != NULL && !fPunkRel)
  362. Verify(GlobalFree(pMedium->hGlobal) == 0);
  363. break;
  364. case TYMED_GDI:
  365. if (pMedium->hGlobal != NULL && !fPunkRel)
  366. DeleteObject(pMedium->hGlobal);
  367. break;
  368. case TYMED_MFPICT:
  369. if (pMedium->hGlobal != NULL && !fPunkRel)
  370. {
  371. LPMETAFILEPICT pmfp;
  372. if ((pmfp = (LPMETAFILEPICT)GlobalLock(pMedium->hGlobal)) ==
  373. NULL)
  374. break;
  375. DeleteMetaFile(pmfp->hMF);
  376. GlobalUnlock(pMedium->hGlobal);
  377. Verify(GlobalFree(pMedium->hGlobal) == 0);
  378. }
  379. break;
  380. case TYMED_FILE:
  381. if (pMedium->lpszFileName != NULL)
  382. {
  383. if (!IsValidPtrIn(pMedium->lpszFileName, 1))
  384. break;
  385. if (!fPunkRel)
  386. {
  387. OFSTRUCT of;
  388. OpenFile(pMedium->lpszFileName, &of, OF_DELETE);
  389. }
  390. delete pMedium->lpszFileName;
  391. }
  392. break;
  393. case TYMED_ISTREAM:
  394. if (pMedium->pstm != NULL &&
  395. IsValidInterface(pMedium->pstm))
  396. pMedium->pstm->Release();
  397. break;
  398. case TYMED_ISTORAGE:
  399. if (pMedium->pstg != NULL &&
  400. IsValidInterface(pMedium->pstg))
  401. pMedium->pstg->Release();
  402. break;
  403. case TYMED_NULL:
  404. break;
  405. default:
  406. thkAssert(!"Invalid medium in ReleaseStgMedium");
  407. }
  408. // NULL out to prevent unwanted use of just freed data
  409. pMedium->tymed = TYMED_NULL;
  410. if (pMedium->pUnkForRelease)
  411. {
  412. if (IsValidInterface(pMedium->pUnkForRelease))
  413. pMedium->pUnkForRelease->Release();
  414. pMedium->pUnkForRelease = NULL;
  415. }
  416. }
  417. }
  418. //+---------------------------------------------------------------------------
  419. //
  420. // Function: OleDoAutoConvert, local
  421. //
  422. // Synopsis: Taken from ole32 code
  423. //
  424. // History: 06-Oct-94 DrewB Created
  425. //
  426. // Notes: This routine must be local because it can return
  427. // information through pClsidNew even when it is
  428. // returning an error
  429. //
  430. //----------------------------------------------------------------------------
  431. STDAPI OleDoAutoConvert(LPSTORAGE pStg, LPCLSID pClsidNew)
  432. {
  433. HRESULT error;
  434. CLSID clsidOld;
  435. CLIPFORMAT cfOld;
  436. LPSTR lpszOld = NULL;
  437. LPSTR lpszNew = NULL;
  438. LPMALLOC pma;
  439. if ((error = ReadClassStg(pStg, &clsidOld)) != NOERROR)
  440. {
  441. clsidOld = CLSID_NULL;
  442. goto errRtn;
  443. }
  444. if ((error = OleGetAutoConvert(clsidOld, pClsidNew)) != NOERROR)
  445. {
  446. goto errRtn;
  447. }
  448. // read old fmt/old user type; sets out params to NULL on error
  449. error = ReadFmtUserTypeStg(pStg, &cfOld, &lpszOld);
  450. Assert(error == NOERROR || (cfOld == NULL && lpszOld == NULL));
  451. // get new user type name; if error, set to NULL string
  452. if ((error = OleRegGetUserType(*pClsidNew, USERCLASSTYPE_FULL,
  453. &lpszNew)) != NOERROR)
  454. {
  455. lpszNew = NULL;
  456. }
  457. // write class stg
  458. if ((error = WriteClassStg(pStg, *pClsidNew)) != NOERROR)
  459. {
  460. goto errRtn;
  461. }
  462. // write old fmt/new user type;
  463. if ((error = WriteFmtUserTypeStg(pStg, cfOld, lpszNew)) != NOERROR)
  464. {
  465. goto errRewriteInfo;
  466. }
  467. // set convert bit
  468. if ((error = SetConvertStg(pStg, TRUE)) != NOERROR)
  469. {
  470. goto errRewriteInfo;
  471. }
  472. goto okRtn;
  473. errRewriteInfo:
  474. (void)WriteClassStg(pStg, clsidOld);
  475. (void)WriteFmtUserTypeStg(pStg, cfOld, lpszOld);
  476. errRtn:
  477. *pClsidNew = clsidOld;
  478. okRtn:
  479. if (CoGetMalloc(MEMCTX_TASK, &pma) == NOERROR)
  480. {
  481. pma->Free(lpszOld);
  482. pma->Free(lpszNew);
  483. pma->Release();
  484. }
  485. return error;
  486. }
  487. /****** Other API defintions **********************************************/
  488. //+---------------------------------------------------------------------------
  489. //
  490. // Function: Utility functions not in the spec; in ole2.dll.
  491. //
  492. // History: 20-Apr-94 DrewB Taken from OLE2 sources
  493. //
  494. //----------------------------------------------------------------------------
  495. #define AVERAGE_STR_SIZE 64
  496. FARINTERNAL_(HRESULT) StRead (IStream FAR * lpstream, LPVOID lpBuf, ULONG ulLen)
  497. {
  498. HRESULT error;
  499. ULONG cbRead;
  500. if ((error = lpstream->Read( lpBuf, ulLen, &cbRead)) != NOERROR)
  501. return error;
  502. return ((cbRead != ulLen) ? ResultFromScode(STG_E_READFAULT) : NOERROR);
  503. }
  504. // returns S_OK when string read and allocated (even if zero length)
  505. OLEAPI ReadStringStream( LPSTREAM pstm, LPSTR FAR * ppsz )
  506. {
  507. ULONG cb;
  508. HRESULT hresult;
  509. *ppsz = NULL;
  510. if ((hresult = StRead(pstm, (void FAR *)&cb, sizeof(ULONG))) != NOERROR)
  511. return hresult;
  512. if (cb == NULL)
  513. // NULL string case
  514. return NOERROR;
  515. if ((LONG)cb < 0 || cb > INT_MAX)
  516. // out of range
  517. return ReportResult(0, E_UNSPEC, 0, 0);
  518. if (!(*ppsz = new FAR char[(int)cb]))
  519. return ReportResult(0, E_OUTOFMEMORY, 0, 0);
  520. if ((hresult = StRead(pstm, (void FAR *)(*ppsz), cb)) != NOERROR)
  521. goto errRtn;
  522. return NOERROR;
  523. errRtn:
  524. delete *ppsz;
  525. *ppsz = NULL;
  526. return hresult;
  527. }
  528. OLEAPI WriteStringStream(LPSTREAM pstm, LPCSTR psz)
  529. {
  530. HRESULT error;
  531. ULONG cb = NULL;
  532. if (psz) {
  533. cb = 1 + _fstrlen(psz);
  534. // if possible, do a single write instead of two
  535. if (cb <= AVERAGE_STR_SIZE-4) {
  536. char szBuf[AVERAGE_STR_SIZE];
  537. *((ULONG FAR*) szBuf) = cb;
  538. lstrcpy(szBuf+sizeof(ULONG), psz);
  539. return pstm->Write((VOID FAR *)szBuf, cb+sizeof(ULONG), NULL);
  540. }
  541. }
  542. if (error = pstm->Write((VOID FAR *)&cb, sizeof(ULONG), NULL))
  543. return error;
  544. if (psz == NULL)
  545. // we are done writing the string
  546. return NOERROR;
  547. return pstm->Write((VOID FAR *)psz, cb, NULL);
  548. }
  549. OLEAPI OpenOrCreateStream( IStorage FAR * pstg, char const FAR * pwcsName,
  550. IStream FAR* FAR* ppstm)
  551. {
  552. HRESULT error;
  553. error = pstg->CreateStream(pwcsName,
  554. STGM_SALL | STGM_FAILIFTHERE, 0, 0, ppstm);
  555. if (GetScode(error) == STG_E_FILEALREADYEXISTS)
  556. error = pstg->OpenStream(pwcsName, NULL, STGM_SALL, 0, ppstm);
  557. return error;
  558. }