Seite 1 von 1

GELÖST: GetDiskFreeSpaceEx funkioniert unter Unicode nicht

Verfasst: 14.12.2009 14:39
von Vulcan_TBB
Hallo Community!

Nach einiger Zeit des passiven Mitlesens (und dem finden zahlreicher Tipps und Kniffe)
bin ich nun auf ein Problem gestossen, bei dem ich irgendwie nicht weiterkomme.

Wegen Lokalisierung eines kleinen Tools wurde es notwendig, das ich ich eine Unicode-Version meiner Executable erstelle.
Einige kleiner Unicode-Problemchen konnten ich umschiffen - nur bei einem Problem hänge ich im Moment noch.

Der allseits beliebte API-Call GetDiskFreeSpaceEx funktioniert unter Unicode nicht mehr.

Code: Alles auswählen

;--- GetDiskFreeSpaceDynamic.pbi --- 
; ProcedureReturn = FreeMB ;==> OK
; ProcedureReturn = -1     ;==> GetDiskFreeSpaceExA not available under Win95A

Procedure.l GetDiskFreeSpaceDynamic(Drive$)
  
   Structure int64 
     Long1.l 
     Long2.l 
   EndStructure 
   
   FreeMB.l = -1 
   
   If OSVersion() <> #PB_OS_Windows_95  
      DLL = OpenLibrary(#PB_Any, "Kernel32") 
      If DLL 
         SetErrorMode_(#SEM_FAILCRITICALERRORS)
         CallFunction(DLL, "GetDiskFreeSpaceExA", @drive$, BytesFreeToCaller.int64, TotalBytes.int64, TotalFreeBytes.int64)
         SetErrorMode_(0)
         CloseLibrary(DLL)                              
      EndIf    
      ; calculate sizes in mb. 
      ; TotalMB = ((TotalBytes\Long1 >> 20) & $FFF) | (TotalBytes\Long2 << 12) 
      FreeMB = ((TotalFreeBytes\Long1 >> 20) & $FFF) | (TotalFreeBytes\Long2 << 12) 
   EndIf 

   ProcedureReturn FreeMB 
EndProcedure

; Drive$   = "C:\"
; FreeMB.l = 0
; FreeMB   =GetDiskFreeSpaceDynamic(Drive$)
; If FreeMB = -1 
;    MessageRequester (" Error", "GetDiskFreeSpaceExA not available under Win95A",0)
; Else
;    MessageRequester (" OK",    "Free: " + Str(FreeMB) + " MB")
; EndIf
Ich vermute, das der Hund irgendwo in der Structure int64 (long vielleicht nicht ausreichend?) oder in der right/left-shifterei ( FreeMB = .... ) begraben liegt. Ich hab leider nur ein gefährliches Halbwissen, was Unicode unter PB angeht.

Gerade, was Offsets & Co angeht, habe ich in anderen Sprachen schon einige Überraschungen erlebt. Wie wird das unter PB gehandelt? Bzw. könnte mir eventuell jemand einen Tipp geben, wie ich die Funktion auch unter unicode zum laufen bekomme?

Besten Dank für eure Hilfe - Mein Dank wird euch ewig nachschleichen! ;)
Stefan

Re: GetDiskFreeSpaceEx-Aufruf unter Unicode funkioniert nicht

Verfasst: 14.12.2009 14:47
von Vulcan_TBB
Urgs!

Kurz nachdem ich hier gepostet habe, bin ich noch ein wenig tiefer in die MSDNeingestiegen - und habe doch glatt die Lösung selbst gefunden.

Machmal sieht man den Wald vor lauter Bäumen nicht; unter Unicode lautet der Funktionsname: GetDiskFreeSpaceExW

Der korrekte, funktionierende Funktion sieht dann also so aus:

Code: Alles auswählen

   Structure int64 
     Long1.i 
     Long2.i 
   EndStructure 
    
   FreeMB.l = -1 
    
   If OSVersion() <> #PB_OS_Windows_95  
      DLL = OpenLibrary(#PB_Any, "Kernel32") 
      If DLL 
         SetErrorMode_(#SEM_FAILCRITICALERRORS) 
         CallFunction(DLL, "GetDiskFreeSpaceExW", @drive$, BytesFreeToCaller.int64, TotalBytes.int64, TotalFreeBytes.int64) 
         SetErrorMode_(0) 
         CloseLibrary(DLL)                              
      EndIf    
      ; calculate sizes in mb. 
      ; TotalMB = ((TotalBytes\Long1 >> 20) & $FFF) | (TotalBytes\Long2 << 12) 
      FreeMB = ((TotalFreeBytes\Long1 >> 20) & $FFF) | (TotalFreeBytes\Long2 << 12) 
   EndIf  
Trotzdem Danke an alle, die hier mit reingelesen haben! ;)

Re: GELÖST: GetDiskFreeSpaceEx funkioniert unter Unicode nicht

Verfasst: 14.12.2009 20:54
von HeX0R
Hast du nur die Demo von PB, oder warum machst du das so umständlich?

Falls du die Vollversion (>= 4.0) hast, kannst du es auch so machen, und PB kümmert sich darum, die richtige Version der API (also Unicode oder nicht) zu benutzen:

Code: Alles auswählen

Procedure.d GetDiskFreeSpaceDynamic(Drive$)
	Protected Result.d = -1, BytesFreeToCaller.q, TotalBytes.q, TotalFreeBytes.q

	If OSVersion() > #PB_OS_Windows_95
		SetErrorMode_(#SEM_FAILCRITICALERRORS)
		GetDiskFreeSpaceEx_(@Drive$, @BytesFreeToCaller, @TotalBytes, @TotalFreeBytes)
		SetErrorMode_(0)
		Result = TotalFreeBytes / 1048576
	EndIf

	ProcedureReturn Result
EndProcedure

Drive$   = "C:\"
FreeMB.d = 0
FreeMB   = GetDiskFreeSpaceDynamic(Drive$)
If FreeMB = -1
	MessageRequester (" Error", "GetDiskFreeSpaceExA not available under Win95A", 0)
Else
	MessageRequester (" OK",    "Free: " + StrD(FreeMB, 2) + " MB")
EndIf