Windows2003-3790/inetcore/wininet/dll/event.cxx
2020-09-30 16:53:55 +02:00

148 lines
3.7 KiB
C++

//
// event.cxx - simple eventing mechanism for ras/offline/logon events
//
#include "wininetp.h"
#include <docobj.h>
//
// Globals
//
static const TCHAR szEventKey[] = REGSTR_PATH_INETEVENTS;
CLSID clsidEventGroup = { /* ab8ed004-b86a-11d1-b1f8-00c04fa357fa */
0xab8ed004,
0xb86a,
0x11d1,
{0xb1, 0xf8, 0x00, 0xc0, 0x4f, 0xa3, 0x57, 0xfa}
};
//
// remember events so we don't repeat them
//
static DWORD g_dwOffline = 0;
//
// SendEvent - deliver an event to a single client
//
BOOL SendEvent(DWORD dwEvent, VARIANTARG *pva, LPTSTR pszValue)
{
CLSID clsid;
IOleCommandTarget *poct;
HRESULT hr = E_FAIL;
#ifdef UNICODE
if(FAILED(CLSIDFromString(pszValue, &clsid)))
return FALSE;
#else
WCHAR wszCLSID[80];
MultiByteToWideChar(CP_ACP, 0, pszValue, -1, wszCLSID, sizeof(wszCLSID) / sizeof(WCHAR));
if(FAILED(CLSIDFromString(wszCLSID, &clsid)))
return FALSE;
#endif
hr = (CoCreateInstance(clsid, NULL, CLSCTX_ALL,
IID_IOleCommandTarget, (void **)&poct));
if(SUCCEEDED(hr))
{
// ensure client likes our group
hr = poct->Exec(&clsidEventGroup, dwEvent, 0, pva, NULL);
poct->Release();
}
return SUCCEEDED(hr);
}
//
// EnumClients - send all events to clients in a reg key
//
DWORD EnumClients(HKEY hkey, DWORD dwEvent, LPWSTR pwsEventDesc, DWORD dwEventData)
{
DWORD cbData, cbValue, dwType, i, dwMask;
TCHAR szValueName[80];
VARIANTARG va;
va.vt = VT_EMPTY;
//
// Enumerate everyone
//
for (i = 0; ; i++)
{
LONG lEnum;
cbValue = sizeof(szValueName) / sizeof(TCHAR);
cbData = sizeof(DWORD);
// BUGBUG (Unicode, Davepl) I'm assuming that the data is UNICODE,
// but I'm not sure who put it there yet... double check.
if( ( lEnum = RegEnumValue( hkey, i, szValueName, &cbValue, NULL,
&dwType, (LPBYTE)&dwMask, &cbData ) ) == ERROR_MORE_DATA )
{
// ERROR_MORE_DATA means the value name or data was too large
// skip to the next item
continue;
}
else if( lEnum != ERROR_SUCCESS )
{
// could be ERROR_NO_MORE_ENTRIES, or some kind of failure
// we can't recover from any other registry problem, anyway
break;
}
if(0 != (dwMask & dwEvent)) {
// this guy wants this event
SendEvent(dwEvent, &va, szValueName);
}
}
return 0;
}
//
// DispatchEvent - enumerate all clients and deliver the event to them
//
DWORD InternetDispatchEvent(DWORD dwEvent, LPWSTR pwsEventDesc, DWORD dwEventData)
{
HKEY hkey;
// get rid of repeated events here
switch(dwEvent) {
case INETEVT_OFFLINE:
if(g_dwOffline == dwEvent)
return 0;
g_dwOffline = dwEvent;
break;
case INETEVT_ONLINE:
if(g_dwOffline == dwEvent)
return 0;
g_dwOffline = dwEvent;
break;
default:
return ERROR_INVALID_PARAMETER;
}
// fire up com
if(SUCCEEDED(CoInitialize(NULL))) {
if (REGOPENKEY(HKEY_CURRENT_USER, szEventKey, &hkey) == ERROR_SUCCESS) {
EnumClients(hkey, dwEvent, pwsEventDesc, dwEventData);
REGCLOSEKEY(hkey);
}
if (REGOPENKEY(HKEY_LOCAL_MACHINE, szEventKey, &hkey) == ERROR_SUCCESS) {
EnumClients(hkey, dwEvent, pwsEventDesc, dwEventData);
REGCLOSEKEY(hkey);
}
CoUninitialize();
}
return 0;
}