[INCLUDE]
UIntAddUInt

[API]
VirtualAlloc
VirtualProtect
VirtualFree
RtlMoveMemory
CallWindowProcA

[DEFINE]
Private CallFunction_tmpArray() As Byte
Private CallFunction_tmpParam() As Long
Private CallFunction_tmpPAPos As Long

[CODE]
Private Function CallFunction_Real(ByVal FunctionAddress As Long) As Long
  Dim xLong1 As Long

  ReDim CallFunction_tmpArray(9& + 5& * (UBound(CallFunction_tmpParam())))  '5x due no cdll
  CallFunction_tmpPAPos = 0&
  For xLong1 = UBound(CallFunction_tmpParam()) - 1& To 0& Step -1&
    CallFunction_AddOpCode32 &H68&, CallFunction_tmpParam(xLong1)
    Next
  CallFunction_AddOpCode32 &HB8&, FunctionAddress 'mov eax, ...
  CallFunction_AddOpCode32 &HFF&, &H10C2D0        ' call eax, ret 10
  
  xLong1 = VirtualAlloc(0&, CallFunction_tmpPAPos + 15&, &H1000&, 4&)
  If Not xLong1 = 0& Then
    FunctionAddress = xLong1
    Call UIntAddUInt(FunctionAddress, 15&)
    FunctionAddress = (FunctionAddress And &HFFFFFFF0)
    Call RtlMoveMemory(ByVal FunctionAddress, CallFunction_tmpArray(0), CallFunction_tmpPAPos)
    If Not VirtualProtect(ByVal xLong1, CallFunction_tmpPAPos + 15&, &H20&, 0&) = 0& Then
      CallFunction_Real = CallWindowProcA(FunctionAddress, 0, 0, 0, 0)
      End If
    Call VirtualFree(xLong1, 0&, &H8000&)
    End If
  
  On Error Resume Next
  xLong1 = Timer
  On Error GoTo 0
  ReDim CallFunction_tmpParam(0&)
  ReDim CallFunction_tmpArray(0&)
  End Function

Private Sub CallFunction_AddOpCode32(ByVal preByte As Long, ByVal xLong1 As Long)
  CallFunction_tmpArray(CallFunction_tmpPAPos) = preByte
  Call RtlMoveMemory(CallFunction_tmpArray(CallFunction_tmpPAPos + 1&), ByVal VarPtr(xLong1), 4&)
  CallFunction_tmpPAPos = CallFunction_tmpPAPos + 5&
  End Sub