|  |  | 
|  | 
|  | 
| - Seite 1 - | 
| 
 
 | 
|  | | Hallo Profaner... 
 Ich benötige unter möglichst allen 32BIt Windowssystemen (geht nicht unter NT4) die Rückgaben aus der Editbox für den unten stehenden Quelltext. Es geht um die Aufdeckung eines "Fehlers" in der MSDN Dokumentation. Ich habe schon etwas länger den Verdacht, dass da irgendetwas ganz und gar nicht stimmt....
 KompilierenMarkierenSeparieren
 Def @GetWindowThreadProcessId(2) !"USER32","GetWindowThreadProcessId"
Def @CreateToolhelp32Snapshot(2) !"kernel32","CreateToolhelp32Snapshot"
Def @Heap32ListNext(2) !"kernel32","Heap32ListNext"
Def @Heap32ListFirst(2) !"kernel32","Heap32ListFirst"
Def @Heap32Next(1) !"kernel32","Heap32Next"
Def @Heap32First(3) !"kernel32","Heap32First"
Def @CloseHandle(1) !"KERNEL32","CloseHandle"
Def @GetLastError(0) !"KERNEL32","GetLastError"
Def @GetVersionEx(1) !"KERNEL32","GetVersionExA"
DEF &Ver_Platform_Win32_Windows 1
DEF &Ver_Platform_Win32_NT 2
Declare Fenster&, PROCESSID#, ThreadID&, PROCESSID&, HEAPLIST32#, Result_HL&, hSnapshot&, HeapCount%
Declare HEAPENTRY32#, HeapBlockCount%, Result2&, Zwischenmerker&, Heap_Handle_LIST%, Zwischenmerker$
Declare WinVer&, Winver$, OS#
Struct HEAPLIST32 = LISTdwsize&, Listth32ProcessID&, LISTth32HeapID&, dwLISTFlags&
Struct HEAPENTRY32 = HEdwsize&, hHandle&, dwAddress&, dwBlockSize&, dwFlags&, dwLockCount&, dwResvd&, HEth32ProcessID&, HEth32HeapID&
Struct OSVERSIONINFO = dwOSVersionInfoSize&,dwMajorVersion&,dwMinorVersion&,dwBuildNumber&,dwPlatformId&,szCSDVersion$(128)
Proc ?_GetWinVersion
    Parameters ServicePack%
    Declare ServicePack$
    Windows-Version ermitteln
    DEF &Ver_Platform_Win32_Windows 1
    DEF &Ver_Platform_Win32_NT 2
    Dim OS#,OSVERSIONINFO
    OS#.dwOSVersionInfoSize& = 148
    External("Kernel32","GetVersionExA",OS#)
    LET Winver& = 100
    LET ServicePack$ = " ("+OS#.szCSDVersion$+")"
    If OS#.dwPlatformId& = &Ver_Platform_Win32_Windows
        If OS#.dwMajorVersion& = 4
            Case OS#.dwMinorVersion& = 0  : Winver& = 1
            Case OS#.dwMinorVersion& = 10 : Winver& = 2
            Case OS#.dwMinorVersion& = 90 : Winver& = 3
        Endif
    ElseIf OS#.dwPlatformId& = &Ver_Platform_Win32_NT
        Case OS#.dwMajorVersion& = 3 : Winver& = 4
        Case OS#.dwMajorVersion& = 4 : Winver& = 5
        IF @and(OS#.dwMajorVersion& = 5,OS#.dwMinorVersion& <> 2)
            LET Winver& = 6
        Elseif @and(OS#.dwMajorVersion& = 5,OS#.dwMinorVersion& = 2)
            LET Winver& = 8
        endif
        IF @and(OS#.dwMajorVersion& = 6,OS#.dwMinorVersion& = 0)
            LET Winver& = 9
        endif
        Case OS#.dwMinorVersion& = 1 : Winver& = 7
    Endif
    Dispose OS#
    case WinVer& = 1: Let Winver$ = "Windows95"
    case WinVer& = 2: Let Winver$ = "Windows98"
    case WinVer& = 3: Let Winver$ = "WindowsME"
    case WinVer& = 4: Let Winver$ = "WindowsNT 3.5"
    case WinVer& = 5: Let Winver$ = "WindowesNT 4"
    case WinVer& = 6: Let Winver$ = "Windows2000"
    case WinVer& = 7: Let Winver$ = "WindowsXP"
    case WinVer& = 8: Let Winver$ = "Windows Server 2003"
    case WinVer& = 9: Let Winver$ = "WindowsVista oder Longhorn"
    case WinVer& = 100: Let Winver$ = "unbekannte Windowsversion"
    CASE ServicePack% = 1 : Let Winver$ = Winver$ + ServicePack$
EndProc
@winexec("WRITE.EXE", 1)
Sleep 500
LET Fenster& = @FindWindow("Dokument - ")
DIM PROCESSID#, 4
LET ThreadID& = @GetWindowThreadProcessId(Fenster&, PROCESSID#)
LET PROCESSID& = @Long(PROCESSID#, 0)
Dispose PROCESSID#
Dim HEAPLIST32#, HEAPLIST32
Dim HEAPENTRY32#, HEAPENTRY32
Clear HEAPLIST32#
LET Heap_Handle_LIST% = 1
HEAPLIST32#.LISTdwsize& = 16
LET hSnapshot& = @CreateToolhelp32Snapshot($1, ProcessID&)
IfNot hSnapshot& = -1
    Clearlist
    ?_GetWinVersion 1
    Addstring "Windowsversion: "+Winver$
    LET Result_HL& = @Heap32ListFirst(hSnapshot&, HEAPLIST32#)
    While Result_HL& = 1
        Clear HEAPENTRY32#
        HEAPENTRY32#.HEdwsize& = 36
        INC HeapCount%
        Clear HeapBlockCount%
        Addstring "____________________________"
        LET Result2& = @Heap32First(HEAPENTRY32#, ProcessID&, HEAPLIST32#.Listth32HeapID&)
        LET Zwischenmerker& = HEAPLIST32#.dwLISTFlags&
        Addstring "Daten des "+@STR$(HEAPCOUNT%)+".Heaps"
        Addstring "Heapflags: $"+@HEX$(Zwischenmerker&)
        IF Heap_Handle_LIST% = 1
            IF Result2& = 1
                Addstring "Handle im Prozess: "+@STR$(HEAPENTRY32#.hHandle&)
                Addstring "Toolhelp-ID des Heaps: "+@STR$(HEAPLIST32#.LISTth32HeapID&)
            Else
                Addstring "Handle im Prozess: "+@STR$(HEAPLIST32#.LISTth32HeapID&)
            endif
            IF @or(Zwischenmerker&, $2) = Zwischenmerker&
                Addstring "Speicherstatus: "+"Heap kann wachsen"
                LET Zwischenmerker& = Zwischenmerker&-$2
            else
                Addstring "Speicherstatus: "+"Größe beschränkt"
            Endif
            IF @or(Zwischenmerker&, $1) = Zwischenmerker&
                Addstring "Speicherverwaltung: "+"Kein gleichzeitiger Zugriff mehrerer Threads"
                LET Zwischenmerker& = Zwischenmerker&-$1
            else
                Addstring "Speicherverwaltung: "+"Gleichzeitiger Zugriff mehrerer Threads möglich"
            Endif
            IF @or(Zwischenmerker&, $4) = Zwischenmerker&
                Addstring "Fehlerbehandlung: "+"Meldung einer Zugriffsverletzung bei Fehlern"
                LET Zwischenmerker& = Zwischenmerker&-$4
            else
                Addstring "Fehlerbehandlung: "+"API gibt bei Fehlern 0 zurück"
            Endif
        else
            IF @or(Zwischenmerker&, $1) = Zwischenmerker&
                Addstring "Typ: "+"Standard Prozessheap"
                LET Zwischenmerker& = Zwischenmerker&-$1
            endif
            IF @or(Zwischenmerker&, $2) = Zwischenmerker&
                Addstring "Speicherverwaltung: "+"Shared Heap"
                LET Zwischenmerker& = Zwischenmerker&-$2
            endif
        endif
        IF Zwischenmerker&<>0
            Addstring "Nicht erkannte Heapflags: "+"$"+@Hex$(Zwischenmerker&)
        endif
        While Result2& = 1
            INC HeapBlockCount%
            Addstring ""
            IF Heap_Handle_LIST% = 0
                Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Handle im Prozess: "+@STR$(HEAPENTRY32#.hHandle&)
                Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Startadresse: "+@STR$(HEAPENTRY32#.dwAddress&)
            Else
                Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Startadresse: "+@STR$(HEAPENTRY32#.dwAddress&)
            endif
            Let Zwischenmerker$ = " ("
            IF HEAPENTRY32#.dwFlags& = $1
                LET Zwischenmerker$ = Zwischenmerker$+"feste Adresse"
            ElseIf HEAPENTRY32#.dwFlags& = $2
                LET Zwischenmerker$ = Zwischenmerker$+"frei"
            ElseIf HEAPENTRY32#.dwFlags& = $4
                LET Zwischenmerker$ = Zwischenmerker$+"beweglich"
            Else
                LET Zwischenmerker$ = Zwischenmerker$+"$"+@HEX$(HEAPENTRY32#.dwFlags&)
            endif
            Let Zwischenmerker$ = Zwischenmerker$+")"
            Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Größe / Status: "+@STR$(HEAPENTRY32#.dwBlockSize&)+" Bytes"+Zwischenmerker$
            LET Result2& = @Heap32Next(HEAPENTRY32#)
        wend
        LET Result_HL& = @Heap32ListNext(hSnapshot&, HEAPLIST32#)
    wend
    @CloseHandle(hSnapshot&)
endif
Dispose HEAPLIST32#
Dispose HEAPENTRY32#
@Editbox("Infos über Heaps von Wordpad", 1)
Und für alle die, die den Code so nicht testen können, hier die EXE zum Downloaden:
 [...]
  | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  |  | 
|  | 
| - Seite 1 - | 
| 
 
 | 
|  | | Das meine ich nicht, es geht um das Handle des Heapblocks. Wordpad muss übrigens offen bleiben, bis die Editbox kommt. | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  Nico
 Madysa
 | | Bitteschön, hier meine Ergebnis: | 
 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  | | Wo sind sie denn? Gerade die brauche ich noch! | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  | | Danke Nico, Vermutung scheint (wenn ich mich nicht irgendwo total verhaspelt habe  ) bestätigt. | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  Nico
 Madysa
 | | Freut mich für dich. Ich hab von dem Zeug nämlich nix kapiert.  | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  |  | 
|  | 
| - Seite 2 - | 
| 
 
 | 
|  | 
|  | | Kurz gesagt: Microsoft scheint unter NT Systemen etwas in der API geändert zu haben und verschweigt scheinbar diese Änderung seit Windows2000. Diese Änderung betrifft die Toolhelp Strukturen HEAPLIST32 und HEAPENTRY32, die von den APIs Heap32ListFirst,  Heap32ListNext Heap32First und Heap32Next genutzt werden. Richtet man sich nach der Dokumentation, bekommt man falsche Werte. Toll, oder? 
 Hat jemand gegen meine Feststellung etwas einzuwenden?
 | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  Nico
 Madysa
 | | 
 Toll, oder? 
 Im Hinblick darauf, dass diese Feststellung offensichtlich ironisch gemeint ist, hab ich nichts dagegen einzuwenden.
  | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  | | Ich habe mir gerade die kompletten Rückmeldungen von Vista (danke Rolf) angesehen. Chaotik ohne gleichen - und das bei einer dokumentierten API! Wer irgendwie an Loghorn / 2003 kommt - auch davon hätte ich gerne die kompletten Rückmeldungen des Quelltextes!
 
 Wie soll man denn Programme schreiben, wenn Microsoft dokumentiertes Verhalten einer API laufend ändert?
  (ausführlicher Artikel dazu auf meiner Homepage [...]
  ) | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  | | Du sollst ebend die SDKs benutzen.  | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  | | Was steht da genau zu den Strukturen? Ist die Erklärung da besser? | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  | | iF 
 Du sollst ebend die SDKs benutzen.   
 Sorry, dass ich nochmals nachfrage: Wie genau sieht die Erklärung der Strukturen HEAPLIST32 und HEAPENTRY32 im SDK zu Windows2000 oder XP aus? Da MSDN ihre Dokumentation scheinbar nach dem Erscheinen von Vista angepasst hat, gehe ich im Augenblick davon aus, dass da nichts anderes steht.
 | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 | 
|  | 
|  | | Wir reden aneinander vorbei - habe grad ein blöderes Problem die Codeanzeige der Nity ist futsch.  | 
 | 
|  | 
|  |  | 
|  | 
| 
 
 
 |