You mentioned the desire for "serial number" and "type." There is no "type", but there is a manufacturer identifier and a product identifier. For the most part, they are not stored as meaningful strings in the information you return ... they are just numeric values. And they are all in the first 16 bytes.
I will decode the beginning according to the specification you are quoting.
Bytes 0,1,2,3,4,5,6,7 - Header Information
This should be the literal string "00h FFh FFh FFh FFh FFh FFh 00h", which serves as a health check that we are considering a valid EDID block. Your data begins exactly with what we expect:
00 FF FF FF FF FF FF 00
Bytes 8 and 9 - The identifier of the manufacturer.
These identifiers are assigned by Microsoft and are three-letter codes. Of course, they could "spend" three integer bytes in ASCII for this. But that would be too reasonable. Thus, they collected eight bytes on an extremely “non-magic” header number and invented a “brilliant” way to encode these three letters into sixteen bits stored in two bytes. How did they take it off?
+--------+--------+ | Byte 8 | Byte 9 | --------+--------+--------+ Bit
Thus, the high-order bit of byte 8 is always zero, and the remaining 15 bits are divided into three groups of 5 bits each (which I named α, β, and γ). Each of them is interpreted as a letter, where "00001 = A"; "00010 = B"; ... "11010 = Z".
You have:
10 AC
And the hexadecimal 10AC , expressed as 16 binary bits, is 0001000010101100 . So bring this table back:
+--------+--------+ | Byte 8 | Byte 9 | --------+--------+--------+ Bit
So α = 00100 (decimal number 4), β = 00101 (decimal number 5), γ = 01100 (decimal number 12). Using these decimal numbers as indices in the English alphabet, we get DEL. Thanks to this magical witchcraft, we determined that your monitor was most likely made by Dell. :)
Bytes 10 and 11 - Product Identifier Code
This is a two-byte number assigned by the manufacturer, which is stored as "LSB first". This means that the first byte is the least significant place value. You have:
4C 40
What we need to interpret as a 404C hexadecimal number.
Byte 12,13,14,15 - Serial number.
This is a 32-bit value assigned by the manufacturer and does not require a format. It is "usually stored as LSB first", but not required.
53 43 34 42
You can interpret this as 0x53433442 , or 0x42344353 , or something else ... as long as you are incompatible in comparing one value with another.
So, now you see only three letters and some numbers. Once you get the bytes into the buffer, there are many ways to extract information. @freerider provided some information about this, I will just add a little more.
The EDID standard says that what you get as a description is 128 bytes. This applies to the registry key, and you can probably assume that if 128 bytes are not corrupted, this is damage. So, using the code provided by @freerider, you wouldn't have to skip anything more than that ... you could technically go down to just 16 if that is the only part of the EDID that you are interested in:
#define EDID_BUFFER_SIZE 128 // in idiomatic C++ it 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 }
(Note: I prefer to avoid using sizeof on arrays like @freerider sizeof( Buffer ) above. Although this will technically work in this case, it does not return the number of elements in the array ... rather the number of bytes that the array occupies in memory . In this case, the elements are actually bytes, so they will work .. but you quickly run into problems, for example, when you pass an array to another function with a pointer, and suddenly it starts reporting its size as the size of the pointer ...)
Also, your question about how to extract structural data from a byte buffer is very general and so fundamental to C-style programming that if you don’t know where to start, then you should probably work through simpler programs . Getting three five-bit segments from the manufacturer’s name includes things like bit offsets, bit masking, or bit fields. Array traversal addresses addresses and indexing methods of arrays, etc.
The closest parallel question I could find right now is this:
extract IP from byte buffer
There are many ways to do this, but the interesting thing is that you can define the layout of the structure in memory and then tell the program “hey, this memory block that I found is laid out just like I defined the structure. So let me extract the information from it just as if I defined an object in my program "...
But then you should be sensitive to issues such as data structure alignment. This is because the way your compiler naturally places objects in memory does not necessarily match what you think it will do:
http://en.wikipedia.org/wiki/Data_structure_alignment
With the information above, you can at least take a picture while reading some lessons and find out what works. If you cannot understand one part of the problem, then break this small part as your own question and show what you tried and why it did not work ...