📄 memory.cpp
字号:
__try
{
// if the tail is greater than the head, no overlap
// is in effect
if (pExceptionInfo->dwExceptionTail >= pExceptionInfo->dwExceptionHead)
{
*dwCurrentSize = pExceptionInfo->dwExceptionTail - pExceptionInfo->dwExceptionHead;
}
else
{
// calculate tail to end
*dwCurrentSize = (m_pExceptionArea->GetCurrentSize() /
sizeof(EXCEPTION_DESC)) - pExceptionInfo->dwExceptionTail;
// add in head
*dwCurrentSize += pExceptionInfo->dwExceptionHead;
}
}
__except(MemoryExcFilter(GetExceptionInformation(),EXCEPTION_AREA))
{
dwStatus = GetExceptionCode();
switch (dwStatus)
{
case EXCEPTION_GMMF_DISKFULL: dwStatus = MEM_DISKFULL; break;
case EXCEPTION_GMMF_CORRUPTEDRGN: dwStatus = MEM_CORRUPT; break;
case EXCEPTION_GMMF_WRITEPAST: dwStatus = MEM_WRITEPAST; break;
default: dwStatus = MEM_UNKNOWN; break;
}
LETGO(m_hExceptionLock);
return(dwStatus);
}
LETGO(m_hExceptionLock);
return(dwStatus);
}
//
// Start of Event Area access functions
//
//----(Member Function)-------------------------------------------------------
//
// @mfunc This function adds an Event to the Event queue
//
// @parm IN LPVOID | pEvent | Pointer to Event information
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
//
EXPORT32 LONG CCommonMemory::AddEvent(IN LPVOID pEvent)
{
// get a pointer to the Event area
// first part of Event area is the information part containing
// the head and tail, and statistics
EVENT_INFO *pEventInfo;// = (EVENT_INFO *)m_pEventArea->GetAddress();
EVENT_DESC *pEventArea;// = (EVENT_DESC *)(pEventInfo + 1);
DWORD dwCurrentSize,
dwStatus = ERROR_SUCCESS;
// Check for a NULL pointer
if (NULL == pEvent)
return(ERROR_INVALID_PARAMETER);
WAITFOR(m_hEventLock);
pEventInfo = (EVENT_INFO *)m_pEventArea->GetAddress();
pEventArea = (EVENT_DESC *)(pEventInfo + 1);
__try
{
DWORD dwTempTail;
// jump to the tail, make sure to jump passed info at beginning
pEventArea += pEventInfo->dwEventTail;
// Check if this will cause an overrun
if (m_pEventArea->GetCurrentSize() == 0)
dwTempTail = 1;
else
dwTempTail = (pEventInfo->dwEventTail + 1) %
(m_pEventArea->GetCurrentSize() / sizeof(EVENT_DESC));
if (dwTempTail == pEventInfo->dwEventHead)
{
// Do overrun stuff
memcpy((CHAR *)m_pEventArea->GetAddress() + m_pEventArea->GetCurrentSize(),
m_pEventArea->GetAddress(),
pEventInfo->dwEventTail * sizeof(EVENT_DESC));
dwTempTail = (pEventInfo->dwEventTail + 1) %
(m_pEventArea->GetCurrentSize() / sizeof(EVENT_DESC));
}
// now add our new Event at the tail
memcpy(pEventArea, pEvent, sizeof(EVENT_DESC));
// update the tail pointer
pEventInfo->dwEventTail = dwTempTail;
pEventArea->bInUse = BLOCK_INUSE;
}
__except(MemoryExcFilter(GetExceptionInformation(),EVENT_AREA))
{
dwStatus = GetExceptionCode();
switch (dwStatus)
{
case EXCEPTION_GMMF_DISKFULL: dwStatus = MEM_DISKFULL; break;
case EXCEPTION_GMMF_CORRUPTEDRGN: dwStatus = MEM_CORRUPT; break;
case EXCEPTION_GMMF_WRITEPAST: dwStatus = MEM_WRITEPAST; break;
default: dwStatus = MEM_UNKNOWN; break;
}
LETGO(m_hEventLock);
return(dwStatus);
}
// keep track of statistics on this area
// if the tail is greater than the head, no overlap
// is in effect
if (pEventInfo->dwEventTail > pEventInfo->dwEventHead)
{
dwCurrentSize = pEventInfo->dwEventTail - pEventInfo->dwEventHead;
}
else
{
// calculate head to end
dwCurrentSize = (m_pEventArea->GetCurrentSize() /
sizeof(EVENT_DESC)) - pEventInfo->dwEventHead;
// add in tail
dwCurrentSize += pEventInfo->dwEventTail;
}
if (pEventInfo->dwMaxNumEvent <= dwCurrentSize)
pEventInfo->dwMaxNumEvent = dwCurrentSize;
LETGO(m_hEventLock);
return(dwStatus);
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc This function Removes an Event from the Event queue
//
// @parm IN LPVOID | pEvent | Pointer to Event information
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
// @rvalue ERROR_NO_MORE_ITEMS | if no Events in queue
//
EXPORT32 LONG CCommonMemory::GetEventHead(OUT LPVOID pEvent)
{
// get a pointer to the Event area
// first part of Event area is the information part containing
// the head and tail, and statistics
EVENT_INFO *pEventInfo;// = (EVENT_INFO *)m_pEventArea->GetAddress();
EVENT_DESC *pEventArea;// = (EVENT_DESC *)(pEventInfo + 1);
DWORD dwStatus = ERROR_SUCCESS;
// Check for a NULL pointer
if (NULL == pEvent)
return(ERROR_INVALID_PARAMETER);
WAITFOR(m_hEventLock);
pEventInfo = (EVENT_INFO *)m_pEventArea->GetAddress();
pEventArea = (EVENT_DESC *)(pEventInfo + 1);
__try
{
// Make sure Events exist
if (pEventInfo->dwEventHead != pEventInfo->dwEventTail)
{
// XXXX need to check for block not in use....
// jump to the head
pEventArea += pEventInfo->dwEventHead;
// copy to return value
memcpy(pEvent, pEventArea, sizeof(EVENT_DESC));
// update the head
pEventInfo->dwEventHead = (pEventInfo->dwEventHead + 1) %
(m_pEventArea->GetCurrentSize() / sizeof(EVENT_DESC));
pEventArea->bInUse = BLOCK_FREE;
}
else
{
dwStatus = ERROR_NO_MORE_ITEMS;
}
}
__except(MemoryExcFilter(GetExceptionInformation(),EVENT_AREA))
{
dwStatus = GetExceptionCode();
switch (dwStatus)
{
case EXCEPTION_GMMF_DISKFULL: dwStatus = MEM_DISKFULL; break;
case EXCEPTION_GMMF_CORRUPTEDRGN: dwStatus = MEM_CORRUPT; break;
case EXCEPTION_GMMF_WRITEPAST: dwStatus = MEM_WRITEPAST; break;
default: dwStatus = MEM_UNKNOWN; break;
}
LETGO(m_hEventLock);
return(dwStatus);
}
LETGO(m_hEventLock);
return(dwStatus);
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc This function Removes a specific Event from a the Event queue
//
// @parm IN LPVOID | pEvent | Pointer to Event information
//
// @parm IN DWORD | dwEventNumber | Event to retrieve
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
// @rvalue ERROR_NO_MORE_ITEMS | if no Events in queue
//
EXPORT32 LONG CCommonMemory::GetEventAt(OUT LPVOID pEvent,
IN DWORD dwEventNumber)
{
// get a pointer to the Event area
// first part of Event area is the information part containing
// the head and tail, and statistics
EVENT_INFO *pEventInfo;// = (EVENT_INFO *)m_pEventArea->GetAddress();
EVENT_DESC *pEventArea;// = (EVENT_DESC *)(pEventInfo + 1);
DWORD dwStatus = ERROR_SUCCESS;
// Check for a NULL pointer
if (NULL == pEvent)
return(ERROR_INVALID_PARAMETER);
WAITFOR(m_hEventLock);
pEventInfo = (EVENT_INFO *)m_pEventArea->GetAddress();
pEventArea = (EVENT_DESC *)(pEventInfo + 1);
__try
{
// Make sure Events exist
if (pEventInfo->dwEventHead != pEventInfo->dwEventTail)
{
// jump to the head
pEventArea += dwEventNumber;
// check for block not in use
if (pEventArea->bInUse)
{
// copy to return value
memcpy(pEvent, pEventArea, sizeof(EVENT_DESC));
// if this block is also the head, update the head
if (dwEventNumber == pEventInfo->dwEventHead)
{
pEventInfo->dwEventHead = (pEventInfo->dwEventHead + 1) %
(m_pEventArea->GetCurrentSize() / sizeof(EVENT_DESC));
}
else if (dwEventNumber == pEventInfo->dwEventTail)
{
if (pEventInfo->dwEventTail == 0)
{
pEventInfo->dwEventTail = (m_pEventArea->GetCurrentSize() / sizeof(EVENT_DESC));
}
else
{
pEventInfo->dwEventTail--;
}
}
pEventArea->bInUse = BLOCK_FREE;
}
else
{
dwStatus = ERROR_INVALID_BLOCK;
}
}
else
{
dwStatus = ERROR_NO_MORE_ITEMS;
}
}
__except(MemoryExcFilter(GetExceptionInformation(),EVENT_AREA))
{
dwStatus = GetExceptionCode();
switch (dwStatus)
{
case EXCEPTION_GMMF_DISKFULL: dwStatus = MEM_DISKFULL; break;
case EXCEPTION_GMMF_CORRUPTEDRGN: dwStatus = MEM_CORRUPT; break;
case EXCEPTION_GMMF_WRITEPAST: dwStatus = MEM_WRITEPAST; break;
default: dwStatus = MEM_UNKNOWN; break;
}
LETGO(m_hEventLock);
return(dwStatus);
}
LETGO(m_hEventLock);
return(dwStatus);
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc This function returns the number of elements in the Event queue
//
// @parm None
//
// @rvalue ERROR_SUCCESS | If successful
//
EXPORT32 DWORD CCommonMemory::GetEventCount(OUT DWORD *dwCurrentSize)
{
// get a pointer to the Event area
// first part of Event area is the information part containing
// the head and tail, and statistics
EVENT_INFO *pEventInfo;// = (EVENT_INFO *)m_pEventArea->GetAddress();
EVENT_DESC *pEventArea;// = (EVENT_DESC *)(pEventInfo + 1);
// Check for a NULL pointer
if (NULL == dwCurrentSize)
return(ERROR_INVALID_PARAMETER);
WAITFOR(m_hEventLock);
pEventInfo = (EVENT_INFO *)m_pEventArea->GetAddress();
pEventArea = (EVENT_DESC *)(pEventInfo + 1);
// if the tail is greater than the head, no overlap
// is in effect
if (pEventInfo->dwEventTail >= pEventInfo->dwEventHead)
{
*dwCurrentSize = pEventInfo->dwEventTail - pEventInfo->dwEventHead;
}
else
{
// calculate head to end
*dwCurrentSize = (m_pEventArea->GetCurrentSize() /
sizeof(EVENT_DESC)) - pEventInfo->dwEventHead;
// add in tail
*dwCurrentSize += pEventInfo->dwEventTail;
}
LETGO(m_hEventLock);
return(ERROR_SUCCESS);
}
LONG WINAPI CCommonMemory::MemoryExcFilter(PEXCEPTION_POINTERS pException,
int nWhichArea)
{
switch (pException->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_GMMF_DISKFULL:
case EXCEPTION_GMMF_WRITEPAST:
case EXCEPTION_GMMF_CORRUPTEDRGN:
return(EXCEPTION_EXECUTE_HANDLER);
break;
default:
break;
}
switch (nWhichArea)
{
case DATA_AREA:
return(m_pDataArea->ExcFilter(pException));
break;
case OUTPUT_AREA:
return(m_pOutputArea->ExcFilter(pException));
break;
case EXCEPTION_AREA:
return(m_pExceptionArea->ExcFilter(pException));
break;
case BLOCK_LIST:
return(m_pBlockList->ExcFilter(pException));
break;
case EVENT_AREA:
return(m_pEventArea->ExcFilter(pException));
break;
}
return(EXCEPTION_CONTINUE_SEARCH);
}
/*------------------------------------------------------------------------
EXPORT32 void CCommonMemory::DumpBytes(IN WORD nDumpWhich,
IN const TCHAR *szFileName,
IN OPTIONAL DWORD dwOffset,
IN OPTIONAL DWORD dwCount)
{
CFile myFile;
CFileException fileException;
void *pBytesToDump;
DWORD dwNumBytes = dwCount;
if (!myFile.Open(szFileName, CFile::modeCreate |
CFile::modeReadWrite, &fileException ))
{
TRACE( "Can't open file %s, error = %u\n",
szFileName, fileException.m_cause );
}
switch (nDumpWhich)
{
case 0:
pBytesToDump = m_pBlockList->GetAddress();
pBytesToDump = (char *)pBytesToDump + dwOffset;
if (dwCount == 0)
dwNumBytes = m_pBlockList->GetCurrentSize() - dwOffset;
break;
case 1:
pBytesToDump = m_pDataArea->GetAddress();
pBytesToDump = (char *)pBytesToDump + dwOffset;
if (dwCount == 0)
dwNumBytes = m_pDataArea->GetCurrentSize() - dwOffset;
break;
}
myFile.Write(pBytesToDump, dwNumBytes);
myFile.Close();
}
------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -