windows-nt/Source/XPSP1/NT/net/layer2svc/wastore/wmistore.c
2020-09-26 16:20:57 +08:00

594 lines
14 KiB
C

#include "precomp.h"
LPWSTR gpszWirelessWMINamespace = L"root\\rsop\\computer";
DWORD
Win32FromWmiHresult(
HRESULT hr
)
{
if (FAILED(hr)) {
switch (hr) {
case WBEM_E_ACCESS_DENIED:
return ERROR_ACCESS_DENIED;
case REGDB_E_CLASSNOTREG:
case CLASS_E_NOAGGREGATION:
case E_NOINTERFACE:
case WBEM_E_INVALID_NAMESPACE:
case WBEM_E_INVALID_PARAMETER:
case WBEM_E_NOT_FOUND:
case WBEM_E_INVALID_CLASS:
case WBEM_E_INVALID_OBJECT_PATH:
return ERROR_INVALID_PARAMETER;
case WBEM_E_OUT_OF_MEMORY:
return ERROR_OUTOFMEMORY;
case WBEM_E_TRANSPORT_FAILURE:
return RPC_S_CALL_FAILED;
case WBEM_E_FAILED:
default:
return ERROR_WMI_TRY_AGAIN;
}
} else {
return ERROR_SUCCESS;
}
}
DWORD
UnMarshallWMIPolicyObject(
IWbemClassObject *pWbemClassObject,
PWIRELESS_POLICY_OBJECT * ppWirelessPolicyObject
)
{
PWIRELESS_POLICY_OBJECT pWirelessPolicyObject = NULL;
HKEY hRegKey = NULL;
DWORD dwType = 0;
DWORD dwSize = 0;
DWORD dwWirelessDataType = 0;
DWORD dwWhenChanged = 0;
LPBYTE pBuffer = NULL;
DWORD i = 0;
DWORD dwCount = 0;
DWORD dwError = 0;
HRESULT hr = S_OK;
LPWSTR pszString = NULL;
LPWSTR pszRelativeName = NULL;
DWORD dwRootPathLen = 0;
////start
VARIANT var; //contains pszWirelessPolicyDN
VariantInit(&var);
hr = IWbemClassObject_Get(pWbemClassObject,
L"id",
0,
&var,
0,
0);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
pWirelessPolicyObject = (PWIRELESS_POLICY_OBJECT)AllocPolMem(sizeof(WIRELESS_POLICY_OBJECT));
if (!pWirelessPolicyObject) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
pWirelessPolicyObject->pszWirelessOwnersReference = AllocPolStr((LPWSTR)var.bstrVal);
VariantClear(&var);
if (!pWirelessPolicyObject->pszWirelessOwnersReference) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
pWirelessPolicyObject->pRsopInfo = (PRSOP_INFO)AllocPolMem(sizeof(RSOP_INFO));
if (!pWirelessPolicyObject->pRsopInfo) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
dwError = WMIstoreQueryValue(pWbemClassObject,
L"creationtime",
VT_BSTR,
(LPBYTE *)&pWirelessPolicyObject->pRsopInfo->pszCreationtime,
&dwSize);
//BAIL_ON_WIN32_ERROR(dwError);
dwError = WMIstoreQueryValue(pWbemClassObject,
L"GPOID",
VT_BSTR,
(LPBYTE *)&pWirelessPolicyObject->pRsopInfo->pszGPOID,
&dwSize);
//BAIL_ON_WIN32_ERROR(dwError);
dwError = WMIstoreQueryValue(pWbemClassObject,
L"id",
VT_BSTR,
(LPBYTE *)&pWirelessPolicyObject->pRsopInfo->pszID,
&dwSize);
BAIL_ON_WIN32_ERROR(dwError);
dwError = WMIstoreQueryValue(pWbemClassObject,
L"name",
VT_BSTR,
(LPBYTE *)&pWirelessPolicyObject->pRsopInfo->pszName,
&dwSize);
BAIL_ON_WIN32_ERROR(dwError);
dwError = WMIstoreQueryValue(pWbemClassObject,
L"SOMID",
VT_BSTR,
(LPBYTE *)&pWirelessPolicyObject->pRsopInfo->pszSOMID,
&dwSize);
//BAIL_ON_WIN32_ERROR(dwError);
hr = IWbemClassObject_Get(pWbemClassObject,
L"precedence",
0,
&var,
0,
0);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
pWirelessPolicyObject->pRsopInfo->uiPrecedence = var.lVal;
dwError = WMIstoreQueryValue(pWbemClassObject,
L"msieee80211Name",
VT_BSTR,
(LPBYTE *)&pWirelessPolicyObject->pszWirelessName,
&dwSize);
BAIL_ON_WIN32_ERROR(dwError);
dwError = WMIstoreQueryValue(pWbemClassObject,
L"description",
VT_BSTR,
(LPBYTE *)&pWirelessPolicyObject->pszDescription,
&dwSize);
// BAIL_ON_WIN32_ERROR(dwError);
dwError = WMIstoreQueryValue(pWbemClassObject,
L"msieee80211ID",
VT_BSTR,
(LPBYTE *)&pWirelessPolicyObject->pszWirelessID,
&dwSize);
BAIL_ON_WIN32_ERROR(dwError);
hr = IWbemClassObject_Get(pWbemClassObject,
L"msieee80211DataType",
0,
&var,
0,
0);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
dwWirelessDataType = var.lVal;
pWirelessPolicyObject->dwWirelessDataType = dwWirelessDataType;
dwError = WMIstoreQueryValue(pWbemClassObject,
L"msieee80211Data",
VT_ARRAY|VT_UI1,
&pWirelessPolicyObject->pWirelessData,
&pWirelessPolicyObject->dwWirelessDataLen);
BAIL_ON_WIN32_ERROR(dwError);
hr = IWbemClassObject_Get(pWbemClassObject,
L"whenChanged",
0,
&var,
0,
0);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
dwWhenChanged = var.lVal;
pWirelessPolicyObject->dwWhenChanged = dwWhenChanged;
*ppWirelessPolicyObject = pWirelessPolicyObject;
cleanup:
return(dwError);
error:
if (pWirelessPolicyObject) {
FreeWirelessPolicyObject(pWirelessPolicyObject);
}
*ppWirelessPolicyObject = NULL;
goto cleanup;
}
DWORD
WMIstoreQueryValue(
IWbemClassObject *pWbemClassObject,
LPWSTR pszValueName,
DWORD dwType,
LPBYTE *ppValueData,
LPDWORD pdwSize
)
{
DWORD dwSize = 0;
LPWSTR pszValueData = NULL;
DWORD dwError = 0;
HRESULT hr = S_OK;
LPBYTE pBuffer = NULL;
LPWSTR pszBuf = NULL;
SAFEARRAY *pSafeArray = NULL;
VARIANT var;
DWORD i = 0;
DWORD dw = 0;
LPWSTR pszTmp = NULL;
LPWSTR pszString = NULL;
LPWSTR pMem = NULL;
LPWSTR *ppszTmp = NULL;
long lUbound = 0;
DWORD dwCount = 0;
LPBYTE pdw = NULL;
BSTR HUGEP *pbstrTmp = NULL;
BYTE HUGEP *pbyteTmp = NULL;
VariantInit(&var);
if(!pWbemClassObject) {
dwError = ERROR_INVALID_DATA;
BAIL_ON_WIN32_ERROR(dwError);
}
hr = IWbemClassObject_Get(pWbemClassObject,
pszValueName,
0,
&var,
0,
0);
if(hr == WBEM_E_NOT_FOUND) {
dwError = ERROR_INVALID_DATA;
BAIL_ON_WIN32_ERROR(dwError);
}
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
////sanity check
if(dwType != var.vt) {
dwError = ERROR_INVALID_DATA;
BAIL_ON_WIN32_ERROR(dwError);
}
switch(dwType) {
case VT_BSTR:
pszTmp = var.bstrVal;
dwSize = wcslen(pszTmp)*sizeof(WCHAR);
pBuffer = (LPBYTE)AllocPolStr(pszTmp);
if (!pBuffer) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
break;
case (VT_ARRAY|VT_UI1):
pSafeArray = var.parray;
if(!pSafeArray) {
dwError = ERROR_INVALID_DATA;
BAIL_ON_WIN32_ERROR(dwError);
}
hr = SafeArrayGetUBound(
pSafeArray,
1,
&lUbound
);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
dwSize = lUbound+1;
if (dwSize == 0) {
dwError = ERROR_INVALID_DATA;
BAIL_ON_WIN32_ERROR(dwError);
}
pBuffer = (LPBYTE)AllocPolMem(dwSize);
if (!pBuffer) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
for(i = 0; i < dwSize; i++) {
hr = SafeArrayGetElement(pSafeArray, (long *)&i, &pBuffer[i]);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
}
break;
case (VT_ARRAY|VT_BSTR):
pSafeArray = var.parray;
if(!pSafeArray) {
dwError = ERROR_INVALID_DATA;
BAIL_ON_WIN32_ERROR(dwError);
}
hr = SafeArrayGetUBound(
pSafeArray,
1,
&lUbound
);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
dwCount = lUbound+1;
if (dwCount == 0) {
dwError = ERROR_INVALID_DATA;
BAIL_ON_WIN32_ERROR(dwError);
}
ppszTmp = (LPWSTR *)AllocPolMem(
sizeof(LPWSTR)*dwCount
);
if (!ppszTmp) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
hr = SafeArrayAccessData(
pSafeArray,
(void HUGEP**)&pbstrTmp
);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
for(i = 0; i < dwCount; i++) {
pszTmp = pbstrTmp[i];
ppszTmp[i] = AllocPolStr(pszTmp);
if (!ppszTmp[i]) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
}
SafeArrayUnaccessData(pSafeArray);
//ppszTmp => string array
for(i = 0; i < dwCount; i++) {
dwSize += wcslen(ppszTmp[i])+1;
}
dwSize++;
pMem = (LPWSTR)AllocPolMem(sizeof(WCHAR)*dwSize);
if (!pMem) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
//adjust dwSize to byte size
dwSize *= sizeof(WCHAR);
pszString = pMem;
for(i = 0; i < dwCount; i++) {
memcpy(pszString, ppszTmp[i], wcslen(ppszTmp[i])*sizeof(WCHAR));
pszString += wcslen(pszString)+1;
}
pBuffer = (LPBYTE)pMem;
break;
default:
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
break;
}
switch(dwType) {
case VT_BSTR:
pszBuf = (LPWSTR)pBuffer;
if (!pszBuf || !*pszBuf) {
dwError = ERROR_INVALID_DATA;
BAIL_ON_WIN32_ERROR(dwError);
}
break;
default:
break;
}
*ppValueData = pBuffer;
*pdwSize = dwSize;
VariantClear(&var);
cleanup:
if(ppszTmp) {
FreePolMem(ppszTmp);
}
return(dwError);
error:
if (pBuffer) {
FreePolMem(pBuffer);
}
*ppValueData = NULL;
*pdwSize = 0;
goto cleanup;
}
HRESULT
ReadPolicyObjectFromDirectoryEx(
LPWSTR pszMachineName,
LPWSTR pszPolicyDN,
BOOL bDeepRead,
PWIRELESS_POLICY_OBJECT * ppWirelessPolicyObject
)
{
DWORD dwError = 0;
HLDAP hLdapBindHandle = NULL;
LPWSTR pszDefaultDirectory = NULL;
PWIRELESS_POLICY_OBJECT pWirelessPolicyObject = NULL;
if (!pszMachineName || !*pszMachineName) {
dwError = ComputeDefaultDirectory(
&pszDefaultDirectory
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = OpenDirectoryServerHandle(
pszDefaultDirectory,
389,
&hLdapBindHandle
);
BAIL_ON_WIN32_ERROR(dwError);
} else {
dwError = OpenDirectoryServerHandle(
pszMachineName,
389,
&hLdapBindHandle
);
BAIL_ON_WIN32_ERROR(dwError);
}
dwError = ReadPolicyObjectFromDirectory(
hLdapBindHandle,
pszPolicyDN,
&pWirelessPolicyObject
);
BAIL_ON_WIN32_ERROR(dwError);
*ppWirelessPolicyObject = pWirelessPolicyObject;
cleanup:
if (pszDefaultDirectory) {
FreePolStr(pszDefaultDirectory);
}
if (hLdapBindHandle) {
CloseDirectoryServerHandle(hLdapBindHandle);
}
return (HRESULT_FROM_WIN32(dwError));
error:
*ppWirelessPolicyObject = NULL;
goto cleanup;
}
HRESULT
WritePolicyObjectDirectoryToWMI(
IWbemServices *pWbemServices,
PWIRELESS_POLICY_OBJECT pWirelessPolicyObject,
PGPO_INFO pGPOInfo
)
{
HRESULT hr = S_OK;
PWIRELESS_POLICY_OBJECT pWirelessWMIPolicyObject = NULL;
//
// Create a copy of the directory policy in WMI terms
//
hr = CloneDirectoryPolicyObjectEx(
pWirelessPolicyObject,
&pWirelessWMIPolicyObject
);
BAIL_ON_HRESULT_ERROR(hr);
//
// Write the WMI policy
//
hr = PersistWMIObject(
pWbemServices,
pWirelessWMIPolicyObject,
pGPOInfo
);
BAIL_ON_HRESULT_ERROR(hr);
cleanup:
if (pWirelessWMIPolicyObject) {
FreeWirelessPolicyObject(
pWirelessWMIPolicyObject
);
}
return(hr);
error:
goto cleanup;
}
DWORD
CreateIWbemServices(
LPWSTR pszWirelessWMINamespace,
IWbemServices **ppWbemServices
)
{
DWORD dwError = 0;
HRESULT hr = S_OK;
IWbemLocator *pWbemLocator = NULL;
LPWSTR pszWirelessWMIPath = NULL;
BSTR bstrWirelessWMIPath = NULL;
if(!pszWirelessWMINamespace || !*pszWirelessWMINamespace) {
pszWirelessWMIPath = gpszWirelessWMINamespace;
} else {
pszWirelessWMIPath = pszWirelessWMINamespace;
}
hr = CoCreateInstance(
&CLSID_WbemLocator,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IWbemLocator,
&pWbemLocator
);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
bstrWirelessWMIPath = SysAllocString(pszWirelessWMIPath);
if(!bstrWirelessWMIPath) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
hr = IWbemLocator_ConnectServer(
pWbemLocator,
bstrWirelessWMIPath,
NULL,
NULL,
NULL,
0,
NULL,
NULL,
ppWbemServices
);
SysFreeString(bstrWirelessWMIPath);
BAIL_ON_WMI_ERROR_WITH_WIN32(hr, dwError);
if(pWbemLocator)
IWbemLocator_Release(pWbemLocator);
error:
return (dwError);
}