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

📄 cache.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                                 is running, skip remove!", CacheEntry);
                    }
                } else 
                {
                    TraceTag(ttidSsdpCache, "Byebye for %x which is not current earliest, just remove", CacheEntry); 
                    RemoveEntryWithNotification(CacheEntry, pSsdpRequest); 
                }

            }
            else
            {
                // alive or search result, cache list owns the memory in SsdpRequest if updated
                if (CacheEntry != pCacheEntryFirst)
                {
                    bRetVal = UpdateCacheEntry(CacheEntry, pSsdpRequest);
                } else 
                {
                    if (CTEStopTimer(&timerCleanup))
                    {
                        bRetVal = UpdateCacheEntry(CacheEntry, pSsdpRequest);
                        
                        StartCacheCleanupTimer(); 
                    
                    } else 
                    {
                        // Too late, the timer has fired. 
                        // The current entry will be removed by timer proc. 
                        // Insert a new one. 

                        found = FALSE;
                        break;
                    }
                }

            }
#ifdef DBG
            PrintListCache();
#endif // DBG
            break; 
        }
    }

    if (!found && !IsByebye && IsSubscribed)
    {
        PSSDP_CACHE_ENTRY CacheEntry = CreateCacheEntryFromRequest(pSsdpRequest,0);
        if (CacheEntry != NULL)
        {
            AddToListCache(CacheEntry);
            TraceTag(ttidSsdpCache, "Created cache entry %x", CacheEntry);
            bRetVal = TRUE; 
#ifdef DBG
            PrintListCache();
#endif // DBG
        }
        else
        {
            TraceTag(ttidSsdpCache, "Couldn't create cache entry");
        }
    } 

    LeaveCriticalSection(&CSListCache);

    return bRetVal; 
}

VOID PrintCacheEntry(SSDP_CACHE_ENTRY *CacheEntry)
{
    CHAR szBuf[BUF_SIZE];

    TraceTag(ttidSsdpCache, "----- SSDP Cache Entry %x-----",CacheEntry);

    FileTimeToString(FILETIME_FROM_ULONGLONG(CacheEntry->ExpireTime), szBuf, BUF_SIZE);

    TraceTag(ttidSsdpCache, "Expired ? : %d", CacheEntryExpired(CacheEntry));
    TraceTag(ttidSsdpCache, "Expire Time is %s", szBuf);

    PrintSsdpRequest(&CacheEntry->SsdpRequest);
}

VOID PrintListCache()
{
    PLIST_ENTRY p;
    LIST_ENTRY *pListHead = &listCache;

    TraceTag(ttidSsdpCache, "----- SSDP Cache List -----");

    EnterCriticalSection(&CSListCache);

    for (p = pListHead->Flink; p != pListHead; p = p->Flink)
    {

        SSDP_CACHE_ENTRY *CacheEntry;

        CacheEntry = CONTAINING_RECORD (p, SSDP_CACHE_ENTRY, linkage);

        PrintCacheEntry(CacheEntry);

    }
    LeaveCriticalSection(&CSListCache);
}

BOOL WriteCacheEntryToFile(HANDLE CacheFile, PSSDP_CACHE_ENTRY CacheEntry)
{
    CHAR *Buffer = NULL;
    DWORD BufferSize = 0;
    DWORD BytesWritten = 0;

    if(!ComposeSsdpRequest(&CacheEntry->SsdpRequest, &Buffer))
    {
        TraceTag(ttidSsdpCache, "----- ComposeSsdpRequest failed");
        return FALSE;
    }
    BufferSize = strlen(Buffer) + 1;

    // Write the absolute expire time to file.

    WriteFile(CacheFile, (CHAR *) &BufferSize, sizeof(INT), &BytesWritten, NULL);
    if (BytesWritten != sizeof(INT))
    {
        TraceTag(ttidSsdpCache, "----- Write size failed. %d written, should be "
                 "%d -----", BytesWritten, BufferSize);
        free(Buffer);
        return FALSE;
    }

    WriteFile(CacheFile, Buffer, BufferSize, &BytesWritten, NULL);
    free(Buffer);
   
    if (BufferSize != BytesWritten)
    {
        TraceTag(ttidSsdpCache, "----- Write failed. %d written, should "
                 "be %d -----", BytesWritten, BufferSize);
        return FALSE;
    }

    WriteFile(CacheFile, (CHAR *) &CacheEntry->ExpireTime, 
              sizeof(ULONGLONG), &BytesWritten, NULL); 

    if (BytesWritten != sizeof(ULONGLONG))
    {
        TraceTag(ttidSsdpCache, "----- Write Expire time failed. %d written, should be "
                 "%d -----", BytesWritten, BufferSize);
        return FALSE;
    }

    return TRUE;
}

VOID ReadCacheFileToList()
{
    HANDLE CacheFile;
    DWORD EntrySize;
    DWORD BytesRead = 0;

    TCHAR CacheFilePath[BUF_SIZE]; 

    TraceTag(ttidSsdpCache, "----- Reading SSDP Cache File -----");

#ifdef UNDER_CE
    memcpy(CacheFilePath,g_szWinDir,sizeof(g_szWinDir));
#else
    GetEnvironmentVariable(g_szSystemDir, CacheFilePath, BUF_SIZE); 
#endif    

    lstrcat(CacheFilePath, g_szCacheFileName);  

    CacheFile = CreateFile(CacheFilePath, GENERIC_READ, 0, NULL,
                           OPEN_EXISTING, 0, NULL);
    if (CacheFile == INVALID_HANDLE_VALUE)
    {
        TraceTag(ttidSsdpCache, "Failed to open cache file, error (%d).",
                 GetLastError());
        // To-Do: Event Log.
        return;
    }

    while (ReadFile(CacheFile, (CHAR *) &EntrySize, sizeof(INT),
                    &BytesRead, NULL) && BytesRead > 0)
    {
        CHAR *Buffer;
        SSDP_REQUEST SsdpRequest;
        ULONGLONG ExpireTime; 
        PSSDP_CACHE_ENTRY CacheEntry; 
        BOOL bOK;

        Assert(EntrySize > 0);

        // Should terminate with '\0'
        Buffer = (CHAR *) malloc(sizeof(CHAR) * EntrySize);
        if(!Buffer)
        {
            TraceTag(ttidSsdpCache, "%s:  OOM allocating Buffer.", __FUNCTION__);
            break;
        }

        bOK = ReadFile(CacheFile, Buffer, EntrySize, &BytesRead, NULL);

        if (!bOK || BytesRead != EntrySize)
        {
            TraceTag(ttidSsdpCache, "Need %d, read %d, error %d.", EntrySize,
                     BytesRead, GetLastError());
            return;
        }
        Assert(Buffer[EntrySize-1] == '\0');

        bOK = ReadFile(CacheFile, (CHAR *) &ExpireTime, sizeof(ULONGLONG),
                 &BytesRead, NULL); 

        if (!bOK || BytesRead != sizeof(ULONGLONG))
        {
            TraceTag(ttidSsdpCache, "Need %d, read %d, error %d.", sizeof(ULONGLONG),
                     BytesRead, GetLastError());
            return;
        }

        InitializeSsdpRequest(&SsdpRequest);

        ParseHeaders(Buffer, &SsdpRequest);

        CacheEntry = CreateCacheEntryFromRequest(&SsdpRequest,ExpireTime);
        if (CacheEntry != NULL && !CacheEntryExpired(CacheEntry))
        {
            AddToListCache(CacheEntry);
            TraceTag(ttidSsdpCache, "Created cache entry %x", CacheEntry);
        }
        else
        {
            TraceTag(ttidSsdpCache, "Couldn't create cache entry");
            FreeSsdpRequest(&SsdpRequest); 
        }

        if(Buffer)
            free(Buffer);
    }

    CloseHandle(CacheFile);
}

VOID WriteListCacheToFile()
{
    PLIST_ENTRY p;
    LIST_ENTRY *pListHead = &listCache;
    HANDLE CacheFile;
    TCHAR CacheFilePath[BUF_SIZE]; 

    TraceTag(ttidSsdpCache, "----- Writing SSDP Cache List to File -----");

#ifdef UNDER_CE
    memcpy(CacheFilePath,g_szWinDir,sizeof(g_szWinDir));
#else
    GetEnvironmentVariable(g_szSystemDir, CacheFilePath, BUF_SIZE);
#endif

    lstrcat(CacheFilePath, g_szCacheFileName);  

    CacheFile = CreateFile(CacheFilePath, GENERIC_WRITE, 0, NULL,
                           CREATE_ALWAYS, 0, NULL);

    if (CacheFile == INVALID_HANDLE_VALUE)
    {
        TraceTag(ttidSsdpCache, "Failed to open file to write the cache. (%d)",
                 GetLastError());
        // To-Do: Event Log.
        return;
    }

    EnterCriticalSection(&CSListCache);

    for (p = pListHead->Flink; p != pListHead; p = p->Flink)
    {
        SSDP_CACHE_ENTRY *CacheEntry;

        CacheEntry = CONTAINING_RECORD (p, SSDP_CACHE_ENTRY, linkage);

        WriteCacheEntryToFile(CacheFile, CacheEntry);
    }

    LeaveCriticalSection(&CSListCache);
    CloseHandle(CacheFile);
}

BOOL CacheEntryExpired(SSDP_CACHE_ENTRY *CacheEntry)
{
    FILETIME TempTime;

    ULONGLONG CurrentTime;

#ifdef DBG
    CHAR szBuf[BUF_SIZE];
#endif // DBG

    GetSystemTimeAsFileTime(&TempTime);

    // FILETIME is in 100 nano seconds, max-age is in seconds.
    CurrentTime = ULONGLONG_FROM_FILETIME(TempTime); 

#ifdef DBG
    FileTimeToString(TempTime, szBuf, BUF_SIZE);

    TraceTag(ttidSsdpCache, "Current Time is %s", szBuf);

    FileTimeToString(FILETIME_FROM_ULONGLONG(CacheEntry->ExpireTime), szBuf, BUF_SIZE);

    TraceTag(ttidSsdpCache, "Expire Time is %s", szBuf);
#endif // DBG

    if (CurrentTime < CacheEntry->ExpireTime)
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

INT SearchListCache(CHAR *szType, SSDP_MESSAGE ***svcList)
{
    LIST_ENTRY *pListHead = &listCache;
    PLIST_ENTRY p;
    SSDP_MESSAGE **pSsdpMessageList = NULL;

    INT nHits = 0;

    

    EnterCriticalSection(&CSListCache);

    TraceTag(ttidSsdpCache, "Searching cache list for %s", szType);

    // First scan cache to calculate number of matches
    p = pListHead->Flink;
    while (p != pListHead)
    {
        SSDP_CACHE_ENTRY *CacheEntry;

        CacheEntry = CONTAINING_RECORD (p, SSDP_CACHE_ENTRY, linkage);

        p = p->Flink;

        if (CacheEntryExpired(CacheEntry))
        {
            TraceTag(ttidSsdpCache, " !!!!! WARNING !!!!!! : Cache entry 0x%08X has expired. Continue to the next one.",
                     CacheEntry);
            continue;
        }

        // To-Do: Should this be case insensitive?

        if ((strcmp(szType, "ssdp:all") == 0) ||
            (CacheEntry->SsdpRequest.Headers[SSDP_NT] != NULL &&
             strcmp(CacheEntry->SsdpRequest.Headers[SSDP_NT], szType) == 0) ||
            (CacheEntry->SsdpRequest.Headers[SSDP_ST] != NULL &&
             strcmp(CacheEntry->SsdpRequest.Headers[SSDP_ST], szType) == 0))
        {
            nHits++;
        }
    }
    if (nHits)
    {
        // allocate memory
        pSsdpMessageList = (PSSDP_MESSAGE *)malloc(sizeof(PSSDP_MESSAGE) * nHits);
        nHits = 0;
        if (pSsdpMessageList)
        {
            // Now scan cache to copy the matched contents
            p = pListHead->Flink;
            while (p != pListHead)
            {
                SSDP_CACHE_ENTRY *CacheEntry;

                CacheEntry = CONTAINING_RECORD (p, SSDP_CACHE_ENTRY, linkage);

                p = p->Flink;

                if (CacheEntryExpired(CacheEntry))
                {
                    TraceTag(ttidSsdpCache, " !!!!! WARNING !!!!!! : Cache entry 0x%08X has expired. Continue to the next one.",
                             CacheEntry);
                    continue;
                }

                
                // To-Do: Should this be case insensitive?

                if ((strcmp(szType, "ssdp:all") == 0) ||
                    (CacheEntry->SsdpRequest.Headers[SSDP_NT] != NULL &&
                     strcmp(CacheEntry->SsdpRequest.Headers[SSDP_NT], szType) == 0) ||
                    (CacheEntry->SsdpRequest.Headers[SSDP_ST] != NULL &&
                     strcmp(CacheEntry->SsdpRequest.Headers[SSDP_ST], szType) == 0))
                {
                    pSsdpMessageList[nHits] = InitializeSsdpMessageFromRequest(&CacheEntry->SsdpRequest);
                    if (!pSsdpMessageList[nHits])
                        break;  // out of memory
                    ++nHits;
                }
            }

        }
    }
    *svcList = pSsdpMessageList;
    LeaveCriticalSection(&CSListCache);

    return nHits;
}

void FreeSsdpMessageList(SSDP_MESSAGE **pSsdpMessageList, int nEntries)
{
    Assert(pSsdpMessageList);
    int i;
    for (i=0; i < nEntries;i++)
    {
        if (pSsdpMessageList[i])
            FreeSsdpMessage(pSsdpMessageList[i]);
    }
    free(pSsdpMessageList);
}

VOID FileTimeToString(FILETIME FileTime, CHAR *szBuf, INT BufSize)
{
    SYSTEMTIME SystemTime;
    INT Size;

    FileTimeToLocalFileTime(&FileTime, &FileTime);

    FileTimeToSystemTime(&FileTime,&SystemTime);

#ifdef UNDER_CE
    WCHAR wszTemp[128];
    Size=GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &SystemTime, NULL,
                          wszTemp, min(sizeof(wszTemp)/sizeof(WCHAR),BufSize-1) );
    wcstombs(szBuf,wszTemp,Size);

    szBuf[Size-1] = ' ';
    szBuf += Size;
    
    Size= GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, 0, &SystemTime, NULL,
                   wszTemp, min(sizeof(wszTemp)/sizeof(WCHAR),BufSize-Size));
    wcstombs(szBuf, wszTemp, Size);
#else
    Size = GetDateFormatA(LOCALE_SYSTEM_DEFAULT, 0, &SystemTime, NULL,
                          szBuf, BufSize-1 );
    szBuf[Size-1] = ' ';
    GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &SystemTime, NULL,
                   szBuf+Size, BufSize-Size);
#endif                   
}


VOID InitializeSsdpRequestFromMessage(
    PSSDP_REQUEST pSsdpRequest,
    const SSDP_MESSAGE *pSsdpMessage)
{
    memset(pSsdpRequest,0, sizeof(SSDP_REQUEST));
    pSsdpRequest->Method = SSDP_NOTIFY;
    pSsdpRequest->Headers[SSDP_NT] = SsdpDup(pSsdpMessage->szType);
    pSsdpRequest->Headers[SSDP_LOCATION] = SsdpDup(pSsdpMessage->szLocHeader);
    pSsdpRequest->Headers[SSDP_USN] = SsdpDup(pSsdpMessage->szUSN);
    if ((int)(pSsdpMessage->iLifeTime) >= 0
        && (pSsdpRequest->Headers[SSDP_CACHECONTROL] = (LPSTR)SsdpAlloc(64)))
    {
        sprintf(pSsdpRequest->Headers[SSDP_CACHECONTROL],"max-age=%d", pSsdpMessage->iLifeTime);
    }
}

// Public APIs
VOID _UpdateCache(PSSDP_MESSAGE pSsdpMessage)
{
    SSDP_REQUEST SsdpRequest;


    InitializeSsdpRequestFromMessage(&SsdpRequest, pSsdpMessage);

    if (UpdateListCache(&SsdpRequest, TRUE) == FALSE)
    {
        FreeSsdpRequest(&SsdpRequest);
    }
}


//+---------------------------------------------------------------------------
//
//  Function:   CleanupCache
//
//  Purpose:    Public API to clean up SSDP cache
//
BOOL WINAPI _CleanupCache()
{
    BOOL    fResult = TRUE;

    if (cInitialized == 0)
    {
        SetLastError(ERROR_NOT_READY);
        return FALSE;
    }

    CleanupListCache();

    TraceResult("CleanupCache", fResult);
    return fResult;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -