Проблема с TDI драйвером

Discussion in 'WASM.NETWORKS' started by steelfactor, Nov 15, 2007.

  1. steelfactor

    steelfactor New Member

    Blog Posts:
    0
    Joined:
    Apr 26, 2007
    Messages:
    501
    Господа, гляньте код, кому не лень...
    Драйвер TDI, который просто посылает запрос в мир из r0 и вроде должен получать ответ...
    но при вызове функции recv валится с багкодом С0000184
    (по-моему STATUS_DRIVER_INTERNAL_ERROR)
    в какую сторону курить?
     
  2. TarasCo

    TarasCo New Member

    Blog Posts:
    0
    Joined:
    Feb 2, 2005
    Messages:
    106
    1. MmProbeAndLockPage - поменяйте на MmBuildMdlForNonPagedPool
    2. Уберите SetEventHandler(AddressFileObject, TDI_EVENT_RECEIVE, EventReceive, 0); . Или будте готовы к приему данных через нотифкатор
    3. В тесте поменяйте recv и send. Иначе при работе с web сервером ваш код повиснет
     
  3. steelfactor

    steelfactor New Member

    Blog Posts:
    0
    Joined:
    Apr 26, 2007
    Messages:
    501
    TarasCo
    Ок, пробую... Вопрос, обязательно ли в драйвере реализовывать TDI_ACCEPT? В сети где-то видел подобное...
     
  4. TarasCo

    TarasCo New Member

    Blog Posts:
    0
    Joined:
    Feb 2, 2005
    Messages:
    106
    TDI_ACCEPT нужен, только если Вы хотите принимать входящие соединения, т.е быть сервером. Стандартный драйвер afd.sys не использует этот запрос, а устанавливает нотификатор ClientEventConnect для транспортного адреса. В последнем случае гарантируется, что соединение не будет пропущено.
     
  5. steelfactor

    steelfactor New Member

    Blog Posts:
    0
    Joined:
    Apr 26, 2007
    Messages:
    501
    TarasCo
    замена MmProbeAndLockPage на MmBuildMdlForNonPagedPool выдает BSOD с багом 0x4Е, что-то там машина с mdl списками путает, насколько я понял... не силен в MDL...
     
  6. steelfactor

    steelfactor New Member

    Blog Posts:
    0
    Joined:
    Apr 26, 2007
    Messages:
    501
    похоже, начинаю разбираться...
    при использовании MmProbeAndLockPage и игноре обработки событий все срабатывает, только вот вызов функции receive вываливается с вечным STATUS_PENDING. По отчету google'a это является довольно распространенной ошибкой...
    тот же TarasCo вроде привел решение http://www.ntkernel.com/forum/viewtopic.php?t=154, посмотрю... по результатам отпишусь
     
  7. TarasCo

    TarasCo New Member

    Blog Posts:
    0
    Joined:
    Feb 2, 2005
    Messages:
    106
    На самом деле, все работает так:
    Если есть установленный обработчик ClientEventReceive ( и возможно ClientEventChainedReceive ), то при приеме данных они срабатывают. НО! только если нет незавершенных запросов TDI_RECEIVE. Т.е в Вашем случае формально все правильно.

    Функция recv висит в бесконечном ожидании потому как, нечего принимать - я же писал, вы вызваете recv раньше, чем отправляете запрос web серверу .
     
  8. steelfactor

    steelfactor New Member

    Blog Posts:
    0
    Joined:
    Apr 26, 2007
    Messages:
    501
    В предыдущем посте именно так и было - функция recv шла ПОСЛЕ send'a, и все равно status был равен 0x00000103... снифер показывал установку соединения, но отправки вот этого
    Code (Text):
    1. char *Data[]=
    2. {
    3.     "GET /index.html HTTP/1.1\r\n",
    4.     "Accept-Language: ru\r\n",
    5.     "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en)\r\n",
    6.     "Host: www.ya.ru\r\n",
    7.     NULL
    8. }
    не было... короче, после установка соединения с указанным хостом проходила нормально, а дальше функция recv выпадала со STATUS_PENDING.
    чувствую, что туплю, но где именно...???
     
  9. TarasCo

    TarasCo New Member

    Blog Posts:
    0
    Joined:
    Feb 2, 2005
    Messages:
    106
    убери звездочку перед Data[] и запятые - т.е сделай просто строку.

    и поставь send обратно перед recv ом.
     
  10. steelfactor

    steelfactor New Member

    Blog Posts:
    0
    Joined:
    Apr 26, 2007
    Messages:
    501
    исправил... уже лучше
    снифер показывает хандшейк между драйвером и сервером и команду "GET", чего раньше не было... (:
    Code (Text):
    1. ...B\....>....E
    2. ..,.n@........:
    3. .....b.PQ$q..
    4. .G.P.......GET
    на этом соединение заканчивается с уже доставшим STATUS_PENDING функции recv...
     
  11. TarasCo

    TarasCo New Member

    Blog Posts:
    0
    Joined:
    Feb 2, 2005
    Messages:
    106
    сервер ничего не отвечает, потому что неправильно запрос ему сформирован
    нужно так ( оставил только необходимые поля ):
    Code (Text):
    1.     static const char       http_get[] =
    2.                                 "GET / HTTP/1.1\r\n"
    3.                                 "Host: www.ya.ru\r\n"
    4.                                 "Connection: close\r\n"
    5.                                 "\r\n";
    Прошу обратить внимание на последнюю пустую строку "\r\n" - без этого работать не будет
     
  12. steelfactor

    steelfactor New Member

    Blog Posts:
    0
    Joined:
    Apr 26, 2007
    Messages:
    501
    мдя... век живи, век учись...
    GET ушел как нуна, но STATUS_PENDING функции recv пока остался... ответа сервера нет. Поколдую с Event'ами на приеме, потом отпишу
    Уважаемый TarasCo, уж простите мою непонятливость, но опыта работы с сетью в r0 у меня нет, не судите строго :) Надеюсь на Вашу помощь
     
  13. TarasCo

    TarasCo New Member

    Blog Posts:
    0
    Joined:
    Feb 2, 2005
    Messages:
    106
    Ну, если ответа от сервера нет, значит GET ушел не "как нужно", иначе сервер бы ответил и Вы видели бы его ответ сниффером. Подозреваю, что Вы указали длину sizeof( http_get ) и отправили еще до кучи терминирующий ноль. Возможно, сервер будет теперь ждать, когда вы передадите ему тело запроса.
     
  14. steelfactor

    steelfactor New Member

    Blog Posts:
    0
    Joined:
    Apr 26, 2007
    Messages:
    501
    TarasCo
    А размер буфера в recv имеет значение? Он в коде в 4 кb размером... Можно, конечно, выделить динамически, но подумалось, что 4 кб под стартовую страничку ya.ru должно хватить... Насколько я понимаю, буфер в recv используется именно для этих целей?
     
  15. steelfactor

    steelfactor New Member

    Blog Posts:
    0
    Joined:
    Apr 26, 2007
    Messages:
    501
    Заработала... =)
    Как и говорил TarasCo проблема была в неверно сформированном запросе к серверу, по сути поэтому recv и подвисала...
    нужно было запрос к серверу объявить как static const char и в функции send в IoAllocateMdl привести его к PVOID'у
    TarasCo, спасибо!