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

📄 memory.cpp

📁 具有工业强度的内存池动态库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// @doc
//
// @module		Memory.cpp - Common Memory Object |
//
// The CCommonMemory class contains member functions that allow the
// caller to read and write the runtime data for the I/O driver
//

// Maintenance:
//	
// Version		Date		Who		What
// -------   -----------  ------	-------------------------------------
// 7.0		 07/27/96		msb		Created
//			 01/06/97		msb		added functions for nio access and block status
//			 02/04/97		msb		added functions for IOA access
//			 02/27/97		blm		Integrated EventArea from Raptor (kwr)
//									Renamed Memory.h DrvMemory.h
//			 05/29/98		blm		Added security attributes to CreateMutex() and
//									CreateEvent() so would work as a Service
//
// 7.12		 12/28/99		mvs		Modified CreateDataBlock() - We need to 
//									initialize the internal addresses else if 
//									this is a block which is being reused we 
//									could end up with the wrong internal address
//

#include "stdafx.h"
#include <stdio.h>
#include <ItkErr.h>
#include "DrvMemory.h"


// 
// @mfunc <c CCommonMemory> constructor for this class. This
//		  constuctor creates the memory areas required for the
//		  shared data for the driver
//
EXPORT32 CCommonMemory::CCommonMemory( IN DWORD dwAreas, IN const TCHAR *szAppName)
{
	TCHAR	szAreaName[MAX_PATH],
			szRegistryName[MAX_PATH];

	sprintf(szRegistryName, "Software\\Intellution\\Drivers\\%s", szAppName);

	//
	// Initialize all our data members for this class
	//
	m_pDataArea			= NULL;
	m_pBlockList		= NULL;
	m_pOutputArea		= NULL;
	m_pExceptionArea	= NULL;
	m_pEventArea		= NULL;
	m_hDataLock			= NULL;
	m_hOutputLock		= NULL;
	m_hExceptionLock	= NULL;
	m_hEventLock		= NULL;
	m_dwHoles			= 0;


	//
	//  Initialize the Win32 security attributes structures
	//  Let everybody in...
	//

	SECURITY_ATTRIBUTES SecAttr;
	SECURITY_DESCRIPTOR SecDesc;

	INIT_SECURITY_ALL(SecAttr, SecDesc);


	// 
	// Create the input area & initialize variables
	//
	if (dwAreas & DATA_AREA)
	{
		sprintf(szAreaName, "%s_InputArea", szAppName);
		m_pDataArea = new CGmmf(szAppName, szRegistryName, szAreaName);
		sprintf(szAreaName, "%s_InputLock", szAppName);
		m_hDataLock = CreateMutex(&SecAttr, FALSE, szAreaName);
	}
	
	//
	// Create the Block List area
	//
	if (dwAreas & BLOCK_LIST)
	{
		sprintf(szAreaName, "%s_BlockList", szAppName);
		m_pBlockList = new CGmmf(szAppName, szRegistryName, szAreaName);
		m_dwHoles = 0;
	}

	//
	// Create the Output area & initialize variables
	// Also create an event that will be triggered when someone places data 
	// in the output area to be written.
	//
	if (dwAreas & OUTPUT_AREA)
	{
		sprintf(szAreaName, "%s_OutputArea", szAppName);
		m_pOutputArea = new CGmmf(szAppName, szRegistryName, szAreaName);
		sprintf(szAreaName, "%s_OutputLock", szAppName);
		m_hOutputLock = CreateMutex(&SecAttr, FALSE, szAreaName);

		sprintf(szAreaName, "%s_OutputEvent", szAppName);
		m_hOutputEvent = CreateEvent(&SecAttr, FALSE, FALSE, szAreaName);
	}

	//
	// Create the exception area & initialize variables
	//
	if (dwAreas & EXCEPTION_AREA)
	{
		sprintf(szAreaName, "%s_ExceptionArea", szAppName);
		m_pExceptionArea = new CGmmf(szAppName, szRegistryName, szAreaName);
		sprintf(szAreaName, "%s_ExceptionLock", szAppName);
		m_hExceptionLock = CreateMutex(&SecAttr, FALSE, szAreaName);
	}

	//
	// Create the events area & initialize variables
	//
	if (dwAreas & EVENT_AREA)
	{
		sprintf(szAreaName, "%s_EventArea", szAppName);
		m_pEventArea = new CGmmf(szAppName, szRegistryName, szAreaName);
		sprintf(szAreaName, "%s_EventLock", szAppName);
		m_hEventLock = CreateMutex(&SecAttr, FALSE, szAreaName);
	}
}



// 
// @mfunc <c CCommonMemory> destructor for this class. This
//		  destuctor deletes the memory areas required for the
//		  shared data for the driver
//
EXPORT32 CCommonMemory::~CCommonMemory(void)
{
	// remove the four areas and the locks that were created
	if (NULL != m_pDataArea)
		delete m_pDataArea;
	if (NULL != m_pBlockList)
		delete m_pBlockList;
	if (NULL != m_hDataLock)
		CloseHandle(m_hDataLock);

	if (NULL != m_pOutputArea)
		delete m_pOutputArea;
	if (NULL != m_hOutputLock)
		CloseHandle(m_hOutputLock);
	if (NULL != m_hOutputEvent)
		CloseHandle(m_hOutputEvent);

	if (NULL != m_pExceptionArea)
		delete m_pExceptionArea;
	if (NULL != m_hExceptionLock)
		CloseHandle(m_hExceptionLock);

	if (NULL != m_pEventArea)
		delete m_pEventArea;
	if (NULL != m_hEventLock)
		CloseHandle(m_hEventLock);
}

//
// @mfunc This function creates a block for storing real time data
//
// @parm OUT LONG * | lBlockNum | Index of block number
//
// @parm IN OPTIONAL WORD | wByteSize | Number of bytes block should be
//
// @parm IN OPTIONAL DWORD | dwDataBlockHandle | Handle of DataBlock this
//		memory block is being created for
//
// @rvalue Error value. ERROR_SUCCESS if successful.
//
EXPORT32 DWORD CCommonMemory::CreateDataBlock(OUT WORD *wBlockNum,
											 IN OPTIONAL WORD wByteSize /* = 250 */,
											 IN OPTIONAL DWORD dwDataBlockHandle /* = NULL */)
{
	DWORD dwStatus = ERROR_SUCCESS;

	// get a pointer to the list of blocks
	DATA_AREA_LINK  *pBlockLink,// = (DATA_AREA_LINK *)m_pBlockList->GetAddress(),
					*pPrevBlockLink;

	*wBlockNum = 0;
	
	WAITFOR(m_hDataLock);

	pBlockLink = (DATA_AREA_LINK *)m_pBlockList->GetAddress();

	__try
	{
		if (m_dwHoles != 0)
		{
			// find an unused block in the list. Either free and will fit, or never used
			while (!((pBlockLink->bInUse == BLOCK_FREE) &&
				    ((wByteSize <= pBlockLink->wBlockSize) || 
					 (pBlockLink->wBlockSize == 0))))
			{
				// get next block number and keep track of number
				pBlockLink++;
				(*wBlockNum)++;
			}

			// used a hole if this was previously used
			if (pBlockLink->wBlockSize != 0)
				m_dwHoles--; 
		}
		else
		{
			// go right to the end
			*wBlockNum = (WORD)m_pBlockList->GetElements();
			pBlockLink += *wBlockNum;
		}

		// need pointer to previous block to update this one
		pPrevBlockLink = pBlockLink;

		// make sure this isn't the first one
		if (pBlockLink != m_pBlockList->GetAddress())
			pPrevBlockLink--;

		// now we have one, record the information
		pBlockLink->bInUse = BLOCK_INUSE;
		pBlockLink->wBlockSize = wByteSize;
		//	mvs122899 - We need to initialize the internal addresses 
		//	else if this is a block which is being reused we could end 
		//	up with the wrong internal addresses
		pBlockLink->lInternalAddress1 = 0;
		pBlockLink->lInternalAddress2 = 0;
		pBlockLink->wBytesInUse = 0;
		pBlockLink->wDataStatus = 0;
		pBlockLink->bNIOAccess = FALSE;
		pBlockLink->dwDataBlockHandle = dwDataBlockHandle;

		// store the offset to this block
		if (pPrevBlockLink != pBlockLink)
			pBlockLink->dwBlockOffset = pPrevBlockLink->dwBlockOffset + pPrevBlockLink->wBlockSize;
	}
	__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);
	}

	__try
	{
		// point to the data area and clear it
		char *pDataArea = (char *)m_pDataArea->GetAddress();
		pDataArea += pBlockLink->dwBlockOffset;
		memset(pDataArea, 0, pBlockLink->wBlockSize);
	}
	__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);
	}

	// keep track of how many data blocks are currently in use
	m_pBlockList->IncElements();

	LETGO(m_hDataLock);

	return(ERROR_SUCCESS);
}

//----(Member Function)-------------------------------------------------------
//
// @mfunc This function Sets the actual number of bytes in use 
// for a datablock
//
// @parm  IN WORD | wBlockNumber | Number of block
// @parm  IN WORD | wNumBytes | Number of bytes in use
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
EXPORT32 DWORD CCommonMemory::SetBytesInUse(IN WORD wBlockNumber, IN WORD wNumBytes)
{
	// 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->wBytesInUse = wNumBytes;
			}
			__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 deletes a block for storing real time data
//
// @parm  IN WORD | wBlockNumber | Number of block to free
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
EXPORT32 DWORD CCommonMemory::DestroyDataBlock(IN WORD wBlockNumber)
{
	// 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_INUSE)
		{
			pBlockLink->bInUse = BLOCK_FREE;
			m_dwHoles++; // made a hole

			// keep track of how many data blocks are currently in use
			m_pBlockList->DecElements();
		}
		else
		{
			dwStatus = ERROR_INVALID_BLOCK;
		}
	}
	 __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 returns a block of real time data
//
// @parm  IN WORD | wBlockNumber | Number of block to access
//
// @parm  IN WORD | wNumBytes | Number of bytes to return
//
// @parm  OUT LPVOID | pData | Buffer to hold data
//
// @parm  IN OPTIONAL WORD | wOffset | Number of bytes to offset from start
//
// @parm  IN OPTIONAL BOOL | bIgnoreBytesInUse | Ignore bytes in use value and get block anyway
//
// @rvalue ERROR_SUCCESS | If successful
//
// @rvalue ERROR_INVALID_BLOCK | If block not in use
//
// @rvalue ERROR_INVALID_BLOCK_LENGTH | if wNumBytes is greater than block size
//
EXPORT32 DWORD CCommonMemory::GetDataBlock(IN WORD wBlockNumber, 
										   IN WORD wNumBytes, 

⌨️ 快捷键说明

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