BOOL CUploadTransferED2K::ServeRequests()
{
	if ( m_nState != upsUploading && m_nState != upsRequest ) return TRUE;
	ASSERT( m_pBaseFile != NULL );
	
	if ( m_pClient == NULL || m_pClient->m_pOutput == NULL ) return TRUE;
	if ( m_pClient->m_pOutput->m_nLength > Settings.eDonkey.FrameSize ) return TRUE;
	
	if ( m_nLength == SIZE_UNKNOWN )
	{
		// Check has just finished
		if ( m_bStopTransfer )
		{
			m_tRotateTime = 0;
			m_bStopTransfer	= FALSE;
			
			CUploadQueue* pQueue = m_pQueue;
			if ( pQueue ) pQueue->Dequeue( this );
			pQueue->Enqueue( this, TRUE, FALSE );
			
			int nQpos = UploadQueues.GetPosition( this, TRUE );
			if ( nQpos != 0 )
			{			
				if ( m_pBaseFile != NULL && m_pClient->IsOnline() )
				{
					Send( CEDPacket::New( ED2K_C2C_FINISHUPLOAD ) );
				}
				
				if ( nQpos > 0 )	// If we aren't uploading any more (the queue wasn't empty)
				{
					// Set state to queued, and reset ranking to send a queue ranking packet.
					m_tRequest = GetTickCount();
					m_nState = upsQueued;
					m_nRanking = -1;
				}

				return TRUE;
			}
		}
		if ( ! OpenFile() ) return FALSE;
		if ( ! StartNextRequest() ) return FALSE;
	}
	
	if ( m_nLength != SIZE_UNKNOWN )
	{
		if ( DispatchNextChunk() )
		{
			CheckFinishedRequest();
		}
		else
		{
			Cleanup();
			Close();
			return FALSE;
		}
	}
	return TRUE;
}
BOOL CUploadTransferDC::RequestFile(CLibraryFile* pFile, QWORD nOffset, QWORD nLength)
{
	m_pXML.Clear();

	if ( ! RequestComplete( pFile ) )
	{
		ASSERT( FALSE );
		return FALSE;
	}

	if ( ! UploadQueues.CanUpload( PROTOCOL_DC, pFile, FALSE ) )
	{
		theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress, (LPCTSTR)m_sName );

		m_pClient->SendCommand( FILE_NOT_AVAILABLE );

		return TRUE;
	}

	m_nOffset = nOffset;
	if ( m_nOffset >= m_nSize )
		m_nLength = SIZE_UNKNOWN;
	else
		m_nLength = min( ( ( nLength == SIZE_UNKNOWN ) ? m_nSize : nLength ), m_nSize - m_nOffset );
	m_nPosition = 0;

	if ( m_nLength > m_nSize || m_nOffset + m_nLength > m_nSize )
	{
		theApp.Message( MSG_ERROR, IDS_UPLOAD_BAD_RANGE, (LPCTSTR)m_sAddress, (LPCTSTR)m_sName );

		m_pClient->SendCommand( FILE_NOT_AVAILABLE );

		return TRUE;
	}

	AllocateBaseFile();

	if ( m_bStopTransfer )
	{
		m_tRotateTime = 0;
		m_bStopTransfer = FALSE;

		CUploadQueue* pQueue = m_pQueue;
		if ( pQueue )
			pQueue->Dequeue( this );
	}

	int nPosition = UploadQueues.GetPosition( this, TRUE );
	if ( nPosition < 0 && UploadQueues.Enqueue( this ) )
	{
		nPosition = UploadQueues.GetPosition( this, TRUE );
	}

	if ( nPosition == 0 )
	{
		// Ready to send
		if ( m_bGet )
			return TRUE;	// Wait for $Send

		return SendFile();
	}
	else if ( nPosition > 0 )
	{
		// Queued
		theApp.Message( MSG_INFO, IDS_UPLOAD_QUEUED, (LPCTSTR)m_sName, (LPCTSTR)m_sAddress, nPosition, m_pQueue->GetQueuedCount(), (LPCTSTR)m_pQueue->m_sName );

		CString strQueued;
		strQueued.Format( UPLOAD_QUEUE, nPosition );

		m_pClient->SendCommand( strQueued );

		StartSending( upsPreQueue );

		m_tRankingCheck = GetTickCount();

		return TRUE;
	}
	else
	{
		// Unable to queue anywhere
		UploadQueues.Dequeue( this );
		ASSERT( m_pQueue == NULL );

		theApp.Message( MSG_ERROR, IDS_UPLOAD_BUSY_QUEUE, (LPCTSTR)m_sName, (LPCTSTR)m_sAddress, (LPCTSTR)m_sUserAgent );

		m_pClient->SendCommand( UPLOAD_BUSY );

		return TRUE;
	}
}