Peer Eventing and you
Now that we are successfully able to enumerate a static snapshot of people online at a particular time, It would be useful to register for when one of the people near you came or went. The Peer Collaboration stack allows you to do this with its eventing system. (this is the same eventing system as used in PeerGraph and PeerGroup)
The first thing you need to do is register for the event you are interested in, this is accomplished with this api:
HRESULT WINAPI PeerRegisterEvent(
HANDLE hEvent ,
DWORD cEventRegistration ,
PPEER_EVENT_REGISTRATION pEventRegistrations ,
HPEEREVENT* phPeerEvent
);
https://windowssdk.msdn.microsoft.com/library/en-us/P2PSDK/p2p/peerregisterevent.asp
Of interest, this api takes a NT event which to signal, an array of events that you may be interested in and returns a Peer Event Handle that is used to identify this registration.
HRESULT WINAPI PeerUnregisterEvent(
HPEEREVENT hPeerEvent
);
https://windowssdk.msdn.microsoft.com/library/en-us/P2PSDK/p2p/peerunregisterevent.asp
which tells the system you are no longer interested in being signaled when this event happens.
When the event that you passed in to PeerRegisterEvent is signaled informing you that there is data, you call
HRESULT WINAPI PeerGetEventData(
HPEEREVENT hPeerEvent ,
PPEER_EVENT_DATA* ppEventData
);
https://windowssdk.msdn.microsoft.com/library/en-us/P2PSDK/p2p/peergeteventdata.asp
Which returns the data associated with the event.
In practice the code looks like this:
typedef struct thread_data_tag
{
HANDLE hEvent;
HANDLE hPeerEvent;
HANDLE hShutdown;
} THREAD_DATA, *PTHREAD_DATA;
HRESULT RegisterForEvents(
HANDLE hShutdown,
PHANDLE phWaitEvent
)
{
HRESULT hr=S_OK;
PTHREAD_DATA pThreadData;
PEER_EVENT_REGISTRATION eventReg;
eventReg.eventType = PEER_EVENT_ENDPOINT_NEAR_ME_CHANGED;
eventReg.pInstance = NULL;
pThreadData =(PTHREAD_DATA)HeapAlloc(GetProcessHeap(), 0, sizeof(THREAD_DATA));
if ( pThreadData == NULL )
{
return E_OUTOFMEMORY;
}
pThreadData->hShutdown = hShutdown;
pThreadData->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);;
if ( pThreadData->hEvent == NULL )
{
HeapFree(GetProcessHeap(),0,pThreadData);
return HRESULT_FROM_WIN32(GetLastError());
}
hr = PeerRegisterEvent(pThreadData->hEvent, 1, &eventReg, &pThreadData->hPeerEvent );
if ( SUCCEEDED(hr) )
{
*phWaitEvent = CreateThread(NULL,0,EventThread,(LPVOID)pThreadData,0,NULL);
if ( phWaitEvent == NULL )
{
hr=HRESULT_FROM_WIN32(GetLastError());
}
}
if ( FAILED(hr) )
{
HeapFree(GetProcessHeap(),0,pThreadData);
CloseHandle(pThreadData->hEvent);
}
return hr;
}
DWORD WINAPI EventThread(LPVOID lpWaitHandles)
{
PTHREAD_DATA pThreadData = (PTHREAD_DATA)lpWaitHandles;
PHANDLE phWaitHandles;
BOOL bShutdown = FALSE;
phWaitHandles = (PHANDLE)HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLE) * 2);
if ( phWaitHandles != NULL )
{
phWaitHandles[0] = pThreadData->hShutdown;
phWaitHandles[1] = pThreadData->hEvent;
while ( !bShutdown )
{
switch ( WaitForMultipleObjects(2,phWaitHandles,FALSE,INFINITE) )
{
case WAIT_OBJECT_0:
{
printf("Shutdown\n");
bShutdown=TRUE;
break;
}
break;
case WAIT_OBJECT_0 + 1:
{
ProcessEvent(pThreadData->hPeerEvent);
}
break;
}
}
}
CloseHandle(pThreadData->hEvent);
PeerUnregisterEvent(pThreadData->hPeerEvent);
HeapFree(GetProcessHeap(),0,lpWaitHandles);
return 0;
}
VOID ProcessEvent(HPEEREVENT hPeerEvent )
{
PEER_EVENT_DATA *pEventData = NULL;
HRESULT hr=S_OK;
while ( TRUE )
{
hr = PeerGetEventData(hPeerEvent, &pEventData);
if ( FAILED(hr) || hr == PEER_S_NO_EVENT_DATA )
{
return;
}
switch ( pEventData->eventType )
{
case PEER_EVENT_ENDPOINT_NEAR_ME_CHANGED:
{
printf("%S",
pEventData->endpointNearMeChangedData.pEndpointNearMe->pwzFriendlyName,
);
}
break;
default:
{
printf("Event not Implemented");
}
break;
}
PeerFreeData(pEventData);
}
}
int __cdecl main(int argc, __in_ecount(argc) char *argv[])
{
HANDLE hThread;
HANDLE hShutdown;
HRESULT hr=S_OK;
char buff[512];
hr = PeerCollabStartup(PEER_COLLAB_VERSION);
if (SUCCEEDED(hr))
{
hr = PeerCollabSignin(PEER_PRESENCE_NEAR_ME);
if (SUCCEEDED(hr))
{
hr=EnumeratePeopleNearMe();
}
hShutdown =CreateEvent(NULL, FALSE, FALSE, NULL);
if ( hShutdown != NULL )
{
if ( SUCCEEDED(RegisterForEvents(hShutdown,&hThread)) )
{
while ( TRUE )
{
Sleep(0);
hr = StringCchGetsA(buff, 512);
if ( FAILED(hr) )
{
printf("StringCchGets failure.\n");
continue;
}
if ( strncmp(buff + 1, "quit", strlen("quit")) == 0 )
{
break;
}
}
SetEvent(hShutdown);
WaitForSingleObject(hThread,INFINITE);
}
CloseHandle(hShutdown);
CloseHandle(hThread);
}
(void)PeerCollabShutdown();
}
return 0;
}
Sorry for the repost, I didnt publish this correctly