Beispiel #1
0
HRESULT CHeader::Parse(const Byte *p)
{
  UInt32 haderSize = Get32(p + 8);
  if (haderSize < 0x74)
    return S_FALSE;
  Version = Get32(p + 0x0C);
  Flags = Get32(p + 0x10);
  if (!IsSupported())
    return S_FALSE;
  UInt32 chunkSize = Get32(p + 0x14);
  if (chunkSize != kChunkSize && chunkSize != 0)
    return S_FALSE;
  memcpy(Guid, p + 0x18, 16);
  PartNumber = Get16(p + 0x28);
  NumParts = Get16(p + 0x2A);
  int offset = 0x2C;
  if (IsNewVersion())
  {
    NumImages = Get32(p + offset);
    offset += 4;
  }
  GetResource(p + offset, OffsetResource);
  GetResource(p + offset + 0x18, XmlResource);
  GetResource(p + offset + 0x30, MetadataResource);
  /*
  if (IsNewVersion())
  {
    if (haderSize < 0xD0)
      return S_FALSE;
    IntegrityResource.Parse(p + offset + 0x4C);
    BootIndex = Get32(p + 0x48);
  }
  */
  return S_OK;
}
Beispiel #2
0
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();
}