📄 upnpsvc.h
字号:
void CreateUDN(LPWSTR *ppUDN);
LONG IncRef()
{
return InterlockedIncrement(&m_cRef);
}
LONG DecRef()
{
LONG cRef = InterlockedDecrement(&m_cRef);
if (cRef == 0 && m_hShutdownEvent)
SetEvent(m_hShutdownEvent);
return cRef;
}
void AddToList(LIST_ENTRY *pList)
{
InsertHeadList(pList, &m_link);
}
void RemoveFromList()
{
RemoveEntryList(&m_link);
}
PCWSTR UDN()
{
return m_pszUDN;
}
int UDNSuffix()
{
return m_nUDNSuffix;
}
PCWSTR Name()
{
return m_pszName;
}
PCWSTR DescFileName()
{
return m_pszDescFileName;
}
HANDLE OwnerProc()
{
return m_hOwnerProc;
}
HANDLE Owner()
{
return m_hOwner;
}
ce::SAXWriter* SAXWriter()
{
return &m_SAXWriter;
}
HostedService *FindService(PCWSTR szUDN, PCWSTR pszServiceId)
{
return m_pRootDevice ? m_pRootDevice->FindService(szUDN, pszServiceId) : NULL;
}
HostedDevice *FindDevice(PCWSTR pszUDN)
{
return m_pRootDevice ? m_pRootDevice->FindDevice(pszUDN) : NULL;
}
HostedDevice *FindDeviceByOrigUDN(PCWSTR pszTemplateUDN)
{
if (!m_pRootDevice)
return NULL;
// NULL pszTemplateUDN matches the root device
return pszTemplateUDN ? m_pRootDevice->FindByOrigUDN(pszTemplateUDN) : m_pRootDevice;
}
BOOL Initialize(UPNPDEVICEINFO *pDevInfo, HANDLE hOwnerProc, HANDLE hOwner);
static DWORD Initialize2(void *pHDTI);
BOOL Publish();
BOOL Unpublish();
BOOL Subscribe(PCWSTR szUDN, PCWSTR szServiceId);
BOOL Control(ControlRequest *);
BOOL SetControlResponse(DWORD dwHttpStatus, PCWSTR pszResponse);
BOOL Unsubscribe(PCWSTR szUDN, PCWSTR szServiceId);
BOOL DoDeviceCallback(ControlRequest *pControlReq, UPNPCB_ID id, PCWSTR pszUDN, PCWSTR pszServiceId, PCWSTR pszReqXML);
BOOL Shutdown(DWORD flags = 0);
BOOL SubmitPropertyEvent(PCWSTR szUDN, PCWSTR szServiceId, DWORD dwFlags, DWORD nArgs, UPNPPARAM *rgArgs);
// ISAXContentHandler
private:
virtual HRESULT STDMETHODCALLTYPE startDocument(void);
virtual HRESULT STDMETHODCALLTYPE startElement(
/* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
/* [in] */ int cchNamespaceUri,
/* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
/* [in] */ int cchLocalName,
/* [in] */ const wchar_t __RPC_FAR *pwchQName,
/* [in] */ int cchQName,
/* [in] */ ISAXAttributes __RPC_FAR *pAttributes);
virtual HRESULT STDMETHODCALLTYPE endElement(
/* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
/* [in] */ int cchNamespaceUri,
/* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
/* [in] */ int cchLocalName,
/* [in] */ const wchar_t __RPC_FAR *pwchQName,
/* [in] */ int cchQName);
virtual HRESULT STDMETHODCALLTYPE characters(
/* [in] */ const wchar_t __RPC_FAR *pwchChars,
/* [in] */ int cchChars);
virtual HRESULT STDMETHODCALLTYPE endDocument(void);
};
#define SIMPLE_BUFFER_DEFAULT_GRANULARITY 256
//
// This class represents an incoming HTTP/UPNP control request
// It is instantiated on each HttpExtensionProc invocation.
// Parses the request and provides methods to construct the response before it is
// returned to the control point.
//
class ControlRequest
{
//friend BOOL SetRawControlResponse(UPNPSERVICECONTROL *pSvcCtl, DWORD dwHttpStatus,PCWSTR pszResp);
private:
LPEXTENSION_CONTROL_BLOCK m_pecb;
DWORD m_dwHttpStatus; // the status that we respond with (initialized to 200 OK)
HostedDeviceTree *m_pDevTree; // device that is hosting the invoked service
PWSTR m_pszServiceId; // service Id (from the UPNP device description)
PWSTR m_pszUDN;
PWSTR m_pszServiceType; // service type(from the UPNP device description)
PSTR m_pszResponse; // response body, if any
PWSTR m_pszRequestXML; // request body
// the UPNPSERVICECONTROL struct is used for callbacks into the device implementation.
// It contains mapped aliases to the actionName, args etc and should not be freed or generally
// touched.
UPNPSERVICECONTROL m_SvcCtl;
public:
ControlRequest(LPEXTENSION_CONTROL_BLOCK pecb);
~ControlRequest();
BOOL ParseRequest();
BOOL ForwardRequest();
BOOL SetResponse(DWORD dwHttpStatus, PCWSTR pszResp);
BOOL SendResponse();
BOOL StatusOk() { return m_dwHttpStatus == HTTP_STATUS_OK;}
PCWSTR ServiceId(void) { return m_pszServiceId;}
PCWSTR UDN(void) { return m_pszUDN;}
PCWSTR RequestXML(void) { return m_pszRequestXML;}
};
const WCHAR c_szHttpPrefix[] = L"http://";
const WCHAR c_szURLPrefix[] = L"/upnp/";
const WCHAR c_szLocalWebRootDir[] = L"\\windows\\upnp\\";
PSTR StrDupWtoA(LPCWSTR pwszSource);
PWSTR StrDupAtoW(LPCSTR pszaSource);
PWSTR StrDupW(LPCWSTR pwszSource);
BOOL SubscribeCallback(BOOL fSubscribe, PSTR pszUri);
HostedDeviceTree *FindDevTreeAndServiceIdFromUri(PCSTR pszaUri, PWSTR *ppszUDN, PWSTR *ppszSid);
void UpnpCleanUpProc(HANDLE hProc);
/**
* DispatchGate:
*
* - synchronizes one or more 'requestor' threads with a single 'request handler' thread
*
* - requestor sequence:
* EnterGate()
* DoCallback()
* LeaveGate()
*
* - request sequence:
* CheckResetMutexRequestor()
* SetCallerBuffer()
* WaitForRequests()
* DispatchRequests()
*
* - there is one DispatchGate object per process, regardless of number of devices per process.
* - there can be only one request handler thread performing the request sequence.
*/
class DispatchGate
{
/*
The state sequence is:
INVALID -> INITED -> READY -> ENTERED -> REQUEST_WAITING -> REQUEST_HANDLING
-> REQUEST_DONE -> READY
*/
typedef enum {
CBGATE_INVALID,
CBGATE_INITED,
CBGATE_READY,
CBGATE_ENTERED,
CBGATE_REQUEST_WAITING,
CBGATE_REQUEST_HANDLING,
CBGATE_REQUEST_DONE
} CBGateState;
private:
CBGateState m_state;
BOOL m_ResetMutexRequestor; // indicates whether to signal request done
BOOL m_fShuttingDown; // set by CancelReceiveInvokeRequestImpl
LONG m_RefCount; // number of threads accessing the object
HANDLE m_hMutexRequestor; // serialize entry to the gate by requestors
HANDLE m_hEvtRequest; // signaled when new request is created
HANDLE m_hEvtRequestDone; // signaled when request is completed
PBYTE m_pbReqBuf; // request buffer in target proc
PDWORD m_pcbReqBufSize; // the number of bytes written to the request buffer
DWORD m_cbReqBufSize; // max size of target request buffer
DWORD m_dwReturnCode; // return code from request
UpnpInvokeRequestContainer_t *m_UpnpInvokeRequestContainer; // invoke request information
HANDLE GetTargetProc() { return m_hTargetProc; }
public:
DispatchGate(HANDLE hTargetProc);
~DispatchGate();
LONG IncRef();
LONG DecRef();
BOOL EnterGate(DWORD dwTimeout = INFINITE);
BOOL DoCallback(UpnpInvokeRequestContainer_t &requestContainer, DWORD dwTimeout = INFINITE);
BOOL LeaveGate(void);
void CheckResetMutexRequestor(DWORD retCode);
void SetCallerBuffer(PBYTE pbReq, DWORD cbReqSize, PDWORD pcbReqSize);
// prepare for request
BOOL WaitForRequests(DWORD dwTime = INFINITE);
BOOL DispatchRequest(void);
BOOL Shutdown(void);
// dispatch gate list data structure
LIST_ENTRY m_Link;
HANDLE m_hTargetProc; // process in which to dispatch callbacks
static LIST_ENTRY list;
static DispatchGate *FindDispatchGateForProc(HANDLE hProc);
static BOOL AddDispatchGateForProc(HANDLE hProc);
static DispatchGate *RemoveDispatchGateForProc(HANDLE hProc);
static void Link(DispatchGate *pDispatchGate) { InsertHeadList(&list, &pDispatchGate->m_Link); }
static void Unlink(DispatchGate *pDispatchGate) { RemoveEntryList(&pDispatchGate->m_Link); }
};
extern CRITICAL_SECTION g_csUPNP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -