-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathevents.cpp
executable file
·127 lines (106 loc) · 3.02 KB
/
events.cpp
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// We can't avoid this when using maps
#pragma warning(push)
#pragma warning(disable:4786)
#include <map>
#include "events.h"
std::map<SOCKET, WSAEventData> events;
HANDLE events_mutex;
HINSTANCE events_instance;
HWND events_window;
static const char* events_window_name = "WINSOCK351";
void SetEventData(SOCKET socket, const WSAEventData& data) {
const DWORD wait_result = WaitForSingleObject(events_mutex, INFINITE);
switch (wait_result) {
case WAIT_OBJECT_0:
events[socket] = data;
ReleaseMutex(events_mutex);
case WAIT_ABANDONED:
return;
}
}
int GetEventData(SOCKET socket, WSAEventData* data) {
const DWORD wait_result = WaitForSingleObject(events_mutex, INFINITE);
switch (wait_result) {
case WAIT_OBJECT_0:
if (events.find(socket) == events.end())
return -1;
*data = events[socket];
ReleaseMutex(events_mutex);
case WAIT_ABANDONED:
return -1;
}
return 0;
}
void DeleteEventData(SOCKET socket) {
const DWORD wait_result = WaitForSingleObject(events_mutex, INFINITE);
switch (wait_result) {
case WAIT_OBJECT_0:
events.erase(socket);
ReleaseMutex(events_mutex);
case WAIT_ABANDONED:
return;
}
}
void DeleteEvents() {
const DWORD wait_result = WaitForSingleObject(events_mutex, INFINITE);
switch (wait_result) {
case WAIT_OBJECT_0:
events.clear();
ReleaseMutex(events_mutex);
case WAIT_ABANDONED:
return;
}
}
LRESULT CALLBACK EventsWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (uMsg > WM_USER) {
const WSAEVENT event = reinterpret_cast<WSAEVENT>(uMsg - WM_USER);
WSAEventData data;
int err = GetEventData(wParam, &data);
if (err != 0)
return FALSE;
data.lNetworkEvents = WSAGETSELECTEVENT(lParam);
SetEventData(wParam, data);
return SetEvent(event);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
void SetEventsInstance(HINSTANCE hinstance) {
events_instance = hinstance;
}
HWND GetEventsWindow() {
return events_window;
}
int StartupEvents() {
events_mutex = CreateMutex(NULL, TRUE, NULL);
if (events_mutex == NULL)
return GetLastError();
// In order to receive WSAAsync events locally we will create an
// invisible window to receive those messages
// HWND_MESSAGE didn't exist on NT 3.51 so we have to do it this way
WNDCLASS wc;
// Register the main window class
wc.style = 0;
wc.lpfnWndProc = EventsWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = events_instance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = events_window_name;
RegisterClass(&wc);
events_window = CreateWindow(events_window_name, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL);
return 0;
}
int CleanupEvents() {
DeleteEvents();
const int err = CloseHandle(events_mutex);
if (err != 0) {
return err;
}
DestroyWindow(events_window);
UnregisterClass(events_window_name, NULL);
return 0;
}
#pragma warning(pop)