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 615 by douglas, 2005-12-12T19:26:43-08:00 vs.
Revision 619 by douglas, 2005-12-13T02:27:26-08:00

# Line 5 | Line 5
5   // Windows Finger Daemon
6  
7   #include <windows.h>
8 < #include <tchar.h>
8 > #include <lm.h>
9   #include <signal.h>
10 + #include <tchar.h>
11 + #include <shlobj.h>
12   #include <wtsapi32.h>
11 #include <lm.h>
13  
14 < #include <iostream>
14 > #include <algorithm>
15 > #include <cctype>
16 > #include <cwctype>
17 > #include <fstream>
18   #include <iomanip>
19 < #include <string>
19 > #include <iostream>
20 > #include <map>
21   #include <sstream>
22 + #include <string>
23   #include <vector>
18 #include <set>
24  
25   std::ostream &operator<<(std::ostream &out, WTS_CONNECTSTATE_CLASS status)
26   {
# Line 67 | Line 72 | inline std::string Utf8(const std::wstri
72  
73   class Finger
74   {
75 < private:
71 <        struct Login
75 >        class Login
76          {
77 <                std::string login, name, session;
77 >                std::wstring login;
78 >                mutable USER_INFO_11 *info;
79 >
80 >                inline void GetInfo() const
81 >                {
82 >                        if (!info)
83 >                                ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
84 >                }
85 >        public:
86 >                std::string session;
87                  DWORD id;
88                  WTS_CONNECTSTATE_CLASS status;
89 <                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)
89 >
90 >                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)
91                  {
92 <                        USER_INFO_11 *info;
92 >                }
93  
94 <                        ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
94 >                ~Login()
95 >                {
96 >                        if (!info)
97 >                                ::NetApiBufferFree(info);
98 >                }
99  
100 <                        name = Utf8(std::wstring(info->usri11_full_name).substr(0, 20));
100 >                std::string GetShortName() const
101 >                {
102 >                        GetInfo();
103  
104 <                        ::NetApiBufferFree(info);
104 >                        return Utf8(std::wstring(info->usri11_full_name).substr(0, 20));
105                  }
106  
107 <                bool operator<(const Login &login) const
107 >                std::string GetName() const
108                  {
109 <                        if (this->login == login.login)
110 <                                return id < login.id;
109 >                        GetInfo();
110 >
111 >                        return Utf8(info->usri11_full_name);
112 >                }
113 >
114 >                std::string GetDirectory() const
115 >                {
116 >                        HANDLE token;
117 >
118 >                        if (::WTSQueryUserToken(id, &token))
119 >                        {
120 >                                TCHAR directory[MAX_PATH];
121 >
122 >                                ::SHGetFolderPath(NULL, CSIDL_PROFILE, token, SHGFP_TYPE_CURRENT, directory);
123 >                                ::CloseHandle(token);
124 >
125 >                                return Utf8(directory);
126 >                        }
127                          else
128 <                                return this->login < login.login;
128 >                        {
129 >                                TCHAR directory_[MAX_PATH];
130 >
131 >                                ::SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, directory_);
132 >
133 >                                std::wstring directory(directory_);
134 >
135 >                                directory.replace(directory.rfind('\\') + 1, std::wstring::npos, login);
136 >
137 >                                return Utf8(directory);
138 >                        }
139                  }
140          };
141 +
142          std::ostringstream stream;
143 <        std::set<Login> logins;
143 >        std::multimap<std::string, Login> logins;
144 >
145 >        void Full()
146 >        {
147 >                for (std::multimap<std::string, Login>::const_iterator login(logins.begin()); login != logins.end(); login = logins.upper_bound(login->first))
148 >                {
149 >                        if (login != logins.begin())
150 >                                stream << "\r\n";
151 >
152 >                        std::string directory(login->second.GetDirectory());
153 >
154 >                        stream << "Login: " << login->first << std::string(33 - login->first.size(), ' ') << "Name: " << login->second.GetName() << "\r\nDirectory: " << directory << "\r\n";
155 >
156 >                        for (std::multimap<std::string, Login>::const_iterator login_(logins.lower_bound(login->first)); login_ != logins.upper_bound(login->first); ++login_)
157 >                                stream << login_->second.status << ' ' << login_->second.session << ' ' << login_->second.id << "\r\n";
158 >
159 >                        std::string files[] = { "\\.project", "\\.plan" };
160 >
161 >                        for (std::string *file(files); file != files + sizeof (files) / sizeof (*file); ++file)
162 >                        {
163 >                                file->insert(0, directory);
164 >
165 >                                std::ifstream in(file->c_str());
166 >
167 >                                if (!in.is_open())
168 >                                        continue;
169 >
170 >                                switch (file - files)
171 >                                {
172 >                                case 0:
173 >                                        stream << "Project:\r\n";
174 >
175 >                                        break;
176 >                                case 1:
177 >                                        stream << "Plan:\r\n";
178 >                                }
179 >
180 >                                std::string buffer;
181 >
182 >                                while (std::getline(in, buffer))
183 >                                        stream << buffer << std::endl;
184 >                        }
185 >                }
186 >        }
187  
188   public:
189          Finger(bool full)
# Line 110 | Line 200 | public:
200  
201                          ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &name, &size);
202  
203 <                        if (!std::wstring(name).empty())
203 >                        std::wstring name_(name);
204 >
205 >                        ::WTSFreeMemory(name);
206 >
207 >                        if (!name_.empty())
208                          {
209 +                                std::transform(name_.begin(), name_.end(), name_.begin(), std::towlower);
210 +
211                                  LPTSTR session_;
212  
213                                  ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSWinStationName, &session_, &size);
214  
215 <                                Login login(name, session->SessionId, session_, session->State);
215 >                                Login login(name_, session->SessionId, session_, session->State);
216  
217                                  ::WTSFreeMemory(session_);
218  
219 <                                logins.insert(login);
219 >                                logins.insert(std::make_pair(Utf8(name_), login));
220                          }
125
126                        ::WTSFreeMemory(name);
221                  }
222  
223                  ::WTSFreeMemory(sessions);
224  
225                  if (!full)
226                  {
227 <                        stream << "Login\t\tName" << std::string(17, ' ') << "Id     Session       Status\r\n";
227 >                        stream << "Login" << std::string(11, ' ') << "Name" << std::string(17, ' ') << "Id     Session       Status\r\n";
228  
229 <                        for (std::set<Login>::const_iterator login(logins.begin()); login != logins.end(); ++login)
230 <                                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";
229 >                        for (std::multimap<std::string, Login>::const_iterator login(logins.begin()); login != logins.end(); ++login)
230 >                                stream << login->first << std::string(16 - login->first.size(), ' ') << login->second.GetShortName() << std::string(21 - login->second.GetShortName().size(), ' ') << std::setw(5) << std::left << login->second.id << "  " << login->second.session << std::string(14 - login->second.session.size(), ' ') << login->second.status << "\r\n";
231                  }
232 +                else
233 +                        Full();
234          }
235  
236          Finger(const std::string &name)
# Line 165 | Line 261 | void WINAPI FingerControl(DWORD control)
261  
262   int _tmain(int argc, TCHAR *argv[])
263   {
264 <        SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
264 >        SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCSFinger"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
265  
266          if (!::StartServiceCtrlDispatcher(entry))
267          {
# Line 196 | Line 292 | int _tmain(int argc, TCHAR *argv[])
292          return 0;
293  
294   go:
295 +        for (int index(1); index != argc; ++index)
296 +        {
297 +                std::wstring arg(argv[index]);
298 +
299 +                if (arg == TEXT("create"))
300 +                {
301 +                        TCHAR file[MAX_PATH];
302 +
303 +                        ::GetModuleFileName(NULL, file, MAX_PATH);
304 +
305 +                        SC_HANDLE manager(::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE)), service(::CreateService(manager, TEXT("CCSFinger"), TEXT("CCS Finger Daemon"), 0, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, file, NULL, NULL, TEXT("TermService\0"), NULL, TEXT("")));
306 +
307 +                        if (!service)
308 +                                std::cerr << ::GetLastError() << std::endl;
309 +                        else
310 +                                ::CloseServiceHandle(service);
311 +
312 +                        ::CloseServiceHandle(manager);
313 +
314 +                        return 0;
315 +                }
316 +                else if (arg == TEXT("delete"))
317 +                {
318 +                        SC_HANDLE manager(::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, DELETE)), service(::OpenService(manager, TEXT("CCSFinger"), DELETE));
319 +
320 +                        if (!::DeleteService(service))
321 +                                std::cerr << ::GetLastError() << std::endl;
322 +
323 +                        ::CloseServiceHandle(service);
324 +                        ::CloseServiceHandle(manager);
325 +
326 +                        return 0;
327 +                }
328 +        }
329 +
330          stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
331  
332          ::signal(SIGINT, FingerStop);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines