1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
// 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"
// function definitions
extern "C" HRESULT CatalogsParseFromXml(
__in BURN_CATALOGS* pCatalogs,
__in IXMLDOMNode* pixnBundle
)
{
HRESULT hr = S_OK;
IXMLDOMNodeList* pixnNodes = NULL;
IXMLDOMNode* pixnNode = NULL;
DWORD cNodes = 0;
LPWSTR scz = NULL;
// select catalog nodes
hr = XmlSelectNodes(pixnBundle, L"Catalog", &pixnNodes);
ExitOnFailure(hr, "Failed to select catalog nodes.");
// get catalog node count
hr = pixnNodes->get_length((long*)&cNodes);
ExitOnFailure(hr, "Failed to get payload node count.");
if (!cNodes)
{
ExitFunction();
}
// allocate memory for catalogs
pCatalogs->rgCatalogs = (BURN_CATALOG*)MemAlloc(sizeof(BURN_CATALOG) * cNodes, TRUE);
ExitOnNull(pCatalogs->rgCatalogs, hr, E_OUTOFMEMORY, "Failed to allocate memory for payload structs.");
pCatalogs->cCatalogs = cNodes;
// parse catalog elements
for (DWORD i = 0; i < cNodes; ++i)
{
BURN_CATALOG* pCatalog = &pCatalogs->rgCatalogs[i];
pCatalog->hFile = INVALID_HANDLE_VALUE;
hr = XmlNextElement(pixnNodes, &pixnNode, NULL);
ExitOnFailure(hr, "Failed to get next node.");
// @Id
hr = XmlGetAttributeEx(pixnNode, L"Id", &pCatalog->sczKey);
ExitOnFailure(hr, "Failed to get @Id.");
// @Payload
hr = XmlGetAttributeEx(pixnNode, L"Payload", &pCatalog->sczPayload);
ExitOnFailure(hr, "Failed to get @Payload.");
// prepare next iteration
ReleaseNullObject(pixnNode);
}
LExit:
ReleaseObject(pixnNodes);
ReleaseObject(pixnNode);
ReleaseStr(scz);
return hr;
}
extern "C" HRESULT CatalogFindById(
__in BURN_CATALOGS* pCatalogs,
__in_z LPCWSTR wzId,
__out BURN_CATALOG** ppCatalog
)
{
HRESULT hr = S_OK;
BURN_CATALOG* pCatalog = NULL;
for (DWORD i = 0; i < pCatalogs->cCatalogs; ++i)
{
pCatalog = &pCatalogs->rgCatalogs[i];
if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pCatalog->sczKey, -1, wzId, -1))
{
*ppCatalog = pCatalog;
ExitFunction1(hr = S_OK);
}
}
hr = E_NOTFOUND;
LExit:
return hr;
}
extern "C" HRESULT CatalogLoadFromPayload(
__in BURN_CATALOGS* pCatalogs,
__in BURN_PAYLOADS* pPayloads
)
{
HRESULT hr = S_OK;
BURN_CATALOG* pCatalog = NULL;
BURN_PAYLOAD* pPayload = NULL;
// go through each catalog file
for (DWORD i = 0; i < pCatalogs->cCatalogs; i++)
{
pCatalog = &pCatalogs->rgCatalogs[i];
// get the payload for this catalog file
hr = PayloadFindById(pPayloads, pCatalog->sczPayload, &pPayload);
ExitOnFailure(hr, "Failed to find payload for catalog file.");
// Get the local file name
hr = StrAllocString(&pCatalog->sczLocalFilePath, pPayload->sczLocalFilePath, 0);
ExitOnFailure(hr, "Failed to get catalog local file path");
// Get a handle to the file
pCatalog->hFile = ::CreateFileW(pCatalog->sczLocalFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (INVALID_HANDLE_VALUE == pCatalog->hFile)
{
ExitWithLastError(hr, "Failed to open catalog in working path: %ls", pCatalog->sczLocalFilePath);
}
// Verify the catalog file
hr = CacheVerifyPayloadSignature(pPayload, pCatalog->sczLocalFilePath, pCatalog->hFile);
ExitOnFailure(hr, "Failed to verify catalog signature: %ls", pCatalog->sczLocalFilePath);
}
LExit:
return hr;
}
extern "C" HRESULT CatalogElevatedUpdateCatalogFile(
__in BURN_CATALOGS* pCatalogs,
__in_z LPCWSTR wzId,
__in_z LPCWSTR wzPath
)
{
HRESULT hr = S_OK;
BURN_CATALOG* pCatalog = NULL;
// Find the catalog
hr = CatalogFindById(pCatalogs, wzId, &pCatalog);
ExitOnFailure(hr, "Failed to locate catalog information.");
if (NULL == pCatalog->sczLocalFilePath)
{
hr = StrAllocString(&pCatalog->sczLocalFilePath, wzPath, 0);
ExitOnFailure(hr, "Failed to allocated catalog path.");
// Get a handle to the file
pCatalog->hFile = ::CreateFileW(pCatalog->sczLocalFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (INVALID_HANDLE_VALUE == pCatalog->hFile)
{
ExitWithLastError(hr, "Failed to open catalog in working path: %ls", pCatalog->sczLocalFilePath);
}
}
LExit:
return hr;
}
extern "C" void CatalogUninitialize(
__in BURN_CATALOGS* pCatalogs
)
{
if (pCatalogs->rgCatalogs)
{
for (DWORD i = 0; i < pCatalogs->cCatalogs; ++i)
{
BURN_CATALOG* pCatalog = &pCatalogs->rgCatalogs[i];
ReleaseHandle(pCatalog->hFile);
ReleaseStr(pCatalog->sczKey);
ReleaseStr(pCatalog->sczLocalFilePath);
ReleaseStr(pCatalog->sczPayload);
}
MemFree(pCatalogs->rgCatalogs);
}
// clear struct
memset(pCatalogs, 0, sizeof(BURN_CATALOGS));
}
|