none
WEC7, connect wifi using connection manager api RRS feed

  • Question

  • Hello,

    our OS (WEC7) contains connection manager so we have to use connection manager api to make connection to wifi. Our system should reconnect automatically to an access point after reboot.

    After establishing a connection using onscreen connection manager I retrieve configuration with CmGetConnectionConfig(SSID, pConfig, &cbSize) and store the configuration in a file (it is about 2 kilobytes, most of them contains xml-information).


    After reboot I use this file to populate a Config struct, according following code:

    #define SSID L"Connectify-me"

        CM_CONNECTION_DETAILS *pDetails = NULL;
        CM_SESSION_HANDLE myhandle = CmCreateSession(); 
        CM_CONNECTION_HANDLE hConnection = NULL;
        CM_RESULT result;
        CM_CONNECTION_CONFIG* pConfig = NULL;
        DWORD cbConfigSize = 10;
    
        unsigned char * ptr = (unsigned char *)pConfig;
        FILE * fp = _wfopen(L"\\flashdisk\\wifi.txt",L"rb");
        if (fp) {
          fseek(fp,0,SEEK_END);
          cbConfigSize = ftell(fp);
          fseek(fp,0,SEEK_SET);
          pConfig = (CM_CONNECTION_CONFIG*)LocalAlloc(0, cbConfigSize);
          int numread = 0;
          if (pConfig) 
             numread = fread(pConfig,1,cbConfigSize,fp);
          fclose(fp);
        }
     
        if (pConfig) {      
          result = CmAddConnectionConfig(SSID,pConfig,cbConfigSize);
          LocalFree(pConfig);
        }
     
        Sleep(5000);
    
        for (result = CmGetFirstCandidateConnection(myhandle, NULL, CMSO_DEFAULT, &hConnection);result==CMRE_SUCCESS;
                  result = CmGetNextCandidateConnection(myhandle, &hConnection)) {
          DWORD dwError = GetConnectionDetailsByHandle(hConnection, &pDetails);
          if (dwError==0) {
            if (memcmp(&pDetails->Type, &CM_CSP_WIFI_TYPE, sizeof(CM_CONNECTION_TYPE)) == 0) {
              if (wcscmp(pDetails->szName,SSID) == 0) {
                result = CmAcquireConnection(hConnection);
                int aa = 0;
              }
            }
          }
        }
        CmCloseSession(myhandle);
      }
    DWORD GetConnectionDetailsByHandle(CM_CONNECTION_HANDLE hConnection, CM_CONNECTION_DETAILS** ppDetails)
    {
        DWORD dwError = ERROR_SUCCESS;
        CM_RESULT result = CMRE_INSUFFICIENT_BUFFER;
        CM_CONNECTION_DETAILS* pDetails = NULL;
        DWORD dwDetailSize = 255;
        // Get the connection details.
        for (int i = 0; i < MAX_TRY_COUNT_FOR_INSUFFICIENT_BUFFER && result == CMRE_INSUFFICIENT_BUFFER; i++) {
          LocalFree(pDetails);
          pDetails = (CM_CONNECTION_DETAILS *)LocalAlloc(0, dwDetailSize);
          if (pDetails)
            result = CmGetConnectionDetailsByHandle(hConnection,pDetails,&dwDetailSize);
        }
        *ppDetails = pDetails;
        pDetails = NULL;
        LocalFree(pDetails);
        return dwError;
    }


     CmAddConnectionConfig(SSID,pConfig,cbConfigSize) returns CMRE_SUCCESS, but CmAcquireConnection(hConnection) returns CMRE_CONNECTION_ACQUIRE_FAILED.

    On screen in wifi connect dialog Ii see FAILED TO ASSOCIATE WITH ssid.

    When I have a look into registry HKLM\Comm\Connmgr\Settings\Connections\ssid I see that field Data 0 is much larger (3088 compared to 2280) than it is when the connection is establised using on screen connection dialog.

    What is going wrong ?

    Is there another way for automatic reconnection to an access point ?

    Any ideas welcome !

    Thank you !


    Friday, July 3, 2015 8:23 AM

All replies

  • Hello,

    after many trials I think I have found the reason for the problem:

     in the xml-part of the configuration that I get with CmGetConnectionDetailsByHandle the password is protected

        <keyType>passPhrase</keyType>
        <protected>true</protected>

    I think that CmAcquireConnection does not know how to deal with protected keys.

    Wednesday, July 8, 2015 7:49 AM
  • Hi,

    Even I am facing this issue wherein I need to import the connection string and add it using connection manager APIs(CmAddConnectionConfig) and then attempt to connect it using cmAcquireConnection which returns the error code 13015(CMRE_CONNECTION_ACQUIRE_FAILED).I see the root cause is the same as you observed ie.. protected field is "true" as this is how it is returned by CmGetConnectionConfigByName.

     Is there a way this issue can be resolved? Is it possible for us to use any APIs to decrypt the protected key received?


    Thursday, August 23, 2018 12:08 PM
  • Pass the keymaterial to the hexString input.

    LampSys_API HRESULT fnUnProtectKeyMaterial(__in LPCTSTR hexString,bool isWEP,

       __deref_out_opt LPTSTR* passphrase)   

    {

    DATA_BLOB DataIn; //Input DATA_BLOB for CryptUnprotectData


    DATA_BLOB DataOut; //Output DATA_BLOB for CryptUnprotectData


    HRESULT hr = ERROR_SUCCESS; // return value


    LPWSTR pDescrOut =  NULL;

    WCHAR *temp = NULL;

    DWORD noofbytes = 0;

    BSTR bstrInnerText;

    *passphrase = NULL;

    //convert the hex tsring to byte array


    DWORD dwBufferLen = BinHexToBufferLength(hexString, wcslen(hexString));

    BYTE *dataarr = (BYTE*)LocalAlloc(0, dwBufferLen);

    ConvertBinHexToBuffer(hexString,  wcslen(hexString), dataarr);

    //assign the input DATA_BLOB structure


    DataIn.cbData = dwBufferLen;

    DataIn.pbData = (BYTE *)dataarr;

    //initialize the output DATA_BLOB structure


    DataOut.cbData = 0;

    DataOut.pbData = NULL;

    //unprotect the key material


    CBREx((TRUE == CryptUnprotectData(&DataIn,

    &pDescrOut,

    NULL,                               // Optional entropy not used.


    NULL,

    NULL,

    CRYPTPROTECT_SYSTEM,//0,


    &DataOut)), GetLastError());

    if(isWEP)

    {

    //if network type is WEP, then the decrypted key material 


    // should be returned as hex string


    //Hence convert the DataOut byte array to hex string


    DWORD dwHexLen = (DWORD)BufferToBinHexLength(DataOut.pbData, DataOut.cbData);

    bstrInnerText = SysAllocStringLen(L"", dwHexLen + 1);

    CPR(bstrInnerText); 

    ConvertBufferToBinHex(DataOut.pbData, DataOut.cbData, bstrInnerText, dwHexLen + 1);

    //assign the network key to output variable.


    wcscpy((wchar_t*)passphrase,bstrInnerText);

    }

    else


    {

    //if network type is personal, the decrypted byte array should be converted to wide char



    noofbytes = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)(DataOut.pbData), DataOut.cbData, NULL, 0);

    temp = new WCHAR[noofbytes];

    MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)(DataOut.pbData), DataOut.cbData, temp, noofbytes);

    //assign the passphrase to the output variable.


    wcscpy((wchar_t*)passphrase, temp);

    }

    Error:

    if(dataarr)

    {

    LocalFree(dataarr);

    }

    if(DataOut.pbData)

    {

    LocalFree(DataOut.pbData);

    }

    if(pDescrOut)

    {

    LocalFree(pDescrOut);

    }

    if(temp)

    {

    delete temp;

    }

    if(bstrInnerText)

    {

    SysFreeString(bstrInnerText);

    }

    return hr;

    }

    • Proposed as answer by RachanaSingh Tuesday, September 4, 2018 7:05 AM
    Tuesday, September 4, 2018 7:05 AM