advprop.c

来自「一个类似windows」· C语言 代码 · 共 1,799 行 · 第 1/4 页

C
1,799
字号
                             couldn't be found
                             - disable  button
                           - else
                             - Properties
                         - else
                           - Update driver
                 */
                break;

            case CM_PROB_FAILED_ADD:
                TroubleShootStrId = IDS_PROPERTIES;
                break;
        }
    }

    if (LoadString(hDllInstance,
                   TroubleShootStrId,
                   dap->szTemp,
                   sizeof(dap->szTemp) / sizeof(dap->szTemp[0])) != 0)
    {
        SetWindowText(hDevProbBtn,
                      dap->szTemp);
    }
    EnableWindow(hDevProbBtn,
                 dap->IsAdmin && bDevActionAvailable);

    /* check if the device can be enabled/disabled */
    hDevUsage = GetDlgItem(hwndDlg,
                           IDC_DEVUSAGE);

    dap->CanDisable = FALSE;
    dap->DeviceStarted = FALSE;

    if (CanDisableDevice(DeviceInfoData->DevInst,
                         dap->hMachine,
                         &bFlag))
    {
        dap->CanDisable = bFlag;
    }

    if (IsDeviceStarted(DeviceInfoData->DevInst,
                        dap->hMachine,
                        &bFlag))
    {
        dap->DeviceStarted = bFlag;
    }

    /* enable/disable the device usage controls */
    EnableWindow(GetDlgItem(hwndDlg,
                            IDC_DEVUSAGELABEL),
                 dap->CanDisable && dap->IsAdmin);
    EnableWindow(hDevUsage,
                 dap->CanDisable && dap->IsAdmin);

    /* clear the combobox */
    SendMessage(hDevUsage,
                CB_RESETCONTENT,
                0,
                0);
    if (dap->CanDisable)
    {
        InitDevUsageActions(hwndDlg,
                            hDevUsage,
                            dap);
    }

    /* find out how many new device property sheets to add.
       fake a PROPSHEETHEADER structure, we don't plan to
       call PropertySheet again!*/
    psh.dwSize = sizeof(PROPSHEETHEADER);
    psh.dwFlags = 0;
    psh.nPages = 0;

    /* get the number of device property sheets for the device */
    if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet,
                                          DeviceInfoData,
                                          &psh,
                                          0,
                                          &nDriverPages,
                                          dap->PropertySheetType) &&
        nDriverPages != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        dap->nDevPropSheets += nDriverPages;
    }
    else
    {
        nDriverPages = 0;
    }

    /* include the driver page */
    if (dap->HasDriverPage)
        dap->nDevPropSheets++;

    /* add the device property sheets */
    if (dap->nDevPropSheets != 0)
    {
        dap->DevPropSheets = HeapAlloc(GetProcessHeap(),
                                       HEAP_ZERO_MEMORY,
                                       dap->nDevPropSheets * sizeof(HPROPSHEETPAGE));
        if (dap->DevPropSheets != NULL)
        {
            if (nDriverPages != 0)
            {
                psh.phpage = dap->DevPropSheets;

                /* query the device property sheet pages to add */
                if (SetupDiGetClassDevPropertySheets(DeviceInfoSet,
                                                     DeviceInfoData,
                                                     &psh,
                                                     dap->nDevPropSheets,
                                                     NULL,
                                                     dap->PropertySheetType))
                {
                    /* add the property sheets */
                    for (iPage = 0;
                         iPage != nDriverPages;
                         iPage++)
                    {
                        PropSheet_AddPage(hPropSheetDlg,
                                          dap->DevPropSheets[iPage]);
                    }

                    dap->FreeDevPropSheets = TRUE;
                }
                else
                {
                    /* cleanup, we were unable to get the device property sheets */
                    iPage = nDriverPages;
                    dap->nDevPropSheets -= nDriverPages;
                    nDriverPages = 0;
                }
            }
            else
                iPage = 0;

            /* add the driver page if necessary */
            if (dap->HasDriverPage)
            {
                PROPSHEETPAGE pspDriver = {0};
                pspDriver.dwSize = sizeof(PROPSHEETPAGE);
                pspDriver.dwFlags = PSP_DEFAULT;
                pspDriver.hInstance = hDllInstance;
                pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDRIVER);
                pspDriver.pfnDlgProc = AdvProcDriverDlgProc;
                pspDriver.lParam = (LPARAM)dap;
                dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver);
                if (dap->DevPropSheets[iPage] != NULL)
                {
                    if (PropSheet_AddPage(hPropSheetDlg,
                                          dap->DevPropSheets[iPage]))
                    {
                        iPage++;
                    }
                    else
                    {
                        dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
                        dap->DevPropSheets[iPage] = NULL;
                    }
                }
            }
        }
        else
            dap->nDevPropSheets = 0;
    }

    /* finally, disable the apply button */
    PropSheet_UnChanged(hPropSheetDlg,
                        hwndDlg);
    dap->DeviceUsageChanged = FALSE;
}


static LRESULT
CALLBACK
DlgParentSubWndProc(IN HWND hwnd,
                    IN UINT uMsg,
                    IN WPARAM wParam,
                    IN LPARAM lParam)
{
    PDEVADVPROP_INFO dap;

    dap = (PDEVADVPROP_INFO)GetProp(hwnd,
                                    L"DevMgrDevChangeSub");
    if (dap != NULL)
    {
        if (uMsg == WM_DEVICECHANGE && !IsWindowVisible(dap->hWndGeneralPage))
        {
            SendMessage(dap->hWndGeneralPage,
                        WM_DEVICECHANGE,
                        wParam,
                        lParam);
        }

        /* pass the message the the old window proc */
        return CallWindowProc(dap->ParentOldWndProc,
                              hwnd,
                              uMsg,
                              wParam,
                              lParam);
    }
    else
    {
        /* this is not a good idea if the subclassed window was an ansi
           window, but we failed finding out the previous window proc
           so we can't use CallWindowProc. This should rarely - if ever -
           happen. */

        return DefWindowProc(hwnd,
                             uMsg,
                             wParam,
                             lParam);
    }
}


static INT_PTR
CALLBACK
AdvPropGeneralDlgProc(IN HWND hwndDlg,
                      IN UINT uMsg,
                      IN WPARAM wParam,
                      IN LPARAM lParam)
{
    PDEVADVPROP_INFO dap;
    INT_PTR Ret = FALSE;

    dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg,
                                             DWL_USER);

    if (dap != NULL || uMsg == WM_INITDIALOG)
    {
        switch (uMsg)
        {
            case WM_COMMAND:
            {
                switch (LOWORD(wParam))
                {
                    case IDC_DEVUSAGE:
                    {
                        if (HIWORD(wParam) == CBN_SELCHANGE)
                        {
                            PropSheet_Changed(GetParent(hwndDlg),
                                              hwndDlg);
                            dap->DeviceUsageChanged = TRUE;
                        }
                        break;
                    }

                    case IDC_DEVPROBLEM:
                    {
                        if (dap->IsAdmin)
                        {
                            /* display the device problem wizard */
                            ShowDeviceProblemWizard(hwndDlg,
                                                    dap->DeviceInfoSet,
                                                    &dap->DeviceInfoData,
                                                    dap->hMachine);
                        }
                        break;
                    }
                }
                break;
            }

            case WM_NOTIFY:
            {
                NMHDR *hdr = (NMHDR*)lParam;
                switch (hdr->code)
                {
                    case PSN_APPLY:
                        ApplyGeneralSettings(hwndDlg,
                                             dap);
                        break;
                }
                break;
            }

            case WM_INITDIALOG:
            {
                dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
                if (dap != NULL)
                {
                    HWND hWndParent;

                    dap->hWndGeneralPage = hwndDlg;

                    SetWindowLongPtr(hwndDlg,
                                     DWL_USER,
                                     (DWORD_PTR)dap);

                    /* subclass the parent window to always receive
                       WM_DEVICECHANGE messages */
                    hWndParent = GetParent(hwndDlg);
                    if (hWndParent != NULL)
                    {
                        /* subclass the parent window. This is not safe
                           if the parent window belongs to another thread! */
                        dap->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent,
                                                                          GWLP_WNDPROC,
                                                                          (LONG_PTR)DlgParentSubWndProc);

                        if (dap->ParentOldWndProc != NULL &&
                            SetProp(hWndParent,
                                    L"DevMgrDevChangeSub",
                                    (HANDLE)dap))
                        {
                            dap->hWndParent = hWndParent;
                        }
                    }

                    /* do not call UpdateDevInfo directly in here because it modifies
                       the pages of the property sheet! */
                    PostMessage(hwndDlg,
                                PM_INITIALIZE,
                                0,
                                0);
                }
                Ret = TRUE;
                break;
            }

            case WM_DEVICECHANGE:
            {
                /* FIXME - don't call UpdateDevInfo for all events */
                UpdateDevInfo(hwndDlg,
                              dap,
                              TRUE);
                Ret = TRUE;
                break;
            }

            case PM_INITIALIZE:
            {
                UpdateDevInfo(hwndDlg,
                              dap,
                              FALSE);
                dap->PageInitialized = TRUE;
                break;
            }

            case WM_DESTROY:
            {
                /* restore the old window proc of the subclassed parent window */
                if (dap->hWndParent != NULL && dap->ParentOldWndProc != NULL)
                {
                    if (SetWindowLongPtr(dap->hWndParent,
                                         GWLP_WNDPROC,
                                         (LONG_PTR)dap->ParentOldWndProc) == (LONG_PTR)DlgParentSubWndProc)
                    {
                        RemoveProp(dap->hWndParent,
                                   L"DevMgrDevChangeSub");
                    }
                }
                break;
            }
        }
    }

    return Ret;
}


INT_PTR
DisplayDeviceAdvancedProperties(IN HWND hWndParent,
                                IN LPCWSTR lpDeviceID  OPTIONAL,
                                IN HDEVINFO DeviceInfoSet,
                                IN PSP_DEVINFO_DATA DeviceInfoData,
                                IN HINSTANCE hComCtl32,
                                IN LPCWSTR lpMachineName,
                                IN DWORD dwFlags)
{
    PROPSHEETHEADER psh = {0};
    PROPSHEETPAGE pspGeneral = {0};
    PPROPERTYSHEETW pPropertySheetW;
    PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW;
    PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage;
    PDEVADVPROP_INFO DevAdvPropInfo;
    HMACHINE hMachine = NULL;
    DWORD DevIdSize = 0;
    INT_PTR Ret = -1;

    /* we don't want to statically link against comctl32, so find the
       functions we need dynamically */
    pPropertySheetW =
        (PPROPERTYSHEETW)GetProcAddress(hComCtl32,
                                        "PropertySheetW");
    pCreatePropertySheetPageW =
        (PCREATEPROPERTYSHEETPAGEW)GetProcAddress(hComCtl32,
                                                  "CreatePropertySheetPageW");
    pDestroyPropertySheetPage =
        (PDESTROYPROPERTYSHEETPAGE)GetProcAddress(hComCtl32,
                                                  "DestroyPropertySheetPage");
    if (pPropertySheetW == NULL ||
        pCreatePropertySheetPageW == NULL ||
        pDestroyPropertySheetPage == NULL)
    {
        return -1;
    }

    if (lpDeviceID == NULL)
    {
        /* find out how much size is needed for the device id */
        if (SetupDiGetDeviceInstanceId(DeviceInfoSet,
                                       DeviceInfoData,
                                       NULL,
                                       0,
                                       &DevIdSize))
        {
            DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
            return -1;
        }

        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        {
            return -1;
        }
    }
    else
    {
        DevIdSize = (DWORD)wcslen(lpDeviceID) + 1;
    }

    if (lpMachineName != NULL && lpMachineName[0] != L'\0')
    {
        CONFIGRET cr = CM_Connect_Machine(lpMachineName,
                                          &hMachine);
        if (cr != CR_SUCCESS)
        {
            return -1;
        }
    }

    /* create the internal structure associated with the "General",
       "Driver", ... pages */
    DevAdvPropInfo = HeapAlloc(GetProcessHeap(),
                               HEAP_ZERO_MEMORY,
                               FIELD_OFFSET(DEVADVPROP_INFO,
                                            szDeviceID) +
                                   (DevIdSize * sizeof(WCHAR)));
    if (DevAdvPropInfo == NULL)
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        goto Cleanup;
    }

    if (lpDeviceID == NULL)
    {
        /* read the device instance id */
        if (!SetupDiGetDeviceInstanceId(DeviceInfoSet,
                                        DeviceInfoData,
                                        DevAdvPropInfo->szDeviceID,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?