aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/fileutil.cpp
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 /src/dutil/fileutil.cpp
parentd73c29407fe5ec6a0207af7d9c2547457ae0854c (diff)
downloadwix-bcd3ee7ab858d62beb36af9f5986544b68a3dd35.tar.gz
wix-bcd3ee7ab858d62beb36af9f5986544b68a3dd35.tar.bz2
wix-bcd3ee7ab858d62beb36af9f5986544b68a3dd35.zip
Clean up more 32-bit assumptions.
Diffstat (limited to 'src/dutil/fileutil.cpp')
-rw-r--r--src/dutil/fileutil.cpp149
1 files changed, 99 insertions, 50 deletions
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));