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 617 by douglas, 2005-12-13T01:35:20-08:00

# Line 9 | Line 9
9   #include <signal.h>
10   #include <wtsapi32.h>
11   #include <lm.h>
12 + #include <shlobj.h>
13  
14 + #include <algorithm>
15   #include <iostream>
16   #include <iomanip>
17   #include <string>
18   #include <sstream>
19   #include <vector>
20 < #include <set>
20 > #include <map>
21 > #include <cwctype>
22  
23   std::ostream &operator<<(std::ostream &out, WTS_CONNECTSTATE_CLASS status)
24   {
# Line 67 | Line 70 | inline std::string Utf8(const std::wstri
70  
71   class Finger
72   {
73 < private:
71 <        struct Login
73 >        class Login
74          {
75 <                std::string login, name, session;
75 >                std::wstring login;
76 >                mutable USER_INFO_11 *info;
77 >
78 >                inline void GetInfo() const
79 >                {
80 >                        if (!info)
81 >                                ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
82 >                }
83 >        public:
84 >                std::string session;
85                  DWORD id;
86                  WTS_CONNECTSTATE_CLASS status;
87 <                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)
87 >
88 >                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)
89                  {
90 <                        USER_INFO_11 *info;
90 >                }
91  
92 <                        ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
92 >                ~Login()
93 >                {
94 >                        if (!info)
95 >                                ::NetApiBufferFree(info);
96 >                }
97  
98 <                        name = Utf8(std::wstring(info->usri11_full_name).substr(0, 20));
98 >                std::string GetShortName() const
99 >                {
100 >                        GetInfo();
101 >
102 >                        return Utf8(std::wstring(info->usri11_full_name).substr(0, 20));
103 >                }
104  
105 <                        ::NetApiBufferFree(info);
105 >                std::string GetName() const
106 >                {
107 >                        GetInfo();
108 >
109 >                        return Utf8(info->usri11_full_name);
110                  }
111  
112 <                bool operator<(const Login &login) const
112 >                std::string GetDirectory() const
113                  {
114 <                        if (this->login == login.login)
115 <                                return id < login.id;
114 >                        HANDLE token;
115 >
116 >                        if (::WTSQueryUserToken(id, &token))
117 >                        {
118 >                                TCHAR directory[MAX_PATH];
119 >
120 >                                ::SHGetFolderPath(NULL, CSIDL_PROFILE, token, SHGFP_TYPE_CURRENT, directory);
121 >                                ::CloseHandle(token);
122 >
123 >                                return Utf8(directory);
124 >                        }
125                          else
126 <                                return this->login < login.login;
126 >                        {
127 >                                TCHAR directory_[MAX_PATH];
128 >
129 >                                ::SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, directory_);
130 >
131 >                                std::wstring directory(directory_);
132 >
133 >                                directory.replace(directory.rfind('\\') + 1, std::wstring::npos, login);
134 >
135 >                                return Utf8(directory);
136 >                        }
137                  }
138          };
139 +
140          std::ostringstream stream;
141 <        std::set<Login> logins;
141 >        std::multimap<std::string, Login> logins;
142 >
143 >        void Full()
144 >        {
145 >                for (std::multimap<std::string, Login>::const_iterator login(logins.begin()); login != logins.end(); login = logins.upper_bound(login->first))
146 >                {
147 >                        stream << "Login: " << login->first << std::string(33 - login->first.size(), ' ') << "Name: " << login->second.GetName() << "\r\nDirectory: " << login->second.GetDirectory() << "\r\n";
148 >                }
149 >        }
150  
151   public:
152          Finger(bool full)
# Line 110 | Line 163 | public:
163  
164                          ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &name, &size);
165  
166 <                        if (!std::wstring(name).empty())
166 >                        std::wstring name_(name);
167 >
168 >                        ::WTSFreeMemory(name);
169 >
170 >                        if (!name_.empty())
171                          {
172 +                                std::transform(name_.begin(), name_.end(), name_.begin(), std::towlower);
173 +
174                                  LPTSTR session_;
175  
176                                  ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSWinStationName, &session_, &size);
177  
178 <                                Login login(name, session->SessionId, session_, session->State);
178 >                                Login login(name_, session->SessionId, session_, session->State);
179  
180                                  ::WTSFreeMemory(session_);
181  
182 <                                logins.insert(login);
182 >                                logins.insert(std::make_pair(Utf8(name_), login));
183                          }
125
126                        ::WTSFreeMemory(name);
184                  }
185  
186                  ::WTSFreeMemory(sessions);
187  
188                  if (!full)
189                  {
190 <                        stream << "Login\t\tName" << std::string(17, ' ') << "Id     Session       Status\r\n";
190 >                        stream << "Login" << std::string(11, ' ') << "Name" << std::string(17, ' ') << "Id     Session       Status\r\n";
191  
192 <                        for (std::set<Login>::const_iterator login(logins.begin()); login != logins.end(); ++login)
193 <                                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";
192 >                        for (std::multimap<std::string, Login>::const_iterator login(logins.begin()); login != logins.end(); ++login)
193 >                                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";
194                  }
195 +                else
196 +                        Full();
197          }
198  
199          Finger(const std::string &name)
# Line 165 | Line 224 | void WINAPI FingerControl(DWORD control)
224  
225   int _tmain(int argc, TCHAR *argv[])
226   {
227 <        SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
227 >        SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCSFinger"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
228  
229          if (!::StartServiceCtrlDispatcher(entry))
230          {
# Line 196 | Line 255 | int _tmain(int argc, TCHAR *argv[])
255          return 0;
256  
257   go:
258 +        for (int index(1); index != argc; ++index)
259 +        {
260 +                std::wstring arg(argv[index]);
261 +
262 +                if (arg == TEXT("create"))
263 +                {
264 +                        TCHAR file[MAX_PATH];
265 +
266 +                        ::GetModuleFileName(NULL, file, MAX_PATH);
267 +
268 +                        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("")));
269 +
270 +                        if (!service)
271 +                                std::cerr << ::GetLastError() << std::endl;
272 +                        else
273 +                                ::CloseServiceHandle(service);
274 +
275 +                        ::CloseServiceHandle(manager);
276 +
277 +                        return 0;
278 +                }
279 +                else if (arg == TEXT("delete"))
280 +                {
281 +                        SC_HANDLE manager(::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, DELETE)), service(::OpenService(manager, TEXT("CCSFinger"), DELETE));
282 +
283 +                        if (!::DeleteService(service))
284 +                                std::cerr << ::GetLastError() << std::endl;
285 +
286 +                        ::CloseServiceHandle(service);
287 +                        ::CloseServiceHandle(manager);
288 +
289 +                        return 0;
290 +                }
291 +        }
292 +
293          stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
294  
295          ::signal(SIGINT, FingerStop);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines