diff --git a/Plugins/PluginWebParser/WebParser.cpp b/Plugins/PluginWebParser/WebParser.cpp index 667abfa3..eb4e1912 100644 --- a/Plugins/PluginWebParser/WebParser.cpp +++ b/Plugins/PluginWebParser/WebParser.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #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 g_UrlData; static bool g_Debug = false; static HINTERNET hRootHandle = NULL; +static std::map 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::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::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()