实施具有CEN-XFS合规性的新服务提供(SP) [英] Implementing NEW service provide (SP) with CEN-XFS compliance

查看:2396
本文介绍了实施具有CEN-XFS合规性的新服务提供(SP)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在试图开发具有CEN XFS合规性的Windows应用程序+设备驱动程序。此外,还有NOOB到WINDOWS应用程序。



http://en.wikipedia.org/wiki/CEN/XFS



简单架构流程:

  Windows应用程序
|
_____________________
| XFS API |
(CEN / XFS SDK DLL)
| |
| XFS SPI |
| _____________________ | --- XFS Manager
|
|
服务提供商(SP)
(设备驱动程序)

功能性,我们最近采取了设备的一个供应商SP的DLL访问其设备,我们能够成功地使用(Eclipse的MINGW为主)我们的Windows应用程序,他们的设备与沟通。



然后我们开始检查一些示例SP源在互联网尝试我们的实现。 ( https://drive.google.com/file/d/0B60pejPe6yiSejRGQ3JnLUl4dzA/view



使用链接源,我们可以编译并创建输出DLL。但是,当我们尝试访问SP时,总是返回错误。

 在Windows示例应用程序中,总是返回的调用(WFSOPEN)的设备(-15 WFS_ERR_INTERNAL_ERROR)或(-29 WFS_ERR_INVALID_SERVPROV)



< FLOW 1:

 应用程序调用到管理器:

hResult = WFSOpen(QuantumT lpszAppID,dwTraceLevel,dwTimeOut,VER_SPI_REQUIRE,& SrvcVersion,& SPIVersion,& hService);

经理转换WFSOPEN调用SP的WFPOPEN电话:

HRESULT WINAPI WFPOpen(HSERVICE hService,LPSTR lpszLogicalName,HAPP HAPP,LPSTR lpszAppID,DWORD dwTraceLevel,DWORD dwTimeOut,HWND的HWND,
的requestId请求ID,hPROVIDER hProvider,DWORD dwSPIVersionsRequired,LPWFSVERSION lpSPIVersion,DWORD dwSrvcVersionsRequired,LPWFSVERSION lpSrvcVersion)

通过上面的呼叫流程我得到(-29 WFS_ERR_INVALID_SERVPROV)作为我的应用程序$ b $错误b

试用FLow 2(SP中的WFPOPEN仅删除WINAPI界面):

 应用程序调用到经理:
HRESULT = WFSOpen(QuantumT,HAPP,lpszAppID,dwTraceLevel,dwTimeOut,VER_SPI_REQUIRE,&安培; SrvcVersion,&安培; SPIVersion,与放; hService);

经理转换WFSOPEN调用SP的WFPOPEN电话:
HRESULT WFPOpen(HSERVICE hService,LPSTR lpszLogicalName,HAPP HAPP,LPSTR lpszAppID,DWORD dwTraceLevel,DWORD dwTimeOut,HWND的HWND,
的requestId请求ID,hPROVIDER hProvider,DWORD dwSPIVersionsRequired,LPWFSVERSION lpSPIVersion,DWORD dwSrvcVersionsRequired,LPWFSVERSION lpSrvcVersion)

通过上面的呼叫流程我得到(-15 WFS_ERR_INTERNAL_ERROR)作为从马槽我的应用程序的错误,即使我强迫的成功,从SP返回经理

我困惑为什么MANAGER返回不同的错误代码到应用程序如果WINAPI



WINDOWS应用程式范例的连结:
https://drive.google.com/open?id=0B60pejPe6yiSUEp1N2xzdGlXWFE&authuser=0



SP Source(VS C ++ 2010 Express):
https:// drive.google.com/file/d/0B60pejPe6yiSejRGQ3JnLUl4dzA/view



XFSMANAGER INSTALLER:
ftp://ftp.cencenelec.eu/CEN/WhatWeDo/Fields/ICT/eBusiness /WS/XFS/CWA15748/XFS310SDKInstall.zip



但是,whneni调查我创建的DLL和DLL之间的工作(使用PE Studio)。我看到一些不同。
DLL由ME创建:

  _WFPCancelAsyncRequest @ 8, - ,1, - , - ,rdata:0x00001096 
_WFPClose @ 12, - ,2, - , - rdata:0x00001005
_WFPDeregister @ 20, - ,3, - , - rdata:0x00001140
_WFPExecute @ 24, , - , - ,rdata:0x00001131
_WFPGetInfo @ 24, - ,5, - , - rdata:0x000010EB
_WFPLock @ 16, - ,6, - , - rdata:0x00001023
_WFPOpen @ 52, - ,7, - , - ,rdata:0x0000102D
_WFPRegister @ 20, - ,8, - , - rdata:0x00001073
_WFPSetTraceLevel @ 8, - ,9 , - , - ,rdata:0x0000113B
_WFPUnloadService @ 0, - ,10, - , - rdata:0x0000100A
_WFPUnlock @ 12, - ,11, - , - rdata:0x00001082

供应商创建的DLL:

  WFPCancelAsyncRequest, - ,1, - , - ,rdata:0x0000C450 
WFPClose, - ,2, - , - ,rdata:0x0000C6E0
WFPDeregister, - ,3, - ,rdata:0x0000C7F0
WFPExecute, - ,4, - , - ,rdata:0x0000C970
WFPGetInfo, - ,5, - , - rdata:0x0000DFA0
WFPLock, 6, - , - ,rdata:0x0000E490
WFPOpen, - ,7, - , - rdata:0x0000C030
WFPRegister, - ,8, - , - rdata:0x0000E590
WFPSetTraceLevel, - ,9, - , - ,rdata:0x0000E710
WFPUnloadService, - ,10, - , - rdata:0x0000E770
WFPUnlock, - ,11, - , - rdata:0x0000E8F0

即使我确定Extern已添加到我的标题中。

  #ifdef __cplusplus 
externC{
#endif
SPITEST_API HRESULT WINAPI WFPCancelAsyncRequest(HSERVICE hService,REQUESTID RequestID);
SPITEST_API HRESULT WINAPI WFPClose(HSERVICE hService,HWND hWnd,REQUESTID ReqID);
SPITEST_API HRESULT WINAPI WFPDeregister(HSERVICE hService,DWORD dwEventClass,HWND hWndReg,HWND hWnd,REQUESTID ReqID);
SPITEST_API HRESULT WINAPI WFPExecute(HSERVICE hService,DWORD dwCommand,LPVOID lpCmdData,DWORD dwTimeOut,HWND hWnd,REQUESTID ReqID);
SPITEST_API HRESULT WINAPI WFPGetInfo(HSERVICE hService,DWORD dwCategory,LPVOID lpQueryDetails,DWORD dwTimeOut,HWND hWnd,REQUESTID ReqID);
SPITEST_API HRESULT WINAPI WFPLock(HSERVICE hService,DWORD dwTimeOut,HWND hWnd,REQUESTID ReqID);
SPITEST_API HRESULT WINAPI WFPOpen(HSERVICE hService,LPSTR lpszLogicalName,HAPP HAPP,LPSTR lpszAppID,DWORD dwTraceLevel,DWORD dwTimeOut,HWND的HWND,请求ID请求ID,HPROVIDER hProvider,DWORD dwSPIVersionsRequired,LPWFSVERSION lpSPIVersion,DWORD dwSrvcVersionsRequired,LPWFSVERSION lpSrvcVersion);
SPITEST_API HRESULT WINAPI WFPRegister(HSERVICE hService,DWORD dwEventClass,HWND hWndReg,HWND hWnd,REQUESTID ReqID);
SPITEST_API HRESULT WINAPI WFPSetTraceLevel(HSERVICE hService,DWORD dwTraceLevel);
SPITEST_API HRESULT WINAPI WFPUnloadService();
SPITEST_API HRESULT WINAPI WFPUnlock(HSERVICE hService,HWND hWnd,REQUESTID ReqID);
#ifdef __cplusplus
};
#endif

Update1:​​
$ b

根据电压提供的指标验证我的代码,我没有在代码流中发现任何错误。



应用程式代码:

  #include< stdio.h> 
#include< conio.h>
#include< string.h>
#include< stdlib.h>
#include< windows.h>
#includeXFSAPI.H

const char g_szClassName [] =myWindowClass;

DWORD dwThreadID;
HANDLE hThread;
HANDLE hEvent [2];
HWND hwnd;
#define VER_SPI_REQUIRE 0x0B020003
#define VER_XFS_REQUIRE 0x0B020003

HSERVICE hService;


HRESULT SessionOpen(void)
{
WFSVERSION WFSVersion;
DWORD dwVersionRequired;
HRESULT hResult;
HAPP hApp = 0;
LPSTR lpszAppID;
DWORD dwTraceLevel = 0;
WFSVERSION SrvcVersion,SPIVersion;


hApp = WFS_DEFAULT_HAPP;
lpszAppID =(LPSTR)XFSTEST;

dwVersionRequired = VER_XFS_REQUIRE;
hResult = WFSStartUp(dwVersionRequired,& WFSVersion);

printf(\\\
Start up result =%ld \\\
,hResult);
printf(\\\
wVersion:%d \\\
LowVersion:%d \\\
wHighVersion:%d \\\
szDescription:%s \\\
szSystemStatus:%s \\\
,WFSVersion.wVersion ,WFSVersion.wLowVersion,WFSVersion.wHighVersion,WFSVersion.szDescription,WFSVersion.szSystemStatus);
if(hResult!= WFS_SUCCESS)
{
return hResult;
}

hResult = WFSOpen(QuantumT,
hApp,
lpszAppID,
dwTraceLevel,
WFS_INDEFINITE_WAIT,
VER_SPI_REQUIRE ,
& SrvcVersion,
& SPIVersion,
& hService);

if(hResult == WFS_SUCCESS)
{
printf(SrvcVersion Records:\\\
wVersion:%d \\\
LowVersion:%d \\\
wHighVersion:% d \\\
szDescription:%s \\\
szSystemStatus:%s \\\
,SrvcVersion.wVersion,SrvcVersion.wLowVersion,SrvcVersion.wHighVersion,SrvcVersion.szDescription,SrvcVersion.szSystemStatus);
}
printf(SrvcVersion Records:\\\
wVersion:%d \\\
LowVersion:%d \\\
wHighVersion:%d \\\
szDescription:%s \\\
szSystemStatus:%s \\\
,SrvcVersion.wVersion,SrvcVersion.wLowVersion,SrvcVersion.wHighVersion,SrvcVersion.szDescription,SrvcVersion.szSystemStatus);
printf(SPIVersion Records:\\\
wVersion:%d \\\
LowVersion:%d \\\
wHighVersion:%d \\\
szDescription:%s \\\
szSystemStatus:%s \\\
SPIVersion.wVersion,SPIVersion.wLowVersion,SPIVersion.wHighVersion,SPIVersion.szDescription,SPIVersion.szSystemStatus);
printf(\\\
HService Address;%ld,hService);
Sleep(1000);

return hResult;
}



LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
LPWFSRESULT lpwfsResult;

switch(msg)
{

case WFS_SERVICE_EVENT:
case WFS_USER_EVENT:
case WFS_SYSTEM_EVENT:
case WFS_EXECUTE_EVENT:

lpwfsResult =(LPWFSRESULT)lParam;
printf(\\\
Event Received from XFS);
WFSFreeResult(lpwfsResult);
break;

默认值:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 0;
}


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{

HRESULT hResult = 0 ;
WNDCLASSEX wc;

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground =(HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL,IDI_APPLICATION);

if(!RegisterClassEx(& wc))
{
MessageBox(NULL,Window Registration Failed!,Error!,
MB_ICONEXCLAMATION | MB_OK );
return 0;
}

hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
窗口的标题,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,240,120,
NULL,NULL,hInstance,NULL);

if(hwnd == NULL)
{
MessageBox(NULL,Window Creation Failed!,Error!,
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

printf(\\\
Session Open In progress);


hResult = SessionOpen();
printf(\\\
SessionOpen result =%d,hResult);
getch();
return 0;
}

SP的WFPOpen通话



HRESULT 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)
{
WFSRESULT * lpWFSResult;
HRESULT result;

SYSTEMTIME st;
HRESULT rt;

GetSystemTime(& st);
OutputDebugString(INTO WFPOpen);

printf(\\\
msxfs DLL load\\\
);
char strManager [MAX_PATH];
if(0 == RegGetManagerPath(strManager,sizeof(strManager))){
if(0 == GetSystemDirectoryA(strManager,sizeof(strManager)))
return WFS_ERR_INTERNAL_ERROR;
strcat_s(strManager,\\msxfs.dll);
}
if(0!= LoadManagerFunction(strManager))
return WFS_ERR_INTERNAL_ERROR;
printf(\\\
msxfs DLL load completed\\\
);
result = m_pfnWFMAllocateBuffer(sizeof(WFSRESULT),WFS_MEM_ZEROINIT,(void **)& lpWFSResult);
// result = WFMAllocateBuffer(sizeof(WFSRESULT),WFS_MEM_SHARE | WFS_MEM_ZEROINIT,& lpWFSResult);
if(result!= WFS_SUCCESS)
return WFS_ERR_INTERNAL_ERROR;
printf(\\\
WFPOpen Process start\\\
);
if(!g_hMutex ||!g_hLib ||!g_hMsgQueueEvent)return WFS_ERR_INTERNAL_ERROR;
if(IsCancel(ReqID))return WFS_ERR_CANCELED;
CAutoLock AutoLock(g_hMutex);

if(g_hDefThread){
InterlockedIncrement(& g_lDefThreadRef);
return WFS_SUCCESS;
} else {
bQuit = FALSE;
g_hDefThread = BEGINTHREADEX(NULL,0,DefThread,NULL,0,& g_dwDefThreadId);
if(!g_hDefThread || g_dwDefThreadId == 0)
return WFS_ERR_CANCELED;
InterlockedIncrement(& g_lDefThreadRef);
}


lpSPIVersion-> wVersion =(unsigned short)dwCombineVersion(LOW_APIVERSUPPORT,HIGH_APIVERSUPPORT);
lpSPIVersion-> wLowVersion = wFloattoVersion(LOW_APIVERSUPPORT);
lpSPIVersion-> wHighVersion = wFloattoVersion(HIGH_APIVERSUPPORT);


lpSrvcVersion-> wVersion =(unsigned short)dwCombineVersion(LOW_APIVERSUPPORT,HIGH_APIVERSUPPORT);
lpSrvcVersion-> wLowVersion = wFloattoVersion(LOW_APIVERSUPPORT);
lpSrvcVersion-> wHighVersion = wFloattoVersion(HIGH_APIVERSUPPORT);

strcpy(lpSPIVersion-> szDescription,shHicom);
strcpy(lpSPIVersion-> szSystemStatus,Good);
CServiceBasic * pServiceBasic = new CServiceBasic;
pServiceBasic-> m_hService = hService;

UINT uNameLen = min(256,strlen(lpszLogicalName));
memcpy(pServiceBasic-> m_strLogicalName,lpszLogicalName,uNameLen);
pServiceBasic-> m_strLogicalName [uNameLen] ='\0';

pServiceBasic-> m_pServiceThread = hApp;
pServiceBasic-> m_strAppID = lpszAppID;
pServiceBasic-> m_dwTraceLevel = dwTraceLevel;
pServiceBasic-> m_dwTimeOut = dwTimeOut;
pServiceBasic-> m_hWND = hWnd;
pServiceBasic-> m_lpRequestID = new REQUESTID;
* pServiceBasic-> m_lpRequestID = ReqID;
pServiceBasic-> m_bAutoDeleteRequestID = TRUE;
pServiceBasic-> m_hLib = hProvider;
pServiceBasic-> m_dwSrvcVersionsRequired = dwSrvcVersionsRequired;
pServiceBasic-> m_lpSrvcVersion = lpSrvcVersion;

if(WAIT_OBJECT_0!= WaitForSingleObject(g_hMsgQueueEvent,INFINITE))
return WFS_ERR_CANCELED;
BOOL b = PostThreadMessage(g_dwDefThreadId,WM_NI_SP_Open,WPARAM(pServiceBasic),0);
if(!b){
return WFS_ERR_CANCELED;
}
printf(WFPOpen return with success\\\
);
return WFS_SUCCESS;
}

使用onSpOpen的服务线程回调

  LRESULT OnSPOpen(WPARAM wParam,LPARAM lParam)
{
LRESULT lr = WFS_SUCCESS;
// return WFS_SUCCESS;
CServiceBasic * pServiceBasic =(CServiceBasic *)wParam;
if(pServiceBasic){
int nLock = pServiceBasic-> QueryLogicalServiceLock(pServiceBasic-> m_strLogicalName);
if(nLock< = 0){
UINT uBytes = min(strlen(pServiceBasic-> m_strLogicalName),sizeof(g_strLogicalName)-1);
memcpy(g_strLogicalName,pServiceBasic-> m_strLogicalName,uBytes);
g_strLogicalName [uBytes] ='\0';
// lr = pServiceBasic-> OpenDev(g_strLogicalName,g_osp);
lr = WFS_SUCCESS;
} else {
lr = WFS_ERR_CANCELED;
}
} else {
lr = WFS_ERR_INVALID_HSERVICE;
}
WFSRESULT * pResult = NULL;
m_pfnWFMAllocateBuffer(sizeof(WFSRESULT),WFS_MEM_ZEROINIT,(void **)& pResult);
pResult-> RequestID = * pServiceBasic-> m_lpRequestID;
pResult-> hService = pServiceBasic-> m_hService;
pResult-> hResult = lr; //表示结果。
GetLocalTime(& pResult-> tsTimestamp);
HWND hWnd = pServiceBasic-> m_hWND;
delete pServiceBasic;
BOOL b = :: PostMessage(hWnd,WFS_OPEN_COMPLETE,NULL,(LONG)pResult);
printf(SP Open确保它通过POST MESSAGE\\\
发送WFS_OPEN_COMPLETE);

return 0;
}

执行期间的控制台输出 b
$ b

C:\gtkTrials\StandAloneApp\Debug> StandAloneApp.exe



(从StandAloneApp打印) strong>

 会话打开进行中
启动结果= 0(WFS_SUCCESS)

wVersion:3
LowVersion:257
wHighVersion:39171
sz描述:WOSA / XFS API v3.00 / v2.00
szSystemStatus:
执行DllMainProcessAttach



(从SP DLL打印)


$ b b

  msxfs DLL加载
DLL路径:C:\ xfs_sdks\SDK\DLL\msxfs.dll

msxfs DLL load completed

WFPOpen进程启动
执行DllMainProcessAttach
WFPOpen返回成功
SP打开,确保它通过POST发送WF​​S_OPEN_COMPLETE MESSAGE



(从StandAloneApp列印)

  SrvcVersion Records:
wVersion:3
LowVersion:5121
wHighVersion:3
szDescription:α╝`
szSystemStatus:
SPIVersion记录:
wVersion:3
低版本:5121
wHighVersion:3
sz描述:shHicom
szSystemStatus:好


b $ b HService地址; 1
SessionOpen result = -15(WFS_ERR_INTERNAL_ERROR)

请理解此问题。

解决方案

这些导出比较看起来像是使用错误的调用约定。

更改所有SPI输出从WINAPI到__cdecl(只删除WINAPI作为__cdecl是默认),它应该有区别。



为什么你的例子中的返回码的区别:

第一个例子甚至没有到WFPOpen调用,因为管理器没有找到正确的WFPOpen符号后DLL加载 - >无效的ServiceProvider。



第二种接缝进入WFPOpen,但第一个测试失败 - > INTERNAL_ERROR:

if(!g_hMutex ||!g_hLib ||!g_hMsgQueueEvent)return WFS_ERR_INTERNAL_ERROR;



因此,在调用约定修复后,您需要更详细地检查您的初始化代码,以了解为什么它失败。



通过查看那些测试的全局变量发现,你永远不应该从DLLMain中执行的代码调用LoadLibrary。



您可以创建互斥体并保存DLL模块句柄在DLLMain中,并在WFPOpen开始时执行初始化的其余初始化,如库加载。



不能简单地从WFPOpen返回WFS_SUCCESS。
下面是最小实现的一个非常粗略的描述:

1.填充版本结构(其中一个参数是一个指针)

2 。返回WFS_SUCCESS或错误代码。

3.如果WFPOpen返回WFS_SUCCESS,则调用者将预期异步响应。因此,您必须向给定的(hwnd参数)消息窗口句柄发送包含所有必需信息的WFS_OPEN_COMPLETE消息。



查看以下文档中的更多详细信息是第6章​​)。

ftp://ftp.cenorm.be/CWA/CEN/WS-XFS/CWA16374/CWA16374-1-2011_December.pdf


We are trying to develop windows application + device driver with CEN XFS compliance.Also, NOOB to WINDOWS applications.

http://en.wikipedia.org/wiki/CEN/XFS

simple architectural flow:

   Windows Application
           |
  _____________________
 |      XFS APIs         |
    (CEN/XFS SDK DLL)
 |                       |
 |      XFS SPIs         |
 |_____________________|---XFS Manager   
           |
           |
    Service providers (SP)
    (DEVICE DRIVER)

To understand the SP's functionality, we recently took one of the device vendors SP's DLL for accessing their device and we were able to successfully communicate with their device using our windows application(Eclipse MINGW based).

Then we started to check for some sample SP source in internet to try our implementation. (https://drive.google.com/file/d/0B60pejPe6yiSejRGQ3JnLUl4dzA/view)

With the linked source we were able to compile and create an output DLL. But , when we tried to access the SP, It always return error.

With windows sample application, we just tried to open the device with call (WFSOPEN) which always returned (-15 WFS_ERR_INTERNAL_ERROR ) or (-29 WFS_ERR_INVALID_SERVPROV)

Trial FLow 1 :

    Application Call to manager:

        hResult = WFSOpen(    "QuantumT",    hApp,lpszAppID,    dwTraceLevel,dwTimeOut,    VER_SPI_REQUIRE,&SrvcVersion,&SPIVersion,&hService);    

    manager translates WFSOPEN call to SP's WFPOPEN call:

        HRESULT WINAPI  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)

    With above call flow I get (-29 WFS_ERR_INVALID_SERVPROV) as an error for my application

Trial FLow 2 (Just removed WINAPI interface for WFPOPEN in SP):

    Application Call to manager:
        hResult = WFSOpen(    "QuantumT",    hApp,lpszAppID,    dwTraceLevel,dwTimeOut,    VER_SPI_REQUIRE,&SrvcVersion,&SPIVersion,&hService);    

    manager translates WFSOPEN call to SP's WFPOPEN call:
        HRESULT  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)

With above call flow I get (-15 WFS_ERR_INTERNAL_ERROR ) as an error for my application from manger even though i force SUCCESS as return from SP to manager 

I am confused why MANAGER returns different error codes to application if WINAPI definition is removed from WFPOPEN.

Link for WINDOWS APPLICATION SAMPLE: https://drive.google.com/open?id=0B60pejPe6yiSUEp1N2xzdGlXWFE&authuser=0

SP Source (VS C++ 2010 Express): https://drive.google.com/file/d/0B60pejPe6yiSejRGQ3JnLUl4dzA/view)

XFSMANAGER INSTALLER: ftp://ftp.cencenelec.eu/CEN/WhatWeDo/Fields/ICT/eBusiness/WS/XFS/CWA15748/XFS310SDKInstall.zip

However, whneni investigate between working DLL and DLL created by me(Using PE Studio). I see some differnece. DLL Created by ME:

_WFPCancelAsyncRequest@8,-,1,-,-,.rdata:0x00001096
_WFPClose@12,-,2,-,-,.rdata:0x00001005
_WFPDeregister@20,-,3,-,-,.rdata:0x00001140
_WFPExecute@24,-,4,-,-,.rdata:0x00001131
_WFPGetInfo@24,-,5,-,-,.rdata:0x000010EB
_WFPLock@16,-,6,-,-,.rdata:0x00001023
_WFPOpen@52,-,7,-,-,.rdata:0x0000102D
_WFPRegister@20,-,8,-,-,.rdata:0x00001073
_WFPSetTraceLevel@8,-,9,-,-,.rdata:0x0000113B
_WFPUnloadService@0,-,10,-,-,.rdata:0x0000100A
_WFPUnlock@12,-,11,-,-,.rdata:0x00001082

Vendor created DLL:

WFPCancelAsyncRequest,-,1,-,-,.rdata:0x0000C450
WFPClose,-,2,-,-,.rdata:0x0000C6E0
WFPDeregister,-,3,-,-,.rdata:0x0000C7F0
WFPExecute,-,4,-,-,.rdata:0x0000C970
WFPGetInfo,-,5,-,-,.rdata:0x0000DFA0
WFPLock,-,6,-,-,.rdata:0x0000E490
WFPOpen,-,7,-,-,.rdata:0x0000C030
WFPRegister,-,8,-,-,.rdata:0x0000E590
WFPSetTraceLevel,-,9,-,-,.rdata:0x0000E710
WFPUnloadService,-,10,-,-,.rdata:0x0000E770
WFPUnlock,-,11,-,-,.rdata:0x0000E8F0

Even I made sure that Extern is added in my header.

#ifdef __cplusplus
extern "C" {
#endif
SPITEST_API HRESULT  WINAPI WFPCancelAsyncRequest(HSERVICE hService, REQUESTID RequestID);
SPITEST_API HRESULT  WINAPI WFPClose(HSERVICE hService, HWND hWnd, REQUESTID ReqID);
SPITEST_API HRESULT  WINAPI WFPDeregister(HSERVICE hService, DWORD dwEventClass, HWND hWndReg, HWND hWnd, REQUESTID ReqID);
SPITEST_API HRESULT  WINAPI WFPExecute(HSERVICE hService, DWORD dwCommand, LPVOID lpCmdData, DWORD dwTimeOut, HWND hWnd, REQUESTID ReqID);
SPITEST_API HRESULT  WINAPI WFPGetInfo(HSERVICE hService, DWORD dwCategory, LPVOID lpQueryDetails, DWORD dwTimeOut, HWND hWnd, REQUESTID ReqID);
SPITEST_API HRESULT  WINAPI WFPLock(HSERVICE hService, DWORD dwTimeOut, HWND hWnd, REQUESTID ReqID);
SPITEST_API HRESULT  WINAPI 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);
SPITEST_API HRESULT  WINAPI WFPRegister(HSERVICE hService,  DWORD dwEventClass, HWND hWndReg, HWND hWnd, REQUESTID ReqID);
SPITEST_API HRESULT  WINAPI WFPSetTraceLevel(HSERVICE hService, DWORD dwTraceLevel);
SPITEST_API HRESULT  WINAPI WFPUnloadService();
SPITEST_API HRESULT  WINAPI WFPUnlock(HSERVICE hService, HWND hWnd, REQUESTID ReqID);
#ifdef __cplusplus
};
#endif

Update1:

based on the pointers giver by Voltage verified my code and i did not find any erro in the code flow.

Application code:

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include "XFSAPI.H"

const char g_szClassName[] = "myWindowClass";

DWORD   dwThreadID;
HANDLE  hThread;
HANDLE  hEvent[2];
HWND hwnd;
#define VER_SPI_REQUIRE     0x0B020003
#define VER_XFS_REQUIRE     0x0B020003

HSERVICE        hService;


HRESULT SessionOpen(void)
{
    WFSVERSION      WFSVersion;
    DWORD           dwVersionRequired;
    HRESULT         hResult;
    HAPP            hApp=0;
    LPSTR           lpszAppID;
    DWORD           dwTraceLevel = 0;
    WFSVERSION      SrvcVersion,SPIVersion;


    hApp = WFS_DEFAULT_HAPP;
    lpszAppID = (LPSTR)"XFSTEST";

    dwVersionRequired = VER_XFS_REQUIRE;
    hResult = WFSStartUp(dwVersionRequired, &WFSVersion);

    printf("\nStart up result = %ld \n",hResult);
    printf("\n wVersion: %d \n LowVersion: %d \n wHighVersion: %d \n szDescription: %s \n szSystemStatus: %s \n",WFSVersion.wVersion,WFSVersion.wLowVersion,WFSVersion.wHighVersion,WFSVersion.szDescription,WFSVersion.szSystemStatus);
    if(hResult != WFS_SUCCESS)
    {
        return hResult;
    }

    hResult = WFSOpen(  "QuantumT",
            hApp,
            lpszAppID,
            dwTraceLevel,
            WFS_INDEFINITE_WAIT,
            VER_SPI_REQUIRE,
            &SrvcVersion,
            &SPIVersion,
            &hService);

    if(hResult == WFS_SUCCESS)
    {
        printf("SrvcVersion Records: \n wVersion: %d \n LowVersion: %d \n wHighVersion: %d \n szDescription: %s \n szSystemStatus: %s \n",SrvcVersion.wVersion,SrvcVersion.wLowVersion,SrvcVersion.wHighVersion,SrvcVersion.szDescription,SrvcVersion.szSystemStatus);
    }
    printf("SrvcVersion Records: \n wVersion: %d \n LowVersion: %d \n wHighVersion: %d \n szDescription: %s \n szSystemStatus: %s \n",SrvcVersion.wVersion,SrvcVersion.wLowVersion,SrvcVersion.wHighVersion,SrvcVersion.szDescription,SrvcVersion.szSystemStatus);
    printf("SPIVersion Records: \n wVersion: %d \n LowVersion: %d \n wHighVersion: %d \n szDescription: %s \n szSystemStatus: %s \n",SPIVersion.wVersion,SPIVersion.wLowVersion,SPIVersion.wHighVersion,SPIVersion.szDescription,SPIVersion.szSystemStatus);
    printf("\nHService Address ; %ld",hService);
    Sleep(1000);

    return hResult;
}



LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
        LPWFSRESULT             lpwfsResult;

        switch ( msg )
        {

            case WFS_SERVICE_EVENT:
            case WFS_USER_EVENT:
            case WFS_SYSTEM_EVENT:
            case WFS_EXECUTE_EVENT:

                lpwfsResult = (LPWFSRESULT) lParam;
                printf("\nEvent Received from XFS" );
                WFSFreeResult(lpwfsResult);
            break;

            default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{

    HRESULT hResult = 0;
    WNDCLASSEX wc;

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    printf("\nSession Open In progress");


    hResult = SessionOpen();
    printf("\nSessionOpen result = %d",hResult);
    getch();
    return 0;
}

SP's WFPOpen call:

HRESULT 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)
{
        WFSRESULT * lpWFSResult;
        HRESULT  result;

        SYSTEMTIME   st;
        HRESULT  rt;

        GetSystemTime(&st);
        OutputDebugString("INTO  WFPOpen");

        printf("\nmsxfs DLL load\n");
        char strManager[MAX_PATH];
        if(0==RegGetManagerPath(strManager, sizeof(strManager))){
            if(0==GetSystemDirectoryA(strManager, sizeof(strManager)))
              return WFS_ERR_INTERNAL_ERROR;
            strcat_s(strManager, "\\msxfs.dll");
          }
          if(0!=LoadManagerFunction(strManager))
            return WFS_ERR_INTERNAL_ERROR;
          printf("\nmsxfs DLL load completed\n");
        result = m_pfnWFMAllocateBuffer(sizeof(WFSRESULT), WFS_MEM_ZEROINIT, (void**)&lpWFSResult);
        //result = WFMAllocateBuffer(sizeof(WFSRESULT), WFS_MEM_SHARE|WFS_MEM_ZEROINIT, &lpWFSResult);
        if(result!=WFS_SUCCESS)
            return WFS_ERR_INTERNAL_ERROR;
        printf("\nWFPOpen Process start\n");
        if(!g_hMutex ||!g_hLib ||!g_hMsgQueueEvent) return WFS_ERR_INTERNAL_ERROR;
        if(IsCancel(ReqID)) return WFS_ERR_CANCELED;
        CAutoLock AutoLock(g_hMutex);

      if(g_hDefThread){
            InterlockedIncrement(&g_lDefThreadRef);
            return WFS_SUCCESS;
        }else{
        bQuit=FALSE;
            g_hDefThread=BEGINTHREADEX(NULL, 0, DefThread, NULL, 0, &g_dwDefThreadId);
        if(!g_hDefThread ||g_dwDefThreadId==0)
          return WFS_ERR_CANCELED;
            InterlockedIncrement(&g_lDefThreadRef);
        }


        lpSPIVersion->wVersion=(unsigned short) dwCombineVersion(LOW_APIVERSUPPORT,HIGH_APIVERSUPPORT);
        lpSPIVersion->wLowVersion=wFloattoVersion(LOW_APIVERSUPPORT);
        lpSPIVersion->wHighVersion=wFloattoVersion(HIGH_APIVERSUPPORT);


        lpSrvcVersion->wVersion=(unsigned short ) dwCombineVersion(LOW_APIVERSUPPORT,HIGH_APIVERSUPPORT);
        lpSrvcVersion->wLowVersion=wFloattoVersion(LOW_APIVERSUPPORT);
        lpSrvcVersion->wHighVersion=wFloattoVersion(HIGH_APIVERSUPPORT);

        strcpy(lpSPIVersion->szDescription,"shHicom");
        strcpy(lpSPIVersion->szSystemStatus,"Good");
        CServiceBasic *pServiceBasic=new CServiceBasic;
        pServiceBasic->m_hService=hService;

        UINT uNameLen=min(256, strlen(lpszLogicalName));
        memcpy(pServiceBasic->m_strLogicalName, lpszLogicalName, uNameLen);
        pServiceBasic->m_strLogicalName[uNameLen]='\0';

        pServiceBasic->m_pServiceThread=hApp;
        pServiceBasic->m_strAppID=lpszAppID;
        pServiceBasic->m_dwTraceLevel=dwTraceLevel;
        pServiceBasic->m_dwTimeOut=dwTimeOut;
        pServiceBasic->m_hWND=hWnd;
        pServiceBasic->m_lpRequestID=new REQUESTID;
        *pServiceBasic->m_lpRequestID=ReqID;
        pServiceBasic->m_bAutoDeleteRequestID=TRUE;
        pServiceBasic->m_hLib=hProvider;
        pServiceBasic->m_dwSrvcVersionsRequired=dwSrvcVersionsRequired;
        pServiceBasic->m_lpSrvcVersion=lpSrvcVersion;

      if(WAIT_OBJECT_0!=WaitForSingleObject(g_hMsgQueueEvent, INFINITE))
        return WFS_ERR_CANCELED;
      BOOL b=PostThreadMessage(g_dwDefThreadId, WM_NI_SP_Open, WPARAM(pServiceBasic), 0);
      if(!b){
            return WFS_ERR_CANCELED;
      }
      printf("WFPOpen return with success\n");
    return WFS_SUCCESS;
}

Service thread callback with onSpOpen

LRESULT OnSPOpen(WPARAM wParam, LPARAM lParam)
{
    LRESULT lr=WFS_SUCCESS;
    //return WFS_SUCCESS;
    CServiceBasic *pServiceBasic=(CServiceBasic*)wParam;
    if(pServiceBasic){
    int nLock=pServiceBasic->QueryLogicalServiceLock(pServiceBasic->m_strLogicalName);
    if(nLock<=0){
      UINT uBytes=min(strlen(pServiceBasic->m_strLogicalName), sizeof(g_strLogicalName)-1);
      memcpy(g_strLogicalName, pServiceBasic->m_strLogicalName, uBytes);
      g_strLogicalName[uBytes]='\0';
      //lr=pServiceBasic->OpenDev(g_strLogicalName, g_osp);
      lr=WFS_SUCCESS;
    }else{
        lr=WFS_ERR_CANCELED;
        }
    }else{
        lr=WFS_ERR_INVALID_HSERVICE;
    }
    WFSRESULT *pResult=NULL;
    m_pfnWFMAllocateBuffer(sizeof(WFSRESULT), WFS_MEM_ZEROINIT, (void**)&pResult);
    pResult->RequestID=*pServiceBasic->m_lpRequestID;
    pResult->hService=pServiceBasic->m_hService;
    pResult->hResult=lr;//indicate the result.
    GetLocalTime(&pResult->tsTimestamp);
    HWND hWnd=pServiceBasic->m_hWND;
    delete pServiceBasic;
  BOOL b=::PostMessage(hWnd, WFS_OPEN_COMPLETE, NULL, (LONG)pResult);
  printf ("SP Open made sure it sends WFS_OPEN_COMPLETE via POST MESSAGE\n");

  return 0;
}

Console Output during execution

C:\gtkTrials\StandAloneApp\Debug>StandAloneApp.exe

(Print from StandAloneApp )

Session Open In progress 
Start up result = 0  (WFS_SUCCESS)

 wVersion: 3
 LowVersion: 257
 wHighVersion: 39171
 szDescription: WOSA/XFS API v3.00/v2.00
 szSystemStatus:
DllMainProcessAttach is executed

(Print from SP DLL )

msxfs DLL load  
DLL path : C:\xfs_sdks\SDK\DLL\msxfs.dll

msxfs DLL load completed

WFPOpen Process start
DllMainProcessAttach is executed
WFPOpen return with success
SP Open made sure it sends WFS_OPEN_COMPLETE via POST MESSAGE

(Print from StandAloneApp )

SrvcVersion Records:
 wVersion: 3
 LowVersion: 5121
 wHighVersion: 3
 szDescription: α╝`
 szSystemStatus:
SPIVersion Records:
 wVersion: 3
 LowVersion: 5121
 wHighVersion: 3
 szDescription: shHicom
 szSystemStatus: Good



HService Address ; 1
SessionOpen result = -15 (WFS_ERR_INTERNAL_ERROR)

Request some pointers on understanding this issue.

解决方案

Those export comparisons look like you are using wrong calling convention.
Change all your SPI exports from WINAPI to __cdecl (just remove the WINAPI as __cdecl is the default) and it should make the difference.

And why the difference in return codes in your examples:
First example doesn't even get to the WFPOpen call, because the manager doesn't find the correct WFPOpen symbol after DLL load -> Invalid ServiceProvider.

Second case seams to go in to the WFPOpen, but the first test fails -> INTERNAL_ERROR:
if(!g_hMutex ||!g_hLib ||!g_hMsgQueueEvent) return WFS_ERR_INTERNAL_ERROR;

So after calling convention fix you need to check your initailization code in more detail to see why it fails.

One thing I found out by looking those tested globals is that you should NEVER ever call LoadLibrary from code that is executed in DLLMain.

You could just create the mutex and save the DLL module handle in DLLMain and do rest of the initialization like library loading at the begining of the WFPOpen.

One can't simply return WFS_SUCCESS from WFPOpen. The following is a very coarse description of the minimal implementation:
1. Fill the version structure (One of the parameters is a pointer for this)
2. Return WFS_SUCCESS or an error code.
3. If WFPOpen returns WFS_SUCCESS then an asynchronous response is expected by the caller. So you have to send that WFS_OPEN_COMPLETE message with all the required information to the given (hwnd parameter) message window handle.

See more detailed information from the following document (SPI API is chapter 6).
ftp://ftp.cenorm.be/CWA/CEN/WS-XFS/CWA16374/CWA16374-1-2011_December.pdf

这篇关于实施具有CEN-XFS合规性的新服务提供(SP)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆