Reading Binary Data from the Registry 
Author Message
 Reading Binary Data from the Registry

Hello All,

I am in the midst of converting a VB6 application to C# and I am running
into a problem.

In VB6 I used a custom Type to hold the data I needed and I saved the data
to the registry as a binary datatype.

How would/could I use C# to get that registry data out and into a struct? Is
it a straight shot or do I have to start over by writing the original Type
as a C# struct to the registry? What I mean is: am I going to have to forget
my old registry entries and try to save them to the registry as a struct
before I can read them in C#? Will C# be able to read the old VB6 registry
values and get cast to a struct without a whole lot of pain?

I noticed that the value from the registry comes out as a byte array... is
there something I need to do to this before I can cast it to a new struct?

Any code examples would be greatly appreciated.

Thanks in advance!
Richard



Tue, 28 Sep 2004 08:00:40 GMT  
 Reading Binary Data from the Registry
look this http://www.c-sharpcorner.com/1/newmanregistry.asp

Marcos



Quote:
> Hello All,

> I am in the midst of converting a VB6 application to C# and I am running
> into a problem.

> In VB6 I used a custom Type to hold the data I needed and I saved the data
> to the registry as a binary datatype.

> How would/could I use C# to get that registry data out and into a struct?
Is
> it a straight shot or do I have to start over by writing the original Type
> as a C# struct to the registry? What I mean is: am I going to have to
forget
> my old registry entries and try to save them to the registry as a struct
> before I can read them in C#? Will C# be able to read the old VB6 registry
> values and get cast to a struct without a whole lot of pain?

> I noticed that the value from the registry comes out as a byte array... is
> there something I need to do to this before I can cast it to a new struct?

> Any code examples would be greatly appreciated.

> Thanks in advance!
> Richard



Tue, 28 Sep 2004 12:44:28 GMT  
 Reading Binary Data from the Registry
Marcos,

Thanks for the link but the information there doesn't help me. I need to
know what to do with the binary data from the registry once I have it. That
example only shows how to deal with strings.

Richard



Quote:
> look this http://www.c-sharpcorner.com/1/newmanregistry.asp

> Marcos



Tue, 28 Sep 2004 19:33:57 GMT  
 Reading Binary Data from the Registry
you may read my old post (C#)
  http://groups.google.com/groups?hl=en&selm=OzgmlAQUBHA.1348%40tkmsftn...

this one uses the Marshal class:
 namespace           :  System.Runtime.InteropServices
 allocate memory     :  Marshal.AllocHGlobal
 byte[] => memory    :  Marshal.Copy
 memory => structure :  Marshal.PtrToStructure
 free memory         :  Marshal.FreeHGlobal

Another method would be unsafe&pointers....

Quote:

> Thanks for the link but the information there doesn't help me. I need to
> know what to do with the binary data from the registry once I have it. That
> example only shows how to deal with strings.



Tue, 28 Sep 2004 20:18:08 GMT  
 Reading Binary Data from the Registry
NETMaster,

Thanks for the information. I think this is getting me where I need to be.
At least it a lot closer than I was before.

I am using the code you pointed out and now I am getting an error when it
runs. The error is:

Object reference not set to an instance of an object

Here is the code:


RegistryKey mvarRegKey =
Registry.CurrentUser.OpenSubKey(mvarRegPath.ToString());
string[] mvarValNames = mvarRegKey.GetValueNames();

for (int i = 0;i < mvarValNames.Length;i++)
{
    try
    {
        Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
        byte[] aValue = mvarValue as byte[];  // The error occurs here
        int iSize = aValue.Length;
        IntPtr buffer = Marshal.AllocHGlobal(iSize);
        Marshal.Copy(aValue, 0, buffer, iSize);
        RegDServer mvarRegDSvr = (RegDServer) Marshal.PtrToStructure(buffer,
typeof(RegDServer));
        Marshal.FreeHGlobal(buffer);
        LoadRegDServer(mvarRegDSvr);
    }
    catch (Exception e)
    {
        Debug.WriteLine("Error: " + e.Message);
    }

Quote:
}

mvarRegKey.Close();

My question is, do you see something wrong here? I know the data is in the
registry and the GetValueNames() is returning an array of values. It just
seems to be having a problem getting the data (GetValue()) into the Object
mvarValue.

Any input would be greatly appreciated.

Thanks again!
Richard


Quote:
> you may read my old post (C#)

http://groups.google.com/groups?hl=en&selm=OzgmlAQUBHA.1348%40tkmsftn...
Quote:

> this one uses the Marshal class:
>  namespace           :  System.Runtime.InteropServices
>  allocate memory     :  Marshal.AllocHGlobal
>  byte[] => memory    :  Marshal.Copy
>  memory => structure :  Marshal.PtrToStructure
>  free memory         :  Marshal.FreeHGlobal

> Another method would be unsafe&pointers....



Thu, 30 Sep 2004 20:52:30 GMT  
 Reading Binary Data from the Registry
You should check with de{*filter*}:

  - Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
    is 'mvarValue' really a valid object?
    I guess it is null!

  - byte[] aValue = mvarValue as byte[];
     this line only works for binary registry values,
     but you may have other types, too?

Quote:

> Thanks for the information. I think this is getting me where I need to be.
> At least it a lot closer than I was before.
> I am using the code you pointed out and now I am getting an error when it
> runs. The error is:
> Object reference not set to an instance of an object
> Here is the code:


> RegistryKey mvarRegKey =
> Registry.CurrentUser.OpenSubKey(mvarRegPath.ToString());
> string[] mvarValNames = mvarRegKey.GetValueNames();

> for (int i = 0;i < mvarValNames.Length;i++)
> {
>     try
>     {
>         Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
>         byte[] aValue = mvarValue as byte[];  // The error occurs here
>         int iSize = aValue.Length;
>         IntPtr buffer = Marshal.AllocHGlobal(iSize);
>         Marshal.Copy(aValue, 0, buffer, iSize);
>         RegDServer mvarRegDSvr = (RegDServer) Marshal.PtrToStructure(buffer,
> typeof(RegDServer));
>         Marshal.FreeHGlobal(buffer);
>         LoadRegDServer(mvarRegDSvr);
>     }
>     catch (Exception e)
>     {
>         Debug.WriteLine("Error: " + e.Message);
>     }
> }
> mvarRegKey.Close();

> My question is, do you see something wrong here? I know the data is in the
> registry and the GetValueNames() is returning an array of values. It just
> seems to be having a problem getting the data (GetValue()) into the Object
> mvarValue.

> Any input would be greatly appreciated.

> Thanks again!
> Richard



> > you may read my old post (C#)

> http://www.*-*-*.com/ %40tkmsftn...

> > this one uses the Marshal class:
> >  namespace           :  System.Runtime.InteropServices
> >  allocate memory     :  Marshal.AllocHGlobal
> >  byte[] => memory    :  Marshal.Copy
> >  memory => structure :  Marshal.PtrToStructure
> >  free memory         :  Marshal.FreeHGlobal

> > Another method would be unsafe&pointers....



Fri, 01 Oct 2004 01:02:51 GMT  
 Reading Binary Data from the Registry
NetMaster,

I am beginning to wonder if there is some sort of security issues I should
be considering here. Have you ever had to use the
System.Security.Permissions namespace to get the code running? If so, do you
know of an example on how to use it?

Thanks,
Richard


Quote:
> You should check with de{*filter*}:

>   - Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
>     is 'mvarValue' really a valid object?
>     I guess it is null!

>   - byte[] aValue = mvarValue as byte[];
>      this line only works for binary registry values,
>      but you may have other types, too?




- Show quoted text -

Quote:
> > Thanks for the information. I think this is getting me where I need to
be.
> > At least it a lot closer than I was before.
> > I am using the code you pointed out and now I am getting an error when
it
> > runs. The error is:
> > Object reference not set to an instance of an object
> > Here is the code:


> > RegistryKey mvarRegKey =
> > Registry.CurrentUser.OpenSubKey(mvarRegPath.ToString());
> > string[] mvarValNames = mvarRegKey.GetValueNames();

> > for (int i = 0;i < mvarValNames.Length;i++)
> > {
> >     try
> >     {
> >         Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
> >         byte[] aValue = mvarValue as byte[];  // The error occurs here
> >         int iSize = aValue.Length;
> >         IntPtr buffer = Marshal.AllocHGlobal(iSize);
> >         Marshal.Copy(aValue, 0, buffer, iSize);
> >         RegDServer mvarRegDSvr = (RegDServer)

Marshal.PtrToStructure(buffer,

- Show quoted text -

Quote:
> > typeof(RegDServer));
> >         Marshal.FreeHGlobal(buffer);
> >         LoadRegDServer(mvarRegDSvr);
> >     }
> >     catch (Exception e)
> >     {
> >         Debug.WriteLine("Error: " + e.Message);
> >     }
> > }
> > mvarRegKey.Close();

> > My question is, do you see something wrong here? I know the data is in
the
> > registry and the GetValueNames() is returning an array of values. It
just
> > seems to be having a problem getting the data (GetValue()) into the
Object
> > mvarValue.

> > Any input would be greatly appreciated.

> > Thanks again!
> > Richard



> > > you may read my old post (C#)

http://www.*-*-*.com/ %40tkmsftn...

- Show quoted text -

Quote:

> > > this one uses the Marshal class:
> > >  namespace           :  System.Runtime.InteropServices
> > >  allocate memory     :  Marshal.AllocHGlobal
> > >  byte[] => memory    :  Marshal.Copy
> > >  memory => structure :  Marshal.PtrToStructure
> > >  free memory         :  Marshal.FreeHGlobal

> > > Another method would be unsafe&pointers....



Sat, 02 Oct 2004 06:44:41 GMT  
 Reading Binary Data from the Registry
Quote:
> Have you ever had to use the System.Security.Permissions namespace

NO

Quote:
> some sort of security issues

Most registry keys can be read by common users (but not written).
If you just use OpenSubKey("x"), the key is read-only, you can't write.
Also check permission with regedt32

I recommend step-by-step debugging, and post the EXACT behavior you see.

Quote:

> I am beginning to wonder if there is some sort of security issues I should
> be considering here. Have you ever had to use the
> System.Security.Permissions namespace to get the code running? If so, do you
> know of an example on how to use it?
> > You should check with de{*filter*}:
> >   - Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
> >     is 'mvarValue' really a valid object?
> >     I guess it is null!
> >   - byte[] aValue = mvarValue as byte[];
> >      this line only works for binary registry values,
> >      but you may have other types, too?



Sat, 02 Oct 2004 18:51:38 GMT  
 Reading Binary Data from the Registry
NETMaster,

I did do a step-by-step debug and here are the results:


RegistryKey mvarRegKey =
Registry.CurrentUser.OpenSubKey(mvarRegPath.ToString());
string[] mvarValNames = mvarRegKey.GetValueNames();

for (int i = 0;i < mvarValNames.Length;i++)
{
    try
    {
        Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
        byte[] aValue = mvarValue as byte[];
        int iSize = aValue.Length;
         IntPtr buffer = Marshal.AllocHGlobal(iSize);
        Marshal.Copy(aValue, 0, buffer, iSize);
        RegDServer mvarRegDSvr = (RegDServer) Marshal.PtrToStructure(buffer,
typeof(RegDServer));   // The error occurs here!!!
        Marshal.FreeHGlobal(buffer);
        LoadRegDServer(mvarRegDSvr);
    }
    catch (Exception e)
    {
        Debug.WriteLine("Error: " + e.Message);
    }

Quote:
}

mvarRegKey.Close();

The error message is as follows:
Object reference not set to an instance of an object

Everything seems to work great up to the point where the buffer is getting
mashalled to the struct. Then is throws the exception. I can see the bytes
in the array and the length of the array and everything, even the buffer
pointer value.

Thank you for your time!

Richard


Quote:
> > Have you ever had to use the System.Security.Permissions namespace
> NO

> > some sort of security issues
> Most registry keys can be read by common users (but not written).
> If you just use OpenSubKey("x"), the key is read-only, you can't write.
> Also check permission with regedt32

> I recommend step-by-step debugging, and post the EXACT behavior you see.




- Show quoted text -

Quote:
> > I am beginning to wonder if there is some sort of security issues I
should
> > be considering here. Have you ever had to use the
> > System.Security.Permissions namespace to get the code running? If so, do
you
> > know of an example on how to use it?
> > > You should check with de{*filter*}:
> > >   - Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
> > >     is 'mvarValue' really a valid object?
> > >     I guess it is null!
> > >   - byte[] aValue = mvarValue as byte[];
> > >      this line only works for binary registry values,
> > >      but you may have other types, too?



Sun, 03 Oct 2004 02:49:11 GMT  
 Reading Binary Data from the Registry
sorry, but it's a bit difficult to follow...
 - In your previous post, you had the problem at line:  byte[] ...
   now on PtrToStructure ? why?

 - You didn't include the definition of your 'RegDServer' struct!

 - and also better do check for buffer size equals struct size:

// CHECK SIZE! --------------------------
 int iSize = aValue.Length;
 IntPtr buffer = Marshal.AllocHGlobal(iSize);
 Marshal.Copy(aValue, 0, buffer, iSize);

 // NEW: verify size
  int rgdssize = Marshal.SizeOf(typeof(RegDServer));
  if( rgdssize != iSize )
   return;  // fail or throw exception

 RegDServer mvarRegDSvr = (RegDServer) Marshal.PtrToStructure(buffer,
  typeof(RegDServer));   // The error occurs here!!!

// --------------------------

Quote:


> RegistryKey mvarRegKey =
> Registry.CurrentUser.OpenSubKey(mvarRegPath.ToString());
> string[] mvarValNames = mvarRegKey.GetValueNames();

> for (int i = 0;i < mvarValNames.Length;i++)
> {
>     try
>     {
>         Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
>         byte[] aValue = mvarValue as byte[];
>         int iSize = aValue.Length;
>          IntPtr buffer = Marshal.AllocHGlobal(iSize);
>         Marshal.Copy(aValue, 0, buffer, iSize);
>         RegDServer mvarRegDSvr = (RegDServer) Marshal.PtrToStructure(buffer,
> typeof(RegDServer));   // The error occurs here!!!
>         Marshal.FreeHGlobal(buffer);
>         LoadRegDServer(mvarRegDSvr);
>     }
>     catch (Exception e)
>     {
>         Debug.WriteLine("Error: " + e.Message);
>     }
> }
> mvarRegKey.Close();

> The error message is as follows:
> Object reference not set to an instance of an object
> Everything seems to work great up to the point where the buffer is getting
> mashalled to the struct. Then is throws the exception. I can see the bytes
> in the array and the length of the array and everything, even the buffer
> pointer value.



Sun, 03 Oct 2004 18:32:44 GMT  
 Reading Binary Data from the Registry
NETMaster,

I think that was it. When I compared the sizes the were completely
different.

Here is original Type from VB that the reg values were written it:

Type RegdServer
    Key As String * 25
    ServerName As String * 25
    Login As String * 25
    Password As String * 25
    ServerVersion As String * 12
    UseTrustedConnection As Boolean
    AdminLogin As Boolean
    SQLServerName As String * 25
    AppDBName As String * 25
    IAppDBName As String * 25
    SysDBName As String * 25
    PollingInterval As Long
    CompanyID As String * 3
    LangID As Long
End Type

FIXED LENGTH STRINGS!!

But, with C# the struct is as follows:

[StructLayout(LayoutKind.Sequential,Pack=2)]
public struct RegDServer
{
 public string Key;
 public string ServerName;
 public string Login;
 public string Password;
 public string ServerVersion;
 public bool UseTrustedConnection;
 public bool AdminLogin;
 public string SQLServerName;
 public string AppDBName;
 public string IAppDBName;
 public string SysDBName;
 public int PollingInterval;
 public string CompanyID;
 public int LangaugeID;

Quote:
}

No fixed length string, of course you can't do that in C#. The original is
227 bytes and the C# one is 56.

I will try pursuing this in another route. Maybe writing the struct to the
regsitry in C# before reading it.

I do appreciate you time, effort and patience.

If you have any suggestions, I would appreciate it.

Thanks again!!
Richard


Quote:
> sorry, but it's a bit difficult to follow...
>  - In your previous post, you had the problem at line:  byte[] ...
>    now on PtrToStructure ? why?

>  - You didn't include the definition of your 'RegDServer' struct!

>  - and also better do check for buffer size equals struct size:

> // CHECK SIZE! --------------------------
>  int iSize = aValue.Length;
>  IntPtr buffer = Marshal.AllocHGlobal(iSize);
>  Marshal.Copy(aValue, 0, buffer, iSize);

>  // NEW: verify size
>   int rgdssize = Marshal.SizeOf(typeof(RegDServer));
>   if( rgdssize != iSize )
>    return;  // fail or throw exception

>  RegDServer mvarRegDSvr = (RegDServer) Marshal.PtrToStructure(buffer,
>   typeof(RegDServer));   // The error occurs here!!!

> // --------------------------




Quote:

> > RegistryKey mvarRegKey =
> > Registry.CurrentUser.OpenSubKey(mvarRegPath.ToString());
> > string[] mvarValNames = mvarRegKey.GetValueNames();

> > for (int i = 0;i < mvarValNames.Length;i++)
> > {
> >     try
> >     {
> >         Object mvarValue = mvarRegKey.GetValue(mvarValNames[i]);
> >         byte[] aValue = mvarValue as byte[];
> >         int iSize = aValue.Length;
> >          IntPtr buffer = Marshal.AllocHGlobal(iSize);
> >         Marshal.Copy(aValue, 0, buffer, iSize);
> >         RegDServer mvarRegDSvr = (RegDServer)

Marshal.PtrToStructure(buffer,

- Show quoted text -

Quote:
> > typeof(RegDServer));   // The error occurs here!!!
> >         Marshal.FreeHGlobal(buffer);
> >         LoadRegDServer(mvarRegDSvr);
> >     }
> >     catch (Exception e)
> >     {
> >         Debug.WriteLine("Error: " + e.Message);
> >     }
> > }
> > mvarRegKey.Close();

> > The error message is as follows:
> > Object reference not set to an instance of an object
> > Everything seems to work great up to the point where the buffer is
getting
> > mashalled to the struct. Then is throws the exception. I can see the
bytes
> > in the array and the length of the array and everything, even the buffer
> > pointer value.



Mon, 04 Oct 2004 05:52:23 GMT  
 Reading Binary Data from the Registry

Quote:
>>No fixed length string, of course you can't do that in C#.

C# yes, but the .NET marshaler has fixed size strings!

NOTE:
 - strings with 'SizeConst=' include 1 zero terminator,
   so your field 'CompanyID' can have max. 2 char like "XX"
   (tell me if this is a problem for you, I can help)

 - VB6 'Boolean' is 2 byte, have to use 'short' in C# and
   use your own logic. (don't know VB6 equivalent well)

I verified this, it is exactly 227 bytes in size:

[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
public struct RegDServer
 {
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
 public string Key;
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
 public string ServerName;
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
 public string Login;
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
 public string Password;
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=12)]
 public string ServerVersion;
 public short UseTrustedConnection;
 public short AdminLogin;
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
 public string SQLServerName;
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
 public string AppDBName;
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
 public string IAppDBName;
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
 public string SysDBName;
 public int PollingInterval;
  [MarshalAs( UnmanagedType.ByValTStr, SizeConst=3)]
 public string CompanyID;
 public int LangaugeID;
 }

--
  NETMaster  (Thomas Scheidegger)
  http://www.cetus-links.org/oo_csharp.html

Quote:

> I think that was it. When I compared the sizes the were completely
> different.
> Here is original Type from VB that the reg values were written it:
> Type RegdServer
>     Key As String * 25
>     ServerName As String * 25
>     Login As String * 25
>     Password As String * 25
>     ServerVersion As String * 12
>     UseTrustedConnection As Boolean
>     AdminLogin As Boolean
>     SQLServerName As String * 25
>     AppDBName As String * 25
>     IAppDBName As String * 25
>     SysDBName As String * 25
>     PollingInterval As Long
>     CompanyID As String * 3
>     LangID As Long
> End Type
> No fixed length string, of course you can't do that in C#. The original is
> 227 bytes and the C# one is 56.



Mon, 04 Oct 2004 19:27:49 GMT  
 Reading Binary Data from the Registry
VB6 -1 true 0 false

Cromas


Quote:
> >>No fixed length string, of course you can't do that in C#.

> C# yes, but the .NET marshaler has fixed size strings!

> NOTE:
>  - strings with 'SizeConst=' include 1 zero terminator,
>    so your field 'CompanyID' can have max. 2 char like "XX"
>    (tell me if this is a problem for you, I can help)

>  - VB6 'Boolean' is 2 byte, have to use 'short' in C# and
>    use your own logic. (don't know VB6 equivalent well)

> I verified this, it is exactly 227 bytes in size:

> [StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
> public struct RegDServer
>  {
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
>  public string Key;
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
>  public string ServerName;
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
>  public string Login;
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
>  public string Password;
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=12)]
>  public string ServerVersion;
>  public short UseTrustedConnection;
>  public short AdminLogin;
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
>  public string SQLServerName;
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
>  public string AppDBName;
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
>  public string IAppDBName;
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=25)]
>  public string SysDBName;
>  public int PollingInterval;
>   [MarshalAs( UnmanagedType.ByValTStr, SizeConst=3)]
>  public string CompanyID;
>  public int LangaugeID;
>  }

> --
>   NETMaster  (Thomas Scheidegger)
>   http://www.cetus-links.org/oo_csharp.html




- Show quoted text -

Quote:
> > I think that was it. When I compared the sizes the were completely
> > different.
> > Here is original Type from VB that the reg values were written it:
> > Type RegdServer
> >     Key As String * 25
> >     ServerName As String * 25
> >     Login As String * 25
> >     Password As String * 25
> >     ServerVersion As String * 12
> >     UseTrustedConnection As Boolean
> >     AdminLogin As Boolean
> >     SQLServerName As String * 25
> >     AppDBName As String * 25
> >     IAppDBName As String * 25
> >     SysDBName As String * 25
> >     PollingInterval As Long
> >     CompanyID As String * 3
> >     LangID As Long
> > End Type
> > No fixed length string, of course you can't do that in C#. The original
is
> > 227 bytes and the C# one is 56.



Fri, 08 Oct 2004 03:30:57 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. Read/Set Binary Data in registry

2. How to read Binary/Hex data from the registry

3. How to read Binary/Hex data from the registry

4. How can I write binary-data to registry?

5. Reading binary registry value

6. Read a binary value from the registry

7. How to write binary data into the registry?

8. How to write a binary data in registry

9. Store Binary Data in Registry

10. Read data from registry - very need.

11. How can I read data from Sysytem Registry ?

12. Reading and writing binary data

 

 
Powered by phpBB® Forum Software