Skip to main content
GameDev.net gamedev.net
🔒 Locked

[.net] From VB6 to VB.NET - File IO/Memory Problems

Started by VBStrider Apr 17, 2008 at 1:59 PM 5 replies 4.2k views
Original Post
VBStrider
VBStrider
I'm converting my development tools from VB6 to VB.NET. However, I have ran into some problems regarding saving/loading the data. The majority of my tools alter data files, which are encrypted before they are saved. These tools are things such as an item editor, object editor, NPC editor, etc. To load the data with VB6, I would open the file with CreateFile() and read the contents into a byte array using ReadFile(). The byte array would then be fed into the decryption function, which would spit out a new, decrypted, byte array. I then used CopyMemory() (RtlMoveMemory) to copy the byte array into the data array, which is an array of structures. This data array could then be altered with the editor and saved to the data file again, pretty much reversing the steps to load the data. Unfortunately, VB.NET does not appear to like the CopyMemory() function, most likely because it wants to manage the memory itself. I've tried various methods to get the same functionality, but nothing has worked so far. I am currently trying to use the Serialize()/Deserialize() functions to convert to a byte array, and from a byte array to the structure array. Here is the test code. Please note that I am using "Object" instead of the actual structure array. I did this to prevent possible errors with deserializing. The code does not work even if I use the correct structure array.

Dim byBuf() As Byte
Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim stream As New System.IO.MemoryStream()
Dim res As Object

' byBuf is loaded from the data file here.  File IO code not included.

' Alternate way of filling the stream.
' Call formatter.Serialize(stream, byBuf)

' Fill the stream with the byte array.
stream.Write(byBuf, 0, byBuf.Length)

' Go back to the beginning of the stream.  This fixed an error in a previous test.
Call stream.Seek(0, IO.SeekOrigin.Begin)

' Deserialize the stream into the object.  res is used as a debugging stand-in.
res = formatter.Deserialize(stream)


The following error occurs at "res = formatter.Deserialize(stream)":
Quote:
A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll [5] Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization.
I am new to VB.NET, so if there is a better way to do what I need it to do, please let me know. Help would really be appreciated. Development is stalled until these tools can be converted. Note: I no longer have access to VB6, so going back is not an option at the moment.
VBStrider
VBStrider
Thanks for the help, but as far as I know, the problem isn't with reading the file's contents. The problem is getting the byte array to copy into the array of structures.

But I did try your idea. Here is the complete function:
' Loads the graphic information file.Public Function LoadGraphics(ByVal sFilename As String, ByRef lpData() As tGrhData) As Integer	On Error GoTo Handle_Error	' Make sure that the file exists.	If Not File.Exists(sFilename) Then Return 0	' Declare the binary reader, and open the file.	Dim binReader As New BinaryReader(File.Open(sFilename, FileMode.Open))	' Find out how many bytes we need to read in, and store the value.	Dim lLen As Long = binReader.BaseStream.Length	' The buffer that will store the file's binary contents.  Counting starts at 0, so 1 needs to be removed from the length for the array to be the correct size.	Dim byBuf(lLen - 1) As Byte	' Read the contents of the file into the buffer, and store how many bytes were read.	Dim iNumRead As Integer = binReader.Read(byBuf, 0, lLen)	' Check if, for some reason, we couldn't read in all the bytes.	If iNumRead <> lLen Then		' Shutdown the binary reader.  This handles closing the file as well.		Call binReader.Close()		' Return failure.		Return 0	End If	' The encryption key.  The actual key has been removed for obvious reasons.	Dim byKey As Byte() = {}	' Decrypt the data.	Call Decrypt(byKey.Length, byKey(0), byBuf.Length, byBuf(0), byBuf(0))	' The binary formatter that will be used to deserialize the byte array into the array of structures.	Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter	' Create the stream that will be fed into the deserializer and fill it with the byte array.	Dim stream As New System.IO.MemoryStream(byBuf)	' The temporary destination of the deserialization.  Normally, this would be lpData but for debugging purposes, Object is used.	Dim res As Object	' Go back to the beginning of the stream.  This fixed an error in a previous test.	Call stream.Seek(0, IO.SeekOrigin.Begin)	' ***** This is the line that causes the error. *****	' Deserialize the stream into the object.  res is used as a debugging stand-in.	res = formatter.Deserialize(stream)	' *****	' Dispose of the byte array stream, since we no longer need it.	Call stream.Dispose()	' Shutdown the binary reader.  This handles closing the file as well.	Call binReader.Close()	' Return success.	Return 1Handle_Error:	' Report the error.	Call Debug.Print("[" & Err.Number & "]  " & Err.Description)	' Just incase this was in use, dispose of the stream.	Call stream.Dispose()	' Again, just incase this was in use, close the binary reader.  This also closes the open file.	Call binReader.Close()	' Return failure.	Return 0End Function


The same error occurs, on the same line.

Here is what I need this function to do:

1. Load a binary file.
2. Send the file's contents as a byte array to the decryption function, so that file's contents can be decrypted.
3. Copy the decrypted byte array into the array of structures, lpData.

P.S. I know my error handling might not conform to VB.NET standards, but it works for now. Also, the Decrypt() function is inside of a DLL compiled from C++ code. The VB.NET equivalent decryption function ran too slowly to be of use.
EdR
EdR
If LoadMemory() is an unmanaged function, why not just write unmanaged code to work with it and wrap it in a managed assembly?
http://edropple.com
VBStrider
VBStrider
I tried passing the structure array to the C++ DLL, but it errors. Here is the code:

// Loads graphic data.int __stdcall LoadGraphicsData(char *szFilename, tGrhData *lpData){	// Return success.	return (lpData[0].szName[0]);}


Public Declare Function LoadGraphicsData Lib "Common.dll" (ByVal szFilename As String, ByRef lpData As tGrhData) As Integer' Loads the graphic information file.Public Function LoadGraphics(ByVal sFilename As String, ByRef lpData() As tGrhData) As Integer	On Error GoTo Handle_Error	Call Debug.Print(LoadGraphicsData(sFilename, lpData))	' Return success.	Return 1Handle_Error:	' Report the error.	Call Debug.Print("[" & Err.Number & "]  " & Err.Description)	' Return failure.	Return 0End Function


The following error occurs:
Quote:

A first chance exception of type 'System.ArgumentException' occurred in GraphicEditor.exe
[5] The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))


Any ideas?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.