ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSFinger/CCSFinger.cpp
Revision: 609
Committed: 2005-11-30T21:55:40-08:00 (19 years, 7 months ago) by douglas
File size: 5547 byte(s)
Log Message:
Moo!

File Contents

# Content
1 // Douglas Thrift
2 //
3 // CCS Computer Science
4 //
5 // Windows Finger Daemon
6
7 #include <windows.h>
8 #include <tchar.h>
9 #include <signal.h>
10 #include <wtsapi32.h>
11
12 #include <iostream>
13 #include <string>
14 #include <vector>
15
16 LPTSTR name;
17 SERVICE_STATUS status;
18 SERVICE_STATUS_HANDLE handle;
19 HANDLE stop;
20 WSADATA data;
21 std::vector<HANDLE> threads;
22
23 void FingerDaemon();
24 DWORD WINAPI FingerListen(LPVOID server_);
25 DWORD WINAPI FingerDo(LPVOID client_);
26 void FingerStop(int);
27 void WINAPI FingerMain(DWORD argc, LPTSTR *argv);
28 void WINAPI FingerControl(DWORD control);
29
30 int _tmain(int argc, TCHAR *argv[])
31 {
32 SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
33
34 if (!StartServiceCtrlDispatcher(entry))
35 {
36 DWORD error(GetLastError());
37
38 switch (error)
39 {
40 case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
41 goto go;
42
43 case ERROR_INVALID_DATA:
44 std::cerr << "ERROR_INVALID_DATA" << std::endl;
45
46 break;
47
48 case ERROR_SERVICE_ALREADY_RUNNING:
49 std::cerr << "ERROR_SERVICE_ALREADY_RUNNING" << std::endl;
50
51 break;
52
53 default:
54 std::cerr << error << std::endl;
55 }
56
57 return 1;
58 }
59
60 return 0;
61
62 go:
63 stop = CreateEvent(NULL, TRUE, FALSE, NULL);
64
65 signal(SIGINT, FingerStop);
66
67 try
68 {
69 FingerDaemon();
70 }
71 catch (...) {}
72
73 return 0;
74 }
75
76 void FingerDaemon()
77 {
78 WSAStartup(MAKEWORD(2, 0), &data);
79
80 //
81
82 SOCKET server(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
83 SOCKADDR_IN service;
84
85 service.sin_family = AF_INET;
86 service.sin_addr.s_addr = inet_addr("0.0.0.0");
87 service.sin_port = htons(79);
88
89 bind(server, (SOCKADDR *)(&service), sizeof (service));
90 listen(server, SOMAXCONN);
91
92 threads.push_back(CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
93
94 while(WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
95
96 //
97
98 closesocket(server);
99
100 WSACleanup();
101 }
102
103 DWORD WINAPI FingerListen(LPVOID server_)
104 {
105 SOCKET &server(*reinterpret_cast<SOCKET *>(server_));
106
107 while (true)
108 {
109 SOCKET client(accept(server, NULL, NULL));
110
111 threads.push_back(CreateThread(NULL, 0, FingerDo, &client, 0, NULL));
112 }
113
114 return 0;
115 }
116
117 DWORD WINAPI FingerDo(LPVOID client_)
118 {
119 SOCKET &client(*reinterpret_cast<SOCKET *>(client_));
120 char buffer;
121 std::string name;
122
123 while (recv(client, &buffer, 1, 0) > 0)
124 {
125 name += buffer;
126
127 if (name.size() >= 2 && name.rfind("\r\n") == name.size() - 2)
128 {
129 name.erase(name.size() - 2);
130
131 break;
132 }
133 }
134
135 if (name.empty())
136 {
137 std::string header("Login\t\tName\t\tTTY\r\n");
138
139 send(client, header.data(), header.size(), 0);
140
141 /*PWTS_SESSION_INFO sessions;
142 DWORD count;
143
144 if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count))
145 {
146 std::cerr << GetLastError() << std::endl;
147
148 return 1;
149 }
150
151 for (PWTS_SESSION_INFO session = sessions; session != sessions + count; ++session)
152 {
153 LPTSTR userName, clientName;
154 DWORD userNameSize, clientNameSize;
155
156 WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &userName, &userNameSize);
157 WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSClientName, &clientName, &clientNameSize);
158
159 std::wcout << '{' << std::endl
160 << '\t' << session->SessionId << std::endl
161 << '\t' << session->pWinStationName << std::endl
162 << '\t';
163
164 switch (session->State)
165 {
166 case WTSActive:
167 std::cout << "Active";
168
169 break;
170 case WTSConnected:
171 std::cout << "Connected";
172
173 break;
174 case WTSConnectQuery:
175 std::cout << "Connect Query";
176
177 break;
178 case WTSShadow:
179 std::cout << "Shadow";
180
181 break;
182 case WTSDisconnected:
183 std::cout << "Disconnected";
184
185 break;
186 case WTSIdle:
187 std::cout << "Idle";
188
189 break;
190 case WTSListen:
191 std::cout << "Listen";
192
193 break;
194 case WTSReset:
195 std::cout << "Reset";
196
197 break;
198 case WTSDown:
199 std::cout << "Down";
200
201 break;
202 case WTSInit:
203 std::cout << "Init";
204
205 break;
206 }
207
208 std::wcout << std::endl << '\t' << userName << std::endl
209 << '\t' << clientName << std::endl
210 << '}' << std::endl;
211
212 WTSFreeMemory(userName);
213 WTSFreeMemory(clientName);
214 }
215
216 WTSFreeMemory(sessions);*/
217 }
218
219 closesocket(client);
220
221 return 0;
222 }
223
224 void FingerStop(int)
225 {
226 SetEvent(stop);
227
228 std::cout << "Stop!" << std::endl;
229 }
230
231 void WINAPI FingerMain(DWORD argc, LPTSTR *argv)
232 {
233 name = argv[0];
234 handle = RegisterServiceCtrlHandler(name, LPHANDLER_FUNCTION(FingerControl));
235 stop = CreateEvent(NULL, TRUE, FALSE, NULL);
236
237 //
238
239 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
240 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
241 status.dwServiceSpecificExitCode = 0;
242 status.dwCurrentState = SERVICE_RUNNING;
243 status.dwWin32ExitCode = NO_ERROR;
244 status.dwCheckPoint = 0;
245 status.dwWaitHint = 0;
246
247 SetServiceStatus(handle, &status);
248
249 try
250 {
251 FingerDaemon();
252 }
253 catch (...) {}
254
255 status.dwCurrentState = SERVICE_STOPPED;
256 status.dwWin32ExitCode = NO_ERROR;
257 status.dwCheckPoint = 0;
258 status.dwWaitHint = 0;
259
260 SetServiceStatus(handle, &status);
261 }
262
263 void WINAPI FingerControl(DWORD control)
264 {
265 switch (control)
266 {
267 case SERVICE_CONTROL_STOP:
268 case SERVICE_CONTROL_SHUTDOWN:
269 status.dwCurrentState = SERVICE_STOP_PENDING;
270
271 SetEvent(stop);
272
273 break;
274
275 case SERVICE_CONTROL_INTERROGATE:
276 break;
277 }
278
279 SetServiceStatus(handle, &status);
280 }