www.pudn.com > FileGuard.zip > KProtectedFileList.cpp


////////////////////////////////////////////////////////////////////// 
//class KProtectedFileList: 
 
#include "StdAfx.h"	      //StdAfx.h is just an empty file in dir FGHook\ . 
#include "HookError.h" 
#include "Comdef.h" 
#include "..\hookshr\KProtectedFileList.h" 
 
WORD defProtectionType=PT_DELETE | PT_WRITE;	 
 
char KProtectedFileList::driveList[(MAX_DRIVE+1)*2]; 
 
KProtectedFileList::KProtectedFileList() 
{ 
	bIsDelOn=bIsReadOn=bIsWriteOn=bIsHideOn=0; 
	bDelBak=bWriteBak=TRUE; 
 
	 
	int i; 
	//Add empty head node: 
	for(i=0; i<=MAX_DRIVE; i++) 
	{ 
		KProtectedFileList::driveList[2*i]=i; 
		KProtectedFileList::driveList[2*i+1]=0; 
		m_pHead[i]=&m_headNode[i]; 
		m_pHead[i]->protFile.PF_priority=0;		//make sure it is the first node 
		m_pHead[i]->protFile.PF_pPath=&driveList[2*i]; 
		m_pHead[i]->pNextFile=NULL; 
	} 
 
	m_pFindIndex=NULL; 
} 
 
KProtectedFileList::~KProtectedFileList() 
{ 
	Empty(); 
} 
 
// Function name	: KProtectedFileList::Empty 
// Description	    : Empty the list. 
// Return type		: void  
void KProtectedFileList::Empty() 
{ 
	struct FILE_NODE *pNext, *pIndex; 
	int i; 
	for(i=0; i<=MAX_DRIVE; i++) 
	{ 
		pIndex=m_pHead[i]->pNextFile;		//head node is not to free. 
	 
		while(pIndex!=NULL) 
		{ 
	#ifdef FG_VXD 
			if(pIndex->protFile.PF_fsdPath.ppath) 
				free(pIndex->protFile.PF_fsdPath.ppath); 
	#endif 
			free(pIndex->protFile.PF_pPath); 
			pNext=pIndex->pNextFile; 
			free(pIndex); 
			pIndex=pNext; 
		} 
	 
		m_pHead[i]->pNextFile=NULL;	//list is empty. 
	} 
 
	bIsDelOn=bIsReadOn=bIsWriteOn=bIsHideOn=0; 
} 
 
 
//The parament pBCSPath must be a format one (e.g. after calling FGFormatPath()). 
BOOL KProtectedFileList::Remove(const char *pBCSPath) 
{ 
	struct FILE_NODE *pIndex,*pPrevFile; 
 
	pPrevFile=m_pHead[PathToIndex(pBCSPath)]; 
	pIndex=pPrevFile->pNextFile; 
	 
	while(pIndex!=NULL) 
	{ 
		if(strcmp(pIndex->protFile.PF_pPath,pBCSPath)==0) 
		{ 
			pPrevFile->pNextFile=pIndex->pNextFile; 
			ChangeProtNum(pIndex->protFile.PF_type, 0); 
#ifdef FG_VXD 
			free(pIndex->protFile.PF_fsdPath.ppath); 
#endif 
			free(pIndex->protFile.PF_pPath); 
			free(pIndex); 
			 
			return TRUE; 
		} 
		 
		pPrevFile=pIndex; 
		pIndex=pIndex->pNextFile; 
	} 
	 
	return FALSE; 
} 
		 
/*//parament pBCSPath must be capitalized. 
BOOL KProtectedFileList::IsUnderWriteProtection(char *pBCSPath) 
{ 
	FILE_NODE *node=IsUnderProtection(pBCSPath); 
	if(!(node && node->protFile.PF_type & PT_WRITE)) 
		return FALSE; 
	 
	return TRUE; 
}*/ 
/* 
BOOL KProtectedFileList::IsUnderReadProtection(char *pBCSPath) 
{ 
	FILE_NODE *node=IsUnderProtection(pBCSPath); 
	if(!(node && node->protFile.PF_type & PT_READ)) 
		return FALSE; 
	 
	return TRUE; 
} 
*/ 
 
 
/*// Function name	: KProtectedFileList::IsUnderDeleteProtection 
// Description	    :  
//							determine whether a file path is under protection. 
//							parament pBCSPath must be capitalized. 
//							debug: remove it. 
// Return type		: BOOL  
// Argument         : char *pBCSPath 
BOOL KProtectedFileList::IsUnderDeleteProtection(char *pBCSPath) 
{ 
	FILE_NODE *node=IsUnderProtection(pBCSPath); 
 
	if(!(node && node->protFile.PF_type & PT_DELETE)) 
		return FALSE; 
	 
	return TRUE; 
}*/ 
 
BOOL KProtectedFileList::Add(PROTECTED_FILE *pProtFile) 
{ 
	if(pProtFile==NULL || !strlen(pProtFile->PF_pPath))  return TRUE;  //or FALSE??? 
 
	//if the protection type is NULL, remove the path. 
	if(pProtFile->PF_type==NULL) 
	{ 
		Remove(pProtFile->PF_pPath); 
		return TRUE; 
	} 
 
	//Only use capitalized string. 
	//_strupr(pProtFile->PF_pPath); 
 
	//if the path is already in the list, just change the protection type. 
	FILE_NODE *pFNode; 
	if((pFNode=IsInList(pProtFile->PF_pPath))!=NULL) 
	{ 
		ChangeProtNum(pFNode->protFile.PF_type, pProtFile->PF_type); 
		pFNode->protFile.PF_type=pProtFile->PF_type; 
		return TRUE; 
	} 
	 
	char *pNewPath=(char *)malloc((strlen(pProtFile->PF_pPath)+1)* sizeof(char));	//don't forget to add 1 for the last char NULL. 
	if(!pNewPath) 
	{ 
		ErrorHandler(FG_ERR_NOT_ENOUGH_MEMORY); 
		return FALSE; 
	} 
	struct FILE_NODE *pNewPFile=(struct FILE_NODE *)malloc(sizeof(struct FILE_NODE)); 
	if(!pNewPFile) 
	{ 
		ErrorHandler(FG_ERR_NOT_ENOUGH_MEMORY); 
		return FALSE; 
	} 
	 
	//The path string in pProtFile may not awalys exits before destroy pNewPFile.  
	strcpy(pNewPath,pProtFile->PF_pPath); 
	pNewPFile->protFile.PF_pPath=pNewPath; 
	pNewPFile->protFile.PF_type=pProtFile->PF_type; 
	pNewPFile->protFile.PF_priority=GetPriority(pNewPFile->protFile.PF_pPath); 
#ifdef	FG_VXD 
	if(!BCSToFSDPath(&(pNewPFile->protFile.PF_fsdPath), pNewPFile->protFile.PF_pPath)) 
		ErrorHandler(FG_ERR_NOT_ENOUGH_MEMORY); 
#ifdef	DEBUG 
	//dout<<"FSD path:"<protFile.PF_fsdPath.ppath->pp_totalLength<protFile.PF_fsdPath.ppath->pp_prefixLength<protFile.PF_fsdPath.flag<protFile.PF_fsdPath.ppath), pNewPFile->protFile.PF_fsdPath.ppath->pp_totalLength); 
#endif 
#endif 
	pNewPFile->pNextFile=NULL; 
 
	//The position of a record in list is determined by PF_priority. 
#ifdef FG_VXD 
	FILE_NODE *pIndex=m_pHead[GetSafeEntry(pNewPFile->protFile.PF_fsdPath.drive)];	 
#else 
	FILE_NODE *pIndex=m_pHead[PathToIndex(pNewPFile->protFile.PF_pPath)]; 
#endif 
	while(pIndex->pNextFile!=NULL && pIndex->pNextFile->protFile.PF_priority < pNewPFile->protFile.PF_priority) 
		pIndex=pIndex->pNextFile; 
	pNewPFile->pNextFile=pIndex->pNextFile;				//insert after pIndex. 
	pIndex->pNextFile=pNewPFile;		 
	ChangeProtNum(0, pNewPFile->protFile.PF_type); 
	 
	return TRUE; 
} 
 
//Make a path (or a file) under protection using default protection type. 
//parament pBCSPath must be a format one (passing in after calling FGFormatPath(), for example). 
BOOL KProtectedFileList::Add(const char *pBCSPath) 
{ 
	PROTECTED_FILE	protFile(pBCSPath,defProtectionType);      //defaul protectio type. 
	return Add(&protFile); 
} 
 
/*//parament pBCSPath must be capitalized. 
BOOL KProtectedFileList::IsHide(char *pBCSPath) 
{ 
	FILE_NODE *node=IsUnderProtection(pBCSPath); 
	if(!node || !(node->protFile.PF_type & PT_HIDE)) 
		return FALSE; 
	 
	return TRUE; 
}*/ 
 
//ToDo: Modify these two functions. 
 
PROTECTED_FILE *KProtectedFileList::FindFirst() 
{ 
	int i; 
	for(i=0; i<=MAX_DRIVE && !m_pFindIndex; i++) 
		m_pFindIndex=m_pHead[i]->pNextFile; 
 
	if(!m_pFindIndex) 
		return NULL; 
	else return &m_pFindIndex->protFile; 
} 
 
PROTECTED_FILE *KProtectedFileList::FindNext() 
{ 
	if(!m_pFindIndex || m_pFindIndex==m_pHead[PathToIndex(m_pFindIndex->protFile.PF_pPath)]) 
		return NULL; 
 
	//if m_pFindIndex->pNextFile==NULL, then search for the rest entrys of the table. 
	for(int i=PathToIndex(m_pFindIndex->protFile.PF_pPath)+1; i<=MAX_DRIVE && !m_pFindIndex->pNextFile; i++) 
		m_pFindIndex=m_pHead[i]; 
	m_pFindIndex=m_pFindIndex->pNextFile; 
 
	if(!m_pFindIndex) 
		return NULL; 
	else return &m_pFindIndex->protFile; 
} 
 
 
//Is there a path in the list exactly the same to pBCSProtPath. 
//pBCSProtPath should be formatted. 
FILE_NODE * KProtectedFileList::IsInList(const char *pBCSProtPath) 
{ 
	struct FILE_NODE *pIndex=m_pHead[PathToIndex(pBCSProtPath)]->pNextFile; 
 
	while(pIndex!=NULL) 
	{ 
		if(strcmp(pBCSProtPath, pIndex->protFile.PF_pPath)==0) 
			return pIndex; 
		pIndex=pIndex->pNextFile; 
	} 
 
	return NULL; 
} 
 
BOOL KProtectedFileList::Add(const char *pBCSPath, WORD protectionType) 
{ 
	PROTECTED_FILE	protFile(pBCSPath, protectionType);      //PT_DELETE | PT_WRITE. 
	return Add(&protFile); 
} 
 
//Calculate=number of component. 
BYTE KProtectedFileList::GetPriority(char *path) 
{ 
	BYTE prio=0, pos=0; 
	 
	while(path[pos]!=NULL) 
		if(path[pos++]=='\\') 
			prio+=2; 
	 
	if(strchr(path, '*')) 
		prio--;					//directory has higher(smaller) priority. 
 
	return prio; 
} 
 
//If there is any files have the protection attribute of PT_DELETE,set bIsDelOn to TRUE, 
//else to FALSE.  Same to bIsWriteOn, bIsReadOn, bIsHideOn. 
void KProtectedFileList::ChangeProtNum(WORD typeOld, WORD typeNew) 
{ 
	if(typeOld & PT_DELETE && bIsDelOn) 
		bIsDelOn--; 
	if(typeOld & PT_WRITE && bIsWriteOn) 
		bIsWriteOn--; 
	if(typeOld & PT_READ && bIsReadOn) 
		bIsReadOn--; 
	if(typeOld & PT_HIDE && bIsHideOn) 
		bIsHideOn--; 
 
	if(typeNew & PT_DELETE) 
		bIsDelOn++; 
	if(typeNew & PT_WRITE) 
		bIsWriteOn++; 
	if(typeNew & PT_READ) 
		bIsReadOn++; 
	if(typeNew & PT_HIDE) 
		bIsHideOn++; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////////////// 
//Following function used in vxd only. 
 
#ifdef	FG_VXD 
 
PROTECTED_FILE* KProtectedFileList::IsUnderProtection(int drive, ParsedPath *pPPath, WORD filter/*=0xFFFF*/) 
{ 
	FSD_PATH fp; 
	struct FILE_NODE *pIndex; 
	 
	fp.drive=drive; 
	fp.ppath=pPPath; 
	pIndex=m_pHead[GetSafeEntry(drive)]->pNextFile; 
	 
	while(pIndex) 
	{ 
		if(!pIndex->protFile.PF_fsdPath.ppath)	//debug 
			break; 
 
		if(pIndex->protFile.PF_type&filter && FSDPathMatch(&(pIndex->protFile.PF_fsdPath), &fp)) 
			return &(pIndex->protFile); 
 
		pIndex=pIndex->pNextFile; 
	} 
 
	return NULL; 
} 
 
// Function name	: KProtectedFileList::IsUnderProtection 
// Description	    : Determine whether a file is under protection. 
// Return type		: FILE_NODE*  return NULL if not under protection. 
// Argument         : const char *pBCSPath: file path. whilecards are NOT allowed.    
PROTECTED_FILE	* KProtectedFileList::IsUnderProtection(const char *pBCSPath, WORD filter/*=0xFFF*/) 
{ 
	struct FILE_NODE *pIndex=m_pHead[PathToIndex(pBCSPath)]->pNextFile; 
	 
	while(pIndex) 
	{ 
		if(pIndex->protFile.PF_type&filter && PatternMatch((const char *)pIndex->protFile.PF_pPath, pBCSPath, strlen(pIndex->protFile.PF_pPath), strlen(pBCSPath))) 
			return &(pIndex->protFile); 
 
		pIndex=pIndex->pNextFile; 
	} 
 
	return NULL; 
} 
 
/*BOOL KProtectedFileList::IsUnderDeleteProtection(int drive, ParsedPath *pPPath) 
{ 
	FILE_NODE *pFN=IsUnderProtection(drive, pPPath); 
 
	if(!(pFN && pFN->protFile.PF_type&PT_DELETE)) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL KProtectedFileList::IsUnderReadProtection(int drive, ParsedPath *pPPath) 
{ 
#ifdef DEBUG 
	//dout<<"Read protection compare:"<pp_totalLength); 
#endif 
 
	FILE_NODE *pFN=IsUnderProtection(drive, pPPath); 
 
	if(!(pFN && pFN->protFile.PF_type&PT_READ)) 
		return FALSE; 
 
	return TRUE; 
} 
 
 
BOOL KProtectedFileList::IsUnderWriteProtection(int drive, ParsedPath *pPPath) 
{ 
	FILE_NODE *pFN=IsUnderProtection(drive, pPPath); 
 
	if(!(pFN && pFN->protFile.PF_type&PT_WRITE)) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL KProtectedFileList::IsHide(int drive, ParsedPath *pPPath) 
{ 
	FILE_NODE *pFN=IsUnderProtection(drive, pPPath); 
 
	if(!(pFN && pFN->protFile.PF_type&PT_HIDE)) 
		return FALSE; 
 
	return TRUE; 
}*/ 
 
#endif