windows-nt/Source/XPSP1/NT/shell/ext/webcheck/test/upnow/upnow.cpp
2020-09-26 16:20:57 +08:00

250 lines
5.7 KiB
C++

#include <windows.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <shguidp.h>
#include <msnotify.h>
#include <subsmgr.h>
#include <chanmgr.h>
#include <chanmgrp.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <wininet.h>
#include <winineti.h>
#define DIM(x) (sizeof(x) / sizeof(x[0]))
#define DEFAULT_INTERVAL 15
#define GUIDSTR_MAX (1+ 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1)
EXTERN_C const CLSID CLSID_OfflineTrayAgent;
BOOL g_fComInited = FALSE;
INotificationMgr *g_pNotfMgr = NULL;
int g_Interval = DEFAULT_INTERVAL;
char g_szCachePath[MAX_PATH] = "";
void CleanUp()
{
if (g_pNotfMgr)
{
g_pNotfMgr->Release();
g_pNotfMgr = NULL;
}
if (g_fComInited)
{
CoUninitialize();
}
}
void ErrorExit(char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vprintf(fmt, va);
CleanUp();
exit(1);
}
void UpdateNow()
{
HRESULT hr;
INotification *pNotification;
IEnumNotification *pEnumNotification;
ULONG count;
NOTIFICATIONITEM items[1024];
if (g_szCachePath[0])
{
printf("Emptying cache from %s...\n", g_szCachePath);
FreeUrlCacheSpace(g_szCachePath, 100, 0 /*remove all*/);
}
printf("Updating all subscriptions...\n");
hr = g_pNotfMgr->GetEnumNotification(0/*grfFlags*/, &pEnumNotification);
if (FAILED(hr))
{
ErrorExit("Failed to get notification enumerator - hr = %08x\n", hr);
}
hr = pEnumNotification->Next(DIM(items), items, &count);
if (FAILED(hr))
{
ErrorExit("Failed to enumerate notifications - hr = %08x\n", hr);
}
if (!count)
{
printf("There are no subscriptions to update!\n");
return;
}
printf("There are %ld subscriptions to update...\n", count);
BSTR bstrGuids = SysAllocStringLen(NULL, GUIDSTR_MAX * count);
if (!bstrGuids)
{
ErrorExit("Error allocating bstrGuids\n");
}
bstrGuids[0] = L'\0';
for (ULONG i = 0; i < count; i++)
{
WCHAR wszCookie[GUIDSTR_MAX];
int l = StringFromGUID2(items[i].NotificationCookie, wszCookie, DIM(wszCookie));
assert(l == GUIDSTR_MAX);
StrCatW(bstrGuids, wszCookie);
if (items[i].pNotification)
{
items[i].pNotification->Release();
}
}
hr = g_pNotfMgr->CreateNotification(NOTIFICATIONTYPE_AGENT_START,
0,
NULL,
&pNotification,
0);
if (FAILED(hr))
{
ErrorExit("Failed to create notification - hr = %08x\n", hr);
}
VARIANT Val;
Val.vt = VT_BSTR;
Val.bstrVal = bstrGuids;
hr = pNotification->Write(L"Guids Array", Val, 0);
SysFreeString(bstrGuids);
if (FAILED(hr))
{
ErrorExit("Failed to write Guids Array property - hr = %08x\n", hr);
}
hr = g_pNotfMgr->DeliverNotification(pNotification, CLSID_OfflineTrayAgent,
0, NULL, NULL, 0);
pNotification->Release();
if (FAILED(hr))
{
ErrorExit("Failed to deliver notification - hr = %08x\n", hr);
}
}
void Wait()
{
#define HASH_AT 5000
DWORD dwNow = GetTickCount();
DWORD dwNextHash = dwNow + HASH_AT;
DWORD dwNextMin = dwNow + 1000 * 60;
DWORD dwStopTick = dwNow + (g_Interval * 1000 * 60);
int minToGo = g_Interval;
printf("Waiting %d minutes.", g_Interval);
do
{
// Not exactly fool proof accuracy but it will do
if (dwNow > dwNextHash)
{
printf(".");
dwNextHash += HASH_AT;
}
if (dwNow > dwNextMin)
{
printf("\n%d minutes to go.", --minToGo);
dwNextMin += 1000 * 60;
}
Sleep(1000);
dwNow = GetTickCount();
}
while (dwStopTick > dwNow);
printf("\n");
}
int _cdecl main(int argc, char **argv)
{
if (argc > 1)
{
int interval = atoi(argv[1]);
if (interval)
{
g_Interval = interval;
printf("Interval is set to %d minutes\n", g_Interval);
}
else
{
printf("Invalid interval specified on command line - must be integer > 0\n");
printf("Using default of %d minutes\n", g_Interval);
}
}
else
{
printf("No interval specified on command line\n");
printf("Using default of %d minutes\n", g_Interval);
}
printf("Initializing COM...\n");
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
ErrorExit("CoInitialize failed with hr = %08x\n", hr);
}
printf("Creating Notification Manager...\n");
hr = CoCreateInstance(CLSID_StdNotificationMgr, NULL, CLSCTX_INPROC_SERVER, IID_INotificationMgr, (void**)&g_pNotfMgr);
if (FAILED(hr))
{
ErrorExit("CoCreate failed on notification manager with hr = %08x\n", hr);
}
g_fComInited = TRUE;
HKEY hkey;
LONG l = RegOpenKeyEx(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
0,
KEY_READ,
&hkey);
if (l == ERROR_SUCCESS)
{
DWORD dwSize = DIM(g_szCachePath);
if (RegQueryValueEx(hkey, "Cache", NULL, NULL, (LPBYTE)g_szCachePath, &dwSize) != ERROR_SUCCESS)
{
printf("Uh-oh - couldn't get cache path...\n");
}
RegCloseKey(hkey);
}
while (1)
{
UpdateNow();
Wait();
}
CleanUp();
return 0;
}