292 lines
7.6 KiB
C
292 lines
7.6 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:
|
|
|
|
Reg.c
|
|
|
|
Abstract:
|
|
|
|
This C file includes sample code for registration portion of
|
|
an nspv2 naming provider
|
|
|
|
--********************************************************************/
|
|
#include "Reg.h"
|
|
|
|
CRITICAL_SECTION g_cs;
|
|
RegInfo g_Registrations[MAX_REGISTRATIONS];
|
|
ULONG g_cRegistrations = 0;
|
|
|
|
// Utility routine to get the number of bytes in a string
|
|
//
|
|
ULONG StringSize(PCWSTR wz)
|
|
{
|
|
if (wz == NULL)
|
|
return 0;
|
|
else
|
|
return (ULONG) ((wcslen(wz) + 1) * sizeof(WCHAR));
|
|
}
|
|
|
|
|
|
// Utility routine which allocates memory and copies a string
|
|
//
|
|
INT CopyString(PCWSTR wzSrc, __deref_out PWSTR *pwzDest)
|
|
{
|
|
INT err = NO_ERROR;
|
|
ULONG cb = StringSize(wzSrc);
|
|
|
|
*pwzDest = malloc(cb);
|
|
if (*pwzDest == NULL)
|
|
{
|
|
err = WSA_NOT_ENOUGH_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
memcpy(*pwzDest, wzSrc, cb);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
// Utility routine to allocate memory and copy an array of CSADDR_INFO
|
|
//
|
|
INT CopyAddrs(__in_ecount(cAddrs) CSADDR_INFO *rgAddrsSrc,
|
|
DWORD cAddrs,
|
|
__deref_out CSADDR_INFO **prgAddrsDest)
|
|
{
|
|
INT err = NO_ERROR;
|
|
ULONG i = 0;
|
|
|
|
CSADDR_INFO *rgAddrsDest = (CSADDR_INFO *)malloc(cAddrs * sizeof(CSADDR_INFO));
|
|
|
|
if (rgAddrsDest == NULL)
|
|
{
|
|
return WSA_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
ZeroMemory(rgAddrsDest, cAddrs * sizeof(CSADDR_INFO));
|
|
|
|
for (i = 0; i < cAddrs; i++)
|
|
{
|
|
// copy static members
|
|
rgAddrsDest[i] = rgAddrsSrc[i];
|
|
|
|
// copy embedded memory
|
|
if (rgAddrsSrc[i].LocalAddr.lpSockaddr != NULL)
|
|
{
|
|
rgAddrsDest[i].LocalAddr.lpSockaddr =
|
|
(LPSOCKADDR) malloc(rgAddrsDest[i].LocalAddr.iSockaddrLength);
|
|
|
|
if (rgAddrsDest[i].LocalAddr.lpSockaddr == NULL)
|
|
{
|
|
err = WSA_NOT_ENOUGH_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
// copy address byte-for-byte
|
|
memcpy(rgAddrsDest[i].LocalAddr.lpSockaddr,
|
|
rgAddrsSrc[i].LocalAddr.lpSockaddr,
|
|
rgAddrsDest[i].LocalAddr.iSockaddrLength);
|
|
}
|
|
|
|
// copy embedded memory
|
|
if (rgAddrsSrc[i].RemoteAddr.lpSockaddr != NULL)
|
|
{
|
|
rgAddrsDest[i].RemoteAddr.lpSockaddr =
|
|
(LPSOCKADDR)malloc(rgAddrsDest[i].RemoteAddr.iSockaddrLength);
|
|
|
|
if (rgAddrsDest[i].RemoteAddr.lpSockaddr == NULL)
|
|
{
|
|
err = WSA_NOT_ENOUGH_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
// copy address byte-for-byte
|
|
memcpy(rgAddrsDest[i].RemoteAddr.lpSockaddr,
|
|
rgAddrsSrc[i].RemoteAddr.lpSockaddr,
|
|
rgAddrsDest[i].RemoteAddr.iSockaddrLength);
|
|
|
|
}
|
|
}
|
|
|
|
// success
|
|
*prgAddrsDest = rgAddrsDest;
|
|
return NO_ERROR;
|
|
|
|
// failure
|
|
cleanup:
|
|
for (i = 0; i < cAddrs; i++)
|
|
{
|
|
if (rgAddrsDest[i].LocalAddr.lpSockaddr != NULL)
|
|
free(rgAddrsDest[i].LocalAddr.lpSockaddr);
|
|
if (rgAddrsDest[i].RemoteAddr.lpSockaddr != NULL)
|
|
free(rgAddrsDest[i].RemoteAddr.lpSockaddr);
|
|
}
|
|
|
|
free(rgAddrsDest);
|
|
return err;
|
|
}
|
|
|
|
// Note: Caller must take g_cs lock in order to call this safely
|
|
//
|
|
BOOL FindRegistration(PCWSTR pcwzEmailAddress, PCWSTR pcwzServiceName, __out RegInfo **ppRegInfo)
|
|
{
|
|
ULONG i = 0;
|
|
|
|
for (i = 0; i < g_cRegistrations; i++)
|
|
{
|
|
if ( (_wcsicmp(pcwzEmailAddress, g_Registrations[i].pwzEmailAddress) == 0) &&
|
|
(_wcsicmp(pcwzServiceName, g_Registrations[i].pwzServiceName) == 0)
|
|
)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == g_cRegistrations)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
*ppRegInfo = &g_Registrations[i];
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
// Add a registration to the cache
|
|
//
|
|
INT AddRegistration(__in LPWSAQUERYSET2 pQuerySet)
|
|
{
|
|
INT err = NO_ERROR;
|
|
|
|
EnterCriticalSection(&g_cs);
|
|
|
|
// If it already exists, we remove it
|
|
RemoveRegistration(pQuerySet);
|
|
|
|
if (g_cRegistrations == MAX_REGISTRATIONS)
|
|
{
|
|
err = WSA_NOT_ENOUGH_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
err = CopyString(pQuerySet->lpszServiceInstanceName,
|
|
&g_Registrations[g_cRegistrations].pwzEmailAddress);
|
|
|
|
if (err != NO_ERROR)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
err = CopyString(pQuerySet->lpszContext,
|
|
&g_Registrations[g_cRegistrations].pwzServiceName);
|
|
if (err != NO_ERROR)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
err = CopyAddrs(pQuerySet->lpcsaBuffer,
|
|
pQuerySet->dwNumberOfCsAddrs,
|
|
&g_Registrations[g_cRegistrations].prgAddresses);
|
|
|
|
if (err != NO_ERROR)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
printf("Registration for %S (service = %S) added.\n",
|
|
pQuerySet->lpszServiceInstanceName,
|
|
pQuerySet->lpszContext);
|
|
g_Registrations[g_cRegistrations].cAddresses = pQuerySet->dwNumberOfCsAddrs;
|
|
g_cRegistrations++;
|
|
|
|
LeaveCriticalSection(&g_cs);
|
|
|
|
return err;
|
|
|
|
cleanup:
|
|
|
|
free(g_Registrations[g_cRegistrations].pwzEmailAddress);
|
|
free(g_Registrations[g_cRegistrations].pwzServiceName);
|
|
|
|
LeaveCriticalSection(&g_cs);
|
|
|
|
return err;
|
|
}
|
|
|
|
void RemoveAllRegistrations()
|
|
{
|
|
ULONG i;
|
|
|
|
EnterCriticalSection(&g_cs);
|
|
|
|
while (g_cRegistrations > 0)
|
|
{
|
|
free(g_Registrations[g_cRegistrations-1].pwzEmailAddress);
|
|
|
|
for (i = 0; i < g_Registrations[g_cRegistrations-1].cAddresses; i++)
|
|
{
|
|
if (g_Registrations[g_cRegistrations-1].prgAddresses[i].LocalAddr.lpSockaddr != NULL)
|
|
free(g_Registrations[g_cRegistrations-1].prgAddresses[i].LocalAddr.lpSockaddr);
|
|
if (g_Registrations[g_cRegistrations-1].prgAddresses[i].RemoteAddr.lpSockaddr != NULL)
|
|
free(g_Registrations[g_cRegistrations-1].prgAddresses[i].RemoteAddr.lpSockaddr);
|
|
}
|
|
|
|
free(g_Registrations[g_cRegistrations-1].prgAddresses);
|
|
g_cRegistrations--;
|
|
}
|
|
|
|
LeaveCriticalSection(&g_cs);
|
|
|
|
printf("All registrations removed.\n");
|
|
}
|
|
|
|
INT RemoveRegistration(__in LPWSAQUERYSET2 pQuerySet)
|
|
{
|
|
ULONG i, j;
|
|
int err;
|
|
|
|
err = WSAHOST_NOT_FOUND;
|
|
|
|
EnterCriticalSection(&g_cs);
|
|
|
|
for (i = 0; i < g_cRegistrations; i++)
|
|
{
|
|
if ( (wcscmp(pQuerySet->lpszServiceInstanceName, g_Registrations[i].pwzEmailAddress) == 0) &&
|
|
(wcscmp(pQuerySet->lpszContext, g_Registrations[i].pwzServiceName) == 0)
|
|
)
|
|
{
|
|
// found registration to remove
|
|
free(g_Registrations[i].pwzEmailAddress);
|
|
|
|
for (j = 0; j < g_Registrations[i].cAddresses; j++)
|
|
{
|
|
if (g_Registrations[i].prgAddresses[j].LocalAddr.lpSockaddr != NULL)
|
|
free(g_Registrations[i].prgAddresses[j].LocalAddr.lpSockaddr);
|
|
if (g_Registrations[i].prgAddresses[j].RemoteAddr.lpSockaddr != NULL)
|
|
free(g_Registrations[i].prgAddresses[j].RemoteAddr.lpSockaddr);
|
|
}
|
|
|
|
free(g_Registrations[i].prgAddresses);
|
|
|
|
g_Registrations[i] = g_Registrations[g_cRegistrations-1];
|
|
g_cRegistrations--;
|
|
printf("Registration for %S removed.\n", pQuerySet->lpszServiceInstanceName);
|
|
|
|
err = NO_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&g_cs);
|
|
|
|
return err;
|
|
}
|