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

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) 1995-1997  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   server.c
  9. //
  10. //  PURPOSE:  Implements the body of the RPC service sample.
  11. //
  12. //  FUNCTIONS:
  13. //            Called by service.c:
  14. //            ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
  15. //            ServiceStop( );
  16. //
  17. //            Called by RPC:
  18. //            error_status_t Ping(handle_t)
  19. //
  20. //  COMMENTS: The ServerStart and ServerStop functions implemented here are
  21. //            prototyped in service.h.  The other functions are RPC manager
  22. //            functions prototypes in rpcsvc.h.
  23. //              
  24. //
  25. //  AUTHOR: Craig Link - Microsoft Developer Support
  26. //          Mario Goertzel - RPC Development
  27. //
  28. #include <windows.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <process.h>
  32. #include <tchar.h>
  33. #include <rpc.h>
  34. #include "service.h"
  35. #include "rpcsvc.h"
  36. //
  37. // RPC configuration.
  38. //
  39. // This service listens to all the protseqs listed in this array.
  40. // This should be read from the service's configuration in the
  41. // registery.
  42. TCHAR *ProtocolArray[] = { TEXT("ncalrpc"),
  43.                            TEXT("ncacn_ip_tcp"),
  44.                            TEXT("ncacn_np"),
  45.                            TEXT("ncadg_ip_udp")
  46.                          };
  47. // Used in RpcServerUseProtseq, for some protseqs
  48. // this is used as a hint for buffer size.
  49. ULONG ProtocolBuffer = 3;
  50. // Use in RpcServerListen().  More threads will increase performance,
  51. // but use more memory.
  52. ULONG MinimumThreads = 3;
  53. //
  54. //  FUNCTION: ServiceStart
  55. //
  56. //  PURPOSE: Actual code of the service
  57. //           that does the work.
  58. //
  59. //  PARAMETERS:
  60. //    dwArgc   - number of command line arguments
  61. //    lpszArgv - array of command line arguments
  62. //
  63. //  RETURN VALUE:
  64. //    none
  65. //
  66. //  COMMENTS:
  67. //    Starts the service listening for RPC requests.
  68. //
  69. VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
  70. {
  71.     UINT i;
  72.     RPC_BINDING_VECTOR *pbindingVector = 0;
  73.     RPC_STATUS status;
  74.     BOOL fListening = FALSE;
  75.     ///////////////////////////////////////////////////
  76.     //
  77.     // Service initialization
  78.     //
  79.     //
  80.     // Use protocol sequences (protseqs) specified in ProtocolArray.
  81.     //
  82.     for(i = 0; i < sizeof(ProtocolArray)/sizeof(TCHAR *); i++)
  83.         {
  84.         // Report the status to the service control manager.
  85.         if (!ReportStatusToSCMgr(
  86.             SERVICE_START_PENDING, // service state
  87.             NO_ERROR,              // exit code
  88.             3000))                 // wait hint
  89.             return;
  90.         status = RpcServerUseProtseq(ProtocolArray[i],
  91.                                      ProtocolBuffer,
  92.                                      0);
  93.         if (status == RPC_S_OK)
  94.             {
  95.             fListening = TRUE;
  96.             }
  97.         }
  98.     if (!fListening)
  99.         {
  100.         // Unable to listen to any protocol!
  101.         //
  102.         AddToMessageLog(TEXT("RpcServerUseProtseq() failedn"));
  103.         return;
  104.         }
  105.     // Report the status to the service control manager.
  106.     //
  107.     if (!ReportStatusToSCMgr(
  108.         SERVICE_START_PENDING, // service state
  109.         NO_ERROR,              // exit code
  110.         3000))                 // wait hint
  111.         return;
  112.     // Register the services interface(s).
  113.     //
  114.     status = RpcServerRegisterIf(RpcServiceSample_v1_0_s_ifspec,   // from rpcsvc.h
  115.                                  0,
  116.                                  0);
  117.     if (status != RPC_S_OK)
  118.         return;
  119.     // Report the status to the service control manager.
  120.     //
  121.     if (!ReportStatusToSCMgr(
  122.         SERVICE_START_PENDING, // service state
  123.         NO_ERROR,              // exit code
  124.         3000))                 // wait hint
  125.         return;
  126.     // Register interface(s) and binding(s) (endpoints) with
  127.     // the endpoint mapper.
  128.     //
  129.     status = RpcServerInqBindings(&pbindingVector);
  130.     if (status != RPC_S_OK)
  131.         {
  132.         return;
  133.         }
  134.     status = RpcEpRegister(RpcServiceSample_v1_0_s_ifspec,   // from rpcsvc.h
  135.                            pbindingVector,
  136.                            0,
  137.                            0);
  138.     if (status != RPC_S_OK)
  139.         {
  140.         return;
  141.         }
  142.     // Report the status to the service control manager.
  143.     //
  144.     if (!ReportStatusToSCMgr(
  145.         SERVICE_START_PENDING, // service state
  146.         NO_ERROR,              // exit code
  147.         3000))                 // wait hint
  148.         return;
  149.     // Enable NT LM Security Support Provider (NtLmSsp service)
  150.     //
  151.     status = RpcServerRegisterAuthInfo(0,
  152.                                        RPC_C_AUTHN_WINNT,
  153.                                        0,
  154.                                        0
  155.                                        );
  156.     if (status != RPC_S_OK)
  157.         {
  158.         return;
  159.         }
  160.     // Report the status to the service control manager.
  161.     //
  162.     if (!ReportStatusToSCMgr(
  163.         SERVICE_START_PENDING, // service state
  164.         NO_ERROR,              // exit code
  165.         3000))                 // wait hint
  166.         return;
  167.     // Start accepting client calls.
  168.     //
  169.     status = RpcServerListen(MinimumThreads,
  170.                              RPC_C_LISTEN_MAX_CALLS_DEFAULT,  // rpcdce.h
  171.                              TRUE);                           // don't block.
  172.     if (status != RPC_S_OK)
  173.         {
  174.         return;
  175.         }
  176.     // Report the status to the service control manager.
  177.     //
  178.     if (!ReportStatusToSCMgr(
  179.         SERVICE_RUNNING,       // service state
  180.         NO_ERROR,              // exit code
  181.         0))                    // wait hint
  182.         return;
  183.     //
  184.     // End of initialization
  185.     //
  186.     ////////////////////////////////////////////////////////////
  187.     ////////////////////////////////////////////////////////////
  188.     //
  189.     // Cleanup
  190.     //
  191.     // RpcMgmtWaitServerListen() will block until the server has
  192.     // stopped listening.  If this service had something better to
  193.     // do with this thread, it would delay this call until
  194.     // ServiceStop() had been called. (Set an event in ServiceStop()).
  195.     //
  196.     status = RpcMgmtWaitServerListen();
  197.     // ASSERT(status == RPC_S_OK)
  198.     // Remove entries from the endpoint mapper database.
  199.     //
  200.     RpcEpUnregister(RpcServiceSample_v1_0_s_ifspec,   // from rpcsvc.h
  201.                     pbindingVector,
  202.                     0);
  203.     // Delete the binding vector
  204.     //
  205.     RpcBindingVectorFree(&pbindingVector);
  206.     //
  207.     ////////////////////////////////////////////////////////////
  208.     return;
  209. }
  210. //
  211. //  FUNCTION: ServiceStop
  212. //
  213. //  PURPOSE: Stops the service
  214. //
  215. //  PARAMETERS:
  216. //    none
  217. //
  218. //  RETURN VALUE:
  219. //    none
  220. //
  221. //  COMMENTS:
  222. //    If a ServiceStop procedure is going to
  223. //    take longer than 3 seconds to execute,
  224. //    it should spawn a thread to execute the
  225. //    stop code, and return.  Otherwise, the
  226. //    ServiceControlManager will believe that
  227. //    the service has stopped responding.
  228. //    
  229. VOID ServiceStop()
  230. {
  231.     // Stop's the server, wakes the main thread.
  232.     RpcMgmtStopServerListening(0);
  233. }
  234. //
  235. //  FUNCTION: Ping
  236. //
  237. //  PURPOSE: Implements the Ping() operation.
  238. //
  239. //  PARAMETERS:
  240. //    none
  241. //
  242. //  RETURN VALUE:
  243. //    none
  244. //
  245. //  COMMENTS:
  246. //    Ping() operation defined in rpcsvc.idl.
  247. //    Used by clients to test the connection.
  248. //
  249. error_status_t
  250. Ping(
  251.     handle_t h
  252.     )
  253. {
  254.     return(0);
  255. }
  256. //
  257. //  FUNCTIONS: BufferIn1, BufferIn2, BufferIn3
  258. //
  259. //  PURPOSE: Implements three different methods
  260. //           for sending data to the server.
  261. //
  262. //  PARAMETERS:
  263. //    see rpcsvc.idl
  264. //
  265. //  RETURN VALUE:
  266. //    error_status_t - 0;
  267. //
  268. error_status_t
  269. BufferIn1(
  270.          handle_t h,
  271.          byte Buffer[],
  272.          unsigned long Length,
  273.          unsigned long Size
  274.          )
  275. {
  276.     return(0);
  277. }
  278. error_status_t
  279. BufferIn2(
  280.          handle_t h,
  281.          byte Buffer[],
  282.          unsigned long Length
  283.          )
  284. {
  285.     return(0);
  286. }
  287. error_status_t
  288. BufferIn3(
  289.          handle_t h,
  290.          byte Buffer[],
  291.          unsigned long Length
  292.          )
  293. {
  294.     return(0);
  295. }
  296. //
  297. //  FUNCTIONS: BufferOut1, BufferOut2, BufferOut3, BufferOut4
  298. //
  299. //  PURPOSE: Implements four different methods
  300. //           for reading data from the server.
  301. //
  302. //  PARAMETERS:
  303. //    see rpcsvc.idl
  304. //
  305. //  RETURN VALUE:
  306. //    error_status_t - 0;
  307. //
  308. error_status_t
  309. BufferOut1(
  310.          handle_t h,
  311.          byte Buffer[],
  312.          unsigned long *pLength
  313.          )
  314. {
  315.     *pLength = BUFFER_SIZE;
  316.     return(0);
  317. }
  318. error_status_t
  319. BufferOut2(
  320.           handle_t h,
  321.           byte Buffer[],
  322.           unsigned long Size,
  323.           unsigned long *pLength
  324.           )
  325. {
  326.     *pLength = BUFFER_SIZE;
  327.     return(0);
  328. }
  329. error_status_t
  330. BufferOut3(
  331.           handle_t h,
  332.           BUFFER *pBuffer
  333.           )
  334. {
  335.     pBuffer->BufferLength = BUFFER_SIZE;
  336.     pBuffer->Buffer = MIDL_user_allocate(BUFFER_SIZE);
  337.     if (pBuffer->Buffer == 0)
  338.         {
  339.         return(RPC_S_OUT_OF_MEMORY);
  340.         }
  341.     return(0);
  342. }
  343. error_status_t
  344. BufferOut4(
  345.           handle_t h,
  346.           byte Buffer[],
  347.           unsigned long *pLength
  348.           )
  349. {
  350.     *pLength = BUFFER_SIZE;
  351.     return(0);
  352. }
  353. //
  354. //  FUNCTIONS: StructsIn1, StructsIn2, StructsIn3
  355. //
  356. //  PURPOSE: Implements server side of the struct/enum operations.
  357. //
  358. //  PARAMETERS:
  359. //    see rpcsvc.idl
  360. //
  361. //  RETURN VALUE:
  362. //    error_status_t - 0;
  363. //
  364. //
  365. error_status_t
  366. StructsIn1(
  367.           handle_t h,
  368.           struct BAD1 array[50]
  369.           )
  370. {
  371.     return(0);
  372. }
  373. error_status_t
  374. StructsIn2(
  375.           handle_t h,
  376.           struct BAD2 array[50]
  377.           )
  378. {
  379.     return(0);
  380. }
  381. error_status_t
  382. StructsIn3(
  383.           handle_t h,
  384.           struct GOOD array[50]
  385.           )
  386. {
  387.     return(0);
  388. }
  389. //
  390. //  FUNCTIONS: ListIn, ListOut1, ListOut2
  391. //
  392. //  PURPOSE: Implements server side of linked list functions.
  393. //
  394. //
  395. //  PARAMETERS:
  396. //    see rpcsvc.idl
  397. //
  398. //  RETURN VALUE:
  399. //    error_status_t - 0;
  400. //
  401. //  NOTES:
  402. //    Since ListOut2 uses [enable_allocate] it
  403. //    must allocate all memory for parameters
  404. //    with RpcSsAllocate().
  405. //
  406. error_status_t
  407. ListIn(
  408.       handle_t h,
  409.       PLIST pList
  410.       )
  411. {
  412.     return(0);
  413. }
  414. error_status_t
  415. ListOut1(
  416.         handle_t h,
  417.         LIST *pList
  418.         )
  419. {
  420.     int i;
  421.     for(i = 0; i < LIST_SIZE; i++)
  422.         {
  423.         pList->data = i;
  424.         pList->pNext = MIDL_user_allocate(sizeof(LIST));
  425.         if (pList->pNext == 0)
  426.             {
  427.             return(RPC_S_OUT_OF_MEMORY);
  428.             }
  429.         pList = pList->pNext;
  430.         }
  431.     pList->data = i;
  432.     pList->pNext = 0;
  433.     return(0);
  434. }
  435. error_status_t
  436. ListOut2(
  437.         handle_t h,
  438.         LIST *pList
  439.         )
  440. {
  441.     int i;
  442.     for(i = 0; i < LIST_SIZE; i++)
  443.         {
  444.         pList->data = i;
  445.         pList->pNext = RpcSsAllocate(sizeof(LIST));
  446.         // RpcSsAllocate raises an exception when it
  447.         // fails.  Use RpcSmAllocate is this is
  448.         // undesirable.
  449.         pList = pList->pNext;
  450.         }
  451.     pList->data = i;
  452.     pList->pNext = 0;
  453.     return(0);
  454. }
  455. //
  456. //  FUNCTIONS: UnionCall1, UnionCall2
  457. //
  458. //  PURPOSE: Implements server side of the Union functions.
  459. //
  460. //  PARAMETERS:
  461. //    see rpcsvc.idl
  462. //
  463. //  RETURN VALUE:
  464. //    error_status_t - 0;
  465. //
  466. //
  467. error_status_t
  468. UnionCall1(
  469.           handle_t h,
  470.           unsigned long Length,
  471.           BAD_UNION aUnion[]
  472.           )
  473. {
  474.     return(0);
  475. }
  476. error_status_t
  477. UnionCall2(
  478.           handle_t h,
  479.           GOOD_UNION *pUnion
  480.           )
  481. {
  482.     return(0);
  483. }
  484. //
  485. //  FUNCTION: CheckSecurity
  486. //
  487. //  PURPOSE: Demonstrates the RPC security APIs.
  488. //
  489. //  PARAMETERS:
  490. //    h - binding to client which made the call.
  491. //
  492. //  RETURN VALUE:
  493. //    0 - no error
  494. //
  495. error_status_t
  496. CheckSecurity(
  497.              handle_t h
  498.              )
  499. {
  500.     RPC_STATUS status;
  501.     // At this point the thread is running in the server
  502.     // security context.  There is guarantee that the client
  503.     // even used a secure connection.
  504.     status = RpcImpersonateClient(h);
  505.     if (status != RPC_S_OK)
  506.         {
  507.         return(RPC_S_ACCESS_DENIED);
  508.         }
  509.     // This thread is now running in the clients security context.
  510.     //
  511.     // The server should now open a file, mutex, event or its own data
  512.     // structure which has an ACL associated with it to check that the
  513.     // client has the right to access the server's protected data.
  514.     //
  515.     status = RpcRevertToSelf();
  516.     // ASSERT(status == RPC_S_OK);
  517.     // This thread is now running in the server's security context.
  518.     return(0);
  519. }
  520. //
  521. //  FUNCTIONS: MIDL_user_allocate and MIDL_user_free
  522. //
  523. //  PURPOSE: Used by stubs to allocate and free memory
  524. //           in standard RPC calls. Not used when
  525. //           [enable_allocate] is specified in the .acf.
  526. //
  527. //
  528. //  PARAMETERS:
  529. //    See documentations.
  530. //
  531. //  RETURN VALUE:
  532. //    Exceptions on error.  This is not required,
  533. //    you can use -error allocation on the midl.exe
  534. //    command line instead.
  535. //
  536. //
  537. void * __RPC_USER MIDL_user_allocate(size_t size)
  538. {
  539.     return(HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, size));
  540. }
  541. void __RPC_USER MIDL_user_free( void *pointer)
  542. {
  543.     HeapFree(GetProcessHeap(), 0, pointer);
  544. }