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 609 by douglas, 2005-11-30T21:55:40-08:00 vs.
Revision 616 by douglas, 2005-12-12T20:25:45-08:00

# Line 8 | Line 8
8   #include <tchar.h>
9   #include <signal.h>
10   #include <wtsapi32.h>
11 + #include <lm.h>
12  
13 + #include <algorithm>
14   #include <iostream>
15 + #include <iomanip>
16   #include <string>
17 + #include <sstream>
18   #include <vector>
19 + #include <map>
20 + #include <cwctype>
21 +
22 + std::ostream &operator<<(std::ostream &out, WTS_CONNECTSTATE_CLASS status)
23 + {
24 +        switch (status)
25 +        {
26 +        case WTSActive:
27 +                return out << "Active";
28 +
29 +        case WTSConnected:
30 +                return out << "Connected";
31 +
32 +        case WTSConnectQuery:
33 +                return out << "Connecting";
34 +
35 +        case WTSShadow:
36 +                return out << "Shadowing";
37 +
38 +        case WTSDisconnected:
39 +                return out << "Disconnected";
40 +
41 +        case WTSIdle:
42 +                return out << "Idle";
43 +
44 +        case WTSListen:
45 +                return out << "Listening";
46 +
47 +        case WTSReset:
48 +                return out << "Reseting";
49 +
50 +        case WTSDown:
51 +                return out << "Down";
52 +
53 +        case WTSInit:
54 +                return out << "Initializing";
55 +
56 +        default:
57 +                return out << "Unknown";
58 +        }
59 + }
60 +
61 + inline std::string Utf8(const std::wstring &wstring)
62 + {
63 +        std::string string(::WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), NULL, 0, NULL, NULL), '\0');
64 +
65 +        ::WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), const_cast<LPSTR>(string.data()), int(string.size()), NULL, NULL);
66 +
67 +        return string;
68 + }
69 +
70 + class Finger
71 + {
72 +        class Login
73 +        {
74 +                std::wstring login;
75 +                mutable USER_INFO_11 *info;
76 +
77 +                inline void GetInfo() const
78 +                {
79 +                        ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
80 +                }
81 +        public:
82 +                std::string session;
83 +                DWORD id;
84 +                WTS_CONNECTSTATE_CLASS status;
85 +
86 +                Login(const std::wstring &login, DWORD id, const std::wstring &session, WTS_CONNECTSTATE_CLASS status) : login(login), info(NULL), id(id), session(Utf8(session)), status(status)
87 +                {
88 +                }
89 +
90 +                ~Login()
91 +                {
92 +                        if (!info)
93 +                                ::NetApiBufferFree(info);
94 +                }
95 +
96 +                std::string GetName() const
97 +                {
98 +                        if (!info)
99 +                                GetInfo();
100 +
101 +                        return Utf8(std::wstring(info->usri11_full_name).substr(0, 20));
102 +                }
103 +        };
104 +
105 +        std::ostringstream stream;
106 +        std::multimap<std::string, Login> logins;
107 +
108 +        void Full()
109 +        {
110 +                for (std::multimap<std::string, Login>::const_iterator login(logins.begin()); login != logins.end(); login = logins.upper_bound(login->first))
111 +                {
112 +                        stream << "Login: " << login->first << std::string(33 - login->first.size(), ' ') << "Name: " << login->second.GetName() << "\r\n";
113 +                }
114 +        }
115 +
116 + public:
117 +        Finger(bool full)
118 +        {
119 +                PWTS_SESSION_INFO sessions;
120 +                DWORD count;
121 +
122 +                ::WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count);
123 +
124 +                for (PWTS_SESSION_INFO session(sessions); session != sessions + count; ++session)
125 +                {
126 +                        LPTSTR name;
127 +                        DWORD size;
128 +
129 +                        ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &name, &size);
130 +
131 +                        std::wstring name_(name);
132 +
133 +                        ::WTSFreeMemory(name);
134 +
135 +                        if (!name_.empty())
136 +                        {
137 +                                std::transform(name_.begin(), name_.end(), name_.begin(), std::towlower);
138 +
139 +                                LPTSTR session_;
140 +
141 +                                ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSWinStationName, &session_, &size);
142 +
143 +                                Login login(name_, session->SessionId, session_, session->State);
144 +
145 +                                ::WTSFreeMemory(session_);
146 +
147 +                                logins.insert(std::make_pair(Utf8(name_), login));
148 +                        }
149 +                }
150 +
151 +                ::WTSFreeMemory(sessions);
152 +
153 +                if (!full)
154 +                {
155 +                        stream << "Login" << std::string(11, ' ') << "Name" << std::string(17, ' ') << "Id     Session       Status\r\n";
156 +
157 +                        for (std::multimap<std::string, Login>::const_iterator login(logins.begin()); login != logins.end(); ++login)
158 +                                stream << login->first << std::string(16 - login->first.size(), ' ') << login->second.GetName() << std::string(21 - login->second.GetName().size(), ' ') << std::setw(5) << std::left << login->second.id << "  " << login->second.session << std::string(14 - login->second.session.size(), ' ') << login->second.status << "\r\n";
159 +                }
160 +                else
161 +                        Full();
162 +        }
163 +
164 +        Finger(const std::string &name)
165 +        {
166 +                //NetQueryDisplayInformation
167 +                //NetUserGetInfo
168 +        }
169 +
170 +        inline operator std::string()
171 +        {
172 +                return stream.str();
173 +        }
174 + };
175  
176   LPTSTR name;
177   SERVICE_STATUS status;
# Line 31 | Line 191 | int _tmain(int argc, TCHAR *argv[])
191   {
192          SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
193  
194 <        if (!StartServiceCtrlDispatcher(entry))
194 >        if (!::StartServiceCtrlDispatcher(entry))
195          {
196 <                DWORD error(GetLastError());
196 >                DWORD error(::GetLastError());
197  
198                  switch (error)
199                  {
# Line 60 | Line 220 | int _tmain(int argc, TCHAR *argv[])
220          return 0;
221  
222   go:
223 <        stop = CreateEvent(NULL, TRUE, FALSE, NULL);
223 >        stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
224  
225 <        signal(SIGINT, FingerStop);
225 >        ::signal(SIGINT, FingerStop);
226  
227          try
228          {
# Line 75 | Line 235 | go:
235  
236   void FingerDaemon()
237   {
238 <        WSAStartup(MAKEWORD(2, 0), &data);
238 >        ::WSAStartup(MAKEWORD(2, 0), &data);
239  
240          //
241  
242 <        SOCKET server(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
242 >        SOCKET server(::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
243          SOCKADDR_IN service;
244          
245          service.sin_family = AF_INET;
246          service.sin_addr.s_addr = inet_addr("0.0.0.0");
247          service.sin_port = htons(79);
248  
249 <        bind(server, (SOCKADDR *)(&service), sizeof (service));
250 <        listen(server, SOMAXCONN);
249 >        ::bind(server, (SOCKADDR *)(&service), sizeof (service));
250 >        ::listen(server, SOMAXCONN);
251  
252 <        threads.push_back(CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
252 >        threads.push_back(::CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
253  
254 <        while(WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
254 >        while(::WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
255  
256          //
257  
258 <        closesocket(server);
258 >        ::closesocket(server);
259  
260 <        WSACleanup();
260 >        ::WSACleanup();
261   }
262  
263   DWORD WINAPI FingerListen(LPVOID server_)
# Line 108 | Line 268 | DWORD WINAPI FingerListen(LPVOID server_
268          {
269                  SOCKET client(accept(server, NULL, NULL));
270  
271 <                threads.push_back(CreateThread(NULL, 0, FingerDo, &client, 0, NULL));
271 >                threads.push_back(::CreateThread(NULL, 0, FingerDo, &client, 0, NULL));
272          }
273  
274          return 0;
# Line 117 | Line 277 | DWORD WINAPI FingerListen(LPVOID server_
277   DWORD WINAPI FingerDo(LPVOID client_)
278   {
279          SOCKET &client(*reinterpret_cast<SOCKET *>(client_));
280 <        char buffer;
281 <        std::string name;
280 >        char buffer[1024];
281 >        std::istringstream stream(std::string(buffer, ::recv(client, buffer, sizeof buffer, 0)));
282 >        std::string line;
283  
284 <        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);
284 >        std::getline(stream, line);
285  
286 <                        std::wcout << '{' << std::endl
160 <                                << '\t' << session->SessionId << std::endl
161 <                                << '\t' << session->pWinStationName << std::endl
162 <                                << '\t';
286 >        stream.str(line);
287  
288 <                        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";
288 >        std::getline(stream, line, '\r');
289  
290 <                                break;
206 <                        }
290 >        stream.str(line);
291  
292 <                        std::wcout << std::endl << '\t' << userName << std::endl
293 <                                << '\t' << clientName << std::endl
210 <                                << '}' << std::endl;
292 >        std::string name;
293 >        bool full(false);
294  
295 <                        WTSFreeMemory(userName);
296 <                        WTSFreeMemory(clientName);
297 <                }
295 >        while (stream >> line)
296 >                if (line == "/W")
297 >                        full = true;
298 >                else
299 >                        name = line;
300  
301 <                WTSFreeMemory(sessions);*/
217 <        }
301 >        std::string finger(name.empty() ? Finger(full) : Finger(name));
302  
303 <        closesocket(client);
303 >        ::send(client, finger.data(), int(finger.size()), 0);
304 >        ::closesocket(client);
305  
306          return 0;
307   }
308  
309   void FingerStop(int)
310   {
311 <        SetEvent(stop);
227 <
228 <        std::cout << "Stop!" << std::endl;
311 >        ::SetEvent(stop);
312   }
313  
314   void WINAPI FingerMain(DWORD argc, LPTSTR *argv)
315   {
316          name = argv[0];
317          handle = RegisterServiceCtrlHandler(name, LPHANDLER_FUNCTION(FingerControl));
318 <        stop = CreateEvent(NULL, TRUE, FALSE, NULL);
318 >        stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
319  
320          //
321  
# Line 244 | Line 327 | void WINAPI FingerMain(DWORD argc, LPTST
327          status.dwCheckPoint = 0;
328          status.dwWaitHint = 0;
329  
330 <        SetServiceStatus(handle, &status);
330 >        ::SetServiceStatus(handle, &status);
331  
332          try
333          {
# Line 257 | Line 340 | void WINAPI FingerMain(DWORD argc, LPTST
340          status.dwCheckPoint = 0;
341          status.dwWaitHint = 0;
342  
343 <        SetServiceStatus(handle, &status);
343 >        ::SetServiceStatus(handle, &status);
344   }
345  
346   void WINAPI FingerControl(DWORD control)
# Line 268 | Line 351 | void WINAPI FingerControl(DWORD control)
351          case SERVICE_CONTROL_SHUTDOWN:
352                  status.dwCurrentState = SERVICE_STOP_PENDING;
353  
354 <                SetEvent(stop);
354 >                ::SetEvent(stop);
355  
356                  break;
357  
# Line 276 | Line 359 | void WINAPI FingerControl(DWORD control)
359                  break;
360          }
361  
362 <        SetServiceStatus(handle, &status);
362 >        ::SetServiceStatus(handle, &status);
363   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines