⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cxferthread.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	c2pstr(s);
	pstrcpy(fs->name, (uchar *)s);
	hpb.ioParam.ioCompletion = NIL;
	hpb.ioParam.ioNamePtr = NIL;
	hpb.ioParam.ioVRefNum = fs->vRefNum;
	hpb.volumeParam.ioVolIndex = 0;
	if(!PBHGetVInfoSync(&hpb))
	{
		if(hpb.volumeParam.ioVFrBlk * hpb.volumeParam.ioVAlBlkSiz
				<= xrf->xi.bytesTotal)
		{
			CStatusPane::GetStatusPane()->AddStatus(0,
				"Not enough disk space to receive file!");
			return FALSE;
		}
		return TRUE;
	}
	return FALSE;
	
#elif	PGP_WIN32

	char savePath[MAX_PATH + 1] = {0x00};
	//char tempPath[MAX_PATH + 1] = {0x00};
	
	// get the default save directory
	if(gPGFOpts.fopt.recvDir[0])
	{
		strcpy(savePath, gPGFOpts.fopt.recvDir);
		
		if(!SetCurrentDirectory(savePath) )
		{
			// need to create it...
		}
	}
	else
	{
		char root[MAX_PATH];
		
		GetCurrentDirectory(sizeof(root), root);

		root[3] = 0x00;
		
		strcpy(savePath,root);  
	}
		
	// parse the platform independant directory
	char* cp = (char*)pathname;
	
	
	while(len > 0)
	{
		char* check = NULL;
		char thisDir[256];
		int dirLength;
		int i;
		
		len -= *cp + 1;
		
		check = cp + 1;
		
		// make sure the directory name is win-friendly
		// chars not allowed in win filenames ->  \ / : * ? " < > |
		
		for(i = 0; i < *cp ; i++, check++)
		{
			if(	*check == '\\' 	|| 
				*check == '/' 	|| 
				*check == ':' 	||
				*check == '*' 	||
				*check == '?' 	||
				*check == '\"' 	|| 
				*check == '<' 	||
				*check == '>' 	||
				*check == '|' 	)
			{
				*check = '-';	// no colons in dirnames
			}
		}
			
		dirLength = *cp;
				
		memcpy(thisDir, cp + 1, dirLength);
		*(thisDir + dirLength) = 0x00;
				
		strcat(savePath, "\\");
		strcat(savePath, thisDir);
		
		if( !SetCurrentDirectory(savePath) )
		{
			// doesn't exist, so create it
			CreateDirectory(savePath, NULL);
		}
		
		cp += *cp + 1;
	}
	
	// tuck away path
	strcpy((char*)xrf->path, savePath);
	
	// parse the platform independant filename
	char filename[256];
	
	len = strlen((char *)p);
	strncpy(filename, (char *)p, 255);
	
	
	cp = filename;
	
	for(;*cp;cp++)
	{
		if(	*cp == '\\' || 
			*cp == '/' 	|| 
			*cp == ':' 	||
			*cp == '*' 	||
			*cp == '?' 	||
			*cp == '\"' || 
			*cp == '<' 	||
			*cp == '>' 	||
			*cp == '|' 	)
		{
			*cp = '-';	// no colons in filenames
		}
	}
	
	if(filename[0] == '.')
	{
		filename[0] = '-';		// no periods in first letter on windows
	}
	
	strcat(savePath, "\\");
	strcat(savePath, filename);
		
	// tuck away path and filename
	strcpy((char*)xrf->xi.filepath, savePath);
	
	xrf->xi.filename = strrchr((char*)xrf->xi.filepath, '\\') + 1;
	
	// check the current disk for space
	
	DWORD sectorsPerCluster; 
	DWORD bytesPerSector;	
	DWORD numberOfFreeClusters;
	DWORD totalNumberOfClusters;	 

	GetDiskFreeSpace( 	NULL, // use current working root
						&sectorsPerCluster,
						&bytesPerSector,	
						&numberOfFreeClusters,
						&totalNumberOfClusters);
						
	DWORD freespace = sectorsPerCluster * bytesPerSector * numberOfFreeClusters;
	
	if(freespace <= xrf->xi.bytesTotal)
	{
		/*CStatusPane::GetStatusPane()->AddStatus(0,
			"Not enough disk space to receive file!");*/
			
		MessageBox(	NULL, 
					"Not enough disk space to receive file!", 
					filename, 
					MB_OK|MB_ICONERROR);
			
		return FALSE;
	}
	
	return TRUE;
	
#endif
}

void
CXferThread::GetFileSize(XSendFile *xsf, void *file)
{
#ifdef	PGP_MACINTOSH
	XferFileSpec *xspec = (XferFileSpec *)file;
	Str255 rootPath, filePath;
	uchar *p;
	short pathlen, dirlen;
	
	if((xspec->rootDir != xspec->fs.parID) || (xspec->rootVol != xspec->fs.vRefNum))
	{
		rootPath[0] = filePath[0] = 0;
		pgp_GetFullPathname(xspec->rootVol, xspec->rootDir, rootPath);
		pgp_GetFullPathname(xspec->fs.vRefNum, xspec->fs.parID, filePath);
		// cut off the root part of the directory and record the partial pathname
		pstrcpy(xsf->path, "\p:");	// add leading colon which will be replaced by sublen
		dirlen = pstrlen(rootPath);
		pathlen = pstrlen(filePath) - dirlen;
		memcpy(&xsf->path[2], &filePath[dirlen+1], pstrlen(filePath) - dirlen);
		xsf->path[0] = pathlen+1;
		pathlen = --xsf->path[0];	// cut off the trailing colon
		for(p=&xsf->path[pathlen],dirlen=0;p>xsf->path;--p)
		{
			if(*p == ':')
			{
				*p = dirlen;
				dirlen = 0;
			}
			else
				dirlen++;
		}
	}
	pgp_memcpy(&xsf->xi.file, &xspec->fs, sizeof(FSSpec));
	xsf->xi.sendAs = SendFileAs(&xsf->xi.file, mPFWindow->GetControlThread()->GetRemoteSystemType());
	CheckSendMethod(this, &xsf->xi);
#elif	PGP_WIN32
	XferFileSpec *xspec = (XferFileSpec *)file;
	//char* path = NULL;
	int dirlen = 0;
	int pathlen = 0;
	char* cp = NULL;
	
	strcpy(xsf->xi.filepath, xspec->path);
	xsf->xi.filename = strrchr(xsf->xi.filepath, '\\') + 1;
	
	*(xsf->path) = 0x00;
	
	if(xspec->root)
	{
		//placeholders for length bytes
		strcpy((char*)xsf->path,".\\");
		
		strcat((char*) (xsf->path + 2), xspec->root);
		
		*(strrchr((char*)xsf->path, '\\')) = 0x00;
		
		// remember total length of path...
		// add one for the extra 'total length byte' 
		pathlen = strlen((char*) (xsf->path + 2)) + 1;
		
		// record the length byte
		*(xsf->path) = pathlen;
													  
		for(cp = (char*)(xsf->path + pathlen), dirlen = 0;cp > (char*)xsf->path; --cp)
		{ 
			if(*cp == '\\')
			{
				*cp = dirlen;
				dirlen = 0;
			}
			else
			{
				dirlen++;
			}
		}
	}
	
	xsf->xi.sendAs = 1; // BINARY
	
	HANDLE handle;
	WIN32_FIND_DATA wfd;
	
	handle = FindFirstFile( xspec->path, &wfd);
	
	if( INVALID_HANDLE_VALUE != handle)
	{
		xsf->xi.bytesTotal = wfd.nFileSizeLow;
		FindClose(handle);
	}
	else
	{
		xsf->xi.bytesTotal = 0;
	}
	
#endif
}

void
CXferThread::AbortSend(uchar localStreamID, ulong *salt)
{
	uchar *p, *e;
	
	// Send an _xst_AbortStream to abort the receiver for this stream
	e = p = (uchar *)safe_malloc(10);	pgpAssert(p);
	*e++ = _xst_AbortStream;
	*e++ = localStreamID;
	pgp_memcpy( e, salt, XFERSALTCHECKSIZE );	e += XFERSALTCHECKSIZE;
	mOutQueue->Send(_mt_filePacket, p, e-p, 1);
}

void
CXferThread::AbortReceive(uchar remoteStreamID, ulong *salt)
{
	uchar *p, *e;
	
	// Send an _xst_RemoteAbortStream to abort the sender for this stream
	e = p = (uchar *)safe_malloc(10);	pgpAssert(p);
	*e++ = _xst_RemoteAbortStream;
	*e++ = remoteStreamID;
	pgp_memcpy( e, salt, XFERSALTCHECKSIZE );	e += XFERSALTCHECKSIZE;
	mOutQueue->Send(_mt_filePacket, p, e-p, 1);
}

CMessageQueue *
CXferThread::GetQueue()
{
	return mInQueue;
}

Boolean
CXferThread::HashPartialFile(XferInfo *xi, SHA *hash, uchar *hashfinal)
{
	LThread *fileThread;
	SHA *cloneHash;
	long fileThreadResult, pull, pullSize, bDone=0;
	Boolean done=FALSE, aborted=FALSE;
	uchar *data;
	
	// Given a file, this function loads it in through the normal pipe
	// mechanism and hashes it to a certain position in order to match
	// the contents on each side.  It is used by the sender to confirm
	// the hash received from the receiver, and by the receiver when it
	// believes it is receiving the completion of a previous partial file.
	
#ifdef PGP_MACINTOSH
	xi->sendAs = SendFileAs(&xi->file, mPFWindow->GetControlThread()->GetRemoteSystemType());
#endif
	xi->pipe = new CPipe(STDPIPESIZE, STDPIPEEXTRA);
	fileThread = new CFileSendPipe(xi, TRUE, (void **)&fileThreadResult);
	xi->pipe->SetPusher(fileThread);
	xi->pipe->SetPuller(this);
	fileThread->Resume();
	while(!done && !aborted)
	{
		pullSize = pull = 1024;
		if(xi->bytesDone)
			if(pull+bDone>xi->bytesDone)
			{
				pull = xi->bytesDone-bDone;
				done = TRUE;
			}
		xi->pipe->DoStartPipePull(&pull, (void **)&data, 0);
		if(pull<pullSize)
			done = TRUE;
		if(pull)
		{
			bDone += pull;
			hash->Update(data, pull);
		}
		xi->pipe->DoEndPipePull(-1);
		(Yield)();
		aborted = xi->pipe->DoPipeAborted();
	}
	if(!aborted)
		xi->pipe->DoAckEndPipe();
	delete xi->pipe;
	xi->pipe = NIL;
	if(!xi->bytesDone)
		xi->bytesDone = bDone;
	if(!aborted)
	{
		cloneHash = hash->Clone();
		cloneHash->Final(hashfinal);
		delete cloneHash;
		return TRUE;
	}
	else
		xi->fatalErr = 0;
	return FALSE;
}

long
CXferThread::GetNextSendPacket(long maxSize)
{
	Boolean done = FALSE, aborted = FALSE;
	long pullSize, pull, sentBytes=0;
	uchar *data, *p, *e, str[80];

	// Activating the following mutex causes a deadlock that is
	// difficult to eliminate.  Using these mutexes is probably
	// desirable however in the long run.  The deadlock scenario:
	//  CPFPacketsOut:	mOutQueue->mFreeSpace is full
	//					calls this func which grabs mSendMutex
	//	CXferThread:	already has mSendMutex
	//					Has called OpenStream to send a packet
	//
	//	This scenario also occurs with a number of the abort
	//	packets.
	//	Eliminating the mutex eliminates the deadlock and
	//	I don't believe it will result in actual problems.
	
	//mSendMutex->Wait();
	if(mSending && mSending->openAckd && mSending->xi.pipe)
	{
		pullSize = pull = minl(maxSize, MAXXFERPACKETSIZE);
		mSending->xi.pipe->DoStartPipePull(&pull, (void **)&data, 0);
		if(pull<pullSize)
			done=TRUE;
		if(pull)
		{
			mSending->xi.bytesDone += pull;
			mSending->hash->Update(data, pull);
			
			mSending->xi.lastTime=pgp_getticks();
			p=e=(uchar *)safe_malloc(pull+2);
			*e++ = _xst_DataStream;
			*e++ = mSending->localStreamID;
			pgp_memcpy(e, data, pull);	e+=pull;
			mPacketThread->Send(_mt_filePacket, p, e-p);
			sentBytes += e-p;
#ifdef	DEBUGXFERLOG
			DebugLog("Send: _xst_DataStream: len %ld", (long)(e-p-2));
#endif
			safe_free(p);
		}
		mSending->xi.pipe->DoEndPipePull(-1);
		aborted = mSending->xi.pipe->DoPipeAborted();
		if(done && !aborted)
		{
			p=e=(uchar *)safe_malloc(6 + SHS_DIGESTSIZE);
			*e++ = _xst_EndStream;
			*e++ = mSending->localStreamID;
			pgp_memcpy( e, &mSending->salt[0], XFERSALTCHECKSIZE );
			e += XFERSALTCHECKSIZE;
			mSending->hash->Final(e);			e+=SHS_DIGESTSIZE;
			mPacketThread->Send(_mt_filePacket, p, e-p);
			sentBytes += e-p;
			safe_free(p);
#ifdef	DEBUGXFERLOG
			DebugLog("Send: _xst_EndStream");
#endif
			mSending->xi.pipe->DoAckEndPipe();
			GetFileName(&mSending->xi, str);
			CStatusPane::GetStatusPane()->AddStatus(0,
				"Sent: %s (%ld K).", str, maxl(mSending->xi.bytesTotal / 1024,1L));
			EndSend();
			if(!mOpeningStream)
				CheckForNewStreams();
		}
		if(aborted)
			mInQueue->Send(_mt_abortSend);
	}
	//mSendMutex->Signal();
	return sentBytes;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -