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

  1. #include "poweroff.h"
  2.  
  3. HINSTANCE hInst;
  4. UINT g_tid=0,g_time_tid=0;
  5. HMENU g_menu;
  6. UINT tray_timer=0;
  7. short debug=0;
  8. SETSUSPENDSTATEPROC MySetSuspendState=NULL;
  9.  
  10. void Log(char *fmt,...)
  11. {
  12.   va_list param;
  13.   char str[5000],str2[5000];
  14.   FILE *f;
  15.   time_t t;
  16.   char timebuf[100];
  17.  
  18.   if (debug)
  19.   {
  20.     va_start(param,fmt);
  21.     _vsnprintf(str,5000,fmt,param);
  22.     va_end(param);
  23.     time(&t);
  24.     strftime(timebuf,100,"%d-%m-%Y %H:%M:%S",localtime(&t));
  25.     if (str[strlen(str)-1]=='\n')
  26.       sprintf(str2,"%19s -> %s",timebuf,str);
  27.     else
  28.       sprintf(str2,"%19s -> %s\n",timebuf,str);
  29.  
  30.     f=fopen("poweroff.log","a+");
  31.     if (f==NULL)
  32.           return;
  33.     fprintf(f,"%s",str2);
  34.     fclose(f);
  35.   }
  36. }
  37.  
  38. void Error(PowerSettings *ps,HWND hWnd,char *str)
  39. {
  40.   Log("Error start");
  41.   if (!ps || ps->quiet==0)
  42.     MessageBox(hWnd,str,"poweroff",MB_OK|MB_ICONERROR);
  43.   Log("ERROR: %s",str);
  44.   Log("Error end");
  45. }
  46.  
  47. void DisplayInformation(PowerSettings *ps,HWND hWnd,char *str)
  48. {
  49.   Log("DisplayInformation start");
  50.   if (hWnd && (!ps || ps->quiet==0))
  51.     MessageBox(NULL,str,"Poweroff",MB_OK|MB_ICONINFORMATION);
  52.   Log("INFO: %s",str);
  53.   Log("DisplayInformation end");
  54. }
  55.  
  56. void WriteEvent(PowerSettings *ps,WORD event_type,char *fmt,...)
  57. {
  58.     HANDLE event_log;
  59.   va_list param;
  60.   char *str;
  61.  
  62.   Log("WriteEvent start");
  63.   str=GlobalAlloc(GMEM_FIXED,5000);
  64.   va_start(param,fmt);
  65.   vsprintf(str,fmt,param);
  66.   va_end(param);
  67.  
  68.   if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_NT)
  69.   {
  70.     event_log=RegisterEventSource(NULL,"Poweroff");
  71.         if (event_log==NULL)
  72.         {
  73.       GlobalFree(str);
  74.             return;
  75.         }
  76.         ReportEvent(event_log,event_type,0,0,NULL,1,0,&str,NULL);
  77.     DeregisterEventSource(event_log);
  78.     }
  79.   GlobalFree(str);
  80.   Log("WriteEvent end");
  81. }
  82.  
  83. void DisplayLastError(PowerSettings *ps,HWND hWnd)
  84. {
  85.   LPVOID lpMsgBuf;
  86.   
  87.   Log("DisplayLastError start");
  88.   FormatMessage( 
  89.     FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  90.     NULL,
  91.     GetLastError(),
  92.     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  93.     (LPTSTR) &lpMsgBuf,    0,    NULL );
  94.   WriteEvent(ps,EVENTLOG_ERROR_TYPE,lpMsgBuf);
  95.   if (hWnd)
  96.     Error(ps, hWnd, lpMsgBuf);
  97.   Log("ERROR: %s",lpMsgBuf);
  98.   LocalFree( lpMsgBuf );
  99.   Log("DisplayLastError end");
  100. }
  101.  
  102. void EnableFields(HWND hWnd,PowerSettings *ps)
  103. {
  104.   Log("EnableFields start");
  105.   if (ps->action==WAKE_ON_LAN)
  106.   {
  107.     ps->who=REMOTE_COMPUTER;
  108.     CheckRadioButton(hWnd,IDC_LOCAL_COMPUTER,IDC_REMOTE_COMPUTER,IDC_REMOTE_COMPUTER);
  109.     EnableWindow(GetDlgItem(hWnd,IDC_LOCAL_COMPUTER),FALSE);
  110.   }
  111.   else
  112.   {
  113.     EnableWindow(GetDlgItem(hWnd,IDC_LOCAL_COMPUTER),TRUE);
  114.   }
  115.   if (ps->who==LOCAL_COMPUTER)
  116.   {
  117.     if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  118.     {
  119.       EnableWindow(GetDlgItem(hWnd,IDC_LOGOFF),TRUE);
  120.       EnableWindow(GetDlgItem(hWnd,IDC_REBOOT),TRUE);
  121.       EnableWindow(GetDlgItem(hWnd,IDC_SHUTDOWN),TRUE);
  122.       /*EnableWindow(GetDlgItem(hWnd,IDC_POWEROFF),FALSE);*/
  123.       EnableWindow(GetDlgItem(hWnd,IDC_POWEROFF),TRUE);
  124.       EnableWindow(GetDlgItem(hWnd,IDC_STANDBY),TRUE);
  125.       EnableWindow(GetDlgItem(hWnd,IDC_HIBERNATE),TRUE);
  126.       EnableWindow(GetDlgItem(hWnd,IDC_LOCK),FALSE);
  127.       if (ps->action==LOCK)
  128.       {
  129.         CheckRadioButton(hWnd,IDC_LOGOFF,IDC_WAKE_ON_LAN,IDC_SHUTDOWN);
  130.         ps->action=POWEROFF;
  131.       }
  132.     }
  133.     else if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_NT
  134.           && ps->windowsversion.dwMajorVersion<5)
  135.     {
  136.       EnableWindow(GetDlgItem(hWnd,IDC_LOCK),FALSE);
  137.       if (ps->action==LOCK)
  138.       {
  139.         CheckRadioButton(hWnd,IDC_LOGOFF,IDC_WAKE_ON_LAN,IDC_POWEROFF);
  140.         ps->action=POWEROFF;
  141.       }
  142.     }
  143.   }
  144.   else
  145.   {
  146.     EnableWindow(GetDlgItem(hWnd,IDC_LOGOFF),TRUE);
  147.     EnableWindow(GetDlgItem(hWnd,IDC_REBOOT),TRUE);
  148.     EnableWindow(GetDlgItem(hWnd,IDC_SHUTDOWN),TRUE);
  149.     EnableWindow(GetDlgItem(hWnd,IDC_POWEROFF),TRUE);
  150.     EnableWindow(GetDlgItem(hWnd,IDC_STANDBY),TRUE);
  151.     EnableWindow(GetDlgItem(hWnd,IDC_HIBERNATE),TRUE);
  152.     EnableWindow(GetDlgItem(hWnd,IDC_LOCK),TRUE);
  153.   }
  154.   if (ps->who==LOCAL_COMPUTER)
  155.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_REMOTE),FALSE);
  156.   else
  157.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_REMOTE),TRUE);
  158.  
  159.   if (ps->options.warning)
  160.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_MESSAGE),TRUE);
  161.   else
  162.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_MESSAGE),FALSE);
  163.  
  164.   if (ps->options.run_program)
  165.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_PROGRAM),TRUE);
  166.   else
  167.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_PROGRAM),FALSE);
  168.  
  169.   if (ps->when==SCHEDULED)
  170.   {
  171.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_SCHEDULE),TRUE);
  172.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_PROCESS),FALSE);
  173.   }
  174.   else if (ps->when==PROCESS)
  175.   {
  176.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_SCHEDULE),FALSE);
  177.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_PROCESS),TRUE);
  178.   }
  179.   else
  180.   {
  181.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_SCHEDULE),FALSE);
  182.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_PROCESS),FALSE);
  183.   }
  184.   if (ps->options.allow_remote_control)
  185.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_REMOTE_CONTROL),TRUE);
  186.   else
  187.     EnableWindow(GetDlgItem(hWnd,IDC_BUT_REMOTE_CONTROL),FALSE);
  188.   Log("EnableFields end");
  189. }
  190.  
  191. void ApplySettings(HWND hWnd,PowerSettings *ps)
  192. {
  193.   Log("ApplySettings start");
  194.   if (IsDlgButtonChecked(hWnd,IDC_LOCAL_COMPUTER))
  195.     ps->who=LOCAL_COMPUTER;
  196.   else
  197.     ps->who=REMOTE_COMPUTER;
  198.   if (IsDlgButtonChecked(hWnd,IDC_LOGOFF))
  199.     ps->action=LOGOFF;
  200.   else if (IsDlgButtonChecked(hWnd,IDC_REBOOT))
  201.     ps->action=REBOOT;
  202.   else if (IsDlgButtonChecked(hWnd,IDC_REBOOT))
  203.     ps->action=REBOOT;
  204.   else if (IsDlgButtonChecked(hWnd,IDC_SHUTDOWN))
  205.     ps->action=SHUTDOWN;
  206.   else if (IsDlgButtonChecked(hWnd,IDC_POWEROFF))
  207.     ps->action=POWEROFF;
  208.   else if (IsDlgButtonChecked(hWnd,IDC_STANDBY))
  209.     ps->action=STANDBY;
  210.   else if (IsDlgButtonChecked(hWnd,IDC_HIBERNATE))
  211.     ps->action=HIBERNATE;
  212.   else if (IsDlgButtonChecked(hWnd,IDC_LOCK))
  213.     ps->action=LOCK;
  214.   else if (IsDlgButtonChecked(hWnd,IDC_WAKE_ON_LAN))
  215.     ps->action=WAKE_ON_LAN;
  216.   else if (IsDlgButtonChecked(hWnd,IDC_MONITOR_OFF))
  217.     ps->action=MONITOR_OFF;
  218.   else if (IsDlgButtonChecked(hWnd,IDC_MONITOR_ON))
  219.     ps->action=MONITOR_ON;
  220.   else if (IsDlgButtonChecked(hWnd,IDC_NO_ACTION))
  221.     ps->action=NO_ACTION;
  222.   ps->options.warning=IsDlgButtonChecked(hWnd,IDC_WARNING);
  223.   ps->options.force=IsDlgButtonChecked(hWnd,IDC_FORCE);
  224.   ps->options.in_tray=IsDlgButtonChecked(hWnd,IDC_TRAY);
  225.   ps->options.run_program=IsDlgButtonChecked(hWnd,IDC_PRE_JOB);
  226.   ps->options.allow_cancel=IsDlgButtonChecked(hWnd,IDC_ALLOW_CANCEL);
  227.   ps->options.allow_remote_control=IsDlgButtonChecked(hWnd,IDC_ALLOW_REMOTE_CONTROL);
  228.   if (IsDlgButtonChecked(hWnd,IDC_IMMEDIATE))
  229.     ps->when=IMMEDIATE;
  230.   else if (IsDlgButtonChecked(hWnd,IDC_SCHEDULED))
  231.     ps->when=SCHEDULED;
  232.   else if (IsDlgButtonChecked(hWnd,IDC_AFTER_PROCESS))
  233.     ps->when=PROCESS;
  234.   EnableFields(hWnd,ps);
  235.   if (ps->run_as_service && ps->options.allow_remote_control && ps->serversocket==INVALID_SOCKET)
  236.     CreateServerSocket(hWnd,ps);
  237.   else if (!ps->options.allow_remote_control && ps->serversocket!=INVALID_SOCKET)
  238.     CloseServerSocket(hWnd,ps);
  239.   Log("ApplySettings end");
  240. }
  241.  
  242. void PutInTray(HWND hWnd,PowerSettings *ps)
  243. {
  244.   NOTIFYICONDATA nid;
  245.  
  246.   Log("PutInTray start");
  247.   nid.cbSize=sizeof(NOTIFYICONDATA);
  248.   nid.hWnd=hWnd;
  249.   nid.uID=1;
  250.   nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
  251.   nid.uCallbackMessage=NMESSAGE;
  252.   nid.hIcon=LoadIcon(hInst, MAKEINTRESOURCE(IDI_POWEROFF_SMALL));
  253.   if (ps->active_timer && ps->when==SCHEDULED)
  254.   {
  255.     if (ps->schedule.schedule==FIXED_DAY)
  256.       _snprintf(nid.szTip,63,"%s scheduled at %02d:%02d on %02d/%02d/%04d",GetModeStr(ps),ps->schedule.time.wHour,ps->schedule.time.wMinute,ps->schedule.date.wDay,ps->schedule.date.wMonth,ps->schedule.date.wYear);
  257.     else if (ps->schedule.schedule==DAILY)
  258.     {
  259.       char str[20]="";
  260.  
  261.       if (ps->schedule.monday)
  262.         ADD_DAY("m")
  263.       if (ps->schedule.tuesday)
  264.         ADD_DAY("t")
  265.       if (ps->schedule.wednesday)
  266.         ADD_DAY("w")
  267.       if (ps->schedule.thursday)
  268.         ADD_DAY("th")
  269.       if (ps->schedule.friday)
  270.         ADD_DAY("f")
  271.       if (ps->schedule.saturday)
  272.         ADD_DAY("s")
  273.       if (ps->schedule.sunday)
  274.         ADD_DAY("su")
  275.       _snprintf(nid.szTip,63,"%s scheduled at %02d:%02d on %s",GetModeStr(ps),ps->schedule.time.wHour,ps->schedule.time.wMinute,str);
  276.     }
  277.     else if (ps->schedule.schedule==DAY_OF_MONTH)
  278.       _snprintf(nid.szTip,63,"%s scheduled at %02d:%02d on day %d",GetModeStr(ps),ps->schedule.time.wHour,ps->schedule.time.wMinute,ps->schedule.day);
  279.     else if (ps->schedule.schedule==AFTER_X_SECONDS)
  280.       _snprintf(nid.szTip,63,"%s scheduled after %d seconds",GetModeStr(ps),ps->remaining_seconds);
  281.   }
  282.   else if (ps->active_timer && ps->when==PROCESS)
  283.   {
  284.     _snprintf(nid.szTip,63,"%s when %s finishes",GetModeStr(ps),ps->process.process);
  285.   }
  286.   else
  287.     strcpy(nid.szTip,"Poweroff idle");
  288.   Shell_NotifyIcon(NIM_ADD,&nid);
  289.   if (ps->run_as_service && tray_timer==0)
  290.   {
  291.     tray_timer=SetTimer(hWnd,ID_TRAY_TIMER,5000,NULL);
  292.     if (tray_timer==0)
  293.       DisplayLastError(ps,hWnd);
  294.   }
  295.   Log("PutInTray end");
  296. }
  297.  
  298. void MinimizePoweroff(HWND hWnd,PowerSettings *ps)
  299. {
  300.   Log("MinimizePoweroff start");
  301.   ShowWindow(hWnd,SW_HIDE);
  302.   if ((!ps->run_as_service && !ps->active_timer) || ps->options.in_tray)
  303.   {
  304.     PutInTray(hWnd,ps);
  305.   }
  306.   if (ps->active_timer && ps->options.allow_cancel)
  307.   {
  308.     EnableMenuItem(g_menu,IDC_CANCEL,MF_ENABLED);
  309.     EnableMenuItem(g_menu,IDC_EXIT,MF_ENABLED);
  310.     EnableMenuItem(g_menu,IDC_RESTORE,MF_GRAYED);
  311.   }
  312.   else if (ps->active_timer && !ps->options.allow_cancel)
  313.   {
  314.     EnableMenuItem(g_menu,IDC_CANCEL,MF_GRAYED);
  315.     EnableMenuItem(g_menu,IDC_EXIT,MF_GRAYED);
  316.     EnableMenuItem(g_menu,IDC_RESTORE,MF_GRAYED);
  317.   }
  318.   else
  319.   {
  320.     EnableMenuItem(g_menu,IDC_CANCEL,MF_GRAYED);
  321.     EnableMenuItem(g_menu,IDC_EXIT,MF_ENABLED);
  322.     EnableMenuItem(g_menu,IDC_RESTORE,MF_ENABLED);
  323.   }
  324.   if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  325.   {
  326.     EnableMenuItem(g_menu,IDC_Q_LOCK,MF_GRAYED);
  327.   }
  328.   if (ps->run_as_service)
  329.     EnableMenuItem(g_menu,IDC_EXIT,MF_GRAYED);
  330.   Log("MinimizePoweroff end");
  331. }
  332.  
  333. void RemoveFromTray(HWND hWnd)
  334. {
  335.   NOTIFYICONDATA nid;
  336.  
  337.   Log("RemoveFromTray start");
  338.   nid.cbSize=sizeof(NOTIFYICONDATA);
  339.   nid.hWnd=hWnd;
  340.   nid.uID=1;
  341.   nid.uFlags=0;
  342.   Shell_NotifyIcon(NIM_DELETE,&nid);
  343.   SetForegroundWindow(hWnd);
  344.   if (tray_timer)
  345.   {
  346.     KillTimer(hWnd,tray_timer);
  347.     tray_timer=0;
  348.   }
  349.   Log("RemoveFromTray end");
  350. }
  351.  
  352. void RestorePoweroff(HWND hWnd,PowerSettings *ps)
  353. {
  354.   Log("RestorePoweroff start");
  355.   if (!ps->active_timer)
  356.   {
  357.     RemoveFromTray(hWnd);
  358.     ShowWindow(hWnd,SW_SHOWNORMAL);
  359.     SetForegroundWindow(hWnd);
  360.   }
  361.   Log("RestorePoweroff end");
  362. }
  363.  
  364. void DisplaySettings(HWND hWnd,PowerSettings *ps)
  365. {
  366.   Log("DisplaySettings start");
  367.   switch (ps->who)
  368.   {
  369.     case LOCAL_COMPUTER:
  370.       CheckRadioButton(hWnd,IDC_LOCAL_COMPUTER,IDC_REMOTE_COMPUTER,IDC_LOCAL_COMPUTER);
  371.       break;
  372.     case REMOTE_COMPUTER:
  373.       CheckRadioButton(hWnd,IDC_LOCAL_COMPUTER,IDC_REMOTE_COMPUTER,IDC_REMOTE_COMPUTER);
  374.       break;
  375.   }
  376.   switch (ps->action)
  377.   {
  378.     case LOGOFF:
  379.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_LOGOFF);
  380.       break;
  381.     case REBOOT:
  382.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_REBOOT);
  383.       break;
  384.     case SHUTDOWN:
  385.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_SHUTDOWN);
  386.       break;
  387.     case POWEROFF:
  388.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_POWEROFF);
  389.       break;
  390.     case STANDBY:
  391.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_STANDBY);
  392.       break;
  393.     case HIBERNATE:
  394.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_HIBERNATE);
  395.       break;
  396.     case LOCK:
  397.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_LOCK);
  398.       break;
  399.     case WAKE_ON_LAN:
  400.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_WAKE_ON_LAN);
  401.       break;
  402.     case MONITOR_OFF:
  403.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_MONITOR_OFF);
  404.       break;
  405.     case MONITOR_ON:
  406.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_MONITOR_ON);
  407.       break;
  408.     case NO_ACTION:
  409.       CheckRadioButton(hWnd,IDC_LOGOFF,IDC_NO_ACTION,IDC_NO_ACTION);
  410.       break;
  411.   }
  412.   switch (ps->when)
  413.   {
  414.     case IMMEDIATE:
  415.       CheckRadioButton(hWnd,IDC_IMMEDIATE,IDC_AFTER_PROCESS,IDC_IMMEDIATE);
  416.       break;
  417.     case SCHEDULED:
  418.       CheckRadioButton(hWnd,IDC_IMMEDIATE,IDC_AFTER_PROCESS,IDC_SCHEDULED);
  419.       break;
  420.     case PROCESS:
  421.       CheckRadioButton(hWnd,IDC_IMMEDIATE,IDC_AFTER_PROCESS,IDC_AFTER_PROCESS);
  422.       break;
  423.   }
  424.   CheckDlgButton(hWnd,IDC_FORCE,ps->options.force?BST_CHECKED:BST_UNCHECKED);
  425.   CheckDlgButton(hWnd,IDC_TRAY,ps->options.in_tray?BST_CHECKED:BST_UNCHECKED);
  426.   CheckDlgButton(hWnd,IDC_PRE_JOB,ps->options.run_program?BST_CHECKED:BST_UNCHECKED);
  427.   CheckDlgButton(hWnd,IDC_WARNING,ps->options.warning?BST_CHECKED:BST_UNCHECKED);
  428.   CheckDlgButton(hWnd,IDC_ALLOW_CANCEL,ps->options.allow_cancel?BST_CHECKED:BST_UNCHECKED);
  429.   CheckDlgButton(hWnd,IDC_ALLOW_REMOTE_CONTROL,ps->options.allow_remote_control?BST_CHECKED:BST_UNCHECKED);
  430.   EnableFields(hWnd,ps);
  431.   if (ps->run_as_service && ps->options.allow_remote_control && ps->serversocket==INVALID_SOCKET)
  432.     CreateServerSocket(hWnd,ps);
  433.   else if (!ps->options.allow_remote_control && ps->serversocket!=INVALID_SOCKET)
  434.     CloseServerSocket(hWnd,ps);
  435.   Log("DisplaySettings end");
  436. }
  437.  
  438. BOOL FAR PASCAL DlgProc(HWND hWnd, unsigned message,DWORD wParam, LONG lParam)
  439. {
  440.   static PowerSettings *ps;
  441.  
  442.   switch (message) 
  443.   {
  444.     case WM_INITDIALOG:
  445.       {
  446.         char str[30];
  447.  
  448.         g_hWnd=hWnd;
  449.         sprintf(str,"Poweroff %s",POWEROFF_VERSION);
  450.         SetWindowText(hWnd,str);
  451.         SendMessage(hWnd,WM_SETICON,(WPARAM)ICON_BIG,(LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_POWEROFF)));
  452.         SendMessage(hWnd,WM_SETICON,(WPARAM)ICON_SMALL,(LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_POWEROFF_SMALL)));
  453.         ps=(PowerSettings*)lParam;
  454.         DisplaySettings(hWnd,ps);
  455.  
  456.         if (!ps->interactive)
  457.         {
  458.           int r;
  459.  
  460.           r=DoIt(hWnd,ps);
  461.           if (r!=0 || ps->when==IMMEDIATE)
  462.             PostQuitMessage(0);
  463.           return FALSE;
  464.         }
  465.         else if (ps->run_as_service)
  466.         {
  467.           ShowWindow(hWnd,SW_SHOWNA);
  468.           if (ps->when==SCHEDULED)
  469.             DoIt(hWnd,ps);
  470.           else
  471.             MinimizePoweroff(hWnd,ps);
  472.           return FALSE;
  473.         }
  474.         else if (ps->start_minimized)
  475.         {
  476.           MinimizePoweroff(hWnd,ps);
  477.           return FALSE;
  478.         }
  479.         else
  480.         {
  481.           ShowWindow(hWnd,SW_SHOWNORMAL);
  482.         }
  483.         SetTimer(hWnd,10,1000,NULL);
  484.       }
  485.       return TRUE;
  486.     case WM_CLOSE:
  487.       if (!ps->run_as_service)
  488.         PostQuitMessage(0);
  489.       else
  490.         MinimizePoweroff(hWnd,ps);
  491.       return TRUE;
  492.       break;
  493.     case WM_QUIT:
  494.     case WM_DESTROY:
  495.       RemoveFromTray(hWnd);
  496.       return TRUE;
  497.       break;
  498.     case WM_TIMER:
  499.       if (wParam==ID_TRAY_TIMER)
  500.         PutInTray(hWnd,ps);
  501.       else if (wParam==ID_STOP_TIMER)
  502.         PostQuitMessage(0);
  503.       else if (ps->active_timer)
  504.       {
  505.         if (wParam==ID_SCHEDULE_TIMER)
  506.           CheckScheduleTimer(hWnd,ps);
  507.         else if (wParam==ID_PROCESS_TIMER)
  508.           CheckProcessTimer(hWnd,ps);
  509.       }
  510.       return TRUE;
  511.       break;
  512.     case WM_COMMAND:
  513.       switch (LOWORD(wParam))
  514.       {
  515.         case IDC_CANCEL:
  516.           if (!ps->run_as_service)
  517.             PostQuitMessage(0);
  518.           else
  519.             MinimizePoweroff(hWnd,ps);
  520.           break;
  521.         case IDC_OK:
  522.           DoIt(hWnd,ps);
  523.           break;
  524.         case IDC_BUT_REMOTE:
  525.           ShowRemoteDialog(hWnd,ps);
  526.           break;
  527.         case IDC_BUT_MESSAGE:
  528.           ShowMessageDialog(hWnd,ps);
  529.           break;
  530.         case IDC_BUT_PROGRAM:
  531.           ShowProgramDialog(hWnd,ps);
  532.           break;
  533.         case IDC_BUT_SCHEDULE:
  534.           ShowScheduleDialog(hWnd,ps);
  535.           break;
  536.         case IDC_BUT_PROCESS:
  537.           ShowProcessDialog(hWnd,ps);
  538.           break;
  539.         case IDC_BUT_REMOTE_CONTROL:
  540.           ShowRemoteControlDialog(hWnd,ps);
  541.           break;
  542.         case IDC_SAVE:
  543.           SaveSettings(HKEY_CURRENT_USER,"SOFTWARE\\JoBo\\Poweroff",ps);
  544.           break;
  545.         case IDC_LOAD_SETTINGS:
  546.           if (!ReadSettings(HKEY_CURRENT_USER,"SOFTWARE\\JoBo\\Poweroff",ps))
  547.             ReadSettings(HKEY_LOCAL_MACHINE,"SOFTWARE\\JoBo\\Poweroff",ps);
  548.           DisplaySettings(hWnd,ps);
  549.           break;
  550.         case IDC_REMOVE_SETTINGS:
  551.           if (!DeleteRegistryKey(HKEY_CURRENT_USER,"SOFTWARE\\JoBo\\Poweroff"))
  552.           {
  553.             DisplayLastError(ps,hWnd);
  554.             break;
  555.           }
  556.           InitializeSettings(ps);
  557.           DisplaySettings(hWnd,ps);
  558.           break;
  559.         case ID_SAVESETTINGSTOSERVICE:
  560.           SaveSettings(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Poweroff\\Parameters",ps);
  561.           if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  562.           {
  563.             DisplayInformation(ps,hWnd,"Please restart your computer for the changes to take effect");
  564.           }
  565.           else
  566.           {
  567.             if (IsPoweroffServiceRunning(hWnd,ps))
  568.             {
  569.               StopPoweroffService(hWnd,ps);
  570.               StartPoweroffService(hWnd,ps);
  571.             }
  572.           }
  573.           break;
  574.         case ID_LOADSETTINGSFROMSERVICE:
  575.           ReadSettings(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Poweroff\\Parameters",ps);
  576.           DisplaySettings(hWnd,ps);
  577.           break;
  578.         case ID_CREATESERVICE:
  579.           CreatePoweroffService(hWnd,ps);
  580.           break;
  581.         case IDC_REMOVE_SERVICE:
  582.           if (IsPoweroffServiceRunning(hWnd,ps))
  583.             StopPoweroffService(hWnd,ps);
  584.           RemovePoweroffService(hWnd,ps);
  585.           break;
  586.         default:
  587.           ApplySettings(hWnd,ps);
  588.             break;
  589.       }
  590.       return TRUE;
  591.       break;
  592.     case WM_SIZE:
  593.       if (wParam==SIZE_MINIMIZED)
  594.       {
  595.         MinimizePoweroff(hWnd,ps);
  596.       }
  597.       return TRUE;
  598.       break;
  599.     case UWM_ACCEPT:
  600.       if (WSAGETSELECTERROR(lParam)==0)
  601.         AcceptClientSocket(hWnd,ps);
  602.       return TRUE;
  603.       break;
  604.     case UWM_READ:
  605.       if (WSAGETSELECTERROR(lParam)==0)
  606.       {
  607.         if (WSAGETSELECTEVENT(lParam)==FD_READ)
  608.           ReadFromClientSocket(hWnd,ps);
  609.         else if (WSAGETSELECTEVENT(lParam)==FD_CLOSE)
  610.           CloseClientSocket(hWnd,ps);
  611.       }
  612.       return TRUE;
  613.       break;
  614.     case NMESSAGE:
  615.       switch (lParam)
  616.       {
  617.         case WM_LBUTTONDBLCLK:
  618.           if (!ps->active_timer || ps->options.allow_cancel)
  619.             RestorePoweroff(hWnd,ps);
  620.           break;
  621.         case WM_RBUTTONDOWN:
  622.           {
  623.             POINT p;
  624.  
  625.             GetCursorPos(&p);
  626.  
  627.             /* Fix for stupid menu behaviour */
  628.             SetForegroundWindow (hWnd);
  629.     
  630.             switch (TrackPopupMenu(GetSubMenu(g_menu,0),
  631.                                    TPM_RIGHTALIGN|TPM_BOTTOMALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON,
  632.                                    p.x,
  633.                                    p.y,
  634.                                    0,
  635.                                    hWnd,
  636.                                    NULL))
  637.             {
  638.               case IDC_LOGOFF:
  639.                 DoQuickAction(ps,LOGOFF);
  640.                 break;             
  641.               case IDC_REBOOT:
  642.                 DoQuickAction(ps,REBOOT);
  643.                 break;              
  644.               case IDC_SHUTDOWN:
  645.                 DoQuickAction(ps,SHUTDOWN);
  646.                 break;              
  647.               case IDC_POWEROFF:
  648.                 DoQuickAction(ps,POWEROFF);
  649.                 break;              
  650.               case IDC_STANDBY:
  651.                 DoQuickAction(ps,STANDBY);
  652.                 break;              
  653.               case IDC_Q_HIBERNATE:
  654.                 DoQuickAction(ps,HIBERNATE);
  655.                 break;
  656.               case IDC_Q_LOCK:
  657.                 DoQuickAction(ps,LOCK);
  658.                 break;
  659.               case IDC_Q_MONITOR_OFF:
  660.                 DoQuickAction(ps,MONITOR_OFF);
  661.                 break;
  662.               case IDC_CANCEL:
  663.                 if (ps->active_timer)
  664.                 {
  665.                   KillTimer(hWnd,ps->active_timer);
  666.                   ps->active_timer=0;
  667.                   RestorePoweroff(hWnd,ps);
  668.                 }
  669.                 break;
  670.               case IDC_RESTORE:
  671.                 RestorePoweroff(hWnd,ps);
  672.                 break;
  673.               case IDC_EXIT:
  674.                 if (!ps->run_as_service)
  675.                 {
  676.                   NOTIFYICONDATA nid;
  677.  
  678.                   nid.cbSize=sizeof(NOTIFYICONDATA);
  679.                   nid.hWnd=hWnd;
  680.                   nid.uID=1;
  681.                   nid.uFlags=0;
  682.                   Shell_NotifyIcon(NIM_DELETE,&nid);
  683.                   PostQuitMessage(0);
  684.                 }
  685.                 break;
  686.             }
  687.  
  688.             /* Fix for stupid menu behaviour */
  689.             PostMessage (hWnd, WM_NULL, 0, 0);
  690.           }
  691.           break;
  692.  
  693.       }
  694.       return TRUE;
  695.       break;               
  696.   }
  697.   return FALSE;
  698. }
  699.  
  700. BOOL InitDialog(HWND hWnd,HINSTANCE hInstance,int nCmdShow,PowerSettings *ps)
  701. {
  702.   FARPROC dlgproc;
  703.   
  704.   Log("InitDialog start");
  705.   dlgproc=MakeProcInstance((FARPROC)DlgProc,hInstance);
  706.     if (CreateDialogParam(hInstance,MAKEINTRESOURCE(IDD_POWEROFF),hWnd,(DLGPROC)dlgproc,(LPARAM)ps)==NULL)
  707.     DisplayLastError(ps,hWnd);
  708.     FreeProcInstance(dlgproc);
  709.   Log("InitDialog end");
  710.   return TRUE;
  711. }
  712.  
  713. void TrySetSuspendState(void)
  714. {
  715.   HINSTANCE hInstLib;
  716.  
  717.   Log("TrySetSuspendState start");
  718.   hInstLib = LoadLibrary( "Powrprof.dll" ) ;
  719.   if( hInstLib == NULL )
  720.   {
  721.     Log("TrySetSuspendState end, failed to load library powrprof.dll");
  722.     return;
  723.   }
  724.   MySetSuspendState=(SETSUSPENDSTATEPROC)GetProcAddress(hInstLib,"SetSuspendState");
  725.   Log("TrySetSuspendState end, MySetSuspendState=%p",MySetSuspendState);
  726. }  
  727.  
  728. int PASCAL WinMain( HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
  729. {
  730.   MSG msg;
  731.   INITCOMMONCONTROLSEX controls;
  732.   PowerSettings ps;
  733.   DWORD tid;
  734.  
  735.   controls.dwSize=sizeof(INITCOMMONCONTROLSEX);
  736.   controls.dwICC=ICC_DATE_CLASSES|ICC_INTERNET_CLASSES;
  737.   InitCommonControlsEx(&controls);
  738.  
  739.   hInst=hInstance;
  740.   InitializeSockets();
  741.   InitializeSettings(&ps);
  742.   TrySetSuspendState();
  743.   if (!ParseCommandLine(GetCommandLine(),&ps))
  744.     ReadDefaultSettings(&ps);
  745.  
  746.   Log("Starting poweroff %s",POWEROFF_VERSION);
  747.   Log("Commandline: %s",GetCommandLine());
  748.   if (debug)
  749.     DebugSettings(&ps);
  750.   if (ps.windowsversion.dwPlatformId==VER_PLATFORM_WIN32_NT)
  751.     Log("PC is running Windows NT version %d.%d build %d (%s)",ps.windowsversion.dwMajorVersion,ps.windowsversion.dwMinorVersion,ps.windowsversion.dwBuildNumber,ps.windowsversion.szCSDVersion);
  752.   else
  753.     Log("PC is running Windows 9x version %d.%d build %d (%s)",ps.windowsversion.dwMajorVersion,ps.windowsversion.dwMinorVersion,LOWORD(ps.windowsversion.dwBuildNumber),ps.windowsversion.szCSDVersion);
  754.  
  755.   CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CheckService,&ps,0,&tid);
  756.  
  757.  
  758.   g_menu=LoadMenu(hInst,MAKEINTRESOURCE(IDR_QUICKMENU));
  759.  
  760.   if (!InitDialog(NULL,hInstance,nCmdShow,&ps))
  761.     return FALSE;
  762.  
  763.   while (GetMessage(&msg,NULL,0,0)==1)
  764.   {
  765.     if (!IsDialogMessage(g_hWnd,&msg))
  766.     {
  767.       TranslateMessage(&msg);
  768.       DispatchMessage(&msg);
  769.     }
  770.   }
  771.   Log("Poweroff stopped");
  772.   Cleanup(&ps);
  773.   return (msg.wParam);
  774. }
  775.  
  776. void Cleanup(PowerSettings *ps)
  777. {
  778.   Log("Cleanup");
  779.   if (g_menu)
  780.   {
  781.     DestroyMenu(g_menu);
  782.     g_menu=NULL;
  783.   }
  784.   DestroySockets(NULL,ps);
  785. }