|
|
/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/ /**********************************************************************/
/*
memmngr.cpp memory manager for the WINS db object
FILE HISTORY: Oct 13 1997 EricDav Modifed
*/
#include "stdafx.h"
#include "wins.h"
#include "memmngr.h"
CMemoryManager::CMemoryManager() { m_hHeap = NULL; }
CMemoryManager::~CMemoryManager() { Reset(); } /*!--------------------------------------------------------------------------
CMemoryManager::Initialize Initializes the memory manager to free up and existing blocks and pre-allocate one block Author: EricDav, v-shubk ---------------------------------------------------------------------------*/ HRESULT CMemoryManager::Initialize() { HRESULT hr = hrOK;
CORg (Reset()); CORg (Allocate());
// create a heap for allocation of the multiple IP address blocks
m_hHeap = HeapCreate(0, 4096, 0); if (m_hHeap == NULL) { Trace1("CMemoryManager::Initialize - HeapCreate failed! %d\n", GetLastError()); return E_FAIL; }
Error: return hr; }
/*!--------------------------------------------------------------------------
CMemoryManager::Reset Free's up all memory Author: EricDav, v-shubk ---------------------------------------------------------------------------*/ HRESULT CMemoryManager::Reset() { // free the memory allocated
for (int i = 0; i< m_BlockArray.GetSize(); i++) { ::GlobalFree(m_BlockArray.GetAt(i)); } m_BlockArray.RemoveAll();
if (m_hHeap) { HeapDestroy(m_hHeap); m_hHeap = NULL; }
return hrOK; }
/*!--------------------------------------------------------------------------
CMemoryManager::Allocate Allocates one memory block Author: EricDav, v-shubk ---------------------------------------------------------------------------*/ HRESULT CMemoryManager::Allocate() { HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, BLOCK_SIZE); if (hMem != NULL) { m_hrowCurrent = (LPWINSDBRECORD) hMem; m_BlockArray.Add(hMem);
return hrOK; }
return E_FAIL; }
/*!--------------------------------------------------------------------------
CMemoryManager::IsvalidHRow Verifies that the given HROW is valid Author: EricDav, v-shubk ---------------------------------------------------------------------------*/ BOOL CMemoryManager::IsValidHRow(HROW hrow) { // check to see thet this HROW lies between the
// limits, i.e b/n hMem and hMem + INIT_SIZE
for (int i = 0; i < m_BlockArray.GetSize(); i++) { if (hrow >= (HROW)(m_BlockArray.GetAt(i)) && (hrow < (HROW)(m_BlockArray.GetAt(i)) + BLOCK_SIZE)) return TRUE; }
return FALSE; }
/*!--------------------------------------------------------------------------
CMemoryManager::AddData Copies a record into our internal store Author: EricDav, v-shubk ---------------------------------------------------------------------------*/ HRESULT CMemoryManager::AddData(const WinsRecord & wRecord, LPHROW phrow) { HRESULT hr = hrOK;
CSingleLock cLock(&m_cs); cLock.Lock();
Assert((BYTE) wRecord.szRecordName[15] == (BYTE) wRecord.dwType);
// check if for the validity fo the current
// m_hrowCurrent
if (!IsValidHRow((HROW) m_hrowCurrent)) { Allocate(); m_hrowCurrent = (LPWINSDBRECORD) (m_BlockArray.GetAt(m_BlockArray.GetSize() - 1)); }
WinsRecordToWinsDbRecord(m_hHeap, wRecord, m_hrowCurrent);
if (phrow) *phrow = (HROW) m_hrowCurrent; // move our pointer to the next record
m_hrowCurrent++;
return hr; }
/*!--------------------------------------------------------------------------
CMemoryManager::GetData Copies a record into our internal store Author: EricDav, v-shubk ---------------------------------------------------------------------------*/ HRESULT CMemoryManager::GetData(HROW hrow, LPWINSRECORD pWinsRecord) { HRESULT hr = hrOK; LPWINSDBRECORD pDbRec = (LPWINSDBRECORD) hrow;
CSingleLock cLock(&m_cs); cLock.Lock();
// check if for the validity fo the current
// m_hrowCurrent
if (!IsValidHRow(hrow)) { return E_FAIL; }
WinsDbRecordToWinsRecord(pDbRec, pWinsRecord);
return hr; }
/*!--------------------------------------------------------------------------
CMemoryManager::Delete Marks a record as deleted Author: EricDav, v-shubk ---------------------------------------------------------------------------*/ HRESULT CMemoryManager::Delete(HROW hrow) { HRESULT hr = hrOK;
CSingleLock cLock(&m_cs); cLock.Lock();
LPWINSDBRECORD pRec = (LPWINSDBRECORD) hrow;
pRec->szRecordName[17] |= WINSDB_INTERNAL_DELETED;
return hr; }
void WinsRecordToWinsDbRecord(HANDLE hHeap, const WinsRecord & wRecord, const LPWINSDBRECORD pRec) { ZeroMemory(pRec, sizeof(WinsDBRecord));
// fill in our internal struct, first the name
if (IS_WINREC_LONGNAME(&wRecord)) { // name is too long for our internal struct, allocate space off of our heap
// this shouldn't happen very often. Only for scoped names.
pRec->szRecordName[17] |= WINSDB_INTERNAL_LONG_NAME; char * pName = (char *) ::HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (wRecord.dwNameLen + 1)); if (pName) { memcpy(pName, &wRecord.szRecordName[0], wRecord.dwNameLen); memcpy(&pRec->szRecordName[0], &pName, sizeof(char *)); } } else { memcpy(&pRec->szRecordName[0], &wRecord.szRecordName[0], 16); }
pRec->dwExpiration = (DWORD) wRecord.dwExpiration; pRec->liVersion.QuadPart = wRecord.liVersion.QuadPart; pRec->dwOwner = wRecord.dwOwner;
// max length is 255, so this is OK
pRec->szRecordName[19] = LOBYTE(LOWORD(wRecord.dwNameLen));
BYTE bTest = HIBYTE(LOWORD(wRecord.dwState));
pRec->szRecordName[20] = HIBYTE(LOWORD(wRecord.dwState));
// only the low byte of the dwState field is used
pRec->szRecordName[18] = (BYTE) wRecord.dwState; pRec->szRecordName[17] |= HIWORD (wRecord.dwType);
// now figure out how many IP addrs there are
if (wRecord.dwNoOfAddrs > 1) { Assert(hHeap); LPDWORD pdwIpAddrs = (LPDWORD) ::HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (wRecord.dwNoOfAddrs + 1) * sizeof(DWORD));
if (pdwIpAddrs) { // first DWORD contains the # of addrs
pdwIpAddrs[0] = wRecord.dwNoOfAddrs; for (UINT i = 0; i < wRecord.dwNoOfAddrs; i++) pdwIpAddrs[i+1] = wRecord.dwIpAdd[i];
// now store our pointer off
pRec->dwIpAdd = (DWORD_PTR) pdwIpAddrs; } } else { pRec->dwIpAdd = wRecord.dwIpAdd[0]; }
Assert((BYTE) pRec->szRecordName[16] == NULL); }
void WinsDbRecordToWinsRecord(const LPWINSDBRECORD pDbRec, LPWINSRECORD pWRec) { Assert((BYTE) pDbRec->szRecordName[16] == NULL);
ZeroMemory(pWRec, sizeof(WinsRecord)); DWORD dwType = 0;
size_t length = pDbRec->szRecordName[19] & 0x000000FF;
// fill in our internal struct, name first
if (IS_DBREC_LONGNAME(pDbRec)) { char * pName = *((char **) pDbRec->szRecordName);
memcpy(&pWRec->szRecordName[0], pName, length); dwType = (DWORD) pName[15]; } else { memcpy(&pWRec->szRecordName[0], &pDbRec->szRecordName[0], 16); dwType = (DWORD) pWRec->szRecordName[15]; }
pWRec->dwExpiration = pDbRec->dwExpiration; pWRec->liVersion.QuadPart = pDbRec->liVersion.QuadPart; pWRec->dwOwner = pDbRec->dwOwner; pWRec->dwNameLen = length; WORD wState = MAKEWORD(pDbRec->szRecordName[18], pDbRec->szRecordName[20]); pWRec->dwState = wState;
//pWRec->dwState = pDbRec->szRecordName[18];
pWRec->dwType = pDbRec->szRecordName[17] & 0x03; pWRec->dwType = pWRec->dwType << 16;
pWRec->dwType |= dwType;
// now the ip address(es)
if (pWRec->dwState & (BYTE) WINSDB_REC_MULT_ADDRS) { LPDWORD pdwIpAddrs = (LPDWORD) pDbRec->dwIpAdd; // the first DWORD is the count
int nCount = pdwIpAddrs[0]; for (int i = 0; i < nCount; i++) pWRec->dwIpAdd[i] = pdwIpAddrs[i+1];
pWRec->dwNoOfAddrs = (DWORD) nCount; } else { pWRec->dwIpAdd[0] = (DWORD) pDbRec->dwIpAdd; pWRec->dwNoOfAddrs = 1; } }
|