home *** CD-ROM | disk | FTP | other *** search
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //
- // Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
- //
- // MODULE: rpcsvc.idl
- //
- // PURPOSE: Simple RPC service .idl file. This defines the wire
- // "contract" between a client and server using this
- // interface. All data types and functions (methods,
- // operations) that go over the wire must be defined here.
- //
- //
- [
- uuid(15cd3850-28ca-11ce-a4e8-00aa006116cb),
- version(1.0)
- ]
- interface RpcServiceSample
- {
-
- error_status_t
- Ping(
- [in] handle_t Binding
- );
-
-
- error_status_t
- CheckSecurity(
- [in] handle_t Binding
- );
-
-
- // Sending a buffer (writing) to the server.
-
- //
- // BufferIn1 and BufferIn2 both use length_is() and size_is().
- // This slows performance, because a larger buffer must be
- // allocated on the sever and the data copied into this larger
- // buffer.
- //
- // BufferIn2 has the most problems because it forces a 16K
- // allocation which may be much larger then needed and requires
- // and extra data copy. It also limits clients to writing 16K
- // at a time.
- //
- // The BufferIn3() function saves the allocation and copy
- // and gives the client complete control of the size.
- //
- // Notes: Avoid length_is() on [in] parameters. Usually
- // size_is() is all that is really needed.
-
- const unsigned long BUFFER_SIZE = 100;
-
- error_status_t
- BufferIn1(
- [in] handle_t Binding,
- [length_is(BufferLength), size_is(BufferSize),
- in ] byte Buffer[],
- [in] unsigned long BufferLength,
- [in] unsigned long BufferSize
- );
-
- error_status_t
- BufferIn2(
- [in] handle_t Binding,
- [length_is(BufferLength), in ] byte Buffer[16*1024],
- [in] unsigned long BufferLength
- );
-
- error_status_t
- BufferIn3(
- [in] handle_t Binding,
- [size_is(BufferLength), in ] byte Buffer[],
- [in] unsigned long BufferLength
- );
-
- // Getting a buffer (reading) from the server.
- //
- // In BufferOut1 the size of the output is limited to 16K,
- // which will force extra round trips when more then 16K
- // is being returned. This requires the client to supply a
- // 16K buffer and the stub to allocate 16K on the server side.
- //
- // In BufferOut2 the client decides how big the buffer
- // should be and only as much as the client wants is
- // allocated in the server. Similar to BufferOut4
- // which is better.
- //
- // In BufferOut3 the server allocates a buffer exactly
- // as large as it wants. This results in two allocations,
- // one in the server manager and one in the client. This
- // is best if the clients have no idea how much data the
- // server will give them.
- //
- // In BufferOut4 the client decides how big the buffer
- // should be. The server can shorten (this should
- // be uncommon) the buffer if needed.
- //
- // Notes: Consider how the client and server interact
- // in your application when choosing a "read" style
- // interface.
-
-
- error_status_t
- BufferOut1(
- [in] handle_t Binding,
- [length_is(*pBufferLength)] byte Buffer[16*1024],
- [out] unsigned long *pBufferLength
- );
-
- error_status_t
- BufferOut2(
- [in] handle_t Binding,
- [size_is(BufferSize), length_is(*pBufferLength),
- out] byte Buffer[],
- [in] unsigned long BufferSize,
- [out] unsigned long *pBufferLength
- );
-
- typedef struct {
- unsigned long BufferLength;
- [unique, size_is(BufferLength)] byte *Buffer;
- } BUFFER;
-
- error_status_t
- BufferOut3(
- [in] handle_t Binding,
- [out] BUFFER *pBuffer
- );
-
- error_status_t
- BufferOut4(
- [in] handle_t Binding,
- [out, size_is(*pBufferLength)] byte Buffer[],
- [in, out] unsigned long *pBufferLength
- );
-
- // Structures and Enums.
- //
- // Use -Zp8 (or higher). (Default on Win32 platforms)
- //
- // Make sure the structure ends on a 0 mod 4 address.
- //
- // Use [v1_enum] on all enumerated types.
- //
- // Following these rules will result in structures (and
- // arrays of structures) which can be memcpy()'ed to and from
- // the wire. Otherwise the structures will be copied
- // member-by-member. (ouch!)
- //
-
- typedef enum {
- A = 1,
- B,
- C,
- D
- } BAD_ENUM;
-
- typedef [v1_enum] enum {
- E = 5,
- F,
- G,
- H
- } GOOD_ENUM;
-
- struct BAD1 {
- long l;
- short s; // Ends on 6 % 4 = 2 byte address.
- };
-
- struct BAD2 {
- BAD_ENUM e; // 16bits on the wire, 32bits in memory!
- long l; // How big is it?
- };
-
- struct GOOD {
- GOOD_ENUM e; // v1_enum 32bits on wire and in memory.
- long l;
- long l2; // Ends on 12 % 4 = 0 byte address.
- };
-
- error_status_t
- StructsIn1(
- [in] handle_t Binding,
- [in] struct BAD1 array[50]
- );
-
- error_status_t
- StructsIn2(
- [in] handle_t Binding,
- [in] struct BAD2 array[50]
- );
-
- error_status_t
- StructsIn3(
- [in] handle_t Binding,
- [in] struct GOOD array[50]
- );
- // Linked list examples
- //
- // Follow the rules for structs when defining your linked
- // list nodes.
- //
- // ListIn and ListOut1 are the basic linked list functions,
- // ListOut1 is more expensive because each node must be copied
- // into nodes on the client. (In ListIn the list pointers
- // are fixed up in one big buffer.)
- //
- // ListOut2 is identical to ListOut1 except that it turns
- // on the RPC allocator in the server.
- //
- // Linked lists are not very efficient for RPC because the
- // often require many memory allocations. When possible,
- // replace linked lists with variably sized arrays of structures.
- //
-
- const unsigned long LIST_SIZE = 50;
-
- typedef struct LIST {
- [unique] struct LIST *pNext;
- unsigned long data;
- } LIST;
-
- typedef [unique] LIST *PLIST;
-
- error_status_t
- ListIn(
- [in] handle_t Binding,
- [in] PLIST pList
- );
-
- error_status_t
- ListOut1(
- [in] handle_t Binding,
- [out] LIST *pListHead
- );
-
- // [enable_allocate] in .acf.
- error_status_t
- ListOut2(
- [in] handle_t Binding,
- [out] LIST *pListHead
- );
-
- // Unions
- //
- // Avoid using very many unions. For example, don't pass an array in
- // which each element contains a union with several arms. Instead,
- // define several different structures and define a union with several
- // arms each being an array of one of the different types of structures.
- //
- // Do NOT define a [default] arm for your unions. This way a future
- // version of the union can include new arms and still interoperate
- // with older versions of the interface.
- //
- // Avoid passing unions by value.
- //
-
- const unsigned long UNION_ARRAY_LEN = 50;
-
- typedef struct BAD_UNION {
- unsigned long Tag;
- [switch_is(Tag)] union
- {
- [case(1)]
- unsigned long ulData;
- [case(2)]
- unsigned hyper uhData;
- [default]
- // The default arm here prevents the addition of
- // another case in future versions.
- ;
- } u;
- } BAD_UNION;
-
- typedef struct ONE {
- unsigned long DataLength;
- [size_is(DataLength)] unsigned long *Data;
- } ARM_ONE;
-
- typedef struct TWO {
- unsigned long DataLength;
- [size_is(DataLength)] unsigned hyper *Data;
- } ARM_TWO;
-
- typedef struct {
- unsigned long Tag;
- [switch_is(Tag)] union
- {
- [case (1)]
- [unique] ARM_ONE *pOne;
- [case (2)]
- [unique] ARM_TWO *pTwo;
-
- // May add [case(3)] in a future version.
- //
- // When calling a down level server with Tag == 3 the
- // error RPC_S_INVALID_TAG will get returned. Values
- // 1 and 2 will continue to work.
- //
- // If there was a [default] arm this wouldn't work.
-
- } u;
- } GOOD_UNION;
-
- error_status_t
- UnionCall1(
- [in] handle_t Binding,
- [in] unsigned long Length,
- [in, size_is(Length)] BAD_UNION ArrayOfUnions[]
- );
-
- error_status_t
- UnionCall2(
- [in] handle_t Binding,
- [in] GOOD_UNION *pUnionContainingArrays
- );
-
- }
-