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 memcpy(entry
->annotation
, entries
[i
].annotation
, sizeof(entries
[i
].annotation
));
117 rpc_status
= TowerExplode(entries
[i
].tower
, &entry
->iface
, &entry
->syntax
,
118 &entry
->protseq
, &entry
->endpoint
,
120 if (rpc_status
!= RPC_S_OK
)
122 WINE_WARN("TowerExplode failed %u\n", rpc_status
);
123 *status
= rpc_status
;
124 HeapFree(GetProcessHeap(), 0, entry
);
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
);
174 delete_registered_ept_entry(entry
);
177 *status
= EPT_S_NOT_REGISTERED
;
182 LeaveCriticalSection(&csEpm
);
185 void __cdecl
ept_lookup(handle_t h
,
186 unsigned32 inquiry_type
,
188 rpc_if_id_p_t interface_id
,
189 unsigned32 vers_option
,
190 ept_lookup_handle_t
*entry_handle
,
192 unsigned32
*num_ents
,
193 ept_entry_t entries
[],
194 error_status_t
*status
)
196 WINE_FIXME("(%p, %p, %p): stub\n", h
, entry_handle
, status
);
198 *status
= EPT_S_CANT_PERFORM_OP
;
201 void __cdecl
ept_map(handle_t h
,
204 ept_lookup_handle_t
*entry_handle
,
205 unsigned32 max_towers
,
206 unsigned32
*num_towers
,
208 error_status_t
*status
)
210 RPC_STATUS rpc_status
;
211 RPC_SYNTAX_IDENTIFIER iface
, syntax
;
213 struct registered_ept_entry
*entry
;
218 WINE_TRACE("(%p, %p, %p, %p, %u, %p, %p, %p)\n", h
, object
, map_tower
,
219 entry_handle
, max_towers
, num_towers
, towers
, status
);
221 rpc_status
= TowerExplode(map_tower
, &iface
, &syntax
, &protseq
,
223 if (rpc_status
!= RPC_S_OK
)
225 *status
= rpc_status
;
229 EnterCriticalSection(&csEpm
);
231 LIST_FOR_EACH_ENTRY(entry
, ®istered_ept_entry_list
, struct registered_ept_entry
, entry
)
233 if (IsEqualGUID(&entry
->iface
.SyntaxGUID
, &iface
.SyntaxGUID
) &&
234 (entry
->iface
.SyntaxVersion
.MajorVersion
== iface
.SyntaxVersion
.MajorVersion
) &&
235 (entry
->iface
.SyntaxVersion
.MinorVersion
>= iface
.SyntaxVersion
.MinorVersion
) &&
236 !memcmp(&entry
->syntax
, &syntax
, sizeof(syntax
)) &&
237 !strcmp(entry
->protseq
, protseq
) &&
238 ((!object
&& IsEqualGUID(&entry
->object
, &nil_object
)) || IsEqualGUID(object
, &entry
->object
)))
240 if (*num_towers
< max_towers
)
242 rpc_status
= TowerConstruct(&entry
->iface
, &entry
->syntax
,
243 entry
->protseq
, entry
->endpoint
,
245 &towers
[*num_towers
]);
246 if (rpc_status
!= RPC_S_OK
)
248 *status
= rpc_status
;
249 break; /* FIXME: more cleanup? */
256 LeaveCriticalSection(&csEpm
);
261 void __cdecl
ept_lookup_handle_free(handle_t h
,
262 ept_lookup_handle_t
*entry_handle
,
263 error_status_t
*status
)
265 WINE_FIXME("(%p, %p, %p): stub\n", h
, entry_handle
, status
);
267 *status
= EPT_S_CANT_PERFORM_OP
;
270 void __cdecl
ept_inq_object(handle_t h
,
272 error_status_t
*status
)
274 WINE_FIXME("(%p, %p, %p): stub\n", h
, ept_object
, status
);
276 *status
= EPT_S_CANT_PERFORM_OP
;
279 void __cdecl
ept_mgmt_delete(handle_t h
,
280 boolean32 object_speced
,
283 error_status_t
*status
)
285 WINE_FIXME("(%p, %d, %p, %p, %p): stub\n", h
, object_speced
, object
, tower
, status
);
287 *status
= EPT_S_CANT_PERFORM_OP
;