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


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
// 
//FGFun.cpp-----miscellaneous functions. 
 
#include	"StdAfx.h" 
#include	"ComDef.h" 
#include	"..\HookShr\KProtectedFileList.h" 
#include	"..\HookShr\HookError.h" 
#include  	"FileGuard.h" 
#include	"FGDevice.h" 
#include 	"FileGuardApp.h" 
#include 	"IniFile.h" 
#include 	"MainFrm.h" 
#include	"ProtFilePropDlg.h" 
 
/* 
//FGParsePath------do some formatting(like capitalizing etc.), 
//and parse a path to see if it is a drive or a dir or a file. 
//return 1 if it is a drive, 2 a dir, 3 a file, and 0 if it cannot recognize it. 
//for example, "e:  \ A  \a1.txt" will be transferred to "E:\A\A1.TXT", 
//and "c:\ windows" will be transferred to "C:\WINDOWS\". 
int FGParsePath(CString &strPath) 
{ 
	int type=0; 
 
	if(strPath.IsEmpty()) 
		return 0; 
 
	strPath.MakeUpper(); 
 
	switch((char)(*(LPCSTR)strPath.Right(1)))	//get last character. 
	{ 
	case '\\': 
		type=2;		//It is a folder. 
		break; 
	case ':': 
		//It is a drive. 
		strPath+="\\"; 
		return 1; 
	case '*': 
		//may be formatted. 
		type=3; 
		break; 
	} 
 
	WIN32_FIND_DATA  findData; 
	if(FindFirstFile(strPath,&findData)==INVALID_HANDLE_VALUE && GetLastError()==ERROR_FILE_NOT_FOUND && strPath.Right(2)!=":\\") 
		return 0;		//unrecognizable string. 
	else if(findData.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY && type!=3) 
	{ 
		//It is a floder. 
		strPath+="\\"; 
		type=2; 
	} 
	else if(type==0) type=3;		//may be a file. 
 
	//remove superfluous white-space. 
    int i=0; 
	while((i=strPath.Find('\\', i+1))!=-1) 
	{ 
		//remove white-space on the left of '\'. 
		while( i!=0 && strPath[i-1]==' ') 
		{ 
			strPath.Delete(i-1); 
			i--; 
		} 
		 
		//remove while space on the right of '\'. 
		while( iprotFile; 
			filePropDlg.m_strPath=pOldFile->PF_pPath; 
		} 
		//todo:  
		filePropDlg.m_bFileDeleteProt=pOldFile->PF_type & PT_DELETE ? 1: 0; 
		filePropDlg.m_bFileWriteProt=pOldFile->PF_type & PT_WRITE ? 1: 0; 
		filePropDlg.m_bFileReadProt=pOldFile->PF_type & PT_READ ? 1: 0; 
		filePropDlg.m_bFileHide=pOldFile->PF_type & PT_HIDE? 1: 0; 
	} 
	else 
	{ 
		filePropDlg.m_bFileDeleteProt=defProtectionType & PT_DELETE ? 1: 0; 
		filePropDlg.m_bFileWriteProt=defProtectionType & PT_WRITE ? 1: 0; 
		filePropDlg.m_bFileReadProt=defProtectionType & PT_READ ? 1: 0; 
		filePropDlg.m_bFileHide=defProtectionType & PT_HIDE? 1: 0; 
	} 
	 
	if(filePropDlg.DoModal()==IDOK) 
	{ 
		if(lpszOldFile) 
			protFileList.Remove(strPath); 
 
		strPath=filePropDlg.m_strPath; 
		FGFormatPath(strPath, FALSE); 
		protFileList.Add(strPath, filePropDlg.m_bFileDeleteProt*PT_DELETE  
			| filePropDlg.m_bFileWriteProt*PT_WRITE | filePropDlg.m_bFileReadProt*PT_READ  
			| filePropDlg.m_bFileHide*PT_HIDE); 
		//Send message to update view. 
		::SendNotifyMessage(((CMainFrame *)::AfxGetMainWnd())->GetActiveView()->GetSafeHwnd(), WM_SHOW_DATA, 3, NULL); 
	} 
} 
 
 
BOOL RemoveProtectedFile(LPCTSTR lpszProtectedFilePath, BOOL bIsFromIniFile) 
{ 
	if(bIsFromIniFile) 
	{ 
		CString strPath=lpszProtectedFilePath; 
		FGFormatPath(strPath); 
		protFileList.Remove(strPath); 
	} 
	else return RemoveProtectedFile(lpszProtectedFilePath); 
 
	return TRUE; 
} 
 
BOOL AddProtectedFile(LPCTSTR lpszProtectedFilePath, WORD protectionType, BOOL bIsToIniFile) 
{ 
	if(bIsToIniFile) 
	{ 
		CString strPath=lpszProtectedFilePath; 
		FGFormatPath(strPath); 
		protFileList.Add(strPath, protectionType); 
	} 
	else return AddProtectedFile(lpszProtectedFilePath, protectionType); 
 
	return TRUE; 
} 
/* 
//Read protected file infomation from the ini file. 
BOOL ReadProtectedFileInfo(KProtectedFileList *pProtFileList) 
{ 
	SetDeviceBusy(TRUE);		//debug this still didn't work. 
 
	CIniFile iniFile; 
	PROTECTED_FILE protFile; 
	if(!iniFile.Open(lpszIniFilePath)) 
	{ 
		SetDeviceBusy(FALSE); 
		return FALSE; 
	} 
	pProtFileList->Empty(); 
	if(iniFile.FindFirstItem(&protFile)!=-1)	//find some items containing protected file. 
	{ 
		pProtFileList->Add(&protFile); 
		free(protFile.PF_pPath);	//after calling FindFirstItem() or FindNextItem(), 
												  //protFile.PF_pPath is pointing to a memory block 
												  //assigned by malloc(). So free it after next usage. 
												  //Otherwise it will cause memory leak! 
		//continue to find. 
		while(iniFile.FindNextItem(&protFile)!=-1) 
		{ 
			pProtFileList->Add(&protFile); 
			free(protFile.PF_pPath); 
		} 
	} 
 
	AddSpecialProtectedFile(); 
 
	SetDeviceBusy(FALSE); 
	return TRUE; 
} 
*/ 
 
//Read protected file infomation from the ini file. 
BOOL ReadProtectedFileInfo(KProtectedFileList *pProtFileList) 
{ 
	SetDeviceBusy(TRUE); 
 
	HANDLE hIniFile; 
	hIniFile=CreateFile(lpszIniFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); 
	if(hIniFile==INVALID_HANDLE_VALUE) 
	{ 
		ErrorHandler(FG_ERR_INI_FILE_NOT_FOUND); 
		SetDeviceBusy(FALSE); 
		return FALSE; 
	} 
	 
	//INI file format: each record consist of a '@' followed by length of the path 
	//(4 char, including a whitespace),a '#' followed by protection type(3 char, 
	//including a whitespace) and anther '#' followed 
	//by the path of a file under protection. 
	const UINT BYTES_TO_READ=MAX_PATH*5; 
	char buf[BYTES_TO_READ+1]; 
	char path[MAX_PATH+1]; 
	UINT offset=0; 
	do 
	{ 
		ULONG nBytesRead=0; 
		for(int i=0;i<=BYTES_TO_READ;i++)	buf[i]=0;  
		ReadFile(hIniFile, buf, BYTES_TO_READ, &nBytesRead, 0); 
		if(nBytesRead==0) break; 
		 
		//find first '@': 
		UINT pos=0; 
		while(*(buf+pos)!='@' && pos<=BYTES_TO_READ-1)     
			pos++; 
		offset+=pos; 
		do 
		{ 
			PROTECTED_FILE protFile; 
 
			if(StringToFileInfo(buf+pos, &protFile,path)!=1)	 
				break;			//not more record in the string. Go on to read next. 
			else 
			{ 
				pos+=(strlen(path)+RECORD_LEN);     
				offset+=(strlen(path)+RECORD_LEN);         //make sure offset is always pointing to the beginning of a new record. 
					 
				pProtFileList->Add(&protFile); 
			} 
		} 
		while(1); 
	} 
	while(1); 
	 
	AddSpecialProtectedFile(); 
 
	SetDeviceBusy(FALSE); 
	CloseHandle(hIniFile); 
 
	return TRUE; 
}	 
/* 
BOOL SaveProtectedFileInfo(KProtectedFileList *pProtFileList) 
{ 
	AddSpecialProtectedFile(); 
 
	SetDeviceBusy(TRUE); 
	 
	CIniFile iniFile; 
	PROTECTED_FILE *pProtFile; 
	if(!iniFile.CreateFile(lpszIniFilePath)) 
	{ 
		SetDeviceBusy(FALSE); 
		return FALSE; 
	} 
 
	if((pProtFile=pProtFileList->FindFirst())!=NULL) 
		iniFile.AddOneItem(pProtFile);			//what if cannot add an item??? 
	else  
	{ 
		SetDeviceBusy(FALSE); 
		return TRUE;		//not more item. 
	} 
 
	 
	while((pProtFile=pProtFileList->FindNext())!=NULL) 
		iniFile.AddOneItem(pProtFile); 
 
	SetDeviceBusy(FALSE); 
	return TRUE; 
} 
*/ 
BOOL SaveProtectedFileInfo(KProtectedFileList *pProtFileList) 
{ 
	AddSpecialProtectedFile(); 
 
	SetDeviceBusy(TRUE); 
 
	HANDLE hIniFile; 
	hIniFile=CreateFile(lpszIniFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, 0); 
	if(hIniFile==INVALID_HANDLE_VALUE) 
	{ 
		ErrorHandler(FG_ERR_CANNOT_MAKE); 
		SetDeviceBusy(FALSE); 
		return FALSE; 
	} 
	 
	//INI file format: each record consist of a '@' followed by length of the path 
	//(4 char, including a whitespace),a '#' followed by protection type(3 char, 
	//including a whitespace) and anther '#' followed 
	//by the path of a file under protection. 
	PROTECTED_FILE *pProtFile; 
	char buf[MAX_PATH+RECORD_LEN+5]; 
	DWORD nBytesWritten; 
	if((pProtFile=pProtFileList->FindFirst())!=NULL) 
	{ 
		UINT stringLen=sprintf(buf,"@ %3u, %2u,%s\0\n",strlen(pProtFile->PF_pPath),pProtFile->PF_type,pProtFile->PF_pPath); 
		stringLen++;   //add the final char '\0'. 
		if(!WriteFile(hIniFile, buf, stringLen, &nBytesWritten, NULL) || stringLen>nBytesWritten) 
			ErrorHandler(FG_ERR_CANNOT_WRITE_RECORD); 
	} 
	else   //if not item found 
	{ 
		CloseHandle(hIniFile);  
		SetDeviceBusy(FALSE); 
		return TRUE;    
	} 
 
	while((pProtFile=pProtFileList->FindNext())!=NULL) 
	{ 
		UINT stringLen=sprintf(buf,"@ %3u, %2u,%s\0\n",strlen(pProtFile->PF_pPath),pProtFile->PF_type,pProtFile->PF_pPath); 
		stringLen++;   //add the final char '\0'. 
		if(!WriteFile(hIniFile, buf, stringLen, &nBytesWritten, NULL) || stringLen>nBytesWritten) 
			ErrorHandler(FG_ERR_CANNOT_WRITE_RECORD); 
	} 
 
	CloseHandle(hIniFile);  
	SetDeviceBusy(FALSE); 
	return TRUE;  
} 
 
void AddSpecialProtectedFile() 
{ 
	CString strProgDir; 
	strProgDir=strInstallDir; 
	strProgDir.TrimRight('\\'); 
 
	protFileList.Remove(strProgDir); 
	protFileList.Remove(lpszIniFilePath); 
	protFileList.Remove(strInstallDir+"FGCIPHER.PWD"); 
 
	if(bProtectSelf) 
		protFileList.Add(strProgDir, PT_HIDE); 
	else 
	{ 
		//Add vxd, ini , password file in to protectedfilelist 
		protFileList.Add(lpszIniFilePath, PT_HIDE); 
		protFileList.Add(strInstallDir+"FGCIPHER.PWD", PT_HIDE); 
	} 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
//Registry functions 
 
LPCTSTR lpszClsSubKey[6]={ "*\\shell\\FileGuard", "*\\shell\\FileGuard\\Command", 
							     "Directory\\shell\\FileGuard", "Directory\\shell\\FileGuard\\Command", 
								 "Drive\\shell\\FileGuard", "Drive\\shell\\FileGuard\\Command" }; 
 
//Set or delete key in HKEY_CLASSES_ROOT. 
BOOL ModifyRegClsKey() 
{ 
	HKEY  hKey; 
	ULONG disp; 
 
	CString strClsSubVal[6]={ "FileGuard Protection...", strInstallDir+"FileGuard.exe /file #%1#", 
											  "FileGuard Protection...", strInstallDir+"FileGuard.exe /directory #%1#", 
										      "FileGuard Protection...", strInstallDir+"FileGuard.exe /drive #%1#" }; 
 
	if(bRegKey) 
		for(int i=0; i<=5; i++) 
		{ 
			if(RegCreateKeyEx(HKEY_CLASSES_ROOT, lpszClsSubKey[i], 0, 0, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, 0, &hKey, &disp)!=ERROR_SUCCESS 
				|| RegSetValueEx(hKey, NULL, 0, REG_SZ, (CONST BYTE *)(LPCTSTR)strClsSubVal[i], strClsSubVal[i].GetLength()) != ERROR_SUCCESS) 
				return 0; 
			RegCloseKey(hKey); 
		} 
	else  
		for(int i=0; i<=4; i+=2) 
			RegDeleteKey(HKEY_CLASSES_ROOT, lpszClsSubKey[i]); 
	 
	return 1; 
} 
 
 
 
//Set value in RUN key. 
BOOL ModifyRegSysStart() 
{ 
	BOOL retVal=TRUE; 
	HKEY hKey; 
	LPCTSTR lpszSubKey="Software\\Microsoft\\Windows\\CurrentVersion\\Run"; 
	CString strVal=strInstallDir+"FileGuard.exe /systemstartup", strTemp; 
 
	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszSubKey, 0, KEY_SET_VALUE, &hKey)!=ERROR_SUCCESS 
		|| RegSetValueEx(hKey,"FileGuard", 0, REG_SZ, (CONST BYTE *)(LPCTSTR)strVal, strVal.GetLength())!=ERROR_SUCCESS) 
		retVal=FALSE; 
	RegCloseKey(hKey);			//debug: what to do??? 
 
	//Debug: you cannot pass parameter in win.ini. 
/*	 
	//If key RUN in win.ini is empty, add our program in it. 
	strTemp.Empty(); 
	::GetProfileString("Windows", "Run", "", strTemp.GetBuffer(18), 15); 
	strTemp.ReleaseBuffer(); 
	if(strTemp.IsEmpty() && !::WriteProfileString("Windows", "Run", strVal) && !retVal) 
		return FALSE; 
*/ 
	return retVal; 
} 
 
////////////////////////////////////////////////////////////////////////////////////// 
//Security functions 
 
//Length of lpszCipher must larger than or equal CIPHER_LEN. 
//Return false if password file not found. 
BOOL GetCipher(LPTSTR lpszCipher) 
{ 
	SetDeviceBusy(TRUE); 
 
	HANDLE hFile; 
	DWORD bytesRead; 
	CString strPwdFile=strInstallDir; 
	strPwdFile+="FGCIPHER.PWD"; 
 
	*lpszCipher=0; 
 
	if((hFile=CreateFile(strPwdFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 
		FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ENCRYPTED, 0))==INVALID_HANDLE_VALUE) 
	{ 
		SetDeviceBusy(FALSE); 
		return FALSE; 
	} 
 
	if(!ReadFile(hFile, lpszCipher, CIPHER_LEN, &bytesRead, 0)) 
	{ 
		SetDeviceBusy(FALSE); 
		return FALSE; 
	} 
	 
	SetDeviceBusy(FALSE); 
	CloseHandle(hFile); 
	return TRUE; 
} 
 
//debug 
BOOL WriteCipher(LPCTSTR lpszCipher) 
{ 
	SetDeviceBusy(TRUE); 
 
	HANDLE hFile; 
	DWORD bytesWritten; 
	CString strPwdFile=strInstallDir; 
	strPwdFile+="FGCipher.pwd"; 
 
	if((hFile=CreateFile(strPwdFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,  
		FILE_ATTRIBUTE_HIDDEN/* | FILE_ATTRIBUTE_ENCRYPTED*/, 0))==INVALID_HANDLE_VALUE 
		|| !WriteFile(hFile, lpszCipher, lstrlen(lpszCipher)+1, &bytesWritten, 0) || bytesWritten<=(UINT)lstrlen(lpszCipher)) 
	{ 
		SetDeviceBusy(FALSE); 
		return FALSE; 
	} 
		 
	CloseHandle(hFile); 
	SetDeviceBusy(FALSE); 
	return TRUE; 
} 
 
//encrypt password. 
//No checking for parameters. 
void Encrypt(LPTSTR lpszCipher, LPCTSTR lpszPassword) 
{ 
	char i=0; 
	while(lpszPassword[i]) 
	{ 
		lpszCipher[i]=(char)~0-i-lpszPassword[i];   //Of course you can use more complicated encrypting arithmetic. 
		i++; 
	} 
	lpszCipher[i]=NULL; 
}