home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / rpc / rpcsvc / rpcsvc.idl < prev    next >
Encoding:
Text File  |  1997-10-05  |  9.3 KB  |  322 lines

  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:   rpcsvc.idl
  9. //
  10. //  PURPOSE:  Simple RPC service .idl file.  This defines the wire
  11. //            "contract" between a client and server using this
  12. //            interface.  All data types and functions (methods,
  13. //            operations) that go over the wire must be defined here.
  14. //
  15. //
  16. [
  17. uuid(15cd3850-28ca-11ce-a4e8-00aa006116cb),
  18. version(1.0)
  19. ]
  20. interface RpcServiceSample
  21. {
  22.  
  23.     error_status_t
  24.     Ping(
  25.         [in] handle_t Binding
  26.         );
  27.  
  28.  
  29.     error_status_t
  30.     CheckSecurity(
  31.         [in] handle_t Binding
  32.         );
  33.  
  34.  
  35.     // Sending a buffer (writing) to the server.
  36.  
  37.     //
  38.     // BufferIn1 and BufferIn2 both use length_is() and size_is().
  39.     // This slows performance, because a larger buffer must be
  40.     // allocated on the sever and the data copied into this larger
  41.     // buffer.
  42.     //
  43.     // BufferIn2 has the most problems because it forces a 16K
  44.     // allocation which may be much larger then needed and requires
  45.     // and extra data copy.  It also limits clients to writing 16K
  46.     // at a time.
  47.     //
  48.     // The BufferIn3() function saves the allocation and copy
  49.     // and gives the client complete control of the size.
  50.     //
  51.     // Notes: Avoid length_is() on [in] parameters.  Usually
  52.     //        size_is() is all that is really needed.
  53.  
  54.     const unsigned long BUFFER_SIZE = 100;
  55.  
  56.     error_status_t
  57.     BufferIn1(
  58.              [in] handle_t Binding,
  59.              [length_is(BufferLength), size_is(BufferSize),
  60.               in ] byte Buffer[],
  61.              [in] unsigned long BufferLength,
  62.              [in] unsigned long BufferSize
  63.              );
  64.  
  65.     error_status_t
  66.     BufferIn2(
  67.              [in] handle_t Binding,
  68.              [length_is(BufferLength), in ] byte Buffer[16*1024],
  69.              [in] unsigned long BufferLength
  70.              );
  71.  
  72.     error_status_t
  73.     BufferIn3(
  74.              [in] handle_t Binding,
  75.              [size_is(BufferLength), in ] byte Buffer[],
  76.              [in] unsigned long BufferLength
  77.              );
  78.  
  79.     // Getting a buffer (reading) from the server.
  80.     //
  81.     // In BufferOut1 the size of the output is limited to 16K,
  82.     // which will force extra round trips when more then 16K
  83.     // is being returned. This requires the client to supply a
  84.     // 16K buffer and the stub to allocate 16K on the server side.
  85.     //
  86.     // In BufferOut2 the client decides how big the buffer
  87.     // should be and only as much as the client wants is
  88.     // allocated in the server.  Similar to BufferOut4
  89.     // which is better.
  90.     //
  91.     // In BufferOut3 the server allocates a buffer exactly
  92.     // as large as it wants.  This results in two allocations,
  93.     // one in the server manager and one in the client.  This
  94.     // is best if the clients have no idea how much data the
  95.     // server will give them.
  96.     //
  97.     // In BufferOut4 the client decides how big the buffer
  98.     // should be.  The server can shorten (this should
  99.     // be uncommon) the buffer if needed.
  100.     //
  101.     // Notes: Consider how the client and server interact
  102.     //   in your application when choosing a "read" style
  103.     //   interface.
  104.  
  105.  
  106.     error_status_t
  107.     BufferOut1(
  108.               [in] handle_t Binding,
  109.               [length_is(*pBufferLength)] byte Buffer[16*1024],
  110.               [out] unsigned long *pBufferLength
  111.               );
  112.  
  113.     error_status_t
  114.     BufferOut2(
  115.               [in] handle_t Binding,
  116.               [size_is(BufferSize), length_is(*pBufferLength),
  117.                out] byte Buffer[],
  118.               [in] unsigned long BufferSize,
  119.               [out] unsigned long *pBufferLength
  120.               );
  121.  
  122.     typedef struct {
  123.         unsigned long BufferLength;
  124.         [unique, size_is(BufferLength)] byte *Buffer;
  125.         } BUFFER;
  126.  
  127.     error_status_t
  128.     BufferOut3(
  129.               [in] handle_t Binding,
  130.               [out] BUFFER *pBuffer
  131.               );
  132.  
  133.     error_status_t
  134.     BufferOut4(
  135.               [in] handle_t Binding,
  136.               [out, size_is(*pBufferLength)] byte Buffer[],
  137.               [in, out] unsigned long *pBufferLength
  138.               );
  139.  
  140.     // Structures and Enums.
  141.     //
  142.     // Use -Zp8 (or higher). (Default on Win32 platforms)
  143.     //
  144.     // Make sure the structure ends on a 0 mod 4 address.
  145.     //
  146.     // Use [v1_enum] on all enumerated types.
  147.     //
  148.     // Following these rules will result in structures (and
  149.     // arrays of structures) which can be memcpy()'ed to and from
  150.     // the wire.  Otherwise the structures will be copied
  151.     // member-by-member. (ouch!)
  152.     // 
  153.  
  154.     typedef enum {
  155.         A = 1,
  156.         B,
  157.         C,
  158.         D
  159.         } BAD_ENUM;
  160.  
  161.     typedef [v1_enum] enum {
  162.         E = 5,
  163.         F,
  164.         G,
  165.         H
  166.         } GOOD_ENUM;
  167.  
  168.     struct BAD1 {
  169.         long l;
  170.         short s;  // Ends on 6 % 4 = 2 byte address.
  171.         };
  172.  
  173.     struct BAD2 {
  174.         BAD_ENUM e;  // 16bits on the wire, 32bits in memory!
  175.         long l;      // How big is it?
  176.         };
  177.  
  178.     struct GOOD {
  179.         GOOD_ENUM e;  // v1_enum 32bits on wire and in memory.
  180.         long l;
  181.         long l2;      // Ends on 12 % 4 = 0 byte address.
  182.         };
  183.  
  184.     error_status_t
  185.     StructsIn1(
  186.               [in] handle_t Binding,
  187.               [in] struct BAD1 array[50]
  188.               );
  189.  
  190.     error_status_t
  191.     StructsIn2(
  192.               [in] handle_t Binding,
  193.               [in] struct BAD2 array[50]
  194.               );
  195.  
  196.     error_status_t
  197.     StructsIn3(
  198.               [in] handle_t Binding,
  199.               [in] struct GOOD array[50]
  200.               );
  201.     // Linked list examples
  202.     //
  203.     // Follow the rules for structs when defining your linked
  204.     // list nodes.
  205.     //
  206.     // ListIn and ListOut1 are the basic linked list functions,
  207.     // ListOut1 is more expensive because each node must be copied
  208.     // into nodes on the client.  (In ListIn the list pointers
  209.     // are fixed up in one big buffer.)
  210.     //
  211.     // ListOut2 is identical to ListOut1 except that it turns
  212.     // on the RPC allocator in the server.
  213.     //
  214.     // Linked lists are not very efficient for RPC because the
  215.     // often require many memory allocations.  When possible,
  216.     // replace linked lists with variably sized arrays of structures.
  217.     //
  218.  
  219.     const unsigned long LIST_SIZE = 50;
  220.  
  221.     typedef struct LIST {
  222.         [unique] struct LIST *pNext;
  223.         unsigned long data;
  224.         } LIST;
  225.  
  226.     typedef [unique] LIST *PLIST;
  227.  
  228.     error_status_t
  229.     ListIn(
  230.           [in] handle_t Binding,
  231.           [in] PLIST pList
  232.           );
  233.  
  234.     error_status_t
  235.     ListOut1(
  236.             [in] handle_t Binding,
  237.             [out] LIST *pListHead
  238.             );
  239.  
  240.     // [enable_allocate] in .acf.
  241.     error_status_t
  242.     ListOut2(
  243.             [in] handle_t Binding,
  244.             [out] LIST *pListHead
  245.             );
  246.  
  247.     // Unions
  248.     //
  249.     // Avoid using very many unions. For example, don't pass an array in
  250.     // which each element contains a union with several arms.  Instead,
  251.     // define several different structures and define a union with several
  252.     // arms each being an array of one of the different types of structures.
  253.     // 
  254.     // Do NOT define a [default] arm for your unions.  This way a future
  255.     // version of the union can include new arms and still interoperate
  256.     // with older versions of the interface.
  257.     //
  258.     // Avoid passing unions by value.
  259.     //
  260.  
  261.     const unsigned long UNION_ARRAY_LEN = 50;
  262.  
  263.     typedef struct BAD_UNION {
  264.         unsigned long Tag;
  265.         [switch_is(Tag)] union
  266.             {
  267.             [case(1)]
  268.                 unsigned long ulData;
  269.             [case(2)]
  270.                 unsigned hyper uhData;
  271.             [default]
  272.                 // The default arm here prevents the addition of
  273.                 // another case in future versions.
  274.                 ;
  275.             } u;
  276.         } BAD_UNION;
  277.  
  278.     typedef struct ONE {
  279.         unsigned long DataLength;
  280.         [size_is(DataLength)] unsigned long *Data;
  281.         } ARM_ONE;
  282.  
  283.     typedef struct TWO {
  284.         unsigned long DataLength;
  285.         [size_is(DataLength)] unsigned hyper *Data;
  286.         } ARM_TWO;
  287.  
  288.     typedef struct {
  289.         unsigned long Tag;
  290.         [switch_is(Tag)] union
  291.             {
  292.             [case (1)]
  293.                 [unique] ARM_ONE *pOne;
  294.             [case (2)]
  295.                 [unique] ARM_TWO *pTwo;
  296.  
  297.             // May add [case(3)] in a future version.
  298.             //
  299.             // When calling a down level server with Tag == 3 the
  300.             // error RPC_S_INVALID_TAG will get returned.  Values
  301.             // 1 and 2 will continue to work.
  302.             //
  303.             // If there was a [default] arm this wouldn't work.
  304.  
  305.             } u;
  306.         } GOOD_UNION;
  307.  
  308.         error_status_t
  309.         UnionCall1(
  310.                   [in] handle_t Binding,
  311.                   [in] unsigned long Length,
  312.                   [in, size_is(Length)] BAD_UNION ArrayOfUnions[]
  313.                   );
  314.     
  315.         error_status_t
  316.         UnionCall2(
  317.                   [in] handle_t Binding,
  318.                   [in] GOOD_UNION *pUnionContainingArrays
  319.                   );
  320.  
  321. }
  322.