Вы упоминаете, что хотите "серийный номер" и "тип".Здесь нет «типа», но есть идентификатор производителя и идентификатор продукта.По большей части они не хранятся в виде значимых строк в информации, которую вы возвращаете ... они просто числовые значения.И все они в первых 16 байтах.
Я буду декодировать начало в соответствии со спецификацией, которую вы цитируете.
Байты 0,1,2,3, 4,5,6,7 - Информация заголовка
Это должна быть буквальная строка «00h FFh FFh FFh FFh FFh FFh 00h», которая служит проверкой работоспособности, которую мы смотрим надействительный блок EDID.Ваши данные начинаются с того, что мы ожидаем:
00 FF FF FF FF FF FF 00
Байты 8 и 9 - Идентификатор производителя.
Эти идентификаторы назначаются Microsoft и имеют трибуквенные коды.О, конечно, они могли бы "потратить" три целых байта в ASCII для этого.Но это было бы слишком разумно.Таким образом, они отбросили восемь байтов чрезвычайно «немагического» числа для заголовка и изобрели «оригинальный» способ кодировать эти три буквы в шестнадцать битов, содержащихся в двух байтах.Как они справились?
+--------+--------+
| Byte 8 | Byte 9 |
--------+--------+--------+
Bit # 76543210 76543210
-----------------=---------
Meaning 0αααααββ βββγγγγγ
Таким образом, бит старшего разряда байта 8 всегда равен нулю, а оставшиеся 15 бит разделены на три группы по 5 бит (которые я назвал α, β и γ).Каждый интерпретируется как буква, где «00001 = A»;"00010 = В";... "11010 = Z".
Вы получили:
10 AC
И шестнадцатеричное 10AC
, выраженное в 16 двоичных разрядах, равно 0001000010101100
.Итак, давайте снова вернем эту таблицу:
+--------+--------+
| Byte 8 | Byte 9 |
--------+--------+--------+
Bit # 76543210 76543210
-----------------=---------
Meaning 0αααααββ βββγγγγγ
-----------------=---------
Yours 00010000 10101100
Итак α = 00100
(десятичный 4), β = 00101
(десятичный 5), γ = 01100
(десятичный 12).Используя эти десятичные числа в качестве указателей на английский алфавит, мы получаем DEL.По этому тайному колдовству мы определили, что ваш монитор, скорее всего, сделан Dell.:)
Байты 10 и 11 - Идентификатор продукта Код
Это двухбайтовый номер, назначенный производителем и сохраненный как «LSB first».Это означает, что первый байт является наименее значимым значением места.У вас есть:
4C 40
Который нам нужно интерпретировать как шестнадцатеричное число 404C
.
Байт 12,13,14,15 - Серийный номер.
Это 32-разрядное значение, назначенное производителем, которое не имеет требований к формату.Он «обычно сохраняется как младший бит», но не обязательно.
53 43 34 42
Вы можете интерпретировать это как 0x53433442
, или 0x42344353
, или как угодно ... до тех пор, пока выпоследовательны в сравнении одного значения с другим.
Итак, теперь вы видите, что это всего три буквы и несколько цифр.Как только вы помещаете байты в буфер, есть много способов извлечь информацию.@freerider предоставил некоторую информацию об этом, я просто добавлю немного больше.
Стандарт EDID говорит, что в качестве описания вы получите 128 байтов.Это относится к разделу реестра, и вы, вероятно, можете предположить, что, если нет точно 128 байтов, он поврежден.Таким образом, используя код, предоставленный @freerider, не нужно было бы передавать что-то большее, чем это ... технически вы могли бы опуститься до 16, если это единственная часть EDID, которая вас интересует:
#define EDID_BUFFER_SIZE 128
// in idiomatic C++ it's better to say:
// const size_t edidBufferSize = 128;
BYTE edidBuffer[EDID_BUFFER_SIZE];
DWORD nLength = GetLocalMachineProfileBuffer( Buffer, EDID_BUFFER_SIZE );
if (nLength != EDID_BUFFER_SIZE) {
// handle error case, not a valid EDID block
} else {
// valid EDID block, do extraction:
// * manufacturer ID
// * product ID
// * serial number
}
(Примечание: я предпочитаю избегать использования sizeof
для массивов, таких как @ freerider's sizeof( Buffer )
выше. Хотя это технически будет работать в этом случае, оно не возвращает количество элементов вмассив ... скорее количество байтов, которое массив занимает в памяти . В этом случае элементы оказываются фактически байтами, так что это будет работать ... но вы быстро сталкиваетесь с проблемами, как когда выпередать массив в другую функцию по указателю, и вдруг он начинает сообщать свой размер как размер указателя ...)
Кроме того, ваш вопрос о том, как извлечь структурные данные из буфера байтов, является очень общим и настолько фундаментальным для программирования в стиле C, что если вы не знаете, с чего начать, то вам, вероятно, следуетработать через более простые программы.Получение трех пятибитных сегментов из названия производителя включает такие вещи, как смещение битов, маскирование битов или битовые поля.Прохождение массива имеет дело с адресами и с тем, как индексировать массивы и тому подобное.
Ближайший параллельный вопрос, который я мог бы найти сейчас, заключается в следующем:
извлечение IP из буферабайт
Множество способов сделать это, но интересным является то, что вы можете определить расположение структуры в памяти и затем сказать программе: «Эй, этот блок памяти, который я нашел, заложенкак структура, которую я определил. Итак, позвольте мне извлечь информацию из нее так же просто, как если бы я определил объект в моей программе "...
Но тогда вы должны быть чувствительны к таким вопросам, как структура данныхвыравнивание.Это связано с тем, что способ, которым ваш компилятор естественным образом помещает объекты в память, не обязательно соответствует тому, что вы думаете:
http://en.wikipedia.org/wiki/Data_structure_alignment
С приведенной выше информацией вы по крайней мере сможетепопробуйте прочитать некоторые учебники и посмотреть, что работает.Если вы не можете понять одну часть проблемы, выделите эту небольшую часть как отдельный вопрос и покажите, что вы пытались и почему она не сработала ...