home *** CD-ROM | disk | FTP | other *** search
/ PC World 2004 November / PCWorld_2004-11_cd.bin / software / temacd / poweroff / pwroff30.exe / src / service.c < prev    next >
C/C++ Source or Header  |  2002-02-16  |  12KB  |  421 lines

  1. #include "poweroff.h"
  2.  
  3. SERVICE_STATUS_HANDLE sh;
  4. SERVICE_STATUS status;
  5.  
  6. int CopyPoweroffToSystem(HWND hWnd,PowerSettings *ps,char *system_poweroff)
  7. {
  8.   char system_dir[MAX_PATH],path[1024]="",original_poweroff[MAX_PATH];
  9.   char *pos,*lastpos;
  10.   HANDLE f=INVALID_HANDLE_VALUE;
  11.  
  12.   Log("CopyPoweroffToSystem start, executable=%s, system_poweroff=%s",ps->executable,system_poweroff);
  13.   if (strlen(ps->executable)<4 || _stricmp(&ps->executable[strlen(ps->executable)-4],".exe"))
  14.     strcat(ps->executable,".exe");
  15.  
  16.   if (!strchr(ps->executable,'\\'))
  17.   {
  18.     strcpy(original_poweroff,ps->executable);
  19.     if ((f=CreateFile(ps->executable,
  20.                       0,
  21.                       FILE_SHARE_READ,
  22.                       NULL,
  23.                       OPEN_EXISTING,
  24.                       0,
  25.                       NULL))==INVALID_HANDLE_VALUE)
  26.     {
  27.       GetEnvironmentVariable("PATH",path,1024);
  28.       lastpos=path;
  29.       pos=strchr(lastpos,';');
  30.       while (pos)
  31.       {
  32.         *pos='\0';
  33.         sprintf(original_poweroff,"%s\\%s",lastpos,ps->executable);
  34.         if ((f=CreateFile(original_poweroff,
  35.                           0,
  36.                           FILE_SHARE_READ,
  37.                           NULL,
  38.                           OPEN_EXISTING,
  39.                           0,
  40.                           NULL))!=INVALID_HANDLE_VALUE)
  41.           break;
  42.         lastpos=pos+1;
  43.         pos=strchr(lastpos,';');
  44.       }
  45.       if (f==INVALID_HANDLE_VALUE)
  46.       {
  47.         sprintf(original_poweroff,"%s\\%s",lastpos,ps->executable);
  48.         f=CreateFile(original_poweroff,
  49.                      0,
  50.                      FILE_SHARE_READ,
  51.                      NULL,
  52.                      OPEN_EXISTING,
  53.                      0,
  54.                      NULL);
  55.       }
  56.     }
  57.   }
  58.   else
  59.   {
  60.     strcpy(original_poweroff,ps->executable);
  61.     f=CreateFile(original_poweroff,
  62.                  0,
  63.                  FILE_SHARE_READ,
  64.                  NULL,
  65.                  OPEN_EXISTING,
  66.                  0,
  67.                  NULL);
  68.   }
  69.   if (f==INVALID_HANDLE_VALUE)
  70.   {
  71.     Error(ps,NULL,"Can't find poweroff.exe!");
  72.     return 0;
  73.   }
  74.   CloseHandle(f);
  75.   
  76.   if (GetSystemDirectory(system_dir,MAX_PATH)==0)
  77.   {
  78.     DisplayLastError(ps,hWnd);
  79.     return 0;
  80.   }
  81.   sprintf(system_poweroff,"%s\\poweroff.exe",system_dir);
  82.  
  83.   if (_stricmp(original_poweroff,system_poweroff))
  84.   {
  85.     Log("Copying %s to %s",original_poweroff,system_poweroff);
  86.     if (CopyFile(original_poweroff,system_poweroff,FALSE)==0)
  87.     {
  88.       DisplayLastError(ps,hWnd);
  89.       CloseHandle(f);
  90.       return 0;
  91.     }
  92.   }
  93.   sprintf(path,"\"%s\" -service",system_poweroff);
  94.   strcpy(system_poweroff,path);
  95.   Log("CopyPoweroffToSystem end");
  96.   return 1;
  97. }
  98.  
  99. void CreatePoweroffService(HWND hWnd,PowerSettings *ps)
  100. {
  101.   char system_poweroff[MAX_PATH];
  102.   SC_HANDLE hsm,sh;
  103.  
  104.   Log("CreatePoweroffService start");
  105.   if (!CopyPoweroffToSystem(hWnd,ps,system_poweroff))
  106.     return;
  107.   SaveSettings(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Poweroff\\Parameters",ps);
  108.  
  109.   if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  110.   {
  111.     Log("Creating WIN98 service");
  112.     if (!WriteRegistryString(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices","Poweroff",system_poweroff))
  113.     {
  114.       DisplayLastError(ps,hWnd);
  115.       return;
  116.     }
  117.     DisplayInformation(ps,hWnd,"Please restart your computer to start the service");
  118.   }
  119.   else /* Create a real service */
  120.   {
  121.     Log("Creating real NT service");
  122.     hsm=OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
  123.     if (hsm==NULL)
  124.     {
  125.       DisplayLastError(ps,hWnd);
  126.       return;
  127.     }
  128.  
  129.     sh=CreateService(hsm,
  130.                     "Poweroff",
  131.                     "Poweroff",
  132.                     STANDARD_RIGHTS_REQUIRED|SERVICE_START,
  133.                     SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
  134.                     SERVICE_AUTO_START,
  135.                     SERVICE_ERROR_NORMAL,
  136.                     system_poweroff,
  137.                     NULL,
  138.                     NULL,
  139.                     NULL,
  140.                     NULL,
  141.                     NULL);
  142.     if (sh==NULL)
  143.     {
  144.       DisplayLastError(ps,hWnd);
  145.       CloseServiceHandle(hsm);
  146.       return;
  147.     }
  148.     Log("Starting service");
  149.     if (StartService(sh,0,NULL)==0)
  150.     {
  151.       DisplayLastError(ps,hWnd);
  152.       CloseServiceHandle(sh);
  153.       CloseServiceHandle(hsm);
  154.       return;
  155.     }
  156.     CloseServiceHandle(hsm);
  157.     DisplayInformation(ps,hWnd,"Poweroff service succesfully installed");
  158.   }
  159.   Log("CreatePoweroffService end");
  160. }
  161.  
  162. void RemovePoweroffService(HWND hWnd,PowerSettings *ps)
  163. {
  164.   SC_HANDLE hsm,sh;
  165.  
  166.   Log("RemovePoweroffService start");
  167.   if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  168.   {
  169.     Log("Deleting WIN98 service");
  170.     if (!DeleteRegistryValue(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices","Poweroff"))
  171.     {
  172.       DisplayLastError(ps,hWnd);
  173.       return;
  174.     }
  175.     DisplayInformation(ps,hWnd,"Please restart your computer to stop the service");
  176.   }
  177.   else
  178.   {
  179.     Log("Deleting NT service");
  180.     hsm=OpenSCManager(NULL,NULL,GENERIC_WRITE);
  181.     if (hsm==NULL)
  182.     {
  183.       DisplayLastError(ps,hWnd);
  184.       return;
  185.     }
  186.     sh=OpenService(hsm,"Poweroff",DELETE);
  187.     if (sh==NULL)
  188.     {
  189.       DisplayLastError(ps,hWnd);
  190.       CloseServiceHandle(hsm);
  191.       return;
  192.     }
  193.     if (!DeleteService(sh))
  194.     {
  195.       DisplayLastError(ps,hWnd);
  196.     }
  197.     CloseServiceHandle(sh);
  198.     CloseServiceHandle(hsm);
  199.     DisplayInformation(ps,hWnd,"Poweroff service succesfully deleted");
  200.   }
  201.   DeleteRegistryKey(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Poweroff\\Parameters");
  202.   Log("RemovePoweroffService end");
  203. }
  204.  
  205. VOID WINAPI ServiceHandlerProcedure(DWORD fdwControl)
  206. {
  207.   Log("ServiceHandlerProcedure start, fdwControl=%d",fdwControl);
  208.   switch (fdwControl)
  209.   {
  210.     case SERVICE_CONTROL_STOP:
  211.       status.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
  212.       status.dwCurrentState=SERVICE_STOPPED;
  213.       status.dwControlsAccepted=SERVICE_ACCEPT_STOP;
  214.       status.dwWin32ExitCode=NO_ERROR;
  215.       status.dwCheckPoint++;
  216.       status.dwWaitHint=1000;
  217.       SetServiceStatus(sh,&status);
  218.       RemoveFromTray(g_hWnd);
  219.       Cleanup(NULL);
  220.       SetTimer(g_hWnd,ID_STOP_TIMER,1000,NULL);
  221.       break;
  222.     case SERVICE_CONTROL_PAUSE:
  223.       break;
  224.     case SERVICE_CONTROL_CONTINUE:
  225.       break;
  226.     case SERVICE_CONTROL_INTERROGATE:
  227.       status.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
  228.       status.dwCurrentState=SERVICE_RUNNING;
  229.       status.dwControlsAccepted=SERVICE_ACCEPT_STOP;
  230.       status.dwWin32ExitCode=NO_ERROR;
  231.       status.dwCheckPoint++;
  232.       status.dwWaitHint=1000;
  233.       SetServiceStatus(sh,&status);
  234.       break;
  235.     case SERVICE_CONTROL_SHUTDOWN:
  236.       status.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
  237.       status.dwCurrentState=SERVICE_STOPPED;
  238.       status.dwControlsAccepted=SERVICE_ACCEPT_STOP;
  239.       status.dwWin32ExitCode=NO_ERROR;
  240.       status.dwCheckPoint++;
  241.       status.dwWaitHint=1000;
  242.       SetServiceStatus(sh,&status);
  243.       SendMessage(g_hWnd,WM_QUIT,0,0);
  244.       break;
  245.   }
  246.   Log("ServiceHandlerProcedure end");
  247. }
  248.  
  249. VOID WINAPI ServiceProcedure(DWORD dwArgc,LPTSTR *lpszArgv)
  250. {
  251.   Log("ServiceProcedure start");
  252.   sh=RegisterServiceCtrlHandler("Poweroff",ServiceHandlerProcedure);
  253.   if (sh==0)
  254.   {
  255.     return;
  256.   }
  257.   status.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
  258.   status.dwCurrentState=SERVICE_START_PENDING;
  259.   status.dwControlsAccepted=SERVICE_ACCEPT_STOP;
  260.   status.dwWin32ExitCode=NO_ERROR;
  261.   status.dwCheckPoint=0;
  262.   status.dwWaitHint=1000;
  263.   SetServiceStatus(sh,&status);
  264.   status.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
  265.   status.dwCurrentState=SERVICE_RUNNING;
  266.   status.dwControlsAccepted=SERVICE_ACCEPT_STOP;
  267.   status.dwWin32ExitCode=NO_ERROR;
  268.   status.dwCheckPoint=0;
  269.   status.dwWaitHint=1000;
  270.   SetServiceStatus(sh,&status);
  271.   Log("Waiting for service to start");
  272.   while (status.dwCurrentState==SERVICE_RUNNING)
  273.     Sleep(500);
  274.   Log("ServiceProcedure end");
  275.  
  276. DWORD WINAPI CheckService(PowerSettings *ps)
  277. {
  278.   SERVICE_TABLE_ENTRY service_table[2];
  279.  
  280.   Log("CheckService start");
  281.   if (ps->run_as_service && ps->windowsversion.dwPlatformId!=VER_PLATFORM_WIN32_WINDOWS)
  282.   {
  283.     Log("Starting as NT service");
  284.     service_table[0].lpServiceName="Poweroff";
  285.     service_table[0].lpServiceProc=ServiceProcedure;
  286.     service_table[1].lpServiceName=NULL;
  287.     service_table[1].lpServiceProc=NULL;
  288.     StartServiceCtrlDispatcher(service_table);
  289.   }
  290.   else if (ps->run_as_service)
  291.   {
  292.     HMODULE hm;
  293.     DWORD (WINAPI * RegisterServiceProcess)(DWORD dwProcessId,DWORD dwType);
  294.  
  295.     Log("Starting as WIN98 service");
  296.     hm=LoadLibrary("kernel32");
  297.     if (hm==NULL)
  298.     {
  299.       DisplayLastError(ps,NULL);
  300.       return 0;
  301.     }
  302.     RegisterServiceProcess=(void*)GetProcAddress(hm,"RegisterServiceProcess");
  303.     if (RegisterServiceProcess==NULL)
  304.     {
  305.       DisplayLastError(ps,NULL);
  306.       return 0;
  307.     }
  308.     RegisterServiceProcess(0,1);
  309.     FreeLibrary(hm);
  310.   }
  311.   Log("CheckService end");
  312.   return 0;
  313. }
  314.  
  315. int IsPoweroffServiceRunning(HWND hWnd,PowerSettings *ps)
  316. {
  317.   Log("IsPoweroffServiceRunning start");
  318.   if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  319.   {
  320.     return 0;
  321.   }
  322.   else
  323.   {
  324.     SERVICE_STATUS ss;
  325.     SC_HANDLE hsm,sh;
  326.  
  327.     hsm=OpenSCManager(NULL,NULL,GENERIC_READ);
  328.     if (hsm==NULL)
  329.     {
  330.       return 0;
  331.     }
  332.     sh=OpenService(hsm,"Poweroff",SERVICE_QUERY_STATUS);
  333.     if (sh==NULL)
  334.     {
  335.       CloseServiceHandle(hsm);
  336.       return 0;
  337.     }
  338.     if (!QueryServiceStatus(sh,&ss))
  339.     {
  340.       CloseServiceHandle(sh);
  341.       CloseServiceHandle(hsm);
  342.       return 0;
  343.     }
  344.     CloseServiceHandle(sh);
  345.     CloseServiceHandle(hsm);
  346.     if (ss.dwCurrentState==SERVICE_RUNNING)
  347.       return 1;
  348.   }
  349.   Log("IsPoweroffServiceRunning stop");
  350.   return 0;
  351. }
  352.  
  353. void StartPoweroffService(HWND hWnd,PowerSettings *ps)
  354. {
  355.   SC_HANDLE hsm,sh;
  356.  
  357.   Log("StartPoweroffService start");
  358.   if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  359.   {
  360.   }
  361.   else
  362.   {
  363.     hsm=OpenSCManager(NULL,NULL,GENERIC_WRITE);
  364.     if (hsm==NULL)
  365.     {
  366.       DisplayLastError(ps,hWnd);
  367.       return;
  368.     }
  369.     sh=OpenService(hsm,"Poweroff",SERVICE_START);
  370.     if (sh==NULL)
  371.     {
  372.       DisplayLastError(ps,hWnd);
  373.       CloseServiceHandle(hsm);
  374.       return;
  375.     }
  376.     if (!StartService(sh,0,NULL))
  377.     {
  378.       DisplayLastError(ps,hWnd);
  379.     }
  380.     CloseServiceHandle(sh);
  381.     CloseServiceHandle(hsm);
  382.   }
  383.   Log("StartPoweroffService end");
  384. }
  385.  
  386. void StopPoweroffService(HWND hWnd,PowerSettings *ps)
  387. {
  388.   SC_HANDLE hsm,sh;
  389.  
  390.   Log("StopPoweroffService start");
  391.   if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  392.   {
  393.   }
  394.   else
  395.   {
  396.     SERVICE_STATUS ss;
  397.  
  398.     hsm=OpenSCManager(NULL,NULL,GENERIC_WRITE);
  399.     if (hsm==NULL)
  400.     {
  401.       DisplayLastError(ps,hWnd);
  402.       return;
  403.     }
  404.     sh=OpenService(hsm,"Poweroff",SERVICE_STOP);
  405.     if (sh==NULL)
  406.     {
  407.       DisplayLastError(ps,hWnd);
  408.       CloseServiceHandle(hsm);
  409.       return;
  410.     }
  411.     if (!ControlService(sh,SERVICE_CONTROL_STOP,&ss))
  412.     {
  413.       DisplayLastError(ps,hWnd);
  414.     }
  415.     CloseServiceHandle(sh);
  416.     CloseServiceHandle(hsm);
  417.   }
  418.   Log("StopPoweroffService end");
  419. }
  420.