234 lines
6.3 KiB
C++
234 lines
6.3 KiB
C++
|
#include <windows.h>
|
||
|
#include <netcfgx.h>
|
||
|
#include <netcfgn.h>
|
||
|
|
||
|
#include <setupapi.h>
|
||
|
#include <devguid.h>
|
||
|
#include <tchar.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
const WCHAR szComponentId[] = L"DSMIGRAT";
|
||
|
const WCHAR szName[] = L"deldsm.exe";
|
||
|
const WCHAR szClient[] = L"ms_nwclient";
|
||
|
const WCHAR szUnknown[] = L"Microsoft";
|
||
|
const WCHAR szDSM[] = L"dsmigrat";
|
||
|
|
||
|
HRESULT
|
||
|
HrFindAndRemoveComponent2(
|
||
|
INetCfg* pnc,
|
||
|
const GUID* pguidClass,
|
||
|
PCWSTR pszComponentId,
|
||
|
OBO_TOKEN* pOboToken)
|
||
|
{
|
||
|
// Get the component class object.
|
||
|
//
|
||
|
INetCfgClass* pncclass;
|
||
|
HRESULT hr = pnc->QueryNetCfgClass (pguidClass, IID_INetCfgClass,
|
||
|
reinterpret_cast<void**>(&pncclass));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Find the component to remove.
|
||
|
//
|
||
|
INetCfgComponent* pnccRemove;
|
||
|
hr = pncclass->FindComponent (pszComponentId, &pnccRemove);
|
||
|
if (S_OK == hr)
|
||
|
{
|
||
|
INetCfgClassSetup* pncclasssetup;
|
||
|
hr = pncclass->QueryInterface (IID_INetCfgClassSetup,
|
||
|
reinterpret_cast<void**>(&pncclasssetup));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = pncclasssetup->DeInstall (pnccRemove, pOboToken, NULL);
|
||
|
|
||
|
//ReleaseObj (pncclasssetup);
|
||
|
pncclasssetup->Release();
|
||
|
}
|
||
|
|
||
|
//ReleaseObj (pnccRemove);
|
||
|
pnccRemove->Release();
|
||
|
}
|
||
|
else if (S_FALSE == hr)
|
||
|
{
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
|
||
|
//ReleaseObj (pncclass);
|
||
|
pncclass->Release();
|
||
|
}
|
||
|
/*
|
||
|
TraceHr (ttidError, FAL, hr,
|
||
|
(NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
|
||
|
"HrFindAndRemoveComponent");
|
||
|
*/
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
HrRemoveComponentOboSoftware2 (
|
||
|
INetCfg* pnc,
|
||
|
const GUID& rguidClass,
|
||
|
PCWSTR pszComponentId,
|
||
|
PCWSTR pszManufacturer,
|
||
|
PCWSTR pszProduct,
|
||
|
PCWSTR pszDisplayName)
|
||
|
{
|
||
|
// Make an "on behalf of" token for the software.
|
||
|
//
|
||
|
OBO_TOKEN OboToken;
|
||
|
ZeroMemory (&OboToken, sizeof(OboToken));
|
||
|
OboToken.Type = OBO_SOFTWARE;
|
||
|
OboToken.pszwManufacturer = pszManufacturer;
|
||
|
OboToken.pszwProduct = pszProduct;
|
||
|
OboToken.pszwDisplayName = pszDisplayName;
|
||
|
|
||
|
HRESULT hr = HrFindAndRemoveComponent2(pnc, &rguidClass, pszComponentId,
|
||
|
&OboToken);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
HrCreateAndInitializeINetCfg2 (
|
||
|
BOOL* pfInitCom,
|
||
|
INetCfg** ppnc,
|
||
|
BOOL fGetWriteLock,
|
||
|
DWORD cmsTimeout,
|
||
|
PCWSTR pszClientDesc,
|
||
|
PWSTR* ppszClientDesc)
|
||
|
{
|
||
|
//Assert (ppnc);
|
||
|
|
||
|
// Initialize the output parameters.
|
||
|
*ppnc = NULL;
|
||
|
|
||
|
if (ppszClientDesc)
|
||
|
{
|
||
|
*ppszClientDesc = NULL;
|
||
|
}
|
||
|
|
||
|
// Initialize COM if the caller requested.
|
||
|
HRESULT hr = S_OK;
|
||
|
if (pfInitCom && *pfInitCom)
|
||
|
{
|
||
|
hr = CoInitializeEx( NULL,
|
||
|
COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED );
|
||
|
if (RPC_E_CHANGED_MODE == hr)
|
||
|
{
|
||
|
hr = S_OK;
|
||
|
*pfInitCom = FALSE;
|
||
|
}
|
||
|
}
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Create the object implementing INetCfg.
|
||
|
//
|
||
|
INetCfg* pnc;
|
||
|
|
||
|
hr = CoCreateInstance(
|
||
|
CLSID_CNetCfg,
|
||
|
NULL,
|
||
|
CLSCTX_INPROC_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
|
||
|
IID_INetCfg,
|
||
|
reinterpret_cast<void**>(&pnc));
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
INetCfgLock * pnclock = NULL;
|
||
|
if (fGetWriteLock)
|
||
|
{
|
||
|
// Get the locking interface
|
||
|
hr = pnc->QueryInterface(IID_INetCfgLock,
|
||
|
reinterpret_cast<LPVOID *>(&pnclock));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Attempt to lock the INetCfg for read/write
|
||
|
hr = pnclock->AcquireWriteLock(cmsTimeout, pszClientDesc,
|
||
|
ppszClientDesc);
|
||
|
if (S_FALSE == hr)
|
||
|
{
|
||
|
// Couldn't acquire the lock
|
||
|
hr = NETCFG_E_NO_WRITE_LOCK;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Initialize the INetCfg object.
|
||
|
//
|
||
|
hr = pnc->Initialize (NULL);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
*ppnc = pnc;
|
||
|
//AddRefObj (pnc);
|
||
|
pnc->AddRef();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pnclock)
|
||
|
{
|
||
|
pnclock->ReleaseWriteLock();
|
||
|
}
|
||
|
}
|
||
|
// Transfer reference to caller.
|
||
|
}
|
||
|
//ReleaseObj(pnclock);
|
||
|
pnclock->Release();
|
||
|
|
||
|
//ReleaseObj(pnc);
|
||
|
pnc->Release();
|
||
|
}
|
||
|
|
||
|
// If we failed anything above, and we've initialized COM,
|
||
|
// be sure an uninitialize it.
|
||
|
//
|
||
|
if (FAILED(hr) && pfInitCom && *pfInitCom)
|
||
|
{
|
||
|
CoUninitialize ();
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
extern "C" int __cdecl wmain(
|
||
|
IN int argc,
|
||
|
IN PWSTR argv[]
|
||
|
)
|
||
|
{
|
||
|
INetCfg *pnc = NULL;
|
||
|
HRESULT hr = S_OK;
|
||
|
PWSTR pszDesc = NULL;
|
||
|
BOOL fInitCom = TRUE;
|
||
|
BOOL fWriteLock = TRUE;
|
||
|
|
||
|
hr = HrCreateAndInitializeINetCfg2(&fInitCom,
|
||
|
&pnc,
|
||
|
fWriteLock,
|
||
|
0,
|
||
|
szName,
|
||
|
&pszDesc);
|
||
|
if (FAILED(hr)) {
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
hr = HrRemoveComponentOboSoftware2(pnc,
|
||
|
GUID_DEVCLASS_NETCLIENT,
|
||
|
szClient,
|
||
|
szUnknown,
|
||
|
szDSM,
|
||
|
szComponentId);
|
||
|
if (FAILED(hr)) {
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
printf("DSMU's dependencies on GSNW and IPX have been removed. To complete the uninstall, please delete the 'DSMigrat' directory under the directory 'Program Files'.\n");
|
||
|
error:
|
||
|
if (FAILED(hr)) {
|
||
|
printf("The uninstallation of Dsmigrat has failed with an error 0x%x\n",hr);
|
||
|
}
|
||
|
if (pnc)
|
||
|
pnc->Release();
|
||
|
return 0;
|
||
|
}
|
||
|
|