// Douglas Thrift // // CCS Computer Science // // Windows Finger Daemon #include #include #include #include #include #include LPTSTR name; SERVICE_STATUS status; SERVICE_STATUS_HANDLE handle; HANDLE stop; WSADATA data; void FingerDaemon(); void FingerStop(int); void WINAPI FingerMain(DWORD argc, LPTSTR *argv); void WINAPI FingerControl(DWORD control); int _tmain(int argc, TCHAR *argv[]) { PWTS_SESSION_INFO sessions; DWORD count; if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count)) { std::cerr << GetLastError() << std::endl; return 1; } for (PWTS_SESSION_INFO session = sessions; session != sessions + count; ++session) { LPTSTR userName, clientName; DWORD userNameSize, clientNameSize; WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &userName, &userNameSize); WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSClientName, &clientName, &clientNameSize); std::wcout << '{' << std::endl << '\t' << session->SessionId << std::endl << '\t' << session->pWinStationName << std::endl << '\t'; switch (session->State) { case WTSActive: std::cout << "Active"; break; case WTSConnected: std::cout << "Connected"; break; case WTSConnectQuery: std::cout << "Connect Query"; break; case WTSShadow: std::cout << "Shadow"; break; case WTSDisconnected: std::cout << "Disconnected"; break; case WTSIdle: std::cout << "Idle"; break; case WTSListen: std::cout << "Listen"; break; case WTSReset: std::cout << "Reset"; break; case WTSDown: std::cout << "Down"; break; case WTSInit: std::cout << "Init"; break; } std::wcout << std::endl << '\t' << userName << std::endl << '\t' << clientName << std::endl << '}' << std::endl; WTSFreeMemory(userName); WTSFreeMemory(clientName); } WTSFreeMemory(sessions); /*SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } }; if (!StartServiceCtrlDispatcher(entry)) { DWORD error(GetLastError()); switch (error) { case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: goto go; case ERROR_INVALID_DATA: std::cerr << "ERROR_INVALID_DATA" << std::endl; break; case ERROR_SERVICE_ALREADY_RUNNING: std::cerr << "ERROR_SERVICE_ALREADY_RUNNING" << std::endl; break; default: std::cerr << error << std::endl; } return 1; } return 0; go: stop = CreateEvent(NULL, TRUE, FALSE, NULL); signal(SIGINT, FingerStop); try { FingerDaemon(); } catch (...) {} return 0;*/ } void FingerDaemon() { WSAStartup(MAKEWORD(2, 0), &data); // SOCKET server(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)); SOCKADDR_IN service; service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr("0.0.0.0"); service.sin_port = htons(79); bind(server, (SOCKADDR *)(&service), sizeof (service)); listen(server, SOMAXCONN); SOCKET client; while(WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0 && (client = accept(server, NULL, NULL)) == SOCKET_ERROR) { // } // closesocket(server); WSACleanup(); } void FingerStop(int) { SetEvent(stop); std::cout << "Stop!" << std::endl; } void WINAPI FingerMain(DWORD argc, LPTSTR *argv) { name = argv[0]; handle = RegisterServiceCtrlHandler(name, LPHANDLER_FUNCTION(FingerControl)); stop = CreateEvent(NULL, TRUE, FALSE, NULL); // status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; status.dwServiceSpecificExitCode = 0; status.dwCurrentState = SERVICE_RUNNING; status.dwWin32ExitCode = NO_ERROR; status.dwCheckPoint = 0; status.dwWaitHint = 0; SetServiceStatus(handle, &status); try { FingerDaemon(); } catch (...) {} status.dwCurrentState = SERVICE_STOPPED; status.dwWin32ExitCode = NO_ERROR; status.dwCheckPoint = 0; status.dwWaitHint = 0; SetServiceStatus(handle, &status); } void WINAPI FingerControl(DWORD control) { switch (control) { case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_SHUTDOWN: status.dwCurrentState = SERVICE_STOP_PENDING; SetEvent(stop); break; case SERVICE_CONTROL_INTERROGATE: break; } SetServiceStatus(handle, &status); }