Есть проблема с Ndis

Тема в разделе "WASM.NT.KERNEL", создана пользователем neutronion, 8 апр 2011.

  1. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    В общем такая проблема:
    Вызываю NdisRequest, чтобы карточка перешла в прослушивающий режим.
    В колбэк функции ProtocolRequestComplete приходит ответ STATUS_SUCCESS
    это значит, что карточка переведена в прослушивающий режим.
    Однако, колбэки при получении пакета не вызываются, что обычно должно делаться.
    Пробую разобраться с драйвером ndis.sys однако, не понятно за что зацепиться,
    так как ndis.sys возвращает статус ок.
    Что подскажете? Хотелось бы поковыряться в ndis.sys, таким образом решить вопрос принципиально.
     
  2. AES256

    AES256 New Member

    Публикаций:
    0
    Регистрация:
    23 авг 2010
    Сообщения:
    15
    У тебя свой протокольный фильтр, или ты перехватываешь методы существующего протокола? Какая версия ОС? Покажи фрагмент кода, где вызывается NdisRequest.
     
  3. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    Мой собственный протокольный драйвер, на базе кстати работающего от winpcap. Есть разница, winpcap переводит карточку в прослушивающий режим в функции
    IO_control, команда поступает из юзерленда, меня это не устраивает, я вызываю перевод карточки в DriverEntry, не уверен насколько это критично. Ok. Регистрация
    протокола, здесь все ок.
    Код (Text):
    1.     NdisRegisterProtocol(
    2.         &Status,
    3.         &g_NdisProtocolHandle,
    4.         &ProtocolChar,
    5.         sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
    6.  
    7.     if (Status != NDIS_STATUS_SUCCESS) {
    8.  
    9.         TRACE_MESSAGE(PACKET_DEBUG_INIT,"Failed to register protocol with NDIS");
    10.  
    11.         TRACE_EXIT();
    12.         return Status;
    13.  
    14.     }
    Затем я получаю имя своего адаптера, здесь имя совпадает, тут без проблем
    и открываю его, здесь тоже нет проблем
    Код (Text):
    1.     NdisOpenAdapter(
    2.         &Status,
    3.         &ErrorStatus,
    4.         &Open->AdapterHandle,
    5.         &Open->Medium,
    6.         MediumArray,
    7.         NUM_NDIS_MEDIA,
    8.         g_NdisProtocolHandle,
    9.         Open,
    10.         &AdaptName,
    11.         0,
    12.         NULL);
    13.  
    14.     TRACE_MESSAGE1(PACKET_DEBUG_LOUD,"Opened the device, Status=%x",Status);
    15.  
    16.     if (Status == NDIS_STATUS_PENDING)
    17.     {
    18.         NdisWaitEvent(&Open->NdisOpenCloseCompleteEvent, 0);
    19.  
    20.         if (!NT_SUCCESS(Open->OpenCloseStatus))
    21.         {
    22.             *stat = returnStatus = Open->OpenCloseStatus;
    23.         }
    24.         else
    25.         {
    26.             *stat = returnStatus = STATUS_SUCCESS;
    27.         }
    28.     }
    Потом переводим карточку в прослушку.
    Код (Text):
    1. ULONG aMode = NDIS_PACKET_TYPE_PROMISCUOUS;
    2.     //
    3.     PLIST_ENTRY         RequestListEntry;
    4.     PINTERNAL_REQUEST   MaxSizeReq;
    5.     NDIS_STATUS         ReqStatus;
    6.  
    7.     TRACE_ENTER();
    8.  
    9.     ASSERT(Open != NULL);
    10.     //ASSERT(pIrp != NULL);
    11.     //ASSERT(pMtu != NULL);
    12.  
    13.     // Extract a request from the list of free ones
    14.     //_asm int 3
    15.     RequestListEntry = ExInterlockedRemoveHeadList(&Open->RequestList, &Open->RequestSpinLock);
    16.  
    17.     if (RequestListEntry == NULL)
    18.     {
    19.         //
    20.         // THIS IS WRONG
    21.         //
    22.  
    23.         //
    24.         // Assume Ethernet
    25.         //
    26.         //*pMtu = 1514;
    27.         TRACE_EXIT();
    28.         return ;
    29.     }
    30.  
    31.     MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement);
    32.  
    33.     MaxSizeReq->Request.RequestType = NdisRequestQueryInformation;
    34.     MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
    35.  
    36.     MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = &aMode;
    37.     MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(ULONG);
    38.  
    39.     NdisResetEvent(&MaxSizeReq->InternalRequestCompletedEvent);
    40.  
    41.     //  submit the request
    42.     _asm int 3  
    43.     NdisRequest(
    44.         &ReqStatus,
    45.         Open->AdapterHandle,
    46.         &MaxSizeReq->Request);
    47.  
    48.     if (ReqStatus == NDIS_STATUS_PENDING)
    49.     {
    50.         NdisWaitEvent(&MaxSizeReq->InternalRequestCompletedEvent, 0);
    51.         ReqStatus = MaxSizeReq->RequestStatus;
    52.         _asm int 3
    53.     }
    54.  
    55.  
    56.     TRACE_EXIT();
    в колбэк функции RequestCompleteHandler
    статус возвращается ок.
    Код (Text):
    1.  PINTERNAL_REQUEST   pRequest;
    2.  
    3.     //_asm int 3
    4.     TRACE_ENTER();
    5.  
    6.     pRequest = CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
    7.  
    8.         //это я чисто для себя проверил.
    9.     if(NdisRequest->DATA.QUERY_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER)
    10.     {
    11.         _asm int 3
    12.     }
    13.  
    14.  
    15.     //
    16.     // Set the request result
    17.     //
    18.     pRequest->RequestStatus = Status;
    19.  
    20.     //
    21.     // and awake the caller
    22.     //
    23.     NdisSetEvent(&pRequest->InternalRequestCompletedEvent);
    24.  
    25.     TRACE_EXIT();
    26.     return;
    Здесь статус тоже ок, то есть ноль. Соответственно весь код вызывается из DriverEntry, не напрямую конечно, а через функции. Думаю приводит код DriverEntry нет резона, статусы нормальные приходят от всех вышеописанных функций. Еще вопрос, в книге Хоглуда, зачем-то он вызывает колбэк функции в своем же драйвере, в драйвере от winpcap я этого нигде не обнаружил. Нигде драйвер winpcap не вызывает зарегистрированные функции! Но это так, оффтоп.

    windows xp 2sp
     
  4. AES256

    AES256 New Member

    Публикаций:
    0
    Регистрация:
    23 авг 2010
    Сообщения:
    15
    Если речь про 5-й NDIS - то у тебя, скорее всего, неправильно регистрируется драйвер: протокольный фильтр должен через inf-файл ставится, что бы все биндинги протоколов правильно разрезолвились. Если драйвер протокольного фильтра тупо через NtLoadDriver или CreateService/StartService загрузить - то входящие пакеты ловиться не будут.
     
  5. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    Да, но я же гружу драйвер динамически от winpcap, и он все отлавливает.
    мой же драйвер, имеет то же имя что и winpcap npf.sys, это значит что все внутренние имена такие же как и у работающего. Гружу так и свой и winpcap
    Код (Text):
    1.     char filePart[MAX_PATH] = {0};
    2.     SC_HANDLE   hService;
    3.     SC_HANDLE   hSCManager;
    4.     HANDLE   hDevice;
    5.     char g_driver_path[MAX_PATH];
    6.  
    7.     //pseudo-code
    8.     //Open SCManager
    9.     hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
    10.  
    11.     if(NULL == hSCManager)
    12.         return GetLastError();
    13.  
    14.     //GetName of the driver
    15.     GetFullPathName("npf.sys",sizeof(g_driver_path),
    16.                 g_driver_path,(LPSTR*)filePart);
    17.  
    18.     //CreateService
    19.     hService = CreateService(hSCManager,"npf",
    20.                         "\\Device\\npf",SERVICE_START | DELETE,
    21.                         SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,
    22.                         SERVICE_ERROR_IGNORE,(LPCSTR)g_driver_path,NULL,
    23.                         NULL,
    24.                         NULL,
    25.                         NULL,
    26.                         NULL);
    27.  
    28.     int lastErr;
    29.     if(NULL == hService)
    30.     {
    31.         char _s[256];
    32.         lastErr = GetLastError();
    33.        
    34.         itoa(lastErr,_s,10);
    35.  
    36.         //::MessageBoxA(NULL,_s,"cREATE SERVICE FAILED",MB_OK);
    37.  
    38.         if(ERROR_SERVICE_EXISTS == lastErr)
    39.         {
    40.             hService = OpenService(hSCManager,"npf",STANDARD_RIGHTS_REQUIRED | \
    41.                                 SERVICE_QUERY_CONFIG | \
    42.                                 SERVICE_QUERY_STATUS | \
    43.                                 SERVICE_START);
    44.             if(NULL == hService)
    45.             {
    46.                 lastErr = GetLastError();
    47.            
    48.                 itoa(lastErr,_s,10);
    49.  
    50.                 ::MessageBoxA(NULL,_s,"Open SERVICE FAILED",MB_OK);
    51.                 return false;
    52.             }
    53.  
    54.  
    55.         }else
    56.         {
    57.                 itoa(lastErr,_s,10);
    58.  
    59.                 ::MessageBoxA(NULL,_s,"Some SERVICE FAILE error",MB_OK);
    60.  
    61.             return true;
    62.         }
    63.     }
    64.  
    65.     //StartService
    66.     if(!StartService(hService,0,NULL))
    67.     {
    68.         lastErr = GetLastError();
    69.         return false;
    70.     }
     
  6. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    У меня есть решение, конечно, переводить карточку в прослушку в IO_control как делает это драйвер winpcap , без юзерленда и с минимумом вмешательства в код, но хотелось бы разобраться в принципе.
     
  7. ntkernelspawn

    ntkernelspawn New Member

    Публикаций:
    0
    Регистрация:
    17 дек 2010
    Сообщения:
    61
    neutronion
    В WDK есть пример по написанию фильтров для NDIS. И перестанте смотреть всякий бред ...
     
  8. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    дружище, вы не в потоке, о фильтрах никто не говорил. Прощу прощения, нехорошо сказал, вы наверное имели ввиду ndisprot.
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Я не совсем понял, но вот этот код:
    Код (Text):
    1. MaxSizeReq->Request.RequestType = NdisRequestQueryInformation;
    2. MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
    запрашивает, а не устанавливает фильтр. Может быть имелось в виду NdisRequestSetInformation?
     
  10. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    Блин!!!!!!!!!!! Глаз настолько замылился с кучей драйверов. Конечно вы правы, я выдрал не ту ветку в рабочем драйвер, все поля поправил, кроме этого.
    Сейчас все заработало!!! Куда высылать ящик пива? Большое спасибо, а то я уже на завтра запланировал экскурсию в недра ядра.