|
|
//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000.
//
// File: filters-r.c
//
// Contents: Filter management for registry.
//
//
// History: KrishnaG.
// AbhisheV.
//
//----------------------------------------------------------------------------
#include "precomp.h"
extern LPWSTR FilterDNAttributes[];
DWORD RegEnumFilterData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_FILTER_DATA ** pppIpsecFilterData, PDWORD pdwNumFilterObjects ) { DWORD dwError = 0; PIPSEC_FILTER_OBJECT * ppIpsecFilterObjects = NULL; PIPSEC_FILTER_DATA pIpsecFilterData = NULL; PIPSEC_FILTER_DATA * ppIpsecFilterData = NULL; DWORD dwNumFilterObjects = 0; DWORD i = 0; DWORD j = 0;
dwError = RegEnumFilterObjects( hRegistryKey, pszIpsecRootContainer, &ppIpsecFilterObjects, &dwNumFilterObjects ); BAIL_ON_WIN32_ERROR(dwError);
if (dwNumFilterObjects) { ppIpsecFilterData = (PIPSEC_FILTER_DATA *) AllocPolMem( dwNumFilterObjects*sizeof(PIPSEC_FILTER_DATA) ); if (!ppIpsecFilterData) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } }
for (i = 0; i < dwNumFilterObjects; i++) {
dwError = RegUnmarshallFilterData( *(ppIpsecFilterObjects + i), &pIpsecFilterData ); if (!dwError) { *(ppIpsecFilterData + j) = pIpsecFilterData; j++; } }
if (j == 0) { if (ppIpsecFilterData) { FreePolMem(ppIpsecFilterData); ppIpsecFilterData = NULL; } }
*pppIpsecFilterData = ppIpsecFilterData; *pdwNumFilterObjects = j;
dwError = ERROR_SUCCESS;
cleanup:
if (ppIpsecFilterObjects) { FreeIpsecFilterObjects( ppIpsecFilterObjects, dwNumFilterObjects ); }
return(dwError);
error:
if (ppIpsecFilterData) { FreeMulIpsecFilterData( ppIpsecFilterData, i ); }
*pppIpsecFilterData = NULL; *pdwNumFilterObjects = 0;
goto cleanup;
}
DWORD RegEnumFilterObjects( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_FILTER_OBJECT ** pppIpsecFilterObjects, PDWORD pdwNumFilterObjects ) {
DWORD dwError = 0; DWORD i = 0; DWORD dwCount = 0; PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL; PIPSEC_FILTER_OBJECT * ppIpsecFilterObjects = NULL;
DWORD dwNumFilterObjectsReturned = 0; DWORD dwIndex = 0; WCHAR szFilterName[MAX_PATH]; DWORD dwSize = 0;
*pppIpsecFilterObjects = NULL; *pdwNumFilterObjects = 0;
while (1) {
dwSize = MAX_PATH; szFilterName[0] = L'\0';
dwError = RegEnumKeyExW( hRegistryKey, dwIndex, szFilterName, &dwSize, NULL, NULL, 0, 0 ); if (dwError == ERROR_NO_MORE_ITEMS) { break; } BAIL_ON_WIN32_ERROR(dwError);
if (!wcsstr(szFilterName, L"ipsecFilter")) { dwIndex++; continue; }
pIpsecFilterObject = NULL;
dwError =UnMarshallRegistryFilterObject( hRegistryKey, pszIpsecRootContainer, szFilterName, REG_RELATIVE_NAME, &pIpsecFilterObject ); if (dwError == ERROR_SUCCESS) {
dwError = ReallocatePolMem( (LPVOID *) &ppIpsecFilterObjects, sizeof(PIPSEC_FILTER_OBJECT)*(dwNumFilterObjectsReturned), sizeof(PIPSEC_FILTER_OBJECT)*(dwNumFilterObjectsReturned + 1) ); BAIL_ON_WIN32_ERROR(dwError);
*(ppIpsecFilterObjects + dwNumFilterObjectsReturned) = pIpsecFilterObject;
dwNumFilterObjectsReturned++;
}
dwIndex++;
}
*pppIpsecFilterObjects = ppIpsecFilterObjects; *pdwNumFilterObjects = dwNumFilterObjectsReturned;
dwError = ERROR_SUCCESS;
return(dwError);
error:
if (ppIpsecFilterObjects) { FreeIpsecFilterObjects( ppIpsecFilterObjects, dwNumFilterObjectsReturned ); }
if (pIpsecFilterObject) { FreeIpsecFilterObject( pIpsecFilterObject ); }
*pppIpsecFilterObjects = NULL; *pdwNumFilterObjects = 0;
return(dwError); }
DWORD RegSetFilterData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, LPWSTR pszLocationName, PIPSEC_FILTER_DATA pIpsecFilterData ) { DWORD dwError = 0; PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL;
dwError = RegMarshallFilterObject( pIpsecFilterData, &pIpsecFilterObject ); BAIL_ON_WIN32_ERROR(dwError);
dwError = RegSetFilterObject( hRegistryKey, pszIpsecRootContainer, pIpsecFilterObject ); BAIL_ON_WIN32_ERROR(dwError);
dwError = RegBackPropIncChangesForFilterToNFA( hRegistryKey, pszIpsecRootContainer, pszLocationName, pIpsecFilterObject ); BAIL_ON_WIN32_ERROR(dwError);
error:
if (pIpsecFilterObject) { FreeIpsecFilterObject(pIpsecFilterObject); }
return(dwError); }
DWORD RegSetFilterObject( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_FILTER_OBJECT pIpsecFilterObject ) { DWORD dwError = 0;
dwError = PersistFilterObject( hRegistryKey, pIpsecFilterObject ); BAIL_ON_WIN32_ERROR(dwError);
error:
return(dwError); }
DWORD RegCreateFilterData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_FILTER_DATA pIpsecFilterData ) { DWORD dwError = 0; PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL;
dwError = RegMarshallFilterObject( pIpsecFilterData, &pIpsecFilterObject ); BAIL_ON_WIN32_ERROR(dwError);
dwError = RegCreateFilterObject( hRegistryKey, pszIpsecRootContainer, pIpsecFilterObject ); BAIL_ON_WIN32_ERROR(dwError);
error:
if (pIpsecFilterObject) { FreeIpsecFilterObject( pIpsecFilterObject ); }
return(dwError); }
DWORD RegCreateFilterObject( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_FILTER_OBJECT pIpsecFilterObject ) {
DWORD dwError = 0;
dwError = PersistFilterObject( hRegistryKey, pIpsecFilterObject ); BAIL_ON_WIN32_ERROR(dwError);
error:
return(dwError); }
DWORD RegDeleteFilterData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, GUID FilterIdentifier ) { DWORD dwError = ERROR_SUCCESS; WCHAR szGuid[MAX_PATH]; WCHAR szDistinguishedName[MAX_PATH]; LPWSTR pszStringUuid = NULL;
szGuid[0] = L'\0'; szDistinguishedName[0] = L'\0';
dwError = UuidToString( &FilterIdentifier, &pszStringUuid ); BAIL_ON_WIN32_ERROR(dwError); wcscpy(szGuid, L"{"); wcscat(szGuid, pszStringUuid); wcscat(szGuid, L"}");
wcscpy(szDistinguishedName,L"ipsecFilter"); wcscat(szDistinguishedName, szGuid);
dwError = RegDeleteKeyW( hRegistryKey, szDistinguishedName ); BAIL_ON_WIN32_ERROR(dwError);
error:
if (pszStringUuid) { RpcStringFree(&pszStringUuid); }
return(dwError); }
DWORD RegUnmarshallFilterData( PIPSEC_FILTER_OBJECT pIpsecFilterObject, PIPSEC_FILTER_DATA * ppIpsecFilterData ) { DWORD dwError = 0;
dwError = UnmarshallFilterObject( pIpsecFilterObject, ppIpsecFilterData );
return(dwError); }
DWORD RegMarshallFilterObject( PIPSEC_FILTER_DATA pIpsecFilterData, PIPSEC_FILTER_OBJECT * ppIpsecFilterObject ) { DWORD dwError = 0; PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL; WCHAR szGuid[MAX_PATH]; WCHAR szDistinguishedName[MAX_PATH]; LPBYTE pBuffer = NULL; DWORD dwBufferLen = 0; LPWSTR pszStringUuid = NULL; time_t PresentTime;
szGuid[0] = L'\0'; szDistinguishedName[0] = L'\0'; pIpsecFilterObject = (PIPSEC_FILTER_OBJECT)AllocPolMem( sizeof(IPSEC_FILTER_OBJECT) ); if (!pIpsecFilterObject) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); }
dwError = UuidToString( &pIpsecFilterData->FilterIdentifier, &pszStringUuid ); BAIL_ON_WIN32_ERROR(dwError); wcscpy(szGuid, L"{"); wcscat(szGuid, pszStringUuid); wcscat(szGuid, L"}");
//
// Fill in the distinguishedName
//
wcscpy(szDistinguishedName,L"ipsecFilter"); wcscat(szDistinguishedName, szGuid); pIpsecFilterObject->pszDistinguishedName = AllocPolStr( szDistinguishedName ); if (!pIpsecFilterObject->pszDistinguishedName) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); }
//
// Fill in the ipsecName
//
if (pIpsecFilterData->pszIpsecName && *pIpsecFilterData->pszIpsecName) { pIpsecFilterObject->pszIpsecName = AllocPolStr( pIpsecFilterData->pszIpsecName ); if (!pIpsecFilterObject->pszIpsecName) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } }
if (pIpsecFilterData->pszDescription && *pIpsecFilterData->pszDescription) { pIpsecFilterObject->pszDescription = AllocPolStr( pIpsecFilterData->pszDescription ); if (!pIpsecFilterObject->pszDescription) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } }
//
// Fill in the ipsecID
//
pIpsecFilterObject->pszIpsecID = AllocPolStr( szGuid ); if (!pIpsecFilterObject->pszIpsecID) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); }
//
// Fill in the ipsecDataType
//
pIpsecFilterObject->dwIpsecDataType = 0x100;
//
// Marshall the pIpsecDataBuffer and the Length
//
dwError = MarshallFilterBuffer( pIpsecFilterData, &pBuffer, &dwBufferLen ); BAIL_ON_WIN32_ERROR(dwError);
pIpsecFilterObject->pIpsecData = pBuffer;
pIpsecFilterObject->dwIpsecDataLen = dwBufferLen;
time(&PresentTime);
pIpsecFilterObject->dwWhenChanged = (DWORD) PresentTime;
*ppIpsecFilterObject = pIpsecFilterObject;
cleanup:
if (pszStringUuid) { RpcStringFree( &pszStringUuid ); }
return(dwError);
error:
if (pIpsecFilterObject) { FreeIpsecFilterObject( pIpsecFilterObject ); }
*ppIpsecFilterObject = NULL; goto cleanup; }
DWORD MarshallFilterBuffer( PIPSEC_FILTER_DATA pIpsecFilterData, LPBYTE * ppBuffer, DWORD * pdwBufferLen ) { LPBYTE pMem = NULL; DWORD dwNumFilterSpecs = 0; PIPSEC_FILTER_SPEC * ppIpsecFilterSpecs = NULL; PIPSEC_FILTER_SPEC pIpsecFilterSpec = NULL; DWORD i = 0; DWORD dwNumBytesAdvanced = 0; DWORD dwError = 0; LPBYTE pBuffer = NULL; LPBYTE pCurrentPos = NULL; PSPEC_BUFFER pSpecBuffer = NULL; DWORD dwSpecSize = 0; DWORD dwTotalSize = 0; DWORD dwEffectiveSize = 0;
// {80DC20B5-2EC8-11d1-A89E-00A0248D3021}
static const GUID GUID_IPSEC_FILTER_BLOB = { 0x80dc20b5, 0x2ec8, 0x11d1, { 0xa8, 0x9e, 0x0, 0xa0, 0x24, 0x8d, 0x30, 0x21 } };
//
// Advance by the GUID
//
dwTotalSize += sizeof(GUID);
//
// Advance by a DWORD - Total size of the buffer.
//
dwTotalSize += sizeof(DWORD);
//
// Advance by a DWORD - this is dwNumFilterSpecs;
//
dwTotalSize += sizeof(DWORD);
dwNumFilterSpecs = pIpsecFilterData->dwNumFilterSpecs;
pSpecBuffer = (PSPEC_BUFFER)AllocPolMem( sizeof(SPEC_BUFFER)*dwNumFilterSpecs ); if (!pSpecBuffer) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); }
for (i = 0; i < dwNumFilterSpecs;i++){
dwError = MarshallFilterSpecBuffer( *(pIpsecFilterData->ppFilterSpecs + i), &pMem, &dwSpecSize ); BAIL_ON_WIN32_ERROR(dwError);
dwTotalSize += dwSpecSize;
//
// Fill in the spec size information
//
(pSpecBuffer + i)->dwSize = dwSpecSize; (pSpecBuffer + i)->pMem = pMem;
}
dwTotalSize++;
pBuffer = AllocPolMem(dwTotalSize); if (!pBuffer) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } pCurrentPos = pBuffer;
//
// Copy the GUID
//
memcpy(pCurrentPos, &GUID_IPSEC_FILTER_BLOB, sizeof(GUID)); pCurrentPos += sizeof(GUID);
dwEffectiveSize = dwTotalSize - sizeof(GUID) - sizeof(DWORD) - 1;
memcpy(pCurrentPos, &dwEffectiveSize, sizeof(DWORD)); pCurrentPos += sizeof(DWORD);
memcpy(pCurrentPos, &dwNumFilterSpecs, sizeof(DWORD)); pCurrentPos += sizeof(DWORD);
for (i = 0; i < dwNumFilterSpecs; i++) {
pMem = (pSpecBuffer + i)->pMem; dwSpecSize = (pSpecBuffer + i)->dwSize;
memcpy(pCurrentPos, pMem, dwSpecSize); pCurrentPos += dwSpecSize;
}
*ppBuffer = pBuffer; *pdwBufferLen = dwTotalSize;
cleanup:
if (pSpecBuffer) { FreeSpecBuffer( pSpecBuffer, dwNumFilterSpecs ); }
return(dwError);
error:
if (pBuffer) { FreePolMem(pBuffer); }
*ppBuffer = NULL; *pdwBufferLen = 0;
goto cleanup; }
DWORD MarshallFilterSpecBuffer( PIPSEC_FILTER_SPEC pIpsecFilterSpec, LPBYTE * ppMem, DWORD * pdwSize ) { DWORD dwSrcDNSNameLen = 0; DWORD dwDestDNSNameLen = 0; DWORD dwDescriptionLen = 0;
LPBYTE pMem = NULL; LPBYTE pCurrentPos = NULL;
DWORD dwSize = 0; DWORD dwError = 0;
dwSize += sizeof(DWORD);
if (pIpsecFilterSpec->pszSrcDNSName && *pIpsecFilterSpec->pszSrcDNSName) { dwSrcDNSNameLen = (wcslen(pIpsecFilterSpec->pszSrcDNSName) + 1) *sizeof(WCHAR); } else { dwSrcDNSNameLen = sizeof(WCHAR); }
if (dwSrcDNSNameLen) { dwSize += dwSrcDNSNameLen; }
dwSize += sizeof(DWORD);
if (pIpsecFilterSpec->pszDestDNSName && *pIpsecFilterSpec->pszDestDNSName) { dwDestDNSNameLen = (wcslen(pIpsecFilterSpec->pszDestDNSName) + 1) *sizeof(WCHAR); } else { dwDestDNSNameLen = sizeof(WCHAR); }
if (dwDestDNSNameLen) { dwSize += dwDestDNSNameLen; }
dwSize += sizeof(DWORD);
if (pIpsecFilterSpec->pszDescription && *pIpsecFilterSpec->pszDescription) { dwDescriptionLen = (wcslen(pIpsecFilterSpec->pszDescription) + 1) *sizeof(WCHAR); } else { dwDescriptionLen = sizeof(WCHAR); }
if (dwDescriptionLen) { dwSize += dwDescriptionLen; }
//
// Filter Spec GUID
//
dwSize += sizeof(GUID);
//
// dwMirrorFlag
//
dwSize += sizeof(DWORD);
dwSize += sizeof(IPSEC_FILTER);
pMem = (LPBYTE)AllocPolMem(dwSize); if (!pMem) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); }
pCurrentPos = pMem;
memcpy(pCurrentPos, &(dwSrcDNSNameLen), sizeof(DWORD)); pCurrentPos += sizeof(DWORD);
if (pIpsecFilterSpec->pszSrcDNSName && *pIpsecFilterSpec->pszSrcDNSName) { memcpy(pCurrentPos, pIpsecFilterSpec->pszSrcDNSName, dwSrcDNSNameLen); } pCurrentPos += dwSrcDNSNameLen;
memcpy(pCurrentPos, &(dwDestDNSNameLen), sizeof(DWORD)); pCurrentPos += sizeof(DWORD);
if (pIpsecFilterSpec->pszDestDNSName && *pIpsecFilterSpec->pszDestDNSName) { memcpy(pCurrentPos, pIpsecFilterSpec->pszDestDNSName, dwDestDNSNameLen); } pCurrentPos += dwDestDNSNameLen;
memcpy(pCurrentPos, &(dwDescriptionLen), sizeof(DWORD)); pCurrentPos += sizeof(DWORD);
if (pIpsecFilterSpec->pszDescription && *pIpsecFilterSpec->pszDescription) { memcpy(pCurrentPos, pIpsecFilterSpec->pszDescription, dwDescriptionLen); } pCurrentPos += dwDescriptionLen;
memcpy(pCurrentPos, &(pIpsecFilterSpec->FilterSpecGUID), sizeof(GUID)); pCurrentPos += sizeof(GUID);
memcpy(pCurrentPos, &(pIpsecFilterSpec->dwMirrorFlag), sizeof(DWORD)); pCurrentPos += sizeof(DWORD);
memcpy(pCurrentPos, &(pIpsecFilterSpec->Filter), sizeof(IPSEC_FILTER));
*ppMem = pMem; *pdwSize = dwSize;
return(dwError);
error:
*ppMem = NULL; *pdwSize = 0; return(dwError); }
DWORD RegGetFilterData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, GUID FilterGUID, PIPSEC_FILTER_DATA * ppIpsecFilterData ) { DWORD dwError = 0; PIPSEC_FILTER_OBJECT pIpsecFilterObject = NULL; PIPSEC_FILTER_DATA pIpsecFilterData = NULL; WCHAR szIpsecFilterName[MAX_PATH]; LPWSTR pszFilterName = NULL;
szIpsecFilterName[0] = L'\0'; wcscpy(szIpsecFilterName, L"ipsecFilter");
dwError = UuidToString(&FilterGUID, &pszFilterName); BAIL_ON_WIN32_ERROR(dwError);
wcscat(szIpsecFilterName, L"{"); wcscat(szIpsecFilterName, pszFilterName); wcscat(szIpsecFilterName, L"}");
dwError =UnMarshallRegistryFilterObject( hRegistryKey, pszIpsecRootContainer, szIpsecFilterName, REG_RELATIVE_NAME, &pIpsecFilterObject ); BAIL_ON_WIN32_ERROR(dwError);
dwError = RegUnmarshallFilterData( pIpsecFilterObject, &pIpsecFilterData ); BAIL_ON_WIN32_ERROR(dwError);
error:
if (pIpsecFilterObject) { FreeIpsecFilterObject( pIpsecFilterObject );
}
if (pszFilterName) { RpcStringFree(&pszFilterName); }
*ppIpsecFilterData = pIpsecFilterData;
return(dwError); }
VOID FreeSpecBuffer( PSPEC_BUFFER pSpecBuffer, DWORD dwNumFilterSpecs ) { DWORD i = 0;
if (pSpecBuffer) { for (i = 0; i < dwNumFilterSpecs; i++) { if ((pSpecBuffer+i)->pMem) { FreePolMem((pSpecBuffer+i)->pMem); } } FreePolMem(pSpecBuffer); }
return; }
|