// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
#pragma once
#include <vld.h>
#include <vector>
#include <string>
#include <atlmisc.h>
#include <wininet.h>
#include <iphlpapi.h>
#include "AmHttpSocket.h"
#pragma comment(lib,"WS2_32.Lib")
#define RRP_RSSFETCH WM_USER + 10
#define RRP_FETCHCOMPLETE WM_USER + 11
#define RRP_REFRESH WM_USER + 12
#define RRP_REMOVE WM_USER + 13
#define RRP_TOOLBAR_REG WM_USER + 14
#define RRP_TOOLBAR_UNREG WM_USER + 15
#define RRP_FETCHER_PROCESS_BUSY WM_USER + 16
#define RRP_FETCHER_PROCESS_FREE WM_USER + 17
#define RRP_CLEAN WM_USER + 18
#include "ras.h"
#define RASCN_Connection 0x00000001
DWORD (WINAPI *RasNotify)(HRASCONN, HANDLE, DWORD);
using namespace std;
//Structures used in message exchange
typedef struct RssInfo {
UINT message;
string localName;
string remoteName;
FILETIME systemTime;
}RssInfo;
typedef struct TRssInfo {
UINT message;
char localName[50];//cant be more than 10 actually
char remoteName[1024];//I've heard this is the URL limit
HWND toolbarHandle;
}TRssInfo;
class CMainFrame : public CFrameWindowImpl<CMainFrame>,
public CMessageFilter,
public CIdleHandler
{
public:
DECLARE_FRAME_WND_CLASS("RRPRssFetcherWindowClass", IDR_MAINFRAME)
virtual BOOL PreTranslateMessage(MSG* pMsg) {
return CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg);
}
virtual BOOL OnIdle() {
return FALSE;
}
CMainFrame() {
retryCount = 0;
oneMinCount = 0;
::GetSystemTimeAsFileTime(&startTime);
}
~CMainFrame() {
// rssDir.~basic_string();
}
BEGIN_MSG_MAP(CMainFrame)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_COPYDATA, OnWmCopy)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_TIMER, OnTimer)
MESSAGE_HANDLER(RRP_TOOLBAR_REG,OnToolbarReg)
MESSAGE_HANDLER(RRP_TOOLBAR_UNREG,OnToolbarUnReg)
MESSAGE_HANDLER(RRP_CLEAN,OnClean)
MESSAGE_HANDLER(RRP_RSSFETCH,OnRssFetchRequest)
MESSAGE_HANDLER(RRP_REMOVE ,OnRssRemove)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
END_MSG_MAP()
// Handler prototypes (uncomment arguments if needed):
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
LRESULT OnToolbarReg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
// ::MessageBox(NULL,"Toolbar Reg","Message",MB_ICONHAND);
referenceCount++;
return 0;
}
LRESULT OnToolbarUnReg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
// ::MessageBox(NULL,"Toolbar UnReg","Message",MB_ICONHAND);
referenceCount--;
if(referenceCount <= 0)
PostMessage(WM_CLOSE);
return 0;
}
LRESULT OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
if(wParam == 2) {
if(referenceCount <= 0)
PostMessage(WM_CLOSE);
oneMinCount++;
if(oneMinCount%12 == 0) {
::PostMessage(m_toolbarHandle,RRP_FETCHER_PROCESS_FREE,0,0);
retryCount = 0;
}
return 0;
}
::GetSystemTimeAsFileTime(&startTime);
return 0;
}
LRESULT OnClean(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
int n = rssInfoVector.size();
for(int i = 0;i<n;i++) {
// if(rssInfoVector[i]) {
if(true) {
rssInfoVector[i].systemTime.dwHighDateTime = 0;
rssInfoVector[i].systemTime.dwLowDateTime = 0;
}
}
return 0;
}
UINT ConnNotification(HWND toolbarHandle) {
SECURITY_ATTRIBUTES SecAtt;
SecAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
SecAtt.lpSecurityDescriptor = NULL;
SecAtt.bInheritHandle = FALSE;
HANDLE hActive = CreateEvent(&SecAtt, TRUE, FALSE, "Connect");
HANDLE hInst = LoadLibrary("rasapi32.dll");
RasNotify = (DWORD (WINAPI *)(HRASCONN, HANDLE, DWORD)) GetProcAddress ((HMODULE) hInst, "RasConnectionNotificationA");
DWORD ret = ::RasNotify((HRASCONN)INVALID_HANDLE_VALUE, hActive, RASCN_Connection);
if(ret == 0)
WaitForSingleObject(hActive, INFINITE);
::FreeLibrary((HMODULE)hInst);
return 0;
}
//Invoked when the rss fetch request comes
LRESULT OnRssFetchRequest(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
RssInfo *obj = reinterpret_cast<RssInfo *>(lParam);
HWND toolbarHandle = reinterpret_cast<HWND>(wParam);
::PostMessage(toolbarHandle,RRP_FETCHER_PROCESS_BUSY,0,0);
char *receivedData = httpRequest.GetPage(obj->remoteName.c_str());
if(!receivedData) {
delete obj;
::PostMessage(toolbarHandle,RRP_FETCHER_PROCESS_FREE,0,0);
return 0;
}
//Checkinng if the downloaded file is the xml file
if(strstr(receivedData,"<?xml") != receivedData) {
// delete receivedData;
delete obj;
::PostMessage(toolbarHandle,RRP_FETCHER_PROCESS_FREE,0,0);
return 0;
}
if(strcmp(receivedData,"Error") == 0) {
// delete receivedData;
delete obj;
::PostMessage(toolbarHandle,RRP_FETCHER_PROCESS_FREE,0,0);
return 0;
}
//Creating the file name
string dir = getInstallationDirectory();
string myFile = dir;
myFile += "\\rss\\";
myFile += obj->localName;
FILE *fp = fopen(myFile.c_str(),"w");
fprintf(fp,"%s",receivedData);
fclose(fp);
//RRP_FETCHCOMPLETE also tells that process is free now!!
::PostMessage(toolbarHandle,RRP_FETCHCOMPLETE,0,0);
bool found = false;
int n = rssInfoVector.size();
for(int i = 0;i<n;i++) {
// if(rssInfoVector[i]) {
if(true) {
if(rssInfoVector[i].remoteName.compare(obj->remoteName)) {
found = true;
GetSystemTimeAsFileTime(&(rssInfoVector[i].systemTime));
}
}
}
if(found == false) {
RssInfo tobj;
tobj.localName = obj->localName;
tobj.remoteName = obj->remoteName;
tobj.systemTime = obj->systemTime;
GetSystemTimeAsFileTime(&(tobj.systemTime));
rssInfoVector.push_back(tobj);
}
delete obj;
return 0;
}
//Invoked when rss remove request comes
LRESULT OnRssRemove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) {
/* int n = rssInfoVector.size();
RssInfo *obj = reinterpret_cast<RssInfo*>(lParam);
for(int i=0;i<n;i++)
if(rssInfoVector[i].remoteName.compare(obj->remoteName)) {
rssInfoVector.erase(i);
break;
}*/
return 0;
}
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
init();
referenceCount = 0;
// rssInfoVector = std::vector<RssInfo*>();
SetTimer(1,1000*60*10);
SetTimer(2,5000);
// request = Request();
// register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
return 0;
}
//De-Multiplexing messages
//Need to see if the files are really present on the disk or not
LRESULT OnWmCopy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) {
COPYDATASTRUCT *cds = reinterpret_cast<COPYDATASTRUCT *>(lParam);
RssInfo *obj;
// rssInfo->toolbarHandle;
if(cds->cbData = sizeof(TRssInfo)) {
TRssInfo *rssInfo = reinterpret_cast<TRssInfo *>(cds->lpData);
int n = rssInfoVector.size();
bool loaded = false;
for(int i = 0;i<n;i++) {
// if(rssInfoVector[i]) {
if(true) {
if(rssInfoVector[i].remoteName.compare(rssInfo->remoteName) == 0) {
if(rssInfoVector[i].systemTime.dwHighDateTime > startTime.dwHighDateTime) {
loaded = true;
break;
}
else
if((rssInfoVector[i].systemTime.dwHighDateTime == startTime.dwHighDateTime) &&
(rssInfoVector[i].systemTime.dwLowDateTime > startTime.dwLowDateTime)) {
loaded = true;
break;
}
}
}
}
if(loaded) {
::PostMessage(rssInfo->toolbarHandle,RRP_FETCHCOMPLETE,0,0);
return 0;
}
switch(rssInfo->message) {
case RRP_RSSFETCH:
if(prevRomoteFilename.compare(rssInfo->remoteName) == 0)
retryCount++;
//If the retry request comes for the same file
//more than 5 times It means that Probably internet connection
//is not there,so send FREE messaged after 1 min
if(retryCount >= 5) {
m_toolbarHandle = rssInfo->toolbarHandle;
::PostMessage(rssInfo->toolbarHandle,RRP_FETCHER_PROCESS_BUSY,0,0);
return 0;
}
prevRomoteFilename = rssInfo->remoteName;
obj = getRssInfo(rssInfo->localName,rssInfo->remoteName);
PostMessage(RRP_RSSFETCH,reinterpret_cast<WPARAM>(rssInfo->toolbarHandle),(LPARAM)obj);
break;
case RRP_REMOVE:
obj = getRssInfo(rssInfo->localName,rssInfo->remoteName);
PostMessage(RRP_RSSFETCH,reinterpret_cast<WPARAM>(rssInfo->toolbarHandle),(LPARAM)obj);
break;
}
}
return 0;
}
LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) {
if(referenceCount <= 0) {
DestroyWindow();
}
return 0;
}
RssInfo * getRssInfo(char *localName,char *remoteName) {
RssInfo *rssInfo = new RssInfo();
ZeroMemory(rssInfo,sizeof(RssInfo));
rssInfo->localName = localName;
rssInfo->remoteName = remoteName;
return rssInfo;
}
string getInstallationDirectory() {
return rssDir;
}
void init() {
CRegKey currentVersionRegEntry;
TCHAR programFilesAddress[2048];
currentVersionRegEntry.Create(HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\Windows\\CurrentVersion"));
DWORD length= 2048;
if(ERROR_SUCCESS ==
currentVersionRegEntry.QueryValue(programFilesAddress, _T("ProgramFilesDir"),&length)) {
rssDir = programFilesAddress;
rssDir += _T("\\RssReader for IE");
}
else {
//C:\\Program Files is taken as default
rssDir = _T("C:\\Program Files\\RssReader for IE");
}
// rssDir = rssDirectory;
}
private:
int referenceCount;
std::vector<RssInfo> rssInfoVector;
string rssDir;
string prevRomoteFilename;
int retryCount;
ULONG oneMinCount;
HWND m_toolbarHandle ;
FILETIME CMainFrame::startTime;
//File Time is much easier to handle
CAmHttpSocket httpRequest;
};