diff --git a/harbour/ChangeLog b/harbour/ChangeLog index e98445aae8..f28f40203d 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,37 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-02-13 18:28 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) + * contrib/hbwin/hbwin.h + * contrib/hbwin/hbwin.ch + * contrib/hbwin/win_dllx.c + * contrib/hbwin/win_dll.c + * contrib/hbwin/legacycd.c + * contrib/hbwin/tests/testdll.prg + + Reworked WIN_DLLCALL() and low-level hbwin_dllCall() interfaces. + * WIN_DLLCALL() should be called as follows: + + WIN_DLLCALL( , ... ) -> + + where can be: + { | , | [, [, , ..., ]] } + { [, [, , ..., ]] } + + With above API it's possible to access all low-level options and + merge all possible call types in one call. If passing function ordinal + or name, it will also autodetect UNICODE mode. Autodetection turns + on UNICODE mode for WinCE permanently and for functions ending with 'W'. + + * Call convention, C type and unicode flags are now merged into one + callflag value. + * Unicode flag extended to RAW, ASCII, UTF8, UTF16. + + Added support for UTF-8 and forced raw encoding for char pointer types. + * GETPROCADDRESS() finally moved to legacy source. + + * contrib/hbsms/hbsms.prg + ! Fixed SMS_SEND() to return numeric value when port couldn't + be opened. + 2010-02-13 15:57 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/ChangeLog ! fixed typo diff --git a/harbour/contrib/hbsms/hbsms.prg b/harbour/contrib/hbsms/hbsms.prg index 2d8b94bac4..176ab1a4b6 100644 --- a/harbour/contrib/hbsms/hbsms.prg +++ b/harbour/contrib/hbsms/hbsms.prg @@ -55,7 +55,7 @@ /* NOTE: Source of information: http://www.smssolutions.net/tutorials/gsm/receivesmsat/ - http://www.developershome.com/sms/readSmsByAtCommands.asp + http://www.developershome.com/sms/readSmsByAtCommands.asp [vszakats] */ /* NOTE: As it happens ATM, Harbour doesn't have a unified @@ -83,17 +83,17 @@ STATIC FUNCTION port_rece( h, n, t ) FUNCTION sms_Send( cPort, cPhoneNo, cText, lNotification, cPIN ) LOCAL smsctx - LOCAL lRetVal + LOCAL nRetVal IF ! Empty( smsctx := smsctx_New( cPort ) ) smsctx_PIN( smsctx, cPIN ) - lRetVal := smsctx_Send( smsctx, cPhoneNo, cText, lNotification ) + nRetVal := smsctx_Send( smsctx, cPhoneNo, cText, lNotification ) smsctx_Close( smsctx ) ELSE - lRetVal := .F. + nRetVal := -99 ENDIF - RETURN lRetVal + RETURN nRetVal FUNCTION sms_ReceiveAll( cPort, cPIN ) LOCAL smsctx diff --git a/harbour/contrib/hbwin/hbwin.ch b/harbour/contrib/hbwin/hbwin.ch index a4fe4e1fe2..2d1a8f7916 100644 --- a/harbour/contrib/hbwin/hbwin.ch +++ b/harbour/contrib/hbwin/hbwin.ch @@ -57,41 +57,47 @@ #define HBWIN_CH_ /* WIN_DLLCALL() C calling convention */ -#define HB_WIN_DLL_CALLCONV_CDECL 1 -#define HB_WIN_DLL_CALLCONV_STDCALL 2 +#define HB_WIN_DLL_CALLCONV_STDCALL 0x000000 +#define HB_WIN_DLL_CALLCONV_CDECL 0x100000 + +/* WIN_DLLCALL() string encoding */ +#define HB_WIN_DLL_ENC_ASCII 0x000000 +#define HB_WIN_DLL_ENC_UTF8 0x010000 +#define HB_WIN_DLL_ENC_UTF16 0x040000 +#define HB_WIN_DLL_ENC_RAW 0x080000 /* WIN_DLLCALL() C types */ -#define HB_WIN_DLL_CTYPE_DEFAULT 0x0000 -#define HB_WIN_DLL_CTYPE_CHAR 0x0001 -#define HB_WIN_DLL_CTYPE_CHAR_UNSIGNED 0x0011 -#define HB_WIN_DLL_CTYPE_CHAR_PTR 0x0101 -#define HB_WIN_DLL_CTYPE_CHAR_UNSIGNED_PTR 0x0111 -#define HB_WIN_DLL_CTYPE_SHORT 0x0002 -#define HB_WIN_DLL_CTYPE_SHORT_UNSIGNED 0x0012 -#define HB_WIN_DLL_CTYPE_SHORT_PTR 0x0102 -#define HB_WIN_DLL_CTYPE_SHORT_UNSIGNED_PTR 0x0112 -#define HB_WIN_DLL_CTYPE_INT 0x0003 -#define HB_WIN_DLL_CTYPE_INT_UNSIGNED 0x0013 -#define HB_WIN_DLL_CTYPE_INT_PTR 0x0103 -#define HB_WIN_DLL_CTYPE_INT_UNSIGNED_PTR 0x0113 -#define HB_WIN_DLL_CTYPE_LONG 0x0004 -#define HB_WIN_DLL_CTYPE_LONG_UNSIGNED 0x0014 -#define HB_WIN_DLL_CTYPE_LONG_PTR 0x0104 -#define HB_WIN_DLL_CTYPE_LONG_UNSIGNED_PTR 0x0114 -#define HB_WIN_DLL_CTYPE_LLONG 0x0005 -#define HB_WIN_DLL_CTYPE_LLONG_UNSIGNED 0x0015 -#define HB_WIN_DLL_CTYPE_LLONG_PTR 0x0105 -#define HB_WIN_DLL_CTYPE_LLONG_UNSIGNED_PTR 0x0115 -#define HB_WIN_DLL_CTYPE_FLOAT 0x0006 -#define HB_WIN_DLL_CTYPE_FLOAT_PTR 0x0106 -#define HB_WIN_DLL_CTYPE_DOUBLE 0x0007 -#define HB_WIN_DLL_CTYPE_DOUBLE_PTR 0x0107 -#define HB_WIN_DLL_CTYPE_BOOL 0x0008 -#define HB_WIN_DLL_CTYPE_BOOL_PTR 0x0108 -#define HB_WIN_DLL_CTYPE_VOID 0x0009 -#define HB_WIN_DLL_CTYPE_VOID_PTR 0x0109 -#define HB_WIN_DLL_CTYPE_STRUCTURE 0x000A -#define HB_WIN_DLL_CTYPE_STRUCTURE_PTR 0x010A +#define HB_WIN_DLL_CTYPE_DEFAULT 0x000000 +#define HB_WIN_DLL_CTYPE_CHAR 0x000001 +#define HB_WIN_DLL_CTYPE_CHAR_UNSIGNED 0x000011 +#define HB_WIN_DLL_CTYPE_CHAR_PTR 0x000101 +#define HB_WIN_DLL_CTYPE_CHAR_UNSIGNED_PTR 0x000111 +#define HB_WIN_DLL_CTYPE_SHORT 0x000002 +#define HB_WIN_DLL_CTYPE_SHORT_UNSIGNED 0x000012 +#define HB_WIN_DLL_CTYPE_SHORT_PTR 0x000102 +#define HB_WIN_DLL_CTYPE_SHORT_UNSIGNED_PTR 0x000112 +#define HB_WIN_DLL_CTYPE_INT 0x000003 +#define HB_WIN_DLL_CTYPE_INT_UNSIGNED 0x000013 +#define HB_WIN_DLL_CTYPE_INT_PTR 0x000103 +#define HB_WIN_DLL_CTYPE_INT_UNSIGNED_PTR 0x000113 +#define HB_WIN_DLL_CTYPE_LONG 0x000004 +#define HB_WIN_DLL_CTYPE_LONG_UNSIGNED 0x000014 +#define HB_WIN_DLL_CTYPE_LONG_PTR 0x000104 +#define HB_WIN_DLL_CTYPE_LONG_UNSIGNED_PTR 0x000114 +#define HB_WIN_DLL_CTYPE_LLONG 0x000005 +#define HB_WIN_DLL_CTYPE_LLONG_UNSIGNED 0x000015 +#define HB_WIN_DLL_CTYPE_LLONG_PTR 0x000105 +#define HB_WIN_DLL_CTYPE_LLONG_UNSIGNED_PTR 0x000115 +#define HB_WIN_DLL_CTYPE_FLOAT 0x000006 +#define HB_WIN_DLL_CTYPE_FLOAT_PTR 0x000106 +#define HB_WIN_DLL_CTYPE_DOUBLE 0x000007 +#define HB_WIN_DLL_CTYPE_DOUBLE_PTR 0x000107 +#define HB_WIN_DLL_CTYPE_BOOL 0x000008 +#define HB_WIN_DLL_CTYPE_BOOL_PTR 0x000108 +#define HB_WIN_DLL_CTYPE_VOID 0x000009 +#define HB_WIN_DLL_CTYPE_VOID_PTR 0x000109 +#define HB_WIN_DLL_CTYPE_STRUCTURE 0x00000A +#define HB_WIN_DLL_CTYPE_STRUCTURE_PTR 0x00010A /* WIN_MAPISENDMAIL() address types */ #define WIN_MAPI_TO 1 diff --git a/harbour/contrib/hbwin/hbwin.h b/harbour/contrib/hbwin/hbwin.h index 3b655099fd..529eecad85 100644 --- a/harbour/contrib/hbwin/hbwin.h +++ b/harbour/contrib/hbwin/hbwin.h @@ -93,9 +93,9 @@ HB_EXTERN_BEGIN extern HB_EXPORT int hbwin_bitmapType( const void * pImgBuf, HB_SIZE size ); -extern HB_EXPORT void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFunction, int iParams, int iFirst, int * piArgType ); +extern HB_EXPORT void hbwin_dllCall( int iFuncFlags, FARPROC lpFunction, int iParams, int iFirst, int * piArgFlags ); -extern FARPROC hbwin_getprocaddress( HMODULE hDLL, int iParam, HB_BOOL * pbUNICODE ); +extern FARPROC hbwin_getprocaddress( HMODULE hDLL, PHB_ITEM pParam, HB_BOOL * pbUNICODE ); HB_EXTERN_END diff --git a/harbour/contrib/hbwin/legacycd.c b/harbour/contrib/hbwin/legacycd.c index a3f15888a5..c7df674cf5 100644 --- a/harbour/contrib/hbwin/legacycd.c +++ b/harbour/contrib/hbwin/legacycd.c @@ -106,17 +106,29 @@ HB_FUNC( FREELIBRARY ) HB_FUNC( CALLDLL ) { - hbwin_dllCall( HB_WIN_DLL_CALLCONV_STDCALL, HB_WIN_DLL_CTYPE_DEFAULT, HB_FALSE, ( FARPROC ) hb_parptr( 1 ), hb_pcount(), 2, NULL ); + hbwin_dllCall( 0, ( FARPROC ) hb_parptr( 1 ), hb_pcount(), 2, NULL ); } HB_FUNC( CALLDLLBOOL ) { - hbwin_dllCall( HB_WIN_DLL_CALLCONV_STDCALL, HB_WIN_DLL_CTYPE_BOOL , HB_FALSE, ( FARPROC ) hb_parptr( 1 ), hb_pcount(), 2, NULL ); + hbwin_dllCall( HB_WIN_DLL_CTYPE_BOOL, ( FARPROC ) hb_parptr( 1 ), hb_pcount(), 2, NULL ); } HB_FUNC( CALLDLLTYPED ) { - hbwin_dllCall( HB_WIN_DLL_CALLCONV_STDCALL, hb_parni( 2 ) , HB_FALSE, ( FARPROC ) hb_parptr( 1 ), hb_pcount(), 3, NULL ); + hbwin_dllCall( hb_parni( 2 ), ( FARPROC ) hb_parptr( 1 ), hb_pcount(), 3, NULL ); +} + +HB_FUNC( GETPROCADDRESS ) +{ + HMODULE hDLL; + + if( HB_ISNUM( 1 ) ) + hDLL = ( HMODULE ) ( HB_PTRDIFF ) hb_parnint( 1 ); + else + hDLL = ( HMODULE ) hb_parptr( 1 ); + + hb_retptr( hDLL ? ( void * ) hbwin_getprocaddress( hDLL, hb_param( 2, HB_IT_ANY ), NULL ) : NULL ); } #endif diff --git a/harbour/contrib/hbwin/tests/testdll.prg b/harbour/contrib/hbwin/tests/testdll.prg index f0e7320142..7a23769caa 100644 --- a/harbour/contrib/hbwin/tests/testdll.prg +++ b/harbour/contrib/hbwin/tests/testdll.prg @@ -76,8 +76,9 @@ PROCEDURE Main() IF hb_FileExists( "libcurl.dll" ) hDLL := wapi_LoadLibrary( "libcurl.dll" ) ? GetProcAddress( hDLL, "curl_version" ) - ? win_dllCall( { NIL, HB_WIN_DLL_CTYPE_CHAR_PTR }, GetProcAddress( hDLL, "curl_version" ) ) + ? win_dllCall( { "curl_version", hDLL, HB_WIN_DLL_CTYPE_CHAR_PTR } ) wapi_FreeLibrary( hDLL ) + ? win_dllCall( { "curl_version", "libcurl.dll", HB_WIN_DLL_CTYPE_CHAR_PTR } ) ENDIF /* Force Windows not to show dragged windows contents */ @@ -96,21 +97,31 @@ PROCEDURE Main() hDLL := wapi_LoadLibrary( "shell32.dll" ) ? "ValType( hDLL ): ", ValType( hDLL ) + ? "------" cData := Space( MAX_PATH ) - ? "WIN_DLLCALL (BOOL retval): ", win_dllCall( { NIL, HB_WIN_DLL_CTYPE_BOOL }, GetProcAddress( hDLL, "SHGetSpecialFolderPath" ), 0, @cData, CSIDL_APPDATA, 0 ) + ? "WIN_DLLCALL (BOOL retval): ", win_dllCall( { "SHGetSpecialFolderPath", hDLL, HB_WIN_DLL_CTYPE_BOOL }, 0, @cData, CSIDL_APPDATA, 0 ) ? "@cData: ", cData - ? "WIN_DLLCALL: ", win_dllCall( GetProcAddress( hDLL, "SHGetFolderPath" ), 0, CSIDL_ADMINTOOLS, 0, 0, cData ) // WRONG + ? "------" + cData := Space( MAX_PATH ) + ? "WIN_DLLCALL (BOOL retval): ", win_dllCall( { GetProcAddress( hDLL, "SHGetSpecialFolderPath" ), HB_WIN_DLL_CTYPE_BOOL }, 0, @cData, CSIDL_APPDATA, 0 ) + ? "@cData: ", cData + ? "------" + ? "WIN_DLLCALL: ", win_dllCall( { "SHGetFolderPath", hDLL }, 0, CSIDL_ADMINTOOLS, 0, 0, cData ) // WRONG ? "cData:", cData + ? "------" cData := Space( MAX_PATH ) - ? "WIN_DLLCALL (PARAMS): ", win_dllCall( { NIL, NIL, NIL, HB_WIN_DLL_CTYPE_BOOL }, GetProcAddress( hDLL, "SHGetSpecialFolderPath" ), 0, @cData, CSIDL_APPDATA, 0 ) + ? "WIN_DLLCALL (PARAMS): ", win_dllCall( { "SHGetSpecialFolderPath", hDLL, NIL, NIL, NIL, HB_WIN_DLL_CTYPE_BOOL }, 0, @cData, CSIDL_APPDATA, 0 ) ? "@cData: ", cData + ? "------" cData := Space( MAX_PATH ) - ? "WIN_DLLCALL: ", win_dllCall( GetProcAddress( hDLL, "SHGetFolderPath" ), 0, CSIDL_ADMINTOOLS, 0, 0, @cData ) + ? "WIN_DLLCALL: ", win_dllCall( { "SHGetFolderPath", hDLL }, 0, CSIDL_ADMINTOOLS, 0, 0, @cData ) ? "@cData: ", cData + ? "------" cData := Space( MAX_PATH ) ? "cData BEFORE: ", cData - ? "WIN_DLLCALL (MISSING @1): ", win_dllCall( GetProcAddress( hDLL, "SHGetFolderPath" ), 0, CSIDL_ADMINTOOLS, 0, 0, cData ) + ? "WIN_DLLCALL (MISSING @1): ", win_dllCall( { "SHGetFolderPath", hDLL }, 0, CSIDL_ADMINTOOLS, 0, 0, cData ) ? "cData AFTER: ", cData + ? "------" wapi_FreeLibrary( hDLL ) ? "DLLCALL" diff --git a/harbour/contrib/hbwin/win_dll.c b/harbour/contrib/hbwin/win_dll.c index e409baa68f..8f3cf039eb 100644 --- a/harbour/contrib/hbwin/win_dll.c +++ b/harbour/contrib/hbwin/win_dll.c @@ -61,6 +61,10 @@ #undef HB_LEGACY_LEVEL3 #include "hbwin.ch" +#define _MASK_CALLCONV 0xF00000 +#define _MASK_ENCODING 0x0F0000 +#define _MASK_CTYPE 0x00FFFF + /* C raw return types */ #define _RETTYPERAW_INT32 1 #define _RETTYPERAW_INT64 2 @@ -104,7 +108,7 @@ typedef struct { void * hString; int iType; - HB_BOOL bUNICODE; + int iEncoding; HB_BOOL bByRef; HB_U64 nValue; } HB_WINARG, * PHB_WINARG; @@ -158,17 +162,32 @@ static HB_U64 hb_u64par( PHB_ITEM pParam, PHB_WINARG pArg ) break; case HB_WIN_DLL_CTYPE_CHAR_PTR: - if( pArg->bUNICODE ) + + switch( pArg->iEncoding ) { - HB_SIZE nLen; - const HB_WCHAR * s = hb_itemGetStrU16( pParam, HB_CDP_ENDIAN_NATIVE, &pArg->hString, &nLen ); - r = ( HB_PTRUINT ) hb_wstrunshare( &pArg->hString, s, nLen ); - } - else - { - HB_SIZE nLen; - const char * s = hb_itemGetStr( pParam, hb_setGetOSCP(), &pArg->hString, &nLen ); - r = ( HB_PTRUINT ) hb_strunshare( &pArg->hString, s, nLen ); + case HB_WIN_DLL_ENC_ASCII: + { + HB_SIZE nLen; + const char * s = hb_itemGetStr( pParam, hb_setGetOSCP(), &pArg->hString, &nLen ); + r = ( HB_PTRUINT ) hb_strunshare( &pArg->hString, s, nLen ); + break; + } + case HB_WIN_DLL_ENC_UTF8: + { + HB_SIZE nLen; + const char * s = hb_itemGetStrUTF8( pParam, &pArg->hString, &nLen ); + r = ( HB_PTRUINT ) hb_strunshare( &pArg->hString, s, nLen ); + break; + } + case HB_WIN_DLL_ENC_UTF16: + { + HB_SIZE nLen; + const HB_WCHAR * s = hb_itemGetStrU16( pParam, HB_CDP_ENDIAN_NATIVE, &pArg->hString, &nLen ); + r = ( HB_PTRUINT ) hb_wstrunshare( &pArg->hString, s, nLen ); + break; + } + default: + r = ( HB_PTRUINT ) hb_strunshare( &pArg->hString, hb_itemGetCPtr( pParam ), hb_itemGetCLen( pParam ) ); } pArg->nValue = r; break; @@ -203,7 +222,7 @@ static HB_U64 hb_u64par( PHB_ITEM pParam, PHB_WINARG pArg ) return r; } -static PHB_ITEM hb_u64ret( PHB_ITEM pItem, int iRetType, HB_BOOL bUNICODE, HB_U64 nRetVal ) +static PHB_ITEM hb_u64ret( PHB_ITEM pItem, int iRetType, int iEncoding, HB_U64 nRetVal ) { switch( iRetType ) { @@ -239,10 +258,20 @@ static PHB_ITEM hb_u64ret( PHB_ITEM pItem, int iRetType, HB_BOOL bUNICODE, HB_U6 break; case HB_WIN_DLL_CTYPE_CHAR_PTR: - if( bUNICODE ) - hb_itemPutStrU16( pItem, HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) nRetVal ); - else - hb_itemPutStr( pItem, hb_setGetOSCP(), ( const char * ) nRetVal ); + switch( iEncoding ) + { + case HB_WIN_DLL_ENC_ASCII: + hb_itemPutStr( pItem, hb_setGetOSCP(), ( const char * ) nRetVal ); + break; + case HB_WIN_DLL_ENC_UTF8: + hb_itemPutStrUTF8( pItem, ( const char * ) nRetVal ); + break; + case HB_WIN_DLL_ENC_UTF16: + hb_itemPutStrU16( pItem, HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) nRetVal ); + break; + default: + hb_itemPutC( pItem, ( const char * ) nRetVal ); + } break; case HB_WIN_DLL_CTYPE_INT_PTR: @@ -304,7 +333,7 @@ typedef struct { void * hString; int iType; - HB_BOOL bUNICODE; + int iEncoding; HB_BOOL bByRef; HB_WINVAL value; } HB_WINARG, * PHB_WINARG; @@ -376,17 +405,32 @@ static void hb_u32par( PHB_ITEM pParam, PHB_WINARG pArg, HB_U32 * r1, HB_U32 * r break; case HB_WIN_DLL_CTYPE_CHAR_PTR: - if( pArg->bUNICODE ) + + switch( pArg->iEncoding ) { - HB_SIZE nLen; - const HB_WCHAR * s = hb_itemGetStrU16( pParam, HB_CDP_ENDIAN_NATIVE, &pArg->hString, &nLen ); - *r1 = ( HB_U32 ) hb_wstrunshare( &pArg->hString, s, nLen ); - } - else - { - HB_SIZE nLen; - const char * s = hb_itemGetStr( pParam, hb_setGetOSCP(), &pArg->hString, &nLen ); - *r1 = ( HB_U32 ) hb_strunshare( &pArg->hString, s, nLen ); + case HB_WIN_DLL_ENC_ASCII: + { + HB_SIZE nLen; + const char * s = hb_itemGetStr( pParam, hb_setGetOSCP(), &pArg->hString, &nLen ); + *r1 = ( HB_U32 ) hb_strunshare( &pArg->hString, s, nLen ); + break; + } + case HB_WIN_DLL_ENC_UTF8: + { + HB_SIZE nLen; + const char * s = hb_itemGetStrUTF8( pParam, &pArg->hString, &nLen ); + *r1 = ( HB_U32 ) hb_strunshare( &pArg->hString, s, nLen ); + break; + } + case HB_WIN_DLL_ENC_UTF16: + { + HB_SIZE nLen; + const HB_WCHAR * s = hb_itemGetStrU16( pParam, HB_CDP_ENDIAN_NATIVE, &pArg->hString, &nLen ); + *r1 = ( HB_U32 ) hb_wstrunshare( &pArg->hString, s, nLen ); + break; + } + default: + *r1 = ( HB_U32 ) hb_strunshare( &pArg->hString, hb_itemGetCPtr( pParam ), hb_itemGetCLen( pParam ) ); } pArg->value.t.n32 = *r1; break; @@ -419,7 +463,7 @@ static void hb_u32par( PHB_ITEM pParam, PHB_WINARG pArg, HB_U32 * r1, HB_U32 * r } } -static PHB_ITEM hb_u32ret( PHB_ITEM pItem, int iRetType, HB_BOOL bUNICODE, HB_WINVAL value ) +static PHB_ITEM hb_u32ret( PHB_ITEM pItem, int iRetType, int iEncoding, HB_WINVAL value ) { switch( iRetType ) { @@ -461,10 +505,20 @@ static PHB_ITEM hb_u32ret( PHB_ITEM pItem, int iRetType, HB_BOOL bUNICODE, HB_WI break; case HB_WIN_DLL_CTYPE_CHAR_PTR: - if( bUNICODE ) - hb_itemPutStrU16( pItem, HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) value.t.n32 ); - else - hb_itemPutStr( pItem, hb_setGetOSCP(), ( const char * ) value.t.n32 ); + switch( iEncoding ) + { + case HB_WIN_DLL_ENC_ASCII: + hb_itemPutStr( pItem, hb_setGetOSCP(), ( const char * ) value.t.n32 ); + break; + case HB_WIN_DLL_ENC_UTF8: + hb_itemPutStrUTF8( pItem, ( const char * ) value.t.n32 ); + break; + case HB_WIN_DLL_ENC_UTF16: + hb_itemPutStrU16( pItem, HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) value.t.n32 ); + break; + default: + hb_itemPutC( pItem, ( const char * ) value.t.n32 ); + } break; case HB_WIN_DLL_CTYPE_INT_PTR: @@ -746,16 +800,15 @@ typedef float ( _cdecl * WIN32_CFLP30 )( HB_U32, HB_U32, HB_U32, HB_U32, HB_U #endif -void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFunction, int iParams, int iFirst, int * piArgTypeReq ) +void hbwin_dllCall( int iFuncFlags, FARPROC lpFunction, int iParams, int iFirst, int * piArgFlags ) { - int tmp; - if( ! lpFunction ) return; #if defined( HB_ARCH_64BIT ) { - HB_SYMBOL_UNUSED( iCallConv ); + int iRetType = iFuncFlags & _MASK_CTYPE; + int iEncoding = iFuncFlags & _MASK_ENCODING; iParams -= iFirst - 1; @@ -764,6 +817,7 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun HB_U64 nRetVal = 0; HB_U64 rawpar[ _DLLEXEC_MAXPARAM ]; HB_WINARG * pArg; + int tmp; if( iParams ) { @@ -777,12 +831,20 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun { PHB_ITEM pParam = hb_param( iFirst + tmp, HB_IT_ANY ); - pArg[ tmp ].iType = piArgTypeReq ? piArgTypeReq[ tmp ] : HB_WIN_DLL_CTYPE_DEFAULT; + if( piArgFlags ) + { + pArg[ tmp ].iType = piArgFlags[ tmp ] & _MASK_CTYPE; + pArg[ tmp ].iEncoding = piArgFlags[ tmp ] & _MASK_ENCODING; + } + else + { + pArg[ tmp ].iType = HB_WIN_DLL_CTYPE_DEFAULT; + pArg[ tmp ].iEncoding = iEncoding; + } if( pArg[ tmp ].iType == HB_WIN_DLL_CTYPE_DEFAULT ) pArg[ tmp ].iType = hb_hbtoctype( HB_ITEM_TYPE( pParam ) ); - pArg[ tmp ].bUNICODE = bUNICODE; pArg[ tmp ].bByRef = HB_ISBYREF( iFirst + tmp ); rawpar[ tmp ] = hb_u64par( pParam, &pArg[ tmp ] ); @@ -808,7 +870,7 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun case 15: nRetVal = ( ( WIN64_15 ) *lpFunction )( rawpar[ 0 ], rawpar[ 1 ], rawpar[ 2 ], rawpar[ 3 ], rawpar[ 4 ], rawpar[ 5 ], rawpar[ 6 ], rawpar[ 7 ], rawpar[ 8 ], rawpar[ 9 ], rawpar[ 10 ], rawpar[ 11 ], rawpar[ 12 ], rawpar[ 13 ], rawpar[ 14 ] ); break; } - hb_u64ret( hb_stackReturnItem(), iRetType, bUNICODE, nRetVal ); + hb_u64ret( hb_stackReturnItem(), iRetType, iEncoding, nRetVal ); for( tmp = 0; tmp < iParams; ++tmp ) { @@ -848,10 +910,20 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun break; case HB_WIN_DLL_CTYPE_CHAR_PTR: - if( pArg[ tmp ].bUNICODE ) - hb_storstrlen_u16( HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) pArg[ tmp ].nValue, hb_parclen( iFirst + tmp ), iFirst + tmp ); - else - hb_storstrlen( hb_setGetOSCP(), ( const char * ) pArg[ tmp ].nValue, hb_parclen( iFirst + tmp ), iFirst + tmp ); + switch( pArg[ tmp ].iEncoding ) + { + case HB_WIN_DLL_ENC_ASCII: + hb_storstrlen( hb_setGetOSCP(), ( const char * ) pArg[ tmp ].nValue, hb_parclen( iFirst + tmp ), iFirst + tmp ); + break; + case HB_WIN_DLL_ENC_UTF8: + hb_storstrlen_utf8( ( const char * ) pArg[ tmp ].nValue, hb_parclen( iFirst + tmp ), iFirst + tmp ); + break; + case HB_WIN_DLL_ENC_UTF16: + hb_storstrlen_u16( HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) pArg[ tmp ].nValue, hb_parclen( iFirst + tmp ), iFirst + tmp ); + break; + default: + hb_storclen( ( const char * ) pArg[ tmp ].nValue, hb_parclen( iFirst + tmp ), iFirst + tmp ); + } break; case HB_WIN_DLL_CTYPE_INT_PTR: @@ -889,6 +961,10 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun } #elif defined( HB_ARCH_32BIT ) { + int iCallConv = iFuncFlags & _MASK_CALLCONV; + int iRetType = iFuncFlags & _MASK_CTYPE; + int iEncoding = iFuncFlags & _MASK_ENCODING; + iParams -= iFirst - 1; if( iParams <= _DLLEXEC_MAXPARAM ) @@ -896,6 +972,7 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun int iRetTypeRaw; HB_WINVAL ret; HB_WINARG * pArg; + int tmp; int iParamsRaw = 0; HB_U32 rawpar[ _DLLEXEC_MAXPARAM * 2 ]; @@ -925,12 +1002,20 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun HB_U32 r2; HB_BOOL b64; - pArg[ tmp ].iType = piArgTypeReq ? piArgTypeReq[ tmp ] : HB_WIN_DLL_CTYPE_DEFAULT; + if( piArgFlags ) + { + pArg[ tmp ].iType = piArgFlags[ tmp ] & _MASK_CTYPE; + pArg[ tmp ].iEncoding = piArgFlags[ tmp ] & _MASK_ENCODING; + } + else + { + pArg[ tmp ].iType = HB_WIN_DLL_CTYPE_DEFAULT; + pArg[ tmp ].iEncoding = iEncoding; + } if( pArg[ tmp ].iType == HB_WIN_DLL_CTYPE_DEFAULT ) pArg[ tmp ].iType = hb_hbtoctype( HB_ITEM_TYPE( pParam ) ); - pArg[ tmp ].bUNICODE = bUNICODE; pArg[ tmp ].bByRef = HB_ISBYREF( iFirst + tmp ); hb_u32par( pParam, &pArg[ tmp ], &r1, &r2, &b64 ); @@ -1242,7 +1327,7 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun } } - hb_u32ret( hb_stackReturnItem(), iRetType, bUNICODE, ret ); + hb_u32ret( hb_stackReturnItem(), iRetType, iEncoding, ret ); for( tmp = 0; tmp < iParams; ++tmp ) { @@ -1288,10 +1373,20 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun break; case HB_WIN_DLL_CTYPE_CHAR_PTR: - if( pArg[ tmp ].bUNICODE ) - hb_storstrlen_u16( HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) pArg[ tmp ].value.t.n32, hb_parclen( iFirst + tmp ), iFirst + tmp ); - else - hb_storstrlen( hb_setGetOSCP(), ( const char * ) pArg[ tmp ].value.t.n32, hb_parclen( iFirst + tmp ), iFirst + tmp ); + switch( pArg[ tmp ].iEncoding ) + { + case HB_WIN_DLL_ENC_ASCII: + hb_storstrlen( hb_setGetOSCP(), ( const char * ) pArg[ tmp ].value.t.n32, hb_parclen( iFirst + tmp ), iFirst + tmp ); + break; + case HB_WIN_DLL_ENC_UTF8: + hb_storstrlen_utf8( ( const char * ) pArg[ tmp ].value.t.n32, hb_parclen( iFirst + tmp ), iFirst + tmp ); + break; + case HB_WIN_DLL_ENC_UTF16: + hb_storstrlen_u16( HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) pArg[ tmp ].value.t.n32, hb_parclen( iFirst + tmp ), iFirst + tmp ); + break; + default: + hb_storclen( ( const char * ) pArg[ tmp ].value.t.n32, hb_parclen( iFirst + tmp ), iFirst + tmp ); + } break; case HB_WIN_DLL_CTYPE_INT_PTR: @@ -1330,20 +1425,24 @@ void hbwin_dllCall( int iCallConv, int iRetType, HB_BOOL bUNICODE, FARPROC lpFun else hb_errRT_BASE( EG_ARG, 2010, "A maximum of 15 parameters is supported", HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } - +#else + HB_SYMBOL_UNUSED( iFuncFlags ); + HB_SYMBOL_UNUSED( iParams ); + HB_SYMBOL_UNUSED( iFirst ); + HB_SYMBOL_UNUSED( piArgFlags ); #endif } /* ------------------------------------------------------------------ */ -FARPROC hbwin_getprocaddress( HMODULE hDLL, int iParam, HB_BOOL * pbUNICODE ) +FARPROC hbwin_getprocaddress( HMODULE hDLL, PHB_ITEM pParam, HB_BOOL * pbUNICODE ) { #if defined( HB_OS_WIN_CE ) void * hStr; HB_SIZE nLen; - LPCWSTR szProc = hb_parstr_u16( iParam, HB_CDP_ENDIAN_NATIVE, &hStr, &nLen ); + LPCWSTR szProc = hb_itemGetStrU16( pParam, HB_CDP_ENDIAN_NATIVE, &hStr, &nLen ); FARPROC lpFunction = GetProcAddress( hDLL, szProc ? szProc : - ( LPCWSTR ) ( HB_PTRDIFF ) ( hb_parni( iParam ) & 0x0FFFF ) ); + ( LPCWSTR ) ( HB_PTRDIFF ) ( hb_itemGetNI( pParam ) & 0x0FFFF ) ); if( ! lpFunction && szProc ) /* try with WIDE suffix? */ { @@ -1359,9 +1458,9 @@ FARPROC hbwin_getprocaddress( HMODULE hDLL, int iParam, HB_BOOL * pbUNICODE ) if( pbUNICODE ) *pbUNICODE = HB_TRUE; #else - const char * szProc = hb_parc( iParam ); + const char * szProc = hb_itemGetCPtr( pParam ); FARPROC lpFunction = GetProcAddress( hDLL, szProc ? szProc : - ( LPCSTR ) ( HB_PTRDIFF ) ( hb_parni( iParam ) & 0x0FFFF ) ); + ( LPCSTR ) ( HB_PTRDIFF ) ( hb_itemGetNI( pParam ) & 0x0FFFF ) ); if( pbUNICODE ) *pbUNICODE = HB_FALSE; @@ -1389,54 +1488,85 @@ FARPROC hbwin_getprocaddress( HMODULE hDLL, int iParam, HB_BOOL * pbUNICODE ) return lpFunction; } -HB_FUNC( GETPROCADDRESS ) -{ - HMODULE hDLL; - - if( HB_ISNUM( 1 ) ) - hDLL = ( HMODULE ) ( HB_PTRDIFF ) hb_parnint( 1 ); - else - hDLL = ( HMODULE ) hb_parptr( 1 ); - - hb_retptr( hDLL ? ( void * ) hbwin_getprocaddress( hDLL, 2, NULL ) : NULL ); -} - HB_FUNC( WIN_DLLCALL ) { - PHB_ITEM pParam = hb_param( 1, HB_IT_ARRAY ); - int iFirst = 1; - int * piArgTypeReq = NULL; + PHB_ITEM pParam = hb_param( 1, HB_IT_POINTER | HB_IT_ARRAY ); + int * piArgFlags = NULL; + int iFuncFlags = 0; + HB_BOOL bFreeDLL = HB_FALSE; - int iCallConv = HB_WIN_DLL_CALLCONV_STDCALL; - int iRetType = HB_WIN_DLL_CTYPE_DEFAULT; - HB_BOOL bUNICODE = HB_FALSE; + HMODULE hDLL = NULL; + FARPROC lpFunction = NULL; if( pParam ) { - HB_SIZE nLen = hb_arrayLen( pParam ); - - ++iFirst; - - if( nLen >= 1 && HB_IS_NUMERIC( hb_arrayGetItemPtr( pParam, 1 ) ) ) - iCallConv = hb_arrayGetNI( pParam, 1 ); - if( nLen >= 2 && HB_IS_NUMERIC( hb_arrayGetItemPtr( pParam, 2 ) ) ) - iRetType = hb_arrayGetNI( pParam, 2 ); - if( nLen >= 3 && HB_IS_LOGICAL( hb_arrayGetItemPtr( pParam, 3 ) ) ) - bUNICODE = hb_arrayGetL( pParam, 3 ); - if( nLen >= 4 ) + if( HB_IS_ARRAY( pParam ) ) { - HB_SIZE nPos; - HB_SIZE nArgCount = hb_pcount() - iFirst; + HB_SIZE nLen = hb_arrayLen( pParam ); - piArgTypeReq = ( int * ) hb_xgrab( sizeof( int ) * nArgCount ); + if( nLen >= 1 ) + { + PHB_ITEM pFunction = hb_arrayGetItemPtr( pParam, 1 ); + HB_SIZE nBasePos = 2; - for( nPos = 0; nPos < nArgCount; ++nPos ) - piArgTypeReq[ nPos ] = ( ( nPos + 4 ) <= nLen && HB_IS_NUMERIC( hb_arrayGetItemPtr( pParam, nPos + 4 ) ) ) ? hb_arrayGetNI( pParam, nPos + 4 ) : HB_WIN_DLL_CTYPE_DEFAULT; + if( HB_IS_POINTER( pFunction ) ) + lpFunction = ( FARPROC ) hb_itemGetPtr( pFunction ); + else if( ( HB_IS_NUMERIC( pFunction ) || HB_IS_STRING( pFunction ) ) && nLen >= nBasePos ) + { + PHB_ITEM pLibrary = hb_arrayGetItemPtr( pParam, nBasePos ); + + if( HB_IS_STRING( pLibrary ) ) + { + void * hFileName; + hDLL = LoadLibrary( HB_ITEMGETSTR( pLibrary, &hFileName, NULL ) ); + hb_strfree( hFileName ); + if( ( HB_PTRDIFF ) hDLL < 32 ) + hDLL = NULL; + else + bFreeDLL = HB_TRUE; + } + else if( HB_IS_POINTER( pLibrary ) ) + hDLL = ( HMODULE ) hb_itemGetPtr( pLibrary ); + + if( hDLL ) + { + HB_BOOL bUNICODE; + lpFunction = hbwin_getprocaddress( hDLL, pFunction, &bUNICODE ); + if( bUNICODE ) + iFuncFlags |= HB_WIN_DLL_ENC_UTF16; + } + + ++nBasePos; + } + + /* Function flags */ + if( nLen >= nBasePos ) + iFuncFlags = hb_arrayGetNI( pParam, nBasePos ); + + ++nBasePos; + + /* Argument flags */ + if( nLen >= nBasePos ) + { + HB_SIZE nPos; + HB_SIZE nArgCount = hb_pcount() - 1; + + piArgFlags = ( int * ) hb_xgrab( sizeof( int ) * nArgCount ); + + for( nPos = 0; nPos < nArgCount; ++nPos ) + piArgFlags[ nPos ] = ( ( nPos + nBasePos ) <= nLen && HB_IS_NUMERIC( hb_arrayGetItemPtr( pParam, nPos + nBasePos ) ) ) ? hb_arrayGetNI( pParam, nPos + nBasePos ) : HB_WIN_DLL_CTYPE_DEFAULT; + } + } } + else if( HB_IS_POINTER( pParam ) ) + lpFunction = ( FARPROC ) hb_itemGetPtr( pParam ); } - hbwin_dllCall( iCallConv, iRetType, bUNICODE, ( FARPROC ) hb_parptr( iFirst ), hb_pcount(), iFirst + 1, piArgTypeReq ); + hbwin_dllCall( iFuncFlags, lpFunction, hb_pcount(), 2, piArgFlags ); - if( piArgTypeReq ) - hb_xfree( piArgTypeReq ); + if( piArgFlags ) + hb_xfree( piArgFlags ); + + if( bFreeDLL ) + FreeLibrary( hDLL ); } diff --git a/harbour/contrib/hbwin/win_dllx.c b/harbour/contrib/hbwin/win_dllx.c index fb900c8564..c38fba7550 100644 --- a/harbour/contrib/hbwin/win_dllx.c +++ b/harbour/contrib/hbwin/win_dllx.c @@ -72,9 +72,7 @@ typedef struct { HMODULE hDLL; /* Handle */ HB_BOOL bFreeDLL; /* Free library handle on destroy? */ - int iCallConv; - int iRetType; - HB_BOOL bUNICODE; + int iFuncFlags; FARPROC lpFunction; /* Function Address */ } HB_DLLEXEC, * PHB_DLLEXEC; @@ -134,11 +132,9 @@ HB_FUNC( DLLCALL ) if( hDLL && ( HB_PTRDIFF ) hDLL >= 32 ) { HB_BOOL bUNICODE; - FARPROC lpFunction = hbwin_getprocaddress( hDLL, 3, &bUNICODE ); + FARPROC lpFunction = hbwin_getprocaddress( hDLL, hb_param( 3, HB_IT_ANY ), &bUNICODE ); - hbwin_dllCall( HB_ISNUM( 2 ) ? hb_parni( 2 ) : HB_WIN_DLL_CALLCONV_STDCALL, - HB_WIN_DLL_CTYPE_DEFAULT, - bUNICODE, + hbwin_dllCall( ( HB_ISNUM( 2 ) ? hb_parni( 2 ) : HB_WIN_DLL_CALLCONV_STDCALL ) | ( bUNICODE ? HB_WIN_DLL_ENC_UTF16 : 0 ), lpFunction, hb_pcount(), 4, @@ -174,11 +170,10 @@ HB_FUNC( DLLPREPARECALL ) if( xec->hDLL ) { HB_BOOL bUNICODE; - xec->lpFunction = hbwin_getprocaddress( xec->hDLL, 3, &bUNICODE ); + xec->lpFunction = hbwin_getprocaddress( xec->hDLL, hb_param( 3, HB_IT_ANY ), &bUNICODE ); if( xec->lpFunction ) { - xec->iCallConv = HB_ISNUM( 2 ) ? hb_parni( 2 ) : HB_WIN_DLL_CALLCONV_STDCALL; - xec->bUNICODE = bUNICODE; + xec->iFuncFlags = ( HB_ISNUM( 2 ) ? hb_parni( 2 ) : HB_WIN_DLL_CALLCONV_STDCALL ) | ( bUNICODE ? HB_WIN_DLL_ENC_UTF16 : 0 ); hb_retptrGC( xec ); return; @@ -199,9 +194,7 @@ HB_FUNC( DLLEXECUTECALL ) if( xec && xec->hDLL && xec->lpFunction ) { - hbwin_dllCall( xec->iCallConv, - xec->iRetType, - xec->bUNICODE, + hbwin_dllCall( xec->iFuncFlags, xec->lpFunction, hb_pcount(), 2,