Merevlemez leállítása szoftveresen

Merevlemez leállítása szoftveresen
2013-11-25T17:52:28+01:00
2013-11-26T09:04:18+01:00
2022-10-23T06:20:32+02:00
  • Most másik gépen vagyok ugyan, így a kódot nem tudom idemásolni, de működik! A megoldás az ATA -s struktúra használata volt.
    Több SATA parancsal is sikerült megállítani.
    Igazából elég lenne egyfajta "PAUSE".

    Esetleg tudtok ajánlani valami kis tool-t amivel a merevlemezek státuszát tudom figyelni?

    Köszi az eddigi segítséget végül is úgy tűnik meg van a megoldás. Pár nem 100% erre van szükség, de ebből már összehozom.
    Mutasd a teljes hozzászólást!
  • Ha nem számít a fogyasztás, akkor a mozgás a gond? Nem tudom mennyi az órabéred, de vegyél bele egy ssd-t, olcsóbb lesz.
    (de lehetne akár CF, SDHC kártya, pendrive stb -> még kevesebb helyet is foglal, sőt van sata/ide -be közvetlen dugható kivitelezés is, se kábel, se hely igénye nincs)
    Mutasd a teljes hozzászólást!
  • A miértet nem látom még sajnos, a hogyan-ban pedig nem tudok segíteni (se idő, se kedv beleásni magam MSDN-be).
    Majd ha időd engedi, kicsit jobban kifejtenéd, hogy ennek mi lesz a haszna?
    Mutasd a teljes hozzászólást!
  • A DeviceIoControl doksi idevágó szakasza:
    If lpOverlapped is NULL, lpBytesReturned cannot be NULL. Even when an operation returns no output data and lpOutBuffer is NULL, DeviceIoControl makes use of lpBytesReturned. After such an operation, the value of lpBytesReturned is meaningless.


    Első blikkre ezért panaszkodik érvénytelen paraméterre, de lehet, hogy más gond is van.

    szerk: Megint csak a doksi szerint, ehhez az IOCTL kódhoz nem ilyen típusú input és output structokat kéne átadni. Az IOCTL_ATA_PASS_THROUGH kódhoz a doksi szerint ATA_PASS_THROUGH_EX struktúrákat kell használni.
    Mutasd a teljes hozzászólást!
  • Frissített kód:


    #include <stdio.h> #include <conio.h> #include <windows.h> #include <Ntddscsi.h> #include <winioctl.h> #define DFP_GET_VERSION 0x00074080 #define DFP_SEND_DRIVE_COMMAND 0x0007c084 #define DFP_RECEIVE_DRIVE_DATA 0x0007c088 int main() { HANDLE hSMARTIOCTL = 0; hSMARTIOCTL = CreateFile("\\.\PHYSICALDRIVE0",GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); if ( hSMARTIOCTL == INVALID_HANDLE_VALUE) { printf("Unable to open physical drive, error code: 0x%lX\n", GetLastError()); } else { printf("Physical drive opened successfully\n"); } BOOL fResult; DWORD dwError; SENDCMDINPARAMS SCIP; SENDCMDOUTPARAMS SCOP; PDWORD BytesReturned = NULL; memset((&SCIP), 0, sizeof(SENDCMDINPARAMS)); memset((&SCOP), 0, sizeof(SENDCMDOUTPARAMS)); //SCIP.irDriveRegs.bFeaturesReg = ENABLE_DISABLE_AUTO_OFFLINE; SCIP.cBufferSize = 0; SCIP.irDriveRegs.bCommandReg = 0x00; // NOP: 0x00 // SLEEP IMMEDIATELY 0xE6, IDLE: 0xE1, STANDBY: 0xE2 fResult=DeviceIoControl(hSMARTIOCTL, IOCTL_ATA_PASS_THROUGH, (LPVOID)(&SCIP), sizeof(SENDCMDINPARAMS) - 1, (LPVOID)(&SCOP), sizeof(SENDCMDOUTPARAMS) - 1, BytesReturned, NULL) ; if (!fResult) { dwError = GetLastError (); printf("dwError=%d\n",dwError); } else { printf("OK!!!"); } system("pause"); return 0; }

    Jelenlegi hiba a DeviceIoControl hívásnál jön, "87" -es ami elvileg "ERROR_INVALID_PARAMETER", talán az input struktúra amiben a command-ot kapja? Próbálkozom...

    A megnyitás jó lehet,mert most tényleg csak admin módban fut.
    Mutasd a teljes hozzászólást!
  • Hát passzolom a kérdést, az MSDN-nél nem vagyok okosabb a témában, mert én még sose csináltam ilyet. Minden esetre beírhatnád a kódot, amivel most próbálkozol, úgy többet tudnánk segíteni. (Lehet, hogy valami flag még mindig nem stimmel, vagy hasonló apróbb hiba van már csak.)
    Mutasd a teljes hozzászólást!
  • wmic-vel kilistázva a meghajtóm "\.\PHYSICALDRIVE0" névre hallgat, átírtam erre és az említett OPEN_EXISITING -re

    így most a CreateFile nem sikerül és a hibakód "0x02"
    Mutasd a teljes hozzászólást!
  • Jogos.. Viszont így 0x2 hibaüzit kapok mindjárt a CreateFile hívásánál, ami ha minden igaz file not found -ot jelent
    Mutasd a teljes hozzászólást!
  • Az MSDN szerint a fizikai meghajtóknak nem olyan a nevük, hogy "akarmi.txt", hanem "\\.\PhysicalDrive0", "\\.\PhysicalDrive1", stb. Ezen kívül admin jogban kell futnia a nyitást kérő processznek, és az ötödik paraméterben szerepelnie kell az OPEN_EXISTING flagnek.

    Valószínűleg ezért kapod a hibát is, mert egy mezei fájlnak akarsz ioctl parancsokat adni.
    Mutasd a teljes hozzászólást!
  • Megvannak az érvényes ATA parancsok is.
    Aktuális kód:


    #include <stdio.h> #include <conio.h> #include <windows.h> #include <Ntddscsi.h> #include <winioctl.h> #define DFP_GET_VERSION 0x00074080 #define DFP_SEND_DRIVE_COMMAND 0x0007c084 #define DFP_RECEIVE_DRIVE_DATA 0x0007c088 int main() { HANDLE hSMARTIOCTL = 0; if ((hSMARTIOCTL = CreateFile("akarmi.txt",GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,0,NULL)) == INVALID_HANDLE_VALUE) { printf("Unable to open physical drive, error code: 0x%lX\n", GetLastError()); } else { printf("Physical drive opened successfully\n"); } BOOL fResult; DWORD dwError; SENDCMDINPARAMS SCIP; SENDCMDOUTPARAMS SCOP; PDWORD BytesReturned = NULL; memset((&SCIP), 0, sizeof(SENDCMDINPARAMS)); memset((&SCOP), 0, sizeof(SENDCMDOUTPARAMS)); SCIP.cBufferSize = 0; SCIP.irDriveRegs.bCommandReg = 0x00; // NOP: 0x00 // SLEEP IMMEDIATELY 0xE6, IDLE: 0xE1, STANDBY: 0xE2 fResult=DeviceIoControl(hSMARTIOCTL, IOCTL_ATA_PASS_THROUGH, (LPVOID)(&SCIP), sizeof(SENDCMDINPARAMS) - 1, (LPVOID)(&SCOP), sizeof(SENDCMDOUTPARAMS) - 1, BytesReturned, NULL) ; if (!fResult) { dwError = GetLastError (); printf("dwError=%d\n",dwError); } else { printf("OK!!!"); } system("pause"); return 0; }

    A 0x00 parancs tehát a NOP és még arra is hibát kapok akkor gondolom a DeviceIoCtl hívásnál keressem a problémát.

    Bárki, bármi tipp?
    Mutasd a teljes hozzászólást!
  • Semmi köze a fogyasztáshoz természetesen :)
    Egy célhardware mellé kellene, ami egy szimpla PC-n is futhatna.
    Annyi nem lehet kivitelezhetetlen a dolog, hiszen egy mezei Windows is megoldja.

    Kipróbálva a linkelt fórum utolsó forráskódját most ott tartok ahol a hozzászóló, kapom én is a hibakódokat "87", "86", attól függően melyik ATA command-ot próbálom küldeni, egy oldalon találtam többfélét mind kapcsolatos a SLEEP-el.
    Gondolom amin próbálkozom gép éppen ismeretlen a hardware számára ez a parancs, na de a winyó leállítható Windows-ból probléma nélkül. Tehát valamit ismer, de honnan kéne tudni, hogy micsodát?
    Mutasd a teljes hozzászólást!
  • Mi a cél, vagy a probléma, amire ez a megoldás?

    Ha a fogyasztás, akkor nem hiszem, hogy érdemes ebbe túl sok energiát ölnöd!
    Mutasd a teljes hozzászólást!
  • Igen, megtaláltam ezt is, de nem igazán történt semmi.
    Átnézem még amiket írtak, bár mintha nekik sem működött volna az ott bemásolt forráskódokból.
    Mutasd a teljes hozzászólást!
  • Lásd itt
    Mutasd a teljes hozzászólást!
  • Üdv!

    Útmutatást keresek a témában. Néhány fórum olvasgatása után úgy tűnik van több megoldás is, de nem feltétlen működnek. A WMI-ben van egy függvény ami a SetPowerState -re hallgat, de a hivatalos dokumentáció szerint nincs implementálva és saját magam kéne ezt megtennem. (Majdnem kimaradt: Ez sem kizáró ok, de akkor ebben kérek szépen útmutatást)
    A cél, hogy egy C++ -os szoftverből kikapcsoljam a PC-n található összes merevlemezt, mindezt azonnal kéne. Találtam és ki is próbáltam, hogy ATA parancsot küldök a merevlemeznek a DeviceIoControl függvénnyel. Lefut és nem is kapok hibát, de a világon nem történik semmi, többféle ATA command -al is próbálkoztam. Windows XP -től felefele kéne működnie.
    Bármilyen tippet meghallgatok, azt sem bánom, ha alacsony szintű megoldást találnék (sőt..).
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd