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

# User Rev Content
1 douglas 594 // Douglas Thrift
2     //
3     // CCS Computer Science
4     //
5     // Windows Finger Daemon
6    
7     #include <windows.h>
8     #include <tchar.h>
9 douglas 596 #include <signal.h>
10 douglas 608 #include <wtsapi32.h>
11 douglas 594
12 douglas 595 #include <iostream>
13 douglas 608 #include <string>
14 douglas 609 #include <vector>
15 douglas 595
16     LPTSTR name;
17 douglas 594 SERVICE_STATUS status;
18     SERVICE_STATUS_HANDLE handle;
19 douglas 595 HANDLE stop;
20 douglas 594 WSADATA data;
21 douglas 609 std::vector<HANDLE> threads;
22 douglas 594
23 douglas 596 void FingerDaemon();
24 douglas 609 DWORD WINAPI FingerListen(LPVOID server_);
25     DWORD WINAPI FingerDo(LPVOID client_);
26 douglas 596 void FingerStop(int);
27 douglas 595 void WINAPI FingerMain(DWORD argc, LPTSTR *argv);
28     void WINAPI FingerControl(DWORD control);
29 douglas 594
30     int _tmain(int argc, TCHAR *argv[])
31     {
32 douglas 609 SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
33 douglas 594
34     if (!StartServiceCtrlDispatcher(entry))
35     {
36     DWORD error(GetLastError());
37    
38     switch (error)
39     {
40     case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
41 douglas 595 goto go;
42 douglas 594
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 douglas 595
62     go:
63 douglas 608 stop = CreateEvent(NULL, TRUE, FALSE, NULL);
64    
65 douglas 596 signal(SIGINT, FingerStop);
66 douglas 595
67 douglas 596 try
68     {
69     FingerDaemon();
70     }
71     catch (...) {}
72    
73 douglas 609 return 0;
74 douglas 594 }
75    
76 douglas 596 void FingerDaemon()
77 douglas 594 {
78     WSAStartup(MAKEWORD(2, 0), &data);
79    
80     //
81    
82 douglas 608 SOCKET server(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
83 douglas 594 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 douglas 608 bind(server, (SOCKADDR *)(&service), sizeof (service));
90     listen(server, SOMAXCONN);
91 douglas 594
92 douglas 609 threads.push_back(CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
93 douglas 608
94 douglas 609 while(WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
95 douglas 594
96     //
97    
98 douglas 608 closesocket(server);
99    
100 douglas 594 WSACleanup();
101 douglas 596 }
102 douglas 594
103 douglas 609 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 douglas 596 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 douglas 595 status.dwCurrentState = SERVICE_STOPPED;
256 douglas 594 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 douglas 595 SetServiceStatus(handle, &status);
280 douglas 594 }