Вот моя реализация (FYI, СПФ содержит весь этот код и многое другое)
internal class NDISQueryOid
{
protected const int NDISUIO_QUERY_OID_SIZE = 12;
protected byte[] m_data;
public int Size { get; private set; }
public NDISQueryOid(byte[] data)
{
int extrasize = data.Length;
Size = 8 + extrasize;
m_data = new byte[Size];
Buffer.BlockCopy(data, 0, m_data, DataOffset, data.Length);
}
public NDISQueryOid(int extrasize)
{
Size = NDISUIO_QUERY_OID_SIZE + extrasize;
m_data = new byte[Size];
}
protected const int OidOffset = 0;
public uint Oid
{
get { return BitConverter.ToUInt32(m_data, OidOffset); }
set
{
byte[] bytes = BitConverter.GetBytes(value);
Buffer.BlockCopy(bytes, 0, m_data, OidOffset, 4);
}
}
protected const int ptcDeviceNameOffset = OidOffset + 4;
public unsafe byte* ptcDeviceName
{
get
{
return (byte*)BitConverter.ToUInt32(m_data, ptcDeviceNameOffset);
}
set
{
byte[] bytes = BitConverter.GetBytes((UInt32)value);
Buffer.BlockCopy(bytes, 0, m_data, ptcDeviceNameOffset, 4);
}
}
protected const int DataOffset = ptcDeviceNameOffset + 4;
public byte[] Data
{
get
{
byte[] b = new byte[Size - DataOffset];
Array.Copy(m_data, DataOffset, b, 0, Size - DataOffset);
return b;
}
set
{
Size = 8 + value.Length;
m_data = new byte[Size];
Buffer.BlockCopy(value, 0, m_data, DataOffset, value.Length);
}
}
public byte[] getBytes()
{
return m_data;
}
public static implicit operator byte[](NDISQueryOid qoid)
{
return qoid.m_data;
}
}
Заметим, что в моем использовании, NDIS IOCT принимает указатель (большая часть моей NDIS работы все сделанные как небезопасные), поэтому вам нужно будет немного подкорректировать.
Так что если, например, вы запрашивая BSSID, я знаю, что данные BSSID 36 байт, так что я бы создать что-то вроде этого:
var queryOID = new NDISQueryOid(36);
затем выделить имя и вызвать NDIS (код производства имеет гораздо больше, чем это проверка):
byte[] nameBytes = System.Text.Encoding.Unicode.GetBytes(adapterName + '\0');
fixed (byte* pName = &nameBytes[0])
{
queryOID.ptcDeviceName = pName;
queryOID.Oid = (uint)oid;
var bytes = queryOID.getBytes();
ndis.DeviceIoControl(IOCTL_NDISUIO_QUERY_OID_VALUE, bytes, bytes);
var result = new byte[queryOID.Data.Length];
Buffer.BlockCopy(queryOID.Data, 0, result, 0, result.Length);
}
EDIT
Так result
член выше является байтовым массивом «результата» запроса.Что это значит и как вы это интерпретируете, зависит от того, что было запрошено OID. Например, если вы запрашивая в настоящее время подключенного SSID (т.е. NDIS_OID.SSID
), то, что возвращается в длину 4 байта, за которым следует имя ASCII кодировке, так что вы бы расшифровать так:
int len = BitConverter.ToInt32(data, 0);
if (len > 0)
{
ssid = System.Text.Encoding.ASCII.GetString(data, 4, len);
}
Но опять же, это только для одного конкретного OID. Вы должны обрабатывать каждый случай возврата для каждого входящего OID, который вы решите поддержать.
Можете привести более подробную информацию. Кажется, что на родной стороне у вас есть 4-байтовый буфер, Data, в который вы нажимаете 8 байтов. Как это может работать? Кто что выделяет? –
@DavidHeffernan Привет SRY за поздний ответ :(Я буду обновлять Qn .. – arya2arya
@DavidHeffernan Подобным же образом, как и в C++, Можно ли в C# ?? Я пытаюсь путем преобразования структуры в PTR, а затем используя Marshal.copy() – arya2arya