Page 2 of 3

Re: Borland7 versus VisualStudio

PostPosted: Wed Mar 16, 2016 9:22 pm
by JmGarcia
Quitando PASCAL me da el error de "Programa.exe dejo de funcionar..." usando tanto GetBinaryTypeW como GetBinaryTypeA.

Después de mucho probar por fin he conseguido que funcione pero usando código C con #pragma BEGINDUMP/ENDDUMP.

Gracias por tu ayuda, siempre se aprenden cosas.

Y después de los desvelos la satisfacción de poder "donar" el código al mundo mundial... aquí os lo dejo:
Code: Select all  Expand view
******************************************************************************
*                                                                            *
*                                GetBinaryType                               *
*        https://msdn.microsoft.com/en-us/library/aa364819(VS.85).aspx       *
*  Determina el tipo de fichero ejecutable: MS-DOS, 16bits, 32bts, 64bits... *
*                   © JmGarcia 2016 (BCC7 o VS12 y FHW1602)                  *
*                                                                            *
******************************************************************************

#include "FiveWin.Ch"

FUNCTION main()
public cFichero:="",nTipo:=-1

cFichero:=cGetFile("Ficheros (*.exe)|*.exe|Ficheros (*.com)|*.com|Todos (*.*)|*.*","Escoja fichero ejecutable")
cFichero:=alltrim(cFichero)
nTipo:=GetBinaryType(cFichero)
do case
   case nTipo=0 ; MsgInfo("Ejecutable de 32 bits")
   case nTipo=1 ; MsgInfo("Ejecutable MS-DOS")
   case nTipo=2 ; MsgInfo("Ejecutable de 16 bits")
   case nTipo=3 ; MsgInfo("Ejecutable PIF/MS-DOS")
   case nTipo=4 ; MsgInfo("Ejecutable POSIX")
   case nTipo=5 ; MsgInfo("Ejecutable de 16 OS/2")
   case nTipo=6 ; MsgInfo("Ejecutable de 64 bits")
otherwise
   MsgInfo("Tipo de fichero/ejecutable desconocido")
endcase
return nil

#pragma BEGINDUMP
#include <windows.h>
#include "hbapi.h"
#include "hbapierr.h"
HB_FUNC( GETBINARYTYPE )
{
 DWORD dwBinaryType;
 GetBinaryType(hb_parc(1),&dwBinaryType);
 hb_retni(dwBinaryType);
}
#pragma ENDDUMP

No descarto conseguir hacer que funcione wrapeando lo de DLL32 FUNCTION... :roll: :cry:

Re: Borland7 versus VisualStudio

PostPosted: Wed Mar 16, 2016 9:35 pm
by Antonio Linares
JM,

gracias!

No consigo que funcione con DLL FUNCTION. He estado probándolo
de varias formas pero no va :-(

Tendré que tracear el código a bajo nivel para ver que ocurre...

Re: Borland7 versus VisualStudio

PostPosted: Wed Mar 16, 2016 9:39 pm
by JmGarcia
Gracias a ti por tu ayuda :D

Re: Borland7 versus VisualStudio

PostPosted: Wed Mar 16, 2016 11:48 pm
by cnavarro
Pruébalo asi:

Code: Select all  Expand view


DLL32 FUNCTION GetBinaryType( cFile AS LPSTR, @nType AS DWORD ) AS LONG PASCAL FROM "GetBinaryTypeA" LIB "Kernel32.dll"

Function Tipo()

  local cFichero := "d:\fwh\fwhteam\samples\prucmenu.exe"
  //local cFichero := "d:\fwh\samples\tutor01.exe"
  local nTipo    := 0

  GetBinaryType( cFichero, @nTipo )
  MsgInfo( nTipo, "Tipo de fichero" )

return nil

 

Re: Borland7 versus VisualStudio

PostPosted: Thu Mar 17, 2016 8:18 am
by Antonio Linares
Cristobal,

Genial!

Esta funcionando bien, muchas gracias :-)

Re: Borland7 versus VisualStudio

PostPosted: Thu Mar 17, 2016 9:02 am
by mastintin
Aqui esto parece que funciona bien ...
Code: Select all  Expand view


Function Tipo(cExe)

  local cFichero := cExe
   local nTipo    := 0

  nTipo := GetBinaryType( cFichero )
 
  MsgInfo( nTipo, "Tipo de fichero" )

return nil


#pragma BEGINDUMP
#include <windows.h>
#include "hbapi.h"
#include "hbapierr.h"

HB_FUNC( GETBINARYTYPE )
{
 LPCTSTR lpApplicationName = ( LPCTSTR ) hb_parc( 1 ) ;
 DWORD dwBinaryType;
 GetBinaryType(lpApplicationName,&dwBinaryType) ;
 hb_retni( dwBinaryType  ) ;
}
#pragma ENDDUMP

 

Re: Borland7 versus VisualStudio

PostPosted: Thu Mar 17, 2016 2:56 pm
by JmGarcia
cnavarro wrote:DLL32 FUNCTION GetBinaryType( cFile AS LPSTR, @nType AS DWORD ) AS LONG PASCAL FROM "GetBinaryTypeA" LIB "Kernel32.dll"
Desconocía que se pudieran poner variables pasadas por referencia en el wrapeado de funciones de una DLL.
Esto me ha funciona perfectamente :mrgreen: :D

De hecho, yo, cuando son string pasadas por referencia las defino en la DLL32... así "...AS LPSTR" y en la llamada a la función (en código FWH) sí la pongo por referencia (@). Quiere pues decir que podría definirla, en la DLL32..., como AS STRING pasada por referencia y en la llamada, por supuesto, también por referencia.

Lo escribo.

Yo hago/hacía esto:
FuncionDll( @cTexto, nValor)
.../...
DLL32 FUNCTION FuncionDll( Variable1 AS LPSTR, Variable2 AS INT ) AS LONG PASCAL FROM "FuncionDllA" LIB "Libreria.dll"

Entiendo que se puede hacer así:
FuncionDll( @cTexto, nValor)
.../...
DLL32 FUNCTION FuncionDll( @Variable1 AS STRING, Variable2 AS INT ) AS LONG PASCAL FROM "FuncionDllA" LIB "Libreria.dll"


Mas "fino" este código C :D
mastintin wrote:HB_FUNC( GETBINARYTYPE )
{
LPCTSTR lpApplicationName = ( LPCTSTR ) hb_parc( 1 ) ;
DWORD dwBinaryType;
GetBinaryType(lpApplicationName,&dwBinaryType) ;
hb_retni( dwBinaryType ) ;
}
#pragma ENDDUMP


Gracias a todos.

Re: Borland7 versus VisualStudio

PostPosted: Thu Mar 17, 2016 9:40 pm
by JmGarcia
El programa compilado en 64 bits (VS12) no funciona con la opción de wrapear con DLL32 FUNCTION... sí funciona con la opción de insertar código C (BEGINDUMP/ENDDUMP).

El programa se ejecuta, aparece la ventana de cGetFile, se escoge el fichero deseado <intro> y... no aparece nada y al rato termina la ejecución.

¿Alguna idea?

Re: Borland7 versus VisualStudio

PostPosted: Thu Mar 17, 2016 10:30 pm
by cnavarro
No lo he probado

Code: Select all  Expand view


DLL32 FUNCTION GetBinaryType( cFile AS LPSTR, @nType AS DWORD ) AS LONGLONG PASCAL FROM "GetBinaryTypeW" LIB "Kernel32.dll"

Function Tipo()

  local cFichero := "d:\fwh\fwhteam\samples\prucmenu.exe"
  //local cFichero := "d:\fwh\fwhteam\samples\scilex64.dll"
  local nTipo    := 0

  GetBinaryType( cFichero, @nTipo )
  MsgInfo( nTipo, "Tipo de fichero" )

return nil



 

Re: Borland7 versus VisualStudio

PostPosted: Fri Mar 18, 2016 7:28 am
by Antonio Linares
JM,

Aqui funciona bien el código que ha publicado Cristobal:

viewtopic.php?p=187982#p187982

Re: Borland7 versus VisualStudio

PostPosted: Fri Mar 18, 2016 10:52 am
by JmGarcia
A mi no me funciona si dejo la parte de código DLL32 FUNCTION... al principio del programa, antes del main().
Si la parte de código DLL32 FUNCTION... la pongo después del return nil funciona. Todo esto en 32 bits.

El ejemplo de Cristóbal no me funciona en 64 bits.

Es decir, se repite lo que dije en mi mensaje anterior:
JmGarcia wrote:El programa compilado en 64 bits (VS12) no funciona con la opción de wrapear con DLL32 FUNCTION... sí funciona con la opción de insertar código C (BEGINDUMP/ENDDUMP)....

Parece ser que las DLL32 FUNCTION... no se llevan bien con los 64 bits de Visual Studio.
Seguiremos investigando.
Gracias a todos.

Re: Borland7 versus VisualStudio

PostPosted: Fri Mar 18, 2016 11:07 am
by Antonio Linares
JM,

Si, la declaración de DLL FUNCTION hay que hacerla despues de function Main()

Efectivamente con 64 bits esta generando una excepción y se crea el fichero hb_out.log

Voy a revisarlo, gracias :-)

Re: Borland7 versus VisualStudio

PostPosted: Fri Mar 18, 2016 11:15 am
by Antonio Linares
JM,

Acabo de caer en la cuenta que estamos intentando acceder a una DLL de 32 bits desde una aplicación de 64 bits:

... FROM "GetBinaryTypeA" LIB "Kernel32.dll"

Y eso no se puede hacer, de ahi que se produzca el GPF.

Imagino que en 64 bits forzosamente tenemos que usar BEGINDUMP y ENDDUMP

Re: Borland7 versus VisualStudio

PostPosted: Fri Mar 18, 2016 1:54 pm
by cnavarro
A mi no me genera GPF, pero no devuelve el valor correcto ( 6 ), devuelve 0

Code: Select all  Expand view


DLL32 FUNCTION GetBinaryType( cFile AS LPSTR, @nType AS DWORD ) AS DWORD PASCAL FROM "GetBinaryTypeW" LIB "Kernel32.dll"

Function Tipo()

  local cFichero := "d:\fwh\fwhteam\samples\prucmenu.exe"
  //local cFichero := "d:\fwh\fwhteam\samples\scilex64.dll"
  local nTipo    := 0

  GetBinaryType( cFichero, @nTipo )
  MsgInfo( nTipo, "Tipo de fichero" )

return nil

 

Re: Borland7 versus VisualStudio

PostPosted: Fri Mar 18, 2016 7:14 pm
by JmGarcia
cnavarro wrote:A mi no me genera GPF, pero no devuelve el valor correcto ( 6 ), devuelve 0

Cristóbal,

Si inicializas la variable con un valor distinto de CERO (ejemplo nTipo:=-1) podrás comprobar si al pasarla por referencia se cambia el valor, probablemente ni siquiera funcione la "llamada a la función".

A mi me ha pasado a veces casos de variables que no cambian de valor y como el CERO es un valor "muy usado" en los valores devueltos por funciones pues procuro no usar el cero, a veces, para según que casos.

Antonio,

No existe una KERNEL.DLL de 64 bits o similar, al menos no la he encontrado. Los comentarios encontrados en SanGoogle apuntan a que no existe. Estoy buscando comentario al respecto, si encuentro algo te lo paso.

Al respecto he encontrado esto http://stackoverflow.com/questions/1364 ... e-kernel64
Aquí comenta que (traducción Google):
"En las versiones de 64 bits de Windows la kernel32.dll contiene código de 64 bits, pero todavía se llama kernel32.dll. Esto es al menos engañoso".
"Siempre llama kernel32.dll, incluso en Windows de 64 bits. Esto es por las mismas razones de compatibilidad que system32 contiene los binarios de 64 bits, mientras que syswow64 contiene binarios de 32 bits".
64-bit de Windows proporciona un entorno como "fuera de la caja" y es compatible con aplicaciones de 32 bits utilizando el 'Windows on Windows 64' subsistema, abreviado a WOW64, que se ejecuta en modo usuario y asigna la de 32 bits llama al sistema operativo núcleo en una llamada de 64 bits equivalente. Esto es normalmente casi invisible a los que llaman program.Windows proporciona un conjunto de DLL de 64 bits en% windir% \ system32 y un conjunto equivalente de DLL de 32 bits en% windir% \ syswow64. De hecho la mayor parte de las imágenes binarias en este directorio son idénticos a los mismos archivos en el directorio System32 en una instalación de Windows de 32 bits. (Me parece una cuestión de nomenclatura lamentable que las DLL de 64 bits viven en system32 y los 32 bits viven en syswow64, pero no lo es)".


Se me ocurre si sería bueno que aumentaras los "#xcommand" del fichero DLL.CH adaptándolo a 64 bits. En este fichero de cabecera tienes #xcommand DLL... #xcommand DLL32... si se pudiera añadir un #xcommand DLL64.... También hay funciones GetProcAdd/GetProc32, FWCallDLL/FWCallDLL32, LoadLibrary/LoadLib32 y FreeLibrary/FreeLib32 lo que denota que tuviste que adaptar el tema en su tiempo.

Gracias.

P.D.: Sea como fuere la solución esta aquí (alguien que sepa ingles "técnico" y lo comprenda):
Why can't 32-bit DLL's be used in a 64-bit program? Is there a way to evade this limitation?
http://www.viva64.com/en/l/0002/#ID0E5MAC
Why can't you thunk between 32-bit and 64-bit Windows?
http://blogs.msdn.com/b/oldnewthing/arc ... 06720.aspx
Accessing 32-bit DLLs from 64-bit code
http://blog.mattmags.com/2007/06/30/acc ... -bit-code/