CEN-XFS 兼容 SP 软件和来自 msxfs.dl 的错误

问题描述 投票:0回答:2

我们正在尝试为 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;

}

整个代码如下;

https://drive.google.com/file/d/1iFV1OFBTPDWCPW9ehXXSnORZJV3PkDF9/view?usp=sharing

还有一件事是违规来自的访问地址。 它是 0xFE555058D 与 WFSOpen 的 HAPP 值相同的地址。

WFSOpen 值也是

我无法弄清楚问题所在。我想我遗漏了一个应该在 xfs 标准中的部分。不幸的是我找不到它是什么。

我该怎么做才能使我的 WFPOpen 流正常工作

在此先感谢您的帮助

c++ sp cen-xfs
2个回答
0
投票

为了快速查看,您似乎还没有初始化 lpHApp 变量,它指向一些垃圾内存,因此在您使用 *lpHApp 取消引用它时会导致访问冲突。 您可以直接传递 WFS_DEFAULT_HAPP(而不是使用 *lpHApp,只需将 WFS_DEFAULT_HAPP 放在函数调用参数中)或者如果您想使用指针变量,您需要先分配一些内存供其引用。


0
投票

lpHapp 值是直接从客户端代码传递过来的,请看下面的创建代码。 WFSCreateHandle 函数返回且没有任何错误,值如下。

© www.soinside.com 2019 - 2024. All rights reserved.