{"id":388,"date":"2009-05-01T10:23:32","date_gmt":"2009-05-01T10:23:32","guid":{"rendered":"https:\/\/driverentry.com.br\/en\/2009\/05\/01\/enumerating-devices\/"},"modified":"2026-07-30T19:55:22","modified_gmt":"2026-07-30T19:55:22","slug":"enumerating-devices","status":"publish","type":"post","link":"https:\/\/driverentry.com.br\/en\/2009\/05\/01\/enumerating-devices\/","title":{"rendered":"Enumerating devices"},"content":{"rendered":"<div style=\"text-align: right;\"><a href=\"https:\/\/driverentry.com.br\/2009\/05\/01\/enumerando-dispositivos\/\"><img loading=\"lazy\" decoding=\"async\" title=\"Em Portugues\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/br.gif\" alt=\"\" width=\"21\" height=\"19\" \/><\/a><\/div>\n<p>Among my current tasks was reading the samples from a gyroscope using a serial port and generating a file with them. This file would be read by a driver similar to the one demonstrated <a href=\"https:\/\/driverentry.com.br\/en\/2009\/04\/01\/reading-files\/\">in the post before this one<\/a>. In the gyroscope&#8217;s <a href=\"http:\/\/pt.wikipedia.org\/wiki\/Datasheet\">datasheet<\/a> there is a description of the protocol, not to mention the example made in Visual Basic that exists on the <a href=\"http:\/\/www.sparkfun.com\/\">manufacturer&#8217;s site<\/a>, which demonstrates the <a href=\"http:\/\/pt.wikipedia.org\/wiki\/Acelera%C3%A7%C3%A3o_angular\">angular acceleration<\/a> on each axis as well as their <a href=\"http:\/\/pt.wikipedia.org\/wiki\/Acelera%C3%A7%C3%A3o\">linear accelerations<\/a> as shown below.<\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/IMU6DOF.png\" alt=\"\" \/><\/div>\n<p><br class=\"spacer_\" \/><\/p>\n<p>The entire interface for configuring and obtaining the gyroscope&#8217;s data is done through the serial port. Even without a dedicated application you can use any program, like HyperTerminal, to access the menus offered by the device. Using a serial port, any microcontroller kit that has no display and not even a keyboard can offer a quite friendly interface.<\/p>\n<p>Writing serial protocols is not something that scares me. What is hard is having to remember how to program a <span style=\"font-style: italic;\">User-Mode<\/span> application that has windows, buttons and other controls, but nothing that a little <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms632587(VS.85).aspx\">MSDN<\/a> does not solve. Driver programmers usually test everything they can using console applications, so I developed a small terminal software to deal directly with the device. Its source follows below and is a bonus for anyone who needs to play with serial ports some day.<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/****<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">***     main<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      And off we go...<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">*\/<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">int<\/span> _tmain(<span style=\"color: blue;\">int<\/span> argc, _TCHAR* argv[])<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">{<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    DWORD           dwBytes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                    dwError = ERROR_SUCCESS;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    HANDLE          hCom;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    ULONG           i;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    UCHAR           ucByteIn[<span style=\"color: purple;\">512<\/span>], ucByteOut;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    DCB             dcb;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    COMMTIMEOUTS    CommTimeouts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Here we open the desired serial port<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    hCom = CreateFile(L<span style=\"color: #a31515;\">\"COM3\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                      GENERIC_READ | GENERIC_WRITE,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                      <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                      NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                      OPEN_EXISTING,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                      <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                      NULL);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Checks whether we succeeded<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">if<\/span> (hCom == INVALID_HANDLE_VALUE) <\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Oops!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        dwError = GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        printf(<span style=\"color: #a31515;\">\"CreateFile failed with error %d.\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                dwError);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">return<\/span> dwError;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; There are 7 kilos of serial port settings.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      Instead of configuring each one of them, we will just<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      get the system default settings and modify<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      only the ones we care about.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">if<\/span> (!GetCommState(hCom, &amp;dcb))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Oops!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        dwError = GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        printf (<span style=\"color: #a31515;\">\"GetCommState failed with error %d.\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                dwError);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        CloseHandle(hCom);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">return<\/span> dwError;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Here we modify the settings to set the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      settings required by the gyroscope.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      57600, 8 N 1 (no flow control)<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    dcb.DCBlength = <span style=\"color: blue;\">sizeof<\/span>(DCB);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    dcb.BaudRate = CBR_57600;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    dcb.ByteSize = <span style=\"color: purple;\">8<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    dcb.Parity = NOPARITY;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    dcb.StopBits = ONESTOPBIT;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    dcb.fDtrControl = DTR_CONTROL_DISABLE;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    dcb.fRtsControl = RTS_CONTROL_DISABLE;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Here we apply the settings we modified<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">if<\/span> (!SetCommState(hCom, &amp;dcb))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Oops!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        dwError = GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        printf (<span style=\"color: #a31515;\">\"SetCommState failed with error %d.\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                dwError);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        CloseHandle(hCom);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">return<\/span> dwError;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; I am going to configure the timeouts so that a<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      read is completed after 100ms even if<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      no character is received by the application.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      This prevents the application from getting stuck in ReadFile<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      until a byte is received by the serial port<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    CommTimeouts.ReadIntervalTimeout = <span style=\"color: purple;\">0<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    CommTimeouts.ReadTotalTimeoutMultiplier = <span style=\"color: purple;\">0<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    CommTimeouts.ReadTotalTimeoutConstant = <span style=\"color: purple;\">100<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    CommTimeouts.WriteTotalTimeoutConstant = <span style=\"color: purple;\">0<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    CommTimeouts.WriteTotalTimeoutMultiplier = <span style=\"color: purple;\">0<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Applies the timeout settings<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">if<\/span> (!SetCommTimeouts(hCom, &amp;CommTimeouts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Oops!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        dwError = GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        printf (<span style=\"color: #a31515;\">\"SetCommTimeouts failed with error %d.\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                dwError);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        CloseHandle(hCom);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">return<\/span> dwError;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Here begins the infinite loop that will run<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      forever and ever until the end of days.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      Actually, if you press [ESC] it ends.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">while<\/span>(<span style=\"color: purple;\">1<\/span>)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Checks whether there is a byte to be received by the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      application in the keyboard buffer.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">if<\/span> (_kbhit())<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Gets the key<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            ucByteOut = _getch();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; Checks whether the received key is [ESC]<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (ucByteOut == <span style=\"color: purple;\">27<\/span>)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                <span style=\"color: blue;\">break<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; Sends the received byte to the serial port<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (!WriteFile(hCom,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                           &amp;ucByteOut,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                           <span style=\"color: purple;\">1<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                           &amp;dwBytes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                           NULL))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                <span style=\"color: green;\">\/\/--&gt; Oops!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                dwError = GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                <span style=\"color: blue;\">break<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Checks whether any byte was received by the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      serial port. Note that in this loop there is no<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      typical Sleep() to keep from driving the CPU<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      to 100%. This wait is performed inside the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      call to ReadFile(). The function waits for a<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      byte for up to 100ms, as configured in the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      timeouts.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: blue;\">if<\/span> (!ReadFile(hCom,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                      ucByteIn,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                      <span style=\"color: blue;\">sizeof<\/span>(ucByteIn),<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                      &amp;dwBytes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                      NULL))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; Oops!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            dwError = GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">break<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Prints the received character sequence on the screen<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: blue;\">for<\/span> (i=<span style=\"color: purple;\">0<\/span>; i&lt;dwBytes; i++)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (ucByteIn[i] == <span style=\"color: purple;\">0x0d<\/span>)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                puts(<span style=\"color: #a31515;\">\"\"<\/span>);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">else<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                printf(<span style=\"color: #a31515;\">\"%c\"<\/span>, ucByteIn[i]);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Well, if we got to this point it is because we reached<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      the end of days or the ESC key was pressed.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      Let us close the serial port and run away.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    CloseHandle(hCom);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">return<\/span> dwError;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">}<\/pre>\n<\/div>\n<p>Opening a serial port is the simplest part of this story; the problem is deciding which port to open. Like any decent program, there should be a combo list with the serial ports available on the computer, where the user would choose one and that is it. From there it is just a matter of getting the port selected by the user and building a call to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa363858(VS.85).aspx\">CreateFile()<\/a> routine as illustrated in the code above.<\/p>\n<p>All right, I dragged the control onto the window I was programming and now I just have to fill it in. So I thought: <span style=\"font-style: italic;\">&#8220;There must be some function like EnumerateCommPorts() in the API&#8221;<\/span>, but that is not what the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa363194(VS.85).aspx\">reference page<\/a> showed me. &#8211; What do you mean there is not one? <a href=\"http:\/\/www.google.com\">Google<\/a> must know something about it. &#8211; I ended up finding out that this is a pretty common question out there. Some solve this problem by making a loop that tries to open the serial ports in sequence (COM1, COM2,&#8230; ), others use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa365461(VS.85).aspx\">QueryDosDevice()<\/a> function and filter the <span style=\"font-style: italic;\">Symbolic Links<\/span> that start with &#8220;COM(n)&#8221;, but the method I am going to show here is capable of enumerating any type of interface using the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms791318.aspx\">SetupAPI<\/a>.<\/p>\n<h3>Setup who?<\/h3>\n<p>The SetupAPI is a part of <span style=\"font-weight: bold;\">Plug-And-Play<\/span> that provides services to <span style=\"font-style: italic;\">User-Mode<\/span> applications. One of the objectives of <span style=\"font-style: italic;\">Plug-And-Play<\/span> is to unify the configuration, use and enumeration of similar devices and services. This way all manufacturers of boards that offer serial port services can have their devices configured in a single way. Devices that offer serial port services must implement a predefined interface, that is, they must show themselves willing to receive <span style=\"font-weight: bold;\">IOCTLs<\/span> and respond to them in a manner foreseen in the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms800933.aspx\">documentation<\/a>.<\/p>\n<p>The driver that wants to create devices that implement the serial port interface must declare this through the call to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa490533.aspx\">IoRegisterDeviceInterface()<\/a> routine. Here a device is associated with a device interface class, which is identified by a <span style=\"font-weight: bold;\">GUID<\/span>. There are several predefined device interface classes in the system, as listed <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb663138.aspx\">here<\/a>, and the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb663174.aspx\">serial ports class<\/a> is one of them. From there, your device will be enumerated by <span style=\"font-style: italic;\">Plug-and-Play<\/span> routines as a provider of a given interface.<\/p>\n<p>All right then. What we have to do is use these interface enumeration functions to find out which devices implement the serial port interface. The <span style=\"font-style: italic;\">SetupAPI<\/span> is going to help us with that task. But before we take a look at the source, let us settle one little thing. I have seen different ways of using <span style=\"font-weight: bold;\">GUID_DEVINTERFACE_COMPORT<\/span>, some include the <span style=\"font-weight: bold;\">Kernel-Mode<\/span> header <span style=\"font-style: italic;\">Ntddser.h<\/span>, others define the <span style=\"font-style: italic;\">GUID<\/span> by hand, but what would be the correct way?<\/p>\n<h3>Defining the interface GUID<\/h3>\n<p>It all starts with the call to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms792959.aspx\">SetupDiGetClassDevs()<\/a> routine that will gather information about the group of devices that match the search criteria adopted in the parameters. We are going to want devices that implement the interface identified by GUID_DEVINTERFACE_COMPORT, but if we simply make the call as shown below&#8230;<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">hDevInfoSet = SetupDiGetClassDevs(&amp;GUID_DEVINTERFACE_COMPORT,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                  NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                  DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);<\/pre>\n<\/div>\n<p>&#8230;we will get the error shown next.<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">1>z:\\sources\\samples\\enumserialport.obj : error LNK2001: unresolved external<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"> symbol _GUID_DEVINTERFACE_COMPORT<\/pre>\n<\/div>\n<p>This happens because GUID_DEVINTERFACE_COMPORT is declared in <span style=\"font-style: italic;\">WinIoCtl.h<\/span>. Remember that this header is indirectly included by <span style=\"font-style: italic;\">Windows.h<\/span> when the WIN32_LEAN_AND_MEAN symbol is not defined, as I already commented on in this <a href=\"https:\/\/driverentry.com.br\/en\/2008\/10\/16\/buffered-direct-or-neither-in-ioctls\/\">other post<\/a>. But even including this header we still have the same problem. Let us look at this a little more closely.<\/p>\n<p>In the <span style=\"font-style: italic;\">WinIoCtl.h<\/span> header we have:<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">DEFINE_GUID(GUID_DEVINTERFACE_COMPORT, <span style=\"color: purple;\">0x86e0d1e0L<\/span>, <span style=\"color: purple;\">0x8089<\/span>, <span style=\"color: purple;\">0x11d0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: purple;\">0x9c<\/span>, <span style=\"color: purple;\">0xe4<\/span>, <span style=\"color: purple;\">0x08<\/span>, <span style=\"color: purple;\">0x00<\/span>, <span style=\"color: purple;\">0x3e<\/span>, <span style=\"color: purple;\">0x30<\/span>, <span style=\"color: purple;\">0x1f<\/span>, <span style=\"color: purple;\">0x73<\/span>);<\/pre>\n<\/div>\n<p>But what is DEFINE_GUID anyway?<\/p>\n<p>In GuidDef.h we have:<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#ifdef<\/span> INITGUID<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">#define<\/span> DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \\<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        EXTERN_C <span style=\"color: blue;\">const<\/span> GUID DECLSPEC_SELECTANY name \\<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#else<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">#define<\/span> DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \\<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    EXTERN_C <span style=\"color: blue;\">const<\/span> GUID FAR name<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">#endif<\/span> <span style=\"color: green;\">\/\/ INITGUID<\/span><\/pre>\n<\/div>\n<p>So now comes the resounding &#8220;Aaaah, right!&#8221;. GUID_DEVINTERFACE_COMPORT is a constant that is defined when the INITGUID symbol is defined; otherwise, this constant is only declared. The INITGUID symbol is defined in the <span style=\"font-style: italic;\">InitGuid.h<\/span> header. So, when you want to use the GUIDs declared with DEFINE_GUID, you will have to, in one of your modules, include the <span style=\"font-style: italic;\">Initguid.h<\/span> header before <span style=\"font-style: italic;\">Windows.h<\/span>. Since our example has only one module, it is easy. As usual, all the source code is contained in an example available for download.<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/-f--&gt; We will have to put these includes in the right order<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">\/\/      so that the GUID that identifies the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/\/      GUID_DEVINTERFACE_COMPORT interface gets defined.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">#include<\/span> <span style=\"color: #a31515;\">&lt;InitGuid.h&gt;<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">#include<\/span> <span style=\"color: #a31515;\">&lt;Windows.h&gt;<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: blue;\">#include<\/span> <span style=\"color: #a31515;\">&lt;SetupApi.h&gt;<\/span><\/pre>\n<\/div>\n<h3>Enumerating interfaces<\/h3>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/****<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">***     EnumSerialInterfaces<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      Routine that enumerates devices that<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      implement the serial port interface<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">*\/<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">DWORD EnumSerialInterfaces(<span style=\"color: blue;\">void<\/span>)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">{<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    CHAR                        szFriendlyName[<span style=\"color: purple;\">100<\/span>];<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    HDEVINFO                    hDevInfoSet = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    SP_DEVICE_INTERFACE_DATA    DevInterfaceData;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    SP_DEVINFO_DATA             DevInfoData;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    DWORD                       dwReturn,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                dwInterfaceIndex = <span style=\"color: purple;\">0<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">try<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Gathering information about devices that implement<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      the desired interface that are present at the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      moment this routine is called.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        hDevInfoSet = SetupDiGetClassDevs(&amp;GUID_DEVINTERFACE_COMPORT,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                          NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                          NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                          DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">if<\/span> (hDevInfoSet == INVALID_HANDLE_VALUE)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">throw<\/span> GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        DevInterfaceData.cbSize = <span style=\"color: blue;\">sizeof<\/span>(SP_DEVICE_INTERFACE_DATA);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Now enumerates each of the interfaces<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">while<\/span> (SetupDiEnumDeviceInterfaces(hDevInfoSet,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                           <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                           &amp;GUID_DEVINTERFACE_COMPORT,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                           dwInterfaceIndex++,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                           &amp;DevInterfaceData))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            DevInfoData.cbSize = <span style=\"color: blue;\">sizeof<\/span>(SP_DEVINFO_DATA);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; For each of the interfaces, we get the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      device that implements it.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (SetupDiGetDeviceInterfaceDetail(hDevInfoSet,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                &amp;DevInterfaceData,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                &amp;DevInfoData))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                <span style=\"color: blue;\">throw<\/span> GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Now we just get the friendly name of the device<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (!SetupDiGetDeviceRegistryProperty(hDevInfoSet,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                  &amp;DevInfoData,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                  SPDRP_FRIENDLYNAME,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                  NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                  (PBYTE)szFriendlyName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                  <span style=\"color: blue;\">sizeof<\/span>(szFriendlyName),<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                  NULL))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                <span style=\"color: blue;\">throw<\/span> GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Printf them...<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            printf(<span style=\"color: #a31515;\">\"%d) %s\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                   dwInterfaceIndex,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                   szFriendlyName);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">catch<\/span>(DWORD dwError)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Oops!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        printf(<span style=\"color: #a31515;\">\"Error %d on trying enumerate device interfaces.\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">               dwError);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        dwReturn = dwError;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Frees the obtained information<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">if<\/span> (hDevInfoSet)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        SetupDiDestroyDeviceInfoList(hDevInfoSet);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">return<\/span> dwReturn;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">}<\/pre>\n<\/div>\n<p>With this implementation, we will have the following output.<\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/FriendlyName.png\" alt=\"\" \/><\/div>\n<p><br class=\"spacer_\" \/><\/p>\n<h3>Cool, but that was not quite it&#8230;<\/h3>\n<p>Very well. The ports were enumerated, but how would I pass a string like that to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa363858(VS.85).aspx\">CreateFile()<\/a> function? Will I have to keep interpreting that string to get the &#8220;COM1&#8221; part that is between parentheses?<\/p>\n<p>Actually there are ways for you to obtain the <span style=\"font-style: italic;\">Symbolic Link<\/span> of the devices also using <span style=\"font-style: italic;\">SetupAPI<\/span> functions, but I imagine that what you wanted is the same as what I want. To fill a <span style=\"font-style: italic;\">Combo Box<\/span> with the simple name of the serial ports, like any normal program.<\/p>\n<p>The port name, which is the &#8220;COMx&#8221; string we are looking for, is written as a registry value in the device&#8217;s key. Every serial port driver has to have this value as shown on <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms800601.aspx\">this page<\/a>. To obtain the registry key regarding the device, we will use another <span style=\"font-style: italic;\">SetupAPI<\/span> routine. The source below will enumerate the serial ports the way we want.<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/****<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">***     EnumSerialPorts<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      Routine that enumerates devices that<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      implement the serial port interface and<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      prints a name that is not friendly but that<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      still serves some purpose.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">*\/<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">DWORD EnumSerialPorts(<span style=\"color: blue;\">void<\/span>)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">{<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    CHAR                        szPortName[<span style=\"color: purple;\">10<\/span>];<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    HDEVINFO                    hDevInfoSet = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    SP_DEVICE_INTERFACE_DATA    DevInterfaceData;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    SP_DEVINFO_DATA             DevInfoData;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    DWORD                       dwReturn,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                dwSize,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                dwInterfaceIndex = <span style=\"color: purple;\">0<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    HKEY                        hKey;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">try<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Gathering information about devices that implement<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      the desired interface that are present at the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      moment this routine is called.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        hDevInfoSet = SetupDiGetClassDevs(&amp;GUID_DEVINTERFACE_COMPORT,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                          NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                          NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                          DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">if<\/span> (hDevInfoSet == INVALID_HANDLE_VALUE)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">throw<\/span> GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        DevInterfaceData.cbSize = <span style=\"color: blue;\">sizeof<\/span>(SP_DEVICE_INTERFACE_DATA);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Now enumerates each of the interfaces<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">while<\/span> (SetupDiEnumDeviceInterfaces(hDevInfoSet,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                           <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                           &amp;GUID_DEVINTERFACE_COMPORT,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                           dwInterfaceIndex++,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                           &amp;DevInterfaceData))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            DevInfoData.cbSize = <span style=\"color: blue;\">sizeof<\/span>(SP_DEVINFO_DATA);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; For each of the interfaces, we get the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      device that implements it.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (SetupDiGetDeviceInterfaceDetail(hDevInfoSet,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                &amp;DevInterfaceData,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                &amp;DevInfoData))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                <span style=\"color: blue;\">throw<\/span> GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Here we get the registry key of the<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      device that implements the interface.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            hKey = SetupDiOpenDevRegKey(hDevInfoSet,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                        &amp;DevInfoData,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                        DICS_FLAG_GLOBAL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                        <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                        DIREG_DEV,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                        KEY_QUERY_VALUE);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: blue;\">if<\/span> (hKey == INVALID_HANDLE_VALUE)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                <span style=\"color: blue;\">throw<\/span> GetLastError();<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Here we get the PortName value from the Registry<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            dwSize = <span style=\"color: blue;\">sizeof<\/span>(szPortName);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            dwReturn = RegQueryValueEx(hKey,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                       <span style=\"color: #a31515;\">\"PortName\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                       NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                       NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                       (LPBYTE)szPortName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                       &amp;dwSize);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            RegCloseKey(hKey);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: blue;\">if<\/span> (dwReturn != ERROR_SUCCESS)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                <span style=\"color: blue;\">throw<\/span> dwReturn;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; Printf them...<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            printf(<span style=\"color: #a31515;\">\"%d) %s\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                   dwInterfaceIndex,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                   szPortName);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">catch<\/span>(DWORD dwError)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Oops!<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        printf(<span style=\"color: #a31515;\">\"Error %d on trying enumerate device interfaces.\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">               dwError);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        dwReturn = dwError;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Frees the obtained information<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">if<\/span> (hDevInfoSet)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        SetupDiDestroyDeviceInfoList(hDevInfoSet);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">return<\/span> dwReturn;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">}<\/pre>\n<\/div>\n<p>Now yes&#8230;<\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/PortName.png\" alt=\"\" \/><\/div>\n<p><br class=\"spacer_\" \/><\/p>\n<p>Putting this in a combo box is already a subject for another blog. For a driver developer, the window below is not so bad after all.<\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/GyroReader.png\" alt=\"\" \/><\/div>\n<p><br class=\"spacer_\" \/><\/p>\n<p>See you! \ud83d\ude09<\/p>\n<p class=\"download\"><a href=\"http:\/\/www.driverentry.com.br\/samples\/EnumSerialPort.zip\">EnumSerialPort.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Among my current tasks was reading the samples from a gyroscope using a serial port and generating a file with them. This file would be read by a driver similar to the one demonstrated in the post before this one. In the gyroscope&#8217;s datasheet there is a description of the protocol, not to mention the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-388","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/388","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/comments?post=388"}],"version-history":[{"count":2,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/388\/revisions"}],"predecessor-version":[{"id":390,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/388\/revisions\/390"}],"wp:attachment":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/media?parent=388"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/categories?post=388"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/tags?post=388"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}