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

228 lines
4.5 KiB
C

/* Copyright (c) Microsoft Corporation. All rights reserved. */
#include "windows.h"
#include "radutil.h"
#include "multisz.h"
LPVOID
WINAPI
RadiusAlloc(
SIZE_T dwBytes
)
{
return HeapAlloc(GetProcessHeap(), 0, dwBytes);
}
VOID
WINAPI
RadiusFree(
LPVOID lpMem
)
{
HeapFree(GetProcessHeap(), 0, lpMem);
}
DWORD
WINAPI
RadiusFindFirstIndex(
PRADIUS_ATTRIBUTE_ARRAY pAttrs,
DWORD dwAttrType
)
{
DWORD dwIndex, dwSize;
const RADIUS_ATTRIBUTE *pAttr;
if (pAttrs == NULL)
{
return RADIUS_ATTR_NOT_FOUND;
}
/* Get the number of attributes in the array */
dwSize = pAttrs->GetSize(pAttrs);
/* Iterate through the array ... */
for (dwIndex = 0; dwIndex < dwSize; ++dwIndex)
{
/* ... looking for the first attribute that matches the type. */
pAttr = pAttrs->AttributeAt(pAttrs, dwIndex);
if (pAttr->dwAttrType == dwAttrType)
{
return dwIndex;
}
}
return RADIUS_ATTR_NOT_FOUND;
}
const RADIUS_ATTRIBUTE*
WINAPI
RadiusFindFirstAttribute(
PRADIUS_ATTRIBUTE_ARRAY pAttrs,
DWORD dwAttrType
)
{
DWORD dwIndex;
dwIndex = RadiusFindFirstIndex(pAttrs, dwAttrType);
if (dwIndex != RADIUS_ATTR_NOT_FOUND)
{
return pAttrs->AttributeAt(pAttrs, dwIndex);
}
else
{
return NULL;
}
}
DWORD
WINAPI
RadiusReplaceFirstAttribute(
PRADIUS_ATTRIBUTE_ARRAY pAttrs,
const RADIUS_ATTRIBUTE* pSrc
)
{
DWORD dwIndex;
if ((pAttrs == NULL) || (pSrc == NULL))
{
return ERROR_INVALID_PARAMETER;
}
dwIndex = RadiusFindFirstIndex(pAttrs, pSrc->dwAttrType);
if (dwIndex != RADIUS_ATTR_NOT_FOUND)
{
/* It already exists, so overwrite the existing attribute. */
return pAttrs->SetAt(pAttrs, dwIndex, pSrc);
}
else
{
/* It doesn't exist, so add it to the end of the array. */
return pAttrs->Add(pAttrs, pSrc);
}
}
HRESULT
WINAPI
RadiusExtensionInstall(
HMODULE hModule,
LPCWSTR pwszType,
BOOL fInstall
)
{
LONG lResult;
HKEY hKey;
DWORD nChar, dwError;
WCHAR wszFileName[MAX_PATH];
MULTI_SZ value;
LPWSTR pwszSelf;
if ((hModule == NULL) || (pwszType == NULL))
{
return ERROR_INVALID_PARAMETER;
}
/* Retrieve the full path to the extension DLL. */
nChar = GetModuleFileNameW(
hModule,
wszFileName,
MAX_PATH
);
if (nChar == 0)
{
dwError = GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
/* Open or create the parameters key. */
lResult = RegCreateKeyExW(
HKEY_LOCAL_MACHINE,
AUTHSRV_PARAMETERS_KEY_W,
0,
NULL,
REG_OPTION_NON_VOLATILE,
(KEY_QUERY_VALUE | KEY_SET_VALUE),
NULL,
&hKey,
NULL
);
if (lResult != NO_ERROR)
{
return HRESULT_FROM_WIN32(lResult);
}
/* Read the current registered extensions DLLs. */
lResult = MultiSzQuery(
&value,
hKey,
pwszType
);
switch (lResult)
{
case NO_ERROR:
case ERROR_FILE_NOT_FOUND:
case ERROR_INVALID_DATA:
break;
default:
RegCloseKey(hKey);
return HRESULT_FROM_WIN32(lResult);
}
/* Is this DLL currently registered? */
pwszSelf = MultiSzFind(&value, wszFileName);
if (fInstall)
{
if (pwszSelf == NULL)
{
/* We're installing and we're not currently registered, so we have to
* add ourself to the list of DLLs. */
lResult = MultiSzAppend(&value, wszFileName);
if (lResult == NO_ERROR)
{
lResult = MultiSzSet(&value, hKey, pwszType);
}
}
else
{
/* The DLL is already registered -- nothing to do. */
lResult = NO_ERROR;
}
}
else
{
if (pwszSelf != NULL)
{
/* We're uninstalling and we're currently registered, so we have to
* remove ourself from the list of DLLs. */
MultiSzErase(&value, pwszSelf);
if (value.nChar > 1)
{
lResult = MultiSzSet(&value, hKey, pwszType);
}
else
{
lResult = RegDeleteValueW(hKey, pwszType);
}
}
else
{
/* The DLL isn't registered -- nothing to do. */
lResult = NO_ERROR;
}
}
/* Clean up the MULTI_SZ. */
MultiSzFree(&value);
return HRESULT_FROM_WIN32(lResult);
}