@Andreas21: Ich vermute, AHCI ist auf Deinem PC nicht aktiviert (bitte mal im BIOS nachschauen!). Damit wird übrigens auch etliche Leistung verschenkt. Im nachfolgen Code habe ich weiter Abfragen eingebaut (hatte bisher vorausgesetzt, dass mindestens eine AHCI-SATA-Platte angeschlossen ist).
Code: Alles auswählen
;- Festplatten-Aktivität AHCI-SATA-Geräte, 64-Bit-Windows
;- "Helle" Klaus Helbing, 06.01.2012, PB v4.60 (x64)
;- Benötigt WinIo v3.0 und für 64-Bit die Atsiv.exe; es sei denn andere Treiber sind vorhanden
#PROCESSOR_ARCHITECTURE_AMD64 = $9
#SATA_SIG_ATA = $00000101 ;SATA drive = HDD
#SATA_SIG_ATAPI = $EB140101 ;SATAPI drive = CD/DVD (optisches LW)
#SATA_SIG_SEMB = $C33C0101 ;Enclosure management bridge
#SATA_SIG_PM = $96690101 ;Port multiplier
#Class_ID = $01060000 ;Class $01=mass storage device, SubClass $06=serial ATA
;einmaliges Install für 32-Bit; Prinzip, ungetestet
;If OpenLibrary(0, "WinIo32.dll") ;32-Bit-Version laden, Pfad beachten
;Prototype.i ProtoWinIo(Pfad.i, Bool.i)
;Global WIO_InstallWinIoDriver.ProtoWinIo = GetFunction(0, "InstallWinIoDriver")
;Pfad$ = "C:\Codes\PureBasic 4.0\IO\64-Bit\WinIO\PB\" ;Pfad zu WinIo32.sys
;WIO_InstallWinIoDriver(@Pfad$, #False)
;CloseLibrary(0)
;EndIf
OpenWindow(0, 0, 0, 400, 400, "Festplatten-Aktivität AHCI-SATA-Geräte", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;ermitteln, ob 32- oder 64-Bit-Betriebssystem
SI.SYSTEM_INFO ;Structure System_Info
GetSystemInfo_(@SI)
If SI\wProcessorArchitecture = #PROCESSOR_ARCHITECTURE_AMD64
DLLOK = OpenLibrary(0, "WinIo64.dll") ;64-Bit-Version laden
;----- dies nur für 64-Bit; Pfad beachten (hier Atsiv.exe im selben Verzeichnis wie .pb oder .exe)
RunProgram("Atsiv.exe" ," -u " + "WinIo64.sys", "", #PB_Program_Hide) ;oder auslagern
Delay(250)
RunProgram("Atsiv.exe" ," -f " + "WinIo64.sys", "", #PB_Program_Hide)
Delay(250) ;evtl.anpassen
;-----
Else
DLLOK = OpenLibrary(0, "WinIo32.dll") ;32-Bit-Version laden
EndIf
If DLLOK
Prototype.i ProtoWinIo_0()
Global WIO_InitializeWinIo.ProtoWinIo_0 = GetFunction(0, "InitializeWinIo")
Global WIO_ShutdownWinIo.ProtoWinIo_0 = GetFunction(0, "ShutdownWinIo")
Prototype.i ProtoWinIo_2(physAddr.i, physVal.l)
Global WIO_GetPhysLong.ProtoWinIo_2 = GetFunction(0, "GetPhysLong")
Prototype.i ProtoWinIo_3(Port.w, Value.l, G.b)
Global WIO_SetPortVal.ProtoWinIo_3 = GetFunction(0, "SetPortVal")
Global WIO_GetPortVal.ProtoWinIo_3 = GetFunction(0, "GetPortVal")
WIO_InitializeWinIo()
;- Aufbau Bus-Configuration-Address-Register, Adresse $0CF8:
;- Bit 0-1: Reserviert
;- Bit 2-7: Register-Nummern (DWords) 0-63, $2=Class/SubClass-ID
;- Bit 8-10: Funktions-Nummer 0-7
;- Bit 11-15 Device-Nummer 0-31
;- Bit 16-23 Bus-Nummer 0-255, 0=PCI
;- Bit 24-30 Reserviert
;- Bit 31: Configuration-Address-Register Ein/Aus
;PCI-Bus absuchen nach Class $01=mass storage device, SubClass $06=serial ATA
ABAR.i
Port_BCAR.w = $0CF8 ;Bus-Configuration-Address-Register
Port_BCDR.w = $0CFC ;Bus-Configuration-Data-Register
GetValue.l
SetValue.l = $80000000 + %1000 ;Bit 31 setzen sowie Class/SubClass
For i = 0 To 31 ;Device-Nr.
SetValue & $FFFFF8FF ;Funktions-Nr. auf Null setzen
For k = 0 To 7 ;Funktions-Nr.
WIO_SetPortVal(Port_BCAR, SetValue, 4) ;4=Dword-Wert schreiben
WIO_GetPortVal(Port_BCDR, @GetValue, 4) ;Bus-Configuration-Data-Register auslesen
If (GetValue & $FFFF0000) = #Class_ID ;$01060000
SetValue = (SetValue & $FFFFFFF0) + %100100 ;ABAR auslesen (Register-Nummer 9)
WIO_SetPortVal(Port_BCAR, SetValue, 4) ;4=Dword-Wert schreiben
WIO_GetPortVal(Port_BCDR, @GetValue, 4) ;Bus-Configuration-Data-Register auslesen
ABAR = GetValue & $FFFFFFFF ;ABAR=AHCI Base Address
ABAR$ = "AHCI Base Address gefunden an Adresse : $" + Hex(ABAR)
Break 2
EndIf
SetValue + $100
Next
Next
If ABAR = 0
MessageRequester("Achtung !", "AHCI nicht vorhanden oder nicht aktiviert !")
End
EndIf
TextGadget(1, 10, 10, 380, 20, ABAR$)
;ermitteln, wieviel AHCI-Ports vorhanden sind
WIO_GetPhysLong(ABAR + $0C, @GetValue) ;$0C=Ports Implemented, jedes gesetzte Bit ist ein SATA-Port (0-31)
If GetValue = 0
MessageRequester("Achtung !", "Keinen AHCI-SATA-Port gefunden !")
End
EndIf
Anz_SATA = Len(Bin(GetValue))
Anz_SATA$ = "Anzahl SATA-Ports gefunden : " + Str(Anz_SATA)
TextGadget(2, 10, 30, 380, 20, Anz_SATA$)
;was ist dran an gefundenen Ports?
Signatur = ABAR + $124 ;$124=Signatur Port0
Matrix = 0
k = 1
For i = 1 To Anz_SATA
WIO_GetPhysLong(Signatur, @GetValue)
Typ = GetValue & $FFFFFFFF
Select Typ
Case #SATA_SIG_ATA
Typ$ = "Port " + Str(i - 1) + " ist ein SATA-Drive (HDD)"
Matrix | k
Case #SATA_SIG_ATAPI
Typ$ = "Port " + Str(i - 1) + " ist ein SATAPI-Drive (z.B. optisches LW)"
Case #SATA_SIG_SEMB
Typ$ = "Port " + Str(i - 1) + " ist eine Enclosure Management Bridge)"
Case #SATA_SIG_PM
Typ$ = "Port " + Str(i - 1) + " ist ein Port Multiplier"
Default
Typ$ = "Port " + Str(i - 1) + " ist z.Z. nicht belegt"
EndSelect
TextGadget(2 + i, 10, 30 + (20 * i), 380, 20, Typ$)
Signatur + $80 ;nächster Port
k << 1
Next
If Matrix = 0
MessageRequester("Achtung !", "Keine AHCI-SATA-Platte gefunden !")
End
EndIf
k = i
j = Matrix
For n = i To Anz_SATA + i - 1
If j & 1
TextGadget(2 + k, 10, 50 + (20 * k), 80, 20, "Status Port " + Str(n - i) + " : ")
TextGadget(2 + k + Anz_SATA, 100, 50 + (20 * k), 80, 20, "Ruhe", #PB_Gadget_FrontColor)
k + 1
j >> 1
EndIf
Next
;jetzt die SATA-Platten beobachten
AddWindowTimer(0, 0, 5) ;5 ms, Geschmackssache
Repeat
If Event = #PB_Event_Timer And EventTimer() = 0 ;Aktualisierung und Anzeige ca. alle 0.05 Sekunden
SATA_Activ = ABAR + $134 ;$134=Port0 Device Status auslesen, ist nur eine von mehreren Möglichkeiten
k = i
j = Matrix
For n = i To Anz_SATA + i - 1
If j & 1
WIO_GetPhysLong(SATA_Activ, @GetValue)
If GetValue
SetGadgetText(2 + k + Anz_SATA, "Action") ;kann man natürlich auch grafisch gestalten
SetGadgetColor(2 + k + Anz_SATA, #PB_Gadget_FrontColor, $D0)
Else
SetGadgetText(2 + k + Anz_SATA, "Ruhe")
SetGadgetColor(2 + k + Anz_SATA, #PB_Gadget_FrontColor, $8800)
EndIf
k + 1
j >> 1
EndIf
SATA_Activ + $80 ;nächster Port
Next
EndIf
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
;WIO_ShutdownWinIo()
CloseLibrary(0)
EndIf