Help - Search - Members - Calendar
Full Version: Free Armadillo Source Code for VB Programmers
SRT User Discussion Forums > SoftwarePassport/Armadillo Public Forums > Code snippets (Public)
videoguy
Hi Everyone,

I thought I'd anonymously share a class that I wrote for wrappering the functions in the Armadillo .DLL that make it very easy to use from VB. I call the class CArmadillo.Cls.

Since I don't see a quick way to attach a file to this post, I'm putting all of the class code here in "cut-and-paste" form. If anyone should need to contact me about this code, I'm sure that Chad knows how to de-anonymize me for contact.

You may need to modify the error trapping to suit your style, but most of it should be almost ready to use.

Without further commentary, here is the class. Enjoy!


CODE
Option Explicit

   '+---------------------------------------------------------------------+'
   '|                                                                     |'
   '|                     CArmadillo Wrapper Class                        |'
   '|                                                                     |'
   '| This class wraps the Armadillo registration/crack-protection shell  |'
   '| making it easy to retrive information from the shell or execute     |'
   '| commands on it.                                                     |'
   '|                                                                     |'
   '| This class is released as open source to assist others using the    |'
   '| Armadillo Shell from the Visual Basic environment and is free for   |'
   '| use in all programs, commercial and otherwise, as long as this      |'
   '| comment block remains intact.                                       |'
   '|                                                                     |'
   '| Armadillo is a product from Silicon Realms software.                |'
   '|                                                                     |'
   '+---------------------------------------------------------------------+'

Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function GetEnvironmentVariable Lib "kernel32" Alias "GetEnvironmentVariableA" (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long
Private Declare Function FormatMessageAPI Lib "kernel32" Alias "FormatMessageA" _
   (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, _
   ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, _
   Arguments As Long) As Long

'Put ArmAccess.DLL in your program's directory or somewhere on the path (such as the Windows directory).
'Now you can call the functions directly, and use Err.LastDllError to get any error codes if necessary

'If using one of these functions causes the certificate to expire (or detects that it's expired, due to
'date-change for instance), Armadillo simply sets the EXPIRED variable. It is up to your program to
'check for and deal with this.
'
'These functions set the last error value (retrieved with the Windows API function GetLastError()). This
'lets you determine why the call failed, if you wish to. Note that it is usually enough to check the
'return value; these codes are provided mostly for debugging purposes. The following values
'may be returned by GetLastError():
Private Declare Function ArmCheckCode Lib "dll_name.dll" Alias "CheckCode" (ByVal name As String, ByVal Code As String) As Byte
Private Declare Function ArmVerifyKey Lib "dll_name.dll" Alias "VerifyKey" (ByVal name As String, ByVal Code As String) As Byte
Private Declare Function ArmInstallKey Lib "dll_name.dll" Alias "InstallKey" (ByVal name As String, ByVal Code As String) As Byte
Private Declare Function ArmInstallKeyLater Lib "dll_name.dll" Alias "InstallKeyLater" (ByVal name As String, ByVal Code As String) As Byte
Private Declare Function ArmUninstallKey Lib "dll_name.dll" Alias "UninstallKey" () As Byte
Private Declare Function ArmSetDefaultKey Lib "dll_name.dll" Alias "SetDefaultKey" () As Byte
Private Declare Function ArmUpdateEnvironment Lib "dll_name.dll" Alias "UpdateEnvironment" () As Byte
Private Declare Function ArmIncrementCounter Lib "dll_name.dll" Alias "IncrementCounter" () As Byte
Private Declare Function ArmCopiesRunning Lib "dll_name.dll" Alias "CopiesRunning" () As Long
Private Declare Function ArmChangeHardwareLock Lib "dll_name.dll" Alias "ChangeHardwareLock" () As Byte
Private Declare Function ArmGetShellProcessID Lib "dll_name.dll" Alias "GetShellProcessID" () As Long

' SetWindowPos Flags
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOZORDER = &H4
Private Const SWP_NOREDRAW = &H8
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_FRAMECHANGED = &H20        '  The frame changed: send WM_NCCALCSIZE
Private Const SWP_SHOWWINDOW = &H40
Private Const SWP_HIDEWINDOW = &H80
Private Const SWP_NOCOPYBITS = &H100
Private Const SWP_NOOWNERZORDER = &H200      '  Don't do owner Z ordering
Private Const SWP_DRAWFRAME = SWP_FRAMECHANGED
Private Const SWP_NOREPOSITION = SWP_NOOWNERZORDER

' SetWindowPos() hWndInsertAfter values
Private Const HWND_TOP = 0
Private Const HWND_BOTTOM = 1
Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2

Public Enum ArmadilloErrors
   ERROR_SUCCESS = 0
   ERROR_BAD_ENVIRONMENT = 10
   ERROR_INVALID_DATA = 13
   ERROR_BROKEN_PIPE = 109
   ERROR_BUSY = 170
   ERROR_ACCOUNT_RESTRICTION = 1327
   ERROR_ACCOUNT_DISABLED = 1331
   ERROR_LICENSE_QUOTA_EXCEEDED = 1395
   ERROR_ACCOUNT_EXPIRED = 1793
   ERROR_INVALID_DATATYPE = 1804
   ERROR_ACCOUNT_LOCKED_OUT = 1909
   ERROR_BAD_USERNAME = 2202
End Enum

Private Function ErrCodeToString(ByVal ErrCode As Long) As String
   On Error GoTo Hell
   Dim strTemp As String
   
   Select Case ErrCode
       Case ERROR_SUCCESS: strTemp = "Operation was completed successfully."
       Case ERROR_BAD_ENVIRONMENT: strTemp = "Can't establish communications with the Armadillo shell. This usually means that you haven't protected the program."
       Case ERROR_INVALID_DATA: strTemp = "There was an error in the communications path. You might be able to get it to work if you try the call a second time. If you receive this error again, it's probably unrecoverable."
       Case ERROR_BROKEN_PIPE: strTemp = "Could not open the communications path. This is probably an unrecoverable error."
       Case ERROR_BUSY: strTemp = "Returned only by the CopiesRunning function, if the network is too busy to get a response. Should almost never be seen in the real world."
       Case ERROR_ACCOUNT_RESTRICTION: strTemp = "The certificate has 'Limit Key Validity' set, and this key is either past the date it is allowed to be installed, or Armadillo has detected a problem with the system clock."
       Case ERROR_ACCOUNT_DISABLED: strTemp = "The key is an upgrade key, and the user does not have an existing upgradable key installed."
       Case ERROR_LICENSE_QUOTA_EXCEEDED: strTemp = "The key was successfully installed, but there are now more computers using this key than it is licensed for. Please see the discussion on the Limit Copies option for more information."
       Case ERROR_ACCOUNT_EXPIRED: strTemp = "The name/key you specified was valid at one time, but is now expired. It should not be considered a usable key."
       Case ERROR_INVALID_DATATYPE: strTemp = "The certificate in use is not expire-by-uses (IncrementCounter, or the key installed is not a hardware locked key (UninstallKey."
       Case ERROR_ACCOUNT_LOCKED_OUT: strTemp = "This key is listed in the Stolen Codes Database for the program."
       Case ERROR_BAD_USERNAME: strTemp = "The name/key you specified is not valid for this program."
       Case Else
           strTemp = FormatMessage(ErrCode) '//Assume it's from the Windows API
           Debug.Assert False
   End Select
   
   ErrCodeToString = strTemp

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.ErrCodeToString(ErrCode)", ErrCode, EA_INTERNCALL
End Function

Private Function FormatMessage(ByVal ErrNum As String) As String
   Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
       Dim strBuffer As String * 512, strMsg As String
       On Error GoTo errHandler
   
   FormatMessageAPI FORMAT_MESSAGE_FROM_SYSTEM, Null, ErrNum, 0, strBuffer, 512, 0
   strMsg = strBuffer
           'Strange but necessary manipulations
   strMsg = Replace(strMsg, vbNewLine, "")
   strMsg = Replace(strMsg, Chr(0), "")
   FormatMessage = strMsg
   
   Exit Function
errHandler:
       'Nothing to do...
End Function

Private Function GetEnvironString(name As String) As String
   On Error GoTo Hell
   'Define a string for the return value
   Dim ReturnString As String

   'First, pad the return value string so that it's big enough.
   ReturnString = Space$(256)

   'Now call the GetEnvironmentVariable function. If the function indicates
   'that the variable doesn't exist, return an empty string. Otherwise,
   'return the contents of the variable.
   If GetEnvironmentVariable(name, ReturnString, 256) <> 0 Then
       GetEnvironString = Trim$(StripNulls(ReturnString))
   Else
       GetEnvironString = ""
   End If

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.GetEnvironString(Name)", name, EA_INTERNCALL
End Function

Public Function hWndLoading() As Long
   On Error GoTo Hell
   Dim strTemp As String

   'LOADINGWINDOW: If you use a custom bitmap loading window, this variable holds the
   'handle of this window, in hexadecimal format. You can use this handle to close or
   'hide the loading window when your program starts up, if you don't wish to rely on Armadillo's timer.
   
   'You could also issue a WM_CLOSE to the Window, but I thought it to be safer to leave the hWnd valid
   'for Armadillo to close the Window when the timer expires.
   
   'You should call this method when the main window of your application is fully loaded to remove the
   'loading window if you are using it as the Splash screen of your application.
   
   strTemp = GetEnvironString("LOADINGWINDOW")
   If Len(strTemp) > 0 Then
       hWndLoading = CLng("&H" & strTemp)
   End If

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.hWndLoading(strTemp)", strTemp, EA_INTERNCALL
End Function

Public Sub HideLoadingWindow()
   On Error GoTo Hell
   Dim hwnd As Long
   Dim strTemp As String

   'LOADINGWINDOW: If you use a custom bitmap loading window, this variable holds the
   'handle of this window, in hexadecimal format. You can use this handle to close or
   'hide the loading window when your program starts up, if you don't wish to rely on Armadillo's timer.
   
   'You could also issue a WM_CLOSE to the Window, but I thought it to be safer to leave the hWnd valid
   'for Armadillo to close the Window when the timer expires.
   
   'You should call this method when the main window of your application is fully loaded to remove the
   'loading window if you are using it as the Splash screen of your application.
   
   hwnd = Me.hWndLoading
   If hwnd <> 0 Then
       SetWindowPos hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER Or SWP_NOSIZE Or SWP_NOMOVE Or SWP_HIDEWINDOW
   End If

Exit_Proc:
   Exit Sub

Hell:
   ErrorIn "CArmadillo.HideLoadingWindow(hwnd)", hwnd, EA_INTERNCALL
End Sub

Public Sub Register()
   On Error GoTo Hell

   'PROTECTEDFILE: This variable holds the path and filename of the (protected) EXE file.
   'If your program needs to know where the original EXE file is (for instance, to locate
   'some data files that are in the same directory), it should use this variable's contents
   'instead of relying on the Windows API call GetModuleFileName(). The reason:
   'GetModuleFileName() returns the name of the actual file. In the case of an
   'Armadillo-protected program, this will be the temporary file (usually with the
   'extension .TMP0 instead of EXE), and if your program is run from a read-only
   'directory or CD, Armadillo is forced to create this file in the Windows temporary
   'directory instead of the one where the program is stored.

   Dim strTemp As String
   
   
   If IsInIDE Then Exit Sub
   strTemp = GetEnvironString("PROTECTEDFILE")
   If Len(strTemp) > 0 Then
       Shell strTemp & " REGISTER", vbNormalFocus
   Else
       MsgBox "The registration attempt failed.  Registration shell is not present." & vbCrLf & vbCrLf & "Please contact technical support", vbCritical, APPNAME
   End If
   
Exit_Proc:
   Exit Sub

Hell:
   ErrorIn "CArmadillo.Register", , EA_INTERNCALL
End Sub

Public Sub ShowRegInfo()
   On Error GoTo Hell

   Dim strTemp As String
   
   
   strTemp = GetEnvironString("PROTECTEDFILE")
   If Len(strTemp) > 0 Then
       Shell strTemp & " INFO", vbNormalFocus
   Else
       GoTo Hell
   End If
   
Exit_Proc:
   Exit Sub

Hell:
   ErrorIn "CArmadillo.ShowRegInfo", , EA_INTERNCALL
End Sub

Public Property Get HardwareFingerPrint(Optional ByVal Enhanced As Boolean = False) As String
   On Error GoTo Hell
   'ENHFINGERPRINT: Similar to the FINGERPRINT variable documented below, this
   'one holds the enhanced hardware-locking fingerprint, for certificates that use enhanced hardware locking.

   'FINGERPRINT: This variable appears only if your program includes at least one
   'hardware-locked certificate. It contains the eight-digit hexadecimal
   '"machine fingerprint" of the computer your program is currently running
   'on, which is necessary to make a hardware-locked key.
   
   If Enhanced Then
       HardwareFingerPrint = GetEnvironString("ENHFINGERPRINT")
   Else
       HardwareFingerPrint = GetEnvironString("FINGERPRINT")
   End If

Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.HardwareFingerPrint(Enhanced)", Enhanced, EA_INTERNCALL
End Property

Public Property Get IsRegistered() As Boolean
   On Error GoTo Hell
   '//ASSUMES: when the 'Default' certificate is installed, the software is UNregistered.
   '//When any other certificate is installed, the software is registered.
   
#If INTERNAL_BUILD Then
   IsRegistered = True
   Exit Property
#End If
   
   IsRegistered = CBool(Len(Me.UserName) > 0)
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.IsRegistered", , EA_INTERNCALL
End Property
   
Public Property Get IsRegisteredEx(ByVal ExtraInfoMatch As Integer) As Boolean
   On Error GoTo Hell
   '//Returns TRUE only if the product is REGISTERED, and if the stored ExtraInfo
   '//matches the ExtraInfo passed into the method.

#If INTERNAL_BUILD Then
   IsRegisteredEx = True
   Exit Property
#End If
   
   If Me.IsRegistered Then
       IsRegisteredEx = CBool(Me.ExtraInfo = ExtraInfoMatch)
   End If

Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.IsRegisteredEx", , EA_INTERNCALL
End Property


Private Function StripNulls(OriginalStr As String) As String
   On Error GoTo Hell

' Strips any trailing nulls from path names retrieved
' from the registry. This function is found in the
' following Microsoft(r) knowledge base articles:
' Q183009 "HOWTO: Enumerate Windows Using the WIN32 API"
' Q185476 "HOWTO: Search Directories to Find or List Files"
' Q190218 "HOWTO: Retrieve Settings From a Printer Driver"

 If (InStr(OriginalStr, Chr(0)) > 0) Then
   OriginalStr = Left(OriginalStr, _
       InStr(OriginalStr, Chr(0)) - 1)
 End If
 
 StripNulls = OriginalStr

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.StripNulls(OriginalStr)", OriginalStr, EA_INTERNCALL
End Function


Public Property Get UserName() As String
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'USERNAME: This is the name on the user's key, or DEFAULT if they're using the default certificate.
   'Note that this string is used by some other programs; for compatibility, the user's name is also
   'stored in the ALTUSERNAME string. Note: If the registry information is somehow corrupted, and
   'you were using an older version of Armadillo before, then the user's name may be lost. In this case,
   'it will appear as the string "MISSING" (without the quotes) instead. All other information, including
   'the number of days or uses remaining, will remain.
   
   
#If INTERNAL_BUILD Then
   UserName = "Milori Insider"
   Exit Property
#End If
   
   strTemp = Trim$(GetEnvironString("ALTUSERNAME"))
   If UCase(strTemp) = "DEFAULT" Then strTemp = ""
   If IsInIDE And Len(strTemp) = 0 Then strTemp = "Program Author"
   If Len(strTemp) > 0 Then
       UserName = strTemp
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.UserName", , EA_INTERNCALL
End Property


Public Property Get DaysInstalled() As Long
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'DAYSINSTALLED: This variable contains the number of days since the current key was
   'installed. On the day of installation, it is zero.
   
   strTemp = GetEnvironString("DAYSINSTALLED")
   If Len(strTemp) > 0 Then
       DaysInstalled = CLng(strTemp)
   Else
       DaysInstalled = 0
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.DaysInstalled", , EA_INTERNCALL
End Property

Public Property Get ExtraInfo() As Integer
   On Error GoTo Hell
   Dim strTemp As String
   
   'EXTRAINFO: Any "extra information" you have stored in the key is stored in this
   'variable, in decimal format. If the certificate uses the extra bits for another
   'purpose, such as storing expiration information in the key, then this variable will contain a zero.
   
   strTemp = GetEnvironString("EXTRAINFO")
   If Len(strTemp) > 0 Then
       ExtraInfo = CInt(strTemp)
   Else
       ExtraInfo = 0
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.ExtraInfo", , EA_INTERNCALL
End Property

Public Property Get KeyCreated() As String
   On Error GoTo Hell
   Dim strTemp As String
   
   'KEYCREATED: This contains the date, in the form "YYYY.MM.DD", that the user's key was created on.
   'It is not set for the default key.
   
   KeyCreated = GetEnvironString("KEYCREATED")
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.KeyCreated", , EA_INTERNCALL
End Property

Public Property Get UserKey() As String
   On Error GoTo Hell
   Dim strTemp As String
   
   'USERKEY: This is the key that the program is currently running under. It is not set for
   'the default key, and should not be trusted for expire-by-uses keys entered before version 1.73.

   UserKey = GetEnvironString("USERKEY")
   If IsInIDE And Len(UserKey) = 0 Then UserKey = "Development"
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.UserKey", , EA_INTERNCALL
End Property

Public Property Get DaysLeft() As Long
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'DAYSLEFT: For date- and day-limited certificates, this is set to the number of valid
   'days left on the key. When this is set to 1, the key will expire at midnight.
   
   strTemp = GetEnvironString("DAYSLEFT")
   If Len(strTemp) > 0 Then
       DaysLeft = CLng(strTemp)
   Else
       DaysLeft = 0
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.DaysLeft", , EA_INTERNCALL
End Property

Public Property Get CopiesAllowed() As Long
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'COPIESALLOWED: If your program uses the Limit Copies feature, this variable is set to the
   'number of copies permitted for the current certificate and key.
   
   strTemp = GetEnvironString("COPIESALLOWED")
   If Len(strTemp) > 0 Then
       CopiesAllowed = CLng(strTemp)
   Else
       CopiesAllowed = 0
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.CopiesAllowed", , EA_INTERNCALL
End Property

Public Property Get DaysInstalledBit(ByVal BitNumber As Byte) As Boolean
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'DAYSINSTALLEDBITx: This is actually fifteen different variables, DAYSINSTALLEDBIT1 through DAYSINSTALLEDBIT15.
   'They contain the number of days since the corresponding "extra information" bit was last changed,
   'and can be used with Modification Keys to set up a trial period for separate modules in your program.
   
   strTemp = GetEnvironString("DAYSINSTALLEDBIT" & CStr(BitNumber))
   If Len(strTemp) > 0 Then
       DaysInstalledBit = CBool(strTemp)
   Else
       DaysInstalledBit = False
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.DaysInstalledBit(BitNumber)", BitNumber, EA_INTERNCALL
End Property

Public Property Get Expired() As Boolean
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'EXPIRED: This variable is set only if you've chosen the "don't show expiration message"
   '(on the Expire window) and the certificate has expired. Armadillo will let the program run
   'after expiration if that box is checked, the program itself must check for this variable.
   
   strTemp = GetEnvironString("EXPIRED")
   If Len(strTemp) > 0 Then
       Expired = CBool(strTemp)
   Else
       Expired = False
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.Expired", , EA_INTERNCALL
End Property

Public Property Get ExpiredVersion() As String
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'EXPIREVER: For the expire-by-version certificates, this tells you what version the key will expire on.
   
   strTemp = GetEnvironString("EXPIREVER")
   If Len(strTemp) > 0 Then
       ExpiredVersion = strTemp
   Else
       ExpiredVersion = ""
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.ExpiredVersion", , EA_INTERNCALL
End Property

Public Property Get UsesLeft() As Long
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'USESLEFT: For certificates offering a limited number-of-uses, this is set to the number
   'of uses remaining. If the user is on the last use, this is set to 1.
   
   strTemp = GetEnvironString("USESLEFT")
   If Len(strTemp) > 0 Then
       UsesLeft = CLng(strTemp)
   Else
       UsesLeft = 0
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.UsesLeft", , EA_INTERNCALL
End Property

Public Property Get ClockBack() As Boolean
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'CLOCKBACK: If you have chosen to disable Armadillo's clock-back checking
   '(by way of the Don't Report Clock-Back on the Project window), this variable
   'will be set when Armadillo detects a problem with an incorrect system clock.
   
   strTemp = GetEnvironString("CLOCKBACK")
   If Len(strTemp) > 0 Then
       ClockBack = CBool(strTemp)
   Else
       ClockBack = False
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.ClockBack", , EA_INTERNCALL
End Property

Public Property Get InvalidKey() As Boolean
   On Error GoTo Hell
   Dim strTemp As String
   
   
   'INVALIDKEY: This variable is only used if you have the Auto-revert on invalid key
   'option set, and the key stored on a user's system is invalid (probably because you've
   'changed an encryption template). It is only set during the first such run; after that,
   'the user will be automatically reset to the default certificate, if any. This is
   'intended to let your program gracefully warn the user of the change.
   
   strTemp = GetEnvironString("INVALIDKEY")
   If Len(strTemp) > 0 Then
       InvalidKey = CBool(strTemp)
   Else
       InvalidKey = False
   End If
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.InvalidKey", , EA_INTERNCALL
End Property


'Do It Yourself: Integrating Armadillo With Your Programs Using ArmAccess.DLL
'You have the option of bypassing all of Armadillo's screens and replacing them with your own if you wish
'by using the included ArmAccess.DLL file.

'What it does
'ArmAccess.DLL (which you can distribute with your programs free of charge) is a small dynamic-link
'library which hooks into the Armadillo shell around your program, allowing you two-way communication
'with it. This lets you create your own registration dialogs instead of using Armadillo's default
'"register" screen, among other things.

'The Functions
'ArmAccess.DLL exports several functions. Most of them return non-zero (a Boolean 'true' in C) on success,
'or zero if there is an error or they cannot carry out the requested function for some reason.

Public Function InstallKey(ByVal name As String, ByVal Key As String, Optional ByVal InstallOnExit As Boolean = False) As Boolean
   On Error GoTo Hell
   'CheckCode: Checks a name/key pair, and (if valid) stores it as the new key. Returns non-zero if the code is valid.
   'InstallKey: This is identical to CheckCode. You can use either name.
   'InstallKeyLater: This function, like VerifyKey (below), checks whether a key is good and returns non-zero
   '(and sets environment variables) if it is. It doesn't install the key until that copy of the program exits though.

   If InstallOnExit Then
       InstallKey = CBool(ArmInstallKeyLater(name, Key))
   Else
       InstallKey = CBool(ArmInstallKey(name, Key))
   End If

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.InstallKey(Name,Key,InstallOnExit)", Array(name, Key, InstallOnExit), _
        EA_INTERNCALL
End Function

Public Function LastErrorS() As String
   On Error GoTo Hell
   LastErrorS = ErrCodeToString(Err.LastDllError)

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.LastErrorS", , EA_INTERNCALL
End Function

Public Function UninstallKey() As String
   On Error GoTo Hell
   'UninstallKey: Securely uninstalls a hardware-locked key, and change the hardware "fingerprint"
   'so that it can't be reinstalled. It also gives you an uninstall code (in the otherwise-undocumented
   'environment variable UNINSTALLCODE), so that you can manually verify that the key has been uninstalled.
   
   '//This function uninstalls the license and returns the uninstallcode
   If CBool(ArmUninstallKey) Then
       UninstallKey = GetEnvironString("UNINSTALLCODE")
   End If

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.UninstallKey", , EA_INTERNCALL
End Function

Public Function IsValidKey(ByVal name As String, ByVal Key As String, Optional ByVal UpdateEnvironment As Boolean = False) As Boolean
   On Error GoTo Hell
   'VerifyKey: This function is similar to CheckCode/InstallKey. It checks a name/key pair,
   'returning non-zero if it's valid and could be installed. However, unlike CheckCode/InstallKey,
   'it does not install the key; the original key remains installed. After calling VerifyKey,
   'the environment variables are set as if the key were installed; to recover the environment
   'variables for the original key, call UpdateEnvironment.
   
   If CBool(ArmVerifyKey(name, Key)) Then
       IsValidKey = True
       If UpdateEnvironment Then
           '//Do nothing.  This happens automatically.
       Else
           '//Restore the environment back the way that it was, if the user didn't
           '//intend to update the environment.
           ArmUpdateEnvironment
       End If
   Else
       IsValidKey = False
   End If


Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.IsValidKey(Name,Key,UpdateEnvironment)", Array(name, Key, UpdateEnvironment), _
        EA_INTERNCALL
End Function

Public Function RestoreDefaultKey() As Boolean
   On Error GoTo Hell
   'SetDefaultKey: Calling this function will force the Armadillo shell to revert to the default
   'certificate (if any) for your program.
   RestoreDefaultKey = CBool(ArmSetDefaultKey)

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.RestoreDefaultKey", , EA_INTERNCALL
End Function

Public Function UpdateEnvironment() As Boolean
   On Error GoTo Hell
   'UpdateEnvironment: You can call this function to have Armadillo update the environment strings it sets.
   'This is intended for programs that are often left running for days at a time, and lets you check
   'whether the current key is still valid.
   UpdateEnvironment = CBool(ArmUpdateEnvironment)

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.UpdateEnvironment", , EA_INTERNCALL
End Function

Public Function IncrementCounter() As Boolean
   On Error GoTo Hell
   'IncrementCounter: This function allows you to control the "usage count" of an Armadillo
   'expire-by-uses certificate. Every time it's called, it increases the usage count by one
   'and updates the environment. If you're using this function to count uses, and don't
   'want Armadillo to automatically increment the counter when the program starts, then set
   'the certificate to expire "After number of uses (counted by DLL)".
   IncrementCounter = CBool(ArmIncrementCounter)

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.IncrementCounter", , EA_INTERNCALL
End Function

Public Function CopiesRunning() As Long
   On Error GoTo Hell
   'CopiesRunning: Mainly used with network licenses, this function returns the number of copies running
   'on the network at the time it is called (including the calling copy). Returns zero if there is an error.
   'Note that this function only reports the number of copies that are using the same key as the one
   'that makes the request.
   CopiesRunning = ArmCopiesRunning

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.CopiesRunning", , EA_INTERNCALL
End Function

Public Function ChangeHardwareLock() As Boolean
   On Error GoTo Hell
   'ChangeHardwareLock: Used only with hardware-locked keys, this function randomly changes the
   'hardware "fingerprint" for a machine, just as if the TRANSFER command were used.
   ChangeHardwareLock = CBool(ArmChangeHardwareLock)

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.ChangeHardwareLock", , EA_INTERNCALL
End Function

Public Function PID() As Long
   On Error GoTo Hell
   'GetShellProcessID: Returns the Process ID of the Armadillo shell around your program,
   'for some web-update programs and other advanced usage.
   PID = ArmGetShellProcessID

Exit_Proc:
   Exit Function

Hell:
   ErrorIn "CArmadillo.PID", , EA_INTERNCALL
End Function
videoguy
He, he, he.

The error trap was censored!

It said "On Error Goto H*ll", but I guess that's not appropriate.

lol.gif
Chad Nelson
Thanks for posting that! smile.gif We've gotten several such "donations" in the past from various people (possibly from you as well, I would have to go back and look), but we had no place to put them where everyone could use them. I hadn't thought to put them here. smile.gif

QUOTE
If anyone should need to contact me about this code, I'm sure that Chad knows how to de-anonymize me for contact.

No need, I believe they can private-message you through the forum, even "anonymized." smile.gif
Rayg
Thanks for the VB code. I am trying to get it to work but the sub or function ErrorIn was not defined. COuld you post the ErrorIn sub or function. Thanks for the code it will make it easy for me to work with armadillo!
Thanks
Ray
videoguy
Hi Ray,

"ErrorIn" is a function in the free, open-source error-handling library for VB called "HuntErr". Search Google for HuntErr and you will find it.

Since it is someone else's code, I really should not post it, but it is great (although complex enough to need a little getting familiar with).

Good luck!
Simon
I found the "HuntErr" library but i'm not sure how to add it to the prject. Every time I try I get errors. Can some one help me? Thanks
GaryG
I've discovered what I think is a bug in the IsRegistered property. It's testing for a zero-length Me.UserName string, and setting IsRegistered = True if the user name is a zero length string.

But, the UserName property Get procedure returns a user name of "Trial Version" when the ALTUSERNAME = "DEFAULT".

So, IsRegistered will always return True when the default certificate (or, any certificate) is installed.

Fortunately, fixing this is easy. Just test for Me.UserName = "Trial Version" in the IsRegistered property Get procedure, and assume it is NOT registered if the user name = "Trial Version". My code in IsRegistered now looks like this:

If LenB(Me.UserName) = 0 Then
IsRegistered = False
ElseIf Me.UserName = "Trial Version" Then
IsRegistered = False
Else
IsRegistered = True
End If

HTH,

GG
k_kampen
Thanks for the code. as a beginner it will help greatly.

but as a beginner i cannot for the life of me figure out how to call it. sad.gif

I have purchased Armadillo Basic edition

I get the user to put in thier username and key in a dialog.

How do i pass that to the InstallKey function. I know, i know this is basic programming..

Thanks you in advance
LadyWinger
QUOTE (videoguy @ 2002.07.31 03:12 (Wednesday))
Public Property Get UserKey() As String
   On Error GoTo Hell
   Dim strTemp As String
   
   'USERKEY: This is the key that the program is currently running under. It is not set for
   'the default key, and should not be trusted for expire-by-uses keys entered before version 1.73.

   UserKey = GetEnvironString("USERKEY")
   If IsInIDE And Len(UserKey) = 0 Then UserKey = "Development"
   
Exit_Proc:
   Exit Property

Hell:
   ErrorIn "CArmadillo.UserKey", , EA_INTERNCALL
End Property

I thank you so very much for posting the class module. Unfortunately as soon as I tried running I got an error on the Get UserKey Property. It tells me that IsInIDE is not a defined variable. Is there something missing or should I go through all the code and look for everything?

Once again, thanks. lol.gif I wa pulling my hair out trying to work with the ArmAccess.DLL

LadyWinger
raysun
Hi:
Below is the registration part of a VB program. How do I call the Armadillo class that Videoguy had posted? All I want to capture are the Customer's Name and the registration key coming from the armadillo.dll.

'================
Public Sub Main()
Dim key As RegType
Dim reg As RegType
Dim fnum%

On Error Resume Next

If App.PrevInstance <> 0 Then
MsgBox "MyApp is already running. Please click its " & _
"icon on the Taskbar.", vbInformation
End

' Else
' 'check if registered
' key.id = GetSetting("apw", "info", "id")
' key.owner = GetSetting("apw", "info", "owner")
' If (Trim(key.owner) = "") Or (Trim(key.id) = "") Then
' frmReg2.Show 1
' reg.id = Trim(UCase(frmReg2.txt(1)))
' reg.owner = Trim(frmReg2.txt(0))
' Unload frmReg2

' Else
' fnum = FreeFile
' Open App.Path & "\reg.key" For Binary Access Read As #fnum Len = Len(reg)
' Get #fnum, 1, reg
' Close #fnum

' If Err <> 0 Then
' MsgBox "Registration key not found.", vbCritical
' End

' ElseIf (StrComp(StrReverse(Trim(UCase(key.id))), Trim(UCase(reg.id)), vbBinaryCompare) <> 0) Or _
' (StrComp(StrReverse(Trim(UCase(key.owner))), Trim(UCase(reg.owner)), vbBinaryCompare) <> 0) Then
' MsgBox "Registration key does not match original setup." & vbCrLf & vbCrLf & _
' "You need to repeat registration process.", vbCritical
' frmReg2.Show 1
' reg.id = Trim(UCase(frmReg2.txt(1)))
' reg.owner = Trim(frmReg2.txt(0))
' Unload frmReg2
' End If 'err<>0
' End If '(key.owner="") or (key.id="")
End If 'app.previnstance

'set property
Randomize Timer
Screen.MousePointer = vbHourglass
frmMain.Show
frmSplash.lbl(9) = Trim(reg.owner)
frmSplash.lbl(11) = Trim(reg.id)
frmSplash.Show '1
Status True, "connecting to database..."

'==========================

Thanks.
Raysun
LadyWinger
QUOTE (raysun @ 2004.03.13 06:35 (Saturday))
Hi:
Below is the registration part of a VB program.  How do I call the Armadillo class that Videoguy had posted?  All I want to capture are the Customer's Name and the registration key coming from the armadillo.dll.

Thanks.
Raysun

To call the armadillo class

Dim Arm as new cArmadillo (assuming that yours is named cArmadillo

Checking a version.

if arm.version = xxx then
end if

want to show the days left
arm.daysleft


Some mods have to be made to the class to get it to work. Videoguy did some generalizations in the code that need to be cleaned up. It took a little while but I got it to work.

I created a subroutine called CheckReg that does all the work and calls all the methods of the class. That way I can just call CheckReg if I want to include it or comment out that line if I want to remove the checking.

Suzette
raysun
Thank you ladywinger. That would start me out.

Cheers!
Raysun
GaryG
The VB Armadillo class code posted in this forum contains a .Register routine. That routine shells the "PROTECTEDFILE" variable, with the "REGISTER" command line option, like this:

Shell strTemp & " REGISTER", vbNormalFocus

Now that the ShowEnterKeyDialog function is available in ArmAccess.dll, I assume the following would be a suitable replacement for the .Register function in this class:

Dim nResult As Byte

nResult = ShowEnterKeyDialog(0)

If nResult <> 0 Then
' Successful registration.
Else
' Registration failed
End If

This assumes that the new function has been declared in the class, as follows:
Private Declare Function ShowEnterKeyDialog Lib "ArmAccess.DLL" (ByVal ParentWindow As Long) As Byte


Does this look correct? In particular, can the ShowEnterKeyDialog function be called with a hWnd parameter = 0?
Chad Nelson
QUOTE (GaryG @ 2004.07.06 17:39 (Tuesday))
[...] Does this look correct?  In particular, can the ShowEnterKeyDialog function be called with a hWnd parameter = 0?

Yes it does, and yes it can. A zero for the parent window just tells Armadillo that the window shouldn't have a parent. The same goes for all of the ArmAccess.DLL functions that use parent window handles.
XLR8
>'Put ArmAccess.DLL in your program's directory or somewhere on the path (such >as the Windows directory).
>'Now you can call the functions directly, and use Err.LastDllError to get any error >codes if necessary

Can this code just call the "Attached" "internal" ArmAccess.DLL ?

How do I add a reference to the internal dll in VB6 ?
MikeWilson
In Classic VB, select "Project" from the main menu, and then "References". You can select a reference to any registered .dll library from here.

My question is, when attempting to compile a .dll library using only this class - EA_INTERNCALL is not declared. Is this because I need a reference to some Armadillio library from the ArmAccess library project?

Thanks!
MikeWilson
I get an undefined variable on "IsInIDE" during compilation.

My guess is that my process hasn't attached to the ArmAccess.dll.

How would I go about attaching to this process without explicitally adding a reference to the ArmAccess.dll?

Thanks!

Mike
MikeWilson
I'm also unable to get my Armadillo installation working. Does anyone have any sample code that works?
ChadAmberg
Here's a version of the Armadillo class that I've updated for many of the new features...
CODE
Option Explicit

  '+---------------------------------------------------------------------+'
  '|                                                                     |'
  '|                     clsArmadillo Wrapper Class                      |'
  '|                                                                     |'
  '| This class wraps the Armadillo registration/crack-protection shell  |'
  '| making it easy to retrive information from the shell or execute     |'
  '| commands on it.                                                     |'
  '|                                                                     |'
  '| This class is released as open source to assist others using the    |'
  '| Armadillo Shell from the Visual Basic environment and is free for   |'
  '| use in all programs, commercial and otherwise, as long as this      |'
  '| comment block remains intact.                                       |'
  '|                                                                     |'
  '| Armadillo is a product from Silicon Realms software.                |'
  '|                                                                     |'
  '+---------------------------------------------------------------------+'
Private m_bInIDE As Boolean
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function GetEnvironmentVariable Lib "kernel32" Alias "GetEnvironmentVariableA" (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long
Private Declare Function FormatMessageAPI Lib "kernel32" Alias "FormatMessageA" _
  (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, _
  ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, _
  Arguments As Long) As Long

'Put ArmAccess.DLL in your program's directory or somewhere on the path (such as the Windows directory).
'Now you can call the functions directly, and use Err.LastDllError to get any error codes if necessary

'If using one of these functions causes the certificate to expire (or detects that it's expired, due to
'date-change for instance), Armadillo simply sets the EXPIRED variable. It is up to your program to
'check for and deal with this.
'
'These functions set the last error value (retrieved with the Windows API function GetLastError()). This
'lets you determine why the call failed, if you wish to. Note that it is usually enough to check the
'return value; these codes are provided mostly for debugging purposes. The following values
'may be returned by GetLastError():

Private Declare Function ArmCheckCode Lib "ArmAccess.dll" Alias "CheckCode" (ByVal Name As String, ByVal code As String) As Byte
Private Declare Function ArmVerifyKey Lib "ArmAccess.dll" Alias "VerifyKey" (ByVal Name As String, ByVal code As String) As Byte
Private Declare Function ArmInstallKey Lib "ArmAccess.dll" Alias "InstallKey" (ByVal Name As String, ByVal code As String) As Byte
Private Declare Function ArmInstallKeyLater Lib "ArmAccess.dll" Alias "InstallKeyLater" (ByVal Name As String, ByVal code As String) As Byte
Private Declare Function ArmUninstallKey Lib "ArmAccess.dll" Alias "UninstallKey" () As Byte
Private Declare Function ArmSetDefaultKey Lib "ArmAccess.dll" Alias "SetDefaultKey" () As Byte
Private Declare Function ArmUpdateEnvironment Lib "ArmAccess.dll" Alias "UpdateEnvironment" () As Byte
Private Declare Function ArmIncrementCounter Lib "ArmAccess.dll" Alias "IncrementCounter" () As Byte
Private Declare Function ArmCopiesRunning Lib "ArmAccess.dll" Alias "CopiesRunning" () As Long
Private Declare Function ArmChangeHardwareLock Lib "ArmAccess.dll" Alias "ChangeHardwareLock" () As Byte
Private Declare Function ArmGetShellProcessID Lib "ArmAccess.dll" Alias "GetShellProcessID" () As Long

Private Declare Function ArmFixClock Lib "ArmAccess.dll" Alias "FixClock" (ByVal FixClockKey$) As Byte
Private Declare Function ArmRawFingerprintInfo Lib "ArmAccess.dll" Alias "RawFingerprintInfo" (ByVal Item As Long) As Long
Private Declare Function ArmSetUserString Lib "ArmAccess.dll" Alias "SetUserString" (ByVal which As Long, ByVal Str$) As Byte
Private Declare Function ArmVBGetUserString Lib "ArmAccess.dll" Alias "VBGetUserString" (ByVal which As Long) As String
Private Declare Function ArmWriteHardwareChangeLog Lib "ArmAccess.dll" Alias "WriteHardwareChangeLog" (ByVal filename$) As Byte
Private Declare Function ArmConnectedToServer Lib "ArmAccess.dll" Alias "ConnectedToServer" () As Byte
Private Declare Function ArmCallBuyNowURL Lib "ArmAccess.dll" Alias "CallBuyNowURL" (ByVal ParentWindow As Long) As Byte
Private Declare Function ArmShowReminderMessage Lib "ArmAccess.dll" Alias "ShowReminderMessage" (ByVal ParentWindow As Long)
Private Declare Function ArmShowReminderMessage2 Lib "ArmAccess.dll" Alias "ShowReminderMessage2" (ByVal ParentWindow As Long)
Private Declare Function ArmShowEnterKeyDialog Lib "ArmAccess.dll" Alias "ShowEnterKeyDialog" (ByVal ParentWindow As Long) As Byte
Private Declare Function ArmExpireCurrentKey Lib "ArmAccess.dll" Alias "ExpireCurrentKey" () As Byte
Private Declare Function ArmEnviron Lib "ArmAccess.dll" Alias "Environ" (ByVal Name$) As String


' SetWindowPos Flags
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOZORDER = &H4
Private Const SWP_NOREDRAW = &H8
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_FRAMECHANGED = &H20        '  The frame changed: send WM_NCCALCSIZE
Private Const SWP_SHOWWINDOW = &H40
Private Const SWP_HIDEWINDOW = &H80
Private Const SWP_NOCOPYBITS = &H100
Private Const SWP_NOOWNERZORDER = &H200      '  Don't do owner Z ordering
Private Const SWP_DRAWFRAME = SWP_FRAMECHANGED
Private Const SWP_NOREPOSITION = SWP_NOOWNERZORDER

' SetWindowPos() hWndInsertAfter values
Private Const HWND_TOP = 0
Private Const HWND_BOTTOM = 1
Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2

Public Enum ArmadilloErrors
  ERROR_SUCCESS = 0
  ERROR_BAD_ENVIRONMENT = 10
  ERROR_INVALID_DATA = 13
  ERROR_BROKEN_PIPE = 109
  ERROR_BUSY = 170
  ERROR_ACCOUNT_RESTRICTION = 1327
  ERROR_ACCOUNT_DISABLED = 1331
  ERROR_LICENSE_QUOTA_EXCEEDED = 1395
  ERROR_ACCOUNT_EXPIRED = 1793
  ERROR_INVALID_DATATYPE = 1804
  ERROR_ACCOUNT_LOCKED_OUT = 1909
  ERROR_BAD_USERNAME = 2202
End Enum

Private Function ErrCodeToString(ByVal ErrCode As Long) As String
  On Error GoTo Hell
  Dim strTemp As String
 
  Select Case ErrCode
      Case ERROR_SUCCESS: strTemp = "Operation was completed successfully."
      Case ERROR_BAD_ENVIRONMENT: strTemp = "Can't establish communications with the Armadillo shell. This usually means that you haven't protected the program."
      Case ERROR_INVALID_DATA: strTemp = "There was an error in the communications path. You might be able to get it to work if you try the call a second time. If you receive this error again, it's probably unrecoverable."
      Case ERROR_BROKEN_PIPE: strTemp = "Could not open the communications path. This is probably an unrecoverable error."
      Case ERROR_BUSY: strTemp = "Returned only by the CopiesRunning function, if the network is too busy to get a response. Should almost never be seen in the real world."
      Case ERROR_ACCOUNT_RESTRICTION: strTemp = "The certificate has 'Limit Key Validity' set, and this key is either past the date it is allowed to be installed, or Armadillo has detected a problem with the system clock."
      Case ERROR_ACCOUNT_DISABLED: strTemp = "The key is an upgrade key, and the user does not have an existing upgradable key installed."
      Case ERROR_LICENSE_QUOTA_EXCEEDED: strTemp = "The key was successfully installed, but there are now more computers using this key than it is licensed for. Please see the discussion on the Limit Copies option for more information."
      Case ERROR_ACCOUNT_EXPIRED: strTemp = "The name/key you specified was valid at one time, but is now expired. It should not be considered a usable key."
      Case ERROR_INVALID_DATATYPE: strTemp = "The certificate in use is not expire-by-uses (IncrementCounter, or the key installed is not a hardware locked key (UninstallKey."
      Case ERROR_ACCOUNT_LOCKED_OUT: strTemp = "This key is listed in the Stolen Codes Database for the program."
      Case ERROR_BAD_USERNAME: strTemp = "The name/key you specified is not valid for this program."
      Case Else
          strTemp = FormatMessage(ErrCode) '//Assume it's from the Windows API
          Debug.Assert False
  End Select
 
  ErrCodeToString = strTemp

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.ErrCodeToString(ErrCode): " & ErrCode
End Function

Private Function FormatMessage(ByVal ErrNum As String) As String
  Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
      Dim strBuffer As String * 512, strMsg As String
      On Error GoTo ErrHandler
 
  FormatMessageAPI FORMAT_MESSAGE_FROM_SYSTEM, Null, ErrNum, 0, strBuffer, 512, 0
  strMsg = strBuffer
          'Strange but necessary manipulations
  strMsg = Replace(strMsg, vbNewLine, "")
  strMsg = Replace(strMsg, Chr(0), "")
  FormatMessage = strMsg
 
  Exit Function
ErrHandler:
      'Nothing to do...
End Function

Public Function GetEnvironString(Name As String) As String
  On Error GoTo Hell
  'Define a string for the return value
  Dim ReturnString As String

  'First, pad the return value string so that it's big enough.
  ReturnString = Space$(256)

  'Now call the GetEnvironmentVariable function. If the function indicates
  'that the variable doesn't exist, return an empty string. Otherwise,
  'return the contents of the variable.
  If GetEnvironmentVariable(Name, ReturnString, 256) <> 0 Then
      GetEnvironString = Trim$(StripNulls(ReturnString))
  Else
      GetEnvironString = ""
  End If

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.GetEnvironString(Name): " & Name
End Function

Public Function hWndLoading() As Long
  On Error GoTo Hell
  Dim strTemp As String

  'LOADINGWINDOW: If you use a custom bitmap loading window, this variable holds the
  'handle of this window, in hexadecimal format. You can use this handle to close or
  'hide the loading window when your program starts up, if you don't wish to rely on Armadillo's timer.
 
  'You could also issue a WM_CLOSE to the Window, but I thought it to be safer to leave the hWnd valid
  'for Armadillo to close the Window when the timer expires.
 
  'You should call this method when the main window of your application is fully loaded to remove the
  'loading window if you are using it as the Splash screen of your application.
 
  strTemp = GetEnvironString("LOADINGWINDOW")
  If Len(strTemp) > 0 Then
      hWndLoading = CLng("&H" & strTemp)
  End If

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.hWndLoading(strTemp)"
End Function

Public Sub HideLoadingWindow()
  On Error GoTo Hell
  Dim hwnd As Long
  Dim strTemp As String

  'LOADINGWINDOW: If you use a custom bitmap loading window, this variable holds the
  'handle of this window, in hexadecimal format. You can use this handle to close or
  'hide the loading window when your program starts up, if you don't wish to rely on Armadillo's timer.
 
  'You could also issue a WM_CLOSE to the Window, but I thought it to be safer to leave the hWnd valid
  'for Armadillo to close the Window when the timer expires.
 
  'You should call this method when the main window of your application is fully loaded to remove the
  'loading window if you are using it as the Splash screen of your application.
 
  hwnd = Me.hWndLoading
  If hwnd <> 0 Then
      SetWindowPos hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER Or SWP_NOSIZE Or SWP_NOMOVE Or SWP_HIDEWINDOW
  End If

Exit_Proc:
  Exit Sub

Hell:
  ErrorIn "clsArmadillo.HideLoadingWindow(hwnd)"
End Sub

Public Sub ShowRegisterScreen()
   On Error GoTo Hell

Dim nResult As Byte

nResult = ArmShowEnterKeyDialog(0)

If nResult <> 0 Then
' Successful registration.
Else
' Registration failed
End If

Exit_Proc:
   Exit Sub

Hell:
   ErrorIn "clsArmadillo.Register"
End Sub

Public Function GetUserString(which As Integer) As String
   On Error GoTo Hell
   If which < 0 Or which > 7 Then Exit Function
   GetUserString = ArmVBGetUserString(which)
Exit_Proc:
   Exit Function

Hell:
   ErrorIn "clsArmadillo.GetUserString"

End Function

Public Function SetUserString(which As Integer, ByVal what As String) As Boolean
   On Error GoTo Hell
   If which < 0 Or which > 7 Then Exit Function

   SetUserString = CBool(ArmSetUserString(which, Left(what, 255) + ""))
Exit_Proc:
   Exit Function

Hell:
   ErrorIn "clsArmadillo.SetUserString"

End Function

Public Sub ShowRegInfo()
  On Error GoTo Hell

  Dim strTemp As String
 
 
  strTemp = GetEnvironString("PROTECTEDFILE")
  If Len(strTemp) > 0 Then
      Shell strTemp & " INFO", vbNormalFocus
  Else
      GoTo Hell
  End If
 
Exit_Proc:
  Exit Sub

Hell:
  ErrorIn "clsArmadillo.ShowRegInfo"
End Sub

Public Property Get HardwareFingerPrint(Optional ByVal Enhanced As Boolean = False) As String
  On Error GoTo Hell
  'ENHFINGERPRINT: Similar to the FINGERPRINT variable documented below, this
  'one holds the enhanced hardware-locking fingerprint, for certificates that use enhanced hardware locking.

  'FINGERPRINT: This variable appears only if your program includes at least one
  'hardware-locked certificate. It contains the eight-digit hexadecimal
  '"machine fingerprint" of the computer your program is currently running
  'on, which is necessary to make a hardware-locked key.
 
  If Enhanced Then
      HardwareFingerPrint = GetEnvironString("ENHFINGERPRINT")
  Else
      HardwareFingerPrint = GetEnvironString("FINGERPRINT")
  End If

Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.HardwareFingerPrint(Enhanced)"
End Property

Public Property Get IsRegistered() As Boolean
  On Error GoTo Hell
  '//ASSUMES: when the 'Default' certificate is installed, the software is UNregistered.
  '//When any other certificate is installed, the software is registered.
 
#If INTERNAL_BUILD Then
  IsRegistered = True
  Exit Property
#End If
 
   If LenB(Me.UserName) = 0 Then
   IsRegistered = False
   ElseIf Me.UserName = "Trial Version" Then
   IsRegistered = False
   Else
   IsRegistered = True
   End If
 
 
  'IsRegistered = CBool(Len(Me.UserName) > 0)
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.IsRegistered"
End Property
 
Public Property Get IsRegisteredEx(ByVal ExtraInfoMatch As Integer) As Boolean
  On Error GoTo Hell
  '//Returns TRUE only if the product is REGISTERED, and if the stored ExtraInfo
  '//matches the ExtraInfo passed into the method.

#If INTERNAL_BUILD Then
  IsRegisteredEx = True
  Exit Property
#End If
 
  If Me.IsRegistered Then
      IsRegisteredEx = CBool(Me.ExtraInfo = ExtraInfoMatch)
  End If

Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.IsRegisteredEx"
End Property


Private Function StripNulls(OriginalStr As String) As String
  On Error GoTo Hell

' Strips any trailing nulls from path names retrieved
' from the registry. This function is found in the
' following Microsoft(r) knowledge base articles:
' Q183009 "HOWTO: Enumerate Windows Using the WIN32 API"
' Q185476 "HOWTO: Search Directories to Find or List Files"
' Q190218 "HOWTO: Retrieve Settings From a Printer Driver"

If (InStr(OriginalStr, Chr(0)) > 0) Then
  OriginalStr = Left(OriginalStr, _
      InStr(OriginalStr, Chr(0)) - 1)
End If

StripNulls = OriginalStr

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.StripNulls(OriginalStr)"
End Function


Public Property Get UserName() As String
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'USERNAME: This is the name on the user's key, or DEFAULT if they're using the default certificate.
  'Note that this string is used by some other programs; for compatibility, the user's name is also
  'stored in the ALTUSERNAME string. Note: If the registry information is somehow corrupted, and
  'you were using an older version of Armadillo before, then the user's name may be lost. In this case,
  'it will appear as the string "MISSING" (without the quotes) instead. All other information, including
  'the number of days or uses remaining, will remain.
 
 
  strTemp = Trim$(GetEnvironString("ALTUSERNAME"))
  If UCase(strTemp) = "DEFAULT" Then strTemp = ""
  If IsInIDE And Len(strTemp) = 0 Then strTemp = "Program Author"
  If Len(strTemp) > 0 Then
      UserName = strTemp
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.UserName"
End Property


Public Property Get DaysInstalled() As Long
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'DAYSINSTALLED: This variable contains the number of days since the current key was
  'installed. On the day of installation, it is zero.
 
  strTemp = GetEnvironString("DAYSINSTALLED")
  If Len(strTemp) > 0 Then
      DaysInstalled = CLng(strTemp)
  Else
      DaysInstalled = 0
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.DaysInstalled"
End Property

Public Property Get ExtraInfo() As Integer
  On Error GoTo Hell
  Dim strTemp As String
 
  'EXTRAINFO: Any "extra information" you have stored in the key is stored in this
  'variable, in decimal format. If the certificate uses the extra bits for another
  'purpose, such as storing expiration information in the key, then this variable will contain a zero.
 
  strTemp = GetEnvironString("EXTRAINFO")
  If Len(strTemp) > 0 Then
      ExtraInfo = CInt(strTemp)
  Else
      ExtraInfo = 0
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.ExtraInfo"
End Property

Public Property Get KeyCreated() As String
  On Error GoTo Hell
  Dim strTemp As String
 
  'KEYCREATED: This contains the date, in the form "YYYY.MM.DD", that the user's key was created on.
  'It is not set for the default key.
 
  KeyCreated = GetEnvironString("KEYCREATED")
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.KeyCreated"
End Property

Public Property Get UserKey() As String
  On Error GoTo Hell
  Dim strTemp As String
 
  'USERKEY: This is the key that the program is currently running under. It is not set for
  'the default key, and should not be trusted for expire-by-uses keys entered before version 1.73.

  UserKey = GetEnvironString("USERKEY")
  If IsInIDE And Len(UserKey) = 0 Then UserKey = "Development"
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.UserKey"
End Property

Public Property Get DaysLeft() As Long
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'DAYSLEFT: For date- and day-limited certificates, this is set to the number of valid
  'days left on the key. When this is set to 1, the key will expire at midnight.
 
  strTemp = GetEnvironString("DAYSLEFT")
  If Len(strTemp) > 0 Then
      DaysLeft = CLng(strTemp)
  Else
      DaysLeft = 0
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.DaysLeft"
End Property

Public Property Get Emulator() As String
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'Emulator - Shows if it is running in a virtual PC
 
  strTemp = GetEnvironString("EMULATOR")
  If Len(strTemp) > 0 Then
      Emulator = strTemp
  Else
      Emulator = ""
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.Emulator"
End Property

Public Property Get CommandLine() As String
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'The Program's command line
 
  strTemp = GetEnvironString("COMMANDLINE")
  If Len(strTemp) > 0 Then
      CommandLine = strTemp
  Else
      CommandLine = ""
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.CommandLine"
End Property

Public Property Get TotalUsesAllKeys() As Long
  On Error GoTo Hell
  Dim strTemp As String
 
  strTemp = GetEnvironString("TOTALUSESALLKEYS")
  If Len(strTemp) > 0 Then
      TotalUsesAllKeys = CLng(strTemp)
  Else
      TotalUsesAllKeys = 0
  End If
 
Exit_Proc:
  Exit Property

Hell:
      TotalUsesAllKeys = 0
End Property


Public Property Get CopiesAllowed() As Long
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'COPIESALLOWED: If your program uses the Limit Copies feature, this variable is set to the
  'number of copies permitted for the current certificate and key.
 
  strTemp = GetEnvironString("COPIESALLOWED")
  If Len(strTemp) > 0 Then
      CopiesAllowed = CLng(strTemp)
  Else
      CopiesAllowed = 0
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.CopiesAllowed"
End Property

Public Property Get DaysInstalledBit(ByVal BitNumber As Byte) As Boolean
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'DAYSINSTALLEDBITx: This is actually fifteen different variables, DAYSINSTALLEDBIT1 through DAYSINSTALLEDBIT15.
  'They contain the number of days since the corresponding "extra information" bit was last changed,
  'and can be used with Modification Keys to set up a trial period for separate modules in your program.
 
  strTemp = GetEnvironString("DAYSINSTALLEDBIT" & CStr(BitNumber))
  If Len(strTemp) > 0 Then
      DaysInstalledBit = CBool(strTemp)
  Else
      DaysInstalledBit = False
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.DaysInstalledBit(BitNumber)"
End Property

Public Property Get Expired() As Boolean
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'EXPIRED: This variable is set only if you've chosen the "don't show expiration message"
  '(on the Expire window) and the certificate has expired. Armadillo will let the program run
  'after expiration if that box is checked, the program itself must check for this variable.
 
  strTemp = GetEnvironString("EXPIRED")
  If Len(strTemp) > 0 Then
      Expired = CBool(strTemp)
  Else
      Expired = False
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.Expired"
End Property

Public Property Get ExpiredVersion() As String
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'EXPIREVER: For the expire-by-version certificates, this tells you what version the key will expire on.
 
  strTemp = GetEnvironString("EXPIREVER")
  If Len(strTemp) > 0 Then
      ExpiredVersion = strTemp
  Else
      ExpiredVersion = ""
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.ExpiredVersion"
End Property

Public Property Get KeyString() As String
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'KeyString: Return a string embedded into the reg key.
 
  strTemp = GetEnvironString("KEYSTRING")
  If Len(strTemp) > 0 Then
      KeyString = strTemp
  Else
      KeyString = ""
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.keystring"
End Property

Public Property Get UsesLeft() As Long
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'USESLEFT: For certificates offering a limited number-of-uses, this is set to the number
  'of uses remaining. If the user is on the last use, this is set to 1.
 
  strTemp = GetEnvironString("USESLEFT")
  If Len(strTemp) > 0 Then
      UsesLeft = CLng(strTemp)
  Else
      UsesLeft = 0
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.UsesLeft"
End Property

Public Property Get UsesLeftAfter() As Long
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'USESLEFT: For certificates offering a limited number-of-uses, this is set to the number
  'of uses remaining. If the user is on the last use, this is set to 1.
 
  strTemp = GetEnvironString("USESLEFTAFTER")
  If Len(strTemp) > 0 Then
      UsesLeftAfter = CLng(strTemp)
  Else
      UsesLeftAfter = 0
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.UsesLeftAfter"
End Property


Public Property Get ClockBack() As Boolean
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'CLOCKBACK: If you have chosen to disable Armadillo's clock-back checking
  '(by way of the Don't Report Clock-Back on the Project window), this variable
  'will be set when Armadillo detects a problem with an incorrect system clock.
 
  strTemp = GetEnvironString("CLOCKBACK")
  If Len(strTemp) > 0 Then
      ClockBack = CBool(strTemp)
  Else
      ClockBack = False
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.ClockBack"
End Property

Public Property Get InvalidKey() As Boolean
  On Error GoTo Hell
  Dim strTemp As String
 
 
  'INVALIDKEY: This variable is only used if you have the Auto-revert on invalid key
  'option set, and the key stored on a user's system is invalid (probably because you've
  'changed an encryption template). It is only set during the first such run; after that,
  'the user will be automatically reset to the default certificate, if any. This is
  'intended to let your program gracefully warn the user of the change.
 
  strTemp = GetEnvironString("INVALIDKEY")
  If Len(strTemp) > 0 Then
      InvalidKey = CBool(strTemp)
  Else
      InvalidKey = False
  End If
 
Exit_Proc:
  Exit Property

Hell:
  ErrorIn "clsArmadillo.InvalidKey"
End Property


'Do It Yourself: Integrating Armadillo With Your Programs Using ArmAccess.DLL
'You have the option of bypassing all of Armadillo's screens and replacing them with your own if you wish
'by using the included ArmAccess.DLL file.

'What it does
'ArmAccess.DLL (which you can distribute with your programs free of charge) is a small dynamic-link
'library which hooks into the Armadillo shell around your program, allowing you two-way communication
'with it. This lets you create your own registration dialogs instead of using Armadillo's default
'"register" screen, among other things.

'The Functions
'ArmAccess.DLL exports several functions. Most of them return non-zero (a Boolean 'true' in C) on success,
'or zero if there is an error or they cannot carry out the requested function for some reason.

Public Function InstallKey(ByVal Name As String, ByVal Key As String, Optional ByVal InstallOnExit As Boolean = False) As Boolean
  'On Error GoTo Hell
  'CheckCode: Checks a name/key pair, and (if valid) stores it as the new key. Returns non-zero if the code is valid.
  'InstallKey: This is identical to CheckCode. You can use either name.
  'InstallKeyLater: This function, like VerifyKey (below), checks whether a key is good and returns non-zero
  '(and sets environment variables) if it is. It doesn't install the key until that copy of the program exits though.
   
  If InstallOnExit Then
      InstallKey = CBool(ArmInstallKeyLater(Name, Key))
  Else
      InstallKey = CBool(ArmInstallKey(Name, Key))
  End If

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.InstallKey(Name,Key,InstallOnExit)"
End Function

Public Function LastErrorS() As String
  On Error GoTo Hell
  LastErrorS = ErrCodeToString(Err.LastDllError)

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.LastErrorS"
End Function

Public Function UninstallKey() As String
  On Error GoTo Hell
  'UninstallKey: Securely uninstalls a hardware-locked key, and change the hardware "fingerprint"
  'so that it can't be reinstalled. It also gives you an uninstall code (in the otherwise-undocumented
  'environment variable UNINSTALLCODE), so that you can manually verify that the key has been uninstalled.
 
  '//This function uninstalls the license and returns the uninstallcode
  If CBool(ArmUninstallKey) Then
      UninstallKey = GetEnvironString("UNINSTALLCODE")
  End If

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.UninstallKey"
End Function

Public Function CheckCode(ByVal Name As String, ByVal Key As String, Optional ByVal UpdateEnvironment As Boolean = False) As Boolean
  On Error GoTo Hell
  'VerifyKey: This function is similar to CheckCode/InstallKey. It checks a name/key pair,
  'returning non-zero if it's valid and could be installed. However, unlike CheckCode/InstallKey,
  'it does not install the key; the original key remains installed. After calling VerifyKey,
  'the environment variables are set as if the key were installed; to recover the environment
  'variables for the original key, call UpdateEnvironment.
 
  If CBool(ArmCheckCode(Name, Key)) Then
      CheckCode = True
      If UpdateEnvironment Then
          '//Do nothing.  This happens automatically.
      Else
          '//Restore the environment back the way that it was, if the user didn't
          '//intend to update the environment.
          ArmUpdateEnvironment
      End If
  Else
      CheckCode = False
  End If


Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.CheckCode(Name,Key,UpdateEnvironment)"
       
End Function

Public Function RestoreDefaultKey() As Boolean
  On Error GoTo Hell
  'SetDefaultKey: Calling this function will force the Armadillo shell to revert to the default
  'certificate (if any) for your program.
  RestoreDefaultKey = CBool(ArmSetDefaultKey)

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.RestoreDefaultKey"
End Function

Public Function FixClock(ByVal FixClockKey As String) As Boolean
  On Error GoTo Hell
  ' Repairs a program when they muck around with the clock
  FixClock = CBool(ArmFixClock(FixClockKey))

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.FixClockKey"
End Function

Public Function WriteHardwareChangeLog(ByVal filename As String) As Boolean
  On Error GoTo Hell
  ' Create the Hardware Change Log
  WriteHardwareChangeLog = CBool(ArmWriteHardwareChangeLog(filename))

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.FixClockKey"
End Function

Public Sub CallBuyNowURL()
  On Error GoTo Hell
  ' Show the Buy Now URL
  ArmCallBuyNowURL (0)

Exit_Proc:
  Exit Sub

Hell:
  ErrorIn "clsArmadillo.CallBuyNowURL"
End Sub

Public Sub ShowReminderMessage()
  On Error GoTo Hell
  ' Show the Reminder Message
  ArmShowReminderMessage (0)
Exit_Proc:
  Exit Sub
Hell:
  ErrorIn "clsArmadillo.ShowReminderMessage"
End Sub

Public Sub ShowReminderMessage2()
  On Error GoTo Hell
  ' Show the Reminder Message 2
  ArmShowReminderMessage2 (0)
Exit_Proc:
  Exit Sub
Hell:
  ErrorIn "clsArmadillo.ShowReminderMessage2"
End Sub

Public Sub ShowEnterKeyDialog()
  On Error GoTo Hell
  ' Show the Enter Username and Key Dialog
  ArmShowEnterKeyDialog (0)
Exit_Proc:
  Exit Sub
Hell:
  ErrorIn "clsArmadillo.ShowEnterKeyDialog"
End Sub

Public Sub ExpireCurrentKey()
  On Error GoTo Hell
  ' Reset to the Default Key
  ArmExpireCurrentKey
Exit_Proc:
  Exit Sub
Hell:
  ErrorIn "clsArmadillo.ExpireCurrentKey"
End Sub

Public Function UpdateEnvironment() As Boolean
  On Error GoTo Hell
  'UpdateEnvironment: You can call this function to have Armadillo update the environment strings it sets.
  'This is intended for programs that are often left running for days at a time, and lets you check
  'whether the current key is still valid.
  UpdateEnvironment = CBool(ArmUpdateEnvironment)

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.UpdateEnvironment"
End Function

Public Function IncrementCounter() As Boolean
  On Error GoTo Hell
  'IncrementCounter: This function allows you to control the "usage count" of an Armadillo
  'expire-by-uses certificate. Every time it's called, it increases the usage count by one
  'and updates the environment. If you're using this function to count uses, and don't
  'want Armadillo to automatically increment the counter when the program starts, then set
  'the certificate to expire "After number of uses (counted by DLL)".
  IncrementCounter = CBool(ArmIncrementCounter)

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.IncrementCounter"
End Function

Public Function CopiesRunning() As Long
  On Error GoTo Hell
  'CopiesRunning: Mainly used with network licenses, this function returns the number of copies running
  'on the network at the time it is called (including the calling copy). Returns zero if there is an error.
  'Note that this function only reports the number of copies that are using the same key as the one
  'that makes the request.
  CopiesRunning = ArmCopiesRunning

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.CopiesRunning"
End Function

Public Function ChangeHardwareLock() As Boolean
  On Error GoTo Hell
  'ChangeHardwareLock: Used only with hardware-locked keys, this function randomly changes the
  'hardware "fingerprint" for a machine, just as if the TRANSFER command were used.
  ChangeHardwareLock = CBool(ArmChangeHardwareLock)

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.ChangeHardwareLock"
End Function

Public Function PID() As Long
  On Error GoTo Hell
  'GetShellProcessID: Returns the Process ID of the Armadillo shell around your program,
  'for some web-update programs and other advanced usage.
  PID = ArmGetShellProcessID

Exit_Proc:
  Exit Function

Hell:
  ErrorIn "clsArmadillo.PID"
End Function


Private Function ErrorIn(functionName As String) As Boolean
   MsgBox "An unhandled exception has occured." & vbCrLf & _
       "This software will exit after this message is displayed." & vbCrLf & _
       "Please contact technical support." & vbCrLf & _
       "Module.Function: " & functionName, vbCritical, "Error Message"
Exit Function
       Dim frm As Form, ctl As Control, obj As Object
quitprogram:
   On Error Resume Next
   For Each frm In Forms
       For Each ctl In frm.Controls
           Set ctl = Nothing
       Next ctl
       For Each obj In frm.Objects
           Set obj = Nothing
       Next obj
       Unload frm
       Set frm = Nothing
   Next frm
   End
End Function


Private Function DoIDECheck() As Boolean

'this will only be called in we are running inside the IDE
m_bInIDE = True
DoIDECheck = True


End Function

Private Function IsInIDE() As Boolean


'are we running inside the VB IDE ?
Debug.Assert (DoIDECheck())
IsInIDE = m_bInIDE

End Function
GaryG
I'm not sure if it's a good idea to use "plain text" strings in your error handlers (for example, "ErrorIn "clsArmadillo.GetEnvironString(Name): " & Name").

Those strings may clue the hackers in to what your code is doing, and since they already know what Armadillo is, I think this represents a potential security issue.

I have intentionally disguised all the strings in my error handling/logging code related to Armadillo - no need to help the hackers.

Does this sound reasonable Chad?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2012 Invision Power Services, Inc.