You can write addin for this purpose. Also you can use special undocumented function from vba6.dll in order to obtain code and modules, but it will work only IDE.
Printable View
You can write addin for this purpose. Also you can use special undocumented function from vba6.dll in order to obtain code and modules, but it will work only IDE.
Hi the Trick,
Do you know of any useful examples of undocumented functions from vba6.dll ? .. There seems to be very little documentation specially with regards to the vba dll functions parameters ie: vartypes,number of arguments etc ..
When I open the vba6.dll in Dependency Walker, all I see is the name of the functions , the ordinal number and Entry point but I can't see the function arguments
I heard somewhere that there was a tool/program that explores this dll functions but i searched the net and coudn't find anything
I use an addin called MZ-Tools, it provides a lines-of-code counter that even breaks it down to comment lines vs actual code lines.
Thankjs .. I know of the MZ-Tools addin but that's not i was asking about .. I am asking if there is a tool/program/website that helps figure out the definitions and argument descriptions of the vba6.dll or msvbvm60.dll functions
Regards.
But you are hi-jacking someone's thread to ask an unrelated question to the original Post.
You should start your own thread to ask your own questions.
I show you later the using of undocumented function from vba6. Write exactly what you want?
Hi the Trick,
There are some websites with some examples such as :http://foro.elhacker.net/programacio...t365053.0.html .. the examples are trivial/useless .. What I want is to be able to explore in some more depth the dll (functions,arguments, types, Byref ,ByVal etc...)
I remember seeing a tool which ressembled IDA/dependency walker that would show each dll function arguments and their variable types but I can't remeber what the program was
Thank you
This code obtain some information about current project. You should add to reference OLELIB - library, and TypeLib Information library.
Code:Private Declare Sub EbGetExecutingProj Lib "vba6" (ByRef lpPrjObj As IUnknown)
Private Sub Form_Load()
Dim objProj As IUnknown
Dim TLI As TLI.TLIApplication
Dim LibInfo As TLI.TypeLibInfo
Dim typeLib As ITypeLib
Dim typeInf As TypeInfo
Dim index As Long
' // Get current project
EbGetExecutingProj objProj
' // Get ITypeLib interfaces describes current project
Set typLib = objProj
' // For help we used TLI library
Set TLI = New TLIApplication
Set LibInfo = TLI.TypeLibInfoFromITypeLib(typLib)
' // Get each info
For Each typeInf In LibInfo.TypeInfos
Dim member As MemberInfo
' // Get name
Debug.Print "Module: "; typeInf.Name
' // Get members
For Each member In typeInf.Members
' // Skip private constants
If member.MemberId <> -1 Then
' // Get Type member
If member.DESCKIND = DESCKIND_VARDESC Then
' // Variable
Debug.Print Tab(5); "Variable "; member.Name;
ElseIf member.DESCKIND = DESCKIND_FUNCDESC Then
Dim param As ParameterInfo
If member.INVOKEKIND = INVOKE_FUNC Then
If member.ReturnType.VarType = VT_VOID Then
Debug.Print Tab(5); "Sub "; member.Name;
Else
Debug.Print Tab(5); "Function "; member.Name;
End If
ElseIf member.INVOKEKIND = INVOKE_PROPERTYGET Then
Debug.Print Tab(5); "Property Get "; member.Name;
ElseIf member.INVOKEKIND = INVOKE_PROPERTYPUT Or member.INVOKEKIND = INVOKE_PROPERTYPUTREF Then
Debug.Print Tab(5); "Property Let/Set "; member.Name;
End If
Debug.Print "(";
index = 0
' // Get parameters
For Each param In member.Parameters
If param.flags And PARAMFLAG_FOPT Then
Debug.Print "Optional ";
End If
If param.flags And PARAMFLAG_FOUT Then
Debug.Print "ByRef ";
Else
Debug.Print "ByVal ";
End If
Debug.Print param.Name;
Debug.Print GetStringTypeName(param.VarTypeInfo);
If index < member.Parameters.Count - 1 Then
Debug.Print ", ";
End If
index = index + 1
Next
Debug.Print ")";
End If
If member.ReturnType.VarType <> VT_VOID Then
Debug.Print GetStringTypeName(member.ReturnType)
Else
Debug.Print
End If
End If
Next
Next
Set objProj = Nothing
End Sub
Private Function GetStringTypeName(v As VarTypeInfo) As String
Dim locType As TliVarType
locType = v.VarType
If locType And VT_ARRAY Then
GetStringTypeName = "()"
locType = locType And Not VT_ARRAY
End If
GetStringTypeName = GetStringTypeName & " As "
Select Case locType
Case TliVarType.VT_BOOL: GetStringTypeName = GetStringTypeName & "Boolean"
Case TliVarType.VT_BSTR: GetStringTypeName = GetStringTypeName & "String"
Case TliVarType.VT_CY: GetStringTypeName = GetStringTypeName & "Currency"
Case TliVarType.VT_DATE: GetStringTypeName = GetStringTypeName & "Date"
Case TliVarType.VT_DISPATCH: GetStringTypeName = GetStringTypeName & "Object"
Case TliVarType.VT_HRESULT: GetStringTypeName = GetStringTypeName & "HRESULT"
Case TliVarType.VT_I2: GetStringTypeName = GetStringTypeName & "Integer"
Case TliVarType.VT_I4: GetStringTypeName = GetStringTypeName & "Long"
Case TliVarType.VT_R4: GetStringTypeName = GetStringTypeName & "Single"
Case TliVarType.VT_R8: GetStringTypeName = GetStringTypeName & "Double"
Case TliVarType.VT_UI1: GetStringTypeName = GetStringTypeName & "Byte"
Case TliVarType.VT_UNKNOWN: GetStringTypeName = GetStringTypeName & "IUnknown"
Case TliVarType.VT_VARIANT: GetStringTypeName = GetStringTypeName & "Variant"
Case TliVarType.VT_VOID: GetStringTypeName = GetStringTypeName & "Any"
Case TliVarType.VT_EMPTY
If Not v.TypeInfo Is Nothing Then
GetStringTypeName = GetStringTypeName & v.TypeInfo.Name
End If
End Select
End Function
Hmmm.. I don't understand. You want get information about current project from it? Or you want get information about any ActiveX dll?
There are many functions, and explanation of everything functions i think you don't find.Quote:
I want information about the functions in the VB rutime dll - ie: MSVBVM60.dll and vba6.dll
If you have question with some functions, ask here i'll answer.
Of course you can use debugger and disassembly for this purpose, but you should have knowledge in reverse-engineering.
You can find a explanation of function on network, because many functions already were used. Most of functions is same that standard functions. For example MsgBox is rtcMsgBox.
Many functions from vba6.dll is same that from MSVBVM. Some functions is without different, some functions has check runtime mode, and some functions has different behavior. In vba6.dll there are many functions for work with project, code. For example you can get a call-stack information at runtime or you can get objects which represent project, module etc. Also i add that almost each entity has COM-object, which supports many interfaces. As i wrote above in code EbGetExecutingProj retrieve a "project" object; for example TipGetModule retrieve a "module" object, but you can use a special IVBProject (name chosen arbitrary) method for retrieve this object.
Thank you the trick
For what it's worth, the thread was originally located on this thread: http://www.vbforums.com/showthread.p...97#post4901797
Dear the trick, can we get a line of code from vb6 IDE
when we using the Erl() function, it only return the wrong line in Proc, but it did not return the wrong line code in string
can we make it in IDE and EXE?
in VB6 AddIn we can use CodePane.GetSelection and CodeModule.Lines to get a line of source code string
Hello The trick ,can you show me an example of how to call any function exported by msvbvm60.dll say rtcMessageBox can be called instead of MsgBox since it is said that MsgBox
calls rtcMsgBox.When I try to use rtcMsgBox directly instead of MsgBox it crashes.I declared rtcMsgBox as follows:
Private Declare Sub rtcMsgBox Lib "msvbvm60" (byval str as string)
I donot know whether the above declaration is correct.Is there any code which takes vba6 or msvbvm60 dll and returns correct signature of exported function.
How to get the correct no and type of parameters and return type of msvbvm60.dll exported functions and use then correctly so that the application will not crash even when used in c using loadlibrary and getprocaddress
Thanks.
Hello the trick,
I tried vb6 standalone application containing only single module(ModMain.bas) with startup as Main and no forms by changing the declaration of rtcMessageBox as follows which is similar to MsgBox declaration:
ModMain.bas
Code:Private Declare Function rtcMsgBox Lib "msvbvm60" ( _
Str As String , _
Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, _
Optional Title As String = "", _
Optional ByVal TimeOutMSec As Long = 0, _
Optional flags As Long = 0, _
Optional ByVal hwnd As Long = 0) As VbMsgBoxResult
Sub Main()
rtcMsgBox "in main" 'crashes here
End Sub
But the app crashes at rtcMsgBox call but works fine when I use MsgBox instead of rtcMsgBox.
Am I doing something wrong and Is there anything more I have to do to make it work fine like MsgBox.
Thanks.
See declaration in the Object Browser.
Code:Private Declare Function rtcMsgBox Lib "msvbvm60" ( _
ByRef vPrompt As Variant, _
Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, _
Optional ByRef vTitle As Variant, _
Optional ByRef vHelpFile As Variant, _
Optional ByRef vContext As Variant) As VbMsgBoxResult
Hello The Trick,
Thanks for the reply and it worked fine in vb6.But when I use the same like the below code in win32 console c application using loadlibrary and getprocaddress it crashes without displaying msgbox.
What should I do to make it work.
Thanks.
rtcmsgbox_in_c.c/*c code*/
Code:#include <stdio.h>
#include <windows.h>
// Exported VB function
typedef DWORD (__stdcall * PFUNC)(VARIANT* ,int,VARIANT*,VARIANT*,VARIANT*);
int main(int argc, char* argv[])
{
HINSTANCE hMod = 0;
PFUNC pFunc = NULL;
VARIANT x1,x2,x3,x4 ;
VariantInit(&x1);
x1.vt = VT_BSTR;
x1.bstrVal = SysAllocString(L"Hello world1");
VariantInit(&x2);
x2.vt = VT_BSTR;
x2.bstrVal = SysAllocString(L"Hello world2");
VariantInit(&x3);
x3.vt = VT_BSTR;
x3.bstrVal = SysAllocString(L"Hello world3");
VariantInit(&x4);
x4.vt = VT_BSTR;
x4.bstrVal = SysAllocString(L"Hello world4");
printf( "lib rtcMsgBox\n");
// Load the VB DLL:
hMod = LoadLibrary("msvbvm60.dll");//success
if (hMod)
{
// Call the export:
pFunc = (PFUNC)GetProcAddress(hMod, "rtcMsgBox");//success
if (pFunc)
{
printf( " rtcMsgBox msvbvm\n");
pFunc(&x1,0,&x2,&x3,&x4);//crashes without displaying msgbox
printf( " rtcMsgBox after\n");
VariantClear(&x1);
VariantClear(&x2);
VariantClear(&x3);
VariantClear(&x4);
} else
printf("proc not found rtcMsgBox\n");
FreeLibrary (hMod);
} else
printf("error lib\n");
return 0;
}
You need to initialize STA, runtime and project context.
@smkperu: Have you ever thought about implementing some more simple projects first?
How about instead of thinkering w/ mutli-threading and FFI across different languages you start with the proverbial School Library project in VB6 or C/C++?
cheers,
</wqw>
Hello the trick,
I donot know whether I am correct.I use structures in c but no classes and objects.Correct me if I am wrong.
Thanks
You can work with COM in C as well as in C++.
Hello the Trick,
If we can use C as said above can I create simple VB6-AXDll object using C code and display msgbox without crash.
I also have doubt about the line
pFunc(&x1,0,&x2,&x3,&x4); //rtcMsgBox api call
in the c code whether it will work fine in the sense whether I am passing parameters correctly even when we somehow create simple VB6-AXDll object
Thanks
Just initialize STA and create a VB6 AxDll object (using CoCreateInstance for example). Because of MsgBox requires project-specific data you need to initialize a project context (for example to display the project title in MsgBox). The simpliest method is to create an object instance of the project.
This is screenshot of calling rtcMsgBox from pure-C code:
https://www.vbforums.com/images/ieimages/2021/12/9.png
Hello The Trick,
I understood that we have to use APIs like CoInitialize() and CoCreateInstance to init project and runtime.
I modified the application by incorporating the changes as below.But still the application crashes at rtcMessageBox call.Still something is missing.
Thanks
Code:#include <stdio.h>
#include <windows.h>
#include <ole2.h>
// Exported VB function
typedef LONG (__stdcall * PFUNC)(VARIANT *,LONG,VARIANT*,VARIANT*,VARIANT*);
static const GUID xyz = { 0x98e1a1d8, 0x07bc, 0x4925, { 0x8f, 0xd0, 0x2b, 0xd5, 0xa9, 0x6e, 0xf8, 0xf1 } };
int main(int argc, char* argv[])
{
HINSTANCE hMod = 0;
IUnknown *x=NULL;
PFUNC pFunc = NULL;
VARIANT x1,x2,x3,x4;
if (SUCCEEDED(CoInitialize(NULL)));//new change
if (SUCCEEDED(CoCreateInstance(&xyz,NULL,CLSCTX_INPROC_SERVER,&IID_IUnknown,&x)));//new change
{
x1.vt = VT_BSTR;
x1.bstrVal = SysAllocString(L"Hello world1");
printf( "lib rtcMsgBox\n");
x2.vt=x3.vt=x4.vt=VT_ERROR;//new change
x2.scode=x3.scode=x4.scode=DISP_E_PARAMNOTFOUND;//new change
// Load the VB DLL:
hMod = LoadLibrary("msvbvm60.dll");//success
if (hMod)
{
// Call the export:
pFunc = (PFUNC)GetProcAddress(hMod, "rtcMsgBox");//success
if (pFunc)
{
printf( " rtcMsgBox msvbvm\n");
pFunc(&x1,0,&x2,&x3,&x4);//crashes without displaying msgbox
printf( " rtcMsgBox after\n");
VariantClear(&x1);
} else
printf("proc not found rtcMsgBox\n");
FreeLibrary (hMod);
} else
printf("error lib\n");
}
return 0;
}
Your CoCreateInstance call isn't SUCCEEDED (remove semicolon). You should use valid CLSID of an object in an VB6-produced-AxDll library.
Hello the Trick,
So you mean we must use another vb6 dll application for using a exported API of msvbvm60.dll by exporting the API through the vb Ax dll.
We can use MessageBox windows api directly in c instead of this overhead.Is there any way to avoid overhead and do this in a simple way just by using some API directly.
Thanks.
Hello The Trick,
How to get
static const GUID CLSID_CCORE = { 0x98e1a1d8, 0x07bc, 0x4925, { 0x8f, 0xd0, 0x2b, 0xd5, 0xa9, 0x6e, 0xf8, 0xf1 } };
value of vb ax dll used in c code.
In your c app you exported rtcMsgBox also from the same vb Ax dll.
Because of these two dependencies I wanted other way to use like as you said instantiating project manually.
Thanks
You didn't answer the question.
Hello The Trick,
I could first understand rtcMsgBox declaration from you and I thought I could use in vb6 and did it easily just by call.
So I tried the same and understood that it is not so easy to do in c code since project has to be initialized as you said
but using another vb6 app(vb Ax dll) in addition which was not the case when I use export in vb6 app directly.
As I said I wanted to avoid overhead of using another application(VB Ax Dll) in order to use a export function in c if
possible .
Thanks
Use standard MessageBox api as Olaf suggested.
Hello The Trick,
Yes as suggested I can use MessageBox API for this rtcMsgBox API.But there are many exported functions like this in msvbvm60.dll as you said for which I may not be knowing equivalent in c and therefore for using them we have to use
them directly like rtcMsgBox.
Thanks
The background behind 'the tricks' question above is,
that nearly all the functions of msvbvm60.dll are covered already by "system-layer-Dlls",
like User32, Ole32, OleAut32...
For example the VB6-Format(...)-Function is contained in oleaut32.dll, described here:
https://docs.microsoft.com/en-us/win...auto-varformat
(along with a whole lot of other "Variant-Conversion-Functions", when you look at the left-hand-side of that MSDN-Page).
And as for the few functions wich are not covered - like e.g. GetMem4,
come on - you're working in C...
"copying 4 Bytes around" should be a childsplay using a bit of "C-Pointer-voodoo".
Olaf
Hello The Trick,
In msvbvm60.dll I have seen export functions like
EbLoadRunTime
EbCreateContext
Can these type of functions along with coinitialize which you showed in c code of help to initialize STA, runtime and project context. as you said You need to initialize STA, runtime and project context. so that we can make the rtcMsgBox to run without using VB AX dll.
Thanks
Hello The Trick,
There are many fumctions in msvbvm60.dll as follows as per DEPENDS utility as follows:
They start with rtc or Eb or _ or VBDll or DLLGet or Get or Tip etc.Code:ThunRTMain
VBDllUnRegisterServer
VBDllCanUnloadNow
VBDllRegisterServer
VBDllGetClassObject
UserDllMain
DllRegisterServer
DllUnregisterServer
__vbaAryLock
__vbaBoolErrVar
__vbaRedimVar2
__vbaStrErrVarCopy
__vbaVarLateMemCallLd
__vbaVarLateMemCallLdRf
__vbaVarLateMemCallSt
__vbaVarLateMemSt
__vbaVarLateMemStAd
__vbaAryVarVarg
__vbaFpCDblR4
__vbaFpCDblR8
__vbaFpCSngR4
__vbaFpCSngR8
__vbaFpCmpCy
__vbaFpCy
__vbaFpI2
__vbaFpI4
__vbaFpR4
__vbaFpR8
__vbaFpUI1
__vbaFreeObj
__vbaFreeStr
__vbaFreeVar
__vbaFreeVarg
__vbaI2Abs
__vbaI2I4
__vbaI2Sgn
__vbaI4Abs
__vbaI4Sgn
__vbaStrCopy
__vbaStrMove
__vbaUI1I2
__vbaUI1I4
__vbaUI1Sgn
__vbaVarCopy
__vbaVarDup
__vbaVarMove
__vbaVarVargNofree
__vbaVarZero
__vbaVargParmRef
__vbaVargVar
__vbaVargVarCopy
__vbaVargVarMove
__vbaVargVarRef
DLLGetDocumentation
DllCanUnloadNow
DllGetClassObject
_CIatan
_CIcos
_CIexp
_CIlog
_CIsin
_CIsqrt
_CItan
__vbaAptOffset
__vbaAryConstruct2
__vbaAryConstruct
__vbaAryCopy
__vbaAryDestruct
__vbaAryMove
__vbaAryRebase1Var
__vbaAryRecCopy
__vbaAryRecMove
__vbaAryUnlock
__vbaAryVar
__vbaBoolStr
__vbaBoolVar
__vbaBoolVarNull
__vbaCVarAryUdt
__vbaCastObj
__vbaCastObjVar
__vbaCheckType
__vbaCheckTypeVar
__vbaChkstk
__vbaCopyBytes
__vbaCopyBytesZero
__vbaCyAbs
ProcCallEngine
DllFunctionCall
__vbaCyAdd
__vbaCyErrVar
CopyRecord
__vbaCyFix
__vbaCyForInit
__vbaCyForNext
__vbaCyI2
TipGetAddressOfPredeclaredInstance
__vbaCyI4
__vbaCyInt
__vbaCyMul
MethCallEngine
__vbaCyMulI2
__vbaCySgn
__vbaCyStr
__vbaCySub
__vbaCyUI1
__vbaCyVar
__vbaDateR4
__vbaDateR8
__vbaDateStr
__vbaDateVar
__vbaDerefAry
__vbaDerefAry1
__vbaEnd
__vbaErase
__vbaEraseKeepData
__vbaEraseNoPop
__vbaError
__vbaErrorOverflow
__vbaExceptHandler
__vbaExitEachAry
TipSetOption
__vbaExitEachColl
__vbaExitEachVar
__vbaExitProc
__vbaFPException
__vbaFPFix
__vbaFPInt
TipUnloadProject
__vbaFailedFriend
__vbaFileClose
TipCreateInstanceProject2
EbResetProject
EbGetHandleOfExecutingProject
__vbaFileCloseAll
__vbaFileLock
__vbaFileOpen
__vbaFileSeek
__vbaFixstrConstruct
__vbaForEachAry
__vbaForEachCollAd
__vbaForEachCollObj
__vbaForEachCollVar
__vbaForEachVar
__vbaFreeObjList
__vbaFreeStrList
__vbaFreeVarList
__vbaGenerateBoundsError
__vbaGet3
__vbaGet4
__vbaGetFxStr3
__vbaGetFxStr4
__vbaGetOwner3
__vbaGetOwner4
__vbaGosub
__vbaGosubFree
__vbaGosubReturn
__vbaHresultCheck
__vbaHresultCheckNonvirt
__vbaHresultCheckObj
__vbaI2Cy
__vbaI2ErrVar
__vbaI2ForNextCheck
__vbaI2Str
__vbaI2Var
__vbaI4Cy
EbResetProjectNormal
TipUnloadInstance
__vbaI4ErrVar
EbLibraryLoad
EbLibraryUnload
__vbaI4ForNextCheck
EbLoadRunTime
__vbaI4Str
__vbaI4Var
EbCreateContext
EbDestroyContext
EbSetContextWorkerThread
__vbaInStr
__vbaInStrB
__vbaInStrVar
__vbaInStrVarB
__vbaInputFile
__vbaLateIdCall
__vbaLateIdCallLd
EbGetErrorInfo
__vbaLateIdCallSt
__vbaLateIdNamedCall
__vbaLateIdNamedCallLd
__vbaLateIdNamedCallSt
__vbaLateIdNamedStAd
__vbaLateIdSt
__vbaLateIdStAd
__vbaLateMemCall
__vbaLateMemCallLd
__vbaLateMemCallSt
__vbaLateMemNamedCall
__vbaLateMemNamedCallLd
__vbaLateMemNamedCallSt
EbIsProjectOnStack
TipCreateInstanceEx
GetMem2
GetMem4
GetMem8
GetMemStr
GetMemVar
GetMemObj
PutMem2
PutMem4
PutMem8
PutMemStr
PutMemVar
PutMemObj
SetMemVar
SetMemObj
GetMemNewObj
PutMemNewObj
SetMemNewObj
GetMem1
PutMem1
GetMemEvent
PutMemEvent
SetMemEvent
__vbaLateMemNamedStAd
__vbaLateMemSt
__vbaLateMemStAd
__vbaLbound
__vbaLdZeroAry
__vbaLenBstr
__vbaLenBstrB
__vbaLenVar
__vbaLenVarB
__vbaLineInputStr
__vbaLineInputVar
__vbaLsetFixstr
__vbaLsetFixstrFree
__vbaMidStmtBstr
__vbaMidStmtBstrB
__vbaMidStmtVar
__vbaMidStmtVarB
__vbaNameFile
__vbaNew2
__vbaNew
__vbaNextEachAry
__vbaNextEachCollAd
__vbaNextEachCollObj
__vbaNextEachCollVar
__vbaNextEachVar
__vbaObjAddref
__vbaObjIs
__vbaObjSet
__vbaObjSetAddref
__vbaObjVar
__vbaOnError
__vbaOnGoCheck
__vbaPowerR8
__vbaPrintFile
__vbaPrintObj
__vbaPut3
__vbaPut4
__vbaPutFxStr3
__vbaPutFxStr4
__vbaPutOwner3
__vbaPutOwner4
__vbaR4Cy
__vbaR4ErrVar
__vbaR4ForNextCheck
__vbaR4Sgn
__vbaR4Str
__vbaR4Var
__vbaR8Cy
__vbaR8ErrVar
__vbaR8FixI2
__vbaR8FixI4
__vbaR8ForNextCheck
__vbaR8IntI2
__vbaR8IntI4
__vbaR8Sgn
__vbaR8Str
__vbaR8Var
__vbaRaiseEvent
__vbaRecAnsiToUni
__vbaRecAssign
__vbaRecDestruct
__vbaRecDestructAnsi
__vbaRecUniToAnsi
__vbaRedim
__vbaRedimPreserve
__vbaRedimPreserveVar
__vbaRedimPreserveVar2
__vbaRedimVar
__vbaRefVarAry
__vbaResume
__vbaRsetFixstr
__vbaRsetFixstrFree
__vbaSetSystemError
__vbaStopExe
__vbaStr2Vec
__vbaStrAryToAnsi
__vbaStrAryToUnicode
__vbaStrBool
EVENT_SINK_QueryInterface
EVENT_SINK_AddRef
EVENT_SINK_Release
EVENT_SINK_GetIDsOfNames
EVENT_SINK_Invoke
__vbaStrCat
__vbaStrCmp
__vbaStrComp
__vbaStrCompVar
__vbaStrCy
BASIC_CLASS_QueryInterface
BASIC_CLASS_AddRef
BASIC_CLASS_Release
BASIC_CLASS_GetIDsOfNames
BASIC_CLASS_Invoke
__vbaStrDate
__vbaStrFixstr
__vbaStrI2
__vbaStrI4
__vbaStrLike
BASIC_DISPINTERFACE_GetTICount
BASIC_DISPINTERFACE_GetTypeInfo
__vbaStrR4
__vbaStrR8
__vbaStrTextCmp
__vbaStrTextLike
__vbaStrToAnsi
__vbaStrToUnicode
__vbaStrUI1
__vbaStrVarCopy
Zombie_QueryInterface
Zombie_AddRef
Zombie_Release
Zombie_GetTypeInfoCount
Zombie_GetTypeInfo
Zombie_GetIDsOfNames
Zombie_Invoke
__vbaStrVarMove
__vbaStrVarVal
__vbaUI1Cy
EVENT_SINK2_AddRef
EVENT_SINK2_Release
__vbaUI1ErrVar
__vbaUI1Str
__vbaUI1Var
__vbaUbound
__vbaUdtVar
__vbaUnkVar
__vbaVar2Vec
__vbaVarAbs
__vbaVarAdd
__vbaVarAnd
__vbaVarCat
__vbaVarCmpEq
__vbaVarCmpGe
__vbaVarCmpGt
__vbaVarCmpLe
__vbaVarCmpLt
__vbaVarCmpNe
__vbaVarDateVar
__vbaVarDiv
__vbaVarEqv
__vbaVarErrI4
__vbaVarFix
__vbaVarForInit
__vbaVarForNext
__vbaVarIdiv
__vbaVarImp
__vbaVarIndexLoad
__vbaVarIndexLoadRef
__vbaVarIndexLoadRefLock
__vbaVarIndexStore
__vbaVarIndexStoreObj
__vbaVarInt
__vbaVarLike
__vbaVarLikeVar
__vbaVarMod
__vbaVarMul
__vbaVarNeg
__vbaVarNot
__vbaVarOr
__vbaVarPow
__vbaVarSetObj
__vbaVarSetObjAddref
__vbaVarSetUnk
__vbaVarSetUnkAddref
__vbaVarSetVar
__vbaVarSetVarAddref
__vbaVarSub
__vbaVarTextCmpEq
__vbaVarTextCmpGe
__vbaVarTextCmpGt
__vbaVarTextCmpLe
__vbaVarTextCmpLt
__vbaVarTextCmpNe
__vbaVarTextLike
__vbaVarTextLikeVar
__vbaVarTextTstEq
__vbaVarTextTstGe
__vbaVarTextTstGt
__vbaVarTextTstLe
__vbaVarTextTstLt
__vbaVarTextTstNe
__vbaVarTstEq
__vbaVarTstGe
__vbaVarTstGt
__vbaVarTstLe
__vbaVarTstLt
__vbaVarTstNe
__vbaVarXor
__vbaVargObj
__vbaVargObjAddref
rtcLeftBstr
rtcLeftVar
rtcRightBstr
rtcRightVar
rtcAnsiValueBstr
rtcLowerCaseBstr
rtcLowerCaseVar
rtcTrimBstr
rtcTrimVar
rtcLeftTrimBstr
rtcLeftTrimVar
rtcRightTrimBstr
rtcRightTrimVar
rtcSpaceBstr
rtcSpaceVar
rtcUpperCaseBstr
rtcUpperCaseVar
rtcKillFiles
rtcChangeDir
rtcMakeDir
rtcRemoveDir
rtcChangeDrive
rtcBeep
rtcGetTimer
rtcStrFromVar
rtcBstrFromAnsi
rtcPackDate
rtcPackTime
rtcGetDateValue
rtcGetTimeValue
rtcGetDayOfMonth
rtcGetHourOfDay
rtcGetMinuteOfHour
rtcGetMonthOfYear
rtcGetPresentDate
rtcGetSecondOfMinute
rtcSetDateVar
rtcSetDateBstr
rtcSetTimeVar
rtcSetTimeBstr
rtcGetDayOfWeek
rtcGetYear
rtcFileReset
rtcFileAttributes
rtcIsArray
rtcIsDate
rtcIsEmpty
rtcIsError
rtcIsNull
rtcIsNumeric
rtcIsObject
rtcVarType
rtDecFromVar
rtcFileWidth
rtcInputCount
rtcInputCountVar
rtcFileSeek
rtcFileLocation
rtcFileLength
rtcEndOfFile
rtcHexBstrFromVar
rtcHexVarFromVar
rtcOctBstrFromVar
rtcOctVarFromVar
rtcFileCopy
rtcFileDateTime
rtcFileLen
rtcGetFileAttr
rtcSetFileAttr
rtcR8ValFromBstr
rtcSin
rtcCos
rtcTan
rtcAtn
rtcExp
rtcLog
rtcRgb
rtcQBColor
rtcMacId
rtcTypeName
rtcIsMissing
rtcRandomNext
rtcRandomize
rtcMsgBox
rtcInputBox
rtcAppActivate
rtcDoEvents
rtcSendKeys
rtcShell
rtcArray
__vbaVargUnk
__vbaVargUnkAddref
__vbaVerifyVarObj
rtcGetErl
rtcStringBstr
rtcStringVar
rtcVarBstrFromAnsi
rtcGetDateBstr
rtcGetDateVar
rtcGetTimeBstr
rtcGetTimeVar
rtcVarStrFromVar
rtcSqr
rtcIMEStatus
rtcLeftCharBstr
rtcLeftCharVar
rtcRightCharBstr
rtcRightCharVar
rtcInputCharCount
rtcInputCharCountVar
rtcStrConvVar
__vbaWriteFile
rtcGetHostLCID
rtcCreateObject
rtcGetObject
rtcAppleScript
rtcMidBstr
rtcMidVar
rtcInStr
rtcMidCharBstr
rtcMidCharVar
rtcInStrChar
rtBstrFromErrVar
rtBoolFromErrVar
rtCyFromErrVar
rtI2FromErrVar
rtI4FromErrVar
rtR4FromErrVar
rtR8FromErrVar
rtcDateFromVar
rtcVarFromVar
rtcCVErrFromVar
VarPtr
rtcDir
rtcCurrentDirBstr
rtcCurrentDir
rtcFreeFile
rtcCompareBstr
rtcBstrFromFormatVar
rtcBstrFromError
rtcVarFromError
rtcLenCharVar
rtcLenVar
rtcFixVar
rtcAbsVar
rtcIntVar
rtcSgnVar
_adj_fdiv_m16i
rtcVarFromFormatVar
rtcDateAdd
rtcDateDiff
rtcDatePart
rtcPartition
rtcChoose
rtcEnvironVar
rtcEnvironBstr
rtcSwitch
rtcCommandBstr
rtcCommandVar
rtcSLN
rtcSYD
rtcDDB
rtcIPMT
rtcPPMT
rtcPMT
rtcPV
rtcFV
rtcNPer
rtcRate
rtcImmediateIf
rtcIRR
rtcMIRR
rtcNPV
rtcErrObj
rtUI1FromErrVar
rtcVarDateFromVar
_adj_fdiv_m32
rtcGetSetting
rtcSaveSetting
rtcDeleteSetting
rtcGetAllSettings
rtcByteValueBstr
rtcBstrFromByte
rtcVarBstrFromByte
rtcCharValueBstr
rtcBstrFromChar
rtcVarBstrFromChar
rtcSetCurrentCalendar
rtcGetCurrentCalendar
_adj_fdiv_m32i
rtcFormatNumber
rtcFormatCurrency
rtcFormatPercent
rtcFormatDateTime
rtcWeekdayName
rtcMonthName
rtcFilter
rtcInStrRev
rtcJoin
rtcSplit
rtcReplace
rtcStrReverse
rtcRound
rtcCallByName
rtcCreateObject2
rtcStrConvVar2
_adj_fdiv_m64
_adj_fdiv_r
_adj_fdivr_m16i
_adj_fdivr_m32
_adj_fdivr_m32i
_adj_fdivr_m64
_adj_fpatan
_adj_fprem
_adj_fprem1
_adj_fptan
_allmul
...
TipInvokeMethod2
...
TipInvokeMethod
...
IID_IVbaHost
EbGetObjConnectionCounts
...
...
...
...
...
CreateIExprSrvObj
...
EbGetVBAObject
For GetMemX there is c rtlmovememory.
For rtcMsgBox there is c MessageBox. etc
For DLLGetxxx there is c DLLGetxxx
For Eb ???
For VBDll ???
For Tip ???
For _ ???
So there are different types of exports.
Is there any other way that I could manually init STA,project context,runtime ie simulate the vb AX dll functionality so that I can use export functions of msvbvm60.dll if I know the declaration of the export function.
Thanks
You don't need any equvalent in C.
No. rtcMsgBox has different behavior when you have unattended execution option in a project.
You don't need the most of functions outside VB6-application especially in C.
Yes, there is a way to do manual initialization but i don't see reason to show it. This question looks like bunch of messages which i regularly get from script-kiddie-malware-developers which want to "bypass AV" etc. So if you want i help you to solve your issue you should explain (clear) why you want to use that method.
Hello The Trick,
For initializing project instead of using separate VB Ax Dll can we use the same msvbvm60.dll for
initializing STA and create a VB6 AxDll object so that overhead may be reduced.
Thanks.
Dear smkperu,
If you want to use msvbvm60.dll instead of a new activex dll there are two ways to initialize project:
1. Identifying a multiuse class from msvbvm60.dll activex dll and creating its instance using cocreateinstance after calling coinitialize just as shown by Trick in his C code.
or
2. Getting the VBHeader(EXEProjectInfo) structure from the msvbvm60.dll thru its module instance which you already have thru LoadLibrary("msvbvm60.dll") and calling VBDllGetClassObject( by passing the VBHeader as one of input parameters to it ) after calling coinitialize in same C code.
I donot know about the manual project initialization which only Trick can help.
regards,
JSVenu
Hello The Trick,
I made a simple win32 console c/c++ application which takes any .exe file and runs it from memory.It is similar to your Patcher vb6 application of VBLoader which loads a .exe into memory and removes the runtime without running it.
Can you show me how to add runtime to the .exe given as input to the above c/c++ console application using functions likeCode:// smkperupe.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<stdio.h>
#include<windows.h>
typedef long int (__stdcall* NtUnmapViewOfSectionF)(HANDLE,PVOID);
NtUnmapViewOfSectionF NtUnmapViewOfSection = (NtUnmapViewOfSectionF)GetProcAddress(LoadLibrary( "ntdll.dll"),"NtUnmapViewOfSection");
void RunFromMemory(char* pImage)
{
DWORD dwWritten = 0;
DWORD dwHeader = 0;
DWORD dwImageSize = 0;
DWORD dwSectionCount = 0;
DWORD dwSectionSize = 0;
DWORD firstSection = 0;
DWORD previousProtection = 0;
DWORD jmpSize = 0;
IMAGE_NT_HEADERS INH;
IMAGE_DOS_HEADER IDH;
IMAGE_SECTION_HEADER Sections[1000];
PROCESS_INFORMATION peProcessInformation;
STARTUPINFO peStartUpInformation;
CONTEXT pContext;
char* pMemory;
char* pFile;
char pPath[MAX_PATH];
GetModuleFileName(NULL,pPath,MAX_PATH);
char* lfMemory;
int fSize;
FILE* pLocalFile = fopen(pPath,"rb");
fseek(pLocalFile,0,SEEK_END);
fSize = ftell(pLocalFile);
rewind(pLocalFile);
lfMemory = (char*)malloc(fSize);
fread(lfMemory,1,fSize,pLocalFile);
fclose(pLocalFile);
memcpy(&IDH,lfMemory,sizeof(IDH));
memcpy(&INH,(void*)((DWORD)lfMemory+IDH.e_lfanew),sizeof(INH));
free(lfMemory);
DWORD localImageBase = INH.OptionalHeader.ImageBase;
DWORD localImageSize = INH.OptionalHeader.SizeOfImage;
memcpy(&IDH,pImage,sizeof(IDH));
memcpy(&INH,(void*)((DWORD)pImage+IDH.e_lfanew),sizeof(INH));
dwImageSize = INH.OptionalHeader.SizeOfImage;
pMemory = (char*)malloc(dwImageSize);
memset(pMemory,0,dwImageSize);
pFile = pMemory;
dwHeader = INH.OptionalHeader.SizeOfHeaders;
firstSection = (DWORD)(((DWORD)pImage+IDH.e_lfanew) + sizeof(IMAGE_NT_HEADERS));
memcpy(Sections,(char*)(firstSection),sizeof(IMAGE_SECTION_HEADER)*INH.FileHeader.NumberOfSections);
memcpy(pFile,pImage,dwHeader);
if((INH.OptionalHeader.SizeOfHeaders % INH.OptionalHeader.SectionAlignment)==0)
jmpSize = INH.OptionalHeader.SizeOfHeaders;
else
{
jmpSize = INH.OptionalHeader.SizeOfHeaders / INH.OptionalHeader.SectionAlignment;
jmpSize += 1;
jmpSize *= INH.OptionalHeader.SectionAlignment;
}
pFile = (char*)((DWORD)pFile + jmpSize);
for(dwSectionCount = 0; dwSectionCount < INH.FileHeader.NumberOfSections; dwSectionCount++)
{
jmpSize = 0;
dwSectionSize = Sections[dwSectionCount].SizeOfRawData;
memcpy(pFile,(char*)(pImage + Sections[dwSectionCount].PointerToRawData),dwSectionSize);
if((Sections[dwSectionCount].Misc.VirtualSize % INH.OptionalHeader.SectionAlignment)==0)
jmpSize = Sections[dwSectionCount].Misc.VirtualSize;
else
{
jmpSize = Sections[dwSectionCount].Misc.VirtualSize / INH.OptionalHeader.SectionAlignment;
jmpSize += 1;
jmpSize *= INH.OptionalHeader.SectionAlignment;
}
pFile = (char*)((DWORD)pFile + jmpSize);
}
memset(&peStartUpInformation,0,sizeof(STARTUPINFO));
memset(&peProcessInformation,0,sizeof(PROCESS_INFORMATION));
memset(&pContext,0,sizeof(CONTEXT));
peStartUpInformation.cb = sizeof(peStartUpInformation);
if(CreateProcess(NULL,pPath,NULL,NULL,0,CREATE_SUSPENDED, NULL,NULL,&peStartUpInformation,&peProcessInformation))
{
pContext.ContextFlags = CONTEXT_FULL;
GetThreadContext(peProcessInformation.hThread,&pContext);
if(INH.OptionalHeader.ImageBase==localImageBase&&INH.OptionalHeader.SizeOfImage<=localImageSize)
VirtualProtectEx(peProcessInformation.hProcess,(LPVOID)(INH.OptionalHeader.ImageBase),dwImageSize,PAGE_EXECUTE_READWRITE,&previousProtection);
else
{
NtUnmapViewOfSection(peProcessInformation.hProcess,(PVOID)(localImageBase));
VirtualAllocEx(peProcessInformation.hProcess,(LPVOID)(INH.OptionalHeader.ImageBase),dwImageSize,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
}
WriteProcessMemory(peProcessInformation.hProcess,(void*)(INH.OptionalHeader.ImageBase),pMemory,dwImageSize,&dwWritten);
WriteProcessMemory(peProcessInformation.hProcess,(void*)(pContext.Ebx + 8),&INH.OptionalHeader.ImageBase,4,&dwWritten);
pContext.Eax = INH.OptionalHeader.ImageBase + INH.OptionalHeader.AddressOfEntryPoint;
SetThreadContext(peProcessInformation.hThread,&pContext);
VirtualProtectEx(peProcessInformation.hProcess,(void*)(INH.OptionalHeader.ImageBase),dwImageSize,previousProtection,0);
ResumeThread(peProcessInformation.hThread);
}
free(pMemory);
}
int main(int argc,char* argv[])
{
char* lpMemory;
int fSize;
FILE* pFile = fopen("inputapp.exe","rb");// full path of .exe
fseek(pFile,0,SEEK_END);
fSize = ftell(pFile);
rewind(pFile);
lpMemory = (char*)malloc(fSize);
if(lpMemory==NULL)return 0;
fread(lpMemory,1,fSize,pFile);
fclose(pFile);
RunFromMemory(lpMemory);
return 0;
}
AddRuntimeToIAT similar to RemoveRuntimeFromIAT(of Patcher app of VBLoader)
FillRuntimeImport similar to ClearRuntimeImport(of Patcher app of VBLoader )
So that in addition I can add runtime and then run my .exe in memory using the above c/c++ console app so that I can display rtcMsgBox properly.
Thanks
You haven't explained why you really need it. It's look like a "malware".
There is nothing exported from msvbvm60.dll which cannot be done in "normal fashion" from C/C++ so using rtcMsgBox is hilarious at least.
This whole thread looks like a very unhealthy interest in VB6 runtime.
cheers,
</wqw>
Hello The Trick,
I donot know what to answer.
I already explained the need that when I am already using dll(msvbvm60.dll) can I avoid using another vb6 Ax dll since one dll is better than using two since it avoids the overhead of using another dll.
JSVenu has suggested a way to use msvbvm60.dll directly instead of a second VB Ax dll which I could not understand.
I have gone thru your VBLoader https://www.vbforums.com/showthread....ithout-runtime
from which based on your patch application for removing runtime I developed a simple Win32 c/c++ console app for which if we can add runtime to input .exe we could run the said rtc... API calls properly.
Thanks
Smkperu, DLLs can (and often do) have dependencies just like our main program can. I don't know for sure, but you're probably already loading up things like Kernel32.dll and User32.dll anyway, even if you're not directly referencing them. So, since they're loaded anyway, why not just directly use them? That sort of obviates your explanation.
Hello The Trick,
I tried to add the msvbvm60.dll imports using PE editor tool for a simple vb6 standard exe application which calls rtcMsgBox for which the runtime was removed using patcher of vbloader.The application worked fine.
I also tried your c/c++ application which worked fine after initializing project using coinitialize and cocreateinstance.
I tried this even in new thread using createthread api for which even in the new thread function it works fine only after initializing project using coinitialize and cocreateinstance.
I understood that adding runtime imports only works for main thread and not for new threads.
Can you show me an API like EbLoadRuntime which works for new thread in vb6 and which can be used in c/c++ in any thread for initializing project so that I can display rtc... APIs without crash.
What are the parameters of EbLoadRuntime and what is usage of it.
How can I use the above API if possible or any other APIs in vb6 as well as c/c++ so that the project is initialized properly for displaying rtc... APIs.
Thanks.
Hello the Trick,
When we display call stack using dbghelp.dll using stackwalk api we get
__vbaS calls ThunRTMain calls EbLoadRunTime calls main calls ...
for a simple vb6 standard exe project with a simple sub main with genarate debugging information enabled.
This confirms that EbLoadRunTime loads runtime.
Can you help me what are the parameters to be passed to EbLoadRunTime to make it to work even in new thread for the same vb6 std exe.
Thanks
Hello Trick,
You have shown me how to use undocumented rtcMsgBox API of msvbvm60.dll properly using parameters properly.
As per your guidance in the link https://www.vbforums.com/showthread....=1#post5548715 the following is a simple working example which displays msgbox using undocumented rtcMsgBox API of msvbvm60.dll in c/c++ win32 console application as follows:
Code:#include <stdio.h>
#include <windows.h>
#include <ole2.h>
#include <objbase.h>
// Exported VB function
typedef LONG (__stdcall * PFUNC)(VARIANT *,LONG,VARIANT*,VARIANT*,VARIANT*);
int main(int argc, char* argv[])
{
HINSTANCE hMod = 0;
IUnknown *x=NULL;
PFUNC pFunc = NULL;
VARIANT x1,x2,x3,x4;
LPWSTR guidstr;
GUID guid;
CLSID clsid;
HRESULT hr;
MSG msg;
DWORD id;
LPOLESTR p;
p = OLESTR("vbrtc22.Class1");//actx dll vbrtc22 with empty dummy multiuse class Class1 and the vbrtc22.dll should
//be in the same folder as c/c++ console app exe
//"Getting Clsid from string name
hr = CLSIDFromProgID( p ,&guid);
if( hr != S_OK ){
//Failed to get Clsid from string");
return 1;
}
//initialize STA
if (SUCCEEDED(CoInitialize(NULL)))
//initialize project
if (SUCCEEDED(CoCreateInstance(&guid,NULL,CLSCTX_INPROC_SERVER,&IID_IUnknown,&x)))
{
x1.vt = VT_BSTR;
x1.bstrVal = SysAllocString(L"Hello world1");
printf( "lib rtcMsgBox\n");
x2.vt=x3.vt=x4.vt=VT_ERROR;//new change
x2.scode=x3.scode=x4.scode=DISP_E_PARAMNOTFOUND;
// Load the VB DLL:
hMod = LoadLibrary("msvbvm60.dll");
if (hMod)
{
// Call the export:
pFunc = (PFUNC)GetProcAddress(hMod, "rtcMsgBox");
if (pFunc)
{
printf( " rtcMsgBox msvbvm\n");
pFunc(&x1,0,&x2,&x3,&x4);
printf( " rtcMsgBox after\n");
VariantClear(&x1);
} else
printf("proc not found rtcMsgBox\n");
FreeLibrary (hMod);
} else
printf("error lib\n");
}
return 0;
}
Similarly can you show how to use VBDllGetClassObject undocumented API of msvbvm60.dll in the above console application just like rtcMsgBox properly without crash after which I shall mark as my query resolved.I don't mind whether
it is treated as vb6 or moved to c/c++ forum.
source code for both c/c++ win32 console app and vbrtc22 actx dll app attached in vbrtc22.zip
Thanks
Hello Trick,
I tried the above code with vbdllgetclassobject instead of rtcMsgBox in c/c++ win32 app as follows:
But it crashes at vbdllgetclassobject call as shown in code above.Code:#include <stdio.h>
#include <windows.h>
#include <ole2.h>
#include <objbase.h>
// Exported VB function
typedef LONG (__stdcall * PFUNC)(VARIANT *,LONG,VARIANT*,VARIANT*,VARIANT*);
typedef HRESULT (__stdcall * vbDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv);
typedef HRESULT (__stdcall * tVBDllGetClassObject)(HINSTANCE,long,void *,REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv);
int main(int argc, char* argv[])
{
HINSTANCE hMod = 0;
HINSTANCE hMod1 = 0;
HINSTANCE hMod2 = 0;
IUnknown *x=NULL;
PFUNC pFunc = NULL;
vbDllGetClassObject pvbDllGetClassObject = NULL;
tVBDllGetClassObject fVBDllGetClassObject =NULL;
VARIANT x1,x2,x3,x4;
LPWSTR guidstr;
GUID guid,guid1;
CLSID clsid;
HRESULT hr;
MSG msg;
DWORD id;
LPOLESTR p;
void *vbhdr;
////////////////////////////////////////////////
p = OLESTR("vbrtc22.Class1");
printf("\nGetting Clsid Struc from string name");
hr = CLSIDFromProgID( p ,&guid);// &clsid);
if( hr != S_OK )
{
printf("\nFailed to get Clsid from string");
return 1;
}
if (SUCCEEDED(CoInitialize(NULL)))//new change
if (SUCCEEDED(CoCreateInstance(&guid,NULL,CLSCTX_INPROC_SERVER,&IID_IUnknown,&x)))
{
//////////////////////////////////////////
////////////////////////////////////////////
// Load the VB DLL:
hMod1 = LoadLibrary("vbrtc22.dll");//success
hMod2 = LoadLibrary("msvbvm60.dll");
if (hMod1)
{
// Call the export:
pvbDllGetClassObject = (vbDllGetClassObject)GetProcAddress(hMod1, "DllGetClassObject");//success
fVBDllGetClassObject = (tVBDllGetClassObject)GetProcAddress(hMod2, "VBDllGetClassObject");//success
if (pvbDllGetClassObject)
{
vbhdr=(void*)((long)pvbDllGetClassObject+2);
printf( " vbdllgetclassobject msvbvm\n");
fVBDllGetClassObject(hMod1,0,vbhdr,&guid1,&IID_IUnknown,NULL);//crashes here
printf( " VBDllGetClassObject after\n");
// VariantClear(&x1);
} else
printf("proc not found VBDllGetClassObject\n");
FreeLibrary (hMod1);
} else
printf("error lib\n");
// }
}
return 0;
}
Am I sending the parameters in correct way.Please correct me to make it work fine.
code attached
thanks
Hello Trick,
When we use the following code c/c++ console app code the MsgBox is displayed.
Here we are creating instance of VbActxDllvb6 activex dll having multiuse class CMultiuseClass.Code:#include <stdafx.h>
#include <stdio.h>
#include <windows.h>
#include "msvbvm60.tlh"
//#include <ole2.h>
// Exported VB function
typedef LONG (__stdcall * PFUNC)(VARIANT *,LONG,VARIANT*,VARIANT*,VARIANT*);
IDispatch *IUnk=NULL;
int main(int argc, char* argv[])
{
HINSTANCE hMod = 0;
HINSTANCE hvb = 0;
IUnknown *x=NULL;
PFUNC pFunc = NULL;
PFUNC1 pFunc1 = NULL;
VARIANT x1,x2,x3,x4;
HRESULT hr;
int x1111=3;
int y;
CLSID clsid;
LPOLESTR p = OLESTR("VbActxDll.CMultiuseClass");
printf("\nInitilizing COM library for thread");
hr = CoInitialize(NULL);
printf("\nGetting Clsid Struc from string name");
hr = CLSIDFromProgID( p , &clsid);
if( hr != S_OK ){
printf("\nFailed to get Clsid from string");
return 1;
}
printf("\nCreating Instance of Specified Clsid");
// create an instance and get IDispatch pointer
hr = CoCreateInstance( clsid,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDispatch ,
(void**) &IUnk
);
if ( hr != S_OK )
{
printf("\nCoCreate failed");
return 1;
}
//{
x1.vt = VT_BSTR;
x1.bstrVal = SysAllocString(L"Hello world1");
printf( "lib rtcMsgBox\n");
x2.vt=VT_ERROR;
x3.vt=VT_ERROR;
x4.vt=VT_ERROR;
x2.scode=DISP_E_PARAMNOTFOUND;
x3.scode=DISP_E_PARAMNOTFOUND;
x4.scode=DISP_E_PARAMNOTFOUND;
// Load the VB DLL:
hMod = LoadLibrary("msvbvm60.dll");//success
// hMod = LoadLibrary("user32.dll");//success
if (hMod)
{
// Call the export:
pFunc = (PFUNC)GetProcAddress(hMod, "rtcMsgBox");//success
if (pFunc)
{
printf( " rtcMsgBox msvbvm\n");
pFunc(&x1,0,&x2,&x3,&x4);//crashes without displaying msgbox
printf( " rtcMsgBox after\n");
VariantClear(&x1);
} else
printf("proc not found rtcMsgBox\n");
FreeLibrary (hMod);
} else
printf("error lib\n");
return 0;
}
But when we use a ATL project Comobjvc and insert SimpleObject comobj
and then try to create instance of this comobj project as follows:
Code:LPOLESTR p = OLESTR("Comobjvc.comobj");//does not work
printf("\nInitilizing COM library for thread");
hr = CoInitialize(NULL);
printf("\nGetting Clsid Struc from string name");
hr = CLSIDFromProgID( p , &clsid);
if( hr != S_OK ){
printf("\nFailed to get Clsid from string");
return 1;
}
printf("\nCreating Instance of Specified Clsid");
// create an instance and get IDispatch pointer
hr = CoCreateInstance( clsid,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDispatch ,
(void**) &IUnk
);
the MsgBox is not displayed.
What is the difference between ATL simpleobject and vb6 activex dll multiuse class.
Can we create the same multiuse class functionality of vb6 in ATL or c/c++ so that the MsgBox can be displayed.
Please clarify?
ATL project attached
Thanks