mirror of
https://github.com/reactos/reactos.git
synced 2025-04-30 02:58:48 +00:00
[KERNEL32_WINETEST] Sync everything except file.c and virtual.c with Wine Staging 3.3. CORE-14434
This commit is contained in:
parent
4b456ff7cd
commit
ed41a4dee2
33 changed files with 2320 additions and 1062 deletions
|
@ -10,7 +10,6 @@ list(APPEND SOURCE
|
|||
codepage.c
|
||||
comm.c
|
||||
console.c
|
||||
cpu.c
|
||||
debugger.c
|
||||
directory.c
|
||||
drive.c
|
||||
|
|
|
@ -16,11 +16,18 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "wine/test.h"
|
||||
#include <winbase.h>
|
||||
#include <windef.h>
|
||||
#include <winnt.h>
|
||||
#include <winternl.h>
|
||||
#include <winnls.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <objbase.h>
|
||||
#include <oaidl.h>
|
||||
#include <initguid.h>
|
||||
#include "oaidl.h"
|
||||
#include "initguid.h"
|
||||
|
||||
static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
|
||||
static HANDLE (WINAPI *pCreateActCtxA)(PCACTCTXA);
|
||||
|
@ -419,9 +426,9 @@ static const char compat_manifest_vista_7_8_10_81[] =
|
|||
" <assemblyIdentity version=\"1.0.0.0\" name=\"Wine.Test\" type=\"win32\"></assemblyIdentity>"
|
||||
" <compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">"
|
||||
" <application>"
|
||||
" <supportedOS Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\" />" /* Windows Vista */
|
||||
" <supportedOS Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\" ></supportedOS>" /* Windows Vista */
|
||||
" <supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\" />" /* Windows 7 */
|
||||
" <supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\" />" /* Windows 8 */
|
||||
" <supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\" ></supportedOS>" /* Windows 8 */
|
||||
" <supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\" />" /* Windows 10 */
|
||||
" <supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\" />" /* Windows 8.1 */
|
||||
" </application>"
|
||||
|
@ -2323,7 +2330,7 @@ static HANDLE create_manifest(const char *filename, const char *data, int line)
|
|||
return handle;
|
||||
}
|
||||
|
||||
static void kernel32_find(ULONG section, const char *string_to_find, BOOL should_find, BOOL todo, int line)
|
||||
static void kernel32_find(ULONG section, const char *string_to_find, BOOL should_find, int line)
|
||||
{
|
||||
UNICODE_STRING string_to_findW;
|
||||
ACTCTX_SECTION_KEYED_DATA data;
|
||||
|
@ -2340,7 +2347,6 @@ static void kernel32_find(ULONG section, const char *string_to_find, BOOL should
|
|||
err = GetLastError();
|
||||
ok_(__FILE__, line)(ret == should_find,
|
||||
"FindActCtxSectionStringA: expected ret = %u, got %u\n", should_find, ret);
|
||||
todo_wine_if(todo)
|
||||
ok_(__FILE__, line)(err == (should_find ? ERROR_SUCCESS : ERROR_SXS_KEY_NOT_FOUND),
|
||||
"FindActCtxSectionStringA: unexpected error %u\n", err);
|
||||
|
||||
|
@ -2352,7 +2358,6 @@ static void kernel32_find(ULONG section, const char *string_to_find, BOOL should
|
|||
err = GetLastError();
|
||||
ok_(__FILE__, line)(ret == should_find,
|
||||
"FindActCtxSectionStringW: expected ret = %u, got %u\n", should_find, ret);
|
||||
todo_wine_if(todo)
|
||||
ok_(__FILE__, line)(err == (should_find ? ERROR_SUCCESS : ERROR_SXS_KEY_NOT_FOUND),
|
||||
"FindActCtxSectionStringW: unexpected error %u\n", err);
|
||||
|
||||
|
@ -2375,7 +2380,7 @@ static void kernel32_find(ULONG section, const char *string_to_find, BOOL should
|
|||
pRtlFreeUnicodeString(&string_to_findW);
|
||||
}
|
||||
|
||||
static void ntdll_find(ULONG section, const char *string_to_find, BOOL should_find, BOOL todo, int line)
|
||||
static void ntdll_find(ULONG section, const char *string_to_find, BOOL should_find, int line)
|
||||
{
|
||||
UNICODE_STRING string_to_findW;
|
||||
ACTCTX_SECTION_KEYED_DATA data;
|
||||
|
@ -2387,12 +2392,10 @@ static void ntdll_find(ULONG section, const char *string_to_find, BOOL should_fi
|
|||
data.cbSize = sizeof(data);
|
||||
|
||||
ret = pRtlFindActivationContextSectionString(0, NULL, section, &string_to_findW, &data);
|
||||
todo_wine_if(todo)
|
||||
ok_(__FILE__, line)(ret == (should_find ? STATUS_SUCCESS : STATUS_SXS_KEY_NOT_FOUND),
|
||||
"RtlFindActivationContextSectionString: unexpected status 0x%x\n", ret);
|
||||
|
||||
ret = pRtlFindActivationContextSectionString(0, NULL, section, &string_to_findW, NULL);
|
||||
todo_wine_if(todo)
|
||||
ok_(__FILE__, line)(ret == (should_find ? STATUS_SUCCESS : STATUS_SXS_KEY_NOT_FOUND),
|
||||
"RtlFindActivationContextSectionString: unexpected status 0x%x\n", ret);
|
||||
|
||||
|
@ -2410,22 +2413,22 @@ static void test_findsectionstring(void)
|
|||
ok(ret, "ActivateActCtx failed: %u\n", GetLastError());
|
||||
|
||||
/* first we show the parameter validation from kernel32 */
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "testdep", FALSE, TRUE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib.dll", TRUE, FALSE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib2.dll", TRUE, FALSE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib3.dll", FALSE, FALSE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass", TRUE, FALSE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass2", TRUE, FALSE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass3", FALSE, FALSE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "testdep", FALSE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib.dll", TRUE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib2.dll", TRUE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib3.dll", FALSE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass", TRUE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass2", TRUE, __LINE__);
|
||||
kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass3", FALSE, __LINE__);
|
||||
|
||||
/* then we show that ntdll plays by different rules */
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "testdep", FALSE, TRUE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib.dll", TRUE, FALSE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib2.dll", TRUE, FALSE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib3.dll", FALSE, FALSE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass", TRUE, FALSE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass2", TRUE, FALSE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass3", FALSE, FALSE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "testdep", FALSE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib.dll", TRUE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib2.dll", TRUE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib3.dll", FALSE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass", TRUE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass2", TRUE, __LINE__);
|
||||
ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass3", FALSE, __LINE__);
|
||||
|
||||
ret = pDeactivateActCtx(0, cookie);
|
||||
ok(ret, "DeactivateActCtx failed: %u\n", GetLastError());
|
||||
|
|
|
@ -18,7 +18,14 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winuser.h"
|
||||
|
||||
#define DOUBLE(x) (WCHAR)((x<<8)|(x))
|
||||
|
||||
|
|
|
@ -26,7 +26,15 @@
|
|||
* FILE_NOTIFY_CHANGE_CREATION
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "wine/test.h"
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winternl.h>
|
||||
|
||||
static DWORD CALLBACK NotificationThread(LPVOID arg)
|
||||
{
|
||||
|
@ -375,6 +383,7 @@ static void test_readdirectorychanges(void)
|
|||
static const WCHAR szHoo[] = { '\\','h','o','o',0 };
|
||||
static const WCHAR szGa[] = { '\\','h','o','o','\\','g','a',0 };
|
||||
PFILE_NOTIFY_INFORMATION pfni;
|
||||
BOOL got_subdir_change = FALSE;
|
||||
|
||||
if (!pReadDirectoryChangesW)
|
||||
{
|
||||
|
@ -542,26 +551,40 @@ static void test_readdirectorychanges(void)
|
|||
r = CreateDirectoryW( subsubdir, NULL );
|
||||
ok( r == TRUE, "failed to create directory\n");
|
||||
|
||||
r = WaitForSingleObject( ov.hEvent, 1000 );
|
||||
ok( r == WAIT_OBJECT_0, "should be ready\n" );
|
||||
|
||||
ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
|
||||
ok( ov.InternalHigh == 0x18 || ov.InternalHigh == 0x12 + 0x18,
|
||||
"ov.InternalHigh wrong %lx\n", ov.InternalHigh);
|
||||
|
||||
pfni = (PFILE_NOTIFY_INFORMATION) buffer;
|
||||
if (pfni->NextEntryOffset) /* we may get a modified event on the parent dir */
|
||||
while (1)
|
||||
{
|
||||
ok( pfni->NextEntryOffset == 0x12, "offset wrong %x\n", pfni->NextEntryOffset );
|
||||
ok( pfni->Action == FILE_ACTION_MODIFIED, "action wrong %d\n", pfni->Action );
|
||||
ok( pfni->FileNameLength == 3*sizeof(WCHAR), "len wrong\n" );
|
||||
ok( !memcmp(pfni->FileName,&szGa[1],3*sizeof(WCHAR)), "name wrong\n");
|
||||
pfni = (PFILE_NOTIFY_INFORMATION)((char *)pfni + pfni->NextEntryOffset);
|
||||
r = WaitForSingleObject( ov.hEvent, 1000 );
|
||||
ok(r == WAIT_OBJECT_0, "should be ready\n" );
|
||||
if (r == WAIT_TIMEOUT) break;
|
||||
|
||||
ok((NTSTATUS) ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
|
||||
|
||||
pfni = (PFILE_NOTIFY_INFORMATION) buffer;
|
||||
while (1)
|
||||
{
|
||||
/* We might get one or more modified events on the parent dir */
|
||||
if (pfni->Action == FILE_ACTION_MODIFIED)
|
||||
{
|
||||
ok(pfni->FileNameLength == 3 * sizeof(WCHAR), "len wrong\n" );
|
||||
ok(!memcmp(pfni->FileName, &szGa[1], 3 * sizeof(WCHAR)), "name wrong\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(pfni->Action == FILE_ACTION_ADDED, "action wrong\n");
|
||||
ok(pfni->FileNameLength == 6 * sizeof(WCHAR), "len wrong\n" );
|
||||
ok(!memcmp(pfni->FileName, &szGa[1], 6 * sizeof(WCHAR)), "name wrong\n");
|
||||
got_subdir_change = TRUE;
|
||||
}
|
||||
if (!pfni->NextEntryOffset) break;
|
||||
pfni = (PFILE_NOTIFY_INFORMATION)((char *)pfni + pfni->NextEntryOffset);
|
||||
}
|
||||
|
||||
if (got_subdir_change) break;
|
||||
|
||||
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
|
||||
ok(r==TRUE, "should return true\n");
|
||||
}
|
||||
ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
|
||||
ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
|
||||
ok( pfni->FileNameLength == 6*sizeof(WCHAR), "len wrong\n" );
|
||||
ok( !memcmp(pfni->FileName,&szGa[1],6*sizeof(WCHAR)), "name wrong\n" );
|
||||
ok(got_subdir_change, "didn't get subdir change\n");
|
||||
|
||||
r = RemoveDirectoryW( subsubdir );
|
||||
ok( r == TRUE, "failed to remove directory\n");
|
||||
|
|
|
@ -19,7 +19,14 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
|
||||
static const char foobarA[] = "foobar";
|
||||
static const WCHAR foobarW[] = {'f','o','o','b','a','r',0};
|
||||
|
|
|
@ -18,7 +18,14 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "wine/test.h"
|
||||
#include "winternl.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
|
||||
#define TIMEOUT 1000 /* one second for Timeouts*/
|
||||
#define SLOWBAUD 150
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include "wine/test.h"
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static BOOL (WINAPI *pGetConsoleInputExeNameA)(DWORD, LPSTR);
|
||||
static DWORD (WINAPI *pGetConsoleProcessList)(LPDWORD, DWORD);
|
||||
|
@ -2580,6 +2582,11 @@ static void test_ReadConsole(void)
|
|||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetFileSize(std_input, NULL);
|
||||
if (GetLastError() == 0xdeadbeef)
|
||||
{
|
||||
skip("stdin is redirected\n");
|
||||
return;
|
||||
}
|
||||
ok(ret == INVALID_FILE_SIZE, "expected INVALID_FILE_SIZE, got %#x\n", ret);
|
||||
ok(GetLastError() == ERROR_INVALID_HANDLE ||
|
||||
GetLastError() == ERROR_INVALID_FUNCTION, /* Win 8, 10 */
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Unit test suite for cpu functions
|
||||
*
|
||||
* Copyright 2014 Michael Müller
|
||||
*
|
||||
* 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 "precomp.h"
|
||||
|
||||
static BOOL (WINAPI *pGetNumaProcessorNode)(UCHAR, PUCHAR);
|
||||
|
||||
static void InitFunctionPointers(void)
|
||||
{
|
||||
HMODULE hkernel32 = GetModuleHandleA("kernel32");
|
||||
|
||||
pGetNumaProcessorNode = (void *)GetProcAddress(hkernel32, "GetNumaProcessorNode");
|
||||
}
|
||||
|
||||
static void test_GetNumaProcessorNode(void)
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
UCHAR node;
|
||||
BOOL ret;
|
||||
int i;
|
||||
|
||||
if (!pGetNumaProcessorNode)
|
||||
{
|
||||
win_skip("GetNumaProcessorNode() is missing\n");
|
||||
return;
|
||||
}
|
||||
|
||||
GetSystemInfo(&si);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
ret = pGetNumaProcessorNode(i, &node);
|
||||
if (i < si.dwNumberOfProcessors)
|
||||
{
|
||||
ok(ret, "expected TRUE, got FALSE for processor %d\n", i);
|
||||
ok(node != 0xFF, "expected node != 0xFF, but got 0xFF\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(!ret, "expected FALSE, got TRUE for processor %d\n", i);
|
||||
ok(node == 0xFF, "expected node == 0xFF, but got %x\n", node);
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
/* crashes on windows */
|
||||
if (0)
|
||||
{
|
||||
ok(!pGetNumaProcessorNode(0, NULL), "expected return value FALSE, got TRUE\n");
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(cpu)
|
||||
{
|
||||
InitFunctionPointers();
|
||||
test_GetNumaProcessorNode();
|
||||
}
|
|
@ -18,7 +18,13 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <winreg.h>
|
||||
#include "wine/test.h"
|
||||
|
||||
#ifndef STATUS_DEBUGGER_INACTIVE
|
||||
#define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354)
|
||||
|
|
|
@ -18,7 +18,13 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winternl.h"
|
||||
|
||||
static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
|
||||
|
||||
|
|
|
@ -18,7 +18,12 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
static DWORD (WINAPI *pGetDiskFreeSpaceExA)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
|
||||
|
||||
|
|
|
@ -18,7 +18,13 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
|
||||
static CHAR string[MAX_PATH];
|
||||
#define ok_w(res, format, szString) \
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include "wine/test.h"
|
||||
|
||||
static LPVOID (WINAPI *pCreateFiber)(SIZE_T,LPFIBER_START_ROUTINE,LPVOID);
|
||||
static LPVOID (WINAPI *pConvertThreadToFiber)(LPVOID);
|
||||
|
|
|
@ -17,11 +17,16 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
|
||||
#define ULL(a,b) (((ULONG64)(a) << 32) | (b))
|
||||
|
||||
static DWORD __cdecl doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
|
||||
static DWORD WINAPIV doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
|
||||
LPSTR out, DWORD outsize, ... )
|
||||
{
|
||||
__ms_va_list list;
|
||||
|
@ -34,7 +39,7 @@ static DWORD __cdecl doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
|
|||
return r;
|
||||
}
|
||||
|
||||
static DWORD __cdecl doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
|
||||
static DWORD WINAPIV doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
|
||||
LPWSTR out, DWORD outsize, ... )
|
||||
{
|
||||
__ms_va_list list;
|
||||
|
@ -1554,6 +1559,10 @@ static void test_message_from_hmodule(void)
|
|||
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
|
||||
ok(ret != 0, "FormatMessageA returned 0\n");
|
||||
|
||||
ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, TRUST_E_NOSIGNATURE,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
|
||||
ok(ret != 0, "FormatMessageA returned 0\n");
|
||||
|
||||
/* Test a message string with an insertion without passing any variadic arguments. */
|
||||
ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 193 /* ERROR_BAD_EXE_FORMAT */,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
|
||||
|
|
|
@ -20,7 +20,15 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/test.h"
|
||||
|
||||
#define MAGIC_DEAD 0xdeadbeef
|
||||
|
||||
|
@ -200,7 +208,7 @@ static void test_heap(void)
|
|||
((GetLastError() == ERROR_NOT_LOCKED) || (GetLastError() == MAGIC_DEAD)),
|
||||
"returned %d with %d (expected '0' with: ERROR_NOT_LOCKED or "
|
||||
"MAGIC_DEAD)\n", res, GetLastError());
|
||||
|
||||
|
||||
GlobalFree(gbl);
|
||||
/* invalid handles are caught in windows: */
|
||||
SetLastError(MAGIC_DEAD);
|
||||
|
@ -209,6 +217,18 @@ static void test_heap(void)
|
|||
"returned %p with 0x%08x (expected %p with ERROR_INVALID_HANDLE)\n",
|
||||
hsecond, GetLastError(), gbl);
|
||||
SetLastError(MAGIC_DEAD);
|
||||
hsecond = GlobalFree(LongToHandle(0xdeadbeef)); /* bogus handle */
|
||||
ok( (hsecond == LongToHandle(0xdeadbeef)) && (GetLastError() == ERROR_INVALID_HANDLE),
|
||||
"returned %p with 0x%08x (expected %p with ERROR_INVALID_HANDLE)\n",
|
||||
hsecond, GetLastError(), LongToHandle(0xdeadbeef));
|
||||
SetLastError(MAGIC_DEAD);
|
||||
hsecond = GlobalFree(LongToHandle(0xdeadbee0)); /* bogus pointer */
|
||||
ok( (hsecond == LongToHandle(0xdeadbee0)) &&
|
||||
((GetLastError() == ERROR_INVALID_HANDLE) || broken(GetLastError() == ERROR_NOACCESS) /* wvista+ */),
|
||||
"returned %p with 0x%08x (expected %p with ERROR_NOACCESS)\n",
|
||||
hsecond, GetLastError(), LongToHandle(0xdeadbee0));
|
||||
|
||||
SetLastError(MAGIC_DEAD);
|
||||
flags = GlobalFlags(gbl);
|
||||
ok( (flags == GMEM_INVALID_HANDLE) && (GetLastError() == ERROR_INVALID_HANDLE),
|
||||
"returned 0x%04x with 0x%08x (expected GMEM_INVALID_HANDLE with "
|
||||
|
@ -242,7 +262,7 @@ static void test_heap(void)
|
|||
ok(mem == NULL, "Expected NULL, got %p\n", mem);
|
||||
|
||||
/* invalid free */
|
||||
if (sizeof(void *) != 8) /* crashes on 64-bit Vista */
|
||||
if (sizeof(void *) != 8) /* crashes on 64-bit */
|
||||
{
|
||||
SetLastError(MAGIC_DEAD);
|
||||
mem = GlobalFree(gbl);
|
||||
|
@ -560,7 +580,7 @@ static void test_HeapCreate(void)
|
|||
ok(HeapFree(heap,0,mem3),"HeapFree didn't pass successfully\n");
|
||||
}
|
||||
|
||||
/* Check that HeapRealloc works */
|
||||
/* Check that HeapReAlloc works */
|
||||
mem2a=HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
|
||||
ok(mem2a!=NULL,"HeapReAlloc failed\n");
|
||||
if(mem2a) {
|
||||
|
@ -574,7 +594,7 @@ static void test_HeapCreate(void)
|
|||
ok(!error,"HeapReAlloc should have zeroed out its allocated memory\n");
|
||||
}
|
||||
|
||||
/* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */
|
||||
/* 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) {
|
||||
|
|
|
@ -18,9 +18,20 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <delayloadhandler.h>
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winternl.h"
|
||||
#include "winuser.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)
|
||||
|
@ -40,10 +51,12 @@ struct PROCESS_BASIC_INFORMATION_PRIVATE
|
|||
static LONG *child_failures;
|
||||
static WORD cb_count;
|
||||
static DWORD page_size;
|
||||
static BOOL is_win64 = sizeof(void *) > sizeof(int);
|
||||
static BOOL is_wow64;
|
||||
|
||||
static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *,
|
||||
const LARGE_INTEGER *, ULONG, ULONG, HANDLE );
|
||||
static NTSTATUS (WINAPI *pNtQuerySection)(HANDLE, SECTION_INFORMATION_CLASS, void *, ULONG, ULONG *);
|
||||
static NTSTATUS (WINAPI *pNtQuerySection)(HANDLE, SECTION_INFORMATION_CLASS, void *, SIZE_T, SIZE_T *);
|
||||
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);
|
||||
|
@ -65,6 +78,7 @@ static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
|
|||
static BOOL (WINAPI *pFlsSetValue)(DWORD, PVOID);
|
||||
static PVOID (WINAPI *pFlsGetValue)(DWORD);
|
||||
static BOOL (WINAPI *pFlsFree)(DWORD);
|
||||
static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
|
||||
|
||||
static PVOID RVAToAddr(DWORD_PTR rva, HMODULE module)
|
||||
{
|
||||
|
@ -154,13 +168,18 @@ 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 )
|
||||
const IMAGE_NT_HEADERS *nt_header, char dll_name[MAX_PATH] )
|
||||
{
|
||||
char temp_path[MAX_PATH];
|
||||
DWORD dummy, size, file_align;
|
||||
HANDLE hfile;
|
||||
BOOL ret;
|
||||
|
||||
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, "failed to create %s err %u\n", dll_name, GetLastError() );
|
||||
if (hfile == INVALID_HANDLE_VALUE) return 0;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
|
@ -233,17 +252,64 @@ static DWORD create_test_dll( const IMAGE_DOS_HEADER *dos_header, UINT dos_size,
|
|||
return size;
|
||||
}
|
||||
|
||||
static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HEADERS *nt_header )
|
||||
static DWORD create_test_dll_sections( const IMAGE_DOS_HEADER *dos_header, const IMAGE_NT_HEADERS *nt_header,
|
||||
const IMAGE_SECTION_HEADER *sections, const void *section_data,
|
||||
char dll_name[MAX_PATH] )
|
||||
{
|
||||
char temp_path[MAX_PATH];
|
||||
DWORD dummy, i, size;
|
||||
HANDLE hfile;
|
||||
BOOL ret;
|
||||
|
||||
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, "failed to create %s err %u\n", dll_name, GetLastError() );
|
||||
if (hfile == INVALID_HANDLE_VALUE) return 0;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = WriteFile(hfile, dos_header, sizeof(*dos_header), &dummy, NULL);
|
||||
ok(ret, "WriteFile error %d\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = WriteFile(hfile, nt_header, offsetof(IMAGE_NT_HEADERS, OptionalHeader) + nt_header->FileHeader.SizeOfOptionalHeader, &dummy, NULL);
|
||||
ok(ret, "WriteFile error %d\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = WriteFile(hfile, sections, sizeof(*sections) * nt_header->FileHeader.NumberOfSections,
|
||||
&dummy, NULL);
|
||||
ok(ret, "WriteFile error %d\n", GetLastError());
|
||||
|
||||
for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
SetFilePointer(hfile, sections[i].PointerToRawData, NULL, FILE_BEGIN);
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = WriteFile(hfile, section_data, sections[i].SizeOfRawData, &dummy, NULL);
|
||||
ok(ret, "WriteFile error %d\n", GetLastError());
|
||||
}
|
||||
size = GetFileSize(hfile, NULL);
|
||||
CloseHandle(hfile);
|
||||
return size;
|
||||
}
|
||||
|
||||
static BOOL query_image_section( int id, const char *dll_name, const IMAGE_NT_HEADERS *nt_header,
|
||||
const void *section_data )
|
||||
{
|
||||
static BOOL is_winxp;
|
||||
SECTION_BASIC_INFORMATION info;
|
||||
SECTION_IMAGE_INFORMATION image;
|
||||
ULONG info_size = 0xdeadbeef;
|
||||
const IMAGE_COR20_HEADER *cor_header = NULL;
|
||||
SIZE_T info_size = (SIZE_T)0xdeadbeef << 16;
|
||||
NTSTATUS status;
|
||||
HANDLE file, mapping;
|
||||
ULONG file_size;
|
||||
LARGE_INTEGER map_size;
|
||||
SIZE_T max_stack, commit_stack;
|
||||
void *entry_point;
|
||||
|
||||
/* truncated header is not handled correctly in windows <= w2k3 */
|
||||
BOOL truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(nt_header->OptionalHeader);
|
||||
BOOL truncated;
|
||||
|
||||
file = CreateFileA( dll_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE,
|
||||
NULL, OPEN_EXISTING, 0, 0 );
|
||||
|
@ -256,22 +322,56 @@ static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HE
|
|||
if (status)
|
||||
{
|
||||
CloseHandle( file );
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
status = pNtQuerySection( mapping, SectionImageInformation, &image, sizeof(image), &info_size );
|
||||
ok( !status, "%u: NtQuerySection failed err %x\n", id, status );
|
||||
ok( info_size == sizeof(image), "%u: NtQuerySection wrong size %u\n", id, info_size );
|
||||
ok( (char *)image.TransferAddress == (char *)nt_header->OptionalHeader.ImageBase + nt_header->OptionalHeader.AddressOfEntryPoint,
|
||||
"%u: TransferAddress wrong %p / %p+%08x\n", id,
|
||||
image.TransferAddress, (char *)nt_header->OptionalHeader.ImageBase,
|
||||
nt_header->OptionalHeader.AddressOfEntryPoint );
|
||||
ok( info_size == sizeof(image), "%u: NtQuerySection wrong size %lu\n", id, info_size );
|
||||
if (nt_header->OptionalHeader.Magic == (is_win64 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC
|
||||
: IMAGE_NT_OPTIONAL_HDR32_MAGIC))
|
||||
{
|
||||
max_stack = nt_header->OptionalHeader.SizeOfStackReserve;
|
||||
commit_stack = nt_header->OptionalHeader.SizeOfStackCommit;
|
||||
entry_point = (char *)nt_header->OptionalHeader.ImageBase + nt_header->OptionalHeader.AddressOfEntryPoint;
|
||||
truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER);
|
||||
if (!truncated &&
|
||||
nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress &&
|
||||
nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size)
|
||||
cor_header = section_data;
|
||||
}
|
||||
else if (nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
|
||||
{
|
||||
const IMAGE_NT_HEADERS64 *nt64 = (const IMAGE_NT_HEADERS64 *)nt_header;
|
||||
max_stack = 0x100000;
|
||||
commit_stack = 0x10000;
|
||||
entry_point = (void *)0x81231234;
|
||||
truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER64);
|
||||
if (!truncated &&
|
||||
nt64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress &&
|
||||
nt64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size)
|
||||
cor_header = section_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
const IMAGE_NT_HEADERS32 *nt32 = (const IMAGE_NT_HEADERS32 *)nt_header;
|
||||
max_stack = nt32->OptionalHeader.SizeOfStackReserve;
|
||||
commit_stack = nt32->OptionalHeader.SizeOfStackCommit;
|
||||
entry_point = (char *)(ULONG_PTR)nt32->OptionalHeader.ImageBase + nt32->OptionalHeader.AddressOfEntryPoint;
|
||||
truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER32);
|
||||
if (!truncated &&
|
||||
nt32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress &&
|
||||
nt32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size)
|
||||
cor_header = section_data;
|
||||
}
|
||||
ok( (char *)image.TransferAddress == (char *)entry_point ||
|
||||
(S(U(image)).ImageDynamicallyRelocated && LOWORD(image.TransferAddress) == LOWORD(entry_point)),
|
||||
"%u: TransferAddress wrong %p / %p (%08x)\n", id,
|
||||
image.TransferAddress, entry_point, nt_header->OptionalHeader.AddressOfEntryPoint );
|
||||
ok( image.ZeroBits == 0, "%u: ZeroBits wrong %08x\n", id, image.ZeroBits );
|
||||
ok( image.MaximumStackSize == nt_header->OptionalHeader.SizeOfStackReserve || broken(truncated),
|
||||
"%u: MaximumStackSize wrong %lx / %lx\n", id,
|
||||
image.MaximumStackSize, (SIZE_T)nt_header->OptionalHeader.SizeOfStackReserve );
|
||||
ok( image.CommittedStackSize == nt_header->OptionalHeader.SizeOfStackCommit || broken(truncated),
|
||||
"%u: CommittedStackSize wrong %lx / %lx\n", id,
|
||||
image.CommittedStackSize, (SIZE_T)nt_header->OptionalHeader.SizeOfStackCommit );
|
||||
ok( image.MaximumStackSize == max_stack || broken(truncated),
|
||||
"%u: MaximumStackSize wrong %lx / %lx\n", id, image.MaximumStackSize, max_stack );
|
||||
ok( image.CommittedStackSize == commit_stack || broken(truncated),
|
||||
"%u: CommittedStackSize wrong %lx / %lx\n", id, image.CommittedStackSize, commit_stack );
|
||||
if (truncated)
|
||||
ok( !image.SubSystemType || broken(truncated),
|
||||
"%u: SubSystemType wrong %08x / 00000000\n", id, image.SubSystemType );
|
||||
|
@ -293,18 +393,66 @@ static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HE
|
|||
image.DllCharacteristics, nt_header->OptionalHeader.DllCharacteristics );
|
||||
ok( image.Machine == nt_header->FileHeader.Machine, "%u: Machine wrong %04x / %04x\n", id,
|
||||
image.Machine, nt_header->FileHeader.Machine );
|
||||
ok( image.LoaderFlags == nt_header->OptionalHeader.LoaderFlags,
|
||||
"%u: LoaderFlags wrong %08x / %08x\n", id,
|
||||
image.LoaderFlags, nt_header->OptionalHeader.LoaderFlags );
|
||||
ok( image.LoaderFlags == (cor_header != NULL), "%u: LoaderFlags wrong %08x\n", id, image.LoaderFlags );
|
||||
ok( image.ImageFileSize == file_size || broken(!image.ImageFileSize), /* winxpsp1 */
|
||||
"%u: ImageFileSize wrong %08x / %08x\n", id, image.ImageFileSize, file_size );
|
||||
ok( image.CheckSum == nt_header->OptionalHeader.CheckSum || broken(truncated),
|
||||
"%u: CheckSum wrong %08x / %08x\n", id,
|
||||
image.CheckSum, nt_header->OptionalHeader.CheckSum );
|
||||
|
||||
if (nt_header->OptionalHeader.SizeOfCode || nt_header->OptionalHeader.AddressOfEntryPoint)
|
||||
ok( image.ImageContainsCode == TRUE, "%u: ImageContainsCode wrong %u\n", id,
|
||||
image.ImageContainsCode );
|
||||
else if ((nt_header->OptionalHeader.SectionAlignment % page_size) ||
|
||||
(nt_header->FileHeader.NumberOfSections == 1 &&
|
||||
(section.Characteristics & IMAGE_SCN_MEM_EXECUTE)))
|
||||
ok( image.ImageContainsCode == TRUE || broken(!image.ImageContainsCode), /* <= win8 */
|
||||
"%u: ImageContainsCode wrong %u\n", id, image.ImageContainsCode );
|
||||
else
|
||||
ok( !image.ImageContainsCode, "%u: ImageContainsCode wrong %u\n", id, image.ImageContainsCode );
|
||||
|
||||
if (cor_header &&
|
||||
(cor_header->Flags & COMIMAGE_FLAGS_ILONLY) &&
|
||||
(cor_header->MajorRuntimeVersion > 2 ||
|
||||
(cor_header->MajorRuntimeVersion == 2 && cor_header->MinorRuntimeVersion >= 5)))
|
||||
{
|
||||
ok( S(U(image)).ComPlusILOnly || broken(is_winxp),
|
||||
"%u: wrong ComPlusILOnly flags %02x\n", id, U(image).ImageFlags );
|
||||
if (nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
|
||||
!(cor_header->Flags & COMIMAGE_FLAGS_32BITREQUIRED))
|
||||
ok( S(U(image)).ComPlusNativeReady || broken(is_winxp),
|
||||
"%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags );
|
||||
else
|
||||
ok( !S(U(image)).ComPlusNativeReady,
|
||||
"%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags );
|
||||
}
|
||||
else
|
||||
{
|
||||
ok( !S(U(image)).ComPlusILOnly, "%u: wrong ComPlusILOnly flags %02x\n", id, U(image).ImageFlags );
|
||||
ok( !S(U(image)).ComPlusNativeReady, "%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags );
|
||||
}
|
||||
if (!(nt_header->OptionalHeader.SectionAlignment % page_size))
|
||||
ok( !S(U(image)).ImageMappedFlat, "%u: wrong ImageMappedFlat flags %02x\n", id, U(image).ImageFlags );
|
||||
else
|
||||
{
|
||||
/* winxp doesn't support any of the loader flags */
|
||||
if (!S(U(image)).ImageMappedFlat) is_winxp = TRUE;
|
||||
ok( S(U(image)).ImageMappedFlat || broken(is_winxp),
|
||||
"%u: wrong ImageMappedFlat flags %02x\n", id, U(image).ImageFlags );
|
||||
}
|
||||
if (!(nt_header->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE))
|
||||
ok( !S(U(image)).ImageDynamicallyRelocated || broken( S(U(image)).ComPlusILOnly ), /* <= win7 */
|
||||
"%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags );
|
||||
else if (image.ImageContainsCode && !cor_header)
|
||||
ok( S(U(image)).ImageDynamicallyRelocated || broken(is_winxp),
|
||||
"%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags );
|
||||
else
|
||||
ok( !S(U(image)).ImageDynamicallyRelocated || broken(TRUE), /* <= win8 */
|
||||
"%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags );
|
||||
ok( !S(U(image)).BaseBelow4gb, "%u: wrong BaseBelow4gb flags %02x\n", id, U(image).ImageFlags );
|
||||
|
||||
/* FIXME: needs more work: */
|
||||
/* image.GpValue */
|
||||
/* image.ImageFlags */
|
||||
/* image.ImageContainsCode */
|
||||
|
||||
map_size.QuadPart = (nt_header->OptionalHeader.SizeOfImage + page_size - 1) & ~(page_size - 1);
|
||||
status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
|
||||
|
@ -345,23 +493,22 @@ static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HE
|
|||
CloseHandle( mapping );
|
||||
|
||||
CloseHandle( file );
|
||||
return image.ImageContainsCode && (!cor_header || !(cor_header->Flags & COMIMAGE_FLAGS_ILONLY));
|
||||
}
|
||||
|
||||
/* helper to test image section mapping */
|
||||
static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header )
|
||||
static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header, const IMAGE_SECTION_HEADER *sections,
|
||||
const void *section_data, int line )
|
||||
{
|
||||
char temp_path[MAX_PATH];
|
||||
char dll_name[MAX_PATH];
|
||||
LARGE_INTEGER size;
|
||||
HANDLE file, map;
|
||||
NTSTATUS status;
|
||||
ULONG file_size;
|
||||
BOOL has_code;
|
||||
HMODULE mod;
|
||||
|
||||
GetTempPathA(MAX_PATH, temp_path);
|
||||
GetTempFileNameA(temp_path, "ldr", 0, dll_name);
|
||||
|
||||
file_size = create_test_dll( &dos_header, sizeof(dos_header), nt_header, dll_name );
|
||||
ok( file_size, "could not create %s\n", dll_name);
|
||||
file_size = create_test_dll_sections( &dos_header, nt_header, sections, section_data, dll_name );
|
||||
|
||||
file = CreateFileA(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||||
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
|
@ -372,15 +519,39 @@ static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header )
|
|||
if (!status)
|
||||
{
|
||||
SECTION_BASIC_INFORMATION info;
|
||||
ULONG info_size = 0xdeadbeef;
|
||||
SIZE_T info_size = 0xdeadbeef;
|
||||
NTSTATUS ret = pNtQuerySection( map, SectionBasicInformation, &info, sizeof(info), &info_size );
|
||||
ok( !ret, "NtQuerySection failed err %x\n", ret );
|
||||
ok( info_size == sizeof(info), "NtQuerySection wrong size %u\n", info_size );
|
||||
ok( info_size == sizeof(info), "NtQuerySection wrong size %lu\n", info_size );
|
||||
ok( info.Attributes == (SEC_IMAGE | SEC_FILE), "NtQuerySection wrong attr %x\n", info.Attributes );
|
||||
ok( info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", info.BaseAddress );
|
||||
ok( info.Size.QuadPart == file_size, "NtQuerySection wrong size %x%08x / %08x\n",
|
||||
info.Size.u.HighPart, info.Size.u.LowPart, file_size );
|
||||
query_image_section( 1000, dll_name, nt_header );
|
||||
has_code = query_image_section( line, dll_name, nt_header, section_data );
|
||||
/* test loading dll of wrong 32/64 bitness */
|
||||
if (nt_header->OptionalHeader.Magic == (is_win64 ? IMAGE_NT_OPTIONAL_HDR32_MAGIC
|
||||
: IMAGE_NT_OPTIONAL_HDR64_MAGIC))
|
||||
{
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = LoadLibraryExA( dll_name, 0, DONT_RESOLVE_DLL_REFERENCES );
|
||||
if (!has_code && nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
{
|
||||
BOOL il_only = FALSE;
|
||||
if (((const IMAGE_NT_HEADERS32 *)nt_header)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
|
||||
{
|
||||
const IMAGE_COR20_HEADER *cor_header = section_data;
|
||||
il_only = (cor_header->Flags & COMIMAGE_FLAGS_ILONLY) != 0;
|
||||
}
|
||||
ok( mod != NULL || broken(il_only), /* <= win7 */
|
||||
"%u: loading failed err %u\n", line, GetLastError() );
|
||||
}
|
||||
else
|
||||
{
|
||||
ok( !mod, "%u: loading succeeded\n", line );
|
||||
ok( GetLastError() == ERROR_BAD_EXE_FORMAT, "%u: wrong error %u\n", line, GetLastError() );
|
||||
}
|
||||
if (mod) FreeLibrary( mod );
|
||||
}
|
||||
}
|
||||
if (map) CloseHandle( map );
|
||||
CloseHandle( file );
|
||||
|
@ -540,23 +711,19 @@ static void test_Loader(void)
|
|||
DWORD file_size;
|
||||
HANDLE h;
|
||||
HMODULE hlib, hlib_as_data_file;
|
||||
char temp_path[MAX_PATH];
|
||||
char dll_name[MAX_PATH];
|
||||
SIZE_T size;
|
||||
BOOL ret;
|
||||
NTSTATUS status;
|
||||
WORD orig_machine = nt_header_template.FileHeader.Machine;
|
||||
WORD alt_machine, orig_machine = nt_header_template.FileHeader.Machine;
|
||||
IMAGE_NT_HEADERS nt_header;
|
||||
IMAGE_COR20_HEADER cor_header;
|
||||
|
||||
/* prevent displaying of the "Unable to load this DLL" message box */
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
|
||||
GetTempPathA(MAX_PATH, temp_path);
|
||||
|
||||
for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
|
||||
{
|
||||
GetTempFileNameA(temp_path, "ldr", 0, dll_name);
|
||||
|
||||
nt_header = nt_header_template;
|
||||
nt_header.FileHeader.NumberOfSections = td[i].number_of_sections;
|
||||
nt_header.FileHeader.SizeOfOptionalHeader = td[i].size_of_optional_header;
|
||||
|
@ -567,11 +734,6 @@ static void test_Loader(void)
|
|||
nt_header.OptionalHeader.SizeOfHeaders = td[i].size_of_headers;
|
||||
|
||||
file_size = create_test_dll( &dos_header, td[i].size_of_dos_header, &nt_header, dll_name );
|
||||
if (!file_size)
|
||||
{
|
||||
ok(0, "could not create %s\n", dll_name);
|
||||
break;
|
||||
}
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hlib = LoadLibraryA(dll_name);
|
||||
|
@ -601,8 +763,6 @@ static void test_Loader(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ptr = VirtualAlloc(hlib, page_size, MEM_COMMIT, info.Protect);
|
||||
ok(!ptr, "%d: VirtualAlloc should fail\n", i);
|
||||
/* FIXME: Remove once Wine is fixed */
|
||||
todo_wine_if (info.Protect == PAGE_WRITECOPY || info.Protect == PAGE_EXECUTE_WRITECOPY)
|
||||
ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
|
@ -687,8 +847,6 @@ static void test_Loader(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
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 */
|
||||
todo_wine_if (info.Protect == PAGE_WRITECOPY || info.Protect == PAGE_EXECUTE_WRITECOPY)
|
||||
ok(GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == ERROR_INVALID_ADDRESS,
|
||||
"%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
|
||||
}
|
||||
|
@ -716,7 +874,7 @@ static void test_Loader(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
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");
|
||||
ok(((ULONG_PTR)hlib_as_data_file & 3) == 1, "hlib_as_data_file got %p\n", hlib_as_data_file);
|
||||
|
||||
hlib = GetModuleHandleA(dll_name);
|
||||
ok(!hlib, "GetModuleHandle should fail\n");
|
||||
|
@ -732,7 +890,7 @@ static void test_Loader(void)
|
|||
|
||||
SetLastError(0xdeadbeef);
|
||||
hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);
|
||||
if (!((ULONG_PTR)hlib_as_data_file & 1) || /* winxp */
|
||||
if (!((ULONG_PTR)hlib_as_data_file & 3) || /* winxp */
|
||||
(!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER)) /* w2k3 */
|
||||
{
|
||||
win_skip( "LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE not supported\n" );
|
||||
|
@ -744,10 +902,37 @@ static void test_Loader(void)
|
|||
|
||||
SetLastError(0xdeadbeef);
|
||||
h = CreateFileA( dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
|
||||
todo_wine ok( h == INVALID_HANDLE_VALUE, "open succeeded\n" );
|
||||
todo_wine ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error %u\n", GetLastError() );
|
||||
ok( h == INVALID_HANDLE_VALUE, "open succeeded\n" );
|
||||
ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error %u\n", GetLastError() );
|
||||
CloseHandle( h );
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
h = CreateFileA( dll_name, GENERIC_READ | DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
|
||||
ok( h != INVALID_HANDLE_VALUE, "open failed err %u\n", GetLastError() );
|
||||
CloseHandle( h );
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = FreeLibrary(hlib_as_data_file);
|
||||
ok(ret, "FreeLibrary error %d\n", GetLastError());
|
||||
}
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE);
|
||||
if (!((ULONG_PTR)hlib_as_data_file & 3) || /* winxp */
|
||||
(!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER)) /* w2k3 */
|
||||
{
|
||||
win_skip( "LOAD_LIBRARY_AS_IMAGE_RESOURCE not supported\n" );
|
||||
FreeLibrary(hlib_as_data_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(hlib_as_data_file != 0, "LoadLibraryEx error %u\n", GetLastError());
|
||||
ok(((ULONG_PTR)hlib_as_data_file & 3) == 2, "hlib_as_data_file got %p\n",
|
||||
hlib_as_data_file);
|
||||
|
||||
hlib = GetModuleHandleA(dll_name);
|
||||
ok(!hlib, "GetModuleHandle should fail\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = FreeLibrary(hlib_as_data_file);
|
||||
ok(ret, "FreeLibrary error %d\n", GetLastError());
|
||||
|
@ -764,7 +949,8 @@ static void test_Loader(void)
|
|||
ok(0, "could not create %s\n", dll_name);
|
||||
break;
|
||||
}
|
||||
query_image_section( i, dll_name, &nt_header );
|
||||
|
||||
query_image_section( i, dll_name, &nt_header, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -797,49 +983,118 @@ static void test_Loader(void)
|
|||
nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER);
|
||||
nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + page_size;
|
||||
|
||||
status = map_image_section( &nt_header );
|
||||
section.SizeOfRawData = sizeof(section_data);
|
||||
section.PointerToRawData = page_size;
|
||||
section.VirtualAddress = page_size;
|
||||
section.Misc.VirtualSize = page_size;
|
||||
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.OptionalHeader.SizeOfCode = 0x1000;
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
nt_header.OptionalHeader.SizeOfCode = 0;
|
||||
nt_header.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
|
||||
|
||||
dos_header.e_magic = 0;
|
||||
status = map_image_section( &nt_header );
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
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 );
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_INVALID_IMAGE_NE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.Signature = 0xdeadbeef;
|
||||
status = map_image_section( &nt_header );
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
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 );
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
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 );
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
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 );
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
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;
|
||||
case IMAGE_FILE_MACHINE_I386: alt_machine = IMAGE_FILE_MACHINE_ARMNT; break;
|
||||
case IMAGE_FILE_MACHINE_AMD64: alt_machine = IMAGE_FILE_MACHINE_ARM64; break;
|
||||
case IMAGE_FILE_MACHINE_ARMNT: alt_machine = IMAGE_FILE_MACHINE_I386; break;
|
||||
case IMAGE_FILE_MACHINE_ARM64: alt_machine = IMAGE_FILE_MACHINE_AMD64; break;
|
||||
}
|
||||
status = map_image_section( &nt_header );
|
||||
nt_header.FileHeader.Machine = alt_machine;
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
switch (orig_machine)
|
||||
{
|
||||
case IMAGE_FILE_MACHINE_I386: alt_machine = IMAGE_FILE_MACHINE_AMD64; break;
|
||||
case IMAGE_FILE_MACHINE_AMD64: alt_machine = IMAGE_FILE_MACHINE_I386; break;
|
||||
case IMAGE_FILE_MACHINE_ARMNT: alt_machine = IMAGE_FILE_MACHINE_ARM64; break;
|
||||
case IMAGE_FILE_MACHINE_ARM64: alt_machine = IMAGE_FILE_MACHINE_ARMNT; break;
|
||||
}
|
||||
nt_header.FileHeader.Machine = alt_machine;
|
||||
status = map_image_section( &nt_header, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.FileHeader.Machine = orig_machine;
|
||||
nt_header.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
|
||||
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = page_size;
|
||||
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = sizeof(cor_header);
|
||||
section.SizeOfRawData = sizeof(cor_header);
|
||||
|
||||
memset( &cor_header, 0, sizeof(cor_header) );
|
||||
cor_header.cb = sizeof(cor_header);
|
||||
cor_header.MajorRuntimeVersion = 2;
|
||||
cor_header.MinorRuntimeVersion = 4;
|
||||
cor_header.Flags = COMIMAGE_FLAGS_ILONLY;
|
||||
U(cor_header).EntryPointToken = 0xbeef;
|
||||
status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.MinorRuntimeVersion = 5;
|
||||
status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.MajorRuntimeVersion = 3;
|
||||
cor_header.MinorRuntimeVersion = 0;
|
||||
status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITREQUIRED;
|
||||
status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITPREFERRED;
|
||||
status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.Flags = 0;
|
||||
status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = 1;
|
||||
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = 1;
|
||||
status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
if (nt_header.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
{
|
||||
IMAGE_NT_HEADERS64 nt64;
|
||||
|
@ -849,17 +1104,111 @@ static void test_Loader(void)
|
|||
nt64.FileHeader.Machine = orig_machine;
|
||||
nt64.FileHeader.NumberOfSections = 1;
|
||||
nt64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64);
|
||||
nt64.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL;
|
||||
nt64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
||||
nt64.OptionalHeader.MajorLinkerVersion = 1;
|
||||
nt64.OptionalHeader.SizeOfCode = 0x1000;
|
||||
nt64.OptionalHeader.AddressOfEntryPoint = 0x1000;
|
||||
nt64.OptionalHeader.ImageBase = 0x10000000;
|
||||
nt64.OptionalHeader.SectionAlignment = 0x1000;
|
||||
nt64.OptionalHeader.FileAlignment = 0x1000;
|
||||
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 );
|
||||
nt64.OptionalHeader.SizeOfStackReserve = 0x321000;
|
||||
nt64.OptionalHeader.SizeOfStackCommit = 0x123000;
|
||||
section.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
|
||||
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_INVALID_IMAGE_FORMAT : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
switch (orig_machine)
|
||||
{
|
||||
case IMAGE_FILE_MACHINE_I386: nt64.FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64; break;
|
||||
case IMAGE_FILE_MACHINE_ARMNT: nt64.FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64; break;
|
||||
}
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_INVALID_IMAGE_FORMAT : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt64.FileHeader.Machine = alt_machine;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt64.OptionalHeader.SizeOfCode = 0;
|
||||
nt64.OptionalHeader.AddressOfEntryPoint = 0x1000;
|
||||
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt64.OptionalHeader.SizeOfCode = 0;
|
||||
nt64.OptionalHeader.AddressOfEntryPoint = 0;
|
||||
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt64.OptionalHeader.SizeOfCode = 0x1000;
|
||||
nt64.OptionalHeader.AddressOfEntryPoint = 0;
|
||||
nt64.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
|
||||
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt64.OptionalHeader.SizeOfCode = 0;
|
||||
nt64.OptionalHeader.AddressOfEntryPoint = 0;
|
||||
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt64.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
|
||||
nt64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = page_size;
|
||||
nt64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = sizeof(cor_header);
|
||||
cor_header.MajorRuntimeVersion = 2;
|
||||
cor_header.MinorRuntimeVersion = 4;
|
||||
cor_header.Flags = COMIMAGE_FLAGS_ILONLY;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt64.OptionalHeader.SizeOfCode = 0x1000;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.MinorRuntimeVersion = 5;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITREQUIRED;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITPREFERRED;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.Flags = 0;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = 1;
|
||||
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = 1;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ );
|
||||
ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64),
|
||||
"NtCreateSection error %08x\n", status );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -870,20 +1219,180 @@ static void test_Loader(void)
|
|||
nt32.FileHeader.Machine = orig_machine;
|
||||
nt32.FileHeader.NumberOfSections = 1;
|
||||
nt32.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32);
|
||||
nt32.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL;
|
||||
nt32.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
|
||||
nt32.OptionalHeader.MajorLinkerVersion = 1;
|
||||
nt32.OptionalHeader.SizeOfCode = 0x1000;
|
||||
nt32.OptionalHeader.AddressOfEntryPoint = 0x1000;
|
||||
nt32.OptionalHeader.ImageBase = 0x10000000;
|
||||
nt32.OptionalHeader.SectionAlignment = 0x1000;
|
||||
nt32.OptionalHeader.FileAlignment = 0x1000;
|
||||
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 );
|
||||
nt32.OptionalHeader.SizeOfStackReserve = 0x321000;
|
||||
nt32.OptionalHeader.SizeOfStackCommit = 0x123000;
|
||||
section.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
|
||||
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status );
|
||||
|
||||
switch (orig_machine)
|
||||
{
|
||||
case IMAGE_FILE_MACHINE_AMD64: nt32.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT; break;
|
||||
case IMAGE_FILE_MACHINE_ARM64: nt32.FileHeader.Machine = IMAGE_FILE_MACHINE_I386; break;
|
||||
}
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(!status) /* win8 */,
|
||||
"NtCreateSection error %08x\n", status );
|
||||
|
||||
nt32.FileHeader.Machine = alt_machine;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt32.OptionalHeader.SizeOfCode = 0;
|
||||
nt32.OptionalHeader.AddressOfEntryPoint = 0x1000;
|
||||
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt32.OptionalHeader.SizeOfCode = 0;
|
||||
nt32.OptionalHeader.AddressOfEntryPoint = 0;
|
||||
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt32.OptionalHeader.SizeOfCode = 0x1000;
|
||||
nt32.OptionalHeader.AddressOfEntryPoint = 0;
|
||||
nt32.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
|
||||
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt32.OptionalHeader.SizeOfCode = 0;
|
||||
nt32.OptionalHeader.AddressOfEntryPoint = 0;
|
||||
section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt32.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
|
||||
nt32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = page_size;
|
||||
nt32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = sizeof(cor_header);
|
||||
cor_header.MajorRuntimeVersion = 2;
|
||||
cor_header.MinorRuntimeVersion = 4;
|
||||
cor_header.Flags = COMIMAGE_FLAGS_ILONLY;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt32.OptionalHeader.SizeOfCode = 0x1000;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.MinorRuntimeVersion = 5;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITREQUIRED;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITPREFERRED;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
cor_header.Flags = 0;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
|
||||
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = 1;
|
||||
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = 1;
|
||||
status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ );
|
||||
ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status );
|
||||
}
|
||||
|
||||
nt_header.FileHeader.Machine = orig_machine; /* restore it for the next tests */
|
||||
section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
|
||||
}
|
||||
|
||||
static void test_filenames(void)
|
||||
{
|
||||
IMAGE_NT_HEADERS nt_header = nt_header_template;
|
||||
char dll_name[MAX_PATH], long_path[MAX_PATH], short_path[MAX_PATH], buffer[MAX_PATH];
|
||||
HMODULE mod, mod2;
|
||||
BOOL ret;
|
||||
|
||||
nt_header.FileHeader.NumberOfSections = 1;
|
||||
nt_header.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
|
||||
|
||||
nt_header.OptionalHeader.SectionAlignment = page_size;
|
||||
nt_header.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
|
||||
nt_header.OptionalHeader.FileAlignment = page_size;
|
||||
nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER);
|
||||
nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + page_size;
|
||||
|
||||
create_test_dll( &dos_header, sizeof(dos_header), &nt_header, dll_name );
|
||||
strcpy( long_path, dll_name );
|
||||
strcpy( strrchr( long_path, '\\' ), "\\this-is-a-long-name.dll" );
|
||||
ret = MoveFileA( dll_name, long_path );
|
||||
ok( ret, "MoveFileA failed err %u\n", GetLastError() );
|
||||
GetShortPathNameA( long_path, short_path, MAX_PATH );
|
||||
|
||||
mod = LoadLibraryA( short_path );
|
||||
ok( mod != NULL, "loading failed err %u\n", GetLastError() );
|
||||
GetModuleFileNameA( mod, buffer, MAX_PATH );
|
||||
ok( !lstrcmpiA( buffer, short_path ), "got wrong path %s / %s\n", buffer, short_path );
|
||||
mod2 = GetModuleHandleA( short_path );
|
||||
ok( mod == mod2, "wrong module %p for %s\n", mod2, short_path );
|
||||
mod2 = GetModuleHandleA( long_path );
|
||||
ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path );
|
||||
mod2 = LoadLibraryA( long_path );
|
||||
ok( mod2 != NULL, "loading failed err %u\n", GetLastError() );
|
||||
ok( mod == mod2, "library loaded twice\n" );
|
||||
GetModuleFileNameA( mod2, buffer, MAX_PATH );
|
||||
ok( !lstrcmpiA( buffer, short_path ), "got wrong path %s / %s\n", buffer, short_path );
|
||||
FreeLibrary( mod2 );
|
||||
FreeLibrary( mod );
|
||||
|
||||
mod = LoadLibraryA( long_path );
|
||||
ok( mod != NULL, "loading failed err %u\n", GetLastError() );
|
||||
GetModuleFileNameA( mod, buffer, MAX_PATH );
|
||||
ok( !lstrcmpiA( buffer, long_path ), "got wrong path %s / %s\n", buffer, long_path );
|
||||
mod2 = GetModuleHandleA( short_path );
|
||||
ok( mod == mod2, "wrong module %p for %s\n", mod2, short_path );
|
||||
mod2 = GetModuleHandleA( long_path );
|
||||
ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path );
|
||||
mod2 = LoadLibraryA( short_path );
|
||||
ok( mod2 != NULL, "loading failed err %u\n", GetLastError() );
|
||||
ok( mod == mod2, "library loaded twice\n" );
|
||||
GetModuleFileNameA( mod2, buffer, MAX_PATH );
|
||||
ok( !lstrcmpiA( buffer, long_path ), "got wrong path %s / %s\n", buffer, long_path );
|
||||
FreeLibrary( mod2 );
|
||||
FreeLibrary( mod );
|
||||
|
||||
strcpy( dll_name, long_path );
|
||||
strcpy( strrchr( dll_name, '\\' ), "\\this-is-another-name.dll" );
|
||||
ret = CreateHardLinkA( dll_name, long_path, NULL );
|
||||
ok( ret, "CreateHardLinkA failed err %u\n", GetLastError() );
|
||||
if (ret)
|
||||
{
|
||||
mod = LoadLibraryA( dll_name );
|
||||
ok( mod != NULL, "loading failed err %u\n", GetLastError() );
|
||||
GetModuleFileNameA( mod, buffer, MAX_PATH );
|
||||
ok( !lstrcmpiA( buffer, dll_name ), "got wrong path %s / %s\n", buffer, dll_name );
|
||||
mod2 = GetModuleHandleA( long_path );
|
||||
ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path );
|
||||
mod2 = LoadLibraryA( long_path );
|
||||
ok( mod2 != NULL, "loading failed err %u\n", GetLastError() );
|
||||
ok( mod == mod2, "library loaded twice\n" );
|
||||
GetModuleFileNameA( mod2, buffer, MAX_PATH );
|
||||
ok( !lstrcmpiA( buffer, dll_name ), "got wrong path %s / %s\n", buffer, short_path );
|
||||
FreeLibrary( mod2 );
|
||||
FreeLibrary( mod );
|
||||
DeleteFileA( dll_name );
|
||||
}
|
||||
DeleteFileA( long_path );
|
||||
}
|
||||
|
||||
static void test_FakeDLL(void)
|
||||
|
@ -1536,7 +2045,7 @@ static void test_import_resolution(void)
|
|||
nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = DATA_RVA(&data.tls);
|
||||
|
||||
memset( &data, 0, sizeof(data) );
|
||||
data.descr[0].OriginalFirstThunk = DATA_RVA( data.original_thunks );
|
||||
U(data.descr[0]).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" );
|
||||
|
@ -1647,7 +2156,7 @@ static DWORD WINAPI mutex_thread_proc(void *param)
|
|||
wait_list[2] = peb_lock_event;
|
||||
wait_list[3] = heap_lock_event;
|
||||
|
||||
trace("%04u: mutex_thread_proc: starting\n", GetCurrentThreadId());
|
||||
trace("%04x: mutex_thread_proc: starting\n", GetCurrentThreadId());
|
||||
while (1)
|
||||
{
|
||||
ret = WaitForMultipleObjects(sizeof(wait_list)/sizeof(wait_list[0]), wait_list, FALSE, 50);
|
||||
|
@ -1655,7 +2164,7 @@ static DWORD WINAPI mutex_thread_proc(void *param)
|
|||
else if (ret == WAIT_OBJECT_0 + 1)
|
||||
{
|
||||
ULONG_PTR loader_lock_magic;
|
||||
trace("%04u: mutex_thread_proc: Entering loader lock\n", GetCurrentThreadId());
|
||||
trace("%04x: mutex_thread_proc: Entering loader lock\n", GetCurrentThreadId());
|
||||
ret = pLdrLockLoaderLock(0, NULL, &loader_lock_magic);
|
||||
ok(!ret, "LdrLockLoaderLock error %#x\n", ret);
|
||||
inside_loader_lock++;
|
||||
|
@ -1663,21 +2172,21 @@ static DWORD WINAPI mutex_thread_proc(void *param)
|
|||
}
|
||||
else if (ret == WAIT_OBJECT_0 + 2)
|
||||
{
|
||||
trace("%04u: mutex_thread_proc: Entering PEB lock\n", GetCurrentThreadId());
|
||||
trace("%04x: mutex_thread_proc: Entering PEB lock\n", GetCurrentThreadId());
|
||||
pRtlAcquirePebLock();
|
||||
inside_peb_lock++;
|
||||
SetEvent(ack_event);
|
||||
}
|
||||
else if (ret == WAIT_OBJECT_0 + 3)
|
||||
{
|
||||
trace("%04u: mutex_thread_proc: Entering heap lock\n", GetCurrentThreadId());
|
||||
trace("%04x: mutex_thread_proc: Entering heap lock\n", GetCurrentThreadId());
|
||||
HeapLock(GetProcessHeap());
|
||||
inside_heap_lock++;
|
||||
SetEvent(ack_event);
|
||||
}
|
||||
}
|
||||
|
||||
trace("%04u: mutex_thread_proc: exiting\n", GetCurrentThreadId());
|
||||
trace("%04x: mutex_thread_proc: exiting\n", GetCurrentThreadId());
|
||||
return 196;
|
||||
}
|
||||
|
||||
|
@ -1693,11 +2202,11 @@ static DWORD WINAPI semaphore_thread_proc(void *param)
|
|||
while (1)
|
||||
{
|
||||
if (winetest_debug > 1)
|
||||
trace("%04u: semaphore_thread_proc: still alive\n", GetCurrentThreadId());
|
||||
trace("%04x: semaphore_thread_proc: still alive\n", GetCurrentThreadId());
|
||||
if (WaitForSingleObject(stop_event, 50) != WAIT_TIMEOUT) break;
|
||||
}
|
||||
|
||||
trace("%04u: semaphore_thread_proc: exiting\n", GetCurrentThreadId());
|
||||
trace("%04x: semaphore_thread_proc: exiting\n", GetCurrentThreadId());
|
||||
return 196;
|
||||
}
|
||||
|
||||
|
@ -1709,7 +2218,7 @@ static DWORD WINAPI noop_thread_proc(void *param)
|
|||
InterlockedIncrement(noop_thread_started);
|
||||
}
|
||||
|
||||
trace("%04u: noop_thread_proc: exiting\n", GetCurrentThreadId());
|
||||
trace("%04x: noop_thread_proc: exiting\n", GetCurrentThreadId());
|
||||
return 195;
|
||||
}
|
||||
|
||||
|
@ -2273,7 +2782,6 @@ static void child_process(const char *dll_name, DWORD target_offset)
|
|||
case 3:
|
||||
trace("signalling thread exit\n");
|
||||
SetEvent(stop_event);
|
||||
CloseHandle(stop_event);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
@ -3262,8 +3770,10 @@ START_TEST(loader)
|
|||
pFlsSetValue = (void *)GetProcAddress(kernel32, "FlsSetValue");
|
||||
pFlsGetValue = (void *)GetProcAddress(kernel32, "FlsGetValue");
|
||||
pFlsFree = (void *)GetProcAddress(kernel32, "FlsFree");
|
||||
pIsWow64Process = (void *)GetProcAddress(kernel32, "IsWow64Process");
|
||||
pResolveDelayLoadedAPI = (void *)GetProcAddress(kernel32, "ResolveDelayLoadedAPI");
|
||||
|
||||
if (pIsWow64Process) pIsWow64Process( GetCurrentProcess(), &is_wow64 );
|
||||
GetSystemInfo( &si );
|
||||
page_size = si.dwPageSize;
|
||||
dos_header.e_magic = IMAGE_DOS_SIGNATURE;
|
||||
|
@ -3289,6 +3799,7 @@ START_TEST(loader)
|
|||
|
||||
test_Loader();
|
||||
test_FakeDLL();
|
||||
test_filenames();
|
||||
test_ResolveDelayLoadedAPI();
|
||||
test_ImportDescriptors();
|
||||
test_section_access();
|
||||
|
|
|
@ -25,7 +25,16 @@
|
|||
* the control panel i8n page), we will still get the expected results.
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
|
||||
static const WCHAR upper_case[] = {'\t','J','U','S','T','!',' ','A',',',' ','T','E','S','T',';',' ','S','T','R','I','N','G',' ','1','/','*','+','-','.','\r','\n',0};
|
||||
static const WCHAR lower_case[] = {'\t','j','u','s','t','!',' ','a',',',' ','t','e','s','t',';',' ','s','t','r','i','n','g',' ','1','/','*','+','-','.','\r','\n',0};
|
||||
|
@ -2471,7 +2480,7 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
|
|||
ok(ret == ret2, "%s ret %d, expected value %d\n", func_name, ret2, ret);
|
||||
|
||||
/* test LCMAP_FULLWIDTH | LCMAP_HIRAGANA
|
||||
(half-width katakana is converted into full-wdith hiragana) */
|
||||
(half-width katakana is converted into full-width hiragana) */
|
||||
ret = func_ptr(LCMAP_FULLWIDTH | LCMAP_HIRAGANA,
|
||||
halfwidth_text, -1, buf, sizeof(buf)/sizeof(WCHAR));
|
||||
ok(ret == lstrlenW(hiragana_text) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
|
||||
|
@ -2770,42 +2779,51 @@ static void test_LocaleNameToLCID(void)
|
|||
ptr++;
|
||||
}
|
||||
|
||||
/* zh-Hant */
|
||||
/* zh-Hant has LCID 0x7c04, but LocaleNameToLCID actually returns 0x0c04, which is the LCID of zh-HK */
|
||||
lcid = pLocaleNameToLCID(zhHantW, 0);
|
||||
todo_wine ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT),
|
||||
ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT),
|
||||
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhHantW), lcid);
|
||||
ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0);
|
||||
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHantW), ret);
|
||||
todo_wine ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n",
|
||||
ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n",
|
||||
wine_dbgstr_w(zhHantW), wine_dbgstr_w(buffer));
|
||||
/* check that 0x7c04 also works and is mapped to zh-HK */
|
||||
ret = pLCIDToLocaleName(MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_CHINESE_TRADITIONAL), buffer, sizeof(buffer)/sizeof(WCHAR), 0);
|
||||
todo_wine ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHantW), ret);
|
||||
ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n",
|
||||
wine_dbgstr_w(zhHantW), wine_dbgstr_w(buffer));
|
||||
|
||||
/* zh-hant */
|
||||
lcid = pLocaleNameToLCID(zhhantW, 0);
|
||||
todo_wine ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT),
|
||||
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhantW),
|
||||
MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT));
|
||||
ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT),
|
||||
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhantW), lcid);
|
||||
ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0);
|
||||
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhhantW), ret);
|
||||
todo_wine ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n",
|
||||
ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n",
|
||||
wine_dbgstr_w(zhhantW), wine_dbgstr_w(buffer));
|
||||
|
||||
/* zh-Hans */
|
||||
/* zh-Hans has LCID 0x0004, but LocaleNameToLCID actually returns 0x0804, which is the LCID of zh-CN */
|
||||
lcid = pLocaleNameToLCID(zhHansW, 0);
|
||||
todo_wine ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT),
|
||||
/* check that LocaleNameToLCID actually returns 0x0804 */
|
||||
ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT),
|
||||
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhHansW), lcid);
|
||||
ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0);
|
||||
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHansW), ret);
|
||||
todo_wine ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n",
|
||||
ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n",
|
||||
wine_dbgstr_w(zhHansW), wine_dbgstr_w(buffer));
|
||||
/* check that 0x0004 also works and is mapped to zh-CN */
|
||||
ret = pLCIDToLocaleName(MAKELANGID(LANG_CHINESE, SUBLANG_NEUTRAL), buffer, sizeof(buffer)/sizeof(WCHAR), 0);
|
||||
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHansW), ret);
|
||||
ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n",
|
||||
wine_dbgstr_w(zhHansW), wine_dbgstr_w(buffer));
|
||||
|
||||
/* zh-hans */
|
||||
lcid = pLocaleNameToLCID(zhhansW, 0);
|
||||
todo_wine ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT),
|
||||
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhansW),
|
||||
MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT));
|
||||
ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT),
|
||||
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhansW), lcid);
|
||||
ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0);
|
||||
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhhansW), ret);
|
||||
todo_wine ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n",
|
||||
ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n",
|
||||
wine_dbgstr_w(zhhansW), wine_dbgstr_w(buffer));
|
||||
}
|
||||
}
|
||||
|
@ -4465,6 +4483,14 @@ static void test_GetLocaleInfoEx(void)
|
|||
ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret);
|
||||
ok(!lstrcmpW(bufferW, enuW), "got %s\n", wine_dbgstr_w(bufferW));
|
||||
|
||||
ret = pGetLocaleInfoEx(enusW, LOCALE_SPARENT, bufferW, sizeof(bufferW)/sizeof(WCHAR));
|
||||
ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret);
|
||||
ok(!lstrcmpW(bufferW, enW), "got %s\n", wine_dbgstr_w(bufferW));
|
||||
|
||||
ret = pGetLocaleInfoEx(enW, LOCALE_SPARENT, bufferW, sizeof(bufferW)/sizeof(WCHAR));
|
||||
ok(ret == 1, "got %d\n", ret);
|
||||
ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW));
|
||||
|
||||
ret = pGetLocaleInfoEx(enW, LOCALE_SCOUNTRY, bufferW, sizeof(bufferW)/sizeof(WCHAR));
|
||||
ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret);
|
||||
if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) ||
|
||||
|
|
|
@ -18,7 +18,14 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
static const char szmspath[] = "\\\\.\\mailslot\\wine_mailslot_test";
|
||||
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <psapi.h>
|
||||
|
||||
static DWORD (WINAPI *pGetDllDirectoryA)(DWORD,LPSTR);
|
||||
|
@ -28,8 +29,6 @@ static BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR);
|
|||
static DLL_DIRECTORY_COOKIE (WINAPI *pAddDllDirectory)(const WCHAR*);
|
||||
static BOOL (WINAPI *pRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
|
||||
static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD);
|
||||
static BOOL (WINAPI *pGetModuleHandleExA)(DWORD,LPCSTR,HMODULE*);
|
||||
static BOOL (WINAPI *pGetModuleHandleExW)(DWORD,LPCWSTR,HMODULE*);
|
||||
static BOOL (WINAPI *pK32GetModuleInformation)(HANDLE process, HMODULE module,
|
||||
MODULEINFO *modinfo, DWORD cb);
|
||||
|
||||
|
@ -179,8 +178,7 @@ static void testGetModuleFileName(const char* name)
|
|||
ok(len1W / 2 == len2W, "Correct length in GetModuleFilenameW with buffer too small (%d/%d)\n", len1W / 2, len2W);
|
||||
}
|
||||
|
||||
ok(len1A / 2 == len2A ||
|
||||
len1A / 2 == len2A + 1, /* Win9x */
|
||||
ok(len1A / 2 == len2A,
|
||||
"Correct length in GetModuleFilenameA with buffer too small (%d/%d)\n", len1A / 2, len2A);
|
||||
}
|
||||
|
||||
|
@ -199,9 +197,7 @@ static void testGetModuleFileName_Wrong(void)
|
|||
|
||||
bufA[0] = '*';
|
||||
ok(GetModuleFileNameA((void*)0xffffffff, bufA, sizeof(bufA)) == 0, "Unexpected success in module handle\n");
|
||||
ok(bufA[0] == '*' ||
|
||||
bufA[0] == 0 /* Win9x */,
|
||||
"When failing, buffer shouldn't be written to\n");
|
||||
ok(bufA[0] == '*', "When failing, buffer shouldn't be written to\n");
|
||||
}
|
||||
|
||||
static void testLoadLibraryA(void)
|
||||
|
@ -220,14 +216,10 @@ static void testLoadLibraryA(void)
|
|||
|
||||
SetLastError(0xdeadbeef);
|
||||
hModule1 = LoadLibraryA("kernel32 ");
|
||||
/* Only winNT does this */
|
||||
if (GetLastError() != ERROR_DLL_NOT_FOUND)
|
||||
{
|
||||
ok( hModule1 != NULL, "\"kernel32 \" should be loadable\n");
|
||||
ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError());
|
||||
ok( hModule == hModule1, "Loaded wrong module\n");
|
||||
FreeLibrary(hModule1);
|
||||
}
|
||||
ok( hModule1 != NULL, "\"kernel32 \" should be loadable\n" );
|
||||
ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError() );
|
||||
ok( hModule == hModule1, "Loaded wrong module\n" );
|
||||
FreeLibrary(hModule1);
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
|
||||
|
@ -252,7 +244,7 @@ static void testNestedLoadLibraryA(void)
|
|||
hModule1 = LoadLibraryA(path1);
|
||||
if (!hModule1)
|
||||
{
|
||||
/* We must be on Windows NT, so we cannot test */
|
||||
/* We must be on Windows, so we cannot test */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -260,12 +252,7 @@ static void testNestedLoadLibraryA(void)
|
|||
strcat(path2, "\\system32\\");
|
||||
strcat(path2, dllname);
|
||||
hModule2 = LoadLibraryA(path2);
|
||||
if (!hModule2)
|
||||
{
|
||||
/* We must be on Windows 9x, so we cannot test */
|
||||
ok(FreeLibrary(hModule1), "FreeLibrary() failed\n");
|
||||
return;
|
||||
}
|
||||
ok(hModule2 != NULL, "LoadLibrary(%s) failed\n", path2);
|
||||
|
||||
/* The first LoadLibrary() call may have registered the dll under the
|
||||
* system32 path. So load it, again, under the '...\system\...' path so
|
||||
|
@ -295,8 +282,7 @@ static void testLoadLibraryA_Wrong(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
hModule = LoadLibraryA("non_ex_pv.dll");
|
||||
ok( !hModule, "non_ex_pv.dll should be not loadable\n");
|
||||
ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_DLL_NOT_FOUND,
|
||||
"Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND (win9x), got %d\n", GetLastError());
|
||||
ok( GetLastError() == ERROR_MOD_NOT_FOUND, "Expected ERROR_MOD_NOT_FOUND, got %d\n", GetLastError() );
|
||||
|
||||
/* Just in case */
|
||||
FreeLibrary(hModule);
|
||||
|
@ -309,14 +295,12 @@ static void testGetProcAddress_Wrong(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
fp = GetProcAddress(NULL, "non_ex_call");
|
||||
ok( !fp, "non_ex_call should not be found\n");
|
||||
ok( GetLastError() == ERROR_PROC_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE,
|
||||
"Expected ERROR_PROC_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError());
|
||||
ok( GetLastError() == ERROR_PROC_NOT_FOUND, "Expected ERROR_PROC_NOT_FOUND, got %d\n", GetLastError() );
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
fp = GetProcAddress((HMODULE)0xdeadbeef, "non_ex_call");
|
||||
ok( !fp, "non_ex_call should not be found\n");
|
||||
ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE,
|
||||
"Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError());
|
||||
ok( GetLastError() == ERROR_MOD_NOT_FOUND, "Expected ERROR_MOD_NOT_FOUND, got %d\n", GetLastError() );
|
||||
}
|
||||
|
||||
static void testLoadLibraryEx(void)
|
||||
|
@ -332,28 +316,20 @@ static void testLoadLibraryEx(void)
|
|||
ok(hfile != INVALID_HANDLE_VALUE, "Expected a valid file handle\n");
|
||||
|
||||
/* NULL lpFileName */
|
||||
if (is_unicode_enabled)
|
||||
{
|
||||
SetLastError(0xdeadbeef);
|
||||
hmodule = LoadLibraryExA(NULL, NULL, 0);
|
||||
ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
|
||||
ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
|
||||
GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
|
||||
"Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n",
|
||||
GetLastError());
|
||||
}
|
||||
else
|
||||
win_skip("NULL filename crashes on WinMe\n");
|
||||
SetLastError(0xdeadbeef);
|
||||
hmodule = LoadLibraryExA(NULL, NULL, 0);
|
||||
ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
|
||||
ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
|
||||
GetLastError() == ERROR_INVALID_PARAMETER,
|
||||
"Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
||||
|
||||
/* empty lpFileName */
|
||||
SetLastError(0xdeadbeef);
|
||||
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_INVALID_PARAMETER /* win8 */,
|
||||
"Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND, got %d\n",
|
||||
GetLastError());
|
||||
"Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND, got %d\n", GetLastError());
|
||||
|
||||
/* hFile is non-NULL */
|
||||
SetLastError(0xdeadbeef);
|
||||
|
@ -362,8 +338,7 @@ static void testLoadLibraryEx(void)
|
|||
todo_wine
|
||||
{
|
||||
ok(GetLastError() == ERROR_SHARING_VIOLATION ||
|
||||
GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */
|
||||
GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
|
||||
GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */
|
||||
"Unexpected last error, got %d\n", GetLastError());
|
||||
}
|
||||
|
||||
|
@ -373,8 +348,7 @@ static void testLoadLibraryEx(void)
|
|||
todo_wine
|
||||
{
|
||||
ok(GetLastError() == ERROR_SHARING_VIOLATION ||
|
||||
GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */
|
||||
GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
|
||||
GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */
|
||||
"Unexpected last error, got %d\n", GetLastError());
|
||||
}
|
||||
|
||||
|
@ -384,10 +358,8 @@ static void testLoadLibraryEx(void)
|
|||
ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
|
||||
todo_wine
|
||||
{
|
||||
ok(GetLastError() == ERROR_SHARING_VIOLATION ||
|
||||
GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */
|
||||
"Expected ERROR_SHARING_VIOLATION or ERROR_FILE_NOT_FOUND, got %d\n",
|
||||
GetLastError());
|
||||
ok(GetLastError() == ERROR_SHARING_VIOLATION,
|
||||
"Expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
|
||||
}
|
||||
|
||||
/* lpFileName does not matter */
|
||||
|
@ -398,8 +370,7 @@ static void testLoadLibraryEx(void)
|
|||
ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
|
||||
ok(GetLastError() == ERROR_MOD_NOT_FOUND ||
|
||||
GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */
|
||||
"Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n",
|
||||
GetLastError());
|
||||
"Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
||||
}
|
||||
|
||||
CloseHandle(hfile);
|
||||
|
@ -410,10 +381,8 @@ static void testLoadLibraryEx(void)
|
|||
ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
|
||||
todo_wine
|
||||
{
|
||||
ok(GetLastError() == ERROR_FILE_INVALID ||
|
||||
GetLastError() == ERROR_BAD_FORMAT, /* win9x */
|
||||
"Expected ERROR_FILE_INVALID or ERROR_BAD_FORMAT, got %d\n",
|
||||
GetLastError());
|
||||
ok(GetLastError() == ERROR_FILE_INVALID,
|
||||
"Expected ERROR_FILE_INVALID, got %d\n", GetLastError());
|
||||
}
|
||||
|
||||
DeleteFileA("testfile.dll");
|
||||
|
@ -428,7 +397,7 @@ static void testLoadLibraryEx(void)
|
|||
hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||
ok(hmodule != 0, "Expected valid module handle\n");
|
||||
ok(GetLastError() == 0xdeadbeef ||
|
||||
GetLastError() == ERROR_SUCCESS, /* win9x */
|
||||
GetLastError() == ERROR_SUCCESS,
|
||||
"Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError());
|
||||
|
||||
/* try invalid file handle */
|
||||
|
@ -443,9 +412,7 @@ static void testLoadLibraryEx(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
hmodule = LoadLibraryExA("kernel32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||
ok(hmodule != 0, "Expected valid module handle\n");
|
||||
ok(GetLastError() == 0xdeadbeef ||
|
||||
GetLastError() == ERROR_SUCCESS, /* win9x */
|
||||
"Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError());
|
||||
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
|
||||
|
||||
FreeLibrary(hmodule);
|
||||
|
||||
|
@ -461,8 +428,7 @@ static void testLoadLibraryEx(void)
|
|||
{
|
||||
ok(hmodule == 0, "Expected 0, got %p\n", hmodule);
|
||||
}
|
||||
ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
|
||||
broken(GetLastError() == ERROR_INVALID_HANDLE), /* nt4 */
|
||||
ok(GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
|
||||
|
||||
/* Free the loaded dll when it's the first time this dll is loaded
|
||||
|
@ -730,22 +696,15 @@ static void init_pointers(void)
|
|||
MAKEFUNC(AddDllDirectory);
|
||||
MAKEFUNC(RemoveDllDirectory);
|
||||
MAKEFUNC(SetDefaultDllDirectories);
|
||||
MAKEFUNC(GetModuleHandleExA);
|
||||
MAKEFUNC(GetModuleHandleExW);
|
||||
MAKEFUNC(K32GetModuleInformation);
|
||||
#undef MAKEFUNC
|
||||
|
||||
/* not all Windows versions export this in kernel32 */
|
||||
/* before Windows 7 this was not exported in kernel32 */
|
||||
if (!pK32GetModuleInformation)
|
||||
{
|
||||
HMODULE hPsapi = LoadLibraryA("psapi.dll");
|
||||
if (hPsapi)
|
||||
{
|
||||
pK32GetModuleInformation = (void *)GetProcAddress(hPsapi, "GetModuleInformation");
|
||||
if (!pK32GetModuleInformation) FreeLibrary(hPsapi);
|
||||
}
|
||||
pK32GetModuleInformation = (void *)GetProcAddress(hPsapi, "GetModuleInformation");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void testGetModuleHandleEx(void)
|
||||
|
@ -756,113 +715,107 @@ static void testGetModuleHandleEx(void)
|
|||
DWORD error;
|
||||
HMODULE mod, mod_kernel32;
|
||||
|
||||
if (!pGetModuleHandleExA || !pGetModuleHandleExW)
|
||||
{
|
||||
win_skip( "GetModuleHandleEx not available\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExA( 0, NULL, NULL );
|
||||
ret = GetModuleHandleExA( 0, NULL, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExA( 0, "kernel32", NULL );
|
||||
ret = GetModuleHandleExA( 0, "kernel32", NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExA( 0, "kernel32", &mod );
|
||||
ret = GetModuleHandleExA( 0, "kernel32", &mod );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
|
||||
FreeLibrary( mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExA( 0, "nosuchmod", &mod );
|
||||
ret = GetModuleHandleExA( 0, "nosuchmod", &mod );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
|
||||
ok( mod == NULL, "got %p\n", mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExW( 0, NULL, NULL );
|
||||
ret = GetModuleHandleExW( 0, NULL, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExW( 0, kernel32W, NULL );
|
||||
ret = GetModuleHandleExW( 0, kernel32W, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExW( 0, kernel32W, &mod );
|
||||
ret = GetModuleHandleExW( 0, kernel32W, &mod );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
|
||||
FreeLibrary( mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExW( 0, nosuchmodW, &mod );
|
||||
ret = GetModuleHandleExW( 0, nosuchmodW, &mod );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
|
||||
ok( mod == NULL, "got %p\n", mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL );
|
||||
ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", NULL );
|
||||
ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", &mod );
|
||||
ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", &mod );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "nosuchmod", &mod );
|
||||
ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "nosuchmod", &mod );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
|
||||
ok( mod == NULL, "got %p\n", mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL );
|
||||
ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, NULL );
|
||||
ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, &mod );
|
||||
ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, &mod );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nosuchmodW, &mod );
|
||||
ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nosuchmodW, &mod );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
|
||||
|
@ -871,54 +824,54 @@ static void testGetModuleHandleEx(void)
|
|||
mod_kernel32 = LoadLibraryA( "kernel32" );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL );
|
||||
ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, NULL );
|
||||
ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, &mod );
|
||||
ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, &mod );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( mod == mod_kernel32, "got %p\n", mod );
|
||||
FreeLibrary( mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)0xbeefdead, &mod );
|
||||
ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)0xbeefdead, &mod );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
|
||||
ok( mod == NULL, "got %p\n", mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL );
|
||||
ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, NULL );
|
||||
ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, &mod );
|
||||
ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, &mod );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( mod == mod_kernel32, "got %p\n", mod );
|
||||
FreeLibrary( mod );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
mod = (HMODULE)0xdeadbeef;
|
||||
ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)0xbeefdead, &mod );
|
||||
ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)0xbeefdead, &mod );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error );
|
||||
|
@ -933,12 +886,6 @@ static void testK32GetModuleInformation(void)
|
|||
HMODULE mod;
|
||||
BOOL ret;
|
||||
|
||||
if (!pK32GetModuleInformation)
|
||||
{
|
||||
win_skip("K32GetModuleInformation not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mod = GetModuleHandleA(NULL);
|
||||
memset(&info, 0xAA, sizeof(info));
|
||||
ret = pK32GetModuleInformation(GetCurrentProcess(), mod, &info, sizeof(info));
|
||||
|
@ -971,7 +918,8 @@ static void test_AddDllDirectory(void)
|
|||
|
||||
buf[0] = '\0';
|
||||
GetTempPathW( sizeof(path)/sizeof(path[0]), path );
|
||||
GetTempFileNameW( path, tmpW, 0, buf );
|
||||
ret = GetTempFileNameW( path, tmpW, 0, buf );
|
||||
ok( ret, "GetTempFileName failed err %u\n", GetLastError() );
|
||||
SetLastError( 0xdeadbeef );
|
||||
cookie = pAddDllDirectory( buf );
|
||||
ok( cookie != NULL, "AddDllDirectory failed err %u\n", GetLastError() );
|
||||
|
|
|
@ -19,7 +19,15 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
|
||||
#define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
|
||||
|
||||
|
|
|
@ -18,7 +18,16 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winternl.h"
|
||||
#include "winioctl.h"
|
||||
#include "wine/test.h"
|
||||
|
||||
#define PIPENAME "\\\\.\\PiPe\\tests_pipe.c"
|
||||
#define PIPENAME_SPECIAL "\\\\.\\PiPe\\tests->pipe.c"
|
||||
|
@ -54,7 +63,7 @@ struct rpcThreadArgs
|
|||
static DWORD CALLBACK rpcThreadMain(LPVOID arg)
|
||||
{
|
||||
struct rpcThreadArgs *rpcargs = (struct rpcThreadArgs *)arg;
|
||||
trace("rpcThreadMain starting\n");
|
||||
if (winetest_debug > 1) trace("rpcThreadMain starting\n");
|
||||
SetLastError( rpcargs->lastError );
|
||||
|
||||
switch (rpcargs->op)
|
||||
|
@ -74,7 +83,7 @@ static DWORD CALLBACK rpcThreadMain(LPVOID arg)
|
|||
}
|
||||
|
||||
rpcargs->lastError = GetLastError();
|
||||
trace("rpcThreadMain returning\n");
|
||||
if (winetest_debug > 1) trace("rpcThreadMain returning\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -201,6 +210,11 @@ static void test_CreateNamedPipe(int pipemode)
|
|||
ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
|
||||
test_signaled(hnp);
|
||||
|
||||
ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n",
|
||||
ret, GetLastError());
|
||||
|
||||
ret = WaitNamedPipeA(PIPENAME, 2000);
|
||||
ok(ret, "WaitNamedPipe failed (%d)\n", GetLastError());
|
||||
|
||||
|
@ -211,6 +225,12 @@ static void test_CreateNamedPipe(int pipemode)
|
|||
|
||||
ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError());
|
||||
|
||||
/* Test ConnectNamedPipe() in both directions */
|
||||
ok(!ConnectNamedPipe(hnp, NULL), "ConnectNamedPipe(server) succeeded\n");
|
||||
ok(GetLastError() == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %u\n", GetLastError());
|
||||
ok(!ConnectNamedPipe(hFile, NULL), "ConnectNamedPipe(client) succeeded\n");
|
||||
ok(GetLastError() == ERROR_INVALID_FUNCTION, "expected ERROR_INVALID_FUNCTION, got %u\n", GetLastError());
|
||||
|
||||
/* don't try to do i/o if one side couldn't be opened, as it hangs */
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
HANDLE hFile2;
|
||||
|
@ -343,9 +363,7 @@ static void test_CreateNamedPipe(int pipemode)
|
|||
ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail);
|
||||
ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek3\n");
|
||||
if (pipemode == PIPE_TYPE_BYTE) {
|
||||
/* currently the Wine behavior depends on the kernel version */
|
||||
/* ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden); */
|
||||
if (readden != sizeof(obuf) + sizeof(obuf2)) todo_wine ok(0, "peek3 got %d bytes\n", readden);
|
||||
ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden);
|
||||
ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek3 got %d bytes left\n", left);
|
||||
}
|
||||
else
|
||||
|
@ -382,9 +400,7 @@ static void test_CreateNamedPipe(int pipemode)
|
|||
ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail);
|
||||
ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek4\n");
|
||||
if (pipemode == PIPE_TYPE_BYTE) {
|
||||
/* currently the Wine behavior depends on the kernel version */
|
||||
/* ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden); */
|
||||
if (readden != sizeof(obuf) + sizeof(obuf2)) todo_wine ok(0, "peek4 got %d bytes\n", readden);
|
||||
ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden);
|
||||
ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek4 got %d bytes left\n", left);
|
||||
}
|
||||
else
|
||||
|
@ -621,7 +637,7 @@ static void test_CreateNamedPipe(int pipemode)
|
|||
ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe with special characters failed\n");
|
||||
ok(CloseHandle(hnp), "CloseHandle\n");
|
||||
|
||||
trace("test_CreateNamedPipe returning\n");
|
||||
if (winetest_debug > 1) trace("test_CreateNamedPipe returning\n");
|
||||
}
|
||||
|
||||
static void test_CreateNamedPipe_instances_must_match(void)
|
||||
|
@ -709,11 +725,65 @@ static void test_CreateNamedPipe_instances_must_match(void)
|
|||
ok(CloseHandle(hnp2), "CloseHandle\n");
|
||||
}
|
||||
|
||||
static void test_ReadFile(void)
|
||||
{
|
||||
HANDLE server, client;
|
||||
OVERLAPPED overlapped;
|
||||
DWORD size;
|
||||
BOOL res;
|
||||
|
||||
static char buf[512];
|
||||
|
||||
server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||
1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL);
|
||||
ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
|
||||
|
||||
client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING, 0, 0);
|
||||
ok(client != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
|
||||
|
||||
ok(WriteFile(client, buf, sizeof(buf), &size, NULL), "WriteFile\n");
|
||||
|
||||
res = ReadFile(server, buf, 1, &size, NULL);
|
||||
ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError());
|
||||
ok(size == 1, "size = %u\n", size);
|
||||
|
||||
/* pass both overlapped and ret read */
|
||||
memset(&overlapped, 0, sizeof(overlapped));
|
||||
res = ReadFile(server, buf, 1, &size, &overlapped);
|
||||
ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError());
|
||||
ok(size == 0, "size = %u\n", size);
|
||||
ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "Internal = %lx\n", overlapped.Internal);
|
||||
ok(overlapped.InternalHigh == 1, "InternalHigh = %lx\n", overlapped.InternalHigh);
|
||||
|
||||
DisconnectNamedPipe(server);
|
||||
|
||||
memset(&overlapped, 0, sizeof(overlapped));
|
||||
overlapped.InternalHigh = 0xdeadbeef;
|
||||
res = ReadFile(server, buf, 1, &size, &overlapped);
|
||||
ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError());
|
||||
ok(size == 0, "size = %u\n", size);
|
||||
ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal);
|
||||
ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh);
|
||||
|
||||
memset(&overlapped, 0, sizeof(overlapped));
|
||||
overlapped.InternalHigh = 0xdeadbeef;
|
||||
res = WriteFile(server, buf, 1, &size, &overlapped);
|
||||
ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError());
|
||||
ok(size == 0, "size = %u\n", size);
|
||||
ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal);
|
||||
ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh);
|
||||
|
||||
CloseHandle(server);
|
||||
CloseHandle(client);
|
||||
}
|
||||
|
||||
/** implementation of alarm() */
|
||||
static DWORD CALLBACK alarmThreadMain(LPVOID arg)
|
||||
{
|
||||
DWORD_PTR timeout = (DWORD_PTR) arg;
|
||||
trace("alarmThreadMain\n");
|
||||
if (winetest_debug > 1) trace("alarmThreadMain\n");
|
||||
if (WaitForSingleObject( alarm_event, timeout ) == WAIT_TIMEOUT)
|
||||
{
|
||||
ok(FALSE, "alarm\n");
|
||||
|
@ -729,7 +799,7 @@ static DWORD CALLBACK serverThreadMain1(LPVOID arg)
|
|||
{
|
||||
int i;
|
||||
|
||||
trace("serverThreadMain1 start\n");
|
||||
if (winetest_debug > 1) trace("serverThreadMain1 start\n");
|
||||
/* Set up a simple echo server */
|
||||
hnp = CreateNamedPipeA(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_BYTE | PIPE_WAIT,
|
||||
|
@ -747,30 +817,30 @@ static DWORD CALLBACK serverThreadMain1(LPVOID arg)
|
|||
BOOL success;
|
||||
|
||||
/* Wait for client to connect */
|
||||
trace("Server calling ConnectNamedPipe...\n");
|
||||
if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n");
|
||||
ok(ConnectNamedPipe(hnp, NULL)
|
||||
|| GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n");
|
||||
trace("ConnectNamedPipe returned.\n");
|
||||
if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n");
|
||||
|
||||
/* Echo bytes once */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
trace("Server reading...\n");
|
||||
if (winetest_debug > 1) trace("Server reading...\n");
|
||||
success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
|
||||
trace("Server done reading.\n");
|
||||
if (winetest_debug > 1) trace("Server done reading.\n");
|
||||
ok(success, "ReadFile\n");
|
||||
ok(readden, "short read\n");
|
||||
|
||||
trace("Server writing...\n");
|
||||
if (winetest_debug > 1) trace("Server writing...\n");
|
||||
ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n");
|
||||
trace("Server done writing.\n");
|
||||
if (winetest_debug > 1) trace("Server done writing.\n");
|
||||
ok(written == readden, "write file len\n");
|
||||
|
||||
/* finish this connection, wait for next one */
|
||||
ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
|
||||
trace("Server done flushing.\n");
|
||||
if (winetest_debug > 1) trace("Server done flushing.\n");
|
||||
ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
|
||||
trace("Server done disconnecting.\n");
|
||||
if (winetest_debug > 1) trace("Server done disconnecting.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -802,28 +872,28 @@ static DWORD CALLBACK serverThreadMain2(LPVOID arg)
|
|||
|
||||
user_apc_ran = FALSE;
|
||||
if (i == 0 && pQueueUserAPC) {
|
||||
trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
|
||||
if (winetest_debug > 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
|
||||
ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0);
|
||||
ok(ret, "QueueUserAPC failed: %d\n", GetLastError());
|
||||
}
|
||||
|
||||
/* Wait for client to connect */
|
||||
trace("Server calling ConnectNamedPipe...\n");
|
||||
if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n");
|
||||
ok(ConnectNamedPipe(hnp, NULL)
|
||||
|| GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n");
|
||||
trace("ConnectNamedPipe returned.\n");
|
||||
if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n");
|
||||
|
||||
/* Echo bytes once */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
trace("Server reading...\n");
|
||||
if (winetest_debug > 1) trace("Server reading...\n");
|
||||
success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
|
||||
trace("Server done reading.\n");
|
||||
if (winetest_debug > 1) trace("Server done reading.\n");
|
||||
ok(success, "ReadFile\n");
|
||||
|
||||
trace("Server writing...\n");
|
||||
if (winetest_debug > 1) trace("Server writing...\n");
|
||||
ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n");
|
||||
trace("Server done writing.\n");
|
||||
if (winetest_debug > 1) trace("Server done writing.\n");
|
||||
ok(written == readden, "write file len\n");
|
||||
|
||||
/* finish this connection, wait for next one */
|
||||
|
@ -859,7 +929,7 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg)
|
|||
int i;
|
||||
HANDLE hEvent;
|
||||
|
||||
trace("serverThreadMain3\n");
|
||||
if (winetest_debug > 1) trace("serverThreadMain3\n");
|
||||
/* Set up a simple echo server */
|
||||
hnp = CreateNamedPipeA(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
||||
PIPE_TYPE_BYTE | PIPE_WAIT,
|
||||
|
@ -892,17 +962,17 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg)
|
|||
|
||||
/* Wait for client to connect */
|
||||
if (i == 0) {
|
||||
trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
|
||||
if (winetest_debug > 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
|
||||
success = ConnectNamedPipe(hnp, NULL);
|
||||
err = GetLastError();
|
||||
ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err);
|
||||
trace("ConnectNamedPipe operation complete.\n");
|
||||
if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n");
|
||||
} else {
|
||||
trace("Server calling overlapped ConnectNamedPipe...\n");
|
||||
if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n");
|
||||
success = ConnectNamedPipe(hnp, &oOverlap);
|
||||
err = GetLastError();
|
||||
ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), "overlapped ConnectNamedPipe\n");
|
||||
trace("overlapped ConnectNamedPipe returned.\n");
|
||||
if (winetest_debug > 1) trace("overlapped ConnectNamedPipe returned.\n");
|
||||
if (!success && (err == ERROR_IO_PENDING)) {
|
||||
if (letWFSOEwait)
|
||||
{
|
||||
|
@ -919,18 +989,18 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg)
|
|||
}
|
||||
}
|
||||
ok(success || (err == ERROR_PIPE_CONNECTED), "GetOverlappedResult ConnectNamedPipe\n");
|
||||
trace("overlapped ConnectNamedPipe operation complete.\n");
|
||||
if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n");
|
||||
}
|
||||
|
||||
/* Echo bytes once */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
trace("Server reading...\n");
|
||||
if (winetest_debug > 1) trace("Server reading...\n");
|
||||
success = ReadFile(hnp, buf, sizeof(buf), &readden, &oOverlap);
|
||||
trace("Server ReadFile returned...\n");
|
||||
if (winetest_debug > 1) trace("Server ReadFile returned...\n");
|
||||
err = GetLastError();
|
||||
ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile\n");
|
||||
trace("overlapped ReadFile returned.\n");
|
||||
if (winetest_debug > 1) trace("overlapped ReadFile returned.\n");
|
||||
if (!success && (err == ERROR_IO_PENDING)) {
|
||||
if (letWFSOEwait)
|
||||
{
|
||||
|
@ -946,15 +1016,15 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg)
|
|||
success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE);
|
||||
}
|
||||
}
|
||||
trace("Server done reading.\n");
|
||||
if (winetest_debug > 1) trace("Server done reading.\n");
|
||||
ok(success, "overlapped ReadFile\n");
|
||||
|
||||
trace("Server writing...\n");
|
||||
if (winetest_debug > 1) trace("Server writing...\n");
|
||||
success = WriteFile(hnp, buf, readden, &written, &oOverlap);
|
||||
trace("Server WriteFile returned...\n");
|
||||
if (winetest_debug > 1) trace("Server WriteFile returned...\n");
|
||||
err = GetLastError();
|
||||
ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile\n");
|
||||
trace("overlapped WriteFile returned.\n");
|
||||
if (winetest_debug > 1) trace("overlapped WriteFile returned.\n");
|
||||
if (!success && (err == ERROR_IO_PENDING)) {
|
||||
if (letWFSOEwait)
|
||||
{
|
||||
|
@ -970,7 +1040,7 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg)
|
|||
success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE);
|
||||
}
|
||||
}
|
||||
trace("Server done writing.\n");
|
||||
if (winetest_debug > 1) trace("Server done writing.\n");
|
||||
ok(success, "overlapped WriteFile\n");
|
||||
ok(written == readden, "write file len\n");
|
||||
|
||||
|
@ -988,7 +1058,7 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg)
|
|||
HANDLE hcompletion;
|
||||
BOOL ret;
|
||||
|
||||
trace("serverThreadMain4\n");
|
||||
if (winetest_debug > 1) trace("serverThreadMain4\n");
|
||||
/* Set up a simple echo server */
|
||||
hnp = CreateNamedPipeA(PIPENAME "serverThreadMain4", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
||||
PIPE_TYPE_BYTE | PIPE_WAIT,
|
||||
|
@ -1020,13 +1090,13 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg)
|
|||
memset(&oWrite, 0, sizeof(oWrite));
|
||||
|
||||
/* Wait for client to connect */
|
||||
trace("Server calling overlapped ConnectNamedPipe...\n");
|
||||
if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n");
|
||||
success = ConnectNamedPipe(hnp, &oConnect);
|
||||
err = GetLastError();
|
||||
ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED),
|
||||
"overlapped ConnectNamedPipe got %u err %u\n", success, err );
|
||||
if (!success && err == ERROR_IO_PENDING) {
|
||||
trace("ConnectNamedPipe GetQueuedCompletionStatus\n");
|
||||
if (winetest_debug > 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n");
|
||||
success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 0);
|
||||
if (!success)
|
||||
{
|
||||
|
@ -1041,14 +1111,14 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg)
|
|||
ok(oResult == &oConnect, "got overlapped pointer %p instead of %p\n", oResult, &oConnect);
|
||||
}
|
||||
}
|
||||
trace("overlapped ConnectNamedPipe operation complete.\n");
|
||||
if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n");
|
||||
|
||||
/* Echo bytes once */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
trace("Server reading...\n");
|
||||
if (winetest_debug > 1) trace("Server reading...\n");
|
||||
success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead);
|
||||
trace("Server ReadFile returned...\n");
|
||||
if (winetest_debug > 1) trace("Server ReadFile returned...\n");
|
||||
err = GetLastError();
|
||||
ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile, err=%i\n", err);
|
||||
success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey,
|
||||
|
@ -1059,11 +1129,11 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg)
|
|||
ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey);
|
||||
ok(oResult == &oRead, "got overlapped pointer %p instead of %p\n", oResult, &oRead);
|
||||
}
|
||||
trace("Server done reading.\n");
|
||||
if (winetest_debug > 1) trace("Server done reading.\n");
|
||||
|
||||
trace("Server writing...\n");
|
||||
if (winetest_debug > 1) trace("Server writing...\n");
|
||||
success = WriteFile(hnp, buf, readden, &written, &oWrite);
|
||||
trace("Server WriteFile returned...\n");
|
||||
if (winetest_debug > 1) trace("Server WriteFile returned...\n");
|
||||
err = GetLastError();
|
||||
ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile failed, err=%u\n", err);
|
||||
success = GetQueuedCompletionStatus(hcompletion, &written, &compkey,
|
||||
|
@ -1075,7 +1145,46 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg)
|
|||
ok(oResult == &oWrite, "got overlapped pointer %p instead of %p\n", oResult, &oWrite);
|
||||
ok(written == readden, "write file len\n");
|
||||
}
|
||||
trace("Server done writing.\n");
|
||||
if (winetest_debug > 1) trace("Server done writing.\n");
|
||||
|
||||
/* Client will finish this connection, the following ops will trigger broken pipe errors. */
|
||||
|
||||
/* Wait for the pipe to break. */
|
||||
while (PeekNamedPipe(hnp, NULL, 0, NULL, &written, &written));
|
||||
|
||||
if (winetest_debug > 1) trace("Server writing on disconnected pipe...\n");
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
success = WriteFile(hnp, buf, readden, &written, &oWrite);
|
||||
err = GetLastError();
|
||||
todo_wine_if (!success && err == ERROR_PIPE_NOT_CONNECTED) ok(!success && err == ERROR_NO_DATA,
|
||||
"overlapped WriteFile on disconnected pipe returned %u, err=%i\n", success, err);
|
||||
|
||||
/* No completion status is queued on immediate error. */
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
oResult = (OVERLAPPED *)0xdeadbeef;
|
||||
success = GetQueuedCompletionStatus(hcompletion, &written, &compkey,
|
||||
&oResult, 0);
|
||||
err = GetLastError();
|
||||
ok(!success && err == WAIT_TIMEOUT && !oResult,
|
||||
"WriteFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
|
||||
success, err, oResult);
|
||||
|
||||
if (winetest_debug > 1) trace("Server reading from disconnected pipe...\n");
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead);
|
||||
if (winetest_debug > 1) trace("Server ReadFile from disconnected pipe returned...\n");
|
||||
err = GetLastError();
|
||||
ok(!success && err == ERROR_BROKEN_PIPE,
|
||||
"overlapped ReadFile on disconnected pipe returned %u, err=%i\n", success, err);
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
oResult = (OVERLAPPED *)0xdeadbeef;
|
||||
success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey,
|
||||
&oResult, 0);
|
||||
err = GetLastError();
|
||||
ok(!success && err == WAIT_TIMEOUT && !oResult,
|
||||
"ReadFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
|
||||
success, err, oResult);
|
||||
|
||||
/* finish this connection, wait for next one */
|
||||
ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
|
||||
|
@ -1111,7 +1220,7 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg)
|
|||
int i;
|
||||
HANDLE hEvent;
|
||||
|
||||
trace("serverThreadMain5\n");
|
||||
if (winetest_debug > 1) trace("serverThreadMain5\n");
|
||||
/* Set up a simple echo server */
|
||||
hnp = CreateNamedPipeA(PIPENAME "serverThreadMain5", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
||||
PIPE_TYPE_BYTE | PIPE_WAIT,
|
||||
|
@ -1139,23 +1248,23 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg)
|
|||
oOverlap.hEvent = hEvent;
|
||||
|
||||
/* Wait for client to connect */
|
||||
trace("Server calling ConnectNamedPipe...\n");
|
||||
if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n");
|
||||
success = ConnectNamedPipe(hnp, NULL);
|
||||
err = GetLastError();
|
||||
ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err);
|
||||
trace("ConnectNamedPipe operation complete.\n");
|
||||
if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n");
|
||||
|
||||
/* Echo bytes once */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
trace("Server reading...\n");
|
||||
if (winetest_debug > 1) trace("Server reading...\n");
|
||||
completion_called = 0;
|
||||
ResetEvent(hEvent);
|
||||
success = ReadFileEx(hnp, buf, sizeof(buf), &oOverlap, completion_routine);
|
||||
trace("Server ReadFileEx returned...\n");
|
||||
if (winetest_debug > 1) trace("Server ReadFileEx returned...\n");
|
||||
ok(success, "ReadFileEx failed, err=%i\n", GetLastError());
|
||||
ok(completion_called == 0, "completion routine called before ReadFileEx return\n");
|
||||
trace("ReadFileEx returned.\n");
|
||||
if (winetest_debug > 1) trace("ReadFileEx returned.\n");
|
||||
if (success) {
|
||||
DWORD ret;
|
||||
do {
|
||||
|
@ -1168,16 +1277,16 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg)
|
|||
ok(completion_num_bytes != 0, "read 0 bytes\n");
|
||||
ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped);
|
||||
readden = completion_num_bytes;
|
||||
trace("Server done reading.\n");
|
||||
if (winetest_debug > 1) trace("Server done reading.\n");
|
||||
|
||||
trace("Server writing...\n");
|
||||
if (winetest_debug > 1) trace("Server writing...\n");
|
||||
completion_called = 0;
|
||||
ResetEvent(hEvent);
|
||||
success = WriteFileEx(hnp, buf, readden, &oOverlap, completion_routine);
|
||||
trace("Server WriteFileEx returned...\n");
|
||||
if (winetest_debug > 1) trace("Server WriteFileEx returned...\n");
|
||||
ok(success, "WriteFileEx failed, err=%i\n", GetLastError());
|
||||
ok(completion_called == 0, "completion routine called before ReadFileEx return\n");
|
||||
trace("overlapped WriteFile returned.\n");
|
||||
if (winetest_debug > 1) trace("overlapped WriteFile returned.\n");
|
||||
if (success) {
|
||||
DWORD ret;
|
||||
do {
|
||||
|
@ -1185,7 +1294,7 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg)
|
|||
} while (ret == WAIT_IO_COMPLETION);
|
||||
ok(ret == 0, "wait WriteFileEx returned %x\n", ret);
|
||||
}
|
||||
trace("Server done writing.\n");
|
||||
if (winetest_debug > 1) trace("Server done writing.\n");
|
||||
ok(completion_called == 1, "completion routine called %i times\n", completion_called);
|
||||
ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %d\n", completion_errorcode);
|
||||
ok(completion_num_bytes == readden, "read %i bytes wrote %i\n", readden, completion_num_bytes);
|
||||
|
@ -1202,7 +1311,7 @@ static void exercizeServer(const char *pipename, HANDLE serverThread)
|
|||
{
|
||||
int i;
|
||||
|
||||
trace("exercizeServer starting\n");
|
||||
if (winetest_debug > 1) trace("exercizeServer starting\n");
|
||||
for (i = 0; i < NB_SERVER_LOOPS; i++) {
|
||||
HANDLE hFile=INVALID_HANDLE_VALUE;
|
||||
static const char obuf[] = "Bit Bucket";
|
||||
|
@ -1213,7 +1322,7 @@ static void exercizeServer(const char *pipename, HANDLE serverThread)
|
|||
|
||||
for (loop = 0; loop < 3; loop++) {
|
||||
DWORD err;
|
||||
trace("Client connecting...\n");
|
||||
if (winetest_debug > 1) trace("Client connecting...\n");
|
||||
/* Connect to the server */
|
||||
hFile = CreateFileA(pipename, GENERIC_READ | GENERIC_WRITE, 0,
|
||||
NULL, OPEN_EXISTING, 0, 0);
|
||||
|
@ -1224,28 +1333,28 @@ static void exercizeServer(const char *pipename, HANDLE serverThread)
|
|||
ok(err == ERROR_PIPE_BUSY || err == ERROR_FILE_NOT_FOUND, "connecting to pipe\n");
|
||||
else
|
||||
ok(err == ERROR_PIPE_BUSY, "connecting to pipe\n");
|
||||
trace("connect failed, retrying\n");
|
||||
if (winetest_debug > 1) trace("connect failed, retrying\n");
|
||||
Sleep(200);
|
||||
}
|
||||
ok(hFile != INVALID_HANDLE_VALUE, "client opening named pipe\n");
|
||||
|
||||
/* Make sure it can echo */
|
||||
memset(ibuf, 0, sizeof(ibuf));
|
||||
trace("Client writing...\n");
|
||||
if (winetest_debug > 1) trace("Client writing...\n");
|
||||
ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile to client end of pipe\n");
|
||||
ok(written == sizeof(obuf), "write file len\n");
|
||||
trace("Client reading...\n");
|
||||
if (winetest_debug > 1) trace("Client reading...\n");
|
||||
ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile from client end of pipe\n");
|
||||
ok(readden == sizeof(obuf), "read file len\n");
|
||||
ok(memcmp(obuf, ibuf, written) == 0, "content check\n");
|
||||
|
||||
trace("Client closing...\n");
|
||||
if (winetest_debug > 1) trace("Client closing...\n");
|
||||
ok(CloseHandle(hFile), "CloseHandle\n");
|
||||
}
|
||||
|
||||
ok(WaitForSingleObject(serverThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n");
|
||||
CloseHandle(hnp);
|
||||
trace("exercizeServer returning\n");
|
||||
if (winetest_debug > 1) trace("exercizeServer returning\n");
|
||||
}
|
||||
|
||||
static void test_NamedPipe_2(void)
|
||||
|
@ -1299,7 +1408,7 @@ static void test_NamedPipe_2(void)
|
|||
|
||||
ok(SetEvent( alarm_event ), "SetEvent\n");
|
||||
CloseHandle( alarm_event );
|
||||
trace("test_NamedPipe_2 returning\n");
|
||||
if (winetest_debug > 1) trace("test_NamedPipe_2 returning\n");
|
||||
}
|
||||
|
||||
static int test_DisconnectNamedPipe(void)
|
||||
|
@ -1349,10 +1458,20 @@ static int test_DisconnectNamedPipe(void)
|
|||
ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
|
||||
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED,
|
||||
"ReadFile from disconnected pipe with bytes waiting\n");
|
||||
|
||||
ok(!DisconnectNamedPipe(hnp) && GetLastError() == ERROR_PIPE_NOT_CONNECTED,
|
||||
"DisconnectNamedPipe worked twice\n");
|
||||
ret = WaitForSingleObject(hFile, 0);
|
||||
ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %X\n", ret);
|
||||
|
||||
ret = PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "PeekNamedPipe returned %x (%u)\n",
|
||||
ret, GetLastError());
|
||||
ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n",
|
||||
ret, GetLastError());
|
||||
ok(CloseHandle(hFile), "CloseHandle\n");
|
||||
}
|
||||
|
||||
|
@ -1463,6 +1582,11 @@ static void test_CloseHandle(void)
|
|||
ok(ret, "ReadFile failed with %u\n", GetLastError());
|
||||
ok(numbytes == 0, "expected 0, got %u\n", numbytes);
|
||||
|
||||
numbytes = 0xdeadbeef;
|
||||
ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL);
|
||||
ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
|
||||
ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
|
||||
|
||||
numbytes = 0xdeadbeef;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL);
|
||||
|
@ -1480,6 +1604,12 @@ static void test_CloseHandle(void)
|
|||
ok(!ret, "ReadFile unexpectedly succeeded\n");
|
||||
ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
|
||||
|
||||
numbytes = 0xdeadbeef;
|
||||
ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL);
|
||||
ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n",
|
||||
ret, GetLastError());
|
||||
ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL);
|
||||
ok(!ret, "WriteFile unexpectedly succeeded\n");
|
||||
|
@ -1562,6 +1692,11 @@ static void test_CloseHandle(void)
|
|||
"ReadFile failed with %u\n", GetLastError());
|
||||
ok(numbytes == 0, "expected 0, got %u\n", numbytes);
|
||||
|
||||
numbytes = 0xdeadbeef;
|
||||
ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL);
|
||||
ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
|
||||
ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
|
||||
|
||||
numbytes = 0xdeadbeef;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL);
|
||||
|
@ -1579,6 +1714,12 @@ static void test_CloseHandle(void)
|
|||
ok(!ret, "ReadFile unexpectedly succeeded\n");
|
||||
ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
|
||||
|
||||
numbytes = 0xdeadbeef;
|
||||
ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL);
|
||||
ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n",
|
||||
ret, GetLastError());
|
||||
ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL);
|
||||
ok(!ret, "WriteFile unexpectedly succeeded\n");
|
||||
|
@ -2501,11 +2642,9 @@ static void test_readfileex_pending(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ret = ReadFile(server, read_buf, 0, &num_bytes, &overlapped);
|
||||
ok(!ret, "ReadFile should fail\n");
|
||||
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);
|
||||
|
@ -2517,11 +2656,9 @@ todo_wine
|
|||
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);
|
||||
|
||||
|
@ -2587,7 +2724,7 @@ static void _overlapped_read_sync(unsigned line, HANDLE reader, void *buf, DWORD
|
|||
else
|
||||
ok_(__FILE__,line)(res, "ReadFile failed: %u\n", GetLastError());
|
||||
if(partial_read)
|
||||
todo_wine ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes);
|
||||
ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes);
|
||||
else
|
||||
ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %u expected %u\n", read_bytes, expected_result);
|
||||
|
||||
|
@ -2648,7 +2785,7 @@ static void _overlapped_write_async(unsigned line, HANDLE writer, void *buf, DWO
|
|||
overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
res = WriteFile(writer, buf, size, &written_bytes, overlapped);
|
||||
ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%u)\n", res, GetLastError());
|
||||
todo_wine ok_(__FILE__,line)(!written_bytes, "written_bytes = %u\n", written_bytes);
|
||||
ok_(__FILE__,line)(!written_bytes, "written_bytes = %u\n", written_bytes);
|
||||
|
||||
_test_not_signaled(line, overlapped->hEvent);
|
||||
}
|
||||
|
@ -3048,6 +3185,7 @@ START_TEST(pipe)
|
|||
test_CreateNamedPipe(PIPE_TYPE_BYTE);
|
||||
test_CreateNamedPipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE);
|
||||
test_CreatePipe();
|
||||
test_ReadFile();
|
||||
test_CloseHandle();
|
||||
test_impersonation();
|
||||
test_overlapped();
|
||||
|
@ -3057,6 +3195,5 @@ START_TEST(pipe)
|
|||
test_readfileex_pending();
|
||||
test_overlapped_transport(TRUE, FALSE);
|
||||
test_overlapped_transport(TRUE, TRUE);
|
||||
if (broken(1)) /* FIXME: Remove once Wine is ready. */
|
||||
test_overlapped_transport(FALSE, FALSE);
|
||||
test_overlapped_transport(FALSE, FALSE);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
|
||||
#ifndef _KERNEL32_WINETEST_PRECOMP_H_
|
||||
#define _KERNEL32_WINETEST_PRECOMP_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <ntstatus.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
#define COBJMACROS
|
||||
|
||||
#include <ntstatus.h>
|
||||
#define WIN32_NO_STATUS
|
||||
|
||||
#include <windows.h>
|
||||
#include <wine/test.h>
|
||||
#include <wine/winternl.h>
|
||||
#include <winuser.h>
|
||||
|
|
|
@ -20,7 +20,24 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "wincon.h"
|
||||
#include "winnls.h"
|
||||
#include "winternl.h"
|
||||
#include "tlhelp32.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#include "winnt.h"
|
||||
|
||||
/* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
|
||||
#define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000)
|
||||
|
@ -1399,7 +1416,7 @@ static void test_SuspendFlag(void)
|
|||
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startup, &info), "CreateProcess\n");
|
||||
|
||||
ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n");
|
||||
Sleep(8000);
|
||||
Sleep(1000);
|
||||
ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n");
|
||||
ok(ResumeThread(info.hThread) == 1, "Resuming thread\n");
|
||||
|
||||
|
@ -1669,6 +1686,9 @@ static void test_Console(void)
|
|||
ok(ReadFile(hParentIn, buffer, sizeof(buffer), &w, NULL), "Reading from child\n");
|
||||
ok(strcmp(buffer, msg) == 0, "Should have received '%s'\n", msg);
|
||||
|
||||
/* the child may also send the final "n tests executed" string, so read it to avoid a deadlock */
|
||||
ReadFile(hParentIn, buffer, sizeof(buffer), &w, NULL);
|
||||
|
||||
/* wait for child to terminate */
|
||||
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
|
||||
/* child process has changed result file, so let profile functions know about it */
|
||||
|
@ -2378,6 +2398,69 @@ static void _create_process(int line, const char *command, LPPROCESS_INFORMATION
|
|||
ok_(__FILE__, line)(ret, "CreateProcess error %u\n", GetLastError());
|
||||
}
|
||||
|
||||
#define test_assigned_proc(job, ...) _test_assigned_proc(__LINE__, job, __VA_ARGS__)
|
||||
static void _test_assigned_proc(int line, HANDLE job, int expected_count, ...)
|
||||
{
|
||||
char buf[sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + sizeof(ULONG_PTR) * 20];
|
||||
PJOBOBJECT_BASIC_PROCESS_ID_LIST pid_list = (JOBOBJECT_BASIC_PROCESS_ID_LIST *)buf;
|
||||
DWORD ret_len, pid;
|
||||
va_list valist;
|
||||
int n;
|
||||
BOOL ret;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = pQueryInformationJobObject(job, JobObjectBasicProcessIdList, pid_list, sizeof(buf), &ret_len);
|
||||
ok_(__FILE__, line)(ret, "QueryInformationJobObject error %u\n", GetLastError());
|
||||
if (ret)
|
||||
{
|
||||
todo_wine_if(expected_count)
|
||||
ok_(__FILE__, line)(expected_count == pid_list->NumberOfAssignedProcesses,
|
||||
"Expected NumberOfAssignedProcesses to be %d (expected_count) is %d\n",
|
||||
expected_count, pid_list->NumberOfAssignedProcesses);
|
||||
todo_wine_if(expected_count)
|
||||
ok_(__FILE__, line)(expected_count == pid_list->NumberOfProcessIdsInList,
|
||||
"Expected NumberOfProcessIdsInList to be %d (expected_count) is %d\n",
|
||||
expected_count, pid_list->NumberOfProcessIdsInList);
|
||||
|
||||
va_start(valist, expected_count);
|
||||
for (n = 0; n < min(expected_count, pid_list->NumberOfProcessIdsInList); ++n)
|
||||
{
|
||||
pid = va_arg(valist, DWORD);
|
||||
ok_(__FILE__, line)(pid == pid_list->ProcessIdList[n],
|
||||
"Expected pid_list->ProcessIdList[%d] to be %x is %lx\n",
|
||||
n, pid, pid_list->ProcessIdList[n]);
|
||||
}
|
||||
va_end(valist);
|
||||
}
|
||||
}
|
||||
|
||||
#define test_accounting(job, total_proc, active_proc, terminated_proc) _test_accounting(__LINE__, job, total_proc, active_proc, terminated_proc)
|
||||
static void _test_accounting(int line, HANDLE job, int total_proc, int active_proc, int terminated_proc)
|
||||
{
|
||||
JOBOBJECT_BASIC_ACCOUNTING_INFORMATION basic_accounting;
|
||||
DWORD ret_len;
|
||||
BOOL ret;
|
||||
|
||||
memset(&basic_accounting, 0, sizeof(basic_accounting));
|
||||
ret = pQueryInformationJobObject(job, JobObjectBasicAccountingInformation, &basic_accounting, sizeof(basic_accounting), &ret_len);
|
||||
ok_(__FILE__, line)(ret, "QueryInformationJobObject error %u\n", GetLastError());
|
||||
if (ret)
|
||||
{
|
||||
/* Not going to check process times or page faults */
|
||||
|
||||
todo_wine_if(total_proc)
|
||||
ok_(__FILE__, line)(total_proc == basic_accounting.TotalProcesses,
|
||||
"Expected basic_accounting.TotalProcesses to be %d (total_proc) is %d\n",
|
||||
total_proc, basic_accounting.TotalProcesses);
|
||||
todo_wine_if(active_proc)
|
||||
ok_(__FILE__, line)(active_proc == basic_accounting.ActiveProcesses,
|
||||
"Expected basic_accounting.ActiveProcesses to be %d (active_proc) is %d\n",
|
||||
active_proc, basic_accounting.ActiveProcesses);
|
||||
ok_(__FILE__, line)(terminated_proc == basic_accounting.TotalTerminatedProcesses,
|
||||
"Expected basic_accounting.TotalTerminatedProcesses to be %d (terminated_proc) is %d\n",
|
||||
terminated_proc, basic_accounting.TotalTerminatedProcesses);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_IsProcessInJob(void)
|
||||
{
|
||||
|
@ -2404,11 +2487,15 @@ static void test_IsProcessInJob(void)
|
|||
ret = pIsProcessInJob(pi.hProcess, job, &out);
|
||||
ok(ret, "IsProcessInJob error %u\n", GetLastError());
|
||||
ok(!out, "IsProcessInJob returned out=%u\n", out);
|
||||
test_assigned_proc(job, 0);
|
||||
test_accounting(job, 0, 0, 0);
|
||||
|
||||
out = TRUE;
|
||||
ret = pIsProcessInJob(pi.hProcess, job2, &out);
|
||||
ok(ret, "IsProcessInJob error %u\n", GetLastError());
|
||||
ok(!out, "IsProcessInJob returned out=%u\n", out);
|
||||
test_assigned_proc(job2, 0);
|
||||
test_accounting(job2, 0, 0, 0);
|
||||
|
||||
out = TRUE;
|
||||
ret = pIsProcessInJob(pi.hProcess, NULL, &out);
|
||||
|
@ -2422,11 +2509,15 @@ static void test_IsProcessInJob(void)
|
|||
ret = pIsProcessInJob(pi.hProcess, job, &out);
|
||||
ok(ret, "IsProcessInJob error %u\n", GetLastError());
|
||||
ok(out, "IsProcessInJob returned out=%u\n", out);
|
||||
test_assigned_proc(job, 1, pi.dwProcessId);
|
||||
test_accounting(job, 1, 1, 0);
|
||||
|
||||
out = TRUE;
|
||||
ret = pIsProcessInJob(pi.hProcess, job2, &out);
|
||||
ok(ret, "IsProcessInJob error %u\n", GetLastError());
|
||||
ok(!out, "IsProcessInJob returned out=%u\n", out);
|
||||
test_assigned_proc(job2, 0);
|
||||
test_accounting(job2, 0, 0, 0);
|
||||
|
||||
out = FALSE;
|
||||
ret = pIsProcessInJob(pi.hProcess, NULL, &out);
|
||||
|
@ -2442,6 +2533,8 @@ static void test_IsProcessInJob(void)
|
|||
ret = pIsProcessInJob(pi.hProcess, job, &out);
|
||||
ok(ret, "IsProcessInJob error %u\n", GetLastError());
|
||||
ok(out, "IsProcessInJob returned out=%u\n", out);
|
||||
test_assigned_proc(job, 0);
|
||||
test_accounting(job, 1, 0, 0);
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
|
@ -2458,11 +2551,15 @@ static void test_TerminateJobObject(void)
|
|||
|
||||
job = pCreateJobObjectW(NULL, NULL);
|
||||
ok(job != NULL, "CreateJobObject error %u\n", GetLastError());
|
||||
test_assigned_proc(job, 0);
|
||||
test_accounting(job, 0, 0, 0);
|
||||
|
||||
create_process("wait", &pi);
|
||||
|
||||
ret = pAssignProcessToJobObject(job, pi.hProcess);
|
||||
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
|
||||
test_assigned_proc(job, 1, pi.dwProcessId);
|
||||
test_accounting(job, 1, 1, 0);
|
||||
|
||||
ret = pTerminateJobObject(job, 123);
|
||||
ok(ret, "TerminateJobObject error %u\n", GetLastError());
|
||||
|
@ -2470,6 +2567,8 @@ static void test_TerminateJobObject(void)
|
|||
dwret = WaitForSingleObject(pi.hProcess, 1000);
|
||||
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
|
||||
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
|
||||
test_assigned_proc(job, 0);
|
||||
test_accounting(job, 1, 0, 0);
|
||||
|
||||
ret = GetExitCodeProcess(pi.hProcess, &dwret);
|
||||
ok(ret, "GetExitCodeProcess error %u\n", GetLastError());
|
||||
|
@ -2489,6 +2588,8 @@ static void test_TerminateJobObject(void)
|
|||
ret = pAssignProcessToJobObject(job, pi.hProcess);
|
||||
ok(!ret, "AssignProcessToJobObject unexpectedly succeeded\n");
|
||||
expect_eq_d(ERROR_ACCESS_DENIED, GetLastError());
|
||||
test_assigned_proc(job, 0);
|
||||
test_accounting(job, 1, 0, 0);
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
|
@ -2675,11 +2776,15 @@ static void test_KillOnJobClose(void)
|
|||
return;
|
||||
}
|
||||
ok(ret, "SetInformationJobObject error %u\n", GetLastError());
|
||||
test_assigned_proc(job, 0);
|
||||
test_accounting(job, 0, 0, 0);
|
||||
|
||||
create_process("wait", &pi);
|
||||
|
||||
ret = pAssignProcessToJobObject(job, pi.hProcess);
|
||||
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
|
||||
test_assigned_proc(job, 1, pi.dwProcessId);
|
||||
test_accounting(job, 1, 1, 0);
|
||||
|
||||
CloseHandle(job);
|
||||
|
||||
|
@ -2790,6 +2895,8 @@ static HANDLE test_AddSelfToJob(void)
|
|||
|
||||
ret = pAssignProcessToJobObject(job, GetCurrentProcess());
|
||||
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
|
||||
test_assigned_proc(job, 1, GetCurrentProcessId());
|
||||
test_accounting(job, 1, 1, 0);
|
||||
|
||||
return job;
|
||||
}
|
||||
|
@ -2817,6 +2924,8 @@ static void test_jobInheritance(HANDLE job)
|
|||
ret = pIsProcessInJob(pi.hProcess, job, &out);
|
||||
ok(ret, "IsProcessInJob error %u\n", GetLastError());
|
||||
ok(out, "IsProcessInJob returned out=%u\n", out);
|
||||
test_assigned_proc(job, 2, GetCurrentProcessId(), pi.dwProcessId);
|
||||
test_accounting(job, 2, 2, 0);
|
||||
|
||||
dwret = WaitForSingleObject(pi.hProcess, 1000);
|
||||
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
|
||||
|
@ -2845,6 +2954,8 @@ static void test_BreakawayOk(HANDLE job)
|
|||
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi);
|
||||
ok(!ret, "CreateProcessA expected failure\n");
|
||||
expect_eq_d(ERROR_ACCESS_DENIED, GetLastError());
|
||||
test_assigned_proc(job, 1, GetCurrentProcessId());
|
||||
test_accounting(job, 2, 1, 0);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
|
@ -2867,6 +2978,8 @@ static void test_BreakawayOk(HANDLE job)
|
|||
ret = pIsProcessInJob(pi.hProcess, job, &out);
|
||||
ok(ret, "IsProcessInJob error %u\n", GetLastError());
|
||||
ok(!out, "IsProcessInJob returned out=%u\n", out);
|
||||
test_assigned_proc(job, 1, GetCurrentProcessId());
|
||||
test_accounting(job, 2, 1, 0);
|
||||
|
||||
dwret = WaitForSingleObject(pi.hProcess, 1000);
|
||||
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
|
||||
|
@ -2884,6 +2997,8 @@ static void test_BreakawayOk(HANDLE job)
|
|||
ret = pIsProcessInJob(pi.hProcess, job, &out);
|
||||
ok(ret, "IsProcessInJob error %u\n", GetLastError());
|
||||
ok(!out, "IsProcessInJob returned out=%u\n", out);
|
||||
test_assigned_proc(job, 1, GetCurrentProcessId());
|
||||
test_accounting(job, 2, 1, 0);
|
||||
|
||||
dwret = WaitForSingleObject(pi.hProcess, 1000);
|
||||
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
|
||||
|
@ -2965,6 +3080,389 @@ static void test_DetachConsoleHandles(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
static BOOL read_nt_header(HANDLE process_handle, MEMORY_BASIC_INFORMATION *mbi,
|
||||
IMAGE_NT_HEADERS *nt_header)
|
||||
{
|
||||
IMAGE_DOS_HEADER dos_header;
|
||||
|
||||
if (!ReadProcessMemory(process_handle, mbi->BaseAddress, &dos_header, sizeof(dos_header), NULL))
|
||||
return FALSE;
|
||||
|
||||
if ((dos_header.e_magic != IMAGE_DOS_SIGNATURE) ||
|
||||
((ULONG)dos_header.e_lfanew > mbi->RegionSize) ||
|
||||
(dos_header.e_lfanew < sizeof(dos_header)))
|
||||
return FALSE;
|
||||
|
||||
if (!ReadProcessMemory(process_handle, (char *)mbi->BaseAddress + dos_header.e_lfanew,
|
||||
nt_header, sizeof(*nt_header), NULL))
|
||||
return FALSE;
|
||||
|
||||
return (nt_header->Signature == IMAGE_NT_SIGNATURE);
|
||||
}
|
||||
|
||||
static PVOID get_process_exe(HANDLE process_handle, IMAGE_NT_HEADERS *nt_header)
|
||||
{
|
||||
PVOID exe_base, address;
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
||||
/* Find the EXE base in the new process */
|
||||
exe_base = NULL;
|
||||
for (address = NULL ;
|
||||
VirtualQueryEx(process_handle, address, &mbi, sizeof(mbi)) ;
|
||||
address = (char *)mbi.BaseAddress + mbi.RegionSize) {
|
||||
if ((mbi.Type == SEC_IMAGE) &&
|
||||
read_nt_header(process_handle, &mbi, nt_header) &&
|
||||
!(nt_header->FileHeader.Characteristics & IMAGE_FILE_DLL)) {
|
||||
exe_base = mbi.BaseAddress;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return exe_base;
|
||||
}
|
||||
|
||||
static BOOL are_imports_resolved(HANDLE process_handle, PVOID module_base, IMAGE_NT_HEADERS *nt_header)
|
||||
{
|
||||
BOOL ret;
|
||||
IMAGE_IMPORT_DESCRIPTOR iid;
|
||||
ULONG_PTR orig_iat_entry_value, iat_entry_value;
|
||||
|
||||
ok(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, "Import table VA is zero\n");
|
||||
ok(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size, "Import table Size is zero\n");
|
||||
|
||||
if (!nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress ||
|
||||
!nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
|
||||
return FALSE;
|
||||
|
||||
/* Read the first IID */
|
||||
ret = ReadProcessMemory(process_handle,
|
||||
(char *)module_base + nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
|
||||
&iid, sizeof(iid), NULL);
|
||||
ok(ret, "Failed to read remote module IID (%d)\n", GetLastError());
|
||||
|
||||
/* Validate the IID is present and not a bound import, and that we have
|
||||
an OriginalFirstThunk to compare with */
|
||||
ok(iid.Name, "Module first IID does not have a Name\n");
|
||||
ok(iid.FirstThunk, "Module first IID does not have a FirstThunk\n");
|
||||
ok(!iid.TimeDateStamp, "Module first IID is a bound import (UNSUPPORTED for current test)\n");
|
||||
ok(iid.OriginalFirstThunk, "Module first IID does not have an OriginalFirstThunk (UNSUPPORTED for current test)\n");
|
||||
|
||||
/* Read a single IAT entry from the FirstThunk */
|
||||
ret = ReadProcessMemory(process_handle, (char *)module_base + iid.FirstThunk,
|
||||
&iat_entry_value, sizeof(iat_entry_value), NULL);
|
||||
ok(ret, "Failed to read IAT entry from FirstThunk (%d)\n", GetLastError());
|
||||
ok(iat_entry_value, "IAT entry in FirstThunk is NULL\n");
|
||||
|
||||
/* Read a single IAT entry from the OriginalFirstThunk */
|
||||
ret = ReadProcessMemory(process_handle, (char *)module_base + iid.OriginalFirstThunk,
|
||||
&orig_iat_entry_value, sizeof(orig_iat_entry_value), NULL);
|
||||
ok(ret, "Failed to read IAT entry from OriginalFirstThunk (%d)\n", GetLastError());
|
||||
ok(orig_iat_entry_value, "IAT entry in OriginalFirstThunk is NULL\n");
|
||||
|
||||
return iat_entry_value != orig_iat_entry_value;
|
||||
}
|
||||
|
||||
static void test_SuspendProcessNewThread(void)
|
||||
{
|
||||
BOOL ret;
|
||||
STARTUPINFOA si = {0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
PVOID exe_base, exit_thread_ptr;
|
||||
IMAGE_NT_HEADERS nt_header;
|
||||
HANDLE thread_handle = NULL;
|
||||
DWORD dret, exit_code = 0;
|
||||
CONTEXT ctx;
|
||||
|
||||
exit_thread_ptr = GetProcAddress(hkernel32, "ExitThread");
|
||||
ok(exit_thread_ptr != NULL, "GetProcAddress ExitThread failed\n");
|
||||
|
||||
si.cb = sizeof(si);
|
||||
ret = CreateProcessA(NULL, selfname, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
|
||||
ok(ret, "Failed to create process (%d)\n", GetLastError());
|
||||
|
||||
exe_base = get_process_exe(pi.hProcess, &nt_header);
|
||||
ok(exe_base != NULL, "Could not find EXE in remote process\n");
|
||||
|
||||
ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header);
|
||||
ok(!ret, "IAT entry resolved prematurely\n");
|
||||
|
||||
thread_handle = CreateRemoteThread(pi.hProcess, NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE)exit_thread_ptr,
|
||||
(PVOID)(ULONG_PTR)0x1234, CREATE_SUSPENDED, NULL);
|
||||
ok(thread_handle != NULL, "Could not create remote thread (%d)\n", GetLastError());
|
||||
|
||||
ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header);
|
||||
ok(!ret, "IAT entry resolved prematurely\n");
|
||||
|
||||
ctx.ContextFlags = CONTEXT_ALL;
|
||||
ret = GetThreadContext( thread_handle, &ctx );
|
||||
ok( ret, "Failed retrieving remote thread context (%d)\n", GetLastError() );
|
||||
ok( ctx.ContextFlags == CONTEXT_ALL, "wrong flags %x\n", ctx.ContextFlags );
|
||||
#ifdef __x86_64__
|
||||
ok( !ctx.Rax, "rax is not zero %lx\n", ctx.Rax );
|
||||
ok( !ctx.Rbx, "rbx is not zero %lx\n", ctx.Rbx );
|
||||
ok( ctx.Rcx == (ULONG_PTR)exit_thread_ptr, "wrong rcx %lx/%p\n", ctx.Rcx, exit_thread_ptr );
|
||||
ok( ctx.Rdx == 0x1234, "wrong rdx %lx\n", ctx.Rdx );
|
||||
ok( !ctx.Rsi, "rsi is not zero %lx\n", ctx.Rsi );
|
||||
ok( !ctx.Rdi, "rdi is not zero %lx\n", ctx.Rdi );
|
||||
ok( !ctx.Rbp, "rbp is not zero %lx\n", ctx.Rbp );
|
||||
ok( !ctx.R8, "r8 is not zero %lx\n", ctx.R8 );
|
||||
ok( !ctx.R9, "r9 is not zero %lx\n", ctx.R9 );
|
||||
ok( !ctx.R10, "r10 is not zero %lx\n", ctx.R10 );
|
||||
ok( !ctx.R11, "r11 is not zero %lx\n", ctx.R11 );
|
||||
ok( !ctx.R12, "r12 is not zero %lx\n", ctx.R12 );
|
||||
ok( !ctx.R13, "r13 is not zero %lx\n", ctx.R13 );
|
||||
ok( !ctx.R14, "r14 is not zero %lx\n", ctx.R14 );
|
||||
ok( !ctx.R15, "r15 is not zero %lx\n", ctx.R15 );
|
||||
ok( !((ctx.Rsp + 0x28) & 0xfff), "rsp is not at top of stack page %lx\n", ctx.Rsp );
|
||||
ok( ctx.EFlags == 0x200, "wrong flags %08x\n", ctx.EFlags );
|
||||
ok( ctx.MxCsr == 0x1f80, "wrong mxcsr %08x\n", ctx.MxCsr );
|
||||
ok( ctx.FltSave.ControlWord == 0x27f, "wrong control %08x\n", ctx.FltSave.ControlWord );
|
||||
#else
|
||||
ok( !ctx.Ebp || broken(ctx.Ebp), /* winxp */ "ebp is not zero %08x\n", ctx.Ebp );
|
||||
if (!ctx.Ebp) /* winxp is completely different */
|
||||
{
|
||||
ok( !ctx.Ecx, "ecx is not zero %08x\n", ctx.Ecx );
|
||||
ok( !ctx.Edx, "edx is not zero %08x\n", ctx.Edx );
|
||||
ok( !ctx.Esi, "esi is not zero %08x\n", ctx.Esi );
|
||||
ok( !ctx.Edi, "edi is not zero %08x\n", ctx.Edi );
|
||||
}
|
||||
ok( ctx.Eax == (ULONG_PTR)exit_thread_ptr, "wrong eax %08x/%p\n", ctx.Eax, exit_thread_ptr );
|
||||
ok( ctx.Ebx == 0x1234, "wrong ebx %08x\n", ctx.Ebx );
|
||||
ok( !((ctx.Esp + 0x10) & 0xfff) || broken( !((ctx.Esp + 4) & 0xfff) ), /* winxp, w2k3 */
|
||||
"esp is not at top of stack page or properly aligned: %08x\n", ctx.Esp );
|
||||
ok( (ctx.EFlags & ~2) == 0x200, "wrong flags %08x\n", ctx.EFlags );
|
||||
ok( (WORD)ctx.FloatSave.ControlWord == 0x27f, "wrong control %08x\n", ctx.FloatSave.ControlWord );
|
||||
ok( *(WORD *)ctx.ExtendedRegisters == 0x27f, "wrong control %08x\n", *(WORD *)ctx.ExtendedRegisters );
|
||||
#endif
|
||||
|
||||
ResumeThread( thread_handle );
|
||||
dret = WaitForSingleObject(thread_handle, 60000);
|
||||
ok(dret == WAIT_OBJECT_0, "Waiting for remote thread failed (%d)\n", GetLastError());
|
||||
ret = GetExitCodeThread(thread_handle, &exit_code);
|
||||
ok(ret, "Failed to retrieve remote thread exit code (%d)\n", GetLastError());
|
||||
ok(exit_code == 0x1234, "Invalid remote thread exit code\n");
|
||||
|
||||
ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header);
|
||||
ok(ret, "EXE IAT entry not resolved\n");
|
||||
|
||||
if (thread_handle)
|
||||
CloseHandle(thread_handle);
|
||||
|
||||
TerminateProcess(pi.hProcess, 0);
|
||||
WaitForSingleObject(pi.hProcess, 10000);
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
|
||||
static void test_SuspendProcessState(void)
|
||||
{
|
||||
struct pipe_params
|
||||
{
|
||||
ULONG pipe_write_buf;
|
||||
ULONG pipe_read_buf;
|
||||
ULONG bytes_returned;
|
||||
CHAR pipe_name[MAX_PATH];
|
||||
};
|
||||
|
||||
#ifdef __x86_64__
|
||||
struct remote_rop_chain
|
||||
{
|
||||
void *exit_process_ptr;
|
||||
ULONG_PTR home_rcx;
|
||||
ULONG_PTR home_rdx;
|
||||
ULONG_PTR home_r8;
|
||||
ULONG_PTR home_r9;
|
||||
ULONG_PTR pipe_read_buf_size;
|
||||
ULONG_PTR bytes_returned;
|
||||
ULONG_PTR timeout;
|
||||
};
|
||||
#else
|
||||
struct remote_rop_chain
|
||||
{
|
||||
void *exit_process_ptr;
|
||||
ULONG_PTR pipe_name;
|
||||
ULONG_PTR pipe_write_buf;
|
||||
ULONG_PTR pipe_write_buf_size;
|
||||
ULONG_PTR pipe_read_buf;
|
||||
ULONG_PTR pipe_read_buf_size;
|
||||
ULONG_PTR bytes_returned;
|
||||
ULONG_PTR timeout;
|
||||
void *unreached_ret;
|
||||
ULONG_PTR exit_code;
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char pipe_name[] = "\\\\.\\pipe\\TestPipe";
|
||||
static const ULONG pipe_write_magic = 0x454e4957;
|
||||
STARTUPINFOA si = {0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
PVOID exe_base, remote_pipe_params, exit_process_ptr,
|
||||
call_named_pipe_a;
|
||||
IMAGE_NT_HEADERS nt_header;
|
||||
struct pipe_params pipe_params;
|
||||
struct remote_rop_chain rop_chain;
|
||||
CONTEXT ctx;
|
||||
HANDLE server_pipe_handle;
|
||||
BOOL pipe_connected;
|
||||
ULONG pipe_magic, numb;
|
||||
BOOL ret;
|
||||
void *entry_ptr, *peb_ptr;
|
||||
PEB child_peb;
|
||||
|
||||
exit_process_ptr = GetProcAddress(hkernel32, "ExitProcess");
|
||||
ok(exit_process_ptr != NULL, "GetProcAddress ExitProcess failed\n");
|
||||
|
||||
call_named_pipe_a = GetProcAddress(hkernel32, "CallNamedPipeA");
|
||||
ok(call_named_pipe_a != NULL, "GetProcAddress CallNamedPipeA failed\n");
|
||||
|
||||
si.cb = sizeof(si);
|
||||
ret = CreateProcessA(NULL, selfname, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
|
||||
ok(ret, "Failed to create process (%d)\n", GetLastError());
|
||||
|
||||
exe_base = get_process_exe(pi.hProcess, &nt_header);
|
||||
/* Make sure we found the EXE in the new process */
|
||||
ok(exe_base != NULL, "Could not find EXE in remote process\n");
|
||||
|
||||
ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header);
|
||||
ok(!ret, "IAT entry resolved prematurely\n");
|
||||
|
||||
server_pipe_handle = CreateNamedPipeA(pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 0x20000, 0x20000,
|
||||
0, NULL);
|
||||
ok(server_pipe_handle != INVALID_HANDLE_VALUE, "Failed to create communication pipe (%d)\n", GetLastError());
|
||||
|
||||
/* Set up the remote process environment */
|
||||
ctx.ContextFlags = CONTEXT_ALL;
|
||||
ret = GetThreadContext(pi.hThread, &ctx);
|
||||
ok(ret, "Failed retrieving remote thread context (%d)\n", GetLastError());
|
||||
ok( ctx.ContextFlags == CONTEXT_ALL, "wrong flags %x\n", ctx.ContextFlags );
|
||||
|
||||
remote_pipe_params = VirtualAllocEx(pi.hProcess, NULL, sizeof(pipe_params), MEM_COMMIT, PAGE_READWRITE);
|
||||
ok(remote_pipe_params != NULL, "Failed allocating memory in remote process (%d)\n", GetLastError());
|
||||
|
||||
pipe_params.pipe_write_buf = pipe_write_magic;
|
||||
pipe_params.pipe_read_buf = 0;
|
||||
pipe_params.bytes_returned = 0;
|
||||
strcpy(pipe_params.pipe_name, pipe_name);
|
||||
|
||||
ret = WriteProcessMemory(pi.hProcess, remote_pipe_params,
|
||||
&pipe_params, sizeof(pipe_params), NULL);
|
||||
ok(ret, "Failed to write to remote process memory (%d)\n", GetLastError());
|
||||
|
||||
#ifdef __x86_64__
|
||||
ok( !ctx.Rax, "rax is not zero %lx\n", ctx.Rax );
|
||||
ok( !ctx.Rbx, "rbx is not zero %lx\n", ctx.Rbx );
|
||||
ok( !ctx.Rsi, "rsi is not zero %lx\n", ctx.Rsi );
|
||||
ok( !ctx.Rdi, "rdi is not zero %lx\n", ctx.Rdi );
|
||||
ok( !ctx.Rbp, "rbp is not zero %lx\n", ctx.Rbp );
|
||||
ok( !ctx.R8, "r8 is not zero %lx\n", ctx.R8 );
|
||||
ok( !ctx.R9, "r9 is not zero %lx\n", ctx.R9 );
|
||||
ok( !ctx.R10, "r10 is not zero %lx\n", ctx.R10 );
|
||||
ok( !ctx.R11, "r11 is not zero %lx\n", ctx.R11 );
|
||||
ok( !ctx.R12, "r12 is not zero %lx\n", ctx.R12 );
|
||||
ok( !ctx.R13, "r13 is not zero %lx\n", ctx.R13 );
|
||||
ok( !ctx.R14, "r14 is not zero %lx\n", ctx.R14 );
|
||||
ok( !ctx.R15, "r15 is not zero %lx\n", ctx.R15 );
|
||||
ok( !((ctx.Rsp + 0x28) & 0xfff), "rsp is not at top of stack page %lx\n", ctx.Rsp );
|
||||
ok( ctx.EFlags == 0x200, "wrong flags %08x\n", ctx.EFlags );
|
||||
ok( ctx.MxCsr == 0x1f80, "wrong mxcsr %08x\n", ctx.MxCsr );
|
||||
ok( ctx.FltSave.ControlWord == 0x27f, "wrong control %08x\n", ctx.FltSave.ControlWord );
|
||||
entry_ptr = (void *)ctx.Rcx;
|
||||
peb_ptr = (void *)ctx.Rdx;
|
||||
|
||||
rop_chain.exit_process_ptr = exit_process_ptr;
|
||||
ctx.Rcx = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_name);
|
||||
ctx.Rdx = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_write_buf);
|
||||
ctx.R8 = sizeof(pipe_params.pipe_write_buf);
|
||||
ctx.R9 = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_read_buf);
|
||||
rop_chain.pipe_read_buf_size = sizeof(pipe_params.pipe_read_buf);
|
||||
rop_chain.bytes_returned = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, bytes_returned);
|
||||
rop_chain.timeout = 10000;
|
||||
|
||||
ctx.Rip = (ULONG_PTR)call_named_pipe_a;
|
||||
ctx.Rsp -= sizeof(rop_chain);
|
||||
ret = WriteProcessMemory(pi.hProcess, (void *)ctx.Rsp, &rop_chain, sizeof(rop_chain), NULL);
|
||||
ok(ret, "Failed to write to remote process thread stack (%d)\n", GetLastError());
|
||||
#else
|
||||
ok( !ctx.Ebp || broken(ctx.Ebp), /* winxp */ "ebp is not zero %08x\n", ctx.Ebp );
|
||||
if (!ctx.Ebp) /* winxp is completely different */
|
||||
{
|
||||
ok( !ctx.Ecx, "ecx is not zero %08x\n", ctx.Ecx );
|
||||
ok( !ctx.Edx, "edx is not zero %08x\n", ctx.Edx );
|
||||
ok( !ctx.Esi, "esi is not zero %08x\n", ctx.Esi );
|
||||
ok( !ctx.Edi, "edi is not zero %08x\n", ctx.Edi );
|
||||
}
|
||||
ok( !((ctx.Esp + 0x10) & 0xfff) || broken( !((ctx.Esp + 4) & 0xfff) ), /* winxp, w2k3 */
|
||||
"esp is not at top of stack page or properly aligned: %08x\n", ctx.Esp );
|
||||
ok( (ctx.EFlags & ~2) == 0x200, "wrong flags %08x\n", ctx.EFlags );
|
||||
ok( (WORD)ctx.FloatSave.ControlWord == 0x27f, "wrong control %08x\n", ctx.FloatSave.ControlWord );
|
||||
ok( *(WORD *)ctx.ExtendedRegisters == 0x27f, "wrong control %08x\n", *(WORD *)ctx.ExtendedRegisters );
|
||||
entry_ptr = (void *)ctx.Eax;
|
||||
peb_ptr = (void *)ctx.Ebx;
|
||||
|
||||
rop_chain.exit_process_ptr = exit_process_ptr;
|
||||
rop_chain.pipe_name = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_name);
|
||||
rop_chain.pipe_write_buf = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_write_buf);
|
||||
rop_chain.pipe_write_buf_size = sizeof(pipe_params.pipe_write_buf);
|
||||
rop_chain.pipe_read_buf = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_read_buf);
|
||||
rop_chain.pipe_read_buf_size = sizeof(pipe_params.pipe_read_buf);
|
||||
rop_chain.bytes_returned = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, bytes_returned);
|
||||
rop_chain.timeout = 10000;
|
||||
rop_chain.exit_code = 0;
|
||||
|
||||
ctx.Eip = (ULONG_PTR)call_named_pipe_a;
|
||||
ctx.Esp -= sizeof(rop_chain);
|
||||
ret = WriteProcessMemory(pi.hProcess, (void *)ctx.Esp, &rop_chain, sizeof(rop_chain), NULL);
|
||||
ok(ret, "Failed to write to remote process thread stack (%d)\n", GetLastError());
|
||||
#endif
|
||||
|
||||
ret = ReadProcessMemory( pi.hProcess, peb_ptr, &child_peb, sizeof(child_peb), NULL );
|
||||
ok( ret, "Failed to read PEB (%u)\n", GetLastError() );
|
||||
ok( child_peb.ImageBaseAddress == exe_base, "wrong base %p/%p\n",
|
||||
child_peb.ImageBaseAddress, exe_base );
|
||||
ok( entry_ptr == (char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint,
|
||||
"wrong entry point %p/%p\n", entry_ptr,
|
||||
(char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint );
|
||||
|
||||
ret = SetThreadContext(pi.hThread, &ctx);
|
||||
ok(ret, "Failed to set remote thread context (%d)\n", GetLastError());
|
||||
|
||||
ResumeThread(pi.hThread);
|
||||
|
||||
pipe_connected = ConnectNamedPipe(server_pipe_handle, NULL) || (GetLastError() == ERROR_PIPE_CONNECTED);
|
||||
ok(pipe_connected, "Pipe did not connect\n");
|
||||
|
||||
ret = ReadFile(server_pipe_handle, &pipe_magic, sizeof(pipe_magic), &numb, NULL);
|
||||
ok(ret, "Failed to read buffer from pipe (%d)\n", GetLastError());
|
||||
|
||||
ok(pipe_magic == pipe_write_magic, "Did not get the correct magic from the remote process\n");
|
||||
|
||||
/* Validate the Imports, at this point the thread in the new process should have
|
||||
initialized the EXE module imports and call each dll DllMain notifying it on
|
||||
the new thread in the process. */
|
||||
ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header);
|
||||
ok(ret, "EXE IAT is not resolved\n");
|
||||
|
||||
ret = WriteFile(server_pipe_handle, &pipe_magic, sizeof(pipe_magic), &numb, NULL);
|
||||
ok(ret, "Failed to write the magic back to the pipe (%d)\n", GetLastError());
|
||||
|
||||
CloseHandle(server_pipe_handle);
|
||||
TerminateProcess(pi.hProcess, 0);
|
||||
WaitForSingleObject(pi.hProcess, 10000);
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
#else
|
||||
static void test_SuspendProcessNewThread(void)
|
||||
{
|
||||
}
|
||||
static void test_SuspendProcessState(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void test_DetachStdHandles(void)
|
||||
{
|
||||
#ifndef _WIN64
|
||||
|
@ -3371,7 +3869,7 @@ static void test_ProcThreadAttributeList(void)
|
|||
ok(GetLastError() == ERROR_OBJECT_NAME_EXISTS, "got %d\n", GetLastError());
|
||||
|
||||
ret = pUpdateProcThreadAttribute(&list, 0, PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR, handles, sizeof(PROCESSOR_NUMBER), NULL, NULL);
|
||||
ok(ret || (!ret && GetLastError() == ERROR_NOT_SUPPORTED), "got %d gle %d\n", ret, GetLastError());
|
||||
ok(ret || GetLastError() == ERROR_NOT_SUPPORTED, "got %d gle %d\n", ret, GetLastError());
|
||||
|
||||
if (ret)
|
||||
{
|
||||
|
@ -3484,6 +3982,8 @@ START_TEST(process)
|
|||
test_GetActiveProcessorCount();
|
||||
test_largepages();
|
||||
test_ProcThreadAttributeList();
|
||||
test_SuspendProcessState();
|
||||
test_SuspendProcessNewThread();
|
||||
|
||||
/* things that can be tested:
|
||||
* lookup: check the way program to be executed is searched
|
||||
|
|
|
@ -18,7 +18,14 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "windows.h"
|
||||
#include "sddl.h"
|
||||
|
||||
#define KEY "ProfileInt"
|
||||
#define SECTION "Test"
|
||||
|
@ -526,6 +533,41 @@ static BOOL emptystr_ok(CHAR emptystr[MAX_PATH])
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_profile_directory_readonly(void)
|
||||
{
|
||||
BOOL ret;
|
||||
CHAR path_folder[MAX_PATH];
|
||||
CHAR path_file[MAX_PATH];
|
||||
const char *sddl_string_everyone_readonly = "D:PAI(A;;0x1200a9;;;WD)";
|
||||
SECURITY_ATTRIBUTES attributes = {0};
|
||||
char lpStruct[] = { 's', 't', 'r', 'i', 'n', 'g' };
|
||||
|
||||
attributes.nLength = sizeof(attributes);
|
||||
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(sddl_string_everyone_readonly, SDDL_REVISION_1, &attributes.lpSecurityDescriptor, NULL);
|
||||
ok(ret == TRUE, "ConvertStringSecurityDescriptorToSecurityDescriptor failed: %d\n", GetLastError());
|
||||
|
||||
GetTempPathA(MAX_PATH, path_folder);
|
||||
lstrcatA(path_folder, "wine-test");
|
||||
|
||||
strcpy(path_file, path_folder);
|
||||
lstrcatA(path_file, "\\tmp.ini");
|
||||
|
||||
ret = CreateDirectoryA(path_folder, &attributes);
|
||||
ok(ret == TRUE, "CreateDirectoryA failed: %d\n", GetLastError());
|
||||
|
||||
ret = WritePrivateProfileStringA("App", "key", "string", path_file);
|
||||
ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
|
||||
|
||||
ret = WritePrivateProfileSectionA("App", "key=string", path_file);
|
||||
ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
|
||||
|
||||
ret = WritePrivateProfileStructA("App", "key", lpStruct, sizeof(lpStruct), path_file);
|
||||
ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
|
||||
|
||||
ret = RemoveDirectoryA(path_folder);
|
||||
ok(ret == TRUE, "RemoveDirectoryA failed: %d\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_GetPrivateProfileString(const char *content, const char *descript)
|
||||
{
|
||||
DWORD ret, len;
|
||||
|
@ -1124,6 +1166,7 @@ START_TEST(profile)
|
|||
test_profile_existing();
|
||||
test_profile_delete_on_close();
|
||||
test_profile_refresh();
|
||||
test_profile_directory_readonly();
|
||||
test_GetPrivateProfileString(
|
||||
"[section1]\r\n"
|
||||
"name1=val1\r\n"
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
static const char filename[] = "test_.exe";
|
||||
static DWORD GLE;
|
||||
|
|
|
@ -18,24 +18,28 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#ifndef __REACTOS__
|
||||
#define _WIN32_WINNT 0x500
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winternl.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#ifdef __REACTOS__
|
||||
#define QueryDepthSList(x) RtlQueryDepthSList(x)
|
||||
#define InterlockedPushEntrySList(x,y) RtlInterlockedPushEntrySList(x,y)
|
||||
#define InterlockedPopEntrySList(x) RtlInterlockedPopEntrySList(x)
|
||||
#define InterlockedFlushSList(x) RtlInterlockedFlushSList(x)
|
||||
#endif
|
||||
|
||||
#undef __fastcall
|
||||
#define __fastcall __stdcall
|
||||
|
||||
static BOOL (WINAPI *pChangeTimerQueueTimer)(HANDLE, HANDLE, ULONG, ULONG);
|
||||
static HANDLE (WINAPI *pCreateTimerQueue)(void);
|
||||
static BOOL (WINAPI *pCreateTimerQueueTimer)(PHANDLE, HANDLE, WAITORTIMERCALLBACK,
|
||||
PVOID, DWORD, DWORD, ULONG);
|
||||
static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*,BOOL,LPCSTR);
|
||||
static BOOL (WINAPI *pDeleteTimerQueueEx)(HANDLE, HANDLE);
|
||||
static BOOL (WINAPI *pDeleteTimerQueueTimer)(HANDLE, HANDLE, HANDLE);
|
||||
static HANDLE (WINAPI *pOpenWaitableTimerA)(DWORD,BOOL,LPCSTR);
|
||||
static HANDLE (WINAPI *pCreateMemoryResourceNotification)(MEMORY_RESOURCE_NOTIFICATION_TYPE);
|
||||
static BOOL (WINAPI *pQueryMemoryResourceNotification)(HANDLE, PBOOL);
|
||||
static VOID (WINAPI *pInitOnceInitialize)(PINIT_ONCE);
|
||||
|
@ -106,25 +110,12 @@ static void init_fastcall_thunk(void)
|
|||
|
||||
static void test_signalandwait(void)
|
||||
{
|
||||
DWORD (WINAPI *pSignalObjectAndWait)(HANDLE, HANDLE, DWORD, BOOL);
|
||||
HMODULE kernel32;
|
||||
DWORD r;
|
||||
HANDLE event[2], semaphore[2], file;
|
||||
int i;
|
||||
|
||||
kernel32 = GetModuleHandleA("kernel32.dll");
|
||||
pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait");
|
||||
|
||||
if (!pSignalObjectAndWait)
|
||||
return;
|
||||
|
||||
/* invalid parameters */
|
||||
r = pSignalObjectAndWait(NULL, NULL, 0, 0);
|
||||
if (r == ERROR_INVALID_FUNCTION)
|
||||
{
|
||||
win_skip("SignalObjectAndWait is not implemented\n");
|
||||
return; /* Win98/ME */
|
||||
}
|
||||
r = SignalObjectAndWait(NULL, NULL, 0, 0);
|
||||
ok( r == WAIT_FAILED, "should fail\n");
|
||||
|
||||
event[0] = CreateEventW(NULL, 0, 0, NULL);
|
||||
|
@ -132,22 +123,22 @@ static void test_signalandwait(void)
|
|||
|
||||
ok( event[0] && event[1], "failed to create event flags\n");
|
||||
|
||||
r = pSignalObjectAndWait(event[0], NULL, 0, FALSE);
|
||||
r = SignalObjectAndWait(event[0], NULL, 0, FALSE);
|
||||
ok( r == WAIT_FAILED, "should fail\n");
|
||||
|
||||
r = pSignalObjectAndWait(NULL, event[0], 0, FALSE);
|
||||
r = SignalObjectAndWait(NULL, event[0], 0, FALSE);
|
||||
ok( r == WAIT_FAILED, "should fail\n");
|
||||
|
||||
|
||||
/* valid parameters */
|
||||
r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
|
||||
r = SignalObjectAndWait(event[0], event[1], 0, FALSE);
|
||||
ok( r == WAIT_OBJECT_0, "should succeed\n");
|
||||
|
||||
/* event[0] is now signalled - we repeat this test multiple times
|
||||
* to ensure that the wineserver handles this situation properly. */
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
|
||||
r = SignalObjectAndWait(event[0], event[0], 0, FALSE);
|
||||
ok(r == WAIT_OBJECT_0, "should succeed\n");
|
||||
}
|
||||
|
||||
|
@ -155,12 +146,12 @@ static void test_signalandwait(void)
|
|||
r = WaitForSingleObject(event[0], 0);
|
||||
ok( r == WAIT_TIMEOUT, "event was signalled\n");
|
||||
|
||||
r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
|
||||
r = SignalObjectAndWait(event[0], event[0], 0, FALSE);
|
||||
ok( r == WAIT_OBJECT_0, "should succeed\n");
|
||||
|
||||
/* clear event[1] and check for a timeout */
|
||||
ok(ResetEvent(event[1]), "failed to clear event[1]\n");
|
||||
r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
|
||||
r = SignalObjectAndWait(event[0], event[1], 0, FALSE);
|
||||
ok( r == WAIT_TIMEOUT, "should timeout\n");
|
||||
|
||||
CloseHandle(event[0]);
|
||||
|
@ -171,10 +162,10 @@ static void test_signalandwait(void)
|
|||
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);
|
||||
r = SignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
|
||||
ok( r == WAIT_OBJECT_0, "should succeed\n");
|
||||
|
||||
r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
|
||||
r = SignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
|
||||
ok( r == WAIT_FAILED, "should fail\n");
|
||||
|
||||
r = ReleaseSemaphore(semaphore[0],1,NULL);
|
||||
|
@ -189,7 +180,7 @@ static void test_signalandwait(void)
|
|||
/* try a registry key */
|
||||
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);
|
||||
r = SignalObjectAndWait(file, file, 0, FALSE);
|
||||
ok( r == WAIT_FAILED, "should fail\n");
|
||||
ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n");
|
||||
CloseHandle(file);
|
||||
|
@ -282,6 +273,16 @@ todo_wine
|
|||
ok(!hOpened, "OpenMutex succeeded\n");
|
||||
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hOpened = OpenMutexA(READ_CONTROL, FALSE, NULL);
|
||||
ok(!hOpened, "OpenMutex succeeded\n");
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hOpened = OpenMutexW(READ_CONTROL, FALSE, NULL);
|
||||
ok(!hOpened, "OpenMutex succeeded\n");
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hOpened = CreateMutexA(NULL, FALSE, "WineTestMutex");
|
||||
ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
|
||||
|
@ -535,6 +536,16 @@ static void test_event(void)
|
|||
ok( !handle2, "OpenEvent succeeded\n");
|
||||
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, NULL );
|
||||
ok( !handle2, "OpenEvent succeeded\n");
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = OpenEventW( EVENT_ALL_ACCESS, FALSE, NULL );
|
||||
ok( !handle2, "OpenEvent succeeded\n");
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
|
||||
|
||||
CloseHandle( handle );
|
||||
|
||||
/* resource notifications are events too */
|
||||
|
@ -604,6 +615,16 @@ static void test_semaphore(void)
|
|||
ok( !handle2, "OpenSemaphore succeeded\n");
|
||||
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, NULL );
|
||||
ok( !handle2, "OpenSemaphore succeeded\n");
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = OpenSemaphoreW( SEMAPHORE_ALL_ACCESS, FALSE, NULL );
|
||||
ok( !handle2, "OpenSemaphore succeeded\n");
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
|
||||
|
||||
CloseHandle( handle );
|
||||
}
|
||||
|
||||
|
@ -611,42 +632,44 @@ static void test_waitable_timer(void)
|
|||
{
|
||||
HANDLE handle, handle2;
|
||||
|
||||
if (!pCreateWaitableTimerA || !pOpenWaitableTimerA)
|
||||
{
|
||||
win_skip("{Create,Open}WaitableTimerA() is not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* test case sensitivity */
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
|
||||
handle = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
|
||||
ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError());
|
||||
ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
|
||||
handle2 = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
|
||||
ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
|
||||
ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
|
||||
CloseHandle( handle2 );
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
|
||||
handle2 = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
|
||||
ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
|
||||
ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
|
||||
CloseHandle( handle2 );
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
|
||||
handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
|
||||
ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError());
|
||||
CloseHandle( handle2 );
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
|
||||
handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
|
||||
ok( !handle2, "OpenWaitableTimer succeeded\n");
|
||||
ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
|
||||
GetLastError() == ERROR_INVALID_NAME, /* win98 */
|
||||
"wrong error %u\n", GetLastError());
|
||||
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, NULL );
|
||||
ok( !handle2, "OpenWaitableTimer failed with error %d\n", GetLastError());
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
handle2 = OpenWaitableTimerW( TIMER_ALL_ACCESS, FALSE, NULL );
|
||||
ok( !handle2, "OpenWaitableTimer failed with error %d\n", GetLastError());
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
|
||||
|
||||
CloseHandle( handle );
|
||||
}
|
||||
|
@ -776,7 +799,7 @@ static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
|
|||
SetLastError(0xdeadbeef);
|
||||
/* Note, XP SP2 does *not* do any deadlock checking, so passing
|
||||
INVALID_HANDLE_VALUE here will just hang. */
|
||||
ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
|
||||
ret = DeleteTimerQueueTimer(d->q, d->t, NULL);
|
||||
ok(!ret, "DeleteTimerQueueTimer\n");
|
||||
ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
|
||||
}
|
||||
|
@ -790,7 +813,7 @@ static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
|
|||
{
|
||||
/* Basically kill the timer since it won't have time to run
|
||||
again. */
|
||||
BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 10000, 0);
|
||||
BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 10000, 0);
|
||||
ok(ret, "ChangeTimerQueueTimer\n");
|
||||
}
|
||||
}
|
||||
|
@ -806,7 +829,7 @@ static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
|
|||
period of zero (run once), then ChangeTimerQueueTimer will
|
||||
fail if the timer is already flagged. Hence we really run
|
||||
only once. Otherwise we will run multiple times. */
|
||||
BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 50, 50);
|
||||
BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 50, 50);
|
||||
ok(ret, "ChangeTimerQueueTimer\n");
|
||||
++d->num_calls;
|
||||
}
|
||||
|
@ -838,15 +861,15 @@ static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
|
|||
|
||||
/* The delete will pend while we are in this callback. */
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
|
||||
ret = DeleteTimerQueueTimer(d->q, d->t, NULL);
|
||||
ok(!ret, "DeleteTimerQueueTimer\n");
|
||||
ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
|
||||
|
||||
ret = pCreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
|
||||
ret = CreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
ret = pDeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
|
||||
ret = DeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
|
||||
ok(ret, "DeleteTimerQueueTimer\n");
|
||||
|
||||
/* Now we stay alive by hanging around in the callback. */
|
||||
|
@ -862,35 +885,27 @@ static void test_timer_queue(void)
|
|||
HANDLE e, et1, et2;
|
||||
BOOL ret, ret0;
|
||||
|
||||
if (!pChangeTimerQueueTimer || !pCreateTimerQueue || !pCreateTimerQueueTimer
|
||||
|| !pDeleteTimerQueueEx || !pDeleteTimerQueueTimer)
|
||||
{
|
||||
win_skip("TimerQueue API not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Test asynchronous deletion of the queue. */
|
||||
q = pCreateTimerQueue();
|
||||
q = CreateTimerQueue();
|
||||
ok(q != NULL, "CreateTimerQueue\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueEx(q, NULL);
|
||||
ret = DeleteTimerQueueEx(q, NULL);
|
||||
ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
|
||||
"DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
|
||||
GetLastError());
|
||||
|
||||
/* Test synchronous deletion of the queue and running timers. */
|
||||
q = pCreateTimerQueue();
|
||||
q = CreateTimerQueue();
|
||||
ok(q != NULL, "CreateTimerQueue\n");
|
||||
|
||||
/* Not called. */
|
||||
t0 = NULL;
|
||||
n0 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t0, q, timer_queue_cb1, &n0, 0,
|
||||
300, 0);
|
||||
ret = CreateTimerQueueTimer(&t0, q, timer_queue_cb1, &n0, 0, 300, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t0 != NULL, "CreateTimerQueueTimer\n");
|
||||
ret0 = pDeleteTimerQueueTimer(q, t0, NULL);
|
||||
ret0 = DeleteTimerQueueTimer(q, t0, NULL);
|
||||
ok((!ret0 && GetLastError() == ERROR_IO_PENDING) ||
|
||||
broken(ret0), /* Win 2000 & XP & 2003 */
|
||||
"DeleteTimerQueueTimer ret=%d le=%u\n", ret0, GetLastError());
|
||||
|
@ -898,40 +913,35 @@ static void test_timer_queue(void)
|
|||
/* Called once. */
|
||||
t1 = NULL;
|
||||
n1 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
|
||||
0, 0);
|
||||
ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0, 0, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t1 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
/* A slow one. */
|
||||
t2 = NULL;
|
||||
n2 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
|
||||
100, 0);
|
||||
ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0, 100, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t2 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
/* A fast one. */
|
||||
t3 = NULL;
|
||||
n3 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
|
||||
10, 0);
|
||||
ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0, 10, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t3 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
/* Start really late (it won't start). */
|
||||
t4 = NULL;
|
||||
n4 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
|
||||
10, 0);
|
||||
ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000, 10, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t4 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
/* Start soon, but delay so long it won't run again. */
|
||||
t5 = NULL;
|
||||
n5 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
|
||||
10000, 0);
|
||||
ret = CreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0, 10000, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t5 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
|
@ -939,14 +949,14 @@ static void test_timer_queue(void)
|
|||
Sleep(500);
|
||||
|
||||
/* Test deleting a once-only timer. */
|
||||
ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
|
||||
ret = DeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
|
||||
ok(ret, "DeleteTimerQueueTimer\n");
|
||||
|
||||
/* A periodic timer. */
|
||||
ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
|
||||
ret = DeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
|
||||
ok(ret, "DeleteTimerQueueTimer\n");
|
||||
|
||||
ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
|
||||
ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
|
||||
ok(ret, "DeleteTimerQueueEx\n");
|
||||
todo_wine
|
||||
ok(n0 == 1 || broken(ret0 && n0 == 0), "Timer callback 0 expected 1 got %d\n", n0);
|
||||
|
@ -965,32 +975,30 @@ static void test_timer_queue(void)
|
|||
return;
|
||||
}
|
||||
|
||||
q = pCreateTimerQueue();
|
||||
q = CreateTimerQueue();
|
||||
ok(q != NULL, "CreateTimerQueue\n");
|
||||
|
||||
/* Run once and finish quickly (should be done when we delete it). */
|
||||
t1 = NULL;
|
||||
ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
|
||||
ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t1 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
/* Run once and finish slowly (shouldn't be done when we delete it). */
|
||||
t2 = NULL;
|
||||
ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0,
|
||||
0, 0);
|
||||
ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t2 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
/* Run once and finish quickly (should be done when we delete it). */
|
||||
t3 = NULL;
|
||||
ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
|
||||
ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t3 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
/* Run once and finish slowly (shouldn't be done when we delete it). */
|
||||
t4 = NULL;
|
||||
ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0,
|
||||
0, 0);
|
||||
ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t4 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
|
@ -1000,20 +1008,20 @@ static void test_timer_queue(void)
|
|||
/* DeleteTimerQueueTimer always returns PENDING with a NULL event,
|
||||
even if the timer is finished. */
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueTimer(q, t1, NULL);
|
||||
ret = DeleteTimerQueueTimer(q, t1, NULL);
|
||||
ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
|
||||
"DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
|
||||
GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueTimer(q, t2, NULL);
|
||||
ret = DeleteTimerQueueTimer(q, t2, NULL);
|
||||
ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
|
||||
ok(GetLastError() == ERROR_IO_PENDING,
|
||||
"DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
|
||||
GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueTimer(q, t3, et1);
|
||||
ret = DeleteTimerQueueTimer(q, t3, et1);
|
||||
ok(ret, "DeleteTimerQueueTimer call was expected to fail\n");
|
||||
ok(GetLastError() == 0xdeadbeef,
|
||||
"DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n",
|
||||
|
@ -1022,7 +1030,7 @@ static void test_timer_queue(void)
|
|||
"Timer destruction event not triggered\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueTimer(q, t4, et2);
|
||||
ret = DeleteTimerQueueTimer(q, t4, et2);
|
||||
ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
|
||||
ok(GetLastError() == ERROR_IO_PENDING,
|
||||
"DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
|
||||
|
@ -1031,7 +1039,7 @@ static void test_timer_queue(void)
|
|||
"Timer destruction event not triggered\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueEx(q, e);
|
||||
ret = DeleteTimerQueueEx(q, e);
|
||||
ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
|
||||
"DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
|
||||
GetLastError());
|
||||
|
@ -1040,25 +1048,23 @@ static void test_timer_queue(void)
|
|||
CloseHandle(e);
|
||||
|
||||
/* Test deleting/changing a timer in execution. */
|
||||
q = pCreateTimerQueue();
|
||||
q = CreateTimerQueue();
|
||||
ok(q != NULL, "CreateTimerQueue\n");
|
||||
|
||||
/* Test changing a once-only timer before it fires (this is allowed,
|
||||
whereas after it fires you cannot). */
|
||||
n1 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000,
|
||||
0, 0);
|
||||
ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000, 0, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t1 != NULL, "CreateTimerQueueTimer\n");
|
||||
ret = pChangeTimerQueueTimer(q, t1, 0, 0);
|
||||
ret = ChangeTimerQueueTimer(q, t1, 0, 0);
|
||||
ok(ret, "ChangeTimerQueueTimer\n");
|
||||
|
||||
d2.t = t2 = NULL;
|
||||
d2.num_calls = 0;
|
||||
d2.max_calls = 3;
|
||||
d2.q = q;
|
||||
ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10,
|
||||
10, 0);
|
||||
ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10, 10, 0);
|
||||
d2.t = t2;
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t2 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
@ -1067,8 +1073,7 @@ static void test_timer_queue(void)
|
|||
d3.num_calls = 0;
|
||||
d3.max_calls = 4;
|
||||
d3.q = q;
|
||||
ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10,
|
||||
10, 0);
|
||||
ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10, 10, 0);
|
||||
d3.t = t3;
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t3 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
@ -1076,15 +1081,14 @@ static void test_timer_queue(void)
|
|||
d4.t = t4 = NULL;
|
||||
d4.num_calls = 0;
|
||||
d4.q = q;
|
||||
ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10,
|
||||
0, 0);
|
||||
ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10, 0, 0);
|
||||
d4.t = t4;
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t4 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
Sleep(500);
|
||||
|
||||
ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
|
||||
ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
|
||||
ok(ret, "DeleteTimerQueueEx\n");
|
||||
ok(n1 == 1, "ChangeTimerQueueTimer\n");
|
||||
ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
|
||||
|
@ -1092,15 +1096,14 @@ static void test_timer_queue(void)
|
|||
ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
|
||||
|
||||
/* Test an obscure bug that was in the original implementation. */
|
||||
q = pCreateTimerQueue();
|
||||
q = CreateTimerQueue();
|
||||
ok(q != NULL, "CreateTimerQueue\n");
|
||||
|
||||
/* All the work is done in the callback. */
|
||||
d1.t = t1 = NULL;
|
||||
d1.num_calls = 0;
|
||||
d1.q = q;
|
||||
ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100,
|
||||
100, WT_EXECUTELONGFUNCTION);
|
||||
ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100, 100, WT_EXECUTELONGFUNCTION);
|
||||
d1.t = t1;
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t1 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
@ -1108,7 +1111,7 @@ static void test_timer_queue(void)
|
|||
Sleep(750);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueEx(q, NULL);
|
||||
ret = DeleteTimerQueueEx(q, NULL);
|
||||
ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
|
||||
"DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
|
||||
GetLastError());
|
||||
|
@ -1117,57 +1120,54 @@ static void test_timer_queue(void)
|
|||
/* Test functions on the default timer queue. */
|
||||
t1 = NULL;
|
||||
n1 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000,
|
||||
1000, 0);
|
||||
ret = CreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000, 1000, 0);
|
||||
ok(ret, "CreateTimerQueueTimer, default queue\n");
|
||||
ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
|
||||
|
||||
ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
|
||||
ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000);
|
||||
ok(ret, "ChangeTimerQueueTimer, default queue\n");
|
||||
|
||||
ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
|
||||
ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
|
||||
ok(ret, "DeleteTimerQueueTimer, default queue\n");
|
||||
|
||||
/* Try mixing default and non-default queues. Apparently this works. */
|
||||
q = pCreateTimerQueue();
|
||||
q = CreateTimerQueue();
|
||||
ok(q != NULL, "CreateTimerQueue\n");
|
||||
|
||||
t1 = NULL;
|
||||
n1 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000,
|
||||
1000, 0);
|
||||
ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000, 1000, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t1 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
t2 = NULL;
|
||||
n2 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000,
|
||||
1000, 0);
|
||||
ret = CreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000, 1000, 0);
|
||||
ok(ret, "CreateTimerQueueTimer\n");
|
||||
ok(t2 != NULL, "CreateTimerQueueTimer\n");
|
||||
|
||||
ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
|
||||
ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000);
|
||||
ok(ret, "ChangeTimerQueueTimer\n");
|
||||
|
||||
ret = pChangeTimerQueueTimer(q, t2, 2000, 2000);
|
||||
ret = ChangeTimerQueueTimer(q, t2, 2000, 2000);
|
||||
ok(ret, "ChangeTimerQueueTimer\n");
|
||||
|
||||
ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
|
||||
ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
|
||||
ok(ret, "DeleteTimerQueueTimer\n");
|
||||
|
||||
ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
|
||||
ret = DeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
|
||||
ok(ret, "DeleteTimerQueueTimer\n");
|
||||
|
||||
/* Try to delete the default queue? In any case: not allowed. */
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueEx(NULL, NULL);
|
||||
ret = DeleteTimerQueueEx(NULL, NULL);
|
||||
ok(!ret, "DeleteTimerQueueEx call was expected to fail\n");
|
||||
ok(GetLastError() == ERROR_INVALID_HANDLE,
|
||||
"DeleteTimerQueueEx, GetLastError: expected ERROR_INVALID_HANDLE, got %d\n",
|
||||
GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pDeleteTimerQueueEx(q, NULL);
|
||||
ret = DeleteTimerQueueEx(q, NULL);
|
||||
ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
|
||||
"DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
|
||||
GetLastError());
|
||||
|
@ -2645,15 +2645,6 @@ START_TEST(sync)
|
|||
HMODULE hdll = GetModuleHandleA("kernel32.dll");
|
||||
HMODULE hntdll = GetModuleHandleA("ntdll.dll");
|
||||
|
||||
pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer");
|
||||
pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue");
|
||||
pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer");
|
||||
pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
|
||||
pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx");
|
||||
pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer");
|
||||
pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
|
||||
pCreateMemoryResourceNotification = (void *)GetProcAddress(hdll, "CreateMemoryResourceNotification");
|
||||
pQueryMemoryResourceNotification = (void *)GetProcAddress(hdll, "QueryMemoryResourceNotification");
|
||||
pInitOnceInitialize = (void *)GetProcAddress(hdll, "InitOnceInitialize");
|
||||
pInitOnceExecuteOnce = (void *)GetProcAddress(hdll, "InitOnceExecuteOnce");
|
||||
pInitOnceBeginInitialize = (void *)GetProcAddress(hdll, "InitOnceBeginInitialize");
|
||||
|
|
|
@ -9,7 +9,6 @@ extern void func_change(void);
|
|||
extern void func_codepage(void);
|
||||
extern void func_comm(void);
|
||||
extern void func_console(void);
|
||||
extern void func_cpu(void);
|
||||
extern void func_debugger(void);
|
||||
extern void func_directory(void);
|
||||
extern void func_drive(void);
|
||||
|
|
|
@ -18,7 +18,27 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
/* Define _WIN32_WINNT to get SetThreadIdealProcessor on Windows */
|
||||
#ifndef __REACTOS__
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* the tests intentionally pass invalid pointers and need an exception handler */
|
||||
#define WINE_NO_INLINE_STRING
|
||||
|
||||
#include <ntstatus.h>
|
||||
#define WIN32_NO_STATUS
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winnt.h>
|
||||
#include <winerror.h>
|
||||
#include <winnls.h>
|
||||
#include <winternl.h>
|
||||
#include "wine/test.h"
|
||||
|
||||
/* THREAD_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
|
||||
#define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
|
||||
|
@ -1380,10 +1400,12 @@ static DWORD WINAPI LS_ThreadProc(LPVOID p)
|
|||
ok(LS_index0 != LS_index1, "%s failed\n", LS_AllocFuncName);
|
||||
|
||||
/* Both slots should be initialized to NULL */
|
||||
SetLastError(0xdeadbeef);
|
||||
val = LS_GetValueFunc(LS_index0);
|
||||
ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
|
||||
ok(val == NULL, "Slot not initialized correctly\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
val = LS_GetValueFunc(LS_index1);
|
||||
ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
|
||||
ok(val == NULL, "Slot not initialized correctly\n");
|
||||
|
@ -1392,10 +1414,12 @@ static DWORD WINAPI LS_ThreadProc(LPVOID p)
|
|||
|
||||
if (sync_threads_and_run_one(0, id))
|
||||
{
|
||||
SetLastError(0xdeadbeef);
|
||||
val = LS_GetValueFunc(LS_index0);
|
||||
ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
|
||||
ok(val == NULL, "Slot not initialized correctly\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
val = LS_GetValueFunc(LS_index1);
|
||||
ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
|
||||
ok(val == NULL, "Slot not initialized correctly\n");
|
||||
|
@ -1406,10 +1430,12 @@ static DWORD WINAPI LS_ThreadProc(LPVOID p)
|
|||
ret = LS_SetValueFunc(LS_index1, (LPVOID) 2);
|
||||
ok(ret, "%s failed\n", LS_SetValueFuncName);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
val = LS_GetValueFunc(LS_index0);
|
||||
ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
|
||||
ok(val == (LPVOID) 1, "Slot not initialized correctly\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
val = LS_GetValueFunc(LS_index1);
|
||||
ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
|
||||
ok(val == (LPVOID) 2, "Slot not initialized correctly\n");
|
||||
|
@ -1702,6 +1728,7 @@ static WORD get_thread_fpu_cw(void)
|
|||
res = CloseHandle(ctx.finished);
|
||||
ok(!!res, "Failed to close event handle, last error %#x.\n", GetLastError());
|
||||
|
||||
CloseHandle(thread);
|
||||
return ctx.cw;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "winternl.h"
|
||||
|
||||
static BOOL (WINAPI *pTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME);
|
||||
static BOOL (WINAPI *pSystemTimeToTzSpecificLocalTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME);
|
||||
|
|
|
@ -18,7 +18,13 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#ifndef __REACTOS__
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#endif
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
|
||||
|
||||
static void test_timer(void)
|
||||
{
|
||||
|
|
|
@ -18,7 +18,15 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "tlhelp32.h"
|
||||
#include "wine/test.h"
|
||||
#include "winuser.h"
|
||||
|
||||
static char selfname[MAX_PATH];
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,9 +18,11 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include <wine/ddk/ntddcdvd.h>
|
||||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
#include "winioctl.h"
|
||||
#include <stdio.h>
|
||||
#include "wine/ddk/ntddcdvd.h"
|
||||
|
||||
#include <pshpack1.h>
|
||||
struct COMPLETE_DVD_LAYER_DESCRIPTOR
|
||||
|
@ -258,7 +260,7 @@ static void test_GetVolumeNameForVolumeMountPointW(void)
|
|||
}
|
||||
|
||||
ret = pGetVolumeNameForVolumeMountPointW(path, volume, 0);
|
||||
ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n");
|
||||
ok(ret == FALSE, "GetVolumeNameForVolumeMountPointW succeeded\n");
|
||||
ok(GetLastError() == ERROR_FILENAME_EXCED_RANGE ||
|
||||
GetLastError() == ERROR_INVALID_PARAMETER, /* Vista */
|
||||
"wrong error, last=%d\n", GetLastError());
|
||||
|
|
Loading…
Reference in a new issue