9 |
|
#include <signal.h> |
10 |
|
#include <wtsapi32.h> |
11 |
|
#include <lm.h> |
12 |
+ |
#include <shlobj.h> |
13 |
|
|
14 |
|
#include <algorithm> |
15 |
|
#include <iostream> |
77 |
|
|
78 |
|
inline void GetInfo() const |
79 |
|
{ |
80 |
< |
::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info)); |
80 |
> |
if (!info) |
81 |
> |
::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info)); |
82 |
|
} |
83 |
|
public: |
84 |
|
std::string session; |
95 |
|
::NetApiBufferFree(info); |
96 |
|
} |
97 |
|
|
98 |
< |
std::string GetName() const |
98 |
> |
std::string GetShortName() const |
99 |
|
{ |
100 |
< |
if (!info) |
99 |
< |
GetInfo(); |
100 |
> |
GetInfo(); |
101 |
|
|
102 |
|
return Utf8(std::wstring(info->usri11_full_name).substr(0, 20)); |
103 |
|
} |
104 |
+ |
|
105 |
+ |
std::string GetName() const |
106 |
+ |
{ |
107 |
+ |
GetInfo(); |
108 |
+ |
|
109 |
+ |
return Utf8(info->usri11_full_name); |
110 |
+ |
} |
111 |
+ |
|
112 |
+ |
std::string GetDirectory() const |
113 |
+ |
{ |
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 |
+ |
{ |
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; |
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\n"; |
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 |
|
|
190 |
|
stream << "Login" << std::string(11, ' ') << "Name" << std::string(17, ' ') << "Id Session Status\r\n"; |
191 |
|
|
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.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"; |
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(); |
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 |
|
{ |
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); |