Skip to content

Commit

Permalink
Fea #80, WSAIoctl添加SIO_BASE_HANDLE模拟(PR #124
Browse files Browse the repository at this point in the history
  • Loading branch information
stevefan1999-personal authored and mingkuang-Chuyu committed Oct 22, 2024
1 parent 761fe75 commit 0b415bf
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
3 changes: 2 additions & 1 deletion ThunksList.md
Original file line number Diff line number Diff line change
Expand Up @@ -813,4 +813,5 @@
| FreeAddrInfoEx(W) | 不存在时,内部实现。
| GetAddrInfoW | 不存在时,调用getaddrinfo。
| FreeAddrInfoW | 不存在时,内部实现。
| WSASocketW(A) | 低于6.1.7601时自动去除 `WSA_FLAG_NO_HANDLE_INHERIT`
| WSASocketW(A) | 低于6.1.7601时自动去除 `WSA_FLAG_NO_HANDLE_INHERIT`
| WSAIoctl | 低于6.0时,`SIO_BASE_HANDLE` 代码返回SOCKET自身。
60 changes: 60 additions & 0 deletions src/Thunks/WS2_32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#endif // ! FreeAddrInfoEx
#endif

#if (YY_Thunks_Target < __WindowsNT6)
#include <Mswsock.h>
#endif

#if (YY_Thunks_Target < __WindowsNT6_1_SP1) && !defined(__Comment_Lib_ws2_32)
#define __Comment_Lib_ws2_32
#pragma comment(lib, "Ws2_32.lib")
Expand Down Expand Up @@ -1471,6 +1475,62 @@ namespace YY::Thunks
#endif


#if (YY_Thunks_Target < __WindowsNT6)

// Windows XP就支持
// 但是 Windows XP不支持 SIO_BASE_HANDLE
__DEFINE_THUNK(
ws2_32,
36,
int,
WSAAPI,
WSAIoctl,
_In_ SOCKET s,
_In_ DWORD dwIoControlCode,
_In_reads_bytes_opt_(cbInBuffer) LPVOID lpvInBuffer,
_In_ DWORD cbInBuffer,
_Out_writes_bytes_to_opt_(cbOutBuffer, *lpcbBytesReturned) LPVOID lpvOutBuffer,
_In_ DWORD cbOutBuffer,
_Out_ LPDWORD lpcbBytesReturned,
_Inout_opt_ LPWSAOVERLAPPED lpOverlapped,
_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
{
// Upon successful completion, the WSAIoctl returns zero. Otherwise, a value of SOCKET_ERROR is returned,
// and a specific error code can be retrieved by calling WSAGetLastError.
auto const _pfnWSAIoctl = try_get_WSAIoctl();
if (!_pfnWSAIoctl)
{
WSASetLastError(WSAVERNOTSUPPORTED);
return SOCKET_ERROR;
}

if (dwIoControlCode == SIO_BASE_HANDLE && internal::GetSystemVersion() < internal::MakeVersion(6, 0))
{
// So while we do have layered service providers in Windows XP or earlier, this specific io control is not supported.
// Worse, LSP is actually deprecated since Windows Server 2012, meaning this io control should likely return the socket
// input on later OS as well (effectively bypassed the LSPs)
// So almost nobody except mio's library uses this io control...god help...

if (lpvOutBuffer == nullptr || lpcbBytesReturned == nullptr)
{
// https://learn.microsoft.com/zh-cn/windows/win32/winsock/winsock-ioctls#sio_bsp_handle-opcode-setting-o-t1
// If the output buffer is not large enough for a socket handle (the cbOutBuffer is less than the size of a SOCKET) or the lpvOutBuffer
// parameter is a NULL pointer, SOCKET_ERROR is returned as the result of this IOCTL and WSAGetLastError returns WSAEFAULT.
WSASetLastError(WSAEFAULT);
return SOCKET_ERROR;
}

*(SOCKET*)lpvOutBuffer = s;
*lpcbBytesReturned = sizeof(SOCKET);
return 0;
}

return _pfnWSAIoctl(s, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpOverlapped, lpCompletionRoutine);
}
#endif


#if (YY_Thunks_Target < __WindowsNT6_1_SP1)

// Windows XP
Expand Down

0 comments on commit 0b415bf

Please sign in to comment.