Page 1 of 2 12 LastLast
Results 1 to 40 of 60

Thread: Undocumented Function using VBA6.Dll

  1. #1

  2. #2
    Lively Member
    Join Date
    Apr 2009
    Posts
    64

    Re: Hi I have a question on vb6.0

    Quote Originally Posted by The trick View Post
    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

  3. #3
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,653

    Re: Hi I have a question on vb6.0

    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.

  4. #4
    Lively Member
    Join Date
    Apr 2009
    Posts
    64

    Re: Hi I have a question on vb6.0

    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.

  5. #5
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Hi I have a question on vb6.0

    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.

  6. #6
    Lively Member
    Join Date
    Apr 2009
    Posts
    64

    Re: Hi I have a question on vb6.0

    Quote Originally Posted by passel View Post
    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.
    Sorry, I didn't mean to hi-jack the thread ... the reason I posted my question here is because the forum member 'The trick' mentioned in post #4 that he could use undocumented functions from vba6.dll in which I am interested

  7. #7

  8. #8
    Lively Member
    Join Date
    Apr 2009
    Posts
    64

    Re: Hi I have a question on vb6.0

    Quote Originally Posted by The trick View Post
    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

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,673

    Re: Hi I have a question on vb6.0

    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

  10. #10

  11. #11
    Lively Member
    Join Date
    Apr 2009
    Posts
    64

    Re: Hi I have a question on vb6.0

    Quote Originally Posted by The trick View Post
    Hmmm.. I don't understand. You want get information about current project from it? Or you want get information about any ActiveX dll?
    Thanks the trick,
    I want information about the functions in the VB rutime dll - ie: MSVBVM60.dll and vba6.dll
    I need information about the functions you see when you open MSVBVM60.dll in Dependency walker

    Thanks you

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,673

    Re: Hi I have a question on vb6.0

    I want information about the functions in the VB rutime dll - ie: MSVBVM60.dll and vba6.dll
    There are many functions, and explanation of everything functions i think you don't find.
    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.

  13. #13
    Lively Member
    Join Date
    Apr 2009
    Posts
    64

    Re: Hi I have a question on vb6.0

    Thank you the trick

  14. #14
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,715

    Re: Undocumented Function using VBA6.Dll

    For what it's worth, the thread was originally located on this thread: http://www.vbforums.com/showthread.p...97#post4901797
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  15. #15
    Hyperactive Member
    Join Date
    Jan 2015
    Posts
    323

    Re: Undocumented Function using VBA6.Dll

    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?

  16. #16
    Hyperactive Member
    Join Date
    Jan 2015
    Posts
    323

    Re: Undocumented Function using VBA6.Dll

    in VB6 AddIn we can use CodePane.GetSelection and CodeModule.Lines to get a line of source code string

  17. #17
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Hi I have a question on vb6.0

    Quote Originally Posted by The trick View Post
    There are many functions, and explanation of everything functions i think you don't find.
    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.
    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.

  18. #18
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Hi I have a question on vb6.0

    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.

  19. #19

  20. #20
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    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;
    }

  21. #21

  22. #22
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by The trick View Post
    You need to initialize STA, runtime and project context.
    Hello the trick,
    Is there a simple c code to do the above ie., " initialize STA, runtime and project context" in the simple console c app so that I can display msgbox without crash.

    Thanks

  23. #23

  24. #24
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by The trick View Post
    The simple way is to create an VB6-AXDll object to initialize all.
    Hello the Trick,

    But I cannot create object in c as in c++ since I am using pure c console app which
    donot support classes and objects.

    Thanks

  25. #25

  26. #26
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,121

    Re: Undocumented Function using VBA6.Dll

    @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>

  27. #27
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    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

  28. #28

  29. #29
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by The trick View Post
    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

  30. #30

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,673

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by smkperu View Post
    If we can use C as said above can I create simple VB6-AXDll object using C code and display msgbox without crash.
    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:

  31. #31
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by The trick View Post
    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:

    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;
    }

  32. #32

  33. #33
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by The trick View Post
    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.

  34. #34
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by smkperu View Post
    We can use MessageBox windows api directly in c instead of this overhead.
    So, why not use this MS-API (which is exported by user32.dll)?

    Why fumbling around with the difficult to use (and for the most part un-documented) exports in the VB6/VBA-runtime-Dlls?

    What's the end-goal?

    Olaf

  35. #35

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,673

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by smkperu View Post
    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.
    Why do you need that? There is a way to instantiate project manually but why do you need to use that?

  36. #36
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by The trick View Post
    Why do you need that? There is a way to instantiate project manually but why do you need to use that?
    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

  37. #37

  38. #38
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by The trick View Post
    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

  39. #39

  40. #40
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: Undocumented Function using VBA6.Dll

    Quote Originally Posted by The trick View Post
    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

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width