Source code of Windows XP (NT5)
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.

272 lines
7.2 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1994 **/
  4. /**********************************************************************/
  5. /*
  6. mimemap.cxx
  7. This module contains the code for MIME to file type mappings
  8. The mime mappings are used for selecting the correct type based on file
  9. extensions and for indicating what types the server accepts.
  10. FILE HISTORY:
  11. Johnl 23-Aug-1994 Created
  12. */
  13. #include "w3p.hxx"
  14. //
  15. // Private constants.
  16. //
  17. //
  18. // Private globals.
  19. //
  20. //
  21. // Private prototypes.
  22. //
  23. BOOL
  24. SelectCustomMimeMapping(
  25. IN const CHAR *pszPath,
  26. IN STR *pstrContentType,
  27. IN CHAR *pszMimeMapping
  28. )
  29. /*++
  30. Routine Description
  31. Called when we have a configured metadata mime mapping on a directory,
  32. and want to look it up.
  33. Arguments
  34. pszPath - Path including extension to be looked up.
  35. pstrContentType - Where to return the content type.
  36. pszMimeMapping - Pointer to mime mapping string.
  37. Returns
  38. TRUE if operation successful.
  39. --*/
  40. {
  41. CHAR *pszCurrentMimeType;
  42. CHAR *pszExt;
  43. DWORD dwExtLength;
  44. BOOL bCheckingDefault;
  45. CHAR *pszLastSlash;
  46. if (pszPath == NULL)
  47. {
  48. pszExt = "*";
  49. dwExtLength = sizeof("*") - 1;
  50. bCheckingDefault = TRUE;
  51. }
  52. else
  53. {
  54. // Need to find the extension. The extension is whatever follows the
  55. // dot after the last slash in the path.
  56. // Find the last slash. If there isn't one, use the start of the path.
  57. pszLastSlash = strrchr((CHAR *)pszPath, '\\');
  58. if (pszLastSlash == NULL)
  59. {
  60. pszLastSlash = (CHAR *)pszPath;
  61. }
  62. pszExt = strrchr(pszLastSlash, '.');
  63. if (pszExt == NULL || *(pszExt+1) == '\0')
  64. {
  65. // Didn't find one, so look for the default mapping.
  66. pszExt = "*";
  67. dwExtLength = sizeof("*") - 1;
  68. bCheckingDefault = TRUE;
  69. }
  70. else
  71. {
  72. dwExtLength = strlen(pszExt);
  73. bCheckingDefault = FALSE;
  74. }
  75. }
  76. // Look at the mime type mapping string and see if we have a match. The
  77. // string was preformatted when we read the metadata, and is stored as
  78. // a set of multi-sz mime-type, .ext strings. If we're not looking for the
  79. // default, and we don't find one on the first pass, we'll try to find the
  80. // default mapping.
  81. for (;;)
  82. {
  83. pszCurrentMimeType = pszMimeMapping;
  84. do {
  85. CHAR *pszCurrentSeparator;
  86. DWORD dwCurrentExtLength;
  87. CHAR *pszCurrentMimeString;
  88. DWORD dwCurrentMimeStringLength;
  89. // First, isolate the mime type from the extension.
  90. pszCurrentSeparator = strchr(pszCurrentMimeType, ',');
  91. // Compute the length of the extension
  92. dwCurrentExtLength = DIFF(pszCurrentSeparator - pszCurrentMimeType);
  93. // Find the mime map string, and it's length
  94. pszCurrentMimeString = pszCurrentSeparator + 1;
  95. dwCurrentMimeStringLength = strlen(pszCurrentMimeString);
  96. // We have the extension and the length, compare against the
  97. // input extension.
  98. if (dwExtLength == dwCurrentExtLength &&
  99. !_strnicmp(pszExt, pszCurrentMimeType, dwExtLength))
  100. {
  101. // Allright, we have a winner.
  102. return pstrContentType->Copy(pszCurrentMimeString,
  103. dwCurrentMimeStringLength);
  104. }
  105. // Otherwise, look at the next one.
  106. pszCurrentMimeType = pszCurrentMimeString + dwCurrentMimeStringLength + 1;
  107. } while ( *pszCurrentMimeType != '\0' );
  108. if (!bCheckingDefault)
  109. {
  110. // Look backwards for another '.' so we can support extensions
  111. // like ".xyz.xyz" or ".a.b.c".
  112. if ( pszExt > pszLastSlash )
  113. {
  114. pszExt--;
  115. while ( ( pszExt > pszLastSlash ) && ( *pszExt != '.' ) )
  116. {
  117. pszExt--;
  118. }
  119. if ( *pszExt == '.' )
  120. {
  121. dwExtLength = strlen( pszExt );
  122. continue;
  123. }
  124. }
  125. // Didn't find one, so look for the default mapping.
  126. pszExt = "*";
  127. dwExtLength = sizeof("*") - 1;
  128. bCheckingDefault = TRUE;
  129. }
  130. else
  131. {
  132. break;
  133. }
  134. }
  135. return FALSE;
  136. }
  137. /*******************************************************************
  138. NAME: SelectMimeMapping
  139. SYNOPSIS: Given a file name, this routine finds the appropriate
  140. MIME type for the name
  141. ENTRY: pstrContentType - Receives MIME type or icon file to use
  142. pszPath - Path of file being requested (extension
  143. is used for the mime mapping). Should be
  144. fully qualified and canonicalized. If NULL, then the
  145. default mapping is used
  146. mmtype - Type of data to retrieve. Can retrieve either
  147. the mime type associated with the file extension or
  148. the icon associated with the extension
  149. RETURNS: TRUE on success, FALSE on error (call GetLastError)
  150. HISTORY:
  151. Johnl 04-Sep-1994 Created
  152. ********************************************************************/
  153. BOOL SelectMimeMapping( STR * pstrContentType,
  154. const CHAR * pszPath,
  155. PW3_METADATA pMetaData,
  156. enum MIMEMAP_TYPE mmtype )
  157. {
  158. BOOL fRet = TRUE;
  159. CHAR *pszMimeMap;
  160. switch ( mmtype )
  161. {
  162. case MIMEMAP_MIME_TYPE:
  163. pszMimeMap = (CHAR *)pMetaData->QueryMimeMap()->QueryPtr();
  164. if (*pszMimeMap != '\0')
  165. {
  166. fRet = SelectCustomMimeMapping( pszPath,
  167. pstrContentType,
  168. pszMimeMap );
  169. if ( fRet )
  170. {
  171. break;
  172. }
  173. }
  174. fRet = SelectMimeMappingForFileExt( g_pInetSvc,
  175. pszPath,
  176. pstrContentType );
  177. break;
  178. case MIMEMAP_MIME_ICON:
  179. fRet = SelectMimeMappingForFileExt( g_pInetSvc,
  180. pszPath,
  181. NULL,
  182. pstrContentType );
  183. break;
  184. default:
  185. DBG_ASSERT( FALSE );
  186. SetLastError( ERROR_INVALID_PARAMETER );
  187. return FALSE;
  188. }
  189. IF_DEBUG( PARSING )
  190. {
  191. if ( mmtype == MIMEMAP_MIME_TYPE )
  192. DBGPRINTF((DBG_CONTEXT,
  193. "[SelectMimeMapping] Returning %s for extension %s\n",
  194. pstrContentType->QueryStr(),
  195. pszPath ? pszPath : TEXT("*") ));
  196. }
  197. return fRet;
  198. }
  199. //
  200. // Private functions.
  201. //
  202.