📄 utils.cpp
字号:
goto Done;
}
//
// Update structures
ASSERT(pLastNode->m_uiReadyToRead >= uiToRead);
ASSERT(m_uiReadyToRead >= uiToRead);
ASSERT((BYTE*)pLastNode->m_pHead + pLastNode->m_uiBlockSize + 1 >= pLastNode->m_pReadBuffer + uiToRead);
pLastNode->m_uiReadyToRead -= uiToRead;
pLastNode->m_pReadBuffer += uiToRead;
m_uiReadyToRead -= uiToRead;
//
// If nothing is left in this buffer and its done being written to,
// return it to the buffer pool
if(0 == pLastNode->m_uiWriteRemaining &&
0 == pLastNode->m_uiReadyToRead) {
m_BufferList.pop_back();
SMB_Globals::g_PrinterMemMapBuffers.Return(pLastNode->m_pHead);
//TRACEMSG(ZONE_PRINTQUEUE, (L"SMB_SRV: Ring buffer using -%d nodes", m_BufferList.size()));
delete pLastNode;
}
*puiReturned = uiToRead;
}
//
// Success
hr = S_OK;
Done:
LeaveCriticalSection(&m_myLock);
return hr;
}
HRESULT
RingBuffer::Write(const BYTE *pSrc, UINT uiSize, UINT *puiWritten)
{
EnterCriticalSection(&m_myLock);
HRESULT hr = E_FAIL;
UINT uiToWrite;
RING_NODE *pFirstNode = NULL;
BOOL fNewNodeNeeded = FALSE;
*puiWritten = 0;
#ifdef DEBUG
{
//
// Verify we have the correct amount of memory accounted for
UINT uiVerify = 0;
ce::list<RING_NODE *, RING_LIST_NODE_ALLOC >::iterator it = m_BufferList.begin();
ce::list<RING_NODE *, RING_LIST_NODE_ALLOC >::iterator itEnd = m_BufferList.end();
while(it != itEnd) {
uiVerify += (*it)->m_uiReadyToRead;
it ++;
}
ASSERT(uiVerify == m_uiReadyToRead);
}
#endif
//
// If we dont have any buffers in our list or the first one is empty
// create a new one
if(0 == m_BufferList.size()) {
fNewNodeNeeded = TRUE;
} else {
pFirstNode = m_BufferList.front();
if(0 == pFirstNode->m_uiWriteRemaining) {
fNewNodeNeeded = TRUE;
}
}
//
// If we need a new node, do the creation
if(TRUE == fNewNodeNeeded) {
RING_NODE *pNew = new RING_NODE();
if(NULL == pNew) {
goto Done;
}
pNew->m_pHead = SMB_Globals::g_PrinterMemMapBuffers.Create(&pNew->m_uiBlockSize);
if(NULL == pNew->m_pHead) {
TRACEMSG(ZONE_ERROR, (L"SMB_SRV: RingBuffer cant get new memory block! -- this is okay but we cant continue"));
delete pNew;
hr = S_OK;
goto Done;
}
pNew->m_pReadBuffer = pNew->m_pWriteBuffer = (BYTE *)pNew->m_pHead;
pNew->m_uiWriteRemaining = pNew->m_uiBlockSize;
pNew->m_uiReadyToRead = 0;
if(!m_BufferList.push_front(pNew)) {
delete pNew;
hr = E_OUTOFMEMORY;
goto Done;
}
TRACEMSG(ZONE_PRINTQUEUE, (L"SMB_SRV: Ring buffer using +(%d) nodes", m_BufferList.size()));
}
pFirstNode = m_BufferList.front();
ASSERT(pFirstNode->m_uiWriteRemaining >= 0);
//
// If there is data remaining on the current block
// read it now
uiToWrite = uiSize;
if(uiToWrite > pFirstNode->m_uiWriteRemaining) {
uiToWrite = pFirstNode->m_uiWriteRemaining;
}
//
// Do the move (note exception handler because this is from
// memmap file
__try {
memcpy(pFirstNode->m_pWriteBuffer, pSrc, uiToWrite);
} __except(1) {
TRACEMSG(ZONE_ERROR, (L"SMB_SRV: RingBuffer caught exception!! this is BAD"));
ASSERT(FALSE);
hr = E_FAIL;
goto Done;
}
//
// Update structures
m_uiReadyToRead += uiToWrite;
pFirstNode->m_uiReadyToRead += uiToWrite;
pFirstNode->m_uiWriteRemaining -= uiToWrite;
pFirstNode->m_pWriteBuffer += uiToWrite;
*puiWritten = uiToWrite;
ASSERT(uiSize >= uiToWrite);
//
// Success
hr = S_OK;
Done:
LeaveCriticalSection(&m_myLock);
return hr;
}
UINT
RingBuffer::BytesReadyToRead()
{
CCritSection csLock(&m_myLock);
csLock.Lock();
return m_uiReadyToRead;
}
//
// Return the # of seconds since Jan1 1970 at 0:00:00
unsigned int SecSinceJan1970_0_0_0 (void) {
SYSTEMTIME st;
GetSystemTime (&st);
LARGE_INTEGER ft;
SystemTimeToFileTime (&st, (FILETIME *)&ft);
ft.QuadPart -= 0x019db1ded53e8000;
ft.QuadPart /= 10000000;
return ft.LowPart;
}
unsigned int SecSinceJan1970_0_0_0 (FILETIME *_ft) {
LARGE_INTEGER ft; //<-- this copying is done b/c we might not be aligned on 8 bytes!
memcpy(&ft, _ft, sizeof(LARGE_INTEGER));
ASSERT(sizeof(FILETIME) == sizeof(LARGE_INTEGER));
ft.QuadPart -= 0x019db1ded53e8000;
ft.QuadPart /= 10000000;
return ft.LowPart;
}
BOOL FileTimeFromSecSinceJan1970(UINT uiSec, FILETIME *_ft) {
LARGE_INTEGER ft;
ft.QuadPart = uiSec;
ft.QuadPart *= 10000000;
ft.QuadPart += 0x019db1ded53e8000;
memcpy(_ft, &ft, sizeof(LARGE_INTEGER));
return 1;
}
MemMappedBuffer::MemMappedBuffer():
m_hFile(INVALID_HANDLE_VALUE),
m_hMapping(INVALID_HANDLE_VALUE),
m_pNext(NULL),
m_uiMaxSize(0),
m_uiInc(0),
m_uiBlocksOutstanding(0),
m_uiUsed(0),
m_fInited(FALSE)
{
InitializeCriticalSection(&myLock);
}
MemMappedBuffer::~MemMappedBuffer()
{
ASSERT(NULL == m_pNext);
ASSERT(0 == m_uiBlocksOutstanding);
ASSERT(0 == m_uiUsed);
TRACEMSG(ZONE_PRINTQUEUE, (L"SMB_SRV: MemMappedBuffer going down\n"));
TRACEMSG(ZONE_PRINTQUEUE, (L" %d blocks outstanding", m_uiBlocksOutstanding));
TRACEMSG(ZONE_PRINTQUEUE, (L" %d bytes used\n", m_uiUsed));
//
// Close the file mapping
if(INVALID_HANDLE_VALUE != m_hMapping) {
CloseHandle(m_hMapping);
}
DeleteCriticalSection(&myLock);
}
HRESULT
MemMappedBuffer::Close()
{
CCritSection csLock(&myLock);
csLock.Lock();
ASSERT(NULL == m_pNext);
ASSERT(0 == m_uiBlocksOutstanding);
ASSERT(0 == m_uiUsed);
if(INVALID_HANDLE_VALUE != m_hMapping) {
CloseHandle(m_hMapping);
}
m_hFile = INVALID_HANDLE_VALUE;
m_hMapping =INVALID_HANDLE_VALUE;
m_pNext = NULL;
m_uiMaxSize = 0;
m_uiInc = 0;
m_uiBlocksOutstanding = 0;
m_uiUsed = 0;
m_fInited = FALSE;
//
// Success
return S_OK;
}
HRESULT
MemMappedBuffer::Open(WCHAR *pFile, UINT _uiMaxSize, UINT _uiInc)
{
EnterCriticalSection(&myLock);
HRESULT hr = E_FAIL;
ASSERT(FALSE == m_fInited);
//
// If we are in the incorrect state, assert and return unexpected
if(INVALID_HANDLE_VALUE != m_hFile ||
INVALID_HANDLE_VALUE != m_hMapping ||
NULL != m_pNext ||
0 != m_uiUsed) {
TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error Open called twice?"));
ASSERT(FALSE);
LeaveCriticalSection(&myLock);
return E_UNEXPECTED;
}
m_uiMaxSize = _uiMaxSize;
m_uiInc = _uiInc;
//
// Call CreateFileForMapping to open up our file
m_hFile = CreateFileForMapping(pFile,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE == m_hFile) {
TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error -- cant open file!: 0x%x", GetLastError()));
hr = E_UNEXPECTED;
goto Done;
}
//
// Create an unnamed file mapping
m_hMapping = CreateFileMapping(m_hFile,
NULL,
PAGE_READWRITE,
NULL,
m_uiMaxSize,
NULL);
if(INVALID_HANDLE_VALUE == m_hMapping) {
TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error -- CreateFileMapping failed with 0x%x!", GetLastError()));
ASSERT(FALSE);
hr = E_UNEXPECTED;
goto Done;
}
#ifdef DEBUG
{
VOID *pRet;
//
// Make sure we can actually map the entire contents of the file before
// going on. This is just for debugging because we handle the case
// where it CANT be done later -- but in order for testing to be accurate
// we want to acutally have the correct buffer spaces
pRet = MapViewOfFile(m_hMapping,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
m_uiMaxSize);
if(NULL != pRet) {
__try {
memset(pRet, 0, m_uiMaxSize);
} __except(1) {
TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error -- memset on mapping test THREW!"));
ASSERT(FALSE);
}
UnmapViewOfFile(pRet);
} else {
TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error -- cant map view of file! 0x%x!", GetLastError()));
ASSERT(FALSE);
}
}
#endif
//
// At this point we dont have anything memory mapped -- this is to prevent
// us from using too much space
//
hr = S_OK;
Done:
if(FAILED(hr)) {
//
// Close the file mapping
if(INVALID_HANDLE_VALUE != m_hMapping) {
CloseHandle(m_hMapping);
}
//
// Get back into steady state
m_hMapping = INVALID_HANDLE_VALUE;
m_hFile = INVALID_HANDLE_VALUE;
m_uiMaxSize = 0;
m_uiInc = 0;
m_pNext=NULL;
m_uiUsed=0;
} else {
m_uiMaxSize = _uiMaxSize;
m_uiInc = _uiInc;
m_fInited = TRUE;
}
LeaveCriticalSection(&myLock);
return hr;
}
VOID *
MemMappedBuffer::Create(UINT *pBlockSize)
{
EnterCriticalSection(&myLock);
VOID *pRet = NULL;
*pBlockSize = 0;
//
// If we havent been inited error out
if(FALSE == m_fInited) {
ASSERT(FALSE);
goto Done;
}
//
// First thing, see if we have any memory laying around that we can
// give out
if(NULL != m_pNext) {
//TRACEMSG(ZONE_PRINTQUEUE, (L"SMB-MEMMAP: Got a free block to give back -- no work required."));
pRet = m_pNext;
m_pNext = (VOID *)(*(UINT *)m_pNext);
goto Done;
}
//
// If there isnt a free block, see if we can map a new one on the tail end of the file
if(m_uiMaxSize - m_uiUsed >= m_uiInc) {
//
// Do the file mapping
pRet = MapViewOfFile(m_hMapping,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
m_uiUsed,
m_uiInc);
if(NULL == pRet) {
TRACEMSG(ZONE_PRINTQUEUE, (L"SMB-MEMMAP: Couldnt map a file view... this is bad and is an internal error: %d", GetLastError()));
ASSERT(FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -