📄 devtree.cpp
字号:
}
// recurse down
if (fRet && m_pFirstChildDev)
fRet = m_pFirstChildDev->SsdpRegister(dwLifeTime, pszDescURL);
// recurse right
if (fRet && m_pNextDev)
fRet = m_pNextDev->SsdpRegister(dwLifeTime, pszDescURL);
if (!fRet)
{
SsdpUnregister();
}
return fRet;
}
BOOL HostedDevice::SsdpUnregister(void)
{
BOOL fRet = TRUE;
HostedService *pService;
if (m_pFirstChildDev)
fRet &= m_pFirstChildDev->SsdpUnregister();
if (m_pNextDev)
fRet &= m_pNextDev->SsdpUnregister();
if (VALIDSSDPH(m_hSSDPUDN))
fRet &= DeregisterUpnpService(m_hSSDPUDN, TRUE);
m_hSSDPUDN = INVALID_HANDLE_VALUE;
if (VALIDSSDPH(m_hSSDPDevType))
fRet &= DeregisterUpnpService(m_hSSDPDevType, TRUE);
m_hSSDPDevType = INVALID_HANDLE_VALUE;
for (pService=m_pFirstService;pService;pService=pService->NextService())
{
fRet &= pService->SsdpUnregister();
}
return fRet;
}
BOOL
HostedDeviceTree::DoDeviceCallback(ControlRequest *pControlReq, UPNPCB_ID id, PCWSTR pszUDN, PCWSTR pszServiceId, PCWSTR pszReqXML)
{
BOOL fRet = FALSE;
DispatchGate *pGate = NULL;
TraceTag(ttidControl, "%s: [%08x] Perform Callback [%08x]\n", __FUNCTION__, this, m_pfCallback);
if (!m_pfCallback)
return FALSE;
pGate = DispatchGate::FindDispatchGateForProc(m_hOwnerProc);
if (!pGate)
return FALSE;
fRet = pGate->EnterGate();
if (!fRet)
{
pGate->DecRef(); // ensure that the gate reference is released
return FALSE; // we are unable to initiate a callback
}
fRet = FALSE;
UpnpInvokeRequestContainer_t requestContainer;
__try {
if(requestContainer.CreateUpnpInvokeRequest(
pszReqXML,
pszServiceId,
pszUDN,
(DWORD) m_pszName,
(DWORD) m_pvCallbackContext,
id) == FALSE) {
TraceTag(ttidError,"%s: [%08x] Exception packing invoke request in DoDeviceCallback id= %d", __FUNCTION__, this, id);
goto Finish;
}
m_pCurControlReq = pControlReq;
TraceTag(ttidControl, "%s: [%08x] Setting Current Control Request [%08x]\n", __FUNCTION__, this, m_pCurControlReq);
fRet = pGate->DoCallback(requestContainer); // this will block
m_pCurControlReq = NULL;
TraceTag(ttidControl, "%s: [%08x] Unsetting Current Control Request [%08x]\n", __FUNCTION__, this, m_pCurControlReq);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
TraceTag(ttidError,"Exception in DoDeviceCallback id= %d", id);
}
Finish:
pGate->LeaveGate();
pGate->DecRef();
return fRet;
}
BOOL
HostedDeviceTree::Control(ControlRequest *pCReq)
{
HostedService *pService;
BOOL fRet = FALSE;
TraceTag(ttidControl, "%s: [%08x] Control Request for UDN[%S]\n", __FUNCTION__, this, m_pszName);
TraceTag(ttidControl, "%s: [%08x] Control Request for ServiceID[%S]\n", __FUNCTION__, this, pCReq->ServiceId());
Lock();
Assert(m_pRootDevice);
pService = m_pRootDevice->FindService(pCReq->UDN(), pCReq->ServiceId());
TraceTag(ttidControl, "%s: [%08x] Control Request Service [%08x]\n", __FUNCTION__, this, pService);
if (m_state >= DevTreePublished && pService)
{
// assume its okay to control
if (m_state < DevTreeRunning)
{
// the device is being invoked for the first time
m_state = DevTreeRunning;
// Send the startup notification to the device implementation
TraceTag(ttidControl, "%s: [%08x] UPNPCB_INIT\n", __FUNCTION__, this);
Unlock();
fRet = DoDeviceCallback(NULL, UPNPCB_INIT, NULL, NULL, NULL);
Lock();
if (!fRet && m_state > DevTreePublished)
{
m_state = DevTreePublished; // uh-oh Init failed
TraceTag(ttidControl, "%s: [%08x] failed init\n", __FUNCTION__, this);
}
}
// since we may have changed state in the previous Unlock(), check again
if (m_state >= DevTreeRunning)
{
TraceTag(ttidControl, "%s: [%08x] UPNPCB_CONTROL\n", __FUNCTION__, this);
Unlock();
fRet = DoDeviceCallback(pCReq, UPNPCB_CONTROL, pCReq->UDN(), pCReq->ServiceId(), pCReq->RequestXML());
Lock();
}
}
Unlock();
TraceTag(ttidControl, "%s: [%08x] Completed Control Request [%S]\n", __FUNCTION__, this, fRet ? L"TRUE" : L"FALSE");
return fRet;
}
BOOL
HostedDeviceTree::Subscribe(PCWSTR szUDN, PCWSTR pszServiceId)
{
HostedService *pService;
BOOL fRet = FALSE;
TraceTag(ttidTrace, "%s: [%08x] Subscribing UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, pszServiceId);
Lock();
Assert(m_pRootDevice);
pService = m_pRootDevice->FindService(szUDN, pszServiceId);
if (m_state >= DevTreePublished && pService)
{
// assume its okay to subscribe
if (m_state < DevTreeRunning)
{
// the device is being invoked for the first time
m_state = DevTreeRunning;
// Send the startup notification to the device implementation
Unlock();
fRet = DoDeviceCallback(NULL, UPNPCB_INIT, NULL, NULL, NULL);
Lock();
if (!fRet && m_state > DevTreePublished)
m_state = DevTreePublished; // uh-oh Init failed
}
// since we may have changed state in the previous Unlock(), check again
if (m_state >= DevTreeRunning)
{
Unlock();
fRet = DoDeviceCallback(NULL, UPNPCB_SUBSCRIBING, szUDN, pszServiceId, NULL);
Lock();
}
}
Unlock();
TraceTag(ttidTrace, "%s: [%08x] Subscribed UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, pszServiceId);
return fRet;
}
BOOL
HostedDeviceTree::Unsubscribe(PCWSTR szUDN, PCWSTR pszServiceId)
{
TraceTag(ttidTrace, "%s: [%08x] Unsubscribing UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, pszServiceId);
DoDeviceCallback(NULL, UPNPCB_UNSUBSCRIBING, szUDN, pszServiceId, NULL);
TraceTag(ttidTrace, "%s: [%08x] Unsubscribed UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, pszServiceId);
return TRUE;
}
BOOL
HostedDeviceTree::SetControlResponse(DWORD dwHttpStatus, PCWSTR pszResp)
{
BOOL fRet = FALSE;
Lock();
if (m_pCurControlReq)
fRet = m_pCurControlReq->SetResponse(dwHttpStatus, pszResp);
else
Assert(false);
Unlock();
TraceTag(ttidTrace, "%s: [%08x] Set Control Response [%S]\n", __FUNCTION__, this, fRet ? L"TRUE" : L"FALSE");
return fRet;
}
static void FreeUPNP_PROPERTY(DWORD nArgs, UPNP_PROPERTY *rgUpnpProps)
{
DWORD i;
for (i=0;i<nArgs;i++)
{
if(rgUpnpProps[i].szName)
free(rgUpnpProps[i].szName);
if(rgUpnpProps[i].szValue)
free(rgUpnpProps[i].szValue);
}
delete [] rgUpnpProps;
}
static UPNP_PROPERTY *CopyUPNPPARAMtoPROPERTY(DWORD nArgs, UPNPPARAM *rgArgs)
{
UPNP_PROPERTY *rgUpnpProps = new UPNP_PROPERTY [nArgs];
DWORD i;
if (rgUpnpProps)
{
__try {
for (i=0;i<nArgs;i++)
{
rgUpnpProps[i].szName = _wcsdup(rgArgs[i].pszName);
rgUpnpProps[i].szValue = _wcsdup(rgArgs[i].pszValue);
rgUpnpProps[i].dwFlags = 0;
if (!rgUpnpProps[i].szName || !rgUpnpProps[i].szValue)
break;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
if (i<nArgs)
{
FreeUPNP_PROPERTY(i, rgUpnpProps);
rgUpnpProps = NULL;
}
}
return rgUpnpProps;
}
HostedService::~HostedService()
{
delete m_pNextService;
delete m_pszServiceId;
delete m_pszServiceType;
delete m_pszSCPDPath;
if (m_pszaUri)
{
if (m_fEventing)
DeregisterUpnpEventSource(m_pszaUri);
delete m_pszaUri;
}
}
BOOL
HostedService::SsdpRegister(DWORD dwLifeTime, PCWSTR pszDescURL, PCWSTR pszUDN )
{
// publish the service type:
//
m_hSSDPSvc = RegisterSSDPService(dwLifeTime, pszDescURL, pszUDN, m_pszServiceType);
// Register this service as an event source
if (VALIDSSDPH(m_hSSDPSvc))
m_fEventing = RegisterUpnpEventSource(m_pszaUri, 0, NULL);
return (VALIDSSDPH(m_hSSDPSvc) && m_fEventing);
}
BOOL
HostedService::SsdpUnregister()
{
BOOL fRet = TRUE;
if (VALIDSSDPH(m_hSSDPSvc))
fRet = DeregisterUpnpService(m_hSSDPSvc, TRUE);
m_hSSDPSvc = INVALID_HANDLE_VALUE;
if (m_fEventing && m_pszaUri)
{
DeregisterUpnpEventSource(m_pszaUri);
m_fEventing = FALSE;
}
return fRet;
}
BOOL
HostedService::SubmitPropertyEvent(
DWORD dwFlags,
DWORD nArgs,
UPNPPARAM *rgArgs)
{
BOOL fRet;
UPNP_PROPERTY *rgUpnpProps;
// convert to ascii parameter array, understood by eventing subsystem
rgUpnpProps = CopyUPNPPARAMtoPROPERTY(nArgs, rgArgs);
if (!rgUpnpProps)
return FALSE;
fRet = FALSE;
if (m_fEventing)
fRet = SubmitUpnpPropertyEvent(m_pszaUri, dwFlags, nArgs, rgUpnpProps);
FreeUPNP_PROPERTY(nArgs, rgUpnpProps);
return fRet;
}
HostedDevice *
HostedDevice::FindDevice(PCWSTR pszUDN)
{
HostedDevice *pDevice = NULL;
if (wcscmp(pszUDN, m_pszUDN) == 0)
{
return this;
}
// recurse down
if (m_pFirstChildDev && (pDevice = m_pFirstChildDev->FindDevice(pszUDN)))
return pDevice;
// recurse left
if (m_pNextDev)
pDevice = m_pNextDev->FindDevice(pszUDN);
return pDevice;
}
HostedDevice *
HostedDevice::FindByOrigUDN(PCWSTR pszTemplateUDN)
{
HostedDevice *pDevice = NULL;
if (m_pszOrigUDN && wcscmp(pszTemplateUDN, m_pszOrigUDN) == 0)
{
return this;
}
// recurse down
if (m_pFirstChildDev && (pDevice = m_pFirstChildDev->FindByOrigUDN(pszTemplateUDN)))
return pDevice;
// recurse left
if (m_pNextDev)
pDevice = m_pNextDev->FindByOrigUDN(pszTemplateUDN);
return pDevice;
}
HostedService *
HostedDevice::FindService(PCWSTR pszUDN, PCWSTR pszServiceId)
{
HostedService *pService = NULL;
if(0 == wcscmp(pszUDN, m_pszUDN))
for (pService = m_pFirstService; pService; pService = pService->NextService())
{
if (wcscmp(pszServiceId, pService->ServiceId()) == 0)
return pService;
}
// recurse down
if (m_pFirstChildDev && (pService = m_pFirstChildDev->FindService(pszUDN, pszServiceId)))
return pService;
// recurse left
if (m_pNextDev)
pService = m_pNextDev->FindService(pszUDN, pszServiceId);
return pService;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -