Registering components(dll, ocx, etc) via API

B

bianko_124

Hi, I wrote this little function to register ocxs or dlls.. When it's
all right this function works properly, but justly, for example, if the
application runs with a user that hasn't administrator rights the
registration does not work. The problem is that it seems that the
called function 'dllregisterserver' does not return failure values.
Doesn't the function 'WaitForSingleObject' should return a non-zero
value if some fails? I'd really need that if the function that
registers the component fails for some reason I would be able to trap
the error someway. Here follows the code I use. I don't write here APIs
declaration too.
Some suggest to know if the registration works fine or not using this
method?

Thank you very much...

PS: Comments are in italian as I'm italian :))

Public Function RegisterCmp(cmpPath As String) As Boolean
On Error GoTo err_RegisterCmp

Dim hLib As Long
Dim pAddress As Long
Dim hThread As Long
Dim dwThreadId As Long, dwRC As Long
Dim response As Long

RegisterCmp = False

hLib = 0
pAddress = 0
hThread = 0
dwThreadId = 0
dwRC = 0

hLib = LoadLibrary(cmpPath)

' controllo che hLib sia valido come valore (<>0)
If hLib Then
'Ottengo l'indirizzo della funzione DllRegisterServer
pAddress = GetProcAddress(hLib, "DllRegisterServer")
Else
oLog.Scrivi "ClsMgmFls_RegisterCmp(): Error loading library " &
cmpPath & _
".", Error
'Esco dalla function
Exit Function
End If

'Controllo pAddress che sia valido (<>0)
If pAddress Then
'Creo un thread che esegue la funzione presente all'indirizzo
retReg
'(DllRegisterServer). CreateThread restituisce un handle a tale
thread
hThread = CreateThread(0&, 0, pAddress, 0&, 0, _
dwThreadId)
Else
oLog.Scrivi "ClsMgmFls_RegisterCmp(): Error locating function "
& _
"''DllRegisterServer''.", Error
'Pulisco l'handle della library caricata in memoria
FreeLibrary hLib
Exit Function
End If

'Controllo che hThread sia valido (<>0). Se valido sta girando il
thread
If hThread Then
'Se dwRC prende un valore<>0 significa che sta ancora girando.
'Viene restituito un valore da WaitForSingleObject() ogni 100ms
dwRC = WaitForSingleObject(hThread, 100)
Else
oLog.Scrivi "ClsMgmFls_RegisterCmp(): Could not create the
thread " & _
"''DllRegisterServer''.", Error
'Pulisco l'handle della library caricata in memoria
FreeLibrary hLib
'Esco dalla funzione
Exit Function
End If

'Finchè dwRC non assume il valore 0 gli viene riassegnato il
valore di
'WaitForSingleObject ogni 100ms. Se ottiene 0 il thread è stato
eseguito
'con successo. Ovviamente se è già a 0 dopo la precedente
chiamata di
'WaitForSingleObject il ciclo non viene nemmeno eseguito.
Do While dwRC <> WAIT_OBJECT_0
dwRC = WaitForSingleObject(hThread, 100)
Loop

RegisterCmp = True

'Pulisco gli handles del thread creato e della library caricata
CloseHandle hThread
FreeLibrary hLib

Exit Function

err_RegisterCmp:
oLog.Scrivi "ClsMgmFls_RegisterCmp(): " & Err.Number & " - " &
Err.Description, Error
'Se esiste o l'handle della library o l'handle thread eseguo
pulizia
If hThread Then CloseHandle hThread
If hLib Then FreeLibrary hLib
End Function
 
M

Mattias Sjögren

The problem is that it seems that the
called function 'dllregisterserver' does not return failure values.

It should, but different implementations may behave in different ways.

I don't write here APIs declaration too.

That's a shame, because I suspect they are incorrect based on your use
of Longs.

Some suggest to know if the registration works fine or not using this
method?

Well first of all I suggest you get rid of the CreateThread hack and
call the function with the proper signature. Here's an example

http://www.msjogren.net/dotnet/eng/samples/dotnet_dynpinvoke.asp



Mattias
 
B

Bianko

Ok Mattias I post here API decalrations too that I use in the module
where I define my function..

Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule
As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias
"LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule
As Long, ByVal lpProcName As String) As Long
Private Declare Function CreateThread Lib "kernel32" _
(ByVal lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal
lpStartAddress As _
Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId
As Long) _
As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As
Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal
hHandle As Long, _
ByVal dwMilliseconds As Long) As Long

Private Const WAIT_OBJECT_0 = &H0&

I repeat that the registration works very well.. The problem is that
the function WaitForSingleObject always returns the value '0'
(WAIT_OBJECT_O), that is, the value returned in case of success of the
function (DllRegisterServer in my case) even if, insted, the
registration fails. I wonder the reason of it, I am driving crazy for
it!! :)
 
B

Bianko

Thank you all equally (is it right?? :) )
I''ve found my misterious key to resolve my problem.. I use the API
function GetExitCodeThread() that as out parameters gives the
dwExitCode that is a pointer to a variable which contains the return
code of the function that has run into the thread. In fact if I make
run the app with non admin privileges the dwExitCode contains
-2147467259 that is E_FAIL ;-)) Good!!

Bye bye!
 
Top