windows-nt/Source/XPSP1/NT/shell/osshell/snapins/devmgr/snapin/devrmdlg.cpp
2020-09-26 16:20:57 +08:00

260 lines
6.1 KiB
C++

/*++
Copyright (C) 1997-1999 Microsoft Corporation
Module Name:
devrmdlg.cpp
Abstract:
This module implements CRemoveDevDlg -- device removing dialog box
Author:
William Hsieh (williamh) created
Revision History:
--*/
#include "devmgr.h"
#include "hwprof.h"
#include "devrmdlg.h"
//
// help topic ids
//
const DWORD g_a210HelpIDs[]=
{
IDC_REMOVEDEV_ICON, IDH_DISABLEHELP, // Confirm Device Removal: "" (Static)
IDC_REMOVEDEV_DEVDESC, IDH_DISABLEHELP, // Confirm Device Removal: "" (Static)
IDC_REMOVEDEV_WARNING, IDH_DISABLEHELP, // Confirm Device Removal: "" (Static)
0, 0
};
//
// CRemoveDevDlg implementation
//
BOOL CRemoveDevDlg::OnInitDialog()
{
SetDlgItemText(m_hDlg, IDC_REMOVEDEV_DEVDESC, m_pDevice->GetDisplayName());
HICON hIconOld;
hIconOld = (HICON)SendDlgItemMessage(m_hDlg, IDC_REMOVEDEV_ICON,
STM_SETICON,
(WPARAM)(m_pDevice->LoadClassIcon()),
0
);
if (hIconOld)
DestroyIcon(hIconOld);
try
{
String str;
str.LoadString(g_hInstance, IDS_REMOVEDEV_WARN);
SetDlgItemText(m_hDlg, IDC_REMOVEDEV_WARNING, str);
}
catch (CMemoryException* e)
{
e->Delete();
return FALSE;
}
return TRUE;
}
void
CRemoveDevDlg::OnCommand(
WPARAM wParam,
LPARAM lParam
)
{
if (BN_CLICKED == HIWORD(wParam))
{
if (IDOK == LOWORD(wParam))
{
OnOk();
}
else if (IDCANCEL == LOWORD(wParam))
{
EndDialog(m_hDlg, IDCANCEL);
}
}
}
void CRemoveDevDlg::OnOk()
{
SP_REMOVEDEVICE_PARAMS rmdParams;
int hwpfIndex;
BOOL Continue = TRUE;
CHwProfile* phwpf;
rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
HCURSOR hCursorOld;
hCursorOld = SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)));
//
// Uninstall does not apply to specific profiles -- it is global.
//
rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL;
rmdParams.HwProfile = 0;
//
// walk down the tree and remove all of this device's children
//
if (m_pDevice->GetChild() &&
!IsRemoveSubtreeOk(m_pDevice->GetChild(), &rmdParams))
{
//
// Children refuse the removal. Cancel the removal.
//
MsgBoxParam(m_hDlg, IDS_DESCENDANTS_VETO, 0, MB_OK | MB_ICONINFORMATION);
EndDialog(m_hDlg, IDCANCEL);
return;
}
SP_DEVINSTALL_PARAMS dip;
dip.cbSize = sizeof(dip);
m_pDevice->m_pMachine->DiSetClassInstallParams(*m_pDevice,
&rmdParams.ClassInstallHeader,
sizeof(rmdParams));
BOOL RemovalOK;
//
// Either this device has no children or the children has no
// objection on removal. Remove it.
//
RemovalOK = m_pDevice->m_pMachine->DiCallClassInstaller(DIF_REMOVE, *m_pDevice);
if (hCursorOld)
{
SetCursor(hCursorOld);
}
m_pDevice->m_pMachine->DiSetClassInstallParams(*m_pDevice, NULL, 0);
if (RemovalOK)
{
EndDialog(m_hDlg, IDOK);
}
else
{
//
// Can not removed the device, return Cancel so that
// the caller know what is going on.
//
MsgBoxParam(m_hDlg, IDS_UNINSTALL_FAILED, 0, MB_OK | MB_ICONINFORMATION);
EndDialog(m_hDlg, IDCANCEL);
}
}
//
// This function walks the substree started with the given CDevice to
// see if it is ok to removed the CDevice.
// INPUT:
// pDevice -- the device
// prmdParams -- parameter used to call the setupapi
// OUTPUT:
// TRUE -- it is ok to remove
// FALSE -- it is NOT ok to remove
BOOL
CRemoveDevDlg::IsRemoveSubtreeOk(
CDevice* pDevice,
PSP_REMOVEDEVICE_PARAMS prmdParams
)
{
BOOL Result = TRUE;
HDEVINFO hDevInfo;
while (Result && pDevice)
{
//
// if the device has children, remove all of them.
//
if (Result && pDevice->GetChild())
{
Result = IsRemoveSubtreeOk(pDevice->GetChild(), prmdParams);
}
//
// create a new HDEVINFO just for this device -- we do not want
// to change anything in the main device tree maintained by CMachine
//
hDevInfo = pDevice->m_pMachine->DiCreateDeviceInfoList(NULL, m_hDlg);
if (INVALID_HANDLE_VALUE == hDevInfo)
{
return FALSE;
}
SP_DEVINFO_DATA DevData;
DevData.cbSize = sizeof(DevData);
CDevInfoList DevInfoList(hDevInfo, m_hDlg);
//
// include the device in the newly created hdevinfo
//
DevInfoList.DiOpenDeviceInfo(pDevice->GetDeviceID(), m_hDlg, 0,
&DevData);
DevInfoList.DiSetClassInstallParams(&DevData,
&prmdParams->ClassInstallHeader,
sizeof(SP_REMOVEDEVICE_PARAMS)
);
//
// remove this devnode.
//
Result = DevInfoList.DiCallClassInstaller(DIF_REMOVE, &DevData);
DevInfoList.DiSetClassInstallParams(&DevData, NULL, 0);
//
// continue the query on all the siblings
//
pDevice = pDevice->GetSibling();
}
return Result;
}
BOOL
CRemoveDevDlg::OnDestroy()
{
HICON hIcon;
if(hIcon = (HICON)SendDlgItemMessage(m_hDlg, IDC_REMOVEDEV_ICON, STM_GETICON, 0, 0)) {
DestroyIcon(hIcon);
}
return FALSE;
}
BOOL
CRemoveDevDlg::OnHelp(
LPHELPINFO pHelpInfo
)
{
WinHelp((HWND)pHelpInfo->hItemHandle, DEVMGR_HELP_FILE_NAME, HELP_WM_HELP,
(ULONG_PTR)g_a210HelpIDs);
return FALSE;
}
BOOL
CRemoveDevDlg::OnContextMenu(
HWND hWnd,
WORD xPos,
WORD yPos
)
{
WinHelp(hWnd, DEVMGR_HELP_FILE_NAME, HELP_CONTEXTMENU,
(ULONG_PTR)g_a210HelpIDs);
return FALSE;
}