-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
688 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,10 @@ | ||
/src_win32_vc4/Debug | ||
/src_mfc_vc4/Debug | ||
*.dll | ||
*.exp | ||
*.ilk | ||
*.lib | ||
*.pdb | ||
*.pch | ||
Debug/WSAWrapper.obj | ||
Debug/vc40.idb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,379 @@ | ||
// Copyright © 2023 Dmitry Tretyakov (aka. Tinelix) | ||
// | ||
// This program is free software: you can redistribute it and/or modify it under the terms of | ||
// the GNU Lesser General Public License as published by the Free Software Foundation, either | ||
// version 2.1 of the License, or (at your option) any later version. | ||
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; | ||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
// See the GNU Lesser General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU Lesser General Public License along with this | ||
// program. If not, see https://www.gnu.org/licenses/. | ||
// | ||
// Source code: https://github.com/tinelix/WSAWrapper | ||
|
||
|
||
#include <windows.h> | ||
#include <winsock.h> | ||
#include <stdio.h> | ||
#include "WSAWrapper.h" | ||
|
||
#pragma comment(lib, "wsock32.lib"); | ||
|
||
SOCKET s; | ||
int BUFFER_LENGTH = 4096; | ||
char* recv_buff; | ||
struct hostent *hostent; | ||
char hostent_char[MAXGETHOSTSTRUCT]; | ||
struct sockaddr_in addr; | ||
char* g_address; | ||
int g_port; | ||
char debug_str[400]; | ||
char ip_addr[40]; | ||
BOOL is_win32s; | ||
int error_code = 0; | ||
BOOL debug; | ||
|
||
struct NetworkStatistics stats; | ||
|
||
int WINAPI DllMain(HINSTANCE hInst, DWORD fdReas, PVOID pvRes) { | ||
switch(fdReas) { | ||
case DLL_PROCESS_ATTACH: | ||
error_code = 0; | ||
// Checking if it's Win32s | ||
if(GetVersion() & 0x80000000 && (GetVersion() & 0xFF) == 3) { | ||
is_win32s = TRUE; | ||
} else { | ||
is_win32s = FALSE; | ||
} | ||
|
||
debug = FALSE; | ||
|
||
if(!is_win32s) { | ||
OutputDebugString("\r\nWinsock Wrapper - Win32 DLL implementation" | ||
"\r\nCopyright © 2023 Dmitry Tretyakov (aka. Tinelix). Licensed under LGPLv2.1." | ||
"\r\nSource code: https://github.com/tinelix/WSAWrapper\r\n"); | ||
} | ||
InitializeWinSock(); | ||
break; | ||
case DLL_PROCESS_DETACH: | ||
CloseConnection(); | ||
WSACleanup(); | ||
if(!is_win32s) { | ||
OutputDebugString("\r\nWinsock Wrapper is shutting down...\r\n"); | ||
} | ||
break; | ||
} | ||
|
||
return TRUE; | ||
} | ||
|
||
EXPORT void CALLBACK EnableDebugging(BOOL value) { | ||
if(!is_win32s) { | ||
debug = value; | ||
if(debug == TRUE) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Debug Enabled"); | ||
OutputDebugString(debug_str); | ||
} | ||
} else { | ||
MessageBox(NULL, "Direct DLL debugging is not possible in the current Windows version.", | ||
"WSAWrapper", MB_ICONSTOP|MB_OK); | ||
} | ||
} | ||
|
||
EXPORT BOOL CALLBACK InitializeWinSock() { | ||
WSADATA wsadata; | ||
if(FAILED(WSAStartup(MAKEWORD(1,1), &wsadata))) { | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Winsock initialization " | ||
"failed / Error Code: %d", WSAGetLastError()); | ||
OutputDebugString(debug_str); | ||
} | ||
return FALSE; | ||
} | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Winsock 1.1+ initialized."); | ||
OutputDebugString(debug_str); | ||
} | ||
return TRUE; | ||
} | ||
|
||
EXPORT BOOL CALLBACK EnableCustomAsyncMessages(HWND hWnd, int message, int nStatus) { | ||
if(message != 0xAFFE) { | ||
int WSAAsync = WSAAsyncSelect(s, hWnd, 0xAFFF, nStatus); | ||
if(hWnd != NULL) { | ||
if(WSAAsync > 0 && debug) { | ||
error_code = WSAGetLastError(); | ||
if(!is_win32s) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Async Messages initialization " | ||
"failed / Error code: %d", error_code); | ||
OutputDebugString(debug_str); | ||
} | ||
return FALSE; | ||
} | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Async Messages initialized."); | ||
OutputDebugString(debug_str); | ||
} | ||
return TRUE; | ||
} else { | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Async Messages initialization " | ||
"failed / hWnd is NULL"); | ||
OutputDebugString(debug_str); | ||
} | ||
return FALSE; | ||
} | ||
} else { | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Async Messages initialization " | ||
"failed / Invalid message code"); | ||
OutputDebugString(debug_str); | ||
} | ||
return FALSE; | ||
} | ||
} | ||
|
||
EXPORT BOOL CALLBACK EnableAsyncMessages(HWND hWnd) { | ||
int WSAAsync = WSAAsyncSelect(s, hWnd, 0xAFFF, FD_READ); | ||
if(hWnd != NULL) { | ||
if(WSAAsync > 0) { | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Async Messages initialization " | ||
"failed / Error Code: %d", WSAGetLastError()); | ||
OutputDebugString(debug_str); | ||
} | ||
return EnableCustomAsyncMessages(hWnd, 0xE0001, FD_CLOSE); | ||
} | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Async Messages initialized."); | ||
OutputDebugString(debug_str); | ||
} | ||
return TRUE; | ||
} else { | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Async Messages initialization " | ||
"failed / hWnd is NULL"); | ||
OutputDebugString(debug_str); | ||
} | ||
return FALSE; | ||
} | ||
} | ||
|
||
EXPORT int CALLBACK GetWSAError() { | ||
return error_code; | ||
} | ||
|
||
EXPORT BOOL CALLBACK CreateConnection(char* address, int port) { | ||
error_code = 0; | ||
|
||
stats.packets_read = 0; | ||
stats.packets_sent = 0; | ||
stats.total_bytes_read = 0; | ||
stats.total_bytes_sent = 0; | ||
|
||
g_address = address; | ||
if(INVALID_SOCKET == (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) { | ||
error_code = WSAGetLastError(); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Socket initialization failed / Error Code: %d", error_code); | ||
OutputDebugString(debug_str); | ||
} | ||
return FALSE; | ||
} | ||
ZeroMemory(&addr, sizeof(addr)); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Searching IP Address of %s:%d...", address, port); | ||
OutputDebugString(debug_str); | ||
} | ||
hostent = gethostbyname(address); | ||
addr.sin_family = AF_INET; | ||
if(hostent) { | ||
addr.sin_addr.S_un.S_addr = | ||
inet_addr((char*)inet_ntoa(**(in_addr**)hostent->h_addr_list)); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] IP Address Found: %s:%d -> %s:%d", address, port, | ||
(char*)inet_ntoa(**(in_addr**)hostent->h_addr_list), port); | ||
OutputDebugString(debug_str); | ||
} | ||
} else { | ||
error_code = WSAGetLastError(); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] IP Search failed / Error Code: %d", error_code); | ||
OutputDebugString(debug_str); | ||
} | ||
return FALSE; | ||
} | ||
addr.sin_port = htons(port); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Connecting to %s:%d...", address, port); | ||
OutputDebugString(debug_str); | ||
} | ||
if(SOCKET_ERROR == (connect(s, (sockaddr*)&addr, sizeof(addr)))) { | ||
error_code = WSAGetLastError(); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Connection failed / Error Code: %d", error_code); | ||
OutputDebugString(debug_str); | ||
} | ||
return FALSE; | ||
} | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Successfully connected!"); | ||
OutputDebugString(debug_str); | ||
} | ||
error_code = 0; | ||
return TRUE; | ||
} | ||
|
||
EXPORT int CALLBACK CreateAsyncConnection( | ||
char* address, int port, int part, int message, HWND hWnd | ||
) { | ||
if(part == 0) { | ||
g_address = address; | ||
g_port = port; | ||
PostMessage(hWnd, 0xAFFE, 0, 0); | ||
if(INVALID_SOCKET == (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) { | ||
error_code = WSAGetLastError(); | ||
if(!is_win32s) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Socket initialization failed / " | ||
"Error Code: %d", error_code); | ||
OutputDebugString(debug_str); | ||
} | ||
return 0; | ||
} | ||
ZeroMemory(&addr, sizeof(addr)); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Searching IP Address of %s:%d...", address, port); | ||
OutputDebugString(debug_str); | ||
} | ||
WSAAsyncGetHostByName(hWnd, message, g_address, hostent_char, sizeof(hostent_char)); | ||
return 2; | ||
} else { | ||
hostent = (struct hostent*)hostent_char; | ||
addr.sin_family = AF_INET; | ||
if(hostent) { | ||
addr.sin_addr.S_un.S_addr = inet_addr((char*)inet_ntoa(**(in_addr**)hostent->h_addr_list)); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Redirecting: %s:%d -> %s:%d", g_address, g_port, | ||
(char*)inet_ntoa(**(in_addr**)hostent->h_addr_list), g_port); | ||
OutputDebugString(debug_str); | ||
} | ||
} else { | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] IP Search failed / Error Code: %d", WSAGetLastError()); | ||
OutputDebugString(debug_str); | ||
} | ||
return 0; | ||
} | ||
addr.sin_port = htons(g_port); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Connecting to %s:%d...", g_address, g_port); | ||
OutputDebugString(debug_str); | ||
} | ||
if(SOCKET_ERROR == (connect(s, (sockaddr*)&addr, sizeof(addr)))) { | ||
error_code = WSAGetLastError(); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Connection failed / Error Code: %d", error_code); | ||
OutputDebugString(debug_str); | ||
} | ||
return 0; | ||
} | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Successfully connected!"); | ||
OutputDebugString(debug_str); | ||
} | ||
return 1; | ||
} | ||
} | ||
|
||
EXPORT BOOL CALLBACK SendData(char* buff) { | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Sending data to %s... (%d bytes)", | ||
g_address, strlen(buff)); | ||
OutputDebugString(debug_str); | ||
} | ||
|
||
int length = send(s, buff, strlen(buff), 0); | ||
|
||
if(SOCKET_ERROR == length) { | ||
error_code = WSAGetLastError(); | ||
if(error_code > 0) { // workaround: check error code | ||
if(!is_win32s) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Send Data failed / Error Code: %d", error_code); | ||
OutputDebugString(debug_str); | ||
} | ||
return FALSE; | ||
} else { | ||
stats.packets_sent = stats.total_bytes_sent / BUFFER_LENGTH; | ||
stats.total_bytes_sent += strlen(buff); | ||
error_code = 0; | ||
return TRUE; | ||
} | ||
} else { | ||
stats.packets_sent = stats.total_bytes_sent / BUFFER_LENGTH; | ||
stats.total_bytes_sent += strlen(buff); | ||
} | ||
error_code = 0; | ||
return TRUE; | ||
} | ||
|
||
|
||
EXPORT char* CALLBACK GetInputBuffer(SOCKET s) { | ||
int length = 0; | ||
recv_buff = new char[BUFFER_LENGTH]; | ||
length = recv(s, (char*)recv_buff, BUFFER_LENGTH, 0); | ||
if(SOCKET_ERROR == length) { | ||
error_code = WSAGetLastError(); | ||
if(error_code == 10035) { // workaround: if it's non-blocking socket | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Buffer Read error / " | ||
" Error Code: %d", g_address, error_code); | ||
OutputDebugString(debug_str); | ||
} | ||
sprintf(recv_buff, "\r\n[Missing Socket Data]"); | ||
Sleep(200); | ||
} else if(error_code > 0) { // workaround: check error code | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Connection with %s closed / " | ||
" Error Code: %d", g_address, error_code); | ||
OutputDebugString(debug_str); | ||
} | ||
closesocket(s); | ||
sprintf(recv_buff, "[WSAWrapper] 0xE0001\r\n"); | ||
} else { | ||
stats.total_bytes_read += length; | ||
stats.packets_read = stats.total_bytes_read / BUFFER_LENGTH; | ||
recv_buff[length] = '\0'; | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Receiving Data from %s... (%d bytes)", | ||
g_address, length); | ||
OutputDebugString(debug_str); | ||
} | ||
} | ||
} else { | ||
stats.total_bytes_read += length; | ||
stats.packets_read = stats.total_bytes_read / BUFFER_LENGTH; | ||
recv_buff[length] = '\0'; | ||
} | ||
return recv_buff; | ||
} | ||
|
||
EXPORT struct NetworkStatistics GetNetworkStatistics() { | ||
return stats; | ||
} | ||
|
||
EXPORT void CALLBACK CloseConnection() { | ||
try { | ||
error_code = 0; | ||
closesocket(s); | ||
if(!is_win32s && debug) { | ||
sprintf(debug_str, "\r\n[WSAWrapper] Successfully closed!"); | ||
OutputDebugString(debug_str); | ||
} | ||
} catch(...) { | ||
|
||
} | ||
} | ||
|
||
|
||
|
Oops, something went wrong.