Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSVBVM60 DLL redirections #360

Closed
WaynePhillipsEA opened this issue Aug 18, 2021 · 23 comments
Closed

MSVBVM60 DLL redirections #360

WaynePhillipsEA opened this issue Aug 18, 2021 · 23 comments

Comments

@WaynePhillipsEA
Copy link
Collaborator

Is your feature request related to a problem? Please describe.
There are some useful exported DLL functions from MSVBVM60 that VB6 developers are known to have used in their code via Declare statements. These pose a problem when switching on 64-bit support, since there is no 64-bit version of that DLL.

Describe the solution you'd like
I'd like the twinBASIC compiler to detect Declare statements into known MSVBVM60 endpoints, and redirect them to internal implementations that do the same thing.

Additional context
Let's start by making a list of the well known and most used exports from MSVBVM60 here so that we can consider them for automatic redirection by tB.

@Kr00l
Copy link
Collaborator

Kr00l commented Aug 18, 2021

Will the 32 bit version exports also be redirected by tB?
This would ensure a broader test basis and help reducing dependencies.

@WaynePhillipsEA
Copy link
Collaborator Author

Yes, the more dependencies we remove the better.

@Kr00l
Copy link
Collaborator

Kr00l commented Aug 18, 2021

I think the most used functions are GetMem and PutMem.

declare sub GetMem1 lib "msvbvm60.dll" (byVal addr as longPtr,  retVal As byte    )
declare sub GetMem2 lib "msvbvm60.dll" (byVal addr as longPtr,  retVal As integer )
declare sub GetMem4 lib "msvbvm60.dll" (byVal addr as longPtr,  retVal As long    )
declare sub GetMem8 lib "msvbvm60.dll" (byVal addr as longPtr,  retVal As currency)

declare sub PutMem1 lib "msvbvm60.dll" (byVal addr as longPtr, byVal newVal As byte    )
declare sub PutMem2 lib "msvbvm60.dll" (byVal addr as longPtr, byVal newVal As integer )
declare sub PutMem4 lib "msvbvm60.dll" (byVal addr as longPtr, byVal newVal As long    )
declare sub PutMem8 lib "msvbvm60.dll" (byVal addr as longPtr, byVal newVal As currency)

Then the VarPtr is often used to wrap around an aliased ArrPtr declare
declare function VarPtr lib "msvbvm60.dll" (byVal ptr as longPtr) as longPtr

Then the shadow object pointer stuff

declare function vbaObjSetAddref  lib "msvbvm60.dll" alias "__vbaObjSetAddref"  (dstObject as any, byVal srcObjPtr as longPtr) as long(Ptr?)
declare function vbaObjSet        lib "msvbvm60.dll" alias "__vbaObjSet"        (dstObject as any, byVal srcObjPtr as longPtr) as long(Ptr?)

Other memory functions similar to RtlMoveMemory/RtlZeroMemory

declare function vbaCopyBytes     lib "msvbvm60.dll" alias "__vbaCopyBytes"     (byVal length as long, dst as any, src as any) as long
declare function vbaCopyBytesZero lib "msvbvm60.dll" alias "__vbaCopyBytesZero" (byVal length as long, dst as any, src as any) as long

@wqweto
Copy link

wqweto commented Aug 18, 2021

Here is a link to a code search for "lib msvbvm60" in all of PSC organization here.

Overall Krool's list above covers 100% of msvbvm60 declares in my codebases.

@Kr00l
Copy link
Collaborator

Kr00l commented Aug 18, 2021

I believe it's a overkill to implement ALL exports from msvbvm60.
IMO just start with the most common used ones. #360 (comment)

Maybe if there are some more later on these could be also added, but not ALL.

@WaynePhillipsEA
Copy link
Collaborator Author

@Kr00l we'll just do the most widely used ones. Your list looks like a good start, and then we can add more later if they get reported.

@KarlSevenSeven
Copy link

Declare Function ComCtlsPtrToShadowObj Lib "msvbvm60.dll" Alias "__vbaObjSetAddref" (ByRef Destination As Any, ByVal lpObject As Long) As Long

Is used quite often ;-)

@Kr00l
Copy link
Collaborator

Kr00l commented Aug 20, 2021

Declare Function ComCtlsPtrToShadowObj Lib "msvbvm60.dll" Alias "__vbaObjSetAddref" (ByRef Destination As Any, ByVal lpObject As Long) As Long

Is used quite often ;-)

It's only an alias for a "better" name.
__vbaObjSetAddref is already covered in my list above.

@KarlSevenSeven
Copy link

@Kr00l
I see this now, sorry for my duplicate.

@WaynePhillipsEA
Copy link
Collaborator Author

These are now redirected to internal implementations as of v0.10.4755. If any more are wanted, just comment here and I'll re-open the issue.

@EduardoVB
Copy link

EduardoVB commented Sep 7, 2021

FYI I use:

Declare Function rtcCallByName Lib "msvbvm60" (ByRef vRet As Variant, ByVal cObj As Object, ByVal sMethod As Long, ByVal eCallType As VbCallType, ByRef pArgs() As Variant, ByVal LCID As Long) As Long
Declare Function rtcCallByNameIDE Lib "vba6" Alias "rtcCallByName" (ByRef vRet As Variant, ByVal cObj As Object, ByVal sMethod As Long, ByVal eCallType As VbCallType, ByRef pArgs() As Variant, ByVal LCID As Long) As Long

Here is why I needed it.
Or may be twinBASIC could provide a fix or workaround for the issue?

@bclothier
Copy link
Collaborator

I need a clarification here.

Those are set up for 32-bits but I imagine at least some of those expect a pointer data type and thus we need to update the declarations for 64-bits compatibility.

I'll use those 2 as an example:

Private Declare Function GetMem4 Lib "msvbvm60" (Src As Any, Dst As Any) As Long
Private Declare Function CopyBytesZero Lib "msvbvm60" Alias "__vbaCopyBytesZero" (ByVal Length As Long, Dst As Any, Src As Any) As Long

Based on my google search, the GetMem4 returns a HRESULT, so the Long should be unchanged.
However, the __vbaCopyBytesZero is harder one. Again, by googling, it's mentioned it's similar to RtlCopyMemory but the signatures don't quite match. I'm guessing that the return is just a HRESULT but the Length is one I'm not as sure. Should it be now a LongPtr?

So maybe this....

Private Declare PtrSafe Function GetMem4 Lib "msvbvm60" (Src As Any, Dst As Any) As Long
Private Declare PtrSafe Function CopyBytesZero Lib "msvbvm60" Alias "__vbaCopyBytesZero" (ByVal Length As LongPtr, Dst As Any, Src As Any) As Long

How would we know how to translate those functions since they are not documented so that it'll work on 64-bit tB? It may not be safe to assume that we can just narrow the pointers into a Long data type.

@Kr00l
Copy link
Collaborator

Kr00l commented Sep 19, 2021

AFAIK..

vbaCopyBytes is like RtlMoveMemory.
And vbaCopyBytesZero like RtlZeroMemory.

@Kr00l
Copy link
Collaborator

Kr00l commented Oct 17, 2021

Maybe it would be good to have a "information" compiler warning on msvbvm60 declares that it is redirected to allow for 64 bit.
A developer can then decide (after he got aware of this) to ignore them or to put as error so he can replace them.
Otherwise some folks don't have the awareness and think when switching to 64 bit it doesn't work..

@bclothier
Copy link
Collaborator

bclothier commented Apr 30, 2022

A minor suggestion. It might be useful to somehow indicate whether a redirection is happening or not. Maybe by highlighting the line or something like that so that it's clear that this Declare will be handled by the twinBASIC, even though the original DLL is not present.

What Kr00l already said above.

@Kr00l
Copy link
Collaborator

Kr00l commented Apr 30, 2022

A minor suggestion. It might be useful to somehow indicate whether a redirection is happening or not. Maybe by highlighting the line or something like that so that it's clear that this Declare will be handled by the twinBASIC, even though the original DLL is not present.

What Kr00l already said above.

I would have suggested my answer now again. Forgot that I suggested it already when you would not have edited your comment. :D

@wqweto
Copy link

wqweto commented Jul 21, 2022

Btw, are equivalent API declares from VBA runtime redirected?

For instance will this

Private Declare PtrSafe Function ArrPtr Lib "vbe7" Alias "VarPtr" (Ptr() As Any) As LongPtr

. . . get redirected the way ArrPtr lib msvbvm60 API declare is getting special treatment?

There are probably similar declares on old version vba6, not sure if there used to be vbe6 (like vbe7 now). Someone w/ VBA experience can chime in.

@Kr00l
Copy link
Collaborator

Kr00l commented Oct 28, 2022

Private Declare Function vbaCheckType Lib "msvbvm60" Alias "__vbaCheckType" (ByVal pObj As Any, ByRef pIID As Any) As Boolean

Seems to be interesting to add.

@fafalone
Copy link
Collaborator

I believe these same functions should be redirected when they appear as calls to msvbvm50.dll as well; noticed the issue when I got a 'can't load DLL' on
Private Declare Function VarPtrArray Lib "msvbvm50" Alias "VarPtr" (Ptr() As Any) As Long

I know there's no concern for VB5 compatibility but this should be such a trivial add I don't see any reason not to have the bonus compatibility.

@Kr00l
Copy link
Collaborator

Kr00l commented Jun 27, 2023

The following API call does not work in tB x64:

Private Declare PtrSafe Function vbaObjAddref Lib "msvbvm60.dll" Alias "__vbaObjAddref" (ByVal lpObject As LongPtr) As Long

image

It basically does an IUnknown.AddRef on an object pointer.

This can be convenient in combination with Nothing call to 'vbaObjSetAddref' which does an IUnknown.Release.
vbaObjSetAddref Nothing, ObjPtr(This)

@Kr00l Kr00l reopened this Jun 27, 2023
@WaynePhillipsEA
Copy link
Collaborator Author

Indeed, we've got vbaObjSetAddref redirected to an internal implementation, but not vbaObjAddref. I'll get that added, thanks.

@WaynePhillipsEA
Copy link
Collaborator Author

vbaObjAddref support added in BETA 344. Thanks!

@Kr00l
Copy link
Collaborator

Kr00l commented Jun 29, 2023

Thanks.

vbaObjSetAddref Nothing, ObjPtr(This)
does not make an IUnknown::Release. It was my error.

Instead this will make an IUnknown::Release.
vbaObjSet Nothing, ObjPtr(This)

But all works fine in tB x86 and x64. Just correcting a false information ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants