Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Траблы с WSAStartup и нетолько


Автор: drZmeu 27.2.2007, 21:53
Всем привет!!!
Есть такая трабла : я начёркал приложение TCP сервер оно должно хранится в dll но почемуто всегда выскакивает ошибка на WSAStartup  smile 

Вот код:

Код

#include <winsock2.h>
#include <windows.h>
#pragma comment (lib,"ws2_32.lib")

DWORD WINAPI SockSend(LPVOID lParam)
{
char szRecv[1024],szSend[1024];
SOCKET s=(SOCKET)lParam;
int ret;

while(1)
{
ret=recv(s,szRecv,sizeof(szRecv),0);
if(ret == 0)
break;
else if(ret == SOCKET_ERROR)
{
MessageBox(0,"Recvid faild","",0);
break;
}
strcpy(szSend,szRecv);
ret=send(s,szSend,sizeof(szSend),0);
if(ret == SOCKET_ERROR)break;
}
closesocket(s);
MessageBox(0,"Socket close !!!","",0);
return 0;
}


DWORD WINAPI CreSock(LPVOID lParam)
{
SOCKET s,sclient;
struct sockaddr_in local,cstruc;
HANDLE hSockSend;
DWORD iSockSend;
int    iSize;

s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(s==SOCKET_ERROR){
MessageBox(0,"Can't load WinSock","",0);
return 0;
}
local.sin_family=AF_INET;
local.sin_addr.s_addr=htonl(ADDR_ANY);
local.sin_port = htons(1764);

if(bind(s,(struct sockaddr *)&local,sizeof(local))==SOCKET_ERROR)
{
MessageBox(0,"Can't bind start","",0);
return 1;
}
MessageBox(0,"Bind OK !!!","",0);
listen(s,4);
MessageBox(0,"List OK !!!","",0);

while(1)
{
iSize = sizeof(cstruc);
sclient=accept(s,(struct sockaddr *)&cstruc,&iSize);
if(sclient == INVALID_SOCKET)
{
MessageBox(0,"Accept faild","",0);
break;
}
hSockSend=CreateThread(NULL,0,SockSend,(LPVOID)sclient,0,&iSockSend);
if(hSockSend == INVALID_HANDLE_VALUE)
{
MessageBox(0,"Error hSockSend","",0);
break;
}
CloseHandle(hSockSend);
}
closesocket(s);
return 0;
}

BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{

WSADATA wsa;
HANDLE hNextStep;
DWORD    iNextStep;
if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
MessageBox(0,"WsaError","",0);
return 0;
//Если всё ОК то начали

}
hNextStep=CreateThread(NULL,0,CreSock,0,0,&iNextStep);
if(hNextStep == NULL){MessageBox(0,"Cant jump creSock","",0);}
WSACleanup();
return TRUE;
}

Почему именно так непрокатывает с библеотекой.???

Автор: drZmeu 28.2.2007, 19:30
Ну народ помогите я очень мало работал с dll'лками...
 smile  

Автор: Tyjin 28.2.2007, 19:41
Убери WSAStartup из DllMain. Вынеси в отдельную функцию.

Автор: drZmeu 28.2.2007, 21:03
Вау круто тогда можно с такой же лёгкостью вынести всё =))))))))
+ если я захочу внедрить её в процесс =)))

Автор: dumb 28.2.2007, 21:18
drZmeu,
Цитата(msdn(DllMain))

The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary) during process termination, because this can result in a DLL being used after the system has executed its termination code.

Because Kernel32.dll is guaranteed to be loaded in the process address space when the entry-point function is called, calling functions in Kernel32.dll does not result in the DLL being used before its initialization code has been executed. Therefore, the entry-point function can call functions in Kernel32.dll that do not load other DLLs. For example, DllMain can create synchronization objects such as critical sections and mutexes, and use TLS. 

Calling functions that require DLLs other than Kernel32.dll may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions load other system components. Conversely, calling functions such as these during termination can cause access violation errors because the corresponding component may already have been unloaded or uninitialized.

Because DLL notifications are serialized, entry-point functions should not attempt to communicate with other threads or processes. Deadlocks may occur as a result.

If your DLL is linked with the C run-time library (CRT), the entry point provided by the CRT calls the constructors and destructors for global and static C++ objects. Therefore, these restrictions for DllMain also apply to constructors and destructors and any code that is called from them.


все еще смешно? smile

Автор: drZmeu 28.2.2007, 22:19
Блин ну я много слышал про разных троев и нетолько троев были и какието легальные программы у которых работа с сетью была в dll...

Добавлено @ 22:28 
Вынес её так:

Код

#include <winsock2.h>
#include <windows.h>
#pragma comment (lib,"ws2_32.lib")



DWORD WINAPI SockSend(LPVOID lParam)
{
char szRecv[1024],szSend[1024];
SOCKET s=(SOCKET)lParam;
int ret;

while(1)
{
ret=recv(s,szRecv,sizeof(szRecv),0);
if(ret == 0)
break;
else if(ret == SOCKET_ERROR)
{
MessageBox(0,"Recvid faild","",0);
break;
}
strcpy(szSend,szRecv);
ret=send(s,szSend,sizeof(szSend),0);
if(ret == SOCKET_ERROR)break;
}
closesocket(s);
MessageBox(0,"Socket close !!!","",0);
return 0;
}


DWORD WINAPI CreSock(LPVOID lParam)
{
SOCKET s,sclient;
struct sockaddr_in local,cstruc;
HANDLE hSockSend;
DWORD iSockSend;
int    iSize;



s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(s==SOCKET_ERROR){
MessageBox(0,"Can't load WinSock","",0);
return 0;
}
local.sin_family=AF_INET;
local.sin_addr.s_addr=htonl(ADDR_ANY);
local.sin_port = htons(1764);

if(bind(s,(struct sockaddr *)&local,sizeof(local))==SOCKET_ERROR)
{
MessageBox(0,"Can't bind start","",0);
return 1;
}
MessageBox(0,"Bind OK !!!","",0);
listen(s,4);
MessageBox(0,"List OK !!!","",0);

while(1)
{
iSize = sizeof(cstruc);
sclient=accept(s,(struct sockaddr *)&cstruc,&iSize);
if(sclient == INVALID_SOCKET)
{
MessageBox(0,"Accept faild","",0);
break;
}
hSockSend=CreateThread(NULL,0,SockSend,(LPVOID)sclient,0,&iSockSend);
if(hSockSend == INVALID_HANDLE_VALUE)
{
MessageBox(0,"Error hSockSend","",0);
break;
}
CloseHandle(hSockSend);
}
closesocket(s);
return 0;
}

//----------------------------------------
DWORD WINAPI WsaStr(LPVOID lParam)
{
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
MessageBox(0,"WsaError","",0);
return 0;
//Если всё ОК то начали
}

HANDLE hNextStep;
DWORD    iNextStep;
hNextStep=CreateThread(NULL,0,CreSock,0,0,&iNextStep);
if(hNextStep == NULL){MessageBox(0,"Cant jump creSock","",0);}
WSACleanup();
return 0;
}
//----------------------------------------

BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if(ul_reason_for_call == 1)
    {
WsaStr(NULL);
    }


return 0;
}



а она теперь ошибку выдаёт  smile 

Автор: Tyjin 1.3.2007, 13:26
и что изменилось? она все равно дергается из Entry Point.
См. полезный коммент от dumb.

Тебе надо вынести "сложную" инициализацию в отдельную функцию, которую будет дергать сам клиент, использующий dll.

Автор: dumb 2.3.2007, 07:57
Цитата(drZmeu @  28.2.2007,  21:03 Найти цитируемый пост)
если я захочу внедрить её в процесс

как вариант - поставить любой хук(SetWindowsHookEx имеется ввиду), а в функции хука запустить нужную процедуру(можно для нее свой поток создать) и сразу хук снять.

Автор: drZmeu 2.3.2007, 12:02
Нужно подумать =\
Ибо dll как плагин должна внедрятся в процесс и работать с сетью.
С хуком конечно попробую...
Тоесть система должна быть такая.
Я допустим ставлю хук на клавиатуру при ножатии вызывается моя функция и
тутже снимаю хук =\
Можно попробовать но думаю непрокатит =\

Автор: dumb 2.3.2007, 14:20
Цитата(drZmeu @  2.3.2007,  12:02 Найти цитируемый пост)
Я допустим ставлю хук на клавиатуру при ножатии

зачем клавиатурный то? - ставь на какой-нибудь WH_GETMESSAGE...

Цитата(drZmeu @  2.3.2007,  12:02 Найти цитируемый пост)
Можно попробовать но думаю непрокатит

это зависит от того, как пробовать будешь. если я написал фразу "как вариант", то это вовсе не означает, что этот вариант нерабочий.

Автор: drZmeu 3.3.2007, 13:38
Да ладно незлись попробую расскажу как прошло =)

Автор: drZmeu 3.3.2007, 18:17
Уря пасибо dumb !!!
работает  smile 
Только осталось пара вопросов
1 как упростить код:
Код

#include <winsock2.h>
#include <windows.h>
#include <iostream>
#pragma comment (lib, "ws2_32.lib")
#ifdef __cplusplus
extern "C" {
#endif

HHOOK hHKeyBrd = NULL;
WSADATA wsa;
HANDLE hSTgo;
DWORD iSTgo;

DWORD WINAPI SockChat(LPVOID lParam)
{
SOCKET s=(SOCKET)lParam;
char szRecv[1024],szSend[1024];
int ret;

while(1)
{
    ret=recv(s,szRecv,sizeof(szRecv),0);
    if(ret==0)
        break;
    else if(ret==SOCKET_ERROR)
    {
    MessageBox(0,"Recvid faild","",0);
    break;
    }
    strcpy(szSend,szRecv);
    ret=send(s,szSend,sizeof(szSend),0);
    if(ret==SOCKET_ERROR)
    {
    break;
    }
}
return 0;
}

DWORD WINAPI SockStart(LPVOID lParam)
{
SOCKET s,sclient;
struct sockaddr_in local,lclient;
int iSize;
MessageBox(0,"JUMP TO STSOCK OK","",0);
s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(s==SOCKET_ERROR)
{
MessageBox(0,"Can't create socket","",0);
}
local.sin_family=AF_INET;
local.sin_addr.s_addr=htonl(ADDR_ANY);
local.sin_port = htons(2432);
if(bind(s,(struct sockaddr *)&local,sizeof(local)) == SOCKET_ERROR)
{
MessageBox(0,"bind error","",0);
}
MessageBox(0,"Bind OK","",0);
listen(s,8);
MessageBox(0,"list ok","",0);
while(1)
{
iSize=sizeof(lclient);
sclient = accept(s,(struct sockaddr *)&lclient, &iSize);
if(sclient == INVALID_SOCKET)
{
MessageBox(0,"Accept faild","",0);
}
HANDLE socksay;
DWORD isocksay;
socksay=CreateThread(NULL,0,SockChat,(LPVOID)sclient,0,&isocksay);
if(socksay == INVALID_HANDLE_VALUE)
{
MessageBox(0,"Can't jump SockChat","",0);
}
CloseHandle(socksay);
}
closesocket(s);
return 0;
}
//--------------------------------
DWORD WINAPI WSAGO(LPVOID lParam)
{
WSADATA wsa;
HANDLE HSOCKS;
DWORD ISOCKS;
UnhookWindowsHookEx(hHKeyBrd);
if(WSAStartup(0x0202,&wsa)!=0)
{
MessageBox(0,"Fuck","",0);
}
MessageBox(0,"WSASTGO OK","",0);
HSOCKS=CreateThread(NULL,0,SockStart,0,0,&ISOCKS);
if(HSOCKS == INVALID_HANDLE_VALUE){MessageBox(0,"Can't jump to start sock","",0);}
return 0;
}

LRESULT CALLBACK KeyBrdProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0){
        hSTgo=CreateThread(NULL,0,WSAGO,0,0,&iSTgo);
        if(hSTgo == INVALID_HANDLE_VALUE)
        {
        MessageBox(0,"bad","",0);
        }
    }
    return CallNextHookEx (hHKeyBrd,nCode,wParam,lParam);
}

__declspec(dllexport) bool SetHooks(HINSTANCE hModule)
{
    hHKeyBrd = SetWindowsHookEx(WH_KEYBOARD, KeyBrdProc, (HINSTANCE) hModule, NULL);
    return true; 
}

__declspec(dllexport) bool UnHook()
{
    return true;
}

#ifdef __cplusplus
}
#endif


И 2 как при внедрении выполнить dll ,,,???,,,

Автор: drZmeu 4.3.2007, 22:10
Так как выполнить вопрос откидывается...
Вопрос как воткнуть хук чтоб он после вызова снялся...?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)