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
ac90bc1e
Commit
ac90bc1e
authored
Jul 22, 2022
by
Shaun Ren
Committed by
Alexandre Julliard
Aug 03, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
webservices: Support faults in error.
Signed-off-by:
Shaun Ren
<
sren@codeweavers.com
>
parent
da77cc8c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
702 additions
and
3 deletions
+702
-3
error.c
dlls/webservices/error.c
+348
-0
reader.c
dlls/webservices/tests/reader.c
+310
-0
webservices.spec
dlls/webservices/webservices.spec
+3
-3
webservices_private.h
dlls/webservices/webservices_private.h
+2
-0
webservices.h
include/webservices.h
+39
-0
No files found.
dlls/webservices/error.c
View file @
ac90bc1e
...
...
@@ -47,6 +47,8 @@ struct error
ULONG
strs_count
;
ULONG
strs_size
;
/* Maximum length of the strs array */
WS_STRING
*
strs
;
WS_FAULT
*
fault
;
WS_XML_STRING
fault_action
;
};
#define ERROR_MAGIC (('E' << 24) | ('R' << 16) | ('R' << 8) | 'O')
...
...
@@ -85,6 +87,60 @@ static void free_error( struct error *error )
free
(
error
);
}
void
free_fault_fields
(
WS_HEAP
*
heap
,
WS_FAULT
*
fault
)
{
WS_FAULT_CODE
*
code
,
*
prev_code
;
ULONG
i
;
code
=
fault
->
code
;
while
(
code
)
{
ws_free
(
heap
,
code
->
value
.
localName
.
bytes
,
code
->
value
.
localName
.
length
);
ws_free
(
heap
,
code
->
value
.
ns
.
bytes
,
code
->
value
.
ns
.
length
);
prev_code
=
code
;
code
=
code
->
subCode
;
ws_free
(
heap
,
prev_code
,
sizeof
(
*
prev_code
)
);
}
for
(
i
=
0
;
i
<
fault
->
reasonCount
;
i
++
)
{
ws_free
(
heap
,
fault
->
reasons
[
i
].
text
.
chars
,
fault
->
reasons
[
i
].
text
.
length
*
sizeof
(
WCHAR
)
);
ws_free
(
heap
,
fault
->
reasons
[
i
].
lang
.
chars
,
fault
->
reasons
[
i
].
lang
.
length
*
sizeof
(
WCHAR
)
);
}
ws_free
(
heap
,
fault
->
reasons
,
fault
->
reasonCount
*
sizeof
(
*
fault
->
reasons
)
);
ws_free
(
heap
,
fault
->
actor
.
chars
,
fault
->
actor
.
length
*
sizeof
(
WCHAR
)
);
ws_free
(
heap
,
fault
->
node
.
chars
,
fault
->
node
.
length
*
sizeof
(
WCHAR
)
);
free_xmlbuf
((
struct
xmlbuf
*
)
fault
->
detail
);
}
static
void
free_fault
(
WS_HEAP
*
heap
,
WS_FAULT
*
fault
)
{
if
(
!
fault
)
return
;
free_fault_fields
(
heap
,
fault
);
ws_free
(
heap
,
fault
,
sizeof
(
*
fault
)
);
}
static
BOOL
copy_xml_string
(
WS_HEAP
*
heap
,
const
WS_XML_STRING
*
src
,
WS_XML_STRING
*
dst
)
{
if
(
!
src
->
length
)
return
TRUE
;
if
(
!
(
dst
->
bytes
=
ws_alloc
(
heap
,
src
->
length
)))
return
FALSE
;
memcpy
(
dst
->
bytes
,
src
->
bytes
,
src
->
length
);
dst
->
length
=
src
->
length
;
return
TRUE
;
}
static
BOOL
copy_string
(
WS_HEAP
*
heap
,
const
WS_STRING
*
src
,
WS_STRING
*
dst
)
{
ULONG
size
;
if
(
!
src
->
length
)
return
TRUE
;
size
=
src
->
length
*
sizeof
(
WCHAR
);
if
(
!
(
dst
->
chars
=
ws_alloc
(
heap
,
size
)))
return
FALSE
;
memcpy
(
dst
->
chars
,
src
->
chars
,
size
);
dst
->
length
=
src
->
length
;
return
TRUE
;
}
/* Grow the strs array to fit an extra element. */
static
HRESULT
grow_strs_array
(
struct
error
*
error
)
{
...
...
@@ -115,6 +171,142 @@ static HRESULT grow_strs_array( struct error *error )
return
S_OK
;
}
static
WS_FAULT
*
dup_fault
(
WS_HEAP
*
heap
,
const
WS_FAULT
*
src
)
{
WS_FAULT
*
new_fault
;
WS_FAULT_CODE
*
code
,
*
prev_code
,
*
new_code
;
struct
xmlbuf
*
buf
,
*
new_buf
;
ULONG
i
;
BOOL
success
=
FALSE
;
if
(
!
(
new_fault
=
ws_alloc_zero
(
heap
,
sizeof
(
*
new_fault
)
)))
return
NULL
;
prev_code
=
NULL
;
code
=
src
->
code
;
while
(
code
)
{
if
(
!
(
new_code
=
ws_alloc_zero
(
heap
,
sizeof
(
*
new_code
)
))
||
!
copy_xml_string
(
heap
,
&
code
->
value
.
localName
,
&
new_code
->
value
.
localName
)
||
!
copy_xml_string
(
heap
,
&
code
->
value
.
ns
,
&
new_code
->
value
.
ns
))
goto
done
;
if
(
prev_code
)
prev_code
->
subCode
=
new_code
;
else
new_fault
->
code
=
new_code
;
prev_code
=
new_code
;
code
=
code
->
subCode
;
}
if
(
src
->
reasonCount
>
0
)
{
if
(
!
(
new_fault
->
reasons
=
ws_alloc_zero
(
heap
,
sizeof
(
*
new_fault
->
reasons
)
*
src
->
reasonCount
)))
goto
done
;
new_fault
->
reasonCount
=
src
->
reasonCount
;
for
(
i
=
0
;
i
<
src
->
reasonCount
;
i
++
)
{
if
(
!
copy_string
(
heap
,
&
src
->
reasons
[
i
].
text
,
&
new_fault
->
reasons
[
i
].
text
)
||
!
copy_string
(
heap
,
&
src
->
reasons
[
i
].
lang
,
&
new_fault
->
reasons
[
i
].
lang
))
goto
done
;
}
}
if
(
!
copy_string
(
heap
,
&
src
->
actor
,
&
new_fault
->
actor
)
||
!
copy_string
(
heap
,
&
src
->
node
,
&
new_fault
->
node
))
goto
done
;
buf
=
(
struct
xmlbuf
*
)
src
->
detail
;
new_buf
=
NULL
;
if
(
buf
)
{
if
(
!
(
new_buf
=
alloc_xmlbuf
(
heap
,
buf
->
bytes
.
length
,
buf
->
encoding
,
buf
->
charset
,
buf
->
dict_static
,
buf
->
dict
)))
goto
done
;
memcpy
(
new_buf
->
bytes
.
bytes
,
buf
->
bytes
.
bytes
,
buf
->
bytes
.
length
);
new_buf
->
bytes
.
length
=
buf
->
bytes
.
length
;
}
new_fault
->
detail
=
(
WS_XML_BUFFER
*
)
new_buf
;
success
=
TRUE
;
done:
if
(
!
success
)
{
free_fault
(
heap
,
new_fault
);
return
NULL
;
}
return
new_fault
;
}
static
HRESULT
set_fault
(
struct
error
*
error
,
const
WS_FAULT
*
value
)
{
static
const
WCHAR
prefix
[]
=
L"The fault reason was: '"
;
static
const
WCHAR
postfix
[]
=
L"'."
;
static
const
ULONG
prefix_len
=
ARRAY_SIZE
(
prefix
)
-
1
,
postfix_len
=
ARRAY_SIZE
(
postfix
)
-
1
;
WS_FAULT
*
fault
;
WS_STRING
*
str
;
WCHAR
*
dst
;
ULONG
len
;
HRESULT
hr
=
S_OK
;
if
(
!
(
fault
=
dup_fault
(
error
->
heap
,
value
)))
return
E_OUTOFMEMORY
;
/* FIXME: check if reason lang matches error property langid */
if
(
fault
->
reasonCount
>
0
)
{
if
((
hr
=
grow_strs_array
(
error
))
!=
S_OK
)
goto
done
;
str
=
&
error
->
strs
[
error
->
strs_count
];
len
=
prefix_len
+
fault
->
reasons
[
0
].
text
.
length
+
postfix_len
;
if
(
!
(
str
->
chars
=
ws_alloc
(
error
->
heap
,
len
*
sizeof
(
WCHAR
)
)))
{
hr
=
E_OUTOFMEMORY
;
goto
done
;
}
dst
=
str
->
chars
;
memcpy
(
dst
,
prefix
,
prefix_len
*
sizeof
(
WCHAR
)
);
dst
+=
prefix_len
;
memcpy
(
dst
,
fault
->
reasons
[
0
].
text
.
chars
,
fault
->
reasons
[
0
].
text
.
length
*
sizeof
(
WCHAR
)
);
dst
+=
fault
->
reasons
[
0
].
text
.
length
;
memcpy
(
dst
,
postfix
,
postfix_len
*
sizeof
(
WCHAR
)
);
str
->
length
=
len
;
error
->
strs_count
++
;
}
free_fault
(
error
->
heap
,
error
->
fault
);
error
->
fault
=
fault
;
done:
if
(
hr
!=
S_OK
)
free_fault
(
error
->
heap
,
fault
);
return
hr
;
}
static
HRESULT
set_action
(
struct
error
*
error
,
const
WS_XML_STRING
*
value
)
{
BYTE
*
buf
;
if
(
value
->
length
==
0
)
{
ws_free
(
error
->
heap
,
error
->
fault_action
.
bytes
,
error
->
fault_action
.
length
);
memset
(
&
error
->
fault_action
,
0
,
sizeof
(
error
->
fault_action
)
);
return
S_OK
;
}
if
(
!
(
buf
=
ws_alloc
(
error
->
heap
,
value
->
length
)))
return
E_OUTOFMEMORY
;
memcpy
(
buf
,
value
->
bytes
,
value
->
length
);
ws_free
(
error
->
heap
,
error
->
fault_action
.
bytes
,
error
->
fault_action
.
length
);
error
->
fault_action
.
bytes
=
buf
;
error
->
fault_action
.
length
=
value
->
length
;
return
S_OK
;
}
/**************************************************************************
* WsCreateError [webservices.@]
*/
...
...
@@ -160,6 +352,9 @@ static void reset_error( struct error *error )
error
->
strs
=
NULL
;
error
->
strs_count
=
error
->
strs_size
=
0
;
error
->
fault
=
NULL
;
memset
(
&
error
->
fault_action
,
0
,
sizeof
(
error
->
fault_action
)
);
WsResetHeap
(
error
->
heap
,
NULL
);
}
...
...
@@ -359,3 +554,156 @@ done:
TRACE
(
"returning %#lx
\n
"
,
hr
);
return
hr
;
}
/**************************************************************************
* WsGetFaultErrorDetail [webservices.@]
*/
HRESULT
WINAPI
WsGetFaultErrorDetail
(
WS_ERROR
*
handle
,
const
WS_FAULT_DETAIL_DESCRIPTION
*
desc
,
WS_READ_OPTION
option
,
WS_HEAP
*
heap
,
void
*
value
,
ULONG
size
)
{
static
const
WS_XML_STRING
detail
=
{
6
,
(
BYTE
*
)
"detail"
};
struct
error
*
error
=
(
struct
error
*
)
handle
;
WS_XML_READER
*
reader
=
NULL
;
const
WS_XML_NODE
*
node
;
const
WS_XML_ELEMENT_NODE
*
elem
;
BOOL
nil
=
FALSE
;
HRESULT
hr
=
S_OK
;
TRACE
(
"%p %p %u %p %p %lu
\n
"
,
handle
,
desc
,
option
,
heap
,
value
,
size
);
if
(
!
error
||
!
desc
||
!
value
)
return
E_INVALIDARG
;
if
((
option
==
WS_READ_REQUIRED_POINTER
||
option
==
WS_READ_OPTIONAL_POINTER
||
option
==
WS_READ_NILLABLE_POINTER
)
&&
size
!=
sizeof
(
void
*
))
return
E_INVALIDARG
;
EnterCriticalSection
(
&
error
->
cs
);
if
(
error
->
magic
!=
ERROR_MAGIC
)
{
hr
=
E_INVALIDARG
;
goto
done
;
}
if
(
!
error
->
fault
||
!
error
->
fault
->
detail
)
{
nil
=
TRUE
;
goto
done
;
}
if
((
hr
=
WsCreateReader
(
NULL
,
0
,
&
reader
,
NULL
))
!=
S_OK
)
goto
done
;
if
((
hr
=
WsSetInputToBuffer
(
reader
,
error
->
fault
->
detail
,
NULL
,
0
,
NULL
))
!=
S_OK
)
goto
done
;
if
((
hr
=
WsReadNode
(
reader
,
NULL
))
!=
S_OK
)
goto
done
;
if
((
hr
=
WsGetReaderNode
(
reader
,
&
node
,
NULL
))
!=
S_OK
)
goto
done
;
elem
=
(
const
WS_XML_ELEMENT_NODE
*
)
node
;
if
(
!
(
node
->
nodeType
==
WS_XML_NODE_TYPE_ELEMENT
&&
WsXmlStringEquals
(
elem
->
localName
,
&
detail
,
NULL
)
==
S_OK
))
{
hr
=
WS_E_INVALID_FORMAT
;
goto
done
;
}
if
(
desc
->
action
&&
error
->
fault_action
.
length
&&
WsXmlStringEquals
(
desc
->
action
,
&
error
->
fault_action
,
NULL
)
!=
S_OK
)
{
nil
=
TRUE
;
goto
done
;
}
if
((
hr
=
WsReadNode
(
reader
,
NULL
))
!=
S_OK
)
goto
done
;
if
((
hr
=
WsReadElement
(
reader
,
desc
->
detailElementDescription
,
option
,
heap
,
value
,
size
,
handle
))
!=
S_OK
)
goto
done
;
done:
LeaveCriticalSection
(
&
error
->
cs
);
WsFreeReader
(
reader
);
if
((
hr
!=
S_OK
||
nil
)
&&
(
option
==
WS_READ_OPTIONAL_POINTER
||
option
==
WS_READ_NILLABLE_POINTER
))
*
(
void
**
)
value
=
NULL
;
if
(
nil
&&
!
(
option
==
WS_READ_OPTIONAL_POINTER
||
option
==
WS_READ_NILLABLE_POINTER
))
hr
=
WS_E_INVALID_FORMAT
;
TRACE
(
"returning %#lx
\n
"
,
hr
);
return
hr
;
}
/**************************************************************************
* WsGetFaultErrorProperty [webservices.@]
*/
HRESULT
WINAPI
WsGetFaultErrorProperty
(
WS_ERROR
*
handle
,
WS_FAULT_ERROR_PROPERTY_ID
id
,
void
*
buf
,
ULONG
size
)
{
struct
error
*
error
=
(
struct
error
*
)
handle
;
HRESULT
hr
=
S_OK
;
TRACE
(
"%p %u %p %lu
\n
"
,
handle
,
id
,
buf
,
size
);
if
(
!
error
||
!
buf
)
return
E_INVALIDARG
;
if
(
id
>
WS_FAULT_ERROR_PROPERTY_HEADER
)
return
E_INVALIDARG
;
else
if
(
id
==
WS_FAULT_ERROR_PROPERTY_HEADER
)
{
FIXME
(
"WS_FAULT_ERROR_PROPERTY_HEADER not supported
\n
"
);
return
E_NOTIMPL
;
}
EnterCriticalSection
(
&
error
->
cs
);
if
(
error
->
magic
!=
ERROR_MAGIC
)
{
hr
=
E_INVALIDARG
;
goto
done
;
}
if
(
id
==
WS_FAULT_ERROR_PROPERTY_FAULT
&&
size
==
sizeof
(
WS_FAULT
*
))
*
(
WS_FAULT
**
)
buf
=
error
->
fault
;
else
if
(
id
==
WS_FAULT_ERROR_PROPERTY_ACTION
&&
size
==
sizeof
(
WS_XML_STRING
))
memcpy
(
buf
,
&
error
->
fault_action
,
sizeof
(
WS_XML_STRING
)
);
else
hr
=
E_INVALIDARG
;
done:
LeaveCriticalSection
(
&
error
->
cs
);
TRACE
(
"returning %#lx
\n
"
,
hr
);
return
hr
;
}
/**************************************************************************
* WsSetFaultErrorProperty [webservices.@]
*/
HRESULT
WINAPI
WsSetFaultErrorProperty
(
WS_ERROR
*
handle
,
WS_FAULT_ERROR_PROPERTY_ID
id
,
const
void
*
value
,
ULONG
size
)
{
struct
error
*
error
=
(
struct
error
*
)
handle
;
HRESULT
hr
=
S_OK
;
TRACE
(
"%p %u %p %lu
\n
"
,
handle
,
id
,
value
,
size
);
if
(
!
error
||
!
value
)
return
E_INVALIDARG
;
if
(
id
>
WS_FAULT_ERROR_PROPERTY_HEADER
)
return
E_INVALIDARG
;
else
if
(
id
==
WS_FAULT_ERROR_PROPERTY_HEADER
)
{
FIXME
(
"WS_FAULT_ERROR_PROPERTY_HEADER not supported
\n
"
);
return
E_NOTIMPL
;
}
EnterCriticalSection
(
&
error
->
cs
);
if
(
error
->
magic
!=
ERROR_MAGIC
)
{
hr
=
E_INVALIDARG
;
goto
done
;
}
if
(
id
==
WS_FAULT_ERROR_PROPERTY_FAULT
&&
size
==
sizeof
(
WS_FAULT
))
hr
=
set_fault
(
error
,
value
);
else
if
(
id
==
WS_FAULT_ERROR_PROPERTY_ACTION
&&
size
==
sizeof
(
WS_XML_STRING
))
hr
=
set_action
(
error
,
value
);
else
hr
=
E_INVALIDARG
;
done:
LeaveCriticalSection
(
&
error
->
cs
);
TRACE
(
"returning %#lx
\n
"
,
hr
);
return
hr
;
}
dlls/webservices/tests/reader.c
View file @
ac90bc1e
...
...
@@ -3894,6 +3894,9 @@ static void test_WsResetError(void)
WS_ERROR
*
error
;
LANGID
langid
;
WS_STRING
str
;
WS_FAULT
fault
;
WS_XML_STRING
xmlstr
;
WS_FAULT
*
faultp
;
HRESULT
hr
;
hr
=
WsResetError
(
NULL
);
...
...
@@ -3971,6 +3974,34 @@ static void test_WsResetError(void)
ok
(
count
==
0
,
"got %lu
\n
"
,
count
);
WsFreeError
(
error
);
memset
(
&
fault
,
0
,
sizeof
(
fault
)
);
xmlstr
.
bytes
=
(
BYTE
*
)
"str"
;
xmlstr
.
length
=
3
;
hr
=
WsCreateError
(
NULL
,
0
,
&
error
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_FAULT
,
&
fault
,
sizeof
(
fault
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_ACTION
,
&
xmlstr
,
sizeof
(
WS_XML_STRING
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsResetError
(
error
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
faultp
=
(
WS_FAULT
*
)
0xdeadbeef
;
hr
=
WsGetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_FAULT
,
&
faultp
,
sizeof
(
faultp
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
faultp
==
NULL
,
"faultp != NULL
\n
"
);
xmlstr
.
length
=
0xdeadbeef
;
xmlstr
.
bytes
=
(
BYTE
*
)
0xdeadbeef
;
hr
=
WsGetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_ACTION
,
&
xmlstr
,
sizeof
(
xmlstr
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
xmlstr
.
length
==
0
,
"got %lu
\n
"
,
xmlstr
.
length
);
WsFreeError
(
error
);
}
static
void
test_WsGetReaderPosition
(
void
)
...
...
@@ -7122,6 +7153,283 @@ static void test_WsAddErrorString(void)
WsFreeError
(
error
);
}
static
void
test_WsSetFaultErrorProperty
(
void
)
{
static
const
WCHAR
expected_errorstr
[]
=
L"The fault reason was: 'Some reason'."
;
static
const
char
detailxml
[]
=
"<detail><ErrorCode>1030</ErrorCode></detail>"
;
static
const
LANGID
langid
=
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_ENGLISH_US
);
static
const
WS_XML_STRING
action
=
{
24
,
(
BYTE
*
)
"http://example.com/fault"
};
WS_ERROR_PROPERTY
prop
;
WS_ERROR
*
error
;
WS_FAULT
fault
;
WS_FAULT
*
faultp
;
WS_XML_STRING
outxmlstr
;
WS_STRING
outstr
;
ULONG
count
;
WS_HEAP
*
heap
;
WS_XML_READER
*
reader
;
HRESULT
hr
;
prop
.
id
=
WS_ERROR_PROPERTY_LANGID
;
prop
.
value
=
(
void
*
)
&
langid
;
prop
.
valueSize
=
sizeof
(
langid
);
hr
=
WsCreateError
(
&
prop
,
1
,
&
error
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_FAULT
,
NULL
,
sizeof
(
WS_FAULT
)
);
ok
(
hr
==
E_INVALIDARG
,
"got %#lx
\n
"
,
hr
);
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_ACTION
,
NULL
,
sizeof
(
WS_XML_STRING
)
);
ok
(
hr
==
E_INVALIDARG
,
"got %#lx
\n
"
,
hr
);
memset
(
&
fault
,
0
,
sizeof
(
fault
)
);
fault
.
code
=
calloc
(
1
,
sizeof
(
WS_FAULT_CODE
)
);
fault
.
code
->
value
.
localName
.
bytes
=
(
BYTE
*
)
"Server"
;
fault
.
code
->
value
.
localName
.
length
=
6
;
fault
.
code
->
subCode
=
calloc
(
1
,
sizeof
(
WS_FAULT_CODE
)
);
fault
.
code
->
subCode
->
value
.
localName
.
bytes
=
(
BYTE
*
)
"SubCode"
;
fault
.
code
->
subCode
->
value
.
localName
.
length
=
7
;
fault
.
reasons
=
calloc
(
1
,
sizeof
(
*
fault
.
reasons
)
);
fault
.
reasonCount
=
1
;
fault
.
reasons
[
0
].
lang
.
chars
=
(
WCHAR
*
)
L"en-US"
;
fault
.
reasons
[
0
].
lang
.
length
=
5
;
fault
.
reasons
[
0
].
text
.
chars
=
(
WCHAR
*
)
L"Some reason"
;
fault
.
reasons
[
0
].
text
.
length
=
11
;
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_FAULT
,
&
fault
,
sizeof
(
WS_FAULT
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
faultp
=
NULL
;
hr
=
WsGetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_FAULT
,
&
faultp
,
sizeof
(
faultp
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
faultp
!=
NULL
,
"faultp not set
\n
"
);
ok
(
faultp
!=
&
fault
,
"fault not copied
\n
"
);
ok
(
faultp
->
code
&&
faultp
->
code
!=
fault
.
code
,
"fault code not copied
\n
"
);
ok
(
faultp
->
code
->
value
.
localName
.
length
==
6
,
"got %lu
\n
"
,
faultp
->
code
->
value
.
localName
.
length
);
ok
(
!
memcmp
(
faultp
->
code
->
value
.
localName
.
bytes
,
fault
.
code
->
value
.
localName
.
bytes
,
6
),
"wrong code localName
\n
"
);
ok
(
faultp
->
code
->
value
.
localName
.
bytes
!=
fault
.
code
->
value
.
localName
.
bytes
,
"fault code localName not copied
\n
"
);
ok
(
faultp
->
code
->
value
.
ns
.
length
==
0
,
"got %lu
\n
"
,
faultp
->
code
->
value
.
ns
.
length
);
ok
(
faultp
->
code
->
subCode
&&
faultp
->
code
->
subCode
!=
fault
.
code
->
subCode
,
"fault code subCode not copied
\n
"
);
ok
(
faultp
->
code
->
subCode
->
value
.
localName
.
length
==
7
,
"got %lu
\n
"
,
faultp
->
code
->
subCode
->
value
.
localName
.
length
);
ok
(
!
memcmp
(
faultp
->
code
->
subCode
->
value
.
localName
.
bytes
,
fault
.
code
->
subCode
->
value
.
localName
.
bytes
,
7
),
"wrong subCode localName
\n
"
);
ok
(
faultp
->
code
->
subCode
->
value
.
localName
.
bytes
!=
fault
.
code
->
subCode
->
value
.
localName
.
bytes
,
"fault code subCode localName not copied
\n
"
);
ok
(
faultp
->
code
->
subCode
->
value
.
ns
.
length
==
0
,
"got %lu
\n
"
,
faultp
->
code
->
subCode
->
value
.
ns
.
length
);
ok
(
faultp
->
code
->
subCode
->
subCode
==
NULL
,
"fault->code->subCode->subCode != NULL
\n
"
);
ok
(
faultp
->
reasons
!=
fault
.
reasons
,
"fault reasons not copied
\n
"
);
ok
(
faultp
->
reasonCount
==
1
,
"got %lu
\n
"
,
faultp
->
reasonCount
);
ok
(
faultp
->
reasons
[
0
].
lang
.
length
==
5
,
"got %lu
\n
"
,
faultp
->
reasons
[
0
].
text
.
length
);
ok
(
!
memcmp
(
faultp
->
reasons
[
0
].
lang
.
chars
,
fault
.
reasons
[
0
].
lang
.
chars
,
5
*
sizeof
(
WCHAR
)
),
"wrong fault reason lang
\n
"
);
ok
(
faultp
->
reasons
[
0
].
lang
.
chars
!=
fault
.
reasons
[
0
].
lang
.
chars
,
"fault reason lang not copied
\n
"
);
ok
(
faultp
->
reasons
[
0
].
text
.
length
==
11
,
"got %lu
\n
"
,
faultp
->
reasons
[
0
].
text
.
length
);
ok
(
!
memcmp
(
faultp
->
reasons
[
0
].
text
.
chars
,
fault
.
reasons
[
0
].
text
.
chars
,
11
*
sizeof
(
WCHAR
)
),
"wrong fault reason text
\n
"
);
ok
(
faultp
->
reasons
[
0
].
text
.
chars
!=
fault
.
reasons
[
0
].
text
.
chars
,
"fault reason text not copied
\n
"
);
ok
(
faultp
->
actor
.
length
==
0
,
"got %lu
\n
"
,
faultp
->
actor
.
length
);
ok
(
faultp
->
node
.
length
==
0
,
"got %lu
\n
"
,
faultp
->
node
.
length
);
ok
(
faultp
->
detail
==
NULL
,
"faultp->detail != NULL
\n
"
);
count
=
0xdeadbeef
;
hr
=
WsGetErrorProperty
(
error
,
WS_ERROR_PROPERTY_STRING_COUNT
,
&
count
,
sizeof
(
count
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
count
==
1
,
"got %lu
\n
"
,
count
);
hr
=
WsGetErrorString
(
error
,
0
,
&
outstr
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
outstr
.
length
==
ARRAY_SIZE
(
expected_errorstr
)
-
1
,
"got %lu
\n
"
,
outstr
.
length
);
ok
(
!
memcmp
(
outstr
.
chars
,
expected_errorstr
,
(
ARRAY_SIZE
(
expected_errorstr
)
-
1
)
*
sizeof
(
WCHAR
)
),
"wrong error string
\n
"
);
outxmlstr
.
bytes
=
(
BYTE
*
)
0xdeadbeef
;
outxmlstr
.
length
=
0xdeadbeef
;
hr
=
WsGetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_ACTION
,
&
outxmlstr
,
sizeof
(
outxmlstr
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
outxmlstr
.
length
==
0
,
"got %lu
\n
"
,
outxmlstr
.
length
);
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_ACTION
,
&
action
,
sizeof
(
action
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
outxmlstr
.
bytes
=
(
BYTE
*
)
0xdeadbeef
;
outxmlstr
.
length
=
0xdeadbeef
;
hr
=
WsGetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_ACTION
,
&
outxmlstr
,
sizeof
(
outxmlstr
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
outxmlstr
.
length
==
24
,
"got %lu
\n
"
,
outxmlstr
.
length
);
ok
(
!
memcmp
(
outxmlstr
.
bytes
,
action
.
bytes
,
24
),
"wrong fault action
\n
"
);
hr
=
WsCreateHeap
(
1
<<
16
,
0
,
NULL
,
0
,
&
heap
,
NULL
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsCreateReader
(
NULL
,
0
,
&
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
set_input
(
reader
,
detailxml
,
strlen
(
detailxml
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsReadXmlBuffer
(
reader
,
heap
,
&
fault
.
detail
,
NULL
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_FAULT
,
&
fault
,
sizeof
(
WS_FAULT
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsGetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_FAULT
,
&
faultp
,
sizeof
(
faultp
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
faultp
!=
NULL
,
"faultp not set
\n
"
);
ok
(
faultp
->
detail
!=
NULL
,
"fault detail not set
\n
"
);
ok
(
faultp
->
detail
!=
fault
.
detail
,
"fault detail not copied
\n
"
);
check_output_buffer
(
faultp
->
detail
,
detailxml
,
__LINE__
);
free
(
fault
.
code
->
subCode
);
free
(
fault
.
code
);
free
(
fault
.
reasons
);
WsFreeReader
(
reader
);
WsFreeHeap
(
heap
);
WsFreeError
(
error
);
}
static
void
test_WsGetFaultErrorDetail
(
void
)
{
static
const
char
detailxml
[]
=
"<detail><ErrorCode>1030</ErrorCode></detail>"
;
static
const
char
badxml
[]
=
"<bad><ErrorCode>1030</ErrorCode></bad>"
;
WS_ERROR
*
error
;
WS_HEAP
*
heap
;
WS_XML_READER
*
reader
;
WS_FAULT
fault
;
WS_XML_STRING
action
=
{
24
,
(
BYTE
*
)
"http://example.com/fault"
};
WS_XML_STRING
action2
=
{
25
,
(
BYTE
*
)
"http://example.com/fault2"
};
WS_XML_STRING
localname
=
{
9
,
(
BYTE
*
)
"ErrorCode"
},
localname2
=
{
9
,
(
BYTE
*
)
"OtherCode"
};
WS_XML_STRING
ns
=
{
0
};
WS_ELEMENT_DESCRIPTION
desc
=
{
&
localname
,
&
ns
,
WS_UINT32_TYPE
,
NULL
};
WS_ELEMENT_DESCRIPTION
desc2
=
{
&
localname2
,
&
ns
,
WS_UINT32_TYPE
,
NULL
};
WS_FAULT_DETAIL_DESCRIPTION
fault_desc
;
UINT32
code
;
UINT32
*
codep
;
HRESULT
hr
;
hr
=
WsCreateError
(
NULL
,
0
,
&
error
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
memset
(
&
fault
,
0
,
sizeof
(
fault
)
);
hr
=
WsCreateHeap
(
1
<<
16
,
0
,
NULL
,
0
,
&
heap
,
NULL
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsCreateReader
(
NULL
,
0
,
&
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
set_input
(
reader
,
detailxml
,
strlen
(
detailxml
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsReadXmlBuffer
(
reader
,
heap
,
&
fault
.
detail
,
NULL
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_FAULT
,
&
fault
,
sizeof
(
fault
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
fault_desc
.
action
=
NULL
;
fault_desc
.
detailElementDescription
=
&
desc
;
code
=
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_REQUIRED_VALUE
,
heap
,
&
code
,
sizeof
(
code
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
code
==
1030
,
"got %u
\n
"
,
code
);
codep
=
(
UINT32
*
)
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_OPTIONAL_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
codep
!=
NULL
,
"codep == NULL
\n
"
);
ok
(
*
codep
==
1030
,
"got %u
\n
"
,
*
codep
);
fault_desc
.
action
=
&
action
;
code
=
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_REQUIRED_VALUE
,
heap
,
&
code
,
sizeof
(
code
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
code
==
1030
,
"got %u
\n
"
,
code
);
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_ACTION
,
&
action
,
sizeof
(
action
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
fault_desc
.
action
=
NULL
;
code
=
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_REQUIRED_VALUE
,
heap
,
&
code
,
sizeof
(
code
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
code
==
1030
,
"got %u
\n
"
,
code
);
fault_desc
.
action
=
&
action2
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_REQUIRED_VALUE
,
heap
,
&
code
,
sizeof
(
code
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_REQUIRED_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
codep
=
(
UINT32
*
)
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_OPTIONAL_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
codep
==
NULL
,
"codep != NULL
\n
"
);
codep
=
(
UINT32
*
)
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_NILLABLE_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ok
(
codep
==
NULL
,
"codep != NULL
\n
"
);
fault_desc
.
action
=
NULL
;
fault_desc
.
detailElementDescription
=
&
desc2
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_REQUIRED_VALUE
,
heap
,
&
code
,
sizeof
(
code
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_REQUIRED_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
codep
=
(
UINT32
*
)
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_OPTIONAL_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
ok
(
codep
==
NULL
,
"codep != NULL
\n
"
);
codep
=
(
UINT32
*
)
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_NILLABLE_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
ok
(
codep
==
NULL
,
"codep != NULL
\n
"
);
hr
=
set_input
(
reader
,
badxml
,
strlen
(
badxml
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsReadXmlBuffer
(
reader
,
heap
,
&
fault
.
detail
,
NULL
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsSetFaultErrorProperty
(
error
,
WS_FAULT_ERROR_PROPERTY_FAULT
,
&
fault
,
sizeof
(
fault
)
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_REQUIRED_VALUE
,
heap
,
&
code
,
sizeof
(
code
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_REQUIRED_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
codep
=
(
UINT32
*
)
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_OPTIONAL_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
ok
(
codep
==
NULL
,
"codep != NULL
\n
"
);
codep
=
(
UINT32
*
)
0xdeadbeef
;
hr
=
WsGetFaultErrorDetail
(
error
,
&
fault_desc
,
WS_READ_NILLABLE_POINTER
,
heap
,
&
codep
,
sizeof
(
codep
)
);
ok
(
hr
==
WS_E_INVALID_FORMAT
,
"got %#lx
\n
"
,
hr
);
ok
(
codep
==
NULL
,
"codep != NULL
\n
"
);
WsFreeReader
(
reader
);
WsFreeHeap
(
heap
);
WsFreeError
(
error
);
}
START_TEST
(
reader
)
{
test_WsCreateError
();
...
...
@@ -7174,4 +7482,6 @@ START_TEST(reader)
test_stream_input
();
test_description_type
();
test_WsAddErrorString
();
test_WsSetFaultErrorProperty
();
test_WsGetFaultErrorDetail
();
}
dlls/webservices/webservices.spec
View file @
ac90bc1e
...
...
@@ -64,8 +64,8 @@
@ stdcall WsGetDictionary(long ptr ptr)
@ stdcall WsGetErrorProperty(ptr long ptr long)
@ stdcall WsGetErrorString(ptr long ptr)
@ st
ub WsGetFaultErrorDetail
@ st
ub WsGetFaultErrorProperty
@ st
dcall WsGetFaultErrorDetail(ptr ptr ptr ptr ptr long)
@ st
dcall WsGetFaultErrorProperty(ptr long ptr long)
@ stdcall WsGetHeader(ptr long long long ptr ptr long ptr)
@ stub WsGetHeaderAttributes
@ stdcall WsGetHeapProperty(ptr long ptr long ptr)
...
...
@@ -148,7 +148,7 @@
@ stdcall WsSetChannelProperty(ptr long ptr long ptr)
@ stdcall WsSetErrorProperty(ptr long ptr long)
@ stub WsSetFaultErrorDetail
@ st
ub WsSetFaultErrorProperty
@ st
dcall WsSetFaultErrorProperty(ptr long ptr long)
@ stdcall WsSetHeader(ptr long long long ptr long ptr)
@ stdcall WsSetInput(ptr ptr ptr ptr long ptr)
@ stdcall WsSetInputToBuffer(ptr ptr ptr long ptr)
...
...
dlls/webservices/webservices_private.h
View file @
ac90bc1e
...
...
@@ -171,6 +171,8 @@ HRESULT channel_get_reader( WS_CHANNEL *, WS_XML_READER ** ) DECLSPEC_HIDDEN;
HRESULT
parse_url
(
const
WS_STRING
*
,
WS_URL_SCHEME_TYPE
*
,
WCHAR
**
,
USHORT
*
)
DECLSPEC_HIDDEN
;
void
free_fault_fields
(
WS_HEAP
*
,
WS_FAULT
*
)
DECLSPEC_HIDDEN
;
enum
record_type
{
/* 0x00 reserved */
...
...
include/webservices.h
View file @
ac90bc1e
...
...
@@ -1116,6 +1116,41 @@ struct _WS_ENDPOINT_ADDRESS {
WS_ENDPOINT_IDENTITY
*
identity
;
};
typedef
struct
_WS_FAULT_CODE
{
WS_XML_QNAME
value
;
struct
_WS_FAULT_CODE
*
subCode
;
}
WS_FAULT_CODE
;
typedef
struct
_WS_FAULT_REASON
{
WS_STRING
text
;
WS_STRING
lang
;
}
WS_FAULT_REASON
;
typedef
struct
_WS_FAULT
{
WS_FAULT_CODE
*
code
;
WS_FAULT_REASON
*
reasons
;
ULONG
reasonCount
;
WS_STRING
actor
;
WS_STRING
node
;
WS_XML_BUFFER
*
detail
;
}
WS_FAULT
;
typedef
struct
_WS_FAULT_DESCRIPTION
{
WS_ENVELOPE_VERSION
envelopeVersion
;
}
WS_FAULT_DESCRIPTION
;
typedef
struct
_WS_FAULT_DETAIL_DESCRIPTION
{
WS_XML_STRING
*
action
;
WS_ELEMENT_DESCRIPTION
*
detailElementDescription
;
}
WS_FAULT_DETAIL_DESCRIPTION
;
typedef
enum
{
WS_FAULT_ERROR_PROPERTY_FAULT
=
0
,
WS_FAULT_ERROR_PROPERTY_ACTION
=
1
,
WS_FAULT_ERROR_PROPERTY_HEADER
=
2
}
WS_FAULT_ERROR_PROPERTY_ID
;
struct
_WS_HTTP_POLICY_DESCRIPTION
{
WS_CHANNEL_PROPERTIES
channelProperties
;
};
...
...
@@ -1649,6 +1684,9 @@ HRESULT WINAPI WsGetCustomHeader(WS_MESSAGE*, const WS_ELEMENT_DESCRIPTION*, WS_
HRESULT
WINAPI
WsGetDictionary
(
WS_ENCODING
,
WS_XML_DICTIONARY
**
,
WS_ERROR
*
);
HRESULT
WINAPI
WsGetErrorProperty
(
WS_ERROR
*
,
WS_ERROR_PROPERTY_ID
,
void
*
,
ULONG
);
HRESULT
WINAPI
WsGetErrorString
(
WS_ERROR
*
,
ULONG
,
WS_STRING
*
);
HRESULT
WINAPI
WsGetFaultErrorDetail
(
WS_ERROR
*
,
const
WS_FAULT_DETAIL_DESCRIPTION
*
,
WS_READ_OPTION
,
WS_HEAP
*
,
void
*
,
ULONG
);
HRESULT
WINAPI
WsGetFaultErrorProperty
(
WS_ERROR
*
,
WS_FAULT_ERROR_PROPERTY_ID
,
void
*
,
ULONG
);
HRESULT
WINAPI
WsGetHeader
(
WS_MESSAGE
*
,
WS_HEADER_TYPE
,
WS_TYPE
,
WS_READ_OPTION
,
WS_HEAP
*
,
void
*
,
ULONG
,
WS_ERROR
*
);
HRESULT
WINAPI
WsGetHeapProperty
(
WS_HEAP
*
,
WS_HEAP_PROPERTY_ID
,
void
*
,
ULONG
,
WS_ERROR
*
);
...
...
@@ -1731,6 +1769,7 @@ HRESULT WINAPI WsSendReplyMessage(WS_CHANNEL*, WS_MESSAGE*, const WS_MESSAGE_DES
const
WS_ASYNC_CONTEXT
*
,
WS_ERROR
*
);
HRESULT
WINAPI
WsSetChannelProperty
(
WS_CHANNEL
*
,
WS_CHANNEL_PROPERTY_ID
,
const
void
*
,
ULONG
,
WS_ERROR
*
);
HRESULT
WINAPI
WsSetErrorProperty
(
WS_ERROR
*
,
WS_ERROR_PROPERTY_ID
,
const
void
*
,
ULONG
);
HRESULT
WINAPI
WsSetFaultErrorProperty
(
WS_ERROR
*
,
WS_FAULT_ERROR_PROPERTY_ID
,
const
void
*
,
ULONG
);
HRESULT
WINAPI
WsSetHeader
(
WS_MESSAGE
*
,
WS_HEADER_TYPE
,
WS_TYPE
,
WS_WRITE_OPTION
,
const
void
*
,
ULONG
,
WS_ERROR
*
);
HRESULT
WINAPI
WsSetInput
(
WS_XML_READER
*
,
const
WS_XML_READER_ENCODING
*
,
const
WS_XML_READER_INPUT
*
,
...
...
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