[VB.NET/WinAPI] SizeOfResource

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • StijnH
  • Registratie: December 2005
  • Laatst online: 27-07 12:45
Eerst en vooral: ik heb nog niet zo veel kennis van het werken met de Windows API. Wat ik nu heb is het resultaat van een 10tal uur te zoeken en te lezen.

Ik ben me wat aan het verdiepen in het hele resources gedoe, vooral het wijzigen ervan dan.
De DLL die ik gebruik is msgslang.14.0.8064.0206.dll dewelke onderdeel is van Windows Live Messenger.

Nu heb ik het volgende probleem waarvan ik totaal geen idee heb wat de oorzaak is.
Volgende code levert, bij gelijk welke resource geselecteerd is, een size van 51539607552 (waarde van hResLoad, hResLock en ulngResSize tijdens het debuggen).
test.dll is een kopie van het origineel.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Const cResType = "RT_DIALOG"
Const cResID = "202"
Const cResLang = "&H409" 'United States (US)
Const cPath = "H:\test.dll"

Dim hLib As Long
Dim hRes As Long
Dim hResLoad As Long
Dim hResLock As Long
Dim ulngResSize As ULong
hLib = LoadLibrary(cPath)
hRes = FindResource(hLib, cResID, cResType)
hResLoad = LoadResource(Nothing, hRes)
hResLock = LockResource(hResLoad)
ulngResSize = SizeOfResource(Nothing, hRes)


De grootte is niet wat ik verwacht, dus duidelijk doe ik ergens iets verkeerd (wat best mogelijk is, overgrote deel van de voorbeelden zijn C++, waar ik niet echt thuis in ben).

Acties:
  • 0 Henk 'm!

Verwijderd

Zie msdn voor documentatie over de functie SizeOfResource. Dan had je overigens gelijk al kunnen zien dat de eerste parameter natuurlijk geen null waarde kan bevatten. Voor de rest had je iets als getlasterror kunnen gebruiken om te achterhalen wat er fout ging.

[ Voor 1% gewijzigd door Verwijderd op 14-07-2009 08:37 . Reden: Onzin weggehaald ]


Acties:
  • 0 Henk 'm!

  • StijnH
  • Registratie: December 2005
  • Laatst online: 27-07 12:45
Terwijl het niet expliciet vermeld wordt op MSDN, mag dit wel.
Het volgende staat vermeldt bij LoadResource()
If hModule is NULL, the system loads the resource from the module that was used to create the current process.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:02
-Stijn- schreef op dinsdag 14 juli 2009 @ 09:15:
Terwijl het niet expliciet vermeld wordt op MSDN, mag dit wel.
Het volgende staat vermeldt bij LoadResource()

[...]
De vraag is of Nothing gelijk is aan NULL

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • StijnH
  • Registratie: December 2005
  • Laatst online: 27-07 12:45
farlane schreef op dinsdag 14 juli 2009 @ 09:31:
[...]


De vraag is of Nothing gelijk is aan NULL
Voor zover ik weet, is Nothing in VB.NET hetzelfde als NULL in C#.
Ben ik echter verkeerd als ik aanneem dat NULL in C# hetzelfde is als NULL in C++ ?

[ Voor 15% gewijzigd door StijnH op 14-07-2009 09:42 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
farlane schreef op dinsdag 14 juli 2009 @ 09:31:
[...]


De vraag is of Nothing gelijk is aan NULL
Het antwoord staat in MSDN :P

(Overigens is het [url="http://www.google.com/#hl=en&safe=off&q="null+reference+(Nothing+in+Visual+Basic)"+site%3Amsdn.microsoft.com"]vergeven in MSDN[/url] van de "blabla null reference (or Nothing in Visual Basic)" tekstjes...)

[ Voor 31% gewijzigd door RobIII op 14-07-2009 09:58 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • StijnH
  • Registratie: December 2005
  • Laatst online: 27-07 12:45
Het probleem zit blijkbaar helemaal bij het begin.
Wanneer LoadLibrary() het bestand in het opgegeven pad niet vindt, zou deze NULL moeten returnen.
Nu mag ik echter gelijk welke bestandsnaam opgeven, de functie zal niet failen en geen NULL returnen :?

Zal proberen uit te zoeken hoe dit komt.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
-Stijn- schreef op woensdag 15 juli 2009 @ 01:24:
Het probleem zit blijkbaar helemaal bij het begin.
Wanneer LoadLibrary() het bestand in het opgegeven pad niet vindt, zou deze NULL moeten returnen.
RobIII in "\[VB.NET/WinAPI] SizeOfResource"

Hoe check je die NULL? "if blabla is Nothing" of "if blabla = null" of...? En al eens gekeken wat GetLastError geeft? Daarbij, je defined hlib als (non-nullable) Long; waar had je die Null dan in verwacht? Je zou eens kunnen kijken of hlib dan 0 is (implicit casting gedoe van VB.Net enzo, geen idee of het ook zo is maar 't zou me niets verbazen) i.p.v. Null/Nothing.

[ Voor 26% gewijzigd door RobIII op 15-07-2009 01:51 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • StijnH
  • Registratie: December 2005
  • Laatst online: 27-07 12:45
RobIII schreef op woensdag 15 juli 2009 @ 01:47:
[...]

Je zou eens kunnen kijken of hlib dan 0 is (implicit casting gedoe van VB.Net enzo, geen idee of het ook zo is maar 't zou me niets verbazen) i.p.v. Null/Nothing.
Dat heb ik gedaan, hlib heeft gewoon een waarde als 1090921693184 en dat vind ik vreemd.
code:
1
If hLib = Nothing Then
is dan FALSE.

Ivm het definen van hLib als Long, volgens wat ik heb begrepen van 'handles' is dat het gebruikelijke datatype. Maar dat zal ik dus nog eens moeten herbekijken.

Nu, ik ben er enkele dagen tussenuit, binnen een week laat ik iets horen of ik al dan niet verder ben geraakt.

[ Voor 13% gewijzigd door StijnH op 15-07-2009 02:27 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
-Stijn- schreef op woensdag 15 juli 2009 @ 02:24:
[...]

Dat heb ik gedaan, hlib heeft gewoon een waarde als 1090921693184 en dat vind ik vreemd.
code:
1
If hLib = Nothing Then
is dan FALSE.
Vergelijken met nothing doe je niet met de = operator maar met de is operator:
Visual Basic .NET:
1
if bla is Nothing then...

Overigens, as a sidenote, wordt mijn vermoeden hier bevestigd:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
Public Structure testStruct
    Public name As String
    Public number As Short
End Structure
Dim ts As testStruct, i As Integer, b As Boolean
ts = Nothing 
' The preceding statement sets ts.name to "" and ts.number to 0.
i = Nothing 
b = Nothing 
' The preceding statements set i to 0 and b to False.
-Stijn- schreef op woensdag 15 juli 2009 @ 02:24:
Ivm het definen van hLib als Long, volgens wat ik heb begrepen van 'handles' is dat het gebruikelijke datatype.
Klopt; althans, dat meen ik ook te herinneren :P Euh, nee. In Vb6 ja; daar is een long een 4-byte value. In VB.Net is een long een 8-byte value en moet je volgens mij gewoon een 32 bit int (lees: integer) hebben.

VB6 Integer -> VB.Net Short = 16 bits
VB6 Long -> VB.Net Integer = 32 bits

En AFAIK geven API-calls doorgaans 32bits results/handles/blatiebla

[ Voor 65% gewijzigd door RobIII op 15-07-2009 02:41 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • StijnH
  • Registratie: December 2005
  • Laatst online: 27-07 12:45
code:
1
Dim hLib As Nullable(Of Long)

Snel even opgezocht, zo is hLib een nullable Long, correct?

Nu, maakt geen verschil zoals ik verwacht, want inderdaad zou in het geval van een NULL value, de value gewoon 0 zijn.

Edit:
Wanneer ik er een nullable Integer van maak, krijg ik een overflow.
Dan moet ik natuurlijk wel zorgen dat de functie zelf ook een Integer als return value heeft |:(

[ Voor 28% gewijzigd door StijnH op 15-07-2009 03:59 ]


Acties:
  • 0 Henk 'm!

  • StijnH
  • Registratie: December 2005
  • Laatst online: 27-07 12:45
Ondertussen al iets verder geraakt.
De handle als Integer ipv Long was inderdaad een stap in de goeie richting.

code:
1
2
3
4
hLib = LoadLibrary(cPath)
If hLib = "0" Then
      MessageBox.Show(New Win32Exception(Err.LastDllError).Message)
 End If

Resultaat: "The specified module could not be found"
Nu aan het uitzoeken waarom de DLL niet gevonden wordt.

Trouwens, hLib is een nullable Integer, maar bij een fout is het resultaat "0" en geen NULL (of Nothing) :/

Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Volgens deze pagina onderaan in de comments zou de syntax van je definitie van load library als volgt moeten zijn:
Visual Basic .NET:
1
2
3
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function LoadLibrary(<[In], MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String) As IntPtr
End Function


Dus niet een nullable integer.
-Stijn- schreef op woensdag 15 juli 2009 @ 04:43:
..
code:
1
2
3
4
hLib = LoadLibrary(cPath)
If hLib = "0" Then
      MessageBox.Show(New Win32Exception(Err.LastDllError).Message)
 End If

...
Over je code: je kunt gewoon met 0 (zonder quotes) vergelijken. De documentatie lijkt vooral gericht op C++ programmeurs en ik vermoed dat op een int de NULL gelijk is aan 0. Mogelijk dat een C++ goeroe dit kan bevestigen.

[ Voor 37% gewijzigd door bigbeng op 15-07-2009 05:25 ]


Acties:
  • 0 Henk 'm!

  • Dricus
  • Registratie: Februari 2002
  • Laatst online: 19-09 12:26

Dricus

ils sont fous, ces tweakers

NULL is inderdaad gelijk aan 0. Wat mij opvalt is dat de waarden die je noemt (51539607552 == 0xC00000000 en 1090921693184 == 0xFE00000000) beide groter zijn dan de 32 bits die de functies die je gebruikt teruggeven. Het lijkt er dus sterk op dat je DllImport declaraties niet goed zijn.

De DllImport declaratie (zonder EntryPoint attribuut) van bigbeng gaat niet werken trouwens. Ik heb net even getest en het lijkt erop dat op deze manier automatisch de ANSI versie geladen wordt (LoadLibraryA dus, MSDN zegt hier op het eerste gezicht niks over trouwens). De CharSet moet dan dus op CharSet.Ansi staan. CharSet.Auto default namelijk naar Unicode op Windows NT, 2000, XP, etc. Ook is het sowieso handig om door middel van EntryPoint expliciet aan te geven welke versie van LoadLibrary en andere functies je gebruiken wilt, dus óf LoadLibraryA óf LoadLibraryW. LoadLibrary is namelijk niet als entrypoint aanwezig in kernel32.dll.

Zo dus:

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
' ANSI versie
<DllImport("kernel32.dll", EntryPoint:="LoadLibraryA", CharSet:=CharSet.Ansi, SetLastError:=True)> _
Public Shared Function LoadLibrary(<[In], MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String) As IntPtr
End Function

' Unicode versie
<DllImport("kernel32.dll", EntryPoint:="LoadLibraryW", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Public Shared Function LoadLibrary(<[In], MarshalAs(UnmanagedType.LPWStr)> ByVal lpFileName As String) As IntPtr
End Function

Stel niet uit tot morgen wat je vandaag nog tot morgen kunt uitstellen...


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
bigbeng schreef op woensdag 15 juli 2009 @ 05:22:
Volgens deze pagina onderaan in de comments zou de syntax van je definitie van load library als volgt moeten zijn:
Visual Basic .NET:
1
2
3
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function LoadLibrary(<[In], MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String) As IntPtr
End Function


Dus niet een nullable integer.
Ah; dus toch de IntPtr. Ergens jeukte er al iets... :X

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Pagina: 1