usb to serial using wmi, not working

Hello, I am new to these forums, I thought it would be best to sign up to a forum as I am learning c++.

However I do have a problem I am working on and can not seem to work it out. What I want to do it enumerate serial ports and find out which one is available and go from there. Currently I have just got a for loop and goes through testing com ports and then finds the correct one.

I have now decided to go down the route of using WMI and have modified the example on msdn website to take "SELECT * FROM Win32_SerialPort" Works great shows all com ports apart from one.

The one I need is a USB to Serial connection which it some how doesn't find. I hope some one can point me in the right direction.

Thank you in advance.
We've had the same problem at work some time ago. If you are not answered until monday, i'll try to find how we solved it
Tried pnp as i thought i may be able to access it this way

bstr_t("SELECT * FROM Win32_PnPDevice"),

or this

bstr_t("SELECT * FROM Win32_PnPEntity"),

Still nothing there on usb to serial :(. Starting to pull my hair out lol!
Thank you Bartoli and guestgulkan.

The link above uses

1
2
root\\WMI",
        "SELECT * FROM MSSerial_PortName"); 


Which from the looks of things is on cs, I could not find anything similar for c++
Last edited on
The available serial ports can also be found at the values at the HKEY_LOCAL_MACHINE\hardware\devicemap\serialcomm key in the registry.

In c++ you could use QueryDosDevice() API call or CreateFile() with appropiate syntax and check if it succeed.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365461(v=vs.85).aspx
Hi modoran, I tried that and i did find it that way. However my senior programmer said if windows decided to store the information diffiderently in the future , the code will have to be re-written. And said its better to use a provided method by Microsoft (wmi).
You could try to use SetupDiGetClassDevs() function, as other people did:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff551069(v=vs.85).aspx

Or if you insist on using WMI, try Win32_SerialPort WMI class,
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394413(v=vs.85).aspx
bstr_t("SELECT * FROM Win32_SerialPort "),
I think this is the function we used in our code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
static BOOL WinNT40ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue)
/* Unlike Win9x, information on serial ports registry storing in NT 4.0 is
 * scarce. HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM is reliably
 * documented to hold the names of all installed serial ports, but I haven't
 * confirmed this for infrared ports and other nonstandard drivers.
 * Descriptions stored under SERIALCOMM lack the "FRIENDLYNAME" found
 * in Win9x, there's only the bare names of the ports.
 */
{
  DWORD  dwError=0;
  HKEY   hKey=NULL;
  DWORD  dwIndex;
  LPTSTR lpValueName=NULL;
  LPTSTR lpPortName=NULL;

  if(dwError=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
                          0,KEY_READ,&hKey)){
    /* it is really strange that this key does not exist, but could happen in theory */
    if(dwError==ERROR_FILE_NOT_FOUND)dwError=0;
    goto end;
  }

  for(dwIndex=0;;++dwIndex){
    DWORD              cbValueName=32*sizeof(TCHAR);
    DWORD              cbPortName=32*sizeof(TCHAR);
    LISTPORTS_PORTINFO portinfo;

    /* loop asking for the value data til we allocated enough memory */

    for(;;){
      free(lpValueName);
      if(!(lpValueName=(LPTSTR)malloc(cbValueName))){
        dwError=ERROR_NOT_ENOUGH_MEMORY;
        goto end;
      }
      free(lpPortName);
      if(!(lpPortName=(LPTSTR)malloc(cbPortName))){
        dwError=ERROR_NOT_ENOUGH_MEMORY;
        goto end;
      }
      if(!(dwError=RegEnumValue(hKey,dwIndex,lpValueName,&cbValueName,
                                NULL,NULL,(LPBYTE)lpPortName,&cbPortName))){
        break; /* we did it */
      }
      else if(dwError==ERROR_MORE_DATA){ /* not enough space */
        dwError=0;
        /* no indication of space required, we try doubling */
        cbValueName=(cbValueName+sizeof(TCHAR))*2;
      }
      else goto end;
    }

    portinfo.lpPortName=lpPortName;
    portinfo.lpFriendlyName=lpPortName; /* no friendly name in NT 4.0 */
    portinfo.lpTechnology=TEXT(""); /* this information is not available */
    if(!lpCbk(lpCbkValue,&portinfo)){
      goto end; /* listing aborted by callback */
    }
  } 

end:
  free(lpValueName);
  free(lpPortName);
  if(hKey!=NULL)RegCloseKey(hKey);
  if(dwError!=0){
    SetLastError(dwError);
    return FALSE;
  }
  else return TRUE;
}


An other issue you might face. If you need to open a comp pot greater than 9, you will have to enter "\\\\.\\COM10" for com10 instead of just "COM10" for example in you port opening function

EDIT : Here is a link to the apparently original source file from the author where the function is based from :
http://code.google.com/p/pockettune/source/browse/trunk/PocketTune/listports.c?r=11
Last edited on
thank you again bartoli , so the only way is to use the registry to find usb to serial and not WMI?
I'm afraid i can't tell you more, i know the function i gave you works for me, but i don't know more about WMI. Do you have issues about using the registry?
Got the com port used this instead
 
SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0") 


My senior programmer managed to sort it (thank god).

**EDIT**

Thank you everyone for your help, forgot to say that before :)
Last edited on
Topic archived. No new replies allowed.