HPFSUtil v0.02 by Mike Ruskai This program is a consolidation of various test programs I put together while investigating the structure of HPFS, with the original purpose of discovering just how much space HPFS takes up for itself, and how that amount correlates with drive size. The program usage: Usage: hpfsutil.exe - letter of HPFS drive to process Options: /GD - report current dirty bit status /DT - toggle dirty bit /SD: - set dirty status to True or False /FS - compare actual and reported free space /SU - show HPFS system space usage /BS - show bad sector count /SHSU - display contents of SuperBlock /SHSP - display contents of SpareBlock /SHSPFD - display SpareBlock with full spare DirBlk list /DS:[-] - dump sector(s) to file /FN: - filename to dump sectors to; default sectdata.dat /NL - don't use IBM linedraw characters Argument order is unimportant. You may specify as many different options as you want on the same commandline. They will be executed in a set order (not the order you specify them). Duplicate options aren't permitted (including duplicate sector dumps - you'll have to run the program multiple times for multiple sector ranges). Also, the DT and SD options are mutually exclusive. Explanation of the options: GD - Get the current dirty status of the drive. This just checks bit 0 of the partition status byte (the 9th byte in the HPFS SpareBlock), and reports accordingly (1 = dirty; 0 = clean). *** DT - Toggle the dirty status of the drive. If it's dirty, it's set clean. If it's clean, it's set dirty. The program reports which action was taken. SD: - This sets the dirty status to True or False (/SD:T or /SD:F), regardless of what the current status is. If no errors are encountered, it reports the change. *** ** Note ** The above two options write directly to your drive. I am in no way responsible for any data loss you may have due to any problems coinciding with using this program with either of these options. Use them at your own peril. That said, they work fine here, and should work fine anywhere. But if bad information is given by OS/2 to the program, there's no guarantee that the correct sector is read and written back to disk. ** FS - This traverses all of the freespace bitmaps on the drive, tallying up free sectors, and compares the results with what DosQueryFSInfo() reports. The implementation of HPFS on Warp 4 (and possibly others) has a bug which reports 4096 fewer sectors free than are actually free, on drives from 120MB to 3GB (the range I tested). A 10MB drive had a discrepancy of 443 sectors. This space is free, but unreachable in OS/2. SU - Display an itemized list of the amount of space reserved by HPFS. This doesn't include any HPFS structures created for the purpose of allocating data files (FNodes, ALSECs, etc.). BS - Display the bad sector count, as reported by HPFS (time to replace the drive if any are found). SHSU - Output a formatted display of the HPFS SuperBlock sector. The offset field is in the format hex/decimal. The hex is logical (0-based), and the decimal is absolute (1-based). The size of the data can be determined by noting the length of the hex value. Each two hex digits indicate one byte of data. See further on in this file for detailed info on each item. SHSP - Output a formatted display of the HPFS SpareBlock sector. The format is the same as for the SuperBlock display. The addition of FD prompts a complete list of the spare DirBlk locations. By default, only the first is listed (the SpareBlock contains the entire list). See further on in this file for detailed info on each item. DS:-[] - Dump the sector or sector range to file (default sectdata.dat - see next option for how to change this). The value must be a decimal number from 0 to the number of sectors on the drive (exceeding the boundary will report an error). There are three macros that can be used in place of a decimal value: "boot", "super", and "spare" (without the quotes). These correspond to the locations of the BootBlock (LSN 0), SuperBlock (LSN 16), and SpareBlock (LSN 17), respectively. FN: - This specifies an alternate sector data filename (default is sectdata.dat). If the file can't be opened, an error will be reported. NL - This tells the program to not use IBM linedraw characters, in the event that your codepage makes those character values into something other than lines. They are replaced with standard ASCII characters. The HPFS SuperBlock: 64-bit SuperBlock signature - self explanatory. HPFS version - reports 2 for HPFS and HPFS386. Vol size (2:<=4GB; 3:>4GB) - indicates whether or not drive is larger than 4GB - a value of 2 means less than or equal to 4GB, while 3 means larger than 4GB. Root dir FNode location - self explanatory. Total sector count - total number of sectors on the drive, including those taken up by system structures. Bad sector count - actually *known* bad sector count, which should be 0, unless your drive is failing. Free space bitmap list - location of the list, which consists of consecutive 4-byte sector numbers, indicating the location of one four-sector bitmap each. The size of the list depends on the size of the drive - it's a minimum of four sectors, and increases four sectors at a time as needed to accomodate larger drives. Spare bitmap list - probably originally for accomodating larger drives that need more freespace bitmaps than four sectors could list, but is unused now, and always 0, since the main bitmap list is larger when necessary. Bad sector list - location of a four-sector list of bad sectors. Spare bad sector list - If you need more than four sectors to list the number of bad sectors, this would be used (and your drive would really be shot). Date CHKDSK /F last run - in the form of a 4-byte Unix timestamp. Date last optimized - presumably for application use, but GammaTech's optimizer doesn't use it. Dir band sector count - number of sectors in the directory band. Directory band start - location of first sector of directory band. Directory band end - location of last sector of directory band. Directory band bitmap - four sectors covering the allocation of the directory band. First ACL block location - location of eight-sector block of ACL's, which are only used by HPFS386. The HPFS SpareBlock: 64-bit SpareBlock signature - self explanatory. Partition status byte - a bitmask, with the following definitions: 0: Dirty flag 1: Spare DirBlk's used 2: Hotfix sectors used 3: Bad sectors exist 4: Bad bitmaps exist 5: Fast formatted 6: Unknown 7: Written by old IFS In each case, 1 means true, 0 means false. Hotfix list location - location of four-sector list of hotfix sector numbers. The first 400 bytes of the first sector are empty, and used to store the locations of any sectors which have been hotfixed (the position of the sector number says which hotfix sector contains the data). Hotfix sectors in use - the count of hotfix sectors in use. Total hotfix sectors - the total number of hotfix sectors, which is always 100 (which is why only 400 bytes in the list are reserved). Spare DirBlk count - the number of spare directory blocks there are, which exist in the event that space runs out while making directory adjustments. The default count is 20. Free spare DirBlk's - the number of spare DirBlks not in use. Code page list location - the sector address of the code page list, which contains the code page numbers, and some other info. The next sector contains the code pages themselves. Number of code pages - number of installed code pages, which is always 2. HPFS SuperBlock 32-bit CRC - cyclic redundancy check of the SuperBlock, which is used by HPFS386 to determine when the SuperBlock has been altered. HPFS SpareBlock 32-bit CRC - cyclic redundancy check of the SpareBlock, used by HPFS386 to determine when the SpareBlock has been altered. Spare DirBlk #1-#20 location - sector addresses of the 20 spare directory blocks. Each address is four sectors apart, since a directory block is four sectors long. Disclaimer: The author is in no way responsible for anything bad happening to you or your computer after you run this program. The /SD and /DT options are the only ones which directly write information to your drive (/DS uses the standard file system methods of writing), but for all I know, loading this program into memory may be the last straw that breaks your power supply's fuse, while you were in the middle of using Partition Magic on your sensitive data partition with no backup. Source: The source code to this program is included in the archive, in a separate archive entitled source.zip. This source may be freely modified and compiled, but credit where credit is due would be nice. Each C file should be compiled separately, and all the objects linked together. There are few source comments, but the code should be self-explanatory (since I don't use obscure variable names or bad structure, unlike a disconcerting number of programmers out there). Acknowledgements: Virtually all information about the structure of HPFS was obtained from the EDM/2 articles about HPFS by Dan Bridges. Additional info was provided by Jan Van Wijk, author of the DFSEE utility program. In addition, some of the OS/2-specific programming tasks were accomplished with the indirect help of various people on UseNet (by reading their posts from a Deja.com search), most notably Peter Fitzsimmons, who seems to have answered virtually every OS/2 programming question conceivable at one time or another. Known problems/limitations: There exists the possibility that a bad sector turn up where a freespace bitmap should be. I don't yet know how to deal with this situation properly, so if the bad bitmap bit is set in the partition status, the free space discrepancy option won't run. No check is currently done to see if there are any bad sectors in the range specified to dump to file. Either the read will succeed (meaning the bad sector either isn't bad, or only bad some of the time), or it'll fail, stopping the sector dump. Caveats: If you use the current drive for the sector data dump file, and you choose a sector range that includes free sectors, there's a decent chance that what you're reading will overlap what's being written to the dump file. This won't cause any errors, but it'll make the utility of the dump file rather specious. Questions/comments/bug reports: Send them all to thannymeister@yahoo.com, and I'll ignore them or act on them at my discretion. History: 11-22-1999 - Original release. 11-27-1999 - Changed sector read function to only read one sector at a time, since garbage would be returned if a track boundary is reached during a multiple-sector read. This slows things down a bit during the free space discrepancy scan. Changed checking of freespace bitmap data to increase performance, so much of the performance loss above is regained here. Changed loops in display routines to memset() calls, which speeds them up a bit. Fixed an error in the calculation of how many bitmap list sectors are required, which hopefully is what caused the problems people have been pointing out. Compile this time with VACPP 3.08's Compact optimization. Had Speed optimization bug pointed out by someone else, which no longer affects the program (the loops in the display functions were being incorrectly optimized, but have been removed). Other VACPP 3.08 users might want to look out for this type of error, which can be worked around by making the loop counter variable 'volatile'. This is version 0.02