[WebParser]

- Added new option for decoding Character references.

DecodeCharacterReference
Set to 0 : Does nothing. (default)
Set to 1 : Decodes both numeric character references and character entity references.
Set to 2 : Decodes only numeric character references.
Set to 3 : Decodes only character entity references.

- Replaced CreateThread() to _beginthreadex() to fix minor memory leak.
- Fixed the issue that UpdateRate is set to 0 if UpdateRate= is set.
This commit is contained in:
spx 2010-08-31 19:49:47 +00:00
parent c14cd5491b
commit e29b2a2d4b

View File

@ -29,6 +29,7 @@
#include <vector>
#include <Wininet.h>
#include <shlwapi.h>
#include <process.h>
#include "pcre-8.10/pcre.h"
#include "..\..\Library\Export.h" // Rainmeter's exported functions
@ -53,6 +54,7 @@ struct UrlData
int codepage;
int stringIndex;
int stringIndex2;
int decodeCharacterReference;
UINT updateRate;
UINT updateCounter;
std::wstring section;
@ -70,8 +72,8 @@ struct UrlData
BYTE* DownloadUrl(std::wstring& url, DWORD* dwSize, bool forceReload);
void ShowError(int lineNumber, WCHAR* errorMsg = NULL);
DWORD WINAPI NetworkThreadProc(LPVOID pParam);
DWORD WINAPI NetworkDownloadThreadProc(LPVOID pParam);
unsigned __stdcall NetworkThreadProc(void* pParam);
unsigned __stdcall NetworkDownloadThreadProc(void* pParam);
void Log(const WCHAR* string);
void ParseData(UrlData* urlData, LPCSTR parseData);
@ -82,6 +84,8 @@ static std::map<UINT, UrlData*> g_UrlData;
static bool g_Debug = false;
static HINTERNET hRootHandle = NULL;
static std::map<std::wstring, WCHAR> g_CERs;
#define OVECCOUNT 300 // should be a multiple of 3
std::wstring ConvertToWide(LPCSTR str, int codepage)
@ -159,6 +163,366 @@ std::string ConvertAsciiToUTF8(LPCSTR str, int codepage)
return szUTF8;
}
std::wstring& DecodeReferences(std::wstring& str, int opt)
{
// (opt <= 0 || opt > 3) : Do nothing.
// (opt == 1) : Decode both numeric character references and character entity references.
// (opt == 2) : Decode only numeric character references.
// (opt == 3) : Decode only character entity references.
if (opt >= 1 && opt <= 3)
{
std::wstring::size_type start = 0;
while ((start = str.find(L'&', start)) != std::wstring::npos)
{
std::wstring::size_type end, pos;
if ((end = str.find(L';', start)) == std::wstring::npos) break;
pos = start + 1;
if (pos == end) // &; - skip
{
start = end + 1;
continue;
}
else if ((end - pos) > 10) // name (or number) is too long
{
++start;
continue;
}
if (str[pos] == L'#') // Numeric character reference
{
if (opt == 3 || // Decode only character entity references,
++pos == end) // &#; - skip
{
start = end + 1;
continue;
}
int base;
if (str[pos] == L'x' || str[pos] == L'X')
{
if (++pos == end) // &#x; or &#X; - skip
{
start = end + 1;
continue;
}
base = 16;
}
else
{
base = 10;
}
std::wstring num(str, pos, end - pos);
WCHAR* pch = NULL;
errno = 0;
long ch = wcstol(num.c_str(), &pch, base);
if (pch == NULL || *pch != L'\0' || errno == ERANGE || ch <= 0 || ch >= 0xFFFE) // invalid character
{
start = pos;
continue;
}
str.replace(start, end - start + 1, 1, (WCHAR)ch);
++start;
}
else // Character entity reference
{
if (opt == 2) // Decode only numeric character references - skip
{
start = end + 1;
continue;
}
std::wstring name(str, pos, end - pos);
std::map<std::wstring, WCHAR>::const_iterator iter = g_CERs.find(name);
if (iter != g_CERs.end())
{
str.replace(start, end - start + 1, 1, (*iter).second);
}
++start;
}
}
}
return str;
}
void FillCharacterEntityReferences()
{
// List from: http://www.w3.org/TR/html4/sgml/entities.html
// for markup-significant and internationalization characters
g_CERs[L"quot"] = (WCHAR)34;
g_CERs[L"amp"] = (WCHAR)38;
g_CERs[L"lt"] = (WCHAR)60;
g_CERs[L"gt"] = (WCHAR)62;
g_CERs[L"OElig"] = (WCHAR)338;
g_CERs[L"oelig"] = (WCHAR)339;
g_CERs[L"Scaron"] = (WCHAR)352;
g_CERs[L"scaron"] = (WCHAR)353;
g_CERs[L"Yuml"] = (WCHAR)376;
g_CERs[L"circ"] = (WCHAR)710;
g_CERs[L"tilde"] = (WCHAR)732;
g_CERs[L"ensp"] = (WCHAR)8194;
g_CERs[L"emsp"] = (WCHAR)8195;
g_CERs[L"thinsp"] = (WCHAR)8201;
g_CERs[L"zwnj"] = (WCHAR)8204;
g_CERs[L"zwj"] = (WCHAR)8205;
g_CERs[L"lrm"] = (WCHAR)8206;
g_CERs[L"rlm"] = (WCHAR)8207;
g_CERs[L"ndash"] = (WCHAR)8211;
g_CERs[L"mdash"] = (WCHAR)8212;
g_CERs[L"lsquo"] = (WCHAR)8216;
g_CERs[L"rsquo"] = (WCHAR)8217;
g_CERs[L"sbquo"] = (WCHAR)8218;
g_CERs[L"ldquo"] = (WCHAR)8220;
g_CERs[L"rdquo"] = (WCHAR)8221;
g_CERs[L"bdquo"] = (WCHAR)8222;
g_CERs[L"dagger"] = (WCHAR)8224;
g_CERs[L"Dagger"] = (WCHAR)8225;
g_CERs[L"permil"] = (WCHAR)8240;
g_CERs[L"lsaquo"] = (WCHAR)8249;
g_CERs[L"rsaquo"] = (WCHAR)8250;
g_CERs[L"euro"] = (WCHAR)8364;
// for ISO 8859-1 characters
g_CERs[L"nbsp"] = (WCHAR)160;
g_CERs[L"iexcl"] = (WCHAR)161;
g_CERs[L"cent"] = (WCHAR)162;
g_CERs[L"pound"] = (WCHAR)163;
g_CERs[L"curren"] = (WCHAR)164;
g_CERs[L"yen"] = (WCHAR)165;
g_CERs[L"brvbar"] = (WCHAR)166;
g_CERs[L"sect"] = (WCHAR)167;
g_CERs[L"uml"] = (WCHAR)168;
g_CERs[L"copy"] = (WCHAR)169;
g_CERs[L"ordf"] = (WCHAR)170;
g_CERs[L"laquo"] = (WCHAR)171;
g_CERs[L"not"] = (WCHAR)172;
g_CERs[L"shy"] = (WCHAR)173;
g_CERs[L"reg"] = (WCHAR)174;
g_CERs[L"macr"] = (WCHAR)175;
g_CERs[L"deg"] = (WCHAR)176;
g_CERs[L"plusmn"] = (WCHAR)177;
g_CERs[L"sup2"] = (WCHAR)178;
g_CERs[L"sup3"] = (WCHAR)179;
g_CERs[L"acute"] = (WCHAR)180;
g_CERs[L"micro"] = (WCHAR)181;
g_CERs[L"para"] = (WCHAR)182;
g_CERs[L"middot"] = (WCHAR)183;
g_CERs[L"cedil"] = (WCHAR)184;
g_CERs[L"sup1"] = (WCHAR)185;
g_CERs[L"ordm"] = (WCHAR)186;
g_CERs[L"raquo"] = (WCHAR)187;
g_CERs[L"frac14"] = (WCHAR)188;
g_CERs[L"frac12"] = (WCHAR)189;
g_CERs[L"frac34"] = (WCHAR)190;
g_CERs[L"iquest"] = (WCHAR)191;
g_CERs[L"Agrave"] = (WCHAR)192;
g_CERs[L"Aacute"] = (WCHAR)193;
g_CERs[L"Acirc"] = (WCHAR)194;
g_CERs[L"Atilde"] = (WCHAR)195;
g_CERs[L"Auml"] = (WCHAR)196;
g_CERs[L"Aring"] = (WCHAR)197;
g_CERs[L"AElig"] = (WCHAR)198;
g_CERs[L"Ccedil"] = (WCHAR)199;
g_CERs[L"Egrave"] = (WCHAR)200;
g_CERs[L"Eacute"] = (WCHAR)201;
g_CERs[L"Ecirc"] = (WCHAR)202;
g_CERs[L"Euml"] = (WCHAR)203;
g_CERs[L"Igrave"] = (WCHAR)204;
g_CERs[L"Iacute"] = (WCHAR)205;
g_CERs[L"Icirc"] = (WCHAR)206;
g_CERs[L"Iuml"] = (WCHAR)207;
g_CERs[L"ETH"] = (WCHAR)208;
g_CERs[L"Ntilde"] = (WCHAR)209;
g_CERs[L"Ograve"] = (WCHAR)210;
g_CERs[L"Oacute"] = (WCHAR)211;
g_CERs[L"Ocirc"] = (WCHAR)212;
g_CERs[L"Otilde"] = (WCHAR)213;
g_CERs[L"Ouml"] = (WCHAR)214;
g_CERs[L"times"] = (WCHAR)215;
g_CERs[L"Oslash"] = (WCHAR)216;
g_CERs[L"Ugrave"] = (WCHAR)217;
g_CERs[L"Uacute"] = (WCHAR)218;
g_CERs[L"Ucirc"] = (WCHAR)219;
g_CERs[L"Uuml"] = (WCHAR)220;
g_CERs[L"Yacute"] = (WCHAR)221;
g_CERs[L"THORN"] = (WCHAR)222;
g_CERs[L"szlig"] = (WCHAR)223;
g_CERs[L"agrave"] = (WCHAR)224;
g_CERs[L"aacute"] = (WCHAR)225;
g_CERs[L"acirc"] = (WCHAR)226;
g_CERs[L"atilde"] = (WCHAR)227;
g_CERs[L"auml"] = (WCHAR)228;
g_CERs[L"aring"] = (WCHAR)229;
g_CERs[L"aelig"] = (WCHAR)230;
g_CERs[L"ccedil"] = (WCHAR)231;
g_CERs[L"egrave"] = (WCHAR)232;
g_CERs[L"eacute"] = (WCHAR)233;
g_CERs[L"ecirc"] = (WCHAR)234;
g_CERs[L"euml"] = (WCHAR)235;
g_CERs[L"igrave"] = (WCHAR)236;
g_CERs[L"iacute"] = (WCHAR)237;
g_CERs[L"icirc"] = (WCHAR)238;
g_CERs[L"iuml"] = (WCHAR)239;
g_CERs[L"eth"] = (WCHAR)240;
g_CERs[L"ntilde"] = (WCHAR)241;
g_CERs[L"ograve"] = (WCHAR)242;
g_CERs[L"oacute"] = (WCHAR)243;
g_CERs[L"ocirc"] = (WCHAR)244;
g_CERs[L"otilde"] = (WCHAR)245;
g_CERs[L"ouml"] = (WCHAR)246;
g_CERs[L"divide"] = (WCHAR)247;
g_CERs[L"oslash"] = (WCHAR)248;
g_CERs[L"ugrave"] = (WCHAR)249;
g_CERs[L"uacute"] = (WCHAR)250;
g_CERs[L"ucirc"] = (WCHAR)251;
g_CERs[L"uuml"] = (WCHAR)252;
g_CERs[L"yacute"] = (WCHAR)253;
g_CERs[L"thorn"] = (WCHAR)254;
g_CERs[L"yuml"] = (WCHAR)255;
// for symbols, mathematical symbols, and Greek letters
g_CERs[L"fnof"] = (WCHAR)402;
g_CERs[L"Alpha"] = (WCHAR)913;
g_CERs[L"Beta"] = (WCHAR)914;
g_CERs[L"Gamma"] = (WCHAR)915;
g_CERs[L"Delta"] = (WCHAR)916;
g_CERs[L"Epsilon"] = (WCHAR)917;
g_CERs[L"Zeta"] = (WCHAR)918;
g_CERs[L"Eta"] = (WCHAR)919;
g_CERs[L"Theta"] = (WCHAR)920;
g_CERs[L"Iota"] = (WCHAR)921;
g_CERs[L"Kappa"] = (WCHAR)922;
g_CERs[L"Lambda"] = (WCHAR)923;
g_CERs[L"Mu"] = (WCHAR)924;
g_CERs[L"Nu"] = (WCHAR)925;
g_CERs[L"Xi"] = (WCHAR)926;
g_CERs[L"Omicron"] = (WCHAR)927;
g_CERs[L"Pi"] = (WCHAR)928;
g_CERs[L"Rho"] = (WCHAR)929;
g_CERs[L"Sigma"] = (WCHAR)931;
g_CERs[L"Tau"] = (WCHAR)932;
g_CERs[L"Upsilon"] = (WCHAR)933;
g_CERs[L"Phi"] = (WCHAR)934;
g_CERs[L"Chi"] = (WCHAR)935;
g_CERs[L"Psi"] = (WCHAR)936;
g_CERs[L"Omega"] = (WCHAR)937;
g_CERs[L"alpha"] = (WCHAR)945;
g_CERs[L"beta"] = (WCHAR)946;
g_CERs[L"gamma"] = (WCHAR)947;
g_CERs[L"delta"] = (WCHAR)948;
g_CERs[L"epsilon"] = (WCHAR)949;
g_CERs[L"zeta"] = (WCHAR)950;
g_CERs[L"eta"] = (WCHAR)951;
g_CERs[L"theta"] = (WCHAR)952;
g_CERs[L"iota"] = (WCHAR)953;
g_CERs[L"kappa"] = (WCHAR)954;
g_CERs[L"lambda"] = (WCHAR)955;
g_CERs[L"mu"] = (WCHAR)956;
g_CERs[L"nu"] = (WCHAR)957;
g_CERs[L"xi"] = (WCHAR)958;
g_CERs[L"omicron"] = (WCHAR)959;
g_CERs[L"pi"] = (WCHAR)960;
g_CERs[L"rho"] = (WCHAR)961;
g_CERs[L"sigmaf"] = (WCHAR)962;
g_CERs[L"sigma"] = (WCHAR)963;
g_CERs[L"tau"] = (WCHAR)964;
g_CERs[L"upsilon"] = (WCHAR)965;
g_CERs[L"phi"] = (WCHAR)966;
g_CERs[L"chi"] = (WCHAR)967;
g_CERs[L"psi"] = (WCHAR)968;
g_CERs[L"omega"] = (WCHAR)969;
g_CERs[L"thetasym"] = (WCHAR)977;
g_CERs[L"upsih"] = (WCHAR)978;
g_CERs[L"piv"] = (WCHAR)982;
g_CERs[L"bull"] = (WCHAR)8226;
g_CERs[L"hellip"] = (WCHAR)8230;
g_CERs[L"prime"] = (WCHAR)8242;
g_CERs[L"Prime"] = (WCHAR)8243;
g_CERs[L"oline"] = (WCHAR)8254;
g_CERs[L"frasl"] = (WCHAR)8260;
g_CERs[L"weierp"] = (WCHAR)8472;
g_CERs[L"image"] = (WCHAR)8465;
g_CERs[L"real"] = (WCHAR)8476;
g_CERs[L"trade"] = (WCHAR)8482;
g_CERs[L"alefsym"] = (WCHAR)8501;
g_CERs[L"larr"] = (WCHAR)8592;
g_CERs[L"uarr"] = (WCHAR)8593;
g_CERs[L"rarr"] = (WCHAR)8594;
g_CERs[L"darr"] = (WCHAR)8595;
g_CERs[L"harr"] = (WCHAR)8596;
g_CERs[L"crarr"] = (WCHAR)8629;
g_CERs[L"lArr"] = (WCHAR)8656;
g_CERs[L"uArr"] = (WCHAR)8657;
g_CERs[L"rArr"] = (WCHAR)8658;
g_CERs[L"dArr"] = (WCHAR)8659;
g_CERs[L"hArr"] = (WCHAR)8660;
g_CERs[L"forall"] = (WCHAR)8704;
g_CERs[L"part"] = (WCHAR)8706;
g_CERs[L"exist"] = (WCHAR)8707;
g_CERs[L"empty"] = (WCHAR)8709;
g_CERs[L"nabla"] = (WCHAR)8711;
g_CERs[L"isin"] = (WCHAR)8712;
g_CERs[L"notin"] = (WCHAR)8713;
g_CERs[L"ni"] = (WCHAR)8715;
g_CERs[L"prod"] = (WCHAR)8719;
g_CERs[L"sum"] = (WCHAR)8721;
g_CERs[L"minus"] = (WCHAR)8722;
g_CERs[L"lowast"] = (WCHAR)8727;
g_CERs[L"radic"] = (WCHAR)8730;
g_CERs[L"prop"] = (WCHAR)8733;
g_CERs[L"infin"] = (WCHAR)8734;
g_CERs[L"ang"] = (WCHAR)8736;
g_CERs[L"and"] = (WCHAR)8743;
g_CERs[L"or"] = (WCHAR)8744;
g_CERs[L"cap"] = (WCHAR)8745;
g_CERs[L"cup"] = (WCHAR)8746;
g_CERs[L"int"] = (WCHAR)8747;
g_CERs[L"there4"] = (WCHAR)8756;
g_CERs[L"sim"] = (WCHAR)8764;
g_CERs[L"cong"] = (WCHAR)8773;
g_CERs[L"asymp"] = (WCHAR)8776;
g_CERs[L"ne"] = (WCHAR)8800;
g_CERs[L"equiv"] = (WCHAR)8801;
g_CERs[L"le"] = (WCHAR)8804;
g_CERs[L"ge"] = (WCHAR)8805;
g_CERs[L"sub"] = (WCHAR)8834;
g_CERs[L"sup"] = (WCHAR)8835;
g_CERs[L"nsub"] = (WCHAR)8836;
g_CERs[L"sube"] = (WCHAR)8838;
g_CERs[L"supe"] = (WCHAR)8839;
g_CERs[L"oplus"] = (WCHAR)8853;
g_CERs[L"otimes"] = (WCHAR)8855;
g_CERs[L"perp"] = (WCHAR)8869;
g_CERs[L"sdot"] = (WCHAR)8901;
g_CERs[L"lceil"] = (WCHAR)8968;
g_CERs[L"rceil"] = (WCHAR)8969;
g_CERs[L"lfloor"] = (WCHAR)8970;
g_CERs[L"rfloor"] = (WCHAR)8971;
g_CERs[L"lang"] = (WCHAR)9001;
g_CERs[L"rang"] = (WCHAR)9002;
g_CERs[L"loz"] = (WCHAR)9674;
g_CERs[L"spades"] = (WCHAR)9824;
g_CERs[L"clubs"] = (WCHAR)9827;
g_CERs[L"hearts"] = (WCHAR)9829;
g_CERs[L"diams"] = (WCHAR)9830;
// for DEBUG
//std::map<std::wstring, WCHAR>::const_iterator iter = g_CERs.begin();
//for ( ; iter != g_CERs.end(); ++iter)
//{
// WCHAR buffer[64];
// wsprintf(buffer, L"%s - %c", (*iter).first.c_str(), (*iter).second);
// Log(buffer);
//}
}
bool BelongToSameProcess(HWND wnd)
{
DWORD procId = 0;
@ -216,11 +580,13 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
if (!g_Initialized)
{
InitializeCriticalSection(&g_CriticalSection);
FillCharacterEntityReferences();
g_Initialized = true;
}
UrlData* data = new UrlData;
data->section = section;
data->decodeCharacterReference = 0;
data->updateRate = 600;
data->updateCounter = 0;
data->iniFile = iniFile;
@ -255,8 +621,14 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
data->stringIndex2 = _wtoi(tmpSz);
}
tmpSz = ReadConfigString(section, L"UpdateRate", L"600");
tmpSz = ReadConfigString(section, L"DecodeCharacterReference", L"0");
if (tmpSz)
{
data->decodeCharacterReference = _wtoi(tmpSz);
}
tmpSz = ReadConfigString(section, L"UpdateRate", L"600");
if (tmpSz && *tmpSz)
{
data->updateRate = _wtoi(tmpSz);
}
@ -307,7 +679,8 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
if (hRootHandle == NULL)
{
ShowError(__LINE__);
return NULL;
delete data;
return 0;
}
}
@ -346,8 +719,19 @@ double Update2(UINT id)
if (urlData->updateCounter == 0)
{
// Launch a new thread to fetch the web data
DWORD id;
urlData->dlThreadHandle = CreateThread(NULL, 0, NetworkDownloadThreadProc, urlData, 0, &id);
unsigned int id;
HANDLE threadHandle = (HANDLE)_beginthreadex(NULL, 0, NetworkDownloadThreadProc, urlData, 0, &id);
if (threadHandle)
{
urlData->dlThreadHandle = threadHandle;
}
else // error
{
std::wstring error = L"WebParser: Failed to begin download thread: [";
error += urlData->section;
error += L"]";
Log(error.c_str());
}
}
urlData->updateCounter++;
@ -379,8 +763,19 @@ double Update2(UINT id)
if (urlData->updateCounter == 0)
{
// Launch a new thread to fetch the web data
DWORD id;
urlData->threadHandle = CreateThread(NULL, 0, NetworkThreadProc, urlData, 0, &id);
unsigned int id;
HANDLE threadHandle = (HANDLE)_beginthreadex(NULL, 0, NetworkThreadProc, urlData, 0, &id);
if (threadHandle)
{
urlData->threadHandle = threadHandle;
}
else // error
{
std::wstring error = L"WebParser: Failed to begin thread: [";
error += urlData->section;
error += L"]";
Log(error.c_str());
}
}
urlData->updateCounter++;
@ -401,7 +796,7 @@ double Update2(UINT id)
/*
Thread that fetches the data from the net and parses the page.
*/
DWORD WINAPI NetworkThreadProc(LPVOID pParam)
unsigned __stdcall NetworkThreadProc(void* pParam)
{
UrlData* urlData = (UrlData*)pParam;
DWORD dwSize = 0;
@ -504,9 +899,9 @@ void ParseData(UrlData* urlData, LPCSTR parseData)
{
if (urlData->debug != 0)
{
for (int i = 0; i < rc; i++)
for (int i = 0; i < rc; ++i)
{
WCHAR buffer[1024];
WCHAR buffer[512];
const char* substring_start = parseData + ovector[2 * i];
int substring_length = ovector[2 * i + 1] - ovector[2 * i];
substring_length = min(substring_length, 256);
@ -521,7 +916,7 @@ void ParseData(UrlData* urlData, LPCSTR parseData)
EnterCriticalSection(&g_CriticalSection);
std::string szResult(substring_start, substring_length);
urlData->resultString = ConvertUTF8ToWide(szResult.c_str());
urlData->resultString = DecodeReferences(ConvertUTF8ToWide(szResult.c_str()), urlData->decodeCharacterReference);
LeaveCriticalSection(&g_CriticalSection);
}
else
@ -539,7 +934,7 @@ void ParseData(UrlData* urlData, LPCSTR parseData)
std::wstring compareStr = L"[";
compareStr += urlData->section;
compareStr += L"]";
for ( ; i != g_UrlData.end(); i++)
for ( ; i != g_UrlData.end(); ++i)
{
if ((((*i).second)->url.find(compareStr) != std::wstring::npos) && (urlData->iniFile == ((*i).second)->iniFile))
{
@ -568,14 +963,25 @@ void ParseData(UrlData* urlData, LPCSTR parseData)
std::wstring wzUrl = ((*i).second)->url;
wzUrl.replace(wzUrl.find(compareStr), compareStr.size(), wzResult);
((*i).second)->resultString = wzUrl;
((*i).second)->resultString = DecodeReferences(wzUrl, (*i).second->decodeCharacterReference);
// Start download threads for the references
if (((*i).second)->download)
{
// Start the download thread
DWORD id;
((*i).second)->dlThreadHandle = CreateThread(NULL, 0, NetworkDownloadThreadProc, ((*i).second), 0, &id);
unsigned int id;
HANDLE threadHandle = (HANDLE)_beginthreadex(NULL, 0, NetworkDownloadThreadProc, ((*i).second), 0, &id);
if (threadHandle)
{
((*i).second)->dlThreadHandle = threadHandle;
}
else // error
{
std::wstring error = L"WebParser: Failed to begin download thread: [";
error += (*i).second->section;
error += L"]";
Log(error.c_str());
}
}
LeaveCriticalSection(&g_CriticalSection);
@ -597,7 +1003,7 @@ void ParseData(UrlData* urlData, LPCSTR parseData)
else
{
// Matching failed: handle error cases
WCHAR buffer[1024];
WCHAR buffer[64];
wsprintf(buffer, L"WebParser: Matching error! (%d)\n", rc);
Log(buffer);
@ -609,7 +1015,7 @@ void ParseData(UrlData* urlData, LPCSTR parseData)
std::wstring compareStr = L"[";
compareStr += urlData->section;
compareStr += L"]";
for ( ; i != g_UrlData.end(); i++)
for ( ; i != g_UrlData.end(); ++i)
{
if ((((*i).second)->url.find(compareStr) != std::wstring::npos) && (urlData->iniFile == ((*i).second)->iniFile))
{
@ -625,7 +1031,7 @@ void ParseData(UrlData* urlData, LPCSTR parseData)
else
{
// Compilation failed: print the error message and exit
WCHAR buffer[1024];
WCHAR buffer[512];
wsprintf(buffer, L"WebParser: PCRE compilation failed at offset %d: %s\n", erroffset, ConvertAsciiToWide(error).c_str());
Log(buffer);
}
@ -633,8 +1039,19 @@ void ParseData(UrlData* urlData, LPCSTR parseData)
if (urlData->download)
{
// Start the download thread
DWORD id;
urlData->dlThreadHandle = CreateThread(NULL, 0, NetworkDownloadThreadProc, urlData, 0, &id);
unsigned int id;
HANDLE threadHandle = (HANDLE)_beginthreadex(NULL, 0, NetworkDownloadThreadProc, urlData, 0, &id);
if (threadHandle)
{
urlData->dlThreadHandle = threadHandle;
}
else // error
{
std::wstring error = L"WebParser: Failed to begin download thread: [";
error += urlData->section;
error += L"]";
Log(error.c_str());
}
}
else
{
@ -660,7 +1077,7 @@ void ParseData(UrlData* urlData, LPCSTR parseData)
/*
Thread that downloads the file from the new.
*/
DWORD WINAPI NetworkDownloadThreadProc(LPVOID pParam)
unsigned __stdcall NetworkDownloadThreadProc(void* pParam)
{
UrlData* urlData = (UrlData*)pParam;
@ -1080,6 +1497,8 @@ void Finalize(HMODULE instance, UINT id)
hRootHandle = NULL;
}
g_CERs.clear();
// Last instance deletes the critical section
DeleteCriticalSection(&g_CriticalSection);
g_Initialized = false;
@ -1129,16 +1548,15 @@ BYTE* DownloadUrl(std::wstring& url, DWORD* dwDataSize, bool forceReload)
*dwDataSize = 0;
// Allocate the buffer.
lpData = new BYTE[CHUNK_SIZE];
do
{
// Allocate the buffer.
lpData = new BYTE[CHUNK_SIZE];
// Read the data.
if (!InternetReadFile(hUrlDump, (LPVOID)lpData, CHUNK_SIZE, &dwSize))
{
ShowError(__LINE__);
delete [] lpData;
break;
}
else
@ -1147,14 +1565,12 @@ BYTE* DownloadUrl(std::wstring& url, DWORD* dwDataSize, bool forceReload)
// never get called on the first time through the loop.
if (dwSize == 0)
{
// Delete the existing buffers.
delete [] lpData;
break;
}
// Determine the buffer size to hold the new data and the data
// already written (if any).
nBufferSize = nCounter * CHUNK_SIZE;
nBufferSize = *dwDataSize + dwSize;
// Allocate the output buffer.
lpOutPut = new BYTE[nBufferSize + 2];
@ -1186,10 +1602,10 @@ BYTE* DownloadUrl(std::wstring& url, DWORD* dwDataSize, bool forceReload)
lpOutPut[dwSize + 1] = 0;
// Increment the number of buffers read.
nCounter++;
++nCounter;
// Delete the buffer
delete [] lpData;
// Clear the buffer
memset(lpData, 0, CHUNK_SIZE);
}
} while (TRUE);
@ -1200,6 +1616,9 @@ BYTE* DownloadUrl(std::wstring& url, DWORD* dwDataSize, bool forceReload)
err += url;
Log(err.c_str());
// Delete the existing buffers.
delete [] lpData;
// Return.
return lpHolding;
}
@ -1209,8 +1628,6 @@ BYTE* DownloadUrl(std::wstring& url, DWORD* dwDataSize, bool forceReload)
*/
void ShowError(int lineNumber, WCHAR* errorMsg)
{
WCHAR szBuffer[4096];
DWORD dwErr = GetLastError();
WCHAR buffer[16];
@ -1224,7 +1641,8 @@ void ShowError(int lineNumber, WCHAR* errorMsg)
{
if (dwErr == ERROR_INTERNET_EXTENDED_ERROR)
{
DWORD dwError, dwLen = 4096;
WCHAR szBuffer[1024];
DWORD dwError, dwLen = 1024;
if (InternetGetLastResponseInfo(&dwError, szBuffer, &dwLen))
{
err += szBuffer;
@ -1292,7 +1710,7 @@ void Log(const WCHAR* string)
UINT GetPluginVersion()
{
return 1012;
return 1013;
}
LPCTSTR GetPluginAuthor()