[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.interop

How can I translate a DWORD to a .NET object?

ssg31415926

11/15/2007 9:11:00 AM

I have a byte array and I'm trying to translate a DWORD in that array
into an integer so that I can use it as an offset into a later part of
the array. Once I get the offset, I've successfully worked out how to
translate the offset part into a string but I can't work out how to
translate the offset itself.

I'm trying to interpret this structure:

typedef struct {
CLSID clsidNamespace;
UINT cItems;
DSOBJECT aObjects[1];
} DSOBJECTNAMES,
*LPDSOBJECTNAMES;

which contains count cItems of this structure:

typedef struct {
DWORD dwFlags;
DWORD dwProviderFlags;
DWORD offsetName;
DWORD offsetClass;
} DSOBJECT,
*LPDSOBJECT;
5 Answers

ssg31415926

11/15/2007 11:18:00 AM

0

I think I've figured it out by going back to basics and going through
the byte array byte-by-byte. It seems that I should translate it like
this:

byte1 + byte2 * 256 + byte3 * 65536 + byte4 * 16777216

or
double offset = 0;
for (int j = 0; j < 4; j++)
{
offset = offset + Math.Pow(256, j) * offsetBytes[j];
}
return (uint)offset;

where offsetBytes is the byte array with the relevant values.

Still, I feel that there should be a built-in way of doing this as it
must be quite common. E.g. I need it to write an extension property
sheet in a MMC 3.0 extension to Active Directory Users and Computers.

One further question: should I be using the same method to translate
the uint in the DSOBJECTNAMES structure?

ssg31415926 wrote:
> I have a byte array and I'm trying to translate a DWORD in that array
> into an integer so that I can use it as an offset into a later part of
> the array. Once I get the offset, I've successfully worked out how to
> translate the offset part into a string but I can't work out how to
> translate the offset itself.
>
> I'm trying to interpret this structure:
>
> typedef struct {
> CLSID clsidNamespace;
> UINT cItems;
> DSOBJECT aObjects[1];
> } DSOBJECTNAMES,
> *LPDSOBJECTNAMES;
>
> which contains count cItems of this structure:
>
> typedef struct {
> DWORD dwFlags;
> DWORD dwProviderFlags;
> DWORD offsetName;
> DWORD offsetClass;
> } DSOBJECT,
> *LPDSOBJECT;

martin

11/15/2007 12:10:00 PM

0

DWORD is defined in winDef.h to be a "unsigned long". A long in turn can be
defined to be 32-bit or 64-bit depending on the underlying processor. In C#
if you need to represent a value which is either 32 or 64-bit then you should
use IntPtr (or possibly UIntPtr). Basicly, the IntPtr type is an
encapsulation of a 32 or 64 value.

To complicate things further, an integer value can be encoded in either
little endian or big endian byte order. The multiplication example you
provided above is hardcoding one of these (which may or may not be what you
want). As you probably know, pretty much all PCs use little endian byte order
(while SPARC etc use big endian). Also for network packages it's common to
use big endian byte order.

A really nice way to handle this mess in C# is to create a MemoryStream
object which points to the relevant byte array:
http://msdn2.microsoft.com/en-us/library/63z...

Then you create a corresponding BinaryReader object and use the
..ReadUInt32() or .ReadUInt64() methods to fetch the data:
http://msdn2.microsoft.com/en-us/library/system.io.binaryreader_me...

Note: BinaryReader uses little endian only but you can choose to use
different character encodings (such as UNICODE, UTF8 etc) in conjunction with
the ReadChar/ReadString methods.


Martin


"ssg31415926" wrote:
> I think I've figured it out by going back to basics and going through
> the byte array byte-by-byte. It seems that I should translate it like
> this:
>
> byte1 + byte2 * 256 + byte3 * 65536 + byte4 * 16777216
>
> or
> double offset = 0;
> for (int j = 0; j < 4; j++)
> {
> offset = offset + Math.Pow(256, j) * offsetBytes[j];
> }
> return (uint)offset;
>
> where offsetBytes is the byte array with the relevant values.
>
> Still, I feel that there should be a built-in way of doing this as it
> must be quite common. E.g. I need it to write an extension property
> sheet in a MMC 3.0 extension to Active Directory Users and Computers.
>
> One further question: should I be using the same method to translate
> the uint in the DSOBJECTNAMES structure?
>
> ssg31415926 wrote:
> > I have a byte array and I'm trying to translate a DWORD in that array
> > into an integer so that I can use it as an offset into a later part of
> > the array. Once I get the offset, I've successfully worked out how to
> > translate the offset part into a string but I can't work out how to
> > translate the offset itself.
> >
> > I'm trying to interpret this structure:
> >
> > typedef struct {
> > CLSID clsidNamespace;
> > UINT cItems;
> > DSOBJECT aObjects[1];
> > } DSOBJECTNAMES,
> > *LPDSOBJECTNAMES;
> >
> > which contains count cItems of this structure:
> >
> > typedef struct {
> > DWORD dwFlags;
> > DWORD dwProviderFlags;
> > DWORD offsetName;
> > DWORD offsetClass;
> > } DSOBJECT,
> > *LPDSOBJECT;
>

Christian Fröschlin

11/15/2007 12:44:00 PM

0


> DWORD is defined in winDef.h to be a "unsigned long". A long in turn can be
> defined to be 32-bit or 64-bit depending on the underlying processor.

I was under the impression that a C/C++ long on Windows means 32-bit
even on 64-bit platforms, at least when using Microsoft or compatible
compilers. So don't expect to be able to store pointers in longs ;-)

ssg31415926

11/15/2007 1:30:00 PM

0

Thanks very much for this. It appears to do exactly what I need.

Do you think I should be using the same mechanism to read the UINT in
the first struct?

The strings are null-terminated. At the moment, my code starts from
the offset and reads until it finds two consecutive 00s and stops.
Again, this works but it doesn't strike me as good code. Is there a
standard way of extracting a string?

martin wrote:
> DWORD is defined in winDef.h to be a "unsigned long". A long in turn can be
> defined to be 32-bit or 64-bit depending on the underlying processor. In C#
> if you need to represent a value which is either 32 or 64-bit then you should
> use IntPtr (or possibly UIntPtr). Basicly, the IntPtr type is an
> encapsulation of a 32 or 64 value.
>
> To complicate things further, an integer value can be encoded in either
> little endian or big endian byte order. The multiplication example you
> provided above is hardcoding one of these (which may or may not be what you
> want). As you probably know, pretty much all PCs use little endian byte order
> (while SPARC etc use big endian). Also for network packages it's common to
> use big endian byte order.
>
> A really nice way to handle this mess in C# is to create a MemoryStream
> object which points to the relevant byte array:
> http://msdn2.microsoft.com/en-us/library/63z...
>
> Then you create a corresponding BinaryReader object and use the
> .ReadUInt32() or .ReadUInt64() methods to fetch the data:
> http://msdn2.microsoft.com/en-us/library/system.io.binaryreader_me...
>
> Note: BinaryReader uses little endian only but you can choose to use
> different character encodings (such as UNICODE, UTF8 etc) in conjunction with
> the ReadChar/ReadString methods.
>
>
> Martin
>
>
> "ssg31415926" wrote:
> > I think I've figured it out by going back to basics and going through
> > the byte array byte-by-byte. It seems that I should translate it like
> > this:
> >
> > byte1 + byte2 * 256 + byte3 * 65536 + byte4 * 16777216
> >
> > or
> > double offset = 0;
> > for (int j = 0; j < 4; j++)
> > {
> > offset = offset + Math.Pow(256, j) * offsetBytes[j];
> > }
> > return (uint)offset;
> >
> > where offsetBytes is the byte array with the relevant values.
> >
> > Still, I feel that there should be a built-in way of doing this as it
> > must be quite common. E.g. I need it to write an extension property
> > sheet in a MMC 3.0 extension to Active Directory Users and Computers.
> >
> > One further question: should I be using the same method to translate
> > the uint in the DSOBJECTNAMES structure?
> >
> > ssg31415926 wrote:
> > > I have a byte array and I'm trying to translate a DWORD in that array
> > > into an integer so that I can use it as an offset into a later part of
> > > the array. Once I get the offset, I've successfully worked out how to
> > > translate the offset part into a string but I can't work out how to
> > > translate the offset itself.
> > >
> > > I'm trying to interpret this structure:
> > >
> > > typedef struct {
> > > CLSID clsidNamespace;
> > > UINT cItems;
> > > DSOBJECT aObjects[1];
> > > } DSOBJECTNAMES,
> > > *LPDSOBJECTNAMES;
> > >
> > > which contains count cItems of this structure:
> > >
> > > typedef struct {
> > > DWORD dwFlags;
> > > DWORD dwProviderFlags;
> > > DWORD offsetName;
> > > DWORD offsetClass;
> > > } DSOBJECT,
> > > *LPDSOBJECT;
> >

martin

11/15/2007 2:19:00 PM

0

Ops... you're absolutely right Christian:
http://msdn2.microsoft.com/en-us/library/aa3...

Thanks for the clarification.




Martin


"Christian Fröschlin" wrote:
>
> > DWORD is defined in winDef.h to be a "unsigned long". A long in turn can be
> > defined to be 32-bit or 64-bit depending on the underlying processor.
>
> I was under the impression that a C/C++ long on Windows means 32-bit
> even on 64-bit platforms, at least when using Microsoft or compatible
> compilers. So don't expect to be able to store pointers in longs ;-)
>