Hi,

I use approach listed below. And I suggest... not to use it! :)
And this code is NOT the one I want to see in Harbour. It's Windows 32bit only, code is on data segment, etc.

Syntax:
  CallProc( ptrFunc, param1, param2, ... )
or
  cStackFrame := L2BIN(something) + L2BIN(something) + ...
  CallProcByFrame( ptrFunc | "cDll:cFunc", cStackFrame )


Actually when I've wrote "I use approach listed below", I was wrong. My friends were using it in cases they need some WinAPI call. In a few days I include function wrapper to call this WinAPI in my CAWI library, and they delete this CallProc hack. That was time of developing CAWI. We have not used CallProc() for a few years now.


Have a good GPF pleasure,
Mindaugas



Viktor Szakáts wrote:
I don't have huge recruiting experiences, so cannot tell, but maybe
someone in our crew (Mindaugas :) could find it interesting in the
future and even find time for it.

Of course everyone is welcome and you can try getting ppl interested,
I seem to recall there is some infrastructure for that on sf.net even.

Brgds,
Viktor


static const BYTE CallProcByStackFrameCode[] = {
    0x55,                //             push    ebp
    0x8B, 0xEC,          //             mov     ebp,esp
    0x8B, 0x4D, 0x10,    //             mov     ecx,dword ptr [ebp+16]
    0x67, 0xE3, 0x10,    //             jcxz    @@noparam
    0x8B, 0x5D, 0x0C,    //             mov     ebx,dword ptr [ebp+12]
    0x2B, 0xE1,          //             sub     esp,ecx
    0x8B, 0xD4,          //             mov     edx,esp
    0x8A, 0x03,          // @@loop:     mov     al,byte ptr [ebx]
    0x36, 0x88, 0x02,    //             mov     byte ptr ss:[edx],al
    0x43,                //             inc     ebx
    0x42,                //             inc     edx
    0xE2, 0xF7,          //             loop    @@loop
    0x8B, 0x45, 0x08,    // @@noparam:  mov     eax,dword ptr [ebp+8]
    0xFF, 0xD0,          //             call    eax
    0x8B, 0xE5,          //             mov     esp,ebp
    0x5D,                //             pop     ebp
    0xC3};               //             ret

typedef int (* CallProcByStackFrameFunc) (void*, void*, int);

CallProcByStackFrameFunc CallProcByStackFrame = (CallProcByStackFrameFunc)CallProcByStackFrameCode;


HB_FUNC ( CALLPROCBYSTACKFRAME )
{
   if ( ISCHAR( 2 ) )
hb_retnl( CallProcByStackFrame( hb_parptr( 1 ), hb_parc( 2 ), hb_parclen( 2 ) ) );
   else
      hb_retnl( CallProcByStackFrame( hb_parptr( 1 ), NULL, 0 ) );
}


HB_FUNC ( CALLPROC )
{
// TODO: this function always returns LONG type. It could be pointer!
   long       pbuf[ 10 ];
   int        i, j, pcount, storn = 0, storc = 0, storp = 0;
   char       *pstr, *pFuncName;
   HINSTANCE  hInst;
   void*      pFunc;

   pcount = hb_parinfo( 0 );
   j = 9;
   for ( i = 2; i <= pcount; i++ )
   {
      if ( i - 2 >= j )
      {
         // ### runerror
         hb_ret();
         return;
      }

      if ( ISNUM( i ) )
      {
         if ( ISBYREF( i ) )
         {
            pbuf[ j ] = (long) hb_parnl( i );
            pbuf[ i - 2 ] = (long) &pbuf[ j ];
            j--;
            storn |= 1 << ( i - 2 );
         }
         else
            pbuf[ i - 2 ] = (long) hb_parnl( i );
      }
      else if ( ISCHAR( i ) )
      {
         if ( ISBYREF( i ) )
         {
pbuf[ i - 2 ] = (long) hb_xgrabcopy( hb_parclen( i ) + 1, hb_parc( i ) );
            storc |= 1 << ( i - 2 );
         }
         else
            pbuf[ i - 2 ] = (long) hb_parc( i );
      }
      else if ( ISPOINTER( i ) )
      {
         if ( ISBYREF( i ) )
         {
            pbuf[ j ] = (long) hb_parptr( i );
            pbuf[ i - 2 ] = (long) &pbuf[ j ];
            j--;
            storp |= 1 << ( i - 2 );
         }
         else
            pbuf[ i - 2 ] = (long) hb_parptr( i );
      }
      else if ( ISLOG(i) )
         pbuf[ i-2 ] = (long) hb_parl( i );
   }

   hInst = NULL;
   if ( ISPOINTER( 1 ) )  pFunc = hb_parptr( 1 );
   else
   {
      pstr = hb_parc(1);
      if ( ( pFuncName = strrchr( pstr, ':' ) ) == NULL )
      {
         // ### runerror
         hb_ret();
         return;
      }
      *pFuncName = '\0';
      hInst = LoadLibrary( pstr );
      *pFuncName = ':';
      pFunc = GetProcAddress( hInst, pFuncName + 1 );
   }

   if ( ! pFunc )
   {
      // ### runerror
      hb_ret();
      return;
   }

   hb_retnl( CallProcByStackFrame( pFunc, &pbuf, ( pcount - 1 ) * 4 ) );

   if ( hInst )
      FreeLibrary( hInst );

   for ( i = 0; i < pcount - 1; i++ )
   {
      if ( storn & (1 << i) )
      {
         hb_stornl( * (long*) pbuf[ i ], i + 2 );
      }
      else if ( storc & (1 << i) )
      {
         hb_storclen( (char*) pbuf[ i ], hb_parclen( i + 2 ), i + 2 );
         hb_xfree( (char*) pbuf[ i ] );
      }
      else if ( storp & (1 << i) )
      {
         hb_storptr( (void*) pbuf[ i ], i + 2 );
      }
   }
}
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to