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.

456 lines
9.3 KiB

  1. #include "stdafx.h"
  2. #include "imgutil.h"
  3. #include "resource.h"
  4. #include "cmapmime.h"
  5. CMapStringToCLSID* g_pDefaultMappings = NULL;
  6. BOOL g_bDefaultMappingsInitialized = FALSE;
  7. CRITICAL_SECTION g_csDefaultMappings;
  8. const LPCTSTR MIME_DATABASE_ROOT = _T( "MIME\\Database\\Content Type" );
  9. int UNICODEstrlen(LPCTSTR psz)
  10. {
  11. const TCHAR *p;
  12. for (p = psz; *p; ++p)
  13. ;
  14. return (int)(p - psz);
  15. }
  16. HRESULT InitDefaultMappings()
  17. {
  18. HRESULT hResult;
  19. LONG nResult;
  20. HKEY hKey;
  21. ULONG iSubkey;
  22. HKEY hSubkey;
  23. BOOL bDone;
  24. ULONG nNameLength;
  25. TCHAR szKeyName[MAX_PATH+1];
  26. CMapStringToCLSID* pMapping;
  27. FILETIME time;
  28. InitializeCriticalSection( &g_csDefaultMappings );
  29. nResult = RegOpenKeyEx( HKEY_CLASSES_ROOT, MIME_DATABASE_ROOT, 0, KEY_READ,
  30. &hKey );
  31. if( nResult != ERROR_SUCCESS )
  32. {
  33. return( E_FAIL );
  34. }
  35. iSubkey = 0;
  36. bDone = FALSE;
  37. while( !bDone )
  38. {
  39. nNameLength = sizeof( szKeyName )/sizeof( *szKeyName );
  40. nResult = RegEnumKeyEx( hKey, iSubkey, szKeyName, &nNameLength, NULL,
  41. NULL, NULL, &time );
  42. if( (nResult != ERROR_SUCCESS) && (nResult != ERROR_NO_MORE_ITEMS) )
  43. {
  44. RegCloseKey( hKey );
  45. return( E_FAIL );
  46. }
  47. if( nResult == ERROR_SUCCESS )
  48. {
  49. nResult = RegOpenKeyEx( hKey, szKeyName, 0, KEY_READ, &hSubkey );
  50. if( nResult != ERROR_SUCCESS )
  51. {
  52. RegCloseKey( hKey );
  53. return( E_FAIL );
  54. }
  55. pMapping = new CMapStringToCLSID;
  56. if( pMapping == NULL )
  57. {
  58. return( E_OUTOFMEMORY );
  59. }
  60. hResult = pMapping->InitFromKey( hSubkey, szKeyName );
  61. if( SUCCEEDED( hResult ) )
  62. {
  63. pMapping->m_pNext = g_pDefaultMappings;
  64. g_pDefaultMappings = pMapping;
  65. }
  66. else
  67. {
  68. delete pMapping;
  69. }
  70. RegCloseKey( hSubkey );
  71. }
  72. else
  73. {
  74. bDone = TRUE;
  75. }
  76. iSubkey++;
  77. }
  78. return( S_OK );
  79. }
  80. void CleanupDefaultMappings()
  81. {
  82. CMapStringToCLSID* pKill;
  83. EnterCriticalSection( &g_csDefaultMappings );
  84. while( g_pDefaultMappings != NULL )
  85. {
  86. pKill = g_pDefaultMappings;
  87. g_pDefaultMappings = g_pDefaultMappings->m_pNext;
  88. delete pKill;
  89. }
  90. LeaveCriticalSection( &g_csDefaultMappings );
  91. DeleteCriticalSection( &g_csDefaultMappings );
  92. }
  93. static HRESULT DefaultMapMIMEToCLSID( LPCTSTR pszMIMEType, CLSID* pCLSID )
  94. {
  95. CMapStringToCLSID* pTrav;
  96. BOOL bFound;
  97. _ASSERTE( pszMIMEType != NULL );
  98. _ASSERTE( pCLSID != NULL );
  99. *pCLSID = CLSID_NULL;
  100. EnterCriticalSection( &g_csDefaultMappings );
  101. bFound = FALSE;
  102. pTrav = g_pDefaultMappings;
  103. while( (pTrav != NULL) && !bFound )
  104. {
  105. if( lstrcmp( pszMIMEType, pTrav->GetString() ) == 0 )
  106. {
  107. *pCLSID = pTrav->GetCLSID();
  108. bFound = TRUE;
  109. }
  110. pTrav = pTrav->m_pNext;
  111. }
  112. LeaveCriticalSection( &g_csDefaultMappings );
  113. if( IsEqualCLSID( *pCLSID, CLSID_NULL ) )
  114. {
  115. return( S_FALSE );
  116. }
  117. else
  118. {
  119. return( S_OK );
  120. }
  121. }
  122. CMapStringToCLSID::CMapStringToCLSID() :
  123. m_pNext( NULL ),
  124. m_pszString( NULL ),
  125. m_clsid( CLSID_NULL ),
  126. m_dwMapMode( MAPMIME_DEFAULT )
  127. {
  128. memcpy( m_achSignature, "NoLK", 4 );
  129. }
  130. CMapStringToCLSID::~CMapStringToCLSID()
  131. {
  132. delete m_pszString;
  133. }
  134. const CLSID& CMapStringToCLSID::GetCLSID() const
  135. {
  136. return( m_clsid );
  137. }
  138. DWORD CMapStringToCLSID::GetMapMode() const
  139. {
  140. return( m_dwMapMode );
  141. }
  142. LPCTSTR CMapStringToCLSID::GetString() const
  143. {
  144. _ASSERTE( m_pszString != NULL );
  145. return( m_pszString );
  146. }
  147. HRESULT CMapStringToCLSID::InitFromKey( HKEY hKey, LPCTSTR pszKeyName )
  148. {
  149. LONG nResult;
  150. HRESULT hResult;
  151. DWORD dwValueType;
  152. BYTE* pData;
  153. ULONG nBytes = 0;
  154. CLSID clsid;
  155. USES_CONVERSION;
  156. nResult = RegQueryValueEx( hKey, _T( "Image Filter CLSID" ), NULL,
  157. &dwValueType, NULL, &nBytes );
  158. if( (nResult != ERROR_SUCCESS) || (dwValueType != REG_SZ) || nBytes > 8192 )
  159. {
  160. return( E_FAIL );
  161. }
  162. pData = LPBYTE( _alloca( nBytes ) );
  163. nResult = RegQueryValueEx( hKey, _T( "Image Filter CLSID" ), NULL,
  164. &dwValueType, pData, &nBytes );
  165. if( nResult != ERROR_SUCCESS )
  166. {
  167. return( E_FAIL );
  168. }
  169. hResult = SetString( pszKeyName );
  170. if( FAILED( hResult ) )
  171. {
  172. return( hResult );
  173. }
  174. CLSIDFromString( T2OLE( LPTSTR( pData ) ), &clsid );
  175. SetCLSID( clsid );
  176. return( S_OK );
  177. }
  178. void CMapStringToCLSID::SetCLSID( REFGUID clsid )
  179. {
  180. m_clsid = clsid;
  181. }
  182. void CMapStringToCLSID::SetMapMode( DWORD dwMapMode )
  183. {
  184. m_dwMapMode = dwMapMode;
  185. }
  186. HRESULT CMapStringToCLSID::SetString( LPCTSTR pszString )
  187. {
  188. _ASSERTE( m_pszString == NULL );
  189. m_pszString = new TCHAR[UNICODEstrlen( pszString )+1];
  190. if( m_pszString == NULL )
  191. {
  192. return( E_OUTOFMEMORY );
  193. }
  194. lstrcpy( m_pszString, pszString );
  195. return( S_OK );
  196. }
  197. CMapMIMEToCLSID::CMapMIMEToCLSID() :
  198. m_nMappings( 0 ),
  199. m_pMappings( NULL ),
  200. m_bEnableDefaultMappings( TRUE )
  201. {
  202. }
  203. CMapMIMEToCLSID::~CMapMIMEToCLSID()
  204. {
  205. CMapStringToCLSID* pKill;
  206. while( m_pMappings != NULL )
  207. {
  208. pKill = m_pMappings;
  209. m_pMappings = m_pMappings->m_pNext;
  210. delete pKill;
  211. }
  212. }
  213. CMapStringToCLSID* CMapMIMEToCLSID::FindMapping( LPCTSTR pszMIMEType )
  214. {
  215. CMapStringToCLSID* pMapping;
  216. pMapping = m_pMappings;
  217. while( pMapping != NULL )
  218. {
  219. if( lstrcmp( pMapping->GetString(), pszMIMEType ) == 0 )
  220. {
  221. return( pMapping );
  222. }
  223. pMapping = pMapping->m_pNext;
  224. }
  225. return( NULL );
  226. }
  227. CMapStringToCLSID* CMapMIMEToCLSID::AddMapping( LPCTSTR pszMIMEType )
  228. {
  229. CMapStringToCLSID* pMapping;
  230. HRESULT hResult;
  231. pMapping = new CMapStringToCLSID;
  232. if( pMapping == NULL )
  233. {
  234. return( NULL );
  235. }
  236. hResult = pMapping->SetString( pszMIMEType );
  237. if( FAILED( hResult ) )
  238. {
  239. delete pMapping;
  240. return( NULL );
  241. }
  242. pMapping->m_pNext = m_pMappings;
  243. m_pMappings = pMapping;
  244. m_nMappings++;
  245. return( pMapping );
  246. }
  247. void CMapMIMEToCLSID::DeleteMapping( LPCTSTR pszMIMEType )
  248. {
  249. CMapStringToCLSID* pMapping;
  250. CMapStringToCLSID* pFollow;
  251. pFollow = NULL;
  252. pMapping = m_pMappings;
  253. while( pMapping != NULL )
  254. {
  255. if( lstrcmp( pMapping->GetString(), pszMIMEType ) == 0 )
  256. {
  257. if( pFollow == NULL )
  258. {
  259. m_pMappings = pMapping->m_pNext;
  260. }
  261. else
  262. {
  263. pFollow->m_pNext = pMapping->m_pNext;
  264. }
  265. delete pMapping;
  266. m_nMappings--;
  267. return;
  268. }
  269. pFollow = pMapping;
  270. pMapping = pMapping->m_pNext;
  271. }
  272. }
  273. STDMETHODIMP CMapMIMEToCLSID::SetMapping( LPCOLESTR pszMIMEType,
  274. DWORD dwMapMode, REFGUID clsid )
  275. {
  276. USES_CONVERSION;
  277. CMapStringToCLSID* pMapping;
  278. LPCTSTR pszMIMETypeT;
  279. if( pszMIMEType == NULL )
  280. {
  281. return( E_INVALIDARG );
  282. }
  283. if( dwMapMode > MAPMIME_DEFAULT_ALWAYS )
  284. {
  285. return( E_INVALIDARG );
  286. }
  287. pszMIMETypeT = OLE2CT( pszMIMEType );
  288. if( dwMapMode == MAPMIME_DEFAULT )
  289. {
  290. DeleteMapping( pszMIMETypeT );
  291. }
  292. else
  293. {
  294. pMapping = FindMapping( pszMIMETypeT );
  295. if( pMapping == NULL )
  296. {
  297. pMapping = AddMapping( pszMIMETypeT );
  298. if( pMapping == NULL )
  299. {
  300. return( E_OUTOFMEMORY );
  301. }
  302. }
  303. pMapping->SetMapMode( dwMapMode );
  304. if( dwMapMode == MAPMIME_CLSID )
  305. {
  306. pMapping->SetCLSID( clsid );
  307. }
  308. }
  309. return( S_OK );
  310. }
  311. STDMETHODIMP CMapMIMEToCLSID::EnableDefaultMappings( BOOL bEnable )
  312. {
  313. m_bEnableDefaultMappings = bEnable;
  314. return( S_OK );
  315. }
  316. STDMETHODIMP CMapMIMEToCLSID::MapMIMEToCLSID( LPCOLESTR pszMIMEType,
  317. GUID* pCLSID )
  318. {
  319. USES_CONVERSION;
  320. LPCTSTR pszMIMETypeT;
  321. DWORD dwMapMode;
  322. GUID clsid = CLSID_NULL;
  323. CMapStringToCLSID* pMapping;
  324. HRESULT hResult;
  325. if( pCLSID != NULL )
  326. {
  327. *pCLSID = CLSID_NULL;
  328. }
  329. if( pszMIMEType == NULL )
  330. {
  331. return( E_INVALIDARG );
  332. }
  333. if( pCLSID == NULL )
  334. {
  335. return( E_POINTER );
  336. }
  337. pszMIMETypeT = OLE2CT( pszMIMEType );
  338. pMapping = FindMapping( pszMIMETypeT );
  339. if( pMapping != NULL )
  340. {
  341. dwMapMode = pMapping->GetMapMode();
  342. if( dwMapMode == MAPMIME_CLSID )
  343. {
  344. clsid = pMapping->GetCLSID();
  345. }
  346. }
  347. else
  348. {
  349. dwMapMode = MAPMIME_DEFAULT;
  350. }
  351. switch( dwMapMode )
  352. {
  353. case MAPMIME_DEFAULT:
  354. if( m_bEnableDefaultMappings )
  355. {
  356. hResult = DefaultMapMIMEToCLSID( pszMIMETypeT, &clsid );
  357. }
  358. else
  359. {
  360. hResult = S_FALSE;
  361. }
  362. break;
  363. case MAPMIME_DEFAULT_ALWAYS:
  364. hResult = DefaultMapMIMEToCLSID( pszMIMETypeT, &clsid );
  365. break;
  366. case MAPMIME_CLSID:
  367. hResult = S_OK;
  368. break;
  369. case MAPMIME_DISABLE:
  370. hResult = S_FALSE;
  371. break;
  372. default:
  373. _ASSERT( FALSE );
  374. hResult = E_FAIL;
  375. break;
  376. }
  377. if( hResult == S_OK )
  378. {
  379. *pCLSID = clsid;
  380. }
  381. return( hResult );
  382. }