Seite 4 von 5

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 00:50
von Falko
Versuch mal in folgenden Codeteil aus dem Source den Wert 0 in 1 oder 2 zu ändern.
If OpenPhysDrive(0) = #INVALID_HANDLE_VALUE
End ; es gibt keinen Ausstieg aus dem Programm-CD
EndIf
If OpenPhysDrive(1) = #INVALID_HANDLE_VALUE
End ; es gibt keinen Ausstieg aus dem Programm-CD
EndIf
Hier steckt die Auswahl zum physikalischen Laufwerk. Normal ist C Physikalisch das Laufwerk 0.
Vielleicht ist aber eine zweite Platte vorhanden, die C ist und evtl. dann auf 1 oder 2 liegt. Das müsste man ausprobieren.

Gruß,
Falko

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 01:16
von Bisonte
Nach Schwenk auf "2" funktioniert es nun ;)

Es kommt schon synchron mit der Gehäuse LED hin, allerdings leuchtet die Gehäuse LED
ab und an mal auf, aber Scroll Lock nicht. Wird jetzt nur ein einziges Laufwerk abgefragt,
und muss ich mich jetzt um andere Laufwerke noch kümmern, oder ist das eigentlich jetzt
schon so : Laufwerk "all inclusive" ?

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 01:38
von Falko
Welche Laufwerke meinst du?
So wie es aussieht ist mit physikalischen Laufwerk die Festplatte gemeint.
Hat diese also Partitionen sind dieses logische Laufwerke, die ebenfalls mit
der LED angezeigt werden. Wenn eine weitere Festplatte vorhanden ist, die
z.B. mit dem Aufruf der Procedure in diesem String eingesetzt wird, also:
"\\.\PHYSICALDRIVE" + Str(CurrentDrive)..."
Quasi im Moment ist deine Platte C wohl auf CurrentDrive = 2, dann auf
2 oder 0, dann müsstest du die Procedure erweitern, da nur das hdh
überprüft wird und somit auch in der Repeatschleife nur auf hdh reagiert wird.

Das mit dem Scroll-Lock würde ich mal von Hand überprüfen, ob es geht.

Code: Alles auswählen

Procedure SetScrollLED(VKkey.l, bState.b)

Dim keyState.b(256)
GetKeyboardState_(@keyState(0))

If (bState = #True And keyState(VKkey) = 0) or (bState = #False And keyState(VKkey) = 1)
  keybd_event_(VKkey, 0, #KEYEVENTF_EXTENDEDKEY, 0)
  keybd_event_(VKkey, 0, #KEYEVENTF_EXTENDEDKEY + #KEYEVENTF_KEYUP, 0)
  keyState(VKkey) = bState
  SetKeyboardState_(@keyState(0))
EndIf

EndProcedure  

SetScrollLED(#VK_SCROLL,#True) 
MessageRequester("HDD", "Scroll-Lock eingeschaltet?", #PB_MessageRequester_Ok)
SetScrollLED(#VK_SCROLL,#False) 
MessageRequester("HDD", "Scroll-Lock ausgeschaltet?", #PB_MessageRequester_Ok)
Wenn dieser kleine Ausschnitt funktioniert, müsste der Code eigentlich bei dir auch komplett
funktionieren. Evtl. das Delay(10) etwas vergrößern, denke ich. Vielleicht ist das aus diesem
Grund im Code vorhanden. Leider kenne ich den Source auch nicht und muss mich darin
etwas hineindenken :)

Gruß,
Falko

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 01:47
von Helle

http://www.mdcc-fun.de/k.helbing/HDD-LED/

Wie heisst es so schön: Das Angebot gilt nur begrenzt... :mrgreen:
Es ist aber wirklich nichts Gefährliches; gab dazu auch in der c´t mal einen Beitrag.

Gruß
Helle

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 15:58
von Andreas21
Helle hat geschrieben:
http://www.mdcc-fun.de/k.helbing/HDD-LED/

Wie heisst es so schön: Das Angebot gilt nur begrenzt... :mrgreen:
Es ist aber wirklich nichts Gefährliches; gab dazu auch in der c´t mal einen Beitrag.

Gruß
Helle
Hi, dieser Code zeigt bei mir nur 1 SATA Laufwerk an obwohl ich 2 habe und sagt das "Port 0 ist z.Z. nicht belegt" und "Keine AHCI-SATA-Platte gefunden !".
Windows 7 x86

SATA sind Drive 0 und 1 DVD ist nicht angeschlossen.
Und auch kein anderes Laufwerk wie USB Festplatten u.s.w.

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 17:01
von Helle
@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
Gruß
Helle

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 19:47
von mk-soft
@Falko

Das mit "Delay(10)" war um die LED zum blinken zu bringen. Darum hat es auch so komisch geblinkt wenn keine Aktivität vorhangen war und in das Popupmenu gegangen wurde.
Habe doch den Code deswegen angepasst das die LED nur leuchtet wenn auch Schreib oder Lesezugriffe sind.

P.S. Somit ist der Code auch besser lesbar

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 19:58
von Falko
@mk-soft
ich finde das doch prima, das du den Source nochmal angepasst hast.
Er ist ja nicht von mir. :)

Dann könnte man für Lese und Schreibzugriffe das Menü in der Task leiste,
wenn man auf das Symbol mit den Plattenicons mit Rechts anklickt und auf
Über einstellt doch weglassen. Damit Blinkt die LED viel schneller und zurückschalten
kann man das wohl nicht, außer wenn man mal die Scroll-Lock-Taste kurz ein und ausschaltet.

Aber sonst sieht das prima aus. Da ich kein Russisch kann :cry: musste ich mich
mit der Googleübersetzung zufrieden geben und hier und da was anpassen, wo ich meine,
das es dazu besser passt.

Auf jeden Fall ist der Code in der letzten Änderung super und kommt ganz ohne 3.Partie-DLLs aus.

Warum das bei Bisonte nicht funktionieren sollte, bis auf den blinkenden Icons, wundert mich ein bisschen, da dieses normale Standard-APIs sind.

Gruß,
Falko

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 21:00
von Andreas21
Hi,

AHCI ist nun an.
Unter Win7 x64 leufts nun aber unter Win7 x86 kommt immer noch diese meldung.

Re: Festplattenaktivität feststellen ?

Verfasst: 06.01.2012 21:07
von mk-soft
@falko

Vielleicht ist auch seine LED total kaputt :mrgreen: