SIMPLE.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993-1997  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   simple.c
  9. //
  10. //  PURPOSE:  Implements the body of the service.
  11. //            The default behavior is to open a
  12. //            named pipe, \.pipesimple, and read
  13. //            from it.  It the modifies the data and
  14. //            writes it back to the pipe.
  15. //
  16. //  FUNCTIONS:
  17. //            ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
  18. //            ServiceStop( );
  19. //
  20. //  COMMENTS: The functions implemented in simple.c are
  21. //            prototyped in service.h
  22. //              
  23. //
  24. //  AUTHOR: Craig Link - Microsoft Developer Support
  25. //
  26. #include <windows.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <process.h>
  30. #include <tchar.h>
  31. #include "service.h"
  32. // this event is signalled when the
  33. // service should end
  34. //
  35. HANDLE  hServerStopEvent = NULL;
  36. //
  37. //  FUNCTION: ServiceStart
  38. //
  39. //  PURPOSE: Actual code of the service
  40. //           that does the work.
  41. //
  42. //  PARAMETERS:
  43. //    dwArgc   - number of command line arguments
  44. //    lpszArgv - array of command line arguments
  45. //
  46. //  RETURN VALUE:
  47. //    none
  48. //
  49. //  COMMENTS:
  50. //    The default behavior is to open a
  51. //    named pipe, \.pipesimple, and read
  52. //    from it.  It the modifies the data and
  53. //    writes it back to the pipe.  The service
  54. //    stops when hServerStopEvent is signalled
  55. //
  56. VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
  57. {
  58.     HANDLE                  hPipe = INVALID_HANDLE_VALUE;
  59.     HANDLE                  hEvents[2] = {NULL, NULL};
  60.     OVERLAPPED              os;
  61.     PSECURITY_DESCRIPTOR    pSD = NULL;
  62.     SECURITY_ATTRIBUTES     sa;
  63.     TCHAR                   szIn[80];
  64.     TCHAR                   szOut[80];
  65.     LPTSTR                  lpszPipeName = TEXT("\\.\pipe\simple");
  66.     BOOL                    bRet;
  67.     DWORD                   cbRead;
  68.     DWORD                   cbWritten;
  69.     DWORD                   dwWait;
  70.     UINT                    ndx;
  71.     ///////////////////////////////////////////////////
  72.     //
  73.     // Service initialization
  74.     //
  75.     // report the status to the service control manager.
  76.     //
  77.     if (!ReportStatusToSCMgr(
  78.         SERVICE_START_PENDING, // service state
  79.         NO_ERROR,              // exit code
  80.         3000))                 // wait hint
  81.         goto cleanup;
  82.     // create the event object. The control handler function signals
  83.     // this event when it receives the "stop" control code.
  84.     //
  85.     hServerStopEvent = CreateEvent(
  86.         NULL,    // no security attributes
  87.         TRUE,    // manual reset event
  88.         FALSE,   // not-signalled
  89.         NULL);   // no name
  90.     if ( hServerStopEvent == NULL)
  91.         goto cleanup;
  92.     hEvents[0] = hServerStopEvent;
  93.     // report the status to the service control manager.
  94.     //
  95.     if (!ReportStatusToSCMgr(
  96.         SERVICE_START_PENDING, // service state
  97.         NO_ERROR,              // exit code
  98.         3000))                 // wait hint
  99.         goto cleanup;
  100.     // create the event object object use in overlapped i/o
  101.     //
  102.     hEvents[1] = CreateEvent(
  103.         NULL,    // no security attributes
  104.         TRUE,    // manual reset event
  105.         FALSE,   // not-signalled
  106.         NULL);   // no name
  107.     if ( hEvents[1] == NULL)
  108.         goto cleanup;
  109.     // report the status to the service control manager.
  110.     //
  111.     if (!ReportStatusToSCMgr(
  112.         SERVICE_START_PENDING, // service state
  113.         NO_ERROR,              // exit code
  114.         3000))                 // wait hint
  115.         goto cleanup;
  116.     // create a security descriptor that allows anyone to write to
  117.     //  the pipe...
  118.     //
  119.     pSD = (PSECURITY_DESCRIPTOR) malloc( SECURITY_DESCRIPTOR_MIN_LENGTH );
  120.     if (pSD == NULL)
  121.         goto cleanup;
  122.     if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
  123.         goto cleanup;
  124.     // add a NULL disc. ACL to the security descriptor.
  125.     //
  126.     if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE))
  127.         goto cleanup;
  128.     sa.nLength = sizeof(sa);
  129.     sa.lpSecurityDescriptor = pSD;
  130.     sa.bInheritHandle = TRUE;
  131.     // report the status to the service control manager.
  132.     //
  133.     if (!ReportStatusToSCMgr(
  134.         SERVICE_START_PENDING, // service state
  135.         NO_ERROR,              // exit code
  136.         3000))                 // wait hint
  137.         goto cleanup;
  138.     // allow user tp define pipe name
  139.     for ( ndx = 1; ndx < dwArgc-1; ndx++ )
  140.     {
  141.         if ( ( (*(lpszArgv[ndx]) == TEXT('-')) ||
  142.                (*(lpszArgv[ndx]) == TEXT('/')) ) &&
  143.              _tcsicmp( TEXT("pipe"), lpszArgv[ndx]+1 ) == 0 )
  144.         {
  145.             lpszPipeName = lpszArgv[++ndx];
  146.         }
  147.     }
  148.     // open our named pipe...
  149.     //
  150.     hPipe = CreateNamedPipe(
  151.                     lpszPipeName         ,  // name of pipe
  152.                     FILE_FLAG_OVERLAPPED |
  153.                     PIPE_ACCESS_DUPLEX,     // pipe open mode
  154.                     PIPE_TYPE_MESSAGE |
  155.                     PIPE_READMODE_MESSAGE |
  156.                     PIPE_WAIT,              // pipe IO type
  157.                     1,                      // number of instances
  158.                     0,                      // size of outbuf (0 == allocate as necessary)
  159.                     0,                      // size of inbuf
  160.                     1000,                   // default time-out value
  161.                     &sa);                   // security attributes
  162.     if (hPipe == INVALID_HANDLE_VALUE) {
  163.         AddToMessageLog(TEXT("Unable to create named pipe"));
  164.         goto cleanup;
  165.     }
  166.     // report the status to the service control manager.
  167.     //
  168.     if (!ReportStatusToSCMgr(
  169.         SERVICE_RUNNING,       // service state
  170.         NO_ERROR,              // exit code
  171.         0))                    // wait hint
  172.         goto cleanup;
  173.     //
  174.     // End of initialization
  175.     //
  176.     ////////////////////////////////////////////////////////
  177.     ////////////////////////////////////////////////////////
  178.     //
  179.     // Service is now running, perform work until shutdown
  180.     //
  181.     while ( 1 )
  182.     {
  183.         // init the overlapped structure
  184.         //
  185.         memset( &os, 0, sizeof(OVERLAPPED) );
  186.         os.hEvent = hEvents[1];
  187.         ResetEvent( hEvents[1] );
  188.         // wait for a connection...
  189.         //
  190.         ConnectNamedPipe(hPipe, &os);
  191.         if ( GetLastError() == ERROR_IO_PENDING )
  192.         {
  193.             dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE );
  194.             if ( dwWait != WAIT_OBJECT_0+1 )     // not overlapped i/o event - error occurred,
  195.                 break;                           // or server stop signaled
  196.         }
  197.         // init the overlapped structure
  198.         //
  199.         memset( &os, 0, sizeof(OVERLAPPED) );
  200.         os.hEvent = hEvents[1];
  201.         ResetEvent( hEvents[1] );
  202.         // grab whatever's coming through the pipe...
  203.         //
  204.         bRet = ReadFile(
  205.                     hPipe,          // file to read from
  206.                     szIn,           // address of input buffer
  207.                     sizeof(szIn),   // number of bytes to read
  208.                     &cbRead,        // number of bytes read
  209.                     &os);           // overlapped stuff, not needed
  210.         if ( !bRet && ( GetLastError() == ERROR_IO_PENDING ) )
  211.         {
  212.             dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE );
  213.             if ( dwWait != WAIT_OBJECT_0+1 )     // not overlapped i/o event - error occurred,
  214.                 break;                           // or server stop signaled
  215.         }
  216.         // munge the string
  217.         //
  218.         _stprintf(szOut, TEXT("Hello! [%s]"), szIn);
  219.         // init the overlapped structure
  220.         //
  221.         memset( &os, 0, sizeof(OVERLAPPED) );
  222.         os.hEvent = hEvents[1];
  223.         ResetEvent( hEvents[1] );
  224.         // send it back out...
  225.         //
  226.         bRet = WriteFile(
  227.                     hPipe,          // file to write to
  228.                     szOut,          // address of output buffer
  229.                     sizeof(szOut),  // number of bytes to write
  230.                     &cbWritten,     // number of bytes written
  231.                     &os);           // overlapped stuff, not needed
  232.         if ( !bRet && ( GetLastError() == ERROR_IO_PENDING ) )
  233.         {
  234.             dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE );
  235.             if ( dwWait != WAIT_OBJECT_0+1 )     // not overlapped i/o event - error occurred,
  236.                 break;                           // or server stop signaled
  237.         }
  238.         // drop the connection...
  239.         //
  240.         DisconnectNamedPipe(hPipe);
  241.     }
  242.   cleanup:
  243.     if (hPipe != INVALID_HANDLE_VALUE )
  244.         CloseHandle(hPipe);
  245.     if (hServerStopEvent)
  246.         CloseHandle(hServerStopEvent);
  247.     if (hEvents[1]) // overlapped i/o event
  248.         CloseHandle(hEvents[1]);
  249.     if ( pSD )
  250.         free( pSD );
  251. }
  252. //
  253. //  FUNCTION: ServiceStop
  254. //
  255. //  PURPOSE: Stops the service
  256. //
  257. //  PARAMETERS:
  258. //    none
  259. //
  260. //  RETURN VALUE:
  261. //    none
  262. //
  263. //  COMMENTS:
  264. //    If a ServiceStop procedure is going to
  265. //    take longer than 3 seconds to execute,
  266. //    it should spawn a thread to execute the
  267. //    stop code, and return.  Otherwise, the
  268. //    ServiceControlManager will believe that
  269. //    the service has stopped responding.
  270. //    
  271. VOID ServiceStop()
  272. {
  273.     if ( hServerStopEvent )
  274.         SetEvent(hServerStopEvent);
  275. }