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

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

Added ID tags

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