871 lines
15 KiB
C++
871 lines
15 KiB
C++
//***************************************************************************
|
|
//
|
|
// Useful.CPP
|
|
//
|
|
// Module: CDM Provider
|
|
//
|
|
// Purpose: Useful classes
|
|
//
|
|
// Copyright (c) 2000 Microsoft Corporation
|
|
//
|
|
//***************************************************************************
|
|
|
|
#include <objbase.h>
|
|
#include <wbemprov.h>
|
|
|
|
#include "debug.h"
|
|
#include "useful.h"
|
|
#include "wbemmisc.h"
|
|
|
|
void FreeTheBSTRArray(
|
|
BSTR *Array,
|
|
ULONG Size
|
|
)
|
|
/*+++
|
|
|
|
Routine Description:
|
|
|
|
This routine will free the contents of an array of BSTR and then
|
|
the array itself
|
|
|
|
Arguments:
|
|
|
|
Array is the array to be freed
|
|
|
|
Size is the number of elements in the array
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
---*/
|
|
{
|
|
ULONG i;
|
|
|
|
if (Array != NULL)
|
|
{
|
|
for (i = 0; i < Size; i++)
|
|
{
|
|
if (Array[i] != NULL)
|
|
{
|
|
SysFreeString(Array[i]);
|
|
}
|
|
}
|
|
WmipFree(Array);
|
|
}
|
|
}
|
|
|
|
CBstrArray::CBstrArray()
|
|
{
|
|
Array = NULL;
|
|
ListSize = 0xffffffff;
|
|
}
|
|
|
|
CBstrArray::~CBstrArray()
|
|
{
|
|
ULONG i;
|
|
|
|
if (Array != NULL)
|
|
{
|
|
for (i = 0; i < ListSize; i++)
|
|
{
|
|
if (Array[i] != NULL)
|
|
{
|
|
SysFreeString(Array[i]);
|
|
}
|
|
}
|
|
WmipFree(Array);
|
|
}
|
|
|
|
ListSize = 0xffffffff;
|
|
}
|
|
|
|
HRESULT CBstrArray::Initialize(
|
|
ULONG ListCount
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
ULONG AllocSize;
|
|
|
|
if (ListCount != 0)
|
|
{
|
|
AllocSize = ListCount * sizeof(BSTR *);
|
|
Array = (BSTR *)WmipAlloc(AllocSize);
|
|
if (Array != NULL)
|
|
{
|
|
memset(Array, 0, AllocSize);
|
|
ListSize = ListCount;
|
|
} else {
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
} else {
|
|
ListSize = ListCount;
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
BOOLEAN CBstrArray::IsInitialized(
|
|
)
|
|
{
|
|
return( (Array != NULL) || (ListSize == 0) );
|
|
}
|
|
|
|
BSTR CBstrArray::Get(
|
|
ULONG Index
|
|
)
|
|
{
|
|
WmipAssert(Index < ListSize);
|
|
|
|
WmipAssert(IsInitialized());
|
|
|
|
return(Array[Index]);
|
|
}
|
|
|
|
void CBstrArray::Set(
|
|
ULONG Index,
|
|
BSTR s
|
|
)
|
|
{
|
|
WmipAssert(Index < ListSize);
|
|
|
|
WmipAssert(IsInitialized());
|
|
|
|
Array[Index] = s;
|
|
}
|
|
|
|
ULONG CBstrArray::GetListSize(
|
|
)
|
|
{
|
|
WmipAssert(IsInitialized());
|
|
|
|
return(ListSize);
|
|
}
|
|
|
|
|
|
CWbemObjectList::CWbemObjectList()
|
|
{
|
|
//
|
|
// Constructor, init internal values
|
|
//
|
|
List = NULL;
|
|
RelPaths = NULL;
|
|
ListSize = 0xffffffff;
|
|
}
|
|
|
|
CWbemObjectList::~CWbemObjectList()
|
|
{
|
|
ULONG i;
|
|
|
|
//
|
|
// Destructor, free memory held by this class
|
|
//
|
|
|
|
if (List != NULL)
|
|
{
|
|
for (i = 0; i < ListSize; i++)
|
|
{
|
|
if (List[i] != NULL)
|
|
{
|
|
List[i]->Release();
|
|
}
|
|
}
|
|
WmipFree(List);
|
|
}
|
|
List = NULL;
|
|
|
|
if (RelPaths != NULL)
|
|
{
|
|
FreeTheBSTRArray(RelPaths, ListSize);
|
|
RelPaths = NULL;
|
|
}
|
|
|
|
ListSize = 0xffffffff;
|
|
}
|
|
|
|
HRESULT CWbemObjectList::Initialize(
|
|
ULONG NumberPointers
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
ULONG AllocSize;
|
|
|
|
//
|
|
// Initialize class by allocating internal list array
|
|
//
|
|
|
|
WmipAssert(List == NULL);
|
|
|
|
if (NumberPointers != 0)
|
|
{
|
|
AllocSize = NumberPointers * sizeof(IWbemClassObject *);
|
|
List = (IWbemClassObject **)WmipAlloc(AllocSize);
|
|
if (List != NULL)
|
|
{
|
|
memset(List, 0, AllocSize);
|
|
AllocSize = NumberPointers * sizeof(BSTR);
|
|
|
|
RelPaths = (BSTR *)WmipAlloc(AllocSize);
|
|
if (RelPaths != NULL)
|
|
{
|
|
memset(RelPaths, 0, AllocSize);
|
|
ListSize = NumberPointers;
|
|
hr = WBEM_S_NO_ERROR;
|
|
} else {
|
|
WmipDebugPrint(("CDMProv: Could not alloc memory for CWbemObjectList RelPaths\n"));
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
} else {
|
|
WmipDebugPrint(("CDMProv: Could not alloc memory for CWbemObjectList\n"));
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
} else {
|
|
ListSize = NumberPointers;
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
ULONG CWbemObjectList::GetListSize(
|
|
void
|
|
)
|
|
{
|
|
//
|
|
// Accessor for list size
|
|
//
|
|
|
|
WmipAssert(IsInitialized());
|
|
|
|
return(ListSize);
|
|
}
|
|
|
|
IWbemClassObject *CWbemObjectList::Get(
|
|
ULONG Index
|
|
)
|
|
{ IWbemClassObject *Pointer;
|
|
|
|
WmipAssert(Index < ListSize);
|
|
WmipAssert(IsInitialized());
|
|
|
|
Pointer = List[Index];
|
|
|
|
return(Pointer);
|
|
}
|
|
|
|
|
|
HRESULT CWbemObjectList::Set(
|
|
IN ULONG Index,
|
|
IN IWbemClassObject *Pointer
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
VARIANT v;
|
|
|
|
WmipAssert(Pointer != NULL);
|
|
|
|
WmipAssert(Index < ListSize);
|
|
WmipAssert(IsInitialized());
|
|
|
|
hr = WmiGetProperty(Pointer,
|
|
L"__RelPath",
|
|
CIM_REFERENCE,
|
|
&v);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
RelPaths[Index] = v.bstrVal;
|
|
List[Index] = Pointer;
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
BSTR /* NOFREE */ CWbemObjectList::GetRelPath(
|
|
IN ULONG Index
|
|
)
|
|
{
|
|
WmipAssert(Index < ListSize);
|
|
WmipAssert(IsInitialized());
|
|
|
|
return(RelPaths[Index]);
|
|
}
|
|
|
|
BOOLEAN CWbemObjectList::IsInitialized(
|
|
)
|
|
{
|
|
return((ListSize == 0) ||
|
|
((List != NULL) && (RelPaths != NULL)));
|
|
}
|
|
|
|
|
|
CValueMapping::CValueMapping(
|
|
)
|
|
{
|
|
VariantInit(&Values);
|
|
ValueMap = NULL;
|
|
}
|
|
|
|
CValueMapping::~CValueMapping(
|
|
)
|
|
{
|
|
if (ValueMap != NULL)
|
|
{
|
|
WmipFree(ValueMap);
|
|
}
|
|
|
|
VariantClear(&Values);
|
|
}
|
|
|
|
|
|
|
|
HRESULT CValueMapping::EstablishByName(
|
|
IWbemServices *pServices,
|
|
PWCHAR ClassName,
|
|
PWCHAR PropertyName
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
PWCHAR Names[2];
|
|
VARTYPE Types[2];
|
|
VARIANT v[2];
|
|
VARTYPE IsValueMapArray, IsValuesArray;
|
|
|
|
Names[0] = L"ValueMap";
|
|
Types[0] = VT_BSTR;
|
|
|
|
Names[1] = L"Values";
|
|
Types[1] = VT_BSTR;
|
|
hr = WmiGetQualifierListByName(pServices,
|
|
ClassName,
|
|
PropertyName,
|
|
2,
|
|
Names,
|
|
Types,
|
|
v);
|
|
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
IsValueMapArray = v[0].vt & VT_ARRAY;
|
|
IsValuesArray = v[1].vt & VT_ARRAY;
|
|
if (IsValueMapArray == IsValuesArray)
|
|
{
|
|
if (IsValueMapArray)
|
|
{
|
|
//
|
|
// Qualifiers specified as arrays so we can just
|
|
// set them up
|
|
//
|
|
hr = EstablishByArrays(&v[1],
|
|
&v[0]);
|
|
} else {
|
|
//
|
|
// Qualifiers specified as scalars
|
|
//
|
|
hr = EstablishByScalars(v[1].bstrVal,
|
|
v[0].bstrVal);
|
|
}
|
|
} else {
|
|
//
|
|
// Both must be an array or a scalar
|
|
//
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
|
|
VariantClear(&v[0]);
|
|
VariantClear(&v[1]);
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CValueMapping::EstablishByScalars(
|
|
BSTR vValues,
|
|
BSTR vValueMap
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
PULONG Number;
|
|
LONG Index;
|
|
SAFEARRAYBOUND Bound;
|
|
|
|
//
|
|
// First, establish the ValueMap values
|
|
//
|
|
ValueMap = (PULONG64)WmipAlloc(sizeof(ULONG64));
|
|
if (ValueMap != NULL)
|
|
{
|
|
*ValueMap = _wtoi(vValueMap);
|
|
ValueMapElements = 1;
|
|
|
|
//
|
|
// Now build a safearray to store the Values element
|
|
//
|
|
ValuesLBound = 0;
|
|
Bound.lLbound = ValuesLBound;
|
|
Bound.cElements = 1;
|
|
Values.parray = SafeArrayCreate(VT_BSTR,
|
|
1,
|
|
&Bound);
|
|
if (Values.parray != NULL)
|
|
{
|
|
Values.vt = VT_BSTR | VT_ARRAY;
|
|
Index = 0;
|
|
hr = SafeArrayPutElement(Values.parray,
|
|
&Index,
|
|
vValues);
|
|
if (hr != WBEM_S_NO_ERROR)
|
|
{
|
|
VariantClear(&Values);
|
|
}
|
|
}
|
|
|
|
} else {
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CValueMapping::EstablishByArrays(
|
|
VARIANT *vValues,
|
|
VARIANT *vValueMap
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
BSTR s;
|
|
LONG ValueMapLBound, ValueMapUBound;
|
|
LONG ValuesUBound, ValuesElements;
|
|
LONG Index;
|
|
LONG i;
|
|
|
|
//
|
|
// Get the array sizes and ensure that they match
|
|
//
|
|
hr = WmiGetArraySize(vValueMap->parray,
|
|
&ValueMapLBound,
|
|
&ValueMapUBound,
|
|
&ValueMapElements);
|
|
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
hr = WmiGetArraySize(vValues->parray,
|
|
&ValuesLBound,
|
|
&ValuesUBound,
|
|
&ValuesElements);
|
|
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
if ((ValuesLBound == ValueMapLBound) &&
|
|
(ValuesUBound == ValueMapUBound) &&
|
|
(ValuesElements == ValueMapElements))
|
|
{
|
|
//
|
|
// The ValueMap is balance with the values so parse the
|
|
// valuemaps from strings to ulongs
|
|
//
|
|
ValueMap = (PULONG64)WmipAlloc(ValueMapElements * sizeof(ULONG64));
|
|
if (ValueMap != NULL)
|
|
{
|
|
for (i = 0; i < ValueMapElements; i++)
|
|
{
|
|
Index = i + ValueMapLBound;
|
|
hr = SafeArrayGetElement(vValueMap->parray,
|
|
&Index,
|
|
&s);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
ValueMap[i] = _wtoi(s);
|
|
SysFreeString(s);
|
|
}
|
|
}
|
|
|
|
//
|
|
// And assign Values to our class
|
|
//
|
|
Values = *vValues;
|
|
VariantInit(vValues);
|
|
} else {
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CValueMapping::MapToString(
|
|
IN ULONG64 Number,
|
|
OUT BSTR *String
|
|
)
|
|
{
|
|
LONG i;
|
|
WCHAR ss[MAX_PATH];
|
|
LONG Index;
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Loop over all values and try to find a match
|
|
//
|
|
for (i = 0, hr = WBEM_E_FAILED;
|
|
(i < ValueMapElements) && (hr != WBEM_S_NO_ERROR);
|
|
i++)
|
|
{
|
|
if (Number == ValueMap[i])
|
|
{
|
|
//
|
|
// We found something to map the value to
|
|
//
|
|
Index = i + ValuesLBound;
|
|
hr = SafeArrayGetElement(Values.parray,
|
|
&Index,
|
|
String);
|
|
}
|
|
}
|
|
|
|
if (hr != WBEM_S_NO_ERROR)
|
|
{
|
|
//
|
|
// There was no match so we just leave the result as a number
|
|
//
|
|
wsprintfW(ss, L"%d", Number);
|
|
*String = SysAllocString(ss);
|
|
if (*String == NULL)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CValueMapping::MapToNumber(
|
|
IN BSTR String,
|
|
OUT PULONG64 Number
|
|
)
|
|
{
|
|
LONG i;
|
|
BSTR s;
|
|
LONG Index;
|
|
HRESULT hr, hr2;
|
|
|
|
for (i = 0, hr = WBEM_E_FAILED;
|
|
(i < ValueMapElements) && (hr != WBEM_S_NO_ERROR);
|
|
i++)
|
|
{
|
|
Index = i + ValuesLBound;
|
|
hr2 = SafeArrayGetElement(Values.parray,
|
|
&Index,
|
|
&s);
|
|
|
|
if (hr2 == WBEM_S_NO_ERROR)
|
|
{
|
|
if (_wcsicmp(s, String) == 0)
|
|
{
|
|
*Number = ValueMap[i];
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
SysFreeString(s);
|
|
}
|
|
}
|
|
|
|
//
|
|
// There was no match so we don't really have anything to map to
|
|
//
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CValueMapping::MapVariantToNumber(
|
|
VARIANT *v,
|
|
CIMTYPE NewType
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
VARTYPE BaseType, IsArray;
|
|
ULONG64 Number;
|
|
VARTYPE NewVarType;
|
|
WCHAR ss[MAX_PATH];
|
|
|
|
BaseType = v->vt & ~VT_ARRAY;
|
|
IsArray = v->vt & VT_ARRAY;
|
|
|
|
WmipAssert(BaseType == VT_BSTR);
|
|
|
|
if (IsArray == VT_ARRAY)
|
|
{
|
|
//
|
|
// The variant is an array so we need to map each element in an
|
|
// array
|
|
//
|
|
SAFEARRAYBOUND Bounds;
|
|
SAFEARRAY *Array;
|
|
ULONG Value;
|
|
LONG UBound, LBound, Elements, Index;
|
|
BSTR s;
|
|
LONG i;
|
|
|
|
hr = WmiGetArraySize(v->parray,
|
|
&LBound,
|
|
&UBound,
|
|
&Elements);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
if ((NewType == (CIM_SINT64 | CIM_FLAG_ARRAY)) ||
|
|
(NewType == (CIM_UINT64 | CIM_FLAG_ARRAY)))
|
|
{
|
|
//
|
|
// If we are mapping to a 64bit number we need to make
|
|
// it into a string so setup as an safearray of strings
|
|
//
|
|
NewVarType = VT_BSTR | VT_ARRAY;
|
|
} else {
|
|
NewVarType = (VARTYPE)NewType;
|
|
}
|
|
|
|
Bounds.lLbound = LBound;
|
|
Bounds.cElements = Elements;
|
|
Array = SafeArrayCreate(NewVarType,
|
|
1,
|
|
&Bounds);
|
|
|
|
if (Array != NULL)
|
|
{
|
|
for (i = 0;
|
|
(i < Elements) && (hr == WBEM_S_NO_ERROR);
|
|
i++)
|
|
{
|
|
Index = i + LBound;
|
|
hr = SafeArrayGetElement(v->parray,
|
|
&Index,
|
|
&s);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
hr = MapToNumber(s,
|
|
&Number);
|
|
SysFreeString(s);
|
|
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
if (NewVarType == (VT_BSTR | VT_ARRAY))
|
|
{
|
|
//
|
|
// Mapping to a 64bit number so convert
|
|
// to string first
|
|
//
|
|
wsprintfW(ss, L"%d", Number);
|
|
s = SysAllocString(ss);
|
|
if (s != NULL)
|
|
{
|
|
hr = SafeArrayPutElement(Array,
|
|
&Index,
|
|
s);
|
|
SysFreeString(s);
|
|
} else {
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
} else {
|
|
hr = SafeArrayPutElement(Array,
|
|
&Index,
|
|
&Number);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
VariantClear(v);
|
|
v->vt = NewType | VT_ARRAY;
|
|
v->parray = Array;
|
|
} else {
|
|
SafeArrayDestroy(Array);
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// The variant is a scalar so we just need to map one thing
|
|
//
|
|
hr = MapToNumber(v->bstrVal,
|
|
&Number);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
VariantClear(v);
|
|
WmiSetNumberInVariant(v,
|
|
NewType,
|
|
Number);
|
|
}
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CValueMapping::MapVariantToString(
|
|
VARIANT *v,
|
|
CIMTYPE OldType
|
|
)
|
|
{
|
|
VARTYPE BaseType, IsArray;
|
|
ULONG64 Number;
|
|
BSTR s;
|
|
HRESULT hr;
|
|
LONG i;
|
|
|
|
BaseType = v->vt & ~VT_ARRAY;
|
|
IsArray = v->vt & VT_ARRAY;
|
|
|
|
if (IsArray == VT_ARRAY)
|
|
{
|
|
//
|
|
// The variant is an array so we need to map each element in an
|
|
// array
|
|
//
|
|
SAFEARRAYBOUND Bounds;
|
|
SAFEARRAY *Array;
|
|
ULONG Value;
|
|
LONG UBound, LBound, Elements, Index;
|
|
|
|
hr = WmiGetArraySize(v->parray,
|
|
&LBound,
|
|
&UBound,
|
|
&Elements);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
Bounds.lLbound = LBound;
|
|
Bounds.cElements = Elements;
|
|
Array = SafeArrayCreate(VT_BSTR,
|
|
1,
|
|
&Bounds);
|
|
|
|
if (Array != NULL)
|
|
{
|
|
for (i = 0;
|
|
(i < Elements) && (hr == WBEM_S_NO_ERROR);
|
|
i++)
|
|
{
|
|
Index = i + LBound;
|
|
|
|
if (BaseType == VT_BSTR)
|
|
{
|
|
//
|
|
// If base type is a string then we assume that
|
|
// we've got a 64bit number which is encoded as
|
|
// a string. So we need to fish out the string
|
|
// and convert it to a ULONG64
|
|
//
|
|
WmipAssert((OldType == (CIM_SINT64 | CIM_FLAG_ARRAY)) ||
|
|
(OldType == (CIM_UINT64 | CIM_FLAG_ARRAY)));
|
|
|
|
hr = SafeArrayGetElement(v->parray,
|
|
&Index,
|
|
&s);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
Number = _wtoi(s);
|
|
SysFreeString(s);
|
|
}
|
|
} else {
|
|
//
|
|
// Otherwise the number is acutally encoded as
|
|
// a number so fish out the number
|
|
//
|
|
Number = 0;
|
|
hr = SafeArrayGetElement(v->parray,
|
|
&Index,
|
|
&Number);
|
|
}
|
|
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
hr = MapToString(Number,
|
|
&s);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
hr = SafeArrayPutElement(Array,
|
|
&Index,
|
|
s);
|
|
SysFreeString(s);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
VariantClear(v);
|
|
v->vt = VT_BSTR | VT_ARRAY;
|
|
v->parray = Array;
|
|
} else {
|
|
SafeArrayDestroy(Array);
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// The variant is a scalar so we just need to map one thing
|
|
//
|
|
WmiGetNumberFromVariant(v,
|
|
OldType,
|
|
&Number);
|
|
|
|
hr = MapToString(Number,
|
|
&s);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
VariantClear(v);
|
|
v->vt = VT_BSTR;
|
|
v->bstrVal = s;
|
|
}
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
#ifndef HEAP_DEBUG
|
|
PVOID WmipAlloc(
|
|
IN ULONG Size
|
|
)
|
|
/*+++
|
|
|
|
Routine Description:
|
|
|
|
Internal memory allocator
|
|
|
|
Arguments:
|
|
|
|
Size is the number of bytes to allocate
|
|
|
|
Return Value:
|
|
|
|
pointer to alloced memory or NULL
|
|
|
|
---*/
|
|
{
|
|
return(LocalAlloc(LPTR, Size));
|
|
}
|
|
|
|
void WmipFree(
|
|
IN PVOID Ptr
|
|
)
|
|
/*+++
|
|
|
|
Routine Description:
|
|
|
|
Internal memory deallocator
|
|
|
|
Arguments:
|
|
|
|
Pointer to freed memory
|
|
|
|
Return Value:
|
|
|
|
void
|
|
|
|
---*/
|
|
{
|
|
WmipAssert(Ptr != NULL);
|
|
LocalFree(Ptr);
|
|
}
|
|
|
|
#endif
|
|
|
|
|