Example #1
0
//////////////////
//
// XPK fileformat:
// chunk-based, crunched data in chunks
// 
// File header:
// starts as common IFF-style header:
// - 4-byte ID, 'XPKF'
// - 4-byte int for filesize minus header (8)
// - 4-byte sub-type (cruncher-ID) e.g. 'SQSH'
// - 4-byte int for total uncompressed length ?
// - first 16-bytes of original file
// - 1 byte for flags
// - 1 byte for header checksum ?
// - 1 byte for minor version of cruncher/library ?
//  - actually version required of sub-library..
// - 1 byte for major version of cruncher/library ?
//
bool XpkTags::ReadStreamHeader(CIOBuffer &Buffer)
{
	// should have enough data to actually parse file header
	if (Buffer.GetSize() < sizeof(XpkStreamHeader))
	{
		return false;
	}
	
	if (isXpkFile(Buffer.GetBegin()) == false)
	{
		return false;
	}
	Buffer.SetCurrentPos(0); // start at beginning if not already..
	
	// set default
	m_formatType = XPKMODE_UPSTD;
	
	// "XPKF", 0x58504b46 (XPK_COOKIE, magic number)
	// note: support also XFD-packed files? ("XFDD")
	m_streamHeader.xsh_PackID = GetULong(Buffer.GetNext(4));
	
	if (m_streamHeader.xsh_PackID != MakeTag("XPKF"))
	// this too ? && m_streamHeader.xsh_PackID != MakeTag("XFDD"))
	{
		return false;
	}
	
	// file length without IFF header (type+length = 8) ?
	m_streamHeader.xsh_CompressedLen = GetULong(Buffer.GetNext(4));
	
	// keep packer type as type name/ID,
	// just access as-is
	m_typeName.assign((char*)Buffer.GetAtCurrent(), 4);
	
	// packer type, e.g. "SQSH", "NUKE", "RLEN"..
	m_streamHeader.xsh_PackerType = GetULong(Buffer.GetNext(4));
	
	// TODO: check supported types..? if != MakeTag()..
	// -> caller/parent should do (knows libraries..)
	
	// uncompressed length?
	m_streamHeader.xsh_UnpackedLen = GetULong(Buffer.GetNext(4));

	// first 16 bytes of original file
	::memcpy(m_streamHeader.xsh_Initial, Buffer.GetNext(16), 16);
	
	// flags
	m_streamHeader.xsh_Flags = Buffer.GetNextByte();
	
	/*
	// also check "XFDD", 0x58464444 in file ID?
	if (m_streamHeader.xsh_Flags & XMF_XFD && m_streamHeader.xsh_PackID == MakeTag("XFDD"))
	{
		m_formatType = XPKMODE_UPXFD;
	}
	
	if (m_streamHeader.xsh_Flags & XMF_PASSTHRU)
	{
		// unpacked?
		m_formatType = XPKMODE_UPUP;
	}
	
	if (m_streamHeader.xsh_Flags & XPKSTREAMF_PASSWORD)
	{
		// password-protected file?
	}
	*/
	
	// ..no idea.. header checksum?
	m_streamHeader.xsh_HeaderChk = Buffer.GetNextByte();
	
	// minor&major version of XPK master/cruncher?
	m_streamHeader.xsh_SubVrs = Buffer.GetNextByte(); // sub-library version required?
	m_streamHeader.xsh_MasVrs = Buffer.GetNextByte();
	
	// TODO: remove later, debug-test..
	if (Buffer.GetCurrentPos() != sizeof(XpkStreamHeader))
	{
		throw IOException("Read size does not match stream-header size");
	}
	
	// non-zero header checksum? (note where doing checksumming..)
    if (hchecksum(Buffer.GetBegin(), sizeof(XpkStreamHeader)) != 0)
    {
		throw ArcException("Header checksum error", m_streamHeader.xsh_HeaderChk);
    }
    
    // has extended header?
    if (m_streamHeader.xsh_Flags & XPKSTREAMF_EXTHEADER)
    {
		// size of extended header if present?
		m_extHeaderLen = GetUWord(Buffer.GetNext(2));
		
		/*
		// this done above..		
	    if(!hookread(xbuf, XIO_READ, &exthlen, sizeof(UWORD)))
			goto Abort; -> exception
			
		// no read, just skip it??
        if(!hookread(xbuf, XIO_READ, NULL, exthlen))
			goto Abort; -> exception
			
		// later it is read anyway, why not just directly when detected?
			
		*/
		
		// increment by length-field size anyway..
        m_extHeaderLen += sizeof(uint16_t);	/* for unwinding while XpkExamine */
        
        // note: increase buffer position by size of extended header?
	}

	// header parsed, should be valid file?	
	return true;
}
Example #2
0
int CSocketServer::Run()
{
	try
	{
		vector<WorkerThread *> workers;
		
		workers.reserve( m_numThreads );
		
		for ( size_t i = 0; i < m_numThreads; ++i )
		{
			/*
			 * Call to unqualified virtual function
			 */
			WorkerThread *pThread = CreateWorkerThread( m_iocp ); 
			
			workers.push_back( pThread );
			
			pThread->Start();
		}
		
		HANDLE handlesToWaitFor[2];
		
		handlesToWaitFor[0] = m_shutdownEvent.GetEvent();
		handlesToWaitFor[1] = m_acceptConnectionsEvent.GetEvent();
		
		while ( !m_shutdownEvent.Wait( 0 ) )
		{
			DWORD waitResult = ::WaitForMultipleObjects( 2, handlesToWaitFor, false, INFINITE );
			
			if ( waitResult == WAIT_OBJECT_0 )
			{
				/*
				 * Time to shutdown
				 */
				break;
			}
			else if ( waitResult == WAIT_OBJECT_0 + 1 )
			{
				/*
				 * accept connections
				 */
				
				while ( !m_shutdownEvent.Wait( 0 ) && m_acceptConnectionsEvent.Wait( 0 ) )
				{
					CIOBuffer *pAddress = Allocate();
					
					int addressSize = (int)pAddress->GetSize();
					
					SOCKET acceptedSocket = ::WSAAccept(
									m_listeningSocket, 
									reinterpret_cast<sockaddr *>(const_cast<BYTE *>( pAddress->GetBuffer() ) ), 
									&addressSize, 
									0, 
									0);
					
					pAddress->Use( addressSize );
					
					if ( acceptedSocket != INVALID_SOCKET )
					{
						Socket *pSocket = AllocateSocket( acceptedSocket );
						
						/*
						 * Call to unqualified virtual function
						 */
						OnConnectionEstablished( pSocket, pAddress );
					}
					else if ( m_acceptConnectionsEvent.Wait( 0 ) )
					{
						/*
						 * Call to unqualified virtual function
						 */
						OnError( _T("CSocketServer::Run() - WSAAccept:") + GetLastErrorMessage( ::WSAGetLastError() ) );
					}
					
					pAddress->Release();
				}
			}
			else
			{
				/*
				 * Call to unqualified virtual function
				 */
				OnError( _T("CSocketServer::Run() - WaitForMultipleObjects: ") + GetLastErrorMessage( ::GetLastError() ) );
			}
		}
		
		for ( i = 0; i < m_numThreads; ++i )
		{
			workers[i]->InitiateShutdown();
		}  
		
		for ( i = 0; i < m_numThreads; ++i )
		{
			workers[i]->WaitForShutdownToComplete();
			
			delete workers[i];
			
			workers[i] = 0;
		}  
	}
	catch( const CException &e )
	{
		/*
		 * Call to unqualified virtual function
		 */
		OnError( _T("CSocketServer::Run() - Exception: ") + e.GetWhere() + _T(" - ") + e.GetMessage() );
	}
	catch(...)
	{
		/*
		 * Call to unqualified virtual function
		 */
		OnError( _T("CSocketServer::Run() - Unexpected exception") );
	}
	
	/*
	 * Call to unqualified virtual function
	 */
	OnShutdownComplete();
	
	return 0;
}