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

154 lines
4.4 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:
Install.c
Abstract:
This C file includes sample code for installation of an nspv2
naming provider
--********************************************************************/
#include "install.h"
// Utility routine to calculate the number of characters in an array of strings
//
ULONG GetTotalCch(ULONG cStrings, __in_ecount(cStrings) PCWSTR *prgStrings)
{
ULONG cch = 0;
ULONG i = 0;
for (i = 0; i < cStrings; i++)
{
cch += (ULONG) wcslen(prgStrings[i]);
}
return cch;
}
// Installation of a naming provider requires a "blob" of a specific format to be created.
// This function will create this blob. This function should be reusable by all naming providers.
//
// Layout: [All offsets are from beginning of buffer]
//
// | INSTALL_BLOB | DOMAIN_BLOB1 | DOMAIN_BLOB2 | DomainName1 | DomainName2 |
//
INT CreateInstallationBlob(
BOOL fWildcard,
ULONG cDomains,
__in_ecount(cDomains) PCWSTR *prgwzDomain,
__in_ecount(cDomains) BOOL *prgfPrimary,
__out ULONG *pcbBuffer,
__out PBYTE *ppbBuffer)
{
ULONG i = 0;
ULONG cchDomains = GetTotalCch(cDomains, prgwzDomain);
NAPI_INSTALL_BLOB InstallBlob = {0};
BYTE *pCurrent = NULL;
ULONG cbBlob = sizeof(NAPI_INSTALL_BLOB) + cDomains * sizeof(NAPI_DOMAIN_BLOB) +
cchDomains * sizeof(WCHAR);
BYTE *pBlob = malloc(cbBlob);
if (pBlob == NULL)
{
return WSA_NOT_ENOUGH_MEMORY;
}
// Copy install blob fields
//
InstallBlob.dwVersion = 1;
InstallBlob.dwReserved = 0;
InstallBlob.fSupportsWildCard = fWildcard;
InstallBlob.cDomains = cDomains;
InstallBlob.OffsetFirstDomain = sizeof(InstallBlob);
CopyMemory(pBlob, &InstallBlob, sizeof(InstallBlob));
pCurrent = pBlob + sizeof(InstallBlob);
cchDomains = 0;
// Serialize information about each domain supported
//
for (i = 0; i < cDomains; i++)
{
NAPI_DOMAIN_BLOB DomainBlob = {0};
ULONG cchThisDomain = (ULONG) wcslen(prgwzDomain[i]);
// Copy domain blob fields
//
DomainBlob.level = prgfPrimary[i] ? Primary : Secondary;
DomainBlob.cchDomainName = cchThisDomain;
DomainBlob.OffsetNextDomainBlob = sizeof(InstallBlob) + (i+1) * sizeof(NAPI_DOMAIN_BLOB);
DomainBlob.OffsetThisDomainName = sizeof(InstallBlob) + cDomains * sizeof(NAPI_DOMAIN_BLOB)
+ cchDomains * sizeof(WCHAR);
// Copy domain blob to current buffer location
//
CopyMemory(pCurrent, &DomainBlob, sizeof(DomainBlob));
pCurrent += sizeof(DomainBlob);
// copy domain name
//
CopyMemory(pBlob + DomainBlob.OffsetThisDomainName, prgwzDomain[i], cchThisDomain * sizeof(WCHAR));
cchDomains += cchThisDomain;
}
*pcbBuffer = cbBlob;
*ppbBuffer = pBlob;
return NO_ERROR;
}
// A sample routine demonstrating how a naming provider would install itself. Typically this would
// happen in an applications setup logic.
//
INT DoInstall(GUID ProviderId)
{
INT err = NO_ERROR;
ULONG cbBlob = 0;
BYTE *pbBlob = NULL;
// Setup domain arrays such that we are Primary for the domain "sampleprovider.net"
//
PWSTR rgDomains[] = { L"sampleprovider.net" };
BOOL rgAuthoritative[] = { TRUE };
// Create the blob
//
err = CreateInstallationBlob(FALSE,
celems(rgDomains),
rgDomains,
rgAuthoritative,
&cbBlob,
&pbBlob);
if (err == NO_ERROR)
{
// Call into winsock to install our naming provider
//
BLOB blob = { 0 };
blob.cbSize = cbBlob;
blob.pBlobData = pbBlob;
err = WSCInstallNameSpaceEx(L"Sample Provider", L"", NS_EMAIL, 1, &ProviderId, &blob);
free(pbBlob);
}
return err;
}
// Simple wrapper function to the winsock call to uninstall the namespace provider
VOID DoUninstall(GUID ProviderId)
{
WSCUnInstallNameSpace(&ProviderId);
}