diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/auth/Loginbox/download.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/auth/Loginbox/download.cpp')
-rw-r--r-- | Src/auth/Loginbox/download.cpp | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/Src/auth/Loginbox/download.cpp b/Src/auth/Loginbox/download.cpp new file mode 100644 index 00000000..ecc66042 --- /dev/null +++ b/Src/auth/Loginbox/download.cpp @@ -0,0 +1,268 @@ +#include "./common.h" +#include "./download.h" +#include "./downloadResult.h" +#include "../api.h" +#include <api/service/waservicefactory.h> + +#include "./providerLoader.h" +#include "./providerEnumerator.h" + +#include <shlwapi.h> + +LoginDownload::LoginDownload() +{ +} + +LoginDownload::~LoginDownload() +{ + +} + +HRESULT LoginDownload::Begin(LPCWSTR pszUrl, UINT type, LoginDownloadResult::Callback callback, void *data, LoginStatus *pStatus, LoginDownloadResult **result) +{ + if (NULL == result) return E_POINTER; + *result = NULL; + + if (NULL == pszUrl || L'\0' == *pszUrl) + return E_INVALIDARG; + + HRESULT hr; + + LPSTR addressAnsi; + hr = LoginBox_WideCharToMultiByte(CP_UTF8, 0, pszUrl, -1, NULL, NULL, &addressAnsi); + if (SUCCEEDED(hr)) + { + if (NULL != WASABI_API_SVC) + { + waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(DownloadManagerGUID); + api_downloadManager *manager = (NULL != sf) ? (api_downloadManager *)sf->getInterface() : NULL; + if (NULL == manager) + hr = E_UNEXPECTED; + else + { + hr = LoginDownloadResult::CreateInstance(manager, type, callback, data, pStatus, result); + if (SUCCEEDED(hr)) + { + if (0 == manager->DownloadEx(addressAnsi, *result, api_downloadManager::DOWNLOADEX_TEMPFILE)) + { + (*result)->Release(); + *result = NULL; + hr = E_FAIL; + } + } + else + { + sf->releaseInterface(manager); + } + } + } + } + + LoginBox_FreeAnsiString(addressAnsi); + return hr; +} + +HRESULT LoginDownload::End(LoginDownloadResult *result, BSTR *bstrFileName) +{ + if (NULL != bstrFileName) + *bstrFileName = NULL; + + if (NULL == result) return E_INVALIDARG; + + HRESULT hr; + UINT state; + if (FAILED(result->GetState(&state)) || LoginDownloadResult::stateCompleted != state) + { + HANDLE completed; + hr = result->GetWaitHandle(&completed); + if (FAILED(hr)) return hr; + + while(WAIT_OBJECT_0 != WaitForSingleObjectEx(completed, INFINITE, TRUE)); + CloseHandle(completed); + } + + UINT type; + hr = result->GetType(&type); + if (FAILED(hr)) return hr; + + + + switch(type) + { + case LoginDownloadResult::typeProviderList: + hr = SaveProviderList(result, bstrFileName); + break; + case LoginDownloadResult::typeImage: + hr = SaveImage(result, bstrFileName); + break; + case LoginDownloadResult::typeUnknown: + hr = E_NOTIMPL; + break; + } + + return hr; +} + +HRESULT LoginDownload::SaveProviderList(LoginDownloadResult *result, BSTR *bstrFileName) +{ + if (NULL == result) + return E_INVALIDARG; + + HRESULT hr; + LPCWSTR pszSource; + hr = result->GetFile(&pszSource); + if (FAILED(hr)) return hr; + + WCHAR szTarget[2048] = {0}; + hr = LoginBox_GetConfigPath(szTarget, TRUE); + if (FAILED(hr)) return hr; + + if (FALSE == PathAppend(szTarget, L"loginProviders.xml")) + return E_FAIL; + + if (S_OK == IsBinaryEqual(pszSource, szTarget)) + hr = S_FALSE; + else + { + // validate source + LoginProviderEnumerator *enumerator; + LoginProviderLoader loader; + if (FAILED(loader.ReadXml(pszSource, &enumerator, NULL))) + hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + else + { + enumerator->Release(); + + if (FALSE == CopyFile(pszSource, szTarget, FALSE)) + { + DWORD errorCode = GetLastError(); + hr = HRESULT_FROM_WIN32(errorCode); + } + else + hr = S_OK; + } + } + + if (NULL != bstrFileName) + *bstrFileName = (SUCCEEDED(hr)) ? SysAllocString(szTarget) : NULL; + + return hr; +} + +HRESULT LoginDownload::SaveImage(LoginDownloadResult *result, BSTR *bstrFileName) +{ + if (NULL == result) + return E_INVALIDARG; + + HRESULT hr; + LPCWSTR pszSource; + hr = result->GetFile(&pszSource); + if (FAILED(hr)) return hr; + + WCHAR szTarget[2048] = {0}; + hr = LoginBox_GetConfigPath(szTarget, TRUE); + if (FAILED(hr)) return hr; + + CHAR szFileAnsi[MAX_PATH] = {0}, szUrlAnsi[2096] = {0}; + hr = result->CreateDownloadFileName(szFileAnsi, ARRAYSIZE(szFileAnsi)); + if (FAILED(hr)) return hr; + + hr = result->GetUrl(szUrlAnsi, ARRAYSIZE(szUrlAnsi)); + if (FAILED(hr)) return hr; + + LPWSTR pszFile; + hr = LoginBox_MultiByteToWideChar(CP_UTF8, 0, szFileAnsi, -1, &pszFile); + if (FAILED(hr)) return hr; + + if (FALSE == PathAppend(szTarget, pszFile)) + hr = E_FAIL; + else if (FALSE == CopyFile(pszSource, szTarget, FALSE)) + { + DWORD errorCode = GetLastError(); + hr = HRESULT_FROM_WIN32(errorCode); + } + if (NULL != bstrFileName) + *bstrFileName = SysAllocString(szTarget); + + LoginBox_FreeString(pszFile); + return hr; +} + +HRESULT LoginDownload::IsBinaryEqual(LPCWSTR pszFile1, LPCWSTR pszFile2) +{ + HRESULT hr; + HANDLE hFile1, hFile2; + + hFile1 = CreateFile(pszFile1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (INVALID_HANDLE_VALUE == hFile1) + { + DWORD errorCode = GetLastError(); + hr = HRESULT_FROM_WIN32(errorCode); + } + else hr = S_OK; + + if (SUCCEEDED(hr)) + { + hFile2 = CreateFile(pszFile2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (INVALID_HANDLE_VALUE == hFile2) + { + DWORD errorCode = GetLastError(); + hr = HRESULT_FROM_WIN32(errorCode); + } + } + else + hFile2 = INVALID_HANDLE_VALUE; + + if (SUCCEEDED(hr)) + { + // check sizes; + LARGE_INTEGER size1, size2; + if (FALSE == GetFileSizeEx(hFile1, &size1) || FALSE == GetFileSizeEx(hFile2, &size2)) + { + DWORD errorCode = GetLastError(); + hr = HRESULT_FROM_WIN32(errorCode); + } + else + { + if (size1.QuadPart == size2.QuadPart) + { + // compare data + BYTE szBuffer1[4096] = {0}, szBuffer2[4096] = {0}; + for(;;) + { + DWORD read1 = 0, read2 = 0; + if (FALSE == ReadFile(hFile1, szBuffer1, ARRAYSIZE(szBuffer1), &read1, NULL) || + FALSE == ReadFile(hFile2, szBuffer2, ARRAYSIZE(szBuffer2), &read2, NULL)) + { + DWORD errorCode = GetLastError(); + hr = HRESULT_FROM_WIN32(errorCode); + break; + + } + + if (0 == read1 || 0 == read2) + { + hr = (read1 == read2) ? S_OK : S_FALSE; + break; + } + + if(read1 != read2 || 0 != memcmp(szBuffer1, szBuffer2, read1)) + { + hr = S_FALSE; + break; + } + } + } + else + hr = S_FALSE; + } + } + + if (INVALID_HANDLE_VALUE != hFile1) + CloseHandle(hFile1); + + if (INVALID_HANDLE_VALUE != hFile2) + CloseHandle(hFile2); + + return hr; +}
\ No newline at end of file |