Move all windows specific definitions from network.socket to the sys-package

This commit is contained in:
Eugen Wissner 2017-09-15 10:58:23 +02:00
parent aabb6334be
commit 9b54017840
10 changed files with 354 additions and 519 deletions

View File

@ -27,8 +27,8 @@ import tanya.async.watcher;
import tanya.memory;
import tanya.memory.mmappool;
import tanya.network.socket;
import tanya.sys.windows.winbase;
import core.sys.windows.mswsock;
import core.sys.windows.winbase;
import core.sys.windows.winsock2;
/**
@ -285,7 +285,7 @@ final class IOCPLoop : Loop
{
DWORD lpNumberOfBytes;
size_t key;
LPOVERLAPPED overlap;
OVERLAPPED* overlap;
immutable timeout = cast(immutable int) blockTime.total!"msecs";
auto result = GetQueuedCompletionStatus(completionPort,

View File

@ -37,8 +37,7 @@ else version (D_Ddoc)
version (WindowsDoc):
import core.sys.windows.winbase;
import core.sys.windows.windef;
import tanya.sys.windows.winbase;
/**
* Provides an extendable representation of a Win32 $(D_PSYMBOL OVERLAPPED)

View File

@ -29,19 +29,7 @@ pure nothrow @system @nogc
// RDI and RSI should be preserved.
mov RAX, RDI;
mov R8, RSI;
}
// Set the registers for movsb/movsq.
version (Windows) asm pure nothrow @nogc
{
// RDX - source.
// RCX - target.
mov RDI, [ RCX + 8 ];
mov RSI, [ RDX + 8 ];
mov RDX, [ RDX ];
}
else asm pure nothrow @nogc
{
// RDX - source length.
// RCX - source data.
// RDI - target length
@ -49,9 +37,7 @@ pure nothrow @system @nogc
mov RDI, RSI;
mov RSI, RCX;
}
asm pure nothrow @nogc
{
cmp RDX, 0x08;
jc aligned_1;
test EDI, 0x07;
@ -85,209 +71,160 @@ pure nothrow @system @nogc
}
}
package (tanya.memory) template fill(ubyte Byte)
pragma(inline, true)
package (tanya.memory) void fill(void[], ulong) pure nothrow @system @nogc
{
private enum const(char[]) MovArrayPointer(string Destination)()
asm pure nothrow @nogc
{
string asmCode = "asm pure nothrow @nogc { mov ";
version (Windows)
{
asmCode ~= Destination ~ ", [ RCX + 8 ];";
}
else
{
asmCode ~= Destination ~ ", RSI;";
}
return asmCode ~ "}";
}
naked;
pragma(inline, true)
void fill(void[] memory)
{
asm pure nothrow @nogc
{
naked;
}
version (Windows) asm pure nothrow @nogc
{
/*
* RCX - array.
*/
mov R8, [ RCX ];
}
else asm pure nothrow @nogc
{
/*
* RSI - pointer.
* RDI - length.
*/
mov R8, RDI;
}
mixin(MovArrayPointer!"R9");
// Check for zero length.
test RSI, RSI;
jz end;
/*
* RDX - pointer.
* RSI - length.
* RDI - value filled with a byte.
*/
mov RAX, RSI;
mov R8, RDX;
movq XMM0, RDI;
movlhps XMM0, XMM0;
// Check if the pointer is aligned to a 16-byte boundary.
and R8, -0x10;
asm pure nothrow @nogc
{
// Check for zero length.
test R8, R8;
jz end;
}
// Set 128- and 64-bit registers to values we want to fill with.
static if (Byte == 0)
{
asm pure nothrow @nogc
{
xor RAX, RAX;
pxor XMM0, XMM0;
}
}
else
{
enum ulong FilledBytes = FilledBytes!Byte;
asm pure nothrow @nogc
{
mov RAX, FilledBytes;
movq XMM0, RAX;
movlhps XMM0, XMM0;
}
}
asm pure nothrow @nogc
{
// Check if the pointer is aligned to a 16-byte boundary.
and R9, -0x10;
}
// Compute the number of misaligned bytes.
mixin(MovArrayPointer!"R10");
asm pure nothrow @nogc
{
sub R10, R9;
mov R9, RDX;
sub R9, R8;
test R10, R10;
jz aligned;
test R9, R9;
jz aligned;
// Get the number of bytes to be written until we are aligned.
mov RDX, 0x10;
sub RDX, R10;
}
mixin(MovArrayPointer!"R9");
asm pure nothrow @nogc
{
naligned:
mov [ R9 ], AL; // Write a byte.
// Get the number of bytes to be written until we are aligned.
mov RCX, 0x10;
sub RCX, R9;
// Advance the pointer. Decrease the total number of bytes
// and the misaligned ones.
inc R9;
dec RDX;
dec R8;
mov R8, RDX;
// Checks if we are aligned.
test RDX, RDX;
jnz naligned;
naligned:
mov [ R8 ], DIL; // Write a byte.
aligned:
// Checks if we're done writing bytes.
test R8, R8;
jz end;
// Advance the pointer. Decrease the total number of bytes
// and the misaligned ones.
inc R8;
dec RCX;
dec RAX;
// Write 1 byte at a time.
cmp R8, 8;
jl aligned_1;
// Checks if we are aligned.
test RCX, RCX;
jnz naligned;
// Write 8 bytes at a time.
cmp R8, 16;
jl aligned_8;
aligned:
// Checks if we're done writing bytes.
test RAX, RAX;
jz end;
// Write 16 bytes at a time.
cmp R8, 32;
jl aligned_16;
// Write 1 byte at a time.
cmp RAX, 8;
jl aligned_1;
// Write 32 bytes at a time.
cmp R8, 64;
jl aligned_32;
// Write 8 bytes at a time.
cmp RAX, 16;
jl aligned_8;
aligned_64:
movdqa [ R9 ], XMM0;
movdqa [ R9 + 16 ], XMM0;
movdqa [ R9 + 32 ], XMM0;
movdqa [ R9 + 48 ], XMM0;
// Write 16 bytes at a time.
cmp RAX, 32;
jl aligned_16;
add R9, 64;
sub R8, 64;
// Write 32 bytes at a time.
cmp RAX, 64;
jl aligned_32;
cmp R8, 64;
jge aligned_64;
aligned_64:
movdqa [ R8 ], XMM0;
movdqa [ R8 + 16 ], XMM0;
movdqa [ R8 + 32 ], XMM0;
movdqa [ R8 + 48 ], XMM0;
// Checks if we're done writing bytes.
test R8, R8;
jz end;
add R8, 64;
sub RAX, 64;
// Write 1 byte at a time.
cmp R8, 8;
jl aligned_1;
cmp RAX, 64;
jge aligned_64;
// Write 8 bytes at a time.
cmp R8, 16;
jl aligned_8;
// Checks if we're done writing bytes.
test RAX, RAX;
jz end;
// Write 16 bytes at a time.
cmp R8, 32;
jl aligned_16;
// Write 1 byte at a time.
cmp RAX, 8;
jl aligned_1;
aligned_32:
movdqa [ R9 ], XMM0;
movdqa [ R9 + 16 ], XMM0;
// Write 8 bytes at a time.
cmp RAX, 16;
jl aligned_8;
add R9, 32;
sub R8, 32;
// Write 16 bytes at a time.
cmp RAX, 32;
jl aligned_16;
// Checks if we're done writing bytes.
test R8, R8;
jz end;
aligned_32:
movdqa [ R8 ], XMM0;
movdqa [ R8 + 16 ], XMM0;
// Write 1 byte at a time.
cmp R8, 8;
jl aligned_1;
add R8, 32;
sub RAX, 32;
// Write 8 bytes at a time.
cmp R8, 16;
jl aligned_8;
// Checks if we're done writing bytes.
test RAX, RAX;
jz end;
aligned_16:
movdqa [ R9 ], XMM0;
// Write 1 byte at a time.
cmp RAX, 8;
jl aligned_1;
add R9, 16;
sub R8, 16;
// Write 8 bytes at a time.
cmp RAX, 16;
jl aligned_8;
// Checks if we're done writing bytes.
test R8, R8;
jz end;
aligned_16:
movdqa [ R8 ], XMM0;
// Write 1 byte at a time.
cmp R8, 8;
jl aligned_1;
add R8, 16;
sub RAX, 16;
aligned_8:
mov [ R9 ], RAX;
// Checks if we're done writing bytes.
test RAX, RAX;
jz end;
add R9, 8;
sub R8, 8;
// Write 1 byte at a time.
cmp RAX, 8;
jl aligned_1;
// Checks if we're done writing bytes.
test R8, R8;
jz end;
aligned_8:
mov [ R8 ], RDI;
aligned_1:
mov [ R9 ], AL;
add R8, 8;
sub RAX, 8;
inc R9;
dec R8;
// Checks if we're done writing bytes.
test RAX, RAX;
jz end;
test R8, R8;
jnz aligned_1;
aligned_1:
mov [ R8 ], DIL;
end:
ret;
}
inc R8;
dec RAX;
test RAX, RAX;
jnz aligned_1;
end:
ret;
}
}
@ -302,22 +239,7 @@ pure nothrow @system @nogc
// Save the registers should be restored.
mov R8, RSI;
mov R9, RDI;
}
// Prepare the registers for movsb.
version (Windows) asm pure nothrow @nogc
{
// RDX - source.
// RCX - target.
mov RAX, [ RCX + 8 ];
mov R10, [ RDX + 8 ];
mov RCX, [ RDX ];
lea RDI, [ RAX + RCX - 1 ];
lea RSI, [ R10 + RCX - 1 ];
}
else asm pure nothrow @nogc
{
// RDX - source length.
// RCX - source data.
// RDI - target length
@ -326,9 +248,7 @@ pure nothrow @system @nogc
lea RDI, [ RSI + RDX - 1 ];
lea RSI, [ RCX + RDX - 1 ];
mov RCX, RDX;
}
asm pure nothrow @nogc
{
std; // Set the direction flag.
rep;
@ -355,20 +275,7 @@ pure nothrow @system @nogc
// RDI and RSI should be preserved.
mov R9, RDI;
mov R8, RSI;
}
// Set the registers for cmpsb/cmpsq.
version (Windows) asm pure nothrow @nogc
{
// RDX - r1.
// RCX - r2.
mov RDI, [ RCX + 8 ];
mov RSI, [ RDX + 8 ];
mov RDX, [ RDX ];
mov RCX, [ RCX ];
}
else asm pure nothrow @nogc
{
// RDX - r1 length.
// RCX - r1 data.
// RDI - r2 length
@ -377,9 +284,7 @@ pure nothrow @system @nogc
mov RSI, RCX;
mov RCX, RDI;
mov RDI, R8;
}
asm pure nothrow @nogc
{
// Compare the lengths.
cmp RDX, RCX;
jl less;

View File

@ -14,7 +14,11 @@
*/
module tanya.memory.op;
version (D_InlineAsm_X86_64)
version (TanyaPhobos)
{
import core.stdc.string;
}
else
{
static import tanya.memory.arch.x86_64;
}
@ -45,47 +49,14 @@ in
}
body
{
version (D_InlineAsm_X86_64)
version (TanyaPhobos)
{
memcpy(target.ptr, source.ptr, source.length);
}
else
{
tanya.memory.arch.x86_64.copy(source, target);
}
else // Naive implementation.
{
auto source1 = cast(const(ubyte)*) source;
auto target1 = cast(ubyte*) target;
auto count = source.length;
// Check if the pointers are aligned or at least can be aligned
// properly.
ushort naligned = (cast(size_t) source.ptr) & alignMask;
if (naligned == ((cast(size_t) target.ptr) & alignMask))
{
// Align the pointers if possible.
if (naligned != 0)
{
count -= naligned;
while (naligned--)
{
*target1++ = *source1++;
}
}
// Copy size_t.sizeof bytes at once.
auto longSource = cast(const(size_t)*) source1;
auto longTarget = cast(size_t*) target1;
for (; count >= size_t.sizeof; count -= size_t.sizeof)
{
*longTarget++ = *longSource++;
}
// Adjust the original pointers.
source1 = cast(const(ubyte)*) longSource;
target1 = cast(ubyte*) longTarget;
}
// Copy the remaining bytes by one.
while (count--)
{
*target1++ = *source1++;
}
}
}
///
@ -120,58 +91,34 @@ private pure nothrow @safe @nogc unittest
/*
* size_t value each of which bytes is set to `Byte`.
*/
package template FilledBytes(ubyte Byte, ubyte I = 0)
private template filledBytes(ubyte Byte, ubyte I = 0)
{
static if (I == size_t.sizeof)
{
enum size_t FilledBytes = Byte;
enum size_t filledBytes = Byte;
}
else
{
enum size_t FilledBytes = (FilledBytes!(Byte, I + 1) << 8) | Byte;
enum size_t filledBytes = (filledBytes!(Byte, I + 1) << 8) | Byte;
}
}
/**
* Fills $(D_PARAM memory) with single $(D_PARAM Byte)s.
* Fills $(D_PARAM memory) with the single byte $(D_PARAM c).
*
* Param:
* Byte = The value to fill $(D_PARAM memory) with.
* c = The value to fill $(D_PARAM memory) with.
* memory = Memory block.
*/
void fill(ubyte Byte = 0)(void[] memory) @trusted
void fill(ubyte c = 0)(void[] memory) @trusted
{
version (D_InlineAsm_X86_64)
version (TanyaPhobos)
{
tanya.memory.arch.x86_64.fill!Byte(memory);
memset(memory.ptr, c, memory.length);
}
else // Naive implementation.
else
{
auto n = memory.length;
ubyte* vp = cast(ubyte*) memory.ptr;
// Align.
while (((cast(size_t) vp) & alignMask) != 0)
{
*vp++ = Byte;
--n;
}
// Set size_t.sizeof bytes at ones.
auto sp = cast(size_t*) vp;
while (n / size_t.sizeof > 0)
{
*sp++ = FilledBytes!Byte;
n -= size_t.sizeof;
}
// Write the remaining bytes.
vp = cast(ubyte*) sp;
while (n--)
{
*vp = Byte;
++vp;
}
tanya.memory.arch.x86_64.fill(memory, filledBytes!c);
}
}
@ -240,42 +187,14 @@ in
}
body
{
version (D_InlineAsm_X86_64)
version (TanyaPhobos)
{
memmove(target.ptr, source.ptr, source.length);
}
else
{
tanya.memory.arch.x86_64.copyBackward(source, target);
}
else // Naive implementation.
{
auto count = source.length;
// Try to align the pointers if possible.
if (((cast(size_t) source.ptr) & alignMask) == ((cast(size_t) target.ptr) & alignMask))
{
while (((cast(size_t) (source.ptr + count)) & alignMask) != 0)
{
if (!count--)
{
return;
}
(cast(ubyte[]) target)[count]
= (cast(const(ubyte)[]) source)[count];
}
}
// Write as long we're aligned.
for (; count >= size_t.sizeof; count -= size_t.sizeof)
{
*(cast(size_t*) (target.ptr + count - size_t.sizeof))
= *(cast(const(size_t)*) (source.ptr + count - size_t.sizeof));
}
// Write the remaining bytes.
while (count--)
{
(cast(ubyte[]) target)[count]
= (cast(const(ubyte)[]) source)[count];
}
}
}
///
@ -316,60 +235,17 @@ private nothrow @safe @nogc unittest
*/
int cmp(const void[] r1, const void[] r2) pure nothrow @trusted @nogc
{
version (D_InlineAsm_X86_64)
{
return tanya.memory.arch.x86_64.cmp(r1, r2);
}
else // Naive implementation.
version (TanyaPhobos)
{
if (r1.length > r2.length)
{
return 1;
}
else if (r1.length < r2.length)
{
return -1;
}
auto p1 = cast(const(ubyte)*) r1;
auto p2 = cast(const(ubyte)*) r2;
auto count = r1.length;
// Check if the pointers are aligned or at least can be aligned
// properly.
if (((cast(size_t) p1) & alignMask) == ((cast(size_t) p2) & alignMask))
{
// Align the pointers if possible.
for (; ((cast(size_t) p1) & alignMask) != 0; ++p1, ++p2, --count)
{
if (*p1 != *p2)
{
return *p1 - *p2;
}
}
// Compare size_t.sizeof bytes at once.
for (; count >= size_t.sizeof; count -= size_t.sizeof)
{
if (*(cast(const(size_t)*) p1) > *(cast(const(size_t)*) p2))
{
return 1;
}
else if (*(cast(const(size_t)*) p1) < *(cast(const(size_t)*) p2))
{
return -1;
}
p1 += size_t.sizeof;
p2 += size_t.sizeof;
}
}
// Compare the remaining bytes by one.
for (; count--; ++p1, ++p2)
{
if (*p1 != *p2)
{
return *p1 - *p2;
}
}
return 0;
return r1.length < r2.length ? -1 : memcmp(r1.ptr, r2.ptr, r1.length);
}
else
{
return tanya.memory.arch.x86_64.cmp(r1, r2);
}
}

View File

@ -44,12 +44,8 @@ version (Posix)
}
else version (Windows)
{
import core.sys.windows.basetyps : GUID;
import core.sys.windows.mswsock : WSAID_ACCEPTEX;
import core.sys.windows.winbase : LPOVERLAPPED,
GetModuleHandle,
import core.sys.windows.winbase : GetModuleHandle,
GetProcAddress,
GetOverlappedResult,
ERROR_IO_PENDING,
ERROR_IO_INCOMPLETE;
import core.sys.windows.winsock2 : sockaddr,
@ -64,7 +60,6 @@ else version (Windows)
socklen_t,
SOCKADDR,
SOCKADDR_STORAGE,
LPWSAOVERLAPPED_COMPLETION_ROUTINE,
addrinfo,
sockaddr_in,
sockaddr_in6,
@ -92,6 +87,8 @@ else version (Windows)
EPROTOTYPE = WSAEPROTOTYPE,
ETIMEDOUT = WSAETIMEDOUT,
ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT;
import tanya.sys.windows.def;
public import tanya.sys.windows.winbase;
public import tanya.sys.windows.winsock2;
enum SocketType : size_t
@ -101,105 +98,6 @@ else version (Windows)
private alias LingerField = ushort;
struct WSAPROTOCOL_INFO
{
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;
TCHAR[WSAPROTOCOL_LEN + 1] szProtocol;
}
alias LPWSAPROTOCOL_INFO = WSAPROTOCOL_INFO*;
extern (Windows) @nogc nothrow
{
private SOCKET WSASocketW(int af,
int type,
int protocol,
LPWSAPROTOCOL_INFO lpProtocolInfo,
GROUP g,
DWORD dwFlags);
int WSARecv(SOCKET s,
WSABUF* lpBuffers,
DWORD dwBufferCount,
DWORD* lpNumberOfBytesRecvd,
DWORD* lpFlags,
LPOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
int WSASend(SOCKET s,
WSABUF* lpBuffers,
DWORD dwBufferCount,
DWORD* lpNumberOfBytesRecvd,
DWORD lpFlags,
LPOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
int WSAIoctl(SOCKET s,
uint dwIoControlCode,
void* lpvInBuffer,
uint cbInBuffer,
void* lpvOutBuffer,
uint cbOutBuffer,
uint* lpcbBytesReturned,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
alias LPFN_ACCEPTEX = BOOL function(SOCKET,
SOCKET,
void*,
DWORD,
DWORD,
DWORD,
DWORD*,
LPOVERLAPPED);
}
alias WSASocket = WSASocketW;
alias LPFN_GETACCEPTEXSOCKADDRS = void function(void*,
DWORD,
DWORD,
DWORD,
SOCKADDR**,
INT*,
SOCKADDR**,
INT*);
const GUID WSAID_GETACCEPTEXSOCKADDRS = {
0xb5367df2, 0xcbac, 0x11cf,
[ 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 ],
};
struct WSAOVERLAPPED
{
size_t Internal;
size_t InternalHigh;
union
{
struct
{
DWORD Offset;
DWORD OffsetHigh;
}
void* Pointer;
}
HANDLE hEvent;
}
alias LPWSAOVERLAPPED = WSAOVERLAPPED*;
enum SO_UPDATE_ACCEPT_CONTEXT = 0x700B;
enum OverlappedSocketEvent
{
accept = 1,
@ -256,7 +154,7 @@ else version (Windows)
overlapped.buffer.buf = cast(char*) buffer.ptr;
auto result = WSARecv(handle_,
&overlapped.buffer,
cast(WSABUF*) &overlapped.buffer,
1u,
null,
&receiveFlags,

View File

@ -3,6 +3,19 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Base type definitions and aliases.
*
* This module doesn't provide aliases for all types used by Windows, but only
* for types that can vary on different platforms. For example there is no
* need to define `INT32` alias for D, since $(D_KEYWORD int) is always a
* 32-bit signed integer. But `int` and its Windows alias `INT` is not the
* same on all platforms in C, so its size can be something differen than
* 32 bit, therefore an $(D_PSYMBOL INT) alias is available in this module.
* $(D_PARAM TCHAR) can be a $(D_KEYWORD char) if Unicode isn't supported or
* $(D_KEYWORD wchar) if Unicode is supported, so $(D_PSYMBOL TCHAR) is
* defined here.
* Also aliases for specific types like $(D_PSYMBOL SOCKET) are defined here.
*
* Copyright: Eugene Wissner 2017.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
@ -34,6 +47,15 @@ alias BOOL = int;
alias BOOLEAN = BYTE;
alias HANDLE = void*;
enum HANDLE INVALID_HANDLE_VALUE = cast(HANDLE) -1;
enum TRUE = 1;
enum FALSE = 0;
enum FALSE = 0;
align(1) struct GUID
{
uint Data1;
ushort Data2;
ushort Data3;
char[8] Data4;
}

View File

@ -16,5 +16,5 @@ version (Windows):
public import tanya.sys.windows.def;
public import tanya.sys.windows.error;
public import tanya.sys.windows.wdm;
public import tanya.sys.windows.winbase;
public import tanya.sys.windows.winsock2;

View File

@ -1,37 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Copyright: Eugene Wissner 2017.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/sys/windows/wdm.d,
* tanya/sys/windows/wdm.d)
*/
module tanya.sys.windows.wdm;
version (Windows):
extern(Windows)
void RtlCopyMemory(scope void* Destination,
scope const(void)* Source,
size_t Length) pure nothrow @system @nogc;
extern(Windows)
void RtlZeroMemory(scope void* Destination, size_t length)
pure nothrow @system @nogc;
extern(Windows)
void RtlMoveMemory(scope void* Destination,
scope const(void)* Source,
size_t Length) pure nothrow @system @nogc;
extern(Windows)
void RtlFillMemory(scope void* Destination, size_t length, char Fill)
pure nothrow @system @nogc;
extern(Windows)
void* RtlSecureZeroMemory(return void* ptr, size_t cnt)
pure nothrow @system @nogc;

View File

@ -0,0 +1,55 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Definitions from winbase.h.
*
* Copyright: Eugene Wissner 2017.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/sys/windows/winbase.d,
* tanya/sys/windows/winbase.d)
*/
module tanya.sys.windows.winbase;
version (Windows):
public import tanya.sys.windows.def;
struct OVERLAPPED
{
size_t Internal;
size_t InternalHigh;
union
{
struct
{
DWORD Offset;
DWORD OffsetHigh;
}
void* Pointer;
}
HANDLE hEvent;
}
extern(Windows)
HANDLE CreateIoCompletionPort(HANDLE FileHandle,
HANDLE ExistingCompletionPort,
size_t CompletionKey,
DWORD NumberOfConcurrentThreads)
nothrow @system @nogc;
extern(Windows)
BOOL GetQueuedCompletionStatus(HANDLE CompletionPort,
DWORD* lpNumberOfBytes,
size_t* lpCompletionKey,
OVERLAPPED** lpOverlapped,
DWORD dwMilliseconds) nothrow @system @nogc;
extern(Windows)
BOOL GetOverlappedResult(HANDLE hFile,
OVERLAPPED* lpOverlapped,
DWORD* lpNumberOfBytesTransferred,
BOOL bWait) nothrow @system @nogc;

View File

@ -3,6 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Definitions from winsock2.h, ws2def.h and MSWSock.h.
*
* Copyright: Eugene Wissner 2017.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
@ -15,6 +17,7 @@ module tanya.sys.windows.winsock2;
version (Windows):
public import tanya.sys.windows.def;
public import tanya.sys.windows.winbase;
alias SOCKET = size_t;
enum SOCKET INVALID_SOCKET = ~0;
@ -99,4 +102,118 @@ struct WSABUF
{
ULONG len;
CHAR* buf;
}
struct WSAPROTOCOL_INFO
{
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;
TCHAR[WSAPROTOCOL_LEN + 1] szProtocol;
}
const GUID WSAID_GETACCEPTEXSOCKADDRS = {
0xb5367df2, 0xcbac, 0x11cf,
[0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92],
};
const GUID WSAID_ACCEPTEX = {
0xb5367df1, 0xcbac, 0x11cf,
[0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92],
};
alias LPWSAOVERLAPPED_COMPLETION_ROUTINE = void function(DWORD dwError,
DWORD cbTransferred,
OVERLAPPED* lpOverlapped,
DWORD dwFlags) nothrow @nogc;
extern(Windows)
SOCKET WSASocket(int af,
int type,
int protocol,
WSAPROTOCOL_INFO* lpProtocolInfo,
GROUP g,
DWORD dwFlags) nothrow @system @nogc;
extern(Windows)
int WSARecv(SOCKET s,
WSABUF* lpBuffers,
DWORD dwBufferCount,
DWORD* lpNumberOfBytesRecvd,
DWORD* lpFlags,
OVERLAPPED* lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
nothrow @system @nogc;
extern(Windows)
int WSASend(SOCKET s,
WSABUF* lpBuffers,
DWORD dwBufferCount,
DWORD* lpNumberOfBytesRecvd,
DWORD lpFlags,
OVERLAPPED* lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
nothrow @system @nogc;
extern(Windows)
int WSAIoctl(SOCKET s,
uint dwIoControlCode,
void* lpvInBuffer,
uint cbInBuffer,
void* lpvOutBuffer,
uint cbOutBuffer,
uint* lpcbBytesReturned,
OVERLAPPED* lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
nothrow @system @nogc;
alias ADDRESS_FAMILY = USHORT;
struct SOCKADDR
{
ADDRESS_FAMILY sa_family; // Address family.
CHAR[14] sa_data; // Up to 14 bytes of direct address.
}
alias LPFN_GETACCEPTEXSOCKADDRS = void function(void*,
DWORD,
DWORD,
DWORD,
SOCKADDR**,
INT*,
SOCKADDR**,
INT*) nothrow @nogc;
alias LPFN_ACCEPTEX = extern(Windows) BOOL function(SOCKET,
SOCKET,
void*,
DWORD,
DWORD,
DWORD,
DWORD*,
OVERLAPPED*) @nogc nothrow;
enum
{
SO_MAXDG = 0x7009,
SO_MAXPATHDG = 0x700A,
SO_UPDATE_ACCEPT_CONTEXT = 0x700B,
SO_CONNECT_TIME = 0x700C,
SO_UPDATE_CONNECT_CONTEXT = 0x7010,
}