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.

454 lines
13 KiB

  1. //
  2. // Mime stuff used by shell32/shdocvw/shdoc401
  3. //
  4. #include "priv.h"
  5. #define TF_MIME 0
  6. /*----------------------------------------------------------
  7. Purpose: Generates the HKEY_CLASSES_ROOT subkey for a MIME
  8. type
  9. Returns:
  10. Cond: --
  11. */
  12. STDAPI_(BOOL) GetMIMETypeSubKeyA(LPCSTR pcszMIMEType, LPSTR pszSubKeyBuf, UINT cchBuf)
  13. {
  14. BOOL bResult;
  15. bResult = ((UINT)lstrlenA(TEXT("MIME\\Database\\Content Type\\")) +
  16. (UINT)lstrlenA(pcszMIMEType) < cchBuf);
  17. if (bResult)
  18. {
  19. StringCchPrintfA(pszSubKeyBuf, cchBuf, TEXT("MIME\\Database\\Content Type\\%s"), pcszMIMEType);
  20. }
  21. else
  22. {
  23. if (cchBuf > 0)
  24. *pszSubKeyBuf = '\0';
  25. TraceMsg(TF_WARNING, "GetMIMETypeSubKey(): Given sub key buffer of length %u is too short to hold sub key for MIME type %hs.",
  26. cchBuf, pcszMIMEType);
  27. }
  28. ASSERT(! cchBuf ||
  29. (IS_VALID_STRING_PTRA(pszSubKeyBuf, -1) &&
  30. (UINT)lstrlenA(pszSubKeyBuf) < cchBuf));
  31. ASSERT(bResult ||
  32. ! cchBuf ||
  33. ! *pszSubKeyBuf);
  34. return(bResult);
  35. }
  36. STDAPI_(BOOL) GetMIMETypeSubKeyW(LPCWSTR pszMIMEType, LPWSTR pszBuf, UINT cchBuf)
  37. {
  38. BOOL bRet;
  39. char szMIMEType[MAX_PATH];
  40. char sz[MAX_PATH];
  41. ASSERT(IS_VALID_STRING_PTRW(pszMIMEType, -1));
  42. WideCharToMultiByte(CP_ACP, 0, pszMIMEType, -1, szMIMEType, SIZECHARS(szMIMEType), NULL, NULL);
  43. bRet = GetMIMETypeSubKeyA(szMIMEType, sz, SIZECHARS(sz));
  44. if (bRet)
  45. {
  46. ASSERT(cchBuf <= SIZECHARS(sz));
  47. MultiByteToWideChar(CP_ACP, 0, sz, -1, pszBuf, cchBuf);
  48. }
  49. return bRet;
  50. }
  51. /*
  52. ** RegisterExtensionForMIMEType()
  53. **
  54. ** Under HKEY_CLASSES_ROOT\MIME\Database\Content Type\mime/type, add
  55. ** Content Type = mime/type and Extension = .ext.
  56. **
  57. */
  58. STDAPI_(BOOL) RegisterExtensionForMIMETypeA(LPCSTR pcszExtension, LPCSTR pcszMIMEContentType)
  59. {
  60. BOOL bResult;
  61. CHAR szMIMEContentTypeSubKey[MAX_PATH];
  62. ASSERT(IS_VALID_STRING_PTRA(pcszExtension, -1));
  63. ASSERT(IS_VALID_STRING_PTRA(pcszMIMEContentType, -1));
  64. ASSERT(IsValidExtensionA(pcszExtension));
  65. bResult = GetMIMETypeSubKeyA(pcszMIMEContentType, szMIMEContentTypeSubKey,
  66. SIZECHARS(szMIMEContentTypeSubKey));
  67. if (bResult)
  68. {
  69. /* (+ 1) for null terminator. */
  70. bResult = (NO_ERROR == SHSetValueA(HKEY_CLASSES_ROOT, szMIMEContentTypeSubKey,
  71. "Extension", REG_SZ, pcszExtension,
  72. CbFromCchA(lstrlenA(pcszExtension) + 1)));
  73. }
  74. return(bResult);
  75. }
  76. STDAPI_(BOOL) RegisterExtensionForMIMETypeW(LPCWSTR pcszExtension, LPCWSTR pcszMIMEContentType)
  77. {
  78. BOOL bResult;
  79. WCHAR szMIMEContentTypeSubKey[MAX_PATH];
  80. ASSERT(IS_VALID_STRING_PTRW(pcszExtension, -1));
  81. ASSERT(IS_VALID_STRING_PTRW(pcszMIMEContentType, -1));
  82. ASSERT(IsValidExtensionW(pcszExtension));
  83. bResult = GetMIMETypeSubKeyW(pcszMIMEContentType, szMIMEContentTypeSubKey,
  84. SIZECHARS(szMIMEContentTypeSubKey));
  85. if (bResult)
  86. {
  87. /* (+ 1) for null terminator. */
  88. bResult = (NO_ERROR == SHSetValueW(HKEY_CLASSES_ROOT, szMIMEContentTypeSubKey,
  89. TEXTW("Extension"), REG_SZ, pcszExtension,
  90. (lstrlenW(pcszExtension) + 1)*sizeof(WCHAR)));
  91. }
  92. return(bResult);
  93. }
  94. /*
  95. ** UnregisterExtensionForMIMEType()
  96. **
  97. ** Deletes Extension under
  98. ** HKEY_CLASSES_ROOT\MIME\Database\Content Type\mime/type. If no other values
  99. ** or sub keys are left, deletes
  100. ** HKEY_CLASSES_ROOT\MIME\Database\Content Type\mime/type.
  101. **
  102. ** Side Effects: May also delete MIME key.
  103. */
  104. STDAPI_(BOOL) UnregisterExtensionForMIMETypeA(LPCSTR pcszMIMEContentType)
  105. {
  106. BOOL bResult;
  107. CHAR szMIMEContentTypeSubKey[MAX_PATH];
  108. ASSERT(IS_VALID_STRING_PTRA(pcszMIMEContentType, -1));
  109. bResult = (GetMIMETypeSubKeyA(pcszMIMEContentType, szMIMEContentTypeSubKey,
  110. SIZECHARS(szMIMEContentTypeSubKey)) &&
  111. NO_ERROR == SHDeleteValueA(HKEY_CLASSES_ROOT, szMIMEContentTypeSubKey,
  112. "Extension") &&
  113. NO_ERROR == SHDeleteEmptyKeyA(HKEY_CLASSES_ROOT, szMIMEContentTypeSubKey));
  114. return(bResult);
  115. }
  116. STDAPI_(BOOL) UnregisterExtensionForMIMETypeW(LPCWSTR pcszMIMEContentType)
  117. {
  118. BOOL bResult;
  119. WCHAR szMIMEContentTypeSubKey[MAX_PATH];
  120. ASSERT(IS_VALID_STRING_PTRW(pcszMIMEContentType, -1));
  121. bResult = (GetMIMETypeSubKeyW(pcszMIMEContentType, szMIMEContentTypeSubKey,
  122. SIZECHARS(szMIMEContentTypeSubKey)) &&
  123. NO_ERROR == SHDeleteValueW(HKEY_CLASSES_ROOT, szMIMEContentTypeSubKey,
  124. TEXTW("Extension")) &&
  125. NO_ERROR == SHDeleteEmptyKeyW(HKEY_CLASSES_ROOT, szMIMEContentTypeSubKey));
  126. return(bResult);
  127. }
  128. /*
  129. ** UnregisterMIMETypeForExtension()
  130. **
  131. ** Deletes Content Type under HKEY_CLASSES_ROOT\.ext.
  132. **
  133. ** Side Effects: none
  134. */
  135. STDAPI_(BOOL) UnregisterMIMETypeForExtensionA(LPCSTR pcszExtension)
  136. {
  137. ASSERT(IS_VALID_STRING_PTRA(pcszExtension, -1));
  138. ASSERT(IsValidExtensionA(pcszExtension));
  139. return NO_ERROR == SHDeleteValueA(HKEY_CLASSES_ROOT, pcszExtension, "Content Type");
  140. }
  141. STDAPI_(BOOL) UnregisterMIMETypeForExtensionW(LPCWSTR pcszExtension)
  142. {
  143. ASSERT(IS_VALID_STRING_PTRW(pcszExtension, -1));
  144. ASSERT(IsValidExtensionW(pcszExtension));
  145. return NO_ERROR == SHDeleteValueW(HKEY_CLASSES_ROOT, pcszExtension, TEXTW("Content Type"));
  146. }
  147. /*
  148. ** RegisterMIMETypeForExtension()
  149. **
  150. ** Under HKEY_CLASSES_ROOT\.ext, add Content Type = mime/type.
  151. **
  152. ** Arguments:
  153. **
  154. ** Returns:
  155. **
  156. ** Side Effects: none
  157. */
  158. STDAPI_(BOOL) RegisterMIMETypeForExtensionA(LPCSTR pcszExtension, LPCSTR pcszMIMEContentType)
  159. {
  160. ASSERT(IS_VALID_STRING_PTRA(pcszExtension, -1));
  161. ASSERT(IS_VALID_STRING_PTRA(pcszMIMEContentType, -1));
  162. ASSERT(IsValidExtensionA(pcszExtension));
  163. /* (+ 1) for null terminator. */
  164. return NO_ERROR == SHSetValueA(HKEY_CLASSES_ROOT, pcszExtension, "Content Type",
  165. REG_SZ, pcszMIMEContentType,
  166. CbFromCchA(lstrlenA(pcszMIMEContentType) + 1));
  167. }
  168. STDAPI_(BOOL) RegisterMIMETypeForExtensionW(LPCWSTR pcszExtension, LPCWSTR pcszMIMEContentType)
  169. {
  170. ASSERT(IS_VALID_STRING_PTRW(pcszExtension, -1));
  171. ASSERT(IS_VALID_STRING_PTRW(pcszMIMEContentType, -1));
  172. ASSERT(IsValidExtensionW(pcszExtension));
  173. /* (+ 1) for null terminator. */
  174. return NO_ERROR == SHSetValueW(HKEY_CLASSES_ROOT, pcszExtension, TEXTW("Content Type"),
  175. REG_SZ, pcszMIMEContentType,
  176. (lstrlenW(pcszMIMEContentType) + 1) * sizeof(WCHAR));
  177. }
  178. /*
  179. ** GetMIMEValue()
  180. **
  181. ** Retrieves the data for a value of a MIME type.
  182. **
  183. ** Arguments:
  184. **
  185. ** Returns:
  186. **
  187. ** Side Effects: none
  188. */
  189. STDAPI_(BOOL) GetMIMEValueA(LPCSTR pcszMIMEType, LPCSTR pcszValue,
  190. PDWORD pdwValueType, PBYTE pbyteValueBuf,
  191. PDWORD pdwcbValueBufLen)
  192. {
  193. BOOL bResult;
  194. CHAR szMIMETypeSubKey[MAX_PATH];
  195. ASSERT(IS_VALID_STRING_PTRA(pcszMIMEType, -1));
  196. ASSERT(! pcszValue ||
  197. IS_VALID_STRING_PTRA(pcszValue, -1));
  198. ASSERT(IS_VALID_WRITE_PTR(pdwValueType, DWORD));
  199. ASSERT(IS_VALID_WRITE_BUFFER(pbyteValueBuf, BYTE, *pdwcbValueBufLen));
  200. bResult = (GetMIMETypeSubKeyA(pcszMIMEType, szMIMETypeSubKey,SIZECHARS(szMIMETypeSubKey)) &&
  201. NO_ERROR == SHGetValueA(HKEY_CLASSES_ROOT, szMIMETypeSubKey,
  202. pcszValue, pdwValueType, pbyteValueBuf,
  203. pdwcbValueBufLen));
  204. return(bResult);
  205. }
  206. STDAPI_(BOOL) GetMIMEValueW(LPCWSTR pcszMIMEType, LPCWSTR pcszValue,
  207. PDWORD pdwValueType, PBYTE pbyteValueBuf,
  208. PDWORD pdwcbValueBufLen)
  209. {
  210. BOOL bResult;
  211. WCHAR szMIMETypeSubKey[MAX_PATH];
  212. ASSERT(IS_VALID_STRING_PTRW(pcszMIMEType, -1));
  213. ASSERT(! pcszValue ||
  214. IS_VALID_STRING_PTRW(pcszValue, -1));
  215. ASSERT(IS_VALID_WRITE_PTR(pdwValueType, DWORD));
  216. ASSERT(IS_VALID_WRITE_BUFFER(pbyteValueBuf, BYTE, *pdwcbValueBufLen));
  217. bResult = (GetMIMETypeSubKeyW(pcszMIMEType, szMIMETypeSubKey,SIZECHARS(szMIMETypeSubKey)) &&
  218. NO_ERROR == SHGetValueW(HKEY_CLASSES_ROOT, szMIMETypeSubKey,
  219. pcszValue, pdwValueType, pbyteValueBuf,
  220. pdwcbValueBufLen));
  221. return(bResult);
  222. }
  223. /*
  224. ** GetMIMETypeStringValue()
  225. **
  226. ** Retrieves the string for a registered MIME type's value.
  227. **
  228. ** Arguments:
  229. **
  230. ** Returns:
  231. **
  232. ** Side Effects: none
  233. */
  234. STDAPI_(BOOL) GetMIMETypeStringValueA(LPCSTR pcszMIMEType, LPCSTR pcszValue,
  235. LPSTR pszBuf, UINT ucBufLen)
  236. {
  237. BOOL bResult;
  238. DWORD dwValueType;
  239. DWORD dwcbLen = CbFromCchA(ucBufLen);
  240. /* GetMIMEValue() will verify parameters. */
  241. bResult = (GetMIMEValueA(pcszMIMEType, pcszValue, &dwValueType, (PBYTE)pszBuf, &dwcbLen) &&
  242. dwValueType == REG_SZ);
  243. if (! bResult)
  244. {
  245. if (ucBufLen > 0)
  246. *pszBuf = '\0';
  247. }
  248. ASSERT(! ucBufLen || IS_VALID_STRING_PTRA(pszBuf, -1));
  249. return(bResult);
  250. }
  251. STDAPI_(BOOL) GetMIMETypeStringValueW(LPCWSTR pcszMIMEType, LPCWSTR pcszValue,
  252. LPWSTR pszBuf, UINT ucBufLen)
  253. {
  254. BOOL bResult;
  255. DWORD dwValueType;
  256. DWORD dwcbLen = CbFromCchW(ucBufLen);
  257. /* GetMIMEValue() will verify parameters. */
  258. bResult = (GetMIMEValueW(pcszMIMEType, pcszValue, &dwValueType, (PBYTE)pszBuf, &dwcbLen) &&
  259. dwValueType == REG_SZ);
  260. if (! bResult)
  261. {
  262. if (ucBufLen > 0)
  263. *pszBuf = '\0';
  264. }
  265. ASSERT(! ucBufLen || IS_VALID_STRING_PTRW(pszBuf, -1));
  266. return(bResult);
  267. }
  268. /*
  269. ** MIME_GetExtension()
  270. **
  271. ** Determines the file name extension to be used when writing a file of a MIME
  272. ** type to the file system.
  273. **
  274. ** Arguments:
  275. **
  276. ** Returns:
  277. **
  278. ** Side Effects: none
  279. */
  280. STDAPI_(BOOL) MIME_GetExtensionA(LPCSTR pcszMIMEType, LPSTR pszExtensionBuf, UINT ucExtensionBufLen)
  281. {
  282. BOOL bResult = FALSE;
  283. ASSERT(IS_VALID_STRING_PTRA(pcszMIMEType, -1));
  284. ASSERT(IS_VALID_WRITE_BUFFER(pszExtensionBuf, CHAR, ucExtensionBufLen));
  285. if (EVAL(ucExtensionBufLen > 2))
  286. {
  287. /* Leave room for possible leading period. */
  288. if (GetMIMETypeStringValueA(pcszMIMEType, "Extension", pszExtensionBuf + 1, ucExtensionBufLen - 1))
  289. {
  290. if (pszExtensionBuf[1])
  291. {
  292. /* Prepend period if necessary. */
  293. if (pszExtensionBuf[1] == TEXT('.'))
  294. /* (+ 1) for null terminator. */
  295. MoveMemory(pszExtensionBuf, pszExtensionBuf + 1,
  296. CbFromCchA(lstrlenA(pszExtensionBuf + 1) + 1));
  297. else
  298. pszExtensionBuf[0] = TEXT('.');
  299. bResult = TRUE;
  300. }
  301. }
  302. }
  303. if (! bResult)
  304. {
  305. if (ucExtensionBufLen > 0)
  306. *pszExtensionBuf = '\0';
  307. }
  308. if (bResult)
  309. TraceMsgA(TF_MIME, "MIME_GetExtension(): Extension %s registered as default extension for MIME type %s.",
  310. pszExtensionBuf, pcszMIMEType);
  311. ASSERT((bResult &&
  312. IsValidExtensionA(pszExtensionBuf)) ||
  313. (! bResult &&
  314. (! ucExtensionBufLen ||
  315. ! *pszExtensionBuf)));
  316. ASSERT(! ucExtensionBufLen ||
  317. (UINT)lstrlenA(pszExtensionBuf) < ucExtensionBufLen);
  318. return(bResult);
  319. }
  320. STDAPI_(BOOL) MIME_GetExtensionW(LPCWSTR pcszMIMEType, LPWSTR pszExtensionBuf, UINT ucExtensionBufLen)
  321. {
  322. BOOL bResult = FALSE;
  323. ASSERT(IS_VALID_STRING_PTRW(pcszMIMEType, -1));
  324. ASSERT(IS_VALID_WRITE_BUFFER(pszExtensionBuf, CHAR, ucExtensionBufLen));
  325. if (EVAL(ucExtensionBufLen > 2))
  326. {
  327. /* Leave room for possible leading period. */
  328. if (GetMIMETypeStringValueW(pcszMIMEType, TEXTW("Extension"), pszExtensionBuf + 1, ucExtensionBufLen - 1))
  329. {
  330. if (pszExtensionBuf[1])
  331. {
  332. /* Prepend period if necessary. */
  333. if (pszExtensionBuf[1] == TEXT('.'))
  334. /* (+ 1) for null terminator. */
  335. MoveMemory(pszExtensionBuf, pszExtensionBuf + 1,
  336. CbFromCchW(lstrlenW(pszExtensionBuf + 1) + 1));
  337. else
  338. pszExtensionBuf[0] = TEXT('.');
  339. bResult = TRUE;
  340. }
  341. }
  342. }
  343. if (! bResult)
  344. {
  345. if (ucExtensionBufLen > 0)
  346. *pszExtensionBuf = '\0';
  347. }
  348. if (bResult)
  349. TraceMsgW(TF_MIME, "MIME_GetExtension(): Extension %s registered as default extension for MIME type %s.",
  350. pszExtensionBuf, pcszMIMEType);
  351. ASSERT((bResult &&
  352. IsValidExtensionW(pszExtensionBuf)) ||
  353. (! bResult &&
  354. (! ucExtensionBufLen ||
  355. ! *pszExtensionBuf)));
  356. ASSERT(! ucExtensionBufLen ||
  357. (UINT)lstrlenW(pszExtensionBuf) < ucExtensionBufLen);
  358. return(bResult);
  359. }