mime.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 13k
Category:

Windows Kernel

Development Platform:

Visual C++

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