📄 subs.cpp
字号:
// Notes:
//
DWORD ResubscribeTimerProc(VOID *pvContext)
{
UPNP_SUBSCRIBER * pSub = (UPNP_SUBSCRIBER *) pvContext;
UPNP_EVENT_SOURCE *pes;
LPSTR pstrUri;
pSub->fInTimer = TRUE;
pes = pSub->pes;
TraceTag(ttidEvents, "ResubscribeTimerProc: Entering");
EnterCriticalSection(&g_csListEventSource);
//EnterCriticalSection(&(pes->cs));
if (pes->fCleanup)
{
SetEvent(pSub->hEventCleanup);
TraceTag(ttidEvents, "ResubscribeTimerProc: Signalling done event");
pSub->fInTimer = FALSE;
//LeaveCriticalSection(&(pes->cs));
LeaveCriticalSection(&g_csListEventSource);
return 0;
}
TraceTag(ttidEvents, "ResubscribeTimerProc: Leaving");
RemoveFromListSubscriber(pSub);
pstrUri = _strdup(pes->szRequestUri);
//LeaveCriticalSection(&(pes->cs));
LeaveCriticalSection(&g_csListEventSource);
if (pstrUri && pfSubscribeCallback)
{
pfSubscribeCallback(FALSE, pstrUri);
free(pstrUri);
}
pSub->fInTimer = FALSE;
FreeUpnpSubscriber(pSub);
return 0;
}
//+---------------------------------------------------------------------------
//
// Function: RemoveFromListSubscriber
//
// Purpose: Removes the given subscriber from the list within the event
// source.
//
// Arguments:
// pSub [in] Subscriber to be removed
//
// Returns: Nothing
//
// Author: danielwe 13 Oct 1999
//
// Notes:
//
VOID RemoveFromListSubscriber(UPNP_SUBSCRIBER * pSub)
{
InterlockedDecrement(&g_nSubscribers);
RemoveEntryList(&(pSub->linkage));
}
//+---------------------------------------------------------------------------
//
// Function: StartResubscribeTimer
//
// Purpose: Starts the re-subscription timer for a subscription
//
// Arguments:
// pSub [in] Subscription to start timer for
//
// Returns: Nothing
//
// Author: danielwe 13 Oct 1999
//
// Notes:
//
VOID StartResubscribeTimer(UPNP_SUBSCRIBER * pSub)
{
UPNP_EVENT_SOURCE * pes;
pes = pSub->pes;
//EnterCriticalSection(&(pes->cs));
if(!(pSub->dwTimerCookie = g_pThreadPool->StartTimer(ResubscribeTimerProc, pSub, pSub->csecTimeout * 1000)))
{
TraceTag(ttidEvents, "Failed to start subscriber timer.");
RemoveFromListSubscriber(pSub);
FreeUpnpSubscriber(pSub);
}
else
{
TraceTag(ttidEvents, "Started subscriber timer for %d sec.",
pSub->csecTimeout);
}
//LeaveCriticalSection(&(pes->cs));
}
//+---------------------------------------------------------------------------
//
// Function: StopResubscribeTimer
//
// Purpose: Stops the resubscription timer for the given subscription
//
// Arguments:
// pSub [in] Pointer to subscription
//
// Returns: Nothing
//
// Author: danielwe 12 Oct 1999
//
// Notes: WARNING! The event source lock MUST be held before entering
// this function!
//
VOID StopResubscribeTimer(UPNP_SUBSCRIBER * pSub)
{
UPNP_EVENT_SOURCE *pes;
pes = pSub->pes;
pes->fCleanup = TRUE;
TraceTag(ttidEvents, "Stopping Resubscribe timer for pSub 0x%08X", pSub);
if (g_pThreadPool->StopTimer(pSub->dwTimerCookie))
{
TraceTag(ttidEvents, "Resubscribe timer stopped for pSub 0x%08X", pSub);
}
else
{
TraceTag(ttidEvents, "Resubscribe timer wasn't stoppable for"
" pSub 0x%08X", pSub);
if (pSub->fInTimer)
{
// Timer is running. Should rarely happen
TraceTag(ttidEvents, "Resubscribe timer is running, wait ...0x%08X", pSub);
//LeaveCriticalSection(&pes->cs);
WaitForSingleObject(pSub->hEventCleanup, INFINITE);
//EnterCriticalSection(&pes->cs);
}
}
pes->fCleanup = FALSE;
}
//+---------------------------------------------------------------------------
//
// Function: FreeUpnpSubscriber
//
// Purpose: Frees the memory used by a subscrption
//
// Arguments:
// pSub [in] Subscription to free
//
// Returns: Nothing
//
// Author: danielwe 13 Oct 1999
//
// Notes:
//
VOID FreeUpnpSubscriber(UPNP_SUBSCRIBER* pSub)
{
if (pSub)
{
TraceTag(ttidEvents, "Freeing Subscriber: 0x%08X", pSub);
if (pSub->hEventCleanup)
CloseHandle(pSub->hEventCleanup);
if (pSub->szDestUrl)
free(pSub->szDestUrl);
if (pSub->szSid)
free(pSub->szSid);
if (pSub->rgesModified)
free(pSub->rgesModified);
free(pSub);
}
}
//+---------------------------------------------------------------------------
//
// Function: CleanupSubscriberEntry
//
// Purpose: Cleans up memory and related structures used by a subscription
//
// Arguments:
// pSub [in] Subscription to clean up
//
// Returns: Nothing
//
// Author: danielwe 13 Oct 1999
//
// Notes:
//
VOID CleanupSubscriberEntry(UPNP_SUBSCRIBER * pSub)
{
RemoveFromListSubscriber(pSub);
StopResubscribeTimer(pSub);
FreeUpnpSubscriber(pSub);
}
//+---------------------------------------------------------------------------
//
// Function: CleanupListSubscriber
//
// Purpose: Cleans up the subscriber list within an event source.
//
// Arguments:
// pListHead [in] Subscriber list to clean up.
//
// Returns: Nothing
//
// Author: danielwe 13 Oct 1999
//
// Notes:
//
VOID CleanupListSubscriber(PLIST_ENTRY pListHead)
{
PLIST_ENTRY p;
TraceTag(ttidEvents, "----- Cleanup ListSubscriber List -----");
for (p = pListHead->Flink; p != pListHead;)
{
UPNP_SUBSCRIBER * pSub;
pSub = CONTAINING_RECORD (p, UPNP_SUBSCRIBER , linkage);
p = p->Flink;
CleanupSubscriberEntry(pSub);
}
}
#if DBG
VOID PrintSubscription(UPNP_SUBSCRIBER * pSub)
{
TraceTag(ttidEvents, "Subscription at address 0x%08X", pSub);
TraceTag(ttidEvents, "--------------------------------------");
TraceTag(ttidEvents, "Subscription timeout is %d seconds from now.", pSub->csecTimeout);
TraceTag(ttidEvents, "Sequence # : %d", pSub->iSeq);
TraceTag(ttidEvents, "Callback Url: %s", pSub->szDestUrl);
TraceTag(ttidEvents, "SID : %s", pSub->szSid);
TraceTag(ttidEvents, "--------------------------------------");
}
#endif
//+---------------------------------------------------------------------------
//
// Function: DwParseTime
//
// Purpose: Parses the Timeout header for a subscription
//
// Arguments:
// szTime [in] Timeout value in the format defined by RFC2518
//
// Returns: Timeout value in SECONDS
//
// Author: danielwe 13 Oct 1999
//
// Notes: NYI
//
DWORD DwParseTime(LPCSTR szTime)
{
DWORD dwTimeoutSeconds;
if(0 == strcmp(szTime, "Second-infinite"))
dwTimeoutSeconds = upnp_config::max_sub_timeout();
else
{
if(1 != sscanf(szTime, "Second-%d", &dwTimeoutSeconds))
dwTimeoutSeconds = upnp_config::default_sub_timeout();
if(dwTimeoutSeconds < upnp_config::min_sub_timeout())
dwTimeoutSeconds = upnp_config::min_sub_timeout();
if(dwTimeoutSeconds > upnp_config::max_sub_timeout())
dwTimeoutSeconds = upnp_config::max_sub_timeout();
}
return dwTimeoutSeconds;
}
//+---------------------------------------------------------------------------
//
// Function: FParseCallbackUrl
//
// Purpose: Given the Callback URL header value, determines the first
// http:// URL.
//
// Arguments:
// szCallbackUrl [in] URL to process (comes from Callback: header)
// pszOut [out] Returns the callback URL
//
// Returns: TRUE if URL format is valid, FALSE if not or if out of
// memory.
//
// Author: danielwe 13 Oct 1999
//
// Notes:
//
BOOL FParseCallbackUrl(LPCSTR szCallbackUrl, LPSTR *pszOut)
{
CONST INT c_cchPrefix = strlen(c_szUrlPrefix);
LPSTR szTemp;
LPSTR pchPos;
LPSTR szOrig = NULL;
BOOL fResult = FALSE;
// NOTE: This function will return http:// as a URL.. Corner case, but
// not catastrophic
Assert(szCallbackUrl);
Assert(pszOut);
*pszOut = NULL;
// Copy the original URL so we can lowercase
//
szTemp = _strdup(szCallbackUrl);
szOrig = szTemp;
_strlwr(szTemp);
// Look for http://
//
pchPos = strstr(szTemp, c_szUrlPrefix);
if (pchPos)
{
// Look for the closing '>'
szTemp = pchPos + c_cchPrefix;
while (*szTemp && *szTemp != '>')
{
szTemp++;
}
if (*szTemp)
{
ULONG cchOut;
Assert(*szTemp == '>');
// Allocate space for the URL, and copy it in
//
cchOut = szTemp - pchPos; //georgej: removed + 1
__assume(cchOut < ULONG_MAX);
*pszOut = (LPSTR) malloc(cchOut + 1);
if (*pszOut)
{
strncpy(*pszOut, szCallbackUrl + (pchPos - szOrig), cchOut);
(*pszOut)[cchOut] = 0;
fResult = TRUE;
}
}
}
free(szOrig);
TraceResult("FParseCallbackUrl", fResult);
return fResult;
}
//+---------------------------------------------------------------------------
//
// Function: SzGetNewSid
//
// Purpose: Returns a new "uuid:<sid>" identifier
//
// Arguments:
// (none)
//
// Returns: Newly allocated SID string
//
// Author: danielwe 13 Oct 1999
//
// Notes: Caller must free the returned string
//
LPSTR SzGetNewSid()
{
#ifndef UNDER_CE
CHAR szSid[256];
UUID uuid;
unsigned char * szUuid;
UuidCreate(&uuid);
UuidToStringA(&uuid, &szUuid);
sprintf(szSid, "uuid:%s", szUuid);
RpcStringFreeA(&szUuid);
return _strdup(szSid);
#else
PCHAR pszSid = (PCHAR)malloc(42);
LONGLONG uuid64 = GenerateUUID64();
if (pszSid)
sprintf(pszSid, "uuid:%04x%04x-%04x-%04x-0000-000000000000", (WORD)uuid64, *((WORD*)&uuid64 + 1), *((WORD*)&uuid64 + 2), *((WORD*)&uuid64 + 3));
return pszSid;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -