CEN XFS準拠のwindowsアプリケーション+デバイスドライバの開発を試みています。また、NOOBからWINDOWSアプリケーションへ。
http://en.wikipedia.org/wiki/CEN/XFS
シンプルなアーキテクチャ フロー:
Windows Application
|
_____________________
| XFS APIs |
(CEN/XFS SDK DLL)
| |
| XFS SPIs |
|_____________________|---XFS Manager
|
|
Service providers (SP)
(DEVICE DRIVER)
SP の機能を理解するために、デバイス ベンダーの 1 つ SP の DLL を使用してデバイスにアクセスし、Windows アプリケーション (Eclipse MINGW ベース) を使用してデバイスと正常に通信することができました。
次に、実装を試すために、インターネットでサンプル SP ソースを確認し始めました。( https://drive.google.com/file/d/0B60pejPe6yiSejRGQ3JnLUl4dzA/view )
リンクされたソースを使用して、出力 DLL をコンパイルして作成することができました。しかし、SPにアクセスしようとすると、常にエラーが返されます。
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)
トライアルフロー 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
トライアル フロー 2 (SP で WFPOPEN の WINAPI インターフェイスを削除しただけ):
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
WINAPI 定義が WFPOPEN から削除された場合、MANAGER がアプリケーションに異なるエラー コードを返す理由がわかりません。
Windows アプリケーションのサンプルへのリンク: https://drive.google.com/open?id=0B60pejPe6yiSUEp1N2xzdGlXWFE&authuser=0
SP ソース (VS C++ 2010 Express): https://drive.google.com/file/d/0B60pejPe6yiSejRGQ3JnLUl4dzA/view )
XFSMANAGER インストーラー: ftp://ftp.cencenelec.eu/CEN/WhatWeDo/Fields/ICT/eBusiness/WS/XFS/CWA15748/XFS310SDKInstall.zip
ただし、動作中の DLL と私が作成した DLL (PE Studio を使用) を調査するときは、次のようにします。若干の違いが見られます。私が作成した DLL:
_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
ベンダーが作成した 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
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
アップデート1:
Voltageによって提供されたポインターに基づいて、コードが検証され、コードフローにエラーは見つかりませんでした。
アプリケーション コード:
#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 の 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("\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;
}
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;
}
実行中のコンソール出力
C:\gtkTrials\StandAloneApp\Debug>StandAloneApp.exe
( 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
(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
( 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)
この問題を理解するための指針を求めてください。