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__); }
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__); }
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; }
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__ ); } }
void RakVoice::Deinit(void) { // check pointer before free if (bufferedOutput) { rakFree_Ex(bufferedOutput, __FILE__, __LINE__ ); bufferedOutput = 0; CloseAllChannels(); } }
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(); }
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); } }
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; }
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; }
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; }
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++; } } }
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__ ); }
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; }
ConsoleServer::~ConsoleServer() { if (prompt) rakFree_Ex(prompt, __FILE__, __LINE__); }
void RNS2_NativeClient::DeallocSP(RNS2_SendParameters_NativeClient *sp) { rakFree_Ex(sp->data, _FILE_AND_LINE_); RakNet::OP_DELETE(sp, _FILE_AND_LINE_); }
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; }