//---------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 2001. // // File: api.c // // Contents: APIs exported to snapin to manage WIFI policy objects on AD // // // History: TaroonM // 10/30/01 // // Remarks: Wireless Network Policy Management Currently doesnt support Registry based(local) policies. However we are // keeping the Registry based code, for possible use later. //---------------------------------------------------------------------------- #include "precomp.h" DWORD WirelessEnumPolicyData( HANDLE hPolicyStore, PWIRELESS_POLICY_DATA ** pppWirelessPolicyData, PDWORD pdwNumPolicyObjects ) { DWORD dwError = 0; DWORD dwProvider = 0; PWIRELESS_POLICY_STORE pPolicyStore = NULL; IWbemServices *pWbemServices = NULL; pPolicyStore = (PWIRELESS_POLICY_STORE)hPolicyStore; switch (pPolicyStore->dwProvider) { case WIRELESS_REGISTRY_PROVIDER: break; case WIRELESS_DIRECTORY_PROVIDER: dwError = DirEnumWirelessPolicyData( (pPolicyStore->hLdapBindHandle), pPolicyStore->pszWirelessRootContainer, pppWirelessPolicyData, pdwNumPolicyObjects ); break; case WIRELESS_WMI_PROVIDER: dwError = CreateIWbemServices( pPolicyStore->pszLocationName, &pWbemServices ); if(dwError == ERROR_SUCCESS) { dwError = WMIEnumPolicyDataEx( pWbemServices, pppWirelessPolicyData, pdwNumPolicyObjects ); IWbemServices_Release(pWbemServices); } break; default: dwError = ERROR_INVALID_PARAMETER; break; } return(dwError); } DWORD WirelessSetPolicyData( HANDLE hPolicyStore, PWIRELESS_POLICY_DATA pWirelessPolicyData ) { DWORD dwError = 0; DWORD dwProvider = 0; PWIRELESS_POLICY_STORE pPolicyStore = NULL; dwError = ValidateWirelessPolicyData( pWirelessPolicyData ); BAIL_ON_WIN32_ERROR(dwError); pPolicyStore = (PWIRELESS_POLICY_STORE)hPolicyStore; switch (pPolicyStore->dwProvider) { case WIRELESS_REGISTRY_PROVIDER: break; case WIRELESS_DIRECTORY_PROVIDER: dwError = DirSetWirelessPolicyData( (pPolicyStore->hLdapBindHandle), pPolicyStore->pszWirelessRootContainer, pWirelessPolicyData ); break; case WIRELESS_WMI_PROVIDER: dwError = ERROR_NOT_SUPPORTED; break; default: dwError = ERROR_INVALID_PARAMETER; break; } error: return(dwError); } DWORD WirelessCreatePolicyData( HANDLE hPolicyStore, PWIRELESS_POLICY_DATA pWirelessPolicyData ) { DWORD dwError = 0; DWORD dwProvider = 0; PWIRELESS_POLICY_STORE pPolicyStore = NULL; dwError = ValidateWirelessPolicyData( pWirelessPolicyData ); BAIL_ON_WIN32_ERROR(dwError); pPolicyStore = (PWIRELESS_POLICY_STORE)hPolicyStore; switch (pPolicyStore->dwProvider) { case WIRELESS_REGISTRY_PROVIDER: /* dwError = RegCreatePolicyData( (pPolicyStore->hRegistryKey), pPolicyStore->pszWirelessRootContainer, pWirelessPolicyData ); */ break; case WIRELESS_DIRECTORY_PROVIDER: dwError = DirCreateWirelessPolicyData( (pPolicyStore->hLdapBindHandle), pPolicyStore->pszWirelessRootContainer, pWirelessPolicyData ); break; case WIRELESS_WMI_PROVIDER: dwError = ERROR_NOT_SUPPORTED; break; default: dwError = ERROR_INVALID_PARAMETER; break; } error: return(dwError); } DWORD WirelessDeletePolicyData( HANDLE hPolicyStore, PWIRELESS_POLICY_DATA pWirelessPolicyData ) { DWORD dwError = 0; DWORD dwProvider = 0; PWIRELESS_POLICY_STORE pPolicyStore = NULL; pPolicyStore = (PWIRELESS_POLICY_STORE)hPolicyStore; switch (pPolicyStore->dwProvider) { case WIRELESS_REGISTRY_PROVIDER: break; case WIRELESS_DIRECTORY_PROVIDER: dwError = DirDeleteWirelessPolicyData( (pPolicyStore->hLdapBindHandle), pPolicyStore->pszWirelessRootContainer, pWirelessPolicyData ); break; case WIRELESS_WMI_PROVIDER: dwError = ERROR_NOT_SUPPORTED; break; default: dwError = ERROR_INVALID_PARAMETER; break; } return(dwError); } /* pszGPO name contains the LDAP path of the GPO whose extesnion snapin is making this call. */ DWORD WirelessGPOOpenPolicyStore( LPWSTR pszMachineName, DWORD dwTypeOfStore, LPWSTR pszGPOName, LPWSTR pszFileName, HANDLE * phPolicyStore ) { DWORD dwError = 0; switch (dwTypeOfStore) { case WIRELESS_REGISTRY_PROVIDER: break; case WIRELESS_DIRECTORY_PROVIDER: dwError = DirGPOOpenPolicyStore( pszMachineName, pszGPOName, phPolicyStore ); break; case WIRELESS_FILE_PROVIDER: break; case WIRELESS_WMI_PROVIDER: dwError = WMIOpenPolicyStore( pszMachineName, phPolicyStore ); break; default: dwError = ERROR_INVALID_PARAMETER; break; } return (dwError); } DWORD DirGPOOpenPolicyStore( LPWSTR pszMachineName, LPWSTR pszGPOName, HANDLE * phPolicyStore ) { PWIRELESS_POLICY_STORE pPolicyStore = NULL; DWORD dwError = 0; LPWSTR pszWirelessRootContainer = NULL; HLDAP hLdapBindHandle = NULL; LPWSTR pszDefaultDirectory = NULL; if (!pszMachineName || !*pszMachineName) { dwError = ComputeDefaultDirectory( &pszDefaultDirectory ); BAIL_ON_WIN32_ERROR(dwError); dwError = OpenDirectoryServerHandle( pszDefaultDirectory, 389, &hLdapBindHandle ); BAIL_ON_WIN32_ERROR(dwError); dwError = ComputeGPODirLocationName( pszGPOName, &pszWirelessRootContainer ); BAIL_ON_WIN32_ERROR(dwError); } else { dwError = OpenDirectoryServerHandle( pszMachineName, 389, &hLdapBindHandle ); BAIL_ON_WIN32_ERROR(dwError); dwError = ComputeGPODirLocationName( pszGPOName, &pszWirelessRootContainer ); BAIL_ON_WIN32_ERROR(dwError); } pPolicyStore = (PWIRELESS_POLICY_STORE)AllocPolMem( sizeof(WIRELESS_POLICY_STORE) ); if (!pPolicyStore) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } pPolicyStore->dwProvider = WIRELESS_DIRECTORY_PROVIDER; pPolicyStore->hParentRegistryKey = NULL; pPolicyStore->hRegistryKey = NULL; pPolicyStore->pszLocationName = NULL; pPolicyStore->hLdapBindHandle = hLdapBindHandle; pPolicyStore->pszWirelessRootContainer = pszWirelessRootContainer; pPolicyStore->pszFileName = NULL; *phPolicyStore = pPolicyStore; cleanup: if (pszDefaultDirectory) { FreePolStr(pszDefaultDirectory); } return(dwError); error: if (hLdapBindHandle) { CloseDirectoryServerHandle(hLdapBindHandle); } if (pszWirelessRootContainer) { FreePolStr(pszWirelessRootContainer); } if (pPolicyStore) { FreePolMem(pPolicyStore); } *phPolicyStore = NULL; goto cleanup; } DWORD WirelessClosePolicyStore( HANDLE hPolicyStore ) { DWORD dwError = 0; PWIRELESS_POLICY_STORE pPolicyStore = NULL; pPolicyStore = (PWIRELESS_POLICY_STORE)hPolicyStore; switch (pPolicyStore->dwProvider) { case WIRELESS_REGISTRY_PROVIDER: break; case WIRELESS_DIRECTORY_PROVIDER: if (pPolicyStore->hLdapBindHandle) { CloseDirectoryServerHandle( pPolicyStore->hLdapBindHandle ); } if (pPolicyStore->pszWirelessRootContainer) { FreePolStr(pPolicyStore->pszWirelessRootContainer); } break; case WIRELESS_FILE_PROVIDER: break; default: dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); break; } if (pPolicyStore) { FreePolMem(pPolicyStore); } error: return(dwError); } DWORD ComputeGPODirLocationName( LPWSTR pszDirDomainName, LPWSTR * ppszDirFQPathName ) { DWORD dwError = 0; WCHAR szName[MAX_PATH]; LPWSTR pszDirFQPathName = NULL; DWORD dwDirDomainNameLen = 0; DWORD dwDirLocationNameLen = 0; DWORD dwTotalLen = 0; szName[0] = L'\0'; wcscpy(szName, L"CN=Wireless, CN=Windows,CN=Microsoft,"); dwDirDomainNameLen = wcslen(pszDirDomainName); dwDirLocationNameLen = wcslen(szName); dwTotalLen = dwDirDomainNameLen+dwDirLocationNameLen; pszDirFQPathName = AllocPolMem((dwTotalLen+1) * sizeof(WCHAR)); if (!pszDirFQPathName) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } wcsncpy(pszDirFQPathName, szName, dwDirLocationNameLen); wcsncat(pszDirFQPathName, pszDirDomainName, dwDirDomainNameLen); pszDirFQPathName[dwTotalLen] = L'\0'; *ppszDirFQPathName = pszDirFQPathName; return (dwError); error: *ppszDirFQPathName = NULL; return(dwError); } /* Helper Function: Set PS in a Policy Structure */ DWORD WirelessSetPSDataInPolicy( PWIRELESS_POLICY_DATA pWirelessPolicyData, PWIRELESS_PS_DATA pWirelessPSData ) { DWORD dwError = 0; DWORD dwPSId = -1; WirelessPolicyPSId(pWirelessPolicyData, pWirelessPSData->pszWirelessSSID, &dwPSId ); if (dwPSId == -1) { dwError = ERROR_PS_NOT_PRESENT; BAIL_ON_WIN32_ERROR(dwError); } dwError = ModifyWirelessPSData( pWirelessPolicyData->ppWirelessPSData[dwPSId], pWirelessPSData ); BAIL_ON_WIN32_ERROR(dwError); dwError = ERROR_SUCCESS; return(dwError); error: return(dwError); } DWORD WirelessAddPSToPolicy( PWIRELESS_POLICY_DATA pWirelessPolicyData, PWIRELESS_PS_DATA pWirelessPSData ) { DWORD dwNumPreferredSettings = 0; DWORD dwError = 0; PWIRELESS_PS_DATA *ppWirelessPSData=NULL; PWIRELESS_PS_DATA *ppNewWirelessPSData=NULL; DWORD i = 0; DWORD dwInsertIndex = 0; DWORD dwNumAPNetworks = 0; dwNumPreferredSettings = pWirelessPolicyData->dwNumPreferredSettings; dwNumAPNetworks = pWirelessPolicyData->dwNumAPNetworks; ppWirelessPSData = pWirelessPolicyData->ppWirelessPSData; ppNewWirelessPSData = (PWIRELESS_PS_DATA *) AllocPolMem(sizeof(PWIRELESS_PS_DATA)*(dwNumPreferredSettings+1)); if(!ppNewWirelessPSData) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } if(pWirelessPSData->dwNetworkType == WIRELESS_NETWORK_TYPE_ADHOC) { dwInsertIndex = dwNumPreferredSettings; } else { dwInsertIndex = dwNumAPNetworks; pWirelessPolicyData->dwNumAPNetworks = dwNumAPNetworks+1; } for (i = 0; i < dwInsertIndex; ++i) { ppNewWirelessPSData[i] = ppWirelessPSData[i]; } ppNewWirelessPSData[dwInsertIndex] = pWirelessPSData; pWirelessPSData->dwId = dwInsertIndex; for (i = dwInsertIndex; i < dwNumPreferredSettings; ++i) { ppNewWirelessPSData[i+1] = ppWirelessPSData[i]; ppNewWirelessPSData[i+1]->dwId = i+1; } pWirelessPolicyData->dwNumPreferredSettings = dwNumPreferredSettings+1; pWirelessPolicyData->ppWirelessPSData = ppNewWirelessPSData; FreePolMem(ppWirelessPSData); return(0); error: return(dwError); } DWORD WirelessRemovePSFromPolicy( PWIRELESS_POLICY_DATA pWirelessPolicyData, LPCWSTR pszSSID ) { DWORD dwNumPreferredSettings = 0; DWORD dwError = 0; PWIRELESS_PS_DATA *ppWirelessPSData; PWIRELESS_PS_DATA *ppNewWirelessPSData; DWORD i = 0; DWORD dwPSId; dwNumPreferredSettings = pWirelessPolicyData->dwNumPreferredSettings; ppWirelessPSData = pWirelessPolicyData->ppWirelessPSData; WirelessPolicyPSId(pWirelessPolicyData,pszSSID,&dwPSId); if(dwPSId == -1) { dwError = ERROR_PS_NOT_PRESENT; BAIL_ON_WIN32_ERROR(dwError); } ppNewWirelessPSData = (PWIRELESS_PS_DATA *) AllocPolMem(sizeof(PWIRELESS_PS_DATA)*(dwNumPreferredSettings-1)); if(!ppNewWirelessPSData) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } for(i = 0; i < dwPSId; ++i) { ppNewWirelessPSData[i] = ppWirelessPSData[i]; } for(i = dwPSId; i < dwNumPreferredSettings-1; ++i) { ppNewWirelessPSData[i] = ppWirelessPSData[i+1]; } pWirelessPolicyData->dwNumPreferredSettings = dwNumPreferredSettings-1; pWirelessPolicyData->ppWirelessPSData = ppNewWirelessPSData; FreePolMem(ppWirelessPSData); return(0); error: return(dwError); } DWORD WirelessRemovePSFromPolicyId( PWIRELESS_POLICY_DATA pWirelessPolicyData, DWORD dwId ) { DWORD dwNumPreferredSettings = 0; DWORD dwError = 0; PWIRELESS_PS_DATA *ppWirelessPSData; PWIRELESS_PS_DATA *ppNewWirelessPSData; DWORD i = 0; DWORD dwPSId; dwNumPreferredSettings = pWirelessPolicyData->dwNumPreferredSettings; ppWirelessPSData = pWirelessPolicyData->ppWirelessPSData; if(dwId >= dwNumPreferredSettings ) { dwError = ERROR_PS_NOT_PRESENT; BAIL_ON_WIN32_ERROR(dwError); } ppNewWirelessPSData = (PWIRELESS_PS_DATA *) AllocPolMem(sizeof(PWIRELESS_PS_DATA)*(dwNumPreferredSettings-1)); if(!ppNewWirelessPSData) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } for(i = 0; i < dwId; ++i) { ppNewWirelessPSData[i] = ppWirelessPSData[i]; } if (ppWirelessPSData[dwId]->dwNetworkType == WIRELESS_NETWORK_TYPE_AP) { pWirelessPolicyData->dwNumAPNetworks--; } for(i = dwId; i < dwNumPreferredSettings-1; ++i) { ppNewWirelessPSData[i] = ppWirelessPSData[i+1]; ppNewWirelessPSData[i]->dwId = i; } pWirelessPolicyData->dwNumPreferredSettings = dwNumPreferredSettings-1; pWirelessPolicyData->ppWirelessPSData = ppNewWirelessPSData; FreePolMem(ppWirelessPSData); return(0); error: return(dwError); } void WirelessPolicyPSId(PWIRELESS_POLICY_DATA pWirelessPolicyData, LPCWSTR pszSSID, DWORD *dwId) { DWORD dwError=0; DWORD dwNumPreferredSettings; DWORD dwSSIDLen = 0; DWORD i = 0; DWORD dwCompare = 1; DWORD dwPId = -1; PWIRELESS_PS_DATA *ppWirelessPSData; PWIRELESS_PS_DATA pWirelessPSData; dwSSIDLen = lstrlenW(pszSSID); dwNumPreferredSettings = pWirelessPolicyData->dwNumPreferredSettings; ppWirelessPSData = pWirelessPolicyData->ppWirelessPSData; for(i = 0; i < dwNumPreferredSettings; ++i) { pWirelessPSData = ppWirelessPSData[i]; if(pWirelessPSData->dwWirelessSSIDLen == dwSSIDLen) { dwCompare = memcmp(pWirelessPSData->pszWirelessSSID,pszSSID,dwSSIDLen*2); } if (dwCompare == 0) { dwPId = i; break; } } *dwId = dwPId; return; } void UpdateWirelessPSData( PWIRELESS_PS_DATA pWirelessPSData ) { DWORD dwDescriptionLen = 0; DWORD dwEAPDataLen = 0; DWORD dwWirelessSSIDLen = 0; DWORD dwPSLen = 0; // may be replace it with actual counting. dwWirelessSSIDLen = lstrlenW(pWirelessPSData->pszWirelessSSID); dwDescriptionLen = lstrlenW(pWirelessPSData->pszDescription); //dwPSLen = 20 * sizeof(DWORD) + 32*2 + 2 * dwDescriptionLen; dwEAPDataLen = pWirelessPSData->dwEAPDataLen; dwPSLen = (sizeof(WIRELESS_PS_DATA) - sizeof(DWORD) - sizeof(LPWSTR)) + sizeof(WCHAR) * dwDescriptionLen - sizeof(LPBYTE) + dwEAPDataLen; pWirelessPSData->dwPSLen = dwPSLen; pWirelessPSData->dwWirelessSSIDLen = (dwWirelessSSIDLen < 32) ? dwWirelessSSIDLen : 32; pWirelessPSData->dwDescriptionLen = dwDescriptionLen; } DWORD WMIOpenPolicyStore( LPWSTR pszMachineName, HANDLE * phPolicyStore ) { PWIRELESS_POLICY_STORE pPolicyStore = NULL; DWORD dwError = 0; pPolicyStore = (PWIRELESS_POLICY_STORE)AllocPolMem( sizeof(WIRELESS_POLICY_STORE) ); if (!pPolicyStore) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } pPolicyStore->dwProvider = WIRELESS_WMI_PROVIDER; pPolicyStore->hParentRegistryKey = NULL; pPolicyStore->hRegistryKey = NULL; pPolicyStore->pszLocationName = pszMachineName; pPolicyStore->hLdapBindHandle = NULL; pPolicyStore->pszWirelessRootContainer = NULL; pPolicyStore->pszFileName = NULL; *phPolicyStore = pPolicyStore; cleanup: return(dwError); error: if (pPolicyStore) { FreePolMem(pPolicyStore); } *phPolicyStore = NULL; goto cleanup; } HRESULT WirelessWriteDirectoryPolicyToWMI( LPWSTR pszMachineName, LPWSTR pszPolicyDN, PGPO_INFO pGPOInfo, IWbemServices *pWbemServices ) { DWORD dwError = 0; HRESULT hr = S_OK; PWIRELESS_POLICY_OBJECT pWirelessPolicyObject = NULL; BOOL bDeepRead = FALSE; if (!pWbemServices || !pszPolicyDN || !pGPOInfo ) { hr = E_INVALIDARG; BAIL_ON_HRESULT_ERROR(hr); } bDeepRead = (pGPOInfo->uiPrecedence == 1); hr = ReadPolicyObjectFromDirectoryEx( pszMachineName, pszPolicyDN, bDeepRead, &pWirelessPolicyObject ); BAIL_ON_HRESULT_ERROR(hr); hr = WritePolicyObjectDirectoryToWMI( pWbemServices, pWirelessPolicyObject, pGPOInfo ); BAIL_ON_HRESULT_ERROR(hr); error: if (pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyObject); } return(hr); } HRESULT WirelessClearWMIStore( IWbemServices *pWbemServices ) { HRESULT hr = S_OK; if (!pWbemServices) { hr = E_INVALIDARG; BAIL_ON_HRESULT_ERROR(hr); } hr = DeleteWMIClassObject( pWbemServices, WIRELESS_RSOP_CLASSNAME ); BAIL_ON_HRESULT_ERROR(hr); error: return(hr); }