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;
}