0% found this document useful (0 votes)
80 views

Excel - How Can I Create Product Keys For VBA Applications So TH

The document discusses how to create product keys for VBA applications to prevent illegal distribution. It provides code to retrieve the hard disk serial number and CPU number to generate a unique code for each system. The code is then encrypted and sent to the developer for activation.

Uploaded by

Fabio C
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
80 views

Excel - How Can I Create Product Keys For VBA Applications So TH

The document discusses how to create product keys for VBA applications to prevent illegal distribution. It provides code to retrieve the hard disk serial number and CPU number to generate a unique code for each system. The code is then encrypted and sent to the developer for activation.

Uploaded by

Fabio C
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

How can I create product keys for VBA applications so that

illegal distribution of software is prevented?


Asked 9 years, 7 months ago Modified 8 years, 3 months ago Viewed 15k times

I am working on an Excel VBA application.

7 My company wants to make it a product. This application should be installable only on one
system. Could someone please help me with this.

vba excel
10

Share Follow edited Dec 21, 2012 at 6:11 asked Dec 21, 2012 at 4:20
Siddharth Rout Developer
143k 17 199 246 269 5 7 19

Sorted by:
1 Answer
Highest score (default)

This is just a basic example on how to ensure that your product is installed on just one
system.
24
Logic:

1. Retrieve the Hardware ID (Ex: Hard Disk Number, CPU Number etc...)

2. You may also ask the user Name and email address

3. Encrypt the above info to generate an Unique Code (This is done within the App)

4. User sends you the Unique Code (Be it via email / Online Activation / Telephone)

5. You send the user an Activation Id based on the Unique Code

CODE for retrieving HardDisk Serial Number and CPU Number

Paste this code in a class module (Not my code. Copyright info mentioned in the code)

Private Const VER_PLATFORM_WIN32S = 0

Private Const VER_PLATFORM_WIN32_WINDOWS = 1

Private Const VER_PLATFORM_WIN32_NT = 2

Private Const DFP_RECEIVE_DRIVE_DATA = &H7C088

Private Const FILE_SHARE_READ = &H1


Private Const FILE_SHARE_WRITE = &H2

Private Const GENERIC_READ = &H80000000

Private Const GENERIC_WRITE = &H40000000


Private
Join Stack Const
Overflow OPEN_EXISTING
to find = 3
to your technical question, help others
the best answer
Private Const CREATE_NEW = 1
Sign up
answer theirs.
Private Enum HDINFO

HD_MODEL_NUMBER

HD_SERIAL_NUMBER

HD_FIRMWARE_REVISION

End Enum

Private Type OSVERSIONINFO

dwOSVersionInfoSize As Long

dwMajorVersion As Long

dwMinorVersion As Long

dwBuildNumber As Long

dwPlatformId As Long

szCSDVersion As String * 128

End Type

Private Type IDEREGS

bFeaturesReg As Byte

bSectorCountReg As Byte

bSectorNumberReg As Byte

bCylLowReg As Byte

bCylHighReg As Byte

bDriveHeadReg As Byte

bCommandReg As Byte

bReserved As Byte

End Type

Private Type SENDCMDINPARAMS

cBufferSize As Long

irDriveRegs As IDEREGS

bDriveNumber As Byte

bReserved(1 To 3) As Byte

dwReserved(1 To 4) As Long

End Type

Private Type DRIVERSTATUS

bDriveError As Byte

bIDEStatus As Byte

bReserved(1 To 2) As Byte

dwReserved(1 To 2) As Long

End Type

Private Type SENDCMDOUTPARAMS

cBufferSize As Long

DStatus As DRIVERSTATUS

bBuffer(1 To 512) As Byte

End Type

Private Declare Function GetVersionEx _

Lib "kernel32" Alias "GetVersionExA" _

(lpVersionInformation As OSVERSIONINFO) As Long

Private Declare Function CreateFile _

Lib "kernel32" Alias "CreateFileA" _

(ByVal lpFileName As String, _

ByVal dwDesiredAccess As Long, _

ByVal dwShareMode As Long, _

ByVal lpSecurityAttributes As Long, _

ByVal dwCreationDisposition As Long, _

ByVal dwFlagsAndAttributes As Long, _

ByVal hTemplateFile As Long) As Long

Private Declare Function CloseHandle _

Lib "kernel32" _

(ByVal hObject As Long) As Long

Join Stack Overflow to find the best answer to your technical question, help others
Sign up
answer theirs.
Private Declare Function DeviceIoControl _

Lib "kernel32" _

(ByVal hDevice As Long, _

ByVal dwIoControlCode As Long, _

lpInBuffer As Any, _

ByVal nInBufferSize As Long, _

lpOutBuffer As Any, _

ByVal nOutBufferSize As Long, _

lpBytesReturned As Long, _

ByVal lpOverlapped As Long) As Long

Private Declare Sub ZeroMemory _

Lib "kernel32" Alias "RtlZeroMemory" _

(dest As Any, _

ByVal numBytes As Long)

Private Declare Sub CopyMemory _

Lib "kernel32" Alias "RtlMoveMemory" _

(Destination As Any, _

Source As Any, _
ByVal Length As Long)

Private Declare Function GetLastError _

Lib "kernel32" () As Long

Private mvarCurrentDrive As Byte

Private mvarPlatform As String

Public Property Get Copyright() As String

Copyright = "HDSN Vrs. 1.00, (C) Antonio Giuliana, 2001-2003"

End Property

Public Function GetModelNumber() As String

GetModelNumber = CmnGetHDData(HD_MODEL_NUMBER)

End Function

Public Function GetSerialNumber() As String

GetSerialNumber = CmnGetHDData(HD_SERIAL_NUMBER)

End Function

Public Function GetFirmwareRevision() As String

GetFirmwareRevision = CmnGetHDData(HD_FIRMWARE_REVISION)

End Function

Public Property Let CurrentDrive(ByVal vData As Byte)

If vData < 0 Or vData > 3 Then

Err.Raise 10000, , "Illegal drive number" ' IDE drive 0..3

End If

mvarCurrentDrive = vData

End Property

Public Property Get CurrentDrive() As Byte

CurrentDrive = mvarCurrentDrive

End Property

Public Property Get Platform() As String

Platform = mvarPlatform

End Property

Private Sub Class_Initialize()


Dim OS As OSVERSIONINFO

OS.dwOSVersionInfoSize = Len(OS)

Call GetVersionEx(OS)
mvarPlatform = "Unk"

Join Stack Overflow to findOS.dwPlatformId

Select Case the best answer to your technical question, help others
Sign up
answer theirs. Case Is = VER_PLATFORM_WIN32S

mvarPlatform = "32S"

Case Is = VER_PLATFORM_WIN32_WINDOWS

If OS.dwMinorVersion = 0 Then

mvarPlatform = "W95"

Else

mvarPlatform = "W98"

End If

Case Is = VER_PLATFORM_WIN32_NT

mvarPlatform = "WNT"

End Select

End Sub

Private Function CmnGetHDData(hdi As HDINFO) As String

Dim bin As SENDCMDINPARAMS


Dim bout As SENDCMDOUTPARAMS

Dim hdh As Long

Dim br As Long

Dim ix As Long

Dim hddfr As Long

Dim hddln As Long

Dim s As String

Select Case hdi

Case HD_MODEL_NUMBER

hddfr = 55

hddln = 40

Case HD_SERIAL_NUMBER

hddfr = 21

hddln = 20

Case HD_FIRMWARE_REVISION

hddfr = 47

hddln = 8

Case Else

Err.Raise 10001, "Illegal HD Data type"

End Select

Select Case mvarPlatform

Case "WNT"

hdh = CreateFile("\\.\PhysicalDrive" & mvarCurrentDrive, _

GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ +


FILE_SHARE_WRITE, _

0, OPEN_EXISTING, 0, 0)

Case "W95", "W98"

hdh = CreateFile("\\.\Smartvsd", _

0, 0, 0, CREATE_NEW, 0, 0)

Case Else

Err.Raise 10002, , "Illegal platform (only WNT, W98 or W95)"

End Select

If hdh = 0 Then

Err.Raise 10003, , "Error on CreateFile"

End If

ZeroMemory bin, Len(bin)

ZeroMemory bout, Len(bout)

With bin

.bDriveNumber = mvarCurrentDrive

.cBufferSize = 512

With .irDriveRegs

If (mvarCurrentDrive And 1) Then

.bDriveHeadReg = &HB0

Else

.bDriveHeadReg = &HA0

Join Stack Overflow to findIfthe


End
best answer to your technical question, help others Sign up
answer theirs. .bCommandReg = &HEC

.bSectorCountReg = 1

.bSectorNumberReg = 1

End With

End With

DeviceIoControl hdh, DFP_RECEIVE_DRIVE_DATA, _

bin, Len(bin), bout, Len(bout), br, 0

s = ""
For ix = hddfr To hddfr + hddln - 1 Step 2

If bout.bBuffer(ix + 1) = 0 Then Exit For

s = s & Chr(bout.bBuffer(ix + 1))

If bout.bBuffer(ix) = 0 Then Exit For

s = s & Chr(bout.bBuffer(ix))

Next ix

CloseHandle hdh

CmnGetHDData = Trim(s)

End Function

You can then call it using

'~~> Get the CPU No

CPU = GetWmiDeviceSingleValue("Win32_Processor", "ProcessorID")

'~~> Get the Hard Disk No

Dim h As HDSN

Set h = New HDSN

With h

.CurrentDrive = 0

HDNo = .GetSerialNumber

End With

Set h = Nothing

Once you have this info, you can then merge it with the First Name, Last Name and the email
address to create a string. For example

strg = Trim(FirstName) & Chr(1) & Trim(LastName) & Chr(1) & _

Trim(EmailAddress) & Chr(1) & Trim(CPU) & Chr(1) & Trim(HDNo)

Once you have the string, you can then encrypt it. Here is another basic example of encrypting
it. You can choose any type of encryption that you would like

For i = 1 To Len(strg)

RandomNo = (Rnd * 100)

tmp = tmp & Hex((Asc(Mid(strg, i, 1)) Xor RandomNo))

Next

The tmp above holds the encrypted string.

Once you receive this string, you will have to decode it and create an Activation Id based on
Join Stack Overflow to find the best answer to your technical question, help others
Signto
that. You App should be able to accept the Activation Id . You also have an option upstore
answer theirs.
this info in the registry or in a Dat File.

A simple registration window might look like this.

Hope this gets you started! :)

IMP: Though you can lock your VBA project but it is definitely not hack proof. You might want
to explore VSTO to create DLLs which does the above thing.

Share Follow answered Dec 21, 2012 at 6:10


Siddharth Rout
143k 17 199 246

1 Thank you sooooooooooooo much for all the detailed steps. Highly appreciate you for taking time to
put together all the info. You saved my life. Thanks a ton.... –  Developer Dec 21, 2012 at 6:30

@SiddharthRout Hi, so the idea behind is locking the VBA project? But as you mentioned, it can be
easily hack? – Larry Dec 21, 2012 at 6:50

2 @Larry: Locking the VBA project like I mentioned is not the ideal thing to do. One can take the VSTO

Join Stackapproach
Overflowto create the dlls. – Siddharth Rout Dec 21, 2012 at 6:52
to find the best answer to your technical question, help others
Sign up
answer theirs.
@SiddharthRout, does this work on x64 machine, like OS windows 8.1 x64 ? I plan to use this code in
MS Access VBA, we can have .accde which changes VBA to machine code. – Sham Yemul Jun 16, 2014
at 14:33

@SiddharthRout, I am getting sub or function not defined for GetWmiDeviceSingleValue. This does not
seem to be API, I searched Net and APIGuide. – Sham Yemul Jun 16, 2014 at 15:24

Highly active question. Earn 10 reputation (not counting the association bonus) in order to answer this
question. The reputation requirement helps protect this question from spam and non-answer activity.

Join Stack Overflow to find the best answer to your technical question, help others
Sign up
answer theirs.

You might also like