Attribute VB_Name = "DinkeyPro"

' A VBA Interface to the Dinkey Pro/FD API

' ***********************
' DO NOT MODIFY THIS FILE
' ***********************

Option Explicit

' ------------------------------------------------------------------------------
' Windows API functions used by this module

#If VBA7 Then
    Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
#Else
    Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
#End If

' ------------------------------------------------------------------------------
' Dinkey Runtime Information Structure (DRIS)

Type DRIS
    header As String * 4                ' should be set to "DRIS"
    ' Inputs
    size As Long                        ' size of this structure
    seed1 As Long                       ' seed for data/dris encryption
    seed2 As Long                       ' as above
    function As Long                    ' specify only one function
    flags As Long                       ' options for the function selected. To use more than one OR them together: OPTION1 Or OPTION2...
    execs_decrement As Long             ' amount by which to decrement execs if the DEC_MANY_EXECS flag is used
    data_crypt_key_num As Long          ' number of the key (1-3) that the dongle uses to encrypt or decrypt user data
    rw_offset As Long                   ' offset in the dongle data area to read or write data
    rw_length As Long                   ' length of data to read/write/encrypt/decrypt
#If VBA7 Then
    not_used As LongPtr                 ' This field is a pointer used in other programming languages. 4 bytes in 32-bit Excel, 8 bytes in 64-bit Excel
#Else
    not_used As Long
#End If
    alt_licence_name As String * 256    ' protection check for different licence instead of this one, must be null-terminated ASCII
    var_a As Long                       ' variable values for user algorithms
    var_b As Long
    var_c As Long
    var_d As Long
    var_e As Long
    var_f As Long
    var_g As Long
    var_h As Long
    alg_number As Long                  ' the number of the user algorithm that you want to execute

    ' Outputs
    ret_code As Long                    ' the return code from the protection check
    ext_err As Long                     ' extended error
    type As Long                        ' type of dongle detected. Possible values shown below
    model As Long                       ' model of dongle detected. Possible values shown below
    sdsn As Long                        ' Software Developer's Serial Number
    prodcode As String * 12             ' product code (null-terminated)
    dongle_number As Long               ' dongle serial number
    update_number As Long
    data_area_size As Long              ' size of the data area in the dongle detected
    max_alg_num As Long                 ' the maximum algorithm number in the dongle detected
    execs As Long                       ' executions left: -1 indicates 'no limit'
    exp_day As Long                     ' expiry day: -1 indicates 'no limit'
    exp_month As Long                   ' expiry month: -1 indicates 'no limit'
    exp_year As Long                    ' expiry year: -1 indicates 'no limit'
    features As Long                    ' features value
    net_users As Long                   ' maximum number of network users for the dongle detected: -1 indicates 'mo limit'
    alg_answer As Long                  ' answer to the user algorithm executed with the given variable values
    fd_capacity As Long                 ' FD dongles only- capacity of the data area. Currently fixed at ~8KB but may change in the future.
    fd_drive As String * 128            ' FD dongles only - drive letter of the dongle's flash drive, e.g. "F:\"
    swkey_type As Long                  ' 0 = no software key detected, 1 = temporary software key, 2 = demo software key
    swkey_exp_day As Long               ' software key expiry date (if software key detected)
    swkey_exp_month As Long
    swkey_exp_year As Long
End Type

' ------------------------------------------------------------------------------
' Useful Constants

' Possible dris.function values
Public Const PROTECTION_CHECK = 1           ' Standard protection check
Public Const EXECUTE_ALGORITHM = 2          ' Protection check + execute an algorithm stored in the dongle
Public Const WRITE_DATA_AREA = 3            ' Protection check + write to the dongle data area
Public Const READ_DATA_AREA = 4             ' Protection check + read from the dongle data area
Public Const ENCRYPT_USER_DATA = 5          ' Protection check + use the dongle's encryption engine to encrypt your own data
Public Const DECRYPT_USER_DATA = 6          ' Protection check + the dongle will decrypt user data
Public Const FAST_PRESENCE_CHECK = 7        ' Checks for the presence of a valid dongle. Very quick but weaker security
Public Const STOP_NET_USER = 8              ' Stop a network user (a protection check is NOT performed)

' Possible dris.flags values
Public Const DEC_ONE_EXEC = 1               ' Decrement execs by 1
Public Const DEC_MANY_EXECS = 2             ' Decrement execs by number specified in execs
Public Const START_NET_USER = 4             ' Start a network user
Public Const USE_FUNCTION_ARGUMENT = 16     ' Use the extra argument in the function for pointers
Public Const CHECK_LOCAL_FIRST = 32         ' Force the API to look for a local dongle before a network dongle
Public Const CHECK_NETWORK_FIRST = 64       ' Force the API to look for a dongle on the network before looking in local ports
Public Const USE_ALT_LICENCE_NAME = 128     ' Use name specified in alt_licence_name instead of the default one
Public Const DONT_SET_MAXDAYS_EXPIRY = 256  ' If the max days expiry date has not been calculated then do not do it this time
Public Const MATCH_DONGLE_NUMBER = 512      ' Restrict the search to match the dongle number specified in the DRIS
Public Const DONT_RETURN_FD_DRIVE = 1024    ' if an FD dongle has been detected then don't return the flash drive/mount name in the DRIS 


' Possible dris.type values
Public Const DONGLE_TYPE_PRO = 1    ' Dinkey Pro dongle
Public Const DONGLE_TYPE_FD = 2     ' Dinkey FD dongle

' Possible dris.model values
Public Const DONGLE_MODEL_LITE = 1  ' Lite dongle
Public Const DONGLE_MODEL_PLUS = 2  ' Plus dongle
Public Const DONGLE_MODEL_NET5 = 4  ' Net dongle, 5 users
Public Const DONGLE_MODEL_NETU = 7  ' Net dongle, unlimited users

' ------------------------------------------------------------------------------
' A function to initialise the DRIS with random values

Public Sub RandomSetDrisElements(DrisToSet As DRIS)
    Dim TempDris(Len(DrisToSet)) As Byte
    Dim I As Integer

    Call Randomize

    For I = 0 To Len(DrisToSet) - 1
        TempDris(I) = Int(256 * Rnd())  ' The int part of a random float 0 <= N < 256, i.e. an int between 0 and 255
    Next

    Call CopyMemory(DrisToSet, TempDris(0), Len(DrisToSet))
End Sub

' ------------------------------------------------------------------------------
' This function will convert a C string returned in the DRIS to a VB string

Function TrimCString(CString As String) As String
    Dim I As Integer
    I = InStr(CString, vbNullChar)      ' Find position of terminating null character
    TrimCString = Left(CString, I - 1)  ' Return everything before that position
End Function

' ------------------------------------------------------------------------------
' Visual Basic for Applications only supports signed integers,
' but some DRIS fields such as dongle_number are stored as unsigned integers.
' Use this function to convert those fields to Double values

Public Function UnsignedLongToDouble(Number As Long) As Double
    If (Number < 0) Then
        UnsignedLongToDouble = Number + 4294967296#
    Else
        UnsignedLongToDouble = Number
    End If
End Function
