summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/tanya/async/event/iocp.d4
-rw-r--r--source/tanya/async/iocp.d3
-rw-r--r--source/tanya/memory/arch/x86_64.d383
-rw-r--r--source/tanya/memory/op.d182
-rw-r--r--source/tanya/network/socket.d110
-rw-r--r--source/tanya/sys/windows/def.d24
-rw-r--r--source/tanya/sys/windows/package.d2
-rw-r--r--source/tanya/sys/windows/wdm.d37
-rw-r--r--source/tanya/sys/windows/winbase.d55
-rw-r--r--source/tanya/sys/windows/winsock2.d117
10 files changed, 376 insertions, 541 deletions
diff --git a/source/tanya/async/event/iocp.d b/source/tanya/async/event/iocp.d
index e682ab9..3544900 100644
--- a/source/tanya/async/event/iocp.d
+++ b/source/tanya/async/event/iocp.d
@@ -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,
diff --git a/source/tanya/async/iocp.d b/source/tanya/async/iocp.d
index afe16ef..1a72c60 100644
--- a/source/tanya/async/iocp.d
+++ b/source/tanya/async/iocp.d
@@ -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)
diff --git a/source/tanya/memory/arch/x86_64.d b/source/tanya/memory/arch/x86_64.d
index 6cae323..57e1563 100644
--- a/source/tanya/memory/arch/x86_64.d
+++ b/source/tanya/memory/arch/x86_64.d
@@ -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;
+
+ // 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;
- 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");
-
- 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;
-
- test R10, R10;
- 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.
-
- // Advance the pointer. Decrease the total number of bytes
- // and the misaligned ones.
- inc R9;
- dec RDX;
- dec R8;
-
- // Checks if we are aligned.
- test RDX, RDX;
- jnz naligned;
-
- aligned:
- // Checks if we're done writing bytes.
- test R8, R8;
- jz end;
-
- // Write 1 byte at a time.
- cmp R8, 8;
- jl aligned_1;
-
- // Write 8 bytes at a time.
- cmp R8, 16;
- jl aligned_8;
-
- // Write 16 bytes at a time.
- cmp R8, 32;
- jl aligned_16;
-
- // Write 32 bytes at a time.
- cmp R8, 64;
- jl aligned_32;
-
- aligned_64:
- movdqa [ R9 ], XMM0;
- movdqa [ R9 + 16 ], XMM0;
- movdqa [ R9 + 32 ], XMM0;
- movdqa [ R9 + 48 ], XMM0;
-
- add R9, 64;
- sub R8, 64;
-
- cmp R8, 64;
- jge aligned_64;
-
- // Checks if we're done writing bytes.
- test R8, R8;
- jz end;
-
- // Write 1 byte at a time.
- cmp R8, 8;
- jl aligned_1;
-
- // Write 8 bytes at a time.
- cmp R8, 16;
- jl aligned_8;
-
- // Write 16 bytes at a time.
- cmp R8, 32;
- jl aligned_16;
-
- aligned_32:
- movdqa [ R9 ], XMM0;
- movdqa [ R9 + 16 ], XMM0;
-
- add R9, 32;
- sub R8, 32;
-
- // Checks if we're done writing bytes.
- test R8, R8;
- jz end;
-
- // Write 1 byte at a time.
- cmp R8, 8;
- jl aligned_1;
-
- // Write 8 bytes at a time.
- cmp R8, 16;
- jl aligned_8;
-
- aligned_16:
- movdqa [ R9 ], XMM0;
-
- add R9, 16;
- sub R8, 16;
+ mov R9, RDX;
+ sub R9, R8;
- // Checks if we're done writing bytes.
- test R8, R8;
- jz end;
+ test R9, R9;
+ jz aligned;
- // Write 1 byte at a time.
- cmp R8, 8;
- jl aligned_1;
+ // Get the number of bytes to be written until we are aligned.
+ mov RCX, 0x10;
+ sub RCX, R9;
- aligned_8:
- mov [ R9 ], RAX;
+ mov R8, RDX;
- add R9, 8;
- sub R8, 8;
+ naligned:
+ mov [ R8 ], DIL; // Write a byte.
- // 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;
- aligned_1:
- mov [ R9 ], AL;
+ // Checks if we are aligned.
+ test RCX, RCX;
+ jnz naligned;
+
+ aligned:
+ // Checks if we're done writing bytes.
+ test RAX, RAX;
+ jz end;
+
+ // Write 1 byte at a time.
+ cmp RAX, 8;
+ jl aligned_1;
+
+ // Write 8 bytes at a time.
+ cmp RAX, 16;
+ jl aligned_8;
+
+ // Write 16 bytes at a time.
+ cmp RAX, 32;
+ jl aligned_16;
+
+ // Write 32 bytes at a time.
+ cmp RAX, 64;
+ jl aligned_32;
+
+ aligned_64:
+ movdqa [ R8 ], XMM0;
+ movdqa [ R8 + 16 ], XMM0;
+ movdqa [ R8 + 32 ], XMM0;
+ movdqa [ R8 + 48 ], XMM0;
+
+ add R8, 64;
+ sub RAX, 64;
- inc R9;
- dec R8;
+ cmp RAX, 64;
+ jge aligned_64;
- test R8, R8;
- jnz aligned_1;
+ // Checks if we're done writing bytes.
+ test RAX, RAX;
+ jz end;
+
+ // Write 1 byte at a time.
+ cmp RAX, 8;
+ jl aligned_1;
+
+ // Write 8 bytes at a time.
+ cmp RAX, 16;
+ jl aligned_8;
+
+ // Write 16 bytes at a time.
+ cmp RAX, 32;
+ jl aligned_16;
+
+ aligned_32:
+ movdqa [ R8 ], XMM0;
+ movdqa [ R8 + 16 ], XMM0;
+
+ add R8, 32;
+ sub RAX, 32;
+
+ // Checks if we're done writing bytes.
+ test RAX, RAX;
+ jz end;
- end:
- ret;
- }
+ // Write 1 byte at a time.
+ cmp RAX, 8;
+ jl aligned_1;
+
+ // Write 8 bytes at a time.
+ cmp RAX, 16;
+ jl aligned_8;
+
+ aligned_16:
+ movdqa [ R8 ], XMM0;
+
+ add R8, 16;
+ sub RAX, 16;
+
+ // Checks if we're done writing bytes.
+ test RAX, RAX;
+ jz end;
+
+ // Write 1 byte at a time.
+ cmp RAX, 8;
+ jl aligned_1;
+
+ aligned_8:
+ mov [ R8 ], RDI;
+
+ add R8, 8;
+ sub RAX, 8;
+
+ // Checks if we're done writing bytes.
+ test RAX, RAX;
+ jz end;
+
+ aligned_1:
+ mov [ R8 ], DIL;
+
+ 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;
diff --git a/source/tanya/memory/op.d b/source/tanya/memory/op.d
index d415ed4..beb37b5 100644
--- a/source/tanya/memory/op.d
+++ b/source/tanya/memory/op.d
@@ -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,46 +49,13 @@ in
}
body
{
- version (D_InlineAsm_X86_64)
+ version (TanyaPhobos)
{
- tanya.memory.arch.x86_64.copy(source, target);
+ memcpy(target.ptr, source.ptr, source.length);
}
- else // Naive implementation.
+ else
{
- 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++;
- }
+ tanya.memory.arch.x86_64.copy(source, target);
}
}
@@ -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,41 +187,13 @@ in
}
body
{
- version (D_InlineAsm_X86_64)
+ version (TanyaPhobos)
{
- tanya.memory.arch.x86_64.copyBackward(source, target);
+ memmove(target.ptr, source.ptr, source.length);
}
- else // Naive implementation.
+ else
{
- 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];
- }
+ tanya.memory.arch.x86_64.copyBackward(source, target);
}
}
@@ -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);
}
}
diff --git a/source/tanya/network/socket.d b/source/tanya/network/socket.d
index eb193be..114ee83 100644
--- a/source/tanya/network/socket.d
+++ b/source/tanya/network/socket.d
@@ -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,
diff --git a/source/tanya/sys/windows/def.d b/source/tanya/sys/windows/def.d
index 6b0634e..f4e5d04 100644
--- a/source/tanya/sys/windows/def.d
+++ b/source/tanya/sys/windows/def.d
@@ -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; \ No newline at end of file
+enum FALSE = 0;
+
+align(1) struct GUID
+{
+ uint Data1;
+ ushort Data2;
+ ushort Data3;
+ char[8] Data4;
+} \ No newline at end of file
diff --git a/source/tanya/sys/windows/package.d b/source/tanya/sys/windows/package.d
index 9bf1432..07b17d7 100644
--- a/source/tanya/sys/windows/package.d
+++ b/source/tanya/sys/windows/package.d
@@ -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; \ No newline at end of file
diff --git a/source/tanya/sys/windows/wdm.d b/source/tanya/sys/windows/wdm.d
deleted file mode 100644
index a55a075..0000000
--- a/source/tanya/sys/windows/wdm.d
+++ /dev/null
@@ -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; \ No newline at end of file
diff --git a/source/tanya/sys/windows/winbase.d b/source/tanya/sys/windows/winbase.d
new file mode 100644
index 0000000..bbcc712
--- /dev/null
+++ b/source/tanya/sys/windows/winbase.d
@@ -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; \ No newline at end of file
diff --git a/source/tanya/sys/windows/winsock2.d b/source/tanya/sys/windows/winsock2.d
index 31139d0..c9bae7f 100644
--- a/source/tanya/sys/windows/winsock2.d
+++ b/source/tanya/sys/windows/winsock2.d
@@ -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,
} \ No newline at end of file