ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

advprop.c
Go to the documentation of this file.
00001 /*
00002  * ReactOS Device Manager Applet
00003  * Copyright (C) 2004 - 2005 ReactOS Team
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 /*
00020  *
00021  * PROJECT:         ReactOS devmgr.dll
00022  * FILE:            lib/devmgr/advprop.c
00023  * PURPOSE:         ReactOS Device Manager
00024  * PROGRAMMER:      Thomas Weidenmueller <w3seek@reactos.com>
00025  *                  Ged Murphy <gedmurphy@reactos.org>
00026  * UPDATE HISTORY:
00027  *      04-04-2004  Created
00028  */
00029 #include <precomp.h>
00030 
00031 #define NDEBUG
00032 #include <debug.h>
00033 
00034 typedef INT_PTR (WINAPI *PPROPERTYSHEETW)(LPCPROPSHEETHEADERW);
00035 typedef HPROPSHEETPAGE (WINAPI *PCREATEPROPERTYSHEETPAGEW)(LPCPROPSHEETPAGEW);
00036 typedef BOOL (WINAPI *PDESTROYPROPERTYSHEETPAGE)(HPROPSHEETPAGE);
00037 
00038 typedef struct _DEVADVPROP_INFO
00039 {
00040     HWND hWndGeneralPage;
00041     HWND hWndParent;
00042     WNDPROC ParentOldWndProc;
00043     HICON hDevIcon;
00044 
00045     HDEVINFO DeviceInfoSet;
00046     SP_DEVINFO_DATA DeviceInfoData;
00047     HDEVINFO CurrentDeviceInfoSet;
00048     SP_DEVINFO_DATA CurrentDeviceInfoData;
00049     DEVINST ParentDevInst;
00050     HMACHINE hMachine;
00051     LPCWSTR lpMachineName;
00052 
00053     HINSTANCE hComCtl32;
00054     PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW;
00055     PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage;
00056 
00057     DWORD PropertySheetType;
00058     DWORD nDevPropSheets;
00059     HPROPSHEETPAGE *DevPropSheets;
00060 
00061     union
00062     {
00063         UINT Flags;
00064         struct
00065         {
00066             UINT Extended : 1;
00067             UINT FreeDevPropSheets : 1;
00068             UINT CanDisable : 1;
00069             UINT DeviceStarted : 1;
00070             UINT DeviceUsageChanged : 1;
00071             UINT CloseDevInst : 1;
00072             UINT IsAdmin : 1;
00073             UINT DoDefaultDevAction : 1;
00074             UINT PageInitialized : 1;
00075             UINT ShowRemotePages : 1;
00076             UINT HasDriverPage : 1;
00077             UINT HasResourcePage : 1;
00078             UINT HasPowerPage : 1;
00079         };
00080     };
00081 
00082     WCHAR szDevName[255];
00083     WCHAR szTemp[255];
00084     WCHAR szDeviceID[1];
00085     /* struct may be dynamically expanded here! */
00086 } DEVADVPROP_INFO, *PDEVADVPROP_INFO;
00087 
00088 
00089 typedef struct _ENUMDRIVERFILES_CONTEXT
00090 {
00091     HWND hDriversListView;
00092     UINT nCount;
00093 } ENUMDRIVERFILES_CONTEXT, *PENUMDRIVERFILES_CONTEXT;
00094 
00095 #define PM_INITIALIZE (WM_APP + 0x101)
00096 
00097 
00098 static UINT WINAPI
00099 EnumDeviceDriverFilesCallback(IN PVOID Context,
00100                               IN UINT Notification,
00101                               IN UINT_PTR Param1,
00102                               IN UINT_PTR Param2)
00103 {
00104     LVITEM li;
00105     PENUMDRIVERFILES_CONTEXT EnumDriverFilesContext = (PENUMDRIVERFILES_CONTEXT)Context;
00106 
00107     li.mask = LVIF_TEXT | LVIF_STATE;
00108     li.iItem = EnumDriverFilesContext->nCount++;
00109     li.iSubItem = 0;
00110     li.state = (li.iItem == 0 ? LVIS_SELECTED : 0);
00111     li.stateMask = LVIS_SELECTED;
00112     li.pszText = (LPWSTR)Param1;
00113     (void)ListView_InsertItem(EnumDriverFilesContext->hDriversListView,
00114                               &li);
00115     return NO_ERROR;
00116 }
00117 
00118 
00119 static VOID
00120 UpdateDriverDetailsDlg(IN HWND hwndDlg,
00121                        IN HWND hDriversListView,
00122                        IN PDEVADVPROP_INFO dap)
00123 {
00124     HDEVINFO DeviceInfoSet;
00125     PSP_DEVINFO_DATA DeviceInfoData;
00126     SP_DRVINFO_DATA DriverInfoData;
00127     ENUMDRIVERFILES_CONTEXT EnumDriverFilesContext;
00128 
00129     if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
00130     {
00131         DeviceInfoSet = dap->CurrentDeviceInfoSet;
00132         DeviceInfoData = &dap->CurrentDeviceInfoData;
00133     }
00134     else
00135     {
00136         DeviceInfoSet = dap->DeviceInfoSet;
00137         DeviceInfoData = &dap->DeviceInfoData;
00138     }
00139 
00140     /* set the device image */
00141     SendDlgItemMessage(hwndDlg,
00142                        IDC_DEVICON,
00143                        STM_SETICON,
00144                        (WPARAM)dap->hDevIcon,
00145                        0);
00146 
00147     /* set the device name edit control text */
00148     SetDlgItemText(hwndDlg,
00149                    IDC_DEVNAME,
00150                    dap->szDevName);
00151 
00152     /* fill the driver files list view */
00153     EnumDriverFilesContext.hDriversListView = hDriversListView;
00154     EnumDriverFilesContext.nCount = 0;
00155 
00156     (void)ListView_DeleteAllItems(EnumDriverFilesContext.hDriversListView);
00157     DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
00158     if (FindCurrentDriver(DeviceInfoSet,
00159                           DeviceInfoData,
00160                           &DriverInfoData) &&
00161         SetupDiSetSelectedDriver(DeviceInfoSet,
00162                                  DeviceInfoData,
00163                                  &DriverInfoData))
00164     {
00165         HSPFILEQ queueHandle;
00166 
00167         queueHandle = SetupOpenFileQueue();
00168         if (queueHandle != (HSPFILEQ)INVALID_HANDLE_VALUE)
00169         {
00170             SP_DEVINSTALL_PARAMS DeviceInstallParams = {0};
00171             DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
00172             if (SetupDiGetDeviceInstallParams(DeviceInfoSet,
00173                                               DeviceInfoData,
00174                                               &DeviceInstallParams))
00175             {
00176                 DeviceInstallParams.FileQueue = queueHandle;
00177                 DeviceInstallParams.Flags |= DI_NOVCP;
00178 
00179                 if (SetupDiSetDeviceInstallParams(DeviceInfoSet,
00180                                                   DeviceInfoData,
00181                                                   &DeviceInstallParams) &&
00182                     SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES,
00183                                               DeviceInfoSet,
00184                                               DeviceInfoData))
00185                 {
00186                     DWORD scanResult;
00187                     RECT rcClient;
00188                     LVCOLUMN lvc;
00189 
00190                     /* enumerate the driver files */
00191                     SetupScanFileQueue(queueHandle,
00192                                        SPQ_SCAN_USE_CALLBACK,
00193                                        NULL,
00194                                        EnumDeviceDriverFilesCallback,
00195                                        &EnumDriverFilesContext,
00196                                        &scanResult);
00197 
00198                     /* update the list view column width */
00199                     GetClientRect(hDriversListView,
00200                                   &rcClient);
00201                     lvc.mask = LVCF_WIDTH;
00202                     lvc.cx = rcClient.right;
00203                     (void)ListView_SetColumn(hDriversListView,
00204                                              0,
00205                                              &lvc);
00206 
00207                     /* highlight the first item from list */
00208                     if (ListView_GetSelectedCount(hDriversListView) != 0)
00209                     {
00210                         ListView_SetItemState(hDriversListView,
00211                                               0,
00212                                               LVIS_FOCUSED | LVIS_SELECTED,
00213                                               LVIS_FOCUSED | LVIS_SELECTED);
00214                     }
00215                 }
00216             }
00217 
00218             SetupCloseFileQueue(queueHandle);
00219         }
00220     }
00221 }
00222 
00223 
00224 static VOID
00225 UpdateDriverVersionInfoDetails(IN HWND hwndDlg,
00226                                IN LPCWSTR lpszDriverPath)
00227 {
00228     DWORD dwHandle;
00229     DWORD dwVerInfoSize;
00230     LPVOID lpData = NULL;
00231     LPVOID lpInfo;
00232     UINT uInfoLen;
00233     DWORD dwLangId;
00234     WCHAR szLangInfo[255];
00235     WCHAR szLangPath[MAX_PATH];
00236     LPWSTR lpCompanyName = NULL;
00237     LPWSTR lpFileVersion = NULL;
00238     LPWSTR lpLegalCopyright = NULL;
00239     LPWSTR lpDigitalSigner = NULL;
00240     UINT uBufLen;
00241     WCHAR szNotAvailable[255];
00242 
00243     /* extract version info from selected file */
00244     dwVerInfoSize = GetFileVersionInfoSize(lpszDriverPath,
00245                                            &dwHandle);
00246     if (!dwVerInfoSize)
00247         goto done;
00248 
00249     lpData = HeapAlloc(GetProcessHeap(),
00250                        HEAP_ZERO_MEMORY,
00251                        dwVerInfoSize);
00252     if (!lpData)
00253         goto done;
00254 
00255     if (!GetFileVersionInfo(lpszDriverPath,
00256                             dwHandle,
00257                             dwVerInfoSize,
00258                             lpData))
00259         goto done;
00260 
00261     if (!VerQueryValue(lpData,
00262                        L"\\VarFileInfo\\Translation",
00263                        &lpInfo,
00264                        &uInfoLen))
00265         goto done;
00266 
00267     dwLangId = *(LPDWORD)lpInfo;
00268     swprintf(szLangInfo, L"\\StringFileInfo\\%04x%04x\\",
00269              LOWORD(dwLangId), HIWORD(dwLangId));
00270 
00271     /* read CompanyName */
00272     wcscpy(szLangPath, szLangInfo);
00273     wcscat(szLangPath, L"CompanyName");
00274 
00275     VerQueryValue(lpData,
00276                   szLangPath,
00277                   (void **)&lpCompanyName,
00278                   (PUINT)&uBufLen);
00279 
00280     /* read FileVersion */
00281     wcscpy(szLangPath, szLangInfo);
00282     wcscat(szLangPath, L"FileVersion");
00283 
00284     VerQueryValue(lpData,
00285                   szLangPath,
00286                   (void **)&lpFileVersion,
00287                   (PUINT)&uBufLen);
00288 
00289     /* read LegalTrademarks */
00290     wcscpy(szLangPath, szLangInfo);
00291     wcscat(szLangPath, L"LegalCopyright");
00292 
00293     VerQueryValue(lpData,
00294                   szLangPath,
00295                   (void **)&lpLegalCopyright,
00296                   (PUINT)&uBufLen);
00297 
00298     /* TODO: read digital signer info */
00299 
00300 done:
00301     if (!LoadString(hDllInstance,
00302                     IDS_NOTAVAILABLE,
00303                     szNotAvailable,
00304                     sizeof(szNotAvailable) / sizeof(WCHAR)))
00305     {
00306         wcscpy(szNotAvailable, L"n/a");
00307     }
00308 
00309     /* update labels */
00310     if (!lpCompanyName)
00311         lpCompanyName = szNotAvailable;
00312     SetDlgItemText(hwndDlg,
00313                    IDC_FILEPROVIDER,
00314                    lpCompanyName);
00315 
00316     if (!lpFileVersion)
00317         lpFileVersion = szNotAvailable;
00318     SetDlgItemText(hwndDlg,
00319                    IDC_FILEVERSION,
00320                    lpFileVersion);
00321 
00322     if (!lpLegalCopyright)
00323         lpLegalCopyright = szNotAvailable;
00324     SetDlgItemText(hwndDlg,
00325                    IDC_FILECOPYRIGHT,
00326                    lpLegalCopyright);
00327 
00328     if (!lpDigitalSigner)
00329         lpDigitalSigner = szNotAvailable;
00330     SetDlgItemText(hwndDlg,
00331                    IDC_DIGITALSIGNER,
00332                    lpDigitalSigner);
00333 
00334     /* release version info */
00335     if (lpData)
00336         HeapFree(GetProcessHeap(),
00337                  0,
00338                  lpData);
00339 }
00340 
00341 
00342 static INT_PTR
00343 CALLBACK
00344 DriverDetailsDlgProc(IN HWND hwndDlg,
00345                      IN UINT uMsg,
00346                      IN WPARAM wParam,
00347                      IN LPARAM lParam)
00348 {
00349     PDEVADVPROP_INFO dap;
00350     INT_PTR Ret = FALSE;
00351 
00352     dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg,
00353                                              DWL_USER);
00354 
00355     if (dap != NULL || uMsg == WM_INITDIALOG)
00356     {
00357         switch (uMsg)
00358         {
00359             case WM_COMMAND:
00360             {
00361                 switch (LOWORD(wParam))
00362                 {
00363                     case IDOK:
00364                     case IDCANCEL:
00365                     {
00366                         EndDialog(hwndDlg,
00367                                   IDOK);
00368                         break;
00369                     }
00370                 }
00371                 break;
00372             }
00373 
00374             case WM_CLOSE:
00375             {
00376                 EndDialog(hwndDlg,
00377                           IDCANCEL);
00378                 break;
00379             }
00380 
00381             case WM_INITDIALOG:
00382             {
00383                 LV_COLUMN lvc;
00384                 HWND hDriversListView;
00385 
00386                 dap = (PDEVADVPROP_INFO)lParam;
00387                 if (dap != NULL)
00388                 {
00389                     SetWindowLongPtr(hwndDlg,
00390                                      DWL_USER,
00391                                      (DWORD_PTR)dap);
00392 
00393                     hDriversListView = GetDlgItem(hwndDlg,
00394                                                   IDC_DRIVERFILES);
00395 
00396                     /* add a column to the list view control */
00397                     lvc.mask = LVCF_FMT | LVCF_WIDTH;
00398                     lvc.fmt = LVCFMT_LEFT;
00399                     lvc.cx = 0;
00400                     (void)ListView_InsertColumn(hDriversListView,
00401                                                 0,
00402                                                 &lvc);
00403 
00404                     UpdateDriverDetailsDlg(hwndDlg,
00405                                            hDriversListView,
00406                                            dap);
00407                 }
00408 
00409                 Ret = TRUE;
00410                 break;
00411             }
00412 
00413             case WM_NOTIFY:
00414             {
00415                 LPNMHDR pnmhdr = (LPNMHDR)lParam;
00416 
00417                 switch (pnmhdr->code)
00418                 {
00419                 case LVN_ITEMCHANGED:
00420                     {
00421                         LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
00422                         HWND hDriversListView = GetDlgItem(hwndDlg,
00423                                                            IDC_DRIVERFILES);
00424 
00425                         if (ListView_GetSelectedCount(hDriversListView) == 0)
00426                         {
00427                             /* nothing is selected - empty the labels */
00428                             SetDlgItemText(hwndDlg,
00429                                            IDC_FILEPROVIDER,
00430                                            NULL);
00431                             SetDlgItemText(hwndDlg,
00432                                            IDC_FILEVERSION,
00433                                            NULL);
00434                             SetDlgItemText(hwndDlg,
00435                                            IDC_FILECOPYRIGHT,
00436                                            NULL);
00437                             SetDlgItemText(hwndDlg,
00438                                            IDC_DIGITALSIGNER,
00439                                            NULL);
00440                         }
00441                         else if (pnmv->uNewState != 0)
00442                         {
00443                             /* extract version info and update the labels */
00444                             WCHAR szDriverPath[MAX_PATH];
00445 
00446                             ListView_GetItemText(hDriversListView,
00447                                                  pnmv->iItem,
00448                                                  pnmv->iSubItem,
00449                                                  szDriverPath,
00450                                                  MAX_PATH);
00451 
00452                             UpdateDriverVersionInfoDetails(hwndDlg,
00453                                                            szDriverPath);
00454                         }
00455                     }
00456                 }
00457                 break;
00458             }
00459         }
00460     }
00461 
00462     return Ret;
00463 }
00464 
00465 
00466 static VOID
00467 UpdateDriverDlg(IN HWND hwndDlg,
00468                 IN PDEVADVPROP_INFO dap)
00469 {
00470     HDEVINFO DeviceInfoSet;
00471     PSP_DEVINFO_DATA DeviceInfoData;
00472 
00473     if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
00474     {
00475         DeviceInfoSet = dap->CurrentDeviceInfoSet;
00476         DeviceInfoData = &dap->CurrentDeviceInfoData;
00477     }
00478     else
00479     {
00480         DeviceInfoSet = dap->DeviceInfoSet;
00481         DeviceInfoData = &dap->DeviceInfoData;
00482     }
00483 
00484     /* set the device image */
00485     SendDlgItemMessage(hwndDlg,
00486                        IDC_DEVICON,
00487                        STM_SETICON,
00488                        (WPARAM)dap->hDevIcon,
00489                        0);
00490 
00491     /* set the device name edit control text */
00492     SetDlgItemText(hwndDlg,
00493                    IDC_DEVNAME,
00494                    dap->szDevName);
00495 
00496     /* query the driver provider */
00497     if (GetDriverProviderString(DeviceInfoSet,
00498                                 DeviceInfoData,
00499                                 dap->szTemp,
00500                                 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
00501     {
00502         SetDlgItemText(hwndDlg,
00503                        IDC_DRVPROVIDER,
00504                        dap->szTemp);
00505     }
00506 
00507     /* query the driver date */
00508     if (GetDriverDateString(DeviceInfoSet,
00509                             DeviceInfoData,
00510                             dap->szTemp,
00511                             sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
00512     {
00513         SetDlgItemText(hwndDlg,
00514                        IDC_DRVDATE,
00515                        dap->szTemp);
00516     }
00517 
00518     /* query the driver version */
00519     if (GetDriverVersionString(DeviceInfoSet,
00520                                DeviceInfoData,
00521                                dap->szTemp,
00522                                sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
00523     {
00524         SetDlgItemText(hwndDlg,
00525                        IDC_DRVVERSION,
00526                        dap->szTemp);
00527     }
00528 }
00529 
00530 
00531 static INT_PTR
00532 CALLBACK
00533 AdvProcDriverDlgProc(IN HWND hwndDlg,
00534                      IN UINT uMsg,
00535                      IN WPARAM wParam,
00536                      IN LPARAM lParam)
00537 {
00538     PDEVADVPROP_INFO dap;
00539     INT_PTR Ret = FALSE;
00540 
00541     dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg,
00542                                              DWL_USER);
00543 
00544     if (dap != NULL || uMsg == WM_INITDIALOG)
00545     {
00546         switch (uMsg)
00547         {
00548             case WM_COMMAND:
00549             {
00550                 switch (LOWORD(wParam))
00551                 {
00552                     case IDC_DRIVERDETAILS:
00553                     {
00554                         DialogBoxParam(hDllInstance,
00555                                        MAKEINTRESOURCE(IDD_DRIVERDETAILS),
00556                                        hwndDlg,
00557                                        DriverDetailsDlgProc,
00558                                        (ULONG_PTR)dap);
00559                         break;
00560                     }
00561                 }
00562                 break;
00563             }
00564 
00565             case WM_NOTIFY:
00566             {
00567                 NMHDR *hdr = (NMHDR*)lParam;
00568                 switch (hdr->code)
00569                 {
00570                     case PSN_APPLY:
00571                         break;
00572                 }
00573                 break;
00574             }
00575 
00576             case WM_INITDIALOG:
00577             {
00578                 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
00579                 if (dap != NULL)
00580                 {
00581                     SetWindowLongPtr(hwndDlg,
00582                                      DWL_USER,
00583                                      (DWORD_PTR)dap);
00584 
00585                     UpdateDriverDlg(hwndDlg,
00586                                     dap);
00587                 }
00588                 Ret = TRUE;
00589                 break;
00590             }
00591         }
00592     }
00593 
00594     return Ret;
00595 }
00596 
00597 
00598 static VOID
00599 SetListViewText(HWND hwnd,
00600                 INT iItem,
00601                 LPWSTR lpText)
00602 {
00603     LVITEM li;
00604 
00605     li.mask = LVIF_TEXT | LVIF_STATE;
00606     li.iItem = iItem;
00607     li.iSubItem = 0;
00608     li.state = 0; //(li.iItem == 0 ? LVIS_SELECTED : 0);
00609     li.stateMask = LVIS_SELECTED;
00610     li.pszText = lpText;
00611     (void)ListView_InsertItem(hwnd,
00612                               &li);
00613 }
00614 
00615 
00616 static VOID
00617 UpdateDetailsDlg(IN HWND hwndDlg,
00618                  IN PDEVADVPROP_INFO dap)
00619 {
00620     HWND hwndComboBox;
00621     HWND hwndListView;
00622     LV_COLUMN lvc;
00623     RECT rcClient;
00624 
00625     UINT i;
00626     UINT Properties[] =
00627     {
00628         IDS_PROP_DEVICEID,
00629         IDS_PROP_HARDWAREIDS,
00630         IDS_PROP_COMPATIBLEIDS,
00631         IDS_PROP_MATCHINGDEVICEID,
00632         IDS_PROP_SERVICE,
00633         IDS_PROP_ENUMERATOR,
00634         IDS_PROP_CAPABILITIES,
00635         IDS_PROP_DEVNODEFLAGS,
00636         IDS_PROP_CONFIGFLAGS,
00637         IDS_PROP_CSCONFIGFLAGS,
00638         IDS_PROP_EJECTIONRELATIONS,
00639         IDS_PROP_REMOVALRELATIONS,
00640         IDS_PROP_BUSRELATIONS,
00641         IDS_PROP_DEVUPPERFILTERS,
00642         IDS_PROP_DEVLOWERFILTERS,
00643         IDS_PROP_CLASSUPPERFILTERS,
00644         IDS_PROP_CLASSLOWERFILTERS,
00645         IDS_PROP_CLASSINSTALLER,
00646         IDS_PROP_CLASSCOINSTALLER,
00647         IDS_PROP_DEVICECOINSTALLER,
00648         IDS_PROP_FIRMWAREREVISION,
00649         IDS_PROP_CURRENTPOWERSTATE,
00650         IDS_PROP_POWERCAPABILITIES,
00651         IDS_PROP_POWERSTATEMAPPINGS
00652     };
00653 
00654 
00655     /* set the device image */
00656     SendDlgItemMessage(hwndDlg,
00657                        IDC_DEVICON,
00658                        STM_SETICON,
00659                        (WPARAM)dap->hDevIcon,
00660                        0);
00661 
00662     /* set the device name edit control text */
00663     SetDlgItemText(hwndDlg,
00664                    IDC_DEVNAME,
00665                    dap->szDevName);
00666 
00667 
00668     hwndComboBox = GetDlgItem(hwndDlg,
00669                               IDC_DETAILSPROPNAME);
00670 
00671     hwndListView = GetDlgItem(hwndDlg,
00672                               IDC_DETAILSPROPVALUE);
00673 
00674     for (i = 0; i != sizeof(Properties) / sizeof(Properties[0]); i++)
00675     {
00676         /* fill in the device usage combo box */
00677         if (LoadString(hDllInstance,
00678                        Properties[i],
00679                        dap->szTemp,
00680                        sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
00681         {
00682             SendMessage(hwndComboBox,
00683                         CB_ADDSTRING,
00684                         0,
00685                         (LPARAM)dap->szTemp);
00686         }
00687     }
00688 
00689 
00690     GetClientRect(hwndListView,
00691                   &rcClient);
00692 
00693     /* add a column to the list view control */
00694     lvc.mask = LVCF_FMT | LVCF_WIDTH;
00695     lvc.fmt = LVCFMT_LEFT;
00696     lvc.cx = rcClient.right;
00697     (void)ListView_InsertColumn(hwndListView,
00698                                 0,
00699                                 &lvc);
00700 
00701     SendMessage(hwndComboBox,
00702                 CB_SETCURSEL,
00703                 0,
00704                 0);
00705 
00706     SetListViewText(hwndListView, 0, dap->szDeviceID);
00707 
00708     SetFocus(hwndComboBox);
00709 }
00710 
00711 
00712 static VOID
00713 DisplayDevicePropertyText(IN PDEVADVPROP_INFO dap,
00714                           IN HWND hwndListView,
00715                           IN DWORD dwProperty)
00716 {
00717     HDEVINFO DeviceInfoSet;
00718     PSP_DEVINFO_DATA DeviceInfoData;
00719     DWORD dwType;
00720     DWORD dwSize;
00721     DWORD dwValue;
00722     LPBYTE lpBuffer;
00723     LPWSTR lpStr;
00724     INT len;
00725     INT index;
00726 
00727     if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
00728     {
00729         DeviceInfoSet = dap->CurrentDeviceInfoSet;
00730         DeviceInfoData = &dap->CurrentDeviceInfoData;
00731     }
00732     else
00733     {
00734         DeviceInfoSet = dap->DeviceInfoSet;
00735         DeviceInfoData = &dap->DeviceInfoData;
00736     }
00737 
00738     dwSize = 0;
00739     SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
00740                                      DeviceInfoData,
00741                                      dwProperty,
00742                                      &dwType,
00743                                      NULL,
00744                                      0,
00745                                      &dwSize);
00746     if (dwSize == 0)
00747     {
00748         if (GetLastError() != ERROR_FILE_NOT_FOUND)
00749         {
00750             swprintf(dap->szTemp, L"Error: Getting the size failed! (Error: %ld)", GetLastError());
00751             SetListViewText(hwndListView, 0, dap->szTemp);
00752         }
00753         return;
00754     }
00755 
00756     lpBuffer = HeapAlloc(GetProcessHeap(),
00757                          HEAP_ZERO_MEMORY,
00758                          dwSize);
00759     if (lpBuffer == NULL)
00760     {
00761         SetListViewText(hwndListView, 0, L"Error: Allocating the buffer failed!");
00762         return;
00763     }
00764 
00765     if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
00766                                          DeviceInfoData,
00767                                          dwProperty,
00768                                          &dwType,
00769                                          lpBuffer,
00770                                          dwSize,
00771                                          &dwSize))
00772     {
00773         if (dwType == REG_SZ)
00774         {
00775             SetListViewText(hwndListView, 0, (LPWSTR)lpBuffer);
00776         }
00777         else if (dwType == REG_MULTI_SZ)
00778         {
00779             lpStr = (LPWSTR)lpBuffer;
00780             index = 0;
00781             while (*lpStr != 0)
00782             {
00783                 len = wcslen(lpStr) + 1;
00784 
00785                 SetListViewText(hwndListView, index, lpStr);
00786 
00787                 lpStr += len;
00788                 index++;
00789             }
00790         }
00791         else if (dwType == REG_DWORD)
00792         {
00793             dwValue = *(DWORD *) lpBuffer;
00794 
00795             switch (dwProperty)
00796             {
00797                 case SPDRP_CAPABILITIES:
00798                     index = 0;
00799                     if (dwValue & CM_DEVCAP_LOCKSUPPORTED)
00800                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_LOCKSUPPORTED");
00801                     if (dwValue & CM_DEVCAP_EJECTSUPPORTED)
00802                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_EJECTSUPPORTED");
00803                     if (dwValue & CM_DEVCAP_REMOVABLE)
00804                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_REMOVABLE");
00805                     if (dwValue & CM_DEVCAP_DOCKDEVICE)
00806                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_DOCKDEVICE");
00807                     if (dwValue & CM_DEVCAP_UNIQUEID)
00808                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_UNIQUEID");
00809                     if (dwValue & CM_DEVCAP_SILENTINSTALL)
00810                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_SILENTINSTALL");
00811                     if (dwValue & CM_DEVCAP_RAWDEVICEOK)
00812                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_RAWDEVICEOK");
00813                     if (dwValue & CM_DEVCAP_SURPRISEREMOVALOK)
00814                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_SURPRISEREMOVALOK");
00815                     if (dwValue & CM_DEVCAP_HARDWAREDISABLED)
00816                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_HARDWAREDISABLED");
00817                     if (dwValue & CM_DEVCAP_NONDYNAMIC)
00818                         SetListViewText(hwndListView, index++, L"CM_DEVCAP_NONDYNAMIC");
00819                     break;
00820 
00821                 case SPDRP_CONFIGFLAGS:
00822                     index = 0;
00823                     if (dwValue & CONFIGFLAG_DISABLED)
00824                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_DISABLED");
00825                     if (dwValue & CONFIGFLAG_REMOVED)
00826                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_REMOVED");
00827                     if (dwValue & CONFIGFLAG_MANUAL_INSTALL)
00828                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_MANUAL_INSTALL");
00829                     if (dwValue & CONFIGFLAG_IGNORE_BOOT_LC)
00830                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_IGNORE_BOOT_LC");
00831                     if (dwValue & CONFIGFLAG_NET_BOOT)
00832                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_NET_BOOT");
00833                     if (dwValue & CONFIGFLAG_REINSTALL)
00834                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_REINSTALL");
00835                     if (dwValue & CONFIGFLAG_FAILEDINSTALL)
00836                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_FAILEDINSTALL");
00837                     if (dwValue & CONFIGFLAG_CANTSTOPACHILD)
00838                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_CANTSTOPACHILD");
00839                     if (dwValue & CONFIGFLAG_OKREMOVEROM)
00840                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_OKREMOVEROM");
00841                     if (dwValue & CONFIGFLAG_NOREMOVEEXIT)
00842                         SetListViewText(hwndListView, index++, L"CONFIGFLAG_NOREMOVEEXIT");
00843                     break;
00844 
00845                 default:
00846                     swprintf(dap->szTemp, L"0x%08lx", dwValue);
00847                     SetListViewText(hwndListView, 0, dap->szTemp);
00848                     break;
00849             }
00850         }
00851         else
00852         {
00853             SetListViewText(hwndListView, 0, L"Error: Unsupported value type!");
00854 
00855         }
00856     }
00857     else
00858     {
00859         SetListViewText(hwndListView, 0, L"Error: Retrieving the value failed!");
00860     }
00861 
00862     HeapFree(GetProcessHeap(),
00863              0,
00864              lpBuffer);
00865 }
00866 
00867 static VOID
00868 DisplayDevNodeFlags(IN PDEVADVPROP_INFO dap,
00869                     IN HWND hwndListView)
00870 {
00871     DWORD dwStatus = 0;
00872     DWORD dwProblem = 0;
00873     INT index;
00874 
00875     CM_Get_DevNode_Status_Ex(&dwStatus,
00876                              &dwProblem,
00877                              dap->DeviceInfoData.DevInst,
00878                              0,
00879                              dap->hMachine);
00880 
00881     index = 0;
00882     if (dwStatus & DN_ROOT_ENUMERATED)
00883         SetListViewText(hwndListView, index++, L"DN_ROOT_ENUMERATED");
00884     if (dwStatus & DN_DRIVER_LOADED)
00885         SetListViewText(hwndListView, index++, L"DN_DRIVER_LOADED");
00886     if (dwStatus & DN_ENUM_LOADED)
00887         SetListViewText(hwndListView, index++, L"DN_ENUM_LOADED");
00888     if (dwStatus & DN_STARTED)
00889         SetListViewText(hwndListView, index++, L"DN_STARTED");
00890     if (dwStatus & DN_MANUAL)
00891         SetListViewText(hwndListView, index++, L"DN_MANUAL");
00892     if (dwStatus & DN_NEED_TO_ENUM)
00893         SetListViewText(hwndListView, index++, L"DN_NEED_TO_ENUM");
00894     if (dwStatus & DN_DRIVER_BLOCKED)
00895         SetListViewText(hwndListView, index++, L"DN_DRIVER_BLOCKED");
00896     if (dwStatus & DN_HARDWARE_ENUM)
00897         SetListViewText(hwndListView, index++, L"DN_HARDWARE_ENUM");
00898     if (dwStatus & DN_NEED_RESTART)
00899         SetListViewText(hwndListView, index++, L"DN_NEED_RESTART");
00900     if (dwStatus & DN_CHILD_WITH_INVALID_ID)
00901         SetListViewText(hwndListView, index++, L"DN_CHILD_WITH_INVALID_ID");
00902     if (dwStatus & DN_HAS_PROBLEM)
00903         SetListViewText(hwndListView, index++, L"DN_HAS_PROBLEM");
00904     if (dwStatus & DN_FILTERED)
00905         SetListViewText(hwndListView, index++, L"DN_FILTERED");
00906     if (dwStatus & DN_LEGACY_DRIVER)
00907         SetListViewText(hwndListView, index++, L"DN_LEGACY_DRIVER");
00908     if (dwStatus & DN_DISABLEABLE)
00909         SetListViewText(hwndListView, index++, L"DN_DISABLEABLE");
00910     if (dwStatus & DN_REMOVABLE)
00911         SetListViewText(hwndListView, index++, L"DN_REMOVABLE");
00912     if (dwStatus & DN_PRIVATE_PROBLEM)
00913         SetListViewText(hwndListView, index++, L"DN_PRIVATE_PROBLEM");
00914     if (dwStatus & DN_MF_PARENT)
00915         SetListViewText(hwndListView, index++, L"DN_MF_PARENT");
00916     if (dwStatus & DN_MF_CHILD)
00917         SetListViewText(hwndListView, index++, L"DN_MF_CHILD");
00918     if (dwStatus & DN_WILL_BE_REMOVED)
00919         SetListViewText(hwndListView, index++, L"DN_WILL_BE_REMOVED");
00920 
00921     if (dwStatus & DN_NOT_FIRST_TIMEE)
00922         SetListViewText(hwndListView, index++, L"DN_NOT_FIRST_TIMEE");
00923     if (dwStatus & DN_STOP_FREE_RES)
00924         SetListViewText(hwndListView, index++, L"DN_STOP_FREE_RES");
00925     if (dwStatus & DN_REBAL_CANDIDATE)
00926         SetListViewText(hwndListView, index++, L"DN_REBAL_CANDIDATE");
00927     if (dwStatus & DN_BAD_PARTIAL)
00928         SetListViewText(hwndListView, index++, L"DN_BAD_PARTIAL");
00929     if (dwStatus & DN_NT_ENUMERATOR)
00930         SetListViewText(hwndListView, index++, L"DN_NT_ENUMERATOR");
00931     if (dwStatus & DN_NT_DRIVER)
00932         SetListViewText(hwndListView, index++, L"DN_NT_DRIVER");
00933 
00934     if (dwStatus & DN_NEEDS_LOCKING)
00935         SetListViewText(hwndListView, index++, L"DN_NEEDS_LOCKING");
00936     if (dwStatus & DN_ARM_WAKEUP)
00937         SetListViewText(hwndListView, index++, L"DN_ARM_WAKEUP");
00938     if (dwStatus & DN_APM_ENUMERATOR)
00939         SetListViewText(hwndListView, index++, L"DN_APM_ENUMERATOR");
00940     if (dwStatus & DN_APM_DRIVER)
00941         SetListViewText(hwndListView, index++, L"DN_APM_DRIVER");
00942     if (dwStatus & DN_SILENT_INSTALL)
00943         SetListViewText(hwndListView, index++, L"DN_SILENT_INSTALL");
00944     if (dwStatus & DN_NO_SHOW_IN_DM)
00945         SetListViewText(hwndListView, index++, L"DN_NO_SHOW_IN_DM");
00946     if (dwStatus & DN_BOOT_LOG_PROB)
00947         SetListViewText(hwndListView, index++, L"DN_BOOT_LOG_PROB");
00948 
00949 //    swprintf(dap->szTemp, L"0x%08x", dwStatus);
00950 //    SetListViewText(hwndListView, 0, dap->szTemp);
00951 }
00952 
00953 
00954 static VOID
00955 DisplayDevNodeEnumerator(IN PDEVADVPROP_INFO dap,
00956                          IN HWND hwndListView)
00957 {
00958     PSP_DEVINFO_DATA DeviceInfoData;
00959 
00960     DWORD dwType = 0;
00961     WCHAR szBuffer[256];
00962     DWORD dwSize = 256 * sizeof(WCHAR);
00963 
00964     if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
00965     {
00966         DeviceInfoData = &dap->CurrentDeviceInfoData;
00967     }
00968     else
00969     {
00970         DeviceInfoData = &dap->DeviceInfoData;
00971     }
00972 
00973     CM_Get_DevNode_Registry_Property_ExW(DeviceInfoData->DevInst,
00974                                          CM_DRP_ENUMERATOR_NAME,
00975                                          &dwType,
00976                                          &szBuffer,
00977                                          &dwSize,
00978                                          0,
00979                                          dap->hMachine);
00980 
00981     SetListViewText(hwndListView, 0, szBuffer);
00982 }
00983 
00984 
00985 static VOID
00986 DisplayCsFlags(IN PDEVADVPROP_INFO dap,
00987                IN HWND hwndListView)
00988 {
00989     DWORD dwValue = 0;
00990     INT index;
00991 
00992     CM_Get_HW_Prof_Flags_Ex(dap->szDevName,
00993                             0, /* current hardware profile */
00994                             &dwValue,
00995                             0,
00996                             dap->hMachine);
00997 
00998     index = 0;
00999     if (dwValue & CSCONFIGFLAG_DISABLED)
01000         SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DISABLED");
01001 
01002     if (dwValue & CSCONFIGFLAG_DO_NOT_CREATE)
01003         SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_CREATE");
01004 
01005     if (dwValue & CSCONFIGFLAG_DO_NOT_START)
01006         SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_START");
01007 }
01008 
01009 
01010 static VOID
01011 DisplayMatchingDeviceId(IN PDEVADVPROP_INFO dap,
01012                         IN HWND hwndListView)
01013 {
01014     HDEVINFO DeviceInfoSet;
01015     PSP_DEVINFO_DATA DeviceInfoData;
01016     WCHAR szBuffer[256];
01017     HKEY hKey;
01018     DWORD dwSize;
01019     DWORD dwType;
01020 
01021     if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
01022     {
01023         DeviceInfoSet = dap->CurrentDeviceInfoSet;
01024         DeviceInfoData = &dap->CurrentDeviceInfoData;
01025     }
01026     else
01027     {
01028         DeviceInfoSet = dap->DeviceInfoSet;
01029         DeviceInfoData = &dap->DeviceInfoData;
01030     }
01031 
01032     hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
01033                                 DeviceInfoData,
01034                                 DICS_FLAG_GLOBAL,
01035                                 0,
01036                                 DIREG_DRV,
01037                                 KEY_QUERY_VALUE);
01038     if (hKey != INVALID_HANDLE_VALUE)
01039     {
01040         dwSize = 256 * sizeof(WCHAR);
01041         if (RegQueryValueEx(hKey,
01042                             L"MatchingDeviceId",
01043                             NULL,
01044                             &dwType,
01045                             (LPBYTE)szBuffer,
01046                             &dwSize) == ERROR_SUCCESS)
01047         {
01048             SetListViewText(hwndListView, 0, szBuffer);
01049         }
01050 
01051         RegCloseKey(hKey);
01052     }
01053 }
01054 
01055 
01056 static VOID
01057 DisplayDeviceCoinstallers(IN PDEVADVPROP_INFO dap,
01058                           IN HWND hwndListView)
01059 {
01060     HDEVINFO DeviceInfoSet;
01061     PSP_DEVINFO_DATA DeviceInfoData;
01062     HKEY hKey;
01063     DWORD dwSize;
01064     DWORD dwType;
01065     LPBYTE lpBuffer;
01066     LPWSTR lpStr;
01067     INT index;
01068     INT len;
01069 
01070     if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
01071     {
01072         DeviceInfoSet = dap->CurrentDeviceInfoSet;
01073         DeviceInfoData = &dap->CurrentDeviceInfoData;
01074     }
01075     else
01076     {
01077         DeviceInfoSet = dap->DeviceInfoSet;
01078         DeviceInfoData = &dap->DeviceInfoData;
01079     }
01080 
01081     hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
01082                                 DeviceInfoData,
01083                                 DICS_FLAG_GLOBAL,
01084                                 0,
01085                                 DIREG_DRV,
01086                                 KEY_QUERY_VALUE);
01087     if (hKey != INVALID_HANDLE_VALUE)
01088     {
01089         dwSize = 0;
01090         if (RegQueryValueEx(hKey,
01091                             L"CoInstallers32",
01092                             NULL,
01093                             &dwType,
01094                             NULL,
01095                             &dwSize) == ERROR_SUCCESS &&
01096             dwSize > 0)
01097         {
01098 
01099             lpBuffer = HeapAlloc(GetProcessHeap(),
01100                                  HEAP_ZERO_MEMORY,
01101                                  dwSize);
01102 
01103             RegQueryValueEx(hKey,
01104                             L"CoInstallers32",
01105                             NULL,
01106                             &dwType,
01107                             lpBuffer,
01108                             &dwSize);
01109 
01110             lpStr = (LPWSTR)lpBuffer;
01111             index = 0;
01112             while (*lpStr != 0)
01113             {
01114                 len = wcslen(lpStr) + 1;
01115 
01116                 SetListViewText(hwndListView, index, lpStr);
01117 
01118                 lpStr += len;
01119                 index++;
01120             }
01121 
01122             HeapFree(GetProcessHeap(),
01123                      0,
01124                      lpBuffer);
01125         }
01126 
01127         RegCloseKey(hKey);
01128     }
01129 }
01130 
01131 
01132 static VOID
01133 DisplayClassProperties(IN PDEVADVPROP_INFO dap,
01134                        IN HWND hwndListView,
01135                        IN LPWSTR lpProperty)
01136 {
01137     HDEVINFO DeviceInfoSet;
01138     PSP_DEVINFO_DATA DeviceInfoData;
01139     WCHAR szClassGuid[45];
01140     DWORD dwSize;
01141     DWORD dwType;
01142     HKEY hKey;
01143     GUID ClassGuid;
01144     LPBYTE lpBuffer;
01145     LPWSTR lpStr;
01146     INT index = 0;
01147     INT len;
01148 
01149     if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
01150     {
01151         DeviceInfoSet = dap->CurrentDeviceInfoSet;
01152         DeviceInfoData = &dap->CurrentDeviceInfoData;
01153     }
01154     else
01155     {
01156         DeviceInfoSet = dap->DeviceInfoSet;
01157         DeviceInfoData = &dap->DeviceInfoData;
01158     }
01159 
01160     dwSize = 45 * sizeof(WCHAR);
01161     if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
01162                                           DeviceInfoData,
01163                                           SPDRP_CLASSGUID,
01164                                           &dwType,
01165                                           (LPBYTE)szClassGuid,
01166                                           dwSize,
01167                                           &dwSize))
01168         return;
01169 
01170     pSetupGuidFromString(szClassGuid,
01171                          &ClassGuid);
01172 
01173     hKey = SetupDiOpenClassRegKey(&ClassGuid,
01174                                   KEY_QUERY_VALUE);
01175     if (hKey != INVALID_HANDLE_VALUE)
01176     {
01177         dwSize = 0;
01178         if (RegQueryValueEx(hKey,
01179                             lpProperty,
01180                             NULL,
01181                             &dwType,
01182                             NULL,
01183                             &dwSize) == ERROR_SUCCESS &&
01184             dwSize > 0)
01185         {
01186             lpBuffer = HeapAlloc(GetProcessHeap(),
01187                                  HEAP_ZERO_MEMORY,
01188                                  dwSize);
01189 
01190             RegQueryValueEx(hKey,
01191                             lpProperty,
01192                             NULL,
01193                             &dwType,
01194                             lpBuffer,
01195                             &dwSize);
01196 
01197             if (dwType == REG_SZ)
01198             {
01199                 SetListViewText(hwndListView, 0, (LPWSTR)lpBuffer);
01200             }
01201             else if (dwType == REG_MULTI_SZ)
01202             {
01203                 lpStr = (LPWSTR)lpBuffer;
01204                 index = 0;
01205                 while (*lpStr != 0)
01206                 {
01207                     len = wcslen(lpStr) + 1;
01208 
01209                     SetListViewText(hwndListView, index, lpStr);
01210 
01211                     lpStr += len;
01212                     index++;
01213                 }
01214             }
01215 
01216             HeapFree(GetProcessHeap(),
01217                      0,
01218                      lpBuffer);
01219         }
01220 
01221         RegCloseKey(hKey);
01222     }
01223 }
01224 
01225 
01226 static VOID
01227 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap,
01228                         IN HWND hwndComboBox,
01229                         IN HWND hwndListView)
01230 {
01231     INT Index;
01232 
01233     Index = (INT)SendMessage(hwndComboBox,
01234                              CB_GETCURSEL,
01235                              0,
01236                              0);
01237     if (Index == CB_ERR)
01238         return;
01239 
01240     (void)ListView_DeleteAllItems(hwndListView);
01241 
01242     switch (Index)
01243     {
01244         case 0:
01245             SetListViewText(hwndListView, 0, dap->szDeviceID);
01246             break;
01247 
01248         case 1: /* Hardware ID */
01249             DisplayDevicePropertyText(dap,
01250                                       hwndListView,
01251                                       SPDRP_HARDWAREID);
01252             break;
01253 
01254         case 2: /* Compatible IDs */
01255             DisplayDevicePropertyText(dap,
01256                                       hwndListView,
01257                                       SPDRP_COMPATIBLEIDS);
01258             break;
01259 
01260         case 3: /* Matching ID */
01261             DisplayMatchingDeviceId(dap,
01262                                     hwndListView);
01263             break;
01264 
01265         case 4: /* Service */
01266             DisplayDevicePropertyText(dap,
01267                                       hwndListView,
01268                                       SPDRP_SERVICE);
01269             break;
01270 
01271         case 5: /* Enumerator */
01272             DisplayDevNodeEnumerator(dap,
01273                                      hwndListView);
01274             break;
01275 
01276         case 6: /* Capabilities */
01277             DisplayDevicePropertyText(dap,
01278                                       hwndListView,
01279                                       SPDRP_CAPABILITIES);
01280             break;
01281 
01282         case 7: /* Devnode Flags */
01283             DisplayDevNodeFlags(dap,
01284                                 hwndListView);
01285             break;
01286 
01287         case 8: /* Config Flags */
01288             DisplayDevicePropertyText(dap,
01289                                       hwndListView,
01290                                       SPDRP_CONFIGFLAGS);
01291             break;
01292 
01293         case 9: /* CSConfig Flags */
01294             DisplayCsFlags(dap,
01295                            hwndListView);
01296             break;
01297 
01298 #if 0
01299         case 10: /* Ejection relation */
01300             break;
01301 
01302         case 11: /* Removal relations */
01303             break;
01304 
01305         case 12: /* Bus relation */
01306             break;
01307 #endif
01308 
01309         case 13: /* Device Upper Filters */
01310             DisplayDevicePropertyText(dap,
01311                                       hwndListView,
01312                                       SPDRP_UPPERFILTERS);
01313             break;
01314 
01315         case 14: /* Device Lower Filters */
01316             DisplayDevicePropertyText(dap,
01317                                       hwndListView,
01318                                       SPDRP_LOWERFILTERS);
01319             break;
01320 
01321         case 15: /* Class Upper Filters */
01322             DisplayClassProperties(dap,
01323                                    hwndListView,
01324                                    L"UpperFilters");
01325             break;
01326 
01327         case 16: /* Class Lower Filters */
01328             DisplayClassProperties(dap,
01329                                    hwndListView,
01330                                    L"LowerFilters");
01331             break;
01332 
01333         case 17: /* Class Installer */
01334             DisplayClassProperties(dap,
01335                                    hwndListView,
01336                                    L"Installer32");
01337             break;
01338 
01339 #if 0
01340         case 18: /* Class Coinstaller */
01341             break;
01342 #endif
01343 
01344         case 19: /* Device Coinstaller */
01345             DisplayDeviceCoinstallers(dap,
01346                                       hwndListView);
01347             break;
01348 
01349 #if 0
01350         case 20: /* Firmware Revision */
01351             break;
01352 
01353         case 21: /* Current Power State */
01354             break;
01355 
01356         case 20: /* Power Capabilities */
01357             break;
01358 
01359         case 21: /* Power State Mappings */
01360             break;
01361 #endif
01362 
01363         default:
01364             SetListViewText(hwndListView, 0, L"<Not implemented yet>");
01365             break;
01366     }
01367 }
01368 
01369 
01370 static INT_PTR
01371 CALLBACK
01372 AdvProcDetailsDlgProc(IN HWND hwndDlg,
01373                       IN UINT uMsg,
01374                       IN WPARAM wParam,
01375                       IN LPARAM lParam)
01376 {
01377     PDEVADVPROP_INFO dap;
01378     INT_PTR Ret = FALSE;
01379 
01380     dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg,
01381                                              DWL_USER);
01382 
01383     if (dap != NULL || uMsg == WM_INITDIALOG)
01384     {
01385         switch (uMsg)
01386         {
01387             case WM_COMMAND:
01388             {
01389                 switch (LOWORD(wParam))
01390                 {
01391                     case IDC_DETAILSPROPNAME:
01392                         if (HIWORD(wParam) == CBN_SELCHANGE)
01393                         {
01394                             DisplayDeviceProperties(dap,
01395                                                     GetDlgItem(hwndDlg, IDC_DETAILSPROPNAME),
01396                                                     GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE));
01397                         }
01398                         break;
01399                 }
01400                 break;
01401             }
01402 
01403             case WM_NOTIFY:
01404             {
01405                 NMHDR *hdr = (NMHDR*)lParam;
01406                 switch (hdr->code)
01407                 {
01408                     case PSN_APPLY:
01409                         break;
01410                 }
01411                 break;
01412             }
01413 
01414             case WM_INITDIALOG:
01415             {
01416                 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
01417                 if (dap != NULL)
01418                 {
01419                     SetWindowLongPtr(hwndDlg,
01420                                      DWL_USER,
01421                                      (DWORD_PTR)dap);
01422 
01423                     UpdateDetailsDlg(hwndDlg,
01424                                      dap);
01425                 }
01426                 Ret = TRUE;
01427                 break;
01428             }
01429         }
01430     }
01431 
01432     return Ret;
01433 }
01434 
01435 
01436 static VOID
01437 InitDevUsageActions(IN HWND hwndDlg,
01438                     IN HWND hComboBox,
01439                     IN PDEVADVPROP_INFO dap)
01440 {
01441     INT Index;
01442     UINT i;
01443     UINT Actions[] =
01444     {
01445         IDS_ENABLEDEVICE,
01446         IDS_DISABLEDEVICE,
01447     };
01448 
01449     for (i = 0;
01450          i != sizeof(Actions) / sizeof(Actions[0]);
01451          i++)
01452     {
01453         /* fill in the device usage combo box */
01454         if (LoadString(hDllInstance,
01455                        Actions[i],
01456                        dap->szTemp,
01457                        sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
01458         {
01459             Index = (INT)SendMessage(hComboBox,
01460                                      CB_ADDSTRING,
01461                                      0,
01462                                      (LPARAM)dap->szTemp);
01463             if (Index != CB_ERR)
01464             {
01465                 SendMessage(hComboBox,
01466                             CB_SETITEMDATA,
01467                             (WPARAM)Index,
01468                             (LPARAM)Actions[i]);
01469 
01470                 switch (Actions[i])
01471                 {
01472                     case IDS_ENABLEDEVICE:
01473                         if (dap->DeviceStarted)
01474                         {
01475                             SendMessage(hComboBox,
01476                                         CB_SETCURSEL,
01477                                         (WPARAM)Index,
01478                                         0);
01479                         }
01480                         break;
01481 
01482                     case IDS_DISABLEDEVICE:
01483                         if (!dap->DeviceStarted)
01484                         {
01485                             SendMessage(hComboBox,
01486                                         CB_SETCURSEL,
01487                                         (WPARAM)Index,
01488                                         0);
01489                         }
01490                         break;
01491 
01492                     default:
01493                         break;
01494                 }
01495             }
01496         }
01497     }
01498 }
01499 
01500 
01501 static UINT
01502 GetSelectedUsageAction(IN HWND hComboBox)
01503 {
01504     INT Index;
01505     UINT Ret = 0;
01506 
01507     Index = (INT)SendMessage(hComboBox,
01508                              CB_GETCURSEL,
01509                              0,
01510                              0);
01511     if (Index != CB_ERR)
01512     {
01513         INT iRet = (INT) SendMessage(hComboBox,
01514                                CB_GETITEMDATA,
01515                                (WPARAM)Index,
01516                                0);
01517         if (iRet != CB_ERR)
01518         {
01519             Ret = (UINT)iRet;
01520         }
01521     }
01522 
01523     return Ret;
01524 }
01525 
01526 
01527 static BOOL
01528 ApplyGeneralSettings(IN HWND hwndDlg,
01529                      IN PDEVADVPROP_INFO dap)
01530 {
01531     BOOL Ret = FALSE;
01532 
01533     if (dap->DeviceUsageChanged && dap->IsAdmin && dap->CanDisable)
01534     {
01535         UINT SelectedUsageAction;
01536         BOOL NeedReboot = FALSE;
01537 
01538         SelectedUsageAction = GetSelectedUsageAction(GetDlgItem(hwndDlg,
01539                                                                 IDC_DEVUSAGE));
01540         switch (SelectedUsageAction)
01541         {
01542             case IDS_ENABLEDEVICE:
01543                 if (!dap->DeviceStarted)
01544                 {
01545                     Ret = EnableDevice(dap->DeviceInfoSet,
01546                                        &dap->DeviceInfoData,
01547                                        TRUE,
01548                                        0,
01549                                        &NeedReboot);
01550                 }
01551                 break;
01552 
01553             case IDS_DISABLEDEVICE:
01554                 if (dap->DeviceStarted)
01555                 {
01556                     Ret = EnableDevice(dap->DeviceInfoSet,
01557                                        &dap->DeviceInfoData,
01558                                        FALSE,
01559                                        0,
01560                                        &NeedReboot);
01561                 }
01562                 break;
01563 
01564             default:
01565                 break;
01566         }
01567 
01568         if (Ret)
01569         {
01570             if (NeedReboot)
01571             {
01572                 /* make PropertySheet() return PSM_REBOOTSYSTEM */
01573                 PropSheet_RebootSystem(hwndDlg);
01574             }
01575         }
01576         else
01577         {
01578             /* FIXME - display an error message */
01579             DPRINT1("Failed to enable/disable device! LastError: %d\n",
01580                     GetLastError());
01581         }
01582     }
01583     else
01584         Ret = !dap->DeviceUsageChanged;
01585 
01586     /* disable the apply button */
01587     PropSheet_UnChanged(GetParent(hwndDlg),
01588                         hwndDlg);
01589     dap->DeviceUsageChanged = FALSE;
01590     return Ret;
01591 }
01592 
01593 
01594 static VOID
01595 UpdateDevInfo(IN HWND hwndDlg,
01596               IN PDEVADVPROP_INFO dap,
01597               IN BOOL ReOpen)
01598 {
01599     HWND hDevUsage, hPropSheetDlg, hDevProbBtn;
01600     CONFIGRET cr;
01601     ULONG Status, ProblemNumber;
01602     SP_DEVINSTALL_PARAMS_W InstallParams;
01603     UINT TroubleShootStrId = IDS_TROUBLESHOOTDEV;
01604     BOOL bFlag, bDevActionAvailable = TRUE;
01605     BOOL bDrvInstalled = FALSE;
01606     DWORD iPage;
01607     HDEVINFO DeviceInfoSet = NULL;
01608     PSP_DEVINFO_DATA DeviceInfoData = NULL;
01609     PROPSHEETHEADER psh;
01610     DWORD nDriverPages = 0;
01611     BOOL RecalcPages = FALSE;
01612 
01613     hPropSheetDlg = GetParent(hwndDlg);
01614 
01615     if (dap->PageInitialized)
01616     {
01617         /* switch to the General page */
01618         PropSheet_SetCurSelByID(hPropSheetDlg,
01619                                 IDD_DEVICEGENERAL);
01620 
01621         /* remove and destroy the existing device property sheet pages */
01622         if (dap->DevPropSheets != NULL)
01623         {
01624             for (iPage = 0;
01625                  iPage != dap->nDevPropSheets;
01626                  iPage++)
01627             {
01628                 if (dap->DevPropSheets[iPage] != NULL)
01629                 {
01630                     PropSheet_RemovePage(hPropSheetDlg,
01631                                          (WPARAM) -1,
01632                                          dap->DevPropSheets[iPage]);
01633                     RecalcPages = TRUE;
01634                 }
01635             }
01636         }
01637     }
01638 
01639     iPage = 0;
01640 
01641     if (dap->FreeDevPropSheets)
01642     {
01643         /* don't free the array if it's the one allocated in
01644            DisplayDeviceAdvancedProperties */
01645         HeapFree(GetProcessHeap(),
01646                  0,
01647                  dap->DevPropSheets);
01648 
01649         dap->FreeDevPropSheets = FALSE;
01650     }
01651 
01652     dap->DevPropSheets = NULL;
01653     dap->nDevPropSheets = 0;
01654 
01655     if (ReOpen)
01656     {
01657         /* create a new device info set and re-open the device */
01658         if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
01659         {
01660             SetupDiDestroyDeviceInfoList(dap->CurrentDeviceInfoSet);
01661         }
01662 
01663         dap->ParentDevInst = 0;
01664         dap->CurrentDeviceInfoSet = SetupDiCreateDeviceInfoListEx(NULL,
01665                                                                   hwndDlg,
01666                                                                   dap->lpMachineName,
01667                                                                   NULL);
01668         if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
01669         {
01670             if (SetupDiOpenDeviceInfo(dap->CurrentDeviceInfoSet,
01671                                       dap->szDeviceID,
01672                                       hwndDlg,
01673                                       0,
01674                                       &dap->CurrentDeviceInfoData))
01675             {
01676                 if (dap->CloseDevInst)
01677                 {
01678                     SetupDiDestroyDeviceInfoList(dap->DeviceInfoSet);
01679                 }
01680 
01681                 dap->CloseDevInst = TRUE;
01682                 dap->DeviceInfoSet = dap->CurrentDeviceInfoSet;
01683                 dap->DeviceInfoData = dap->CurrentDeviceInfoData;
01684                 dap->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
01685             }
01686             else
01687                 goto GetParentNode;
01688         }
01689         else
01690         {
01691 GetParentNode:
01692             /* get the parent node from the initial devinst */
01693             CM_Get_Parent_Ex(&dap->ParentDevInst,
01694                              dap->DeviceInfoData.DevInst,
01695                              0,
01696                              dap->hMachine);
01697         }
01698 
01699         if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
01700         {
01701             DeviceInfoSet = dap->CurrentDeviceInfoSet;
01702             DeviceInfoData = &dap->CurrentDeviceInfoData;
01703         }
01704         else
01705         {
01706             DeviceInfoSet = dap->DeviceInfoSet;
01707             DeviceInfoData = &dap->DeviceInfoData;
01708         }
01709     }
01710     else
01711     {
01712         DeviceInfoSet = dap->DeviceInfoSet;
01713         DeviceInfoData = &dap->DeviceInfoData;
01714     }
01715 
01716     dap->HasDriverPage = FALSE;
01717     dap->HasResourcePage = FALSE;
01718     dap->HasPowerPage = FALSE;
01719     if (IsDriverInstalled(DeviceInfoData->DevInst,
01720                           dap->hMachine,
01721                           &bDrvInstalled) &&
01722         bDrvInstalled)
01723     {
01724         if (SetupDiCallClassInstaller((dap->ShowRemotePages ?
01725                                            DIF_ADDREMOTEPROPERTYPAGE_ADVANCED :
01726                                            DIF_ADDPROPERTYPAGE_ADVANCED),
01727                                       DeviceInfoSet,
01728                                       DeviceInfoData))
01729         {
01730             /* get install params */
01731             InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
01732             if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet,
01733                                                 DeviceInfoData,
01734                                                 &InstallParams))
01735             {
01736                 /* zero the flags */
01737                 InstallParams.Flags = 0;
01738             }
01739 
01740             dap->HasDriverPage = !(InstallParams.Flags & DI_DRIVERPAGE_ADDED);
01741             dap->HasResourcePage = !(InstallParams.Flags & DI_RESOURCEPAGE_ADDED);
01742             dap->HasPowerPage = !(InstallParams.Flags & DI_FLAGSEX_POWERPAGE_ADDED);
01743         }
01744     }
01745 
01746     /* get the device icon */
01747     if (dap->hDevIcon != NULL)
01748     {
01749         DestroyIcon(dap->hDevIcon);
01750         dap->hDevIcon = NULL;
01751     }
01752     if (!SetupDiLoadClassIcon(&DeviceInfoData->ClassGuid,
01753                               &dap->hDevIcon,
01754                               NULL))
01755     {
01756         dap->hDevIcon = NULL;
01757     }
01758 
01759     /* get the device name */
01760     if (GetDeviceDescriptionString(DeviceInfoSet,
01761                                    DeviceInfoData,
01762                                    dap->szDevName,
01763                                    sizeof(dap->szDevName) / sizeof(dap->szDevName[0])))
01764     {
01765         PropSheet_SetTitle(hPropSheetDlg,
01766                            PSH_PROPTITLE,
01767                            dap->szDevName);
01768     }
01769 
01770     /* set the device image */
01771     SendDlgItemMessage(hwndDlg,
01772                        IDC_DEVICON,
01773                        STM_SETICON,
01774                        (WPARAM)dap->hDevIcon,
01775                        0);
01776 
01777     /* set the device name edit control text */
01778     SetDlgItemText(hwndDlg,
01779                    IDC_DEVNAME,
01780                    dap->szDevName);
01781 
01782     /* set the device type edit control text */
01783     if (GetDeviceTypeString(DeviceInfoData,
01784                             dap->szTemp,
01785                             sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
01786     {
01787         SetDlgItemText(hwndDlg,
01788                        IDC_DEVTYPE,
01789                        dap->szTemp);
01790     }
01791 
01792     /* set the device manufacturer edit control text */
01793     if (GetDeviceManufacturerString(DeviceInfoSet,
01794                                     DeviceInfoData,
01795                                     dap->szTemp,
01796                                     sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
01797     {
01798         SetDlgItemText(hwndDlg,
01799                        IDC_DEVMANUFACTURER,
01800                        dap->szTemp);
01801     }
01802 
01803     /* set the device location edit control text */
01804     if (GetDeviceLocationString(DeviceInfoSet,
01805                                 DeviceInfoData,
01806                                 dap->ParentDevInst,
01807                                 dap->szTemp,
01808                                 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
01809     {
01810         SetDlgItemText(hwndDlg,
01811                        IDC_DEVLOCATION,
01812                        dap->szTemp);
01813     }
01814 
01815     /* set the device status edit control text */
01816     if (GetDeviceStatusString(DeviceInfoData->DevInst,
01817                               dap->hMachine,
01818                               dap->szTemp,
01819                               sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
01820     {
01821         SetDlgItemText(hwndDlg,
01822                        IDC_DEVSTATUS,
01823                        dap->szTemp);
01824     }
01825 
01826     /* set the device troubleshoot button text and disable it if necessary */
01827     hDevProbBtn = GetDlgItem(hwndDlg,
01828                              IDC_DEVPROBLEM);
01829     cr = CM_Get_DevNode_Status_Ex(&Status,
01830                                   &ProblemNumber,
01831                                   DeviceInfoData->DevInst,
01832                                   0,
01833                                   dap->hMachine);
01834     if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM))
01835     {
01836         switch (ProblemNumber)
01837         {
01838             case CM_PROB_DEVLOADER_FAILED:
01839             {
01840                 /* FIXME - only if it's not a root bus devloader,
01841                            disable the button otherwise */
01842                 TroubleShootStrId = IDS_UPDATEDRV;
01843                 break;
01844             }
01845 
01846             case CM_PROB_OUT_OF_MEMORY:
01847             case CM_PROB_ENTRY_IS_WRONG_TYPE:
01848             case CM_PROB_LACKED_ARBITRATOR:
01849             case CM_PROB_FAILED_START:
01850             case CM_PROB_LIAR:
01851             case CM_PROB_UNKNOWN_RESOURCE:
01852             {
01853                 TroubleShootStrId = IDS_UPDATEDRV;
01854                 break;
01855             }
01856 
01857             case CM_PROB_BOOT_CONFIG_CONFLICT:
01858             case CM_PROB_NORMAL_CONFLICT:
01859             case CM_PROB_REENUMERATION:
01860             {
01861                 /* FIXME - Troubleshoot conflict */
01862                 break;
01863             }
01864 
01865             case CM_PROB_FAILED_FILTER:
01866             case CM_PROB_REINSTALL:
01867             case CM_PROB_FAILED_INSTALL:
01868             {
01869                 TroubleShootStrId = IDS_REINSTALLDRV;
01870                 break;
01871             }
01872 
01873             case CM_PROB_DEVLOADER_NOT_FOUND:
01874             {
01875                 /* FIXME - 4 cases:
01876                    1) if it's a missing system devloader:
01877                       - disable the button (Reinstall Driver)
01878                    2) if it's not a system devloader but still missing:
01879                       - Reinstall Driver
01880                    3) if it's not a system devloader but the file can be found:
01881                       - Update Driver
01882                    4) if it's a missing or empty software key
01883                       - Update Driver
01884                  */
01885                 break;
01886             }
01887 
01888             case CM_PROB_INVALID_DATA:
01889             case CM_PROB_PARTIAL_LOG_CONF:
01890             case CM_PROB_NO_VALID_LOG_CONF:
01891             case CM_PROB_HARDWARE_DISABLED:
01892             case CM_PROB_CANT_SHARE_IRQ:
01893             case CM_PROB_TRANSLATION_FAILED:
01894             case CM_PROB_SYSTEM_SHUTDOWN:
01895             case CM_PROB_PHANTOM:
01896                 bDevActionAvailable = FALSE;
01897                 break;
01898 
01899             case CM_PROB_NOT_VERIFIED:
01900             case CM_PROB_DEVICE_NOT_THERE:
01901                 /* FIXME - search hardware */
01902                 break;
01903 
01904             case CM_PROB_NEED_RESTART:
01905             case CM_PROB_WILL_BE_REMOVED:
01906             case CM_PROB_MOVED:
01907             case CM_PROB_TOO_EARLY:
01908             case CM_PROB_DISABLED_SERVICE:
01909                 TroubleShootStrId = IDS_REBOOT;
01910                 break;
01911 
01912             case CM_PROB_REGISTRY:
01913                 /* FIXME - check registry? */
01914                 break;
01915 
01916             case CM_PROB_DISABLED:
01917                 /* if device was disabled by the user: */
01918                 TroubleShootStrId = IDS_ENABLEDEV;
01919                 /* FIXME - otherwise disable button because the device was
01920                            disabled by the system*/
01921                 break;
01922 
01923             case CM_PROB_DEVLOADER_NOT_READY:
01924                 /* FIXME - if it's a graphics adapter:
01925                            - if it's a a secondary adapter and the main adapter
01926                              couldn't be found
01927                              - disable  button
01928                            - else
01929                              - Properties
01930                          - else
01931                            - Update driver
01932                  */
01933                 break;
01934 
01935             case CM_PROB_FAILED_ADD:
01936                 TroubleShootStrId = IDS_PROPERTIES;
01937                 break;
01938         }
01939     }
01940 
01941     if (LoadString(hDllInstance,
01942                    TroubleShootStrId,
01943                    dap->szTemp,
01944                    sizeof(dap->szTemp) / sizeof(dap->szTemp[0])) != 0)
01945     {
01946         SetWindowText(hDevProbBtn,
01947                       dap->szTemp);
01948     }
01949     EnableWindow(hDevProbBtn,
01950                  dap->IsAdmin && bDevActionAvailable);
01951 
01952     /* check if the device can be enabled/disabled */
01953     hDevUsage = GetDlgItem(hwndDlg,
01954                            IDC_DEVUSAGE);
01955 
01956     dap->CanDisable = FALSE;
01957     dap->DeviceStarted = FALSE;
01958 
01959     if (CanDisableDevice(DeviceInfoData->DevInst,
01960                          dap->hMachine,
01961                          &bFlag))
01962     {
01963         dap->CanDisable = bFlag;
01964     }
01965 
01966     if (IsDeviceStarted(DeviceInfoData->DevInst,
01967                         dap->hMachine,
01968                         &bFlag))
01969     {
01970         dap->DeviceStarted = bFlag;
01971     }
01972 
01973     /* enable/disable the device usage controls */
01974     EnableWindow(GetDlgItem(hwndDlg,
01975                             IDC_DEVUSAGELABEL),
01976                  dap->CanDisable && dap->IsAdmin);
01977     EnableWindow(hDevUsage,
01978                  dap->CanDisable && dap->IsAdmin);
01979 
01980     /* clear the combobox */
01981     SendMessage(hDevUsage,
01982                 CB_RESETCONTENT,
01983                 0,
01984                 0);
01985     if (dap->CanDisable)
01986     {
01987         InitDevUsageActions(hwndDlg,
01988                             hDevUsage,
01989                             dap);
01990     }
01991 
01992     /* find out how many new device property sheets to add.
01993        fake a PROPSHEETHEADER structure, we don't plan to
01994        call PropertySheet again!*/
01995     psh.dwSize = sizeof(PROPSHEETHEADER);
01996     psh.dwFlags = 0;
01997     psh.nPages = 0;
01998 
01999     /* get the number of device property sheets for the device */
02000     if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet,
02001                                           DeviceInfoData,
02002                                           &psh,
02003                                           0,
02004                                           &nDriverPages,
02005                                           dap->PropertySheetType) &&
02006         nDriverPages != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
02007     {
02008         dap->nDevPropSheets += nDriverPages;
02009     }
02010     else
02011     {
02012         nDriverPages = 0;
02013     }
02014 
02015     /* include the driver page */
02016     if (dap->HasDriverPage)
02017         dap->nDevPropSheets++;
02018 
02019     /* include the details page */
02020     if (dap->Extended)
02021         dap->nDevPropSheets++;
02022 
02023     /* add the device property sheets */
02024     if (dap->nDevPropSheets != 0)
02025     {
02026         dap->DevPropSheets = HeapAlloc(GetProcessHeap(),
02027                                        HEAP_ZERO_MEMORY,
02028                                        dap->nDevPropSheets * sizeof(HPROPSHEETPAGE));
02029         if (dap->DevPropSheets != NULL)
02030         {
02031             if (nDriverPages != 0)
02032             {
02033                 psh.phpage = dap->DevPropSheets;
02034 
02035                 /* query the device property sheet pages to add */
02036                 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet,
02037                                                      DeviceInfoData,
02038                                                      &psh,
02039                                                      dap->nDevPropSheets,
02040                                                      NULL,
02041                                                      dap->PropertySheetType))
02042                 {
02043                     /* add the property sheets */
02044                     for (iPage = 0;
02045                          iPage != nDriverPages;
02046                          iPage++)
02047                     {
02048                         if (PropSheet_AddPage(hPropSheetDlg,
02049                                               dap->DevPropSheets[iPage]))
02050                         {
02051                             RecalcPages = TRUE;
02052                         }
02053                     }
02054 
02055                     dap->FreeDevPropSheets = TRUE;
02056                 }
02057                 else
02058                 {
02059                     /* cleanup, we were unable to get the device property sheets */
02060                     iPage = nDriverPages;
02061                     dap->nDevPropSheets -= nDriverPages;
02062                     nDriverPages = 0;
02063                 }
02064             }
02065             else
02066                 iPage = 0;
02067 
02068             /* add the driver page if necessary */
02069             if (dap->HasDriverPage)
02070             {
02071                 PROPSHEETPAGE pspDriver = {0};
02072                 pspDriver.dwSize = sizeof(PROPSHEETPAGE);
02073                 pspDriver.dwFlags = PSP_DEFAULT;
02074                 pspDriver.hInstance = hDllInstance;
02075                 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDRIVER);
02076                 pspDriver.pfnDlgProc = AdvProcDriverDlgProc;
02077                 pspDriver.lParam = (LPARAM)dap;
02078                 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver);
02079                 if (dap->DevPropSheets[iPage] != NULL)
02080                 {
02081                     if (PropSheet_AddPage(hPropSheetDlg,
02082                                           dap->DevPropSheets[iPage]))
02083                     {
02084                         iPage++;
02085                         RecalcPages = TRUE;
02086                     }
02087                     else
02088                     {
02089                         dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
02090                         dap->DevPropSheets[iPage] = NULL;
02091                     }
02092                 }
02093             }
02094 
02095             if (dap->Extended)
02096             {
02097                 /* Add the details page */
02098                 PROPSHEETPAGE pspDetails = {0};
02099                 pspDetails.dwSize = sizeof(PROPSHEETPAGE);
02100                 pspDetails.dwFlags = PSP_DEFAULT;
02101                 pspDetails.hInstance = hDllInstance;
02102                 pspDetails.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDETAILS);
02103                 pspDetails.pfnDlgProc = AdvProcDetailsDlgProc;
02104                 pspDetails.lParam = (LPARAM)dap;
02105                 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDetails);
02106                 if (dap->DevPropSheets[iPage] != NULL)
02107                 {
02108                     if (PropSheet_AddPage(hPropSheetDlg,
02109                                           dap->DevPropSheets[iPage]))
02110                     {
02111                         iPage++;
02112                         RecalcPages = TRUE;
02113                     }
02114                     else
02115                     {
02116                         dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
02117                         dap->DevPropSheets[iPage] = NULL;
02118                     }
02119                 }
02120 
02121                 /* FIXME: Add the resources page */
02122             }
02123 
02124             /* FIXME: Add the power page */
02125         }
02126         else
02127             dap->nDevPropSheets = 0;
02128     }
02129 
02130     if (RecalcPages)
02131     {
02132         PropSheet_RecalcPageSizes(hPropSheetDlg);
02133     }
02134 
02135     /* finally, disable the apply button */
02136     PropSheet_UnChanged(hPropSheetDlg,
02137                         hwndDlg);
02138     dap->DeviceUsageChanged = FALSE;
02139 }
02140 
02141 
02142 static LRESULT
02143 CALLBACK
02144 DlgParentSubWndProc(IN HWND hwnd,
02145                     IN UINT uMsg,
02146                     IN WPARAM wParam,
02147                     IN LPARAM lParam)
02148 {
02149     PDEVADVPROP_INFO dap;
02150 
02151     dap = (PDEVADVPROP_INFO)GetProp(hwnd,
02152                                     L"DevMgrDevChangeSub");
02153     if (dap != NULL)
02154     {
02155         if (uMsg == WM_DEVICECHANGE && !IsWindowVisible(dap->hWndGeneralPage))
02156         {
02157             SendMessage(dap->hWndGeneralPage,
02158                         WM_DEVICECHANGE,
02159                         wParam,
02160                         lParam);
02161         }
02162 
02163         /* pass the message the the old window proc */
02164         return CallWindowProc(dap->ParentOldWndProc,
02165                               hwnd,
02166                               uMsg,
02167                               wParam,
02168                               lParam);
02169     }
02170     else
02171     {
02172         /* this is not a good idea if the subclassed window was an ansi
02173            window, but we failed finding out the previous window proc
02174            so we can't use CallWindowProc. This should rarely - if ever -
02175            happen. */
02176 
02177         return DefWindowProc(hwnd,
02178                              uMsg,
02179                              wParam,
02180                              lParam);
02181     }
02182 }
02183 
02184 
02185 static INT_PTR
02186 CALLBACK
02187 AdvPropGeneralDlgProc(IN HWND hwndDlg,
02188                       IN UINT uMsg,
02189                       IN WPARAM wParam,
02190                       IN LPARAM lParam)
02191 {
02192     PDEVADVPROP_INFO dap;
02193     INT_PTR Ret = FALSE;
02194 
02195     dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg,
02196                                              DWL_USER);
02197 
02198     if (dap != NULL || uMsg == WM_INITDIALOG)
02199     {
02200         switch (uMsg)
02201         {
02202             case WM_COMMAND:
02203             {
02204                 switch (LOWORD(wParam))
02205                 {
02206                     case IDC_DEVUSAGE:
02207                     {
02208                         if (HIWORD(wParam) == CBN_SELCHANGE)
02209                         {
02210                             PropSheet_Changed(GetParent(hwndDlg),
02211                                               hwndDlg);
02212                             dap->DeviceUsageChanged = TRUE;
02213                         }
02214                         break;
02215                     }
02216 
02217                     case IDC_DEVPROBLEM:
02218                     {
02219                         if (dap->IsAdmin)
02220                         {
02221                             /* display the device problem wizard */
02222                             ShowDeviceProblemWizard(hwndDlg,
02223                                                     dap->DeviceInfoSet,
02224                                                     &dap->DeviceInfoData,
02225                                                     dap->hMachine);
02226                         }
02227                         break;
02228                     }
02229                 }
02230                 break;
02231             }
02232 
02233             case WM_NOTIFY:
02234             {
02235                 NMHDR *hdr = (NMHDR*)lParam;
02236                 switch (hdr->code)
02237                 {
02238                     case PSN_APPLY:
02239                         ApplyGeneralSettings(hwndDlg,
02240                                              dap);
02241                         break;
02242                 }
02243                 break;
02244             }
02245 
02246             case WM_INITDIALOG:
02247             {
02248                 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
02249                 if (dap != NULL)
02250                 {
02251                     HWND hWndParent;
02252 
02253                     dap->hWndGeneralPage = hwndDlg;
02254 
02255                     SetWindowLongPtr(hwndDlg,
02256                                      DWL_USER,
02257                                      (DWORD_PTR)dap);
02258 
02259                     /* subclass the parent window to always receive
02260                        WM_DEVICECHANGE messages */
02261                     hWndParent = GetParent(hwndDlg);
02262                     if (hWndParent != NULL)
02263                     {
02264                         /* subclass the parent window. This is not safe
02265                            if the parent window belongs to another thread! */
02266                         dap->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent,
02267                                                                           GWLP_WNDPROC,
02268                                                                           (LONG_PTR)DlgParentSubWndProc);
02269 
02270                         if (dap->ParentOldWndProc != NULL &&
02271                             SetProp(hWndParent,
02272                                     L"DevMgrDevChangeSub",
02273                                     (HANDLE)dap))
02274                         {
02275                             dap->hWndParent = hWndParent;
02276                         }
02277                     }
02278 
02279                     /* do not call UpdateDevInfo directly in here because it modifies
02280                        the pages of the property sheet! */
02281                     PostMessage(hwndDlg,
02282                                 PM_INITIALIZE,
02283                                 0,
02284                                 0);
02285                 }
02286                 Ret = TRUE;
02287                 break;
02288             }
02289 
02290             case WM_DEVICECHANGE:
02291             {
02292                 /* FIXME - don't call UpdateDevInfo for all events */
02293                 UpdateDevInfo(hwndDlg,
02294                               dap,
02295                               TRUE);
02296                 Ret = TRUE;
02297                 break;
02298             }
02299 
02300             case PM_INITIALIZE:
02301             {
02302                 UpdateDevInfo(hwndDlg,
02303                               dap,
02304                               FALSE);
02305                 dap->PageInitialized = TRUE;
02306                 break;
02307             }
02308 
02309             case WM_DESTROY:
02310             {
02311                 /* restore the old window proc of the subclassed parent window */
02312                 if (dap->hWndParent != NULL && dap->ParentOldWndProc != NULL)
02313                 {
02314                     if (SetWindowLongPtr(dap->hWndParent,
02315                                          GWLP_WNDPROC,
02316                                          (LONG_PTR)dap->ParentOldWndProc) == (LONG_PTR)DlgParentSubWndProc)
02317                     {
02318                         RemoveProp(dap->hWndParent,
02319                                    L"DevMgrDevChangeSub");
02320                     }
02321                 }
02322                 break;
02323             }
02324         }
02325     }
02326 
02327     return Ret;
02328 }
02329 
02330 
02331 INT_PTR
02332 DisplayDeviceAdvancedProperties(IN HWND hWndParent,
02333                                 IN LPCWSTR lpDeviceID  OPTIONAL,
02334                                 IN HDEVINFO DeviceInfoSet,
02335                                 IN PSP_DEVINFO_DATA DeviceInfoData,
02336                                 IN HINSTANCE hComCtl32,
02337                                 IN LPCWSTR lpMachineName,
02338                                 IN DWORD dwFlags)
02339 {
02340     PROPSHEETHEADER psh = {0};
02341     PROPSHEETPAGE pspGeneral = {0};
02342     PPROPERTYSHEETW pPropertySheetW;
02343     PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW;
02344     PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage;
02345     PDEVADVPROP_INFO DevAdvPropInfo;
02346     HMACHINE hMachine = NULL;
02347     DWORD DevIdSize = 0;
02348     INT_PTR Ret = -1;
02349 
02350     /* we don't want to statically link against comctl32, so find the
02351        functions we need dynamically */
02352     pPropertySheetW =
02353         (PPROPERTYSHEETW)GetProcAddress(hComCtl32,
02354                                         "PropertySheetW");
02355     pCreatePropertySheetPageW =
02356         (PCREATEPROPERTYSHEETPAGEW)GetProcAddress(hComCtl32,
02357                                                   "CreatePropertySheetPageW");
02358     pDestroyPropertySheetPage =
02359         (PDESTROYPROPERTYSHEETPAGE)GetProcAddress(hComCtl32,
02360                                                   "DestroyPropertySheetPage");
02361     if (pPropertySheetW == NULL ||
02362         pCreatePropertySheetPageW == NULL ||
02363         pDestroyPropertySheetPage == NULL)
02364     {
02365         return -1;
02366     }
02367 
02368     if (lpDeviceID == NULL)
02369     {
02370         /* find out how much size is needed for the device id */
02371         if (SetupDiGetDeviceInstanceId(DeviceInfoSet,
02372                                        DeviceInfoData,
02373                                        NULL,
02374                                        0,
02375                                        &DevIdSize))
02376         {
02377             DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
02378             return -1;
02379         }
02380 
02381         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
02382         {
02383             return -1;
02384         }
02385     }
02386     else
02387     {
02388         DevIdSize = (DWORD)wcslen(lpDeviceID) + 1;
02389     }
02390 
02391     if (lpMachineName != NULL && lpMachineName[0] != L'\0')
02392     {
02393         CONFIGRET cr = CM_Connect_Machine(lpMachineName,
02394                                           &hMachine);
02395         if (cr != CR_SUCCESS)
02396         {
02397             return -1;
02398         }
02399     }
02400 
02401     /* create the internal structure associated with the "General",
02402        "Driver", ... pages */
02403     DevAdvPropInfo = HeapAlloc(GetProcessHeap(),
02404                                HEAP_ZERO_MEMORY,
02405                                FIELD_OFFSET(DEVADVPROP_INFO,
02406                                             szDeviceID) +
02407                                    (DevIdSize * sizeof(WCHAR)));
02408     if (DevAdvPropInfo == NULL)
02409     {
02410         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02411         goto Cleanup;
02412     }
02413 
02414     if (lpDeviceID == NULL)
02415     {
02416         /* read the device instance id */
02417         if (!SetupDiGetDeviceInstanceId(DeviceInfoSet,
02418                                         DeviceInfoData,
02419                                         DevAdvPropInfo->szDeviceID,
02420                                         DevIdSize,
02421                                         NULL))
02422         {
02423             goto Cleanup;
02424         }
02425     }
02426     else
02427     {
02428         /* copy the device instance id supplied by the caller */
02429         wcscpy(DevAdvPropInfo->szDeviceID,
02430                lpDeviceID);
02431     }
02432 
02433     DevAdvPropInfo->DeviceInfoSet = DeviceInfoSet;
02434     DevAdvPropInfo->DeviceInfoData = *DeviceInfoData;
02435     DevAdvPropInfo->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
02436     DevAdvPropInfo->CurrentDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
02437 
02438     DevAdvPropInfo->ShowRemotePages = (lpMachineName != NULL && lpMachineName[0] != L'\0');
02439     DevAdvPropInfo->hMachine = hMachine;
02440     DevAdvPropInfo->lpMachineName = lpMachineName;
02441     DevAdvPropInfo->szDevName[0] = L'\0';
02442     DevAdvPropInfo->hComCtl32 = hComCtl32;
02443     DevAdvPropInfo->pCreatePropertySheetPageW = pCreatePropertySheetPageW;
02444     DevAdvPropInfo->pDestroyPropertySheetPage = pDestroyPropertySheetPage;
02445 
02446     DevAdvPropInfo->IsAdmin = IsUserAdmin();
02447     DevAdvPropInfo->DoDefaultDevAction = ((dwFlags & DPF_DEVICE_STATUS_ACTION) != 0);
02448     DevAdvPropInfo->Extended = ((dwFlags & DPF_EXTENDED) != 0);
02449 
02450     psh.dwSize = sizeof(PROPSHEETHEADER);
02451     psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW;
02452     psh.hwndParent = hWndParent;
02453     psh.pszCaption = DevAdvPropInfo->szDevName;
02454 
02455     DevAdvPropInfo->PropertySheetType = DevAdvPropInfo->ShowRemotePages ?
02456                                             DIGCDP_FLAG_REMOTE_ADVANCED :
02457                                             DIGCDP_FLAG_ADVANCED;
02458 
02459     psh.phpage = HeapAlloc(GetProcessHeap(),
02460                            HEAP_ZERO_MEMORY,
02461                            1 * sizeof(HPROPSHEETPAGE));
02462     if (psh.phpage == NULL)
02463     {
02464         goto Cleanup;
02465     }
02466 
02467     /* add the "General" property sheet */
02468     pspGeneral.dwSize = sizeof(PROPSHEETPAGE);
02469     pspGeneral.dwFlags = PSP_DEFAULT;
02470     pspGeneral.hInstance = hDllInstance;
02471     pspGeneral.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEGENERAL);
02472     pspGeneral.pfnDlgProc = AdvPropGeneralDlgProc;
02473     pspGeneral.lParam = (LPARAM)DevAdvPropInfo;
02474     psh.phpage[psh.nPages] = pCreatePropertySheetPageW(&pspGeneral);
02475     if (psh.phpage[psh.nPages] != NULL)
02476     {
02477         psh.nPages++;
02478     }
02479 
02480     DevAdvPropInfo->nDevPropSheets = psh.nPages;
02481 
02482     if (psh.nPages != 0)
02483     {
02484         Ret = pPropertySheetW(&psh);
02485 
02486         /* NOTE: no need to destroy the property sheets anymore! */
02487     }
02488     else
02489     {
02490         UINT i;
02491 
02492 Cleanup:
02493         /* in case of failure the property sheets must be destroyed */
02494         if (psh.phpage != NULL)
02495         {
02496             for (i = 0;
02497                  i < psh.nPages;
02498                  i++)
02499             {
02500                 if (psh.phpage[i] != NULL)
02501                 {
02502                     pDestroyPropertySheetPage(psh.phpage[i]);
02503                 }
02504             }
02505         }
02506     }
02507 
02508     if (DevAdvPropInfo != NULL)
02509     {
02510         if (DevAdvPropInfo->FreeDevPropSheets)
02511         {
02512             /* don't free the array if it's the one allocated in
02513                DisplayDeviceAdvancedProperties */
02514             HeapFree(GetProcessHeap(),
02515                      0,
02516                      DevAdvPropInfo->DevPropSheets);
02517         }
02518 
02519         if (DevAdvPropInfo->CloseDevInst)
02520         {
02521             /* close the device info set in case a new one was created */
02522             SetupDiDestroyDeviceInfoList(DevAdvPropInfo->DeviceInfoSet);
02523         }
02524 
02525         if (DevAdvPropInfo->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
02526         {
02527             SetupDiDestroyDeviceInfoList(DevAdvPropInfo->CurrentDeviceInfoSet);
02528         }
02529 
02530         if (DevAdvPropInfo->hDevIcon != NULL)
02531         {
02532             DestroyIcon(DevAdvPropInfo->hDevIcon);
02533         }
02534 
02535         HeapFree(GetProcessHeap(),
02536                  0,
02537                  DevAdvPropInfo);
02538     }
02539 
02540     if (psh.phpage != NULL)
02541     {
02542         HeapFree(GetProcessHeap(),
02543                  0,
02544                  psh.phpage);
02545     }
02546 
02547     if (hMachine != NULL)
02548     {
02549         CM_Disconnect_Machine(hMachine);
02550     }
02551 
02552     return Ret;
02553 }
02554 
02555 
02556 static BOOL
02557 GetDeviceAndComputerName(LPWSTR lpString,
02558                          WCHAR szDeviceID[],
02559                          WCHAR szMachineName[])
02560 {
02561     BOOL ret = FALSE;
02562 
02563     szDeviceID[0] = L'\0';
02564     szMachineName[0] = L'\0';
02565 
02566     while (*lpString != L'\0')
02567     {
02568         if (*lpString == L'/')
02569         {
02570             lpString++;
02571             if(!_wcsnicmp(lpString, L"DeviceID", 8))
02572             {
02573                 lpString += 9;
02574                 if (*lpString != L'\0')
02575                 {
02576                     int i = 0;
02577                     while ((*lpString != L' ') &&
02578                            (*lpString != L'\0') &&
02579                            (i <= MAX_DEVICE_ID_LEN))
02580                     {
02581                         szDeviceID[i++] = *lpString++;
02582                     }
02583                     szDeviceID[i] = L'\0';
02584                     ret = TRUE;
02585                 }
02586             }
02587             else if (!_wcsnicmp(lpString, L"MachineName", 11))
02588             {
02589                 lpString += 12;
02590                 if (*lpString != L'\0')
02591                 {
02592                     int i = 0;
02593                     while ((*lpString != L' ') &&
02594                            (*lpString != L'\0') &&
02595                            (i <= MAX_COMPUTERNAME_LENGTH))
02596                     {
02597                         szMachineName[i++] = *lpString++;
02598                     }
02599                     szMachineName[i] = L'\0';
02600                 }
02601             }
02602             /* knock the pointer back one and let the next
02603              * pointer deal with incrementing, otherwise we
02604              * go past the end of the string */
02605              lpString--;
02606         }
02607         lpString++;
02608     }
02609 
02610     return ret;
02611 }
02612 
02613 
02614 /***************************************************************************
02615  * NAME                                                         EXPORTED
02616  *      DeviceAdvancedPropertiesW
02617  *
02618  * DESCRIPTION
02619  *   Invokes the device properties dialog, this version may add some property pages
02620  *   for some devices
02621  *
02622  * ARGUMENTS
02623  *   hWndParent:    Handle to the parent window
02624  *   lpMachineName: Machine Name, NULL is the local machine
02625  *   lpDeviceID:    Specifies the device whose properties are to be shown
02626  *
02627  * RETURN VALUE
02628  *   Always returns -1, a call to GetLastError returns 0 if successful
02629  *
02630  * @implemented
02631  */
02632 INT_PTR
02633 WINAPI
02634 DeviceAdvancedPropertiesW(IN HWND hWndParent  OPTIONAL,
02635                           IN LPCWSTR lpMachineName  OPTIONAL,
02636                           IN LPCWSTR lpDeviceID)
02637 {
02638     HDEVINFO hDevInfo;
02639     SP_DEVINFO_DATA DevInfoData;
02640     HINSTANCE hComCtl32;
02641     INT_PTR Ret = -1;
02642 
02643     if (lpDeviceID == NULL)
02644     {
02645         SetLastError(ERROR_INVALID_PARAMETER);
02646         return FALSE;
02647     }
02648 
02649     /* dynamically load comctl32 */
02650     hComCtl32 = LoadAndInitComctl32();
02651     if (hComCtl32 != NULL)
02652     {
02653         hDevInfo = SetupDiCreateDeviceInfoListEx(NULL,
02654                                                  hWndParent,
02655                                                  lpMachineName,
02656                                                  NULL);
02657         if (hDevInfo != INVALID_HANDLE_VALUE)
02658         {
02659             DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
02660             if (SetupDiOpenDeviceInfo(hDevInfo,
02661                                       lpDeviceID,
02662                                       hWndParent,
02663                                       0,
02664                                       &DevInfoData))
02665             {
02666                 Ret = DisplayDeviceAdvancedProperties(hWndParent,
02667                                                       lpDeviceID,
02668                                                       hDevInfo,
02669                                                       &DevInfoData,
02670                                                       hComCtl32,
02671                                                       lpMachineName,
02672                                                       0);
02673             }
02674 
02675             SetupDiDestroyDeviceInfoList(hDevInfo);
02676         }
02677 
02678         FreeLibrary(hComCtl32);
02679     }
02680 
02681     return Ret;
02682 }
02683 
02684 
02685 /***************************************************************************
02686  * NAME                                                         EXPORTED
02687  *      DeviceAdvancedPropertiesA
02688  *
02689  * DESCRIPTION
02690  *   Invokes the device properties dialog, this version may add some property pages
02691  *   for some devices
02692  *
02693  * ARGUMENTS
02694  *   hWndParent:    Handle to the parent window
02695  *   lpMachineName: Machine Name, NULL is the local machine
02696  *   lpDeviceID:    Specifies the device whose properties are to be shown
02697  *
02698  * RETURN VALUE
02699  *   Always returns -1, a call to GetLastError returns 0 if successful
02700  *
02701  * @implemented
02702  */
02703 INT_PTR
02704 WINAPI
02705 DeviceAdvancedPropertiesA(IN HWND hWndParent  OPTIONAL,
02706                           IN LPCSTR lpMachineName  OPTIONAL,
02707                           IN LPCSTR lpDeviceID)
02708 {
02709     LPWSTR lpMachineNameW = NULL;
02710     LPWSTR lpDeviceIDW = NULL;
02711     INT_PTR Ret = -1;
02712 
02713     if (lpMachineName != NULL)
02714     {
02715         if (!(lpMachineNameW = ConvertMultiByteToUnicode(lpMachineName,
02716                                                          CP_ACP)))
02717         {
02718             goto Cleanup;
02719         }
02720     }
02721     if (lpDeviceID != NULL)
02722     {
02723         if (!(lpDeviceIDW = ConvertMultiByteToUnicode(lpDeviceID,
02724                                                       CP_ACP)))
02725         {
02726             goto Cleanup;
02727         }
02728     }
02729 
02730     Ret = DeviceAdvancedPropertiesW(hWndParent,
02731                                     lpMachineNameW,
02732                                     lpDeviceIDW);
02733 
02734 Cleanup:
02735     if (lpMachineNameW != NULL)
02736     {
02737         HeapFree(GetProcessHeap(),
02738                  0,
02739                  lpMachineNameW);
02740     }
02741     if (lpDeviceIDW != NULL)
02742     {
02743         HeapFree(GetProcessHeap(),
02744                  0,
02745                  lpDeviceIDW);
02746     }
02747 
02748     return Ret;
02749 }
02750 
02751 
02752 /***************************************************************************
02753  * NAME                                                         EXPORTED
02754  *      DevicePropertiesExA
02755  *
02756  * DESCRIPTION
02757  *   Invokes the extended device properties dialog
02758  *
02759  * ARGUMENTS
02760  *   hWndParent:    Handle to the parent window
02761  *   lpMachineName: Machine Name, NULL is the local machine
02762  *   lpDeviceID:    Specifies the device whose properties are to be shown, optional if
02763  *                  bShowDevMgr is nonzero
02764  *   dwFlags:       This parameter can be a combination of the following flags:
02765  *                  * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
02766  *                                              the default device status action button
02767  *                                              to be clicked (Troubleshoot, Enable
02768  *                                              Device, etc)
02769  *   bShowDevMgr:   If non-zero it displays the device manager instead of
02770  *                  the advanced device property dialog
02771  *
02772  * RETURN VALUE
02773  *   1:  if bShowDevMgr is non-zero and no error occured
02774  *   -1: a call to GetLastError returns 0 if successful
02775  *
02776  * @implemented
02777  */
02778 INT_PTR
02779 WINAPI
02780 DevicePropertiesExA(IN HWND hWndParent  OPTIONAL,
02781                     IN LPCSTR lpMachineName  OPTIONAL,
02782                     IN LPCSTR lpDeviceID  OPTIONAL,
02783                     IN DWORD dwFlags  OPTIONAL,
02784                     IN BOOL bShowDevMgr)
02785 {
02786     LPWSTR lpMachineNameW = NULL;
02787     LPWSTR lpDeviceIDW = NULL;
02788     INT_PTR Ret = -1;
02789 
02790     if (lpMachineName != NULL)
02791     {
02792         if (!(lpMachineNameW = ConvertMultiByteToUnicode(lpMachineName,
02793                                                          CP_ACP)))
02794         {
02795             goto Cleanup;
02796         }
02797     }
02798     if (lpDeviceID != NULL)
02799     {
02800         if (!(lpDeviceIDW = ConvertMultiByteToUnicode(lpDeviceID,
02801                                                       CP_ACP)))
02802         {
02803             goto Cleanup;
02804         }
02805     }
02806 
02807     Ret = DevicePropertiesExW(hWndParent,
02808                               lpMachineNameW,
02809                               lpDeviceIDW,
02810                               dwFlags,
02811                               bShowDevMgr);
02812 
02813 Cleanup:
02814     if (lpMachineNameW != NULL)
02815     {
02816         HeapFree(GetProcessHeap(),
02817                  0,
02818                  lpMachineNameW);
02819     }
02820     if (lpDeviceIDW != NULL)
02821     {
02822         HeapFree(GetProcessHeap(),
02823                  0,
02824                  lpDeviceIDW);
02825     }
02826 
02827     return Ret;
02828 }
02829 
02830 
02831 /***************************************************************************
02832  * NAME                                                         EXPORTED
02833  *      DevicePropertiesExW
02834  *
02835  * DESCRIPTION
02836  *   Invokes the extended device properties dialog
02837  *
02838  * ARGUMENTS
02839  *   hWndParent:    Handle to the parent window
02840  *   lpMachineName: Machine Name, NULL is the local machine
02841  *   lpDeviceID:    Specifies the device whose properties are to be shown, optional if
02842  *                  bShowDevMgr is nonzero
02843  *   dwFlags:       This parameter can be a combination of the following flags:
02844  *                  * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
02845  *                                              the default device status action button
02846  *                                              to be clicked (Troubleshoot, Enable
02847  *                                              Device, etc)
02848  *   bShowDevMgr:   If non-zero it displays the device manager instead of
02849  *                  the advanced device property dialog
02850  *
02851  * RETURN VALUE
02852  *   1:  if bShowDevMgr is non-zero and no error occured
02853  *   -1: a call to GetLastError returns 0 if successful
02854  *
02855  * @implemented
02856  */
02857 INT_PTR
02858 WINAPI
02859 DevicePropertiesExW(IN HWND hWndParent  OPTIONAL,
02860                     IN LPCWSTR lpMachineName  OPTIONAL,
02861                     IN LPCWSTR lpDeviceID  OPTIONAL,
02862                     IN DWORD dwFlags  OPTIONAL,
02863                     IN BOOL bShowDevMgr)
02864 {
02865     INT_PTR Ret = -1;
02866 
02867     if (dwFlags & ~(DPF_EXTENDED | DPF_DEVICE_STATUS_ACTION))
02868     {
02869         DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
02870                 dwFlags & ~(DPF_EXTENDED | DPF_DEVICE_STATUS_ACTION));
02871         SetLastError(ERROR_INVALID_FLAGS);
02872         return -1;
02873     }
02874 
02875     if (bShowDevMgr)
02876     {
02877         DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
02878         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
02879     }
02880     else
02881     {
02882         HDEVINFO hDevInfo;
02883         SP_DEVINFO_DATA DevInfoData;
02884         HINSTANCE hComCtl32;
02885 
02886         if (lpDeviceID == NULL)
02887         {
02888             SetLastError(ERROR_INVALID_PARAMETER);
02889             return -1;
02890         }
02891 
02892         /* dynamically load comctl32 */
02893         hComCtl32 = LoadAndInitComctl32();
02894         if (hComCtl32 != NULL)
02895         {
02896             hDevInfo = SetupDiCreateDeviceInfoListEx(NULL,
02897                                                      hWndParent,
02898                                                      lpMachineName,
02899                                                      NULL);
02900             if (hDevInfo != INVALID_HANDLE_VALUE)
02901             {
02902                 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
02903                 if (SetupDiOpenDeviceInfo(hDevInfo,
02904                                           lpDeviceID,
02905                                           hWndParent,
02906                                           0,
02907                                           &DevInfoData))
02908                 {
02909                     Ret = DisplayDeviceAdvancedProperties(hWndParent,
02910                                                           lpDeviceID,
02911                                                           hDevInfo,
02912                                                           &DevInfoData,
02913                                                           hComCtl32,
02914                                                           lpMachineName,
02915                                                           dwFlags);
02916                 }
02917 
02918                 SetupDiDestroyDeviceInfoList(hDevInfo);
02919             }
02920 
02921             FreeLibrary(hComCtl32);
02922         }
02923     }
02924 
02925     return Ret;
02926 }
02927 
02928 
02929 /***************************************************************************
02930  * NAME                                                         EXPORTED
02931  *      DevicePropertiesA
02932  *
02933  * DESCRIPTION
02934  *   Invokes the device properties dialog directly
02935  *
02936  * ARGUMENTS
02937  *   hWndParent:    Handle to the parent window
02938  *   lpMachineName: Machine Name, NULL is the local machine
02939  *   lpDeviceID:    Specifies the device whose properties are to be shown
02940  *   bShowDevMgr:   If non-zero it displays the device manager instead of
02941  *                  the device property dialog
02942  *
02943  * RETURN VALUE
02944  *   >=0: if no errors occured
02945  *   -1:  if errors occured
02946  *
02947  * REVISIONS
02948  *
02949  * @implemented
02950  */
02951 int
02952 WINAPI
02953 DevicePropertiesA(HWND hWndParent,
02954                   LPCSTR lpMachineName,
02955                   LPCSTR lpDeviceID,
02956                   BOOL bShowDevMgr)
02957 {
02958     return DevicePropertiesExA(hWndParent,
02959                                lpMachineName,
02960                                lpDeviceID,
02961                                DPF_EXTENDED,
02962                                bShowDevMgr);
02963 }
02964 
02965 
02966 /***************************************************************************
02967  * NAME                                                         EXPORTED
02968  *      DevicePropertiesW
02969  *
02970  * DESCRIPTION
02971  *   Invokes the device properties dialog directly
02972  *
02973  * ARGUMENTS
02974  *   hWndParent:    Handle to the parent window
02975  *   lpMachineName: Machine Name, NULL is the local machine
02976  *   lpDeviceID:    Specifies the device whose properties are to be shown
02977  *   bShowDevMgr:   If non-zero it displays the device manager instead of
02978  *                  the device property dialog
02979  *
02980  * RETURN VALUE
02981  *   >=0: if no errors occured
02982  *   -1:  if errors occured
02983  *
02984  * REVISIONS
02985  *
02986  * @implemented
02987  */
02988 int
02989 WINAPI
02990 DevicePropertiesW(HWND hWndParent,
02991                   LPCWSTR lpMachineName,
02992                   LPCWSTR lpDeviceID,
02993                   BOOL bShowDevMgr)
02994 {
02995     return DevicePropertiesExW(hWndParent,
02996                                lpMachineName,
02997                                lpDeviceID,
02998                                DPF_EXTENDED,
02999                                bShowDevMgr);
03000 }
03001 
03002 
03003 /***************************************************************************
03004  * NAME                                                         EXPORTED
03005  *      DeviceProperties_RunDLLA
03006  *
03007  * DESCRIPTION
03008  *   Invokes the device properties dialog
03009  *
03010  * ARGUMENTS
03011  *   hWndParent:  Handle to the parent window
03012  *   hInst:       Handle to the application instance
03013  *   lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
03014  *                also see NOTEs
03015  *   nCmdShow:    Specifies how the window should be shown
03016  *
03017  * RETURN VALUE
03018  *
03019  * REVISIONS
03020  *
03021  * NOTE
03022  *   - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
03023  *     (/MachineName is optional). This function only parses this string and eventually
03024  *     calls DeviceProperties().
03025  *
03026  * @implemented
03027  */
03028 VOID
03029 WINAPI
03030 DeviceProperties_RunDLLA(HWND hWndParent,
03031                          HINSTANCE hInst,
03032                          LPCSTR lpDeviceCmd,
03033                          int nCmdShow)
03034 {
03035     LPWSTR lpDeviceCmdW = NULL;
03036 
03037     if (lpDeviceCmd != NULL)
03038     {
03039         if ((lpDeviceCmdW = ConvertMultiByteToUnicode(lpDeviceCmd,
03040                                                       CP_ACP)))
03041         {
03042             DeviceProperties_RunDLLW(hWndParent,
03043                                      hInst,
03044                                      lpDeviceCmdW,
03045                                      nCmdShow);
03046         }
03047     }
03048 
03049     if (lpDeviceCmdW != NULL)
03050     {
03051         HeapFree(GetProcessHeap(),
03052                  0,
03053                  lpDeviceCmdW);
03054     }
03055 }
03056 
03057 
03058 /***************************************************************************
03059  * NAME                                                         EXPORTED
03060  *      DeviceProperties_RunDLLW
03061  *
03062  * DESCRIPTION
03063  *   Invokes the device properties dialog
03064  *
03065  * ARGUMENTS
03066  *   hWndParent:  Handle to the parent window
03067  *   hInst:       Handle to the application instance
03068  *   lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
03069  *                also see NOTEs
03070  *   nCmdShow:    Specifies how the window should be shown
03071  *
03072  * RETURN VALUE
03073  *
03074  * REVISIONS
03075  *
03076  * NOTE
03077  *   - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
03078  *     (/MachineName is optional). This function only parses this string and eventually
03079  *     calls DeviceProperties().
03080  *
03081  * @implemented
03082  */
03083 VOID
03084 WINAPI
03085 DeviceProperties_RunDLLW(HWND hWndParent,
03086                          HINSTANCE hInst,
03087                          LPCWSTR lpDeviceCmd,
03088                          int nCmdShow)
03089 {
03090     WCHAR szDeviceID[MAX_DEVICE_ID_LEN+1];
03091     WCHAR szMachineName[MAX_COMPUTERNAME_LENGTH+1];
03092     LPWSTR lpString = (LPWSTR)lpDeviceCmd;
03093 
03094     if (!GetDeviceAndComputerName(lpString,
03095                                   szDeviceID,
03096                                   szMachineName))
03097     {
03098         DPRINT1("DeviceProperties_RunDLLW DeviceID: %S, MachineName: %S\n", szDeviceID, szMachineName);
03099         return;
03100     }
03101 
03102     DevicePropertiesW(hWndParent,
03103                       szMachineName,
03104                       szDeviceID,
03105                       FALSE);
03106 }

Generated on Sat May 26 2012 04:22:03 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.