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
9e1c7a30
Commit
9e1c7a30
authored
Jun 25, 2008
by
Rob Shearman
Committed by
Alexandre Julliard
Jun 26, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rpcrt4: Use DCE/RPC to contact the endpoint-mapper server.
parent
16849ceb
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
353 additions
and
130 deletions
+353
-130
.gitignore
.gitignore
+2
-0
Makefile.in
dlls/rpcrt4/Makefile.in
+3
-0
epm.idl
dlls/rpcrt4/epm.idl
+19
-0
epm_towers.h
dlls/rpcrt4/epm_towers.h
+2
-4
rpc_epmap.c
dlls/rpcrt4/rpc_epmap.c
+327
-126
No files found.
.gitignore
View file @
9e1c7a30
...
...
@@ -346,6 +346,8 @@ dlls/riched20/tests/testlist.c
dlls/riched32/tests/*.ok
dlls/riched32/tests/riched32_crosstest.exe
dlls/riched32/tests/testlist.c
dlls/rpcrt4/epm.h
dlls/rpcrt4/epm_c.c
dlls/rpcrt4/librpcrt4.def
dlls/rpcrt4/tests/*.ok
dlls/rpcrt4/tests/rpcrt4_crosstest.exe
...
...
dlls/rpcrt4/Makefile.in
View file @
9e1c7a30
...
...
@@ -30,6 +30,9 @@ C_SRCS = \
RC_SRCS
=
version.rc
IDL_C_SRCS
=
\
epm.idl
@MAKE_DLL_RULES@
@DEPENDENCIES@
# everything below this line is overwritten by make depend
dlls/rpcrt4/epm.idl
0 → 100644
View file @
9e1c7a30
/*
*
Copyright
2008
Robert
Shearman
*
*
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/epm.idl"
dlls/rpcrt4/epm_towers.h
View file @
9e1c7a30
...
...
@@ -19,6 +19,8 @@
*
*/
#include "wine/epm.h"
#define EPM_PROTOCOL_DNET_NSP 0x04
#define EPM_PROTOCOL_OSI_TP4 0x05
#define EPM_PROTOCOL_OSI_CLNS 0x06
...
...
@@ -48,10 +50,6 @@
#include <pshpack1.h>
typedef
unsigned
char
u_int8
;
typedef
unsigned
short
u_int16
;
typedef
unsigned
int
u_int32
;
typedef
struct
{
u_int16
count_lhs
;
...
...
dlls/rpcrt4/rpc_epmap.c
View file @
9e1c7a30
...
...
@@ -3,6 +3,7 @@
*
* Copyright 2002 Greg Turner
* Copyright 2001 Ove Kven, TransGaming Technologies
* Copyright 2008 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
...
...
@@ -17,14 +18,9 @@
* 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
*
* TODO:
* - actually do things right
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
...
...
@@ -33,8 +29,10 @@
#include "rpc.h"
#include "wine/debug.h"
#include "wine/exception.h"
#include "rpc_binding.h"
#include "epm.h"
#include "epm_towers.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
ole
);
...
...
@@ -43,8 +41,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
*
* ncadg_ip_udp: 135
* ncacn_ip_tcp: 135
* ncacn_np: \\pipe\epmapper
(?)
* ncacn_np: \\pipe\epmapper
* ncalrpc: epmapper
* ncacn_http: 593
*
* If the user's machine ran a DCE RPC daemon, it would
* probably be possible to connect to it, but there are many
...
...
@@ -63,77 +62,210 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
* of running a fully functional DCOM server using Wine...
*/
static
const
struct
epm_endpoints
{
const
char
*
protseq
;
const
char
*
endpoint
;
}
epm_endpoints
[]
=
{
{
"ncacn_np"
,
"
\\
pipe
\\
epmapper"
},
{
"ncacn_ip_tcp"
,
"135"
},
{
"ncacn_ip_udp"
,
"135"
},
{
"ncalprc"
,
"epmapper"
},
{
"ncacn_http"
,
"593"
},
};
static
BOOL
start_rpcss
(
void
)
{
PROCESS_INFORMATION
pi
;
STARTUPINFOW
si
;
static
WCHAR
cmd
[
6
];
static
const
WCHAR
rpcss
[]
=
{
'r'
,
'p'
,
'c'
,
's'
,
's'
,
0
};
BOOL
rslt
;
TRACE
(
"
\n
"
);
ZeroMemory
(
&
pi
,
sizeof
(
PROCESS_INFORMATION
));
ZeroMemory
(
&
si
,
sizeof
(
STARTUPINFOA
));
si
.
cb
=
sizeof
(
STARTUPINFOA
);
memcpy
(
cmd
,
rpcss
,
sizeof
(
rpcss
));
rslt
=
CreateProcessW
(
NULL
,
/* executable */
cmd
,
/* command line */
NULL
,
/* process security attributes */
NULL
,
/* primary thread security attributes */
FALSE
,
/* inherit handles */
0
,
/* creation flags */
NULL
,
/* use parent's environment */
NULL
,
/* use parent's current directory */
&
si
,
/* STARTUPINFO pointer */
&
pi
/* PROCESS_INFORMATION */
);
if
(
rslt
)
{
CloseHandle
(
pi
.
hProcess
);
CloseHandle
(
pi
.
hThread
);
Sleep
(
100
);
}
return
rslt
;
}
static
RPC_STATUS
get_epm_handle_client
(
RPC_BINDING_HANDLE
handle
,
RPC_BINDING_HANDLE
*
epm_handle
)
{
RpcBinding
*
bind
=
(
RpcBinding
*
)
handle
;
const
char
*
pszEndpoint
=
NULL
;
RPC_STATUS
status
;
RpcBinding
*
epm_bind
;
unsigned
int
i
;
if
(
bind
->
server
)
return
RPC_S_INVALID_BINDING
;
for
(
i
=
0
;
i
<
sizeof
(
epm_endpoints
)
/
sizeof
(
epm_endpoints
[
0
]);
i
++
)
if
(
!
strcmp
(
bind
->
Protseq
,
epm_endpoints
[
i
].
protseq
))
pszEndpoint
=
epm_endpoints
[
i
].
endpoint
;
if
(
!
pszEndpoint
)
{
FIXME
(
"no endpoint for the endpoint-mapper found for protseq %s
\n
"
,
debugstr_a
(
bind
->
Protseq
));
return
RPC_S_PROTSEQ_NOT_SUPPORTED
;
}
status
=
RpcBindingCopy
(
handle
,
epm_handle
);
if
(
status
!=
RPC_S_OK
)
return
status
;
epm_bind
=
(
RpcBinding
*
)
*
epm_handle
;
if
(
epm_bind
->
AuthInfo
)
{
/* don't bother with authenticating against the EPM by default
* (see EnableAuthEpResolution registry value) */
RpcAuthInfo_Release
(
epm_bind
->
AuthInfo
);
epm_bind
->
AuthInfo
=
NULL
;
}
RPCRT4_ResolveBinding
(
epm_bind
,
pszEndpoint
);
TRACE
(
"RPC_S_OK
\n
"
);
return
RPC_S_OK
;
}
static
RPC_STATUS
get_epm_handle_server
(
RPC_BINDING_HANDLE
*
epm_handle
)
{
unsigned
char
string_binding
[]
=
"ncacn_np:.[
\\
pipe
\\
epmapper]"
;
return
RpcBindingFromStringBindingA
(
string_binding
,
epm_handle
);
}
static
LONG
WINAPI
rpc_filter
(
EXCEPTION_POINTERS
*
__eptr
)
{
switch
(
GetExceptionCode
())
{
case
EXCEPTION_ACCESS_VIOLATION
:
case
EXCEPTION_ILLEGAL_INSTRUCTION
:
return
EXCEPTION_CONTINUE_SEARCH
;
default:
return
EXCEPTION_EXECUTE_HANDLER
;
}
}
/***********************************************************************
* RpcEpRegisterA (RPCRT4.@)
*/
RPC_STATUS
WINAPI
RpcEpRegisterA
(
RPC_IF_HANDLE
IfSpec
,
RPC_BINDING_VECTOR
*
BindingVector
,
UUID_VECTOR
*
UuidVector
,
RPC_CSTR
Annotation
)
{
RPCSS_NP_MESSAGE
msg
;
RPCSS_NP_REPLY
reply
;
char
*
vardata_payload
,
*
vp
;
PRPC_SERVER_INTERFACE
If
=
(
PRPC_SERVER_INTERFACE
)
IfSpec
;
unsigned
long
c
;
RPC_STATUS
rslt
=
RPC_S_OK
;
unsigned
long
i
;
RPC_STATUS
status
=
RPC_S_OK
;
error_status_t
status2
;
ept_entry_t
*
entries
;
handle_t
handle
;
TRACE
(
"(%p,%p,%p,%s)
\n
"
,
IfSpec
,
BindingVector
,
UuidVector
,
debugstr_a
((
char
*
)
Annotation
));
TRACE
(
" ifid=%s
\n
"
,
debugstr_guid
(
&
If
->
InterfaceId
.
SyntaxGUID
));
for
(
c
=
0
;
c
<
BindingVector
->
Count
;
c
++
)
{
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
c
]);
TRACE
(
" protseq[%ld]=%s
\n
"
,
c
,
debugstr_a
(
bind
->
Protseq
));
TRACE
(
" endpoint[%ld]=%s
\n
"
,
c
,
debugstr_a
(
bind
->
Endpoint
));
for
(
i
=
0
;
i
<
BindingVector
->
Count
;
i
++
)
{
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
i
]);
TRACE
(
" protseq[%ld]=%s
\n
"
,
i
,
debugstr_a
(
bind
->
Protseq
));
TRACE
(
" endpoint[%ld]=%s
\n
"
,
i
,
debugstr_a
(
bind
->
Endpoint
));
}
if
(
UuidVector
)
{
for
(
c
=
0
;
c
<
UuidVector
->
Count
;
c
++
)
TRACE
(
" obj[%ld]=%s
\n
"
,
c
,
debugstr_guid
(
UuidVector
->
Uuid
[
c
]));
for
(
i
=
0
;
i
<
UuidVector
->
Count
;
i
++
)
TRACE
(
" obj[%ld]=%s
\n
"
,
i
,
debugstr_guid
(
UuidVector
->
Uuid
[
i
]));
}
/* FIXME: Do something with annotation. */
if
(
!
BindingVector
->
Count
)
return
RPC_S_OK
;
/* construct the message to rpcss */
msg
.
message_type
=
RPCSS_NP_MESSAGE_TYPEID_REGISTEREPMSG
;
msg
.
message
.
registerepmsg
.
iface
=
If
->
InterfaceId
;
msg
.
message
.
registerepmsg
.
no_replace
=
0
;
entries
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
entries
)
*
BindingVector
->
Count
*
(
UuidVector
?
UuidVector
->
Count
:
1
));
if
(
!
entries
)
return
RPC_S_OUT_OF_MEMORY
;
msg
.
message
.
registerepmsg
.
object_count
=
(
UuidVector
)
?
UuidVector
->
Count
:
0
;
msg
.
message
.
registerepmsg
.
binding_count
=
BindingVector
->
Count
;
/* calculate vardata payload size */
msg
.
vardata_payload_size
=
msg
.
message
.
registerepmsg
.
object_count
*
sizeof
(
UUID
);
for
(
c
=
0
;
c
<
msg
.
message
.
registerepmsg
.
binding_count
;
c
++
)
{
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
c
]);
msg
.
vardata_payload_size
+=
strlen
(
bind
->
Protseq
)
+
1
;
msg
.
vardata_payload_size
+=
strlen
(
bind
->
Endpoint
)
+
1
;
status
=
get_epm_handle_server
(
&
handle
);
if
(
status
!=
RPC_S_OK
)
{
HeapFree
(
GetProcessHeap
(),
0
,
entries
);
return
status
;
}
/* allocate the payload buffer */
vp
=
vardata_payload
=
LocalAlloc
(
LPTR
,
msg
.
vardata_payload_size
);
if
(
!
vardata_payload
)
return
RPC_S_OUT_OF_MEMORY
;
/* populate the payload data */
for
(
c
=
0
;
c
<
msg
.
message
.
registerepmsg
.
object_count
;
c
++
)
{
CopyMemory
(
vp
,
UuidVector
->
Uuid
[
c
],
sizeof
(
UUID
));
vp
+=
sizeof
(
UUID
);
for
(
i
=
0
;
i
<
BindingVector
->
Count
;
i
++
)
{
unsigned
j
;
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
i
]);
for
(
j
=
0
;
j
<
(
UuidVector
?
UuidVector
->
Count
:
1
);
j
++
)
{
int
len
=
strlen
((
char
*
)
Annotation
);
status
=
TowerConstruct
(
&
If
->
InterfaceId
,
&
If
->
TransferSyntax
,
bind
->
Protseq
,
bind
->
Endpoint
,
bind
->
NetworkAddr
,
&
entries
[
i
*
(
UuidVector
?
UuidVector
->
Count
:
1
)
+
j
].
tower
);
if
(
status
!=
RPC_S_OK
)
break
;
if
(
UuidVector
)
memcpy
(
&
entries
[
i
*
UuidVector
->
Count
].
object
,
&
UuidVector
->
Uuid
[
j
],
sizeof
(
GUID
));
else
memset
(
&
entries
[
i
].
object
,
0
,
sizeof
(
entries
[
i
].
object
));
memcpy
(
entries
[
i
].
annotation
,
Annotation
,
min
(
len
+
1
,
ept_max_annotation_size
));
}
}
for
(
c
=
0
;
c
<
msg
.
message
.
registerepmsg
.
binding_count
;
c
++
)
{
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
c
]);
unsigned
long
pslen
=
strlen
(
bind
->
Protseq
)
+
1
,
eplen
=
strlen
(
bind
->
Endpoint
)
+
1
;
CopyMemory
(
vp
,
bind
->
Protseq
,
pslen
);
vp
+=
pslen
;
CopyMemory
(
vp
,
bind
->
Endpoint
,
eplen
);
vp
+=
eplen
;
if
(
status
==
RPC_S_OK
)
{
while
(
TRUE
)
{
__TRY
{
ept_insert
(
handle
,
BindingVector
->
Count
*
(
UuidVector
?
UuidVector
->
Count
:
1
),
entries
,
TRUE
,
&
status2
);
}
__EXCEPT
(
rpc_filter
)
{
status2
=
GetExceptionCode
();
}
__ENDTRY
if
(
status2
==
RPC_S_SERVER_UNAVAILABLE
)
{
if
(
start_rpcss
())
continue
;
}
if
(
status2
!=
RPC_S_OK
)
ERR
(
"ept_insert failed with error %d
\n
"
,
status2
);
status
=
status2
;
/* FIXME: convert status? */
break
;
}
}
RpcBindingFree
(
&
handle
);
/* send our request */
if
(
!
RPCRT4_RPCSSOnDemandCall
(
&
msg
,
vardata_payload
,
&
reply
))
rslt
=
RPC_S_OUT_OF_MEMORY
;
for
(
i
=
0
;
i
<
BindingVector
->
Count
;
i
++
)
{
unsigned
j
;
for
(
j
=
0
;
j
<
(
UuidVector
?
UuidVector
->
Count
:
1
);
j
++
)
I_RpcFree
(
entries
[
i
*
(
UuidVector
?
UuidVector
->
Count
:
1
)
+
j
].
tower
);
}
/* free the payload buffer */
LocalFree
(
vardata_payload
);
HeapFree
(
GetProcessHeap
(),
0
,
entries
);
return
rslt
;
return
status
;
}
/***********************************************************************
...
...
@@ -142,68 +274,85 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
RPC_STATUS
WINAPI
RpcEpUnregister
(
RPC_IF_HANDLE
IfSpec
,
RPC_BINDING_VECTOR
*
BindingVector
,
UUID_VECTOR
*
UuidVector
)
{
RPCSS_NP_MESSAGE
msg
;
RPCSS_NP_REPLY
reply
;
char
*
vardata_payload
,
*
vp
;
PRPC_SERVER_INTERFACE
If
=
(
PRPC_SERVER_INTERFACE
)
IfSpec
;
unsigned
long
c
;
RPC_STATUS
rslt
=
RPC_S_OK
;
unsigned
long
i
;
RPC_STATUS
status
=
RPC_S_OK
;
error_status_t
status2
;
ept_entry_t
*
entries
;
handle_t
handle
;
TRACE
(
"(%p,%p,%p)
\n
"
,
IfSpec
,
BindingVector
,
UuidVector
);
TRACE
(
" ifid=%s
\n
"
,
debugstr_guid
(
&
If
->
InterfaceId
.
SyntaxGUID
));
for
(
c
=
0
;
c
<
BindingVector
->
Count
;
c
++
)
{
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
c
]);
TRACE
(
" protseq[%ld]=%s
\n
"
,
c
,
debugstr_a
(
bind
->
Protseq
));
TRACE
(
" endpoint[%ld]=%s
\n
"
,
c
,
debugstr_a
(
bind
->
Endpoint
));
for
(
i
=
0
;
i
<
BindingVector
->
Count
;
i
++
)
{
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
i
]);
TRACE
(
" protseq[%ld]=%s
\n
"
,
i
,
debugstr_a
(
bind
->
Protseq
));
TRACE
(
" endpoint[%ld]=%s
\n
"
,
i
,
debugstr_a
(
bind
->
Endpoint
));
}
if
(
UuidVector
)
{
for
(
c
=
0
;
c
<
UuidVector
->
Count
;
c
++
)
TRACE
(
" obj[%ld]=%s
\n
"
,
c
,
debugstr_guid
(
UuidVector
->
Uuid
[
c
]));
for
(
i
=
0
;
i
<
UuidVector
->
Count
;
i
++
)
TRACE
(
" obj[%ld]=%s
\n
"
,
i
,
debugstr_guid
(
UuidVector
->
Uuid
[
i
]));
}
/* construct the message to rpcss */
msg
.
message_type
=
RPCSS_NP_MESSAGE_TYPEID_UNREGISTEREPMSG
;
msg
.
message
.
unregisterepmsg
.
iface
=
If
->
InterfaceId
;
msg
.
message
.
unregisterepmsg
.
object_count
=
(
UuidVector
)
?
UuidVector
->
Count
:
0
;
msg
.
message
.
unregisterepmsg
.
binding_count
=
BindingVector
->
Count
;
entries
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
entries
)
*
BindingVector
->
Count
*
(
UuidVector
?
UuidVector
->
Count
:
1
));
if
(
!
entries
)
return
RPC_S_OUT_OF_MEMORY
;
/* calculate vardata payload size */
msg
.
vardata_payload_size
=
msg
.
message
.
unregisterepmsg
.
object_count
*
sizeof
(
UUID
);
for
(
c
=
0
;
c
<
msg
.
message
.
unregisterepmsg
.
binding_count
;
c
++
)
{
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
c
]);
msg
.
vardata_payload_size
+=
strlen
(
bind
->
Protseq
)
+
1
;
msg
.
vardata_payload_size
+=
strlen
(
bind
->
Endpoint
)
+
1
;
status
=
get_epm_handle_server
(
&
handle
);
if
(
status
!=
RPC_S_OK
)
{
HeapFree
(
GetProcessHeap
(),
0
,
entries
);
return
status
;
}
/* allocate the payload buffer */
vp
=
vardata_payload
=
LocalAlloc
(
LPTR
,
msg
.
vardata_payload_size
);
if
(
!
vardata_payload
)
return
RPC_S_OUT_OF_MEMORY
;
/* populate the payload data */
for
(
c
=
0
;
c
<
msg
.
message
.
unregisterepmsg
.
object_count
;
c
++
)
{
CopyMemory
(
vp
,
UuidVector
->
Uuid
[
c
],
sizeof
(
UUID
));
vp
+=
sizeof
(
UUID
);
for
(
i
=
0
;
i
<
BindingVector
->
Count
;
i
++
)
{
unsigned
j
;
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
i
]);
for
(
j
=
0
;
j
<
(
UuidVector
?
UuidVector
->
Count
:
1
);
j
++
)
{
status
=
TowerConstruct
(
&
If
->
InterfaceId
,
&
If
->
TransferSyntax
,
bind
->
Protseq
,
bind
->
Endpoint
,
bind
->
NetworkAddr
,
&
entries
[
i
*
(
UuidVector
?
UuidVector
->
Count
:
1
)
+
j
].
tower
);
if
(
status
!=
RPC_S_OK
)
break
;
if
(
UuidVector
)
memcpy
(
&
entries
[
i
*
UuidVector
->
Count
+
j
].
object
,
&
UuidVector
->
Uuid
[
j
],
sizeof
(
GUID
));
else
memset
(
&
entries
[
i
].
object
,
0
,
sizeof
(
entries
[
i
].
object
));
}
}
for
(
c
=
0
;
c
<
msg
.
message
.
unregisterepmsg
.
binding_count
;
c
++
)
{
RpcBinding
*
bind
=
(
RpcBinding
*
)(
BindingVector
->
BindingH
[
c
]);
unsigned
long
pslen
=
strlen
(
bind
->
Protseq
)
+
1
,
eplen
=
strlen
(
bind
->
Endpoint
)
+
1
;
CopyMemory
(
vp
,
bind
->
Protseq
,
pslen
);
vp
+=
pslen
;
CopyMemory
(
vp
,
bind
->
Endpoint
,
eplen
);
vp
+=
eplen
;
if
(
status
==
RPC_S_OK
)
{
__TRY
{
ept_insert
(
handle
,
BindingVector
->
Count
*
(
UuidVector
?
UuidVector
->
Count
:
1
),
entries
,
TRUE
,
&
status2
);
}
__EXCEPT
(
rpc_filter
)
{
status2
=
GetExceptionCode
();
}
__ENDTRY
if
(
status2
==
RPC_S_SERVER_UNAVAILABLE
)
status2
=
EPT_S_NOT_REGISTERED
;
if
(
status2
!=
RPC_S_OK
)
ERR
(
"ept_insert failed with error %d
\n
"
,
status2
);
status
=
status2
;
/* FIXME: convert status? */
}
RpcBindingFree
(
&
handle
);
/* send our request */
if
(
!
RPCRT4_RPCSSOnDemandCall
(
&
msg
,
vardata_payload
,
&
reply
))
rslt
=
RPC_S_OUT_OF_MEMORY
;
for
(
i
=
0
;
i
<
BindingVector
->
Count
;
i
++
)
{
unsigned
j
;
for
(
j
=
0
;
j
<
(
UuidVector
?
UuidVector
->
Count
:
1
);
j
++
)
I_RpcFree
(
entries
[
i
*
(
UuidVector
?
UuidVector
->
Count
:
1
)
+
j
].
tower
);
}
/* free the payload buffer */
LocalFree
(
vardata_payload
);
HeapFree
(
GetProcessHeap
(),
0
,
entries
);
return
rslt
;
return
status
;
}
/***********************************************************************
...
...
@@ -211,51 +360,93 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
*/
RPC_STATUS
WINAPI
RpcEpResolveBinding
(
RPC_BINDING_HANDLE
Binding
,
RPC_IF_HANDLE
IfSpec
)
{
RPCSS_NP_MESSAGE
msg
;
RPCSS_NP_REPLY
reply
;
PRPC_CLIENT_INTERFACE
If
=
(
PRPC_CLIENT_INTERFACE
)
IfSpec
;
RpcBinding
*
bind
=
(
RpcBinding
*
)
Binding
;
RPC_STATUS
status
;
error_status_t
status2
;
handle_t
handle
;
ept_lookup_handle_t
entry_handle
=
NULL
;
twr_t
*
tower
;
twr_t
*
towers
[
4
]
=
{
NULL
};
unsigned32
num_towers
,
i
;
GUID
uuid
=
GUID_NULL
;
char
*
resolved_endpoint
=
NULL
;
TRACE
(
"(%p,%p)
\n
"
,
Binding
,
IfSpec
);
TRACE
(
" protseq=%s
\n
"
,
debugstr_a
(
bind
->
Protseq
));
TRACE
(
" obj=%s
\n
"
,
debugstr_guid
(
&
bind
->
ObjectUuid
));
TRACE
(
" networkaddr=%s
\n
"
,
debugstr_a
(
bind
->
NetworkAddr
));
TRACE
(
" ifid=%s
\n
"
,
debugstr_guid
(
&
If
->
InterfaceId
.
SyntaxGUID
));
/* FIXME: totally untested */
/* just return for fully bound handles */
if
(
bind
->
Endpoint
&&
(
bind
->
Endpoint
[
0
]
!=
'\0'
))
return
RPC_S_OK
;
/* construct the message to rpcss */
msg
.
message_type
=
RPCSS_NP_MESSAGE_TYPEID_RESOLVEEPMSG
;
msg
.
message
.
resolveepmsg
.
iface
=
If
->
InterfaceId
;
msg
.
message
.
resolveepmsg
.
object
=
bind
->
ObjectUuid
;
msg
.
vardata_payload_size
=
strlen
(
bind
->
Protseq
)
+
1
;
status
=
get_epm_handle_client
(
Binding
,
&
handle
);
if
(
status
!=
RPC_S_OK
)
return
status
;
status
=
TowerConstruct
(
&
If
->
InterfaceId
,
&
If
->
TransferSyntax
,
bind
->
Protseq
,
((
RpcBinding
*
)
handle
)
->
Endpoint
,
bind
->
NetworkAddr
,
&
tower
);
if
(
status
!=
RPC_S_OK
)
{
WARN
(
"couldn't get tower
\n
"
);
RpcBindingFree
(
&
handle
);
return
status
;
}
/* send the message */
if
(
!
RPCRT4_RPCSSOnDemandCall
(
&
msg
,
bind
->
Protseq
,
&
reply
))
return
RPC_S_OUT_OF_MEMORY
;
while
(
TRUE
)
{
__TRY
{
ept_map
(
handle
,
&
uuid
,
tower
,
&
entry_handle
,
sizeof
(
towers
)
/
sizeof
(
towers
[
0
]),
&
num_towers
,
towers
,
&
status2
);
/* FIXME: translate status2? */
}
__EXCEPT
(
rpc_filter
)
{
status2
=
GetExceptionCode
();
}
__ENDTRY
if
(
status2
==
RPC_S_SERVER_UNAVAILABLE
)
{
if
(
start_rpcss
())
continue
;
}
break
;
};
/* empty-string result means not registered */
if
(
reply
.
as_string
[
0
]
==
'\0'
)
return
EPT_S_NOT_REGISTERED
;
/* otherwise we fully bind the handle & return RPC_S_OK */
return
RPCRT4_ResolveBinding
(
Binding
,
reply
.
as_string
);
}
RpcBindingFree
(
&
handle
);
I_RpcFree
(
tower
);
typedef
unsigned
int
unsigned32
;
typedef
struct
twr_t
if
(
status2
!=
RPC_S_OK
)
{
ERR
(
"ept_map failed for ifid %s, protseq %s, networkaddr %s
\n
"
,
debugstr_guid
(
&
If
->
TransferSyntax
.
SyntaxGUID
),
bind
->
Protseq
,
bind
->
NetworkAddr
);
return
status2
;
}
for
(
i
=
0
;
i
<
num_towers
;
i
++
)
{
/* only parse the tower if we haven't already found a suitable
* endpoint, otherwise just free the tower */
if
(
!
resolved_endpoint
)
{
unsigned32
tower_length
;
/* [size_is] */
BYTE
tower_octet_string
[
1
];
}
twr_t
;
status
=
TowerExplode
(
towers
[
i
],
NULL
,
NULL
,
NULL
,
&
resolved_endpoint
,
NULL
);
TRACE
(
"status = %ld
\n
"
,
status
);
}
I_RpcFree
(
towers
[
i
]);
}
if
(
resolved_endpoint
)
{
RPCRT4_ResolveBinding
(
Binding
,
resolved_endpoint
);
I_RpcFree
(
resolved_endpoint
);
return
RPC_S_OK
;
}
WARN
(
"couldn't find an endpoint
\n
"
);
return
EPT_S_NOT_REGISTERED
;
}
/***********************************************************************
* TowerExplode (RPCRT4.@)
*/
RPC_STATUS
WINAPI
TowerExplode
(
const
twr_t
*
tower
,
PRPC_SYNTAX_IDENTIFIER
object
,
PRPC_SYNTAX_IDENTIFIER
syntax
,
char
**
protseq
,
char
**
endpoint
,
char
**
address
)
...
...
@@ -388,3 +579,13 @@ RPC_STATUS WINAPI TowerConstruct(
}
return
RPC_S_OK
;
}
void
__RPC_FAR
*
__RPC_USER
MIDL_user_allocate
(
size_t
len
)
{
return
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
}
void
__RPC_USER
MIDL_user_free
(
void
__RPC_FAR
*
ptr
)
{
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
}
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