Easily Overwrite VB Plugin without closing Messenger |
Author: |
Message: |
matty
Scripting Guru
Posts: 8336 Reputation: 109
39 / /
Joined: Dec 2002
Status: Away
|
O.P. Easily Overwrite VB Plugin without closing Messenger
Ok guys we all have found in the past that this is near impossible to do right? Well up until now it was.
The steps to do this are in this order
1. Unregister DLL
2. Reload Plus! Plugins
The first step in the process is call a DllUnregisterServer (or using regsvr32 ) to unregister the DLL.
In a Module
code:
'Declare API Variables Used to Unregister the DLL
Option Explicit
Public Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
ByVal hWnd As Long, _
ByVal Msg As Any, _
ByVal wParam As Any, _
ByVal lParam As Any) _
As Long
Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) _
As Long
Public Declare Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long
Public Const INFINITE = &HFFFF
'Function to call the DllUnregisterServer
'Usage: UnregisterServer Me.hWnd, "C:\Program Files\MessengerPlus! 3\Plugins\MyDLL.dll"
'DllServerPath - Must be a COMPLETE PATH
Public Function UnregisterServer(hWnd As Long, DllServerPath As String)
On Error Resume Next
Dim lb As Long, pa As Long
'Check to see if the file exists, if it doesn't then exit after displaying a message box
'Load the DLL into memory
lb = LoadLibrary(DllServerPath)
If lb Then
MsgBox "File Not Found!" & vbCrLf & "Unable to continue. " & _
"(DllServerPath must be the full path to the file, " & _
"or this program must be in the same directory.)"
Exit Function
End If
'Get the address of the function DllUnregisterServer from the DLL
pa = GetProcAddress(lb, "DllUnregisterServer")
'Send the DLLs function to the main form
If CallWindowProc(pa, hWnd, ByVal 0&, ByVal 0&, ByVal 0&) = ERROR_SUCCESS Then
MsgBox "Successful"
Else
MsgBox "Unuccessful"
End If
FreeLibrary lb
End Function
'Delete the Plugin, code will not continue until this is done (WaitForSingleObject)
Public Function DeletePlugin() As Boolean
Dim nMsg As Long, retVal As Long
retVal = DeleteFile("C:\Program Files\MessengerPlus! 3\Plugins\MyDLL.dll")
WaitForSingleObject retVal, INFINITE
DeletePlugin = CBool(retVal)
End Function
The second step is to Reload the Plugins. Now Plus! wont be able to load our DLL because it has been unregistered from the system
code:
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) _
As Long
Public Declare Function RegisterWindowMessageA Lib "user32" (ByVal lpString As String) As Long
Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) _
As Long
Public Const INFINITE = &HFFFF
Public Const HWND_BROADCAST = &HFFFF&
'Unload the Plugins, code will not continue until this is done (WaitForSingleObject)
Public Function UnloadPlugins()
Dim nMsg As Long, retVal As Long
nMsg = RegisterWindowMessageA("MessengerPlus_PluginChange")
retVal = SendMessage(HWND_BROADCAST, nMsg, 0&, 0&)
WaitForSingleObject retVal, INFINITE
End Function
On the other hand if you want to trim this down you can use the following
code:
Public Function DllUnregister(strFile As String)
Dim retVal As Long
retval = shell("regsvr32 /u " & Chr(34) & strFile & Chr(34)), vbHide
WaitForSingleObject retval, INFINITE
End Function
Now with that said instead of hardcoding the path into the program you will want to get the value from the registry as follows.
In a Module
code: Public Const REG_SZ = 1
Public Const REG_BINARY = 3
Public Const HKEY_CURRENT_USER = &H80000001
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Public Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, _
ByVal lpSubKey As String, _
phkResult As Long) _
As Long
Public Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, _
ByVal lpValueName As String) _
As Long
Public Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, _
ByVal lpSubKey As String, _
phkResult As Long) _
As Long
Public Declare Function RegQueryValueExA Lib "advapi32.dll" (ByVal hKey As Long, _
ByVal lpValueName As String, _
ByVal lpReserved As Long, _
lpType As Long, _
lpData As Any, _
lpcbData As Long) _
As Long
Public Declare Function RegQueryValueExA Lib "advapi32.dll" (ByVal hKey As Long, _
ByVal lpValueName As String, _
ByVal lpReserved As Long, _
lpType As Long, _
lpData As Any, _
lpcbData As Long) _
As Long
Public Function RegQueryStringValue(ByVal hKey As Long, ByVal strValueName As String) As String
Dim lResult As Long, lValueType As Long, strBuf As String, lDataBufSize As Long
lResult = RegQueryValueExA(hKey, strValueName, 0, lValueType, ByVal 0, lDataBufSize)
If lResult = 0 Then
If lValueType = REG_SZ Then
strBuf = String(lDataBufSize, Chr$(0))
lResult = RegQueryValueExA(hKey, strValueName, 0, 0, ByVal strBuf, lDataBufSize)
If lResult = 0 Then
RegQueryStringValue = Left$(strBuf, InStr(1, strBuf, Chr$(0)) - 1)
End If
ElseIf lValueType = REG_BINARY Then
Dim strData As Integer
lResult = RegQueryValueExA(hKey, strValueName, 0, 0, strData, lDataBufSize)
If lResult = 0 Then
RegQueryStringValue = strData
End If
End If
End If
End Function
Public Function GetStringvalue(hKey As Long, strPath As String, strValue As String) As String
Dim Ret
RegOpenKey hKey, strPath, Ret
GetStringvalue = RegQueryStringValue(Ret, strValue)
RegCloseKey Ret
End Function
On A Form
code: Private Sub Form_Load()
Dim sText As String
sText = LCase(GetStringvalue(HKEY_LOCAL_MACHINE, "software\patchou\msgplus2\", "plugindir"))
If sText = vbNullString Then
sText = LCase(GetStringvalue(HKEY_CURRENT_USER, "software\patchou\msgplus2\", "plugindir"))
If sText = vbNullString Then
MsgBox "Messenger Plus! not installed"
Else
MsgBox "Plugin Dir: " & sText
End If
Else
MsgBox "Plugin Dir: " & sText
End If
End Sub
The path that is returned from GetStringValue() will be the path directly for the plugins so you can continue on from there. If anyone needs help with anything don't hesitate to ask.
Matty
(Cook if any of this code is wrong or can be done differently then on you, its 1:20 in the morning and I am tired but wanted to post this so).
This post was edited on 10-11-2005 at 10:23 PM by matty.
|
|
10-08-2005 05:19 AM |
|
|
J-Thread
Full Member
Posts: 467 Reputation: 8
– / / –
Joined: Jul 2004
|
RE: Easily Overwrite VB Plugin without closing Messenger
Cool, this is a really interesting post! I didn't try it, but I assume it works as you said...
C#.NET plugins are also "locked", but they are registered with regasm. I hope it works for them also that would be really cool!
|
|
10-08-2005 07:13 AM |
|
|
matty
Scripting Guru
Posts: 8336 Reputation: 109
39 / /
Joined: Dec 2002
Status: Away
|
O.P. RE: Easily Overwrite VB Plugin without closing Messenger
Logically if you unregister a something then another app can't call it directly (without example in VB adding a reference to it). So technically it should work. I know I said its an easy way to do it but and it looks like a lot of code its not actually just spread out well.
|
|
10-08-2005 07:21 AM |
|
|
TazDevil
Full Member
sleep(0);
Posts: 359 Reputation: 11
41 / /
Joined: May 2004
|
RE: Easily Overwrite VB Plugin without closing Messenger
are you sure that,
WaitForSingleObject retVal, INFINITE
is being called ? becasue after sendMessage the libraries are inaccessible since they are unloaded ....
Anyway what i wanted to ask...
Would you happen to know how to load a VB plugin in a c++ plugin
i want to add a configure command for vb plugins as well..
i have done it for c++ plugins but i am having dificulties with vb plugins
Thanks
Window Manager is discontinued, for WLM try the new,
Enhancer for contact list docking, auto-hide, hide taskbar button, remove button flashing and remember keyboard layout in conversation windows
|
|
10-08-2005 12:30 PM |
|
|
matty
Scripting Guru
Posts: 8336 Reputation: 109
39 / /
Joined: Dec 2002
Status: Away
|
O.P. RE: Easily Overwrite VB Plugin without closing Messenger
For VB Plugins you have to load it the same way Plus! does. Thats why for VB Plugins you have to put in the registry Projectname.Classname. Thats how they are loaded from Plus! since VB Plugins alone don't export their functions.
This is for VB not sure about C++
What you can do is Enum through the RegisteredPlugins section and CreateObject() for the Projectname.Classname
Then call configure.
code: Private Sub Form_Load()
Dim Plugin As Object
Set Plugin = CreateObject("%Projectname%.%Classname%")
Plugin.Configure
End Sub
|
|
10-08-2005 07:11 PM |
|
|
brian
Senior Member
Posts: 819 Reputation: 43
– / / –
Joined: Sep 2004
|
RE: Easily Overwrite VB Plugin without closing Messenger
quote: Originally posted by Matty
Public Function UnrregisterServer(hWnd As Long, DllServerPath As String)
Unr registerServer
|
|
10-08-2005 09:51 PM |
|
|
matty
Scripting Guru
Posts: 8336 Reputation: 109
39 / /
Joined: Dec 2002
Status: Away
|
O.P. RE: Easily Overwrite VB Plugin without closing Messenger
quote: Originally posted by brian
quote: Originally posted by Matty
Public Function UnrregisterServer(hWnd As Long, DllServerPath As String)
UnrregisterServer
Blah it is just an insignificant function but I will fix it.
|
|
10-08-2005 09:53 PM |
|
|
|
|