idnits 2.17.1 draft-brown-dcom-v1-spec-00.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** Cannot find the required boilerplate sections (Copyright, IPR, etc.) in this document. Expected boilerplate is as follows today (2024-04-25) according to https://trustee.ietf.org/license-info : IETF Trust Legal Provisions of 28-dec-2009, Section 6.a: This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. IETF Trust Legal Provisions of 28-dec-2009, Section 6.b(i), paragraph 2: Copyright (c) 2024 IETF Trust and the persons identified as the document authors. All rights reserved. IETF Trust Legal Provisions of 28-dec-2009, Section 6.b(i), paragraph 3: This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- ** Missing expiration date. The document expiration date should appear on the first and last page. ** The document seems to lack a 1id_guidelines paragraph about Internet-Drafts being working documents. ** The document seems to lack a 1id_guidelines paragraph about the list of current Internet-Drafts. ** The document seems to lack a 1id_guidelines paragraph about the list of Shadow Directories. == No 'Intended status' indicated for this document; assuming Proposed Standard == The page length should not exceed 58 lines per page, but there was 1 longer page, the longest (page 1) being 1892 lines Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** The document seems to lack separate sections for Informative/Normative References. All references will be assumed normative when checking for downward references. ** There is 1 instance of lines with control characters in the document. Miscellaneous warnings: ---------------------------------------------------------------------------- == Line 498 has weird spacing: '...robable to ca...' == Line 645 has weird spacing: '...d short wTo...' == Line 646 has weird spacing: '...d short aNe...' == Line 653 has weird spacing: '...d short wAu...' == Line 654 has weird spacing: '...d short wAu...' == (19 more instances...) -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (May 2, 1996) is 10220 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Possible downref: Non-RFC (?) normative reference: ref. 'CAE RPC' -- Possible downref: Non-RFC (?) normative reference: ref. 'COM' Summary: 8 errors (**), 0 flaws (~~), 8 warnings (==), 5 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 1 Network Working Group Nat Brown 2 INTERNET-DRAFT Charlie Kindel 3 Microsoft Corporation 4 Expires in six months May 2, 1996 6 Distributed Component Object Model Protocol -- DCOM/1.0 8 Status of this Memo 10 This document is an Internet-Draft. Internet-Drafts are working 11 documents of the Internet Engineering Task Force (IETF), its areas, 12 and its working groups. Note that other groups may also distribute 13 working documents as Internet-Drafts. 15 Internet-Drafts are draft documents valid for a maximum of six 16 months and may be updated, replaced, or obsoleted by other 17 documents at any time. It is inappropriate to use Internet-Drafts 18 as reference material or to cite them other than as "work in 19 progress." 21 To learn the current status of any Internet-Draft, please check the 22 "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow 23 Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), 24 munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or 25 ftp.isi.edu (US West Coast). 27 Distribution of this document is unlimited. Please send comments to 28 the authors at . General discussions about 29 DCOM and its applications should take place on the 30 mailing list. To subscribe, send a piece of 31 mail to , and in the body of the message, 32 first type "subscribe" for non-digest or "digest" for digest 33 version, followed by "dcom", and finally by your email address. 34 (example: "subscribe dcom johndoe@gizmo.com") 36 Abstract 38 The Distributed Component Object Model protocol is an application- 39 level protocol for object-oriented remote procedure calls useful for 40 distributed, component-based systems of all types. It is a generic 41 protocol layered on the distributed computing environment (DCE) RPC 42 specification and facilitates the construction of task-specific 43 communication protocols through features such as: a platform 44 neutral argument/parameter marshaling format (NDR), the ability for 45 objects to support multiple interfaces with a safe, interface-level 46 versioning scheme suited to independent evolution by multiple 47 parties, the ability to make authenticated connections and to choose 48 levels of channel security, and a transport-neutral data 49 representation for references (including by-value) to objects. 51 Table of Contents 53 1. Introduction 54 1.1 Purpose 55 2. Overall Operation 56 2.1 Object Calls 57 2.2 OXIDs and Object Exporters 58 2.3 Marshaled Interface References 59 2.4 Reference Counting 60 2.5 Pinging 61 2.5.1 Delta Pinging 62 2.6 QueryInterface 63 2.7 Causality ID 64 3. Data Types and Structures 65 3.1 DCE Packet Headers 66 3.2 ORPC Base Definitions 67 3.3 OBJREF Structure 68 3.3.1 OBJREF_STANDARD form 69 3.3.2 OBJREF_HANDLER form 70 3.3.3 OBJREF_CUSTOM form 71 3.4 STDOBJREF Structure 72 3.5 SORFLAGS Constants 73 3.6 ORPCINFOFLAGS Constants 74 3.7 ORPCTHIS Structure 75 3.8 ORPCTHAT Structure 76 3.9 HRESULTs 77 3.10 Body Extensions 78 3.10.1 Debugging Extension 79 3.10.2 Extended Error Extension 80 4. IRemUnknown Interface 81 4.1 IRemUnknown::RemQueryInterface 82 4.1.1 REMQIRESULT Structure 83 4.2 IRemUnknown::RemAddRef 84 4.3 IRemUnknown::RemRelease 85 5. The Object Exporter 86 5.1 Object Exporter Reserved Ports 87 5.2 The IObjectExporter Interface 88 5.2.1 IObjectExporter::ResolveOxid 89 5.2.1.1 Lookup Between Friends 90 5.2.1.2 My First Lookup 91 5.2.1.3 Middleman Lookup 92 5.2.1.4 Lazy Use Protseq 93 5.2.2 IObjectExporter::SimplePing 94 5.2.3 IObjectExporter::ComplexPing 95 6. Security Considerations 96 7. Acknowledgements 97 8. References 98 9. Author's Address 100 1. Introduction 102 The Distributed Component Object Model protocol (DCOM) is an 103 application-level protocol for object-oriented remote procedure 104 calls and is thus also called "Object RPC" or ORPC. The protocol 105 consists of a set of extensions, layered on the distributed 106 computing environment (DCE) RPC specification [CAE RPC], with which 107 familiarity is assumed. Familiarity is also assumed with the 108 COM (Component Object Model) specification [COM]. 110 Object RPC specifies: 112 * How calls are made on an object 114 * How object references are represented, communicated, and 115 maintained 117 1.1 Purpose 119 There is a natural tendency in a networked environment to create 120 entirely new application-level protocols as each new or seemingly 121 unique combination of client, user agent, and server requirement 122 arises. 124 While in many situations the definition of a new protocol is 125 useful and justifiable, there are numerous features which have 126 eventually been added to or required from each new protocol (or 127 which become layered above them) as they evolve and become used 128 in broader contexts. 130 A design goal of the DCOM protocol is the inherent support of 131 standard features required by any distributed application 132 communication protocol. In other words, to act as a framework 133 to facilitate the construction of task-specific communication 134 paths between distributed applications. 136 Data Marshaling 138 A common occurrence among user agents using the HTTP protocol 139 today is the use of complex, task-specific Query URL syntax and 140 HTTP POSTs. Also increasingly common is the POSTing and response 141 with custom MIME types to and from resources which interpret 142 the format and reply in same. While workable, there are drawbacks 143 to this approach including increased complexity and work to 144 produce and consume each new (and unique) format in the client 145 and server, lessened ability to build task-specific firewalls 146 for administration and security purposes, and in many cases 147 definition of platform-centric formats. 149 DCOM utilizes the Network Data Representation for arbitrary 150 data types supported by DCE RPC. 152 Security 154 DCOM leverages the authentication, authorization, and message 155 integrity capabilities of DCE RPC. An implementation may 156 support any level of DCE RPC security. Any connection or call 157 can be made as secure or as insecure as negotiated by the 158 client and the server. 160 Safe Non-Coordinated Versioning of Interfaces 162 In DCOM versioning of interfaces is done through identifiers 163 which are universally unique (UUID's). To version a published 164 interface, a new interface is defined with a different UUID to 165 the updated specification. Multiple parties can simultaneously 166 introduce "revisions" to interfaces by defining related but 167 distinct interfaces without fear of colliding with each other's 168 version numbers and without fear of breaking each other's 169 down-level or up-level clients. 171 To date, the bulk of task-specific protocols (such as custom 172 POSTs or MIME types using HTTP) have little or no concept of 173 versioning at all, and simply "narrow" the incompatibility window 174 by updating clients (typically pages which are being downloaded 175 anyway) and servers (CGI scripts or other HTTP server 176 infrastructure) simultaneously. 178 2. Overall Operation 180 The Object RPC protocol highly leverages the OSF DCE RPC network 181 protocol (see the reference [CAE RPC]). This leverage occurs at both 182 the specification level and the implementation level: the bulk of 183 the implementation effort involved in implementing the DCOM network 184 protocol is in fact that of implementing the DCE RPC network 185 protocol on which it is built. 187 2.1 Object Calls 189 An actual COM network remote procedure call (hereinafter referred to 190 as "an ORPC") is in fact a true DCE remote procedure call (herein 191 termed "a DCE RPC"), a "Request PDU" conforming to the specification 192 for such calls per [CAE RPC]. 194 In an ORPC, the object ID field of the invocation header as specified 195 in [CAE RPC] contains an "IPID". An IPID is a 128-bit identifier 196 known as an interface pointer identifier which represents a 197 particular interface on a particular object in a particular server. 198 As it is passed in the object ID fields of a DCE RPC, the static type 199 of an IPID is in fact a UUID. However, IPIDs are scoped not globally 200 but rather only relative to the machine on which the server is 201 located (and which thus originally allocated them); IPIDs do not 202 necessarily use the standard UUID allocation algorithm, but rather 203 may use a machine-specific algorithm which can assist with 204 dispatching. 206 In an ORPC, the interface ID field of the RPC header specifies the 207 IID, and arguments are found in the body, as usual. However, when 208 viewed from the DCE RPC perspective an additional first argument is 209 always present that is absent in the corresponding interface 210 specification. This argument is of type ORPCTHIS, which is described 211 in Section 3.7. It is placed first in the body of the Request PDU, 212 before the actual arguments of the ORPC. 214 It is specifically legal for an ORPC to attempt a call a method 215 number on a given interface which is beyond the number of methods 216 believed by the server to be in that interface. Such calls should 217 cause a fault. 219 Similarly, in a reply to an ORPC (a DCE RPC "Response PDU"), when 220 viewed from the DCE RPC perspective, an additional first return value 221 is always present that is absent in the corresponding COM interface 222 specification. This argument is of type ORPCTHAT, which is described 223 in Section 3.8. It is placed first in the body of the Response PDU, 224 before the actual return values of the ORPC. 226 An ORPCTHAT may also be present in a "Fault PDU." In the 227 Connectionless (CL) Fault PDU, it is placed four bytes after the 32- 228 bit fault code which normally comprises the entire body of the PDU, 229 thus achieving eight byte alignment for the ORPCTHAT; the 230 intervening padding bytes are presently reserved and must be zero. 231 The PDU body length is of course set to encompass the entire body 232 of the Fault PDU, including the ORPCTHAT. In the Connection- 233 Oriented (CO) Fault PDU, the ORPCTHAT is placed in the standard 234 location allocated for the "stub data." In a Fault PDU of either 235 form that results from an ORPC, if an ORPCTHAT is not present then 236 no other data may be substituted in its here-specified location in 237 the PDU. 239 2.2 OXIDs and Object Exporters 241 Although an IPID from a logical perspective semantically determines 242 the server, object and interface to which a particular call should 243 be directed, it does not by itself indicate the binding information 244 necessary to actually carry out an invocation. 246 The protocol represents this "how-to" communication information in a 247 UUID called an object exporter identifier, otherwise known as an 248 OXID. Conceptually, an OXID can be thought of as an implementation 249 scope for an object, which may be a whole machine, a given 250 process, a thread within that process, or other more esoteric 251 implementation scope, but the exact definition of such scopes has no 252 bearing on the protocol itself. 254 A given machine at any moment may support several OXIDs; however 255 there is always a unique Object Exporter service per machine which 256 coordinates the management of all the OXIDs on the machine. Data 257 structures in each Object Exporter keep track of the IPIDs exported 258 and imported by that Object Exporter. The Object Exporter resides at 259 well-known ports (or endpoints, depending on your terminology -- 260 one per protocol, of course) on the machine. It supports a DCE RPC 261 interface known as IObjectExporter, described in Section 5.2. 263 An OXID is used to determine the RPC string bindings that allow 264 calls to reach their target IPID. Before making a call, the calling 265 process must translate an OXID into a set of bindings that the 266 underlying RPC implementation understands. It accomplishes by 267 maintaining a cache of these mappings. When the destination 268 application receives an object reference, it checks to see if it 269 recognizes the OXID. If it does not, then it asks the source of the 270 object reference (the server machine from which the object reference 271 was acquired, which is not necessarily the home machine for the 272 interface pointer) for the translation, and saves the resulting set 273 of string bindings in a local table that maps OXIDs to string 274 bindings. 276 Associated with each OXID (not each Object Exporter) is COM object 277 termed an "OXID object." OXID objects implement (at least) the 278 IRemUnknown interface, a COM (not DCE-RPC) interface through which 279 remote management of reference counts and requests for interfaces 280 are returned. 282 2.3 Marshaled Interface References 284 The DCOM protocol extends the Network Data Representation standard 285 specified in [CAE RPC] by defining what can be thought of as a new 286 primitive data type that can be marshaled: that of an interface 287 reference to an object. This is the only extension to NDR made by 288 the DCOM protocol. 290 A marshaled interface reference is described by a type known as an 291 OBJREF, which is described in detail in Section 3.3. An OBJREF in 292 actuality has several variations: 294 NULL 296 This is a reference to no object. 298 STANDARD 300 A standard remote reference. Known as a STDOBJREF. A STDOBJREF 301 contains: 303 * An IPID, which uniquely specifies the interface and object. 305 * An object ID (OID), which uniquely specifies the identity 306 of the object on which the IPID is found (scoped to the 307 object exporter with which the object is associated). 309 * An OXID, which identifies the scope where the implementation 310 of the object is active, and can be used to reach the 311 interface pointer. 313 * A reference count, indicating the number of references to 314 this IPID that are conveyed by this marshaling. This count, 315 though typically a value of one, may in fact be zero, one, or 316 more (see the next section). 318 * Some flags, explained later. 320 CUSTOM 322 Contains a class ID (CLSID) and class-specific information. 324 The Custom format gives an object control over the 325 representation of references to itself. For example, an 326 immutable object might be passed by value, in which case the 327 class-specific information would contain the object's immutable 328 data. 330 HANDLER 332 A sub-case of the custom reference in which the class- 333 specific information is standardized. 335 For example, an object wishes to be represented in client 336 address spaces by a proxy object that caches state. In this 337 case, the class-specific information is just a standard 338 reference to an interface pointer that the handler (proxy 339 object) will use to communicate with the original object. 341 Interface references are always marshaled in little-endian byte 342 order, irrespective of the byte order prevailing in the remainder of 343 the data being marshaled. 345 2.4 Reference Counting 347 In the DCOM protocol, remote reference counting is conducted per 348 interface (per IPID). 350 The actual increment and decrement calls are carried out using 351 (respectively) the RemAddRef and RemRelease methods in a COM 352 interface known as IRemUnknown found on an object associated with 353 each OXID, the IPID of which is returned from the function 354 IObjectExporter::ResolveOxid (section 5.2.1). In contrast to their 355 analogues in IUnknown, RemAddRef and RemRelease can in one call 356 increment or decrement the reference count of many different IPIDs 357 by an arbitrary amount; this allows for greater network efficiency. 358 In the interests of performance, client COM implementations 359 typically do not immediately translate each local AddRef and Release 360 into a remote RemAddRef and RemRelease. Rather, the actual remote 361 release of all interfaces on an object is typically deferred until 362 all local references to all interfaces on that object have been 363 released. Further, one actual remote reference count may be used to 364 service many local reference counts; that is, the client 365 infrastructure may multiplex zero or more local references to an 366 interface into zero or one remote references on the actual IPID. 368 2.5 Pinging 370 The above reference counting scheme would be entirely adequate on 371 its own if clients never terminated abnormally, but in fact they do, 372 and the system needs to be robust in the face of clients terminating 373 abnormally when they hold remote references. In a DCE RPC, one 374 typically addresses this issue through the use of context handles. 375 Context handles are not used, however, by the DCOM protocol, for 376 reasons of expense. The basic underlying technology used in virtually 377 all protocols for detecting remote abnormal termination is that of 378 periodic pings. Naive use of RPC context handles would result in 379 per object per client process pings being sent to the server. The 380 DCOM protocol includes a pinging infrastructure to reduce network 381 traffic by relying on the client Object Exporter implementation 382 to do local management of client liveness detection, and having 383 the actual pings be sent only on a machine to machine basis. 385 Pinging is carried out on a per-object (per OID), not a per- 386 interface (per-IPID) basis. Architecturally, at its server machine, 387 each exported object (each exported OID) has associated with it a 388 pingPeriod time value and a numPingsToTimeOut count which together 389 (through their product) determine the overall amount of time known 390 as the "ping period" that must elapse without receiving a ping on 391 that OID before all the remote references to IPIDs associated with 392 that OID can be considered to have expired. Once expiration has 393 occurred, the interfaces behind the IPIDs can as would be expected 394 be reclaimed solely on the basis local knowledge, though the 395 timeliness with which this is carried out, if at all, is an 396 implementation specific. If the server COM infrastructure defers 397 such garbage collection in this situation (perhaps because it has 398 local references keeping the interface pointer alive) and it later 399 hears a ping or receives a remote call, then it knows a network 400 partition healed. It can consider the extant remote references to be 401 reactivated and can continue remote operations. 403 When interface pointers are conveyed from one client to another, 404 such as being passed as either [in] or [out] parameters to a call, 405 the interface pointer is marshaled in one client and unmarshaled in 406 the other. In order to successfully unmarshal the interface, the 407 destination client must obtain at least one reference count on the 408 interface. This is usually accomplished by passing in the marshaled 409 interface STDOBJREF a cRefs of (at least) one; the destination 410 client then takes ownership of that many (more) reference counts to 411 the indicated IPID, and the source client then owns that many fewer 412 reference counts on the IPID. It is legal, however, for zero 413 reference counts to be passed in the STDOBJREF; here, the 414 destination client must (if it does not already have access to that 415 IPID and thus have a non-zero reference count for it) before it 416 successfully unmarshals the interface reference (concretely, e.g., 417 before CoUnmarshalInterface returns) call to the object's exporter 418 using IRemUnknown::RemAddRef to obtain a reference count for it. 419 If the destination client is in fact the object's server, then 420 special processing is required by the destination client. The remote 421 reference counts being passed to it should, in effect, be "taken out 422 of circulation," as what where heretofore remote references are 423 being converted into local references. Thus, the reference counts 424 present in the STDOBJREF are in fact decremented from the remote 425 reference count for the IPID in question. 427 Some objects have a usage model such that they do not need to be 428 pinged at all; such objects are indicated by the presence of a flag 429 in a STDOBJREF to an interface on the object. Objects which are not 430 pinged in fact need not be reference counted either, though it is 431 legal (but pointless) for a client to reference count the IPIDs of 432 such objects. 434 For all other objects, assuming a non-zero ping period, it is the 435 responsibility of the holder of an interface reference on some 436 object to ensure that pings reach the server frequently enough to 437 prevent expiration of the object. The frequency used by a client 438 depends on the ping period, the reliability of the channel between 439 the client and the server, and the probability of failure (no pings 440 getting through and possible premature garbage-collection) that the 441 client is willing to tolerate. The ping packet and / or its reply 442 may both request changes to the ping period. Through this mechanism, 443 network traffic may be reduced in the face of slow links to busy 444 servers. 446 2.5.1 Delta Pinging 448 Without any further refinements, ping messages could be quite hefty. 449 If machine A held 1024 remote object references (OIDs) on machine B, 450 then it would send 16K byte ping messages. This would be annoying if 451 the set of remote objects was relatively stable and the ping 452 messages were the same from ping to ping. 454 The delta mechanism reduces the size of ping messages. It uses a 455 ping-set interface that allows the pinging of a single set to replace 456 the pinging of multiple OIDs. 458 Instead of pinging each OID, the client defines a set. Each ping 459 contains only the set id and the list of additions and subtractions 460 to the set. Objects that come and go within one ping period are 461 removed from the set without ever having been added. 463 The pinging protocol is carried out using two methods in the (DCE) 464 interface IObjectExporter on the Object Exporter: ComplexPing, and 465 SimplePing. ComplexPing is used by clients to group the set of OIDs 466 that they must ping into UUID-tagged sets known to the server. These 467 entire sets of OIDs can then be subsequently pinged with a single, 468 short, call to SimplePing. 470 2.6 QueryInterface 472 The IRemUnknown interface on the object-exporter specified object, in 473 addition to servicing reference counting as described above also 474 services QueryInterface calls for remote clients for IPIDs managed by 475 that exporter. IRemUnknown::RemQueryInterface differs from 476 IUnknown::QueryInterface in much the same way as RemAddRef and 477 RemRelease differ from AddRef and Release, in that it is optimized 478 for network access by being able to retrieve many interfaces at once. 480 2.7 Causality ID 482 Each ORPC carries with it a UUID known as the causality id that 483 connects together the chain of ORPC calls that are causally related. 484 If an outgoing ORPC is made while servicing an incoming ORPC, the 485 outgoing call is to have the same causality id as the incoming call. 486 If an outgoing ORPC is made while not servicing an incoming ORPC, 487 then a new causality id is allocated for it. 489 Causality ids may in theory be reused as soon as it is certain that 490 no transitively outstanding call is still in progress which uses 491 that call. In practice, however, in the face of transitive calls and 492 the possibility of network failures in the middle of such call 493 chains, it is difficult to know for certain when this occurs. Thus, 494 pragmatically, causality ids are not reusable. 496 The causality id can be used by servers to understand when blocking 497 or deferring an incoming call (supported in some COM server 498 programming models) is very highly probable to cause a deadlock, 499 and thus should be avoided. 501 The causality id for maybe, idempotent, and broadcast calls must be 502 set to null. If a server makes a ORPC call while processing such a 503 call, a new causality id must be generated as if it were a top level 504 call. 506 3. Data Types and Structures 508 This following several sections present the technical details of the 509 DCOM protocol. 511 3.1 DCE Packet Headers 513 Object RPC sits entirely on top of DCE RPC. The following list 514 describes the elements of ORPC that are specified above and beyond 515 DCE RPC. 517 * The object id field of the header must contain the IPID. 519 * The interface id of the RPC header must contain the IID, even 520 though it is not needed given the IPID. This allows ORPC to 521 sit on top of DCE RPC. An unmodified DCE RPC implementation 522 will correctly dispatch based on IID and IPID. An optimized 523 RPC need only dispatch based on IPID. 525 * An IPID uniquely identifies a particular interface on a 526 particular object on a machine. The converse is not true; a 527 particular interface on a particular object may be represented 528 by multiple IPIDs. IPIDs are unique on their OXID. IPIDs may 529 be reused, however reuse of IPIDs should be avoided. 531 * Datagram, maybe, and idempotent calls are all allowed in ORPC. 533 * Interface pointers may not be passed on maybe or idempotent 534 calls. 536 * Datagram broadcasts are not allowed in ORPC. 538 * Faults are returned in the stub fault field of the DCE RPC fault 539 packet. Any 32 bit value may be returned. Only the following 540 value is pre-specified: 542 RPC_E_VERSION_MISMATCH 544 * DCE cancel is supported. 546 * All interface version numbers must be 0.0. 548 3.2 ORPC Base Definitions 550 There are several fundamental data types and structures on which the 551 COM network protocol is built. These types are shown here in standard 552 C header format. 554 //////////////////////////////////////////////////////////// 555 // Basic Definitions 556 //////////////////////////////////////////////////////////// 557 typedef unsiged long HRESULT; // 32-bit integer: success/failure 558 typedef t_uuid UUID; // rename DCE-RPC type 559 typedef UUID GUID; // Globally Unique IDentifier 560 typedef unsigned hyper ID; // 64-bit integer 561 typedef ID OXID; // Object Exporter Identifier 562 typedef ID OID; // Object Identifer 563 typedef ID SETID; // Ping Set Identifier 564 typedef GUID IPID; // Interface Pointer Identifier 565 typedef GUID* REFIPID; 566 typedef GUID CID; // Causality Identifier 567 #define CID_NULL uuid_null; // All zeros 569 ////////////////////////////////////////////////////////////////// 570 // ORPC Call Packet Format 571 ////////////////////////////////////////////////////////////////// 572 const unsigned short COM_MAJOR_VERSION = 4; 573 const unsigned short COM_MINOR_VERSION = 1; 575 typedef struct tagCOMVERSION { 576 unsigned short MajorVersion; // Major version number 577 unsigned short MinorVersion; // Minor version number 578 } COMVERSION; 580 const unsigned long ORPCF_NULL = 0; // no additional info 581 // in packet 582 const unsigned long ORPCF_LOCAL = 1; // call is local to this 583 // machine 584 const unsigned long ORPCF_RESERVED1 = 2; // reserved for local use 585 const unsigned long ORPCF_RESERVED2 = 4; // reserved for local use 586 const unsigned long ORPCF_RESERVED3 = 8; // reserved for local use 587 const unsigned long ORPCF_RESERVED4 = 16; // reserved for local use 589 // Extension to implicit parameters. 590 typedef struct tagORPC_EXTENT { 591 GUID id; // Extension identifier 592 unsigned long size; // Extension size 593 byte data[]; // [size_is((size+7)&~7)] 594 } ORPC_EXTENT; 596 // Array of extensions. 597 typedef struct tagORPC_EXTENT_ARRAY { 598 unsigned long size; // Num extents. 599 unsigned long reserved; // Must be zero. 600 ORPC_EXTENT** extent; // [size_is((size+1)&~1), unique] 601 } ORPC_EXTENT_ARRAY; 603 // implicit 'this' pointer which is the first [in] parameter on 604 // every ORPC call. 605 typedef struct tagORPCTHIS { 606 COMVERSION version; // COM version number 607 unsigned long flags; // ORPCF flags for presence of 608 // other data 609 unsigned long reserved1; // set to zero 610 CID cid; // causality id of caller 611 ORPC_EXTENT_ARRAY* extensions; // [unique] extensions 612 } ORPCTHIS; 614 // implicit 'that' pointer which is the first [out] parameter on 615 // every ORPC call. 616 typedef struct tagORPCTHAT { 617 unsigned long flags; // ORPCF flags for presence 618 // of other data 619 ORPC_EXTENT_ARRAY *extensions; // [unique] extensions 620 } ORPCTHAT; 622 ////////////////////////////////////////////////////////////////// 623 // Marshaled COM Interface Wire Format 624 ////////////////////////////////////////////////////////////////// 625 typedef enum tagMSHLFLAGS { 626 MSHLFLAGS_NORMAL = 0, 627 MSHLFLAGS_TABLESTRONG = 1, 628 MSHLFLAGS_TABLEWEAK = 2, 629 } MSHLFLAGS; 631 // Tower IDs for common protocols 632 const unsigned short NCADG_IP_UDP = 0x08; 633 const unsigned short NCACN_IP_TCP = 0x07; 634 const unsigned short NCADG_IPX = 0x0E; 635 const unsigned short NCACN_SPX = 0x0C; 636 const unsigned short NCACN_NB_NB = 0x12; 637 const unsigned short NCACN_NB_IPX = 0x0D; 638 const unsigned short NCACN_DNET_NSP = 0x04; 639 const unsigned short NCALRPC = 0x10; 641 // This is the return type for arrays of string bindings or protseqs 642 // used by many ORPC interfaces. 644 typedef struct tagSTRINGBINDING { 645 unsigned short wTowerId; // Cannot be zero. 646 unsigned short aNetworkAddr; // Zero terminated. 647 } STRINGBINDING; 649 // this value (invalid in DCE RPC) indicates to use default authz 650 const unsigned short COM_C_AUTHZ_NONE = 0xffff; 652 typedef struct tagSECURITYBINDING { 653 unsigned short wAuthnSvc; // Must not be zero 654 unsigned short wAuthzSvc; // Must not be zero 655 unsigned short aPrincName; // NULL terminated 656 } SECURITYBINDING; 658 // DUALSTRINGARRAYS are the return type for arrays of network 659 // addresses, arrays of endpoints and arrays of both used in 660 // many ORPC interfaces 661 typedef struct tagDUALSTRINGARRAY { 662 unsigned short wNumEntries; // # of entries in array 663 unsigned short wSecurityOffset; // Offset of security info 665 // The array contains two parts, a set of STRINGBINDINGs 666 // and a set of SECURITYBINDINGs. Each set is terminated by an 667 // extra zero. The shortest array contains four zeros. 668 unsigned short aStringArray[]; // [size_is(wNumEntries)] 669 } DUALSTRINGARRAY; 671 // arbitrary value to help ensure validity 672 const unsigned long OBJREF_SIGNATURE = 0x574f454d; 674 const unsigned long OBJREF_STANDARD = 0x1; 675 const unsigned long OBJREF_HANDLER = 0x2; 676 const unsigned long OBJREF_CUSTOM = 0x4; 678 // Flag values for a STDOBJREF (standard part of an OBJREF). 679 // SORF_OXRES1 - SORF_OXRES8 are reserved for the object exporters 680 // use only, object importers must ignore them and must not enforce 681 // MBZ. 682 const unsigned long SORF_NULL = 0x0000; // convenient for init 683 const unsigned long SORF_OXRES1 = 0x0001; // reserved by exporter 684 const unsigned long SORF_OXRES2 = 0x0020; // reserved by exporter 685 const unsigned long SORF_OXRES3 = 0x0040; // reserved by exporter 686 const unsigned long SORF_OXRES4 = 0x0080; // reserved by exporter 687 const unsigned long SORF_OXRES5 = 0x0100; // reserved by exporter 688 const unsigned long SORF_OXRES6 = 0x0200; // reserved by exporter 689 const unsigned long SORF_OXRES7 = 0x0400; // reserved by exporter 690 const unsigned long SORF_OXRES8 = 0x0800; // reserved by exporter 691 const unsigned long SORF_NOPING = 0x1000; // Pinging not required 693 typedef struct tagSTDOBJREF { 694 unsigned long flags; // SORF_ flags (see above) 695 unsigned long cPublicRefs; // count of references passed 696 OXID oxid; // oxid of server with this oid 697 OID oid; // oid of object with this ipid 698 IPID ipid; // ipid of Interface 699 } STDOBJREF; 701 // although this structure is conformant, it is always marshaled 702 // in little-endian byte-order. 703 typedef struct tagOBJREF { 704 unsigned long signature; // must be OBJREF_SIGNATURE 705 unsigned long flags; // OBJREF flags (see above) 706 GUID iid; // interface identifier 708 union { // [switch_is(flags), switch_type(unsigned long)] 709 struct { // [case(OBJREF_STANDARD)] 710 STDOBJREF std; // standard objref 711 DUALSTRINGARRAY saResAddr; // resolver address 712 } u_standard; 714 struct { // [case(OBJREF_HANDLER)] 715 STDOBJREF std; // standard objref 716 CLSID clsid; // Clsid of handler code 717 DUALSTRINGARRAY saResAddr; // resolver address 718 } u_handler; 720 struct { // [case(OBJREF_CUSTOM)] 721 CLSID clsid; // Clsid of unmarshaling code 722 unsigned long size; // size of data that follows 723 byte* pData; // class specific data, 724 // [size_is(size), ref] 725 } u_custom; 726 } u_objref; 727 } OBJREF; 729 // wire representation of a marshalled interface pointer, 730 // always the little-endian form of an OBJREF 731 typedef struct tagMInterfacePointer { 732 ULONG ulCntData; // size of data 733 byte abData[]; // [size_is(ulCntData)] data 734 } MInterfacePointer, *PMInterfacePointer; 736 // OXID Resolver information associated with each OXID. 737 typedef struct tagOXID_INFO { 738 IPID ipidRemUnknown; // IRemUnknown IPID for 739 // object exporter 740 unsigned long dwAuthnHint; // 32-bit RPC_C_AUTHN value 741 DUALSTRINGARRAY* psa; // [unique] protocol and 742 // security info 743 } OXID_INFO; 744 ////////////////////////////////////////////////////////////////// 746 3.3 OBJREF 748 An OBJREF is the data type used to represent an actual marshaled 749 object reference. An OBJREF can either be empty or assume one of 750 three variations, depending on the degree to which the object 751 being marshaled uses the hook architecture (IMarshal, etc.) in 752 the marshaling infrastructure. The OBJREF structure is a union 753 consisting of a switch flag followed by the appropriate data. 755 3.3.1 OBJREF_STANDARD 757 Contains one interface of an object marshaled in standard form. 758 Contains a standard reference, along with a set of protocol sequences 759 and network addresses that can be used to bind to an OXID resolver 760 that is able to resolve the OXID in the STDOBJREF. This is useful 761 when marshaling a proxy to give to another machine (a.k.a. the 762 "middleman" case). The marshaling machine can specify the saResAddr 763 for the resolver on the server machine so that the unmarshaler does 764 not need to call the marshaler (middleman) back to get this 765 information. Further, the marshaler does not need to keep the OXID 766 in its cache beyond the lifetime of its own references in order to 767 satisfy requests from parties that it just gave the OBJREF to. 769 Member Type Semantic 770 ------------------------------------------------------------------ 771 std STDOBJREF A standard object reference used to 772 connect to the source object. 773 saResAddr STRINGARRAY The resolver address. 775 3.3.2 OBJREF_HANDLER 777 A marshaling of an object that wishes to use handler marshaling. For 778 example, an object wishes to be represented in client address spaces 779 by a proxy object that caches state. In this case, the class- 780 specific information is just a standard reference to an interface 781 pointer that the handler (proxy object) will use to communicate with 782 the original object. See the IStdMarshalInfo interface. 784 Member Type Semantic 785 ------------------------------------------------------------------ 786 std STDOBJREF A standard object reference used to 787 connect to the source object (Section 788 3.4). 789 clsid CLSID The CLSID of handler to create in the 790 destination client. 792 3.3.3 OBJREF_CUSTOM 794 A marshaling of an object which supports custom marshaling. The 795 Custom format gives an object control over the representation of 796 references to itself. For example, an immutable object might be 797 passed by value, in which case the class-specific information would 798 contain the object's immutable data. See the IMarshal interface. 800 Member Type Semantic 801 ------------------------------------------------------------------ 802 clsid CLSID The CLSID of the object to create in 803 the destination client. 804 size unsigned long The size of the marshaled data provided 805 by the source object and passed here in 806 pData. 807 pData byte* The data bytes that should be passed to 808 IMarshal::UnmarshalInterface on a new 809 instance of class clsid in order to 810 initialize it and complete the unmarshal 811 process. 813 3.4 STDOBJREF 815 An instance of a STDOBJREF represents a COM interface pointer that 816 has been marshaled using the standard COM network protocol. 818 The members and semantics of the STDOBJREF structure are as follows: 820 Member Semantic 821 ------------------------------------------------------------------ 822 flags Flag values taken from the enumeration SORFFLAGS. 823 These are described in Section 3.5. 824 crefs The number of reference counts on ipid that being 825 transferred in this marshaling. 826 Ipid The IPID of the interface being marshaled. 827 oid The OID of the object to which ipid corresponds. 828 oxid The OXID of the server that owns this OID. 830 3.5 SORFLAGS 832 The various SORFLAGS values have the following meanings. The 833 SORF_OXRESxxx bit flags are reserved for the object exporter's use 834 only, and must be ignored by object importers. They need not be 835 passed through when marshaling an interface proxy. 837 Flag Value Meaning 838 ------------------------------------------------------------------ 839 SORF_NULL 0 Convenient for initialization. 840 SORF_OXRES1 1 Reserved for exporter. 841 SORF_OXRES2 32 Reserved for exporter. 842 SORF_OXRES3 64 Reserved for exporter. 843 SORF_OXRES4 128 Reserved for exporter. 844 SORF_OXRES5 256 Reserved for exporter. 845 SORF_OXRES6 512 Reserved for exporter. 846 SORF_OXRES7 1024 Reserved for exporter. 847 SORF_OXRES8 2048 Reserved for exporter. 848 SORF_NOPING 4096 This OID does not require pinging. 849 Further, all interfaces on this OID, 850 including this IPID, need not be 851 reference counted. Pinging and 852 reference counting on this object and 853 its interfaces are still permitted, 854 however, though such action is 855 pointless. 857 3.6 ORPCINFOFLAGS 859 The various ORPCINFOFLAGS have the following meanings. 861 Flag Meaning 862 ------------------------------------------------------------------ 863 INFO_NULL (Not a real flag. Merely a defined constant 864 indicating the absence of any flag values.) 865 INFO_LOCAL The destination of this call is on the same machine 866 on which it originates. This value is never to be 867 specified in calls which are not in fact local. 868 INFO_RESERVED1 If INFO_LOCAL is set, then reserved for local use; 869 otherwise, reserved for future use. 870 INFO_RESERVED2 If INFO_LOCAL is set, then reserved for local use; 871 otherwise, reserved for future use. 872 INFO_RESERVED3 If INFO_LOCAL is set, then reserved for local use; 873 otherwise, reserved for future use. 874 INFO_RESERVED4 If INFO_LOCAL is set, then reserved for local use; 875 otherwise, reserved for future use. 877 Implementations may use the local and reserved flags to indicate 878 any extra information needed for local calls. Note that if the 879 INFO_LOCAL bit is not set and any of the other bits are set then 880 the receiver should return a fault. 882 3.7 ORPCTHIS 884 In every Request PDU that is an ORPC, the body (CL case) or the stub 885 data (CO case) which normally contains the marshaled arguments in 886 fact begins with an instance of the ORPCTHIS structure. The marshaled 887 arguments of the COM interface invocation follow the ORPCTHIS; thus, 888 viewed at the DCE RPC perspective, the call has an additional first 889 argument. The ORPCTHIS is padded with zero-bytes if necessary to 890 achieve an overall size that is a multiple of eight bytes; thus, the 891 remaining arguments are as a whole eight byte aligned. 893 As in regular calls, the causality id must be propagated. If A calls 894 ComputePi on B, B calls Release on C (which gets converted to 895 RemRelease), and C calls Add on A, A will see the same causality id 896 that it called B with. 898 Member Type Semantic 899 ------------------------------------------------------------------ 900 version COMVERSION The version number of the COM protocol 901 used to make this particular ORPC. The 902 initial value will be 4.1. Each packet 903 contains the sender's major and minor 904 ORPC version numbers. The client's and 905 server's major versions must be equal. 906 Backward compatible changes in the 907 protocol are indicated by higher minor 908 version numbers. Therefore, a server's 909 minor version must be greater than or 910 equal to the client's. However, if 911 the server's minor version exceeds the 912 client's minor version, it must return 913 the client's minor version and restrict 914 its use of the protocol to the minor 915 version specified by the client. A 916 protocol version mismatch causes the 917 RPC_E_VERSION_MISMATCH ORPC fault to 918 be returned. 919 Flags unsigned long Flag values taken from the enumeration 920 ORPCINFOFLAGS (section 3.6). 921 Reserved unsigned long Must be set to zero. 922 Cid CID The causality id of this ORPC. 923 Extensions ORPC_EXTENT_ARRAY* The body extensions, if any, passed 924 with this call. Body extensions are 925 GUID-tagged blobs of data which are 926 marshaled as an array of bytes. 927 Extensions are always marshaled with 928 initial eight byte alignment. Body 929 extensions which are presently defined 930 are described in Section 3.10. 932 The cid field contains the causality id. Each time a client makes 933 a unique call, a new causality id is generated. If a server makes a 934 call while processing a request from a client, the new call must 935 have the same causality id. This allows simple servers to avoid 936 working on more then one thing at a time (for example A calls B 937 calls A again, meanwhile C tries to call A with a new causality id). 938 It tells the server that he is being called because he asked someone 939 to do something for him. There are several interesting exceptions. 941 The causality id for maybe and idempotent calls must be set to 942 CID_NULL. If a server makes a ORPC call while processing such a 943 call, a new causality id must be generated. 945 In the face of network failures, the same causality id may end up 946 in use by two independent processes at the same time. If A calls B 947 calls C calls D and C fails, both B and D can independently, 948 simultaneously make calls to E with the same causality id. 950 The extensions field contains extensions to the channel header, 951 described in Section 3.10. Note that in order to force the 952 ORPCTHIS header to be 8 byte aligned an even number of extensions 953 must be present and the size of the extension data must be a 954 multiple of 8. 956 3.8 ORPCTHAT 958 In every Response PDU that is an ORPC, the body (CL case) or the stub 959 data (CO case) which normally contains the marshaled output 960 parameters in fact begins with an instance of the ORPCTHAT structure. 961 The marshaled output parameters of the COM interface invocation 962 follow the ORPCTHAT; thus, viewed at the DCE RPC perspective, the 963 call has an additional output parameters. The ORPCTHAT is padded with 964 zero-bytes if necessary to achieve an overall size that is a multiple 965 of eight bytes; thus, the remaining output parameters as a whole 966 eight byte aligned. 968 Member Type Semantic 969 ------------------------------------------------------------------ 970 flags unsigned long Flag values taken from the enumeration 971 ORPCINFOFLAGS (section 3.6). 972 Extensions ORPC_EXTENT_ARRAY* The body extensions, if any, 973 returned by this call. See Section 3.10 974 for a general description of body 975 extensions as well as a description of 976 existing well-known extensions. 978 3.9 HRESULTs 980 HRESULTs are the 32-bit return value from all ORPC methods. The 981 following is a partial list of already defined HRESULTs. 983 Further details TBS. 985 S_OK Success. 986 (0x00000000) 988 E_OUTOFMEMORY Insufficient memory to complete the call. 989 (0x80000002) 991 E_INVALIDARG One or more arguments are invalid. 992 (0x80000003) 994 E_NOINTERFACE No such interface supported 995 (0x80000004) 997 E_ACCESSDENIED A secured operation has failed due to 998 (0x80070005) inadequate security privileges. 1000 E_UNEXPECTED Unknown, but relatively catastrophic 1001 (0x8000FFFF) error. 1003 RPC_E_INVALID_OXID The object exporter was not found. 1004 (0x80070776) 1006 RPC_E_INVALID_OID The object specified was not found or 1007 (0x80070777) recognized. 1009 RPC_E_INVALID_SET The object exporter set specified was 1010 (0x80070778) not found. 1012 3.10 Body Extensions 1014 Body Extensions are UUID-tagged blobs of data which are useful for 1015 conveying additional, typically out-of-band, information on 1016 incoming invocations (within ORPCTHIS, Section 3.7) and in replies 1017 (within ORPCTHAT, Section 3.8). 1019 Any implementations of the DCOM protocol may define its own 1020 extensions with their own UUIDs. Implementations should skip over 1021 extensions which they do not recognize or do not wish to support. 1023 Body Extensions are marshaled as an array of bytes with initial 1024 eight byte alignment. 1026 The following sections descrobe several existing body extensions. 1028 3.10.1 Debugging Extension: {f1f19680-4d2a-11ce-a66a-0020af6e72f4} 1030 This extension aids in debugging ORPC. In particular it is designed 1031 to allow single stepping over an ORPC call into the server and out of 1032 the server into the client. 1034 Further details TBS. 1036 3.10.2 Extended Error Extension: {f1f19681-4d2a-11ce-a66a-0020af6e72f4} 1038 The extended error information body extension conveys extended error 1039 information concerning the original root cause of a error back to a 1040 caller can deal with it. This extension is only semantically useful 1041 in Response and Fault PDUs. 1043 It is intended that this error information is suitable for 1044 displaying information to a human being who is the user; this 1045 information is not intended to be the basis for logic decisions in a 1046 piece of client code, for doing so couples the client code to the 1047 implementation of the server. Rather, client code should act 1048 semantically only on the information returned through the interface 1049 that it invokes. 1051 Further details TBS. 1053 4. IRemUnknown interface 1055 The IRemUnknown interface is used by remote clients for manipulating 1056 reference counts on the IPIDs that they hold and for obtaining 1057 additional interfaces on the objects on which those IPIDs are found. 1059 References are kept per interface rather then per object. 1061 This interface is implemented by the COM "OXID object" associated 1062 with each OXID (nb. not each Object Exporter). The IPID for the 1063 IRemUnknown interface on this object is returned from 1064 IObjectExporter::ResolveOxid; see Section 5.2.1. An OXID object need 1065 never be pinged; its interfaces (this IPID included) need never be 1066 reference counted. IRemUnknown is specified as follows: 1068 //--------------------------------------------------------------- 1069 // The remote version of IUnknown. Once instance of this 1070 // interface exists per OXID (whether an OXID represents either 1071 // a thread or a process is implementation specific). This 1072 // interface is passed along during OXID resolution. It is used 1073 // by clients to query for new interfaces, get additional 1074 // references (for marshalling), and release outstanding 1075 // references. 1076 //--------------------------------------------------------------- 1078 // return structure from a QI call 1079 typedef struct tagREMQIRESULT { 1080 HRESULT hResult; // result of call 1081 STDOBJREF std; // data for returned interface 1082 } REMQIRESULT; 1084 // structure passed to AddRef/Release to specify interface and 1085 // count of references to Add/Release. 1086 typedef struct tagREMINTERFACEREF { 1087 IPID ipid; // ipid to AddRef/Release 1088 unsigned long cPublicRefs; 1089 unsigned long cPrivateRefs; 1090 } REMINTERFACEREF; 1092 [object, uuid(99fcff28-5260-101b-bbcb-00aa0021347a)] 1093 interface IRemUnknown : IUnknown { 1094 HRESULT RemQueryInterface( 1095 [in] IPID ipid, // interface to QI on 1096 [in] unsigned long cRefs, // count of AddRefs requested 1097 // for each interface 1098 [in] unsigned short cIids, // count of IIDs that follow 1099 [in, size_is(cIids)] 1100 IID* iids, // IIDs to query for 1101 [out, size_is(cIids)] 1102 REMQIRESULT** ppQIResults // results returned 1103 ); 1105 HRESULT RemAddRef( 1106 [in] unsigned short cInterfaceRefs, 1107 [in, size_is(cInterfaceRefs)] 1108 REMINTERFACEREF InterfaceRefs[], 1109 [out, size_is(cInterfaceRefs)] 1110 HRESULT* pResults 1111 ); 1113 HRESULT RemRelease( 1114 [in] unsigned short cInterfaceRefs, 1115 [in, size_is(cInterfaceRefs)] 1116 REMINTERFACEREF InterfaceRefs[], 1117 ); 1118 } 1120 4.1 IRemUnknown::RemQueryInterface 1122 QueryInterface for and return the result thereof for zero or more 1123 interfaces from the interface behind the IPID ipid. ipid must 1124 designate an interface derived from IUnknown (recall that all remoted 1125 interfaces must derive from IUnknown). The QueryInterface calls on 1126 the object that are used to service this request are conducted on 1127 the IUnknown interface of the object. 1129 Argument Type Semantic 1130 ------------------------------------------------------------------ 1131 ipid IPID The interface on an object from whom 1132 more interfaces are desired. 1133 cRefs REFCNT The number of references sought on each 1134 of the returned IIDs. 1135 cIids USHORT The number of interfaces being 1136 requested. 1137 iids IID* The list of IIDs that name the 1138 interfaces sought on this object. 1139 ppQIResults REMQIRESULT** The place at which the array of the 1140 results of the various QueryInterface 1141 calls are returned. 1143 Return Value Meaning 1144 --------------------------------------------------------------- 1145 S_OK Success. An attempt was made to retrieve 1146 each of the requested interfaces from 1147 the indicated object; that is, 1148 QueryInterface was actually invoked for 1149 each IID. 1150 E_INVALIDARG One or more arguments (likely ipid) were 1151 invalid. No result values are returned. 1152 E_UNEXPECTED An unspecified error occurred. No result 1153 values are returned. 1155 4.1.1 REMQIRESULT 1157 The REMQIRESULT structure contains the following members: 1159 Member Type Semantic 1160 ------------------------------------------------------------------ 1161 hResult HRESULT The result code from the QueryInterface 1162 call made for the requested IID. 1163 std STDOBJREF The data for the returned interface. 1164 Note that if hResult indicates failure 1165 then the contents of STDOBJREF are 1166 undefined. 1168 4.2 IRemUnknown::RemAddRef 1170 Obtain and grant ownership to the caller of one or more reference 1171 counts on one or more IPIDs managed by the corresponding OXID. 1173 Argument Type Semantic 1174 ------------------------------------------------------------------ 1175 cRefs unsigned short The size of the rgRefs array. 1176 rgRefs REMINTERFACEREF An array of IPID, cRefs pairs, cRefs 1177 large. Each IPID indicates an interface 1178 managed by this OXID on whom more 1179 reference counts are sought. The 1180 corresponding reference count (cRefs), 1181 which may not be zero (and thus is one 1182 or more), indicates the number of 1183 reference counts sought on that IPID. 1185 Return Value Meaning 1186 --------------------------------------------------------------- 1187 S_OK Success. An attempt was made to retrieve 1188 each of the requested interface 1189 references. 1190 E_INVALIDARG One or more of the IPIDs indicated were 1191 not in fact managed by this OXID, or one 1192 or more of the requested reference 1193 counts was zero. None of the requested 1194 reference counts have been granted to 1195 the caller; the call is a no-op. 1196 E_UNEXPECTED An unspecified error occurred. It is 1197 unknown whether any or all of the 1198 requested reference counts have been 1199 granted. 1201 A useful optimization is for a caller to RemAddRef more than needed. 1203 When a process receives an out marshaled interface, it receives one 1204 reference count. If the process wishes to pass that interface as an 1205 out parameter, it must get another reference to pass along. Instead, 1206 the process (or middleman) should get a large number of references. 1207 Then if the interface is passed out multiple times, no new remote 1208 calls are needed to gain additional references. 1210 A marshaler may optionally specify more than one reference in the 1211 STDOBJREF when marshaling an interface. This allows the middle man 1212 case to pre-fill its cache of references without making an extra 1213 RemAddRef call. The number of references passed is always 1214 specified in the STDOBJREF field. 1216 4.3 IRemUnknown::RemRelease 1218 Release ownership of one or more reference counts on one or more 1219 IPIDs managed by the corresponding OXID. 1221 Argument Type Semantic 1222 ------------------------------------------------------------------ 1223 cRefs unsigned short The size of the rgRefs array. 1224 rgRefs REMINTERFACEREF An array of IPID, cRefs pairs, cRefs 1225 large. Each IPID indicates an interface 1226 managed by this OXID on whom more 1227 reference counts are being returned. The 1228 corresponding reference count, which may 1229 not be zero (and thus is one or more), 1230 indicates the number of reference counts 1231 returned on that IPID. 1233 Return Value Meaning 1234 --------------------------------------------------------------- 1235 S_OK Success. An attempt was made to release 1236 each of the requested interface 1237 references. 1238 E_INVALIDARG One or more of the IPIDs indicated were 1239 not in fact managed by this OXID, or one 1240 or more of the requested reference 1241 counts was zero. None of the offered 1242 reference counts have been accepted by 1243 the server; the call is a no-op. 1244 E_UNEXPECTED An unspecified error occurred. It is 1245 unknown whether any or all of the 1246 offered reference counts have been 1247 accepted. 1249 5. The Object Exporter 1251 Each machine that supports the COM network protocol supports a one- 1252 per-machine service known as the machine's `Object Exporter.' 1253 Communication with an Object Exporter is via a DCE RPC, not an 1254 ORPC. 1256 The Object Exporter performs several services: 1258 It caches and returns to clients when asked the string bindings 1259 necessary to connect to OXIDs of exported objects for which this 1260 machine is it either itself a client or is the server. 1262 It receives pings from remote client machines to keep its own 1263 objects alive. 1265 These services are carried out through an RPC interface (not a COM 1266 interface) known as IObjectExporter. An Object Exporter may be 1267 asked for the information required to connect to one of two 1268 different kinds of OXIDs, either the OXIDs associated with its own 1269 objects, or the OXIDs associated with objects for which it itself 1270 is a client, and which it has passed on to a second client 1271 machine. This second case, where one marshals an object from one 1272 client machine to a second, is colloquially referred to the 1273 "middleman" case. In the middleman case, the exporter is required 1274 to retain the connection information associated with the OXIDs 1275 that it passes on until it is certain that that the second client 1276 machine no longer needs them. 1278 5.1 Object Exporter Ports/Endpoints 1280 The Object Exporter resides at different endpoints (ports) depending 1281 on the transport being used. The Object Exporter optimally resides 1282 at the same endpoints as the DCE RPC Endpoint Mapper (EPM). To 1283 accommodate systems where DCOM will coexist with existing DCE RPC 1284 installations (i.e., where an EPM and presumably a complete DCE RPC 1285 runtime already exists), the DCOM implementation on that system will 1286 register its interfaces with the DCE EPM and all DCOM implementations 1287 must be able to fall back if they make DCOM-specific calls on the DCE 1288 EPM endpoint which fail. 1290 Protocol String 1291 Name(s) Description Endpoint 1292 ------------------------------------------------------------------ 1293 ncadg_ip_udp, ip CL over UDP/IP 135 1294 ncacn_ip_tcp CO over TCP/IP 135 1295 ncadg_ipx CL over IPX TBD 1296 ncacn_spx CO over SPX TBD 1297 ncacn_nb_nb CO over NetBIOS over NetBEUI TBD 1298 ncacn_nb_tcp CO over NetBIOS over TCP/IP 135 1299 ncacn_np CO over Named Pipes TBD 1300 ncacn_dnet_nsp CO over DECNet Network Services 96 1301 Protocol (DECNet Phase IV) 1302 ncacn_osi_dna CO over Open Systems 69 1303 Interconnection (DECNet Phase V) 1304 ncadg_dds, dds CL over Domain Datagram Service 12 1305 ncahttp Hybrid over HTTP (TBS) 80 1307 5.2 The IObjectExporter Interface 1309 IObjectExporter is defined as follows: 1311 [uuid(99fcfec4-5260-101b-bbcb-00aa0021347a)] 1312 interface IObjectExporter { 1314 [idempotent] error_status_t ResolveOxid( 1315 [in] handle_t hRpc, 1316 [in] OXID *pOxid, 1317 [in] unsigned short cRequestedProtseqs, 1318 [in, ref, size_is(cRequestedProtseqs)] 1319 unsigned short arRequestedProtseqs[], 1320 [out, ref] DUALSTRINGARRAY **psaOxidBindings, 1321 [out, ref] IPID *pipidRemUnknown, 1322 [out, ref] unsigned long *pdwAuthnHint 1323 ); 1325 [idempotent] error_status_t SimplePing( 1326 [in] handle_t hRpc, 1327 [in] SETID *pSetId 1328 ); 1330 [idempotent] error_status_t ComplexPing( 1331 [in] handle_t hRpc, 1332 [in] SETID *pSetId, 1333 [in] unsigned short SequenceNum, 1334 [in] unsigned short cAddToSet, 1335 [in] unsigned short cDelFromSet, 1336 [in, unique, size_is(cAddToSet)] 1337 OID AddToSet[], 1338 [in, unique, size_is(cDelFromSet)] 1339 OID DelFromSet[] 1340 [out] unsigned short *pPingBackoffFactor 1341 ); 1342 } 1344 5.2.1 IObjectExporter::ResolveOxid 1346 Return the string bindings necessary to connect to a given OXID 1347 object. 1349 On entry, arRequestedProtseqs contains the protocol sequences the 1350 client is willing to use to reach the server. These should be 1351 decreasing order of protocol preference, with no duplicates 1352 permitted. Local protocols (such as "ncalrpc") are not permitted. 1354 On exit, psaOxidBindings contains the string bindings that may be 1355 used to connect to the indicated OXID; if no such protocol bindings 1356 exist which match the requested protocol sequences, NULL may be 1357 returned. The returned string bindings are in decreasing order of 1358 preference of the server, with duplicate string bindings permitted 1359 (and not necessarily of the same preferential priority), though of 1360 course duplicates are of no utility. Local protocol sequences may 1361 not be present; however, protocol sequences that were not in the 1362 set of protocol sequences requested by the client may be. The 1363 string bindings returned need not contain endpoints; the endpoint 1364 mapper will be used as usual to obtain these dynamically. 1366 If a ResolveOxid call is received for which the recipient Object 1367 Exporter is a middleman, the action required of the middleman 1368 depends on how the ordered list of requested protocol sequences 1369 (arRequested-Protseqs) relate to lists of protocol sequences 1370 previously known by the middleman to have been previously requested 1371 of the server. If the list of requested protocol sequences is a 1372 (perhaps non-proper) subset in order of a protocol sequence list 1373 previously requested of the server, then the corresponding cached 1374 string bindings may be returned immediately to the caller without 1375 actually communicating with the server. Otherwise, the actual 1376 psaRequestedProtseqs must be forwarded to the server, and the 1377 returned string bindings propagated back to the client. In such 1378 cases, it behooves the middleman to cache the returned string 1379 bindings for use in later calls. 1381 Argument Type Description 1382 ------------------------------------------------------------------ 1383 hRpc handle_t An RPC binding handle used to make the 1384 request. 1385 pOxid OXID* The OXID for whom string bindings are 1386 requested. The OXID may or may not 1387 represent a process on the machine that 1388 receives the ResolveOxid call. 1389 cRequestedProtseqs 1390 unsigned short The number of protocol sequences 1391 requested. 1392 arRequestedProtseqs 1393 unsigned short[] arRequestedProtseqs must be 1394 initialized with all the protocol id's 1395 the client is willing to use to reach 1396 the server. It cannot contain local 1397 protocol sequences. The object exporter 1398 must take care of local lookups 1399 privately. The protocol sequences are 1400 in order of preference or random order. 1401 No duplicates are allowed. See the 1402 Lazy Use Protseq section for more 1403 details. 1404 psaOxidBindings 1405 STRINGARRAY** The string bindings supported by this 1406 OXID, in preferential order. Note that 1407 these are Unicode strings. 1408 pipidRemUnknown 1409 IPID* The IPID to the IRemUnknown interface 1410 the OXID object for this OXID. 1412 pdwAuthnHint unsigned long* A value taken from the RPC_C_AUTHN 1413 constants. A hint to the caller as to the 1414 minimum authentication level which the 1415 server will accept. 1417 Return Value Meaning 1418 --------------------------------------------------------------- 1419 S_OK Success. The requested information was 1420 returned. 1421 RPC_E_INVALID_OXID This OXID is unknown to this Object 1422 Exporter, and thus no information was 1423 returned. 1424 E_UNEXPECTED An unspecified error occurred. Some of 1425 the requested information may not be 1426 returned. 1428 Since the object exporter ages string bindings and discards them, 1429 object references are transient things. They are not meant to be 1430 stored in files or otherwise kept persistently. In any case, well 1431 known object references can be constructed from well known string 1432 bindings, IPIDs and OIDs. 1434 Conversely, since object references are aged, it is the 1435 responsibility of each client to unmarshal them and begin pinging 1436 them in a timely fashion. 1438 The basic use of the ResolveOxid method is to translate an OXID to 1439 string bindings. Put another way, this method translates an opaque 1440 process and machine identifier to the information needed to reach 1441 that machine and process. There are four interesting cases: 1443 1. Looking up an OXID the first time an interface is 1444 unmarshaled on a machine, 1445 2. Looking up an OXID between a pair of machines that already 1446 have connections, and 1447 3. Looking up an OXID from a middleman, and 1448 4. Looking up string bindings with unresolved endpoints 1449 (lazy use protseq). 1451 Another interesting topic is garbage collection of stored string 1452 binding vectors. 1454 5.2.1.2 Lookup Between Friends 1456 The case of a lookup between two machines that have already 1457 established communication is the easiest. In this scenario there 1458 are two machines, A and B. Process D already has an interface 1459 pointer to process F. Object exporter C already knows the string 1460 bindings for object exporter E and process F, but not process G. 1462 +=========+===========+==+=========+===========+===========+ 1463 | OX C | Process D | | OX E | Process F | Process G | 1464 +=========+===========+==+=========+===========+===========+ 1465 | | call F | | | | | 1466 +---------+-----------+--+---------+-----------+-----------+ 1467 | | | | | pass out | | 1468 | | | | | ref to G | | 1469 +---------+-----------+--+---------+-----------+-----------+ 1470 | | receive | | | | | 1471 | | out ref | | | | | 1472 | | to G | | | | | 1473 +---------+-----------+--+---------+-----------+-----------+ 1474 | | ask local | | | | | 1475 | | OX to | | | | | 1476 | | resolve G | | | | | 1477 +---------+-----------+--+---------+-----------+-----------+ 1478 | ask OX | | | | | | 1479 | E to | | | | | | 1480 | resolve | | | | | | 1481 | OXID G | | | | | | 1482 +---------+-----------+--+---------+-----------+-----------+ 1483 | | | | lookup | | | 1484 | | | | G and | | | 1485 | | | | return | | | 1486 | | | | endpts | | | 1487 +---------+-----------+--+---------+-----------+-----------+ 1488 | cache | | | | | | 1489 | binding | | | | | | 1490 | vector | | | | | | 1491 | for G, | | | | | | 1492 | return | | | | | | 1493 | to D | | | | | | 1494 +---------+-----------+--+---------+-----------+-----------+ 1495 | | ready to | | | | | 1496 | | call G | | | | | 1497 +---------+-----------+--+---------+-----------+-----------+ 1499 Object exporter E knows the string bindings for all the servers on 1500 its machine, i.e. processes F and G. Process D calls process F and 1501 gets a reference to process G. Since process D has never seen the 1502 OXID for G before, it asks its local object exporter to resolve G. 1503 Process D also has to tell object exporter C where it got the 1504 reference from, in this case, process F. Object exporter C does 1505 not recognize the OXID G. However it does recognize the OXID F 1506 and knows the object exporter E is on the same machine as process 1507 F. So OX C calls ResolveOxid on OX E. OX E recognizes G and passes 1508 the string bindings back to OX C with the machine id B. OX C caches 1509 this information so that if D ever gets a reference from G, it 1510 knows who to ask to resolve that reference. 1512 5.2.1.2 My First Lookup 1514 The previous example assumes that OX C already knows about OX E and 1515 process D is already talking to process F. Setting up the first 1516 connection between D and F (as well as C and E) is a tricky 1517 business known as activation. ORPC as described in this 1518 specification does not include activation models. Thus different 1519 vendors may have different activation models. However there is one 1520 basic form of activation shared by all ORPC. If two processes can 1521 communicate via DCE RPC, they can pass long standard object 1522 references. While this is not expected to be a common form of 1523 activation, it is a simple one that should certainly work across 1524 all ORPC implementations. Thus if D and E have established DCE RPC 1525 (or raw RPC) communication, they can bootstrap ORPC communication 1526 as follows. 1528 +==============+==============+==+==============+==============+ 1529 | OX C | Process D | | OX E | Process F | 1530 +==============+==============+==+==============+==============+ 1531 | | | | register | | 1532 | | | | endpointts & | | 1533 | | | | OXID for F | | 1534 |--------------+--------------+--+--------------+--------------+ 1535 | | call F with | | | | 1536 | | raw RPC | | | | 1537 |--------------+--------------+--+--------------+--------------+ 1538 | | | | | pass an out | 1539 | | | | | ref to F, | 1540 | | | | | pass IID as | 1541 | | | | | additional | 1542 | | | | | parameter | 1543 |--------------+--------------+--+--------------+--------------+ 1544 | | tell C the | | | | 1545 | | OXID_INFO | | | | 1546 | | for F. | | | | 1547 | | includes net | | | | 1548 | | address(es) | | | | 1549 |--------------+--------------+--+--------------+--------------+ 1550 | compute the | | | | | 1551 | string bind- | | | | | 1552 | ings for OX | | | | | 1553 | E from F. | | | | | 1554 | ask E to | | | | | 1555 | resolve F | | | | | 1556 | to get end- | | | | | 1557 | points for F | | | | | 1558 |--------------+--------------+--+--------------+--------------+ 1559 | | | | return end- | | 1560 | | | | points | | 1561 |--------------+--------------+--+--------------+--------------+ 1562 | | ready to | | | | 1563 | | call F | | | | 1564 |--------------+--------------+--+--------------+--------------+ 1566 This example points out that there has to be a local interface 1567 between processes and the local object exporter. 1569 5.2.1.3 Middleman Lookup 1571 The next case shows how lookup works between multiple machines. 1573 Suppose that E has a reference to G and G has a reference to I. 1575 Similarly, D knows about F and G and F knows about H and I. What 1576 happens if G passes a reference to I over to E? 1578 +=============+===========+======+============+========+===========+ 1579 | OX D | Process E | OX F | Process G | OX H | Process I | 1580 +=============+===========+======+============+========+===========+ 1581 | | call G | | | | | 1582 +-------------+-----------+------+------------+--------+-----------+ 1583 | | | | return a | | | 1584 | | | | long ref | | | 1585 | | | | to I | | | 1586 +-------------+-----------+------+------------+--------+-----------+ 1587 | | ask D to | | | | | 1588 | | lookup I | | | | | 1589 +-------------+-----------+------+------------+--------+-----------+ 1590 | since it's | | | | | | 1591 | long, call | | | | | | 1592 | ResolveOxid | | | | | | 1593 | on H | | | | | | 1594 +-------------+-----------+------+------------+--------+-----------+ 1595 | | | | | return | | 1596 | | | | | end- | | 1597 | | | | | points | | 1598 | | | | | to I | | 1599 +-------------+-----------+------+------------+--------+-----------+ 1600 | compute | | | | | | 1601 | bindings to | | | | | | 1602 | I from end- | | | | | | 1603 | points & | | | | | | 1604 | network | | | | | | 1605 | addresses | | | | | | 1606 | return | | | | | | 1607 | string | | | | | | 1608 | bindings to | | | | | | 1609 | E | | | | | | 1610 +-------------+-----------+------+------------+--------+-----------+ 1612 Note that when process G returned a reference to I, it used he long 1613 form of the OBJREF which includes the protocol id's and network 1614 addresses of the OXID resolver for process I (in this example, the 1615 addresses for OX H). This would results in OX D calling OX H 1616 directly, rather than needing to call OX F. The advantage of this 1617 is that if no references to process I needed by OX F, it could 1618 remove it from its OXID cache at any time, rather than keeping it 1619 around at least until OX D has had a chance to call it back to 1620 resolve OXID I. 1622 5.2.1.4 Lazy Use Protseq 1624 In a homogeneous network, all machines communication via the same 1625 protocol sequence. In a heterogeneous network, machines may support 1626 multiple protocol sequences. Since it is often expensive in 1627 resources to allocate endpoints (RpcServerUseProtseq) for all 1628 available protocol sequences, ORPC provides a mechanism where they 1629 may be allocated on demand. To implement this extension fully, there 1630 are some changes in the server. However, changes are optional. If 1631 not implemented, ORPC will still work correctly if less optimally 1632 in heterogeneous networks. 1634 There are two cases: the server implements the lazy use protocol or 1635 it does not. 1637 If the server is using the lazy use protseq protocol, the use of 1638 ResolveOxid is modified slightly. When the client OX calls the 1639 server OX, it passes the requested protseq vector. If none of the 1640 requested protseqs have endpoints allocated in the server, the 1641 server OX performs some local magic to get one allocated. 1643 If the server does not implement the lazy use protseq protocol, 1644 then all protseqs are registered by the server and contain 1645 complete endpoints. However, if they are not, the endpoint mapper 1646 can be used to forward calls to the server. This requires that all 1647 server IIDs are registered in the endpoint mapper. It also allows 1648 a different lazy use protseq mechanism. The endpoint mapper can 1649 perform some local magic to force the server to allocate an 1650 endpoint. This is less efficient since no OXs ever learn the new 1651 endpoints. 1653 The client will always pass in a vector of requested protseqs which 1654 the server can ignore if it does not implement the lazy use protseq 1655 protocol. 1657 5.4 IObjectExporter::SimplePing 1659 Pings provide a mechanism to garbage collect interfaces. If an 1660 interface has references but is not being pinged, it may be 1661 released. Conversely, if an interface has no references, it may be 1662 released even though it has recently been pinged. SimplePing just 1663 pings the contents of a set. The set must be created with 1664 ComplexPing (section 5.2.3). 1666 Ping a set, previously created with IObjectExporter::ComplexPing, of 1667 OIDs owned by this Object Exporter. Note that neither IPIDs nor OIDs 1668 may be pinged, only explicitly created SETIDs. 1670 Argument Type Description 1671 ------------------------------------------------------------------ 1672 hRpc handle_t An RPC binding handle used to make the 1673 request. 1674 pSetId SETID* A SETID previously created with 1675 IObjectExporter::ComplexPing on this 1676 same Object Exporter. 1678 Return Value Meaning 1679 --------------------------------------------------------------- 1680 S_OK Success. The set was pinged. 1681 RPC_E_INVALID_SET This SETID is unknown to this Object 1682 Exporter, and thus the ping did not 1683 occur. 1684 E_UNEXPECTED An unspecified error occurred. It is 1685 not known whether the ping was done or 1686 not. 1688 5.5 IObjectExporter::ComplexPing 1690 Ping a ping set. Optionally, add and/or remove some OIDs from the 1691 set. Optionally, adjust some ping timing parameters associated with 1692 the set. After a set is defined, a SimplePing will mark the entire 1693 contents of the set as active. After a set is defined, SimplePing 1694 should be used to ping the set. ComplexPing need only be used to 1695 adjust the contents of the set (or to adjust the time-out). 1697 Ping set ids (SETIDs) are allocated unilaterally by a client Object 1698 Exporter. The client Object Exporter then communicates with the 1699 server Object Exporter to add (and later remove) OIDs from the ping 1700 set. Clients must ensure the SETIDs pinged at a given server are 1701 unique over all of that server's clients. Thus, the client must only 1702 use SETIDs that it knows not to be in use as SETIDs by other clients 1703 on that server. (In practice, clients allocate SETIDs as globally 1704 unique). A client may use as many sets as it likes, though using 1705 fewer sets is more efficient. 1707 Each OID owned by a server Object Exporter may be placed in zero or 1708 more ping sets by the various clients of the OID. The client owner 1709 of each such set will set a ping period and a ping time-out count 1710 for the set, thus determining an overall time-out period for the set 1711 as the product of these two values. The time-out period is 1712 implicitly applied to each OID contained in the set and to future 1713 OIDs that might add be added to it. The server Object Exporter is 1714 responsible for ensuring that an OID that it owns does not expire 1715 until at least a period of time t has elapsed without that OID being 1716 pinged, where t is the maximum time-out period over all the sets 1717 which presently contain the given OID, or, if OID is not presently 1718 in any such sets but was previously, t is the time-out period for 1719 the last set from which OID was removed at the instant that that 1720 removal was done; otherwise, OID has never been in a set, and t 1721 is a default value (ping period equals 120 seconds, ping time-out 1722 count equals three (3), t equals 360 seconds, or six (6) minutes). 1724 Clients are responsible for pinging servers often enough to ensure 1725 that they do not expire given the possibility of network delays, lost 1726 packets, and so on. If a client only requires access to a given 1727 object for what it would consider less than a time-out period for the 1728 object (that is, it receives and release the object in that period of 1729 time), then unless it is certain it has not itself passed the object 1730 to another client it must be sure to nevertheless ping the object (a 1731 ComplexPing that both adds and removes the OID will suffice). This 1732 ensures that an object will not expire as it is passed through a 1733 chain of calls from one client to another. 1735 An OID is said to be pinged when a set into which it was previously 1736 added and presently still resides is pinged with either a SimplePing 1737 or a ComplexPing, or when it is newly added to a set with 1738 ComplexPing. Note that these rules imply that a ComplexPing that 1739 removes an OID from a set still counts as a ping on that OID. 1740 In addition to pinging the set SETID, this call sets the time-out 1741 period of the set as the product of a newly-specified ping period and 1743 a newly-specified "ping count to expiration;" these values take 1744 effect immediately. Ping periods are specified in tenths of a second, 1746 yielding a maximum allowable ping period of about 1 hr 50 min. 1748 Adjustment of the time-out period of the set is considered to happen 1749 before the addition of any new OIDs to the set, which is in turn 1750 considered to happen before the removal of any OIDs from the set. 1751 Thus, an OID that is added and removed in a single call no longer 1752 resides in the set, but is considered to have been pinged, and will 1753 have as its time-out at least the time-out period specified in that 1754 ComplexPing call. 1756 On exit, the server may request that the client adjust the time-out 1757 period; that is, ask it to specify a different time-out period in 1758 subsequent calls to ComplexPing. This capability can be used to 1759 reduce traffic in busy servers or over slow links. The server 1760 indicates its desire through the values it returns through the 1761 variables pReqSetPingPeriod and pReqSetNumPingsToTimeOut. If the 1762 server seeks no change, it simply returns the corresponding values 1763 passed by the client; if it wishes a longer time-out period, it 1764 indicates larger values for one or both of these variables; if it 1765 wishes a smaller period, it indicates smaller values. When indicating 1766 a larger value, the server must start immediately acting on that 1767 larger value by adjusting the time-out period of the set. However, 1768 when indicating a smaller value, it must consider its request as 1769 purely advice to the client, and not take any action: if the client 1770 wishes to oblige, it will do so in a subsequent call to ComplexPing 1771 by specifying an appropriate time-out period. 1773 Argument Type Description 1774 ------------------------------------------------------------------ 1775 hRpc handle_t An RPC binding handle used to make the 1776 request. 1777 pSetId SETID The SETID being manipulated. 1778 SequenceNum unsigned short The sequence number allows the object 1779 exporter to detect duplicate packets. 1780 Since the call is idempotent, it is 1781 possible for duplicates to get executed 1782 and for calls to arrive out of order 1783 when one ping is delayed. 1784 cAddToSet unsigned short The size of the array AddToSet. 1785 cDelFromSet unsigned short The size of the array DelFromSet. 1786 AddToSet OID[] The list of OIDs which are to be added 1787 to this set. Adding an OID to a set in 1788 which it already exists is permitted; 1789 such an action, as would be expected, 1790 is considered to ping the OID. 1791 DelFromSet OID[] The list of OIDs which are to be removed 1792 from this set. Removal counts as a ping. 1793 An IPID removed from a set will expire 1794 after the number of ping periods has 1795 expired without any pings (not the 1796 number of ping periods - 1). If an id is 1797 added and removed from a set in the same 1798 ComplexPing, the id is considered to 1799 have been deleted. 1800 pPingBackoffFactor 1801 unsigned short* Acts as a hint (only) from the server to 1802 the client in order to reduce ping 1803 traffic. Clients are requested to not ping 1804 more often than (1<<*pPingBackoffFactor)* 1805 (BasePingInterval=120) seconds, and the 1806 number of pings until timeout remains 1807 unchanged at the default of 3. Clients may 1808 choose to assume that this parameter is 1809 always zero. 1811 Return Value Meaning 1812 --------------------------------------------------------------- 1813 S_OK Success. The set was pinged, etc. 1814 RPC_E_INVALID_OID Indicates that some OID was not 1815 recognized. There is no recovery action 1816 for this error, it is informational only. 1817 E_ACCESSDENIED Access is denied. 1818 E_OUTOFMEMORY There was not enough memory to service 1819 the call. The caller may retry adding 1820 OIDs to the set on the next ping. 1821 E_UNEXPECTED An unspecified error occurred. It is not 1822 known whether the ping or any of the 1823 other actions were done or not. 1825 6. Security Considerations 1827 In general, like any generic data transfer protocol, DCOM cannot 1828 regulate the content of the data that is transferred, nor is there 1829 any a priori method of determining the sensitivity of any particular 1830 piece of information within the context of any given ORPC. 1832 Specifically, however, DCOM entirely leverages the security 1833 infrastructure defined by DCE RPC, which allows for various forms of 1834 authentication, authorization, and message integrity. 1836 Further details TBS. 1838 7. Acknowledgements 1840 As previously noted, the DCOM protocol highly leverages the DCE 1841 RPC Specification [CAE RPC], and we again acknowledge its 1842 usefulness to this specification. 1844 The DCOM protocol itself is the combined effort of a large number 1845 of people. The following individuals in particular were critical 1846 to the definitions which appear in this specification. 1848 Bob Atkinson Deborah Black 1849 Vibhas Chandorkar Richard Draves 1850 Mario Goertzel Rick Hill 1851 Gregory Jensenworth David Kays 1852 Paul Leach Alex Mitchell 1853 Kevin Ross Mark Ryland 1854 Bharat Shah Tony Williams 1856 8. References 1858 [CAE RPC] CAE Specification, X/Open DCE: Remote Procedure Call, 1859 X/Open Company Limited, Reading, Berkshire, UK 1860 (xopen.co.uk), 1994. X/Open Document Number C309. 1861 ISBN 1-85912-041-5. 1862 (also available online through from the OSF at 1863 after 1864 registration) 1866 [COM] The Component Object Model Specification, Version 0.9, 1867 October 24, 1995, Microsoft Corporation. 1868 (also available online from Microsoft at 1869 1872 9. Author's Addresses 1874 Nat Brown 1875 One Microsoft Way 1876 Redmond, WA 98052-6399, U.S.A. 1877 Fax: +1 (206) 936 7329 1878 Email: natbro@microsoft.com 1880 Charlie Kindel 1881 One Microsoft Way 1882 Redmond, WA 98052-6399, U.S.A. 1883 Fax: +1 (206) 936 7329 1884 Email: ckindel@microsoft.com