wbemprox: Partially implement Win32_Process.Create method.
Fixes FunCom launcher failure to launch games. Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
09b0154ac1
commit
85abea6070
|
@ -312,6 +312,7 @@ static const struct column col_process[] =
|
|||
{ L"ThreadCount", CIM_UINT32 },
|
||||
{ L"WorkingSetSize", CIM_UINT64 },
|
||||
/* methods */
|
||||
{ L"Create", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
|
||||
{ L"GetOwner", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
|
||||
};
|
||||
static const struct column col_processor[] =
|
||||
|
@ -725,6 +726,7 @@ struct record_process
|
|||
UINT32 thread_count;
|
||||
UINT64 workingsetsize;
|
||||
/* methods */
|
||||
class_method *create;
|
||||
class_method *get_owner;
|
||||
};
|
||||
struct record_processor
|
||||
|
@ -892,6 +894,9 @@ static const struct record_param data_param[] =
|
|||
{ L"StdRegProv", L"CreateKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
|
||||
{ L"StdRegProv", L"CreateKey", 1, L"sSubKeyName", CIM_STRING },
|
||||
{ L"StdRegProv", L"CreateKey", -1, L"ReturnValue", CIM_UINT32 },
|
||||
{ L"StdRegProv", L"DeleteKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
|
||||
{ L"StdRegProv", L"DeleteKey", 1, L"sSubKeyName", CIM_STRING },
|
||||
{ L"StdRegProv", L"DeleteKey", -1, L"ReturnValue", CIM_UINT32 },
|
||||
{ L"StdRegProv", L"EnumKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
|
||||
{ L"StdRegProv", L"EnumKey", 1, L"sSubKeyName", CIM_STRING },
|
||||
{ L"StdRegProv", L"EnumKey", -1, L"ReturnValue", CIM_UINT32 },
|
||||
|
@ -916,13 +921,14 @@ static const struct record_param data_param[] =
|
|||
{ L"StdRegProv", L"SetDWORDValue", 1, L"sValueName", CIM_STRING },
|
||||
{ L"StdRegProv", L"SetDWORDValue", 1, L"uValue", CIM_UINT32 },
|
||||
{ L"StdRegProv", L"SetDWORDValue", -1, L"ReturnValue", CIM_UINT32 },
|
||||
{ L"StdRegProv", L"DeleteKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
|
||||
{ L"StdRegProv", L"DeleteKey", 1, L"sSubKeyName", CIM_STRING },
|
||||
{ L"StdRegProv", L"DeleteKey", -1, L"ReturnValue", CIM_UINT32 },
|
||||
{ L"SystemRestore", L"Disable", 1, L"Drive", CIM_STRING },
|
||||
{ L"SystemRestore", L"Disable", -1, L"ReturnValue", CIM_UINT32 },
|
||||
{ L"SystemRestore", L"Enable", 1, L"Drive", CIM_STRING },
|
||||
{ L"SystemRestore", L"Enable", -1, L"ReturnValue", CIM_UINT32 },
|
||||
{ L"Win32_Process", L"Create", 1, L"CommandLine", CIM_STRING },
|
||||
{ L"Win32_Process", L"Create", 1, L"CurrentDirectory", CIM_STRING },
|
||||
{ L"Win32_Process", L"Create", -1, L"ProcessId", CIM_UINT32 },
|
||||
{ L"Win32_Process", L"Create", -1, L"ReturnValue", CIM_UINT32 },
|
||||
{ L"Win32_Process", L"GetOwner", -1, L"ReturnValue", CIM_UINT32 },
|
||||
{ L"Win32_Process", L"GetOwner", -1, L"User", CIM_STRING },
|
||||
{ L"Win32_Process", L"GetOwner", -1, L"Domain", CIM_STRING },
|
||||
|
@ -3162,6 +3168,8 @@ static enum fill_status fill_process( struct table *table, const struct expr *co
|
|||
rec->pprocess_id = entry.th32ParentProcessID;
|
||||
rec->thread_count = entry.cntThreads;
|
||||
rec->workingsetsize = 0;
|
||||
/* methods */
|
||||
rec->create = process_create;
|
||||
rec->get_owner = process_get_owner;
|
||||
if (!match_row( table, row, cond, &status ))
|
||||
{
|
||||
|
|
|
@ -110,3 +110,113 @@ done:
|
|||
if (out_params) IWbemClassObject_Release( out_params );
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT process_create( IWbemClassObject *obj, IWbemContext *context, IWbemClassObject *in, IWbemClassObject **out )
|
||||
{
|
||||
VARIANT command_line, current_directory, startup_info;
|
||||
HRESULT ret = WBEM_E_INVALID_PARAMETER, hr;
|
||||
IWbemClassObject *sig, *out_params = NULL;
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFOW si;
|
||||
UINT32 error;
|
||||
VARIANT v;
|
||||
BOOL bret;
|
||||
CIMTYPE type;
|
||||
|
||||
FIXME("%p, %p, %p, %p stub\n", obj, context, in, out);
|
||||
|
||||
*out = NULL;
|
||||
|
||||
if ((hr = create_signature( L"Win32_Process", L"Create", PARAM_OUT, &sig ))) return hr;
|
||||
|
||||
VariantInit( &command_line );
|
||||
VariantInit( ¤t_directory );
|
||||
VariantInit( &startup_info );
|
||||
|
||||
if (FAILED(hr = IWbemClassObject_Get( in, L"CommandLine", 0, &command_line, &type, NULL ))
|
||||
|| V_VT( &command_line ) != VT_BSTR)
|
||||
WARN( "Invalid CommandLine, hr %#x, type %u.\n", hr, V_VT( &command_line ));
|
||||
else
|
||||
TRACE( "CommandLine %s.\n", debugstr_w( V_BSTR( &command_line )));
|
||||
|
||||
if (FAILED(hr = IWbemClassObject_Get( in, L"CurrentDirectory", 0, ¤t_directory, &type, NULL ))
|
||||
|| V_VT( ¤t_directory ) != VT_BSTR)
|
||||
WARN("Invalid CurrentDirectory, hr %#x, type %u.\n", hr, V_VT( ¤t_directory ));
|
||||
else
|
||||
TRACE( "CurrentDirectory %s.\n", debugstr_w( V_BSTR( ¤t_directory )));
|
||||
|
||||
if (SUCCEEDED(IWbemClassObject_Get( in, L"ProcessStartupInformation", 0, &startup_info, &type, NULL ))
|
||||
&& V_VT( &startup_info ) == VT_UNKNOWN && V_UNKNOWN( &startup_info ))
|
||||
FIXME( "ProcessStartupInformation is not implemented, vt_type %u, type %u, val %p.\n",
|
||||
V_VT( &startup_info ), type, V_UNKNOWN( &startup_info ));
|
||||
|
||||
if (out && (hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params )))
|
||||
{
|
||||
ret = hr;
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset( &si, 0, sizeof(si) );
|
||||
si.cb = sizeof(si);
|
||||
|
||||
if (V_VT( &command_line ) == VT_BSTR && V_BSTR( &command_line ))
|
||||
{
|
||||
bret = CreateProcessW( NULL, V_BSTR( &command_line ), NULL, NULL, FALSE, 0L,
|
||||
V_VT( ¤t_directory ) == VT_BSTR ? V_BSTR( ¤t_directory ) : NULL,
|
||||
NULL, &si, &pi );
|
||||
TRACE( "CreateProcessW ret %#x, GetLastError() %u.\n", bret, GetLastError() );
|
||||
if (bret)
|
||||
{
|
||||
CloseHandle( pi.hThread );
|
||||
CloseHandle( pi.hProcess );
|
||||
error = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
error = 9;
|
||||
break;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
error = 2;
|
||||
break;
|
||||
default:
|
||||
error = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bret = FALSE;
|
||||
error = 21;
|
||||
}
|
||||
|
||||
if (out)
|
||||
{
|
||||
VariantInit( &v );
|
||||
|
||||
V_VT( &v ) = VT_UI4;
|
||||
V_UI4( &v ) = pi.dwProcessId;
|
||||
|
||||
if (bret && (ret = IWbemClassObject_Put( out_params, L"ProcessId", 0, &v, 0 ))) goto done;
|
||||
|
||||
V_UI4( &v ) = error;
|
||||
if ((ret = IWbemClassObject_Put( out_params, L"ReturnValue", 0, &v, 0 ))) goto done;
|
||||
|
||||
*out = out_params;
|
||||
IWbemClassObject_AddRef( out_params );
|
||||
}
|
||||
ret = S_OK;
|
||||
|
||||
done:
|
||||
IWbemClassObject_Release( sig );
|
||||
if (out_params) IWbemClassObject_Release( out_params );
|
||||
VariantClear( &command_line );
|
||||
VariantClear( ¤t_directory );
|
||||
VariantClear( &startup_info );
|
||||
TRACE( "ret %#x.\n", ret );
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -453,6 +453,10 @@ static void test_Win32_Baseboard( IWbemServices *services )
|
|||
SysFreeString( wql );
|
||||
}
|
||||
|
||||
static void test_Win32_Process_created_process(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void test_Win32_Process( IWbemServices *services, BOOL use_full_path )
|
||||
{
|
||||
static const LONG expected_flavor = WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE |
|
||||
|
@ -460,15 +464,19 @@ static void test_Win32_Process( IWbemServices *services, BOOL use_full_path )
|
|||
WBEM_FLAVOR_ORIGIN_PROPAGATED;
|
||||
WCHAR full_path[MAX_COMPUTERNAME_LENGTH + ARRAY_SIZE( L"\\\\%s\\ROOT\\CIMV2:" )];
|
||||
BSTR class, method;
|
||||
IWbemClassObject *process, *sig_in, *sig_out, *out;
|
||||
IWbemClassObject *process, *sig_in, *sig_out, *out, *params;
|
||||
WCHAR cmdlineW[MAX_PATH + 64 + 1];
|
||||
IWbemQualifierSet *qualifiers;
|
||||
VARIANT retval, val;
|
||||
SAFEARRAY *names;
|
||||
LONG bound, i;
|
||||
DWORD full_path_len = 0;
|
||||
ULONG refcount;
|
||||
LONG flavor;
|
||||
CIMTYPE type;
|
||||
HRESULT hr;
|
||||
DWORD ret;
|
||||
HANDLE h;
|
||||
|
||||
if (use_full_path)
|
||||
{
|
||||
|
@ -511,6 +519,109 @@ static void test_Win32_Process( IWbemServices *services, BOOL use_full_path )
|
|||
ok( !sig_in, "Got unexpected sig_in %p.\n", sig_in );
|
||||
ok( !sig_out, "Got unexpected sig_out %p.\n", sig_out );
|
||||
|
||||
sig_in = (void *)0xdeadbeef;
|
||||
sig_out = (void *)0xdeadbeef;
|
||||
hr = IWbemClassObject_GetMethod( process, L"Create", 0, &sig_in, &sig_out );
|
||||
ok( hr == S_OK, "Got unexpected hr %#x\n", hr );
|
||||
ok( !!sig_in, "Got unexpected sig_in %p.\n", sig_in );
|
||||
ok( !!sig_out, "Got unexpected sig_out %p.\n", sig_out );
|
||||
|
||||
hr = IWbemClassObject_SpawnInstance( sig_in, 0, ¶ms );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
out = NULL;
|
||||
class = SysAllocString( L"Win32_Process" );
|
||||
method = SysAllocString( L"Create" );
|
||||
hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, params, &out, NULL );
|
||||
ok( hr == S_OK, "failed to execute method %08x\n", hr );
|
||||
SysFreeString( method );
|
||||
SysFreeString( class );
|
||||
|
||||
VariantInit( &retval );
|
||||
hr = IWbemClassObject_Get( out, L"ReturnValue", 0, &retval, &type, NULL );
|
||||
ok( hr == S_OK, "failed to get return value %08x\n", hr );
|
||||
ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
|
||||
ok( V_I4( &retval ) == 21, "unexpected error %u\n", V_I4( &retval ) );
|
||||
|
||||
IWbemClassObject_Release( out );
|
||||
|
||||
V_VT( &val ) = VT_BSTR;
|
||||
V_BSTR( &val ) = SysAllocString( L"unknown" );
|
||||
hr = IWbemClassObject_Put( params, L"CommandLine", 0, &val, 0 );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
VariantClear( &val );
|
||||
|
||||
out = NULL;
|
||||
class = SysAllocString( L"Win32_Process" );
|
||||
method = SysAllocString( L"Create" );
|
||||
hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, params, &out, NULL );
|
||||
ok( hr == S_OK, "failed to execute method %08x\n", hr );
|
||||
SysFreeString( method );
|
||||
SysFreeString( class );
|
||||
|
||||
VariantInit( &retval );
|
||||
hr = IWbemClassObject_Get( out, L"ReturnValue", 0, &retval, &type, NULL );
|
||||
ok( hr == S_OK, "failed to get return value %08x\n", hr );
|
||||
ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
|
||||
ok( V_I4( &retval ) == 9, "unexpected error %u\n", V_I4( &retval ) );
|
||||
|
||||
VariantInit( &retval );
|
||||
V_VT( &retval ) = VT_I4;
|
||||
hr = IWbemClassObject_Get( out, L"ProcessId", 0, &retval, &type, NULL );
|
||||
ok( hr == S_OK, "failed to get return value %08x\n", hr );
|
||||
todo_wine ok( V_VT( &retval ) == VT_NULL && type == CIM_UINT32, "unexpected variant type 0x%x, type %u\n",
|
||||
V_VT( &retval ), type );
|
||||
|
||||
IWbemClassObject_Release( out );
|
||||
|
||||
ret = GetModuleFileNameW( NULL, cmdlineW, MAX_PATH + 1 );
|
||||
ok( ret < MAX_PATH + 1, "Got unexpected ret %u.\n", ret );
|
||||
lstrcatW( cmdlineW, L" query created_process");
|
||||
V_VT( &val ) = VT_BSTR;
|
||||
V_BSTR( &val ) = SysAllocString( cmdlineW );
|
||||
hr = IWbemClassObject_Put( params, L"CommandLine", 0, &val, 0 );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
VariantClear( &val );
|
||||
|
||||
out = NULL;
|
||||
class = SysAllocString( L"Win32_Process" );
|
||||
method = SysAllocString( L"Create" );
|
||||
hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, params, &out, NULL );
|
||||
ok( hr == S_OK, "failed to execute method %08x\n", hr );
|
||||
SysFreeString( method );
|
||||
SysFreeString( class );
|
||||
|
||||
VariantInit( &retval );
|
||||
hr = IWbemClassObject_Get( out, L"ReturnValue", 0, &retval, &type, NULL );
|
||||
ok( hr == S_OK, "failed to get return value %08x\n", hr );
|
||||
ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
|
||||
ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
|
||||
|
||||
VariantInit( &retval );
|
||||
V_VT( &retval ) = VT_I4;
|
||||
hr = IWbemClassObject_Get( out, L"ProcessId", 0, &retval, &type, NULL );
|
||||
ok( hr == S_OK, "failed to get return value %08x\n", hr );
|
||||
ok( V_VT( &retval ) == VT_I4 && type == CIM_UINT32, "unexpected variant type 0x%x, type %u\n",
|
||||
V_VT( &retval ), type );
|
||||
ok( !!V_UI4( &retval ), "unexpected zero pid\n" );
|
||||
|
||||
IWbemClassObject_Release( out );
|
||||
|
||||
h = OpenProcess( SYNCHRONIZE, FALSE, V_UI4( &retval ));
|
||||
ok( !!h, "failed to open process %#x.\n", V_UI4( &retval ));
|
||||
|
||||
ret = WaitForSingleObject( h, INFINITE );
|
||||
ok( ret == WAIT_OBJECT_0, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError() );
|
||||
CloseHandle( h );
|
||||
|
||||
refcount = IWbemClassObject_Release( params );
|
||||
ok( !refcount, "Got unexpected refcount %u.\n", refcount );
|
||||
|
||||
refcount = IWbemClassObject_Release( sig_in );
|
||||
ok( !refcount, "Got unexpected refcount %u.\n", refcount );
|
||||
refcount = IWbemClassObject_Release( sig_out );
|
||||
ok( !refcount, "Got unexpected refcount %u.\n", refcount );
|
||||
|
||||
sig_in = (void*)0xdeadbeef;
|
||||
hr = IWbemClassObject_GetMethod( process, L"getowner", 0, &sig_in, NULL );
|
||||
ok( hr == S_OK, "failed to get GetOwner method %08x\n", hr );
|
||||
|
@ -1956,7 +2067,17 @@ START_TEST(query)
|
|||
IWbemLocator *locator;
|
||||
IWbemServices *services;
|
||||
DWORD authn_svc;
|
||||
char **argv;
|
||||
HRESULT hr;
|
||||
int argc;
|
||||
|
||||
argc = winetest_get_mainargs( &argv );
|
||||
if (argc >= 3)
|
||||
{
|
||||
if (!strcmp( argv[2], "created_process" ))
|
||||
test_Win32_Process_created_process();
|
||||
return;
|
||||
}
|
||||
|
||||
CoInitialize( NULL );
|
||||
CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
|
||||
|
|
|
@ -245,6 +245,7 @@ HRESULT EnumWbemClassObject_create(struct query *, LPVOID *) DECLSPEC_HIDDEN;
|
|||
HRESULT WbemQualifierSet_create(const WCHAR *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT process_get_owner(IWbemClassObject *obj, IWbemContext *context, IWbemClassObject *in, IWbemClassObject **out) DECLSPEC_HIDDEN;
|
||||
HRESULT process_create(IWbemClassObject *obj, IWbemContext *context, IWbemClassObject *in, IWbemClassObject **out) DECLSPEC_HIDDEN;
|
||||
HRESULT reg_create_key(IWbemClassObject *obj, IWbemContext *context, IWbemClassObject *in, IWbemClassObject **out) DECLSPEC_HIDDEN;
|
||||
HRESULT reg_enum_key(IWbemClassObject *obj, IWbemContext *context, IWbemClassObject *in, IWbemClassObject **out) DECLSPEC_HIDDEN;
|
||||
HRESULT reg_enum_values(IWbemClassObject *obj, IWbemContext *context, IWbemClassObject *in, IWbemClassObject **out) DECLSPEC_HIDDEN;
|
||||
|
|
Loading…
Reference in New Issue