Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a structure to a byte array in C#?

Tags:

c#

struct

How do I convert a structure to a byte array in C#?

I have defined a structure like this:

public struct CIFSPacket {     public uint protocolIdentifier; //The value must be "0xFF+'SMB'".     public byte command;      public byte errorClass;     public byte reserved;     public ushort error;      public byte flags;      //Here there are 14 bytes of data which is used differently among different dialects.     //I do want the flags2. However, so I'll try parsing them.     public ushort flags2;      public ushort treeId;     public ushort processId;     public ushort userId;     public ushort multiplexId;      //Trans request     public byte wordCount;//Count of parameter words defining the data portion of the packet.     //From here it might be undefined...      public int parametersStartIndex;      public ushort byteCount; //Buffer length     public int bufferStartIndex;      public string Buffer; } 

In my main method, I create an instance of it and assign values to it:

CIFSPacket packet = new CIFSPacket(); packet.protocolIdentifier = 0xff; packet.command = (byte)CommandTypes.SMB_COM_NEGOTIATE; packet.errorClass = 0xff; packet.error = 0; packet.flags = 0x00; packet.flags2 = 0x0001; packet.multiplexId = 22; packet.wordCount = 0; packet.byteCount = 119;  packet.Buffer = "NT LM 0.12"; 

Now I want to send this Packet by socket. For that, I need to convert the structure to a byte array. How can I do it?

My full code is as follows.

static void Main(string[] args) {    Socket MyPing = new Socket(AddressFamily.InterNetwork,   SocketType.Stream , ProtocolType.Unspecified ) ;     MyPing.Connect("172.24.18.240", 139);      //Fake an IP Address so I can send with SendTo     IPAddress IP = new IPAddress(new byte[] { 172,24,18,240 });     IPEndPoint IPEP = new IPEndPoint(IP, 139);      //Local IP for Receiving     IPEndPoint Local = new IPEndPoint(IPAddress.Any, 0);     EndPoint EP = (EndPoint)Local;      CIFSPacket packet = new CIFSPacket();     packet.protocolIdentifier = 0xff;     packet.command = (byte)CommandTypes.SMB_COM_NEGOTIATE;     packet.errorClass = 0xff;     packet.error = 0;     packet.flags = 0x00;     packet.flags2 = 0x0001;     packet.multiplexId = 22;     packet.wordCount = 0;     packet.byteCount = 119;      packet.Buffer = "NT LM 0.12";      MyPing.SendTo(It takes byte array as parameter); } 

What would a code snippet be?

like image 231
Swapnil Gupta Avatar asked Jul 19 '10 06:07

Swapnil Gupta


1 Answers

This is fairly easy, using marshalling.

Top of file

using System.Runtime.InteropServices 

Function

byte[] getBytes(CIFSPacket str) {     int size = Marshal.SizeOf(str);     byte[] arr = new byte[size];      IntPtr ptr = Marshal.AllocHGlobal(size);     Marshal.StructureToPtr(str, ptr, true);     Marshal.Copy(ptr, arr, 0, size);     Marshal.FreeHGlobal(ptr);     return arr; } 

And to convert it back:

CIFSPacket fromBytes(byte[] arr) {     CIFSPacket str = new CIFSPacket();      int size = Marshal.SizeOf(str);     IntPtr ptr = Marshal.AllocHGlobal(size);      Marshal.Copy(arr, 0, ptr, size);      str = (CIFSPacket)Marshal.PtrToStructure(ptr, str.GetType());     Marshal.FreeHGlobal(ptr);      return str; } 

In your structure, you will need to put this before a string

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)] public string Buffer; 

And make sure SizeConst is as big as your biggest possible string.

And you should probably read this: http://msdn.microsoft.com/en-us/library/4ca6d5z7.aspx

like image 72
Vincent McNabb Avatar answered Sep 23 '22 02:09

Vincent McNabb