windows-nt/Source/XPSP1/NT/net/ias/policy/dll_bld/iasattr.cpp
2020-09-26 16:20:57 +08:00

192 lines
3.8 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000, Microsoft Corp. All rights reserved.
//
// FILE
//
// iasattr.cpp
//
// SYNOPSIS
//
// Defines the API for manipulating IASATTRIBUTE structs.
//
// MODIFICATION HISTORY
//
// 02/02/2000 Original version.
//
///////////////////////////////////////////////////////////////////////////////
#include <polcypch.h>
#include <iaspolcy.h>
#include <iasattr.h>
DWORD
WINAPI
IASAttributeAlloc(
DWORD dwCount,
IASATTRIBUTE** ppAttribute
)
{
PIASATTRIBUTE* next = ppAttribute;
for ( ; dwCount; --dwCount, ++next)
{
if (!(*next = (PIASATTRIBUTE)CoTaskMemAlloc(sizeof(IASATTRIBUTE))))
{
while (next > ppAttribute)
{
CoTaskMemFree(*--next);
}
return ERROR_NOT_ENOUGH_MEMORY;
}
memset(*next, 0, sizeof(IASATTRIBUTE));
(*next)->dwReserved = 1;
}
return NO_ERROR;
}
DWORD
WINAPI
IASAttributeAddRef(
PIASATTRIBUTE pAttribute
)
{
if (pAttribute) { InterlockedIncrement((PLONG)&pAttribute->dwReserved); }
return NO_ERROR;
}
DWORD
WINAPI
IASAttributeRelease(
PIASATTRIBUTE pAttribute
)
{
if (pAttribute && !InterlockedDecrement((PLONG)&pAttribute->dwReserved))
{
switch (pAttribute->Value.itType)
{
case IASTYPE_STRING:
{
CoTaskMemFree(pAttribute->Value.String.pszAnsi);
CoTaskMemFree(pAttribute->Value.String.pszWide);
break;
}
case IASTYPE_OCTET_STRING:
{
CoTaskMemFree(pAttribute->Value.OctetString.lpValue);
break;
}
}
CoTaskMemFree(pAttribute);
}
return ERROR_SUCCESS;
}
DWORD
WINAPI
IASAttributeUnicodeAlloc(
PIASATTRIBUTE pAttribute
)
{
if (!pAttribute ||
pAttribute->Value.itType != IASTYPE_STRING ||
pAttribute->Value.String.pszWide != NULL ||
pAttribute->Value.String.pszAnsi == NULL)
{
return NO_ERROR;
}
// Find out how big a buffer we need.
int lenW = MultiByteToWideChar(
CP_ACP,
0,
pAttribute->Value.String.pszAnsi,
-1,
NULL,
0);
if (!lenW) { return GetLastError(); }
LPWSTR wide = (LPWSTR)CoTaskMemAlloc(lenW * sizeof(WCHAR));
if (!wide) { return ERROR_NOT_ENOUGH_MEMORY; }
// Do the conversion.
MultiByteToWideChar(
CP_ACP,
0,
pAttribute->Value.String.pszAnsi,
-1,
wide,
lenW
);
CoTaskMemFree(
InterlockedExchangePointer(
(PVOID*)&pAttribute->Value.String.pszWide,
wide
)
);
return NO_ERROR;
}
DWORD
WINAPI
IASAttributeAnsiAlloc(
PIASATTRIBUTE pAttribute
)
{
if (!pAttribute ||
pAttribute->Value.itType != IASTYPE_STRING ||
pAttribute->Value.String.pszAnsi != NULL ||
pAttribute->Value.String.pszWide == NULL)
{
return NO_ERROR;
}
// Find out how big a buffer we need.
int lenA = WideCharToMultiByte(
CP_ACP,
0,
pAttribute->Value.String.pszWide,
-1,
NULL,
0,
NULL,
NULL
);
if (!lenA) { return GetLastError(); }
LPSTR ansi = (LPSTR)CoTaskMemAlloc(lenA * sizeof(CHAR));
if (!ansi) { return ERROR_NOT_ENOUGH_MEMORY; }
// Do the conversion.
WideCharToMultiByte(
CP_ACP,
0,
pAttribute->Value.String.pszWide,
-1,
ansi,
lenA,
NULL,
NULL
);
CoTaskMemFree(
InterlockedExchangePointer(
(PVOID*)&pAttribute->Value.String.pszAnsi,
ansi
)
);
return NO_ERROR;
}