[ActiveLock-Development] CVS: activelock/src ActiveLock.cls,1.8,1.9 ActiveLock2.vbp,1.5,1.6 ActiveLo
Brought to you by:
ialkan
From: Thanh H. T. <th...@us...> - 2004-04-18 01:50:56
|
Update of /cvsroot/activelock/activelock/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28263 Modified Files: ActiveLock.cls ActiveLock2.vbp ActiveLockEventNotifier.cls FileKeyStore.cls Globals.cls IActiveLock.cls modActiveLock.bas ProductLicense.cls Log Message: Batch commit for 2.0.5--see individual module change logs for details Index: ActiveLock.cls =================================================================== RCS file: /cvsroot/activelock/activelock/src/ActiveLock.cls,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- ActiveLock.cls 4 Nov 2003 07:41:19 -0000 1.8 +++ ActiveLock.cls 18 Apr 2004 01:50:46 -0000 1.9 @@ -13,7 +13,7 @@ Attribute VB_Exposed = False '* ActiveLock '* Copyright 1998-2002 Nelson Ferraz -'* Copyright 2003 The ActiveLock Software Group (ASG) +'* Copyright 2003-2004 The ActiveLock Software Group (ASG) '* All material is the property of the contributing authors. '* '* Redistribution and use in source and binary forms, with or without @@ -84,6 +84,17 @@ ' hashing an empty string. ' 11.02.03 - th2tran - alcrypto.dll now resides in the Windows System directory ' - IActiveLock_Transfer raise alerrNotImplemented error until we get this implemented +' 02.24.04 - th2tran - Fixed bug: mismatched logic between IActiveLock.LockCode() and ALUGENLib.Generator#GenKey() +' implementations caused the key validation process to fail for keys generated +' from blank LockCode. +' 02.25.04 - th2tran - Changed IActiveLock_Register() not to validate the license (leave this task to IActiveLock_Acquire()). +' This allows ALUGEN to use this method to save the generated license key to the license file. +' Potentially, with this approach we can do away with handing liberation keys to the users. +' Instead, we would be handing them a license file to plop into their application directory...a much simplier +' process than manually registering the liberation key. +' 04.17.04 - th2tran - Rolled back changes from 02.25.04. The above implementation smalll breached in security: +' User can blank out the LastUsed property, set their clock back and continue to use an otherwise-expired +' license. ' </pre> ' /////////////////////////////////////////////////////////////////////// @@ -105,6 +116,8 @@ Private MyNotifier As New ActiveLockEventNotifier Private MyGlobals As New Globals +Private mLibKeyPath As String + ' Registry hive used to store Active Lock settings. Private Const AL_REGISTRY_HIVE$ = "Software\ActiveLock Software Group\ActiveLock2" @@ -116,18 +129,25 @@ ''' ' IActiveLock Interface implementations '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +Private Property Let IActiveLock_AutoRegisterKeyPath(ByVal RHS As String) + mLibKeyPath = RHS +End Property +Private Property Get AutoRegisterKeyPath() As String + AutoRegisterKeyPath = mLibKeyPath +End Property + Private Property Get IActiveLock_EventNotifier() As ActiveLockEventNotifier Set IActiveLock_EventNotifier = MyNotifier End Property -Private Sub IActiveLock_Init(Arg1 As Variant, ParamArray OtherArgs() As Variant) +Private Sub IActiveLock_Init() ' If running in Debug mode, don't bother with dll authentication #If AL_DEBUG = 1 Then GoTo Done #End If ' Checksum ALCrypto.dll - Const ALCRYPTO_MD5$ = "1941fefd79fed9403e24f3d7fd76ae13" + Const ALCRYPTO_MD5$ = "be299ad0f52858fdd9ea3626468dc05c" Dim strdata As String, strMD5 As String Call modActiveLock.ReadFile(WinSysDir() & "\alcrypto.dll", strdata) strMD5 = modMD5.Hash(strdata) ' use our own MD5 hashing routine instead of ALCrypto's md5_hash() function. @@ -135,10 +155,34 @@ If strMD5 <> ALCRYPTO_MD5 Then Err.Raise ActiveLockErrCodeConstants.alerrFileTampered, "IActiveLock_Acquire", "alcrypto.dll has been tampered." End If + ' Perform automatic license registration + If AutoRegisterKeyPath <> "" Then DoAutoRegistration Done: mfInit = True End Sub +'' +' Check the specified path to see if +Private Sub DoAutoRegistration() + ' Don't bother to proceed unless the file is there. + If Not FileExists(AutoRegisterKeyPath) Then Exit Sub + + Dim strLibKey As String + ReadLibKey AutoRegisterKeyPath, strLibKey + IActiveLock_Register strLibKey + ' If registration is successful, delete the liberation file so we won't register the same file on next startup + Kill AutoRegisterKeyPath +End Sub +Private Sub ReadLibKey(ByVal sFileName As String, ByRef strLibKey As String) + Dim hFile As Long + hFile = FreeFile + Open sFileName For Input As #hFile + On Error GoTo Finally + strLibKey = Input$(LOF(hFile), hFile) +Finally: + Close #hFile +End Sub + Private Sub IActiveLock_Acquire() If mKeyStore Is Nothing Then Err.Raise ActiveLockErrCodeConstants.alerrKeyStoreInvalid, "IActiveLock_Acquire", "Key Store Provider hasn't been initialized yet." @@ -188,13 +232,15 @@ Dim Key As RSAKey Dim strPubKey As String strPubKey = mSoftwareCode + Dim strSig As String Dim strLic As String Dim strLicKey As String strLic = IActiveLock_LockCode(Lic) strLicKey = Lic.LicenseKey - + + ' decode the license key strSig = MyGlobals.Base64Decode(strLicKey) ' Print out some info for debugging purposes @@ -278,14 +324,14 @@ ' TODO: Implement Me! End Sub -Private Property Let IActiveLock_KeyStorePath(RHS As String) +Private Property Let IActiveLock_KeyStorePath(ByVal RHS As String) If Not mKeyStore Is Nothing Then mKeyStore.KeyStorePath = RHS End If mKeyStorePath = RHS End Property -Private Property Let IActiveLock_KeyStoreType(RHS As LicStoreType) +Private Property Let IActiveLock_KeyStoreType(ByVal RHS As LicStoreType) ' Instantiate Key Store Provider If RHS = alsFile Then Set mKeyStore = New FileKeyStoreProvider @@ -298,7 +344,7 @@ End If End Property -Private Property Let IActiveLock_LockType(RHS As ALLockTypes) +Private Property Let IActiveLock_LockType(ByVal RHS As ALLockTypes) mLockTypes = RHS End Property Private Property Get IActiveLock_LockType() As ALLockTypes @@ -332,7 +378,7 @@ RandomNumber = CStr(CLng(Rnd(1) * 2147483647)) End Function -Private Property Let IActiveLock_SoftwareName(RHS As String) +Private Property Let IActiveLock_SoftwareName(ByVal RHS As String) mSoftwareName = RHS End Property Private Property Get IActiveLock_SoftwareName() As String @@ -373,12 +419,13 @@ If Left(strLock, 1) = vbLf Then strLock = Mid(strLock, 2) + ' Append lockcode. + ' Note: The logic here must match the corresponding logic + ' in ALUGENLib.Generator#GenKey() If Lic Is Nothing Then IActiveLock_LockCode = strLock - ElseIf strLock <> "" Then - IActiveLock_LockCode = Lic.ToString() & vbLf & strLock Else - IActiveLock_LockCode = Lic.ToString() + IActiveLock_LockCode = Lic.ToString() & vbLf & strLock End If End Function @@ -390,20 +437,20 @@ End If End Sub -Private Property Let IActiveLock_SoftwareVersion(RHS As String) +Private Property Let IActiveLock_SoftwareVersion(ByVal RHS As String) mSoftwareVer = RHS End Property Private Property Get IActiveLock_SoftwareVersion() As String IActiveLock_SoftwareVersion = mSoftwareVer End Property -Private Property Let IActiveLock_SoftwareCode(RHS As String) +Private Property Let IActiveLock_SoftwareCode(ByVal RHS As String) ' SoftwareCode is an RSA public key. This code will be used to verify license keys later on. mSoftwareCode = RHS End Property -Private Function IActiveLock_Transfer(OtherSoftwareCode As String) As String +Private Function IActiveLock_Transfer(ByVal OtherSoftwareCode As String) As String ' TODO: Implement me! Err.Raise ActiveLockErrCodeConstants.alerrNotImplemented, "IActiveLock_Transfer", "Operation not implemented" End Function Index: ActiveLock2.vbp =================================================================== RCS file: /cvsroot/activelock/activelock/src/ActiveLock2.vbp,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- ActiveLock2.vbp 3 Nov 2003 06:31:47 -0000 1.5 +++ ActiveLock2.vbp 18 Apr 2004 01:50:46 -0000 1.6 @@ -32,11 +32,11 @@ VersionCompatible32="1" MajorVer=2 MinorVer=0 -RevisionVer=4 +RevisionVer=5 AutoIncrementVer=0 ServerSupportFiles=0 VersionCompanyName="The ActiveLock Software Group" -VersionLegalCopyright="Copyright © 2003" +VersionLegalCopyright="Copyright © 2003-2004" VersionProductName="ActiveLock" CompilationType=0 OptimizationType=0 Index: ActiveLockEventNotifier.cls =================================================================== RCS file: /cvsroot/activelock/activelock/src/ActiveLockEventNotifier.cls,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- ActiveLockEventNotifier.cls 13 Oct 2003 04:49:03 -0000 1.2 +++ ActiveLockEventNotifier.cls 18 Apr 2004 01:50:46 -0000 1.3 @@ -92,7 +92,7 @@ ' @param Value Property value. Public Event ValidateValue(ByRef Value As String) -Friend Sub Notify(EventName As String, ParamArray Args()) +Friend Sub Notify(ByVal EventName As String, ParamArray Args()) If EventName = "ValidateValue" Then Dim Result As String Result = Args(0) Index: FileKeyStore.cls =================================================================== RCS file: /cvsroot/activelock/activelock/src/FileKeyStore.cls,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- FileKeyStore.cls 3 Nov 2003 06:30:42 -0000 1.2 +++ FileKeyStore.cls 18 Apr 2004 01:50:46 -0000 1.3 @@ -62,8 +62,11 @@ ' ' 07.07.03 - mcrute - Updated the header comments for this file. ' 11.02.03 - th2tran - Handle loading and saving of new MaxCount property +' 04.17.04 - th2tran - Don't save the product key to the license file. +' - Now creates an empty license file if it doesn't exist, +' instead of raising alerrKeyStoreInvalid error. ' -' + ' /////////////////////////////////////////////////////////////////////// ' / MODULE CODE BEGINS BELOW THIS LINE / ' /////////////////////////////////////////////////////////////////////// @@ -93,18 +96,26 @@ Private Property Let IKeyStoreProvider_KeyStorePath(RHS As String) If Not FileExists(RHS) Then - Err.Raise alerrKeyStoreInvalid, , "License file '" & RHS & "' not found." + ' Create an empty file if it doesn't exists + CreateEmptyFile RHS + 'Err.Raise alerrKeyStoreInvalid, , "License file '" & RHS & "' not found." End If mstrPath = RHS mIniFile.File = mstrPath End Property +Private Sub CreateEmptyFile(ByVal sFilePath As String) + Dim hFile As Long + hFile = FreeFile + Open sFilePath For Output As #hFile + Close #hFile +End Sub + Private Sub IKeyStoreProvider_Store(Lic As ProductLicense) ' Write license properties to INI file section ' TODO: Perhaps we need to lock the file first.? mIniFile.Section = Lic.ProductName With Lic - mIniFile.Values(KEY_PRODKEY) = .ProductKey mIniFile.Values(KEY_PRODVER) = .ProductVer mIniFile.Values(KEY_LICTYPE) = .LicenseType mIniFile.Values(KEY_LICCLASS) = .LicenseClass @@ -115,8 +126,6 @@ mIniFile.Values(KEY_LASTRUN_DATE) = .LastUsed mIniFile.Values(KEY_LASTRUN_DATE_HASH) = .Hash1 mIniFile.Values(KEY_EXP) = .Expiration - - End With End Sub @@ -139,7 +148,6 @@ With Lic .ProductName = ProductName .ProductVer = mIniFile.GetValue(KEY_PRODVER) - .ProductKey = mIniFile.GetValue(KEY_PRODKEY) .Licensee = mIniFile.GetValue(KEY_LICENSEE) .MaxCount = CLng(mIniFile.Values(KEY_MAXCOUNT)) .LicenseType = mIniFile.GetValue(KEY_LICTYPE) @@ -155,14 +163,3 @@ InvalidValue: Err.Raise alerrKeyStoreInvalid, "ActiveLock2.FileKeyStoreProvider", "A license property contains an invalid value." End Function - - -'' -' Determines if a file exists. -' -Private Function FileExists(FilePath As String) As Boolean - If Len(FilePath) > 0 Then - FileExists = (Len(Dir$(FilePath)) > 0) - End If -End Function - Index: Globals.cls =================================================================== RCS file: /cvsroot/activelock/activelock/src/Globals.cls,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- Globals.cls 4 Nov 2003 07:41:19 -0000 1.4 +++ Globals.cls 18 Apr 2004 01:50:46 -0000 1.5 @@ -75,6 +75,8 @@ ' 10.13.03 - th2tran - Corrections to ActiveLockErrCodeConstants vbdox errors. ' - Added VB descriptions for VB Object Browser's sake. ' 11.02.03 - th2tran - Added ActiveLockErrCodeConstants.alerrNotImplemented +' 04.17.04 - th2tran - NewInstance() no longer calls Init(). Callers will have to +' init the instance themselves. ' </pre> ' /////////////////////////////////////////////////////////////////////// ' / MODULE CODE BEGINS BELOW THIS LINE / @@ -110,17 +112,14 @@ '' ' Obtains a new instance of an object that implements IActiveLock interface. -' @param Args Optional list of parameters. +' As of 2.0.5, this method will no longer initialize the instance automatically. +' Callers will have to call Init() by themselves subsequent to obtaining the instance. ' @return ActiveLock interface. ' -Public Function NewInstance(Optional Args As Variant) As IActiveLock 'TODO: Add parameters as appropriate +Public Function NewInstance() As IActiveLock Attribute NewInstance.VB_Description = "Returns a new instance of an object that implements IActiveLock interface." Dim NewInst As IActiveLock Set NewInst = New ActiveLock - With NewInst - ' Initialize properties ..... - .Init Args - End With Set NewInstance = NewInst End Function @@ -141,7 +140,7 @@ ' @param MaxUsers Maximum number of users allowed to use this license ' ' @return License object. -Public Function CreateProductLicense(ByVal Name As String, _ +Public Function CreateProductLicense(ByVal name As String, _ ByVal Ver As String, _ ByVal Code As String, _ ByVal Flags As ActiveLock2.LicFlags, _ @@ -275,7 +274,7 @@ ' @param strSig Private key blob ' @return Zero if verification is successful; Non-zero otherwise. ' -Public Function RSAVerify(strPub As String, strdata As String, strSig As String) As Long +Public Function RSAVerify(ByVal strPub As String, ByVal strdata As String, ByVal strSig As String) As Long Attribute RSAVerify.VB_Description = "Verifies an RSA signature." Dim Key As RSAKey Dim rc& Index: IActiveLock.cls =================================================================== RCS file: /cvsroot/activelock/activelock/src/IActiveLock.cls,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- IActiveLock.cls 4 Nov 2003 07:43:15 -0000 1.5 +++ IActiveLock.cls 18 Apr 2004 01:50:46 -0000 1.6 @@ -118,6 +118,12 @@ ' ' Specify Lock Type ' MyActiveLock.LockType = lockHD ' +' ' Sets path to liberation key file for automatic registration +' MyActiveLock.AutoRegisterKeyPath = App.path & "\myapp.alb" +' +' ' Initialize the instance +' MyActiveLock.Init +' ' ' Check registration status by calling Acquire() ' ' Note: Calling Acquire() may trigger ActiveLockEventNotifier_ValidateValue() event. ' ' So we should be prepared to handle that. @@ -220,6 +226,12 @@ ' 11.02.03 - th2tran - LicFlags Enum and its corresponding property don't belong here. Moved its definition to ProductLicense. ' - Added InstallationCode and RegisteredUser properties ' - Updated VBDox with new/simpler registration instructions. +' 04.10.04 - th2tran - Added ByVal modifier to parameter declarations for better compatibility with other COM languages (like VC++) +' 04.17.04 - th2tran - Removed the ParamArray thingy in Init() since it doesn't seem very forward-compatible. +' It's inconceivable to account for all possible future requirements, and if we try, we'll end up +' complicating ourselves in terms of compatibility. +' Better to do it via property accessors (such as the AutoRegisterKeyPath property), and +' leave Init() with no parameters. ' </pre> ' /////////////////////////////////////////////////////////////////////// @@ -265,7 +277,7 @@ ' Specifies the lock type for this instance of ActiveLock. ' @param LockTypes Lock Types. ' -Public Property Let LockType(LockTypes As ALLockTypes) +Public Property Let LockType(ByVal LockTypes As ALLockTypes) Attribute LockType.VB_Description = "Lock type for this instance of ActiveLock." End Property @@ -281,7 +293,7 @@ ' Specifies the name of the product being locked. ' @param sName Software Name ' -Public Property Let SoftwareName(sName As String) +Public Property Let SoftwareName(ByVal sName As String) Attribute SoftwareName.VB_Description = "Name of the product being locked." End Property @@ -296,7 +308,7 @@ '' ' Specifies the software code (product code) ' @param sCode Software Code. -Public Property Let SoftwareCode(sCode As String) +Public Property Let SoftwareCode(ByVal sCode As String) Attribute SoftwareCode.VB_Description = "software code (product code). This is Code1 generated by ALUGEN." End Property @@ -305,7 +317,7 @@ ' Specifies the version of the product being locked. ' @param sVer Version string e.g. "1.0" ' -Public Property Let SoftwareVersion(sVer As String) +Public Property Let SoftwareVersion(ByVal sVer As String) Attribute SoftwareVersion.VB_Description = "Version of the product being locked." End Property @@ -322,7 +334,7 @@ ' Specifies the key store type. ' @param KeyStore Key Store Type. ' -Public Property Let KeyStoreType(KeyStore As LicStoreType) +Public Property Let KeyStoreType(ByVal KeyStore As LicStoreType) Attribute KeyStoreType.VB_Description = "Specifies the key store (e.g. registry or file)." End Property @@ -334,7 +346,7 @@ ' then <code>Path</code> specifies the path to the license file. ' If <a href="IActiveLock.LicStoreType.html">alsRegistry</a> is used for <a href="IActiveLock.Let.KeyStoreType.htm">KeyStoreType</a>, ' the Path specifies the Registry hive where license information is stored. -Public Property Let KeyStorePath(sPath As String) +Public Property Let KeyStorePath(ByVal sPath As String) Attribute KeyStorePath.VB_Description = "Specifies the path where the license store resides." End Property @@ -348,6 +360,17 @@ End Property +'' +' Specifies the file path that contains the liberation key. +' If this file exists, ActiveLock will attempt to register the key automatically during its initialization. +' Upon successful registration, the liberation file WILL be deleted. +' <p>Note: This property is only effective if it is set prior to calling <code>Init</code>. +' @param sPath Full path to where the liberation file may reside. +Public Property Let AutoRegisterKeyPath(ByVal sPath As String) +Attribute AutoRegisterKeyPath.VB_Description = "Specifies the file path that contains the liberation key for automatic registration upon startup. Upon successful registration, the liberation file WILL be deleted." + +End Property + '* '*''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '* Interface Methods @@ -375,7 +398,7 @@ ' Transfers the current license to another computer. ' @param InstallCode Installation Code generated from the other computer. ' @return The liberation key tailored for the request code generated from the other machine. -Public Function Transfer(InstallCode As String) As String +Public Function Transfer(ByVal InstallCode As String) As String Attribute Transfer.VB_Description = "Transfers the current license to another computer." End Function @@ -383,14 +406,9 @@ '' ' Initializes ActiveLock before use. Some of the routines, including <a href="IActiveLock.Acquire.html">Acquire()</a> ' and <a href="IActiveLock.Register.html">Register()</a> requires <code>Init()</code> to be called first. -' This routine accepts varying number of parameters. -' Note: If you're accessing IActiveLock via <a href="Globals.NewInstance.html">ActiveLock2.NewInstance()</a>, -' then Init() would already have been called for you, so you don't need to call it again. ' -' @param Arg1 First parameter to be passed to this routine. -' @param OtherArgs The remaining array of arguments to be passed into this routine. -Public Sub Init(Arg1 As Variant, ParamArray OtherArgs() As Variant) -Attribute Init.VB_Description = "Initializes ActiveLock. This routine must be called before anything else." +Public Sub Init() +Attribute Init.VB_Description = "Initializes ActiveLock. This routine must be called before any other routine such as Acquire() or Register()." End Sub Index: modActiveLock.bas =================================================================== RCS file: /cvsroot/activelock/activelock/src/modActiveLock.bas,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- modActiveLock.bas 5 Oct 2003 08:40:18 -0000 1.2 +++ modActiveLock.bas 18 Apr 2004 01:50:46 -0000 1.3 @@ -65,6 +65,7 @@ ' instead. This approach was suggested by Peter Young (vbclassicforever) ' in the forum and mailing list a while back. ' 08.02.03 - th2tran - VBdox'd this module. +' 04.17.04 - th2tran - Added FileExists() routine. ' </pre> ' /////////////////////////////////////////////////////////////////////// @@ -314,3 +315,15 @@ 30 strFileName = Left(strFileName, lngCount) 40 IsRunningInIde = UCase(Right(strFileName, 7)) = "VB6.EXE" End Function + +'' +' Checks if a file exists in the system. +' +Public Function FileExists(ByVal strFile As String) As Boolean + FileExists = False + If Not Dir(strFile) = "" Then + FileExists = True + End If +End Function + + Index: ProductLicense.cls =================================================================== RCS file: /cvsroot/activelock/activelock/src/ProductLicense.cls,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- ProductLicense.cls 4 Nov 2003 07:43:15 -0000 1.5 +++ ProductLicense.cls 18 Apr 2004 01:50:46 -0000 1.6 @@ -70,6 +70,9 @@ ' 11.02.03 - th2tran - New license properties: License Type, MaxCount ' - Removed CLASS_n constants ' - Moved LicFlags definition from IActiveLock into here +' 04.17.04 - th2tran - Don't save product key property--it is now considered a +' transient (non-serializable) property. Saving the product key is unnecessary +' and will make our liberation key look (unnecessarily) horrendous. ' </pre> @@ -82,7 +85,7 @@ Private mstrLicensee As String Private mstrLicenseClass As String Private mLicType As ALLicType -Private mstrProductKey As String +Private mstrProductKey As String ' This is a transient property -- TODO: Remove this property Private mstrProductName As String Private mstrProductVer As String Private mstrLicenseKey As String @@ -92,6 +95,7 @@ Private mstrHash1 As String ' hash of mstrRegisteredDate Private mnMaxCount As Long ' max number of concurrent users + '' ' License Flags. Values can be combined (OR'ed) together. ' @@ -210,7 +214,7 @@ ' the risk of invalidating your existing license. ' @param Name Name of the licensed user ' -Public Property Let Licensee(ByVal Name As String) +Public Property Let Licensee(ByVal name As String) mstrLicensee = name End Property @@ -330,7 +334,6 @@ Attribute ToString.VB_Description = "Returns a line-feed delimited string encoding of this object's properties." ToString = ProductName & vbCrLf & _ ProductVer & vbCrLf & _ - ProductKey & vbCrLf & _ LicenseClass & vbCrLf & _ LicenseType & vbCrLf & _ Licensee & vbCrLf & _ @@ -354,14 +357,13 @@ ' Initialize appropriate properties ProductName = arrParts(0) ProductVer = arrParts(1) - ProductKey = arrParts(2) - LicenseClass = arrParts(3) - LicenseType = CLng(arrParts(4)) - Licensee = arrParts(5) - RegisteredDate = arrParts(6) - Expiration = arrParts(7) - MaxCount = CLng(arrParts(8)) - LicenseKey = arrParts(9) + LicenseClass = arrParts(2) + LicenseType = CLng(arrParts(3)) + Licensee = arrParts(4) + RegisteredDate = arrParts(5) + Expiration = arrParts(6) + MaxCount = CLng(arrParts(7)) + LicenseKey = arrParts(8) End Sub '' |