Anyone managed to permanently disable Advanced Power Management in WD10JPVX?

I don’t have access to a suitable WD drive at the moment, so I can’t help with testing.

I believe all AF drives still use 512-byte sectoring in the System Area.

As for the checksum, in the following example …

52 4F 59 4C 01 00 30 00 32 00 20 00 FF 9B BF DA

… you would compute the sum as …

0x4C594F52 + 0x00300001 + 0x00200032 + 0xDABF9BFF + …

BTW, the only way that I know to determine the size of a module is to begin with a sector count of 1 and read its first sector. Then change the sector count to reflect the size of the module, and read the entire module.

Thanks Franc, that’s what I did actually. Read the first sector, grab the sector count from Byte number 11 (if we start from 0x00 then it is 0xA, i.e. 2 bytes before the first checksum byte), then read the whole mod by multiplying it with 512.

Currently it is able to :

  1. Read the whole Mod 0x32 and save it into a file.

  2. Set offsets 0x84 - EOF to 00

  3. Clear the checksum in order to calculate the total of each 32 bits value.

  4. Recalculate the checksum and store it in offsets 0xC-0xF

  5. Save the modified Mod 32 into a new file.

*** Since my drive is good, both original and new files’ md5sum are identical ***

  1. Read the new file, determine its length and number of sectors (filesize divide by 512 - a bit lazy to code to read it from Byte 11) into memory buffer and write from memory back to a third file (instead of writing to my hard disk)

*** Validated that the third file’s md5sum is identical with the first two ***

I think we are almost there. Let me think carefully if I want to lose my 160GB if things go unexpectedly :slight_smile: Or perhaps generate some non-0 values in 0x84-EOF, write to the hard disk, retrieve and see if my program gets to fix them.

I believe all AF drives still use 512-byte sectoring in the System Area.

Thanks for this one too.

Think I’m done coding for Mod 32h. Now for Mod 02.

I’ve read http://malthus.zapto.org/viewtopic.php?f=86&t=848 and it was mentioned that it’s Mod 02 Record 1A Offset 2, but in the example you gave earlier, it was Record 1B Offset 2. Which is correct?

Also, my code will zero fill anything from 0x84 onwards. If this is incorrect, I need you to tell me where to start.

Thanks Franc.

Please give me some time to get my head around MOD 32 (and MOD 02).

Just today I received some feedback from someone who is using a professional tool. There are some differences between what the tool does and what the thread at the HDD Oracle is suggesting. I have also been offered a broken WD drive for testing.

MOD 32 cleared

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 AC 6B FD E5 ROYL............
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000........
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030 A4 00 00 00 98 01 00 00 88 1A 00 00 C4 20 00 00
00000040 00 27 00 00 78 33 00 00 F0 3F 00 00 B9 05 00 00
00000050 76 00 B9 05 00 00 00 00 00 00 00 00 00 00 00 00
00000060 00 00 00 00 00 00 00 00 72 29 AC 74 3D B4 9B 74
00000070 78 29 03 00 05 00 00 00 B9 05 00 00 93 18 13 01
00000080 D0 CC AE 75 00 00 00 00 00 00 00 00 00 00 00 00
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000A0 00 00 00 00




MOD 32 with bad sectors.

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 FF 9B BF DA ROYL............
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000........
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030 A4 00 00 00 98 01 00 00 88 1A 00 00 C4 20 00 00
00000040 00 27 00 00 78 33 00 00 F0 3F 00 00 BA 04 00 00
00000050 76 00 B9 05 00 00 00 00 5D 03 FF 00 5E 02 00 00
00000060 5E 02 00 00 00 00 00 00 60 85 B1 74 C8 09 9D 74
00000070 F8 28 03 00 03 00 00 00 B9 05 00 00 D8 7E 22 01
00000080 A0 88 BF 75 00 00 02 47 65 00 63 00 00 00 00 00
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000A0 00 00 00 00

No worries, take your time.

Some output from my good drives. Now the challenge is to determine values before 0x84 that were changed and not zeroed.

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 A6 32 EF E5 ROYL .0.2. . 2  
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000 1.....
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 A4 00 00 00 98 01 00 00 88 1A 00 00 C4 20 00 00 ... .. .. ..
00000040 00 27 00 00 78 33 00 00 F0 3F 00 00 B9 05 00 00 .'..x3.. ?.. ..
00000050 76 00 B9 05 00 00 00 00 00 00 00 00 00 00 00 00 v. ............
00000060 00 00 00 00 00 00 00 00 FE F3 09 75 FD 11 F1 74 ........ u t
00000070 05 A4 03 00 02 00 00 00 B9 05 00 00 CB B4 95 00 . ... .. .
00000080 C8 C6 86 75 u

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 5F 21 30 29 ROYL .0.2. ._!0)
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000 1.....
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 A4 00 00 00 C0 00 00 00 08 1A 00 00 5C 20 00 00 ... ... ..\ ..
00000040 B0 26 00 00 54 33 00 00 F8 3F 00 00 B9 05 00 00 &..T3.. ?.. ..
00000050 0A 00 B9 05 00 00 00 00 00 00 00 00 00 00 00 00 . ............
00000060 00 00 00 00 00 00 00 00 CB C5 94 09 0B 0D 92 09 ........        
00000070 85 E4 01 00 00 80 00 00 B9 05 00 00 87 7A 0F 00 .. .. .. z .
00000080 92 87 A1 09

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 3C 00 DA CD AE C2 ROYL .0.2.<.    
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000 1.....
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 A4 00 00 00 20 01 00 00 A8 30 00 00 8C 3C 00 00 ... .. 0.. <..
00000040 70 48 00 00 34 60 00 00 F8 77 00 00 E1 0B 00 00 pH..4`.. w.. ..
00000050 3B 00 E1 0B 00 00 00 00 00 00 00 00 00 00 00 00 ;. ............
00000060 00 00 00 00 00 00 00 00 B6 1D AB 07 98 AF 9A 3A ........ :
00000070 06 B2 03 00 00 00 00 00 E1 0B 00 00 15 9F 05 00 ..... .. .
00000080 3F A8 C7 3A ? :

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 52 4F 59 4C 01 00 30 00 32 00 20 00 94 24 0C D8 ROYL .0.2. . $  
00000010 30 30 31 37 30 30 30 30 08 14 31 00 00 00 00 00 00170000 1.....
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 A4 00 00 00 F8 00 00 00 28 1A 00 00 74 20 00 00 ... ...( ..t ..
00000040 C0 26 00 00 58 33 00 00 F0 3F 00 00 F9 02 00 00 &..X3.. ?.. ..
00000050 26 00 F9 02 00 00 00 00 00 00 00 00 00 00 00 00 &. ............
00000060 00 00 00 00 00 00 00 00 E9 E5 7B 25 15 EC 74 25 ........ {% t%
00000070 86 BD 02 00 00 00 00 00 F9 02 00 00 C7 DF 2A 00 ..... .. *.
00000080 DC CB 9F 25 %

(4Ch and 4Dh) could be copied from (52h and 53h) or (78h and 79h)

The “section” number for MOD 02 is 1B, not 1A. Initially I couldn’t decide whether the numbers should begin with 0 or 1, but I eventually settled on the latter.

Rather than “contaminating” this thread, I’ll post my findings in respect of MOD 32 to the HDD Oracle “WD slow issue” thread. That way I’ll be sure to attract the attention of interested parties who may be able to help fill in the blanks and correct any errors.

This is what I have managed to come up with:

Offset 0x58 = number of entries in relo-list
0x5A = number of reallocated sectors
0x5C = number of pending sectors
0x4C = number of remaining spare sectors (= total spares - reallocated sectors)
0x52 = 0x78 = total available spares = max entries in relo-list
0x68, 0x6C, 0x80 = somehow related to drive capacity ?
0x30, 0x34, 0x38, 0x3C, 0x40, 0x44, 0x48 = locations of data sections
0x50 = number of entries (words) in first data section ?

I’ve just been informed by a user that the latest demo/trial version of WDMarvel has a solution for the “slow issue”, so it may be that I’ve wasted your time. :frowning: I’ll still post my findings in regard to MOD 32, though. That said, I know that there are times when one needs to rewrite various MODs, so your code could still be useful in the future. All I would need to do would be to adapt the MOD ID. In fact I suspect that there may be numerous common data recovery cases that could be solved with freeware tools and some inside knowledge.

No worries Franc. It’s good to write some real program, though I needed Christophe’s code as reference since I’m not a programmer and we’re talking about a very low level access to the hard disk. I might be able to modify this further to dump out all the mods but I see very little value in doing so since there are already tools capable of doing this.

I’ll update the code to include the calculations given in those offsets in the next few days.

0x68, 0x6C, 0x80 = somehow related to drive capacity ?

Looks like it. Can’t tell why the After value is smaller than the Before value.

0x68-6B should be related to bytes per sector. I checked a few of the AF drives and they have a very small value. If I multiply the 32bit by 8, I get a value very close to the non-AF drives.

WD5000LPVX : B6 1D AB 07 * 8 = B0 ED 58 3D, very close to the value of the non-AF drive.

B0 ED 58 3D = 1029238192. Multiply by 512 and we get 526 969 954 304 (~500GB)

0x6C and 0x80 does not need to x8.

Looks like 58h59h = 5Ah5Bh + 5Ch5Dh

Yes, I think so, too.

What’s annoying is that there are obviously many people doing the same kind of “research”, but few, if any, are willing to share. If this information was out there, then we would have numerous freeware tools that would empower DIY-ers.

I guess it’s only a matter of time before more people hop in and publish their findings. The research you’ve done and shared so far has helped a lot.

It just came to my mind that the larger-than-actual-capacity values in 0x68, 0x6C, 0x80 could be due to each sector’s overhead (GAP, Sync, Addy Mark headers and ECC). See http://www.seagate.com/tech-insights/advanced-format-4k-sector-hard-drives-master-ti/. There’s also some books written about this. I’m also making a wild guess that these larger 32 bit values before the defects were cleared represent the total space used (default allocated sectors + spare sectors). So when more spares are used, the larger it becomes.

I’ve been trying to port my APM prog to DOS/Win32 the last few days. Managed to get an EXE file but the IOCTL portion failed to function - apparently a recode is required. Otherwise we can have a Win32/DOS open source to dump the mods :slight_smile: I got the source from hdparm 6.9 and managed to compile into EXE and run it. hdparm 9.x (and probably versions after 6.9) uses sgio (sg = SCSI Generic) - this probably explains why no one made any Win32 versions after that.

Update : The sgio.c looks very similar to scsiata.cpp from the smartmontools project. Let me see if I can utilize scsiata.cpp to port this to Windows or the sg3_utils

I’ve been analysing MOD 32 on and off. I’m having difficulty finding consistency between my various examples. It seems as if each example has some aspect that differs from the others.

Did you manage to get your “slow fix” code working? Apparently WDMarvel does “deal with slow responding”, but not in the demo version. Instead one would need to purchase a one-month licence (US$9).

I’ve also been examining the relevant section of MOD 02 (0x1B). It appears to consist of several time constants or timeout values. I suspect that one or more of these determine the amount of time that the drive allows for dealing with retries.

BTW, if you need to access the HDD Oracle forum, it is now at http://www.alexsoft.org. Some psychopath has been attacking the web site, presumably because it champions freedom of information for DIY-ers. It seems that our work has struck a nerve.

Oh you just reminded me that malthus.zapto.org was down for quite a while. Didn’t know it was DoSed.

I haven’t really spend more time on it since you said that WDMarvel does it for free. Instead I spent quite some time trying to port it to Windows/DOS and gave up. I thought it’d be more useful to port it to Windows instead of reinventing the wheel.

Now that you said that it doesn’t do it for free, sure I can resume my coding. I think I can probably leave those unknown sections as it is since your existing MHDD script does not touch them and it does fix the problem.

There is an SG3_utils that compiles on Mingw32 and runs on Windows but the sg3raw does not seem to be able to capture the part of the response from the drive that we need.

Incidentally, I got a 320gb drive today with 57 pending sectors, but I itchily zerofilled part of it, leaving me with 12 pending sectors when I thought of dumping out the mods. Hope it’s good enough for us to determine how are the remaining 3x32bit sections calculated. I can repeat the process and stop once the pending sectors reduce and do more dumps.

Comparing Mod32h of a good identical model.

58h Good : 00

58h Pending 12 : 0D

5Ch Good : 00

5Ch Pending 12 : 0C

60h Good : 00

60h Pending 12 : 0C

68h Good : E9E57B25

68h Pending 12 : 577B7E25

6Ch Good : 15EC7425

6Ch Pending 12 : 32F27325

70h Good : 86

70h Pending 12 : F9

74h Good : 00

74h Pending 12 : 01

7Ch Good : C7DF2A

7Ch Pending 12 : 64FB26

80h Good : DCCB9F25

80h Pending 12 : 96ED9A25

So it appears that, at least for a drive with pending sectors, it has a larger 68h value but smaller 6Ch and 80h values compared to a good drive.

I repeated my zerofill and the current pending sectors count went down from 12 to 3 by the time I stopped it.

Between 00h and 83h, apart from the 32 bit checksum, only 3 bytes changed, 58h, 5Ch, and 60h, and they all changed to 0x03.

Update : Next zerofill brought the pending sectors count to 0.

Between 00h and 83h, apart from the 32 bit checksum, only 3 bytes changed, 58h, 5Ch, and 60h, and they all changed to 0x00.

I’m unsure how much does a Reallocated Sector impact 68h, 6Ch, and 7Ch. I just realized that despite being the same model, both 320gb were made 1 year apart, so I’m not surprised that these values are different. For sure, there are no changes in the 3 locations after the Pending Sectors were cleared with a zerofill on the same drive.

Coding is complete though it’s a bit messy. Need some time to clean up.

What it does :

  1. Save the original Mod 02 as a file.

  2. Patch Mod 02 Record 1B Offset 2 to 00. From what I see, the default value is 2.

  3. Save the original Mod 32h as a file.

  4. Fill Mod32h’s 54h-67h with 00. Fill Mod32h’s 84h onwards with 00. Recalculate Mod32h’s checksum.

  5. Write the modified Mod32h to the hard disk.

What it doesn’t do yet :

  1. Restore the original Mod 02 Record 1B Offset 2 from the backup file back into the hard disk.

  2. Restore the original Mod 32h from the backup file back into the hard disk.

  3. Modify 68h, 6Ch, and 7Ch.

Tested with a 160GB disk. Think if you have the resources to test out further for the world (after I clean the code)? :slight_smile:

Thanks very much for your continued indulgence. ISTM that it may be better to create two tools, one to modify MOD 02 (the “slow fix”) and a second to clear MOD 32 (the relo-list).

Furthermore, it now seems to me that offset 0x4C should be returned to its original value, namely the same value as at 0x5C. AFAICT, this represents the total number of available spares.

I have seen two results produced by professional tools. In one case there is no before-and-after difference in the values at offsets 0x68 - 0x8F whereas the second tool does have differences in this area. ISTM that it would be safest to leave these locations alone, at least until we can determine what they mean.

As for filling MOD 32 with zeros, I would begin at the offset pointed to by 0x30, not 0x84. That appears to be the beginning of the data area.