![]() |
Re: Festplatte ausschalten
Hmm, ich hab' mir den Treiber mal angesehen. Er importiert zumindestens nicht allzu viele Funktionen:
Delphi-Quellcode:
Hat irgendwer eine Idee, wie der Treiber arbeiten könnte? Könnte ein Anfänger in Sachen Treiberprogrammierung mit Grund - C - Syntax - Kenntnissen und ab jetzt zuviel Zeit (/ME) sowas auch schreiben?
//Impotierte Funktionen
IoCreateSymbolicLink 00010280 IoCreateDevice 00010284 RtlInitUnicodeString 00010288 IofCompleteRequest 0001028C IoDeleteSymbolicLink 00010290 KeQuerySystemTime 00010294 IoDeleteDevice 00010298 //Interne Funktionen aDeviceHdsback 000102A0 aDosdevicesHdsb 000102C0 aDosdevicesHd_0 00010420 //Exportierte Funktionen start 000102E8 P *auf Olli wart'* |
Re: Festplatte ausschalten
![]() Zitat:
|
Re: Festplatte ausschalten
So, um meinen Monolog jetzt zu komplettieren (:mrgreen:)
Die Lösung Man definiere folgende Typen (Dank' an Alex Konshin für seine Unit, die diese Definitionen schon beinhaltet)
Delphi-Quellcode:
Man übernehme diese Konstanten:
Type
TIDERegs = packed record bFeaturesReg : Byte; // Used for specifying SMART "commands". bSectorCountReg : Byte; // IDE sector count register bSectorNumberReg : Byte; // IDE sector number register bCylLowReg : Byte; // IDE low order cylinder value bCylHighReg : Byte; // IDE high order cylinder value bDriveHeadReg : Byte; // IDE drive/head register bCommandReg : Byte; // Actual IDE command. bReserved : Byte; // reserved for future use. Must be zero. end; IDEREGS = TIDERegs; PIDERegs = ^TIDERegs; TIdSector = packed record wGenConfig : Word; //00 wNumCyls : Word; wReserved : Word; wNumHeads : Word; wBytesPerTrack : Word; wBytesPerSector : Word; wSectorsPerTrack : Word; wVendorUnique : Array[0..2] of Word; sSerialNumber : Array[0..19] of Char; //10-19 wBufferType : Word; wBufferSize : Word; wECCSize : Word; sFirmwareRev : Array[0..7] of Char; //23-26 sModelNumber : Array[0..39] of Char; //27-46 wMoreVendorUnique : Word; wDoubleWordIO : Word; wCapabilities : Word; wReserved1 : Word; wPIOTiming : Word; wDMATiming : Word; wBS : Word; wNumCurrentCyls : Word; wNumCurrentHeads : Word; wNumCurrentSectorsPerTrack : Word; ulCurrentSectorCapacity : ULONG; //57-58 wMultSectorStuff : Word; ulTotalAddressableSectors : ULONG; //60-61 wSingleWordDMA : Word; wMultiWordDMA : Word; //63 wFlowControlPIOSupported : Word; //64 wMinimumMultiWordDMA : Word; //65 wRecommendedMultiWordDMA : Word; //66 wMinimumPIOCycleWOFlow : Word; //67 wMinimumPIOCycleIORDYFlow : Word; //68 bReserved1 : Array[0..21] of Byte; //69-79 wMajorVersionNumber : Word; //80 wMinorVersionNumber : Word; //81 wCommandSetSupported : Word; //82 wCommandSetSupported2 : Word; //83 wCommandSetExtension : Word; //84 wCommandSetFeatureEnabled1 : Word; //85 wCommandSetFeatureEnabled2 : Word; //86 wCommandSetFeatureEnabled3 : Word; //87 wUltraDMAMode : Word; //88 wTimeRequiredErase : Word; //89 wTimeRequiredEnhancedErase : Word; //90 wAbleMode : Word; //91 bReserved2 : Array[0..71] of Byte; //92-127 wSecurityModeFeature : Word; //128 wCurrentFeatureOption : Word; //129 wReserved2 : Word; //130 wInitialPowerMode : Word; //131 bReserved3 : Array[0..247] of Byte; //132-255 end; PIdSector = ^TIdSector;
Delphi-Quellcode:
Und dann diese beiden Funktionen:
const
BufferSize = SizeOf(TIDERegs)+4; IOCTL_IDE_PASS_THROUGH = $0004d028;
Delphi-Quellcode:
Voilà.
Function IdeRegPassThrough(Device: String; var ideregs: TIDERegs ): Boolean;
var ret:BOOL; hDevice : THandle; cbBytesReturned : DWORD; pInData : PIDERegs; pOutData : Pointer; Buffer : Array[0..BufferSize-1] of Byte; begin Result := False; FillChar(Buffer,BufferSize,#0); hDevice := CreateFile( PChar(Device), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 ); if hDevice=INVALID_HANDLE_VALUE then Exit; try pInData := @Buffer; pOutData := pInData; pInData^ := ideregs; ret := DeviceIoControl( hDevice, IOCTL_IDE_PASS_THROUGH, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil ); if not ret then begin Exit; end; ideregs := PIDERegs(pOutData)^; finally CloseHandle(hDevice); end; Result := True; end; function SendToSleep(Device: String): Boolean; var ideregs : TIDERegs; begin Result := False; with ideregs do begin bFeaturesReg := 0; bSectorCountReg := 0; bSectorNumberReg := 0; bCylLowReg := 0; bCylHighReg := 0; bDriveHeadReg := $A0; bCommandReg := $E6; bReserved := 0; end; if not IdeRegPassThrough(Device, ideregs ) then Exit else Result := True; end; Jetzt die Erklärung: Die Funktion IdeRegPassThrough stammt aus einem japanischen Projekt, in dem es darum ging, das APM von Festplatten unter W2k zu kontrollieren. Um dies zu tun, werden ATA - Kommandos an die Festplatte geschickt. Dies kann man unter Windows 2000 aufwärts mit dem Befehl IOCTL_IDE_PASS_THROUGH bewerkstelligen. Jetzt brauch man eigentlich nur den Befehl zum Ausschalten an die Platte senden. Dies geschieht mit meiner Funktion SendToSleep, die als Parameter \\.\PhysicalDriveX erwartet, wobei X hier für eine Zahl steht. Dabei repräsentiert die 0 euer erstes IDE - Laufwerk, die 1 euer zweites usw... Der eigentliche Befehl findet sich in dieser Zeile:
Delphi-Quellcode:
$E6 ist laut ATA - Definition der Sleep-Befehl. Dieser ist ab ATA4 Pflicht. Er erwartet keine weiteren Parameter und gibt auch keine Werte zurück.
bCommandReg := $E6;
Beispielaufruf: Aufgerufen werden könnte die Funktion zum Beispiel so:
Delphi-Quellcode:
Mal sehen, vllt. baue ich so eine Funktion noch in mein SMART - Programm ein. Über den Sinn und Zweck schweige ich mich aus. Es gibt Solche, die meinen, soetwas sei für die Lebensdauer der Hardware nicht förderlich, wieder andere meinen, ab einer gewissen Zeit würde das sogar Sinn ergeben.
if SendToSleep('\\.\PhysicalDrive'+ SleepEdit.Text) then
Showmessage('Laufwerk erfolgreich schlafen gelegt') else Showmessage('Laufwerk nicht schlafen legen können'); end; Ich hoffe, ich konnte euch etwas helfen... |
Re: Festplatte ausschalten
Hatte mal vor 'ner ewigkeit so'ne "Doku" gesehn, darin ging es um den Umzug ein (Fernseh)Redaktion und odrt haben die masig aufwand bestrieben, daß die Festplatten janicht zuweit abkühlen ... die Dinger liefen (weil es "angeblich" besser ist) immer durch ... vom Einbau, bis sie mal irgendwann durch 'ne neue esetzt werden (was aus Sicherheitsgrünnden alle ner bestimmten Zeit gemacht wurde)
Also angeblich soll es demnach besser sein, wenn die nicht ständig abschalten ... sich erwärmen und abkühlen, also ausdehnen und zusammenziehn ... wodurch struckturelle Schäden entstehen sollen. Kann man sich so wie en Sand in den meisten Wüsten vorstellen .. das waren mal rießige steine ... sie eißen Tage und kalten Nächte haben sie aber zebröseln lassen ._. Für den Umzug liefen die platten also is zur letzten Sekunde wuren superschnell ausbebaut, spezialverpackt verschickt und immernoch warm wieder eingebaut, und angeschaltet ... damit die blosnicht zu sehr auskühlen ... |
Re: Festplatte ausschalten
Moin Himitsu,
da muss man aber zwischen Server- und Workstationplatten unterscheiden. Serverplatten sind für den Dauerbetrieb ausgelegt, normale Workstationplatten dafür, dass man ihnen auch mal Ruhe gönnt (was die Serverplatten nicht so sehr mögen ;-)) |
Re: Festplatte ausschalten
Zitat:
|
Re: Festplatte ausschalten
dann muß ich mir wohl Sorgen machen ... also wenn die mal ein paar Tage/Wochen durchlaufen?
|
Re: Festplatte ausschalten
Moin Himitsu,
ich würde mir zumindest immer mal wieder die SMART-Daten anschauen, speziell auf Veränderungen |
Re: Festplatte ausschalten
Zitat:
|
Re: Festplatte ausschalten
naja...aber für leute mit einem homeserver die ihre festplatten aus defekten rechnern aus der schule beziehen könnte das zumindest für die backup-festplatte interessant sein ;-)
diese Linux-variante hört sich SEHR interessant an :-) Edit: Ahhhhh....ist das Leise an meinem Server... *genieß* |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz