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
737510ee
Commit
737510ee
authored
Dec 16, 2007
by
Rob Shearman
Committed by
Alexandre Julliard
Dec 17, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rpcrt4: Move association code into a separate file.
parent
22f530c8
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
442 additions
and
383 deletions
+442
-383
Makefile.in
dlls/rpcrt4/Makefile.in
+1
-0
rpc_assoc.c
dlls/rpcrt4/rpc_assoc.c
+392
-0
rpc_assoc.h
dlls/rpcrt4/rpc_assoc.h
+46
-0
rpc_binding.c
dlls/rpcrt4/rpc_binding.c
+1
-1
rpc_binding.h
dlls/rpcrt4/rpc_binding.h
+1
-25
rpc_server.c
dlls/rpcrt4/rpc_server.c
+1
-0
rpc_transport.c
dlls/rpcrt4/rpc_transport.c
+0
-357
No files found.
dlls/rpcrt4/Makefile.in
View file @
737510ee
...
...
@@ -18,6 +18,7 @@ C_SRCS = \
ndr_marshall.c
\
ndr_ole.c
\
ndr_stubless.c
\
rpc_assoc.c
\
rpc_binding.c
\
rpc_epmap.c
\
rpc_message.c
\
...
...
dlls/rpcrt4/rpc_assoc.c
0 → 100644
View file @
737510ee
/*
* Associations
*
* Copyright 2007 Robert Shearman (for CodeWeavers)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#include <stdarg.h>
#include <assert.h>
#include "rpc.h"
#include "rpcndr.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "rpc_binding.h"
#include "rpc_assoc.h"
#include "rpc_message.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
rpc
);
static
CRITICAL_SECTION
assoc_list_cs
;
static
CRITICAL_SECTION_DEBUG
assoc_list_cs_debug
=
{
0
,
0
,
&
assoc_list_cs
,
{
&
assoc_list_cs_debug
.
ProcessLocksList
,
&
assoc_list_cs_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": assoc_list_cs"
)
}
};
static
CRITICAL_SECTION
assoc_list_cs
=
{
&
assoc_list_cs_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
struct
list
client_assoc_list
=
LIST_INIT
(
client_assoc_list
);
static
struct
list
server_assoc_list
=
LIST_INIT
(
server_assoc_list
);
static
LONG
last_assoc_group_id
;
static
RPC_STATUS
RpcAssoc_Alloc
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
RpcAssoc
**
assoc_out
)
{
RpcAssoc
*
assoc
;
assoc
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
assoc
));
if
(
!
assoc
)
return
RPC_S_OUT_OF_RESOURCES
;
assoc
->
refs
=
1
;
list_init
(
&
assoc
->
free_connection_pool
);
InitializeCriticalSection
(
&
assoc
->
cs
);
assoc
->
Protseq
=
RPCRT4_strdupA
(
Protseq
);
assoc
->
NetworkAddr
=
RPCRT4_strdupA
(
NetworkAddr
);
assoc
->
Endpoint
=
RPCRT4_strdupA
(
Endpoint
);
assoc
->
NetworkOptions
=
NetworkOptions
?
RPCRT4_strdupW
(
NetworkOptions
)
:
NULL
;
assoc
->
assoc_group_id
=
0
;
list_init
(
&
assoc
->
entry
);
*
assoc_out
=
assoc
;
return
RPC_S_OK
;
}
RPC_STATUS
RPCRT4_GetAssociation
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
RpcAssoc
**
assoc_out
)
{
RpcAssoc
*
assoc
;
RPC_STATUS
status
;
EnterCriticalSection
(
&
assoc_list_cs
);
LIST_FOR_EACH_ENTRY
(
assoc
,
&
client_assoc_list
,
RpcAssoc
,
entry
)
{
if
(
!
strcmp
(
Protseq
,
assoc
->
Protseq
)
&&
!
strcmp
(
NetworkAddr
,
assoc
->
NetworkAddr
)
&&
!
strcmp
(
Endpoint
,
assoc
->
Endpoint
)
&&
((
!
assoc
->
NetworkOptions
&&
!
NetworkOptions
)
||
!
strcmpW
(
NetworkOptions
,
assoc
->
NetworkOptions
)))
{
assoc
->
refs
++
;
*
assoc_out
=
assoc
;
LeaveCriticalSection
(
&
assoc_list_cs
);
TRACE
(
"using existing assoc %p
\n
"
,
assoc
);
return
RPC_S_OK
;
}
}
status
=
RpcAssoc_Alloc
(
Protseq
,
NetworkAddr
,
Endpoint
,
NetworkOptions
,
&
assoc
);
if
(
status
!=
RPC_S_OK
)
{
LeaveCriticalSection
(
&
assoc_list_cs
);
return
status
;
}
list_add_head
(
&
client_assoc_list
,
&
assoc
->
entry
);
*
assoc_out
=
assoc
;
LeaveCriticalSection
(
&
assoc_list_cs
);
TRACE
(
"new assoc %p
\n
"
,
assoc
);
return
RPC_S_OK
;
}
RPC_STATUS
RpcServerAssoc_GetAssociation
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
unsigned
long
assoc_gid
,
RpcAssoc
**
assoc_out
)
{
RpcAssoc
*
assoc
;
RPC_STATUS
status
;
EnterCriticalSection
(
&
assoc_list_cs
);
if
(
assoc_gid
)
{
LIST_FOR_EACH_ENTRY
(
assoc
,
&
server_assoc_list
,
RpcAssoc
,
entry
)
{
/* FIXME: NetworkAddr shouldn't be NULL */
if
(
assoc
->
assoc_group_id
==
assoc_gid
&&
!
strcmp
(
Protseq
,
assoc
->
Protseq
)
&&
(
!
NetworkAddr
||
!
assoc
->
NetworkAddr
||
!
strcmp
(
NetworkAddr
,
assoc
->
NetworkAddr
))
&&
!
strcmp
(
Endpoint
,
assoc
->
Endpoint
)
&&
((
!
assoc
->
NetworkOptions
==
!
NetworkOptions
)
&&
(
!
NetworkOptions
||
!
strcmpW
(
NetworkOptions
,
assoc
->
NetworkOptions
))))
{
assoc
->
refs
++
;
*
assoc_out
=
assoc
;
LeaveCriticalSection
(
&
assoc_list_cs
);
TRACE
(
"using existing assoc %p
\n
"
,
assoc
);
return
RPC_S_OK
;
}
}
*
assoc_out
=
NULL
;
return
RPC_S_NO_CONTEXT_AVAILABLE
;
}
status
=
RpcAssoc_Alloc
(
Protseq
,
NetworkAddr
,
Endpoint
,
NetworkOptions
,
&
assoc
);
if
(
status
!=
RPC_S_OK
)
{
LeaveCriticalSection
(
&
assoc_list_cs
);
return
status
;
}
assoc
->
assoc_group_id
=
InterlockedIncrement
(
&
last_assoc_group_id
);
list_add_head
(
&
server_assoc_list
,
&
assoc
->
entry
);
*
assoc_out
=
assoc
;
LeaveCriticalSection
(
&
assoc_list_cs
);
TRACE
(
"new assoc %p
\n
"
,
assoc
);
return
RPC_S_OK
;
}
ULONG
RpcAssoc_Release
(
RpcAssoc
*
assoc
)
{
ULONG
refs
;
EnterCriticalSection
(
&
assoc_list_cs
);
refs
=
--
assoc
->
refs
;
if
(
!
refs
)
list_remove
(
&
assoc
->
entry
);
LeaveCriticalSection
(
&
assoc_list_cs
);
if
(
!
refs
)
{
RpcConnection
*
Connection
,
*
cursor2
;
TRACE
(
"destroying assoc %p
\n
"
,
assoc
);
LIST_FOR_EACH_ENTRY_SAFE
(
Connection
,
cursor2
,
&
assoc
->
free_connection_pool
,
RpcConnection
,
conn_pool_entry
)
{
list_remove
(
&
Connection
->
conn_pool_entry
);
RPCRT4_DestroyConnection
(
Connection
);
}
HeapFree
(
GetProcessHeap
(),
0
,
assoc
->
NetworkOptions
);
HeapFree
(
GetProcessHeap
(),
0
,
assoc
->
Endpoint
);
HeapFree
(
GetProcessHeap
(),
0
,
assoc
->
NetworkAddr
);
HeapFree
(
GetProcessHeap
(),
0
,
assoc
->
Protseq
);
DeleteCriticalSection
(
&
assoc
->
cs
);
HeapFree
(
GetProcessHeap
(),
0
,
assoc
);
}
return
refs
;
}
#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
static
RPC_STATUS
RpcAssoc_BindConnection
(
const
RpcAssoc
*
assoc
,
RpcConnection
*
conn
,
const
RPC_SYNTAX_IDENTIFIER
*
InterfaceId
,
const
RPC_SYNTAX_IDENTIFIER
*
TransferSyntax
)
{
RpcPktHdr
*
hdr
;
RpcPktHdr
*
response_hdr
;
RPC_MESSAGE
msg
;
RPC_STATUS
status
;
TRACE
(
"sending bind request to server
\n
"
);
hdr
=
RPCRT4_BuildBindHeader
(
NDR_LOCAL_DATA_REPRESENTATION
,
RPC_MAX_PACKET_SIZE
,
RPC_MAX_PACKET_SIZE
,
assoc
->
assoc_group_id
,
InterfaceId
,
TransferSyntax
);
status
=
RPCRT4_Send
(
conn
,
hdr
,
NULL
,
0
);
RPCRT4_FreeHeader
(
hdr
);
if
(
status
!=
RPC_S_OK
)
return
status
;
status
=
RPCRT4_Receive
(
conn
,
&
response_hdr
,
&
msg
);
if
(
status
!=
RPC_S_OK
)
{
ERR
(
"receive failed
\n
"
);
return
status
;
}
switch
(
response_hdr
->
common
.
ptype
)
{
case
PKT_BIND_ACK
:
{
RpcAddressString
*
server_address
=
msg
.
Buffer
;
if
((
msg
.
BufferLength
>=
FIELD_OFFSET
(
RpcAddressString
,
string
[
0
]))
||
(
msg
.
BufferLength
>=
ROUND_UP
(
FIELD_OFFSET
(
RpcAddressString
,
string
[
server_address
->
length
]),
4
)))
{
unsigned
short
remaining
=
msg
.
BufferLength
-
ROUND_UP
(
FIELD_OFFSET
(
RpcAddressString
,
string
[
server_address
->
length
]),
4
);
RpcResults
*
results
=
(
RpcResults
*
)((
ULONG_PTR
)
server_address
+
ROUND_UP
(
FIELD_OFFSET
(
RpcAddressString
,
string
[
server_address
->
length
]),
4
));
if
((
results
->
num_results
==
1
)
&&
(
remaining
>=
sizeof
(
*
results
)))
{
switch
(
results
->
results
[
0
].
result
)
{
case
RESULT_ACCEPT
:
conn
->
assoc_group_id
=
response_hdr
->
bind_ack
.
assoc_gid
;
conn
->
MaxTransmissionSize
=
response_hdr
->
bind_ack
.
max_tsize
;
conn
->
ActiveInterface
=
*
InterfaceId
;
break
;
case
RESULT_PROVIDER_REJECTION
:
switch
(
results
->
results
[
0
].
reason
)
{
case
REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
:
ERR
(
"syntax %s, %d.%d not supported
\n
"
,
debugstr_guid
(
&
InterfaceId
->
SyntaxGUID
),
InterfaceId
->
SyntaxVersion
.
MajorVersion
,
InterfaceId
->
SyntaxVersion
.
MinorVersion
);
status
=
RPC_S_UNKNOWN_IF
;
break
;
case
REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED
:
ERR
(
"transfer syntax not supported
\n
"
);
status
=
RPC_S_SERVER_UNAVAILABLE
;
break
;
case
REASON_NONE
:
default:
status
=
RPC_S_CALL_FAILED_DNE
;
}
break
;
case
RESULT_USER_REJECTION
:
default:
ERR
(
"rejection result %d
\n
"
,
results
->
results
[
0
].
result
);
status
=
RPC_S_CALL_FAILED_DNE
;
}
}
else
{
ERR
(
"incorrect results size
\n
"
);
status
=
RPC_S_CALL_FAILED_DNE
;
}
}
else
{
ERR
(
"bind ack packet too small (%d)
\n
"
,
msg
.
BufferLength
);
status
=
RPC_S_PROTOCOL_ERROR
;
}
break
;
}
case
PKT_BIND_NACK
:
switch
(
response_hdr
->
bind_nack
.
reject_reason
)
{
case
REJECT_LOCAL_LIMIT_EXCEEDED
:
case
REJECT_TEMPORARY_CONGESTION
:
ERR
(
"server too busy
\n
"
);
status
=
RPC_S_SERVER_TOO_BUSY
;
break
;
case
REJECT_PROTOCOL_VERSION_NOT_SUPPORTED
:
ERR
(
"protocol version not supported
\n
"
);
status
=
RPC_S_PROTOCOL_ERROR
;
break
;
case
REJECT_UNKNOWN_AUTHN_SERVICE
:
ERR
(
"unknown authentication service
\n
"
);
status
=
RPC_S_UNKNOWN_AUTHN_SERVICE
;
break
;
case
REJECT_INVALID_CHECKSUM
:
ERR
(
"invalid checksum
\n
"
);
status
=
ERROR_ACCESS_DENIED
;
break
;
default:
ERR
(
"rejected bind for reason %d
\n
"
,
response_hdr
->
bind_nack
.
reject_reason
);
status
=
RPC_S_CALL_FAILED_DNE
;
}
break
;
default:
ERR
(
"wrong packet type received %d
\n
"
,
response_hdr
->
common
.
ptype
);
status
=
RPC_S_PROTOCOL_ERROR
;
break
;
}
I_RpcFreeBuffer
(
&
msg
);
RPCRT4_FreeHeader
(
response_hdr
);
return
status
;
}
static
RpcConnection
*
RpcAssoc_GetIdleConnection
(
RpcAssoc
*
assoc
,
const
RPC_SYNTAX_IDENTIFIER
*
InterfaceId
,
const
RPC_SYNTAX_IDENTIFIER
*
TransferSyntax
,
const
RpcAuthInfo
*
AuthInfo
,
const
RpcQualityOfService
*
QOS
)
{
RpcConnection
*
Connection
;
EnterCriticalSection
(
&
assoc
->
cs
);
/* try to find a compatible connection from the connection pool */
LIST_FOR_EACH_ENTRY
(
Connection
,
&
assoc
->
free_connection_pool
,
RpcConnection
,
conn_pool_entry
)
{
if
(
!
memcmp
(
&
Connection
->
ActiveInterface
,
InterfaceId
,
sizeof
(
RPC_SYNTAX_IDENTIFIER
))
&&
RpcAuthInfo_IsEqual
(
Connection
->
AuthInfo
,
AuthInfo
)
&&
RpcQualityOfService_IsEqual
(
Connection
->
QOS
,
QOS
))
{
list_remove
(
&
Connection
->
conn_pool_entry
);
LeaveCriticalSection
(
&
assoc
->
cs
);
TRACE
(
"got connection from pool %p
\n
"
,
Connection
);
return
Connection
;
}
}
LeaveCriticalSection
(
&
assoc
->
cs
);
return
NULL
;
}
RPC_STATUS
RpcAssoc_GetClientConnection
(
RpcAssoc
*
assoc
,
const
RPC_SYNTAX_IDENTIFIER
*
InterfaceId
,
const
RPC_SYNTAX_IDENTIFIER
*
TransferSyntax
,
RpcAuthInfo
*
AuthInfo
,
RpcQualityOfService
*
QOS
,
RpcConnection
**
Connection
)
{
RpcConnection
*
NewConnection
;
RPC_STATUS
status
;
*
Connection
=
RpcAssoc_GetIdleConnection
(
assoc
,
InterfaceId
,
TransferSyntax
,
AuthInfo
,
QOS
);
if
(
*
Connection
)
return
RPC_S_OK
;
/* create a new connection */
status
=
RPCRT4_CreateConnection
(
&
NewConnection
,
FALSE
/* is this a server connection? */
,
assoc
->
Protseq
,
assoc
->
NetworkAddr
,
assoc
->
Endpoint
,
assoc
->
NetworkOptions
,
AuthInfo
,
QOS
);
if
(
status
!=
RPC_S_OK
)
return
status
;
status
=
RPCRT4_OpenClientConnection
(
NewConnection
);
if
(
status
!=
RPC_S_OK
)
{
RPCRT4_DestroyConnection
(
NewConnection
);
return
status
;
}
status
=
RpcAssoc_BindConnection
(
assoc
,
NewConnection
,
InterfaceId
,
TransferSyntax
);
if
(
status
!=
RPC_S_OK
)
{
RPCRT4_DestroyConnection
(
NewConnection
);
return
status
;
}
*
Connection
=
NewConnection
;
return
RPC_S_OK
;
}
void
RpcAssoc_ReleaseIdleConnection
(
RpcAssoc
*
assoc
,
RpcConnection
*
Connection
)
{
assert
(
!
Connection
->
server
);
EnterCriticalSection
(
&
assoc
->
cs
);
if
(
!
assoc
->
assoc_group_id
)
assoc
->
assoc_group_id
=
Connection
->
assoc_group_id
;
list_add_head
(
&
assoc
->
free_connection_pool
,
&
Connection
->
conn_pool_entry
);
LeaveCriticalSection
(
&
assoc
->
cs
);
}
dlls/rpcrt4/rpc_assoc.h
0 → 100644
View file @
737510ee
/*
* Associations
*
* Copyright 2007 Robert Shearman (for CodeWeavers)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#include "wine/list.h"
typedef
struct
_RpcAssoc
{
struct
list
entry
;
/* entry in the global list of associations */
LONG
refs
;
LPSTR
Protseq
;
LPSTR
NetworkAddr
;
LPSTR
Endpoint
;
LPWSTR
NetworkOptions
;
/* id of this association group */
ULONG
assoc_group_id
;
CRITICAL_SECTION
cs
;
/* connections available to be used */
struct
list
free_connection_pool
;
}
RpcAssoc
;
RPC_STATUS
RPCRT4_GetAssociation
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
RpcAssoc
**
assoc
);
RPC_STATUS
RpcAssoc_GetClientConnection
(
RpcAssoc
*
assoc
,
const
RPC_SYNTAX_IDENTIFIER
*
InterfaceId
,
const
RPC_SYNTAX_IDENTIFIER
*
TransferSyntax
,
RpcAuthInfo
*
AuthInfo
,
RpcQualityOfService
*
QOS
,
RpcConnection
**
Connection
);
void
RpcAssoc_ReleaseIdleConnection
(
RpcAssoc
*
assoc
,
RpcConnection
*
Connection
);
ULONG
RpcAssoc_Release
(
RpcAssoc
*
assoc
);
RPC_STATUS
RpcServerAssoc_GetAssociation
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
unsigned
long
assoc_gid
,
RpcAssoc
**
assoc_out
);
dlls/rpcrt4/rpc_binding.c
View file @
737510ee
...
...
@@ -39,7 +39,7 @@
#include "wine/debug.h"
#include "rpc_binding.h"
#include "rpc_
message
.h"
#include "rpc_
assoc
.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
rpc
);
...
...
dlls/rpcrt4/rpc_binding.h
View file @
737510ee
...
...
@@ -49,24 +49,6 @@ typedef struct _RpcQualityOfService
RPC_SECURITY_QOS_V2_W
*
qos
;
}
RpcQualityOfService
;
typedef
struct
_RpcAssoc
{
struct
list
entry
;
/* entry in the global list of associations */
LONG
refs
;
LPSTR
Protseq
;
LPSTR
NetworkAddr
;
LPSTR
Endpoint
;
LPWSTR
NetworkOptions
;
/* id of this association group */
ULONG
assoc_group_id
;
CRITICAL_SECTION
cs
;
/* connections available to be used */
struct
list
free_connection_pool
;
}
RpcAssoc
;
struct
connection_ops
;
typedef
struct
_RpcConnection
...
...
@@ -127,7 +109,7 @@ typedef struct _RpcBinding
RPC_BLOCKING_FN
BlockingFn
;
ULONG
ServerTid
;
RpcConnection
*
FromConn
;
RpcAssoc
*
Assoc
;
struct
_
RpcAssoc
*
Assoc
;
/* authentication */
RpcAuthInfo
*
AuthInfo
;
...
...
@@ -150,12 +132,6 @@ ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos);
ULONG
RpcQualityOfService_Release
(
RpcQualityOfService
*
qos
);
BOOL
RpcQualityOfService_IsEqual
(
const
RpcQualityOfService
*
qos1
,
const
RpcQualityOfService
*
qos2
);
RPC_STATUS
RPCRT4_GetAssociation
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
RpcAssoc
**
assoc
);
RPC_STATUS
RpcAssoc_GetClientConnection
(
RpcAssoc
*
assoc
,
const
RPC_SYNTAX_IDENTIFIER
*
InterfaceId
,
const
RPC_SYNTAX_IDENTIFIER
*
TransferSyntax
,
RpcAuthInfo
*
AuthInfo
,
RpcQualityOfService
*
QOS
,
RpcConnection
**
Connection
);
void
RpcAssoc_ReleaseIdleConnection
(
RpcAssoc
*
assoc
,
RpcConnection
*
Connection
);
ULONG
RpcAssoc_Release
(
RpcAssoc
*
assoc
);
RPC_STATUS
RpcServerAssoc_GetAssociation
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
unsigned
long
assoc_gid
,
RpcAssoc
**
assoc_out
);
RPC_STATUS
RPCRT4_CreateConnection
(
RpcConnection
**
Connection
,
BOOL
server
,
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
RpcAuthInfo
*
AuthInfo
,
RpcQualityOfService
*
QOS
);
RPC_STATUS
RPCRT4_DestroyConnection
(
RpcConnection
*
Connection
);
RPC_STATUS
RPCRT4_OpenClientConnection
(
RpcConnection
*
Connection
);
...
...
dlls/rpcrt4/rpc_server.c
View file @
737510ee
...
...
@@ -42,6 +42,7 @@
#include "wine/exception.h"
#include "rpc_server.h"
#include "rpc_assoc.h"
#include "rpc_message.h"
#include "rpc_defs.h"
#include "ncastatus.h"
...
...
dlls/rpcrt4/rpc_transport.c
View file @
737510ee
...
...
@@ -79,20 +79,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
rpc
);
static
CRITICAL_SECTION
assoc_list_cs
;
static
CRITICAL_SECTION_DEBUG
assoc_list_cs_debug
=
{
0
,
0
,
&
assoc_list_cs
,
{
&
assoc_list_cs_debug
.
ProcessLocksList
,
&
assoc_list_cs_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": assoc_list_cs"
)
}
};
static
CRITICAL_SECTION
assoc_list_cs
=
{
&
assoc_list_cs_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
struct
list
client_assoc_list
=
LIST_INIT
(
client_assoc_list
);
static
struct
list
server_assoc_list
=
LIST_INIT
(
server_assoc_list
);
static
LONG
last_assoc_group_id
;
/**** ncacn_np support ****/
typedef
struct
_RpcConnection_np
...
...
@@ -1485,349 +1471,6 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server,
return
RPC_S_OK
;
}
static
RPC_STATUS
RpcAssoc_Alloc
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
RpcAssoc
**
assoc_out
)
{
RpcAssoc
*
assoc
;
assoc
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
assoc
));
if
(
!
assoc
)
return
RPC_S_OUT_OF_RESOURCES
;
assoc
->
refs
=
1
;
list_init
(
&
assoc
->
free_connection_pool
);
InitializeCriticalSection
(
&
assoc
->
cs
);
assoc
->
Protseq
=
RPCRT4_strdupA
(
Protseq
);
assoc
->
NetworkAddr
=
RPCRT4_strdupA
(
NetworkAddr
);
assoc
->
Endpoint
=
RPCRT4_strdupA
(
Endpoint
);
assoc
->
NetworkOptions
=
NetworkOptions
?
RPCRT4_strdupW
(
NetworkOptions
)
:
NULL
;
assoc
->
assoc_group_id
=
0
;
list_init
(
&
assoc
->
entry
);
*
assoc_out
=
assoc
;
return
RPC_S_OK
;
}
RPC_STATUS
RPCRT4_GetAssociation
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
RpcAssoc
**
assoc_out
)
{
RpcAssoc
*
assoc
;
RPC_STATUS
status
;
EnterCriticalSection
(
&
assoc_list_cs
);
LIST_FOR_EACH_ENTRY
(
assoc
,
&
client_assoc_list
,
RpcAssoc
,
entry
)
{
if
(
!
strcmp
(
Protseq
,
assoc
->
Protseq
)
&&
!
strcmp
(
NetworkAddr
,
assoc
->
NetworkAddr
)
&&
!
strcmp
(
Endpoint
,
assoc
->
Endpoint
)
&&
((
!
assoc
->
NetworkOptions
&&
!
NetworkOptions
)
||
!
strcmpW
(
NetworkOptions
,
assoc
->
NetworkOptions
)))
{
assoc
->
refs
++
;
*
assoc_out
=
assoc
;
LeaveCriticalSection
(
&
assoc_list_cs
);
TRACE
(
"using existing assoc %p
\n
"
,
assoc
);
return
RPC_S_OK
;
}
}
status
=
RpcAssoc_Alloc
(
Protseq
,
NetworkAddr
,
Endpoint
,
NetworkOptions
,
&
assoc
);
if
(
status
!=
RPC_S_OK
)
{
LeaveCriticalSection
(
&
assoc_list_cs
);
return
status
;
}
list_add_head
(
&
client_assoc_list
,
&
assoc
->
entry
);
*
assoc_out
=
assoc
;
LeaveCriticalSection
(
&
assoc_list_cs
);
TRACE
(
"new assoc %p
\n
"
,
assoc
);
return
RPC_S_OK
;
}
RPC_STATUS
RpcServerAssoc_GetAssociation
(
LPCSTR
Protseq
,
LPCSTR
NetworkAddr
,
LPCSTR
Endpoint
,
LPCWSTR
NetworkOptions
,
unsigned
long
assoc_gid
,
RpcAssoc
**
assoc_out
)
{
RpcAssoc
*
assoc
;
RPC_STATUS
status
;
EnterCriticalSection
(
&
assoc_list_cs
);
if
(
assoc_gid
)
{
LIST_FOR_EACH_ENTRY
(
assoc
,
&
server_assoc_list
,
RpcAssoc
,
entry
)
{
/* FIXME: NetworkAddr shouldn't be NULL */
if
(
assoc
->
assoc_group_id
==
assoc_gid
&&
!
strcmp
(
Protseq
,
assoc
->
Protseq
)
&&
(
!
NetworkAddr
||
!
assoc
->
NetworkAddr
||
!
strcmp
(
NetworkAddr
,
assoc
->
NetworkAddr
))
&&
!
strcmp
(
Endpoint
,
assoc
->
Endpoint
)
&&
((
!
assoc
->
NetworkOptions
==
!
NetworkOptions
)
&&
(
!
NetworkOptions
||
!
strcmpW
(
NetworkOptions
,
assoc
->
NetworkOptions
))))
{
assoc
->
refs
++
;
*
assoc_out
=
assoc
;
LeaveCriticalSection
(
&
assoc_list_cs
);
TRACE
(
"using existing assoc %p
\n
"
,
assoc
);
return
RPC_S_OK
;
}
}
*
assoc_out
=
NULL
;
return
RPC_S_NO_CONTEXT_AVAILABLE
;
}
status
=
RpcAssoc_Alloc
(
Protseq
,
NetworkAddr
,
Endpoint
,
NetworkOptions
,
&
assoc
);
if
(
status
!=
RPC_S_OK
)
{
LeaveCriticalSection
(
&
assoc_list_cs
);
return
status
;
}
assoc
->
assoc_group_id
=
InterlockedIncrement
(
&
last_assoc_group_id
);
list_add_head
(
&
server_assoc_list
,
&
assoc
->
entry
);
*
assoc_out
=
assoc
;
LeaveCriticalSection
(
&
assoc_list_cs
);
TRACE
(
"new assoc %p
\n
"
,
assoc
);
return
RPC_S_OK
;
}
ULONG
RpcAssoc_Release
(
RpcAssoc
*
assoc
)
{
ULONG
refs
;
EnterCriticalSection
(
&
assoc_list_cs
);
refs
=
--
assoc
->
refs
;
if
(
!
refs
)
list_remove
(
&
assoc
->
entry
);
LeaveCriticalSection
(
&
assoc_list_cs
);
if
(
!
refs
)
{
RpcConnection
*
Connection
,
*
cursor2
;
TRACE
(
"destroying assoc %p
\n
"
,
assoc
);
LIST_FOR_EACH_ENTRY_SAFE
(
Connection
,
cursor2
,
&
assoc
->
free_connection_pool
,
RpcConnection
,
conn_pool_entry
)
{
list_remove
(
&
Connection
->
conn_pool_entry
);
RPCRT4_DestroyConnection
(
Connection
);
}
HeapFree
(
GetProcessHeap
(),
0
,
assoc
->
NetworkOptions
);
HeapFree
(
GetProcessHeap
(),
0
,
assoc
->
Endpoint
);
HeapFree
(
GetProcessHeap
(),
0
,
assoc
->
NetworkAddr
);
HeapFree
(
GetProcessHeap
(),
0
,
assoc
->
Protseq
);
DeleteCriticalSection
(
&
assoc
->
cs
);
HeapFree
(
GetProcessHeap
(),
0
,
assoc
);
}
return
refs
;
}
#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
static
RPC_STATUS
RpcAssoc_BindConnection
(
const
RpcAssoc
*
assoc
,
RpcConnection
*
conn
,
const
RPC_SYNTAX_IDENTIFIER
*
InterfaceId
,
const
RPC_SYNTAX_IDENTIFIER
*
TransferSyntax
)
{
RpcPktHdr
*
hdr
;
RpcPktHdr
*
response_hdr
;
RPC_MESSAGE
msg
;
RPC_STATUS
status
;
TRACE
(
"sending bind request to server
\n
"
);
hdr
=
RPCRT4_BuildBindHeader
(
NDR_LOCAL_DATA_REPRESENTATION
,
RPC_MAX_PACKET_SIZE
,
RPC_MAX_PACKET_SIZE
,
assoc
->
assoc_group_id
,
InterfaceId
,
TransferSyntax
);
status
=
RPCRT4_Send
(
conn
,
hdr
,
NULL
,
0
);
RPCRT4_FreeHeader
(
hdr
);
if
(
status
!=
RPC_S_OK
)
return
status
;
status
=
RPCRT4_Receive
(
conn
,
&
response_hdr
,
&
msg
);
if
(
status
!=
RPC_S_OK
)
{
ERR
(
"receive failed
\n
"
);
return
status
;
}
switch
(
response_hdr
->
common
.
ptype
)
{
case
PKT_BIND_ACK
:
{
RpcAddressString
*
server_address
=
msg
.
Buffer
;
if
((
msg
.
BufferLength
>=
FIELD_OFFSET
(
RpcAddressString
,
string
[
0
]))
||
(
msg
.
BufferLength
>=
ROUND_UP
(
FIELD_OFFSET
(
RpcAddressString
,
string
[
server_address
->
length
]),
4
)))
{
unsigned
short
remaining
=
msg
.
BufferLength
-
ROUND_UP
(
FIELD_OFFSET
(
RpcAddressString
,
string
[
server_address
->
length
]),
4
);
RpcResults
*
results
=
(
RpcResults
*
)((
ULONG_PTR
)
server_address
+
ROUND_UP
(
FIELD_OFFSET
(
RpcAddressString
,
string
[
server_address
->
length
]),
4
));
if
((
results
->
num_results
==
1
)
&&
(
remaining
>=
sizeof
(
*
results
)))
{
switch
(
results
->
results
[
0
].
result
)
{
case
RESULT_ACCEPT
:
conn
->
assoc_group_id
=
response_hdr
->
bind_ack
.
assoc_gid
;
conn
->
MaxTransmissionSize
=
response_hdr
->
bind_ack
.
max_tsize
;
conn
->
ActiveInterface
=
*
InterfaceId
;
break
;
case
RESULT_PROVIDER_REJECTION
:
switch
(
results
->
results
[
0
].
reason
)
{
case
REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
:
ERR
(
"syntax %s, %d.%d not supported
\n
"
,
debugstr_guid
(
&
InterfaceId
->
SyntaxGUID
),
InterfaceId
->
SyntaxVersion
.
MajorVersion
,
InterfaceId
->
SyntaxVersion
.
MinorVersion
);
status
=
RPC_S_UNKNOWN_IF
;
break
;
case
REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED
:
ERR
(
"transfer syntax not supported
\n
"
);
status
=
RPC_S_SERVER_UNAVAILABLE
;
break
;
case
REASON_NONE
:
default:
status
=
RPC_S_CALL_FAILED_DNE
;
}
break
;
case
RESULT_USER_REJECTION
:
default:
ERR
(
"rejection result %d
\n
"
,
results
->
results
[
0
].
result
);
status
=
RPC_S_CALL_FAILED_DNE
;
}
}
else
{
ERR
(
"incorrect results size
\n
"
);
status
=
RPC_S_CALL_FAILED_DNE
;
}
}
else
{
ERR
(
"bind ack packet too small (%d)
\n
"
,
msg
.
BufferLength
);
status
=
RPC_S_PROTOCOL_ERROR
;
}
break
;
}
case
PKT_BIND_NACK
:
switch
(
response_hdr
->
bind_nack
.
reject_reason
)
{
case
REJECT_LOCAL_LIMIT_EXCEEDED
:
case
REJECT_TEMPORARY_CONGESTION
:
ERR
(
"server too busy
\n
"
);
status
=
RPC_S_SERVER_TOO_BUSY
;
break
;
case
REJECT_PROTOCOL_VERSION_NOT_SUPPORTED
:
ERR
(
"protocol version not supported
\n
"
);
status
=
RPC_S_PROTOCOL_ERROR
;
break
;
case
REJECT_UNKNOWN_AUTHN_SERVICE
:
ERR
(
"unknown authentication service
\n
"
);
status
=
RPC_S_UNKNOWN_AUTHN_SERVICE
;
break
;
case
REJECT_INVALID_CHECKSUM
:
ERR
(
"invalid checksum
\n
"
);
status
=
ERROR_ACCESS_DENIED
;
break
;
default:
ERR
(
"rejected bind for reason %d
\n
"
,
response_hdr
->
bind_nack
.
reject_reason
);
status
=
RPC_S_CALL_FAILED_DNE
;
}
break
;
default:
ERR
(
"wrong packet type received %d
\n
"
,
response_hdr
->
common
.
ptype
);
status
=
RPC_S_PROTOCOL_ERROR
;
break
;
}
I_RpcFreeBuffer
(
&
msg
);
RPCRT4_FreeHeader
(
response_hdr
);
return
status
;
}
static
RpcConnection
*
RpcAssoc_GetIdleConnection
(
RpcAssoc
*
assoc
,
const
RPC_SYNTAX_IDENTIFIER
*
InterfaceId
,
const
RPC_SYNTAX_IDENTIFIER
*
TransferSyntax
,
const
RpcAuthInfo
*
AuthInfo
,
const
RpcQualityOfService
*
QOS
)
{
RpcConnection
*
Connection
;
EnterCriticalSection
(
&
assoc
->
cs
);
/* try to find a compatible connection from the connection pool */
LIST_FOR_EACH_ENTRY
(
Connection
,
&
assoc
->
free_connection_pool
,
RpcConnection
,
conn_pool_entry
)
{
if
(
!
memcmp
(
&
Connection
->
ActiveInterface
,
InterfaceId
,
sizeof
(
RPC_SYNTAX_IDENTIFIER
))
&&
RpcAuthInfo_IsEqual
(
Connection
->
AuthInfo
,
AuthInfo
)
&&
RpcQualityOfService_IsEqual
(
Connection
->
QOS
,
QOS
))
{
list_remove
(
&
Connection
->
conn_pool_entry
);
LeaveCriticalSection
(
&
assoc
->
cs
);
TRACE
(
"got connection from pool %p
\n
"
,
Connection
);
return
Connection
;
}
}
LeaveCriticalSection
(
&
assoc
->
cs
);
return
NULL
;
}
RPC_STATUS
RpcAssoc_GetClientConnection
(
RpcAssoc
*
assoc
,
const
RPC_SYNTAX_IDENTIFIER
*
InterfaceId
,
const
RPC_SYNTAX_IDENTIFIER
*
TransferSyntax
,
RpcAuthInfo
*
AuthInfo
,
RpcQualityOfService
*
QOS
,
RpcConnection
**
Connection
)
{
RpcConnection
*
NewConnection
;
RPC_STATUS
status
;
*
Connection
=
RpcAssoc_GetIdleConnection
(
assoc
,
InterfaceId
,
TransferSyntax
,
AuthInfo
,
QOS
);
if
(
*
Connection
)
return
RPC_S_OK
;
/* create a new connection */
status
=
RPCRT4_CreateConnection
(
&
NewConnection
,
FALSE
/* is this a server connection? */
,
assoc
->
Protseq
,
assoc
->
NetworkAddr
,
assoc
->
Endpoint
,
assoc
->
NetworkOptions
,
AuthInfo
,
QOS
);
if
(
status
!=
RPC_S_OK
)
return
status
;
status
=
RPCRT4_OpenClientConnection
(
NewConnection
);
if
(
status
!=
RPC_S_OK
)
{
RPCRT4_DestroyConnection
(
NewConnection
);
return
status
;
}
status
=
RpcAssoc_BindConnection
(
assoc
,
NewConnection
,
InterfaceId
,
TransferSyntax
);
if
(
status
!=
RPC_S_OK
)
{
RPCRT4_DestroyConnection
(
NewConnection
);
return
status
;
}
*
Connection
=
NewConnection
;
return
RPC_S_OK
;
}
void
RpcAssoc_ReleaseIdleConnection
(
RpcAssoc
*
assoc
,
RpcConnection
*
Connection
)
{
assert
(
!
Connection
->
server
);
EnterCriticalSection
(
&
assoc
->
cs
);
if
(
!
assoc
->
assoc_group_id
)
assoc
->
assoc_group_id
=
Connection
->
assoc_group_id
;
list_add_head
(
&
assoc
->
free_connection_pool
,
&
Connection
->
conn_pool_entry
);
LeaveCriticalSection
(
&
assoc
->
cs
);
}
RPC_STATUS
RPCRT4_SpawnConnection
(
RpcConnection
**
Connection
,
RpcConnection
*
OldConnection
)
{
...
...
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