1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
#include "HsNet.h"
#include <string.h>
#ifdef _WIN32
LPWSACMSGHDR cmsg_firsthdr(LPWSAMSG mhdr) {
return (WSA_CMSG_FIRSTHDR(mhdr));
}
LPWSACMSGHDR cmsg_nxthdr(LPWSAMSG mhdr, LPWSACMSGHDR cmsg) {
return (WSA_CMSG_NXTHDR(mhdr, cmsg));
}
unsigned char *cmsg_data(LPWSACMSGHDR cmsg) {
return (WSA_CMSG_DATA(cmsg));
}
unsigned int cmsg_space(unsigned int l) {
return (WSA_CMSG_SPACE(l));
}
unsigned int cmsg_len(unsigned int l) {
return (WSA_CMSG_LEN(l));
}
static LPFN_WSASENDMSG ptr_SendMsg;
static LPFN_WSARECVMSG ptr_RecvMsg;
/* GUIDS to lookup WSASend/RecvMsg */
static GUID WSARecvMsgGUID = WSAID_WSARECVMSG;
static GUID WSASendMsgGUID = WSAID_WSASENDMSG;
int WINAPI
WSASendMsg (SOCKET s, LPWSAMSG lpMsg, DWORD flags,
LPDWORD lpdwNumberOfBytesRecvd, LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
if (!ptr_SendMsg) {
DWORD len;
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
&WSASendMsgGUID, sizeof(WSASendMsgGUID), &ptr_SendMsg,
sizeof(ptr_SendMsg), &len, NULL, NULL) != 0)
return -1;
}
return ptr_SendMsg (s, lpMsg, flags, lpdwNumberOfBytesRecvd, lpOverlapped,
lpCompletionRoutine);
}
/**
* WSARecvMsg function
*/
int WINAPI
WSARecvMsg (SOCKET s, LPWSAMSG lpMsg, LPDWORD lpdwNumberOfBytesRecvd,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
if (!ptr_RecvMsg) {
DWORD len;
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
&WSARecvMsgGUID, sizeof(WSARecvMsgGUID), &ptr_RecvMsg,
sizeof(ptr_RecvMsg), &len, NULL, NULL) != 0)
return -1;
}
int res = ptr_RecvMsg (s, lpMsg, lpdwNumberOfBytesRecvd, lpOverlapped,
lpCompletionRoutine);
/* If the msg was truncated then this pointer can be garbage. */
if (res == SOCKET_ERROR && GetLastError () == WSAEMSGSIZE)
{
lpMsg->Control.len = 0;
lpMsg->Control.buf = NULL;
}
return res;
}
#else
struct cmsghdr *cmsg_firsthdr(struct msghdr *mhdr) {
return (CMSG_FIRSTHDR(mhdr));
}
struct cmsghdr *cmsg_nxthdr(struct msghdr *mhdr, struct cmsghdr *cmsg) {
return (CMSG_NXTHDR(mhdr, cmsg));
}
unsigned char *cmsg_data(struct cmsghdr *cmsg) {
return (CMSG_DATA(cmsg));
}
size_t cmsg_space(size_t l) {
return (CMSG_SPACE(l));
}
size_t cmsg_len(size_t l) {
return (CMSG_LEN(l));
}
#endif /* _WIN32 */
|