DoxigAlpha

WSASocketW

Microsoft requires WSAStartup to be called to initialize, or else WSASocketW will return WSANOTINITIALISED. Since this is a standard library, we do not have the luxury of putting initialization code anywhere, because we would not want to pay the cost of calling WSAStartup if there ended up being no networking. Also, if Zig code is used as a library, Zig is not in charge of the start code, and we couldn't put in any initialization code even if we wanted to. The documentation for WSAStartup mentions that there must be a matching WSACleanup call. It is not possible for the Zig Standard Library to honor this for the same reason - there is nowhere to put deinitialization code. So, API users of the zig std lib have two options:

  • (recommended) The simple, cross-platform way: just call WSASocketW and don't worry about it. Zig will call WSAStartup() in a thread-safe manner and never deinitialize networking. This is ideal for an application which has the capability to do networking.
  • The getting-your-hands-dirty way: call WSAStartup() before doing networking, so that the error handling code for WSANOTINITIALISED never gets run, which then allows the application or library to call WSACleanup(). This could make sense for a library, which has init and deinit functions for the whole library's lifetime.

Function parameters

Parameters

#
af:i32
socket_type:i32
protocol:i32
protocolInfo:?*ws2_32.WSAPROTOCOL_INFOW
g:ws2_32.GROUP

Type definitions in this namespace

Types

#
GetFinalPathNameByHandleFormat
Specifies how to format volume path in the result of `GetFinalPathNameByHandle`.
TransferType
https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/buffer-descriptions-for-i-o-control-codes
PEB
Process Environment Block
PEB_LDR_DATA
The `PEB_LDR_DATA` structure is the main record of what modules are loaded in a process.
LDR_DATA_TABLE_ENTRY
Microsoft documentation of this is incomplete, the fields here are taken from various resources including:
PF
Processor feature enumeration.
KUSER_SHARED_DATA
Shared Kernel User Data

Functions in this namespace

Functions

#
CreatePipe
A Zig wrapper around `NtCreateNamedPipeFile` and `NtCreateFile` syscalls.
DeviceIoControl
A Zig wrapper around `NtDeviceIoControlFile` and `NtFsControlFile` syscalls.
RtlGenRandom
Call RtlGenRandom() instead of CryptGetRandom() on Windows
ReadFile
If buffer's length exceeds what a Windows DWORD integer can hold, it will be broken into
GetCurrentDirectory
The result is a slice of `buffer`, indexed from 0.
CreateSymbolicLink
Needs either:
SetFilePointerEx_BEGIN
The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_BEGIN`.
SetFilePointerEx_CURRENT
The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_CURRENT`.
SetFilePointerEx_END
The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_END`.
SetFilePointerEx_CURRENT_get
The SetFilePointerEx function with parameters to get the current offset.
GetFinalPathNameByHandle
Returns canonical (normalized) path of handle.
WSASocketW
Microsoft requires WSAStartup to be called to initialize, or else
fromSysTime
A file time is a 64-bit value that represents the number of 100-nanosecond
nanoSecondsToFileTime
Converts a number of nanoseconds since the POSIX epoch to a Windows FILETIME.
eqlIgnoreCaseWTF16
Compares two WTF16 strings using the equivalent functionality of
eqlIgnoreCaseWtf8
Compares two WTF-8 strings using the equivalent functionality of
removeDotDirsSanitized
Removes '.' and '..' path components from a "sanitized relative path".
normalizePath
Normalizes a Windows path with the following steps:
cStrToPrefixedFileW
Same as `sliceToPrefixedFileW` but accepts a pointer
sliceToPrefixedFileW
Same as `wToPrefixedFileW` but accepts a WTF-8 encoded path.
wToPrefixedFileW
Converts the `path` to WTF16, null-terminated.
getNamespacePrefix
If `T` is `u16`, then `path` should be encoded as WTF-16LE.
getUnprefixedPathType
Get the path type of a path that is known to not have any namespace prefixes
ntToWin32Namespace
Similar to `RtlNtPathNameToDosPathName` but does not do any heap allocation.
loadWinsockExtensionFunction
Loads a Winsock extension function in runtime specified by a GUID.
unexpectedError
Call this when you made a windows DLL call or something that does SetLastError
unexpectedStatus
Call this when you made a windows NtDll call
CTL_CODE
https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
FileInformationIterator
Helper for iterating a byte buffer of FILE_*_INFORMATION structures (from
ProcessBaseAddress
Returns the base address of the process loaded into memory.

Error sets in this namespace

Error Sets

#
RemoveDotDirsError
The error type for `removeDotDirsSanitized`

= @as(HANDLE, @ptrFromInt(maxInt(usize)))

Values

#
self_process_handle
= @as(HANDLE, @ptrFromInt(maxInt(usize)))
STD_INPUT_HANDLE
The standard input device.
STD_OUTPUT_HANDLE
The standard output device.
STD_ERROR_HANDLE
The standard error device.
TCHAR
= @compileError("Deprecated: choose between `CHAR` or `WCHAR` directly instead.")
LPTSTR
= @compileError("Deprecated: choose between `LPSTR` or `LPWSTR` directly instead.")
LPCTSTR
= @compileError("Deprecated: choose between `LPCSTR` or `LPCWSTR` directly instead.")
PTSTR
= @compileError("Deprecated: choose between `PSTR` or `PWSTR` directly instead.")
PCTSTR
= @compileError("Deprecated: choose between `PCSTR` or `PCWSTR` directly instead.")
TRUE
= 1
INVALID_HANDLE_VALUE
= @as(HANDLE, @ptrFromInt(maxInt(usize)))
INVALID_FILE_ATTRIBUTES
= @as(DWORD, maxInt(DWORD))
reparse_tag_name_surrogate_bit
"If this bit is set, the file or directory represents another named entity in the system."
FILE_NAME_NORMALIZED
Return the normalized drive name.
FILE_NAME_OPENED
Return the opened file name (not normalized).
VOLUME_NAME_DOS
Return the path with the drive letter.
VOLUME_NAME_GUID
Return the path with a volume GUID path instead of the drive name.
VOLUME_NAME_NONE
Return the path with no drive information.
VOLUME_NAME_NT
Return the path with the volume device path.
PIPE_ACCESS_DUPLEX
= 0x00000003
PIPE_TYPE_BYTE
= 0x00000000
PIPE_TYPE_MESSAGE
= 0x00000004
PIPE_READMODE_BYTE
= 0x00000000
PIPE_WAIT
= 0x00000000
PIPE_NOWAIT
= 0x00000001
GENERIC_READ
= 0x80000000
GENERIC_WRITE
= 0x40000000
GENERIC_EXECUTE
= 0x20000000
GENERIC_ALL
= 0x10000000
FILE_SHARE_DELETE
= 0x00000004
FILE_SHARE_READ
= 0x00000001
FILE_SHARE_WRITE
= 0x00000002
DELETE
= 0x00010000
READ_CONTROL
= 0x00020000
WRITE_DAC
= 0x00040000
WRITE_OWNER
= 0x00080000
SYNCHRONIZE
= 0x00100000
STANDARD_RIGHTS_READ
= READ_CONTROL
STANDARD_RIGHTS_WRITE
= READ_CONTROL
STANDARD_RIGHTS_REQUIRED
= DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER
MAXIMUM_ALLOWED
= 0x02000000
FILE_READ_DATA
= 0x00000001
FILE_WRITE_DATA
= 0x00000002
FILE_ADD_FILE
= 0x00000002
FILE_APPEND_DATA
= 0x00000004
FILE_READ_EA
= 0x00000008
FILE_WRITE_EA
= 0x00000010
FILE_EXECUTE
= 0x00000020
FILE_TRAVERSE
= 0x00000020
FILE_DELETE_CHILD
= 0x00000040
FILE_WRITE_THROUGH
= 0x00000002
FILE_RANDOM_ACCESS
= 0x00000800
FILE_ALL_ACCESS
= STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1ff
FILE_GENERIC_READ
= STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE
FILE_GENERIC_WRITE
= STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE
FILE_GENERIC_EXECUTE
= STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE
MEM_IMAGE
= 0x1000000
MEM_MAPPED
= 0x40000
MEM_PRIVATE
= 0x20000
STARTF_USEHOTKEY
= 0x00000200
STARTF_USEPOSITION
= 0x00000004
STARTF_USESIZE
= 0x00000002
INFINITE
= 4294967295
WAIT_ABANDONED
= 0x00000080
WAIT_ABANDONED_0
= WAIT_ABANDONED + 0
WAIT_OBJECT_0
= 0x00000000
WAIT_TIMEOUT
= 0x00000102
WAIT_FAILED
= 0xFFFFFFFF
HEAP_NO_SERIALIZE
= 0x00000001
MEM_COMMIT
= 0x1000
MEM_RESERVE
= 0x2000
MEM_FREE
= 0x10000
MEM_RESET
= 0x80000
MEM_RESET_UNDO
= 0x1000000
MEM_LARGE_PAGES
= 0x20000000
MEM_PHYSICAL
= 0x400000
MEM_TOP_DOWN
= 0x100000
MEM_WRITE_WATCH
= 0x200000
PAGE_GUARD
= 0x100
MEM_DECOMMIT
= 0x4000
MEM_RELEASE
= 0x8000
FOLDERID_LocalAppData
= GUID.parse("{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}")
KF_FLAG_ALIAS_ONLY
= -2147483648
S_OK
= 0
S_FALSE
= 0x00000001
E_NOTIMPL
= @as(c_long, @bitCast(@as(c_ulong, 0x80004001)))
E_NOINTERFACE
= @as(c_long, @bitCast(@as(c_ulong, 0x80004002)))
E_POINTER
= @as(c_long, @bitCast(@as(c_ulong, 0x80004003)))
E_ABORT
= @as(c_long, @bitCast(@as(c_ulong, 0x80004004)))
E_FAIL
= @as(c_long, @bitCast(@as(c_ulong, 0x80004005)))
E_UNEXPECTED
= @as(c_long, @bitCast(@as(c_ulong, 0x8000FFFF)))
E_ACCESSDENIED
= @as(c_long, @bitCast(@as(c_ulong, 0x80070005)))
E_HANDLE
= @as(c_long, @bitCast(@as(c_ulong, 0x80070006)))
E_OUTOFMEMORY
= @as(c_long, @bitCast(@as(c_ulong, 0x8007000E)))
E_INVALIDARG
= @as(c_long, @bitCast(@as(c_ulong, 0x80070057)))
TLS_OUT_OF_INDEXES
= 4294967295
SECTION_ALL_ACCESS
= STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE
SEC_64K_PAGES
= 0x80000
SEC_FILE
= 0x800000
SEC_IMAGE
= 0x1000000
SEC_RESERVE
= 0x4000000
SEC_COMMIT
= 0x8000000
SEC_IMAGE_NO_EXECUTE
= SEC_IMAGE | SEC_NOCACHE
SEC_NOCACHE
= 0x10000000
SEC_WRITECOMBINE
= 0x40000000
SEC_LARGE_PAGES
= 0x80000000
HKEY_CLASSES_ROOT
= @ptrFromInt(0x80000000)
HKEY_CURRENT_USER
= @ptrFromInt(0x80000001)
HKEY_LOCAL_MACHINE
= @ptrFromInt(0x80000002)
HKEY_USERS
= @ptrFromInt(0x80000003)
HKEY_PERFORMANCE_DATA
= @ptrFromInt(0x80000004)
HKEY_PERFORMANCE_TEXT
= @ptrFromInt(0x80000050)
HKEY_PERFORMANCE_NLSTEXT
= @ptrFromInt(0x80000060)
HKEY_CURRENT_CONFIG
= @ptrFromInt(0x80000005)
HKEY_DYN_DATA
= @ptrFromInt(0x80000006)
HKEY_CURRENT_USER_LOCAL_SETTINGS
= @ptrFromInt(0x80000007)
KEY_ALL_ACCESS
Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY,
KEY_CREATE_LINK
Reserved for system use.
KEY_CREATE_SUB_KEY
Required to create a subkey of a registry key.
KEY_ENUMERATE_SUB_KEYS
Required to enumerate the subkeys of a registry key.
KEY_EXECUTE
Equivalent to KEY_READ.
KEY_NOTIFY
Required to request change notifications for a registry key or for subkeys of a registry key.
KEY_QUERY_VALUE
Required to query the values of a registry key.
KEY_READ
Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
KEY_SET_VALUE
Required to create, delete, or set a registry value.
KEY_WOW64_32KEY
Indicates that an application on 64-bit Windows should operate on the 32-bit registry view.
KEY_WOW64_64KEY
Indicates that an application on 64-bit Windows should operate on the 64-bit registry view.
KEY_WRITE
Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.
REG_OPTION_OPEN_LINK
Open symbolic link.
RTL_REGISTRY_ABSOLUTE
Path is a full path
RTL_REGISTRY_SERVICES
\Registry\Machine\System\CurrentControlSet\Services
RTL_REGISTRY_CONTROL
\Registry\Machine\System\CurrentControlSet\Control
RTL_REGISTRY_WINDOWS_NT
\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
RTL_REGISTRY_DEVICEMAP
\Registry\Machine\Hardware\DeviceMap
RTL_REGISTRY_USER
\Registry\User\CurrentUser
RTL_REGISTRY_HANDLE
Low order bits are registry handle
RTL_REGISTRY_OPTIONAL
Indicates the key node is optional
RTL_QUERY_REGISTRY_SUBKEY
Name is a subkey and remainder of table or until next subkey are value
RTL_QUERY_REGISTRY_TOPKEY
Reset current key to original key for this and all following table entries.
RTL_QUERY_REGISTRY_REQUIRED
Fail if no match found for this table entry.
RTL_QUERY_REGISTRY_NOVALUE
Used to mark a table entry that has no value name, just wants a call out, not
RTL_QUERY_REGISTRY_NOEXPAND
Used to suppress the expansion of REG_MULTI_SZ into multiple callouts or
RTL_QUERY_REGISTRY_DIRECT
QueryRoutine field ignored.
RTL_QUERY_REGISTRY_DELETE
Used to delete value keys after they are queried.
RTL_QUERY_REGISTRY_TYPECHECK
Use this flag with the RTL_QUERY_REGISTRY_DIRECT flag to verify that the REG_XXX type
FILE_ACTION_ADDED
= 0x00000001
INIT_ONCE_STATIC_INIT
= RTL_RUN_ONCE_INIT
RTL_RUN_ONCE_INIT
= RTL_RUN_ONCE{ .Ptr = null }
PATH_MAX_WIDE
> The maximum path of 32,767 characters is approximate, because the "\\?\"
NAME_MAX
> [Each file name component can be] up to the value returned in the
OBJ_INHERIT
= 0x00000002
OBJ_PERMANENT
= 0x00000010
OBJ_EXCLUSIVE
= 0x00000020
OBJ_OPENIF
= 0x00000080
OBJ_OPENLINK
= 0x00000100
OBJ_KERNEL_HANDLE
= 0x00000200
IOCTL_MOUNTMGR_QUERY_POINTS
= CTL_CODE(MOUNTMGRCONTROLTYPE, 2, .METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
= CTL_CODE(MOUNTMGRCONTROLTYPE, 12, .METHOD_BUFFERED, FILE_ANY_ACCESS)
SRWLOCK_INIT
= SRWLOCK{}
CONDITION_VARIABLE_INIT
= CONDITION_VARIABLE{}
SharedUserData
Read-only user-mode address for the shared data.
TH32CS_SNAPPROCESS
= 0x00000002
TH32CS_SNAPTHREAD
= 0x00000004
TH32CS_SNAPMODULE
= 0x00000008
TH32CS_SNAPALL
= TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE
TH32CS_INHERIT
= 0x80000000

Source

Implementation

#
pub fn WSASocketW(
    af: i32,
    socket_type: i32,
    protocol: i32,
    protocolInfo: ?*ws2_32.WSAPROTOCOL_INFOW,
    g: ws2_32.GROUP,
    dwFlags: DWORD,
) !ws2_32.SOCKET {
    var first = true;
    while (true) {
        const rc = ws2_32.WSASocketW(af, socket_type, protocol, protocolInfo, g, dwFlags);
        if (rc == ws2_32.INVALID_SOCKET) {
            switch (ws2_32.WSAGetLastError()) {
                .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
                .WSAEMFILE => return error.ProcessFdQuotaExceeded,
                .WSAENOBUFS => return error.SystemResources,
                .WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,
                .WSANOTINITIALISED => {
                    if (!first) return error.Unexpected;
                    first = false;
                    try callWSAStartup();
                    continue;
                },
                else => |err| return unexpectedWSAError(err),
            }
        }
        return rc;
    }
}