Ghost21 Posted December 11, 2007 Share Posted December 11, 2007 Yeah sounds simple.. Well not so much .. I need to be able to unlock a locked PC on my network. So if I try to Remote Assistance the user and the user is there its no problem .. but if I get busy the user is gone and the Remote Assistance session locks I can't send CTRL + ALT + DEL to the session to log back in.. and no CTRL + ALT + END does not work ... is there somethign else that I can do to get past or around.. Not trying to hack or anything this is actually a Big problem ... The clock starts now... ... ideas so far something like scheduled task does a ctrl 3 mins later... ... psexec something ??? I would like it instant is possible... ??? Link to comment Share on other sites More sharing options...
Shevilie Posted December 11, 2007 Share Posted December 11, 2007 Yeah sounds simple.. Well not so much .. I need to be able to unlock a locked PC on my network. So if I try to Remote Assistance the user and the user is there its no problem .. but if I get busy the user is gone and the Remote Assistance session locks I can't send CTRL + ALT + DEL to the session to log back in.. and no CTRL + ALT + END does not work ... is there somethign else that I can do to get past or around.. Not trying to hack or anything this is actually a Big problem ... The clock starts now...... ideas so far something like scheduled task does a ctrl 3 mins later...... psexec something ???I would like it instant is possible... ???"N.B. Windows does not allow the simulation of the "CTRL-ALT-DEL" combination!"http://www.autoitscript.com/autoit3/docs/functions/Send.htm Start here if you are new Valuater's AutoIT 1-2-3Looking for an UDF - Look hereDo you need to do it twice - Autoit Link to comment Share on other sites More sharing options...
schilbiz Posted December 11, 2007 Share Posted December 11, 2007 "N.B. Windows does not allow the simulation of the "CTRL-ALT-DEL" combination!"http://www.autoitscript.com/autoit3/docs/functions/Send.htmIf you have admin credentials on the pc just use a remote desktop session and log in. Otherwise to simulate (ctrl alt dlt) on a remote machine just hit (ctrl shft esc) and that will bring up the task manager.You could try, mstsc /console which will override any remote session on the system. But you still need login credentials. Link to comment Share on other sites More sharing options...
Ghost21 Posted December 11, 2007 Author Share Posted December 11, 2007 "N.B. Windows does not allow the simulation of the "CTRL-ALT-DEL" combination!"http://www.autoitscript.com/autoit3/docs/functions/Send.htmJust because it says it cannot be done doesn't mean that there isn't a registry key or something else that can be done to work around it.. There is always more then ONE way to skin a CAT even when you drag it scratching and hissing..like windows does... Link to comment Share on other sites More sharing options...
Ghost21 Posted December 11, 2007 Author Share Posted December 11, 2007 Come on people any thoughts ???? Link to comment Share on other sites More sharing options...
weaponx Posted December 11, 2007 Share Posted December 11, 2007 Ditch remote desktop and use UltraVNC. You can send Ctrl+Alt+Del with the click of a button. Link to comment Share on other sites More sharing options...
JustinReno Posted December 11, 2007 Share Posted December 11, 2007 Haha, NO. CTRLALTDELETE can not be sent. Link to comment Share on other sites More sharing options...
Ghost21 Posted December 11, 2007 Author Share Posted December 11, 2007 Right now I use REMOTE Assistance not Remote Desktop as I can show the USER whats going on .. .. Workaround for the ctrl alt del... Reboot pc.. Ehhh slow.. but will work.. .. Remote desktop pc.. Log in then .. Remote assistance.. The machine... SLOW too... Can I just make the desktop visable... ? Change a registery key.. Stand on my head ??? Link to comment Share on other sites More sharing options...
Ghost21 Posted December 11, 2007 Author Share Posted December 11, 2007 I even thought about Running OSK.EXE " On - Screen Keyboard... " with psexec.. frekin winblowz blocked that too... Link to comment Share on other sites More sharing options...
weaponx Posted December 11, 2007 Share Posted December 11, 2007 Haha, NO.CTRLALTDELETE can not be sent.I've used it for 4 years now. Yes it can.Look at this picture:http://www.limsi.fr/Individu/pointal/winre...BarreOutils.jpgAll the way to the left it says CAD. Link to comment Share on other sites More sharing options...
weaponx Posted December 11, 2007 Share Posted December 11, 2007 You don't even have to stop using Remote Desktop, you can just install the VNC server on all of your clients with Active Directory authentication so you don't have to worry about managing passwords on hundreds of machines, you can simply choose which groups are allowed to access it.- You can transfer files / folders.- Integrates with Hyena- Web client available- Copy / paste works well remotely- Encryption optionaletc... Link to comment Share on other sites More sharing options...
John117 Posted December 11, 2007 Share Posted December 11, 2007 (edited) I've used it for 4 years now. Yes it can.I see your picture, but was of the thought that CAD was a hardware (Keyboard) interupt. (not a keypress)Edit: Can this be coded? -never tried it autoit because I was told no in VBA after looking it up Edited December 11, 2007 by Hatcheda Link to comment Share on other sites More sharing options...
Danny35d Posted December 11, 2007 Share Posted December 11, 2007 Right now I use REMOTE Assistance not Remote Desktop as I can show the USER whats going on .. .. Workaround for the ctrl alt del... Reboot pc.. Ehhh slow.. but will work.... Remote desktop pc.. Log in then .. Remote assistance.. The machine... SLOW too...Can I just make the desktop visable... ?Change a registery key.. Stand on my head ???What you can do is to change the policy so it will disable C-A-D and and jump right to the login screen.Not Requiring Ctrl-ALT-DEL at logon AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line Link to comment Share on other sites More sharing options...
weaponx Posted December 11, 2007 Share Posted December 11, 2007 At my old job I had to manage a lot of computers remotely. I used Sysinternals Psexec to push out this script to all of the machines. This would run silently and block the user from disabling the server. You could also hide the status icon on the remote machine. If you wanted to give your clients more control there is an option to prompt for confirmation on their end before access is allowed. ;Extract all files from UltraVNC 1.0.1 Server zip here before compiling $path = @ProgramFilesDir & "\UltraVNC" DirCreate ( $path ) FileInstall("vncserver.reg",$path & "\vncserver.reg",1) FileInstall("winvnc.exe",$path & "\winvnc.exe",1) FileInstall("authadmin.dll",$path & "\*.dll",1) FileInstall("authSSP.dll",$path & "\*.dll",1) FileInstall("ldapauth.dll",$path & "\*.dll",1) FileInstall("logging.dll",$path & "\*.dll",1) FileInstall("logmessages.dll",$path & "\*.dll",1) FileInstall("UnZip32.dll",$path & "\*.dll",1) FileInstall("vnchooks.dll",$path & "\*.dll",1) FileInstall("workgrpdomnt4.dll",$path & "\*.dll",1) FileInstall("Zip32.dll",$path & "\*.dll",1) If NOT FileExists ($path & "\vncserver.reg") Then MsgBox(0,"","vncserver.reg not found in " & $path) Exit EndIf If NOT FileExists ($path & "\winvnc.exe") Then MsgBox(0,"","winvnc.exe not found in " & $path) Exit EndIf $run0 = RunWait("regedit.exe /S " & "vncserver.reg", $path) $run1 = RunWait($path & "\winvnc -reinstall", $path) $run2 = RunWait(@ComSpec & " /c " & "net start WinVNC",$path,@SW_HIDE) $run3 = RunWait($path & "\winvnc -servicehelper", $path) Link to comment Share on other sites More sharing options...
DW1 Posted December 11, 2007 Share Posted December 11, 2007 Yep, I have used all the VNCs (Real, Ultra, and a couple others). ALL of them have simulated CTRL-ALT-DEL AutoIt3 Online Help Link to comment Share on other sites More sharing options...
icadea Posted December 16, 2007 Share Posted December 16, 2007 The code below is from VNC(open source). There is a function called SimulateCtrlAltDel which i believe is used to generate Ctrl-Alt-Del. Hope someone can generate that in Autoit expandcollapse popup// Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This file is part of the VNC system. // // The VNC system is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // If the source code for the VNC system is not available from the place // whence you received this file, check http://www.uk.research.att.com/vnc or contact // the authors on vnc@uk.research.att.com for information on obtaining it. // vncService // Implementation of service-oriented functionality of WinVNC #include "stdhdrs.h" // Header #include "vncService.h" #include <lmcons.h> #include "omnithread.h" #include "WinVNC.h" #include "vncMenu.h" #include "vncTimedMsgBox.h" #include "localization.h" // Act : add localization on messages // Error message logging void LogErrorMsg(char *message); BOOL serviceshutdown; // OS-SPECIFIC ROUTINES // Create an instance of the vncService class to cause the static fields to be // initialised properly vncService init; DWORD g_platform_id; BOOL g_impersonating_user = 0; DWORD g_version_major; DWORD g_version_minor; vncService::vncService() { OSVERSIONINFO osversioninfo; osversioninfo.dwOSVersionInfoSize = sizeof(osversioninfo); // Get the current OS version if (!GetVersionEx(&osversioninfo)) g_platform_id = 0; g_platform_id = osversioninfo.dwPlatformId; g_version_major = osversioninfo.dwMajorVersion; g_version_minor = osversioninfo.dwMinorVersion; serviceshutdown=false; } // CurrentUser - fills a buffer with the name of the current user! BOOL GetCurrentUser(char *buffer, UINT size) // RealVNC 336 change { // How to obtain the name of the current user depends upon the OS being used if ((g_platform_id == VER_PLATFORM_WIN32_NT) && vncService::RunningAsService()) { // Windows NT, service-mode // -=- FIRSTLY - verify that a user is logged on // Get the current Window station HWINSTA station = GetProcessWindowStation(); if (station == NULL) return FALSE; // Get the current user SID size DWORD usersize; GetUserObjectInformation(station, UOI_USER_SID, NULL, 0, &usersize); DWORD dwErrorCode = GetLastError(); SetLastError(0); // Check the required buffer size isn't zero if (usersize == 0) { // No user is logged in - ensure we're not impersonating anyone RevertToSelf(); g_impersonating_user = FALSE; // Return "" as the name... if (strlen("") >= size) return FALSE; strcpy(buffer, ""); return TRUE; } // -=- SECONDLY - a user is logged on but if we're not impersonating // them then we can't continue! if (!g_impersonating_user) { // Return "" as the name... if (strlen("") >= size) return FALSE; strcpy(buffer, ""); return TRUE; } } // -=- When we reach here, we're either running under Win9x, or we're running // under NT as an application or as a service impersonating a user // Either way, we should find a suitable user name. switch (g_platform_id) { case VER_PLATFORM_WIN32_WINDOWS: case VER_PLATFORM_WIN32_NT: { // Just call GetCurrentUser DWORD length = size; if (GetUserName(buffer, &length) == 0) { UINT error = GetLastError(); if (error == ERROR_NOT_LOGGED_ON) { // No user logged on if (strlen("") >= size) return FALSE; strcpy(buffer, ""); return TRUE; } else { // Genuine error... vnclog.Print(LL_INTERR, VNCLOG("getusername error %d\n"), GetLastError()); return FALSE; } } } return TRUE; }; // OS was not recognised! return FALSE; } // RealVNC 336 change BOOL vncService::CurrentUser(char *buffer, UINT size) { BOOL result = GetCurrentUser(buffer, size); if (result && (strcmp(buffer, "") == 0) && !vncService::RunningAsService()) { strncpy(buffer, "Default", size); } return result; } BOOL vncService::IsWSLocked() { if (!IsWinNT()) return false; bool bLocked = false; HDESK hDesk; BOOL bRes; DWORD dwLen; char sName[200]; hDesk = OpenInputDesktop(0, FALSE, 0); if (hDesk == NULL) { bLocked = true; } else { bRes = GetUserObjectInformation(hDesk, UOI_NAME, sName, sizeof(sName), &dwLen); if (bRes) sName[dwLen]='\0'; else sName[0]='\0'; CloseDesktop(hDesk); if (stricmp(sName,"Default") != 0) bLocked = true; // WS is locked or screen saver active else bLocked = false; } return bLocked; } // IsWin95 - returns a BOOL indicating whether the current OS is Win95 BOOL vncService::IsWin95() { return (g_platform_id == VER_PLATFORM_WIN32_WINDOWS); } // IsWinNT - returns a bool indicating whether the current OS is WinNT BOOL vncService::IsWinNT() { return (g_platform_id == VER_PLATFORM_WIN32_NT); } // Version info DWORD vncService::VersionMajor() { return g_version_major; } DWORD vncService::VersionMinor() { return g_version_minor; } // Internal routine to find the WinVNC menu class window and // post a message to it! BOOL PostToWinVNC(UINT message, WPARAM wParam, LPARAM lParam) { // Locate the hidden WinVNC menu window HWND hservwnd = FindWindow(MENU_CLASS_NAME, NULL); if (hservwnd == NULL) return FALSE; // Post the message to WinVNC PostMessage(hservwnd, message, wParam, lParam); return TRUE; } // Static routines only used on Windows NT to ensure we're in the right desktop // These routines are generally available to any thread at any time. // - SelectDesktop(HDESK) // Switches the current thread into a different desktop by deskto handle // This call takes care of all the evil memory management involved BOOL vncService::SelectHDESK(HDESK new_desktop) { // Are we running on NT? if (IsWinNT()) { HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); DWORD dummy; char new_name[256]; if (!GetUserObjectInformation(new_desktop, UOI_NAME, &new_name, 256, &dummy)) { return FALSE; } vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK to %s (%x) from %x\n"), new_name, new_desktop, old_desktop); // Switch the desktop if(!SetThreadDesktop(new_desktop)) { return FALSE; } // Switched successfully - destroy the old desktop if (!CloseDesktop(old_desktop)) vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK failed to close old desktop %x (Err=%d)\n"), old_desktop, GetLastError()); return TRUE; } return TRUE; } // - SelectDesktop(char *) // Switches the current thread into a different desktop, by name // Calling with a valid desktop name will place the thread in that desktop. // Calling with a NULL name will place the thread in the current input desktop. BOOL vncService::SelectDesktop(char *name) { // Are we running on NT? if (IsWinNT()) { HDESK desktop; vnclog.Print(LL_INTERR, VNCLOG("SelectDesktop \n")); if (name != NULL) { vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop2 named\n")); // Attempt to open the named desktop desktop = OpenDesktop(name, 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } else { vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop2 NULL\n")); // No, so open the input desktop desktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } // Did we succeed? if (desktop == NULL) { vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop2 \n")); return FALSE; } else vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop2 OK\n")); // Switch to the new desktop if (!SelectHDESK(desktop)) { // Failed to enter the new desktop, so free it! if (!CloseDesktop(desktop)) vnclog.Print(LL_INTERR, VNCLOG("SelectDesktop failed to close desktop\n")); return FALSE; } // We successfully switched desktops! return TRUE; } return (name == NULL); } // Find the visible window station and switch to it // This would allow the service to be started non-interactive // Needs more supporting code & a redesign of the server core to // work, with better partitioning between server & UI components. static HWINSTA home_window_station = GetProcessWindowStation(); BOOL CALLBACK WinStationEnumProc(LPTSTR name, LPARAM param) { HWINSTA station = OpenWindowStation(name, FALSE, GENERIC_ALL); HWINSTA oldstation = GetProcessWindowStation(); USEROBJECTFLAGS flags; if (!GetUserObjectInformation(station, UOI_FLAGS, &flags, sizeof(flags), NULL)) { return TRUE; } BOOL visible = flags.dwFlags & WSF_VISIBLE; if (visible) { if (SetProcessWindowStation(station)) { if (oldstation != home_window_station) { CloseWindowStation(oldstation); } } else { CloseWindowStation(station); } return FALSE; } return TRUE; } BOOL vncService::SelectInputWinStation() { home_window_station = GetProcessWindowStation(); return EnumWindowStations(&WinStationEnumProc, NULL); } void vncService::SelectHomeWinStation() { HWINSTA station=GetProcessWindowStation(); SetProcessWindowStation(home_window_station); CloseWindowStation(station); } // NT only function to establish whether we're on the current input desktop BOOL vncService::InputDesktopSelected() { // Are we running on NT? // if (serviceshutdown==true) return TRUE; if (IsWinNT()) { // Get the input and thread desktops HDESK threaddesktop = GetThreadDesktop(GetCurrentThreadId()); HDESK inputdesktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); // Get the desktop names: // *** I think this is horribly inefficient but I'm not sure. if (inputdesktop == NULL) { DWORD lasterror; lasterror=GetLastError(); vnclog.Print(LL_INTERR, VNCLOG("OpenInputDesktop I\n")); if (lasterror==170) return TRUE; vnclog.Print(LL_INTERR, VNCLOG("OpenInputDesktop II\n")); return FALSE; } DWORD dummy; char threadname[256]; char inputname[256]; if (!GetUserObjectInformation(threaddesktop, UOI_NAME, &threadname, 256, &dummy)) { if (!CloseDesktop(inputdesktop)) vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n")); return FALSE; } _ASSERT(dummy <= 256); if (!GetUserObjectInformation(inputdesktop, UOI_NAME, &inputname, 256, &dummy)) { if (!CloseDesktop(inputdesktop)) vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n")); return FALSE; } _ASSERT(dummy <= 256); if (!CloseDesktop(inputdesktop)) vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n")); if (strcmp(threadname, inputname) != 0) return FALSE; } return TRUE; } // Static routine used to fool Winlogon into thinking CtrlAltDel was pressed void * SimulateCtrlAltDelThreadFn(void *context) { HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); // Switch into the Winlogon desktop if (!vncService::SelectDesktop("Winlogon")) { vnclog.Print(LL_INTERR, VNCLOG("failed to select logon desktop\n")); return FALSE; } vnclog.Print(LL_ALL, VNCLOG("generating ctrl-alt-del\n")); // Fake a hotkey event to any windows we find there.... :( // Winlogon uses hotkeys to trap Ctrl-Alt-Del... PostMessage(HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE)); // Switch back to our original desktop if (old_desktop != NULL) vncService::SelectHDESK(old_desktop); return NULL; } // Static routine to simulate Ctrl-Alt-Del locally BOOL vncService::SimulateCtrlAltDel() { vnclog.Print(LL_ALL, VNCLOG("preparing to generate ctrl-alt-del\n")); // Are we running on NT? if (IsWinNT()) { vnclog.Print(LL_ALL, VNCLOG("spawn ctrl-alt-del thread...\n")); // *** This is an unpleasant hack. Oh dear. // I simulate CtrAltDel by posting a WM_HOTKEY message to all // the windows on the Winlogon desktop. // This requires that the current thread is part of the Winlogon desktop. // But the current thread has hooks set & a window open, so it can't // switch desktops, so I instead spawn a new thread & let that do the work... omni_thread *thread = omni_thread::create(SimulateCtrlAltDelThreadFn); if (thread == NULL) return FALSE; thread->join(NULL); return TRUE; } return TRUE; } // Static routine to lock a 2K or above workstation BOOL vncService::LockWorkstation() { if (!IsWinNT()) { vnclog.Print(LL_INTERR, VNCLOG("unable to lock workstation - not NT\n")); return FALSE; } vnclog.Print(LL_ALL, VNCLOG("locking workstation\n")); // Load the user32 library HMODULE user32 = LoadLibrary("user32.dll"); if (!user32) { vnclog.Print(LL_INTERR, VNCLOG("unable to load User32 DLL (%u)\n"), GetLastError()); return FALSE; } // Get the LockWorkstation function typedef BOOL (*LWProc) (); LWProc lockworkstation = (LWProc)GetProcAddress(user32, "LockWorkStation"); if (!lockworkstation) { vnclog.Print(LL_INTERR, VNCLOG("unable to locate LockWorkStation - requires Windows 2000 or above (%u)\n"), GetLastError()); FreeLibrary(user32); return FALSE; } // Attempt to lock the workstation BOOL result = (lockworkstation)(); if (!result) { vnclog.Print(LL_INTERR, VNCLOG("call to LockWorkstation failed\n")); FreeLibrary(user32); return FALSE; } FreeLibrary(user32); return result; } // Static routine to show the Properties dialog for a currently-running // copy of WinVNC, (usually a servicified version.) BOOL vncService::ShowProperties() { // Post to the WinVNC menu window if (!PostToWinVNC(MENU_PROPERTIES_SHOW, 0, 0)) { MessageBox(NULL, sz_ID_NO_EXIST_INST, szAppName, MB_ICONEXCLAMATION | MB_OK); return FALSE; } return TRUE; } // Static routine to show the Default Properties dialog for a currently-running // copy of WinVNC, (usually a servicified version.) BOOL vncService::ShowDefaultProperties() { // Post to the WinVNC menu window if (!PostToWinVNC(MENU_DEFAULT_PROPERTIES_SHOW, 0, 0)) { MessageBox(NULL, sz_ID_NO_EXIST_INST, szAppName, MB_ICONEXCLAMATION | MB_OK); return FALSE; } return TRUE; } // Static routine to show the About dialog for a currently-running // copy of WinVNC, (usually a servicified version.) BOOL vncService::ShowAboutBox() { // Post to the WinVNC menu window if (!PostToWinVNC(MENU_ABOUTBOX_SHOW, 0, 0)) { MessageBox(NULL, sz_ID_NO_EXIST_INST, szAppName, MB_ICONEXCLAMATION | MB_OK); return FALSE; } return TRUE; } // Static routine to tell a locally-running instance of the server // to connect out to a new client BOOL vncService::PostAddNewClient(unsigned long ipaddress, unsigned short port) { // Post to the WinVNC menu window if (!PostToWinVNC(MENU_ADD_CLIENT_MSG, (WPARAM)port, (LPARAM)ipaddress)) { MessageBox(NULL, sz_ID_NO_EXIST_INST, szAppName, MB_ICONEXCLAMATION | MB_OK); return FALSE; } return TRUE; } // Static routine to tell a locally-running instance of the server // about a reconnect BOOL vncService::PostAddAutoConnectClient( const char* pszId ) { ATOM aId = NULL; if ( pszId ) { aId = GlobalAddAtom( pszId ); // delete pszId; } return ( PostToWinVNC(MENU_AUTO_RECONNECT_MSG, NULL, (LPARAM)aId) ); } // SERVICE-MODE ROUTINES // Service-mode defines: // Executable name #define VNCAPPNAME "winvnc" // Internal service name #define VNCSERVICENAME "winvnc" // Displayed service name #define VNCSERVICEDISPLAYNAME "VNC Server" // List of other required services ("dependency 1\0dependency 2\0\0") // *** These need filling in properly #define VNCDEPENDENCIES "" // Internal service state SERVICE_STATUS g_srvstatus; // current status of the service SERVICE_STATUS_HANDLE g_hstatus; DWORD g_error = 0; DWORD g_servicethread = NULL; char* g_errortext[256]; // Forward defines of internal service functions void WINAPI ServiceMain(DWORD argc, char **argv); void ServiceWorkThread(void *arg); void ServiceStop(); void WINAPI ServiceCtrl(DWORD ctrlcode); bool WINAPI CtrlHandler (DWORD ctrltype); BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint); // ROUTINE TO QUERY WHETHER THIS PROCESS IS RUNNING AS A SERVICE OR NOT BOOL g_servicemode = FALSE; BOOL vncService::RunningAsService() { return g_servicemode; } BOOL vncService::KillRunningCopy() { // Locate the hidden WinVNC menu window HWND hservwnd; while ((hservwnd = FindWindow(MENU_CLASS_NAME, NULL)) != NULL) { // Post the message to WinVNC PostMessage(hservwnd, WM_CLOSE, 0, 0); omni_thread::sleep(1); } return TRUE; } // ROUTINE TO POST THE HANDLE OF THE CURRENT USER TO THE RUNNING WINVNC, IN ORDER // THAT IT CAN LOAD THE APPROPRIATE SETTINGS. THIS IS USED ONLY BY THE SVCHELPER // OPTION, WHEN RUNNING UNDER NT BOOL vncService::PostUserHelperMessage() { // - Check the platform type if (!IsWinNT()) return TRUE; // - Get the current process ID DWORD processId = GetCurrentProcessId(); // - Post it to the existing WinVNC // RealVNC 336 change // if (!PostToWinVNC(MENU_SERVICEHELPER_MSG, 0, (LPARAM)processId)) // return FALSE; int retries = 6; while (!PostToWinVNC(MENU_SERVICEHELPER_MSG, 0, (LPARAM)processId) && retries--) omni_thread::sleep(10); // - Wait until it's been used omni_thread::sleep(5); return retries; } // ROUTINE TO PROCESS AN INCOMING INSTANCE OF THE ABOVE MESSAGE BOOL vncService::ProcessUserHelperMessage(WPARAM wParam, LPARAM lParam) { // - Check the platform type if (!IsWinNT() || !vncService::RunningAsService()) return TRUE; // - Close the HKEY_CURRENT_USER key, to force NT to reload it for the new user // NB: Note that this is _really_ dodgy if ANY other thread is accessing the key! if (RegCloseKey(HKEY_CURRENT_USER) != ERROR_SUCCESS) { vnclog.Print(LL_INTERR, VNCLOG("failed to close current registry hive\n")); return FALSE; } // - Revert to our own identity RevertToSelf(); g_impersonating_user = FALSE; // Modif Jeremy C. if (lParam!=0) // Normal case { // if lParam is zero then we are just re-setting the impersonation *((PHANDLE)wParam)=NULL; // - Open the specified process HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)lParam); if (processHandle == NULL) { vnclog.Print(LL_INTERR, VNCLOG("failed to open specified process(%d)\n"), GetLastError()); return FALSE; } // - Get the token for the given process if (!OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, (PHANDLE)wParam)) { vnclog.Print(LL_INTERR, VNCLOG("failed to get user token(%d)\n"), GetLastError()); CloseHandle(processHandle); return FALSE; } CloseHandle(processHandle); } // Modif Jeremy C. - Duplicate and store the security token to use later HANDLE userToken = NULL; if (!DuplicateToken(*((PHANDLE)wParam), SecurityImpersonation, &userToken)) { vnclog.Print(LL_INTERR, VNCLOG("failed to duplicate user token(%d)\n"), GetLastError()); return FALSE; } // - Set this thread to impersonate them if (!ImpersonateLoggedOnUser(userToken)) { vnclog.Print(LL_INTERR, VNCLOG("failed to impersonate user(%d)\n"), GetLastError()); CloseHandle(userToken); return FALSE; } CloseHandle(userToken); g_impersonating_user = TRUE; vnclog.Print(LL_INTINFO, VNCLOG("impersonating logged on user\n")); return TRUE; } // SERVICE MAIN ROUTINE int vncService::WinVNCServiceMain() { typedef DWORD (WINAPI * RegisterServiceProc)(DWORD, DWORD); const ULONG RSP_SIMPLE_SERVICE = 0x00000001; const ULONG RSP_UNREGISTER_SERVICE = 0x00000000; g_servicemode = TRUE; // How to run as a service depends upon the OS being used switch (g_platform_id) { // Windows 95/98 case VER_PLATFORM_WIN32_WINDOWS: { // Obtain a handle to the kernel library HINSTANCE kerneldll = LoadLibrary("KERNEL32.DLL"); if (kerneldll == NULL) break; // And find the RegisterServiceProcess function RegisterServiceProc RegisterService; RegisterService = (RegisterServiceProc) GetProcAddress(kerneldll, "RegisterServiceProcess"); if (RegisterService == NULL) break; // Register this process with the OS as a service! RegisterService(NULL, RSP_SIMPLE_SERVICE); // Run the service itself WinVNCAppMain(); // Then remove the service from the system service table RegisterService(NULL, RSP_UNREGISTER_SERVICE); // Free the kernel library FreeLibrary(kerneldll); // *** If we don't kill the process directly here, then // for some reason, WinVNC crashes... // *** Is this now fixed (with the stdcall patch above)? //ExitProcess(0); } break; // Windows NT case VER_PLATFORM_WIN32_NT: { // Create a service entry table SERVICE_TABLE_ENTRY dispatchTable[] = { {VNCSERVICENAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain}, {NULL, NULL} }; // Call the service control dispatcher with our entry table if (!StartServiceCtrlDispatcher(dispatchTable)) LogErrorMsg("StartServiceCtrlDispatcher failed."); } break; }; return 0; } // SERVICE MAIN ROUTINE void WINAPI ServiceMain(DWORD argc, char**argv) { // Register the service control handler g_hstatus = RegisterServiceCtrlHandler(VNCSERVICENAME, ServiceCtrl); if (g_hstatus == 0) return; // Set up some standard service state values g_srvstatus.dwServiceType = SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS; g_srvstatus.dwServiceSpecificExitCode = 0; // Give this status to the SCM if (!ReportStatus( SERVICE_START_PENDING, // Service state NO_ERROR, // Exit code type 15000)) // Hint as to how long WinVNC should have hung before you assume error { ReportStatus( SERVICE_STOPPED, g_error, 0); return; } // Now start the service for real omni_thread *workthread = omni_thread::create(ServiceWorkThread); return; } //////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// // SERVICE START ROUTINE - thread that calls WinVNCAppMain void ServiceWorkThread(void *arg) { // Save the current thread identifier g_servicethread = GetCurrentThreadId(); // report the status to the service control manager. // if (!ReportStatus( SERVICE_RUNNING, // service state NO_ERROR, // exit code 0)) // wait hint return; // RUN! WinVNCAppMain(); // Mark that we're no longer running g_servicethread = NULL; // Tell the service manager that we've stopped. ReportStatus( SERVICE_STOPPED, g_error, 0); } // SERVICE STOP ROUTINE - post a quit message to the relevant thread void ServiceStop() { // Post a quit message to the main service thread if (g_servicethread != NULL) { vnclog.Print(LL_INTINFO, VNCLOG("quitting from ServiceStop\n")); PostThreadMessage(g_servicethread, WM_QUIT, 0, 0); } } // SERVICE INSTALL ROUTINE int vncService::ReinstallService() { RemoveService(1); Sleep(1000); InstallService(1); return 0; } int vncService::InstallService(BOOL silent) { const int pathlength = 2048; char path[pathlength]; char servicecmd[pathlength]; // Get the filename of this executable if (GetModuleFileName(NULL, path, pathlength-(strlen(winvncRunService)+2)) == 0) { if (!silent) { MessageBox(NULL, sz_ID_UNABLE_INST, szAppName, MB_ICONEXCLAMATION | MB_OK); } return 0; } // Append the service-start flag to the end of the path: if (strlen(path) + 4 + strlen(winvncRunService) < pathlength) sprintf(servicecmd, "\"%s\" %s", path, winvncRunService); else return 0; // How to add the WinVNC service depends upon the OS switch (g_platform_id) { // Windows 95/98 case VER_PLATFORM_WIN32_WINDOWS: { // Locate the RunService registry entry HKEY runservices; if (RegCreateKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", &runservices) != ERROR_SUCCESS) { if (!silent) { MessageBox(NULL, sz_ID_SCM_NOT_HERE, szAppName, MB_ICONEXCLAMATION | MB_OK); } break; } // Attempt to add a WinVNC key if (RegSetValueEx(runservices, szAppName, 0, REG_SZ, (unsigned char *)servicecmd, strlen(servicecmd)+1) != ERROR_SUCCESS) { RegCloseKey(runservices); if (!silent) { MessageBox(NULL, sz_ID_SERV_NOT_REG, szAppName, MB_ICONEXCLAMATION | MB_OK); } break; } RegCloseKey(runservices); // We have successfully installed the service! if (!silent)vncTimedMsgBox::Do( sz_ID_SERV_SUCCESS_INST, szAppName, MB_ICONINFORMATION | MB_OK); // Run the service... STARTUPINFO si; si.cb = sizeof(si); si.cbReserved2 = 0; si.lpReserved = NULL; si.lpReserved2 = NULL; si.dwFlags = 0; si.lpTitle = NULL; PROCESS_INFORMATION pi; if (!CreateProcess( NULL, servicecmd, // Program name & path NULL, NULL, // Security attributes FALSE, // Inherit handles? NORMAL_PRIORITY_CLASS, // Extra startup flags NULL, // Environment table NULL, // Current directory &si, &pi )) { if(!silent) { MessageBox(NULL, sz_ID_SERV_FAIL_ST, szAppName, MB_IConstop | MB_OK); } break; } } break; // Windows NT case VER_PLATFORM_WIN32_NT: { SC_HANDLE hservice; SC_HANDLE hsrvmanager; // Open the default, local Service Control Manager database hsrvmanager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hsrvmanager == NULL) { if (!silent) { MessageBox(NULL, sz_ID_SERV_CT_MISS, szAppName, MB_ICONEXCLAMATION | MB_OK); } break; } // Create an entry for the WinVNC service hservice = CreateService( hsrvmanager, // SCManager database VNCSERVICENAME, // name of service VNCSERVICEDISPLAYNAME, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type servicecmd, // service's binary NULL, // no load ordering group NULL, // no tag identifier VNCDEPENDENCIES, // dependencies NULL, // LocalSystem account NULL); // no password if (hservice == NULL) { DWORD error = GetLastError(); if (!silent) { if (error == ERROR_SERVICE_EXISTS) { MessageBox(NULL, sz_ID_SERV_OLD_REG, szAppName, MB_ICONEXCLAMATION | MB_OK); } else { MessageBox(NULL, sz_ID_SERV_NOT_REG, szAppName, MB_ICONEXCLAMATION | MB_OK); } } CloseServiceHandle(hsrvmanager); break; } CloseServiceHandle(hsrvmanager); CloseServiceHandle(hservice); // Now install the servicehelper registry setting... // Locate the RunService registry entry HKEY runapps; if (RegCreateKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", &runapps) != ERROR_SUCCESS) { if (!silent) { MessageBox(NULL, sz_ID_SERVHELP_UNAB, szAppName, MB_ICONEXCLAMATION | MB_OK); } } else { char servicehelpercmd[pathlength]; // Append the service-helper-start flag to the end of the path: if (strlen(path) + 4 + strlen(winvncRunServiceHelper) < pathlength) sprintf(servicehelpercmd, "\"%s\" %s", path, winvncRunServiceHelper); else return 0; // Add the VNCserviceHelper entry if (RegSetValueEx(runapps, szAppName, 0, REG_SZ, (unsigned char *)servicehelpercmd, strlen(servicehelpercmd)+1) != ERROR_SUCCESS) { if (!silent) { MessageBox(NULL, sz_ID_SERVHELP_UNAB, szAppName, MB_ICONEXCLAMATION | MB_OK); } } RegCloseKey(runapps); } // Everything went fine if (!silent)vncTimedMsgBox::Do( sz_ID_SERV_SUCCESS_REG, szAppName, MB_ICONINFORMATION | MB_OK); } break; }; return 0; } // SERVICE REMOVE ROUTINE int vncService::RemoveService(BOOL silent) { // How to remove the WinVNC service depends upon the OS switch (g_platform_id) { // Windows 95/98 case VER_PLATFORM_WIN32_WINDOWS: { // Locate the RunService registry entry HKEY runservices; if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", &runservices) != ERROR_SUCCESS) { if (!silent) { MessageBox(NULL, sz_ID_SERV_CT_UNREG, szAppName, MB_ICONEXCLAMATION | MB_OK); } } else { // Attempt to delete the WinVNC key if (RegDeleteValue(runservices, szAppName) != ERROR_SUCCESS) { RegCloseKey(runservices); if (!silent) { MessageBox(NULL, sz_ID_SERV_NOT_UNRG, szAppName, MB_ICONEXCLAMATION | MB_OK); } } RegCloseKey(runservices); break; } // Try to kill any running copy of WinVNC if (!KillRunningCopy()) { if (!silent) { MessageBox(NULL, sz_ID_SERV_NCONTACT, szAppName, MB_ICONEXCLAMATION | MB_OK); } break; } // We have successfully removed the service! if (!silent) vncTimedMsgBox::Do(sz_ID_SERV_SUCCESS_UNREG, szAppName, MB_ICONINFORMATION | MB_OK); } break; // Windows NT case VER_PLATFORM_WIN32_NT: { SC_HANDLE hservice; SC_HANDLE hsrvmanager; // Attempt to remove the service-helper hook HKEY runapps; if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", &runapps) == ERROR_SUCCESS) { // Attempt to delete the WinVNC key if (RegDeleteValue(runapps, szAppName) != ERROR_SUCCESS) { if (!silent) { MessageBox(NULL, sz_ID_SERVHELP_NREM, szAppName, MB_ICONEXCLAMATION | MB_OK); } } RegCloseKey(runapps); } // Open the SCM hsrvmanager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if (hsrvmanager) { hservice = OpenService(hsrvmanager, VNCSERVICENAME, SERVICE_ALL_ACCESS); if (hservice != NULL) { SERVICE_STATUS status; // Try to stop the WinVNC service if (ControlService(hservice, SERVICE_CONTROL_STOP, &status)) { while(QueryServiceStatus(hservice, &status)) { if (status.dwCurrentState == SERVICE_STOP_PENDING) Sleep(1000); else break; } if (status.dwCurrentState != SERVICE_STOPPED) { if (!silent) { MessageBox(NULL, sz_ID_SERV_NOT_STOP, szAppName, MB_ICONEXCLAMATION | MB_OK); } } } // Now remove the service from the SCM if(DeleteService(hservice)) { if (!silent) vncTimedMsgBox::Do(sz_ID_SERV_SUCCESS_UNREG, szAppName, MB_ICONINFORMATION | MB_OK); } else { DWORD error = GetLastError(); if (error == ERROR_SERVICE_MARKED_FOR_DELETE) { if (!silent) MessageBox(NULL, sz_ID_SERV_MK_UNREG, szAppName, MB_ICONEXCLAMATION | MB_OK); } else { if (!silent) MessageBox(NULL, sz_ID_SERV_NOT_UNRG, szAppName, MB_ICONEXCLAMATION | MB_OK); } } CloseServiceHandle(hservice); } else if (!silent) MessageBox(NULL, sz_ID_SERV_NT_FOUND, szAppName, MB_ICONEXCLAMATION | MB_OK); CloseServiceHandle(hsrvmanager); } else if (!silent) MessageBox(NULL, sz_ID_SERV_CT_UNREG, szAppName, MB_ICONEXCLAMATION | MB_OK); } break; }; return 0; } // USEFUL SERVICE SUPPORT ROUTINES // Service control routine void WINAPI ServiceCtrl(DWORD ctrlcode) { // What control code have we been sent? // Beep(1000,10); // vnclog.Print(LL_INTINFO, VNCLOG("ctrlcode %d \n"),ctrlcode); switch(ctrlcode) { case SERVICE_CONTROL_SHUTDOWN: g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING; // ServiceStop(); serviceshutdown=true; vnclog.Print(LL_INTERR, VNCLOG("SERVICE_CONTROL_SHUTDOWN\n")); break; case SERVICE_CONTROL_STOP: // STOP : The service must stop g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING; vnclog.Print(LL_INTERR, VNCLOG("SERVICE_CONTROL_STOP\n")); ServiceStop(); break; case SERVICE_CONTROL_INTERROGATE: // QUERY : Service control manager just wants to know our state break; default: // Control code not recognised break; } // Tell the control manager what we're up to. ReportStatus(g_srvstatus.dwCurrentState, NO_ERROR, 0); } // Service manager status reporting BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint) { static DWORD checkpoint = 1; BOOL result = TRUE; // If we're in the start state then we don't want the control manager // sending us control messages because they'll confuse us. if (state == SERVICE_START_PENDING) g_srvstatus.dwControlsAccepted = 0; else g_srvstatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN; // Save the new status we've been given g_srvstatus.dwCurrentState = state; g_srvstatus.dwWin32ExitCode = exitcode; g_srvstatus.dwWaitHint = waithint; // Update the checkpoint variable to let the SCM know that we // haven't died if requests take a long time if ((state == SERVICE_RUNNING) || (state == SERVICE_STOPPED)) g_srvstatus.dwCheckPoint = 0; else g_srvstatus.dwCheckPoint = checkpoint++; // Tell the SCM our new status if (!(result = SetServiceStatus(g_hstatus, &g_srvstatus))) LogErrorMsg("SetServiceStatus failed"); return result; } // Error reporting void LogErrorMsg(char *message) { char msgbuff[256]; HANDLE heventsrc; char * strings[2]; // Save the error code g_error = GetLastError(); // Use event logging to log the error heventsrc = RegisterEventSource(NULL, VNCSERVICENAME); _snprintf(msgbuff, 256, "%s error: %d", VNCSERVICENAME, g_error); strings[0] = msgbuff; strings[1] = message; if (heventsrc != NULL) { MessageBeep(MB_OK); ReportEvent( heventsrc, // handle of event source EVENTLOG_ERROR_TYPE, // event type 0, // event category 0, // event ID NULL, // current user's SID 2, // strings in 'strings' 0, // no bytes of raw data (const char **)strings, // array of error strings NULL); // no raw data DeregisterEventSource(heventsrc); } } Link to comment Share on other sites More sharing options...
weaponx Posted December 16, 2007 Share Posted December 16, 2007 There is no reason to post that entire piece of code here. A link would suffice. Also considering the command has to be run remotely it would only be useful if you were already connected remotely using vnc. Link to comment Share on other sites More sharing options...
icadea Posted December 17, 2007 Share Posted December 17, 2007 ok. acknowledged. Link to comment Share on other sites More sharing options...
shiner Posted February 13, 2008 Share Posted February 13, 2008 (edited) Hey I know this is an old thread, but I stumbled on it while looking for some help on another project but there IS a way to send out CTRL ALT DEL to remote computers to unlock them. Using an executable from softtreetech.com called logon.exe found here (http://www.softtreetech.com/24x7/archive/51.htm) it will emulate a logon on a local computer using Logon <-u user> -p password (command line parameters) from say a scheduled batch file. Now if you add the functionality of PSEXEC from sysinternals/micorsoft (http://technet.microsoft.com/en-ca/sysinternals/bb897553.aspx) , you can do something like this:psexec.exe \\computername -i -s -c -f logon.exe -u <username> -p <password> You may need to use admin account when running psexec in interactive mode so try:psexec.exe \\computername -u <username> -p <password> -i -s -c -f logon.exe -u <username> -p <password> *where -u username and -p password after computername has the admin rights to copy and execute logon.exe on the remote computer. (This works awesome, especially when you have a group of computers to logon to or unlock after locking. I've automated a group of them where I can wake-up, logon, lock, unlock, logoff, reboot, shutdown and my life has been made alot easier. I used psexec and the rest of the pstools in the past but ran into the issue of remotely logging onto a remote workstation WITHOUT using VNC or remote desktop tools. THis completely automates it so no taking over a full desktop to login.I found this tool through the maker of open-source RC-LOGON which is a GUI and can do most things listed with command lines in the background, I just wanted the ability to lock and unlock workstations, and script it in a multithreaded manner to speed things up a bit using BeyondExec instead. RC LOGON can be found here: http://sourceforge.net/projects/rclogon/Hope this may help someone. Edited February 13, 2008 by shiner Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now