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

📄 fghook.cpp

📁 文件加密的过滤驱动程序源代码.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
					ShellPostError(FG_ERR_WARNING, FG_WARN_PT_DELETE);	//Send a warning.
					return pir->ir_error;
				}
			}

			//go on to find next file
			R0_FindNextFile(hFind, &bcsFindData, &error);

		}		//while(error==ERROR_SUCCESS)

	}		//if(pir->ir_attr&FILE_FLAG_WILDCARDS || pir->ir_attr&FILE_FLAG_HAS_STAR)

	else if((pProtFile=protFileList.IsUnderProtection(Drive, pir->ir_ppath, PT_DELETE|PT_HIDE))!=NULL)
	{
		//Deal with file name without wildcards:

		if(pProtFile->PF_type&PT_HIDE)						
			pir->ir_error=ERROR_FILE_NOT_FOUND;		//Protect hidden file.
		if(!protFileList.bDelBak)						
		{
			//Deny delete
			pir->ir_error=ERROR_ACCESS_DENIED;
			ShellPostError(FG_ERR_WARNING, FG_WARN_PT_DELETE);	//Send a warning.
		}
		else 
		{
			//Back up on delete.
			UniToBCSPathEx((PUCHAR)pBCSPath,pir->ir_ppath->pp_elements,Drive,MAX_PATH,CodePage,&res);	
			pir->ir_error=FileRename(pBCSPath);
		}
		return pir->ir_error;
	}

	return ERROR_SUCCESS;
}

//Append a extension like ".BAK0" or ".BAK1" to the file name.
//(the maximum number appended at the tail depends on MAX_BAK_NUM)
//If every optional back up file name have been used, return FALSE, 
//else return TRUE.
//No checking for the parameters. pBCSNewName must be long enough.
BOOL  AppendBakExtension(const char *pBCSOldName, char *pBCSNewName)
{
	strcpy(pBCSNewName,pBCSOldName);
	strcat(pBCSNewName,".BAK1");      //Rename the file.

	WORD error;
	_WIN32_FIND_DATA_BCS findData;

	char i;
	for(i='2'; i<='1'+maxBakNum-1; i++)
	{
		R0_FindFirstFile(pBCSNewName, NULL, &findData, &error);
		if(error==ERROR_FILE_NOT_FOUND)
			return TRUE;
		else 
			//if the file name has already been used, make some change.
			pBCSNewName[strlen(pBCSNewName)-1]=i;					
	}

	return FALSE;
}

//Backup a file by renaming it:
//e.g. "A.txt"  to "A.txt.BAK".
WORD FileRename(char *pBCSOldName)
{
	char pBCSNewName[MAX_PATH+1];
	WORD error;
	
    //Name the bak file.
	AppendBakExtension(pBCSOldName, pBCSNewName);

	R0_RenameFile(pBCSOldName,pBCSNewName,&error);
	
	return error;
}

// Function name	: FileBackupByHandle
//							Backup a file identified by pir->ir_fh & pBCSName.
//							Using pir->ir_fh to read from the file.
//							if	the handle is open with out Generic_Read, this function will fail.
//							Only call this function in HookProc.
WORD FileBackupByHandle(pioreq pir,int Drive, int ResType, int CodePage,const char *pBCSName)
{
	char pBCSNewName[MAX_PATH+1];
	HANDLE hNewFile;
	BYTE action;
	WORD error, retVal=ERROR_SUCCESS;
	ifsreq ifsr;
	
	//Name the bak file.
	AppendBakExtension(pBCSName, pBCSNewName);
	
	hNewFile=R0_OpenCreateFile(FALSE, pBCSNewName,OPEN_ACCESS_WRITEONLY | OPEN_SHARE_COMPATIBLE,
		ATTR_NORMAL, ACTION_IFEXISTS_TRUNCATE | ACTION_IFNOTEXISTS_CREATE,0 ,&error,&action);
	if(error!=ERROR_SUCCESS) return error;
	
	char buf[BUF_LEN+1];
	DWORD nBytesRead=0,nBytesWrite=0,offset=0;
	memcpy(&ifsr,pir,sizeof(ifsreq));
	pIFSFunc  readFunc = ifsr.ifs_hndl->hf_read;
	while(1)
	{
		ifsr.ifsir.ir_length=BUF_LEN;
		ifsr.ifsir.ir_options=R0_NO_CACHE;
		ifsr.ifsir.ir_data=buf;
		ifsr.ifsir.ir_pos=offset;	
		if((*PrevHookProc)(readFunc, IFSFN_READ,Drive, ResType, CodePage,(pioreq) &ifsr)==STATUS_PENDING)
			IFSMgr_CompleteAsync((pioreq) &ifsr);  

		nBytesRead=ifsr.ifsir.ir_length;
		if(ifsr.ifsir.ir_error!=ERROR_SUCCESS || !nBytesRead) 
		{
			retVal=ifsr.ifsir.ir_error;
			break;
		}

		nBytesWrite=R0_WriteFile(FALSE,hNewFile,buf,nBytesRead,offset,&error);

		if(error!=ERROR_SUCCESS)
		{
			retVal=error;
			break;
		}
		
		offset+=nBytesRead;
	}
	
	R0_CloseFile(hNewFile,&error);

	return retVal;
}

// Function name	: FileBackup
//							Back up a file identify by pBCSName.
//							If the file is currently open by other user with DENY_READ, this function will fail.
WORD FileBackup(char *pBCSName)
{
	char pBCSNewName[MAX_PATH+1];
	HANDLE hOldFile, hNewFile;
	BYTE action;
	WORD error, retVal=ERROR_SUCCESS;
	
	//Name the bak file.
	AppendBakExtension(pBCSName, pBCSNewName);

	hOldFile=R0_OpenCreateFile(FALSE, pBCSName,OPEN_ACCESS_READONLY	 | OPEN_SHARE_COMPATIBLE,
		ATTR_NORMAL, ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_FAIL	,0 ,&error,&action);
	if(error!=ERROR_SUCCESS)
	{
		return error;
	}
	hNewFile=R0_OpenCreateFile(FALSE, pBCSNewName,OPEN_ACCESS_WRITEONLY | OPEN_SHARE_COMPATIBLE,
		ATTR_NORMAL, ACTION_IFEXISTS_TRUNCATE | ACTION_IFNOTEXISTS_CREATE,0 ,&error,&action);
	if(error!=ERROR_SUCCESS) return error;

	char buf[BUF_LEN+1];
	DWORD nBytesRead=0,nBytesWrite=0,offset=0;
	while(1)
	{
		nBytesRead=R0_ReadFile(FALSE, hOldFile, buf, BUF_LEN, offset, &error);
		if(error!=ERROR_SUCCESS || !nBytesRead)
		{
			retVal=error;
			break;
		}

		nBytesWrite=R0_WriteFile(FALSE,hNewFile,buf,nBytesRead,offset,&error);
		if(error!=ERROR_SUCCESS) 
		{
			retVal=error;
			break;
		}
		
		offset+=nBytesRead;
	}
	
	R0_CloseFile(hOldFile, &error);
	R0_CloseFile(hNewFile,&error);

	return retVal;
}

//Similar to UniToBCSPath(...)
void  UniToBCSPathEx(PUCHAR pBCSPath, PathElement* pUniPath, int Drive, DWORD maxLength, int charSet, _QWORD* pResult)
{
	//Get driver volume:
	pBCSPath[0]=(char)Drive-1+'A';
	pBCSPath[1]=':';
	
	UniToBCSPath(pBCSPath+2,pUniPath,maxLength,charSet,pResult);
	pBCSPath[pResult->ddLower+2]=NULL;
}

//Get full Canonicalized Path from pir->ir_fh.
BOOL GetFullNameByHandle(pioreq pir,int &Drive, int ResType, int CodePage,path_t pPPath, BOOL bFindHandle)
{
	//Search in handle table first.
	if((bFindHandle && findHTable.Find(pir->ir_fh, Drive, pPPath, MAX_PATH)) || openHTable.Find(pir->ir_fh, Drive, pPPath, MAX_PATH))
		return TRUE;

	//if not found in handle table, call FS_EnumerateHandle to get file path.
    ifsreq      ifsr;
    memcpy( &ifsr, pir, sizeof(ifsreq));
    ifsr.ifsir.ir_flags = bFindHandle ?  ENUMH_GETFINDINFO : ENUMH_GETFILENAME;
    ifsr.ifsir.ir_ppath = pPPath;
   	pIFSFunc    enumFunc = ifsr.ifs_hndl->hf_misc->hm_func[HM_ENUMHANDLE];		//get address of FS_EnumerateHandle from struct hndlfunc.

    if((*PrevHookProc)(enumFunc, IFSFN_ENUMHANDLE, Drive, ResType, CodePage,(pioreq) &ifsr)!= ERROR_SUCCESS) return FALSE;

	return TRUE;
}

void SetLastError(WORD errorCode)
{
	lastError=errorCode;
}

WORD GetLastError()
{
	return lastError;
}

UINT refData;	
SHELLMessage_THUNK thunk;

//Gobal error handler for device:
//err: error code.	severity: 0 means a fatal error, 1 a minor one.
//return value: 0 ---the moduel where the error occurs must stop processing.
//						1 ---processing can go on.
int ErrorHandler(unsigned int err, int severity/*=1*/)
{
	ShellPostError(err,severity);
	return 1;
}

//Callback function for user's response of shell_message.
void __stdcall MsgCallBack(DWORD ResponseCode,PVOID Refdata)
{
	switch(*((UINT *)Refdata))
	{
		case ON_MSG_FILE_NOT_FOUND:
			if(ResponseCode==IDNO)
				ShellUnloadDevice();		//call on FileGuard win32 GUI to stop protection.
			break;
	}
}

//Read protected file information:
//DO NOT call this function from within HookProc.
BOOL ReadProtectedFileInfo(char *pFileName)
{
	//Prevent reentry:
	bBusy=TRUE;

	HANDLE hIniFile;
	WORD error;
	BYTE action;
	hIniFile=R0_OpenCreateFile(TRUE,pFileName,OPEN_ACCESS_READONLY|OPEN_SHARE_COMPATIBLE|OPEN_FLAGS_COMMIT,ATTR_NORMAL,ACTION_IFEXISTS_OPEN|ACTION_IFNOTEXISTS_FAIL,R0_NO_CACHE,&error,&action);
	if(error!=ERROR_SUCCESS)
	{
		ErrorHandler(FG_ERR_INI_FILE_NOT_FOUND);
		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
	{
		BYTE nBytesRead=0;
		for(int i=0;i<=BYTES_TO_READ;i++)	buf[i]=0; 
		nBytesRead=R0_ReadFile(FALSE,hIniFile,buf,BYTES_TO_READ,offset,&error);
		if(nBytesRead==0) break;
		if(error!=ERROR_SUCCESS)
			continue;
		
		UINT pos=0;
		//find first '@':
		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.
				
				#ifdef DEBUG
					dout <<path<<endl;
				#endif
					
				protFileList.Add(&protFile);
			}
		}
		while(1);
	}
	while(1);
	
	R0_CloseFile(hIniFile,&error);

	bBusy=FALSE;
	return TRUE;
}		

//save protected file information.   
//DO NOT call this function from within HookProc.
BOOL SaveProtectedFileInfo(char *pFileName)								//debug: unreferrence function.
{
	//Prevent reentry:
	bBusy=TRUE;

	HANDLE hIniFile;
	WORD error;
	BYTE action;
	hIniFile=R0_OpenCreateFile(TRUE,pFileName,OPEN_ACCESS_WRITEONLY|OPEN_SHARE_COMPATIBLE|OPEN_FLAGS_COMMIT,ATTR_NORMAL,ACTION_IFNOTEXISTS_CREATE|ACTION_IFEXISTS_TRUNCATE,R0_NO_CACHE,&error,&action);
	if(error!=ERROR_SUCCESS)
	{
		ErrorHandler(FG_ERR_CANNOT_MAKE);
		#ifdef DEBUG
			dout << "Save file list: can't open file." << endl;
		#endif
		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=(char *)malloc(MAX_PATH+15);
	UINT offset=0;
	if((pProtFile=protFileList.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((stringLen>R0_WriteFile(FALSE, hIniFile, buf, stringLen, offset, &error)) || error!=ERROR_SUCCESS)
		{
			ErrorHandler(FG_ERR_CANNOT_WRITE_RECORD);
			#ifdef DEBUG
				dout << "Save file list: can't write an record." << endl;
			#endif
		}
		else offset+=stringLen;  //writing success.
	}
	else   //if not item found
	{
		R0_CloseFile(hIniFile, &error); 
		free(buf);
		return TRUE;   
	}

	while((pProtFile=protFileList.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((stringLen>R0_WriteFile(FALSE, hIniFile, buf, stringLen, offset, &error)) || error!=ERROR_SUCCESS)
		{
			ErrorHandler(FG_ERR_CANNOT_WRITE_RECORD);
			#ifdef DEBUG
				dout << "Save file list: can't write an record." << endl;
			#endif
		}
		else offset+=stringLen;  //writing success.
	}

	R0_CloseFile(hIniFile, &error); 
	free(buf);

	bBusy=FALSE;
	return TRUE;    //end of list.
}

//call for win32 GUI to stop protection.
BOOL ShellUnloadDevice()
{
	if(!hAppWnd)
		return FALSE;
	return SHELL_PostMessage(hAppWnd, SM_DEVICE_FATAL_ERROR, 0, 0, 0, 0);
}

//Post errer code to win32 app.
BOOL ShellPostError(DWORD err, int severity)
{
	if(!hAppWnd)
		return FALSE;
	return SHELL_PostMessage(hAppWnd, SM_DEVICE_ERROR, (WORD)severity, err, 0, 0);		//Error message sended to win32 app.
																															 //wParam is severity, lParam is error code.
}

int wstrlen(unsigned short *uniString)
{
    int i = 0;
    int len = 0;
  
    while( uniString[i++] != 0 ) len+=2;

    return len;
}

//Make characters in a wide character string to upper case.
//Return Value: string length.
int StringUpper(WCHAR *s, int len)
{
	int i=-1;

	while(++i<=len)
		if(s[i]>='a' && s[i]<='z')
			s[i]-=32;

	return i;
}

//Convert BCS path to file system device's Canonicalized Path.
BOOL BCSToFSDPath(FSD_PATH *fp, const char *pBCSPath)
{
	fp->ppath=(struct ParsedPath *)malloc((strlen(pBCSPath)+1)*sizeof(WCHAR));
	if(!fp->ppath)	return FALSE;

	fp->flag=0;
	fp->drive=pBCSPath[0]-'A'+1;		//used first character as drive volume.
	
	//i: index;  prefix: prefix in parsed element(pe_length);  elemLength: length of an element;
	unsigned int i=3,prefix=4, elemLength=0, totalLenghth=0;		
	_QWORD res;
	do
	{
		if(*(pBCSPath+i)=='\\')
		{	
			BCSToUni((WCHAR *)((char *)fp->ppath+prefix+sizeof(WCHAR)), (PUCHAR)pBCSPath+i-elemLength, elemLength, BCS_OEM, &res);
			*(short *)((char*)fp->ppath+prefix)=sizeof(WCHAR)+res.ddLower;		//set pe_length.				
			totalLenghth+=*((char*)fp->ppath+prefix);
			prefix+=*((char*)fp->ppath+prefix);		//pointing to current '\' (pe_length).
			elemLength=0;
			i++;
			continue;
		}
		else if(*(pBCSPath+i)=='*')
			fp->flag|=FG_FILE_FLAG_HAS_STAR;
		else if(*(pBCSPath+i)=='?')
			fp->flag|=FG_FILE_FLAG_HAS_QUERYMARK;
		
		elemLength++;
		i++;
	}
	while(*(pBCSPath+i));

	BCSToUni((WCHAR *)((char *)fp->ppath+prefix+sizeof(WCHAR)), (PUCHAR)pBCSPath+i-elemLength, elemLength, BCS_OEM, &res);
	*(short *)((char*)fp->ppath+prefix)=sizeof(WCHAR)+res.ddLower;		//set pe_length for last element.
	totalLenghth+=*((char*)fp->ppath+prefix);
	fp->ppath->pp_totalLength=2*sizeof(WCHAR)+totalLenghth;				//set total length.
	fp->ppath->pp_prefixLength=prefix;		//pointing to last path element.
	*(short *)((char *)fp->ppath+fp->ppath->pp_totalLength)=NULL;

	return TRUE;
}

//Compare two parsed element.
BOOL _inline ElementMatch(PathElement *pPattern, PathElement *pMatcher, int flag)
{
	if(!(flag&FG_FILE_FLAG_HAS_STAR) && pPattern->pe_length!=pMatcher->pe_length)		//if pattern has not stars, and lengths don't equal, then match fail.
		return FALSE;
	
	return PatternMatch((WCHAR *)pPattern->pe_unichars, (WCHAR *)pMatcher->pe_unichars, pPattern->pe_length/sizeof(WCHAR)-1, pMatcher->pe_length/sizeof(WCHAR)-1);
}

//Compare two FSD_PATH struct.
BOOL _inline FSDPathMatch(FSD_PATH *pPattern, FSD_PATH *pMatcher)
{
	//compare path.
	if((pPattern->drive!=pMatcher->drive) || (!(pPattern->flag&FG_FILE_FLAG_HAS_STAR) && pPattern->ppath->pp_totalLength!=pMatcher->ppath->pp_totalLength))
		return FALSE;

	PathElement *ppe, *mpe;
	ppe=pPattern->ppath->pp_elements;
	mpe=pMatcher->ppath->pp_elements;

	while(ppe->pe_length)
	{
		//compare each parsed element.

		if(!ElementMatch(ppe, mpe, pPattern->flag))
			return FALSE;

		ppe=IFSNextElement(ppe);
		mpe=IFSNextElement(mpe);
	}

	return TRUE;
}

⌨️ 快捷键说明

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