2025-11-28 00:35:46 +09:00

266 lines
7.8 KiB
C

/**********************************************************************
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) Microsoft Corporation. All Rights Reserved.
Module Name:
InvitationHelpers.c
Abstract:
This C file includes sample code inviting people near me to an
application.
--********************************************************************/
#pragma warning(disable:4201) // nameless struct/union
#include "InvitationHelpers.h"
// Variable declarations
//
static HANDLE g_hInviteEvent = NULL;
static HANDLE g_hInviteWaitObject = NULL;
static HANDLE g_hInvite = NULL;
//-----------------------------------------------------------------------------
// Function: RefreshEndpointData
//
// Purpose: Refreshes the data associated with an endpoint
//
// Returns: HRESULT
//
HRESULT RefreshEndpointData(PCPEER_ENDPOINT pEndpoint)
{
HPEEREVENT hPeerEvent = NULL;
HRESULT hr = S_OK;
HANDLE hEvent = NULL;
PEER_COLLAB_EVENT_DATA *pEventData = NULL;
PEER_COLLAB_EVENT_REGISTRATION eventReg = {0};
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (hEvent == NULL)
{
return E_OUTOFMEMORY;
}
eventReg.eventType = PEER_EVENT_REQUEST_STATUS_CHANGED;
eventReg.pInstance = NULL;
// Register to be notified when the request finishes
hr = PeerCollabRegisterEvent(hEvent, 1, &eventReg, &hPeerEvent);
if (SUCCEEDED(hr))
{
hr = PeerCollabRefreshEndpointData(pEndpoint);
if (FAILED(hr))
{
PeerCollabUnregisterEvent(hPeerEvent);
CloseHandle(hEvent);
return hr;
}
// Block until an event is set indicating that endpoint data has
// successfully been refreshed
if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0)
{
// Find out if refresh request succeeded
hr = PeerCollabGetEventData(hPeerEvent, &pEventData);
if (SUCCEEDED(hr) &&
SUCCEEDED(pEventData->requestStatusChangedData.hrChange))
{
PeerFreeData(pEventData);
}
}
PeerCollabUnregisterEvent(hPeerEvent);
}
CloseHandle(hEvent);
return hr;
}
//-----------------------------------------------------------------------------
// Function: ProcessInviteResponse
//
// Purpose: Utility routine to check whether a contact/endpoint pair has
// the desired application
//
// Returns: DWORD
//
DWORD CALLBACK ProcessInviteResponse(LPVOID lpContext)
{
PPEER_INVITATION_RESPONSE pResponse = NULL;
HRESULT hr = S_OK;
ENDPOINT_INVITATION_CONTEXT * pInvitationContext = (ENDPOINT_INVITATION_CONTEXT *) lpContext;
// Get the invitation response
//
hr = PeerCollabInviteEndpoint(pInvitationContext->pEndpoint, pInvitationContext->pInvite, &pResponse);
if (SUCCEEDED(hr))
{
if (pResponse->action == PEER_INVITATION_RESPONSE_DECLINED)
{
MessageBox(NULL, L"Your invitation was declined.", L"Invitation Declined", MB_OK);
}
if (pResponse->action == PEER_INVITATION_RESPONSE_ERROR)
{
MessageBox(NULL, L"An error occured sending the invitation.", L"Invitation Error", MB_OK);
}
if (pResponse->action == PEER_INVITATION_RESPONSE_EXPIRED)
{
MessageBox(NULL, L"The invitation expired without being accepted.", L"Invitation Error", MB_OK);
}
}
// Free the used PEER resources
//
PeerFreeData(pResponse);
FreeInvitationContext(pInvitationContext);
return 0;
}
//-----------------------------------------------------------------------------
// Function: DuplicateInvitationContext
//
// Purpose: Utility routine to duplicate the invitation context
//
// Returns: HRESULT
//
HRESULT DuplicateInvitationContext(ENDPOINT_INVITATION_CONTEXT ** pDestination, ENDPOINT_INVITATION_CONTEXT * pSource)
{
HRESULT hr = S_OK;
ENDPOINT_INVITATION_CONTEXT * pTempDestination = NULL;
size_t cbMessage = 0;
cbMessage = (wcslen(pSource->pInvite->pwzMessage) * sizeof(WCHAR)) + sizeof(WCHAR);
// Copy the base structure
//
pTempDestination = malloc(sizeof(ENDPOINT_INVITATION_CONTEXT));
if (NULL == pTempDestination)
{
return E_OUTOFMEMORY;
}
ZeroMemory(pTempDestination, sizeof(ENDPOINT_INVITATION_CONTEXT));
// Copy the endpoint structure
//
pTempDestination->pEndpoint = malloc(sizeof(PEER_ENDPOINT));
if (NULL == pTempDestination->pEndpoint)
{
FreeInvitationContext(pTempDestination);
return E_OUTOFMEMORY;
}
ZeroMemory(pTempDestination->pEndpoint, sizeof(PEER_ENDPOINT));
memcpy(&pTempDestination->pEndpoint->address, &pSource->pEndpoint->address, sizeof(PEER_ADDRESS));
// Copy the PEER_INVITATION structure
//
pTempDestination->pInvite = malloc(sizeof(PEER_INVITATION));
if (NULL == pTempDestination->pInvite)
{
FreeInvitationContext(pTempDestination);
return E_OUTOFMEMORY;
}
ZeroMemory(pTempDestination->pInvite, sizeof(PEER_INVITATION));
// Copy the application data
//
pTempDestination->pInvite->applicationData.cbData = pSource->pInvite->applicationData.cbData;
pTempDestination->pInvite->applicationData.pbData = malloc(pSource->pInvite->applicationData.cbData);
if (NULL == pTempDestination->pInvite->applicationData.pbData)
{
FreeInvitationContext(pTempDestination);
return E_OUTOFMEMORY;
}
memcpy(pTempDestination->pInvite->applicationData.pbData, pSource->pInvite->applicationData.pbData, pSource->pInvite->applicationData.cbData);
// Copy the invitation message
//
pTempDestination->pInvite->pwzMessage = malloc(cbMessage);
if (NULL == pTempDestination->pInvite->pwzMessage)
{
FreeInvitationContext(pTempDestination);
return E_OUTOFMEMORY;
}
memcpy(pTempDestination->pInvite->pwzMessage, pSource->pInvite->pwzMessage, cbMessage);
// Copy the application ID
//
pTempDestination->pInvite->applicationId = pSource->pInvite->applicationId;
*pDestination = pTempDestination;
return hr;
}
//-----------------------------------------------------------------------------
// Function: Free Invitation Context
//
// Purpose: Frees an ENDPOINT_INVITATION_CONTEXT structure allocated by the model
//
// Returns: VOID
//
VOID FreeInvitationContext(ENDPOINT_INVITATION_CONTEXT * pInvitationContext)
{
if (NULL != pInvitationContext)
{
free(pInvitationContext->pEndpoint);
if (NULL != pInvitationContext->pInvite)
{
free(pInvitationContext->pInvite->applicationData.pbData);
free(pInvitationContext->pInvite->pwzMessage);
free(pInvitationContext->pInvite);
}
free(pInvitationContext);
}
}
//-----------------------------------------------------------------------------
// Function: SendInviteOnThread
//
// Purpose: Utility routine to send an invitation
//
// Returns: HRESULT
//
HRESULT SendInviteOnThread(ENDPOINT_INVITATION_CONTEXT * pIncomingInvitationContext)
{
HRESULT hr = S_OK;
ENDPOINT_INVITATION_CONTEXT * pInvitationContext = NULL;
hr = DuplicateInvitationContext(&pInvitationContext, pIncomingInvitationContext);
if (SUCCEEDED(hr))
{
if (!QueueUserWorkItem(ProcessInviteResponse, (PVOID) pInvitationContext, 0))
{
hr = HRESULT_FROM_WIN32(GetLastError());
MessageBox(NULL, L"Error", L"QueueUserWorkItem failed", 1);
}
}
return hr;
}