| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 | 
							- #include "main.h"
 
- #include "./cacheGroup.h"
 
- #include "./cacheRecord.h"
 
- #include "./cacheManager.h"
 
- #include <wininet.h>
 
- #include <shlwapi.h>
 
- #include <strsafe.h>
 
- #include <algorithm>
 
- CacheGroup::CacheGroup(LPCWSTR pszName)
 
- 	: ref(1), name(NULL), owner(NULL)
 
- {
 
- 	name = Plugin_CopyString(pszName);
 
- }
 
- CacheGroup::~CacheGroup()
 
- {
 
- 	Clear();
 
- 	Plugin_FreeString(name);
 
- }
 
- HRESULT CacheGroup::CreateInstance(LPCWSTR pszName, CacheGroup **instance)
 
- {
 
- 	if (NULL == instance) return E_POINTER;
 
- 	*instance = NULL;
 
- 	*instance = new CacheGroup(pszName);
 
- 	if (NULL == *instance) return E_OUTOFMEMORY;
 
- 	return S_OK;
 
- }
 
- size_t CacheGroup::AddRef()
 
- {
 
- 	return InterlockedIncrement((LONG*)&ref);
 
- }
 
- size_t CacheGroup::Release()
 
- {
 
- 	if (0 == ref)
 
- 		return ref;
 
- 	
 
- 	LONG r = InterlockedDecrement((LONG*)&ref);
 
- 	if (0 == r)
 
- 		delete(this);
 
- 	
 
- 	return r;
 
- }
 
- int CacheGroup::QueryInterface(GUID interface_guid, void **object)
 
- {
 
- 	if (NULL == object) return E_POINTER;
 
- 	if (IsEqualIID(interface_guid, IFC_OmCacheGroup))
 
- 		*object = static_cast<ifc_omcachegroup*>(this);
 
- 	else
 
- 	{
 
- 		*object = NULL;
 
- 		return E_NOINTERFACE;
 
- 	}
 
- 	if (NULL == *object)
 
- 		return E_UNEXPECTED;
 
- 	AddRef();
 
- 	return S_OK;
 
- }
 
- HRESULT CacheGroup::SetOwner(CacheManager *group)
 
- {
 
- 	owner = group;
 
- 	return S_OK;
 
- }
 
- HRESULT CacheGroup::GetName(LPWSTR pszBuffer, UINT cchBufferMax)
 
- {
 
- 	if (NULL == pszBuffer || 0 == cchBufferMax) 
 
- 		return E_INVALIDARG;
 
- 	return StringCchCopyEx(pszBuffer, cchBufferMax, name, NULL, NULL, STRSAFE_IGNORE_NULLS);
 
- }
 
- HRESULT CacheGroup::IsEqualName(LPCWSTR pszGroup)
 
- {
 
- 	if (NULL == pszGroup)
 
- 		return (NULL == name) ? S_OK : S_FALSE;
 
- 	
 
- 	if (NULL == name) return S_FALSE;
 
- 	INT result = CompareString(CSTR_INVARIANT, NORM_IGNORECASE, pszGroup, -1, name, -1);
 
- 	if (0 == result)
 
- 	{
 
- 		DWORD error = GetLastError();
 
- 		return HRESULT_FROM_WIN32(error);
 
- 	}
 
- 	return (CSTR_EQUAL == result) ? S_OK : S_FALSE;
 
- }
 
- HRESULT CacheGroup::IsEqual(CacheGroup *group)
 
- {
 
- 	return (NULL != group) ? IsEqualName(group->name) : E_INVALIDARG;
 
- }
 
- HRESULT CacheGroup::IsEmpty()
 
- {
 
- 	return (0 == recordList.size()) ? S_OK : S_FALSE;
 
- }
 
- HRESULT CacheGroup::Delete(LPCWSTR pszName)
 
- {
 
- 	HRESULT hr = S_FALSE;
 
- 	size_t index = recordList.size();
 
- 	while(index--)
 
- 	{
 
- 		CacheRecord *record = recordList[index];
 
- 		if (NULL != record && S_OK == record->IsEqualName(pszName))
 
- 		{
 
- 			recordList.erase(recordList.begin() + index);
 
- 			record->Release();
 
- 			hr = S_OK;
 
- 			break;
 
- 		}
 
- 	}
 
- 	return hr;
 
- }
 
- HRESULT CacheGroup::Clear()
 
- {
 
- 	size_t index = recordList.size();
 
- 	while(index--)
 
- 	{
 
- 		CacheRecord *record = recordList[index];
 
- 		if (NULL != record) record->Release();
 
- 	}
 
- 	recordList.clear();
 
- 	return S_OK;
 
- }
 
- __inline static int __cdecl CacheGroup_RecordSearch(const void *elem1, const void *elem2)
 
- {
 
- 	int r = ((CacheRecord*)elem2)->CompareTo((LPCWSTR)elem1); 
 
- 	return -r;
 
- }
 
- HRESULT CacheGroup::Find(LPCWSTR pszName, BOOL fInsertMissing, CacheRecord **recordOut, BOOL *created)
 
- {
 
- 	if (NULL != created)
 
- 		*created = FALSE;
 
- 	if (NULL == recordOut) 
 
- 		return E_POINTER;
 
- 		
 
- 	HRESULT hr = S_FALSE;
 
- 	size_t index = recordList.size();
 
- 	if (0 != index)
 
- 	{		
 
- 		//CacheRecord *rec = (CacheRecord*)bsearch(pszName, recordList.at(0), recordList.size(), sizeof(CacheRecord*), CacheGroup_RecordSearch);
 
- 		auto it = std::find_if(recordList.begin(), recordList.end(),
 
- 			[&](CacheRecord* upT) -> bool
 
- 			{
 
- 				return upT->CompareTo(pszName) == 0;
 
- 			}
 
- 		);
 
- 		if (it != recordList.end())
 
- 		{			
 
- 			*recordOut = *it;
 
- 			(*recordOut)->AddRef();
 
- 			hr = S_OK;
 
- 		}
 
- 	}
 
- 	
 
- 	if (S_FALSE == hr && FALSE != fInsertMissing)
 
- 	{
 
- 		hr = CacheRecord::CreateInstance(pszName, NULL, 0, recordOut);
 
- 		if (SUCCEEDED(hr))
 
- 		{
 
- 			recordList.push_back(*recordOut);
 
- 			Sort();
 
- 			(*recordOut)->AddRef();
 
- 			(*recordOut)->SetOwner(this);
 
- 			
 
- 			if (NULL != created)
 
- 				*created = TRUE;
 
- 		}
 
- 	}
 
- 	if (S_OK != hr)
 
- 		*recordOut = NULL;
 
- 	
 
- 	return hr;
 
- }
 
- HRESULT CacheGroup::GetPath(LPWSTR pszBuffer, UINT cchBufferMax)
 
- {
 
- 	if (NULL == pszBuffer || 0 == cchBufferMax) 
 
- 		return E_INVALIDARG;
 
- 	
 
- 	HRESULT hr;
 
- 	if (NULL != owner)
 
- 	{
 
- 		hr = owner->GetPath(pszBuffer, cchBufferMax);
 
- 		if (SUCCEEDED(hr) && NULL != name)
 
- 		{
 
- 			if (FALSE == PathAppend(pszBuffer, name))
 
- 				hr = E_OUTOFMEMORY;
 
- 		}
 
- 	}
 
- 	else
 
- 	{
 
- 		*pszBuffer = L'\0';
 
- 		hr = E_UNEXPECTED;
 
- 	}
 
- 	return hr;
 
- }
 
- static HRESULT CacheGroup_FormatStoreData(LPWSTR pszBuffer, size_t cchBufferMax, LPCWSTR pszPath, UINT *cchLength)
 
- {
 
- 	if (NULL == pszBuffer) 
 
- 		return E_INVALIDARG;
 
- 	
 
- 	size_t remaining = cchBufferMax;
 
- 	HRESULT hr;
 
- 	hr = StringCchCopyEx(pszBuffer, remaining, L"path=", &pszBuffer, &remaining, 0);
 
- 	if (FAILED(hr)) return hr;
 
- 	hr = StringCchCopyEx(pszBuffer, remaining, pszPath, &pszBuffer, &remaining, 0);
 
- 	if (FAILED(hr)) return hr;
 
- 	if (0 == remaining) 
 
- 		return E_OUTOFMEMORY;
 
- 	remaining--;
 
- 	pszBuffer++;
 
- 	*pszBuffer = L'\0';
 
- 	
 
- 	if (NULL != cchLength)
 
- 		*cchLength = (UINT)(cchBufferMax - remaining) + 1;
 
- 	return S_OK;
 
- }
 
- HRESULT CacheGroup::Store(LPCWSTR pszName, LPCWSTR pszPath)
 
- {
 
- 	HRESULT hr;
 
- 	WCHAR szBuffer[2048] = {0};
 
- 	
 
- 	hr = GetPath(szBuffer, ARRAYSIZE(szBuffer));
 
- 	if (FAILED(hr)) return hr;
 
- 	Plugin_EnsurePathExist(szBuffer);
 
- 	
 
- 	if (FALSE == PathAppend(szBuffer, L"cache.ini"))
 
- 		return E_OUTOFMEMORY;
 
- 	
 
- 	LPSTR pathAnsi = Plugin_WideCharToMultiByte(CP_UTF8, 0, szBuffer, -1,  NULL, NULL);
 
- 	if (NULL == pathAnsi) return E_OUTOFMEMORY;
 
- 	
 
- 	LPSTR nameAnsi = Plugin_WideCharToMultiByte(CP_UTF8, 0, pszName, -1,  NULL, NULL);
 
- 	if (NULL == nameAnsi) return E_OUTOFMEMORY;
 
- 	LPSTR dataAnsi = NULL;
 
- 	if (NULL != pszPath)
 
- 	{
 
- 		UINT cchData;
 
- 		hr = CacheGroup_FormatStoreData(szBuffer, ARRAYSIZE(szBuffer), pszPath, &cchData);
 
- 		if (SUCCEEDED(hr))
 
- 		{
 
- 			dataAnsi = Plugin_WideCharToMultiByte(CP_UTF8, 0, szBuffer, cchData, NULL, NULL);
 
- 			if (NULL == dataAnsi)
 
- 				hr = E_OUTOFMEMORY;
 
- 		}
 
- 	}
 
- 	if (SUCCEEDED(hr) && 0 == WritePrivateProfileSectionA(nameAnsi, dataAnsi, pathAnsi))
 
- 	{
 
- 		DWORD error = GetLastError();
 
- 		hr = HRESULT_FROM_WIN32(error);
 
- 	}
 
- 		
 
- 	Plugin_FreeAnsiString(dataAnsi);
 
- 	Plugin_FreeAnsiString(nameAnsi);
 
- 	Plugin_FreeAnsiString(pathAnsi);
 
- 	return hr;
 
- }
 
- HRESULT CacheGroup::Load()
 
- {
 
- 	HRESULT hr;
 
- 	WCHAR szBuffer[4096] = {0};
 
- 	hr = GetPath(szBuffer, ARRAYSIZE(szBuffer));
 
- 	if (FAILED(hr)) return hr;
 
- 	if (FALSE == PathAppend(szBuffer, L"cache.ini"))
 
- 		return E_OUTOFMEMORY;
 
- 	HANDLE hFile = CreateFile(szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
 
- 	if (INVALID_HANDLE_VALUE == hFile)
 
- 	{
 
- 		DWORD error = GetLastError();
 
- 		return HRESULT_FROM_WIN32(error);
 
- 	}
 
- 	DWORD read = 0;
 
- 	CHAR szLine[INTERNET_MAX_URL_LENGTH + 3] = {0};
 
- 	WCHAR szUnicode[ARRAYSIZE(szLine)] = {0};
 
- 	UINT lineIndex = 0;
 
- 	CacheRecord *record = NULL;
 
- 	UINT recordSet = 0;
 
- 	size_t inserted = 0;
 
- 	RecordList cleanupList;
 
- 	while (0 != ReadFile(hFile, szBuffer, sizeof(szBuffer), &read, NULL))
 
- 	{
 
- 		LPCSTR cursor = (LPCSTR)szBuffer;
 
- 		LPCSTR end = cursor + read;
 
- 		
 
- 		for(;;)
 
- 		{
 
- 			if (cursor >= end)
 
- 				break;
 
- 			if (cursor == end || ('\r' == *cursor && '\n' == *(cursor+1)))
 
- 			{
 
- 				szLine[lineIndex] = '\0';
 
- 				
 
- 				if (lineIndex > 0)
 
- 				{
 
- 					if ('[' == szLine[0] && ']' == szLine[lineIndex-1])
 
- 					{
 
- 						if (NULL != record)
 
- 						{
 
- 							if (0 != (0x00000001 & recordSet))
 
- 							{
 
- 								recordList.push_back(record);
 
- 								inserted++;
 
- 							}
 
- 							else
 
- 							{
 
- 								cleanupList.push_back(record);
 
- 							}
 
- 							
 
- 							record = NULL;
 
- 						}
 
- 						
 
- 						szLine[lineIndex-1] = '\0';
 
-                         if (0 != MultiByteToWideChar(CP_UTF8, 0, szLine + 1, -1, szUnicode, ARRAYSIZE(szUnicode)) && 
 
- 							SUCCEEDED(CacheRecord::CreateInstance(szUnicode, NULL, 0, &record)))
 
- 						{
 
- 							record->SetOwner(this);
 
- 							recordSet = 0;
 
- 						}
 
- 					}
 
- 					else
 
- 					{
 
- 						const char kw_path[] = "path=";
 
- 						UINT cchKey = ARRAYSIZE(kw_path) - 1; 
 
- 						if (NULL != record && 
 
- 							lineIndex > cchKey && 
 
- 							CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, NORM_IGNORECASE, kw_path, cchKey, szLine, cchKey) &&
 
- 							0 != MultiByteToWideChar(CP_UTF8, 0, szLine + cchKey, -1, szUnicode, ARRAYSIZE(szUnicode)))
 
- 						{
 
- 							if(SUCCEEDED(record->SetPath(szUnicode)) && 
 
- 								SUCCEEDED(record->GetPath(szUnicode, ARRAYSIZE(szUnicode))) &&
 
- 								FALSE != PathFileExists(szUnicode))
 
- 							{
 
- 								recordSet |= 0x00000001;
 
- 							}
 
- 						}
 
- 					}
 
- 				}
 
-     
 
- 				lineIndex = 0;
 
- 				cursor += 2;
 
- 				continue;
 
- 			}
 
- 			
 
- 			if (lineIndex < ARRAYSIZE(szLine) - 2)
 
- 			{
 
- 				szLine[lineIndex++] = *cursor;
 
- 			}
 
- 			cursor++;
 
- 		}
 
- 		if (0 == read)
 
- 		{
 
- 			if (NULL != record)
 
- 			{
 
- 				if (0 != (0x00000001 & recordSet))
 
- 				{
 
- 					recordList.push_back(record);
 
- 					inserted++;
 
- 				}
 
- 				else
 
- 					record->Release();
 
- 			}
 
- 			break;
 
- 		}
 
- 	}
 
- 	CloseHandle(hFile);
 
- 	if (0 != inserted)
 
- 	{
 
- 		Sort();
 
- 	}
 
- 	size_t i = cleanupList.size();
 
- 	if (0 != i)
 
- 	{
 
- 		while (i--)
 
- 		{
 
- 			aTRACE_LINE("ADD CACHE CLEANUP!!!!");
 
- 			cleanupList[i]->Release();
 
- 		}
 
- 	}
 
- 	return S_OK;
 
- }
 
- __inline static int __cdecl CacheGroup_RecordComparer(const void *elem1, const void *elem2)
 
- {
 
- 	return CacheRecord::Compare((CacheRecord*)elem1, (CacheRecord*)elem2);
 
- }
 
- __inline static bool __cdecl CacheGroup_RecordComparer_V2(const void* elem1, const void* elem2)
 
- {
 
- 	return CacheGroup_RecordComparer(elem1, elem2) < 0;
 
- }
 
- HRESULT CacheGroup::Sort()
 
- {
 
- 	HRESULT hr;
 
- 	if (0 == recordList.size())
 
- 	{
 
- 		hr = S_FALSE;
 
- 	}
 
- 	else
 
- 	{
 
- 		//qsort(recordList.first(), recordList.size(), sizeof(CacheRecord*), CacheGroup_RecordComparer);
 
- 		std::sort(recordList.begin(), recordList.end(), CacheGroup_RecordComparer_V2);
 
- 		hr = S_OK;
 
- 	}
 
- 	return hr;
 
- }
 
- #define CBCLASS CacheGroup
 
- START_DISPATCH;
 
- CB(ADDREF, AddRef)
 
- CB(RELEASE, Release)
 
- CB(QUERYINTERFACE, QueryInterface)
 
- CB(API_GETNAME, GetName)
 
- CB(API_FIND, Find)
 
- CB(API_DELETE, Delete)
 
- CB(API_CLEAR, Clear)
 
- END_DISPATCH;
 
- #undef CBCLASS
 
 
  |