1238 lines
32 KiB
C++
1238 lines
32 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (C) Microsoft Corporation, 1997 - 1999
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
senssink.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Main entry point for the Sample SENS Subscriber.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Gopal Parupudi <GopalP>
|
|||
|
|
|||
|
[Notes:]
|
|||
|
|
|||
|
optional-notes
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
GopalP 11/17/1997 Start.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// Define this once and only once per exe.
|
|||
|
#define INITGUIDS
|
|||
|
|
|||
|
#include <common.hxx>
|
|||
|
#include <objbase.h>
|
|||
|
#include <windows.h>
|
|||
|
#include <ole2ver.h>
|
|||
|
#include <initguid.h>
|
|||
|
#include <eventsys.h>
|
|||
|
#include <sensevts.h>
|
|||
|
#include <sens.h>
|
|||
|
#include "sinkcomn.hxx"
|
|||
|
#include "sinkguid.hxx"
|
|||
|
#include "senssink.hxx"
|
|||
|
#include "cfacnet.hxx"
|
|||
|
#include "cfaclogn.hxx"
|
|||
|
#include "cfacpwr.hxx"
|
|||
|
|
|||
|
|
|||
|
#if defined(SENS_NT4)
|
|||
|
#define SENS_TLB SENS_BSTR("SENS.EXE")
|
|||
|
#else // SENS_NT4
|
|||
|
#define SENS_TLB SENS_BSTR("SENS.DLL")
|
|||
|
#endif // SENS_NT4
|
|||
|
|
|||
|
#define SUBSCRIBER SENS_STRING("SENS_SUBSCRIBER: ")
|
|||
|
#define MAX_QUERY_SIZE 512
|
|||
|
#define MAJOR_VER 1
|
|||
|
#define MINOR_VER 0
|
|||
|
#define DEFAULT_LCID 0x0
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Globals
|
|||
|
//
|
|||
|
IEventSystem *gpIEventSystem;
|
|||
|
ITypeInfo *gpITypeInfoNetwork;
|
|||
|
ITypeInfo *gpITypeInfoLogon;
|
|||
|
ITypeInfo *gpITypeInfoLogon2;
|
|||
|
ITypeInfo *gpITypeInfoOnNow;
|
|||
|
DWORD gTid;
|
|||
|
HANDLE ghEvent;
|
|||
|
|
|||
|
|
|||
|
#if defined(SENS_CHICAGO)
|
|||
|
|
|||
|
#ifdef DBG
|
|||
|
DWORD gdwDebugOutputLevel;
|
|||
|
#endif // DBG
|
|||
|
|
|||
|
#endif // SENS_CHICAGO
|
|||
|
|
|||
|
|
|||
|
|
|||
|
int __cdecl
|
|||
|
main(
|
|||
|
int argc,
|
|||
|
char ** argv
|
|||
|
)
|
|||
|
{
|
|||
|
HRESULT hr;
|
|||
|
DWORD dwVer;
|
|||
|
DWORD dwRegCO;
|
|||
|
DWORD dwWaitStatus;
|
|||
|
BOOL fInitialized;
|
|||
|
BOOL bUnregister;
|
|||
|
BOOL bSetupPhase;
|
|||
|
MSG msg;
|
|||
|
LPCLASSFACTORY pNetCF;
|
|||
|
LPCLASSFACTORY pLogonCF;
|
|||
|
LPCLASSFACTORY pLogon2CF;
|
|||
|
LPCLASSFACTORY pPowerCF;
|
|||
|
ITypeLib *pITypeLib;
|
|||
|
|
|||
|
hr = S_OK;
|
|||
|
dwRegCO = 0x0;
|
|||
|
bUnregister = FALSE;
|
|||
|
bSetupPhase = FALSE;
|
|||
|
fInitialized = FALSE;
|
|||
|
pNetCF = NULL;
|
|||
|
pLogonCF = NULL;
|
|||
|
pLogon2CF = NULL;
|
|||
|
pPowerCF = NULL;
|
|||
|
gpIEventSystem = NULL;
|
|||
|
pITypeLib = NULL;
|
|||
|
gpITypeInfoNetwork = NULL;
|
|||
|
gpITypeInfoLogon = NULL;
|
|||
|
gpITypeInfoLogon2 = NULL;
|
|||
|
gpITypeInfoOnNow = NULL;
|
|||
|
|
|||
|
dwVer = CoBuildVersion();
|
|||
|
if (rmm != HIWORD(dwVer))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoBuildVersion() returned incompatible version.\n")));
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoInitializeEx() returned 0x%x.\n"), hr));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
fInitialized = TRUE;
|
|||
|
|
|||
|
//
|
|||
|
// Check the command-line args
|
|||
|
//
|
|||
|
if ( ((argc == 2) && ((argv[1][0] != '-') && (argv[1][0] != '/')))
|
|||
|
|| (argc > 2))
|
|||
|
{
|
|||
|
Usage();
|
|||
|
return (-1);
|
|||
|
}
|
|||
|
|
|||
|
if (argc == 2)
|
|||
|
{
|
|||
|
switch (argv[1][1])
|
|||
|
{
|
|||
|
case 'i':
|
|||
|
case 'I':
|
|||
|
bSetupPhase = TRUE;
|
|||
|
bUnregister = FALSE;
|
|||
|
break;
|
|||
|
|
|||
|
case 'u':
|
|||
|
case 'U':
|
|||
|
bSetupPhase = TRUE;
|
|||
|
bUnregister = TRUE;
|
|||
|
break;
|
|||
|
|
|||
|
case 'e':
|
|||
|
case 'E':
|
|||
|
// SCM calls me with /Embedding flag
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
Usage();
|
|||
|
return (-1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (bSetupPhase == TRUE)
|
|||
|
{
|
|||
|
hr = RegisterWithES(bUnregister);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
// Network Subscriber
|
|||
|
hr = RegisterSubscriberCLSID(
|
|||
|
CLSID_SensTestSubscriberNetwork,
|
|||
|
TEST_SUBSCRIBER_NAME_NETWORK,
|
|||
|
bUnregister
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister Test Subscriber Network CLSID")
|
|||
|
SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered Test Subscriber Network CLSID.\n"),
|
|||
|
bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
|
|||
|
}
|
|||
|
|
|||
|
// Logon Subscriber
|
|||
|
hr = RegisterSubscriberCLSID(
|
|||
|
CLSID_SensTestSubscriberLogon,
|
|||
|
TEST_SUBSCRIBER_NAME_LOGON,
|
|||
|
bUnregister
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister Test Subscriber Logon CLSID")
|
|||
|
SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered Test Subscriber Logon CLSID.\n"),
|
|||
|
bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
|
|||
|
}
|
|||
|
|
|||
|
// Logon2 Subscriber
|
|||
|
hr = RegisterSubscriberCLSID(
|
|||
|
CLSID_SensTestSubscriberLogon2,
|
|||
|
TEST_SUBSCRIBER_NAME_LOGON2,
|
|||
|
bUnregister
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister Test Subscriber Logon2 CLSID")
|
|||
|
SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered Test Subscriber Logon2 CLSID.\n"),
|
|||
|
bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
|
|||
|
}
|
|||
|
|
|||
|
// Power Subscriber
|
|||
|
hr = RegisterSubscriberCLSID(
|
|||
|
CLSID_SensTestSubscriberOnNow,
|
|||
|
TEST_SUBSCRIBER_NAME_POWER,
|
|||
|
bUnregister
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister Test Subscriber Power CLSID")
|
|||
|
SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered Test Subscriber Power CLSID.\n"),
|
|||
|
bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
|
|||
|
}
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Get the ITypeInfo pointer.
|
|||
|
//
|
|||
|
hr = LoadRegTypeLib(
|
|||
|
LIBID_SensEvents,
|
|||
|
MAJOR_VER,
|
|||
|
MINOR_VER,
|
|||
|
DEFAULT_LCID,
|
|||
|
&pITypeLib
|
|||
|
);
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("LoadRegTypeLib() returned 0x%x\n"), hr));
|
|||
|
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
hr = LoadTypeLib(
|
|||
|
SENS_TLB,
|
|||
|
&pITypeLib
|
|||
|
);
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("LoadTypeLib() returned 0x%x\n"), hr));
|
|||
|
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Get type information for the ISensNetwork interface.
|
|||
|
hr = pITypeLib->GetTypeInfoOfGuid(
|
|||
|
IID_ISensNetwork,
|
|||
|
&gpITypeInfoNetwork
|
|||
|
);
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ITypeLib::GetTypeInfoOfGuid(ISensNetwork) returned 0x%x\n"), hr));
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
// Get type information for the ISensLogon interface.
|
|||
|
hr = pITypeLib->GetTypeInfoOfGuid(
|
|||
|
IID_ISensLogon,
|
|||
|
&gpITypeInfoLogon
|
|||
|
);
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ITypeLib::GetTypeInfoOfGuid(ISensLogon) returned 0x%x\n"), hr));
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
// Get type information for the ISensLogon2 interface.
|
|||
|
hr = pITypeLib->GetTypeInfoOfGuid(
|
|||
|
IID_ISensLogon2,
|
|||
|
&gpITypeInfoLogon2
|
|||
|
);
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ITypeLib::GetTypeInfoOfGuid(ISensLogon2) returned 0x%x\n"), hr));
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
// Get type information for the ISensOnNow interface.
|
|||
|
hr = pITypeLib->GetTypeInfoOfGuid(
|
|||
|
IID_ISensOnNow,
|
|||
|
&gpITypeInfoOnNow
|
|||
|
);
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ITypeLib::GetTypeInfoOfGuid(ISensOnNow) returned 0x%x\n"), hr));
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Create the event
|
|||
|
//
|
|||
|
ghEvent = CreateEvent(
|
|||
|
NULL, // Security Attributes
|
|||
|
FALSE, // bManualReset
|
|||
|
FALSE, // Initial state
|
|||
|
SENS_STRING("SENS Test Subscriber Quit Event")
|
|||
|
);
|
|||
|
if (ghEvent == NULL)
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CreateEvent() failed.\n")));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Create the Network ClassFactory and register it with COM.
|
|||
|
//
|
|||
|
|
|||
|
pNetCF = new CISensNetworkCF;
|
|||
|
if (NULL == pNetCF)
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
pNetCF->AddRef(); // Because we hold on to it.
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ClassFactory created successfully.\n")));
|
|||
|
|
|||
|
// Register the CLSID
|
|||
|
hr = CoRegisterClassObject(
|
|||
|
CLSID_SensTestSubscriberNetwork,
|
|||
|
(LPUNKNOWN) pNetCF,
|
|||
|
CLSCTX_LOCAL_SERVER,
|
|||
|
REGCLS_MULTIPLEUSE,
|
|||
|
&dwRegCO
|
|||
|
);
|
|||
|
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoRegisterClassObject(Network) returned 0x%x.\n"), hr));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully registered the ISensNetwork Class Factory.\n")));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Create the Logon ClassFactory and register it with COM.
|
|||
|
//
|
|||
|
|
|||
|
pLogonCF = new CISensLogonCF;
|
|||
|
if (NULL == pLogonCF)
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
pLogonCF->AddRef(); // Because we hold on to it.
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ClassFactory created successfully.\n")));
|
|||
|
|
|||
|
hr = CoRegisterClassObject(
|
|||
|
CLSID_SensTestSubscriberLogon,
|
|||
|
(LPUNKNOWN) pLogonCF,
|
|||
|
CLSCTX_LOCAL_SERVER,
|
|||
|
REGCLS_MULTIPLEUSE,
|
|||
|
&dwRegCO
|
|||
|
);
|
|||
|
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoRegisterClassObject(Logon) returned 0x%x.\n"), hr));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully registered the ISensLogon Class Factory.\n")));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Create the Logon2 ClassFactory and register it with COM.
|
|||
|
//
|
|||
|
|
|||
|
pLogon2CF = new CISensLogon2CF;
|
|||
|
if (NULL == pLogon2CF)
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
pLogon2CF->AddRef(); // Because we hold on to it.
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ClassFactory created successfully.\n")));
|
|||
|
|
|||
|
hr = CoRegisterClassObject(
|
|||
|
CLSID_SensTestSubscriberLogon2,
|
|||
|
(LPUNKNOWN) pLogon2CF,
|
|||
|
CLSCTX_LOCAL_SERVER,
|
|||
|
REGCLS_MULTIPLEUSE,
|
|||
|
&dwRegCO
|
|||
|
);
|
|||
|
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoRegisterClassObject(Logon2) returned 0x%x.\n"), hr));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully registered the ISensLogon2 Class Factory.\n")));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Create the Power ClassFactory and register it with COM.
|
|||
|
//
|
|||
|
|
|||
|
pPowerCF = new CISensOnNowCF;
|
|||
|
if (NULL == pPowerCF)
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
pPowerCF->AddRef(); // Because we hold on to it.
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ClassFactory created successfully.\n")));
|
|||
|
|
|||
|
hr = CoRegisterClassObject(
|
|||
|
CLSID_SensTestSubscriberOnNow,
|
|||
|
(LPUNKNOWN) pPowerCF,
|
|||
|
CLSCTX_LOCAL_SERVER,
|
|||
|
REGCLS_MULTIPLEUSE,
|
|||
|
&dwRegCO
|
|||
|
);
|
|||
|
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoRegisterClassObject(Power) returned 0x%x.\n"), hr));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully registered the ISensOnNow Class Factory.\n")));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Wait to quit.
|
|||
|
//
|
|||
|
dwWaitStatus = WaitForSingleObject(ghEvent, INFINITE);
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("WaitForSingleObject returned %d\n"), dwWaitStatus));
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Cleanup
|
|||
|
//
|
|||
|
Cleanup:
|
|||
|
|
|||
|
if ( (0L != dwRegCO)
|
|||
|
&& (bSetupPhase == TRUE)
|
|||
|
&& (bUnregister == TRUE))
|
|||
|
{
|
|||
|
CoRevokeClassObject(dwRegCO);
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("CoRevokeClassObject() returned 0x%x.\n"), hr));
|
|||
|
}
|
|||
|
|
|||
|
if (bSetupPhase == TRUE)
|
|||
|
{
|
|||
|
SensPrint(SENS_INFO, (SENS_STRING("\n") SUBSCRIBER SENS_STRING("Sens Test Subscriber Configuration %s.\n"),
|
|||
|
FAILED(hr) ? SENS_STRING("failed") : SENS_STRING("successful")));
|
|||
|
}
|
|||
|
|
|||
|
if (NULL != pNetCF)
|
|||
|
{
|
|||
|
pNetCF->Release();
|
|||
|
}
|
|||
|
if (NULL != pLogonCF)
|
|||
|
{
|
|||
|
pLogonCF->Release();
|
|||
|
}
|
|||
|
if (NULL != pLogon2CF)
|
|||
|
{
|
|||
|
pLogon2CF->Release();
|
|||
|
}
|
|||
|
if (NULL != pPowerCF)
|
|||
|
{
|
|||
|
pPowerCF->Release();
|
|||
|
}
|
|||
|
if (NULL != pITypeLib)
|
|||
|
{
|
|||
|
pITypeLib->Release();
|
|||
|
}
|
|||
|
if (NULL != gpITypeInfoNetwork)
|
|||
|
{
|
|||
|
gpITypeInfoNetwork->Release();
|
|||
|
}
|
|||
|
if (NULL != gpITypeInfoLogon)
|
|||
|
{
|
|||
|
gpITypeInfoLogon->Release();
|
|||
|
}
|
|||
|
if (NULL != gpITypeInfoLogon2)
|
|||
|
{
|
|||
|
gpITypeInfoLogon2->Release();
|
|||
|
}
|
|||
|
if (NULL != gpITypeInfoOnNow)
|
|||
|
{
|
|||
|
gpITypeInfoOnNow->Release();
|
|||
|
}
|
|||
|
|
|||
|
if (fInitialized)
|
|||
|
{
|
|||
|
CoUninitialize();
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT
|
|||
|
RegisterWithES(
|
|||
|
BOOL bUnregister
|
|||
|
)
|
|||
|
{
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
hr = S_OK;
|
|||
|
|
|||
|
//
|
|||
|
// Instantiate the Event System
|
|||
|
//
|
|||
|
hr = CoCreateInstance(
|
|||
|
CLSID_CEventSystem,
|
|||
|
NULL,
|
|||
|
CLSCTX_SERVER,
|
|||
|
IID_IEventSystem,
|
|||
|
(LPVOID *) &gpIEventSystem
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to create CEventSystem, HRESULT=%x\n"), hr));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully created CEventSystem\n")));
|
|||
|
|
|||
|
#if 0
|
|||
|
//
|
|||
|
// Test to see if we can get the MachineName
|
|||
|
//
|
|||
|
BSTR bstrMachineName;
|
|||
|
|
|||
|
hr = gpIEventQuery->get_MachineName(&bstrMachineName);
|
|||
|
|
|||
|
if (SUCCEEDED(hr))
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Configuring Test Subscriber on %s...\n"), bstrMachineName));
|
|||
|
else
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("get_MachineName failed, hr = %x\n"), hr));
|
|||
|
#endif // 0
|
|||
|
|
|||
|
//
|
|||
|
// Register my Subscriber's subscriptions with SENS.
|
|||
|
//
|
|||
|
hr = RegisterSubscriptions(bUnregister);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister SensSink Subscriptions")
|
|||
|
SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered SensSink Subscriptions.\n"),
|
|||
|
bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
|
|||
|
|
|||
|
Cleanup:
|
|||
|
//
|
|||
|
// Cleanup
|
|||
|
//
|
|||
|
if (gpIEventSystem)
|
|||
|
{
|
|||
|
gpIEventSystem->Release();
|
|||
|
}
|
|||
|
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT
|
|||
|
RegisterSubscriptions(
|
|||
|
BOOL bUnregister
|
|||
|
)
|
|||
|
{
|
|||
|
int i;
|
|||
|
int errorIndex;
|
|||
|
HRESULT hr;
|
|||
|
LPOLESTR strGuid;
|
|||
|
LPOLESTR strSubscriptionID;
|
|||
|
WCHAR szQuery[MAX_QUERY_SIZE];
|
|||
|
BSTR bstrEventClassID;
|
|||
|
BSTR bstrInterfaceID;
|
|||
|
BSTR bstrSubscriberCLSID;
|
|||
|
BSTR bstrPublisherID;
|
|||
|
BSTR bstrSubscriptionID;
|
|||
|
BSTR bstrSubscriptionName;
|
|||
|
BSTR bstrMethodName;
|
|||
|
BSTR bstrPropertyName;
|
|||
|
BSTR bstrPropertyValue;
|
|||
|
ULONG ulPropertyValue;
|
|||
|
VARIANT variantPropertyValue;
|
|||
|
BSTR bstrPROGID_EventSubscription;
|
|||
|
IEventSubscription *pIEventSubscription;
|
|||
|
|
|||
|
hr = S_OK;
|
|||
|
strGuid = NULL;
|
|||
|
errorIndex = 0;
|
|||
|
strSubscriptionID = NULL;
|
|||
|
bstrEventClassID = NULL;
|
|||
|
bstrInterfaceID = NULL;
|
|||
|
bstrSubscriberCLSID = NULL;
|
|||
|
bstrPublisherID = NULL;
|
|||
|
bstrSubscriptionID = NULL;
|
|||
|
bstrSubscriptionName = NULL;
|
|||
|
bstrMethodName = NULL;
|
|||
|
bstrPropertyName = NULL;
|
|||
|
bstrPropertyValue = NULL;
|
|||
|
ulPropertyValue = 0x0;
|
|||
|
bstrPROGID_EventSubscription = NULL;
|
|||
|
pIEventSubscription = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// Build a Subscriber
|
|||
|
//
|
|||
|
AllocateBstrFromGuid(bstrPublisherID, SENSGUID_PUBLISHER);
|
|||
|
AllocateBstrFromString(bstrPROGID_EventSubscription, PROGID_EventSubscription);
|
|||
|
|
|||
|
for (i = 0; i < TEST_SUBSCRIPTIONS_COUNT; i++)
|
|||
|
{
|
|||
|
if (bUnregister)
|
|||
|
{
|
|||
|
// Form the query
|
|||
|
wcscpy(szQuery, SENS_BSTR("SubscriptionID"));
|
|||
|
wcscat(szQuery, SENS_BSTR("="));
|
|||
|
AllocateStrFromGuid(strSubscriptionID, *(gTestSubscriptions[i].pSubscriptionID));
|
|||
|
wcscat(szQuery, strSubscriptionID);
|
|||
|
|
|||
|
hr = gpIEventSystem->Remove(
|
|||
|
PROGID_EventSubscription,
|
|||
|
szQuery,
|
|||
|
&errorIndex
|
|||
|
);
|
|||
|
FreeStr(strSubscriptionID);
|
|||
|
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("RegisterSubscriptions(%d) failed to unregister")
|
|||
|
SENS_STRING(" - hr = <%x>\n"), i, hr));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Get a new IEventSubscription object to play with.
|
|||
|
hr = CoCreateInstance(
|
|||
|
CLSID_CEventSubscription,
|
|||
|
NULL,
|
|||
|
CLSCTX_SERVER,
|
|||
|
IID_IEventSubscription,
|
|||
|
(LPVOID *) &pIEventSubscription
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("RegisterSubscriptions(%d) failed to create ")
|
|||
|
SENS_STRING("IEventSubscriptions - hr = <%x>\n"), i, hr));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
AllocateBstrFromGuid(bstrSubscriptionID, *(gTestSubscriptions[i].pSubscriptionID));
|
|||
|
hr = pIEventSubscription->put_SubscriptionID(bstrSubscriptionID);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
|
|||
|
AllocateBstrFromGuid(bstrSubscriberCLSID, *(gTestSubscriptions[i].pSubscriberCLSID));
|
|||
|
hr = pIEventSubscription->put_SubscriberCLSID(bstrSubscriberCLSID);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
|
|||
|
hr = pIEventSubscription->put_PublisherID(bstrPublisherID);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
|
|||
|
hr = pIEventSubscription->put_SubscriptionID(bstrSubscriptionID);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
|
|||
|
AllocateBstrFromString(bstrSubscriptionName, gTestSubscriptions[i].strSubscriptionName);
|
|||
|
hr = pIEventSubscription->put_SubscriptionName(bstrSubscriptionName);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
|
|||
|
AllocateBstrFromString(bstrMethodName, gTestSubscriptions[i].strMethodName);
|
|||
|
hr = pIEventSubscription->put_MethodName(bstrMethodName);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
|
|||
|
AllocateBstrFromGuid(bstrEventClassID, *(gTestSubscriptions[i].pEventClassID));
|
|||
|
hr = pIEventSubscription->put_EventClassID(bstrEventClassID);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
|
|||
|
AllocateBstrFromGuid(bstrInterfaceID, *(gTestSubscriptions[i].pInterfaceID));
|
|||
|
hr = pIEventSubscription->put_InterfaceID(bstrInterfaceID);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
|
|||
|
if (wcscmp(gTestSubscriptions[i].strMethodName, SENS_BSTR("ConnectionMadeNoQOCInfo")) == 0)
|
|||
|
{
|
|||
|
AllocateBstrFromString(bstrPropertyName, SENS_BSTR("ulConnectionMadeTypeNoQOC"));
|
|||
|
ulPropertyValue = CONNECTION_LAN;
|
|||
|
InitializeDwordVariant(&variantPropertyValue, ulPropertyValue);
|
|||
|
hr = pIEventSubscription->PutPublisherProperty(
|
|||
|
bstrPropertyName,
|
|||
|
&variantPropertyValue
|
|||
|
);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("PutPublisherProperty(WAN/LAN) returned 0x%x\n"), hr));
|
|||
|
FreeBstr(bstrPropertyName);
|
|||
|
ulPropertyValue = 0x0;
|
|||
|
}
|
|||
|
else
|
|||
|
if ( (wcscmp(gTestSubscriptions[i].strMethodName, SENS_BSTR("DestinationReachable")) == 0)
|
|||
|
|| (wcscmp(gTestSubscriptions[i].strMethodName, SENS_BSTR("DestinationReachableNoQOCInfo")) == 0))
|
|||
|
{
|
|||
|
// Set the DestinationName for which we want to be notified for.
|
|||
|
AllocateBstrFromString(bstrPropertyName, gTestSubscriptions[i].strPropertyMethodName);
|
|||
|
AllocateBstrFromString(bstrPropertyValue, gTestSubscriptions[i].strPropertyMethodNameValue);
|
|||
|
InitializeBstrVariant(&variantPropertyValue, bstrPropertyValue);
|
|||
|
hr = pIEventSubscription->PutPublisherProperty(
|
|||
|
bstrPropertyName,
|
|||
|
&variantPropertyValue
|
|||
|
);
|
|||
|
ASSERT(SUCCEEDED(hr));
|
|||
|
SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("PutPublisherProperty(DestinationName) returned 0x%x\n"), hr));
|
|||
|
FreeBstr(bstrPropertyName);
|
|||
|
FreeBstr(bstrPropertyValue);
|
|||
|
}
|
|||
|
|
|||
|
FreeBstr(bstrSubscriptionID);
|
|||
|
FreeBstr(bstrSubscriberCLSID);
|
|||
|
FreeBstr(bstrEventClassID);
|
|||
|
FreeBstr(bstrInterfaceID);
|
|||
|
FreeBstr(bstrSubscriptionName);
|
|||
|
FreeBstr(bstrMethodName);
|
|||
|
|
|||
|
hr = gpIEventSystem->Store(bstrPROGID_EventSubscription, pIEventSubscription);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("RegisterSubscriptions(%d) failed to commit")
|
|||
|
SENS_STRING(" - hr = <%x>\n"), i, hr));
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
pIEventSubscription->Release();
|
|||
|
|
|||
|
pIEventSubscription = NULL;
|
|||
|
} // for loop
|
|||
|
|
|||
|
Cleanup:
|
|||
|
//
|
|||
|
// Cleanup
|
|||
|
//
|
|||
|
if (pIEventSubscription)
|
|||
|
{
|
|||
|
pIEventSubscription->Release();
|
|||
|
}
|
|||
|
|
|||
|
FreeBstr(bstrPublisherID);
|
|||
|
FreeBstr(bstrSubscriberCLSID);
|
|||
|
FreeStr(strGuid);
|
|||
|
|
|||
|
return (hr);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT
|
|||
|
RegisterSubscriberCLSID(
|
|||
|
REFIID clsid,
|
|||
|
TCHAR* strSubscriberName,
|
|||
|
BOOL bUnregister
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Register/Unregister the CLSID of the Test subscriber.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
clsid - CLSID of the Subscriber.
|
|||
|
|
|||
|
strSubscriberName - Name of the Subscriber.
|
|||
|
|
|||
|
bUnregister - If TRUE, then unregister all subscriptions of SENS Test subscriber.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK, if successful
|
|||
|
|
|||
|
hr, otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESULT hr;
|
|||
|
HMODULE hModule;
|
|||
|
HKEY appidKey = 0;
|
|||
|
HKEY clsidKey = 0;
|
|||
|
HKEY serverKey = 0;
|
|||
|
TCHAR szModule[MAX_PATH+1];
|
|||
|
WCHAR *szCLSID = 0;
|
|||
|
WCHAR *szLIBID = 0;
|
|||
|
TCHAR *szCLSID_t = 0;
|
|||
|
TCHAR *szLIBID_t = 0;
|
|||
|
TCHAR *szFriendlyName = strSubscriberName;
|
|||
|
|
|||
|
hr = S_OK;
|
|||
|
|
|||
|
// Convert the CLSID into a TCHAR.
|
|||
|
hr = StringFromCLSID(clsid, &szCLSID);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
if (bUnregister == FALSE)
|
|||
|
{
|
|||
|
hr = StringFromCLSID(LIBID_SensEvents, &szLIBID);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
hModule = GetModuleHandle(0);
|
|||
|
|
|||
|
// Get Subscriber location.
|
|||
|
const size_t moduleBufSize = sizeof szModule / sizeof szModule[0];
|
|||
|
DWORD dwResult = GetModuleFileName(hModule, szModule, moduleBufSize);
|
|||
|
if (dwResult == 0)
|
|||
|
{
|
|||
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Convert UNICODE strings into ANSI, if necessary
|
|||
|
//
|
|||
|
#if !defined(SENS_CHICAGO)
|
|||
|
|
|||
|
szCLSID_t = szCLSID;
|
|||
|
szLIBID_t = szLIBID;
|
|||
|
|
|||
|
#else // SENS_CHICAGO
|
|||
|
|
|||
|
szCLSID_t = SensUnicodeStringToAnsi(szCLSID);
|
|||
|
szLIBID_t = SensUnicodeStringToAnsi(szLIBID);
|
|||
|
if ( (NULL == szCLSID_t)
|
|||
|
|| (NULL == szLIBID_t))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
#endif // SENS_CHICAGO
|
|||
|
|
|||
|
|
|||
|
// Build the key CLSID\\{clsid}
|
|||
|
TCHAR clsidKeyName[sizeof "CLSID\\{12345678-1234-1234-1234-123456789012}"];
|
|||
|
|
|||
|
_tcscpy(clsidKeyName, SENS_STRING("CLSID\\"));
|
|||
|
_tcscat(clsidKeyName, szCLSID_t);
|
|||
|
|
|||
|
// Build the key AppID\\{clsid}
|
|||
|
TCHAR appidKeyName[sizeof "AppID\\{12345678-1234-1234-1234-123456789012}"];
|
|||
|
_tcscpy(appidKeyName, SENS_STRING("AppID\\"));
|
|||
|
_tcscat(appidKeyName, szCLSID_t);
|
|||
|
|
|||
|
if (bUnregister)
|
|||
|
{
|
|||
|
hr = RecursiveDeleteKey(HKEY_CLASSES_ROOT, clsidKeyName);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
hr = RecursiveDeleteKey(HKEY_CLASSES_ROOT, appidKeyName);
|
|||
|
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
// Create the CLSID\\{clsid} key
|
|||
|
hr = CreateKey(
|
|||
|
HKEY_CLASSES_ROOT,
|
|||
|
clsidKeyName,
|
|||
|
szFriendlyName,
|
|||
|
&clsidKey
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Under the CLSID\\{clsid} key, create a named value
|
|||
|
// AppID = {clsid}
|
|||
|
hr = CreateNamedValue(clsidKey, SENS_STRING("AppID"), szCLSID_t);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Create the appropriate server key beneath the clsid key.
|
|||
|
// For servers, this is CLSID\\{clsid}\\LocalServer32.
|
|||
|
// In both cases, the default value is the module path name.
|
|||
|
//
|
|||
|
hr = CreateKey(
|
|||
|
clsidKey,
|
|||
|
SENS_STRING("LocalServer32"),
|
|||
|
szModule,
|
|||
|
&serverKey
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
RegCloseKey(serverKey);
|
|||
|
|
|||
|
//
|
|||
|
// Create CLSID\\{clsid}\\TypeLib subkey with a default value of
|
|||
|
// the LIBID of the TypeLib
|
|||
|
//
|
|||
|
hr = CreateKey(
|
|||
|
clsidKey,
|
|||
|
SENS_STRING("TypeLib"),
|
|||
|
szLIBID_t,
|
|||
|
&serverKey
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
RegCloseKey(serverKey);
|
|||
|
|
|||
|
|
|||
|
// We're finished with the CLSID\\{clsid} key
|
|||
|
RegCloseKey(clsidKey);
|
|||
|
|
|||
|
// Register APPID.
|
|||
|
hr = CreateKey(
|
|||
|
HKEY_CLASSES_ROOT,
|
|||
|
appidKeyName,
|
|||
|
szFriendlyName,
|
|||
|
&appidKey
|
|||
|
);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
// Under AppId\{clsid} key, create a named value [RunAs = "Interactive User"]
|
|||
|
hr = CreateNamedValue(appidKey, SENS_STRING("RunAs"), SENS_STRING("Interactive User"));
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
RegCloseKey(appidKey);
|
|||
|
|
|||
|
|
|||
|
Cleanup:
|
|||
|
//
|
|||
|
// Cleanup
|
|||
|
//
|
|||
|
CoTaskMemFree(szCLSID);
|
|||
|
CoTaskMemFree(szLIBID);
|
|||
|
|
|||
|
#if defined(SENS_CHICAGO)
|
|||
|
|
|||
|
if (szCLSID_t != NULL)
|
|||
|
{
|
|||
|
delete szCLSID_t;
|
|||
|
}
|
|||
|
if (szLIBID_t != NULL)
|
|||
|
{
|
|||
|
delete szLIBID_t;
|
|||
|
}
|
|||
|
|
|||
|
#endif // SENS_CHICAGO
|
|||
|
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT
|
|||
|
CreateKey(
|
|||
|
HKEY hParentKey,
|
|||
|
const TCHAR* KeyName,
|
|||
|
const TCHAR* defaultValue,
|
|||
|
HKEY* hKey
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Create a key (with an optional default value). The handle to the key is
|
|||
|
returned as an [out] parameter. If NULL is passed as the key parameter,
|
|||
|
the key is created in the registry, then closed.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hParentKey - Handle to the parent Key.
|
|||
|
|
|||
|
KeyName - Name of the key to create.
|
|||
|
|
|||
|
defaultValue - The default value for the key to create.
|
|||
|
|
|||
|
hKey - OUT Handle to key that was created.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK, if successful
|
|||
|
|
|||
|
hr, otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HKEY hTempKey;
|
|||
|
LONG lResult;
|
|||
|
|
|||
|
hTempKey = NULL;
|
|||
|
|
|||
|
lResult = RegCreateKeyEx(
|
|||
|
hParentKey, // Handle to open key
|
|||
|
KeyName, // Subkey name
|
|||
|
0, // Reserved
|
|||
|
NULL, // Class string
|
|||
|
REG_OPTION_NON_VOLATILE, // Options Flag
|
|||
|
KEY_ALL_ACCESS, // Desired Security access
|
|||
|
NULL, // Pointer to Security Attributes structure
|
|||
|
&hTempKey, // Handle of the opened/created key
|
|||
|
NULL // Disposition value
|
|||
|
);
|
|||
|
|
|||
|
if (lResult != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
return HRESULT_FROM_WIN32(lResult);
|
|||
|
}
|
|||
|
|
|||
|
// Set the default value for the key
|
|||
|
if (defaultValue != NULL)
|
|||
|
{
|
|||
|
lResult = RegSetValueEx(
|
|||
|
hTempKey, // Key to set Value for.
|
|||
|
NULL, // Value to set
|
|||
|
0, // Reserved
|
|||
|
REG_SZ, // Value Type
|
|||
|
(BYTE*) defaultValue, // Address of Value data
|
|||
|
sizeof(TCHAR) * (_tcslen(defaultValue)+1) // Size of Value
|
|||
|
);
|
|||
|
|
|||
|
if (lResult != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
RegCloseKey(hTempKey);
|
|||
|
return HRESULT_FROM_WIN32(lResult);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (hKey == NULL)
|
|||
|
{
|
|||
|
RegCloseKey(hTempKey);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*hKey = hTempKey;
|
|||
|
}
|
|||
|
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT
|
|||
|
CreateNamedValue(
|
|||
|
HKEY hKey,
|
|||
|
const TCHAR* title,
|
|||
|
const TCHAR* value
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Create a named value under a key
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hKey - Handle to the parent Key.
|
|||
|
|
|||
|
title - Name of the Value to create.
|
|||
|
|
|||
|
value - The data for the Value under the Key.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK, if successful
|
|||
|
|
|||
|
hr, otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESULT hr;
|
|||
|
LONG lResult;
|
|||
|
|
|||
|
hr = S_OK;
|
|||
|
|
|||
|
lResult = RegSetValueEx(
|
|||
|
hKey, // Key to set Value for.
|
|||
|
title, // Value to set
|
|||
|
0, // Reserved
|
|||
|
REG_SZ, // Value Type
|
|||
|
(BYTE*) value, // Address of Value data
|
|||
|
sizeof(TCHAR) * (_tcslen(value)+1) // Size of Value
|
|||
|
);
|
|||
|
|
|||
|
if (lResult != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
hr = HRESULT_FROM_WIN32(lResult);
|
|||
|
}
|
|||
|
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT
|
|||
|
RecursiveDeleteKey(
|
|||
|
HKEY hKeyParent,
|
|||
|
const TCHAR* lpszKeyChild
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Delete a key and all of its descendents.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hKeyParent - Handle to the parent Key.
|
|||
|
|
|||
|
lpszKeyChild - The data for the Value under the Key.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK, if successful
|
|||
|
|
|||
|
hr, otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HKEY hKeyChild;
|
|||
|
LONG lResult;
|
|||
|
|
|||
|
//
|
|||
|
// Open the child.
|
|||
|
//
|
|||
|
lResult = RegOpenKeyEx(
|
|||
|
hKeyParent, // Handle to the Parent
|
|||
|
lpszKeyChild, // Name of the child key
|
|||
|
0, // Reserved
|
|||
|
KEY_ALL_ACCESS, // Security Access Mask
|
|||
|
&hKeyChild // Handle to the opened key
|
|||
|
);
|
|||
|
|
|||
|
if (lResult != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
return HRESULT_FROM_WIN32(lResult);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate all of the decendents of this child.
|
|||
|
//
|
|||
|
FILETIME time;
|
|||
|
TCHAR szBuffer[MAX_PATH+1];
|
|||
|
const DWORD bufSize = sizeof szBuffer / sizeof szBuffer[0];
|
|||
|
DWORD dwSize = bufSize;
|
|||
|
|
|||
|
while (TRUE)
|
|||
|
{
|
|||
|
lResult = RegEnumKeyEx(
|
|||
|
hKeyChild, // Handle of the key to enumerate
|
|||
|
0, // Index of the subkey to retrieve
|
|||
|
szBuffer, // OUT Name of the subkey
|
|||
|
&dwSize, // OUT Size of the buffer for name of subkey
|
|||
|
NULL, // Reserved
|
|||
|
NULL, // OUT Class of the enumerated subkey
|
|||
|
NULL, // OUT Size of the class of the subkey
|
|||
|
&time // OUT Last time the subkey was written to
|
|||
|
);
|
|||
|
|
|||
|
if (lResult != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// Delete the decendents of this child.
|
|||
|
lResult = RecursiveDeleteKey(hKeyChild, szBuffer);
|
|||
|
if (lResult != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
// Cleanup before exiting.
|
|||
|
RegCloseKey(hKeyChild);
|
|||
|
return HRESULT_FROM_WIN32(lResult);
|
|||
|
}
|
|||
|
|
|||
|
dwSize = bufSize;
|
|||
|
} // while
|
|||
|
|
|||
|
// Close the child.
|
|||
|
RegCloseKey(hKeyChild);
|
|||
|
|
|||
|
// Delete this child.
|
|||
|
lResult = RegDeleteKey(hKeyParent, lpszKeyChild);
|
|||
|
|
|||
|
return HRESULT_FROM_WIN32(lResult);
|
|||
|
}
|