1384 lines
29 KiB
C++
1384 lines
29 KiB
C++
#include "catalog.h"
|
|
#include "Catmeta.h"
|
|
#include "WriterGlobalHelper.h"
|
|
#include "Writer.h"
|
|
#include "WriterGlobals.h"
|
|
#include "MBPropertyWriter.h"
|
|
#include "MBCollectionWriter.h"
|
|
#include "mddefw.h"
|
|
#include "pudebug.h"
|
|
|
|
typedef CMBPropertyWriter* LP_CMBPropertyWriter;
|
|
|
|
#define IIS_SYNTAX_ID_DWORD 1
|
|
#define IIS_SYNTAX_ID_STRING 2
|
|
#define IIS_SYNTAX_ID_EXPANDSZ 3
|
|
#define IIS_SYNTAX_ID_MULTISZ 4
|
|
#define IIS_SYNTAX_ID_BINARY 5
|
|
#define IIS_SYNTAX_ID_BOOL 6
|
|
#define IIS_SYNTAX_ID_BOOL_BITMASK 7
|
|
#define IIS_SYNTAX_ID_MIMEMAP 8
|
|
#define IIS_SYNTAX_ID_IPSECLIST 9
|
|
#define IIS_SYNTAX_ID_NTACL 10
|
|
#define IIS_SYNTAX_ID_HTTPERRORS 11
|
|
#define IIS_SYNTAX_ID_HTTPHEADERS 12
|
|
|
|
#define cMaxFlag 32 // TODO: Check if max flag is ok.
|
|
|
|
static DWORD g_dwCatalogTypeFromSynID[]=
|
|
{
|
|
0, //invalid no equivalent in IISSynID.h
|
|
eCOLUMNMETA_DWORD_METADATA, //#define IIS_SYNTAX_ID_DWORD 1
|
|
eCOLUMNMETA_STRING_METADATA, //#define IIS_SYNTAX_ID_STRING 2
|
|
eCOLUMNMETA_EXPANDSZ_METADATA, //#define IIS_SYNTAX_ID_EXPANDSZ 3
|
|
eCOLUMNMETA_MULTISZ_METADATA, //#define IIS_SYNTAX_ID_MULTISZ 4
|
|
eCOLUMNMETA_BINARY_METADATA, //#define IIS_SYNTAX_ID_BINARY 5
|
|
eCOLUMNMETA_DWORD_METADATA, //#define IIS_SYNTAX_ID_BOOL 6
|
|
eCOLUMNMETA_DWORD_METADATA, //#define IIS_SYNTAX_ID_BOOL_BITMASK 7
|
|
eCOLUMNMETA_MULTISZ_METADATA, //#define IIS_SYNTAX_ID_MIMEMAP 8
|
|
eCOLUMNMETA_MULTISZ_METADATA, //#define IIS_SYNTAX_ID_IPSECLIST 9
|
|
eCOLUMNMETA_BINARY_METADATA, //#define IIS_SYNTAX_ID_NTACL 10
|
|
eCOLUMNMETA_MULTISZ_METADATA, //#define IIS_SYNTAX_ID_HTTPERRORS 11
|
|
eCOLUMNMETA_MULTISZ_METADATA, //#define IIS_SYNTAX_ID_HTTPHEADERS 12
|
|
0
|
|
};
|
|
|
|
static DWORD g_dwMetabaseTypeFromSynID[]=
|
|
{
|
|
0, //invalid no equivalent in IISSynID.h
|
|
DWORD_METADATA, //#define IIS_SYNTAX_ID_DWORD 1
|
|
STRING_METADATA, //#define IIS_SYNTAX_ID_STRING 2
|
|
EXPANDSZ_METADATA, //#define IIS_SYNTAX_ID_EXPANDSZ 3
|
|
MULTISZ_METADATA, //#define IIS_SYNTAX_ID_MULTISZ 4
|
|
BINARY_METADATA, //#define IIS_SYNTAX_ID_BINARY 5
|
|
DWORD_METADATA, //#define IIS_SYNTAX_ID_BOOL 6
|
|
DWORD_METADATA, //#define IIS_SYNTAX_ID_BOOL_BITMASK 7
|
|
MULTISZ_METADATA, //#define IIS_SYNTAX_ID_MIMEMAP 8
|
|
MULTISZ_METADATA, //#define IIS_SYNTAX_ID_IPSECLIST 9
|
|
BINARY_METADATA, //#define IIS_SYNTAX_ID_NTACL 10
|
|
MULTISZ_METADATA, //#define IIS_SYNTAX_ID_HTTPERRORS 11
|
|
MULTISZ_METADATA, //#define IIS_SYNTAX_ID_HTTPHEADERS 12
|
|
0
|
|
};
|
|
|
|
static DWORD g_dwCatalogTypeFromMetaType[]=
|
|
{
|
|
0, //invalid no equivalent for metatype
|
|
eCOLUMNMETA_DWORD_METADATA, //#define DWORD_METADATA 1
|
|
eCOLUMNMETA_STRING_METADATA, //#define STRING_METADATA 2
|
|
eCOLUMNMETA_BINARY_METADATA, //#define BINARY_METADATA 3
|
|
eCOLUMNMETA_EXPANDSZ_METADATA, //#define EXPANDSZ_METADATA 4
|
|
eCOLUMNMETA_MULTISZ_METADATA, //#define MULTISZ_METADATA 5
|
|
0
|
|
};
|
|
|
|
//
|
|
// TODO: Delete after getting from schema
|
|
//
|
|
|
|
LPWSTR g_wszDWORD = L"DWORD";
|
|
LPWSTR g_wszBINARY = L"BINARY";
|
|
LPWSTR g_wszSTRING = L"STRING";
|
|
LPWSTR g_wszGUID = L"GUID";
|
|
LPWSTR g_wszDBTIMESTAMP = L"DBTIMESTAMP";
|
|
|
|
LPWSTR g_wszUNKNOWN_UserType = L"UNKNOWN_UserType";
|
|
LPWSTR g_wszIIS_MD_UT_SERVER = L"IIS_MD_UT_SERVER";
|
|
LPWSTR g_wszIIS_MD_UT_FILE = L"IIS_MD_UT_FILE";
|
|
LPWSTR g_wszIIS_MD_UT_WAM = L"IIS_MD_UT_WAM";
|
|
LPWSTR g_wszASP_MD_UT_APP = L"ASP_MD_UT_APP";
|
|
|
|
HRESULT GetType(DWORD i_dwType,
|
|
LPWSTR* o_pwszType)
|
|
{
|
|
switch(i_dwType)
|
|
{
|
|
case 19:
|
|
*o_pwszType = g_wszDWORD;
|
|
break;
|
|
case 128:
|
|
*o_pwszType = g_wszBINARY;
|
|
break;
|
|
case 130:
|
|
*o_pwszType = g_wszSTRING;
|
|
break;
|
|
case 72:
|
|
*o_pwszType = g_wszGUID;
|
|
break;
|
|
case 135:
|
|
*o_pwszType = g_wszDBTIMESTAMP;
|
|
break;
|
|
default:
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT GetTypefromSynID(DWORD i_dwSynID,
|
|
LPWSTR* o_pwszType)
|
|
{
|
|
if((i_dwSynID < 1) || (i_dwSynID > 12))
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
else
|
|
{
|
|
*o_pwszType = (LPWSTR)g_aSynIDToWszType[i_dwSynID];
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Constructor for CMBPropertyWriter
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
CMBPropertyWriter::CMBPropertyWriter():
|
|
m_pCWriter(NULL),
|
|
m_wszName(NULL),
|
|
m_pType(NULL),
|
|
m_dwID(0),
|
|
m_bDefault(NULL),
|
|
m_cbDefault(0),
|
|
m_apFlag(NULL),
|
|
m_cFlag(0),
|
|
m_iFlag(0),
|
|
m_IsProperty(TRUE),
|
|
m_bMandatory(FALSE),
|
|
m_pCollection(NULL)
|
|
{
|
|
|
|
} // CMBPropertyWriter::CMBPropertyWriter
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Destructor for CMBPropertyWriter
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
CMBPropertyWriter::~CMBPropertyWriter()
|
|
{
|
|
if(NULL != m_apFlag)
|
|
{
|
|
for(ULONG i=0; i<m_iFlag; i++)
|
|
{
|
|
if(NULL != m_apFlag[i])
|
|
{
|
|
m_apFlag[i] = NULL; // No need to delete because you had simply saved the pointer.
|
|
}
|
|
}
|
|
|
|
delete [] m_apFlag;
|
|
m_apFlag = NULL;
|
|
}
|
|
|
|
m_cFlag = 0;
|
|
m_iFlag = 0;
|
|
|
|
} // CMBPropertyWriter::CMBPropertyWriter
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Initialize property writer.
|
|
|
|
Arguments:
|
|
|
|
[in] Property ID
|
|
[in] Bool indicating manditory property or optional.
|
|
[in] Pointer to the Collection writer object to which it belongs.
|
|
Assuming that the collection writer is valid for the lifetime
|
|
of this property writer.
|
|
[in] Pointer to the writer object. Assuming that the writer is valid for
|
|
the lifetime of this property writer.
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
void CMBPropertyWriter::Initialize(DWORD i_dwID,
|
|
BOOL i_bMandatory,
|
|
CMBCollectionWriter* i_pCollection,
|
|
CWriter* i_pcWriter)
|
|
{
|
|
//
|
|
// Assumption: i_pcWriter will be valid for the
|
|
// lifetime of the schema writer object.
|
|
//
|
|
m_pCWriter = i_pcWriter;
|
|
m_dwID = i_dwID;
|
|
m_bMandatory = i_bMandatory;
|
|
//
|
|
// Assumption: i_pCollection will be valid for the
|
|
// lifetime of the property writer object.
|
|
//
|
|
m_pCollection = i_pCollection;
|
|
|
|
return;
|
|
|
|
} // CMBPropertyWriter::Initialize
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Initialize property's name.
|
|
|
|
Arguments:
|
|
|
|
[in] Property Name
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::AddNameToProperty(LPCWSTR i_wszName)
|
|
{
|
|
//
|
|
// We have to make a copy of the name because
|
|
//
|
|
|
|
m_wszName = i_wszName;
|
|
|
|
return S_OK;
|
|
|
|
} // CMBPropertyWriter::Initialize
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Initialize property type.
|
|
|
|
Arguments:
|
|
|
|
[in] PropValue structure that has metabase type information.
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::AddTypeToProperty(PropValue* i_pType)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// First save the type, then if the meta/prop ids differ, mark the
|
|
// object as a flag and add it to its property.
|
|
//
|
|
|
|
m_pType = i_pType;
|
|
|
|
//
|
|
// A lot of tests dont really ensure that PropID == MetaID.
|
|
// They just set PropID to zero. We must not interpret this as a flag
|
|
//
|
|
|
|
if((0 != i_pType->dwPropID) && (i_pType->dwMetaID != i_pType->dwPropID))
|
|
{
|
|
//
|
|
// This is a flag. Add it as a flag to its property
|
|
//
|
|
|
|
//
|
|
// TODO: Assert that the ID of this object is the same as the propID.
|
|
//
|
|
|
|
CMBPropertyWriter* pPropertyWriter = NULL;
|
|
|
|
DBGINFOW((DBG_CONTEXT,
|
|
L"[AddTypeToProperty] Saving a non-shipped flag. Adding tag ID %d to its property ID %d\n",
|
|
i_pType->dwPropID,
|
|
i_pType->dwMetaID));
|
|
|
|
hr = m_pCollection->GetMBPropertyWriter(i_pType->dwMetaID,
|
|
&pPropertyWriter);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = pPropertyWriter->AddFlagToProperty(this);
|
|
|
|
m_IsProperty = FALSE;
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
} // CMBPropertyWriter::Initialize
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Initialize property defaults.
|
|
|
|
Arguments:
|
|
|
|
[in] Default value
|
|
[in] Count of bytes for default value.
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::AddDefaultToProperty(BYTE* i_bDefault,
|
|
ULONG i_cbDefault)
|
|
{
|
|
m_bDefault = i_bDefault;
|
|
m_cbDefault = i_cbDefault;
|
|
|
|
return S_OK;
|
|
|
|
} // CMBPropertyWriter::Initialize
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Save property's flag. Note that flag objects are also the same data
|
|
structure as property objects i.e. CMBPropertyWriter
|
|
|
|
Arguments:
|
|
|
|
[in] Flag object
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::AddFlagToProperty(CMBPropertyWriter* i_pFlag)
|
|
{
|
|
//
|
|
// ASSUMPTION: A meta ID will have only one occurance of a Prop ID. i.e. flag
|
|
//
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_iFlag == m_cFlag)
|
|
{
|
|
hr = ReAllocate();
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
m_apFlag[m_iFlag++] = i_pFlag;
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Helper function to grow the buffer that holds the flag objects
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::ReAllocate()
|
|
{
|
|
CMBPropertyWriter** pSav = NULL;
|
|
|
|
pSav = new LP_CMBPropertyWriter[m_cFlag + cMaxFlag];
|
|
if(NULL == pSav)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
memset(pSav, 0, (sizeof(LP_CMBPropertyWriter))*(m_cFlag + cMaxFlag));
|
|
|
|
if(NULL != m_apFlag)
|
|
{
|
|
memcpy(pSav, m_apFlag, (sizeof(LP_CMBPropertyWriter))*(m_cFlag));
|
|
delete [] m_apFlag;
|
|
m_apFlag = NULL;
|
|
}
|
|
|
|
m_apFlag = pSav;
|
|
m_cFlag = m_cFlag + cMaxFlag;
|
|
|
|
return S_OK;
|
|
|
|
} // CMBPropertyWriter::ReAllocate
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Function that writes the property.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::WriteProperty()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(!m_IsProperty)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
if(0 == _wcsicmp(m_pCollection->Name(), wszTABLE_IIsConfigObject))
|
|
{
|
|
hr = WritePropertyLong();
|
|
}
|
|
else
|
|
{
|
|
hr = WritePropertyShort();
|
|
}
|
|
|
|
return hr;
|
|
|
|
} // CMBPropertyWriter::WriteProperty
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Helper function to determine if the property is a bool.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
BOOL CMBPropertyWriter::IsPropertyFlag(BOOL i_bLog)
|
|
{
|
|
if(NULL != m_apFlag)
|
|
{
|
|
DBGINFOW((DBG_CONTEXT,
|
|
L"[IsPropertyFlag] PropertyID %d. Type: %d.\n",
|
|
m_dwID,
|
|
m_pType));
|
|
|
|
DBGINFOW((DBG_CONTEXT,
|
|
L"[IsPropertyFlag] PropertyID %d. SynID: %d.\n",
|
|
m_dwID,
|
|
m_pType->dwSynID));
|
|
|
|
if(eCOLUMNMETA_DWORD_METADATA == g_dwCatalogTypeFromSynID[m_pType->dwSynID])
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
if(i_bLog)
|
|
{
|
|
DBGINFOW((DBG_CONTEXT,
|
|
L"[IsPropertyFlag] PropertyID %d is not a DWORD. Ignoring flags for this property.\n",m_dwID));
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
} // CMBPropertyWriter::IsPropertyFlag
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Function that writes the property (long form) i.e. property that belongs
|
|
to the global IIsConfigObject collection.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::WritePropertyLong()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = BeginWritePropertyLong();
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
if(HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE) == hr)
|
|
{
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
if(IsPropertyFlag(FALSE))
|
|
{
|
|
for(ULONG i=0; i<m_iFlag; i++)
|
|
{
|
|
hr = WriteFlag(i);
|
|
// hr = m_aFlag[i]->WriteFlag;
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = EndWritePropertyLong();
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
return hr;
|
|
|
|
} // CMBPropertyWriter::WritePropertyLong
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Function that writes the property (short form) i.e. property that belongs
|
|
to a non-IIsConfigObject collection.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::WritePropertyShort()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
static WCHAR wchSeparator = L',';
|
|
WCHAR* wszEndName = NULL;
|
|
WCHAR* wszName = NULL;
|
|
WCHAR wszUnknownName[25];
|
|
size_t cchPropertyName = 0;
|
|
DWORD dwMetaFlagsEx = fCOLUMNMETA_MANDATORY;
|
|
DWORD iColMetaFlagsEx = iCOLUMNMETA_SchemaGeneratorFlags;
|
|
WCHAR* wszMetaFlagsEx = NULL;
|
|
|
|
if(NULL == m_wszName)
|
|
{
|
|
|
|
CreateUnknownName(wszUnknownName,
|
|
m_dwID);
|
|
wszName = wszUnknownName;
|
|
cchPropertyName = wcslen(wszName);
|
|
}
|
|
else
|
|
{
|
|
wszName = (LPWSTR)m_wszName;
|
|
wszEndName = wcschr(m_wszName, wchSeparator);
|
|
if(NULL == wszEndName)
|
|
{
|
|
cchPropertyName = wcslen(m_wszName);
|
|
}
|
|
else
|
|
{
|
|
cchPropertyName = wszEndName-m_wszName; // No need to divide by WCHAR because both are WCHAR pointers
|
|
}
|
|
}
|
|
|
|
if(m_bMandatory)
|
|
{
|
|
hr = m_pCWriter->m_pCWriterGlobalHelper->FlagToString(dwMetaFlagsEx,
|
|
&wszMetaFlagsEx,
|
|
wszTABLE_COLUMNMETA,
|
|
iColMetaFlagsEx);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszBeginPropertyShort,
|
|
g_cchBeginPropertyShort);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszName,
|
|
cchPropertyName);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
if(m_bMandatory)
|
|
{
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropMetaFlagsExEq,
|
|
g_cchPropMetaFlagsExEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszOr,
|
|
g_cchOr);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszMetaFlagsEx,
|
|
wcslen(wszMetaFlagsEx));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszEndPropertyShort,
|
|
g_cchEndPropertyShort);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
|
|
if(NULL != wszMetaFlagsEx)
|
|
{
|
|
delete [] wszMetaFlagsEx;
|
|
wszMetaFlagsEx = NULL;
|
|
}
|
|
|
|
return hr;
|
|
|
|
} // CMBPropertyWriter::WritePropertyShort
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Function that writes the property (long form) i.e. property that belongs
|
|
to a IIsConfigObject collection.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::BeginWritePropertyLong()
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
WCHAR* wszEndName = NULL;
|
|
static WCHAR wchSeparator = L',';
|
|
WCHAR* wszName = NULL;
|
|
WCHAR wszUnknownName[40];
|
|
size_t cchPropertyName = 0;
|
|
WCHAR wszID[11];
|
|
WCHAR* wszType = NULL;
|
|
DWORD iColType = iCOLUMNMETA_Type;
|
|
WCHAR* wszUserType = NULL;
|
|
ULONG cchUserType = 0;
|
|
BOOL bAllocedUserType = FALSE;
|
|
WCHAR* wszAttribute = NULL;
|
|
DWORD iColAttribute = iCOLUMNMETA_Attributes;
|
|
WCHAR* wszMetaFlags = NULL;
|
|
WCHAR* wszMetaFlagsEx = NULL;
|
|
WCHAR* wszDefault = NULL;
|
|
WCHAR wszMinValue[40];
|
|
WCHAR wszMaxValue[40];
|
|
|
|
//
|
|
// Compute the individual strings and lengths.
|
|
//
|
|
|
|
//
|
|
// Name
|
|
//
|
|
|
|
if(NULL == m_wszName)
|
|
{
|
|
|
|
CreateUnknownName(wszUnknownName,
|
|
m_dwID);
|
|
wszName = wszUnknownName;
|
|
cchPropertyName = wcslen(wszName);
|
|
}
|
|
else
|
|
{
|
|
wszName = (LPWSTR)m_wszName;
|
|
wszEndName = wcschr(m_wszName, wchSeparator);
|
|
if(NULL == wszEndName)
|
|
{
|
|
cchPropertyName = wcslen(m_wszName);
|
|
}
|
|
else
|
|
{
|
|
cchPropertyName = wszEndName-m_wszName; // // No need to divide by WCHAR because both are WCHAR pointers
|
|
}
|
|
}
|
|
|
|
//
|
|
// ID
|
|
//
|
|
|
|
wszID[0] = 0;
|
|
_ultow(m_dwID, wszID, 10);
|
|
|
|
//
|
|
// Type
|
|
//
|
|
|
|
if(NULL == m_pType)
|
|
{
|
|
//
|
|
// TODO: Log the fact that you found a property with no type and move on to the next property
|
|
//
|
|
DBGINFOW((DBG_CONTEXT,
|
|
L"[BeginWritePropertyLong] Type not found for PropertyID %d.\n",
|
|
m_dwID));
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE);
|
|
goto exit;
|
|
}
|
|
|
|
hr = GetTypefromSynID(m_pType->dwSynID,
|
|
&wszType);
|
|
|
|
/*
|
|
|
|
TODO: Get from schema
|
|
|
|
hr = m_pCWriter->m_pCWriterGlobalHelper->FlagToString(g_dwCatalogTypeFromSynID[m_pType->dwSynID],
|
|
&wszType,
|
|
wszTABLE_COLUMNMETA,
|
|
iColType);
|
|
*/
|
|
if(FAILED(hr) || (NULL == wszType))
|
|
{
|
|
DBGINFOW((DBG_CONTEXT,
|
|
L"[GetType] PropertyID %d, type: %d from synid %d is invalid.\n",
|
|
m_dwID,
|
|
g_dwCatalogTypeFromSynID[m_pType->dwSynID],
|
|
m_pType->dwSynID));
|
|
goto exit;
|
|
}
|
|
|
|
if(g_dwCatalogTypeFromSynID[m_pType->dwSynID] != g_dwCatalogTypeFromMetaType[m_pType->dwMetaType])
|
|
{
|
|
//
|
|
// TODO: Log a warning.
|
|
//
|
|
}
|
|
|
|
//
|
|
// UserType
|
|
//
|
|
|
|
hr = m_pCWriter->m_pCWriterGlobalHelper->GetUserType(m_pType->dwUserGroup,
|
|
&wszUserType,
|
|
&cchUserType,
|
|
&bAllocedUserType);
|
|
if(FAILED(hr))
|
|
{
|
|
DBGINFOW((DBG_CONTEXT,
|
|
L"[GetUserType] PropertyID %d, usertype: %d is invalid.\n",m_dwID, m_pType->dwUserGroup));
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Attribute
|
|
// TODO: Check if value stored in metabase is the same as catalog.
|
|
//
|
|
|
|
hr = m_pCWriter->m_pCWriterGlobalHelper->FlagToString(m_pType->dwMetaFlags,
|
|
&wszAttribute,
|
|
wszTABLE_COLUMNMETA,
|
|
iColAttribute);
|
|
|
|
if(FAILED(hr) || (NULL == wszAttribute))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Since this object is used only to write MBSchemaExt.XML, we are not
|
|
// writing the MetaFlags tag, because it will be derived on a compile.
|
|
// And besides, we do not have this info in the metabase - this tag
|
|
// contains catalog related data
|
|
//
|
|
|
|
//
|
|
// MetaFlagsEx (only the relavant ones - CACHE_PROPERTY_MODIFIED, CACHE_PROPERTY_CLEARED, EXTENDEDTYPE0-3)
|
|
//
|
|
|
|
hr = GetMetaFlagsExTag(&wszMetaFlagsEx);
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// DefaultValue
|
|
//
|
|
|
|
if(NULL != m_bDefault && m_cbDefault != 0)
|
|
{
|
|
hr = m_pCWriter->m_pCWriterGlobalHelper->ToString(m_bDefault,
|
|
m_cbDefault,
|
|
m_dwID,
|
|
g_dwMetabaseTypeFromSynID[m_pType->dwSynID],
|
|
METADATA_NO_ATTRIBUTES, // Do not check for attributes while applying defaults
|
|
&wszDefault);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
wszMinValue[0] = 0;
|
|
wszMaxValue[0] = 0;
|
|
|
|
if(DWORD_METADATA == g_dwMetabaseTypeFromSynID[m_pType->dwSynID])
|
|
{
|
|
//
|
|
// Set min/max values only for DWORD types
|
|
//
|
|
|
|
//
|
|
// TODO: Get the catalog's default for min/max from schema/ header file
|
|
//
|
|
|
|
if(0 != m_pType->dwMinRange)
|
|
{
|
|
_ultow(m_pType->dwMinRange, wszMinValue, 10);
|
|
}
|
|
|
|
if(-1 != m_pType->dwMaxRange)
|
|
{
|
|
_ultow(m_pType->dwMaxRange, wszMaxValue, 10);
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Write the values into the file.
|
|
//
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszBeginPropertyLong,
|
|
g_cchBeginPropertyLong);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszName,
|
|
cchPropertyName);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropIDEq,
|
|
g_cchPropIDEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszID,
|
|
wcslen(wszID));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropTypeEq,
|
|
g_cchPropTypeEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszType,
|
|
wcslen(wszType));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropUserTypeEq,
|
|
g_cchPropUserTypeEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszUserType,
|
|
cchUserType);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropAttributeEq,
|
|
g_cchPropAttributeEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszAttribute,
|
|
wcslen(wszAttribute));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
if(NULL != wszMetaFlags)
|
|
{
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropMetaFlagsEq,
|
|
g_cchPropMetaFlagsEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszMetaFlags,
|
|
wcslen(wszMetaFlags));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
if(NULL != wszMetaFlagsEx)
|
|
{
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropMetaFlagsExEq,
|
|
g_cchPropMetaFlagsExEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszMetaFlagsEx,
|
|
wcslen(wszMetaFlagsEx));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
|
|
}
|
|
if(NULL != wszDefault)
|
|
{
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropDefaultEq,
|
|
g_cchPropDefaultEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszDefault,
|
|
wcslen(wszDefault));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
if(0 != *wszMinValue)
|
|
{
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropMinValueEq,
|
|
g_cchPropMinValueEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszMinValue,
|
|
wcslen(wszMinValue));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
if(0 != *wszMaxValue)
|
|
{
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszPropMaxValueEq,
|
|
g_cchPropMaxValueEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszMaxValue,
|
|
wcslen(wszMaxValue));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
if(IsPropertyFlag(FALSE))
|
|
{
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszEndPropertyLongBeforeFlag,
|
|
g_cchEndPropertyLongBeforeFlag);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
|
|
exit:
|
|
|
|
/*
|
|
if(NULL != wszType)
|
|
{
|
|
delete [] wszType;
|
|
wszType = NULL;
|
|
}
|
|
*/
|
|
|
|
if((NULL != wszUserType) && bAllocedUserType)
|
|
{
|
|
delete [] wszUserType;
|
|
wszUserType = NULL;
|
|
}
|
|
if(NULL != wszAttribute)
|
|
{
|
|
delete [] wszAttribute;
|
|
wszAttribute = NULL;
|
|
}
|
|
|
|
if(NULL != wszMetaFlags)
|
|
{
|
|
delete [] wszMetaFlags;
|
|
wszMetaFlags = NULL;
|
|
}
|
|
|
|
if(NULL != wszMetaFlagsEx)
|
|
{
|
|
delete [] wszMetaFlagsEx;
|
|
wszMetaFlagsEx = NULL;
|
|
}
|
|
|
|
if(NULL != wszDefault)
|
|
{
|
|
delete [] wszDefault;
|
|
wszDefault = NULL;
|
|
}
|
|
|
|
return hr;
|
|
|
|
} // CMBPropertyWriter::BeginWritePropertyLong
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Function that writes the property (long form) i.e. property that belongs
|
|
to a IIsConfigObject collection.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::EndWritePropertyLong()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WCHAR* wszEndProperty = NULL;
|
|
|
|
if(IsPropertyFlag(FALSE))
|
|
{
|
|
wszEndProperty = (LPWSTR)g_wszEndPropertyLongAfterFlag;
|
|
}
|
|
else
|
|
{
|
|
wszEndProperty = (LPWSTR)g_wszEndPropertyShort;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszEndProperty,
|
|
wcslen(wszEndProperty));
|
|
return hr;
|
|
|
|
} // CMBPropertyWriter::EndWriterPropertyLong
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Function that writes a flag of the property
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::WriteFlag(ULONG i_iFlag)
|
|
{
|
|
CMBPropertyWriter* pFlag = m_apFlag[i_iFlag];
|
|
HRESULT hr = S_OK;
|
|
WCHAR wszValue[40];
|
|
WCHAR wszID[40];
|
|
WCHAR wszUnknownName[40];
|
|
ULONG cchFlagName = 0;
|
|
WCHAR* wszFlagName = NULL;
|
|
|
|
if(NULL != pFlag->Name())
|
|
{
|
|
wszFlagName = (LPWSTR)pFlag->Name();
|
|
}
|
|
else
|
|
{
|
|
CreateUnknownName(wszUnknownName,
|
|
pFlag->ID());
|
|
wszFlagName = wszUnknownName;
|
|
}
|
|
cchFlagName = wcslen(wszFlagName);
|
|
|
|
wszValue[0] = 0;
|
|
_ultow(pFlag->FlagValue(), wszValue, 10);
|
|
|
|
wszID[0] = 0;
|
|
_ultow(pFlag->ID(), wszID, 10);
|
|
|
|
//
|
|
// Write values to the flag
|
|
//
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszBeginFlag,
|
|
g_cchBeginFlag);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszFlagName,
|
|
cchFlagName);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszFlagValueEq,
|
|
g_cchFlagValueEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszValue,
|
|
wcslen(wszValue));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszFlagIDEq,
|
|
g_cchFlagIDEq);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)wszID,
|
|
wcslen(wszID));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = m_pCWriter->WriteToFile((LPVOID)g_wszEndFlag,
|
|
g_cchEndFlag);
|
|
|
|
return hr;
|
|
|
|
} // CMBPropertyWriter::WriteFlag
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Helper funciton that creates an unknown name
|
|
TODO: Should we make this a standalone function since it is also used in
|
|
locationWriter?
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
void CMBPropertyWriter::CreateUnknownName(LPWSTR io_wszUnknownName,
|
|
DWORD i_dwID)
|
|
{
|
|
WCHAR wszID[40];
|
|
wcscpy(io_wszUnknownName, L"UnknownName_");
|
|
|
|
_ultow(m_dwID, wszID, 10);
|
|
wcscat(io_wszUnknownName, wszID);
|
|
|
|
return;
|
|
|
|
} // CMBPropertyWriter::CreateUnknownName
|
|
|
|
|
|
/***************************************************************************++
|
|
Routine Description:
|
|
|
|
Helper funciton that creates metaflagsex tag
|
|
|
|
Arguments:
|
|
|
|
[out] String form of metaflags ex
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--***************************************************************************/
|
|
HRESULT CMBPropertyWriter::GetMetaFlagsExTag(LPWSTR* o_pwszMetaFlagsEx)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwMetaFlagsEx = 0;
|
|
DWORD iColMetaFlagsEx = iCOLUMNMETA_SchemaGeneratorFlags;
|
|
DWORD dwSynIDAsMetaFlagsEx = 0;
|
|
|
|
//
|
|
// TODO: Check if IIS_SYNTAX_ID_BOOL_BITMASK is bool.
|
|
//
|
|
|
|
if(1 == m_pType->dwFlags)
|
|
{
|
|
dwMetaFlagsEx = dwMetaFlagsEx | fCOLUMNMETA_CACHE_PROPERTY_MODIFIED;
|
|
}
|
|
else if (2 == m_pType->dwFlags)
|
|
{
|
|
dwMetaFlagsEx = dwMetaFlagsEx | fCOLUMNMETA_CACHE_PROPERTY_CLEARED;
|
|
}
|
|
|
|
if(0 != dwMetaFlagsEx)
|
|
{
|
|
hr = m_pCWriter->m_pCWriterGlobalHelper->FlagToString(dwMetaFlagsEx,
|
|
o_pwszMetaFlagsEx,
|
|
wszTABLE_COLUMNMETA,
|
|
iColMetaFlagsEx);
|
|
}
|
|
else
|
|
{
|
|
*o_pwszMetaFlagsEx = NULL;
|
|
}
|
|
|
|
|
|
return hr;
|
|
|
|
} // CMBPropertyWriter::GetMetaFlagsTag
|