home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / winnt / pop3 / service.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  6KB  |  244 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples.
  4. *       Copyright (C) 1992-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. //+---------------------------------------------------------------------------
  13. //
  14. //  File:       service.c
  15. //
  16. //  Contents:
  17. //
  18. //  Classes:
  19. //
  20. //  Functions:
  21. //
  22. //----------------------------------------------------------------------------
  23.  
  24. #include "pop3srvp.h"
  25. #pragma hdrstop
  26.  
  27. SERVICE_STATUS_HANDLE   hService = 0;
  28. WCHAR                   wszServiceName[] = APPLICATION_NAME;
  29. SERVICE_STATUS          ServiceStatus;
  30.  
  31. extern  BOOLEAN fService;
  32. extern  BOOLEAN fTestMode;
  33. #if DBG
  34. extern  void TestLoop(void);
  35. #endif
  36.  
  37. SOCKET sListener;
  38. HANDLE  hCompletionPort;
  39. WSADATA WsaData;
  40. BOOL bServiceTerminating = FALSE;
  41.  
  42. //+---------------------------------------------------------------------------
  43. //
  44. //  Function:   ServiceControlHandler
  45. //
  46. //  Synopsis:   Handles requests from the service controller.
  47. //
  48. //  Arguments:  [fdwControl] -- Request code
  49. //
  50. //  History:    1-11-95   RichardW   Created
  51. //
  52. //  Notes:
  53. //
  54. //----------------------------------------------------------------------------
  55. VOID
  56. WINAPI
  57. ServiceControlHandler(
  58.     DWORD           fdwControl)
  59. {
  60.     switch (fdwControl)
  61.     {
  62.         case SERVICE_CONTROL_STOP:
  63.  
  64.             UpdateServiceStatus(SERVICE_STOP_PENDING);
  65.  
  66.             //
  67.             // Remember that the service is terminating.
  68.             //
  69.  
  70.             bServiceTerminating = TRUE;
  71.  
  72.             //
  73.             // Close the completion port and the listening socket.
  74.             // These actions will cause the other threads to exit.
  75.             //
  76.  
  77.             closesocket( sListener );
  78.             CloseHandle( hCompletionPort );
  79.  
  80.             UpdateServiceStatus(SERVICE_STOPPED);
  81.             return;
  82.  
  83.         case SERVICE_CONTROL_INTERROGATE:
  84.             UpdateServiceStatus(ServiceStatus.dwCurrentState);
  85.             return;
  86.  
  87.         default:
  88.             return;
  89.     }
  90.  
  91. }
  92.  
  93. //+---------------------------------------------------------------------------
  94. //
  95. //  Function:   NotifyServiceController
  96. //
  97. //  Synopsis:   Notifies the service controller of our control entry point,
  98. //              and tells it that we're trying to start up.
  99. //
  100. //  Arguments:  (none)
  101. //
  102. //  Algorithm:
  103. //
  104. //  History:    1-11-95   RichardW   Created
  105. //
  106. //  Notes:
  107. //
  108. //----------------------------------------------------------------------------
  109. BOOL
  110. NotifyServiceController(
  111.             VOID)
  112. {
  113.     if (!fService)
  114.     {
  115.         return(TRUE);
  116.     }
  117.     ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  118.     ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  119.     ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  120.     ServiceStatus.dwWin32ExitCode = 0;
  121.     ServiceStatus.dwServiceSpecificExitCode = 0;
  122.     ServiceStatus.dwCheckPoint = 0;
  123.     ServiceStatus.dwWaitHint = 0;
  124.  
  125.     hService = RegisterServiceCtrlHandler(wszServiceName, ServiceControlHandler);
  126.  
  127.     if (hService)
  128.     {
  129.         UpdateServiceStatus(SERVICE_START_PENDING);
  130.         return(TRUE);
  131.     }
  132.     else
  133.         return(FALSE);
  134.  
  135. }
  136.  
  137. BOOL
  138. UpdateServiceStatus(DWORD   Status)
  139. {
  140.     if (hService)
  141.     {
  142.         ServiceStatus.dwCurrentState = Status;
  143.         if ((Status == SERVICE_START_PENDING) || (Status == SERVICE_STOP_PENDING))
  144.         {
  145.             ServiceStatus.dwCheckPoint ++;
  146.             ServiceStatus.dwWaitHint = 5000;    // 5 sec.
  147.         }
  148.         else
  149.         {
  150.             ServiceStatus.dwCheckPoint = 0;
  151.             ServiceStatus.dwWaitHint = 0;
  152.         }
  153.  
  154.         return(SetServiceStatus(hService, &ServiceStatus));
  155.     }
  156.  
  157.     return(FALSE);
  158. }
  159.  
  160. void
  161. FailServiceStart(
  162.     DWORD           Win32Code,
  163.     DWORD           PrivateCode)
  164. {
  165.     ServiceStatus.dwWin32ExitCode = Win32Code;
  166.     ServiceStatus.dwServiceSpecificExitCode = PrivateCode;
  167.     UpdateServiceStatus(SERVICE_STOPPED);
  168.  
  169. }
  170.  
  171. void
  172. WINAPI
  173. Pop3SrvMain(
  174.     DWORD       argc,
  175.     LPTSTR      argv[])
  176. {
  177.     int error;
  178.  
  179.     if (!NotifyServiceController())
  180.     {
  181.         DebugLog((DEB_ERROR, "Could not contact service controller\n"));
  182.         return;
  183.     }
  184.  
  185.     if (!InitializeEvents())
  186.     {
  187.         DebugLog((DEB_ERROR, "Could not initialize events\n"));
  188.         FailServiceStart(GetLastError(), 0);
  189.         return;
  190.     }
  191.  
  192.     UpdateServiceStatus(SERVICE_START_PENDING);
  193.  
  194.     if (!ReadParameters())
  195.     {
  196.         DebugLog((DEB_ERROR, "Could not read parameters!\n"));
  197.         FailServiceStart(GetLastError(), 0);
  198.         return;
  199.     }
  200.  
  201.     UpdateServiceStatus(SERVICE_START_PENDING);
  202.  
  203.  
  204.     ReportServiceEvent(
  205.         EVENTLOG_INFORMATION_TYPE,
  206.         POP3EVENT_SERVICE_STARTED,
  207.         0, NULL, 0);
  208.  
  209.  
  210.     if (fTestMode)
  211.     {
  212. #if DBG
  213.         TestLoop();
  214. #endif
  215.     }
  216.     else
  217.     {
  218.  
  219.         error = WSAStartup( 0x0101, &WsaData );
  220.         if ( error == SOCKET_ERROR ) {
  221.             printf( "WSAStartup failed.\n" );
  222.         }
  223.  
  224.         UpdateServiceStatus(SERVICE_START_PENDING);
  225.  
  226.         //
  227.         // Initialize the POP3SRV worker threads.
  228.         //
  229.  
  230.         hCompletionPort = InitializeThreads( );
  231.         if ( hCompletionPort == NULL ) {
  232.             printf( "it failed.\n" );
  233.         }
  234.  
  235.         UpdateServiceStatus(SERVICE_RUNNING);
  236.  
  237.         //
  238.         // Start accepting and processing clients.
  239.         //
  240.  
  241.         AcceptClients( hCompletionPort );
  242.     }
  243. }
  244.