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.

1224 lines
35 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: media.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 1-20-96 JohannP (Johann Posch) Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <mon.h>
  18. PerfDbgTag(tagMedia, "Urlmon", "Log Media methods", DEB_FORMAT);
  19. PerfDbgTag(tagMediaApi, "Urlmon", "Log Media API", DEB_ASYNCAPIS);
  20. #if 1
  21. CHAR vszTextPlain[] = "text/plain";
  22. CHAR vszTextRichText[] = "text/richtext";
  23. CHAR vszImageXBitmap[] = "image/x-xbitmap";
  24. CHAR vszApplicationPostscript[] = "application/postscript";
  25. CHAR vszApplicationBase64[] = "application/base64";
  26. CHAR vszApplicationMacBinhex[] = "application/macbinhex40";
  27. CHAR vszApplicationPdf[] = "application/pdf";
  28. CHAR vszAudioAiff[] = "audio/x-aiff";
  29. CHAR vszAudioBasic[] = "audio/basic";
  30. CHAR vszAudioWav[] = "audio/wav";
  31. CHAR vszImageGif[] = "image/gif";
  32. CHAR vszImagePJpeg[] = "image/pjpeg";
  33. CHAR vszImageJpeg[] = "image/jpeg";
  34. CHAR vszImageTiff[] = "image/tiff";
  35. CHAR vszImagePng[] = "image/x-png";
  36. CHAR vszImagePng2[] = "image/png";
  37. CHAR vszImageBmp[] = "image/bmp";
  38. CHAR vszImageJG[] = "image/x-jg";
  39. CHAR vszImageArt[] = "image/x-art";
  40. CHAR vszImageEmf[] = "image/x-emf";
  41. CHAR vszImageWmf[] = "image/x-wmf";
  42. CHAR vszVideoAvi[] = "video/avi";
  43. CHAR vszVideoMS[] = "video/x-msvideo";
  44. CHAR vszVideoMpeg[] = "video/mpeg";
  45. CHAR vszApplicationCompressed[] = "application/x-compressed";
  46. CHAR vszApplicationZipCompressed[] = "application/x-zip-compressed";
  47. CHAR vszApplicationGzipCompressed[] = "application/x-gzip-compressed";
  48. CHAR vszApplicationMSDownload[] = "application/x-msdownload";
  49. CHAR vszApplicationJava[] = "application/java";
  50. CHAR vszApplicationOctetStream[] = "application/octet-stream";
  51. CHAR vszTextHTML[] = "text/html";
  52. CHAR vszApplicationCDF[] = "application/x-cdf";
  53. CHAR vszApplicationCommonDataFormat[] = "application/x-netcdf";
  54. CHAR vszTextScriptlet[] = "text/scriptlet";
  55. #endif
  56. const GUID IID_IMediaHolder = {0x79eac9ce, 0xbaf9, 0x11ce, {0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b}};
  57. #define XCLSID_MsHtml {0x25336920, 0x03F9, 0x11cf, {0x8F, 0xD0, 0x00, 0xAA, 0x00, 0x68, 0x6F, 0x13}}
  58. #define XCLSID_CDFVIEW {0xf39a0dc0, 0x9cc8, 0x11d0, {0xa5, 0x99, 0x0, 0xc0, 0x4f, 0xd6, 0x44, 0x33}}
  59. BOOL g_fDefaultMediaRegistered = FALSE;
  60. static MediaInfo rgMediaInfo[] =
  61. {
  62. { vszTextHTML , 0, DATAFORMAT_TEXTORBINARY, XCLSID_MsHtml, 0x00000070 ,0 ,CLSCTX_INPROC }
  63. ,{ vszTextPlain , 0, DATAFORMAT_AMBIGUOUS, {0} ,0 ,0 ,0 }
  64. ,{ vszTextRichText , 0, DATAFORMAT_TEXT, {0} ,0 ,0 ,0 }
  65. ,{ vszImageXBitmap , 0, DATAFORMAT_TEXT, {0} ,0 ,0 ,0 }
  66. ,{ vszApplicationPostscript , 0, DATAFORMAT_TEXT, {0} ,0 ,0 ,0 }
  67. ,{ vszApplicationBase64 , 0, DATAFORMAT_TEXT, {0} ,0 ,0 ,0 }
  68. ,{ vszApplicationMacBinhex , 0, DATAFORMAT_TEXT, {0} ,0 ,0 ,0 }
  69. ,{ vszApplicationPdf , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  70. ,{ vszAudioAiff , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  71. ,{ vszAudioBasic , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  72. ,{ vszAudioWav , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  73. ,{ vszImageGif , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  74. ,{ vszImagePJpeg , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  75. ,{ vszImageJpeg , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  76. ,{ vszImageTiff , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  77. ,{ vszImagePng , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  78. ,{ vszImagePng2 , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  79. ,{ vszImageBmp , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  80. ,{ vszImageJG , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  81. ,{ vszImageArt , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  82. ,{ vszImageEmf , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  83. ,{ vszImageWmf , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  84. ,{ vszVideoAvi , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  85. ,{ vszVideoMS , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  86. ,{ vszVideoMpeg , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  87. ,{ vszApplicationCompressed , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  88. ,{ vszApplicationZipCompressed , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  89. ,{ vszApplicationGzipCompressed , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  90. ,{ vszApplicationJava , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  91. ,{ vszApplicationMSDownload , 0, DATAFORMAT_BINARY, {0} ,0 ,0 ,0 }
  92. ,{ vszApplicationOctetStream , 0, DATAFORMAT_AMBIGUOUS, {0} ,0 ,0 ,0 }
  93. ,{ vszApplicationCDF , 0, DATAFORMAT_TEXT, XCLSID_CDFVIEW ,(MI_GOTCLSID | MI_CLASSLOOKUP) ,0 ,CLSCTX_INPROC }
  94. ,{ vszApplicationCommonDataFormat , 0, DATAFORMAT_AMBIGUOUS, {0} ,0 ,0 ,0 }
  95. ,{ vszTextScriptlet , 0, DATAFORMAT_TEXT, {0} ,0 ,0 ,0 }
  96. };
  97. CMediaTypeHolder *g_pCMHolder = NULL;
  98. //+---------------------------------------------------------------------------
  99. //
  100. // Function: GetMediaTypeHolder
  101. //
  102. // Synopsis: Retrieves the media type holder for this apartment
  103. //
  104. // Arguments: (none)
  105. //
  106. // Returns:
  107. //
  108. // History: 1-20-96 JohannP (Johann Posch) Created
  109. //
  110. // Notes:
  111. //
  112. //----------------------------------------------------------------------------
  113. CMediaTypeHolder *GetMediaTypeHolder()
  114. {
  115. PerfDbgLog(tagMediaApi, NULL, "+GetMediaTypeHolder");
  116. #ifdef PER_THREAD
  117. CUrlMkTls tls;
  118. CMediaTypeHolder *pCMHolder;
  119. if ((pCMHolder = tls->pCMediaHolder) == NULL)
  120. {
  121. tls->pCMediaHolder = pCMHolder = new CMediaTypeHolder();
  122. }
  123. #else
  124. CLock lck(g_mxsMedia);
  125. if (g_pCMHolder == NULL)
  126. {
  127. g_pCMHolder = new CMediaTypeHolder();
  128. }
  129. #endif //PER_THREAD
  130. PerfDbgLog1(tagMediaApi, NULL, "-GetMediaTypeHolder (pCMHolder:%lx)", g_pCMHolder);
  131. return g_pCMHolder;
  132. }
  133. void CMediaType::Initialize(LPSTR szType, CLIPFORMAT cfFormat)
  134. {
  135. _pszType = szType;
  136. _cfFormat = cfFormat;
  137. }
  138. void CMediaType::Initialize(CLIPFORMAT cfFormat, CLSID *pClsID)
  139. {
  140. _pszType = NULL;
  141. _cfFormat = cfFormat;
  142. _clsID = *pClsID;
  143. _dwInitFlags |= MI_GOTCLSID;
  144. }
  145. CMediaTypeHolder::CMediaTypeHolder() : _CRefs()
  146. {
  147. _pCMTNode = NULL;
  148. }
  149. CMediaTypeHolder::~CMediaTypeHolder()
  150. {
  151. CMediaTypeNode *pCMTNode, *pNext;
  152. pCMTNode = _pCMTNode;
  153. // Delete everything that was allocated by Register.
  154. while (pCMTNode)
  155. {
  156. pNext = pCMTNode->GetNextNode();
  157. delete pCMTNode;
  158. pCMTNode = pNext;
  159. }
  160. _pCMTNode = NULL;
  161. }
  162. //+---------------------------------------------------------------------------
  163. //
  164. // Method: CMediaTypeHolder::RegisterW
  165. //
  166. // Synopsis:
  167. //
  168. // Arguments: [ctypes] --
  169. // [rgszTypes] --
  170. // [rgcfTypes] --
  171. //
  172. // Returns:
  173. //
  174. // History: 3-22-96 JohannP (Johann Posch) Created
  175. //
  176. // Notes:
  177. //
  178. //----------------------------------------------------------------------------
  179. HRESULT CMediaTypeHolder::RegisterW(UINT ctypes, const LPCWSTR* rgszTypes, CLIPFORMAT* rgcfTypes)
  180. {
  181. PerfDbgLog(tagMedia, this, "+CMediaTypeHolder::Register");
  182. HRESULT hr = NOERROR;
  183. UINT i;
  184. if (ctypes)
  185. {
  186. ULONG ulSize;
  187. LPCWSTR pwzStr;
  188. LPSTR pszStr;
  189. LPSTR pszHelp;
  190. LPSTR pszTextBuffer;
  191. CMediaType *pCMType;
  192. CMediaTypeNode *pCMTNode;
  193. // Calculate size of single buffer needed to hold all strings.
  194. for (ulSize = i = 0; i < ctypes; i++)
  195. {
  196. pwzStr = *(rgszTypes + i);
  197. ulSize += wcslen(pwzStr) + 1;
  198. //PerfDbgLog2(tagMedia, this, "CMTHolder::Register(sz:%ws; len:%ld)", pszStr, ulSize));
  199. }
  200. pszTextBuffer = pszStr = new CHAR[ulSize];
  201. if (!pszTextBuffer)
  202. {
  203. hr = E_OUTOFMEMORY;
  204. goto RegisterExit;
  205. }
  206. pCMType = new CMediaType[ctypes];
  207. if (!pCMType)
  208. {
  209. delete pszTextBuffer;
  210. hr = E_OUTOFMEMORY;
  211. goto RegisterExit;
  212. }
  213. pCMTNode = new CMediaTypeNode(pCMType, pszTextBuffer, ctypes, _pCMTNode);
  214. if (!pCMTNode)
  215. {
  216. delete pCMType;
  217. delete pszTextBuffer;
  218. hr = E_OUTOFMEMORY;
  219. goto RegisterExit;
  220. }
  221. pszHelp = pszStr;
  222. for (i = 0; i < ctypes; i++)
  223. {
  224. pwzStr = *(rgszTypes + i);
  225. //wcscpy(pszHelp, pszStr);
  226. W2A(pwzStr, pszHelp, wcslen(pwzStr) + 1);
  227. (pCMType + i)->Initialize(pszHelp, *(rgcfTypes + i));
  228. pszHelp += strlen(pszHelp) + 1;
  229. }
  230. // New node is first on list.
  231. _pCMTNode = pCMTNode;
  232. }
  233. RegisterExit:
  234. PerfDbgLog1(tagMedia, this, "-CMediaTypeHolder::Register (hr:%lx)", hr);
  235. return hr;
  236. }
  237. //+---------------------------------------------------------------------------
  238. //
  239. // Method: CMediaTypeHolder::Register
  240. //
  241. // Synopsis:
  242. //
  243. // Arguments: [ctypes] --
  244. // [rgszTypes] --
  245. // [rgcfTypes] --
  246. //
  247. // Returns:
  248. //
  249. // History: 3-22-96 JohannP (Johann Posch) Created
  250. //
  251. // Notes:
  252. //
  253. //----------------------------------------------------------------------------
  254. HRESULT CMediaTypeHolder::Register(UINT ctypes, const LPCSTR* rgszTypes, CLIPFORMAT* rgcfTypes)
  255. {
  256. PerfDbgLog(tagMedia, this, "+CMediaTypeHolder::Register");
  257. HRESULT hr = NOERROR;
  258. UINT i;
  259. if (ctypes)
  260. {
  261. ULONG ulSize;
  262. LPCSTR pszStr;
  263. LPSTR pszNewStr;
  264. LPSTR pszHelp;
  265. LPSTR pszTextBuffer;
  266. CMediaType *pCMType;
  267. CMediaTypeNode *pCMTNode;
  268. // Calculate size of single buffer needed to hold all strings.
  269. for (ulSize = i = 0; i < ctypes; i++)
  270. {
  271. pszStr = *(rgszTypes + i);
  272. ulSize += strlen(pszStr) + 1;
  273. //PerfDbgLog2(tagMedia, this, "CMTHolder::Register(sz:%s; len:%ld)", pszStr, ulSize));
  274. }
  275. pszTextBuffer = pszNewStr = new CHAR[ulSize];
  276. if (!pszTextBuffer)
  277. {
  278. hr = E_OUTOFMEMORY;
  279. goto RegisterExit;
  280. }
  281. pCMType = new CMediaType[ctypes];
  282. if (!pCMType)
  283. {
  284. delete pszTextBuffer;
  285. hr = E_OUTOFMEMORY;
  286. goto RegisterExit;
  287. }
  288. pCMTNode = new CMediaTypeNode(pCMType, pszTextBuffer, ctypes, _pCMTNode);
  289. if (!pCMTNode)
  290. {
  291. delete pCMType;
  292. delete pszTextBuffer;
  293. hr = E_OUTOFMEMORY;
  294. goto RegisterExit;
  295. }
  296. pszHelp = pszNewStr;
  297. for (i = 0; i < ctypes; i++)
  298. {
  299. pszStr = *(rgszTypes + i);
  300. StrNCpy(pszHelp, pszStr, strlen(pszStr) + 1);
  301. *(rgcfTypes + i) = (CLIPFORMAT) RegisterClipboardFormat(pszStr);
  302. (pCMType + i)->Initialize(pszHelp, *(rgcfTypes + i));
  303. pszHelp += strlen(pszHelp) + 1;
  304. }
  305. // New node is first on list.
  306. if (!_pCMTNode)
  307. {
  308. _pCMTNode = pCMTNode;
  309. }
  310. else
  311. {
  312. CMediaTypeNode *pCMTNext = _pCMTNode->GetNextNode();
  313. _pCMTNode->SetNextNode(pCMTNode);
  314. pCMTNode->SetNextNode(pCMTNext);
  315. }
  316. }
  317. RegisterExit:
  318. PerfDbgLog1(tagMedia, this, "-CMediaTypeHolder::Register (hr:%lx)", hr);
  319. return hr;
  320. }
  321. //+---------------------------------------------------------------------------
  322. //
  323. // Method: CMediaTypeHolder::Register
  324. //
  325. // Synopsis:
  326. //
  327. // Arguments: [ctypes] --
  328. // [rgszTypes] --
  329. // [rgcfTypes] --
  330. //
  331. // Returns:
  332. //
  333. // History: 3-22-96 JohannP (Johann Posch) Created
  334. //
  335. // Notes:
  336. //
  337. //----------------------------------------------------------------------------
  338. HRESULT CMediaTypeHolder::RegisterMediaInfo(UINT ctypes, MediaInfo *pMediaInfo, BOOL fFree)
  339. {
  340. PerfDbgLog(tagMedia, this, "+CMediaTypeHolder::RegisterMediaInfo");
  341. HRESULT hr = NOERROR;
  342. UINT i;
  343. if (ctypes)
  344. {
  345. CMediaType *pCMType;
  346. CMediaTypeNode *pCMTNode;
  347. // Calculate size of single buffer needed to hold all strings.
  348. pCMType = (CMediaType *)pMediaInfo;
  349. if (!pCMType)
  350. {
  351. goto RegisterExit;
  352. }
  353. pCMTNode = new CMediaTypeNode(pCMType, NULL, ctypes, _pCMTNode, FALSE);
  354. if (!pCMTNode)
  355. {
  356. hr = E_OUTOFMEMORY;
  357. goto RegisterExit;
  358. }
  359. for (i = 0; i < ctypes; i++)
  360. {
  361. CMediaType *pCMT = (pCMType + i);
  362. CLIPFORMAT cf = (CLIPFORMAT) RegisterClipboardFormat(pCMT->GetTypeString());
  363. pCMT->SetClipFormat(cf);
  364. }
  365. // New node is first on list.
  366. _pCMTNode = pCMTNode;
  367. }
  368. RegisterExit:
  369. PerfDbgLog1(tagMedia, this, "-CMediaTypeHolder::RegisterMediaInfo (hr:%lx)", hr);
  370. return hr;
  371. }
  372. //+---------------------------------------------------------------------------
  373. //
  374. // Method: CMediaTypeHolder::FindCMediaType
  375. //
  376. // Synopsis:
  377. //
  378. // Arguments: [pszMimeStr] --
  379. // [ppCMType] --
  380. //
  381. // Returns:
  382. //
  383. // History: 3-26-96 JohannP (Johann Posch) Created
  384. //
  385. // Notes:
  386. //
  387. //----------------------------------------------------------------------------
  388. HRESULT CMediaTypeHolder::FindCMediaType(CLIPFORMAT cfFormat, CMediaType **ppCMType)
  389. {
  390. PerfDbgLog(tagMedia, this, "+CMediaTypeHolder::FindCMediaType");
  391. HRESULT hr = E_INVALIDARG;
  392. CMediaTypeNode *pCMTNode;
  393. CMediaType *pCMType;
  394. UINT i;
  395. UrlMkAssert((ppCMType));
  396. *ppCMType = NULL;
  397. pCMTNode = _pCMTNode;
  398. if (!pCMTNode)
  399. {
  400. hr = E_FAIL;
  401. }
  402. else while (pCMTNode)
  403. {
  404. pCMType = pCMTNode->GetMediaTypeArray();
  405. for (i = 0; i < pCMTNode->GetElementCount(); i++)
  406. {
  407. if (cfFormat == (pCMType + i)->GetClipFormat())
  408. {
  409. *ppCMType = pCMType + i;
  410. hr = NOERROR;
  411. break;
  412. }
  413. }
  414. if (*ppCMType)
  415. {
  416. break;
  417. }
  418. pCMTNode = pCMTNode->GetNextNode();
  419. }
  420. PerfDbgLog1(tagMedia, this, "-CMediaTypeHolder::FindCMediaType (hr:%lx)", hr);
  421. return hr;
  422. }
  423. //+---------------------------------------------------------------------------
  424. //
  425. // Method: CMediaTypeHolder::FindCMediaType
  426. //
  427. // Synopsis:
  428. //
  429. // Arguments: [pszMimeStr] --
  430. // [ppCMType] --
  431. //
  432. // Returns:
  433. //
  434. // History: 3-28-96 JohannP (Johann Posch) Created
  435. //
  436. // Notes:
  437. //
  438. //----------------------------------------------------------------------------
  439. HRESULT CMediaTypeHolder::FindCMediaType(LPCSTR pszMimeStr, CMediaType **ppCMType)
  440. {
  441. PerfDbgLog(tagMedia, this, "+CMediaTypeHolder::FindCMediaType");
  442. HRESULT hr = E_INVALIDARG;
  443. CMediaTypeNode *pCMTNode;
  444. CMediaType *pCMType;
  445. UINT i;
  446. *ppCMType = NULL;
  447. pCMTNode = _pCMTNode;
  448. if (!pCMTNode)
  449. {
  450. hr = E_FAIL;
  451. }
  452. else while (pCMTNode)
  453. {
  454. pCMType = pCMTNode->GetMediaTypeArray();
  455. for (i = 0; i < pCMTNode->GetElementCount(); i++)
  456. {
  457. if (!stricmp(pszMimeStr, (pCMType + i)->GetTypeString()))
  458. {
  459. *ppCMType = pCMType + i;
  460. hr = NOERROR;
  461. break;
  462. }
  463. }
  464. if (*ppCMType)
  465. {
  466. break;
  467. }
  468. pCMTNode = pCMTNode->GetNextNode();
  469. }
  470. PerfDbgLog1(tagMedia, this, "-CMediaTypeHolder::FindCMediaType (hr:%lx)", hr);
  471. return hr;
  472. }
  473. //+---------------------------------------------------------------------------
  474. //
  475. // Method: CMediaTypeHolder::QueryInterface
  476. //
  477. // Synopsis:
  478. //
  479. // Arguments: [riid] --
  480. // [ppv] --
  481. //
  482. // Returns:
  483. //
  484. // History: 11-11-95 JohannP (Johann Posch) Created
  485. //
  486. // Notes:
  487. //
  488. //----------------------------------------------------------------------------
  489. STDMETHODIMP CMediaTypeHolder::QueryInterface( REFIID riid, void **ppv )
  490. {
  491. HRESULT hr = NOERROR;
  492. PerfDbgLog2(tagMedia, this, "+CMediaTypeHolder::QueryInterface (%lx, %lx)", riid, ppv);
  493. if ( IsEqualIID(riid, IID_IUnknown)
  494. || IsEqualIID(riid, IID_IMediaHolder))
  495. {
  496. *ppv = (void FAR *)this;
  497. AddRef();
  498. }
  499. else
  500. {
  501. *ppv = NULL;
  502. hr = E_NOINTERFACE;
  503. }
  504. PerfDbgLog2(tagMedia, this, "-CMediaTypeHolder::QueryInterface (%lx)[%lx]", hr, *ppv);
  505. return hr;
  506. }
  507. //+---------------------------------------------------------------------------
  508. //
  509. // Method: CMediaTypeHolder::AddRef
  510. //
  511. // Synopsis:
  512. //
  513. // Arguments: [void] --
  514. //
  515. // Returns:
  516. //
  517. // History: 11-11-95 JohannP (Johann Posch) Created
  518. //
  519. // Notes:
  520. //
  521. //----------------------------------------------------------------------------
  522. STDMETHODIMP_(ULONG) CMediaTypeHolder::AddRef( void )
  523. {
  524. LONG lRet = _CRefs++;
  525. PerfDbgLog1(tagMedia, this, "CMediaTypeHolder::AddRef (%ld)", lRet);
  526. return lRet;
  527. }
  528. //+---------------------------------------------------------------------------
  529. //
  530. // Method: CMediaTypeHolder::Release
  531. //
  532. // Synopsis:
  533. //
  534. // Arguments: [void] --
  535. //
  536. // Returns:
  537. //
  538. // History: 11-11-95 JohannP (Johann Posch) Created
  539. //
  540. // Notes:
  541. //
  542. //----------------------------------------------------------------------------
  543. STDMETHODIMP_(ULONG) CMediaTypeHolder::Release( void )
  544. {
  545. PerfDbgLog(tagMedia, this, "+CMediaTypeHolder::Release");
  546. LONG lRet = --_CRefs;
  547. if (_CRefs == 0)
  548. {
  549. delete this;
  550. }
  551. PerfDbgLog1(tagMedia, this, "-CMediaTypeHolder::Release (%ld)", lRet);
  552. return lRet;
  553. }
  554. //+---------------------------------------------------------------------------
  555. //
  556. // Method: CMediaTypeHolder::RegisterClassMapping
  557. //
  558. // Synopsis: registers a class mapping for given mimes strings
  559. //
  560. // Arguments: [ctypes] --
  561. // [rgszNames] --
  562. // [rgClsIDs] --
  563. // [dwReserved] --
  564. //
  565. // Returns:
  566. //
  567. // History: 8-20-96 JohannP (Johann Posch) Created
  568. //
  569. // Notes:
  570. //
  571. //----------------------------------------------------------------------------
  572. STDMETHODIMP CMediaTypeHolder::RegisterClassMapping (DWORD ctypes, LPCSTR rgszNames[], CLSID rgClsIDs[], DWORD dwReserved)
  573. {
  574. PerfDbgLog(tagMedia, this, "+CMediaTypeHolder::RegisterClassMapping");
  575. HRESULT hr = RegisterClass(ctypes, rgszNames, rgClsIDs );
  576. PerfDbgLog1(tagMedia, this, "-CMediaTypeHolder::RegisterClassMapping (hr:%lX)", hr);
  577. return hr;
  578. }
  579. //+---------------------------------------------------------------------------
  580. //
  581. // Method: CMediaTypeHolder::FindClassMapping
  582. //
  583. // Synopsis: returns the class for a given mime if registered
  584. //
  585. // Arguments: [szMime] --
  586. // [pClassID] --
  587. // [dwReserved] --
  588. //
  589. // Returns:
  590. //
  591. // History: 8-20-96 JohannP (Johann Posch) Created
  592. //
  593. // Notes:
  594. //
  595. //----------------------------------------------------------------------------
  596. STDMETHODIMP CMediaTypeHolder::FindClassMapping(LPCSTR szMime, CLSID *pClassID, DWORD dwReserved)
  597. {
  598. PerfDbgLog(tagMedia, this, "+CMediaTypeHolder::FindClassMapping");
  599. HRESULT hr = NOERROR;
  600. CLIPFORMAT cfTypes = CF_NULL;
  601. TransAssert((pClassID));
  602. *pClassID = CLSID_NULL;
  603. cfTypes = (CLIPFORMAT) RegisterClipboardFormat(szMime);
  604. if (cfTypes != CF_NULL)
  605. {
  606. CMediaType *pCMType = NULL;
  607. hr = FindCMediaType(cfTypes, &pCMType);
  608. if (hr == NOERROR)
  609. {
  610. TransAssert((pCMType));
  611. hr = pCMType->GetClsID(pClassID);
  612. }
  613. }
  614. else
  615. {
  616. hr = E_INVALIDARG;
  617. }
  618. PerfDbgLog1(tagMedia, this, "-CMediaTypeHolder::FindClassMapping (hr:%lx)", hr);
  619. return hr;
  620. }
  621. //+---------------------------------------------------------------------------
  622. //
  623. // Method: CMediaTypeHolder::RegisterClass
  624. //
  625. // Synopsis:
  626. //
  627. // Arguments: [ctypes] --
  628. // [rgszTypes] --
  629. // [rgcfTypes] --
  630. //
  631. // Returns:
  632. //
  633. // History: 3-22-96 JohannP (Johann Posch) Created
  634. //
  635. // Notes:
  636. //
  637. //----------------------------------------------------------------------------
  638. HRESULT CMediaTypeHolder::RegisterClass(UINT ctypes, const LPCSTR* rgszTypes, CLSID *rgclsID)
  639. {
  640. PerfDbgLog(tagMedia, this, "+CMediaTypeHolder::RegisterClass");
  641. HRESULT hr = NOERROR;
  642. UINT i;
  643. if (ctypes)
  644. {
  645. ULONG ulSize;
  646. CMediaType *pCMType;
  647. CMediaTypeNode *pCMTNode;
  648. // Calculate size of single buffer needed to hold all strings.
  649. pCMType = new CMediaType[ctypes];
  650. if (!pCMType)
  651. {
  652. hr = E_OUTOFMEMORY;
  653. goto RegisterExit;
  654. }
  655. pCMTNode = new CMediaTypeNode(pCMType, NULL, ctypes, _pCMTNode);
  656. if (!pCMTNode)
  657. {
  658. delete pCMType;
  659. hr = E_OUTOFMEMORY;
  660. goto RegisterExit;
  661. }
  662. for (i = 0; i < ctypes; i++)
  663. {
  664. CLIPFORMAT cfTypes;
  665. LPCSTR pszStr = *(rgszTypes + i);
  666. cfTypes = (CLIPFORMAT) RegisterClipboardFormat(pszStr);
  667. pCMType[i].Initialize(cfTypes,(rgclsID + i));
  668. }
  669. // New node is first on list.
  670. _pCMTNode = pCMTNode;
  671. }
  672. RegisterExit:
  673. PerfDbgLog1(tagMedia, this, "-CMediaTypeHolder::RegisterClass (hr:%lx)", hr);
  674. return hr;
  675. }
  676. //+---------------------------------------------------------------------------
  677. //
  678. // Function: RegisterDefaultMediaType
  679. //
  680. // Synopsis:
  681. //
  682. // Arguments: (none)
  683. //
  684. // Returns:
  685. //
  686. // History: 3-28-96 JohannP (Johann Posch) Created
  687. //
  688. // Notes:
  689. //
  690. //----------------------------------------------------------------------------
  691. HRESULT RegisterDefaultMediaType()
  692. {
  693. PerfDbgLog(tagMediaApi, NULL, "+RegisterDefaultMediaType");
  694. HRESULT hr = InternalRegisterDefaultMediaType();
  695. PerfDbgLog(tagMediaApi, NULL, "-RegisterDefaultMediaType");
  696. return hr;
  697. }
  698. //+---------------------------------------------------------------------------
  699. //
  700. // Function: InternalRegisterDefaultMediaType
  701. //
  702. // Synopsis:
  703. //
  704. // Arguments: (none)
  705. //
  706. // Returns:
  707. //
  708. // History: 7-24-96 JohannP (Johann Posch) Created
  709. //
  710. // Notes:
  711. //
  712. //----------------------------------------------------------------------------
  713. HRESULT InternalRegisterDefaultMediaType()
  714. {
  715. HRESULT hr = NOERROR;
  716. PerfDbgLog(tagMediaApi, NULL, "+InternalRegisterDefaultMediaType");
  717. static DWORD s_dwfHonorTextPlain = 42;
  718. CLock lck(g_mxsMedia);
  719. // Provide a registry hook for enabling urlmon to honor
  720. // text/plain, rather than defer to the extension.
  721. // Previously, this was considered ambiguous due to compat
  722. // reasons with older servers sending this for unknown content types.
  723. //
  724. // TODO: Consider making this the default behavior because
  725. // other browsers (e.g. Nav 4.61) are moving in this
  726. // direction.
  727. if (s_dwfHonorTextPlain == 42)
  728. {
  729. HKEY hKey;
  730. DWORD dwType;
  731. DWORD dwSize = sizeof(s_dwfHonorTextPlain);
  732. s_dwfHonorTextPlain = 0;
  733. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_QUERY_VALUE, &hKey))
  734. {
  735. if (ERROR_SUCCESS != RegQueryValueEx(hKey, TEXT("IsTextPlainHonored"), NULL, &dwType, (LPBYTE)&s_dwfHonorTextPlain, &dwSize))
  736. s_dwfHonorTextPlain = 0;
  737. RegCloseKey(hKey);
  738. }
  739. // rgMediaInfo is a static global, so we only need to do this once.
  740. if (s_dwfHonorTextPlain)
  741. {
  742. DWORD d = 0;
  743. dwSize = sizeof(rgMediaInfo)/sizeof(MediaInfo);
  744. for (d = 0; d < dwSize; d++)
  745. {
  746. if (!lstrcmp(vszTextPlain, rgMediaInfo[d]._pszType))
  747. {
  748. rgMediaInfo[d]._dwDataFormat = DATAFORMAT_TEXTORBINARY; // remove the ambiguity
  749. break;
  750. }
  751. }
  752. }
  753. }
  754. if (g_fDefaultMediaRegistered == FALSE)
  755. {
  756. CMediaTypeHolder *pCMHolder;
  757. g_fDefaultMediaRegistered = TRUE;
  758. pCMHolder = GetMediaTypeHolder();
  759. if (pCMHolder)
  760. {
  761. DWORD dwSize =sizeof(rgMediaInfo)/sizeof(MediaInfo);
  762. hr = pCMHolder->RegisterMediaInfo(dwSize,rgMediaInfo,FALSE);
  763. }
  764. else
  765. {
  766. hr = E_OUTOFMEMORY;
  767. }
  768. }
  769. PerfDbgLog(tagMediaApi, NULL, "-InternalRegisterDefaultMediaType");
  770. return hr;
  771. }
  772. //+---------------------------------------------------------------------------
  773. //
  774. // Function: FindMediaType
  775. //
  776. // Synopsis:
  777. //
  778. // Arguments: [pwzType] --
  779. // [cfType] --
  780. //
  781. // Returns:
  782. //
  783. // History: 3-22-96 JohannP (Johann Posch) Created
  784. //
  785. // Notes:
  786. //
  787. //----------------------------------------------------------------------------
  788. HRESULT FindMediaType(LPCSTR pszType, CLIPFORMAT *cfType)
  789. {
  790. HRESULT hr = E_OUTOFMEMORY;
  791. PerfDbgLog(tagMediaApi, NULL, "+FindMediaType");
  792. CMediaTypeHolder *pCMHolder;
  793. CLock lck(g_mxsMedia);
  794. UrlMkAssert((cfType));
  795. InternalRegisterDefaultMediaType();
  796. if ((pszType == NULL) || (cfType == CF_NULL))
  797. {
  798. hr = E_INVALIDARG;
  799. }
  800. else if ((pCMHolder = GetMediaTypeHolder()) != NULL)
  801. {
  802. CMediaType *pCMType;
  803. *cfType = CF_NULL;
  804. hr = pCMHolder->FindCMediaType(pszType, &pCMType);
  805. if (hr == NOERROR)
  806. {
  807. *cfType = pCMType->GetClipFormat();
  808. }
  809. }
  810. else
  811. {
  812. hr = E_FAIL;
  813. }
  814. PerfDbgLog(tagMediaApi, NULL, "-FindMediaType");
  815. return hr;
  816. }
  817. //+---------------------------------------------------------------------------
  818. //
  819. // Function: FindMediaTypeW
  820. //
  821. // Synopsis:
  822. //
  823. // Arguments: [pwzType] --
  824. // [cfType] --
  825. //
  826. // Returns:
  827. //
  828. // History: 3-22-96 JohannP (Johann Posch) Created
  829. //
  830. // Notes:
  831. //
  832. //----------------------------------------------------------------------------
  833. HRESULT FindMediaTypeW(LPCWSTR pwzType, CLIPFORMAT *pcfType)
  834. {
  835. HRESULT hr = E_NOTIMPL;
  836. PerfDbgLog(tagMediaApi, NULL, "+FindMediaTypeW");
  837. CMediaTypeHolder *pCMHolder;
  838. CLock lck(g_mxsMedia);
  839. char szMime[SZMIMESIZE_MAX];
  840. W2A(pwzType, szMime, SZMIMESIZE_MAX);
  841. if (FindMediaType((LPCSTR)szMime,pcfType) != NOERROR)
  842. {
  843. *pcfType = (CLIPFORMAT) RegisterClipboardFormat(szMime);
  844. hr = NOERROR;
  845. }
  846. PerfDbgLog(tagMediaApi, NULL, "-FindMediaTypeW");
  847. return hr;
  848. }
  849. //+---------------------------------------------------------------------------
  850. //
  851. // Function: FindMediaString
  852. //
  853. // Synopsis:
  854. //
  855. // Arguments: [cfFormat] --
  856. // [ppStr] --
  857. //
  858. // Returns:
  859. //
  860. // History: 3-29-96 JohannP (Johann Posch) Created
  861. //
  862. // Notes:
  863. //
  864. //----------------------------------------------------------------------------
  865. HRESULT FindMediaString(CLIPFORMAT cfFormat, LPSTR *ppStr)
  866. {
  867. HRESULT hr = E_OUTOFMEMORY;
  868. PerfDbgLog1(tagMediaApi, NULL, "+FindMediaString (cfFormat:%d)", cfFormat);
  869. CMediaTypeHolder *pCMHolder;
  870. CLock lck(g_mxsMedia);
  871. UrlMkAssert((cfFormat));
  872. InternalRegisterDefaultMediaType();
  873. if ((pCMHolder = GetMediaTypeHolder()) != NULL)
  874. {
  875. CMediaType *pCMType = NULL;
  876. hr = pCMHolder->FindCMediaType(cfFormat, &pCMType);
  877. if ((hr == NOERROR) && pCMType)
  878. {
  879. *ppStr = pCMType->GetTypeString();
  880. UrlMkAssert((*ppStr));
  881. }
  882. else
  883. {
  884. hr = E_FAIL;
  885. }
  886. }
  887. else
  888. {
  889. hr = E_FAIL;
  890. }
  891. PerfDbgLog2(tagMediaApi, NULL, "-FindMediaString (clFormat:%d -> szMime:%s)",cfFormat,hr?"":*ppStr);
  892. return hr;
  893. }
  894. //+---------------------------------------------------------------------------
  895. //
  896. // Function: FindMediaTypeFormat
  897. //
  898. // Synopsis:
  899. //
  900. // Arguments: [pszType] --
  901. // [cfType] --
  902. // [pdwFormat] --
  903. //
  904. // Returns:
  905. //
  906. // History: 7-23-96 JohannP (Johann Posch) Created
  907. //
  908. // Notes:
  909. //
  910. //----------------------------------------------------------------------------
  911. HRESULT FindMediaTypeFormat(LPCWSTR pwzType, CLIPFORMAT *cfType, DWORD *pdwFormat)
  912. {
  913. HRESULT hr = E_OUTOFMEMORY;
  914. PerfDbgLog(tagMediaApi, NULL, "+FindMediaTypeFormat");
  915. CMediaTypeHolder *pCMHolder;
  916. CLock lck(g_mxsMedia);
  917. UrlMkAssert((cfType));
  918. LPSTR pszType = DupW2A(pwzType);
  919. InternalRegisterDefaultMediaType();
  920. if ((pszType == NULL) || (cfType == CF_NULL) || (!pdwFormat))
  921. {
  922. hr = E_INVALIDARG;
  923. }
  924. else if ((pCMHolder = GetMediaTypeHolder()) != NULL)
  925. {
  926. CMediaType *pCMType;
  927. *cfType = CF_NULL;
  928. hr = pCMHolder->FindCMediaType(pszType, &pCMType);
  929. if (hr == NOERROR)
  930. {
  931. *cfType = pCMType->GetClipFormat();
  932. *pdwFormat = pCMType->GetDataFormat();
  933. }
  934. }
  935. else
  936. {
  937. hr = E_FAIL;
  938. }
  939. if (pszType)
  940. {
  941. delete pszType;
  942. }
  943. PerfDbgLog4(tagMediaApi, NULL, "-FindMediaTypeFormat (hr:%lx Mime:%ws, cf:%ld, DataFormat:%ld)",
  944. hr, pwzType, cfType, *pdwFormat);
  945. return hr;
  946. }
  947. //+---------------------------------------------------------------------------
  948. //
  949. // Function: FindMediaTypeClassInfo
  950. //
  951. // Synopsis:
  952. //
  953. // Arguments: [pszType] --
  954. // [pclsid] --
  955. // [pdwClsCtx] --
  956. //
  957. // Returns:
  958. //
  959. // History: 7-23-96 JohannP (Johann Posch) Created
  960. //
  961. // Notes:
  962. //
  963. //----------------------------------------------------------------------------
  964. HRESULT FindMediaTypeClassInfo(LPCSTR pszType, LPCSTR pszFileName, LPCLSID pclsid, DWORD *pdwClsCtx, DWORD dwFlags)
  965. {
  966. HRESULT hr = E_OUTOFMEMORY;
  967. PerfDbgLog(tagMediaApi, NULL,"+FindMediaTypeClassInfo\n");
  968. CMediaTypeHolder *pCMHolder;
  969. BOOL fChecked = FALSE;
  970. CLock lck(g_mxsMedia);
  971. UrlMkAssert((pclsid));
  972. InternalRegisterDefaultMediaType();
  973. if ((pszType == NULL) || (!pclsid))
  974. {
  975. hr = E_INVALIDARG;
  976. }
  977. else if ((pCMHolder = GetMediaTypeHolder()) != NULL)
  978. {
  979. CMediaType *pCMType;
  980. *pclsid = CLSID_NULL;
  981. hr = pCMHolder->FindCMediaType(pszType, &pCMType);
  982. if ( hr == NOERROR && !(dwFlags & MIMEFLAGS_IGNOREMIME_CLASSID) )
  983. {
  984. fChecked = TRUE;
  985. hr = pCMType->GetClsID(pclsid);
  986. if (hr == NOERROR)
  987. {
  988. hr = pCMType->GetClsCtx(pdwClsCtx);
  989. if (hr != NOERROR)
  990. {
  991. hr = GetClsIDInfo(pclsid, 0, pdwClsCtx);
  992. if (hr == NOERROR)
  993. {
  994. pCMType->SetClsCtx(*pdwClsCtx);
  995. }
  996. }
  997. }
  998. else if (!pCMType->IsLookupDone())
  999. {
  1000. pCMType->SetLookupDone();
  1001. //
  1002. // find the clsid and clsctx
  1003. DWORD dwMimeFlags = 0;
  1004. hr = GetMimeInfo((LPSTR)pszType, pclsid, FALSE, &dwMimeFlags);
  1005. if (hr == NOERROR)
  1006. {
  1007. pCMType->SetMimeInfo(*pclsid, dwMimeFlags);
  1008. hr = GetClsIDInfo(pclsid, 0, pdwClsCtx);
  1009. if (hr == NOERROR)
  1010. {
  1011. pCMType->SetClsCtx(*pdwClsCtx);
  1012. }
  1013. }
  1014. // no class found yet - try the filename
  1015. if (hr != NOERROR && pszFileName)
  1016. {
  1017. WCHAR wzFileName[MAX_PATH];
  1018. A2W((LPSTR)pszFileName,wzFileName, MAX_PATH);
  1019. hr = GetClassFile(wzFileName, pclsid);
  1020. if (hr == NOERROR)
  1021. {
  1022. // do not trust filename-app/oc combination
  1023. // example: a.doc and a.xls are both marked as app/oc
  1024. if( strcmp(pszType, "application/octet-stream"))
  1025. {
  1026. // found a class for this mime
  1027. pCMType->SetMimeInfo(*pclsid, dwMimeFlags);
  1028. hr = GetClsIDInfo(pclsid, 0, pdwClsCtx);
  1029. if (hr == NOERROR)
  1030. {
  1031. pCMType->SetClsCtx(*pdwClsCtx);
  1032. }
  1033. }
  1034. else
  1035. {
  1036. pCMType->SetLookupDone(FALSE);
  1037. }
  1038. }
  1039. }
  1040. }
  1041. }
  1042. if ( (hr != NOERROR || (dwFlags & MIMEFLAGS_IGNOREMIME_CLASSID) )
  1043. && !fChecked )
  1044. {
  1045. hr = GetClassMime((LPSTR)pszType, pclsid, (dwFlags & MIMEFLAGS_IGNOREMIME_CLASSID));
  1046. }
  1047. }
  1048. else
  1049. {
  1050. hr = E_FAIL;
  1051. }
  1052. PerfDbgLog1(tagMediaApi, NULL, "-FindMediaTypeClassInfo (hr:%lx)\n",hr);
  1053. return hr;
  1054. }