Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
823aa24f
Commit
823aa24f
authored
Apr 20, 2017
by
Hans Leidekker
Committed by
Alexandre Julliard
Apr 20, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
webservices: Implement WsOpenListener and WsCloseListener.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
79be5ad4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
266 additions
and
3 deletions
+266
-3
Makefile.in
dlls/webservices/Makefile.in
+1
-1
listener.c
dlls/webservices/listener.c
+187
-0
listener.c
dlls/webservices/tests/listener.c
+76
-0
webservices.spec
dlls/webservices/webservices.spec
+2
-2
No files found.
dlls/webservices/Makefile.in
View file @
823aa24f
MODULE
=
webservices.dll
MODULE
=
webservices.dll
IMPORTLIB
=
webservices
IMPORTLIB
=
webservices
IMPORTS
=
winhttp rpcrt4 user32
IMPORTS
=
winhttp rpcrt4 user32
ws2_32
C_SRCS
=
\
C_SRCS
=
\
channel.c
\
channel.c
\
...
...
dlls/webservices/listener.c
View file @
823aa24f
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include "windef.h"
#include "windef.h"
#include "winbase.h"
#include "winbase.h"
#include "ws2tcpip.h"
#include "webservices.h"
#include "webservices.h"
#include "wine/debug.h"
#include "wine/debug.h"
...
@@ -29,6 +30,23 @@
...
@@ -29,6 +30,23 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
webservices
);
WINE_DEFAULT_DEBUG_CHANNEL
(
webservices
);
static
BOOL
winsock_loaded
;
static
BOOL
WINAPI
winsock_startup
(
INIT_ONCE
*
once
,
void
*
param
,
void
**
ctx
)
{
int
ret
;
WSADATA
data
;
if
(
!
(
ret
=
WSAStartup
(
MAKEWORD
(
1
,
1
),
&
data
)))
winsock_loaded
=
TRUE
;
else
ERR
(
"WSAStartup failed: %d
\n
"
,
ret
);
return
TRUE
;
}
static
void
winsock_init
(
void
)
{
static
INIT_ONCE
once
=
INIT_ONCE_STATIC_INIT
;
InitOnceExecuteOnce
(
&
once
,
winsock_startup
,
NULL
,
NULL
);
}
static
const
struct
prop_desc
listener_props
[]
=
static
const
struct
prop_desc
listener_props
[]
=
{
{
{
sizeof
(
ULONG
),
FALSE
},
/* WS_LISTENER_PROPERTY_LISTEN_BACKLOG */
{
sizeof
(
ULONG
),
FALSE
},
/* WS_LISTENER_PROPERTY_LISTEN_BACKLOG */
...
@@ -57,6 +75,7 @@ struct listener
...
@@ -57,6 +75,7 @@ struct listener
WS_CHANNEL_TYPE
type
;
WS_CHANNEL_TYPE
type
;
WS_CHANNEL_BINDING
binding
;
WS_CHANNEL_BINDING
binding
;
WS_LISTENER_STATE
state
;
WS_LISTENER_STATE
state
;
SOCKET
socket
;
ULONG
prop_count
;
ULONG
prop_count
;
struct
prop
prop
[
sizeof
(
listener_props
)
/
sizeof
(
listener_props
[
0
])];
struct
prop
prop
[
sizeof
(
listener_props
)
/
sizeof
(
listener_props
[
0
])];
};
};
...
@@ -80,8 +99,16 @@ static struct listener *alloc_listener(void)
...
@@ -80,8 +99,16 @@ static struct listener *alloc_listener(void)
return
ret
;
return
ret
;
}
}
static
void
reset_listener
(
struct
listener
*
listener
)
{
closesocket
(
listener
->
socket
);
listener
->
socket
=
-
1
;
listener
->
state
=
WS_LISTENER_STATE_CREATED
;
}
static
void
free_listener
(
struct
listener
*
listener
)
static
void
free_listener
(
struct
listener
*
listener
)
{
{
reset_listener
(
listener
);
listener
->
cs
.
DebugInfo
->
Spare
[
0
]
=
0
;
listener
->
cs
.
DebugInfo
->
Spare
[
0
]
=
0
;
DeleteCriticalSection
(
&
listener
->
cs
);
DeleteCriticalSection
(
&
listener
->
cs
);
heap_free
(
listener
);
heap_free
(
listener
);
...
@@ -109,6 +136,7 @@ static HRESULT create_listener( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding
...
@@ -109,6 +136,7 @@ static HRESULT create_listener( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding
listener
->
type
=
type
;
listener
->
type
=
type
;
listener
->
binding
=
binding
;
listener
->
binding
=
binding
;
listener
->
socket
=
-
1
;
*
ret
=
listener
;
*
ret
=
listener
;
return
S_OK
;
return
S_OK
;
...
@@ -173,6 +201,165 @@ void WINAPI WsFreeListener( WS_LISTENER *handle )
...
@@ -173,6 +201,165 @@ void WINAPI WsFreeListener( WS_LISTENER *handle )
free_listener
(
listener
);
free_listener
(
listener
);
}
}
static
HRESULT
resolve_hostname
(
const
WCHAR
*
host
,
USHORT
port
,
struct
sockaddr
*
addr
,
int
*
addr_len
)
{
static
const
WCHAR
fmtW
[]
=
{
'%'
,
'u'
,
0
};
WCHAR
service
[
6
];
ADDRINFOW
*
res
,
*
info
;
HRESULT
hr
=
WS_E_ADDRESS_NOT_AVAILABLE
;
*
addr_len
=
0
;
sprintfW
(
service
,
fmtW
,
port
);
if
(
GetAddrInfoW
(
host
,
service
,
NULL
,
&
res
))
return
HRESULT_FROM_WIN32
(
WSAGetLastError
()
);
info
=
res
;
while
(
info
&&
info
->
ai_family
!=
AF_INET
&&
info
->
ai_family
!=
AF_INET6
)
info
=
info
->
ai_next
;
if
(
info
)
{
memcpy
(
addr
,
info
->
ai_addr
,
info
->
ai_addrlen
);
*
addr_len
=
info
->
ai_addrlen
;
hr
=
S_OK
;
}
FreeAddrInfoW
(
res
);
return
hr
;
}
static
HRESULT
parse_url
(
const
WS_STRING
*
str
,
WCHAR
**
host
,
USHORT
*
port
)
{
WS_HEAP
*
heap
;
WS_NETTCP_URL
*
url
;
HRESULT
hr
;
if
((
hr
=
WsCreateHeap
(
1
<<
8
,
0
,
NULL
,
0
,
&
heap
,
NULL
))
!=
S_OK
)
return
hr
;
if
((
hr
=
WsDecodeUrl
(
str
,
0
,
heap
,
(
WS_URL
**
)
&
url
,
NULL
))
!=
S_OK
)
{
WsFreeHeap
(
heap
);
return
hr
;
}
if
(
url
->
host
.
length
==
1
&&
(
url
->
host
.
chars
[
0
]
==
'+'
||
url
->
host
.
chars
[
0
]
==
'*'
))
*
host
=
NULL
;
else
{
if
(
!
(
*
host
=
heap_alloc
(
(
url
->
host
.
length
+
1
)
*
sizeof
(
WCHAR
)
)))
{
WsFreeHeap
(
heap
);
return
E_OUTOFMEMORY
;
}
memcpy
(
*
host
,
url
->
host
.
chars
,
url
->
host
.
length
*
sizeof
(
WCHAR
)
);
(
*
host
)[
url
->
host
.
length
]
=
0
;
}
*
port
=
url
->
port
;
WsFreeHeap
(
heap
);
return
hr
;
}
static
HRESULT
open_listener
(
struct
listener
*
listener
,
const
WS_STRING
*
url
)
{
struct
sockaddr_storage
storage
;
struct
sockaddr
*
addr
=
(
struct
sockaddr
*
)
&
storage
;
int
addr_len
;
WCHAR
*
host
;
USHORT
port
;
HRESULT
hr
;
if
((
hr
=
parse_url
(
url
,
&
host
,
&
port
))
!=
S_OK
)
return
hr
;
winsock_init
();
hr
=
resolve_hostname
(
host
,
port
,
addr
,
&
addr_len
);
heap_free
(
host
);
if
(
hr
!=
S_OK
)
return
hr
;
if
((
listener
->
socket
=
socket
(
addr
->
sa_family
,
SOCK_STREAM
,
0
))
==
-
1
)
return
HRESULT_FROM_WIN32
(
WSAGetLastError
()
);
if
(
bind
(
listener
->
socket
,
addr
,
addr_len
)
<
0
)
{
closesocket
(
listener
->
socket
);
listener
->
socket
=
-
1
;
return
HRESULT_FROM_WIN32
(
WSAGetLastError
()
);
}
if
(
listen
(
listener
->
socket
,
0
)
<
0
)
{
closesocket
(
listener
->
socket
);
listener
->
socket
=
-
1
;
return
HRESULT_FROM_WIN32
(
WSAGetLastError
()
);
}
listener
->
state
=
WS_LISTENER_STATE_OPEN
;
return
S_OK
;
}
/**************************************************************************
* WsOpenListener [webservices.@]
*/
HRESULT
WINAPI
WsOpenListener
(
WS_LISTENER
*
handle
,
WS_STRING
*
url
,
const
WS_ASYNC_CONTEXT
*
ctx
,
WS_ERROR
*
error
)
{
struct
listener
*
listener
=
(
struct
listener
*
)
handle
;
HRESULT
hr
;
TRACE
(
"%p %s %p %p
\n
"
,
handle
,
url
?
debugstr_wn
(
url
->
chars
,
url
->
length
)
:
"null"
,
ctx
,
error
);
if
(
error
)
FIXME
(
"ignoring error parameter
\n
"
);
if
(
ctx
)
FIXME
(
"ignoring ctx parameter
\n
"
);
if
(
!
listener
||
!
url
)
return
E_INVALIDARG
;
EnterCriticalSection
(
&
listener
->
cs
);
if
(
listener
->
magic
!=
LISTENER_MAGIC
)
{
LeaveCriticalSection
(
&
listener
->
cs
);
return
E_INVALIDARG
;
}
if
(
listener
->
state
!=
WS_LISTENER_STATE_CREATED
)
{
LeaveCriticalSection
(
&
listener
->
cs
);
return
WS_E_INVALID_OPERATION
;
}
hr
=
open_listener
(
listener
,
url
);
LeaveCriticalSection
(
&
listener
->
cs
);
return
hr
;
}
static
void
close_listener
(
struct
listener
*
listener
)
{
reset_listener
(
listener
);
listener
->
state
=
WS_LISTENER_STATE_CLOSED
;
}
/**************************************************************************
* WsCloseListener [webservices.@]
*/
HRESULT
WINAPI
WsCloseListener
(
WS_LISTENER
*
handle
,
const
WS_ASYNC_CONTEXT
*
ctx
,
WS_ERROR
*
error
)
{
struct
listener
*
listener
=
(
struct
listener
*
)
handle
;
TRACE
(
"%p %p %p
\n
"
,
handle
,
ctx
,
error
);
if
(
error
)
FIXME
(
"ignoring error parameter
\n
"
);
if
(
ctx
)
FIXME
(
"ignoring ctx parameter
\n
"
);
if
(
!
listener
)
return
E_INVALIDARG
;
EnterCriticalSection
(
&
listener
->
cs
);
if
(
listener
->
magic
!=
LISTENER_MAGIC
)
{
LeaveCriticalSection
(
&
listener
->
cs
);
return
E_INVALIDARG
;
}
close_listener
(
listener
);
LeaveCriticalSection
(
&
listener
->
cs
);
return
S_OK
;
}
/**************************************************************************
/**************************************************************************
* WsGetListenerProperty [webservices.@]
* WsGetListenerProperty [webservices.@]
*/
*/
...
...
dlls/webservices/tests/listener.c
View file @
823aa24f
...
@@ -79,7 +79,83 @@ static void test_WsCreateListener(void)
...
@@ -79,7 +79,83 @@ static void test_WsCreateListener(void)
WsFreeListener
(
listener
);
WsFreeListener
(
listener
);
}
}
static
void
test_WsOpenListener
(
void
)
{
WCHAR
str
[]
=
{
'n'
,
'e'
,
't'
,
'.'
,
't'
,
'c'
,
'p'
,
':'
,
'/'
,
'/'
,
'+'
,
':'
,
'2'
,
'0'
,
'1'
,
'7'
,
'/'
,
'p'
,
'a'
,
't'
,
'h'
};
WCHAR
str2
[]
=
{
'n'
,
'e'
,
't'
,
'.'
,
't'
,
'c'
,
'p'
,
':'
,
'/'
,
'/'
,
'l'
,
'o'
,
'c'
,
'a'
,
'l'
,
'h'
,
'o'
,
's'
,
't'
,
':'
,
'2'
,
'0'
,
'1'
,
'7'
};
WCHAR
str3
[]
=
{
'n'
,
'e'
,
't'
,
'.'
,
't'
,
'c'
,
'p'
,
':'
,
'/'
,
'/'
,
'1'
,
'2'
,
'7'
,
'.'
,
'0'
,
'.'
,
'0'
,
'.'
,
'1'
,
':'
,
'2'
,
'0'
,
'1'
,
'7'
};
WS_STRING
url
;
WS_LISTENER
*
listener
;
HRESULT
hr
;
hr
=
WsOpenListener
(
NULL
,
NULL
,
NULL
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"got %08x
\n
"
,
hr
);
hr
=
WsCreateListener
(
WS_CHANNEL_TYPE_DUPLEX_SESSION
,
WS_TCP_CHANNEL_BINDING
,
NULL
,
0
,
NULL
,
&
listener
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
WsCloseListener
(
listener
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
WsFreeListener
(
listener
);
hr
=
WsCreateListener
(
WS_CHANNEL_TYPE_DUPLEX_SESSION
,
WS_TCP_CHANNEL_BINDING
,
NULL
,
0
,
NULL
,
&
listener
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
WsOpenListener
(
listener
,
NULL
,
NULL
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"got %08x
\n
"
,
hr
);
url
.
length
=
sizeof
(
str
)
/
sizeof
(
str
[
0
]);
url
.
chars
=
str
;
hr
=
WsOpenListener
(
NULL
,
&
url
,
NULL
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"got %08x
\n
"
,
hr
);
hr
=
WsOpenListener
(
listener
,
&
url
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
WsOpenListener
(
listener
,
&
url
,
NULL
,
NULL
);
ok
(
hr
==
WS_E_INVALID_OPERATION
,
"got %08x
\n
"
,
hr
);
hr
=
WsCloseListener
(
listener
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
WsFreeListener
(
listener
);
hr
=
WsCreateListener
(
WS_CHANNEL_TYPE_DUPLEX_SESSION
,
WS_TCP_CHANNEL_BINDING
,
NULL
,
0
,
NULL
,
&
listener
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
url
.
length
=
sizeof
(
str2
)
/
sizeof
(
str2
[
0
]);
url
.
chars
=
str2
;
hr
=
WsOpenListener
(
listener
,
&
url
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
WsCloseListener
(
listener
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
WsFreeListener
(
listener
);
hr
=
WsCreateListener
(
WS_CHANNEL_TYPE_DUPLEX_SESSION
,
WS_TCP_CHANNEL_BINDING
,
NULL
,
0
,
NULL
,
&
listener
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
url
.
length
=
sizeof
(
str3
)
/
sizeof
(
str3
[
0
]);
url
.
chars
=
str3
;
hr
=
WsOpenListener
(
listener
,
&
url
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
WsCloseListener
(
listener
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
WsCloseListener
(
NULL
,
NULL
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"got %08x
\n
"
,
hr
);
WsFreeListener
(
listener
);
}
START_TEST
(
listener
)
START_TEST
(
listener
)
{
{
test_WsCreateListener
();
test_WsCreateListener
();
test_WsOpenListener
();
}
}
dlls/webservices/webservices.spec
View file @
823aa24f
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
@ stdcall WsCall(ptr ptr ptr ptr ptr long ptr ptr)
@ stdcall WsCall(ptr ptr ptr ptr ptr long ptr ptr)
@ stub WsCheckMustUnderstandHeaders
@ stub WsCheckMustUnderstandHeaders
@ stdcall WsCloseChannel(ptr ptr ptr)
@ stdcall WsCloseChannel(ptr ptr ptr)
@ st
ub WsCloseListener
@ st
dcall WsCloseListener(ptr ptr ptr)
@ stub WsCloseServiceHost
@ stub WsCloseServiceHost
@ stdcall WsCloseServiceProxy(ptr ptr ptr)
@ stdcall WsCloseServiceProxy(ptr ptr ptr)
@ stub WsCombineUrl
@ stub WsCombineUrl
...
@@ -96,7 +96,7 @@
...
@@ -96,7 +96,7 @@
@ stdcall WsMoveReader(ptr long ptr ptr)
@ stdcall WsMoveReader(ptr long ptr ptr)
@ stdcall WsMoveWriter(ptr long ptr ptr)
@ stdcall WsMoveWriter(ptr long ptr ptr)
@ stdcall WsOpenChannel(ptr ptr ptr ptr)
@ stdcall WsOpenChannel(ptr ptr ptr ptr)
@ st
ub WsOpenListener
@ st
dcall WsOpenListener(ptr ptr ptr ptr)
@ stub WsOpenServiceHost
@ stub WsOpenServiceHost
@ stdcall WsOpenServiceProxy(ptr ptr ptr ptr)
@ stdcall WsOpenServiceProxy(ptr ptr ptr ptr)
@ stub WsPullBytes
@ stub WsPullBytes
...
...
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