Example #1
0
void FileList::AddFile(const char *filepath, const char *filename, FileListNodeContext context)
{
	if (filepath == 0 || filename == 0)
		return;
	char *data;
	//std::fstream file;
	//file.open(filename, std::ios::in | std::ios::binary);
	FILE *fp = fopen(filepath, "rb");
	if (fp == 0)
		return;
	fseek(fp, 0, SEEK_END);
	int length = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	if (length > (int)((unsigned int) - 1 / 8)) {
		// If this assert hits, split up your file. You could also change BitSize_t in RakNetTypes.h to unsigned long long but this is not recommended for performance reasons
		RakAssert("Cannot add files over 536 MB" && 0);
		fclose(fp);
		return;
	}
	bool usedAlloca = false;
	if (length < MAX_ALLOCA_STACK_ALLOCATION) {
		data = (char*) alloca(length);
		usedAlloca = true;
	} else
		data = (char*) rakMalloc_Ex(length, __FILE__, __LINE__);
	fread(data, 1, length, fp);
	AddFile(filename, filepath, data, length, length, context);
	fclose(fp);
	if (usedAlloca == false)
		rakFree_Ex(data, __FILE__, __LINE__);
}
Example #2
0
void FileList::Clear(void)
{
	unsigned i;
	for (i = 0; i < fileList.Size(); i++)
		rakFree_Ex(fileList[i].data, __FILE__, __LINE__);
	fileList.Clear(false, __FILE__, __LINE__);
}
Example #3
0
void TCPInterface::DeallocatePacket( Packet *packet )
{
    if (packet==0)
        return;
    if (packet->deleteData)
    {
        rakFree_Ex(packet->data, __FILE__, __LINE__ );
        incomingMessages.Deallocate(packet, __FILE__,__LINE__);
    }
    else
    {
        // Came from userspace AllocatePacket
        rakFree_Ex(packet->data, __FILE__, __LINE__ );
        RakNet::OP_DELETE(packet, __FILE__, __LINE__);
    }
}
void HuffmanEncodingTree::FreeMemory( void )
{
	if ( root == 0 )
		return ;

	// Use an in-order traversal to delete the tree
	DataStructures::Queue<HuffmanEncodingTreeNode *> nodeQueue;

	HuffmanEncodingTreeNode *node;

	nodeQueue.Push( root, __FILE__, __LINE__  );

	while ( nodeQueue.Size() > 0 )
	{
		node = nodeQueue.Pop();

		if ( node->left )
			nodeQueue.Push( node->left, __FILE__, __LINE__  );

		if ( node->right )
			nodeQueue.Push( node->right, __FILE__, __LINE__  );

		RakNet::OP_DELETE(node, __FILE__, __LINE__);
	}

	// Delete the encoding table
	for ( int i = 0; i < 256; i++ )
		rakFree_Ex(encodingTable[ i ].encoding, __FILE__, __LINE__ );

	root = 0;
}
Example #5
0
void MessageFilter::DeallocateFilterSet(FilterSet* filterSet)
{
	unsigned i;
	for (i = 0; i < filterSet->allowedRPCs.Size(); i++)
		rakFree_Ex(filterSet->allowedRPCs[i], __FILE__, __LINE__);
	RakNet::OP_DELETE(filterSet, __FILE__, __LINE__);
}
bool SystemAddressList::Load(const char *filename)
{
	FILE *fp = NULL;
	unsigned long fileSize;

	if ( ( fp = fopen( filename, "rb" ) ) == 0 )
		return false;

	fseek( fp, 0, SEEK_END );
	fileSize = ftell( fp );
	fseek( fp, 0, SEEK_SET );
	if (fileSize==0)
	{
		fclose(fp);
		return false;
	}
	unsigned char *filedata = (unsigned char*) rakMalloc_Ex( fileSize, __FILE__, __LINE__ );
	fread(filedata, fileSize, 1, fp);
	fclose(fp);

	RakNet::BitStream bs(filedata, fileSize, false);
	Deserialize(&bs);
	rakFree_Ex(filedata, __FILE__, __LINE__ );
	return true;
}
ThreadsafePacketLogger::~ThreadsafePacketLogger()
{
	char **msg;
	while ((msg = logMessages.ReadLock()) != 0)
	{
		rakFree_Ex((*msg), __FILE__, __LINE__ );
	}
}
void FileListTransfer::PushReference(SystemAddress systemAddress)
{
	// Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this
	unsigned int i=0;
	unsigned int bytesRead;	
	char *dataBlocks[2];
	int lengths[2];
	RakNet::BitStream outBitstream;
	while (i < filesToPush.Size())
	{
		if (filesToPush[i].systemAddress==systemAddress)
		{
			outBitstream.Reset();
			outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH);
			outBitstream.Write(filesToPush[i].fileListNode.context);
			outBitstream.Write(filesToPush[i].setID);
			stringCompressor->EncodeString(filesToPush[i].fileListNode.filename, 512, &outBitstream);
			outBitstream.WriteCompressed(filesToPush[i].setIndex);
			outBitstream.WriteCompressed(filesToPush[i].fileListNode.dataLengthBytes); // Original length in bytes

			// Read and send chunk. If done, delete at this index
			void *buff = rakMalloc_Ex(filesToPush[i].chunkSize, __FILE__, __LINE__);
			if (buff==0)
			{
				notifyOutOfMemory(__FILE__, __LINE__);
				continue;
			}
			bytesRead=filesToPush[i].incrementalReadInterface->GetFilePart(filesToPush[i].fileListNode.fullPathToFile, filesToPush[i].currentOffset, filesToPush[i].chunkSize, buff, filesToPush[i].fileListNode.context);
			outBitstream.WriteCompressed(filesToPush[i].currentOffset);
			filesToPush[i].currentOffset+=bytesRead;
			outBitstream.WriteCompressed(bytesRead);
			bool done = bytesRead!=filesToPush[i].chunkSize;
			outBitstream.Write(done);

			if (callback)
			{
				callback->OnFilePush(filesToPush[i].fileListNode.filename, filesToPush[i].fileListNode.fileLengthBytes, filesToPush[i].currentOffset-bytesRead, bytesRead, done, filesToPush[i].systemAddress);
			}

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=(char*) buff;
			lengths[1]=bytesRead;
			//rakPeerInterface->SendList(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false);
			SendListUnified(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false);
			if (done)
			{
				// Done
				RakNet::OP_DELETE_ARRAY(filesToPush[i].fileListNode.filename, __FILE__, __LINE__);
				filesToPush.RemoveAtIndex(i);
			}
			rakFree_Ex(buff, __FILE__, __LINE__ );
			return;
		}			
		else
			i++;
	}	
}
void ThreadsafePacketLogger::Update(void)
{
	char **msg;
	while ((msg = logMessages.ReadLock()) != 0)
	{
		WriteLog(*msg);
		rakFree_Ex((*msg), __FILE__, __LINE__ );
	}
}
Example #10
0
void RakVoice::Deinit(void)
{
	// check pointer before free
	if (bufferedOutput)
	{
		rakFree_Ex(bufferedOutput, __FILE__, __LINE__ );
		bufferedOutput = 0;
		CloseAllChannels();
	}
}
Example #11
0
void RakNetTransport2::Stop(void)
{
	newConnections.Clear(__FILE__, __LINE__);
	lostConnections.Clear(__FILE__, __LINE__);
	for (unsigned int i=0; i < packetQueue.Size(); i++)
	{
		rakFree_Ex(packetQueue[i]->data,__FILE__,__LINE__);
		RakNet::OP_DELETE(packetQueue[i],__FILE__,__LINE__);
	}
	packetQueue.Clear(__FILE__, __LINE__);
}
RakNet::RakString PostgreSQLInterface::GetEscapedString(const char *input) const
{
	unsigned long len = (unsigned long) strlen(input);
	char *fn = (char*) rakMalloc_Ex(len*2+1,_FILE_AND_LINE_);
	int error;
	PQescapeStringConn(pgConn, fn, input, len, &error);
	RakNet::RakString output;
	// Use assignment so it doesn't parse printf escape strings
	output = fn;
	rakFree_Ex(fn,_FILE_AND_LINE_);
	return output;
}
	void StopThreads(void)
	{
		threadPool.StopThreads();
		RakAssert(threadPool.NumThreadsWorking()==0);

		unsigned i;
		AutopatcherClientThreadInfo* info;
		for (i=0; i < threadPool.InputSize(); i++)
		{
			info = threadPool.GetInputAtIndex(i);
			if (info->prePatchFile)
				rakFree_Ex(info->prePatchFile, _FILE_AND_LINE_ );
			if (info->postPatchFile)
				rakFree_Ex(info->postPatchFile, _FILE_AND_LINE_ );
			if (info->onFileStruct.fileData)
				rakFree_Ex(info->onFileStruct.fileData, _FILE_AND_LINE_ );
			RakNet::OP_DELETE(info, _FILE_AND_LINE_);
		}
		threadPool.ClearInput();
		for (i=0; i < threadPool.OutputSize(); i++)
		{
			info = threadPool.GetOutputAtIndex(i);
			if (info->prePatchFile)
				rakFree_Ex(info->prePatchFile, _FILE_AND_LINE_ );
			if (info->postPatchFile)
				rakFree_Ex(info->postPatchFile, _FILE_AND_LINE_ );
			if (info->onFileStruct.fileData)
				rakFree_Ex(info->onFileStruct.fileData, _FILE_AND_LINE_ );
			RakNet::OP_DELETE(info, _FILE_AND_LINE_);
		}
		threadPool.ClearOutput();
	}
Example #14
0
void TelnetTransport::SetSendPrefix(const char *prefix)
{
	if (sendPrefix)
	{
		rakFree_Ex(sendPrefix, __FILE__, __LINE__ );
		sendPrefix=0;
	}
	if (prefix)
	{
		sendPrefix = (char*) rakMalloc_Ex(strlen(prefix)+1, __FILE__, __LINE__);
		strcpy(sendPrefix, prefix);
	}
}
Example #15
0
void ConsoleServer::SetPrompt(const char *_prompt)
{
	if (prompt)
		rakFree_Ex(prompt,__FILE__,__LINE__);
	if (_prompt && _prompt[0])
	{
		size_t len = strlen(_prompt);
		prompt = (char*) rakMalloc_Ex(len+1,__FILE__,__LINE__);
		strcpy(prompt,_prompt);
	}
	else
		prompt=0;
}
void FullyConnectedMesh::Startup(const char *password, int _passwordLength)
{
	if (pw)
		rakFree_Ex(pw, __FILE__, __LINE__ );
	if (password)
	{
		pw = (char*) rakMalloc_Ex( _passwordLength, __FILE__, __LINE__ );
		memcpy(pw, password, _passwordLength);
		passwordLength=_passwordLength;
	}
	else
		pw=0;
	
}
Example #17
0
void FileList::AddFile(const char *filename, const char *fullPathToFile, const char *data, const unsigned dataLength, const unsigned fileLength, FileListNodeContext context, bool isAReference)
{
	if (filename==0)
		return;
	if (strlen(filename)>MAX_FILENAME_LENGTH)
	{
		// Should be enough for anyone
		RakAssert(0);
		return;
	}
	// If adding a reference, do not send data
	RakAssert(isAReference==false || data==0);
	// Avoid duplicate insertions unless the data is different, in which case overwrite the old data
	unsigned i;
	for (i=0; i<fileList.Size();i++)
	{
		if (strcmp(fileList[i].filename, filename)==0)
		{
			if (fileList[i].fileLengthBytes==fileLength && fileList[i].dataLengthBytes==dataLength &&
				(dataLength==0 || fileList[i].data==0 ||
				memcmp(fileList[i].data, data, dataLength)==0
				))
				// Exact same file already here
				return;

			// File of the same name, but different contents, so overwrite
			rakFree_Ex(fileList[i].data, __FILE__, __LINE__ );
			fileList.RemoveAtIndex(i);
			break;
		}
	}

	FileListNode n;
//	size_t fileNameLen = strlen(filename);
	if (dataLength && data)
	{
		n.data=(char*) rakMalloc_Ex( dataLength, __FILE__, __LINE__ );
		memcpy(n.data, data, dataLength);
	}
	else
		n.data=0;
	n.dataLengthBytes=dataLength;
	n.fileLengthBytes=fileLength;
	n.isAReference=isAReference;
	n.context=context;
	n.filename=filename;
	n.fullPathToFile=fullPathToFile;
		
	fileList.Insert(n, __FILE__, __LINE__);
}
void FileListTransfer::SendIRIToAddress(SystemAddress systemAddress)
{
	// Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this
	unsigned int bytesRead;	
	const char *dataBlocks[2];
	int lengths[2];
	unsigned int smallFileTotalSize=0;
	RakNet::BitStream outBitstream;

	filesToPushAllSameAddressMutex.Lock();
	for (unsigned int ftpIndex=0; ftpIndex < filesToPushAllSameAddress.Size(); ftpIndex++)
	{
		FileToPushRecipient *ftpr = filesToPushAllSameAddress[ftpIndex];
		if (ftpr->systemAddress==systemAddress)
		{
			FileToPush *ftp = ftpr->filesToPush.Peek();

			// Read and send chunk. If done, delete at this index
			void *buff = rakMalloc_Ex(ftp->chunkSize, __FILE__, __LINE__);
			if (buff==0)
			{
				filesToPushAllSameAddressMutex.Unlock();
				notifyOutOfMemory(__FILE__, __LINE__);
				return;
			}

			bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);
			bool done = bytesRead!=ftp->chunkSize;
			while (done && ftp->currentOffset==0 && ftpr->filesToPush.Size()>=2 && smallFileTotalSize<ftp->chunkSize)
			{
				// Send all small files at once, rather than wait for ID_FILE_LIST_REFERENCE_PUSH. But at least one ID_FILE_LIST_REFERENCE_PUSH must be sent
				outBitstream.Reset();
				outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE);
				outBitstream.Write(ftp->fileListNode.context);
				outBitstream.Write(ftp->setID);
				stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
				outBitstream.WriteCompressed(ftp->setIndex);
				outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
				outBitstream.AlignWriteToByteBoundary();
				dataBlocks[0]=(char*) outBitstream.GetData();
				lengths[0]=outBitstream.GetNumberOfBytesUsed();
				dataBlocks[1]=(const char*) buff;
				lengths[1]=bytesRead;
				SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);

				RakNet::OP_DELETE(ftp,__FILE__,__LINE__);
				ftpr->filesToPush.Pop();
				smallFileTotalSize+=bytesRead;
				done = bytesRead!=ftp->chunkSize;
				ftp = ftpr->filesToPush.Peek();
				bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);
			}


			outBitstream.Reset();
			outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH);
			outBitstream.Write(ftp->fileListNode.context);
			outBitstream.Write(ftp->setID);
			stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
			outBitstream.WriteCompressed(ftp->setIndex);
			outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
			outBitstream.WriteCompressed(ftp->currentOffset);
			ftp->currentOffset+=bytesRead;
			outBitstream.WriteCompressed(bytesRead);
			outBitstream.Write(done);

			if (callback)
			{
				callback->OnFilePush(ftp->fileListNode.filename, ftp->fileListNode.fileLengthBytes, ftp->currentOffset-bytesRead, bytesRead, done, systemAddress);
			}

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=(char*) buff;
			lengths[1]=bytesRead;
			//rakPeerInterface->SendList(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, ftp->systemAddress, false);
			SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);
			if (done)
			{
				// Done
				RakNet::OP_DELETE(ftp,__FILE__,__LINE__);
				ftpr->filesToPush.Pop();
				if (ftpr->filesToPush.Size()==0)
				{
					RakNet::OP_DELETE(ftpr,__FILE__,__LINE__);
					filesToPushAllSameAddress.RemoveAtIndexFast(ftpIndex);
				}
			}
			rakFree_Ex(buff, __FILE__, __LINE__ );
			break;
		}
	}
	filesToPushAllSameAddressMutex.Unlock();
}
	// Update is run in the user thread
	virtual bool Update(void)
	{
		if (threadPool.HasOutputFast() && threadPool.HasOutput())
		{
			AutopatcherClientThreadInfo *threadInfo = threadPool.GetOutput();
			threadInfo->onFileStruct.context.op=threadInfo->result;
			switch (threadInfo->result)
			{
				case PC_NOTICE_WILL_COPY_ON_RESTART:
				{
					client->CopyAndRestart(threadInfo->onFileStruct.fileName);
					if (threadInfo->onFileStruct.context.op==PC_WRITE_FILE)
					{
						// Regular file in use but we can write the temporary file.  Restart and copy it over the existing
						onFileCallback->OnFile(&threadInfo->onFileStruct);
					}
					else
					{
						// Regular file in use but we can write the temporary file.  Restart and copy it over the existing
						rakFree_Ex(threadInfo->onFileStruct.fileData, _FILE_AND_LINE_ );
						threadInfo->onFileStruct.fileData=threadInfo->postPatchFile;
						onFileCallback->OnFile(&threadInfo->onFileStruct);
						threadInfo->onFileStruct.fileData=0;
					}
				}
				break;
				case PC_ERROR_FILE_WRITE_FAILURE:
				{
					if (threadInfo->onFileStruct.context.op==PC_WRITE_FILE)
					{
						onFileCallback->OnFile(&threadInfo->onFileStruct);
					}
					else
					{
						rakFree_Ex(threadInfo->onFileStruct.fileData, _FILE_AND_LINE_ );
						threadInfo->onFileStruct.fileData=threadInfo->postPatchFile;
						threadInfo->onFileStruct.byteLengthOfThisFile=threadInfo->postPatchLength;
						onFileCallback->OnFile(&threadInfo->onFileStruct);
						threadInfo->onFileStruct.fileData=0;
					}					
				}
				break;
				case PC_ERROR_PATCH_TARGET_MISSING:
				{
					onFileCallback->OnFile(&threadInfo->onFileStruct);
					client->Redownload(threadInfo->onFileStruct.fileName);
				}
				break;
				case PC_ERROR_PATCH_APPLICATION_FAILURE:
				{
					// Failure - signal class and download this file.
					onFileCallback->OnFile(&threadInfo->onFileStruct);
					client->Redownload(threadInfo->onFileStruct.fileName);
				}
				break;
				case PC_ERROR_PATCH_RESULT_CHECKSUM_FAILURE:
				{
					// Failure - signal class and download this file.
					onFileCallback->OnFile(&threadInfo->onFileStruct);
					client->Redownload(threadInfo->onFileStruct.fileName);
				}
				break;
				default:
				{
					if (threadInfo->onFileStruct.context.op==PC_WRITE_FILE)
					{
						onFileCallback->OnFile(&threadInfo->onFileStruct);
					}
					else
					{
						rakFree_Ex(threadInfo->onFileStruct.fileData, _FILE_AND_LINE_ );
						threadInfo->onFileStruct.fileData=threadInfo->postPatchFile;
						onFileCallback->OnFile(&threadInfo->onFileStruct);
						threadInfo->onFileStruct.fileData=0;
					}
				}
				break;
			}

			if (threadInfo->prePatchFile)
				rakFree_Ex(threadInfo->prePatchFile, _FILE_AND_LINE_ );
			if (threadInfo->postPatchFile)
				rakFree_Ex(threadInfo->postPatchFile, _FILE_AND_LINE_ );
			if (threadInfo->onFileStruct.fileData)
				rakFree_Ex(threadInfo->onFileStruct.fileData, _FILE_AND_LINE_ );
			RakNet::OP_DELETE(threadInfo, _FILE_AND_LINE_);
		}

		// If both input and output are empty, we are done.
		if (onFileCallback->Update()==false)
			canDeleteUser=true;

		if ( downloadComplete &&
			canDeleteUser &&
			threadPool.IsWorking()==false)
		{
			// Stop threads before calling OnThreadCompletion, in case the other thread starts a new instance of this thread.
			StopThreads();
			client->OnThreadCompletion();
			return false;
		}

		return true;
	}
Example #20
0
int SendIRIToAddressCB(FileListTransfer::ThreadData threadData, bool *returnOutput, void* perThreadData)
{
	(void) perThreadData;

	FileListTransfer *fileListTransfer = threadData.fileListTransfer;
	SystemAddress systemAddress = threadData.systemAddress;
	*returnOutput=false;

	// Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this
	unsigned int bytesRead;	
	const char *dataBlocks[2];
	int lengths[2];
	unsigned int smallFileTotalSize=0;
	RakNet::BitStream outBitstream;
	unsigned int ftpIndex;

	fileListTransfer->fileToPushRecipientListMutex.Lock();
	for (ftpIndex=0; ftpIndex < fileListTransfer->fileToPushRecipientList.Size(); ftpIndex++)
	{
		FileListTransfer::FileToPushRecipient *ftpr = fileListTransfer->fileToPushRecipientList[ftpIndex];
		// Referenced by both ftpr and list
		ftpr->AddRef();

		fileListTransfer->fileToPushRecipientListMutex.Unlock();

		if (ftpr->systemAddress==systemAddress)
		{
			FileListTransfer::FileToPush *ftp = ftpr->filesToPush.Peek();

			// Read and send chunk. If done, delete at this index
			void *buff = rakMalloc_Ex(ftp->chunkSize, _FILE_AND_LINE_);
			if (buff==0)
			{
				ftpr->Deref();
				notifyOutOfMemory(_FILE_AND_LINE_);
				return 0;
			}

			// Read the next file chunk
			bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);

			bool done = ftp->fileListNode.dataLengthBytes == ftp->currentOffset+bytesRead;
			while (done && ftp->currentOffset==0 && ftpr->filesToPush.Size()>=2 && smallFileTotalSize<ftp->chunkSize)
			{
				// Send all small files at once, rather than wait for ID_FILE_LIST_REFERENCE_PUSH. But at least one ID_FILE_LIST_REFERENCE_PUSH must be sent
				outBitstream.Reset();
				outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE);
				// outBitstream.Write(ftp->fileListNode.context);
				outBitstream << ftp->fileListNode.context;
				outBitstream.Write(ftp->setID);
				StringCompressor::Instance()->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
				outBitstream.WriteCompressed(ftp->setIndex);
				outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
				outBitstream.AlignWriteToByteBoundary();
				dataBlocks[0]=(char*) outBitstream.GetData();
				lengths[0]=outBitstream.GetNumberOfBytesUsed();
				dataBlocks[1]=(const char*) buff;
				lengths[1]=bytesRead;

				fileListTransfer->SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);

				// LWS : fixed freed pointer reference
//				unsigned int chunkSize = ftp->chunkSize;
				RakNet::OP_DELETE(ftp,_FILE_AND_LINE_);
				ftpr->filesToPush.Pop();
				smallFileTotalSize+=bytesRead;
				//done = bytesRead!=ftp->chunkSize;
				ftp = ftpr->filesToPush.Peek();

				bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);
				done = ftp->fileListNode.dataLengthBytes == ftp->currentOffset+bytesRead;
			}


			outBitstream.Reset();
			outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH);
			// outBitstream.Write(ftp->fileListNode.context);
			outBitstream << ftp->fileListNode.context;
			outBitstream.Write(ftp->setID);
			StringCompressor::Instance()->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
			outBitstream.WriteCompressed(ftp->setIndex);
			outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
			outBitstream.WriteCompressed(ftp->currentOffset);
			ftp->currentOffset+=bytesRead;
			outBitstream.WriteCompressed(bytesRead);
			outBitstream.Write(done);

			for (unsigned int flpcIndex=0; flpcIndex < fileListTransfer->fileListProgressCallbacks.Size(); flpcIndex++)
				fileListTransfer->fileListProgressCallbacks[flpcIndex]->OnFilePush(ftp->fileListNode.filename, ftp->fileListNode.fileLengthBytes, ftp->currentOffset-bytesRead, bytesRead, done, systemAddress, ftp->setID);

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=(char*) buff;
			lengths[1]=bytesRead;
			//rakPeerInterface->SendList(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, ftp->systemAddress, false);
			fileListTransfer->SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);

			// Mutex state: FileToPushRecipient (ftpr) has AddRef. fileToPushRecipientListMutex not locked.
			if (done)
			{
				// Done
				unsigned short setId = ftp->setID;
				RakNet::OP_DELETE(ftp,_FILE_AND_LINE_);
				ftpr->filesToPush.Pop();

				if (ftpr->filesToPush.Size()==0)
				{
					for (unsigned int flpcIndex=0; flpcIndex < fileListTransfer->fileListProgressCallbacks.Size(); flpcIndex++)
						fileListTransfer->fileListProgressCallbacks[flpcIndex]->OnFilePushesComplete(systemAddress, setId);

					// Remove ftpr from fileToPushRecipientList
					fileListTransfer->RemoveFromList(ftpr);
				}
			}

			// ftpr out of scope
			ftpr->Deref();

			rakFree_Ex(buff, _FILE_AND_LINE_ );
			return 0;
		}
		else
		{
			ftpr->Deref();
			fileListTransfer->fileToPushRecipientListMutex.Lock();
		}
	}

	fileListTransfer->fileToPushRecipientListMutex.Unlock();

	return 0;
}
Example #21
0
void FileList::PopulateDataFromDisk(const char *applicationDirectory, bool writeFileData, bool writeFileHash, bool removeUnknownFiles)
{
	FILE *fp;
	char fullPath[512];
	unsigned i;
//	CSHA1 sha1;

	i=0;
	while (i < fileList.Size())
	{
		rakFree_Ex(fileList[i].data, __FILE__, __LINE__ );
		strcpy(fullPath, applicationDirectory);
		FixEndingSlash(fullPath);
		strcat(fullPath,fileList[i].filename.C_String());
		fp=fopen(fullPath, "rb");
		if (fp)
		{
			if (writeFileHash || writeFileData)
			{
				fseek(fp, 0, SEEK_END);
				fileList[i].fileLengthBytes = ftell(fp);
				fseek(fp, 0, SEEK_SET);
				if (writeFileHash)
				{
					if (writeFileData)
					{
						// Hash + data so offset the data by HASH_LENGTH
						fileList[i].data=(char*) rakMalloc_Ex( fileList[i].fileLengthBytes+HASH_LENGTH, __FILE__, __LINE__ );
						fread(fileList[i].data+HASH_LENGTH, fileList[i].fileLengthBytes, 1, fp);
//						sha1.Reset();
//						sha1.Update((unsigned char*)fileList[i].data+HASH_LENGTH, fileList[i].fileLength);
//						sha1.Final();
						unsigned int hash = SuperFastHash(fileList[i].data+HASH_LENGTH, fileList[i].fileLengthBytes);
						if (RakNet::BitStream::DoEndianSwap())
							RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash, sizeof(hash));
//						memcpy(fileList[i].data, sha1.GetHash(), HASH_LENGTH);
						memcpy(fileList[i].data, &hash, HASH_LENGTH);
					}
					else
					{
						// Hash only
						fileList[i].dataLengthBytes=HASH_LENGTH;
						if (fileList[i].fileLengthBytes < HASH_LENGTH)
							fileList[i].data=(char*) rakMalloc_Ex( HASH_LENGTH, __FILE__, __LINE__ );
						else
							fileList[i].data=(char*) rakMalloc_Ex( fileList[i].fileLengthBytes, __FILE__, __LINE__ );
						fread(fileList[i].data, fileList[i].fileLengthBytes, 1, fp);
				//		sha1.Reset();
				//		sha1.Update((unsigned char*)fileList[i].data, fileList[i].fileLength);
				//		sha1.Final();
						unsigned int hash = SuperFastHash(fileList[i].data, fileList[i].fileLengthBytes);
						if (RakNet::BitStream::DoEndianSwap())
							RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash, sizeof(hash));
						// memcpy(fileList[i].data, sha1.GetHash(), HASH_LENGTH);
						memcpy(fileList[i].data, &hash, HASH_LENGTH);
					}
				}
				else
				{
					// Data only
					fileList[i].dataLengthBytes=fileList[i].fileLengthBytes;
					fileList[i].data=(char*) rakMalloc_Ex( fileList[i].fileLengthBytes, __FILE__, __LINE__ );
					fread(fileList[i].data, fileList[i].fileLengthBytes, 1, fp);
				}

				fclose(fp);
				i++;
			}
			else
			{
				fileList[i].data=0;
				fileList[i].dataLengthBytes=0;
			}
		}
		else
		{
			if (removeUnknownFiles)
			{
				fileList.RemoveAtIndex(i);
			}
			else
				i++;			
		}
	}
}
Example #22
0
void FileList::AddFilesFromDirectory(const char *applicationDirectory, const char *subDirectory, bool writeHash, bool writeData, bool recursive, FileListNodeContext context)
{
	DataStructures::Queue<char*> dirList;
	char root[260];
	char fullPath[520];
	_finddata_t fileInfo;
	intptr_t dir;
	FILE *fp;
	char *dirSoFar, *fileData;
	dirSoFar=(char*) rakMalloc_Ex( 520, __FILE__, __LINE__ );

	if (applicationDirectory)
		strcpy(root, applicationDirectory);
	else
		root[0]=0;

	int rootLen=(int)strlen(root);
	if (rootLen)
	{
		strcpy(dirSoFar, root);
		if (FixEndingSlash(dirSoFar))
			rootLen++;
	}
	else
		dirSoFar[0]=0;
	
	if (subDirectory)
	{
		strcat(dirSoFar, subDirectory);
		FixEndingSlash(dirSoFar);
	}
	if (callback)
		callback->OnAddFilesFromDirectoryStarted(this, dirSoFar);
	// RAKNET_DEBUG_PRINTF("Adding files from directory %s\n",dirSoFar);
	dirList.Push(dirSoFar, __FILE__, __LINE__ );
	while (dirList.Size())
	{
		dirSoFar=dirList.Pop();
		strcpy(fullPath, dirSoFar);
		// Changed from *.* to * for Linux compatibility
		strcat(fullPath, "*");


                dir=_findfirst(fullPath, &fileInfo );
		if (dir==-1)
		{
			_findclose(dir);
			rakFree_Ex(dirSoFar, __FILE__, __LINE__ );
			unsigned i;
			for (i=0; i < dirList.Size(); i++)
				rakFree_Ex(dirList[i], __FILE__, __LINE__ );
			return;
		}

//		RAKNET_DEBUG_PRINTF("Adding %s. %i remaining.\n", fullPath, dirList.Size());
		if (callback)
			callback->OnDirectory(this, fullPath, dirList.Size());

                do
		{
                    // no guarantee these entries are first...
                    if (strcmp("." , fileInfo.name) == 0 ||
                        strcmp("..", fileInfo.name) == 0)
                    {
                        continue;
                    }
                    
			if ((fileInfo.attrib & (_A_HIDDEN | _A_SUBDIR | _A_SYSTEM))==0)
			{
				strcpy(fullPath, dirSoFar);
				strcat(fullPath, fileInfo.name);
				fileData=0;

				if (callback)
					callback->OnFile(this, dirSoFar, fileInfo.name, fileInfo.size);

				if (writeData && writeHash)
				{
					fileData= (char*) rakMalloc_Ex( fileInfo.size+HASH_LENGTH, __FILE__, __LINE__ );
					fp = fopen(fullPath, "rb");
					fread(fileData+HASH_LENGTH, fileInfo.size, 1, fp);
					fclose(fp);

					unsigned int hash = SuperFastHash(fileData+HASH_LENGTH, fileInfo.size);
					if (RakNet::BitStream::DoEndianSwap())
						RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash, sizeof(hash));
					memcpy(fileData, &hash, HASH_LENGTH);

//					sha1.Reset();
//					sha1.Update( ( unsigned char* ) fileData+HASH_LENGTH, fileInfo.size );
//					sha1.Final();
//					memcpy(fileData, sha1.GetHash(), HASH_LENGTH);
					// File data and hash
					AddFile((const char*)fullPath+rootLen, fullPath, fileData, fileInfo.size+HASH_LENGTH, fileInfo.size, context);
				}
				else if (writeHash)
				{
//					sha1.Reset();
//					sha1.HashFile((char*)fullPath);
//					sha1.Final();

					unsigned int hash = SuperFastHashFile(fullPath);
					if (RakNet::BitStream::DoEndianSwap())
						RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash, sizeof(hash));

					// Hash only
				//	AddFile((const char*)fullPath+rootLen, (const char*)sha1.GetHash(), HASH_LENGTH, fileInfo.size, context);
					AddFile((const char*)fullPath+rootLen, fullPath, (const char*)&hash, HASH_LENGTH, fileInfo.size, context);
				}
				else if (writeData)
				{
					fileData= (char*) rakMalloc_Ex( fileInfo.size, __FILE__, __LINE__ );
					fp = fopen(fullPath, "rb");
					fread(fileData, fileInfo.size, 1, fp);
					fclose(fp);

					// File data only
					AddFile(fullPath+rootLen, fullPath, fileData, fileInfo.size, fileInfo.size, context);
				}
				else
				{
					// Just the filename
					AddFile(fullPath+rootLen, fullPath, 0, 0, fileInfo.size, context);
				}

				if (fileData)
					rakFree_Ex(fileData, __FILE__, __LINE__ );
			}
			else if ((fileInfo.attrib & _A_SUBDIR) && (fileInfo.attrib & (_A_HIDDEN | _A_SYSTEM))==0 && recursive)
			{
				char *newDir=(char*) rakMalloc_Ex( 520, __FILE__, __LINE__ );
				strcpy(newDir, dirSoFar);
				strcat(newDir, fileInfo.name);
				strcat(newDir, "/");
				dirList.Push(newDir, __FILE__, __LINE__ );
			}

		} while (_findnext(dir, &fileInfo ) != -1);

		_findclose(dir);
		rakFree_Ex(dirSoFar, __FILE__, __LINE__ );
	}
}
FullyConnectedMesh::~FullyConnectedMesh()
{
	if (pw)
		rakFree_Ex(pw, __FILE__, __LINE__ );
}
Example #24
0
bool WriteFileWithDirectories( const char *path, char *data, unsigned dataLength )
{
    int index;
    FILE *fp;
    char *pathCopy;
    int res;

    if ( path == 0 || path[ 0 ] == 0 )
        return false;

    pathCopy = (char*) rakMalloc_Ex( strlen( path ) + 1, _FILE_AND_LINE_ );

    strcpy( pathCopy, path );

    // Ignore first / if there is one
    if (pathCopy[0])
    {
        index = 1;
        while ( pathCopy[ index ] )
        {
            if ( pathCopy[ index ] == '/' || pathCopy[ index ] == '\\')
            {
                pathCopy[ index ] = 0;

#ifdef _WIN32
#pragma warning( disable : 4966 ) // mkdir declared deprecated by Microsoft in order to make it harder to be cross platform.  I don't agree it's deprecated.
                res = mkdir( pathCopy );
#else

                res = mkdir( pathCopy, 0744 );
#endif
                if (res<0 && errno!=EEXIST && errno!=EACCES)
                {
                    rakFree_Ex(pathCopy, _FILE_AND_LINE_ );
                    return false;
                }

                pathCopy[ index ] = '/';
            }

            index++;
        }
    }

    if (data)
    {
        fp = fopen( path, "wb" );

        if ( fp == 0 )
        {
            rakFree_Ex(pathCopy, _FILE_AND_LINE_ );
            return false;
        }

        fwrite( data, 1, dataLength, fp );

        fclose( fp );
    }
    else
    {
#ifdef _WIN32
#pragma warning( disable : 4966 ) // mkdir declared deprecated by Microsoft in order to make it harder to be cross platform.  I don't agree it's deprecated.
        res = mkdir( pathCopy );
#else
        res = mkdir( pathCopy, 0744 );
#endif

        if (res<0 && errno!=EEXIST)
        {
            rakFree_Ex(pathCopy, _FILE_AND_LINE_ );
            return false;
        }
    }

    rakFree_Ex(pathCopy, _FILE_AND_LINE_ );

    return true;
}
Example #25
0
ConsoleServer::~ConsoleServer()
{
	if (prompt)
		rakFree_Ex(prompt, __FILE__, __LINE__);
}
Example #26
0
void RNS2_NativeClient::DeallocSP(RNS2_SendParameters_NativeClient *sp)
{
	rakFree_Ex(sp->data, _FILE_AND_LINE_);
	RakNet::OP_DELETE(sp, _FILE_AND_LINE_);
}
Example #27
0
void RakNetTransport2::DeallocatePacket( Packet *packet )
{
	rakFree_Ex(packet->data, __FILE__, __LINE__ );
	RakNet::OP_DELETE(packet, __FILE__, __LINE__ );
}
void FileListTransfer::OnReferencePush(Packet *packet, bool fullFile)
{
	// fullFile is always true for TCP, since TCP does not return SPLIT_PACKET_NOTIFICATION

	RakNet::BitStream refPushAck;
	refPushAck.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH_ACK);
	SendUnified(&refPushAck,HIGH_PRIORITY, RELIABLE, 0, packet->systemAddress, false);

	FileListTransferCBInterface::OnFileStruct onFileStruct;
	RakNet::BitStream inBitStream(packet->data, packet->length, false);
	inBitStream.IgnoreBits(8);

	unsigned int partCount=0;
	unsigned int partTotal=1;
	unsigned int partLength=0;
	onFileStruct.fileData=0;
	if (fullFile==false)
	{
		// Disable endian swapping on reading this, as it's generated locally in ReliabilityLayer.cpp
		inBitStream.ReadBits( (unsigned char* ) &partCount, BYTES_TO_BITS(sizeof(partCount)), true );
		inBitStream.ReadBits( (unsigned char* ) &partTotal, BYTES_TO_BITS(sizeof(partTotal)), true );
		inBitStream.ReadBits( (unsigned char* ) &partLength, BYTES_TO_BITS(sizeof(partLength)), true );
		inBitStream.IgnoreBits(8);
		// The header is appended to every chunk, which we continue to read after this statement block
	}

	inBitStream.Read(onFileStruct.context);
	inBitStream.Read(onFileStruct.setID);
	FileListReceiver *fileListReceiver;
	if (fileListReceivers.Has(onFileStruct.setID)==false)
	{
		return;
	}
	fileListReceiver=fileListReceivers.Get(onFileStruct.setID);
	if (fileListReceiver->allowedSender!=packet->systemAddress)
	{
#ifdef _DEBUG
		RakAssert(0);
#endif
		return;
	}

#ifdef _DEBUG
	RakAssert(fileListReceiver->gotSetHeader==true);
#endif

	if (stringCompressor->DecodeString(onFileStruct.fileName, 512, &inBitStream)==false)
	{
#ifdef _DEBUG
		RakAssert(0);
#endif
		return;
	}

	inBitStream.ReadCompressed(onFileStruct.fileIndex);
	inBitStream.ReadCompressed(onFileStruct.finalDataLength);
	unsigned int offset;
	unsigned int chunkLength;
	inBitStream.ReadCompressed(offset);
	inBitStream.ReadCompressed(chunkLength);
//	if (chunkLength==0)
//		return;
	bool lastChunk;
	inBitStream.Read(lastChunk);
	bool finished = lastChunk && fullFile;

	if (fullFile==false)
		fileListReceiver->partLength=partLength;

	FLR_MemoryBlock mb;
	if (fileListReceiver->pushedFiles.Has(onFileStruct.fileIndex)==false)
	{
		if (chunkLength > 1000000000 || onFileStruct.finalDataLength > 1000000000)
		{
			RakAssert("FileListTransfer::OnReferencePush: file too large" && 0);
			return;
		}

		mb.allocatedLength=onFileStruct.finalDataLength;
		mb.block = (char*) rakMalloc_Ex(onFileStruct.finalDataLength, __FILE__, __LINE__);
		if (mb.block==0)
		{
			notifyOutOfMemory(__FILE__, __LINE__);
			return;
		}

		fileListReceiver->pushedFiles.SetNew(onFileStruct.fileIndex, mb);
	}
	else
		mb=fileListReceiver->pushedFiles.Get(onFileStruct.fileIndex);

	if (offset+chunkLength > mb.allocatedLength)
	{
		// Overrun
		RakAssert("FileListTransfer::OnReferencePush: Write would overrun allocated block" && 0);
		return;
	}

	// Read header uncompressed so the data is byte aligned, for speed
	onFileStruct.compressedTransmissionLength=(unsigned int) onFileStruct.finalDataLength;

	unsigned int unreadBits = inBitStream.GetNumberOfUnreadBits();
	unsigned int unreadBytes = BITS_TO_BYTES(unreadBits);
	unsigned int amountToRead;
	if (fullFile)
		amountToRead=chunkLength;
	else
		amountToRead=unreadBytes;

	inBitStream.AlignReadToByteBoundary();
	if (fullFile || (rakPeerInterface->GetSplitMessageProgressInterval() != 0 && (int)partCount==rakPeerInterface->GetSplitMessageProgressInterval()))
	{
		inBitStream.Read(mb.block+offset, amountToRead);
	}

	onFileStruct.setCount=fileListReceiver->setCount;
	onFileStruct.setTotalCompressedTransmissionLength=fileListReceiver->setTotalCompressedTransmissionLength;
	onFileStruct.setTotalFinalLength=fileListReceiver->setTotalFinalLength;
	onFileStruct.fileData=mb.block;

	if (finished)
	{
		if (fileListReceiver->downloadHandler->OnFile(&onFileStruct))
			rakFree_Ex(onFileStruct.fileData, __FILE__, __LINE__ );
		fileListReceiver->pushedFiles.Delete(onFileStruct.fileIndex);

		fileListReceiver->filesReceived++;

		// If this set is done, free the memory for it.
		if ((int) fileListReceiver->setCount==fileListReceiver->filesReceived)
		{
			if (fileListReceiver->downloadHandler->OnDownloadComplete()==false)
			{
				fileListReceiver->downloadHandler->OnDereference();
				fileListReceivers.Delete(onFileStruct.setID);
				if (fileListReceiver->deleteDownloadHandler)
					RakNet::OP_DELETE(fileListReceiver->downloadHandler, __FILE__, __LINE__);
				RakNet::OP_DELETE(fileListReceiver, __FILE__, __LINE__);
			}
		}
	}
	else
	{
		unsigned int totalNotifications;
		unsigned int currentNotificationIndex;
		unsigned int unreadBytes;

		if (rakPeerInterface==0 || rakPeerInterface->GetSplitMessageProgressInterval()==0)
		{
			totalNotifications = onFileStruct.finalDataLength / chunkLength + 1;
			currentNotificationIndex = offset / chunkLength;
			unreadBytes = mb.allocatedLength - ((offset+1)*chunkLength);
		}
		else
		{
			totalNotifications = onFileStruct.finalDataLength / fileListReceiver->partLength + 1;
			if (fullFile==false)
				currentNotificationIndex = (offset+partCount*fileListReceiver->partLength) / fileListReceiver->partLength ;
			else
				currentNotificationIndex = (offset+chunkLength) / fileListReceiver->partLength ;
			unreadBytes = onFileStruct.finalDataLength - ((currentNotificationIndex+1) * fileListReceiver->partLength);
		}
		fileListReceiver->downloadHandler->OnFileProgress(&onFileStruct, currentNotificationIndex, totalNotifications, unreadBytes, mb.block);
	}

	return;
}
FileListReceiver::~FileListReceiver() {
	unsigned int i=0;
	for (i=0; i < pushedFiles.Size(); i++)
		rakFree_Ex(pushedFiles[i].block, __FILE__, __LINE__ );
}
bool FileListTransfer::DecodeFile(Packet *packet, bool fullFile)
{
	FileListTransferCBInterface::OnFileStruct onFileStruct;
	RakNet::BitStream inBitStream(packet->data, packet->length, false);
	inBitStream.IgnoreBits(8);

	unsigned int partCount=0;
	unsigned int partTotal=0;
	unsigned int partLength=0;
	onFileStruct.fileData=0;
	if (fullFile==false)
	{
		// Disable endian swapping on reading this, as it's generated locally in ReliabilityLayer.cpp
		inBitStream.ReadBits( (unsigned char* ) &partCount, BYTES_TO_BITS(sizeof(partCount)), true );
		inBitStream.ReadBits( (unsigned char* ) &partTotal, BYTES_TO_BITS(sizeof(partTotal)), true );
		inBitStream.ReadBits( (unsigned char* ) &partLength, BYTES_TO_BITS(sizeof(partLength)), true );
		inBitStream.IgnoreBits(8);
		// The header is appended to every chunk, which we continue to read after this statement block
	}
	inBitStream.Read(onFileStruct.context);
	inBitStream.Read(onFileStruct.setID);
	FileListReceiver *fileListReceiver;
	if (fileListReceivers.Has(onFileStruct.setID)==false)
	{
		return false;
	}
	fileListReceiver=fileListReceivers.Get(onFileStruct.setID);
	if (fileListReceiver->allowedSender!=packet->systemAddress)
	{
#ifdef _DEBUG
		RakAssert(0);
#endif
		return false;
	}

#ifdef _DEBUG
	RakAssert(fileListReceiver->gotSetHeader==true);
#endif

	if (stringCompressor->DecodeString(onFileStruct.fileName, 512, &inBitStream)==false)
	{
#ifdef _DEBUG
		RakAssert(0);
#endif
		return false;
	}

	inBitStream.ReadCompressed(onFileStruct.fileIndex);
	inBitStream.ReadCompressed(onFileStruct.finalDataLength);

	// Read header uncompressed so the data is byte aligned, for speed
	onFileStruct.compressedTransmissionLength=(unsigned int) onFileStruct.finalDataLength;

	if (fullFile)
	{
		// Support SendLists
		inBitStream.AlignReadToByteBoundary();

		onFileStruct.fileData = (char*) rakMalloc_Ex( (size_t) onFileStruct.finalDataLength, __FILE__, __LINE__ );

		inBitStream.Read((char*)onFileStruct.fileData, onFileStruct.finalDataLength);
	}
	

	onFileStruct.setCount=fileListReceiver->setCount;
	onFileStruct.setTotalCompressedTransmissionLength=fileListReceiver->setTotalCompressedTransmissionLength;
	onFileStruct.setTotalFinalLength=fileListReceiver->setTotalFinalLength;

	// User callback for this file.
	if (fullFile)
	{
		if (fileListReceiver->downloadHandler->OnFile(&onFileStruct))
			rakFree_Ex(onFileStruct.fileData, __FILE__, __LINE__ );

		fileListReceiver->filesReceived++;

		// If this set is done, free the memory for it.
		if ((int) fileListReceiver->setCount==fileListReceiver->filesReceived)
		{
			if (fileListReceiver->downloadHandler->OnDownloadComplete()==false)
			{
				fileListReceiver->downloadHandler->OnDereference();
				if (fileListReceiver->deleteDownloadHandler)
					RakNet::OP_DELETE(fileListReceiver->downloadHandler, __FILE__, __LINE__);
				fileListReceivers.Delete(onFileStruct.setID);
				RakNet::OP_DELETE(fileListReceiver, __FILE__, __LINE__);
			}
		}

	}
	else
	{
		inBitStream.AlignReadToByteBoundary();

		bool usedAlloca=false;
		char *firstDataChunk;
		unsigned int unreadBits = inBitStream.GetNumberOfUnreadBits();
		unsigned int unreadBytes = BITS_TO_BYTES(unreadBits);
		if (unreadBytes>0)
		{
#if !defined(_XBOX) && !defined(_X360)
			if (unreadBits < MAX_ALLOCA_STACK_ALLOCATION)
			{
				firstDataChunk = ( char* ) alloca( unreadBytes );
				usedAlloca=true;
			}
			else
#endif
				firstDataChunk = (char*) rakMalloc_Ex( unreadBytes, __FILE__, __LINE__ );

			// Read partLength bytes, reported to OnFileProgress

			inBitStream.Read((char*)firstDataChunk, unreadBytes );

		}
		else
			firstDataChunk=0;

		fileListReceiver->downloadHandler->OnFileProgress(&onFileStruct, partCount, partTotal, unreadBytes, firstDataChunk);

		if (usedAlloca==false)
			RakNet::OP_DELETE_ARRAY(firstDataChunk, __FILE__, __LINE__);
	}

	return true;
}