UnicornDVC is software providing an API that allows you to create communication channels in remote desktop connections. The software package consists of several parts:
- UnicornDVC Application library: communication library for applications
- UnicornDVC Plugin library: communication library for client software
UnicornDVC Application library
The UnicornDVC Application library is the library used by an application to communicate to the dynamic virtual channel. This so called app lib can be used both for server and client side communications. An instance of the library supports both one server and one client connection at a time. The export symbols of the app lib consist of eight functions which are used for communication from application to DVC, which are exported using the WINAPI (__stdcall) calling convension and have a return type of DWORD (unsigned long), unless otherwise specified. You will have to provide seven callback functions in your application in order to facilitate communication from the DVC to your application. Consult the provided ‘UnicornDVCAppLib.h’ header file for more information and prototypes.
App to DVC communication functions
These functions are called from within an application to open and communicate to virtual channels.
ConnectionType enumeration
Most App to DVC communication functions take a connectionType parameter of type ConnectionType. This is an enumeration with the following values:
- connectionTypeServer (0)
- connectionTypeClient (1)
Unicorn_Initialize
Prototype: PROTO_UNICORN_INITIALIZE
Parameters:
- ConnectionType connectionType
Possible return values:
- ERROR_SUCCESS (0): The function call succeeded
- ERROR_FILE_NOT_FOUND (2): Trying to initialize in client mode when the DVC plugin is not registered
- ERROR_INVALID_PARAMETER (87): either the provided connection type or channel name is invalid
- ERROR_ALREADY_INITIALIZED (1247): Initialization allready took place
The initialize function is usually the first function to call after loading the library. Calling this function is required to initiate a connection.
Unicorn_SetLicenseKey
Prototype: PROTO_UNICORN_SETLICENSEKEY
Parameters:
- WCHAR* licenseKey: the license key to use during activation
- BOOL activate: If set to FALSE, the provided license key is validated only (not activated). Setting this parameter to TRUE will activate a copy of the product against the license server
- WCHAR* oErrorMessage: Output parameter that will receive a user readable presentation of an error, if the license activation results in an error
Possible return values:
- ERROR_SUCCESS (0): The function call succeeded
- ERROR_INVALID_FUNCTION (1): Unidentified error
- ERROR_NOT_ENOUGH_MEMORY: There is unsufficient memory available to satisfy the request
- ERROR_INVALID_ACCESS: Invalid license key
- ERROR_DS_ENCODING_ERROR: Invalid license key encoding
- ERROR_UNEXP_NET_ERR: Network error during activation (oErrorMessage may contain more details)
- ERROR_INVALID_HW_PROFILE: Invalid hardware identifier (oErrorMessage may contain more details)
- ERROR_CTX_LICENSE_EXPIRED: License expired
- ERROR_ACCESS_DENIED: Invalid activation key
This function is optionally used before initialization to set a license key that will be used to activate the product. When this function is not executed, Unicorn will try to use stored license data or operates in trial mode.
Unicorn_GetHardwareId
Prototype: PROTO_UNICORN_GETHARDWAREID
Parameters: none
Return type: const WCHAR* containing the Hardware ID
This function is used to retrieve the hardware ID of a system. This hardware ID is used in the activation process.
Unicorn_Open
Prototype: PROTO_UNICORN_OPEN
Parameters:
- ConnectionType connectionType
Possible return values:
- ERROR_SUCCESS (0): The function call succeeded
- ERROR_INVALID_FUNCTION (1): Server error indicating that it has been tried to open the channel outside a supported remote session
- ERROR_NOT_READY (21): The function has been called without initializing first
- ERROR_GEN_FAILURE (31): Opening a server side channel has been denied by the client
- ERROR_REQ_NOT_ACCEP (71): The connection has already been opened
- ERROR_INVALID_PARAMETER (87): An invalid channel name has been provided.
- RPC_S_SERVER_UNAVAILABLE (1722): Client error indicating that it was not possible to communicate to the DVC Plugin
This function is called on both sides to open the DVC. In client mode, this function will tell the plugin that the apclient’s end of the connection is ready to accept the server’s initiative to actually create the channel. In server mode, the actual channel will be created.
Unicorn_Write
Prototype: PROTO_UNICORN_WRITE
Parameters:
- ConnectionType connectionType
- ULONG cbSize: The size of the provided buffer (pBuffer)
- BYTE* pBuffer: pointer to an array of bytes to send to the other end of the dvc. Must be cbSize in size
Possible return values:
- ERROR_SUCCESS (0): The function call succeeded
- ERROR_INVALID_HANDLE (6): There was no channel to write to
- ERROR_NOT_READY (21): The function has been called without initializing first
- RPC_S_SERVER_UNAVAILABLE (1722): Client error indicating that it was not possible to communicate to the DVC Plugin
This function is used to write data to the DVC. Note that if you want to send text from one side to another, you will have to provide the conversion routines (e.g. from CHAR* to BYTE* or vise versa) yourself.
Unicorn_Close
Prototype: PROTO_UNICORN_CLOSE
Parameters:
- ConnectionType connectionType
Possible return values:
- ERROR_SUCCESS (0): The function call succeeded
- ERROR_NOT_READY (21): The function has been called without initializing first
- RPC_S_SERVER_UNAVAILABLE (1722): Client error indicating that it was not possible to communicate to the DVC Plugin. Note: This will assume that the DVC Client has already been closed, so even though an error is raised, the state of the app lib will return to closed and you can reopen a channel.
This function closes the virtual channel from the calling side. The _OnClose callback will be called on the other end of the connection. Calling this function is optional, as a call of Terminate will also call Close for you if the channel is still open. It is however advised to do things the clean way…
Unicorn_Terminate
Prototype: PROTO_UNICORN_TERMINATE
Parameters:
- ConnectionType connectionType
Possible return values:
- ERROR_SUCCESS (0): The function call succeeded, library can safely be freed.
- ERROR_NOT_READY (21): The function has been called without initializing first
This function will terminate all communication from and to the library in either server or client mode. After this function has been called for the used connection types, it is possible to free the library if desired. Calling this function is optional, since it will automatically be called upon freeing the library.
Unicorn_SetCallbacks
Prototype: PROTO_UNICORN_SetCallbacks
Parameters:
- ConnectionType connectionType
- PROTO_UNICORN_CONNECTED* _Connected,
- PROTO_UNICORN_DISCONNECTED* _Disconnected,
- PROTO_UNICORN_TERMINATED* _Terminated,
- PROTO_UNICORN_ONNEWCHANNELCONNECTION* _OnNewChannelConnection,
- PROTO_UNICORN_ONDATARECEIVED* _OnDataReceived,
- PROTO_UNICORN_ONREADERROR* _OnReadError,
- PROTO_UNICORN_ONCLOSE* _OnClose
Return type: void
This function is used to register the callback functions you provide/write with the application library. Please consult the section below as well as the example materials for more information.
DVC to app communication callback functions
To support incoming data, it is required that you provide six pointers to the callback functions you have to implement in your application. You can register your callback functions using the Unicorn_SetCallbacks function. This allows communication from the other end of the DVC to flow into your application. See the examples folder for more information about your specific programming language.
_Connected
Note: This callback function is only used in client mode.
Prototype: PROTO_UNICORN_CONNECTED
Parameters: none
This callback is called when the remote client (e.g. mstsc) has established a connection to a remote server.
_Disconnected
Note: This callback function is only used in client mode.
Prototype: PROTO_UNICORN_DISCONNECTED
Parameters:
- DWORD dwDisconnectCode: A code sent from the DVC Plugin to identify the cause of disconnection
This callback is called when the remote client (e.g. mstsc) is disconnected from a remote server.
_Terminated;
Note: This callback function is only used in client mode.
Prototype: PROTO_UNICORN_TERMINATED
Parameters: none
This callback is called when the remote client (e.g. mstsc) is terminated.
_OnNewChannelConnection
Prototype: PROTO_UNICORN_ONNEWCHANNELCONNECTION
Parameters: none
This function is called when a side to side connection has been established, i.e. communication can take place. When the library is used in server mode,an additional thread is created to handle incoming data.
_OnDataReceived
Prototype: PROTO_UNICORN_ONDATARECEIVED
Parameters:
- ULONG cbSize: The size of the provided buffer (pBuffer)
- BYTE* pBuffer: pointer to an array of bytes which contains the received data from the other end of the dvc. Must be cbSize in size
This callback is called for every chunk of data coming from the DVC. Note that if you want to send text from one side to another, you will have to provide the conversion routines (e.g. from BYTE* to CHAR* or vise versa) yourself. Consult the example materials for more information.
_OnReadError
Note: This callback function is only used in server mode.
Prototype: PROTO_UNICORN_ONREADERROR
Parameters:
- DWORD dwErrorCode: A code which identifies the error raised in the Reader function.
This callback is called in server mode when an error is raised when reading from the dvc.
_OnClose
Prototype: PROTO_UNICORN_ONCLOSE
Parameters: none
This callback is called when the other party closed the DVC.
Example workflow
- The client side application initializes the app lib
- A remote desktop connection or similar is created which automatically initializes the DVC Plugin
- The client application opens the channel. In this process, the provided channel name is validated in the DVC Plugin
- The server side application initializes the app lib
- The server application opens the channel
- On both sides, the _OnNewChannelConnection callback is called
- Both sides can exchange data. Data flows out using the Write function, and flows in using the _OnDataReceived callback function
- One side closes the channel, which causes the other end’s _OnClose callback to be called
- Both sides terminate the app lib
Note that the order of steps above may vary. For example, an order of 4, 2, 1, 3, 5 is perfectly valid. However, you should make sure that the client side opens the channel first, as the server side’s request to open the channel requires a respons from the client.
It might be good practice to keep polling the open function on both sides. As soon as both sides of the connection have their app lib initialized, it is allowed to keep calling Open until it returns a value of 0 (ERROR_SUCCESS). Though this may sound slightly tricky, this is the recommended way if you want to create a working connection as soon as possible without having to care about synchronizing both sides of the connection.
UnicornDVC Plugin library
The UnicornDVC Plugin library is the library used for communication by your client software (e.g. Remote Desktop Client, VMware Horizon Client or Citrix Receiver). It implements the Microsoft DVC client-side APIs, which guarantees compatibility with all major remote desktop platforms currently available on the market. It is only required on client systems and doesn’t have to be installed on a server, unless the particular server is a jump server (see below). It should be noted that this library is not suitable for portable use, since using it requires certain information to be added to the Windows Registry. The installer automatically adds the required keys to the registry for use with Remote Desktop Client and VMware Horizon Client. For Citrix Receiver, it is required to modify the registry manually.
Automatic installation
By default, our installer software automatically installs the UnicornDVC Plugin library component. On X64 systems, it will allow you to use the library from both X86 and X64 client software. To support Citrix Receiver, you need to enable Citrix support during the installation. You should also consult the section about Citrix Receiver plugin registration.
Manual installation
If you want to use the UnicornDVC Plugin library from a manual location, go to the particular location from a command prompt with administrative privileges and run the following command:
regsvr32 UnicornDVCPlugin.dll
To uninstall, i.e. to remove the required registry keys, run the following instead:
regsvr32 /u UnicornDVCPlugin.dll
It is recommended to perform the manual installation/removal for both the X86 and X64 version of the UnicornDVC Plugin library.
Note: There is a hyper manual installation method, i.e. avoid the regsvr32 approach and do all the registry tweaks yourself, but due to the risks involved in this process, we do not support this.
Citrix Receiver plugin registration
To use the UnicornDVC Plugin library with Citrix Receiver, additional steps are required:
- Go to the windows registry. If you don’t know how to get there, you are strongly discouraged to go on with this
- Find the following registry key on X64 systems:
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Citrix\ICA Client\Engine\Configuration\Advanced\Modules
And on X86 systems:
HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\ICA Client\Engine\Configuration\Advanced\Modules
- Open the sub key “DVCAdapter”
- Find the value called “DvcPlugins”
- Add the following to the end of the string:
,UnicornDVCPlugin
- If you did not run our installer, additional steps are required. Repeat step 2, be sure that you are add the “Modules” sub key
- Create a new sub key called “DVCPlugin_UnicornDVCPlugin”
- Within this sub key, add the following registry values:
"DvcNames"="UnicornDVCPlugin" "PluginClassId"="{E8BACC05-64F6-4534-9764-FB6698CA3362}"