flat assembler
Message board for the users of flat assembler.

Index > Windows > [example] Disable APM on HDD

Author
Thread Post new topic Reply to topic
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek
This programme disables APM on HDD (which on some models is cause of clicking and excessive increase of "Load Cycle Count" S.M.A.R.T. parameter).

Structures and disable APM part are ripped off from quietHDD programme.

Code:
;http://www.codeproject.com/Articles/19165/Vista-UAC-The-Definitive-Guide

format PE GUI 4.0
include 'win32a.inc'


BROADCAST_QUERY_DENY        = $424D5144
PBT_APMQUERYSUSPEND      = $00
WM_POWERBROADCAST      = $218
PBT_APMBATTERYLOW     = $09
PBT_APMPOWERSTATUSCHANGE   = $0A
PBT_APMOEMEVENT            = $0B
PBT_APMQUERYSUSPEND    = $00
PBT_APMQUERYSUSPENDFAILED  = $02
PBT_APMRESUMECRITICAL      = $06
PBT_APMRESUMEAUTOMATIC         = $12
PBT_APMQUERYSUSPENDFAILED  = $02

IOCTL_IDE_PASS_THROUGH         = $04D028
IOCTL_ATA_PASS_THROUGH     = $04D02C
HDIO_DRIVE_CMD             = $03F1   ; Taken from /usr/include/linux/hdreg.h
HDIO_SET_ACOUSTIC          = $032C
HDIO_GET_ACOUSTIC    = $030F
WIN_SETFEATURES      = $EF
SETFEATURES_EN_AAM     = $42
SETFEATURES_DIS_AAM    = $C2
SETFEATURES_EN_APM     = $05
SETFEATURES_DIS_APM    = $85
ATA_FLAGS_DRDY_REQUIRED    = $01
ATA_FLAGS_DATA_IN          = $02
ATA_FLAGS_DATA_OUT     = $04
ATA_FLAGS_48BIT_COMMAND    = $08

struct IDEREGS
  bFeaturesReg            db ?
        bSectorCountReg         db ?
        bSectorNumberReg        db ?
        bCylLowReg              db ?
        bCylHighReg             db ?
        bDriveHeadReg           db ?
        bCommandReg             db ?
        bReserved               db ?
ends

struct ATA_PASS_THROUGH_EX
      Length                  dw ?
        AtaFlags                dw ?
        PathId                  db ?
        TargetId                db ?
        Lun                     db ?
        ReservedAsUchar         db ?
        DataTransferLength      dd ?
        TimeOutValue            dd ?
        ReservedAsUlong         dd ?
        DataBufferOffset        dd ?
        PreviousTaskFile        IDEREGS
     CurrentTaskFile         IDEREGS
ends
     
struct ATA_PASS_THROUGH_EX_WITH_BUFFERS
 Length                  dw ?
        AtaFlags                dw ?
        PathId                  db ?
        TargetId                db ?
        Lun                     db ?
        ReservedAsUchar         db ?
        DataTransferLength      dd ?
        TimeOutValue            dd ?
        ReservedAsUlong         dd ?
        DataBufferOffset        dd ?
        PreviousTaskFile        IDEREGS
     CurrentTaskFile         IDEREGS
     Filler                  db ?
        ucDataBuf               db 512 dup (?)
ends

section '.text' code readable executable
;http://stackoverflow.com/questions/5070987/sending-ata-commands-directly-to-device-in-windows
entry $
   invoke  IsUserAnAdmin
       or      eax,eax
     jz      noadmin

 invoke  CreateFile,_drive,GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ+FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0
        cmp     eax,-1
      je      finish
      mov     [hDrive],eax

    mov     [inbuffer.AtaFlags],ATA_FLAGS_DATA_IN
       mov     [inbuffer.DataTransferLength],512
   mov     [inbuffer.DataBufferOffset],sizeof.ATA_PASS_THROUGH_EX
;       mov     [inbuffer.CurrentTaskFile.bCommandReg],0ECh
;       mov     [inbuffer.CurrentTaskFile.bSectorCountReg],1
       mov     byte[inbuffer.ucDataBuf],$CF
        mov     [inbuffer.TimeOutValue],1
   mov     [inbuffer.CurrentTaskFile.bCommandReg],WIN_SETFEATURES
      mov     [inbuffer.CurrentTaskFile.bFeaturesReg],SETFEATURES_DIS_APM
 mov     [inbuffer.CurrentTaskFile.bSectorCountReg],0

    invoke  DeviceIoControl,[hDrive],IOCTL_ATA_PASS_THROUGH,inbuffer,sizeof.ATA_PASS_THROUGH_EX_WITH_BUFFERS,inbuffer,sizeof.ATA_PASS_THROUGH_EX_WITH_BUFFERS,bytes_count,0

;       invoke  CreateFile,_output,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
;       mov     [hFile],eax
;       invoke  WriteFile,eax,inbuffer,sizeof.ATA_PASS_THROUGH_EX_WITH_BUFFERS,bytes_count,0
;       invoke  CloseHandle,[hFile]


 invoke  CloseHandle,[hDrive]
        invoke  MessageBox,0,_Ok,0,MB_OK+MB_ICONINFORMATION
  finish:    
    invoke  ExitProcess,0

  noadmin:
 invoke  MessageBox,0,_adminReqd,0,MB_OK+MB_ICONHAND
 jmp     finish



section '.data' data readable writeable

  _drive TCHAR '\\.\PhysicalDrive0',0
  ;_output      TCHAR 'ata.dmp',0
  _adminReqd        TCHAR 'Administrator rights required to run this programme',0
  _Ok                TCHAR 'APM Disabled',0
  inbuffer  ATA_PASS_THROUGH_EX_WITH_BUFFERS     sizeof.ATA_PASS_THROUGH_EX

  hDrive dd ?
;  hFile                dd ?
  bytes_count   dd ?

section '.idata' import data readable
  library kernel32,'KERNEL32.DLL',\
         user32,'USER32.DLL',\
    shell32,'SHELL32.DLL'

  include 'api/kernel32.inc'
  import user32,\
        MessageBox,'MessageBoxA'
  import shell32,\
   IsUserAnAdmin,'IsUserAnAdmin'

section '.rsrc' resource data readable
  directory RT_MANIFEST,manifest

  resource manifest,\
  1,LANG_NEUTRAL,man
  resdata man
    file 'dipasm.manifest.xml'
  endres

    


dipasm.manifest.xml:
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
          manifestVersion="1.0"> 
<dependency> 
    <dependentAssembly> 
        <assemblyIdentity 
            type="win32" 
            name="Microsoft.Windows.Common-Controls" 
            version="6.0.0.0" 
            processorArchitecture="X86" 
            publicKeyToken="6595b64144ccf1df" 
            language="*" 
        /> 
    </dependentAssembly> 
</dependency> 
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel 
                level="requireAdministrator" 
                uiAccess="false"/>
        </requestedPrivileges>
    </security>
</trustInfo>
</assembly>
    


Last edited by bzdashek on 06 Aug 2012, 03:14; edited 1 time in total
Post 11 Jul 2012, 06:05
View user's profile Send private message Reply with quote
kalambong



Joined: 08 Nov 2008
Posts: 165
kalambong
Post 12 Jul 2012, 23:54
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek
Yes, that's the reason why I thought about writing a small one, since I needed only one parameter.
Post 14 Jul 2012, 21:33
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
I´ve been wanting to do something like this for some time. I´m also suffering from this problem and the clicking noise most of the time is really loud, very hard to not listen. Currently I´m firing a program and manually disabling APM each time I turn on my notebook (which I use it as my desktop PC on a daily basis).

Thanks for sharing.
Post 15 Jul 2012, 17:58
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek
Yep, me also. Have to launch it every PC wake up - from hibernation or sleep also. Why don't they patch their firmware, I wonder? Mine is Hitachi HTS545050A7E
Post 15 Jul 2012, 18:26
View user's profile Send private message Reply with quote
Goplat



Joined: 15 Sep 2006
Posts: 181
Goplat
It's really a pity that this has become necessary. Disk head parking used to be a good idea, since HDDs would often be idle for very long periods of time. Parking the heads would reduce power usage, so the temperature wouldn't get as high and it would actually extend the life of the drive. But this feature's been ruined by idiot programmers who think it's acceptable for a program to write to disk every 10 seconds for no reason... Sad
Post 20 Jul 2012, 02:04
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17720
Location: In your JS exploiting you and your system
revolution
Goplat wrote:
... idiot programmers who think it's acceptable for a program to write to disk every 10 seconds for no reason...
What do you mean no good reason? Is it not necessary to write all your logs to disk so that the TLAs can come along later and see what you have been up to?

[/sarcasm]
Post 20 Jul 2012, 07:44
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Mine is WDC WD6400BPVT-55HXZT2.

In the case of my computer, the HDD led turns on every second, and yet it insist in parking the heads moving them very aggressively (in fact I think the click sound is a bit louder than when I turn the computer off). I guess this is probably caused by the HDD internal buffer that doesn't cause R/W head activity soon enough to not timeout the idle timer.

At the rate the load/unload cycles occur, in my case it would exceed the manufacturer count limit in less than 3 years (and the warranty is 2 years, so forgive if I think they do this on purpose).
Post 20 Jul 2012, 16:35
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek
Fixed and updated source - now it works in GUI mode, and utilizes UAC (via manifest). Also, I'm not sure if old version disabled APM, since one parameter ([inbuffer.TimeOutValue]) was 0, but should be 1
Post 06 Aug 2012, 03:16
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek
I made it live in tray and keep an eye on Load Cycle Count parameter, and when it increases, it shoots the disabler, so even after a hibernation or sleep, it will be on-guard.

Sources are included


Description:
Filesize: 27.12 KB
Viewed: 2878 Time(s)

disapm2.png


Description:
Download
Filename: DisableAPM2.zip
Filesize: 59.02 KB
Downloaded: 181 Time(s)

Post 25 Aug 2012, 20:21
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.