* Sync with Wine 1.7.17.
CORE-8080
svn path=/trunk/; revision=62787
-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
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)
#include <initguid.h>
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);
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__
"<assemblyIdentity version=\"1.0.0.0\" name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
"</assembly>";
+static const char manifest1_1[] =
+"<assembly xmlns = \"urn:schemas-microsoft-com:asm.v1\" manifestVersion = \"1.0\">"
+"<assemblyIdentity version = \"1.0.0.0\" name = \"Wine.Test\" type = \"win32\"></assemblyIdentity>"
+"</assembly>";
+
static const char manifest2[] =
"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
"<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\">"
"</dependency>"
"</assembly>";
-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[] =
"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
" miscStatusContent=\"insideout\""
" miscStatusThumbnail=\"alignable\""
" miscStatusDocPrint=\"simpleframe,setclientsitefirst\""
+" >"
+" <progid>ProgId.ProgId.1</progid>"
+" <progid>ProgId.ProgId.2</progid>"
+" <progid>ProgId.ProgId.3</progid>"
+" <progid>ProgId.ProgId.4</progid>"
+" <progid>ProgId.ProgId.5</progid>"
+" <progid>ProgId.ProgId.6</progid>"
+" </comClass>"
+" <comClass clsid=\"{12345678-1234-5678-1234-111122223334}\" threadingModel=\"Neutral\" >"
+" <progid>ProgId.ProgId.7</progid>"
+" </comClass>"
+" <comInterfaceProxyStub "
+" name=\"Iifaceps\""
+" tlbid=\"{99999999-8888-7777-6666-555555555558}\""
+" iid=\"{66666666-8888-7777-6666-555555555555}\""
+" proxyStubClsid32=\"{66666666-8888-7777-6666-555555555556}\""
+" threadingModel=\"Free\""
+" numMethods=\"10\""
+" baseInterface=\"{66666666-8888-7777-6666-555555555557}\""
" />"
"</file>"
+" <comInterfaceExternalProxyStub "
+" name=\"Iifaceps2\""
+" tlbid=\"{99999999-8888-7777-6666-555555555558}\""
+" iid=\"{76666666-8888-7777-6666-555555555555}\""
+" proxyStubClsid32=\"{66666666-8888-7777-6666-555555555556}\""
+" numMethods=\"10\""
+" baseInterface=\"{66666666-8888-7777-6666-555555555557}\""
+" />"
+" <comInterfaceExternalProxyStub "
+" name=\"Iifaceps3\""
+" tlbid=\"{99999999-8888-7777-6666-555555555558}\""
+" iid=\"{86666666-8888-7777-6666-555555555555}\""
+" numMethods=\"10\""
+" baseInterface=\"{66666666-8888-7777-6666-555555555557}\""
+" />"
+" <clrSurrogate "
+" clsid=\"{96666666-8888-7777-6666-555555555555}\""
+" name=\"testsurrogate\""
+" runtimeVersion=\"v2.0.50727\""
+" />"
+" <clrClass "
+" clsid=\"{22345678-1234-5678-1234-111122223333}\""
+" name=\"clrclass\""
+" progid=\"clrprogid\""
+" description=\"test description\""
+" tlbid=\"{99999999-8888-7777-6666-555555555555}\""
+" runtimeVersion=\"1.2.3.4\""
+" threadingModel=\"Neutral\""
+" >"
+" <progid>clrprogid.1</progid>"
+" <progid>clrprogid.2</progid>"
+" <progid>clrprogid.3</progid>"
+" <progid>clrprogid.4</progid>"
+" <progid>clrprogid.5</progid>"
+" <progid>clrprogid.6</progid>"
+" </clrClass>"
"</assembly>";
static const char manifest_wndcls1[] =
" <windowClass versioned=\"no\">wndClass3</windowClass>"
" <windowClass>wndClass4</windowClass>"
" <typelib tlbid=\"{99999999-8888-7777-6666-555555555555}\" version=\"1.0\" helpdir=\"help\" resourceid=\"409\""
-" flags=\"HIDDEN,CONTROL,RESTRICTED\" />"
+" flags=\"HiddeN,CoNTROL,rESTRICTED\" />"
" <typelib tlbid=\"{99999999-8888-7777-6666-555555555556}\" version=\"1.0\" helpdir=\"help1\" resourceid=\"409\" />"
" <typelib tlbid=\"{99999999-8888-7777-6666-555555555557}\" version=\"1.0\" helpdir=\"\" />"
"</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);
DWORD unk1[3];
ULONG count;
ULONG index_offset;
- DWORD unk2[4];
+ DWORD unk2[2];
+ ULONG global_offset;
+ ULONG global_len;
};
struct string_index
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;
ULONG name_offset;
ULONG progid_len;
ULONG progid_offset;
- DWORD res2[2];
+ ULONG clrdata_len;
+ ULONG clrdata_offset;
DWORD miscstatus;
DWORD miscstatuscontent;
DWORD miscstatusthumbnail;
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));
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;
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;
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 */
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);
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};
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");
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");
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");
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);
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;
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__);
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) {
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) {
}
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) {
}
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__);
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);
}
}
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) {
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__);
}
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__);
}
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__);
char path[MAX_PATH];
char **argv;
PROCESS_INFORMATION pi;
- STARTUPINFO si = { 0 };
+ STARTUPINFOA si = { 0 };
HANDLE file;
FILETIME now;
BOOL ret;
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);
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);
}
test_actctx();
+ test_CreateActCtx();
run_child_process();
}
+++ /dev/null
-/*
- * 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 <stdarg.h>
-
-#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;i++) {
- if(mem2[i]!=0) {
- error=1;
- }
- }
- ok(!error,"HeapAlloc should have zeroed out it's allocated memory\n");
- }
-
-/* Check that HeapAlloc returns NULL when requested way too much memory */
- mem3=HeapAlloc(heap,0,5*memchunk);
- ok(mem3==NULL,"HeapAlloc should return NULL\n");
- if(mem3) {
- ok(HeapFree(heap,0,mem3),"HeapFree didn't pass successfully\n");
- }
-
-/* Check that HeapRealloc works */
- mem2a=HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
- ok(mem2a!=NULL,"HeapReAlloc failed\n");
- if(mem2a) {
- ok(HeapSize(heap,0,mem2a)>=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<memchunk;i++) {
- if(mem2ptr[i]!=0) {
- error=1;
- }
- }
- ok(!error,"GlobalAlloc should have zeroed out it's allocated memory\n");
- }
- }
-/* Check that GlobalReAlloc works */
-/* Check that we can change GMEM_FIXED to GMEM_MOVEABLE */
- mem2a=GlobalReAlloc(mem2,0,GMEM_MODIFY | GMEM_MOVEABLE);
- if(mem2a!=NULL) {
- mem2=mem2a;
- mem2ptr=GlobalLock(mem2a);
- ok(mem2ptr!=NULL && !GlobalUnlock(mem2a)&&GetLastError()==NO_ERROR,
- "Converting from FIXED to MOVEABLE didn't REALLY work\n");
- }
-
-/* Check that ReAllocing memory works as expected */
- mem2a=GlobalReAlloc(mem2,2*memchunk,GMEM_MOVEABLE | GMEM_ZEROINIT);
- ok(mem2a!=NULL,"GlobalReAlloc failed\n");
- if(mem2a) {
- ok(GlobalSize(mem2a)>=2*memchunk,"GlobalReAlloc failed\n");
- mem2ptr=GlobalLock(mem2a);
- ok(mem2ptr!=NULL,"GlobalLock Failed\n");
- if(mem2ptr) {
- error=0;
- for(i=0;i<memchunk;i++) {
- if(mem2ptr[memchunk+i]!=0) {
- error=1;
- }
- }
- ok(!error,"GlobalReAlloc should have zeroed out it's allocated memory\n");
-
-/* Check that GlobalHandle works */
- mem2b=GlobalHandle(mem2ptr);
- ok(mem2b==mem2a,"GlobalHandle didn't return the correct memory handle\n");
-
-/* Check that we can't discard locked memory */
- mem2b=GlobalDiscard(mem2a);
- if(mem2b==NULL) {
- ok(!GlobalUnlock(mem2a) && GetLastError()==NO_ERROR,"GlobalUnlock Failed\n");
- }
- }
- }
- if(mem1) {
- ok(GlobalFree(mem1)==NULL,"GlobalFree failed\n");
- }
- if(mem2a) {
- ok(GlobalFree(mem2a)==NULL,"GlobalFree failed\n");
- } else {
- ok(GlobalFree(mem2)==NULL,"GlobalFree 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
- LocalDiscard
- LocalFlags
-*/
-/* In addition, these features aren't being tested
- LMEM_DISCARDABLE
- LMEM_NOCOMPACT
-*/
-static void test_Local(void)
-{
- ULONG memchunk;
- HLOCAL mem1,mem2,mem2a,mem2b;
- UCHAR *mem2ptr;
- UINT error,i;
- memchunk=100000;
-
-/* Check that a normal alloc works */
- mem1=LocalAlloc(0,memchunk);
- ok(mem1!=NULL,"LocalAlloc failed: error=%d\n",GetLastError());
- if(mem1) {
- ok(LocalSize(mem1)>=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<memchunk;i++) {
- if(mem2ptr[i]!=0) {
- error=1;
- }
- }
- ok(!error,"LocalAlloc should have zeroed out it's allocated memory\n");
- SetLastError(0);
- error=LocalUnlock(mem2);
- ok(error==0 && GetLastError()==NO_ERROR,
- "LocalUnlock Failed: rc=%d err=%d\n",error,GetLastError());
- }
- }
- mem2a=LocalFree(mem2);
- ok(mem2a==NULL, "LocalFree failed: %p\n",mem2a);
-
-/* Reallocate mem2 as moveable memory */
- mem2=LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,memchunk);
- ok(mem2!=NULL, "LocalAlloc failed to create moveable memory, error=%d\n",GetLastError());
-
-/* Check that ReAllocing memory works as expected */
- mem2a=LocalReAlloc(mem2,2*memchunk,LMEM_MOVEABLE | LMEM_ZEROINIT);
- ok(mem2a!=NULL,"LocalReAlloc failed, error=%d\n",GetLastError());
- if(mem2a) {
- ok(LocalSize(mem2a)>=2*memchunk,"LocalReAlloc failed\n");
- mem2ptr=LocalLock(mem2a);
- ok(mem2ptr!=NULL,"LocalLock Failed\n");
- if(mem2ptr) {
- error=0;
- for(i=0;i<memchunk;i++) {
- if(mem2ptr[memchunk+i]!=0) {
- error=1;
- }
- }
- ok(!error,"LocalReAlloc should have zeroed out it's allocated memory\n");
-/* Check that LocalHandle works */
- mem2b=LocalHandle(mem2ptr);
- ok(mem2b==mem2a,"LocalHandle didn't return the correct memory handle\n");
-/* Check that we can't discard locked memory */
- mem2b=LocalDiscard(mem2a);
- ok(mem2b==NULL,"Discarded memory we shouldn't have\n");
- SetLastError(NO_ERROR);
- ok(!LocalUnlock(mem2a) && GetLastError()==NO_ERROR, "LocalUnlock Failed\n");
- }
- }
- if(mem1) {
- ok(LocalFree(mem1)==NULL,"LocalFree failed\n");
- }
- if(mem2a) {
- ok(LocalFree(mem2a)==NULL,"LocalFree failed\n");
- } else {
- ok(LocalFree(mem2)==NULL,"LocalFree failed\n");
- }
-}
-
-/* The Virtual* routines are not tested as thoroughly,
- since I don't really understand how to use them correctly :)
- The following routines are not tested at all
- VirtualAllocEx
- VirtualFreeEx
- VirtualLock
- VirtualProtect
- VirtualProtectEx
- VirtualQuery
- VirtualQueryEx
- VirtualUnlock
- And the only features (flags) being tested are
- MEM_COMMIT
- MEM_RELEASE
- PAGE_READWRITE
- Testing the rest requires using exceptions, which I really don't
- understand well
-*/
-static void test_Virtual(void)
-{
- SYSTEM_INFO sysInfo;
- ULONG memchunk;
- UCHAR *mem1;
- UINT error,i;
-
-/* Retrieve the page size for this system */
- sysInfo.dwPageSize=0;
- GetSystemInfo(&sysInfo);
- ok(sysInfo.dwPageSize>0,"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<memchunk;i++) {
- if(mem1[i]!=0) {
- error=1;
- }
- }
- ok(!error,"VirtualAlloc did not initialize memory to '0's\n");
-/* Check that we can read/write to memory */
- error=0;
- for(i=0;i<memchunk;i+=100) {
- mem1[i]='a';
- if(mem1[i]!='a') {
- error=1;
- }
- }
- ok(!error,"Virtual memory was not writable\n");
- }
- ok(VirtualFree(mem1,0,MEM_RELEASE),"VirtualFree failed\n");
-}
-START_TEST(alloc)
-{
- test_Heap();
- test_Global();
- test_Local();
- test_Virtual();
-}
OPEN_EXISTING, fflags, NULL);
ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
- ov.hEvent = CreateEvent( NULL, 1, 0, NULL );
+ ov.hEvent = CreateEventW( NULL, 1, 0, NULL );
SetLastError(0xd0b00b00);
r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,0,NULL,NULL,NULL);
OPEN_EXISTING, fflags, NULL);
ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
- ov.hEvent = CreateEvent( NULL, 1, 0, NULL );
+ ov.hEvent = CreateEventW( NULL, 1, 0, NULL );
filter = FILE_NOTIFY_CHANGE_FILE_NAME;
filter |= FILE_NOTIFY_CHANGE_DIR_NAME;
DeleteFileW( file );
RemoveDirectoryW( subdir );
RemoveDirectoryW( path );
-
+
r = CreateDirectoryW(path, NULL);
ok( r == TRUE, "failed to create directory\n");
OPEN_EXISTING, fflags, NULL);
ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
- ov.hEvent = CreateEvent( NULL, 0, 0, NULL );
+ ov.hEvent = CreateEventW( NULL, 0, 0, NULL );
filter = FILE_NOTIFY_CHANGE_FILE_NAME;
START_TEST(change)
{
- HMODULE hkernel32 = GetModuleHandle("kernel32");
+ HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
pReadDirectoryChangesW = (void *)GetProcAddress(hkernel32, "ReadDirectoryChangesW");
test_ffcnMultipleThreads();
}
}
+static void test_threadcp(void)
+{
+ static const LCID ENGLISH = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
+ static const LCID HINDI = MAKELCID(MAKELANGID(LANG_HINDI, SUBLANG_HINDI_INDIA), SORT_DEFAULT);
+ static const LCID GEORGIAN = MAKELCID(MAKELANGID(LANG_GEORGIAN, SUBLANG_GEORGIAN_GEORGIA), SORT_DEFAULT);
+ static const LCID RUSSIAN = MAKELCID(MAKELANGID(LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA), SORT_DEFAULT);
+ static const LCID JAPANESE = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), SORT_DEFAULT);
+ static const LCID CHINESE = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT);
+
+ BOOL islead, islead_acp;
+ CPINFOEXA cpi;
+ UINT cp, acp;
+ int i, num;
+ LCID last;
+ BOOL ret;
+
+ struct test {
+ LCID lcid;
+ UINT threadcp;
+ } lcids[] = {
+ { HINDI, 0 },
+ { GEORGIAN, 0 },
+ { ENGLISH, 1252 },
+ { RUSSIAN, 1251 },
+ { JAPANESE, 932 },
+ { CHINESE, 936 }
+ };
+
+ struct test_islead_nocp {
+ LCID lcid;
+ BYTE testchar;
+ } isleads_nocp[] = {
+ { HINDI, 0x00 },
+ { HINDI, 0x81 },
+ { HINDI, 0xa0 },
+ { HINDI, 0xe0 },
+
+ { GEORGIAN, 0x00 },
+ { GEORGIAN, 0x81 },
+ { GEORGIAN, 0xa0 },
+ { GEORGIAN, 0xe0 },
+ };
+
+ struct test_islead {
+ LCID lcid;
+ BYTE testchar;
+ BOOL islead;
+ } isleads[] = {
+ { ENGLISH, 0x00, FALSE },
+ { ENGLISH, 0x81, FALSE },
+ { ENGLISH, 0xa0, FALSE },
+ { ENGLISH, 0xe0, FALSE },
+
+ { RUSSIAN, 0x00, FALSE },
+ { RUSSIAN, 0x81, FALSE },
+ { RUSSIAN, 0xa0, FALSE },
+ { RUSSIAN, 0xe0, FALSE },
+
+ { JAPANESE, 0x00, FALSE },
+ { JAPANESE, 0x81, TRUE },
+ { JAPANESE, 0xa0, FALSE },
+ { JAPANESE, 0xe0, TRUE },
+
+ { CHINESE, 0x00, FALSE },
+ { CHINESE, 0x81, TRUE },
+ { CHINESE, 0xa0, TRUE },
+ { CHINESE, 0xe0, TRUE },
+ };
+
+ last = GetThreadLocale();
+ acp = GetACP();
+
+ for (i = 0; i < sizeof(lcids)/sizeof(lcids[0]); i++)
+ {
+ SetThreadLocale(lcids[i].lcid);
+
+ cp = 0xdeadbeef;
+ GetLocaleInfoA(lcids[i].lcid, LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER, (LPSTR)&cp, sizeof(cp));
+ ok(cp == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n", cp, lcids[i].threadcp, cp);
+
+ /* GetCPInfoEx/GetCPInfo - CP_ACP */
+ SetLastError(0xdeadbeef);
+ memset(&cpi, 0, sizeof(cpi));
+ ret = GetCPInfoExA(CP_ACP, 0, &cpi);
+ ok(ret, "GetCPInfoExA failed for lcid %04x, error %d\n", lcids[i].lcid, GetLastError());
+ ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n", cpi.CodePage, lcids[i].lcid, acp);
+
+ /* WideCharToMultiByte - CP_ACP */
+ num = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
+ ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
+
+ /* MultiByteToWideChar - CP_ACP */
+ num = MultiByteToWideChar(CP_ACP, 0, "foobar", -1, NULL, 0);
+ ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
+
+ /* GetCPInfoEx/GetCPInfo - CP_THREAD_ACP */
+ SetLastError(0xdeadbeef);
+ memset(&cpi, 0, sizeof(cpi));
+ ret = GetCPInfoExA(CP_THREAD_ACP, 0, &cpi);
+ ok(ret, "GetCPInfoExA failed for lcid %04x, error %d\n", lcids[i].lcid, GetLastError());
+ if (lcids[i].threadcp)
+ ok(cpi.CodePage == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n",
+ cpi.CodePage, lcids[i].lcid, lcids[i].threadcp);
+ else
+ ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n",
+ cpi.CodePage, lcids[i].lcid, acp);
+
+ /* WideCharToMultiByte - CP_THREAD_ACP */
+ num = WideCharToMultiByte(CP_THREAD_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
+ ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
+
+ /* MultiByteToWideChar - CP_THREAD_ACP */
+ num = MultiByteToWideChar(CP_THREAD_ACP, 0, "foobar", -1, NULL, 0);
+ ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
+ }
+
+ /* IsDBCSLeadByteEx - locales without codepage */
+ for (i = 0; i < sizeof(isleads_nocp)/sizeof(isleads_nocp[0]); i++)
+ {
+ SetThreadLocale(isleads_nocp[i].lcid);
+
+ islead_acp = IsDBCSLeadByteEx(CP_ACP, isleads_nocp[i].testchar);
+ islead = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads_nocp[i].testchar);
+
+ ok(islead == islead_acp, "wrong islead %i for test char %x in lcid %04x. should be %i\n",
+ islead, isleads_nocp[i].testchar, isleads_nocp[i].lcid, islead_acp);
+ }
+
+ /* IsDBCSLeadByteEx - locales with codepage */
+ for (i = 0; i < sizeof(isleads)/sizeof(isleads[0]); i++)
+ {
+ SetThreadLocale(isleads[i].lcid);
+
+ islead = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads[i].testchar);
+ ok(islead == isleads[i].islead, "wrong islead %i for test char %x in lcid %04x. should be %i\n",
+ islead, isleads[i].testchar, isleads[i].lcid, isleads[i].islead);
+ }
+
+ SetThreadLocale(last);
+}
+
START_TEST(codepage)
{
BOOL bUsedDefaultChar;
test_string_conversion(&bUsedDefaultChar);
test_undefined_byte_char();
+ test_threadcp();
}
#include <stdio.h>
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#include "wine/test.h"
+#include "winternl.h"
#include "winbase.h"
#include "winnls.h"
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];
COMMCONFIG commconfig;
DWORD size = sizeof(COMMCONFIG);
- if(GetDefaultCommConfig(port_name, &commconfig, &size))
+ if(GetDefaultCommConfigA(port_name, &commconfig, &size))
{
port = port_name[3];
break;
/* 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;
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;
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");
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 */
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");
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");
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");
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;
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);
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 */
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");
ok((ret = GetCommModemStatus(hcom, &defaultStat)), "GetCommModemStatus failed\n");
if (!ret) {
skip("modem status failed -> skip.\n");
+ CloseHandle(hcom);
return;
}
if(defaultStat & MS_RING_ON)
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");
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;
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");
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");
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;
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();
test_WaitDcd();
test_WaitBreak();
test_stdio();
+ test_read_write();
if (!winetest_interactive)
{
#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); \
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
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);
}
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++)
{
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++)
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)
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++)
{
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++)
{
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++)
{
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++)
{
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;
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;
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);
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++)
{
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++)
{
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++)
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++)
{
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;
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;
/* 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);
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);
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);
* 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());
}
}
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
{
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;
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);
}
{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;
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;
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. */
"[%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;
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;
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. */
"[%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;
const struct
{
HANDLE hConsoleOutput;
- CONST WORD *attr;
+ const WORD *attr;
DWORD length;
COORD coord;
LPDWORD lpNumAttrsWritten;
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";
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) */
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);
}
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)
{
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);
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);
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));
{
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);
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);
}
}
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)
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 */
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;
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);
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);
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)
*/
/* ReplaceFile requires Windows 2000 or newer */
-#define _WIN32_WINNT 0x0600
+#define _WIN32_WINNT 0x0601
#include <stdarg.h>
#include <stdlib.h>
#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);
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";
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 )
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);
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);
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.
"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());
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 );
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;
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());
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 )
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);
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);
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());
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 );
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)
static char get_windows_drive(void)
{
char windowsdir[MAX_PATH];
- GetWindowsDirectory(windowsdir, sizeof(windowsdir));
+ GetWindowsDirectoryA(windowsdir, sizeof(windowsdir));
return windowsdir[0];
}
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 );
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\*.*" */
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" */
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" */
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*" */
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" */
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" */
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 );
}
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 */
}
#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");
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 );
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) {
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");
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 )
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);
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;
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);
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() );
}
}
}
}
-static void test_CreatFile(void)
+static void test_CreateFile(void)
{
static const struct test_data
{
/* 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());
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);
}
}
- 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)
}
CloseHandle(directory);
- DeleteFile(tempFileName);
+ DeleteFileA(tempFileName);
}
static void test_OpenFileById(void)
CloseHandle(handle);
CloseHandle(directory);
- DeleteFile(tempFileName);
+ DeleteFileA(tempFileName);
}
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);
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)
test_GetTempFileNameA();
test_CopyFileA();
test_CopyFileW();
- test_CreatFile();
+ test_CopyFile2();
+ test_CreateFile();
test_CreateFileA();
test_CreateFileW();
+ test_CreateFile2();
test_DeleteFileA();
test_DeleteFileW();
test_MoveFileA();
test_GetFileInformationByHandleEx();
test_OpenFileById();
test_SetFileValidData();
+ test_file_access();
}
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
/*
* Unit test suite for heap functions
*
+ * Copyright 2002 Geoffrey Hausheer
* Copyright 2003 Dimitrie O. Paun
* Copyright 2006 Detlef Riekenberg
*
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");
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");
}
+
+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;i++) {
+ if(mem2[i]!=0) {
+ error=TRUE;
+ }
+ }
+ ok(!error,"HeapAlloc should have zeroed out its allocated memory\n");
+ }
+
+ /* Check that HeapAlloc returns NULL when requested way too much memory */
+ mem3=HeapAlloc(heap,0,5*memchunk);
+ ok(mem3==NULL,"HeapAlloc should return NULL\n");
+ if(mem3) {
+ ok(HeapFree(heap,0,mem3),"HeapFree didn't pass successfully\n");
+ }
+
+ /* Check that HeapRealloc works */
+ mem2a=HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
+ ok(mem2a!=NULL,"HeapReAlloc failed\n");
+ if(mem2a) {
+ ok(HeapSize(heap,0,mem2a)>=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<memchunk;i++) {
+ if(mem2ptr[i]!=0) {
+ error=TRUE;
+ }
+ }
+ ok(!error,"GlobalAlloc should have zeroed out its allocated memory\n");
+ }
+ }
+ /* Check that GlobalReAlloc works */
+ /* Check that we can change GMEM_FIXED to GMEM_MOVEABLE */
+ mem2a=GlobalReAlloc(mem2,0,GMEM_MODIFY | GMEM_MOVEABLE);
+ if(mem2a!=NULL) {
+ mem2=mem2a;
+ mem2ptr=GlobalLock(mem2a);
+ ok(mem2ptr!=NULL && !GlobalUnlock(mem2a)&&GetLastError()==NO_ERROR,
+ "Converting from FIXED to MOVEABLE didn't REALLY work\n");
+ }
+
+ /* Check that ReAllocing memory works as expected */
+ mem2a=GlobalReAlloc(mem2,2*memchunk,GMEM_MOVEABLE | GMEM_ZEROINIT);
+ ok(mem2a!=NULL,"GlobalReAlloc failed\n");
+ if(mem2a) {
+ ok(GlobalSize(mem2a)>=2*memchunk,"GlobalReAlloc failed\n");
+ mem2ptr=GlobalLock(mem2a);
+ ok(mem2ptr!=NULL,"GlobalLock Failed\n");
+ if(mem2ptr) {
+ error=FALSE;
+ for(i=0;i<memchunk;i++) {
+ if(mem2ptr[memchunk+i]!=0) {
+ error=TRUE;
+ }
+ }
+ ok(!error,"GlobalReAlloc should have zeroed out its allocated memory\n");
+
+ /* Check that GlobalHandle works */
+ mem2b=GlobalHandle(mem2ptr);
+ ok(mem2b==mem2a,"GlobalHandle didn't return the correct memory handle %p/%p for %p\n",
+ mem2a, mem2b, mem2ptr);
+ /* Check that we can't discard locked memory */
+ mem2b=GlobalDiscard(mem2a);
+ if(mem2b==NULL) {
+ ok(!GlobalUnlock(mem2a) && GetLastError()==NO_ERROR,"GlobalUnlock Failed\n");
+ }
+ }
+ }
+ if(mem1) {
+ ok(GlobalFree(mem1)==NULL,"GlobalFree failed\n");
+ }
+ if(mem2a) {
+ ok(GlobalFree(mem2a)==NULL,"GlobalFree failed\n");
+ } else {
+ ok(GlobalFree(mem2)==NULL,"GlobalFree failed\n");
+ }
+}
+
+
+static void test_LocalAlloc(void)
+{
+ ULONG memchunk;
+ HLOCAL mem1,mem2,mem2a,mem2b;
+ UCHAR *mem2ptr;
+ UINT i;
+ BOOL error;
+ memchunk=100000;
+
+ /* Check that a normal alloc works */
+ mem1=LocalAlloc(0,memchunk);
+ ok(mem1!=NULL,"LocalAlloc failed: error=%d\n",GetLastError());
+ if(mem1) {
+ ok(LocalSize(mem1)>=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<memchunk;i++) {
+ if(mem2ptr[i]!=0) {
+ error=TRUE;
+ }
+ }
+ ok(!error,"LocalAlloc should have zeroed out its allocated memory\n");
+ SetLastError(0);
+ error=LocalUnlock(mem2);
+ ok(!error && GetLastError()==NO_ERROR,
+ "LocalUnlock Failed: rc=%d err=%d\n",error,GetLastError());
+ }
+ }
+ mem2a=LocalFree(mem2);
+ ok(mem2a==NULL, "LocalFree failed: %p\n",mem2a);
+
+ /* Reallocate mem2 as moveable memory */
+ mem2=LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,memchunk);
+ ok(mem2!=NULL, "LocalAlloc failed to create moveable memory, error=%d\n",GetLastError());
+
+ /* Check that ReAllocing memory works as expected */
+ mem2a=LocalReAlloc(mem2,2*memchunk,LMEM_MOVEABLE | LMEM_ZEROINIT);
+ ok(mem2a!=NULL,"LocalReAlloc failed, error=%d\n",GetLastError());
+ if(mem2a) {
+ ok(LocalSize(mem2a)>=2*memchunk,"LocalReAlloc failed\n");
+ mem2ptr=LocalLock(mem2a);
+ ok(mem2ptr!=NULL,"LocalLock Failed\n");
+ if(mem2ptr) {
+ error=FALSE;
+ for(i=0;i<memchunk;i++) {
+ if(mem2ptr[memchunk+i]!=0) {
+ error=TRUE;
+ }
+ }
+ ok(!error,"LocalReAlloc should have zeroed out its allocated memory\n");
+ /* Check that LocalHandle works */
+ mem2b=LocalHandle(mem2ptr);
+ ok(mem2b==mem2a,"LocalHandle didn't return the correct memory handle %p/%p for %p\n",
+ mem2a, mem2b, mem2ptr);
+ /* Check that we can't discard locked memory */
+ mem2b=LocalDiscard(mem2a);
+ ok(mem2b==NULL,"Discarded memory we shouldn't have\n");
+ SetLastError(NO_ERROR);
+ ok(!LocalUnlock(mem2a) && GetLastError()==NO_ERROR, "LocalUnlock Failed\n");
+ }
+ }
+ if(mem1) {
+ ok(LocalFree(mem1)==NULL,"LocalFree failed\n");
+ }
+ if(mem2a) {
+ ok(LocalFree(mem2a)==NULL,"LocalFree failed\n");
+ } else {
+ ok(LocalFree(mem2)==NULL,"LocalFree failed\n");
+ }
+}
+
static void test_obsolete_flags(void)
{
static struct {
SIZE_T size;
BOOL ret;
- pHeapQueryInformation = (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "HeapQueryInformation");
+ pHeapQueryInformation = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "HeapQueryInformation");
if (!pHeapQueryInformation)
{
win_skip("HeapQueryInformation is not available\n");
test_heap();
test_obsolete_flags();
+ test_HeapCreate();
+ test_GlobalAlloc();
+ test_LocalAlloc();
/* Test both short and very long blocks */
test_sized_HeapAlloc(1);
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define NONAMELESSUNION
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#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)))
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);
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)
{
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 =
{
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;
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,
/* 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,
{ 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;
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)
- {
- 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)
+ file_size = create_test_dll( &dos_header, td[i].size_of_dos_header, &nt_header, dll_name );
+ if (!file_size)
{
- 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());
+ ok(0, "could not create %s\n", dll_name);
+ break;
}
- file_size = GetFileSize(hfile, NULL);
- CloseHandle(hfile);
-
SetLastError(0xdeadbeef);
- hlib = LoadLibrary(dll_name);
+ hlib = LoadLibraryA(dll_name);
if (hlib)
{
MEMORY_BASIC_INFORMATION info;
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)
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);*/
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);
}
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);
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)
}
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");
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);
}
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 */
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;
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);
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);
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);
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);
};
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;
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);
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);
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);
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);
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);
}
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());
}
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);
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);
CloseHandle(hfile);
SetLastError(0xdeadbeef);
- hlib = LoadLibrary(dll_name);
+ hlib = LoadLibraryA(dll_name);
ok(hlib != 0, "LoadLibrary error %d\n", GetLastError());
SetLastError(0xdeadbeef);
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);
/* 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
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);
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);
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;
}
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;
}
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;
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
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);
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);
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);
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);
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));
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)
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;
/* 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);
/* 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");
/* 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");
/* 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");
/* 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");
{
*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");
{
*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");
/* 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");
/* 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);
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());
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);
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);
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());
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;
-
- 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");
-
- mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "winetest_loader");
+ HANDLE ntdll, mapping;
+ SYSTEM_INFO si;
+
+ 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");
+
+ 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
}
test_Loader();
+ test_ResolveDelayLoadedAPI();
test_ImportDescriptors();
test_section_access();
+ test_import_resolution();
test_ExitProcess();
}
return NULL;
}
-static inline int isdigitW( WCHAR wc )
+static inline BOOL isdigitW( WCHAR wc )
{
WORD type;
GetStringTypeW( CT_CTYPE1, &wc, 1, &type );
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);
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)
{
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) \
#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)
"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;
/* 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");
/* 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 */,
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 */,
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 */,
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 */,
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);
"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;
0x0030, /* '0'-'9' */
0x0660, /* Eastern Arabic */
0x06F0, /* Arabic - Hindu */
+ 0x07C0, /* Nko */
0x0966, /* Devengari */
0x09E6, /* Bengalii */
0x0A66, /* Gurmukhi */
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 */
};
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 */
};
{
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 */
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)
(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;
DWORD in_len;
const WCHAR in[64];
DWORD ret;
+ DWORD broken_ret;
const WCHAR out[64];
DWORD flags;
DWORD err;
} 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
},
};
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<sizeof(test_data)/sizeof(*test_data); i++)
{
ret = pIdnToNameprepUnicode(test_data[i].flags, test_data[i].in,
test_data[i].in_len, buf, sizeof(buf)/sizeof(WCHAR));
err = GetLastError();
- if(!test_data[i].todo) {
- ok(ret == test_data[i].ret, "%d) ret = %d\n", i, ret);
- ok(err == test_data[i].err, "%d) err = %d\n", i, err);
- ok(!memcmp(test_data[i].out, buf, ret*sizeof(WCHAR)),
- "%d) buf = %s\n", i, wine_dbgstr_wn(buf, ret));
- }else {
- todo_wine ok(!memcmp(test_data[i].out, buf, ret*sizeof(WCHAR)),
- "%d) buf = %s\n", i, wine_dbgstr_wn(buf, ret));
+
+ if (!test_data[i].todo)
+ {
+ ok(ret == test_data[i].ret ||
+ broken(ret == test_data[i].broken_ret), "%d) ret = %d\n", i, ret);
}
+ else
+ {
+ todo_wine ok(ret == test_data[i].ret ||
+ broken(ret == test_data[i].broken_ret), "%d) ret = %d\n", i, ret);
+ }
+ if(ret != test_data[i].ret)
+ continue;
+
+ ok(err == test_data[i].err, "%d) err = %d\n", i, err);
+ ok(!memcmp(test_data[i].out, buf, ret*sizeof(WCHAR)),
+ "%d) buf = %s\n", i, wine_dbgstr_wn(buf, ret));
}
}
test_GetCurrencyFormatA(); /* Also tests the W version */
test_GetNumberFormatA(); /* Also tests the W version */
test_CompareStringA();
+ test_CompareStringEx();
test_LCMapStringA();
test_LCMapStringW();
test_LCMapStringEx();
&dwMsgCount, &dwTimeout ), "getmailslotinfo succeeded\n");
/* open a mailslot that doesn't exist */
- hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
+ hWriter = CreateFileA(szmspath, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
ok( hWriter == INVALID_HANDLE_VALUE, "nonexistent mailslot\n");
/* open a mailslot without the right name */
- hSlot = CreateMailslot( "blah", 0, 0, NULL );
+ hSlot = CreateMailslotA( "blah", 0, 0, NULL );
ok( hSlot == INVALID_HANDLE_VALUE,
"Created mailslot with invalid name\n");
ok( GetLastError() == ERROR_INVALID_NAME,
"error should be ERROR_INVALID_NAME\n");
/* open a mailslot with a null name */
- hSlot = CreateMailslot( NULL, 0, 0, NULL );
+ hSlot = CreateMailslotA( NULL, 0, 0, NULL );
ok( hSlot == INVALID_HANDLE_VALUE, "Created mailslot with invalid name\n");
ok( GetLastError() == ERROR_PATH_NOT_FOUND, "error should be ERROR_PATH_NOT_FOUND\n");
/* valid open, but with wacky parameters ... then check them */
- hSlot = CreateMailslot( szmspath, -1, -1, NULL );
+ hSlot = CreateMailslotA( szmspath, -1, -1, NULL );
ok( hSlot != INVALID_HANDLE_VALUE , "mailslot with valid name failed\n");
dwMax = dwNext = dwMsgCount = dwTimeout = 0;
ok( GetMailslotInfo( hSlot, &dwMax, &dwNext, &dwMsgCount, &dwTimeout ),
ok( CloseHandle(hSlot), "failed to close mailslot\n");
/* now open it for real */
- hSlot = CreateMailslot( szmspath, 0, 0, NULL );
+ hSlot = CreateMailslotA( szmspath, 0, 0, NULL );
ok( hSlot != INVALID_HANDLE_VALUE , "valid mailslot failed\n");
/* try and read/write to it */
+ count = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = ReadFile(INVALID_HANDLE_VALUE, buffer, 0, &count, NULL);
+ ok(!ret, "ReadFile should fail\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError());
+ ok(count == 0, "expected 0, got %u\n", count);
+
+ count = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = ReadFile(hSlot, buffer, 0, &count, NULL);
+ ok(!ret, "ReadFile should fail\n");
+todo_wine
+ ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError());
+ ok(count == 0, "expected 0, got %u\n", count);
+
count = 0;
memset(buffer, 0, sizeof buffer);
ret = ReadFile( hSlot, buffer, sizeof buffer, &count, NULL);
ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
/* now try and open the client, but with the wrong sharing mode */
- hWriter = CreateFile(szmspath, GENERIC_WRITE,
+ hWriter = CreateFileA(szmspath, GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
ok( hWriter != INVALID_HANDLE_VALUE /* vista */ || GetLastError() == ERROR_SHARING_VIOLATION,
"error should be ERROR_SHARING_VIOLATION got %p / %u\n", hWriter, GetLastError());
if (hWriter != INVALID_HANDLE_VALUE) CloseHandle( hWriter );
/* now open the client with the correct sharing mode */
- hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
+ hWriter = CreateFileA(szmspath, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
ok( hWriter != INVALID_HANDLE_VALUE, "existing mailslot err %u\n", GetLastError());
else ok( count == 0, "wrong count %u\n", count );
/* now try open another writer... should fail */
- hWriter2 = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
+ hWriter2 = CreateFileA(szmspath, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
/* succeeds on vista, don't test */
if (hWriter2 != INVALID_HANDLE_VALUE) CloseHandle( hWriter2 );
/* now try open another as a reader ... also fails */
- hWriter2 = CreateFile(szmspath, GENERIC_READ,
+ hWriter2 = CreateFileA(szmspath, GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
/* succeeds on vista, don't test */
if (hWriter2 != INVALID_HANDLE_VALUE) CloseHandle( hWriter2 );
/* now try open another as a writer ... still fails */
- hWriter2 = CreateFile(szmspath, GENERIC_WRITE,
+ hWriter2 = CreateFileA(szmspath, GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
/* succeeds on vista, don't test */
if (hWriter2 != INVALID_HANDLE_VALUE) CloseHandle( hWriter2 );
/* now open another one */
- hSlot2 = CreateMailslot( szmspath, 0, 0, NULL );
+ hSlot2 = CreateMailslotA( szmspath, 0, 0, NULL );
ok( hSlot2 == INVALID_HANDLE_VALUE , "opened two mailslots\n");
/* close the client again */
* now try reopen it with slightly different permissions ...
* shared writing
*/
- hWriter = CreateFile(szmspath, GENERIC_WRITE,
+ hWriter = CreateFileA(szmspath, GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
ok( hWriter != INVALID_HANDLE_VALUE, "sharing writer\n");
* now try open another as a writer ...
* but don't share with the first ... fail
*/
- hWriter2 = CreateFile(szmspath, GENERIC_WRITE,
+ hWriter2 = CreateFileA(szmspath, GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
/* succeeds on vista, don't test */
if (hWriter2 != INVALID_HANDLE_VALUE) CloseHandle( hWriter2 );
/* now try open another as a writer ... and share with the first */
- hWriter2 = CreateFile(szmspath, GENERIC_WRITE,
+ hWriter2 = CreateFileA(szmspath, GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
ok( hWriter2 != INVALID_HANDLE_VALUE, "2nd sharing writer\n");
ok( CloseHandle( hSlot ), "closing the mailslot\n");
/* test timeouts */
- hSlot = CreateMailslot( szmspath, 0, 1000, NULL );
+ hSlot = CreateMailslotA( szmspath, 0, 1000, NULL );
ok( hSlot != INVALID_HANDLE_VALUE , "valid mailslot failed\n");
count = 0;
memset(buffer, 0, sizeof buffer);
WCHAR bufW[MAX_PATH];
DWORD len1A, len1W = 0, len2A, len2W = 0;
- hMod = (name) ? GetModuleHandle(name) : NULL;
+ hMod = (name) ? GetModuleHandleA(name) : NULL;
/* first test, with enough space in buffer */
memset(bufA, '-', sizeof(bufA));
* - it must not already be loaded
* - it must not have a 16-bit counterpart
*/
- GetWindowsDirectory(path1, sizeof(path1));
+ GetWindowsDirectoryA(path1, sizeof(path1));
strcat(path1, "\\system\\");
strcat(path1, dllname);
hModule1 = LoadLibraryA(path1);
return;
}
- GetWindowsDirectory(path2, sizeof(path2));
+ GetWindowsDirectoryA(path2, sizeof(path2));
strcat(path2, "\\system32\\");
strcat(path2, dllname);
hModule2 = LoadLibraryA(path2);
ok(FreeLibrary(hModule3), "FreeLibrary() failed\n");
ok(FreeLibrary(hModule2), "FreeLibrary() failed\n");
ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
- ok(GetModuleHandle(dllname) == NULL, "%s was not fully unloaded\n", dllname);
+ ok(GetModuleHandleA(dllname) == NULL, "%s was not fully unloaded\n", dllname);
/* Try to load the dll again, if refcounting is ok, this should work */
hModule1 = LoadLibraryA(path1);
hmodule = LoadLibraryExA("", NULL, 0);
ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
- GetLastError() == ERROR_DLL_NOT_FOUND, /* win9x */
+ GetLastError() == ERROR_DLL_NOT_FOUND /* win9x */ ||
+ GetLastError() == ERROR_INVALID_PARAMETER /* win8 */,
"Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND, got %d\n",
GetLastError());
if (!hmodule) /* succeeds on xp and older */
ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
- CloseHandle(hmodule);
+ FreeLibrary(hmodule);
/* load kernel32.dll with no path */
SetLastError(0xdeadbeef);
GetLastError() == ERROR_SUCCESS, /* win9x */
"Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError());
- CloseHandle(hmodule);
+ FreeLibrary(hmodule);
GetCurrentDirectoryA(MAX_PATH, path);
if (path[lstrlenA(path) - 1] != '\\')
broken(GetLastError() == ERROR_INVALID_HANDLE), /* nt4 */
"Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
- /* Free the loaded dll when its the first time this dll is loaded
+ /* Free the loaded dll when it's the first time this dll is loaded
in process - First time should pass, second fail */
SetLastError(0xdeadbeef);
hmodule = LoadLibraryExA("comctl32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
ret = FreeLibrary(hmodule);
ok(!ret, "Unexpected ability to free the module, failed with %d\n", GetLastError());
- CloseHandle(hmodule);
-
+ /* load with full path, name without extension */
+ GetSystemDirectoryA(path, MAX_PATH);
+ if (path[lstrlenA(path) - 1] != '\\')
+ lstrcatA(path, "\\");
+ lstrcatA(path, "kernel32");
+ hmodule = LoadLibraryExA(path, NULL, 0);
+ ok(hmodule != NULL, "got %p\n", hmodule);
+ FreeLibrary(hmodule);
+
+ /* same with alterate search path */
+ hmodule = LoadLibraryExA(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+ ok(hmodule != NULL, "got %p\n", hmodule);
+ FreeLibrary(hmodule);
}
static void testGetDllDirectory(void)
bufferA[length] = 'A';
bufferA[length + 1] = 'A';
ret = pGetDllDirectoryA(length + 1, bufferA);
- ok(ret == length, "i=%d, Expected %u, got %u\n", i, length, ret);
+ ok(ret == length || broken(ret + 1 == length) /* win8 */,
+ "i=%d, Expected %u(+1), got %u\n", i, length, ret);
ok(bufferA[length + 1] == 'A', "i=%d, Buffer overflow\n", i);
ok(strcmp(bufferA, dll_directories[i]) == 0, "i=%d, Wrong path returned: '%s'\n", i, bufferA);
ok(cmpStrAW(dll_directories[i], bufferW, length, length),
"i=%d, Wrong path returned: %s\n", i, wine_dbgstr_w(bufferW));
- /* zero size buffer
- * the A version always null-terminates the buffer,
- * the W version doesn't do it on some platforms */
+ /* Zero size buffer. The buffer may or may not be terminated depending
+ * on the Windows version and whether the A or W API is called. */
bufferA[0] = 'A';
ret = pGetDllDirectoryA(0, bufferA);
ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
- ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i);
bufferW[0] = 'A';
ret = pGetDllDirectoryW(0, bufferW);
bufferA[0] = 'A';
ret = pGetDllDirectoryA(length, bufferA);
ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret);
- ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i);
+ if (length != 0)
+ ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i);
bufferW[0] = 'A';
ret = pGetDllDirectoryW(length, bufferW);
#define NOT_A_VALID_DRIVE '@'
+#ifdef __i386__
+#define ARCH "x86"
+#elif defined __x86_64__
+#define ARCH "amd64"
+#else
+#define ARCH "none"
+#endif
+
/* the following characters don't work well with GetFullPathNameA
in Win98. I don't know if this is a FAT thing, or if it is an OS thing
but I don't test these characters now.
static DWORD (WINAPI *pSearchPathA)(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*);
static DWORD (WINAPI *pSearchPathW)(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*);
+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);
+
/* a structure to deal with wine todos somewhat cleanly */
typedef struct {
DWORD shortlen;
/* split path into leading directory, and 8.3 filename */
static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
- int done,error;
+ BOOL done = FALSE, error = FALSE;
int ext,fil;
int len,i;
len=lstrlenA(path);
- ext=len; fil=len; done=0; error=0;
+ ext=len;
+ fil=len;
/* walk backwards over path looking for '.' or '\\' separators */
for(i=len-1;(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;
}
}
}
"%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);
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 */
/* 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 */
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());
/* 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)),
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",
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",
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);
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);
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)),
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",
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",
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);
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);
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]);
/* 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]);
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]);
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]);
/* 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])
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]);
/* 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]);
#undef is_upper_case_letter
}
+static const char manifest_dep[] =
+"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
+"<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
+" <file name=\"testdep.dll\" />"
+" <file name=\"ole32\" />"
+" <file name=\"kernel32.dll\" />"
+"</assembly>";
+
+static const char manifest_main[] =
+"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
+"<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
+"<dependency>"
+" <dependentAssembly>"
+" <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
+" </dependentAssembly>"
+"</dependency>"
+"</assembly>";
+
+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)
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)
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)
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;
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);
#include <stdarg.h>
#include <stdio.h>
-#include <windef.h>
-#include <winbase.h>
-#include <winsock.h>
-#include <wtypes.h>
-#include <winerror.h>
-
+#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"
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,
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,
"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,
/* 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,
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,
/* 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,
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,
/* 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,
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,
/* 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,
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,
/* 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,
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,
char buf[512];
DWORD written;
DWORD readden;
- DWORD success;
+ BOOL success;
/* Wait for client to connect */
trace("Server calling ConnectNamedPipe...\n");
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,
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 */
/* 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,
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,
/* 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 */
DWORD written;
DWORD readden;
DWORD dummy;
- DWORD success;
+ BOOL success;
OVERLAPPED oOverlap;
int letWFSOEwait = (i & 2);
int letGORwait = (i & 1);
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,
DWORD written;
DWORD readden;
DWORD dummy;
- DWORD success;
+ BOOL success;
OVERLAPPED oConnect;
OVERLAPPED oRead;
OVERLAPPED oWrite;
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,
/* 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 */
for (i = 0; i < NB_SERVER_LOOPS; i++) {
char buf[512];
DWORD readden;
- DWORD success;
+ BOOL success;
OVERLAPPED oOverlap;
DWORD err;
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());
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,
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);
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;
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,
/* 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());
* 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
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,
/* 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());
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,
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);
{
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())
#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); \
* 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 */
pQueryFullProcessImageNameA = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameA");
pQueryFullProcessImageNameW = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameW");
pK32GetProcessImageFileNameA = (void *) GetProcAddress(hkernel32, "K32GetProcessImageFileNameA");
- return 1;
+ return TRUE;
}
/******************************************************************
}
/* 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);
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);
}
}
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
{
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);
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);
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");
START_TEST(process)
{
- int b = init();
+ BOOL b = init();
ok(b, "Basic init of CreateProcess test\n");
if (!b) return;
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;
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
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);
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);
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);
/* 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);
/* 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);
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);
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 */
HANDLE res;
SetLastError(0xdeadbeef);
- res = BeginUpdateResource( filename, TRUE );
+ res = BeginUpdateResourceA( filename, TRUE );
GLE = GetLastError();
ok( res == NULL, "BeginUpdateResource should fail\n");
}
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");
}
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");
}
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");
}
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());
}
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");
}
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 );
{
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() );
{
DWORD i;
- DeleteFile( filename );
+ DeleteFileA( filename );
update_missing_exe();
if (GLE == ERROR_CALL_NOT_IMPLEMENTED)
check_exe( &sec->chk_version );
update_resources_bigdata();
check_exe( &sec->chk_bigdata );
- DeleteFile( filename );
+ DeleteFileA( filename );
}
test_find_resource();
}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define _WIN32_WINNT 0x600
+//#define _WIN32_WINNT 0x500
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
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);
DWORD r;
HANDLE event[2], semaphore[2], file;
- kernel32 = GetModuleHandle("kernel32");
+ kernel32 = GetModuleHandleA("kernel32.dll");
pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait");
if (!pSignalObjectAndWait)
}
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");
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);
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");
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());
}
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");
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);
/* 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);
} 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);
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");
}
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)
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);
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");
* we can wait on that many */
for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
{
- maxevents[i] = CreateEvent(NULL, i==0, TRUE, NULL);
+ maxevents[i] = CreateEventW(NULL, i==0, TRUE, NULL);
ok( maxevents[i] != 0, "should create enough events\n");
}
if (!pInitializeConditionVariable) {
/* function is not yet in XP, only in newer Windows */
- /* and not yet implemented in Wine for some days/weeks */
- todo_wine win_skip("no condition variable support.\n");
+ win_skip("no condition variable support.\n");
return;
}
static DWORD condvar_seq = 0;
static CONDITION_VARIABLE condvar_base = CONDITION_VARIABLE_INIT;
static CRITICAL_SECTION condvar_crit;
+static SRWLOCK condvar_srwlock;
/* Sequence of wake/sleep to check boundary conditions:
* 0: init
* 6: a wakeall is handed to a SleepConditionVariableCS
* 7: sleep after above should timeout
* 8: wake with crit section locked into the sleep timeout
- * 9: end
+ *
+ * the following tests will only be executed if InitializeSRWLock is available
+ *
+ * 9: producer (exclusive) wakes up consumer (exclusive)
+ * 10: producer (exclusive) wakes up consumer (shared)
+ * 11: producer (shared) wakes up consumer (exclusive)
+ * 12: producer (shared) wakes up consumer (shared)
+ * 13: end
*/
static DWORD WINAPI condvar_base_producer(LPVOID x) {
while (condvar_seq < 1) Sleep(1);
Sleep(50);
LeaveCriticalSection (&condvar_crit);
+ /* skip over remaining tests if InitializeSRWLock is not available */
+ if (!pInitializeSRWLock)
+ return 0;
+
+ while (condvar_seq < 9) Sleep(1);
+ pAcquireSRWLockExclusive(&condvar_srwlock);
+ pWakeConditionVariable(&condvar_base);
+ pReleaseSRWLockExclusive(&condvar_srwlock);
+
+ while (condvar_seq < 10) Sleep(1);
+ pAcquireSRWLockExclusive(&condvar_srwlock);
+ pWakeConditionVariable(&condvar_base);
+ pReleaseSRWLockExclusive(&condvar_srwlock);
+
+ while (condvar_seq < 11) Sleep(1);
+ pAcquireSRWLockShared(&condvar_srwlock);
+ pWakeConditionVariable(&condvar_base);
+ pReleaseSRWLockShared(&condvar_srwlock);
+
+ while (condvar_seq < 12) Sleep(1);
+ Sleep(50); /* ensure that consumer waits for cond variable */
+ pAcquireSRWLockShared(&condvar_srwlock);
+ pWakeConditionVariable(&condvar_base);
+ pReleaseSRWLockShared(&condvar_srwlock);
+
return 0;
}
ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 20);
LeaveCriticalSection (&condvar_crit);
ok (ret, "SleepConditionVariableCS should still return TRUE on crit unlock delay\n");
- condvar_seq = 9;
+ /* skip over remaining tests if InitializeSRWLock is not available */
+ if (!pInitializeSRWLock)
+ {
+ win_skip("no srw lock support.\n");
+ condvar_seq = 13; /* end */
+ return 0;
+ }
+
+ pAcquireSRWLockExclusive(&condvar_srwlock);
+ condvar_seq = 9;
+ ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0);
+ pReleaseSRWLockExclusive(&condvar_srwlock);
+ ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
+
+ pAcquireSRWLockShared(&condvar_srwlock);
+ condvar_seq = 10;
+ ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED);
+ pReleaseSRWLockShared(&condvar_srwlock);
+ ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
+
+ pAcquireSRWLockExclusive(&condvar_srwlock);
+ condvar_seq = 11;
+ ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0);
+ pReleaseSRWLockExclusive(&condvar_srwlock);
+ ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
+
+ pAcquireSRWLockShared(&condvar_srwlock);
+ condvar_seq = 12;
+ ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED);
+ pReleaseSRWLockShared(&condvar_srwlock);
+ ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
+
+ condvar_seq = 13;
return 0;
}
if (!pInitializeConditionVariable) {
/* function is not yet in XP, only in newer Windows */
- /* and not yet implemented in Wine for some days/weeks */
- todo_wine win_skip("no condition variable support.\n");
+ win_skip("no condition variable support.\n");
return;
}
InitializeCriticalSection (&condvar_crit);
+ if (pInitializeSRWLock)
+ pInitializeSRWLock(&condvar_srwlock);
+
EnterCriticalSection (&condvar_crit);
ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
LeaveCriticalSection (&condvar_crit);
ok (!ret, "SleepConditionVariableCS should return FALSE on untriggered condvar\n");
ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
+ if (pInitializeSRWLock)
+ {
+ pAcquireSRWLockExclusive(&condvar_srwlock);
+ ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, 0);
+ pReleaseSRWLockExclusive(&condvar_srwlock);
+
+ ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n");
+ ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
+
+ pAcquireSRWLockShared(&condvar_srwlock);
+ ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, CONDITION_VARIABLE_LOCKMODE_SHARED);
+ pReleaseSRWLockShared(&condvar_srwlock);
+
+ ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n");
+ ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
+ }
+
hp = CreateThread(NULL, 0, condvar_base_producer, NULL, 0, &dummy);
hc = CreateThread(NULL, 0, condvar_base_consumer, NULL, 0, &dummy);
WaitForSingleObject(hc, 100);
}
+static LONG srwlock_seq = 0;
+static SRWLOCK srwlock_base;
+static struct
+{
+ LONG wrong_execution_order;
+ LONG samethread_excl_excl;
+ LONG samethread_excl_shared;
+ LONG samethread_shared_excl;
+ LONG multithread_excl_excl;
+ LONG excl_not_preferred;
+ LONG trylock_excl;
+ LONG trylock_shared;
+} srwlock_base_errors;
+
+/* Sequence of acquire/release to check boundary conditions:
+ * 0: init
+ *
+ * 1: thread2 acquires an exclusive lock and tries to acquire a second exclusive lock
+ * 2: thread1 expects a deadlock and releases the waiting lock
+ * thread2 releases the lock again
+ *
+ * 3: thread2 acquires an exclusive lock and tries to acquire a shared lock
+ * 4: thread1 expects a deadlock and releases the waiting lock
+ * thread2 releases the lock again
+ *
+ * 5: thread2 acquires a shared lock and tries to acquire an exclusive lock
+ * 6: thread1 expects a deadlock and releases the waiting lock
+ * thread2 releases the lock again
+ *
+ * 7: thread2 acquires and releases two nested shared locks
+ *
+ * 8: thread1 acquires an exclusive lock
+ * 9: thread2 tries to acquire the exclusive lock, too
+ * thread1 releases the exclusive lock again
+ * 10: thread2 enters the exclusive lock and leaves it immediately again
+ *
+ * 11: thread1 acquires a shared lock
+ * 12: thread2 acquires and releases a shared lock
+ * thread1 releases the lock again
+ *
+ * 13: thread1 acquires a shared lock
+ * 14: thread2 tries to acquire an exclusive lock
+ * 15: thread3 tries to acquire a shared lock
+ * 16: thread1 releases the shared lock
+ * 17: thread2 wakes up and releases the exclusive lock
+ * 18: thread3 wakes up and releases the shared lock
+ *
+ * the following tests will only be executed if TryAcquireSRWLock* is available
+ *
+ * 19: thread1 calls TryAcquireSRWLockExclusive which should return TRUE
+ * thread1 checks the result of recursive calls to TryAcquireSRWLock*
+ * thread1 releases the exclusive lock
+ *
+ * thread1 calls TryAcquireSRWLockShared which should return TRUE
+ * thread1 checks the result of recursive calls to TryAcquireSRWLock*
+ * thread1 releases the shared lock
+ *
+ * thread1 acquires an exclusive lock
+ * 20: thread2 calls TryAcquireSRWLockShared which should return FALSE
+ * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
+ * 21: thread1 releases the exclusive lock
+ *
+ * thread1 acquires an shared lock
+ * 22: thread2 calls TryAcquireSRWLockShared which should return TRUE
+ * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
+ * 23: thread1 releases the shared lock
+ *
+ * thread1 acquires a shared lock and tries to acquire an exclusive lock
+ * 24: thread2 calls TryAcquireSRWLockShared which should return FALSE
+ * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
+ * 25: thread1 releases the exclusive lock
+ *
+ * thread1 acquires two shared locks
+ * 26: thread2 calls TryAcquireSRWLockShared which should return TRUE
+ * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
+ * 27: thread1 releases one shared lock
+ * 28: thread2 calls TryAcquireSRWLockShared which should return TRUE
+ * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
+ * 29: thread1 releases the second shared lock
+ * 30: thread2 calls TryAcquireSRWLockShared which should return TRUE
+ * thread2 calls TryAcquireSRWLockExclusive which should return TRUE
+ *
+ * 31: end
+ */
+
+static DWORD WINAPI srwlock_base_thread1(LPVOID x)
+{
+ /* seq 2 */
+ while (srwlock_seq < 2) Sleep(1);
+ Sleep(100);
+ if (InterlockedIncrement(&srwlock_seq) != 3)
+ InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
+ pReleaseSRWLockExclusive(&srwlock_base);
+
+ /* seq 4 */
+ while (srwlock_seq < 4) Sleep(1);
+ Sleep(100);
+ if (InterlockedIncrement(&srwlock_seq) != 5)
+ InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
+ pReleaseSRWLockExclusive(&srwlock_base);
+
+ /* seq 6 */
+ while (srwlock_seq < 6) Sleep(1);
+ Sleep(100);
+ if (InterlockedIncrement(&srwlock_seq) != 7)
+ InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
+ pReleaseSRWLockShared(&srwlock_base);
+
+ /* seq 8 */
+ while (srwlock_seq < 8) Sleep(1);
+ pAcquireSRWLockExclusive(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 9)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+ Sleep(100);
+ if (InterlockedIncrement(&srwlock_seq) != 10)
+ InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
+ pReleaseSRWLockExclusive(&srwlock_base);
+
+ /* seq 11 */
+ while (srwlock_seq < 11) Sleep(1);
+ pAcquireSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 12)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 13 */
+ while (srwlock_seq < 13) Sleep(1);
+ pReleaseSRWLockShared(&srwlock_base);
+ pAcquireSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 14)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 16 */
+ while (srwlock_seq < 16) Sleep(1);
+ Sleep(50); /* ensure that both the exclusive and shared access thread are queued */
+ if (InterlockedIncrement(&srwlock_seq) != 17)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+ pReleaseSRWLockShared(&srwlock_base);
+
+ /* skip over remaining tests if TryAcquireSRWLock* is not available */
+ if (!pTryAcquireSRWLockExclusive)
+ return 0;
+
+ /* seq 19 */
+ while (srwlock_seq < 19) Sleep(1);
+ if (pTryAcquireSRWLockExclusive(&srwlock_base))
+ {
+ if (pTryAcquireSRWLockShared(&srwlock_base))
+ InterlockedIncrement(&srwlock_base_errors.trylock_shared);
+ if (pTryAcquireSRWLockExclusive(&srwlock_base))
+ InterlockedIncrement(&srwlock_base_errors.trylock_excl);
+ pReleaseSRWLockExclusive(&srwlock_base);
+ }
+ else
+ InterlockedIncrement(&srwlock_base_errors.trylock_excl);
+
+ if (pTryAcquireSRWLockShared(&srwlock_base))
+ {
+ if (pTryAcquireSRWLockShared(&srwlock_base))
+ pReleaseSRWLockShared(&srwlock_base);
+ else
+ InterlockedIncrement(&srwlock_base_errors.trylock_shared);
+ if (pTryAcquireSRWLockExclusive(&srwlock_base))
+ InterlockedIncrement(&srwlock_base_errors.trylock_excl);
+ pReleaseSRWLockShared(&srwlock_base);
+ }
+ else
+ InterlockedIncrement(&srwlock_base_errors.trylock_shared);
+
+ pAcquireSRWLockExclusive(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 20)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 21 */
+ while (srwlock_seq < 21) Sleep(1);
+ pReleaseSRWLockExclusive(&srwlock_base);
+ pAcquireSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 22)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 23 */
+ while (srwlock_seq < 23) Sleep(1);
+ pReleaseSRWLockShared(&srwlock_base);
+ pAcquireSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 24)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 25 */
+ pAcquireSRWLockExclusive(&srwlock_base);
+ if (srwlock_seq != 25)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+ pReleaseSRWLockExclusive(&srwlock_base);
+
+ pAcquireSRWLockShared(&srwlock_base);
+ pAcquireSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 26)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 27 */
+ while (srwlock_seq < 27) Sleep(1);
+ pReleaseSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 28)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 29 */
+ while (srwlock_seq < 29) Sleep(1);
+ pReleaseSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 30)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ return 0;
+}
+
+static DWORD WINAPI srwlock_base_thread2(LPVOID x)
+{
+ /* seq 1 */
+ while (srwlock_seq < 1) Sleep(1);
+ pAcquireSRWLockExclusive(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 2)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 3 */
+ pAcquireSRWLockExclusive(&srwlock_base);
+ if (srwlock_seq != 3)
+ InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
+ pReleaseSRWLockExclusive(&srwlock_base);
+ pAcquireSRWLockExclusive(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 4)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 5 */
+ pAcquireSRWLockShared(&srwlock_base);
+ if (srwlock_seq != 5)
+ InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
+ pReleaseSRWLockShared(&srwlock_base);
+ pAcquireSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 6)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 7 */
+ pAcquireSRWLockExclusive(&srwlock_base);
+ if (srwlock_seq != 7)
+ InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
+ pReleaseSRWLockExclusive(&srwlock_base);
+ pAcquireSRWLockShared(&srwlock_base);
+ pAcquireSRWLockShared(&srwlock_base);
+ pReleaseSRWLockShared(&srwlock_base);
+ pReleaseSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 8)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 9, 10 */
+ while (srwlock_seq < 9) Sleep(1);
+ pAcquireSRWLockExclusive(&srwlock_base);
+ if (srwlock_seq != 10)
+ InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
+ pReleaseSRWLockExclusive(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 11)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 12 */
+ while (srwlock_seq < 12) Sleep(1);
+ pAcquireSRWLockShared(&srwlock_base);
+ pReleaseSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 13)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 14 */
+ while (srwlock_seq < 14) Sleep(1);
+ if (InterlockedIncrement(&srwlock_seq) != 15)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 17 */
+ pAcquireSRWLockExclusive(&srwlock_base);
+ if (srwlock_seq != 17)
+ InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
+ if (InterlockedIncrement(&srwlock_seq) != 18)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+ pReleaseSRWLockExclusive(&srwlock_base);
+
+ /* skip over remaining tests if TryAcquireSRWLock* is not available */
+ if (!pTryAcquireSRWLockExclusive)
+ return 0;
+
+ /* seq 20 */
+ while (srwlock_seq < 20) Sleep(1);
+ if (pTryAcquireSRWLockShared(&srwlock_base))
+ InterlockedIncrement(&srwlock_base_errors.trylock_shared);
+ if (pTryAcquireSRWLockExclusive(&srwlock_base))
+ InterlockedIncrement(&srwlock_base_errors.trylock_excl);
+ if (InterlockedIncrement(&srwlock_seq) != 21)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 22 */
+ while (srwlock_seq < 22) Sleep(1);
+ if (pTryAcquireSRWLockShared(&srwlock_base))
+ pReleaseSRWLockShared(&srwlock_base);
+ else
+ InterlockedIncrement(&srwlock_base_errors.trylock_shared);
+ if (pTryAcquireSRWLockExclusive(&srwlock_base))
+ InterlockedIncrement(&srwlock_base_errors.trylock_excl);
+ if (InterlockedIncrement(&srwlock_seq) != 23)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 24 */
+ while (srwlock_seq < 24) Sleep(1);
+ Sleep(50); /* ensure that exclusive access request is queued */
+ if (pTryAcquireSRWLockShared(&srwlock_base))
+ {
+ pReleaseSRWLockShared(&srwlock_base);
+ InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
+ }
+ if (pTryAcquireSRWLockExclusive(&srwlock_base))
+ InterlockedIncrement(&srwlock_base_errors.trylock_excl);
+ if (InterlockedIncrement(&srwlock_seq) != 25)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+ pReleaseSRWLockShared(&srwlock_base);
+
+ /* seq 26 */
+ while (srwlock_seq < 26) Sleep(1);
+ if (pTryAcquireSRWLockShared(&srwlock_base))
+ pReleaseSRWLockShared(&srwlock_base);
+ else
+ InterlockedIncrement(&srwlock_base_errors.trylock_shared);
+ if (pTryAcquireSRWLockExclusive(&srwlock_base))
+ InterlockedIncrement(&srwlock_base_errors.trylock_excl);
+ if (InterlockedIncrement(&srwlock_seq) != 27)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 28 */
+ while (srwlock_seq < 28) Sleep(1);
+ if (pTryAcquireSRWLockShared(&srwlock_base))
+ pReleaseSRWLockShared(&srwlock_base);
+ else
+ InterlockedIncrement(&srwlock_base_errors.trylock_shared);
+ if (pTryAcquireSRWLockExclusive(&srwlock_base))
+ InterlockedIncrement(&srwlock_base_errors.trylock_excl);
+ if (InterlockedIncrement(&srwlock_seq) != 29)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 30 */
+ while (srwlock_seq < 30) Sleep(1);
+ if (pTryAcquireSRWLockShared(&srwlock_base))
+ pReleaseSRWLockShared(&srwlock_base);
+ else
+ InterlockedIncrement(&srwlock_base_errors.trylock_shared);
+ if (pTryAcquireSRWLockExclusive(&srwlock_base))
+ pReleaseSRWLockExclusive(&srwlock_base);
+ else
+ InterlockedIncrement(&srwlock_base_errors.trylock_excl);
+ if (InterlockedIncrement(&srwlock_seq) != 31)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ return 0;
+}
+
+static DWORD WINAPI srwlock_base_thread3(LPVOID x)
+{
+ /* seq 15 */
+ while (srwlock_seq < 15) Sleep(1);
+ Sleep(50); /* some delay, such that thread2 can try to acquire a second exclusive lock */
+ if (InterlockedIncrement(&srwlock_seq) != 16)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* seq 18 */
+ pAcquireSRWLockShared(&srwlock_base);
+ if (srwlock_seq != 18)
+ InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
+ pReleaseSRWLockShared(&srwlock_base);
+ if (InterlockedIncrement(&srwlock_seq) != 19)
+ InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
+
+ /* skip over remaining tests if TryAcquireSRWLock* is not available */
+ if (!pTryAcquireSRWLockExclusive)
+ {
+ /* function is only in Windows 7 and newer */
+ win_skip("no srw trylock support.\n");
+ srwlock_seq = 31; /* end */
+ return 0;
+ }
+
+ return 0;
+}
+
+static void test_srwlock_base(void)
+{
+ HANDLE h1, h2, h3;
+ DWORD dummy;
+
+ if (!pInitializeSRWLock)
+ {
+ /* function is not yet in XP, only in newer Windows */
+ win_skip("no srw lock support.\n");
+ return;
+ }
+
+ pInitializeSRWLock(&srwlock_base);
+ memset(&srwlock_base_errors, 0, sizeof(srwlock_base_errors));
+
+ h1 = CreateThread(NULL, 0, srwlock_base_thread1, NULL, 0, &dummy);
+ h2 = CreateThread(NULL, 0, srwlock_base_thread2, NULL, 0, &dummy);
+ h3 = CreateThread(NULL, 0, srwlock_base_thread3, NULL, 0, &dummy);
+
+ srwlock_seq = 1; /* go */
+ while (srwlock_seq < 31)
+ Sleep(5);
+
+ WaitForSingleObject(h1, 100);
+ WaitForSingleObject(h2, 100);
+ WaitForSingleObject(h3, 100);
+
+ ok(!srwlock_base_errors.wrong_execution_order,
+ "thread commands were executed in the wrong order (occurred %d times).\n",
+ srwlock_base_errors.wrong_execution_order);
+
+ ok(!srwlock_base_errors.samethread_excl_excl,
+ "AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred %d times).\n",
+ srwlock_base_errors.samethread_excl_excl);
+
+ ok(!srwlock_base_errors.samethread_excl_shared,
+ "AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred %d times).\n",
+ srwlock_base_errors.samethread_excl_shared);
+
+ ok(!srwlock_base_errors.samethread_shared_excl,
+ "AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred %d times).\n",
+ srwlock_base_errors.samethread_shared_excl);
+
+ ok(!srwlock_base_errors.multithread_excl_excl,
+ "AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred %d times).\n",
+ srwlock_base_errors.multithread_excl_excl);
+
+ ok(!srwlock_base_errors.excl_not_preferred,
+ "thread waiting for exclusive access to the SHMLock was not preferred (occurred %d times).\n",
+ srwlock_base_errors.excl_not_preferred);
+
+ ok(!srwlock_base_errors.trylock_excl,
+ "TryAcquireSRWLockExclusive didn't behave as expected (occurred %d times).\n",
+ srwlock_base_errors.trylock_excl);
+
+ ok(!srwlock_base_errors.trylock_shared,
+ "TryAcquireSRWLockShared didn't behave as expected (occurred %d times).\n",
+ srwlock_base_errors.trylock_shared);
+
+}
+
+static SRWLOCK srwlock_example;
+static LONG srwlock_protected_value = 0;
+static LONG srwlock_example_errors = 0, srwlock_inside = 0, srwlock_cnt = 0;
+static BOOL srwlock_stop = FALSE;
+
+static DWORD WINAPI srwlock_example_thread(LPVOID x) {
+ DWORD *cnt = x;
+ LONG old;
+
+ while (!srwlock_stop)
+ {
+
+ /* periodically request exclusive access */
+ if (InterlockedIncrement(&srwlock_cnt) % 13 == 0)
+ {
+ pAcquireSRWLockExclusive(&srwlock_example);
+ if (InterlockedIncrement(&srwlock_inside) != 1)
+ InterlockedIncrement(&srwlock_example_errors);
+
+ InterlockedIncrement(&srwlock_protected_value);
+ Sleep(1);
+
+ if (InterlockedDecrement(&srwlock_inside) != 0)
+ InterlockedIncrement(&srwlock_example_errors);
+ pReleaseSRWLockExclusive(&srwlock_example);
+ }
+
+ /* request shared access */
+ pAcquireSRWLockShared(&srwlock_example);
+ InterlockedIncrement(&srwlock_inside);
+ old = srwlock_protected_value;
+
+ (*cnt)++;
+ Sleep(1);
+
+ if (old != srwlock_protected_value)
+ InterlockedIncrement(&srwlock_example_errors);
+ InterlockedDecrement(&srwlock_inside);
+ pReleaseSRWLockShared(&srwlock_example);
+ }
+
+ return 0;
+}
+
+static void test_srwlock_example(void)
+{
+ HANDLE h1, h2, h3;
+ DWORD dummy;
+ DWORD cnt1, cnt2, cnt3;
+
+ if (!pInitializeSRWLock) {
+ /* function is not yet in XP, only in newer Windows */
+ win_skip("no srw lock support.\n");
+ return;
+ }
+
+ pInitializeSRWLock(&srwlock_example);
+
+ cnt1 = cnt2 = cnt3 = 0;
+
+ h1 = CreateThread(NULL, 0, srwlock_example_thread, &cnt1, 0, &dummy);
+ h2 = CreateThread(NULL, 0, srwlock_example_thread, &cnt2, 0, &dummy);
+ h3 = CreateThread(NULL, 0, srwlock_example_thread, &cnt3, 0, &dummy);
+
+ /* limit run to 1 second. */
+ Sleep(1000);
+
+ /* tear down start */
+ srwlock_stop = TRUE;
+
+ WaitForSingleObject(h1, 1000);
+ WaitForSingleObject(h2, 1000);
+ WaitForSingleObject(h3, 1000);
+
+ ok(!srwlock_inside, "threads didn't terminate properly, srwlock_inside is %d.\n", srwlock_inside);
+ ok(!srwlock_example_errors, "errors occurred while running SRWLock example test (number of errors: %d)\n",
+ srwlock_example_errors);
+
+ trace("number of shared accesses per thread are c1 %d, c2 %d, c3 %d\n", cnt1, cnt2, cnt3);
+ trace("number of total exclusive accesses is %d\n", srwlock_protected_value);
+}
START_TEST(sync)
{
- HMODULE hdll = GetModuleHandle("kernel32");
+ HMODULE hdll = GetModuleHandleA("kernel32.dll");
pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer");
pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue");
pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer");
pInitOnceComplete = (void *)GetProcAddress(hdll, "InitOnceComplete");
pInitializeConditionVariable = (void *)GetProcAddress(hdll, "InitializeConditionVariable");
pSleepConditionVariableCS = (void *)GetProcAddress(hdll, "SleepConditionVariableCS");
+ pSleepConditionVariableSRW = (void *)GetProcAddress(hdll, "SleepConditionVariableSRW");
pWakeAllConditionVariable = (void *)GetProcAddress(hdll, "WakeAllConditionVariable");
pWakeConditionVariable = (void *)GetProcAddress(hdll, "WakeConditionVariable");
+ pInitializeSRWLock = (void *)GetProcAddress(hdll, "InitializeSRWLock");
+ pAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "AcquireSRWLockExclusive");
+ pAcquireSRWLockShared = (void *)GetProcAddress(hdll, "AcquireSRWLockShared");
+ pReleaseSRWLockExclusive = (void *)GetProcAddress(hdll, "ReleaseSRWLockExclusive");
+ pReleaseSRWLockShared = (void *)GetProcAddress(hdll, "ReleaseSRWLockShared");
+ pTryAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "TryAcquireSRWLockExclusive");
+ pTryAcquireSRWLockShared = (void *)GetProcAddress(hdll, "TryAcquireSRWLockShared");
test_signalandwait();
test_mutex();
test_initonce();
test_condvars_base();
test_condvars_consumer_producer();
+ test_srwlock_base();
+ test_srwlock_example();
}
#include "wine/test.h"
extern void func_actctx(void);
-extern void func_alloc(void);
extern void func_atom(void);
extern void func_change(void);
extern void func_codepage(void);
const struct test winetest_testlist[] =
{
{ "actctx", func_actctx },
- { "alloc", func_alloc },
{ "atom", func_atom },
{ "change", func_change },
{ "codepage", func_codepage },
*/
/* Define _WIN32_WINNT to get SetThreadIdealProcessor on Windows */
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x0600
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
-#include "wine/test.h"
+#include <wine/test.h>
+
#include <windef.h>
#include <winbase.h>
#include <winnt.h>
#include <winerror.h>
+#include <winnls.h>
+
+/* 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
# 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);
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)
{
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());
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;
}
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 */
}
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);
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) {
"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) {
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");
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");
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");
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)
/* QueueUserWorkItem not present on win9x */
if (!pQueueUserWorkItem) return;
- finish_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ finish_event = CreateEventW(NULL, TRUE, FALSE, NULL);
before = GetTickCount();
/* 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());
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);
}
#endif
+static const char manifest_dep[] =
+"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
+"<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
+" <file name=\"testdep.dll\" />"
+"</assembly>";
+
+static const char manifest_main[] =
+"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
+"<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
+"<dependency>"
+" <dependentAssembly>"
+" <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
+" </dependentAssembly>"
+"</dependency>"
+"</assembly>";
+
+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)
return;
}
+ test_reserved_tls();
test_CreateRemoteThread();
test_CreateThread_basic();
test_CreateThread_suspended();
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
test_thread_fpu_cw();
#endif
+ test_thread_actctx();
+
+ test_threadpool();
}
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");
{
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;
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 */
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)
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 ));
}
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 ));
}
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);
/* Needed for PRODUCT_* defines and GetProductInfo() */
#define _WIN32_WINNT 0x0600
-#include <assert.h>
-
#include "wine/test.h"
#include "winbase.h"
static void test_VerifyVersionInfo(void)
{
- OSVERSIONINFOEX info;
+ OSVERSIONINFOEXA info;
BOOL ret;
DWORD servicepack, error;
/* 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));
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,
}
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,
/* 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,
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,
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,
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,
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));
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());
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 );
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 );
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 );
"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 );
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() );
}
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 );
}
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);
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)
{
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);
CloseHandle(hmap);
CloseHandle(hfile);
- DeleteFile(file_name);
+ DeleteFileA(file_name);
}
#define ACCESS_READ 0x01
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);
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)
{
/* 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);
}
CloseHandle(hfile);
- DeleteFile(file_name);
+ DeleteFileA(file_name);
}
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());
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);
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();
}
/* 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);
"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);
}
/* 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,
"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])) {
/* 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 */
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, */
"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 */
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 */
}
/*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];
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);
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);
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);
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);
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';
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)