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; - 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; 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,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); } } 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