You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
389 lines
7.7 KiB
389 lines
7.7 KiB
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1997, Microsoft Corp. All rights reserved.
|
|
//
|
|
// FILE
|
|
//
|
|
// iasutil.cpp
|
|
//
|
|
// SYNOPSIS
|
|
//
|
|
// This file implements assorted utility functions, etc.
|
|
//
|
|
// MODIFICATION HISTORY
|
|
//
|
|
// 11/14/1997 Original version.
|
|
// 08/11/1998 Major overhaul and consolidation of utility functions.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <ias.h>
|
|
#include <iasapi.h>
|
|
#include <iasutil.h>
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// String functions.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Duplicates a WSTR using new[].
|
|
PWSTR
|
|
WINAPI
|
|
ias_wcsdup(PCWSTR str)
|
|
{
|
|
LPWSTR sz = NULL;
|
|
|
|
if (str)
|
|
{
|
|
size_t len = wcslen(str) + 1;
|
|
|
|
if (sz = new (std::nothrow) WCHAR[len])
|
|
{
|
|
memcpy(sz, str, len * sizeof(WCHAR));
|
|
}
|
|
}
|
|
|
|
return sz;
|
|
}
|
|
|
|
|
|
// Duplicates a STR using CoTaskMemAlloc.
|
|
PSTR
|
|
WINAPI
|
|
com_strdup(PCSTR str)
|
|
{
|
|
LPSTR sz = NULL;
|
|
|
|
if (str)
|
|
{
|
|
size_t size = sizeof(CHAR) * (strlen(str) + 1);
|
|
|
|
if (sz = (LPSTR)CoTaskMemAlloc(size))
|
|
{
|
|
memcpy(sz, str, size);
|
|
}
|
|
}
|
|
|
|
return sz;
|
|
}
|
|
|
|
|
|
// Duplicates a WSTR using CoTaskMemAlloc.
|
|
PWSTR
|
|
WINAPI
|
|
com_wcsdup(PCWSTR str)
|
|
{
|
|
LPWSTR sz = NULL;
|
|
|
|
if (str)
|
|
{
|
|
size_t size = sizeof(WCHAR) * (wcslen(str) + 1);
|
|
|
|
if (sz = (LPWSTR)CoTaskMemAlloc(size))
|
|
{
|
|
memcpy(sz, str, size);
|
|
}
|
|
}
|
|
|
|
return sz;
|
|
}
|
|
|
|
|
|
// Compares two WSTR's allowing for null pointers.
|
|
INT
|
|
WINAPI
|
|
ias_wcscmp(PCWSTR str1, PCWSTR str2)
|
|
{
|
|
if (str1 != NULL && str2 != NULL) return wcscmp(str1, str2);
|
|
|
|
return str1 == str2 ? 0 : (str1 > str2 ? 1 : -1);
|
|
}
|
|
|
|
|
|
// Concatenate a null-terminated list of strings.
|
|
LPWSTR
|
|
WINAPIV
|
|
ias_makewcs(LPCWSTR str1, ...)
|
|
{
|
|
size_t len = 0;
|
|
|
|
//////////
|
|
// Iterate through the arguments and calculate how much space we need.
|
|
//////////
|
|
|
|
va_list marker;
|
|
va_start(marker, str1);
|
|
LPCWSTR sz = str1;
|
|
while (sz)
|
|
{
|
|
len += wcslen(sz);
|
|
sz = va_arg(marker, LPCWSTR);
|
|
}
|
|
va_end(marker);
|
|
|
|
// Add room for the null-terminator.
|
|
++len;
|
|
|
|
//////////
|
|
// Allocate memory to hold the concatentated string.
|
|
//////////
|
|
|
|
LPWSTR rv = new (std::nothrow) WCHAR[len];
|
|
if (!rv) return NULL;
|
|
|
|
// Initialize the string so wcscat will work.
|
|
*rv = L'\0';
|
|
|
|
//////////
|
|
// Concatenate the strings.
|
|
//////////
|
|
|
|
va_start(marker, str1);
|
|
sz = str1;
|
|
while (sz)
|
|
{
|
|
wcscat(rv, sz);
|
|
sz = va_arg(marker, LPCWSTR);
|
|
}
|
|
va_end(marker);
|
|
|
|
return rv;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Functions to move integers to and from a buffer.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
VOID
|
|
WINAPI
|
|
IASInsertDWORD(
|
|
PBYTE pBuffer,
|
|
DWORD dwValue
|
|
)
|
|
{
|
|
*pBuffer++ = (BYTE)((dwValue >> 24) & 0xFF);
|
|
*pBuffer++ = (BYTE)((dwValue >> 16) & 0xFF);
|
|
*pBuffer++ = (BYTE)((dwValue >> 8) & 0xFF);
|
|
*pBuffer = (BYTE)((dwValue ) & 0xFF);
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
IASExtractDWORD(
|
|
CONST BYTE *pBuffer
|
|
)
|
|
{
|
|
return (DWORD)(pBuffer[0] << 24) | (DWORD)(pBuffer[1] << 16) |
|
|
(DWORD)(pBuffer[2] << 8) | (DWORD)(pBuffer[3] );
|
|
}
|
|
|
|
VOID
|
|
WINAPI
|
|
IASInsertWORD(
|
|
PBYTE pBuffer,
|
|
WORD wValue
|
|
)
|
|
{
|
|
*pBuffer++ = (BYTE)((wValue >> 8) & 0xFF);
|
|
*pBuffer = (BYTE)((wValue ) & 0xFF);
|
|
}
|
|
|
|
WORD
|
|
WINAPI
|
|
IASExtractWORD(
|
|
CONST BYTE *pBuffer
|
|
)
|
|
{
|
|
return (WORD)(pBuffer[0] << 8) | (WORD)(pBuffer[1]);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Extensions to _com_error to handle Win32 errors.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void __stdcall _w32_issue_error(DWORD errorCode) throw (_w32_error)
|
|
{
|
|
throw _w32_error(errorCode);
|
|
}
|
|
|
|
|
|
namespace
|
|
{
|
|
// Get the path to a database on the local computer.
|
|
DWORD GetDatabasePath(
|
|
const wchar_t* fileName,
|
|
wchar_t* buffer,
|
|
DWORD* size
|
|
) throw ()
|
|
{
|
|
// Value where the path to the IAS directory is stored.
|
|
static const wchar_t productDirValue[] = L"ProductDir";
|
|
|
|
if ((fileName == 0) || (buffer == 0) || (size == 0))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// Initialize the out parameter.
|
|
DWORD inSize = *size;
|
|
*size = 0;
|
|
|
|
// Open the registry key.
|
|
LONG result;
|
|
HKEY hKey;
|
|
result = RegOpenKeyExW(
|
|
HKEY_LOCAL_MACHINE,
|
|
IAS_POLICY_KEY,
|
|
0,
|
|
KEY_READ,
|
|
&hKey
|
|
);
|
|
if (result != NO_ERROR)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
// Read the ProductDir value.
|
|
DWORD dwType;
|
|
DWORD cbData = inSize * sizeof(wchar_t);
|
|
result = RegQueryValueExW(
|
|
hKey,
|
|
productDirValue,
|
|
0,
|
|
&dwType,
|
|
reinterpret_cast<BYTE*>(buffer),
|
|
&cbData
|
|
);
|
|
|
|
// We're done with the registry key.
|
|
RegCloseKey(hKey);
|
|
|
|
// Compute the length of the full path in characters.
|
|
DWORD outSize = (cbData / sizeof(WCHAR)) + wcslen(fileName);
|
|
|
|
if (result != NO_ERROR)
|
|
{
|
|
// If we overflowed, return the needed size.
|
|
if (result == ERROR_MORE_DATA)
|
|
{
|
|
*size = outSize;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// The registry value must contain a string.
|
|
if (dwType != REG_SZ)
|
|
{
|
|
return REGDB_E_INVALIDVALUE;
|
|
}
|
|
|
|
// Do we have enough room to append the filename.
|
|
if (outSize <= inSize)
|
|
{
|
|
wcscat(buffer, fileName);
|
|
}
|
|
else
|
|
{
|
|
result = ERROR_MORE_DATA;
|
|
}
|
|
|
|
// Return the size (whether actual or needed).
|
|
*size = outSize;
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
IASGetConfigPath(
|
|
OUT PWSTR buffer,
|
|
IN OUT PDWORD size
|
|
)
|
|
{
|
|
return GetDatabasePath(L"\\ias.mdb", buffer, size);
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
IASGetDictionaryPath(
|
|
OUT PWSTR buffer,
|
|
IN OUT PDWORD size
|
|
)
|
|
{
|
|
return GetDatabasePath(L"\\dnary.mdb", buffer, size);
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
IASGetProductLimitsForType(
|
|
IN IAS_LICENSE_TYPE type,
|
|
OUT IAS_PRODUCT_LIMITS* limits
|
|
)
|
|
{
|
|
static const IAS_PRODUCT_LIMITS workstationLimits =
|
|
{
|
|
0,
|
|
FALSE,
|
|
0
|
|
};
|
|
static const IAS_PRODUCT_LIMITS standardServerLimits =
|
|
{
|
|
50,
|
|
FALSE,
|
|
2
|
|
};
|
|
static const IAS_PRODUCT_LIMITS unlimitedServerLimits =
|
|
{
|
|
IAS_NO_LIMIT,
|
|
TRUE,
|
|
IAS_NO_LIMIT
|
|
};
|
|
|
|
if (limits == 0)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
switch (type)
|
|
{
|
|
case IASLicenseTypeProfessional:
|
|
case IASLicenseTypePersonal:
|
|
{
|
|
*limits = workstationLimits;
|
|
break;
|
|
}
|
|
|
|
case IASLicenseTypeStandardServer:
|
|
case IASLicenseTypeWebBlade:
|
|
case IASLicenseTypeSmallBusinessServer:
|
|
{
|
|
*limits = standardServerLimits;
|
|
break;
|
|
}
|
|
|
|
case IASLicenseTypeDownlevel:
|
|
case IASLicenseTypeEnterpriseServer:
|
|
case IASLicenseTypeDataCenter:
|
|
{
|
|
*limits = unlimitedServerLimits;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|