aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/cabcutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dutil/cabcutil.cpp218
1 files changed, 117 insertions, 101 deletions
diff --git a/src/dutil/cabcutil.cpp b/src/dutil/cabcutil.cpp
index 8619822d..93a9b7e1 100644
--- a/src/dutil/cabcutil.cpp
+++ b/src/dutil/cabcutil.cpp
@@ -2,6 +2,22 @@
2 2
3#include "precomp.h" 3#include "precomp.h"
4 4
5
6// Exit macros
7#define CabcExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_CABCUTIL, x, s, __VA_ARGS__)
8#define CabcExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_CABCUTIL, x, s, __VA_ARGS__)
9#define CabcExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_CABCUTIL, x, s, __VA_ARGS__)
10#define CabcExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_CABCUTIL, x, s, __VA_ARGS__)
11#define CabcExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_CABCUTIL, x, s, __VA_ARGS__)
12#define CabcExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_CABCUTIL, x, s, __VA_ARGS__)
13#define CabcExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_CABCUTIL, p, x, e, s, __VA_ARGS__)
14#define CabcExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_CABCUTIL, p, x, s, __VA_ARGS__)
15#define CabcExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_CABCUTIL, p, x, e, s, __VA_ARGS__)
16#define CabcExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_CABCUTIL, p, x, s, __VA_ARGS__)
17#define CabcExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_CABCUTIL, e, x, s, __VA_ARGS__)
18#define CabcExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_CABCUTIL, g, x, s, __VA_ARGS__)
19
20
5static const WCHAR CABC_MAGIC_UNICODE_STRING_MARKER = '?'; 21static const WCHAR CABC_MAGIC_UNICODE_STRING_MARKER = '?';
6static const DWORD MAX_CABINET_HEADER_SIZE = 16 * 1024 * 1024; 22static const DWORD MAX_CABINET_HEADER_SIZE = 16 * 1024 * 1024;
7 23
@@ -144,19 +160,19 @@ static HRESULT UtcFileTimeToLocalDosDateTime(
144 __out USHORT* pTime 160 __out USHORT* pTime
145 ); 161 );
146 162
147static __callback int DIAMONDAPI CabCFilePlaced(__in PCCAB pccab, __in_z PSTR szFile, __in long cbFile, __in BOOL fContinuation, __out_bcount(CABC_HANDLE_BYTES) void *pv); 163static __callback int DIAMONDAPI CabCFilePlaced(__in PCCAB pccab, __in_z PSTR szFile, __in long cbFile, __in BOOL fContinuation, __inout_bcount(CABC_HANDLE_BYTES) void *pv);
148static __callback void * DIAMONDAPI CabCAlloc(__in ULONG cb); 164static __callback void * DIAMONDAPI CabCAlloc(__in ULONG cb);
149static __callback void DIAMONDAPI CabCFree(__out_bcount(CABC_HANDLE_BYTES) void *pv); 165static __callback void DIAMONDAPI CabCFree(__out_bcount(CABC_HANDLE_BYTES) void *pv);
150static __callback INT_PTR DIAMONDAPI CabCOpen(__in_z PSTR pszFile, __in int oflag, __in int pmode, __out int *err, __out_bcount(CABC_HANDLE_BYTES) void *pv); 166static __callback INT_PTR DIAMONDAPI CabCOpen(__in_z PSTR pszFile, __in int oflag, __in int pmode, __out int *err, __inout_bcount(CABC_HANDLE_BYTES) void *pv);
151static __callback UINT FAR DIAMONDAPI CabCRead(__in INT_PTR hf, __out_bcount(cb) void FAR *memory, __in UINT cb, __out int *err, __out_bcount(CABC_HANDLE_BYTES) void *pv); 167static __callback UINT FAR DIAMONDAPI CabCRead(__in INT_PTR hf, __out_bcount(cb) void FAR *memory, __in UINT cb, __out int *err, __inout_bcount(CABC_HANDLE_BYTES) void *pv);
152static __callback UINT FAR DIAMONDAPI CabCWrite(__in INT_PTR hf, __in_bcount(cb) void FAR *memory, __in UINT cb, __out int *err, __out_bcount(CABC_HANDLE_BYTES) void *pv); 168static __callback UINT FAR DIAMONDAPI CabCWrite(__in INT_PTR hf, __in_bcount(cb) void FAR *memory, __in UINT cb, __out int *err, __inout_bcount(CABC_HANDLE_BYTES) void *pv);
153static __callback long FAR DIAMONDAPI CabCSeek(__in INT_PTR hf, __in long dist, __in int seektype, __out int *err, __out_bcount(CABC_HANDLE_BYTES) void *pv); 169static __callback long FAR DIAMONDAPI CabCSeek(__in INT_PTR hf, __in long dist, __in int seektype, __out int *err, __inout_bcount(CABC_HANDLE_BYTES) void *pv);
154static __callback int FAR DIAMONDAPI CabCClose(__in INT_PTR hf, __out int *err, __out_bcount(CABC_HANDLE_BYTES) void *pv); 170static __callback int FAR DIAMONDAPI CabCClose(__in INT_PTR hf, __out int *err, __inout_bcount(CABC_HANDLE_BYTES) void *pv);
155static __callback int DIAMONDAPI CabCDelete(__in_z PSTR szFile, __out int *err, __out_bcount(CABC_HANDLE_BYTES) void *pv); 171static __callback int DIAMONDAPI CabCDelete(__in_z PSTR szFile, __out int *err, __inout_bcount(CABC_HANDLE_BYTES) void *pv);
156__success(return != FALSE) static __callback BOOL DIAMONDAPI CabCGetTempFile(__out_bcount_z(cbFile) char *szFile, __in int cbFile, __out_bcount(CABC_HANDLE_BYTES) void *pv); 172__success(return != FALSE) static __callback BOOL DIAMONDAPI CabCGetTempFile(__out_bcount_z(cbFile) char *szFile, __in int cbFile, __inout_bcount(CABC_HANDLE_BYTES) void *pv);
157__success(return != FALSE) static __callback BOOL DIAMONDAPI CabCGetNextCabinet(__in PCCAB pccab, __in ULONG ul, __out_bcount(CABC_HANDLE_BYTES) void *pv); 173__success(return != FALSE) static __callback BOOL DIAMONDAPI CabCGetNextCabinet(__in PCCAB pccab, __in ULONG ul, __out_bcount(CABC_HANDLE_BYTES) void *pv);
158static __callback INT_PTR DIAMONDAPI CabCGetOpenInfo(__in_z PSTR pszName, __out USHORT *pdate, __out USHORT *ptime, __out USHORT *pattribs, __out int *err, __out_bcount(CABC_HANDLE_BYTES) void *pv); 174static __callback INT_PTR DIAMONDAPI CabCGetOpenInfo(__in_z PSTR pszName, __out USHORT *pdate, __out USHORT *ptime, __out USHORT *pattribs, __out int *err, __out_bcount(CABC_HANDLE_BYTES) void *pv);
159static __callback long DIAMONDAPI CabCStatus(__in UINT uiTypeStatus, __in ULONG cb1, __in ULONG cb2, __out_bcount(CABC_HANDLE_BYTES) void *pv); 175static __callback long DIAMONDAPI CabCStatus(__in UINT uiTypeStatus, __in ULONG cb1, __in ULONG cb2, __inout_bcount(CABC_HANDLE_BYTES) void *pv);
160 176
161 177
162/******************************************************************** 178/********************************************************************
@@ -174,7 +190,7 @@ extern "C" HRESULT DAPI CabCBegin(
174 __in DWORD dwMaxSize, 190 __in DWORD dwMaxSize,
175 __in DWORD dwMaxThresh, 191 __in DWORD dwMaxThresh,
176 __in COMPRESSION_TYPE ct, 192 __in COMPRESSION_TYPE ct,
177 __out HANDLE *phContext 193 __out_bcount(CABC_HANDLE_BYTES) HANDLE *phContext
178 ) 194 )
179{ 195{
180 Assert(wzCab && *wzCab && phContext); 196 Assert(wzCab && *wzCab && phContext);
@@ -190,28 +206,28 @@ extern "C" HRESULT DAPI CabCBegin(
190 if (wzCabDir) 206 if (wzCabDir)
191 { 207 {
192 hr = ::StringCchLengthW(wzCabDir, MAX_PATH, &cchPathBuffer); 208 hr = ::StringCchLengthW(wzCabDir, MAX_PATH, &cchPathBuffer);
193 ExitOnFailure(hr, "Failed to get length of cab directory"); 209 CabcExitOnFailure(hr, "Failed to get length of cab directory");
194 210
195 // Need room to terminate with L'\\' and L'\0' 211 // Need room to terminate with L'\\' and L'\0'
196 if((MAX_PATH - 1) <= cchPathBuffer || 0 == cchPathBuffer) 212 if((MAX_PATH - 1) <= cchPathBuffer || 0 == cchPathBuffer)
197 { 213 {
198 hr = E_INVALIDARG; 214 hr = E_INVALIDARG;
199 ExitOnFailure(hr, "Cab directory had invalid length: %u", cchPathBuffer); 215 CabcExitOnFailure(hr, "Cab directory had invalid length: %u", cchPathBuffer);
200 } 216 }
201 217
202 hr = ::StringCchCopyW(wzPathBuffer, countof(wzPathBuffer), wzCabDir); 218 hr = ::StringCchCopyW(wzPathBuffer, countof(wzPathBuffer), wzCabDir);
203 ExitOnFailure(hr, "Failed to copy cab directory to buffer"); 219 CabcExitOnFailure(hr, "Failed to copy cab directory to buffer");
204 220
205 if (L'\\' != wzPathBuffer[cchPathBuffer - 1]) 221 if (L'\\' != wzPathBuffer[cchPathBuffer - 1])
206 { 222 {
207 hr = ::StringCchCatW(wzPathBuffer, countof(wzPathBuffer), L"\\"); 223 hr = ::StringCchCatW(wzPathBuffer, countof(wzPathBuffer), L"\\");
208 ExitOnFailure(hr, "Failed to cat \\ to end of buffer"); 224 CabcExitOnFailure(hr, "Failed to cat \\ to end of buffer");
209 ++cchPathBuffer; 225 ++cchPathBuffer;
210 } 226 }
211 } 227 }
212 228
213 pcd = static_cast<CABC_DATA*>(MemAlloc(sizeof(CABC_DATA), TRUE)); 229 pcd = static_cast<CABC_DATA*>(MemAlloc(sizeof(CABC_DATA), TRUE));
214 ExitOnNull(pcd, hr, E_OUTOFMEMORY, "failed to allocate cab creation data structure"); 230 CabcExitOnNull(pcd, hr, E_OUTOFMEMORY, "failed to allocate cab creation data structure");
215 231
216 pcd->hrLastError = S_OK; 232 pcd->hrLastError = S_OK;
217 pcd->fGoodCab = TRUE; 233 pcd->fGoodCab = TRUE;
@@ -266,35 +282,35 @@ extern "C" HRESULT DAPI CabCBegin(
266 else 282 else
267 { 283 {
268 hr = E_INVALIDARG; 284 hr = E_INVALIDARG;
269 ExitOnFailure(hr, "Invalid compression type specified."); 285 CabcExitOnFailure(hr, "Invalid compression type specified.");
270 } 286 }
271 287
272 if (0 == ::WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wzCab, -1, pcd->ccab.szCab, sizeof(pcd->ccab.szCab), NULL, NULL)) 288 if (0 == ::WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wzCab, -1, pcd->ccab.szCab, sizeof(pcd->ccab.szCab), NULL, NULL))
273 { 289 {
274 ExitWithLastError(hr, "failed to convert cab name to multi-byte"); 290 CabcExitWithLastError(hr, "failed to convert cab name to multi-byte");
275 } 291 }
276 292
277 if (0 == ::WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wzPathBuffer, -1, pcd->ccab.szCabPath, sizeof(pcd->ccab.szCab), NULL, NULL)) 293 if (0 == ::WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wzPathBuffer, -1, pcd->ccab.szCabPath, sizeof(pcd->ccab.szCab), NULL, NULL))
278 { 294 {
279 ExitWithLastError(hr, "failed to convert cab dir to multi-byte"); 295 CabcExitWithLastError(hr, "failed to convert cab dir to multi-byte");
280 } 296 }
281 297
282 // Remember the path to the cabinet. 298 // Remember the path to the cabinet.
283 hr= ::StringCchCopyW(pcd->wzCabinetPath, countof(pcd->wzCabinetPath), wzPathBuffer); 299 hr= ::StringCchCopyW(pcd->wzCabinetPath, countof(pcd->wzCabinetPath), wzPathBuffer);
284 ExitOnFailure(hr, "Failed to copy cabinet path from path: %ls", wzPathBuffer); 300 CabcExitOnFailure(hr, "Failed to copy cabinet path from path: %ls", wzPathBuffer);
285 301
286 hr = ::StringCchCatW(pcd->wzCabinetPath, countof(pcd->wzCabinetPath), wzCab); 302 hr = ::StringCchCatW(pcd->wzCabinetPath, countof(pcd->wzCabinetPath), wzCab);
287 ExitOnFailure(hr, "Failed to concat to cabinet path cabinet name: %ls", wzCab); 303 CabcExitOnFailure(hr, "Failed to concat to cabinet path cabinet name: %ls", wzCab);
288 304
289 // Get the empty file to use as the blank marker for duplicates. 305 // Get the empty file to use as the blank marker for duplicates.
290 if (!::GetTempPathW(countof(wzTempPath), wzTempPath)) 306 if (!::GetTempPathW(countof(wzTempPath), wzTempPath))
291 { 307 {
292 ExitWithLastError(hr, "Failed to get temp path."); 308 CabcExitWithLastError(hr, "Failed to get temp path.");
293 } 309 }
294 310
295 if (!::GetTempFileNameW(wzTempPath, L"WSC", 0, pcd->wzEmptyFile)) 311 if (!::GetTempFileNameW(wzTempPath, L"WSC", 0, pcd->wzEmptyFile))
296 { 312 {
297 ExitWithLastError(hr, "Failed to create a temp file name."); 313 CabcExitWithLastError(hr, "Failed to create a temp file name.");
298 } 314 }
299 315
300 // Try to open the newly created empty file (remember, GetTempFileName() is kind enough to create a file for us) 316 // Try to open the newly created empty file (remember, GetTempFileName() is kind enough to create a file for us)
@@ -303,7 +319,7 @@ extern "C" HRESULT DAPI CabCBegin(
303 pcd->hEmptyFile = ::CreateFileW(pcd->wzEmptyFile, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); 319 pcd->hEmptyFile = ::CreateFileW(pcd->wzEmptyFile, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
304 320
305 hr = DictCreateWithEmbeddedKey(&pcd->shDictHandle, dwMaxFiles, reinterpret_cast<void **>(&pcd->prgFiles), offsetof(CABC_FILE, pwzSourcePath), DICT_FLAG_CASEINSENSITIVE); 321 hr = DictCreateWithEmbeddedKey(&pcd->shDictHandle, dwMaxFiles, reinterpret_cast<void **>(&pcd->prgFiles), offsetof(CABC_FILE, pwzSourcePath), DICT_FLAG_CASEINSENSITIVE);
306 ExitOnFailure(hr, "Failed to create dictionary to keep track of duplicate files"); 322 CabcExitOnFailure(hr, "Failed to create dictionary to keep track of duplicate files");
307 323
308 // Make sure to allocate at least some space, or we won't be able to realloc later if they "lied" about having zero files 324 // Make sure to allocate at least some space, or we won't be able to realloc later if they "lied" about having zero files
309 if (1 > dwMaxFiles) 325 if (1 > dwMaxFiles)
@@ -315,10 +331,10 @@ extern "C" HRESULT DAPI CabCBegin(
315 size_t cbFileAllocSize = 0; 331 size_t cbFileAllocSize = 0;
316 332
317 hr = ::SizeTMult(pcd->cMaxFilePaths, sizeof(CABC_FILE), &(cbFileAllocSize)); 333 hr = ::SizeTMult(pcd->cMaxFilePaths, sizeof(CABC_FILE), &(cbFileAllocSize));
318 ExitOnFailure(hr, "Maximum allocation exceeded on initialization."); 334 CabcExitOnFailure(hr, "Maximum allocation exceeded on initialization.");
319 335
320 pcd->prgFiles = static_cast<CABC_FILE*>(MemAlloc(cbFileAllocSize, TRUE)); 336 pcd->prgFiles = static_cast<CABC_FILE*>(MemAlloc(cbFileAllocSize, TRUE));
321 ExitOnNull(pcd->prgFiles, hr, E_OUTOFMEMORY, "Failed to allocate memory for files."); 337 CabcExitOnNull(pcd->prgFiles, hr, E_OUTOFMEMORY, "Failed to allocate memory for files.");
322 338
323 // Tell cabinet API about our configuration. 339 // Tell cabinet API about our configuration.
324 pcd->hfci = ::FCICreate(&(pcd->erf), CabCFilePlaced, CabCAlloc, CabCFree, CabCOpen, CabCRead, CabCWrite, CabCClose, CabCSeek, CabCDelete, CabCGetTempFile, &(pcd->ccab), pcd); 340 pcd->hfci = ::FCICreate(&(pcd->erf), CabCFilePlaced, CabCAlloc, CabCFree, CabCOpen, CabCRead, CabCWrite, CabCClose, CabCSeek, CabCDelete, CabCGetTempFile, &(pcd->ccab), pcd);
@@ -331,12 +347,12 @@ extern "C" HRESULT DAPI CabCBegin(
331 } 347 }
332 else 348 else
333 { 349 {
334 ExitWithLastError(hr, "failed to create FCI object Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType); 350 CabcExitWithLastError(hr, "failed to create FCI object Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType);
335 } 351 }
336 352
337 pcd->fGoodCab = FALSE; 353 pcd->fGoodCab = FALSE;
338 354
339 ExitOnFailure(hr, "failed to create FCI object Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType); // TODO: can these be converted to HRESULTS? 355 CabcExitOnFailure(hr, "failed to create FCI object Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType); // TODO: can these be converted to HRESULTS?
340 } 356 }
341 357
342 *phContext = pcd; 358 *phContext = pcd;
@@ -392,25 +408,25 @@ extern "C" HRESULT DAPI CabCAddFile(
392 { 408 {
393 // Store file size, primarily used to determine which files to hash for duplicates 409 // Store file size, primarily used to determine which files to hash for duplicates
394 hr = FileSize(wzFile, &llFileSize); 410 hr = FileSize(wzFile, &llFileSize);
395 ExitOnFailure(hr, "Failed to check size of file %ls", wzFile); 411 CabcExitOnFailure(hr, "Failed to check size of file %ls", wzFile);
396 412
397 hr = CheckForDuplicateFile(pcd, &pcfDuplicate, wzFile, &pmfLocalHash, llFileSize); 413 hr = CheckForDuplicateFile(pcd, &pcfDuplicate, wzFile, &pmfLocalHash, llFileSize);
398 ExitOnFailure(hr, "Failed while checking for duplicate of file: %ls", wzFile); 414 CabcExitOnFailure(hr, "Failed while checking for duplicate of file: %ls", wzFile);
399 } 415 }
400 416
401 if (pcfDuplicate) // This will be null for smart cabbing case 417 if (pcfDuplicate) // This will be null for smart cabbing case
402 { 418 {
403 DWORD index; 419 DWORD index;
404 hr = ::PtrdiffTToDWord(pcfDuplicate - pcd->prgFiles, &index); 420 hr = ::PtrdiffTToDWord(pcfDuplicate - pcd->prgFiles, &index);
405 ExitOnFailure(hr, "Failed to calculate index of file name: %ls", pcfDuplicate->pwzSourcePath); 421 CabcExitOnFailure(hr, "Failed to calculate index of file name: %ls", pcfDuplicate->pwzSourcePath);
406 422
407 hr = AddDuplicateFile(pcd, index, wzFile, wzToken, pcd->dwLastFileIndex); 423 hr = AddDuplicateFile(pcd, index, wzFile, wzToken, pcd->dwLastFileIndex);
408 ExitOnFailure(hr, "Failed to add duplicate of file name: %ls", pcfDuplicate->pwzSourcePath); 424 CabcExitOnFailure(hr, "Failed to add duplicate of file name: %ls", pcfDuplicate->pwzSourcePath);
409 } 425 }
410 else 426 else
411 { 427 {
412 hr = AddNonDuplicateFile(pcd, wzFile, wzToken, pmfLocalHash, llFileSize, pcd->dwLastFileIndex); 428 hr = AddNonDuplicateFile(pcd, wzFile, wzToken, pmfLocalHash, llFileSize, pcd->dwLastFileIndex);
413 ExitOnFailure(hr, "Failed to add non-duplicated file: %ls", wzFile); 429 CabcExitOnFailure(hr, "Failed to add non-duplicated file: %ls", wzFile);
414 } 430 }
415 431
416 ++pcd->dwLastFileIndex; 432 ++pcd->dwLastFileIndex;
@@ -483,13 +499,13 @@ extern "C" HRESULT DAPI CabCFinish(
483 { 499 {
484 LPCWSTR pwzTemp = pcd->prgFiles[dwArrayFileIndex].pwzToken; 500 LPCWSTR pwzTemp = pcd->prgFiles[dwArrayFileIndex].pwzToken;
485 hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP); 501 hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP);
486 ExitOnFailure(hr, "failed to convert file token to ANSI: %ls", pwzTemp); 502 CabcExitOnFailure(hr, "failed to convert file token to ANSI: %ls", pwzTemp);
487 } 503 }
488 else 504 else
489 { 505 {
490 LPCWSTR pwzTemp = FileFromPath(fileInfo.wzSourcePath); 506 LPCWSTR pwzTemp = FileFromPath(fileInfo.wzSourcePath);
491 hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP); 507 hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP);
492 ExitOnFailure(hr, "failed to convert file name to ANSI: %ls", pwzTemp); 508 CabcExitOnFailure(hr, "failed to convert file name to ANSI: %ls", pwzTemp);
493 } 509 }
494 510
495 if (pcd->prgFiles[dwArrayFileIndex].fHasDuplicates) 511 if (pcd->prgFiles[dwArrayFileIndex].fHasDuplicates)
@@ -518,13 +534,13 @@ extern "C" HRESULT DAPI CabCFinish(
518 { 534 {
519 LPCWSTR pwzTemp = pcd->prgDuplicates[dwDupeArrayFileIndex].pwzToken; 535 LPCWSTR pwzTemp = pcd->prgDuplicates[dwDupeArrayFileIndex].pwzToken;
520 hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP); 536 hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP);
521 ExitOnFailure(hr, "failed to convert duplicate file token to ANSI: %ls", pwzTemp); 537 CabcExitOnFailure(hr, "failed to convert duplicate file token to ANSI: %ls", pwzTemp);
522 } 538 }
523 else 539 else
524 { 540 {
525 LPCWSTR pwzTemp = FileFromPath(fileInfo.wzSourcePath); 541 LPCWSTR pwzTemp = FileFromPath(fileInfo.wzSourcePath);
526 hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP); 542 hr = StrAnsiAllocString(&pszFileToken, pwzTemp, 0, CP_ACP);
527 ExitOnFailure(hr, "failed to convert duplicate file name to ANSI: %ls", pwzTemp); 543 CabcExitOnFailure(hr, "failed to convert duplicate file name to ANSI: %ls", pwzTemp);
528 } 544 }
529 545
530 // Flush afterward only if this isn't a duplicate of the previous file, and at least one non-duplicate file remains to be added to the cab 546 // Flush afterward only if this isn't a duplicate of the previous file, and at least one non-duplicate file remains to be added to the cab
@@ -543,14 +559,14 @@ extern "C" HRESULT DAPI CabCFinish(
543 else // If it's neither duplicate nor non-duplicate, throw an error 559 else // If it's neither duplicate nor non-duplicate, throw an error
544 { 560 {
545 hr = HRESULT_FROM_WIN32(ERROR_EA_LIST_INCONSISTENT); 561 hr = HRESULT_FROM_WIN32(ERROR_EA_LIST_INCONSISTENT);
546 ExitOnRootFailure(hr, "Internal inconsistency in data structures while creating CAB file - a non-standard, non-duplicate file was encountered"); 562 CabcExitOnRootFailure(hr, "Internal inconsistency in data structures while creating CAB file - a non-standard, non-duplicate file was encountered");
547 } 563 }
548 564
549 if (fFlushBefore && pcd->llBytesSinceLastFlush > pcd->llFlushThreshhold) 565 if (fFlushBefore && pcd->llBytesSinceLastFlush > pcd->llFlushThreshhold)
550 { 566 {
551 if (!::FCIFlushFolder(pcd->hfci, CabCGetNextCabinet, CabCStatus)) 567 if (!::FCIFlushFolder(pcd->hfci, CabCGetNextCabinet, CabCStatus))
552 { 568 {
553 ExitWithLastError(hr, "failed to flush FCI folder before adding file, Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType); 569 CabcExitWithLastError(hr, "failed to flush FCI folder before adding file, Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType);
554 } 570 }
555 pcd->llBytesSinceLastFlush = 0; 571 pcd->llBytesSinceLastFlush = 0;
556 } 572 }
@@ -574,10 +590,10 @@ extern "C" HRESULT DAPI CabCFinish(
574 } 590 }
575 else 591 else
576 { 592 {
577 ExitWithLastError(hr, "failed to add file to FCI object Oper: 0x%x Type: 0x%x File: %ls", pcd->erf.erfOper, pcd->erf.erfType, fileInfo.wzSourcePath); 593 CabcExitWithLastError(hr, "failed to add file to FCI object Oper: 0x%x Type: 0x%x File: %ls", pcd->erf.erfOper, pcd->erf.erfType, fileInfo.wzSourcePath);
578 } 594 }
579 595
580 ExitOnFailure(hr, "failed to add file to FCI object Oper: 0x%x Type: 0x%x File: %ls", pcd->erf.erfOper, pcd->erf.erfType, fileInfo.wzSourcePath); // TODO: can these be converted to HRESULTS? 596 CabcExitOnFailure(hr, "failed to add file to FCI object Oper: 0x%x Type: 0x%x File: %ls", pcd->erf.erfOper, pcd->erf.erfType, fileInfo.wzSourcePath); // TODO: can these be converted to HRESULTS?
581 } 597 }
582 598
583 // For Cabinet Splitting case, check for pcd->hrLastError that may be set as result of Error in CabCGetNextCabinet 599 // For Cabinet Splitting case, check for pcd->hrLastError that may be set as result of Error in CabCGetNextCabinet
@@ -585,14 +601,14 @@ extern "C" HRESULT DAPI CabCFinish(
585 if (pcd->fCabinetSplittingEnabled && FAILED(pcd->hrLastError)) 601 if (pcd->fCabinetSplittingEnabled && FAILED(pcd->hrLastError))
586 { 602 {
587 hr = pcd->hrLastError; 603 hr = pcd->hrLastError;
588 ExitOnFailure(hr, "Failed to create next cabinet name while splitting cabinet."); 604 CabcExitOnFailure(hr, "Failed to create next cabinet name while splitting cabinet.");
589 } 605 }
590 606
591 if (fFlushAfter && pcd->llBytesSinceLastFlush > pcd->llFlushThreshhold) 607 if (fFlushAfter && pcd->llBytesSinceLastFlush > pcd->llFlushThreshhold)
592 { 608 {
593 if (!::FCIFlushFolder(pcd->hfci, CabCGetNextCabinet, CabCStatus)) 609 if (!::FCIFlushFolder(pcd->hfci, CabCGetNextCabinet, CabCStatus))
594 { 610 {
595 ExitWithLastError(hr, "failed to flush FCI folder after adding file, Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType); 611 CabcExitWithLastError(hr, "failed to flush FCI folder after adding file, Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType);
596 } 612 }
597 pcd->llBytesSinceLastFlush = 0; 613 pcd->llBytesSinceLastFlush = 0;
598 } 614 }
@@ -610,10 +626,10 @@ extern "C" HRESULT DAPI CabCFinish(
610 } 626 }
611 else 627 else
612 { 628 {
613 ExitWithLastError(hr, "failed while creating CAB FCI object Oper: 0x%x Type: 0x%x File: %s", pcd->erf.erfOper, pcd->erf.erfType); 629 CabcExitWithLastError(hr, "failed while creating CAB FCI object Oper: 0x%x Type: 0x%x File: %ls", pcd->erf.erfOper, pcd->erf.erfType, fileInfo.wzSourcePath);
614 } 630 }
615 631
616 ExitOnFailure(hr, "failed while creating CAB FCI object Oper: 0x%x Type: 0x%x File: %s", pcd->erf.erfOper, pcd->erf.erfType); // TODO: can these be converted to HRESULTS? 632 CabcExitOnFailure(hr, "failed while creating CAB FCI object Oper: 0x%x Type: 0x%x File: %ls", pcd->erf.erfOper, pcd->erf.erfType, fileInfo.wzSourcePath); // TODO: can these be converted to HRESULTS?
617 } 633 }
618 634
619 // Only flush the cabinet if we actually succeeded in previous calls - otherwise we just waste time (a lot on big cabs) 635 // Only flush the cabinet if we actually succeeded in previous calls - otherwise we just waste time (a lot on big cabs)
@@ -621,13 +637,13 @@ extern "C" HRESULT DAPI CabCFinish(
621 { 637 {
622 // If we have a last error, use that, otherwise return the useless error 638 // If we have a last error, use that, otherwise return the useless error
623 hr = FAILED(pcd->hrLastError) ? pcd->hrLastError : E_FAIL; 639 hr = FAILED(pcd->hrLastError) ? pcd->hrLastError : E_FAIL;
624 ExitOnFailure(hr, "failed to flush FCI object Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType); // TODO: can these be converted to HRESULTS? 640 CabcExitOnFailure(hr, "failed to flush FCI object Oper: 0x%x Type: 0x%x", pcd->erf.erfOper, pcd->erf.erfType); // TODO: can these be converted to HRESULTS?
625 } 641 }
626 642
627 if (pcd->fGoodCab && pcd->cDuplicates) 643 if (pcd->fGoodCab && pcd->cDuplicates)
628 { 644 {
629 hr = UpdateDuplicateFiles(pcd); 645 hr = UpdateDuplicateFiles(pcd);
630 ExitOnFailure(hr, "Failed to update duplicates in cabinet: %ls", pcd->wzCabinetPath); 646 CabcExitOnFailure(hr, "Failed to update duplicates in cabinet: %ls", pcd->wzCabinetPath);
631 } 647 }
632 648
633LExit: 649LExit:
@@ -697,8 +713,8 @@ static HRESULT CheckForDuplicateFile(
697 HRESULT hr = S_OK; 713 HRESULT hr = S_OK;
698 UINT er = ERROR_SUCCESS; 714 UINT er = ERROR_SUCCESS;
699 715
700 ExitOnNull(ppcf, hr, E_INVALIDARG, "No file structure sent while checking for duplicate file"); 716 CabcExitOnNull(ppcf, hr, E_INVALIDARG, "No file structure sent while checking for duplicate file");
701 ExitOnNull(ppmfHash, hr, E_INVALIDARG, "No file hash structure pointer sent while checking for duplicate file"); 717 CabcExitOnNull(ppmfHash, hr, E_INVALIDARG, "No file hash structure pointer sent while checking for duplicate file");
702 718
703 *ppcf = NULL; // By default, we'll set our output to NULL 719 *ppcf = NULL; // By default, we'll set our output to NULL
704 720
@@ -712,7 +728,7 @@ static HRESULT CheckForDuplicateFile(
712 { 728 {
713 hr = S_OK; 729 hr = S_OK;
714 } 730 }
715 ExitOnFailure(hr, "Failed while searching for file in dictionary of previously added files"); 731 CabcExitOnFailure(hr, "Failed while searching for file in dictionary of previously added files");
716 732
717 for (i = 0; i < pcd->cFilePaths; ++i) 733 for (i = 0; i < pcd->cFilePaths; ++i)
718 { 734 {
@@ -723,22 +739,22 @@ static HRESULT CheckForDuplicateFile(
723 if (pcd->prgFiles[i].pmfHash == NULL) 739 if (pcd->prgFiles[i].pmfHash == NULL)
724 { 740 {
725 pcd->prgFiles[i].pmfHash = (PMSIFILEHASHINFO)MemAlloc(sizeof(MSIFILEHASHINFO), FALSE); 741 pcd->prgFiles[i].pmfHash = (PMSIFILEHASHINFO)MemAlloc(sizeof(MSIFILEHASHINFO), FALSE);
726 ExitOnNull(pcd->prgFiles[i].pmfHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for candidate duplicate file's MSI file hash"); 742 CabcExitOnNull(pcd->prgFiles[i].pmfHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for candidate duplicate file's MSI file hash");
727 743
728 pcd->prgFiles[i].pmfHash->dwFileHashInfoSize = sizeof(MSIFILEHASHINFO); 744 pcd->prgFiles[i].pmfHash->dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
729 er = ::MsiGetFileHashW(pcd->prgFiles[i].pwzSourcePath, 0, pcd->prgFiles[i].pmfHash); 745 er = ::MsiGetFileHashW(pcd->prgFiles[i].pwzSourcePath, 0, pcd->prgFiles[i].pmfHash);
730 ExitOnWin32Error(er, hr, "Failed while getting MSI file hash of candidate duplicate file: %ls", pcd->prgFiles[i].pwzSourcePath); 746 CabcExitOnWin32Error(er, hr, "Failed while getting MSI file hash of candidate duplicate file: %ls", pcd->prgFiles[i].pwzSourcePath);
731 } 747 }
732 748
733 // If our own file hasn't yet been hashed, hash it 749 // If our own file hasn't yet been hashed, hash it
734 if (NULL == *ppmfHash) 750 if (NULL == *ppmfHash)
735 { 751 {
736 *ppmfHash = (PMSIFILEHASHINFO)MemAlloc(sizeof(MSIFILEHASHINFO), FALSE); 752 *ppmfHash = (PMSIFILEHASHINFO)MemAlloc(sizeof(MSIFILEHASHINFO), FALSE);
737 ExitOnNull(*ppmfHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for file's MSI file hash"); 753 CabcExitOnNull(*ppmfHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for file's MSI file hash");
738 754
739 (*ppmfHash)->dwFileHashInfoSize = sizeof(MSIFILEHASHINFO); 755 (*ppmfHash)->dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
740 er = ::MsiGetFileHashW(wzFileName, 0, *ppmfHash); 756 er = ::MsiGetFileHashW(wzFileName, 0, *ppmfHash);
741 ExitOnWin32Error(er, hr, "Failed while getting MSI file hash of file: %ls", pcd->prgFiles[i].pwzSourcePath); 757 CabcExitOnWin32Error(er, hr, "Failed while getting MSI file hash of file: %ls", pcd->prgFiles[i].pwzSourcePath);
742 } 758 }
743 759
744 // If the two file hashes are both of the expected size, and they match, we've got a match, so return it! 760 // If the two file hashes are both of the expected size, and they match, we've got a match, so return it!
@@ -779,17 +795,17 @@ static HRESULT AddDuplicateFile(
779 size_t cbDuplicates = 0; 795 size_t cbDuplicates = 0;
780 796
781 hr = ::SizeTMult(pcd->cMaxDuplicates, sizeof(CABC_DUPLICATEFILE), &cbDuplicates); 797 hr = ::SizeTMult(pcd->cMaxDuplicates, sizeof(CABC_DUPLICATEFILE), &cbDuplicates);
782 ExitOnFailure(hr, "Maximum allocation exceeded."); 798 CabcExitOnFailure(hr, "Maximum allocation exceeded.");
783 799
784 if (pcd->cDuplicates) 800 if (pcd->cDuplicates)
785 { 801 {
786 pv = MemReAlloc(pcd->prgDuplicates, cbDuplicates, FALSE); 802 pv = MemReAlloc(pcd->prgDuplicates, cbDuplicates, FALSE);
787 ExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to reallocate memory for duplicate file."); 803 CabcExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to reallocate memory for duplicate file.");
788 } 804 }
789 else 805 else
790 { 806 {
791 pv = MemAlloc(cbDuplicates, FALSE); 807 pv = MemAlloc(cbDuplicates, FALSE);
792 ExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to allocate memory for duplicate file."); 808 CabcExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to allocate memory for duplicate file.");
793 } 809 }
794 810
795 ZeroMemory(reinterpret_cast<BYTE*>(pv) + (pcd->cDuplicates * sizeof(CABC_DUPLICATEFILE)), (pcd->cMaxDuplicates - pcd->cDuplicates) * sizeof(CABC_DUPLICATEFILE)); 811 ZeroMemory(reinterpret_cast<BYTE*>(pv) + (pcd->cDuplicates * sizeof(CABC_DUPLICATEFILE)), (pcd->cMaxDuplicates - pcd->cDuplicates) * sizeof(CABC_DUPLICATEFILE));
@@ -804,12 +820,12 @@ static HRESULT AddDuplicateFile(
804 pcd->prgFiles[dwFileArrayIndex].fHasDuplicates = TRUE; // Mark original file as having duplicates 820 pcd->prgFiles[dwFileArrayIndex].fHasDuplicates = TRUE; // Mark original file as having duplicates
805 821
806 hr = StrAllocString(&pcd->prgDuplicates[pcd->cDuplicates].pwzSourcePath, wzSourcePath, 0); 822 hr = StrAllocString(&pcd->prgDuplicates[pcd->cDuplicates].pwzSourcePath, wzSourcePath, 0);
807 ExitOnFailure(hr, "Failed to copy duplicate file path: %ls", wzSourcePath); 823 CabcExitOnFailure(hr, "Failed to copy duplicate file path: %ls", wzSourcePath);
808 824
809 if (wzToken && *wzToken) 825 if (wzToken && *wzToken)
810 { 826 {
811 hr = StrAllocString(&pcd->prgDuplicates[pcd->cDuplicates].pwzToken, wzToken, 0); 827 hr = StrAllocString(&pcd->prgDuplicates[pcd->cDuplicates].pwzToken, wzToken, 0);
812 ExitOnFailure(hr, "Failed to copy duplicate file token: %ls", wzToken); 828 CabcExitOnFailure(hr, "Failed to copy duplicate file token: %ls", wzToken);
813 } 829 }
814 830
815 ++pcd->cDuplicates; 831 ++pcd->cDuplicates;
@@ -839,10 +855,10 @@ static HRESULT AddNonDuplicateFile(
839 size_t cbFilePaths = 0; 855 size_t cbFilePaths = 0;
840 856
841 hr = ::SizeTMult(pcd->cMaxFilePaths, sizeof(CABC_FILE), &cbFilePaths); 857 hr = ::SizeTMult(pcd->cMaxFilePaths, sizeof(CABC_FILE), &cbFilePaths);
842 ExitOnFailure(hr, "Maximum allocation exceeded."); 858 CabcExitOnFailure(hr, "Maximum allocation exceeded.");
843 859
844 pv = MemReAlloc(pcd->prgFiles, cbFilePaths, FALSE); 860 pv = MemReAlloc(pcd->prgFiles, cbFilePaths, FALSE);
845 ExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to reallocate memory for file."); 861 CabcExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to reallocate memory for file.");
846 862
847 ZeroMemory(reinterpret_cast<BYTE*>(pv) + (pcd->cFilePaths * sizeof(CABC_FILE)), (pcd->cMaxFilePaths - pcd->cFilePaths) * sizeof(CABC_FILE)); 863 ZeroMemory(reinterpret_cast<BYTE*>(pv) + (pcd->cFilePaths * sizeof(CABC_FILE)), (pcd->cMaxFilePaths - pcd->cFilePaths) * sizeof(CABC_FILE));
848 864
@@ -859,7 +875,7 @@ static HRESULT AddNonDuplicateFile(
859 if (pmfHash && sizeof(MSIFILEHASHINFO) == pmfHash->dwFileHashInfoSize) 875 if (pmfHash && sizeof(MSIFILEHASHINFO) == pmfHash->dwFileHashInfoSize)
860 { 876 {
861 pcf->pmfHash = (PMSIFILEHASHINFO)MemAlloc(sizeof(MSIFILEHASHINFO), FALSE); 877 pcf->pmfHash = (PMSIFILEHASHINFO)MemAlloc(sizeof(MSIFILEHASHINFO), FALSE);
862 ExitOnNull(pcf->pmfHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for individual file's MSI file hash"); 878 CabcExitOnNull(pcf->pmfHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for individual file's MSI file hash");
863 879
864 pcf->pmfHash->dwFileHashInfoSize = sizeof(MSIFILEHASHINFO); 880 pcf->pmfHash->dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
865 pcf->pmfHash->dwData[0] = pmfHash->dwData[0]; 881 pcf->pmfHash->dwData[0] = pmfHash->dwData[0];
@@ -869,18 +885,18 @@ static HRESULT AddNonDuplicateFile(
869 } 885 }
870 886
871 hr = StrAllocString(&pcf->pwzSourcePath, wzFile, 0); 887 hr = StrAllocString(&pcf->pwzSourcePath, wzFile, 0);
872 ExitOnFailure(hr, "Failed to copy file path: %ls", wzFile); 888 CabcExitOnFailure(hr, "Failed to copy file path: %ls", wzFile);
873 889
874 if (wzToken && *wzToken) 890 if (wzToken && *wzToken)
875 { 891 {
876 hr = StrAllocString(&pcf->pwzToken, wzToken, 0); 892 hr = StrAllocString(&pcf->pwzToken, wzToken, 0);
877 ExitOnFailure(hr, "Failed to copy file token: %ls", wzToken); 893 CabcExitOnFailure(hr, "Failed to copy file token: %ls", wzToken);
878 } 894 }
879 895
880 ++pcd->cFilePaths; 896 ++pcd->cFilePaths;
881 897
882 hr = DictAddValue(pcd->shDictHandle, pcf); 898 hr = DictAddValue(pcd->shDictHandle, pcf);
883 ExitOnFailure(hr, "Failed to add file to dictionary of added files"); 899 CabcExitOnFailure(hr, "Failed to add file to dictionary of added files");
884 900
885LExit: 901LExit:
886 ReleaseMem(pv); 902 ReleaseMem(pv);
@@ -903,14 +919,14 @@ static HRESULT UpdateDuplicateFiles(
903 hCabinet = ::CreateFileW(pcd->wzCabinetPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 919 hCabinet = ::CreateFileW(pcd->wzCabinetPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
904 if (INVALID_HANDLE_VALUE == hCabinet) 920 if (INVALID_HANDLE_VALUE == hCabinet)
905 { 921 {
906 ExitWithLastError(hr, "Failed to open cabinet: %ls", pcd->wzCabinetPath); 922 CabcExitWithLastError(hr, "Failed to open cabinet: %ls", pcd->wzCabinetPath);
907 } 923 }
908 924
909 // Shouldn't need more than 16 MB to get the whole cabinet header into memory so use that as 925 // Shouldn't need more than 16 MB to get the whole cabinet header into memory so use that as
910 // the upper bound for the memory map. 926 // the upper bound for the memory map.
911 if (!::GetFileSizeEx(hCabinet, &liCabinetSize)) 927 if (!::GetFileSizeEx(hCabinet, &liCabinetSize))
912 { 928 {
913 ExitWithLastError(hr, "Failed to get size of cabinet: %ls", pcd->wzCabinetPath); 929 CabcExitWithLastError(hr, "Failed to get size of cabinet: %ls", pcd->wzCabinetPath);
914 } 930 }
915 931
916 if (0 == liCabinetSize.HighPart && liCabinetSize.LowPart < MAX_CABINET_HEADER_SIZE) 932 if (0 == liCabinetSize.HighPart && liCabinetSize.LowPart < MAX_CABINET_HEADER_SIZE)
@@ -926,11 +942,11 @@ static HRESULT UpdateDuplicateFiles(
926 hCabinetMapping = ::CreateFileMappingW(hCabinet, NULL, PAGE_READWRITE | SEC_COMMIT, 0, cbCabinet, NULL); 942 hCabinetMapping = ::CreateFileMappingW(hCabinet, NULL, PAGE_READWRITE | SEC_COMMIT, 0, cbCabinet, NULL);
927 if (NULL == hCabinetMapping || INVALID_HANDLE_VALUE == hCabinetMapping) 943 if (NULL == hCabinetMapping || INVALID_HANDLE_VALUE == hCabinetMapping)
928 { 944 {
929 ExitWithLastError(hr, "Failed to memory map cabinet file: %ls", pcd->wzCabinetPath); 945 CabcExitWithLastError(hr, "Failed to memory map cabinet file: %ls", pcd->wzCabinetPath);
930 } 946 }
931 947
932 pv = ::MapViewOfFile(hCabinetMapping, FILE_MAP_WRITE, 0, 0, 0); 948 pv = ::MapViewOfFile(hCabinetMapping, FILE_MAP_WRITE, 0, 0, 0);
933 ExitOnNullWithLastError(pv, hr, "Failed to map view of cabinet file: %ls", pcd->wzCabinetPath); 949 CabcExitOnNullWithLastError(pv, hr, "Failed to map view of cabinet file: %ls", pcd->wzCabinetPath);
934 950
935 pCabinetHeader = static_cast<MS_CABINET_HEADER*>(pv); 951 pCabinetHeader = static_cast<MS_CABINET_HEADER*>(pv);
936 952
@@ -939,7 +955,7 @@ static HRESULT UpdateDuplicateFiles(
939 const CABC_DUPLICATEFILE *pDuplicateFile = pcd->prgDuplicates + i; 955 const CABC_DUPLICATEFILE *pDuplicateFile = pcd->prgDuplicates + i;
940 956
941 hr = DuplicateFile(pCabinetHeader, pcd, pDuplicateFile); 957 hr = DuplicateFile(pCabinetHeader, pcd, pDuplicateFile);
942 ExitOnFailure(hr, "Failed to find cabinet file items at index: %d and %d", pDuplicateFile->dwFileArrayIndex, pDuplicateFile->dwDuplicateCabFileIndex); 958 CabcExitOnFailure(hr, "Failed to find cabinet file items at index: %d and %d", pDuplicateFile->dwFileArrayIndex, pDuplicateFile->dwDuplicateCabFileIndex);
943 } 959 }
944 960
945LExit: 961LExit:
@@ -974,7 +990,7 @@ static HRESULT DuplicateFile(
974 pDuplicate->dwDuplicateCabFileIndex <= pcd->prgFiles[pDuplicate->dwFileArrayIndex].dwCabFileIndex) 990 pDuplicate->dwDuplicateCabFileIndex <= pcd->prgFiles[pDuplicate->dwFileArrayIndex].dwCabFileIndex)
975 { 991 {
976 hr = E_UNEXPECTED; 992 hr = E_UNEXPECTED;
977 ExitOnFailure(hr, "Unexpected duplicate file indices, header cFiles: %d, file index: %d, duplicate index: %d", pHeader->cFiles, pcd->prgFiles[pDuplicate->dwFileArrayIndex].dwCabFileIndex, pDuplicate->dwDuplicateCabFileIndex); 993 CabcExitOnFailure(hr, "Unexpected duplicate file indices, header cFiles: %d, file index: %d, duplicate index: %d", pHeader->cFiles, pcd->prgFiles[pDuplicate->dwFileArrayIndex].dwCabFileIndex, pDuplicate->dwDuplicateCabFileIndex);
978 } 994 }
979 995
980 // Step through each cabinet items until we get to the original 996 // Step through each cabinet items until we get to the original
@@ -1002,7 +1018,7 @@ static HRESULT DuplicateFile(
1002 if (0 != pDuplicateItem->cbFile) 1018 if (0 != pDuplicateItem->cbFile)
1003 { 1019 {
1004 hr = E_UNEXPECTED; 1020 hr = E_UNEXPECTED;
1005 ExitOnFailure(hr, "Failed because duplicate file does not have a file size of zero: %d", pDuplicateItem->cbFile); 1021 CabcExitOnFailure(hr, "Failed because duplicate file does not have a file size of zero: %d", pDuplicateItem->cbFile);
1006 } 1022 }
1007 1023
1008 pDuplicateItem->cbFile = pOriginalItem->cbFile; 1024 pDuplicateItem->cbFile = pOriginalItem->cbFile;
@@ -1031,12 +1047,12 @@ static HRESULT UtcFileTimeToLocalDosDateTime(
1031 1047
1032 if (!::FileTimeToLocalFileTime(pFileTime, &ftLocal)) 1048 if (!::FileTimeToLocalFileTime(pFileTime, &ftLocal))
1033 { 1049 {
1034 ExitWithLastError(hr, "Filed to convert file time to local file time."); 1050 CabcExitWithLastError(hr, "Filed to convert file time to local file time.");
1035 } 1051 }
1036 1052
1037 if (!::FileTimeToDosDateTime(&ftLocal, pDate, pTime)) 1053 if (!::FileTimeToDosDateTime(&ftLocal, pDate, pTime))
1038 { 1054 {
1039 ExitWithLastError(hr, "Filed to convert file time to DOS date time."); 1055 CabcExitWithLastError(hr, "Filed to convert file time to DOS date time.");
1040 } 1056 }
1041 1057
1042LExit: 1058LExit:
@@ -1053,7 +1069,7 @@ static __callback int DIAMONDAPI CabCFilePlaced(
1053 __in_z PSTR szFile, 1069 __in_z PSTR szFile,
1054 __in long cbFile, 1070 __in long cbFile,
1055 __in BOOL fContinuation, 1071 __in BOOL fContinuation,
1056 __out_bcount(CABC_HANDLE_BYTES) void *pv 1072 __inout_bcount(CABC_HANDLE_BYTES) void *pv
1057 ) 1073 )
1058{ 1074{
1059 UNREFERENCED_PARAMETER(pccab); 1075 UNREFERENCED_PARAMETER(pccab);
@@ -1085,7 +1101,7 @@ static __callback INT_PTR DIAMONDAPI CabCOpen(
1085 __in int oflag, 1101 __in int oflag,
1086 __in int pmode, 1102 __in int pmode,
1087 __out int *err, 1103 __out int *err,
1088 __out_bcount(CABC_HANDLE_BYTES) void *pv 1104 __inout_bcount(CABC_HANDLE_BYTES) void *pv
1089 ) 1105 )
1090{ 1106{
1091 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv); 1107 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv);
@@ -1139,7 +1155,7 @@ static __callback INT_PTR DIAMONDAPI CabCOpen(
1139 1155
1140 if (INVALID_HANDLE_VALUE == reinterpret_cast<HANDLE>(pFile)) 1156 if (INVALID_HANDLE_VALUE == reinterpret_cast<HANDLE>(pFile))
1141 { 1157 {
1142 ExitOnLastError(hr, "failed to open file: %s", pszFile); 1158 CabcExitOnLastError(hr, "failed to open file: %s", pszFile);
1143 } 1159 }
1144 1160
1145LExit: 1161LExit:
@@ -1155,18 +1171,18 @@ static __callback UINT FAR DIAMONDAPI CabCRead(
1155 __out_bcount(cb) void FAR *memory, 1171 __out_bcount(cb) void FAR *memory,
1156 __in UINT cb, 1172 __in UINT cb,
1157 __out int *err, 1173 __out int *err,
1158 __out_bcount(CABC_HANDLE_BYTES) void *pv 1174 __inout_bcount(CABC_HANDLE_BYTES) void *pv
1159 ) 1175 )
1160{ 1176{
1161 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv); 1177 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv);
1162 HRESULT hr = S_OK; 1178 HRESULT hr = S_OK;
1163 DWORD cbRead = 0; 1179 DWORD cbRead = 0;
1164 1180
1165 ExitOnNull(hf, *err, E_INVALIDARG, "Failed to read during cabinet extraction because no file handle was provided"); 1181 CabcExitOnNull(hf, *err, E_INVALIDARG, "Failed to read during cabinet extraction because no file handle was provided");
1166 if (!::ReadFile(reinterpret_cast<HANDLE>(hf), memory, cb, &cbRead, NULL)) 1182 if (!::ReadFile(reinterpret_cast<HANDLE>(hf), memory, cb, &cbRead, NULL))
1167 { 1183 {
1168 *err = ::GetLastError(); 1184 *err = ::GetLastError();
1169 ExitOnLastError(hr, "failed to read during cabinet extraction"); 1185 CabcExitOnLastError(hr, "failed to read during cabinet extraction");
1170 } 1186 }
1171 1187
1172LExit: 1188LExit:
@@ -1184,18 +1200,18 @@ static __callback UINT FAR DIAMONDAPI CabCWrite(
1184 __in_bcount(cb) void FAR *memory, 1200 __in_bcount(cb) void FAR *memory,
1185 __in UINT cb, 1201 __in UINT cb,
1186 __out int *err, 1202 __out int *err,
1187 __out_bcount(CABC_HANDLE_BYTES) void *pv 1203 __inout_bcount(CABC_HANDLE_BYTES) void *pv
1188 ) 1204 )
1189{ 1205{
1190 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv); 1206 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv);
1191 HRESULT hr = S_OK; 1207 HRESULT hr = S_OK;
1192 DWORD cbWrite = 0; 1208 DWORD cbWrite = 0;
1193 1209
1194 ExitOnNull(hf, *err, E_INVALIDARG, "Failed to write during cabinet extraction because no file handle was provided"); 1210 CabcExitOnNull(hf, *err, E_INVALIDARG, "Failed to write during cabinet extraction because no file handle was provided");
1195 if (!::WriteFile(reinterpret_cast<HANDLE>(hf), memory, cb, &cbWrite, NULL)) 1211 if (!::WriteFile(reinterpret_cast<HANDLE>(hf), memory, cb, &cbWrite, NULL))
1196 { 1212 {
1197 *err = ::GetLastError(); 1213 *err = ::GetLastError();
1198 ExitOnLastError(hr, "failed to write during cabinet extraction"); 1214 CabcExitOnLastError(hr, "failed to write during cabinet extraction");
1199 } 1215 }
1200 1216
1201LExit: 1217LExit:
@@ -1211,7 +1227,7 @@ static __callback long FAR DIAMONDAPI CabCSeek(
1211 __in long dist, 1227 __in long dist,
1212 __in int seektype, 1228 __in int seektype,
1213 __out int *err, 1229 __out int *err,
1214 __out_bcount(CABC_HANDLE_BYTES) void *pv 1230 __inout_bcount(CABC_HANDLE_BYTES) void *pv
1215 ) 1231 )
1216{ 1232{
1217 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv); 1233 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv);
@@ -1233,7 +1249,7 @@ static __callback long FAR DIAMONDAPI CabCSeek(
1233 default : 1249 default :
1234 dwMoveMethod = 0; 1250 dwMoveMethod = 0;
1235 hr = E_UNEXPECTED; 1251 hr = E_UNEXPECTED;
1236 ExitOnFailure(hr, "unexpected seektype in FCISeek(): %d", seektype); 1252 CabcExitOnFailure(hr, "unexpected seektype in FCISeek(): %d", seektype);
1237 } 1253 }
1238 1254
1239 // SetFilePointer returns -1 if it fails (this will cause FDI to quit with an FDIERROR_USER_ABORT error. 1255 // SetFilePointer returns -1 if it fails (this will cause FDI to quit with an FDIERROR_USER_ABORT error.
@@ -1243,7 +1259,7 @@ static __callback long FAR DIAMONDAPI CabCSeek(
1243 if (DWORD_MAX == lMove) 1259 if (DWORD_MAX == lMove)
1244 { 1260 {
1245 *err = ::GetLastError(); 1261 *err = ::GetLastError();
1246 ExitOnLastError(hr, "failed to move file pointer %d bytes", dist); 1262 CabcExitOnLastError(hr, "failed to move file pointer %d bytes", dist);
1247 } 1263 }
1248 1264
1249LExit: 1265LExit:
@@ -1259,7 +1275,7 @@ LExit:
1259static __callback int FAR DIAMONDAPI CabCClose( 1275static __callback int FAR DIAMONDAPI CabCClose(
1260 __in INT_PTR hf, 1276 __in INT_PTR hf,
1261 __out int *err, 1277 __out int *err,
1262 __out_bcount(CABC_HANDLE_BYTES) void *pv 1278 __inout_bcount(CABC_HANDLE_BYTES) void *pv
1263 ) 1279 )
1264{ 1280{
1265 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv); 1281 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv);
@@ -1268,7 +1284,7 @@ static __callback int FAR DIAMONDAPI CabCClose(
1268 if (!::CloseHandle(reinterpret_cast<HANDLE>(hf))) 1284 if (!::CloseHandle(reinterpret_cast<HANDLE>(hf)))
1269 { 1285 {
1270 *err = ::GetLastError(); 1286 *err = ::GetLastError();
1271 ExitOnLastError(hr, "failed to close file during cabinet extraction"); 1287 CabcExitOnLastError(hr, "failed to close file during cabinet extraction");
1272 } 1288 }
1273 1289
1274LExit: 1290LExit:
@@ -1283,7 +1299,7 @@ LExit:
1283static __callback int DIAMONDAPI CabCDelete( 1299static __callback int DIAMONDAPI CabCDelete(
1284 __in_z PSTR szFile, 1300 __in_z PSTR szFile,
1285 __out int *err, 1301 __out int *err,
1286 __out_bcount(CABC_HANDLE_BYTES) void *pv 1302 __inout_bcount(CABC_HANDLE_BYTES) void *pv
1287 ) 1303 )
1288{ 1304{
1289 UNREFERENCED_PARAMETER(err); 1305 UNREFERENCED_PARAMETER(err);
@@ -1302,7 +1318,7 @@ __success(return != FALSE)
1302static __callback BOOL DIAMONDAPI CabCGetTempFile( 1318static __callback BOOL DIAMONDAPI CabCGetTempFile(
1303 __out_bcount_z(cbFile) char *szFile, 1319 __out_bcount_z(cbFile) char *szFile,
1304 __in int cbFile, 1320 __in int cbFile,
1305 __out_bcount(CABC_HANDLE_BYTES) void *pv 1321 __inout_bcount(CABC_HANDLE_BYTES) void *pv
1306 ) 1322 )
1307{ 1323{
1308 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv); 1324 CABC_DATA *pcd = reinterpret_cast<CABC_DATA*>(pv);
@@ -1316,7 +1332,7 @@ static __callback BOOL DIAMONDAPI CabCGetTempFile(
1316 1332
1317 if (MAX_PATH < ::GetTempPathA(cchTempPath, szTempPath)) 1333 if (MAX_PATH < ::GetTempPathA(cchTempPath, szTempPath))
1318 { 1334 {
1319 ExitWithLastError(hr, "Failed to get temp path during cabinet creation."); 1335 CabcExitWithLastError(hr, "Failed to get temp path during cabinet creation.");
1320 } 1336 }
1321 1337
1322 for (DWORD i = 0; i < DWORD_MAX; ++i) 1338 for (DWORD i = 0; i < DWORD_MAX; ++i)
@@ -1324,7 +1340,7 @@ static __callback BOOL DIAMONDAPI CabCGetTempFile(
1324 LONG dwTempIndex = ::InterlockedIncrement(reinterpret_cast<volatile LONG*>(&dwIndex)); 1340 LONG dwTempIndex = ::InterlockedIncrement(reinterpret_cast<volatile LONG*>(&dwIndex));
1325 1341
1326 hr = ::StringCbPrintfA(szFile, cbFile, "%s\\%08x.%03x", szTempPath, dwTempIndex, dwProcessId); 1342 hr = ::StringCbPrintfA(szFile, cbFile, "%s\\%08x.%03x", szTempPath, dwTempIndex, dwProcessId);
1327 ExitOnFailure(hr, "failed to format log file path."); 1343 CabcExitOnFailure(hr, "failed to format log file path.");
1328 1344
1329 hTempFile = ::CreateFileA(szFile, 0, FILE_SHARE_DELETE, NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); 1345 hTempFile = ::CreateFileA(szFile, 0, FILE_SHARE_DELETE, NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
1330 if (INVALID_HANDLE_VALUE != hTempFile) 1346 if (INVALID_HANDLE_VALUE != hTempFile)
@@ -1338,7 +1354,7 @@ static __callback BOOL DIAMONDAPI CabCGetTempFile(
1338 hr = E_FAIL; // this file was taken so be pessimistic and assume we're not going to find one. 1354 hr = E_FAIL; // this file was taken so be pessimistic and assume we're not going to find one.
1339 } 1355 }
1340 } 1356 }
1341 ExitOnFailure(hr, "failed to find temporary file."); 1357 CabcExitOnFailure(hr, "failed to find temporary file.");
1342 1358
1343LExit: 1359LExit:
1344 ReleaseFileHandle(hTempFile); 1360 ReleaseFileHandle(hTempFile);
@@ -1377,7 +1393,7 @@ static __callback BOOL DIAMONDAPI CabCGetNextCabinet(
1377 len -= 4; // remove Extention ".cab" of 8.3 Format 1393 len -= 4; // remove Extention ".cab" of 8.3 Format
1378 } 1394 }
1379 hr = ::StringCchCatNW(pcd->wzFirstCabinetName, countof(pcd->wzFirstCabinetName), pwzCabinetName, len); 1395 hr = ::StringCchCatNW(pcd->wzFirstCabinetName, countof(pcd->wzFirstCabinetName), pwzCabinetName, len);
1380 ExitOnFailure(hr, "Failed to remove extension to create next Cabinet File Name"); 1396 CabcExitOnFailure(hr, "Failed to remove extension to create next Cabinet File Name");
1381 } 1397 }
1382 1398
1383 const int nAlphabets = 26; // Number of Alphabets from a to z 1399 const int nAlphabets = 26; // Number of Alphabets from a to z
@@ -1385,9 +1401,9 @@ static __callback BOOL DIAMONDAPI CabCGetNextCabinet(
1385 { 1401 {
1386 // Construct next cab names like cab1a.cab, cab1b.cab, cab1c.cab, ........ 1402 // Construct next cab names like cab1a.cab, cab1b.cab, cab1c.cab, ........
1387 hr = ::StringCchPrintfA(pccab->szCab, sizeof(pccab->szCab), "%ls%c.cab", pcd->wzFirstCabinetName, char(((int)('a') - 1) + pccab->iCab)); 1403 hr = ::StringCchPrintfA(pccab->szCab, sizeof(pccab->szCab), "%ls%c.cab", pcd->wzFirstCabinetName, char(((int)('a') - 1) + pccab->iCab));
1388 ExitOnFailure(hr, "Failed to create next Cabinet File Name"); 1404 CabcExitOnFailure(hr, "Failed to create next Cabinet File Name");
1389 hr = ::StringCchPrintfW(wzNewCabName, countof(wzNewCabName), L"%ls%c.cab", pcd->wzFirstCabinetName, WCHAR(((int)('a') - 1) + pccab->iCab)); 1405 hr = ::StringCchPrintfW(wzNewCabName, countof(wzNewCabName), L"%ls%c.cab", pcd->wzFirstCabinetName, WCHAR(((int)('a') - 1) + pccab->iCab));
1390 ExitOnFailure(hr, "Failed to create next Cabinet File Name"); 1406 CabcExitOnFailure(hr, "Failed to create next Cabinet File Name");
1391 } 1407 }
1392 else if (pccab->iCab <= nAlphabets*nAlphabets) 1408 else if (pccab->iCab <= nAlphabets*nAlphabets)
1393 { 1409 {
@@ -1401,14 +1417,14 @@ static __callback BOOL DIAMONDAPI CabCGetNextCabinet(
1401 char1--; // First Char must be decremented by 1 1417 char1--; // First Char must be decremented by 1
1402 } 1418 }
1403 hr = ::StringCchPrintfA(pccab->szCab, sizeof(pccab->szCab), "%ls%c%c.cab", pcd->wzFirstCabinetName, char(((int)('a') - 1) + char1), char(((int)('a') - 1) + char2)); 1419 hr = ::StringCchPrintfA(pccab->szCab, sizeof(pccab->szCab), "%ls%c%c.cab", pcd->wzFirstCabinetName, char(((int)('a') - 1) + char1), char(((int)('a') - 1) + char2));
1404 ExitOnFailure(hr, "Failed to create next Cabinet File Name"); 1420 CabcExitOnFailure(hr, "Failed to create next Cabinet File Name");
1405 hr = ::StringCchPrintfW(wzNewCabName, countof(wzNewCabName), L"%ls%c%c.cab", pcd->wzFirstCabinetName, WCHAR(((int)('a') - 1) + char1), WCHAR(((int)('a') - 1) + char2)); 1421 hr = ::StringCchPrintfW(wzNewCabName, countof(wzNewCabName), L"%ls%c%c.cab", pcd->wzFirstCabinetName, WCHAR(((int)('a') - 1) + char1), WCHAR(((int)('a') - 1) + char2));
1406 ExitOnFailure(hr, "Failed to create next Cabinet File Name"); 1422 CabcExitOnFailure(hr, "Failed to create next Cabinet File Name");
1407 } 1423 }
1408 else 1424 else
1409 { 1425 {
1410 hr = DISP_E_BADINDEX; // Value 0x8002000B stands for Invalid index. 1426 hr = DISP_E_BADINDEX; // Value 0x8002000B stands for Invalid index.
1411 ExitOnFailure(hr, "Cannot Split Cabinet more than 26*26 = 676 times. Failed to create next Cabinet File Name"); 1427 CabcExitOnFailure(hr, "Cannot Split Cabinet more than 26*26 = 676 times. Failed to create next Cabinet File Name");
1412 } 1428 }
1413 1429
1414 // Callback from PFNFCIGETNEXTCABINET CabCGetNextCabinet method 1430 // Callback from PFNFCIGETNEXTCABINET CabCGetNextCabinet method
@@ -1478,7 +1494,7 @@ static __callback INT_PTR DIAMONDAPI CabCGetOpenInfo(
1478 1494
1479 if (!::GetFileAttributesExW(pFileInfo->wzSourcePath, GetFileExInfoStandard, &fad)) 1495 if (!::GetFileAttributesExW(pFileInfo->wzSourcePath, GetFileExInfoStandard, &fad))
1480 { 1496 {
1481 ExitWithLastError(hr, "Failed to get file attributes on '%s'.", pFileInfo->wzSourcePath); 1497 CabcExitWithLastError(hr, "Failed to get file attributes on '%ls'.", pFileInfo->wzSourcePath);
1482 } 1498 }
1483 1499
1484 // Set the attributes but only allow the few attributes that CAB supports. 1500 // Set the attributes but only allow the few attributes that CAB supports.
@@ -1492,7 +1508,7 @@ static __callback INT_PTR DIAMONDAPI CabCGetOpenInfo(
1492 // found. This would create further problems if the file was written to the CAB without this value. Windows 1508 // found. This would create further problems if the file was written to the CAB without this value. Windows
1493 // Installer would then fail to extract the file. 1509 // Installer would then fail to extract the file.
1494 hr = UtcFileTimeToLocalDosDateTime(&fad.ftCreationTime, pdate, ptime); 1510 hr = UtcFileTimeToLocalDosDateTime(&fad.ftCreationTime, pdate, ptime);
1495 ExitOnFailure(hr, "Filed to read a valid file time stucture on file '%s'.", pszName); 1511 CabcExitOnFailure(hr, "Filed to read a valid file time stucture on file '%s'.", pszName);
1496 } 1512 }
1497 1513
1498 iResult = CabCOpen(pszFilePlusMagic, _O_BINARY|_O_RDONLY, 0, err, pv); 1514 iResult = CabCOpen(pszFilePlusMagic, _O_BINARY|_O_RDONLY, 0, err, pv);
@@ -1512,7 +1528,7 @@ static __callback long DIAMONDAPI CabCStatus(
1512 __in UINT ui, 1528 __in UINT ui,
1513 __in ULONG cb1, 1529 __in ULONG cb1,
1514 __in ULONG cb2, 1530 __in ULONG cb2,
1515 __out_bcount(CABC_HANDLE_BYTES) void *pv 1531 __inout_bcount(CABC_HANDLE_BYTES) void *pv
1516 ) 1532 )
1517{ 1533{
1518 UNREFERENCED_PARAMETER(ui); 1534 UNREFERENCED_PARAMETER(ui);