text: //+-------------------------------------------------------------------------
  //
  //  Microsoft Windows
  //
  //  Copyright (C) Microsoft Corporation
  //
  //  File:       pnpenum.c
  //
  //--------------------------------------------------------------------------
  
  #include "hdwwiz.h"
  
  
  INT_PTR CALLBACK HdwAskDetectDlgProc(
      HWND hDlg,
      UINT wMsg,
      WPARAM wParam,
      LPARAM lParam
      )
  {
      PHARDWAREWIZ HardwareWiz = (PHARDWAREWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
  
      UNREFERENCED_PARAMETER(wParam);
  
      switch (wMsg)  {
          case WM_INITDIALOG: {
              LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  
              HardwareWiz = (PHARDWAREWIZ)lppsp->lParam;
              SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)HardwareWiz);
  
              break;
          }
  
          case WM_COMMAND:
              break;
  
          case WM_NOTIFY:
              switch (((NMHDR FAR *)lParam)->code) {
                  case PSN_SETACTIVE:
  
                      PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK | PSWIZB_NEXT);
                      HardwareWiz->PrevPage = IDD_ADDDEVICE_ASKDETECT;
  
                      //
                      // Set the Initial radio button state.
                      // default to do autodetection.
                      //
                      CheckRadioButton(hDlg,
                                       IDC_ADDDEVICE_ASKDETECT_AUTO,
                                       IDC_ADDDEVICE_ASKDETECT_SPECIFIC,
                                       IDC_ADDDEVICE_ASKDETECT_AUTO
                                       );
  
                      break;
  
  
                  case PSN_WIZBACK:
                      //
                      // If we are going back then this is effectively a Cancel
                      //
                      SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_PROBLIST);
                      break;
  
                  case PSN_WIZNEXT:
                      if (IsDlgButtonChecked(hDlg, IDC_ADDDEVICE_ASKDETECT_AUTO)) {
  
                          SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_DETECTION);
  
                      } else {
  
                          SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_SELECTCLASS);
                      }
                      break;
  
                  case PSN_RESET:
                      HardwareWiz->Cancelled = TRUE;
                      break;
                  }
  
              break;
  
          default:
              return(FALSE);
          }
  
      return(TRUE);
  }
  
  DWORD
  PNPEnumerate(
      PHARDWAREWIZ HardwareWiz
      )
  {
      CONFIGRET ConfigRet;
      DEVINST RootDevInst, ChildDevInst;
  
      if (HardwareWiz->ExitDetect) {
  
          return 0;
      }
  
      //
      // reenumerate from the root of the devnode tree
      //
      ConfigRet = CM_Locate_DevNode_Ex(&RootDevInst,
                                       NULL,
                                       CM_LOCATE_DEVNODE_NORMAL,
                                       NULL
                                       );
  
  
      if (ConfigRet != CR_SUCCESS) {
  
          return 0;
      }
  
  
      //
      // Force install of ALL devices which still need installing.
      // save reboot flags to pass back to main thread.
      //
      ConfigRet = CM_Get_Child_Ex(&ChildDevInst,
                                  RootDevInst,
                                  0,
                                  NULL
                                  );
  
      if (ConfigRet == CR_SUCCESS) {
  
          InstallSilentChildSiblings(NULL, HardwareWiz, ChildDevInst, TRUE);
      }
  
  
      if (HardwareWiz->Reboot) {
  
          return 0;
      }
  
      Sleep(100); // give a chance for new devices to be noticed by PNP
  
      //
      // Ask PNP to look for newly arrived devices.
      //
      CM_Reenumerate_DevNode_Ex(
          RootDevInst,
          CM_REENUMERATE_SYNCHRONOUS | CM_REENUMERATE_RETRY_INSTALLATION,
          NULL
          );
  
      Sleep(5000); // give a chance for new devices to be noticed by PNP
  
      do {
  
          if (HardwareWiz->ExitDetect) {
  
              return 0;
          }
  
      } while (CMP_WaitNoPendingInstallEvents(1000) == WAIT_TIMEOUT);
  
  
      return 0;
  }
  
  int
  InsertDeviceNodeListView(
      HWND hwndList,
      PHARDWAREWIZ HardwareWiz,
      PSP_DEVINFO_DATA DeviceInfoData
      )
  {
      INT lvIndex;
      LV_ITEM lviItem;
      PTCHAR DeviceName;
      ULONG Status = 0, Problem = 0;
  
      lviItem.mask = LVIF_TEXT | LVIF_PARAM;
      lviItem.iItem = -1;
      lviItem.iSubItem = 0;
  
      if (SetupDiGetClassImageIndex(&HardwareWiz->ClassImageList,
                                    &DeviceInfoData->ClassGuid,
                                    &lviItem.iImage
                                    )) {
  
          lviItem.mask |= LVIF_IMAGE;
      }
  
      DeviceName = BuildFriendlyName(DeviceInfoData->DevInst);
  
      if (DeviceName) {
  
          lviItem.pszText = DeviceName;
  
      } else {
  
          lviItem.pszText = szUnknown;
      }
  
      lviItem.mask |= LVIF_STATE;
  
      if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData->DevInst, 0) == CR_SUCCESS) {
          if (Problem) {
              //
              // Add the yellow ! or red X overlay to the devnode if it has a 
              // problem.
              //
              lviItem.state = (Problem == CM_PROB_DISABLED) ?
                              INDEXTOOVERLAYMASK(IDI_DISABLED_OVL - IDI_CLASSICON_OVERLAYFIRST + 1) :
                              INDEXTOOVERLAYMASK(IDI_PROBLEM_OVL - IDI_CLASSICON_OVERLAYFIRST + 1);
      
          } else {
              lviItem.state = INDEXTOOVERLAYMASK(0);
          }
  
          lviItem.stateMask = LVIS_OVERLAYMASK;
      }
  
  
      lviItem.lParam = (LPARAM)DeviceInfoData->DevInst;
      lvIndex = ListView_InsertItem(hwndList, &lviItem);
  
      if (DeviceName) {
  
          LocalFree(DeviceName);
      }
  
      return lvIndex;
  }
  
  BOOL
  AnyNewPnPDevicesFound(
      HWND hDlg,
      PHARDWAREWIZ HardwareWiz
      )
  {
      HDEVINFO NewDeviceInfo, OldDeviceInfo;
      BOOL NewDevicesFound;
      BOOL NewDevice;
      INT iNew, iOld;
      SP_DEVINFO_DATA NewDeviceInfoData, OldDeviceInfoData;
  
      OldDeviceInfo = HardwareWiz->PNPEnumDeviceInfo;
      NewDeviceInfo = SetupDiGetClassDevs(NULL,
                                       NULL,
                                       GetParent(hDlg),
                                       DIGCF_ALLCLASSES
                                       );
  
      if (!OldDeviceInfo || NewDeviceInfo == INVALID_HANDLE_VALUE) {
  
          return FALSE;
      }
  
      NewDevicesFound = FALSE;
      iNew = 0;
      NewDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  
      while (SetupDiEnumDeviceInfo(NewDeviceInfo, iNew++, &NewDeviceInfoData)) {
  
          NewDevice = TRUE;
          iOld = 0;
          OldDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  
          while (SetupDiEnumDeviceInfo(OldDeviceInfo, iOld++, &OldDeviceInfoData)) {
  
              if (NewDeviceInfoData.DevInst == OldDeviceInfoData.DevInst) {
  
                  //
                  // If this DevInst exists in the Old DeviceInfo list then it is
                  // not a new device.
                  //
                  NewDevice = FALSE;
                  break;
              }
          }
  
          //
          // If we did not find this device in the original list then it is a new
          // PnP device.  Set the NewDevicesFound BOOL and break out of the loop.
          //
          if (NewDevice) {
  
              NewDevicesFound = TRUE;
              break;
          }
      }
  
      SetupDiDestroyDeviceInfoList(NewDeviceInfo);
  
      return NewDevicesFound;
  }
  
  INT_PTR CALLBACK
  HdwPnpEnumDlgProc(
      HWND hDlg,
      UINT wMsg,
      WPARAM wParam,
      LPARAM lParam
      )
  {
      PHARDWAREWIZ HardwareWiz = (PHARDWAREWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
  
      UNREFERENCED_PARAMETER(wParam);
  
      if (wMsg == WM_INITDIALOG) {
  
          LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  
          HardwareWiz = (PHARDWAREWIZ)lppsp->lParam;
          SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)HardwareWiz);
          return TRUE;
      }
  
  
      switch (wMsg)  {
  
      case WM_COMMAND:
          break;
  
      case WM_DESTROY:
          if (HardwareWiz->PNPEnumDeviceInfo) {
  
              SetupDiDestroyDeviceInfoList(HardwareWiz->PNPEnumDeviceInfo);
              HardwareWiz->PNPEnumDeviceInfo = NULL;
          }
          break;
  
  
      case WUM_PNPENUMERATE:
          HardwareWiz->InstallPending = FALSE;
          HardwareWiz->CurrCursor = NULL;
          SetCursor(HardwareWiz->IdcArrow);
          Animate_Stop(GetDlgItem(hDlg, IDC_ANIMATE_SEARCH));
  
          if (HardwareWiz->ExitDetect) {
  
              break;
          }
  
          HardwareWiz->FoundPnPDevices = AnyNewPnPDevicesFound(hDlg, HardwareWiz);
          PropSheet_PressButton(GetParent(hDlg), PSBTN_NEXT);
          break;
  
  
      case WM_NOTIFY:
          switch (((NMHDR FAR *)lParam)->code) {
  
              case PSN_SETACTIVE: {
                  int PrevPage;
  
                  PrevPage = HardwareWiz->PrevPage;
                  HardwareWiz->PrevPage = IDD_ADDDEVICE_PNPENUM;
                  HardwareWiz->ExitDetect = FALSE;
  
  
                  //
                  // If moving forwards, kick off enumeration.
                  //
                  if (PrevPage != IDD_ADDDEVICE_ASKDETECT) {
                      EnableWindow(GetDlgItem(GetParent(hDlg), IDCANCEL), FALSE);
                      PropSheet_SetWizButtons(GetParent(hDlg), 0);
                      SetDlgText(hDlg, IDC_HDW_TEXT, IDS_ADDDEVICE_PNPENUMERATE, IDS_ADDDEVICE_PNPENUMERATE);
  
                      Animate_Open(GetDlgItem(hDlg, IDC_ANIMATE_SEARCH), MAKEINTRESOURCE(IDA_SEARCHING));
                      Animate_Play(GetDlgItem(hDlg, IDC_ANIMATE_SEARCH), 0, -1, -1);
  
                      //
                      // Create a list of all of the installed devices, which
                      // will be used after enumeration to build the list of
                      // newly installed.
                      //
                      HardwareWiz->PNPEnumDeviceInfo = SetupDiGetClassDevs(
                                                          NULL,
                                                          NULL,
                                                          GetParent(hDlg),
                                                          DIGCF_ALLCLASSES
                                                          );
  
                      if (HardwareWiz->PNPEnumDeviceInfo == INVALID_HANDLE_VALUE) {
  
                          HardwareWiz->PNPEnumDeviceInfo = NULL;
                      }
  
  
                      HardwareWiz->InstallPending = TRUE;
  
                      HardwareWiz->CurrCursor = HardwareWiz->IdcAppStarting;
                      SetCursor(HardwareWiz->CurrCursor);
  
                      if (!SearchThreadRequest(HardwareWiz->SearchThread,
                                          hDlg,
                                          SEARCH_PNPENUM,
                                          0
                                          )) {
  
                          EnableWindow(GetDlgItem(GetParent(hDlg), IDCANCEL), TRUE);
                          PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK| PSWIZB_NEXT);
                          SetDlgText(hDlg, IDC_HDW_TEXT, IDS_ADDDEVICE_PNPENUMERROR, IDS_ADDDEVICE_PNPENUMERROR);
                          Animate_Stop(GetDlgItem(hDlg, IDC_ANIMATE_SEARCH));
                      }
                  }
              }
              break;
  
              case PSN_QUERYCANCEL:
                  if (HardwareWiz->InstallPending) {
  
                      if (HardwareWiz->ExitDetect) {
  
                          SetDlgMsgResult(hDlg, wMsg, TRUE);
                          break;
                      }
  
                      HardwareWiz->ExitDetect = TRUE;
                      HardwareWiz->CurrCursor = HardwareWiz->IdcWait;
                      SetCursor(HardwareWiz->CurrCursor);
                      CancelSearchRequest(HardwareWiz);
                      HardwareWiz->CurrCursor = NULL;
                  }
  
                  SetDlgMsgResult(hDlg, wMsg, FALSE);
                  break;
  
              case PSN_RESET:
                 HardwareWiz->Cancelled = TRUE;
                 Animate_Stop(GetDlgItem(hDlg, IDC_ANIMATE_SEARCH));
                 break;
  
              case PSN_WIZBACK:
                 SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_WELCOME);
                 break;
  
              case PSN_WIZNEXT:
                  if (HardwareWiz->FoundPnPDevices) {
  
                      SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_PNPFINISH);
  
                  } else {
  
                      EnableWindow(GetDlgItem(GetParent(hDlg),  IDCANCEL), TRUE);
                      SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_CONNECTED);
                  }
                  break;
  
          }
          break;
  
      case WM_SETCURSOR:
          if (HardwareWiz->CurrCursor) {
  
              SetCursor(HardwareWiz->CurrCursor);
              break;
          }
  
          // fall thru to return(FALSE);
  
      default:
          return(FALSE);
      }
  
      return(TRUE);
  }
  
  BOOL
  FillInstalledDevicesList(
      HWND hDlg,
      PHARDWAREWIZ HardwareWiz
      )
  {
      HDEVINFO NewDeviceInfo, OldDeviceInfo;
      BOOL Installed;
      BOOL NewDevice;
      INT iNew, iOld;
      SP_DEVINFO_DATA NewDeviceInfoData, OldDeviceInfoData;
      HWND hwndList;
  
      hwndList = GetDlgItem(hDlg, IDC_FOUNDPNP_LIST);
      SendMessage(hwndList, WM_SETREDRAW, FALSE, 0L);
      ListView_DeleteAllItems(hwndList);
  
      OldDeviceInfo = HardwareWiz->PNPEnumDeviceInfo;
      NewDeviceInfo = SetupDiGetClassDevs(NULL,
                                       NULL,
                                       GetParent(hDlg),
                                       DIGCF_ALLCLASSES
                                       );
  
      if (!OldDeviceInfo || NewDeviceInfo == INVALID_HANDLE_VALUE) {
  
          SendMessage(hwndList, WM_SETREDRAW, TRUE, 0L);
          return FALSE;
      }
  
      //
      // For each element in the new list check to see if its in the old list.
      // If its not then it is a newly installed devnode so add it to the list box.
      //
      Installed = FALSE;
      iNew = 0;
      NewDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  
      while (SetupDiEnumDeviceInfo(NewDeviceInfo, iNew++, &NewDeviceInfoData)) {
  
          NewDevice = TRUE;
          iOld = 0;
          OldDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  
          while (SetupDiEnumDeviceInfo(OldDeviceInfo, iOld++, &OldDeviceInfoData)) {
  
              if (NewDeviceInfoData.DevInst == OldDeviceInfoData.DevInst) {
                  //
                  // If this DevInst exists in the Old DeviceInfo list then it is
                  // not a new device.
                  //
                  NewDevice = FALSE;
                  break;
              }
          }
  
          //
          // If this is a new device then add it to the list view and set
          // the Installed boolean to TRUE.
          //
          if (NewDevice) {
  
              InsertDeviceNodeListView(hwndList, HardwareWiz, &NewDeviceInfoData);
              Installed = TRUE;
          }
      }
  
      SetupDiDestroyDeviceInfoList(NewDeviceInfo);
  
      if (!Installed) {
  
          SendMessage(hwndList, WM_SETREDRAW, TRUE, 0L);
          SetupDiDestroyDeviceInfoList(HardwareWiz->PNPEnumDeviceInfo);
          HardwareWiz->PNPEnumDeviceInfo = NULL;
          return FALSE;
      }
  
  
      ListView_SetItemState(hwndList,
                            0,
                            LVIS_SELECTED|LVIS_FOCUSED,
                            LVIS_SELECTED|LVIS_FOCUSED
                            );
  
      //
      // scroll the selected item into view.
      //
      ListView_EnsureVisible(hwndList, 0, FALSE);
      ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER);
  
      SendMessage(hwndList, WM_SETREDRAW, TRUE, 0L);
  
      return Installed;
  }
  
  BOOL
  InitPnpFinishDlgProc(
      HWND hDlg,
      PHARDWAREWIZ HardwareWiz
      )
  {
      HWND hwndList;
      LV_COLUMN lvcCol;
      TCHAR Buffer[64];
  
      //
      // Insert columns for listview.
      // 0 == device name
      //
      hwndList = GetDlgItem(hDlg, IDC_FOUNDPNP_LIST);
  
      lvcCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
      lvcCol.fmt = LVCFMT_LEFT;
      lvcCol.pszText = Buffer;
  
      lvcCol.iSubItem = 0;
      LoadString(hHdwWiz, IDS_DEVINSTALLED, Buffer, SIZECHARS(Buffer));
      ListView_InsertColumn(hwndList, 0, &lvcCol);
  
      SendMessage(hwndList,
                  LVM_SETEXTENDEDLISTVIEWSTYLE,
                  LVS_EX_FULLROWSELECT,
                  LVS_EX_FULLROWSELECT
                  );
  
      if (HardwareWiz->ClassImageList.cbSize) {
  
          ListView_SetImageList(hwndList,
                                HardwareWiz->ClassImageList.ImageList,
                                LVSIL_SMALL
                                );
      }
  
      return TRUE;
  }
  
  INT_PTR CALLBACK
  HdwPnpFinishDlgProc(
      HWND hDlg,
      UINT wMsg,
      WPARAM wParam,
      LPARAM lParam
      )
  {
      PHARDWAREWIZ HardwareWiz = (PHARDWAREWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
      HWND hwndParentDlg=GetParent(hDlg);
  
      UNREFERENCED_PARAMETER(wParam);
  
      switch (wMsg)  {
      case WM_INITDIALOG: {
          LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  
          HardwareWiz = (PHARDWAREWIZ)lppsp->lParam;
          SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)HardwareWiz);
          SetWindowFont(GetDlgItem(hDlg, IDC_HDWNAME), HardwareWiz->hfontTextBigBold, TRUE);
  
          if (!InitPnpFinishDlgProc(hDlg, HardwareWiz)) {
              return FALSE;
          }
  
          break;
          }
  
      case WM_DESTROY:
          break;
  
      case WM_NOTIFY:
          switch (((LPNMHDR)lParam)->code) {
          case PSN_SETACTIVE:
              PropSheet_SetWizButtons(hwndParentDlg, PSWIZB_FINISH);
              EnableWindow(GetDlgItem(hwndParentDlg, IDCANCEL), FALSE);
              FillInstalledDevicesList(hDlg, HardwareWiz);
              break;
  
          case PSN_WIZFINISH:
              break;
  
          case NM_DBLCLK:
              if ((((LPNMHDR)lParam)->idFrom) == IDC_FOUNDPNP_LIST) {
                  LVITEM lvItem;
  
                  lvItem.mask = LVIF_PARAM;
                  lvItem.iSubItem = 0;
                  lvItem.iItem = ListView_GetNextItem(GetDlgItem(hDlg, IDC_FOUNDPNP_LIST),
                                                      -1, 
                                                      LVNI_SELECTED);
  
                  if ((lvItem.iItem != -1) &&
                      ListView_GetItem(GetDlgItem(hDlg, IDC_FOUNDPNP_LIST), &lvItem) &&
                      (lvItem.lParam)) {
                      //
                      // Launch the properties for this device.
                      //
                      DeviceProperties(hDlg,
                                       (DEVNODE)lvItem.lParam,
                                       0
                                       );
                  }
              }
          }
          break;
  
  
      default:
          return(FALSE);
      }
  
      return(TRUE);
  }
  
  INT_PTR CALLBACK
  HdwConnectedDlgProc(
      HWND hDlg,
      UINT wMsg,
      WPARAM wParam,
      LPARAM lParam
      )
  {
      PHARDWAREWIZ HardwareWiz = (PHARDWAREWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
  
  
      if (wMsg == WM_INITDIALOG) {
  
          LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  
          HardwareWiz = (PHARDWAREWIZ)lppsp->lParam;
          SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)HardwareWiz);
          return TRUE;
      }
  
  
      switch (wMsg)  {
  
      case WM_COMMAND:
          switch (LOWORD(wParam)) {
          case IDC_ADDDEVICE_CONNECTED_YES:
          case IDC_ADDDEVICE_CONNECTED_NO:
              //
              // Only show the next button if one of the radio buttons are
              // selected.
              //
              if (IsDlgButtonChecked(hDlg, IDC_ADDDEVICE_CONNECTED_YES) ||
                  IsDlgButtonChecked(hDlg, IDC_ADDDEVICE_CONNECTED_NO)) {
                  PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK | PSWIZB_NEXT);
              } else {
                  PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK);
              }
              break;
          }
          break;
  
      case WM_DESTROY:
          break;
  
      case WM_NOTIFY:
          switch (((NMHDR FAR *)lParam)->code) {
  
              case PSN_SETACTIVE:
                  HardwareWiz->PrevPage = IDD_ADDDEVICE_CONNECTED;
                  
                  //
                  // Only show the next button if one of the radio buttons are
                  // selected.
                  //
                  if (IsDlgButtonChecked(hDlg, IDC_ADDDEVICE_CONNECTED_YES) ||
                      IsDlgButtonChecked(hDlg, IDC_ADDDEVICE_CONNECTED_NO)) {
                      PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK | PSWIZB_NEXT);
                  } else {
                      PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK);
                  }
                  break;
  
              case PSN_WIZBACK:
                  SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_WELCOME);
                  break;
  
              case PSN_WIZNEXT:
                  if (IsDlgButtonChecked(hDlg, IDC_ADDDEVICE_CONNECTED_YES)) {
  
                      SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_PROBLIST);
  
                  } else {
  
                      SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_CONNECTED_FINISH);
                  }
                  break;
  
          }
          break;
  
      default:
          return(FALSE);
      }
  
      return(TRUE);
  }
  
  INT_PTR CALLBACK
  HdwConnectedFinishDlgProc(
      HWND hDlg,
      UINT wMsg,
      WPARAM wParam,
      LPARAM lParam
      )
  {
      PHARDWAREWIZ HardwareWiz = (PHARDWAREWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
  
      UNREFERENCED_PARAMETER(wParam);
  
      if (wMsg == WM_INITDIALOG) {
  
          LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  
          HardwareWiz = (PHARDWAREWIZ)lppsp->lParam;
          SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)HardwareWiz);
          SetWindowFont(GetDlgItem(hDlg, IDC_HDWNAME), HardwareWiz->hfontTextBigBold, TRUE);
          return TRUE;
      }
  
  
      switch (wMsg)  {
  
      case WM_COMMAND:
          break;
  
      case WM_DESTROY:
          break;
  
      case WM_NOTIFY:
          switch (((NMHDR FAR *)lParam)->code) {
  
          case PSN_SETACTIVE:
              PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK | PSWIZB_FINISH);
              break;
  
          case PSN_WIZBACK:
              SetDlgMsgResult(hDlg, wMsg, IDD_ADDDEVICE_CONNECTED);
              break;
  
          case PSN_WIZFINISH:
              if (IsDlgButtonChecked(hDlg, IDC_NEED_SHUTDOWN)) {
                  //
                  // Rember that we need to shutdown.
                  //
                  HardwareWiz->Shutdown = TRUE;    
              }
              break;
  
          }
          break;
  
      default:
          return(FALSE);
      }
  
      return(TRUE);
  }
  
  