Autosyncing with Wine HEAD

svn path=/trunk/; revision=28513
This commit is contained in:
The Wine Synchronizer 2007-08-24 09:42:29 +00:00
parent 95797b4cf7
commit c18bbbf9a7
13 changed files with 2458 additions and 257 deletions

View file

@ -23,6 +23,9 @@
<directory name="lz32">
<xi:include href="lz32/lz32.rbuild" />
</directory>
<directory name="mlang">
<xi:include href="mlang/mlang.rbuild" />
</directory>
<directory name="msi">
<xi:include href="msi/msi.rbuild" />
</directory>

View file

@ -0,0 +1,788 @@
/*
* Unit test suite for MLANG APIs.
*
* Copyright 2004 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "mlang.h"
#include "wine/test.h"
#ifndef CP_UNICODE
#define CP_UNICODE 1200
#endif
#if 0
#define DUMP_CP_INFO
#define DUMP_SCRIPT_INFO
#if defined DUMP_CP_INFO || defined DUMP_SCRIPT_INFO
#include "wine/debug.h"
#endif
#endif /* 0 */
#define TRACE_2 OutputDebugStringA
static BOOL (WINAPI *pGetCPInfoExA)(UINT,DWORD,LPCPINFOEXA);
static void test_multibyte_to_unicode_translations(IMultiLanguage2 *iML2)
{
/* these APIs are broken regarding constness of the input buffer */
char stringA[] = "Just a test string\0"; /* double 0 for CP_UNICODE tests */
WCHAR stringW[] = {'J','u','s','t',' ','a',' ','t','e','s','t',' ','s','t','r','i','n','g',0};
char bufA[256];
WCHAR bufW[256];
UINT lenA, lenW, expected_len;
HRESULT ret;
HMODULE hMlang;
FARPROC pConvertINetMultiByteToUnicode;
FARPROC pConvertINetUnicodeToMultiByte;
hMlang = LoadLibraryA("mlang.dll");
ok(hMlang != 0, "couldn't load mlang.dll\n");
pConvertINetMultiByteToUnicode = GetProcAddress(hMlang, "ConvertINetMultiByteToUnicode");
ok(pConvertINetMultiByteToUnicode != NULL, "couldn't resolve ConvertINetMultiByteToUnicode\n");
pConvertINetUnicodeToMultiByte = GetProcAddress(hMlang, "ConvertINetUnicodeToMultiByte");
ok(pConvertINetUnicodeToMultiByte != NULL, "couldn't resolve ConvertINetUnicodeToMultiByte\n");
/* IMultiLanguage2_ConvertStringToUnicode tests */
memset(bufW, 'x', sizeof(bufW));
lenA = 0;
lenW = sizeof(bufW)/sizeof(bufW[0]);
TRACE_2("Call IMultiLanguage2_ConvertStringToUnicode\n");
ret = IMultiLanguage2_ConvertStringToUnicode(iML2, NULL, 1252, stringA, &lenA, bufW, &lenW);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringToUnicode failed: %08x\n", ret);
ok(lenA == 0, "expected lenA 0, got %u\n", lenA);
ok(lenW == 0, "expected lenW 0, got %u\n", lenW);
memset(bufW, 'x', sizeof(bufW));
lenA = -1;
lenW = sizeof(bufW)/sizeof(bufW[0]);
TRACE_2("Call IMultiLanguage2_ConvertStringToUnicode\n");
ret = IMultiLanguage2_ConvertStringToUnicode(iML2, NULL, 1252, stringA, &lenA, bufW, &lenW);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringToUnicode failed: %08x\n", ret);
ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
if (lenW < sizeof(bufW)/sizeof(bufW[0])) {
/* can only happen if the convert call fails */
ok(bufW[lenW] != 0, "buf should not be 0 terminated\n");
bufW[lenW] = 0; /* -1 doesn't include 0 terminator */
}
ok(!lstrcmpW(bufW, stringW), "bufW/stringW mismatch\n");
memset(bufW, 'x', sizeof(bufW));
lenA = -1;
lenW = 5;
TRACE_2("Call IMultiLanguage2_ConvertStringToUnicode\n");
ret = IMultiLanguage2_ConvertStringToUnicode(iML2, NULL, 1252, stringA, &lenA, bufW, &lenW);
ok(ret == E_FAIL, "IMultiLanguage2_ConvertStringToUnicode should fail: %08x\n", ret);
ok(lenW == 0, "expected lenW 0, got %u\n", lenW);
/* still has to do partial conversion */
ok(!memcmp(bufW, stringW, 5 * sizeof(WCHAR)), "bufW/stringW mismatch\n");
memset(bufW, 'x', sizeof(bufW));
lenA = -1;
lenW = sizeof(bufW)/sizeof(bufW[0]);
TRACE_2("Call IMultiLanguage2_ConvertStringToUnicode\n");
ret = IMultiLanguage2_ConvertStringToUnicode(iML2, NULL, CP_UNICODE, stringA, &lenA, bufW, &lenW);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringToUnicode failed: %08x\n", ret);
ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
ok(lenW == lstrlenW(stringW)/(int)sizeof(WCHAR), "wrong lenW %u\n", lenW);
ok(bufW[lenW] != 0, "buf should not be 0 terminated\n");
bufW[lenW] = 0; /* -1 doesn't include 0 terminator */
ok(!lstrcmpA((LPCSTR)bufW, stringA), "bufW/stringA mismatch\n");
memset(bufW, 'x', sizeof(bufW));
lenA = lstrlenA(stringA);
lenW = 0;
ret = IMultiLanguage2_ConvertStringToUnicode(iML2, NULL, 1252, stringA, &lenA, NULL, &lenW);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringToUnicode failed: %08x\n", ret);
ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
expected_len = MultiByteToWideChar(1252, 0, stringA, lenA, NULL, 0);
ok(lenW == expected_len, "expected lenW %u, got %u\n", expected_len, lenW);
memset(bufW, 'x', sizeof(bufW));
lenA = lstrlenA(stringA);
lenW = sizeof(bufW)/sizeof(bufW[0]);
ret = pConvertINetMultiByteToUnicode(NULL, 1252, stringA, &lenA, NULL, &lenW);
ok(ret == S_OK, "ConvertINetMultiByteToUnicode failed: %08x\n", ret);
ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
expected_len = MultiByteToWideChar(1252, 0, stringA, lenA, NULL, 0);
ok(lenW == expected_len, "expected lenW %u, got %u\n", expected_len, lenW);
memset(bufW, 'x', sizeof(bufW));
lenA = lstrlenA(stringA);
lenW = 0;
ret = pConvertINetMultiByteToUnicode(NULL, 1252, stringA, &lenA, NULL, &lenW);
ok(ret == S_OK, "ConvertINetMultiByteToUnicode failed: %08x\n", ret);
ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
expected_len = MultiByteToWideChar(1252, 0, stringA, lenA, NULL, 0);
ok(lenW == expected_len, "expected lenW %u, got %u\n", expected_len, lenW);
/* IMultiLanguage2_ConvertStringFromUnicode tests */
memset(bufA, 'x', sizeof(bufA));
lenW = 0;
lenA = sizeof(bufA);
TRACE_2("Call IMultiLanguage2_ConvertStringFromUnicode\n");
ret = IMultiLanguage2_ConvertStringFromUnicode(iML2, NULL, 1252, stringW, &lenW, bufA, &lenA);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringFromUnicode failed: %08x\n", ret);
ok(lenA == 0, "expected lenA 0, got %u\n", lenA);
ok(lenW == 0, "expected lenW 0, got %u\n", lenW);
memset(bufA, 'x', sizeof(bufA));
lenW = -1;
lenA = sizeof(bufA);
TRACE_2("Call IMultiLanguage2_ConvertStringFromUnicode\n");
ret = IMultiLanguage2_ConvertStringFromUnicode(iML2, NULL, 1252, stringW, &lenW, bufA, &lenA);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringFromUnicode failed: %08x\n", ret);
ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
ok(bufA[lenA] != 0, "buf should not be 0 terminated\n");
bufA[lenA] = 0; /* -1 doesn't include 0 terminator */
ok(!lstrcmpA(bufA, stringA), "bufA/stringA mismatch\n");
memset(bufA, 'x', sizeof(bufA));
lenW = -1;
lenA = 5;
TRACE_2("Call IMultiLanguage2_ConvertStringFromUnicode\n");
ret = IMultiLanguage2_ConvertStringFromUnicode(iML2, NULL, 1252, stringW, &lenW, bufA, &lenA);
ok(ret == E_FAIL, "IMultiLanguage2_ConvertStringFromUnicode should fail: %08x\n", ret);
ok(lenA == 0, "expected lenA 0, got %u\n", lenA);
/* still has to do partial conversion */
ok(!memcmp(bufA, stringA, 5), "bufW/stringW mismatch\n");
memset(bufA, 'x', sizeof(bufA));
lenW = -1;
lenA = sizeof(bufA);
TRACE_2("Call IMultiLanguage2_ConvertStringFromUnicode\n");
ret = IMultiLanguage2_ConvertStringFromUnicode(iML2, NULL, CP_UNICODE, stringW, &lenW, bufA, &lenA);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringFromUnicode failed: %08x\n", ret);
ok(lenA == lstrlenA(stringA) * (int)sizeof(WCHAR), "wrong lenA %u\n", lenA);
ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
ok(bufA[lenA] != 0 && bufA[lenA+1] != 0, "buf should not be 0 terminated\n");
bufA[lenA] = 0; /* -1 doesn't include 0 terminator */
bufA[lenA+1] = 0; /* sizeof(WCHAR) */
ok(!lstrcmpW((LPCWSTR)bufA, stringW), "bufA/stringW mismatch\n");
memset(bufA, 'x', sizeof(bufA));
lenW = lstrlenW(stringW);
lenA = 0;
ret = IMultiLanguage2_ConvertStringFromUnicode(iML2, NULL, 1252, stringW, &lenW, NULL, &lenA);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringFromUnicode failed: %08x\n", ret);
ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
expected_len = WideCharToMultiByte(1252, 0, stringW, lenW, NULL, 0, NULL, NULL);
ok(lenA == expected_len, "expected lenA %u, got %u\n", expected_len, lenA);
memset(bufA, 'x', sizeof(bufA));
lenW = lstrlenW(stringW);
lenA = sizeof(bufA);
ret = pConvertINetUnicodeToMultiByte(NULL, 1252, stringW, &lenW, NULL, &lenA);
ok(ret == S_OK, "ConvertINetUnicodeToMultiByte failed: %08x\n", ret);
ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
expected_len = WideCharToMultiByte(1252, 0, stringW, lenW, NULL, 0, NULL, NULL);
ok(lenA == expected_len, "expected lenA %u, got %u\n", expected_len, lenA);
memset(bufA, 'x', sizeof(bufA));
lenW = lstrlenW(stringW);
lenA = 0;
ret = pConvertINetUnicodeToMultiByte(NULL, 1252, stringW, &lenW, NULL, &lenA);
ok(ret == S_OK, "ConvertINetUnicodeToMultiByte failed: %08x\n", ret);
ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
expected_len = WideCharToMultiByte(1252, 0, stringW, lenW, NULL, 0, NULL, NULL);
ok(lenA == expected_len, "expected lenA %u, got %u\n", expected_len, lenA);
}
static inline void cpinfo_cmp(MIMECPINFO *cpinfo1, MIMECPINFO *cpinfo2)
{
ok(cpinfo1->dwFlags == cpinfo2->dwFlags, "dwFlags mismatch: %08x != %08x\n", cpinfo1->dwFlags, cpinfo2->dwFlags);
ok(cpinfo1->uiCodePage == cpinfo2->uiCodePage, "uiCodePage mismatch: %u != %u\n", cpinfo1->uiCodePage, cpinfo2->uiCodePage);
ok(cpinfo1->uiFamilyCodePage == cpinfo2->uiFamilyCodePage, "uiFamilyCodePage mismatch: %u != %u\n", cpinfo1->uiFamilyCodePage, cpinfo2->uiFamilyCodePage);
ok(!lstrcmpW(cpinfo1->wszDescription, cpinfo2->wszDescription), "wszDescription mismatch\n");
ok(!lstrcmpW(cpinfo1->wszWebCharset, cpinfo2->wszWebCharset), "wszWebCharset mismatch\n");
ok(!lstrcmpW(cpinfo1->wszHeaderCharset, cpinfo2->wszHeaderCharset), "wszHeaderCharset mismatch\n");
ok(!lstrcmpW(cpinfo1->wszBodyCharset, cpinfo2->wszBodyCharset), "wszBodyCharset mismatch\n");
ok(!lstrcmpW(cpinfo1->wszFixedWidthFont, cpinfo2->wszFixedWidthFont), "wszFixedWidthFont mismatch\n");
ok(!lstrcmpW(cpinfo1->wszProportionalFont, cpinfo2->wszProportionalFont), "wszProportionalFont mismatch\n");
ok(cpinfo1->bGDICharset == cpinfo2->bGDICharset, "bGDICharset mismatch: %d != %d\n", cpinfo1->bGDICharset, cpinfo2->bGDICharset);
}
#ifdef DUMP_CP_INFO
static const char *dump_mime_flags(DWORD flags)
{
static char buf[1024];
buf[0] = 0;
if (flags & MIMECONTF_MAILNEWS) strcat(buf, " MIMECONTF_MAILNEWS");
if (flags & MIMECONTF_BROWSER) strcat(buf, " MIMECONTF_BROWSER");
if (flags & MIMECONTF_MINIMAL) strcat(buf, " MIMECONTF_MINIMAL");
if (flags & MIMECONTF_IMPORT) strcat(buf, " MIMECONTF_IMPORT");
if (flags & MIMECONTF_SAVABLE_MAILNEWS) strcat(buf, " MIMECONTF_SAVABLE_MAILNEWS");
if (flags & MIMECONTF_SAVABLE_BROWSER) strcat(buf, " MIMECONTF_SAVABLE_BROWSER");
if (flags & MIMECONTF_EXPORT) strcat(buf, " MIMECONTF_EXPORT");
if (flags & MIMECONTF_PRIVCONVERTER) strcat(buf, " MIMECONTF_PRIVCONVERTER");
if (flags & MIMECONTF_VALID) strcat(buf, " MIMECONTF_VALID");
if (flags & MIMECONTF_VALID_NLS) strcat(buf, " MIMECONTF_VALID_NLS");
if (flags & MIMECONTF_MIME_IE4) strcat(buf, " MIMECONTF_MIME_IE4");
if (flags & MIMECONTF_MIME_LATEST) strcat(buf, " MIMECONTF_MIME_LATEST");
if (flags & MIMECONTF_MIME_REGISTRY) strcat(buf, " MIMECONTF_MIME_REGISTRY");
return buf;
}
#endif
static void test_EnumCodePages(IMultiLanguage2 *iML2, DWORD flags)
{
IEnumCodePage *iEnumCP = NULL;
MIMECPINFO *cpinfo;
MIMECPINFO cpinfo2;
HRESULT ret;
ULONG i, n;
UINT total;
total = 0;
TRACE_2("Call IMultiLanguage2_GetNumberOfCodePageInfo\n");
ret = IMultiLanguage2_GetNumberOfCodePageInfo(iML2, &total);
ok(ret == S_OK && total != 0, "IMultiLanguage2_GetNumberOfCodePageInfo: expected S_OK/!0, got %08x/%u\n", ret, total);
trace("total mlang supported codepages %u\n", total);
TRACE_2("Call IMultiLanguage2_EnumCodePages\n");
ret = IMultiLanguage2_EnumCodePages(iML2, flags, LANG_NEUTRAL, &iEnumCP);
trace("IMultiLanguage2_EnumCodePages = %08x, iEnumCP = %p\n", ret, iEnumCP);
ok(ret == S_OK && iEnumCP, "IMultiLanguage2_EnumCodePages: expected S_OK/!NULL, got %08x/%p\n", ret, iEnumCP);
TRACE_2("Call IEnumCodePage_Reset\n");
ret = IEnumCodePage_Reset(iEnumCP);
ok(ret == S_OK, "IEnumCodePage_Reset: expected S_OK, got %08x\n", ret);
n = 65536;
TRACE_2("Call IEnumCodePage_Next\n");
ret = IEnumCodePage_Next(iEnumCP, 0, NULL, &n);
ok(n == 0 && ret == S_FALSE, "IEnumCodePage_Next: expected 0/S_FALSE, got %u/%08x\n", n, ret);
TRACE_2("Call IEnumCodePage_Next\n");
ret = IEnumCodePage_Next(iEnumCP, 0, NULL, NULL);
ok(ret == S_FALSE, "IEnumCodePage_Next: expected S_FALSE, got %08x\n", ret);
cpinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*cpinfo) * total * 2);
n = total * 2;
TRACE_2("Call IEnumCodePage_Next\n");
ret = IEnumCodePage_Next(iEnumCP, 0, cpinfo, &n);
trace("IEnumCodePage_Next = %08x, n = %u\n", ret, n);
ok(ret == S_FALSE && n == 0, "IEnumCodePage_Next: expected S_FALSE/0, got %08x/%u\n", ret, n);
n = total * 2;
TRACE_2("Call IEnumCodePage_Next\n");
ret = IEnumCodePage_Next(iEnumCP, n, cpinfo, &n);
ok(ret == S_OK && n != 0, "IEnumCodePage_Next: expected S_OK/!0, got %08x/%u\n", ret, n);
trace("flags %08x, enumerated codepages %u\n", flags, n);
if (!flags)
{
ok(n == total, "IEnumCodePage_Next: expected %u, got %u\n", total, n);
flags = MIMECONTF_MIME_LATEST;
}
total = n;
for (i = 0; i < n; i++)
{
CPINFOEXA cpinfoex;
CHARSETINFO csi;
MIMECSETINFO mcsi;
static const WCHAR autoW[] = {'_','a','u','t','o',0};
#ifdef DUMP_CP_INFO
trace("MIMECPINFO #%u:\n"
"dwFlags %08x %s\n"
"uiCodePage %u\n"
"uiFamilyCodePage %u\n"
"wszDescription %s\n"
"wszWebCharset %s\n"
"wszHeaderCharset %s\n"
"wszBodyCharset %s\n"
"wszFixedWidthFont %s\n"
"wszProportionalFont %s\n"
"bGDICharset %d\n\n",
i,
cpinfo[i].dwFlags, dump_mime_flags(cpinfo[i].dwFlags),
cpinfo[i].uiCodePage,
cpinfo[i].uiFamilyCodePage,
wine_dbgstr_w(cpinfo[i].wszDescription),
wine_dbgstr_w(cpinfo[i].wszWebCharset),
wine_dbgstr_w(cpinfo[i].wszHeaderCharset),
wine_dbgstr_w(cpinfo[i].wszBodyCharset),
wine_dbgstr_w(cpinfo[i].wszFixedWidthFont),
wine_dbgstr_w(cpinfo[i].wszProportionalFont),
cpinfo[i].bGDICharset);
#endif
ok(cpinfo[i].dwFlags & flags, "enumerated flags %08x do not include requested %08x\n", cpinfo[i].dwFlags, flags);
if (TranslateCharsetInfo((DWORD *)cpinfo[i].uiFamilyCodePage, &csi, TCI_SRCCODEPAGE))
ok(cpinfo[i].bGDICharset == csi.ciCharset, "%d != %d\n", cpinfo[i].bGDICharset, csi.ciCharset);
else
trace("TranslateCharsetInfo failed for cp %u\n", cpinfo[i].uiFamilyCodePage);
if (pGetCPInfoExA)
{
if (pGetCPInfoExA(cpinfo[i].uiCodePage, 0, &cpinfoex))
trace("CodePage %u name: %s\n", cpinfo[i].uiCodePage, cpinfoex.CodePageName);
else
trace("GetCPInfoExA failed for cp %u\n", cpinfo[i].uiCodePage);
if (pGetCPInfoExA(cpinfo[i].uiFamilyCodePage, 0, &cpinfoex))
trace("CodePage %u name: %s\n", cpinfo[i].uiFamilyCodePage, cpinfoex.CodePageName);
else
trace("GetCPInfoExA failed for cp %u\n", cpinfo[i].uiFamilyCodePage);
}
/* Win95 does not support UTF-7 */
if (cpinfo[i].uiCodePage == CP_UTF7) continue;
/* support files for some codepages might be not installed, or
* the codepage is just an alias.
*/
if (IsValidCodePage(cpinfo[i].uiCodePage))
{
TRACE_2("Call IMultiLanguage2_IsConvertible\n");
ret = IMultiLanguage2_IsConvertible(iML2, cpinfo[i].uiCodePage, CP_UNICODE);
ok(ret == S_OK, "IMultiLanguage2_IsConvertible(%u -> CP_UNICODE) = %08x\n", cpinfo[i].uiCodePage, ret);
TRACE_2("Call IMultiLanguage2_IsConvertible\n");
ret = IMultiLanguage2_IsConvertible(iML2, CP_UNICODE, cpinfo[i].uiCodePage);
ok(ret == S_OK, "IMultiLanguage2_IsConvertible(CP_UNICODE -> %u) = %08x\n", cpinfo[i].uiCodePage, ret);
TRACE_2("Call IMultiLanguage2_IsConvertible\n");
ret = IMultiLanguage2_IsConvertible(iML2, cpinfo[i].uiCodePage, CP_UTF8);
ok(ret == S_OK, "IMultiLanguage2_IsConvertible(%u -> CP_UTF8) = %08x\n", cpinfo[i].uiCodePage, ret);
TRACE_2("Call IMultiLanguage2_IsConvertible\n");
ret = IMultiLanguage2_IsConvertible(iML2, CP_UTF8, cpinfo[i].uiCodePage);
ok(ret == S_OK, "IMultiLanguage2_IsConvertible(CP_UTF8 -> %u) = %08x\n", cpinfo[i].uiCodePage, ret);
}
else
trace("IsValidCodePage failed for cp %u\n", cpinfo[i].uiCodePage);
ret = IMultiLanguage2_GetCharsetInfo(iML2, cpinfo[i].wszWebCharset, &mcsi);
/* _autoxxx charsets are a fake and GetCharsetInfo fails for them */
if (memcmp(cpinfo[i].wszWebCharset, autoW, 5 * sizeof(WCHAR)))
{
ok (ret == S_OK, "IMultiLanguage2_GetCharsetInfo failed: %08x\n", ret);
#ifdef DUMP_CP_INFO
trace("%s: %u %u %s\n", wine_dbgstr_w(cpinfo[i].wszWebCharset), mcsi.uiCodePage, mcsi.uiInternetEncoding, wine_dbgstr_w(mcsi.wszCharset));
#endif
ok(!lstrcmpiW(cpinfo[i].wszWebCharset, mcsi.wszCharset),
#ifdef DUMP_CP_INFO
"%s != %s\n",
wine_dbgstr_w(cpinfo[i].wszWebCharset), wine_dbgstr_w(mcsi.wszCharset));
#else
"wszWebCharset mismatch");
#endif
if (0)
{
/* native mlang returns completely messed up encodings in some cases */
ok(mcsi.uiInternetEncoding == cpinfo[i].uiCodePage || mcsi.uiInternetEncoding == cpinfo[i].uiFamilyCodePage,
"%u != %u || %u\n", mcsi.uiInternetEncoding, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
ok(mcsi.uiCodePage == cpinfo[i].uiCodePage || mcsi.uiCodePage == cpinfo[i].uiFamilyCodePage,
"%u != %u || %u\n", mcsi.uiCodePage, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
}
}
ret = IMultiLanguage2_GetCharsetInfo(iML2, cpinfo[i].wszHeaderCharset, &mcsi);
/* _autoxxx charsets are a fake and GetCharsetInfo fails for them */
if (memcmp(cpinfo[i].wszHeaderCharset, autoW, 5 * sizeof(WCHAR)))
{
ok (ret == S_OK, "IMultiLanguage2_GetCharsetInfo failed: %08x\n", ret);
#ifdef DUMP_CP_INFO
trace("%s: %u %u %s\n", wine_dbgstr_w(cpinfo[i].wszHeaderCharset), mcsi.uiCodePage, mcsi.uiInternetEncoding, wine_dbgstr_w(mcsi.wszCharset));
#endif
ok(!lstrcmpiW(cpinfo[i].wszHeaderCharset, mcsi.wszCharset),
#ifdef DUMP_CP_INFO
"%s != %s\n",
wine_dbgstr_w(cpinfo[i].wszHeaderCharset), wine_dbgstr_w(mcsi.wszCharset));
#else
"wszHeaderCharset mismatch");
#endif
if (0)
{
/* native mlang returns completely messed up encodings in some cases */
ok(mcsi.uiInternetEncoding == cpinfo[i].uiCodePage || mcsi.uiInternetEncoding == cpinfo[i].uiFamilyCodePage,
"%u != %u || %u\n", mcsi.uiInternetEncoding, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
ok(mcsi.uiCodePage == cpinfo[i].uiCodePage || mcsi.uiCodePage == cpinfo[i].uiFamilyCodePage,
"%u != %u || %u\n", mcsi.uiCodePage, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
}
}
ret = IMultiLanguage2_GetCharsetInfo(iML2, cpinfo[i].wszBodyCharset, &mcsi);
/* _autoxxx charsets are a fake and GetCharsetInfo fails for them */
if (memcmp(cpinfo[i].wszBodyCharset, autoW, 5 * sizeof(WCHAR)))
{
ok (ret == S_OK, "IMultiLanguage2_GetCharsetInfo failed: %08x\n", ret);
#ifdef DUMP_CP_INFO
trace("%s: %u %u %s\n", wine_dbgstr_w(cpinfo[i].wszBodyCharset), mcsi.uiCodePage, mcsi.uiInternetEncoding, wine_dbgstr_w(mcsi.wszCharset));
#endif
ok(!lstrcmpiW(cpinfo[i].wszBodyCharset, mcsi.wszCharset),
#ifdef DUMP_CP_INFO
"%s != %s\n",
wine_dbgstr_w(cpinfo[i].wszBodyCharset), wine_dbgstr_w(mcsi.wszCharset));
#else
"wszBodyCharset mismatch");
#endif
if (0)
{
/* native mlang returns completely messed up encodings in some cases */
ok(mcsi.uiInternetEncoding == cpinfo[i].uiCodePage || mcsi.uiInternetEncoding == cpinfo[i].uiFamilyCodePage,
"%u != %u || %u\n", mcsi.uiInternetEncoding, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
ok(mcsi.uiCodePage == cpinfo[i].uiCodePage || mcsi.uiCodePage == cpinfo[i].uiFamilyCodePage,
"%u != %u || %u\n", mcsi.uiCodePage, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
}
}
trace("---\n");
}
/* now IEnumCodePage_Next should fail, since pointer is at the end */
n = 1;
ret = IEnumCodePage_Next(iEnumCP, 1, &cpinfo2, &n);
ok(ret == S_FALSE && n == 0, "IEnumCodePage_Next: expected S_FALSE/0, got %08x/%u\n", ret, n);
ret = IEnumCodePage_Reset(iEnumCP);
ok(ret == S_OK, "IEnumCodePage_Reset: expected S_OK, got %08x\n", ret);
n = 0;
ret = IEnumCodePage_Next(iEnumCP, 1, &cpinfo2, &n);
ok(n == 1 && ret == S_OK, "IEnumCodePage_Next: expected 1/S_OK, got %u/%08x\n", n, ret);
cpinfo_cmp(&cpinfo[0], &cpinfo2);
if (0)
{
/* Due to a bug in MS' implementation of IEnumCodePage_Skip
* it's not used here.
*/
ret = IEnumCodePage_Skip(iEnumCP, 1);
ok(ret == S_OK, "IEnumCodePage_Skip: expected S_OK, got %08x\n", ret);
}
for (i = 0; i < total - 1; i++)
{
n = 0;
ret = IEnumCodePage_Next(iEnumCP, 1, &cpinfo2, &n);
ok(n == 1 && ret == S_OK, "IEnumCodePage_Next: expected 1/S_OK, got %u/%08x\n", n, ret);
cpinfo_cmp(&cpinfo[i + 1], &cpinfo2);
}
HeapFree(GetProcessHeap(), 0, cpinfo);
IEnumCodePage_Release(iEnumCP);
}
static inline void scriptinfo_cmp(SCRIPTINFO *sinfo1, SCRIPTINFO *sinfo2)
{
ok(sinfo1->ScriptId == sinfo2->ScriptId, "ScriptId mismatch: %d != %d\n", sinfo1->ScriptId, sinfo2->ScriptId);
ok(sinfo1->uiCodePage == sinfo2->uiCodePage, "uiCodePage mismatch: %u != %u\n", sinfo1->uiCodePage, sinfo2->uiCodePage);
ok(!lstrcmpW(sinfo1->wszDescription, sinfo2->wszDescription), "wszDescription mismatch\n");
ok(!lstrcmpW(sinfo1->wszFixedWidthFont, sinfo2->wszFixedWidthFont), "wszFixedWidthFont mismatch\n");
ok(!lstrcmpW(sinfo1->wszProportionalFont, sinfo2->wszProportionalFont), "wszProportionalFont mismatch\n");
}
static void test_EnumScripts(IMultiLanguage2 *iML2, DWORD flags)
{
IEnumScript *iEnumScript = NULL;
SCRIPTINFO *sinfo;
SCRIPTINFO sinfo2;
HRESULT ret;
ULONG i, n;
UINT total;
total = 0;
TRACE_2("Call IMultiLanguage2_GetNumberOfScripts\n");
ret = IMultiLanguage2_GetNumberOfScripts(iML2, &total);
ok(ret == S_OK && total != 0, "IMultiLanguage2_GetNumberOfScripts: expected S_OK/!0, got %08x/%u\n", ret, total);
trace("total mlang supported scripts %u\n", total);
TRACE_2("Call IMultiLanguage2_EnumScripts\n");
ret = IMultiLanguage2_EnumScripts(iML2, flags, LANG_NEUTRAL, &iEnumScript);
trace("IMultiLanguage2_EnumScripts = %08x, iEnumScript = %p\n", ret, iEnumScript);
ok(ret == S_OK && iEnumScript, "IMultiLanguage2_EnumScripts: expected S_OK/!NULL, got %08x/%p\n", ret, iEnumScript);
TRACE_2("Call IEnumScript_Reset\n");
ret = IEnumScript_Reset(iEnumScript);
ok(ret == S_OK, "IEnumScript_Reset: expected S_OK, got %08x\n", ret);
n = 65536;
TRACE_2("Call IEnumScript_Next\n");
ret = IEnumScript_Next(iEnumScript, 0, NULL, &n);
ok(n == 65536 && ret == E_FAIL, "IEnumScript_Next: expected 65536/E_FAIL, got %u/%08x\n", n, ret);
TRACE_2("Call IEnumScript_Next\n");
ret = IEnumScript_Next(iEnumScript, 0, NULL, NULL);
ok(ret == E_FAIL, "IEnumScript_Next: expected E_FAIL, got %08x\n", ret);
sinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*sinfo) * total * 2);
n = total * 2;
TRACE_2("Call IEnumScript_Next\n");
ret = IEnumScript_Next(iEnumScript, 0, sinfo, &n);
ok(ret == S_FALSE && n == 0, "IEnumScript_Next: expected S_FALSE/0, got %08x/%u\n", ret, n);
n = total * 2;
TRACE_2("Call IEnumScript_Next\n");
ret = IEnumScript_Next(iEnumScript, n, sinfo, &n);
ok(ret == S_OK && n != 0, "IEnumScript_Next: expected S_OK, got %08x/%u\n", ret, n);
trace("flags %08x, enumerated scripts %u\n", flags, n);
if (!flags)
{
ok(n == total, "IEnumScript_Next: expected %u, got %u\n", total, n);
flags = SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM;
}
total = n;
for (i = 0; pGetCPInfoExA && i < n; i++)
{
CPINFOEXA cpinfoex;
#ifdef DUMP_SCRIPT_INFO
trace("SCRIPTINFO #%u:\n"
"ScriptId %08x\n"
"uiCodePage %u\n"
"wszDescription %s\n"
"wszFixedWidthFont %s\n"
"wszProportionalFont %s\n\n",
i,
sinfo[i].ScriptId,
sinfo[i].uiCodePage,
wine_dbgstr_w(sinfo[i].wszDescription),
wine_dbgstr_w(sinfo[i].wszFixedWidthFont),
wine_dbgstr_w(sinfo[i].wszProportionalFont));
#endif
if (pGetCPInfoExA(sinfo[i].uiCodePage, 0, &cpinfoex))
trace("CodePage %u name: %s\n", sinfo[i].uiCodePage, cpinfoex.CodePageName);
else
trace("GetCPInfoExA failed for cp %u\n", sinfo[i].uiCodePage);
trace("---\n");
}
/* now IEnumScript_Next should fail, since pointer is at the end */
n = 1;
ret = IEnumScript_Next(iEnumScript, 1, &sinfo2, &n);
ok(ret == S_FALSE && n == 0, "IEnumScript_Next: expected S_FALSE/0, got %08x/%u\n", ret, n);
ret = IEnumScript_Reset(iEnumScript);
ok(ret == S_OK, "IEnumScript_Reset: expected S_OK, got %08x\n", ret);
n = 0;
ret = IEnumScript_Next(iEnumScript, 1, &sinfo2, &n);
ok(n == 1 && ret == S_OK, "IEnumScript_Next: expected 1/S_OK, got %u/%08x\n", n, ret);
scriptinfo_cmp(&sinfo[0], &sinfo2);
if (0)
{
/* Due to a bug in MS' implementation of IEnumScript_Skip
* it's not used here.
*/
ret = IEnumScript_Skip(iEnumScript, 1);
ok(ret == S_OK, "IEnumScript_Skip: expected S_OK, got %08x\n", ret);
}
for (i = 0; i < total - 1; i++)
{
n = 0;
ret = IEnumScript_Next(iEnumScript, 1, &sinfo2, &n);
ok(n == 1 && ret == S_OK, "IEnumScript_Next: expected 1/S_OK, got %u/%08x\n", n, ret);
scriptinfo_cmp(&sinfo[i + 1], &sinfo2);
}
HeapFree(GetProcessHeap(), 0, sinfo);
IEnumScript_Release(iEnumScript);
}
static void IMLangFontLink_Test(IMLangFontLink* iMLFL)
{
DWORD dwCodePages = 0;
DWORD dwManyCodePages = 0;
UINT CodePage = 0;
ok(IMLangFontLink_CodePageToCodePages(iMLFL, 932, &dwCodePages)==S_OK,
"IMLangFontLink_CodePageToCodePages failed\n");
ok (dwCodePages != 0, "No CodePages returned\n");
ok(IMLangFontLink_CodePagesToCodePage(iMLFL, dwCodePages, 1035,
&CodePage)==S_OK,
"IMLangFontLink_CodePagesToCodePage failed\n");
ok(CodePage == 932, "Incorrect CodePage Returned (%i)\n",CodePage);
ok(IMLangFontLink_CodePageToCodePages(iMLFL, 1252, &dwCodePages)==S_OK,
"IMLangFontLink_CodePageToCodePages failed\n");
dwManyCodePages = dwManyCodePages | dwCodePages;
ok(IMLangFontLink_CodePageToCodePages(iMLFL, 1256, &dwCodePages)==S_OK,
"IMLangFontLink_CodePageToCodePages failed\n");
dwManyCodePages = dwManyCodePages | dwCodePages;
ok(IMLangFontLink_CodePageToCodePages(iMLFL, 874, &dwCodePages)==S_OK,
"IMLangFontLink_CodePageToCodePages failed\n");
dwManyCodePages = dwManyCodePages | dwCodePages;
ok(IMLangFontLink_CodePagesToCodePage(iMLFL, dwManyCodePages, 1256,
&CodePage)==S_OK,
"IMLangFontLink_CodePagesToCodePage failed\n");
ok(CodePage == 1256, "Incorrect CodePage Returned (%i)\n",CodePage);
ok(IMLangFontLink_CodePagesToCodePage(iMLFL, dwManyCodePages, 936,
&CodePage)==S_OK,
"IMLangFontLink_CodePagesToCodePage failed\n");
ok(CodePage == 1252, "Incorrect CodePage Returned (%i)\n",CodePage);
}
static void test_rfc1766(IMultiLanguage2 *iML2)
{
IEnumRfc1766 *pEnumRfc1766;
RFC1766INFO info;
ULONG n;
HRESULT ret;
ret = IMultiLanguage2_EnumRfc1766(iML2, LANG_NEUTRAL, &pEnumRfc1766);
ok(ret == S_OK, "IMultiLanguage2_EnumRfc1766 error %08x\n", ret);
while (1)
{
ret = IEnumRfc1766_Next(pEnumRfc1766, 1, &info, &n);
if (ret != S_OK) break;
#ifdef DUMP_CP_INFO
trace("lcid %04x rfc_name %s locale_name %s\n",
info.lcid, wine_dbgstr_w(info.wszRfc1766), wine_dbgstr_w(info.wszLocaleName));
#endif
ok(n == 1, "couldn't fetch 1 RFC1766INFO structure\n");
ok(IsValidLocale(info.lcid, LCID_SUPPORTED), "invalid lcid %04x\n", info.lcid);
}
}
static void test_GetLcidFromRfc1766(IMultiLanguage2 *iML2)
{
LCID lcid;
HRESULT ret;
static WCHAR e[] = { 'e',0 };
static WCHAR en[] = { 'e','n',0 };
static WCHAR empty[] = { 0 };
static WCHAR dash[] = { '-',0 };
static WCHAR e_dash[] = { 'e','-',0 };
static WCHAR en_gb[] = { 'e','n','-','g','b',0 };
static WCHAR en_us[] = { 'e','n','-','u','s',0 };
static WCHAR en_them[] = { 'e','n','-','t','h','e','m',0 };
static WCHAR english[] = { 'e','n','g','l','i','s','h',0 };
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, NULL, en);
ok(ret == E_INVALIDARG, "GetLcidFromRfc1766 returned: %08x\n", ret);
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, NULL);
ok(ret == E_INVALIDARG, "GetLcidFromRfc1766 returned: %08x\n", ret);
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, e);
ok(ret == E_FAIL, "GetLcidFromRfc1766 returned: %08x\n", ret);
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, empty);
ok(ret == E_FAIL, "GetLcidFromRfc1766 returned: %08x\n", ret);
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, dash);
ok(ret == E_FAIL, "GetLcidFromRfc1766 returned: %08x\n", ret);
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, e_dash);
ok(ret == E_FAIL, "GetLcidFromRfc1766 returned: %08x\n", ret);
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, en_them);
ok(ret == E_FAIL, "GetLcidFromRfc1766 returned: %08x\n", ret);
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, english);
ok(ret == E_FAIL, "GetLcidFromRfc1766 returned: %08x\n", ret);
lcid = 0;
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, en);
ok(ret == S_OK, "GetLcidFromRfc1766 returned: %08x\n", ret);
ok(lcid == 9, "got wrong lcid: %04x\n", lcid);
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, en_gb);
ok(ret == S_OK, "GetLcidFromRfc1766 returned: %08x\n", ret);
ok(lcid == 0x809, "got wrong lcid: %04x\n", lcid);
ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, en_us);
ok(ret == S_OK, "GetLcidFromRfc1766 returned: %08x\n", ret);
ok(lcid == 0x409, "got wrong lcid: %04x\n", lcid);
}
START_TEST(mlang)
{
IMultiLanguage2 *iML2 = NULL;
IMLangFontLink *iMLFL = NULL;
HRESULT ret;
pGetCPInfoExA = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCPInfoExA");
CoInitialize(NULL);
TRACE_2("Call CoCreateInstance\n");
ret = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
&IID_IMultiLanguage2, (void **)&iML2);
trace("ret = %08x, MultiLanguage2 iML2 = %p\n", ret, iML2);
if (ret != S_OK || !iML2) return;
test_rfc1766(iML2);
test_GetLcidFromRfc1766(iML2);
test_EnumCodePages(iML2, 0);
test_EnumCodePages(iML2, MIMECONTF_MIME_LATEST);
test_EnumCodePages(iML2, MIMECONTF_BROWSER);
test_EnumCodePages(iML2, MIMECONTF_MINIMAL);
test_EnumCodePages(iML2, MIMECONTF_VALID);
/* FIXME: why MIMECONTF_MIME_REGISTRY returns 0 of supported codepages? */
/*test_EnumCodePages(iML2, MIMECONTF_MIME_REGISTRY);*/
test_EnumScripts(iML2, 0);
test_EnumScripts(iML2, SCRIPTCONTF_SCRIPT_USER);
test_EnumScripts(iML2, SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM);
TRACE_2("Call IMultiLanguage2_IsConvertible\n");
ret = IMultiLanguage2_IsConvertible(iML2, CP_UTF8, CP_UNICODE);
ok(ret == S_OK, "IMultiLanguage2_IsConvertible(CP_UTF8 -> CP_UNICODE) = %08x\n", ret);
TRACE_2("Call IMultiLanguage2_IsConvertible\n");
ret = IMultiLanguage2_IsConvertible(iML2, CP_UNICODE, CP_UTF8);
ok(ret == S_OK, "IMultiLanguage2_IsConvertible(CP_UNICODE -> CP_UTF8) = %08x\n", ret);
test_multibyte_to_unicode_translations(iML2);
IMultiLanguage2_Release(iML2);
ret = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
&IID_IMLangFontLink, (void **)&iMLFL);
trace("ret = %08x, IMLangFontLink iMLFL = %p\n", ret, iMLFL);
if (ret != S_OK || !iML2) return;
IMLangFontLink_Test(iMLFL);
IMLangFontLink_Release(iMLFL);
CoUninitialize();
}

View file

@ -0,0 +1,15 @@
<module name="mlang_winetest" type="win32cui" installbase="bin" installname="mlang_winetest.exe" allowwarnings="true">
<include base="mlang_winetest">.</include>
<define name="__USE_W32API" />
<define name="_WIN32_IE">0x600</define>
<define name="_WIN32_WINNT">0x501</define>
<define name="WINVER">0x501</define>
<library>wine</library>
<library>ole32</library>
<library>gdi32</library>
<library>kernel32</library>
<library>uuid</library>
<library>ntdll</library>
<file>mlang.c</file>
<file>testlist.c</file>
</module>

View file

@ -0,0 +1,15 @@
/* Automatically generated file; DO NOT EDIT!! */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define STANDALONE
#include "wine/test.h"
extern void func_mlang(void);
const struct test winetest_testlist[] =
{
{ "mlang", func_mlang },
{ 0, 0 }
};

View file

@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
@ -214,33 +214,30 @@ static HRESULT (WINAPI *pSHLWAPI_214)(_IDummyStream*,ULARGE_INTEGER*);
static void InitFunctionPtrs(void)
{
SHLWAPI_hshlwapi = LoadLibraryA("shlwapi.dll");
ok(SHLWAPI_hshlwapi != 0, "LoadLibrary failed\n");
if (SHLWAPI_hshlwapi)
{
pSHLWAPI_17 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)17);
ok(pSHLWAPI_17 != 0, "No Ordinal 17\n");
pSHLWAPI_18 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)18);
ok(pSHLWAPI_18 != 0, "No Ordinal 18\n");
pSHLWAPI_19 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)19);
ok(pSHLWAPI_19 != 0, "No Ordinal 19\n");
pSHLWAPI_20 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)20);
ok(pSHLWAPI_20 != 0, "No Ordinal 20\n");
pSHLWAPI_21 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)21);
ok(pSHLWAPI_21 != 0, "No Ordinal 21\n");
pSHLWAPI_22 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)22);
ok(pSHLWAPI_22 != 0, "No Ordinal 22\n");
pSHLWAPI_166 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)166);
ok(pSHLWAPI_166 != 0, "No Ordinal 166\n");
pSHLWAPI_184 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)184);
ok(pSHLWAPI_184 != 0, "No Ordinal 184\n");
pSHLWAPI_212 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)212);
ok(pSHLWAPI_212 != 0, "No Ordinal 212\n");
pSHLWAPI_213 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)213);
ok(pSHLWAPI_213 != 0, "No Ordinal 213\n");
pSHLWAPI_214 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)214);
ok(pSHLWAPI_214 != 0, "No Ordinal 214\n");
}
SHLWAPI_hshlwapi = GetModuleHandleA("shlwapi.dll");
pSHLWAPI_17 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)17);
ok(pSHLWAPI_17 != 0, "No Ordinal 17\n");
pSHLWAPI_18 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)18);
ok(pSHLWAPI_18 != 0, "No Ordinal 18\n");
pSHLWAPI_19 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)19);
ok(pSHLWAPI_19 != 0, "No Ordinal 19\n");
pSHLWAPI_20 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)20);
ok(pSHLWAPI_20 != 0, "No Ordinal 20\n");
pSHLWAPI_21 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)21);
ok(pSHLWAPI_21 != 0, "No Ordinal 21\n");
pSHLWAPI_22 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)22);
ok(pSHLWAPI_22 != 0, "No Ordinal 22\n");
pSHLWAPI_166 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)166);
ok(pSHLWAPI_166 != 0, "No Ordinal 166\n");
pSHLWAPI_184 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)184);
ok(pSHLWAPI_184 != 0, "No Ordinal 184\n");
pSHLWAPI_212 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)212);
ok(pSHLWAPI_212 != 0, "No Ordinal 212\n");
pSHLWAPI_213 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)213);
ok(pSHLWAPI_213 != 0, "No Ordinal 213\n");
pSHLWAPI_214 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)214);
ok(pSHLWAPI_214 != 0, "No Ordinal 214\n");
}
static void InitDummyStream(_IDummyStream* iface)
@ -299,21 +296,20 @@ static void test_CList(void)
inserted = pSHLWAPI_22(list, item->ulId);
ok(inserted != NULL, "lost after adding\n");
ok(!inserted || inserted->ulId != ~0UL, "find returned a container\n");
ok(!inserted || inserted->ulId != ~0U, "find returned a container\n");
/* Check size */
if (inserted && inserted->ulSize & 0x3)
{
/* Contained */
ok(inserted[-1].ulId == ~0UL, "invalid size is not countained\n");
ok(inserted[-1].ulId == ~0U, "invalid size is not countained\n");
ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST),
"container too small\n");
}
else if (inserted)
{
ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST),
"id %ld size wrong (%ld!=%ld)\n", inserted->ulId, inserted->ulSize,
item->ulSize+sizeof(SHLWAPI_CLIST));
"id %d wrong size %d\n", inserted->ulId, inserted->ulSize);
}
if (inserted)
{
@ -370,20 +366,22 @@ static void test_CList(void)
/* The call succeeds but the item is not inserted, except on some early
* versions which return failure. Wine behaves like later versions.
*/
#if 0
if (0)
{
ok(hRet == S_OK, "failed bad element size\n");
#endif
}
inserted = pSHLWAPI_22(list, 33);
ok(inserted == NULL, "inserted bad element size\n");
inserted = (LPSHLWAPI_CLIST)buff;
inserted->ulSize = 44;
inserted->ulId = ~0UL;
inserted->ulId = ~0U;
hRet = pSHLWAPI_20(&list, inserted);
/* See comment above, some early versions fail this call */
#if 0
if (0)
{
ok(hRet == S_OK, "failed adding a container\n");
#endif
}
item = SHLWAPI_CLIST_items;
/* Look for nonexistent item in populated list */
@ -424,21 +422,20 @@ static void test_CList(void)
inserted = pSHLWAPI_22(list, item->ulId);
ok(inserted != NULL, "lost after adding\n");
ok(!inserted || inserted->ulId != ~0UL, "find returned a container\n");
ok(!inserted || inserted->ulId != ~0U, "find returned a container\n");
/* Check size */
if (inserted && inserted->ulSize & 0x3)
{
/* Contained */
ok(inserted[-1].ulId == ~0UL, "invalid size is not countained\n");
ok(inserted[-1].ulId == ~0U, "invalid size is not countained\n");
ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST),
"container too small\n");
}
else if (inserted)
{
ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST),
"id %ld size wrong (%ld!=%ld)\n", inserted->ulId, inserted->ulSize,
item->ulSize+sizeof(SHLWAPI_CLIST));
"id %d wrong size %d\n", inserted->ulId, inserted->ulSize);
}
ok(!inserted || inserted->ulId==item->ulId, "find got wrong item\n");
if (inserted)
@ -637,7 +634,4 @@ START_TEST(clist)
test_SHLWAPI_213();
test_SHLWAPI_214();
}
if (SHLWAPI_hshlwapi)
FreeLibrary(SHLWAPI_hshlwapi);
}

View file

@ -14,19 +14,25 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#define INITGUID
#include "wine/test.h"
#include "winbase.h"
#include "winerror.h"
#include "winnls.h"
#include "winuser.h"
#include "shlguid.h"
#include "wine/shobjidl.h"
#include "shobjidl.h"
#include "olectl.h"
#define INITGUID
#include "initguid.h"
/* This GUID has been removed from the PSDK */
DEFINE_OLEGUID(WINE_IID_IDelayedRelease, 0x000214EDL, 0, 0);
/* Function ptrs for ordinal calls */
static HMODULE hShlwapi = 0;
@ -56,7 +62,7 @@ const GUID * TEST_guids[] = {
&IID_IPersistFolder,
&IID_IExtractIconA,
&IID_IShellDetails,
&IID_IDelayedRelease,
&WINE_IID_IDelayedRelease,
&IID_IShellLinkA,
&IID_IShellCopyHookA,
&IID_IFileViewerA,
@ -153,19 +159,33 @@ static void test_ClassIDs(void)
ok(szBuff[0] == '{', "Didn't write to buffer with ok length\n");
}
static void test_CLSIDFromProgIDWrap(void)
{
HRESULT (WINAPI *pCLSIDFromProgIDWrap)(LPCOLESTR,LPCLSID);
CLSID clsid = IID_NULL;
HRESULT hres;
static const WCHAR wszStdPicture[] = {'S','t','d','P','i','c','t','u','r','e',0};
pCLSIDFromProgIDWrap = (void*)GetProcAddress(hShlwapi,(char*)435);
hres = pCLSIDFromProgIDWrap(wszStdPicture, &clsid);
ok(hres == S_OK, "CLSIDFromProgIDWrap failed: %08x\n", hres);
ok(IsEqualGUID(&CLSID_StdPicture, &clsid), "wrong clsid\n");
hres = pCLSIDFromProgIDWrap(NULL, &clsid);
ok(hres == E_INVALIDARG, "CLSIDFromProgIDWrap failed: %08x, expected E_INVALIDARG\n", hres);
hres = pCLSIDFromProgIDWrap(wszStdPicture, NULL);
ok(hres == E_INVALIDARG, "CLSIDFromProgIDWrap failed: %08x, expected E_INVALIDARG\n", hres);
}
START_TEST(clsid)
{
hShlwapi = LoadLibraryA("shlwapi.dll");
ok(hShlwapi != 0, "LoadLibraryA failed\n");
if (hShlwapi)
{
pSHLWAPI_269 = (void*)GetProcAddress(hShlwapi, (LPSTR)269);
pSHLWAPI_23 = (void*)GetProcAddress(hShlwapi, (LPSTR)23);
}
hShlwapi = GetModuleHandleA("shlwapi.dll");
pSHLWAPI_269 = (void*)GetProcAddress(hShlwapi, (LPSTR)269);
pSHLWAPI_23 = (void*)GetProcAddress(hShlwapi, (LPSTR)23);
test_ClassIDs();
if (hShlwapi)
FreeLibrary(hShlwapi);
test_CLSIDFromProgIDWrap();
}

View file

@ -157,11 +157,6 @@ static void test_pack_HUSKEY(void)
TEST_TYPE(HUSKEY, 4, 4);
}
static void test_pack_IQueryAssociations(void)
{
/* IQueryAssociations */
}
static void test_pack_PHUSKEY(void)
{
/* PHUSKEY */
@ -176,7 +171,6 @@ static void test_pack(void)
test_pack_DLLVERSIONINFO();
test_pack_DLLVERSIONINFO2();
test_pack_HUSKEY();
test_pack_IQueryAssociations();
test_pack_PHUSKEY();
}

View file

@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
@ -46,8 +46,8 @@ static void test_GetAcceptLanguagesA(void)
memset(buffer, 0, sizeof(buffer));
SetLastError(ERROR_SUCCESS);
retval = pGetAcceptLanguagesA( buffer, &buffersize);
trace("GetAcceptLanguagesA: retval %08lx, size %08lx, buffer (%s),"
" last error %ld\n", retval, buffersize, buffer, GetLastError());
trace("GetAcceptLanguagesA: retval %08x, size %08x, buffer (%s),"
" last error %u\n", retval, buffersize, buffer, GetLastError());
if(retval != S_OK) {
trace("GetAcceptLanguagesA: skipping tests\n");
return;
@ -56,39 +56,39 @@ static void test_GetAcceptLanguagesA(void)
(ERROR_CLASS_DOES_NOT_EXIST == GetLastError()) ||
(ERROR_PROC_NOT_FOUND == GetLastError()) ||
(ERROR_CALL_NOT_IMPLEMENTED == GetLastError()) ||
(ERROR_SUCCESS == GetLastError()), "last error set to %ld\n", GetLastError());
(ERROR_SUCCESS == GetLastError()), "last error set to %u\n", GetLastError());
exactsize = strlen(buffer);
SetLastError(ERROR_SUCCESS);
retval = pGetAcceptLanguagesA( NULL, NULL);
ok(retval == E_FAIL,
"function result wrong: got %08lx; expected E_FAIL\n", retval);
ok(ERROR_SUCCESS == GetLastError(), "last error set to %ld\n", GetLastError());
"function result wrong: got %08x; expected E_FAIL\n", retval);
ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
buffersize = sizeof(buffer);
SetLastError(ERROR_SUCCESS);
retval = pGetAcceptLanguagesA( NULL, &buffersize);
ok(retval == E_FAIL,
"function result wrong: got %08lx; expected E_FAIL\n", retval);
"function result wrong: got %08x; expected E_FAIL\n", retval);
ok(buffersize == sizeof(buffer),
"buffersize was changed (2nd parameter; not on Win2k)\n");
ok(ERROR_SUCCESS == GetLastError(), "last error set to %ld\n", GetLastError());
ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
SetLastError(ERROR_SUCCESS);
retval = pGetAcceptLanguagesA( buffer, NULL);
ok(retval == E_FAIL,
"function result wrong: got %08lx; expected E_FAIL\n", retval);
ok(ERROR_SUCCESS == GetLastError(), "last error set to %ld\n", GetLastError());
"function result wrong: got %08x; expected E_FAIL\n", retval);
ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
buffersize = 0;
memset(buffer, 0, sizeof(buffer));
SetLastError(ERROR_SUCCESS);
retval = pGetAcceptLanguagesA( buffer, &buffersize);
ok(retval == E_FAIL,
"function result wrong: got %08lx; expected E_FAIL\n", retval);
"function result wrong: got %08x; expected E_FAIL\n", retval);
ok(buffersize == 0,
"buffersize wrong(changed) got %08lx; expected 0 (2nd parameter; not on Win2k)\n", buffersize);
ok(ERROR_SUCCESS == GetLastError(), "last error set to %ld\n", GetLastError());
"buffersize wrong(changed) got %08x; expected 0 (2nd parameter; not on Win2k)\n", buffersize);
ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
buffersize = buffersize2 = 1;
memset(buffer, 0, sizeof(buffer));
@ -99,29 +99,29 @@ static void test_GetAcceptLanguagesA(void)
if(buffersize == exactsize) {
ok( (ERROR_SUCCESS == GetLastError()) || (ERROR_CALL_NOT_IMPLEMENTED == GetLastError()) ||
(ERROR_PROC_NOT_FOUND == GetLastError()) || (ERROR_NO_IMPERSONATION_TOKEN == GetLastError()),
"last error wrong: got %08lx; expected ERROR_SUCCESS(NT4)/ERROR_CALL_NOT_IMPLEMENTED(98/ME)/"
"last error wrong: got %u; expected ERROR_SUCCESS(NT4)/ERROR_CALL_NOT_IMPLEMENTED(98/ME)/"
"ERROR_PROC_NOT_FOUND(NT4)/ERROR_NO_IMPERSONATION_TOKEN(XP)\n", GetLastError());
ok(exactsize == strlen(buffer),
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), exactsize);
"buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), exactsize);
} else if((buffersize +1) == buffersize2) {
ok(ERROR_SUCCESS == GetLastError(),
"last error wrong: got %08lx; expected ERROR_SUCCESS\n", GetLastError());
"last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
ok(buffersize == strlen(buffer),
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), buffersize);
"buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize);
} else
ok( 0, "retval %08lx, size %08lx, buffer (%s), last error %ld\n",
ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
retval, buffersize, buffer, GetLastError());
break;
case E_INVALIDARG:
ok(buffersize == 0,
"buffersize wrong: got %08lx, expected 0 (2nd parameter;Win2k)\n", buffersize);
"buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
"last error wrong: got %08lx; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
"last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
ok(buffersize2 == strlen(buffer),
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), buffersize2);
"buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize2);
break;
default:
ok( 0, "retval %08lx, size %08lx, buffer (%s), last error %ld\n",
ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
retval, buffersize, buffer, GetLastError());
break;
}
@ -133,25 +133,25 @@ static void test_GetAcceptLanguagesA(void)
switch(retval) {
case 0L:
ok(ERROR_SUCCESS == GetLastError(),
"last error wrong: got %08lx; expected ERROR_SUCCESS\n", GetLastError());
"last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
if((buffersize == exactsize) /* XP */ ||
((buffersize +1)== exactsize) /* 98 */)
ok(buffersize == strlen(buffer),
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), buffersize);
"buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize);
else
ok( 0, "retval %08lx, size %08lx, buffer (%s), last error %ld\n",
ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
retval, buffersize, buffer, GetLastError());
break;
case E_INVALIDARG:
ok(buffersize == 0,
"buffersize wrong: got %08lx, expected 0 (2nd parameter;Win2k)\n", buffersize);
"buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
"last error wrong: got %08lx; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
"last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
ok(buffersize2 == strlen(buffer),
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), buffersize2);
"buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize2);
break;
default:
ok( 0, "retval %08lx, size %08lx, buffer (%s), last error %ld\n",
ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
retval, buffersize, buffer, GetLastError());
break;
}
@ -208,31 +208,232 @@ static void test_alloc_shared(void)
procid=GetCurrentProcessId();
hmem=pSHAllocShared(NULL,10,procid);
ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %ld\n", GetLastError());
ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
ret = pSHFreeShared(hmem, procid);
ok( ret, "SHFreeShared failed: %ld\n", GetLastError());
ok( ret, "SHFreeShared failed: %u\n", GetLastError());
val=0x12345678;
hmem=pSHAllocShared(&val,4,procid);
ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %ld\n", GetLastError());
ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
p=(int*)pSHLockShared(hmem,procid);
ok(p!=NULL,"SHLockShared failed: %ld\n", GetLastError());
ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError());
if (p!=NULL)
ok(*p==val,"Wrong value in shared memory: %d instead of %d\n",*p,val);
ret = pSHUnlockShared(p);
ok( ret, "SHUnlockShared failed: %ld\n", GetLastError());
ok( ret, "SHUnlockShared failed: %u\n", GetLastError());
ret = pSHFreeShared(hmem, procid);
ok( ret, "SHFreeShared failed: %ld\n", GetLastError());
ok( ret, "SHFreeShared failed: %u\n", GetLastError());
}
static void test_fdsa(void)
{
typedef struct
{
DWORD num_items; /* Number of elements inserted */
void *mem; /* Ptr to array */
DWORD blocks_alloced; /* Number of elements allocated */
BYTE inc; /* Number of elements to grow by when we need to expand */
BYTE block_size; /* Size in bytes of an element */
BYTE flags; /* Flags */
} FDSA_info;
BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
DWORD init_blocks);
BOOL (WINAPI *pFDSA_Destroy)(FDSA_info *info);
DWORD (WINAPI *pFDSA_InsertItem)(FDSA_info *info, DWORD where, const void *block);
BOOL (WINAPI *pFDSA_DeleteItem)(FDSA_info *info, DWORD where);
FDSA_info info;
int block_size = 10, init_blocks = 4, inc = 2;
DWORD ret;
char *mem;
pFDSA_Initialize = (void *)GetProcAddress(hShlwapi, (LPSTR)208);
pFDSA_Destroy = (void *)GetProcAddress(hShlwapi, (LPSTR)209);
pFDSA_InsertItem = (void *)GetProcAddress(hShlwapi, (LPSTR)210);
pFDSA_DeleteItem = (void *)GetProcAddress(hShlwapi, (LPSTR)211);
mem = HeapAlloc(GetProcessHeap(), 0, block_size * init_blocks);
memset(&info, 0, sizeof(info));
ok(pFDSA_Initialize(block_size, inc, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
ok(info.num_items == 0, "num_items = %d\n", info.num_items);
ok(info.mem == mem, "mem = %p\n", info.mem);
ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
ok(info.inc == inc, "inc = %d\n", info.inc);
ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
ok(info.flags == 0, "flags = %d\n", info.flags);
ret = pFDSA_InsertItem(&info, 1234, "1234567890");
ok(ret == 0, "ret = %d\n", ret);
ok(info.num_items == 1, "num_items = %d\n", info.num_items);
ok(info.mem == mem, "mem = %p\n", info.mem);
ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
ok(info.inc == inc, "inc = %d\n", info.inc);
ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
ok(info.flags == 0, "flags = %d\n", info.flags);
ret = pFDSA_InsertItem(&info, 1234, "abcdefghij");
ok(ret == 1, "ret = %d\n", ret);
ret = pFDSA_InsertItem(&info, 1, "klmnopqrst");
ok(ret == 1, "ret = %d\n", ret);
ret = pFDSA_InsertItem(&info, 0, "uvwxyzABCD");
ok(ret == 0, "ret = %d\n", ret);
ok(info.mem == mem, "mem = %p\n", info.mem);
ok(info.flags == 0, "flags = %d\n", info.flags);
/* This next InsertItem will cause shlwapi to allocate its own mem buffer */
ret = pFDSA_InsertItem(&info, 0, "EFGHIJKLMN");
ok(ret == 0, "ret = %d\n", ret);
ok(info.mem != mem, "mem = %p\n", info.mem);
ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
ok(info.flags == 0x1, "flags = %d\n", info.flags);
ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem);
ok(pFDSA_DeleteItem(&info, 2), "rets FALSE\n");
ok(info.mem != mem, "mem = %p\n", info.mem);
ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
ok(info.flags == 0x1, "flags = %d\n", info.flags);
ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem);
ok(pFDSA_DeleteItem(&info, 3), "rets FALSE\n");
ok(info.mem != mem, "mem = %p\n", info.mem);
ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
ok(info.flags == 0x1, "flags = %d\n", info.flags);
ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem);
ok(!pFDSA_DeleteItem(&info, 4), "does not ret FALSE\n");
/* As shlwapi has allocated memory internally, Destroy will ret FALSE */
ok(!pFDSA_Destroy(&info), "FDSA_Destroy does not ret FALSE\n");
/* When Initialize is called with inc = 0, set it to 1 */
ok(pFDSA_Initialize(block_size, 0, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
ok(info.inc == 1, "inc = %d\n", info.inc);
/* This time, because shlwapi hasn't had to allocate memory
internally, Destroy rets non-zero */
ok(pFDSA_Destroy(&info), "FDSA_Destroy rets FALSE\n");
HeapFree(GetProcessHeap(), 0, mem);
}
typedef struct SHELL_USER_SID {
SID_IDENTIFIER_AUTHORITY sidAuthority;
DWORD dwUserGroupID;
DWORD dwUserID;
} SHELL_USER_SID, *PSHELL_USER_SID;
typedef struct SHELL_USER_PERMISSION {
SHELL_USER_SID susID;
DWORD dwAccessType;
BOOL fInherit;
DWORD dwAccessMask;
DWORD dwInheritMask;
DWORD dwInheritAccessMask;
} SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
static void test_GetShellSecurityDescriptor(void)
{
SHELL_USER_PERMISSION supCurrentUserFull = {
{ {SECURITY_NULL_SID_AUTHORITY}, 0, 0 },
ACCESS_ALLOWED_ACE_TYPE, FALSE,
GENERIC_ALL, 0, 0 };
#define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
SHELL_USER_PERMISSION supEveryoneDenied = {
{ {SECURITY_WORLD_SID_AUTHORITY}, SECURITY_WORLD_RID, 0 },
ACCESS_DENIED_ACE_TYPE, TRUE,
GENERIC_WRITE, MY_INHERITANCE | 0xDEADBA00, GENERIC_READ };
PSHELL_USER_PERMISSION rgsup[2] = {
&supCurrentUserFull, &supEveryoneDenied,
};
SECURITY_DESCRIPTOR* psd;
SECURITY_DESCRIPTOR* (WINAPI*pGetShellSecurityDescriptor)(PSHELL_USER_PERMISSION*,int);
pGetShellSecurityDescriptor=(void*)GetProcAddress(hShlwapi,(char*)475);
psd = pGetShellSecurityDescriptor(NULL, 2);
ok(psd==NULL, "GetShellSecurityDescriptor should fail\n");
psd = pGetShellSecurityDescriptor(rgsup, 0);
ok(psd==NULL, "GetShellSecurityDescriptor should fail\n");
psd = pGetShellSecurityDescriptor(rgsup, 2);
ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
if (psd!=NULL)
{
BOOL bHasDacl = FALSE, bDefaulted;
PACL pAcl;
DWORD dwRev;
SECURITY_DESCRIPTOR_CONTROL control;
ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n");
ok(GetSecurityDescriptorControl(psd, &control, &dwRev),
"GetSecurityDescriptorControl failed with error %u\n", GetLastError());
ok(0 == (control & SE_SELF_RELATIVE), "SD should be absolute\n");
ok(GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted),
"GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
ok(bHasDacl, "SD has no DACL\n");
if (bHasDacl)
{
ok(!bDefaulted, "DACL should not be defaulted\n");
ok(pAcl != NULL, "NULL DACL!\n");
if (pAcl != NULL)
{
ACL_SIZE_INFORMATION asiSize;
ok(IsValidAcl(pAcl), "DACL is not valid\n");
ok(GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation),
"GetAclInformation failed with error %u\n", GetLastError());
ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount);
if (asiSize.AceCount == 3)
{
ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */
ok(GetAce(pAcl, 0, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
ok(paaa->Header.AceType == ACCESS_ALLOWED_ACE_TYPE,
"Invalid ACE type %d\n", paaa->Header.AceType);
ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %x\n", paaa->Mask);
ok(GetAce(pAcl, 1, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
"Invalid ACE type %d\n", paaa->Header.AceType);
/* first one of two ACEs generated from inheritable entry - without inheritance */
ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %x\n", paaa->Mask);
ok(GetAce(pAcl, 2, (LPVOID*)&paaa), "GetAce failed with error %u\n", GetLastError());
ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE,
"Invalid ACE type %d\n", paaa->Header.AceType);
/* second ACE - with inheritance */
ok(paaa->Header.AceFlags == MY_INHERITANCE,
"Invalid ACE flags %x\n", paaa->Header.AceFlags);
ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %x\n", paaa->Mask);
}
}
}
LocalFree(psd);
}
}
START_TEST(ordinal)
{
hShlwapi = LoadLibraryA("shlwapi.dll");
ok(hShlwapi != 0, "LoadLibraryA failed\n");
if (!hShlwapi)
return;
hShlwapi = GetModuleHandleA("shlwapi.dll");
pGetAcceptLanguagesA = (void*)GetProcAddress(hShlwapi, (LPSTR)14);
pSHSearchMapInt = (void*)GetProcAddress(hShlwapi, (LPSTR)198);
@ -244,5 +445,6 @@ START_TEST(ordinal)
test_GetAcceptLanguagesA();
test_SHSearchMapInt();
test_alloc_shared();
FreeLibrary(hShlwapi);
test_fdsa();
test_GetShellSecurityDescriptor();
}

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,23 @@
<module name="shlwapi_winetest" type="win32cui" installbase="bin" installname="shlwapi_winetest.exe" allowwarnings="true">
<include base="shlwapi_winetest">.</include>
<define name="__USE_W32API" />
<library>ntdll</library>
<library>shlwapi</library>
<library>ole32</library>
<library>oleaut32</library>
<library>kernel32</library>
<library>advapi32</library>
<file>clist.c</file>
<file>ordinal.c</file>
<file>shreg.c</file>
<file>string.c</file>
<file>testlist.c</file>
<include base="shlwapi_winetest">.</include>
<define name="__USE_W32API" />
<define name="_WIN32_IE">0x600</define>
<define name="_WIN32_WINNT">0x501</define>
<define name="WINVER">0x501</define>
<library>wine</library>
<library>shlwapi</library>
<library>advapi32</library>
<library>ole32</library>
<library>oleaut32</library>
<library>kernel32</library>
<library>uuid</library>
<library>ntdll</library>
<file>clist.c</file>
<file>clsid.c</file>
<file>generated.c</file>
<file>ordinal.c</file>
<file>path.c</file>
<file>shreg.c</file>
<file>string.c</file>
<file>testlist.c</file>
</module>

View file

@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
@ -39,21 +39,21 @@ static SHCopyKeyA_func pSHCopyKeyA;
typedef DWORD (WINAPI *SHRegGetPathA_func)(HKEY,LPCSTR,LPCSTR,LPSTR,DWORD);
static SHRegGetPathA_func pSHRegGetPathA;
static const char * sTestpath1 = "%LONGSYSTEMVAR%\\subdir1";
static const char * sTestpath2 = "%FOO%\\subdir1";
static char sTestpath1[] = "%LONGSYSTEMVAR%\\subdir1";
static char sTestpath2[] = "%FOO%\\subdir1";
static const char * sEnvvar1 = "bar";
static const char * sEnvvar2 = "ImARatherLongButIndeedNeededString";
static char sExpTestpath1[MAX_PATH];
static char sExpTestpath2[MAX_PATH];
static unsigned sExpLen1;
static unsigned sExpLen2;
static DWORD nExpLen1;
static DWORD nExpLen2;
static const char * sEmptyBuffer ="0123456789";
/* delete key and all its subkeys */
static DWORD delete_key( HKEY hkey, LPSTR parent, LPSTR keyname )
static DWORD delete_key( HKEY hkey, LPCSTR parent, LPCSTR keyname )
{
HKEY parentKey;
DWORD ret;
@ -75,12 +75,13 @@ static HKEY create_test_entries(void)
{
HKEY hKey;
DWORD ret;
DWORD nExpectedLen1, nExpectedLen2;
SetEnvironmentVariableA("LONGSYSTEMVAR", sEnvvar1);
SetEnvironmentVariableA("FOO", sEnvvar2);
ret = RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY, &hKey);
ok( ERROR_SUCCESS == ret, "RegCreateKeyA failed, ret=%lu\n", ret);
ok( ERROR_SUCCESS == ret, "RegCreateKeyA failed, ret=%u\n", ret);
if (hKey)
{
@ -89,15 +90,24 @@ static HKEY create_test_entries(void)
ok(!RegSetValueExA(hKey,"Test3",0,REG_EXPAND_SZ, (LPBYTE) sTestpath2, strlen(sTestpath2)+1), "RegSetValueExA failed\n");
}
sExpLen1 = ExpandEnvironmentStringsA(sTestpath1, sExpTestpath1, sizeof(sExpTestpath1));
sExpLen2 = ExpandEnvironmentStringsA(sTestpath2, sExpTestpath2, sizeof(sExpTestpath2));
nExpLen1 = ExpandEnvironmentStringsA(sTestpath1, sExpTestpath1, sizeof(sExpTestpath1));
nExpLen2 = ExpandEnvironmentStringsA(sTestpath2, sExpTestpath2, sizeof(sExpTestpath2));
ok(sExpLen1 > 0, "Couldn't expand %s\n", sTestpath1);
trace("sExplen1 = (%d)\n", sExpLen1);
ok(sExpLen2 > 0, "Couldn't expand %s\n", sTestpath2);
trace("sExplen2 = (%d)\n", sExpLen2);
nExpectedLen1 = strlen(sTestpath1) - strlen("%LONGSYSTEMVAR%") + strlen(sEnvvar1) + 1;
nExpectedLen2 = strlen(sTestpath2) - strlen("%FOO%") + strlen(sEnvvar2) + 1;
/* ExpandEnvironmentStringsA on NT4 returns 2x the correct result */
trace("sExplen1 = (%d)\n", nExpLen1);
if (nExpectedLen1 != nExpLen1)
trace( "Expanding %s failed (expected %d) - known bug in NT4\n", sTestpath1, nExpectedLen1 );
return hKey;
trace("sExplen2 = (%d)\n", nExpLen2);
if (nExpectedLen2 != nExpLen2)
trace( "Expanding %s failed (expected %d) - known bug in NT4\n", sTestpath2, nExpectedLen2 );
/* Make sure we carry on with correct values */
nExpLen1 = nExpectedLen1;
nExpLen2 = nExpectedLen2;
return hKey;
}
static void test_SHGetValue(void)
@ -111,17 +121,17 @@ static void test_SHGetValue(void)
dwSize = MAX_PATH;
dwType = -1;
dwRet = SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", &dwType, buf, &dwSize);
ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%lu\n", dwRet);
ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%u\n", dwRet);
ok( 0 == strcmp(sExpTestpath1, buf), "Comparing of (%s) with (%s) failed\n", buf, sExpTestpath1);
ok( REG_SZ == dwType, "Expected REG_SZ, got (%lu)\n", dwType);
ok( REG_SZ == dwType, "Expected REG_SZ, got (%u)\n", dwType);
strcpy(buf, sEmptyBuffer);
dwSize = MAX_PATH;
dwType = -1;
dwRet = SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", &dwType, buf, &dwSize);
ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%lu\n", dwRet);
ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%u\n", dwRet);
ok( 0 == strcmp(sTestpath1, buf) , "Comparing of (%s) with (%s) failed\n", buf, sTestpath1);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType);
}
static void test_SHGetRegPath(void)
@ -134,7 +144,7 @@ static void test_SHGetRegPath(void)
strcpy(buf, sEmptyBuffer);
dwRet = (*pSHRegGetPathA)(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", buf, 0);
ok( ERROR_SUCCESS == dwRet, "SHRegGetPathA failed, ret=%lu\n", dwRet);
ok( ERROR_SUCCESS == dwRet, "SHRegGetPathA failed, ret=%u\n", dwRet);
ok( 0 == strcmp(sExpTestpath1, buf) , "Comparing (%s) with (%s) failed\n", buf, sExpTestpath1);
}
@ -150,7 +160,7 @@ static void test_SHQUeryValueEx(void)
sTestedFunction = "RegOpenKeyExA";
dwRet = RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_KEY, 0, KEY_QUERY_VALUE, &hKey);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet);
/****** SHQueryValueExA ******/
@ -161,15 +171,15 @@ static void test_SHQUeryValueEx(void)
* Case 1.1 All arguments are NULL
*/
dwRet = SHQueryValueExA( hKey, "Test1", NULL, NULL, NULL, NULL);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet);
/*
* Case 1.2 dwType is set
*/
dwType = -1;
dwRet = SHQueryValueExA( hKey, "Test1", NULL, &dwType, NULL, NULL);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType);
/*
* dwSize is set
@ -177,16 +187,16 @@ static void test_SHQUeryValueEx(void)
*/
dwSize = 6;
dwRet = SHQueryValueExA( hKey, "Test1", NULL, NULL, NULL, &dwSize);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
ok( dwSize == nUsedBuffer1, "Buffer sizes (%lu) and (%lu) are not equal\n", dwSize, nUsedBuffer1);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet);
ok( dwSize == nUsedBuffer1, "Buffer sizes (%u) and (%u) are not equal\n", dwSize, nUsedBuffer1);
/*
* dwExpanded > dwUnExpanded
*/
dwSize = 6;
dwRet = SHQueryValueExA( hKey, "Test3", NULL, NULL, NULL, &dwSize);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet);
ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2);
/*
* Case 1 string shrinks during expanding
@ -195,63 +205,65 @@ static void test_SHQUeryValueEx(void)
dwSize = 6;
dwType = -1;
dwRet = SHQueryValueExA( hKey, "Test1", NULL, &dwType, buf, &dwSize);
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet);
ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer);
ok( dwSize == nUsedBuffer1, "Buffer sizes (%lu) and (%lu) are not equal\n", dwSize, nUsedBuffer1);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
ok( dwSize == nUsedBuffer1, "Buffer sizes (%u) and (%u) are not equal\n", dwSize, nUsedBuffer1);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType);
/*
* string grows during expanding
* dwSize is smaller then the size of the unexpanded string
* dwSize is smaller than the size of the unexpanded string
*/
strcpy(buf, sEmptyBuffer);
dwSize = 6;
dwType = -1;
dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize);
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet);
ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer);
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType);
/*
* string grows during expanding
* dwSize is larger then the size of the unexpanded string but smaller than the part before the backslash
* if the unexpanded string fits into the buffer it can get cut when expanded
* dwSize is larger than the size of the unexpanded string, but
* smaller than the part before the backslash. If the unexpanded
* string fits into the buffer, it can get cut when expanded.
*/
strcpy(buf, sEmptyBuffer);
dwSize = strlen(sEnvvar2) - 2;
dwType = -1;
dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize);
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet);
todo_wine
{
ok( (0 == strcmp("", buf)) | (0 == strcmp(sTestpath2, buf)),
ok( (0 == strcmp("", buf)) || (0 == strcmp(sTestpath2, buf)),
"Expected empty or unexpanded string (win98), got (%s)\n", buf);
}
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType);
/*
* string grows during expanding
* dwSize is larger then the size of the part before the backslash but smaller then the expanded string
* if the unexpanded string fits into the buffer it can get cut when expanded
* dwSize is larger than the size of the part before the backslash,
* but smaller than the expanded string. If the unexpanded string fits
* into the buffer, it can get cut when expanded.
*/
strcpy(buf, sEmptyBuffer);
dwSize = sExpLen2 - 4;
dwSize = nExpLen2 - 4;
dwType = -1;
dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize);
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet);
todo_wine
{
ok( (0 == strcmp("", buf)) | (0 == strcmp(sEnvvar2, buf)),
ok( (0 == strcmp("", buf)) || (0 == strcmp(sEnvvar2, buf)),
"Expected empty or first part of the string \"%s\", got \"%s\"\n", sEnvvar2, buf);
}
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType);
/*
* The buffer is NULL but the size is set
@ -260,9 +272,9 @@ static void test_SHQUeryValueEx(void)
dwSize = 6;
dwType = -1;
dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, NULL, &dwSize);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet);
ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2);
ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType);
RegCloseKey(hKey);
}
@ -284,7 +296,7 @@ static void test_SHCopyKey(void)
dwRet = RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination", &hKeyDst);
if (dwRet || !hKeyDst)
{
ok( 0, "Destination couldn't be created, RegCreateKeyA returned (%lu)\n", dwRet);
ok( 0, "Destination couldn't be created, RegCreateKeyA returned (%u)\n", dwRet);
return;
}
@ -292,7 +304,7 @@ static void test_SHCopyKey(void)
dwRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, REG_CURRENT_VERSION, &hKeySrc);
if (dwRet || !hKeySrc)
{
ok( 0, "Source couldn't be opened, RegOpenKeyA returned (%lu)\n", dwRet);
ok( 0, "Source couldn't be opened, RegOpenKeyA returned (%u)\n", dwRet);
return;
}
@ -300,7 +312,7 @@ static void test_SHCopyKey(void)
if (pSHCopyKeyA)
{
dwRet = (*pSHCopyKeyA)(hKeySrc, NULL, hKeyDst, 0);
ok ( ERROR_SUCCESS == dwRet, "Copy failed, ret=(%lu)\n", dwRet);
ok ( ERROR_SUCCESS == dwRet, "Copy failed, ret=(%u)\n", dwRet);
}
RegCloseKey(hKeySrc);
@ -311,7 +323,7 @@ static void test_SHCopyKey(void)
dwRet = RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination\\Setup", &hKeyDst);
if (dwRet || !hKeyDst)
{
ok ( 0, "Copy couldn't be opened, RegOpenKeyA returned (%lu)\n", dwRet);
ok ( 0, "Copy couldn't be opened, RegOpenKeyA returned (%u)\n", dwRet);
return;
}
@ -352,7 +364,7 @@ static void test_SHDeleteKey(void)
{
dwRet = SHDeleteKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\ODBC");
ok ( ERROR_SUCCESS == dwRet, "SHDeleteKey failed, ret=(%lu)\n", dwRet);
ok ( ERROR_SUCCESS == dwRet, "SHDeleteKey failed, ret=(%u)\n", dwRet);
dwRet = RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\ODBC", &hKeyS);
ok ( ERROR_FILE_NOT_FOUND == dwRet, "SHDeleteKey did not delete\n");
@ -371,11 +383,8 @@ START_TEST(shreg)
if (!hkey) return;
hshlwapi = GetModuleHandleA("shlwapi.dll");
if (hshlwapi)
{
pSHCopyKeyA=(SHCopyKeyA_func)GetProcAddress(hshlwapi,"SHCopyKeyA");
pSHRegGetPathA=(SHRegGetPathA_func)GetProcAddress(hshlwapi,"SHRegGetPathA");
}
pSHCopyKeyA=(SHCopyKeyA_func)GetProcAddress(hshlwapi,"SHCopyKeyA");
pSHRegGetPathA=(SHRegGetPathA_func)GetProcAddress(hshlwapi,"SHRegGetPathA");
test_SHGetValue();
test_SHQUeryValueEx();
test_SHGetRegPath();

View file

@ -14,13 +14,11 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "wine/test.h"
#include "winbase.h"
#include "winerror.h"
@ -32,6 +30,11 @@
#include "shlwapi.h"
#include "shtypes.h"
#define expect_eq(expr, val, type, fmt) do { \
type ret = expr; \
ok(ret == val, "Unexpected value of '" #expr "': " #fmt " instead of " #val "\n", ret); \
} while (0);
static HMODULE hShlwapi;
static LPSTR (WINAPI *pStrCpyNXA)(LPSTR,LPCSTR,int);
static LPWSTR (WINAPI *pStrCpyNXW)(LPWSTR,LPCWSTR,int);
@ -43,7 +46,7 @@ static BOOL (WINAPI *pIntlStrEqWorkerA)(BOOL,LPCSTR,LPCSTR,int);
static BOOL (WINAPI *pStrIsIntlEqualW)(BOOL,LPCWSTR,LPCWSTR,int);
static BOOL (WINAPI *pIntlStrEqWorkerW)(BOOL,LPCWSTR,LPCWSTR,int);
static inline int strcmpW(const WCHAR *str1, const WCHAR *str2)
static int strcmpW(const WCHAR *str1, const WCHAR *str2)
{
while (*str1 && (*str1 == *str2)) { str1++; str2++; }
return *str1 - *str2;
@ -492,7 +495,7 @@ static void test_StrFormatByteSize64A(void)
StrFormatByteSize64A(result->value, szBuff, 256);
ok(!strcmp(result->byte_size_64, szBuff),
"Formatted %lx%08lx wrong: got %s, expected %s\n",
"Formatted %x%08x wrong: got %s, expected %s\n",
(LONG)(result->value >> 32), (LONG)result->value, szBuff, result->byte_size_64);
result++;
@ -510,7 +513,7 @@ static void test_StrFormatKBSizeW(void)
StrFormatKBSizeW(result->value, szBuffW, 256);
WideCharToMultiByte(0,0,szBuffW,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR),0,0);
ok(!strcmp(result->kb_size, szBuff),
"Formatted %lx%08lx wrong: got %s, expected %s\n",
"Formatted %x%08x wrong: got %s, expected %s\n",
(LONG)(result->value >> 32), (LONG)result->value, szBuff, result->kb_size);
result++;
}
@ -526,7 +529,7 @@ static void test_StrFormatKBSizeA(void)
StrFormatKBSizeA(result->value, szBuff, 256);
ok(!strcmp(result->kb_size, szBuff),
"Formatted %lx%08lx wrong: got %s, expected %s\n",
"Formatted %x%08x wrong: got %s, expected %s\n",
(LONG)(result->value >> 32), (LONG)result->value, szBuff, result->kb_size);
result++;
}
@ -541,7 +544,7 @@ static void test_StrFromTimeIntervalA(void)
{
StrFromTimeIntervalA(szBuff, 256, result->ms, result->digits);
ok(!strcmp(result->time_interval, szBuff), "Formatted %ld %d wrong\n",
ok(!strcmp(result->time_interval, szBuff), "Formatted %d %d wrong\n",
result->ms, result->digits);
result++;
}
@ -602,7 +605,7 @@ static void test_StrCmpW(void)
static WCHAR *CoDupStrW(const char* src)
{
INT len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
WCHAR* szTemp = (WCHAR*)CoTaskMemAlloc(len * sizeof(WCHAR));
WCHAR* szTemp = CoTaskMemAlloc(len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, src, -1, szTemp, len);
return szTemp;
}
@ -619,28 +622,28 @@ static void test_StrRetToBSTR(void)
if (!pStrRetToBSTR) return;
strret.uType = STRRET_WSTR;
strret.u.pOleStr = CoDupStrW("Test");
U(strret).pOleStr = CoDupStrW("Test");
bstr = 0;
ret = pStrRetToBSTR(&strret, NULL, &bstr);
ok(ret == S_OK && bstr && !strcmpW(bstr, szTestW),
"STRRET_WSTR: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr);
"STRRET_WSTR: dup failed, ret=0x%08x, bstr %p\n", ret, bstr);
if (bstr)
SysFreeString(bstr);
strret.uType = STRRET_CSTR;
lstrcpyA(strret.u.cStr, "Test");
lstrcpyA(U(strret).cStr, "Test");
ret = pStrRetToBSTR(&strret, NULL, &bstr);
ok(ret == S_OK && bstr && !strcmpW(bstr, szTestW),
"STRRET_CSTR: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr);
"STRRET_CSTR: dup failed, ret=0x%08x, bstr %p\n", ret, bstr);
if (bstr)
SysFreeString(bstr);
strret.uType = STRRET_OFFSET;
strret.u.uOffset = 1;
U(strret).uOffset = 1;
strcpy((char*)&iidl, " Test");
ret = pStrRetToBSTR(&strret, iidl, &bstr);
ok(ret == S_OK && bstr && !strcmpW(bstr, szTestW),
"STRRET_OFFSET: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr);
"STRRET_OFFSET: dup failed, ret=0x%08x, bstr %p\n", ret, bstr);
if (bstr)
SysFreeString(bstr);
@ -683,6 +686,45 @@ static void test_StrCpyNXW(void)
dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
}
#define check_strrstri(type, str, pos, needle, exp) \
ret##type = StrRStrI##type(str, str+pos, needle); \
ok(ret##type == (exp), "Type " #type ", expected %p but got %p (string base %p)\n", \
(exp), ret##type, str);
static void test_StrRStrI(void)
{
static const CHAR szTest[] = "yAxxxxAy";
static const CHAR szTest2[] = "ABABABAB";
static const WCHAR wszTest[] = {'y','A','x','x','x','x','A','y',0};
static const WCHAR wszTest2[] = {'A','B','A','B','A','B','A','B',0};
static const WCHAR wszPattern1[] = {'A',0};
static const WCHAR wszPattern2[] = {'a','X',0};
static const WCHAR wszPattern3[] = {'A','y',0};
static const WCHAR wszPattern4[] = {'a','b',0};
LPWSTR retW;
LPSTR retA;
check_strrstri(A, szTest, 4, "A", szTest+1);
check_strrstri(A, szTest, 4, "aX", szTest+1);
check_strrstri(A, szTest, 4, "Ay", NULL);
check_strrstri(W, wszTest, 4, wszPattern1, wszTest+1);
check_strrstri(W, wszTest, 4, wszPattern2, wszTest+1);
check_strrstri(W, wszTest, 4, wszPattern3, NULL);
check_strrstri(A, szTest2, 4, "ab", szTest2+2);
check_strrstri(A, szTest2, 3, "ab", szTest2+2);
check_strrstri(A, szTest2, 2, "ab", szTest2);
check_strrstri(A, szTest2, 1, "ab", szTest2);
check_strrstri(A, szTest2, 0, "ab", NULL);
check_strrstri(W, wszTest2, 4, wszPattern4, wszTest2+2);
check_strrstri(W, wszTest2, 3, wszPattern4, wszTest2+2);
check_strrstri(W, wszTest2, 2, wszPattern4, wszTest2);
check_strrstri(W, wszTest2, 1, wszPattern4, wszTest2);
check_strrstri(W, wszTest2, 0, wszPattern4, NULL);
}
static void test_SHAnsiToAnsi(void)
{
char dest[8];
@ -695,7 +737,7 @@ static void test_SHAnsiToAnsi(void)
memset(dest, '\n', sizeof(dest));
dwRet = pSHAnsiToAnsi("hello", dest, sizeof(dest)/sizeof(dest[0]));
ok(dwRet == 6 && !memcmp(dest, "hello\0\n\n", sizeof(dest)),
"SHAnsiToAnsi: expected 6, \"hello\\0\\n\\n\", got %ld, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
"SHAnsiToAnsi: expected 6, \"hello\\0\\n\\n\", got %d, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
}
@ -714,17 +756,79 @@ static void test_SHUnicodeToUnicode(void)
memcpy(dest, lpInit, sizeof(lpInit));
dwRet = pSHUnicodeToUnicode(lpSrc, dest, sizeof(dest)/sizeof(dest[0]));
ok(dwRet == 6 && !memcmp(dest, lpRes, sizeof(dest)),
"SHUnicodeToUnicode: expected 6, \"hello\\0\\n\\n\", got %ld, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
"SHUnicodeToUnicode: expected 6, \"hello\\0\\n\\n\", got %d, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
}
static void test_StrXXX_overflows(void)
{
CHAR str1[2*MAX_PATH+1], buf[2*MAX_PATH];
WCHAR wstr1[2*MAX_PATH+1], wbuf[2*MAX_PATH];
const WCHAR fmt[] = {'%','s',0};
STRRET strret;
int ret;
int i;
for (i=0; i<2*MAX_PATH; i++)
{
str1[i] = '0'+(i%10);
wstr1[i] = '0'+(i%10);
}
str1[2*MAX_PATH] = 0;
wstr1[2*MAX_PATH] = 0;
memset(buf, 0xbf, sizeof(buf));
expect_eq(StrCpyNA(buf, str1, 10), buf, PCHAR, "%p");
expect_eq(buf[9], 0, CHAR, "%x");
expect_eq(buf[10], '\xbf', CHAR, "%x");
expect_eq(StrCatBuffA(buf, str1, 100), buf, PCHAR, "%p");
expect_eq(buf[99], 0, CHAR, "%x");
expect_eq(buf[100], '\xbf', CHAR, "%x");
memset(wbuf, 0xbf, sizeof(wbuf));
expect_eq(StrCpyNW(wbuf, wstr1, 10), wbuf, PWCHAR, "%p");
expect_eq(wbuf[9], 0, WCHAR, "%x");
expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
expect_eq(StrCatBuffW(wbuf, wstr1, 100), wbuf, PWCHAR, "%p");
expect_eq(wbuf[99], 0, WCHAR, "%x");
expect_eq(wbuf[100], (WCHAR)0xbfbf, WCHAR, "%x");
memset(wbuf, 0xbf, sizeof(wbuf));
strret.uType = STRRET_WSTR;
U(strret).pOleStr = StrDupW(wstr1);
expect_eq(StrRetToBufW(&strret, NULL, wbuf, 10), S_OK, HRESULT, "%x");
expect_eq(wbuf[9], 0, WCHAR, "%x");
expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
memset(buf, 0xbf, sizeof(buf));
strret.uType = STRRET_CSTR;
StrCpyN(U(strret).cStr, str1, MAX_PATH);
expect_eq(StrRetToBufA(&strret, NULL, buf, 10), S_OK, HRESULT, "%x");
expect_eq(buf[9], 0, CHAR, "%x");
expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
memset(buf, 0xbf, sizeof(buf));
ret = wnsprintfA(buf, 10, "%s", str1);
todo_wine ok(ret == 9, "Unexpected wsnprintfA return %d, expected 9\n", ret);
expect_eq(buf[9], 0, CHAR, "%x");
expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
memset(wbuf, 0xbf, sizeof(wbuf));
ret = wnsprintfW(wbuf, 10, fmt, wstr1);
todo_wine ok(ret == 9, "Unexpected wsnprintfW return %d, expected 9\n", ret);
expect_eq(wbuf[9], 0, WCHAR, "%x");
expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
}
START_TEST(string)
{
TCHAR thousandDelim[8];
TCHAR decimalDelim[8];
CoInitialize(0);
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousandDelim, 8);
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimalDelim, 8);
hShlwapi = GetModuleHandleA("shlwapi");
if (!hShlwapi)
return;
test_StrChrA();
test_StrChrW();
@ -738,23 +842,27 @@ START_TEST(string)
test_StrToIntExA();
test_StrToIntExW();
test_StrDupA();
if (0)
if (lstrcmp(thousandDelim, ",")==0 && lstrcmp(decimalDelim, ".")==0)
{
/* this test fails on locales which do not use '.' as a decimal separator */
/* these tests are locale-dependent */
test_StrFormatByteSize64A();
/* this test fails on locales which do not use '.' as a decimal separator */
test_StrFormatKBSizeA();
/* FIXME: Awaiting NLS fixes in kernel before these succeed */
test_StrFormatKBSizeW();
}
test_StrFromTimeIntervalA();
/* language-dependent test */
if (PRIMARYLANGID(GetUserDefaultLangID()) != LANG_ENGLISH)
trace("Skipping StrFromTimeInterval test for non English language\n");
else
test_StrFromTimeIntervalA();
test_StrCmpA();
test_StrCmpW();
test_StrRetToBSTR();
test_StrCpyNXA();
test_StrCpyNXW();
test_StrRStrI();
test_SHAnsiToAnsi();
test_SHUnicodeToUnicode();
test_StrXXX_overflows();
}

View file

@ -17,10 +17,10 @@ extern void func_string(void);
const struct test winetest_testlist[] =
{
{ "clist", func_clist },
// { "clsid", func_clsid },
// { "generated", func_generated },
{ "clsid", func_clsid },
{ "generated", func_generated },
{ "ordinal", func_ordinal },
// { "path", func_path },
{ "path", func_path },
{ "shreg", func_shreg },
{ "string", func_string },
{ 0, 0 }