Leaked source code of windows server 2003
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.
 
 
 
 
 
 

426 lines
13 KiB

// cimpexp.cxx
#include "precomp.hxx"
#include <atlbase.h>
#include <iadm.h>
#include "coiadm.hxx"
#define DEFAULT_TIMEOUT_VALUE 30000
// Implementation of CImpExpHelp
CADMCOMW::CImpExpHelp::CImpExpHelp()
{
return;
}
CADMCOMW::CImpExpHelp::~CImpExpHelp(void)
{
return;
}
VOID CADMCOMW::CImpExpHelp::Init(CADMCOMW *pBackObj)
{
// Init the Back Object Pointer to point to the parent object.
m_pUnkOuter = (IUnknown*)pBackObj;
return;
}
STDMETHODIMP CADMCOMW::CImpExpHelp::QueryInterface(
REFIID riid,
PPVOID ppv)
{
// Delegate this call to the outer object's QueryInterface.
return m_pUnkOuter->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG) CADMCOMW::CImpExpHelp::AddRef(void)
{
// Delegate this call to the outer object's AddRef.
return m_pUnkOuter->AddRef();
}
STDMETHODIMP_(ULONG) CADMCOMW::CImpExpHelp::Release(void)
{
// Delegate this call to the outer object's Release.
return m_pUnkOuter->Release();
}
STDMETHODIMP CADMCOMW::CImpExpHelp::EnumeratePathsInFile (
/* [unique, in, string] */ LPCWSTR pszFileName,
/* [unique, in, string] */ LPCWSTR pszKeyType,
/* [in] */ DWORD dwMDBufferSize,
/* [out, size_is(dwMDBufferSize)] */ WCHAR *pszBuffer,
/* [out] */ DWORD *pdwMDRequiredBufferSize)
{
HRESULT hr = S_OK;
CComPtr<ISimpleTableDispenser2> spISTDisp;
CComPtr<ISimpleTableRead2> spISTProperty;
CComPtr<IErrorInfo> spErrorInfo;
CComPtr<ISimpleTableRead2> spISTError;
CComPtr<ICatalogErrorLogger2> spILogger;
CComPtr<IAdvancedTableDispenser> spISTDispAdvanced;
ULONG iRowDuplicateLocation = 0;
STRAU strFileName;
if ((!pszFileName)||(!*pszFileName)||(!pszKeyType))
{
hr = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
goto done;
}
if (!pszBuffer)
{
dwMDBufferSize = 0;
}
hr = CoImpersonateClient();
if (FAILED(hr))
{
goto done;
}
METADATA_HANDLE hActualHandle;
CADMCOMW* pOuter = NULL;
pOuter = (CADMCOMW*)m_pUnkOuter;
hr = pOuter->LookupAndAccessCheck( METADATA_MASTER_ROOT_HANDLE,
&hActualHandle,
L"",
MD_ADMIN_ACL,
METADATA_PERMISSION_WRITE);
if (FAILED(hr))
{
goto done;
}
// IVANPASH 598894 (SCR)
// Prepend the file name with \\?\ (or \\?\UNC\) to prevent canonicalization
hr = MakePathCanonicalizationProof( pszFileName, TRUE, &strFileName );
if ( FAILED( hr ) )
{
goto done;
}
// Don't use i_wszFileName any more
pszFileName = NULL;
STQueryCell QueryCell[1];
//
// Get the property table.
//
QueryCell[0].pData = (LPVOID)strFileName.QueryStrW();
QueryCell[0].eOperator = eST_OP_EQUAL;
QueryCell[0].iCell = iST_CELL_FILE;
QueryCell[0].dbType = DBTYPE_WSTR;
QueryCell[0].cbSize = (lstrlenW(strFileName.QueryStrW())+1)*sizeof(WCHAR);
ULONG cCell = sizeof(QueryCell)/sizeof(STQueryCell);
//
// No need to initilize dispenser (InitializeSimpleTableDispenser()),
// because we now specify USE_CRT=1 in sources, which means that
// globals will be initialized.
//
hr = DllGetSimpleObjectByIDEx( eSERVERWIRINGMETA_TableDispenser, IID_ISimpleTableDispenser2, (VOID**)&spISTDisp, WSZ_PRODUCT_IIS );
if(FAILED(hr))
{
DBGERROR((
DBG_CONTEXT,
"[%s] DllGetSimpleObjectByIDEx failed with hr = 0x%x.\n",__FUNCTION__,hr));
goto done;
}
hr = spISTDisp->GetTable(
wszDATABASE_METABASE,
wszTABLE_MBProperty,
(LPVOID)QueryCell,
(LPVOID)&cCell,
eST_QUERYFORMAT_CELLS,
fST_LOS_DETAILED_ERROR_TABLE | fST_LOS_NO_LOGGING,
(LPVOID *)&spISTProperty);
//
// Log warnings/errors in getting the mb property table
// Do this BEFORE checking the return code of GetTable.
//
HRESULT hrErrorTable = GetErrorInfo(0, &spErrorInfo);
if(hrErrorTable == S_OK) // GetErrorInfo returns S_FALSE when there is no error object
{
//
// Get the ICatalogErrorLogger interface to log the errors.
//
hrErrorTable = spISTDisp->QueryInterface(
IID_IAdvancedTableDispenser,
(LPVOID*)&spISTDispAdvanced);
if(FAILED(hrErrorTable))
{
DBGWARN((
DBG_CONTEXT,
"[%s] Could not QI for Adv Dispenser, hr=0x%x\n", __FUNCTION__, hrErrorTable));
goto done;
}
hrErrorTable = spISTDispAdvanced->GetCatalogErrorLogger(&spILogger);
if(FAILED(hrErrorTable))
{
DBGWARN((
DBG_CONTEXT,
"[%s] Could not get ICatalogErrorLogger2, hr=0x%x\n", __FUNCTION__, hrErrorTable));
goto done;
}
//
// Get the ISimpleTableRead2 interface to read the errors.
//
hrErrorTable =
spErrorInfo->QueryInterface(IID_ISimpleTableRead2, (LPVOID*)&spISTError);
if(FAILED(hrErrorTable))
{
DBGWARN((DBG_CONTEXT, "[%s] Could not get ISTRead2 from IErrorInfo\n, __FUNCTION__"));
goto done;
}
for(ULONG iRow=0; ; iRow++)
{
tDETAILEDERRORSRow ErrorInfo;
hrErrorTable = spISTError->GetColumnValues(
iRow,
cDETAILEDERRORS_NumberOfColumns,
0,
0,
(LPVOID*)&ErrorInfo);
if(hrErrorTable == E_ST_NOMOREROWS)
{
break;
}
if(FAILED(hrErrorTable))
{
DBGWARN((DBG_CONTEXT, "[%s] Could not read an error row.\n", __FUNCTION__));
goto done;
}
DBG_ASSERT(ErrorInfo.pEvent);
switch(*ErrorInfo.pEvent)
{
case IDS_METABASE_DUPLICATE_LOCATION:
iRowDuplicateLocation = iRow;
break;
default:
hrErrorTable =
spILogger->ReportError(
BaseVersion_DETAILEDERRORS,
ExtendedVersion_DETAILEDERRORS,
cDETAILEDERRORS_NumberOfColumns,
0,
(LPVOID*)&ErrorInfo);
if(FAILED(hrErrorTable))
{
DBGWARN((DBG_CONTEXT, "[%s] Could not log error.\n", __FUNCTION__));
goto done;
}
hr = MD_ERROR_READ_METABASE_FILE;
}
} // for(ULONG iRow=0; ; iRow++)
} // if(hrErrorTable == S_OK)
if(FAILED(hr))
{
DBGERROR((DBG_CONTEXT, "[%s] GetTable failed with hr = 0x%x.\n",__FUNCTION__,hr));
goto done;
}
//
// All of the stuff is read into pISTProperty.
// Now loop through and populate in-memory cache.
// Properties are sorted by location.
//
ULONG acbMBPropertyRow[cMBProperty_NumberOfColumns];
tMBPropertyRow MBPropertyRow;
DWORD dwPreviousLocationID = (DWORD)-1;
DWORD bufLoc = 0;
DWORD dSize = 0;
const WCHAR cSpace[2] = L" ";
const WCHAR cNoName[2] = L"/";
const WCHAR cWebDirType[17] = L"IIsWebVirtualDir";
const WCHAR cFtpDirType[17] = L"IIsFtpVirtualDir";
const WCHAR cRoot[6] = L"ROOT/";
DWORD dwWSLoc = (DWORD)-1;
bool bServCommAdded = true;
ULONG topIndex = 0;
bool bSameLocation = true;
long spot = 0;
long avail = dwMDBufferSize - 1;
for(ULONG i=0; ;i++)
{
hr = spISTProperty->GetColumnValues(
i,
cMBProperty_NumberOfColumns,
0,
acbMBPropertyRow,
(LPVOID*)&MBPropertyRow);
if(E_ST_NOMOREROWS == hr)
{
hr = S_OK;
break;
}
else if(FAILED(hr))
{
DBGINFO((DBG_CONTEXT,
"[ReadSomeDataFromXML] GetColumnValues failed with hr = 0x%x. Table:%ws. Read row index:%d.\n", \
hr, wszTABLE_MBProperty, i));
goto done;
}
if(dwPreviousLocationID != *MBPropertyRow.pLocationID)
{
dwPreviousLocationID = *MBPropertyRow.pLocationID;
topIndex = i;
}
if(*MBPropertyRow.pID == MD_KEY_TYPE)
{
if (!wcscmp((LPCWSTR)MBPropertyRow.pValue, pszKeyType))
{
// MBPropertyRow.pLocation
dSize = (DWORD)wcslen(MBPropertyRow.pLocation);
spot = bufLoc + dSize;
if (spot < avail)
{
wcscpy(&(pszBuffer[bufLoc]), MBPropertyRow.pLocation);
pszBuffer[bufLoc + dSize] = 0;
}
bufLoc += dSize+1;
dwWSLoc = *MBPropertyRow.pLocationID;
bServCommAdded = false;
// now check from topIndex down for a ServerComment
hr = S_OK;
bSameLocation = true;
while (SUCCEEDED(hr) && !bServCommAdded && bSameLocation)
{
// special case for "IIsWebVirtualDir"
if (!wcscmp(pszKeyType, cWebDirType) || !wcscmp(pszKeyType, cFtpDirType))
{
WCHAR* pCopy = NULL;
WCHAR* pPos = NULL;
pCopy = _wcsdup(MBPropertyRow.pLocation);
if (!pCopy)
{
hr = E_OUTOFMEMORY;
goto done;
}
if (!_wcsupr(pCopy))
{
hr = E_FAIL;
goto done;
}
pPos = wcsstr(pCopy, cRoot);
if (pPos)
{
LONG_PTR lPos = pPos - pCopy;
pPos = MBPropertyRow.pLocation + lPos + wcslen(cRoot);
}
else
{
pPos = (WCHAR*)cNoName;
}
// now copy pPos if applicable
dSize = (DWORD)wcslen(pPos);
spot = bufLoc + dSize;
if (spot < avail)
{
wcscpy(&(pszBuffer[bufLoc]), pPos);
pszBuffer[bufLoc + dSize] = 0;
}
bufLoc += dSize+1;
free(pCopy);
bServCommAdded = true;
break;
}
hr = spISTProperty->GetColumnValues(
topIndex,
cMBProperty_NumberOfColumns,
0,
acbMBPropertyRow,
(LPVOID*)&MBPropertyRow);
if (*MBPropertyRow.pLocationID != dwWSLoc)
{
bSameLocation = false;
break;
}
if (*MBPropertyRow.pID == MD_SERVER_COMMENT)
{
dSize = (DWORD)wcslen((WCHAR*)MBPropertyRow.pValue);
spot = bufLoc + dSize;
if (spot < avail)
{
wcscpy(&(pszBuffer[bufLoc]), (WCHAR*)MBPropertyRow.pValue);
pszBuffer[bufLoc + dSize] = 0;
}
bufLoc += dSize+1;
bServCommAdded = true;
}
topIndex++;
}
if (!bServCommAdded)
{
// need to add in " "
dSize = (DWORD)wcslen(cSpace);
spot = bufLoc + dSize;
if (spot < avail)
{
wcscpy(&(pszBuffer[bufLoc]), cSpace);
pszBuffer[bufLoc + dSize] = 0;
}
bufLoc += dSize+1;
}
}
}
}
if (bufLoc < dwMDBufferSize)
{
pszBuffer[bufLoc] = 0;
}
else if (pszBuffer)
{
pszBuffer[dwMDBufferSize-1] = 0;
pszBuffer[dwMDBufferSize-2] = 0;
hr = RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER);
}
*pdwMDRequiredBufferSize = bufLoc + 1;
done:
return hr;
}