Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@daurnimator
Created March 29, 2015 13:28
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daurnimator/63d2970aedc952f0beb3 to your computer and use it in GitHub Desktop.
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
#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;
}
#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);
#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;
}
@daurnimator
Copy link
Author

This project has more afd defines: https://afdmjhk.googlecode.com/svn/trunk/INCLUDE/afd.h

@piscisaureus
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment