//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: init.c // //-------------------------------------------------------------------------- #include "hdwwiz.h" HMODULE hHdwWiz; int g_BlankIconIndex; INT CALLBACK iHdwWizardDlgCallback( IN HWND hwndDlg, IN UINT uMsg, IN LPARAM lParam ) /*++ Routine Description: Call back used to remove the "?" from the wizard page. Arguments: hwndDlg - Handle to the property sheet dialog box. uMsg - Identifies the message being received. This parameter is one of the following values: PSCB_INITIALIZED - Indicates that the property sheet is being initialized. The lParam value is zero for this message. PSCB_PRECREATE Indicates that the property sheet is about to be created. The hwndDlg parameter is NULL and the lParam parameter is a pointer to a dialog template in memory. This template is in the form of a DLGTEMPLATE structure followed by one or more DLGITEMTEMPLATE structures. lParam - Specifies additional information about the message. The meaning of this value depends on the uMsg parameter. Return Value: The function returns zero. --*/ { switch( uMsg ) { case PSCB_INITIALIZED: break; case PSCB_PRECREATE: if( lParam ){ DLGTEMPLATE *pDlgTemplate = (DLGTEMPLATE *)lParam; pDlgTemplate->style &= ~(DS_CONTEXTHELP | WS_SYSMENU); } break; } return FALSE; } PHDWPROPERTYSHEET HdwWizard( HWND hwndParent, PHARDWAREWIZ HardwareWiz, int StartPageId ) { PHDWPROPERTYSHEET HdwPropertySheet; LPPROPSHEETHEADER PropSheetHeader; PROPSHEETPAGE psp; LPTSTR Title; LONG Error; LONG DialogBaseUnits; int Index; // // Allocate memory for the header and the page array. // HdwPropertySheet = LocalAlloc(LPTR, sizeof(HDWPROPERTYSHEET)); if (!HdwPropertySheet) { return NULL; } memset(HdwPropertySheet, 0, sizeof(*HdwPropertySheet)); if (ERROR_SUCCESS != HdwBuildClassInfoList(HardwareWiz, DIBCI_NOINSTALLCLASS, HardwareWiz->hMachine ? HardwareWiz->MachineName : NULL)) { return NULL; } // // Initialize the PropertySheet Header // PropSheetHeader = &HdwPropertySheet->PropSheetHeader; PropSheetHeader->dwSize = sizeof(HdwPropertySheet->PropSheetHeader); PropSheetHeader->dwFlags = PSH_WIZARD | PSH_USECALLBACK | PSH_WIZARD97 | PSH_WATERMARK | PSH_STRETCHWATERMARK | PSH_HEADER; PropSheetHeader->hwndParent = hwndParent; PropSheetHeader->hInstance = hHdwWiz; PropSheetHeader->pszCaption = MAKEINTRESOURCE(IDS_HDWWIZNAME); PropSheetHeader->phpage = HdwPropertySheet->PropSheetPages; PropSheetHeader->pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK); PropSheetHeader->pszbmHeader = MAKEINTRESOURCE(IDB_BANNER); PropSheetHeader->pfnCallback = iHdwWizardDlgCallback; PropSheetHeader->nStartPage = 0; PropSheetHeader->nPages = 0; psp.dwSize = sizeof(PROPSHEETPAGE); psp.hInstance = hHdwWiz; psp.lParam = (LPARAM)HardwareWiz; psp.pszTitle = MAKEINTRESOURCE(IDS_HDWWIZNAME); // // If the StartPageId is IDD_INSTALLNEWDEVICE then we don't need to create the detection // and removal pages. // if (IDD_INSTALLNEWDEVICE == StartPageId) { psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_INSTALLNEWDEVICE); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLNEWDEVICE); psp.pfnDlgProc = InstallNewDeviceDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); } else { psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_WELCOME); psp.pfnDlgProc = HdwIntroDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; // // Add Hardware wizard pages // psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_PNPENUM); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_PNPENUM); psp.pfnDlgProc = HdwPnpEnumDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); // // Finish page // psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_PNPFINISH); psp.pfnDlgProc = HdwPnpFinishDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_CONNECTED); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_CONNECTED); psp.pfnDlgProc = HdwConnectedDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); // // Finish page // psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_CONNECTED_FINISH); psp.pfnDlgProc = HdwConnectedFinishDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_PROBLIST); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_PROBLIST); psp.pfnDlgProc = HdwProbListDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_PROBLIST_FINISH); psp.pfnDlgProc = HdwProbListFinishDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_ASKDETECT); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_ASKDETECT); psp.pfnDlgProc = HdwAskDetectDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_DETECTION); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_DETECTION); psp.pfnDlgProc = HdwDetectionDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_DETECTINSTALL); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_DETECTINSTALL); psp.pfnDlgProc = HdwDetectInstallDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); // // Finish page // psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_DETECTREBOOT); psp.pfnDlgProc = HdwDetectRebootDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); } // // These pages are always shown // psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_SELECTCLASS); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_SELECTCLASS); psp.pfnDlgProc = HdwPickClassDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = NULL; psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_SELECTDEVICE); psp.pfnDlgProc = HdwSelectDeviceDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_ANALYZEDEV); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_ANALYZEDEV); psp.pfnDlgProc = HdwAnalyzeDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_INSTALLDEV); psp.pszHeaderSubTitle = NULL; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_INSTALLDEV); psp.pfnDlgProc = HdwInstallDevDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); // // Finish page // psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER; psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_FINISH); psp.pfnDlgProc = HdwAddDeviceFinishDlgProc; PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp); // // check for failure on CreatePropertySheetPage. // Index = PropSheetHeader->nPages; while (Index--) { if (!PropSheetHeader->phpage[Index]) { break; } } if (Index >= 0) { Index = PropSheetHeader->nPages; while (Index--) { if (PropSheetHeader->phpage[Index]) { DestroyPropertySheetPage(PropSheetHeader->phpage[Index]); } } LocalFree(HdwPropertySheet); return NULL; } HardwareWiz->PrevPage = 0; LoadString(hHdwWiz, IDS_UNKNOWN, (PTCHAR)szUnknown, SIZECHARS(szUnknown) ); LenUnknown = lstrlen(szUnknown) * sizeof(TCHAR) + sizeof(TCHAR); LoadString(hHdwWiz, IDS_UNKNOWNDEVICE, (PTCHAR)szUnknownDevice, SIZECHARS(szUnknownDevice) ); LenUnknownDevice = lstrlen(szUnknownDevice) * sizeof(TCHAR) + sizeof(TCHAR); // // Get the Class Icon Image Lists. // HardwareWiz->ClassImageList.cbSize = sizeof(SP_CLASSIMAGELIST_DATA); if (SetupDiGetClassImageList(&HardwareWiz->ClassImageList)) { HICON hIcon; // // Add the blank icon for "None of the following devices" // if ((hIcon = LoadIcon(hHdwWiz, MAKEINTRESOURCE(IDI_BLANK))) != NULL) { g_BlankIconIndex = ImageList_AddIcon(HardwareWiz->ClassImageList.ImageList, hIcon); } } else { HardwareWiz->ClassImageList.cbSize = 0; } // // Load the cursors that the wizard will need // HardwareWiz->CurrCursor = NULL; HardwareWiz->IdcWait = LoadCursor(NULL, IDC_WAIT); HardwareWiz->IdcAppStarting = LoadCursor(NULL, IDC_APPSTARTING); HardwareWiz->IdcArrow = LoadCursor(NULL, IDC_ARROW); return HdwPropertySheet; } BOOL WINAPI InstallNewDevice( HWND hwndParent, LPGUID ClassGuid, PDWORD pReboot ) /*++ Routine Description: Exported Entry point from hdwwiz.cpl. Installs a new device. A new Devnode is created and the user is prompted to select the device. If the class guid is not specified then then the user begins at class selection. Arguments: hwndParent - Window handle of the top-level window to use for any UI related to installing the device. LPGUID ClassGuid - Optional class of the new device to install. If ClassGuid is NULL we start at detection choice page. If ClassGuid == GUID_NULL or GUID_DEVCLASS_UNKNOWN we start at class selection page. pReboot - Optional address of variable to receive reboot flags (DI_NEEDRESTART,DI_NEEDREBOOT) Return Value: BOOL TRUE for success (does not mean device was installed or updated), FALSE unexpected error. GetLastError returns the winerror code. --*/ { HARDWAREWIZ HardwareWiz; PHDWPROPERTYSHEET HdwPropertySheet; int PropSheetResult; SEARCHTHREAD SearchThread; BOOL StartDetect; if (NoPrivilegeWarning(hwndParent)) { SetLastError(ERROR_ACCESS_DENIED); return FALSE; } // // Check to make sure another Device install is underway. // This entry point is primarily for manual legacy installs. // While Base PNP has queued found new hdw installs, we don't // allow the user to install anything manually, since we may get // duplicate entries. // // if (CMP_WaitNoPendingInstallEvents(5000) == WAIT_TIMEOUT) { HdwMessageBox(hwndParent, MAKEINTRESOURCE(IDS_HDW_RUNNING_MSG), MAKEINTRESOURCE(IDS_HDW_RUNNING_TITLE), MB_OK | MB_ICONINFORMATION ); return FALSE; } memset(&HardwareWiz, 0, sizeof(HardwareWiz)); HardwareWiz.PromptForReboot = pReboot == NULL; StartDetect = (ClassGuid == NULL); // // Create a DeviceInfoList, using the classers Class guid if any. // if (ClassGuid && (IsEqualGUID(ClassGuid, &GUID_NULL) || IsEqualGUID(ClassGuid, &GUID_DEVCLASS_UNKNOWN))) { ClassGuid = NULL; } HardwareWiz.hDeviceInfo = SetupDiCreateDeviceInfoList(ClassGuid, hwndParent); if (HardwareWiz.hDeviceInfo == INVALID_HANDLE_VALUE) { return FALSE; } try { // // If the caller specified a ClassGuid, retrieve the class information // and create a DeviceInfo for it. // if (ClassGuid) { HardwareWiz.ClassGuidSelected = ClassGuid; // // Add a new element to the DeviceInfo from the GUID and class name // HardwareWiz.DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (!SetupDiGetClassDescription(HardwareWiz.ClassGuidSelected, HardwareWiz.ClassDescription, sizeof(HardwareWiz.ClassDescription)/sizeof(TCHAR), NULL ) || !SetupDiClassNameFromGuid(HardwareWiz.ClassGuidSelected, HardwareWiz.ClassName, sizeof(HardwareWiz.ClassName)/sizeof(TCHAR), NULL )) { HardwareWiz.LastError = GetLastError(); goto INDLeaveExcept; } if (!SetupDiCreateDeviceInfo(HardwareWiz.hDeviceInfo, HardwareWiz.ClassName, ClassGuid, NULL, hwndParent, DICD_GENERATE_ID, &HardwareWiz.DeviceInfoData ) || !SetupDiSetSelectedDevice(HardwareWiz.hDeviceInfo, &HardwareWiz.DeviceInfoData )) { HardwareWiz.LastError = GetLastError(); goto INDLeaveExcept; } } memset(&SearchThread, 0, sizeof(SEARCHTHREAD)); HardwareWiz.SearchThread = &SearchThread; HardwareWiz.LastError = CreateSearchThread(&HardwareWiz); if (HardwareWiz.LastError != ERROR_SUCCESS) { goto INDLeaveExcept; } // // Load the libraries that we will need // hDevMgr = LoadLibrary(TEXT("devmgr.dll")); hNewDev = LoadLibrary(TEXT("newdev.dll")); // // Create the property sheet // HdwPropertySheet = HdwWizard(hwndParent, &HardwareWiz, StartDetect ? IDD_ADDDEVICE_PNPENUM : IDD_INSTALLNEWDEVICE ); if (HdwPropertySheet) { PropSheetResult = (int)PropertySheet(&HdwPropertySheet->PropSheetHeader); LocalFree(HdwPropertySheet); } // // See if we need to run a troubleshooter // if (HardwareWiz.RunTroubleShooter) { TCHAR DeviceID[MAX_DEVICE_ID_LEN]; if (CM_Get_Device_ID_Ex(HardwareWiz.ProblemDevInst, DeviceID, SIZECHARS(DeviceID), 0, HardwareWiz.hMachine ) == CR_SUCCESS) { PDEVICEPROBLEMWIZARD pDeviceProblemWizard = NULL; pDeviceProblemWizard = (PVOID) GetProcAddress(hDevMgr, "DeviceProblemWizardW"); if (pDeviceProblemWizard) { (pDeviceProblemWizard)(hwndParent, HardwareWiz.MachineName, DeviceID ); } } } // // Final cleanup of DeviceInfoData and DeviceInfoList. // if (HardwareWiz.ClassGuidList) { LocalFree(HardwareWiz.ClassGuidList); HardwareWiz.ClassGuidList = NULL; HardwareWiz.ClassGuidSize = HardwareWiz.ClassGuidNum = 0; } if (HardwareWiz.ClassImageList.cbSize) { SetupDiDestroyClassImageList(&HardwareWiz.ClassImageList); HardwareWiz.ClassImageList.cbSize = 0; } if (HardwareWiz.Cancelled || (HardwareWiz.Registered && !HardwareWiz.Installed)) { HdwRemoveDevice(&HardwareWiz); HardwareWiz.Reboot = 0; } SetupDiDestroyDeviceInfoList(HardwareWiz.hDeviceInfo); HardwareWiz.hDeviceInfo = NULL; INDLeaveExcept:; } except(HdwUnhandledExceptionFilter(GetExceptionInformation())) { HardwareWiz.LastError = RtlNtStatusToDosError(GetExceptionCode()); } if (HardwareWiz.hDeviceInfo && HardwareWiz.hDeviceInfo != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(HardwareWiz.hDeviceInfo); HardwareWiz.hDeviceInfo = NULL; } if (HardwareWiz.SearchThread) { DestroySearchThread(&SearchThread); } if (hDevMgr) { FreeLibrary(hDevMgr); } if (hNewDev) { FreeLibrary(hNewDev); } // // Copy out the reboot flags for the caller // or put up the restart dialog if caller didn't ask for the reboot flag // if (pReboot) { *pReboot = HardwareWiz.Reboot; } else if (HardwareWiz.Reboot) { RestartDialogEx(hwndParent, NULL, EWX_REBOOT, REASON_PLANNED_FLAG | REASON_HWINSTALL); } // // See if we need to shutdown the machine. // if (HardwareWiz.Shutdown) { ShutdownMachine(hwndParent); } SetLastError(HardwareWiz.LastError); return HardwareWiz.LastError == ERROR_SUCCESS; } void AddHardwareWizard( HWND hwnd, PTCHAR MachineName ) /*++ Routine Description: Arguments: hwnd - Window handle of the top-level window to use for any UI related to installing the device. Return Value: --*/ { HARDWAREWIZ HardwareWiz; PHDWPROPERTYSHEET HdwPropertySheet; int PropSheetResult; SEARCHTHREAD SearchThread; CONFIGRET ConfigRet; // // If the user does not have SE_LOAD_DRIVER_NAME privileges then just display a warning // message and exit. // if (NoPrivilegeWarning(hwnd)) { SetLastError(ERROR_ACCESS_DENIED); return; } if (MachineName) { lstrcpy(HardwareWiz.MachineName, MachineName); ConfigRet = CM_Connect_Machine(MachineName, &HardwareWiz.hMachine); if (ConfigRet != CR_SUCCESS) { return; } } // // Check to make sure another Device install is underway. // This entry point is primarily for manual legacy installs. // While Base PNP has queued found new hdw installs, we don't // allow the user to install anything manually, since we may get // duplicate entries. // // if (CMP_WaitNoPendingInstallEvents(5000) == WAIT_TIMEOUT) { HdwMessageBox(hwnd, MAKEINTRESOURCE(IDS_HDW_RUNNING_MSG), MAKEINTRESOURCE(IDS_HDW_RUNNING_TITLE), MB_OK | MB_ICONINFORMATION ); return; } memset(&HardwareWiz, 0, sizeof(HardwareWiz)); // // Create a DeviceInfoList HardwareWiz.hDeviceInfo = SetupDiCreateDeviceInfoList(NULL, hwnd); if (HardwareWiz.hDeviceInfo == INVALID_HANDLE_VALUE) { return; } // // Create the Search thread to look for compatible drivers. // This thread will sit around waiting for requests until // told to go away. // memset(&SearchThread, 0, sizeof(SEARCHTHREAD)); HardwareWiz.SearchThread = &SearchThread; if (CreateSearchThread(&HardwareWiz) != ERROR_SUCCESS) { SetupDiDestroyDeviceInfoList(HardwareWiz.hDeviceInfo); return; } // // Load the libraries that we will need // hDevMgr = LoadLibrary(TEXT("devmgr.dll")); hNewDev = LoadLibrary(TEXT("newdev.dll")); HdwPropertySheet = HdwWizard(hwnd, &HardwareWiz, 0); if (HdwPropertySheet) { PropSheetResult = (int)PropertySheet(&HdwPropertySheet->PropSheetHeader); LocalFree(HdwPropertySheet); } // // See if we need to run a troubleshooter // if (HardwareWiz.RunTroubleShooter) { TCHAR DeviceID[MAX_DEVICE_ID_LEN]; if (CM_Get_Device_ID_Ex(HardwareWiz.ProblemDevInst, DeviceID, SIZECHARS(DeviceID), 0, HardwareWiz.hMachine ) == CR_SUCCESS) { PDEVICEPROBLEMWIZARD pDeviceProblemWizard = NULL; pDeviceProblemWizard = (PVOID) GetProcAddress(hDevMgr, "DeviceProblemWizardW"); if (pDeviceProblemWizard) { (pDeviceProblemWizard)(hwnd, HardwareWiz.MachineName, DeviceID ); } } } // // Final cleanup of DeviceInfoData and DeviceInfoList // if (HardwareWiz.ClassGuidList) { LocalFree(HardwareWiz.ClassGuidList); HardwareWiz.ClassGuidList = NULL; HardwareWiz.ClassGuidSize = HardwareWiz.ClassGuidNum = 0; } if (HardwareWiz.ClassImageList.cbSize) { SetupDiDestroyClassImageList(&HardwareWiz.ClassImageList); HardwareWiz.ClassImageList.cbSize = 0; } if (HardwareWiz.Cancelled || (HardwareWiz.Registered && !HardwareWiz.Installed)) { HdwRemoveDevice(&HardwareWiz); HardwareWiz.Reboot = 0; } SetupDiDestroyDeviceInfoList(HardwareWiz.hDeviceInfo); HardwareWiz.hDeviceInfo = NULL; if (HardwareWiz.SearchThread) { DestroySearchThread(HardwareWiz.SearchThread); } if (hDevMgr) { FreeLibrary(hDevMgr); } if (hNewDev) { FreeLibrary(hNewDev); } // // Do we need to reboot? // if (HardwareWiz.Reboot) { RestartDialogEx(hwnd, NULL, EWX_REBOOT, REASON_PLANNED_FLAG | REASON_HWINSTALL); } // // Do we need to shutdown? // if (HardwareWiz.Shutdown) { ShutdownMachine(hwnd); } return; } LONG CPlApplet( HWND hWnd, WORD uMsg, DWORD_PTR lParam1, LPARAM lParam2 ) { LPNEWCPLINFO lpCPlInfo; LPCPLINFO lpOldCPlInfo; switch (uMsg) { case CPL_INIT: return TRUE; case CPL_GETCOUNT: return 1; case CPL_INQUIRE: lpOldCPlInfo = (LPCPLINFO)(LPARAM)lParam2; lpOldCPlInfo->lData = 0L; lpOldCPlInfo->idIcon = IDI_HDWWIZICON; lpOldCPlInfo->idName = IDS_HDWWIZ; lpOldCPlInfo->idInfo = IDS_HDWWIZINFO; return TRUE; case CPL_NEWINQUIRE: lpCPlInfo = (LPNEWCPLINFO)(LPARAM)lParam2; lpCPlInfo->hIcon = LoadIcon(hHdwWiz, MAKEINTRESOURCE(IDI_HDWWIZICON)); LoadString(hHdwWiz, IDS_HDWWIZ, lpCPlInfo->szName, sizeof(lpCPlInfo->szName)); LoadString(hHdwWiz, IDS_HDWWIZINFO, lpCPlInfo->szInfo, sizeof(lpCPlInfo->szInfo)); lpCPlInfo->dwHelpContext = IDH_HDWWIZAPPLET; lpCPlInfo->dwSize = sizeof(NEWCPLINFO); lpCPlInfo->lData = 0; lpCPlInfo->szHelpFile[0] = '\0'; return TRUE; case CPL_DBLCLK: AddHardwareWizard(hWnd, NULL); break; case CPL_STARTWPARMS: // // what does this mean ? // break; case CPL_EXIT: // Free up any allocations of resources made. break; default: break; } return 0L; } BOOL DllInitialize( IN PVOID hmod, IN ULONG ulReason, IN PCONTEXT pctx OPTIONAL ) { hHdwWiz = hmod; if (ulReason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hmod); SHFusionInitializeFromModule(hmod); } else if (ulReason == DLL_PROCESS_DETACH) { SHFusionUninitialize(); } return TRUE; }