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

📄 db.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//DB.cpp: Implementation of CVoipDB

#include "DB.h"

BOOL operator==(const SORTORDERSPEC &c_sort1, const SORTORDERSPEC &c_sort2)
{
    return !memcmp(&c_sort1, &c_sort2, sizeof(SORTORDERSPEC));
}
BOOL operator!=(const SORTORDERSPEC &c_sort1, const SORTORDERSPEC &c_sort2)
{
    return !(c_sort1 == c_sort2);
}

//Destructor: Closes db handle and cleans up resources
CVoipDB::~CVoipDB()
{
    if (m_Database != INVALID_HANDLE_VALUE)
    {
        CloseHandle(m_Database);
    }

    CEGUID  Zeros = {0};
    if (memcmp(&Zeros, &m_guidDB, sizeof(CEGUID)) != 0)
    {
        CeUnmountDBVol(&m_guidDB);
    }
}

/*--------------------
Constructor
    Params: [in]Database Name, [in] Number of properties in a record
    Makes a new instance of this database, that must be initialized to work
----------------------*/
CVoipDB::CVoipDB(
    DWORD dwNumProps
    )
{
    //Set default properties  - not initialized, no entries, max entries, handle is invalid
    //And no versioning number yet
    m_Initialized       = FALSE;
    m_CurrentNumEntries = 0;
    m_MaxNumEntries     = INFINITE;
    m_NumProps          = dwNumProps;
    
    m_Database          = INVALID_HANDLE_VALUE;
    m_oidDB             = 0;
    m_CurrentSeek       = 0;

    ZeroMemory(&m_guidDB, sizeof(m_guidDB));
    ZeroMemory(m_pName, sizeof(m_pName));
}

/*-------------------
Function: Initialize
    Performs underlying CE DB functions to initialize the underlying DB and member variables
    returns: TRUE on success, FALSE on failure
-------------------*/
HRESULT CVoipDB::Initialize(
    const WCHAR*     pName,
    SORTORDERSPECEX* pSort
    )
{
    if (! pName)
    {
        ASSERT(FALSE);
        return E_POINTER;
    }

    if (m_Initialized)
    {
        return HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);
    }

    //copy the name
    StringCchCopy(
        m_pName, 
        _countof(m_pName),
        pName
        );

    //mount the volume
    if (! CeMountDBVol(&m_guidDB, VOIP_DB_VOL_NAME, OPEN_ALWAYS))
    {
        ASSERT(FALSE);
        return HRESULT_FROM_WIN32(GetLastError());
    }

    //Open the database
    HRESULT hr = Open(pSort);
    if (FAILED(hr))
    {
        CeUnmountDBVol(&m_guidDB);
        ZeroMemory(&m_guidDB, sizeof(m_guidDB));

        return hr;
    }

    m_Initialized = true;
    return S_OK;
}

HRESULT
CVoipDB::Open(
    SORTORDERSPECEX*    pSort
    )
{
    //try to open the existing database
    m_Database = CeOpenDatabaseEx2(
        &m_guidDB, 
        &m_oidDB, 
        m_pName, 
        pSort, 
        0, 
        NULL
        );

    if (m_Database == INVALID_HANDLE_VALUE)
    {
        //failed to open - is it because the database doesn't exist?
        if (GetLastError() != ERROR_FILE_NOT_FOUND)
        {
            ASSERT(FALSE);
            return HRESULT_FROM_WIN32(GetLastError());
        }

        //database doesn't exist - create it first
        CEDBASEINFOEX Info = {0};
        Info.wVersion      = 1;
        Info.dwFlags       = CEDB_VALIDCREATE;
        Info.dwDbaseType   = OBJTYPE_DATABASE;
        Info.wNumSortOrder = 1;
        
        StringCchCopy(
            Info.szDbaseName, 
            _countof(Info.szDbaseName),
            m_pName
            );

        memcpy(
            &Info.rgSortSpecs[0], 
            pSort,
            sizeof(SORTORDERSPECEX)
            );
        
        //create the DB and check return val
        m_oidDB = CeCreateDatabaseEx2(
            &m_guidDB, 
            &Info
            );
        if (! m_oidDB)
        {
            ASSERT(FALSE);
            return HRESULT_FROM_WIN32(GetLastError());
        }

        m_Database = CeOpenDatabaseEx2(
            &m_guidDB, 
            &m_oidDB, 
            m_pName, 
            pSort, 
            0, 
            NULL
            );
        if (m_Database == INVALID_HANDLE_VALUE)
        {
            ASSERT(FALSE);
            return HRESULT_FROM_WIN32(GetLastError());
        }
    }

    //read the existing properties from the database
    CEOIDINFO   OidInfo = {0};

    if (! CeOidGetInfoEx(&m_guidDB, m_oidDB, &OidInfo))
    {
        goto error;
    }

    if (OidInfo.wObjType != OBJTYPE_DATABASE || OidInfo.infDatabase.wNumRecords < 0)
    {
        ASSERT(FALSE);
        SetLastError(ERROR_DATABASE_FAILURE);

        goto error;
    }

    //record the current number of entries...
    m_CurrentNumEntries = OidInfo.infDatabase.wNumRecords;

    m_CurrentSeek = 0;
    
    return S_OK;

error:
    CloseHandle(m_Database);
    m_Database = INVALID_HANDLE_VALUE;

    return HRESULT_FROM_WIN32(GetLastError());
} 


/*-------------------
Function: AddNewRecord
    Params: [in] CEPROPVAL* (a record) - array of cepropvals
    Adds a new recod to the DB
    returns: a valid CEOID (of the records location in the DB) on success, 0 on failure
-------------------*/
HRESULT CVoipDB::AddNewRecord(
    CEPROPVAL *pcpv,
    CEOID*     pOid
    )
{   
    //Check Params
    if (pcpv == NULL || ! pOid)
    {
        ASSERT(FALSE);
        return E_POINTER;
    }

    //Initialize the out parameter
    *pOid = NULL;
    
    //Write the record to the DB
    *pOid = CeWriteRecordProps(
        m_Database, 
        0, 
        (WORD)(m_NumProps), 
        pcpv
        );

    if (*pOid)
    {
        m_CurrentNumEntries++;

        if (m_CurrentNumEntries > m_MaxNumEntries)
        {
            RemoveOldest();
        }
        return S_OK;
    }

    return HRESULT_FROM_WIN32(GetLastError()); 
} //AddNewRecord


/*-------------------
Function: FindRecord
    Params:  [in] CEPROPVAL (propid and value to search for)
    Finds a record in the DB by searching on a cepropval
    returns: CEOID of matching record on success, 0 on failure
-------------------*/
CEOID CVoipDB::FindRecord(
    CEPROPVAL* pVal
    )
{
    //Seek to the first value that matches this property
    DWORD dwIndex = 0;

    return CeSeekDatabase(
        m_Database, 
        CEDB_SEEK_VALUEFIRSTEQUAL, 
        (DWORD)pVal, 
        &dwIndex
        );    
} //FindRecord
    
/*-------------------
Function: DeleteRecord
    Params:  [in] CEOID the record to delete
    Deletes the record 
    returns: TRUE on success, FALSE on failure
-------------------*/
BOOL CVoipDB::DeleteRecord(CEOID ceoid)
{
    if (CeDeleteRecord(m_Database, ceoid))
    {
        m_CurrentNumEntries--;
        return TRUE;
    }

    return FALSE;
} //DeleteRecord


/*-------------------
Function: EditRecord
    Params:  [in]CEOID ceoid to rewrite, [in]CEPROPVAL* record, [in]int number of props
    ReWrites a record's properties to the DB using a CEOID as index   
    returns: TRUE on success, FALSE on failure
-------------------*/
BOOL CVoipDB::EditRecord(CEOID ceoid, CEPROPVAL *pcpvNew, int cProps)
{
    return (CeWriteRecordProps(m_Database, ceoid, cProps, pcpvNew) == ceoid);
} //Edit Record


/*-------------------
Function: ReadCurrentRecord
    Params:  [out]CEPROPVAL**, [out]int*, [out]ceoid*
    1. Fills in cepropval** with contents of current record
    2. Fills int* with size of cepropval** in ints
    returns: TRUE on success, FALSE on failure

    Note: ppcpvFill needs to be freed by LocalFree after this is called.
-------------------*/
BOOL  CVoipDB::ReadCurrentRecord(CEPROPVAL **ppcpvFill, int *pcSize, CEOID *pceoid)
{
    int cb = 0;
    WORD wCount = 0;

    //Check params
    if (ppcpvFill == NULL || pcSize == NULL || pceoid == NULL)
    {
        ASSERT(FALSE);
        return FALSE;
    }

    //Initialize filling array
    *ppcpvFill = NULL;

    //Read props from DB with all defaults, and allow the DB to reallocate memory, return ceoid
    *pceoid = CeReadRecordProps(
        m_Database, 
        CEDB_ALLOWREALLOC, 
        &wCount, 
        NULL, 
        (BYTE **)ppcpvFill, 
        (ULONG*)&cb
        );
    *pcSize = wCount;

    return (*pceoid != 0);
} //ReadRecord


/*-------------------
Function: SeekTo Next
    Params:  [in] int cElts
    Seeks to the next cElt'th element
    returns: TRUE on success, FALSE on failure
-------------------*/
BOOL CVoipDB::SeekToNext(
    int cElts
    )
{
    CEOID ceoid;
    DWORD dwIndex = 0;

    //Check param
    if (cElts < 0)
    {
        return FALSE;
    }
    
    //If you seek 0 elements forward, nothing can go wrong.
    if (cElts == 0)
    {
        return TRUE;
    }

    //If we are not at the begnining of the db, seek from current
    if (m_CurrentSeek != 0)
    {
        ceoid = CeSeekDatabase(m_Database, CEDB_SEEK_CURRENT, cElts, &dwIndex);
    }
    else
    {
        //else seek from beginning-1 (for 0th element)
        ceoid = CeSeekDatabase(m_Database, CEDB_SEEK_BEGINNING, cElts-1, &dwIndex);
    }

    if (ceoid != 0)
    {
        m_CurrentSeek += cElts;
        return TRUE;
    }

    return FALSE;
}

//Resets the seek member variable, so that an enumerator will seek from 
//the beginning of the DB
BOOL    CVoipDB::ResetSeek()
{
    m_CurrentSeek = 0;
    return TRUE;
}

int     CVoipDB::GetCapacity()
{
    if (!m_Initialized)
        return -1;

    return m_MaxNumEntries;
}

BOOL CVoipDB::RemoveOldest()
{
    DWORD dwIndex = 0;
    CEOID ceoid   = 0;

    //If we are allowing infinite number of records, we don't need to ever
    //remove the oldest
    if (m_MaxNumEntries == INFINITE)
    {
        return TRUE;
    }
    
    //Seek to the end of the DB as the records are in descending order by timestamp
    ceoid = CeSeekDatabase(m_Database, CEDB_SEEK_END, 0, &dwIndex);
    if (! ceoid)
    {
        return FALSE;
    }

    //Reset seek
    m_CurrentSeek = 0;

    //Delete oldest - also updates version number
    DeleteRecord(ceoid);

    return TRUE;
}


/*-------------------
Function: Resize
    Params:  [in] int newMax
    1. If there are more entries in the DB than newMax
       remove the records over the threshold value. 
    returns: TRUE on success, FALSE on failure
-------------------*/
BOOL CVoipDB::Resize(int dwMaxNew)
{
    //if we are allowing infinite records, no need to resize
    if (dwMaxNew == INFINITE)
    {
        return TRUE;
    }
    //continually remove the oldest record until we have the desired number of records
    if (m_CurrentNumEntries > dwMaxNew)
    {
        while (m_CurrentNumEntries > dwMaxNew)
        {
            //Changes the version number for us.
            if (!RemoveOldest())
                return FALSE;

            m_MaxNumEntries = m_CurrentNumEntries;
        }
    }

    m_MaxNumEntries = dwMaxNew;
    return TRUE;
}//Resize

⌨️ 快捷键说明

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