4 * Copyright (C) 2007 Robert Shearman for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/debug.h"
24 #include "wine/list.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
28 struct registered_ept_entry
32 RPC_SYNTAX_IDENTIFIER iface
;
33 RPC_SYNTAX_IDENTIFIER syntax
;
37 char annotation
[ept_max_annotation_size
];
40 static struct list registered_ept_entry_list
= LIST_INIT(registered_ept_entry_list
);
42 static CRITICAL_SECTION csEpm
;
43 static CRITICAL_SECTION_DEBUG critsect_debug
=
46 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
47 0, 0, { (DWORD_PTR
)(__FILE__
": csEpm") }
49 static CRITICAL_SECTION csEpm
= { &critsect_debug
, -1, 0, 0, 0, 0 };
51 static const UUID nil_object
;
53 /* must be called inside csEpm */
54 static void delete_registered_ept_entry(struct registered_ept_entry
*entry
)
56 I_RpcFree(entry
->protseq
);
57 I_RpcFree(entry
->endpoint
);
58 I_RpcFree(entry
->address
);
59 list_remove(&entry
->entry
);
60 HeapFree(GetProcessHeap(), 0, entry
);
63 static struct registered_ept_entry
*find_ept_entry(
64 const RPC_SYNTAX_IDENTIFIER
*iface
, const RPC_SYNTAX_IDENTIFIER
*syntax
,
65 const char *protseq
, const char *endpoint
, const char *address
,
68 struct registered_ept_entry
*entry
;
69 LIST_FOR_EACH_ENTRY(entry
, ®istered_ept_entry_list
, struct registered_ept_entry
, entry
)
71 if (memcmp(&entry
->iface
, iface
, sizeof(RPC_SYNTAX_IDENTIFIER
))) continue;
72 if (memcmp(&entry
->syntax
, syntax
, sizeof(RPC_SYNTAX_IDENTIFIER
))) continue;
73 if (strcmp(entry
->protseq
, protseq
)) continue;
74 if (memcmp(&entry
->object
, object
, sizeof(UUID
))) continue;
75 WINE_TRACE("found entry with iface %d.%d %s, syntax %d.%d %s, protseq %s, object %s\n",
76 entry
->iface
.SyntaxVersion
.MajorVersion
, entry
->iface
.SyntaxVersion
.MinorVersion
,
77 wine_dbgstr_guid(&entry
->iface
.SyntaxGUID
),
78 entry
->syntax
.SyntaxVersion
.MajorVersion
, entry
->syntax
.SyntaxVersion
.MinorVersion
,
79 wine_dbgstr_guid(&entry
->syntax
.SyntaxGUID
), protseq
,
80 wine_dbgstr_guid(&entry
->object
));
83 WINE_TRACE("not found\n");
87 void __RPC_USER
ept_lookup_handle_t_rundown(ept_lookup_handle_t entry_handle
)
89 WINE_FIXME("%p\n", entry_handle
);
92 void __cdecl
ept_insert(handle_t h
,
94 ept_entry_t entries
[],
96 error_status_t
*status
)
99 RPC_STATUS rpc_status
;
101 WINE_TRACE("(%p, %u, %p, %u, %p)\n", h
, num_ents
, entries
, replace
, status
);
105 EnterCriticalSection(&csEpm
);
107 for (i
= 0; i
< num_ents
; i
++)
109 struct registered_ept_entry
*entry
= HeapAlloc(GetProcessHeap(), 0, sizeof(*entry
));
112 /* FIXME: cleanup code to delete added entries */
113 *status
= EPT_S_CANT_PERFORM_OP
;
116 list_init(&entry
->entry
);
117 memcpy(entry
->annotation
, entries
[i
].annotation
, sizeof(entries
[i
].annotation
));
118 rpc_status
= TowerExplode(entries
[i
].tower
, &entry
->iface
, &entry
->syntax
,
119 &entry
->protseq
, &entry
->endpoint
,
121 if (rpc_status
!= RPC_S_OK
)
123 WINE_WARN("TowerExplode failed %u\n", rpc_status
);
124 *status
= rpc_status
;
125 break; /* FIXME: more cleanup? */
128 entry
->object
= entries
[i
].object
;
132 /* FIXME: correct find algorithm */
133 struct registered_ept_entry
*old_entry
= find_ept_entry(&entry
->iface
, &entry
->syntax
, entry
->protseq
, entry
->endpoint
, entry
->address
, &entry
->object
);
134 if (old_entry
) delete_registered_ept_entry(old_entry
);
136 list_add_tail(®istered_ept_entry_list
, &entry
->entry
);
139 LeaveCriticalSection(&csEpm
);
142 void __cdecl
ept_delete(handle_t h
,
144 ept_entry_t entries
[],
145 error_status_t
*status
)
148 RPC_STATUS rpc_status
;
152 WINE_TRACE("(%p, %u, %p, %p)\n", h
, num_ents
, entries
, status
);
154 EnterCriticalSection(&csEpm
);
156 for (i
= 0; i
< num_ents
; i
++)
158 struct registered_ept_entry
*entry
;
159 RPC_SYNTAX_IDENTIFIER iface
, syntax
;
163 rpc_status
= TowerExplode(entries
[i
].tower
, &iface
, &syntax
, &protseq
,
164 &endpoint
, &address
);
165 if (rpc_status
!= RPC_S_OK
)
167 entry
= find_ept_entry(&iface
, &syntax
, protseq
, endpoint
, address
, &entries
[i
].object
);
169 delete_registered_ept_entry(entry
);
172 *status
= EPT_S_NOT_REGISTERED
;
180 LeaveCriticalSection(&csEpm
);
183 void __cdecl
ept_lookup(handle_t h
,
184 unsigned32 inquiry_type
,
186 rpc_if_id_p_t interface_id
,
187 unsigned32 vers_option
,
188 ept_lookup_handle_t
*entry_handle
,
190 unsigned32
*num_ents
,
191 ept_entry_t entries
[],
192 error_status_t
*status
)
194 WINE_FIXME("(%p, %p, %p): stub\n", h
, entry_handle
, status
);
196 *status
= EPT_S_CANT_PERFORM_OP
;
199 void __cdecl
ept_map(handle_t h
,
202 ept_lookup_handle_t
*entry_handle
,
203 unsigned32 max_towers
,
204 unsigned32
*num_towers
,
206 error_status_t
*status
)
208 RPC_STATUS rpc_status
;
209 RPC_SYNTAX_IDENTIFIER iface
, syntax
;
211 struct registered_ept_entry
*entry
;
216 WINE_TRACE("(%p, %p, %p, %p, %u, %p, %p, %p)\n", h
, object
, map_tower
,
217 entry_handle
, max_towers
, num_towers
, towers
, status
);
219 rpc_status
= TowerExplode(map_tower
, &iface
, &syntax
, &protseq
,
221 if (rpc_status
!= RPC_S_OK
)
223 *status
= rpc_status
;
227 EnterCriticalSection(&csEpm
);
229 LIST_FOR_EACH_ENTRY(entry
, ®istered_ept_entry_list
, struct registered_ept_entry
, entry
)
231 if (IsEqualGUID(&entry
->iface
.SyntaxGUID
, &iface
.SyntaxGUID
) &&
232 (entry
->iface
.SyntaxVersion
.MajorVersion
== iface
.SyntaxVersion
.MajorVersion
) &&
233 (entry
->iface
.SyntaxVersion
.MinorVersion
>= iface
.SyntaxVersion
.MinorVersion
) &&
234 !memcmp(&entry
->syntax
, &syntax
, sizeof(syntax
)) &&
235 !strcmp(entry
->protseq
, protseq
) &&
236 ((!object
&& IsEqualGUID(&entry
->object
, &nil_object
)) || IsEqualGUID(object
, &entry
->object
)))
238 if (*num_towers
< max_towers
)
240 rpc_status
= TowerConstruct(&entry
->iface
, &entry
->syntax
,
241 entry
->protseq
, entry
->endpoint
,
243 &towers
[*num_towers
]);
244 if (rpc_status
!= RPC_S_OK
)
246 *status
= rpc_status
;
247 break; /* FIXME: more cleanup? */
254 LeaveCriticalSection(&csEpm
);
257 void __cdecl
ept_lookup_handle_free(handle_t h
,
258 ept_lookup_handle_t
*entry_handle
,
259 error_status_t
*status
)
261 WINE_FIXME("(%p, %p, %p): stub\n", h
, entry_handle
, status
);
263 *status
= EPT_S_CANT_PERFORM_OP
;
266 void __cdecl
ept_inq_object(handle_t h
,
268 error_status_t
*status
)
270 WINE_FIXME("(%p, %p, %p): stub\n", h
, ept_object
, status
);
272 *status
= EPT_S_CANT_PERFORM_OP
;
275 void __cdecl
ept_mgmt_delete(handle_t h
,
276 boolean32 object_speced
,
279 error_status_t
*status
)
281 WINE_FIXME("(%p, %d, %p, %p, %p): stub\n", h
, object_speced
, object
, tower
, status
);
283 *status
= EPT_S_CANT_PERFORM_OP
;