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
18df4912
Commit
18df4912
authored
Sep 19, 2020
by
Zebediah Figura
Committed by
Alexandre Julliard
Sep 22, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ws2_32: Reimplement WSASocketW() on top of NtOpenFile() and IOCTL_AFD_CREATE.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
29334489
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
63 additions
and
46 deletions
+63
-46
socket.c
dlls/ws2_32/socket.c
+63
-46
No files found.
dlls/ws2_32/socket.c
View file @
18df4912
...
...
@@ -155,6 +155,7 @@
#define USE_WC_PREFIX
/* For CMSG_DATA */
#include "iphlpapi.h"
#include "ip2string.h"
#include "wine/afd.h"
#include "wine/server.h"
#include "wine/debug.h"
#include "wine/exception.h"
...
...
@@ -7593,8 +7594,15 @@ SOCKET WINAPI WSASocketA(int af, int type, int protocol,
*/
SOCKET
WINAPI
WSASocketW
(
int
af
,
int
type
,
int
protocol
,
LPWSAPROTOCOL_INFOW
lpProtocolInfo
,
GROUP
g
,
DWORD
dwF
lags
)
GROUP
g
,
DWORD
f
lags
)
{
static
const
WCHAR
afdW
[]
=
{
'\\'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
'\\'
,
'A'
,
'f'
,
'd'
,
0
};
struct
afd_create_params
create_params
;
OBJECT_ATTRIBUTES
attr
;
UNICODE_STRING
string
;
IO_STATUS_BLOCK
io
;
NTSTATUS
status
;
HANDLE
handle
;
SOCKET
ret
;
DWORD
err
;
int
unixaf
,
unixtype
,
ipxptype
=
-
1
;
...
...
@@ -7605,7 +7613,7 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
*/
TRACE
(
"af=%d type=%d protocol=%d protocol_info=%p group=%d flags=0x%x
\n
"
,
af
,
type
,
protocol
,
lpProtocolInfo
,
g
,
dwF
lags
);
af
,
type
,
protocol
,
lpProtocolInfo
,
g
,
f
lags
);
if
(
!
num_startup
)
{
...
...
@@ -7706,62 +7714,71 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
goto
done
;
}
SERVER_START_REQ
(
create_socket
)
RtlInitUnicodeString
(
&
string
,
afdW
);
InitializeObjectAttributes
(
&
attr
,
&
string
,
(
flags
&
WSA_FLAG_NO_HANDLE_INHERIT
)
?
0
:
OBJ_INHERIT
,
NULL
,
NULL
);
if
((
status
=
NtOpenFile
(
&
handle
,
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
,
&
attr
,
&
io
,
0
,
0
)))
{
req
->
family
=
unixaf
;
req
->
type
=
unixtype
;
req
->
protocol
=
protocol
;
req
->
access
=
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
;
req
->
attributes
=
(
dwFlags
&
WSA_FLAG_NO_HANDLE_INHERIT
)
?
0
:
OBJ_INHERIT
;
req
->
flags
=
dwFlags
&
~
WSA_FLAG_NO_HANDLE_INHERIT
;
err
=
NtStatusToWSAError
(
wine_server_call
(
req
)
);
ret
=
HANDLE2SOCKET
(
wine_server_ptr_handle
(
reply
->
handle
));
WARN
(
"Failed to create socket, status %#x.
\n
"
,
status
);
WSASetLastError
(
NtStatusToWSAError
(
status
));
return
INVALID_SOCKET
;
}
SERVER_END_REQ
;
if
(
ret
)
{
TRACE
(
"
\t
created %04lx
\n
"
,
ret
);
if
(
ipxptype
>
0
)
set_ipx_packettype
(
ret
,
ipxptype
);
if
(
unixaf
==
AF_INET
||
unixaf
==
AF_INET6
)
create_params
.
family
=
unixaf
;
create_params
.
type
=
unixtype
;
create_params
.
protocol
=
protocol
;
create_params
.
flags
=
flags
&
~
WSA_FLAG_NO_HANDLE_INHERIT
;
if
((
status
=
NtDeviceIoControlFile
(
handle
,
NULL
,
NULL
,
NULL
,
&
io
,
IOCTL_AFD_CREATE
,
&
create_params
,
sizeof
(
create_params
),
NULL
,
0
)))
{
WARN
(
"Failed to initialize socket, status %#x.
\n
"
,
status
);
err
=
NtStatusToWSAError
(
status
);
if
(
err
==
WSAEACCES
)
/* raw socket denied */
{
/* ensure IP_DONTFRAGMENT is disabled for SOCK_DGRAM and SOCK_RAW, enabled for SOCK_STREAM */
if
(
unixtype
==
SOCK_DGRAM
||
unixtype
==
SOCK_RAW
)
/* in Linux the global default can be enabled */
set_dont_fragment
(
ret
,
unixaf
==
AF_INET6
?
IPPROTO_IPV6
:
IPPROTO_IP
,
FALSE
);
else
if
(
unixtype
==
SOCK_STREAM
)
set_dont_fragment
(
ret
,
unixaf
==
AF_INET6
?
IPPROTO_IPV6
:
IPPROTO_IP
,
TRUE
);
if
(
type
==
SOCK_RAW
)
ERR_
(
winediag
)(
"Failed to create a socket of type SOCK_RAW, this requires special permissions.
\n
"
);
else
ERR_
(
winediag
)(
"Failed to create socket, this requires special permissions.
\n
"
);
}
WSASetLastError
(
err
);
NtClose
(
handle
);
return
INVALID_SOCKET
;
}
ret
=
HANDLE2SOCKET
(
handle
);
TRACE
(
"
\t
created %04lx
\n
"
,
ret
);
if
(
ipxptype
>
0
)
set_ipx_packettype
(
ret
,
ipxptype
);
if
(
unixaf
==
AF_INET
||
unixaf
==
AF_INET6
)
{
/* ensure IP_DONTFRAGMENT is disabled for SOCK_DGRAM and SOCK_RAW, enabled for SOCK_STREAM */
if
(
unixtype
==
SOCK_DGRAM
||
unixtype
==
SOCK_RAW
)
/* in Linux the global default can be enabled */
set_dont_fragment
(
ret
,
unixaf
==
AF_INET6
?
IPPROTO_IPV6
:
IPPROTO_IP
,
FALSE
);
else
if
(
unixtype
==
SOCK_STREAM
)
set_dont_fragment
(
ret
,
unixaf
==
AF_INET6
?
IPPROTO_IPV6
:
IPPROTO_IP
,
TRUE
);
}
#ifdef IPV6_V6ONLY
if
(
unixaf
==
AF_INET6
)
{
int
fd
=
get_sock_fd
(
ret
,
0
,
NULL
);
if
(
fd
!=
-
1
)
{
/* IPV6_V6ONLY is set by default on Windows */
int
enable
=
1
;
if
(
setsockopt
(
fd
,
IPPROTO_IPV6
,
IPV6_V6ONLY
,
&
enable
,
sizeof
(
enable
)))
WARN
(
"
\t
setting IPV6_V6ONLY failed - errno = %i
\n
"
,
errno
);
release_sock_fd
(
ret
,
fd
);
}
}
#endif
if
(
!
socket_list_add
(
ret
))
if
(
unixaf
==
AF_INET6
)
{
int
fd
=
get_sock_fd
(
ret
,
0
,
NULL
);
if
(
fd
!=
-
1
)
{
CloseHandle
(
SOCKET2HANDLE
(
ret
));
return
INVALID_SOCKET
;
/* IPV6_V6ONLY is set by default on Windows */
int
enable
=
1
;
if
(
setsockopt
(
fd
,
IPPROTO_IPV6
,
IPV6_V6ONLY
,
&
enable
,
sizeof
(
enable
)))
WARN
(
"
\t
setting IPV6_V6ONLY failed - errno = %i
\n
"
,
errno
);
release_sock_fd
(
ret
,
fd
);
}
return
ret
;
}
if
(
err
==
WSAEACCES
)
/* raw socket denied */
#endif
if
(
!
socket_list_add
(
ret
))
{
if
(
type
==
SOCK_RAW
)
ERR_
(
winediag
)(
"Failed to create a socket of type SOCK_RAW, this requires special permissions.
\n
"
);
else
ERR_
(
winediag
)(
"Failed to create socket, this requires special permissions.
\n
"
);
CloseHandle
(
handle
);
return
INVALID_SOCKET
;
}
return
ret
;
done:
WARN
(
"
\t\t
failed, error %d!
\n
"
,
err
);
...
...
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