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.
1805 lines
47 KiB
1805 lines
47 KiB
/*++
|
|
|
|
Copyright (c) 2000-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
SecConLib.cpp
|
|
|
|
Abstract:
|
|
|
|
Implementation of:
|
|
CSecConLib
|
|
|
|
Author:
|
|
|
|
Brent R. Midwood Apr-2002
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "secconlib.h"
|
|
#include "debug.h"
|
|
#include "iiscnfg.h"
|
|
|
|
#define BAIL_ON_FAILURE(hr) if (FAILED(hr)) { goto done; }
|
|
#define DEFAULT_TIMEOUT_VALUE 30000
|
|
#define SEMICOLON_STRING L";"
|
|
#define SEMICOLON_CHAR L';'
|
|
#define COMMA_STRING L","
|
|
#define COMMA_CHAR L','
|
|
#define ZERO_STRING L"0"
|
|
#define ZERO_CHAR L'0'
|
|
#define ONE_STRING L"1"
|
|
#define ONE_CHAR L'1'
|
|
|
|
CSecConLib::CSecConLib()
|
|
{
|
|
m_bInit = false;
|
|
}
|
|
|
|
CSecConLib::CSecConLib(
|
|
IMSAdminBase* pIABase)
|
|
{
|
|
SC_ASSERT(pIABase != NULL);
|
|
m_spIABase = pIABase;
|
|
m_bInit = true;
|
|
}
|
|
|
|
CSecConLib::~CSecConLib()
|
|
{
|
|
}
|
|
|
|
HRESULT
|
|
CSecConLib::InternalInitIfNecessary()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CSafeLock csSafe(m_SafeCritSec);
|
|
|
|
if(m_bInit)
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = csSafe.Lock();
|
|
hr = HRESULT_FROM_WIN32(hr);
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
if(!m_bInit)
|
|
{
|
|
hr = CoCreateInstance(
|
|
CLSID_MSAdminBase,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IMSAdminBase,
|
|
(void**)&m_spIABase);
|
|
if(FAILED(hr))
|
|
{
|
|
m_bInit = false;
|
|
}
|
|
else
|
|
{
|
|
m_bInit = true;
|
|
}
|
|
}
|
|
|
|
csSafe.Unlock();
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::EnableApplication(
|
|
/* [in] */ LPCWSTR wszApplication,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
DWORD dwAppNameSz = 0;
|
|
WCHAR *pwszAppProp = NULL;
|
|
DWORD dwAppPropSz = 0;
|
|
HRESULT hr = S_OK;
|
|
bool bFound = false;
|
|
WCHAR *pTop = NULL;
|
|
|
|
// compute arg length
|
|
dwAppNameSz = (DWORD)wcslen(wszApplication);
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for applicationdep list
|
|
hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (NULL == pwszAppProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
pTop = pwszAppProp;
|
|
|
|
// go thru the apps one by one
|
|
while (pwszAppProp[0])
|
|
{
|
|
DWORD dwTokSz = (DWORD)wcslen(pwszAppProp) + 1;
|
|
|
|
// check to see if the app matches
|
|
if (!_wcsnicmp(wszApplication, pwszAppProp, dwAppNameSz) &&
|
|
pwszAppProp[dwAppNameSz] == SEMICOLON_CHAR)
|
|
{
|
|
bFound = true;
|
|
|
|
WCHAR *pGroups = &pwszAppProp[dwAppNameSz + ((DWORD)sizeof(SEMICOLON_CHAR) / (DWORD)sizeof(WCHAR))];
|
|
|
|
while (pGroups)
|
|
{
|
|
WCHAR *pTemp = wcschr(pGroups, COMMA_CHAR);
|
|
|
|
if (pTemp)
|
|
{
|
|
*pTemp = 0; // replace comma w/ null
|
|
}
|
|
|
|
hr = EnableWebServiceExtension(pGroups, wszPath);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (pTemp)
|
|
{
|
|
pGroups = pTemp + 1; // go past comma
|
|
}
|
|
else
|
|
{
|
|
pGroups = NULL;
|
|
}
|
|
}
|
|
}
|
|
pwszAppProp += dwTokSz; // go to the next part of the multisz
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
|
|
}
|
|
|
|
done:
|
|
if (pTop)
|
|
{
|
|
delete [] pTop;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSecConLib::SetMultiSZPropVal(
|
|
LPCWSTR wszPath,
|
|
DWORD dwMetaId,
|
|
WCHAR *pBuffer,
|
|
DWORD dwBufSize)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
METADATA_RECORD mdrMDData;
|
|
METADATA_HANDLE hObjHandle = NULL;
|
|
|
|
hr = m_spIABase->OpenKey(
|
|
METADATA_MASTER_ROOT_HANDLE,
|
|
wszPath,
|
|
METADATA_PERMISSION_WRITE,
|
|
DEFAULT_TIMEOUT_VALUE,
|
|
&hObjHandle
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (!pBuffer)
|
|
{
|
|
hr = m_spIABase->DeleteData(
|
|
hObjHandle,
|
|
(LPWSTR)L"",
|
|
dwMetaId,
|
|
ALL_METADATA
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
else
|
|
{
|
|
MD_SET_DATA_RECORD(&mdrMDData,
|
|
dwMetaId,
|
|
METADATA_NO_ATTRIBUTES,
|
|
IIS_MD_UT_SERVER,
|
|
MULTISZ_METADATA,
|
|
dwBufSize * sizeof(WCHAR),
|
|
pBuffer);
|
|
|
|
hr = m_spIABase->SetData(
|
|
hObjHandle,
|
|
L"",
|
|
&mdrMDData
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
done:
|
|
|
|
m_spIABase->CloseKey(hObjHandle);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSecConLib::GetMultiSZPropVal(
|
|
LPCWSTR wszPath,
|
|
DWORD dwMetaId,
|
|
WCHAR **ppBuffer,
|
|
DWORD *dwBufSize)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwBufferSize = 0;
|
|
METADATA_RECORD mdrMDData;
|
|
WCHAR *pBuffer = NULL;
|
|
METADATA_HANDLE hObjHandle = NULL;
|
|
|
|
hr = m_spIABase->OpenKey(
|
|
METADATA_MASTER_ROOT_HANDLE,
|
|
wszPath,
|
|
METADATA_PERMISSION_READ,
|
|
DEFAULT_TIMEOUT_VALUE,
|
|
&hObjHandle
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
MD_SET_DATA_RECORD(&mdrMDData,
|
|
dwMetaId,
|
|
METADATA_NO_ATTRIBUTES,
|
|
IIS_MD_UT_SERVER,
|
|
MULTISZ_METADATA,
|
|
dwBufferSize,
|
|
pBuffer);
|
|
|
|
hr = m_spIABase->GetData(
|
|
hObjHandle,
|
|
L"",
|
|
&mdrMDData,
|
|
&dwBufferSize
|
|
);
|
|
|
|
if (dwBufferSize > 0)
|
|
{
|
|
*dwBufSize = dwBufferSize / sizeof(WCHAR);
|
|
pBuffer = (WCHAR*) new BYTE[dwBufferSize];
|
|
|
|
if (!pBuffer) {
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
MD_SET_DATA_RECORD(&mdrMDData,
|
|
dwMetaId,
|
|
METADATA_NO_ATTRIBUTES,
|
|
IIS_MD_UT_SERVER,
|
|
MULTISZ_METADATA,
|
|
dwBufferSize,
|
|
pBuffer);
|
|
|
|
hr = m_spIABase->GetData(
|
|
hObjHandle,
|
|
L"",
|
|
&mdrMDData,
|
|
&dwBufferSize
|
|
);
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
*ppBuffer = pBuffer;
|
|
|
|
hr = m_spIABase->CloseKey(hObjHandle);
|
|
|
|
return hr;
|
|
|
|
done:
|
|
|
|
if (pBuffer) {
|
|
delete [] pBuffer;
|
|
}
|
|
|
|
m_spIABase->CloseKey(hObjHandle);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::RemoveApplication(
|
|
/* [in] */ LPCWSTR wszApplication,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
DWORD dwAppNameSz = 0;
|
|
WCHAR *pwszOrig = NULL;
|
|
WCHAR *pTopOrig = NULL;
|
|
WCHAR *pwszAppProp = NULL;
|
|
DWORD dwAppPropSz = 0;
|
|
HRESULT hr = S_OK;
|
|
bool bFound = false;
|
|
|
|
// compute arg length
|
|
dwAppNameSz = (DWORD)wcslen(wszApplication);
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for applicationdep list
|
|
hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
// remove the application
|
|
|
|
// copy the property
|
|
pwszOrig = new WCHAR[dwAppPropSz];
|
|
pTopOrig = pwszOrig;
|
|
|
|
if (!pwszOrig)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
memcpy(pwszOrig, pwszAppProp, dwAppPropSz * sizeof(WCHAR));
|
|
|
|
dwAppPropSz = 1; //reset size to contain one for the last null
|
|
WCHAR* pMidBuf = pwszAppProp;
|
|
|
|
// copy the old apps one by one
|
|
while (pwszOrig[0])
|
|
{
|
|
DWORD dwTokSz = (DWORD)wcslen(pwszOrig) + 1;
|
|
|
|
// check to see if the app already exists
|
|
if (!_wcsnicmp(wszApplication, pwszOrig, dwAppNameSz) &&
|
|
pwszOrig[dwAppNameSz] == SEMICOLON_CHAR)
|
|
{
|
|
bFound = true;
|
|
}
|
|
else
|
|
{
|
|
// copy it in
|
|
if (NULL == pMidBuf)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
wcscpy(pMidBuf, pwszOrig);
|
|
pMidBuf += dwTokSz; // advance past null
|
|
*pMidBuf = 0; // add the last null
|
|
dwAppPropSz += dwTokSz;
|
|
}
|
|
pwszOrig += dwTokSz; // go to the next part of the multisz
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
|
|
}
|
|
|
|
// set the new property value for property
|
|
if (dwAppPropSz < 3)
|
|
{
|
|
// handle deleting the last one
|
|
hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, NULL, 0);
|
|
}
|
|
else
|
|
{
|
|
hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, pwszAppProp, dwAppPropSz);
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
done:
|
|
if (pTopOrig)
|
|
{
|
|
delete [] pTopOrig;
|
|
}
|
|
|
|
if (pwszAppProp)
|
|
{
|
|
delete [] pwszAppProp;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::QueryGroupIDStatus(
|
|
/* [in] */ LPCWSTR wszPath,
|
|
/* [in] */ LPCWSTR wszGroupID,
|
|
/* [out] */ WCHAR **pszBuffer, // MULTI_SZ - allocated in here, caller should delete
|
|
/* [out] */ DWORD *pdwBufferSize) // length includes double null
|
|
{
|
|
WCHAR *pwszAppProp = NULL;
|
|
DWORD dwAppPropSz = 0;
|
|
WCHAR *pList = NULL;
|
|
WCHAR *pTempList = NULL;
|
|
DWORD dwListLen = 1; // one for the extra null at the end
|
|
DWORD dwOldListLen = 1;
|
|
HRESULT hr = S_OK;
|
|
WCHAR *pTop = NULL;
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for applicationdep list
|
|
hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (NULL == pwszAppProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
pTop = pwszAppProp;
|
|
|
|
// iterate through the apps
|
|
while (pwszAppProp[0])
|
|
{
|
|
// reset bFound
|
|
bool bFound = false;
|
|
|
|
WCHAR* pMidBuf = wcschr(pwszAppProp, SEMICOLON_CHAR);
|
|
if (!pMidBuf)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_FAIL);
|
|
}
|
|
|
|
// null the semicolon and go past it
|
|
*pMidBuf = 0;
|
|
*pMidBuf++;
|
|
|
|
// does this app have a dependency on the GroupID that got passed in?
|
|
WCHAR* pGroupID = NULL;
|
|
WCHAR* pGroups = new WCHAR[(DWORD)wcslen(pMidBuf) + 1];
|
|
if (!pGroups)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
// copy in the GroupIDs
|
|
wcscpy(pGroups, pMidBuf);
|
|
|
|
// look at each GroupID
|
|
pGroupID = wcstok(pGroups, COMMA_STRING);
|
|
|
|
while (pGroupID && !bFound)
|
|
{
|
|
if (!wcscmp(pGroupID, wszGroupID))
|
|
{
|
|
bFound = true;
|
|
}
|
|
|
|
pGroupID = wcstok(NULL, COMMA_STRING);
|
|
}
|
|
|
|
if (pGroups)
|
|
{
|
|
delete [] pGroups;
|
|
}
|
|
|
|
// do we want to add this app to the list?
|
|
if (bFound)
|
|
{
|
|
// allocate the memory
|
|
dwListLen += (DWORD)wcslen(pwszAppProp) + 1; // for the null
|
|
pTempList = new WCHAR[dwListLen];
|
|
|
|
if (!pTempList)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (pList)
|
|
{
|
|
// copy the previous list
|
|
memcpy(pTempList, pList, dwOldListLen * sizeof(WCHAR));
|
|
delete [] pList;
|
|
}
|
|
|
|
// copy on the app name
|
|
wcscpy(&pTempList[dwOldListLen - 1], pwszAppProp);
|
|
pTempList[dwListLen-1] = 0;
|
|
pTempList[dwListLen-2] = 0;
|
|
|
|
pList = pTempList;
|
|
dwOldListLen = dwListLen;
|
|
}
|
|
|
|
// now go to the next application
|
|
pwszAppProp = pMidBuf + (DWORD)wcslen(pMidBuf) + 1;
|
|
}
|
|
|
|
*pszBuffer = pList;
|
|
*pdwBufferSize = dwListLen;
|
|
|
|
done:
|
|
if (pTop)
|
|
{
|
|
delete [] pTop;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::ListApplications(
|
|
/* [in] */ LPCWSTR wszPath,
|
|
/* [out] */ WCHAR **pszBuffer, // MULTI_SZ - allocated in here, caller should delete
|
|
/* [out] */ DWORD *pdwBufferSize) // length includes double null
|
|
{
|
|
WCHAR *pwszAppProp = NULL;
|
|
DWORD dwAppPropSz = 0;
|
|
WCHAR *pList = NULL;
|
|
WCHAR *pTempList = NULL;
|
|
DWORD dwListLen = 1; // one for the extra null at the end
|
|
DWORD dwOldListLen = 1;
|
|
HRESULT hr = S_OK;
|
|
WCHAR *pTop = NULL;
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for applicationdep list
|
|
hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (NULL == pwszAppProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
pTop = pwszAppProp;
|
|
|
|
// iterate through the apps
|
|
while (pwszAppProp[0])
|
|
{
|
|
WCHAR* pMidBuf = wcschr(pwszAppProp, SEMICOLON_CHAR);
|
|
if (!pMidBuf)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_FAIL);
|
|
}
|
|
|
|
// null the semicolon and go past it
|
|
*pMidBuf = 0;
|
|
*pMidBuf++;
|
|
|
|
// allocate the memory
|
|
dwListLen += (DWORD)wcslen(pwszAppProp) + 1; // for the null
|
|
pTempList = new WCHAR[dwListLen];
|
|
|
|
if (!pTempList)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (pList)
|
|
{
|
|
// copy the previous list
|
|
memcpy(pTempList, pList, dwOldListLen * sizeof(WCHAR));
|
|
delete [] pList;
|
|
}
|
|
|
|
// copy on the app name
|
|
wcscpy(&pTempList[dwOldListLen - 1], pwszAppProp);
|
|
pTempList[dwListLen-1] = 0;
|
|
pTempList[dwListLen-2] = 0;
|
|
|
|
pList = pTempList;
|
|
dwOldListLen = dwListLen;
|
|
|
|
// now go to the next application
|
|
pwszAppProp = pMidBuf + (DWORD)wcslen(pMidBuf) + 1;
|
|
}
|
|
|
|
if (!pList)
|
|
{
|
|
// make it a valid empty multisz
|
|
dwListLen = 2;
|
|
pList = new WCHAR[dwListLen];
|
|
if (!pList)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
wmemset(pList, 0, dwListLen);
|
|
}
|
|
|
|
*pszBuffer = pList;
|
|
*pdwBufferSize = dwListLen;
|
|
|
|
done:
|
|
if (pTop)
|
|
{
|
|
delete [] pTop;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::AddDependency(
|
|
/* [in] */ LPCWSTR wszApplication,
|
|
/* [in] */ LPCWSTR wszGroupID,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
WCHAR *pwszAppProp = NULL;
|
|
WCHAR *pwszOrig = NULL;
|
|
WCHAR *pwszTopOrig = NULL;
|
|
DWORD dwAppPropSz = 0;
|
|
DWORD dwAppNameSz = 0;
|
|
DWORD dwGroupIDSz = 0;
|
|
HRESULT hr = S_OK;
|
|
bool bDone = false;
|
|
|
|
// compute arg length
|
|
dwAppNameSz = (DWORD)wcslen(wszApplication);
|
|
dwGroupIDSz = (DWORD)wcslen(wszGroupID);
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for applicationdep list
|
|
hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
|
|
|
|
if (MD_ERROR_DATA_NOT_FOUND == hr)
|
|
{
|
|
// this is okay, we just need to create the property.
|
|
hr = S_OK;
|
|
dwAppPropSz = 0;
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
// add the dependency
|
|
|
|
if (!dwAppPropSz)
|
|
{
|
|
// create the property
|
|
|
|
// size of the property = len(App) + 1(semicolon) + len(GID) + 2(double null MULTISZ)
|
|
dwAppPropSz = dwAppNameSz + (DWORD)wcslen(SEMICOLON_STRING) + dwGroupIDSz + 2;
|
|
|
|
// No Leak
|
|
// pwszAppProp never got alloced since we didn't get any value back,
|
|
// so no need to delete first...
|
|
|
|
pwszAppProp = new WCHAR[dwAppPropSz];
|
|
if (!pwszAppProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
wcscpy(pwszAppProp, wszApplication);
|
|
wcscat(pwszAppProp, SEMICOLON_STRING);
|
|
wcscat(pwszAppProp, wszGroupID);
|
|
|
|
// add the double null
|
|
pwszAppProp[dwAppPropSz-1] = 0;
|
|
pwszAppProp[dwAppPropSz-2] = 0;
|
|
}
|
|
|
|
else
|
|
{
|
|
// property already exists
|
|
|
|
// copy the property
|
|
pwszOrig = new WCHAR[dwAppPropSz];
|
|
pwszTopOrig = pwszOrig;
|
|
|
|
if (!pwszOrig)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
memcpy(pwszOrig, pwszAppProp, dwAppPropSz * sizeof(WCHAR));
|
|
|
|
// resize the new property to the biggest possible
|
|
if (pwszAppProp)
|
|
{
|
|
delete [] pwszAppProp;
|
|
}
|
|
|
|
// max new size is old size + len(app) + 1(semicolon) + len(GID) + null
|
|
dwAppPropSz = dwAppPropSz + dwAppNameSz + (DWORD)wcslen(SEMICOLON_STRING) +
|
|
dwGroupIDSz + 1;
|
|
|
|
pwszAppProp = new WCHAR[dwAppPropSz];
|
|
if (!pwszAppProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
WCHAR* pMidBuf = pwszAppProp;
|
|
|
|
// copy the old dependencies one by one
|
|
while (pwszOrig[0])
|
|
{
|
|
wcscpy(pMidBuf, pwszOrig);
|
|
|
|
// check to see if the app already exists
|
|
if (!_wcsnicmp(wszApplication, pMidBuf, dwAppNameSz) &&
|
|
pMidBuf[dwAppNameSz] == SEMICOLON_CHAR)
|
|
{
|
|
// since we're not adding the app, subtract the size of the app and trailing null
|
|
dwAppPropSz = dwAppPropSz - dwAppNameSz - 1;
|
|
|
|
// this is the correct app, so now look for the GroupID
|
|
pMidBuf += dwAppNameSz + 1; // go to the first GroupID
|
|
|
|
// need a temp copy, sinc wcstok modifies the string
|
|
WCHAR* pTokTemp = new WCHAR[(DWORD)wcslen(pMidBuf) + 1];
|
|
if (!pTokTemp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
wcscpy(pTokTemp, pMidBuf);
|
|
|
|
WCHAR* token = wcstok( pTokTemp, COMMA_STRING );
|
|
while (token && !bDone)
|
|
{
|
|
if (!_wcsicmp(token, wszGroupID))
|
|
{
|
|
// we found the group ID, so the user is trying
|
|
// to add a dependency that is already there
|
|
if (pTokTemp)
|
|
{
|
|
delete [] pTokTemp;
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(ERROR_DUP_NAME));
|
|
}
|
|
token = wcstok( NULL, COMMA_STRING );
|
|
}
|
|
|
|
if (pTokTemp)
|
|
{
|
|
delete [] pTokTemp;
|
|
}
|
|
|
|
pMidBuf += (DWORD)wcslen(pMidBuf); // go to the null at the end of this part
|
|
|
|
if (!bDone)
|
|
{
|
|
// we didn't find the GroupID, so add it
|
|
wcscat(pMidBuf, COMMA_STRING);
|
|
wcscat(pMidBuf, wszGroupID);
|
|
pMidBuf += (DWORD)wcslen(pMidBuf); // go to the null at the end of this part
|
|
bDone = true;
|
|
}
|
|
|
|
pMidBuf++; // go to the next char and make it a null
|
|
pMidBuf[0] = 0;
|
|
}
|
|
|
|
else // no change here, move pMidBuf along...
|
|
{
|
|
pMidBuf += (DWORD)wcslen(pMidBuf) + 1; // go past the null
|
|
}
|
|
|
|
pwszOrig += (DWORD)wcslen(pwszOrig) + 1; // go to the next part of the multisz
|
|
}
|
|
|
|
if (!bDone)
|
|
{
|
|
// we didn't even find the application, so add both app & groupID
|
|
wcscpy(pMidBuf, wszApplication);
|
|
wcscat(pMidBuf, SEMICOLON_STRING);
|
|
wcscat(pMidBuf, wszGroupID);
|
|
pMidBuf[(DWORD)wcslen(pMidBuf)+1] = 0; // add the last null
|
|
}
|
|
}
|
|
|
|
// set the new property value for property
|
|
hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, pwszAppProp, dwAppPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
done:
|
|
if (pwszTopOrig)
|
|
{
|
|
delete [] pwszTopOrig;
|
|
}
|
|
|
|
if (pwszAppProp)
|
|
{
|
|
delete [] pwszAppProp;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::RemoveDependency(
|
|
/* [in] */ LPCWSTR wszApplication,
|
|
/* [in] */ LPCWSTR wszGroupID,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WCHAR *pwszOrig = NULL;
|
|
WCHAR *pwszTopOrig = NULL;
|
|
WCHAR *pwszAppProp = NULL;
|
|
WCHAR *pStartStr = NULL;
|
|
DWORD dwAppPropSz = 0;
|
|
DWORD dwAppNameSz = 0;
|
|
DWORD dwGroupIDSz = 0;
|
|
bool bFound = false;
|
|
bool bOtherGIDs = false;
|
|
|
|
// compute arg length
|
|
dwAppNameSz = (DWORD)wcslen(wszApplication);
|
|
dwGroupIDSz = (DWORD)wcslen(wszGroupID);
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for applicationdep list
|
|
hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
// remove the dependency
|
|
|
|
// copy the property
|
|
pwszOrig = new WCHAR[dwAppPropSz];
|
|
pwszTopOrig = pwszOrig;
|
|
|
|
if (!pwszOrig)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
memcpy(pwszOrig, pwszAppProp, dwAppPropSz * sizeof(WCHAR));
|
|
|
|
WCHAR* pMidBuf = pwszAppProp;
|
|
|
|
// copy the old dependencies one by one
|
|
while (pwszOrig[0])
|
|
{
|
|
// check to see if the app already exists
|
|
if (!_wcsnicmp(wszApplication, pwszOrig, dwAppNameSz) &&
|
|
pwszOrig[dwAppNameSz] == SEMICOLON_CHAR)
|
|
{
|
|
pStartStr = pMidBuf;
|
|
|
|
// this is the correct app, so now look for the GroupID
|
|
pMidBuf += dwAppNameSz + 1; // go to the first GroupID
|
|
|
|
// need a temp copy, sinc wcstok modifies the string
|
|
WCHAR* pTokTemp = new WCHAR[(DWORD)wcslen(pMidBuf) + 1];
|
|
if (!pTokTemp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
wcscpy(pTokTemp, pMidBuf);
|
|
|
|
WCHAR* token = wcstok( pTokTemp, COMMA_STRING );
|
|
while (token)
|
|
{
|
|
if (bOtherGIDs)
|
|
{
|
|
wcscpy(pMidBuf, COMMA_STRING);
|
|
pMidBuf += (DWORD)wcslen(pMidBuf);
|
|
}
|
|
|
|
if (!wcscmp(token, wszGroupID))
|
|
{
|
|
// we found the group ID
|
|
bFound = true;
|
|
|
|
// adjust the final length = no comma, no GID
|
|
dwAppPropSz = dwAppPropSz - (DWORD)wcslen(COMMA_STRING) - dwGroupIDSz;
|
|
|
|
if (bOtherGIDs)
|
|
{
|
|
// need to backup over the last comma we inserted
|
|
pMidBuf -= (DWORD)wcslen(COMMA_STRING);
|
|
*pMidBuf = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bOtherGIDs = true;
|
|
wcscpy(pMidBuf, token);
|
|
pMidBuf += (DWORD)wcslen(pMidBuf);
|
|
}
|
|
|
|
token = wcstok( NULL, COMMA_STRING );
|
|
}
|
|
|
|
if (pTokTemp)
|
|
{
|
|
delete [] pTokTemp;
|
|
}
|
|
|
|
if (!bOtherGIDs)
|
|
{
|
|
// deleted last dependency, so delete the app
|
|
pMidBuf = pStartStr;
|
|
dwAppPropSz = dwAppPropSz - dwAppNameSz - 1; // account for null
|
|
}
|
|
else
|
|
{
|
|
pMidBuf++;
|
|
*pMidBuf = 0;
|
|
}
|
|
}
|
|
|
|
else // no change here, move pMidBuf along...
|
|
{
|
|
if (NULL == pMidBuf)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
wcscpy(pMidBuf, pwszOrig); // copy the part without mods
|
|
pMidBuf += (DWORD)wcslen(pMidBuf) + 1; // go past the null
|
|
}
|
|
|
|
pwszOrig += (DWORD)wcslen(pwszOrig) + 1; // go to the next part of the multisz
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
// user is trying to remove a non-existent dependency
|
|
BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
|
|
}
|
|
|
|
*pMidBuf = 0;
|
|
|
|
// set the new property value for property
|
|
if (dwAppPropSz < 3)
|
|
{
|
|
// handle deleting the last one
|
|
hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, NULL, 0);
|
|
}
|
|
else
|
|
{
|
|
hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, pwszAppProp, dwAppPropSz);
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
done:
|
|
if (pwszTopOrig)
|
|
{
|
|
delete [] pwszTopOrig;
|
|
}
|
|
|
|
if (pwszAppProp)
|
|
{
|
|
delete [] pwszAppProp;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::EnableWebServiceExtension(
|
|
/* [in] */ LPCWSTR wszExtension,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = StatusWServEx(true, wszExtension, wszPath);
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
done:
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::DisableWebServiceExtension(
|
|
/* [in] */ LPCWSTR wszExtension,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = StatusWServEx(false, wszExtension, wszPath);
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
done:
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::ListWebServiceExtensions(
|
|
/* [in] */ LPCWSTR wszPath,
|
|
/* [out] */ WCHAR **pszBuffer, // MULTI_SZ - allocated in here, caller should delete
|
|
/* [out] */ DWORD *pdwBufferSize) // length includes double null
|
|
{
|
|
WCHAR *pwszRListProp = NULL;
|
|
DWORD dwRListPropSz = 0;
|
|
WCHAR *pList = NULL;
|
|
WCHAR *pTempList = NULL;
|
|
DWORD dwListLen = 1; // one for the extra null at the end
|
|
DWORD dwOldListLen = 1;
|
|
HRESULT hr = S_OK;
|
|
WCHAR *pTop = NULL;
|
|
WCHAR *pMidBuf = NULL;
|
|
bool bFound = false;
|
|
bool bSpecial = false;
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for applicationdep list
|
|
hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (NULL == pwszRListProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
pTop = pwszRListProp;
|
|
|
|
// iterate through the files
|
|
while (pwszRListProp[0])
|
|
{
|
|
// get to the group ID
|
|
for (int i=0; i<3; i++)
|
|
{
|
|
pMidBuf = wcschr(pwszRListProp, COMMA_CHAR);
|
|
if (!pMidBuf)
|
|
{
|
|
// don't fail. just treat this as a special case and break out
|
|
bSpecial = true;
|
|
pMidBuf = pwszRListProp;
|
|
break;
|
|
}
|
|
|
|
// null the comma and go past it
|
|
*pMidBuf = 0;
|
|
*pMidBuf++;
|
|
pwszRListProp = pMidBuf;
|
|
}
|
|
|
|
if (COMMA_CHAR == pMidBuf[0])
|
|
{
|
|
bSpecial = true;
|
|
pMidBuf = pwszRListProp;
|
|
}
|
|
|
|
if (!bSpecial)
|
|
{
|
|
// now we're looking at the group ID
|
|
pMidBuf = wcschr(pwszRListProp, COMMA_CHAR);
|
|
|
|
// if we can't find the comma, just treat the whole thing as a GroupID
|
|
// otherwise, the GroupID ends at the comma
|
|
if (pMidBuf)
|
|
{
|
|
// null the comma and go past it
|
|
*pMidBuf = 0;
|
|
*pMidBuf++;
|
|
}
|
|
|
|
// check to see if the entry is in the list already
|
|
WCHAR *pCheck = pList;
|
|
while (pCheck && *pCheck)
|
|
{
|
|
if (!_wcsicmp(pCheck, pwszRListProp))
|
|
{
|
|
bFound = true;
|
|
pCheck = NULL;
|
|
}
|
|
else
|
|
{
|
|
pCheck += (DWORD)wcslen(pCheck) + 1;
|
|
}
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
// allocate the memory
|
|
dwListLen += (DWORD)wcslen(pwszRListProp) + 1; // for the null
|
|
pTempList = new WCHAR[dwListLen];
|
|
|
|
if (!pTempList)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (pList)
|
|
{
|
|
// copy the previous list
|
|
memcpy(pTempList, pList, dwOldListLen * sizeof(WCHAR));
|
|
delete [] pList;
|
|
}
|
|
|
|
// copy on the file name
|
|
wcscpy(&pTempList[dwOldListLen - 1], pwszRListProp);
|
|
pTempList[dwListLen-1] = 0;
|
|
pTempList[dwListLen-2] = 0;
|
|
|
|
pList = pTempList;
|
|
dwOldListLen = dwListLen;
|
|
}
|
|
}
|
|
|
|
// now go to the next application
|
|
pwszRListProp = pMidBuf + (DWORD)wcslen(pMidBuf) + 1;
|
|
bFound = false;
|
|
bSpecial = false;
|
|
}
|
|
|
|
if (!pList)
|
|
{
|
|
// make it a valid empty multisz
|
|
dwListLen = 2;
|
|
pList = new WCHAR[dwListLen];
|
|
if (!pList)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
wmemset(pList, 0, dwListLen);
|
|
}
|
|
|
|
*pszBuffer = pList;
|
|
*pdwBufferSize = dwListLen;
|
|
|
|
done:
|
|
if (pTop)
|
|
{
|
|
delete [] pTop;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::EnableExtensionFile(
|
|
/* [in] */ LPCWSTR wszExFile,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = StatusExtensionFile(true, wszExFile, wszPath);
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
done:
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::DisableExtensionFile(
|
|
/* [in] */ LPCWSTR wszExFile,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = StatusExtensionFile(false, wszExFile, wszPath);
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
done:
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSecConLib::StatusWServEx(
|
|
/* [in] */ bool bEnable,
|
|
/* [in] */ LPCWSTR wszWServEx,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
WCHAR *pwszRListProp = NULL;
|
|
WCHAR *pTop = NULL;
|
|
DWORD dwRListPropSz = 0;
|
|
HRESULT hr = S_OK;
|
|
DWORD dwWServExSz = 0;
|
|
bool bFound = false;
|
|
|
|
// compute arg length
|
|
dwWServExSz = (DWORD)wcslen(wszWServEx);
|
|
|
|
// get the current property value for restriction list
|
|
hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (NULL == pwszRListProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
pTop = pwszRListProp;
|
|
|
|
// look at the files one by one
|
|
while (pwszRListProp[0])
|
|
{
|
|
DWORD dwTokSz = (DWORD)wcslen(pwszRListProp) + 1;
|
|
WCHAR *pFileTemp = new WCHAR[dwTokSz];
|
|
WCHAR *pToken;
|
|
|
|
if (!pFileTemp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
// check to see if we're at the right group
|
|
wcscpy(pFileTemp, pwszRListProp);
|
|
|
|
pToken = wcstok( pFileTemp, COMMA_STRING );
|
|
|
|
// look at the group ID
|
|
for (int i=0; i<3; i++)
|
|
{
|
|
if (pToken)
|
|
{
|
|
pToken = wcstok( NULL, COMMA_STRING );
|
|
}
|
|
}
|
|
|
|
if (pToken && (!wcscmp(pToken, wszWServEx)))
|
|
{
|
|
bFound = true;
|
|
if (bEnable)
|
|
{
|
|
pwszRListProp[0] = ONE_CHAR;
|
|
}
|
|
else
|
|
{
|
|
pwszRListProp[0] = ZERO_CHAR;
|
|
}
|
|
}
|
|
pwszRListProp += dwTokSz; // go to the next part of the multisz
|
|
|
|
if (pFileTemp)
|
|
{
|
|
delete [] pFileTemp;
|
|
}
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
|
|
}
|
|
|
|
// set the new property value for property
|
|
hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, pTop, dwRListPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
done:
|
|
|
|
if (pTop)
|
|
{
|
|
delete [] pTop;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSecConLib::StatusExtensionFile(
|
|
/* [in] */ bool bEnable,
|
|
/* [in] */ LPCWSTR wszExFile,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
WCHAR *pwszRListProp = NULL;
|
|
WCHAR *pTop = NULL;
|
|
DWORD dwRListPropSz = 0;
|
|
HRESULT hr = S_OK;
|
|
DWORD dwFileNameSz = 0;
|
|
bool bFound = false;
|
|
|
|
// compute arg length
|
|
dwFileNameSz = (DWORD)wcslen(wszExFile);
|
|
|
|
// get the current property value for restriction list
|
|
hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (NULL == pwszRListProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
pTop = pwszRListProp;
|
|
|
|
// look at the files one by one
|
|
while (pwszRListProp[0])
|
|
{
|
|
DWORD dwTokSz = (DWORD)wcslen(pwszRListProp) + 1;
|
|
|
|
// check to see if we're at the right file
|
|
// look past the bool(1) + comma(sizof_comma_char)
|
|
DWORD dwTemp = (DWORD)sizeof(COMMA_CHAR) / (DWORD)sizeof(WCHAR);
|
|
|
|
if ((!_wcsnicmp(wszExFile, &pwszRListProp[1 + dwTemp], dwFileNameSz)) &&
|
|
((pwszRListProp[dwFileNameSz + dwTemp + 1] == COMMA_CHAR) ||
|
|
(pwszRListProp[dwFileNameSz + dwTemp + 1] == NULL)
|
|
)
|
|
)
|
|
{
|
|
bFound = true;
|
|
if (bEnable)
|
|
{
|
|
pwszRListProp[0] = ONE_CHAR;
|
|
}
|
|
else
|
|
{
|
|
pwszRListProp[0] = ZERO_CHAR;
|
|
}
|
|
}
|
|
pwszRListProp += dwTokSz; // go to the next part of the multisz
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
|
|
}
|
|
|
|
// set the new property value for property
|
|
hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, pTop, dwRListPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
done:
|
|
|
|
if (pTop)
|
|
{
|
|
delete [] pTop;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::AddExtensionFile(
|
|
/* [in] */ LPCWSTR bstrExtensionFile,
|
|
/* [in] */ bool bAccess,
|
|
/* [in] */ LPCWSTR bstrGroupID,
|
|
/* [in] */ bool bCanDelete,
|
|
/* [in] */ LPCWSTR bstrDescription,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WCHAR *pwszRListProp = NULL;
|
|
WCHAR *pwszOrig = NULL;
|
|
WCHAR *pwszTopOrig = NULL;
|
|
DWORD dwRListPropSz = 0;
|
|
DWORD dwFileNameSz = 0;
|
|
DWORD dwGroupIDSz = 0;
|
|
DWORD dwDescSz = 0;
|
|
|
|
// compute arg length
|
|
dwFileNameSz = (DWORD)wcslen(bstrExtensionFile);
|
|
dwGroupIDSz = (DWORD)wcslen(bstrGroupID);
|
|
dwDescSz = (DWORD)wcslen(bstrDescription);
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for restriction list
|
|
hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
|
|
|
|
if (MD_ERROR_DATA_NOT_FOUND == hr)
|
|
{
|
|
// this is okay, we just need to create the property.
|
|
hr = S_OK;
|
|
dwRListPropSz = 0;
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (!dwRListPropSz)
|
|
{
|
|
// create the property
|
|
|
|
// size of the property = 1(0 or 1) + 1(comma) + len(file) + 1(comma) + 1(0 or 1) +
|
|
// 1(comma) + len(GID) + 1(comma) + len(descr) + 2(double null MULTISZ)
|
|
dwRListPropSz = 1 + (DWORD)wcslen(COMMA_STRING) + dwFileNameSz + (DWORD)wcslen(COMMA_STRING) +
|
|
1 + (DWORD)wcslen(COMMA_STRING) + dwGroupIDSz + (DWORD)wcslen(COMMA_STRING) + dwDescSz + 2;
|
|
|
|
// No Leak
|
|
// pwszRListProp never got alloced since we didn't get any value back,
|
|
// so no need to delete first...
|
|
|
|
pwszRListProp = new WCHAR[dwRListPropSz];
|
|
if (!pwszRListProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (bAccess)
|
|
{
|
|
wcscpy(pwszRListProp, ONE_STRING);
|
|
}
|
|
else
|
|
{
|
|
wcscpy(pwszRListProp, ZERO_STRING);
|
|
}
|
|
wcscat(pwszRListProp, COMMA_STRING);
|
|
wcscat(pwszRListProp, bstrExtensionFile);
|
|
wcscat(pwszRListProp, COMMA_STRING);
|
|
if (bCanDelete)
|
|
{
|
|
wcscat(pwszRListProp, ONE_STRING);
|
|
}
|
|
else
|
|
{
|
|
wcscat(pwszRListProp, ZERO_STRING);
|
|
}
|
|
wcscat(pwszRListProp, COMMA_STRING);
|
|
wcscat(pwszRListProp, bstrGroupID);
|
|
wcscat(pwszRListProp, COMMA_STRING);
|
|
wcscat(pwszRListProp, bstrDescription);
|
|
|
|
// add the double null
|
|
pwszRListProp[dwRListPropSz-1] = 0;
|
|
pwszRListProp[dwRListPropSz-2] = 0;
|
|
}
|
|
|
|
else
|
|
{
|
|
// property already exists
|
|
|
|
// copy the property
|
|
pwszOrig = new WCHAR[dwRListPropSz];
|
|
pwszTopOrig = pwszOrig;
|
|
|
|
if (!pwszOrig)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
memcpy(pwszOrig, pwszRListProp, dwRListPropSz * sizeof(WCHAR));
|
|
|
|
// resize the new property to the biggest possible
|
|
if (pwszRListProp)
|
|
{
|
|
delete [] pwszRListProp;
|
|
}
|
|
|
|
// max new size is old size + new stuff
|
|
// new stuff = 1(0 or 1) + 1(comma) + len(file) + 1(comma) + 1(0 or 1) +
|
|
// 1(comma) + len(GID) + 1(comma) + len(descr) + 1(null)
|
|
dwRListPropSz = dwRListPropSz +
|
|
1 + (DWORD)wcslen(COMMA_STRING) + dwFileNameSz + (DWORD)wcslen(COMMA_STRING) +
|
|
1 + (DWORD)wcslen(COMMA_STRING) + dwGroupIDSz + (DWORD)wcslen(COMMA_STRING) + dwDescSz + 1;
|
|
|
|
pwszRListProp = new WCHAR[dwRListPropSz];
|
|
if (!pwszRListProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
WCHAR* pMidBuf = pwszRListProp;
|
|
|
|
// copy the old list entries one by one
|
|
while (pwszOrig[0])
|
|
{
|
|
wcscpy(pMidBuf, pwszOrig);
|
|
|
|
// skip over the #,
|
|
pMidBuf += 1 + (DWORD)wcslen(COMMA_STRING);
|
|
|
|
// check to see if the app already exists
|
|
if ((!_wcsnicmp(bstrExtensionFile, pMidBuf, dwFileNameSz)) &&
|
|
((pMidBuf[dwFileNameSz] == COMMA_CHAR) ||
|
|
(pMidBuf[dwFileNameSz] == NULL)
|
|
)
|
|
)
|
|
{
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(ERROR_DUP_NAME));
|
|
}
|
|
|
|
pwszOrig += (DWORD)wcslen(pwszOrig) + 1; // go to the next part of the multisz
|
|
pMidBuf += (DWORD)wcslen(pMidBuf) + 1; // go past the null
|
|
}
|
|
|
|
// now copy the new file entry on
|
|
|
|
if (bAccess)
|
|
{
|
|
wcscpy(pMidBuf, ONE_STRING);
|
|
}
|
|
else
|
|
{
|
|
wcscpy(pMidBuf, ZERO_STRING);
|
|
}
|
|
wcscat(pMidBuf, COMMA_STRING);
|
|
wcscat(pMidBuf, bstrExtensionFile);
|
|
wcscat(pMidBuf, COMMA_STRING);
|
|
if (bCanDelete)
|
|
{
|
|
wcscat(pMidBuf, ONE_STRING);
|
|
}
|
|
else
|
|
{
|
|
wcscat(pMidBuf, ZERO_STRING);
|
|
}
|
|
wcscat(pMidBuf, COMMA_STRING);
|
|
wcscat(pMidBuf, bstrGroupID);
|
|
wcscat(pMidBuf, COMMA_STRING);
|
|
wcscat(pMidBuf, bstrDescription);
|
|
|
|
// add the last null
|
|
pMidBuf += (DWORD)wcslen(pMidBuf) + 1;
|
|
*pMidBuf = 0;
|
|
}
|
|
|
|
// set the new property value for property
|
|
hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, pwszRListProp, dwRListPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
done:
|
|
if (pwszTopOrig)
|
|
{
|
|
delete [] pwszTopOrig;
|
|
}
|
|
|
|
if (pwszRListProp)
|
|
{
|
|
delete [] pwszRListProp;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::DeleteExtensionFileRecord(
|
|
/* [in] */ LPCWSTR wszExFile,
|
|
/* [in] */ LPCWSTR wszPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WCHAR *pwszRListProp = NULL;
|
|
WCHAR *pwszOrig = NULL;
|
|
WCHAR *pTopOrig = NULL;
|
|
DWORD dwRListPropSz = 0;
|
|
DWORD dwFileNameSz = 0;
|
|
bool bFound = false;
|
|
|
|
// compute arg length
|
|
dwFileNameSz = (DWORD)wcslen(wszExFile);
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for applicationdep list
|
|
hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
// remove the application
|
|
|
|
// copy the property
|
|
pwszOrig = new WCHAR[dwRListPropSz];
|
|
pTopOrig = pwszOrig;
|
|
|
|
if (!pwszOrig)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
memcpy(pwszOrig, pwszRListProp, dwRListPropSz * sizeof(WCHAR));
|
|
|
|
dwRListPropSz = 1; //reset size to contain one for the last null
|
|
WCHAR* pMidBuf = pwszRListProp;
|
|
|
|
// copy the old apps one by one
|
|
while (pwszOrig[0])
|
|
{
|
|
DWORD dwTokSz = (DWORD)wcslen(pwszOrig) + 1;
|
|
|
|
// check to see if we're at the right file
|
|
// look past the bool(1) + comma(sizof_comma_char)
|
|
DWORD dwTemp = (DWORD)sizeof(COMMA_CHAR) / (DWORD)sizeof(WCHAR);
|
|
if (!_wcsnicmp(wszExFile, &pwszOrig[1 + dwTemp], dwFileNameSz) &&
|
|
pwszOrig[dwFileNameSz + dwTemp + 1] == COMMA_CHAR)
|
|
{
|
|
bFound = true;
|
|
|
|
// we don't want to do this... spec change in progress
|
|
// check if this is deletable or not - if not, bail with an error
|
|
//if (pwszOrig[dwFileNameSz + 1 + (2 * dwTemp)] == ZERO_CHAR)
|
|
//{
|
|
// BAIL_ON_FAILURE(hr = E_FAIL);
|
|
//}
|
|
}
|
|
else
|
|
{
|
|
// copy it in
|
|
wcscpy(pMidBuf, pwszOrig);
|
|
pMidBuf += dwTokSz; // advance past null
|
|
*pMidBuf = 0; // add the last null
|
|
dwRListPropSz += dwTokSz;
|
|
}
|
|
pwszOrig += dwTokSz; // go to the next part of the multisz
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
|
|
}
|
|
|
|
// set the new property value for property
|
|
if (dwRListPropSz < 3)
|
|
{
|
|
// handle deleting the last one
|
|
hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, NULL, 0);
|
|
}
|
|
else
|
|
{
|
|
hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, pwszRListProp, dwRListPropSz);
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
done:
|
|
if (pTopOrig)
|
|
{
|
|
delete [] pTopOrig;
|
|
}
|
|
|
|
if (pwszRListProp)
|
|
{
|
|
delete [] pwszRListProp;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSecConLib::ListExtensionFiles(
|
|
/* [in] */ LPCWSTR wszPath,
|
|
/* [out] */ WCHAR **pszBuffer, // MULTI_SZ - allocated in here, caller should delete
|
|
/* [out] */ DWORD *pdwBufferSize) // length includes double null
|
|
{
|
|
WCHAR *pwszRListProp = NULL;
|
|
DWORD dwRListPropSz = 0;
|
|
WCHAR *pList = NULL;
|
|
WCHAR *pTempList = NULL;
|
|
DWORD dwListLen = 1; // one for the extra null at the end
|
|
DWORD dwOldListLen = 1;
|
|
HRESULT hr = S_OK;
|
|
WCHAR *pTop = NULL;
|
|
|
|
hr = InternalInitIfNecessary();
|
|
if (FAILED(hr))
|
|
{
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
// get the current property value for applicationdep list
|
|
hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (NULL == pwszRListProp)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
pTop = pwszRListProp;
|
|
|
|
// iterate through the files
|
|
while (pwszRListProp[0])
|
|
{
|
|
pwszRListProp += 1 + ((DWORD)sizeof(COMMA_CHAR)/(DWORD)sizeof(WCHAR));
|
|
|
|
WCHAR* pMidBuf = wcschr(pwszRListProp, COMMA_CHAR);
|
|
if (pMidBuf)
|
|
{
|
|
// null the comma and go past it
|
|
*pMidBuf = 0;
|
|
*pMidBuf++;
|
|
|
|
// allocate the memory
|
|
dwListLen += (DWORD)wcslen(pwszRListProp) + 1; // for the null
|
|
pTempList = new WCHAR[dwListLen];
|
|
|
|
if (!pTempList)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (pList)
|
|
{
|
|
// copy the previous list
|
|
memcpy(pTempList, pList, dwOldListLen * sizeof(WCHAR));
|
|
delete [] pList;
|
|
}
|
|
|
|
// copy on the file name
|
|
wcscpy(&pTempList[dwOldListLen - 1], pwszRListProp);
|
|
pTempList[dwListLen-1] = 0;
|
|
pTempList[dwListLen-2] = 0;
|
|
|
|
pList = pTempList;
|
|
dwOldListLen = dwListLen;
|
|
}
|
|
else
|
|
{
|
|
pMidBuf = pwszRListProp + (DWORD)wcslen(pwszRListProp) + 1;
|
|
}
|
|
// now go to the next application
|
|
pwszRListProp = pMidBuf + (DWORD)wcslen(pMidBuf) + 1;
|
|
}
|
|
|
|
if (!pList)
|
|
{
|
|
// make it a valid empty multisz
|
|
dwListLen = 2;
|
|
pList = new WCHAR[dwListLen];
|
|
if (!pList)
|
|
{
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
wmemset(pList, 0, dwListLen);
|
|
}
|
|
|
|
*pszBuffer = pList;
|
|
*pdwBufferSize = dwListLen;
|
|
|
|
done:
|
|
if (pTop)
|
|
{
|
|
delete [] pTop;
|
|
}
|
|
|
|
return hr;
|
|
}
|