Отладка в ide невозможна, IE походу не может получить интерфейс IInternetProtocol, поэтому напихал логов. Логи показали, что в момент подвисания несколько десятков раз происходит Class_Initialize/Terminate.
В описании хендлеров протоколов сказано, что для них требуется реализация двух интерфейсов, IInternetProtocol и IInternetProtocolInfo. Первый обязательно, второй - нет. Собственно в примере его тоже нет и все работает. Появилось подозрение, что в момент подвисания IE как раз таки пытается получить IInternetProtocolInfo. Добавил Implements, код в членов писать не стал, IE стал выдавать ошибку "Недействительный адрес". Дальнейшие копания в этом направлении дали это:
- Код: Выделить всё
STDMETHODIMP CDataPluggableProtocol::CombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
{return INET_E_DEFAULT_ACTION;}
STDMETHODIMP CDataPluggableProtocol::CompareUrl(LPCWSTR pwszUrl1, LPCWSTR pwszUrl2, DWORD dwCompareFlags)
{
ATLTRACE(_T("CompareUrl\n"));
if (pwszUrl1 == NULL || pwszUrl2 == NULL)
return E_POINTER;
HRESULT hr = S_FALSE;
CDataURL url1, url2;
if (url1.Parse(pwszUrl1) && url2.Parse(pwszUrl2) && url1 == url2){
hr = S_OK;
}
return hr;
}
STDMETHODIMP CDataPluggableProtocol::ParseUrl(LPCWSTR pwzUrl, PARSEACTION parseAction, DWORD dwParseFlags,
LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
{return INET_E_DEFAULT_ACTION;}
STDMETHODIMP CDataPluggableProtocol::QueryInfo( LPCWSTR pwzUrl, QUERYOPTION QueryOption, DWORD dwQueryFlags,
LPVOID pBuffer, DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
{return INET_E_DEFAULT_ACTION;}
Вижу два способа решения проблемы: декомпилировать olelib.tlb (если возможно) и поменять объявления, второй способ использовал сам автор в примере. IInternetProtocol.Read тоже описано как Sub, но автору зачем-то понадобилось возвращать значения (хотя и без этого работает). Он заменяет Sub на Function функцией ReplaceVTableEntry, чье говорящее имя описывает способ замены. Она одним из параметров принимает номер функции в vtable.
Из всего этого вытекают такие вопросы:
1) Можно ли (и чем) декомпилировать tlb?
2) Как узнать номер функции в vtable?
3) Может я вообще не туда забрел?