Created
March 29, 2015 13:28
-
-
Save daurnimator/63d2970aedc952f0beb3 to your computer and use it in GitHub Desktop.
windows low level polling. compile with: cl /EHsc /Wall /WX main.c afd.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma warning(push, 3) | |
#define WIN32_LEAN_AND_MEAN | |
#include <windows.h> | |
#include <Winternl.h> | |
#pragma comment(lib, "Ntdll.lib") | |
#pragma warning(pop) | |
#include "afd.h" | |
HANDLE CreateAfdHandle(void) { | |
HANDLE afd; | |
UNICODE_STRING afdName; | |
OBJECT_ATTRIBUTES objectAttributes; | |
IO_STATUS_BLOCK ioStatusBlock; | |
NTSTATUS status; | |
RtlInitUnicodeString(&afdName, L"\\Device\\Afd"); | |
InitializeObjectAttributes(&objectAttributes, &afdName, 0, NULL, NULL); | |
status = NtCreateFile( | |
(PHANDLE)&afd, | |
SYNCHRONIZE, | |
&objectAttributes, | |
&ioStatusBlock, | |
NULL, | |
0, | |
FILE_SHARE_READ | FILE_SHARE_WRITE, | |
FILE_OPEN, | |
0, | |
NULL, | |
0 | |
); | |
if (!NT_SUCCESS(status)) { | |
SetLastError(RtlNtStatusToDosError(status)); | |
return INVALID_HANDLE_VALUE; | |
} | |
return afd; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma warning(push, 3) | |
#include <ws2tcpip.h> | |
#pragma warning(pop) | |
typedef struct _AFD_POLL_HANDLE_INFO { | |
HANDLE Handle; | |
ULONG Events; | |
NTSTATUS Status; | |
} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO; | |
#pragma warning(disable: 4200) | |
typedef struct _AFD_POLL_INFO { | |
LARGE_INTEGER Timeout; | |
ULONG NumberOfHandles; | |
ULONG Exclusive; | |
AFD_POLL_HANDLE_INFO Handles[]; | |
} AFD_POLL_INFO, *PAFD_POLL_INFO; | |
#define AFD_NO_FAST_IO 0x00000001 | |
#define AFD_OVERLAPPED 0x00000002 | |
#define AFD_IMMEDIATE 0x00000004 | |
#define AFD_POLL_RECEIVE_BIT 0 | |
#define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT) | |
#define AFD_POLL_RECEIVE_EXPEDITED_BIT 1 | |
#define AFD_POLL_RECEIVE_EXPEDITED (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT) | |
#define AFD_POLL_SEND_BIT 2 | |
#define AFD_POLL_SEND (1 << AFD_POLL_SEND_BIT) | |
#define AFD_POLL_DISCONNECT_BIT 3 | |
#define AFD_POLL_DISCONNECT (1 << AFD_POLL_DISCONNECT_BIT) | |
#define AFD_POLL_ABORT_BIT 4 | |
#define AFD_POLL_ABORT (1 << AFD_POLL_ABORT_BIT) | |
#define AFD_POLL_LOCAL_CLOSE_BIT 5 | |
#define AFD_POLL_LOCAL_CLOSE (1 << AFD_POLL_LOCAL_CLOSE_BIT) | |
#define AFD_POLL_CONNECT_BIT 6 | |
#define AFD_POLL_CONNECT (1 << AFD_POLL_CONNECT_BIT) | |
#define AFD_POLL_ACCEPT_BIT 7 | |
#define AFD_POLL_ACCEPT (1 << AFD_POLL_ACCEPT_BIT) | |
#define AFD_POLL_CONNECT_FAIL_BIT 8 | |
#define AFD_POLL_CONNECT_FAIL (1 << AFD_POLL_CONNECT_FAIL_BIT) | |
#define AFD_POLL_QOS_BIT 9 | |
#define AFD_POLL_QOS (1 << AFD_POLL_QOS_BIT) | |
#define AFD_POLL_GROUP_QOS_BIT 10 | |
#define AFD_POLL_GROUP_QOS (1 << AFD_POLL_GROUP_QOS_BIT) | |
#define AFD_NUM_POLL_EVENTS 11 | |
#define AFD_POLL_ALL ((1 << AFD_NUM_POLL_EVENTS) - 1) | |
typedef struct _AFD_RECV_DATAGRAM_INFO { | |
LPWSABUF BufferArray; | |
ULONG BufferCount; | |
ULONG AfdFlags; | |
ULONG TdiFlags; | |
struct sockaddr* Address; | |
int* AddressLength; | |
} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO; | |
typedef struct _AFD_RECV_INFO { | |
LPWSABUF BufferArray; | |
ULONG BufferCount; | |
ULONG AfdFlags; | |
ULONG TdiFlags; | |
} AFD_RECV_INFO, *PAFD_RECV_INFO; | |
#define _AFD_CONTROL_CODE(operation, method) \ | |
((FSCTL_AFD_BASE) << 12 | (operation << 2) | method) | |
#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK | |
#define AFD_RECEIVE 5 | |
#define AFD_RECEIVE_DATAGRAM 6 | |
#define AFD_POLL 9 | |
#define IOCTL_AFD_RECEIVE \ | |
_AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER) | |
#define IOCTL_AFD_RECEIVE_DATAGRAM \ | |
_AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER) | |
#define IOCTL_AFD_POLL \ | |
_AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED) | |
HANDLE CreateAfdHandle(void); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma warning(push, 3) | |
#include <stdio.h> | |
#include <stdint.h> /* INT64_MAX */ | |
#include <malloc.h> /* alloca */ | |
#include <winsock2.h> | |
#include <ws2tcpip.h> /* inet_pton */ | |
#pragma comment(lib, "Ws2_32.lib") | |
#pragma warning(pop) | |
#include "afd.h" | |
int waitfor(HANDLE sock, ULONG *events, LONGLONG timeout) { | |
int err = 0; | |
DWORD bytes; | |
OVERLAPPED overlap = {0}; | |
HANDLE afd = INVALID_HANDLE_VALUE; | |
PAFD_POLL_INFO afd_poll_info = alloca(sizeof(AFD_POLL_INFO) + sizeof(AFD_POLL_HANDLE_INFO)*1); | |
afd_poll_info->NumberOfHandles = 1; | |
afd_poll_info->Timeout.QuadPart = timeout; | |
afd_poll_info->Handles[0].Handle = (HANDLE)sock; | |
afd_poll_info->Handles[0].Status = 0; | |
afd_poll_info->Handles[0].Events = *events; | |
if (INVALID_HANDLE_VALUE == (afd = CreateAfdHandle())) { | |
err = GetLastError(); | |
goto done; | |
} | |
if (0 != DeviceIoControl( | |
afd, | |
IOCTL_AFD_POLL, | |
afd_poll_info, | |
sizeof(AFD_POLL_INFO) + sizeof(AFD_POLL_HANDLE_INFO)*1, | |
afd_poll_info, | |
sizeof(AFD_POLL_INFO) + sizeof(AFD_POLL_HANDLE_INFO)*1, | |
NULL, | |
&overlap | |
)) { | |
err = GetLastError(); | |
goto done; | |
} | |
if (0 == GetOverlappedResult(afd, &overlap, &bytes, TRUE)) { | |
err = GetLastError(); | |
goto done; | |
} | |
err = 0; | |
*events = afd_poll_info->Handles[0].Events; | |
done: | |
if (afd != INVALID_HANDLE_VALUE) { | |
CloseHandle(afd); | |
} | |
return err; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This project has more afd defines: https://afdmjhk.googlecode.com/svn/trunk/INCLUDE/afd.h