我们正在尝试为 ALM 设备实施一个小型 XFS 服务提供程序,但我从 msxfs.dl 中得到一个例外。
在目前的情况下,我知道我做错了什么或遗漏了什么,但我找不到。 我请求帮助
请参阅下面的技术细节。
安装了门户上的 xfs 管理器并检查了注册表字段。
新服务提供商的注册表字段创建如下。
我的sp dll是AlarmSP.dll
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\XFS\SERVICE_PROVIDERS\BVK-ALM00]
"dllname"="AlarmSP.dll"
"vendor_name"="BVK"
"version"="3.02"
[HKEY_USERS\.DEFAULT\XFS\LOGICAL_SERVICES\BVK-ALM00]
"class"="ALM"
"provider"="BVK-ALM00"
我可以用测试客户端代码加载我的 sp dll (AlarmSp.dll)。我可以在 sp 上看到调用 __cdecl WFPOpen。不幸的是,这个调用没有成功完成,并且从 msxfs.dll 中得到一个异常
试用流程 1:客户代码
HRESULT hr,hrLog = 0;
char LogStr[1000] = "";
DWORD version = 0x0001ff03;
WFSVERSION ver;
//HAPP hApp;
WFSVERSION WFSVersion1;
WFSVERSION WFSVersion2;
HAPP handleHapp = NULL;
LPHAPP lpHApp = &handleHapp;
WriteLog("CardReaderDevice::OpenXFS Started...", TRACE_LOG);
hr = WFSStartUp(version, &ver);
if (hr != WFS_SUCCESS)
{
if (hr != WFS_ERR_ALREADY_STARTED)
return hr;
}
else
{
sprintf_s(LogStr, "xfs version = %X %X %X %s %s", ver.wVersion, ver.wHighVersion, ver.wLowVersion, ver.szDescription, ver.szSystemStatus);
WriteLog(LogStr, INFO_LOG);
}
WriteLog("CardReaderDevice::OpenXFS Before WFSOpen", TRACE_LOG);
hrLog = WFSCreateAppHandle(lpHApp);
if (hrLog != WFS_SUCCESS){
WriteLog("CardReaderDevice::WFSCreateAppHandle Can not create Handle", ERROR_LOG);
LOGRetCode(hrLog, ERROR_LOG);
*lpHApp = WFS_DEFAULT_HAPP;
}
try
{
sprintf(cDeviceLogicalName, "BVK-ALM00");// //BVK-ALM00
hr = WFSOpen(cDeviceLogicalName,
*lpHApp, //hApp, //WFS_DEFAULT_HAPP, //HAPP hApp,
"CardReaderSession", //NULL, //LPSTR lpszAppID,
WFS_TRACE_ALL_API, //NULL, //DWORD dwTraceLevel,
1000000, //DWORD dwTimeOut, //YANLIZCA KART OKUYUCU ÝÇÝN 10 SN
0x00030203, //DWORD dwSrvcVersionsRequired,
&WFSVersion1, //LPWFSVERSION lpSrvcVersion,
&WFSVersion2, //LPWFSVERSION lpSPIVersion,
&hServiceCARDREADER // LPHSERVICE lphService
);
}
关于 SP 实现细节 .
sp实现由一个*.dll文件和*.exe工程组成。 *.dll 文件导出 XFS 接口中指定的函数。这个 dll 收到来自 xfsmanager 的调用,收集并发送数据到我们通过管道创建的应用程序。 WFPOP如下
HRESULT __cdecl WFPOpen(HSERVICE hService, LPSTR lpszLogicalName, HAPP hApp, \
LPSTR lpszAppID, DWORD dwTraceLevel, DWORD dwTimeOut, HWND hWnd, REQUESTID ReqID, \
HPROVIDER hProvider, DWORD dwSPIVersionsRequired, LPWFSVERSION lpSPIVersion, \
DWORD dwSrvcVersionsRequired, LPWFSVERSION lpSrvcVersion)
{
HRESULT hr = WFS_SUCCESS;
hr = spi_version_match(dwSPIVersionsRequired, dwSrvcVersionsRequired, \
lpSPIVersion, lpSrvcVersion);
if (WFS_SUCCESS != hr)
{
return hr;
}
static Shareobject obj;
obj.hWnd = hWnd;
obj.hService = hService;
obj.RequestID = ReqID;
HANDLE pipe = NULL;
// This call blocks until a client process reads all the data
PipeClient PipeObj;
pipe = PipeObj.CreatePipe();
if(pipe != NULL)
PipeObj.WriteToPipe(pipe,(LPVOID)&obj,sizeof(Shareobject));
else
{
// cannot write
}
// Close the pipe (automatically disconnects client too)
CloseHandle(pipe);
Sleep(5000);
return 0;
}
Application端代码如下:
int main()
{
std::cout << "Hello World!\n";
wcout << "Connecting to pipe..." << endl;
HANDLE hPipe;
DWORD dwRead;
hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists...
1,
1024 * 16,
1024 * 16,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) {
// write_text_to_log_file1("Failed to create outbound pipe instance.");
// look up error code here using GetLastError()
system("pause");
return 1;
}
// write_text_to_log_file1("Waiting for a client to connect to the pipe...");
Shareobject* objectToRead;
LPVOID buffer = (LPVOID)malloc(sizeof(Shareobject)+1);
// This call blocks until a client process connects to the pipe
if (ConnectNamedPipe(hPipe, NULL) != FALSE) // wait for someone to connect to the pipe
{
while (ReadFile(hPipe, buffer, sizeof(Shareobject), &dwRead, NULL) != FALSE)
{
/* add terminating zero */
std::cout << "has been read";
break;
}
}
wcout << "Reading data from pipe..." << endl;
objectToRead = (Shareobject*)buffer;
WFSRESULT* pResult;
HRESULT hr1 = WFMAllocateBuffer(sizeof(WFSRESULT), WFS_MEM_ZEROINIT | WFS_MEM_SHARE, (void**)&pResult);
HRESULT hr2 = WFMAllocateMore(sizeof(WFSRESULT), pResult, (void**)&pResult->lpBuffer);
pResult->RequestID = objectToRead->RequestID; //*pServiceBasic->m_lpRequestID;
pResult->hService = objectToRead->hService;//pServiceBasic->m_hServic
GetLocalTime(&pResult->tsTimestamp);
pResult->hResult = WFS_SUCCESS;
while (1)
{
Sleep(1000);
BOOL b = ::PostMessage(objectToRead->hWnd, WFS_OPEN_COMPLETE, NULL, (LONG)pResult);
if (b) break;
}
return 0;
}
整个代码如下;
还有一件事是违规来自的访问地址。 它是 0xFE555058D 与 WFSOpen 的 HAPP 值相同的地址。
我无法弄清楚问题所在。我想我遗漏了一个应该在 xfs 标准中的部分。不幸的是我找不到它是什么。
我该怎么做才能使我的 WFPOpen 流正常工作
在此先感谢您的帮助