c++ CEN-XFS兼容SP软件和msxfs.dl错误

6ovsh4lw  于 2023-03-14  发布在  其他
关注(0)|答案(2)|浏览(134)

我们正在尝试为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 WFPOen。不幸的是,此调用没有成功完成,并且出现异常msxfs.dl
试验流程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获得调用,收集数据并通过管道发送到我们创建的应用程序。WFPOPen如下所示

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;

}

应用程序端代码如下:

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
还有一个问题是访问违规来源的地址访问位置。它是0xFE 555058 D,与WFSOpen.

的HAPP值地址相同
WFSOnen值也是

我没能找出问题所在。我想我遗漏了一个应该在xfs标准中的部分。不幸的是我找不到它是什么。
如何才能使WFPOpen流正常工作
预先感谢你的帮助

js5cn81o

js5cn81o1#

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

wpx232ag

wpx232ag2#

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

相关问题