如何防止用户删除指定文件夹还有其中的文件?(300分)

  • 主题发起人 主题发起人 fpsky
  • 开始时间 开始时间
F

fpsky

Unregistered / Unconfirmed
GUEST, unregistred user!
其中防止删除文件夹已用COPYHOOK实现在。
但用户还是能进入到指定的目录中去删除
里面的文件。。。
请高手指教
 
禁止删除文件比较麻烦,要做一个VXD驱动实现IFS钩子。
不过可以变相用BHO来实现如下功能:不让用户通过浏览器或我的电脑进入你禁止的目录,这样他就没法执行删除操作。同时禁止windows的进入DOS功能,这可以通过修改注册表实现。
 
to;wolf_cyj,
谢谢你,能具体说一下VXD的实现思路吗?
还有就是不能禁止用户的操作,只能禁止用户对本软件目录(包括其中的文件)的操作。。。
不胜感激。。
 
做一个类似还原的东西就可以了。
 
太麻烦了,人家MS的系统都没有这么做,其实只要在说明书中说一下就可以了
 
再增加一个 Shell Hook 。CopyHook 在这里几乎没有用的。
 
做一个hook在系统启动的时候加载,hook掉文件操作 api
 
to:小雨哥,低调一贱男
可以具体一些吗?3KU
 
使用 Shell 钩子的代码很难写,还好有 hubdog 已经写过一个例子代码了,在哪里自己找
一找看,我忘了哪一篇了。但是,这个 Shell 钩子有一个缺点,就是一旦把这个文件夹的
名字改掉,就没用了,真是奇怪它怎么会同意改名的。所以,我说是“再加一个”的意思,
就是光靠你的 CopyHook 和光靠 IShellExecuteHook 都不行,需要 2 个一起加。
hubdog 的代码你先找找看,我空了也会去找找看的。是 ID:651755 (hubdog)
 
删除以前判断一下
 
to:小雨哥
我看了HUBDOG,里面好像没有啊,帮我解决一下这个问题行吗?
谢谢了
 
买我写的驱动,¥5000,呵呵,需要的话联系我,smhp@163.net
 
1。VXD里要实现一个ifs hook,可以钩到任何文件操作,并禁止它或者转向,硬盘还原之类的东西好象也是这么做的。
2。禁止用资源管理器进入目录用bho就可以了,在onbeforenavegate里判断是file开头的(如果是http开头则是网页)就是访问硬盘,你在其中加入目录名判断就行了。
 
楼上的,错了,硬盘还原卡是改了Int 13的中断向量表
 
给个驱动代码吧

// FGHOOK.cpp - main module for VxD FGHOOK

#define DEVICE_MAIN
#include "FGHOOK.h"
Declare_Virtual_Device(FGHOOK)
#undef DEVICE_MAIN

ppIFSFileHookFunc PrevHookProc=NULL; //Previos hook function.

KProtectedFileList protFileList;
KProtectedFileList recycledPathList
//Path of Recycle.

KHandleTable findHTable, openHTable;
KHotKey *pHotKey;

HANDLE hIniFile,hVM;
HANDLE hAppWnd=NULL; //Handle of win32 app.
char iniFilePath[MAX_PATH+1]="";
ParsedPath *pPPath;

BOOL bBusy, bAppReqBusy=FALSE; //bAppReqBusy--win32 app is about be write file.
WORD lastError=FG_ERR_SUCCESS;
UINT maxBakNum=DEF_MAX_BAK_NUM; //max backup file number.

//NOTICE: I don't know whether more than one object files will be linked properly,
//(And I haven't try it.) So I just include other cpp files in the main cpp file.
//This did not cause any problem.
#include "../HookShr/KProtectedFileList.cpp"
#include "../HookShr/HookCom.cpp"
#include "KHandleTable.cpp"
#include "KHotKey.cpp"

///////////////////////////////////////////////////////////////////
//Main interface:
FGHookVM::FGHookVM(VMHANDLE hVM) : VVirtualMachine(hVM) {}

FGHookThread::FGHookThread(THREADHANDLE hThread) : VThread(hThread) {}


BOOL FGHookDevice::OnSysDynamicDeviceInit()
{
#ifdef DEBUG
dout << "Hello from FGHook!" << endl;
#endif

bBusy=FALSE;

if(!(pPPath=(ParsedPath *)malloc(MAX_PATH*sizeof(WCHAR)+sizeof(ParsedPath))))
{
ErrorHandler(FG_ERR_NOT_ENOUGH_MEMORY);
ShellUnloadDevice();
return FALSE;
}

//Add recycled path.
int i;
char recycledPath[MAX_PATH]="A://RECYCLED//*";
for(i=1
i<=32
i++) //Windows supports up to 32 drives.
{
recycledPath[0]=i+'A'-1;
recycledPathList.Add(recycledPath);
}

//intall key board hook:
pHotKey=new KHotKey;
pHotKey->hook();

return TRUE;
}

BOOL FGHookDevice::OnSysDynamicDeviceExit()
{
free(pPPath);
if(PrevHookProc)
IFSMgr_RemoveFileSystemApiHook(HookProc);

delete pHotKey;

#ifdef DEBUG
dout<<"Hook exit."<<endl;
#endif

return TRUE;
}

#ifdef DEBUG
void PrintUni(WCHAR *p, unsigned int len)
{
int i=0;

while(p &amp;&amp
i<len)
dout<<(char)p[i++];

dout<<endl;
i=0;
while(p &amp;&amp
i<len)
dout<<p[i++]<<" ";

dout<<endl;
}
#endif



DWORD FGHookDevice::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams)
{
switch(pDIOCParams->dioc_IOCtlCode)
{
case DIOC_OPEN:
//SHELL_Message(pDIOCParams->dioc_hvm,MB_OK,"Device initialize.","FGHook message:",0,0,0);
break;

#ifdef DEBUG
case FG_DIOC_DEBUG:
break;
#endif

case FG_DIOC_INSTALL_HOOK:
#ifdef DEBUG
dout<<"Now install hook..."<<endl;
#endif
if((PrevHookProc=IFSMgr_InstallFileSystemApiHook(HookProc))==NULL)
ErrorHandler(FG_ERR_INSTALL_HOOK_FAIL);
protFileList.bDelBak=(UINT)pDIOCParams->dioc_InBuf &amp
0x1; //Get del &amp
write proteciton options.
protFileList.bWriteBak=(((UINT)pDIOCParams->dioc_InBuf &amp
0x2)== 0x2);
break;

case FG_DIOC_UNINSTALL_HOOK:
if(PrevHookProc &amp;&amp
IFSMgr_RemoveFileSystemApiHook(HookProc)==0)
PrevHookProc=NULL;
break;

case FG_DIOC_GET_HWND:
hAppWnd=*((HANDLE *)pDIOCParams->dioc_InBuf); //Retrieve hwnd of main window of win32 app.
break;

case FG_DIOC_FLUSH_PROTECTED_FILE_INFO: //==FG_DIOC_READ_PROTECTED_FILE_INFO
//Flush file information by reread from ini file.
protFileList.Empty();
if(pDIOCParams->dioc_InBuf)
strcpy(iniFilePath,(char *)pDIOCParams->dioc_InBuf);
else if(!*iniFilePath) strcpy(iniFilePath, "ProtFile.ini"); //default ini path.
#ifdef DEBUG
dout<<"INI Path:"<<iniFilePath<<endl;
#endif
ReadProtectedFileInfo(iniFilePath);
break;

case FG_DIOC_ADD_PROTECTED_FILE:
//Add new protected file.
protFileList.Add((PROTECTED_FILE *)pDIOCParams->dioc_InBuf);
break;

case FG_DIOC_REMOVE_PROTECTED_FILE:
protFileList.Remove((char *)pDIOCParams->dioc_InBuf);
break;

case FG_DIOC_EXTRA_INFO:
protFileList.bDelBak=(UINT)pDIOCParams->dioc_InBuf &amp
0x1; //Get del &amp
write proteciton options.
protFileList.bWriteBak=(((UINT)pDIOCParams->dioc_InBuf &amp
0x2)== 0x2);
maxBakNum=(UINT)pDIOCParams->dioc_OutBuf;
break;

case FG_SET_DEVICE_BUSY:
bAppReqBusy=(BOOL)pDIOCParams->dioc_InBuf;
break;
}

_asm clc
return 0;
}

VOID FGHookDevice::PM_API_Entry(VMHANDLE hVM, CLIENT_STRUCT* pRegs)
{
}

//Hook Procedure: all protection is done though this function.
// Argument : pIFSFunc pfn
// address of the function which will perform this file operation.
// Argument : int fn
// number of the function which will perform this file operation.
// Argument : int CodePage
// current code page.
// Argument : pioreq pir
// It is the parameter to be passed to FSD function pfn.
// In many cases, pir->ir_ppath contain ParsedPath.
int _cdecl HookProc(pIFSFunc pfn, int fn, int Drive, int ResType, int CodePage, pioreq pir)
{
struct _QWORD res;
BOOL bLogHandle=FALSE; //Determine whether to add a handle to handle table(use in IFSFN_OPEN);

//bAppReqBusy: Win32 application of fileguard request busy. bBusy: used to prevent reentry.
if(bAppReqBusy || bBusy)
goto EXIT;

bBusy=TRUE;

if(protFileList.bIsHideOn &amp;&amp
(fn==IFSFN_FILEATTRIB || fn==IFSFN_DIR || fn==IFSFN_SEARCH || fn==IFSFN_RENAME))
{
//Hide a file:
if(protFileList.IsUnderProtection(Drive, pir->ir_ppath, PT_HIDE))
{
bBusy=FALSE;
return (IFSFN_DIR? ERROR_PATH_NOT_FOUND : ERROR_FILE_NOT_FOUND);
}
}


switch(fn)
{
case IFSFN_DELETE:
{
//do delete protection:

if(!protFileList.bIsDelOn &amp;&amp
!protFileList.bIsHideOn)
//If there is not protected file has protection type of PT_DELETE or PT_HIDE, skip.
break;

if(DoDeleteProtection(pir, Drive, CodePage)!=ERROR_SUCCESS)
{
bBusy=FALSE;
return pir->ir_error;
}
break;
} //case IFSFN_DELETE

case IFSFN_RENAME:
{
//prevent moving protected file to recycled.

if(!protFileList.bIsDelOn &amp;&amp
!protFileList.bIsHideOn)
//If there is not protected file has protection type of PT_DELETE or PT_HIDE, skip.
break;

//Is the file being renamed to the recycle?
if(!recycledPathList.IsUnderProtection(Drive, pir->ir_ppath2)
|| DoDeleteProtection(pir, Drive, CodePage)==ERROR_SUCCESS)
break;

bBusy=FALSE;
return pir->ir_error;
} //case IFSFN_RENAME

case IFSFN_OPEN:
{
//If a file is opened with ACTION_REPLACEEXISTING, content of the file will be lost.
//so prevent this.
//And prevent opening hidden file.

//Determine whether or not to log open handle:
PROTECTED_FILE *pProtFile;
if(!(pProtFile=protFileList.IsUnderProtection(Drive, pir->ir_ppath)))
break;
else if(pProtFile->PF_type&amp;(PT_READ|PT_DELETE))
bLogHandle=TRUE;

//determine whether the file is under protection.
if(!(protFileList.bIsHideOn || protFileList.bIsDelOn) || !(pProtFile=protFileList.IsUnderProtection(Drive, pir->ir_ppath, PT_DELETE|PT_HIDE)))
break;

if(!(ACTION_REPLACEEXISTING&amp;pir->ir_options) &amp;&amp
!(pProtFile->PF_type&amp;PT_HIDE))
//the file is not to be hidden and it is not opened with ACTION_REPLACEEXISTING, skip.
break;

if(pProtFile->PF_type&amp;PT_HIDE)
{
//protect hidden file.
bBusy=FALSE;
pir->ir_error=ERROR_FILE_NOT_FOUND;
return pir->ir_error;
}
else if(!protFileList.bDelBak)
{
//deny file operation.
ShellPostError(FG_ERR_WARNING, FG_WARN_PT_DELETE)
//Send a warning.
bBusy=FALSE;
pir->ir_error=ERROR_ACCESS_DENIED;
return pir->ir_error;
}

//protect the file by rename it to *.BAK .
char pBCSPath[MAX_PATH+1];
UniToBCSPathEx((PUCHAR)pBCSPath,pir->ir_ppath->pp_elements,Drive,MAX_PATH,CodePage,&amp;res);
if(FileRename(pBCSPath)==ERROR_SUCCESS)
{
//The file exists, so recreate it.
WORD error;
BYTE action;
HANDLE h=R0_OpenCreateFile(TRUE,pBCSPath,0,ATTR_NORMAL,ACTION_IFEXISTS_FAIL|ACTION_IFNOTEXISTS_CREATE,0,&amp;error,&amp;action);
R0_CloseFile(h,&amp;error);
}
break;
} //case IFSFN_OPEN

case IFSFN_WRITE:
{
//do write protection.

if(!protFileList.bIsWriteOn)
//If there is not protected file has protection type of PT_WRITE, skip.
break;

//sometimes, a process writes zero bytes only to verify.
if(pir->ir_length==0) break;

//get full path.
int drive=Drive;
if(!GetFullNameByHandle(pir,drive,ResType,CodePage,pPPath, FALSE))
break;

//determine whether the file is under protection.
if(!protFileList.IsUnderProtection(drive, pPPath, PT_WRITE))
break;

if(!protFileList.bWriteBak)
{
//Deny write.
ShellPostError(FG_ERR_WARNING, FG_WARN_PT_WRITE)
//Send a warning.
bBusy=FALSE;
pir->ir_error=ERROR_ACCESS_DENIED;
return pir->ir_error;
}

//protect the file by copying it to the .BAK file.
char pBCSPath[MAX_PATH+1];
UniToBCSPathEx((PUCHAR)pBCSPath,pPPath->pp_elements,Drive,MAX_PATH,CodePage,&amp;res);
if(FileBackupByHandle(pir,drive,ResType,CodePage,pBCSPath)!=ERROR_SUCCESS &amp;&amp
FileBackup(pBCSPath)!=ERROR_SUCCESS)
{
//if fail to back up the file then deny access.
bBusy=FALSE;
pir->ir_error=ERROR_ACCESS_DENIED;
return pir->ir_error;
}
break;
} //case IFSFN_WRITE

case IFSFN_READ:
{
//prevent process to read protected file.

//Read protection is not on or it is a pagging file.
if(!protFileList.bIsReadOn)
break;

//Get full path.
int drive=Drive;
if(!GetFullNameByHandle(pir,drive,ResType,CodePage,pPPath, FALSE))
break;

//determine whether the file is under protection.
if(!protFileList.IsUnderProtection(drive, pPPath, PT_READ))
break;

//deny read
ShellPostError(FG_ERR_WARNING, FG_WARN_PT_READ)
//Send a warning.
bBusy=FALSE;
pir->ir_error=ERROR_ACCESS_DENIED;
return pir->ir_error;

break;
} //case IFSFN_READ

}

bBusy=FALSE;
EXIT:
int nRetVal=(*PrevHookProc)(pfn,fn,Drive,ResType,CodePage,pir);

//Win32 application of fileguard request busy.
if(bAppReqBusy)
return nRetVal;

//log open handle.
if(bLogHandle)
openHTable.Add(pir->ir_fh, Drive, pir->ir_ppath);

//if find or file is closed, delete the handle in handle table.
if(fn==IFSFN_FINDCLOSE)
findHTable.Delete(pir->ir_fh);
else if(fn==IFSFN_CLOSE &amp;&amp
pir->ir_flags==CLOSE_FINAL)
openHTable.Delete(pir->ir_fh);

if(!bBusy &amp;&amp
protFileList.bIsHideOn &amp;&amp
!nRetVal &amp;&amp
(fn==IFSFN_FINDNEXT || fn==IFSFN_FINDOPEN))
{
//Hide file in file operation FINDOPEN &amp
FINDNEXT.

bBusy=TRUE;

int drive=Drive;
_WIN32_FIND_DATA *findData;

//Get search path:
switch(fn)
{
case IFSFN_FINDOPEN:
memcpy(pPPath, pir->ir_ppath, IFSPathSize(pir->ir_ppath)+sizeof(WCHAR));
findHTable.Add(pir->ir_fh, Drive, pPPath);
break;
case IFSFN_FINDNEXT:
if(!GetFullNameByHandle(pir, drive, ResType, CodePage, pPPath, TRUE))
{
bBusy=FALSE;
return nRetVal;
}
break;
}
//Now we will change the search path to file path which is found by FINDOPEN or FINDNEXT.

//get file directory from search path by removing the last component:
pPPath->pp_totalLength-=IFSLastElement(pPPath)->pe_length;

//get full path by adding file name to file directory.
findData=(_WIN32_FIND_DATA *)pir->ir_data;
IFSLastElement(pPPath)->pe_length=wstrlen(findData->cFileName)+sizeof(WCHAR);
memcpy(IFSLastElement(pPPath)->pe_unichars, findData->cFileName, IFSLastElement(pPPath)->pe_length);
StringUpper((WCHAR *)IFSLastElement(pPPath)->pe_unichars, IFSLastElement(pPPath)->pe_length-sizeof(WCHAR));
pPPath->pp_totalLength+=IFSLastElement(pPPath)->pe_length;
*(WCHAR *)((char *)pPPath+pPPath->pp_totalLength)=NULL;

//determine whether the file is under protection.
if(protFileList.IsUnderProtection(drive, pPPath, PT_HIDE))
{
bBusy=FALSE;

//now we are going to hide the protected file...
if(fn==IFSFN_FINDOPEN)
{
//if it is FINDOPEN operation, we should return the next file.

//using IFSMgr_Ring0_FileIO to find the next file.
_WIN32_FIND_DATA_BCS bcsFindData;
BOOL retVal;
retVal=R0_FindNextFile(pir->ir_fh, &amp;bcsFindData, (PWORD)&amp;pir->ir_error);

if(retVal)
{
//if the next file is found, convert _WIN32_FIND_DATA_BCS (the find data return by IFSMgr_Ring0_FileIO) to _WIN32_FIND_DATA ( the find data used by FS_FINDOPEN).
memcpy(pir->ir_data, &amp;bcsFindData, sizeof(_WIN32_FIND_DATA_BCS)-sizeof(bcsFindData.cFileName)-sizeof(bcsFindData.cAlternateFileName));
BCSToUni(((_WIN32_FIND_DATA *)pir->ir_data)->cFileName, bcsFindData.cFileName, strlen((char *)bcsFindData.cFileName), CodePage, &amp;res);
((_WIN32_FIND_DATA *)pir->ir_data)->cFileName[res.ddLower]=0;
BCSToUni(((_WIN32_FIND_DATA *)pir->ir_data)->cAlternateFileName, bcsFindData.cAlternateFileName, strlen((char *)bcsFindData.cAlternateFileName), CodePage, &amp;res);
((_WIN32_FIND_DATA *)pir->ir_data)->cAlternateFileName[res.ddLower]=0;
}
return retVal;
}
else goto EXIT; //if it is FINDNEXT operation, go on to find next file.
}
bBusy=FALSE;
}

return nRetVal;
}

//Protected file on file delete, rename operation.
//Return value: return ERROR_SUCCESS indicates that the protected file has been back up, and
// the file operation can be continue. Otherwise the file operation should stop.
WORD DoDeleteProtection(ioreq *pir, int Drive, int CodePage)
{
struct _QWORD res;
char pBCSPath[MAX_PATH+1];
PROTECTED_FILE *pProtFile;
if(pir->ir_attr&amp;FILE_FLAG_WILDCARDS || pir->ir_attr&amp;FILE_FLAG_HAS_STAR)
{
//Deal with file name with wildcards.

//Convert from ParsedPath to BCS path.
UniToBCSPathEx((PUCHAR)pBCSPath, pir->ir_ppath->pp_elements, Drive, MAX_PATH, CodePage, &amp;res);

//find first file.
_WIN32_FIND_DATA_BCS bcsFindData;
WORD error;
HANDLE hFind;
hFind=R0_FindFirstFile((PCHAR)pBCSPath, pir->ir_attr, &amp;bcsFindData, &amp;error);

CHAR pFindPath[MAX_PATH];
strcpy(pFindPath, pBCSPath);
_strupr(pFindPath);

while(error==ERROR_SUCCESS)
{
//Get full path by adding file name to file directory.
GetDir(pFindPath);
_strupr((PCHAR)bcsFindData.cFileName);
strcat(pFindPath, (PCHAR)bcsFindData.cFileName);

if((pProtFile=protFileList.IsUnderProtection(pFindPath, PT_DELETE|PT_HIDE))!=NULL)
{
if(pProtFile->PF_type&amp;PT_HIDE)
{
//Protect hidden file.
pir->ir_error=ERROR_FILE_NOT_FOUND;
return pir->ir_error;
}
else if(protFileList.bDelBak)
{
//Deny delete.
if(!FileRename(pFindPath)==ERROR_SUCCESS) //Cannot rename the file, so deny access to the file.
return ERROR_ACCESS_DENIED;
}
else
{
//Back up on delete.
pir->ir_error=ERROR_ACCESS_DENIED;
ShellPostError(FG_ERR_WARNING, FG_WARN_PT_DELETE); //Send a warning.
return pir->ir_error;
}
}

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

} //while(error==ERROR_SUCCESS)

} //if(pir->ir_attr&amp;FILE_FLAG_WILDCARDS || pir->ir_attr&amp;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&amp;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,&amp;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, &amp;findData, &amp;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,&amp;error);

return error;
}

// Function name : FileBackupByHandle
// Backup a file identified by pir->ir_fh &amp
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 ,&amp;error,&amp;action);
if(error!=ERROR_SUCCESS) return error;

char buf[BUF_LEN+1];
DWORD nBytesRead=0,nBytesWrite=0,offset=0;
memcpy(&amp;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) &amp;ifsr)==STATUS_PENDING)
IFSMgr_CompleteAsync((pioreq) &amp;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,&amp;error);

if(error!=ERROR_SUCCESS)
{
retVal=error;
break;
}

offset+=nBytesRead;
}

R0_CloseFile(hNewFile,&amp;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 ,&amp;error,&amp;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 ,&amp;error,&amp;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, &amp;error);
if(error!=ERROR_SUCCESS || !nBytesRead)
{
retVal=error;
break;
}

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

offset+=nBytesRead;
}

R0_CloseFile(hOldFile, &amp;error);
R0_CloseFile(hNewFile,&amp;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 &amp;Drive, int ResType, int CodePage,path_t pPPath, BOOL bFindHandle)
{
//Search in handle table first.
if((bFindHandle &amp;&amp
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( &amp;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) &amp;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,&amp;error,&amp;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=0

nBytesRead=R0_ReadFile(FALSE,hIniFile,buf,BYTES_TO_READ,offset,&amp;error);
if(nBytesRead==0) break;
if(error!=ERROR_SUCCESS)
continue;

UINT pos=0;
//find first '@':
while(*(buf+pos)!='@' &amp;&amp
pos<=BYTES_TO_READ-1)
pos++;
offset+=pos;
do
{
PROTECTED_FILE protFile;

if(StringToFileInfo(buf+pos, &amp;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(&amp;protFile);
}
}
while(1);
}
while(1);

R0_CloseFile(hIniFile,&amp;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,&amp;error,&amp;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, &amp;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, &amp;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, &amp;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, &amp;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>='a' &amp;&amp
s<='z')
s-=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, &amp;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, &amp;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&amp;FG_FILE_FLAG_HAS_STAR) &amp;&amp
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&amp;FG_FILE_FLAG_HAS_STAR) &amp;&amp
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;
}
 
爱元元的哥哥真是个好人。
你怎么把卖钱的代码也拿出来了,呵呵。:)
 
多谢
爱元元的哥哥

VXD好像是在Win98下可以,在win2000下应该怎么办呢?
 
在win9X下若你让别人使用你的机而别人又想荐意搞破坏,那用程序来防止基本上是很难办到的(除非那个人只懂删除这一操作)!
在win2000下可以把硬盘转成ntfs格式,然后对相应的文件,目录设置安全权限,(注意一定不能让搞破坏的人以管理员身份登录,否则他又可以通过重设置安全权限来达到目的)
 
后退
顶部