RFCOMM: Windows Mobile 2003 - Virtual COM Port - ERROR_DEVICE_IN_USE

I'm developing an application (Pocket PC 2003 / Windows Mobile 2003) which should establish a RFCOMM Bluetooth connection to a bluetooth-server-device. ( A serial interface for an older non-bluetooth version of this device already exists. PPC is the T-Mobile MDA )

So i checked the scanty microsoft documentation and found out, that it is possible to create a virtual com port with
RegisterDevice(L"COM", index, L"btd.dll", (DWORD)&pp).

With WSALookupServiceBegin(...) and WSALookupServiceNext(...) it was possible to detect the BT_ADDR needed for the PORTEMUPortParams (see above -> pp ) device parameter.

But RegisterDevice always fails with SystemError:ERROR_DEVICE_IN_USE (The device is in use by an active process and cannot be disconnected.) - Then i checked the "HKLM\drivers\Active" Key in my PPC registry and found out, that there is no service using COM 4, 5 or 6. But this Ports also generate this error message.

Interestingly enough the "btd.dll" is not yet loaded. So i guess my PORTEMUPortParams structure isn't the error source.

The sample source code supplied with Windows CE Evaluation Edition seems to do exactly the same.

Maybe I could have forgotten to implement several important gimmicks. Or maybe there is another way to connect with a RFCOMM bluetooth device.

Thanks in advance.

Here is the source (without catching any errors :)

/*+++++++++++Startup WSA+++++++++++++++++*/
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 2 );
WSAStartup( wVersionRequested, &wsaData );

/*+++++++++++++Search for my device++++++++++++++++*/
INT iResult = 0;
DWORD dwSize = 0;
HANDLE hLookup = 0;
memset (&wsaq, 0, sizeof(wsaq));
wsaq.dwSize = sizeof(wsaq);
wsaq.dwNameSpace = NS_BTH;
wsaq.lpcsaBuffer = NULL;

WSALookupServiceBegin(&wsaq, LUP_CONTAINERS, &hLookup);

union {
CHAR buf[5000];
SOCKADDR_BTH      __unused;
pwsaResults = (LPWSAQUERYSET) buf;
dwSize  = sizeof(buf);            
pwsaResults->dwSize      = sizeof(WSAQUERYSET);
pwsaResults->dwNameSpace = NS_BTH;
pwsaResults->lpBlob      = NULL;

WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults);
// Real device name is found ... pwsaResults->lpszServiceInstanceName;

/*+++++++++Now trying to register the virtual COM Port+++++++++++++++*/
PORTEMUPortParams pp;
memset (&pp, 0, sizeof(pp));
pp.channel = 0;
pp.flocal = false;
pp.device = reinterpret_cast<_SOCKADDR_BTH*>(pwsaResults->lpcsaBuffer->LocalAddr.lpSockaddr)->btAddr;
//the detected BT_ADDR
memcpy(&pp.uuidService, &CLSID_NULL, sizeof(GUID));
int port = 4; //or anything else like 1..4,5 or 6..9 | Limit is 9 i think
HANDLE bth = RegisterDevice  (L"COM", port, L"btd.dll", (DWORD)&pp));

/*++++++++the result+++++++++++++++++++*/
//bth == 0
//GetLastError () == ERROR_DEVICE_IN_USE :(
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Here is some code I use to Register a com port to use with Bluetooth.
I noticed you Channel is 0, try setting it to 1.
You can discover the Channel by Querying for information on the RFCOMM Serial Service but doing full SDP is a pain.

You are correct the limit is 9 for com ports on a CE device.
The GetBA function I call is from a Sample from Microsoft Platform builder.
I included it so you can look at it.

If this function succeeds you should be able to open the Com Port and communicate over it.
This function will not check to see if the device you are connecting to exists, it just sets up the comm port.
When you go to open the Comm Port if the device is out of range, suspended, whatever the CreateFile call will fail.

Hope this helps,

BOOL RegisterPort(void)
      PORTEMUPortParams pp;
      int nIndex;
      WCHAR sBA[13];
      int nChannel;
      WCHAR sChannel[4];


      WCHAR sIdx[2];
      int idx;

      // This section demonstrates how to create a BT virtual COM port
      //  Begin

      memset (&pp, 0, sizeof(pp));                        // Clear the PORTEMUPortParams  structure.
//      pp.channel = 6;      //Printer                              // Set to either an explicit server
      pp.channel = nChannel;                              //  channel, or, for a server
                                                //  application that wants the
                                                //  server channel to be autobound,
                                                //  to RFCOMM_CHANNEL_MULTIPLE.
//      pp.channel = RFCOMM_CHANNEL_MULTIPLE;

      pp.flocal = FALSE;                                    //  Set to FALSE for a client port that
                                                //   is used to creating outgoing connections.

      GetBA(_T("0002C710F63E"), &pp.device);            // Using Static BTADDR

      nIndex = 7;      // This must be the same as the COM port number.

      // For devices that expose the stream interface, the drivers are
      // DLL files. Each driver is initialized by a call to the RegisterDevice
      // function. The Device Manager calls this function on behalf of the
      // driver. However, applications can load their own special-purpose stream
      // interface, in which case they also call this function to register the driver.

      h = RegisterDevice(_T("COM"), nIndex, _T("btd.dll"), (DWORD)&pp);

      if (h != NULL)
            bRegister =  TRUE;
            bRegister =  FALSE;

      SetCursor(LoadCursor(NULL, NULL));                  // Clear the wait cursor
      return bRegister;
      FUNCTION:      GetBA
      PROTOTYPE:  int GetBA (WCHAR *pp, BT_ADDR *pba)
      PURPOSE:      Form the BDADDR in a way the PORTEMUPortParams structure
int GetBA (WCHAR *pp, BT_ADDR *pba)
      // Bump pointer through any leading spaces
      while (*pp == ' ')

      for (int i = 0 ; i < 4 ; ++i, ++pp)
            if (!iswxdigit (*pp))

            int c = *pp;
            if (c >= 'a')
                  c = c - 'a' + 0xa;
            else if (c >= 'A')
                  c = c - 'A' + 0xa;
            else c = c - '0';

            if ((c < 0) || (c > 16))

            *pba = *pba * 16 + c;

      for (i = 0; i < 8 ; ++i, ++pp)
            if (!iswxdigit (*pp))

            int c = *pp;
            if (c >= 'a')
                  c = c - 'a' + 0xa;
            else if (c >= 'A')
                  c = c - 'A' + 0xa;
            else c = c - '0';

            if ((c < 0) || (c > 16))

            *pba = *pba * 16 + c;

      if ((*pp != ' ') && (*pp != '\0'))
tstwkAuthor Commented:
Hello Cynthia,

thanks for the fast reply. Unfortunately it seems that there is no great deviation from my code, unless my BT_ADDR causes the problem. Nonetheless I tested yours, but the result was the same. I also took the sequence out of an additional thread.

>I noticed you Channel is 0, try setting it to 1.
I've already tried every channel with every port. :(

for(pp.channel = 0; pp.channel <= 8; ++pp.channel)
        for(int port = 1; port <= 9; ++port)
            if(bth = RegisterDevice  (L"COM", port, L"btd.dll", (DWORD)&pp))
               return bth;

>This function will not check to see if the device you are connecting to exists, it just sets up the comm port.
>When you go to open the Comm Port if the device is out of range, suspended, whatever the CreateFile call will fail.

So only CreateFile should be interested in BT_ADDR. The BT_ADDR I have detected through WSALookupServiceNext is 0x2c724d6f7. It resembles the BT_ADDR of your sample. The device has a PIN code, but this should have nothing to do with virtual com ports?!?

Is there a way, to find out more about the systems comm ports?
Is HKLM\drivers\Active the only hint, who could occupy the ports?
Is there anything I could have forgotten to initialize?
I am debugging over ASync - might this be a problem?

You're right about the Channel. It shouldn't be an issue when Registering. Sorry about that.
When your registering the COM port, you don't even need the device in the area, since it doesn't try to reach out until you go to open the com port.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\2] <- The bluetooth hardware com port is in this registry setting.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\HCI] <- And this one.

ActiveSync shouldn't effect registering the Virtual Com Port.

This code lists the Active Devices in the system.. Microsoft has a new function to use also called RequestDeviceNotifications.  Its more complicated to use,
so I used this one. It accuractly returned the devices in used on my system.

#include <devload.h>

int WINAPI WinMain(      HINSTANCE hInstance,
                              HINSTANCE hPrevInstance,
                              LPTSTR    lpCmdLine,
                              int       nCmdShow)
       // TODO: Place code here.

      WCHAR szDevList[800];
      DWORD dwBuffer = 800;
      DWORD Return;

      //This function returns a list of the active device file names currently present in the file system.
      //Calling RequestDeviceNotifications with DEVCLASS_STREAM_GUID supersedes this function.

                Return = EnumDevices((WCHAR*)&szDevList, &dwBuffer);
                //The String returned has q List of null-terminated strings. The list terminates with two consecutive null characters, one terminating the last entry in the
                // list and an additional null, for example, "COM1:\0COM2:\0PGR1:\0\0".

      case ERROR_SUCCESS: // The function returned successfully.
            WCHAR szReformat[1500];
            DWORD Start = 0;

                                //Parse the Returned list so I can see it in a MessageBox.
            for(DWORD x = 0; x < dwBuffer; x++)
                  if(szDevList[x] == '\0')
                        if(Start == 0)
                              Start = x+1;
                        else if(Start == x)
                              Start = x+1;
                        Start = x+1;

            MessageBox(NULL,szReformat,L"COM Data",MB_OK);
      case ERROR_INSUFFICIENT_BUFFER: // The lpszDevList buffer was not big enough to hold any entries; lpBufLen will contain the required size.
            MessageBox(NULL,L"Insufficient Buffer",L"COM Data",MB_OK);
      case ERROR_INVALID_PARAMETER: // The lpBufLen parameter was NULL.
            MessageBox(NULL,L"Invalid Parameters", L"COM Data",MB_OK);
      case ERROR_MORE_DATA: // The lpszDevList buffer was not big enough to hold the complete list of active devices; lpBufLen will contain the required size.
            MessageBox(NULL,L"ERROR MORE DATA",L"Com Data",MB_OK);
            MessageBox(NULL,L"No More Devices",L"Com Data",MB_OK);

      return 0;

Challenges in Government Cyber Security

Has cyber security been a challenge in your government organization? Are you looking to improve your government's network security? Learn more about how to improve your government organization's security by viewing our on-demand webinar!

tstwkAuthor Commented:
The serial devices return are COM 1,2,3,6,8 and 9. So there are "free" Ports.
BUT.... the key [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\2] you mentioned above is absend!

Only [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\1] with bthusb.dll and [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\3] with bthcsr.dll (concerning COM6).

I think this is a pretty obvious error. But unfortunately I found out nothing about this registry key. Would you be so kind to give me further informations or a list of sources about my absend [...\BuildIn\2] registry key, so i have the chance to find out more about it. Just to reproduce the problem. Is it the btd.dll mentioned in [...BuiltIn\2]?
Am I right that the hardware manufacturer is responsible for the development (DLLs and registry-settings) of its Win CE Platform?

If I have a blade of grass to hang on, I'll close this question with a clear conscience : )
>>Am I right that the hardware manufacturer is responsible for the development (DLLs and registry-settings) of its Win CE Platform?
Partially.  It depends of whether the Radio is embedded into the device or not. If its embedded than the Device manufacturer would be the one responsible for drivers and registry settings. If you are adding a bluetooth compact flash card, then the card manufacturer would be responsible.

Can I ask what Bluetooth card you are using?
For example, I know that Socket offers an SDK to go with their card but they don't use the Microsoft Stack for their card.

I am currently working on a device that my company is building, we have our own internal Bluetooth chipset and we are using the Microsoft Stack. I got those registry settings from that device.

I have a CE device here with a Socket BT compact flash card in it.  I just looked at it's registry settings and they are different.
Because it's in the Compact Flash slot it doesn't have a Serial port assigned to it, like my other device does.
It has this setting but doesn't have a 2 or 3.

I can register a port with the Socket card, but I am having trouble opening the com port. Of course I can create the connection with the Socket SDK with no problem.
They use the Draker Stack.

I just looked into the IPAQ's I have with Bluetooth in them and they use the WidComm stack. You have to get the SDK to use that stack from them. Looks like they are charging for it.  www.widcomm.com
I can't register a com port on my IPAQ for bluetooth either.  I'm guessing they do this so you are forced to buy their SDK.

Hope this helps some.

tstwkAuthor Commented:
Bluetooth is integrated in the T-Mobile MDA II ... http://msmobiles.com/article.php/54.html (most of the articles I found were german) It seems to have features like the IPaqs. Addionately it has a fantastic camera feature (and is a cell-phone : ). The IPaq (Bluetooth-PPC) might be an alternative for us, but if the problem persists it wouldn't make much sense.

Is it possible to use the wsa sockets on the IPqaw without using the WidComm stack? The thing I don't understand is - Windows Mobile 2003 has a stack for Virtual COM Ports and the manufacturer doesn't implement it, so that no generic software can use it?!?

I have already contacted the manufacturer, but still no answer. Maybe the MDA II has third party bluetooth stuff, too. If telekom answers, I'll know.

Do you have any further ideas?

The device you are working on might be an alternative, too... Currently we are selling yakumo deltas with leica disto pro 4 lasermeasurement devices. But the cable is disturbing while working with the laser device... http://www.mobilaufmass.com/Mobilaufmass/Das_Mobilaufmass_im_Einsatz/Steuerung.htm (unfortunately the site is german)

Thanks for your endurance.

Unfortunately I don't know the widcomm stack so I don't know if you can get around buying their SDK.

The device with the embedded bluetooth that I am using comes from Symbol Technologies, Inc. but is currently not for sale. I am doing some evaluation development work on it.

However, Symbol sells this device:
It has a Socket Bluetooth radio in it and I know Symbol will supply the SDK to their customers, so they will be able to write their own code to use the radio.

It's no problem.  I understand such frustration with new product. Documentation? What documentation!?!
Trust me, you don't want to write an Service Discovery App using the Microsoft Stack. It was difficult, because the documentation provided with the APIs was extremely lacking and wrong.

Good Luck!!

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Hi tstwk,
You wrote..

"Is it possible to use the wsa sockets on the IPaq without using the WidComm stack? The thing I don't understand is - Windows Mobile 2003 has a stack for Virtual COM Ports and the manufacturer doesn't implement it, so that no generic software can use it?!? "

Do you ever resolve this issue?
I'm currently programming an application for an IPaq 2210 and although I've managed to get 1 device connected and transfering data to the IPaq I actaully need to connect 2 Bluetooth devices.  Therefore I really need to create VIRTUAL ports however as you suggest VIRTUAL ports don't come with this stack - sigh.

Another issue wsa that I had to set the IPaq as the master device - although the connection would appear to be made if the IPaq was the slave no data would actually be sent.

I've emailed the maker widcomm.com but never got satisfactory replys.

Your application needs both Bluetooth devices to be paired or it's not necessary because you implement an SDP query? maybe it's implemented by default?
I have a Dell Axim X3 and i want to make a connection between it and a Pc.
Dell Axim X3 Bluetooth hardware manufacturer is Widcomm.Won't I be able to create VIRTUAL COM from my Pocket PC if i don't get the Widcomm SDK?
tstwkAuthor Commented:
We found out, that the RFCOMM stuff simply doesn't work on the MDA II. It's a himalaya device, all of these devices are showing the same peculiarity.
They send us 3 different version of their PPC, but without any progress within the implementation of RFCOMM. There's also a logical error in the user interface: You can "find and connect" the device to the pocket pc in Windows Mobile 2003 and you can set bluetooth com-ports (COM4 output, COM5 input), but there is no setting to combine the com-port with the device?!?

Because of this, you can never connect these Pocket PCs to a RFOMM device (GPS etc.). *g*

Dell Axim X3 question: Now we are using the WIDCOMM stack (only MFC-support I think) for RFCOMM, which has its errors, but with some workarounds you can wangle it. In my opinion the WIDCOMM Support is miserable.
I'm relatively sure, that without buying the WIDCOMM stack you won't be able to connect the devices. But maybe it's possible... There are many extra features for searching devices etc. int the stack, so that the users do not need to establish the connection in the widcomm settings.
Because of some errors the newer WIDCOMM PPCs have revised SDK-DLLs in their ROM, maybe you could use them (BtCoreIf.dll BtSdkCE30.dll)?!? Normally you must install them yourself. It is hard enough with the mfc classes. But it's not, that you pay for nothing...

Having similar trouble on WinCE 4.2.  I haven't written my own app, just used the sample ones that came with it.  I may be able to shed some light on a little of what was said before.

The registry settings under
Are for bluetooth transports.  The transport is the way the Host (WinCE) talks to the bluetooth device.  Eg. Serial/USB/PCMCIA etc.  They are at a lower level then what is trying to be done here.

I've heard that it's possible to get this working but I can't find any resources on the net anywhere.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Wireless Networking

From novice to tech pro — start learning today.