ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSFinger/CCSFinger.cpp
(Generate patch)

Comparing CCSFinger/CCSFinger.cpp (file contents):
Revision 594 by douglas, 2005-11-27T17:04:53-08:00 vs.
Revision 614 by douglas, 2005-12-12T18:47:20-08:00

# Line 6 | Line 6
6  
7   #include <windows.h>
8   #include <tchar.h>
9 + #include <signal.h>
10 + #include <wtsapi32.h>
11 + #include <lm.h>
12 +
13 + #include <iostream>
14 + #include <string>
15 + #include <sstream>
16 + #include <vector>
17 + #include <set>
18  
19 < /*LPTSTR name;
19 > inline std::string Utf8(const std::wstring &wstring)
20 > {
21 >        std::string string(::WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), NULL, 0, NULL, NULL), '\0');
22 >
23 >        ::WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), const_cast<LPSTR>(string.data()), int(string.size()), NULL, NULL);
24 >
25 >        return string;
26 > }
27 >
28 > class Finger
29 > {
30 > private:
31 >        struct Login
32 >        {
33 >                std::string login, name, session;
34 >                Login(const std::wstring &login, const std::wstring &session) : login(Utf8(login)), session(Utf8(session))
35 >                {
36 >                        USER_INFO_11 *info;
37 >
38 >                        ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
39 >
40 >                        name = Utf8(std::wstring(info->usri11_full_name).substr(0, 20));
41 >
42 >                        ::NetApiBufferFree(info);
43 >                }
44 >                bool operator<(const Login &login) const
45 >                {
46 >                        if (this->login == login.login)
47 >                                return session < login.session;
48 >                        else
49 >                                return this->login < login.login;
50 >                }
51 >        };
52 >        std::ostringstream stream;
53 >        std::set<Login> logins;
54 >
55 > public:
56 >        Finger(bool full)
57 >        {
58 >                PWTS_SESSION_INFO sessions;
59 >                DWORD count;
60 >
61 >                ::WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count);
62 >
63 >                for (PWTS_SESSION_INFO session(sessions); session != sessions + count; ++session)
64 >                {
65 >                        LPTSTR name;
66 >                        DWORD size;
67 >
68 >                        ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &name, &size);
69 >
70 >                        if (!std::wstring(name).empty())
71 >                        {
72 >                                LPTSTR session_;
73 >
74 >                                ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSWinStationName, &session_, &size);
75 >
76 >                                Login login(name, session_);
77 >
78 >                                ::WTSFreeMemory(session_);
79 >
80 >                                logins.insert(login);
81 >                        }
82 >
83 >                        ::WTSFreeMemory(name);
84 >                }
85 >
86 >                ::WTSFreeMemory(sessions);
87 >
88 >                if (!full)
89 >                {
90 >                        stream << "Login\t\tName" << std::string(17, ' ') << "Session\r\n";
91 >
92 >                        for (std::set<Login>::const_iterator login(logins.begin()); login != logins.end(); ++login)
93 >                                stream << login->login << std::string(16 - login->login.size(), ' ') << login->name << std::string(21 - login->name.size(), ' ') << login->session << "\r\n";
94 >                }
95 >        }
96 >
97 >        Finger(const std::string &name)
98 >        {
99 >                //NetQueryDisplayInformation
100 >                //NetUserGetInfo
101 >        }
102 >
103 >        inline operator std::string()
104 >        {
105 >                return stream.str();
106 >        }
107 > };
108 >
109 > LPTSTR name;
110   SERVICE_STATUS status;
111   SERVICE_STATUS_HANDLE handle;
112 < HANDLE stop;*/
112 > HANDLE stop;
113   WSADATA data;
114 + std::vector<HANDLE> threads;
115  
116 < /*void WINAPI FingerMain(DWORD argc, LPTSTR *argv);
117 < void WINAPI FingerControl(DWORD control);*/
116 > void FingerDaemon();
117 > DWORD WINAPI FingerListen(LPVOID server_);
118 > DWORD WINAPI FingerDo(LPVOID client_);
119 > void FingerStop(int);
120 > void WINAPI FingerMain(DWORD argc, LPTSTR *argv);
121 > void WINAPI FingerControl(DWORD control);
122  
123   int _tmain(int argc, TCHAR *argv[])
124   {
125 <        /*SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
125 >        SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
126  
127 <        if (!StartServiceCtrlDispatcher(entry))
127 >        if (!::StartServiceCtrlDispatcher(entry))
128          {
129 <                DWORD error(GetLastError());
129 >                DWORD error(::GetLastError());
130  
131                  switch (error)
132                  {
133                  case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
134 <                        std::cerr << "ERROR_FAILED_SERVICE_CONTROLLER_CONNECT" << std::endl;
31 <
32 <                        break;
134 >                        goto go;
135  
136                  case ERROR_INVALID_DATA:
137                          std::cerr << "ERROR_INVALID_DATA" << std::endl;
# Line 49 | Line 151 | int _tmain(int argc, TCHAR *argv[])
151          }
152  
153          return 0;
52 }
154  
155 < void WINAPI FingerMain(DWORD argc, LPTSTR *argv)
156 < {
56 <        name = argv[0];
57 <        handle = RegisterServiceCtrlHandler(name, LPHANDLER_FUNCTION(FingerControl));
58 <        stop = CreateEvent(NULL, TRUE, FALSE, NULL);
155 > go:
156 >        stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
157  
158 <        //*/
158 >        ::signal(SIGINT, FingerStop);
159  
160 <        WSAStartup(MAKEWORD(2, 0), &data);
160 >        try
161 >        {
162 >                FingerDaemon();
163 >        }
164 >        catch (...) {}
165  
166 <        //
166 >        return 0;
167 > }
168  
169 <        /*status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
170 <        status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
171 <        status.dwServiceSpecificExitCode = 0;
69 <        status.dwCurrentState = SERVICE_RUNNING;
70 <        status.dwWin32ExitCode = NO_ERROR;
71 <        status.dwCheckPoint = 0;
72 <        status.dwWaitHint = 0;
169 > void FingerDaemon()
170 > {
171 >        ::WSAStartup(MAKEWORD(2, 0), &data);
172  
173 <        SetServiceStatus(handle, &status);*/
173 >        //
174  
175 <        SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
175 >        SOCKET server(::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
176          SOCKADDR_IN service;
177          
178          service.sin_family = AF_INET;
179          service.sin_addr.s_addr = inet_addr("0.0.0.0");
180          service.sin_port = htons(79);
181  
182 <        bind(sock, (SOCKADDR *)(&service), sizeof (service));
183 <        listen(sock, SOMAXCONN);
182 >        ::bind(server, (SOCKADDR *)(&service), sizeof (service));
183 >        ::listen(server, SOMAXCONN);
184 >
185 >        threads.push_back(::CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
186 >
187 >        while(::WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
188 >
189 >        //
190 >
191 >        ::closesocket(server);
192 >
193 >        ::WSACleanup();
194 > }
195  
196 <        //while(/*WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0*/ /*&&*/)
196 > DWORD WINAPI FingerListen(LPVOID server_)
197 > {
198 >        SOCKET &server(*reinterpret_cast<SOCKET *>(server_));
199 >
200 >        while (true)
201          {
202 <                //
202 >                SOCKET client(accept(server, NULL, NULL));
203 >
204 >                threads.push_back(::CreateThread(NULL, 0, FingerDo, &client, 0, NULL));
205          }
206  
207 +        return 0;
208 + }
209 +
210 + DWORD WINAPI FingerDo(LPVOID client_)
211 + {
212 +        SOCKET &client(*reinterpret_cast<SOCKET *>(client_));
213 +        char buffer[1024];
214 +        std::istringstream stream(std::string(buffer, ::recv(client, buffer, sizeof buffer, 0)));
215 +        std::string line;
216 +
217 +        std::getline(stream, line);
218 +
219 +        stream.str(line);
220 +
221 +        std::getline(stream, line, '\r');
222 +
223 +        stream.str(line);
224 +
225 +        std::string name;
226 +        bool full(false);
227 +
228 +        while (stream >> line)
229 +                if (line == "/W")
230 +                        full = true;
231 +                else
232 +                        name = line;
233 +
234 +        std::string finger(name.empty() ? Finger(full) : Finger(name));
235 +
236 +        ::send(client, finger.data(), int(finger.size()), 0);
237 +        ::closesocket(client);
238 +
239 +        return 0;
240 + }
241 +
242 + void FingerStop(int)
243 + {
244 +        ::SetEvent(stop);
245 + }
246 +
247 + void WINAPI FingerMain(DWORD argc, LPTSTR *argv)
248 + {
249 +        name = argv[0];
250 +        handle = RegisterServiceCtrlHandler(name, LPHANDLER_FUNCTION(FingerControl));
251 +        stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
252 +
253          //
254  
255 <        WSACleanup();
255 >        status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
256 >        status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
257 >        status.dwServiceSpecificExitCode = 0;
258 >        status.dwCurrentState = SERVICE_RUNNING;
259 >        status.dwWin32ExitCode = NO_ERROR;
260 >        status.dwCheckPoint = 0;
261 >        status.dwWaitHint = 0;
262  
263 <        /*status.dwCurrentState = SERVICE_STOPPED;
263 >        ::SetServiceStatus(handle, &status);
264 >
265 >        try
266 >        {
267 >                FingerDaemon();
268 >        }
269 >        catch (...) {}
270 >
271 >        status.dwCurrentState = SERVICE_STOPPED;
272          status.dwWin32ExitCode = NO_ERROR;
273          status.dwCheckPoint = 0;
274          status.dwWaitHint = 0;
275  
276 <        SetServiceStatus(handle, &status);
276 >        ::SetServiceStatus(handle, &status);
277   }
278  
279   void WINAPI FingerControl(DWORD control)
# Line 108 | Line 284 | void WINAPI FingerControl(DWORD control)
284          case SERVICE_CONTROL_SHUTDOWN:
285                  status.dwCurrentState = SERVICE_STOP_PENDING;
286  
287 <                SetEvent(stop);
287 >                ::SetEvent(stop);
288  
289                  break;
290  
# Line 116 | Line 292 | void WINAPI FingerControl(DWORD control)
292                  break;
293          }
294  
295 <        SetServiceStatus(handle, &status);*/
120 <
121 <        return 0;
295 >        ::SetServiceStatus(handle, &status);
296   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines