PDA

Click to See Complete Forum and Search --> : VB6 - Save settings into a file compressed and encrypted


CVMichael
Oct 24th, 2006, 10:23 AM
If you want to save the application settings (or any other data) encrypted and/or compressed, this is how you do it:

Option Explicit

Private Declare Function Compress Lib "zlib.dll" Alias "compress" (dest As Any, destLen As Any, src As Any, ByVal srcLen As Long) As Long
Private Declare Function Uncompress Lib "zlib.dll" Alias "uncompress" (dest As Any, destLen As Any, src As Any, ByVal srcLen As Long) As Long

Private Function LoadSettings(Optional EncPassword As String = "") As PropertyBag
'
' Made by Michael Ciurescu (CVMichael from vbforums.com)
' Original thread: http://www.vbforums.com/showthread.php?t=434490
'

Dim PB As PropertyBag, FLNum As Integer
Dim Data() As Byte, DataLength As Long
Dim EncCompSettings As Byte, OriginalSize As Long
Dim RndNum As Double

Const Encrypted As Byte = 1
Const Compressed As Byte = 2

' On error just return an empty property bag
On Error GoTo ReturnEmpty

Set PB = New PropertyBag

FLNum = FreeFile
Open App.Path & "\Settings.dat" For Binary Access Read As FLNum
Get FLNum, , DataLength ' Get data length (size of buffer)

If DataLength > 0 Then
' Get whether it was compressed and/or encrypted
Get FLNum, , EncCompSettings

' if encrypted, read the random number
If (EncCompSettings And Encrypted) = Encrypted Then Get FLNum, , RndNum

ReDim Data(DataLength)
Get FLNum, , Data ' read the data with the settings

' If data was encrypted, then decrypt it
If (EncCompSettings And Encrypted) = Encrypted Then
Data = StrConv(RndCrypt(StrConv(Data, vbUnicode), EncPassword & RndNum), vbFromUnicode)
End If

' If data was compressed, then decompress it
If (EncCompSettings And Compressed) = Compressed Then
Get FLNum, , OriginalSize

Dim OData() As Byte ' temporary buffer for decompression
ReDim OData(OriginalSize)
Uncompress OData(0), OriginalSize, Data(0), UBound(Data) + 1 ' decompress data

Data = OData
Erase OData
End If

' Put the data in the property bag
PB.Contents = Data
End If
Close FLNum

ReturnEmpty:
Set LoadSettings = PB ' return the property bag
End Function

Private Function SaveSettings(SavePB As PropertyBag, Optional CompressData As Boolean = False, Optional EncPassword As String) As Boolean
'
' Made by Michael Ciurescu (CVMichael from vbforums.com)
' Original thread: http://www.vbforums.com/showthread.php?t=434490
'

Dim Data() As Byte, DataLength As Long
Dim FLNum As Integer, RndNum As Double
Dim EncCompSettings As Byte, OriginalSize As Long

Const Encrypted As Byte = 1
Const Compressed As Byte = 2

' On error exit and return False
On Error GoTo Err_Exit

Data = SavePB.Contents ' get the contents of the property bag

OriginalSize = UBound(Data) + 1 ' get size of buffer (un-altered/original)

If CompressData Then
EncCompSettings = Compressed ' save the setting that we compressed the data

Dim CData() As Byte ' temporary buffer to compress data
DataLength = (UBound(Data) + 1) * 1.01 + 12
ReDim CData(DataLength - 1)

Compress CData(0), DataLength, Data(0), UBound(Data) + 1 ' compress the data

ReDim Preserve CData(DataLength - 1) ' resize buffer to the compressed length
Erase Data
Data = CData ' assign compressed data to main buffer
End If

If Len(EncPassword) > 0 Then
EncCompSettings = EncCompSettings Or Encrypted ' save the setting that we encrypted the data

Randomize
' get a random number
RndNum = 2 ^ 15 * Rnd + 2 ^ 20 * Rnd + 2 ^ 25 * Rnd + 2 ^ 30 * Rnd

' encrypt the data using our password and the random number
Data = StrConv(RndCrypt(StrConv(Data, vbUnicode), EncPassword & RndNum), vbFromUnicode)
End If

' delete the file if it already exists
' (in case the size of the current file is less than before)
If Len(Dir(App.Path & "\Settings.dat")) > 0 Then
On Error Resume Next
SetAttr App.Path & "\Settings.dat", vbNormal
Kill App.Path & "\Settings.dat"
On Error GoTo 0
End If

' Create file, and save all the settings
FLNum = FreeFile
Open App.Path & "\Settings.dat" For Binary Access Write As FLNum
DataLength = UBound(Data)

Put FLNum, , DataLength
Put FLNum, , EncCompSettings

If (EncCompSettings And Encrypted) = Encrypted Then Put FLNum, , RndNum

Put FLNum, , Data

If (EncCompSettings And Compressed) = Compressed Then Put FLNum, , OriginalSize
Close FLNum

SaveSettings = True
Exit Sub

Err_Exit:
SaveSettings = False
End Function

Public Function RndCrypt(ByVal Str As String, ByVal Password As String) As String
'
' Made by Michael Ciurescu (CVMichael from vbforums.com)
' Original thread: http://www.vbforums.com/showthread.php?t=231798
'
Dim SK As Long, K As Long

' init randomizer for password
Rnd -1
Randomize Len(Password)
' (((K Mod 256) Xor Asc(Mid$(Password, K, 1))) Xor Fix(256 * Rnd)) -> makes sure that a
' password like "pass12" does NOT give the same result as the password "sspa12" or "12pass"
' or "1pass2" etc. (or any combination of the same letters)

For K = 1 To Len(Password)
SK = SK + (((K Mod 256) Xor Asc(Mid$(Password, K, 1))) Xor Fix(256 * Rnd))
Next K

' init randomizer for encryption/decryption
Rnd -1
Randomize SK

' encrypt/decrypt every character using the randomizer
For K = 1 To Len(Str)
Mid$(Str, K, 1) = Chr(Fix(256 * Rnd) Xor Asc(Mid$(Str, K, 1)))
Next K

RndCrypt = Str
End Function

How to use the functions (save and load settings/data):

Private Sub Form_Load()
Dim LoadPB As PropertyBag

' load the settings
' Use any password you want, as long as it's the same when you save data
Set LoadPB = LoadSettings("password=-0987654321")

' read the values from the property bag
Me.Top = LoadPB.ReadProperty("Top", Me.Top)
Me.Left = LoadPB.ReadProperty("Left", Me.Left)
Me.Width = LoadPB.ReadProperty("Width", Me.Width)
Me.Height = LoadPB.ReadProperty("Height", Me.Height)
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Dim SavePB As New PropertyBag

' assign the values you need to save in the property bag
SavePB.WriteProperty "Top", Me.Top
SavePB.WriteProperty "Left", Me.Left
SavePB.WriteProperty "Width", Me.Width
SavePB.WriteProperty "Height", Me.Height

' save the settings
' Password must be the same as when you load the data
SaveSettings SavePB, True, "password=-0987654321"
End Sub

As you may already noticed, this code uses ZLib.DLL to compress data, this is the website for ZLIB:
http://www.zlib.net/
And to get the actual DLL, this is the direct link to the ZIP where the DLL is: ZLib.dll (http://www.zlib.net/zlib123-dll.zip)
Upzip the file, and copy and paste the DLL to your windows/system32 directory.

alexis23
Jul 12th, 2007, 08:04 PM
hi,

for the protection of what dll i am using in my application, can i rename the ZLib.dll into another name.???

alexis23

CVMichael
Jul 12th, 2007, 09:07 PM
I pretty sure that if you do that the company/people who created zlib.dll would sue you or something... your using their product, and I'm pretty sure they would not like it if you would "hide" it...

alexis23
Jul 12th, 2007, 09:59 PM
ok thanks,

alexis