⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 announce.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    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 + -