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