From eeb0d2ad7849030ce5fd0fa51df517d2a3b1bf0f Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Fri, 18 Apr 2014 22:50:27 +0000 Subject: [PATCH] [KERNEL32_WINETEST] * Sync with Wine 1.7.17. CORE-8080 svn path=/trunk/; revision=62787 --- rostests/winetests/kernel32/CMakeLists.txt | 11 +- rostests/winetests/kernel32/actctx.c | 562 +++++++++++- rostests/winetests/kernel32/alloc.c | 399 --------- rostests/winetests/kernel32/change.c | 10 +- rostests/winetests/kernel32/codepage.c | 142 +++ rostests/winetests/kernel32/comm.c | 366 +++++++- rostests/winetests/kernel32/console.c | 336 ++++--- rostests/winetests/kernel32/debugger.c | 21 +- rostests/winetests/kernel32/drive.c | 6 +- rostests/winetests/kernel32/environ.c | 2 +- rostests/winetests/kernel32/fiber.c | 31 +- rostests/winetests/kernel32/file.c | 653 ++++++++++++-- rostests/winetests/kernel32/format_msg.c | 2 +- rostests/winetests/kernel32/heap.c | 282 +++++- rostests/winetests/kernel32/loader.c | 989 ++++++++++++++++----- rostests/winetests/kernel32/locale.c | 352 ++++++-- rostests/winetests/kernel32/mailslot.c | 45 +- rostests/winetests/kernel32/module.c | 42 +- rostests/winetests/kernel32/path.c | 347 +++++++- rostests/winetests/kernel32/pipe.c | 140 ++- rostests/winetests/kernel32/process.c | 31 +- rostests/winetests/kernel32/profile.c | 68 +- rostests/winetests/kernel32/resource.c | 70 +- rostests/winetests/kernel32/sync.c | 705 ++++++++++++++- rostests/winetests/kernel32/testlist.c | 2 - rostests/winetests/kernel32/thread.c | 333 ++++++- rostests/winetests/kernel32/time.c | 2 +- rostests/winetests/kernel32/timer.c | 2 +- rostests/winetests/kernel32/toolhelp.c | 20 +- rostests/winetests/kernel32/version.c | 52 +- rostests/winetests/kernel32/virtual.c | 60 +- rostests/winetests/kernel32/volume.c | 45 +- 32 files changed, 4812 insertions(+), 1316 deletions(-) delete mode 100755 rostests/winetests/kernel32/alloc.c diff --git a/rostests/winetests/kernel32/CMakeLists.txt b/rostests/winetests/kernel32/CMakeLists.txt index 2eec89395cd..1b98b38a49d 100644 --- a/rostests/winetests/kernel32/CMakeLists.txt +++ b/rostests/winetests/kernel32/CMakeLists.txt @@ -1,12 +1,8 @@ -add_definitions( - -D__ROS_LONG64__) - remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502) list(APPEND SOURCE actctx.c - alloc.c atom.c change.c codepage.c @@ -40,12 +36,7 @@ list(APPEND SOURCE volume.c testlist.c) -add_executable(kernel32_winetest - ${SOURCE} - resource.rc) - -target_link_libraries(kernel32_winetest wine) +add_executable(kernel32_winetest ${SOURCE} resource.rc) set_module_type(kernel32_winetest win32cui) add_importlibs(kernel32_winetest user32 advapi32 msvcrt kernel32 ntdll) - add_cd_file(TARGET kernel32_winetest DESTINATION reactos/bin FOR all) diff --git a/rostests/winetests/kernel32/actctx.c b/rostests/winetests/kernel32/actctx.c index d0e8433ca60..792a292b8d2 100644 --- a/rostests/winetests/kernel32/actctx.c +++ b/rostests/winetests/kernel32/actctx.c @@ -28,8 +28,10 @@ #include static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*); +static HANDLE (WINAPI *pCreateActCtxA)(PCACTCTXA); static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW); static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR); +static BOOL (WINAPI *pFindActCtxSectionStringA)(DWORD,const GUID *,ULONG,LPCSTR,PACTCTX_SECTION_KEYED_DATA); static BOOL (WINAPI *pFindActCtxSectionStringW)(DWORD,const GUID *,ULONG,LPCWSTR,PACTCTX_SECTION_KEYED_DATA); static BOOL (WINAPI *pGetCurrentActCtx)(HANDLE *); static BOOL (WINAPI *pIsDebuggerPresent)(void); @@ -47,18 +49,6 @@ static const char* strw(LPCWSTR x) return buffer; } -static const char *debugstr_guid(REFIID riid) -{ - static char buf[50]; - - sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], - riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], - riid->Data4[5], riid->Data4[6], riid->Data4[7]); - - return buf; -} - #ifdef __i386__ #define ARCH "x86" #elif defined __x86_64__ @@ -72,6 +62,11 @@ static const char manifest1[] = "" ""; +static const char manifest1_1[] = +"" +"" +""; + static const char manifest2[] = "" "" @@ -84,11 +79,19 @@ static const char manifest2[] = "" ""; -DEFINE_GUID(IID_CoTest, 0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33); -DEFINE_GUID(IID_TlibTest, 0x99999999, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55); +DEFINE_GUID(IID_CoTest, 0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33); +DEFINE_GUID(IID_CoTest2, 0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x11, 0x11, 0x22, 0x22, 0x33, 0x34); +DEFINE_GUID(CLSID_clrclass,0x22345678, 0x1234, 0x5678, 0x12, 0x34, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33); +DEFINE_GUID(IID_TlibTest, 0x99999999, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55); DEFINE_GUID(IID_TlibTest2, 0x99999999, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56); DEFINE_GUID(IID_TlibTest3, 0x99999999, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57); DEFINE_GUID(IID_TlibTest4, 0x99999999, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x58); +DEFINE_GUID(IID_Iifaceps, 0x66666666, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55); +DEFINE_GUID(IID_Ibifaceps, 0x66666666, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57); +DEFINE_GUID(IID_Iifaceps2, 0x76666666, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55); +DEFINE_GUID(IID_Iifaceps3, 0x86666666, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55); +DEFINE_GUID(IID_Iiface, 0x96666666, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55); +DEFINE_GUID(IID_PS32, 0x66666666, 0x8888, 0x7777, 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56); static const char manifest3[] = "" @@ -106,8 +109,63 @@ static const char manifest3[] = " miscStatusContent=\"insideout\"" " miscStatusThumbnail=\"alignable\"" " miscStatusDocPrint=\"simpleframe,setclientsitefirst\"" +" >" +" ProgId.ProgId.1" +" ProgId.ProgId.2" +" ProgId.ProgId.3" +" ProgId.ProgId.4" +" ProgId.ProgId.5" +" ProgId.ProgId.6" +" " +" " +" ProgId.ProgId.7" +" " +" " "" +" " +" " +" " +" " +" clrprogid.1" +" clrprogid.2" +" clrprogid.3" +" clrprogid.4" +" clrprogid.5" +" clrprogid.6" +" " ""; static const char manifest_wndcls1[] = @@ -128,7 +186,7 @@ static const char manifest_wndcls2[] = " wndClass3" " wndClass4" " " +" flags=\"HiddeN,CoNTROL,rESTRICTED\" />" " " " " "" @@ -665,7 +723,8 @@ static HANDLE test_create(const char *file) actctx.lpSource = path; handle = pCreateActCtxW(&actctx); - ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + /* to be tested outside of this helper, including last error */ + if (handle == INVALID_HANDLE_VALUE) return handle; ok(actctx.cbSize == sizeof(actctx), "actctx.cbSize=%d\n", actctx.cbSize); ok(actctx.dwFlags == 0, "actctx.dwFlags=%d\n", actctx.dwFlags); @@ -777,7 +836,9 @@ struct strsection_header DWORD unk1[3]; ULONG count; ULONG index_offset; - DWORD unk2[4]; + DWORD unk2[2]; + ULONG global_offset; + ULONG global_len; }; struct string_index @@ -841,6 +902,13 @@ struct tlibredirect_data WORD minor_version; }; +struct progidredirect_data +{ + ULONG size; + DWORD reserved; + ULONG clsid_offset; +}; + static void test_find_dll_redirection(HANDLE handle, LPCWSTR libname, ULONG exid, int line) { ACTCTX_SECTION_KEYED_DATA data; @@ -1107,7 +1175,8 @@ struct comclassredirect_data { ULONG name_offset; ULONG progid_len; ULONG progid_offset; - DWORD res2[2]; + ULONG clrdata_len; + ULONG clrdata_offset; DWORD miscstatus; DWORD miscstatuscontent; DWORD miscstatusthumbnail; @@ -1115,10 +1184,23 @@ struct comclassredirect_data { DWORD miscstatusdocprint; }; -static void test_find_com_redirection(HANDLE handle, const GUID *clsid, const GUID *tlid, ULONG exid, int line) +struct clrclass_data { + ULONG size; + DWORD res[2]; + ULONG module_len; + ULONG module_offset; + ULONG name_len; + ULONG name_offset; + ULONG version_len; + ULONG version_offset; + DWORD res2[2]; +}; + +static void test_find_com_redirection(HANDLE handle, const GUID *clsid, const GUID *tlid, const WCHAR *progid, ULONG exid, int line) { struct comclassredirect_data *comclass, *comclass2; ACTCTX_SECTION_KEYED_DATA data, data2; + struct guidsection_header *header; BOOL ret; memset(&data, 0xfe, sizeof(data)); @@ -1127,6 +1209,11 @@ static void test_find_com_redirection(HANDLE handle, const GUID *clsid, const GU ret = pFindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, clsid, &data); + if (!ret) + { + skip("failed for guid %s\n", wine_dbgstr_guid(clsid)); + return; + } ok_(__FILE__, line)(ret, "FindActCtxSectionGuid failed: %u\n", GetLastError()); comclass = (struct comclassredirect_data*)data.lpData; @@ -1137,7 +1224,6 @@ static void test_find_com_redirection(HANDLE handle, const GUID *clsid, const GU ok_(__FILE__, line)(comclass->size == sizeof(*comclass), "got %d for header size\n", comclass->size); if (data.lpData && comclass->size == sizeof(*comclass)) { - static const WCHAR progid[] = {'P','r','o','g','I','d','.','P','r','o','g','I','d',0}; WCHAR *ptr; ULONG len; @@ -1145,19 +1231,31 @@ static void test_find_com_redirection(HANDLE handle, const GUID *clsid, const GU ok_(__FILE__, line)(comclass->res1[0] == 0, "got res1[0] as %02x\n", comclass->res1[0]); ok_(__FILE__, line)(comclass->res1[1] == 0, "got res1[1] as %02x\n", comclass->res1[1]); ok_(__FILE__, line)(comclass->model == ThreadingModel_Neutral, "got model %d\n", comclass->model); - ok_(__FILE__, line)(IsEqualGUID(&comclass->clsid, clsid), "got wrong clsid %s\n", debugstr_guid(&comclass->clsid)); - ok_(__FILE__, line)(IsEqualGUID(&comclass->clsid2, clsid), "got wrong clsid2 %s\n", debugstr_guid(&comclass->clsid2)); - ok_(__FILE__, line)(IsEqualGUID(&comclass->tlid, tlid), "got wrong tlid %s\n", debugstr_guid(&comclass->tlid)); + ok_(__FILE__, line)(IsEqualGUID(&comclass->clsid, clsid), "got wrong clsid %s\n", wine_dbgstr_guid(&comclass->clsid)); + ok_(__FILE__, line)(IsEqualGUID(&comclass->clsid2, clsid), "got wrong clsid2 %s\n", wine_dbgstr_guid(&comclass->clsid2)); + if (tlid) + ok_(__FILE__, line)(IsEqualGUID(&comclass->tlid, tlid), "got wrong tlid %s\n", wine_dbgstr_guid(&comclass->tlid)); ok_(__FILE__, line)(comclass->name_len > 0, "got modulename len %d\n", comclass->name_len); - ok_(__FILE__, line)(comclass->progid_offset == comclass->size, "got progid offset %d\n", comclass->progid_offset); - ptr = (WCHAR*)((BYTE*)comclass + comclass->size); - ok_(__FILE__, line)(!lstrcmpW(ptr, progid), "got wrong progid %s, expected %s\n", wine_dbgstr_w(ptr), wine_dbgstr_w(progid)); - ok_(__FILE__, line)(lstrlenW(ptr)*sizeof(WCHAR) == comclass->progid_len, - "got progid name length %d, expected %d\n", comclass->progid_len, lstrlenW(ptr)); + if (progid) + { + len = comclass->size + comclass->clrdata_len; + ok_(__FILE__, line)(comclass->progid_offset == len, "got progid offset %d, expected %d\n", comclass->progid_offset, len); + } + else + ok_(__FILE__, line)(comclass->progid_offset == 0, "got progid offset %d, expected 0\n", comclass->progid_offset); + + if (comclass->progid_offset) + { + ptr = (WCHAR*)((BYTE*)comclass + comclass->progid_offset); + ok_(__FILE__, line)(!lstrcmpW(ptr, progid), "got wrong progid %s, expected %s\n", wine_dbgstr_w(ptr), wine_dbgstr_w(progid)); + ok_(__FILE__, line)(lstrlenW(progid)*sizeof(WCHAR) == comclass->progid_len, + "got progid name length %d\n", comclass->progid_len); + } /* data length is simply header length + string data length including nulls */ - len = comclass->size + comclass->progid_len + sizeof(WCHAR); + len = comclass->size + comclass->clrdata_len; + if (comclass->progid_len) len += comclass->progid_len + sizeof(WCHAR); ok_(__FILE__, line)(data.ulLength == len, "got wrong data length %d, expected %d\n", data.ulLength, len); /* keyed data structure doesn't include module name, it's available from section data */ @@ -1177,12 +1275,47 @@ static void test_find_com_redirection(HANDLE handle, const GUID *clsid, const GU if (comclass->miscmask & MiscStatusDocPrint) ok_(__FILE__, line)(comclass->miscstatusdocprint != 0, "got miscstatusdocprint 0x%08x\n", comclass->miscstatusdocprint); } + + /* part used for clrClass only */ + if (comclass->clrdata_len) + { + static const WCHAR mscoreeW[] = {'M','S','C','O','R','E','E','.','D','L','L',0}; + static const WCHAR mscoree2W[] = {'m','s','c','o','r','e','e','.','d','l','l',0}; + struct clrclass_data *clrclass; + WCHAR *ptrW; + + clrclass = (struct clrclass_data*)((BYTE*)data.lpData + comclass->clrdata_offset); + ok_(__FILE__, line)(clrclass->size == sizeof(*clrclass), "clrclass: got size %d\n", clrclass->size); + ok_(__FILE__, line)(clrclass->res[0] == 0, "clrclass: got res[0]=0x%08x\n", clrclass->res[0]); + ok_(__FILE__, line)(clrclass->res[1] == 2, "clrclass: got res[1]=0x%08x\n", clrclass->res[1]); + ok_(__FILE__, line)(clrclass->module_len == lstrlenW(mscoreeW)*sizeof(WCHAR), "clrclass: got module len %d\n", clrclass->module_len); + ok_(__FILE__, line)(clrclass->module_offset > 0, "clrclass: got module offset %d\n", clrclass->module_offset); + + ok_(__FILE__, line)(clrclass->name_len > 0, "clrclass: got name len %d\n", clrclass->name_len); + ok_(__FILE__, line)(clrclass->name_offset == clrclass->size, "clrclass: got name offset %d\n", clrclass->name_offset); + ok_(__FILE__, line)(clrclass->version_len > 0, "clrclass: got version len %d\n", clrclass->version_len); + ok_(__FILE__, line)(clrclass->version_offset > 0, "clrclass: got version offset %d\n", clrclass->version_offset); + + ok_(__FILE__, line)(clrclass->res2[0] == 0, "clrclass: got res2[0]=0x%08x\n", clrclass->res2[0]); + ok_(__FILE__, line)(clrclass->res2[1] == 0, "clrclass: got res2[1]=0x%08x\n", clrclass->res2[1]); + + /* clrClass uses mscoree.dll as module name, but in two variants - comclass data points to module name + in lower case, clsclass subsection - in upper case */ + ok_(__FILE__, line)(comclass->name_len == lstrlenW(mscoree2W)*sizeof(WCHAR), "clrclass: got com name len %d\n", comclass->name_len); + ok_(__FILE__, line)(comclass->name_offset > 0, "clrclass: got name offset %d\n", clrclass->name_offset); + + ptrW = (WCHAR*)((BYTE*)data.lpSectionBase + comclass->name_offset); + ok_(__FILE__, line)(!lstrcmpW(ptrW, mscoreeW), "clrclass: module name %s\n", wine_dbgstr_w(ptrW)); + + ptrW = (WCHAR*)((BYTE*)data.lpSectionBase + clrclass->module_offset); + ok_(__FILE__, line)(!lstrcmpW(ptrW, mscoree2W), "clrclass: module name2 %s\n", wine_dbgstr_w(ptrW)); + } } -todo_wine { - ok_(__FILE__, line)(data.lpSectionGlobalData != NULL, "data.lpSectionGlobalData == NULL\n"); - ok_(__FILE__, line)(data.ulSectionGlobalDataLength > 0, "data.ulSectionGlobalDataLength=%u\n", + + header = (struct guidsection_header*)data.lpSectionBase; + ok_(__FILE__, line)(data.lpSectionGlobalData == ((BYTE*)header + header->names_offset), "data.lpSectionGlobalData == NULL\n"); + ok_(__FILE__, line)(data.ulSectionGlobalDataLength == header->names_len, "data.ulSectionGlobalDataLength=%u\n", data.ulSectionGlobalDataLength); -} ok_(__FILE__, line)(data.lpSectionBase != NULL, "data.lpSectionBase == NULL\n"); ok_(__FILE__, line)(data.ulSectionTotalLength > 0, "data.ulSectionTotalLength=%u\n", data.ulSectionTotalLength); @@ -1203,6 +1336,210 @@ todo_wine { ok_(__FILE__, line)(!memcmp(comclass, comclass2, comclass->size), "got wrong data\n"); } +enum ifaceps_mask +{ + NumMethods = 1, + BaseIface = 2 +}; + +struct ifacepsredirect_data +{ + ULONG size; + DWORD mask; + GUID iid; + ULONG nummethods; + GUID tlbid; + GUID base; + ULONG name_len; + ULONG name_offset; +}; + +static void test_find_ifaceps_redirection(HANDLE handle, const GUID *iid, const GUID *tlbid, const GUID *base, + const GUID *ps32, ULONG exid, int line) +{ + struct ifacepsredirect_data *ifaceps; + ACTCTX_SECTION_KEYED_DATA data; + BOOL ret; + + memset(&data, 0xfe, sizeof(data)); + data.cbSize = sizeof(data); + + ret = pFindActCtxSectionGuid(0, NULL, + ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION, + iid, &data); + ok_(__FILE__, line)(ret, "FindActCtxSectionGuid failed: %u\n", GetLastError()); + + ifaceps = (struct ifacepsredirect_data*)data.lpData; + + ok_(__FILE__, line)(data.cbSize == sizeof(data), "data.cbSize=%u\n", data.cbSize); + ok_(__FILE__, line)(data.ulDataFormatVersion == 1, "data.ulDataFormatVersion=%u\n", data.ulDataFormatVersion); + ok_(__FILE__, line)(data.lpData != NULL, "data.lpData == NULL\n"); + ok_(__FILE__, line)(ifaceps->size == sizeof(*ifaceps), "got %d for header size\n", ifaceps->size); + if (data.lpData && ifaceps->size == sizeof(*ifaceps)) + { + ULONG len; + + /* for external proxy stubs it contains a value from 'proxyStubClsid32' */ + if (ps32) + { + ok_(__FILE__, line)(IsEqualGUID(&ifaceps->iid, ps32), "got wrong iid %s\n", wine_dbgstr_guid(&ifaceps->iid)); + } + else + ok_(__FILE__, line)(IsEqualGUID(&ifaceps->iid, iid), "got wrong iid %s\n", wine_dbgstr_guid(&ifaceps->iid)); + + ok_(__FILE__, line)(IsEqualGUID(&ifaceps->tlbid, tlbid), "got wrong tlid %s\n", wine_dbgstr_guid(&ifaceps->tlbid)); + ok_(__FILE__, line)(ifaceps->name_len > 0, "got modulename len %d\n", ifaceps->name_len); + ok_(__FILE__, line)(ifaceps->name_offset == ifaceps->size, "got progid offset %d\n", ifaceps->name_offset); + + /* data length is simply header length + string data length including nulls */ + len = ifaceps->size + ifaceps->name_len + sizeof(WCHAR); + ok_(__FILE__, line)(data.ulLength == len, "got wrong data length %d, expected %d\n", data.ulLength, len); + + /* mask purpose is to indicate if attribute was specified, for testing purposes assume that manifest + always has non-zero value for it */ + if (ifaceps->mask & NumMethods) + ok_(__FILE__, line)(ifaceps->nummethods != 0, "got nummethods %d\n", ifaceps->nummethods); + if (ifaceps->mask & BaseIface) + ok_(__FILE__, line)(IsEqualGUID(&ifaceps->base, base), "got base %s\n", wine_dbgstr_guid(&ifaceps->base)); + } + + ok_(__FILE__, line)(data.lpSectionGlobalData == NULL, "data.lpSectionGlobalData != NULL\n"); + ok_(__FILE__, line)(data.ulSectionGlobalDataLength == 0, "data.ulSectionGlobalDataLength=%u\n", + data.ulSectionGlobalDataLength); + ok_(__FILE__, line)(data.lpSectionBase != NULL, "data.lpSectionBase == NULL\n"); + ok_(__FILE__, line)(data.ulSectionTotalLength > 0, "data.ulSectionTotalLength=%u\n", + data.ulSectionTotalLength); + ok_(__FILE__, line)(data.hActCtx == NULL, "data.hActCtx=%p\n", data.hActCtx); + ok_(__FILE__, line)(data.ulAssemblyRosterIndex == exid, "data.ulAssemblyRosterIndex=%u, expected %u\n", + data.ulAssemblyRosterIndex, exid); +} + +struct clrsurrogate_data +{ + ULONG size; + DWORD res; + GUID clsid; + ULONG version_offset; + ULONG version_len; + ULONG name_offset; + ULONG name_len; +}; + +static void test_find_surrogate(HANDLE handle, const GUID *clsid, const WCHAR *name, const WCHAR *version, + ULONG exid, int line) +{ + struct clrsurrogate_data *surrogate; + ACTCTX_SECTION_KEYED_DATA data; + BOOL ret; + + memset(&data, 0xfe, sizeof(data)); + data.cbSize = sizeof(data); + + ret = pFindActCtxSectionGuid(0, NULL, + ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES, + clsid, &data); + if (!ret) + { + skip("surrogate sections are not supported\n"); + return; + } + ok_(__FILE__, line)(ret, "FindActCtxSectionGuid failed: %u\n", GetLastError()); + + surrogate = (struct clrsurrogate_data*)data.lpData; + + ok_(__FILE__, line)(data.cbSize == sizeof(data), "data.cbSize=%u\n", data.cbSize); + ok_(__FILE__, line)(data.ulDataFormatVersion == 1, "data.ulDataFormatVersion=%u\n", data.ulDataFormatVersion); + ok_(__FILE__, line)(data.lpData != NULL, "data.lpData == NULL\n"); + ok_(__FILE__, line)(surrogate->size == sizeof(*surrogate), "got %d for header size\n", surrogate->size); + if (data.lpData && surrogate->size == sizeof(*surrogate)) + { + WCHAR *ptrW; + ULONG len; + + ok_(__FILE__, line)(surrogate->res == 0, "invalid res value %d\n", surrogate->res); + ok_(__FILE__, line)(IsEqualGUID(&surrogate->clsid, clsid), "got wrong clsid %s\n", wine_dbgstr_guid(&surrogate->clsid)); + + ok_(__FILE__, line)(surrogate->version_len == lstrlenW(version)*sizeof(WCHAR), "got version len %d\n", surrogate->version_len); + ok_(__FILE__, line)(surrogate->version_offset == surrogate->size, "got version offset %d\n", surrogate->version_offset); + + ok_(__FILE__, line)(surrogate->name_len == lstrlenW(name)*sizeof(WCHAR), "got name len %d\n", surrogate->name_len); + ok_(__FILE__, line)(surrogate->name_offset > surrogate->version_offset, "got name offset %d\n", surrogate->name_offset); + + len = surrogate->size + surrogate->name_len + surrogate->version_len + 2*sizeof(WCHAR); + ok_(__FILE__, line)(data.ulLength == len, "got wrong data length %d, expected %d\n", data.ulLength, len); + + ptrW = (WCHAR*)((BYTE*)surrogate + surrogate->name_offset); + ok(!lstrcmpW(ptrW, name), "got wrong name %s\n", wine_dbgstr_w(ptrW)); + + ptrW = (WCHAR*)((BYTE*)surrogate + surrogate->version_offset); + ok(!lstrcmpW(ptrW, version), "got wrong name %s\n", wine_dbgstr_w(ptrW)); + } + + ok_(__FILE__, line)(data.lpSectionGlobalData == NULL, "data.lpSectionGlobalData != NULL\n"); + ok_(__FILE__, line)(data.ulSectionGlobalDataLength == 0, "data.ulSectionGlobalDataLength=%u\n", + data.ulSectionGlobalDataLength); + ok_(__FILE__, line)(data.lpSectionBase != NULL, "data.lpSectionBase == NULL\n"); + ok_(__FILE__, line)(data.ulSectionTotalLength > 0, "data.ulSectionTotalLength=%u\n", + data.ulSectionTotalLength); + ok_(__FILE__, line)(data.hActCtx == NULL, "data.hActCtx=%p\n", data.hActCtx); + ok_(__FILE__, line)(data.ulAssemblyRosterIndex == exid, "data.ulAssemblyRosterIndex=%u, expected %u\n", + data.ulAssemblyRosterIndex, exid); +} + +static void test_find_progid_redirection(HANDLE handle, const GUID *clsid, const char *progid, ULONG exid, int line) +{ + struct progidredirect_data *progiddata; + struct comclassredirect_data *comclass; + ACTCTX_SECTION_KEYED_DATA data, data2; + struct strsection_header *header; + BOOL ret; + + memset(&data, 0xfe, sizeof(data)); + data.cbSize = sizeof(data); + + ret = pFindActCtxSectionStringA(0, NULL, + ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION, + progid, &data); + ok_(__FILE__, line)(ret, "FindActCtxSectionStringA failed: %u\n", GetLastError()); + + progiddata = (struct progidredirect_data*)data.lpData; + + ok_(__FILE__, line)(data.cbSize == sizeof(data), "data.cbSize=%u\n", data.cbSize); + ok_(__FILE__, line)(data.ulDataFormatVersion == 1, "data.ulDataFormatVersion=%u\n", data.ulDataFormatVersion); + ok_(__FILE__, line)(data.lpData != NULL, "data.lpData == NULL\n"); + ok_(__FILE__, line)(progiddata->size == sizeof(*progiddata), "got %d for header size\n", progiddata->size); + if (data.lpData && progiddata->size == sizeof(*progiddata)) + { + GUID *guid; + + ok_(__FILE__, line)(progiddata->reserved == 0, "got reserved as %d\n", progiddata->reserved); + ok_(__FILE__, line)(progiddata->clsid_offset > 0, "got clsid_offset as %d\n", progiddata->clsid_offset); + + /* progid data points to generated alias guid */ + guid = (GUID*)((BYTE*)data.lpSectionBase + progiddata->clsid_offset); + + memset(&data2, 0, sizeof(data2)); + data2.cbSize = sizeof(data2); + ret = pFindActCtxSectionGuid(0, NULL, + ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, + guid, &data2); + ok_(__FILE__, line)(ret, "FindActCtxSectionGuid failed: %u\n", GetLastError()); + + comclass = (struct comclassredirect_data*)data2.lpData; + ok_(__FILE__, line)(IsEqualGUID(guid, &comclass->alias), "got wrong alias referenced from progid %s, %s\n", progid, wine_dbgstr_guid(guid)); + ok_(__FILE__, line)(IsEqualGUID(clsid, &comclass->clsid), "got wrong class referenced from progid %s, %s\n", progid, wine_dbgstr_guid(clsid)); + } + + header = (struct strsection_header*)data.lpSectionBase; + ok_(__FILE__, line)(data.lpSectionGlobalData == (BYTE*)header + header->global_offset, "data.lpSectionGlobalData == NULL\n"); + ok_(__FILE__, line)(data.ulSectionGlobalDataLength == header->global_len, "data.ulSectionGlobalDataLength=%u\n", data.ulSectionGlobalDataLength); + ok_(__FILE__, line)(data.lpSectionBase != NULL, "data.lpSectionBase == NULL\n"); + ok_(__FILE__, line)(data.ulSectionTotalLength > 0, "data.ulSectionTotalLength=%u\n", data.ulSectionTotalLength); + ok_(__FILE__, line)(data.hActCtx == NULL, "data.hActCtx=%p\n", data.hActCtx); + ok_(__FILE__, line)(data.ulAssemblyRosterIndex == exid, "data.ulAssemblyRosterIndex=%u, expected %u\n", + data.ulAssemblyRosterIndex, exid); +} + static void test_wndclass_section(void) { static const WCHAR cls1W[] = {'1','.','2','.','3','.','4','!','w','n','d','C','l','a','s','s','1',0}; @@ -1220,6 +1557,8 @@ static void test_wndclass_section(void) create_manifest_file("main_wndcls.manifest", manifest_wndcls_main, -1, NULL, NULL); handle = test_create("main_wndcls.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("testdep1.manifest"); DeleteFileA("testdep2.manifest"); DeleteFileA("main_wndcls.manifest"); @@ -1282,6 +1621,8 @@ static void test_dllredirect_section(void) create_manifest_file("main_wndcls.manifest", manifest_wndcls_main, -1, NULL, NULL); handle = test_create("main_wndcls.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("testdep1.manifest"); DeleteFileA("testdep2.manifest"); DeleteFileA("main_wndcls.manifest"); @@ -1335,6 +1676,8 @@ static void test_typelib_section(void) create_manifest_file("main_wndcls.manifest", manifest_wndcls_main, -1, NULL, NULL); handle = test_create("main_wndcls.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("testdep1.manifest"); DeleteFileA("testdep2.manifest"); DeleteFileA("main_wndcls.manifest"); @@ -1367,6 +1710,10 @@ static void test_typelib_section(void) ok(data.ulSectionTotalLength == data2.ulSectionTotalLength, "got %u, %u\n", data.ulSectionTotalLength, data2.ulSectionTotalLength); + ok(data.lpSectionGlobalData == ((BYTE*)section + section->names_offset), "data.lpSectionGlobalData == NULL\n"); + ok(data.ulSectionGlobalDataLength == section->names_len, "data.ulSectionGlobalDataLength=%u\n", + data.ulSectionGlobalDataLength); + /* test some actual data */ tlib = (struct tlibredirect_data*)data.lpData; ok(tlib->size == sizeof(*tlib), "got %d\n", tlib->size); @@ -1401,6 +1748,13 @@ static void test_actctx(void) pReleaseActCtx(handle); } + /* test for whitespace handling in Eq ::= S? '=' S? */ + create_manifest_file("test1_1.manifest", manifest1_1, -1, NULL, NULL); + handle = test_create("test1_1.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("test1_1.manifest"); + pReleaseActCtx(handle); + if(!create_manifest_file("test1.manifest", manifest1, -1, NULL, NULL)) { skip("Could not create manifest file\n"); return; @@ -1409,6 +1763,7 @@ static void test_actctx(void) trace("manifest1\n"); handle = test_create("test1.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); DeleteFileA("test1.manifest"); if(handle != INVALID_HANDLE_VALUE) { test_basic_info(handle, __LINE__); @@ -1434,6 +1789,7 @@ static void test_actctx(void) trace("manifest2 depmanifest1\n"); handle = test_create("test2.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); DeleteFileA("test2.manifest"); DeleteFileA("testdep.manifest"); if(handle != INVALID_HANDLE_VALUE) { @@ -1452,6 +1808,7 @@ static void test_actctx(void) trace("manifest2 depmanifest2\n"); handle = test_create("test2-2.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); DeleteFileA("test2-2.manifest"); DeleteFileA("testdep.manifest"); if(handle != INVALID_HANDLE_VALUE) { @@ -1480,6 +1837,7 @@ static void test_actctx(void) } handle = test_create("test2-3.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); DeleteFileA("test2-3.manifest"); DeleteFileA("testdep.manifest"); if(handle != INVALID_HANDLE_VALUE) { @@ -1510,8 +1868,17 @@ static void test_actctx(void) } handle = test_create("test3.manifest"); + ok(handle != INVALID_HANDLE_VALUE || broken(handle == INVALID_HANDLE_VALUE) /* XP pre-SP2, win2k3 w/o SP */, + "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + if (handle == INVALID_HANDLE_VALUE) + win_skip("Some activation context features not supported, skipping a test (possibly old XP/Win2k3 system\n"); DeleteFileA("test3.manifest"); if(handle != INVALID_HANDLE_VALUE) { + static const WCHAR nameW[] = {'t','e','s','t','s','u','r','r','o','g','a','t','e',0}; + static const WCHAR versionW[] = {'v','2','.','0','.','5','0','7','2','7',0}; + static const WCHAR progidW[] = {'P','r','o','g','I','d','.','P','r','o','g','I','d',0}; + static const WCHAR clrprogidW[] = {'c','l','r','p','r','o','g','i','d',0}; + test_basic_info(handle, __LINE__); test_detailed_info(handle, &detailed_info1, __LINE__); test_info_in_assembly(handle, 1, &manifest3_info, __LINE__); @@ -1521,11 +1888,31 @@ static void test_actctx(void) ok(b, "ActivateActCtx failed: %u\n", GetLastError()); test_find_dll_redirection(handle, testlib_dll, 1, __LINE__); test_find_dll_redirection(handle, testlib_dll, 1, __LINE__); - test_find_com_redirection(handle, &IID_CoTest, &IID_TlibTest, 1, __LINE__); + test_find_com_redirection(handle, &IID_CoTest, &IID_TlibTest, progidW, 1, __LINE__); + test_find_com_redirection(handle, &IID_CoTest2, NULL, NULL, 1, __LINE__); + test_find_com_redirection(handle, &CLSID_clrclass, &IID_TlibTest, clrprogidW, 1, __LINE__); + test_find_progid_redirection(handle, &IID_CoTest, "ProgId.ProgId", 1, __LINE__); + test_find_progid_redirection(handle, &IID_CoTest, "ProgId.ProgId.1", 1, __LINE__); + test_find_progid_redirection(handle, &IID_CoTest, "ProgId.ProgId.2", 1, __LINE__); + test_find_progid_redirection(handle, &IID_CoTest, "ProgId.ProgId.3", 1, __LINE__); + test_find_progid_redirection(handle, &IID_CoTest, "ProgId.ProgId.4", 1, __LINE__); + test_find_progid_redirection(handle, &IID_CoTest, "ProgId.ProgId.5", 1, __LINE__); + test_find_progid_redirection(handle, &IID_CoTest, "ProgId.ProgId.6", 1, __LINE__); + test_find_progid_redirection(handle, &CLSID_clrclass, "clrprogid", 1, __LINE__); + test_find_progid_redirection(handle, &CLSID_clrclass, "clrprogid.1", 1, __LINE__); + test_find_progid_redirection(handle, &CLSID_clrclass, "clrprogid.2", 1, __LINE__); + test_find_progid_redirection(handle, &CLSID_clrclass, "clrprogid.3", 1, __LINE__); + test_find_progid_redirection(handle, &CLSID_clrclass, "clrprogid.4", 1, __LINE__); + test_find_progid_redirection(handle, &CLSID_clrclass, "clrprogid.5", 1, __LINE__); + test_find_progid_redirection(handle, &CLSID_clrclass, "clrprogid.6", 1, __LINE__); + test_find_surrogate(handle, &IID_Iiface, nameW, versionW, 1, __LINE__); + test_find_ifaceps_redirection(handle, &IID_Iifaceps, &IID_TlibTest4, &IID_Ibifaceps, NULL, 1, __LINE__); + test_find_ifaceps_redirection(handle, &IID_Iifaceps2, &IID_TlibTest4, &IID_Ibifaceps, &IID_PS32, 1, __LINE__); + test_find_ifaceps_redirection(handle, &IID_Iifaceps3, &IID_TlibTest4, &IID_Ibifaceps, NULL, 1, __LINE__); test_find_string_fail(); + b = pDeactivateActCtx(0, cookie); ok(b, "DeactivateActCtx failed: %u\n", GetLastError()); - pReleaseActCtx(handle); } @@ -1537,6 +1924,7 @@ static void test_actctx(void) } handle = test_create("test4.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); DeleteFileA("test4.manifest"); DeleteFileA("testdep.manifest"); if(handle != INVALID_HANDLE_VALUE) { @@ -1557,6 +1945,7 @@ static void test_actctx(void) return; } handle = test_create("..\\test1.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); DeleteFileA("..\\test1.manifest"); if(handle != INVALID_HANDLE_VALUE) { test_basic_info(handle, __LINE__); @@ -1577,6 +1966,7 @@ static void test_actctx(void) } handle = test_create("test1.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); DeleteFileA("test1.manifest"); if (handle != INVALID_HANDLE_VALUE) { test_basic_info(handle, __LINE__); @@ -1592,6 +1982,7 @@ static void test_actctx(void) } handle = test_create("test1.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); DeleteFileA("test1.manifest"); if (handle != INVALID_HANDLE_VALUE) { test_basic_info(handle, __LINE__); @@ -1629,7 +2020,7 @@ static void run_child_process(void) char path[MAX_PATH]; char **argv; PROCESS_INFORMATION pi; - STARTUPINFO si = { 0 }; + STARTUPINFOA si = { 0 }; HANDLE file; FILETIME now; BOOL ret; @@ -1653,7 +2044,7 @@ static void run_child_process(void) CloseHandle(file); } sprintf(cmdline, "\"%s\" %s manifest1", argv[0], argv[1]); - ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "Could not create process: %u\n", GetLastError()); winetest_wait_child_process( pi.hProcess ); CloseHandle(pi.hThread); @@ -1686,14 +2077,108 @@ static void init_paths(void) lstrcpyW(app_manifest_path+lstrlenW(app_manifest_path), dot_manifest); } +static void write_manifest(const char *filename, const char *manifest) +{ + HANDLE file; + DWORD size; + CHAR path[MAX_PATH]; + + GetTempPathA(sizeof(path)/sizeof(CHAR), path); + strcat(path, filename); + + file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError()); + WriteFile(file, manifest, strlen(manifest), &size, NULL); + CloseHandle(file); +} + +static void delete_manifest_file(const char *filename) +{ + CHAR path[MAX_PATH]; + + GetTempPathA(sizeof(path)/sizeof(CHAR), path); + strcat(path, filename); + DeleteFileA(path); +} + +static void test_CreateActCtx(void) +{ + CHAR path[MAX_PATH], dir[MAX_PATH]; + ACTCTXA actctx; + HANDLE handle; + + GetTempPathA(sizeof(path)/sizeof(CHAR), path); + strcat(path, "main_wndcls.manifest"); + + write_manifest("testdep1.manifest", manifest_wndcls1); + write_manifest("testdep2.manifest", manifest_wndcls2); + write_manifest("main_wndcls.manifest", manifest_wndcls_main); + + memset(&actctx, 0, sizeof(ACTCTXA)); + actctx.cbSize = sizeof(ACTCTXA); + actctx.lpSource = path; + + /* create using lpSource without specified directory */ + handle = pCreateActCtxA(&actctx); + ok(handle != INVALID_HANDLE_VALUE, "failed to generate context, error %u\n", GetLastError()); + pReleaseActCtx(handle); + + /* with specified directory, that doesn't contain dependent assembly */ + GetWindowsDirectoryA(dir, sizeof(dir)/sizeof(CHAR)); + + memset(&actctx, 0, sizeof(ACTCTXA)); + actctx.cbSize = sizeof(ACTCTXA); + actctx.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID; + actctx.lpAssemblyDirectory = dir; + actctx.lpSource = path; + + SetLastError(0xdeadbeef); + handle = pCreateActCtxA(&actctx); +todo_wine { + ok(handle == INVALID_HANDLE_VALUE, "got handle %p\n", handle); + ok(GetLastError() == ERROR_SXS_CANT_GEN_ACTCTX, "got error %d\n", GetLastError()); +} + if (handle != INVALID_HANDLE_VALUE) pReleaseActCtx(handle); + + delete_manifest_file("main_wndcls.manifest"); + delete_manifest_file("testdep1.manifest"); + delete_manifest_file("testdep2.manifest"); + + /* ACTCTX_FLAG_HMODULE_VALID but hModule is not set */ + memset(&actctx, 0, sizeof(ACTCTXA)); + actctx.cbSize = sizeof(ACTCTXA); + actctx.dwFlags = ACTCTX_FLAG_HMODULE_VALID; + SetLastError(0xdeadbeef); + handle = pCreateActCtxA(&actctx); + ok(handle == INVALID_HANDLE_VALUE, "got handle %p\n", handle); +todo_wine + ok(GetLastError() == ERROR_SXS_CANT_GEN_ACTCTX || broken(GetLastError() == ERROR_NOT_ENOUGH_MEMORY) /* XP, win2k3 */, + "got error %d\n", GetLastError()); + + /* create from HMODULE - resource doesn't exist, lpSource is set */ + memset(&actctx, 0, sizeof(ACTCTXA)); + actctx.cbSize = sizeof(ACTCTXA); + actctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID; + actctx.lpSource = "dummyfile.dll"; + actctx.lpResourceName = MAKEINTRESOURCEA(20); + actctx.hModule = GetModuleHandleA(NULL); + + SetLastError(0xdeadbeef); + handle = pCreateActCtxA(&actctx); + ok(handle == INVALID_HANDLE_VALUE, "got handle %p\n", handle); + ok(GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND, "got error %d\n", GetLastError()); +} + static BOOL init_funcs(void) { - HMODULE hKernel32 = GetModuleHandle("kernel32"); + HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); #define X(f) if (!(p##f = (void*)GetProcAddress(hKernel32, #f))) return FALSE; X(ActivateActCtx); + X(CreateActCtxA); X(CreateActCtxW); X(DeactivateActCtx); + X(FindActCtxSectionStringA); X(FindActCtxSectionStringW); X(GetCurrentActCtx); X(IsDebuggerPresent); @@ -1725,5 +2210,6 @@ START_TEST(actctx) } test_actctx(); + test_CreateActCtx(); run_child_process(); } diff --git a/rostests/winetests/kernel32/alloc.c b/rostests/winetests/kernel32/alloc.c deleted file mode 100755 index c1b2afc734d..00000000000 --- a/rostests/winetests/kernel32/alloc.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Unit test suite for memory allocation functions. - * - * Copyright 2002 Geoffrey Hausheer - * - * 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 - */ - -#include - -#include "wine/test.h" -#include "windef.h" -#include "winbase.h" -#include "winerror.h" - - - /* The following functions don't have tests, because either I don't know how - to test them, or they are WinNT only, or require multiple threads. - Since the last two issues shouldn't really stop the tests from being - written, assume for now that it is all due to the first case - HeapCompact - HeapLock - HeapQueryInformation - HeapSetInformation - HeapUnlock - HeapValidate - HeapWalk -*/ -/* In addition, these features aren't being tested - HEAP_NO_SERIALIZE - HEAP_GENERATE_EXCEPTIONS - STATUS_ACCESS_VIOLATION (error code from HeapAlloc) -*/ - -static void test_Heap(void) -{ - SYSTEM_INFO sysInfo; - ULONG memchunk; - HANDLE heap; - LPVOID mem1,mem1a,mem3; - UCHAR *mem2,*mem2a; - UINT error,i; - DWORD dwSize; - -/* Retrieve the page size for this system */ - sysInfo.dwPageSize=0; - GetSystemInfo(&sysInfo); - ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n"); - -/* Create a Heap with a minimum and maximum size */ -/* Note that Windows and Wine seem to behave a bit differently with respect - to memory allocation. In Windows, you can't access all the memory - specified in the heap (due to overhead), so choosing a reasonable maximum - size for the heap was done mostly by trial-and-error on Win2k. It may need - more tweaking for otherWindows variants. -*/ - memchunk=10*sysInfo.dwPageSize; - heap=HeapCreate(0,2*memchunk,5*memchunk); - -/* Check that HeapCreate allocated the right amount of ram */ - mem1=HeapAlloc(heap,0,5*memchunk+1); - ok(mem1==NULL,"HeapCreate allocated more Ram than it should have\n"); - HeapFree(heap,0,mem1); - -/* Check that a normal alloc works */ - mem1=HeapAlloc(heap,0,memchunk); - ok(mem1!=NULL,"HeapAlloc failed\n"); - if(mem1) { - ok(HeapSize(heap,0,mem1)>=memchunk, "HeapAlloc should return a big enough memory block\n"); - } - -/* Check that a 'zeroing' alloc works */ - mem2=HeapAlloc(heap,HEAP_ZERO_MEMORY,memchunk); - ok(mem2!=NULL,"HeapAlloc failed\n"); - if(mem2) { - ok(HeapSize(heap,0,mem2)>=memchunk,"HeapAlloc should return a big enough memory block\n"); - error=0; - for(i=0;i=memchunk+5*sysInfo.dwPageSize,"HeapReAlloc failed\n"); - error=0; - for(i=0;i<5*sysInfo.dwPageSize;i++) { - if(mem2a[memchunk+i]!=0) { - error=1; - } - } - ok(!error,"HeapReAlloc should have zeroed out it's allocated memory\n"); - } - -/* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */ - error=0; - mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize); - if(mem1a!=NULL) { - if(mem1a!=mem1) { - error=1; - } - } - ok(mem1a==NULL || error==0,"HeapReAlloc didn't honour HEAP_REALLOC_IN_PLACE_ONLY\n"); - -/* Check that HeapFree works correctly */ - if(mem1a) { - ok(HeapFree(heap,0,mem1a),"HeapFree failed\n"); - } else { - ok(HeapFree(heap,0,mem1),"HeapFree failed\n"); - } - if(mem2a) { - ok(HeapFree(heap,0,mem2a),"HeapFree failed\n"); - } else { - ok(HeapFree(heap,0,mem2),"HeapFree failed\n"); - } - - /* 0-length buffer */ - mem1 = HeapAlloc(heap, 0, 0); - ok(mem1 != NULL, "Reserved memory\n"); - - dwSize = HeapSize(heap, 0, mem1); - /* should work with 0-length buffer */ - ok(dwSize < 0xFFFFFFFF, "The size of the 0-length buffer\n"); - ok(HeapFree(heap, 0, mem1), "Freed the 0-length buffer\n"); - -/* Check that HeapDestry works */ - ok(HeapDestroy(heap),"HeapDestroy failed\n"); -} - -/* The following functions don't have tests, because either I don't know how - to test them, or they are WinNT only, or require multiple threads. - Since the last two issues shouldn't really stop the tests from being - written, assume for now that it is all due to the first case - GlobalFlags - GlobalMemoryStatus - GlobalMemoryStatusEx -*/ -/* In addition, these features aren't being tested - GMEM_DISCARDABLE - GMEM_NOCOMPACT -*/ -static void test_Global(void) -{ - ULONG memchunk; - HGLOBAL mem1,mem2,mem2a,mem2b; - UCHAR *mem2ptr; - UINT error,i; - memchunk=100000; - - SetLastError(NO_ERROR); -/* Check that a normal alloc works */ - mem1=GlobalAlloc(0,memchunk); - ok(mem1!=NULL,"GlobalAlloc failed\n"); - if(mem1) { - ok(GlobalSize(mem1)>=memchunk, "GlobalAlloc should return a big enough memory block\n"); - } - -/* Check that a 'zeroing' alloc works */ - mem2=GlobalAlloc(GMEM_ZEROINIT,memchunk); - ok(mem2!=NULL,"GlobalAlloc failed: error=%d\n",GetLastError()); - if(mem2) { - ok(GlobalSize(mem2)>=memchunk,"GlobalAlloc should return a big enough memory block\n"); - mem2ptr=GlobalLock(mem2); - ok(mem2ptr==mem2,"GlobalLock should have returned the same memory as was allocated\n"); - if(mem2ptr) { - error=0; - for(i=0;i=2*memchunk,"GlobalReAlloc failed\n"); - mem2ptr=GlobalLock(mem2a); - ok(mem2ptr!=NULL,"GlobalLock Failed\n"); - if(mem2ptr) { - error=0; - for(i=0;i=memchunk, "LocalAlloc should return a big enough memory block\n"); - } - -/* Check that a 'zeroing' and lock alloc works */ - mem2=LocalAlloc(LMEM_ZEROINIT|LMEM_MOVEABLE,memchunk); - ok(mem2!=NULL,"LocalAlloc failed: error=%d\n",GetLastError()); - if(mem2) { - ok(LocalSize(mem2)>=memchunk,"LocalAlloc should return a big enough memory block\n"); - mem2ptr=LocalLock(mem2); - ok(mem2ptr!=NULL,"LocalLock: error=%d\n",GetLastError()); - if(mem2ptr) { - error=0; - for(i=0;i=2*memchunk,"LocalReAlloc failed\n"); - mem2ptr=LocalLock(mem2a); - ok(mem2ptr!=NULL,"LocalLock Failed\n"); - if(mem2ptr) { - error=0; - for(i=0;i0,"GetSystemInfo should return a valid page size\n"); - -/* Choose a reasonable allocation size */ - memchunk=10*sysInfo.dwPageSize; - -/* Check that a normal alloc works */ - mem1=VirtualAlloc(NULL,memchunk,MEM_COMMIT,PAGE_READWRITE); - ok(mem1!=NULL,"VirtualAlloc failed\n"); - if(mem1) { -/* check that memory is initialized to 0 */ - error=0; - for(i=0;i +#include "ntstatus.h" +#define WIN32_NO_STATUS #include "wine/test.h" +#include "winternl.h" #include "winbase.h" #include "winnls.h" @@ -48,6 +51,16 @@ static BOOL loopback_dtr_dsr = LOOPBACK_DTR_DSR; static BOOL loopback_dtr_ring = LOOPBACK_DTR_RING; static BOOL loopback_dtr_dcd = LOOPBACK_DTR_DCD; +static NTSTATUS (WINAPI *pNtReadFile)(HANDLE hFile, HANDLE hEvent, + PIO_APC_ROUTINE apc, void* apc_user, + PIO_STATUS_BLOCK io_status, void* buffer, ULONG length, + PLARGE_INTEGER offset, PULONG key); +static NTSTATUS (WINAPI *pNtWriteFile)(HANDLE hFile, HANDLE hEvent, + PIO_APC_ROUTINE apc, void* apc_user, + PIO_STATUS_BLOCK io_status, + const void* buffer, ULONG length, + PLARGE_INTEGER offset, PULONG key); + typedef struct { char string[100]; @@ -633,7 +646,7 @@ static void test_BuildCommDCB(void) COMMCONFIG commconfig; DWORD size = sizeof(COMMCONFIG); - if(GetDefaultCommConfig(port_name, &commconfig, &size)) + if(GetDefaultCommConfigA(port_name, &commconfig, &size)) { port = port_name[3]; break; @@ -684,7 +697,7 @@ static HANDLE test_OpenComm(BOOL doOverlap) /* Try to find a port */ for(port_name[3] = '1'; port_name[3] <= '9'; port_name[3]++) { - hcom = CreateFile( port_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + hcom = CreateFileA( port_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, (doOverlap)?FILE_FLAG_OVERLAPPED:0, NULL ); if (hcom != INVALID_HANDLE_VALUE) break; @@ -780,10 +793,11 @@ static void test_waittxempty(void) DCB dcb; COMMTIMEOUTS timeouts; char tbuf[]="test_waittxempty"; - DWORD before, after, bytes, timediff, evtmask; + DWORD before, after, bytes, timediff, evtmask, errors, i; BOOL res; DWORD baud = SLOWBAUD; - OVERLAPPED ovl_write, ovl_wait; + OVERLAPPED ovl_write, ovl_wait, ovl_wait2; + COMSTAT stat; hcom = test_OpenComm(TRUE); if (hcom == INVALID_HANDLE_VALUE) return; @@ -816,57 +830,62 @@ static void test_waittxempty(void) SetLastError(0xdeadbeef); res = WriteFile(hcom, tbuf, sizeof(tbuf), &bytes, NULL); -todo_wine ok(!res, "WriteFile on an overlapped handle without ovl structure should fail\n"); -todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); S(U(ovl_write)).Offset = 0; S(U(ovl_write)).OffsetHigh = 0; - ovl_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + ovl_write.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); before = GetTickCount(); SetLastError(0xdeadbeef); res = WriteFile(hcom, tbuf, sizeof(tbuf), &bytes, &ovl_write); after = GetTickCount(); -todo_wine - ok(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %d, error %d\n", res, GetLastError()); -todo_wine - ok(!bytes, "expected 0, got %u\n", bytes); + ok((!res && GetLastError() == ERROR_IO_PENDING) || (res && bytes == sizeof(tbuf)), + "WriteFile returned %d, written %u bytes, error %d\n", res, bytes, GetLastError()); + if (!res) ok(!bytes, "expected 0, got %u\n", bytes); ok(after - before < 30, "WriteFile took %d ms to write %d Bytes at %d Baud\n", after - before, bytes, baud); /* don't wait for WriteFile completion */ S(U(ovl_wait)).Offset = 0; S(U(ovl_wait)).OffsetHigh = 0; - ovl_wait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + ovl_wait.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); evtmask = 0; before = GetTickCount(); SetLastError(0xdeadbeef); res = WaitCommEvent(hcom, &evtmask, &ovl_wait); ok(!res && GetLastError() == ERROR_IO_PENDING, "WaitCommEvent error %d\n", GetLastError()); - res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT); -todo_wine + after = GetTickCount(); + ok(after - before < 30, "WaitCommEvent should have returned immediately, took %d ms\n", after - before); + res = WaitForSingleObject(ovl_wait.hEvent, 1500); ok(res == WAIT_OBJECT_0, "WaitCommEvent failed with a timeout\n"); if (res == WAIT_OBJECT_0) { res = GetOverlappedResult(hcom, &ovl_wait, &bytes, FALSE); ok(res, "GetOverlappedResult reported error %d\n", GetLastError()); -todo_wine ok(bytes == sizeof(evtmask), "expected %u, written %u\n", (UINT)sizeof(evtmask), bytes); res = TRUE; } - else res = FALSE; + else + { + /* unblock pending wait */ + trace("recovering after WAIT_TIMEOUT...\n"); + res = SetCommMask(hcom, EV_TXEMPTY); + ok(res, "SetCommMask error %d\n", GetLastError()); + + res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT); + ok(res == WAIT_OBJECT_0, "WaitCommEvent failed with a timeout\n"); + + res = FALSE; + } after = GetTickCount(); -todo_wine ok(res, "WaitCommEvent error %d\n", GetLastError()); -todo_wine ok(evtmask & EV_TXEMPTY, "WaitCommEvent: expected EV_TXEMPTY, got %#x\n", evtmask); CloseHandle(ovl_wait.hEvent); timediff = after - before; - trace("WaitCommEvent for EV_TXEMPTY took %d ms (timeout %d)\n", timediff, TIMEOUT); -todo_wine - ok(timediff < 900, "WaitCommEvent used %d ms for waiting\n", timediff); + trace("WaitCommEvent for EV_TXEMPTY took %d ms (timeout 1500)\n", timediff); + ok(timediff < 1200, "WaitCommEvent used %d ms for waiting\n", timediff); res = WaitForSingleObject(ovl_write.hEvent, 0); ok(res == WAIT_OBJECT_0, "WriteFile failed with a timeout\n"); @@ -876,6 +895,92 @@ todo_wine CloseHandle(ovl_write.hEvent); CloseHandle(hcom); + + for (i = 0; i < 2; i++) + { + hcom = test_OpenComm(TRUE); + if (hcom == INVALID_HANDLE_VALUE) return; + + res = SetCommMask(hcom, EV_TXEMPTY); + ok(res, "SetCommMask error %d\n", GetLastError()); + + if (i == 0) + { + S(U(ovl_write)).Offset = 0; + S(U(ovl_write)).OffsetHigh = 0; + ovl_write.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + before = GetTickCount(); + SetLastError(0xdeadbeef); + res = WriteFile(hcom, tbuf, sizeof(tbuf), &bytes, &ovl_write); + ok((!res && GetLastError() == ERROR_IO_PENDING) || (res && bytes == sizeof(tbuf)), + "WriteFile returned %d, written %u bytes, error %d\n", res, bytes, GetLastError()); + if (!res) ok(!bytes, "expected 0, got %u\n", bytes); + + ClearCommError(hcom, &errors, &stat); + ok(stat.cbInQue == 0, "InQueue should be empty, got %d bytes\n", stat.cbInQue); + ok(stat.cbOutQue != 0 || broken(stat.cbOutQue == 0) /* VM */, "OutQueue should not be empty\n"); + ok(errors == 0, "ClearCommErrors: Unexpected error 0x%08x\n", errors); + + res = GetOverlappedResult(hcom, &ovl_write, &bytes, TRUE); + ok(res, "GetOverlappedResult reported error %d\n", GetLastError()); + ok(bytes == sizeof(tbuf), "expected %u, written %u\n", (UINT)sizeof(tbuf), bytes); + CloseHandle(ovl_write.hEvent); + + res = FlushFileBuffers(hcom); + ok(res, "FlushFileBuffers error %d\n", GetLastError()); + } + + ClearCommError(hcom, &errors, &stat); + ok(stat.cbInQue == 0, "InQueue should be empty, got %d bytes\n", stat.cbInQue); + ok(stat.cbOutQue == 0, "OutQueue should be empty, got %d bytes\n", stat.cbOutQue); + ok(errors == 0, "ClearCommErrors: Unexpected error 0x%08x\n", errors); + + S(U(ovl_wait)).Offset = 0; + S(U(ovl_wait)).OffsetHigh = 0; + ovl_wait.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + evtmask = 0; + SetLastError(0xdeadbeef); + res = WaitCommEvent(hcom, &evtmask, &ovl_wait); + ok((!res && GetLastError() == ERROR_IO_PENDING) || res /* busy system */, "%d: WaitCommEvent error %d\n", i, GetLastError()); + + res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT); + if (i == 0) + ok(res == WAIT_OBJECT_0, "WaitCommEvent failed with a timeout\n"); + else + ok(res == WAIT_TIMEOUT, "WaitCommEvent should fail with a timeout\n"); + if (res == WAIT_OBJECT_0) + { + res = GetOverlappedResult(hcom, &ovl_wait, &bytes, FALSE); + ok(res, "GetOverlappedResult reported error %d\n", GetLastError()); + ok(bytes == sizeof(evtmask), "expected %u, written %u\n", (UINT)sizeof(evtmask), bytes); + ok(res, "WaitCommEvent error %d\n", GetLastError()); + ok(evtmask & EV_TXEMPTY, "WaitCommEvent: expected EV_TXEMPTY, got %#x\n", evtmask); + } + else + { + ok(!evtmask, "WaitCommEvent: expected 0, got %#x\n", evtmask); + + S(U(ovl_wait2)).Offset = 0; + S(U(ovl_wait2)).OffsetHigh = 0; + ovl_wait2.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + SetLastError(0xdeadbeef); + res = WaitCommEvent(hcom, &evtmask, &ovl_wait2); + ok(!res, "WaitCommEvent should fail if there is a pending wait\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + CloseHandle(ovl_wait2.hEvent); + + /* unblock pending wait */ + trace("recovering after WAIT_TIMEOUT...\n"); + res = SetCommMask(hcom, EV_TXEMPTY); + ok(res, "SetCommMask error %d\n", GetLastError()); + + res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT); + ok(res == WAIT_OBJECT_0, "WaitCommEvent failed with a timeout\n"); + CloseHandle(ovl_wait.hEvent); + } + + CloseHandle(hcom); + } } /* A new open handle should not return error or have bytes in the Queues */ @@ -964,7 +1069,7 @@ static void test_LoopbackRead(void) ok(read == sizeof(tbuf),"ReadFile read %d bytes, expected \"%s\"\n", read,rbuf); /* Now do the same with a slower Baud rate. - As we request more characters then written, we will hit the timeout + As we request more characters than written, we will hit the timeout */ ok(GetCommState(hcom, &dcb), "GetCommState failed\n"); @@ -1036,7 +1141,7 @@ static void test_LoopbackCtsRts(void) if (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE) { trace("RTS_CONTROL_HANDSHAKE is set, so don't manipulate RTS\n"); - CloseHandle(hcom); + CloseHandle(hcom); return; } ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n"); @@ -1180,6 +1285,7 @@ static void test_LoopbackDtrRing(void) if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE) { trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n"); + CloseHandle(hcom); return; } ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n"); @@ -1232,12 +1338,12 @@ static void test_WaitRx(void) if (hcom == INVALID_HANDLE_VALUE) return; ok(SetCommMask(hcom, EV_RXCHAR), "SetCommMask failed\n"); - hComPortEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); ok(hComPortEvent != 0, "CreateEvent failed\n"); ZeroMemory( &overlapped, sizeof(overlapped)); overlapped.hEvent = hComPortEvent; - hComWriteEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + hComWriteEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); ok(hComWriteEvent != NULL, "CreateEvent res %d\n", GetLastError()); ZeroMemory( &overlapped_w, sizeof(overlapped_w)); overlapped_w.hEvent = hComWriteEvent; @@ -1352,7 +1458,7 @@ static void test_WaitCts(void) trace("test_WaitCts timeout %ld clt 0x%08lx handle %p\n",args[0], args[1], hcom); ok(SetCommMask(hcom, EV_CTS), "SetCommMask failed\n"); - hComPortEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); ok(hComPortEvent != 0, "CreateEvent failed\n"); args[3] = (DWORD_PTR)hComPortEvent; alarmThread = CreateThread(NULL, 0, toggle_ctlLine, args, 0, &alarmThreadId); @@ -1446,7 +1552,7 @@ static void test_AbortWaitCts(void) trace("test_AbortWaitCts timeout %ld handle %p\n",args[0], hcom); ok(SetCommMask(hcom, EV_CTS), "SetCommMask failed\n"); - hComPortEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); ok(hComPortEvent != 0, "CreateEvent failed\n"); alarmThread = CreateThread(NULL, 0, reset_CommMask, args, 0, &alarmThreadId); /* Wait a minimum to let the thread start up */ @@ -1518,7 +1624,7 @@ static void test_WaitDsr(void) trace("test_WaitDsr timeout %ld clt 0x%08lx handle %p\n",args[0], args[1], hcom); ok(SetCommMask(hcom, EV_DSR), "SetCommMask failed\n"); - hComPortEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); ok(hComPortEvent != 0, "CreateEvent failed\n"); alarmThread = CreateThread(NULL, 0, toggle_ctlLine, args, 0, &alarmThreadId); ok(alarmThread !=0 , "CreateThread Failed\n"); @@ -1592,6 +1698,7 @@ static void test_WaitRing(void) ok((ret = GetCommModemStatus(hcom, &defaultStat)), "GetCommModemStatus failed\n"); if (!ret) { skip("modem status failed -> skip.\n"); + CloseHandle(hcom); return; } if(defaultStat & MS_RING_ON) @@ -1603,7 +1710,7 @@ static void test_WaitRing(void) trace("test_WaitRing timeout %ld clt 0x%08lx handle %p\n",args[0], args[1], hcom); ok(SetCommMask(hcom, EV_RING), "SetCommMask failed\n"); - hComPortEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); ok(hComPortEvent != 0, "CreateEvent failed\n"); alarmThread = CreateThread(NULL, 0, toggle_ctlLine, args, 0, &alarmThreadId); ok(alarmThread !=0 , "CreateThread Failed\n"); @@ -1668,7 +1775,7 @@ static void test_WaitDcd(void) if (dcb.fDtrControl == DTR_CONTROL_DISABLE) { trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n"); - CloseHandle(hcom); + CloseHandle(hcom); return; } args[0]= TIMEOUT >>1; @@ -1682,7 +1789,7 @@ static void test_WaitDcd(void) trace("test_WaitDcd timeout %ld clt 0x%08lx handle %p\n",args[0], args[1], hcom); ok(SetCommMask(hcom, EV_RLSD), "SetCommMask failed\n"); - hComPortEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); ok(hComPortEvent != 0, "CreateEvent failed\n"); alarmThread = CreateThread(NULL, 0, toggle_ctlLine, args, 0, &alarmThreadId); ok(alarmThread !=0 , "CreateThread Failed\n"); @@ -1761,7 +1868,7 @@ static void test_WaitBreak(void) if (hcom == INVALID_HANDLE_VALUE) return; ok(SetCommMask(hcom, EV_BREAK), "SetCommMask failed\n"); - hComPortEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); ok(hComPortEvent != 0, "CreateEvent failed\n"); trace("test_WaitBreak\n"); @@ -1834,7 +1941,7 @@ static void test_WaitCommEvent(void) S(U(ovl_wait)).Offset = 0; S(U(ovl_wait)).OffsetHigh = 0; - ovl_wait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + ovl_wait.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); trace("waiting 10 secs for com port events (turn on/off the device)...\n"); last_event_time = 0; @@ -1897,8 +2004,200 @@ static void test_FlushFileBuffers(void) CloseHandle(hcom); } +static void test_read_write(void) +{ + static const char atz[]="ATZ\r\n"; + char buf[256]; + HANDLE hcom; + DCB dcb; + COMMTIMEOUTS timeouts; + DWORD ret, bytes, status, evtmask, before, after, last_event_time; + OVERLAPPED ovl_wait; + IO_STATUS_BLOCK iob; + LARGE_INTEGER offset; + LONG i; + + if (!pNtReadFile || !pNtWriteFile) + { + win_skip("not running on NT, skipping test\n"); + return; + } + + hcom = test_OpenComm(TRUE); + if (hcom == INVALID_HANDLE_VALUE) return; + + ret = GetCommState(hcom, &dcb); + ok(ret, "GetCommState error %d\n", GetLastError()); + dcb.BaudRate = 9600; + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.fRtsControl = RTS_CONTROL_ENABLE; + dcb.fDtrControl = DTR_CONTROL_ENABLE; + dcb.StopBits = ONESTOPBIT; + ret = SetCommState(hcom, &dcb); + ok(ret, "SetCommState error %d\n", GetLastError()); + + memset(&timeouts, 0, sizeof(timeouts)); + timeouts.ReadTotalTimeoutConstant = TIMEOUT; + ret = SetCommTimeouts(hcom, &timeouts); + ok(ret,"SetCommTimeouts error %d\n", GetLastError()); + + ret = SetupComm(hcom, 1024, 1024); + ok(ret, "SetUpComm error %d\n", GetLastError()); + + bytes = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = WriteFile(hcom, atz, 0, &bytes, NULL); + ok(!ret, "WriteFile should fail\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(bytes == 0, "bytes %u\n", bytes); + + U(iob).Status = -1; + iob.Information = -1; + status = pNtWriteFile(hcom, 0, NULL, NULL, &iob, atz, 0, NULL, NULL); + ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %#x\n", status); + ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); + ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information); + + for (i = -20; i < 20; i++) + { + U(iob).Status = -1; + iob.Information = -1; + offset.QuadPart = (LONGLONG)i; + status = pNtWriteFile(hcom, 0, NULL, NULL, &iob, atz, 0, &offset, NULL); + if (i >= 0 || i == -1) + { + ok(status == STATUS_SUCCESS, "%d: expected STATUS_SUCCESS, got %#x\n", i, status); + ok(U(iob).Status == STATUS_SUCCESS, "%d: expected STATUS_SUCCESS, got %#x\n", i, U(iob).Status); + ok(iob.Information == 0, "%d: expected 0, got %lu\n", i, iob.Information); + } + else + { + ok(status == STATUS_INVALID_PARAMETER, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i, status); + ok(U(iob).Status == -1, "%d: expected -1, got %#x\n", i, U(iob).Status); + ok(iob.Information == -1, "%d: expected -1, got %ld\n", i, iob.Information); + } + } + + U(iob).Status = -1; + iob.Information = -1; + offset.QuadPart = 0; + status = pNtWriteFile(hcom, 0, NULL, NULL, &iob, atz, sizeof(atz), &offset, NULL); + ok(status == STATUS_PENDING || status == STATUS_SUCCESS, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status); + /* Under Windows checking IO_STATUS_BLOCK right after the call leads + * to races, iob.Status is either -1 or STATUS_SUCCESS, which means + * that it's set only when the operation completes. + */ + ret = WaitForSingleObject(hcom, TIMEOUT); + if (ret == WAIT_TIMEOUT) + { + skip("Probably modem is not connected.\n"); + CloseHandle(hcom); + return; + } + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %d\n", ret); + ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); + ok(iob.Information == sizeof(atz), "expected sizeof(atz), got %lu\n", iob.Information); + + ret = SetCommMask(hcom, EV_RXCHAR); + ok(ret, "SetCommMask error %d\n", GetLastError()); + + S(U(ovl_wait)).Offset = 0; + S(U(ovl_wait)).OffsetHigh = 0; + ovl_wait.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + + trace("waiting 3 secs for modem response...\n"); + last_event_time = 0; + before = GetTickCount(); + do + { + evtmask = 0; + SetLastError(0xdeadbeef); + ret = WaitCommEvent(hcom, &evtmask, &ovl_wait); + ok(!ret && GetLastError() == ERROR_IO_PENDING, "WaitCommEvent returned %d, error %d\n", ret, GetLastError()); + if (GetLastError() != ERROR_IO_PENDING) goto done; /* no point in further testing */ + for (;;) + { + ret = WaitForSingleObject(ovl_wait.hEvent, 100); + after = GetTickCount(); + if (ret == WAIT_OBJECT_0) + { + trace("got modem response.\n"); + + last_event_time = after; + ret = GetOverlappedResult(hcom, &ovl_wait, &bytes, FALSE); + ok(ret, "GetOverlappedResult reported error %d\n", GetLastError()); + ok(bytes == sizeof(evtmask), "expected sizeof(evtmask), got %u\n", bytes); + ok(evtmask & EV_RXCHAR, "EV_RXCHAR should be set\n"); + + bytes = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadFile(hcom, buf, 0, &bytes, NULL); + ok(!ret, "ReadFile should fail\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(bytes == 0, "bytes %u\n", bytes); + + U(iob).Status = -1; + iob.Information = -1; + status = pNtReadFile(hcom, 0, NULL, NULL, &iob, buf, 0, NULL, NULL); + ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %#x\n", status); + ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); + ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information); + + for (i = -20; i < 20; i++) + { + U(iob).Status = -1; + iob.Information = -1; + offset.QuadPart = (LONGLONG)i; + status = pNtReadFile(hcom, 0, NULL, NULL, &iob, buf, 0, &offset, NULL); + /* FIXME: Remove once Wine is fixed */ + if (status == STATUS_PENDING) WaitForSingleObject(hcom, TIMEOUT); + if (i >= 0) + { +todo_wine + ok(status == STATUS_SUCCESS, "%d: expected STATUS_SUCCESS, got %#x\n", i, status); +todo_wine + ok(U(iob).Status == STATUS_SUCCESS, "%d: expected STATUS_SUCCESS, got %#x\n", i, U(iob).Status); + ok(iob.Information == 0, "%d: expected 0, got %lu\n", i, iob.Information); + } + else + { + ok(status == STATUS_INVALID_PARAMETER, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i, status); + ok(U(iob).Status == -1, "%d: expected -1, got %#x\n", i, U(iob).Status); + ok(iob.Information == -1, "%d: expected -1, got %ld\n", i, iob.Information); + } + } + + U(iob).Status = -1; + iob.Information = -1; + offset.QuadPart = 0; + status = pNtReadFile(hcom, 0, NULL, NULL, &iob, buf, 1, &offset, NULL); + ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", status); + ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); + ok(iob.Information == 1, "expected 1, got %lu\n", iob.Information); + goto done; + } + else + { + if (last_event_time || after - before >= 3000) goto done; + } + } + } while (after - before < 3000); + +done: + CloseHandle(ovl_wait.hEvent); + CloseHandle(hcom); +} + START_TEST(comm) { + HMODULE ntdll = GetModuleHandleA("ntdll.dll"); + if (ntdll) + { + pNtReadFile = (void *)GetProcAddress(ntdll, "NtReadFile"); + pNtWriteFile = (void *)GetProcAddress(ntdll, "NtWriteFile"); + } + test_ClearCommError(); /* keep it the very first test */ test_FlushFileBuffers(); test_BuildCommDCB(); @@ -1918,6 +2217,7 @@ START_TEST(comm) test_WaitDcd(); test_WaitBreak(); test_stdio(); + test_read_write(); if (!winetest_interactive) { diff --git a/rostests/winetests/kernel32/console.c b/rostests/winetests/kernel32/console.c index df752f457b7..5928e8c7ea7 100755 --- a/rostests/winetests/kernel32/console.c +++ b/rostests/winetests/kernel32/console.c @@ -50,7 +50,7 @@ static BOOL (WINAPI *pVerifyConsoleIoHandle)(HANDLE handle); #define okCHAR(hCon, c, ch, attr) do { \ char __ch; WORD __attr; DWORD __len; BOOL expect; \ - expect = ReadConsoleOutputCharacter((hCon), &__ch, 1, (c), &__len) == 1 && __len == 1 && __ch == (ch); \ + expect = ReadConsoleOutputCharacterA((hCon), &__ch, 1, (c), &__len) == 1 && __len == 1 && __ch == (ch); \ ok(expect, "At (%d,%d): expecting char '%c'/%02x got '%c'/%02x\n", (c).X, (c).Y, (ch), (ch), __ch, __ch); \ expect = ReadConsoleOutputAttribute((hCon), &__attr, 1, (c), &__len) == 1 && __len == 1 && __attr == (attr); \ ok(expect, "At (%d,%d): expecting attr %04x got %04x\n", (c).X, (c).Y, (attr), __attr); \ @@ -179,7 +179,7 @@ static void testEmptyWrite(HANDLE hCon) ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left\n"); len = -1; - ok(WriteConsole(hCon, NULL, 0, &len, NULL) != 0 && len == 0, "WriteConsole\n"); + ok(WriteConsoleA(hCon, NULL, 0, &len, NULL) != 0 && len == 0, "WriteConsole\n"); okCURSOR(hCon, c); /* Passing a NULL lpBuffer with sufficiently large non-zero length succeeds @@ -188,22 +188,22 @@ static void testEmptyWrite(HANDLE hCon) if (0) { len = -1; - ok(!WriteConsole(hCon, NULL, 16, &len, NULL) && len == -1, "WriteConsole\n"); + ok(!WriteConsoleA(hCon, NULL, 16, &len, NULL) && len == -1, "WriteConsole\n"); okCURSOR(hCon, c); /* Cursor advances for this call. */ len = -1; - ok(WriteConsole(hCon, NULL, 128, &len, NULL) != 0 && len == 128, "WriteConsole\n"); + ok(WriteConsoleA(hCon, NULL, 128, &len, NULL) != 0 && len == 128, "WriteConsole\n"); } len = -1; - ok(WriteConsole(hCon, emptybuf, 0, &len, NULL) != 0 && len == 0, "WriteConsole\n"); + ok(WriteConsoleA(hCon, emptybuf, 0, &len, NULL) != 0 && len == 0, "WriteConsole\n"); okCURSOR(hCon, c); /* WriteConsole does not halt on a null terminator and is happy to write * memory contents beyond the actual size of the buffer. */ len = -1; - ok(WriteConsole(hCon, emptybuf, 16, &len, NULL) != 0 && len == 16, "WriteConsole\n"); + ok(WriteConsoleA(hCon, emptybuf, 16, &len, NULL) != 0 && len == 16, "WriteConsole\n"); c.X += 16; okCURSOR(hCon, c); } @@ -219,7 +219,7 @@ static void testWriteSimple(HANDLE hCon) c.X = c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left\n"); - ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); + ok(WriteConsoleA(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); c.Y = 0; for (c.X = 0; c.X < mylen; c.X++) { @@ -246,7 +246,7 @@ static void testWriteNotWrappedNotProcessed(HANDLE hCon, COORD sbSize) c.X = sbSize.X - 3; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-3\n"); - ret = WriteConsole(hCon, mytest, mylen, &len, NULL); + ret = WriteConsoleA(hCon, mytest, mylen, &len, NULL); ok(ret != 0 && len == mylen, "Couldn't write, ret = %d, len = %d\n", ret, len); c.Y = 0; for (p = mylen - 3; p < mylen; p++) @@ -265,7 +265,7 @@ static void testWriteNotWrappedNotProcessed(HANDLE hCon, COORD sbSize) c.X = sbSize.X - mylen; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-3\n"); - ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); + ok(WriteConsoleA(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); } static void testWriteNotWrappedProcessed(HANDLE hCon, COORD sbSize) @@ -285,7 +285,7 @@ static void testWriteNotWrappedProcessed(HANDLE hCon, COORD sbSize) c.X = sbSize.X - 5; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-5\n"); - ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); + ok(WriteConsoleA(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); c.Y = 0; for (c.X = sbSize.X - 5; c.X < sbSize.X - 1; c.X++) { @@ -316,7 +316,7 @@ static void testWriteNotWrappedProcessed(HANDLE hCon, COORD sbSize) c.X = sbSize.X - 4; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-4\n"); - ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); + ok(WriteConsoleA(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); c.Y = 0; for (c.X = sbSize.X - 4; c.X < sbSize.X; c.X++) { @@ -336,7 +336,7 @@ static void testWriteNotWrappedProcessed(HANDLE hCon, COORD sbSize) c.X = sbSize.X - 3; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-4\n"); - ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); + ok(WriteConsoleA(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); c.Y = 0; for (p = mylen2 - 3; p < mylen2; p++) { @@ -369,7 +369,7 @@ static void testWriteWrappedNotProcessed(HANDLE hCon, COORD sbSize) c.X = sbSize.X - 9; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-9\n"); - ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); + ok(WriteConsoleA(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); c.Y = 0; for (p = 0; p < mylen; p++) { @@ -406,7 +406,7 @@ static void testWriteWrappedProcessed(HANDLE hCon, COORD sbSize) c.X = sbSize.X - 9; c.Y = 0; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-9\n"); - ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); + ok(WriteConsoleA(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); for (p = 0; p < 4; p++) { c.X = sbSize.X - 9 + p; @@ -431,7 +431,7 @@ static void testWriteWrappedProcessed(HANDLE hCon, COORD sbSize) c.X = sbSize.X - 3; c.Y = 2; ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-3\n"); - ok(WriteConsole(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); + ok(WriteConsoleA(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); for (p = 0; p < 3; p++) { c.X = sbSize.X - 3 + p; @@ -458,7 +458,7 @@ static void testWriteWrappedProcessed(HANDLE hCon, COORD sbSize) static void testWrite(HANDLE hCon, COORD sbSize) { - /* FIXME: should in fact insure that the sb is at least 10 character wide */ + /* FIXME: should in fact ensure that the sb is at least 10 characters wide */ ok(SetConsoleTextAttribute(hCon, TEST_ATTRIB), "Setting default text color\n"); resetContent(hCon, sbSize, FALSE); testEmptyWrite(hCon); @@ -504,7 +504,7 @@ static void testScroll(HANDLE hCon, COORD sbSize) clip.Top = 0; clip.Bottom = sbSize.Y - 1; - ok(ScrollConsoleScreenBuffer(hCon, &scroll, NULL, dst, &ci), "Scrolling SB\n"); + ok(ScrollConsoleScreenBufferA(hCon, &scroll, NULL, dst, &ci), "Scrolling SB\n"); for (c.Y = 0; c.Y < sbSize.Y; c.Y++) { @@ -539,7 +539,7 @@ static void testScroll(HANDLE hCon, COORD sbSize) clip.Top = 0; clip.Bottom = sbSize.Y - 1; - ok(ScrollConsoleScreenBuffer(hCon, &scroll, NULL, dst, &ci), "Scrolling SB\n"); + ok(ScrollConsoleScreenBufferA(hCon, &scroll, NULL, dst, &ci), "Scrolling SB\n"); for (c.Y = 0; c.Y < sbSize.Y; c.Y++) { @@ -574,7 +574,7 @@ static void testScroll(HANDLE hCon, COORD sbSize) clip.Bottom = min(H + H / 2, sbSize.Y - 1); SetLastError(0xdeadbeef); - ret = ScrollConsoleScreenBuffer(hCon, &scroll, &clip, dst, &ci); + ret = ScrollConsoleScreenBufferA(hCon, &scroll, &clip, dst, &ci); if (ret) { for (c.Y = 0; c.Y < sbSize.Y; c.Y++) @@ -617,7 +617,7 @@ static void testScroll(HANDLE hCon, COORD sbSize) clip.Top = H / 2; clip.Bottom = min(H + H / 2, sbSize.Y - 1); - ok(ScrollConsoleScreenBuffer(hCon, &scroll, &clip, dst, &ci), "Scrolling SB\n"); + ok(ScrollConsoleScreenBufferA(hCon, &scroll, &clip, dst, &ci), "Scrolling SB\n"); for (c.Y = 0; c.Y < sbSize.Y; c.Y++) { @@ -654,8 +654,8 @@ static void testCtrlHandler(void) ok(!SetConsoleCtrlHandler(mch, FALSE), "Shouldn't succeed\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "Bad error %u\n", GetLastError()); ok(SetConsoleCtrlHandler(mch, TRUE), "Couldn't set handler\n"); - /* wine requires the event for the test, as we cannot insure, so far, that event - * are processed synchronously in GenerateConsoleCtrlEvent() + /* wine requires the event for the test, as we cannot ensure, so far, that + * events are processed synchronously in GenerateConsoleCtrlEvent() */ mch_event = CreateEventA(NULL, TRUE, FALSE, NULL); mch_count = 0; @@ -704,7 +704,7 @@ static void testScreenBuffer(HANDLE hConOut) WCHAR test_unicode[] = {0x0442, 0x0435, 0x0441, 0x0442, 0}; WCHAR str_wbuf[20]; char str_buf[20]; - DWORD len; + DWORD len, error; COORD c; BOOL ret; DWORD oldcp; @@ -782,25 +782,25 @@ static void testScreenBuffer(HANDLE hConOut) /* trying to write non-console handle */ SetLastError(0xdeadbeef); - ok(!WriteConsoleA(hFileOutRW, test_str1, lstrlenA(test_str1), &len, NULL), - "Shouldn't succeed\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, - "GetLastError: expecting %u got %u\n", - ERROR_INVALID_HANDLE, GetLastError()); + ret = WriteConsoleA(hFileOutRW, test_str1, lstrlenA(test_str1), &len, NULL); + error = GetLastError(); + ok(!ret, "Shouldn't succeed\n"); + ok(error == ERROR_INVALID_HANDLE || error == ERROR_INVALID_FUNCTION, + "GetLastError: got %u\n", error); SetLastError(0xdeadbeef); - ok(!WriteConsoleA(hFileOutRO, test_str1, lstrlenA(test_str1), &len, NULL), - "Shouldn't succeed\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, - "GetLastError: expecting %u got %u\n", - ERROR_INVALID_HANDLE, GetLastError()); + ret = WriteConsoleA(hFileOutRO, test_str1, lstrlenA(test_str1), &len, NULL); + error = GetLastError(); + ok(!ret, "Shouldn't succeed\n"); + ok(error == ERROR_INVALID_HANDLE || error == ERROR_INVALID_FUNCTION, + "GetLastError: got %u\n", error); SetLastError(0xdeadbeef); - ok(!WriteConsoleA(hFileOutWT, test_str1, lstrlenA(test_str1), &len, NULL), - "Shouldn't succeed\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, - "GetLastError: expecting %u got %u\n", - ERROR_INVALID_HANDLE, GetLastError()); + ret = WriteConsoleA(hFileOutWT, test_str1, lstrlenA(test_str1), &len, NULL); + error = GetLastError(); + ok(!ret, "Shouldn't succeed\n"); + todo_wine ok(error == ERROR_INVALID_HANDLE || error == ERROR_INVALID_FUNCTION, + "GetLastError: got %u\n", error); CloseHandle(hFileOutRW); CloseHandle(hFileOutRO); @@ -927,7 +927,7 @@ static void test_GetSetConsoleInputExeName(void) ok(ret, "GetConsoleInputExeNameA failed\n"); ok(error == ERROR_BUFFER_OVERFLOW, "got %u expected ERROR_BUFFER_OVERFLOW\n", error); - GetModuleFileNameA(GetModuleHandle(NULL), module, sizeof(module)); + GetModuleFileNameA(GetModuleHandleA(NULL), module, sizeof(module)); p = strrchr(module, '\\') + 1; ret = pGetConsoleInputExeNameA(sizeof(buffer)/sizeof(buffer[0]), buffer); @@ -1025,7 +1025,8 @@ static void test_OpenCON(void) for (i = 0; i < sizeof(accesses) / sizeof(accesses[0]); i++) { h = CreateFileW(conW, GENERIC_WRITE, 0, NULL, accesses[i], 0, NULL); - ok(h != INVALID_HANDLE_VALUE, "Expected to open the CON device on write (%x)\n", accesses[i]); + ok(h != INVALID_HANDLE_VALUE || broken(accesses[i] == TRUNCATE_EXISTING /* Win8 */), + "Expected to open the CON device on write (%x)\n", accesses[i]); CloseHandle(h); h = CreateFileW(conW, GENERIC_READ, 0, NULL, accesses[i], 0, NULL); @@ -1034,14 +1035,13 @@ static void test_OpenCON(void) * NT, XP, Vista comply, but Win7 doesn't and allows opening CON with TRUNCATE_EXISTING * So don't test when disposition is TRUNCATE_EXISTING */ - if (accesses[i] != TRUNCATE_EXISTING) - { - ok(h != INVALID_HANDLE_VALUE, "Expected to open the CON device on read (%x)\n", accesses[i]); - } + ok(h != INVALID_HANDLE_VALUE || broken(accesses[i] == TRUNCATE_EXISTING /* Win7+ */), + "Expected to open the CON device on read (%x)\n", accesses[i]); CloseHandle(h); h = CreateFileW(conW, GENERIC_READ|GENERIC_WRITE, 0, NULL, accesses[i], 0, NULL); ok(h == INVALID_HANDLE_VALUE, "Expected not to open the CON device on read-write (%x)\n", accesses[i]); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Unexpected error %x\n", GetLastError()); + ok(GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER, + "Unexpected error %x\n", GetLastError()); } } @@ -1051,6 +1051,7 @@ static void test_OpenConsoleW(void) static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0}; static const WCHAR emptyW[] = {0}; static const WCHAR invalidW[] = {'I','N','V','A','L','I','D',0}; + DWORD gle; static const struct { @@ -1058,42 +1059,63 @@ static void test_OpenConsoleW(void) DWORD access; BOOL inherit; DWORD creation; - DWORD gle; + DWORD gle, gle2; } invalid_table[] = { - {NULL, 0, FALSE, 0, ERROR_INVALID_PARAMETER}, - {NULL, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER}, - {NULL, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {NULL, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER}, - {NULL, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {NULL, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING, ERROR_INVALID_PARAMETER}, - {emptyW, 0, FALSE, 0, ERROR_INVALID_PARAMETER}, - {emptyW, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER}, - {emptyW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {emptyW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER}, - {emptyW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {emptyW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING, ERROR_INVALID_PARAMETER}, - {invalidW, 0, FALSE, 0, ERROR_INVALID_PARAMETER}, - {invalidW, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER}, - {invalidW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER}, - {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING, ERROR_INVALID_PARAMETER}, - {coninW, 0, FALSE, 0, ERROR_SHARING_VIOLATION}, - {coninW, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER}, - {coninW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_SHARING_VIOLATION}, - {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW, ERROR_SHARING_VIOLATION}, - {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS, ERROR_SHARING_VIOLATION}, - {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING, ERROR_INVALID_PARAMETER}, - {conoutW, 0, FALSE, 0, ERROR_SHARING_VIOLATION}, - {conoutW, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER}, - {conoutW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_SHARING_VIOLATION}, - {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW, ERROR_SHARING_VIOLATION}, - {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS, ERROR_SHARING_VIOLATION}, - {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER}, - {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING, ERROR_INVALID_PARAMETER}, + {NULL, 0, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {NULL, 0, FALSE, 0xdeadbeef, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {NULL, 0xdeadbeef, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {NULL, 0xdeadbeef, TRUE, 0xdeadbeef, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {NULL, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {NULL, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {NULL, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {NULL, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {emptyW, 0, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {emptyW, 0, FALSE, 0xdeadbeef, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {emptyW, 0xdeadbeef, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {emptyW, 0xdeadbeef, TRUE, 0xdeadbeef, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {emptyW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {emptyW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {emptyW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {emptyW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING, ERROR_INVALID_PARAMETER, ERROR_PATH_NOT_FOUND}, + {invalidW, 0, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_FILE_NOT_FOUND}, + {invalidW, 0, FALSE, 0xdeadbeef, ERROR_INVALID_PARAMETER, 0}, + {invalidW, 0xdeadbeef, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_FILE_NOT_FOUND}, + {invalidW, 0xdeadbeef, TRUE, 0xdeadbeef, ERROR_INVALID_PARAMETER, 0}, + {invalidW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER, ERROR_FILE_NOT_FOUND}, + {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_FILE_NOT_FOUND}, + {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER, ERROR_FILE_NOT_FOUND}, + {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING, ERROR_INVALID_PARAMETER, ERROR_FILE_NOT_FOUND}, + {coninW, 0, FALSE, 0xdeadbeef, ERROR_INVALID_PARAMETER, 0}, + {coninW, 0xdeadbeef, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_ACCESS_DENIED}, + {coninW, 0xdeadbeef, TRUE, 0xdeadbeef, ERROR_INVALID_PARAMETER, 0}, + {conoutW, 0, FALSE, 0xdeadbeef, ERROR_INVALID_PARAMETER, 0}, + {conoutW, 0xceadbeef, FALSE, 0, ERROR_INVALID_PARAMETER, ERROR_ACCESS_DENIED}, + {conoutW, 0xdeadbeef, TRUE, 0xdeadbeef, ERROR_INVALID_PARAMETER, 0}, + }; + static const struct + { + LPCWSTR name; + DWORD access; + BOOL inherit; + DWORD creation; + } valid_table[] = { + {coninW, 0, FALSE, 0 }, + {coninW, 0, TRUE, 0 }, + {coninW, GENERIC_EXECUTE, TRUE, 0 }, + {coninW, GENERIC_ALL, TRUE, 0 }, + {coninW, 0, FALSE, OPEN_ALWAYS }, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, 0 }, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW }, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS }, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS }, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING}, + {conoutW, 0, FALSE, 0 }, + {conoutW, 0, FALSE, OPEN_ALWAYS }, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, 0 }, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW, }, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS }, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS }, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING}, }; int index; @@ -1110,30 +1132,33 @@ static void test_OpenConsoleW(void) SetLastError(0xdeadbeef); ret = pOpenConsoleW(invalid_table[index].name, invalid_table[index].access, invalid_table[index].inherit, invalid_table[index].creation); + gle = GetLastError(); ok(ret == INVALID_HANDLE_VALUE, "Expected OpenConsoleW to return INVALID_HANDLE_VALUE for index %d, got %p\n", index, ret); - ok(GetLastError() == invalid_table[index].gle, - "Expected GetLastError() to return %u for index %d, got %u\n", - invalid_table[index].gle, index, GetLastError()); + ok(gle == invalid_table[index].gle || (gle != 0 && gle == invalid_table[index].gle2), + "Expected GetLastError() to return %u/%u for index %d, got %u\n", + invalid_table[index].gle, invalid_table[index].gle2, index, gle); + } + + for (index = 0; index < sizeof(valid_table)/sizeof(valid_table[0]); index++) + { + ret = pOpenConsoleW(valid_table[index].name, valid_table[index].access, + valid_table[index].inherit, valid_table[index].creation); + todo_wine + ok(ret != INVALID_HANDLE_VALUE || broken(ret == INVALID_HANDLE_VALUE /* until Win7 */), + "Expected OpenConsoleW to succeed for index %d, got %p\n", index, ret); + if (ret != INVALID_HANDLE_VALUE) + CloseHandle(ret); } - /* OpenConsoleW should not touch the last error on success. */ - SetLastError(0xdeadbeef); ret = pOpenConsoleW(coninW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING); - ok(ret != INVALID_HANDLE_VALUE, - "Expected OpenConsoleW to return a valid handle\n"); - ok(GetLastError() == 0xdeadbeef, - "Expected the last error to be untouched, got %u\n", GetLastError()); + ok(ret != INVALID_HANDLE_VALUE, "Expected OpenConsoleW to return a valid handle\n"); if (ret != INVALID_HANDLE_VALUE) CloseHandle(ret); - SetLastError(0xdeadbeef); ret = pOpenConsoleW(conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING); - ok(ret != INVALID_HANDLE_VALUE, - "Expected OpenConsoleW to return a valid handle\n"); - ok(GetLastError() == 0xdeadbeef, - "Expected the last error to be untouched, got %u\n", GetLastError()); + ok(ret != INVALID_HANDLE_VALUE, "Expected OpenConsoleW to return a valid handle\n"); if (ret != INVALID_HANDLE_VALUE) CloseHandle(ret); } @@ -1158,14 +1183,13 @@ static void test_CreateFileW(void) {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW, 0, FALSE}, {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS, 0, FALSE}, {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, 0, FALSE}, - {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING, 0, FALSE}, {conoutW, 0, FALSE, 0, ERROR_INVALID_PARAMETER, TRUE}, {conoutW, 0, FALSE, OPEN_ALWAYS, 0, FALSE}, {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER, TRUE}, {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW, 0, FALSE}, {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS, 0, FALSE}, {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, 0, FALSE}, - {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING, 0, FALSE}, + /* TRUNCATE_EXISTING is forbidden starting with Windows 8 */ }; int index; @@ -1342,7 +1366,7 @@ static void test_WriteConsoleInputA(HANDLE input_handle) INPUT_RECORD event_list[5]; MOUSE_EVENT_RECORD mouse_event = { {0, 0}, 0, 0, MOUSE_MOVED }; KEY_EVENT_RECORD key_event; - DWORD count, console_mode; + DWORD count, console_mode, gle; BOOL ret; int i; @@ -1353,31 +1377,31 @@ static void test_WriteConsoleInputA(HANDLE input_handle) DWORD count; LPDWORD written; DWORD expected_count; - DWORD last_error; + DWORD gle, gle2; int win_crash; } invalid_table[] = { - {NULL, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {NULL, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {NULL, NULL, 0, &count, 0, ERROR_INVALID_HANDLE}, - {NULL, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {NULL, NULL, 1, &count, 0xdeadbeef, ERROR_INVALID_ACCESS}, - {NULL, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {NULL, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {NULL, NULL, 1, &count, 0xdeadbeef, ERROR_NOACCESS, ERROR_INVALID_ACCESS}, + {NULL, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {NULL, &event, 0, &count, 0, ERROR_INVALID_HANDLE}, - {NULL, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {NULL, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {NULL, &event, 1, &count, 0, ERROR_INVALID_HANDLE}, - {INVALID_HANDLE_VALUE, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {INVALID_HANDLE_VALUE, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {INVALID_HANDLE_VALUE, NULL, 0, &count, 0, ERROR_INVALID_HANDLE}, - {INVALID_HANDLE_VALUE, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {INVALID_HANDLE_VALUE, NULL, 1, &count, 0xdeadbeef, ERROR_INVALID_ACCESS}, - {INVALID_HANDLE_VALUE, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {INVALID_HANDLE_VALUE, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {INVALID_HANDLE_VALUE, NULL, 1, &count, 0xdeadbeef, ERROR_INVALID_HANDLE, ERROR_INVALID_ACCESS}, + {INVALID_HANDLE_VALUE, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {INVALID_HANDLE_VALUE, &event, 0, &count, 0, ERROR_INVALID_HANDLE}, - {INVALID_HANDLE_VALUE, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {INVALID_HANDLE_VALUE, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {INVALID_HANDLE_VALUE, &event, 1, &count, 0, ERROR_INVALID_HANDLE}, - {input_handle, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {input_handle, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {input_handle, NULL, 1, &count, 0xdeadbeef, ERROR_INVALID_ACCESS}, - {input_handle, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {input_handle, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {input_handle, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {input_handle, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {input_handle, NULL, 1, &count, 0xdeadbeef, ERROR_NOACCESS, ERROR_INVALID_ACCESS}, + {input_handle, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {input_handle, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, }; /* Suppress external sources of input events for the duration of the test. */ @@ -1422,9 +1446,10 @@ static void test_WriteConsoleInputA(HANDLE input_handle) "[%d] Expected output count to be %u, got %u\n", i, invalid_table[i].expected_count, count); } - ok(GetLastError() == invalid_table[i].last_error, - "[%d] Expected last error to be %u, got %u\n", - i, invalid_table[i].last_error, GetLastError()); + gle = GetLastError(); + ok(gle == invalid_table[i].gle || (gle != 0 && gle == invalid_table[i].gle2), + "[%d] Expected last error to be %u or %u, got %u\n", + i, invalid_table[i].gle, invalid_table[i].gle2, gle); } count = 0xdeadbeef; @@ -1585,7 +1610,7 @@ static void test_WriteConsoleInputW(HANDLE input_handle) INPUT_RECORD event_list[5]; MOUSE_EVENT_RECORD mouse_event = { {0, 0}, 0, 0, MOUSE_MOVED }; KEY_EVENT_RECORD key_event; - DWORD count, console_mode; + DWORD count, console_mode, gle; BOOL ret; int i; @@ -1596,31 +1621,31 @@ static void test_WriteConsoleInputW(HANDLE input_handle) DWORD count; LPDWORD written; DWORD expected_count; - DWORD last_error; + DWORD gle, gle2; int win_crash; } invalid_table[] = { - {NULL, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {NULL, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {NULL, NULL, 0, &count, 0, ERROR_INVALID_HANDLE}, - {NULL, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {NULL, NULL, 1, &count, 0xdeadbeef, ERROR_INVALID_ACCESS}, - {NULL, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {NULL, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {NULL, NULL, 1, &count, 0xdeadbeef, ERROR_NOACCESS, ERROR_INVALID_ACCESS}, + {NULL, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {NULL, &event, 0, &count, 0, ERROR_INVALID_HANDLE}, - {NULL, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {NULL, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {NULL, &event, 1, &count, 0, ERROR_INVALID_HANDLE}, - {INVALID_HANDLE_VALUE, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {INVALID_HANDLE_VALUE, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {INVALID_HANDLE_VALUE, NULL, 0, &count, 0, ERROR_INVALID_HANDLE}, - {INVALID_HANDLE_VALUE, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {INVALID_HANDLE_VALUE, NULL, 1, &count, 0xdeadbeef, ERROR_INVALID_ACCESS}, - {INVALID_HANDLE_VALUE, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {INVALID_HANDLE_VALUE, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {INVALID_HANDLE_VALUE, NULL, 1, &count, 0xdeadbeef, ERROR_INVALID_HANDLE, ERROR_INVALID_ACCESS}, + {INVALID_HANDLE_VALUE, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {INVALID_HANDLE_VALUE, &event, 0, &count, 0, ERROR_INVALID_HANDLE}, - {INVALID_HANDLE_VALUE, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {INVALID_HANDLE_VALUE, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, {INVALID_HANDLE_VALUE, &event, 1, &count, 0, ERROR_INVALID_HANDLE}, - {input_handle, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {input_handle, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {input_handle, NULL, 1, &count, 0xdeadbeef, ERROR_INVALID_ACCESS}, - {input_handle, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, - {input_handle, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 1}, + {input_handle, NULL, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {input_handle, NULL, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {input_handle, NULL, 1, &count, 0xdeadbeef, ERROR_NOACCESS, ERROR_INVALID_ACCESS}, + {input_handle, &event, 0, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, + {input_handle, &event, 1, NULL, 0xdeadbeef, ERROR_INVALID_ACCESS, 0, 1}, }; /* Suppress external sources of input events for the duration of the test. */ @@ -1665,9 +1690,10 @@ static void test_WriteConsoleInputW(HANDLE input_handle) "[%d] Expected output count to be %u, got %u\n", i, invalid_table[i].expected_count, count); } - ok(GetLastError() == invalid_table[i].last_error, - "[%d] Expected last error to be %u, got %u\n", - i, invalid_table[i].last_error, GetLastError()); + gle = GetLastError(); + ok(gle == invalid_table[i].gle || (gle != 0 && gle == invalid_table[i].gle2), + "[%d] Expected last error to be %u or %u, got %u\n", + i, invalid_table[i].gle, invalid_table[i].gle2, gle); } count = 0xdeadbeef; @@ -2001,7 +2027,7 @@ static void test_WriteConsoleOutputAttribute(HANDLE output_handle) const struct { HANDLE hConsoleOutput; - CONST WORD *attr; + const WORD *attr; DWORD length; COORD coord; LPDWORD lpNumAttrsWritten; @@ -2527,6 +2553,41 @@ static void test_ReadConsoleOutputAttribute(HANDLE output_handle) ok(count == 1, "Expected count to be 1, got %u\n", count); } +static void test_ReadConsole(void) +{ + HANDLE std_input; + DWORD ret, bytes; + char buf[1024]; + + std_input = GetStdHandle(STD_INPUT_HANDLE); + + SetLastError(0xdeadbeef); + ret = GetFileSize(std_input, NULL); + ok(ret == INVALID_FILE_SIZE, "expected INVALID_FILE_SIZE, got %#x\n", ret); + ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + + bytes = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadFile(std_input, buf, -128, &bytes, NULL); + ok(!ret, "expected 0, got %u\n", ret); + ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError()); + ok(!bytes, "expected 0, got %u\n", bytes); + + bytes = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadConsoleA(std_input, buf, -128, &bytes, NULL); + ok(!ret, "expected 0, got %u\n", ret); + ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError()); + ok(bytes == 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", bytes); + + bytes = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadConsoleW(std_input, buf, -128, &bytes, NULL); + ok(!ret, "expected 0, got %u\n", ret); + ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError()); + ok(bytes == 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", bytes); +} + START_TEST(console) { static const char font_name[] = "Lucida Console"; @@ -2620,6 +2681,7 @@ START_TEST(console) ok(sbi.dwSize.Y == size, "Unexpected buffer size: %d instead of %d\n", sbi.dwSize.Y, size); if (!ret) return; + test_ReadConsole(); /* Non interactive tests */ testCursor(hConOut, sbi.dwSize); /* test parameters (FIXME: test functionality) */ diff --git a/rostests/winetests/kernel32/debugger.c b/rostests/winetests/kernel32/debugger.c index e578cdd6240..011ed5ffd06 100644 --- a/rostests/winetests/kernel32/debugger.c +++ b/rostests/winetests/kernel32/debugger.c @@ -113,9 +113,9 @@ static void get_events(const char* name, HANDLE *start_event, HANDLE *done_event event_name=HeapAlloc(GetProcessHeap(), 0, 6+strlen(basename)+1); sprintf(event_name, "start_%s", basename); - *start_event=CreateEvent(NULL, 0,0, event_name); + *start_event=CreateEventA(NULL, 0,0, event_name); sprintf(event_name, "done_%s", basename); - *done_event=CreateEvent(NULL, 0,0, event_name); + *done_event=CreateEventA(NULL, 0,0, event_name); HeapFree(GetProcessHeap(), 0, event_name); } @@ -429,8 +429,8 @@ static void test_ExitCode(void) reg_save_value auto_value; reg_save_value debugger_value; - GetModuleFileNameA(GetModuleHandle(NULL), test_exe, sizeof(test_exe)); - if (GetFileAttributes(test_exe) == INVALID_FILE_ATTRIBUTES) + GetModuleFileNameA(GetModuleHandleA(NULL), test_exe, sizeof(test_exe)); + if (GetFileAttributesA(test_exe) == INVALID_FILE_ATTRIBUTES) strcat(test_exe, ".so"); if (GetFileAttributesA(test_exe) == INVALID_FILE_ATTRIBUTES) { @@ -686,7 +686,7 @@ static void doChildren(int argc, char **argv) p = p ? p+1 : blackbox_file; strcpy(event_name, p); strcat(event_name, "_init"); - event = OpenEvent(EVENT_ALL_ACCESS, FALSE, event_name); + event = OpenEventA(EVENT_ALL_ACCESS, FALSE, event_name); child_ok(event != NULL, "OpenEvent failed, last error %d.\n", GetLastError()); SetEvent(event); CloseHandle(event); @@ -695,7 +695,7 @@ static void doChildren(int argc, char **argv) p = p ? p+1 : blackbox_file; strcpy(event_name, p); strcat(event_name, "_attach"); - event = OpenEvent(EVENT_ALL_ACCESS, FALSE, event_name); + event = OpenEventA(EVENT_ALL_ACCESS, FALSE, event_name); child_ok(event != NULL, "OpenEvent failed, last error %d.\n", GetLastError()); WaitForSingleObject(event, INFINITE); CloseHandle(event); @@ -747,14 +747,14 @@ static void test_debug_children(char *name, DWORD flag, BOOL debug_child) p = p ? p+1 : blackbox_file; strcpy(event_name, p); strcat(event_name, "_init"); - event_init = CreateEvent(NULL, FALSE, FALSE, event_name); + event_init = CreateEventA(NULL, FALSE, FALSE, event_name); ok(event_init != NULL, "OpenEvent failed, last error %d.\n", GetLastError()); p = strrchr(blackbox_file, '\\'); p = p ? p+1 : blackbox_file; strcpy(event_name, p); strcat(event_name, "_attach"); - event_attach = CreateEvent(NULL, FALSE, flag!=0, event_name); + event_attach = CreateEventA(NULL, FALSE, flag!=0, event_name); ok(event_attach != NULL, "CreateEvent failed, last error %d.\n", GetLastError()); memset(&si, 0, sizeof(si)); @@ -814,12 +814,12 @@ START_TEST(debugger) { HMODULE hdll; - hdll=GetModuleHandle("kernel32.dll"); + hdll=GetModuleHandleA("kernel32.dll"); pCheckRemoteDebuggerPresent=(void*)GetProcAddress(hdll, "CheckRemoteDebuggerPresent"); pDebugActiveProcessStop=(void*)GetProcAddress(hdll, "DebugActiveProcessStop"); pDebugSetProcessKillOnExit=(void*)GetProcAddress(hdll, "DebugSetProcessKillOnExit"); pIsDebuggerPresent=(void*)GetProcAddress(hdll, "IsDebuggerPresent"); - hdll=GetModuleHandle("ntdll.dll"); + hdll=GetModuleHandleA("ntdll.dll"); if (hdll) pNtCurrentTeb = (void*)GetProcAddress(hdll, "NtCurrentTeb"); myARGC=winetest_get_mainargs(&myARGV); @@ -846,6 +846,7 @@ START_TEST(debugger) test_debug_loop(myARGC, myARGV); test_debug_children(myARGV[0], DEBUG_PROCESS, TRUE); test_debug_children(myARGV[0], DEBUG_ONLY_THIS_PROCESS, FALSE); + test_debug_children(myARGV[0], DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS, FALSE); test_debug_children(myARGV[0], 0, FALSE); } } diff --git a/rostests/winetests/kernel32/drive.c b/rostests/winetests/kernel32/drive.c index ca6cb44d044..4acd3e8c19c 100755 --- a/rostests/winetests/kernel32/drive.c +++ b/rostests/winetests/kernel32/drive.c @@ -117,7 +117,7 @@ static void test_GetDiskFreeSpaceA(void) if (!ret) /* GetDiskFreeSpaceA() should succeed, but it can fail with too many - different GetLastError() results to be usable for a ok() */ + different GetLastError() results to be usable for an ok() */ trace("GetDiskFreeSpaceA(%s) failed with %d\n", drive, GetLastError()); if( GetVersion() & 0x80000000) @@ -134,7 +134,7 @@ static void test_GetDiskFreeSpaceA(void) if (!ret) /* GetDiskFreeSpaceExA() should succeed, but it can fail with too many - different GetLastError() results to be usable for a ok() */ + different GetLastError() results to be usable for an ok() */ trace("GetDiskFreeSpaceExA(%s) failed with %d\n", drive, GetLastError()); ok( bytes_per_sector == 0 || /* empty cd rom drive */ @@ -192,7 +192,7 @@ static void test_GetDiskFreeSpaceW(void) drive[0], ret, GetLastError()); else if (!ret) /* GetDiskFreeSpaceW() should succeed, but it can fail with too many - different GetLastError() results to be usable for a ok() */ + different GetLastError() results to be usable for an ok() */ trace("GetDiskFreeSpaceW(%c) failed with %d\n", drive[0], GetLastError()); } logical_drives >>= 1; diff --git a/rostests/winetests/kernel32/environ.c b/rostests/winetests/kernel32/environ.c index 3ac86cd7a4b..f8452be2ee6 100755 --- a/rostests/winetests/kernel32/environ.c +++ b/rostests/winetests/kernel32/environ.c @@ -357,7 +357,7 @@ static void test_ExpandEnvironmentStringsA(void) ret_size = ExpandEnvironmentStringsA(buf, buf1, sizeof(buf1)); ok(ret_size == strlen(buf2)+1 || ret_size == (strlen(buf2)+1)*2 /* NT4 */, - "ExpandEnvironmentStrings returned %d instead of %d\n", ret_size, lstrlen(buf2)+1); + "ExpandEnvironmentStrings returned %d instead of %d\n", ret_size, lstrlenA(buf2)+1); ok(!strcmp(buf1, buf2), "ExpandEnvironmentStrings returned [%s]\n", buf1); SetEnvironmentVariableA("IndirectVar", NULL); diff --git a/rostests/winetests/kernel32/fiber.c b/rostests/winetests/kernel32/fiber.c index 0e685351b46..1e4ca666853 100644 --- a/rostests/winetests/kernel32/fiber.c +++ b/rostests/winetests/kernel32/fiber.c @@ -39,7 +39,7 @@ static WORD cbCount; static VOID init_funcs(void) { - HMODULE hKernel32 = GetModuleHandle("kernel32"); + HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); #define X(f) p##f = (void*)GetProcAddress(hKernel32, #f); X(CreateFiber); @@ -181,6 +181,35 @@ static void test_FiberLocalStorage(PFLS_CALLBACK_FUNCTION cbfunc) ok(ret, "FlsFree failed\n"); if (cbfunc) todo_wine ok(cbCount == 1, "Wrong callback count: %d\n", cbCount); + + /* test index 0 */ + SetLastError( 0xdeadbeef ); + val = pFlsGetValue( 0 ); + ok( !val, "fls index 0 set to %p\n", val ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "setting fls index wrong error %u\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pFlsSetValue( 0, (void *)0xdeadbeef ); + ok( !ret, "setting fls index 0 succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "setting fls index wrong error %u\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + val = pFlsGetValue( 0 ); + ok( !val, "fls index 0 wrong value %p\n", val ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "setting fls index wrong error %u\n", GetLastError() ); + + fls = pFlsAlloc( NULL ); + ok( fls != FLS_OUT_OF_INDEXES, "FlsAlloc failed\n" ); + ok( fls != 0, "fls index 0 allocated\n" ); + val = pFlsGetValue( fls ); + ok( !val, "fls index %u wrong value %p\n", fls, val ); + ret = pFlsSetValue( fls, (void *)0xdeadbeef ); + ok( ret, "setting fls index %u failed\n", fls ); + val = pFlsGetValue( fls ); + ok( val == (void *)0xdeadbeef, "fls index %u wrong value %p\n", fls, val ); + pFlsFree( fls ); + ret = pFlsSetValue( fls, (void *)0xdeadbabe ); + ok( ret, "setting fls index %u failed\n", fls ); + val = pFlsGetValue( fls ); + ok( val == (void *)0xdeadbabe, "fls index %u wrong value %p\n", fls, val ); } START_TEST(fiber) diff --git a/rostests/winetests/kernel32/file.c b/rostests/winetests/kernel32/file.c index d0a025c29aa..883aa57b355 100755 --- a/rostests/winetests/kernel32/file.c +++ b/rostests/winetests/kernel32/file.c @@ -21,7 +21,7 @@ */ /* ReplaceFile requires Windows 2000 or newer */ -#define _WIN32_WINNT 0x0600 +#define _WIN32_WINNT 0x0601 #include #include @@ -33,6 +33,7 @@ #include "winbase.h" #include "winerror.h" #include "winnls.h" +#include "fileapi.h" static HANDLE (WINAPI *pFindFirstFileExA)(LPCSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD); static BOOL (WINAPI *pReplaceFileA)(LPCSTR, LPCSTR, LPCSTR, DWORD, LPVOID, LPVOID); @@ -43,6 +44,8 @@ static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR static BOOL (WINAPI *pGetFileInformationByHandleEx)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD); static HANDLE (WINAPI *pOpenFileById)(HANDLE, LPFILE_ID_DESCRIPTOR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD); static BOOL (WINAPI *pSetFileValidData)(HANDLE, LONGLONG); +static HRESULT (WINAPI *pCopyFile2)(PCWSTR,PCWSTR,COPYFILE2_EXTENDED_PARAMETERS*); +static HANDLE (WINAPI *pCreateFile2)(LPCWSTR, DWORD, DWORD, DWORD, CREATEFILE2_EXTENDED_PARAMETERS*); /* keep filename and filenameW the same */ static const char filename[] = "testfile.xxx"; @@ -80,6 +83,8 @@ static void InitFunctionPointers(void) pGetFileInformationByHandleEx = (void *) GetProcAddress(hkernel32, "GetFileInformationByHandleEx"); pOpenFileById = (void *) GetProcAddress(hkernel32, "OpenFileById"); pSetFileValidData = (void *) GetProcAddress(hkernel32, "SetFileValidData"); + pCopyFile2 = (void *) GetProcAddress(hkernel32, "CopyFile2"); + pCreateFile2 = (void *) GetProcAddress(hkernel32, "CreateFile2"); } static void test__hread( void ) @@ -721,7 +726,7 @@ static void test_CopyFileA(void) ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n"); /* check error on copying over a mapped file that was opened with FILE_SHARE_READ */ - hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); ret = CopyFileA(source, dest, FALSE); @@ -735,7 +740,7 @@ static void test_CopyFileA(void) ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n"); /* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */ - hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); ret = CopyFileA(source, dest, FALSE); @@ -788,6 +793,234 @@ static void test_CopyFileW(void) ok(ret, "DeleteFileW: error %d\n", GetLastError()); } +static void test_CopyFile2(void) +{ + static const WCHAR doesntexistW[] = {'d','o','e','s','n','t','e','x','i','s','t',0}; + static const WCHAR prefix[] = {'p','f','x',0}; + WCHAR source[MAX_PATH], dest[MAX_PATH], temp_path[MAX_PATH]; + COPYFILE2_EXTENDED_PARAMETERS params; + HANDLE hfile, hmapfile; + FILETIME ft1, ft2; + DWORD ret, len; + char buf[10]; + HRESULT hr; + + if (!pCopyFile2) + { + skip("CopyFile2 is not available\n"); + return; + } + + ret = GetTempPathW(MAX_PATH, temp_path); + ok(ret != 0, "GetTempPathW error %d\n", GetLastError()); + ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); + + ret = GetTempFileNameW(temp_path, prefix, 0, source); + ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError()); + + ret = GetTempFileNameW(temp_path, prefix, 0, dest); + ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError()); + + /* fail if exists */ + memset(¶ms, 0, sizeof(params)); + params.dwSize = sizeof(params); + params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS; + + SetLastError(0xdeadbeef); + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "CopyFile2: unexpected error 0x%08x\n", hr); + ok(GetLastError() == ERROR_FILE_EXISTS, "CopyFile2: last error %d\n", GetLastError()); + + /* don't fail if exists */ + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == S_OK, "CopyFile2: error 0x%08x\n", hr); + + /* copying a file to itself must fail */ + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + + SetLastError(0xdeadbeef); + hr = pCopyFile2(source, source, ¶ms); + ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: copying a file to itself didn't fail, 0x%08x\n", hr); + ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError()); + + /* make the source have not zero size */ + hfile = CreateFileW(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 ); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n"); + ret = WriteFile(hfile, prefix, sizeof(prefix), &len, NULL ); + ok(ret && len == sizeof(prefix), "WriteFile error %d\n", GetLastError()); + ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n"); + + /* get the file time and change it to prove the difference */ + ret = GetFileTime(hfile, NULL, NULL, &ft1); + ok(ret, "GetFileTime error %d\n", GetLastError()); + ft1.dwLowDateTime -= 600000000; /* 60 second */ + ret = SetFileTime(hfile, NULL, NULL, &ft1); + ok(ret, "SetFileTime error %d\n", GetLastError()); + GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */ + CloseHandle(hfile); + + ret = GetTempFileNameW(temp_path, prefix, 0, dest); + ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS; + + SetLastError(0xdeadbeef); + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "CopyFile2: unexpected error 0x%08x\n", hr); + ok(GetLastError() == ERROR_FILE_EXISTS, "CopyFile2: last error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + hr = pCopyFile2(source, dest, ¶ms); + ok(ret, "CopyFile2: error 0x%08x\n", hr); + + /* copying from a read-locked source fails */ + hfile = CreateFileW(source, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + SetLastError(0xdeadbeef); + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr); + ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError()); + + /* in addition, the source is opened before the destination */ + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + SetLastError(0xdeadbeef); + hr = pCopyFile2(doesntexistW, dest, ¶ms); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "CopyFile2: last error %d\n", GetLastError()); + CloseHandle(hfile); + + /* copying from a r+w opened, r shared source succeeds */ + hfile = CreateFileW(source, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == S_OK, "failed 0x%08x\n", hr); + CloseHandle(hfile); + + /* copying from a delete-locked source mostly succeeds */ + hfile = CreateFileW(source, DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == S_OK, "failed 0x%08x\n", hr); + CloseHandle(hfile); + + /* copying to a write-locked destination fails */ + hfile = CreateFileW(dest, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + SetLastError(0xdeadbeef); + hr = pCopyFile2(source, dest, FALSE); + ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr); + ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError()); + CloseHandle(hfile); + + /* copying to a r+w opened, w shared destination mostly succeeds */ + hfile = CreateFileW(dest, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + hr = pCopyFile2(source, dest, FALSE); + ok(hr == S_OK, "got 0x%08x\n", hr); + CloseHandle(hfile); + + /* copying to a delete-locked destination fails, even when the destination is delete-shared */ + hfile = CreateFileW(dest, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + SetLastError(0xdeadbeef); + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr); + ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError()); + CloseHandle(hfile); + + /* copy to a file that's opened the way Wine opens the source */ + hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == S_OK, "got 0x%08x\n", hr); + CloseHandle(hfile); + + /* make sure that destination has correct size */ + hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n"); + ret = GetFileSize(hfile, NULL); + ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret); + + /* make sure that destination has the same filetime */ + ret = GetFileTime(hfile, NULL, NULL, &ft2); + ok(ret, "GetFileTime error %d\n", GetLastError()); + ok(CompareFileTime(&ft1, &ft2) == 0, "destination file has wrong filetime\n"); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + SetLastError(0xdeadbeef); + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr); + ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError()); + + /* make sure that destination still has correct size */ + ret = GetFileSize(hfile, NULL); + ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret); + ret = ReadFile(hfile, buf, sizeof(buf), &len, NULL); + ok(ret && len == sizeof(prefix), "ReadFile: error %d\n", GetLastError()); + ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n"); + + /* check error on copying over a mapped file that was opened with FILE_SHARE_READ */ + hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + SetLastError(0xdeadbeef); + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr); + ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError()); + + CloseHandle(hmapfile); + CloseHandle(hfile); + + hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n"); + + /* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */ + hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); + + params.dwSize = sizeof(params); + params.dwCopyFlags = 0; + hr = pCopyFile2(source, dest, ¶ms); + ok(hr == HRESULT_FROM_WIN32(ERROR_USER_MAPPED_FILE), "CopyFile2: unexpected error 0x%08x\n", hr); + ok(GetLastError() == ERROR_USER_MAPPED_FILE, "CopyFile2: last error %d\n", GetLastError()); + + CloseHandle(hmapfile); + CloseHandle(hfile); + + DeleteFileW(source); + DeleteFileW(dest); +} /* * Debugging routine to dump a buffer in a hexdump-like fashion. @@ -891,7 +1124,7 @@ static void test_CreateFileA(void) "LastError should have been ERROR_INVALID_NAME or ERROR_FILE_NOT_FOUND but got %u\n", GetLastError()); /* get windows drive letter */ - ret = GetWindowsDirectory(windowsdir, sizeof(windowsdir)); + ret = GetWindowsDirectoryA(windowsdir, sizeof(windowsdir)); ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n"); ok(ret != 0, "GetWindowsDirectory: error %d\n", GetLastError()); @@ -900,7 +1133,7 @@ static void test_CreateFileA(void) ok(ret != 0, "GetTempPathA error %d\n", GetLastError()); strcpy(dirname, temp_path); strcat(dirname, directory); - ret = CreateDirectory(dirname, NULL); + ret = CreateDirectoryA(dirname, NULL); ok( ret, "Createdirectory failed, gle=%d\n", GetLastError() ); /* set current drive & directory to known location */ SetCurrentDirectoryA( temp_path ); @@ -1258,6 +1491,87 @@ static void test_CreateFileW(void) ok(ret, "DeleteFileW: error %d\n", GetLastError()); } +static void test_CreateFile2(void) +{ + HANDLE hFile; + WCHAR temp_path[MAX_PATH]; + WCHAR filename[MAX_PATH]; + CREATEFILE2_EXTENDED_PARAMETERS exparams; + static const WCHAR emptyW[]={'\0'}; + static const WCHAR prefix[] = {'p','f','x',0}; + static const WCHAR bogus[] = { '\\', '\\', '.', '\\', 'B', 'O', 'G', 'U', 'S', 0 }; + DWORD ret; + + if (!pCreateFile2) + { + win_skip("CreateFile2 is missing\n"); + return; + } + + ret = GetTempPathW(MAX_PATH, temp_path); + ok(ret != 0, "GetTempPathW error %d\n", GetLastError()); + ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); + + ret = GetTempFileNameW(temp_path, prefix, 0, filename); + ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + exparams.dwSize = sizeof(exparams); + exparams.dwFileAttributes = FILE_FLAG_RANDOM_ACCESS; + exparams.dwFileFlags = 0; + exparams.dwSecurityQosFlags = 0; + exparams.lpSecurityAttributes = NULL; + exparams.hTemplateFile = 0; + hFile = pCreateFile2(filename, GENERIC_READ, 0, CREATE_NEW, &exparams); + ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS, + "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n"); + + SetLastError(0xdeadbeef); + hFile = pCreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, CREATE_ALWAYS, &exparams); + ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS, + "hFile %p, last error %u\n", hFile, GetLastError()); + CloseHandle(hFile); + + SetLastError(0xdeadbeef); + hFile = pCreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, OPEN_ALWAYS, &exparams); + ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS, + "hFile %p, last error %u\n", hFile, GetLastError()); + CloseHandle(hFile); + + ret = DeleteFileW(filename); + ok(ret, "DeleteFileW: error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + hFile = pCreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, OPEN_ALWAYS, &exparams); + ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0, + "hFile %p, last error %u\n", hFile, GetLastError()); + CloseHandle(hFile); + + ret = DeleteFileW(filename); + ok(ret, "DeleteFileW: error %d\n", GetLastError()); + + hFile = pCreateFile2(emptyW, GENERIC_READ, 0, CREATE_NEW, &exparams); + ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND, + "CreateFile2(\"\") returned ret=%p error=%d\n",hFile,GetLastError()); + + /* test the result of opening a nonexistent driver name */ + exparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; + hFile = pCreateFile2(bogus, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, &exparams); + ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND, + "CreateFile2 on invalid VxD name returned ret=%p error=%d\n",hFile,GetLastError()); + + ret = CreateDirectoryW(filename, NULL); + ok(ret == TRUE, "couldn't create temporary directory\n"); + exparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS; + hFile = pCreateFile2(filename, GENERIC_READ | GENERIC_WRITE, 0, OPEN_ALWAYS, &exparams); + todo_wine + ok(hFile == INVALID_HANDLE_VALUE, + "expected CreateFile2 to fail on existing directory, error: %d\n", GetLastError()); + CloseHandle(hFile); + ret = RemoveDirectoryW(filename); + ok(ret, "DeleteFileW: error %d\n", GetLastError()); +} + static void test_GetTempFileNameA(void) { UINT result; @@ -1266,7 +1580,7 @@ static void test_GetTempFileNameA(void) char windowsdir[MAX_PATH + 10]; char windowsdrive[3]; - result = GetWindowsDirectory(windowsdir, sizeof(windowsdir)); + result = GetWindowsDirectoryA(windowsdir, sizeof(windowsdir)); ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n"); ok(result != 0, "GetWindowsDirectory: error %d\n", GetLastError()); @@ -1318,24 +1632,36 @@ static void test_DeleteFileA( void ) GetLastError() == ERROR_INVALID_FUNCTION), "DeleteFileA(\"nul\") returned ret=%d error=%d\n",ret,GetLastError()); + ret = DeleteFileA("nonexist.txt"); + ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "DeleteFileA(\"nonexist.txt\") returned ret=%d error=%d\n",ret,GetLastError()); + GetTempPathA(MAX_PATH, temp_path); - GetTempFileName(temp_path, "tst", 0, temp_file); + GetTempFileNameA(temp_path, "tst", 0, temp_file); SetLastError(0xdeadbeef); - hfile = CreateFile(temp_file, GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + hfile = CreateFileA(temp_file, GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); ok(hfile != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); SetLastError(0xdeadbeef); - ret = DeleteFile(temp_file); + ret = DeleteFileA(temp_file); todo_wine ok(ret, "DeleteFile error %d\n", GetLastError()); SetLastError(0xdeadbeef); ret = CloseHandle(hfile); ok(ret, "CloseHandle error %d\n", GetLastError()); - ret = DeleteFile(temp_file); + ret = DeleteFileA(temp_file); todo_wine ok(!ret, "DeleteFile should fail\n"); + + SetLastError(0xdeadbeef); + ret = CreateDirectoryA("testdir", NULL); + ok(ret, "CreateDirectory failed, got err %d\n", GetLastError()); + ret = DeleteFileA("testdir"); + ok(!ret && GetLastError() == ERROR_ACCESS_DENIED, + "Expected ERROR_ACCESS_DENIED, got error %d\n", GetLastError()); + ret = RemoveDirectoryA("testdir"); + ok(ret, "Remove a directory failed, got error %d\n", GetLastError()); } static void test_DeleteFileW( void ) @@ -1426,7 +1752,7 @@ static void test_MoveFileA(void) ok( retok && ret == sizeof(prefix), "WriteFile error %d\n", GetLastError()); - hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); ret = MoveFileA(source, dest); @@ -1441,12 +1767,12 @@ static void test_MoveFileA(void) CloseHandle(hfile); /* if MoveFile succeeded, move back to dest */ - if (ret) MoveFile(dest, source); + if (ret) MoveFileA(dest, source); hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n"); - hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); ret = MoveFileA(source, dest); @@ -1461,7 +1787,7 @@ static void test_MoveFileA(void) CloseHandle(hfile); /* if MoveFile succeeded, move back to dest */ - if (ret) MoveFile(dest, source); + if (ret) MoveFileA(dest, source); ret = MoveFileA(source, dest); ok(ret, "MoveFileA: failed, error %d\n", GetLastError()); @@ -1833,7 +2159,7 @@ static unsigned int map_file_access( unsigned int access ) return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); } -static int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2 ) +static BOOL is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2 ) { access1 = map_file_access( access1 ); access2 = map_file_access( access2 ); @@ -1843,22 +2169,22 @@ static int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, if (!access1) sharing1 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE; if (!access2) sharing2 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE; - if ((access1 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing2 & FILE_SHARE_READ)) return 0; - if ((access1 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing2 & FILE_SHARE_WRITE)) return 0; - if ((access1 & DELETE) && !(sharing2 & FILE_SHARE_DELETE)) return 0; - if ((access2 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing1 & FILE_SHARE_READ)) return 0; - if ((access2 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing1 & FILE_SHARE_WRITE)) return 0; - if ((access2 & DELETE) && !(sharing1 & FILE_SHARE_DELETE)) return 0; - return 1; + if ((access1 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing2 & FILE_SHARE_READ)) return FALSE; + if ((access1 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing2 & FILE_SHARE_WRITE)) return FALSE; + if ((access1 & DELETE) && !(sharing2 & FILE_SHARE_DELETE)) return FALSE; + if ((access2 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing1 & FILE_SHARE_READ)) return FALSE; + if ((access2 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing1 & FILE_SHARE_WRITE)) return FALSE; + if ((access2 & DELETE) && !(sharing1 & FILE_SHARE_DELETE)) return FALSE; + return TRUE; } -static int is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 ) +static BOOL is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 ) { if ((map_access == PAGE_READWRITE || map_access == PAGE_EXECUTE_READWRITE) && - !(sharing2 & FILE_SHARE_WRITE)) return 0; + !(sharing2 & FILE_SHARE_WRITE)) return FALSE; access2 = map_file_access( access2 ); - if ((map_access & SEC_IMAGE) && (access2 & FILE_WRITE_DATA)) return 0; - return 1; + if ((map_access & SEC_IMAGE) && (access2 & FILE_WRITE_DATA)) return FALSE; + return TRUE; } static void test_file_sharing(void) @@ -2039,7 +2365,7 @@ static void test_file_sharing(void) static char get_windows_drive(void) { char windowsdir[MAX_PATH]; - GetWindowsDirectory(windowsdir, sizeof(windowsdir)); + GetWindowsDirectoryA(windowsdir, sizeof(windowsdir)); return windowsdir[0]; } @@ -2074,7 +2400,7 @@ static void test_FindFirstFileA(void) ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 ); /* try FindFirstFileA on windows dir */ - GetWindowsDirectory( buffer2, sizeof(buffer2) ); + GetWindowsDirectoryA( buffer2, sizeof(buffer2) ); strcat(buffer2, "\\*"); handle = FindFirstFileA(buffer2, &data); ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 ); @@ -2099,18 +2425,26 @@ static void test_FindFirstFileA(void) strcat(buffer2, "\\"); handle = FindFirstFileA(buffer2, &data); err = GetLastError(); - ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 ); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); todo_wine { ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err ); } + /* try FindFirstFileA without trailing backslash */ + SetLastError( 0xdeadbeaf ); + strcpy(buffer2, nonexistent); + handle = FindFirstFileA(buffer2, &data); + err = GetLastError(); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); + ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err ); + /* try FindFirstFileA on "C:\foo\bar.txt" */ SetLastError( 0xdeadbeaf ); strcpy(buffer2, nonexistent); strcat(buffer2, "\\bar.txt"); handle = FindFirstFileA(buffer2, &data); err = GetLastError(); - ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 ); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err ); /* try FindFirstFileA on "C:\foo\*.*" */ @@ -2119,7 +2453,7 @@ static void test_FindFirstFileA(void) strcat(buffer2, "\\*.*"); handle = FindFirstFileA(buffer2, &data); err = GetLastError(); - ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 ); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err ); /* try FindFirstFileA on "foo\bar.txt" */ @@ -2128,7 +2462,7 @@ static void test_FindFirstFileA(void) strcat(buffer2, "\\bar.txt"); handle = FindFirstFileA(buffer2, &data); err = GetLastError(); - ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 ); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err ); /* try FindFirstFileA on "c:\nul" */ @@ -2178,7 +2512,7 @@ static void test_FindFirstFileA(void) strcat(buffer2, "nul\\*"); handle = FindFirstFileA(buffer2, &data); err = GetLastError(); - ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 ); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err ); /* try FindFirstFileA on "c:\nul*" */ @@ -2187,7 +2521,7 @@ static void test_FindFirstFileA(void) strcat(buffer2, "nul*"); handle = FindFirstFileA(buffer2, &data); err = GetLastError(); - ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 ); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err ); /* try FindFirstFileA on "c:\foo\bar\nul" */ @@ -2196,7 +2530,7 @@ static void test_FindFirstFileA(void) strcat(buffer2, "foo\\bar\\nul"); handle = FindFirstFileA(buffer2, &data); err = GetLastError(); - ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 ); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err ); /* try FindFirstFileA on "c:\foo\nul\bar" */ @@ -2205,7 +2539,7 @@ static void test_FindFirstFileA(void) strcat(buffer2, "foo\\nul\\bar"); handle = FindFirstFileA(buffer2, &data); err = GetLastError(); - ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 ); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err ); } @@ -2219,7 +2553,7 @@ static void test_FindNextFileA(void) buffer[0] = get_windows_drive(); handle = FindFirstFileA(buffer,&search_results); ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" ); - while (FindNextFile(handle, &search_results)) + while (FindNextFileA(handle, &search_results)) { /* get to the end of the files */ } @@ -2256,14 +2590,14 @@ static void test_FindFirstFileExA(FINDEX_SEARCH_OPS search_ops) #define CHECK_NAME(fn) (strcmp((fn), "file1") == 0 || strcmp((fn), "file2") == 0 || strcmp((fn), "dir1") == 0) - ok(FindNextFile(handle, &search_results), "Fetching second file failed\n"); + ok(FindNextFileA(handle, &search_results), "Fetching second file failed\n"); ok(strcmp(search_results.cFileName, "..") == 0, "Second entry should be '..' is %s\n", search_results.cFileName); - ok(FindNextFile(handle, &search_results), "Fetching third file failed\n"); + ok(FindNextFileA(handle, &search_results), "Fetching third file failed\n"); ok(CHECK_NAME(search_results.cFileName), "Invalid third entry - %s\n", search_results.cFileName); SetLastError(0xdeadbeef); - ret = FindNextFile(handle, &search_results); + ret = FindNextFileA(handle, &search_results); if (!ret && (GetLastError() == ERROR_NO_MORE_FILES) && (search_ops == FindExSearchLimitToDirectories)) { skip("File system supports directory filtering\n"); @@ -2276,12 +2610,12 @@ static void test_FindFirstFileExA(FINDEX_SEARCH_OPS search_ops) ok(ret, "Fetching fourth file failed\n"); ok(CHECK_NAME(search_results.cFileName), "Invalid fourth entry - %s\n", search_results.cFileName); - ok(FindNextFile(handle, &search_results), "Fetching fifth file failed\n"); + ok(FindNextFileA(handle, &search_results), "Fetching fifth file failed\n"); ok(CHECK_NAME(search_results.cFileName), "Invalid fifth entry - %s\n", search_results.cFileName); #undef CHECK_NAME - ok(FindNextFile(handle, &search_results) == FALSE, "Fetching sixth file should fail\n"); + ok(FindNextFileA(handle, &search_results) == FALSE, "Fetching sixth file should fail\n"); FindClose( handle ); @@ -2295,8 +2629,8 @@ cleanup: static int test_Mapfile_createtemp(HANDLE *handle) { SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL); - DeleteFile(filename); - *handle = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, 0, + DeleteFileA(filename); + *handle = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (*handle != INVALID_HANDLE_VALUE) { @@ -2313,14 +2647,14 @@ static void test_MapFile(void) ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n"); - hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" ); + hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" ); ok( hmap != NULL, "mapping should work, I named it!\n" ); ok( CloseHandle( hmap ), "can't close mapping handle\n"); /* We have to close file before we try new stuff with mapping again. Else we would always succeed on XP or block descriptors on 95. */ - hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL ); + hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL ); ok( hmap != NULL, "We should still be able to map!\n" ); ok( CloseHandle( hmap ), "can't close mapping handle\n"); ok( CloseHandle( handle ), "can't close file handle\n"); @@ -2328,17 +2662,17 @@ static void test_MapFile(void) ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n"); - hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL ); + hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL ); ok( hmap == NULL, "mapped zero size file\n"); ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n"); - hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL ); + hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL ); ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n"); /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */ if ( hmap ) CloseHandle( hmap ); - hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL ); + hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL ); ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n"); /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */ if ( hmap ) @@ -2352,7 +2686,7 @@ static void test_MapFile(void) static void test_GetFileType(void) { - DWORD type; + DWORD type, type2; HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename ); type = GetFileType(h); @@ -2364,6 +2698,11 @@ static void test_GetFileType(void) ok( type == FILE_TYPE_CHAR, "expected type char for nul got %d\n", type ); CloseHandle( h ); DeleteFileA( filename ); + h = GetStdHandle( STD_OUTPUT_HANDLE ); + ok( h != INVALID_HANDLE_VALUE, "GetStdHandle failed\n" ); + type = GetFileType( (HANDLE)STD_OUTPUT_HANDLE ); + type2 = GetFileType( h ); + ok(type == type2, "expected type %d for STD_OUTPUT_HANDLE got %d\n", type2, type); } static int completion_count; @@ -2830,7 +3169,7 @@ static void test_overlapped(void) ok( result == 0, "wrong result %u\n", result ); SetLastError( 0xb00 ); - ov.hEvent = CreateEvent( NULL, 1, 1, NULL ); + ov.hEvent = CreateEventW( NULL, 1, 1, NULL ); ov.Internal = STATUS_PENDING; ov.InternalHigh = 0xabcd; r = GetOverlappedResult(0, &ov, &result, 0); @@ -2857,19 +3196,19 @@ static void test_RemoveDirectory(void) int rc; char directory[] = "removeme"; - rc = CreateDirectory(directory, NULL); + rc = CreateDirectoryA(directory, NULL); ok( rc, "Createdirectory failed, gle=%d\n", GetLastError() ); - rc = SetCurrentDirectory(directory); + rc = SetCurrentDirectoryA(directory); ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() ); - rc = RemoveDirectory("."); + rc = RemoveDirectoryA("."); if (!rc) { - rc = SetCurrentDirectory(".."); + rc = SetCurrentDirectoryA(".."); ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() ); - rc = RemoveDirectory(directory); + rc = RemoveDirectoryA(directory); ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() ); } } @@ -3179,7 +3518,7 @@ static void test_ReplaceFileW(void) } } -static void test_CreatFile(void) +static void test_CreateFile(void) { static const struct test_data { @@ -3211,20 +3550,61 @@ static void test_CreatFile(void) /* 22*/ { TRUNCATE_EXISTING, 0, ERROR_INVALID_PARAMETER, 0 }, /* 23*/ { TRUNCATE_EXISTING, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 }, /* 24*/ { TRUNCATE_EXISTING, GENERIC_WRITE, 0, 0 }, - /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 } + /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 }, + /* 26*/ { TRUNCATE_EXISTING, FILE_WRITE_DATA, ERROR_INVALID_PARAMETER, 0 } }; char temp_path[MAX_PATH]; char file_name[MAX_PATH]; DWORD i, ret, written; HANDLE hfile; - GetTempPath(MAX_PATH, temp_path); - GetTempFileName(temp_path, "tmp", 0, file_name); + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "tmp", 0, file_name); + + i = strlen(temp_path); + if (i && temp_path[i - 1] == '\\') temp_path[i - 1] = 0; + + for (i = 0; i <= 5; i++) + { + SetLastError(0xdeadbeef); + hfile = CreateFileA(temp_path, GENERIC_READ, 0, NULL, i, 0, 0); + ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n"); + if (i == 0 || i == 5) + { +/* FIXME: remove once Wine is fixed */ +if (i == 5) todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError()); +else + ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError()); + } + else + { +/* FIXME: remove once Wine is fixed */ +if (i == 1) todo_wine + ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError()); +else + ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError()); + } + + SetLastError(0xdeadbeef); + hfile = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, i, 0, 0); + ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n"); + if (i == 0) + ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError()); + else + { +/* FIXME: remove once Wine is fixed */ +if (i == 1) todo_wine + ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError()); +else + ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError()); + } + } for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) { SetLastError(0xdeadbeef); - hfile = CreateFile(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0); + hfile = CreateFileA(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0); if (!td[i].error) { ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError()); @@ -3232,7 +3612,7 @@ static void test_CreatFile(void) SetLastError(0xdeadbeef); ret = WriteFile(hfile, &td[i].error, sizeof(td[i].error), &written, NULL); if (td[i].access & GENERIC_WRITE) - ok(ret, "%d: WriteFile error %d\n", i, GetLastError()); + ok(ret, "%d: WriteFile error %d\n", i, GetLastError()); else { ok(!ret, "%d: WriteFile should fail\n", i); @@ -3259,10 +3639,10 @@ static void test_CreatFile(void) } } - if (td[i].clean_up) DeleteFile(file_name); + if (td[i].clean_up) DeleteFileA(file_name); } - DeleteFile(file_name); + DeleteFileA(file_name); } static void test_GetFileInformationByHandleEx(void) @@ -3335,7 +3715,7 @@ static void test_GetFileInformationByHandleEx(void) } CloseHandle(directory); - DeleteFile(tempFileName); + DeleteFileA(tempFileName); } static void test_OpenFileById(void) @@ -3439,7 +3819,7 @@ static void test_OpenFileById(void) CloseHandle(handle); CloseHandle(directory); - DeleteFile(tempFileName); + DeleteFileA(tempFileName); } static void test_SetFileValidData(void) @@ -3503,12 +3883,13 @@ static void test_SetFileValidData(void) privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token) || - !LookupPrivilegeValue(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) || + !LookupPrivilegeValueA(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) || !AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL) || GetLastError() == ERROR_NOT_ALL_ASSIGNED) { win_skip("cannot enable SE_MANAGE_VOLUME_NAME privilege\n"); CloseHandle(token); + DeleteFileA(filename); return; } handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); @@ -3572,8 +3953,139 @@ static void test_SetFileValidData(void) privs.Privileges[0].Attributes = 0; AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL); + CloseHandle(token); - DeleteFile(filename); + CloseHandle(handle); + DeleteFileA(filename); +} + +static unsigned file_map_access(unsigned access) +{ + if (access & GENERIC_READ) access |= FILE_GENERIC_READ; + if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; + if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; + if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + +static BOOL is_access_compatible(unsigned obj_access, unsigned desired_access) +{ + obj_access = file_map_access(obj_access); + desired_access = file_map_access(desired_access); + return (obj_access & desired_access) == desired_access; +} + +static void test_file_access(void) +{ + static const struct + { + unsigned access, create_error, write_error, read_error; + } td[] = + { + { GENERIC_READ | GENERIC_WRITE, 0, 0, 0 }, + { GENERIC_WRITE, 0, 0, ERROR_ACCESS_DENIED }, + { GENERIC_READ, 0, ERROR_ACCESS_DENIED, 0 }, + { FILE_READ_DATA | FILE_WRITE_DATA, 0, 0, 0 }, + { FILE_WRITE_DATA, 0, 0, ERROR_ACCESS_DENIED }, + { FILE_READ_DATA, 0, ERROR_ACCESS_DENIED, 0 }, + { FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED }, + { FILE_READ_DATA | FILE_APPEND_DATA, 0, 0, 0 }, + { FILE_WRITE_DATA | FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED }, + { 0, 0, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED }, + }; + char path[MAX_PATH], fname[MAX_PATH]; + unsigned char buf[16]; + HANDLE hfile, hdup; + DWORD i, j, ret, bytes; + + GetTempPathA(MAX_PATH, path); + GetTempFileNameA(path, "foo", 0, fname); + + for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) + { + SetLastError(0xdeadbeef); + hfile = CreateFileA(fname, td[i].access, 0, NULL, CREATE_ALWAYS, + FILE_FLAG_DELETE_ON_CLOSE, 0); + if (td[i].create_error) + { + ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i); + ok(td[i].create_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].create_error, GetLastError()); + continue; + } + else + ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError()); + + for (j = 0; j < sizeof(td)/sizeof(td[0]); j++) + { + SetLastError(0xdeadbeef); + ret = DuplicateHandle(GetCurrentProcess(), hfile, GetCurrentProcess(), &hdup, + td[j].access, 0, 0); + if (is_access_compatible(td[i].access, td[j].access)) + ok(ret, "DuplicateHandle(%#x => %#x) error %d\n", td[i].access, td[j].access, GetLastError()); + else + { + /* FIXME: Remove once Wine is fixed */ + if ((td[j].access & (GENERIC_READ | GENERIC_WRITE)) || + (!(td[i].access & (GENERIC_WRITE | FILE_WRITE_DATA)) && (td[j].access & FILE_WRITE_DATA)) || + (!(td[i].access & (GENERIC_READ | FILE_READ_DATA)) && (td[j].access & FILE_READ_DATA)) || + (!(td[i].access & (GENERIC_WRITE)) && (td[j].access & FILE_APPEND_DATA))) + { +todo_wine + ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access); +todo_wine + ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + } + else + { + ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access); + ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + } + } + if (ret) CloseHandle(hdup); + } + + SetLastError(0xdeadbeef); + bytes = 0xdeadbeef; + ret = WriteFile(hfile, "\x5e\xa7", 2, &bytes, NULL); + if (td[i].write_error) + { + ok(!ret, "%d: WriteFile should fail\n", i); + ok(td[i].write_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].write_error, GetLastError()); + ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes); + } + else + { + ok(ret, "%d: WriteFile error %d\n", i, GetLastError()); + ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes); + } + + SetLastError(0xdeadbeef); + ret = SetFilePointer(hfile, 0, NULL, FILE_BEGIN); + ok(ret != INVALID_SET_FILE_POINTER, "SetFilePointer error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + bytes = 0xdeadbeef; + ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL); + if (td[i].read_error) + { + ok(!ret, "%d: ReadFile should fail\n", i); + ok(td[i].read_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].read_error, GetLastError()); + ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes); + } + else + { + ok(ret, "%d: ReadFile error %d\n", i, GetLastError()); + if (td[i].write_error) + ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes); + else + { + ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes); + ok(buf[0] == 0x5e && buf[1] == 0xa7, "%d: expected 5ea7, got %02x%02x\n", i, buf[0], buf[1]); + } + } + + CloseHandle(hfile); + } } START_TEST(file) @@ -3591,9 +4103,11 @@ START_TEST(file) test_GetTempFileNameA(); test_CopyFileA(); test_CopyFileW(); - test_CreatFile(); + test_CopyFile2(); + test_CreateFile(); test_CreateFileA(); test_CreateFileW(); + test_CreateFile2(); test_DeleteFileA(); test_DeleteFileW(); test_MoveFileA(); @@ -3618,4 +4132,5 @@ START_TEST(file) test_GetFileInformationByHandleEx(); test_OpenFileById(); test_SetFileValidData(); + test_file_access(); } diff --git a/rostests/winetests/kernel32/format_msg.c b/rostests/winetests/kernel32/format_msg.c index 005e6c4a66c..e98e08372d1 100755 --- a/rostests/winetests/kernel32/format_msg.c +++ b/rostests/winetests/kernel32/format_msg.c @@ -1543,7 +1543,7 @@ static void test_message_from_hmodule(void) HMODULE h; CHAR out[0x100] = {0}; - h = GetModuleHandle("kernel32.dll"); + h = GetModuleHandleA("kernel32.dll"); ok(h != 0, "GetModuleHandle failed\n"); /*Test existing messageID; as the message strings from wine's kernel32 differ from windows' kernel32 we don't compare diff --git a/rostests/winetests/kernel32/heap.c b/rostests/winetests/kernel32/heap.c index e36336cdd14..a36c373c1a7 100755 --- a/rostests/winetests/kernel32/heap.c +++ b/rostests/winetests/kernel32/heap.c @@ -1,6 +1,7 @@ /* * Unit test suite for heap functions * + * Copyright 2002 Geoffrey Hausheer * Copyright 2003 Dimitrie O. Paun * Copyright 2006 Detlef Riekenberg * @@ -56,7 +57,7 @@ static SIZE_T resize_9x(SIZE_T size) static void test_sized_HeapAlloc(int nbytes) { - int success; + BOOL success; char *buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbytes); ok(buf != NULL, "allocate failed\n"); ok(buf[0] == 0, "buffer not zeroed\n"); @@ -66,7 +67,7 @@ static void test_sized_HeapAlloc(int nbytes) static void test_sized_HeapReAlloc(int nbytes1, int nbytes2) { - int success; + BOOL success; char *buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbytes1); ok(buf != NULL, "allocate failed\n"); ok(buf[0] == 0, "buffer not zeroed\n"); @@ -480,6 +481,278 @@ static void test_heap(void) } + +static void test_HeapCreate(void) +{ + SYSTEM_INFO sysInfo; + ULONG memchunk; + HANDLE heap; + LPVOID mem1,mem1a,mem3; + UCHAR *mem2,*mem2a; + UINT i; + BOOL error; + DWORD dwSize; + + /* Retrieve the page size for this system */ + GetSystemInfo(&sysInfo); + ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n"); + + /* Create a Heap with a minimum and maximum size */ + /* Note that Windows and Wine seem to behave a bit differently with respect + to memory allocation. In Windows, you can't access all the memory + specified in the heap (due to overhead), so choosing a reasonable maximum + size for the heap was done mostly by trial-and-error on Win2k. It may need + more tweaking for otherWindows variants. + */ + memchunk=10*sysInfo.dwPageSize; + heap=HeapCreate(0,2*memchunk,5*memchunk); + ok( !((ULONG_PTR)heap & 0xffff), "heap %p not 64K aligned\n", heap ); + + /* Check that HeapCreate allocated the right amount of ram */ + mem1=HeapAlloc(heap,0,5*memchunk+1); + ok(mem1==NULL,"HeapCreate allocated more Ram than it should have\n"); + HeapFree(heap,0,mem1); + + /* Check that a normal alloc works */ + mem1=HeapAlloc(heap,0,memchunk); + ok(mem1!=NULL,"HeapAlloc failed\n"); + if(mem1) { + ok(HeapSize(heap,0,mem1)>=memchunk, "HeapAlloc should return a big enough memory block\n"); + } + + /* Check that a 'zeroing' alloc works */ + mem2=HeapAlloc(heap,HEAP_ZERO_MEMORY,memchunk); + ok(mem2!=NULL,"HeapAlloc failed\n"); + if(mem2) { + ok(HeapSize(heap,0,mem2)>=memchunk,"HeapAlloc should return a big enough memory block\n"); + error=FALSE; + for(i=0;i=memchunk+5*sysInfo.dwPageSize,"HeapReAlloc failed\n"); + error=FALSE; + for(i=0;i<5*sysInfo.dwPageSize;i++) { + if(mem2a[memchunk+i]!=0) { + error=TRUE; + } + } + ok(!error,"HeapReAlloc should have zeroed out its allocated memory\n"); + } + + /* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */ + error=FALSE; + mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize); + if(mem1a!=NULL) { + if(mem1a!=mem1) { + error=TRUE; + } + } + ok(mem1a==NULL || !error,"HeapReAlloc didn't honour HEAP_REALLOC_IN_PLACE_ONLY\n"); + + /* Check that HeapFree works correctly */ + if(mem1a) { + ok(HeapFree(heap,0,mem1a),"HeapFree failed\n"); + } else { + ok(HeapFree(heap,0,mem1),"HeapFree failed\n"); + } + if(mem2a) { + ok(HeapFree(heap,0,mem2a),"HeapFree failed\n"); + } else { + ok(HeapFree(heap,0,mem2),"HeapFree failed\n"); + } + + /* 0-length buffer */ + mem1 = HeapAlloc(heap, 0, 0); + ok(mem1 != NULL, "Reserved memory\n"); + + dwSize = HeapSize(heap, 0, mem1); + /* should work with 0-length buffer */ + ok(dwSize < 0xFFFFFFFF, "The size of the 0-length buffer\n"); + ok(HeapFree(heap, 0, mem1), "Freed the 0-length buffer\n"); + + /* Check that HeapDestroy works */ + ok(HeapDestroy(heap),"HeapDestroy failed\n"); +} + + +static void test_GlobalAlloc(void) +{ + ULONG memchunk; + HGLOBAL mem1,mem2,mem2a,mem2b; + UCHAR *mem2ptr; + UINT i; + BOOL error; + memchunk=100000; + + SetLastError(NO_ERROR); + /* Check that a normal alloc works */ + mem1=GlobalAlloc(0,memchunk); + ok(mem1!=NULL,"GlobalAlloc failed\n"); + if(mem1) { + ok(GlobalSize(mem1)>=memchunk, "GlobalAlloc should return a big enough memory block\n"); + } + + /* Check that a 'zeroing' alloc works */ + mem2=GlobalAlloc(GMEM_ZEROINIT,memchunk); + ok(mem2!=NULL,"GlobalAlloc failed: error=%d\n",GetLastError()); + if(mem2) { + ok(GlobalSize(mem2)>=memchunk,"GlobalAlloc should return a big enough memory block\n"); + mem2ptr=GlobalLock(mem2); + ok(mem2ptr==mem2,"GlobalLock should have returned the same memory as was allocated\n"); + if(mem2ptr) { + error=FALSE; + for(i=0;i=2*memchunk,"GlobalReAlloc failed\n"); + mem2ptr=GlobalLock(mem2a); + ok(mem2ptr!=NULL,"GlobalLock Failed\n"); + if(mem2ptr) { + error=FALSE; + for(i=0;i=memchunk, "LocalAlloc should return a big enough memory block\n"); + } + + /* Check that a 'zeroing' and lock alloc works */ + mem2=LocalAlloc(LMEM_ZEROINIT|LMEM_MOVEABLE,memchunk); + ok(mem2!=NULL,"LocalAlloc failed: error=%d\n",GetLastError()); + if(mem2) { + ok(LocalSize(mem2)>=memchunk,"LocalAlloc should return a big enough memory block\n"); + mem2ptr=LocalLock(mem2); + ok(mem2ptr!=NULL,"LocalLock: error=%d\n",GetLastError()); + if(mem2ptr) { + error=FALSE; + for(i=0;i=2*memchunk,"LocalReAlloc failed\n"); + mem2ptr=LocalLock(mem2a); + ok(mem2ptr!=NULL,"LocalLock Failed\n"); + if(mem2ptr) { + error=FALSE; + for(i=0;i #include #include @@ -28,6 +29,10 @@ #include "winbase.h" #include "winternl.h" #include "wine/test.h" +#include "delayloadhandler.h" + +/* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */ +#define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000) #define ALIGN_SIZE(size, alignment) (((size) + (alignment - 1)) & ~((alignment - 1))) @@ -41,9 +46,12 @@ struct PROCESS_BASIC_INFORMATION_PRIVATE ULONG_PTR InheritedFromUniqueProcessId; }; -static BOOL is_child; static LONG *child_failures; +static WORD cb_count; +static DWORD page_size; +static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, + const LARGE_INTEGER *, ULONG, ULONG, HANDLE ); static NTSTATUS (WINAPI *pNtMapViewOfSection)(HANDLE, HANDLE, PVOID *, ULONG, SIZE_T, const LARGE_INTEGER *, SIZE_T *, ULONG, ULONG, ULONG); static NTSTATUS (WINAPI *pNtUnmapViewOfSection)(HANDLE, PVOID); static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); @@ -57,6 +65,9 @@ static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG *, ULONG *); static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG); static void (WINAPI *pRtlAcquirePebLock)(void); static void (WINAPI *pRtlReleasePebLock)(void); +static PVOID (WINAPI *pResolveDelayLoadedAPI)(PVOID, PCIMAGE_DELAYLOAD_DESCRIPTOR, + PDELAYLOAD_FAILURE_DLL_CALLBACK, PVOID, + PIMAGE_THUNK_DATA ThunkAddress,ULONG); static PVOID RVAToAddr(DWORD_PTR rva, HMODULE module) { @@ -65,15 +76,7 @@ static PVOID RVAToAddr(DWORD_PTR rva, HMODULE module) return ((char*) module) + rva; } -static const struct -{ - WORD e_magic; /* 00: MZ Header signature */ - WORD unused[29]; - DWORD e_lfanew; /* 3c: Offset to extended header */ -} dos_header = -{ - IMAGE_DOS_SIGNATURE, { 0 }, sizeof(dos_header) -}; +static IMAGE_DOS_HEADER dos_header; static IMAGE_NT_HEADERS nt_header = { @@ -149,11 +152,107 @@ static IMAGE_SECTION_HEADER section = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ, /* Characteristics */ }; + +static const char filler[0x1000]; +static const char section_data[0x10] = "section data"; + +static DWORD create_test_dll( const IMAGE_DOS_HEADER *dos_header, UINT dos_size, + const IMAGE_NT_HEADERS *nt_header, const char *dll_name ) +{ + DWORD dummy, size, file_align; + HANDLE hfile; + BOOL ret; + + hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0); + if (hfile == INVALID_HANDLE_VALUE) return 0; + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, dos_header, dos_size, &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + if (nt_header->FileHeader.SizeOfOptionalHeader) + { + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, &nt_header->OptionalHeader, + min(nt_header->FileHeader.SizeOfOptionalHeader, sizeof(IMAGE_OPTIONAL_HEADER)), + &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + if (nt_header->FileHeader.SizeOfOptionalHeader > sizeof(IMAGE_OPTIONAL_HEADER)) + { + file_align = nt_header->FileHeader.SizeOfOptionalHeader - sizeof(IMAGE_OPTIONAL_HEADER); + assert(file_align < sizeof(filler)); + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, filler, file_align, &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + } + } + + assert(nt_header->FileHeader.NumberOfSections <= 1); + if (nt_header->FileHeader.NumberOfSections) + { + if (nt_header->OptionalHeader.SectionAlignment >= page_size) + { + section.PointerToRawData = dos_size; + section.VirtualAddress = nt_header->OptionalHeader.SectionAlignment; + section.Misc.VirtualSize = section.SizeOfRawData * 10; + } + else + { + section.PointerToRawData = nt_header->OptionalHeader.SizeOfHeaders; + section.VirtualAddress = nt_header->OptionalHeader.SizeOfHeaders; + section.Misc.VirtualSize = 5; + } + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, §ion, sizeof(section), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + /* section data */ + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, section_data, sizeof(section_data), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + } + size = GetFileSize(hfile, NULL); + CloseHandle(hfile); + return size; +} + +/* helper to test image section mapping */ +static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header ) +{ + char temp_path[MAX_PATH]; + char dll_name[MAX_PATH]; + LARGE_INTEGER size; + HANDLE file, map; + NTSTATUS status; + + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "ldr", 0, dll_name); + + size.u.LowPart = create_test_dll( &dos_header, sizeof(dos_header), nt_header, dll_name ); + ok( size.u.LowPart, "could not create %s\n", dll_name); + size.u.HighPart = 0; + + file = CreateFileA(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + + status = pNtCreateSection(&map, STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ, NULL, &size, + PAGE_READONLY, SEC_IMAGE, file ); + if (map) CloseHandle( map ); + CloseHandle( file ); + DeleteFileA( dll_name ); + return status; +} + + static void test_Loader(void) { static const struct test_data { - const void *dos_header; DWORD size_of_dos_header; WORD number_of_sections, size_of_optional_header; DWORD section_alignment, file_alignment; @@ -161,47 +260,47 @@ static void test_Loader(void) DWORD errors[4]; /* 0 means LoadLibrary should succeed */ } td[] = { - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 1, 0, 0, 0, 0, 0, { ERROR_BAD_EXE_FORMAT } }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x1000, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0xe00, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER), { ERROR_BAD_EXE_FORMAT } /* XP doesn't like too small image size */ }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x1000, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x1000, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER), { ERROR_SUCCESS } }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x1000, 0x1f00, 0x1000, { ERROR_SUCCESS } }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x200, 0x200, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x200, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER), { ERROR_SUCCESS, ERROR_INVALID_ADDRESS } /* vista is more strict */ }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x200, 0x1000, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x1000, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER), { ERROR_BAD_EXE_FORMAT } /* XP doesn't like alignments */ }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x200, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x1000, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER), { ERROR_SUCCESS } }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x200, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x1000, 0x200, @@ -210,66 +309,66 @@ static void test_Loader(void) /* Mandatory are all fields up to SizeOfHeaders, everything else * is really optional (at least that's true for XP). */ - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 1, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200, sizeof(dos_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum) + sizeof(IMAGE_SECTION_HEADER) + 0x10, sizeof(dos_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum) + sizeof(IMAGE_SECTION_HEADER), { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT, ERROR_INVALID_ADDRESS, ERROR_NOACCESS } }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200, 0xd0, /* beyond of the end of file */ 0xc0, /* beyond of the end of file */ { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */ }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200, 0x1000, 0, { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */ }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200, 1, 0, { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */ }, #if 0 /* not power of 2 alignments need more test cases */ - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x300, 0x300, 1, 0, { ERROR_BAD_EXE_FORMAT } /* alignment is not power of 2 */ }, #endif - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 4, 4, 1, 0, { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */ }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 1, 1, 1, 0, { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */ }, - { &dos_header, sizeof(dos_header), + { sizeof(dos_header), 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200, 0, 0, { ERROR_BAD_EXE_FORMAT } /* image size == 0 -> failure */ }, /* the following data mimics the PE image which upack creates */ - { &dos_header, 0x10, + { 0x10, 1, 0x148, 0x1000, 0x200, sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x1000, 0x200, { ERROR_SUCCESS } }, /* Minimal PE image that XP is able to load: 92 bytes */ - { &dos_header, 0x04, + { 0x04, 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x04 /* also serves as e_lfanew in the truncated MZ header */, 0x04, 1, @@ -277,40 +376,24 @@ static void test_Loader(void) { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */ } }; - static const char filler[0x1000]; - static const char section_data[0x10] = "section data"; int i; - DWORD dummy, file_size, file_align; - HANDLE hfile; + DWORD file_size; HMODULE hlib, hlib_as_data_file; - SYSTEM_INFO si; char temp_path[MAX_PATH]; char dll_name[MAX_PATH]; SIZE_T size; BOOL ret; - - GetSystemInfo(&si); + NTSTATUS status; + WORD orig_machine = nt_header.FileHeader.Machine; /* prevent displaying of the "Unable to load this DLL" message box */ SetErrorMode(SEM_FAILCRITICALERRORS); - GetTempPath(MAX_PATH, temp_path); + GetTempPathA(MAX_PATH, temp_path); for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) { - GetTempFileName(temp_path, "ldr", 0, dll_name); - - /*trace("creating %s\n", dll_name);*/ - hfile = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); - if (hfile == INVALID_HANDLE_VALUE) - { - ok(0, "could not create %s\n", dll_name); - break; - } - - SetLastError(0xdeadbeef); - ret = WriteFile(hfile, td[i].dos_header, td[i].size_of_dos_header, &dummy, NULL); - ok(ret, "WriteFile error %d\n", GetLastError()); + GetTempFileNameA(temp_path, "ldr", 0, dll_name); nt_header.FileHeader.NumberOfSections = td[i].number_of_sections; nt_header.FileHeader.SizeOfOptionalHeader = td[i].size_of_optional_header; @@ -319,58 +402,16 @@ static void test_Loader(void) nt_header.OptionalHeader.FileAlignment = td[i].file_alignment; nt_header.OptionalHeader.SizeOfImage = td[i].size_of_image; nt_header.OptionalHeader.SizeOfHeaders = td[i].size_of_headers; - SetLastError(0xdeadbeef); - ret = WriteFile(hfile, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL); - ok(ret, "WriteFile error %d\n", GetLastError()); - if (nt_header.FileHeader.SizeOfOptionalHeader) + file_size = create_test_dll( &dos_header, td[i].size_of_dos_header, &nt_header, dll_name ); + if (!file_size) { - SetLastError(0xdeadbeef); - ret = WriteFile(hfile, &nt_header.OptionalHeader, - min(nt_header.FileHeader.SizeOfOptionalHeader, sizeof(IMAGE_OPTIONAL_HEADER)), - &dummy, NULL); - ok(ret, "WriteFile error %d\n", GetLastError()); - if (nt_header.FileHeader.SizeOfOptionalHeader > sizeof(IMAGE_OPTIONAL_HEADER)) - { - file_align = nt_header.FileHeader.SizeOfOptionalHeader - sizeof(IMAGE_OPTIONAL_HEADER); - assert(file_align < sizeof(filler)); - SetLastError(0xdeadbeef); - ret = WriteFile(hfile, filler, file_align, &dummy, NULL); - ok(ret, "WriteFile error %d\n", GetLastError()); - } + ok(0, "could not create %s\n", dll_name); + break; } - assert(nt_header.FileHeader.NumberOfSections <= 1); - if (nt_header.FileHeader.NumberOfSections) - { - if (nt_header.OptionalHeader.SectionAlignment >= si.dwPageSize) - { - section.PointerToRawData = td[i].size_of_dos_header; - section.VirtualAddress = nt_header.OptionalHeader.SectionAlignment; - section.Misc.VirtualSize = section.SizeOfRawData * 10; - } - else - { - section.PointerToRawData = nt_header.OptionalHeader.SizeOfHeaders; - section.VirtualAddress = nt_header.OptionalHeader.SizeOfHeaders; - section.Misc.VirtualSize = 5; - } - - SetLastError(0xdeadbeef); - ret = WriteFile(hfile, §ion, sizeof(section), &dummy, NULL); - ok(ret, "WriteFile error %d\n", GetLastError()); - - /* section data */ - SetLastError(0xdeadbeef); - ret = WriteFile(hfile, section_data, sizeof(section_data), &dummy, NULL); - ok(ret, "WriteFile error %d\n", GetLastError()); - } - - file_size = GetFileSize(hfile, NULL); - CloseHandle(hfile); - SetLastError(0xdeadbeef); - hlib = LoadLibrary(dll_name); + hlib = LoadLibraryA(dll_name); if (hlib) { MEMORY_BASIC_INFORMATION info; @@ -385,17 +426,17 @@ static void test_Loader(void) ok(info.BaseAddress == hlib, "%d: %p != %p\n", i, info.BaseAddress, hlib); ok(info.AllocationBase == hlib, "%d: %p != %p\n", i, info.AllocationBase, hlib); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %x != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect); - ok(info.RegionSize == ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, si.dwPageSize), "%d: got %lx != expected %x\n", - i, info.RegionSize, ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, si.dwPageSize)); + ok(info.RegionSize == ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size), "%d: got %lx != expected %x\n", + i, info.RegionSize, ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size)); ok(info.State == MEM_COMMIT, "%d: %x != MEM_COMMIT\n", i, info.State); - if (nt_header.OptionalHeader.SectionAlignment < si.dwPageSize) + if (nt_header.OptionalHeader.SectionAlignment < page_size) ok(info.Protect == PAGE_EXECUTE_WRITECOPY, "%d: %x != PAGE_EXECUTE_WRITECOPY\n", i, info.Protect); else ok(info.Protect == PAGE_READONLY, "%d: %x != PAGE_READONLY\n", i, info.Protect); ok(info.Type == SEC_IMAGE, "%d: %x != SEC_IMAGE\n", i, info.Type); SetLastError(0xdeadbeef); - ptr = VirtualAlloc(hlib, si.dwPageSize, MEM_COMMIT, info.Protect); + ptr = VirtualAlloc(hlib, page_size, MEM_COMMIT, info.Protect); ok(!ptr, "%d: VirtualAlloc should fail\n", i); /* FIXME: Remove once Wine is fixed */ if (info.Protect == PAGE_WRITECOPY || info.Protect == PAGE_EXECUTE_WRITECOPY) @@ -408,11 +449,11 @@ todo_wine size = VirtualQuery((char *)hlib + info.RegionSize, &info, sizeof(info)); ok(size == sizeof(info), "%d: VirtualQuery error %d\n", i, GetLastError()); - if (nt_header.OptionalHeader.SectionAlignment == si.dwPageSize || + if (nt_header.OptionalHeader.SectionAlignment == page_size || nt_header.OptionalHeader.SectionAlignment == nt_header.OptionalHeader.FileAlignment) { - ok(info.BaseAddress == (char *)hlib + ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, si.dwPageSize), "%d: got %p != expected %p\n", - i, info.BaseAddress, (char *)hlib + ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, si.dwPageSize)); + ok(info.BaseAddress == (char *)hlib + ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size), "%d: got %p != expected %p\n", + i, info.BaseAddress, (char *)hlib + ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size)); ok(info.AllocationBase == 0, "%d: %p != 0\n", i, info.AllocationBase); ok(info.AllocationProtect == 0, "%d: %x != 0\n", i, info.AllocationProtect); /*ok(info.RegionSize == not_practical_value, "%d: %lx != not_practical_value\n", i, info.RegionSize);*/ @@ -426,20 +467,20 @@ todo_wine ok(info.BaseAddress == hlib, "%d: got %p != expected %p\n", i, info.BaseAddress, hlib); ok(info.AllocationBase == hlib, "%d: %p != %p\n", i, info.AllocationBase, hlib); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %x != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect); - ok(info.RegionSize == ALIGN_SIZE(file_size, si.dwPageSize), "%d: got %lx != expected %x\n", - i, info.RegionSize, ALIGN_SIZE(file_size, si.dwPageSize)); + ok(info.RegionSize == ALIGN_SIZE(file_size, page_size), "%d: got %lx != expected %x\n", + i, info.RegionSize, ALIGN_SIZE(file_size, page_size)); ok(info.State == MEM_COMMIT, "%d: %x != MEM_COMMIT\n", i, info.State); ok(info.Protect == PAGE_READONLY, "%d: %x != PAGE_READONLY\n", i, info.Protect); ok(info.Type == SEC_IMAGE, "%d: %x != SEC_IMAGE\n", i, info.Type); } /* header: check the zeroing of alignment */ - if (nt_header.OptionalHeader.SectionAlignment >= si.dwPageSize) + if (nt_header.OptionalHeader.SectionAlignment >= page_size) { const char *start; start = (const char *)hlib + nt_header.OptionalHeader.SizeOfHeaders; - size = ALIGN_SIZE((ULONG_PTR)start, si.dwPageSize) - (ULONG_PTR)start; + size = ALIGN_SIZE((ULONG_PTR)start, page_size) - (ULONG_PTR)start; ok(!memcmp(start, filler, size), "%d: header alignment is not cleared\n", i); } @@ -449,18 +490,18 @@ todo_wine size = VirtualQuery((char *)hlib + section.VirtualAddress, &info, sizeof(info)); ok(size == sizeof(info), "%d: VirtualQuery error %d\n", i, GetLastError()); - if (nt_header.OptionalHeader.SectionAlignment < si.dwPageSize) + if (nt_header.OptionalHeader.SectionAlignment < page_size) { ok(info.BaseAddress == hlib, "%d: got %p != expected %p\n", i, info.BaseAddress, hlib); - ok(info.RegionSize == ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, si.dwPageSize), "%d: got %lx != expected %x\n", - i, info.RegionSize, ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, si.dwPageSize)); + ok(info.RegionSize == ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size), "%d: got %lx != expected %x\n", + i, info.RegionSize, ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size)); ok(info.Protect == PAGE_EXECUTE_WRITECOPY, "%d: %x != PAGE_EXECUTE_WRITECOPY\n", i, info.Protect); } else { ok(info.BaseAddress == (char *)hlib + section.VirtualAddress, "%d: got %p != expected %p\n", i, info.BaseAddress, (char *)hlib + section.VirtualAddress); - ok(info.RegionSize == ALIGN_SIZE(section.Misc.VirtualSize, si.dwPageSize), "%d: got %lx != expected %x\n", - i, info.RegionSize, ALIGN_SIZE(section.Misc.VirtualSize, si.dwPageSize)); + ok(info.RegionSize == ALIGN_SIZE(section.Misc.VirtualSize, page_size), "%d: got %lx != expected %x\n", + i, info.RegionSize, ALIGN_SIZE(section.Misc.VirtualSize, page_size)); ok(info.Protect == PAGE_READONLY, "%d: %x != PAGE_READONLY\n", i, info.Protect); } ok(info.AllocationBase == hlib, "%d: %p != %p\n", i, info.AllocationBase, hlib); @@ -468,23 +509,23 @@ todo_wine ok(info.State == MEM_COMMIT, "%d: %x != MEM_COMMIT\n", i, info.State); ok(info.Type == SEC_IMAGE, "%d: %x != SEC_IMAGE\n", i, info.Type); - if (nt_header.OptionalHeader.SectionAlignment >= si.dwPageSize) + if (nt_header.OptionalHeader.SectionAlignment >= page_size) ok(!memcmp((const char *)hlib + section.VirtualAddress + section.PointerToRawData, &nt_header, section.SizeOfRawData), "wrong section data\n"); else ok(!memcmp((const char *)hlib + section.PointerToRawData, section_data, section.SizeOfRawData), "wrong section data\n"); /* check the zeroing of alignment */ - if (nt_header.OptionalHeader.SectionAlignment >= si.dwPageSize) + if (nt_header.OptionalHeader.SectionAlignment >= page_size) { const char *start; start = (const char *)hlib + section.VirtualAddress + section.PointerToRawData + section.SizeOfRawData; - size = ALIGN_SIZE((ULONG_PTR)start, si.dwPageSize) - (ULONG_PTR)start; + size = ALIGN_SIZE((ULONG_PTR)start, page_size) - (ULONG_PTR)start; ok(memcmp(start, filler, size), "%d: alignment should not be cleared\n", i); } SetLastError(0xdeadbeef); - ptr = VirtualAlloc((char *)hlib + section.VirtualAddress, si.dwPageSize, MEM_COMMIT, info.Protect); + ptr = VirtualAlloc((char *)hlib + section.VirtualAddress, page_size, MEM_COMMIT, info.Protect); ok(!ptr, "%d: VirtualAlloc should fail\n", i); /* FIXME: Remove once Wine is fixed */ if (info.Protect == PAGE_WRITECOPY || info.Protect == PAGE_EXECUTE_WRITECOPY) @@ -497,7 +538,7 @@ todo_wine } SetLastError(0xdeadbeef); - hlib_as_data_file = LoadLibraryEx(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE); + hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE); ok(hlib_as_data_file != 0, "LoadLibraryEx error %u\n", GetLastError()); ok(hlib_as_data_file == hlib, "hlib_as_file and hlib are different\n"); @@ -506,22 +547,22 @@ todo_wine ok(ret, "FreeLibrary error %d\n", GetLastError()); SetLastError(0xdeadbeef); - hlib = GetModuleHandle(dll_name); + hlib = GetModuleHandleA(dll_name); ok(hlib != 0, "GetModuleHandle error %u\n", GetLastError()); SetLastError(0xdeadbeef); ret = FreeLibrary(hlib_as_data_file); ok(ret, "FreeLibrary error %d\n", GetLastError()); - hlib = GetModuleHandle(dll_name); + hlib = GetModuleHandleA(dll_name); ok(!hlib, "GetModuleHandle should fail\n"); SetLastError(0xdeadbeef); - hlib_as_data_file = LoadLibraryEx(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE); + hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE); ok(hlib_as_data_file != 0, "LoadLibraryEx error %u\n", GetLastError()); ok((ULONG_PTR)hlib_as_data_file & 1, "hlib_as_data_file is even\n"); - hlib = GetModuleHandle(dll_name); + hlib = GetModuleHandleA(dll_name); ok(!hlib, "GetModuleHandle should fail\n"); SetLastError(0xdeadbeef); @@ -544,9 +585,105 @@ todo_wine } SetLastError(0xdeadbeef); - ret = DeleteFile(dll_name); + ret = DeleteFileA(dll_name); ok(ret, "DeleteFile error %d\n", GetLastError()); } + + nt_header.FileHeader.NumberOfSections = 1; + nt_header.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); + + nt_header.OptionalHeader.SectionAlignment = page_size; + nt_header.OptionalHeader.FileAlignment = page_size; + nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER); + nt_header.OptionalHeader.SizeOfImage = nt_header.OptionalHeader.SizeOfImage + page_size; + + status = map_image_section( &nt_header ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + dos_header.e_magic = 0; + status = map_image_section( &nt_header ); + ok( status == STATUS_INVALID_IMAGE_NOT_MZ, "NtCreateSection error %08x\n", status ); + + dos_header.e_magic = IMAGE_DOS_SIGNATURE; + nt_header.Signature = IMAGE_OS2_SIGNATURE; + status = map_image_section( &nt_header ); + ok( status == STATUS_INVALID_IMAGE_NE_FORMAT, "NtCreateSection error %08x\n", status ); + + nt_header.Signature = 0xdeadbeef; + status = map_image_section( &nt_header ); + ok( status == STATUS_INVALID_IMAGE_PROTECT, "NtCreateSection error %08x\n", status ); + + nt_header.Signature = IMAGE_NT_SIGNATURE; + nt_header.OptionalHeader.Magic = 0xdead; + status = map_image_section( &nt_header ); + ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status ); + + nt_header.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; + nt_header.FileHeader.Machine = 0xdead; + status = map_image_section( &nt_header ); + ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */ + "NtCreateSection error %08x\n", status ); + + nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_UNKNOWN; + status = map_image_section( &nt_header ); + ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */ + "NtCreateSection error %08x\n", status ); + + switch (orig_machine) + { + case IMAGE_FILE_MACHINE_I386: nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64; break; + case IMAGE_FILE_MACHINE_AMD64: nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_I386; break; + case IMAGE_FILE_MACHINE_ARMNT: nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64; break; + case IMAGE_FILE_MACHINE_ARM64: nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT; break; + } + status = map_image_section( &nt_header ); + ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */ + "NtCreateSection error %08x\n", status ); + + if (nt_header.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) + { + IMAGE_NT_HEADERS64 nt64; + + memset( &nt64, 0, sizeof(nt64) ); + nt64.Signature = IMAGE_NT_SIGNATURE; + nt64.FileHeader.Machine = orig_machine; + nt64.FileHeader.NumberOfSections = 1; + nt64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64); + nt64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; + nt64.OptionalHeader.MajorLinkerVersion = 1; + nt64.OptionalHeader.ImageBase = 0x10000000; + nt64.OptionalHeader.MajorOperatingSystemVersion = 4; + nt64.OptionalHeader.MajorImageVersion = 1; + nt64.OptionalHeader.MajorSubsystemVersion = 4; + nt64.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt64) + sizeof(IMAGE_SECTION_HEADER); + nt64.OptionalHeader.SizeOfImage = nt64.OptionalHeader.SizeOfHeaders + 0x1000; + nt64.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64 ); + ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status ); + } + else + { + IMAGE_NT_HEADERS32 nt32; + + memset( &nt32, 0, sizeof(nt32) ); + nt32.Signature = IMAGE_NT_SIGNATURE; + nt32.FileHeader.Machine = orig_machine; + nt32.FileHeader.NumberOfSections = 1; + nt32.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32); + nt32.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC; + nt32.OptionalHeader.MajorLinkerVersion = 1; + nt32.OptionalHeader.ImageBase = 0x10000000; + nt32.OptionalHeader.MajorOperatingSystemVersion = 4; + nt32.OptionalHeader.MajorImageVersion = 1; + nt32.OptionalHeader.MajorSubsystemVersion = 4; + nt32.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt32) + sizeof(IMAGE_SECTION_HEADER); + nt32.OptionalHeader.SizeOfImage = nt32.OptionalHeader.SizeOfHeaders + 0x1000; + nt32.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32 ); + ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status ); + } + + nt_header.FileHeader.Machine = orig_machine; /* restore it for the next tests */ } /* Verify linking style of import descriptors */ @@ -612,18 +749,15 @@ static void test_image_mapping(const char *dll_name, DWORD scn_page_access, BOOL SIZE_T size; void *addr1, *addr2; MEMORY_BASIC_INFORMATION info; - SYSTEM_INFO si; if (!pNtMapViewOfSection) return; - GetSystemInfo(&si); - SetLastError(0xdeadbeef); - hfile = CreateFile(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + hfile = CreateFileA(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); ok(hfile != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); SetLastError(0xdeadbeef); - hmap = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, 0); + hmap = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, 0); ok(hmap != 0, "CreateFileMapping error %d\n", GetLastError()); offset.u.LowPart = 0; @@ -640,7 +774,7 @@ static void test_image_mapping(const char *dll_name, DWORD scn_page_access, BOOL size = VirtualQuery((char *)addr1 + section.VirtualAddress, &info, sizeof(info)); ok(size == sizeof(info), "VirtualQuery error %d\n", GetLastError()); ok(info.BaseAddress == (char *)addr1 + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)addr1 + section.VirtualAddress); - ok(info.RegionSize == si.dwPageSize, "got %#lx != expected %#x\n", info.RegionSize, si.dwPageSize); + ok(info.RegionSize == page_size, "got %#lx != expected %#x\n", info.RegionSize, page_size); ok(info.Protect == scn_page_access, "got %#x != expected %#x\n", info.Protect, scn_page_access); ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%#x != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect); @@ -668,7 +802,7 @@ static void test_image_mapping(const char *dll_name, DWORD scn_page_access, BOOL size = VirtualQuery((char *)addr2 + section.VirtualAddress, &info, sizeof(info)); ok(size == sizeof(info), "VirtualQuery error %d\n", GetLastError()); ok(info.BaseAddress == (char *)addr2 + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)addr2 + section.VirtualAddress); - ok(info.RegionSize == si.dwPageSize, "got %#lx != expected %#x\n", info.RegionSize, si.dwPageSize); + ok(info.RegionSize == page_size, "got %#lx != expected %#x\n", info.RegionSize, page_size); ok(info.Protect == scn_page_access, "got %#x != expected %#x\n", info.Protect, scn_page_access); ok(info.AllocationBase == addr2, "%p != %p\n", info.AllocationBase, addr2); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%#x != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect); @@ -686,7 +820,7 @@ static void test_image_mapping(const char *dll_name, DWORD scn_page_access, BOOL size = VirtualQuery((char *)addr2 + section.VirtualAddress, &info, sizeof(info)); ok(size == sizeof(info), "VirtualQuery error %d\n", GetLastError()); ok(info.BaseAddress == (char *)addr2 + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)addr2 + section.VirtualAddress); - ok(info.RegionSize == si.dwPageSize, "got %#lx != expected %#x\n", info.RegionSize, si.dwPageSize); + ok(info.RegionSize == page_size, "got %#lx != expected %#x\n", info.RegionSize, page_size); ok(info.Protect == scn_page_access, "got %#x != expected %#x\n", info.Protect, scn_page_access); ok(info.AllocationBase == addr2, "%p != %p\n", info.AllocationBase, addr2); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%#x != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect); @@ -696,7 +830,7 @@ static void test_image_mapping(const char *dll_name, DWORD scn_page_access, BOOL UnmapViewOfFile(addr2); SetLastError(0xdeadbeef); - addr2 = LoadLibrary(dll_name); + addr2 = LoadLibraryA(dll_name); if (is_dll) { ok(!addr2, "LoadLibrary should fail, is_dll %d\n", is_dll); @@ -778,12 +912,9 @@ static void test_VirtualProtect(void *base, void *section) }; DWORD ret, orig_prot, old_prot, rw_prot, exec_prot, i, j; MEMORY_BASIC_INFORMATION info; - SYSTEM_INFO si; - - GetSystemInfo(&si); SetLastError(0xdeadbeef); - ret = VirtualProtect(section, si.dwPageSize, PAGE_NOACCESS, &old_prot); + ret = VirtualProtect(section, page_size, PAGE_NOACCESS, &old_prot); ok(ret, "VirtualProtect error %d\n", GetLastError()); orig_prot = old_prot; @@ -794,7 +925,7 @@ static void test_VirtualProtect(void *base, void *section) ret = VirtualQuery(section, &info, sizeof(info)); ok(ret, "VirtualQuery failed %d\n", GetLastError()); ok(info.BaseAddress == section, "%d: got %p != expected %p\n", i, info.BaseAddress, section); - ok(info.RegionSize == si.dwPageSize, "%d: got %#lx != expected %#x\n", i, info.RegionSize, si.dwPageSize); + ok(info.RegionSize == page_size, "%d: got %#lx != expected %#x\n", i, info.RegionSize, page_size); ok(info.Protect == PAGE_NOACCESS, "%d: got %#x != expected PAGE_NOACCESS\n", i, info.Protect); ok(info.AllocationBase == base, "%d: %p != %p\n", i, info.AllocationBase, base); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %#x != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect); @@ -803,7 +934,7 @@ static void test_VirtualProtect(void *base, void *section) old_prot = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = VirtualProtect(section, si.dwPageSize, td[i].prot_set, &old_prot); + ret = VirtualProtect(section, page_size, td[i].prot_set, &old_prot); if (td[i].prot_get) { ok(ret, "%d: VirtualProtect error %d, requested prot %#x\n", i, GetLastError(), td[i].prot_set); @@ -813,7 +944,7 @@ static void test_VirtualProtect(void *base, void *section) ret = VirtualQuery(section, &info, sizeof(info)); ok(ret, "VirtualQuery failed %d\n", GetLastError()); ok(info.BaseAddress == section, "%d: got %p != expected %p\n", i, info.BaseAddress, section); - ok(info.RegionSize == si.dwPageSize, "%d: got %#lx != expected %#x\n", i, info.RegionSize, si.dwPageSize); + ok(info.RegionSize == page_size, "%d: got %#lx != expected %#x\n", i, info.RegionSize, page_size); ok(info.Protect == td[i].prot_get, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].prot_get); ok(info.AllocationBase == base, "%d: %p != %p\n", i, info.AllocationBase, base); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %#x != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect); @@ -828,7 +959,7 @@ static void test_VirtualProtect(void *base, void *section) old_prot = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = VirtualProtect(section, si.dwPageSize, PAGE_NOACCESS, &old_prot); + ret = VirtualProtect(section, page_size, PAGE_NOACCESS, &old_prot); ok(ret, "%d: VirtualProtect error %d\n", i, GetLastError()); if (td[i].prot_get) ok(old_prot == td[i].prot_get, "%d: got %#x != expected %#x\n", i, old_prot, td[i].prot_get); @@ -847,7 +978,7 @@ static void test_VirtualProtect(void *base, void *section) DWORD prot = exec_prot | rw_prot; SetLastError(0xdeadbeef); - ret = VirtualProtect(section, si.dwPageSize, prot, &old_prot); + ret = VirtualProtect(section, page_size, prot, &old_prot); if ((rw_prot && exec_prot) || (!rw_prot && !exec_prot)) { ok(!ret, "VirtualProtect(%02x) should fail\n", prot); @@ -863,7 +994,7 @@ static void test_VirtualProtect(void *base, void *section) } SetLastError(0xdeadbeef); - ret = VirtualProtect(section, si.dwPageSize, orig_prot, &old_prot); + ret = VirtualProtect(section, page_size, orig_prot, &old_prot); ok(ret, "VirtualProtect error %d\n", GetLastError()); } @@ -908,25 +1039,22 @@ static void test_section_access(void) DWORD dummy, file_align; HANDLE hfile; HMODULE hlib; - SYSTEM_INFO si; char temp_path[MAX_PATH]; char dll_name[MAX_PATH]; SIZE_T size; MEMORY_BASIC_INFORMATION info; - STARTUPINFO sti; + STARTUPINFOA sti; PROCESS_INFORMATION pi; DWORD ret; - GetSystemInfo(&si); - /* prevent displaying of the "Unable to load this DLL" message box */ SetErrorMode(SEM_FAILCRITICALERRORS); - GetTempPath(MAX_PATH, temp_path); + GetTempPathA(MAX_PATH, temp_path); for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) { - GetTempFileName(temp_path, "ldr", 0, dll_name); + GetTempFileNameA(temp_path, "ldr", 0, dll_name); /*trace("creating %s\n", dll_name);*/ hfile = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); @@ -944,9 +1072,9 @@ static void test_section_access(void) nt_header.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); nt_header.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL | IMAGE_FILE_RELOCS_STRIPPED; - nt_header.OptionalHeader.SectionAlignment = si.dwPageSize; + nt_header.OptionalHeader.SectionAlignment = page_size; nt_header.OptionalHeader.FileAlignment = 0x200; - nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + si.dwPageSize; + nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + page_size; nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER); SetLastError(0xdeadbeef); ret = WriteFile(hfile, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL); @@ -978,7 +1106,7 @@ static void test_section_access(void) CloseHandle(hfile); SetLastError(0xdeadbeef); - hlib = LoadLibrary(dll_name); + hlib = LoadLibraryA(dll_name); ok(hlib != 0, "LoadLibrary error %d\n", GetLastError()); SetLastError(0xdeadbeef); @@ -986,7 +1114,7 @@ static void test_section_access(void) ok(size == sizeof(info), "%d: VirtualQuery error %d\n", i, GetLastError()); ok(info.BaseAddress == (char *)hlib + section.VirtualAddress, "%d: got %p != expected %p\n", i, info.BaseAddress, (char *)hlib + section.VirtualAddress); - ok(info.RegionSize == si.dwPageSize, "%d: got %#lx != expected %#x\n", i, info.RegionSize, si.dwPageSize); + ok(info.RegionSize == page_size, "%d: got %#lx != expected %#x\n", i, info.RegionSize, page_size); ok(info.Protect == td[i].scn_page_access, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].scn_page_access); ok(info.AllocationBase == hlib, "%d: %p != %p\n", i, info.AllocationBase, hlib); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %#x != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect); @@ -1021,7 +1149,7 @@ static void test_section_access(void) /* reset IMAGE_FILE_DLL otherwise CreateProcess fails */ nt_header.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_RELOCS_STRIPPED; SetLastError(0xdeadbeef); - hfile = CreateFile(dll_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); + hfile = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); /* LoadLibrary called on an already memory-mapped file in * test_image_mapping() above leads to a file handle leak * under nt4, and inability to overwrite and delete the file @@ -1040,7 +1168,7 @@ static void test_section_access(void) memset(&sti, 0, sizeof(sti)); sti.cb = sizeof(sti); SetLastError(0xdeadbeef); - ret = CreateProcess(dll_name, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sti, &pi); + ret = CreateProcessA(dll_name, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sti, &pi); ok(ret, "CreateProcess() error %d\n", GetLastError()); SetLastError(0xdeadbeef); @@ -1048,7 +1176,7 @@ static void test_section_access(void) ok(size == sizeof(info), "%d: VirtualQuery error %d\n", i, GetLastError()); ok(info.BaseAddress == (char *)hlib + section.VirtualAddress, "%d: got %p != expected %p\n", i, info.BaseAddress, (char *)hlib + section.VirtualAddress); - ok(info.RegionSize == si.dwPageSize, "%d: got %#lx != expected %#x\n", i, info.RegionSize, si.dwPageSize); + ok(info.RegionSize == page_size, "%d: got %#lx != expected %#x\n", i, info.RegionSize, page_size); ok(info.Protect == td[i].scn_page_access, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].scn_page_access); ok(info.AllocationBase == hlib, "%d: %p != %p\n", i, info.AllocationBase, hlib); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %#x != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect); @@ -1075,11 +1203,142 @@ static void test_section_access(void) nt4_is_broken: SetLastError(0xdeadbeef); - ret = DeleteFile(dll_name); + ret = DeleteFileA(dll_name); ok(ret || broken(!ret) /* nt4 */, "DeleteFile error %d\n", GetLastError()); } } +static void test_import_resolution(void) +{ + char temp_path[MAX_PATH]; + char dll_name[MAX_PATH]; + DWORD dummy; + void *expect; + char *str; + HANDLE hfile; + HMODULE mod, mod2; + struct imports + { + IMAGE_IMPORT_DESCRIPTOR descr[2]; + IMAGE_THUNK_DATA original_thunks[2]; + IMAGE_THUNK_DATA thunks[2]; + char module[16]; + struct { WORD hint; char name[32]; } function; + IMAGE_TLS_DIRECTORY tls; + char tls_data[16]; + SHORT tls_index; + } data, *ptr; + IMAGE_NT_HEADERS nt; + IMAGE_SECTION_HEADER section; + int test; + + for (test = 0; test < 3; test++) + { +#define DATA_RVA(ptr) (page_size + ((char *)(ptr) - (char *)&data)) + nt = nt_header; + nt.FileHeader.NumberOfSections = 1; + nt.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); + nt.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_RELOCS_STRIPPED; + if (test != 2) nt.FileHeader.Characteristics |= IMAGE_FILE_DLL; + nt.OptionalHeader.ImageBase = 0x12340000; + nt.OptionalHeader.SizeOfImage = 2 * page_size; + nt.OptionalHeader.SizeOfHeaders = nt.OptionalHeader.FileAlignment; + nt.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; + memset( nt.OptionalHeader.DataDirectory, 0, sizeof(nt.OptionalHeader.DataDirectory) ); + nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = sizeof(data.descr); + nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = DATA_RVA(data.descr); + nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = sizeof(data.tls); + nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = DATA_RVA(&data.tls); + + memset( &data, 0, sizeof(data) ); + data.descr[0].u.OriginalFirstThunk = DATA_RVA( data.original_thunks ); + data.descr[0].FirstThunk = DATA_RVA( data.thunks ); + data.descr[0].Name = DATA_RVA( data.module ); + strcpy( data.module, "kernel32.dll" ); + strcpy( data.function.name, "CreateEventA" ); + data.original_thunks[0].u1.AddressOfData = DATA_RVA( &data.function ); + data.thunks[0].u1.AddressOfData = 0xdeadbeef; + + data.tls.StartAddressOfRawData = nt.OptionalHeader.ImageBase + DATA_RVA( data.tls_data ); + data.tls.EndAddressOfRawData = data.tls.StartAddressOfRawData + sizeof(data.tls_data); + data.tls.AddressOfIndex = nt.OptionalHeader.ImageBase + DATA_RVA( &data.tls_index ); + strcpy( data.tls_data, "hello world" ); + data.tls_index = 9999; + + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "ldr", 0, dll_name); + + hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0); + ok( hfile != INVALID_HANDLE_VALUE, "creation failed\n" ); + + memset( §ion, 0, sizeof(section) ); + memcpy( section.Name, ".text", sizeof(".text") ); + section.PointerToRawData = nt.OptionalHeader.FileAlignment; + section.VirtualAddress = nt.OptionalHeader.SectionAlignment; + section.Misc.VirtualSize = sizeof(data); + section.SizeOfRawData = sizeof(data); + section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; + + WriteFile(hfile, &dos_header, sizeof(dos_header), &dummy, NULL); + WriteFile(hfile, &nt, sizeof(nt), &dummy, NULL); + WriteFile(hfile, §ion, sizeof(section), &dummy, NULL); + + SetFilePointer( hfile, section.PointerToRawData, NULL, SEEK_SET ); + WriteFile(hfile, &data, sizeof(data), &dummy, NULL); + + CloseHandle( hfile ); + + switch (test) + { + case 0: /* normal load */ + mod = LoadLibraryA( dll_name ); + ok( mod != NULL, "failed to load err %u\n", GetLastError() ); + if (!mod) break; + ptr = (struct imports *)((char *)mod + page_size); + expect = GetProcAddress( GetModuleHandleA( data.module ), data.function.name ); + ok( (void *)ptr->thunks[0].u1.Function == expect, "thunk %p instead of %p for %s.%s\n", + (void *)ptr->thunks[0].u1.Function, expect, data.module, data.function.name ); + ok( ptr->tls_index < 32 || broken(ptr->tls_index == 9999), /* before vista */ + "wrong tls index %d\n", ptr->tls_index ); + if (ptr->tls_index != 9999) + { + str = ((char **)NtCurrentTeb()->ThreadLocalStoragePointer)[ptr->tls_index]; + ok( !strcmp( str, "hello world" ), "wrong tls data '%s' at %p\n", str, str ); + } + FreeLibrary( mod ); + break; + case 1: /* load with DONT_RESOLVE_DLL_REFERENCES doesn't resolve imports */ + mod = LoadLibraryExA( dll_name, 0, DONT_RESOLVE_DLL_REFERENCES ); + ok( mod != NULL, "failed to load err %u\n", GetLastError() ); + if (!mod) break; + ptr = (struct imports *)((char *)mod + page_size); + ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n", + (void *)ptr->thunks[0].u1.Function, data.module, data.function.name ); + ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index ); + + mod2 = LoadLibraryA( dll_name ); + ok( mod2 == mod, "loaded twice %p / %p\n", mod, mod2 ); + ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n", + (void *)ptr->thunks[0].u1.Function, data.module, data.function.name ); + ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index ); + FreeLibrary( mod ); + break; + case 2: /* load without IMAGE_FILE_DLL doesn't resolve imports */ + mod = LoadLibraryA( dll_name ); + ok( mod != NULL, "failed to load err %u\n", GetLastError() ); + if (!mod) break; + ptr = (struct imports *)((char *)mod + page_size); + ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n", + (void *)ptr->thunks[0].u1.Function, data.module, data.function.name ); + ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index ); + FreeLibrary( mod ); + break; + } + DeleteFileA( dll_name ); +#undef DATA_RVA + } +} + #define MAX_COUNT 10 static HANDLE attached_thread[MAX_COUNT]; static DWORD attached_thread_count; @@ -1312,7 +1571,7 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param) } SetLastError(0xdeadbeef); - process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); + process = OpenProcess(PROCESS_ALL_ACCESS_NT4, FALSE, GetCurrentProcessId()); ok(process != NULL, "OpenProcess error %d\n", GetLastError()); noop_thread_started = 0; @@ -1340,7 +1599,7 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param) } SetLastError(0xdeadbeef); - handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, NULL); + handle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, NULL); ok(handle != 0, "CreateFileMapping error %d\n", GetLastError()); offset.u.LowPart = 0; @@ -1356,15 +1615,15 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param) CloseHandle(handle); CloseHandle(process); - handle = GetModuleHandle("winver.exe"); + handle = GetModuleHandleA("winver.exe"); ok(!handle, "winver.exe shouldn't be loaded yet\n"); SetLastError(0xdeadbeef); - handle = LoadLibrary("winver.exe"); + handle = LoadLibraryA("winver.exe"); ok(handle != 0, "LoadLibrary error %d\n", GetLastError()); SetLastError(0xdeadbeef); ret = FreeLibrary(handle); ok(ret, "FreeLibrary error %d\n", GetLastError()); - handle = GetModuleHandle("winver.exe"); + handle = GetModuleHandleA("winver.exe"); if (param) ok(handle != 0, "winver.exe should not be unloaded\n"); else @@ -1445,34 +1704,34 @@ static void child_process(const char *dll_name, DWORD target_offset) trace("phase %d: writing %p at %#x\n", test_dll_phase, dll_entry_point, target_offset); SetLastError(0xdeadbeef); - mutex = CreateMutex(NULL, FALSE, NULL); + mutex = CreateMutexW(NULL, FALSE, NULL); ok(mutex != 0, "CreateMutex error %d\n", GetLastError()); SetLastError(0xdeadbeef); - semaphore = CreateSemaphore(NULL, 1, 1, NULL); + semaphore = CreateSemaphoreW(NULL, 1, 1, NULL); ok(semaphore != 0, "CreateSemaphore error %d\n", GetLastError()); SetLastError(0xdeadbeef); - event = CreateEvent(NULL, TRUE, FALSE, NULL); + event = CreateEventW(NULL, TRUE, FALSE, NULL); ok(event != 0, "CreateEvent error %d\n", GetLastError()); SetLastError(0xdeadbeef); - loader_lock_event = CreateEvent(NULL, FALSE, FALSE, NULL); + loader_lock_event = CreateEventW(NULL, FALSE, FALSE, NULL); ok(loader_lock_event != 0, "CreateEvent error %d\n", GetLastError()); SetLastError(0xdeadbeef); - peb_lock_event = CreateEvent(NULL, FALSE, FALSE, NULL); + peb_lock_event = CreateEventW(NULL, FALSE, FALSE, NULL); ok(peb_lock_event != 0, "CreateEvent error %d\n", GetLastError()); SetLastError(0xdeadbeef); - heap_lock_event = CreateEvent(NULL, FALSE, FALSE, NULL); + heap_lock_event = CreateEventW(NULL, FALSE, FALSE, NULL); ok(heap_lock_event != 0, "CreateEvent error %d\n", GetLastError()); SetLastError(0xdeadbeef); - ack_event = CreateEvent(NULL, FALSE, FALSE, NULL); + ack_event = CreateEventW(NULL, FALSE, FALSE, NULL); ok(ack_event != 0, "CreateEvent error %d\n", GetLastError()); - file = CreateFile(dll_name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); + file = CreateFileA(dll_name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); if (file == INVALID_HANDLE_VALUE) { ok(0, "could not open %s\n", dll_name); @@ -1486,11 +1745,11 @@ static void child_process(const char *dll_name, DWORD target_offset) CloseHandle(file); SetLastError(0xdeadbeef); - hmod = LoadLibrary(dll_name); + hmod = LoadLibraryA(dll_name); ok(hmod != 0, "LoadLibrary error %d\n", GetLastError()); SetLastError(0xdeadbeef); - stop_event = CreateEvent(NULL, TRUE, FALSE, NULL); + stop_event = CreateEventW(NULL, TRUE, FALSE, NULL); ok(stop_event != 0, "CreateEvent error %d\n", GetLastError()); SetLastError(0xdeadbeef); @@ -1535,7 +1794,7 @@ static void child_process(const char *dll_name, DWORD target_offset) ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret); SetLastError(0xdeadbeef); - process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); + process = OpenProcess(PROCESS_ALL_ACCESS_NT4, FALSE, GetCurrentProcessId()); ok(process != NULL, "OpenProcess error %d\n", GetLastError()); SetLastError(0xdeadbeef); @@ -1570,7 +1829,7 @@ static void child_process(const char *dll_name, DWORD target_offset) ret = pRtlDllShutdownInProgress(); ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret); - hmod = GetModuleHandle(dll_name); + hmod = GetModuleHandleA(dll_name); ok(hmod != 0, "DLL should not be unloaded\n"); SetLastError(0xdeadbeef); @@ -1591,7 +1850,7 @@ static void child_process(const char *dll_name, DWORD target_offset) ret = pRtlDllShutdownInProgress(); ok(ret, "RtlDllShutdownInProgress returned %d\n", ret); - hmod = GetModuleHandle(dll_name); + hmod = GetModuleHandleA(dll_name); ok(hmod != 0, "DLL should not be unloaded\n"); memset(&pbi, 0, sizeof(pbi)); @@ -1616,7 +1875,7 @@ static void child_process(const char *dll_name, DWORD target_offset) SetLastError(0xdeadbeef); ret = FreeLibrary(hmod); ok(ret, "FreeLibrary error %d\n", GetLastError()); - hmod = GetModuleHandle(dll_name); + hmod = GetModuleHandleA(dll_name); ok(!hmod, "DLL should be unloaded\n"); if (test_dll_phase == 2) @@ -1748,7 +2007,7 @@ static void test_ExitProcess(void) DWORD ret, target_offset, old_prot; char **argv, buf[256]; PROCESS_INFORMATION pi; - STARTUPINFO si = { sizeof(si) }; + STARTUPINFOA si = { sizeof(si) }; CONTEXT ctx; struct PROCESS_BASIC_INFORMATION_PRIVATE pbi; MEMORY_BASIC_INFORMATION mbi; @@ -1781,11 +2040,11 @@ static void test_ExitProcess(void) /* prevent displaying of the "Unable to load this DLL" message box */ SetErrorMode(SEM_FAILCRITICALERRORS); - GetTempPath(MAX_PATH, temp_path); - GetTempFileName(temp_path, "ldr", 0, dll_name); + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "ldr", 0, dll_name); /*trace("creating %s\n", dll_name);*/ - file = CreateFile(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + file = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); if (file == INVALID_HANDLE_VALUE) { ok(0, "could not create %s\n", dll_name); @@ -1841,7 +2100,7 @@ static void test_ExitProcess(void) /* phase 0 */ *child_failures = -1; sprintf(cmdline, "\"%s\" loader %s %u 0", argv[0], dll_name, target_offset); - ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError()); ret = WaitForSingleObject(pi.hProcess, 10000); ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n"); @@ -1859,7 +2118,7 @@ static void test_ExitProcess(void) /* phase 1 */ *child_failures = -1; sprintf(cmdline, "\"%s\" loader %s %u 1", argv[0], dll_name, target_offset); - ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError()); ret = WaitForSingleObject(pi.hProcess, 10000); ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n"); @@ -1877,7 +2136,7 @@ static void test_ExitProcess(void) /* phase 2 */ *child_failures = -1; sprintf(cmdline, "\"%s\" loader %s %u 2", argv[0], dll_name, target_offset); - ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError()); ret = WaitForSingleObject(pi.hProcess, 10000); ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n"); @@ -1895,7 +2154,7 @@ static void test_ExitProcess(void) /* phase 3 */ *child_failures = -1; sprintf(cmdline, "\"%s\" loader %s %u 3", argv[0], dll_name, target_offset); - ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError()); ret = WaitForSingleObject(pi.hProcess, 10000); ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n"); @@ -1915,7 +2174,7 @@ static void test_ExitProcess(void) { *child_failures = -1; sprintf(cmdline, "\"%s\" loader %s %u 4", argv[0], dll_name, target_offset); - ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError()); ret = WaitForSingleObject(pi.hProcess, 10000); ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n"); @@ -1938,7 +2197,7 @@ static void test_ExitProcess(void) { *child_failures = -1; sprintf(cmdline, "\"%s\" loader %s %u 5", argv[0], dll_name, target_offset); - ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError()); ret = WaitForSingleObject(pi.hProcess, 5000); ok(ret == WAIT_TIMEOUT, "child process should fail to terminate\n"); @@ -1965,7 +2224,7 @@ static void test_ExitProcess(void) /* phase 6 */ *child_failures = -1; sprintf(cmdline, "\"%s\" loader %s %u 6", argv[0], dll_name, target_offset); - ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError()); ret = WaitForSingleObject(pi.hProcess, 5000); ok(ret == WAIT_TIMEOUT || broken(ret == WAIT_OBJECT_0) /* XP */, "child process should fail to terminate\n"); @@ -1988,7 +2247,7 @@ static void test_ExitProcess(void) /* test remote process termination */ SetLastError(0xdeadbeef); - ret = CreateProcess(argv[0], NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); ok(ret, "CreateProcess(%s) error %d\n", argv[0], GetLastError()); SetLastError(0xdeadbeef); @@ -1999,7 +2258,6 @@ static void test_ExitProcess(void) ok(ret, "VirtualProtectEx error %d\n", GetLastError()); ok(old_prot == PAGE_READWRITE, "expected PAGE_READWRITE, got %#x\n", old_prot); SetLastError(0xdeadbeef); - ok(0, "I do *not* love goats!\n"); size = VirtualQueryEx(pi.hProcess, NULL, &mbi, sizeof(mbi)); ok(size == sizeof(mbi), "VirtualQueryEx error %d\n", GetLastError()); @@ -2009,7 +2267,7 @@ static void test_ExitProcess(void) ok(size == 4, "expected 4, got %lu\n", size); SetLastError(0xdeadbeef); - hmap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, NULL); + hmap = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, NULL); ok(hmap != 0, "CreateFileMapping error %d\n", GetLastError()); SetLastError(0xdeadbeef); @@ -2063,7 +2321,7 @@ static void test_ExitProcess(void) ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed: %x\n", ret); SetLastError(0xdeadbeef); - process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId); + process = OpenProcess(PROCESS_ALL_ACCESS_NT4, FALSE, pi.dwProcessId); ok(process != NULL, "OpenProcess error %d\n", GetLastError()); CloseHandle(process); @@ -2136,7 +2394,6 @@ static void test_ExitProcess(void) ok(!addr, "VirtualAllocEx should fail\n"); ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); SetLastError(0xdeadbeef); - ok(0, "I do *not* love goats!\n"); size = VirtualQueryEx(pi.hProcess, NULL, &mbi, sizeof(mbi)); ok(!size, "VirtualQueryEx should fail\n"); ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); @@ -2182,36 +2439,350 @@ if (0) CloseHandle(pi.hThread); CloseHandle(pi.hProcess); - ret = DeleteFile(dll_name); + ret = DeleteFileA(dll_name); ok(ret, "DeleteFile error %d\n", GetLastError()); } +static PVOID WINAPI failuredllhook(ULONG ul, DELAYLOAD_INFO* pd) +{ + ok(ul == 4, "expected 4, got %u\n", ul); + ok(!!pd, "no delayload info supplied\n"); + if (pd) + { + ok(pd->Size == sizeof(*pd), "got %u\n", pd->Size); + ok(!!pd->DelayloadDescriptor, "no DelayloadDescriptor supplied\n"); + if (pd->DelayloadDescriptor) + { + ok(pd->DelayloadDescriptor->Attributes.AllAttributes == 1, + "expected 1, got %u\n", pd->DelayloadDescriptor->Attributes.AllAttributes); + ok(pd->DelayloadDescriptor->DllNameRVA == 0x2000, + "expected 0x2000, got %x\n", pd->DelayloadDescriptor->DllNameRVA); + ok(pd->DelayloadDescriptor->ModuleHandleRVA == 0x201a, + "expected 0x201a, got %x\n", pd->DelayloadDescriptor->ModuleHandleRVA); + ok(pd->DelayloadDescriptor->ImportAddressTableRVA > pd->DelayloadDescriptor->ModuleHandleRVA, + "expected %x > %x\n", pd->DelayloadDescriptor->ImportAddressTableRVA, + pd->DelayloadDescriptor->ModuleHandleRVA); + ok(pd->DelayloadDescriptor->ImportNameTableRVA > pd->DelayloadDescriptor->ImportAddressTableRVA, + "expected %x > %x\n", pd->DelayloadDescriptor->ImportNameTableRVA, + pd->DelayloadDescriptor->ImportAddressTableRVA); + ok(pd->DelayloadDescriptor->BoundImportAddressTableRVA == 0, + "expected 0, got %x\n", pd->DelayloadDescriptor->BoundImportAddressTableRVA); + ok(pd->DelayloadDescriptor->UnloadInformationTableRVA == 0, + "expected 0, got %x\n", pd->DelayloadDescriptor->UnloadInformationTableRVA); + ok(pd->DelayloadDescriptor->TimeDateStamp == 0, + "expected 0, got %x\n", pd->DelayloadDescriptor->TimeDateStamp); + } + + ok(!!pd->ThunkAddress, "no ThunkAddress supplied\n"); + if (pd->ThunkAddress) + ok(pd->ThunkAddress->u1.Ordinal == 0, "expected 0, got %x\n", (UINT)pd->ThunkAddress->u1.Ordinal); + + ok(!!pd->TargetDllName, "no TargetDllName supplied\n"); + if (pd->TargetDllName) + ok(!strcmp(pd->TargetDllName, "secur32.dll"), + "expected \"secur32.dll\", got \"%s\"\n", pd->TargetDllName); + + ok(pd->TargetApiDescriptor.ImportDescribedByName == 0, + "expected 0, got %x\n", pd->TargetApiDescriptor.ImportDescribedByName); + ok(pd->TargetApiDescriptor.Description.Ordinal == 0 || + pd->TargetApiDescriptor.Description.Ordinal == 999, + "expected 0, got %x\n", pd->TargetApiDescriptor.Description.Ordinal); + + ok(!!pd->TargetModuleBase, "no TargetModuleBase supplied\n"); + ok(pd->Unused == NULL, "expected NULL, got %p\n", pd->Unused); + ok(pd->LastError, "no LastError supplied\n"); + } + cb_count++; + return (void*)0xdeadbeef; +} + +static void test_ResolveDelayLoadedAPI(void) +{ + static const char test_dll[] = "secur32.dll"; + static const char test_func[] = "SealMessage"; + static const char filler[0x1000]; + char temp_path[MAX_PATH]; + char dll_name[MAX_PATH]; + IMAGE_DELAYLOAD_DESCRIPTOR idd, *delaydir; + IMAGE_THUNK_DATA itd32; + HANDLE hfile; + HMODULE hlib; + DWORD dummy, file_size, i; + WORD hint = 0; + BOOL ret; + static const struct test_data + { + BOOL func; + UINT_PTR ordinal; + BOOL succeeds; + } td[] = + { + { + TRUE, 0, TRUE + }, + { + FALSE, IMAGE_ORDINAL_FLAG | 2, TRUE + }, + { + FALSE, IMAGE_ORDINAL_FLAG | 5, TRUE + }, + { + FALSE, IMAGE_ORDINAL_FLAG | 0, FALSE + }, + { + FALSE, IMAGE_ORDINAL_FLAG | 999, FALSE + }, + }; + + if (!pResolveDelayLoadedAPI) + { + todo_wine win_skip("ResolveDelayLoadedAPI is not available\n"); + return; + } + + if (0) /* crashes on native */ + { + SetLastError(0xdeadbeef); + ok(!pResolveDelayLoadedAPI(NULL, NULL, NULL, NULL, NULL, 0), + "ResolveDelayLoadedAPI succeeded\n"); + ok(GetLastError() == 0xdeadbeef, "GetLastError changed to %x\n", GetLastError()); + + cb_count = 0; + SetLastError(0xdeadbeef); + ok(!pResolveDelayLoadedAPI(NULL, NULL, failuredllhook, NULL, NULL, 0), + "ResolveDelayLoadedAPI succeeded\n"); + ok(GetLastError() == 0xdeadbeef, "GetLastError changed to %x\n", GetLastError()); + ok(cb_count == 1, "Wrong callback count: %d\n", cb_count); + } + + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "ldr", 0, dll_name); + trace("creating %s\n", dll_name); + hfile = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + if (hfile == INVALID_HANDLE_VALUE) + { + ok(0, "could not create %s\n", dll_name); + return; + } + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, &dos_header, sizeof(dos_header), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + nt_header.FileHeader.NumberOfSections = 2; + nt_header.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); + + nt_header.OptionalHeader.SectionAlignment = 0x1000; + nt_header.OptionalHeader.FileAlignment = 0x1000; + nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x2200; + nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + 2 * sizeof(IMAGE_SECTION_HEADER); + nt_header.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress = 0x1000; + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size = 0x100; + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, &nt_header.OptionalHeader, sizeof(IMAGE_OPTIONAL_HEADER), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + /* sections */ + section.PointerToRawData = nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress; + section.VirtualAddress = nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress; + section.Misc.VirtualSize = nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size; + section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, §ion, sizeof(section), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + section.PointerToRawData = 0x2000; + section.VirtualAddress = 0x2000; + i = sizeof(td)/sizeof(td[0]); + section.Misc.VirtualSize = sizeof(test_dll) + sizeof(hint) + sizeof(test_func) + sizeof(HMODULE) + + 2 * (i + 1) * sizeof(IMAGE_THUNK_DATA); + ok(section.Misc.VirtualSize <= 0x1000, "Too much tests, add a new section!\n"); + section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, §ion, sizeof(section), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + /* fill up to delay data */ + file_size = GetFileSize(hfile, NULL); + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, filler, + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress - file_size, + &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + /* delay data */ + idd.Attributes.AllAttributes = 1; + idd.DllNameRVA = 0x2000; + idd.ModuleHandleRVA = idd.DllNameRVA + sizeof(test_dll) + sizeof(hint) + sizeof(test_func); + idd.ImportAddressTableRVA = idd.ModuleHandleRVA + sizeof(HMODULE); + idd.ImportNameTableRVA = idd.ImportAddressTableRVA + (i + 1) * sizeof(IMAGE_THUNK_DATA); + idd.BoundImportAddressTableRVA = 0; + idd.UnloadInformationTableRVA = 0; + idd.TimeDateStamp = 0; + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, &idd, sizeof(idd), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, filler, sizeof(idd), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + /* fill up to extended delay data */ + file_size = GetFileSize(hfile, NULL); + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, filler, idd.DllNameRVA - file_size, &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + /* extended delay data */ + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, test_dll, sizeof(test_dll), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, &hint, sizeof(hint), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, test_func, sizeof(test_func), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + file_size = GetFileSize(hfile, NULL); + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, filler, idd.ImportNameTableRVA - file_size, &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) + { + if (td[i].func) + itd32.u1.AddressOfData = idd.DllNameRVA + sizeof(test_dll); + else + itd32.u1.Ordinal = td[i].ordinal; + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + } + + itd32.u1.Ordinal = 0; + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + /* fill up to eof */ + file_size = GetFileSize(hfile, NULL); + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, filler, section.VirtualAddress + section.Misc.VirtualSize - file_size, &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + CloseHandle(hfile); + + SetLastError(0xdeadbeef); + hlib = LoadLibraryA(dll_name); + ok(hlib != NULL, "LoadLibrary error %u\n", GetLastError()); + if (!hlib) + { + skip("couldn't load %s.\n", dll_name); + DeleteFileA(dll_name); + return; + } + + delaydir = RtlImageDirectoryEntryToData(hlib, TRUE, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, &file_size); + if (!delaydir) + { + skip("haven't found section for delay import directory.\n"); + FreeLibrary(hlib); + DeleteFileA(dll_name); + return; + } + + for (;;) + { + IMAGE_THUNK_DATA *itdn, *itda; + HMODULE htarget; + + if (!delaydir->DllNameRVA || + !delaydir->ImportAddressTableRVA || + !delaydir->ImportNameTableRVA) break; + + itdn = RVAToAddr(delaydir->ImportNameTableRVA, hlib); + itda = RVAToAddr(delaydir->ImportAddressTableRVA, hlib); + htarget = LoadLibraryA(RVAToAddr(delaydir->DllNameRVA, hlib)); + + for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) + { + void *ret, *load; + + if (IMAGE_SNAP_BY_ORDINAL(itdn[i].u1.Ordinal)) + load = (void *)GetProcAddress(htarget, (LPSTR)IMAGE_ORDINAL(itdn[i].u1.Ordinal)); + else + { + const IMAGE_IMPORT_BY_NAME* iibn = RVAToAddr(itdn[i].u1.AddressOfData, hlib); + load = (void *)GetProcAddress(htarget, (char*)iibn->Name); + } + + cb_count = 0; + ret = pResolveDelayLoadedAPI(hlib, delaydir, failuredllhook, NULL, &itda[i], 0); + if (td[i].succeeds) + { + ok(ret != NULL, "Test %u: ResolveDelayLoadedAPI failed\n", i); + ok(ret == load, "Test %u: expected %p, got %p\n", i, load, ret); + ok(ret == (void*)itda[i].u1.AddressOfData, "Test %u: expected %p, got %p\n", + i, ret, (void*)itda[i].u1.AddressOfData); + ok(!cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count); + } + else + { + ok(ret == (void*)0xdeadbeef, "Test %u: ResolveDelayLoadedAPI succeeded with %p\n", i, ret); + ok(cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count); + } + } + delaydir++; + } + + FreeLibrary(hlib); + trace("deleting %s\n", dll_name); + DeleteFileA(dll_name); +} + START_TEST(loader) { int argc; char **argv; - HANDLE mapping; + HANDLE ntdll, mapping; + SYSTEM_INFO si; - pNtMapViewOfSection = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtMapViewOfSection"); - pNtUnmapViewOfSection = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtUnmapViewOfSection"); - pNtTerminateProcess = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtTerminateProcess"); - pNtQueryInformationProcess = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationProcess"); - pNtSetInformationProcess = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtSetInformationProcess"); - pLdrShutdownProcess = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "LdrShutdownProcess"); - pRtlDllShutdownInProgress = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlDllShutdownInProgress"); - pNtAllocateVirtualMemory = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtAllocateVirtualMemory"); - pNtFreeVirtualMemory = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtFreeVirtualMemory"); - pLdrLockLoaderLock = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "LdrLockLoaderLock"); - pLdrUnlockLoaderLock = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "LdrUnlockLoaderLock"); - pRtlAcquirePebLock = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlAcquirePebLock"); - pRtlReleasePebLock = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlReleasePebLock"); + ntdll = GetModuleHandleA("ntdll.dll"); + pNtCreateSection = (void *)GetProcAddress(ntdll, "NtCreateSection"); + pNtMapViewOfSection = (void *)GetProcAddress(ntdll, "NtMapViewOfSection"); + pNtUnmapViewOfSection = (void *)GetProcAddress(ntdll, "NtUnmapViewOfSection"); + pNtTerminateProcess = (void *)GetProcAddress(ntdll, "NtTerminateProcess"); + pNtQueryInformationProcess = (void *)GetProcAddress(ntdll, "NtQueryInformationProcess"); + pNtSetInformationProcess = (void *)GetProcAddress(ntdll, "NtSetInformationProcess"); + pLdrShutdownProcess = (void *)GetProcAddress(ntdll, "LdrShutdownProcess"); + pRtlDllShutdownInProgress = (void *)GetProcAddress(ntdll, "RtlDllShutdownInProgress"); + pNtAllocateVirtualMemory = (void *)GetProcAddress(ntdll, "NtAllocateVirtualMemory"); + pNtFreeVirtualMemory = (void *)GetProcAddress(ntdll, "NtFreeVirtualMemory"); + pLdrLockLoaderLock = (void *)GetProcAddress(ntdll, "LdrLockLoaderLock"); + pLdrUnlockLoaderLock = (void *)GetProcAddress(ntdll, "LdrUnlockLoaderLock"); + pRtlAcquirePebLock = (void *)GetProcAddress(ntdll, "RtlAcquirePebLock"); + pRtlReleasePebLock = (void *)GetProcAddress(ntdll, "RtlReleasePebLock"); + pResolveDelayLoadedAPI = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ResolveDelayLoadedAPI"); - mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "winetest_loader"); + GetSystemInfo( &si ); + page_size = si.dwPageSize; + dos_header.e_magic = IMAGE_DOS_SIGNATURE; + dos_header.e_lfanew = sizeof(dos_header); + + mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "winetest_loader"); ok(mapping != 0, "CreateFileMapping failed\n"); child_failures = MapViewOfFile(mapping, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 4096); if (*child_failures == -1) { - is_child = 1; *child_failures = 0; } else @@ -2226,7 +2797,9 @@ START_TEST(loader) } test_Loader(); + test_ResolveDelayLoadedAPI(); test_ImportDescriptors(); test_section_access(); + test_import_resolution(); test_ExitProcess(); } diff --git a/rostests/winetests/kernel32/locale.c b/rostests/winetests/kernel32/locale.c index 96013df92cb..4d4f9c25ccc 100755 --- a/rostests/winetests/kernel32/locale.c +++ b/rostests/winetests/kernel32/locale.c @@ -64,7 +64,7 @@ static inline WCHAR *strchrW( const WCHAR *str, WCHAR ch ) return NULL; } -static inline int isdigitW( WCHAR wc ) +static inline BOOL isdigitW( WCHAR wc ) { WORD type; GetStringTypeW( CT_CTYPE1, &wc, 1, &type ); @@ -75,9 +75,9 @@ static inline int isdigitW( WCHAR wc ) static HMODULE hKernel32; static WORD enumCount; -static BOOL (WINAPI *pEnumSystemLanguageGroupsA)(LANGUAGEGROUP_ENUMPROC, DWORD, LONG_PTR); -static BOOL (WINAPI *pEnumLanguageGroupLocalesA)(LANGGROUPLOCALE_ENUMPROC, LGRPID, DWORD, LONG_PTR); -static BOOL (WINAPI *pEnumUILanguagesA)(UILANGUAGE_ENUMPROC, DWORD, LONG_PTR); +static BOOL (WINAPI *pEnumSystemLanguageGroupsA)(LANGUAGEGROUP_ENUMPROCA, DWORD, LONG_PTR); +static BOOL (WINAPI *pEnumLanguageGroupLocalesA)(LANGGROUPLOCALE_ENUMPROCA, LGRPID, DWORD, LONG_PTR); +static BOOL (WINAPI *pEnumUILanguagesA)(UILANGUAGE_ENUMPROCA, DWORD, LONG_PTR); static BOOL (WINAPI *pEnumSystemLocalesEx)(LOCALE_ENUMPROCEX, DWORD, LPARAM, LPVOID); static INT (WINAPI *pLCMapStringEx)(LPCWSTR, DWORD, LPCWSTR, INT, LPWSTR, INT, LPNLSVERSIONINFO, LPVOID, LPARAM); static LCID (WINAPI *pLocaleNameToLCID)(LPCWSTR, DWORD); @@ -91,6 +91,8 @@ static INT (WINAPI *pIdnToUnicode)(DWORD, LPCWSTR, INT, LPWSTR, INT); static INT (WINAPI *pGetLocaleInfoEx)(LPCWSTR, LCTYPE, LPWSTR, INT); static BOOL (WINAPI *pIsValidLocaleName)(LPCWSTR); static INT (WINAPI *pCompareStringOrdinal)(const WCHAR *, INT, const WCHAR *, INT, BOOL); +static INT (WINAPI *pCompareStringEx)(LPCWSTR, DWORD, LPCWSTR, INT, LPCWSTR, INT, + LPNLSVERSIONINFO, LPVOID, LPARAM); static void InitFunctionPointers(void) { @@ -111,6 +113,7 @@ static void InitFunctionPointers(void) pGetLocaleInfoEx = (void*)GetProcAddress(hKernel32, "GetLocaleInfoEx"); pIsValidLocaleName = (void*)GetProcAddress(hKernel32, "IsValidLocaleName"); pCompareStringOrdinal = (void*)GetProcAddress(hKernel32, "CompareStringOrdinal"); + pCompareStringEx = (void*)GetProcAddress(hKernel32, "CompareStringEx"); } #define eq(received, expected, label, type) \ @@ -121,7 +124,7 @@ static void InitFunctionPointers(void) #define COUNTOF(x) (sizeof(x)/sizeof(x)[0]) #define STRINGSA(x,y) strcpy(input, x); strcpy(Expected, y); SetLastError(0xdeadbeef); buffer[0] = '\0' -#define EXPECT_LENA ok(ret == lstrlen(Expected)+1, "Expected Len %d, got %d\n", lstrlen(Expected)+1, ret) +#define EXPECT_LENA ok(ret == lstrlenA(Expected)+1, "Expected len %d, got %d\n", lstrlenA(Expected)+1, ret) #define EXPECT_EQA ok(strncmp(buffer, Expected, strlen(Expected)) == 0, \ "Expected '%s', got '%s'\n", Expected, buffer) @@ -660,21 +663,23 @@ static void test_GetDateFormatA(void) "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); STRINGSA("ddd',' MMM dd ''''yy","5/4/2002"); /* Default to DATE_SHORTDATE */ - ret = GetDateFormat(lcid, NUO, &curtime, NULL, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid, NUO, &curtime, NULL, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); if (strncmp(buffer, Expected, strlen(Expected)) && strncmp(buffer, "5/4/02", strlen(Expected)) != 0) ok (0, "Expected '%s' or '5/4/02', got '%s'\n", Expected, buffer); - STRINGSA("ddd',' MMM dd ''''yy", "Saturday, May 04, 2002"); /* DATE_LONGDATE */ - ret = GetDateFormat(lcid, NUO|DATE_LONGDATE, &curtime, NULL, buffer, COUNTOF(buffer)); + SetLastError(0xdeadbeef); buffer[0] = '\0'; /* DATE_LONGDATE */ + ret = GetDateFormatA(lcid, NUO|DATE_LONGDATE, &curtime, NULL, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); - EXPECT_LENA; EXPECT_EQA; + ok(strcmp(buffer, "Saturday, May 04, 2002") == 0 || + strcmp(buffer, "Saturday, May 4, 2002") == 0 /* Win 8 */, + "got an unexpected date string '%s'\n", buffer); /* test for expected DATE_YEARMONTH behavior with null format */ /* NT4 returns ERROR_INVALID_FLAGS for DATE_YEARMONTH */ STRINGSA("ddd',' MMM dd ''''yy", ""); /* DATE_YEARMONTH */ SetLastError(0xdeadbeef); - ret = GetDateFormat(lcid, NUO|DATE_YEARMONTH, &curtime, input, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid, NUO|DATE_YEARMONTH, &curtime, input, buffer, COUNTOF(buffer)); ok(!ret && GetLastError() == ERROR_INVALID_FLAGS, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError()); EXPECT_EQA; @@ -683,12 +688,12 @@ static void test_GetDateFormatA(void) /* and return values */ STRINGSA("m/d/y", ""); /* Invalid flags */ SetLastError(0xdeadbeef); - ret = GetDateFormat(lcid, DATE_YEARMONTH|DATE_SHORTDATE|DATE_LONGDATE, + ret = GetDateFormatA(lcid, DATE_YEARMONTH|DATE_SHORTDATE|DATE_LONGDATE, &curtime, input, buffer, COUNTOF(buffer)); ok(!ret && GetLastError() == ERROR_INVALID_FLAGS, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError()); - ret = GetDateFormat(lcid_ru, 0, &curtime, "ddMMMM", buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, "ddMMMM", buffer, COUNTOF(buffer)); if (!ret) { win_skip("LANG_RUSSIAN locale data unavailable\n"); @@ -697,37 +702,37 @@ static void test_GetDateFormatA(void) /* month part should be in genitive form */ strcpy(genitive_month, buffer + 2); - ret = GetDateFormat(lcid_ru, 0, &curtime, "MMMM", buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, "MMMM", buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); strcpy(month, buffer); ok(strcmp(genitive_month, month) != 0, "Expected different month forms\n"); - ret = GetDateFormat(lcid_ru, 0, &curtime, "ddd", buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, "ddd", buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); strcpy(short_day, buffer); STRINGSA("dd MMMMddd dd", ""); sprintf(Expected, "04 %s%s 04", genitive_month, short_day); - ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); EXPECT_EQA; STRINGSA("MMMMddd dd", ""); sprintf(Expected, "%s%s 04", month, short_day); - ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); EXPECT_EQA; STRINGSA("MMMMddd", ""); sprintf(Expected, "%s%s", month, short_day); - ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); EXPECT_EQA; STRINGSA("MMMMdd", ""); sprintf(Expected, "%s04", genitive_month); sprintf(Broken, "%s04", month); - ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, @@ -736,7 +741,7 @@ static void test_GetDateFormatA(void) STRINGSA("MMMMdd ddd", ""); sprintf(Expected, "%s04 %s", genitive_month, short_day); sprintf(Broken, "%s04 %s", month, short_day); - ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, @@ -744,14 +749,14 @@ static void test_GetDateFormatA(void) STRINGSA("dd dddMMMM", ""); sprintf(Expected, "04 %s%s", short_day, month); - ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); EXPECT_EQA; STRINGSA("dd dddMMMM ddd MMMMdd", ""); sprintf(Expected, "04 %s%s %s %s04", short_day, month, short_day, genitive_month); sprintf(Broken, "04 %s%s %s %s04", short_day, month, short_day, month); - ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, @@ -761,7 +766,7 @@ static void test_GetDateFormatA(void) STRINGSA("ddd',' MMMM dd", ""); sprintf(Expected, "%s, %s 04", short_day, genitive_month); sprintf(Broken, "%s, %s 04", short_day, month); - ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, @@ -1455,7 +1460,7 @@ static void test_CompareStringA(void) ret = CompareStringA(lcid, NORM_IGNORECASE, "_", -1, ".", -1); todo_wine ok(ret == CSTR_GREATER_THAN, "\"_\" vs \".\" expected CSTR_GREATER_THAN, got %d\n", ret); - ret = lstrcmpi("#", "."); + ret = lstrcmpiA("#", "."); todo_wine ok(ret == -1, "\"#\" vs \".\" expected -1, got %d\n", ret); lcid = MAKELCID(MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), SORT_DEFAULT); @@ -1473,6 +1478,202 @@ static void test_CompareStringA(void) "ret %d, error %d, expected value %d\n", ret, GetLastError(), CSTR_EQUAL); } +struct comparestringex_test { + const char *locale; + DWORD flags; + const WCHAR first[2]; + const WCHAR second[2]; + INT ret; + INT broken; + BOOL todo; +}; + +static const struct comparestringex_test comparestringex_tests[] = { + /* default behavior */ + { /* 0 */ + "tr-TR", 0, + {'i',0}, {'I',0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 1 */ + "tr-TR", 0, + {'i',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 2 */ + "tr-TR", 0, + {'i',0}, {0x131,0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 3 */ + "tr-TR", 0, + {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE + }, + { /* 4 */ + "tr-TR", 0, + {'I',0}, {0x131,0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 5 */ + "tr-TR", 0, + {0x130,0}, {0x131,0}, CSTR_GREATER_THAN, -1, TRUE + }, + /* with NORM_IGNORECASE */ + { /* 6 */ + "tr-TR", NORM_IGNORECASE, + {'i',0}, {'I',0}, CSTR_EQUAL, -1, FALSE + }, + { /* 7 */ + "tr-TR", NORM_IGNORECASE, + {'i',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE + }, + { /* 8 */ + "tr-TR", NORM_IGNORECASE, + {'i',0}, {0x131,0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 9 */ + "tr-TR", NORM_IGNORECASE, + {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE + }, + { /* 10 */ + "tr-TR", NORM_IGNORECASE, + {'I',0}, {0x131,0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 11 */ + "tr-TR", NORM_IGNORECASE, + {0x130,0}, {0x131,0}, CSTR_GREATER_THAN, -1, TRUE + }, + /* with NORM_LINGUISTIC_CASING */ + { /* 12 */ + "tr-TR", NORM_LINGUISTIC_CASING, + {'i',0}, {'I',0}, CSTR_GREATER_THAN, CSTR_LESS_THAN, TRUE + }, + { /* 13 */ + "tr-TR", NORM_LINGUISTIC_CASING, + {'i',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 14 */ + "tr-TR", NORM_LINGUISTIC_CASING, + {'i',0}, {0x131,0}, CSTR_GREATER_THAN, CSTR_LESS_THAN, TRUE + }, + { /* 15 */ + "tr-TR", NORM_LINGUISTIC_CASING, + {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE + }, + { /* 16 */ + "tr-TR", NORM_LINGUISTIC_CASING, + {'I',0}, {0x131,0}, CSTR_GREATER_THAN, CSTR_LESS_THAN, TRUE + }, + { /* 17 */ + "tr-TR", NORM_LINGUISTIC_CASING, + {0x130,0}, {0x131,0}, CSTR_GREATER_THAN, -1, TRUE + }, + /* with LINGUISTIC_IGNORECASE */ + { /* 18 */ + "tr-TR", LINGUISTIC_IGNORECASE, + {'i',0}, {'I',0}, CSTR_EQUAL, -1, TRUE + }, + { /* 19 */ + "tr-TR", LINGUISTIC_IGNORECASE, + {'i',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 20 */ + "tr-TR", LINGUISTIC_IGNORECASE, + {'i',0}, {0x131,0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 21 */ + "tr-TR", LINGUISTIC_IGNORECASE, + {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE + }, + { /* 22 */ + "tr-TR", LINGUISTIC_IGNORECASE, + {'I',0}, {0x131,0}, CSTR_LESS_THAN, -1, FALSE + }, + { /* 23 */ + "tr-TR", LINGUISTIC_IGNORECASE, + {0x130,0}, {0x131,0}, CSTR_GREATER_THAN, -1, TRUE + }, + /* with NORM_LINGUISTIC_CASING | NORM_IGNORECASE */ + { /* 24 */ + "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, + {'i',0}, {'I',0}, CSTR_GREATER_THAN, CSTR_EQUAL, TRUE + }, + { /* 25 */ + "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, + {'i',0}, {0x130,0}, CSTR_EQUAL, CSTR_LESS_THAN, FALSE + }, + { /* 26 */ + "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, + {'i',0}, {0x131,0}, CSTR_GREATER_THAN, CSTR_LESS_THAN, TRUE + }, + { /* 27 */ + "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, + {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE + }, + { /* 28 */ + "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, + {'I',0}, {0x131,0}, CSTR_EQUAL, CSTR_LESS_THAN, TRUE + }, + { /* 29 */ + "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, + {0x130,0}, {0x131,0}, CSTR_GREATER_THAN, -1, TRUE + }, + /* with NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE */ + { /* 30 */ + "tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE, + {'i',0}, {'I',0}, CSTR_GREATER_THAN, CSTR_EQUAL, TRUE + }, + { /* 31 */ + "tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE, + {'i',0}, {0x130,0}, CSTR_EQUAL, CSTR_LESS_THAN, TRUE + }, + { /* 32 */ + "tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE, + {'i',0}, {0x131,0}, CSTR_GREATER_THAN, CSTR_LESS_THAN, TRUE + }, + { /* 33 */ + "tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE, + {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE + }, + { /* 34 */ + "tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE, + {'I',0}, {0x131,0}, CSTR_EQUAL, CSTR_LESS_THAN, TRUE + }, + { /* 35 */ + "tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE, + {0x130,0}, {0x131,0}, CSTR_GREATER_THAN, CSTR_LESS_THAN, TRUE + } +}; + +static void test_CompareStringEx(void) +{ + const char *op[] = {"ERROR", "CSTR_LESS_THAN", "CSTR_EQUAL", "CSTR_GREATER_THAN"}; + WCHAR locale[6]; + INT ret, i; + + /* CompareStringEx is only available on Vista+ */ + if (!pCompareStringEx) + { + win_skip("CompareStringEx not supported\n"); + return; + } + + for (i = 0; i < sizeof(comparestringex_tests)/sizeof(comparestringex_tests[0]); i++) + { + const struct comparestringex_test *e = &comparestringex_tests[i]; + + MultiByteToWideChar(CP_ACP, 0, e->locale, -1, locale, sizeof(locale)/sizeof(WCHAR)); + ret = pCompareStringEx(locale, e->flags, e->first, -1, e->second, -1, NULL, NULL, 0); + if (e->todo) + { + todo_wine ok(ret == e->ret || broken(ret == e->broken), + "%d: got %s, expected %s\n", i, op[ret], op[e->ret]); + } + else + { + ok(ret == e->ret || broken(ret == e->broken), + "%d: got %s, expected %s\n", i, op[ret], op[e->ret]); + } + } + +} + static void test_LCMapStringA(void) { int ret, ret2; @@ -2321,6 +2522,7 @@ static void test_FoldStringW(void) 0x0030, /* '0'-'9' */ 0x0660, /* Eastern Arabic */ 0x06F0, /* Arabic - Hindu */ + 0x07C0, /* Nko */ 0x0966, /* Devengari */ 0x09E6, /* Bengalii */ 0x0A66, /* Gurmukhi */ @@ -2332,16 +2534,37 @@ static void test_FoldStringW(void) 0x0D66, /* Maylayalam */ 0x0E50, /* Thai */ 0x0ED0, /* Laos */ - 0x0F29, /* Tibet - 0 is out of sequence */ + 0x0F20, /* Tibet */ + 0x0F29, /* Tibet half - 0 is out of sequence */ + 0x1040, /* Myanmar */ + 0x1090, /* Myanmar Shan */ + 0x1368, /* Ethiopic - no 0 */ + 0x17E0, /* Khmer */ + 0x1810, /* Mongolian */ + 0x1946, /* Limbu */ + 0x19D0, /* New Tai Lue */ + 0x1A80, /* Tai Tham Hora */ + 0x1A90, /* Tai Tham Tham */ + 0x1B50, /* Balinese */ + 0x1BB0, /* Sundanese */ + 0x1C40, /* Lepcha */ + 0x1C50, /* Ol Chiki */ 0x2070, /* Superscript - 1, 2, 3 are out of sequence */ 0x2080, /* Subscript */ 0x245F, /* Circled - 0 is out of sequence */ 0x2473, /* Bracketed */ 0x2487, /* Full stop */ + 0x24F4, /* Double Circled */ 0x2775, /* Inverted circled - No 0 */ 0x277F, /* Patterned circled - No 0 */ 0x2789, /* Inverted Patterned circled - No 0 */ 0x3020, /* Hangzhou */ + 0xA620, /* Vai */ + 0xA8D0, /* Saurashtra */ + 0xA900, /* Kayah Li */ + 0xA9D0, /* Javanese */ + 0xAA50, /* Cham */ + 0xABF0, /* Meetei Mayek */ 0xff10, /* Pliene chasse (?) */ 0xffff /* Terminator */ }; @@ -2351,8 +2574,17 @@ static void test_FoldStringW(void) 0xB9, /* Superscript 1 */ 0xB2, /* Superscript 2 */ 0xB3, /* Superscript 3 */ + 0x0C78, /* Telugu Fraction 0 */ + 0x0C79, /* Telugu Fraction 1 */ + 0x0C7A, /* Telugu Fraction 2 */ + 0x0C7B, /* Telugu Fraction 3 */ + 0x0C7C, /* Telugu Fraction 1 */ + 0x0C7D, /* Telugu Fraction 2 */ + 0x0C7E, /* Telugu Fraction 3 */ 0x0F33, /* Tibetan half zero */ + 0x19DA, /* New Tai Lue Tham 1 */ 0x24EA, /* Circled 0 */ + 0x24FF, /* Negative Circled 0 */ 0x3007, /* Ideographic number zero */ '\0' /* Terminator */ }; @@ -2361,8 +2593,10 @@ static void test_FoldStringW(void) { 0x0BE6, /* No Tamil 0 */ 0x0F29, /* No Tibetan half zero (out of sequence) */ + 0x1368, /* No Ethiopic 0 */ 0x2473, /* No Bracketed 0 */ 0x2487, /* No 0 Full stop */ + 0x24F4, /* No double circled 0 */ 0x2775, /* No inverted circled 0 */ 0x277F, /* No patterned circled */ 0x2789, /* No inverted Patterned circled */ @@ -2490,10 +2724,11 @@ static void test_FoldStringW(void) ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError()); ok(dst[0] == ch || strchrW(outOfSequenceDigits, ch) || - /* Wine (correctly) maps all Unicode 4.0+ digits */ - isdigitW(ch) || (ch >= 0x24F5 && ch <= 0x24FD) || ch == 0x24FF || ch == 0x19da || - (ch >= 0x1369 && ch <= 0x1371), - "MAP_FOLDDIGITS: ch %d 0x%04x Expected unchanged got %d\n", ch, ch, dst[0]); + (ch >= 0xa8e0 && ch <= 0xa8e9), /* combining Devanagari on Win8 */ + "MAP_FOLDDIGITS: ch 0x%04x Expected unchanged got %04x\n", ch, dst[0]); + ok(!isdigitW(ch) || strchrW(outOfSequenceDigits, ch) || + broken( ch >= 0xbf0 && ch <= 0xbf2 ), /* win2k */ + "char %04x should not be a digit\n", ch ); } if (digitRanges[j] == 0xffff) @@ -2520,7 +2755,7 @@ static void test_FoldStringW(void) (digitRanges[j] == 0x3020 && dst[0] == ch) || /* Hangzhou not present in all Windows versions */ (digitRanges[j] == 0x0F29 && dst[0] == ch) || /* Tibetan not present in all Windows versions */ strchrW(noDigitAvailable, c), - "MAP_FOLDDIGITS: ch %d Expected %d got %d\n", + "MAP_FOLDDIGITS: ch %04x Expected %04x got %04x\n", ch, '0' + digitRanges[j] - ch, dst[0]); } prev_ch = ch; @@ -3108,6 +3343,7 @@ static void test_IdnToNameprepUnicode(void) DWORD in_len; const WCHAR in[64]; DWORD ret; + DWORD broken_ret; const WCHAR out[64]; DWORD flags; DWORD err; @@ -3115,77 +3351,77 @@ static void test_IdnToNameprepUnicode(void) } test_data[] = { { 5, {'t','e','s','t',0}, - 5, {'t','e','s','t',0}, + 5, 5, {'t','e','s','t',0}, 0, 0xdeadbeef }, { 3, {'a',0xe111,'b'}, - 0, {0}, + 0, 0, {0}, 0, ERROR_INVALID_NAME }, { 4, {'t',0,'e',0}, - 0, {0}, + 0, 0, {0}, 0, ERROR_INVALID_NAME }, { 1, {'T',0}, - 1, {'T',0}, + 1, 1, {'T',0}, 0, 0xdeadbeef }, { 1, {0}, - 0, {0}, + 0, 0, {0}, 0, ERROR_INVALID_NAME }, { 6, {' ','-','/','[',']',0}, - 6, {' ','-','/','[',']',0}, + 6, 6, {' ','-','/','[',']',0}, 0, 0xdeadbeef }, { 3, {'a','-','a'}, - 3, {'a','-','a'}, + 3, 3, {'a','-','a'}, IDN_USE_STD3_ASCII_RULES, 0xdeadbeef }, { 3, {'a','a','-'}, - 0, {0}, + 0, 0, {0}, IDN_USE_STD3_ASCII_RULES, ERROR_INVALID_NAME }, { /* FoldString is not working as expected when MAP_FOLDCZONE is specified (composition+compatibility) */ 10, {'T',0xdf,0x130,0x143,0x37a,0x6a,0x30c,' ',0xaa,0}, - 12, {'t','s','s','i',0x307,0x144,' ',0x3b9,0x1f0,' ','a',0}, + 12, 12, {'t','s','s','i',0x307,0x144,' ',0x3b9,0x1f0,' ','a',0}, 0, 0xdeadbeef, TRUE }, { 11, {'t',0xad,0x34f,0x1806,0x180b,0x180c,0x180d,0x200b,0x200c,0x200d,0}, - 2, {'t',0}, + 2, 0, {'t',0}, 0, 0xdeadbeef }, { /* Another example of incorrectly working FoldString (composition) */ 2, {0x3b0, 0}, - 2, {0x3b0, 0}, + 2, 2, {0x3b0, 0}, 0, 0xdeadbeef, TRUE }, { 2, {0x221, 0}, - 0, {0}, + 0, 2, {0}, 0, ERROR_NO_UNICODE_TRANSLATION }, { 2, {0x221, 0}, - 2, {0x221, 0}, + 2, 2, {0x221, 0}, IDN_ALLOW_UNASSIGNED, 0xdeadbeef }, { 5, {'a','.','.','a',0}, - 0, {0}, + 0, 0, {0}, 0, ERROR_INVALID_NAME }, { 3, {'a','.',0}, - 3, {'a','.',0}, + 3, 3, {'a','.',0}, 0, 0xdeadbeef }, }; @@ -3245,7 +3481,8 @@ static void test_IdnToNameprepUnicode(void) ret = pIdnToNameprepUnicode(4, NULL, 0, NULL, 0); err = GetLastError(); ok(ret == 0, "ret = %d\n", ret); - ok(err == ERROR_INVALID_FLAGS, "err = %d\n", err); + ok(err == ERROR_INVALID_FLAGS || err == ERROR_INVALID_PARAMETER /* Win8 */, + "err = %d\n", err); for (i=0; i=0) && (!done);i--) { if(path[i]=='.') - if(ext!=len) error=1; else ext=i; + if(ext!=len) error=TRUE; else ext=i; else if(path[i]=='\\') { if(i==len-1) { - error=1; + error=TRUE; } else { fil=i; - done=1; + done=TRUE; } } } @@ -293,7 +308,7 @@ static void test_setdir(CHAR *olddir,CHAR *newdir, "%s: SetCurrentDirectory did not change the directory, though it passed\n", errstr); ok(SetCurrentDirectoryA(olddir), - "%s: Couldn't set directory to it's original value\n",errstr); + "%s: Couldn't set directory to its original value\n",errstr); } else { /* else thest that it fails correctly */ chklen=lstrlenA(olddir); @@ -1058,7 +1073,7 @@ static void test_GetLongPathNameA(void) memset(temppath, 0, MAX_PATH); length = pGetLongPathNameA(tempfile, temppath, 4); /* We have a failure so length should be the minimum plus the terminating '0' */ - ok(length >= lstrlen(tempfile) + 1, "Wrong length\n"); + ok(length >= strlen(tempfile) + 1, "Wrong length\n"); ok(temppath[0] == 0, "Buffer should not have been touched\n"); /* Some UNC syntax tests */ @@ -1089,7 +1104,7 @@ static void test_GetLongPathNameA(void) /* Now an UNC path with the computername */ lstrcpyA(unc_prefix, "\\\\"); hostsize = sizeof(unc_prefix) - 2; - GetComputerName(unc_prefix + 2, &hostsize); + GetComputerNameA(unc_prefix + 2, &hostsize); lstrcatA(unc_prefix, "\\"); /* Create a short syntax for the whole unc path */ @@ -1302,7 +1317,7 @@ static void test_GetSystemDirectory(void) DWORD total; SetLastError(0xdeadbeef); - res = GetSystemDirectory(NULL, 0); + res = GetSystemDirectoryA(NULL, 0); /* res includes the terminating Zero */ ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError()); @@ -1310,10 +1325,10 @@ static void test_GetSystemDirectory(void) /* this crashes on XP */ if (0) - GetSystemDirectory(NULL, total); + GetSystemDirectoryA(NULL, total); SetLastError(0xdeadbeef); - res = GetSystemDirectory(NULL, total-1); + res = GetSystemDirectoryA(NULL, total-1); /* 95+NT: total (includes the terminating Zero) 98+ME: 0 with ERROR_INVALID_PARAMETER */ ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)), @@ -1324,7 +1339,7 @@ static void test_GetSystemDirectory(void) buffer[0] = '\0'; SetLastError(0xdeadbeef); - res = GetSystemDirectory(buffer, total); + res = GetSystemDirectoryA(buffer, total); /* res does not include the terminating Zero */ ok( (res == (total-1)) && (buffer[0]), "returned %d with %d and '%s' (expected '%d' and a string)\n", @@ -1332,7 +1347,7 @@ static void test_GetSystemDirectory(void) buffer[0] = '\0'; SetLastError(0xdeadbeef); - res = GetSystemDirectory(buffer, total + 1); + res = GetSystemDirectoryA(buffer, total + 1); /* res does not include the terminating Zero */ ok( (res == (total-1)) && (buffer[0]), "returned %d with %d and '%s' (expected '%d' and a string)\n", @@ -1341,7 +1356,7 @@ static void test_GetSystemDirectory(void) memset(buffer, '#', total + 1); buffer[total + 2] = '\0'; SetLastError(0xdeadbeef); - res = GetSystemDirectory(buffer, total-1); + res = GetSystemDirectoryA(buffer, total-1); /* res includes the terminating Zero) */ ok( res == total, "returned %d with %d and '%s' (expected '%d')\n", res, GetLastError(), buffer, total); @@ -1349,7 +1364,7 @@ static void test_GetSystemDirectory(void) memset(buffer, '#', total + 1); buffer[total + 2] = '\0'; SetLastError(0xdeadbeef); - res = GetSystemDirectory(buffer, total-2); + res = GetSystemDirectoryA(buffer, total-2); /* res includes the terminating Zero) */ ok( res == total, "returned %d with %d and '%s' (expected '%d')\n", res, GetLastError(), buffer, total); @@ -1362,17 +1377,17 @@ static void test_GetWindowsDirectory(void) DWORD total; SetLastError(0xdeadbeef); - res = GetWindowsDirectory(NULL, 0); + res = GetWindowsDirectoryA(NULL, 0); /* res includes the terminating Zero */ ok(res > 0, "returned %d with %d (expected '>0')\n", res, GetLastError()); total = res; /* this crashes on XP */ if (0) - GetWindowsDirectory(NULL, total); + GetWindowsDirectoryA(NULL, total); SetLastError(0xdeadbeef); - res = GetWindowsDirectory(NULL, total-1); + res = GetWindowsDirectoryA(NULL, total-1); /* 95+NT: total (includes the terminating Zero) 98+ME: 0 with ERROR_INVALID_PARAMETER */ ok( (res == total) || (!res && (GetLastError() == ERROR_INVALID_PARAMETER)), @@ -1383,7 +1398,7 @@ static void test_GetWindowsDirectory(void) buffer[0] = '\0'; SetLastError(0xdeadbeef); - res = GetWindowsDirectory(buffer, total); + res = GetWindowsDirectoryA(buffer, total); /* res does not include the terminating Zero */ ok( (res == (total-1)) && (buffer[0]), "returned %d with %d and '%s' (expected '%d' and a string)\n", @@ -1391,7 +1406,7 @@ static void test_GetWindowsDirectory(void) buffer[0] = '\0'; SetLastError(0xdeadbeef); - res = GetWindowsDirectory(buffer, total + 1); + res = GetWindowsDirectoryA(buffer, total + 1); /* res does not include the terminating Zero */ ok( (res == (total-1)) && (buffer[0]), "returned %d with %d and '%s' (expected '%d' and a string)\n", @@ -1400,7 +1415,7 @@ static void test_GetWindowsDirectory(void) memset(buffer, '#', total + 1); buffer[total + 2] = '\0'; SetLastError(0xdeadbeef); - res = GetWindowsDirectory(buffer, total-1); + res = GetWindowsDirectoryA(buffer, total-1); /* res includes the terminating Zero) */ ok( res == total, "returned %d with %d and '%s' (expected '%d')\n", res, GetLastError(), buffer, total); @@ -1408,7 +1423,7 @@ static void test_GetWindowsDirectory(void) memset(buffer, '#', total + 1); buffer[total + 2] = '\0'; SetLastError(0xdeadbeef); - res = GetWindowsDirectory(buffer, total-2); + res = GetWindowsDirectoryA(buffer, total-2); /* res includes the terminating Zero) */ ok( res == total, "returned %d with %d and '%s' (expected '%d')\n", res, GetLastError(), buffer, total); @@ -1477,7 +1492,7 @@ static void test_drive_letter_case(void) memset(buf, 0, sizeof(buf)); SetLastError(0xdeadbeef); - ret = GetWindowsDirectory(buf, sizeof(buf)); + ret = GetWindowsDirectoryA(buf, sizeof(buf)); ok(ret, "GetWindowsDirectory error %u\n", GetLastError()); ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret); ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]); @@ -1486,7 +1501,7 @@ static void test_drive_letter_case(void) /* re-use the buffer returned by GetFullPathName */ buf[2] = '/'; SetLastError(0xdeadbeef); - ret = GetFullPathName(buf + 2, sizeof(buf), buf, NULL); + ret = GetFullPathNameA(buf + 2, sizeof(buf), buf, NULL); ok(ret, "GetFullPathName error %u\n", GetLastError()); ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret); ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]); @@ -1494,7 +1509,7 @@ static void test_drive_letter_case(void) memset(buf, 0, sizeof(buf)); SetLastError(0xdeadbeef); - ret = GetSystemDirectory(buf, sizeof(buf)); + ret = GetSystemDirectoryA(buf, sizeof(buf)); ok(ret, "GetSystemDirectory error %u\n", GetLastError()); ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret); ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]); @@ -1502,7 +1517,7 @@ static void test_drive_letter_case(void) memset(buf, 0, sizeof(buf)); SetLastError(0xdeadbeef); - ret = GetCurrentDirectory(sizeof(buf), buf); + ret = GetCurrentDirectoryA(sizeof(buf), buf); ok(ret, "GetCurrentDirectory error %u\n", GetLastError()); ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret); ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]); @@ -1511,7 +1526,7 @@ static void test_drive_letter_case(void) /* TEMP is an environment variable, so it can't be tested for case-sensitivity */ memset(buf, 0, sizeof(buf)); SetLastError(0xdeadbeef); - ret = GetTempPath(sizeof(buf), buf); + ret = GetTempPathA(sizeof(buf), buf); ok(ret, "GetTempPath error %u\n", GetLastError()); ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret); if (buf[0]) @@ -1522,7 +1537,7 @@ static void test_drive_letter_case(void) memset(buf, 0, sizeof(buf)); SetLastError(0xdeadbeef); - ret = GetFullPathName(".", sizeof(buf), buf, NULL); + ret = GetFullPathNameA(".", sizeof(buf), buf, NULL); ok(ret, "GetFullPathName error %u\n", GetLastError()); ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret); ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]); @@ -1530,7 +1545,7 @@ static void test_drive_letter_case(void) /* re-use the buffer returned by GetFullPathName */ SetLastError(0xdeadbeef); - ret = GetShortPathName(buf, buf, sizeof(buf)); + ret = GetShortPathNameA(buf, buf, sizeof(buf)); ok(ret, "GetShortPathName error %u\n", GetLastError()); ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret); ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]); @@ -1549,10 +1564,90 @@ static void test_drive_letter_case(void) #undef is_upper_case_letter } +static const char manifest_dep[] = +"" +"" +" " +" " +" " +""; + +static const char manifest_main[] = +"" +"" +"" +" " +" " +" " +"" +""; + +static void create_manifest_file(const char *filename, const char *manifest) +{ + WCHAR path[MAX_PATH], manifest_path[MAX_PATH]; + HANDLE file; + DWORD size; + + MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH ); + + GetTempPathW(sizeof(manifest_path)/sizeof(WCHAR), manifest_path); + lstrcatW(manifest_path, path); + + file = CreateFileW(manifest_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError()); + WriteFile(file, manifest, strlen(manifest), &size, NULL); + CloseHandle(file); +} + +static void delete_manifest_file(const char *filename) +{ + CHAR path[MAX_PATH]; + + GetTempPathA(sizeof(path), path); + strcat(path, filename); + DeleteFileA(path); +} + +static HANDLE test_create(const char *file) +{ + WCHAR path[MAX_PATH], manifest_path[MAX_PATH]; + ACTCTXW actctx; + HANDLE handle; + + MultiByteToWideChar(CP_ACP, 0, file, -1, path, MAX_PATH); + GetTempPathW(sizeof(manifest_path)/sizeof(WCHAR), manifest_path); + lstrcatW(manifest_path, path); + + memset(&actctx, 0, sizeof(ACTCTXW)); + actctx.cbSize = sizeof(ACTCTXW); + actctx.lpSource = manifest_path; + + handle = pCreateActCtxW(&actctx); + ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError()); + + ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize); + ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags); + ok(actctx.lpSource == manifest_path, "lpSource=%p\n", actctx.lpSource); + ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture); + ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId); + ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory); + ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName); + ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName); + ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule); + + return handle; +} + static void test_SearchPathA(void) { - CHAR pathA[MAX_PATH], fileA[] = "", buffA[MAX_PATH]; + static const CHAR testdepA[] = "testdep.dll"; + static const CHAR testdeprelA[] = "./testdep.dll"; + static const CHAR kernel32A[] = "kernel32.dll"; + static const CHAR fileA[] = ""; + CHAR pathA[MAX_PATH], buffA[MAX_PATH], path2A[MAX_PATH]; CHAR *ptrA = NULL; + ULONG_PTR cookie; + HANDLE handle; DWORD ret; if (!pSearchPathA) @@ -1576,12 +1671,73 @@ static void test_SearchPathA(void) ok(ret == 0, "Expected failure, got %d\n", ret); ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); + + if (!pActivateActCtx) + return; + + create_manifest_file("testdep1.manifest", manifest_dep); + create_manifest_file("main.manifest", manifest_main); + + handle = test_create("main.manifest"); + delete_manifest_file("testdep1.manifest"); + delete_manifest_file("main.manifest"); + + /* search fails without active context */ + ret = pSearchPathA(NULL, testdepA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL); + ok(ret == 0, "got %d\n", ret); + + ret = pSearchPathA(NULL, kernel32A, NULL, sizeof(path2A)/sizeof(CHAR), path2A, NULL); + ok(ret && ret == strlen(path2A), "got %d\n", ret); + + ret = pActivateActCtx(handle, &cookie); + ok(ret, "failed to activate context, %u\n", GetLastError()); + + /* works when activated */ + ret = pSearchPathA(NULL, testdepA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL); + ok(ret && ret == strlen(buffA), "got %d\n", ret); + + ret = pSearchPathA(NULL, "testdep.dll", ".ext", sizeof(buffA)/sizeof(CHAR), buffA, NULL); + ok(ret && ret == strlen(buffA), "got %d\n", ret); + + ret = pSearchPathA(NULL, "testdep", ".dll", sizeof(buffA)/sizeof(CHAR), buffA, NULL); + ok(ret && ret == strlen(buffA), "got %d\n", ret); + + ret = pSearchPathA(NULL, "testdep", ".ext", sizeof(buffA)/sizeof(CHAR), buffA, NULL); + ok(!ret, "got %d\n", ret); + + /* name contains path */ + ret = pSearchPathA(NULL, testdeprelA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL); + ok(!ret, "got %d\n", ret); + + /* fails with specified path that doesn't contain this file */ + ret = pSearchPathA(pathA, testdepA, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL); + ok(!ret, "got %d\n", ret); + + /* path is redirected for wellknown names too */ + ret = pSearchPathA(NULL, kernel32A, NULL, sizeof(buffA)/sizeof(CHAR), buffA, NULL); + ok(ret && ret == strlen(buffA), "got %d\n", ret); + ok(strcmp(buffA, path2A), "got wrong path %s, %s\n", buffA, path2A); + + ret = pDeactivateActCtx(0, cookie); + ok(ret, "failed to deactivate context, %u\n", GetLastError()); + pReleaseActCtx(handle); } static void test_SearchPathW(void) { - WCHAR pathW[MAX_PATH], fileW[] = { 0 }, buffW[MAX_PATH]; + static const WCHAR testdeprelW[] = {'.','/','t','e','s','t','d','e','p','.','d','l','l',0}; + static const WCHAR testdepW[] = {'t','e','s','t','d','e','p','.','d','l','l',0}; + static const WCHAR testdep1W[] = {'t','e','s','t','d','e','p',0}; + static const WCHAR kernel32dllW[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0}; + static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0}; + static const WCHAR ole32W[] = {'o','l','e','3','2',0}; + static const WCHAR extW[] = {'.','e','x','t',0}; + static const WCHAR dllW[] = {'.','d','l','l',0}; + static const WCHAR fileW[] = { 0 }; + WCHAR pathW[MAX_PATH], buffW[MAX_PATH], path2W[MAX_PATH]; WCHAR *ptrW = NULL; + ULONG_PTR cookie; + HANDLE handle; DWORD ret; if (!pSearchPathW) @@ -1596,12 +1752,75 @@ if (0) pSearchPathW(pathW, NULL, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW); } + GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR)); + /* empty filename */ SetLastError(0xdeadbeef); ret = pSearchPathW(pathW, fileW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, &ptrW); ok(ret == 0, "Expected failure, got %d\n", ret); ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); + + if (!pActivateActCtx) + return; + + create_manifest_file("testdep1.manifest", manifest_dep); + create_manifest_file("main.manifest", manifest_main); + + handle = test_create("main.manifest"); + delete_manifest_file("testdep1.manifest"); + delete_manifest_file("main.manifest"); + + /* search fails without active context */ + ret = pSearchPathW(NULL, testdepW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL); + ok(ret == 0, "got %d\n", ret); + + ret = pSearchPathW(NULL, kernel32dllW, NULL, sizeof(path2W)/sizeof(WCHAR), path2W, NULL); + ok(ret && ret == lstrlenW(path2W), "got %d\n", ret); + + /* full path, name without 'dll' extension */ + GetSystemDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR)); + ret = pSearchPathW(pathW, kernel32W, NULL, sizeof(path2W)/sizeof(WCHAR), path2W, NULL); + ok(ret == 0, "got %d\n", ret); + + GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR)); + + ret = pActivateActCtx(handle, &cookie); + ok(ret, "failed to activate context, %u\n", GetLastError()); + + /* works when activated */ + ret = pSearchPathW(NULL, testdepW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL); + ok(ret && ret == lstrlenW(buffW), "got %d\n", ret); + + ret = pSearchPathW(NULL, testdepW, extW, sizeof(buffW)/sizeof(WCHAR), buffW, NULL); + ok(ret && ret == lstrlenW(buffW), "got %d\n", ret); + + ret = pSearchPathW(NULL, testdep1W, dllW, sizeof(buffW)/sizeof(WCHAR), buffW, NULL); + ok(ret && ret == lstrlenW(buffW), "got %d\n", ret); + + ret = pSearchPathW(NULL, testdep1W, extW, sizeof(buffW)/sizeof(WCHAR), buffW, NULL); + ok(!ret, "got %d\n", ret); + + /* name contains path */ + ret = pSearchPathW(NULL, testdeprelW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL); + ok(!ret, "got %d\n", ret); + + /* fails with specified path that doesn't contain this file */ + ret = pSearchPathW(pathW, testdepW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL); + ok(!ret, "got %d\n", ret); + + /* path is redirected for wellknown names too, meaning it takes precedence over normal search order */ + ret = pSearchPathW(NULL, kernel32dllW, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL); + ok(ret && ret == lstrlenW(buffW), "got %d\n", ret); + ok(lstrcmpW(buffW, path2W), "got wrong path %s, %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(path2W)); + + /* path is built using on manifest file name */ + ret = pSearchPathW(NULL, ole32W, NULL, sizeof(buffW)/sizeof(WCHAR), buffW, NULL); + ok(ret && ret == lstrlenW(buffW), "got %d\n", ret); + + ret = pDeactivateActCtx(0, cookie); + ok(ret, "failed to deactivate context, %u\n", GetLastError()); + pReleaseActCtx(handle); } static void test_GetFullPathNameA(void) @@ -1717,9 +1936,72 @@ static void init_pointers(void) MAKEFUNC(NeedCurrentDirectoryForExePathW); MAKEFUNC(SearchPathA); MAKEFUNC(SearchPathW); + MAKEFUNC(ActivateActCtx); + MAKEFUNC(CreateActCtxW); + MAKEFUNC(DeactivateActCtx); + MAKEFUNC(GetCurrentActCtx); + MAKEFUNC(ReleaseActCtx); #undef MAKEFUNC } +static void test_relative_path(void) +{ + char path[MAX_PATH], buf[MAX_PATH]; + HANDLE file; + int ret; + + if (!pGetLongPathNameA) return; + + GetTempPathA(MAX_PATH, path); + ret = SetCurrentDirectoryA(path); + ok(ret, "SetCurrentDirectory error %d\n", GetLastError()); + + ret = CreateDirectoryA("foo", NULL); + ok(ret, "CreateDirectory error %d\n", GetLastError()); + file = CreateFileA("foo\\file", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "failed to create temp file\n"); + CloseHandle(file); + ret = CreateDirectoryA("bar", NULL); + ok(ret, "CreateDirectory error %d\n", GetLastError()); + ret = SetCurrentDirectoryA("bar"); + ok(ret, "SetCurrentDirectory error %d\n", GetLastError()); + + ret = GetFileAttributesA("..\\foo\\file"); + ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributes error %d\n", GetLastError()); + + strcpy(buf, "deadbeef"); + ret = pGetLongPathNameA(".", buf, MAX_PATH); + ok(ret, "GetLongPathName error %d\n", GetLastError()); + ok(!strcmp(buf, "."), "expected ., got %s\n", buf); + strcpy(buf, "deadbeef"); + ret = GetShortPathNameA(".", buf, MAX_PATH); + ok(ret, "GetShortPathName error %d\n", GetLastError()); + ok(!strcmp(buf, "."), "expected ., got %s\n", buf); + + strcpy(buf, "deadbeef"); + ret = pGetLongPathNameA("..", buf, MAX_PATH); + ok(ret, "GetLongPathName error %d\n", GetLastError()); + ok(!strcmp(buf, ".."), "expected .., got %s\n", buf); + strcpy(buf, "deadbeef"); + ret = GetShortPathNameA("..", buf, MAX_PATH); + ok(ret, "GetShortPathName error %d\n", GetLastError()); + ok(!strcmp(buf, ".."), "expected .., got %s\n", buf); + + strcpy(buf, "deadbeef"); + ret = pGetLongPathNameA("..\\foo\\file", buf, MAX_PATH); + ok(ret, "GetLongPathName error %d\n", GetLastError()); + ok(!strcmp(buf, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf); + strcpy(buf, "deadbeef"); + ret = GetShortPathNameA("..\\foo\\file", buf, MAX_PATH); + ok(ret, "GetShortPathName error %d\n", GetLastError()); + ok(!strcmp(buf, "..\\foo\\file"), "expected ..\\foo\\file, got %s\n", buf); + + SetCurrentDirectoryA(".."); + DeleteFileA("foo\\file"); + RemoveDirectoryA("foo"); + RemoveDirectoryA("bar"); +} + START_TEST(path) { CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive; @@ -1731,7 +2013,10 @@ START_TEST(path) win_skip("GetLongPathNameA is not available\n"); if (!pGetLongPathNameW) win_skip("GetLongPathNameW is not available\n"); + if (!pActivateActCtx) + win_skip("Activation contexts not supported, some tests will be skipped\n"); + test_relative_path(); test_InitPathA(curdir, &curDrive, &otherDrive); test_CurrentDirectoryA(origdir,curdir); test_PathNameA(curdir, curDrive, otherDrive); diff --git a/rostests/winetests/kernel32/pipe.c b/rostests/winetests/kernel32/pipe.c index 923c0e7adc3..b192f967d51 100755 --- a/rostests/winetests/kernel32/pipe.c +++ b/rostests/winetests/kernel32/pipe.c @@ -21,12 +21,11 @@ #include #include -#include -#include -#include -#include -#include - +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" #include "wine/test.h" #define PIPENAME "\\\\.\\PiPe\\tests_pipe.c" @@ -62,7 +61,7 @@ static void test_CreateNamedPipe(int pipemode) else trace("test_CreateNamedPipe starting in message mode\n"); /* Bad parameter checks */ - hnp = CreateNamedPipe("not a named pipe", PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, + hnp = CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -74,7 +73,7 @@ static void test_CreateNamedPipe(int pipemode) if (pipemode == PIPE_TYPE_BYTE) { /* Bad parameter checks */ - hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE, + hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -84,7 +83,7 @@ static void test_CreateNamedPipe(int pipemode) "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n"); } - hnp = CreateNamedPipe(NULL, + hnp = CreateNamedPipeA(NULL, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND, @@ -97,7 +96,7 @@ static void test_CreateNamedPipe(int pipemode) /* Functional checks */ - hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, + hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -338,7 +337,7 @@ static void test_CreateNamedPipe_instances_must_match(void) HANDLE hnp, hnp2; /* Check no mismatch */ - hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, + hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 2, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -346,7 +345,7 @@ static void test_CreateNamedPipe_instances_must_match(void) /* lpSecurityAttrib */ NULL); ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); - hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, + hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 2, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -358,7 +357,7 @@ static void test_CreateNamedPipe_instances_must_match(void) ok(CloseHandle(hnp2), "CloseHandle\n"); /* Check nMaxInstances */ - hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, + hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -366,7 +365,7 @@ static void test_CreateNamedPipe_instances_must_match(void) /* lpSecurityAttrib */ NULL); ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); - hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, + hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -378,7 +377,7 @@ static void test_CreateNamedPipe_instances_must_match(void) ok(CloseHandle(hnp), "CloseHandle\n"); /* Check PIPE_ACCESS_* */ - hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, + hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 2, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -386,7 +385,7 @@ static void test_CreateNamedPipe_instances_must_match(void) /* lpSecurityAttrib */ NULL); ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); - hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, + hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 2, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -398,7 +397,7 @@ static void test_CreateNamedPipe_instances_must_match(void) ok(CloseHandle(hnp), "CloseHandle\n"); /* check everything else */ - hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, + hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 4, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -406,7 +405,7 @@ static void test_CreateNamedPipe_instances_must_match(void) /* lpSecurityAttrib */ NULL); ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); - hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, + hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, /* nMaxInstances */ 3, /* nOutBufSize */ 102, /* nInBufSize */ 24, @@ -440,7 +439,7 @@ static DWORD CALLBACK serverThreadMain1(LPVOID arg) trace("serverThreadMain1 start\n"); /* Set up a simple echo server */ - hnp = CreateNamedPipe(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX, + hnp = CreateNamedPipeA(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, @@ -453,7 +452,7 @@ static DWORD CALLBACK serverThreadMain1(LPVOID arg) char buf[512]; DWORD written; DWORD readden; - DWORD success; + BOOL success; /* Wait for client to connect */ trace("Server calling ConnectNamedPipe...\n"); @@ -492,7 +491,7 @@ static DWORD CALLBACK serverThreadMain2(LPVOID arg) trace("serverThreadMain2\n"); /* Set up a simple echo server */ - hnp = CreateNamedPipe(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX, + hnp = CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 2, /* nOutBufSize */ 1024, @@ -505,13 +504,15 @@ static DWORD CALLBACK serverThreadMain2(LPVOID arg) char buf[512]; DWORD written; DWORD readden; - DWORD success; + DWORD ret; + BOOL success; + user_apc_ran = FALSE; if (i == 0 && pQueueUserAPC) { trace("Queueing an user APC\n"); /* verify the pipe is non alerable */ - success = pQueueUserAPC(&user_apc, GetCurrentThread(), 0); - ok(success, "QueueUserAPC failed: %d\n", GetLastError()); + ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0); + ok(ret, "QueueUserAPC failed: %d\n", GetLastError()); } /* Wait for client to connect */ @@ -544,7 +545,7 @@ static DWORD CALLBACK serverThreadMain2(LPVOID arg) /* Set up next echo server */ hnpNext = - CreateNamedPipe(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX, + CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 2, /* nOutBufSize */ 1024, @@ -568,7 +569,7 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg) trace("serverThreadMain3\n"); /* Set up a simple echo server */ - hnp = CreateNamedPipe(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + hnp = CreateNamedPipeA(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, @@ -577,7 +578,7 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg) /* lpSecurityAttrib */ NULL); ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); - hEvent = CreateEvent(NULL, /* security attribute */ + hEvent = CreateEventW(NULL, /* security attribute */ TRUE, /* manual reset event */ FALSE, /* initial state */ NULL); /* name */ @@ -588,7 +589,7 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg) DWORD written; DWORD readden; DWORD dummy; - DWORD success; + BOOL success; OVERLAPPED oOverlap; int letWFSOEwait = (i & 2); int letGORwait = (i & 1); @@ -697,7 +698,7 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg) trace("serverThreadMain4\n"); /* Set up a simple echo server */ - hnp = CreateNamedPipe(PIPENAME "serverThreadMain4", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + hnp = CreateNamedPipeA(PIPENAME "serverThreadMain4", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, @@ -714,7 +715,7 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg) DWORD written; DWORD readden; DWORD dummy; - DWORD success; + BOOL success; OVERLAPPED oConnect; OVERLAPPED oRead; OVERLAPPED oWrite; @@ -820,7 +821,7 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg) trace("serverThreadMain5\n"); /* Set up a simple echo server */ - hnp = CreateNamedPipe(PIPENAME "serverThreadMain5", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + hnp = CreateNamedPipeA(PIPENAME "serverThreadMain5", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, @@ -829,7 +830,7 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg) /* lpSecurityAttrib */ NULL); ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); - hEvent = CreateEvent(NULL, /* security attribute */ + hEvent = CreateEventW(NULL, /* security attribute */ TRUE, /* manual reset event */ FALSE, /* initial state */ NULL); /* name */ @@ -838,7 +839,7 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg) for (i = 0; i < NB_SERVER_LOOPS; i++) { char buf[512]; DWORD readden; - DWORD success; + BOOL success; OVERLAPPED oOverlap; DWORD err; @@ -964,7 +965,7 @@ static void test_NamedPipe_2(void) trace("test_NamedPipe_2 starting\n"); /* Set up a twenty second timeout */ - alarm_event = CreateEvent( NULL, TRUE, FALSE, NULL ); + alarm_event = CreateEventW( NULL, TRUE, FALSE, NULL ); SetLastError(0xdeadbeef); alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 20000, 0, &alarmThreadId); ok(alarmThread != NULL, "CreateThread failed: %d\n", GetLastError()); @@ -1020,7 +1021,7 @@ static int test_DisconnectNamedPipe(void) DWORD ret; SetLastError(0xdeadbeef); - hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, + hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, @@ -1177,7 +1178,7 @@ static DWORD CALLBACK named_pipe_client_func(LPVOID p) CloseHandle(process_token); } - pipe = CreateFile(PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, params->security_flags, NULL); + pipe = CreateFileA(PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, params->security_flags, NULL); ok(pipe != INVALID_HANDLE_VALUE, "CreateFile for pipe failed with error %d\n", GetLastError()); ret = WriteFile(pipe, message, sizeof(message), &bytes_written, NULL); @@ -1258,7 +1259,7 @@ static void test_ImpersonateNamedPipeClient(HANDLE hClientToken, DWORD security_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; DWORD size; - hPipeServer = CreateNamedPipe(PIPE_NAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT, NULL); + hPipeServer = CreateNamedPipeA(PIPE_NAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT, NULL); ok(hPipeServer != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with error %d\n", GetLastError()); params.security_flags = security_flags; @@ -1646,7 +1647,7 @@ static void test_NamedPipeHandleState(void) DWORD state, instances, maxCollectionCount, collectDataTimeout; char userName[MAX_PATH]; - server = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, + server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, @@ -1654,10 +1655,10 @@ static void test_NamedPipeHandleState(void) /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, /* lpSecurityAttrib */ NULL); ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); - ret = GetNamedPipeHandleState(server, NULL, NULL, NULL, NULL, NULL, 0); + ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0); todo_wine ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); - ret = GetNamedPipeHandleState(server, &state, &instances, NULL, NULL, NULL, + ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL, 0); todo_wine ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); @@ -1670,7 +1671,7 @@ static void test_NamedPipeHandleState(void) * on a local pipe. */ SetLastError(0xdeadbeef); - ret = GetNamedPipeHandleState(server, &state, &instances, + ret = GetNamedPipeHandleStateA(server, &state, &instances, &maxCollectionCount, &collectDataTimeout, userName, sizeof(userName) / sizeof(userName[0])); todo_wine @@ -1703,7 +1704,7 @@ static void test_NamedPipeHandleState(void) CloseHandle(client); CloseHandle(server); - server = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, + server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, @@ -1711,10 +1712,10 @@ static void test_NamedPipeHandleState(void) /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, /* lpSecurityAttrib */ NULL); ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); - ret = GetNamedPipeHandleState(server, NULL, NULL, NULL, NULL, NULL, 0); + ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0); todo_wine ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); - ret = GetNamedPipeHandleState(server, &state, &instances, NULL, NULL, NULL, + ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL, 0); todo_wine ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); @@ -1761,7 +1762,7 @@ static void test_readfileex_pending(void) const char test_string[] = "test"; int i; - server = CreateNamedPipe(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, + server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT, /* nMaxInstances */ 1, /* nOutBufSize */ 1024, @@ -1855,6 +1856,51 @@ static void test_readfileex_pending(void) ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); + num_bytes = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadFile(INVALID_HANDLE_VALUE, read_buf, 0, &num_bytes, NULL); + ok(!ret, "ReadFile should fail\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError()); + ok(num_bytes == 0, "expected 0, got %u\n", num_bytes); + + S(U(overlapped)).Offset = 0; + S(U(overlapped)).OffsetHigh = 0; + overlapped.Internal = -1; + overlapped.InternalHigh = -1; + overlapped.hEvent = event; + num_bytes = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadFile(server, read_buf, 0, &num_bytes, &overlapped); +todo_wine + ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); + ok(num_bytes == 0, "bytes %u\n", num_bytes); + ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); +todo_wine + ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh); + + wait = WaitForSingleObject(event, 100); + ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", wait); + + num_bytes = 0xdeadbeef; + ret = WriteFile(client, test_string, 1, &num_bytes, NULL); + ok(ret, "WriteFile failed\n"); + ok(num_bytes == 1, "bytes %u\n", num_bytes); + + wait = WaitForSingleObject(event, 100); +todo_wine + ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); + + ok(num_bytes == 1, "bytes %u\n", num_bytes); +todo_wine + ok((NTSTATUS)overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", overlapped.Internal); + ok(overlapped.InternalHigh == 0, "expected 0, got %lu\n", overlapped.InternalHigh); + + /* read the pending byte and clear the pipe */ + num_bytes = 0xdeadbeef; + ret = ReadFile(server, read_buf, 1, &num_bytes, &overlapped); + ok(ret, "ReadFile failed\n"); + ok(num_bytes == 1, "bytes %u\n", num_bytes); + CloseHandle(client); CloseHandle(server); CloseHandle(event); @@ -1864,9 +1910,9 @@ START_TEST(pipe) { HMODULE hmod; - hmod = GetModuleHandle("advapi32.dll"); + hmod = GetModuleHandleA("advapi32.dll"); pDuplicateTokenEx = (void *) GetProcAddress(hmod, "DuplicateTokenEx"); - hmod = GetModuleHandle("kernel32.dll"); + hmod = GetModuleHandleA("kernel32.dll"); pQueueUserAPC = (void *) GetProcAddress(hmod, "QueueUserAPC"); if (test_DisconnectNamedPipe()) diff --git a/rostests/winetests/kernel32/process.c b/rostests/winetests/kernel32/process.c index 34396058360..aa6658da6c3 100755 --- a/rostests/winetests/kernel32/process.c +++ b/rostests/winetests/kernel32/process.c @@ -35,6 +35,9 @@ #include "wine/test.h" +/* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */ +#define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000) + #define expect_eq_d(expected, actual) \ do { \ int value = (actual); \ @@ -183,12 +186,12 @@ static WCHAR* decodeW(const char* str) * exename: executable without the path * function-pointers, which are not implemented in all windows versions */ -static int init(void) +static BOOL init(void) { char *p; myARGC = winetest_get_mainargs( &myARGV ); - if (!GetCurrentDirectoryA(sizeof(base), base)) return 0; + if (!GetCurrentDirectoryA(sizeof(base), base)) return FALSE; strcpy(selfname, myARGV[0]); /* Strip the path of selfname */ @@ -206,7 +209,7 @@ static int init(void) pQueryFullProcessImageNameA = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameA"); pQueryFullProcessImageNameW = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameW"); pK32GetProcessImageFileNameA = (void *) GetProcAddress(hkernel32, "K32GetProcessImageFileNameA"); - return 1; + return TRUE; } /****************************************************************** @@ -1522,7 +1525,7 @@ static void test_OpenProcess(void) } /* without PROCESS_VM_OPERATION */ - hproc = OpenProcess(PROCESS_ALL_ACCESS & ~PROCESS_VM_OPERATION, FALSE, GetCurrentProcessId()); + hproc = OpenProcess(PROCESS_ALL_ACCESS_NT4 & ~PROCESS_VM_OPERATION, FALSE, GetCurrentProcessId()); ok(hproc != NULL, "OpenProcess error %d\n", GetLastError()); SetLastError(0xdeadbeef); @@ -1665,7 +1668,7 @@ static void test_GetProcessImageFileNameA(void) length = sizeof(image); expect_eq_d(TRUE, pQueryFullProcessImageNameA(GetCurrentProcess(), PROCESS_NAME_NATIVE, image, &length)); expect_eq_d(length, lstrlenA(image)); - ok(lstrcmpi(process, image) == 0, "expected '%s' to be equal to '%s'\n", process, image); + ok(lstrcmpiA(process, image) == 0, "expected '%s' to be equal to '%s'\n", process, image); } } @@ -1691,7 +1694,7 @@ static void test_QueryFullProcessImageNameA(void) expect_eq_d(TRUE, pQueryFullProcessImageNameA(GetCurrentProcess(), 0, buf, &length)); expect_eq_d(length, lstrlenA(buf)); ok((buf[0] == '\\' && buf[1] == '\\') || - lstrcmpi(buf, module) == 0, "expected %s to match %s\n", buf, module); + lstrcmpiA(buf, module) == 0, "expected %s to match %s\n", buf, module); /* when the buffer is too small * - function fail with error ERROR_INSUFFICIENT_BUFFER @@ -1930,14 +1933,14 @@ static void test_TerminateProcess(void) { static char cmdline[] = "winver.exe"; PROCESS_INFORMATION pi; - STARTUPINFO si; + STARTUPINFOA si; DWORD ret; HANDLE dummy, thread; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); SetLastError(0xdeadbeef); - ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); + ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); ok(ret, "CreateProcess error %u\n", GetLastError()); SetLastError(0xdeadbeef); @@ -1990,9 +1993,9 @@ static void test_DuplicateHandle(void) ok(out != GetCurrentProcess(), "out = GetCurrentProcess()\n"); CloseHandle(out); - GetTempPath(MAX_PATH, path); - GetTempFileName(path, "wt", 0, file_name); - f = CreateFile(file_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + GetTempPathA(MAX_PATH, path); + GetTempFileNameA(path, "wt", 0, file_name); + f = CreateFileA(file_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); if (f == INVALID_HANDLE_VALUE) { ok(0, "could not create %s\n", file_name); @@ -2043,9 +2046,9 @@ static void test_DuplicateHandle(void) ok(r, "DuplicateHandle error %u\n", GetLastError()); ok(f == out, "f != out\n"); CloseHandle(out); - DeleteFile(file_name); + DeleteFileA(file_name); - f = CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); + f = CreateFileA("CONIN$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); if (!is_console(f)) { skip("DuplicateHandle on console handle\n"); @@ -2062,7 +2065,7 @@ static void test_DuplicateHandle(void) START_TEST(process) { - int b = init(); + BOOL b = init(); ok(b, "Basic init of CreateProcess test\n"); if (!b) return; diff --git a/rostests/winetests/kernel32/profile.c b/rostests/winetests/kernel32/profile.c index 211d0c6075d..2eb90a83ad8 100755 --- a/rostests/winetests/kernel32/profile.c +++ b/rostests/winetests/kernel32/profile.c @@ -92,12 +92,12 @@ static void test_profile_int(void) static void test_profile_string(void) { - static WCHAR emptyW[] = { 0 }; - static WCHAR keyW[] = { 'k','e','y',0 }; - static WCHAR sW[] = { 's',0 }; - static WCHAR TESTFILE2W[] = {'.','\\','t','e','s','t','w','i','n','e','2','.','i','n','i',0}; - static WCHAR valsectionW[] = {'v','a','l','_','e','_','s','e','c','t','i','o','n',0 }; - static WCHAR valnokeyW[] = {'v','a','l','_','n','o','_','k','e','y',0}; + static WCHAR emptyW[] = { 0 }; /* if "const", GetPrivateProfileStringW(emptyW, ...) crashes on win2k */ + static const WCHAR keyW[] = { 'k','e','y',0 }; + static const WCHAR sW[] = { 's',0 }; + static const WCHAR TESTFILE2W[] = {'.','\\','t','e','s','t','w','i','n','e','2','.','i','n','i',0}; + static const WCHAR valsectionW[] = {'v','a','l','_','e','_','s','e','c','t','i','o','n',0 }; + static const WCHAR valnokeyW[] = {'v','a','l','_','n','o','_','k','e','y',0}; HANDLE h; int ret; DWORD count; @@ -382,19 +382,19 @@ static void test_profile_existing(void) for (i=0; i < sizeof(pe)/sizeof(pe[0]); i++) { - h = CreateFile(testfile1, pe[i].dwDesiredAccess, pe[i].dwShareMode, NULL, + h = CreateFileA(testfile1, pe[i].dwDesiredAccess, pe[i].dwShareMode, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); ok(INVALID_HANDLE_VALUE != h, "%d: CreateFile failed\n",i); SetLastError(0xdeadbeef); - ret = WritePrivateProfileString(SECTION, KEY, "12345", testfile1); + ret = WritePrivateProfileStringA(SECTION, KEY, "12345", testfile1); if (!pe[i].write_error) { if (!ret) ok( broken(GetLastError() == pe[i].broken_error), "%d: WritePrivateProfileString failed with error %u\n", i, GetLastError() ); CloseHandle(h); - size = GetPrivateProfileString(SECTION, KEY, 0, buffer, MAX_PATH, testfile1); + size = GetPrivateProfileStringA(SECTION, KEY, 0, buffer, MAX_PATH, testfile1); if (ret) ok( size == 5, "%d: test failed, number of characters copied: %d instead of 5\n", i, size ); else @@ -408,21 +408,21 @@ static void test_profile_existing(void) ok( err == pe[i].write_error, "%d: WritePrivateProfileString failed with error %u/%u\n", i, err, pe[i].write_error ); CloseHandle(h); - size = GetPrivateProfileString(SECTION, KEY, 0, buffer, MAX_PATH, testfile1); + size = GetPrivateProfileStringA(SECTION, KEY, 0, buffer, MAX_PATH, testfile1); ok( !size, "%d: test failed, number of characters copied: %d instead of 0\n", i, size ); } - ok( DeleteFile(testfile1), "delete failed\n" ); + ok( DeleteFileA(testfile1), "delete failed\n" ); } - h = CreateFile(testfile2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + h = CreateFileA(testfile2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); sprintf( buffer, "[%s]\r\n%s=123\r\n", SECTION, KEY ); ok( WriteFile( h, buffer, strlen(buffer), &size, NULL ), "failed to write\n" ); CloseHandle( h ); for (i=0; i < sizeof(pe)/sizeof(pe[0]); i++) { - h = CreateFile(testfile2, pe[i].dwDesiredAccess, pe[i].dwShareMode, NULL, + h = CreateFileA(testfile2, pe[i].dwDesiredAccess, pe[i].dwShareMode, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ok(INVALID_HANDLE_VALUE != h, "%d: CreateFile failed\n",i); SetLastError(0xdeadbeef); @@ -436,24 +436,24 @@ static void test_profile_existing(void) ok( !ret, "%d: GetPrivateProfileString succeeded\n", i ); CloseHandle(h); } - ok( DeleteFile(testfile2), "delete failed\n" ); + ok( DeleteFileA(testfile2), "delete failed\n" ); } static void test_profile_delete_on_close(void) { - static CHAR testfile[] = ".\\testwine5.ini"; HANDLE h; DWORD size, res; + static const CHAR testfile[] = ".\\testwine5.ini"; static const char contents[] = "[" SECTION "]\n" KEY "=123\n"; - h = CreateFile(testfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, + h = CreateFileA(testfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); res = WriteFile( h, contents, sizeof contents - 1, &size, NULL ); ok( res, "Cannot write test file: %x\n", GetLastError() ); ok( size == sizeof contents - 1, "Test file: partial write\n"); SetLastError(0xdeadbeef); - res = GetPrivateProfileInt(SECTION, KEY, 0, testfile); + res = GetPrivateProfileIntA(SECTION, KEY, 0, testfile); ok( res == 123 || broken(res == 0 && GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x, WinME */ "Got %d instead of 123\n", res); @@ -464,20 +464,20 @@ static void test_profile_delete_on_close(void) static void test_profile_refresh(void) { - static CHAR testfile[] = ".\\winetest4.ini"; + static const CHAR testfile[] = ".\\winetest4.ini"; HANDLE h; DWORD size, res; static const char contents1[] = "[" SECTION "]\n" KEY "=123\n"; static const char contents2[] = "[" SECTION "]\n" KEY "=124\n"; - h = CreateFile(testfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, + h = CreateFileA(testfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); res = WriteFile( h, contents1, sizeof contents1 - 1, &size, NULL ); ok( res, "Cannot write test file: %x\n", GetLastError() ); ok( size == sizeof contents1 - 1, "Test file: partial write\n"); SetLastError(0xdeadbeef); - res = GetPrivateProfileInt(SECTION, KEY, 0, testfile); + res = GetPrivateProfileIntA(SECTION, KEY, 0, testfile); ok( res == 123 || broken(res == 0 && GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x, WinME */ "Got %d instead of 123\n", res); @@ -486,14 +486,14 @@ static void test_profile_refresh(void) /* Test proper invalidation of wine's profile file cache */ - h = CreateFile(testfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, + h = CreateFileA(testfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); res = WriteFile( h, contents2, sizeof contents2 - 1, &size, NULL ); ok( res, "Cannot write test file: %x\n", GetLastError() ); ok( size == sizeof contents2 - 1, "Test file: partial write\n"); SetLastError(0xdeadbeef); - res = GetPrivateProfileInt(SECTION, KEY, 0, testfile); + res = GetPrivateProfileIntA(SECTION, KEY, 0, testfile); ok( res == 124 || broken(res == 0 && GetLastError() == 0xdeadbeef), /* Win9x, WinME */ "Got %d instead of 124\n", res); @@ -503,7 +503,7 @@ static void test_profile_refresh(void) /* Cache must be invalidated if file no longer exists and default must be returned */ SetLastError(0xdeadbeef); - res = GetPrivateProfileInt(SECTION, KEY, 421, testfile); + res = GetPrivateProfileIntA(SECTION, KEY, 421, testfile); ok( res == 421 || broken(res == 0 && GetLastError() == 0xdeadbeef), /* Win9x, WinME */ "Got %d instead of 421\n", res); @@ -1019,18 +1019,22 @@ static void test_WritePrivateProfileString(void) broken(GetLastError() == ERROR_PATH_NOT_FOUND), /* Win9x and WinME */ "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); - /* The resulting file will be X:\\%WINDIR%\\win1.tmp */ + /* Relative paths are relative to X:\\%WINDIR% */ GetWindowsDirectoryA(temp, MAX_PATH); GetTempFileNameA(temp, "win", 1, path); - DeleteFileA(path); + if (GetFileAttributesA(path) == INVALID_FILE_ATTRIBUTES) + skip("Not allowed to create a file in the Windows directory\n"); + else + { + DeleteFileA(path); - /* relative path in lpFileName */ - data = "[App]\r\n" - "key=string\r\n"; - ret = WritePrivateProfileStringA("App", "key", "string", "win1.tmp"); - ok(ret == TRUE, "Expected TRUE, got %d\n", ret); - ok(check_file_data(path, data), "File doesn't match\n"); - DeleteFileA(path); + data = "[App]\r\n" + "key=string\r\n"; + ret = WritePrivateProfileStringA("App", "key", "string", "win1.tmp"); + ok(ret == TRUE, "Expected TRUE, got %d, le=%u\n", ret, GetLastError()); + ok(check_file_data(path, data), "File doesn't match\n"); + DeleteFileA(path); + } GetTempPathA(MAX_PATH, temp); GetTempFileNameA(temp, "wine", 0, path); diff --git a/rostests/winetests/kernel32/resource.c b/rostests/winetests/kernel32/resource.c index a85e6d2daa1..f94fed644ad 100644 --- a/rostests/winetests/kernel32/resource.c +++ b/rostests/winetests/kernel32/resource.c @@ -255,7 +255,7 @@ static int build_exe( const sec_build* sec_descr ) file_size = phys_end_of_section; } - file = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); ok (file != INVALID_HANDLE_VALUE, "failed to create file\n"); /* write out the header */ @@ -279,7 +279,7 @@ static void update_missing_exe( void ) HANDLE res; SetLastError(0xdeadbeef); - res = BeginUpdateResource( filename, TRUE ); + res = BeginUpdateResourceA( filename, TRUE ); GLE = GetLastError(); ok( res == NULL, "BeginUpdateResource should fail\n"); } @@ -289,29 +289,29 @@ static void update_empty_exe( void ) HANDLE file, res, test; BOOL r; - file = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); ok (file != INVALID_HANDLE_VALUE, "failed to create file\n"); CloseHandle( file ); - res = BeginUpdateResource( filename, TRUE ); + res = BeginUpdateResourceA( filename, TRUE ); if ( res != NULL || GetLastError() != ERROR_FILE_INVALID ) { ok( res != NULL, "BeginUpdateResource failed\n"); /* check if it's possible to open the file now */ - test = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); + test = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); ok (test != INVALID_HANDLE_VALUE, "failed to create file\n"); CloseHandle( test ); - r = EndUpdateResource( res, FALSE ); + r = EndUpdateResourceA( res, FALSE ); ok( r == FALSE, "EndUpdateResource failed\n"); } else skip( "Can't update resource in empty file\n" ); - res = BeginUpdateResource( filename, FALSE ); + res = BeginUpdateResourceA( filename, FALSE ); ok( res == NULL, "BeginUpdateResource failed\n"); } @@ -320,10 +320,10 @@ static void update_resources_none( void ) HMODULE res; BOOL r; - res = BeginUpdateResource( filename, FALSE ); + res = BeginUpdateResourceA( filename, FALSE ); ok( res != NULL, "BeginUpdateResource failed\n"); - r = EndUpdateResource( res, FALSE ); + r = EndUpdateResourceA( res, FALSE ); ok( r, "EndUpdateResource failed\n"); } @@ -332,10 +332,10 @@ static void update_resources_delete( void ) HMODULE res; BOOL r; - res = BeginUpdateResource( filename, TRUE ); + res = BeginUpdateResourceA( filename, TRUE ); ok( res != NULL, "BeginUpdateResource failed\n"); - r = EndUpdateResource( res, FALSE ); + r = EndUpdateResourceA( res, FALSE ); ok( r, "EndUpdateResource failed\n"); } @@ -345,27 +345,27 @@ static void update_resources_version( void ) BOOL r; char foo[] = "red and white"; - res = BeginUpdateResource( filename, TRUE ); + res = BeginUpdateResourceA( filename, TRUE ); ok( res != NULL, "BeginUpdateResource failed\n"); if (0) /* this causes subsequent tests to fail on Vista */ { - r = UpdateResource( res, - MAKEINTRESOURCE(0x1230), - MAKEINTRESOURCE(0x4567), + r = UpdateResourceA( res, + MAKEINTRESOURCEA(0x1230), + MAKEINTRESOURCEA(0x4567), 0xabcd, NULL, 0 ); ok( r == FALSE, "UpdateResource failed\n"); } - r = UpdateResource( res, - MAKEINTRESOURCE(0x1230), - MAKEINTRESOURCE(0x4567), + r = UpdateResourceA( res, + MAKEINTRESOURCEA(0x1230), + MAKEINTRESOURCEA(0x4567), 0xabcd, foo, sizeof foo ); ok( r == TRUE, "UpdateResource failed: %d\n", GetLastError()); - r = EndUpdateResource( res, FALSE ); + r = EndUpdateResourceA( res, FALSE ); ok( r, "EndUpdateResource failed: %d\n", GetLastError()); } @@ -375,17 +375,17 @@ static void update_resources_bigdata( void ) BOOL r; char foo[2*page_size] = "foobar"; - res = BeginUpdateResource( filename, TRUE ); + res = BeginUpdateResourceA( filename, TRUE ); ok( res != NULL, "BeginUpdateResource succeeded\n"); - r = UpdateResource( res, - MAKEINTRESOURCE(0x3012), - MAKEINTRESOURCE(0x5647), + r = UpdateResourceA( res, + MAKEINTRESOURCEA(0x3012), + MAKEINTRESOURCEA(0x5647), 0xcdba, foo, sizeof foo ); ok( r == TRUE, "UpdateResource failed: %d\n", GetLastError()); - r = EndUpdateResource( res, FALSE ); + r = EndUpdateResourceA( res, FALSE ); ok( r, "EndUpdateResource failed\n"); } @@ -399,13 +399,13 @@ static void check_exe( const sec_verify *verify ) HANDLE file, mapping; DWORD length, sec_count = 0; - file = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); + file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); ok (file != INVALID_HANDLE_VALUE, "failed to create file (%d)\n", GetLastError()); length = GetFileSize( file, NULL ); ok( length >= verify->length, "file size wrong\n"); - mapping = CreateFileMapping( file, NULL, PAGE_READONLY, 0, 0, NULL ); + mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 0, NULL ); ok (mapping != NULL, "failed to create file\n"); dos = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length ); @@ -458,33 +458,33 @@ static void test_find_resource(void) { HRSRC rsrc; - rsrc = FindResourceW( GetModuleHandle(0), (LPCWSTR)MAKEINTRESOURCE(1), (LPCWSTR)RT_MENU ); + rsrc = FindResourceW( GetModuleHandleW(NULL), MAKEINTRESOURCEW(1), (LPCWSTR)RT_MENU ); ok( rsrc != 0, "resource not found\n" ); - rsrc = FindResourceExW( GetModuleHandle(0), (LPCWSTR)RT_MENU, (LPCWSTR)MAKEINTRESOURCE(1), + rsrc = FindResourceExW( GetModuleHandleW(NULL), (LPCWSTR)RT_MENU, MAKEINTRESOURCEW(1), MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL )); ok( rsrc != 0, "resource not found\n" ); - rsrc = FindResourceExW( GetModuleHandle(0), (LPCWSTR)RT_MENU, (LPCWSTR)MAKEINTRESOURCE(1), + rsrc = FindResourceExW( GetModuleHandleW(NULL), (LPCWSTR)RT_MENU, MAKEINTRESOURCEW(1), MAKELANGID( LANG_GERMAN, SUBLANG_DEFAULT )); ok( rsrc != 0, "resource not found\n" ); SetLastError( 0xdeadbeef ); - rsrc = FindResourceW( GetModuleHandle(0), (LPCWSTR)MAKEINTRESOURCE(1), (LPCWSTR)RT_DIALOG ); + rsrc = FindResourceW( GetModuleHandleW(NULL), MAKEINTRESOURCEW(1), (LPCWSTR)RT_DIALOG ); ok( !rsrc, "resource found\n" ); ok( GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND, "wrong error %u\n", GetLastError() ); SetLastError( 0xdeadbeef ); - rsrc = FindResourceW( GetModuleHandle(0), (LPCWSTR)MAKEINTRESOURCE(2), (LPCWSTR)RT_MENU ); + rsrc = FindResourceW( GetModuleHandleW(NULL), MAKEINTRESOURCEW(2), (LPCWSTR)RT_MENU ); ok( !rsrc, "resource found\n" ); ok( GetLastError() == ERROR_RESOURCE_NAME_NOT_FOUND, "wrong error %u\n", GetLastError() ); SetLastError( 0xdeadbeef ); - rsrc = FindResourceExW( GetModuleHandle(0), (LPCWSTR)RT_MENU, (LPCWSTR)MAKEINTRESOURCE(1), + rsrc = FindResourceExW( GetModuleHandleW(NULL), (LPCWSTR)RT_MENU, MAKEINTRESOURCEW(1), MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ) ); ok( !rsrc, "resource found\n" ); ok( GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND, "wrong error %u\n", GetLastError() ); SetLastError( 0xdeadbeef ); - rsrc = FindResourceExW( GetModuleHandle(0), (LPCWSTR)RT_MENU, (LPCWSTR)MAKEINTRESOURCE(1), + rsrc = FindResourceExW( GetModuleHandleW(NULL), (LPCWSTR)RT_MENU, MAKEINTRESOURCEW(1), MAKELANGID( LANG_FRENCH, SUBLANG_DEFAULT ) ); ok( !rsrc, "resource found\n" ); ok( GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND, "wrong error %u\n", GetLastError() ); @@ -494,7 +494,7 @@ START_TEST(resource) { DWORD i; - DeleteFile( filename ); + DeleteFileA( filename ); update_missing_exe(); if (GLE == ERROR_CALL_NOT_IMPLEMENTED) @@ -517,7 +517,7 @@ START_TEST(resource) check_exe( &sec->chk_version ); update_resources_bigdata(); check_exe( &sec->chk_bigdata ); - DeleteFile( filename ); + DeleteFileA( filename ); } test_find_resource(); } diff --git a/rostests/winetests/kernel32/sync.c b/rostests/winetests/kernel32/sync.c index 7b9612bb96f..674e2ec3141 100755 --- a/rostests/winetests/kernel32/sync.c +++ b/rostests/winetests/kernel32/sync.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define _WIN32_WINNT 0x600 +//#define _WIN32_WINNT 0x500 #include #include #include @@ -44,9 +44,18 @@ static BOOL (WINAPI *pInitOnceComplete)(PINIT_ONCE,DWORD,LPVOID); static VOID (WINAPI *pInitializeConditionVariable)(PCONDITION_VARIABLE); static BOOL (WINAPI *pSleepConditionVariableCS)(PCONDITION_VARIABLE,PCRITICAL_SECTION,DWORD); +static BOOL (WINAPI *pSleepConditionVariableSRW)(PCONDITION_VARIABLE,PSRWLOCK,DWORD,ULONG); static VOID (WINAPI *pWakeAllConditionVariable)(PCONDITION_VARIABLE); static VOID (WINAPI *pWakeConditionVariable)(PCONDITION_VARIABLE); +static VOID (WINAPI *pInitializeSRWLock)(PSRWLOCK); +static VOID (WINAPI *pAcquireSRWLockExclusive)(PSRWLOCK); +static VOID (WINAPI *pAcquireSRWLockShared)(PSRWLOCK); +static VOID (WINAPI *pReleaseSRWLockExclusive)(PSRWLOCK); +static VOID (WINAPI *pReleaseSRWLockShared)(PSRWLOCK); +static BOOLEAN (WINAPI *pTryAcquireSRWLockExclusive)(PSRWLOCK); +static BOOLEAN (WINAPI *pTryAcquireSRWLockShared)(PSRWLOCK); + static void test_signalandwait(void) { DWORD (WINAPI *pSignalObjectAndWait)(HANDLE, HANDLE, DWORD, BOOL); @@ -54,7 +63,7 @@ static void test_signalandwait(void) DWORD r; HANDLE event[2], semaphore[2], file; - kernel32 = GetModuleHandle("kernel32"); + kernel32 = GetModuleHandleA("kernel32.dll"); pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait"); if (!pSignalObjectAndWait) @@ -69,8 +78,8 @@ static void test_signalandwait(void) } ok( r == WAIT_FAILED, "should fail\n"); - event[0] = CreateEvent(NULL, 0, 0, NULL); - event[1] = CreateEvent(NULL, 1, 1, NULL); + event[0] = CreateEventW(NULL, 0, 0, NULL); + event[1] = CreateEventW(NULL, 1, 1, NULL); ok( event[0] && event[1], "failed to create event flags\n"); @@ -105,8 +114,8 @@ static void test_signalandwait(void) CloseHandle(event[1]); /* semaphores */ - semaphore[0] = CreateSemaphore( NULL, 0, 1, NULL ); - semaphore[1] = CreateSemaphore( NULL, 1, 1, NULL ); + semaphore[0] = CreateSemaphoreW( NULL, 0, 1, NULL ); + semaphore[1] = CreateSemaphoreW( NULL, 1, 1, NULL ); ok( semaphore[0] && semaphore[1], "failed to create semaphore\n"); r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE); @@ -125,7 +134,7 @@ static void test_signalandwait(void) CloseHandle(semaphore[1]); /* try a registry key */ - file = CreateFile("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + file = CreateFileA("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); r = pSignalObjectAndWait(file, file, 0, FALSE); ok( r == WAIT_FAILED, "should fail\n"); @@ -143,23 +152,23 @@ static void test_mutex(void) DWORD failed = 0; SetLastError(0xdeadbeef); - hOpened = OpenMutex(0, FALSE, "WineTestMutex"); + hOpened = OpenMutexA(0, FALSE, "WineTestMutex"); ok(hOpened == NULL, "OpenMutex succeeded\n"); ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); SetLastError(0xdeadbeef); - hCreated = CreateMutex(NULL, FALSE, "WineTestMutex"); + hCreated = CreateMutexA(NULL, FALSE, "WineTestMutex"); ok(hCreated != NULL, "CreateMutex failed with error %d\n", GetLastError()); SetLastError(0xdeadbeef); - hOpened = OpenMutex(0, FALSE, "WineTestMutex"); + hOpened = OpenMutexA(0, FALSE, "WineTestMutex"); todo_wine ok(hOpened == NULL, "OpenMutex succeeded\n"); todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError()); SetLastError(0xdeadbeef); - hOpened = OpenMutex(GENERIC_EXECUTE, FALSE, "WineTestMutex"); + hOpened = OpenMutexA(GENERIC_EXECUTE, FALSE, "WineTestMutex"); ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError()); wait_ret = WaitForSingleObject(hOpened, INFINITE); ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error %d\n", GetLastError()); @@ -172,7 +181,7 @@ todo_wine } SetLastError(0xdeadbeef); - hOpened = OpenMutex(GENERIC_READ | GENERIC_WRITE, FALSE, "WineTestMutex"); + hOpened = OpenMutexA(GENERIC_READ | GENERIC_WRITE, FALSE, "WineTestMutex"); ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError()); wait_ret = WaitForSingleObject(hOpened, INFINITE); ok(wait_ret == WAIT_FAILED, "WaitForSingleObject succeeded\n"); @@ -181,7 +190,7 @@ todo_wine for (i = 0; i < 32; i++) { SetLastError(0xdeadbeef); - hOpened = OpenMutex(0x1 << i, FALSE, "WineTestMutex"); + hOpened = OpenMutexA(0x1 << i, FALSE, "WineTestMutex"); if(hOpened != NULL) { SetLastError(0xdeadbeef); @@ -211,23 +220,23 @@ todo_wine /* test case sensitivity */ SetLastError(0xdeadbeef); - hOpened = OpenMutex(READ_CONTROL, FALSE, "WINETESTMUTEX"); + hOpened = OpenMutexA(READ_CONTROL, FALSE, "WINETESTMUTEX"); ok(!hOpened, "OpenMutex succeeded\n"); ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); SetLastError(0xdeadbeef); - hOpened = OpenMutex(READ_CONTROL, FALSE, "winetestmutex"); + hOpened = OpenMutexA(READ_CONTROL, FALSE, "winetestmutex"); ok(!hOpened, "OpenMutex succeeded\n"); ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); SetLastError(0xdeadbeef); - hOpened = CreateMutex(NULL, FALSE, "WineTestMutex"); + hOpened = CreateMutexA(NULL, FALSE, "WineTestMutex"); ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError()); ok(GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError()); CloseHandle(hOpened); SetLastError(0xdeadbeef); - hOpened = CreateMutex(NULL, FALSE, "WINETESTMUTEX"); + hOpened = CreateMutexA(NULL, FALSE, "WINETESTMUTEX"); ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError()); ok(GetLastError() == 0, "wrong error %u\n", GetLastError()); CloseHandle(hOpened); @@ -244,8 +253,9 @@ static void test_slist(void) } item1, item2, item3, *pitem; SLIST_HEADER slist_header; - PSLIST_ENTRY entry; + PSLIST_ENTRY entry, next; USHORT size; + int i; VOID (WINAPI *pInitializeSListHead)(PSLIST_HEADER); USHORT (WINAPI *pQueryDepthSList)(PSLIST_HEADER); @@ -254,7 +264,7 @@ static void test_slist(void) PSLIST_ENTRY (WINAPI *pInterlockedPushEntrySList)(PSLIST_HEADER,PSLIST_ENTRY); HMODULE kernel32; - kernel32 = GetModuleHandle("KERNEL32.DLL"); + kernel32 = GetModuleHandleA("KERNEL32.DLL"); pInitializeSListHead = (void*) GetProcAddress(kernel32, "InitializeSListHead"); pQueryDepthSList = (void*) GetProcAddress(kernel32, "QueryDepthSList"); pInterlockedFlushSList = (void*) GetProcAddress(kernel32, "InterlockedFlushSList"); @@ -323,6 +333,21 @@ static void test_slist(void) } ok(((struct item*)entry)->value == 2, "item 2 not in front of list\n"); ok(((struct item*)entry->Next)->value == 1, "item 1 not at the back of list\n"); + + for (i = 0; i < 65536; i++) + { + entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)); + pInterlockedPushEntrySList(&slist_header, entry); + } + + entry = pInterlockedFlushSList(&slist_header); + ok(entry != NULL, "not flushed\n"); + while (entry) + { + next = entry->Next; + HeapFree(GetProcessHeap(), 0, entry); + entry = next; + } } static void test_event(void) @@ -536,7 +561,7 @@ static void test_iocp_callback(void) return; } - sem = CreateSemaphore(NULL, 0, 1, NULL); + sem = CreateSemaphoreW(NULL, 0, 1, NULL); ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n"); ret = GetTempPathA(MAX_PATH, temp_path); @@ -813,9 +838,9 @@ static void test_timer_queue(void) ok(n5 == 1, "Timer callback 5 expected 1 got %d\n", n5); /* Test synchronous deletion of the timer/queue with event trigger. */ - e = CreateEvent(NULL, TRUE, FALSE, NULL); - et1 = CreateEvent(NULL, TRUE, FALSE, NULL); - et2 = CreateEvent(NULL, TRUE, FALSE, NULL); + e = CreateEventW(NULL, TRUE, FALSE, NULL); + et1 = CreateEventW(NULL, TRUE, FALSE, NULL); + et2 = CreateEventW(NULL, TRUE, FALSE, NULL); if (!e || !et1 || !et2) { skip("Failed to create timer queue descruction event\n"); @@ -1123,7 +1148,7 @@ static void test_WaitForMultipleObjects(void) * we can wait on that many */ for (i=0; i #include #include -#include "wine/test.h" +#include + #include #include #include #include +#include + +/* THREAD_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */ +#define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff) /* Specify the number of simultaneous threads to test */ #define NUM_THREADS 4 @@ -54,6 +59,14 @@ # endif #endif +#ifdef __i386__ +#define ARCH "x86" +#elif defined __x86_64__ +#define ARCH "amd64" +#else +#define ARCH "none" +#endif + static BOOL (WINAPI *pGetThreadPriorityBoost)(HANDLE,PBOOL); static HANDLE (WINAPI *pOpenThread)(DWORD,BOOL,DWORD); static BOOL (WINAPI *pQueueUserWorkItem)(LPTHREAD_START_ROUTINE,PVOID,ULONG); @@ -65,6 +78,16 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL); static BOOL (WINAPI *pSetThreadErrorMode)(DWORD,PDWORD); static DWORD (WINAPI *pGetThreadErrorMode)(void); static DWORD (WINAPI *pRtlGetThreadErrorMode)(void); +static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*); +static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW); +static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR); +static BOOL (WINAPI *pGetCurrentActCtx)(HANDLE *); +static void (WINAPI *pReleaseActCtx)(HANDLE); +static PTP_POOL (WINAPI *pCreateThreadpool)(PVOID); +static PTP_WORK (WINAPI *pCreateThreadpoolWork)(PTP_WORK_CALLBACK,PVOID,PTP_CALLBACK_ENVIRON); +static void (WINAPI *pSubmitThreadpoolWork)(PTP_WORK); +static void (WINAPI *pWaitForThreadpoolWorkCallbacks)(PTP_WORK,BOOL); +static void (WINAPI *pCloseThreadpoolWork)(PTP_WORK); static HANDLE create_target_process(const char *arg) { @@ -72,12 +95,12 @@ static HANDLE create_target_process(const char *arg) char cmdline[MAX_PATH]; PROCESS_INFORMATION pi; BOOL ret; - STARTUPINFO si = { 0 }; + STARTUPINFOA si = { 0 }; si.cb = sizeof(si); winetest_get_mainargs( &argv ); sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg); - ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "error: %u\n", GetLastError()); ret = CloseHandle(pi.hThread); ok(ret, "error %u\n", GetLastError()); @@ -102,9 +125,9 @@ static LONG num_synced; static void init_thread_sync_helpers(void) { - start_event = CreateEvent(NULL, TRUE, FALSE, NULL); + start_event = CreateEventW(NULL, TRUE, FALSE, NULL); ok(start_event != NULL, "CreateEvent failed\n"); - stop_event = CreateEvent(NULL, TRUE, FALSE, NULL); + stop_event = CreateEventW(NULL, TRUE, FALSE, NULL); ok(stop_event != NULL, "CreateEvent failed\n"); num_synced = -1; } @@ -258,15 +281,36 @@ static DWORD WINAPI threadFunc_CloseHandle(LPVOID p) return 0; } +struct thread_actctx_param +{ + HANDLE thread_context; + HANDLE handle; +}; + +static DWORD WINAPI thread_actctx_func(void *p) +{ + struct thread_actctx_param *param = (struct thread_actctx_param*)p; + HANDLE cur; + BOOL ret; + + cur = (void*)0xdeadbeef; + ret = pGetCurrentActCtx(&cur); + ok(ret, "thread GetCurrentActCtx failed, %u\n", GetLastError()); + ok(cur == param->handle, "got %p, expected %p\n", cur, param->handle); + param->thread_context = cur; + + return 0; +} + static void create_function_addr_events(HANDLE events[2]) { char buffer[256]; sprintf(buffer, "threadFunc_SetEvent %p", threadFunc_SetEvent); - events[0] = CreateEvent(NULL, FALSE, FALSE, buffer); + events[0] = CreateEventA(NULL, FALSE, FALSE, buffer); sprintf(buffer, "threadFunc_CloseHandle %p", threadFunc_CloseHandle); - events[1] = CreateEvent(NULL, FALSE, FALSE, buffer); + events[1] = CreateEventA(NULL, FALSE, FALSE, buffer); } /* check CreateRemoteThread */ @@ -290,7 +334,7 @@ static VOID test_CreateRemoteThread(void) } ok(ret == WAIT_OBJECT_0 || broken(ret == WAIT_OBJECT_0+1 /* nt4,w2k */), "WaitForAllObjects 2 events %d\n", ret); - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); ok(hEvent != NULL, "Can't create event, err=%u\n", GetLastError()); ret = DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hRemoteEvent, 0, FALSE, DUPLICATE_SAME_ACCESS); @@ -522,7 +566,7 @@ static VOID test_SuspendThread(void) ok(error==1,"SuspendThread did not work\n"); /* check that access restrictions are obeyed */ if (pOpenThread) { - access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_SUSPEND_RESUME), + access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 & (~THREAD_SUSPEND_RESUME), 0,threadId); ok(access_thread!=NULL,"OpenThread returned an invalid handle\n"); if (access_thread!=NULL) { @@ -567,7 +611,7 @@ static VOID test_TerminateThread(void) "TerminateThread didn't work\n"); /* check that access restrictions are obeyed */ if (pOpenThread) { - access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_TERMINATE), + access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 & (~THREAD_TERMINATE), 0,threadId); ok(access_thread!=NULL,"OpenThread returned an invalid handle\n"); if (access_thread!=NULL) { @@ -636,7 +680,7 @@ static VOID test_thread_priority(void) if (pOpenThread) { /* check that access control is obeyed */ - access_thread=pOpenThread(THREAD_ALL_ACCESS & + access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 & (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION), 0,curthreadId); ok(access_thread!=NULL,"OpenThread returned an invalid handle\n"); @@ -708,7 +752,7 @@ static VOID test_thread_priority(void) if (pOpenThread) { /* check that access control is obeyed */ - access_thread=pOpenThread(THREAD_ALL_ACCESS & + access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 & (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION), 0,curthreadId); ok(access_thread!=NULL,"OpenThread returned an invalid handle\n"); @@ -748,7 +792,7 @@ static VOID test_GetThreadTimes(void) ok(thread!=NULL,"Create Thread failed\n"); /* check that access control is obeyed */ if (pOpenThread) { - access_thread=pOpenThread(THREAD_ALL_ACCESS & + access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 & (~THREAD_QUERY_INFORMATION), 0,threadId); ok(access_thread!=NULL, "OpenThread returned an invalid handle\n"); @@ -918,7 +962,7 @@ static void test_SetThreadContext(void) BOOL ret; SetLastError(0xdeadbeef); - event = CreateEvent( NULL, TRUE, FALSE, NULL ); + event = CreateEventW( NULL, TRUE, FALSE, NULL ); thread = CreateThread( NULL, 0, threadFunc6, (void *)2, 0, &threadid ); ok( thread != NULL, "CreateThread failed : (%d)\n", GetLastError() ); if (!thread) @@ -999,7 +1043,7 @@ static void test_QueueUserWorkItem(void) /* QueueUserWorkItem not present on win9x */ if (!pQueueUserWorkItem) return; - finish_event = CreateEvent(NULL, TRUE, FALSE, NULL); + finish_event = CreateEventW(NULL, TRUE, FALSE, NULL); before = GetTickCount(); @@ -1047,8 +1091,8 @@ static void test_RegisterWaitForSingleObject(void) /* test signaled case */ - handle = CreateEvent(NULL, TRUE, TRUE, NULL); - complete_event = CreateEvent(NULL, FALSE, FALSE, NULL); + handle = CreateEventW(NULL, TRUE, TRUE, NULL); + complete_event = CreateEventW(NULL, FALSE, FALSE, NULL); ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE); ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError()); @@ -1391,7 +1435,7 @@ static WORD get_thread_fpu_cw(void) DWORD tid, res; HANDLE thread; - ctx.finished = CreateEvent(NULL, FALSE, FALSE, NULL); + ctx.finished = CreateEventW(NULL, FALSE, FALSE, NULL); ok(!!ctx.finished, "Failed to create event, last error %#x.\n", GetLastError()); thread = CreateThread(NULL, 0, fpu_thread, &ctx, 0, &tid); @@ -1432,28 +1476,243 @@ static void test_thread_fpu_cw(void) } #endif +static const char manifest_dep[] = +"" +"" +" " +""; + +static const char manifest_main[] = +"" +"" +"" +" " +" " +" " +"" +""; + +static void create_manifest_file(const char *filename, const char *manifest) +{ + WCHAR path[MAX_PATH]; + HANDLE file; + DWORD size; + + MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH ); + file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError()); + WriteFile(file, manifest, strlen(manifest), &size, NULL); + CloseHandle(file); +} + +static HANDLE test_create(const char *file) +{ + WCHAR path[MAX_PATH]; + ACTCTXW actctx; + HANDLE handle; + + MultiByteToWideChar(CP_ACP, 0, file, -1, path, MAX_PATH); + memset(&actctx, 0, sizeof(ACTCTXW)); + actctx.cbSize = sizeof(ACTCTXW); + actctx.lpSource = path; + + handle = pCreateActCtxW(&actctx); + ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError()); + + ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize); + ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags); + ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource); + ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture); + ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId); + ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory); + ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName); + ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName); + ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule); + + return handle; +} + +static void test_thread_actctx(void) +{ + struct thread_actctx_param param; + HANDLE thread, handle, context; + ULONG_PTR cookie; + DWORD tid, ret; + BOOL b; + + if (!pActivateActCtx) + { + win_skip("skipping activation context tests\n"); + return; + } + + create_manifest_file("testdep1.manifest", manifest_dep); + create_manifest_file("main.manifest", manifest_main); + + context = test_create("main.manifest"); + DeleteFileA("testdep1.manifest"); + DeleteFileA("main.manifest"); + + handle = (void*)0xdeadbeef; + b = pGetCurrentActCtx(&handle); + ok(b, "GetCurentActCtx failed: %u\n", GetLastError()); + ok(handle == 0, "active context %p\n", handle); + + /* without active context */ + param.thread_context = (void*)0xdeadbeef; + param.handle = NULL; + thread = CreateThread(NULL, 0, thread_actctx_func, ¶m, 0, &tid); + ok(thread != NULL, "failed, got %u\n", GetLastError()); + + ret = WaitForSingleObject(thread, 1000); + ok(ret == WAIT_OBJECT_0, "wait timeout\n"); + ok(param.thread_context == NULL, "got wrong thread context %p\n", param.thread_context); + CloseHandle(thread); + + b = pActivateActCtx(context, &cookie); + ok(b, "activation failed: %u\n", GetLastError()); + + handle = 0; + b = pGetCurrentActCtx(&handle); + ok(b, "GetCurentActCtx failed: %u\n", GetLastError()); + ok(handle != 0, "no active context\n"); + + param.handle = NULL; + b = pGetCurrentActCtx(¶m.handle); + ok(b && param.handle != NULL, "failed to get context, %u\n", GetLastError()); + + param.thread_context = (void*)0xdeadbeef; + thread = CreateThread(NULL, 0, thread_actctx_func, ¶m, 0, &tid); + ok(thread != NULL, "failed, got %u\n", GetLastError()); + + ret = WaitForSingleObject(thread, 1000); + ok(ret == WAIT_OBJECT_0, "wait timeout\n"); + ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context); + CloseHandle(thread); + + /* similar test for CreateRemoteThread() */ + param.thread_context = (void*)0xdeadbeef; + thread = CreateRemoteThread(GetCurrentProcess(), NULL, 0, thread_actctx_func, ¶m, 0, &tid); + ok(thread != NULL, "failed, got %u\n", GetLastError()); + + ret = WaitForSingleObject(thread, 1000); + ok(ret == WAIT_OBJECT_0, "wait timeout\n"); + ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context); + CloseHandle(thread); + + b = pDeactivateActCtx(0, cookie); + ok(b, "DeactivateActCtx failed: %u\n", GetLastError()); + pReleaseActCtx(context); +} + + +static void WINAPI threadpool_workcallback(PTP_CALLBACK_INSTANCE instance, void *context, PTP_WORK work) { + int *foo = (int*)context; + + (*foo)++; +} + + +static void test_threadpool(void) +{ + PTP_POOL pool; + PTP_WORK work; + int workcalled = 0; + + if (!pCreateThreadpool) { + todo_wine win_skip("thread pool apis not supported.\n"); + return; + } + + work = pCreateThreadpoolWork(threadpool_workcallback, &workcalled, NULL); + ok (work != NULL, "Error %d in CreateThreadpoolWork\n", GetLastError()); + pSubmitThreadpoolWork(work); + pWaitForThreadpoolWorkCallbacks(work, FALSE); + pCloseThreadpoolWork(work); + + ok (workcalled == 1, "expected work to be called once, got %d\n", workcalled); + + pool = pCreateThreadpool(NULL); + todo_wine ok (pool != NULL, "CreateThreadpool failed\n"); +} + +static void test_reserved_tls(void) +{ + void *val; + DWORD tls; + BOOL ret; + + /* This seems to be a WinXP SP2+ feature. */ + if(!pIsWow64Process) { + win_skip("Skipping reserved TLS slot on too old Windows.\n"); + return; + } + + val = TlsGetValue(0); + ok(!val, "TlsGetValue(0) = %p\n", val); + + /* Also make sure that there is a TLS allocated. */ + tls = TlsAlloc(); + ok(tls && tls != TLS_OUT_OF_INDEXES, "tls = %x\n", tls); + TlsSetValue(tls, (void*)1); + + val = TlsGetValue(0); + ok(!val, "TlsGetValue(0) = %p\n", val); + + TlsFree(tls); + + /* The following is too ugly to be run by default */ + if(0) { + /* Set TLS index 0 value and see that this works and doesn't cause problems + * for remaining tests. */ + ret = TlsSetValue(0, (void*)1); + ok(ret, "TlsSetValue(0, 1) failed: %u\n", GetLastError()); + + val = TlsGetValue(0); + ok(val == (void*)1, "TlsGetValue(0) = %p\n", val); + } +} + +static void init_funcs(void) +{ + HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); + +/* Neither Cygwin nor mingW export OpenThread, so do a dynamic check + so that the compile passes */ + +#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f) + X(GetThreadPriorityBoost); + X(OpenThread); + X(QueueUserWorkItem); + X(SetThreadIdealProcessor); + X(SetThreadPriorityBoost); + X(RegisterWaitForSingleObject); + X(UnregisterWait); + X(IsWow64Process); + X(SetThreadErrorMode); + X(GetThreadErrorMode); + X(ActivateActCtx); + X(CreateActCtxW); + X(DeactivateActCtx); + X(GetCurrentActCtx); + X(ReleaseActCtx); + + X(CreateThreadpool); + X(CreateThreadpoolWork); + X(SubmitThreadpoolWork); + X(WaitForThreadpoolWorkCallbacks); + X(CloseThreadpoolWork); +#undef X +} + START_TEST(thread) { - HINSTANCE lib; HINSTANCE ntdll; int argc; char **argv; argc = winetest_get_mainargs( &argv ); -/* Neither Cygwin nor mingW export OpenThread, so do a dynamic check - so that the compile passes -*/ - lib=GetModuleHandleA("kernel32.dll"); - ok(lib!=NULL,"Couldn't get a handle for kernel32.dll\n"); - pGetThreadPriorityBoost=(void *)GetProcAddress(lib,"GetThreadPriorityBoost"); - pOpenThread=(void *)GetProcAddress(lib,"OpenThread"); - pQueueUserWorkItem=(void *)GetProcAddress(lib,"QueueUserWorkItem"); - pSetThreadIdealProcessor=(void *)GetProcAddress(lib,"SetThreadIdealProcessor"); - pSetThreadPriorityBoost=(void *)GetProcAddress(lib,"SetThreadPriorityBoost"); - pRegisterWaitForSingleObject=(void *)GetProcAddress(lib,"RegisterWaitForSingleObject"); - pUnregisterWait=(void *)GetProcAddress(lib,"UnregisterWait"); - pIsWow64Process=(void *)GetProcAddress(lib,"IsWow64Process"); - pSetThreadErrorMode=(void *)GetProcAddress(lib,"SetThreadErrorMode"); - pGetThreadErrorMode=(void *)GetProcAddress(lib,"GetThreadErrorMode"); + + init_funcs(); ntdll=GetModuleHandleA("ntdll.dll"); if (ntdll) @@ -1487,6 +1746,7 @@ START_TEST(thread) return; } + test_reserved_tls(); test_CreateRemoteThread(); test_CreateThread_basic(); test_CreateThread_suspended(); @@ -1507,4 +1767,7 @@ START_TEST(thread) #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) test_thread_fpu_cw(); #endif + test_thread_actctx(); + + test_threadpool(); } diff --git a/rostests/winetests/kernel32/time.c b/rostests/winetests/kernel32/time.c index 2f7118462a5..0cc4485cbbe 100755 --- a/rostests/winetests/kernel32/time.c +++ b/rostests/winetests/kernel32/time.c @@ -720,7 +720,7 @@ static void test_GetCalendarInfo(void) START_TEST(time) { - HMODULE hKernel = GetModuleHandle("kernel32"); + HMODULE hKernel = GetModuleHandleA("kernel32"); pTzSpecificLocalTimeToSystemTime = (void *)GetProcAddress(hKernel, "TzSpecificLocalTimeToSystemTime"); pSystemTimeToTzSpecificLocalTime = (void *)GetProcAddress( hKernel, "SystemTimeToTzSpecificLocalTime"); pGetCalendarInfoA = (void *)GetProcAddress(hKernel, "GetCalendarInfoA"); diff --git a/rostests/winetests/kernel32/timer.c b/rostests/winetests/kernel32/timer.c index a06217a1886..bcc800c494f 100755 --- a/rostests/winetests/kernel32/timer.c +++ b/rostests/winetests/kernel32/timer.c @@ -28,7 +28,7 @@ static void test_timer(void) { HANDLE (WINAPI *pCreateWaitableTimerA)( SECURITY_ATTRIBUTES*, BOOL, LPSTR ); BOOL (WINAPI *pSetWaitableTimer)(HANDLE, LARGE_INTEGER*, LONG, PTIMERAPCROUTINE, LPVOID, BOOL); - HMODULE hker = GetModuleHandle("kernel32"); + HMODULE hker = GetModuleHandleA("kernel32.dll"); HANDLE handle; BOOL r; LARGE_INTEGER due; diff --git a/rostests/winetests/kernel32/toolhelp.c b/rostests/winetests/kernel32/toolhelp.c index bfa31277400..ed76c9c6fe8 100644 --- a/rostests/winetests/kernel32/toolhelp.c +++ b/rostests/winetests/kernel32/toolhelp.c @@ -75,13 +75,13 @@ static int init(void) case 4: /* the sub-process */ ev1 = (HANDLE)(INT_PTR)atoi(argv[2]); ev2 = (HANDLE)(INT_PTR)atoi(argv[3]); - ev3 = CreateEvent(NULL, FALSE, FALSE, NULL); + ev3 = CreateEventW(NULL, FALSE, FALSE, NULL); if (ev3 == NULL) ExitProcess(WAIT_ABANDONED); hThread = CreateThread(NULL, 0, sub_thread, ev3, 0, &tid); if (hThread == NULL) ExitProcess(WAIT_ABANDONED); if (!LoadLibraryA("shell32.dll")) ExitProcess(WAIT_ABANDONED); - + /* signal init of sub-process is done */ SetEvent(ev1); /* wait for parent to have done all its queries */ @@ -204,17 +204,19 @@ static void test_thread(DWORD curr_pid, DWORD sub_pcs_pid) static const char* curr_expected_modules[] = { - "kernel32_test.exe" + "kernel32_test.exe", "kernel32.dll", - "ntdll.dll", + "ntdll.dll" }; + static const char* sub_expected_modules[] = { "kernel32_test.exe", "kernel32.dll", "shell32.dll", - "ntdll.dll", + "ntdll.dll" }; + #define NUM_OF(x) (sizeof(x) / sizeof(x[0])) static void test_module(DWORD pid, const char* expected[], unsigned num_expected) @@ -242,7 +244,7 @@ static void test_module(DWORD pid, const char* expected[], unsigned num_expected me.th32ProcessID, me.modBaseAddr, me.modBaseSize, me.szExePath, me.szModule); ok(me.th32ProcessID == pid, "wrong returned process id\n"); for (i = 0; i < num_expected; i++) - if (!lstrcmpi(expected[i], me.szModule)) found[i]++; + if (!lstrcmpiA(expected[i], me.szModule)) found[i]++; num++; } while (pModule32Next( hSnapshot, &me )); } @@ -260,7 +262,7 @@ static void test_module(DWORD pid, const char* expected[], unsigned num_expected trace("PID=%x base=%p size=%x %s %s\n", me.th32ProcessID, me.modBaseAddr, me.modBaseSize, me.szExePath, me.szModule); for (i = 0; i < num_expected; i++) - if (!lstrcmpi(expected[i], me.szModule)) found[i]++; + if (!lstrcmpiA(expected[i], me.szModule)) found[i]++; num--; } while (pModule32Next( hSnapshot, &me )); } @@ -317,8 +319,8 @@ START_TEST(toolhelp) sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; - ev1 = CreateEvent(&sa, FALSE, FALSE, NULL); - ev2 = CreateEvent(&sa, FALSE, FALSE, NULL); + ev1 = CreateEventW(&sa, FALSE, FALSE, NULL); + ev2 = CreateEventW(&sa, FALSE, FALSE, NULL); ok (ev1 != NULL && ev2 != NULL, "Couldn't create events\n"); memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); diff --git a/rostests/winetests/kernel32/version.c b/rostests/winetests/kernel32/version.c index 4b9a4f30241..e27ea4c7984 100644 --- a/rostests/winetests/kernel32/version.c +++ b/rostests/winetests/kernel32/version.c @@ -21,8 +21,6 @@ /* Needed for PRODUCT_* defines and GetProductInfo() */ #define _WIN32_WINNT 0x0600 -#include - #include "wine/test.h" #include "winbase.h" @@ -156,7 +154,7 @@ static void test_GetVersionEx(void) static void test_VerifyVersionInfo(void) { - OSVERSIONINFOEX info; + OSVERSIONINFOEXA info; BOOL ret; DWORD servicepack, error; @@ -169,8 +167,8 @@ static void test_VerifyVersionInfo(void) /* Before we start doing some tests we should check what the version of * the ServicePack is. Tests on a box with no ServicePack will fail otherwise. */ - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionExA((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); servicepack = info.wServicePackMajor; memset(&info, 0, sizeof(info)); @@ -223,8 +221,8 @@ static void test_VerifyVersionInfo(void) VER_MAJORVERSION, VER_GREATER_EQUAL)); ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.wServicePackMinor++; SetLastError(0xdeadbeef); ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, @@ -240,37 +238,37 @@ static void test_VerifyVersionInfo(void) } else { - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.wServicePackMajor--; ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER)); ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.wServicePackMajor--; ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); } - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.wServicePackMajor++; ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS)); ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.wServicePackMajor++; ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS_EQUAL)); ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.wServicePackMajor--; SetLastError(0xdeadbeef); ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, @@ -282,8 +280,8 @@ static void test_VerifyVersionInfo(void) /* test the failure hierarchy for the four version fields */ - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.wServicePackMajor++; SetLastError(0xdeadbeef); ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, @@ -293,8 +291,8 @@ static void test_VerifyVersionInfo(void) ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.dwMinorVersion++; SetLastError(0xdeadbeef); ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, @@ -304,8 +302,8 @@ static void test_VerifyVersionInfo(void) ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.dwMajorVersion++; SetLastError(0xdeadbeef); ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, @@ -319,8 +317,8 @@ static void test_VerifyVersionInfo(void) pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.dwBuildNumber++; SetLastError(0xdeadbeef); ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, @@ -335,8 +333,8 @@ static void test_VerifyVersionInfo(void) ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); /* test bad dwOSVersionInfoSize */ - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO *)&info); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((OSVERSIONINFOA *)&info); info.dwOSVersionInfoSize = 0; ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL)); diff --git a/rostests/winetests/kernel32/virtual.c b/rostests/winetests/kernel32/virtual.c index 99d32864d16..0d417a6b74c 100755 --- a/rostests/winetests/kernel32/virtual.c +++ b/rostests/winetests/kernel32/virtual.c @@ -49,12 +49,12 @@ static HANDLE create_target_process(const char *arg) char cmdline[MAX_PATH]; PROCESS_INFORMATION pi; BOOL ret; - STARTUPINFO si = { 0 }; + STARTUPINFOA si = { 0 }; si.cb = sizeof(si); winetest_get_mainargs( &argv ); sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg); - ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "error: %u\n", GetLastError()); ret = CloseHandle(pi.hThread); ok(ret, "error %u\n", GetLastError()); @@ -586,17 +586,17 @@ static void test_MapViewOfFile(void) SetLastError(0xdeadbeef); name = "Local\\Foo"; - file = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name ); + file = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name ); /* nt4 doesn't have Local\\ */ if (!file && GetLastError() == ERROR_PATH_NOT_FOUND) { name = "Foo"; - file = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name ); + file = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name ); } ok( file != 0, "CreateFileMapping PAGE_READWRITE error %u\n", GetLastError() ); SetLastError(0xdeadbeef); - mapping = OpenFileMapping( FILE_MAP_READ, FALSE, name ); + mapping = OpenFileMappingA( FILE_MAP_READ, FALSE, name ); ok( mapping != 0, "OpenFileMapping FILE_MAP_READ error %u\n", GetLastError() ); SetLastError(0xdeadbeef); ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 ); @@ -623,7 +623,7 @@ static void test_MapViewOfFile(void) CloseHandle( mapping ); SetLastError(0xdeadbeef); - mapping = OpenFileMapping( FILE_MAP_WRITE, FALSE, name ); + mapping = OpenFileMappingA( FILE_MAP_WRITE, FALSE, name ); ok( mapping != 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() ); SetLastError(0xdeadbeef); ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 ); @@ -1053,10 +1053,12 @@ static void test_NtAreMappedFilesTheSame(void) CloseHandle( file2 ); status = pNtAreMappedFilesTheSame( ptr, ptr ); - ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status ); + ok( status == STATUS_SUCCESS || broken(status == STATUS_NOT_SAME_DEVICE), + "NtAreMappedFilesTheSame returned %x\n", status ); status = pNtAreMappedFilesTheSame( ptr, (char *)ptr + 30 ); - ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status ); + ok( status == STATUS_SUCCESS || broken(status == STATUS_NOT_SAME_DEVICE), + "NtAreMappedFilesTheSame returned %x\n", status ); status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") ); ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status ); @@ -1283,7 +1285,7 @@ static void test_write_watch(void) "wrong error %u\n", GetLastError() ); SetLastError( 0xdeadbeef ); - ret = pGetWriteWatch( 0, GetModuleHandle(0), size, results, &count, &pagesize ); + ret = pGetWriteWatch( 0, GetModuleHandleW(NULL), size, results, &count, &pagesize ); if (ret) { ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret ); @@ -1459,7 +1461,7 @@ static void test_write_watch(void) ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); SetLastError( 0xdeadbeef ); - ret = pResetWriteWatch( GetModuleHandle(0), size ); + ret = pResetWriteWatch( GetModuleHandleW(NULL), size ); ok( ret == ~0u, "ResetWriteWatch succeeded %u\n", ret ); ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); } @@ -1486,7 +1488,7 @@ static void test_write_watch(void) ret = pResetWriteWatch( base, 0 ); ok( !ret, "ResetWriteWatch failed %u\n", ret ); - ret = pResetWriteWatch( GetModuleHandle(0), size ); + ret = pResetWriteWatch( GetModuleHandleW(NULL), size ); ok( !ret, "ResetWriteWatch failed %u\n", ret ); } @@ -1861,11 +1863,11 @@ static void test_CreateFileMapping_protection(void) GetSystemInfo(&si); trace("system page size %#x\n", si.dwPageSize); - GetTempPath(MAX_PATH, temp_path); - GetTempFileName(temp_path, "map", 0, file_name); + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "map", 0, file_name); SetLastError(0xdeadbeef); - hfile = CreateFile(file_name, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, NULL, CREATE_ALWAYS, 0, 0); + hfile = CreateFileA(file_name, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, NULL, CREATE_ALWAYS, 0, 0); ok(hfile != INVALID_HANDLE_VALUE, "CreateFile(%s) error %d\n", file_name, GetLastError()); SetFilePointer(hfile, si.dwPageSize, NULL, FILE_BEGIN); SetEndOfFile(hfile); @@ -1873,7 +1875,7 @@ static void test_CreateFileMapping_protection(void) for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) { SetLastError(0xdeadbeef); - hmap = CreateFileMapping(hfile, NULL, td[i].prot | SEC_COMMIT, 0, si.dwPageSize, NULL); + hmap = CreateFileMappingW(hfile, NULL, td[i].prot | SEC_COMMIT, 0, si.dwPageSize, NULL); if (td[i].success) { @@ -1954,7 +1956,7 @@ todo_wine if (page_exec_supported) alloc_prot = PAGE_EXECUTE_READWRITE; else alloc_prot = PAGE_READWRITE; SetLastError(0xdeadbeef); - hmap = CreateFileMapping(hfile, NULL, alloc_prot, 0, si.dwPageSize, NULL); + hmap = CreateFileMappingW(hfile, NULL, alloc_prot, 0, si.dwPageSize, NULL); ok(hmap != 0, "%d: CreateFileMapping error %d\n", i, GetLastError()); SetLastError(0xdeadbeef); @@ -2065,7 +2067,7 @@ todo_wine CloseHandle(hmap); CloseHandle(hfile); - DeleteFile(file_name); + DeleteFileA(file_name); } #define ACCESS_READ 0x01 @@ -2252,11 +2254,11 @@ static void test_mapping(void) GetSystemInfo(&si); trace("system page size %#x\n", si.dwPageSize); - GetTempPath(MAX_PATH, temp_path); - GetTempFileName(temp_path, "map", 0, file_name); + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "map", 0, file_name); SetLastError(0xdeadbeef); - hfile = CreateFile(file_name, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, NULL, CREATE_ALWAYS, 0, 0); + hfile = CreateFileA(file_name, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, NULL, CREATE_ALWAYS, 0, 0); ok(hfile != INVALID_HANDLE_VALUE, "CreateFile(%s) error %d\n", file_name, GetLastError()); SetFilePointer(hfile, si.dwPageSize, NULL, FILE_BEGIN); SetEndOfFile(hfile); @@ -2264,7 +2266,7 @@ static void test_mapping(void) for (i = 0; i < sizeof(page_prot)/sizeof(page_prot[0]); i++) { SetLastError(0xdeadbeef); - hmap = CreateFileMapping(hfile, NULL, page_prot[i] | SEC_COMMIT, 0, si.dwPageSize, NULL); + hmap = CreateFileMappingW(hfile, NULL, page_prot[i] | SEC_COMMIT, 0, si.dwPageSize, NULL); if (page_prot[i] == PAGE_NOACCESS) { @@ -2275,7 +2277,7 @@ static void test_mapping(void) /* A trick to create a not accessible mapping */ SetLastError(0xdeadbeef); - hmap = CreateFileMapping(hfile, NULL, PAGE_READWRITE | SEC_COMMIT, 0, si.dwPageSize, NULL); + hmap = CreateFileMappingW(hfile, NULL, PAGE_READWRITE | SEC_COMMIT, 0, si.dwPageSize, NULL); ok(hmap != 0, "CreateFileMapping(PAGE_READWRITE) error %d\n", GetLastError()); SetLastError(0xdeadbeef); ret = DuplicateHandle(GetCurrentProcess(), hmap, GetCurrentProcess(), &hmap2, 0, FALSE, 0); @@ -2442,7 +2444,7 @@ todo_wine } CloseHandle(hfile); - DeleteFile(file_name); + DeleteFileA(file_name); } static void test_shared_memory(int is_child) @@ -2451,7 +2453,7 @@ static void test_shared_memory(int is_child) LONG *p; SetLastError(0xdeadbef); - mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "winetest_virtual.c"); + mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "winetest_virtual.c"); ok(mapping != 0, "CreateFileMapping error %d\n", GetLastError()); if (is_child) ok(GetLastError() == ERROR_ALREADY_EXISTS, "expected ERROR_ALREADY_EXISTS, got %d\n", GetLastError()); @@ -2469,14 +2471,14 @@ static void test_shared_memory(int is_child) char **argv; char cmdline[MAX_PATH]; PROCESS_INFORMATION pi; - STARTUPINFO si = { sizeof(si) }; + STARTUPINFOA si = { sizeof(si) }; DWORD ret; *p = 0x1a2b3c4d; winetest_get_mainargs(&argv); sprintf(cmdline, "\"%s\" virtual sharedmem", argv[0]); - ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError()); winetest_wait_child_process(pi.hProcess); CloseHandle(pi.hThread); @@ -2525,10 +2527,10 @@ START_TEST(virtual) pVirtualFreeEx = (void *) GetProcAddress(hkernel32, "VirtualFreeEx"); pGetWriteWatch = (void *) GetProcAddress(hkernel32, "GetWriteWatch"); pResetWriteWatch = (void *) GetProcAddress(hkernel32, "ResetWriteWatch"); - pNtAreMappedFilesTheSame = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"), + pNtAreMappedFilesTheSame = (void *)GetProcAddress( GetModuleHandleA("ntdll.dll"), "NtAreMappedFilesTheSame" ); - pNtMapViewOfSection = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtMapViewOfSection"); - pNtUnmapViewOfSection = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtUnmapViewOfSection"); + pNtMapViewOfSection = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtMapViewOfSection"); + pNtUnmapViewOfSection = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"); test_shared_memory(0); test_mapping(); diff --git a/rostests/winetests/kernel32/volume.c b/rostests/winetests/kernel32/volume.c index 5a5b11c1f9c..fd52a2a9274 100644 --- a/rostests/winetests/kernel32/volume.c +++ b/rostests/winetests/kernel32/volume.c @@ -122,7 +122,7 @@ static void test_define_dos_deviceA(void) } /* Map it to point to the current directory */ - ret = GetCurrentDirectory(sizeof(buf), buf); + ret = GetCurrentDirectoryA(sizeof(buf), buf); ok(ret, "GetCurrentDir\n"); ret = DefineDosDeviceA(0, drivestr, buf); @@ -214,7 +214,7 @@ static void test_GetVolumeNameForVolumeMountPointA(void) "GetVolumeNameForVolumeMountPointA failed, wrong error returned, was %d, should be ERROR_FILENAME_EXCED_RANGE\n", GetLastError()); - /* Try on a arbitrary directory */ + /* Try on an arbitrary directory */ /* On FAT filesystems it seems that GetLastError() is set to ERROR_INVALID_FUNCTION. */ ret = pGetVolumeNameForVolumeMountPointA(temp_path, volume, len); @@ -368,26 +368,26 @@ static void test_GetVolumeInformationA(void) } /* get windows drive letter and update strings for testing */ - result = GetWindowsDirectory(windowsdir, sizeof(windowsdir)); + result = GetWindowsDirectoryA(windowsdir, sizeof(windowsdir)); ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n"); ok(result != 0, "GetWindowsDirectory: error %d\n", GetLastError()); Root_Colon[0] = windowsdir[0]; Root_Slash[0] = windowsdir[0]; Root_UNC[4] = windowsdir[0]; - result = GetCurrentDirectory(MAX_PATH, currentdir); + result = GetCurrentDirectoryA(MAX_PATH, currentdir); ok(result, "GetCurrentDirectory: error %d\n", GetLastError()); /* Note that GetCurrentDir yields no trailing slash for subdirs */ /* check for NO error on no trailing \ when current dir is root dir */ - ret = SetCurrentDirectory(Root_Slash); + ret = SetCurrentDirectoryA(Root_Slash); ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL, NULL, NULL, fs_name_buf, fs_name_len); ok(ret, "GetVolumeInformationA root failed, last error %u\n", GetLastError()); /* check for error on no trailing \ when current dir is subdir (windows) of queried drive */ - ret = SetCurrentDirectory(windowsdir); + ret = SetCurrentDirectoryA(windowsdir); ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); SetLastError(0xdeadbeef); ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL, @@ -396,7 +396,7 @@ static void test_GetVolumeInformationA(void) "GetVolumeInformationA did%s fail, last error %u\n", ret ? " not":"", GetLastError()); /* reset current directory */ - ret = SetCurrentDirectory(currentdir); + ret = SetCurrentDirectoryA(currentdir); ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); if (toupper(currentdir[0]) == toupper(windowsdir[0])) { @@ -408,12 +408,12 @@ static void test_GetVolumeInformationA(void) /* C:\windows becomes the current directory on drive C: */ /* Note that paths to subdirs are stored without trailing slash, like what GetCurrentDir yields. */ - ret = SetEnvironmentVariable(Root_Env, windowsdir); + ret = SetEnvironmentVariableA(Root_Env, windowsdir); ok(ret, "SetEnvironmentVariable %s failed\n", Root_Env); - ret = SetCurrentDirectory(windowsdir); + ret = SetCurrentDirectoryA(windowsdir); ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); - ret = SetCurrentDirectory(currentdir); + ret = SetCurrentDirectoryA(currentdir); ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); /* windows dir is current on the root drive, call fails */ @@ -428,9 +428,9 @@ static void test_GetVolumeInformationA(void) NULL, NULL, fs_name_buf, fs_name_len); ok(ret, "GetVolumeInformationA with \\ failed, last error %u\n", GetLastError()); - ret = SetCurrentDirectory(Root_Slash); + ret = SetCurrentDirectoryA(Root_Slash); ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); - ret = SetCurrentDirectory(currentdir); + ret = SetCurrentDirectoryA(currentdir); ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); /* windows dir is STILL CURRENT on root drive; the call fails as before, */ @@ -442,7 +442,7 @@ static void test_GetVolumeInformationA(void) "GetVolumeInformationA did%s fail, last error %u\n", ret ? " not":"", GetLastError()); /* Now C:\ becomes the current directory on drive C: */ - ret = SetEnvironmentVariable(Root_Env, Root_Slash); /* set =C:=C:\ */ + ret = SetEnvironmentVariableA(Root_Env, Root_Slash); /* set =C:=C:\ */ ok(ret, "SetEnvironmentVariable %s failed\n", Root_Env); /* \ is current on root drive, call succeeds */ @@ -451,9 +451,9 @@ static void test_GetVolumeInformationA(void) ok(ret, "GetVolumeInformationA failed, last error %u\n", GetLastError()); /* again, SetCurrentDirectory on another drive does not matter */ - ret = SetCurrentDirectory(Root_Slash); + ret = SetCurrentDirectoryA(Root_Slash); ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); - ret = SetCurrentDirectory(currentdir); + ret = SetCurrentDirectoryA(currentdir); ok(ret, "SetCurrentDirectory: error %d\n", GetLastError()); /* \ is current on root drive, call succeeds */ @@ -533,7 +533,7 @@ static void test_enum_vols(void) } /*get windows drive letter and update strings for testing */ - ret = GetWindowsDirectory( windowsdir, sizeof(windowsdir) ); + ret = GetWindowsDirectoryA( windowsdir, sizeof(windowsdir) ); ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n"); ok(ret != 0, "GetWindowsDirecory: error %d\n", GetLastError()); path[0] = windowsdir[0]; @@ -608,7 +608,6 @@ static void test_GetVolumePathNameA(void) ret = pGetVolumePathNameA(NULL, NULL, 0); error = GetLastError(); ok(!ret, "expected failure\n"); -todo_wine ok(error == ERROR_INVALID_PARAMETER || broken( error == 0xdeadbeef) /* <=XP */, "expected ERROR_INVALID_PARAMETER got %u\n", error); @@ -617,7 +616,6 @@ todo_wine ret = pGetVolumePathNameA("", NULL, 0); error = GetLastError(); ok(!ret, "expected failure\n"); -todo_wine ok(error == ERROR_INVALID_PARAMETER || broken( error == 0xdeadbeef) /* <=XP */, "expected ERROR_INVALID_PARAMETER got %u\n", error); @@ -626,7 +624,6 @@ todo_wine ret = pGetVolumePathNameA(pathC1, NULL, 0); error = GetLastError(); ok(!ret, "expected failure\n"); -todo_wine ok(error == ERROR_INVALID_PARAMETER || broken(error == ERROR_FILENAME_EXCED_RANGE) /* <=XP */, "expected ERROR_INVALID_PARAMETER got %u\n", error); @@ -635,7 +632,6 @@ todo_wine ret = pGetVolumePathNameA(pathC1, volume, 0); error = GetLastError(); ok(!ret, "expected failure\n"); -todo_wine ok(error == ERROR_INVALID_PARAMETER || broken(error == ERROR_FILENAME_EXCED_RANGE ) /* <=XP */, "expected ERROR_INVALID_PARAMETER got %u\n", error); @@ -644,7 +640,6 @@ todo_wine ret = pGetVolumePathNameA(pathC1, volume, 1); error = GetLastError(); ok(!ret, "expected failure\n"); -todo_wine ok(error == ERROR_FILENAME_EXCED_RANGE, "expected ERROR_FILENAME_EXCED_RANGE got %u\n", error); volume[0] = '\0'; @@ -666,6 +661,14 @@ todo_wine ok(ret, "expected success\n"); todo_wine ok(!strcmp(expected, volume), "expected name '%s', returned '%s'\n", expected, volume); + + /* test an invalid path */ + SetLastError( 0xdeadbeef ); + ret = pGetVolumePathNameA("\\\\$$$", volume, 1); + error = GetLastError(); + ok(!ret, "expected failure\n"); + ok(error == ERROR_INVALID_NAME || broken(ERROR_FILENAME_EXCED_RANGE) /* <=2000 */, + "expected ERROR_INVALID_NAME got %u\n", error); } static void test_GetVolumePathNamesForVolumeNameA(void)