aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-04-28 16:36:56 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-04-29 13:58:14 -0500
commitbcd3ee7ab858d62beb36af9f5986544b68a3dd35 (patch)
tree424c4e61a580b7c4b7481712f69ab0193d76b9c4
parentd73c29407fe5ec6a0207af7d9c2547457ae0854c (diff)
downloadwix-bcd3ee7ab858d62beb36af9f5986544b68a3dd35.tar.gz
wix-bcd3ee7ab858d62beb36af9f5986544b68a3dd35.tar.bz2
wix-bcd3ee7ab858d62beb36af9f5986544b68a3dd35.zip
Clean up more 32-bit assumptions.
-rw-r--r--src/dutil/acl2util.cpp10
-rw-r--r--src/dutil/apuputil.cpp2
-rw-r--r--src/dutil/buffutil.cpp126
-rw-r--r--src/dutil/cryputil.cpp16
-rw-r--r--src/dutil/deputil.cpp12
-rw-r--r--src/dutil/dirutil.cpp2
-rw-r--r--src/dutil/dutil.cpp10
-rw-r--r--src/dutil/eseutil.cpp31
-rw-r--r--src/dutil/fileutil.cpp149
-rw-r--r--src/dutil/inc/aclutil.h2
-rw-r--r--src/dutil/inc/buffutil.h2
-rw-r--r--src/dutil/inc/fileutil.h7
-rw-r--r--src/dutil/inc/pathutil.h12
-rw-r--r--src/dutil/inc/strutil.h4
-rw-r--r--src/dutil/inc/verutil.h2
-rw-r--r--src/dutil/inetutil.cpp11
-rw-r--r--src/dutil/logutil.cpp6
-rw-r--r--src/dutil/metautil.cpp9
-rw-r--r--src/dutil/pathutil.cpp58
-rw-r--r--src/dutil/regutil.cpp18
-rw-r--r--src/dutil/reswutil.cpp7
-rw-r--r--src/dutil/strutil.cpp129
-rw-r--r--src/dutil/thmutil.cpp5
-rw-r--r--src/dutil/verutil.cpp11
-rw-r--r--src/dutil/xmlutil.cpp2
-rw-r--r--src/test/DUtilUnitTest/FileUtilTest.cpp10
26 files changed, 446 insertions, 207 deletions
diff --git a/src/dutil/acl2util.cpp b/src/dutil/acl2util.cpp
index 5aba60f0..598f12e7 100644
--- a/src/dutil/acl2util.cpp
+++ b/src/dutil/acl2util.cpp
@@ -23,7 +23,7 @@ NOTE: psczSid should be freed with StrFree()
23********************************************************************/ 23********************************************************************/
24extern "C" HRESULT DAPI AclCalculateServiceSidString( 24extern "C" HRESULT DAPI AclCalculateServiceSidString(
25 __in LPCWSTR wzServiceName, 25 __in LPCWSTR wzServiceName,
26 __in int cchServiceName, 26 __in SIZE_T cchServiceName,
27 __deref_out_z LPWSTR* psczSid 27 __deref_out_z LPWSTR* psczSid
28 ) 28 )
29{ 29{
@@ -39,7 +39,7 @@ extern "C" HRESULT DAPI AclCalculateServiceSidString(
39 39
40 if (0 == cchServiceName) 40 if (0 == cchServiceName)
41 { 41 {
42 hr = ::StringCchLengthW(wzServiceName, INT_MAX, reinterpret_cast<size_t*>(&cchServiceName)); 42 hr = ::StringCchLengthW(wzServiceName, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchServiceName));
43 AclExitOnFailure(hr, "Failed to get the length of the service name."); 43 AclExitOnFailure(hr, "Failed to get the length of the service name.");
44 } 44 }
45 45
@@ -49,7 +49,7 @@ extern "C" HRESULT DAPI AclCalculateServiceSidString(
49 pbHash = reinterpret_cast<BYTE*>(MemAlloc(cbHash, TRUE)); 49 pbHash = reinterpret_cast<BYTE*>(MemAlloc(cbHash, TRUE));
50 AclExitOnNull(pbHash, hr, E_OUTOFMEMORY, "Failed to allocate hash byte array."); 50 AclExitOnNull(pbHash, hr, E_OUTOFMEMORY, "Failed to allocate hash byte array.");
51 51
52 hr = CrypHashBuffer(reinterpret_cast<BYTE*>(sczUpperServiceName), cchServiceName * 2, PROV_RSA_FULL, CALG_SHA1, pbHash, cbHash); 52 hr = CrypHashBuffer(reinterpret_cast<BYTE*>(sczUpperServiceName), cchServiceName * sizeof(WCHAR), PROV_RSA_FULL, CALG_SHA1, pbHash, cbHash);
53 AclExitOnNull(pbHash, hr, E_OUTOFMEMORY, "Failed to hash the service name."); 53 AclExitOnNull(pbHash, hr, E_OUTOFMEMORY, "Failed to hash the service name.");
54 54
55 hr = StrAllocFormatted(psczSid, L"S-1-5-80-%u-%u-%u-%u-%u", 55 hr = StrAllocFormatted(psczSid, L"S-1-5-80-%u-%u-%u-%u-%u",
@@ -80,7 +80,7 @@ extern "C" HRESULT DAPI AclGetAccountSidStringEx(
80 ) 80 )
81{ 81{
82 HRESULT hr = S_OK; 82 HRESULT hr = S_OK;
83 int cchAccount = 0; 83 SIZE_T cchAccount = 0;
84 PSID psid = NULL; 84 PSID psid = NULL;
85 LPWSTR pwz = NULL; 85 LPWSTR pwz = NULL;
86 LPWSTR sczSid = NULL; 86 LPWSTR sczSid = NULL;
@@ -103,7 +103,7 @@ extern "C" HRESULT DAPI AclGetAccountSidStringEx(
103 { 103 {
104 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr) 104 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr)
105 { 105 {
106 HRESULT hrLength = ::StringCchLengthW(wzAccount, INT_MAX, reinterpret_cast<size_t*>(&cchAccount)); 106 HRESULT hrLength = ::StringCchLengthW(wzAccount, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchAccount));
107 AclExitOnFailure(hrLength, "Failed to get the length of the account name."); 107 AclExitOnFailure(hrLength, "Failed to get the length of the account name.");
108 108
109 if (11 < cchAccount && CSTR_EQUAL == CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, L"NT SERVICE\\", 11, wzAccount, 11)) 109 if (11 < cchAccount && CSTR_EQUAL == CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, L"NT SERVICE\\", 11, wzAccount, 11))
diff --git a/src/dutil/apuputil.cpp b/src/dutil/apuputil.cpp
index 6f5825bb..eb96d515 100644
--- a/src/dutil/apuputil.cpp
+++ b/src/dutil/apuputil.cpp
@@ -388,7 +388,7 @@ static HRESULT ParseEnclosure(
388 if (dwDigestStringLength != cchDigestString) 388 if (dwDigestStringLength != cchDigestString)
389 { 389 {
390 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); 390 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
391 ApupExitOnRootFailure(hr, "Invalid digest length (%zu) for digest algorithm (%u).", cchDigestString, dwDigestStringLength); 391 ApupExitOnRootFailure(hr, "Invalid digest length (%Iu) for digest algorithm (%u).", cchDigestString, dwDigestStringLength);
392 } 392 }
393 393
394 pEnclosure->cbDigest = sizeof(BYTE) * dwDigestLength; 394 pEnclosure->cbDigest = sizeof(BYTE) * dwDigestLength;
diff --git a/src/dutil/buffutil.cpp b/src/dutil/buffutil.cpp
index a6d3ac90..b6d58cc0 100644
--- a/src/dutil/buffutil.cpp
+++ b/src/dutil/buffutil.cpp
@@ -70,7 +70,7 @@ extern "C" HRESULT BuffReadNumber64(
70 __in SIZE_T cbBuffer, 70 __in SIZE_T cbBuffer,
71 __inout SIZE_T* piBuffer, 71 __inout SIZE_T* piBuffer,
72 __out DWORD64* pdw64 72 __out DWORD64* pdw64
73) 73 )
74{ 74{
75 Assert(pbBuffer); 75 Assert(pbBuffer);
76 Assert(piBuffer); 76 Assert(piBuffer);
@@ -98,11 +98,11 @@ LExit:
98} 98}
99 99
100extern "C" HRESULT BuffReadPointer( 100extern "C" HRESULT BuffReadPointer(
101 __in_bcount(cbBuffer) const BYTE * pbBuffer, 101 __in_bcount(cbBuffer) const BYTE* pbBuffer,
102 __in SIZE_T cbBuffer, 102 __in SIZE_T cbBuffer,
103 __inout SIZE_T* piBuffer, 103 __inout SIZE_T* piBuffer,
104 __out DWORD_PTR* pdw64 104 __out DWORD_PTR* pdw64
105) 105 )
106{ 106{
107 Assert(pbBuffer); 107 Assert(pbBuffer);
108 Assert(piBuffer); 108 Assert(piBuffer);
@@ -141,8 +141,8 @@ extern "C" HRESULT BuffReadString(
141 Assert(pscz); 141 Assert(pscz);
142 142
143 HRESULT hr = S_OK; 143 HRESULT hr = S_OK;
144 DWORD cch = 0; 144 SIZE_T cch = 0;
145 DWORD cb = 0; 145 SIZE_T cb = 0;
146 SIZE_T cbAvailable = 0; 146 SIZE_T cbAvailable = 0;
147 147
148 // get availiable data size 148 // get availiable data size
@@ -150,19 +150,19 @@ extern "C" HRESULT BuffReadString(
150 BuffExitOnRootFailure(hr, "Failed to calculate available data size for character count."); 150 BuffExitOnRootFailure(hr, "Failed to calculate available data size for character count.");
151 151
152 // verify buffer size 152 // verify buffer size
153 if (sizeof(DWORD) > cbAvailable) 153 if (sizeof(SIZE_T) > cbAvailable)
154 { 154 {
155 hr = E_INVALIDARG; 155 hr = E_INVALIDARG;
156 BuffExitOnRootFailure(hr, "Buffer too small."); 156 BuffExitOnRootFailure(hr, "Buffer too small.");
157 } 157 }
158 158
159 // read character count 159 // read character count
160 cch = *(const DWORD*)(pbBuffer + *piBuffer); 160 cch = *(const SIZE_T*)(pbBuffer + *piBuffer);
161 161
162 hr = ::DWordMult(cch, static_cast<DWORD>(sizeof(WCHAR)), &cb); 162 hr = ::SIZETMult(cch, sizeof(WCHAR), &cb);
163 BuffExitOnRootFailure(hr, "Overflow while multiplying to calculate buffer size"); 163 BuffExitOnRootFailure(hr, "Overflow while multiplying to calculate buffer size");
164 164
165 hr = ::SIZETAdd(*piBuffer, sizeof(DWORD), piBuffer); 165 hr = ::SIZETAdd(*piBuffer, sizeof(SIZE_T), piBuffer);
166 BuffExitOnRootFailure(hr, "Overflow while adding to calculate buffer size"); 166 BuffExitOnRootFailure(hr, "Overflow while adding to calculate buffer size");
167 167
168 // get availiable data size 168 // get availiable data size
@@ -198,8 +198,8 @@ extern "C" HRESULT BuffReadStringAnsi(
198 Assert(pscz); 198 Assert(pscz);
199 199
200 HRESULT hr = S_OK; 200 HRESULT hr = S_OK;
201 DWORD cch = 0; 201 SIZE_T cch = 0;
202 DWORD cb = 0; 202 SIZE_T cb = 0;
203 SIZE_T cbAvailable = 0; 203 SIZE_T cbAvailable = 0;
204 204
205 // get availiable data size 205 // get availiable data size
@@ -207,19 +207,19 @@ extern "C" HRESULT BuffReadStringAnsi(
207 BuffExitOnRootFailure(hr, "Failed to calculate available data size for character count."); 207 BuffExitOnRootFailure(hr, "Failed to calculate available data size for character count.");
208 208
209 // verify buffer size 209 // verify buffer size
210 if (sizeof(DWORD) > cbAvailable) 210 if (sizeof(SIZE_T) > cbAvailable)
211 { 211 {
212 hr = E_INVALIDARG; 212 hr = E_INVALIDARG;
213 BuffExitOnRootFailure(hr, "Buffer too small."); 213 BuffExitOnRootFailure(hr, "Buffer too small.");
214 } 214 }
215 215
216 // read character count 216 // read character count
217 cch = *(const DWORD*)(pbBuffer + *piBuffer); 217 cch = *(const SIZE_T*)(pbBuffer + *piBuffer);
218 218
219 hr = ::DWordMult(cch, static_cast<DWORD>(sizeof(CHAR)), &cb); 219 hr = ::SIZETMult(cch, sizeof(CHAR), &cb);
220 BuffExitOnRootFailure(hr, "Overflow while multiplying to calculate buffer size"); 220 BuffExitOnRootFailure(hr, "Overflow while multiplying to calculate buffer size");
221 221
222 hr = ::SIZETAdd(*piBuffer, sizeof(DWORD), piBuffer); 222 hr = ::SIZETAdd(*piBuffer, sizeof(SIZE_T), piBuffer);
223 BuffExitOnRootFailure(hr, "Overflow while adding to calculate buffer size"); 223 BuffExitOnRootFailure(hr, "Overflow while adding to calculate buffer size");
224 224
225 // get availiable data size 225 // get availiable data size
@@ -257,23 +257,24 @@ extern "C" HRESULT BuffReadStream(
257 Assert(pcbStream); 257 Assert(pcbStream);
258 258
259 HRESULT hr = S_OK; 259 HRESULT hr = S_OK;
260 DWORD64 cb = 0; 260 SIZE_T cb = 0;
261 SIZE_T cbAvailable = 0; 261 SIZE_T cbAvailable = 0;
262 errno_t err = 0;
262 263
263 // get availiable data size 264 // get availiable data size
264 hr = ::SIZETSub(cbBuffer, *piBuffer, &cbAvailable); 265 hr = ::SIZETSub(cbBuffer, *piBuffer, &cbAvailable);
265 BuffExitOnRootFailure(hr, "Failed to calculate available data size for stream size."); 266 BuffExitOnRootFailure(hr, "Failed to calculate available data size for stream size.");
266 267
267 // verify buffer size 268 // verify buffer size
268 if (sizeof(DWORD64) > cbAvailable) 269 if (sizeof(SIZE_T) > cbAvailable)
269 { 270 {
270 hr = E_INVALIDARG; 271 hr = E_INVALIDARG;
271 BuffExitOnRootFailure(hr, "Buffer too small."); 272 BuffExitOnRootFailure(hr, "Buffer too small.");
272 } 273 }
273 274
274 // read stream size 275 // read stream size
275 cb = *(const DWORD64*)(pbBuffer + *piBuffer); 276 cb = *(const SIZE_T*)(pbBuffer + *piBuffer);
276 *piBuffer += sizeof(DWORD64); 277 *piBuffer += sizeof(SIZE_T);
277 278
278 // get availiable data size 279 // get availiable data size
279 hr = ::SIZETSub(cbBuffer, *piBuffer, &cbAvailable); 280 hr = ::SIZETSub(cbBuffer, *piBuffer, &cbAvailable);
@@ -287,15 +288,20 @@ extern "C" HRESULT BuffReadStream(
287 } 288 }
288 289
289 // allocate buffer 290 // allocate buffer
290 *ppbStream = (BYTE*)MemAlloc((SIZE_T)cb, TRUE); 291 *ppbStream = (BYTE*)MemAlloc(cb, TRUE);
291 BuffExitOnNull(*ppbStream, hr, E_OUTOFMEMORY, "Failed to allocate stream."); 292 BuffExitOnNull(*ppbStream, hr, E_OUTOFMEMORY, "Failed to allocate stream.");
292 293
293 // read stream data 294 // read stream data
294 memcpy_s(*ppbStream, cbBuffer - *piBuffer, pbBuffer + *piBuffer, (SIZE_T)cb); 295 err = memcpy_s(*ppbStream, cbBuffer - *piBuffer, pbBuffer + *piBuffer, cb);
295 *piBuffer += (SIZE_T)cb; 296 if (err)
297 {
298 BuffExitOnRootFailure(hr = E_INVALIDARG, "Failed to read stream from buffer, error: %d", err);
299 }
300
301 *piBuffer += cb;
296 302
297 // return stream size 303 // return stream size
298 *pcbStream = (SIZE_T)cb; 304 *pcbStream = cb;
299 305
300LExit: 306LExit:
301 return hr; 307 return hr;
@@ -304,7 +310,7 @@ LExit:
304extern "C" HRESULT BuffWriteNumber( 310extern "C" HRESULT BuffWriteNumber(
305 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer, 311 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer,
306 __inout SIZE_T* piBuffer, 312 __inout SIZE_T* piBuffer,
307 __in DWORD_PTR dw 313 __in DWORD dw
308 ) 314 )
309{ 315{
310 Assert(ppbBuffer); 316 Assert(ppbBuffer);
@@ -317,7 +323,7 @@ extern "C" HRESULT BuffWriteNumber(
317 BuffExitOnFailure(hr, "Failed to ensure buffer size."); 323 BuffExitOnFailure(hr, "Failed to ensure buffer size.");
318 324
319 // copy data to buffer 325 // copy data to buffer
320 *(DWORD_PTR*)(*ppbBuffer + *piBuffer) = dw; 326 *(DWORD*)(*ppbBuffer + *piBuffer) = dw;
321 *piBuffer += sizeof(DWORD); 327 *piBuffer += sizeof(DWORD);
322 328
323LExit: 329LExit:
@@ -351,7 +357,7 @@ extern "C" HRESULT BuffWritePointer(
351 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer, 357 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer,
352 __inout SIZE_T* piBuffer, 358 __inout SIZE_T* piBuffer,
353 __in DWORD_PTR dw 359 __in DWORD_PTR dw
354) 360 )
355{ 361{
356 Assert(ppbBuffer); 362 Assert(ppbBuffer);
357 Assert(piBuffer); 363 Assert(piBuffer);
@@ -380,19 +386,33 @@ extern "C" HRESULT BuffWriteString(
380 Assert(piBuffer); 386 Assert(piBuffer);
381 387
382 HRESULT hr = S_OK; 388 HRESULT hr = S_OK;
383 DWORD cch = (DWORD)lstrlenW(scz); 389 SIZE_T cch = 0;
384 SIZE_T cb = cch * sizeof(WCHAR); 390 SIZE_T cb = 0;
391 errno_t err = 0;
392
393 if (scz)
394 {
395 hr = ::StringCchLengthW(scz, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cch));
396 BuffExitOnRootFailure(hr, "Failed to get string size.")
397 }
398
399 cb = cch * sizeof(WCHAR);
385 400
386 // make sure we have a buffer with sufficient space 401 // make sure we have a buffer with sufficient space
387 hr = EnsureBufferSize(ppbBuffer, *piBuffer + (sizeof(DWORD) + cb)); 402 hr = EnsureBufferSize(ppbBuffer, *piBuffer + (sizeof(SIZE_T) + cb));
388 BuffExitOnFailure(hr, "Failed to ensure buffer size."); 403 BuffExitOnFailure(hr, "Failed to ensure buffer size.");
389 404
390 // copy character count to buffer 405 // copy character count to buffer
391 *(DWORD*)(*ppbBuffer + *piBuffer) = cch; 406 *(SIZE_T*)(*ppbBuffer + *piBuffer) = cch;
392 *piBuffer += sizeof(DWORD); 407 *piBuffer += sizeof(SIZE_T);
393 408
394 // copy data to buffer 409 // copy data to buffer
395 memcpy_s(*ppbBuffer + *piBuffer, cb, scz, cb); 410 err = memcpy_s(*ppbBuffer + *piBuffer, cb, scz, cb);
411 if (err)
412 {
413 BuffExitOnRootFailure(hr = E_INVALIDARG, "Failed to write string to buffer: '%ls', error: %d", scz, err);
414 }
415
396 *piBuffer += cb; 416 *piBuffer += cb;
397 417
398LExit: 418LExit:
@@ -409,19 +429,33 @@ extern "C" HRESULT BuffWriteStringAnsi(
409 Assert(piBuffer); 429 Assert(piBuffer);
410 430
411 HRESULT hr = S_OK; 431 HRESULT hr = S_OK;
412 DWORD cch = (DWORD)lstrlenA(scz); 432 SIZE_T cch = 0;
413 SIZE_T cb = cch * sizeof(CHAR); 433 SIZE_T cb = 0;
434 errno_t err = 0;
435
436 if (scz)
437 {
438 hr = ::StringCchLengthA(scz, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cch));
439 BuffExitOnRootFailure(hr, "Failed to get string size.")
440 }
441
442 cb = cch * sizeof(CHAR);
414 443
415 // make sure we have a buffer with sufficient space 444 // make sure we have a buffer with sufficient space
416 hr = EnsureBufferSize(ppbBuffer, *piBuffer + (sizeof(DWORD) + cb)); 445 hr = EnsureBufferSize(ppbBuffer, *piBuffer + (sizeof(SIZE_T) + cb));
417 BuffExitOnFailure(hr, "Failed to ensure buffer size."); 446 BuffExitOnFailure(hr, "Failed to ensure buffer size.");
418 447
419 // copy character count to buffer 448 // copy character count to buffer
420 *(DWORD*)(*ppbBuffer + *piBuffer) = cch; 449 *(SIZE_T*)(*ppbBuffer + *piBuffer) = cch;
421 *piBuffer += sizeof(DWORD); 450 *piBuffer += sizeof(SIZE_T);
422 451
423 // copy data to buffer 452 // copy data to buffer
424 memcpy_s(*ppbBuffer + *piBuffer, cb, scz, cb); 453 err = memcpy_s(*ppbBuffer + *piBuffer, cb, scz, cb);
454 if (err)
455 {
456 BuffExitOnRootFailure(hr = E_INVALIDARG, "Failed to write string to buffer: '%hs', error: %d", scz, err);
457 }
458
425 *piBuffer += cb; 459 *piBuffer += cb;
426 460
427LExit: 461LExit:
@@ -440,18 +474,24 @@ extern "C" HRESULT BuffWriteStream(
440 Assert(pbStream); 474 Assert(pbStream);
441 475
442 HRESULT hr = S_OK; 476 HRESULT hr = S_OK;
443 DWORD64 cb = cbStream; 477 SIZE_T cb = cbStream;
478 errno_t err = 0;
444 479
445 // make sure we have a buffer with sufficient space 480 // make sure we have a buffer with sufficient space
446 hr = EnsureBufferSize(ppbBuffer, *piBuffer + cbStream + sizeof(DWORD64)); 481 hr = EnsureBufferSize(ppbBuffer, *piBuffer + cbStream + sizeof(SIZE_T));
447 BuffExitOnFailure(hr, "Failed to ensure buffer size."); 482 BuffExitOnFailure(hr, "Failed to ensure buffer size.");
448 483
449 // copy byte count to buffer 484 // copy byte count to buffer
450 *(DWORD64*)(*ppbBuffer + *piBuffer) = cb; 485 *(SIZE_T*)(*ppbBuffer + *piBuffer) = cb;
451 *piBuffer += sizeof(DWORD64); 486 *piBuffer += sizeof(SIZE_T);
452 487
453 // copy data to buffer 488 // copy data to buffer
454 memcpy_s(*ppbBuffer + *piBuffer, cbStream, pbStream, cbStream); 489 err = memcpy_s(*ppbBuffer + *piBuffer, cbStream, pbStream, cbStream);
490 if (err)
491 {
492 BuffExitOnRootFailure(hr = E_INVALIDARG, "Failed to write stream to buffer, error: %d", err);
493 }
494
455 *piBuffer += cbStream; 495 *piBuffer += cbStream;
456 496
457LExit: 497LExit:
diff --git a/src/dutil/cryputil.cpp b/src/dutil/cryputil.cpp
index c5c1b221..24bb83f1 100644
--- a/src/dutil/cryputil.cpp
+++ b/src/dutil/cryputil.cpp
@@ -291,6 +291,9 @@ HRESULT DAPI CrypHashBuffer(
291 HRESULT hr = S_OK; 291 HRESULT hr = S_OK;
292 HCRYPTPROV hProv = NULL; 292 HCRYPTPROV hProv = NULL;
293 HCRYPTHASH hHash = NULL; 293 HCRYPTHASH hHash = NULL;
294 DWORD cbDataHashed = 0;
295 SIZE_T cbTotal = 0;
296 SIZE_T cbRemaining = 0;
294 297
295 // get handle to the crypto provider 298 // get handle to the crypto provider
296 if (!::CryptAcquireContextW(&hProv, NULL, NULL, dwProvType, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) 299 if (!::CryptAcquireContextW(&hProv, NULL, NULL, dwProvType, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
@@ -304,10 +307,17 @@ HRESULT DAPI CrypHashBuffer(
304 CrypExitWithLastError(hr, "Failed to initiate hash."); 307 CrypExitWithLastError(hr, "Failed to initiate hash.");
305 } 308 }
306 309
307 if (!::CryptHashData(hHash, pbBuffer, static_cast<DWORD>(cbBuffer), 0)) 310 do
308 { 311 {
309 CrypExitWithLastError(hr, "Failed to hash data."); 312 cbRemaining = cbBuffer - cbTotal;
310 } 313 cbDataHashed = (DWORD)min(DWORD_MAX, cbRemaining);
314 if (!::CryptHashData(hHash, pbBuffer + cbTotal, cbDataHashed, 0))
315 {
316 CrypExitWithLastError(hr, "Failed to hash data.");
317 }
318
319 cbTotal += cbDataHashed;
320 } while (cbTotal < cbBuffer);
311 321
312 // get hash value 322 // get hash value
313 if (!::CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &cbHash, 0)) 323 if (!::CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &cbHash, 0))
diff --git a/src/dutil/deputil.cpp b/src/dutil/deputil.cpp
index 362b3345..2e6d6a6c 100644
--- a/src/dutil/deputil.cpp
+++ b/src/dutil/deputil.cpp
@@ -122,9 +122,7 @@ DAPI_(HRESULT) DepCheckDependency(
122 LPWSTR sczKey = NULL; 122 LPWSTR sczKey = NULL;
123 HKEY hkKey = NULL; 123 HKEY hkKey = NULL;
124 DWORD64 dw64Version = 0; 124 DWORD64 dw64Version = 0;
125 int cchMinVersion = 0;
126 DWORD64 dw64MinVersion = 0; 125 DWORD64 dw64MinVersion = 0;
127 int cchMaxVersion = 0;
128 DWORD64 dw64MaxVersion = 0; 126 DWORD64 dw64MaxVersion = 0;
129 BOOL fAllowEqual = FALSE; 127 BOOL fAllowEqual = FALSE;
130 LPWSTR sczName = NULL; 128 LPWSTR sczName = NULL;
@@ -171,10 +169,9 @@ DAPI_(HRESULT) DepCheckDependency(
171 // Check MinVersion if provided. 169 // Check MinVersion if provided.
172 if (wzMinVersion) 170 if (wzMinVersion)
173 { 171 {
174 cchMinVersion = lstrlenW(wzMinVersion); 172 if (*wzMinVersion)
175 if (0 < cchMinVersion)
176 { 173 {
177 hr = FileVersionFromStringEx(wzMinVersion, cchMinVersion, &dw64MinVersion); 174 hr = FileVersionFromStringEx(wzMinVersion, 0, &dw64MinVersion);
178 DepExitOnFailure(hr, "Failed to get the 64-bit version number from \"%ls\".", wzMinVersion); 175 DepExitOnFailure(hr, "Failed to get the 64-bit version number from \"%ls\".", wzMinVersion);
179 176
180 fAllowEqual = iAttributes & RequiresAttributesMinVersionInclusive; 177 fAllowEqual = iAttributes & RequiresAttributesMinVersionInclusive;
@@ -206,10 +203,9 @@ DAPI_(HRESULT) DepCheckDependency(
206 // Check MaxVersion if provided. 203 // Check MaxVersion if provided.
207 if (wzMaxVersion) 204 if (wzMaxVersion)
208 { 205 {
209 cchMaxVersion = lstrlenW(wzMaxVersion); 206 if (*wzMaxVersion)
210 if (0 < cchMaxVersion)
211 { 207 {
212 hr = FileVersionFromStringEx(wzMaxVersion, cchMaxVersion, &dw64MaxVersion); 208 hr = FileVersionFromStringEx(wzMaxVersion, 0, &dw64MaxVersion);
213 DepExitOnFailure(hr, "Failed to get the 64-bit version number from \"%ls\".", wzMaxVersion); 209 DepExitOnFailure(hr, "Failed to get the 64-bit version number from \"%ls\".", wzMaxVersion);
214 210
215 fAllowEqual = iAttributes & RequiresAttributesMaxVersionInclusive; 211 fAllowEqual = iAttributes & RequiresAttributesMaxVersionInclusive;
diff --git a/src/dutil/dirutil.cpp b/src/dutil/dirutil.cpp
index b10e71f3..ae2c5e1c 100644
--- a/src/dutil/dirutil.cpp
+++ b/src/dutil/dirutil.cpp
@@ -400,7 +400,7 @@ extern "C" HRESULT DAPI DirGetCurrent(
400 DirExitOnFailure(hr, "Failed to determine size of current directory."); 400 DirExitOnFailure(hr, "Failed to determine size of current directory.");
401 } 401 }
402 402
403 DWORD cchRequired = ::GetCurrentDirectoryW(static_cast<DWORD>(cch), 0 == cch ? NULL : *psczCurrentDirectory); 403 DWORD cchRequired = ::GetCurrentDirectoryW((DWORD)min(DWORD_MAX, cch), 0 == cch ? NULL : *psczCurrentDirectory);
404 if (0 == cchRequired) 404 if (0 == cchRequired)
405 { 405 {
406 DirExitWithLastError(hr, "Failed to get current directory."); 406 DirExitWithLastError(hr, "Failed to get current directory.");
diff --git a/src/dutil/dutil.cpp b/src/dutil/dutil.cpp
index c500191a..56b85207 100644
--- a/src/dutil/dutil.cpp
+++ b/src/dutil/dutil.cpp
@@ -127,9 +127,13 @@ extern "C" void DAPI Dutil_AssertMsg(
127 hAssertFile = ::CreateFileA(szPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 127 hAssertFile = ::CreateFileA(szPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
128 if (INVALID_HANDLE_VALUE != hAssertFile) 128 if (INVALID_HANDLE_VALUE != hAssertFile)
129 { 129 {
130 ::SetFilePointer(hAssertFile, 0, 0, FILE_END); 130 if (INVALID_SET_FILE_POINTER != ::SetFilePointer(hAssertFile, 0, 0, FILE_END))
131 ::StringCchCatA(szMsg, countof(szMsg), "\r\n"); 131 {
132 ::WriteFile(hAssertFile, szMsg, lstrlenA(szMsg), &cch, NULL); 132 if (SUCCEEDED(::StringCchCatA(szMsg, countof(szMsg), "\r\n")))
133 {
134 ::WriteFile(hAssertFile, szMsg, lstrlenA(szMsg), &cch, NULL);
135 }
136 }
133 } 137 }
134 } 138 }
135 } 139 }
diff --git a/src/dutil/eseutil.cpp b/src/dutil/eseutil.cpp
index d2bd7dc5..b9455d4b 100644
--- a/src/dutil/eseutil.cpp
+++ b/src/dutil/eseutil.cpp
@@ -312,12 +312,14 @@ HRESULT AllocIndexCreateStruct(
312 EseExitOnNull(*ppjicIndexCreate, hr, E_OUTOFMEMORY, "Failed to allocate index create structure for database"); 312 EseExitOnNull(*ppjicIndexCreate, hr, E_OUTOFMEMORY, "Failed to allocate index create structure for database");
313 313
314 // Record the size including both null terminators - the struct requires this 314 // Record the size including both null terminators - the struct requires this
315 DWORD dwSize = 0; 315 size_t cchSize = 0;
316 dwSize = lstrlen(pszMultiSzKeys) + 1; // add 1 to include null character at the end 316 hr = ::StringCchLengthA(pszMultiSzKeys, STRSAFE_MAX_LENGTH, &cchSize);
317 EseExitOnFailure(hr, "Failed to get size of keys string"); 317 EseExitOnRootFailure(hr, "Failed to get size of keys string");
318
319 ++cchSize; // add 1 to include null character at the end
318 320
319 // At this point convert all question marks to null characters 321 // At this point convert all question marks to null characters
320 for (i = 0; i < dwSize; ++i) 322 for (i = 0; i < cchSize; ++i)
321 { 323 {
322 if ('?' == pszMultiSzKeys[i]) 324 if ('?' == pszMultiSzKeys[i])
323 { 325 {
@@ -328,7 +330,7 @@ HRESULT AllocIndexCreateStruct(
328 (*ppjicIndexCreate)->cbStruct = sizeof(JET_INDEXCREATE); 330 (*ppjicIndexCreate)->cbStruct = sizeof(JET_INDEXCREATE);
329 (*ppjicIndexCreate)->szIndexName = pszIndexName; 331 (*ppjicIndexCreate)->szIndexName = pszIndexName;
330 (*ppjicIndexCreate)->szKey = pszMultiSzKeys; 332 (*ppjicIndexCreate)->szKey = pszMultiSzKeys;
331 (*ppjicIndexCreate)->cbKey = dwSize; 333 (*ppjicIndexCreate)->cbKey = (DWORD)cchSize;
332 (*ppjicIndexCreate)->grbit = JET_bitIndexUnique | JET_bitIndexPrimary; 334 (*ppjicIndexCreate)->grbit = JET_bitIndexUnique | JET_bitIndexPrimary;
333 (*ppjicIndexCreate)->ulDensity = 80; 335 (*ppjicIndexCreate)->ulDensity = 80;
334 (*ppjicIndexCreate)->lcid = 1033; 336 (*ppjicIndexCreate)->lcid = 1033;
@@ -884,7 +886,16 @@ HRESULT DAPI EseSetColumnString(
884{ 886{
885 HRESULT hr = S_OK; 887 HRESULT hr = S_OK;
886 JET_ERR jEr = JET_errSuccess; 888 JET_ERR jEr = JET_errSuccess;
887 ULONG cbValueSize = static_cast<ULONG>((wcslen(pwzValue) + 1) * sizeof(WCHAR)); // add 1 for null character, then multiply by size of WCHAR to get bytes 889 size_t cchValue = 0;
890 ULONG cbValueSize = 0;
891
892 if (pwzValue)
893 {
894 hr = ::StringCchLengthW(pwzValue, STRSAFE_MAX_LENGTH, &cchValue);
895 EseExitOnRootFailure(hr, "Failed to get string length: %ls", pwzValue);
896 }
897
898 cbValueSize = static_cast<ULONG>((cchValue + 1) * sizeof(WCHAR)); // add 1 for null character, then multiply by size of WCHAR to get bytes
888 899
889 jEr = JetSetColumn(jsSession, tsTable.jtTable, tsTable.pcsColumns[dwColumn].jcColumn, pwzValue, cbValueSize, 0, NULL); 900 jEr = JetSetColumn(jsSession, tsTable.jtTable, tsTable.pcsColumns[dwColumn].jcColumn, pwzValue, cbValueSize, 0, NULL);
890 ExitOnJetFailure(jEr, hr, "Failed to set string value into column of database: %ls", pwzValue); 901 ExitOnJetFailure(jEr, hr, "Failed to set string value into column of database: %ls", pwzValue);
@@ -1196,11 +1207,17 @@ HRESULT DAPI EseSetQueryColumnString(
1196{ 1207{
1197 HRESULT hr = S_OK; 1208 HRESULT hr = S_OK;
1198 DWORD dwStringSize = 0; 1209 DWORD dwStringSize = 0;
1210 size_t cchString = 0;
1199 ESE_QUERY *peqHandle = static_cast<ESE_QUERY *>(eqhHandle); 1211 ESE_QUERY *peqHandle = static_cast<ESE_QUERY *>(eqhHandle);
1200 JET_GRBIT jGrb = 0; 1212 JET_GRBIT jGrb = 0;
1201 1213
1202 dwStringSize = sizeof(WCHAR) * (lstrlenW(pszString) + 1); // Add 1 for null terminator 1214 if (pszString)
1215 {
1216 hr = ::StringCchLengthW(pszString, STRSAFE_MAX_LENGTH, &cchString);
1217 EseExitOnRootFailure(hr, "Failed to get size of column string");
1218 }
1203 1219
1220 dwStringSize = static_cast<DWORD>(sizeof(WCHAR) * (cchString + 1)); // Add 1 for null terminator
1204 1221
1205 if (fFinal) 1222 if (fFinal)
1206 { 1223 {
diff --git a/src/dutil/fileutil.cpp b/src/dutil/fileutil.cpp
index 6cc2a80e..1822727a 100644
--- a/src/dutil/fileutil.cpp
+++ b/src/dutil/fileutil.cpp
@@ -155,40 +155,33 @@ __out LPWSTR *ppwzFileNameNoExtension
155 Assert(wzFileName && *wzFileName); 155 Assert(wzFileName && *wzFileName);
156 156
157 HRESULT hr = S_OK; 157 HRESULT hr = S_OK;
158 158 size_t cchFileName = 0;
159 SIZE_T cchFileName = wcslen(wzFileName);
160
161 LPWSTR pwzFileNameNoExtension = NULL; 159 LPWSTR pwzFileNameNoExtension = NULL;
162 DWORD cchFileNameNoExtension = 0; 160 size_t cchFileNameNoExtension = 0;
163 161 errno_t err = 0;
164 // Filename without extension can not be longer than _MAX_FNAME 162
165 // Filename without extension should also not be longer than filename itself 163 hr = ::StringCchLengthW(wzFileName, STRSAFE_MAX_LENGTH, &cchFileName);
166 if (_MAX_FNAME > cchFileName) 164 FileExitOnRootFailure(hr, "failed to get length of file name: %ls", wzFileName);
167 { 165
168 cchFileNameNoExtension = (DWORD) cchFileName; 166 cchFileNameNoExtension = cchFileName + 1;
169 } 167
170 else
171 {
172 cchFileNameNoExtension = _MAX_FNAME;
173 }
174
175 hr = StrAlloc(&pwzFileNameNoExtension, cchFileNameNoExtension); 168 hr = StrAlloc(&pwzFileNameNoExtension, cchFileNameNoExtension);
176 FileExitOnFailure(hr, "failed to allocate space for File Name without extension"); 169 FileExitOnFailure(hr, "failed to allocate space for File Name without extension");
177 170
178 // _wsplitpath_s can handle drive/path/filename/extension 171 // _wsplitpath_s can handle drive/path/filename/extension
179 errno_t err = _wsplitpath_s(wzFileName, NULL, NULL, NULL, NULL, pwzFileNameNoExtension, cchFileNameNoExtension, NULL, NULL); 172 err = _wsplitpath_s(wzFileName, NULL, NULL, NULL, NULL, pwzFileNameNoExtension, cchFileNameNoExtension, NULL, NULL);
180 if (0 != err) 173 if (err)
181 { 174 {
182 hr = E_INVALIDARG; 175 hr = E_INVALIDARG;
183 FileExitOnFailure(hr, "failed to parse filename: %ls", wzFileName); 176 FileExitOnRootFailure(hr, "failed to parse filename: '%ls', error: %d", wzFileName, err);
184 } 177 }
185 178
186 *ppwzFileNameNoExtension = pwzFileNameNoExtension; 179 *ppwzFileNameNoExtension = pwzFileNameNoExtension;
187 pwzFileNameNoExtension = NULL; 180 pwzFileNameNoExtension = NULL;
188 181
189LExit: 182LExit:
190 ReleaseStr(pwzFileNameNoExtension); 183 ReleaseStr(pwzFileNameNoExtension);
191 184
192 return hr; 185 return hr;
193} 186}
194 187
@@ -237,8 +230,12 @@ extern "C" HRESULT DAPI FileAddSuffixToBaseName(
237 230
238 HRESULT hr = S_OK; 231 HRESULT hr = S_OK;
239 LPWSTR sczNewFileName = NULL; 232 LPWSTR sczNewFileName = NULL;
233 size_t cchFileName = 0;
234
235 hr = ::StringCchLengthW(wzFileName, STRSAFE_MAX_CCH, &cchFileName);
236 FileExitOnRootFailure(hr, "Failed to get length of file name: %ls", wzFileName);
240 237
241 LPCWSTR wzExtension = wzFileName + lstrlenW(wzFileName); 238 LPCWSTR wzExtension = wzFileName + cchFileName;
242 while (wzFileName < wzExtension && L'.' != *wzExtension) 239 while (wzFileName < wzExtension && L'.' != *wzExtension)
243 { 240 {
244 --wzExtension; 241 --wzExtension;
@@ -410,7 +407,7 @@ LExit:
410*******************************************************************/ 407*******************************************************************/
411extern "C" HRESULT DAPI FileVersionFromStringEx( 408extern "C" HRESULT DAPI FileVersionFromStringEx(
412 __in_z LPCWSTR wzVersion, 409 __in_z LPCWSTR wzVersion,
413 __in DWORD cchVersion, 410 __in SIZE_T cchVersion,
414 __out DWORD64* pqwVersion 411 __out DWORD64* pqwVersion
415 ) 412 )
416{ 413{
@@ -428,7 +425,9 @@ extern "C" HRESULT DAPI FileVersionFromStringEx(
428 // get string length if not provided 425 // get string length if not provided
429 if (0 >= cchVersion) 426 if (0 >= cchVersion)
430 { 427 {
431 cchVersion = lstrlenW(wzVersion); 428 hr = ::StringCchLengthW(wzVersion, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchVersion));
429 FileExitOnRootFailure(hr, "Failed to get length of file version string: %ls", wzVersion);
430
432 if (0 >= cchVersion) 431 if (0 >= cchVersion)
433 { 432 {
434 ExitFunction1(hr = E_INVALIDARG); 433 ExitFunction1(hr = E_INVALIDARG);
@@ -996,6 +995,41 @@ LExit:
996 return hr; 995 return hr;
997} 996}
998 997
998extern "C" HRESULT DAPI FileReadHandle(
999 __in HANDLE hFile,
1000 __in_bcount(cbDest) LPBYTE pbDest,
1001 __in SIZE_T cbDest
1002 )
1003{
1004 HRESULT hr = 0;
1005 DWORD cbDataRead = 0;
1006 SIZE_T cbRemaining = cbDest;
1007 SIZE_T cbTotal = 0;
1008
1009 while (0 < cbRemaining)
1010 {
1011 if (!::ReadFile(hFile, pbDest + cbTotal, (DWORD)min(DWORD_MAX, cbRemaining), &cbDataRead, NULL))
1012 {
1013 DWORD er = ::GetLastError();
1014 if (ERROR_MORE_DATA == er)
1015 {
1016 hr = S_OK;
1017 }
1018 else
1019 {
1020 hr = HRESULT_FROM_WIN32(er);
1021 }
1022 FileExitOnRootFailure(hr, "Failed to read data from file handle.");
1023 }
1024
1025 cbRemaining -= cbDataRead;
1026 cbTotal += cbDataRead;
1027 }
1028
1029LExit:
1030 return hr;
1031}
1032
999 1033
1000/******************************************************************* 1034/*******************************************************************
1001 FileWrite - write a file from memory 1035 FileWrite - write a file from memory
@@ -1044,18 +1078,20 @@ extern "C" HRESULT DAPI FileWriteHandle(
1044{ 1078{
1045 HRESULT hr = S_OK; 1079 HRESULT hr = S_OK;
1046 DWORD cbDataWritten = 0; 1080 DWORD cbDataWritten = 0;
1047 DWORD cbTotal = 0; 1081 SIZE_T cbTotal = 0;
1082 SIZE_T cbRemaining = cbData;
1048 1083
1049 // Write out all of the data. 1084 // Write out all of the data.
1050 do 1085 while (0 < cbRemaining)
1051 { 1086 {
1052 if (!::WriteFile(hFile, pbData + cbTotal, (DWORD)(cbData - cbTotal), &cbDataWritten, NULL)) 1087 if (!::WriteFile(hFile, pbData + cbTotal, (DWORD)min(DWORD_MAX, cbRemaining), &cbDataWritten, NULL))
1053 { 1088 {
1054 FileExitOnLastError(hr, "Failed to write data to file handle."); 1089 FileExitOnLastError(hr, "Failed to write data to file handle.");
1055 } 1090 }
1056 1091
1092 cbRemaining -= cbDataWritten;
1057 cbTotal += cbDataWritten; 1093 cbTotal += cbDataWritten;
1058 } while (cbTotal < cbData); 1094 }
1059 1095
1060LExit: 1096LExit:
1061 return hr; 1097 return hr;
@@ -1115,7 +1151,7 @@ extern "C" HRESULT DAPI FileCopyUsingHandlesWithProgress(
1115 __in DWORD64 cbCopy, 1151 __in DWORD64 cbCopy,
1116 __in_opt LPPROGRESS_ROUTINE lpProgressRoutine, 1152 __in_opt LPPROGRESS_ROUTINE lpProgressRoutine,
1117 __in_opt LPVOID lpData 1153 __in_opt LPVOID lpData
1118) 1154 )
1119{ 1155{
1120 HRESULT hr = S_OK; 1156 HRESULT hr = S_OK;
1121 DWORD64 cbTotalCopied = 0; 1157 DWORD64 cbTotalCopied = 0;
@@ -1135,21 +1171,24 @@ extern "C" HRESULT DAPI FileCopyUsingHandlesWithProgress(
1135 liSourceSize.QuadPart = cbCopy; 1171 liSourceSize.QuadPart = cbCopy;
1136 } 1172 }
1137 1173
1138 dwResult = lpProgressRoutine(liSourceSize, liTotalCopied, liZero, liZero, 0, CALLBACK_STREAM_SWITCH, hSource, hTarget, lpData); 1174 if (lpProgressRoutine)
1139 switch (dwResult)
1140 { 1175 {
1141 case PROGRESS_CONTINUE: 1176 dwResult = lpProgressRoutine(liSourceSize, liTotalCopied, liZero, liZero, 0, CALLBACK_STREAM_SWITCH, hSource, hTarget, lpData);
1142 break; 1177 switch (dwResult)
1178 {
1179 case PROGRESS_CONTINUE:
1180 break;
1143 1181
1144 case PROGRESS_CANCEL: 1182 case PROGRESS_CANCEL:
1145 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_REQUEST_ABORTED)); 1183 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_REQUEST_ABORTED));
1146 1184
1147 case PROGRESS_STOP: 1185 case PROGRESS_STOP:
1148 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_REQUEST_ABORTED)); 1186 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_REQUEST_ABORTED));
1149 1187
1150 case PROGRESS_QUIET: 1188 case PROGRESS_QUIET:
1151 lpProgressRoutine = NULL; 1189 lpProgressRoutine = NULL;
1152 break; 1190 break;
1191 }
1153 } 1192 }
1154 1193
1155 // Set size of the target file. 1194 // Set size of the target file.
@@ -1929,23 +1968,27 @@ extern "C" HRESULT DAPI FileFromString(
1929 LPSTR sczUtf8String = NULL; 1968 LPSTR sczUtf8String = NULL;
1930 BYTE *pbFullFileBuffer = NULL; 1969 BYTE *pbFullFileBuffer = NULL;
1931 const BYTE *pcbFullFileBuffer = NULL; 1970 const BYTE *pcbFullFileBuffer = NULL;
1932 DWORD cbFullFileBuffer = 0; 1971 SIZE_T cbFullFileBuffer = 0;
1933 DWORD cbStrLen = 0; 1972 SIZE_T cbStrLen = 0;
1934 1973
1935 switch (feEncoding) 1974 switch (feEncoding)
1936 { 1975 {
1937 case FILE_ENCODING_UTF8: 1976 case FILE_ENCODING_UTF8:
1938 hr = StrAnsiAllocString(&sczUtf8String, sczString, 0, CP_UTF8); 1977 hr = StrAnsiAllocString(&sczUtf8String, sczString, 0, CP_UTF8);
1939 FileExitOnFailure(hr, "Failed to convert string to UTF-8 to write UTF-8 file"); 1978 FileExitOnFailure(hr, "Failed to convert string to UTF-8 to write UTF-8 file");
1940 1979
1941 cbFullFileBuffer = lstrlenA(sczUtf8String); 1980 hr = ::StringCchLengthA(sczUtf8String, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cbFullFileBuffer));
1981 FileExitOnRootFailure(hr, "Failed to get length of UTF-8 string");
1982
1942 pcbFullFileBuffer = reinterpret_cast<BYTE *>(sczUtf8String); 1983 pcbFullFileBuffer = reinterpret_cast<BYTE *>(sczUtf8String);
1943 break; 1984 break;
1944 case FILE_ENCODING_UTF8_WITH_BOM: 1985 case FILE_ENCODING_UTF8_WITH_BOM:
1945 hr = StrAnsiAllocString(&sczUtf8String, sczString, 0, CP_UTF8); 1986 hr = StrAnsiAllocString(&sczUtf8String, sczString, 0, CP_UTF8);
1946 FileExitOnFailure(hr, "Failed to convert string to UTF-8 to write UTF-8 file"); 1987 FileExitOnFailure(hr, "Failed to convert string to UTF-8 to write UTF-8 file");
1947 1988
1948 cbStrLen = lstrlenA(sczUtf8String); 1989 hr = ::StringCchLengthA(sczUtf8String, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cbStrLen));
1990 FileExitOnRootFailure(hr, "Failed to get length of UTF-8 string");
1991
1949 cbFullFileBuffer = sizeof(UTF8BOM) + cbStrLen; 1992 cbFullFileBuffer = sizeof(UTF8BOM) + cbStrLen;
1950 1993
1951 pbFullFileBuffer = reinterpret_cast<BYTE *>(MemAlloc(cbFullFileBuffer, TRUE)); 1994 pbFullFileBuffer = reinterpret_cast<BYTE *>(MemAlloc(cbFullFileBuffer, TRUE));
@@ -1956,11 +1999,17 @@ extern "C" HRESULT DAPI FileFromString(
1956 pcbFullFileBuffer = pbFullFileBuffer; 1999 pcbFullFileBuffer = pbFullFileBuffer;
1957 break; 2000 break;
1958 case FILE_ENCODING_UTF16: 2001 case FILE_ENCODING_UTF16:
1959 cbFullFileBuffer = lstrlenW(sczString) * sizeof(WCHAR); 2002 hr = ::StringCchLengthW(sczString, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cbStrLen));
2003 FileExitOnRootFailure(hr, "Failed to get length of string");
2004
2005 cbFullFileBuffer = cbStrLen * sizeof(WCHAR);
1960 pcbFullFileBuffer = reinterpret_cast<const BYTE *>(sczString); 2006 pcbFullFileBuffer = reinterpret_cast<const BYTE *>(sczString);
1961 break; 2007 break;
1962 case FILE_ENCODING_UTF16_WITH_BOM: 2008 case FILE_ENCODING_UTF16_WITH_BOM:
1963 cbStrLen = lstrlenW(sczString) * sizeof(WCHAR); 2009 hr = ::StringCchLengthW(sczString, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cbStrLen));
2010 FileExitOnRootFailure(hr, "Failed to get length of string");
2011
2012 cbStrLen *= sizeof(WCHAR);
1964 cbFullFileBuffer = sizeof(UTF16BOM) + cbStrLen; 2013 cbFullFileBuffer = sizeof(UTF16BOM) + cbStrLen;
1965 2014
1966 pbFullFileBuffer = reinterpret_cast<BYTE *>(MemAlloc(cbFullFileBuffer, TRUE)); 2015 pbFullFileBuffer = reinterpret_cast<BYTE *>(MemAlloc(cbFullFileBuffer, TRUE));
diff --git a/src/dutil/inc/aclutil.h b/src/dutil/inc/aclutil.h
index 144e4613..ac03f9a8 100644
--- a/src/dutil/inc/aclutil.h
+++ b/src/dutil/inc/aclutil.h
@@ -140,7 +140,7 @@ HRESULT DAPI AclAddAdminToSecurityDescriptor(
140// Following code in acl2util.cpp due to dependency on crypt32.dll. 140// Following code in acl2util.cpp due to dependency on crypt32.dll.
141HRESULT DAPI AclCalculateServiceSidString( 141HRESULT DAPI AclCalculateServiceSidString(
142 __in LPCWSTR wzServiceName, 142 __in LPCWSTR wzServiceName,
143 __in int cchServiceName, 143 __in SIZE_T cchServiceName,
144 __deref_out_z LPWSTR* psczSid 144 __deref_out_z LPWSTR* psczSid
145 ); 145 );
146HRESULT DAPI AclGetAccountSidStringEx( 146HRESULT DAPI AclGetAccountSidStringEx(
diff --git a/src/dutil/inc/buffutil.h b/src/dutil/inc/buffutil.h
index 7509f76a..322209e6 100644
--- a/src/dutil/inc/buffutil.h
+++ b/src/dutil/inc/buffutil.h
@@ -57,7 +57,7 @@ HRESULT BuffReadStream(
57HRESULT BuffWriteNumber( 57HRESULT BuffWriteNumber(
58 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer, 58 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer,
59 __inout SIZE_T* piBuffer, 59 __inout SIZE_T* piBuffer,
60 __in DWORD_PTR dw 60 __in DWORD dw
61 ); 61 );
62HRESULT BuffWriteNumber64( 62HRESULT BuffWriteNumber64(
63 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer, 63 __deref_inout_bcount(*piBuffer) BYTE** ppbBuffer,
diff --git a/src/dutil/inc/fileutil.h b/src/dutil/inc/fileutil.h
index 319c5508..d3e326f7 100644
--- a/src/dutil/inc/fileutil.h
+++ b/src/dutil/inc/fileutil.h
@@ -62,7 +62,7 @@ HRESULT DAPI FileVersionFromString(
62 ); 62 );
63HRESULT DAPI FileVersionFromStringEx( 63HRESULT DAPI FileVersionFromStringEx(
64 __in_z LPCWSTR wzVersion, 64 __in_z LPCWSTR wzVersion,
65 __in DWORD cchVersion, 65 __in SIZE_T cchVersion,
66 __out DWORD64* pqwVersion 66 __out DWORD64* pqwVersion
67 ); 67 );
68HRESULT DAPI FileVersionToStringEx( 68HRESULT DAPI FileVersionToStringEx(
@@ -130,6 +130,11 @@ HRESULT DAPI FileReadPartialEx(
130 __in BOOL fPartialOK, 130 __in BOOL fPartialOK,
131 __in DWORD dwShareMode 131 __in DWORD dwShareMode
132 ); 132 );
133HRESULT DAPI FileReadHandle(
134 __in HANDLE hFile,
135 __in_bcount(cbDest) LPBYTE pbDest,
136 __in SIZE_T cbDest
137 );
133HRESULT DAPI FileWrite( 138HRESULT DAPI FileWrite(
134 __in_z LPCWSTR pwzFileName, 139 __in_z LPCWSTR pwzFileName,
135 __in DWORD dwFlagsAndAttributes, 140 __in DWORD dwFlagsAndAttributes,
diff --git a/src/dutil/inc/pathutil.h b/src/dutil/inc/pathutil.h
index 719ee7d8..579b8454 100644
--- a/src/dutil/inc/pathutil.h
+++ b/src/dutil/inc/pathutil.h
@@ -178,6 +178,18 @@ DAPI_(HRESULT) PathConcat(
178 ); 178 );
179 179
180/******************************************************************* 180/*******************************************************************
181 PathConcatCch - like .NET's Path.Combine, lets you build up a path
182 one piece -- file or directory -- at a time.
183*******************************************************************/
184DAPI_(HRESULT) PathConcatCch(
185 __in_opt LPCWSTR wzPath1,
186 __in SIZE_T cchPath1,
187 __in_opt LPCWSTR wzPath2,
188 __in SIZE_T cchPath2,
189 __deref_out_z LPWSTR* psczCombined
190 );
191
192/*******************************************************************
181 PathEnsureQuoted - ensures that a path is quoted; optionally, 193 PathEnsureQuoted - ensures that a path is quoted; optionally,
182 this function also terminates a directory with a backslash 194 this function also terminates a directory with a backslash
183 if it is not already. 195 if it is not already.
diff --git a/src/dutil/inc/strutil.h b/src/dutil/inc/strutil.h
index cf8c751c..1cff9ab8 100644
--- a/src/dutil/inc/strutil.h
+++ b/src/dutil/inc/strutil.h
@@ -277,12 +277,12 @@ void DAPI StrStringToLower(
277HRESULT DAPI StrAllocStringToUpperInvariant( 277HRESULT DAPI StrAllocStringToUpperInvariant(
278 __deref_out_z LPWSTR* pscz, 278 __deref_out_z LPWSTR* pscz,
279 __in_z LPCWSTR wzSource, 279 __in_z LPCWSTR wzSource,
280 __in int cchSource 280 __in SIZE_T cchSource
281 ); 281 );
282HRESULT DAPI StrAllocStringToLowerInvariant( 282HRESULT DAPI StrAllocStringToLowerInvariant(
283 __deref_out_z LPWSTR* pscz, 283 __deref_out_z LPWSTR* pscz,
284 __in_z LPCWSTR wzSource, 284 __in_z LPCWSTR wzSource,
285 __in int cchSource 285 __in SIZE_T cchSource
286 ); 286 );
287 287
288HRESULT DAPI StrArrayAllocString( 288HRESULT DAPI StrArrayAllocString(
diff --git a/src/dutil/inc/verutil.h b/src/dutil/inc/verutil.h
index 3caa17e1..5247bb61 100644
--- a/src/dutil/inc/verutil.h
+++ b/src/dutil/inc/verutil.h
@@ -74,7 +74,7 @@ void DAPI VerFreeVersion(
74*******************************************************************/ 74*******************************************************************/
75HRESULT DAPI VerParseVersion( 75HRESULT DAPI VerParseVersion(
76 __in_z LPCWSTR wzVersion, 76 __in_z LPCWSTR wzVersion,
77 __in DWORD cchVersion, 77 __in SIZE_T cchVersion,
78 __in BOOL fStrict, 78 __in BOOL fStrict,
79 __out VERUTIL_VERSION** ppVersion 79 __out VERUTIL_VERSION** ppVersion
80 ); 80 );
diff --git a/src/dutil/inetutil.cpp b/src/dutil/inetutil.cpp
index f75849f6..8dace55f 100644
--- a/src/dutil/inetutil.cpp
+++ b/src/dutil/inetutil.cpp
@@ -86,7 +86,8 @@ extern "C" HRESULT DAPI InternetQueryInfoString(
86 ) 86 )
87{ 87{
88 HRESULT hr = S_OK; 88 HRESULT hr = S_OK;
89 DWORD_PTR cbValue = 0; 89 SIZE_T cbOriginal = 0;
90 DWORD cbValue = 0;
90 DWORD dwIndex = 0; 91 DWORD dwIndex = 0;
91 92
92 // If nothing was provided start off with some arbitrary size. 93 // If nothing was provided start off with some arbitrary size.
@@ -96,10 +97,12 @@ extern "C" HRESULT DAPI InternetQueryInfoString(
96 InetExitOnFailure(hr, "Failed to allocate memory for value."); 97 InetExitOnFailure(hr, "Failed to allocate memory for value.");
97 } 98 }
98 99
99 hr = StrSize(*psczValue, &cbValue); 100 hr = StrSize(*psczValue, &cbOriginal);
100 InetExitOnFailure(hr, "Failed to get size of value."); 101 InetExitOnFailure(hr, "Failed to get size of value.");
101 102
102 if (!::HttpQueryInfoW(hRequest, dwInfo, static_cast<void*>(*psczValue), reinterpret_cast<DWORD*>(&cbValue), &dwIndex)) 103 cbValue = (DWORD)min(DWORD_MAX, cbOriginal);
104
105 if (!::HttpQueryInfoW(hRequest, dwInfo, static_cast<void*>(*psczValue), &cbValue, &dwIndex))
103 { 106 {
104 DWORD er = ::GetLastError(); 107 DWORD er = ::GetLastError();
105 if (ERROR_INSUFFICIENT_BUFFER == er) 108 if (ERROR_INSUFFICIENT_BUFFER == er)
@@ -109,7 +112,7 @@ extern "C" HRESULT DAPI InternetQueryInfoString(
109 hr = StrAlloc(psczValue, cbValue / sizeof(WCHAR)); 112 hr = StrAlloc(psczValue, cbValue / sizeof(WCHAR));
110 InetExitOnFailure(hr, "Failed to allocate value."); 113 InetExitOnFailure(hr, "Failed to allocate value.");
111 114
112 if (!::HttpQueryInfoW(hRequest, dwInfo, static_cast<void*>(*psczValue), reinterpret_cast<DWORD*>(&cbValue), &dwIndex)) 115 if (!::HttpQueryInfoW(hRequest, dwInfo, static_cast<void*>(*psczValue), &cbValue, &dwIndex))
113 { 116 {
114 er = ::GetLastError(); 117 er = ::GetLastError();
115 } 118 }
diff --git a/src/dutil/logutil.cpp b/src/dutil/logutil.cpp
index 35251274..ac68036a 100644
--- a/src/dutil/logutil.cpp
+++ b/src/dutil/logutil.cpp
@@ -776,11 +776,15 @@ extern "C" HRESULT LogStringWorkRaw(
776 Assert(szLogData && *szLogData); 776 Assert(szLogData && *szLogData);
777 777
778 HRESULT hr = S_OK; 778 HRESULT hr = S_OK;
779 size_t cchLogData = 0;
779 DWORD cbLogData = 0; 780 DWORD cbLogData = 0;
780 DWORD cbTotal = 0; 781 DWORD cbTotal = 0;
781 DWORD cbWrote = 0; 782 DWORD cbWrote = 0;
782 783
783 cbLogData = lstrlenA(szLogData); 784 hr = ::StringCchLengthA(szLogData, STRSAFE_MAX_CCH, &cchLogData);
785 LoguExitOnRootFailure(hr, "Failed to get length of raw string");
786
787 cbLogData = (DWORD)cchLogData;
784 788
785 // If the log hasn't been initialized yet, store it in a buffer 789 // If the log hasn't been initialized yet, store it in a buffer
786 if (INVALID_HANDLE_VALUE == LogUtil_hLog) 790 if (INVALID_HANDLE_VALUE == LogUtil_hLog)
diff --git a/src/dutil/metautil.cpp b/src/dutil/metautil.cpp
index 109cd31e..f313fc1c 100644
--- a/src/dutil/metautil.cpp
+++ b/src/dutil/metautil.cpp
@@ -299,7 +299,14 @@ extern "C" HRESULT DAPI MetaGetValue(
299 MetaExitOnNull(pmr->pbMDData, hr, E_OUTOFMEMORY, "failed to allocate memory for metabase value"); 299 MetaExitOnNull(pmr->pbMDData, hr, E_OUTOFMEMORY, "failed to allocate memory for metabase value");
300 } 300 }
301 else // set the size of the data to the actual size of the memory 301 else // set the size of the data to the actual size of the memory
302 pmr->dwMDDataLen = (DWORD)MemSize(pmr->pbMDData); 302 {
303 SIZE_T cb = MemSize(pmr->pbMDData);
304 if (cb > DWORD_MAX)
305 {
306 MetaExitOnRootFailure(hr = E_INVALIDSTATE, "metabase data is too large: %Iu", cb);
307 }
308 pmr->dwMDDataLen = (DWORD)cb;
309 }
303 310
304 hr = piMetabase->GetData(mhKey, wzKey, pmr, &cbRequired); 311 hr = piMetabase->GetData(mhKey, wzKey, pmr, &cbRequired);
305 if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) 312 if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr)
diff --git a/src/dutil/pathutil.cpp b/src/dutil/pathutil.cpp
index 183849ac..7c3cfe06 100644
--- a/src/dutil/pathutil.cpp
+++ b/src/dutil/pathutil.cpp
@@ -181,7 +181,7 @@ DAPI_(HRESULT) PathGetDirectory(
181 ) 181 )
182{ 182{
183 HRESULT hr = S_OK; 183 HRESULT hr = S_OK;
184 DWORD cchDirectory = DWORD_MAX; 184 size_t cchDirectory = SIZE_T_MAX;
185 185
186 for (LPCWSTR wz = wzPath; *wz; ++wz) 186 for (LPCWSTR wz = wzPath; *wz; ++wz)
187 { 187 {
@@ -191,11 +191,11 @@ DAPI_(HRESULT) PathGetDirectory(
191 // : => relative path from mapped root 191 // : => relative path from mapped root
192 if (L'\\' == *wz || L'/' == *wz || (L':' == *wz && wz == wzPath + 1)) 192 if (L'\\' == *wz || L'/' == *wz || (L':' == *wz && wz == wzPath + 1))
193 { 193 {
194 cchDirectory = static_cast<DWORD>(wz - wzPath) + 1; 194 cchDirectory = static_cast<size_t>(wz - wzPath) + 1;
195 } 195 }
196 } 196 }
197 197
198 if (DWORD_MAX == cchDirectory) 198 if (SIZE_T_MAX == cchDirectory)
199 { 199 {
200 // we were given just a file name, so there's no directory available 200 // we were given just a file name, so there's no directory available
201 return S_FALSE; 201 return S_FALSE;
@@ -233,7 +233,7 @@ DAPI_(HRESULT) PathGetParentPath(
233 233
234 if (wzParent) 234 if (wzParent)
235 { 235 {
236 DWORD cchPath = static_cast<DWORD>(wzParent - wzPath) + 1; 236 size_t cchPath = static_cast<size_t>(wzParent - wzPath) + 1;
237 237
238 hr = StrAllocString(psczParent, wzPath, cchPath); 238 hr = StrAllocString(psczParent, wzPath, cchPath);
239 PathExitOnFailure(hr, "Failed to copy directory."); 239 PathExitOnFailure(hr, "Failed to copy directory.");
@@ -260,6 +260,7 @@ DAPI_(HRESULT) PathExpand(
260 DWORD cch = 0; 260 DWORD cch = 0;
261 LPWSTR sczExpandedPath = NULL; 261 LPWSTR sczExpandedPath = NULL;
262 DWORD cchExpandedPath = 0; 262 DWORD cchExpandedPath = 0;
263 SIZE_T cbSize = 0;
263 264
264 LPWSTR sczFullPath = NULL; 265 LPWSTR sczFullPath = NULL;
265 266
@@ -305,8 +306,10 @@ DAPI_(HRESULT) PathExpand(
305 } 306 }
306 PathExitOnFailure(hr, "Failed to prefix long path after expanding environment variables."); 307 PathExitOnFailure(hr, "Failed to prefix long path after expanding environment variables.");
307 308
308 hr = StrMaxLength(sczExpandedPath, reinterpret_cast<DWORD_PTR *>(&cchExpandedPath)); 309 hr = StrMaxLength(sczExpandedPath, &cbSize);
309 PathExitOnFailure(hr, "Failed to get max length of expanded path."); 310 PathExitOnFailure(hr, "Failed to get max length of expanded path.");
311
312 cchExpandedPath = (DWORD)min(DWORD_MAX, cbSize);
310 } 313 }
311 } 314 }
312 315
@@ -317,7 +320,7 @@ DAPI_(HRESULT) PathExpand(
317 { 320 {
318 LPWSTR wzFileName = NULL; 321 LPWSTR wzFileName = NULL;
319 LPCWSTR wzPath = sczExpandedPath ? sczExpandedPath : wzRelativePath; 322 LPCWSTR wzPath = sczExpandedPath ? sczExpandedPath : wzRelativePath;
320 DWORD cchFullPath = PATH_GOOD_ENOUGH < cchExpandedPath ? cchExpandedPath : PATH_GOOD_ENOUGH; 323 DWORD cchFullPath = max(PATH_GOOD_ENOUGH, cchExpandedPath);
321 324
322 hr = StrAlloc(&sczFullPath, cchFullPath); 325 hr = StrAlloc(&sczFullPath, cchFullPath);
323 PathExitOnFailure(hr, "Failed to allocate space for full path."); 326 PathExitOnFailure(hr, "Failed to allocate space for full path.");
@@ -836,8 +839,7 @@ DAPI_(BOOL) PathIsAbsolute(
836 __in_z LPCWSTR wzPath 839 __in_z LPCWSTR wzPath
837 ) 840 )
838{ 841{
839 DWORD dwLength = lstrlenW(wzPath); 842 return wzPath && wzPath[0] && wzPath[1] && (wzPath[0] == L'\\') || (wzPath[1] == L':');
840 return (1 < dwLength) && (wzPath[0] == L'\\') || (wzPath[1] == L':');
841} 843}
842 844
843 845
@@ -847,27 +849,39 @@ DAPI_(HRESULT) PathConcat(
847 __deref_out_z LPWSTR* psczCombined 849 __deref_out_z LPWSTR* psczCombined
848 ) 850 )
849{ 851{
852 return PathConcatCch(wzPath1, 0, wzPath2, 0, psczCombined);
853}
854
855
856DAPI_(HRESULT) PathConcatCch(
857 __in_opt LPCWSTR wzPath1,
858 __in SIZE_T cchPath1,
859 __in_opt LPCWSTR wzPath2,
860 __in SIZE_T cchPath2,
861 __deref_out_z LPWSTR* psczCombined
862 )
863{
850 HRESULT hr = S_OK; 864 HRESULT hr = S_OK;
851 865
852 if (!wzPath2 || !*wzPath2) 866 if (!wzPath2 || !*wzPath2)
853 { 867 {
854 hr = StrAllocString(psczCombined, wzPath1, 0); 868 hr = StrAllocString(psczCombined, wzPath1, cchPath1);
855 PathExitOnFailure(hr, "Failed to copy just path1 to output."); 869 PathExitOnFailure(hr, "Failed to copy just path1 to output.");
856 } 870 }
857 else if (!wzPath1 || !*wzPath1 || PathIsAbsolute(wzPath2)) 871 else if (!wzPath1 || !*wzPath1 || PathIsAbsolute(wzPath2))
858 { 872 {
859 hr = StrAllocString(psczCombined, wzPath2, 0); 873 hr = StrAllocString(psczCombined, wzPath2, cchPath2);
860 PathExitOnFailure(hr, "Failed to copy just path2 to output."); 874 PathExitOnFailure(hr, "Failed to copy just path2 to output.");
861 } 875 }
862 else 876 else
863 { 877 {
864 hr = StrAllocString(psczCombined, wzPath1, 0); 878 hr = StrAllocString(psczCombined, wzPath1, cchPath1);
865 PathExitOnFailure(hr, "Failed to copy path1 to output."); 879 PathExitOnFailure(hr, "Failed to copy path1 to output.");
866 880
867 hr = PathBackslashTerminate(psczCombined); 881 hr = PathBackslashTerminate(psczCombined);
868 PathExitOnFailure(hr, "Failed to backslashify."); 882 PathExitOnFailure(hr, "Failed to backslashify.");
869 883
870 hr = StrAllocConcat(psczCombined, wzPath2, 0); 884 hr = StrAllocConcat(psczCombined, wzPath2, cchPath2);
871 PathExitOnFailure(hr, "Failed to append path2 to output."); 885 PathExitOnFailure(hr, "Failed to append path2 to output.");
872 } 886 }
873 887
@@ -1001,15 +1015,25 @@ DAPI_(HRESULT) PathGetHierarchyArray(
1001 LPWSTR sczPathCopy = NULL; 1015 LPWSTR sczPathCopy = NULL;
1002 LPWSTR sczNewPathCopy = NULL; 1016 LPWSTR sczNewPathCopy = NULL;
1003 DWORD cArraySpacesNeeded = 0; 1017 DWORD cArraySpacesNeeded = 0;
1018 size_t cchPath = 0;
1019
1020 hr = ::StringCchLengthW(wzPath, STRSAFE_MAX_LENGTH, &cchPath);
1021 PathExitOnRootFailure(hr, "Failed to get string length of path: %ls", wzPath);
1022
1023 if (!cchPath)
1024 {
1025 ExitFunction1(hr = E_INVALIDARG);
1026 }
1004 1027
1005 for (int i = 0; i < lstrlenW(wzPath); ++i) 1028 for (size_t i = 0; i < cchPath; ++i)
1006 { 1029 {
1007 if (wzPath[i] == L'\\') 1030 if (wzPath[i] == L'\\')
1008 { 1031 {
1009 ++cArraySpacesNeeded; 1032 ++cArraySpacesNeeded;
1010 } 1033 }
1011 } 1034 }
1012 if (wzPath[lstrlenW(wzPath) - 1] != L'\\') 1035
1036 if (wzPath[cchPath - 1] != L'\\')
1013 { 1037 {
1014 ++cArraySpacesNeeded; 1038 ++cArraySpacesNeeded;
1015 } 1039 }
@@ -1034,10 +1058,12 @@ DAPI_(HRESULT) PathGetHierarchyArray(
1034 hr = StrAllocString((*prgsczPathArray) + cArraySpacesNeeded - 1 - i, sczPathCopy, 0); 1058 hr = StrAllocString((*prgsczPathArray) + cArraySpacesNeeded - 1 - i, sczPathCopy, 0);
1035 PathExitOnFailure(hr, "Failed to copy path"); 1059 PathExitOnFailure(hr, "Failed to copy path");
1036 1060
1061 DWORD cchPathCopy = lstrlenW(sczPathCopy);
1062
1037 // If it ends in a backslash, it's a directory path, so cut off everything the last backslash before we get the directory portion of the path 1063 // If it ends in a backslash, it's a directory path, so cut off everything the last backslash before we get the directory portion of the path
1038 if (wzPath[lstrlenW(sczPathCopy) - 1] == L'\\') 1064 if (wzPath[cchPathCopy - 1] == L'\\')
1039 { 1065 {
1040 sczPathCopy[lstrlenW(sczPathCopy) - 1] = L'\0'; 1066 sczPathCopy[cchPathCopy - 1] = L'\0';
1041 } 1067 }
1042 1068
1043 hr = PathGetDirectory(sczPathCopy, &sczNewPathCopy); 1069 hr = PathGetDirectory(sczPathCopy, &sczNewPathCopy);
diff --git a/src/dutil/regutil.cpp b/src/dutil/regutil.cpp
index afd2d089..cb617932 100644
--- a/src/dutil/regutil.cpp
+++ b/src/dutil/regutil.cpp
@@ -294,12 +294,15 @@ extern "C" HRESULT DAPI RegKeyEnum(
294{ 294{
295 HRESULT hr = S_OK; 295 HRESULT hr = S_OK;
296 DWORD er = ERROR_SUCCESS; 296 DWORD er = ERROR_SUCCESS;
297 SIZE_T cb = 0;
297 DWORD cch = 0; 298 DWORD cch = 0;
298 299
299 if (psczKey && *psczKey) 300 if (psczKey && *psczKey)
300 { 301 {
301 hr = StrMaxLength(*psczKey, reinterpret_cast<DWORD_PTR*>(&cch)); 302 hr = StrMaxLength(*psczKey, &cb);
302 RegExitOnFailure(hr, "Failed to determine length of string."); 303 RegExitOnFailure(hr, "Failed to determine length of string.");
304
305 cch = (DWORD)min(DWORD_MAX, cb);
303 } 306 }
304 307
305 if (2 > cch) 308 if (2 > cch)
@@ -462,6 +465,7 @@ extern "C" HRESULT DAPI RegReadString(
462{ 465{
463 HRESULT hr = S_OK; 466 HRESULT hr = S_OK;
464 DWORD er = ERROR_SUCCESS; 467 DWORD er = ERROR_SUCCESS;
468 SIZE_T cbValue = 0;
465 DWORD cch = 0; 469 DWORD cch = 0;
466 DWORD cb = 0; 470 DWORD cb = 0;
467 DWORD dwType = 0; 471 DWORD dwType = 0;
@@ -469,8 +473,10 @@ extern "C" HRESULT DAPI RegReadString(
469 473
470 if (psczValue && *psczValue) 474 if (psczValue && *psczValue)
471 { 475 {
472 hr = StrMaxLength(*psczValue, reinterpret_cast<DWORD_PTR*>(&cch)); 476 hr = StrMaxLength(*psczValue, &cbValue);
473 RegExitOnFailure(hr, "Failed to determine length of string."); 477 RegExitOnFailure(hr, "Failed to determine length of string.");
478
479 cch = (DWORD)min(DWORD_MAX, cbValue);
474 } 480 }
475 481
476 if (2 > cch) 482 if (2 > cch)
@@ -1000,18 +1006,18 @@ static HRESULT WriteStringToRegistry(
1000 __in_z_opt LPCWSTR wzName, 1006 __in_z_opt LPCWSTR wzName,
1001 __in_z_opt LPCWSTR wzValue, 1007 __in_z_opt LPCWSTR wzValue,
1002 __in DWORD dwType 1008 __in DWORD dwType
1003) 1009 )
1004{ 1010{
1005 HRESULT hr = S_OK; 1011 HRESULT hr = S_OK;
1006 DWORD er = ERROR_SUCCESS; 1012 DWORD er = ERROR_SUCCESS;
1007 DWORD cbValue = 0; 1013 size_t cbValue = 0;
1008 1014
1009 if (wzValue) 1015 if (wzValue)
1010 { 1016 {
1011 hr = ::StringCbLengthW(wzValue, STRSAFE_MAX_CCH * sizeof(TCHAR), reinterpret_cast<size_t*>(&cbValue)); 1017 hr = ::StringCbLengthW(wzValue, STRSAFE_MAX_CCH * sizeof(TCHAR), &cbValue);
1012 RegExitOnFailure(hr, "Failed to determine length of registry value: %ls", wzName); 1018 RegExitOnFailure(hr, "Failed to determine length of registry value: %ls", wzName);
1013 1019
1014 er = vpfnRegSetValueExW(hk, wzName, 0, dwType, reinterpret_cast<const BYTE *>(wzValue), cbValue); 1020 er = vpfnRegSetValueExW(hk, wzName, 0, dwType, reinterpret_cast<const BYTE *>(wzValue), static_cast<DWORD>(cbValue));
1015 RegExitOnWin32Error(er, hr, "Failed to set registry value: %ls", wzName); 1021 RegExitOnWin32Error(er, hr, "Failed to set registry value: %ls", wzName);
1016 } 1022 }
1017 else 1023 else
diff --git a/src/dutil/reswutil.cpp b/src/dutil/reswutil.cpp
index 42b49c55..e78de84a 100644
--- a/src/dutil/reswutil.cpp
+++ b/src/dutil/reswutil.cpp
@@ -288,13 +288,16 @@ static HRESULT StringBlockChangeString(
288{ 288{
289 HRESULT hr = S_OK; 289 HRESULT hr = S_OK;
290 LPWSTR pwzData = NULL; 290 LPWSTR pwzData = NULL;
291 DWORD cchData = lstrlenW(szData); 291 size_t cchData = 0;
292
293 hr = ::StringCchLengthW(szData, STRSAFE_MAX_LENGTH, &cchData);
294 ReswExitOnRootFailure(hr, "Failed to get block string length.");
292 295
293 pwzData = static_cast<LPWSTR>(MemAlloc((cchData + 1) * sizeof(WCHAR), TRUE)); 296 pwzData = static_cast<LPWSTR>(MemAlloc((cchData + 1) * sizeof(WCHAR), TRUE));
294 ReswExitOnNull(pwzData, hr, E_OUTOFMEMORY, "Failed to allocate new block string."); 297 ReswExitOnNull(pwzData, hr, E_OUTOFMEMORY, "Failed to allocate new block string.");
295 298
296 hr = ::StringCchCopyW(pwzData, cchData + 1, szData); 299 hr = ::StringCchCopyW(pwzData, cchData + 1, szData);
297 ReswExitOnFailure(hr, "Failed to copy new block string."); 300 ReswExitOnRootFailure(hr, "Failed to copy new block string.");
298 301
299 ReleaseNullMem(pStrBlock->rgwz[dwStringId]); 302 ReleaseNullMem(pStrBlock->rgwz[dwStringId]);
300 303
diff --git a/src/dutil/strutil.cpp b/src/dutil/strutil.cpp
index daa090c9..550d6169 100644
--- a/src/dutil/strutil.cpp
+++ b/src/dutil/strutil.cpp
@@ -46,7 +46,7 @@ static HRESULT AllocFormattedArgsHelper(
46static HRESULT StrAllocStringMapInvariant( 46static HRESULT StrAllocStringMapInvariant(
47 __deref_out_z LPWSTR* pscz, 47 __deref_out_z LPWSTR* pscz,
48 __in_z LPCWSTR wzSource, 48 __in_z LPCWSTR wzSource,
49 __in int cchSource, 49 __in SIZE_T cchSource,
50 __in DWORD dwMapFlags 50 __in DWORD dwMapFlags
51 ); 51 );
52 52
@@ -146,7 +146,7 @@ HRESULT DAPI StrTrimCapacity(
146 SIZE_T cchLen = 0; 146 SIZE_T cchLen = 0;
147 147
148 hr = ::StringCchLengthW(*ppwz, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen)); 148 hr = ::StringCchLengthW(*ppwz, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen));
149 StrExitOnFailure(hr, "Failed to calculate length of string"); 149 StrExitOnRootFailure(hr, "Failed to calculate length of string");
150 150
151 ++cchLen; // Add 1 for null-terminator 151 ++cchLen; // Add 1 for null-terminator
152 152
@@ -170,7 +170,7 @@ HRESULT DAPI StrTrimWhitespace(
170 ) 170 )
171{ 171{
172 HRESULT hr = S_OK; 172 HRESULT hr = S_OK;
173 int i = 0; 173 size_t i = 0;
174 LPWSTR sczResult = NULL; 174 LPWSTR sczResult = NULL;
175 175
176 // Ignore beginning whitespace 176 // Ignore beginning whitespace
@@ -179,7 +179,9 @@ HRESULT DAPI StrTrimWhitespace(
179 wzSource++; 179 wzSource++;
180 } 180 }
181 181
182 i = lstrlenW(wzSource); 182 hr = ::StringCchLengthW(wzSource, STRSAFE_MAX_CCH, &i);
183 StrExitOnRootFailure(hr, "Failed to get length of string");
184
183 // Overwrite ending whitespace with null characters 185 // Overwrite ending whitespace with null characters
184 if (0 < i) 186 if (0 < i)
185 { 187 {
@@ -291,7 +293,7 @@ HRESULT DAPI StrAnsiTrimWhitespace(
291 ) 293 )
292{ 294{
293 HRESULT hr = S_OK; 295 HRESULT hr = S_OK;
294 int i = 0; 296 size_t i = 0;
295 LPSTR sczResult = NULL; 297 LPSTR sczResult = NULL;
296 298
297 // Ignore beginning whitespace 299 // Ignore beginning whitespace
@@ -300,7 +302,9 @@ HRESULT DAPI StrAnsiTrimWhitespace(
300 szSource++; 302 szSource++;
301 } 303 }
302 304
303 i = lstrlen(szSource); 305 hr = ::StringCchLengthA(szSource, STRSAFE_MAX_CCH, &i);
306 StrExitOnRootFailure(hr, "Failed to get length of string");
307
304 // Overwrite ending whitespace with null characters 308 // Overwrite ending whitespace with null characters
305 if (0 < i) 309 if (0 < i)
306 { 310 {
@@ -395,14 +399,15 @@ static HRESULT AllocStringHelper(
395 cch /= sizeof(WCHAR); //convert the count in bytes to count in characters 399 cch /= sizeof(WCHAR); //convert the count in bytes to count in characters
396 } 400 }
397 401
398 if (0 == cchSource) 402 if (0 == cchSource && wzSource)
399 { 403 {
400 cchSource = lstrlenW(wzSource); 404 hr = ::StringCchLengthW(wzSource, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchSource));
405 StrExitOnRootFailure(hr, "failed to get length of source string");
401 } 406 }
402 407
403 SIZE_T cchNeeded; 408 SIZE_T cchNeeded;
404 hr = ::ULongPtrAdd(cchSource, 1, &cchNeeded); // add one for the null terminator 409 hr = ::ULongPtrAdd(cchSource, 1, &cchNeeded); // add one for the null terminator
405 StrExitOnFailure(hr, "source string is too long"); 410 StrExitOnRootFailure(hr, "source string is too long");
406 411
407 if (cch < cchNeeded) 412 if (cch < cchNeeded)
408 { 413 {
@@ -604,19 +609,20 @@ HRESULT DAPI StrAnsiAllocStringAnsi(
604 if (-1 == cch) 609 if (-1 == cch)
605 { 610 {
606 hr = E_INVALIDARG; 611 hr = E_INVALIDARG;
607 StrExitOnFailure(hr, "failed to get size of destination string"); 612 StrExitOnRootFailure(hr, "failed to get size of destination string");
608 } 613 }
609 cch /= sizeof(CHAR); //convert the count in bytes to count in characters 614 cch /= sizeof(CHAR); //convert the count in bytes to count in characters
610 } 615 }
611 616
612 if (0 == cchSource) 617 if (0 == cchSource && szSource)
613 { 618 {
614 cchSource = lstrlenA(szSource); 619 hr = ::StringCchLengthA(szSource, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchSource));
620 StrExitOnRootFailure(hr, "failed to get length of source string");
615 } 621 }
616 622
617 SIZE_T cchNeeded; 623 SIZE_T cchNeeded;
618 hr = ::ULongPtrAdd(cchSource, 1, &cchNeeded); // add one for the null terminator 624 hr = ::ULongPtrAdd(cchSource, 1, &cchNeeded); // add one for the null terminator
619 StrExitOnFailure(hr, "source string is too long"); 625 StrExitOnRootFailure(hr, "source string is too long");
620 626
621 if (cch < cchNeeded) 627 if (cch < cchNeeded)
622 { 628 {
@@ -1075,7 +1081,7 @@ static HRESULT AllocFormattedArgsHelper(
1075 SIZE_T cch = 0; 1081 SIZE_T cch = 0;
1076 LPWSTR pwzOriginal = NULL; 1082 LPWSTR pwzOriginal = NULL;
1077 SIZE_T cbOriginal = 0; 1083 SIZE_T cbOriginal = 0;
1078 SIZE_T cchOriginal = 0; 1084 size_t cchOriginal = 0;
1079 1085
1080 if (*ppwz) 1086 if (*ppwz)
1081 { 1087 {
@@ -1083,11 +1089,13 @@ static HRESULT AllocFormattedArgsHelper(
1083 if (-1 == cbOriginal) 1089 if (-1 == cbOriginal)
1084 { 1090 {
1085 hr = E_INVALIDARG; 1091 hr = E_INVALIDARG;
1086 StrExitOnFailure(hr, "failed to get size of destination string"); 1092 StrExitOnRootFailure(hr, "failed to get size of destination string");
1087 } 1093 }
1088 1094
1089 cch = cbOriginal / sizeof(WCHAR); //convert the count in bytes to count in characters 1095 cch = cbOriginal / sizeof(WCHAR); //convert the count in bytes to count in characters
1090 cchOriginal = lstrlenW(*ppwz); 1096
1097 hr = ::StringCchLengthW(*ppwz, STRSAFE_MAX_CCH, &cchOriginal);
1098 StrExitOnRootFailure(hr, "failed to get length of original string");
1091 } 1099 }
1092 1100
1093 if (0 == cch) // if there is no space in the string buffer 1101 if (0 == cch) // if there is no space in the string buffer
@@ -1124,7 +1132,7 @@ static HRESULT AllocFormattedArgsHelper(
1124 hr = S_FALSE; 1132 hr = S_FALSE;
1125 } 1133 }
1126 } while (S_FALSE == hr); 1134 } while (S_FALSE == hr);
1127 StrExitOnFailure(hr, "failed to format string"); 1135 StrExitOnRootFailure(hr, "failed to format string");
1128 1136
1129LExit: 1137LExit:
1130 if (pwzOriginal && fZeroOnRealloc) 1138 if (pwzOriginal && fZeroOnRealloc)
@@ -1155,7 +1163,7 @@ extern "C" HRESULT DAPI StrAnsiAllocFormattedArgs(
1155 HRESULT hr = S_OK; 1163 HRESULT hr = S_OK;
1156 SIZE_T cch = *ppsz ? MemSize(*ppsz) / sizeof(CHAR) : 0; 1164 SIZE_T cch = *ppsz ? MemSize(*ppsz) / sizeof(CHAR) : 0;
1157 LPSTR pszOriginal = NULL; 1165 LPSTR pszOriginal = NULL;
1158 DWORD cchOriginal = 0; 1166 size_t cchOriginal = 0;
1159 1167
1160 if (*ppsz) 1168 if (*ppsz)
1161 { 1169 {
@@ -1163,11 +1171,12 @@ extern "C" HRESULT DAPI StrAnsiAllocFormattedArgs(
1163 if (-1 == cch) 1171 if (-1 == cch)
1164 { 1172 {
1165 hr = E_INVALIDARG; 1173 hr = E_INVALIDARG;
1166 StrExitOnFailure(hr, "failed to get size of destination string"); 1174 StrExitOnRootFailure(hr, "failed to get size of destination string");
1167 } 1175 }
1168 cch /= sizeof(CHAR); //convert the count in bytes to count in characters 1176 cch /= sizeof(CHAR); //convert the count in bytes to count in characters
1169 1177
1170 cchOriginal = lstrlenA(*ppsz); 1178 hr = ::StringCchLengthA(*ppsz, STRSAFE_MAX_CCH, &cchOriginal);
1179 StrExitOnRootFailure(hr, "failed to get length of original string");
1171 } 1180 }
1172 1181
1173 if (0 == cch) // if there is no space in the string buffer 1182 if (0 == cch) // if there is no space in the string buffer
@@ -1202,7 +1211,7 @@ extern "C" HRESULT DAPI StrAnsiAllocFormattedArgs(
1202 hr = S_FALSE; 1211 hr = S_FALSE;
1203 } 1212 }
1204 } while (S_FALSE == hr); 1213 } while (S_FALSE == hr);
1205 StrExitOnFailure(hr, "failed to format string"); 1214 StrExitOnRootFailure(hr, "failed to format string");
1206 1215
1207LExit: 1216LExit:
1208 ReleaseStr(pszOriginal); 1217 ReleaseStr(pszOriginal);
@@ -1375,6 +1384,8 @@ extern "C" HRESULT DAPI StrReplaceString(
1375 HRESULT hr = S_FALSE; 1384 HRESULT hr = S_FALSE;
1376 LPCWSTR wzSubLocation = NULL; 1385 LPCWSTR wzSubLocation = NULL;
1377 LPWSTR pwzBuffer = NULL; 1386 LPWSTR pwzBuffer = NULL;
1387 size_t cchOldSubString = 0;
1388 size_t cchNewSubString = 0;
1378 1389
1379 if (!*ppwzOriginal) 1390 if (!*ppwzOriginal)
1380 { 1391 {
@@ -1387,8 +1398,20 @@ extern "C" HRESULT DAPI StrReplaceString(
1387 ExitFunction(); 1398 ExitFunction();
1388 } 1399 }
1389 1400
1401 if (wzOldSubString)
1402 {
1403 hr = ::StringCchLengthW(wzOldSubString, STRSAFE_MAX_CCH, &cchOldSubString);
1404 StrExitOnRootFailure(hr, "Failed to get old string length.");
1405 }
1406
1407 if (wzNewSubString)
1408 {
1409 hr = ::StringCchLengthW(wzNewSubString, STRSAFE_MAX_CCH, &cchNewSubString);
1410 StrExitOnRootFailure(hr, "Failed to get new string length.");
1411 }
1412
1390 hr = ::PtrdiffTToDWord(wzSubLocation - *ppwzOriginal, pdwStartIndex); 1413 hr = ::PtrdiffTToDWord(wzSubLocation - *ppwzOriginal, pdwStartIndex);
1391 StrExitOnFailure(hr, "Failed to diff pointers."); 1414 StrExitOnRootFailure(hr, "Failed to diff pointers.");
1392 1415
1393 hr = StrAllocString(&pwzBuffer, *ppwzOriginal, wzSubLocation - *ppwzOriginal); 1416 hr = StrAllocString(&pwzBuffer, *ppwzOriginal, wzSubLocation - *ppwzOriginal);
1394 StrExitOnFailure(hr, "Failed to duplicate string."); 1417 StrExitOnFailure(hr, "Failed to duplicate string.");
@@ -1398,14 +1421,14 @@ extern "C" HRESULT DAPI StrReplaceString(
1398 hr = StrAllocConcat(&pwzBuffer, wzNewSubString, 0); 1421 hr = StrAllocConcat(&pwzBuffer, wzNewSubString, 0);
1399 StrExitOnFailure(hr, "Failed to append new string."); 1422 StrExitOnFailure(hr, "Failed to append new string.");
1400 1423
1401 hr = StrAllocConcat(&pwzBuffer, wzSubLocation + wcslen(wzOldSubString), 0); 1424 hr = StrAllocConcat(&pwzBuffer, wzSubLocation + cchOldSubString, 0);
1402 StrExitOnFailure(hr, "Failed to append post string."); 1425 StrExitOnFailure(hr, "Failed to append post string.");
1403 1426
1404 hr = StrFree(*ppwzOriginal); 1427 hr = StrFree(*ppwzOriginal);
1405 StrExitOnFailure(hr, "Failed to free original string."); 1428 StrExitOnFailure(hr, "Failed to free original string.");
1406 1429
1407 *ppwzOriginal = pwzBuffer; 1430 *ppwzOriginal = pwzBuffer;
1408 *pdwStartIndex = *pdwStartIndex + static_cast<DWORD>(wcslen(wzNewSubString)); 1431 *pdwStartIndex = *pdwStartIndex + static_cast<DWORD>(cchNewSubString);
1409 hr = S_OK; 1432 hr = S_OK;
1410 1433
1411LExit: 1434LExit:
@@ -1516,15 +1539,18 @@ extern "C" HRESULT DAPI StrHexDecode(
1516 Assert(wzSource && pbDest); 1539 Assert(wzSource && pbDest);
1517 1540
1518 HRESULT hr = S_OK; 1541 HRESULT hr = S_OK;
1519 DWORD cchSource = lstrlenW(wzSource); 1542 size_t cchSource = 0;
1520 DWORD i; 1543 size_t i = 0;
1521 BYTE b; 1544 BYTE b = 0;
1545
1546 hr = ::StringCchLengthW(wzSource, STRSAFE_MAX_CCH, &cchSource);
1547 StrExitOnRootFailure(hr, "Failed to get length of hex string: %ls", wzSource);
1522 1548
1523 Assert(0 == cchSource % 2); 1549 Assert(0 == cchSource % 2);
1524 if (cbDest < cchSource / 2) 1550 if (cbDest < cchSource / 2)
1525 { 1551 {
1526 hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); 1552 hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
1527 StrExitOnRootFailure(hr, "Insufficient buffer to decode string '%ls' len: %u into %u bytes.", wzSource, cchSource, cbDest); 1553 StrExitOnRootFailure(hr, "Insufficient buffer to decode string '%ls' len: %Iu into %Iu bytes.", wzSource, cchSource, cbDest);
1528 } 1554 }
1529 1555
1530 for (i = 0; i < cchSource / 2; ++i) 1556 for (i = 0; i < cchSource / 2; ++i)
@@ -1728,17 +1754,20 @@ extern "C" HRESULT DAPI StrAllocBase85Decode(
1728 ) 1754 )
1729{ 1755{
1730 HRESULT hr = S_OK; 1756 HRESULT hr = S_OK;
1731 SIZE_T cchSource = lstrlenW(wzSource); 1757 size_t cchSource = 0;
1732 DWORD_PTR i, n, k; 1758 DWORD_PTR i, n, k;
1733 1759
1734 BYTE* pbDest; 1760 BYTE* pbDest = 0;
1735 SIZE_T cbDest; 1761 SIZE_T cbDest = 0;
1736 1762
1737 if (!wzSource || !ppbDest || !pcbDest) 1763 if (!wzSource || !ppbDest || !pcbDest)
1738 { 1764 {
1739 return E_INVALIDARG; 1765 ExitFunction1(hr = E_INVALIDARG);
1740 } 1766 }
1741 1767
1768 hr = ::StringCchLengthW(wzSource, STRSAFE_MAX_CCH, &cchSource);
1769 StrExitOnRootFailure(hr, "failed to get length of base 85 string: %ls", wzSource);
1770
1742 // evaluate size of output and check it 1771 // evaluate size of output and check it
1743 k = cchSource / 5; 1772 k = cchSource / 5;
1744 cbDest = k << 2; 1773 cbDest = k << 2;
@@ -1932,7 +1961,8 @@ extern "C" HRESULT DAPI MultiSzPrepend(
1932 StrExitOnFailure(hr, "failed to get length of multisz"); 1961 StrExitOnFailure(hr, "failed to get length of multisz");
1933 } 1962 }
1934 1963
1935 cchInsert = lstrlenW(pwzInsert); 1964 hr = ::StringCchLengthW(pwzInsert, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchInsert));
1965 StrExitOnRootFailure(hr, "failed to get length of insert string");
1936 1966
1937 cchResult = cchInsert + cchMultiSz + 1; 1967 cchResult = cchInsert + cchMultiSz + 1;
1938 1968
@@ -1942,7 +1972,7 @@ extern "C" HRESULT DAPI MultiSzPrepend(
1942 1972
1943 // Prepend 1973 // Prepend
1944 hr = ::StringCchCopyW(pwzResult, cchResult, pwzInsert); 1974 hr = ::StringCchCopyW(pwzResult, cchResult, pwzInsert);
1945 StrExitOnFailure(hr, "failed to copy prepend string: %ls", pwzInsert); 1975 StrExitOnRootFailure(hr, "failed to copy prepend string: %ls", pwzInsert);
1946 1976
1947 // If there was no MULTISZ, double null terminate our result, otherwise, copy the MULTISZ in 1977 // If there was no MULTISZ, double null terminate our result, otherwise, copy the MULTISZ in
1948 if (0 == cchMultiSz) 1978 if (0 == cchMultiSz)
@@ -2207,9 +2237,12 @@ extern "C" HRESULT DAPI MultiSzInsertString(
2207 SIZE_T cchProgress = 0; 2237 SIZE_T cchProgress = 0;
2208 LPWSTR pwzResult = NULL; 2238 LPWSTR pwzResult = NULL;
2209 SIZE_T cchResult = 0; 2239 SIZE_T cchResult = 0;
2210 SIZE_T cchString = lstrlenW(pwzInsert); 2240 SIZE_T cchString = 0;
2211 SIZE_T cchMultiSz = 0; 2241 SIZE_T cchMultiSz = 0;
2212 2242
2243 hr = ::StringCchLengthW(pwzInsert, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchString));
2244 StrExitOnRootFailure(hr, "failed to get length of insert string");
2245
2213 if (pcchMultiSz && 0 != *pcchMultiSz) 2246 if (pcchMultiSz && 0 != *pcchMultiSz)
2214 { 2247 {
2215 cchMultiSz = *pcchMultiSz; 2248 cchMultiSz = *pcchMultiSz;
@@ -2464,11 +2497,15 @@ extern "C" HRESULT DAPI StrStringToInt64(
2464 INT iSign = 1; 2497 INT iSign = 1;
2465 INT nDigit = 0; 2498 INT nDigit = 0;
2466 LARGE_INTEGER liValue = { }; 2499 LARGE_INTEGER liValue = { };
2500 size_t cchString = 0;
2467 2501
2468 // get string length if not provided 2502 // get string length if not provided
2469 if (0 >= cchIn) 2503 if (0 >= cchIn)
2470 { 2504 {
2471 cchIn = lstrlenW(wzIn); 2505 hr = ::StringCchLengthW(wzIn, STRSAFE_MAX_CCH, &cchString);
2506 StrExitOnRootFailure(hr, "Failed to get length of string.");
2507
2508 cchIn = (DWORD)cchString;
2472 if (0 >= cchIn) 2509 if (0 >= cchIn)
2473 { 2510 {
2474 ExitFunction1(hr = E_INVALIDARG); 2511 ExitFunction1(hr = E_INVALIDARG);
@@ -2524,11 +2561,15 @@ extern "C" HRESULT DAPI StrStringToUInt64(
2524 DWORD nDigit = 0; 2561 DWORD nDigit = 0;
2525 ULONGLONG ullValue = 0; 2562 ULONGLONG ullValue = 0;
2526 ULONGLONG ull = 0; 2563 ULONGLONG ull = 0;
2564 size_t cchString = 0;
2527 2565
2528 // get string length if not provided 2566 // get string length if not provided
2529 if (0 >= cchIn) 2567 if (0 >= cchIn)
2530 { 2568 {
2531 cchIn = lstrlenW(wzIn); 2569 hr = ::StringCchLengthW(wzIn, STRSAFE_MAX_CCH, &cchString);
2570 StrExitOnRootFailure(hr, "Failed to get length of string.");
2571
2572 cchIn = (DWORD)cchString;
2532 if (0 >= cchIn) 2573 if (0 >= cchIn)
2533 { 2574 {
2534 ExitFunction1(hr = E_INVALIDARG); 2575 ExitFunction1(hr = E_INVALIDARG);
@@ -2588,7 +2629,7 @@ StrAllocStringToUpperInvariant - creates an upper-case copy of a string.
2588extern "C" HRESULT DAPI StrAllocStringToUpperInvariant( 2629extern "C" HRESULT DAPI StrAllocStringToUpperInvariant(
2589 __deref_out_z LPWSTR* pscz, 2630 __deref_out_z LPWSTR* pscz,
2590 __in_z LPCWSTR wzSource, 2631 __in_z LPCWSTR wzSource,
2591 __in int cchSource 2632 __in SIZE_T cchSource
2592 ) 2633 )
2593{ 2634{
2594 return StrAllocStringMapInvariant(pscz, wzSource, cchSource, LCMAP_UPPERCASE); 2635 return StrAllocStringMapInvariant(pscz, wzSource, cchSource, LCMAP_UPPERCASE);
@@ -2601,7 +2642,7 @@ StrAllocStringToLowerInvariant - creates an lower-case copy of a string.
2601extern "C" HRESULT DAPI StrAllocStringToLowerInvariant( 2642extern "C" HRESULT DAPI StrAllocStringToLowerInvariant(
2602 __deref_out_z LPWSTR* pscz, 2643 __deref_out_z LPWSTR* pscz,
2603 __in_z LPCWSTR wzSource, 2644 __in_z LPCWSTR wzSource,
2604 __in int cchSource 2645 __in SIZE_T cchSource
2605 ) 2646 )
2606{ 2647{
2607 return StrAllocStringMapInvariant(pscz, wzSource, cchSource, LCMAP_LOWERCASE); 2648 return StrAllocStringMapInvariant(pscz, wzSource, cchSource, LCMAP_LOWERCASE);
@@ -2704,7 +2745,7 @@ Note: Assumes source and destination buffers will be the same.
2704static HRESULT StrAllocStringMapInvariant( 2745static HRESULT StrAllocStringMapInvariant(
2705 __deref_out_z LPWSTR* pscz, 2746 __deref_out_z LPWSTR* pscz,
2706 __in_z LPCWSTR wzSource, 2747 __in_z LPCWSTR wzSource,
2707 __in int cchSource, 2748 __in SIZE_T cchSource,
2708 __in DWORD dwMapFlags 2749 __in DWORD dwMapFlags
2709 ) 2750 )
2710{ 2751{
@@ -2718,11 +2759,15 @@ static HRESULT StrAllocStringMapInvariant(
2718 // Need the actual string size for LCMapString. This includes the null-terminator 2759 // Need the actual string size for LCMapString. This includes the null-terminator
2719 // but LCMapString doesn't care either way. 2760 // but LCMapString doesn't care either way.
2720 hr = ::StringCchLengthW(*pscz, INT_MAX, reinterpret_cast<size_t*>(&cchSource)); 2761 hr = ::StringCchLengthW(*pscz, INT_MAX, reinterpret_cast<size_t*>(&cchSource));
2721 StrExitOnFailure(hr, "Failed to get the length of the string."); 2762 StrExitOnRootFailure(hr, "Failed to get the length of the string.");
2763 }
2764 else if (INT_MAX < cchSource)
2765 {
2766 StrExitOnRootFailure(hr = E_INVALIDARG, "Source string is too long: %Iu", cchSource);
2722 } 2767 }
2723 2768
2724 // Convert the copy of the string to upper or lower case in-place. 2769 // Convert the copy of the string to upper or lower case in-place.
2725 if (0 == ::LCMapStringW(LOCALE_INVARIANT, dwMapFlags, *pscz, cchSource, *pscz, cchSource)) 2770 if (0 == ::LCMapStringW(LOCALE_INVARIANT, dwMapFlags, *pscz, static_cast<int>(cchSource), *pscz, static_cast<int>(cchSource)))
2726 { 2771 {
2727 StrExitWithLastError(hr, "Failed to convert the string case."); 2772 StrExitWithLastError(hr, "Failed to convert the string case.");
2728 } 2773 }
diff --git a/src/dutil/thmutil.cpp b/src/dutil/thmutil.cpp
index d87e997d..d200a0ea 100644
--- a/src/dutil/thmutil.cpp
+++ b/src/dutil/thmutil.cpp
@@ -1519,13 +1519,16 @@ DAPI_(HRESULT) ThemeGetTextControl(
1519{ 1519{
1520 HRESULT hr = S_OK; 1520 HRESULT hr = S_OK;
1521 HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); 1521 HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1522 SIZE_T cbSize = 0;
1522 DWORD cchText = 0; 1523 DWORD cchText = 0;
1523 DWORD cchTextRead = 0; 1524 DWORD cchTextRead = 0;
1524 1525
1525 // Ensure the string has room for at least one character. 1526 // Ensure the string has room for at least one character.
1526 hr = StrMaxLength(*psczText, reinterpret_cast<DWORD_PTR*>(&cchText)); 1527 hr = StrMaxLength(*psczText, &cbSize);
1527 ThmExitOnFailure(hr, "Failed to get text buffer length."); 1528 ThmExitOnFailure(hr, "Failed to get text buffer length.");
1528 1529
1530 cchText = (DWORD)min(DWORD_MAX, cbSize);
1531
1529 if (!cchText) 1532 if (!cchText)
1530 { 1533 {
1531 cchText = GROW_WINDOW_TEXT; 1534 cchText = GROW_WINDOW_TEXT;
diff --git a/src/dutil/verutil.cpp b/src/dutil/verutil.cpp
index fdb5a10a..21626f94 100644
--- a/src/dutil/verutil.cpp
+++ b/src/dutil/verutil.cpp
@@ -244,7 +244,7 @@ DAPI_(void) VerFreeVersion(
244 244
245DAPI_(HRESULT) VerParseVersion( 245DAPI_(HRESULT) VerParseVersion(
246 __in_z LPCWSTR wzVersion, 246 __in_z LPCWSTR wzVersion,
247 __in DWORD cchVersion, 247 __in SIZE_T cchVersion,
248 __in BOOL fStrict, 248 __in BOOL fStrict,
249 __out VERUTIL_VERSION** ppVersion 249 __out VERUTIL_VERSION** ppVersion
250 ) 250 )
@@ -267,9 +267,14 @@ DAPI_(HRESULT) VerParseVersion(
267 } 267 }
268 268
269 // Get string length if not provided. 269 // Get string length if not provided.
270 if (0 == cchVersion) 270 if (!cchVersion)
271 { 271 {
272 cchVersion = lstrlenW(wzVersion); 272 hr = ::StringCchLengthW(wzVersion, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchVersion));
273 VerExitOnRootFailure(hr, "Failed to get length of version string: %ls", wzVersion);
274 }
275 else if (INT_MAX < cchVersion)
276 {
277 VerExitOnRootFailure(hr = E_INVALIDARG, "Version string is too long: %Iu", cchVersion);
273 } 278 }
274 279
275 if (L'v' == *wzVersion || L'V' == *wzVersion) 280 if (L'v' == *wzVersion || L'V' == *wzVersion)
diff --git a/src/dutil/xmlutil.cpp b/src/dutil/xmlutil.cpp
index 6ecd2449..0f1e611d 100644
--- a/src/dutil/xmlutil.cpp
+++ b/src/dutil/xmlutil.cpp
@@ -1305,7 +1305,7 @@ extern "C" HRESULT DAPI XmlSaveDocumentToBuffer(
1305 XmlExitOnFailure(hr, "Failed to get stream size."); 1305 XmlExitOnFailure(hr, "Failed to get stream size.");
1306 1306
1307 // allocate buffer 1307 // allocate buffer
1308 pbDest = static_cast<BYTE*>(MemAlloc((SIZE_T)statstg.cbSize.LowPart, TRUE)); 1308 pbDest = static_cast<BYTE*>(MemAlloc(statstg.cbSize.LowPart, TRUE));
1309 XmlExitOnNull(pbDest, hr, E_OUTOFMEMORY, "Failed to allocate destination buffer."); 1309 XmlExitOnNull(pbDest, hr, E_OUTOFMEMORY, "Failed to allocate destination buffer.");
1310 1310
1311 // read data from stream 1311 // read data from stream
diff --git a/src/test/DUtilUnitTest/FileUtilTest.cpp b/src/test/DUtilUnitTest/FileUtilTest.cpp
index 0087a1d5..ac071ef2 100644
--- a/src/test/DUtilUnitTest/FileUtilTest.cpp
+++ b/src/test/DUtilUnitTest/FileUtilTest.cpp
@@ -50,7 +50,7 @@ namespace DutilTests
50 } 50 }
51 51
52 private: 52 private:
53 void TestFile(LPWSTR wzDir, LPCWSTR wzTempDir, LPWSTR wzFileName, DWORD dwExpectedStringLength, FILE_ENCODING feExpectedEncoding) 53 void TestFile(LPWSTR wzDir, LPCWSTR wzTempDir, LPWSTR wzFileName, size_t cbExpectedStringLength, FILE_ENCODING feExpectedEncoding)
54 { 54 {
55 HRESULT hr = S_OK; 55 HRESULT hr = S_OK;
56 LPWSTR sczFullPath = NULL; 56 LPWSTR sczFullPath = NULL;
@@ -61,6 +61,7 @@ namespace DutilTests
61 DWORD cbFile1 = 0; 61 DWORD cbFile1 = 0;
62 BYTE *pbFile2 = NULL; 62 BYTE *pbFile2 = NULL;
63 DWORD cbFile2 = 0; 63 DWORD cbFile2 = 0;
64 size_t cbActualStringLength = 0;
64 65
65 try 66 try
66 { 67 {
@@ -77,10 +78,13 @@ namespace DutilTests
77 NativeAssert::Succeeded(hr, "FileToString() returned NULL for file: {0}", sczFullPath); 78 NativeAssert::Succeeded(hr, "FileToString() returned NULL for file: {0}", sczFullPath);
78 } 79 }
79 80
80 if ((DWORD)lstrlenW(sczContents) != dwExpectedStringLength) 81 hr = ::StringCchLengthW(sczContents, STRSAFE_MAX_CCH, &cbActualStringLength);
82 NativeAssert::Succeeded(hr, "Failed to get length of text from file: {0}", sczFullPath);
83
84 if (cbActualStringLength != cbExpectedStringLength)
81 { 85 {
82 hr = E_FAIL; 86 hr = E_FAIL;
83 ExitOnFailure(hr, "FileToString() returned wrong size for file: %ls (expected size %u, found size %u)", sczFullPath, dwExpectedStringLength, lstrlenW(sczContents)); 87 ExitOnFailure(hr, "FileToString() returned wrong size for file: %ls (expected size %Iu, found size %Iu)", sczFullPath, cbExpectedStringLength, cbActualStringLength);
84 } 88 }
85 89
86 if (feEncodingFound != feExpectedEncoding) 90 if (feEncodingFound != feExpectedEncoding)