Some features in Citrix Presentation Server are mostly unknown to large groups of people. COM Port Mapping is perhaps more the back water of the more traditional features. The concept is that it is possible to use COM ports on the client from server applications. This, in concept, is fairly easy. Unfortunately things are never as easy as they sound.
There are two kinds of COM port mapping support in Citrix. Why two? Well, one is the old way of doing things and the other the newer. Don’t ask me why the two ways weren’t combined. I’m not sure about that. It is similar to how there are multiple layers of supporting things related to printing. The old way is very basic and is focused primarily as treating the COM port like a file destination for the sake of printing. This was initially enabled to allow printing to simple printers on COM1 and COM2. In the early days it was common to have these ports defined for Point of Sale (POS) to control a cash register drawer or print receipts. Believe it or not, customers out there are still using it this way. Perhaps Citrix was worried that merging the old and new way would potentially break the customers depending on the old way. That’s my best guess.
The new way does much more work to make the COM port remote. It supports (hypothetically) all the client COM ports and does so in a much more native fashion. Instead of just acting like a basic DOS device, it actually supports all the IOCTLs like a normal serial driver. This means that it covers a much broader range of applications. The applications will think they are dealing with a normal local serial port when really it is doing work with the client’s serial port (note I’m going to use COM and serial port interchangeably even though Microsoft defines them differently). With this level of support, things like HyperTerminal work with remote COM ports.
One of the key steps to getting this working is to enable COM port mapping in the policies and to map the COM ports in the logon script. I recently noticed that CPS has a policy to automatically map the COM ports but this is a very recent development (as far as I know it is new to 4.5). This is the whole reason I decided to write this post. The mapping is where you decide what kind of COM port mapping code you are going to use.
If you do the most natural thing, you are going to end up mapping devices using the OLD way of doing COM ports.
NET USE COM1: \\CLIENT\COM1:
This invokes code in our CDM provider that parses the path and realizes that we are dealing with the old way. It, in turn, asks for access to the device from CDM.SYS which also concludes that we are dealing with the old way. The protocol for the old COM port code is fairly basic and is very similar to the old LPT port mapping code (which is limited to LPT1 and LPT2).
Where’s the the basic assumption goes wrong. If you map to your COM port this way, you will not be able to take advantage of the applications that can access the more recent COM Port API (which translates to the COM Port API that were first included in Windows 95). Things like HyperTerminal simply will not work.
So, this mapping is good for basic printing but not good for something that is more aware. What is the alternative?
NET USE COM1: \\CLIENT\CLIENTPORT:COM1:
CLIENTPORT makes all the difference. It is really just a tag to tell the provider and driver that it needs to treat the COM port as being more advanced. I have often mentioned this during PortICA to the test people and others and it is very relevant to understanding how to select the right technique.
I’ll give you some some technical detail of how things are going to work in PortICA.
Instead of just having one monolithic driver for CDM (Client Device Mapping), PortICA will have four drivers. This is for a couple of reasons. First, splitting it up hopefully will make it easier to support when one device has trouble. Secondly, the Client Drive Mapping has been completely redone for PortICA using the OSR FSDK toolkit. The initial CDM driver was based on the NT file redirector and it was time to move the technology forward. There has been good outcomes already from breaking from the old model already and it hopefully will make it easier to work with in the future. The existing code will be used for COM and LPT ports as well as the Audio kernel support. These last three drivers (known as PICACAM, PICASER, and PICAPAR) will share common code but will have specific code to support there devices. It is much better this way. Obviously there is still more that can be done.
The PortICA provider is new and now smart about splitting up the requests between the different drivers. PICASHELL (derived from WFSHELL) is now driving how the resources get mapped and unmapped within the session. The requests come from PICASHELL to the MPR to the PortICA provider who forwards it ultimately to the relevant drivers using the object manager to create symbolic links.
I know this is a bit technical but I thought someone out there would enjoy it.
As a side note, the PICA prefix is prevalent throughout the PortICA modules and obviously a shortened version of PortICA (the PortICA prefix was just too long). Also obvious is that PICA really stands for Portable ICA but more recently we have concluded that perhaps Personal ICA is a better description of what this project is really about. We’ll let someone outside of Engineering worry about the messages. 🙂