0

I have an UMDF driver which currently is redistributed through 2 standalone installers, one for x64 and one for x86.

The install driver function is this one, copied from devcon:

bool InstallDriver(const TCHAR* InfPath, const wchar_t* TargetID)
{
#define MAX_CLASS_NAME_LEN    32
    GUID ClassGUID = {};
    TCHAR ClassName[MAX_CLASS_NAME_LEN] = {};
    TCHAR hwIdList[LINE_LEN + 4] = {};

    //
    // List of hardware ID's must be double zero-terminated
    //
    ZeroMemory(hwIdList, sizeof(hwIdList));
    if (FAILED(StringCchCopy(hwIdList, LINE_LEN, TargetID)))
    {
        return false;
    }


//
// Use the INF File to extract the Class GUID.
//
    if (!SetupDiGetINFClass(InfPath, &ClassGUID, ClassName, sizeof(ClassName) / sizeof(ClassName[0]), 0))
    {
        return false;
    }
//
// Create the container for the to-be-created Device Information Element.
//
    HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
    DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID, 0);
    if (DeviceInfoSet == INVALID_HANDLE_VALUE)
    {
        return false;
    }


//
// Now create the element.
// Use the Class GUID and Name from the INF file.
//
    SP_DEVINFO_DATA DeviceInfoData;
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    if (!SetupDiCreateDeviceInfo(DeviceInfoSet,
        ClassName,
        &ClassGUID,
        NULL,
        0,
        DICD_GENERATE_ID,
        &DeviceInfoData))
    {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        return false;
    }

//
// Add the HardwareID to the Device's HardwareID property.
//
    if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
        &DeviceInfoData,
        SPDRP_HARDWAREID,
        (LPBYTE)hwIdList,
        (lstrlen(hwIdList) + 1 + 1) * sizeof(TCHAR)))
    {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        return false;
    }

//
// Transform the registry element into an actual devnode
// in the PnP HW tree.
//
    if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
        DeviceInfoSet,
        &DeviceInfoData))
    {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        return false;
    }

//
// update the driver for the device we just created
//
    if (!UpdateDriverForPlugAndPlayDevices(0, TargetID, InfPath, INSTALLFLAG_FORCE, 0))
    {
        int y = GetLastError();
        if (y == ERROR_IN_WOW64 || y == ERROR_NO_SUCH_DEVINST || y == ERROR_NO_SUCH_DEVINST || y == ERROR_FILE_NOT_FOUND)
        {

        }
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        return false;
    }


    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    return true;
}

This works OK, but I want to have a single x86 redistributable which would contain both the x86 and x64 drivers and detect if running in WOW64 and install the x64 driver.

This time the InstallDriver function fails at this call:

if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
    DeviceInfoSet,
    &DeviceInfoData))
{
    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    return false;
}

Last error 3758096949.

I couldn't find more info on that error, plus I didn't see any tip in SetupDiSetDeviceRegistryProperty to set the registry to the x64 one, like in RegCreateKeyEx's KEY_WOW64_64KEY flag.

Is there a way to avoid the 2 executables?

Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78
  • 3758096949 is 0x‭E0000235‬ see: https://stackoverflow.com/questions/41834535/driverpackagepreinstall-to-work-on-64-bit-compiled-to-32-bit – Richard Critten Jan 31 '20 at 16:55
  • 1
    you got `ERROR_IN_WOW64` from [`UpdateDriverForPlugAndPlayDevicesW`](https://learn.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-updatedriverforplugandplaydevicesw) - *The calling application is a 32-bit application attempting to execute in a 64-bit environment, which is not allowed.*. unfortunately this is by design if you need use this api – RbMm Jan 31 '20 at 17:40
  • Move the installation code to a 64bit app, then launch that from your 32bit app – Remy Lebeau Jan 31 '20 at 19:48

0 Answers0