idnits 2.17.1 draft-brown-dcom-v1-spec-01.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-26) 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. == There are 26 instances of lines with non-ascii characters in the document. == No 'Intended status' indicated for this document; assuming Proposed Standard == The page length should not exceed 58 lines per page, but there was 34 longer pages, the longest (page 29) being 92 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. Miscellaneous warnings: ---------------------------------------------------------------------------- == Line 204 has weird spacing: '... to the serve...' == Line 270 has weird spacing: '...esolver which...' == Line 271 has weird spacing: '...ference for t...' == Line 349 has weird spacing: '...ound on the O...' == Line 472 has weird spacing: '...ng into sets ...' == (43 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.) -- Couldn't find a document date in the document -- date freshness check skipped. -- 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: 7 errors (**), 0 flaws (~~), 9 warnings (==), 5 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group Nat Brown 3 INTERNET-DRAFT Charlie Kindel 4 Microsoft Corporation 5 Expires in six months November, 1996 7 Distributed Component Object Model Protocol -- DCOM/1.0 9 Status of this Memo 11 This document is an Internet-Draft. Internet-Drafts are working 12 documents of the Internet Engineering Task Force (IETF), its areas, 13 and its working groups. Note that other groups may also distribute 14 working documents as Internet-Drafts. 16 Internet-Drafts are draft documents valid for a maximum of six months 17 and may be updated, replaced, or obsoleted by other documents at any 18 time. It is inappropriate to use Internet-Drafts as reference material 19 or to cite them other than as "work in 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 at (Africa), 24 (Europe), 25 (Pacific Rim), 26 (US East Coast), or 27 (US West Coast). 29 Distribution of this document is unlimited. Please send comments to 30 the authors at . General discussions 31 about DCOM and its applications should take place on the DCOM mailing 32 list. To subscribe, send a piece of mail to 33 . Leave the subject blank and in the 34 body of the message, first type "subscribe" for non-digest or "digest" 35 for digest version, followed by "DCOM", and finally by your name. 36 (example: "subscribe DCOM John Doe"). 38 See for more 39 details. 41 Abstract 43 The Distributed Component Object Model protocol is an application- 44 level protocol for object-oriented remote procedure calls useful for 45 distributed, component-based systems of all types. It is a generic 46 protocol layered on the distributed computing environment (DCE) RPC 47 specification and facilitates the construction of task-specific 48 communication protocols through features such as: a platform neutral 49 argument/parameter marshaling format (NDR), the ability for objects to 50 support multiple interfaces with a safe, interface-level versioning 51 scheme suited to independent evolution by multiple parties, the 52 ability to make authenticated connections and to choose levels of 53 channel security, and a transport-neutral data representation for 54 references (including by-value) to objects. 56 Table of Contents 58 Status of this Memo...................................1 60 Abstract..............................................1 62 Table of Contents.....................................2 64 1. Introduction.......................................3 66 1.1 Purpose......................................3 68 2. Overall Operation..................................4 70 2.1 Object Calls.................................4 71 2.2 OXIDs and Object Exporters...................5 72 2.3 Marshaled Interface References...............5 73 2.4 Reference Counting...........................6 74 2.5 Pinging......................................7 75 2.6 QueryInterface...............................9 76 2.7 Causality ID.................................9 78 3. Data Types and Structures..........................9 80 3.1 DCE Packet Headers...........................9 81 3.2 ORPC Base Definitions.......................10 82 3.3 OBJREF......................................14 83 3.4 STDOBJREF...................................15 84 3.5 SORFLAGS....................................16 85 3.6 ORPCINFOFLAGS...............................16 86 3.7 ORPCTHIS....................................17 87 3.8 ORPCTHAT....................................18 88 3.9 HRESULTs....................................18 89 3.10 Body Extensions............................19 91 4. IRemUnknown interface.............................20 93 4.1 IRemUnknown::RemQueryInterface..............21 94 4.2 IRemUnknown::RemAddRef......................22 95 4.3 IRemUnknown::RemRelease.....................23 97 5. The OXID Resolver.................................24 99 5.1 OXID Resolver Ports/Endpoints...............24 100 5.2 The IOXIDResolver Interface.................25 102 6. Security Considerations...........................33 104 7. Acknowledgements..................................33 106 8. References........................................33 108 9. Author's Addresses................................34 109 1. Introduction 111 The Distributed Component Object Model protocol (DCOM) is an 112 application-level protocol for object-oriented remote procedure calls 113 and is thus also called "Object RPC" or ORPC. The protocol consists of 114 a set of extensions, layered on the distributed computing environment 115 (DCE) RPC specification [CAE RPC], with which familiarity is assumed. 116 Familiarity is also assumed with the COM (Component Object Model) 117 specification [COM]. 119 Object RPC specifies: 121 � How calls are made on an object 123 � How object references are represented, communicated, and maintained 125 1.1 Purpose 127 There is a natural tendency in a networked environment to create 128 entirely new application-level protocols as each new or seemingly 129 unique combination of client, user agent, and server requirement 130 arises. 132 While in many situations the definition of a new protocol is useful 133 and justifiable, there are numerous features which have eventually 134 been added to or required from each new protocol (or which become 135 layered above them) as they evolve and become used in broader 136 contexts. 138 A design goal of the DCOM protocol is the inherent support of standard 139 features required by any distributed application communication 140 protocol. In other words, to act as a framework to facilitate the 141 construction of task-specific communication paths between distributed 142 applications. 144 Data Marshaling 146 A common occurrence among user agents using the HTTP protocol today is 147 the use of complex, task-specific Query URL syntax and HTTP POSTs. 148 Also increasingly common is the POSTing and response with custom MIME 149 types to and from resources which interpret the format and reply in 150 same. While workable, there are drawbacks to this approach including 151 increased complexity and work to produce and consume each new (and 152 unique) format in the client and server, lessened ability to build 153 task-specific firewalls for administration and security purposes, and 154 in many cases definition of platform-centric formats. 156 DCOM utilizes the Network Data Representation (NDR) for arbitrary data 157 types supported by DCE RPC. 159 Security 161 DCOM leverages the authentication, authorization, and message 162 integrity capabilities of DCE RPC. An implementation may support any 163 level of DCE RPC security. Any connection or call can be made as 164 secure or as insecure as negotiated by the client and the server. 166 Safe Non-Coordinated Versioning of Interfaces 168 In DCOM versioning of interfaces is done through identifiers which are 169 universally unique (UUID's). To version a published interface, a new 170 interface is defined with a different UUID to the updated 171 specification. Multiple parties can simultaneously introduce 172 "revisions" to interfaces by defining related but distinct interfaces 173 without fear of colliding with each other's version numbers and 174 without fear of breaking each other's down-level or up-level clients. 176 To date, the bulk of task-specific protocols (such as custom POSTs or 177 MIME types using HTTP) have little or no concept of versioning at all, 178 and simply "narrow" the incompatibility window by updating clients 179 (typically pages which are being downloaded anyway) and servers (CGI 180 scripts or other HTTP server infrastructure) simultaneously. 182 2. Overall Operation 184 The Object RPC protocol highly leverages the OSF DCE RPC network 185 protocol (see the reference [CAE RPC]). This leverage occurs at both 186 the specification level and the implementation level: the bulk of the 187 implementation effort involved in implementing the DCOM network 188 protocol is in fact that of implementing the DCE RPC network protocol 189 on which it is built. 191 2.1 Object Calls 193 An actual COM network remote procedure call (hereinafter referred to 194 as "an ORPC") is in fact a true DCE remote procedure call (herein 195 termed "a DCE RPC"), a "Request PDU" conforming to the specification 196 for such calls per [CAE RPC]. 198 In an ORPC, the object ID field of the invocation header as specified 199 in [CAE RPC] contains an "IPID". An IPID is a 128-bit identifier known 200 as an interface pointer identifier which represents a particular 201 interface on a particular object in a particular server. As it is 202 passed in the object ID fields of a DCE RPC, the static type of an 203 IPID is in fact a UUID. However, IPIDs are scoped not globally but 204 rather only relative to the server process which originally 205 allocated them; IPIDs do not necessarily use the standard UUID 206 allocation algorithm, but rather may use a machine-specific algorithm 207 which can assist with dispatching. 209 In an ORPC, the interface ID field of the RPC header specifies the 210 IID, and arguments are found in the body, as usual. However, when 211 viewed from the DCE RPC perspective an additional first argument is 212 always present that is absent in the corresponding COM interface 213 specification. This argument is of type ORPCTHIS, which is described 214 in Section 3.7. It is placed first in the body of the Request PDU, 215 before the actual arguments of the ORPC. 217 It is specifically legal for an ORPC to attempt a call a method number 218 on a given interface which is beyond the number of methods believed by 219 the server to be in that interface. Such calls should cause a fault. 221 Similarly, in a reply to an ORPC (a DCE RPC "Response PDU"), when 222 viewed from the DCE RPC perspective, an additional first return value 223 is always present that is absent in the corresponding COM interface 224 specification. This argument is of type ORPCTHAT, which is described 225 in Section 3.8. It is placed first in the body of the Response PDU, 226 before the actual return values of the ORPC. 228 An ORPCTHAT may also be present in a "Fault PDU." In the 229 Connectionless (CL) Fault PDU, it is placed four bytes after the 32- 230 bit fault code which normally comprises the entire body of the PDU, 231 thus achieving eight byte alignment for the ORPCTHAT; the intervening 232 padding bytes are presently reserved and must be zero. The PDU body 233 length is of course set to encompass the entire body of the Fault PDU, 234 including the ORPCTHAT. In the Connection- Oriented (CO) Fault PDU, 235 the ORPCTHAT is placed in the standard location allocated for the 236 "stub data." In a Fault PDU of either form that results from an ORPC, 237 if an ORPCTHAT is not present then no other data may be substituted in 238 its here-specified location in the PDU. 240 2.2 OXIDs and Object Exporters 242 Although an IPID from a logical perspective semantically determines 243 the server, object and interface to which a particular call should be 244 directed, it does not by itself indicate the binding information 245 necessary to actually carry out an invocation. 247 The protocol represents this "how-to" communication information in a 248 64-bit value called an object exporter identifier, otherwise known as 249 an OXID. Conceptually, an OXID can be thought of as an implementation 250 scope for an object, which may be a whole machine, a given process, a 251 thread within that process, or other more esoteric implementation 252 scope, but the exact definition of such scopes has no bearing on the 253 protocol itself. Data structures in each Object Exporter keep track of 254 the IPIDs exported and imported by that Object Exporter. 256 A given machine at any moment may support several OXIDs; however there 257 is always a unique OXID Resolver service per machine which 258 coordinates the management of all the OXIDs on the machine. The OXID 259 Resolver typically (but not necessarily) resides at well-known ports 260 (or endpoints, depending on your terminology -- one per protocol, of 261 course) on the machine. It supports a DCE RPC interface known as 262 IOXIDResolver, described in Section 5.2. 264 An OXID is used to determine the RPC string bindings that allow calls 265 to reach their target IPID. Before making a call, the calling process 266 must translate an OXID into a set of bindings that the underlying RPC 267 implementation understands. It accomplishes this by maintaining a 268 cache of these mappings. When the destination application receives an 269 object reference, it checks to see if it recognizes the OXID. If it 270 does not, then it asks the OXID Resolver which scopes the OXID 271 specified in the object reference for the translation, and saves the 272 resulting set of string bindings in a local table that maps OXIDs to 273 string bindings. 275 Associated with each OXID (ie each Object Exporter) is COM object 276 termed an "OXID object." OXID objects implement (at least) the 277 IRemUnknown interface, a COM interface through which remote 278 management of reference counts and requests for interfaces are 279 returned. 281 2.3 Marshaled Interface References 283 The DCOM protocol extends the Network Data Representation (NDR) 284 standard specified in [CAE RPC] by defining what can be thought of as 285 a new primitive data type that can be marshaled: that of an interface 286 reference to an object. This is the only extension to NDR made by the 287 DCOM protocol. 289 A marshaled interface reference is described by a type known as an 290 OBJREF, which is described in detail in Section 3.3. An OBJREF in 291 actuality has several variations: 293 NULL 295 This is a reference to no object. 297 STANDARD 299 A standard remote reference. Known as a STDOBJREF. A STDOBJREF 300 contains: 302 � An IPID, which uniquely specifies the interface and object. 304 � An object ID (OID), which uniquely specifies the identity of the 305 object on which the IPID is found (scoped to the object exporter 306 with which the object is associated). 308 � An OXID, which identifies the scope where the implementation of the 309 object is active, and can be used to reach the interface pointer. 311 � A reference count, indicating the number of references to this IPID 312 that are conveyed by this marshaling. This count, though typically 313 a value of one, may in fact be zero, one, or more (see the next 314 section). 316 � Some flags, explained later. 318 CUSTOM 320 Contains a class ID (CLSID) and class-specific information. 322 The Custom format gives an object control over the representation of 323 references to itself. For example, an immutable object might be passed 324 by value, in which case the class-specific information would contain 325 the object's immutable data. 327 HANDLER 329 A sub-case of the custom reference in which the class- specific 330 information is standardized. 332 For example, an object wishes to be represented in client address 333 spaces by a proxy object that caches state. In this case, the class- 334 specific information is just a standard reference to an interface 335 pointer that the handler (proxy object) will use to communicate with 336 the original object. 338 Interface references are always marshaled in little-endian byte order, 339 irrespective of the byte order prevailing in the remainder of the data 340 being marshaled. 342 2.4 Reference Counting 344 In the DCOM protocol, remote reference counting is conducted per 345 interface (per IPID). 347 The actual increment and decrement calls are carried out using 348 (respectively) the RemAddRef and RemRelease methods in a COM interface 349 known as IRemUnknown found on the OXID object associated with each 350 OXID, the IPID of which is returned from the function 351 IOXIDResolver::ResolveOxid (section 5.2.1). In contrast to their 352 analogues in IUnknown, RemAddRef and RemRelease can in one call 353 increment or decrement the reference count of many different IPIDs by 354 an arbitrary amount; this allows for greater network efficiency. In 355 the interests of performance, client COM implementations typically do 356 not immediately translate each local AddRef and Release into a remote 357 RemAddRef and RemRelease. Rather, the actual remote release of all 358 interfaces on an object is typically deferred until all local 359 references to all interfaces on that object have been released. 360 Further, one actual remote reference count may be used to service many 361 local reference counts; that is, the client infrastructure may 362 multiplex zero or more local references to an interface into zero or 363 one remote references on the actual IPID. 365 To prevent a malicious application from calling RemRelease 366 incorrectly, an application may request secure references. In that 367 case the application must call RemAddRef (and RemRelease later on) 368 securely and must request private references. Private references are 369 stored by client identity so one client cannot release another 370 client�s references. DCOM requires that each client make a call to get 371 his own secure references, rather then receiving a secure reference 372 from someone who already has one. This reduces the efficiency of 373 interface marshalling because the client must make a callback. 375 2.5 Pinging 377 The above reference counting scheme would be entirely adequate on its 378 own if clients never terminated abnormally, but in fact they do, and 379 the system needs to be robust in the face of clients terminating 380 abnormally when they hold remote references. In a DCE RPC, one 381 typically addresses this issue through the use of context handles. 382 Context handles are not used, however, by the DCOM protocol, for 383 reasons of expense. The basic underlying technology used in virtually 384 all protocols for detecting remote abnormal termination is that of 385 periodic pings. Naive use of RPC context handles would result in per 386 object per client process pings being sent to the server. The DCOM 387 protocol includes a pinging infrastructure to significantly reduce 388 network traffic by relying on the client OXID Resolver implementation 389 to do local management of client liveness detection, and having the 390 actual pings be sent only on a machine by machine basis. 392 Pinging is carried out on a per-object (per OID), not a per- interface 393 (per-IPID) basis. Architecturally, at its server machine, each 394 exported object (each exported OID) has associated with it a 395 pingPeriod time value and a numPingsToTimeOut count which together 396 (through their product) determine the overall amount of time known as 397 the "ping period" that must elapse without receiving a ping on that 398 OID before all the remote references to IPIDs associated with that OID 399 can be considered to have expired. Once expiration has occurred, the 400 interfaces behind the IPIDs can, as would be expected, be reclaimed 401 solely on the basis of local knowledge, though the timeliness with 402 which this is carried out, if at all, is implementation specific 403 detail of the server. If the server COM infrastructure defers such 404 garbage collection in this situation (perhaps because it has local 405 references keeping the interface pointer alive) and it later hears a 406 ping , then it knows a network partition healed. It can consider the 407 extant remote references to be reactivated and can continue remote 408 operations. 410 When interface pointers are conveyed from one client to another, such 411 as being passed as either [in] or [out] parameters to a call, the 412 interface pointer is marshaled in one client and unmarshaled in the 413 other. In order to successfully unmarshal the interface, the 414 destination client must obtain at least one reference count on the 415 interface. This is usually accomplished by passing in the marshaled 416 interface STDOBJREF a cPublicRefs of (at least) one; the destination 417 client then takes ownership of that many (more) reference counts to 418 the indicated IPID, and the source client then owns that many fewer 419 reference counts on the IPID. It is legal, however, for zero reference 420 counts to be passed in the STDOBJREF; here, the destination client 421 must (if it does not already have access to that IPID and thus have a 422 non-zero reference count for it) before it successfully unmarshals the 423 interface reference (concretely, e.g., before CoUnmarshalInterface 424 returns) call to the object exporter using IRemUnknown::RemAddRef to 425 obtain a reference count for it. If the destination client is in fact 426 the object's server, then special processing is required by the 427 destination client. The remote reference counts being passed to it 428 should, in effect, be "taken out of circulation," as what where 429 heretofore remote references are being converted into local 430 references. Thus, the reference counts present in the STDOBJREF are in 431 fact decremented from the remote reference count for the IPID in 432 question. 434 Some objects have a usage model such that they do not need to be 435 pinged at all; such objects are indicated by the presence of a flag in 436 a STDOBJREF to an interface on the object. Objects which are not 437 pinged in fact need not be reference counted either, though it is 438 legal (but pointless) for a client to reference count the IPIDs of 439 such objects. 441 For all other objects, assuming a non-zero ping period, it is the 442 responsibility of the holder of an interface reference on some object 443 to ensure that pings reach the server frequently enough to prevent 444 expiration of the object. The frequency used by a client depends on 445 the ping period, the reliability of the channel between the client and 446 the server, and the probability of failure (no pings getting through 447 and possible premature garbage-collection) that the client is willing 448 to tolerate. The ping packet and / or its reply may both request 449 changes to the ping period. Through this mechanism, network traffic 450 may be reduced in the face of slow links to busy servers. 452 2.5.1 Delta Pinging 454 Without any further refinements, ping messages could be quite hefty. 455 If machine A held 1024 remote object references (OIDs) on machine B, 456 then it would send 16K byte ping messages. This would be annoying if 457 the set of remote objects was relatively stable and the ping messages 458 were the same from ping to ping. 460 The delta mechanism reduces the size of ping messages. It uses a ping- 461 set interface that allows the pinging of a single set to replace the 462 pinging of multiple OIDs. 464 Instead of pinging each OID, the client defines a set. Each ping 465 contains only the set id and the list of additions and subtractions to 466 the set. Objects that come and go within one ping period are removed 467 from the set without ever having been added. 469 The pinging protocol is carried out using two methods in the (DCE RPC) 470 interface IOXIDResolver on the OXID Resolver: ComplexPing, and 471 SimplePing. ComplexPing is used by clients to group the set of OIDs 472 that they must ping into sets known to the server. These entire sets 473 of OIDs can then be subsequently pinged with a single, short, call to 474 SimplePing. 476 2.6 QueryInterface 478 The IRemUnknown interface on the OXID object, in addition to servicing 479 reference counting as described above also services QueryInterface 480 calls for remote clients for IPIDs managed by that object exporter. 481 IRemUnknown::RemQueryInterface differs from IUnknown::QueryInterface 482 in much the same way as RemAddRef and RemRelease differ from AddRef 483 and Release, in that it is optimized for network access by being able 484 to retrieve many interfaces at once. 486 2.7 Causality ID 488 Each ORPC carries with it a UUID known as the causality id that 489 connects together the chain of ORPC calls that are causally related. 490 If an outgoing ORPC is made while servicing an incoming ORPC, the 491 outgoing call is to have the same causality id as the incoming call. 492 If an outgoing ORPC is made while not servicing an incoming ORPC, then 493 a new causality id is allocated for it. 495 Causality ids may in theory be reused as soon as it is certain that no 496 transitively outstanding call is still in progress which uses that 497 call. In practice, however, in the face of transitive calls and the 498 possibility of network failures in the middle of such call chains, it 499 is difficult to know for certain when this occurs. Thus, 500 pragmatically, causality ids are not reusable. 502 The causality id can be used by servers to understand when blocking or 503 deferring an incoming call (supported in some COM server programming 504 models) is very highly probable to cause a deadlock, and thus should 505 be avoided. 507 The causality id for maybe, idempotent, and broadcast calls must be 508 set to null (e.g., all zeros). If a server makes a ORPC call while 509 processing such a call, a new causality id must be generated as if it 510 were a top level call. 512 3. Data Types and Structures 514 This following several sections present the technical details of the 515 DCOM protocol. 517 3.1 DCE Packet Headers 519 Object RPC sits entirely on top of DCE RPC. The following list 520 describes the elements of ORPC that are specified above and beyond DCE 521 RPC. 523 � The object id field of the header must contain the IPID. 525 � The interface id of the RPC header must contain the IID, even 526 though it is not needed given the IPID. This allows ORPC to sit on 527 top of DCE RPC. An unmodified DCE RPC implementation will correctly 528 dispatch based on IID and IPID. An optimized RPC need only dispatch 529 based on IPID. 531 � An IPID uniquely identifies a particular interface on a particular 532 object on a machine. The converse is not true; a particular 533 interface on a particular object may be represented by multiple 534 IPIDs. IPIDs are unique on their OXID. IPIDs may be reused, however 535 reuse of IPIDs should be avoided. 537 � Datagram, maybe, and idempotent calls are all allowed in ORPC. 539 � Interface pointers may not be passed on maybe or idempotent calls. 541 � Datagram broadcasts are not allowed in ORPC. 543 � Faults are returned in the stub fault field of the DCE RPC fault 544 packet. Any 32 bit value may be returned. Only 545 RPC_E_VERSION_MISMATCH is pre-specified: 547 � DCE RPC cancel is supported. 549 � All interface version numbers must be 0.0. 551 3.2 ORPC Base Definitions 553 There are several fundamental data types and structures on which the 554 COM network protocol is built. These types are shown here in standard 555 C header format. 557 //////////////////////////////////////////////////////////// 558 // Basic Definitions 559 //////////////////////////////////////////////////////////// 560 typedef unsiged long HRESULT; // 32-bit integer: success/failure 561 typedef t_uuid UUID; // rename DCE-RPC type 562 typedef UUID GUID; // Globally Unique IDentifier 563 typedef unsigned hyper ID; // 64-bit integer 564 typedef ID OXID; // Object Exporter Identifier 565 typedef ID OID; // Object Identifer 566 typedef ID SETID; // Ping Set Identifier 567 typedef GUID IPID; // Interface Pointer Identifier 568 typedef GUID* REFIPID; 569 typedef GUID CID; // Causality Identifier 570 #define CID_NULL uuid_null; // All zeros 572 ////////////////////////////////////////////////////////////////// 573 // ORPC Call Packet Format 574 ////////////////////////////////////////////////////////////////// 575 const unsigned short COM_MAJOR_VERSION = 5; 576 const unsigned short COM_MINOR_VERSION = 1; 578 typedef struct tagCOMVERSION { 579 unsigned short MajorVersion; // Major version number 580 unsigned short MinorVersion; // Minor version number 581 } COMVERSION; 583 const unsigned long ORPCF_NULL = 0; // no additional info 584 // in packet 585 const unsigned long ORPCF_LOCAL = 1; // call is local to this 586 // machine 587 const unsigned long ORPCF_RESERVED1 = 2; // reserved for local use 588 const unsigned long ORPCF_RESERVED2 = 4; // reserved for local use 589 const unsigned long ORPCF_RESERVED3 = 8; // reserved for local use 590 const unsigned long ORPCF_RESERVED4 = 16; // reserved for local use 592 // Extension to implicit parameters. 593 typedef struct tagORPC_EXTENT { 594 GUID id; // Extension identifier 595 unsigned long size; // Extension size 596 byte data[]; // [size_is((size+7)&~7)] 597 } ORPC_EXTENT; 599 // Array of extensions. 600 typedef struct tagORPC_EXTENT_ARRAY { 601 unsigned long size; // Num extents. 602 unsigned long reserved; // Must be zero. 603 ORPC_EXTENT** extent; // [size_is((size+1)&~1), unique] 604 } ORPC_EXTENT_ARRAY; 606 // implicit 'this' pointer which is the first [in] parameter on 607 // every ORPC call. 608 typedef struct tagORPCTHIS { 609 COMVERSION version; // COM version number 610 unsigned long flags; // ORPCF flags for presence of 611 // other data 612 unsigned long reserved1; // set to zero 613 CID cid; // causality id of caller 614 ORPC_EXTENT_ARRAY* extensions; // [unique] extensions 615 } ORPCTHIS; 617 // implicit 'that' pointer which is the first [out] parameter on 618 // every ORPC call. 619 typedef struct tagORPCTHAT { 620 unsigned long flags; // ORPCF flags for presence 621 // of other data 622 ORPC_EXTENT_ARRAY *extensions; // [unique] extensions 623 } ORPCTHAT; 625 ////////////////////////////////////////////////////////////////// 626 // Marshaled COM Interface Wire Format 627 ////////////////////////////////////////////////////////////////// 628 typedef enum tagMSHLFLAGS { 629 MSHLFLAGS_NORMAL = 0, 630 MSHLFLAGS_TABLESTRONG = 1, 631 MSHLFLAGS_TABLEWEAK = 2, 632 } MSHLFLAGS; 634 // Tower IDs for common protocols 635 const unsigned short NCADG_IP_UDP = 0x08; 636 const unsigned short NCACN_IP_TCP = 0x07; 637 const unsigned short NCADG_IPX = 0x0E; 638 const unsigned short NCACN_SPX = 0x0C; 639 const unsigned short NCACN_NB_NB = 0x12; 640 const unsigned short NCACN_NB_IPX = 0x0D; 641 const unsigned short NCACN_DNET_NSP = 0x04; 642 const unsigned short NCALRPC = 0x10; 644 // This is the return type for arrays of string bindings or protseqs 645 // used by many ORPC interfaces. 647 typedef struct tagSTRINGBINDING { 648 unsigned short wTowerId; // Cannot be zero. 649 unsigned short aNetworkAddr; // Zero terminated. 650 } STRINGBINDING; 652 // this value (invalid in DCE RPC) indicates to use default authz 653 const unsigned short COM_C_AUTHZ_NONE = 0xffff; 655 typedef struct tagSECURITYBINDING { 656 unsigned short wAuthnSvc; // Must not be zero 657 unsigned short wAuthzSvc; // Must not be zero 658 unsigned short aPrincName; // NULL terminated 659 } SECURITYBINDING; 661 // DUALSTRINGARRAYS are the return type for arrays of network 662 // addresses, arrays of endpoints and arrays of both used in 663 // many ORPC interfaces 664 typedef struct tagDUALSTRINGARRAY { 665 unsigned short wNumEntries; // # of entries in array 666 unsigned short wSecurityOffset; // Offset of security info 668 // The array contains two parts, a set of STRINGBINDINGs 669 // and a set of SECURITYBINDINGs. Each set is terminated by an 670 // extra zero. The shortest array contains four zeros. 671 unsigned short aStringArray[]; // [size_is(wNumEntries)] 672 } DUALSTRINGARRAY; 674 // arbitrary value to help ensure validity 675 const unsigned long OBJREF_SIGNATURE = 0x574f454d; 677 const unsigned long OBJREF_STANDARD = 0x1; 678 const unsigned long OBJREF_HANDLER = 0x2; 679 const unsigned long OBJREF_CUSTOM = 0x4; 681 // Flag values for a STDOBJREF (standard part of an OBJREF). 682 // SORF_OXRES1 - SORF_OXRES8 are reserved for the object exporters 683 // use only, object importers must ignore them and must not enforce 684 // MBZ. 685 const unsigned long SORF_NULL = 0x0000; // convenient for init 686 const unsigned long SORF_OXRES1 = 0x0001; // reserved by exporter 687 const unsigned long SORF_OXRES2 = 0x0020; // reserved by exporter 688 const unsigned long SORF_OXRES3 = 0x0040; // reserved by exporter 689 const unsigned long SORF_OXRES4 = 0x0080; // reserved by exporter 690 const unsigned long SORF_OXRES5 = 0x0100; // reserved by exporter 691 const unsigned long SORF_OXRES6 = 0x0200; // reserved by exporter 692 const unsigned long SORF_OXRES7 = 0x0400; // reserved by exporter 693 const unsigned long SORF_OXRES8 = 0x0800; // reserved by exporter 694 const unsigned long SORF_NOPING = 0x1000; // Pinging not required 696 typedef struct tagSTDOBJREF { 697 unsigned long flags; // SORF_ flags (see above) 698 unsigned long cPublicRefs; // count of references passed 699 OXID oxid; // oxid of server with this oid 700 OID oid; // oid of object with this ipid 701 IPID ipid; // ipid of Interface 702 } STDOBJREF; 704 // although this structure is conformant, it is always marshaled 705 // in little-endian byte-order. 706 typedef struct tagOBJREF { 707 unsigned long signature; // must be OBJREF_SIGNATURE 708 unsigned long flags; // OBJREF flags (see above) 709 GUID iid; // interface identifier 711 union { // [switch_is(flags), switch_type(unsigned long)] 712 struct { // [case(OBJREF_STANDARD)] 713 STDOBJREF std; // standard objref 714 DUALSTRINGARRAY saResAddr; // resolver address 715 } u_standard; 717 struct { // [case(OBJREF_HANDLER)] 718 STDOBJREF std; // standard objref 719 CLSID clsid; // Clsid of handler code 720 DUALSTRINGARRAY saResAddr; // resolver address 721 } u_handler; 723 struct { // [case(OBJREF_CUSTOM)] 724 CLSID clsid; // Clsid of unmarshaling code 725 unsigned long cbExtension; // size of extension data 726 unsigned long size; // size of data that follows 727 byte *pData; // extension + 728 // class specific data 729 // [size_is(size), ref] 730 } u_custom; 731 } u_objref; 732 } OBJREF; 734 // wire representation of a marshalled interface pointer, 735 // always the little-endian form of an OBJREF 736 typedef struct tagMInterfacePointer { 737 ULONG ulCntData; // size of data 738 byte abData[]; // [size_is(ulCntData)] data 739 } MInterfacePointer, *PMInterfacePointer; 741 // OXID Resolver information associated with each OXID. 742 typedef struct tagOXID_INFO { 743 DWORD dwTid; // thread id of object exporter 744 DWORD dwPid; // process id of obj exporter 745 IPID ipidRemUnknown; // IRemUnknown IPID for object 746 exporter 747 DWORD dwAuthnHint; 748 DUALSTRINGARRAY *psa; // protocol and security info 749 } OXID_INFO; 751 ////////////////////////////////////////////////////////////////// 752 3.3 OBJREF 754 An OBJREF is the data type used to represent an actual marshaled 755 object reference. An OBJREF can either be empty or assume one of three 756 variations, depending on the degree to which the object being 757 marshaled uses the hook architecture (IMarshal, etc.) in the 758 marshaling infrastructure. The OBJREF structure is a union consisting 759 of a switch flag followed by the appropriate data. 761 3.3.1 OBJREF_STANDARD 763 Contains one interface of an object marshaled in standard form. 764 Contains a standard reference, along with a set of protocol sequences 765 and network addresses that can be used to bind to an OXID resolver 766 that is able to resolve the OXID in the STDOBJREF. This is useful when 767 marshaling a proxy to give to another machine (a.k.a. the "middleman" 768 case). The marshaling machine specifies the saResAddr for the OXID 769 Resolver on the server machine, eliminating the need for the 770 unmarshaler to call the marshaler (middleman) back to get this 771 information. Further, the marshaler does not need to keep the OXID in 772 its cache beyond the lifetime of its own references in order to 773 satisfy requests from parties that it just gave the OBJREF to. 775 Member Type Semantic 777 signature unsigned long must be OBJREF_SIGNATURE 779 flags unsigned long OBJREF flags (section 3.5) 781 GUID iid Interface identifier 783 std STDOBJREF A standard object reference used to 784 connect to the source object (Section 785 3.4). 787 SaResAddr STRINGARRAY The resolver address. 789 3.3.2 OBJREF_HANDLER 791 A marshaling of an object that wishes to use handler marshaling. For 792 example, an object wishes to be represented in client address spaces 793 by a proxy object that caches state. In this case, the class- specific 794 information is just a standard reference to an interface pointer that 795 the handler (proxy object) will use to communicate with the original 796 object. See the IStdMarshalInfo interface. 798 Member Type Semantic 800 signature unsigned long must be OBJREF_SIGNATURE 802 flags unsigned long OBJREF flags (section 3.5) 804 GUID iid Interface identifier 806 std STDOBJREF A standard object reference used to 807 connect to the source object (Section 808 3.4). 810 clsid CLSID The CLSID of handler to create in the 811 destination client. 813 SaResAddr STRINGARRAY The resolver address. 815 3.3.3 OBJREF_CUSTOM 817 A marshaling of an object which supports custom marshaling. The Custom 818 format gives an object control over the representation of references 819 to itself. For example, an immutable object might be passed by value, 820 in which case the class-specific information would contain the 821 object's immutable data. See the IMarshal interface. 823 Member Type Semantic 825 signature unsigned long must be OBJREF_SIGNATURE 827 flags unsigned long OBJREF flags (section 3.5) 829 GUID iid Interface identifier 831 clsid CLSID The CLSID of the object to create in the 832 destination client. 834 cbExtension unsigned long The size of the extension data. 836 size unsigned long The size of the marshaled data provided 837 by the source object, plus the size of 838 the extension data, and passed in pData. 840 pData byte* The data bytes that should be passed to 841 IMarshal::UnmarshalInterface on a new 842 instance of class clsid in order to 843 initialize it and complete the unmarshal 844 process (class specific data). 846 The first cbExtension bytes are the 847 reserved for future extensions to the 848 protocol, and should not be passed into 849 the custom unmarshaler. 850 CoUnmarshalInterface should skip the 851 extension data, and the data starting at 852 pData+cbExtension should be given to the 853 custom unmarshaler. 855 3.4 STDOBJREF 857 An instance of a STDOBJREF represents a COM interface pointer that has 858 been marshaled using the standard COM network protocol. 860 The members and semantics of the STDOBJREF structure are as follows: 862 Member Semantic 864 flags Flag values taken from the enumeration SORFFLAGS. These 865 are described in Section 3.5. 867 cPublicRefs The number of reference counts on ipid that are being 868 transferred in this marshaling. 870 oxid The OXID of the server that owns this OID. 872 oid The OID of the object to which ipid corresponds. 874 ipid The IPID of the interface being marshaled. 876 3.5 SORFLAGS 878 The various SORFLAGS values have the following meanings. The 879 SORF_OXRESxxx bit flags are reserved for the object exporter's use 880 only, and must be ignored by object importers. They need not be passed 881 through when marshaling an interface proxy. 883 Flag Value Meaning 885 SORF_NULL 0 Convenient for initialization. 887 SORF_OXRES1 1 Reserved for exporter. 889 SORF_OXRES2 32 Reserved for exporter. 891 SORF_OXRES3 64 Reserved for exporter. 893 SORF_OXRES4 128 Reserved for exporter. 895 SORF_OXRES5 256 Reserved for exporter. 897 SORF_OXRES6 512 Reserved for exporter. 899 SORF_OXRES7 1024 Reserved for exporter. 901 SORF_OXRES8 2048 Reserved for exporter. 903 SORF_NOPING 4096 This OID does not require pinging. Further, all 904 interfaces on this OID, including this IPID, 905 need not be reference counted. Pinging and 906 reference counting on this object and its 907 interfaces are still permitted, however, though 908 such action is pointless. 910 3.6 ORPCINFOFLAGS 912 The various ORPCINFOFLAGS have the following meanings. 914 Flag Meaning 916 ORPCF_NULL (Not a real flag. Merely a defined constant 917 indicating the absence of any flag values.) 919 ORPCF_LOCAL The destination of this call is on the same machine 920 on which it originates. This value is never to be 921 specified in calls which are not in fact local. 923 ORPCF_RESERVED1 If ORPCF_LOCAL is set, then reserved for local use; 924 otherwise, reserved for future use. 926 ORPCF_RESERVED2 If ORPCF_LOCAL is set, then reserved for local use; 927 otherwise, reserved for future use. 929 ORPCF_RESERVED3 If ORPCF_LOCAL is set, then reserved for local use; 930 otherwise, reserved for future use. 932 ORPCF_RESERVED4 If ORPCF_LOCAL is set, then reserved for local use; 933 otherwise, reserved for future use. 935 Implementations may use the local and reserved flags to indicate any 936 extra information needed for local calls. Note that if the ORPCF_LOCAL 937 bit is not set and any of the other bits are set then the receiver 938 should return a fault. 940 3.7 ORPCTHIS 942 In every Request PDU that is an ORPC, the body (CL case) or the stub 943 data (CO case) which normally contains the marshaled arguments in fact 944 begins with an instance of the ORPCTHIS structure. The marshaled 945 arguments of the COM interface invocation follow the ORPCTHIS; thus, 946 viewed at the DCE RPC perspective, the call has an additional first 947 argument. The ORPCTHIS is padded with zero-bytes if necessary to 948 achieve an overall size that is a multiple of eight bytes; thus, the 949 remaining arguments are as a whole eight byte aligned. 951 As in regular calls, the causality id must be propagated. If A calls 952 ComputePi on B, B calls Release on C (which gets converted to 953 RemRelease), and C calls Add on A, A will see the same causality id 954 that it called B with. 956 Member Type Semantic 958 version COMVERSION The version number of the COM 959 protocol used to make this particular 960 ORPC. The initial value will be 5.1. 961 Each packet contains the sender's 962 major and minor ORPC version numbers. 963 The client's and server's major 964 versions must be equal. Backward 965 compatible changes in the protocol 966 are indicated by higher minor version 967 numbers. Therefore, a server's minor 968 version must be greater than or equal 969 to the client's. However, if the 970 server's minor version exceeds the 971 client's minor version, it must 972 return the client's minor version and 973 restrict its use of the protocol to 974 the minor version specified by the 975 client. A protocol version mismatch 976 causes the RPC_E_VERSION_MISMATCH 977 ORPC fault to be returned. 979 flags unsigned long Flag values taken from the 980 enumeration ORPCINFOFLAGS (section 981 3.6). Reserved unsigned long Must be 982 set to zero. 984 reserved1 unsigned long Set to zero. 986 cid CID The causality id of this ORPC. 988 extensions ORPC_EXTENT_ARRAY* The body extensions, if any, passed 989 with this call. Body extensions are 990 GUID-tagged blobs of data which are 991 marshaled as an array of bytes. 992 Extensions are always marshaled with 993 initial eight byte alignment. Body 994 extensions which are presently 995 defined are described in Section 996 3.10. 998 The cid field contains the causality id. Each time a client makes a 999 unique call, a new causality id is generated. If a server makes a call 1000 while processing a request from a client, the new call must have the 1001 same causality id as the call currently being processed. This allows 1002 simple servers to avoid working on more then one thing at a time (for 1003 example A calls B calls A again, meanwhile C tries to call A with a 1004 new causality id). It tells the server that he is being called because 1005 he asked someone to do something for him. There are several 1006 interesting exceptions. 1008 The causality id for maybe and idempotent calls must be set to 1009 CID_NULL. If a server makes a ORPC call while processing such a call, 1010 a new causality id must be generated. 1012 In the face of network failures, the same causality id may end up in 1013 use by two independent processes at the same time. If A calls B calls 1014 C calls D and C fails, both B and D can independently, simultaneously 1015 make calls to E with the same causality id. 1017 The extensions field contains extensions to the channel header, 1018 described in Section 3.10. Note that in order to force the ORPCTHIS 1019 header to be 8 byte aligned an even number of extensions must be 1020 present and the size of the extension data must be a multiple of 8. 1022 3.8 ORPCTHAT 1024 In every Response PDU that is an ORPC, the body (CL case) or the stub 1025 data (CO case) which normally contains the marshaled output parameters 1026 in fact begins with an instance of the ORPCTHAT structure. The 1027 marshaled output parameters of the COM interface invocation follow the 1028 ORPCTHAT; thus, viewed at the DCE RPC perspective, the call has an 1029 additional output parameters. The ORPCTHAT is padded with zero-bytes 1030 if necessary to achieve an overall size that is a multiple of eight 1031 bytes; thus, the remaining output parameters as a whole are eight byte 1032 aligned. 1034 Member Type Semantic 1036 flags unsigned long Flag values taken from the 1037 enumeration ORPCINFOFLAGS (section 1038 3.6). 1040 extensions ORPC_EXTENT_ARRAY* The body extensions, if any, 1041 returned by this call. See Section 1042 3.10 for a general description of 1043 body extensions as well as a 1044 description of existing well-known 1045 extensions. 1047 3.9 HRESULTs 1049 HRESULTs are the 32-bit return value from all ORPC methods. The 1050 following is a partial list of already defined HRESULTs. 1052 S_OK Success. (0x00000000) 1054 E_OUTOFMEMORY Insufficient memory to complete the call. 1055 (0x80000002) 1057 E_INVALIDARG One or more arguments are invalid. 1059 (0x80000003) 1061 E_NOINTERFACE No such interface supported (0x80000004) 1063 E_ACCESSDENIED A secured operation has failed due to 1064 (0x80070005) inadequate security privileges. 1066 E_UNEXPECTED Unknown, but relatively catastrophic 1067 (0x8000FFFF) error. 1069 RPC_E_INVALID_OXID The object exporter was not found. 1070 (0x80070776) 1072 RPC_E_INVALID_OID The object specified was not found or 1073 (0x80070777) recognized. 1075 RPC_E_INVALID_SET The object exporter set specified was 1076 (0x80070778) not found. 1078 RPC_E_INVALID_OBJECT The requested object does not exist 1080 Further details TBS. 1082 3.10 Body Extensions 1084 Body Extensions are UUID-tagged blocks of data which are useful for 1085 conveying additional, typically out-of-band, information on incoming 1086 invocations (within ORPCTHIS, Section 3.7) and in replies (within 1087 ORPCTHAT, Section 3.8). 1089 Any implementations of the DCOM protocol may define its own extensions 1090 with their own UUIDs. Implementations should skip over extensions 1091 which they do not recognize or do not wish to support. 1093 Body Extensions are marshaled as an array of bytes with initial eight 1094 byte alignment. The following sections describe several existing body 1095 extensions. 1097 3.10.1 Debugging Extension 1099 {f1f19680-4d2a-11ce-a66a-0020af6e72f4} 1101 This extension aids in debugging ORPC. In particular it is designed to 1102 allow single stepping over an ORPC call into the server and out of the 1103 server into the client. 1105 Further details TBS. 1107 3.10.2 Extended Error Extension 1109 {f1f19681-4d2a-11ce-a66a-0020af6e72f4} 1111 The extended error information body extension conveys extended error 1112 information concerning the original root cause of a error back to a 1113 caller so that the caller can deal with it. This extension is only 1114 semantically useful in Response and Fault PDUs. 1116 It is intended that this error information is suitable for displaying 1117 information to a human being who is the user; this information is not 1118 intended to be the basis for logic decisions in a piece of client 1119 code, for doing so couples the client code to the implementation of 1120 the server. Rather, client code should act semantically only on the 1121 information returned through the interface that it invokes. 1123 Further details TBS. 1125 4. IRemUnknown interface 1127 The IRemUnknown interface is used by remote clients for manipulating 1128 reference counts on the IPIDs that they hold and for obtaining 1129 additional interfaces on the objects on which those IPIDs are found. 1131 References are kept per interface rather then per object. 1133 This interface is implemented by the COM "OXID object" associated with 1134 each OXID ( ie each Object Exporter). The IPID for the IRemUnknown 1135 interface on this object is returned from IOXIDResolver::ResolveOxid; 1136 see Section 5.2.1. An OXID object need never be pinged; its interfaces 1137 (this IPID included) need never be reference counted. IRemUnknown is 1138 specified as follows: 1140 // The remote version of IUnknown. This interface exists on every 1141 // OXID (whether an OXID represents either a thread or a process is 1142 // implementation specific). It is used by clients to query for new 1143 // interfaces, get additional references (for marshaling), and 1144 release 1145 // outstanding references. 1146 // This interface is passed along during OXID resolution. 1147 // 1148 [ 1149 object, 1150 uuid(00000131-0000-0000-C000-000000000046) 1151 ] 1152 interface IRemUnknown : IUnknown 1153 { 1154 typedef struct tagREMQIRESULT 1155 { 1156 HRESULT hResult; // result of call 1157 STDOBJREF std; // data for returned interface 1158 } REMQIRESULT; 1160 HRESULT RemQueryInterface 1161 ( 1162 [in] REFIPID ripid, // interface to QI on 1163 [in] unsigned long cRefs, // count of AddRefs requested 1164 [in] unsigned short cIids, // count of IIDs that follow 1165 [in, size_is(cIids)] 1166 IID* iids, // IIDs to QI for 1167 [out, size_is(,cIids)] 1168 REMQIRESULT** ppQIResults // results returned 1169 ); 1171 typedef struct tagREMINTERFACEREF 1172 { 1173 IPID ipid; // ipid to AddRef/Release 1174 unsigned long cPublicRefs; 1175 unsigned long cPrivateRefs; 1176 } REMINTERFACEREF; 1178 HRESULT RemAddRef 1179 ( 1181 [in] unsigned short cInterfaceRefs, 1182 [in, size_is(cInterfaceRefs)] 1183 REMINTERFACEREF InterfaceRefs[], 1184 [out, size_is(cInterfaceRefs)] 1185 HRESULT* pResults 1186 ); 1188 HRESULT RemRelease 1189 ( 1190 [in] unsigned short cInterfaceRefs, 1191 [in, size_is(cInterfaceRefs)] 1192 REMINTERFACEREF InterfaceRefs[] 1193 ); 1194 } 1196 4.1 IRemUnknown::RemQueryInterface 1198 QueryInterface for and return the result thereof for zero or more 1199 interfaces from the interface behind the IPID ipid. ipid must 1200 designate an interface derived from IUnknown (recall that all remoted 1201 interfaces must derive from IUnknown). The QueryInterface calls on the 1202 object that are used to service this request are conducted on the 1203 IUnknown interface of the object. 1205 Argument Type Semantic 1207 ripid REFIPID The interface on an object from whom 1208 more interfaces are desired. 1210 CRefs unsigned long The number of references sought on each 1211 of the returned IIDs. 1213 CIids unsigned short The number of interfaces being 1214 requested. 1216 iids IID* The list of IIDs that name the 1217 interfaces sought on this object. 1219 ppQIResults REMQIRESULT** The place at which the array of the 1220 results of the various QueryInterface 1221 calls are returned. 1223 ReturnValue Meaning 1225 S_OK Success. An attempt was made to retrieve each 1226 of the requested interfaces from the indicated 1227 object; that is, QueryInterface was actually 1228 invoked for each IID. QueryInterface returned 1229 S_OK for every IID specified. 1231 S_FALSE Success. An attempt was made to retrieve each 1232 of the requested interfaces from the indicated 1233 object; that is, QueryInterface was actually 1234 invoked for each IID. QueryInterface returned a 1235 failure code for at least one of the IIDs 1236 specified. 1238 E_NOINTERFACE QueryInterface returned a failure code for 1239 every IID specifed. 1241 E_INVALIDARG One or more arguments (likely ipid) were 1242 invalid. No result values are returned. 1244 E_UNEXPECTED An unspecified error occurred. 1246 E_OUTOFMEMORY Insufficient memory to complete the call. 1248 RPC_E_INVALID_OBJECT The requested object does not exist. No result 1249 values are returned. 1251 4.1.1 REMQIRESULT 1253 The REMQIRESULT structure contains the following members: 1255 Member Type Semantic 1257 hResult HRESULT The result code from the QueryInterface call 1258 made for the requested IID. 1260 std STDOBJREF The data for the returned interface. Note 1261 that if hResult indicates failure then the 1262 contents of STDOBJREF are undefined. 1264 4.2 IRemUnknown::RemAddRef 1266 Obtain and grant ownership to the caller of one or more reference 1267 counts on one or more IPIDs managed by the corresponding OXID. 1269 Argument Type Semantic 1271 cInterfaceRefs unsigned short The size of the rgRefs array. 1273 InterfaceRefs REMINTERFACEREF An array of REMINTERFACEREFs, cRefs 1274 [] large. Each IPID indicates an 1275 interface managed by this OXID on 1276 whom more reference counts are 1277 sought. The corresponding reference 1278 count (cInterfaceRefs), which may 1279 not be zero (and thus is one or 1280 more), indicates the number of 1281 reference counts sought on that 1282 IPID. 1284 PResults HRESULT* An array of HRESULTs cInterfaceRefs 1285 large, each containing the result of 1286 attempting an AddRef on the ipid in 1287 the corresponding REMINTERFACREF. 1289 Return Value Meaning 1291 S_OK Success. An attempt was made to retrieve each of the 1292 requested interface references. 1294 E_INVALIDARG One or more of the IPIDs indicated were not in fact 1295 managed by this OXID, or one or more of the requested 1296 reference counts was zero. None of the requested 1297 reference counts have been granted to the caller; the 1298 call is a no-op. 1300 E_UNEXPECTED An unspecified error occurred. It is unknown whether 1301 any or all of the requested reference counts have 1302 been granted. 1304 CO_E_OBJNOTREG Object is not registered. 1306 A useful optimization is for a caller to RemAddRef more than needed. 1308 When a process receives an out marshaled interface, it receives one 1309 reference count. If the process wishes to pass that interface as an 1310 out parameter, it must get another reference to pass along. Instead, 1311 the process (or middleman) should get a large number of references. 1312 Then if the interface is passed out multiple times, no new remote 1313 calls are needed to gain additional references. 1315 A marshaler may optionally specify more than one reference in the 1316 STDOBJREF when marshaling an interface. This allows the middle man 1317 case to pre-fill its cache of references without making an extra 1318 RemAddRef call. The number of references passed is always specified in 1319 the STDOBJREF field. 1321 If cPrivateRefs is not zero for all IPIDs, the call to RemAddRef must 1322 be made securely. DCOM on the server remembers the name of the client 1323 and the authentication and authorization service used to make to 1324 RemAddRef call. 1326 4.2.1 REMINTERFACEREF 1328 Member Type Semantic 1330 IPID ipid ipid to AddRef/Release. 1332 unsigned cPublicRefs Number of public references granted . 1333 long 1335 unsigned cPrivateRefs Number of private references granted. 1336 long Private references belong only to this 1337 client and can not be passed to other 1338 clients when marshaling the proxy. If a 1339 client has only private references and 1340 wishes to pass the proxy to some other 1341 client, it must first obtain some public 1342 references via IRemUnknown::RemAddRef and 1343 then pass one or more of those references 1344 in the STDOBJREF cPublicRefs field of the 1345 marshaled interface. 1347 4.3 IRemUnknown::RemRelease 1349 Release ownership of one or more reference counts on one or more IPIDs 1350 managed by the corresponding OXID. 1352 If cPrivateRefs is not zero for all IPIDs, the call to RemRelease must 1353 be made securely. For each IPID, DCOM maintains a table of reference 1354 counts indexed by the client identity (name, authn svc, authz svc). 1355 All public references are stored in one entry. Any call to RemRelease 1356 can release public references. Private references can only be 1357 released by the client that added them. 1359 Argument Type Semantic 1361 cRefs unsigned short The size of the rgRefs array. 1363 rgRefs REMINTERFACEREF[] An array of REMINTERFACEREFs, cRefs 1364 large. Each IPID indicates an 1365 interface managed by this OXID on whom 1366 more reference counts are being 1367 returned. The corresponding reference 1368 count, which may not be zero (and thus 1369 is one or more), indicates the number 1370 of reference counts returned on that 1371 IPID. 1373 Return Value Meaning 1375 S_OK Success. An attempt was made to release each of the 1376 requested interface references. 1378 E_INVALIDARG One or more of the IPIDs indicated were not in fact 1379 managed by this OXID, or one or more of the requested 1380 reference counts was zero. None of the offered 1381 reference counts have been accepted by the server; the 1382 call is a no-op. 1384 E_UNEXPECTED An unspecified error occurred. It is unknown whether 1385 any or all of the offered reference counts have been 1386 accepted. 1388 5. The OXID Resolver 1390 Each machine that supports the COM network protocol supports a one- 1391 per-machine service known as the machine's `OXID Resolver.' 1392 Communication with an OXID Resolver is via a DCE RPC, not an ORPC. 1394 The OXID Resolver performs several services: 1396 � It caches and returns to clients when asked the string bindings 1397 necessary to connect to OXIDs of exported objects for which this 1398 machine is either itself a client or is the server. Note that it 1399 typically returns only to client processes on the same machine as 1400 itself, the OXIDs for which it is a client. 1402 � It receives pings from remote client machines to keep its own 1403 objects alive. 1405 � May do lazy protocol registration in the servers which it scopes. 1407 These services are carried out through an RPC interface (not a COM 1408 interface) known as IOXIDResolver. An OXID Resolver may be asked for 1409 the information required to connect to one of two different kinds of 1410 OXIDs, either the OXIDs associated with its own objects, or the OXIDs 1411 associated with objects for which it is itself a client The second 1412 case occurs when two or more client processes on the same machine ask 1413 their local OXID Resolver to resolve a given OXID. The client OXID 1414 Resolver in this case can cache the OXID information an return it to 1415 local clients without having to contact the server�s OXID Resolver 1416 again. 1418 5.1 OXID Resolver Ports/Endpoints 1420 The OXID Resolver resides at different endpoints (ports) depending 1421 on the transport being used. The OXID Resolver optimally resides at 1422 the same endpoints as the DCE RPC Endpoint Mapper (EPM). To 1423 accommodate systems where DCOM will coexist with existing DCE RPC 1424 installations (i.e., where an EPM and presumably a complete DCE RPC 1425 runtime already exists), the DCOM implementation on that system will 1426 register its interfaces with the DCE EPM and all DCOM implementations 1427 must be able to fall back if they make DCOM-specific calls on the DCE 1428 EPM endpoint which fail. 1430 Protocol String Description Endpoint 1431 Name(s) 1433 ncadg_ip_udp, ip CL over UDP/IP 135 1435 ncacn_ip_tcp CO over TCP/IP 135 1437 ncadg_ipx CL over IPX TBD 1439 ncacn_spx CO over SPX TBD 1441 ncacn_nb_nb CO over NetBIOS over NetBEUI TBD 1443 ncacn_nb_tcp CO over NetBIOS over TCP/IP 135 1445 ncacn_np CO over Named Pipes TBD 1447 ncacn_dnet_nsp CO over DECNet Network Services 96 1448 Protocol (DECNet Phase IV) 1450 ncacn_osi_dna CO over Open Systems 69 1451 Interconnection (DECNet Phase V) 1453 ncadg_dds, dds CL over Domain Datagram Service 12 1455 ncahttp Hybrid over HTTP (TBS) 80 1457 5.2 The IOXIDResolver Interface 1459 IOXIDResolver (in earlier DCOM documentation this interface was named 1460 IObjectExporter) is defined as follows: 1462 [ 1463 uuid(99fcfec4-5260-101b-bbcb-00aa0021347a), 1464 pointer_default(unique) 1465 ] 1466 interface IOXIDResolver 1467 { 1468 // Method to get the protocol sequences, string bindings 1469 // and machine id for an object server given its OXID. 1470 [idempotent] error_status_t ResolveOxid 1471 ( 1472 [in] handle_t hRpc, 1473 [in] OXID *pOxid, 1474 [in] unsigned short cRequestedProtseqs, 1475 [in, ref, size_is(cRequestedProtseqs)] 1476 unsigned short arRequestedProtseqs[], 1477 [out, ref] DUALSTRINGARRAY **ppdsaOxidBindings, 1478 [out, ref] IPID *pipidRemUnknown, 1479 [out, ref] DWORD *pAuthnHint 1480 ); 1482 // Simple ping is used to ping a Set. Client machines use this 1483 // to inform the object exporter that it is still using the 1484 // members of the set. 1485 // Returns S_TRUE if the SetId is known by the object exporter, 1486 // S_FALSE if not. 1487 [idempotent] error_status_t SimplePing 1488 ( 1489 [in] handle_t hRpc, 1490 [in] SETID *pSetId // Must not be zero 1491 ); 1492 // Complex ping is used to create sets of OIDs to ping. The 1493 // whole set can subsequently be pinged using SimplePing, 1494 // thus reducing network traffic. 1495 [idempotent] error_status_t ComplexPing 1496 ( 1497 [in] handle_t hRpc, 1498 [in, out] SETID *pSetId, // In of 0 on first 1499 // call for new set. 1500 [in] unsigned short SequenceNum, 1501 [in] unsigned short cAddToSet, 1502 [in] unsigned short cDelFromSet, 1503 [in, unique, size_is(cAddToSet)] OID AddToSet[], 1504 // add these OIDs to the set 1505 [in, unique, size_is(cDelFromSet)] OID DelFromSet[], 1506 // remove these OIDs from the set 1507 [out] unsigned short *pPingBackoffFactor 1508 // 2^factor = multipler 1509 ); 1511 // In some cases the client maybe unsure that a particular 1512 // binding will reach the server. (For example, when the oxid 1513 // bindings have more then one TCP/IP binding) This call 1514 // can be used to validate the binding 1515 // from the client. 1516 [idempotent] error_status_t ServerAlive 1517 ( 1518 [in] handle_t hRpc 1519 ); 1520 } 1522 5.2.1 IOXIDResolver::ResolveOxid 1524 Return the string bindings necessary to connect to a given OXID 1525 object. 1527 On entry, arRequestedProtseqs contains the protocol sequences the 1528 client is willing to use to reach the server. These should be in 1529 decreasing order of protocol preference, with no duplicates permitted. 1530 Local protocols (such as "ncalrpc") are not permitted. 1532 On exit, psaOxidBindings contains the string bindings that may be used 1533 to connect to the indicated OXID; if no such protocol bindings exist 1534 which match the requested protocol sequences, NULL may be returned. 1535 The returned string bindings are in decreasing order of preference of 1536 the server, with duplicate string bindings permitted (and not 1537 necessarily of the same preferential priority), though of course 1538 duplicates are of no utility. Local protocol sequences may not be 1539 present; however, protocol sequences that were not in the set of 1540 protocol sequences requested by the client may be. The string bindings 1541 returned need not contain endpoints; the endpoint mapper will be used 1542 as usual to obtain these dynamically. 1544 Argument Type Description 1546 hRpc handle_t An RPC binding handle used to 1547 make the request. 1549 pOxid OXID* The OXID for whom string 1550 bindings are requested. 1552 cRequestedProtseqs unsigned The number of protocol sequences 1553 short requested. 1555 arRequestedProtseqs unsigned arRequestedProtseqs must be 1556 short[] initialized with all the 1557 protocol id's the client is 1558 willing to use to reach the 1559 server. It cannot contain local 1560 protocol sequences. The object 1561 exporter must take care of local 1562 lookups privately. The protocol 1563 sequences are in order of 1564 preference or random order. No 1565 duplicates are allowed. See the 1566 Lazy Protocol Registration 1567 section for more details. 1569 psaOxidBindings STRINGARRAY** The string bindings supported by 1570 this OXID, in preferential 1571 order. Note that these are 1572 Unicode strings. 1574 pipidRemUnknown IPID* The IPID to the IRemUnknown 1575 interface the OXID object for 1576 this OXID. 1578 pdwAuthnHint unsigned A value taken from the 1579 long* RPC_C_AUTHN constants. A hint to 1580 the caller as to the minimum 1581 authentication level which the 1582 server will accept. 1584 Return Value Meaning 1586 S_OK Success. The requested information was 1587 returned. 1589 RPC_E_INVALID_OXID This OXID is unknown to this OXID Resolver, and 1590 thus no information was returned. 1592 E_UNEXPECTED An unspecified error occurred. Some of the 1593 requested information may not be returned. 1595 Object references are transient things. They are not meant to be 1596 stored in files or otherwise kept persistently. 1598 Conversely, since object references are aged, it is the responsibility 1599 of each client to unmarshal them and begin pinging them in a timely 1600 fashion. 1602 The basic use of the ResolveOxid method is to translate an OXID to 1603 string bindings. Put another way, this method translates an opaque 1604 process and machine identifier to the information needed to reach that 1605 machine and process. There are four interesting cases: 1607 1. Looking up an OXID the first time an interface is unmarshaled on a 1608 machine, 1610 2. Looking up an OXID between a pair of machines that already have 1611 connections, 1613 3. Looking up an OXID from a middleman, and 1614 4. Looking up string bindings with unresolved endpoints (lazy use 1615 protseq). 1617 Another interesting topic is garbage collection of stored string 1618 binding vectors. 1620 5.2.1.2 Lookup Between Friends 1622 Consider the case with two machines A and B. Machine A has OXID 1623 Resolver process C and client process D. Machine B has OXID Resolver 1624 process E and server process F. 1626 Server process F, when it starts up, registers it�s RPC string 1627 bindings with it�s local OXID Resolver process E, and creates an 1628 OBJREF to some object inside process F. At some future time client 1629 process D receives that OBJREF (Note: the mechanism used to acquire 1630 this OBJREF is not relevant to this discussion, it may have come 1631 through the object activation protocol (beyond the scope of this 1632 document) or as an [out] interface parameter in some other ORPC call, 1633 or through some other mechanism). The OBJREF contains the OXID for 1634 process F, and the string bindings for the Resolver process E on the 1635 server machine. 1637 Client Process D asks it�s local OXID Resolver to resolve the OXID for 1638 F. It passes it the OXID and the string bindings for OXID Resolver E. 1639 If Resolver D has never seen the OXID before, it calls the OXID 1640 Resolver E to ask it to resolve the OXID. Resolver E looks up the OXID 1641 and returns the string bindings for server process F. Resolver D then 1642 caches this information for future use, and returns the string 1643 bindings to client process C. Client process C then binds to the 1644 string bindings and is now able to make ORPC calls directly to the 1645 server process F. 1647 If other client processes on machine A receive an OBJREF for process 1648 F, the OXID resolve can be handled completely by the Resolver process 1649 D on machine A. There is no need to contact Resolver process E on the 1650 server again. 1652 If machine A gives an OBJREF for F to a client process on another 1653 machine G, then the Resolver process on G will repeat the same steps 1654 as Resolver process D did to resolve the OXID. 1656 +============+============+ +===========+===========+ 1658 | Machine A | | Machine B | 1660 +============+============+ +===========+===========+ 1662 +============+============+ +===========+===========+ 1664 | Process C | Resolver D | | Resolver E| Process F | 1666 +============+============+ +===========+===========+ 1668 | | | | | register | 1670 | | | | | endpoints | 1672 | | | | | with local| 1674 | | | | | Resolver E| 1676 +------------+------------+ +-----------+-----------+ 1678 | | | | cache F | | 1680 | | | | and it�s | | 1682 | | | | endpoints | | 1683 | | | | | | 1685 +------------+------------+ +-----------+-----------+ 1687 | receive | | | | | 1689 | OBJREF | | | | | 1691 | to F | | | | | 1693 | | | | | | 1695 +------------+------------+ +-----------+-----------+ 1697 | ask local | | | | | 1699 | Resolver C | | | | | 1701 | to resolve | | | | | 1703 | F | | | | | 1705 +------------+------------+ +-----------+-----------+ 1707 | | ask remote | | | | 1709 | | Resolver | | | | 1711 | | E to | | | | 1713 | | resolve F | | | | 1715 +------------+------------+ +-----------+-----------+ 1717 | | | | lookup F | | 1719 | | | | and | | 1721 | | | | return | | 1723 | | | | endpoints | | 1725 +------------+------------+ +-----------+-----------+ 1727 | | cache | | | | 1729 | | endpoints | | | | 1731 | | to F and | | | | 1733 | | return to D| | | | 1735 +------------+------------+ +-----------+-----------+ 1737 | bind to | | | | | 1739 | endpoint | | | | | 1741 | for F | | | | | 1743 | | | | | | 1745 +------------+------------+ +-----------+-----------+ 1747 | invoke | | | | | 1749 | method on | | | | | 1751 | F | | | | | 1753 | | | | | | 1755 +------------+------------+ +-----------+-----------+ 1757 5.2.1.4 Lazy Protocol Registration 1759 In a homogeneous network, all machines communicate via the same 1760 protocol sequence. In a heterogeneous network, machines may support 1761 multiple protocol sequences. Since it is often expensive in resources 1762 to allocate endpoints (RpcServerUseProtseq) for all available protocol 1763 sequences, ORPC provides a mechanism where they may be allocated on 1764 demand. To implement this extension fully, there are some changes in 1765 the server. However, changes are optional. If not implemented, ORPC 1766 will still work correctly if less optimally in heterogeneous networks. 1768 There are two cases: the server implements lazy protocol registration 1769 or it does not. 1771 If the server is using lazy protocol registration, the 1772 implementation of ResolveOxid is modified slightly. When the client 1773 OXID Resolver calls the server OXID Resolver, it passes the requested 1774 protocol sequence vector. If none of the requested protocol sequences 1775 have endpoints allocated in the server, the server OXID Resolver 1776 allocates them according to its own endpoint allocation mechanisms. 1778 If the server does not implement the lazy protocol registration, then 1779 all protocol sequences are registered by the server at server 1780 initialization time. 1782 When registering protocol sequences, the server may register endpoints 1783 and the server�s string bindings will contain the complete endpoints. 1784 However, if the server chooses not register endpoints when it 1785 registers protocol sequences the endpoint mapper process can be used 1786 to forward calls to the server. Using the endpoint mapper requires 1787 that all server IIDs be registered in the endpoint mapper. It also 1788 allows a different lazy protocol registration mechanism. The endpoint 1789 mapper can perform some local magic to force the server to register 1790 the protocol sequences. . 1792 The client will always pass in a vector of requested protocol 1793 sequences which the server can ignore if it does not implement lazy 1794 protocol registration. 1796 5.2.2 IOXIDResolver::SimplePing 1798 Pings provide a mechanism to garbage collect interfaces. If an 1799 interface has references but is not being pinged, it may be released. 1800 Conversely, if an interface has no references, it may be released even 1801 though it has recently been pinged. SimplePing just pings the contents 1802 of a set. The set must be created with ComplexPing (section 5.2.3). 1804 Ping a set, previously created with IOXIDResolver::ComplexPing, of 1805 OIDs owned by this OXID Resolver. Note that neither IPIDs nor OIDs may 1806 be pinged, only explicitly created SETIDs. 1808 Argument Type Description 1810 hRpc handle_t An RPC binding handle used to make the request. 1812 PSetId SETID* A SETID previously created with 1813 IOXIDResolver::ComplexPing on this same OXID 1814 Resolver. 1816 Return Value Meaning 1818 S_OK Success. The set was pinged. 1820 RPC_E_INVALID_SET This SETID is unknown to this OXID Resolver, and 1821 thus the ping did not occur. 1823 E_UNEXPECTED An unspecified error occurred. It is not known 1824 whether the ping was done or not. 1826 5.2.3 IOXIDResolver::ComplexPing 1828 Ping a ping set. Optionally, add and/or remove some OIDs from the set. 1829 Optionally, adjust some ping timing parameters associated with the 1830 set. After a set is defined, a SimplePing will mark the entire 1831 contents of the set as active. After a set is defined, SimplePing 1832 should be used to ping the set. ComplexPing need only be used to 1833 adjust the contents of the set (or to adjust the time-out). 1835 Ping set ids (SETIDs) are allocated unilaterally by the server OXID 1836 Resolver. The client OXID Resolver then communicates with the server 1837 OXID Resolver to add (and later remove) OIDs from the ping set.. 1839 Each OID owned by a server OXID Resolver may be placed in zero or more 1840 ping sets by the various clients of the OID. The client owner of each 1841 such set will set a ping period and a ping time-out count for the set, 1842 thus determining an overall time-out period for the set as the product 1843 of these two values. The time-out period is implicitly applied to each 1844 OID contained in the set and to future OIDs that might add be added to 1845 it. The server OXID Resolver is responsible for ensuring that an OID 1846 that it owns does not expire until at least a period of time t has 1847 elapsed without that OID being pinged, where t is the maximum time-out 1848 period over all the sets which presently contain the given OID, or, if 1849 OID is not presently in any such sets but was previously, t is the 1850 time-out period for the last set from which OID was removed at the 1851 instant that that removal was done; otherwise, OID has never been in a 1852 set, and t is a default value (ping period equals 120 seconds, ping 1853 time-out count equals three (3), t equals 360 seconds, or six (6) 1854 minutes). 1856 Clients are responsible for pinging servers often enough to ensure 1857 that they do not expire given the possibility of network delays, lost 1858 packets, and so on. If a client only requires access to a given object 1859 for what it would consider less than a time-out period for the object 1860 (that is, it receives and release the object in that period of time), 1861 then unless it is certain it has not itself passed the object to 1862 another client, it must be sure to nevertheless ping the object (a 1863 ComplexPing that both adds and removes the OID will suffice). This 1864 ensures that an object will not expire as it is passed through a chain 1865 of calls from one client to another. 1867 An OID is said to be pinged when a set into which it was previously 1868 added and presently still resides is pinged with either a SimplePing 1869 or a ComplexPing, or when it is newly added to a set with ComplexPing. 1870 Note that these rules imply that a ComplexPing that removes an OID 1871 from a set still counts as a ping on that OID. In addition to pinging 1872 the set SETID, this call sets the time-out period of the set as the 1873 product of a newly-specified ping period and a newly-specified "ping 1874 count to expiration;" these values take effect immediately. Ping 1875 periods are specified in tenths of a second, yielding a maximum 1876 allowable ping period of about 1 hr 50 min. 1878 Adjustment of the time-out period of the set is considered to happen 1879 before the addition of any new OIDs to the set, which is in turn 1880 considered to happen before the removal of any OIDs from the set. 1881 Thus, an OID that is added and removed in a single call no longer 1882 resides in the set, but is considered to have been pinged, and will 1883 have as its time-out at least the time-out period specified in that 1884 ComplexPing call. 1886 On exit, the server may request that the client adjust the time-out 1887 period; that is, ask it to specify a different time-out period in 1888 subsequent calls to ComplexPing. This capability can be used to reduce 1889 traffic in busy servers or over slow links. The server indicates its 1890 desire through the values it returns through the variables 1891 pReqSetPingPeriod and pReqSetNumPingsToTimeOut. If the server seeks no 1892 change, it simply returns the corresponding values passed by the 1893 client; if it wishes a longer time-out period, it indicates larger 1894 values for one or both of these variables; if it wishes a smaller 1895 period, it indicates smaller values. When indicating a larger value, 1896 the server must start immediately acting on that larger value by 1897 adjusting the time-out period of the set. However, when indicating a 1898 smaller value, it must consider its request as purely advice to the 1899 client, and not take any action: if the client wishes to oblige, it 1900 will do so in a subsequent call to ComplexPing by specifying an 1901 appropriate time-out period. 1903 Argument Type Description 1905 hRpc handle_t An RPC binding handle used to make 1906 the request. 1908 pSetId SETID The SETID being manipulated. 1909 SequenceNum unsigned short The 1910 sequence number allows the object 1911 exporter to detect duplicate packets. 1912 Since the call is idempotent, it is 1913 possible for duplicates to get 1914 executed and for calls to arrive out 1915 of order when one ping is delayed. 1917 cAddToSet unsigned The size of the array AddToSet. 1918 short 1920 cDelFromSet unsigned The size of the array DelFromSet. 1921 short 1923 AddToSet OID[] The list of OIDs which are to be 1924 added to this set. Adding an OID to a 1925 set in which it already exists is 1926 permitted; such an action, as would 1927 be expected, is considered to ping 1928 the OID. 1930 DelFromSet OID[] The list of OIDs which are to be 1931 removed from this set. Removal counts 1932 as a ping. An OID removed from a set 1933 will expire after the number of ping 1934 periods has expired without any pings 1935 (not the number of ping periods - 1). 1936 If an id is added and removed from a 1937 set in the same ComplexPing, the id 1938 is considered to have been deleted. 1940 pPingBackoffFactor unsigned Acts as a hint (only) from the server 1941 short* to the client in order to reduce ping 1942 traffic. Clients are requested to not 1943 ping more often than 1944 (1<<*pPingBackoffFactor)* 1945 (BasePingInterval=120) seconds, and 1946 the number of pings until timeout 1947 remains unchanged at the default of 1948 3. Clients may choose to assume that 1949 this parameter is always zero. 1951 Return Value Meaning 1953 S_OK Success. The set was pinged, etc. 1955 RPC_E_INVALID_OID Indicates that some OID was not recognized. There 1956 is no recovery action for this error, it is 1957 informational only. 1959 E_ACCESSDENIED Access is denied. 1961 E_OUTOFMEMORY There was not enough memory to service the call. 1962 The caller may retry adding OIDs to the set on 1963 the next ping. 1965 E_UNEXPECTED An unspecified error occurred. It is not known 1966 whether the ping or any of the other actions were 1967 done or not. 1969 6. Security Considerations 1971 In general, like any generic data transfer protocol, DCOM cannot 1972 regulate the content of the data that is transferred, nor is there any 1973 a priori method of determining the sensitivity of any particular piece 1974 of information within the context of any given ORPC. 1976 Specifically, however, DCOM entirely leverages the security 1977 infrastructure defined by DCE RPC, which allows for various forms of 1978 authentication, authorization, and message integrity. 1980 Further details TBS. 1982 7. Acknowledgements 1984 As previously noted, the DCOM protocol highly leverages the DCE RPC 1985 Specification [CAE RPC], and we again acknowledge its usefulness to 1986 this specification. 1988 The DCOM protocol itself is the combined effort of a large number of 1989 people. The following individuals in particular were critical to the 1990 definitions which appear in this specification. 1992 Bob Atkinson Deborah Black 1994 Vibhas Chandorkar Richard Draves 1996 Mario Goertzel Rick Hill 1998 Gregory Jensenworth David Kays 2000 Paul Leach Alex Mitchell 2002 Kevin Ross Mark Ryland 2004 Bharat Shah Tony Williams 2006 8. References 2008 [CAE RPC] CAE Specification, X/Open DCE: Remote Procedure Call, X/Open 2009 Company Limited, Reading, Berkshire, UK (xopen.co.uk), 1994. 2010 X/Open Document Number C309. ISBN 1-85912-041-5. (also available 2011 online through from the OSF at 2012 after registration) 2014 [COM] The Component Object Model Specification, Version 0.99, 2015 November, 1996, Microsoft Corporation. (also available online 2016 from Microsoft at 2017 . Note that 2018 this reference is circular because this document (the DCOM wire 2019 protocol specification) is the same chapter 15 of the COM 2020 Specification. 2022 9. Author's Addresses 2024 Nat Brown One Microsoft Way Redmond, WA 98052-6399, U.S.A. Fax: +1 2025 (206) 936 7329 Email: 2027 Charlie Kindel One Microsoft Way Redmond, WA 98052-6399, U.S.A. Fax: 2028 +1 (206) 936 7329 Email: