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);