diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-04-28 16:36:56 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-04-29 13:58:14 -0500 |
| commit | bcd3ee7ab858d62beb36af9f5986544b68a3dd35 (patch) | |
| tree | 424c4e61a580b7c4b7481712f69ab0193d76b9c4 /src/dutil/fileutil.cpp | |
| parent | d73c29407fe5ec6a0207af7d9c2547457ae0854c (diff) | |
| download | wix-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.cpp | 149 |
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 | ||
| 189 | LExit: | 182 | LExit: |
| 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 | *******************************************************************/ |
| 411 | extern "C" HRESULT DAPI FileVersionFromStringEx( | 408 | extern "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 | ||
| 998 | extern "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 | |||
| 1029 | LExit: | ||
| 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 | ||
| 1060 | LExit: | 1096 | LExit: |
| 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)); |
