123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- #include "main.h"
- #include "./cacheRecord.h"
- #include "./cacheDownloader.h"
- #include "./cacheGroup.h"
- #include "./ifc_omcachecallback.h"
- #include <shlwapi.h>
- #include <strsafe.h>
- CacheRecord::CacheRecord(LPCWSTR pszName, LPCWSTR pszAddress, UINT uFlags)
- : ref(1), owner(NULL), name(NULL), path(NULL), flags(uFlags), downloader(NULL), callbackList(NULL)
- {
- name = Plugin_CopyString(pszName);
- path = Plugin_CopyString(pszAddress);
- InitializeCriticalSection(&lock);
- }
- CacheRecord::~CacheRecord()
- {
- Plugin_FreeString(name);
- Plugin_FreeString(path);
- EnterCriticalSection(&lock);
- if (NULL != downloader)
- {
- downloader->SetOwner(NULL);
- downloader->Release();
- }
- if (NULL != callbackList)
- {
- size_t index = callbackList->size();
- while(index--)
- {
- ifc_omcachecallback *callback = callbackList->at(index);
- if (NULL != callback) callback->Release();
- }
- delete(callbackList);
- }
- LeaveCriticalSection(&lock);
- DeleteCriticalSection(&lock);
- }
- HRESULT CacheRecord::CreateInstance(LPCWSTR pszName, LPCWSTR pszAddress, UINT uFlags, CacheRecord **instance)
- {
- if (NULL == instance) return E_POINTER;
- *instance = NULL;
- if (NULL == pszName || L'\0' == *pszName) return E_INVALIDARG;
- *instance = new CacheRecord(pszName, pszAddress, uFlags);
- if (NULL == *instance) return E_OUTOFMEMORY;
- return S_OK;
- }
- INT CacheRecord::Compare(CacheRecord *record1, CacheRecord *record2)
- {
- if (NULL == record1 || NULL == record2)
- return (INT)(INT_PTR)(record1 - record2);
- return record1->CompareTo(record2->name);
- }
- size_t CacheRecord::AddRef()
- {
- return InterlockedIncrement((LONG*)&ref);
- }
- size_t CacheRecord::Release()
- {
- if (0 == ref)
- return ref;
-
- LONG r = InterlockedDecrement((LONG*)&ref);
- if (0 == r)
- delete(this);
-
- return r;
- }
- int CacheRecord::QueryInterface(GUID interface_guid, void **object)
- {
- if (NULL == object) return E_POINTER;
- if (IsEqualIID(interface_guid, IFC_OmCacheRecord))
- *object = static_cast<ifc_omcacherecord*>(this);
- else
- {
- *object = NULL;
- return E_NOINTERFACE;
- }
- if (NULL == *object)
- return E_UNEXPECTED;
- AddRef();
- return S_OK;
- }
- HRESULT CacheRecord::SetOwner(CacheGroup *group)
- {
- EnterCriticalSection(&lock);
- owner = group;
- LeaveCriticalSection(&lock);
- return S_OK;
- }
- HRESULT CacheRecord::GetName(LPWSTR pszBuffer, UINT cchBufferMax)
- {
- if (NULL == pszBuffer || 0 == cchBufferMax)
- return E_INVALIDARG;
- return StringCchCopyEx(pszBuffer, cchBufferMax, name, NULL, NULL, STRSAFE_IGNORE_NULLS);
- }
- HRESULT CacheRecord::GetPath(LPWSTR pszBuffer, UINT cchBufferMax)
- {
- if (NULL == pszBuffer || 0 == cchBufferMax)
- return E_INVALIDARG;
-
- HRESULT hr;
- EnterCriticalSection(&lock);
- if (NULL == path)
- {
- *pszBuffer = L'\0';
- if (NULL != downloader)
- {
- hr = E_PENDING;
- }
- else if (0 != (flagDownloadFailed & flags))
- {
- hr = E_FAIL;
- }
- else if (NULL != name && L'\0' != *name && PathIsURL(name) &&
- CSTR_EQUAL != CompareString(CSTR_INVARIANT, NORM_IGNORECASE, name, 6, L"res://", 6))
- {
- hr = Download();
- if (SUCCEEDED(hr)) hr = E_PENDING;
- }
- else
- {
- hr = E_FAIL;
- }
- }
- else if (FALSE == PathIsRelative(path))
- {
- hr = StringCchCopy(pszBuffer, cchBufferMax, path);
- }
- else
- {
- if (NULL == owner)
- {
- hr = E_FAIL;
- }
- else if (FAILED(owner->GetPath(pszBuffer, cchBufferMax)) ||
- FALSE == PathAppend(pszBuffer, path))
- {
- hr = E_OUTOFMEMORY;
- }
- else
- {
- hr = S_OK;
- }
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- HRESULT CacheRecord::SetPath(LPCWSTR pszPath)
- {
- EnterCriticalSection(&lock);
- if (NULL != downloader)
- {
- downloader->Abort();
- downloader->Release();
- downloader = NULL;
- }
- Plugin_FreeString(path);
- if (NULL == pszPath)
- {
- path = NULL;
- }
- else
- {
- INT cchCommon = 0;
- if (0 != owner)
- {
- WCHAR szBase[MAX_PATH*2] = {0};
- if (SUCCEEDED(owner->GetPath(szBase, ARRAYSIZE(szBase))))
- cchCommon = PathCommonPrefix(szBase, pszPath, NULL);
- }
-
- if (0 != cchCommon)
- {
- LPCWSTR p = pszPath + cchCommon;
- INT cchSource = lstrlenW(p) + 1/* \0 */;
- path = Plugin_MallocString(cchSource + 1 /*to add '.'*/);
- if (NULL != path)
- {
- *path = L'.';
- CopyMemory(path + 1, p, sizeof(WCHAR) * cchSource);
- }
- }
- else
- {
- path = Plugin_CopyString(pszPath);
- }
- if (NULL == path) return E_OUTOFMEMORY;
- }
- if (0 == (flagNoStore & flags) && NULL != owner)
- owner->Store(name, path);
- if (NULL != callbackList)
- {
- size_t index = callbackList->size();
- while(index--)
- {
- ifc_omcachecallback *cb = callbackList->at(index);
- if (NULL != cb) cb->PathChanged(this);
- }
- }
- LeaveCriticalSection(&lock);
- return S_OK;
- }
- HRESULT CacheRecord::Download()
- {
- HRESULT hr;
- EnterCriticalSection(&lock);
- if (NULL != downloader)
- hr = E_PENDING;
- else
- {
- flags &= ~flagDownloadFailed;
- hr = CacheDownloader::CreateInstance(this, name, FALSE, &downloader);
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- HRESULT CacheRecord::DownloadCompleted(LPCWSTR pszFile, INT errorCode)
- {
- HRESULT hr = S_OK;
- EnterCriticalSection(&lock);
- CacheDownloader *temp = downloader;
- downloader = NULL;
-
- if (api_downloadManager::TICK_SUCCESS == errorCode)
- {
- WCHAR szTarget[MAX_PATH] = {0};
- hr = GetBasePath(szTarget, ARRAYSIZE(szTarget));
- if(SUCCEEDED(hr))
- {
- Plugin_EnsurePathExist(szTarget);
- LPCWSTR fileName = PathFindFileName(name);
- if (NULL == fileName)
- {
- WCHAR szTemp[32] = {0};
- StringCchPrintf(szTemp, ARRAYSIZE(szTemp), L"%08u.cache", GetTickCount());
- PathAppend(szTarget, szTemp);
- }
- else
- {
- PathAppend(szTarget, fileName);
- }
- WCHAR szExt[64] = {0};
- UINT attempt = 0;
- UINT pExtMax = 0;
- LPWSTR pExt = PathFindExtension(szTarget);
- if (pExt == szTarget || L'.' != *pExt || FAILED(StringCchCopy(szExt, ARRAYSIZE(szExt), pExt)))
- {
- szExt[0] = L'\0';
- }
- else
- {
- pExtMax = ARRAYSIZE(szTarget) - (UINT)(pExt - szTarget);
- }
- while(FALSE == CopyFile(pszFile, szTarget, TRUE))
- {
- DWORD error = GetLastError();
- if (ERROR_FILE_EXISTS != error)
- {
- hr = HRESULT_FROM_WIN32(error);
- break;
- }
-
- hr = StringCchPrintf(pExt, pExtMax, L"(%u)%s", ++attempt, szExt);
- if (FAILED(hr)) break;
- }
- }
- if (SUCCEEDED(hr))
- {
- SetPath(szTarget);
- }
- }
- else
- {
- flags |= flagDownloadFailed;
- }
-
- if (NULL != temp)
- temp->Release();
- LeaveCriticalSection(&lock);
- return S_OK;
- }
- INT CacheRecord::CompareTo(LPCWSTR pszName)
- {
- if (NULL == pszName || NULL == name)
- return (INT)(INT_PTR)(name - pszName);
-
- return CompareString(CSTR_INVARIANT, NORM_IGNORECASE, name, -1, pszName, -1) - 2;
- }
- HRESULT CacheRecord::IsEqualName(LPCWSTR pszName)
- {
- HRESULT hr;
- EnterCriticalSection(&lock);
- if (NULL == pszName)
- {
- hr = (NULL == name) ? S_OK : S_FALSE;
- }
- else if (NULL == name)
- {
- hr = S_FALSE;
- }
- else
- {
- INT result = CompareString(CSTR_INVARIANT, NORM_IGNORECASE, pszName, -1, name, -1);
- if (0 == result)
- {
- DWORD error = GetLastError();
- hr = HRESULT_FROM_WIN32(error);
- }
- else
- {
- hr = (CSTR_EQUAL == result) ? S_OK : S_FALSE;
- }
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- HRESULT CacheRecord::IsEqual(CacheRecord *record)
- {
- if (NULL == record) return E_INVALIDARG;
-
- HRESULT hr;
- EnterCriticalSection(&record->lock);
- hr = IsEqualName(record->name);
- LeaveCriticalSection(&record->lock);
- return hr;
- }
- HRESULT CacheRecord::RegisterCallback(ifc_omcachecallback *callback)
- {
- if (NULL == callback)
- return E_INVALIDARG;
- HRESULT hr = S_OK;
- EnterCriticalSection(&lock);
- if (NULL == callbackList)
- {
- callbackList = new CallbackList();
- if (NULL == callbackList) hr = E_OUTOFMEMORY;
- }
- else
- {
- size_t index = callbackList->size();
- while(index--)
- {
- if (callbackList->at(index) == callback)
- hr = E_FAIL;
- }
- }
-
- if (SUCCEEDED(hr) && NULL != callbackList)
- {
- callbackList->push_back(callback);
- callback->AddRef();
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- HRESULT CacheRecord::UnregisterCallback(ifc_omcachecallback *callback)
- {
- if (NULL == callback)
- return E_INVALIDARG;
- HRESULT hr = S_FALSE;
- EnterCriticalSection(&lock);
- if (NULL != callbackList)
- {
- size_t index = callbackList->size();
- while(index--)
- {
- ifc_omcachecallback *test = callbackList->at(index);
- if (test == callback)
- {
- callbackList->erase(callbackList->begin() + index);
- test->Release();
- hr = S_OK;
- if (0 == callbackList->size())
- {
- delete(callbackList);
- callbackList = NULL;
- }
- }
- }
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- HRESULT CacheRecord::GetFlags(UINT *puFlags)
- {
- if (NULL == puFlags) return E_POINTER;
- *puFlags = flags;
- return S_OK;
- }
- HRESULT CacheRecord::SetFlags(UINT uFlags, UINT uMask)
- {
- EnterCriticalSection(&lock);
- flags = (flags & ~uMask) | (uFlags & uMask);
- LeaveCriticalSection(&lock);
- return S_OK;
- }
- HRESULT CacheRecord::GetBasePath(LPWSTR pszBuffer, UINT cchBufferMax)
- {
- if (NULL == pszBuffer || 0 == cchBufferMax)
- return E_INVALIDARG;
-
- HRESULT hr;
- EnterCriticalSection(&lock);
- if (NULL != owner)
- {
- hr = owner->GetPath(pszBuffer, cchBufferMax);
- }
- else
- {
- *pszBuffer = L'\0';
- hr = E_UNEXPECTED;
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- #define CBCLASS CacheRecord
- START_DISPATCH;
- CB(ADDREF, AddRef)
- CB(RELEASE, Release)
- CB(QUERYINTERFACE, QueryInterface)
- CB(API_GETNAME, GetName)
- CB(API_GETPATH, GetPath)
- CB(API_SETPATH, SetPath)
- CB(API_GETFLAGS, GetFlags)
- CB(API_SETFLAGS, SetFlags)
- CB(API_DOWNLOAD, Download)
- CB(API_REGISTERCALLBACK, RegisterCallback)
- CB(API_UNREGISTERCALLBACK, UnregisterCallback)
- END_DISPATCH;
- #undef CBCLASS
|