我正在使用GetProcAddress来访问标准的Isapi Filter DLL方法 - GetFilterVersion 方法,该方法采用指向HTTP_FILTER_VERSION结构的指针。
https://msdn.microsoft.com/en-us/library/ms525822(v=vs.90).aspx
https://msdn.microsoft.com/en-us/library/ms525465(v=vs.90).aspx
我已经针对我编写的工作 Isapi 过滤器测试了代码,它工作正常。我根据供应商的 Isapi 过滤器调试代码(我无法访问源代码或 dll 本身以外的任何内容),并且出现异常"访问冲突写入位置"。可能是什么问题? (两个 Isapi 筛选器都在 IIS 中工作。
//Attempted to define function ptr several ways
typedef BOOL(__cdecl * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
//typedef BOOL( * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
//typedef BOOL(WINAPI * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
void arbitraryMethod()
{
HINSTANCE hDLL; // Handle to DLL
TRIRIGAISAPIV lpfnDllFunc2; // Function pointer
DWORD lastError;
BOOL uReturnVal2;
hDLL = LoadLibrary(L"iisWASPlugin_http.dll"); //vendor's dll
//hDLL = LoadLibrary(L"KLTWebIsapi.dll //my dll
if (hDLL != NULL)
{
lpfnDllFunc2 = (TRIRIGAISAPIV)GetProcAddress(hDLL, "GetFilterVersion");
if (!lpfnDllFunc2)
{
lastError = GetLastError();
// handle the error
FreeLibrary(hDLL);
//return 1;
}
else
{
HTTP_FILTER_VERSION pVer = { 6 };
//Call the function via pointer; Works with my dll, fails with vendor's
uReturnVal2 = lpfnDllFunc2(&pVer);
//................ HELP!!!!!!!!!!!!!
}
}
}
我看到的一个问题是您的函数指针声明不正确。
根据Microsoft文档,GetFilterVersion 的原型为:
BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer);
WINAPI
是一个实际上定义为__stdcall
的Windows宏,因此您在使用__cdecl
时错误地声明了函数指针。
威纳比是什么意思?
因此,您的声明应该是:
typedef BOOL(__stdcall * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
可能是自定义过滤器实际上填充了一些额外的结构字段。
您可以尝试增加结构的大小以查看是否有效,例如:
struct HTTP_FILTER_VERSION_EXTRA {
HTTP_FILTER_VERSION v;
char[1024] extra;
};
HTTP_FILTER_VERSION_EXTRA ver;
ver.v.dwServerFilterVersion = 6;
uReturnVal2 = lpfnDllFunc2(&ver.v);
WinAPI 结构有时允许版本控制,因此可以添加字段。如果函数没有检查(或不知道)实际的结构版本,它可能会尝试使用可能与提供的扩展版本不同的扩展版本 - 如果提供的结构的大小小于 func 尝试使用的结构版本,则可能会发生不好的事情。
还要检查 DLL 是 64 位还是 32 位。您不能通过 64 位应用程序使用 32 位 DLL,反之亦然(但我希望在 LoadLibrary 调用期间已经失败)。