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 615 by douglas, 2005-12-12T19:26:43-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 <iostream>
14 + #include <iomanip>
15   #include <string>
16 + #include <sstream>
17   #include <vector>
18 + #include <set>
19 +
20 + std::ostream &operator<<(std::ostream &out, WTS_CONNECTSTATE_CLASS status)
21 + {
22 +        switch (status)
23 +        {
24 +        case WTSActive:
25 +                return out << "Active";
26 +
27 +        case WTSConnected:
28 +                return out << "Connected";
29 +
30 +        case WTSConnectQuery:
31 +                return out << "Connecting";
32 +
33 +        case WTSShadow:
34 +                return out << "Shadowing";
35 +
36 +        case WTSDisconnected:
37 +                return out << "Disconnected";
38 +
39 +        case WTSIdle:
40 +                return out << "Idle";
41 +
42 +        case WTSListen:
43 +                return out << "Listening";
44 +
45 +        case WTSReset:
46 +                return out << "Reseting";
47 +
48 +        case WTSDown:
49 +                return out << "Down";
50 +
51 +        case WTSInit:
52 +                return out << "Initializing";
53 +
54 +        default:
55 +                return out << "Unknown";
56 +        }
57 + }
58 +
59 + inline std::string Utf8(const std::wstring &wstring)
60 + {
61 +        std::string string(::WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), NULL, 0, NULL, NULL), '\0');
62 +
63 +        ::WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), const_cast<LPSTR>(string.data()), int(string.size()), NULL, NULL);
64 +
65 +        return string;
66 + }
67 +
68 + class Finger
69 + {
70 + private:
71 +        struct Login
72 +        {
73 +                std::string login, name, session;
74 +                DWORD id;
75 +                WTS_CONNECTSTATE_CLASS status;
76 +                Login(const std::wstring &login, DWORD id, const std::wstring &session, WTS_CONNECTSTATE_CLASS status) : login(Utf8(login)), id(id), session(Utf8(session)), status(status)
77 +                {
78 +                        USER_INFO_11 *info;
79 +
80 +                        ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
81 +
82 +                        name = Utf8(std::wstring(info->usri11_full_name).substr(0, 20));
83 +
84 +                        ::NetApiBufferFree(info);
85 +                }
86 +
87 +                bool operator<(const Login &login) const
88 +                {
89 +                        if (this->login == login.login)
90 +                                return id < login.id;
91 +                        else
92 +                                return this->login < login.login;
93 +                }
94 +        };
95 +        std::ostringstream stream;
96 +        std::set<Login> logins;
97 +
98 + public:
99 +        Finger(bool full)
100 +        {
101 +                PWTS_SESSION_INFO sessions;
102 +                DWORD count;
103 +
104 +                ::WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count);
105 +
106 +                for (PWTS_SESSION_INFO session(sessions); session != sessions + count; ++session)
107 +                {
108 +                        LPTSTR name;
109 +                        DWORD size;
110 +
111 +                        ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &name, &size);
112 +
113 +                        if (!std::wstring(name).empty())
114 +                        {
115 +                                LPTSTR session_;
116 +
117 +                                ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSWinStationName, &session_, &size);
118 +
119 +                                Login login(name, session->SessionId, session_, session->State);
120 +
121 +                                ::WTSFreeMemory(session_);
122 +
123 +                                logins.insert(login);
124 +                        }
125 +
126 +                        ::WTSFreeMemory(name);
127 +                }
128 +
129 +                ::WTSFreeMemory(sessions);
130 +
131 +                if (!full)
132 +                {
133 +                        stream << "Login\t\tName" << std::string(17, ' ') << "Id     Session       Status\r\n";
134 +
135 +                        for (std::set<Login>::const_iterator login(logins.begin()); login != logins.end(); ++login)
136 +                                stream << login->login << std::string(16 - login->login.size(), ' ') << login->name << std::string(21 - login->name.size(), ' ') << std::setw(5) << std::left << login->id << "  " << login->session << std::string(14 - login->session.size(), ' ') << login->status << "\r\n";
137 +                }
138 +        }
139 +
140 +        Finger(const std::string &name)
141 +        {
142 +                //NetQueryDisplayInformation
143 +                //NetUserGetInfo
144 +        }
145 +
146 +        inline operator std::string()
147 +        {
148 +                return stream.str();
149 +        }
150 + };
151  
152   LPTSTR name;
153   SERVICE_STATUS status;
# Line 31 | Line 167 | int _tmain(int argc, TCHAR *argv[])
167   {
168          SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
169  
170 <        if (!StartServiceCtrlDispatcher(entry))
170 >        if (!::StartServiceCtrlDispatcher(entry))
171          {
172 <                DWORD error(GetLastError());
172 >                DWORD error(::GetLastError());
173  
174                  switch (error)
175                  {
# Line 60 | Line 196 | int _tmain(int argc, TCHAR *argv[])
196          return 0;
197  
198   go:
199 <        stop = CreateEvent(NULL, TRUE, FALSE, NULL);
199 >        stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
200  
201 <        signal(SIGINT, FingerStop);
201 >        ::signal(SIGINT, FingerStop);
202  
203          try
204          {
# Line 75 | Line 211 | go:
211  
212   void FingerDaemon()
213   {
214 <        WSAStartup(MAKEWORD(2, 0), &data);
214 >        ::WSAStartup(MAKEWORD(2, 0), &data);
215  
216          //
217  
218 <        SOCKET server(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
218 >        SOCKET server(::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
219          SOCKADDR_IN service;
220          
221          service.sin_family = AF_INET;
222          service.sin_addr.s_addr = inet_addr("0.0.0.0");
223          service.sin_port = htons(79);
224  
225 <        bind(server, (SOCKADDR *)(&service), sizeof (service));
226 <        listen(server, SOMAXCONN);
225 >        ::bind(server, (SOCKADDR *)(&service), sizeof (service));
226 >        ::listen(server, SOMAXCONN);
227  
228 <        threads.push_back(CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
228 >        threads.push_back(::CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
229  
230 <        while(WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
230 >        while(::WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
231  
232          //
233  
234 <        closesocket(server);
234 >        ::closesocket(server);
235  
236 <        WSACleanup();
236 >        ::WSACleanup();
237   }
238  
239   DWORD WINAPI FingerListen(LPVOID server_)
# Line 108 | Line 244 | DWORD WINAPI FingerListen(LPVOID server_
244          {
245                  SOCKET client(accept(server, NULL, NULL));
246  
247 <                threads.push_back(CreateThread(NULL, 0, FingerDo, &client, 0, NULL));
247 >                threads.push_back(::CreateThread(NULL, 0, FingerDo, &client, 0, NULL));
248          }
249  
250          return 0;
# Line 117 | Line 253 | DWORD WINAPI FingerListen(LPVOID server_
253   DWORD WINAPI FingerDo(LPVOID client_)
254   {
255          SOCKET &client(*reinterpret_cast<SOCKET *>(client_));
256 <        char buffer;
257 <        std::string name;
258 <
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);
256 >        char buffer[1024];
257 >        std::istringstream stream(std::string(buffer, ::recv(client, buffer, sizeof buffer, 0)));
258 >        std::string line;
259  
260 <                        break;
132 <                }
133 <        }
260 >        std::getline(stream, line);
261  
262 <        if (name.empty())
136 <        {
137 <                std::string header("Login\t\tName\t\tTTY\r\n");
262 >        stream.str(line);
263  
264 <                send(client, header.data(), header.size(), 0);
140 <                
141 <                /*PWTS_SESSION_INFO sessions;
142 <                DWORD count;
264 >        std::getline(stream, line, '\r');
265  
266 <                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;
266 >        stream.str(line);
267  
268 <                        WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &userName, &userNameSize);
269 <                        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 <                        }
268 >        std::string name;
269 >        bool full(false);
270  
271 <                        std::wcout << std::endl << '\t' << userName << std::endl
272 <                                << '\t' << clientName << std::endl
273 <                                << '}' << std::endl;
271 >        while (stream >> line)
272 >                if (line == "/W")
273 >                        full = true;
274 >                else
275 >                        name = line;
276  
277 <                        WTSFreeMemory(userName);
213 <                        WTSFreeMemory(clientName);
214 <                }
277 >        std::string finger(name.empty() ? Finger(full) : Finger(name));
278  
279 <                WTSFreeMemory(sessions);*/
280 <        }
218 <
219 <        closesocket(client);
279 >        ::send(client, finger.data(), int(finger.size()), 0);
280 >        ::closesocket(client);
281  
282          return 0;
283   }
284  
285   void FingerStop(int)
286   {
287 <        SetEvent(stop);
227 <
228 <        std::cout << "Stop!" << std::endl;
287 >        ::SetEvent(stop);
288   }
289  
290   void WINAPI FingerMain(DWORD argc, LPTSTR *argv)
291   {
292          name = argv[0];
293          handle = RegisterServiceCtrlHandler(name, LPHANDLER_FUNCTION(FingerControl));
294 <        stop = CreateEvent(NULL, TRUE, FALSE, NULL);
294 >        stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
295  
296          //
297  
# Line 244 | Line 303 | void WINAPI FingerMain(DWORD argc, LPTST
303          status.dwCheckPoint = 0;
304          status.dwWaitHint = 0;
305  
306 <        SetServiceStatus(handle, &status);
306 >        ::SetServiceStatus(handle, &status);
307  
308          try
309          {
# Line 257 | Line 316 | void WINAPI FingerMain(DWORD argc, LPTST
316          status.dwCheckPoint = 0;
317          status.dwWaitHint = 0;
318  
319 <        SetServiceStatus(handle, &status);
319 >        ::SetServiceStatus(handle, &status);
320   }
321  
322   void WINAPI FingerControl(DWORD control)
# Line 268 | Line 327 | void WINAPI FingerControl(DWORD control)
327          case SERVICE_CONTROL_SHUTDOWN:
328                  status.dwCurrentState = SERVICE_STOP_PENDING;
329  
330 <                SetEvent(stop);
330 >                ::SetEvent(stop);
331  
332                  break;
333  
# Line 276 | Line 335 | void WINAPI FingerControl(DWORD control)
335                  break;
336          }
337  
338 <        SetServiceStatus(handle, &status);
338 >        ::SetServiceStatus(handle, &status);
339   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines