Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54733
Signed-off-by: David Kahurani k.kahurani@gmail.com
-- v9: shlwapi: Implement StrFormatByteSizeEx
From: David Kahurani k.kahurani@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54733 Signed-off-by: David Kahurani k.kahurani@gmail.com --- dlls/shlwapi/shlwapi.spec | 1 + dlls/shlwapi/string.c | 49 +++++++++++++++++++++++++++++++------ dlls/shlwapi/tests/string.c | 35 ++++++++++++++++++++++++++ include/shlwapi.h | 7 ++++++ 4 files changed, 85 insertions(+), 7 deletions(-)
diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec index 801b2c9a890..0d4729b432f 100644 --- a/dlls/shlwapi/shlwapi.spec +++ b/dlls/shlwapi/shlwapi.spec @@ -783,6 +783,7 @@ @ stdcall StrFormatByteSizeA(long ptr long) @ stdcall StrFormatByteSizeW(int64 ptr long) @ stdcall StrFormatKBSizeA(int64 str long) +@ stdcall StrFormatByteSizeEx(int64 long ptr long) @ stdcall StrFormatKBSizeW(int64 wstr long) @ stdcall StrFromTimeIntervalA(ptr long long long) @ stdcall StrFromTimeIntervalW(ptr long long long) diff --git a/dlls/shlwapi/string.c b/dlls/shlwapi/string.c index 77e3b978cee..2c894198239 100644 --- a/dlls/shlwapi/string.c +++ b/dlls/shlwapi/string.c @@ -840,6 +840,30 @@ typedef struct tagSHLWAPI_BYTEFORMATS * There is no StrFormatByteSize64W function, it is called StrFormatByteSizeW(). */ LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax) +{ + HRESULT hr; + + TRACE("(0x%s,%p,%d)\n", wine_dbgstr_longlong(llBytes), lpszDest, cchMax); + + if (!lpszDest || !cchMax) + return lpszDest; + + hr = StrFormatByteSizeEx(llBytes, SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS, + lpszDest, cchMax); + + if (FAILED(hr)) + return NULL; + + return lpszDest; +} + +/************************************************************************* + * StrFormatByteSizeEx [SHLWAPI.@] + * + */ + +HRESULT WINAPI StrFormatByteSizeEx(LONGLONG llBytes, SFBS_FLAGS flags, LPWSTR lpszDest, + UINT cchMax) { #define KB ((ULONGLONG)1024) #define MB (KB*KB) @@ -870,17 +894,17 @@ LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax) double dBytes; UINT i = 0;
- TRACE("(0x%s,%p,%d)\n", wine_dbgstr_longlong(llBytes), lpszDest, cchMax); + TRACE("(0x%s,%d,%p,%d)\n", wine_dbgstr_longlong(llBytes), flags, lpszDest, cchMax);
- if (!lpszDest || !cchMax) - return lpszDest; + if (!cchMax) + return E_INVALIDARG;
if (llBytes < 1024) /* 1K */ { WCHAR wszBytesFormat[64]; LoadStringW(shlwapi_hInstance, IDS_BYTES_FORMAT, wszBytesFormat, 64); swprintf(lpszDest, cchMax, wszBytesFormat, (int)llBytes); - return lpszDest; + return S_OK; }
/* Note that if this loop completes without finding a match, i will be @@ -903,13 +927,24 @@ LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax) else dBytes = (double)llBytes + 0.00001;
- dBytes = floor(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser; + switch(flags) + { + case SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT: + dBytes = round(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser; + break; + case SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS: + dBytes = floor(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser; + break; + default: + return E_INVALIDARG; + }
if (!FormatDouble(dBytes, bfFormats[i].nDecimals, lpszDest, cchMax)) - return NULL; + return E_FAIL; + wszAdd[1] = bfFormats[i].wPrefix; StrCatBuffW(lpszDest, wszAdd, cchMax); - return lpszDest; + return S_OK; }
/************************************************************************* diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index d988e26acb4..6939063a306 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -52,6 +52,7 @@ static DWORD (WINAPI *pStrCatChainW)(LPWSTR,DWORD,DWORD,LPCWSTR); static LPSTR (WINAPI *pStrCpyNXA)(LPSTR,LPCSTR,int); static LPWSTR (WINAPI *pStrCpyNXW)(LPWSTR,LPCWSTR,int); static LPSTR (WINAPI *pStrFormatByteSize64A)(LONGLONG,LPSTR,UINT); +static HRESULT (WINAPI *pStrFormatByteSizeEx)(LONGLONG,SFBS_FLAGS,LPWSTR,UINT); static LPSTR (WINAPI *pStrFormatKBSizeA)(LONGLONG,LPSTR,UINT); static LPWSTR (WINAPI *pStrFormatKBSizeW)(LONGLONG,LPWSTR,UINT); static BOOL (WINAPI *pStrIsIntlEqualA)(BOOL,LPCSTR,LPCSTR,int); @@ -715,6 +716,38 @@ static void test_StrFormatByteSize64A(void) } }
+static void test_StrFormatByteSizeEx(void) +{ + WCHAR szBuff[256]; + HRESULT hr; + LONGLONG test_value = 2147483647; + + if (!pStrFormatByteSizeEx) + { + win_skip("StrFormatByteSizeEx is not available \n"); + return; + } + + hr = pStrFormatByteSizeEx(0xdeadbeef, + SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS, szBuff, 0); + ok(hr == E_INVALIDARG, "Unexpected hr: %#lx expected: %#lx\n", hr, E_INVALIDARG); + + hr = pStrFormatByteSizeEx(0xdeadbeef, 10, szBuff, 256); + ok(hr == E_INVALIDARG, "Unexpected hr: %#lx expected: %#lx\n", hr, E_INVALIDARG); + + hr = pStrFormatByteSizeEx(test_value, SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT, + szBuff, 256); + ok(hr == S_OK, "Invalid arguments \n"); + ok(!wcscmp(szBuff, L"2.00 GB"), "Formatted %s wrong: got %ls, expected 2.00 GB\n", + wine_dbgstr_longlong(test_value), szBuff); + + hr = pStrFormatByteSizeEx(test_value, SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS, + szBuff, 256); + ok(hr == S_OK, "Invalid arguments \n"); + ok(!wcscmp(szBuff, L"1.99 GB"), "Formatted %s wrong: got %ls, expected 1.99 GB\n", + wine_dbgstr_longlong(test_value), szBuff); +} + static void test_StrFormatKBSizeW(void) { WCHAR szBuffW[256]; @@ -1680,6 +1713,7 @@ START_TEST(string) pStrCpyNXW = (void *)GetProcAddress(hShlwapi, (LPSTR)400); pStrChrNW = (void *)GetProcAddress(hShlwapi, "StrChrNW"); pStrFormatByteSize64A = (void *)GetProcAddress(hShlwapi, "StrFormatByteSize64A"); + pStrFormatByteSizeEx = (void *)GetProcAddress(hShlwapi, "StrFormatByteSizeEx"); pStrFormatKBSizeA = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeA"); pStrFormatKBSizeW = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeW"); pStrIsIntlEqualA = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualA"); @@ -1716,6 +1750,7 @@ START_TEST(string) if (is_lang_english() && is_locale_english()) { test_StrFormatByteSize64A(); + test_StrFormatByteSizeEx(); test_StrFormatKBSizeA(); test_StrFormatKBSizeW(); } diff --git a/include/shlwapi.h b/include/shlwapi.h index eee41abf0dc..e81e9f0e1ec 100644 --- a/include/shlwapi.h +++ b/include/shlwapi.h @@ -856,6 +856,13 @@ WINSHLWAPI HRESULT WINAPI SHStrDupW(LPCWSTR,WCHAR**);
WINSHLWAPI LPSTR WINAPI StrFormatByteSizeA (DWORD,LPSTR,UINT);
+typedef enum { + SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT = 0x1, + SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS = 0x2, +} SFBS_FLAGS; + +WINSHLWAPI HRESULT WINAPI StrFormatByteSizeEx(LONGLONG,SFBS_FLAGS,LPWSTR,UINT); + /* A/W Pairing is broken for this function */ WINSHLWAPI LPSTR WINAPI StrFormatByteSize64A (LONGLONG,LPSTR,UINT); WINSHLWAPI LPWSTR WINAPI StrFormatByteSizeW (LONGLONG,LPWSTR,UINT);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=132266
Your paranoid android.
=== debian11 (32 bit report) ===
wldap32: parse: Timeout
This merge request was approved by Nikolay Sivov.