📄 automationproxy.cpp
字号:
}
}
else
{
TraceError("CUPnPAutomationProxy::HrInvokeAction(): "
"Failed to invoke action",
hr);
}
// Cleanup. At this point, all the output information should be
// in the ucresp structure.
if (rgvarg)
{
for (unsigned i = 0; i < cTotalArgs; i++)
VariantClear(&rgvarg[i]);
}
if (rgvargData)
{
for (unsigned i = 0; i < cOutArgs; i++)
VariantClear(&rgvargData[i]);
}
delete [] rgvarg;
rgvarg = NULL;
delete [] rgvargData;
rgvargData = NULL;
VariantClear(&varResult);
}
else
{
// Invalid arguments.
ucresp.fSucceeded = FALSE;
hr = HrBuildFaultResponse(&ucresp.ucrData,
L"SOAP-ENV:Client",
L"UPnPError",
L"402",
L"Invalid Args");
}
}
else
{
// Invalid Action name
ucresp.fSucceeded = FALSE;
hr = HrBuildFaultResponse(&ucresp.ucrData,
L"SOAP-ENV:Client",
L"UPnPError",
L"401",
L"Invalid Action");
}
// If succeeded, copy the response info to the output structure, otherwise
// free it.
if (SUCCEEDED(hr))
{
*pucresp = ucresp;
}
else
{
FreeControlResponse(&ucresp);
}
TraceError("CUPnPAutomationProxy::HrInvokeAction(): "
"Exiting",
hr);
return hr;
}
HRESULT
CUPnPAutomationProxy::HrQueryStateVariable(
UPNP_CONTROL_REQUEST * pucreq,
UPNP_CONTROL_RESPONSE * pucresp)
{
HRESULT hr = S_OK;
UPNP_CONTROL_RESPONSE ucresp = {0};
UPNP_STATE_VARIABLE * pusv = NULL;
BSTR bstrVarName = NULL;
// QueryStateVariable should have 1 input argument which is the variable
// name.
Assert(pucreq->cInputArgs == 1);
Assert(pucreq->rgvarInputArgs[0].vt == VT_BSTR);
bstrVarName = V_BSTR(&pucreq->rgvarInputArgs[0]);
pusv = LookupVariableByName(bstrVarName);
if (pusv)
{
DISPPARAMS dispparamsEmpty = {NULL, NULL, 0, 0};
VARIANT varResult;
EXCEPINFO excepInfo = {0};
VariantInit(&varResult);
// Query the value.
hr = m_pdispService->Invoke(pusv->dispid,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET,
&dispparamsEmpty,
&varResult,
&excepInfo,
NULL);
// Build a response.
if (SUCCEEDED(hr))
{
UPNP_CONTROL_RESPONSE_DATA * pucrd = NULL;
TraceTag(ttidAutomationProxy,
"CUPnPAutomationProxy::HrQueryStateVariable(): "
"PROPGET for %S succeeded",
bstrVarName);
ucresp.bstrActionName = SysAllocString(L"QueryStateVariable");
if (ucresp.bstrActionName)
{
ucresp.fSucceeded = TRUE;
pucrd = &ucresp.ucrData;
pucrd->Success.cOutputArgs = 1;
pucrd->Success.rgvarOutputArgs = (VARIANT *) CoTaskMemAlloc(
sizeof(VARIANT));
if (pucrd->Success.rgvarOutputArgs)
{
VariantInit(&pucrd->Success.rgvarOutputArgs[0]);
hr = StringizeVariant(&varResult, pusv->strDataType);
if (SUCCEEDED(hr))
hr = VariantCopy(&pucrd->Success.rgvarOutputArgs[0], &varResult);
if (SUCCEEDED(hr))
{
TraceTag(ttidAutomationProxy,
"CUPnPAutomationProxy::HrQueryStateVariable(): "
"Successfully copied %S to output", V_BSTR(&varResult));
}
else
{
TraceError("CUPnPAutomationProxy::HrQueryStateVariable(): "
"Failed to copy result to output",
hr);
}
}
else
{
hr = E_OUTOFMEMORY;
TraceError("CUPnPAutomationProxy::HrQueryStateVariable(): "
"Failed to allocate memory for output arg",
hr);
}
}
else
{
hr = E_OUTOFMEMORY;
TraceError("CUPnPAutomationProxy::HrQueryStateVariable(): "
"Failed to allocate memory for action name",
hr);
}
}
else if (DISP_E_EXCEPTION == hr)
{
UPNP_CONTROL_RESPONSE_DATA * pucrd = NULL;
TraceTag(ttidAutomationProxy,
"CUPnPAutomationProxy::HrQueryStateVariable(): "
"PROPGET for %S returned an exception",
bstrVarName);
// Fix up the HRESULT. Even though this is an error in the
// UPnP sense, we are returning success because from the
// processing point of view, the request went through correctly
// and just returned a fault response.
hr = S_OK;
ucresp.bstrActionName = SysAllocString(L"QueryStateVariable");
if (ucresp.bstrActionName)
{
ucresp.fSucceeded = FALSE;
pucrd = &ucresp.ucrData;
// If the service object requested deferred fill-in of
// the exception info, call its callback function now.
if (excepInfo.pfnDeferredFillIn)
{
hr = (*(excepInfo.pfnDeferredFillIn))(&excepInfo);
if (SUCCEEDED(hr))
{
TraceTag(ttidAutomationProxy,
"CUPnPAutomationProxy::HrQueryStateVariable(): "
"Successfully filled in "
"deferred exception info");
}
else
{
TraceError("CUPnPAutomationProxy::HrQueryStateVariable(): "
"Failed to fill in "
"deferred exception info",
hr);
}
}
if (SUCCEEDED(hr))
{
hr = HrBuildFaultResponse(pucrd,
L"SOAP-ENV:Client",
L"UPnPError",
excepInfo.bstrSource,
excepInfo.bstrDescription);
}
}
else
{
hr = E_OUTOFMEMORY;
TraceError("CUPnPAutomationProxy::HrQueryStateVariable(): "
"Failed to allocate memory for action name",
hr);
}
}
else
{
TraceError("CUPnPAutomationProxy::HrQueryStateVariable(): "
"PROPGET failed",
hr);
}
VariantClear(&varResult);
}
else
{
// Invalid variable name
ucresp.fSucceeded = FALSE;
hr = HrBuildFaultResponse(&ucresp.ucrData,
L"SOAP-ENV:Client",
L"UPnPError",
L"404",
L"Invalid Var");
}
// If succeeded, copy the response info to the output structure, otherwise
// free it.
if (SUCCEEDED(hr))
{
*pucresp = ucresp;
}
else
{
FreeControlResponse(&ucresp);
}
TraceError("CUPnPAutomationProxy::HrQueryStateVariable(): "
"Exiting",
hr);
return hr;
}
// yet another strdup
PWSTR COMSzFromWsz(PCWSTR pszSource)
{
int cch;
PWSTR pszDest;
if (!pszSource)
return NULL;
Assert((PCWSTR) 0xcccccccc != pszSource); // containing object hasn't been deleted
cch = wcslen(pszSource)+1;
pszDest = (PWSTR )CoTaskMemAlloc(cch*sizeof(WCHAR));
if (pszDest)
{
memcpy(pszDest, pszSource, cch*sizeof(WCHAR));
}
return pszDest;
}
/*
* Function: GetTypeFromString()
*
* Purpose: Returns the appropriate SDT_DATA_TYPE value for the given
* xml-data type string.
*
* Arguments:
* pszTypeString [in] The data type identifier whose SDT_DATA_TYPE value
* is desired.
*
* Returns:
* If the string is found, it returns the appropriate value of the
* SST_DATA_TYPE enumeration.
* If the string is not found, it returns SDT_INVALID.
*
* Notes:
* The source string is compared to known strings in a case-insensitive
* comparison.
*
*/
SST_DATA_TYPE
GetTypeFromString(LPCWSTR pszTypeString)
{
// there must be an entry in g_rgdtTypeStrings for every real
// value of SST_DATA_TYPE
//
Assert(SDT_INVALID == celems(g_rgdtTypeStrings));
SST_DATA_TYPE sdtResult;
sdtResult = SDT_INVALID;
{
// now search for the string in the list, using a
// standard binary search
//
INT nLow;
INT nMid;
INT nHigh;
nLow = 0;
nHigh = celems(g_rgdtTypeStrings) - 1;
while (TRUE)
{
if (nLow > nHigh)
{
// not found
//
break;
}
nMid = (nLow + nHigh) / 2;
{
LPCWSTR pszCurrent;
int result;
pszCurrent = g_rgdtTypeStrings[nMid].m_pszType;
result = _wcsicmp(pszTypeString, pszCurrent);
if (result < 0)
{
nHigh = nMid - 1;
}
else if (result > 0)
{
nLow = nMid + 1;
}
else
{
// found
//
sdtResult = g_rgdtTypeStrings[nMid].m_sdt;
break;
}
}
}
}
return sdtResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -