void sendPUTRequest(const std::string& server, const std::string& data) { HRESULT hr; CLSID clsid; IWinHttpRequest *pIWinHttpRequest = NULL; _variant_t varFalse(false); _variant_t varData(data.c_str()); hr = CLSIDFromProgID(L"WinHttp.WinHttpRequest.5.1", &clsid); if (SUCCEEDED(hr)){ hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IWinHttpRequest, (void **)&pIWinHttpRequest); } if (SUCCEEDED(hr)){ hr = pIWinHttpRequest->SetTimeouts(1000, 1000, 2000, 1000); } if (SUCCEEDED(hr)){ _bstr_t method("PUT"); _bstr_t url(server.c_str()); hr = pIWinHttpRequest->Open(method, url, varFalse); } if (SUCCEEDED(hr)){ hr = pIWinHttpRequest->Send(varData); } pIWinHttpRequest->Release(); }
void ProcessLatestUpdate() { WORD majorVersion = 0; WORD minorVersion = 0; WORD buildNumber = 0; WORD revisionNumber = 0; wchar_t szTempFileName[MAX_PATH] { 0 }; wchar_t lpTempPathBuffer[MAX_PATH] = { 0 }; wstring thisFileName = g_moduleFilePath; wstring currentVersion; currentVersion = GetAppVersion(thisFileName.c_str(), &majorVersion, &minorVersion, &buildNumber, &revisionNumber); IWinHttpRequest * pIWinHttpRequest = NULL; BSTR bstrResponse = NULL; HRESULT hr = CoInitialize(NULL); do { VARIANT varFalse; VARIANT varEmpty; CLSID clsid; VariantInit(&varFalse); V_VT(&varFalse) = VT_BOOL; V_BOOL(&varFalse) = VARIANT_FALSE; VariantInit(&varEmpty); V_VT(&varEmpty) = VT_ERROR; hr = CLSIDFromProgID(L"WinHttp.WinHttpRequest.5.1", &clsid); if (SUCCEEDED(hr) == FALSE) { break; } hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IWinHttpRequest, (void **)&pIWinHttpRequest); if (SUCCEEDED(hr) == FALSE) { break; } BSTR bstrMethod = SysAllocString(L"GET"); BSTR bstrUrl = SysAllocString(UPDATE_CHECK_URL); hr = pIWinHttpRequest->Open(bstrMethod, bstrUrl, varFalse); SysFreeString(bstrMethod); SysFreeString(bstrUrl); if (SUCCEEDED(hr) == FALSE) { break; } hr = pIWinHttpRequest->Send(varEmpty); if (SUCCEEDED(hr) == FALSE) { break; } hr = pIWinHttpRequest->get_ResponseText(&bstrResponse); wstring txt = bstrResponse; wstring newUpdateVersion = GetNewVersion(txt); if (newUpdateVersion.length() == 0) { break; } if (newUpdateVersion == currentVersion) { if (g_isConsoleApp == TRUE) { OutputConsole(L"This is the latest version (%s)\n", currentVersion.c_str()); } break; } if (IsNewVersion(majorVersion, minorVersion, buildNumber, revisionNumber, newUpdateVersion) == FALSE) { if (g_isConsoleApp == TRUE) { OutputConsole(L"This is the latest version (%s)\n", L"1.0.0.4"); // currentVersion.c_str()); } break; } // if new, update latest version. // if old, roll-back last stable version. bool is32bit = sizeof(char *) == 4; wstring location = GetUpdateLocation(txt, is32bit); VariantInit(&varEmpty); V_VT(&varEmpty) = VT_ERROR; bstrMethod = SysAllocString(L"GET"); bstrUrl = SysAllocString(location.c_str()); pIWinHttpRequest->Open(bstrMethod, bstrUrl, varFalse); SysFreeString(bstrMethod); SysFreeString(bstrUrl); if (SUCCEEDED(hr) == FALSE) { break; } hr = pIWinHttpRequest->Send(varEmpty); if (SUCCEEDED(hr) == FALSE) { break; } VARIANT varResponse; VariantInit(&varResponse); hr = pIWinHttpRequest->get_ResponseStream(&varResponse); if (SUCCEEDED(hr) == FALSE) { break; } txt = pIWinHttpRequest->GetResponseHeader(L"Content-Type").operator const wchar_t *(); if (txt.find(L"text/html") != -1) { OutputError(L"file not found: %s", location.c_str()); break; } IStream* pStream = NULL; BYTE bBuffer[8192]; DWORD cb, cbRead, cbWritten; if (VT_UNKNOWN == V_VT(&varResponse) || VT_STREAM == V_VT(&varResponse)) { hr = V_UNKNOWN(&varResponse)->QueryInterface(IID_IStream, reinterpret_cast<void**>(&pStream)); } else { break; } if (SUCCEEDED(hr) == FALSE) { break; } DWORD dwRetVal = GetTempPath(MAX_PATH, // length of the buffer lpTempPathBuffer); // buffer for path if (dwRetVal > MAX_PATH || (dwRetVal == 0)) { OutputError(L"GetTempPath failed (%d)", GetLastError()); break; } dwRetVal = GetTempFileName(lpTempPathBuffer, // directory for tmp files L"straw", // temp file name prefix 0, // create unique name szTempFileName); // buffer for name if (dwRetVal == 0) { OutputError(L"GetTempFileName failed (%d)", GetLastError()); break; } bool succeed = true; HANDLE hFile = CreateFile(szTempFileName, GENERIC_WRITE, // Open for writing. 0, // Do not share. NULL, // No security. CREATE_ALWAYS, // Overwrite existing. FILE_ATTRIBUTE_NORMAL, // Normal file. NULL); // No attribute template. if (hFile == INVALID_HANDLE_VALUE) { OutputError(L"Can't open a file: %s", szTempFileName); break; } else { cb = sizeof(bBuffer); hr = pStream->Read(bBuffer, cb, &cbRead); while (SUCCEEDED(hr) && 0 != cbRead) { if (!WriteFile(hFile, bBuffer, cbRead, &cbWritten, NULL)) { OutputError(L"WriteFile fails with 0x%08lx\n", HRESULT_FROM_WIN32(GetLastError())); succeed = false; break; } hr = pStream->Read(bBuffer, cb, &cbRead); } } CloseHandle(hFile); pStream->Release(); VariantClear(&varResponse); if (succeed == true) { wstring oldFileName = thisFileName; oldFileName += currentVersion + L".bak"; ::DeleteFile(oldFileName.c_str()); if (MoveFile(thisFileName.c_str(), oldFileName.c_str()) == FALSE) { OutputError(L"Backup fails (%d)", GetLastError()); break; } if (MoveFile(szTempFileName, thisFileName.c_str()) == FALSE) { OutputError(L"Update fails (%d)", GetLastError()); break; } FireRestartCommand(); } } while (false); if (::PathFileExists(szTempFileName) == TRUE) { ::DeleteFile(szTempFileName); } if (pIWinHttpRequest) { pIWinHttpRequest->Release(); } if (bstrResponse) { SysFreeString(bstrResponse); } CoUninitialize(); }