[TFTPD] Fix compilation, and use the #define MAX_SERVERS where needed instead of...
[reactos.git] / base / services / rpcss / epmp.c
1 /*
2 * Endpoint Mapper
3 *
4 * Copyright (C) 2007 Robert Shearman for CodeWeavers
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include "rpcss.h"
22
23 #include <wine/debug.h>
24
25 WINE_DEFAULT_DEBUG_CHANNEL(ole);
26
27 struct registered_ept_entry
28 {
29 struct list entry;
30 GUID object;
31 RPC_SYNTAX_IDENTIFIER iface;
32 RPC_SYNTAX_IDENTIFIER syntax;
33 char *protseq;
34 char *endpoint;
35 char *address;
36 char annotation[ept_max_annotation_size];
37 };
38
39 static struct list registered_ept_entry_list = LIST_INIT(registered_ept_entry_list);
40
41 static CRITICAL_SECTION csEpm;
42 static CRITICAL_SECTION_DEBUG critsect_debug =
43 {
44 0, 0, &csEpm,
45 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
46 0, 0, { (DWORD_PTR)(__FILE__ ": csEpm") }
47 };
48 static CRITICAL_SECTION csEpm = { &critsect_debug, -1, 0, 0, 0, 0 };
49
50 static const UUID nil_object;
51
52 /* must be called inside csEpm */
53 static void delete_registered_ept_entry(struct registered_ept_entry *entry)
54 {
55 I_RpcFree(entry->protseq);
56 I_RpcFree(entry->endpoint);
57 I_RpcFree(entry->address);
58 list_remove(&entry->entry);
59 HeapFree(GetProcessHeap(), 0, entry);
60 }
61
62 static struct registered_ept_entry *find_ept_entry(
63 const RPC_SYNTAX_IDENTIFIER *iface, const RPC_SYNTAX_IDENTIFIER *syntax,
64 const char *protseq, const char *endpoint, const char *address,
65 const UUID *object)
66 {
67 struct registered_ept_entry *entry;
68 LIST_FOR_EACH_ENTRY(entry, &registered_ept_entry_list, struct registered_ept_entry, entry)
69 {
70 if (memcmp(&entry->iface, iface, sizeof(RPC_SYNTAX_IDENTIFIER))) continue;
71 if (memcmp(&entry->syntax, syntax, sizeof(RPC_SYNTAX_IDENTIFIER))) continue;
72 if (strcmp(entry->protseq, protseq)) continue;
73 if (memcmp(&entry->object, object, sizeof(UUID))) continue;
74 WINE_TRACE("found entry with iface %d.%d %s, syntax %d.%d %s, protseq %s, object %s\n",
75 entry->iface.SyntaxVersion.MajorVersion, entry->iface.SyntaxVersion.MinorVersion,
76 wine_dbgstr_guid(&entry->iface.SyntaxGUID),
77 entry->syntax.SyntaxVersion.MajorVersion, entry->syntax.SyntaxVersion.MinorVersion,
78 wine_dbgstr_guid(&entry->syntax.SyntaxGUID), protseq,
79 wine_dbgstr_guid(&entry->object));
80 return entry;
81 }
82 WINE_TRACE("not found\n");
83 return NULL;
84 }
85
86 void __RPC_USER ept_lookup_handle_t_rundown(ept_lookup_handle_t entry_handle)
87 {
88 WINE_FIXME("%p\n", entry_handle);
89 }
90
91 void __cdecl ept_insert(handle_t h,
92 unsigned32 num_ents,
93 ept_entry_t entries[],
94 boolean32 replace,
95 error_status_t *status)
96 {
97 unsigned32 i;
98 RPC_STATUS rpc_status;
99
100 WINE_TRACE("(%p, %u, %p, %u, %p)\n", h, num_ents, entries, replace, status);
101
102 *status = RPC_S_OK;
103
104 EnterCriticalSection(&csEpm);
105
106 for (i = 0; i < num_ents; i++)
107 {
108 struct registered_ept_entry *entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
109 if (!entry)
110 {
111 /* FIXME: cleanup code to delete added entries */
112 *status = EPT_S_CANT_PERFORM_OP;
113 break;
114 }
115 memcpy(entry->annotation, entries[i].annotation, sizeof(entries[i].annotation));
116 rpc_status = TowerExplode(entries[i].tower, &entry->iface, &entry->syntax,
117 &entry->protseq, &entry->endpoint,
118 &entry->address);
119 if (rpc_status != RPC_S_OK)
120 {
121 WINE_WARN("TowerExplode failed %u\n", rpc_status);
122 *status = rpc_status;
123 HeapFree(GetProcessHeap(), 0, entry);
124 break; /* FIXME: more cleanup? */
125 }
126
127 entry->object = entries[i].object;
128
129 if (replace)
130 {
131 /* FIXME: correct find algorithm */
132 struct registered_ept_entry *old_entry = find_ept_entry(&entry->iface, &entry->syntax, entry->protseq, entry->endpoint, entry->address, &entry->object);
133 if (old_entry) delete_registered_ept_entry(old_entry);
134 }
135 list_add_tail(&registered_ept_entry_list, &entry->entry);
136 }
137
138 LeaveCriticalSection(&csEpm);
139 }
140
141 void __cdecl ept_delete(handle_t h,
142 unsigned32 num_ents,
143 ept_entry_t entries[],
144 error_status_t *status)
145 {
146 unsigned32 i;
147 RPC_STATUS rpc_status;
148
149 *status = RPC_S_OK;
150
151 WINE_TRACE("(%p, %u, %p, %p)\n", h, num_ents, entries, status);
152
153 EnterCriticalSection(&csEpm);
154
155 for (i = 0; i < num_ents; i++)
156 {
157 struct registered_ept_entry *entry;
158 RPC_SYNTAX_IDENTIFIER iface, syntax;
159 char *protseq;
160 char *endpoint;
161 char *address;
162 rpc_status = TowerExplode(entries[i].tower, &iface, &syntax, &protseq,
163 &endpoint, &address);
164 if (rpc_status != RPC_S_OK)
165 break;
166 entry = find_ept_entry(&iface, &syntax, protseq, endpoint, address, &entries[i].object);
167
168 I_RpcFree(protseq);
169 I_RpcFree(endpoint);
170 I_RpcFree(address);
171
172 if (entry)
173 delete_registered_ept_entry(entry);
174 else
175 {
176 *status = EPT_S_NOT_REGISTERED;
177 break;
178 }
179 }
180
181 LeaveCriticalSection(&csEpm);
182 }
183
184 void __cdecl ept_lookup(handle_t h,
185 unsigned32 inquiry_type,
186 uuid_p_t object,
187 rpc_if_id_p_t interface_id,
188 unsigned32 vers_option,
189 ept_lookup_handle_t *entry_handle,
190 unsigned32 max_ents,
191 unsigned32 *num_ents,
192 ept_entry_t entries[],
193 error_status_t *status)
194 {
195 WINE_FIXME("(%p, %p, %p): stub\n", h, entry_handle, status);
196
197 *status = EPT_S_CANT_PERFORM_OP;
198 }
199
200 void __cdecl ept_map(handle_t h,
201 uuid_p_t object,
202 twr_p_t map_tower,
203 ept_lookup_handle_t *entry_handle,
204 unsigned32 max_towers,
205 unsigned32 *num_towers,
206 twr_p_t *towers,
207 error_status_t *status)
208 {
209 RPC_STATUS rpc_status;
210 RPC_SYNTAX_IDENTIFIER iface, syntax;
211 char *protseq;
212 struct registered_ept_entry *entry;
213
214 *status = RPC_S_OK;
215 *num_towers = 0;
216
217 WINE_TRACE("(%p, %p, %p, %p, %u, %p, %p, %p)\n", h, object, map_tower,
218 entry_handle, max_towers, num_towers, towers, status);
219
220 rpc_status = TowerExplode(map_tower, &iface, &syntax, &protseq,
221 NULL, NULL);
222 if (rpc_status != RPC_S_OK)
223 {
224 *status = rpc_status;
225 return;
226 }
227
228 EnterCriticalSection(&csEpm);
229
230 LIST_FOR_EACH_ENTRY(entry, &registered_ept_entry_list, struct registered_ept_entry, entry)
231 {
232 if (IsEqualGUID(&entry->iface.SyntaxGUID, &iface.SyntaxGUID) &&
233 (entry->iface.SyntaxVersion.MajorVersion == iface.SyntaxVersion.MajorVersion) &&
234 (entry->iface.SyntaxVersion.MinorVersion >= iface.SyntaxVersion.MinorVersion) &&
235 !memcmp(&entry->syntax, &syntax, sizeof(syntax)) &&
236 !strcmp(entry->protseq, protseq) &&
237 ((!object && IsEqualGUID(&entry->object, &nil_object)) || IsEqualGUID(object, &entry->object)))
238 {
239 if (*num_towers < max_towers)
240 {
241 rpc_status = TowerConstruct(&entry->iface, &entry->syntax,
242 entry->protseq, entry->endpoint,
243 entry->address,
244 &towers[*num_towers]);
245 if (rpc_status != RPC_S_OK)
246 {
247 *status = rpc_status;
248 break; /* FIXME: more cleanup? */
249 }
250 }
251 (*num_towers)++;
252 }
253 }
254
255 LeaveCriticalSection(&csEpm);
256
257 I_RpcFree(protseq);
258 }
259
260 void __cdecl ept_lookup_handle_free(handle_t h,
261 ept_lookup_handle_t *entry_handle,
262 error_status_t *status)
263 {
264 WINE_FIXME("(%p, %p, %p): stub\n", h, entry_handle, status);
265
266 *status = EPT_S_CANT_PERFORM_OP;
267 }
268
269 void __cdecl ept_inq_object(handle_t h,
270 GUID *ept_object,
271 error_status_t *status)
272 {
273 WINE_FIXME("(%p, %p, %p): stub\n", h, ept_object, status);
274
275 *status = EPT_S_CANT_PERFORM_OP;
276 }
277
278 void __cdecl ept_mgmt_delete(handle_t h,
279 boolean32 object_speced,
280 uuid_p_t object,
281 twr_p_t tower,
282 error_status_t *status)
283 {
284 WINE_FIXME("(%p, %d, %p, %p, %p): stub\n", h, object_speced, object, tower, status);
285
286 *status = EPT_S_CANT_PERFORM_OP;
287 }