Footnotes
1. In fact, there exist several standard sets of rules, each promoted by a different organization. Two common such sets of rules are known as "Network Data Representation" (NDR) and "External Data Representation" (XDR) chiefly promoted respectively by the Open Software Foundation and Sun Microsystems. ASN.1 is another standard for the same sort of technology. [Back]
2. Notice here that we're only discussing the marshaling of pointers to interfaces, and that the term "custom object marshaling" applies only to the marshaling of this data type. In general in a given remote procedure call the many other kinds of data which appear as function parameters also needs to be marshaled: strings, integers, structures, and so forth. We will not concern ourselves here with such other data types, but instead concentrate our discussion on marshaling interface pointers. [Back]
3. For example, at compile time of the original marshaling stub. [Back]
4. That is, it is explicitly legal for the caller of GetMarshalSizeMax() to allocate a fixed size marshaling buffer containing no more than the indicated upper bound number of bytes. [Back]
5. Some readers may notice an abuse of terminology here: what is really being marshaled in hand is one particular interface on the object, not the whole object, though in fact in the remote process access to the whole process is indeed obtained: new interfaces on the object will be marshaled later as needed. We trust that this will not lead to too much confusion. [Back]
6. Other RPC systems sometimes instead call these client-side stubs and server-side stubs. Sometimes we mix things up a bit and refer to proxy interfaces and stub interfaces instead of interface proxies and interface stubs. [Back]
7. There are, however, implied requirements for the existence of some piece of code / state that manages the entire set of external remoting connections for a given object. See CoLockObjectExternal(), for example. [Back]
8. The layout of this structure is as odd as it is for historical reasons. Apologies are extended to those whose design aesthetics are offended. [Back]
9. This permits the channel to behind-the-scenes add additional space into the buffer. Such a capability is needed, for example, in order to support remote debugging. [Back]
10. The fact that cbBuffer is unchanged can be of particular use to interface stubs. See IRpcStubBuffer::Invoke(). [Back]
11. That is, if SendReceive() returns an error. Note that this does NOT indicate an error returned from the function invocation on the server object, for in that case SendReceive() returns success; rather, it indicates an error that occurred somewhere in the RPC transmission. [Back]
12. It is possible that in the future a less restrictive rule as to the duration in which the interface proxy may hold on to ppvDestCtxt may be established, such as (perhaps) guaranteeing that the pointer is valid for the lifetime of the interface proxy itself. However, as it stands today, the rule, as stated here, is in fact the law. [Back]
13. Be careful with the terminology here: we are not talking at all about what values are returned from the invocation of the server object, but rather only about errors that occur in the unmarshaling and marshaling process itself. [Back]
14. However, debugging versions of the stub may, if they wish to at this time, check that certain details of the contract of the interface have been upheld. A common example of this is checking that on error return from the server allocated out-values are explicitly NULLed, a policy which is common to many interfaces. This is simply in the interest of improving the debug capabilities. It is illegal, however, to do such things in non-debug versions of stubs; they must always simply marshal back whatever the server returned. [Back]
15. This policy exists in order to enable behind-the-scenes things such as debugging support to function in all cases. [Back]
16. Presently, this is only significant if NDR transfer syntax is in use. In NDR, it is explicitly the case that the return values may be marshaled using a different data representation than was used for the incoming arguments. [Back]
17. That is, the mechanism for unmarshaling a marshaled interface pointer is the same irrespective of whether the marshaling was done using custom or standard marshaling. [Back]
18. Using a higher-level notification scheme appropriate for the semantics of the particular connection. An example of this is OLE 2.0 is broadcasting IAdviseSink::OnClose() to connected links. [Back]
19. More precisely, it may not have a debugger attached to it: depending on the debugger's implementation and the relative location of the two processes with respect to computer boundaries, a new debugger instance may or may not need to be created. The main point is that the process wasn't being debugged. [Back]
20. That is, in the channel implementation approach described here, which uses only one memory buffer. Another channel implementation approach would use two separate buffers, one to give back to the interface proxy, and another independent one for the debug information. Such an implementation would only need to call DebugORPCClientGetBufferSize() in its IRpcChannellBuffer::SendReceive() implementation immediately before calling DebugORPCClientFillBuffer(). While perfectly legal, this will not be elaborated further here, though in fact this is the implementation likely to be used in practice, given how the debug data is to be transmitted in the COM Network Protocol. We trust that readers can accommodate our pedagogical style; apologies to those who cannot. [Back]
21. Some control as to whether this is to be actually carried out is provided by the first four bytes of the incoming debug data; see later in this specification. [Back]
22. This is important in error handling cases to allow us to ensure that breakpoints are always cleared correctly. [Back]
23. "MARB" is "Mike Alex Rico Bob," arranged in an order such that it makes a goofy-sounding syllable. Call us whimsical. [Back]
24. This is so segment names such as .orpc1, .orpc2... can be used if the remoting code needs to be split up into different segments for swap tuning, and so forth. [Back]
25. It is not guaranteed that an RPC call will happen for every such transition. The debugger should deal with the case where it receives no notification about an RPC call. [Back]
26. In Windows NT, the registry is securable. [Back]
27. One can think of this as IDL with (i) default packing override, and (ii) the ability to have a union keyed by a GUID. This will be made more precise in future drafts of this specification. [Back]
28. This is presently Microsoft Corporation. [Back]