diff options
Diffstat (limited to 'src/libs/wcautil/WixToolset.WcaUtil/exbinary.cpp')
-rw-r--r-- | src/libs/wcautil/WixToolset.WcaUtil/exbinary.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
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 @@ | |||
1 | // 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. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | // | ||
6 | // Extracts the data from the Binary table row with the given ID into a buffer. | ||
7 | // | ||
8 | HRESULT WIXAPI WcaExtractBinaryToBuffer( | ||
9 | __in LPCWSTR wzBinaryId, | ||
10 | __out BYTE** pbData, | ||
11 | __out DWORD* pcbData | ||
12 | ) | ||
13 | { | ||
14 | HRESULT hr = S_OK; | ||
15 | LPWSTR pwzSql = NULL; | ||
16 | PMSIHANDLE hView; | ||
17 | PMSIHANDLE hRec; | ||
18 | |||
19 | // make sure we're not horked from the get-go | ||
20 | hr = WcaTableExists(L"Binary"); | ||
21 | if (S_OK != hr) | ||
22 | { | ||
23 | if (SUCCEEDED(hr)) | ||
24 | { | ||
25 | hr = E_UNEXPECTED; | ||
26 | } | ||
27 | ExitOnFailure(hr, "There is no Binary table."); | ||
28 | } | ||
29 | |||
30 | ExitOnNull(wzBinaryId, hr, E_INVALIDARG, "Binary ID cannot be null"); | ||
31 | ExitOnNull(*wzBinaryId, hr, E_INVALIDARG, "Binary ID cannot be empty string"); | ||
32 | |||
33 | hr = StrAllocFormatted(&pwzSql, L"SELECT `Data` FROM `Binary` WHERE `Name`=\'%ls\'", wzBinaryId); | ||
34 | ExitOnFailure(hr, "Failed to allocate Binary table query."); | ||
35 | |||
36 | hr = WcaOpenExecuteView(pwzSql, &hView); | ||
37 | ExitOnFailure(hr, "Failed to open view on Binary table"); | ||
38 | |||
39 | hr = WcaFetchSingleRecord(hView, &hRec); | ||
40 | ExitOnFailure(hr, "Failed to retrieve request from Binary table"); | ||
41 | |||
42 | hr = WcaGetRecordStream(hRec, 1, pbData, pcbData); | ||
43 | ExitOnFailure(hr, "Failed to read Binary.Data."); | ||
44 | |||
45 | LExit: | ||
46 | ReleaseStr(pwzSql); | ||
47 | |||
48 | return hr; | ||
49 | } | ||
50 | |||
51 | // | ||
52 | // Extracts the data from the Binary table row with the given ID into a file. | ||
53 | // | ||
54 | HRESULT WIXAPI WcaExtractBinaryToFile( | ||
55 | __in LPCWSTR wzBinaryId, | ||
56 | __in LPCWSTR wzPath | ||
57 | ) | ||
58 | { | ||
59 | HRESULT hr = S_OK; | ||
60 | BYTE* pbData = NULL; | ||
61 | DWORD cbData = 0; | ||
62 | HANDLE hFile = INVALID_HANDLE_VALUE; | ||
63 | |||
64 | // grab the bits | ||
65 | hr = WcaExtractBinaryToBuffer(wzBinaryId, &pbData, &cbData); | ||
66 | ExitOnFailure(hr, "Failed to extract binary data: %ls", wzBinaryId); | ||
67 | |||
68 | // write 'em to the file | ||
69 | hFile = ::CreateFileW(wzPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | ||
70 | if (INVALID_HANDLE_VALUE == hFile) | ||
71 | { | ||
72 | ExitWithLastError(hr, "Failed to create file: %ls", wzPath); | ||
73 | } | ||
74 | |||
75 | DWORD cbWritten = 0; | ||
76 | if (!::WriteFile(hFile, pbData, cbData, &cbWritten, NULL)) | ||
77 | { | ||
78 | ExitWithLastError(hr, "Failed to write data to file: %ls", wzPath); | ||
79 | } | ||
80 | |||
81 | LExit: | ||
82 | ReleaseFile(hFile); | ||
83 | ReleaseMem(pbData); | ||
84 | |||
85 | return hr; | ||
86 | } | ||
87 | |||
88 | // | ||
89 | // Extracts the data from the Binary table row with the given ID into a string. | ||
90 | // | ||
91 | HRESULT WIXAPI WcaExtractBinaryToString( | ||
92 | __in LPCWSTR wzBinaryId, | ||
93 | __deref_out_z LPWSTR* psczOutput, | ||
94 | __out WCA_ENCODING* encoding | ||
95 | ) | ||
96 | { | ||
97 | HRESULT hr = S_OK; | ||
98 | BYTE* pbData = NULL; | ||
99 | DWORD cbData = 0; | ||
100 | |||
101 | // grab the bits | ||
102 | hr = WcaExtractBinaryToBuffer(wzBinaryId, &pbData, &cbData); | ||
103 | ExitOnFailure(hr, "Failed to extract binary data: %ls", wzBinaryId); | ||
104 | |||
105 | // expand by a NULL character (or two) to make sure the buffer is null-terminated | ||
106 | cbData += 2; | ||
107 | pbData = reinterpret_cast<LPBYTE>(MemReAlloc(pbData, cbData, TRUE)); | ||
108 | ExitOnNull(pbData, hr, E_OUTOFMEMORY, "Failed to expand binary buffer"); | ||
109 | |||
110 | // Check for BOMs. | ||
111 | if (2 < cbData) | ||
112 | { | ||
113 | if ((0xFF == *pbData) && (0xFE == *(pbData + 1))) | ||
114 | { | ||
115 | *encoding = WCA_ENCODING_UTF_16; | ||
116 | hr = StrAllocString(psczOutput, reinterpret_cast<LPWSTR>(pbData), 0); | ||
117 | } | ||
118 | else if ((0xEF == *pbData) && (0xBB == *(pbData + 1)) && (0xBF == *(pbData + 2))) | ||
119 | { | ||
120 | *encoding = WCA_ENCODING_UTF_8; | ||
121 | hr = StrAllocStringAnsi(psczOutput, reinterpret_cast<LPCSTR>(pbData), 0, CP_UTF8); | ||
122 | } | ||
123 | else | ||
124 | { | ||
125 | *encoding = WCA_ENCODING_ANSI; | ||
126 | hr = StrAllocStringAnsi(psczOutput, reinterpret_cast<LPCSTR>(pbData), 0, CP_ACP); | ||
127 | } | ||
128 | ExitOnFailure(hr, "Failed to allocate string for binary buffer."); | ||
129 | } | ||
130 | |||
131 | // Free the byte buffer since it has been converted to a new UNICODE string, one way or another. | ||
132 | if (pbData) | ||
133 | { | ||
134 | WcaFreeStream(pbData); | ||
135 | pbData = NULL; | ||
136 | } | ||
137 | |||
138 | LExit: | ||
139 | ReleaseMem(pbData); | ||
140 | |||
141 | return hr; | ||
142 | } | ||