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

460 lines
13 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>
#define DIM(x) (sizeof(x) / sizeof(x[0]))
#define INI_FILE "autosub.ini"
#define KEY_URL "URL"
#define KEY_NAME "Name"
#define KEY_AUTODIAL "AutoDial"
#define KEY_ONLYIFIDLE "OnlyIfIdle"
#define KEY_EMAILNOTIFY "EmailNotify"
#define KEY_CHANGESONLY "ChangesOnly"
#define KEY_DOWNLOADLEVELS "DownloadLevels"
#define KEY_FOLLOWLINKS "FollowLinks"
#define KEY_IMAGES "Images"
#define KEY_SOUNDANDVIDEO "SoundAndVideo"
#define KEY_CRAPLETS "Craplets"
#define KEY_MAXDOWNLOADK "MaxDownloadK"
#define KEY_SCHEDULENAME "ScheduleName"
char g_szIniFile[MAX_PATH];
BOOL g_fComInited = FALSE;
ISubscriptionMgr *g_pSubsMgr = NULL;
IChannelMgr *g_pChanMgr = NULL;
IChannelMgrPriv *g_pChanMgrPriv = NULL;
INotificationMgr *g_pNotfMgr = NULL;
HWND g_hwnd = NULL;
int g_iAutoDial = 0;
int g_iOnlyIfIdle = 1;
int g_iEmailNotify = 0;
int g_iChangesOnly = 0;
int g_iDownloadLevels = 0;
int g_iFollowLinks = 1;
int g_iImages = 1;
int g_iSoundAndVideo = 0;
int g_iCraplets = 1;
int g_iMaxDownloadK = 0;
char g_szScheduleName[MAX_PATH] = "Auto";
BOOL SetCustomSchedule(int mins, SUBSCRIPTIONINFO *psi)
{
BOOL fResult = FALSE;
IEnumScheduleGroup *pEnumScheduleGroup;
HRESULT hr;
//
// This isn't very efficient but it's simple
//
hr = g_pNotfMgr->GetEnumScheduleGroup(0, &pEnumScheduleGroup);
if (FAILED(hr))
{
printf("Couldn't enum schedule groups - hr = %08x\n", hr);
}
else
{
IScheduleGroup *pScheduleGroup = NULL;
char szSchedName[64];
WCHAR wszSchedName[64];
TASK_TRIGGER tt;
NOTIFICATIONCOOKIE cookie;
GROUPINFO gi;
BOOL fFound = FALSE;
wsprintf(szSchedName, "%d minutes", mins);
MultiByteToWideChar(CP_ACP, 0, szSchedName, -1, wszSchedName, DIM(wszSchedName));
while (!fFound && pEnumScheduleGroup->Next(1, &pScheduleGroup, NULL) == S_OK)
{
if (SUCCEEDED(pScheduleGroup->GetAttributes(&tt, NULL, &cookie, &gi, NULL, NULL)))
{
int cmp = StrCmpIW(gi.pwzGroupname, wszSchedName);
CoTaskMemFree(gi.pwzGroupname);
if (cmp == 0)
{
psi->schedule = SUBSSCHED_CUSTOM;
psi->customGroupCookie = cookie;
fResult = TRUE;
fFound = TRUE;
}
}
pScheduleGroup->Release();
pScheduleGroup = NULL;
}
pEnumScheduleGroup->Release();
if (!fFound)
{
hr = g_pNotfMgr->CreateScheduleGroup(0, &pScheduleGroup, &cookie, 0);
if (FAILED(hr))
{
printf("Couldn't create schedule group - hr = %08x\n", hr);
}
tt.cbTriggerSize = sizeof(TASK_TRIGGER);
tt.wBeginYear = 1997;
tt.wBeginMonth = 9;
tt.wBeginDay = 1;
tt.MinutesDuration = 1440; //All day
tt.MinutesInterval = mins;
tt.TriggerType = TASK_TIME_TRIGGER_DAILY;
tt.Type.Daily.DaysInterval = 1;
gi.cbSize = sizeof(GROUPINFO);
gi.pwzGroupname = wszSchedName;
if (SUCCEEDED(pScheduleGroup->SetAttributes(&tt, NULL, &cookie, &gi, 0)))
{
psi->schedule = SUBSSCHED_CUSTOM;
psi->customGroupCookie = cookie;
fResult = TRUE;
}
pScheduleGroup->Release();
}
}
return fResult;
}
void SetScheduleGroup(char *pszScheduleName, SUBSCRIPTIONINFO *psi, BOOL fIsChannel)
{
psi->schedule = SUBSSCHED_AUTO;
if (lstrcmpi(pszScheduleName, "Manual") == 0)
{
psi->schedule = SUBSSCHED_MANUAL;
}
else if (lstrcmpi(pszScheduleName, "Auto") == 0)
{
if (fIsChannel)
{
psi->fChannelFlags |= CHANNEL_AGENT_DYNAMIC_SCHEDULE;
psi->schedule = SUBSSCHED_AUTO;
}
else
{
psi->schedule = SUBSSCHED_DAILY;
}
}
else if (lstrcmpi(pszScheduleName, "Weekly") == 0)
{
psi->schedule = SUBSSCHED_WEEKLY;
}
else
{
int mins = atoi(pszScheduleName);
if (!mins || !SetCustomSchedule(mins, psi))
{
psi->schedule = SUBSSCHED_DAILY;
}
}
if (psi->schedule != SUBSSCHED_AUTO)
{
psi->pTrigger = NULL;
}
}
void CreateSubscription(char *pszSection, BOOL fIsChannel)
{
char szURL[2048];
char szName[MAX_PATH];
WCHAR wszURL[2048];
WCHAR wszName[MAX_PATH];
char szScheduleName[MAX_PATH];
HRESULT hr;
TASK_TRIGGER tt = {0};
SUBSCRIPTIONINFO si = {0};
BOOL fIsSoftware = FALSE;
SUBSCRIPTIONTYPE st;
printf("Processing [%s]...\n", pszSection);
GetPrivateProfileString(pszSection, KEY_URL, "", szURL, DIM(szURL), g_szIniFile);
if (!szURL[0])
{
printf("No URL specified in %s - moving on...\n", pszSection);
return;
}
MultiByteToWideChar(CP_ACP, 0, szURL, -1, wszURL, DIM(wszURL));
tt.cbTriggerSize = sizeof(TASK_TRIGGER);
si.pTrigger = (LPVOID)&tt;
if (fIsChannel)
{
printf("Downloading CDF %s...\n", szURL);
si.cbSize = sizeof(SUBSCRIPTIONINFO);
si.fUpdateFlags = SUBSINFO_SCHEDULE;
si.schedule = SUBSSCHED_AUTO;
hr = g_pChanMgrPriv->DownloadMinCDF(g_hwnd, wszURL, wszName,
DIM(wszName), &si, &fIsSoftware);
if (FAILED(hr))
{
printf("Error downloading %s hr = %08x - moving on...\n", szURL, hr);
return;
}
CHANNELSHORTCUTINFO csci = {0};
csci.cbSize = sizeof(CHANNELSHORTCUTINFO);
csci.pszTitle = wszName;
csci.pszURL = wszURL;
csci.bIsSoftware = fIsSoftware;
hr = g_pChanMgr->AddChannelShortcut(&csci);
if (FAILED(hr))
{
printf("Error adding channel shortcut for %s hr = %08x - moving on...\n", szURL, hr);
return;
}
st = SUBSTYPE_CHANNEL;
}
else
{
si.cbSize = sizeof(SUBSCRIPTIONINFO);
si.fUpdateFlags = SUBSINFO_SCHEDULE;
GetPrivateProfileString(pszSection, KEY_NAME, szURL, szName, DIM(szName), g_szIniFile);
MultiByteToWideChar(CP_ACP, 0, szName, -1, wszName, DIM(wszName));
st = SUBSTYPE_URL;
}
if (!GetPrivateProfileInt(pszSection, KEY_AUTODIAL, g_iAutoDial, g_szIniFile))
{
si.fTaskFlags |= TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET;
}
if (GetPrivateProfileInt(pszSection, KEY_ONLYIFIDLE, g_iOnlyIfIdle, g_szIniFile))
{
si.fTaskFlags |= TASK_FLAG_START_ONLY_IF_IDLE;
}
if (GetPrivateProfileInt(pszSection, KEY_EMAILNOTIFY, g_iEmailNotify, g_szIniFile))
{
si.bMailNotification = TRUE;
}
if (GetPrivateProfileInt(pszSection, KEY_CHANGESONLY, g_iChangesOnly, g_szIniFile))
{
si.bChangesOnly = TRUE;
}
if (!si.bChangesOnly)
{
if (fIsChannel)
{
si.fChannelFlags |= CHANNEL_AGENT_PRECACHE_ALL;
}
else
{
si.dwRecurseLevels =
GetPrivateProfileInt(pszSection, KEY_DOWNLOADLEVELS, g_iDownloadLevels, g_szIniFile);
}
}
if (GetPrivateProfileInt(pszSection, KEY_FOLLOWLINKS, g_iFollowLinks, g_szIniFile))
{
si.fWebcrawlerFlags |= WEBCRAWL_LINKS_ELSEWHERE;
}
if (GetPrivateProfileInt(pszSection, KEY_IMAGES, g_iImages, g_szIniFile))
{
si.fWebcrawlerFlags |= WEBCRAWL_GET_IMAGES;
}
if (GetPrivateProfileInt(pszSection, KEY_SOUNDANDVIDEO, g_iSoundAndVideo, g_szIniFile))
{
si.fWebcrawlerFlags |= WEBCRAWL_GET_VIDEOS | WEBCRAWL_GET_BGSOUNDS;
}
if (GetPrivateProfileInt(pszSection, KEY_CRAPLETS, g_iCraplets, g_szIniFile))
{
si.fWebcrawlerFlags |= WEBCRAWL_GET_CONTROLS;
}
si.dwMaxSizeKB =
GetPrivateProfileInt(pszSection, KEY_MAXDOWNLOADK, g_iMaxDownloadK, g_szIniFile);
GetPrivateProfileString(pszSection, KEY_SCHEDULENAME, g_szScheduleName, szScheduleName, DIM(szScheduleName), g_szIniFile);
si.fUpdateFlags = SUBSINFO_ALLFLAGS;
SetScheduleGroup(szScheduleName, &si, fIsChannel);
BOOL fIsSubscribed = FALSE;
g_pSubsMgr->IsSubscribed(wszURL, &fIsSubscribed);
if (fIsSubscribed)
{
printf("Deleting old subscription to %s...\n", szURL);
g_pSubsMgr->DeleteSubscription(wszURL, NULL);
}
printf("Subscribing to %s...\n", szURL);
hr = g_pSubsMgr->CreateSubscription(g_hwnd, wszURL, wszName,
CREATESUBS_NOUI | CREATESUBS_ADDTOFAVORITES |
(fIsSoftware ? CREATESUBS_SOFTWAREUPDATE : 0),
st, &si);
if (FAILED(hr))
{
printf("Error creating subscription to %s hr = %08x - moving on...\n", szURL, hr);
return;
}
}
void ReadDefaults(char *pszSection)
{
printf("Reading defaults from [%s]...\n", pszSection);
g_iAutoDial = GetPrivateProfileInt(pszSection, KEY_AUTODIAL, g_iAutoDial, g_szIniFile);
g_iOnlyIfIdle = GetPrivateProfileInt(pszSection, KEY_ONLYIFIDLE, g_iOnlyIfIdle, g_szIniFile);
g_iEmailNotify = GetPrivateProfileInt(pszSection, KEY_EMAILNOTIFY, g_iEmailNotify, g_szIniFile);
g_iChangesOnly = GetPrivateProfileInt(pszSection, KEY_CHANGESONLY, g_iChangesOnly, g_szIniFile);
g_iDownloadLevels = GetPrivateProfileInt(pszSection, KEY_DOWNLOADLEVELS, g_iDownloadLevels, g_szIniFile);
g_iFollowLinks = GetPrivateProfileInt(pszSection, KEY_FOLLOWLINKS, g_iFollowLinks, g_szIniFile);
g_iImages = GetPrivateProfileInt(pszSection, KEY_IMAGES, g_iImages, g_szIniFile);
g_iSoundAndVideo = GetPrivateProfileInt(pszSection, KEY_SOUNDANDVIDEO, g_iSoundAndVideo, g_szIniFile);
g_iCraplets = GetPrivateProfileInt(pszSection, KEY_CRAPLETS, g_iCraplets, g_szIniFile);
g_iMaxDownloadK = GetPrivateProfileInt(pszSection, KEY_MAXDOWNLOADK, g_iMaxDownloadK, g_szIniFile);
GetPrivateProfileString(pszSection, KEY_SCHEDULENAME, "Auto", g_szScheduleName, DIM(g_szScheduleName), g_szIniFile);
}
void CleanUp()
{
if (g_pSubsMgr)
{
g_pSubsMgr->Release();
g_pSubsMgr = NULL;
}
if (g_pChanMgrPriv)
{
g_pChanMgrPriv->Release();
g_pChanMgrPriv = NULL;
}
if (g_pChanMgr)
{
g_pChanMgr->Release();
g_pChanMgr = NULL;
}
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);
}
int _cdecl main(int argc, char **argv)
{
char szSections[8192];
char *pszSection;
if (argc < 2)
{
ErrorExit("Need a file name!\nExample:\nautosub \\\\ohserv\\users\\tnoonan\\autosub.ini\n");
}
lstrcpy(g_szIniFile, argv[1]);
printf("Reading %s...\n", g_szIniFile);
if (!GetPrivateProfileSectionNames(szSections, DIM(szSections), g_szIniFile))
{
ErrorExit("No sections found in %s\n", g_szIniFile);
}
printf("Initializing COM...\n");
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
ErrorExit("CoInitialize failed with hr = %08x\n", hr);
}
g_fComInited = TRUE;
printf("Creating Channel Manager...\n");
hr = CoCreateInstance(CLSID_ChannelMgr, NULL, CLSCTX_INPROC_SERVER, IID_IChannelMgr,
(void **)&g_pChanMgr);
if (FAILED(hr))
{
ErrorExit("CoCreate failed on channel manager with hr = %08x\n", hr);
}
hr = g_pChanMgr->QueryInterface(IID_IChannelMgrPriv, (void **)&g_pChanMgrPriv);
if (FAILED(hr))
{
ErrorExit("QI failed for IID_IChannelMgrPriv with hr = %08x\n", hr);
}
printf("Creating Subscription Manager...\n");
hr = CoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr,
(void **)&g_pSubsMgr);
if (FAILED(hr))
{
ErrorExit("CoCreate failed on channel manager 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_hwnd = GetDesktopWindow();
pszSection = szSections;
ReadDefaults("Defaults");
while (pszSection && *pszSection)
{
BOOL fIsChannel = FALSE;
switch (toupper(*pszSection))
{
case 'C':
fIsChannel = TRUE;
// Fall through
case 'U':
CreateSubscription(pszSection, fIsChannel);
break;
default:
if (lstrcmpi(pszSection, "Defaults") != 0)
{
printf("Skipping [%s]\n", pszSection);
}
break;
}
pszSection += strlen(pszSection) + 1;
}
CleanUp();
return 0;
}