home *** CD-ROM | disk | FTP | other *** search
/ PC World 2004 November / PCWorld_2004-11_cd.bin / software / temacd / poweroff / pwroff30.exe / src / action.c next >
C/C++ Source or Header  |  2003-08-10  |  14KB  |  561 lines

  1. #include "poweroff.h"
  2. #include <winnetwk.h>
  3.  
  4. void RunProgram(HWND hWnd,PowerSettings *ps)
  5. {
  6.     PROCESS_INFORMATION p;
  7.   STARTUPINFO si;
  8.   DWORD exit_code;
  9.   char *directory=NULL;
  10.  
  11.   Log("RunProgram start");
  12.   if (ps->program.directory[0]!='\0')
  13.     directory=ps->program.directory;
  14.  
  15.     si.cb=sizeof(STARTUPINFO);
  16.     si.lpReserved=NULL;
  17.     si.lpDesktop=NULL;
  18.     si.lpTitle=NULL;
  19.     si.dwFlags=0;
  20.     si.cbReserved2=0;
  21.     si.lpReserved2=NULL;
  22.   Log("Running program %s in directory %s",ps->program.program,ps->program.directory);
  23.   if (CreateProcess(NULL,ps->program.program,NULL,NULL,FALSE,0,NULL,directory,&si,&p)==0)
  24.   {
  25.     DisplayLastError(ps,hWnd);
  26.     return;
  27.   }
  28.   Log("Waiting for program to finish");
  29.     do
  30.     {
  31.         GetExitCodeProcess(p.hProcess,&exit_code);
  32.       Sleep(100);
  33.   } while (exit_code==STILL_ACTIVE);
  34.   Log("RunProgram end");
  35. }
  36.  
  37. char *GetModeStr(PowerSettings *ps)
  38. {
  39.   static char str[100];
  40.  
  41.   Log("GetModeStr start");
  42.   str[0]='\0';
  43.   if (ps->options.force)
  44.     strcpy(str,"FORCE ");
  45.   switch (ps->action)
  46.     {
  47.       case LOGOFF:
  48.       strcat(str,"LOGOFF");
  49.       break;
  50.       case REBOOT:
  51.       strcat(str,"REBOOT");
  52.       break;
  53.       case SHUTDOWN:
  54.       strcat(str,"SHUTDOWN");
  55.       break;
  56.       case POWEROFF:
  57.       strcat(str,"POWEROFF");
  58.       break;
  59.       case STANDBY:
  60.       strcat(str,"STANDBY");
  61.       break;
  62.       case HIBERNATE:
  63.       strcat(str,"HIBERNATE");
  64.       break;
  65.       case LOCK:
  66.       strcat(str,"LOCK");
  67.       break;
  68.       case WAKE_ON_LAN:
  69.       strcat(str,"WAKE_ON_LAN");
  70.       break;
  71.       case MONITOR_OFF:
  72.       strcat(str,"MONITOR_OFF");
  73.       break;
  74.       case MONITOR_ON:
  75.       strcat(str,"MONITOR_ON");
  76.       break;
  77.       case NO_ACTION:
  78.       strcat(str,"NO_ACTION");
  79.       break;
  80.         default:
  81.       strcat(str,"UNKNOWN");
  82.     }
  83.   Log("GetModeStr end, str=%s",str);
  84.   return str;
  85. }
  86.  
  87. int AquirePrivileges(HWND hWnd,PowerSettings *ps)
  88. {
  89.   HANDLE current_thread,token;
  90.   TOKEN_PRIVILEGES privs;
  91.   LUID luid;
  92.  
  93.   Log("AquirePrivileges start");
  94.   current_thread=GetCurrentProcess();
  95.   if (!OpenProcessToken(current_thread,TOKEN_ADJUST_PRIVILEGES,&token))
  96.   {
  97.     DisplayLastError(ps,hWnd);
  98.     return -1;
  99.   }
  100.   if (!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid))
  101.   {
  102.     DisplayLastError(ps,hWnd);
  103.     return -1;
  104.   }
  105.   privs.PrivilegeCount=1;
  106.   privs.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
  107.   privs.Privileges[0].Luid=luid;
  108.   if (!AdjustTokenPrivileges(token,FALSE,&privs,0,NULL,NULL))
  109.   {
  110.     DisplayLastError(ps,hWnd);
  111.     return -1;
  112.   }
  113.   Log("AquirePrivileges end");
  114.   return 0;
  115. }
  116.  
  117. BOOL CALLBACK CheckProcessIsRunning(DWORD dw,WORD w16,LPCSTR lpstr,LPARAM lParam)
  118. {
  119.   if (!_stricmp(lpstr,(char*)lParam))
  120.     return FALSE;
  121.   return TRUE;
  122. }
  123.  
  124.  
  125. int UserIsLoggedOn(PowerSettings *ps)
  126. {
  127.   char shell[MAX_PATH];
  128.  
  129.   Log("UserIsLoggedOn start");
  130.   if (!ReadRegistryString(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon","Shell",shell,MAX_PATH))
  131.   {
  132.     Log("Cannot read HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell");
  133.     Log("UserIsLoggedOn end, assume user is logged on");
  134.     return 1;
  135.   }
  136.   Log("Check for program %s",shell);
  137.   if (!EnumProcs(CheckProcessIsRunning,(LPARAM)shell))
  138.   {
  139.     Log("UserIsLoggedOn end, user is logged on");
  140.     return 1;
  141.   }
  142.   Log("UserIsLoggedOn end, user is NOT logged on");
  143.   return 0;
  144. }
  145.  
  146. int DoExitWindowsEx(HWND hWnd,PowerSettings *ps)
  147. {
  148.   UINT mode;
  149.  
  150.   Log("DoExitWindowsEx start, action=%d, force=%d",ps->action,ps->options.force);
  151.   switch (ps->action)
  152.   {
  153.     case LOGOFF:
  154.       if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_NT)
  155.       {
  156.         if (!UserIsLoggedOn(ps))
  157.         {
  158.           WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Wanted to LOGOFF the user, but nobody was logged on");
  159.           Log("DoExitWindowsEx end");
  160.           return 0;
  161.         }
  162.       }
  163.       mode=EWX_LOGOFF;
  164.       break;
  165.     case REBOOT:
  166.       mode=EWX_REBOOT;
  167.       break;
  168.     case SHUTDOWN:
  169.       mode=EWX_SHUTDOWN;
  170.       break;
  171.     case POWEROFF:
  172.       if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  173.         mode=EWX_SHUTDOWN;
  174.       else
  175.         mode=EWX_POWEROFF;
  176.       break;
  177.   }
  178.   if (ps->options.force)
  179.     mode|=EWX_FORCE;
  180.  
  181.   Log("Warning=%d",ps->options.warning);
  182.   if (ps->options.warning)
  183.   {
  184.     if (!ShowWarningMessage(hWnd,ps))
  185.       return 1;
  186.   }
  187.  
  188.   Log("Run_Program=%d",ps->options.run_program);
  189.   if (ps->options.run_program)
  190.   {
  191.     RunProgram(hWnd,ps);
  192.   }
  193.   WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Initiating %s",GetModeStr(ps));
  194.  
  195.   if (ps->simulate)
  196.     Error(ps,hWnd,"ExitWindowsEx");
  197.   else if (!ExitWindowsEx(mode,0))
  198.   {
  199.     DisplayLastError(ps,hWnd);
  200.     return -1;
  201.   }
  202.   else
  203.     WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"ExitWindowsEx executed succesfully!");
  204.   Log("DoExitWindowsEx end");
  205.   return 0;
  206. }
  207.  
  208. int DoSetSystemPowerState(HWND hWnd,PowerSettings *ps)
  209. {
  210.   Log("DoSetSystemPowerState start");
  211.   Log("Warning=%d",ps->options.warning);
  212.   if (ps->options.warning)
  213.   {
  214.     if (!ShowWarningMessage(hWnd,ps))
  215.       return 1;
  216.   }
  217.  
  218.   Log("Run_Program=%d",ps->options.run_program);
  219.   if (ps->options.run_program)
  220.   {
  221.     RunProgram(hWnd,ps);
  222.   }
  223.   WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Initiating %s",GetModeStr(ps));
  224.  
  225.   if (MySetSuspendState==NULL)
  226.   {
  227.     if (ps->simulate)
  228.       Error(ps,hWnd,"SetSystemPowerState");
  229.     else if (!SetSystemPowerState((ps->action==STANDBY)?TRUE:FALSE,ps->options.force?TRUE:FALSE))
  230.     {
  231.       DisplayLastError(ps,hWnd);
  232.       return -1;
  233.     }
  234.     else
  235.       WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"SetSystemPowerState executed succesfully!");
  236.   }
  237.   else
  238.   {
  239.     if (ps->simulate)
  240.       Error(ps,hWnd,"SetSuspendState");
  241.     else if (!MySetSuspendState((ps->action==STANDBY)?FALSE:TRUE,(ps->options.force)?TRUE:FALSE,FALSE))
  242.     {
  243.       /* I've read somewhere that win98 doesn't support this, so try the old method too */
  244.       if (!SetSystemPowerState((ps->action==STANDBY)?TRUE:FALSE,ps->options.force?TRUE:FALSE))
  245.       {
  246.         DisplayLastError(ps,hWnd);
  247.         return -1;
  248.       }
  249.       else
  250.         WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"SetSystemPowerState executed succesfully!");
  251.     }
  252.     else
  253.       WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"SetSuspendState executed succesfully!");
  254.   }
  255.   return 0;
  256. }
  257.  
  258. int DoLockWorkstation(HWND hWnd,PowerSettings *ps)
  259. {
  260.   HINSTANCE lInst;
  261.   FARPROC MyLockWorkstation;
  262.  
  263.   Log("DoLockWorkstation start");
  264.   Log("Warning=%d",ps->options.warning);
  265.   if (ps->options.warning)
  266.   {
  267.     if (!ShowWarningMessage(hWnd,ps))
  268.       return 1;
  269.   }
  270.  
  271.   Log("Run_Program=%d",ps->options.run_program);
  272.   if (ps->options.run_program)
  273.   {
  274.     RunProgram(hWnd,ps);
  275.   }
  276.   if ((lInst=LoadLibrary("user32.dll"))==NULL)
  277.   {
  278.     DisplayLastError(ps,hWnd);
  279.     return -1;
  280.   }
  281.   MyLockWorkstation=GetProcAddress(lInst,"LockWorkStation");
  282.   if (MyLockWorkstation==NULL)
  283.   {
  284.     DisplayLastError(ps,hWnd);
  285.     return -1;
  286.   }
  287.   WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Initiating %s",GetModeStr(ps));
  288.   if (ps->simulate)
  289.     Error(ps,hWnd,"MyLockWorkstation");
  290.   else if (!MyLockWorkstation())
  291.   {
  292.     DisplayLastError(ps,hWnd);
  293.     return -1;
  294.   }
  295.   else
  296.     WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"LockWorkStation executed succesfully!");
  297.   FreeLibrary(lInst);
  298.   Log("DoLockWorkstation end");
  299.   return 0;
  300. }
  301.  
  302. int DoInitiateSystemShutdown(HWND hWnd,PowerSettings *ps)
  303. {
  304.   Log("DoInitiateSystemShutdown start");
  305.   WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Initiating %s on remote computer %s",GetModeStr(ps),ps->remote.computer_name);
  306.   if (ps->simulate)
  307.     Error(ps,hWnd,"InitiateSystemShutdown");
  308.   else
  309.   {
  310.     NETRESOURCE net;
  311.     char str[MAX_PATH];
  312.  
  313.     Log("current_credentials=%d",ps->remote.current_credentials);
  314.     if (!ps->remote.current_credentials)
  315.     {
  316.       if (ps->remote.computer_name[0]!='\\')
  317.         sprintf(str,"\\\\%s\\admin$",ps->remote.computer_name);
  318.       else
  319.         sprintf(str,"%s\\admin$",ps->remote.computer_name);
  320.  
  321.       net.dwScope=RESOURCE_GLOBALNET;
  322.       net.dwType=RESOURCETYPE_ANY;
  323.       net.dwDisplayType=RESOURCEDISPLAYTYPE_GENERIC;
  324.       net.dwUsage=RESOURCEUSAGE_CONNECTABLE;
  325.       net.lpLocalName=NULL;
  326.       net.lpRemoteName=str;
  327.       net.lpComment=NULL;
  328.       net.lpProvider=NULL;
  329.       if (WNetAddConnection2(&net,ps->remote.password,ps->remote.username,0)!=NO_ERROR)
  330.       {
  331.         DisplayLastError(ps,hWnd);
  332.         return -1;
  333.       }
  334.     }
  335.     Log("InitiateSystemShutdown");
  336.     if (!InitiateSystemShutdown(ps->remote.computer_name,ps->warning.message,ps->warning.seconds,ps->options.force,(ps->action==REBOOT)?1:0))
  337.     {
  338.       DisplayLastError(ps,hWnd);
  339.       return -1;
  340.     }
  341.     if (!ps->remote.current_credentials)
  342.     {
  343.       WNetCancelConnection2(str,0,FALSE);
  344.     }
  345.   }
  346.   WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Remote computer has accepted the request");
  347.   if (ps->interactive)
  348.   {
  349.     DisplayInformation(ps,hWnd,"Remote computer has accepted the request");
  350.   }
  351.   Log("DoInitiateSystemShutdown end");
  352.   return 0;
  353. }
  354.  
  355. int DoTurnOffMonitor(HWND hWnd,PowerSettings *ps)
  356. {
  357.   Log("DoTurnOffMonitor start");
  358.   Log("Warning=%d",ps->options.warning);
  359.   if (ps->options.warning)
  360.   {
  361.     if (!ShowWarningMessage(hWnd,ps))
  362.       return 1;
  363.   }
  364.  
  365.   Log("Run_Program=%d",ps->options.run_program);
  366.   if (ps->options.run_program)
  367.   {
  368.     RunProgram(hWnd,ps);
  369.   }
  370.   if (!ps->interactive)
  371.     Sleep(500);
  372.   WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Initiating %s",GetModeStr(ps));
  373.   if (ps->simulate)
  374.     Error(ps,hWnd,"DoTurnOffMonitor");
  375.   else
  376.   {
  377.     if (ps->action==MONITOR_OFF)
  378.       SendMessage(hWnd,WM_SYSCOMMAND,SC_MONITORPOWER,2);
  379.     else
  380.       SendMessage(hWnd,WM_SYSCOMMAND,SC_MONITORPOWER,-1);
  381.   }
  382.   Log("DoTurnOffMonitor end");
  383.   return 0;
  384. }
  385.  
  386. int DoNoAction(HWND hWnd,PowerSettings *ps)
  387. {
  388.   Log("DoNoAction start");
  389.   Log("Warning=%d",ps->options.warning);
  390.   if (ps->options.warning)
  391.   {
  392.     if (!ShowWarningMessage(hWnd,ps))
  393.       return 1;
  394.   }
  395.  
  396.   Log("Run_Program=%d",ps->options.run_program);
  397.   if (ps->options.run_program)
  398.   {
  399.     RunProgram(hWnd,ps);
  400.   }
  401.   WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Initiating %s",GetModeStr(ps));
  402.   Log("DoNoAction end");
  403.   return 0;
  404. }
  405.  
  406. int DoWOL(HWND hWnd,PowerSettings *ps)
  407. {
  408.   Log("DoWOL start");
  409.   WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Waking up remote computer %s",ps->remote.computer_name);
  410.   if (ps->simulate)
  411.     Error(ps,hWnd,"WakeOnLan");
  412.   else if (WakeOnLan(ps,ps->remote.ip_address,ps->remote.subnet_mask,ps->remote.mac_address))
  413.   {
  414.     Error(ps,hWnd,"WakeOnLAN failed");
  415.     return -1;
  416.   }
  417.   WriteEvent(ps,EVENTLOG_INFORMATION_TYPE,"Wake-On-LAN packet has been sent");
  418.   if (ps->interactive)
  419.   {
  420.     DisplayInformation(ps,hWnd,"Wake-On-LAN packet has been sent");
  421.   }
  422.   Log("DoWOL end");
  423.   return 0;
  424. }
  425.  
  426. int PowerOff(HWND hWnd,PowerSettings *ps)
  427. {
  428.   int ret;
  429.  
  430.   Log("PowerOff start");
  431.   ps->schedule.wait=60;
  432.   Log("who=%d, use_nt=%d, action=%d",ps->who,ps->remote.use_nt,ps->action);
  433.   if (ps->who==REMOTE_COMPUTER && !ps->remote.use_nt && ps->action!=WAKE_ON_LAN)
  434.   {
  435.     char str[500];
  436.  
  437.     if ((ret=SendRemoteCommand(hWnd,ps,str))!=0)
  438.     {
  439.       Log("ret=%d",ret);
  440.       if (ret==-2)
  441.         Error(ps,hWnd,str);
  442.       return -1;
  443.     }
  444.     else
  445.     {
  446.       Log("PowerOff end");
  447.       return 0;
  448.     }
  449.   }
  450.   if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_NT)
  451.   {
  452.     if (AquirePrivileges(hWnd,ps)!=0)
  453.     {
  454.       return -1;
  455.     }
  456.   }
  457.   switch (ps->action)
  458.   {
  459.     case LOGOFF:
  460.     case REBOOT:
  461.     case SHUTDOWN:
  462.     case POWEROFF:
  463.       if (ps->who==LOCAL_COMPUTER)
  464.       {
  465.         ret=DoExitWindowsEx(hWnd,ps);
  466.       }
  467.       else
  468.         ret=DoInitiateSystemShutdown(hWnd,ps);
  469.       break;
  470.     case STANDBY:    
  471.     case HIBERNATE:
  472.       ret=DoSetSystemPowerState(hWnd,ps);
  473.       break;
  474.     case LOCK:
  475.       ret=DoLockWorkstation(hWnd,ps);
  476.       break;
  477.     case WAKE_ON_LAN:
  478.       ret=DoWOL(hWnd,ps);
  479.       break;
  480.     case MONITOR_OFF:
  481.     case MONITOR_ON:
  482.       ret=DoTurnOffMonitor(hWnd,ps);
  483.       break;
  484.     case NO_ACTION:
  485.       ret=DoNoAction(hWnd,ps);
  486.       break;
  487.   }
  488.   Log("PowerOff end");
  489.   return ret;
  490. }
  491.  
  492. void DoQuickAction(PowerSettings *ps,Action action)
  493. {
  494.   char actionstr[100];
  495.   Action tmp;
  496.  
  497.   Log("DoQuickAction start");
  498.   tmp=ps->action;
  499.   ps->action=action;
  500.   sprintf(actionstr,"Are you sure that you want to %s your pc now?",GetModeStr(ps));
  501.   if (!ps->options.allow_cancel || MessageBox(NULL,actionstr,"Are you sure?",MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1)==IDYES)
  502.   {
  503.     ps->when=IMMEDIATE;
  504.     ps->who=LOCAL_COMPUTER;
  505.     ps->options.warning=0;
  506.     ps->options.run_program=0;
  507.     PowerOff(g_hWnd,ps);
  508.   }
  509.   else
  510.     ps->action=tmp;
  511.   Log("DoQuickAction end");
  512. }
  513.  
  514. int DoIt(HWND hWnd,PowerSettings *ps)
  515. {
  516.   char str[500];
  517.  
  518.   Log("DoIt start");
  519.   if (!SanityCheck(hWnd,ps,str))
  520.   {
  521.     if (ps->who==REMOTE_COMPUTER && ps->remote.use_nt==0 && (ps->when==IMMEDIATE || ps->remote.schedule_remote) && ps->action!=WAKE_ON_LAN)
  522.     {
  523.       HCURSOR c;
  524.  
  525.       c=SetCursor(LoadCursor(NULL, IDC_WAIT));
  526.       if (SendRemoteCommand(hWnd,ps,str)==-2)
  527.       {
  528.         SetCursor(c);
  529.         Error(ps,hWnd,str);
  530.         return -1;
  531.       }
  532.       SetCursor(c);
  533.     }
  534.     else if (ps->when==IMMEDIATE)
  535.     {
  536.       HCURSOR c;
  537.  
  538.       c=SetCursor(LoadCursor(NULL, IDC_WAIT));
  539.       PowerOff(hWnd,ps);
  540.       SetCursor(c);
  541.     }
  542.     else if (ps->when==SCHEDULED)
  543.     {
  544.       ps->remaining_seconds=ps->schedule.seconds;
  545.       ps->active_timer=SetTimer(hWnd,ID_SCHEDULE_TIMER,1000,NULL);
  546.       MinimizePoweroff(hWnd,ps);
  547.     }
  548.     else if (ps->when==PROCESS)
  549.     {
  550.       ps->active_timer=SetTimer(hWnd,ID_PROCESS_TIMER,1000,NULL);
  551.       MinimizePoweroff(hWnd,ps);
  552.     }
  553.   }
  554.   else
  555.   {
  556.     Error(ps,hWnd,str);
  557.     return -2;
  558.   }
  559.   Log("DoIt end");
  560.   return 0;
  561. }