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.
1507 lines
38 KiB
1507 lines
38 KiB
//---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1997
|
|
//
|
|
// File: schemini.cxx
|
|
//
|
|
// Contents: Loading Schema/Property from metabase code
|
|
//
|
|
// History: 28-Apr-97 Markand Created.
|
|
// History: 18-Aug-98 sophiac Extensible schema
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#include "iis.hxx"
|
|
#define INITGUID
|
|
#pragma hdrstop
|
|
#include "mddef.h"
|
|
#include <tchar.h>
|
|
|
|
#define DEFAULT_TIMEOUT_VALUE 30000
|
|
|
|
StrMap::StrMap() {
|
|
count = 0;
|
|
mapSize = 64;
|
|
map = (StrMapEntry *)malloc(sizeof(StrMapEntry) * mapSize);
|
|
}
|
|
|
|
StrMap::~StrMap() {
|
|
free(map);
|
|
}
|
|
|
|
DWORD StrMap::GetEntries() {
|
|
return count;
|
|
}
|
|
|
|
LPWSTR StrMap::GetEntryName(DWORD dwIndex) {
|
|
return map[dwIndex].m_str;
|
|
}
|
|
|
|
|
|
BOOL StrMap::CheckSpace() {
|
|
if (count < mapSize)
|
|
return TRUE;
|
|
mapSize += 32;
|
|
StrMapEntry* map_old = map;
|
|
if ((map = (StrMapEntry *)realloc(map, sizeof(StrMapEntry)*mapSize)) == NULL)
|
|
{
|
|
if (map_old)
|
|
{
|
|
free(map_old);
|
|
}
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL StrMap::Add(LPWSTR str, void *data) {
|
|
if (!CheckSpace())
|
|
return FALSE;
|
|
map[count].m_str = str;
|
|
map[count].m_data = data;
|
|
count++;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL StrMap::ClearEntry(DWORD dwIndex) {
|
|
|
|
count--;
|
|
|
|
void* prop = map[dwIndex].m_data;
|
|
|
|
// replace object to be deleted by last object in list and decrement count
|
|
|
|
map[dwIndex].m_str = map[count].m_str;
|
|
map[dwIndex].m_data = map[count].m_data;
|
|
map[count].m_str = NULL;
|
|
map[count].m_data = NULL;
|
|
|
|
if (prop)
|
|
delete prop;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void *StrMap::Find(LPWSTR str) {
|
|
for (int i=0; i < count; i++) {
|
|
if (!_wcsicmp(str, map[i].m_str))
|
|
return map[i].m_data;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void *StrMap::operator[] (LPWSTR str) {
|
|
return Find(str);
|
|
}
|
|
|
|
|
|
DWORDMap::DWORDMap() {
|
|
count = 0;
|
|
mapSize = 64;
|
|
map = (DWORDMapEntry *)malloc(sizeof(DWORDMapEntry) * mapSize);
|
|
}
|
|
|
|
DWORDMap::~DWORDMap() {
|
|
free(map);
|
|
}
|
|
|
|
BOOL DWORDMap::CheckSpace() {
|
|
if (count < mapSize)
|
|
return TRUE;
|
|
mapSize += 32;
|
|
|
|
DWORDMapEntry* map_old = map;
|
|
if ((map = (DWORDMapEntry *)realloc(map, sizeof(DWORDMapEntry)*mapSize)) == NULL)
|
|
{
|
|
if (map_old)
|
|
{
|
|
free(map_old);
|
|
}
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL DWORDMap::Add(DWORD val, void *data) {
|
|
if (!CheckSpace())
|
|
return FALSE;
|
|
map[count].m_val = val;
|
|
map[count].m_data = data;
|
|
count++;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL DWORDMap::ClearEntry(DWORD id) {
|
|
// !! don't delete the m_data here
|
|
// !! it will be or already has been deleted
|
|
// !! by StrMap::ClearEntry
|
|
|
|
int ri = 0;
|
|
|
|
for (int i=0; i < count; i++) {
|
|
if (id == map[i].m_val)
|
|
ri = i;
|
|
}
|
|
|
|
count--;
|
|
|
|
map[ri].m_val = map[count].m_val;
|
|
map[ri].m_data = map[count].m_data;
|
|
map[count].m_val = NULL;
|
|
map[count].m_data = NULL;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void *DWORDMap::Find(DWORD val) {
|
|
for (int i=0; i < count; i++) {
|
|
if (val == map[i].m_val)
|
|
return map[i].m_data;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void *DWORDMap::operator[] (DWORD val) {
|
|
return Find(val);
|
|
}
|
|
|
|
IIsSchemaClass::IIsSchemaClass(LPWSTR _name) {
|
|
memset(&classInfo, 0, sizeof(CLASSINFO));
|
|
name = new WCHAR[wcslen(_name)+1];
|
|
wcscpy(name, _name);
|
|
}
|
|
|
|
IIsSchemaClass::~IIsSchemaClass() {
|
|
delete[] name;
|
|
|
|
if (classInfo.bstrContainment)
|
|
FreeADsMem(classInfo.bstrContainment);
|
|
if (classInfo.bstrOptionalProperties)
|
|
FreeADsMem(classInfo.bstrOptionalProperties);
|
|
if (classInfo.bstrMandatoryProperties)
|
|
FreeADsMem(classInfo.bstrMandatoryProperties);
|
|
}
|
|
|
|
HRESULT
|
|
IISSchemaProperty::SetpropInfo(PROPERTYINFO *ppropInfo) {
|
|
|
|
HRESULT hr = S_OK;
|
|
LPWSTR pszStr;
|
|
|
|
if (propInfo.bstrOID) {
|
|
ADsFreeString( propInfo.bstrOID );
|
|
}
|
|
if (propInfo.bstrSyntax) {
|
|
ADsFreeString( propInfo.bstrSyntax );
|
|
}
|
|
if (propInfo.szDefault) {
|
|
if (propInfo.dwSyntaxId == IIS_SYNTAX_ID_STRING ||
|
|
propInfo.dwSyntaxId == IIS_SYNTAX_ID_EXPANDSZ) {
|
|
FreeADsStr( propInfo.szDefault );
|
|
}
|
|
else if (propInfo.dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) {
|
|
FreeADsMem( propInfo.szDefault );
|
|
}
|
|
}
|
|
|
|
memset(&propInfo, 0, sizeof(PROPERTYINFO));
|
|
memcpy(&propInfo, ppropInfo, sizeof(PROPERTYINFO));
|
|
|
|
hr = ADsAllocString(ppropInfo->bstrSyntax, &propInfo.bstrSyntax);
|
|
BAIL_ON_FAILURE(hr);
|
|
hr = ADsAllocString(ppropInfo->bstrOID, &propInfo.bstrOID);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
switch(ppropInfo->dwSyntaxId) {
|
|
case IIS_SYNTAX_ID_DWORD:
|
|
case IIS_SYNTAX_ID_BOOL:
|
|
case IIS_SYNTAX_ID_BOOL_BITMASK:
|
|
propInfo.dwDefault = ppropInfo->dwDefault;
|
|
break;
|
|
|
|
case IIS_SYNTAX_ID_STRING:
|
|
case IIS_SYNTAX_ID_EXPANDSZ:
|
|
if (ppropInfo->szDefault) {
|
|
propInfo.szDefault = AllocADsStr((LPWSTR)(ppropInfo->szDefault));
|
|
if (!propInfo.szDefault) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IIS_SYNTAX_ID_MIMEMAP:
|
|
case IIS_SYNTAX_ID_MULTISZ:
|
|
pszStr = ppropInfo->szDefault;
|
|
|
|
//
|
|
// calculate length
|
|
//
|
|
|
|
if (pszStr) {
|
|
DWORD dwLen = 0;
|
|
|
|
//
|
|
// if first char is a null char
|
|
//
|
|
|
|
if (*pszStr == L'\0') {
|
|
dwLen = 1;
|
|
pszStr++;
|
|
}
|
|
|
|
while (*pszStr != L'\0') {
|
|
while (*pszStr != L'\0') {
|
|
pszStr++;
|
|
dwLen++;
|
|
}
|
|
pszStr++;
|
|
dwLen++;
|
|
}
|
|
propInfo.szDefault = (LPWSTR)AllocADsMem((dwLen +1) * sizeof(WCHAR));
|
|
if (!propInfo.szDefault) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
memcpy(propInfo.szDefault, (LPWSTR)ppropInfo->szDefault,
|
|
(dwLen+1)*sizeof(WCHAR));
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
IISSchemaProperty::IISSchemaProperty(DWORD id, LPWSTR _name, int nameLen) {
|
|
memset(&propInfo, 0, sizeof(PROPERTYINFO));
|
|
name = new WCHAR[nameLen];
|
|
wcscpy(name, _name);
|
|
propID = id;
|
|
}
|
|
|
|
IISSchemaProperty::~IISSchemaProperty() {
|
|
delete[] name;
|
|
if (propInfo.szDefault) {
|
|
if (propInfo.dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) {
|
|
FreeADsMem(propInfo.szDefault);
|
|
}
|
|
else {
|
|
FreeADsStr(propInfo.szDefault);
|
|
}
|
|
}
|
|
}
|
|
|
|
HRESULT IIsSchemaClass::findContainedClassName(LPWSTR pszContainName) {
|
|
WCHAR szName[MAX_PATH];
|
|
LPWSTR ObjectList = (LPWSTR)classInfo.bstrContainment;
|
|
|
|
while ((ObjectList = grabProp(szName, ObjectList)) != NULL) {
|
|
if (*szName != L'\0') {
|
|
if (!_wcsicmp(szName, pszContainName)) {
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return E_ADS_SCHEMA_VIOLATION;
|
|
}
|
|
|
|
HRESULT IIsSchemaClass::SetclassInfo(PCLASSINFO pClassInfo) {
|
|
HRESULT hr = S_OK;
|
|
LPBYTE pBuffer = NULL;
|
|
DWORD dwSize;
|
|
|
|
if (classInfo.bstrContainment)
|
|
FreeADsMem(classInfo.bstrContainment);
|
|
if (classInfo.bstrOptionalProperties)
|
|
FreeADsMem(classInfo.bstrOptionalProperties);
|
|
if (classInfo.bstrMandatoryProperties)
|
|
FreeADsMem(classInfo.bstrMandatoryProperties);
|
|
|
|
memset(&classInfo, 0, sizeof(CLASSINFO));
|
|
|
|
if (pClassInfo) {
|
|
if (pClassInfo->bstrContainment) {
|
|
dwSize = ((DWORD)wcslen(pClassInfo->bstrContainment)+1)*sizeof(WCHAR);
|
|
pBuffer = (LPBYTE)AllocADsMem(dwSize);
|
|
if (!pBuffer) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
memcpy(pBuffer, pClassInfo->bstrContainment, dwSize);
|
|
classInfo.bstrContainment = (BSTR)pBuffer;
|
|
}
|
|
|
|
if (pClassInfo->bstrMandatoryProperties) {
|
|
dwSize = ((DWORD)wcslen(pClassInfo->bstrMandatoryProperties)+1)*sizeof(WCHAR);
|
|
pBuffer = (LPBYTE)AllocADsMem(dwSize);
|
|
if (!pBuffer) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
memcpy(pBuffer, pClassInfo->bstrMandatoryProperties, dwSize);
|
|
classInfo.bstrMandatoryProperties = (BSTR)pBuffer;
|
|
}
|
|
|
|
if (pClassInfo->bstrOptionalProperties) {
|
|
dwSize = ((DWORD)wcslen(pClassInfo->bstrOptionalProperties)+1)*sizeof(WCHAR);
|
|
pBuffer = (LPBYTE)AllocADsMem(dwSize);
|
|
if (!pBuffer) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
memcpy(pBuffer, pClassInfo->bstrOptionalProperties, dwSize);
|
|
classInfo.bstrOptionalProperties = (BSTR)pBuffer;
|
|
}
|
|
classInfo.fContainer = pClassInfo->fContainer;
|
|
}
|
|
|
|
error:
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT IIsSchemaClass::findProp(LPWSTR pszPropName) {
|
|
WCHAR szName[MAX_PATH];
|
|
LPWSTR ObjectList = (LPWSTR)classInfo.bstrOptionalProperties;
|
|
|
|
while ((ObjectList = grabProp(szName, ObjectList)) != NULL) {
|
|
if (*szName != L'\0') {
|
|
if (!_wcsicmp(szName, pszPropName)) {
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
ObjectList = (LPWSTR)classInfo.bstrMandatoryProperties;
|
|
|
|
while ((ObjectList = grabProp(szName, ObjectList)) != NULL) {
|
|
if (*szName != L'\0') {
|
|
if (!_wcsicmp(szName, pszPropName)) {
|
|
return S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
}
|
|
|
|
BOOL IISSchemaProperty::InitFromMetaData(METADATA_GETALL_RECORD *mdga, BYTE *data) {
|
|
PropValue pv;
|
|
|
|
WCHAR* pszSyntax = NULL;
|
|
|
|
if (mdga->dwMDDataType == BINARY_METADATA &&
|
|
mdga->dwMDDataLen >= sizeof(PropValue) - sizeof(LPWSTR))
|
|
{
|
|
memcpy(&pv, (data+mdga->dwMDDataOffset), sizeof(PropValue));
|
|
|
|
propInfo.dwMetaID = pv.dwMetaID;
|
|
propInfo.dwPropID = pv.dwPropID;
|
|
propInfo.dwSyntaxId = pv.dwSynID;
|
|
propInfo.lMaxRange = (long)pv.dwMaxRange;
|
|
propInfo.lMinRange = (long)pv.dwMinRange;
|
|
propInfo.dwFlags = pv.dwFlags;
|
|
propInfo.dwMask = pv.dwMask;
|
|
propInfo.dwMetaFlags = pv.dwMetaFlags;
|
|
propInfo.dwUserGroup = pv.dwUserGroup;
|
|
propInfo.fMultiValued = pv.fMultiValued;
|
|
|
|
pszSyntax = SyntaxIdToString(pv.dwSynID);
|
|
HRESULT hr = ADsAllocString(pszSyntax, &(propInfo.bstrSyntax));
|
|
if FAILED(hr)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL IISSchemaProperty::InitPropertyDefaults(METADATA_GETALL_RECORD *mdga, BYTE *data) {
|
|
|
|
WCHAR *ptr;
|
|
BYTE *bptr;
|
|
|
|
propInfo.dwDefault = 0;
|
|
propInfo.szDefault = NULL;
|
|
|
|
if (!(mdga && data)){
|
|
return TRUE;
|
|
}
|
|
|
|
switch(mdga->dwMDDataType) {
|
|
case DWORD_METADATA:
|
|
propInfo.dwDefault = *(DWORD *)(data+mdga->dwMDDataOffset);
|
|
break;
|
|
case STRING_METADATA:
|
|
case EXPANDSZ_METADATA:
|
|
propInfo.szDefault = AllocADsStr((LPWSTR)(data+mdga->dwMDDataOffset));
|
|
break;
|
|
case MULTISZ_METADATA:
|
|
ptr = (LPWSTR)(data+mdga->dwMDDataOffset);
|
|
propInfo.szDefault = (LPWSTR) AllocADsMem(mdga->dwMDDataLen);
|
|
memcpy(propInfo.szDefault, (LPWSTR)ptr, mdga->dwMDDataLen);
|
|
break;
|
|
|
|
case BINARY_METADATA:
|
|
if (mdga->dwMDDataLen > 0)
|
|
{
|
|
bptr = (BYTE*)(data+mdga->dwMDDataOffset);
|
|
propInfo.szDefault = (LPWSTR) AllocADsMem(mdga->dwMDDataLen);
|
|
memcpy(propInfo.szDefault, bptr, mdga->dwMDDataLen);
|
|
propInfo.dwBinDataLen = mdga->dwMDDataLen;
|
|
}
|
|
else
|
|
{
|
|
propInfo.dwBinDataLen = 0;
|
|
}
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
WCHAR *grabProp(WCHAR *out, WCHAR *in) {
|
|
if (!in || *in == L'\0') {
|
|
*out = L'\0';
|
|
return NULL;
|
|
}
|
|
while (*in != L',' && *in != L'\0') {
|
|
*out++ = *in++;
|
|
}
|
|
*out = L'\0';
|
|
if (*in == L',')
|
|
return ++in;
|
|
return in;
|
|
}
|
|
|
|
WCHAR *SyntaxIdToString(DWORD syntaxID) {
|
|
switch(syntaxID) {
|
|
case IIS_SYNTAX_ID_BOOL:
|
|
case IIS_SYNTAX_ID_BOOL_BITMASK:
|
|
return L"Boolean";
|
|
case IIS_SYNTAX_ID_DWORD:
|
|
return L"Integer";
|
|
case IIS_SYNTAX_ID_STRING:
|
|
return L"String";
|
|
case IIS_SYNTAX_ID_EXPANDSZ:
|
|
return L"ExpandSz";
|
|
case IIS_SYNTAX_ID_MIMEMAP:
|
|
return L"MimeMapList";
|
|
case IIS_SYNTAX_ID_MULTISZ:
|
|
return L"List";
|
|
case IIS_SYNTAX_ID_IPSECLIST:
|
|
return L"IPSec";
|
|
case IIS_SYNTAX_ID_NTACL:
|
|
return L"NTAcl";
|
|
case IIS_SYNTAX_ID_BINARY:
|
|
return L"Binary";
|
|
default:
|
|
return L"(ERROR -- UNDEFINED SYNTAX ID)";
|
|
}
|
|
}
|
|
|
|
BOOL DataForSyntaxID(PROPERTYINFO *pp, METADATA_RECORD *mdr) {
|
|
static DWORD value=0;
|
|
WCHAR *ptr;
|
|
|
|
switch(pp->dwSyntaxId) {
|
|
case IIS_SYNTAX_ID_BOOL:
|
|
case IIS_SYNTAX_ID_BOOL_BITMASK:
|
|
case IIS_SYNTAX_ID_DWORD:
|
|
mdr->dwMDDataType = DWORD_METADATA;
|
|
mdr->dwMDDataLen = sizeof(DWORD);
|
|
mdr->pbMDData = (unsigned char *)&(pp->dwDefault);
|
|
break;
|
|
case IIS_SYNTAX_ID_STRING:
|
|
mdr->dwMDDataType = STRING_METADATA;
|
|
if (pp->szDefault) {
|
|
mdr->dwMDDataLen = ((DWORD)wcslen(pp->szDefault)+1)*2;
|
|
}
|
|
else {
|
|
mdr->dwMDDataLen = 0;
|
|
}
|
|
mdr->pbMDData = (unsigned char *)pp->szDefault;
|
|
break;
|
|
case IIS_SYNTAX_ID_EXPANDSZ:
|
|
mdr->dwMDDataType = EXPANDSZ_METADATA;
|
|
if (pp->szDefault) {
|
|
mdr->dwMDDataLen = ((DWORD)wcslen(pp->szDefault)+1)*2;
|
|
}
|
|
else {
|
|
mdr->dwMDDataLen = 0;
|
|
}
|
|
mdr->pbMDData = (unsigned char *)pp->szDefault;
|
|
break;
|
|
case IIS_SYNTAX_ID_MIMEMAP:
|
|
case IIS_SYNTAX_ID_MULTISZ:
|
|
//
|
|
// Note, ALL multisz types must have an extra \0 in the table.
|
|
//
|
|
mdr->dwMDDataType = MULTISZ_METADATA;
|
|
if (pp->szDefault) {
|
|
ptr = pp->szDefault;
|
|
if (*ptr == L'\0') {
|
|
ptr++;
|
|
}
|
|
while (*ptr!=0) {
|
|
ptr += wcslen(ptr)+1;
|
|
}
|
|
mdr->dwMDDataLen = (DWORD)DIFF((char *)ptr - (char *)pp->szDefault)+2;
|
|
}
|
|
else {
|
|
mdr->dwMDDataLen = 0;
|
|
}
|
|
mdr->pbMDData = (unsigned char *)pp->szDefault;
|
|
break;
|
|
case IIS_SYNTAX_ID_IPSECLIST:
|
|
case IIS_SYNTAX_ID_NTACL:
|
|
case IIS_SYNTAX_ID_BINARY:
|
|
mdr->dwMDDataType = BINARY_METADATA;
|
|
mdr->dwMDDataLen = 0;
|
|
mdr->pbMDData = NULL;
|
|
break;
|
|
default:
|
|
mdr->dwMDDataType = DWORD_METADATA;
|
|
mdr->dwMDDataLen = sizeof(DWORD);
|
|
mdr->pbMDData = (unsigned char *)&value;
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD SyntaxToMetaID(DWORD syntaxID) {
|
|
switch(syntaxID) {
|
|
case IIS_SYNTAX_ID_BOOL:
|
|
case IIS_SYNTAX_ID_BOOL_BITMASK:
|
|
case IIS_SYNTAX_ID_DWORD:
|
|
return DWORD_METADATA;
|
|
|
|
case IIS_SYNTAX_ID_STRING:
|
|
return STRING_METADATA;
|
|
|
|
case IIS_SYNTAX_ID_EXPANDSZ:
|
|
return EXPANDSZ_METADATA;
|
|
|
|
case IIS_SYNTAX_ID_MIMEMAP:
|
|
case IIS_SYNTAX_ID_MULTISZ:
|
|
case IIS_SYNTAX_ID_HTTPERRORS:
|
|
case IIS_SYNTAX_ID_HTTPHEADERS:
|
|
return MULTISZ_METADATA;
|
|
|
|
case IIS_SYNTAX_ID_IPSECLIST:
|
|
case IIS_SYNTAX_ID_NTACL:
|
|
case IIS_SYNTAX_ID_BINARY:
|
|
return BINARY_METADATA;
|
|
|
|
default:
|
|
// printf("ERROR, Unknown Syntax Type %x", syntaxID);
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
MetaHandle::MetaHandle(IMSAdminBasePtr _pmb) : pmb(_pmb) {
|
|
if (pmb)
|
|
pmb->AddRef();
|
|
h = 0;
|
|
}
|
|
MetaHandle::~MetaHandle() {
|
|
if (pmb) {
|
|
if (h)
|
|
pmb->CloseKey(h);
|
|
pmb->Release();
|
|
}
|
|
}
|
|
|
|
HRESULT IIsSchema::IdToPropNameW(DWORD id, LPWSTR buf) {
|
|
IISSchemaProperty *prop = (IISSchemaProperty *)idToProp[id];
|
|
if (!prop)
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
wcscpy(buf, prop->getName());
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT IIsSchema::PropNameWToId(LPWSTR propNameW, DWORD *id) {
|
|
IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[propNameW];
|
|
if (!prop)
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
*id = prop->getPropID();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT IIsSchema::LookupFlagPropName(LPWSTR propNameW, LPWSTR FlagPropName) {
|
|
DWORD id;
|
|
IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[propNameW];
|
|
if (!prop)
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
id = prop->getMetaID();
|
|
return (ConvertID_To_PropName(id, FlagPropName));
|
|
}
|
|
|
|
HRESULT IIsSchema::LookupMetaID(LPWSTR propNameW, PDWORD pdwMetaId) {
|
|
IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[propNameW];
|
|
if (!prop)
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
*pdwMetaId = prop->getMetaID();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT IIsSchema::LookupPropID(LPWSTR propNameW, PDWORD pdwPropId) {
|
|
IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[propNameW];
|
|
if (!prop)
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
*pdwPropId = prop->getPropID();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT IIsSchema::PropNameWToIISSchemaProp(LPWSTR propNameW, IISSchemaProperty **prop) {
|
|
*prop = NULL;
|
|
*prop = (IISSchemaProperty *)nameToProp[propNameW];
|
|
if (!*prop)
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT IIsSchema::ValidatePropertyName( LPWSTR szPropName) {
|
|
DWORD propID;
|
|
HRESULT hr;
|
|
|
|
hr = PropNameWToId(szPropName, &propID);
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT IIsSchema::ValidateProperty(LPWSTR szClassName, LPWSTR szPropName) {
|
|
HRESULT hr;
|
|
IIsSchemaClass *sc;
|
|
|
|
sc = (IIsSchemaClass*)nameToClass[szClassName];
|
|
if (!sc)
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
hr = sc->findProp(szPropName);
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT IIsSchema::ValidateContainedClassName(LPWSTR szClassName, LPWSTR szContainName) {
|
|
HRESULT hr;
|
|
IIsSchemaClass *sc;
|
|
|
|
sc = (IIsSchemaClass *)nameToClass[szClassName];
|
|
if (!sc)
|
|
RRETURN(E_ADS_UNKNOWN_OBJECT);
|
|
hr = sc->findContainedClassName(szContainName);
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT
|
|
IIsSchema::GetDefaultProperty(
|
|
LPWSTR szPropName,
|
|
PDWORD pdwNumValues,
|
|
PDWORD pdwSyntax,
|
|
LPBYTE *pBuffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
LPBYTE *pBuffer - pBuffer is not allocated, it just holds the
|
|
address of the default value in the PROPINFO
|
|
structure
|
|
|
|
Return Value:
|
|
|
|
Notes:
|
|
|
|
Called by CPropertyCache::getproperty
|
|
|
|
Currently binary values are not supported correctly, we
|
|
may not ever support them.
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[szPropName];
|
|
|
|
if (!prop)
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
|
|
*pdwSyntax = prop->getSyntaxID();
|
|
|
|
switch(*pdwSyntax) {
|
|
case IIS_SYNTAX_ID_BOOL:
|
|
case IIS_SYNTAX_ID_BOOL_BITMASK:
|
|
case IIS_SYNTAX_ID_DWORD:
|
|
*pBuffer = (LPBYTE)prop->getdwDefaultAddr();
|
|
*pdwNumValues = 1;
|
|
break;
|
|
case IIS_SYNTAX_ID_BINARY:
|
|
case IIS_SYNTAX_ID_IPSECLIST:
|
|
case IIS_SYNTAX_ID_NTACL:
|
|
//
|
|
// We don't currently support setting or getting default values,
|
|
// so pBuffer should always be NULL. To support default values
|
|
// on binaries, we need to transmit the length in the PROPINFO
|
|
// structure.
|
|
//
|
|
*pBuffer = (LPBYTE)prop->getszDefault();
|
|
*pdwNumValues = (DWORD)prop->getdwBinDataLen();
|
|
break;
|
|
case IIS_SYNTAX_ID_MULTISZ:
|
|
{
|
|
*pBuffer = (LPBYTE)prop->getszDefault();
|
|
LPWSTR pszStr = (LPWSTR)*pBuffer;
|
|
|
|
if (*pszStr == 0) {
|
|
*pdwNumValues = 1;
|
|
}
|
|
else {
|
|
*pdwNumValues = 0;
|
|
}
|
|
|
|
while (*pszStr != L'\0') {
|
|
while (*pszStr != L'\0') {
|
|
pszStr++;
|
|
}
|
|
(*pdwNumValues)++;
|
|
pszStr++;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
*pBuffer = (LPBYTE)prop->getszDefault();
|
|
*pdwNumValues = 1;
|
|
break;
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT IIsSchema::PropNameWToSyntaxId(LPWSTR propNameW, DWORD *syntaxID) {
|
|
IISSchemaProperty *prop;
|
|
HRESULT hr;
|
|
|
|
hr = PropNameWToIISSchemaProp(propNameW, &prop);
|
|
BAIL_ON_FAILURE(hr);
|
|
*syntaxID = prop->getSyntaxID();
|
|
return S_OK;
|
|
error:
|
|
return E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
}
|
|
|
|
HRESULT IIsSchema::ValidateClassName(LPWSTR classNameW) {
|
|
if (nameToClass[classNameW])
|
|
RRETURN(ERROR_SUCCESS);
|
|
else
|
|
RRETURN(E_ADS_SCHEMA_VIOLATION);
|
|
}
|
|
|
|
|
|
HRESULT IIsSchema::ConvertID_To_PropName(
|
|
DWORD dwIdentifier,
|
|
LPWSTR pszPropertyName
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = IdToPropNameW(dwIdentifier, pszPropertyName);
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT IIsSchema::ConvertPropName_To_ID(
|
|
LPWSTR pszPropertyName,
|
|
PDWORD pdwIdentifier
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!pszPropertyName) {
|
|
hr = E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
hr = PropNameWToId(pszPropertyName, pdwIdentifier);
|
|
error:
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
HRESULT IIsSchema::LookupSyntaxID(
|
|
LPWSTR pszPropertyName,
|
|
PDWORD pdwSyntaxId
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!pszPropertyName) {
|
|
hr = E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
hr = PropNameWToSyntaxId(pszPropertyName, pdwSyntaxId);
|
|
error:
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
HRESULT IIsSchema::LookupMDFlags(
|
|
DWORD dwPropID,
|
|
PDWORD pdwAttribute,
|
|
PDWORD pdwUserType
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IISSchemaProperty *prop=(IISSchemaProperty *)idToProp[dwPropID];
|
|
if (prop) {
|
|
*pdwAttribute = prop->getMetaFlags();
|
|
*pdwUserType = prop->getUserGroup();
|
|
} else {
|
|
hr = E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
return S_OK;
|
|
error:
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT
|
|
IIsSchema::LookupBitMask(
|
|
LPWSTR pszPropertyName,
|
|
PDWORD pdwMaskBits
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IISSchemaProperty *prop=NULL;
|
|
|
|
hr = PropNameWToIISSchemaProp(pszPropertyName, &prop);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (prop) {
|
|
*pdwMaskBits = prop->getMask();
|
|
} else {
|
|
hr = E_ADS_PROPERTY_NOT_SUPPORTED;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
return S_OK;
|
|
error:
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT IIsSchema::LoadAllData(IMSAdminBasePtr &pmb,
|
|
MetaHandle &root,
|
|
WCHAR *subdir,
|
|
BYTE **buf,
|
|
DWORD *size,
|
|
DWORD *count) {
|
|
DWORD dataSet;
|
|
DWORD neededSize;
|
|
HRESULT hr;
|
|
//
|
|
// Try to get the property names.
|
|
//
|
|
hr = pmb->GetAllData(root,
|
|
subdir,
|
|
METADATA_NO_ATTRIBUTES,
|
|
ALL_METADATA,
|
|
ALL_METADATA,
|
|
count,
|
|
&dataSet,
|
|
*size,
|
|
*buf,
|
|
&neededSize);
|
|
if (!SUCCEEDED(hr)) {
|
|
DWORD code = ERROR_INSUFFICIENT_BUFFER;
|
|
if (hr == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER)) {
|
|
// printf("Names buf of %d not big enough. Need %d bytes\n",
|
|
// getAllBufSize,
|
|
// neededSize);
|
|
delete *buf;
|
|
*buf = 0;
|
|
*size = neededSize;
|
|
*buf = new BYTE[neededSize];
|
|
hr = pmb->GetAllData(root,
|
|
subdir,
|
|
METADATA_NO_ATTRIBUTES,
|
|
ALL_METADATA,
|
|
ALL_METADATA,
|
|
count,
|
|
&dataSet,
|
|
*size,
|
|
*buf,
|
|
&neededSize);
|
|
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// BUGBUG: Get rid of this constant ASAP!
|
|
// Sergeia: fix for bug 189797, buffer was too small
|
|
const DWORD getAllBufSize = 4096*2;
|
|
|
|
HRESULT IIsSchema::InitSchema(WCHAR *baseName, CCredentials& Credentials)
|
|
{
|
|
DWORD bufSize = getAllBufSize;
|
|
BYTE *buf = new BYTE[bufSize];
|
|
HRESULT hr;
|
|
COSERVERINFO csiName;
|
|
COSERVERINFO *pcsiParam = &csiName;
|
|
IClassFactory * pcsfFactory = NULL;
|
|
IMSAdminBase * pAdminBase = NULL;
|
|
IMSAdminBase * pAdminBaseT = NULL;
|
|
DWORD count=0, dataSet=0, neededSize=0;
|
|
METADATA_GETALL_RECORD *pmd;
|
|
DWORD propBufSize = 128;
|
|
DWORD i;
|
|
MetaHandle root(NULL);
|
|
LPWSTR pContainment = NULL;
|
|
LPWSTR pOptProp = NULL;
|
|
LPWSTR pMandProp = NULL;
|
|
DWORD dwData = 0;
|
|
CLASSINFO classInfo;
|
|
BOOL bMayBeIIS4 = FALSE;
|
|
LPWSTR pszUserName = NULL;
|
|
LPWSTR pszPassword = NULL;
|
|
|
|
hr = Credentials.GetUserName(&pszUserName);
|
|
if (FAILED(hr))
|
|
{
|
|
if (buf)
|
|
{
|
|
delete [] buf;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
hr = Credentials.GetPassword(&pszPassword);
|
|
if (FAILED(hr))
|
|
{
|
|
if (buf)
|
|
{
|
|
delete [] buf;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
CComAuthInfo localAuthInfo(baseName,
|
|
pszUserName,
|
|
pszPassword);
|
|
|
|
memset(pcsiParam, 0, sizeof(COSERVERINFO));
|
|
|
|
pcsiParam = localAuthInfo.CreateServerInfoStruct();
|
|
|
|
hr = CoGetClassObject(
|
|
CLSID_MSAdminBase,
|
|
CLSCTX_SERVER,
|
|
pcsiParam,
|
|
IID_IClassFactory,
|
|
(void**) &pcsfFactory
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = localAuthInfo.ApplyProxyBlanket(pcsfFactory);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pcsfFactory->CreateInstance(
|
|
NULL,
|
|
IID_IMSAdminBase,
|
|
(void **) &pAdminBase
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = localAuthInfo.ApplyProxyBlanket(pAdminBase);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
METADATA_HANDLE MDataHandle;
|
|
hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
|
|
L"/Schema/Properties/Defaults", // Present Only in IIS5
|
|
METADATA_PERMISSION_READ,
|
|
20,
|
|
&MDataHandle);
|
|
|
|
if (HRESULTTOWIN32(hr) == ERROR_PATH_NOT_FOUND)
|
|
{
|
|
bMayBeIIS4 = TRUE;
|
|
}
|
|
if (HRESULTTOWIN32(hr) == ERROR_SUCCESS)
|
|
{
|
|
pAdminBase->CloseKey(MDataHandle);
|
|
}
|
|
|
|
root.setpointer(pAdminBase);
|
|
hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
|
|
L"/Schema/Properties",
|
|
METADATA_PERMISSION_READ,
|
|
DEFAULT_TIMEOUT_VALUE,
|
|
root);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = LoadAllData(pAdminBase, root, L"Names", &buf, &bufSize, &count);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
// Now, here we've gotten the list of properties/names.
|
|
// Create IIsSchemaProperty objects for each. We then
|
|
// Add the object to the two maps. Later, we will load
|
|
// all of the "Properties/Values" properties, look up (by
|
|
// id) the object, and initialize the property value.
|
|
|
|
pmd = (METADATA_GETALL_RECORD *)buf;
|
|
for ( i=0;i < count; i++, pmd++)
|
|
{
|
|
|
|
if (pmd->dwMDDataType != STRING_METADATA)
|
|
{
|
|
continue;
|
|
}
|
|
LPWSTR name = (WCHAR *)(buf + pmd->dwMDDataOffset);
|
|
IISSchemaProperty *pProp = new IISSchemaProperty(
|
|
pmd->dwMDIdentifier,
|
|
name,
|
|
pmd->dwMDDataLen);
|
|
idToProp.Add(pmd->dwMDIdentifier, pProp);
|
|
nameToProp.Add(pProp->getName(), pProp);
|
|
}
|
|
|
|
if (!bMayBeIIS4)
|
|
{
|
|
|
|
hr = LoadAllData(pAdminBase, root, L"Types", &buf, &bufSize, &count);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
// Now, here we've gotten the list of properties/values.
|
|
// We then need to look up the properties by id (since that's
|
|
// what we have) and initialize the property type information.
|
|
|
|
for (i=0;i < count; i++)
|
|
{
|
|
pmd = ((METADATA_GETALL_RECORD*)buf) + i;
|
|
|
|
|
|
IISSchemaProperty *pProp = (IISSchemaProperty *)(idToProp[pmd->dwMDIdentifier]);
|
|
if (pProp == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
pProp->InitFromMetaData(pmd, buf);
|
|
}
|
|
}
|
|
|
|
else
|
|
{ // IIS4 Code
|
|
|
|
// since the binary data stored in metabase changed, read from the resources
|
|
for (i=0;i < g_cIISProperties; i++)
|
|
{
|
|
PROPERTYINFO * pPrpInfo = &g_aIISProperties[i];
|
|
|
|
IISSchemaProperty *pProp = (IISSchemaProperty *)(idToProp[pPrpInfo->dwPropID]);
|
|
if (pProp == NULL) {
|
|
continue;
|
|
}
|
|
|
|
memcpy(pProp->GetpropInfo(),pPrpInfo,sizeof(PROPERTYINFO));
|
|
}
|
|
}
|
|
|
|
if (!bMayBeIIS4)
|
|
{ // in IIS4 the defaults has been already loaded
|
|
|
|
hr = LoadAllData(pAdminBase, root, L"Defaults", &buf, &bufSize, &count);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
// Now, here we've gotten the list of properties/defaults.
|
|
// We then need to look up the properties by id (since that's
|
|
// what we have) and initialize the property type information.
|
|
|
|
for (i=0;i < count; i++)
|
|
{
|
|
pmd = ((METADATA_GETALL_RECORD*)buf) + i;
|
|
|
|
|
|
IISSchemaProperty *pProp = (IISSchemaProperty *)(idToProp[pmd->dwMDIdentifier]);
|
|
if (pProp == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
pProp->InitPropertyDefaults(pmd, buf);
|
|
}
|
|
}
|
|
|
|
root.close();
|
|
// Next, we need to initialize the class map.
|
|
WCHAR className[METADATA_MAX_NAME_LEN];
|
|
|
|
hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
|
|
L"/Schema/Classes",
|
|
METADATA_PERMISSION_READ,
|
|
DEFAULT_TIMEOUT_VALUE,
|
|
root);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
for (i=0; TRUE ; i++)
|
|
{
|
|
hr = pAdminBase->EnumKeys(root, L"", (LPWSTR)className, i);
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
hr = ERROR_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
IIsSchemaClass *psc = new IIsSchemaClass(className);
|
|
|
|
if (bMayBeIIS4)
|
|
{
|
|
DWORD i; // the scope saves us and this variable name
|
|
for (i=0;i<g_cIISClasses;i++)
|
|
{
|
|
if (!_wcsicmp(className, g_aIISClasses[i].bstrName))
|
|
{
|
|
if (g_aIISClasses[i].bstrContainment)
|
|
{
|
|
pContainment = (LPWSTR)AllocADsMem((lstrlenW(g_aIISClasses[i].bstrContainment)+1)*sizeof(WCHAR));
|
|
lstrcpyW(pContainment,g_aIISClasses[i].bstrContainment);
|
|
}
|
|
else
|
|
{
|
|
pContainment=NULL;
|
|
}
|
|
|
|
if (g_aIISClasses[i].bstrOptionalProperties)
|
|
{
|
|
pOptProp = (LPWSTR)AllocADsMem((lstrlenW(g_aIISClasses[i].bstrOptionalProperties)+1)*sizeof(WCHAR));
|
|
lstrcpyW(pOptProp,g_aIISClasses[i].bstrOptionalProperties);
|
|
}
|
|
else
|
|
{
|
|
pOptProp = NULL;
|
|
}
|
|
|
|
if (g_aIISClasses[i].bstrMandatoryProperties)
|
|
{
|
|
pMandProp = (LPWSTR)AllocADsMem((lstrlenW(g_aIISClasses[i].bstrMandatoryProperties)+1)*sizeof(WCHAR));
|
|
lstrcpyW(pMandProp,g_aIISClasses[i].bstrMandatoryProperties);
|
|
}
|
|
else
|
|
{
|
|
pMandProp = NULL;
|
|
}
|
|
dwData = g_aIISClasses[i].fContainer?TRUE:FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
{
|
|
|
|
//
|
|
// Load the Containment, Mandatory, Optional, and Container properties.
|
|
//
|
|
|
|
hr = MetaBaseGetStringData(pAdminBase,
|
|
root,
|
|
className,
|
|
MD_SCHEMA_CLASS_CONTAINMENT,
|
|
(LPBYTE*)&pContainment
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = MetaBaseGetStringData(pAdminBase,
|
|
root,
|
|
className,
|
|
MD_SCHEMA_CLASS_OPT_PROPERTIES,
|
|
(LPBYTE*)&pOptProp
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = MetaBaseGetStringData(pAdminBase,
|
|
root,
|
|
className,
|
|
MD_SCHEMA_CLASS_MAND_PROPERTIES,
|
|
(LPBYTE*)&pMandProp
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = MetaBaseGetDwordData(pAdminBase,
|
|
root,
|
|
className,
|
|
MD_SCHEMA_CLASS_CONTAINER,
|
|
&dwData
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}
|
|
|
|
classInfo.bstrContainment = pContainment;
|
|
classInfo.bstrOptionalProperties = pOptProp;
|
|
classInfo.bstrMandatoryProperties = pMandProp;
|
|
classInfo.fContainer = dwData ? TRUE : FALSE;
|
|
|
|
psc->SetclassInfo(&classInfo);
|
|
nameToClass.Add(psc->getName(), psc);
|
|
|
|
if (pContainment)
|
|
{
|
|
FreeADsMem(pContainment);
|
|
}
|
|
|
|
if (pOptProp)
|
|
{
|
|
FreeADsMem(pOptProp);
|
|
}
|
|
|
|
if (pMandProp)
|
|
{
|
|
FreeADsMem(pMandProp);
|
|
}
|
|
|
|
}
|
|
|
|
localAuthInfo.FreeServerInfoStruct(pcsiParam);
|
|
|
|
error:
|
|
|
|
if (pAdminBase)
|
|
{
|
|
pAdminBase->Release();
|
|
}
|
|
if (buf)
|
|
{
|
|
delete [] buf;
|
|
}
|
|
if (pcsfFactory)
|
|
{
|
|
pcsfFactory->Release();
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT IIsSchema::GetTotalEntries(PDWORD pdwEntries) {
|
|
*pdwEntries = nameToClass.GetEntries() + nameToProp.GetEntries();
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
DWORD IIsSchema::GetClassEntries() {
|
|
return nameToClass.GetEntries();
|
|
}
|
|
|
|
DWORD IIsSchema::GetPropEntries() {
|
|
return nameToProp.GetEntries();
|
|
}
|
|
|
|
LPWSTR IIsSchema::GetClassName(DWORD dwIndex) {
|
|
return nameToClass.GetEntryName(dwIndex);
|
|
}
|
|
|
|
LPWSTR IIsSchema::GetPropName(DWORD dwIndex) {
|
|
return nameToProp.GetEntryName(dwIndex);
|
|
}
|
|
|
|
HRESULT IIsSchema::RemoveEntry(BOOL bClass, LPWSTR pszName) {
|
|
|
|
DWORD i;
|
|
DWORD id = 0;
|
|
LPWSTR pszPropName;
|
|
LPWSTR pszClassName;
|
|
IISSchemaProperty *prop;
|
|
if (bClass)
|
|
{
|
|
// clear nameToClass entry using pszName
|
|
for ( i = 0; i < nameToClass.GetEntries(); i++ )
|
|
{
|
|
pszClassName = nameToClass.GetEntryName(i);
|
|
if (pszClassName != NULL && _wcsicmp( pszClassName, pszName) == 0 ) {
|
|
nameToClass.ClearEntry(i);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// clear nameToProp entry using pszName
|
|
for ( i = 0; i < nameToProp.GetEntries(); i++ )
|
|
{
|
|
pszPropName = nameToProp.GetEntryName(i);
|
|
if (pszPropName != NULL && _wcsicmp( pszPropName, pszName) == 0 ) {
|
|
prop = (IISSchemaProperty *)nameToProp[pszPropName];
|
|
|
|
if (!prop)
|
|
RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
|
|
|
|
id = prop->getPropID();
|
|
nameToProp.ClearEntry(i);
|
|
}
|
|
}
|
|
// clear idToProp entry using id
|
|
|
|
if (id != 0)
|
|
{
|
|
idToProp.ClearEntry(id);
|
|
}
|
|
}
|
|
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
PCLASSINFO IIsSchema::GetClassInfo(LPWSTR pszName) {
|
|
|
|
DWORD i;
|
|
LPWSTR pszClassName;
|
|
IIsSchemaClass *sc;
|
|
|
|
for ( i = 0; i < nameToClass.GetEntries(); i++ )
|
|
{
|
|
pszClassName = nameToClass.GetEntryName(i);
|
|
if (pszClassName != NULL && _wcsicmp( pszClassName, pszName) == 0 ) {
|
|
sc = (IIsSchemaClass *)nameToClass[pszClassName];
|
|
return sc != NULL ? sc->GetclassInfo() : NULL;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
PPROPERTYINFO IIsSchema::GetPropertyInfo(LPWSTR pszName) {
|
|
|
|
DWORD i;
|
|
LPWSTR pszPropName;
|
|
IISSchemaProperty *prop;
|
|
|
|
for ( i = 0; i < nameToProp.GetEntries(); i++ )
|
|
{
|
|
pszPropName = nameToProp.GetEntryName(i);
|
|
if (pszPropName != NULL && _wcsicmp( pszPropName, pszName) == 0 ) {
|
|
prop = (IISSchemaProperty *)nameToProp[pszPropName];
|
|
return prop->GetpropInfo();
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
HRESULT IIsSchema::SetClassInfo(LPWSTR pszName, PCLASSINFO pClassInfo) {
|
|
DWORD i;
|
|
LPWSTR pszClassName;
|
|
IIsSchemaClass *sc;
|
|
|
|
for ( i = 0; i < nameToClass.GetEntries(); i++ )
|
|
{
|
|
pszClassName = nameToClass.GetEntryName(i);
|
|
if (pszClassName != NULL && _wcsicmp( pszClassName, pszName) == 0 ) {
|
|
sc = (IIsSchemaClass *)nameToClass[pszClassName];
|
|
return sc != NULL ? sc->SetclassInfo(pClassInfo) : E_FAIL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// add to schema cache if doesn't exist
|
|
//
|
|
|
|
sc = new IIsSchemaClass(pszName);
|
|
sc->SetclassInfo(pClassInfo);
|
|
nameToClass.Add(sc->getName(), sc);
|
|
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
HRESULT IIsSchema::SetPropertyInfo(LPWSTR pszName, PPROPERTYINFO pPropInfo) {
|
|
DWORD i;
|
|
LPWSTR pszPropName;
|
|
IISSchemaProperty *prop;
|
|
|
|
for ( i = 0; i < nameToProp.GetEntries(); i++ )
|
|
{
|
|
pszPropName = nameToProp.GetEntryName(i);
|
|
if ( _wcsicmp( pszPropName, pszName) == 0 ) {
|
|
prop = (IISSchemaProperty *)nameToProp[pszPropName];
|
|
return prop != NULL ? prop->SetpropInfo(pPropInfo) : E_FAIL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// add to schema cache if doesn't exist
|
|
//
|
|
|
|
prop = new IISSchemaProperty(pPropInfo->dwPropID,
|
|
pszName,
|
|
(DWORD)wcslen(pszName)+1);
|
|
if (prop != NULL)
|
|
prop->SetpropInfo(pPropInfo);
|
|
else
|
|
return E_FAIL;
|
|
idToProp.Add(pPropInfo->dwPropID, prop);
|
|
nameToProp.Add(prop->getName(), prop);
|
|
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
|
|
|
|
IIsSchema::IIsSchema() {}
|
|
|
|
void InitPropValue(PropValue *pv, PROPERTYINFO *pi) {
|
|
pv->dwSynID = pi->dwSyntaxId;
|
|
pv->dwMetaID = pi->dwMetaID;
|
|
pv->dwPropID = pi->dwPropID;
|
|
pv->dwMaxRange = (DWORD)pi->lMaxRange;
|
|
pv->dwMinRange = (DWORD)pi->lMinRange;
|
|
|
|
switch(pi->dwSyntaxId) {
|
|
case IIS_SYNTAX_ID_DWORD:
|
|
case IIS_SYNTAX_ID_BOOL:
|
|
case IIS_SYNTAX_ID_BOOL_BITMASK:
|
|
pv->dwMetaType = DWORD_METADATA;
|
|
break;
|
|
case IIS_SYNTAX_ID_STRING:
|
|
pv->dwMetaType = STRING_METADATA;
|
|
break;
|
|
case IIS_SYNTAX_ID_EXPANDSZ:
|
|
pv->dwMetaType = EXPANDSZ_METADATA;
|
|
break;
|
|
case IIS_SYNTAX_ID_MIMEMAP:
|
|
case IIS_SYNTAX_ID_MULTISZ:
|
|
pv->dwMetaType = MULTISZ_METADATA;
|
|
break;
|
|
case IIS_SYNTAX_ID_NTACL:
|
|
case IIS_SYNTAX_ID_BINARY:
|
|
case IIS_SYNTAX_ID_IPSECLIST:
|
|
pv->dwMetaType = BINARY_METADATA;
|
|
break;
|
|
|
|
}
|
|
pv->dwFlags = pi->dwFlags;
|
|
pv->fMultiValued = pi->fMultiValued;
|
|
pv->dwMask = pi->dwMask;
|
|
pv->dwMetaFlags = pi->dwMetaFlags;
|
|
pv->dwUserGroup = pi->dwUserGroup;
|
|
}
|