source: trunk/src/DPlayX/name_server.cpp@ 4314

Last change on this file since 4314 was 4314, checked in by hugh, 25 years ago

Updated to latest wine version

File size: 9.2 KB
Line 
1/* DPLAYX.DLL name server implementation
2 *
3 * Copyright 2000 - Peter Hunnisett
4 *
5 * <presently under construction - contact hunnise@nortelnetworks.com>
6 *
7 */
8
9/* NOTE: Methods with the NS_ prefix are name server methods */
10
11#include <string.h>
12
13#include <odin.h>
14#define ICOM_CINTERFACE 1
15#define CINTERFACE
16
17#include "winbase.h"
18#include "winuser.h"
19#include "debugtools.h"
20#include "heap.h"
21#include "heapstring.h"
22
23#include "dplayx_global.h"
24#include "name_server.h"
25#include "dplaysp.h"
26#include "dplayx_messages.h"
27#include "dplayx_queue.h"
28
29/* FIXME: Need to create a crit section, store and use it */
30
31DEFAULT_DEBUG_CHANNEL(dplay);
32
33#define debugstr_guid(a) a
34
35/* NS specific structures */
36struct NSCacheData
37{
38 DPQ_ENTRY(NSCacheData) next;
39
40 DWORD dwTime; /* Time at which data was last known valid */
41 LPDPSESSIONDESC2 data;
42
43 LPVOID lpNSAddrHdr;
44
45};
46typedef struct NSCacheData NSCacheData, *lpNSCacheData;
47
48struct NSCache
49{
50 lpNSCacheData present; /* keep track of what is to be looked at when walking */
51
52 DPQ_HEAD(NSCacheData) first;
53};
54typedef struct NSCache NSCache, *lpNSCache;
55
56/* Name Server functions
57 * ---------------------
58 */
59void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd )
60{
61#if 0
62 DPLAYX_SetLocalSession( lpsd );
63#endif
64}
65
66/* Store the given NS remote address for future reference */
67void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
68 DWORD dwHdrSize,
69 LPDPMSG_ENUMSESSIONSREPLY lpMsg,
70 LPVOID lpNSInfo )
71{
72 lpNSCache lpCache = (lpNSCache)lpNSInfo;
73 lpNSCacheData lpCacheNode;
74
75 TRACE( "%p, %p, %p\n", lpNSAddrHdr, lpMsg, lpNSInfo );
76
77 /* FIXME: Should check to see if the reply is for an existing session. If
78 * so we just update the contents and update the timestamp.
79 */
80 lpCacheNode = (lpNSCacheData)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
81 sizeof( *lpCacheNode ) );
82
83 if( lpCacheNode == NULL )
84 {
85 ERR( "no memory for NS node\n" );
86 return;
87 }
88
89 lpCacheNode->lpNSAddrHdr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
90 dwHdrSize );
91 CopyMemory( lpCacheNode->lpNSAddrHdr, lpNSAddrHdr, dwHdrSize );
92
93
94 lpCacheNode->data = (LPDPSESSIONDESC2)HeapAlloc( GetProcessHeap(),
95 HEAP_ZERO_MEMORY,
96 sizeof( *lpCacheNode->data ) );
97
98 if( lpCacheNode->data == NULL )
99 {
100 ERR( "no memory for SESSIONDESC2\n" );
101 return;
102 }
103
104 CopyMemory( lpCacheNode->data, &lpMsg->sd, sizeof( *lpCacheNode->data ) );
105 lpCacheNode->data->sess.lpszSessionNameA = HEAP_strdupWtoA( GetProcessHeap(),
106 HEAP_ZERO_MEMORY,
107 (LPWSTR)(lpMsg+1) );
108
109 lpCacheNode->dwTime = GetTickCount();
110
111 DPQ_INSERT(lpCache->first, lpCacheNode, next );
112
113 lpCache->present = lpCacheNode;
114
115 /* Use this message as an oportunity to weed out any old sessions so
116 * that we don't enum them again
117 */
118 NS_PruneSessionCache( lpNSInfo );
119}
120
121LPVOID NS_GetNSAddr( LPVOID lpNSInfo )
122{
123 lpNSCache lpCache = (lpNSCache)lpNSInfo;
124
125 FIXME( ":quick stub\n" );
126
127 /* Ok. Cheat and don't search for the correct stuff just take the first.
128 * FIXME: In the future how are we to know what is _THE_ enum we used?
129 */
130
131 return lpCache->first.lpQHFirst->lpNSAddrHdr;
132}
133
134/* This function is responsible for sending a request for all other known
135 nameservers to send us what sessions they have registered locally
136 */
137HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid,
138 DWORD dwFlags,
139 LPSPINITDATA lpSpData )
140
141{
142 DPSP_ENUMSESSIONSDATA data;
143 LPDPMSG_ENUMSESSIONSREQUEST lpMsg;
144
145 TRACE( "enumerating for guid %s\n", debugstr_guid( lpcGuid ) );
146
147 /* Get the SP to deal with sending the EnumSessions request */
148 FIXME( ": not all data fields are correct\n" );
149
150 data.dwMessageSize = lpSpData->dwSPHeaderSize + sizeof( *lpMsg ); /*FIXME!*/
151 data.lpMessage = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
152 data.dwMessageSize );
153 data.lpISP = lpSpData->lpISP;
154 data.bReturnStatus = (dwFlags & DPENUMSESSIONS_RETURNSTATUS) ? TRUE : FALSE;
155
156
157 lpMsg = (LPDPMSG_ENUMSESSIONSREQUEST)(((BYTE*)data.lpMessage)+lpSpData->dwSPHeaderSize);
158
159 /* Setup EnumSession reqest message */
160 lpMsg->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
161 lpMsg->envelope.wCommandId = DPMSGCMD_ENUMSESSIONSREQUEST;
162 lpMsg->envelope.wVersion = DPMSGVER_DP6;
163
164 lpMsg->dwPasswordSize = 0; /* FIXME: If enumerating passwords..? */
165 lpMsg->dwFlags = dwFlags;
166
167 CopyMemory( &lpMsg->guidApplication, lpcGuid, sizeof( *lpcGuid ) );
168
169 return (lpSpData->lpCB->EnumSessions)( &data );
170}
171
172DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData );
173DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData )
174{
175 /* FIXME: Memory leak on data (contained ptrs) */
176 HeapFree( GetProcessHeap(), 0, elem->data );
177 HeapFree( GetProcessHeap(), 0, elem->lpNSAddrHdr );
178 HeapFree( GetProcessHeap(), 0, elem );
179}
180
181
182
183/* Render all data in a session cache invalid */
184void NS_InvalidateSessionCache( LPVOID lpNSInfo )
185{
186 lpNSCache lpCache = (lpNSCache)lpNSInfo;
187
188 if( lpCache == NULL )
189 {
190 ERR( ": invalidate non existant cache\n" );
191 return;
192 }
193
194 DPQ_DELETEQ( lpCache->first, next, lpNSCacheData, cbDeleteNSNodeFromHeap );
195
196 /* NULL out the walking pointer */
197 lpCache->present = NULL;
198}
199
200/* Create and initialize a session cache */
201BOOL NS_InitializeSessionCache( LPVOID* lplpNSInfo )
202{
203 lpNSCache lpCache = (lpNSCache)HeapAlloc( GetProcessHeap(),
204 HEAP_ZERO_MEMORY,
205 sizeof( *lpCache ) );
206
207 *lplpNSInfo = lpCache;
208
209 if( lpCache == NULL )
210 {
211 return FALSE;
212 }
213
214 DPQ_INIT(lpCache->first);
215 lpCache->present = NULL;
216
217 return TRUE;
218}
219
220/* Delete a session cache */
221void NS_DeleteSessionCache( LPVOID lpNSInfo )
222{
223 NS_InvalidateSessionCache( (lpNSCache)lpNSInfo );
224}
225
226/* Reinitialize the present pointer for this cache */
227void NS_ResetSessionEnumeration( LPVOID lpNSInfo )
228{
229
230 ((lpNSCache)lpNSInfo)->present = ((lpNSCache)lpNSInfo)->first.lpQHFirst;
231}
232
233LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo )
234{
235 LPDPSESSIONDESC2 lpSessionDesc;
236 lpNSCache lpCache = (lpNSCache)lpNSInfo;
237
238 /* FIXME: The pointers could disappear when walking if a prune happens */
239
240 /* Test for end of the list */
241 if( lpCache->present == NULL )
242 {
243 return NULL;
244 }
245
246 lpSessionDesc = lpCache->present->data;
247
248 /* Advance tracking pointer */
249 lpCache->present = lpCache->present->next.lpQNext;
250
251 return lpSessionDesc;
252}
253
254/* This method should check to see if there are any sessions which are
255 * older than the criteria. If so, just delete that information.
256 */
257void NS_PruneSessionCache( LPVOID lpNSInfo )
258{
259 lpNSCache lpCache = (lpNSCache)lpNSInfo;
260 lpNSCacheData lpCacheEntry;
261
262 DWORD dwPresentTime = GetTickCount();
263#if defined( HACK_TIMEGETTIME )
264 DWORD dwPruneTime = dwPresentTime - 2; /* One iteration with safety */
265#else
266 DWORD dwPruneTime = dwPresentTime - 10000 /* 10 secs? */;
267#endif
268
269 FIXME( ": semi stub\n" );
270
271 /* FIXME: This doesn't handle time roll over correctly */
272 /* FIXME: Session memory leak on delete */
273 do
274 {
275 DPQ_FIND_ENTRY( lpCache->first, next, dwTime, <=, dwPruneTime, lpCacheEntry );
276 }
277 while( lpCacheEntry != NULL );
278
279}
280
281
282
283/* Message stuff */
284void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
285 LPDPSP_REPLYDATA lpReplyData,
286 IDirectPlay2Impl* lpDP )
287{
288 LPDPMSG_ENUMSESSIONSREPLY rmsg;
289 DWORD dwVariableSize;
290 DWORD dwVariableLen;
291 LPWSTR string;
292 /* LPDPMSG_ENUMSESSIONSREQUEST msg = (LPDPMSG_ENUMSESSIONSREQUEST)lpMsg; */
293 BOOL bAnsi = TRUE; /* FIXME: This needs to be in the DPLAY interface */
294
295 FIXME( ": few fixed + need to check request for response\n" );
296
297 dwVariableLen = bAnsi ? lstrlenA( lpDP->dp2->lpSessionDesc->sess.lpszSessionNameA ) + 1
298 : lstrlenW( lpDP->dp2->lpSessionDesc->sess.lpszSessionName ) + 1;
299
300 dwVariableSize = dwVariableLen * sizeof( WCHAR );
301
302 lpReplyData->dwMessageSize = lpDP->dp2->spData.dwSPHeaderSize +
303 sizeof( *rmsg ) + dwVariableSize;
304 lpReplyData->lpMessage = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
305 lpReplyData->dwMessageSize );
306
307 rmsg = (LPDPMSG_ENUMSESSIONSREPLY)( (BYTE*)lpReplyData->lpMessage +
308 lpDP->dp2->spData.dwSPHeaderSize);
309
310 rmsg->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
311 rmsg->envelope.wCommandId = DPMSGCMD_ENUMSESSIONSREPLY;
312 rmsg->envelope.wVersion = DPMSGVER_DP6;
313
314 CopyMemory( &rmsg->sd, lpDP->dp2->lpSessionDesc,
315 sizeof( lpDP->dp2->lpSessionDesc->dwSize ) );
316 rmsg->dwUnknown = 0x0000005c;
317 if( bAnsi )
318 {
319 string = HEAP_strdupAtoW( GetProcessHeap(), 0,
320 lpDP->dp2->lpSessionDesc->sess.lpszSessionNameA );
321 /* FIXME: Memory leak */
322 }
323 else
324 {
325 string = lpDP->dp2->lpSessionDesc->sess.lpszSessionName;
326 }
327
328 lstrcpyW( (LPWSTR)(rmsg+1), string );
329
330}
331
Note: See TracBrowser for help on using the repository browser.