|
|
/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/ /**********************************************************************/
/*
hArray.cpp Index manager for wins db
FILE HISTORY: Oct 13 1997 EricDav Created
*/
#include "stdafx.h"
#include "wins.h"
#include "memmngr.h"
#include "harray.h"
#include "mbstring.h"
#include "vrfysrv.h"
// the lstrcmpA fucntion converts the dbcs string to Unicode using the ACP
// and then does a string compare. So, we need to do the OEMCP conversion
// and then call the string compare ourselves.
int lstrcmpOEM( LPCSTR lpString1, LPCSTR lpString2 ) { CString str1, str2;
MBCSToWide((LPSTR) lpString1, str1, WINS_NAME_CODE_PAGE); MBCSToWide((LPSTR) lpString2, str2, WINS_NAME_CODE_PAGE);
return lstrcmp(str1, str2); }
/*!--------------------------------------------------------------------------
Class CHRowIndex ---------------------------------------------------------------------------*/ CHRowIndex::CHRowIndex(INDEX_TYPE IndexType) : m_dbType(IndexType), m_bAscending(TRUE) { }
CHRowIndex::~CHRowIndex() { }
/*!--------------------------------------------------------------------------
CHRowIndex::GetType - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CHRowIndex::GetType(INDEX_TYPE * pIndexType) { if (pIndexType) *pIndexType = m_dbType;
return hrOK; }
/*!--------------------------------------------------------------------------
CHRowIndex::SetArray - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CHRowIndex::SetArray(HRowArray & hrowArray) { m_hrowArray.Copy(hrowArray);
return hrOK; }
/*!--------------------------------------------------------------------------
CHRowIndex::GetHRow - Author: EricDav ---------------------------------------------------------------------------*/ HROW CHRowIndex::GetHRow(int nIndex) { Assert(nIndex >= 0); Assert(nIndex <= m_hrowArray.GetSize());
if (nIndex < 0 || nIndex >= m_hrowArray.GetSize()) { return NULL; }
return m_hrowArray.GetAt(nIndex); }
/*!--------------------------------------------------------------------------
CHRowIndex::GetIndex - Author: EricDav ---------------------------------------------------------------------------*/ int CHRowIndex::GetIndex(HROW hrow) { Assert(hrow != 0);
LPHROW phrow = (LPHROW) BSearch((const void *)&hrow, (const void *)m_hrowArray.GetData(), (size_t) m_hrowArray.GetSize(), (size_t) sizeof(HROW));
int nIndex = (int) (phrow - (LPHROW) m_hrowArray.GetData()); Assert(nIndex >= 0); Assert(nIndex <= m_hrowArray.GetSize());
int nComp, nIndexTemp; nComp = BCompare(&hrow, phrow); if (nComp == 0) { // found the right one, check the previous one to return the first
// record in a list of duplicates
nIndexTemp = nIndex;
while (nIndexTemp && nComp == 0) { *phrow = (HROW) m_hrowArray.GetAt(--nIndexTemp); nComp = BCompare(&hrow, phrow); }
if (nIndexTemp == nIndex) return nIndex; // nIndex should be zero here as well
else if (nComp == 0) return nIndexTemp; // nIndexTemp should be 0 in this case
else return nIndexTemp++; }
return -1; }
/*!--------------------------------------------------------------------------
CHRowIndex::Add - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CHRowIndex::Add(HROW hrow, BOOL bEnd) { // if we are loading the array then just stick this on the end
if (bEnd) { m_hrowArray.Add(hrow); } else { if (m_hrowArray.GetSize() == 0) { m_hrowArray.Add(hrow); } else { LPHROW phrow = (LPHROW) BSearch((const void *)&hrow, (const void *)m_hrowArray.GetData(), (size_t) m_hrowArray.GetSize(), (size_t) sizeof(HROW)); int nIndex = (int) (phrow - (LPHROW) m_hrowArray.GetData()); Assert(nIndex >= 0); Assert(nIndex <= m_hrowArray.GetSize()); int nComp;
if (m_bAscending) nComp = BCompare(&hrow, phrow); else nComp = BCompareD(&hrow, phrow);
if (nComp < 0) { // Insert before phrow
m_hrowArray.InsertAt(nIndex, hrow); } else { // insert after phrow
m_hrowArray.InsertAt(nIndex + 1, hrow); } } }
return hrOK; }
/*!--------------------------------------------------------------------------
CHRowIndex::Remove - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CHRowIndex::Remove(HROW hrow) { // do a bsearch for the record and then remove
LPHROW phrow = (LPHROW) BSearch((const void*)&hrow, (const void*)m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), (size_t)sizeof(HROW)); // make sure the record is in the database, may not be if we aren't
// filtering
if (phrow) { int nComp = BCompare(&hrow, phrow); Assert(nComp == 0); if (nComp != 0) return E_FAIL;
// calculate the index
int nIndex = (int) (phrow - (LPHROW) m_hrowArray.GetData()); Assert(nIndex >= 0); Assert(nIndex <= m_hrowArray.GetSize());
m_hrowArray.RemoveAt((int) nIndex); }
return hrOK; }
/*!--------------------------------------------------------------------------
CHRowIndex::BSearch Modified bsearch which returns the closest or equal element in an array Author: EricDav ---------------------------------------------------------------------------*/ void * CHRowIndex::BSearch (const void *key, const void *base, size_t num, size_t width) { char *lo = (char *)base; char *hi = (char *)base + (num - 1) * width; char *mid = NULL; unsigned int half = 0; int result = 0;
while (lo <= hi) if (half = num / 2) { mid = lo + (num & 1 ? half : (half - 1)) * width;
if (m_bAscending) { if (!(result = BCompare(key,mid))) return(mid);
else if (result < 0) { hi = mid - width; num = num & 1 ? half : half-1; } else { lo = mid + width; num = half; } } else { if (!(result = BCompareD(key,mid))) return(mid); else if (result < 0) { hi = mid - width; num = num & 1 ? half : half-1; } else { lo = mid + width; num = half; }
} } else if (num) return(lo); else break;
return(mid); }
/*!--------------------------------------------------------------------------
Class CIndexMgr ---------------------------------------------------------------------------*/
CIndexMgr::CIndexMgr() { m_posCurrentIndex = NULL; m_posFilteredIndex = NULL; m_posLastIndex = NULL; m_posUpdatedIndex = NULL; m_bFiltered = FALSE; }
CIndexMgr::~CIndexMgr() { Reset(); } /*!--------------------------------------------------------------------------
CIndexMgr::Initialize - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexMgr::Initialize() { HRESULT hr = hrOK;
CSingleLock cl(&m_cs); cl.Lock();
COM_PROTECT_TRY { // cleanup
Reset();
// Create one index, the named index
CIndexName * pName = new CIndexName(); m_posCurrentIndex = m_listIndicies.AddTail((CHRowIndex *) pName); m_posUpdatedIndex = m_posCurrentIndex;
// this will be the current index, we need the Named Index also
// for the total count
CFilteredIndexName *pFilteredName = new CFilteredIndexName() ; m_posFilteredIndex = m_listFilteredIndices.AddTail((CHRowIndex *) pFilteredName);
} COM_PROTECT_CATCH
return hr; }
/*!--------------------------------------------------------------------------
CIndexMgr::Reset - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexMgr::Reset() { CSingleLock cl(&m_cs); cl.Lock();
while (m_listIndicies.GetCount() > 0) { delete m_listIndicies.RemoveHead(); } while(m_listFilteredIndices.GetCount() > 0 ) { delete m_listFilteredIndices.RemoveHead(); } return hrOK; }
/*!--------------------------------------------------------------------------
CIndexMgr::GetTotalCount The index sorted by name contains the total database and should always be available. Use this for the total count. Author: EricDav ---------------------------------------------------------------------------*/ UINT CIndexMgr::GetTotalCount() { CSingleLock cl(&m_cs); cl.Lock();
CHRowIndex * pIndex = GetNameIndex(); if (pIndex == NULL) return 0;
return (UINT)pIndex->GetArray().GetSize(); }
/*!--------------------------------------------------------------------------
CIndexMgr::GetCurrentCount The current count may differ depending upon if the current Index is a filtered index. Author: EricDav ---------------------------------------------------------------------------*/ UINT CIndexMgr::GetCurrentCount() { CSingleLock cl(&m_cs); cl.Lock();
CHRowIndex * pIndex ;
if (!m_bFiltered) pIndex = m_listIndicies.GetAt(m_posUpdatedIndex); else pIndex = m_listFilteredIndices.GetAt(m_posUpdatedIndex);
if (pIndex == NULL) return 0;
return (UINT)pIndex->GetArray().GetSize(); }
/*!--------------------------------------------------------------------------
CIndexMgr::AddHRow - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexMgr::AddHRow(HROW hrow, BOOL bEnd, BOOL bFilterChecked) { CSingleLock cl(&m_cs); cl.Lock();
INDEX_TYPE indexType;
HRESULT hr = hrOK; POSITION pos = m_listIndicies.GetHeadPosition(); COM_PROTECT_TRY { while (pos) { CHRowIndex * pIndex = m_listIndicies.GetNext(pos);
// check the INDEX type of the HRowIndex,
// if filtered, need to add, depending on
// whether the filter holds good
pIndex->GetType(&indexType); if (indexType != INDEX_TYPE_FILTER) pIndex->Add(hrow, bEnd); }
pos = m_listFilteredIndices.GetHeadPosition();
while(pos) { CHRowIndex * pIndex = m_listFilteredIndices.GetNext(pos);
pIndex->GetType(&indexType); if (indexType != INDEX_TYPE_FILTER) break;
BOOL bCheck = bFilterChecked ? TRUE : ((CFilteredIndexName*)pIndex)->CheckForFilter(&hrow); if (bCheck) pIndex->Add(hrow, bEnd); }
} COM_PROTECT_CATCH
return hr; }
/*!--------------------------------------------------------------------------
CIndexMgr::AcceptHRow - Author: FlorinT ---------------------------------------------------------------------------*/ BOOL CIndexMgr::AcceptWinsRecord(WinsRecord *pWinsRecord) { CSingleLock cl(&m_cs); cl.Lock();
POSITION pos = m_listFilteredIndices.GetHeadPosition();
while(pos) { CHRowIndex *pIndex = m_listFilteredIndices.GetNext(pos); INDEX_TYPE indexType;
pIndex->GetType(&indexType); if (indexType != INDEX_TYPE_FILTER) break;
if (((CFilteredIndexName*)pIndex)->CheckWinsRecordForFilter(pWinsRecord)) return TRUE; }
return FALSE; }
/*!--------------------------------------------------------------------------
CIndexMgr::RemoveHRow - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexMgr::RemoveHRow(HROW hrow) { CSingleLock cl(&m_cs); cl.Lock();
HRESULT hr = hrOK; POSITION pos = m_listIndicies.GetHeadPosition(); COM_PROTECT_TRY { // remove from the normal list
while (pos) { CHRowIndex * pIndex = m_listIndicies.GetNext(pos); pIndex->Remove(hrow); }
// now remove from the filtered list
pos = m_listFilteredIndices.GetHeadPosition(); while (pos) { CHRowIndex * pIndex = m_listFilteredIndices.GetNext(pos); pIndex->Remove(hrow); }
} COM_PROTECT_CATCH
return hr; }
/*!--------------------------------------------------------------------------
CIndexMgr::Sort - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexMgr::Sort(WINSDB_SORT_TYPE SortType, DWORD dwSortOptions) { CSingleLock cl(&m_cs); cl.Lock();
HRESULT hr = hrOK; CHRowIndex * pNameIndex; CHRowIndex * pNewIndex; POSITION pos; INDEX_TYPE indexType; BOOL bAscending = (dwSortOptions & WINSDB_SORT_ASCENDING) ? TRUE : FALSE;
if (!m_bFiltered) { // check to see if we have an index for this.
pos = m_listIndicies.GetHeadPosition(); while (pos) { POSITION posTemp = pos; CHRowIndex * pIndex = m_listIndicies.GetNext(pos); pIndex->GetType(&indexType);
if (indexType == SortType) { if (pIndex->IsAscending() != bAscending) { pIndex->SetAscending(bAscending); pIndex->Sort(); }
m_posCurrentIndex = posTemp; m_posUpdatedIndex = m_posCurrentIndex; // m_posLastIndex = m_posCurrentIndex;
return hrOK; } } } // to save memory, remove all old indicies, except the name index
CleanupIndicies();
COM_PROTECT_TRY { // if not, create one
switch (SortType) { case INDEX_TYPE_NAME: pNewIndex = new CIndexName(); break;
case INDEX_TYPE_IP: pNewIndex = new CIndexIpAddr(); break;
case INDEX_TYPE_VERSION: pNewIndex = new CIndexVersion(); break;
case INDEX_TYPE_TYPE: pNewIndex = new CIndexType(); break;
case INDEX_TYPE_EXPIRATION: pNewIndex = new CIndexExpiration(); break;
case INDEX_TYPE_STATE: pNewIndex = new CIndexState(); break;
case INDEX_TYPE_STATIC: pNewIndex = new CIndexStatic(); break;
case INDEX_TYPE_OWNER: pNewIndex = new CIndexOwner(); break;
case INDEX_TYPE_FILTER: //pNewIndex = new CIndexFilter();
break;
default: Panic1("Invalid sort type passed to IndexMgr::Sort %d\n", SortType); break; } } COM_PROTECT_CATCH
if (FHrSucceeded(hr)) { Assert(pNewIndex);
if (!m_bFiltered) pNameIndex = GetNameIndex(); else pNameIndex = GetFilteredNameIndex();
Assert(pNameIndex);
COM_PROTECT_TRY { // copy the array from the named index
pNewIndex->SetArray(pNameIndex->GetArray()); } COM_PROTECT_CATCH }
if (FHrSucceeded(hr)) { pNewIndex->SetAscending(bAscending); pNewIndex->Sort();
if (!m_bFiltered) { m_posCurrentIndex = m_listIndicies.AddTail(pNewIndex); m_posUpdatedIndex = m_posCurrentIndex; } else { POSITION posTemp = m_posFilteredIndex = m_listFilteredIndices.AddTail(pNewIndex); m_posUpdatedIndex = posTemp;// m_posFilteredIndex;
}
Assert(m_posCurrentIndex); }
if (!FHrSucceeded(hr)) { if (pNewIndex != NULL) delete pNewIndex; }
return hr; }
/*!--------------------------------------------------------------------------
CIndexMgr::GetNameIndex - Author: EricDav ---------------------------------------------------------------------------*/ CHRowIndex * CIndexMgr::GetNameIndex() { CSingleLock cl(&m_cs); cl.Lock();
INDEX_TYPE indexType;
POSITION pos = m_listIndicies.GetHeadPosition(); while (pos) { CHRowIndex * pIndex = m_listIndicies.GetNext(pos); pIndex->GetType(&indexType); if (indexType == INDEX_TYPE_NAME) return pIndex; } return NULL; }
/*!--------------------------------------------------------------------------
CIndexMgr::GetFilteredNameIndex - Author: EricDav ---------------------------------------------------------------------------*/ CHRowIndex * CIndexMgr::GetFilteredNameIndex() { CSingleLock cl(&m_cs); cl.Lock();
INDEX_TYPE indexType;
POSITION pos = m_listFilteredIndices.GetHeadPosition(); while (pos) { CHRowIndex * pIndex = m_listFilteredIndices.GetNext(pos); pIndex->GetType(&indexType); if (indexType == INDEX_TYPE_FILTER) return pIndex; } return NULL; }
/*!--------------------------------------------------------------------------
CIndexMgr::CleanupIndicies Removes all indicies except the name index, and a filtered view Author: EricDav ---------------------------------------------------------------------------*/ void CIndexMgr::CleanupIndicies() { CSingleLock cl(&m_cs); cl.Lock();
INDEX_TYPE indexType;
// clean up the non-filtered indicies
POSITION pos = m_listIndicies.GetHeadPosition(); while (pos) { POSITION posLast = pos; CHRowIndex * pIndex = m_listIndicies.GetNext(pos); pIndex->GetType(&indexType); if (indexType == INDEX_TYPE_NAME || indexType == INDEX_TYPE_FILTER) continue;
m_listIndicies.RemoveAt(posLast); delete pIndex; }
// now clean up the filtered indicies
pos = m_listFilteredIndices.GetHeadPosition();
// delete all except the first one which is the filetered
// name index
//CHRowIndex * pIndex = m_listFilteredIndices.GetNext(pos);
while (pos) { POSITION posLast = pos; CHRowIndex * pIndex = m_listFilteredIndices.GetNext(pos); pIndex->GetType(&indexType); if (indexType == INDEX_TYPE_NAME || indexType == INDEX_TYPE_FILTER) continue;
m_listFilteredIndices.RemoveAt(posLast); delete pIndex; } }
/*!--------------------------------------------------------------------------
CIndexMgr::GetHRow Returns an hrow based on an index into the current sorted list Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexMgr::GetHRow(int nIndex, LPHROW phrow) { CSingleLock cl(&m_cs); cl.Lock();
Assert(m_posCurrentIndex != NULL);
//CHRowIndex * pIndex = m_listIndicies.GetAt(m_posCurrentIndex);
CHRowIndex * pIndex; if (!m_bFiltered) pIndex = m_listIndicies.GetAt(m_posUpdatedIndex); else pIndex = m_listFilteredIndices.GetAt(m_posFilteredIndex);
Assert(pIndex);
if (phrow) *phrow = pIndex->GetHRow(nIndex);
return hrOK; }
/*!--------------------------------------------------------------------------
CIndexMgr::GetIndex Returns the index of an hrow from the current sorted list Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexMgr::GetIndex(HROW hrow, int * pIndex) { CSingleLock cl(&m_cs); cl.Lock();
Assert(m_posCurrentIndex != NULL);
//CHRowIndex * pCurrentIndex = m_listIndicies.GetAt(m_posCurrentIndex);
CHRowIndex * pCurrentIndex;
if (!m_bFiltered) pCurrentIndex = m_listIndicies.GetAt(m_posUpdatedIndex); else pCurrentIndex = m_listFilteredIndices.GetAt(m_posFilteredIndex);
Assert(pCurrentIndex);
if (pIndex) *pIndex = pCurrentIndex->GetIndex(hrow);
return hrOK; }
HRESULT CIndexMgr::Filter(WINSDB_FILTER_TYPE FilterType, DWORD dwParam1, DWORD dwParam2) { CSingleLock cl(&m_cs); cl.Lock();
HRESULT hr = hrOK; CHRowIndex* pNameIndex; CHRowIndex* pNewIndex; POSITION pos; INDEX_TYPE indexType; UINT uCount; UINT i; BOOL bCheck = FALSE; HROW hrow; HRowArray hrowArray;
pNewIndex = GetFilteredNameIndex(); Assert(pNewIndex);
// clear the filtered name index first.
pNewIndex->SetArray(hrowArray);
pNameIndex = GetNameIndex(); Assert(pNameIndex);
// do the filtering here.
uCount = GetTotalCount();
for(i = 0; i< uCount; i++) { hrow = pNameIndex->GetHRow(i);
if (hrow) bCheck = ((CFilteredIndexName *)pNewIndex)->CheckForFilter(&hrow); if (bCheck) pNewIndex->Add(hrow, TRUE); }
// check to see if the filtered view has been sorted on something else besides
// the name. If so, switch back the index to the named index because
// otherwise we will need to resort which can be time consuming...
if (m_listFilteredIndices.GetAt(m_posFilteredIndex) != pNewIndex) { m_posFilteredIndex = m_listFilteredIndices.Find(pNewIndex); }
// get the current position of the filtered index in the list of indices
m_posUpdatedIndex = m_posFilteredIndex;
Assert(m_posUpdatedIndex);
m_bFiltered = TRUE; return hr; }
HRESULT CIndexMgr::AddFilter(WINSDB_FILTER_TYPE FilterType, DWORD dwParam1, DWORD dwParam2, LPCOLESTR strParam3) { CSingleLock cl(&m_cs); cl.Lock();
HRESULT hr = hrOK;
CFilteredIndexName *pFilterName = (CFilteredIndexName *)GetFilteredNameIndex(); pFilterName->AddFilter(FilterType, dwParam1, dwParam2, strParam3); m_bFiltered = TRUE; return hr; }
HRESULT CIndexMgr::ClearFilter(WINSDB_FILTER_TYPE FilterType) { CSingleLock cl(&m_cs); cl.Lock();
HRESULT hr = hrOK;
CFilteredIndexName *pFilterName = (CFilteredIndexName *)GetFilteredNameIndex(); pFilterName->ClearFilter(FilterType); m_bFiltered = FALSE; // m_posCurrentIndex = m_posLastIndex;
return hr; }
HRESULT CIndexMgr::SetActiveView(WINSDB_VIEW_TYPE ViewType) { CSingleLock cl(&m_cs); cl.Lock();
HRESULT hr = hrOK;
switch(ViewType) { case WINSDB_VIEW_FILTERED_DATABASE: m_bFiltered = TRUE; //m_posCurrentIndex = m_posFilteredIndex;
m_posUpdatedIndex = m_posFilteredIndex; break; case WINSDB_VIEW_ENTIRE_DATABASE: m_bFiltered = FALSE; //m_posCurrentIndex = m_posLastIndex;
m_posUpdatedIndex = m_posCurrentIndex; break; default: break; }
return hr; }
/*!--------------------------------------------------------------------------
Class CIndexName ---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
CIndexName::BCompare - Author: EricDav ---------------------------------------------------------------------------*/ int CIndexName::BCompare(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2;
LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2;
LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0]; return lstrcmpOEM(puChar1, puChar2); }
int CIndexName::BCompareD(const void *elem1, const void *elem2) { return -BCompare(elem1, elem2); }
/*!--------------------------------------------------------------------------
CIndexName::Sort - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexName::Sort() { if (m_bAscending) qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareA); else qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareD);
return hrOK; }
/*!--------------------------------------------------------------------------
CIndexName::QCompare - Author: EricDav ---------------------------------------------------------------------------*/ int __cdecl CIndexName::QCompareA(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0]; return lstrcmpOEM(puChar1, puChar2); }
int __cdecl CIndexName::QCompareD(const void * elem1, const void * elem2) { return -QCompareA(elem1, elem2); }
/*!--------------------------------------------------------------------------
Class CIndexType ---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
CIndexType::BCompare - Author: EricDav ---------------------------------------------------------------------------*/ int CIndexType::BCompare(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0];
if ((unsigned char) puChar1[15] > (unsigned char) puChar2[15]) return 1; else if ((unsigned char) puChar1[15] < (unsigned char) puChar2[15]) return -1; else return lstrcmpOEM(puChar1, puChar2); }
int CIndexType::BCompareD(const void *elem1, const void *elem2) { return -BCompare(elem1, elem2); }
/*!--------------------------------------------------------------------------
CIndexType::Sort - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexType::Sort() { if (m_bAscending) qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareA); else qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareD);
return hrOK; }
/*!--------------------------------------------------------------------------
CIndexType::QCompare - Author: EricDav ---------------------------------------------------------------------------*/ int __cdecl CIndexType::QCompareA(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0];
DWORD dwAddr1, dwAddr2; if (pRec1->szRecordName[18] & WINSDB_REC_MULT_ADDRS) { // if this record has multiple addresses, we want the 2nd
// address, because the 1st address is always the WINS server
// first dword is the count.
LPDWORD pdwIpAddrs = (LPDWORD) pRec1->dwIpAdd; dwAddr1 = pdwIpAddrs[2]; } else { dwAddr1 = (DWORD) pRec1->dwIpAdd; } if (pRec2->szRecordName[18] & WINSDB_REC_MULT_ADDRS) { // if this record has multiple addresses, we want the 2nd
// address, because the 1st address is always the WINS server
// first dword is the count.
LPDWORD pdwIpAddrs = (LPDWORD) pRec2->dwIpAdd; dwAddr2 = pdwIpAddrs[2]; } else { dwAddr2 = (DWORD) pRec2->dwIpAdd; }
// check the types first. If they are the same, sort by IP address.
// if for some reason the IP addresses are the same then sort by name.
if ((unsigned char) puChar1[15] > (unsigned char) puChar2[15]) return 1; else if ((unsigned char) puChar1[15] < (unsigned char) puChar2[15]) return -1; else if (dwAddr1 > dwAddr2) return 1; else if (dwAddr1 < dwAddr2) return -1; else return lstrcmpOEM(puChar1, puChar2); }
int __cdecl CIndexType::QCompareD(const void * elem1, const void * elem2) { return -QCompareA(elem1, elem2); }
/*!--------------------------------------------------------------------------
Class CIndexIpAddr ---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
CIndexIpAddr::BCompare - Author: EricDav ---------------------------------------------------------------------------*/ int CIndexIpAddr::BCompare(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; DWORD dwAddr1, dwAddr2; if (pRec1->szRecordName[18] & WINSDB_REC_MULT_ADDRS) { // if this record has multiple addresses, we want the 2nd
// address, because the 1st address is always the WINS server
// first dword is the count.
LPDWORD pdwIpAddrs = (LPDWORD) pRec1->dwIpAdd; dwAddr1 = pdwIpAddrs[2]; } else { dwAddr1 = (DWORD) pRec1->dwIpAdd; } if (pRec2->szRecordName[18] & WINSDB_REC_MULT_ADDRS) { // if this record has multiple addresses, we want the 2nd
// address, because the 1st address is always the WINS server
// first dword is the count.
LPDWORD pdwIpAddrs = (LPDWORD) pRec2->dwIpAdd; dwAddr2 = pdwIpAddrs[2]; } else { dwAddr2 = (DWORD) pRec2->dwIpAdd; }
if (dwAddr1 > dwAddr2) return 1; else if (dwAddr1 < dwAddr2) return -1; else { // if the addresses are the same, compare types, then names
LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0];
if ((unsigned char) puChar1[15] > (unsigned char) puChar2[15]) return 1; else if ((unsigned char) puChar1[15] < (unsigned char) puChar2[15]) return -1; else return lstrcmpOEM(puChar1, puChar2); } }
int CIndexIpAddr::BCompareD(const void *elem1, const void *elem2) { return -BCompare(elem1, elem2); }
/*!--------------------------------------------------------------------------
CIndexIpAddr::Sort - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexIpAddr::Sort() { if (m_bAscending) qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareA); else qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareD);
return hrOK; }
/*!--------------------------------------------------------------------------
CIndexIpAddr::QCompare - Author: EricDav ---------------------------------------------------------------------------*/ int __cdecl CIndexIpAddr::QCompareA(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; DWORD dwAddr1, dwAddr2; if (pRec1->szRecordName[18] & WINSDB_REC_MULT_ADDRS) { // if this record has multiple addresses, we want the 2nd
// address, because the 1st address is always the WINS server
// first dword is the count.
LPDWORD pdwIpAddrs = (LPDWORD) pRec1->dwIpAdd; dwAddr1 = pdwIpAddrs[2]; } else { dwAddr1 = (DWORD) pRec1->dwIpAdd; } if (pRec2->szRecordName[18] & WINSDB_REC_MULT_ADDRS) { // if this record has multiple addresses, we want the 2nd
// address, because the 1st address is always the WINS server
// first dword is the count.
LPDWORD pdwIpAddrs = (LPDWORD) pRec2->dwIpAdd; dwAddr2 = pdwIpAddrs[2]; } else { dwAddr2 = (DWORD) pRec2->dwIpAdd; }
if (dwAddr1 > dwAddr2) return 1; else if (dwAddr1 < dwAddr2) return -1; else { // if the addresses are the same, compare types, then names
LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0];
if ((unsigned char) puChar1[15] > (unsigned char) puChar2[15]) return 1; else if ((unsigned char) puChar1[15] < (unsigned char) puChar2[15]) return -1; else return lstrcmpOEM(puChar1, puChar2); } }
int __cdecl CIndexIpAddr::QCompareD(const void * elem1, const void * elem2) { return -QCompareA(elem1, elem2); }
/*!--------------------------------------------------------------------------
Class CIndexVersion ---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
CIndexVersion::BCompare - Author: EricDav ---------------------------------------------------------------------------*/ int CIndexVersion::BCompare(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; if (pRec1->liVersion.QuadPart > pRec2->liVersion.QuadPart) return 1; else if (pRec1->liVersion.QuadPart < pRec2->liVersion.QuadPart) return -1; else return 0; }
int CIndexVersion::BCompareD(const void *elem1, const void *elem2) { return -BCompare(elem1, elem2); }
/*!--------------------------------------------------------------------------
CIndexVersion::Sort - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexVersion::Sort() { if (m_bAscending) qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareA); else qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareD);
return hrOK; }
/*!--------------------------------------------------------------------------
CIndexVersion::QCompare - Author: EricDav ---------------------------------------------------------------------------*/ int __cdecl CIndexVersion::QCompareA(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; if (pRec1->liVersion.QuadPart > pRec2->liVersion.QuadPart) return 1; else if (pRec1->liVersion.QuadPart < pRec2->liVersion.QuadPart) return -1; else return 0; }
int __cdecl CIndexVersion::QCompareD(const void * elem1, const void * elem2) { return -QCompareA(elem1, elem2); }
/*!--------------------------------------------------------------------------
Class CIndexExpiration ---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
CIndexExpiration::BCompare - Author: EricDav ---------------------------------------------------------------------------*/ int CIndexExpiration::BCompare(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; if (pRec1->dwExpiration > pRec2->dwExpiration) return 1; else if (pRec1->dwExpiration < pRec2->dwExpiration) return -1; else return 0; }
int CIndexExpiration::BCompareD(const void *elem1, const void *elem2) { return -BCompare(elem1, elem2); }
/*!--------------------------------------------------------------------------
CIndexExpiration::Sort - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexExpiration::Sort() { if (m_bAscending) qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareA); else qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareD);
return hrOK; }
/*!--------------------------------------------------------------------------
CIndexExpiration::QCompare - Author: EricDav ---------------------------------------------------------------------------*/ int __cdecl CIndexExpiration::QCompareA(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; if (pRec1->dwExpiration > pRec2->dwExpiration) return 1; else if (pRec1->dwExpiration < pRec2->dwExpiration) return -1; else return 0; }
int __cdecl CIndexExpiration::QCompareD(const void * elem1, const void * elem2) { return -QCompareA(elem1, elem2); }
/*!--------------------------------------------------------------------------
Class CIndexState ---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
CIndexState::BCompare - Author: EricDav ---------------------------------------------------------------------------*/ int CIndexState::BCompare(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; int nPri1 = 0, nPri2 = 0; // calculate relative priorities
if (pRec1->szRecordName[18] & WINSDB_REC_ACTIVE) nPri1 = 0; else if (pRec1->szRecordName[18] & WINSDB_REC_RELEASED) nPri1 = 1; else if (pRec1->szRecordName[18] & WINSDB_REC_TOMBSTONE) nPri1 = 2; else if (pRec1->szRecordName[18] & WINSDB_REC_DELETED) nPri1 = 3;
// now for record 2
if (pRec2->szRecordName[18] & WINSDB_REC_ACTIVE) nPri2 = 0; else if (pRec2->szRecordName[18] & WINSDB_REC_RELEASED) nPri2 = 1; else if (pRec2->szRecordName[18] & WINSDB_REC_TOMBSTONE) nPri2 = 2; else if (pRec2->szRecordName[18] & WINSDB_REC_DELETED) nPri2 = 3; if (nPri1 > nPri2) return 1; else if (nPri1 < nPri2) return -1; else { LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0]; return lstrcmpOEM(puChar1, puChar2); } }
int CIndexState::BCompareD(const void *elem1, const void *elem2) { return -BCompare(elem1, elem2); }
/*!--------------------------------------------------------------------------
CIndexState::Sort - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexState::Sort() { if (m_bAscending) qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareA); else qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareD);
return hrOK; }
/*!--------------------------------------------------------------------------
CIndexState::QCompare - Author: EricDav ---------------------------------------------------------------------------*/ int __cdecl CIndexState::QCompareA(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; int nPri1 = 0, nPri2 = 0; // calculate relative priorities
if (pRec1->szRecordName[18] & WINSDB_REC_ACTIVE) nPri1 = 0; else if (pRec1->szRecordName[18] & WINSDB_REC_RELEASED) nPri1 = 1; else if (pRec1->szRecordName[18] & WINSDB_REC_TOMBSTONE) nPri1 = 2; else if (pRec1->szRecordName[18] & WINSDB_REC_DELETED) nPri1 = 3;
// now for record 2
if (pRec2->szRecordName[18] & WINSDB_REC_ACTIVE) nPri2 = 0; else if (pRec2->szRecordName[18] & WINSDB_REC_RELEASED) nPri2 = 1; else if (pRec2->szRecordName[18] & WINSDB_REC_TOMBSTONE) nPri2 = 2; else if (pRec2->szRecordName[18] & WINSDB_REC_DELETED) nPri2 = 3; if (nPri1 > nPri2) return 1; else if (nPri1 < nPri2) return -1; else { LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0]; return lstrcmpOEM(puChar1, puChar2); } }
int __cdecl CIndexState::QCompareD(const void * elem1, const void * elem2) { return -QCompareA(elem1, elem2); }
/*!--------------------------------------------------------------------------
Class CIndexStatic ---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
CIndexStatic::BCompare - Author: EricDav ---------------------------------------------------------------------------*/ int CIndexStatic::BCompare(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; BOOL bStatic1 = pRec1->szRecordName[18] & LOBYTE(LOWORD(WINSDB_REC_STATIC)); BOOL bStatic2 = pRec2->szRecordName[18] & LOBYTE(LOWORD(WINSDB_REC_STATIC));
if (bStatic1 && !bStatic2) return 1; else if (!bStatic1 && bStatic2) return -1; else { LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0]; return lstrcmpOEM(puChar1, puChar2); } }
int CIndexStatic::BCompareD(const void *elem1, const void *elem2) { return -BCompare(elem1, elem2); }
/*!--------------------------------------------------------------------------
CIndexStatic::Sort - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexStatic::Sort() { if (m_bAscending) qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareA); else qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareD);
return hrOK; }
/*!--------------------------------------------------------------------------
CIndexStatic::QCompare - Author: EricDav ---------------------------------------------------------------------------*/ int __cdecl CIndexStatic::QCompareA(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; BOOL bStatic1 = pRec1->szRecordName[18] & LOBYTE(LOWORD(WINSDB_REC_STATIC)); BOOL bStatic2 = pRec2->szRecordName[18] & LOBYTE(LOWORD(WINSDB_REC_STATIC));
if (bStatic1 && !bStatic2) return 1; else if (!bStatic1 && bStatic2) return -1; else { LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0]; return lstrcmpOEM(puChar1, puChar2); } }
int __cdecl CIndexStatic::QCompareD(const void * elem1, const void * elem2) { return -QCompareA(elem1, elem2); }
/*!--------------------------------------------------------------------------
Class CIndexOwner ---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
CIndexOwner::BCompare - Author: EricDav ---------------------------------------------------------------------------*/ int CIndexOwner::BCompare(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; if (pRec1->dwOwner > pRec2->dwOwner) { return 1; } else if (pRec1->dwOwner < pRec2->dwOwner) { return -1; } else { // if the addresses are the same, compare names
LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0]; return lstrcmpOEM(puChar1, puChar2); } }
int CIndexOwner::BCompareD(const void *elem1, const void *elem2) { return -BCompare(elem1, elem2); }
/*!--------------------------------------------------------------------------
CIndexStatic::Sort - Author: EricDav ---------------------------------------------------------------------------*/ HRESULT CIndexOwner::Sort() { if (m_bAscending) qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareA); else qsort(m_hrowArray.GetData(), (size_t)m_hrowArray.GetSize(), sizeof(HROW), QCompareD);
return hrOK; }
/*!--------------------------------------------------------------------------
CIndexStatic::QCompare - Author: EricDav ---------------------------------------------------------------------------*/ int __cdecl CIndexOwner::QCompareA(const void * elem1, const void * elem2) { LPHROW phrow1 = (LPHROW) elem1; LPHROW phrow2 = (LPHROW) elem2; LPWINSDBRECORD pRec1 = (LPWINSDBRECORD) *phrow1; LPWINSDBRECORD pRec2 = (LPWINSDBRECORD) *phrow2; if (pRec1->dwOwner > pRec2->dwOwner) { return 1; } else if (pRec1->dwOwner < pRec2->dwOwner) { return -1; } else { // if the addresses are the same, compare names
LPCSTR puChar1 = (IS_DBREC_LONGNAME(pRec1)) ? (LPCSTR) *((char **) pRec1->szRecordName) : (LPCSTR) &pRec1->szRecordName[0]; LPCSTR puChar2 = (IS_DBREC_LONGNAME(pRec2)) ? (LPCSTR) *((char **) pRec2->szRecordName) : (LPCSTR) &pRec2->szRecordName[0]; return lstrcmpOEM(puChar1, puChar2); } }
int __cdecl CIndexOwner::QCompareD(const void * elem1, const void * elem2) { return -QCompareA(elem1, elem2); }
HRESULT CFilteredIndexName::AddFilter(WINSDB_FILTER_TYPE FilterType, DWORD dwData1, DWORD dwData2, LPCOLESTR strData3) { HRESULT hr = hrOK; tIpReference ipRef;
switch (FilterType) { case WINSDB_FILTER_BY_TYPE: m_mapFilterTypes.SetAt(dwData1, (BOOL&) dwData2); break;
case WINSDB_FILTER_BY_OWNER: m_dwaFilteredOwners.Add(dwData1); break;
case WINSDB_FILTER_BY_IPADDR: ipRef.Address = dwData1; ipRef.Mask = dwData2; m_taFilteredIp.Add(ipRef); break;
case WINSDB_FILTER_BY_NAME: UINT nData3Len;
nData3Len = (_tcslen(strData3)+1)*sizeof(TCHAR); m_pchFilteredName = new char[nData3Len]; if (m_pchFilteredName != NULL) { #ifdef _UNICODE
if (WideCharToMultiByte(CP_OEMCP, 0, strData3, -1, m_pchFilteredName, nData3Len, NULL, NULL) == 0) { delete m_pchFilteredName; m_pchFilteredName = NULL; } #else
CharToOem(strData3, m_pchFilteredName); #endif
//m_pchFilteredName = _strupr(m_pchFilteredName);
m_bMatchCase = dwData1; } break;
default: Panic0("Invalid filter type passed to CFilteredIndexName::AddFilter"); break; }
return hr; }
BOOL CFilteredIndexName::CheckForFilter(LPHROW hrowCheck) { UINT nCountOwner = (UINT)m_dwaFilteredOwners.GetSize(); UINT nCountType = m_mapFilterTypes.GetHashTableSize(); UINT nCountIPAddrs = (UINT)m_taFilteredIp.GetSize(); BOOL bOwnerFilter = (nCountOwner == 0); BOOL bTypeFilter = (nCountType == 0); BOOL bIPAddrsFilter = (nCountIPAddrs == 0); BOOL bNameFilter = (m_pchFilteredName == NULL); LPWINSDBRECORD pRec = (LPWINSDBRECORD) *hrowCheck; UINT i, j; LPCSTR puChar;
for (i = 0; !bOwnerFilter && i < nCountOwner; i++) { if (pRec->dwOwner == m_dwaFilteredOwners.GetAt(i)) bOwnerFilter = TRUE; }
if (!bOwnerFilter) return FALSE;
puChar = (IS_DBREC_LONGNAME(pRec)) ? (LPCSTR) *((char **) pRec->szRecordName) : (LPCSTR) &pRec->szRecordName[0];
if (!bTypeFilter) { DWORD dwType = puChar[0xF];
if (!m_mapFilterTypes.Lookup(dwType, bTypeFilter)) { // no entry for this name type. Check the FFFF name type (other) to see if we should
// show it.
dwType = 0xFFFF; m_mapFilterTypes.Lookup(dwType, bTypeFilter); } } if (!bTypeFilter) return FALSE;
for (i = 0; !bIPAddrsFilter && i < nCountIPAddrs; i++) { if (pRec->szRecordName[18] & WINSDB_REC_MULT_ADDRS) { LPDWORD pdwIpAddrs = (LPDWORD) pRec->dwIpAdd;
for (j=0; !bIPAddrsFilter && j < pdwIpAddrs[0]; j+=2) { bIPAddrsFilter = SubnetMatching(m_taFilteredIp[i], pdwIpAddrs[j+2]); } } else { bIPAddrsFilter = SubnetMatching(m_taFilteredIp[i], (DWORD)pRec->dwIpAdd); } } if(!bIPAddrsFilter) return FALSE;
if (!bNameFilter) { bNameFilter = (PatternMatching(puChar, m_pchFilteredName, 16) == NULL); }
return bNameFilter; }
BOOL CFilteredIndexName::CheckWinsRecordForFilter(WinsRecord *pWinsRecord) { UINT nCountOwner = (UINT)m_dwaFilteredOwners.GetSize(); UINT nCountType = m_mapFilterTypes.GetHashTableSize(); UINT nCountIPAddrs = (UINT)m_taFilteredIp.GetSize(); BOOL bOwnerFilter = (nCountOwner == 0); BOOL bTypeFilter = (nCountType == 0); BOOL bIPAddrsFilter = (nCountIPAddrs == 0); BOOL bNameFilter = (m_pchFilteredName == NULL); UINT i, j;
//-------------------------------------
// check the owner filter first, if any
for (i = 0; !bOwnerFilter && i < nCountOwner; i++) { if (pWinsRecord->dwOwner == m_dwaFilteredOwners.GetAt(i)) bOwnerFilter = TRUE; } if (!bOwnerFilter) return FALSE;
//-------------------------------------
// check the type filter if any
if (!bTypeFilter) { DWORD dwType; // keep in mind the name's type is in the lowest 16 bits of pWinsRecord->dwType
// (see WinsIntfToWinsRecord())
dwType = pWinsRecord->dwType & 0x0000ffff; if (!m_mapFilterTypes.Lookup(dwType, bTypeFilter)) { // no entry for this name type. Check the FFFF name type (other) to see if we should
// show it.
dwType = 0xFFFF; m_mapFilterTypes.Lookup(dwType, bTypeFilter); } } if (!bTypeFilter) return FALSE;
//-------------------------------------
// check the IP address filter if any
for (i = 0; !bIPAddrsFilter && i < nCountIPAddrs; i++) { if (pWinsRecord->dwState & WINSDB_REC_MULT_ADDRS) { for (j=0; !bIPAddrsFilter && j < pWinsRecord->dwNoOfAddrs; j++) { bIPAddrsFilter = SubnetMatching(m_taFilteredIp[i], pWinsRecord->dwIpAdd[j]); } } else { bIPAddrsFilter = SubnetMatching(m_taFilteredIp[i], pWinsRecord->dwIpAdd[0]); } } if(!bIPAddrsFilter) return FALSE;
//-------------------------------------
// check the name filter if any
if (!bNameFilter) { bNameFilter = (PatternMatching(pWinsRecord->szRecordName, m_pchFilteredName, 16) == NULL); }
return bNameFilter; }
LPCSTR CFilteredIndexName::PatternMatching(LPCSTR pName, LPCSTR pPattern, INT nNameLen) { LPCSTR pNameBak = pName;
// it is guaranteed here we have a valid (not NULL) pattern
while (*pPattern != '\0' && pName-pNameBak < nNameLen) { BOOL bChMatch = (*pPattern == *pName); if (!m_bMatchCase && !bChMatch) { bChMatch = (islower(*pPattern) && _toupper(*pPattern) == *pName) || (islower(*pName) && *pPattern == _toupper(*pName)); }
if (*pPattern == '?' || bChMatch) { pPattern++; } else if (*pPattern == '*') { LPCSTR pTrail = pName; INT nTrailLen = nNameLen-(UINT)(pTrail-pNameBak);
pPattern++; while ((pName = PatternMatching(pTrail, pPattern, nTrailLen)) != NULL) { pTrail++; nTrailLen--; if (*pTrail == '\0' || nTrailLen <= 0) break; }
return pName; } else if (!bChMatch) { // in the test above, note that even in the unikely case *pName == '\0'
// *pName will not match *pPattern so the loop is still broken - which is
// the desired behavior. In this case the pattern was not consummed
// and the name was, so the return will indicate the matching failed
break; }
pName++; }
return *pPattern == '\0' ? NULL : pName; }
BOOL CFilteredIndexName::SubnetMatching(tIpReference &IpRefPattern, DWORD dwIPAddress) { DWORD dwMask;
return (IpRefPattern.Address & IpRefPattern.Mask) == (dwIPAddress & IpRefPattern.Mask); }
HRESULT CFilteredIndexName::ClearFilter(WINSDB_FILTER_TYPE FilterType) { HRESULT hr = hrOK;
switch(FilterType) { case WINSDB_FILTER_BY_TYPE: m_mapFilterTypes.RemoveAll(); break;
case WINSDB_FILTER_BY_OWNER: m_dwaFilteredOwners.RemoveAll(); break;
case WINSDB_FILTER_BY_IPADDR: m_taFilteredIp.RemoveAll(); break;
case WINSDB_FILTER_BY_NAME: if (m_pchFilteredName != NULL) { delete m_pchFilteredName; m_pchFilteredName = NULL; } break; default: Panic0("Invalid filter type passed to CFilteredIndexName::ClearFilter"); break; }
return hr; }
|