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.

356 lines
10 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. StringCchPrintfW( rgDir, ARRAYSIZE(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. LPCWSTR pwzQuery;
  127. LPCWSTR pwzAnchor;
  128. LPCWSTR pwzEnd;
  129. pwzQuery = wcsrchr( pwzUrl, '?' );
  130. pwzAnchor = wcsrchr( pwzUrl, '#' );
  131. if(pwzQuery)
  132. {
  133. if(pwzAnchor) pwzEnd = min(pwzQuery,pwzAnchor);
  134. else pwzEnd = pwzQuery;
  135. }
  136. else
  137. {
  138. if(pwzAnchor) pwzEnd = pwzAnchor;
  139. else pwzEnd = NULL;
  140. }
  141. if(pwzEnd) strUrlModified += pwzEnd;
  142. }
  143. }
  144. else
  145. {
  146. strUrlModified = pwzUrl;
  147. }
  148. }
  149. /////////////////////////////////////////////////////////////////////////////
  150. STDMETHODIMP CPCHWrapProtocolInfo::CombineUrl( /*[in] */ LPCWSTR pwzBaseUrl ,
  151. /*[in] */ LPCWSTR pwzRelativeUrl,
  152. /*[in] */ DWORD dwCombineFlags,
  153. /*[out]*/ LPWSTR pwzResult ,
  154. /*[in] */ DWORD cchResult ,
  155. /*[out]*/ DWORD *pcchResult ,
  156. /*[in] */ DWORD dwReserved )
  157. {
  158. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::CombineUrl");
  159. HRESULT hr;
  160. if(MPC::MSITS::IsCHM( pwzRelativeUrl ))
  161. {
  162. MPC::wstring strUrlModified;
  163. NormalizeUrl( pwzRelativeUrl, strUrlModified, /*fReverse*/false );
  164. if(strUrlModified.size() > cchResult-1)
  165. {
  166. hr = S_FALSE;
  167. }
  168. else
  169. {
  170. StringCchCopyW( pwzResult, cchResult, strUrlModified.c_str() );
  171. hr = S_OK;
  172. }
  173. *pcchResult = strUrlModified.size()+1;
  174. }
  175. else
  176. {
  177. hr = m_realInfo->CombineUrl( pwzBaseUrl ,
  178. pwzRelativeUrl,
  179. dwCombineFlags,
  180. pwzResult ,
  181. cchResult ,
  182. pcchResult ,
  183. dwReserved );
  184. }
  185. __HCP_FUNC_EXIT(hr);
  186. }
  187. STDMETHODIMP CPCHWrapProtocolInfo::CompareUrl( /*[in]*/ LPCWSTR pwzUrl1 ,
  188. /*[in]*/ LPCWSTR pwzUrl2 ,
  189. /*[in]*/ DWORD dwCompareFlags )
  190. {
  191. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::CompareUrl");
  192. HRESULT hr;
  193. hr = m_realInfo->CompareUrl( pwzUrl1 ,
  194. pwzUrl2 ,
  195. dwCompareFlags );
  196. __HCP_FUNC_EXIT(hr);
  197. }
  198. STDMETHODIMP CPCHWrapProtocolInfo::ParseUrl( /*[in] */ LPCWSTR pwzUrl ,
  199. /*[in] */ PARSEACTION parseAction ,
  200. /*[in] */ DWORD dwParseFlags,
  201. /*[out]*/ LPWSTR pwzResult ,
  202. /*[in] */ DWORD cchResult ,
  203. /*[out]*/ DWORD *pcchResult ,
  204. /*[in] */ DWORD dwReserved )
  205. {
  206. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::ParseUrl");
  207. HRESULT hr;
  208. MPC::wstring strUrlModified;
  209. if(parseAction == PARSE_CANONICALIZE ||
  210. parseAction == PARSE_SECURITY_URL )
  211. {
  212. NormalizeUrl( pwzUrl, strUrlModified, /*fReverse*/false );
  213. pwzUrl = strUrlModified.c_str();
  214. }
  215. hr = m_realInfo->ParseUrl( pwzUrl ,
  216. parseAction ,
  217. dwParseFlags,
  218. pwzResult ,
  219. cchResult ,
  220. pcchResult ,
  221. dwReserved );
  222. //
  223. // The MS-ITS: handler returns E_OUTOFMEMORY instead of S_FALSE on a "buffer too small" situation...
  224. //
  225. if(parseAction == PARSE_SECURITY_URL && hr == E_OUTOFMEMORY) hr = S_FALSE;
  226. __HCP_FUNC_EXIT(hr);
  227. }
  228. STDMETHODIMP CPCHWrapProtocolInfo::QueryInfo( /*[in] */ LPCWSTR pwzUrl ,
  229. /*[in] */ QUERYOPTION QueryOption ,
  230. /*[in] */ DWORD dwQueryFlags,
  231. /*[out]*/ LPVOID pBuffer ,
  232. /*[in] */ DWORD cbBuffer ,
  233. /*[out]*/ DWORD *pcbBuf ,
  234. /*[in] */ DWORD dwReserved )
  235. {
  236. __HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::QueryInfo");
  237. HRESULT hr;
  238. hr = m_realInfo->QueryInfo( pwzUrl ,
  239. QueryOption ,
  240. dwQueryFlags,
  241. pBuffer ,
  242. cbBuffer ,
  243. pcbBuf ,
  244. dwReserved );
  245. __HCP_FUNC_EXIT(hr);
  246. }
  247. ////////////////////////////////////////////////////////////////////////////////
  248. STDMETHODIMP CPCHWrapProtocolInfo::CreateInstance( /*[in] */ LPUNKNOWN pUnkOuter ,
  249. /*[in] */ REFIID riid ,
  250. /*[out]*/ void* *ppvObj )
  251. {
  252. HRESULT hr = E_POINTER;
  253. if(ppvObj)
  254. {
  255. *ppvObj = NULL;
  256. if(InlineIsEqualGUID( IID_IInternetProtocolInfo, riid ))
  257. {
  258. hr = QueryInterface( riid, ppvObj );
  259. }
  260. else if(InlineIsEqualGUID( IID_IUnknown , riid ) ||
  261. InlineIsEqualGUID( IID_IInternetProtocol , riid ) ||
  262. InlineIsEqualGUID( IID_IInternetProtocolRoot, riid ) )
  263. {
  264. hr = m_realClass->CreateInstance( pUnkOuter, riid, ppvObj );
  265. }
  266. }
  267. return hr;
  268. }
  269. STDMETHODIMP CPCHWrapProtocolInfo::LockServer( /*[in]*/ BOOL fLock )
  270. {
  271. return m_realClass->LockServer( fLock );
  272. }