Silently install multiple CABs on Windows Mobile


- How to modify MulticabInstall SDK Sample

- Notes about Security

Recently I've been involved in an issue about silently installing mutiple CABs, so I think it may be worth mentioning its results here.

The OS component invoked when installing CABs is WCELOAD.EXE: it's the same if the CAB is created for XML Provisioning (through makecab.exe) or for installing an application (thruogh CabWiz.exe). It's for example responsible to check for certificates when the Security Policies dictate that unsigned CAB are not allowed to run. The version for Windows Mobile (5.0\6) is a bit different from the one for Windows CE 5.0, maily regarding available command-line parameters, check out:

Starting with Windows Mobile 5.0, only one running instance of WCELOAD.EXE is possible, therefore the nested CABs used with Windows Mobile 2003 are no longer possible. A solution to this is the MulticabInstall SDK sample: it basically allows the installation-chaining of CABs packaged into an UberCAB by looking at some registry keys. The sample contains a whitepaper that explains everything needed, I won't double it here.

However, what if I want all those inner CABs to be SILENTLY installed? For a single CAB, the solution is programmatically launch WCELOAD.EXE with /silent option (on Windows Mobile). So I simply looked for the function in the MulticabInstall SDK sample responsible for executing the CAB and found:

BOOL HostExec(LPCTSTR lpszFilePath, HANDLE *phProcess)
{
    BOOL bRet;
    SHELLEXECUTEINFO sei = {0};

    sei.cbSize = sizeof(sei);
    sei.nShow = SW_SHOWNORMAL;
    sei.lpFile = lpszFilePath;
    //sei.lpParameters = TEXT("/silent");  //WRONG APPROACH!!

    bRet = ShellExecuteEx(&sei);

    if (bRet)
    {
        *phProcess = sei.hProcess;
    }

    return bRet;
}

It uses the ShellExecuteEx() API to launch the application on the OS associated to files with .cab extension. I tried to set the parameter lpParameters of the SHELLEXECUTEINFO structure to "/silent", however this didn't work... So I looked at documentation for the SHELLEXECUTEINFO structure and found: "[...] If the lpFile member specifies a document file, this member should be NULL.". At this point I remembered what that sentence means: lpParameters was basically ignored since my lpFile was NOT an .EXE! Embarrassed

In order to continue using ShellExecuteEx (and not CreateProcess, for exampple), the code I came up with was simply:

BOOL HostExec(LPCTSTR lpszFilePath, HANDLE *phProcess)
{
    BOOL bRet;
    SHELLEXECUTEINFO sei = {0};

    sei.cbSize = sizeof(sei);
    sei.nShow = SW_SHOWNORMAL; 
    sei.lpFile = TEXT("\\Windows\\WCELOAD.EXE");

    TCHAR   szLaunchParms[MAX_PATH];
    StringCchPrintf(szLaunchParms,ARRAYSIZE(szLaunchParms), 
            TEXT("/silent \"%s\""), 
            lpszFilePath);
    sei.lpParameters = szLaunchParms;

    bRet = ShellExecuteEx(&sei);

    if (bRet)
    {
        *phProcess = sei.hProcess;
    }

    return bRet;
}

 

As a final note, consider that on WM5 there could be additional prompt regarding CAB installations, if the CAB is not signed with a certificate stored on the SPC store of the device.When using /noui (or /silent) then by default prompts are answered with 'Yes'. However, if the .cab file is unsigned (or signed with a certificate not stored on the device), any security-related prompts will default to 'No' for security reasons, and the installation might SILENTLY fail.

 

Cheers,

~raffaele


Comments (4)
  1. Rolando says:

    I all,

    i try install a root certificate in WM6.1 device

    this is the code:

    SHELLEXECUTEINFO sei;

    ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));

    sei.cbSize = sizeof(SHELLEXECUTEINFO);

    sei.lpFile = TEXT("\Flash File Store\rootGRPS.cer");

    sei.nShow = SW_HIDE;//SW_SHOW;

    sei.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS;

    TCHAR   szLaunchParms[MAX_PATH];

       StringCchPrintf(szLaunchParms,sizeof(szLaunchParms),

               TEXT("/silent "%s""),

               L"\Flash File Store\rootGRPS.cer");

    sei.lpParameters = szLaunchParms;

    ShellExecuteEx(&sei);

    WaitForSingleObject(sei.hProcess, INFINITE);

    this yes intall the certificate, But when finish

    show a message box : One o more certificates were intalled successfully

    how eliminate this message??

    i don't want this message show.

    i hope that you help me !!

    sorry for my very bad english, jejeje

    Saludos a todos

  2. Hi Rolando, I don't know right now if there's a silent way to enroll a .cer file by using the shell (tapping on the .cer file is the same as your ShellExecuteEx). You may want to think about using Windows functions to get a handle of the open dialog and close it, however this won't probably be the cleanest solution. I would suggest asking for help by opening a Support Request at Technical Support: possibly you're already eligible for a free incident and you're not using it.. check this post http://bit.ly/eyAHyR

    HTH!

    ~raffaele

  3. James says:

    Thanks for that one!! Perfect as I had 6 cabs to install. Thanks again.

    James

    Tolt Solutions

Comments are closed.

Skip to main content