📄 memory.cpp
字号:
// @mfunc This function sets the NIO Access state of the data block
//
// @parm IN WORD | wBlockNumber| Block number to set information for
// @parm IN WORD | wState | New NIO Access State of the Block
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
EXPORT32 DWORD CCommonMemory::SetNIOAccess(IN WORD wBlockNumber, BOOL bState)
{
// get a pointer to the list of blocks
DATA_AREA_LINK *pBlockLink;// = (DATA_AREA_LINK *)m_pBlockList->GetAddress();
DWORD dwStatus = ERROR_SUCCESS;
WAITFOR(m_hDataLock);
pBlockLink = (DATA_AREA_LINK *)m_pBlockList->GetAddress();
__try
{
// jump to the requested block
pBlockLink += wBlockNumber;
if (pBlockLink->bInUse == BLOCK_FREE)
{
dwStatus = ERROR_INVALID_BLOCK;
}
else
{
// Set the data
__try
{
pBlockLink->bNIOAccess = bState;
}
__except(MemoryExcFilter(GetExceptionInformation(),DATA_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_hDataLock);
return(dwStatus);
}
}
}
__except(MemoryExcFilter(GetExceptionInformation(),BLOCK_LIST))
{
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_hDataLock);
return(dwStatus);
}
LETGO(m_hDataLock);
return(dwStatus);
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc This function Gets the Internal Address (IOA) of the data block
//
// @parm IN WORD | wBlockNumber| Block number to return information for
// @parm OUT ULONG | pAddress1 | 1st Internal Address
// @parm OUT ULONG | pAddress2 | 2nd Internal Address
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
EXPORT32 DWORD CCommonMemory::GetInternalAddress(IN WORD wBlockNumber, OUT ULONG *pAddress1, OUT ULONG *pAddress2)
{
// get a pointer to the list of blocks
DATA_AREA_LINK *pBlockLink;// = (DATA_AREA_LINK *)m_pBlockList->GetAddress();
DWORD dwStatus = ERROR_SUCCESS;
WAITFOR(m_hDataLock);
pBlockLink = (DATA_AREA_LINK *)m_pBlockList->GetAddress();
__try
{
// jump to the requested block
pBlockLink += wBlockNumber;
if (pBlockLink->bInUse == BLOCK_FREE)
{
dwStatus = ERROR_INVALID_BLOCK;
}
else
{
// Get the data
__try
{
*pAddress1 = pBlockLink->lInternalAddress1;
*pAddress2 = pBlockLink->lInternalAddress2;
}
__except(MemoryExcFilter(GetExceptionInformation(),DATA_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_hDataLock);
return(dwStatus);
}
}
}
__except(MemoryExcFilter(GetExceptionInformation(),BLOCK_LIST))
{
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_hDataLock);
return(dwStatus);
}
LETGO(m_hDataLock);
return(dwStatus);
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc This function Sets the Internal Address (IOA) of the data block
//
// @parm IN WORD | wBlockNumber| Block number to set information for
// @parm IN ULONG | lAddress1 | 1st Internal Address
// @parm IN ULONG | lAddress2 | 2nd Internal Address
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
EXPORT32 DWORD CCommonMemory::SetInternalAddress(IN WORD wBlockNumber, IN ULONG lAddress1, IN ULONG lAddress2)
{
// get a pointer to the list of blocks
DATA_AREA_LINK *pBlockLink;// = (DATA_AREA_LINK *)m_pBlockList->GetAddress();
DWORD dwStatus = ERROR_SUCCESS;
WAITFOR(m_hDataLock);
pBlockLink = (DATA_AREA_LINK *)m_pBlockList->GetAddress();
__try
{
// jump to the requested block
pBlockLink += wBlockNumber;
if (pBlockLink->bInUse == BLOCK_FREE)
{
dwStatus = ERROR_INVALID_BLOCK;
}
else
{
// Set the data
__try
{
pBlockLink->lInternalAddress1 = lAddress1;
pBlockLink->lInternalAddress2 = lAddress2;
}
__except(MemoryExcFilter(GetExceptionInformation(),DATA_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_hDataLock);
return(dwStatus);
}
}
}
__except(MemoryExcFilter(GetExceptionInformation(),BLOCK_LIST))
{
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_hDataLock);
return(dwStatus);
}
LETGO(m_hDataLock);
return(dwStatus);
}
//
// Start of Output Area access functions
//
//----(Member Function)-------------------------------------------------------
//
// @mfunc This function adds an output to the output queue
//
// @parm IN LPVOID | pOutput | Pointer to output information
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
//
EXPORT32 LONG CCommonMemory::AddOutput(IN LPVOID pOutput)
{
// get a pointer to the Output area
// first part of output area is the information part containing
// the head and tail, and statistics
OUTPUT_INFO *pOutputInfo;// = (OUTPUT_INFO *)m_pOutputArea->GetAddress();
OUTPUT_DESC *pOutputArea;// = (OUTPUT_DESC *)(pOutputInfo + 1);
DWORD dwCurrentSize,
dwStatus = ERROR_SUCCESS;
// Check for a NULL pointer
if (NULL == pOutput)
return(ERROR_INVALID_PARAMETER);
WAITFOR(m_hOutputLock);
pOutputInfo = (OUTPUT_INFO *)m_pOutputArea->GetAddress();
pOutputArea = (OUTPUT_DESC *)(pOutputInfo + 1);
__try
{
DWORD dwTempTail;
// jump to the tail, make sure to jump passed info at beginning
pOutputArea += pOutputInfo->dwOutputTail;
// Check if this will cause an overrun
if (m_pOutputArea->GetCurrentSize() == 0)
dwTempTail = 1;
else
dwTempTail = (pOutputInfo->dwOutputTail + 1) %
(m_pOutputArea->GetCurrentSize() / sizeof(OUTPUT_DESC));
if (dwTempTail == pOutputInfo->dwOutputHead)
{
// Do overrun stuff
memcpy((CHAR *)m_pOutputArea->GetAddress() + m_pOutputArea->GetCurrentSize(),
m_pOutputArea->GetAddress(),
pOutputInfo->dwOutputTail * sizeof(OUTPUT_DESC));
dwTempTail = (pOutputInfo->dwOutputTail + 1) %
(m_pOutputArea->GetCurrentSize() / sizeof(OUTPUT_DESC));
}
// now add our new output at the tail
memcpy(pOutputArea, pOutput, sizeof(OUTPUT_DESC));
SetEvent(m_hOutputEvent);
// update the tail pointer
pOutputInfo->dwOutputTail = dwTempTail;
pOutputArea->bInUse = BLOCK_INUSE;
// keep track of statistics on this area
// if the tail is greater than the head, no overlap
// is in effect
if (pOutputInfo->dwOutputTail > pOutputInfo->dwOutputHead)
{
dwCurrentSize = pOutputInfo->dwOutputTail - pOutputInfo->dwOutputHead;
}
else
{
// calculate head to end
dwCurrentSize = (m_pOutputArea->GetCurrentSize() /
sizeof(OUTPUT_DESC)) - pOutputInfo->dwOutputHead;
// add in tail
dwCurrentSize += pOutputInfo->dwOutputTail;
}
if (pOutputInfo->dwMaxNumOutputs <= dwCurrentSize)
pOutputInfo->dwMaxNumOutputs = dwCurrentSize;
}
__except(MemoryExcFilter(GetExceptionInformation(),OUTPUT_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_hOutputLock);
return(dwStatus);
}
LETGO(m_hOutputLock);
return(ERROR_SUCCESS);
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc This function Removes an output from the output queue
//
// @parm IN LPVOID | pOutput | Pointer to output information
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
// @rvalue ERROR_NO_MORE_ITEMS | if no outputs in queue
//
EXPORT32 LONG CCommonMemory::GetOutputHead(OUT LPVOID pOutput)
{
// get a pointer to the Output area
// first part of output area is the information part containing
// the head and tail, and statistics
OUTPUT_INFO *pOutputInfo;// = (OUTPUT_INFO *)m_pOutputArea->GetAddress();
OUTPUT_DESC *pOutputArea;// = (OUTPUT_DESC *)(pOutputInfo + 1);
DWORD dwStatus = ERROR_SUCCESS;
// Check for a NULL pointer
if (NULL == pOutput)
return(ERROR_INVALID_PARAMETER);
WAITFOR(m_hOutputLock);
pOutputInfo = (OUTPUT_INFO *)m_pOutputArea->GetAddress();
pOutputArea = (OUTPUT_DESC *)(pOutputInfo + 1);
__try
{
// Make sure outputs exist
if (pOutputInfo->dwOutputHead != pOutputInfo->dwOutputTail)
{
// jump to the head
pOutputArea += pOutputInfo->dwOutputHead;
// copy to return value
memcpy(pOutput, pOutputArea, sizeof(OUTPUT_DESC));
// update the head
pOutputInfo->dwOutputHead = (pOutputInfo->dwOutputHead + 1) %
(m_pOutputArea->GetCurrentSize() / sizeof(OUTPUT_DESC));
pOutputArea->bInUse = BLOCK_FREE;
// for performance reasons, if the head and tail are the same, go back to beginning
// of memory so that the increment to correct location is less
if (pOutputInfo->dwOutputHead == pOutputInfo->dwOutputTail)
pOutputInfo->dwOutputHead = pOutputInfo->dwOutputTail = 1;
}
else
{
dwStatus = ERROR_NO_MORE_ITEMS;
}
}
__except(MemoryExcFilter(GetExceptionInformation(),OUTPUT_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_hOutputLock);
return(dwStatus);
}
LETGO(m_hOutputLock);
return(dwStatus);
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc This function Removes a specific output from a the output queue
//
// @parm IN LPVOID | pOutput | Pointer to output information
//
// @parm IN DWORD | dwOutputNumber | Output to retrieve
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
// @rvalue ERROR_NO_MORE_ITEMS | if no outputs in queue
//
EXPORT32 LONG CCommonMemory::GetOutputAt(OUT LPVOID pOutput, IN DWORD dwOutputNumber)
{
// get a pointer to the Output area
// first part of output area is the information part containing
// the head and tail, and statistics
OUTPUT_INFO *pOutputInfo;// = (OUTPUT_INFO *)m_pOutputArea->GetAddress();
OUTPUT_DESC *pOutputArea;// = (OUTPUT_DESC *)(pOutputInfo + 1);
DWORD dwStatus = ERROR_SUCCESS;
// Check for a NULL pointer
if (NULL == pOutput)
return(ERROR_INVALID_PARAMETER);
WAITFOR(m_hOutputLock);
pOutputInfo = (OUTPUT_INFO *)m_pOutputArea->GetAddress();
pOutputArea = (OUTPUT_DESC *)(pOutputInfo + 1);
__try
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -