Skip to content

Commit

Permalink
Update gitignore
Browse files Browse the repository at this point in the history
  • Loading branch information
tretdm committed Nov 2, 2023
1 parent cb557cf commit aa07fe1
Show file tree
Hide file tree
Showing 7 changed files with 688 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
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
379 changes: 379 additions & 0 deletions WSAWrapper.cpp
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(...) {

}
}



Loading

0 comments on commit aa07fe1

Please sign in to comment.