/*++ Copyright (c) 1999 Microsoft Corporation Module Name: interface.c Abstract: This module contains all of the code to drive the interface list management of IPSecSPD Service. Author: abhisheV 30-September-1999 Environment User Level: Win32 Revision History: --*/ #include "precomp.h" DWORD CreateInterfaceList( OUT PIPSEC_INTERFACE * ppIfListToCreate ) { DWORD dwError = 0; PIPSEC_INTERFACE pIfList = NULL; dwError = GetInterfaceListFromStack( &pIfList ); ENTER_SPD_SECTION(); *ppIfListToCreate = pIfList; LEAVE_SPD_SECTION(); return (dwError); } VOID DestroyInterfaceList( IN PIPSEC_INTERFACE pIfListToDelete ) { PIPSEC_INTERFACE pIf = NULL; PIPSEC_INTERFACE pTempIf = NULL; pIf = pIfListToDelete; while (pIf) { pTempIf = pIf; pIf = pIf->pNext; FreeIpsecInterface(pTempIf); } } DWORD OnInterfaceChangeEvent( ) { DWORD dwError = 0; PIPSEC_INTERFACE pIfList = NULL; PIPSEC_INTERFACE pObseleteIfList = NULL; PIPSEC_INTERFACE pNewIfList = NULL; PIPSEC_INTERFACE pExistingIfList = NULL; DWORD dwMMError = 0; DWORD dwTxError = 0; DWORD dwTnError = 0; dwError = ResetInterfaceChangeEvent(); (VOID) GetInterfaceListFromStack( &pIfList ); ENTER_SPD_SECTION(); pExistingIfList = gpInterfaceList; // Interface List from Stack can be NULL. FormObseleteAndNewIfLists( pIfList, &pExistingIfList, &pObseleteIfList, &pNewIfList ); if (pNewIfList) { AddToInterfaceList( pNewIfList, &pExistingIfList ); } if (pObseleteIfList) { DestroyInterfaceList( pObseleteIfList ); } gpInterfaceList = pExistingIfList; (VOID) ApplyIfChangeToIniMMFilters( &dwMMError, pExistingIfList ); (VOID) ApplyIfChangeToIniTxFilters( &dwTxError, pExistingIfList ); (VOID) ApplyIfChangeToIniTnFilters( &dwTnError, pExistingIfList ); LEAVE_SPD_SECTION(); if (dwMMError || dwTxError || dwTnError) { AuditEvent( SE_CATEGID_POLICY_CHANGE, SE_AUDITID_IPSEC_POLICY_CHANGED, IPSECSVC_FAILED_PNP_FILTER_PROCESSING, NULL, FALSE, TRUE ); } return (dwError); } VOID FormObseleteAndNewIfLists( IN PIPSEC_INTERFACE pIfList, IN OUT PIPSEC_INTERFACE * ppExistingIfList, OUT PIPSEC_INTERFACE * ppObseleteIfList, OUT PIPSEC_INTERFACE * ppNewIfList ) { PIPSEC_INTERFACE pObseleteIfList = NULL; PIPSEC_INTERFACE pNewIfList = NULL; PIPSEC_INTERFACE pIf = NULL; PIPSEC_INTERFACE pNewIf = NULL; PIPSEC_INTERFACE pTempIf = NULL; BOOL bInterfaceExists = FALSE; PIPSEC_INTERFACE pExistingIf = NULL; PIPSEC_INTERFACE pExistingIfList = NULL; pExistingIfList = *ppExistingIfList; MarkInterfaceListSuspect( pExistingIfList ); pIf = pIfList; while (pIf) { bInterfaceExists = InterfaceExistsInList( pIf, pExistingIfList, &pExistingIf ); if (bInterfaceExists) { // Interface already exists in the list. // Delete the interface. pTempIf = pIf; pIf = pIf->pNext; FreeIpsecInterface(pTempIf); // The corresponding entry in the original interface list // is not a suspect any more. pExistingIf->bIsASuspect = FALSE; } else { // This is a new interface. // Add it to the list of new interfaces. pNewIf = pIf; pIf = pIf->pNext; pTempIf = pNewIfList; pNewIfList = pNewIf; pNewIfList->pNext = pTempIf; } } DeleteObseleteInterfaces( &pExistingIfList, &pObseleteIfList ); *ppExistingIfList = pExistingIfList; *ppObseleteIfList = pObseleteIfList; *ppNewIfList = pNewIfList; } VOID AddToInterfaceList( IN PIPSEC_INTERFACE pIfListToAppend, OUT PIPSEC_INTERFACE * ppOriginalIfList ) { PIPSEC_INTERFACE pIf = NULL; PIPSEC_INTERFACE pIfToAppend = NULL; PIPSEC_INTERFACE pTempIf = NULL; pIf = pIfListToAppend; while (pIf) { pIfToAppend = pIf; pIf = pIf->pNext; pTempIf = *ppOriginalIfList; *ppOriginalIfList = pIfToAppend; (*ppOriginalIfList)->pNext = pTempIf; } } VOID MarkInterfaceListSuspect( IN PIPSEC_INTERFACE pExistingIfList ) { PIPSEC_INTERFACE pIf = NULL; pIf = pExistingIfList; while (pIf) { pIf->bIsASuspect = TRUE; pIf = pIf->pNext; } } VOID DeleteObseleteInterfaces( IN OUT PIPSEC_INTERFACE * ppExistingIfList, OUT PIPSEC_INTERFACE * ppObseleteIfList ) { PIPSEC_INTERFACE pCurIf = NULL; PIPSEC_INTERFACE pPreIf = NULL; PIPSEC_INTERFACE pStartIf = NULL; PIPSEC_INTERFACE pObseleteIfList = NULL; PIPSEC_INTERFACE pObseleteIf = NULL; PIPSEC_INTERFACE pTempIf = NULL; pCurIf = *ppExistingIfList; pStartIf = pCurIf; while (pCurIf) { if (pCurIf->bIsASuspect) { pObseleteIf = pCurIf; pCurIf = pCurIf->pNext; if (pPreIf) { pPreIf->pNext = pCurIf; } else { pStartIf = pCurIf; } pTempIf = pObseleteIfList; pObseleteIfList = pObseleteIf; pObseleteIfList->pNext = pTempIf; } else { pPreIf = pCurIf; pCurIf = pCurIf->pNext; } } *ppObseleteIfList = pObseleteIfList; *ppExistingIfList = pStartIf; } BOOL InterfaceExistsInList( IN PIPSEC_INTERFACE pTestIf, IN PIPSEC_INTERFACE pExistingIfList, OUT PIPSEC_INTERFACE * ppExistingIf ) { PIPSEC_INTERFACE pIf = NULL; PIPSEC_INTERFACE pExistingIf = NULL; BOOL bIfExists = FALSE; pIf = pExistingIfList; while (pIf) { if ((pIf->dwIndex == pTestIf->dwIndex) && (pIf->IpAddress == pTestIf->IpAddress)) { bIfExists = TRUE; pExistingIf = pIf; break; } pIf = pIf->pNext; } *ppExistingIf = pExistingIf; return (bIfExists); } DWORD GetInterfaceListFromStack( OUT PIPSEC_INTERFACE *ppIfList ) { DWORD dwError = 0; PMIB_IPADDRTABLE pMibIpAddrTable = NULL; PMIB_IFTABLE pMibIfTable = NULL; PIPSEC_INTERFACE pIfList = NULL; dwError = PaPNPGetIpAddrTable( &pMibIpAddrTable ); BAIL_ON_WIN32_ERROR(dwError); dwError = PaPNPGetIfTable( &pMibIfTable ); BAIL_ON_WIN32_ERROR(dwError); dwError = GenerateInterfaces( pMibIpAddrTable, pMibIfTable, &pIfList ); BAIL_ON_WIN32_ERROR(dwError); *ppIfList = pIfList; cleanup: if (pMibIfTable) { LocalFree(pMibIfTable); } if (pMibIpAddrTable) { LocalFree(pMibIpAddrTable); } return (dwError); error: AuditEvent( SE_CATEGID_POLICY_CHANGE, SE_AUDITID_IPSEC_POLICY_CHANGED, IPSECSVC_INTERFACE_LIST_INCOMPLETE, NULL, FALSE, TRUE ); *ppIfList = NULL; goto cleanup; } DWORD GenerateInterfaces( IN PMIB_IPADDRTABLE pMibIpAddrTable, IN PMIB_IFTABLE pMibIfTable, OUT PIPSEC_INTERFACE * ppIfList ) { DWORD dwError = 0; DWORD dwInterfaceType = 0; ULONG IpAddress = 0; DWORD dwIndex = 0; DWORD dwNumEntries = 0; DWORD dwCnt = 0; PMIB_IFROW pMibIfRow = NULL; PIPSEC_INTERFACE pNewIf = NULL; PIPSEC_INTERFACE pTempIf = NULL; PIPSEC_INTERFACE pIfList = NULL; DWORD dwNewIfsCnt = 0; dwNumEntries = pMibIpAddrTable->dwNumEntries; for (dwCnt = 0; dwCnt < dwNumEntries; dwCnt++) { dwIndex = pMibIpAddrTable->table[dwCnt].dwIndex; pMibIfRow = GetMibIfRow( pMibIfTable, dwIndex ); if (!pMibIfRow) { continue; } IpAddress = pMibIpAddrTable->table[dwCnt].dwAddr; dwInterfaceType = pMibIfRow->dwType; dwError = CreateNewInterface( dwInterfaceType, IpAddress, dwIndex, pMibIfRow, &pNewIf ); if (dwError) { continue; } pTempIf = pIfList; pIfList = pNewIf; pIfList->pNext = pTempIf; dwNewIfsCnt++; } if (dwNewIfsCnt) { *ppIfList = pIfList; dwError = ERROR_SUCCESS; } else { *ppIfList = NULL; dwError = ERROR_INVALID_DATA; } return (dwError); } PMIB_IFROW GetMibIfRow( IN PMIB_IFTABLE pMibIfTable, IN DWORD dwIndex ) { DWORD i = 0; PMIB_IFROW pMibIfRow = NULL; for (i = 0; i < pMibIfTable->dwNumEntries; i++) { if (pMibIfTable->table[i].dwIndex == dwIndex) { pMibIfRow = &(pMibIfTable->table[i]); break; } } return (pMibIfRow); } DWORD CreateNewInterface( IN DWORD dwInterfaceType, IN ULONG IpAddress, IN DWORD dwIndex, IN PMIB_IFROW pMibIfRow, OUT PIPSEC_INTERFACE * ppNewInterface ) { DWORD dwError = 0; PIPSEC_INTERFACE pNewInterface = NULL; LPWSTR pszString = NULL; LPWSTR pszTemp = NULL; WCHAR szDeviceName[MAXLEN_IFDESCR*sizeof(WCHAR)]; GUID gInterfaceID; szDeviceName[0] = L'\0'; if (IpAddress == INADDR_ANY) { dwError = ERROR_INVALID_DATA; BAIL_ON_WIN32_ERROR(dwError); } else { if (dwInterfaceType == MIB_IF_TYPE_LOOPBACK) { dwError = ERROR_INVALID_DATA; BAIL_ON_WIN32_ERROR(dwError); } } pszString = AllocSPDStr(pMibIfRow->wszName); if (!pszString) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } if (wcslen(pszString) <= wcslen(L"\\DEVICE\\TCPIP_")) { dwError = ERROR_INVALID_DATA; BAIL_ON_WIN32_ERROR(dwError); } pszTemp = pszString + wcslen(L"\\DEVICE\\TCPIP_"); wGUIDFromString(pszTemp, &gInterfaceID); pNewInterface = (PIPSEC_INTERFACE) AllocSPDMem( sizeof(IPSEC_INTERFACE) ); if (!pNewInterface) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } pNewInterface->dwInterfaceType = dwInterfaceType; pNewInterface->IpAddress = IpAddress; pNewInterface->dwIndex = dwIndex; pNewInterface->bIsASuspect = FALSE; memcpy( &pNewInterface->gInterfaceID, &gInterfaceID, sizeof(GUID) ); pNewInterface->pszInterfaceName = NULL; mbstowcs( szDeviceName, pMibIfRow->bDescr, MAXLEN_IFDESCR ); pNewInterface->pszDeviceName = AllocSPDStr( szDeviceName ); if (!pNewInterface->pszDeviceName) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } pNewInterface->pNext = NULL; *ppNewInterface = pNewInterface; cleanup: if (pszString) { FreeSPDStr(pszString); } return(dwError); error: *ppNewInterface = NULL; if (pNewInterface) { FreeIpsecInterface(pNewInterface); } goto cleanup; } BOOL MatchInterfaceType( IN DWORD dwIfListEntryIfType, IN IF_TYPE FilterIfType ) { BOOL bMatchesType = FALSE; if (FilterIfType == INTERFACE_TYPE_ALL) { bMatchesType = TRUE; } else if (FilterIfType == INTERFACE_TYPE_LAN) { bMatchesType = IsLAN(dwIfListEntryIfType); } else if (FilterIfType == INTERFACE_TYPE_DIALUP) { bMatchesType = IsDialUp(dwIfListEntryIfType); } return (bMatchesType); } BOOL IsLAN( IN DWORD dwInterfaceType ) { BOOL bIsLAN = FALSE; if ((dwInterfaceType == MIB_IF_TYPE_ETHERNET) || (dwInterfaceType == MIB_IF_TYPE_FDDI) || (dwInterfaceType == MIB_IF_TYPE_TOKENRING)) { bIsLAN = TRUE; } return (bIsLAN); } BOOL IsDialUp( IN DWORD dwInterfaceType ) { BOOL bIsDialUp = FALSE; if ((dwInterfaceType == MIB_IF_TYPE_PPP) || (dwInterfaceType == MIB_IF_TYPE_SLIP)) { bIsDialUp = TRUE; } return (bIsDialUp); } DWORD InitializeInterfaceChangeEvent( ) { DWORD dwError = 0; WORD wsaVersion = MAKEWORD(2,0); memset(&gwsaOverlapped, 0, sizeof(WSAOVERLAPPED)); // Start up WinSock. dwError = WSAStartup( wsaVersion, &gwsaData ); BAIL_ON_WIN32_ERROR(dwError); gbwsaStarted = TRUE; if ((LOBYTE(gwsaData.wVersion) != LOBYTE(wsaVersion)) || (HIBYTE(gwsaData.wVersion) != HIBYTE(wsaVersion))) { dwError = WSAVERNOTSUPPORTED; BAIL_ON_WIN32_ERROR(dwError); } // Set up the Socket. gIfChangeEventSocket = WSASocket( AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED ); if (gIfChangeEventSocket == INVALID_SOCKET) { dwError = WSAGetLastError(); BAIL_ON_WIN32_ERROR(dwError); } ghIfChangeEvent = WSACreateEvent(); if (ghIfChangeEvent == WSA_INVALID_EVENT) { dwError = WSAGetLastError(); BAIL_ON_WIN32_ERROR(dwError); } ghOverlapEvent = WSACreateEvent(); if (ghOverlapEvent == WSA_INVALID_EVENT) { dwError = WSAGetLastError(); BAIL_ON_WIN32_ERROR(dwError); } gwsaOverlapped.hEvent = ghOverlapEvent; error: return (dwError); } DWORD ResetInterfaceChangeEvent( ) { DWORD dwError = 0; LONG lNetworkEvents = FD_ADDRESS_LIST_CHANGE; DWORD dwOutSize = 0; ResetEvent(ghIfChangeEvent); gbIsIoctlPended = FALSE; dwError = WSAIoctl( gIfChangeEventSocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &dwOutSize, &gwsaOverlapped, NULL ); if (dwError == SOCKET_ERROR) { dwError = WSAGetLastError(); if (dwError != ERROR_IO_PENDING) { return (dwError); } else { gbIsIoctlPended = TRUE; } } dwError = WSAEventSelect( gIfChangeEventSocket, ghIfChangeEvent, lNetworkEvents ); return (dwError); } VOID DestroyInterfaceChangeEvent( ) { DWORD dwStatus = 0; BOOL bDoneWaiting = FALSE; if (gIfChangeEventSocket) { if (gbIsIoctlPended) { CancelIo((HANDLE) gIfChangeEventSocket); while (!bDoneWaiting) { dwStatus = WaitForSingleObject( ghOverlapEvent, 1000 ); switch (dwStatus) { case WAIT_OBJECT_0: bDoneWaiting = TRUE; break; case WAIT_TIMEOUT: ASSERT(FALSE); break; default: bDoneWaiting = TRUE; ASSERT(FALSE); break; } } } closesocket(gIfChangeEventSocket); } if (ghIfChangeEvent) { CloseHandle(ghIfChangeEvent); } if (ghOverlapEvent) { CloseHandle(ghOverlapEvent); } if (gbwsaStarted) { WSACleanup(); } } HANDLE GetInterfaceChangeEvent( ) { return ghOverlapEvent; } BOOL IsMyAddress( IN ULONG IpAddrToCheck, IN ULONG IpAddrMask, IN PIPSEC_INTERFACE pExistingIfList ) { BOOL bIsMyAddress = FALSE; PIPSEC_INTERFACE pIf = NULL; pIf = pExistingIfList; while (pIf) { if ((pIf->IpAddress & IpAddrMask) == (IpAddrToCheck & IpAddrMask)) { bIsMyAddress = TRUE; break; } pIf = pIf->pNext; } return (bIsMyAddress); } VOID PrintInterfaceList( IN PIPSEC_INTERFACE pInterfaceList ) { WCHAR PrintData[256]; PIPSEC_INTERFACE pInterface = NULL; DWORD i = 0; pInterface = pInterfaceList; while (pInterface) { wsprintf(PrintData, L"Interface Entry no. %d\n", i+1); OutputDebugString((LPCTSTR) PrintData); wsprintf(PrintData, L"\tInterface Type: %d\n", pInterface->dwInterfaceType); OutputDebugString((LPCTSTR) PrintData); wsprintf(PrintData, L"\tIP Address: %s\n", pInterface->IpAddress); OutputDebugString((LPCTSTR) PrintData); wsprintf(PrintData, L"\tIndex: %d\n", pInterface->dwIndex); OutputDebugString((LPCTSTR) PrintData); wsprintf(PrintData, L"\tIs a suspect: %d\n", pInterface->bIsASuspect); OutputDebugString((LPCTSTR) PrintData); i++; pInterface = pInterface->pNext; } } DWORD GetMatchingInterfaces( IF_TYPE FilterInterfaceType, PIPSEC_INTERFACE pExistingIfList, MATCHING_ADDR ** ppMatchingAddresses, DWORD * pdwAddrCnt ) { DWORD dwError = 0; MATCHING_ADDR * pMatchingAddresses = NULL; PIPSEC_INTERFACE pTempIf = NULL; BOOL bMatches = FALSE; DWORD dwCnt = 0; DWORD i = 0; pTempIf = pExistingIfList; while (pTempIf) { bMatches = MatchInterfaceType( pTempIf->dwInterfaceType, FilterInterfaceType ); if (bMatches) { dwCnt++; } pTempIf = pTempIf->pNext; } if (!dwCnt) { dwError = ERROR_SUCCESS; BAIL_ON_WIN32_SUCCESS(dwError); } dwError = AllocateSPDMemory( sizeof(MATCHING_ADDR) * dwCnt, (LPVOID *) &pMatchingAddresses ); BAIL_ON_WIN32_ERROR(dwError); pTempIf = pExistingIfList; while (pTempIf) { bMatches = MatchInterfaceType( pTempIf->dwInterfaceType, FilterInterfaceType ); if (bMatches) { pMatchingAddresses[i].uIpAddr = pTempIf->IpAddress; memcpy( &pMatchingAddresses[i].gInterfaceID, &pTempIf->gInterfaceID, sizeof(GUID) ); i++; } pTempIf = pTempIf->pNext; } *ppMatchingAddresses = pMatchingAddresses; *pdwAddrCnt = i; return (dwError); success: error: *ppMatchingAddresses = NULL; *pdwAddrCnt = 0; return (dwError); } BOOL InterfaceAddrIsLocal( ULONG uIpAddr, ULONG uIpAddrMask, MATCHING_ADDR * pLocalAddresses, DWORD dwAddrCnt ) { BOOL bIsLocal = FALSE; DWORD i = 0; for (i = 0; i < dwAddrCnt; i++) { if ((pLocalAddresses[i].uIpAddr & uIpAddrMask) == (uIpAddr & uIpAddrMask)) { bIsLocal = TRUE; break; } } return (bIsLocal); } VOID FreeIpsecInterface( PIPSEC_INTERFACE pIpsecInterface ) { if (pIpsecInterface) { if (pIpsecInterface->pszInterfaceName) { FreeSPDStr(pIpsecInterface->pszInterfaceName); } if (pIpsecInterface->pszDeviceName) { FreeSPDStr(pIpsecInterface->pszDeviceName); } FreeSPDMem(pIpsecInterface); } } DWORD EnumIPSecInterfaces( LPWSTR pServerName, PIPSEC_INTERFACE_INFO pIpsecIfTemplate, PIPSEC_INTERFACE_INFO * ppIpsecInterfaces, DWORD dwPreferredNumEntries, LPDWORD pdwNumInterfaces, LPDWORD pdwNumTotalInterfaces, LPDWORD pdwResumeHandle, DWORD dwFlags ) { DWORD dwError = 0; DWORD dwResumeHandle = 0; DWORD dwNumToEnum = 0; PIPSEC_INTERFACE pIpsecIf = NULL; DWORD dwNumTotalInterfaces = 0; DWORD i = 0; PIPSEC_INTERFACE pTempIf = NULL; DWORD dwNumInterfaces = 0; PIPSEC_INTERFACE_INFO pIpsecInterfaces = NULL; PIPSEC_INTERFACE_INFO pTempInterface = NULL; dwResumeHandle = *pdwResumeHandle; if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_INTERFACE_ENUM_COUNT)) { dwNumToEnum = MAX_INTERFACE_ENUM_COUNT; } else { dwNumToEnum = dwPreferredNumEntries; } ENTER_SPD_SECTION(); dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError); pIpsecIf = gpInterfaceList; for (i = 0; (i < dwResumeHandle) && (pIpsecIf != NULL); i++) { dwNumTotalInterfaces++; pIpsecIf = pIpsecIf->pNext; } if (!pIpsecIf) { dwError = ERROR_NO_DATA; BAIL_ON_LOCK_ERROR(dwError); } pTempIf = pIpsecIf; while (pTempIf && (dwNumInterfaces < dwNumToEnum)) { dwNumTotalInterfaces++; dwNumInterfaces++; pTempIf = pTempIf->pNext; } while (pTempIf) { dwNumTotalInterfaces++; pTempIf = pTempIf->pNext; } dwError = SPDApiBufferAllocate( sizeof(IPSEC_INTERFACE_INFO)*dwNumInterfaces, &pIpsecInterfaces ); BAIL_ON_LOCK_ERROR(dwError); pTempIf = pIpsecIf; pTempInterface = pIpsecInterfaces; for (i = 0; i < dwNumInterfaces; i++) { dwError = CopyIpsecInterface( pTempIf, pTempInterface ); BAIL_ON_LOCK_ERROR(dwError); pTempIf = pTempIf->pNext; pTempInterface++; } *ppIpsecInterfaces = pIpsecInterfaces; *pdwNumInterfaces = dwNumInterfaces; *pdwNumTotalInterfaces = dwNumTotalInterfaces; *pdwResumeHandle = dwResumeHandle + dwNumInterfaces; LEAVE_SPD_SECTION(); return (dwError); lock: LEAVE_SPD_SECTION(); if (pIpsecInterfaces) { FreeIpsecInterfaceInfos( i, pIpsecInterfaces ); } *ppIpsecInterfaces = NULL; *pdwNumInterfaces = 0; *pdwNumTotalInterfaces = 0; *pdwResumeHandle = dwResumeHandle; return (dwError); } DWORD CopyIpsecInterface( PIPSEC_INTERFACE pIpsecIf, PIPSEC_INTERFACE_INFO pIpsecInterface ) { DWORD dwError = 0; memcpy( &(pIpsecInterface->gInterfaceID), &(pIpsecIf->gInterfaceID), sizeof(GUID) ); pIpsecInterface->dwIndex = pIpsecIf->dwIndex; if (!(pIpsecIf->pszInterfaceName)) { (VOID) GetInterfaceName( pIpsecIf->gInterfaceID, &pIpsecIf->pszInterfaceName ); } if (pIpsecIf->pszInterfaceName) { dwError = SPDApiBufferAllocate( wcslen(pIpsecIf->pszInterfaceName)*sizeof(WCHAR) + sizeof(WCHAR), &(pIpsecInterface->pszInterfaceName) ); BAIL_ON_WIN32_ERROR(dwError); wcscpy(pIpsecInterface->pszInterfaceName, pIpsecIf->pszInterfaceName); } dwError = SPDApiBufferAllocate( wcslen(pIpsecIf->pszDeviceName)*sizeof(WCHAR) + sizeof(WCHAR), &(pIpsecInterface->pszDeviceName) ); BAIL_ON_WIN32_ERROR(dwError); wcscpy(pIpsecInterface->pszDeviceName, pIpsecIf->pszDeviceName); pIpsecInterface->dwInterfaceType = pIpsecIf->dwInterfaceType; pIpsecInterface->uIpAddr = pIpsecIf->IpAddress; return (dwError); error: if (pIpsecInterface->pszInterfaceName) { SPDApiBufferFree(pIpsecInterface->pszInterfaceName); } return (dwError); } VOID FreeIpsecInterfaceInfos( DWORD dwNumInterfaces, PIPSEC_INTERFACE_INFO pIpsecInterfaces ) { PIPSEC_INTERFACE_INFO pTempInterface = NULL; DWORD i = 0; if (!pIpsecInterfaces) { return; } pTempInterface = pIpsecInterfaces; for (i = 0; i < dwNumInterfaces; i++) { if (pTempInterface->pszInterfaceName) { SPDApiBufferFree(pTempInterface->pszInterfaceName); } if (pTempInterface->pszDeviceName) { SPDApiBufferFree(pTempInterface->pszDeviceName); } pTempInterface++; } SPDApiBufferFree(pIpsecInterfaces); } DWORD GetInterfaceName( GUID gInterfaceID, LPWSTR * ppszInterfaceName ) { DWORD dwError = 0; DWORD dwSize = 0; WCHAR szInterfaceName[512]; *ppszInterfaceName = NULL; szInterfaceName[0] = L'\0'; dwSize = sizeof(szInterfaceName)/sizeof(WCHAR); dwError = NhGetInterfaceNameFromGuid( &gInterfaceID, szInterfaceName, &dwSize, FALSE, FALSE ); BAIL_ON_WIN32_ERROR(dwError); *ppszInterfaceName = AllocSPDStr( szInterfaceName ); error: return (dwError); }