KDE 1.x has problems with using XShapeCombineMask when there was no
[wine/hacks.git] / dlls / dplayx / name_server.c
blobacae34d5adbfba27d19db948744570555c158838
1 /* DPLAYX.DLL name server implementation
3 * Copyright 2000 - Peter Hunnisett
5 * <presently under construction - contact hunnise@nortelnetworks.com>
7 */
9 /* NOTE: Methods with the NS_ prefix are name server methods */
11 #include "winbase.h"
12 #include "debugtools.h"
13 #include "heap.h"
15 #include "dplayx_global.h"
16 #include "name_server.h"
17 #include "dplaysp.h"
18 #include "dplayx_messages.h"
19 #include "dplayx_queue.h"
21 /* FIXME: Need to create a crit section, store and use it */
23 DEFAULT_DEBUG_CHANNEL(dplay);
25 /* NS specific structures */
26 struct NSCacheData
28 DPQ_ENTRY(NSCacheData) next;
30 DWORD dwTime; /* Time at which data was last known valid */
31 LPDPSESSIONDESC2 data;
33 LPVOID lpNSAddrHdr;
36 typedef struct NSCacheData NSCacheData, *lpNSCacheData;
38 struct NSCache
40 lpNSCacheData present; /* keep track of what is to be looked at when walking */
42 DPQ_HEAD(NSCacheData) first;
43 };
44 typedef struct NSCache NSCache, *lpNSCache;
46 /* Name Server functions
47 * ---------------------
49 void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd )
51 #if 0
52 DPLAYX_SetLocalSession( lpsd );
53 #endif
56 /* Store the given NS remote address for future reference */
57 void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
58 DWORD dwHdrSize,
59 LPDPMSG_ENUMSESSIONSREPLY lpMsg,
60 LPVOID lpNSInfo )
62 lpNSCache lpCache = (lpNSCache)lpNSInfo;
63 lpNSCacheData lpCacheNode;
65 TRACE( "%p, %p, %p\n", lpNSAddrHdr, lpMsg, lpNSInfo );
67 /* FIXME: Should check to see if the reply is for an existing session. If
68 * so we just update the contents and update the timestamp.
70 lpCacheNode = (lpNSCacheData)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
71 sizeof( *lpCacheNode ) );
73 if( lpCacheNode == NULL )
75 ERR( "no memory for NS node\n" );
76 return;
79 lpCacheNode->lpNSAddrHdr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
80 dwHdrSize );
81 CopyMemory( lpCacheNode->lpNSAddrHdr, lpNSAddrHdr, dwHdrSize );
84 lpCacheNode->data = (LPDPSESSIONDESC2)HeapAlloc( GetProcessHeap(),
85 HEAP_ZERO_MEMORY,
86 sizeof( *lpCacheNode->data ) );
88 if( lpCacheNode->data == NULL )
90 ERR( "no memory for SESSIONDESC2\n" );
91 return;
94 CopyMemory( lpCacheNode->data, &lpMsg->sd, sizeof( *lpCacheNode->data ) );
95 lpCacheNode->data->sess.lpszSessionNameA = HEAP_strdupWtoA( GetProcessHeap(),
96 HEAP_ZERO_MEMORY,
97 (LPWSTR)(lpMsg+1) );
99 lpCacheNode->dwTime = GetTickCount();
101 DPQ_INSERT(lpCache->first, lpCacheNode, next );
103 lpCache->present = lpCacheNode;
105 /* Use this message as an oportunity to weed out any old sessions so
106 * that we don't enum them again
108 NS_PruneSessionCache( lpNSInfo );
111 LPVOID NS_GetNSAddr( LPVOID lpNSInfo )
113 lpNSCache lpCache = (lpNSCache)lpNSInfo;
115 FIXME( ":quick stub\n" );
117 /* Ok. Cheat and don't search for the correct stuff just take the first.
118 * FIXME: In the future how are we to know what is _THE_ enum we used?
121 return lpCache->first.lpQHFirst->lpNSAddrHdr;
124 /* This function is responsible for sending a request for all other known
125 nameservers to send us what sessions they have registered locally
127 HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid,
128 DWORD dwFlags,
129 LPSPINITDATA lpSpData )
132 DPSP_ENUMSESSIONSDATA data;
133 LPDPMSG_ENUMSESSIONSREQUEST lpMsg;
135 TRACE( "enumerating for guid %s\n", debugstr_guid( lpcGuid ) );
137 /* Get the SP to deal with sending the EnumSessions request */
138 FIXME( ": not all data fields are correct\n" );
140 data.dwMessageSize = lpSpData->dwSPHeaderSize + sizeof( *lpMsg ); /*FIXME!*/
141 data.lpMessage = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
142 data.dwMessageSize );
143 data.lpISP = lpSpData->lpISP;
144 data.bReturnStatus = (dwFlags & DPENUMSESSIONS_RETURNSTATUS) ? TRUE : FALSE;
147 lpMsg = (LPDPMSG_ENUMSESSIONSREQUEST)(((BYTE*)data.lpMessage)+lpSpData->dwSPHeaderSize);
149 /* Setup EnumSession reqest message */
150 lpMsg->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
151 lpMsg->envelope.wCommandId = DPMSGCMD_ENUMSESSIONSREQUEST;
152 lpMsg->envelope.wVersion = DPMSGVER_DP6;
154 lpMsg->dwPasswordSize = 0; /* FIXME: If enumerating passwords..? */
155 lpMsg->dwFlags = dwFlags;
157 CopyMemory( &lpMsg->guidApplication, lpcGuid, sizeof( *lpcGuid ) );
159 return (lpSpData->lpCB->EnumSessions)( &data );
162 DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData );
163 DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData )
165 /* FIXME: Memory leak on data (contained ptrs) */
166 HeapFree( GetProcessHeap(), 0, elem->data );
167 HeapFree( GetProcessHeap(), 0, elem->lpNSAddrHdr );
168 HeapFree( GetProcessHeap(), 0, elem );
173 /* Render all data in a session cache invalid */
174 void NS_InvalidateSessionCache( LPVOID lpNSInfo )
176 lpNSCache lpCache = (lpNSCache)lpNSInfo;
178 if( lpCache == NULL )
180 ERR( ": invalidate non existant cache\n" );
181 return;
184 DPQ_DELETEQ( lpCache->first, next, lpNSCacheData, cbDeleteNSNodeFromHeap );
186 /* NULL out the walking pointer */
187 lpCache->present = NULL;
190 /* Create and initialize a session cache */
191 BOOL NS_InitializeSessionCache( LPVOID* lplpNSInfo )
193 lpNSCache lpCache = (lpNSCache)HeapAlloc( GetProcessHeap(),
194 HEAP_ZERO_MEMORY,
195 sizeof( *lpCache ) );
197 *lplpNSInfo = lpCache;
199 if( lpCache == NULL )
201 return FALSE;
204 DPQ_INIT(lpCache->first);
205 lpCache->present = NULL;
207 return TRUE;
210 /* Delete a session cache */
211 void NS_DeleteSessionCache( LPVOID lpNSInfo )
213 NS_InvalidateSessionCache( (lpNSCache)lpNSInfo );
216 /* Reinitialize the present pointer for this cache */
217 void NS_ResetSessionEnumeration( LPVOID lpNSInfo )
220 ((lpNSCache)lpNSInfo)->present = ((lpNSCache)lpNSInfo)->first.lpQHFirst;
223 LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo )
225 LPDPSESSIONDESC2 lpSessionDesc;
226 lpNSCache lpCache = (lpNSCache)lpNSInfo;
228 /* FIXME: The pointers could disappear when walking if a prune happens */
230 /* Test for end of the list */
231 if( lpCache->present == NULL )
233 return NULL;
236 lpSessionDesc = lpCache->present->data;
238 /* Advance tracking pointer */
239 lpCache->present = lpCache->present->next.lpQNext;
241 return lpSessionDesc;
244 /* This method should check to see if there are any sessions which are
245 * older than the criteria. If so, just delete that information.
247 void NS_PruneSessionCache( LPVOID lpNSInfo )
249 lpNSCache lpCache = lpNSInfo;
250 lpNSCacheData lpCacheEntry;
252 DWORD dwPresentTime = GetTickCount();
253 #if defined( HACK_TIMEGETTIME )
254 DWORD dwPruneTime = dwPresentTime - 2; /* One iteration with safety */
255 #else
256 DWORD dwPruneTime = dwPresentTime - 10000 /* 10 secs? */;
257 #endif
259 FIXME( ": semi stub\n" );
261 /* FIXME: This doesn't handle time roll over correctly */
262 /* FIXME: Session memory leak on delete */
265 DPQ_FIND_ENTRY( lpCache->first, next, dwTime, <=, dwPruneTime, lpCacheEntry );
267 while( lpCacheEntry != NULL );
273 /* Message stuff */
274 void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
275 LPDPSP_REPLYDATA lpReplyData,
276 IDirectPlay2Impl* lpDP )
278 LPDPMSG_ENUMSESSIONSREPLY rmsg;
279 DWORD dwVariableSize;
280 DWORD dwVariableLen;
281 LPWSTR string;
282 /* LPDPMSG_ENUMSESSIONSREQUEST msg = (LPDPMSG_ENUMSESSIONSREQUEST)lpMsg; */
283 BOOL bAnsi = TRUE; /* FIXME: This needs to be in the DPLAY interface */
285 FIXME( ": few fixed + need to check request for response\n" );
287 dwVariableLen = bAnsi ? lstrlenA( lpDP->dp2->lpSessionDesc->sess.lpszSessionNameA ) + 1
288 : lstrlenW( lpDP->dp2->lpSessionDesc->sess.lpszSessionName ) + 1;
290 dwVariableSize = dwVariableLen * sizeof( WCHAR );
292 lpReplyData->dwMessageSize = lpDP->dp2->spData.dwSPHeaderSize +
293 sizeof( *rmsg ) + dwVariableSize;
294 lpReplyData->lpMessage = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
295 lpReplyData->dwMessageSize );
297 rmsg = (LPDPMSG_ENUMSESSIONSREPLY)( (BYTE*)lpReplyData->lpMessage +
298 lpDP->dp2->spData.dwSPHeaderSize);
300 rmsg->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
301 rmsg->envelope.wCommandId = DPMSGCMD_ENUMSESSIONSREPLY;
302 rmsg->envelope.wVersion = DPMSGVER_DP6;
304 CopyMemory( &rmsg->sd, lpDP->dp2->lpSessionDesc,
305 sizeof( lpDP->dp2->lpSessionDesc->dwSize ) );
306 rmsg->dwUnknown = 0x0000005c;
307 if( bAnsi )
309 string = HEAP_strdupAtoW( GetProcessHeap(), 0,
310 lpDP->dp2->lpSessionDesc->sess.lpszSessionNameA );
311 /* FIXME: Memory leak */
313 else
315 string = lpDP->dp2->lpSessionDesc->sess.lpszSessionName;
318 lstrcpyW( (LPWSTR)(rmsg+1), string );