home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 217 / DPCS0306DVD.ISO / Toolkit / Internet / FileZilla / Server / FileZilla_Server-0.9.11.exe / source / Service.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-03-11  |  13.3 KB  |  545 lines

  1. // FileZilla Server - a Windows ftp server
  2.  
  3. // Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
  4.  
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9.  
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14.  
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. // Based upon example code from Nishant S
  20. // Original code is available under http://www.codeproject.com/system/serviceskeleton.asp
  21.  
  22. #include "stdafx.h"
  23. #include "server.h"
  24. #include "Options.h"
  25. #include "misc/ExceptionReport.h"
  26.  
  27. void ServiceMain(DWORD argc, LPTSTR *argv); 
  28. void ServiceCtrlHandler(DWORD nControlCode);
  29. BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
  30.                      DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
  31.                      DWORD dwWaitHint);
  32. BOOL StartServiceThread();
  33. DWORD ServiceExecutionThread(LPDWORD param);
  34. HANDLE hServiceThread=0;
  35. void KillService();
  36.  
  37. char *strServiceName = "FileZilla Server Service";
  38. SERVICE_STATUS_HANDLE nServiceStatusHandle = 0; 
  39. HANDLE killServiceEvent = 0;
  40. BOOL nServiceRunning = 0;
  41. DWORD nServiceCurrentStatus = 0;
  42.  
  43. int SetAdminPort(LPCTSTR pszPort);
  44. int ReloadConfig();
  45. int CompatMain(LPCTSTR lpCmdLine);
  46.  
  47. int APIENTRY WinMain(HINSTANCE hInstance,
  48.                      HINSTANCE hPrevInstance,
  49.                      LPSTR     lpCmdLine,
  50.                      int       nCmdShow )
  51. {
  52.     BOOL bNT = FALSE;
  53.     BOOL bInstalled = FALSE;
  54.     BOOL dwCurrentState = 0;
  55.     
  56.     int nAction = 0;
  57.     if (lpCmdLine[0] == '/' || lpCmdLine[0] == '-')
  58.     {
  59.         lpCmdLine++;
  60.         if (_tcslen(lpCmdLine) >= 6 && !_tcsncmp(lpCmdLine, "compat", 6))
  61.         {
  62.             lpCmdLine += 6;
  63.             while (lpCmdLine[0] == ' ')
  64.                 lpCmdLine++;
  65.             return CompatMain(lpCmdLine);
  66.         }
  67.         else if (!_tcscmp(lpCmdLine, "install"))
  68.             nAction = 1;
  69.         else if (!_tcscmp(lpCmdLine, "uninstall"))
  70.             nAction = 2;
  71.         else if (!_tcscmp(lpCmdLine, "start"))
  72.             nAction = 3;
  73.         else if (!_tcscmp(lpCmdLine, "stop"))
  74.             nAction = 4;
  75.         else if (!_tcscmp(lpCmdLine, "install auto"))
  76.             nAction = 5;
  77.         else if (_tcslen(lpCmdLine) >= 10 && !_tcsncmp(lpCmdLine, "adminport ", 10))
  78.             nAction = 6;
  79.         else if (!_tcscmp(lpCmdLine, "reload-config"))
  80.             nAction = 7;
  81.     }
  82.  
  83.     if (nAction == 6)
  84.         return SetAdminPort(lpCmdLine + 10);
  85.     else if (nAction == 7)
  86.         return ReloadConfig();
  87.     
  88.     SC_HANDLE hService, hScm;
  89.     hScm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
  90.     
  91.     if (hScm)
  92.     {
  93.         bNT = TRUE;
  94.         hService = OpenService(hScm, "FileZilla Server", GENERIC_READ);
  95.         if (hService)
  96.         {
  97.             bInstalled = TRUE;
  98.  
  99.             SERVICE_STATUS ServiceStatus;
  100.             if (QueryServiceStatus(hService, &ServiceStatus))
  101.             {
  102.                 dwCurrentState = ServiceStatus.dwCurrentState;
  103.                 if (dwCurrentState == SERVICE_START_PENDING)
  104.                 {
  105.                     CloseServiceHandle(hService);
  106.                     CloseServiceHandle(hScm);
  107.                     
  108.                     SERVICE_TABLE_ENTRY servicetable[]=
  109.                     {
  110.                         {strServiceName,(LPSERVICE_MAIN_FUNCTION)ServiceMain},
  111.                         {NULL,NULL}
  112.                     };
  113.                     BOOL success;
  114.                     success=StartServiceCtrlDispatcher(servicetable);
  115.                     if (!success)
  116.                     {
  117.                         int nError=GetLastError();
  118.                         TCHAR buffer[1000];
  119.                         _stprintf(buffer, "StartServiceCtrlDispatcher failed with error %d", nError);
  120.                         MessageBox(0, buffer, "Error while starting service", MB_OK);
  121.                         //error occured
  122.                     }
  123.                     return 0;
  124.                 }
  125.             }
  126.  
  127.             CloseServiceHandle(hService);
  128.         }
  129.         CloseServiceHandle(hScm);
  130.     }
  131.     else
  132.     {
  133.         if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  134.         {
  135.             lpCmdLine--;
  136.             return CompatMain(lpCmdLine);
  137.         }
  138.     }
  139.         
  140.     if (!bInstalled)
  141.     {
  142.         if (nAction==1 || nAction==5 || (nAction == 0 && MessageBox(0, _T("Install Service?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES))
  143.         {
  144.             hScm=OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
  145.             if(!hScm)
  146.             {
  147.                 return 1;
  148.             }
  149.             int nStartMode = (nAction==5)?SERVICE_AUTO_START:SERVICE_DEMAND_START;
  150.             if (!nAction)
  151.                 if (MessageBox(0, _T("Autostart service?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)
  152.                     nStartMode = SERVICE_AUTO_START;
  153.             TCHAR buffer[MAX_PATH+1];
  154.             GetModuleFileName(0, buffer, MAX_PATH);
  155.             hService=CreateService(hScm, "FileZilla Server",
  156.                 "FileZilla Server FTP server",
  157.                 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS, nStartMode,
  158.                 SERVICE_ERROR_NORMAL,
  159.                 buffer,
  160.                 0, 0, 0, 0, 0);
  161.             if(!hService)
  162.             {
  163.                 CloseServiceHandle(hScm);
  164.                 return 1;
  165.             }
  166.             CloseServiceHandle(hService);
  167.             CloseServiceHandle(hScm);
  168.             dwCurrentState = SERVICE_STOPPED;
  169.         }
  170.         else
  171.             return 0;
  172.     }
  173.         
  174.     if (dwCurrentState == SERVICE_STOPPED && (nAction==3 || (nAction == 0 && MessageBox(0, _T("Start server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
  175.     {
  176.         SC_HANDLE hService,hScm;
  177.         hScm=OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
  178.         if(!hScm)
  179.         {
  180.             return 1;
  181.         }
  182.         hService=OpenService(hScm, "FileZilla Server", SERVICE_ALL_ACCESS);
  183.         if(!hService)
  184.         {
  185.             CloseServiceHandle(hScm);
  186.             return 1;
  187.         }
  188.         StartService(hService, 0, NULL);
  189.         CloseServiceHandle(hService);
  190.         CloseServiceHandle(hScm);
  191.         return 0;
  192.     }
  193.  
  194.     if (dwCurrentState == SERVICE_STOPPED && (nAction==2 || (nAction == 0 && MessageBox(0, _T("Uninstall Service?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
  195.     {
  196.         SC_HANDLE hService,hScm;
  197.         hScm=OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
  198.         if(!hScm)
  199.         {
  200.             return 1;
  201.         }
  202.         hService=OpenService(hScm,"FileZilla Server",SERVICE_ALL_ACCESS);
  203.         if(!hService)
  204.         {
  205.             CloseServiceHandle(hScm);
  206.             return 1;
  207.         }
  208.         DeleteService(hService);
  209.         CloseServiceHandle(hService);
  210.         CloseServiceHandle(hScm);
  211.         return 0;
  212.     }
  213.  
  214.     if (dwCurrentState != SERVICE_STOPPED && (nAction==4 || (nAction == 0 && MessageBox(0, _T("Stop Server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
  215.     {
  216.         SC_HANDLE hService,hScm;
  217.         hScm=OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
  218.         if(!hScm)
  219.         {
  220.             return 1;
  221.         }
  222.         hService=OpenService(hScm,"FileZilla Server",SERVICE_ALL_ACCESS);
  223.         if(!hService)
  224.         {
  225.             CloseServiceHandle(hScm);
  226.             return 1;
  227.         }
  228.         SERVICE_STATUS status;
  229.         ControlService(hService, SERVICE_CONTROL_STOP, &status);
  230.         CloseServiceHandle(hService);
  231.         CloseServiceHandle(hScm);
  232.         return 0;
  233.     }
  234.         
  235.     if (dwCurrentState == SERVICE_STOPPED)
  236.         return 0;
  237.  
  238.     return 0;
  239. }
  240.  
  241. void ServiceMain(DWORD argc, LPTSTR *argv)
  242. {
  243.     BOOL success;
  244.     nServiceStatusHandle=RegisterServiceCtrlHandler(strServiceName,
  245.         (LPHANDLER_FUNCTION)ServiceCtrlHandler);
  246.     if(!nServiceStatusHandle)
  247.     {
  248.         return;
  249.     }
  250.     success=UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,3000);
  251.     if(!success)
  252.     {
  253.         return;
  254.     }
  255.     killServiceEvent=CreateEvent(0,TRUE,FALSE,0);
  256.     if(killServiceEvent==NULL)
  257.     {
  258.         return;
  259.     }
  260.     success=UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,2,1000);
  261.     if(!success)
  262.     {
  263.         return;
  264.     }
  265.     success=StartServiceThread();
  266.     if(!success)
  267.     {
  268.         return;
  269.     }
  270.     nServiceCurrentStatus=SERVICE_RUNNING;
  271.     success=UpdateServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0);
  272.     if(!success)
  273.     {
  274.         return;
  275.     }
  276.     WaitForSingleObject(killServiceEvent, INFINITE);
  277.     CloseHandle(killServiceEvent);
  278.     WaitForSingleObject(hServiceThread, INFINITE);
  279.     CloseHandle(hServiceThread);
  280.     UpdateServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0, 0);
  281. }
  282.  
  283.  
  284.  
  285. BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
  286.                      DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
  287.                      DWORD dwWaitHint)
  288. {
  289.     BOOL success;
  290.     SERVICE_STATUS nServiceStatus;
  291.     nServiceStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
  292.     nServiceStatus.dwCurrentState=dwCurrentState;
  293.     if(dwCurrentState==SERVICE_START_PENDING)
  294.     {
  295.         nServiceStatus.dwControlsAccepted=0;
  296.     }
  297.     else
  298.     {
  299.         nServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP            
  300.             |SERVICE_ACCEPT_SHUTDOWN;
  301.     }
  302.     if(dwServiceSpecificExitCode==0)
  303.     {
  304.         nServiceStatus.dwWin32ExitCode=dwWin32ExitCode;
  305.     }
  306.     else
  307.     {
  308.         nServiceStatus.dwWin32ExitCode=ERROR_SERVICE_SPECIFIC_ERROR;
  309.     }
  310.     nServiceStatus.dwServiceSpecificExitCode=dwServiceSpecificExitCode;
  311.     nServiceStatus.dwCheckPoint=dwCheckPoint;
  312.     nServiceStatus.dwWaitHint=dwWaitHint;
  313.  
  314.     success=SetServiceStatus(nServiceStatusHandle,&nServiceStatus);
  315.     if(!success)
  316.     {
  317.         KillService();
  318.         return success;
  319.     }
  320.     else
  321.         return success;
  322. }
  323.  
  324. BOOL StartServiceThread()
  325. {    
  326.     DWORD id;
  327.     hServiceThread=CreateThread(0,0,
  328.         (LPTHREAD_START_ROUTINE)ServiceExecutionThread,
  329.         0,0,&id);
  330.     if(hServiceThread==0)
  331.     {
  332.         return false;
  333.     }
  334.     else
  335.     {
  336.         nServiceRunning=true;
  337.         return true;
  338.     }
  339. }
  340.  
  341. void KillService()
  342. {
  343.     if (hMainWnd)
  344.         PostMessage(hMainWnd, WM_CLOSE, 0, 0);
  345.     nServiceRunning = false;
  346. }
  347.  
  348. void ServiceCtrlHandler(DWORD nControlCode)
  349. {
  350.     BOOL success;
  351.     switch(nControlCode)
  352.     {    
  353.     case SERVICE_CONTROL_SHUTDOWN:
  354.     case SERVICE_CONTROL_STOP:
  355.         nServiceCurrentStatus=SERVICE_STOP_PENDING;
  356.         success=UpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000);
  357.         KillService();        
  358.         return;
  359.     case 128:
  360.         {
  361.             // Reload config
  362.             HWND hWnd = FindWindow(_T("FileZilla Server Helper Window"), _T("FileZilla Server Helper Window"));
  363.  
  364.             if (hWnd)
  365.                 PostMessage(hWnd, WM_FILEZILLA_RELOADCONFIG, 0, 0);
  366.         }
  367.         break;
  368.     default:
  369.         break;
  370.     }
  371.     UpdateServiceStatus(nServiceCurrentStatus,NO_ERROR,0,0,0);
  372. }
  373.  
  374. DWORD ServiceExecutionThread(LPDWORD param)
  375. {
  376.     // initialize Winsock library
  377.     BOOL res=TRUE;
  378.     WSADATA wsaData;
  379.     
  380.     WORD wVersionRequested = MAKEWORD(1, 1);
  381.     int nResult = WSAStartup(wVersionRequested, &wsaData);
  382.     if (nResult != 0)
  383.         res=FALSE;
  384.     else if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
  385.     {
  386.         WSACleanup();
  387.         res=FALSE;
  388.     }
  389.  
  390.     if(!res)
  391.     {
  392.         SetEvent(killServiceEvent);
  393.         UpdateServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0, 0);
  394.         return 0;
  395.     }
  396.  
  397.     CExceptionReport ExceptionReport;
  398.  
  399.     CServer *pServer = new CServer;
  400.     VERIFY(pServer->Create());
  401.  
  402.     if (!nServiceRunning)
  403.         PostQuitMessage(0);
  404.     
  405.     MSG msg;
  406.     while (GetMessage(&msg, 0, 0, 0))
  407.     {
  408.         TranslateMessage(&msg);
  409.         DispatchMessage(&msg);
  410.     }
  411.  
  412.     delete pServer;
  413.     WSACleanup();
  414.  
  415.     SetEvent(killServiceEvent);
  416.     return 0;
  417. }
  418.  
  419. int SetAdminPort(LPCTSTR pszPort)
  420. {
  421.     int nAdminPort = _ttoi(pszPort);
  422.     if (nAdminPort < 1 || nAdminPort > 65535)
  423.         return 1;
  424.  
  425.     COptions *pOptions = new COptions();
  426.     pOptions->SetOption(OPTION_ADMINPORT, nAdminPort);
  427.     delete pOptions;
  428.  
  429.     pOptions = new COptions();
  430.     if (pOptions->GetOptionVal(OPTION_ADMINPORT) != nAdminPort)
  431.     {
  432.         delete pOptions;
  433.         return 1;
  434.     }
  435.     delete pOptions;
  436.  
  437.     return 0;
  438. }
  439.  
  440. int ReloadConfig()
  441. {
  442.     HWND hWnd = FindWindow(_T("FileZilla Server Helper Window"), _T("FileZilla Server Helper Window"));
  443.  
  444.     int res;
  445.     if (hWnd)
  446.         res = PostMessage(hWnd, WM_FILEZILLA_RELOADCONFIG, 0, 0) == 0;
  447.  
  448.     SC_HANDLE hService, hScm;
  449.     hScm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
  450.  
  451.     if (hScm)
  452.     {
  453.         hService = OpenService(hScm, "FileZilla Server", SERVICE_USER_DEFINED_CONTROL);
  454.         if (hService)
  455.         {
  456.             SERVICE_STATUS status;
  457.             res |= ControlService(hService, 128, &status) == 0;
  458.             CloseServiceHandle(hService);
  459.         }
  460.         CloseServiceHandle(hScm);
  461.     }
  462.  
  463.     return !res;
  464. }
  465.  
  466. int CompatMain(LPCTSTR lpCmdLine)
  467. {
  468.     int nAction = 0;
  469.  
  470.     if (lpCmdLine[0] == '/' || lpCmdLine[0] == '-')
  471.     {
  472.         lpCmdLine++;
  473.         if (!_tcscmp(lpCmdLine, "start"))
  474.             nAction = 1;
  475.         else if (!_tcscmp(lpCmdLine, "stop"))
  476.             nAction = 2;
  477.         else if (_tcslen(lpCmdLine) >= 10 && !_tcsncmp(lpCmdLine, "adminport ", 10))
  478.             nAction = 3;
  479.         else if (!_tcscmp(lpCmdLine, "install"))
  480.             return 0;
  481.         else if (!_tcscmp(lpCmdLine, "uninstall"))
  482.             return 0;
  483.         else if (!_tcscmp(lpCmdLine, "install auto"))
  484.             return 0;
  485.         else if (!_tcscmp(lpCmdLine, "reload-config"))
  486.             nAction = 4;
  487.     }
  488.  
  489.     if (nAction == 3)
  490.         return SetAdminPort(lpCmdLine + 10);
  491.     else if (nAction == 4)
  492.         return ReloadConfig();
  493.  
  494.     HWND hWnd = FindWindow(_T("FileZilla Server Helper Window"), _T("FileZilla Server Helper Window"));
  495.     if (nAction == 1 && hWnd)
  496.         return 0;
  497.     else if (nAction==2 && !hWnd)
  498.         return 0;
  499.     
  500.     if (!hWnd && (nAction == 1 || (nAction == 0 && MessageBox(0, _T("Start Server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
  501.     {
  502.         // initialize Winsock library
  503.         BOOL res=TRUE;
  504.         WSADATA wsaData;
  505.         
  506.         WORD wVersionRequested = MAKEWORD(1, 1);
  507.         int nResult = WSAStartup(wVersionRequested, &wsaData);
  508.         if (nResult != 0)
  509.             res=FALSE;
  510.         else if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
  511.         {
  512.             WSACleanup();
  513.             res=FALSE;
  514.         }
  515.         
  516.         if(!res)
  517.         {
  518.             return 1;
  519.         }
  520.         
  521.         CServer *pServer = new CServer;
  522.         VERIFY(pServer->Create());
  523.         
  524.         MSG msg;
  525.         while (GetMessage(&msg, 0, 0, 0))
  526.         {
  527.             TranslateMessage(&msg);
  528.             DispatchMessage(&msg);
  529.         }
  530.         
  531.         delete pServer;
  532.         WSACleanup();
  533.         return 0;
  534.     }        
  535.     else if (hWnd && (nAction == 2 || (nAction == 0 && MessageBox(0, _T("Stop Server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
  536.     {
  537.         SendMessage(hWnd, WM_CLOSE, 0, 0);
  538.         if (GetLastError())
  539.             return 1;
  540.         else
  541.             return 0;
  542.     }
  543.     
  544.     return 1;
  545. }