From 30827588eb0c189b7e2d04693d116080d333200e Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 22 Apr 2021 15:43:19 -0700 Subject: Move wcautil into libs/wcautil --- src/libs/wcautil/WixToolset.WcaUtil/exbinary.cpp | 142 +++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/libs/wcautil/WixToolset.WcaUtil/exbinary.cpp (limited to 'src/libs/wcautil/WixToolset.WcaUtil/exbinary.cpp') diff --git a/src/libs/wcautil/WixToolset.WcaUtil/exbinary.cpp b/src/libs/wcautil/WixToolset.WcaUtil/exbinary.cpp new file mode 100644 index 00000000..5ff24212 --- /dev/null +++ b/src/libs/wcautil/WixToolset.WcaUtil/exbinary.cpp @@ -0,0 +1,142 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +// +// Extracts the data from the Binary table row with the given ID into a buffer. +// +HRESULT WIXAPI WcaExtractBinaryToBuffer( + __in LPCWSTR wzBinaryId, + __out BYTE** pbData, + __out DWORD* pcbData + ) +{ + HRESULT hr = S_OK; + LPWSTR pwzSql = NULL; + PMSIHANDLE hView; + PMSIHANDLE hRec; + + // make sure we're not horked from the get-go + hr = WcaTableExists(L"Binary"); + if (S_OK != hr) + { + if (SUCCEEDED(hr)) + { + hr = E_UNEXPECTED; + } + ExitOnFailure(hr, "There is no Binary table."); + } + + ExitOnNull(wzBinaryId, hr, E_INVALIDARG, "Binary ID cannot be null"); + ExitOnNull(*wzBinaryId, hr, E_INVALIDARG, "Binary ID cannot be empty string"); + + hr = StrAllocFormatted(&pwzSql, L"SELECT `Data` FROM `Binary` WHERE `Name`=\'%ls\'", wzBinaryId); + ExitOnFailure(hr, "Failed to allocate Binary table query."); + + hr = WcaOpenExecuteView(pwzSql, &hView); + ExitOnFailure(hr, "Failed to open view on Binary table"); + + hr = WcaFetchSingleRecord(hView, &hRec); + ExitOnFailure(hr, "Failed to retrieve request from Binary table"); + + hr = WcaGetRecordStream(hRec, 1, pbData, pcbData); + ExitOnFailure(hr, "Failed to read Binary.Data."); + +LExit: + ReleaseStr(pwzSql); + + return hr; +} + +// +// Extracts the data from the Binary table row with the given ID into a file. +// +HRESULT WIXAPI WcaExtractBinaryToFile( + __in LPCWSTR wzBinaryId, + __in LPCWSTR wzPath + ) +{ + HRESULT hr = S_OK; + BYTE* pbData = NULL; + DWORD cbData = 0; + HANDLE hFile = INVALID_HANDLE_VALUE; + + // grab the bits + hr = WcaExtractBinaryToBuffer(wzBinaryId, &pbData, &cbData); + ExitOnFailure(hr, "Failed to extract binary data: %ls", wzBinaryId); + + // write 'em to the file + hFile = ::CreateFileW(wzPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (INVALID_HANDLE_VALUE == hFile) + { + ExitWithLastError(hr, "Failed to create file: %ls", wzPath); + } + + DWORD cbWritten = 0; + if (!::WriteFile(hFile, pbData, cbData, &cbWritten, NULL)) + { + ExitWithLastError(hr, "Failed to write data to file: %ls", wzPath); + } + +LExit: + ReleaseFile(hFile); + ReleaseMem(pbData); + + return hr; +} + +// +// Extracts the data from the Binary table row with the given ID into a string. +// +HRESULT WIXAPI WcaExtractBinaryToString( + __in LPCWSTR wzBinaryId, + __deref_out_z LPWSTR* psczOutput, + __out WCA_ENCODING* encoding + ) +{ + HRESULT hr = S_OK; + BYTE* pbData = NULL; + DWORD cbData = 0; + + // grab the bits + hr = WcaExtractBinaryToBuffer(wzBinaryId, &pbData, &cbData); + ExitOnFailure(hr, "Failed to extract binary data: %ls", wzBinaryId); + + // expand by a NULL character (or two) to make sure the buffer is null-terminated + cbData += 2; + pbData = reinterpret_cast(MemReAlloc(pbData, cbData, TRUE)); + ExitOnNull(pbData, hr, E_OUTOFMEMORY, "Failed to expand binary buffer"); + + // Check for BOMs. + if (2 < cbData) + { + if ((0xFF == *pbData) && (0xFE == *(pbData + 1))) + { + *encoding = WCA_ENCODING_UTF_16; + hr = StrAllocString(psczOutput, reinterpret_cast(pbData), 0); + } + else if ((0xEF == *pbData) && (0xBB == *(pbData + 1)) && (0xBF == *(pbData + 2))) + { + *encoding = WCA_ENCODING_UTF_8; + hr = StrAllocStringAnsi(psczOutput, reinterpret_cast(pbData), 0, CP_UTF8); + } + else + { + *encoding = WCA_ENCODING_ANSI; + hr = StrAllocStringAnsi(psczOutput, reinterpret_cast(pbData), 0, CP_ACP); + } + ExitOnFailure(hr, "Failed to allocate string for binary buffer."); + } + + // Free the byte buffer since it has been converted to a new UNICODE string, one way or another. + if (pbData) + { + WcaFreeStream(pbData); + pbData = NULL; + } + +LExit: + ReleaseMem(pbData); + + return hr; +} -- cgit v1.2.3-55-g6feb