Seite 1 von 2

[Gelöst] Kleines WinAPI Structure Problem

Verfasst: 22.06.2008 20:29
von Ground0
Ich habe folgendes Structure aus der WinAPI Doku:

Code: Alles auswählen

typedef struct _TAPE_GET_MEDIA_PARAMETERS {
  LARGE_INTEGER Capacity;
  LARGE_INTEGER Remaining;
  DWORD BlockSize;
  DWORD PartitionCount;
  BOOLEAN WriteProtected;
} TAPE_GET_MEDIA_PARAMETERS, 
 *PTAPE_GET_MEDIA_PARAMETERS;
Dass habe ich daraus gemacht:

Code: Alles auswählen

  Structure TAPE_GET_MEDIA_PARAMETERS
    Capacity.LARGE_INTEGER 
    Remaining.LARGE_INTEGER 
    BlockSize.l
    PartitionCount.l
    WriteProtected.b
  EndStructure
Ist dass jetzt falsch oder was könte da falsch laufen?

Gruss G0

Verfasst: 22.06.2008 20:31
von Kaeru Gaman
wie hast du LARGE_INTEGER definiert?

..und Boolean ist glaubich auch 32bit lang...

Verfasst: 22.06.2008 20:36
von Ground0
Naja LARGE_INTEGER muss schon ein vordefiniertes Structure sein, habe es nicht selbst definiert...

Ich weiss nur dass es Total 32 Bytes sein müssen ... aber es kommt immer folgendes zurück im Error:234
MSDN:
ERROR_MORE_DATA
234
0xEA
More data is available.
Der Code:

Code: Alles auswählen

rocedure.q Tape_GetFreeSpace(hTape.l) ;Final
  Structure TAPE_GET_MEDIA_PARAMETERS
    Capacity.LARGE_INTEGER 
    Remaining.LARGE_INTEGER 
    BlockSize.l
    PartitionCount.l
    WriteProtected.q
  EndStructure
  Global Parameter.TAPE_GET_MEDIA_PARAMETERS, Size.l, Error.l
  
  Error.l = GetTapeParameters_(hTape.l, 0, @Size.l, @Parameter)
  ;Error.l = GetLastError_()
  If Error.l <> 0
    ProcedureReturn 0
  Else
    ProcedureReturn Parameter\Remaining
  EndIf
EndProcedure
Natürlich gibts noch mehr drum herum aber dass ist der Problembereich alles andere Funktiooniert soweit...

Gruss

Verfasst: 22.06.2008 20:43
von ts-soft
Kaeru Gaman hat geschrieben:wie hast du LARGE_INTEGER definiert?
Das hat PB für ihn getan :mrgreen:
Bei Boolean bin ich mir auch nicht sicher. Laut winnt.h ist es byte

PS: LARGE_INTEGER kannste durch quad ersetzen!

Verfasst: 22.06.2008 22:14
von Kaeru Gaman
Ground0 hat geschrieben:Naja LARGE_INTEGER muss schon ein vordefiniertes Structure sein, habe es nicht selbst definiert...

Ich weiss nur dass es Total 32 Bytes sein müssen ...
dann müßte rechnerisch LARGE_INTEGER 10byte haben, 80bit, durchaus realistisch, meine ich schon mal gehört zu haben...
läßt sich also nicht durch Quad ersetzen.
also ist BOOL 32bit = Long, wie ich vermutet habe.

10 byte Capacity.LARGE_INTEGER
10 byte Remaining.LARGE_INTEGER
04 byte BlockSize.l
04 byte PartitionCount.l
04 byte WriteProtected.l
---------
32 byte

Verfasst: 22.06.2008 22:21
von ts-soft
Structureverzeichnis hat geschrieben:Structure LARGE_INTEGER
lowpart.l
highpart.l
EndStructure
also doch Quad :mrgreen:
In der MSDN ist es als StructureUnion definiert mit einem zusätzlichem Quad.

WriteProtected ist entweder Byte oder Long, aber nichts anderes.
//edit:
http://msdn.microsoft.com/en-us/library/ms817922.aspx
http://tinyurl.com/6xr3sc
http://tinyurl.com/5dqvna

Verfasst: 22.06.2008 22:30
von Kaeru Gaman
ok...
aber dann kommt das mit 32byte nicht hin, dann sinds nur 28

Verfasst: 23.06.2008 08:13
von Danilo
Ground0 hat geschrieben:Ich weiss nur dass es Total 32 Bytes sein müssen ... aber es kommt immer folgendes zurück im Error:234
MSDN:
ERROR_MORE_DATA
234
0xEA
More data is available.
Der Fehler kommt weil Du Size vorher nicht auf die Größe der
Structure setzt, die Du übergibst.
Size ist ein [in/out] Parameter:
in = Größe der Struktur die Du übergibst
out = Größe die erforderlich ist

Scheint ein Fehler in der Dokumentation von Microsoft zu sein.
Ist aber auch logisch, denn woher soll WinAPI sonst wissen wie
groß die übergebene Struktur ist? Diese Info kann es nur durch
den Parameter lpdwSize bekommen, nicht anders.
Ein sehr schlimmer Fehler in der Doku, nicht einfach... :)

Die Struktur wird mit 8 gepackt, d.h. sie wird automatisch aufgefüllt
bis sie eine Größe hat die durch 8 teilbar ist. PB macht das halt nicht,
die anderen Compiler aber. :)
Die Struktur sollte also in PureBasic so aussehen:

Code: Alles auswählen

Structure TAPE_GET_MEDIA_PARAMETERS
  Capacity.LARGE_INTEGER 
  Remaining.LARGE_INTEGER 
  BlockSize.l
  PartitionCount.l
  WriteProtected.b
  __fill.b[7]
EndStructure
Möchtest Du in Deiner Procedure Quads direkt zurückgeben, dann
solltest Du aber auch die LARGE_INTEGER zu Quads machen:

Code: Alles auswählen

Procedure.q Tape_GetFreeSpace(hTape.l) ;Final
  Structure TAPE_GET_MEDIA_PARAMETERS
    Capacity.q
    Remaining.q 
    BlockSize.l
    PartitionCount.l
    WriteProtected.b
    __fill.b[7]
  EndStructure
  Global Parameter.TAPE_GET_MEDIA_PARAMETERS, Size.l, Error.l
  
  Size = sizeOf(TAPE_GET_MEDIA_PARAMETERS)

  Error.l = GetTapeParameters_(hTape.l, 0, @Size.l, @Parameter)
  ;Error.l = GetLastError_()
  If Error.l <> 0
    ProcedureReturn 0
  Else
    ProcedureReturn Parameter\Remaining
  EndIf
EndProcedure
Hoffe das hilft... :)

Verfasst: 23.06.2008 08:29
von Ground0
Danke werde es heute abend testen.

Gruss G0

Verfasst: 23.06.2008 10:16
von hardfalcon
Hmm, das mit dem __fill.b[7] is ein genialer TRick, da wär ich selber nich so schnell drauf gekommen... :oops: Muss ich mir merken,,, :)