From 92450cb4f2dc39f840599ee744c47325ae718478 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Fri, 4 Apr 2014 15:15:37 +0900 Subject: [PATCH] schedsvc: Add some tests for scheduler RPC API. --- configure | 1 + configure.ac | 1 + dlls/schedsvc/tests/Makefile.in | 8 + dlls/schedsvc/tests/rpcapi.c | 493 ++++++++++++++++++++++++++++++++ dlls/schedsvc/tests/schrpc.idl | 3 + 5 files changed, 506 insertions(+) create mode 100644 dlls/schedsvc/tests/Makefile.in create mode 100644 dlls/schedsvc/tests/rpcapi.c create mode 100644 dlls/schedsvc/tests/schrpc.idl diff --git a/configure b/configure index bc651bc8e20..416466bdcf1 100755 --- a/configure +++ b/configure @@ -17137,6 +17137,7 @@ wine_fn_config_dll sccbase enable_sccbase wine_fn_config_dll schannel enable_schannel wine_fn_config_test dlls/schannel/tests schannel_test wine_fn_config_dll schedsvc enable_schedsvc clean +wine_fn_config_test dlls/schedsvc/tests schedsvc_test clean wine_fn_config_dll scrrun enable_scrrun clean wine_fn_config_test dlls/scrrun/tests scrrun_test clean wine_fn_config_dll scsiport.sys enable_scsiport_sys diff --git a/configure.ac b/configure.ac index d5171843220..44d7224151d 100644 --- a/configure.ac +++ b/configure.ac @@ -3116,6 +3116,7 @@ WINE_CONFIG_DLL(sccbase) WINE_CONFIG_DLL(schannel) WINE_CONFIG_TEST(dlls/schannel/tests) WINE_CONFIG_DLL(schedsvc,,[clean]) +WINE_CONFIG_TEST(dlls/schedsvc/tests,[clean]) WINE_CONFIG_DLL(scrrun,,[clean]) WINE_CONFIG_TEST(dlls/scrrun/tests,[clean]) WINE_CONFIG_DLL(scsiport.sys) diff --git a/dlls/schedsvc/tests/Makefile.in b/dlls/schedsvc/tests/Makefile.in new file mode 100644 index 00000000000..f671f855bd8 --- /dev/null +++ b/dlls/schedsvc/tests/Makefile.in @@ -0,0 +1,8 @@ +TESTDLL = schedsvc.dll +IMPORTS = rpcrt4 + +C_SRCS = \ + rpcapi.c + +IDL_SRCS = \ + schrpc.idl diff --git a/dlls/schedsvc/tests/rpcapi.c b/dlls/schedsvc/tests/rpcapi.c new file mode 100644 index 00000000000..e1d21011416 --- /dev/null +++ b/dlls/schedsvc/tests/rpcapi.c @@ -0,0 +1,493 @@ +/* + * Copyright 2014 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include "schrpc.h" + +#include "wine/test.h" + +extern handle_t rpc_handle; + +static LONG CALLBACK rpc_exception_filter(EXCEPTION_POINTERS *ptrs) +{ + skip("Can't connect to Scheduler service: %#x\n", ptrs->ExceptionRecord->ExceptionCode); + + if (winetest_debug) + { + fprintf(stdout, "rpcapi: 0 tests executed (0 marked as todo, 0 failures), 1 skipped.\n"); + fflush(stdout); + } + ExitProcess(0); +} + +START_TEST(rpcapi) +{ + static unsigned char ncalrpc[] = "ncalrpc"; + static const WCHAR empty[] = { 0 }; + static const WCHAR Wine[] = { '\\','W','i','n','e',0 }; + static const WCHAR Wine_Folder1[] = { '\\','W','i','n','e','\\','F','o','l','d','e','r','1',0 }; + static const WCHAR Wine_Folder2[] = { '\\','W','i','n','e','\\','F','o','l','d','e','r','2',0 }; + static const WCHAR Folder1[] = { 'F','o','l','d','e','r','1',0 }; + static const WCHAR Folder2[] = { 'F','o','l','d','e','r','2',0 }; + static const WCHAR Wine_Task1[] = { '\\','W','i','n','e','\\','T','a','s','k','1',0 }; + static const WCHAR Wine_Task2[] = { '\\','W','i','n','e','\\','T','a','s','k','2',0 }; + static const WCHAR Wine_Task3[] = { '\\','W','i','n','e','\\','T','a','s','k','3',0 }; + static const WCHAR Wine_Folder1_Task1[] = { '\\','W','i','n','e','\\','F','o','l','d','e','r','1','\\','T','a','s','k','1',0 }; + static const WCHAR Task1[] = { 'T','a','s','k','1',0 }; + static const WCHAR Task2[] = { 'T','a','s','k','2',0 }; + static const WCHAR Task3[] = { 'T','a','s','k','3',0 }; + static const char xml1[] = + "\n" + "\n" + " \n" + " \"Task1\"\n" + " \n" + " \n" + " false\n" + " false\n" + " \n" + " \n" + " \n" + " \"task1.exe\"\n" + " \n" + " \n" + "\n"; + static const struct + { + DWORD flags, hr; + } create_new_task[] = + { + { 0, S_OK }, + { TASK_CREATE, S_OK }, + { TASK_UPDATE, 0x80070002 /* HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) */ }, + { TASK_CREATE | TASK_UPDATE, S_OK } + }; + static const struct + { + DWORD flags, hr; + } open_existing_task[] = + { + { 0, 0x800700b7 /* HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) */ }, + { TASK_CREATE, 0x800700b7 /* HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) */ }, + { TASK_UPDATE, S_OK }, + { TASK_CREATE | TASK_UPDATE, S_OK } + }; + WCHAR xmlW[sizeof(xml1)], *xml; + HRESULT hr; + DWORD version, start_index, count, i, enumed; + WCHAR *path; + TASK_XML_ERROR_INFO *info; + TASK_NAMES names; + unsigned char *binding_str; + PTOP_LEVEL_EXCEPTION_FILTER old_exception_filter; + + hr = RpcStringBindingComposeA(NULL, ncalrpc, NULL, NULL, NULL, &binding_str); + ok(hr == RPC_S_OK, "RpcStringBindingCompose error %#x\n", hr); + hr = RpcBindingFromStringBindingA(binding_str, &rpc_handle); + ok(hr == RPC_S_OK, "RpcBindingFromStringBinding error %#x\n", hr); + hr = RpcStringFreeA(&binding_str); + ok(hr == RPC_S_OK, "RpcStringFree error %#x\n", hr); + + /* widl generated RpcTryExcept/RpcExcept can't catch raised exceptions */ + old_exception_filter = SetUnhandledExceptionFilter(rpc_exception_filter); + + version = 0; + hr = SchRpcHighestVersion(&version); + ok(version == 0x10002 /* vista */ || version == 0x10003 /* win7 */ || version == 0x10004 /* win8 */, + "wrong version %#x\n", version); + + SetUnhandledExceptionFilter(old_exception_filter); + + hr = SchRpcCreateFolder(Wine_Folder1, NULL, 1); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + + hr = SchRpcCreateFolder(Wine_Folder1, NULL, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + hr = SchRpcCreateFolder(Wine_Folder1, NULL, 0); + ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr); + + hr = SchRpcCreateFolder(Wine_Folder2+1, empty, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + hr = SchRpcDelete(Wine+1, 0); + ok(hr == HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY), "expected ERROR_DIR_NOT_EMPTY, got %#x\n", hr); + + hr = SchRpcDelete(Wine_Folder1+1, 1); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + + hr = SchRpcDelete(Wine_Folder1+1, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + hr = SchRpcDelete(Wine_Folder2, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + hr = SchRpcDelete(Wine, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + hr = SchRpcDelete(Wine, 0); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "expected ERROR_FILE_NOT_FOUND, got %#x\n", hr); + + hr = SchRpcDelete(empty, 0); + ok(hr == E_ACCESSDENIED /* win7 */ || hr == E_INVALIDARG /* vista */, "expected E_ACCESSDENIED, got %#x\n", hr); + + hr = SchRpcCreateFolder(Wine, NULL, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + MultiByteToWideChar(CP_ACP, 0, xml1, -1, xmlW, sizeof(xmlW)/sizeof(xmlW[0])); + + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(Wine+1, xmlW, TASK_VALIDATE_ONLY, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(!path, "expected NULL, path %p\n", path); + ok(!info, "expected NULL, info %p\n", info); + + for (i = 0; i < sizeof(create_new_task)/sizeof(create_new_task[0]); i++) + { + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(Wine_Task1, xmlW, create_new_task[i].flags, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == create_new_task[i].hr, "%u: expected %#x, got %#x\n", i, create_new_task[i].hr, hr); + + if (hr == S_OK) + { + hr = SchRpcDelete(Wine_Task1, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(!info, "expected NULL, info %p\n", info); + MIDL_user_free(path); + } + } + + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(Wine_Task1, xmlW, TASK_VALIDATE_ONLY, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(!path, "expected NULL, path %p\n", path); + ok(!info, "expected NULL, info %p\n", info); + + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(NULL, xmlW, TASK_VALIDATE_ONLY, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(!path, "expected NULL, path %p\n", path); + ok(!info, "expected NULL, info %p\n", info); + + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(Wine_Folder1_Task1+1, xmlW, TASK_CREATE, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(!lstrcmpW(path, Wine_Folder1_Task1) /* win7 */ || !lstrcmpW(path, Wine_Folder1_Task1+1) /* vista */, + "expected \\Wine\\Folder1\\Task1, task actual path %s\n", wine_dbgstr_w(path)); + ok(!info, "expected NULL, info %p\n", info); + MIDL_user_free(path); + + for (i = 0; i < sizeof(open_existing_task)/sizeof(open_existing_task[0]); i++) + { + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(Wine_Folder1_Task1+1, xmlW, open_existing_task[i].flags, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == open_existing_task[i].hr, "%u: expected %#x, got %#x\n", i, open_existing_task[i].hr, hr); + if (hr == S_OK) + { + ok(!lstrcmpW(path, Wine_Folder1_Task1) /* win7 */ || !lstrcmpW(path, Wine_Folder1_Task1+1) /* vista */, + "expected \\Wine\\Folder1\\Task1, task actual path %s\n", wine_dbgstr_w(path)); + MIDL_user_free(path); + } + else + ok(!path, "%u: expected NULL, path %p\n", i, path); + ok(!info, "%u: expected NULL, info %p\n", i, info); + } + + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(Wine_Folder1_Task1+1, xmlW, TASK_CREATE, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr); + ok(!path, "expected NULL, path %p\n", path); + ok(!info, "expected NULL, info %p\n", info); + + count = 0; + xml = NULL; + hr = SchRpcRetrieveTask(Wine_Folder1_Task1, empty, &count, &xml); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + if (hr == S_OK) trace("%s\n", wine_dbgstr_w(xml)); + MIDL_user_free(xml); + + hr = SchRpcDelete(Wine_Folder1_Task1+1, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + hr = SchRpcDelete(Wine_Folder1+1, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + hr = SchRpcDelete(Wine+1, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumFolders(Wine, TASK_ENUM_HIDDEN, &start_index, 0, &count, &names); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "expected ERROR_FILE_NOT_FOUND, got %#x\n", hr); + ok(!count, "expected 0, got %u\n", count); + ok(!start_index, "expected 0, got %u\n", start_index); + ok(!names, "expected NULL, got %p\n", names); + + hr = SchRpcCreateFolder(Wine, NULL, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumFolders(Wine, 0, &start_index, 0, &count, &names); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(!count, "expected 0, got %u\n", count); + ok(!start_index, "expected 0, got %u\n", start_index); + ok(!names, "expected NULL, got %p\n", names); + + hr = SchRpcCreateFolder(Wine_Folder1, NULL, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + hr = SchRpcCreateFolder(Wine_Folder2, NULL, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumFolders(Wine, 0, &start_index, 0, &count, &names); + ok(hr == S_OK, "expected S_FALSE, got %#x\n", hr); + ok(count == 2, "expected 2, got %u\n", count); + ok(start_index == 2, "expected 2, got %u\n", start_index); + ok(names != NULL, "names should not be NULL\n"); + enumed = 0; + for (i = 0; i < count; i++) + { + if (!lstrcmpW(names[i], Folder1)) + enumed += 1; + else if (!lstrcmpW(names[i], Folder2)) + enumed += 2; + MIDL_user_free(names[i]); + } + MIDL_user_free(names); + ok(enumed == 3, "expected 3, got %u\n", enumed); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumFolders(Wine, 0, &start_index, 1, &count, &names); + ok(hr == S_FALSE, "expected S_FALSE, got %#x\n", hr); + ok(count == 1, "expected 1, got %u\n", count); + ok(start_index == 1, "expected 1, got %u\n", start_index); + ok(names != NULL, "names should not be NULL\n"); + ok(!lstrcmpW(names[0], Folder1), "expected Folder1, got %s\n", wine_dbgstr_w(names[0])); + MIDL_user_free(names[0]); + MIDL_user_free(names); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumFolders(Wine, 0, &start_index, 2, &count, &names); + ok(hr == S_FALSE, "expected S_FALSE, got %#x\n", hr); + ok(count == 2, "expected 2, got %u\n", count); + ok(start_index == 2, "expected 2, got %u\n", start_index); + ok(names != NULL, "names should not be NULL\n"); + enumed = 0; + for (i = 0; i < count; i++) + { + if (!lstrcmpW(names[i], Folder1)) + enumed += 1; + else if (!lstrcmpW(names[i], Folder2)) + enumed += 2; + MIDL_user_free(names[i]); + } + MIDL_user_free(names); + ok(enumed == 3, "expected 3, got %u\n", enumed); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumFolders(Wine, 0, &start_index, 10, &count, &names); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(count == 2, "expected 2, got %u\n", count); + ok(start_index == 2, "expected 2, got %u\n", start_index); + ok(names != NULL, "names should not be NULL\n"); + enumed = 0; + for (i = 0; i < count; i++) + { + if (!lstrcmpW(names[i], Folder1)) + enumed += 1; + else if (!lstrcmpW(names[i], Folder2)) + enumed += 2; + MIDL_user_free(names[i]); + } + MIDL_user_free(names); + ok(enumed == 3, "expected 3, got %u\n", enumed); + + start_index = 10; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumFolders(Wine, 0, &start_index, 0, &count, &names); + ok(hr == S_FALSE, "expected S_FALSE, got %#x\n", hr); + ok(!count, "expected 0, got %u\n", count); + ok(start_index == 10, "expected 10, got %u\n", start_index); + ok(!names, "expected NULL, got %p\n", names); + + hr = SchRpcDelete(Wine_Folder1+1, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + hr = SchRpcDelete(Wine_Folder2, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumTasks(Wine_Folder1, TASK_ENUM_HIDDEN, &start_index, 0, &count, &names); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "expected ERROR_FILE_NOT_FOUND, got %#x\n", hr); + ok(!count, "expected 0, got %u\n", count); + ok(!start_index, "expected 0, got %u\n", start_index); + ok(!names, "expected NULL, got %p\n", names); + + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(Wine_Task1+1, xmlW, TASK_CREATE, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(!lstrcmpW(path, Wine_Task1) /* win7 */ || !lstrcmpW(path, Wine_Task1+1) /* vista */, + "expected \\Wine\\Task1, task actual path %s\n", wine_dbgstr_w(path)); + ok(!info, "expected NULL, info %p\n", info); + MIDL_user_free(path); + + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(Wine_Task2, xmlW, TASK_CREATE, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(!lstrcmpW(path, Wine_Task2), "expected \\Wine\\Task2, task actual path %s\n", wine_dbgstr_w(path)); + ok(!info, "expected NULL, info %p\n", info); + MIDL_user_free(path); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumTasks(Wine, 0, &start_index, 0, &count, &names); + ok(hr == S_OK, "expected S_FALSE, got %#x\n", hr); + ok(count == 2, "expected 2, got %u\n", count); + ok(start_index == 2, "expected 2, got %u\n", start_index); + ok(names != NULL, "names should not be NULL\n"); + enumed = 0; + for (i = 0; i < count; i++) + { + if (!lstrcmpW(names[i], Task1)) + enumed += 1; + else if (!lstrcmpW(names[i], Task2)) + enumed += 2; + MIDL_user_free(names[i]); + } + MIDL_user_free(names); + ok(enumed == 3, "expected 3, got %u\n", enumed); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumTasks(Wine, 0, &start_index, 1, &count, &names); + ok(hr == S_FALSE, "expected S_FALSE, got %#x\n", hr); + ok(count == 1, "expected 1, got %u\n", count); + ok(start_index == 1, "expected 1, got %u\n", start_index); + ok(names != NULL, "names should not be NULL\n"); + ok(!lstrcmpW(names[0], Task1), "expected Task1, got %s\n", wine_dbgstr_w(names[0])); + MIDL_user_free(names[0]); + MIDL_user_free(names); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumTasks(Wine, 0, &start_index, 2, &count, &names); + ok(hr == S_FALSE, "expected S_FALSE, got %#x\n", hr); + ok(count == 2, "expected 2, got %u\n", count); + ok(start_index == 2, "expected 2, got %u\n", start_index); + ok(names != NULL, "names should not be NULL\n"); + enumed = 0; + for (i = 0; i < count; i++) + { + if (!lstrcmpW(names[i], Task1)) + enumed += 1; + else if (!lstrcmpW(names[i], Task2)) + enumed += 2; + MIDL_user_free(names[i]); + } + MIDL_user_free(names); + ok(enumed == 3, "expected 3, got %u\n", enumed); + + start_index = 0; + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumTasks(Wine, 0, &start_index, 10, &count, &names); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(count == 2, "expected 2, got %u\n", count); + ok(start_index == 2, "expected 2, got %u\n", start_index); + ok(names != NULL, "names should not be NULL\n"); + enumed = 0; + for (i = 0; i < count; i++) + { + if (!lstrcmpW(names[i], Task1)) + enumed += 1; + else if (!lstrcmpW(names[i], Task2)) + enumed += 2; + MIDL_user_free(names[i]); + } + MIDL_user_free(names); + ok(enumed == 3, "expected 3, got %u\n", enumed); + + path = NULL; + info = NULL; + hr = SchRpcRegisterTask(Wine_Task3+1, xmlW, TASK_CREATE, NULL, TASK_LOGON_NONE, 0, NULL, &path, &info); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(!lstrcmpW(path, Wine_Task3) /* win7 */ || !lstrcmpW(path, Wine_Task3+1) /* vista */, + "expected \\Wine\\Task3, task actual path %s\n", wine_dbgstr_w(path)); + ok(!info, "expected NULL, info %p\n", info); + MIDL_user_free(path); + + count = 0xdeadbeef; + names = NULL; + hr = SchRpcEnumTasks(Wine+1, 0, &start_index, 10, &count, &names); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + ok(count == 1, "expected 1, got %u\n", count); + ok(start_index == 3, "expected 3, got %u\n", start_index); + ok(names != NULL, "names should not be NULL\n"); + ok(!lstrcmpW(names[0], Task3), "expected Task3, got %s\n", wine_dbgstr_w(names[0])); + MIDL_user_free(names[0]); + MIDL_user_free(names); + + hr = SchRpcDelete(Wine_Task1+1, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + hr = SchRpcDelete(Wine_Task2+1, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + hr = SchRpcDelete(Wine_Task3+1, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + hr = SchRpcDelete(Wine, 0); + ok(hr == S_OK, "expected S_OK, got %#x\n", hr); + + hr = RpcBindingFree(&rpc_handle); + ok(hr == RPC_S_OK, "RpcBindingFree error %#x\n", hr); +} + +void __RPC_FAR *__RPC_USER MIDL_user_allocate(SIZE_T n) +{ + return HeapAlloc(GetProcessHeap(), 0, n); +} + +void __RPC_USER MIDL_user_free(void __RPC_FAR *p) +{ + HeapFree(GetProcessHeap(), 0, p); +} diff --git a/dlls/schedsvc/tests/schrpc.idl b/dlls/schedsvc/tests/schrpc.idl new file mode 100644 index 00000000000..d8bca06c90c --- /dev/null +++ b/dlls/schedsvc/tests/schrpc.idl @@ -0,0 +1,3 @@ +#pragma makedep client + +#include "wine/schrpc.idl"