1

How to find which com-port is occupied by serial mouse

Here is how I detect mouse in C# (adapted code from this answer)

var info = IntPtr.Zero;
try
{
    var guid = new Guid("{4d36e96f-e325-11ce-bfc1-08002be10318}"); // mouses
    info = SetupDiGetClassDevsW(ref guid, null, IntPtr.Zero, 0);
    if ((int)info == -1) // INVALID_HANDLE_VALUE
        throw new Exception(string.Format("Error({0}) SetupDiGetClassDevsW", Marshal.GetLastWin32Error()));
    // enumerate mouses
    var device = new SP_DEVINFO_DATA();
    device.cbSize = (UInt32)Marshal.SizeOf(device);
    for (uint i = 0; ; i++)
    {
        // get device info
        if (!SetupDiEnumDeviceInfo(info, i, out device))
        {
            var error = Marshal.GetLastWin32Error();
            if (error == 259) // ERROR_NO_MORE_ITEMS
                break;
            else
                throw new Exception(string.Format("Error({0}) SetupDiEnumDeviceInfo", error));
        }
        string id = GetStringPropertyForDevice(info, device, 1); // SPDRP_HARDWAREID
        if (id != null && id.Contains("*PNP0F09")) // Microsoft BallPoint Serial Mouse
        {
            // ...
            // here I want to check com-port, how?
            // ...
        }
    }
}
finally
{
    if (info != IntPtr.Zero)
        SetupDiDestroyDeviceInfoList(info);
}

Edit

Removing C# tag. Looking for general info (any language).

Community
  • 1
  • 1
Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • Have you tried to pass SPDRP_LOCATION_INFORMATION or SPDRP_LOCATION_PATHS to your GetStringPropertyForDevice function? (from http://msdn.microsoft.com/en-us/library/ff551967.aspx) – Simon Mourier Sep 09 '14 at 06:04
  • @SimonMourier, I receive `ERROR_INVALID_DATA` (which I think is ok, it simply means this device doesn't have such properties) for `SPDRP_LOCATION_INFORMATION` (`0xD`) and `SPDRP_LOCATION_PATHS` (`0x23`). – Sinatr Sep 09 '14 at 07:58
  • The property you're after should in fact be displayed in the "Details" tab. Can you check it's there in your config? – Simon Mourier Sep 09 '14 at 09:18
  • @SimonMourier, none of properties in "Details" tab contains anything like `com6`. I have no clue how windows displays `com6` for this device. Neither opposite: if I get `UnauthorizedAccessException` exception when trying to open `com6` (Access denied blablabla), there is no way to see who is using it. – Sinatr Sep 09 '14 at 09:49
  • 1
    Downvoter without comment should go to forest and die. Question (screnshot) is clear and problem seems to be reasonable: how to obtain unobviously obtainable information, which Windows shows for device. – Sinatr Sep 09 '14 at 09:52
  • +1 for your comment :) Have you tried Parent property or Container id? – Simon Mourier Sep 09 '14 at 09:55
  • @SimonMourier, of what? Of driver? My driver development knowledge are very poor. – Sinatr Sep 09 '14 at 09:57
  • I suggest you use this free GUID Explorer tool to check what information could be useful: http://www.bustrace.com/downloads/free_utilities.php – Simon Mourier Sep 14 '14 at 10:33
  • @SimonMourier, thanks, but its report doesn't shows com-port, nor I can see property of com-port if it is occupied by SerialBall. – Sinatr Sep 16 '14 at 07:14
  • Did you solve the problem? if you did please share your solution, Thanks – Ahmad Al Sayyed Sep 17 '14 at 14:04

2 Answers2

1

You can use Process Monitor from SysInternalSuite and open device manager then find out from where does the device manager getting its values

I tried it on USB Mouse and was able to get (on USB Input Device) as shown below 1. Open Mouse Properties (From Control Panel) enter image description here 2. Open ProcMon 3. Click on the target icon and choose the mouse properties window enter image description here 4. From the Mouse Properties window open the Hardware tab 5. In ProcMon Click on File-> Captuer Events 6. In ProcMon Edit->Find and look for "com" without quotation mark 7. Double click the found row (If you where able to find it)

Process Monitor Registry Event Properties

Another solution would be to get device information using device manager command line utility devcon and parse the information from the output stream

More information on devcon: * http://support.microsoft.com/kb/311272 * https://superuser.com/questions/414280/how-do-i-view-a-list-of-devices-from-the-command-line-in-windows

Hope this help

Community
  • 1
  • 1
Ahmad Al Sayyed
  • 596
  • 5
  • 13
  • What is *map*? So you suggest me to enumerate serial ports in the system and then check something to see if my mouse and my port are .... Are what? Have same id in one of property or what? Idea seems ok, I just can't figure out what exactly should I do. So, what is this *mapping*? – Sinatr Sep 16 '14 at 07:22
  • Could you post your SerialPort Device ID and the Mouse Device ID, also take a look at the second solution (http://support.microsoft.com/kb/311272) – Ahmad Al Sayyed Sep 16 '14 at 07:28
  • Check this out, He gets the device name from the SerialPort: http://stackoverflow.com/questions/17170126/how-to-get-whats-using-the-com-port-visual-basic-net – Ahmad Al Sayyed Sep 16 '14 at 07:31
  • I don't know what to do with *Process Monitor* to get your *Event Properties* window sorry. Do you suspect there is a registry entry and I shall read it? `Device description` of SerialBall is "@msmouse.inf,%*pnp0f09.devicedesc%;Serieller Microsoft BallPoint", found in registry, yet it gives me no clued how to get com-port from it. I can't find "com6" or leads to com6 in registry. – Sinatr Sep 16 '14 at 10:18
  • It is not mine :) I Couldn't validate it for serial mouse I don't have one (as per the question General Knowledge - just trying to help) – Ahmad Al Sayyed Sep 16 '14 at 12:51
  • Oh, I see now. You suggest to see which registry keys windows *Device Manager* windows is querying while populating content of BallPoint properties window. I'll try to look into it, thanks. Pretty good idea tbh, even if it doesn't works. – Sinatr Sep 16 '14 at 13:29
  • I would recommend you to use devcon (The second solution), I used it before to query devices – Ahmad Al Sayyed Sep 16 '14 at 13:41
0

The subroutine that generates the "Location" string in Device Manager is devmgr.dll!GetLocationInformation.

The path in it that interests you - generating the value that is appended in brackets - can be represented with the following code (based on Hex-Rays' decompilation):

int __stdcall GetLocationInformation(DEVINST dnDevInst, wchar_t *lpsResult,
                                     int cchBufferMax, HMACHINE hMachine)
{
  int dwUiNumber;
  HKEY hKey;
  DWORD pulLength;
  wchar_t sRawLocationInfo[260];

  sRawLocationInfo[0] = 0;
  DWORD Type = REG_SZ;
  pulLength = 520;
  if ( !CM_Open_DevNode_Key_Ex(dnDevInst, KEY_READ, 0, 1u, &hKey, 1u, hMachine) )
  {
    RegQueryValueExW(hKey, L"LocationInformationOverride", 0, &Type,
      sRawLocationInfo, &pulLength);
    RegCloseKey(hKey);
  }
  if ( !sRawLocationInfo[0] )
  {
    pulLength = 520;
    CM_Get_DevNode_Registry_Property_ExW(
      dnDevInst,
      CM_DRP_LOCATION_INFORMATION,
      0,
      sRawLocationInfo,
      &pulLength,
      0,
      hMachine);
  }
  pulLength = 4;
  if ( CM_Get_DevNode_Registry_Property_ExW(
         dnDevInst,
         CM_DRP_UI_NUMBER,
         0,
         &dwUiNumber,
         &pulLength,
         0,
         hMachine)
    || pulLength <= 0 )
  {
    <...>   //this block always returns
  }
  else
  {
      <...>
      if ( sRawLocationInfo[0] )
      {
        lstrcatW(lpsResult, L" (");
        lstrcatW(lpsResult, sRawLocationInfo);
        lstrcatW(lpsResult, L")");
      }
      return 0;
  }
}

In a nutshell, the bracketed value is the device node's LocationInformationOverride or LocationInformation property and is only produced if the UiNumber property is absent (or bogus).


The CM_Open_DevNode_Key_Ex and CM_Get_DevNode_Registry_Property_ExW functions are marked "reserved" in the docs. You can


If my guess is right, the "USB Serial Port (COM6)" you see in Device Manager is actually the name of the parent device (=the device this one is connected to as seen in Device Manager in "view devices by connection" mode). If this is correct, the "COM6" is but a part of the name rather than some independent property.

Community
  • 1
  • 1
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
  • Thanks, but the first function used is [`CM_Open_DevNode_Key_Ex`](https://msdn.microsoft.com/en-us/library/windows/hardware/ff538830.aspx) and `CM_Get_DevNode_Registry_Property_ExW` I can't even find. How I suppose to use provided information to obtain device location? Shall I [invoke dll function](http://www.codeproject.com/Articles/7838/Device-Property-Sheet-Dialog)? – Sinatr Jun 17 '15 at 07:44
  • P/Invoke, of course, as it always is with exported DLL functions. – ivan_pozdeev Jun 17 '15 at 10:31
  • I am using `SetupDiGetDeviceRegistryProperty` now. Location you say? I tried `SPDRP_LOCATION_INFORMATION`, but it returns `ERROR_INVALID_DATA`. If you tell me how to get com-port with it then **that would be the perfect answer**. Otherwise your answer has no use to me: some code from codeproject, which uses *reserved* functions, no thanks. – Sinatr Jun 17 '15 at 12:48
  • I only linked to the Code Project for the function prototype, sheesh. – ivan_pozdeev Jun 17 '15 at 13:52
  • I don't have neither a Vista system nor a suitable device on my machine. So I can only test the XP API if I find anything suitable on other machines accessible to me. I'll try this now. – ivan_pozdeev Jun 17 '15 at 13:54
  • 1
    Don't get me wrong, I appreciate effort. But in current state it's like written in Chinese: looks fancy, a lot of explanation, but still no idea of how to use it. – Sinatr Jun 17 '15 at 14:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80805/discussion-between-ivan-pozdeev-and-sinatr). – ivan_pozdeev Jun 17 '15 at 16:53