Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
46cbc360
Commit
46cbc360
authored
May 16, 2013
by
Hans Leidekker
Committed by
Alexandre Julliard
May 16, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wbemprox: Add support for asynchronous queries.
parent
633c3cb0
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
248 additions
and
11 deletions
+248
-11
services.c
dlls/wbemprox/services.c
+208
-8
query.c
dlls/wbemprox/tests/query.c
+33
-3
wbemcli.idl
include/wbemcli.idl
+7
-0
No files found.
dlls/wbemprox/services.c
View file @
46cbc360
...
...
@@ -135,11 +135,68 @@ static const IClientSecurityVtbl client_security_vtbl =
IClientSecurity
client_security
=
{
&
client_security_vtbl
};
struct
async_header
{
IWbemObjectSink
*
sink
;
void
(
*
proc
)(
struct
async_header
*
);
HANDLE
cancel
;
HANDLE
wait
;
};
struct
async_query
{
struct
async_header
hdr
;
WCHAR
*
str
;
};
static
void
free_async
(
struct
async_header
*
async
)
{
if
(
async
->
sink
)
IWbemObjectSink_Release
(
async
->
sink
);
CloseHandle
(
async
->
cancel
);
CloseHandle
(
async
->
wait
);
heap_free
(
async
);
}
static
BOOL
init_async
(
struct
async_header
*
async
,
IWbemObjectSink
*
sink
,
void
(
*
proc
)(
struct
async_header
*
)
)
{
if
(
!
(
async
->
wait
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
)))
return
FALSE
;
if
(
!
(
async
->
cancel
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
)))
{
CloseHandle
(
async
->
wait
);
return
FALSE
;
}
async
->
proc
=
proc
;
async
->
sink
=
sink
;
IWbemObjectSink_AddRef
(
sink
);
return
TRUE
;
}
static
DWORD
CALLBACK
async_proc
(
LPVOID
param
)
{
struct
async_header
*
async
=
param
;
HANDLE
wait
=
async
->
wait
;
async
->
proc
(
async
);
WaitForSingleObject
(
async
->
cancel
,
INFINITE
);
SetEvent
(
wait
);
return
ERROR_SUCCESS
;
}
static
HRESULT
queue_async
(
struct
async_header
*
async
)
{
if
(
QueueUserWorkItem
(
async_proc
,
async
,
WT_EXECUTELONGFUNCTION
))
return
S_OK
;
return
HRESULT_FROM_WIN32
(
GetLastError
()
);
}
struct
wbem_services
{
IWbemServices
IWbemServices_iface
;
LONG
refs
;
CRITICAL_SECTION
cs
;
WCHAR
*
namespace
;
struct
async_header
*
async
;
};
static
inline
struct
wbem_services
*
impl_from_IWbemServices
(
IWbemServices
*
iface
)
...
...
@@ -162,6 +219,17 @@ static ULONG WINAPI wbem_services_Release(
if
(
!
refs
)
{
TRACE
(
"destroying %p
\n
"
,
ws
);
EnterCriticalSection
(
&
ws
->
cs
);
if
(
ws
->
async
)
SetEvent
(
ws
->
async
->
cancel
);
LeaveCriticalSection
(
&
ws
->
cs
);
if
(
ws
->
async
)
{
WaitForSingleObject
(
ws
->
async
->
wait
,
INFINITE
);
free_async
(
ws
->
async
);
}
ws
->
cs
.
DebugInfo
->
Spare
[
0
]
=
0
;
DeleteCriticalSection
(
&
ws
->
cs
);
heap_free
(
ws
->
namespace
);
heap_free
(
ws
);
}
...
...
@@ -221,9 +289,27 @@ static HRESULT WINAPI wbem_services_CancelAsyncCall(
IWbemServices
*
iface
,
IWbemObjectSink
*
pSink
)
{
FIXME
(
"%p, %p
\n
"
,
iface
,
pSink
);
struct
wbem_services
*
services
=
impl_from_IWbemServices
(
iface
);
struct
async_header
*
async
;
TRACE
(
"%p, %p
\n
"
,
iface
,
pSink
);
if
(
!
pSink
)
return
WBEM_E_INVALID_PARAMETER
;
EnterCriticalSection
(
&
services
->
cs
);
if
(
!
(
async
=
services
->
async
))
{
LeaveCriticalSection
(
&
services
->
cs
);
return
WBEM_E_INVALID_PARAMETER
;
}
services
->
async
=
NULL
;
SetEvent
(
async
->
cancel
);
LeaveCriticalSection
(
&
services
->
cs
);
IWbemObjectSink_Release
(
pSink
);
WaitForSingleObject
(
async
->
wait
,
INFINITE
);
free_async
(
async
);
return
S_OK
;
}
...
...
@@ -532,6 +618,30 @@ static HRESULT WINAPI wbem_services_ExecQuery(
return
exec_query
(
strQuery
,
ppEnum
);
}
static
void
async_exec_query
(
struct
async_header
*
hdr
)
{
struct
async_query
*
query
=
(
struct
async_query
*
)
hdr
;
IEnumWbemClassObject
*
result
;
IWbemClassObject
*
obj
;
ULONG
count
;
HRESULT
hr
;
hr
=
exec_query
(
query
->
str
,
&
result
);
if
(
hr
==
S_OK
)
{
for
(;;)
{
IEnumWbemClassObject_Next
(
result
,
WBEM_INFINITE
,
1
,
&
obj
,
&
count
);
if
(
!
count
)
break
;
IWbemObjectSink_Indicate
(
query
->
hdr
.
sink
,
1
,
&
obj
);
IWbemClassObject_Release
(
obj
);
}
IEnumWbemClassObject_Release
(
result
);
}
IWbemObjectSink_SetStatus
(
query
->
hdr
.
sink
,
WBEM_STATUS_COMPLETE
,
hr
,
NULL
,
NULL
);
heap_free
(
query
->
str
);
}
static
HRESULT
WINAPI
wbem_services_ExecQueryAsync
(
IWbemServices
*
iface
,
const
BSTR
strQueryLanguage
,
...
...
@@ -540,8 +650,53 @@ static HRESULT WINAPI wbem_services_ExecQueryAsync(
IWbemContext
*
pCtx
,
IWbemObjectSink
*
pResponseHandler
)
{
FIXME
(
"
\n
"
);
return
WBEM_E_FAILED
;
struct
wbem_services
*
services
=
impl_from_IWbemServices
(
iface
);
IWbemObjectSink
*
sink
;
HRESULT
hr
=
E_OUTOFMEMORY
;
struct
async_header
*
async
;
struct
async_query
*
query
;
TRACE
(
"%p, %s, %s, 0x%08x, %p, %p
\n
"
,
iface
,
debugstr_w
(
strQueryLanguage
),
debugstr_w
(
strQuery
),
lFlags
,
pCtx
,
pResponseHandler
);
if
(
!
pResponseHandler
)
return
WBEM_E_INVALID_PARAMETER
;
hr
=
IWbemObjectSink_QueryInterface
(
pResponseHandler
,
&
IID_IWbemObjectSink
,
(
void
**
)
&
sink
);
if
(
FAILED
(
hr
))
return
hr
;
EnterCriticalSection
(
&
services
->
cs
);
if
(
services
->
async
)
{
FIXME
(
"handle more than one pending async
\n
"
);
hr
=
WBEM_E_FAILED
;
goto
done
;
}
if
(
!
(
query
=
heap_alloc_zero
(
sizeof
(
*
query
)
)))
goto
done
;
async
=
(
struct
async_header
*
)
query
;
if
(
!
(
init_async
(
async
,
sink
,
async_exec_query
)))
{
free_async
(
async
);
goto
done
;
}
if
(
!
(
query
->
str
=
heap_strdupW
(
strQuery
)))
{
free_async
(
async
);
goto
done
;
}
hr
=
queue_async
(
async
);
if
(
hr
==
S_OK
)
services
->
async
=
async
;
else
{
heap_free
(
query
->
str
);
free_async
(
async
);
}
done:
LeaveCriticalSection
(
&
services
->
cs
);
IWbemObjectSink_Release
(
sink
);
return
hr
;
}
static
HRESULT
WINAPI
wbem_services_ExecNotificationQuery
(
...
...
@@ -564,11 +719,53 @@ static HRESULT WINAPI wbem_services_ExecNotificationQueryAsync(
IWbemContext
*
pCtx
,
IWbemObjectSink
*
pResponseHandler
)
{
FIXME
(
"%p, %s, %s, 0x%08x, %p, %p
\n
"
,
iface
,
debugstr_w
(
strQueryLanguage
),
debugstr_w
(
strQuery
),
struct
wbem_services
*
services
=
impl_from_IWbemServices
(
iface
);
IWbemObjectSink
*
sink
;
HRESULT
hr
=
E_OUTOFMEMORY
;
struct
async_header
*
async
;
struct
async_query
*
query
;
TRACE
(
"%p, %s, %s, 0x%08x, %p, %p
\n
"
,
iface
,
debugstr_w
(
strQueryLanguage
),
debugstr_w
(
strQuery
),
lFlags
,
pCtx
,
pResponseHandler
);
IWbemObjectSink_AddRef
(
pResponseHandler
);
return
S_OK
;
if
(
!
pResponseHandler
)
return
WBEM_E_INVALID_PARAMETER
;
hr
=
IWbemObjectSink_QueryInterface
(
pResponseHandler
,
&
IID_IWbemObjectSink
,
(
void
**
)
&
sink
);
if
(
FAILED
(
hr
))
return
hr
;
EnterCriticalSection
(
&
services
->
cs
);
if
(
services
->
async
)
{
FIXME
(
"handle more than one pending async
\n
"
);
hr
=
WBEM_E_FAILED
;
goto
done
;
}
if
(
!
(
query
=
heap_alloc_zero
(
sizeof
(
*
query
)
)))
goto
done
;
async
=
(
struct
async_header
*
)
query
;
if
(
!
(
init_async
(
async
,
sink
,
async_exec_query
)))
{
free_async
(
async
);
goto
done
;
}
if
(
!
(
query
->
str
=
heap_strdupW
(
strQuery
)))
{
free_async
(
async
);
goto
done
;
}
hr
=
queue_async
(
async
);
if
(
hr
==
S_OK
)
services
->
async
=
async
;
else
{
heap_free
(
query
->
str
);
free_async
(
async
);
}
done:
LeaveCriticalSection
(
&
services
->
cs
);
IWbemObjectSink_Release
(
sink
);
return
hr
;
}
static
HRESULT
WINAPI
wbem_services_ExecMethod
(
...
...
@@ -670,8 +867,11 @@ HRESULT WbemServices_create( IUnknown *pUnkOuter, const WCHAR *namespace, LPVOID
if
(
!
ws
)
return
E_OUTOFMEMORY
;
ws
->
IWbemServices_iface
.
lpVtbl
=
&
wbem_services_vtbl
;
ws
->
refs
=
1
;
ws
->
refs
=
1
;
ws
->
namespace
=
heap_strdupW
(
namespace
);
ws
->
async
=
NULL
;
InitializeCriticalSection
(
&
ws
->
cs
);
ws
->
cs
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": wbemprox_services.cs"
);
*
ppObj
=
&
ws
->
IWbemServices_iface
;
...
...
dlls/wbemprox/tests/query.c
View file @
46cbc360
...
...
@@ -546,14 +546,14 @@ static ULONG WINAPI sink_Release(
static
HRESULT
WINAPI
sink_Indicate
(
IWbemObjectSink
*
iface
,
LONG
count
,
IWbemClassObject
**
objects
)
{
trace
(
"%d, %p
\n
"
,
count
,
objects
);
trace
(
"
Indicate:
%d, %p
\n
"
,
count
,
objects
);
return
S_OK
;
}
static
HRESULT
WINAPI
sink_SetStatus
(
IWbemObjectSink
*
iface
,
LONG
flags
,
HRESULT
hresult
,
BSTR
str_param
,
IWbemClassObject
*
obj_param
)
{
trace
(
"%08x, %08x, %s, %p
\n
"
,
flags
,
hresult
,
wine_dbgstr_w
(
str_param
),
obj_param
);
trace
(
"
SetStatus:
%08x, %08x, %s, %p
\n
"
,
flags
,
hresult
,
wine_dbgstr_w
(
str_param
),
obj_param
);
return
S_OK
;
}
...
...
@@ -574,11 +574,40 @@ static void test_notification_query_async( IWbemServices *services )
{
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'*'
,
' '
,
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'W'
,
'i'
,
'n'
,
'3'
,
'2'
,
'_'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
'C'
,
'h'
,
'a'
,
'n'
,
'g'
,
'e'
,
'E'
,
'v'
,
'e'
,
'n'
,
't'
,
0
};
BSTR
wql
=
SysAllocString
(
wqlW
),
query
=
SysAllocString
(
queryW
);
ULONG
prev_sink_refs
;
HRESULT
hr
;
hr
=
IWbemServices_ExecNotificationQueryAsync
(
services
,
wql
,
query
,
0
,
NULL
,
NULL
);
ok
(
hr
==
WBEM_E_INVALID_PARAMETER
,
"got %08x
\n
"
,
hr
);
prev_sink_refs
=
sink_refs
;
hr
=
IWbemServices_ExecNotificationQueryAsync
(
services
,
wql
,
query
,
0
,
NULL
,
&
sink
);
ok
(
hr
==
S_OK
||
broken
(
hr
==
WBEM_E_NOT_FOUND
),
"got %08x
\n
"
,
hr
);
ok
(
sink_refs
,
"got %u
\n
"
,
sink_refs
);
ok
(
sink_refs
>
prev_sink_refs
,
"got %u refs
\n
"
,
sink_refs
);
hr
=
IWbemServices_CancelAsyncCall
(
services
,
&
sink
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
SysFreeString
(
wql
);
SysFreeString
(
query
);
}
static
void
test_query_async
(
IWbemServices
*
services
)
{
static
const
WCHAR
queryW
[]
=
{
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'*'
,
' '
,
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'W'
,
'i'
,
'n'
,
'3'
,
'2'
,
'_'
,
'P'
,
'r'
,
'o'
,
'c'
,
'e'
,
's'
,
's'
,
0
};
BSTR
wql
=
SysAllocString
(
wqlW
),
query
=
SysAllocString
(
queryW
);
HRESULT
hr
;
hr
=
IWbemServices_ExecQueryAsync
(
services
,
wql
,
query
,
0
,
NULL
,
NULL
);
ok
(
hr
==
WBEM_E_INVALID_PARAMETER
,
"got %08x
\n
"
,
hr
);
hr
=
IWbemServices_ExecQueryAsync
(
services
,
wql
,
query
,
0
,
NULL
,
&
sink
);
ok
(
hr
==
S_OK
||
broken
(
hr
==
WBEM_E_NOT_FOUND
),
"got %08x
\n
"
,
hr
);
hr
=
IWbemServices_CancelAsyncCall
(
services
,
NULL
);
ok
(
hr
==
WBEM_E_INVALID_PARAMETER
,
"got %08x
\n
"
,
hr
);
hr
=
IWbemServices_CancelAsyncCall
(
services
,
&
sink
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
...
...
@@ -617,6 +646,7 @@ START_TEST(query)
test_Win32_Service
(
services
);
test_StdRegProv
(
services
);
test_notification_query_async
(
services
);
test_query_async
(
services
);
SysFreeString
(
path
);
IWbemServices_Release
(
services
);
...
...
include/wbemcli.idl
View file @
46cbc360
...
...
@@ -176,6 +176,13 @@ typedef [v1_enum] enum tag_WBEMSTATUS
WBEM_E_PROVIDER_DISABLED
=
0
x8004108a
}
WBEMSTATUS
;
typedef
[
v1_enum
]
enum
tag_WBEM_STATUS_TYPE
{
WBEM_STATUS_COMPLETE
=
0
,
WBEM_STATUS_REQUIREMENTS
=
1
,
WBEM_STATUS_PROGRESS
=
2
}
WBEM_STATUS_TYPE
;
typedef
[
v1_enum
]
enum
tag_WBEM_TIMEOUT_TYPE
{
WBEM_NO_WAIT
=
0
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment