📄 announce.cpp
字号:
PrintSSDPService(pssdpService);
#endif
LeaveCriticalSection(&CSListAnnounce);
return pssdpService;
}
VOID FreeSSDPService(SSDP_SERVICE *pSSDPSvc)
{
//
// We have to make sure that no thread has any reference to this service at this point
// Do we need ref count?
//
Assert(pSSDPSvc);
pSSDPSvc->SsdpRequest.Headers[SSDP_NTS] = NULL; // make sure this header element is not freed.
pSSDPSvc->SsdpRequest.RequestUri = NULL; //make sure this header element is not freed
FreeSsdpRequest(&(pSSDPSvc->SsdpRequest));
DeleteCriticalSection(&(pSSDPSvc->CSService));
CloseHandle(pSSDPSvc->CleanupEvent);
free(pSSDPSvc);
}
VOID RemoveFromListAnnounce(SSDP_SERVICE *pssdpSvc)
{
EnterCriticalSection(&CSListAnnounce);
EnterCriticalSection(&pssdpSvc->CSService);
RemoveEntryList(&(pssdpSvc->linkage));
#ifdef DEBUG
PrintSSDPService(pssdpSvc);
#endif
LeaveCriticalSection(&pssdpSvc->CSService);
//PrintList(&listAnnounce);
LeaveCriticalSection(&CSListAnnounce);
}
BOOL IsInListAnnounce(CHAR *szUSN)
{
PLIST_ENTRY p;
LIST_ENTRY *pListHead = &listAnnounce;
BOOL found = FALSE;
EnterCriticalSection(&CSListAnnounce);
for (p = pListHead->Flink; p != pListHead; p = p->Flink)
{
SSDP_SERVICE *pService;
pService = CONTAINING_RECORD (p, SSDP_SERVICE, linkage);
EnterCriticalSection(&(pService->CSService));
if (strcmp(pService->SsdpRequest.Headers[SSDP_USN], szUSN) == 0)
{
found = TRUE;
LeaveCriticalSection(&(pService->CSService));
break;
}
LeaveCriticalSection(&(pService->CSService));
}
LeaveCriticalSection(&CSListAnnounce);
return found;
}
// It is necessary to hold the list lock while comparing type and put in the PSRT.
VOID SearchListAnnounce(SSDP_REQUEST *SsdpMessage, SOCKET sockRecv, PSOCKADDR_STORAGE pRemoteAddr)
{
PLIST_ENTRY p;
LIST_ENTRY *pListHead = &listAnnounce;
EnterCriticalSection(&CSListAnnounce);
for (p = pListHead->Flink; p != pListHead; p = p->Flink)
{
SSDP_SERVICE *pService;
pService = CONTAINING_RECORD (p, SSDP_SERVICE, linkage);
EnterCriticalSection(&(pService->CSService));
if (strcmp(SsdpMessage->Headers[SSDP_ST], "ssdp:all") == 0 ||
strncmp(SsdpMessage->Headers[SSDP_ST], pService->SsdpRequest.Headers[SSDP_NT], strlen(SsdpMessage->Headers[SSDP_ST])) == 0)
{
PSSDP_SEARCH_RESPONSE ResponseEntry;
ResponseEntry = (PSSDP_SEARCH_RESPONSE) malloc(sizeof(SSDP_SEARCH_RESPONSE));
if (ResponseEntry == NULL)
{
TraceTag(ttidError, "Failed to allocate response "
"entry.");
LeaveCriticalSection(&(pService->CSService));
continue;
}
if (InitializeSearchResponseFromRequest(ResponseEntry,
SsdpMessage,
sockRecv,
pRemoteAddr) == FALSE)
{
LeaveCriticalSection(&(pService->CSService));
continue;
}
ResponseEntry->Owner = pService;
InsertHeadList(&(pService->listSearchResponse),
&(ResponseEntry->linkage));
StartSearchResponseTimer(ResponseEntry, SearchResponseTimerProc);
}
LeaveCriticalSection(&(pService->CSService));
}
LeaveCriticalSection(&CSListAnnounce);
}
PCONTEXT_HANDLE_TYPE * GetServiceByUSN(CHAR *szUSN)
{
PLIST_ENTRY p;
LIST_ENTRY *pListHead = &listAnnounce;
EnterCriticalSection(&CSListAnnounce);
for (p = pListHead->Flink; p != pListHead; p = p->Flink)
{
SSDP_SERVICE *pService;
pService = CONTAINING_RECORD (p, SSDP_SERVICE, linkage);
EnterCriticalSection(&(pService->CSService));
if (strcmp(pService->SsdpRequest.Headers[SSDP_USN], szUSN) == 0)
{
LeaveCriticalSection(&(pService->CSService));
LeaveCriticalSection(&CSListAnnounce);
return pService->RpcContextHandle;
}
else
{
LeaveCriticalSection(&(pService->CSService));
}
}
LeaveCriticalSection(&CSListAnnounce);
return NULL;
}
VOID PrintList(LIST_ENTRY *pListHead)
{
PLIST_ENTRY p;
int i = 1;
TraceTag(ttidSsdpAnnounce, "----- SSDP Announcement List -----");
EnterCriticalSection(&CSListAnnounce);
for (p = pListHead->Flink; p != pListHead; p = p->Flink, i++)
{
SSDP_SERVICE *pService;
TraceTag(ttidSsdpAnnounce, "----- SSDP Service Content %d -----", i);
pService = CONTAINING_RECORD (p, SSDP_SERVICE, linkage);
PrintSSDPService(pService);
}
LeaveCriticalSection(&CSListAnnounce);
}
VOID CleanupAnnounceEntry (SSDP_SERVICE *pService)
{
EnterCriticalSection(&CSListAnnounce);
EnterCriticalSection(&pService->CSService);
RemoveEntryList(&(pService->linkage));
LeaveCriticalSection(&pService->CSService);
LeaveCriticalSection(&CSListAnnounce);
StopAnnounceTimer(pService);
CleanupListSearchResponse(&(pService->listSearchResponse));
}
VOID CleanupListAnnounce()
{
PLIST_ENTRY p;
PLIST_ENTRY pListHead = &listAnnounce;
TraceTag(ttidSsdpAnnounce, "----- Cleanup SSDP Announcement List -----");
EnterCriticalSection(&CSListAnnounce);
for (p = pListHead->Flink; p && p != pListHead;)
{
SSDP_SERVICE *pService;
pService = CONTAINING_RECORD (p, SSDP_SERVICE, linkage);
p = p->Flink;
EnterCriticalSection(&pService->CSService);
pService->state = SERVICE_NO_MASTER_CLEANUP;
LeaveCriticalSection(&pService->CSService);
CleanupAnnounceEntry(pService);
FreeSSDPService(pService);
}
LeaveCriticalSection(&CSListAnnounce);
DeleteCriticalSection(&CSListAnnounce);
}
VOID PrintSSDPService(const SSDP_SERVICE *pSSDPService)
{
PrintSsdpRequest(&(pSSDPService->SsdpRequest));
}
BOOL InitializeSsdpRequestFromMessage(SSDP_REQUEST *pRequest,
const SSDP_MESSAGE *pssdpSrc)
{
CHAR buffer[BUF_SIZE];
InitializeSsdpRequest(pRequest);
pRequest->Method = SSDP_NOTIFY;
if (pssdpSrc->szType != NULL)
{
pRequest->Headers[SSDP_NT] = (CHAR *) malloc(sizeof(CHAR) *
(strlen(pssdpSrc->szType) + 1));
if (pRequest->Headers[SSDP_NT] == NULL)
{
TraceTag(ttidError, "Failed to allocate memory for SSDP Headers");
return FALSE;
}
strcpy(pRequest->Headers[SSDP_NT], pssdpSrc->szType);
}
if (pssdpSrc->szUSN != NULL)
{
pRequest->Headers[SSDP_USN] = (CHAR*) malloc(sizeof(CHAR) *
(strlen(pssdpSrc->szUSN) + 1));
if (pRequest->Headers[SSDP_USN] == NULL)
{
TraceTag(ttidError, "Failed to allocate memory for SSDP Headers");
return FALSE;
}
strcpy(pRequest->Headers[SSDP_USN], pssdpSrc->szUSN);
}
if (pssdpSrc->szAltHeaders != NULL)
{
pRequest->Headers[SSDP_AL] = (CHAR*) malloc(sizeof(CHAR) *
(strlen(pssdpSrc->szAltHeaders) + 1));
if (pRequest->Headers[SSDP_AL] == NULL)
{
TraceTag(ttidError, "Failed to allocate memory for SSDP Headers");
return FALSE;
}
strcpy(pRequest->Headers[SSDP_AL], pssdpSrc->szAltHeaders);
}
if (pssdpSrc->szNls != NULL)
{
pRequest->Headers[SSDP_NLS] = (CHAR*) malloc(sizeof(CHAR) *
(strlen(pssdpSrc->szNls) + 1));
if (pRequest->Headers[SSDP_NLS] == NULL)
{
TraceTag(ttidError, "Failed to allocate memory for SSDP Headers");
return FALSE;
}
strcpy(pRequest->Headers[SSDP_NLS], pssdpSrc->szNls);
}
if (pssdpSrc->szLocHeader != NULL)
{
pRequest->Headers[SSDP_LOCATION] = (CHAR*) malloc(sizeof(CHAR) *
(strlen(pssdpSrc->szLocHeader) + 1));
if (pRequest->Headers[SSDP_LOCATION] == NULL)
{
TraceTag(ttidSsdpAnnounce, "Failed to allocate memory for SSDP Headers");
return FALSE;
}
strcpy(pRequest->Headers[SSDP_LOCATION], pssdpSrc->szLocHeader);
}
_itoa(pssdpSrc->iLifeTime,buffer, 10);
pRequest->Headers[SSDP_CACHECONTROL] = (CHAR *) malloc(sizeof(CHAR) *
(strlen("max-age=") +
strlen(buffer) + 1));
if (pRequest->Headers[SSDP_CACHECONTROL] == NULL)
{
TraceTag(ttidSsdpAnnounce, "Failed to allocate memory for SSDP Headers");
return FALSE;
}
sprintf(pRequest->Headers[SSDP_CACHECONTROL], "max-age=%d",
pssdpSrc->iLifeTime);
// need enough space for major version and minor version
pRequest->Headers[SSDP_SERVER]= (CHAR *) malloc(sizeof(c_szServerVersion)+5+5);
if (pRequest->Headers[SSDP_SERVER] == NULL)
{
TraceTag(ttidSsdpAnnounce, "Failed to allocate memory for SSDP Headers");
return FALSE;
}
sprintf(pRequest->Headers[SSDP_SERVER],c_szServerVersion,CE_MAJOR_VER, CE_MINOR_VER);
return TRUE;
}
BOOL RegisterUpnpServiceIoctl(
__in ce::marshal_arg<ce::copy_in, PSSDP_MESSAGE> pSsdpMessage,
__in DWORD flags,
__out ce::marshal_arg<ce::copy_out, HANDLE*> phService)
{
if(!pSsdpMessage || !phService)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return RegisterUpnpServiceImpl(pSsdpMessage, flags, phService);
}
// Publication
BOOL RegisterUpnpServiceImpl(PSSDP_MESSAGE pSsdpMessage, DWORD flags, HANDLE* phService)
{
DWORD error = ERROR_SUCCESS;
PSSDP_SERVICE pSSDPSvc;
if (InterlockedExchange(&cInitialized, cInitialized) == 0)
{
error = ERROR_NOT_READY;
}
else if (pSsdpMessage->szUSN == NULL || pSsdpMessage->szType == NULL)
{
error = ERROR_INVALID_PARAMETER;
}
else if (pSsdpMessage->szAltHeaders == NULL && pSsdpMessage->szLocHeader == NULL)
{
error = ERROR_INVALID_PARAMETER;
}
else if (IsInListAnnounce(pSsdpMessage->szUSN))
{
error = ERROR_DUPLICATE_SERVICE;
}
else if ((pSSDPSvc = AddToListAnnounce(pSsdpMessage, flags, NULL /* pphContext */)) == NULL)
{
error = ERROR_NOT_ENOUGH_MEMORY;
}
else
{
// send on all networks
EnterCriticalSection(&pSSDPSvc->CSService);
pSSDPSvc->SsdpRequest.Headers[SSDP_NTS] = AliveHeader;
SendAnnouncement(pSSDPSvc);
LeaveCriticalSection(&pSSDPSvc->CSService);
// We need a timer for each network, but one list for all networks.
StartAnnounceTimer(pSSDPSvc, AnnounceTimerProc);
*phService = (HANDLE)pSSDPSvc;
return TRUE;
}
SetLastError(error);
*phService = INVALID_HANDLE_VALUE;
return FALSE;
}
BOOL WINAPI DeregisterUpnpService(HANDLE hRegister, BOOL fByebye)
{
return DeregisterUpnpServiceImpl((ce::PSL_HANDLE)hRegister, fByebye);
}
BOOL DeregisterUpnpServiceImpl(ce::PSL_HANDLE hRegister, BOOL fByebye)
{
SSDP_SERVICE *pSSDPSvc = (SSDP_SERVICE *) (hRegister);
DWORD error = ERROR_SUCCESS;
TraceTag(ttidSsdpAnnounce, "%x is being deregistered.", pSSDPSvc);
if (InterlockedExchange(&cInitialized, cInitialized) == 0)
{
error = ERROR_NOT_READY;
}
else if (!hRegister || (INVALID_HANDLE_VALUE == hRegister))
{
error = ERROR_INVALID_PARAMETER;
}
else if (pSSDPSvc->Type != SSDP_SERVICE_SIGNATURE)
{
TraceTag(ttidSsdpAnnounce, "%x has type %d, not valid", pSSDPSvc, pSSDPSvc->Type);
error = ERROR_INVALID_PARAMETER;
}
else
{
EnterCriticalSection(&(pSSDPSvc->CSService));
if (pSSDPSvc->state != SERVICE_ACTIVE_NO_MASTER &&
pSSDPSvc->state != SERVICE_ACTIVE_W_MASTER)
{
// Ignore possible duplicate deregistration
LeaveCriticalSection(&(pSSDPSvc->CSService));
TraceTag(ttidSsdpAnnounce, "%x is not active.", pSSDPSvc);
error = ERROR_INVALID_PARAMETER;
}
else
{
pSSDPSvc->state = SERVICE_NO_MASTER_CLEANUP;
LeaveCriticalSection(&(pSSDPSvc->CSService));
CleanupAnnounceEntry(pSSDPSvc);
// Annoucement timer should be stopped by now and entry is not on listAnnounce.
// To-Do: What if system service goes down when we are sending byebye?
// Check for NT service.
if (fByebye)
{
ResetEvent(pSSDPSvc->CleanupEvent);
EnterCriticalSection(&pSSDPSvc->CSService);
pSSDPSvc->SsdpRequest.Headers[SSDP_NTS] = ByebyeHeader;
SendAnnouncement(pSSDPSvc);
LeaveCriticalSection(&pSSDPSvc->CSService);
StartAnnounceTimer(pSSDPSvc, ByebyeTimerProc);
}
else
{
FreeSSDPService(pSSDPSvc);
}
return TRUE;
}
}
SetLastError(error);
return FALSE;
}
BOOL WINAPI DeregisterUpnpServiceByUSN(
/* [string][in] */ LPSTR szUSN,
/* [in] */ BOOL fByebye)
{
HANDLE handle = (HANDLE)GetServiceByUSN((LPSTR)szUSN);
if (handle != NULL)
{
return DeregisterUpnpService(handle, fByebye);
}
else
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -