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.

333 lines
9.6 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. ProtocolWrap.cpp
  5. Abstract:
  6. This file contains the implementation of the CPCHWrapProtocolInfo class,
  7. that is used to fix problems in the MS-ITS protocol.
  8. Revision History:
  9. Davide Massarenti (Dmassare) 05/07/2000
  10. created
  11. ******************************************************************************/
  12. #include "stdafx.h"
  13. static const WCHAR l_szWINDIR [] = L"%WINDIR%";
  14. static const WCHAR l_szHELP_LOCATION[] = L"%HELP_LOCATION%";
  15. /////////////////////////////////////////////////////////////////////////////
  16. CPCHWrapProtocolInfo::CPCHWrapProtocolInfo()
  17. {
  18. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::CPCHWrapProtocolInfo");
  19. // CComPtr<IClassFactory> m_realClass;
  20. // CComPtr<IInternetProtocolInfo> m_realInfo;
  21. }
  22. CPCHWrapProtocolInfo::~CPCHWrapProtocolInfo()
  23. {
  24. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::~CPCHWrapProtocolInfo");
  25. }
  26. HRESULT CPCHWrapProtocolInfo::Init( REFGUID realClass )
  27. {
  28. __HCP_FUNC_ENTRY( "CPCHWrapProtocolInfo::Init" );
  29. HRESULT hr;
  30. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoGetClassObject( realClass, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&m_realClass ));
  31. __MPC_EXIT_IF_METHOD_FAILS(hr, m_realClass->CreateInstance( NULL, IID_IInternetProtocolInfo, (void **)&m_realInfo ));
  32. hr = S_OK;
  33. __HCP_FUNC_CLEANUP;
  34. __HCP_FUNC_EXIT(hr);
  35. }
  36. ////////////////////////////////////////////////////////////////////////////////
  37. void CPCHWrapProtocolInfo::ExpandAndConcat( /*[out]*/ CComBSTR& bstrStorageName ,
  38. /*[in]*/ LPCWSTR szVariable ,
  39. /*[in]*/ LPCWSTR szAppend )
  40. {
  41. MPC::wstring strExpanded( szVariable ); MPC::SubstituteEnvVariables( strExpanded );
  42. if(szAppend)
  43. {
  44. if(szAppend[0] != '\\' &&
  45. szAppend[0] != '/' )
  46. {
  47. strExpanded += L"\\";
  48. }
  49. strExpanded += szAppend;
  50. }
  51. bstrStorageName = strExpanded.c_str();
  52. }
  53. void CPCHWrapProtocolInfo::NormalizeUrl( /*[in] */ LPCWSTR pwzUrl ,
  54. /*[out]*/ MPC::wstring& strUrlModified ,
  55. /*[in] */ bool fReverse )
  56. {
  57. CComBSTR bstrStorageName;
  58. CComBSTR bstrFilePath;
  59. bool fModified = false;
  60. SANITIZEWSTR( pwzUrl );
  61. if(MPC::MSITS::IsCHM( pwzUrl, &bstrStorageName, &bstrFilePath ) && bstrStorageName.Length() > 0)
  62. {
  63. if(!_wcsnicmp( bstrStorageName, l_szHELP_LOCATION, MAXSTRLEN( l_szHELP_LOCATION ) ))
  64. {
  65. CComBSTR bstrTmp;
  66. while(1)
  67. {
  68. LPCWSTR szRest = &bstrStorageName[ MAXSTRLEN( l_szHELP_LOCATION ) ];
  69. WCHAR rgDir[MAX_PATH];
  70. //
  71. // First, try the current help directory.
  72. //
  73. ExpandAndConcat( bstrTmp, CHCPProtocolEnvironment::s_GLOBAL->HelpLocation(), szRest );
  74. if(MPC::FileSystemObject::IsFile( bstrTmp )) break;
  75. //
  76. // Then, try the MUI version of the help directory.
  77. //
  78. _snwprintf( rgDir, MAXSTRLEN(rgDir), L"%s\\MUI\\%04lx", HC_HELPSVC_HELPFILES_DEFAULT, CHCPProtocolEnvironment::s_GLOBAL->Instance().m_ths.GetLanguage() );
  79. ExpandAndConcat( bstrTmp, rgDir, szRest );
  80. if(MPC::FileSystemObject::IsFile( bstrTmp )) break;
  81. //
  82. // Finally, try the system help directory.
  83. //
  84. ExpandAndConcat( bstrTmp, HC_HELPSVC_HELPFILES_DEFAULT, szRest );
  85. break;
  86. }
  87. if(MPC::FileSystemObject::IsFile( bstrTmp ))
  88. {
  89. bstrStorageName = bstrTmp;
  90. fModified = true;
  91. }
  92. }
  93. if(!_wcsnicmp( bstrStorageName, l_szWINDIR, MAXSTRLEN( l_szWINDIR ) ))
  94. {
  95. ExpandAndConcat( bstrStorageName, l_szWINDIR, &bstrStorageName[ MAXSTRLEN( l_szWINDIR ) ] );
  96. fModified = true;
  97. }
  98. if(::PathIsRelativeW( bstrStorageName ))
  99. {
  100. ExpandAndConcat( bstrStorageName, CHCPProtocolEnvironment::s_GLOBAL->HelpLocation(), bstrStorageName );
  101. fModified = true;
  102. }
  103. if(fReverse)
  104. {
  105. MPC::wstring strHelpLocation = CHCPProtocolEnvironment::s_GLOBAL->HelpLocation(); MPC::SubstituteEnvVariables( strHelpLocation );
  106. int iSize = strHelpLocation.size();
  107. if(!_wcsnicmp( bstrStorageName, strHelpLocation.c_str(), iSize ))
  108. {
  109. strHelpLocation = l_szHELP_LOCATION;
  110. strHelpLocation += &bstrStorageName[iSize];
  111. bstrStorageName = strHelpLocation.c_str();
  112. fModified = true;
  113. }
  114. }
  115. }
  116. if(fModified)
  117. {
  118. strUrlModified = L"MS-ITS:";
  119. strUrlModified += bstrStorageName;
  120. if(bstrFilePath.Length() > 0)
  121. {
  122. strUrlModified += L"::/";
  123. strUrlModified += bstrFilePath;
  124. }
  125. }
  126. else
  127. {
  128. strUrlModified = pwzUrl;
  129. }
  130. }
  131. /////////////////////////////////////////////////////////////////////////////
  132. STDMETHODIMP CPCHWrapProtocolInfo::CombineUrl( /*[in] */ LPCWSTR pwzBaseUrl ,
  133. /*[in] */ LPCWSTR pwzRelativeUrl,
  134. /*[in] */ DWORD dwCombineFlags,
  135. /*[out]*/ LPWSTR pwzResult ,
  136. /*[in] */ DWORD cchResult ,
  137. /*[out]*/ DWORD *pcchResult ,
  138. /*[in] */ DWORD dwReserved )
  139. {
  140. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::CombineUrl");
  141. HRESULT hr;
  142. if(MPC::MSITS::IsCHM( pwzRelativeUrl ))
  143. {
  144. MPC::wstring strUrlModified;
  145. NormalizeUrl( pwzRelativeUrl, strUrlModified, /*fReverse*/false );
  146. if(strUrlModified.size() > cchResult-1)
  147. {
  148. hr = S_FALSE;
  149. }
  150. else
  151. {
  152. wcscpy( pwzResult, strUrlModified.c_str() );
  153. hr = S_OK;
  154. }
  155. *pcchResult = strUrlModified.size()+1;
  156. }
  157. else
  158. {
  159. hr = m_realInfo->CombineUrl( pwzBaseUrl ,
  160. pwzRelativeUrl,
  161. dwCombineFlags,
  162. pwzResult ,
  163. cchResult ,
  164. pcchResult ,
  165. dwReserved );
  166. }
  167. __HCP_FUNC_EXIT(hr);
  168. }
  169. STDMETHODIMP CPCHWrapProtocolInfo::CompareUrl( /*[in]*/ LPCWSTR pwzUrl1 ,
  170. /*[in]*/ LPCWSTR pwzUrl2 ,
  171. /*[in]*/ DWORD dwCompareFlags )
  172. {
  173. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::CompareUrl");
  174. HRESULT hr;
  175. hr = m_realInfo->CompareUrl( pwzUrl1 ,
  176. pwzUrl2 ,
  177. dwCompareFlags );
  178. __HCP_FUNC_EXIT(hr);
  179. }
  180. STDMETHODIMP CPCHWrapProtocolInfo::ParseUrl( /*[in] */ LPCWSTR pwzUrl ,
  181. /*[in] */ PARSEACTION parseAction ,
  182. /*[in] */ DWORD dwParseFlags,
  183. /*[out]*/ LPWSTR pwzResult ,
  184. /*[in] */ DWORD cchResult ,
  185. /*[out]*/ DWORD *pcchResult ,
  186. /*[in] */ DWORD dwReserved )
  187. {
  188. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::ParseUrl");
  189. HRESULT hr;
  190. MPC::wstring strUrlModified;
  191. if(parseAction == PARSE_CANONICALIZE ||
  192. parseAction == PARSE_SECURITY_URL )
  193. {
  194. NormalizeUrl( pwzUrl, strUrlModified, /*fReverse*/false );
  195. pwzUrl = strUrlModified.c_str();
  196. }
  197. hr = m_realInfo->ParseUrl( pwzUrl ,
  198. parseAction ,
  199. dwParseFlags,
  200. pwzResult ,
  201. cchResult ,
  202. pcchResult ,
  203. dwReserved );
  204. //
  205. // The MS-ITS: handler returns E_OUTOFMEMORY instead of S_FALSE on a "buffer too small" situation...
  206. //
  207. if(parseAction == PARSE_SECURITY_URL && hr == E_OUTOFMEMORY) hr = S_FALSE;
  208. __HCP_FUNC_EXIT(hr);
  209. }
  210. STDMETHODIMP CPCHWrapProtocolInfo::QueryInfo( /*[in] */ LPCWSTR pwzUrl ,
  211. /*[in] */ QUERYOPTION QueryOption ,
  212. /*[in] */ DWORD dwQueryFlags,
  213. /*[out]*/ LPVOID pBuffer ,
  214. /*[in] */ DWORD cbBuffer ,
  215. /*[out]*/ DWORD *pcbBuf ,
  216. /*[in] */ DWORD dwReserved )
  217. {
  218. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::QueryInfo");
  219. HRESULT hr;
  220. hr = m_realInfo->QueryInfo( pwzUrl ,
  221. QueryOption ,
  222. dwQueryFlags,
  223. pBuffer ,
  224. cbBuffer ,
  225. pcbBuf ,
  226. dwReserved );
  227. __HCP_FUNC_EXIT(hr);
  228. }
  229. ////////////////////////////////////////////////////////////////////////////////
  230. STDMETHODIMP CPCHWrapProtocolInfo::CreateInstance( /*[in] */ LPUNKNOWN pUnkOuter ,
  231. /*[in] */ REFIID riid ,
  232. /*[out]*/ void* *ppvObj )
  233. {
  234. HRESULT hr = E_POINTER;
  235. if(ppvObj)
  236. {
  237. *ppvObj = NULL;
  238. if(InlineIsEqualGUID( IID_IInternetProtocolInfo, riid ))
  239. {
  240. hr = QueryInterface( riid, ppvObj );
  241. }
  242. else if(InlineIsEqualGUID( IID_IUnknown , riid ) ||
  243. InlineIsEqualGUID( IID_IInternetProtocol , riid ) ||
  244. InlineIsEqualGUID( IID_IInternetProtocolRoot, riid ) )
  245. {
  246. hr = m_realClass->CreateInstance( pUnkOuter, riid, ppvObj );
  247. }
  248. }
  249. return hr;
  250. }
  251. STDMETHODIMP CPCHWrapProtocolInfo::LockServer( /*[in]*/ BOOL fLock )
  252. {
  253. return m_realClass->LockServer( fLock );
  254. }