jie_0822
驱动牛犊
驱动牛犊
  • 注册日期2002-08-22
  • 最后登录2004-08-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2836回复:5

对WORD文档(.DOC )的写控制

楼主#
更多 发布于:2002-11-12 20:33
请教高手:
    我在filemon中对IRP_MJ_WRITE进行处理,可控制用记事本打开的TXT文件, 同样在IRP_MJ_WRITE中却不能控制WORD打开的.DOC 文档。观察了一下filemon, 感觉WORD 保存文件时,会产生临时文件,先将数据写入临时文件中成功后再进行改名操作 , 但同样的
我在IRP_MJ_SET_INFORMATION中控制改名操作,WORD 同样可以对写入的内容进行保存。 所以我现在无法控制WORD 的写操作。  我想请问各位高手如何实现对WORD文档只能读取但是不能修改其中的内容。
望各位高手能解答!!!!

最新喜欢:

ljmmaryljmmar...
zgc7622
驱动小牛
驱动小牛
  • 注册日期2003-02-24
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分136分
  • 威望15点
  • 贡献值0点
  • 好评度13点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-12-15 21:08
我也遇到了这个问题!!那位高手知道呢???
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2003-12-16 21:23
文件系统版块,也讨论过,不过好象没什么效果。。。。。。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
guyu_susa
驱动牛犊
驱动牛犊
  • 注册日期2003-10-29
  • 最后登录2004-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-12-17 13:50
word文档用的是重命名方式进行保存操作。所以还要判断IRP_MJ_SET_INFORMATION里的FileRenameInformation,它的目的文件是不是你要禁止写的文件。IRP_MJ_WRITE最好留着,win2k上的word好像会在重命名不成功时用它来写。
另,我有一次曾让word认为打开的文件是只读文件。我觉得那样最好。但我忘了是怎么做的了。
guyu_susa
驱动牛犊
驱动牛犊
  • 注册日期2003-10-29
  • 最后登录2004-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-12-17 13:59
重命名中关键在于判断目的文件名是不是你要禁止保存的word文档。
你可以试一下下面的代码。我在NT、2K上试过。可以用。
typedef struct {
    BOOLEAN Replace;
    HANDLE RootDir;
    ULONG FileNameLength;
    WCHAR FileName[1];

} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;

void processSimRename(char *destname,char * filename,PIRP irp,PFILE_RENAME_INFORMATION renameInfo)
{
WCHAR FileNameBuffer[MAXPATHLEN];
WCHAR * NewNameBuffer;
WCHAR * prefix;
ULONG prefixLength;
ULONG length;
length = 0;
mbstowcs(FileNameBuffer,filename,strlen(filename));
prefix = wcsrchr(FileNameBuffer, (int) L\'\\\\\');
if (prefix == NULL) {
// strcpy(destname,\"C:\\\\\");
       return;
} else {
       length = prefixLength = ((prefix - FileNameBuffer) + 1)* sizeof(WCHAR);
}
length += (wcslen(renameInfo->FileName) + 1) * sizeof(WCHAR);
NewNameBuffer = ExAllocatePool(PagedPool, length/*, \"tset\"*/);
if (!NewNameBuffer) { // ? no memory of any type?
// strcpy(destname,\"D:\\\\\");
return ;
}
RtlZeroMemory(NewNameBuffer, length);
(void) wcsncpy(NewNameBuffer, FileNameBuffer, prefixLength);
wcscat(NewNameBuffer, renameInfo->FileName);
//把wchar转化为char
memset(destname,0,MAXPATHLEN);
wcstombs(destname,NewNameBuffer,/*wcslen(NewNameBuffer)*/MAXPATHLEN);
ExFreePool(NewNameBuffer);
}

void processFQRename(char *destname,PIRP irp,PIO_STACK_LOCATION irpSp,PFILE_RENAME_INFORMATION renameInfo)
{
WCHAR * NewNameBuffer;
ULONG startOffset = 0;
ULONG prependChars = 0;
ULONG targetLength = 0;
WCHAR DriveLetter=L\'C\';//问题:怎么得到目的盘符?10月14日
char tmpbuf[MAXPATHLEN];
if (renameInfo->FileName[0] != L\'\\\\\') {
destname[0]=0;
       return;
}
if (0 == _wcsnicmp(L\"\\\\DosDevices\\\\\", renameInfo->FileName, 12)) {
           startOffset = 12;
} else {
//添加于12月1日,for \"\\??\\\"
if(0==_wcsnicmp(L\"\\\\??\\\\\",renameInfo->FileName,4))
   startOffset=4;
else
//
       prependChars = 2;
}
targetLength = (renameInfo->FileNameLength/sizeof(WCHAR))-startOffset + prependChars + 1;
            // make room for NULL too
if (targetLength < 4) {
           // must be at least \"D:\\\"            
       return;
}
NewNameBuffer = ExAllocatePool(PagedPool, targetLength * sizeof(WCHAR), ’tset’);
if (NewNameBuffer == NULL) {
destname[0]=0;
return ;
}
if (prependChars) {
       NewNameBuffer[0] = DriveLetter;
       NewNameBuffer[1] = L\':\';
}
// wcsncpy(NewNameBuffer,renameInfo->FileName,renameInfo->FileNameLength/sizeof(WCHAR));
wcsncpy(NewNameBuffer, &renameInfo->FileName[startOffset],targetLength-1);
//把wchar 转换为char
wcstombs(tmpbuf,NewNameBuffer,targetLength-1/*MAXPATHLEN*/);
tmpbuf[targetLength-1]=0;
ExFreePool(NewNameBuffer);
if(0==_strnicmp(\"\\\\??\\\\\",tmpbuf,4))
{
strcpy(destname,tmpbuf+4);
}
else
strcpy(destname,tmpbuf);
}

void GetRenameDestName(char *destname,char * fn,PIRP Irp,PIO_STACK_LOCATION irpSp)
{
PFILE_RENAME_INFORMATION RenameInfo;
RenameInfo = (PFILE_RENAME_INFORMATION) Irp-                        >AssociatedIrp.SystemBuffer;
if (!irpSp->Parameters.SetFile.FileObject) {
       
           processSimRename(destname,fn,Irp,RenameInfo);
} else {
       if (RenameInfo->RootDir == NULL) {
               processFQRename(destname,Irp, irpSp, RenameInfo);
       } else {
        strncpy(destname,fn,3);
        destname[3]=0;
       }
}
}
这段代码我也是从一个老外的文章了看来的。(经过了一些改动)
xjleaf
驱动牛犊
驱动牛犊
  • 注册日期2005-07-12
  • 最后登录2007-09-02
  • 粉丝0
  • 关注0
  • 积分199分
  • 威望25点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-01-05 17:06
to:guyu_susa
这样的通用性不好吧!
我也实现了,但是不是这样实现的!思路其实已经有了,只是大家要细心的去实现.
先将起属性该为只读,然后禁止其修改只读属性.
将属性该为只读和禁止修改属性都是在IRP_MJ_SET_INFORMATION里面,大家要注意的一点是在驱动里面要修改属性,首先要触发该历程,但是在当前层只能是手动出发(勾选只读的时候出发),要想通过驱动自动触发,只能触发下层,也就要构造IRP包了!至于禁止属性修改,就是禁止手动修改,因此在当前层驱动实现即可。
张之勇
游客

返回顶部