1 /* 2 * Copyright 2017 Doug Lyons 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 /* Documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/bb759975(v=vs.85).aspx */ 20 21 #include <apitest.h> 22 #include <shlwapi.h> 23 #include <strsafe.h> 24 25 #define DO_TEST(exp, str) \ 26 do { \ 27 StrFormatByteSizeW(exp, lpszDest, cchMax);\ 28 if (lpszDest[1] == L',') lpszDest[1] = L'.';\ 29 ok(_wcsicmp(lpszDest, (str)) == 0, "Expected %s got %s\n",\ 30 wine_dbgstr_w((str)), wine_dbgstr_w((lpszDest)));\ 31 } while (0) 32 33 WCHAR lpszDest[260]; 34 UINT cchMax=260; 35 36 /* Returns true if the user interface is in English. Note that this does not 37 * presume of the formatting of dates, numbers, etc. 38 * Taken from WINE. 39 */ 40 static BOOL is_lang_english(void) 41 { 42 static HMODULE hkernel32 = NULL; 43 static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL; 44 static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL; 45 46 if (!hkernel32) 47 { 48 hkernel32 = GetModuleHandleA("kernel32.dll"); 49 pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage"); 50 pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage"); 51 } 52 53 if (pGetThreadUILanguage) 54 return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH; 55 if (pGetUserDefaultUILanguage) 56 return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH; 57 58 return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH; 59 } 60 61 /* Returns true if the dates, numbers, etc. are formatted using English 62 * conventions. 63 * Taken from WINE. 64 */ 65 static BOOL is_locale_english(void) 66 { 67 /* Surprisingly GetThreadLocale() is irrelevant here */ 68 LANGID langid = PRIMARYLANGID(GetUserDefaultLangID()); 69 /* With the checks in DO_TEST, DUTCH can be used here as well. 70 TODO: Add other combinations that should work. */ 71 return langid == LANG_ENGLISH || langid == LANG_DUTCH; 72 } 73 74 START_TEST(StrFormatByteSizeW) 75 { 76 /* language-dependent test */ 77 if (!is_lang_english() || !is_locale_english()) 78 { 79 skip("An English UI and locale is required for the StrFormat*Size tests\n"); 80 return; 81 } 82 DO_TEST(0, L"0 bytes"); // 0x0 83 DO_TEST(1, L"1 bytes"); // 0x1 84 DO_TEST(1024, L"1.00 KB"); // 0x400 85 DO_TEST(1048576, L"1.00 MB"); // 0x100000 86 DO_TEST(1073741824, L"1.00 GB"); // 0x40000000 87 DO_TEST(0x70000000, L"1.75 GB"); // 0x70000000 88 DO_TEST(0x80000000, L"2.00 GB"); // 0x80000000 89 DO_TEST(0x100000000, L"4.00 GB"); // 0x100000000 90 DO_TEST(1099511627776, L"1.00 TB"); // 0x10000000000 91 DO_TEST(1125899906842624, L"1.00 PB"); // 0x4000000000000 92 DO_TEST(1152921504606846976, L"1.00 EB"); // 0x1000000000000000 93 DO_TEST(2305843009213693952, L"2.00 EB"); // 0x2000000000000000 94 DO_TEST(4611686018427387904, L"4.00 EB"); // 0x4000000000000000 95 DO_TEST(0x7fffffffffffffff, L"7.99 EB"); // 0x7fffffffffffffff 96 DO_TEST(0x8000000000000000, L"0 bytes"); // 0x8000000000000000 High Bit Set Here 97 DO_TEST(0xffffffff00000000, L"0 bytes"); // 0xffffffff00000000 98 DO_TEST(0xffffffff00000001, L"1 bytes"); // 0xffffffff00000001 99 DO_TEST(0xffffffff70000000, L"1879048192 bytes"); // 0xffffffff70000000 100 DO_TEST(0xffffffff7fffffff, L"2147483647 bytes"); // 0xffffffff7fffffff 101 DO_TEST(0xffffffff80000000, L"-2147483648 bytes"); // 0xffffffff80000000 // Maximum Negative Number -2.00 GB 102 DO_TEST(0xffffffff80000001, L"-2147483647 bytes"); // 0xffffffff80000001 103 DO_TEST(0xffffffff90000000, L"-1879048192 bytes"); // 0xffffffff90000000 104 DO_TEST(-1073741824, L"-1073741824 bytes"); // 0xffffffffc0000000 -1.00 GB 105 DO_TEST(-1048576, L"-1048576 bytes"); // 0xfffffffffff00000 -1.00 MB 106 DO_TEST(-1024, L"-1024 bytes"); // 0xfffffffffffffc00 -1.00 KB 107 DO_TEST(0xffffffffffffffff, L"-1 bytes"); // 0xffffffffffffffff 108 109 // Here are some large negative tests and they all return zero bytes 110 111 DO_TEST(-4294967296, L"0 bytes"); // 0xffffffff00000000 112 DO_TEST(-8589934592, L"0 bytes"); // 0xfffffffe00000000 113 DO_TEST(-17179869184, L"0 bytes"); // 0xfffffffc00000000 114 DO_TEST(-34359738368, L"0 bytes"); // 0xfffffff800000000 115 DO_TEST(-68719476736, L"0 bytes"); // 0xfffffff000000000 116 DO_TEST(-137438953472, L"0 bytes"); // 0xffffffe000000000 117 DO_TEST(-274877906944, L"0 bytes"); // 0xffffffc000000000 118 DO_TEST(-549755813888, L"0 bytes"); // 0xffffff8000000000 119 DO_TEST(-1099511627776, L"0 bytes"); // 0xffffff0000000000 120 DO_TEST(-1152921504606846976, L"0 bytes"); // 0xf000000000000000 121 122 // These statements create compile errors and seem to be compiler conversion related 123 //DO_TEST(2147483648, L"2.00 GB"); // 2.00 GB & This gives a compile error 124 //DO_TEST(-2147483648, L"0 bytes"); // -2.00 GB & This gives a compile error 125 } 126