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
356 lines
10 KiB
/******************************************************************************
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
ProtocolWrap.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of the CPCHWrapProtocolInfo class,
|
|
that is used to fix problems in the MS-ITS protocol.
|
|
|
|
Revision History:
|
|
Davide Massarenti (Dmassare) 05/07/2000
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
static const WCHAR l_szWINDIR [] = L"%WINDIR%";
|
|
static const WCHAR l_szHELP_LOCATION[] = L"%HELP_LOCATION%";
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
CPCHWrapProtocolInfo::CPCHWrapProtocolInfo()
|
|
{
|
|
__HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::CPCHWrapProtocolInfo");
|
|
|
|
// CComPtr<IClassFactory> m_realClass;
|
|
// CComPtr<IInternetProtocolInfo> m_realInfo;
|
|
}
|
|
|
|
CPCHWrapProtocolInfo::~CPCHWrapProtocolInfo()
|
|
{
|
|
__HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::~CPCHWrapProtocolInfo");
|
|
}
|
|
|
|
HRESULT CPCHWrapProtocolInfo::Init( REFGUID realClass )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHWrapProtocolInfo::Init" );
|
|
|
|
HRESULT hr;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ::CoGetClassObject( realClass, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&m_realClass ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_realClass->CreateInstance( NULL, IID_IInternetProtocolInfo, (void **)&m_realInfo ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CPCHWrapProtocolInfo::ExpandAndConcat( /*[out]*/ CComBSTR& bstrStorageName ,
|
|
/*[in]*/ LPCWSTR szVariable ,
|
|
/*[in]*/ LPCWSTR szAppend )
|
|
{
|
|
MPC::wstring strExpanded( szVariable ); MPC::SubstituteEnvVariables( strExpanded );
|
|
|
|
if(szAppend)
|
|
{
|
|
if(szAppend[0] != '\\' &&
|
|
szAppend[0] != '/' )
|
|
{
|
|
strExpanded += L"\\";
|
|
}
|
|
|
|
strExpanded += szAppend;
|
|
}
|
|
|
|
bstrStorageName = strExpanded.c_str();
|
|
}
|
|
|
|
void CPCHWrapProtocolInfo::NormalizeUrl( /*[in] */ LPCWSTR pwzUrl ,
|
|
/*[out]*/ MPC::wstring& strUrlModified ,
|
|
/*[in] */ bool fReverse )
|
|
{
|
|
CComBSTR bstrStorageName;
|
|
CComBSTR bstrFilePath;
|
|
bool fModified = false;
|
|
|
|
|
|
SANITIZEWSTR( pwzUrl );
|
|
|
|
|
|
if(MPC::MSITS::IsCHM( pwzUrl, &bstrStorageName, &bstrFilePath ) && bstrStorageName.Length() > 0)
|
|
{
|
|
if(!_wcsnicmp( bstrStorageName, l_szHELP_LOCATION, MAXSTRLEN( l_szHELP_LOCATION ) ))
|
|
{
|
|
CComBSTR bstrTmp;
|
|
|
|
while(1)
|
|
{
|
|
LPCWSTR szRest = &bstrStorageName[ MAXSTRLEN( l_szHELP_LOCATION ) ];
|
|
WCHAR rgDir[MAX_PATH];
|
|
|
|
//
|
|
// First, try the current help directory.
|
|
//
|
|
ExpandAndConcat( bstrTmp, CHCPProtocolEnvironment::s_GLOBAL->HelpLocation(), szRest );
|
|
if(MPC::FileSystemObject::IsFile( bstrTmp )) break;
|
|
|
|
//
|
|
// Then, try the MUI version of the help directory.
|
|
//
|
|
StringCchPrintfW( rgDir, ARRAYSIZE(rgDir), L"%s\\MUI\\%04lx", HC_HELPSVC_HELPFILES_DEFAULT, CHCPProtocolEnvironment::s_GLOBAL->Instance().m_ths.GetLanguage() );
|
|
ExpandAndConcat( bstrTmp, rgDir, szRest );
|
|
if(MPC::FileSystemObject::IsFile( bstrTmp )) break;
|
|
|
|
//
|
|
// Finally, try the system help directory.
|
|
//
|
|
ExpandAndConcat( bstrTmp, HC_HELPSVC_HELPFILES_DEFAULT, szRest );
|
|
break;
|
|
}
|
|
|
|
if(MPC::FileSystemObject::IsFile( bstrTmp ))
|
|
{
|
|
bstrStorageName = bstrTmp;
|
|
|
|
fModified = true;
|
|
}
|
|
}
|
|
|
|
if(!_wcsnicmp( bstrStorageName, l_szWINDIR, MAXSTRLEN( l_szWINDIR ) ))
|
|
{
|
|
ExpandAndConcat( bstrStorageName, l_szWINDIR, &bstrStorageName[ MAXSTRLEN( l_szWINDIR ) ] );
|
|
|
|
fModified = true;
|
|
}
|
|
|
|
if(::PathIsRelativeW( bstrStorageName ))
|
|
{
|
|
ExpandAndConcat( bstrStorageName, CHCPProtocolEnvironment::s_GLOBAL->HelpLocation(), bstrStorageName );
|
|
|
|
fModified = true;
|
|
}
|
|
|
|
|
|
if(fReverse)
|
|
{
|
|
MPC::wstring strHelpLocation = CHCPProtocolEnvironment::s_GLOBAL->HelpLocation(); MPC::SubstituteEnvVariables( strHelpLocation );
|
|
int iSize = strHelpLocation.size();
|
|
|
|
if(!_wcsnicmp( bstrStorageName, strHelpLocation.c_str(), iSize ))
|
|
{
|
|
strHelpLocation = l_szHELP_LOCATION;
|
|
strHelpLocation += &bstrStorageName[iSize];
|
|
|
|
bstrStorageName = strHelpLocation.c_str();
|
|
|
|
fModified = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(fModified)
|
|
{
|
|
strUrlModified = L"MS-ITS:";
|
|
strUrlModified += bstrStorageName;
|
|
|
|
|
|
if(bstrFilePath.Length() > 0)
|
|
{
|
|
strUrlModified += L"::/";
|
|
strUrlModified += bstrFilePath;
|
|
}
|
|
|
|
|
|
{
|
|
LPCWSTR pwzQuery;
|
|
LPCWSTR pwzAnchor;
|
|
LPCWSTR pwzEnd;
|
|
|
|
pwzQuery = wcsrchr( pwzUrl, '?' );
|
|
pwzAnchor = wcsrchr( pwzUrl, '#' );
|
|
|
|
if(pwzQuery)
|
|
{
|
|
if(pwzAnchor) pwzEnd = min(pwzQuery,pwzAnchor);
|
|
else pwzEnd = pwzQuery;
|
|
}
|
|
else
|
|
{
|
|
if(pwzAnchor) pwzEnd = pwzAnchor;
|
|
else pwzEnd = NULL;
|
|
}
|
|
|
|
if(pwzEnd) strUrlModified += pwzEnd;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strUrlModified = pwzUrl;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CPCHWrapProtocolInfo::CombineUrl( /*[in] */ LPCWSTR pwzBaseUrl ,
|
|
/*[in] */ LPCWSTR pwzRelativeUrl,
|
|
/*[in] */ DWORD dwCombineFlags,
|
|
/*[out]*/ LPWSTR pwzResult ,
|
|
/*[in] */ DWORD cchResult ,
|
|
/*[out]*/ DWORD *pcchResult ,
|
|
/*[in] */ DWORD dwReserved )
|
|
{
|
|
__HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::CombineUrl");
|
|
|
|
HRESULT hr;
|
|
|
|
if(MPC::MSITS::IsCHM( pwzRelativeUrl ))
|
|
{
|
|
MPC::wstring strUrlModified;
|
|
|
|
NormalizeUrl( pwzRelativeUrl, strUrlModified, /*fReverse*/false );
|
|
|
|
if(strUrlModified.size() > cchResult-1)
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
StringCchCopyW( pwzResult, cchResult, strUrlModified.c_str() );
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
*pcchResult = strUrlModified.size()+1;
|
|
}
|
|
else
|
|
{
|
|
hr = m_realInfo->CombineUrl( pwzBaseUrl ,
|
|
pwzRelativeUrl,
|
|
dwCombineFlags,
|
|
pwzResult ,
|
|
cchResult ,
|
|
pcchResult ,
|
|
dwReserved );
|
|
}
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHWrapProtocolInfo::CompareUrl( /*[in]*/ LPCWSTR pwzUrl1 ,
|
|
/*[in]*/ LPCWSTR pwzUrl2 ,
|
|
/*[in]*/ DWORD dwCompareFlags )
|
|
{
|
|
__HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::CompareUrl");
|
|
|
|
HRESULT hr;
|
|
|
|
hr = m_realInfo->CompareUrl( pwzUrl1 ,
|
|
pwzUrl2 ,
|
|
dwCompareFlags );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CPCHWrapProtocolInfo::ParseUrl( /*[in] */ LPCWSTR pwzUrl ,
|
|
/*[in] */ PARSEACTION parseAction ,
|
|
/*[in] */ DWORD dwParseFlags,
|
|
/*[out]*/ LPWSTR pwzResult ,
|
|
/*[in] */ DWORD cchResult ,
|
|
/*[out]*/ DWORD *pcchResult ,
|
|
/*[in] */ DWORD dwReserved )
|
|
{
|
|
__HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::ParseUrl");
|
|
|
|
HRESULT hr;
|
|
MPC::wstring strUrlModified;
|
|
|
|
|
|
if(parseAction == PARSE_CANONICALIZE ||
|
|
parseAction == PARSE_SECURITY_URL )
|
|
{
|
|
NormalizeUrl( pwzUrl, strUrlModified, /*fReverse*/false );
|
|
|
|
pwzUrl = strUrlModified.c_str();
|
|
}
|
|
|
|
hr = m_realInfo->ParseUrl( pwzUrl ,
|
|
parseAction ,
|
|
dwParseFlags,
|
|
pwzResult ,
|
|
cchResult ,
|
|
pcchResult ,
|
|
dwReserved );
|
|
|
|
//
|
|
// The MS-ITS: handler returns E_OUTOFMEMORY instead of S_FALSE on a "buffer too small" situation...
|
|
//
|
|
if(parseAction == PARSE_SECURITY_URL && hr == E_OUTOFMEMORY) hr = S_FALSE;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHWrapProtocolInfo::QueryInfo( /*[in] */ LPCWSTR pwzUrl ,
|
|
/*[in] */ QUERYOPTION QueryOption ,
|
|
/*[in] */ DWORD dwQueryFlags,
|
|
/*[out]*/ LPVOID pBuffer ,
|
|
/*[in] */ DWORD cbBuffer ,
|
|
/*[out]*/ DWORD *pcbBuf ,
|
|
/*[in] */ DWORD dwReserved )
|
|
{
|
|
__HCP_FUNC_ENTRY("CPCHWrapProtocolInfo::QueryInfo");
|
|
|
|
HRESULT hr;
|
|
|
|
hr = m_realInfo->QueryInfo( pwzUrl ,
|
|
QueryOption ,
|
|
dwQueryFlags,
|
|
pBuffer ,
|
|
cbBuffer ,
|
|
pcbBuf ,
|
|
dwReserved );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CPCHWrapProtocolInfo::CreateInstance( /*[in] */ LPUNKNOWN pUnkOuter ,
|
|
/*[in] */ REFIID riid ,
|
|
/*[out]*/ void* *ppvObj )
|
|
{
|
|
HRESULT hr = E_POINTER;
|
|
|
|
if(ppvObj)
|
|
{
|
|
*ppvObj = NULL;
|
|
|
|
if(InlineIsEqualGUID( IID_IInternetProtocolInfo, riid ))
|
|
{
|
|
hr = QueryInterface( riid, ppvObj );
|
|
}
|
|
else if(InlineIsEqualGUID( IID_IUnknown , riid ) ||
|
|
InlineIsEqualGUID( IID_IInternetProtocol , riid ) ||
|
|
InlineIsEqualGUID( IID_IInternetProtocolRoot, riid ) )
|
|
{
|
|
hr = m_realClass->CreateInstance( pUnkOuter, riid, ppvObj );
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CPCHWrapProtocolInfo::LockServer( /*[in]*/ BOOL fLock )
|
|
{
|
|
return m_realClass->LockServer( fLock );
|
|
}
|