为什么这样做法不能将一个变量传入参数里面

时间:2022-12-12 16:17:49
我的做法是用hook禁止某个文件打开,当点击资源管理窗口里的某个文件时,文件名m_pathname传入到createfile()的lpFileName参数里来实现禁止该文件打开



DETOUR_TRAMPOLINE(HANDLE WINAPI MyCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile), CreateFileW);
HANDLE WINAPI NewCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)

{




CString m_pathname;
m_pathname=qaws;


//CString str="D:\\plm";



WCHAR szText[32]; 
swprintf(szText, L"%s",m_pathname); 


if(wcsncmp(lpFileName,szText,wcslen(szText)) ==0)
{

return MyCreateFileW(lpFileName,0,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);

}




但上面的做法发现m_pathname并没有传入到lpFileName参数里,而如果直接写入文件路径CString str="D:\\plm",该文件就打不开了,用OutputDebugString发现m_pathname的路径和str是一样的,为什么str可以传入,m_pathname却不可以??

42 个解决方案

#1


他为什么会传入到那个参数里?

#2


ls是什么意思呢?

#3


#4


这话代码看不出m_pathname哪里传到lpFileName里了

#5


讲错,不是传入,是比较文件路径是否一样

#6


WCHAR szText[32]; 
swprintf(szText, L"%s",m_pathname); 

你这里又是宽字符又是ansi/dbcs,有点混乱了。

这个工程是unicode的么?
用CStringW

#7


但为什么直接写入文件路径CString str="D:\\plm“就可以而变量m_pathname却不可以?

#8


变量m_pathname里放的是啥内容

#9


比如我点击D盘里的文件plm.txt,文件路径D:\\plm.txt传入m_pathname,当我点击c盘
里的poi.txt文件,C:\\poi.txt传入m_pathname

#10


用MessageBoxW输出一下得到的szText看看是不是这个内容.

#11


当我点击D盘的文件plm,输出的文件路径跟CString str="D:\\plm“是一样的,狂晕

#12


CComBSTR m_pathname;
m_pathname = "C:\\poi.txt";

#13


to ls 
m_pathname是变量啊,我点哪个文件,那个文件名字就会传入m_pathname

#14


再问一次,是不是不是unicode工程?
用用CStringW

#15


不是unicode工程,我需要把它改为unicode工程吗?

#16


应该不用,但是CString换成CStringW看看
有可能是字符结尾0字符个数不够引起的

#17


直接这样写:
{
if(wcsicmp(lpFileName, qaws) == 0)
{
return MyCreateFileW(lpFileName,0,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

#18


to cnzdys

把它改为WCHAR szText[256]; 
swprintf(szText, L"%s",qaws); 


if(wcsicmp(lpFileName, szText) == 0)
{

return MyCreateFileW(lpFileName,0,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

还是一样不成功,不明白明明路径是一样的,str成功,qaws却不成功,晕死了

#19


把lpFileName和szText的内容16进制方式打印出来看,遇到两个连续的0结束打印

#20


你按照我在17楼的写法来试看看是不是可以成功。

#21


貌似楼主没把关键的代码贴出来,贴出的是无关的部分。

应该还有个函数来设置 qaws 变量吧。 通常这类做法(截获、注入什么什么啦)只能是dll。那么qaws在这个 dll里面是如何定义的也是个关键点。

#22


to cnzdgs 

按你17楼的做法出现错误error C2664: 'wcsicmp' : cannot convert parameter 2 from 'class CString' to 'const unsigned short *'

我把它改成

USES_CONVERSION;

LPCWSTR szText=T2W(str);


if ((wcsicmp(lpFileName, szText) == 0) 
{
}
连原来可以的直接写入路径str="D:\\plm"的方法都不成功了




to whoo 


下面就是得到qaws的代码


CString qaws,str_Name1,str_Name;



CEdit* p = (CEdit*)CEdit::FromHandle(handle6);    

p->GetWindowText(str1);


str=str1.Mid(0,2);


p->SetReadOnly();




  CListCtrl* list = (CListCtrl*)CListCtrl::FromHandle(handle9);


int nItem=list->GetNextItem(-1, LVNI_SELECTED);

   str_Name=list->GetItemText(nItem,0);

   str_Name1=str_Name;

   if (str1.Right(1) != '\\')


{

str1+="\\";

}

   qaws=str1+str_Name1;       //得到文件全路径




#23


error C2664: 'wcsicmp' : cannot convert parameter 2 from 'class CString' to 'const unsigned short *' 


既然没改成unicode工程,那么CString是窄字符串,这里要的参数是宽字符的,CString的地方全改成 CStringW

#24


是不是应该用char[]来保存文件路径,而不是CString?

#25


wchar[]

#26


因为你hook的就是W版API

#27


但如果改成CString会出现很多错误

error C2146: syntax error : missing ';'
error C2501: 'CStringW' : missing storage-class or type specifiers

#28


但如果改成CStringW会出现很多错误 

error C2146: syntax error : missing ';' 
error C2501: 'CStringW' : missing storage-class or type specifiers

#29


Windows下面的API调用的都是W版本的。

#30


引用 29 楼 erac 的回复:
Windows下面的API调用的都是W版本的。


是有转换层的,比如你hook immapi,会发现有的程序走的A版有的是走的W版

#31


hook不好,应为你时时都在监控这个文件,浪费啊

#32


问题还没解决啊

#33


引用 19 楼 Amuro1987218 的回复:
把lpFileName和szText的内容16进制方式打印出来看,遇到两个连续的0结束打印


看出来到底是什么样的不就知道问题了么

#34


引用 33 楼 Amuro1987218 的回复:
引用 19 楼 Amuro1987218 的回复:
把lpFileName和szText的内容16进制方式打印出来看,遇到两个连续的0结束打印 
 

看出来到底是什么样的不就知道问题了么


对这方面不熟悉,请问如何把lpFileName和szText的内容转为16进制?谢了

#35


请各位看看22楼的代码,得到文件路径qaws的方法有错误吗?还是那里出问题了?

#36


如果你的项目不是使用Unicode字符集的,建议把qaws定义为WCHAR qaws[MAX_PATH]这种形式,使用GetWindowTextW来获取文字。另外直接用if(wcsicmp(lpFileName, qaws) == 0)来比较。

#37


如果是在非unicode环境下写unicde处理,下面这一句

swprintf(szText, L"%s",m_pathname);

需要改写一下,方法很多,最简单的是把 %s 改成  %S(小写改成大写), 如下:
swprintf(szText, L"%S", (const char*)m_pathname);

#38


我按上面两位老大的方法做了,还是不行,再回归到我原来的问题,一定是因为我没处理好Unicode和非Unicode字符集之间的转换吗?
还是有别的地方所引起的?我再把原来的代码贴上



CString qaws,str_Name1,str_Name;



CEdit* p = (CEdit*)CEdit::FromHandle(handle6);    

p->GetWindowText(str1);


str=str1.Mid(0,2);


p->SetReadOnly();




  CListCtrl* list = (CListCtrl*)CListCtrl::FromHandle(handle9);


int nItem=list->GetNextItem(-1, LVNI_SELECTED);

   str_Name=list->GetItemText(nItem,0);

   str_Name1=str_Name;

   if (str1.Right(1) != '\\')


{

str1+="\\";

}

       qaws=str1+str_Name1;       //得到文件全路径


DETOUR_TRAMPOLINE(HANDLE WINAPI MyCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile), CreateFileW);
HANDLE WINAPI NewCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)

{



//CString str="D:\\plm";



USES_CONVERSION;

LPCWSTR szText=T2W(qaws);


if(wcsncmp(lpFileName,szText,wcslen(szText)) ==0)
{

return MyCreateFileW(lpFileName,0,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);

}


#39


up

#40


直接这样写试试: 

if(wcsicmp(lpFileName, qaws) == 0) 

return CreateFileW(lpFileName,0,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); 


return CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); 
}

你要封装这两个(CreateFileW和CreateFileA)

#41


我认为你是unicode和ansi之间的问题,可以用OutputDebugString输出一下路径字符串,在debugview里看看

#42


to greatws 

我已经用OutputDebugString查看过很多次了,当我点D盘里的plm文件时,debugview出来的
结果是D:\plm,跟str的路径是一样的,所以我才不明白到底是那里出错了,疯了

#1


他为什么会传入到那个参数里?

#2


ls是什么意思呢?

#3


#4


这话代码看不出m_pathname哪里传到lpFileName里了

#5


讲错,不是传入,是比较文件路径是否一样

#6


WCHAR szText[32]; 
swprintf(szText, L"%s",m_pathname); 

你这里又是宽字符又是ansi/dbcs,有点混乱了。

这个工程是unicode的么?
用CStringW

#7


但为什么直接写入文件路径CString str="D:\\plm“就可以而变量m_pathname却不可以?

#8


变量m_pathname里放的是啥内容

#9


比如我点击D盘里的文件plm.txt,文件路径D:\\plm.txt传入m_pathname,当我点击c盘
里的poi.txt文件,C:\\poi.txt传入m_pathname

#10


用MessageBoxW输出一下得到的szText看看是不是这个内容.

#11


当我点击D盘的文件plm,输出的文件路径跟CString str="D:\\plm“是一样的,狂晕

#12


CComBSTR m_pathname;
m_pathname = "C:\\poi.txt";

#13


to ls 
m_pathname是变量啊,我点哪个文件,那个文件名字就会传入m_pathname

#14


再问一次,是不是不是unicode工程?
用用CStringW

#15


不是unicode工程,我需要把它改为unicode工程吗?

#16


应该不用,但是CString换成CStringW看看
有可能是字符结尾0字符个数不够引起的

#17


直接这样写:
{
if(wcsicmp(lpFileName, qaws) == 0)
{
return MyCreateFileW(lpFileName,0,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

#18


to cnzdys

把它改为WCHAR szText[256]; 
swprintf(szText, L"%s",qaws); 


if(wcsicmp(lpFileName, szText) == 0)
{

return MyCreateFileW(lpFileName,0,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

还是一样不成功,不明白明明路径是一样的,str成功,qaws却不成功,晕死了

#19


把lpFileName和szText的内容16进制方式打印出来看,遇到两个连续的0结束打印

#20


你按照我在17楼的写法来试看看是不是可以成功。

#21


貌似楼主没把关键的代码贴出来,贴出的是无关的部分。

应该还有个函数来设置 qaws 变量吧。 通常这类做法(截获、注入什么什么啦)只能是dll。那么qaws在这个 dll里面是如何定义的也是个关键点。

#22


to cnzdgs 

按你17楼的做法出现错误error C2664: 'wcsicmp' : cannot convert parameter 2 from 'class CString' to 'const unsigned short *'

我把它改成

USES_CONVERSION;

LPCWSTR szText=T2W(str);


if ((wcsicmp(lpFileName, szText) == 0) 
{
}
连原来可以的直接写入路径str="D:\\plm"的方法都不成功了




to whoo 


下面就是得到qaws的代码


CString qaws,str_Name1,str_Name;



CEdit* p = (CEdit*)CEdit::FromHandle(handle6);    

p->GetWindowText(str1);


str=str1.Mid(0,2);


p->SetReadOnly();




  CListCtrl* list = (CListCtrl*)CListCtrl::FromHandle(handle9);


int nItem=list->GetNextItem(-1, LVNI_SELECTED);

   str_Name=list->GetItemText(nItem,0);

   str_Name1=str_Name;

   if (str1.Right(1) != '\\')


{

str1+="\\";

}

   qaws=str1+str_Name1;       //得到文件全路径




#23


error C2664: 'wcsicmp' : cannot convert parameter 2 from 'class CString' to 'const unsigned short *' 


既然没改成unicode工程,那么CString是窄字符串,这里要的参数是宽字符的,CString的地方全改成 CStringW

#24


是不是应该用char[]来保存文件路径,而不是CString?

#25


wchar[]

#26


因为你hook的就是W版API

#27


但如果改成CString会出现很多错误

error C2146: syntax error : missing ';'
error C2501: 'CStringW' : missing storage-class or type specifiers

#28


但如果改成CStringW会出现很多错误 

error C2146: syntax error : missing ';' 
error C2501: 'CStringW' : missing storage-class or type specifiers

#29


Windows下面的API调用的都是W版本的。

#30


引用 29 楼 erac 的回复:
Windows下面的API调用的都是W版本的。


是有转换层的,比如你hook immapi,会发现有的程序走的A版有的是走的W版

#31


hook不好,应为你时时都在监控这个文件,浪费啊

#32


问题还没解决啊

#33


引用 19 楼 Amuro1987218 的回复:
把lpFileName和szText的内容16进制方式打印出来看,遇到两个连续的0结束打印


看出来到底是什么样的不就知道问题了么

#34


引用 33 楼 Amuro1987218 的回复:
引用 19 楼 Amuro1987218 的回复:
把lpFileName和szText的内容16进制方式打印出来看,遇到两个连续的0结束打印 
 

看出来到底是什么样的不就知道问题了么


对这方面不熟悉,请问如何把lpFileName和szText的内容转为16进制?谢了

#35


请各位看看22楼的代码,得到文件路径qaws的方法有错误吗?还是那里出问题了?

#36


如果你的项目不是使用Unicode字符集的,建议把qaws定义为WCHAR qaws[MAX_PATH]这种形式,使用GetWindowTextW来获取文字。另外直接用if(wcsicmp(lpFileName, qaws) == 0)来比较。

#37


如果是在非unicode环境下写unicde处理,下面这一句

swprintf(szText, L"%s",m_pathname);

需要改写一下,方法很多,最简单的是把 %s 改成  %S(小写改成大写), 如下:
swprintf(szText, L"%S", (const char*)m_pathname);

#38


我按上面两位老大的方法做了,还是不行,再回归到我原来的问题,一定是因为我没处理好Unicode和非Unicode字符集之间的转换吗?
还是有别的地方所引起的?我再把原来的代码贴上



CString qaws,str_Name1,str_Name;



CEdit* p = (CEdit*)CEdit::FromHandle(handle6);    

p->GetWindowText(str1);


str=str1.Mid(0,2);


p->SetReadOnly();




  CListCtrl* list = (CListCtrl*)CListCtrl::FromHandle(handle9);


int nItem=list->GetNextItem(-1, LVNI_SELECTED);

   str_Name=list->GetItemText(nItem,0);

   str_Name1=str_Name;

   if (str1.Right(1) != '\\')


{

str1+="\\";

}

       qaws=str1+str_Name1;       //得到文件全路径


DETOUR_TRAMPOLINE(HANDLE WINAPI MyCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile), CreateFileW);
HANDLE WINAPI NewCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)

{



//CString str="D:\\plm";



USES_CONVERSION;

LPCWSTR szText=T2W(qaws);


if(wcsncmp(lpFileName,szText,wcslen(szText)) ==0)
{

return MyCreateFileW(lpFileName,0,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);

}


#39


up

#40


直接这样写试试: 

if(wcsicmp(lpFileName, qaws) == 0) 

return CreateFileW(lpFileName,0,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); 


return CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); 
}

你要封装这两个(CreateFileW和CreateFileA)

#41


我认为你是unicode和ansi之间的问题,可以用OutputDebugString输出一下路径字符串,在debugview里看看

#42


to greatws 

我已经用OutputDebugString查看过很多次了,当我点D盘里的plm文件时,debugview出来的
结果是D:\plm,跟str的路径是一样的,所以我才不明白到底是那里出错了,疯了