Dongle Implementation

Overview

Several P.I. Engineering devices are capable of being used as a software dongle for piracy prevention of developer's applications. The main use of the dongle feature is to prevent people from using the developer's software without purchasing a P.I. Engineering Product from that developer. The developer must "initialize" each X-keys unit with a "key". Sample code for setting up a unit for dongle protection is shown in the samples under Set Dongel Key. Sample code for checking the unit is shown in the samples under Check Dongle Key. Below are the steps needed to implement this feature.

Set Dongle Key

This one step procedure is done once per unit by the developer prior to sale.

The developer must choose four arbitrary values between 1 and 254, write them to the device using the Set Dongle Key output report format. See the Set Dongle Key example code included in each sample for specific details. The values; K0, K1, K2 and K3, must be recorded for later use in the check of the key.

Important: The programming switch on the unit must be set (switch up on most devices) in order for the Set Dongle Key to work for the following devices: X-keys Desktop (PID 677), X-keys Professional (PID 679), X-keys Stick (PID 693), Legacy X-keys Switch Interface (PID 695), Legacy X-keys Jog & Shuttle (PID 689), X-keys Button Panel (PID 697), X-keys Pendant (PID 687).

Check Dongle Key

This is done within the developer application to determine if the proper hardware "dongle" is connected.

Checking the key requires the developer to choose four arbitrary values between 1 and 254. These values; N0, N1, N2 and N3 are hashed with the K values from the Set Key process to obtain R0, R1, R2, R3 as shown in the code below.

Next a Check Key output report is sent using the N values.

After writing the Check Key output report the unit will send back an input report with the R values from the hash. The developer simply has to compare the values of returned bytes to that of the R values obtained from the DongleCheck() or DongleCheck2() function to confirm the required hardware is attached.

Sample [C++]

.......
//Set Key Routine

//Pick 4 numbers between 1 and 254.
int K0 =  7;
int K1 = 58;
int K2 = 33;
int K3 = 243;
//Save these numbers, they are needed to check the key!

//Write these to the device using the appropriate Set Key output report of desired device
BYTE  buffer[80];
buffer [0] =  0;
buffer [1]  = 192; //Set Dongle Key command
buffer [2]  = K0;
buffer [3]  = K1;
buffer [4]  = K2;
buffer [5]  = K3;

result = WriteData(hDevice, buffer);
//----------------------------------------------
//Check Key Routine

//IMPORTANT turn off the callback if going so data isn't grabbed there, turn it back on later (not done here)
DisableDataCallback(hDevice, true);

//randomn numbers
int N0 =  3; //pick any  number between 1 and 254
int N1 =  1; //pick any  number between 1 and 254
int N2 =  4; //pick any  number between 1 and 254
int N3 =  1; //pick any  number between 1 and 254

//this is the key from Set Dongle Key
K0 = 7;
K1 = 58;
K2 = 33;
K3 = 243;

//hash and save these for comparison later
DongleCheck2(K0, K1, K2, K3,  N0, N1, N2, N3, R0, R1, R2, R3);
BYTE buffer[80];
//Write to the device using the appropriate Check Key output report of desired device, the following is for an X-keys Desktop (PID=677)
buffer[0]=0;
buffer[1]=193;
buffer[2]=N0;
buffer[3]=N1;
buffer[4]=N2;
buffer[5]=N3;

result =  WriteData(hDevice, buffer);
//after this write the next read will give 4 values which are used below for comparison
for (int i=0;i<80;i++)
{
    buffer[i]=0;
}

int countout=0;
int result = BlockingReadData(HDevice, buffer, 100);

while (result == 304 || (result == 0 && buffer[2]!=193)) //for MWII devices first byte=3 
{
	if (result == 304)//No data received after 100 ms, so increment countout extra
	{
		countout+= 99;
	}
	countout++;
	if (countout >1000) //increase this if have to check more than once
	{
		break;
	}

	result = BlockingReadData(hDevice,buffer,100);
}

if (result == 0 && buffer[2]== 193)
{
	bool fail=false;
	//compare with R  values from the DongleCheck2 function
	if (R0!=buffer[3]) fail=true;
	if (R1!=buffer[4]) fail=true;
	if (R2!=buffer[5]) fail=true;
	if (R3!=buffer[6]) fail=true;
	//if fail==true  then correct hardware is not present
}

........

Sample [C#]

.......

//Set Key Routine

//Pick 4 numbers between 1 and 254
int K0 = 7; //pick any number between 1 and 254, 0 and 255 not allowed
int K1 = 58; //pick any number between 1 and 254, 0 and 255 not allowed
int K2 = 33; //pick any number between 1 and 254, 0 and 255 not allowed
int K3 = 243; //pick any number between 1 and 254, 0 and 255 not allowed
//Save these numbers, they are needed to check the key

//Write these to the device using the appropriate Set Key output report of desired device
wData(0) = 0;
wData(1) = 192; //Set Dongle Key command
wData(2) = (byte)K0;
wData(3) = (byte)K1;
wData(4) = (byte)K2;
wData(5) = (byte)K3;

int result = devices[selecteddevice].WriteData(wData); 
//----------------------------------------------
//Check Key Routine

//IMPORTANT turn off the callback if going so data isn't grabbed there, turn it back on later (not done here)
devices[selecteddevice].callNever = true;

//random numbers
int N0 = 3; //pick 4 randomn numbers between 1 and 254
int N1 = 1; //pick 4 randomn numbers between 1 and 254
int N2 = 4; //pick 4 randomn numbers between 1 and 254
int N3 = 1; //pick 4 randomn numbers between 1 and 254

//this is the key from the Set Key
int K0 = 7;
int K1 = 58;
int K2 = 33;
int K3 = 243;

//hash and save these for comparison later
int R0;
int R1;
int R2;
int R3;

PIEDevice.DongleCheck2(K0. K1, K2, K3, N0, N1, N2, N3, out R0, out R1, out R2, out R3);
//Write to the device using the appropriate Check Dongle Key output report of desired device
wdata[0] = 0;
wdata[1] = 193;
wdata[2] = (byte)N0;
wdata[3] = (byte)N1;
wdata[4] = (byte)N2;
wdata[5] = (byte)N3;

int result = devices[selecteddevice].WriteData(WData);

//after this write the next read will give 4 values which are used below for comparison
byte[] data = null; 
int countout = 0; 
int ret = devices[selecteddevice].BlockingReadData(ref data, 100);

While ((ret == 0 && data[2] != 193) || ret == 304) //for MWII devices first byte=3 
{
	if (ret == 304)
	{
		//Didn't get any data for 100ms, increment the countout extra 
		countout += 100;
	}
	countout ++;

	if (countout > 500) //increase this if have to check more than once
	{ 
		break;
	}

	ret = devices[selecteddevice].BlockingReadData(ref data, 100);
}

if (ret == 0 && data[2] == 193)
{

	//compare with R values from the DongleCheck2 function
	bool fail = false
	if (R0 != data[3]) fail = true;
	if (R1 != data[4]) fail = true;
	if (R2 != data[5]) fail = true;
	if (R3 != data[6]) fail = true;
	//if fail==true then correct hardware is not present
}

........

Sample [VB.NET]

.......

'Set Key Routine
'Pick 4 numbers between 1 and 254
Dim K0 As Integer = 7
Dim K1 As Integer = 58
Dim K2 As Integer = 33
Dim K3 As Integer = 243
'Save these numbers, they are needed to check the key

'Write these to the device using the appropriate Set Dongle Key output report of desired device
Dim buffer() As Byte = New Byte() {} 'write data buffer
buffer(0) = 0
buffer(1) = 192 'Set Dongle Key command
buffer(2) = K0
buffer(3) = K1
buffer(4) = K2
buffer(5) = K3

Dim result As Integer = devices(selecteddevice).WriteData(wdata)

'Check Key Routine

'IMPORTANT turn off the callback if going so data isn't grabbed there, turn it back on later (not done here)
devices(selecteddevice).callNever = True

'pick 4 randomn numbers between 1 and 254
Dim N0 As Integer = 3
Dim N1 As Integer = 1
Dim N2 As Integer = 4
Dim N3 As Integer = 1

'this is the key from the Set Key
Dim K0 As Integer = 7
Dim K1 As Integer = 58
Dim K2 As Integer = 33
Dim K3 As Integer = 243

'hash and save these for comparison later

PIEHidDotNet.PIEDevice.DongleCheck2(K0, K1, K2, K3, N0, N1, N2, N3, R0, R1, R2, R3)

'Write to the device using the appropriate Check Dongle Key output report of desired device
Dim buffer() As Byte = New Byte() {} 'write data buffer
buffer(0) = 0
buffer(1) = 193 'check key command
buffer(2) = N0
buffer(3) = N1
buffer(4) = N2
buffer(5) = N3

'after this write the next read will give 4 values which are used below for comparison
Dim result As Integer = devices(selecteddevice).WriteData(wdata)

Dim keydata(devices(selecteddevice).ReadLength) As Byte
Dim countout As Integer = 0

result = devices(selecteddevice).BlockingReadData(keydata, 100)

While (result = 304 Or (result = 0 And keydata(2) <> 193)
	If result = 304 Then
		'no new data after 100 ms, so increment countout extra
		countout = countout + 99  
	End If 
	countout = countout + 1  
	If (countout > 500) Then
		Exit While
	End If
	result = devices(selecteddevice).BlockingReadData(keydata, 100)
End While

If keydata(2) = 193 Then
	Dim fail As Boolean = False
	If R0 <> keydata(3) Then fail = True
	If R1 <> keydata(4) Then fail = True
	If R2 <> keydata(5) Then fail = True
	If R3 <> keydata(6) Then fail = True
	'if fail==true then correct hardware is not present 
End If

........
Back to top