Долгое ковыряние хелпа и и глубокий дебуг выяснили следующее:
1. Если мы реализуем свой протокол IInternetProtocolInfo, то первым(!!!) методом должен вызваться ParseUrl (прочитайте в MSDN про асинхронные плуг-протоколы), а не Start из IInternetProtocolRoot!!!
2. Теперь посмотрим на параметры функции Start, когда мы в нее попадаем.
R>Происходит ошибка в IInternetProtocolRoot->Start
m_pIProtSink = pOIProtSink
pOIProtSing=1 (это то указатель)
Ага равен 1. А вы не пробовали смотреть чему pOIProtSink равен при последующих вызовах? (Ну если закоментировать присвоение). Он "пляшет" в дипазоне от 1 до 16. Прикольно, правда?
3. Уж не знаю как я этого добился, но в какой-то момент у меня вдруг начал вызываться ParseUrl, а не Start . Причем первый вызов нормальный — приходит урл, а во втором параметре 1 () — это значение PARSE_CANONICALIZE в параметре ParseAction. Здесь я по всем правилам делаю разбор строки и возвращаю необходимое в параметрах UrlMon'у. Там нужно заполнить строковый буфер своими значениями. Здесь внимание(!): идут два параметра: указатель на буфер и его размер (он равен 2048 — ровненько 2к). Потом сразу следует второй вызов ParseUrl. И вот тут начинается дурдом, очень похожий на ваш случай с pOIProtSing=1. В параметре ParseAction сидит какая-то лабуда (что-то вроде адреса, но не как не одно из значений из PARSEACTION енума).
4. Потыкавшись дальше, у меня опять начал вызываться первым Start И вот тут я обратил внимание на значения параметров в функции Start. Они один в один похожи на вызов ParseUrl Да!!! :
pOIProtSing=1 — это PARSEACTION ParseAction из ParseUrl
DWORD dwReserved=2048 — это DWORD cchResult оттуда же
Внимательно всмотритесь в порядок следования параметров обеих функций — они точь в точь совпадают!!!
Т.е. UrlMon не может разобраться где тут ParseUrl, а где Start, а точнее для него укзатели на эти функции имеют одинаковое значение. Он сначала думает, что вызывает ParseUrl (а в действительности "лупит" по адресу Start), а потом вызывает Start (здесь он прав — это действительно Start).
Вывод: Что-то криво с декларацией самого CMyProtocol. Адреса функций "слипаются". В ATL я тоже не спец, надеюсь на помощь тех, кто в нем шарит.
Скорее всего трабла здесь:
/////////////////////////////////////////////////////////////////////////////
// CMyProtocolclass ATL_NO_VTABLE CMyProtocol :
public virtual CComObjectRootEx<CComSingleThreadModel>,
public virtual CComCoClass<CMyProtocol, &CLSID_MyProtocol>,
public IInternetProtocol,
public IInternetProtocolInfo
{
Ох уж мне это множественное наследование ...
Помогите плиз!!!
Re[3]: Как подцепить в свой IE протокол IInternetProtocolInf
Здравствуйте, Tom, Вы писали:
Tom>Есть предложение вообще не реализовывать IInternetProtocolInfo, причём убрать его надо прямо из карты интерфейсов, а не возвращать E_NOTIMPLEMENTED
Так потребность как раз именно в нем. Дело в том, что нужно корректно обрабатывать относительные урлы вида: ../../somedir/somefile.ext. Не зная базового Урл, невозможно построить корректно абсолютный путь. Для этого, я так понимаю, и нужен IInternetProtocolInfo с функциями ParseUrl, CombineUrl, CompareUrl. Хорошо когда в примере стоит: myprot://somefile.txt. Для примера сойдет. В реальности надо чуть больше
Хотелось бы не нарушая принципа древовидности, иметь то же самое и в своем протоколе. Скидывать все в одну кучу некошерно Да и на данный момент есть большое кол-во файлов, лежащих в каталогах. Хотелось бы не нарушая логики, поместить это все куда-нибудь. Для меня идеальный вариант — zip-файл. Сохранится структура и не нужно будет перелопачивать код в поисках "где там какой относительный урл куда показывает".
Re[5]: Как подцепить в свой IE протокол IInternetProtocolInf
Здравствуйте, Nikolaz, Вы писали:
N>Здравствуйте, Tom, Вы писали:
Tom>>Есть предложение вообще не реализовывать IInternetProtocolInfo, причём убрать его надо прямо из карты интерфейсов, а не возвращать E_NOTIMPLEMENTED N>Так потребность как раз именно в нем. Дело в том, что нужно корректно обрабатывать относительные урлы вида: ../../somedir/somefile.ext. Не зная базового Урл, невозможно построить корректно абсолютный путь. Для этого, я так понимаю, и нужен IInternetProtocolInfo с функциями ParseUrl, CombineUrl, CompareUrl. Хорошо когда в примере стоит: myprot://somefile.txt. Для примера сойдет. В реальности надо чуть больше
N>Хотелось бы не нарушая принципа древовидности, иметь то же самое и в своем протоколе. Скидывать все в одну кучу некошерно Да и на данный момент есть большое кол-во файлов, лежащих в каталогах. Хотелось бы не нарушая логики, поместить это все куда-нибудь. Для меня идеальный вариант — zip-файл. Сохранится структура и не нужно будет перелопачивать код в поисках "где там какой относительный урл куда показывает".
Я не вкурсе усройства протоколов, но насколько я знаю встроенный в IE http протокол не реализует данного интерфейса.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[6]: Как подцепить в свой IE протокол IInternetProtocolInf
Tom>Я не вкурсе усройства протоколов, но насколько я знаю встроенный в IE http протокол не реализует данного интерфейса.
Я тоже глубоко пока эти не проникся Интересно как тогда осуществляется разбор полетов с относительными урлами. Мы ведь привыкли писать: <img src="../../somedir/picture.gif"> — это ведь значит подняться на два каталога выше, относительно(!) текущего (а им является тот каталог, где лежит файл, в котором прописана эта строчка кода) и загрузить picture.gif из каталога somedir, который в свою очередь лежит в текущем. О как
Т.е. если строчка <img src="../../somedir/picture.gif"> лежит в файле c:\temp\projects\test.htm,
то src в конце концов должен преобразоваться в c:\somedir\picture.gif,
прежде чем WebControl (или кто там етим занимается) поймет откуда в конце концов грузить эту картинку.
Кстати насчет "реализует или нет". Посмотрите функцию:
Если ее вызвать для урла вида myprot://.., то код сваливается прямо в реализацию интерфейса IInternetProtocolInfo в MyProtocol. Я думаю, если подергать ее со стандартными http:// урлами, то результат тоже будет (это значит, что IInternetProtocolInfo для http:// реализован). В зависимости от ParseAction вам будут возвращаться части переданного урла (урл будет парсится в зависимости от логики протокола http).
Re[7]: Как подцепить в свой IE протокол IInternetProtocolInf
Отвечаю сам себе. Думаю многим тоже будет интересно.
Вообщем накопал на Code Project один проект DataProtocol. Писано под Visual Studio .NET на С++. Имеет поддержку IInternetProtocolInfo. Т.е. все что нужно было при работе с ParseUrl. После недолгих манипуляций с примерами из http://www.rsdn.ru/article/inet/pluggprotocol.xml
и найденной реализацией протокола DataProtocol получил желаемое поведение:
— Реализован собственный IInternetProtocolInfo;— Регистрация DataProtocol также не нужна. Загружается и работает только в рамках собственно приложения (см. TestProtocolApp пример из http://www.codeproject.com/internet/DataProtocol.asp). Собственно это и не моя заслуга Спасибо автору этой статьи!
Фактически я заменил реализацию MyProtocol в примерах из статьи http://www.rsdn.ru/article/inet/pluggprotocol.xml
N>Почему не работал пример из статьи при попытке реализовать в нем IInternetProtocolInfo, я так и не разобрался
Так это самое интересное, остальное — лирика...
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[9]: Как подцепить в свой IE протокол IInternetProtocolInf
Здравствуйте, Tom, Вы писали:
N>>Почему не работал пример из статьи при попытке реализовать в нем IInternetProtocolInfo, я так и не разобрался Tom>Так это самое интересное, остальное — лирика...
Лирика в том, после долгого "приколачивания" этого IInternetProtocolInfo выяснилось следующее: картинки то он нормально подгружает, а вот такое
Напрочь отказывается . Точнее он делает запросы, и я их ему оттдаю (отрабатывают и Start, и Read). И он их как-бы "забрал". Только вот ни отработки скриптов, ни отработки стилей после загрузки основной страницы не происходит
Даже и не знаю куда копать. Предполагаю, что все же неправильно реализованы методы у IInternetProtocolInfo и это как-то связано с секурностью.
Re[10]: Как подцепить в свой IE протокол IInternetProtocolIn
Здравствуйте, Nikolaz, Вы писали:
N>Здравствуйте, Tom, Вы писали:
N>>>Почему не работал пример из статьи при попытке реализовать в нем IInternetProtocolInfo, я так и не разобрался Tom>>Так это самое интересное, остальное — лирика... N>Лирика в том, после долгого "приколачивания" этого IInternetProtocolInfo выяснилось следующее: картинки то он нормально подгружает, а вот такое N>
N>Напрочь отказывается . Точнее он делает запросы, и я их ему оттдаю (отрабатывают и Start, и Read). И он их как-бы "забрал". Только вот ни отработки скриптов, ни отработки стилей после загрузки основной страницы не происходит
Нашел
// Reads data retrieved by the pluggable protocol handler.
HRESULT STDMETHODCALLTYPE CMyProtocol::Read(
/* [length_is][size_is][out][in] */void __RPC_FAR *pv,
/* [in] */ ULONG cb,
/* [out] */ ULONG __RPC_FAR *pcbRead)
{
BOOL Status = FALSE;
//set position of begin
LARGE_INTEGER nLen1;
nLen1.QuadPart = m_lPosition;
if(FAILED(m_pIStream->Seek(nLen1, STREAM_SEEK_SET, NULL)))
return INET_E_DOWNLOAD_FAILURE;
//read data to browserif ( SUCCEEDED( m_pIStream->Read(pv, cb, pcbRead) ))
{
if (*pcbRead != 0)
{
Status = TRUE;
m_lPosition += *pcbRead;
}
else
return S_FALSE;
}
...................................................
if (m_pIProtSink != NULL)
{
m_pIProtSink->ReportData(BSCF_LASTDATANOTIFICATION, m_lSize, m_lSize);
m_pIProtSink->ReportResult(S_OK, 0, NULL); <- ВОТ ЭТО НАДО УБРАТЬ!!!
}
return S_FALSE;
}
m_pIProtSink->ReportResult(S_OK, 0, NULL); все портит.
Я не знаю для чего этот вызов стоит. Автору виднее . Но без него наоборот — все .
А так получается, что ни css, ни скрипты, ничего не работает .
Re[11]: Как подцепить в свой IE протокол IInternetProtocolIn
Здравствуйте, Nikolaz, Вы писали:
N>m_pIProtSink->ReportResult(S_OK, 0, NULL); все портит. N>Я не знаю для чего этот вызов стоит. Автору виднее . Но без него наоборот — все . N>А так получается, что ни css, ни скрипты, ничего не работает .
Зря Вы это убрали. Потому что теперь у Вас не вызывается IInternetProtocolRoot::Terminate и не освобождаются ресурсы. Можете почитать про это здесь, особое внимание обратите на шаг 10. А в вышеуказанном примере достаточно в начале CMyProtocol::Read поставить