INT check_users(printInfoStruct& printInfo) { DOUBLE users = 0; WTS_SESSION_INFOW *pSessionInfo = NULL; DWORD count; DWORD index; if (debug) std::wcout << L"Trying to enumerate terminal sessions" << '\n'; if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &count)) { std::wcout << L"Failed to enumerate terminal sessions" << '\n'; die(); if (pSessionInfo) WTSFreeMemory(pSessionInfo); return 3; } if (debug) std::wcout << L"Got all sessions (" << count << L"), traversing and counting active ones" << '\n'; for (index = 0; index < count; index++) { LPWSTR name; DWORD size; INT len; if (debug) std::wcout << L"Querrying session number " << index << '\n'; if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, pSessionInfo[index].SessionId, WTSUserName, &name, &size)) continue; if (debug) std::wcout << L"Found \"" << name << L"\". Checking whether it's a real session" << '\n'; len = lstrlenW(name); WTSFreeMemory(name); if (!len) continue; if (pSessionInfo[index].State == WTSActive || pSessionInfo[index].State == WTSDisconnected) { users++; if (debug) std::wcout << L"\"" << name << L"\" is a real session, counting it. Now " << users << '\n'; } } if (debug) std::wcout << "Finished coutning user sessions (" << users << "). Freeing memory and returning" << '\n'; WTSFreeMemory(pSessionInfo); printInfo.users = users; return -1; }
int _tmain(int argc, _TCHAR* argv[]) { PWTS_SESSION_INFO pSessionInfo; DWORD dwSessionInfo=0; WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE,0,1,&pSessionInfo,&dwSessionInfo); printf("[*] Windows DACL Enumeration Project - https://github.com/nccgroup/WindowsDACLEnumProject - WinStationsAndDesktopsPerms\n"); printf("[*] NCC Group Plc - http://www.nccgroup.com/ \n"); printf("[*] -h for help \n"); SetPrivilege(GetCurrentProcess(),SE_DEBUG_NAME); DWORD dwSessID = 0; ProcessIdToSessionId(GetCurrentProcessId(),&dwSessID); fprintf(stdout,"[i] Running in session %d\n",dwSessID); EnumWindowStations(&EnumWindowStationProc,NULL); return 0; }
static void WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv ) { WTS_SESSION_INFO *pInfos; DWORD count; if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE,NULL,1,&pInfos,&count)) { for (DWORD i=0;i<count;i++) { LogText("Session %d (%d)\n",pInfos[i].SessionId,pInfos[i].State); if (pInfos[i].State==WTSActive) { StartStartMenu(pInfos[i].SessionId); } } WTSFreeMemory(pInfos); } g_hServiceStatus=RegisterServiceCtrlHandlerEx(g_ServiceName,ServiceHandlerEx,NULL); if (g_hServiceStatus) { g_ServiceStatus.dwServiceType=SERVICE_WIN32; g_ServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_PAUSE_CONTINUE|SERVICE_ACCEPT_SESSIONCHANGE; g_ServiceStatus.dwWin32ExitCode=0; g_ServiceStatus.dwServiceSpecificExitCode=0; g_ServiceStatus.dwCurrentState=SERVICE_RUNNING; g_ServiceStatus.dwCheckPoint=0; g_ServiceStatus.dwWaitHint=0; SetServiceStatus(g_hServiceStatus, &g_ServiceStatus); } }
int TestWtsApiEnumerateSessions(int argc, char* argv[]) { DWORD index; DWORD count; BOOL bSuccess; HANDLE hServer; PWTS_SESSION_INFO pSessionInfo; hServer = WTS_CURRENT_SERVER_HANDLE; count = 0; pSessionInfo = NULL; bSuccess = WTSEnumerateSessions(hServer, 0, 1, &pSessionInfo, &count); if (!bSuccess) { printf("WTSEnumerateSessions failed: %d\n", (int) GetLastError()); return -1; } printf("WTSEnumerateSessions count: %d\n", count); for (index = 0; index < count; index++) { printf("[%d] SessionId: %d State: %d\n", (int) index, (int) pSessionInfo[index].SessionId, (int) pSessionInfo[index].State); } WTSFreeMemory(pSessionInfo); return 0; }
/* *@brief Returns the session number, that is currently in state active. *@return True if a session was in the active state */ bool WinApiHelper::QueryActiveSession(quint64 &SessioNumber) { SessioNumber = 0; PWTS_SESSION_INFO pSessionsBuffer = NULL; DWORD dwSessionCount = 0; WTS_SESSION_INFO wts; if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionsBuffer, &dwSessionCount)) { //Loop through all Sessions for (quint8 i = 0; i < dwSessionCount; i++) { wts = pSessionsBuffer[i]; //Nur aktive Sessions weden berücksichtigt if (wts.State == WTSActive) { SessioNumber = wts.SessionId; m_logger->debug("SessionNumber is: ") << SessioNumber; } } return true; } else { DWORD err = GetLastError(); m_logger->error("WTSEnumerateSessions failed. GetLastError: ") << err; return false; } }
DWORD GetCurrentActiveSessionId() { WTS_SESSION_INFO* pSession = NULL; DWORD session_id = -1; DWORD session_count = 0; std::cout << "GetCurrentActiveSessionId " << std::endl; if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &session_count)) { std::cout << "WTSEnumerateSessions succcessfully!" << std::endl; } else { //log error std::cout << "WTSEnumerateSessions failed!" << std::endl; return session_id; } for (int i = 0; i < session_count; i++) { int nTmpSessionId = pSession[i].SessionId; WTS_CONNECTSTATE_CLASS wts_connect_state = WTSDisconnected; WTS_CONNECTSTATE_CLASS* ptr_wts_connect_state = NULL; DWORD bytes_returned = 0; if (::WTSQuerySessionInformation( WTS_CURRENT_SERVER_HANDLE, nTmpSessionId, WTSConnectState, reinterpret_cast<LPTSTR*>(&ptr_wts_connect_state), &bytes_returned)) { wts_connect_state = *ptr_wts_connect_state; ::WTSFreeMemory(ptr_wts_connect_state); if (wts_connect_state != WTSActive) continue; } else { //log error continue; } session_id = pSession[i].SessionId; break; } std::cout << "current Active Session id: " << session_id << std::endl; return session_id; }
int findSession(TCHAR *userToFind) { int sessionId = -1; WTS_SESSION_INFO *sessions; DWORD count; if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count)) { printError(L"WTSEnumerateSessions failed: %s\n"); return -1; } for (DWORD i = 0; i < count; i++) { WCHAR *sessionUser; DWORD bytes; if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessions[i].SessionId, WTSUserName, &sessionUser, &bytes)) { printError(L"WTSQuerySessionInformation error: %s\n"); continue; } #if DEBUG wprintf(L" * Session %d: \n user: %s\n state: %d\n name: %s\n", sessions[i].SessionId, sessionUser, sessions[i].State, sessions[i].pWinStationName); #endif if (sessionUser != NULL && _wcsicmp(userToFind, sessionUser) == 0) sessionId = sessions[i].SessionId; WTSFreeMemory(sessionUser); if (sessionId != -1) break; } WTSFreeMemory(sessions); return sessionId; }
bool getActiveConsoleId(LPDWORD id) { PWTS_SESSION_INFO sessioninfo; DWORD count; if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessioninfo, &count)) return FALSE; // Ok, now find the active session DWORD i; for (i = 0; i < count; i++) { if (sessioninfo[i].State == WTSActive) { *id = sessioninfo[i].SessionId; break; } } WTSFreeMemory(&sessioninfo); return TRUE; }
// @pymethod (dict,...)|win32ts|WTSEnumerateSessions|Lists sessions on a server // @rdesc Returns a sequence of dictionaries representing WTS_SESSION_INFO structs, containing {SessionId:int, WinStationName:str, State:int} static PyObject *PyWTSEnumerateSessions(PyObject *self, PyObject *args, PyObject *kwargs) { static char *keywords[]={"Server","Version","Reserved", NULL}; HANDLE h=WTS_CURRENT_SERVER_HANDLE; DWORD Reserved=0, Version=1, cnt; PyObject *obh=NULL, *ret=NULL; PWTS_SESSION_INFO buf=NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Okk:WTSEnumerateServers", keywords, &obh, // @pyparm <o PyHANDLE>|Server|WTS_CURRENT_SERVER_HANDLE|Handle to a terminal server &Version, // @pyparm int|Version|1|Version of request, currently 1 is only valid value &Reserved)) // @pyparm int|Reserved|0|Reserved, use 0 if passed in return NULL; if (obh) if (!PyWinObject_AsHANDLE(obh, &h)) return NULL; if (!WTSEnumerateSessions(h,Reserved,Version, &buf, &cnt)) PyWin_SetAPIError("WTSEnumerateSessions"); else{ ret=PyTuple_New(cnt); if (ret) for (DWORD i=0; i<cnt; i++){ PyObject *tuple_item=Py_BuildValue("{s:k,s:u,s:k}", "SessionId", buf[i].SessionId, "WinStationName", buf[i].pWinStationName, "State", buf[i].State); if (!tuple_item){ Py_DECREF(ret); ret=NULL; break; } PyTuple_SET_ITEM(ret, i, tuple_item); } } if (buf) WTSFreeMemory(buf); return ret; }
bool mod_ts::getSessions(vector<KIWI_WTS_SESSION_INFO> * mesSessions, wstring * server) { bool reussite = false; PWTS_SESSION_INFO tabSessions; DWORD nbSessions = 0; HANDLE hServer = NULL; if(openServer(&hServer, server)) { if(reussite = WTSEnumerateSessions(hServer, 0, 1, &tabSessions, &nbSessions) != 0) { for(DWORD i = 0; i < nbSessions; i++) { KIWI_WTS_SESSION_INFO a = {tabSessions[i].SessionId, tabSessions[i].State, tabSessions[i].pWinStationName}; mesSessions->push_back(a); } WTSFreeMemory(tabSessions); } closeServer(hServer); } return reussite; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv){ sprintf( msg_err, "ServiceMain - init." ); DWORD xParam = 1; JOB = 1; // -- hServiceStatus = RegisterServiceCtrlHandlerEx( service_name, (LPHANDLER_FUNCTION_EX)ServiceCtrlHandlerEx, (PVOID)&xParam ); if( !hServiceStatus ){ prn_err( "RegisterServiceCtrlHandlerEx failed.", GetLastError() ); return; } // init service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; service_status.dwCurrentState = SERVICE_START_PENDING; service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_SESSIONCHANGE; service_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; service_status.dwServiceSpecificExitCode = 0; service_status.dwCheckPoint = 0; service_status.dwWaitHint = 5000; if( !SetServiceStatus( hServiceStatus, &service_status )){ prn_err( "SetServiceStatus 'NULL' failed.", GetLastError() ); return; } // Rabota service_status.dwCurrentState = SERVICE_RUNNING; service_status.dwWin32ExitCode = NO_ERROR; // Set New if( !SetServiceStatus( hServiceStatus, &service_status )){ prn_err( "SetServiceStatus 'SERVICE_START_PENDING' failed.", GetLastError() ); return; } // -- usleep(10000); // ------------------------------------------------------------------------ prn_log( "." ); SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ); prn_log( "START SERVICE." ); // --------------------------------- if( !init_conf( service_work, service_name, &conf )){ // возврат всегда "1" prn_err( "Init config-data failed. This message can not be", 0 ); }else{ if( strcasecmp( conf.log_debug, "Off" ) == 0 ) DEBUG = 0; else prn_log( "Logger - DEBUG" ); // -- if( strcasecmp( conf.user_proc, "0" ) == 0 ) prn_log( "WARNING! User Process - disabled." ); if( strcasecmp( conf.maintenance, "0" ) == 0 ) prn_log( "WARNING! Maintenances - disabled." ); if( strcasecmp( conf.git_exec, "0" ) == 0 ) prn_log( "WARNING! Git status - disabled." ); } // -- JOB = 2; // Создаем поток логирования cygwin (сокет /dev/log) для ssh-сессий HANDLE hCygWinLogThread = CreateThread( NULL, 0, &CygWinLogThread, (LPVOID)&conf, 0, NULL ); if( !hCygWinLogThread ){ prn_err( "LogSocket: Create CygWinLogThread - failed.", GetLastError() ); } // --------------------------------- JOB = 3; if( !open_send( conf.zbx_server, conf.zbx_port, conf.zbx_host )){ prn_log( "WARNING! Sender not available: Maintenances - will not be available." ); strcpy( conf.maintenance, "0" ); } // --------------------------------- JOB = 22; // потоки обслуживания // HANDLE hGTimeThread = CreateThread( NULL, 0, >imeThread, NULL, 0, NULL );// поток // --------------------------------- usleep(10000); JOB = 101; send_sm_string( "SM;SyMon;START;!" ); // -- // проверка активных сессий DWORD pCount; HANDLE hToken; PWTS_SESSION_INFO ppSessionInfo = NULL; HANDLE hTS = WTSOpenServer( "" ); // -- if( WTSEnumerateSessions(hTS, 0, 1, &ppSessionInfo, &pCount )){ while( pCount ){ if( ppSessionInfo->State == 0 ){ if( WTSQueryUserToken( ppSessionInfo->SessionId, &hToken )) entering_info( ppSessionInfo->SessionId, 5, hToken, NULL ); else prn_err( "WTS Token failed.", GetLastError() ); } ppSessionInfo++; pCount--; } } // ----------------------------------- while( JOB > 100 ){ // главный цикл git_test(); // выполнение отложенных (тормозных) функций sleep(1); } // -- // CloseHandle( hGTimeThread ); sleep( 2 ); close_send(); sprintf( msg_err, "ServiceMain - return." ); // ------------------------------------------------------------------------ }
int main (int argc, char **argv) { int users = -1; int result = STATE_UNKNOWN; char *perf; #if HAVE_WTSAPI32_H WTS_SESSION_INFO *wtsinfo; DWORD wtscount; DWORD index; #elif HAVE_UTMPX_H struct utmpx *putmpx; #else char input_buffer[MAX_INPUT_BUFFER]; #endif setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); perf = strdup (""); /* Parse extra opts if any */ argv = np_extra_opts (&argc, argv, progname); if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); users = 0; #if HAVE_WTSAPI32_H if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) { printf(_("Could not enumerate RD sessions: %d\n"), GetLastError()); return STATE_UNKNOWN; } for (index = 0; index < wtscount; index++) { LPTSTR username; DWORD size; int len; if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size)) continue; len = lstrlen(username); WTSFreeMemory(username); if (len == 0) continue; if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) users++; } WTSFreeMemory(wtsinfo); #elif HAVE_UTMPX_H /* get currently logged users from utmpx */ setutxent (); while ((putmpx = getutxent ()) != NULL) if (putmpx->ut_type == USER_PROCESS) users++; endutxent (); #else /* run the command */ child_process = spopen (WHO_COMMAND); if (child_process == NULL) { printf (_("Could not open pipe: %s\n"), WHO_COMMAND); return STATE_UNKNOWN; } child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); if (child_stderr == NULL) printf (_("Could not open stderr for %s\n"), WHO_COMMAND); while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { /* increment 'users' on all lines except total user count */ if (input_buffer[0] != '#') { users++; continue; } /* get total logged in users */ if (sscanf (input_buffer, _("# users=%d"), &users) == 1) break; } /* check STDERR */ if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) result = possibly_set (result, STATE_UNKNOWN); (void) fclose (child_stderr); /* close the pipe */ if (spclose (child_process)) result = possibly_set (result, STATE_UNKNOWN); #endif /* check the user count against warning and critical thresholds */ if (users > cusers) result = STATE_CRITICAL; else if (users > wusers) result = STATE_WARNING; else if (users >= 0) result = STATE_OK; if (result == STATE_UNKNOWN) printf ("%s\n", _("Unable to read output")); else { xasprintf (&perf, "%s", perfdata ("users", users, "", TRUE, wusers, TRUE, cusers, TRUE, 0, FALSE, 0)); printf (_("USERS %s - %d users currently logged in |%s\n"), state_text (result), users, perf); } return result; }
DWORD GetSessionIdOfUser(PCWSTR pszUserName, PCWSTR pszDomain) { DWORD dwSessionId = 0xFFFFFFFF; if (pszUserName == NULL) { // If the user name is not provided, try to get the session attached // to the physical console. The physical console is the monitor, // keyboard, and mouse. dwSessionId = WTSGetActiveConsoleSessionId(); } else { // If the user name is provided, get the session of the provided user. // The same user could have more than one session, this sample just // retrieves the first one found. You can add more sophisticated // checks by requesting different types of information from // WTSQuerySessionInformation. PWTS_SESSION_INFO *pSessionsBuffer = NULL; DWORD dwSessionCount = 0; // Enumerate the sessions on the current server. if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, pSessionsBuffer, &dwSessionCount)) { for (DWORD i = 0; (dwSessionId == -1) && (i < dwSessionCount); i++) { DWORD sid = pSessionsBuffer[i]->SessionId; // Get the user name from the session ID. PWSTR pszSessionUserName = NULL; DWORD dwSize; if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sid, WTSUserName, &pszSessionUserName, &dwSize)) { // Compare with the provided user name (case insensitive). if (_wcsicmp(pszUserName, pszSessionUserName) == 0) { // Get the domain from the session ID. PWSTR pszSessionDomain = NULL; if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sid, WTSDomainName, &pszSessionDomain, &dwSize)) { // Compare with the provided domain (case insensitive). if (_wcsicmp(pszDomain, pszSessionDomain) == 0) { // The session of the provided user is found. dwSessionId = sid; } WTSFreeMemory(pszSessionDomain); } } WTSFreeMemory(pszSessionUserName); } } WTSFreeMemory(pSessionsBuffer); pSessionsBuffer = NULL; dwSessionCount = 0; // Cannot find the session of the provided user. if (dwSessionId == 0xFFFFFFFF) { SetLastError(ERROR_INVALID_PARAMETER); } } } return dwSessionId; }
static BOOL check_for_active_sessions(void) { WTS_SESSION_INFO *session_info; DWORD session_info_count; BOOL rv; BOOL found_active_session = FALSE; rv = WTSEnumerateSessions( WTS_CURRENT_SERVER_HANDLE, 0, /* Reserved */ 1, /* Version */ &session_info, &session_info_count); if (!rv) { logger_printf(TEXT("WTSEnumerateSessions: error")); return FALSE; } if (session_info_count > 0) { size_t i; for (i = 0; i < session_info_count; i++) { logger_printf(TEXT("session %d \"%s\" is %d"), session_info[i].SessionId, session_info[i].pWinStationName, session_info[i].State); { TCHAR *pBuffer = NULL; DWORD bytesReturned; if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_info[i].SessionId, WTSUserName, &pBuffer, &bytesReturned)) { logger_printf(TEXT(" username: %s"), pBuffer); if (_tcscmp(TEXT("Student-PAC"), pBuffer) == 0) { logger_printf(TEXT(" this username is EXEMPT")); } else if (session_info[i].State == WTSActive && _tcscmp(TEXT("Console"), session_info[i].pWinStationName) == 0 && _tcslen(pBuffer) > 0) { logger_printf(TEXT(" this session is active")); found_active_session = TRUE; } WTSFreeMemory(pBuffer); pBuffer = NULL; } } } } else { logger_printf(TEXT("no sessions found")); } WTSFreeMemory(session_info); { LASTINPUTINFO lii = { sizeof(LASTINPUTINFO) }; if (GetLastInputInfo(&lii)) { size_t elapsed = GetTickCount() - lii.dwTime; logger_printf(TEXT("Note: %d seconds since last input"), elapsed / 1000); // if (elapsed / 1000 < 300 && lii.dwTime / 1000 > 300) // { // return TRUE; // } } } logger_printf(TEXT("found active session == %s"), found_active_session ? TEXT("true") : TEXT("false")); return found_active_session; }
void main(int argc, char *argv[]) { char *helpMsg = "\nUSAGE: users.exe [hostname]\n\nNot specifying a hostname implies localhost.\nThis command will return information about users currently logged onto\na local or remote computer, including the client's hostname and IP.\nUsers.exe was written by Ryan Ries.\n"; char *hostName, *connState = ""; char *addrFamily = ""; HANDLE hHost = NULL; int retVal = 0; unsigned int i = 0; PWTS_SESSION_INFO pSessionInfo = 0; DWORD dwSessionCount, pBytesReturned = 0; LPTSTR pUser, pDomain, pClientName, pClientAddress; PWTS_CLIENT_ADDRESS pClientAddressStruct = NULL; if(argc > 2) { printf(helpMsg); return; } if(argc == 2) { if(strchr(argv[1],'?') || strchr(argv[1],'/') || strchr(argv[1],'\\')) { printf(helpMsg); return; } } if(argc < 2) hostName = "localhost"; else hostName = argv[1]; hHost = WTSOpenServer(hostName); retVal = WTSEnumerateSessions(hHost, 0, 1, &pSessionInfo, &dwSessionCount); if(retVal == 0) { printf("ERROR %d: Could not connect to %s!", GetLastError(), hostName); WTSCloseServer(hHost); return; } printf("\n"); for(i = 0; i < dwSessionCount; i++) { WTS_SESSION_INFO si = pSessionInfo[i]; // To weed out nonsense if(si.SessionId > 2048 || si.SessionId < 0) continue; WTSQuerySessionInformation(hHost, si.SessionId, WTSUserName, &pUser, &pBytesReturned); WTSQuerySessionInformation(hHost, si.SessionId, WTSDomainName, &pDomain, &pBytesReturned); WTSQuerySessionInformation(hHost, si.SessionId, WTSClientName, &pClientName, &pBytesReturned); WTSQuerySessionInformation(hHost, si.SessionId, WTSClientAddress, &pClientAddress, &pBytesReturned); pClientAddressStruct = (PWTS_CLIENT_ADDRESS)pClientAddress; switch(pClientAddressStruct->AddressFamily) { case 0: addrFamily = "AF_UNSPEC"; break; case 2: addrFamily = "AF_INET"; break; case 6: addrFamily = "AF_IPX"; break; case 17: addrFamily = "AF_NETBIOS"; break; default: addrFamily = "Unknown"; break; } printf("Session ID : %i\n", si.SessionId); if(strlen(pUser) < 1) printf("Domain\\User : System\n"); else printf("Domain\\User : %s\\%s\n", pDomain, pUser); if(strlen(pClientName) < 1) printf("Client Name : Local\n"); else printf("Client Name : %s\n", pClientName); if(pClientAddressStruct->Address[2] == 0 || addrFamily == "AF_UNSPEC") printf("Net Address : n/a\n"); else printf("Net Address : %u.%u.%u.%u (%s)\n", pClientAddressStruct->Address[2], pClientAddressStruct->Address[3], pClientAddressStruct->Address[4], pClientAddressStruct->Address[5], addrFamily); switch(si.State) { case 0: connState = "Active"; break; case 1: connState = "Connected"; break; case 4: connState = "Disconnected"; break; case 5: connState = "Idle"; break; default: connState = "Unknown"; break; } printf("Conn. State : %s\n", connState); printf("\n"); WTSFreeMemory(pClientAddress); WTSFreeMemory(pClientName); WTSFreeMemory(pDomain); WTSFreeMemory(pUser); } WTSFreeMemory(pSessionInfo); WTSCloseServer(hHost); }