Interpreting DirectSetup Flags in the Callback Function

When the application-defined callback function DirectXSetupCallbackFunction is called by the DirectXSetup function, it is passed a parameter that contains the reason that the callback function was invoked. If the reason is DSETUP_CB_MSG_CHECK_DRIVER_UPGRADE, the pInfo parameter points to a structure containing flags that summarize the DirectXSetup function's recommendations on how the upgrade of DirectX components, display drivers, and audio drivers should be performed. For a chart that summarizes the callback function flags, see DirectXSetupCallbackFunction. The structure member containing the flags is called UpgradeFlags .

The flags passed through the UpgradeFlags member of the structure that is pointed to by the pInfo parameter of the callback function are present when the Reason parameter of the callback function is DSETUP_CB_MSG_CHECK_DRIVER_UPGRADE. They occur in the following combinations:

Primary Upgrade Flags
These flags are mutually exclusive. One of them is always present in the UpgradeFlags structure member.

DSETUP_BC_UPGRADE_FORCE

DSETUP_BC_UPGRADE_KEEP

DSETUP_BC_UPGRADE_SAFE

DSETUP_BC_UPGRADE_UNKNOWN

Secondary Upgrade Flags
Any or all of these flags may be present in the UpgradeFlags structure member.

DSETUP_BC_UPGRADE_CANTBACKUP

DSETUP_BC_UPGRADE_HASWARNINGS

Device Active Flag
This flag is present in the UpgradeFlags structure member if the device whose driver is being upgraded is active. This flag may be present in combination with any of the others.

DSETUP_BC_UPGRADE_DEVICE_ACTIVE

Device Class Flags
These flags are mutually exclusive. One of them is always present in the UpgradeFlags structure member.

DSETUP_BC_UPGRADE_DISPLAY

DSETUP_BC_UPGRADE_MEDIA

Every time the Reason parameter has the value DSETUP_CB_MSG_CHECK_DRIVER_UPGRADE, the UpgradeFlags member of the structure pointed to by pInfo contains one Primary Upgrade Flag, zero or more Secondary Upgrade Flags, zero or one Device Active Flag, and one Device Class Flag.

If the UpgradeFlags member is set to DSETUP_CB_UPGRADE_KEEP, the DirectX component or device driver can't be upgraded. Performing an upgrade would cause Windows to cease functioning properly. The DirectXSetup function will not perform an upgrade on the component or driver.

A value of DSETUP_CB_UPGRADE_FORCE in the UpgradeFlags structure member means that the component or driver must be upgraded for Windows to function properly. The DirectXSetup function will upgrade the driver or component. It is possible that the upgrade may adversely affect some programs on the system. When the DirectXSetup function detects this condition, the UpgradeFlags member will be set to DSETUP_CB_UPGRADE_FORCE | DSETUP_CB_UPGRADE_HAS_WARNINGS, where the symbol | represents a bitwise OR operation. When this occurs, the DirectXSetup function will perform the upgrade, but issue a warning to the user.

Components and drivers are considered safe for upgrade if they will not adversely affect the operation of Windows when they are installed. In this case, the UpgradeFlags member will be set to DSETUP_CB_UPGRADE_SAFE. It is possible that the upgrade can be safe for Windows, but still cause problems for programs installed on the system. When DirectXSetup detects this condition, the UpgradeFlags member will contain the value DSETUP_CB_UPGRADE_SAFE | DSETUP_CB_UPGRADE_HAS_WARNINGS. If this occurs, the default action for the DirectXSetup function is to not perform the upgrade.

If no callback is provided, the DirectXSetup function calls the Win32® API function MessageBox to get input from the user if needed. Typically, the DirectXSetup function performs the default action without notifying the user. The application-defined function DirectXSetupCallbackFunction returns the same values that MessageBox would return if it were used.

The MessageBox function displays a message and some buttons for user response. When it is called, flags are passed to it that indicate what buttons should be present and which is the default button. These same flags are passed to the application-defined function DirectXSetupCallbackFunction in the MsgType parameter. These flags are the same flags that can be passed to the MessageBox function through its uType parameter.

The callback function should return what MessageBox would return if it were used. For instance, a callback function can be called with the flags in the MsgType parameter set to MB_YESNO | MB_DEFBUTTON1, where the | symbol is a bitwise OR operation. If MessageBox were called with these flags, it would present the user with a dialog box containing the Yes and No buttons. The default button is the Yes button. The callback should do something that is functionally equivalent to that. In this example, the return value of MessageBox would be the ID of the button that the user selected, either IDYES or IDNO. The return value of the callback function should be whichever button the user selects.

A more complete discussion of the flags and the appropriate return values is contained in the Platform SDK documentation for the MessageBox function.

The following code is a function that can be used by DirectSetup callback functions. It illustrates the process of determining the ID of the default button for any allowable set of input flags.

INT DefaultButton(DWORD MsgType)
{
    INT iDefaultButton=0;

    switch (MsgType & 0x0F0F)
    {
        case MB_OK          | MB_DEFBUTTON1:
        case MB_OKCANCEL    | MB_DEFBUTTON1:
            iDefaultButton = IDOK;
        break;

        case MB_OKCANCEL    | MB_DEFBUTTON2:
        case MB_RETRYCANCEL | MB_DEFBUTTON2:
        case MB_YESNOCANCEL | MB_DEFBUTTON3:
            iDefaultButton = IDCANCEL;
        break;

        case MB_ABORTRETRYIGNORE | MB_DEFBUTTON1:
            iDefaultButton = IDABORT;
        break;

        case MB_RETRYCANCEL      | MB_DEFBUTTON1:
        case MB_ABORTRETRYIGNORE | MB_DEFBUTTON2:
            iDefaultButton = IDRETRY;
        break;

        case MB_ABORTRETRYIGNORE | MB_DEFBUTTON3:
            iDefaultButton = IDIGNORE;
        break;

        case MB_YESNO       | MB_DEFBUTTON1:
        case MB_YESNOCANCEL | MB_DEFBUTTON1:
            iDefaultButton = IDYES;
        break;

        case MB_YESNO       | MB_DEFBUTTON2:
        case MB_YESNOCANCEL | MB_DEFBUTTON2:
            iDefaultButton = IDNO;
        break;
    }

    return iDefaultButton;
}

In this example, the function uses bitwise OR operations to determine what kind of dialog box the MessageBox function would display, and which button is the default. A callback function can use a similar method to determine what value it should return.