It is a common practice when adding new features and capabilities to a terminal services (“TS”) client and terminal server to write software components that are installed on both the terminal server and client sides to enable communication between the client and server by exchanging packets or messages with specific content. Typically, the TS protocol which describes the format and content of these packages is privately established by the components during the design phase of their development and typically have the following specifications: versioning, custom marshalling, security checks, request-reply identification, client/server reversibility, reusability and documentation. Because all the effort for creating new TS protocols is normally manual, significant resources must be expended to handle all the aspects listed above. This situation often results in the generation of complicated, one-time use, error-prone code. Moreover, the addition of new features and capabilities often does not scale well as the feature complexity increases.
This Background is provided to introduce a brief context for the Summary and Detailed Description that follows. This Background is not intended to be an aid in determining the scope of the claimed subject matter nor be viewed as limiting the claimed subject matter to implementations that solve any or all of the disadvantages or problems presented above.
A remote interface marshalling (“RIM”) platform is provided in which a protocol interface described using an interface definition language (“IDL”) is parsed to automatically generate the appropriate communication packets and a protocol layer to enable communication between terminal server components. Use of the RIM platform advantageously enables a developer to create a new TS protocol simply by writing the interface definition (i.e., describe the input/output or “I/O”) using the well-known IDL language which is well supported on virtually all computing platforms. The RIM platform further provides for robust versioning support by providing the developer with an ability to create a new interface that is derived from an existing interface.
In an illustrative example, the RIM platform involves two parts: 1) a RIM compiler which generates RIM code from an input TLB (type library) file to serialize all interface methods in a series of calls to a RIM protocol layer, and 2) the RIM protocol layer which maintains unique IDs for all objects and requests on both the terminal server and client sides. The RIM protocol layer also implements simple primitives for communicating basic scalar data types.
The present RIM platform advantageously streamlines the development of new TS protocols. By automatically generating the TS protocol, much of the manual labor associated with the development is eliminated, leaving the developer to focus on solving problems instead of developing protocol infrastructure. As a result, the development is faster and the resulting code is more robust.
This Summary is provided to introduce a selection of concepts in a simplified form that are further described below in the Detailed Description. This Summary is not intended to identify key features or essential features of the claimed subject matter, nor is it intended to be used as an aid in determining the scope of the claimed subject matter.
Like reference numerals indicate like elements in the figures.
Terminal services provide functionality similar to a terminal-based, centralized host, or mainframe environment in which multiple terminals connect to a host computer. Each terminal provides a conduit for input and output between a user and the host computer. A user can log on at a terminal, and then run applications on the host computer, accessing files, databases, network resources, and so on. Each terminal session is independent, with the host operating system managing multiple users contending for shared resources.
The primary difference between terminal services and the traditional mainframe environment is that the terminals in a mainframe environment only provide character-based input and output. A remote desktop client or emulator provides a complete graphical user interface, including a Microsoft Windows® operating system desktop and support for a variety of input devices, such as a keyboard and mouse, collectively identified by reference numeral 126 in
In the terminal services environment, an application runs entirely on the terminal server. The remote desktop client performs no local execution of application software. The server transmits the graphical user interface to the client. The client transmits the user's input back to the server.
Components respectively installed in the terminal server 105 and client 108 in environment 100 exchange communication packets in support of the TS session. As noted above the format and content of these packets is typically privately established by the components during the design phase of their development and have the following specifications:
Versioning. To be able to improve the TS protocol, typically a versioning or capabilities packet is introduced by the component to resolve backwards and forward compatibility.
Marshalling. Any data of variable length has historically required manual coding on both the client side 112 and server side 115 by a developer who is implementing the component.
Security Checks. Special checks for invalid data must be performed by the packet parser in order to avoid attacks from malicious users. Although these checks are typically trivial, because of the historic need to manually develop the code it can be prone to errors, where the level of errors typically depended on the developer's experience. A common technique to mitigate this problem has been to run code analysis tools, which has typically resulted in fixing bugs late in the shipping cycle which can delay product releases and add costs.
Request-Reply Identification. Historically, the TS protocol consists of a request-reply packet pair, for example one side sends a “request” packet for executing the operation on the other side, and any output data from the operation is sent from the remote side as a “reply” packet. If the “request-reply” is executed asynchronously, an identification for the request must be added to the protocol, which increases the protocol complexity, which may result in more bugs.
Reversibility. Since TS protocols have historically been implemented by hand, it certainly has asymmetric nature from the start. Although rare, in some instances the TS protocol has to work backwards, for example, when the TS protocol implements file redirection from a client to a server. If a developer wants to add a server to the client file redirector, the developer must implement substantially from scratch all packets going the other way. If a “request” packet was being sent by the server and client replies with a “reply” packet, both sides have to add code to handle these packets in reverse manner.
Reusability. As a result of the manual nature of the protocol, parts of it are generally difficult to reuse. For example, a subset of the protocol for audio playback may be desired to be reused by multimedia playback. This generally results in a doubling of the effort for adding new features and losing the opportunity to specialize protocol fragments.
Documentation. Developers are often forced to create documentation for their protocols which adds extra labor into the development. Frustration and mistakes in the documentation are possible outcomes.
A specific example is now provided to highlight several of the design issues noted above. An existing feature provided by the Microsoft Windows® operating system is PnP (Plug and Play) redirection where calls from an application on the terminal server 105 are redirected to a local device coupled to the client 108. One of the PnP direction calls is DeviceIOcontrol which has three input parameters: a file handle, and input buffer, and an input buffer size. The call also has three output parameters: an output buffer, the output buffer size, and the result code. The call must be executed asynchronously with possible cancellation. If the call were to be coded manually, a developer would need to describe four different protocol packets:
1) A request packet that must contain the following fields: a unique file ID, unique request ID, variable length input parameter blob, and a maximum size of output parameter;
2) An I/O control result packet for starting the communication I/O: a request ID (from 1 above), cancellation ID and status error code;
3) A cancellation packet (this packet is sent in order to cancel the request (from 1)): a request ID (from 1) and cancellation ID (from 2); and
4) A completion packet: this packet is sent when the I/O completes (or has been cancelled): request ID, status error code, and variable length output parameter.
Designing these four packets is not a trivial problem. And while experienced developers may be able to come up with a design fairly quickly, they may also miss some aspects. For example, keeping all of the IDs noted above unique is a nontrivial problem and may often lead to some serious synchronization bugs, like canceling a request that is different from the one intended.
The present RIM platform is arranged to automate major portions of the development of interface marshalling between the terminal server 105 and the client computer 108 while addressing the design issues noted in the specifications above. Rather than having to design the communication packets to create the TS protocol, the developer only has to describe the I/O using the IDL language. IDL works by requiring that a program's interfaces be described in a stub that is compiled into it. The stubs in each program are used by a broker program to allow them to communicate. The IDL file used in this example is shown below:
From the interfaces defined in the IDL file, the RIM platform will automatically generate the appropriate packets and protocol layer. The above example also highlights the versioning capability noted above. If a developer wishes to add a second variable length input parameter to the device I/O control call, the developer normally must have included a versioning packet in the first implementation in order to do some special handling based on the remote version. In the present arrangement, the developer only needs to create a new interface that is derived from the old one by adding a “QueryInterface” call for the new version.
As shown in
The IDL file 211 describes all data types, and interfaces with their associated methods. A variety of different data types are typically utilized as shown below:
Scalar type. This is any predefined fixed size language data type, specifically—char, short, int, long or an array of any of these.
scalar=char|short|int|long|guid|scalar[ ]
User defined type. This is a compound type that contains any number of scalar types or any other user type. A typical example of that is structures in C/C++ language.
usertype={scalar|usertype}
Strings. These are single or double char null terminated arrays.
string=char*|wchar*
Unknown. This describes a base interface that only has reference counting and QueryInterface methods. Interfaces that inherit from Unknown are also of this data type. All interfaces that can be remoted by the RIM platform should normally implement from this interface.
unknown=IUnknown|object:IUnknown
Reference type. This could be any a reference to any other type including a recursive reference.
ref=*<type>
Direction. A parameter can be either input or output, this has special relation with the reference type. For example, output parameters should have at least a single level of reference.
Parameters can also have a relation between each other. For example, one parameter can specify the length of an array parameter in a single call. These are marked with a “size_is” attribute, where the parameter inside the “size_is” attribute specifies the number of items in the array. Table 1 lists an illustrative full set of parameters that may be used by the present RIM platform. Table 2 lists a set of illustrative examples of parameter variation.
Each method in the IDL file 211 (
The RIM stub is implemented on the remote side. It is noted that it does not matter whether the implementation is performed on the client 108 (
For example, given the following method:
the RIM proxy will generate a packet that contains the value of “UsDollars” and “ExchangeRate”. The RIM stub will receive that packet and invoke the implementation of MoneyExchange. The output of that call will be “Euro” and HRESULT is returned. The RIM stub will send back a reply with these two values. The RIM proxy will pick up the “Euro” and set the output parameter with that value. The RIM proxy will then exit with the return code from the packet.
The RIM protocol layer 302 includes functionality to support a series of methods for sending different scalar data types, strings, and interfaces, each of which has a very specific wire format, to thereby eliminate confusion, for example, as to how many bits a particular integer utilizes. The RIM protocol layer 302 exposes the functionality to the RIM-generated code through an interface named “RIM message,” as indicated by reference numeral 323 in
For sending/receiving interfaces, the following methods are used:
This method serializes “n” number of interfaces that have interface ID “riid”. The protocol layer generates a unique ID for this interface and stores the IUnknown pointer “p” associated with that ID. It also generates a RIM stub and associates it with the interface ID and the actual pointer “p.”
When remote side receives this ID by calling
it picks up the interface ID from the wire and looks for any pre-existing interface associated with that ID. If the interface ID has just been created, the remote side will not find it and it will be forced to create a proxy, based on the value of “riid”. This means that the code for creating proxies must be available for all interfaces that are being passed.
At the remote side, as shown in
Although the subject matter has been described in language specific to structural features and/or methodological acts, it is to be understood that the subject matter defined in the appended claims is not necessarily limited to the specific features or acts described above. Rather, the specific features and acts described above are disclosed as example forms of implementing the claims.