elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  ¿Comprobar la firma de una función P/Invoke en tiempo de ejecución?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ¿Comprobar la firma de una función P/Invoke en tiempo de ejecución?  (Leído 1,788 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.817



Ver Perfil
¿Comprobar la firma de una función P/Invoke en tiempo de ejecución?
« en: 17 Junio 2015, 03:13 am »

Cómo dice el título del tema, ¿alguien tiene puñetera idea de si es posible, tal vez mediante Reflection, cómo se puede comprobar los valores de los atributos de una firma de una declaración de invocación de plataforma?.

Código
  1. [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  2. private static extern int xxx();

Código
  1. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
  2. Private Shared Function xxx() As Integer
  3. End Function

Basicamente necesito comprobar el valor de SetLastError en tiempo de ejecución, para determinar si es True o es False, pero parece un misterio sin resolver.

¿Alguien sabe de alguna referencia oficial de MSDN donde expliquen este detalle tan específico?, ¿cómo obtener los metadatos del método?.

Es para mejorar la lógica de este método genérico, ya que sin poder determinar ese detalle que me falta, no sirve para nada realizar un checkeo:
Código
  1.    ''' <summary>
  2.    ''' Invokes the encapsulated function, Tthen checks the exit code returned by the function that was called using platform invoke
  3.    ''' that has the <see cref="DllImportAttribute.SetLastError"/> flag set.
  4.    ''' </summary>
  5.    ''' ----------------------------------------------------------------------------------------------------
  6.    ''' <exception cref="Win32Exception">
  7.    ''' Function 'X' thrown an unmanaged Win32 exception with error code 'X'.
  8.    ''' </exception>
  9.    ''' ----------------------------------------------------------------------------------------------------
  10.    Private Shared Sub SafePInvoke(Of T)(ByRef refResult As T, ByVal expr As expression(Of Func(Of T)))
  11.  
  12.        refResult = expr.Compile.Invoke()
  13.  
  14.        Dim exitCode As Integer = Marshal.GetLastWin32Error
  15.        If exitCode <> 0 Then
  16.            Throw New Win32Exception([error]:=exitCode, message:=String.Format("Function '{0}' thrown an unmanaged Win32 exception with error code '{1}'.",
  17.                                                                               CType(expr.Body, MethodCallExpression).Method.Name, CStr(exitCode)))
  18.        End If
  19.  
  20.    End Sub

Saludos!


« Última modificación: 17 Junio 2015, 04:23 am por Eleкtro » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.817



Ver Perfil
Re: ¿Compronar la firma de una función P/Invoke en tiempo de ejecución?
« Respuesta #1 en: 17 Junio 2015, 04:02 am »

Analizando bastante a fondo la TEDIOSA class MethodInfo descubrí cómo resolverlo:

Código
  1. Dim isSetLastError As Boolean =
  2.    CType(expr.Body, MethodCallExpression).Method.GetCustomAttributes(False).
  3.                                                  OfType(Of DllImportAttribute)().FirstOrDefault.SetLastError



EDITO:

Os dejo el método genérico si quereis testearlo, es simplemente el inicio de una solución todo-en-uno para ahorrar toneladas de repetición de escritura de código para llevar a cabo la misma tarea, y cómo tal puede no ser perfecto, de hecho no lo es, es imposible hacer una función de este estilo que sea "compatible" con la magnitud de funciones de la WinAPI, ya que la función GetLastError depende de la función "X" que haya sido llamada, en la que algunos casos no tiene por que devolver "0" para una salida exitosa, pero si estamos seguros del valor de retorno de las funciones que usemos entonces si que es bueno usarlo.

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <remarks>
  3.    ''' Title : SafePInvoke
  4.    ''' Author: Elektro
  5.    ''' Date  : 17-June-2015
  6.    ''' </remarks>
  7.    ''' ----------------------------------------------------------------------------------------------------
  8.    ''' <summary>
  9.    ''' Invokes the specified encapsulated function, trying to provide a higher safety level for error-handling.
  10.    ''' If the function that was called using platform invoke has the <see cref="DllImportAttribute.SetLastError"/>,
  11.    ''' then it checks the exit code returned by the function, and, if is not a success code, throws a <see cref="Win32Exception"/>.
  12.    ''' </summary>
  13.    ''' ----------------------------------------------------------------------------------------------------
  14.    ''' <typeparam name="T"></typeparam>
  15.    '''
  16.    ''' <param name="expr">
  17.    ''' The encapsulated function.
  18.    ''' </param>
  19.    '''
  20.    ''' <param name="refResult">
  21.    ''' The referenced result variable.
  22.    ''' </param>
  23.    ''' ----------------------------------------------------------------------------------------------------
  24.    ''' <returns>
  25.    ''' The type of the return value depends on the function definition.
  26.    ''' </returns>
  27.    ''' ----------------------------------------------------------------------------------------------------
  28.    ''' <exception cref="Win32Exception">
  29.    ''' Function 'X' thrown an unmanaged Win32 exception with error code 'X'.
  30.    ''' </exception>
  31.    ''' ----------------------------------------------------------------------------------------------------
  32.    <DebuggerStepThrough>
  33.    Private Shared Function SafePInvoke(Of T)(ByVal expr As Expression(Of Func(Of T)),
  34.                                              Optional ByVal successCode As Integer = 0) As T
  35.  
  36.        Dim result As T = expr.Compile.Invoke()
  37.  
  38.        Dim method As MethodInfo =
  39.            CType(expr.Body, MethodCallExpression).Method
  40.  
  41.        Dim isSetLastError As Boolean =
  42.            method.GetCustomAttributes(inherit:=False).
  43.                   OfType(Of DllImportAttribute)().FirstOrDefault.SetLastError
  44.  
  45.        If isSetLastError Then
  46.  
  47.            Dim exitCode As Integer = Marshal.GetLastWin32Error
  48.  
  49.            If exitCode <> successCode Then
  50.                Throw New Win32Exception([error]:=exitCode,
  51.                                         message:=String.Format("Function '{0}' thrown an unmanaged Win32 exception with error code '{1}'.",
  52.                                                                method.Name, CStr(exitCode)))
  53.            End If
  54.  
  55.        End If
  56.  
  57.        Return result
  58.  
  59.    End Function
  60.  

Ejemplos de uso ...parciales:

Código
  1. Dim length As Integer = SafePInvoke(Function() NativeMethods.GetWindowTextLength(hWnd))

Código
  1. Dim sb As New StringBuilder(String.Empty, length)
  2. SafePInvoke(Function() NativeMethods.GetWindowText(hWnd, sb, sb.Capacity + 1))

Saludos!


« Última modificación: 17 Junio 2015, 15:27 pm por Eleкtro » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
tiempo de ejecucion « 1 2 »
Programación C/C++
mapers 11 12,977 Último mensaje 26 Junio 2010, 15:37 pm
por cbug
tiempo de ejecucion!!!
Programación General
mapers 3 3,419 Último mensaje 28 Agosto 2010, 09:00 am
por Littlehorse
Modificar código en tiempo de ejecución en función de la versión de python
Scripting
SARGE553413 1 2,509 Último mensaje 7 Noviembre 2014, 10:19 am
por 1quark1
(Consula) ¿Se puede modificar una función en tiempo de ejecución?
Programación C/C++
Seyro97 4 2,324 Último mensaje 4 Octubre 2015, 14:31 pm
por Seyro97
Limitar el tiempo de ejecucion de una funcion.
Programación C/C++
yoelmend 6 3,644 Último mensaje 4 Agosto 2017, 14:16 pm
por engel lex
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines