Skip to content

Commit

Permalink
Merge pull request #183 from denizzzka/win32_support_impr
Browse files Browse the repository at this point in the history
Windows socket duplication implementation
  • Loading branch information
denizzzka authored Apr 27, 2023
2 parents 4f2c7b5 + 16464f1 commit 93bc967
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 11 deletions.
1 change: 1 addition & 0 deletions dub.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"money": "~>3.0.2"
},
"targetType": "sourceLibrary",
"libs-windows": ["ws2_32"],
"-ddoxTool": "scod",
"configurations": [
{
Expand Down
102 changes: 91 additions & 11 deletions src/dpq2/connection.d
Original file line number Diff line number Diff line change
Expand Up @@ -207,27 +207,55 @@ class Connection
}

/// Obtains duplicate file descriptor number of the connection socket to the server
version(Posix)
socket_t posixSocketDuplicate()
{
version(Windows)
{
assert(false, "FIXME: implement socket duplication");
}
else // Posix OS
{
import core.sys.posix.unistd: dup;
import core.sys.posix.unistd: dup;

return cast(socket_t) dup(cast(socket_t) posixSocket);
}
static assert(socket_t.sizeof == int.sizeof);

return cast(socket_t) dup(cast(socket_t) posixSocket);
}

/// Obtains duplicate file descriptor number of the connection socket to the server
version(Windows)
SOCKET posixSocketDuplicate()
{
import core.stdc.stdlib: malloc, free;
import core.sys.windows.winbase: GetCurrentProcessId;

auto protocolInfo = cast(WSAPROTOCOL_INFOW*) malloc(WSAPROTOCOL_INFOW.sizeof);
scope(failure) free(protocolInfo);

int dupStatus = WSADuplicateSocketW(posixSocket, GetCurrentProcessId, protocolInfo);

if(dupStatus)
throw new ConnectionException("WSADuplicateSocketW error, code "~WSAGetLastError().to!string);

SOCKET s = WSASocketW(
FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
protocolInfo,
0,
0
);

if(s == INVALID_SOCKET)
throw new ConnectionException("WSASocket error, code "~WSAGetLastError().to!string);

return s;
}

/// Obtains std.socket.Socket of the connection to the server
///
/// Due to a limitation of Socket actually for the Socket creation
/// Due to a limitation of Dlang Socket actually for the Socket creation
/// duplicate of internal posix socket will be used.
Socket socket()
{
return new Socket(posixSocketDuplicate, AddressFamily.UNSPEC);
version(Windows) static assert(SOCKET.sizeof == socket_t.sizeof);

return new Socket(cast(socket_t) posixSocketDuplicate, AddressFamily.UNSPEC);
}

/// Returns the error message most recently generated by an operation on the connection
Expand Down Expand Up @@ -401,6 +429,58 @@ class Connection
}
}

// Socket duplication stuff for Win32
version(Windows)
private
{
import core.sys.windows.windef;
import core.sys.windows.basetyps: GUID;

alias GROUP = uint;

enum INVALID_SOCKET = 0;
enum FROM_PROTOCOL_INFO =-1;
enum MAX_PROTOCOL_CHAIN = 7;
enum WSAPROTOCOL_LEN = 255;

struct WSAPROTOCOLCHAIN
{
int ChainLen;
DWORD[MAX_PROTOCOL_CHAIN] ChainEntries;
}

struct WSAPROTOCOL_INFOW
{
DWORD dwServiceFlags1;
DWORD dwServiceFlags2;
DWORD dwServiceFlags3;
DWORD dwServiceFlags4;
DWORD dwProviderFlags;
GUID ProviderId;
DWORD dwCatalogEntryId;
WSAPROTOCOLCHAIN ProtocolChain;
int iVersion;
int iAddressFamily;
int iMaxSockAddr;
int iMinSockAddr;
int iSocketType;
int iProtocol;
int iProtocolMaxOffset;
int iNetworkByteOrder;
int iSecurityScheme;
DWORD dwMessageSize;
DWORD dwProviderReserved;
WCHAR[WSAPROTOCOL_LEN+1] szProtocol;
}

extern(Windows) nothrow @nogc
{
import core.sys.windows.winsock2: WSAGetLastError;
int WSADuplicateSocketW(SOCKET s, DWORD dwProcessId, WSAPROTOCOL_INFOW* lpProtocolInfo);
SOCKET WSASocketW(int af, int type, int protocol, WSAPROTOCOL_INFOW*, GROUP, DWORD dwFlags);
}
}

private auto keyValToPQparamsArrays(in string[string] keyValueParams)
{
static struct PQparamsArrays
Expand Down

0 comments on commit 93bc967

Please sign in to comment.