add directory Minix

This commit is contained in:
gohigh
2024-02-19 00:21:39 -05:00
parent 56596ada90
commit 5a46ddb732
2923 changed files with 1764412 additions and 0 deletions

View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@@ -0,0 +1,197 @@
Table of Errors:
Most of these will prevent the hard disk from working correctly under DOS, so
it's not likely that you ever get these errors.
Invalid root sector signature
The last two bytes of the root sector should be 55 AA (hex).
This is a serious error and usually prevents the hard disk from being
accessible under DOS. You can use 'fdisk /mbr' after booting from a
floppy disk to write a correct root sector.
Calculation error
Oops, this is a bug in FIPS. The changed root sector is defective. Please
send a bug report to schaefer@rbg.informatik.th-darmstadt.de
Overlapping partitions
The partition table contains overlapping partitions. This is a serious
problem and should not happen.
Invalid jump instruction in boot sector
The first three bytes of the boot sector must be a 3-byte jump (E9 xx xx)
or a 2-byte jump (EB xx 90). Perhaps the partition is not yet formatted.
FIPS can only split DOS-formatted partitions.
Invalid boot sector
The last two bytes of the boot sector must be 55 AA (hex)
Can't handle number of bytes per sector
The number of bytes per sector must be 512
Number of sectors per cluster must be a power of 2
Only 1, 2, 4, 8, 16, 32, 64 or 128 are allowed
Partition must have 2 FATs
Every DOS partition has 2 copies of the FAT
Number of root directory entries must not be zero
Sounds reasonable, doesn't it?
Number of hidden sectors incorrect
The number of hidden sectors in the boot sector must match the number
of the start sector in the partition table
12-bit FAT not supported
FIPS can't split partitions with a 12-bit FAT
Number of sectors (short) must be zero
For partitions with more than 65536 sectors (BIGDOS) the number of sectors
(short) must be zero
Number of sectors (short) does not match partition info
The number of sectors in the partition table must match the number of
sectors in the boot sector
Number of sectors (long) does not match partition info
The number of sectors in the partition table must match the number of
sectors in the boot sector
Invalid drive number
Only the numbers 128 - 255 are valid drive numbers
Error reading FAT 1
Read error - bad sector
Error reading FAT 2
Read error - bad sector
FAT copies differ
The two copies of the FAT differ - use 'chkdsk /f' to correct this
New partition not empty
The New Partition is not empty. Apparently this is a bug in FIPS, since
the empty space of the partition has been determined before. Please
send a bug report to schaefer@rbg.informatik.th-darmstadt.de
Too many drives found
FIPS can handle up to 9 drives - that should be enough for most PCs :-)
No compatible hard disk found
Hey, where is your drive? Perhaps your hard disk is not int 13h compatible.
No valid partition found
All partitions in the partition table are empty
No free partition
All four partitions are in use
Error reading drive geometry
Interrupt 13h 08h returned an error code
Drive initialization failure
Interrupt 13h 00h returned an error code
Error reading root sector
Read error - bad sector, wrong drive number or incompatible harddrive
Can't split extended partitions
FIPS can not yet split extended DOS partitions
Unknown file system
Only DOS partitions can be split (system indicator byte must be 4 or 6)
Error reading boot sector
Read error - bad sector
Partition too small - can't split
If the partition has only slightly more than 4085 clusters, it can't be
split any further without rewriting the FAT to 12 bit.
Last cylinder is not free
Since the new partition is created at the end of the old one and
contains at least one cylinder, the partition can not be split if
not at least the very last cylinder is completely free.
Probably there is a hidden file like 'image.idx' or 'mirorsav.fil'
in the last cylinder - see the doc.
Error writing root sector
Write error - perhaps the disk is write protected?
Error writing boot sector
Write error :-( - this will hopefully never happen ...
Too many save files on disk
There can only be ten save files on one floppy disk (rootboot.000 to
rootboot.009). Delete some or use another floppy disk.
Can't open file
FIPS tried to write the file rootboot.00? to drive A: but an error occured
Try using another floppy disk
Error writing file
FIPS tried to write the file rootboot.00? to drive A: but an error occured
Try using another floppy disk
Error closing file
FIPS tried to write the file rootboot.00? to drive A: but an error occured
Try using another floppy disk
Warnings:
These will not cause FIPS to exit, since they are not really errors. If you
have the possibility to correct the problem, do it; if not, this will not
affect DOS, so you should be safe.
More than one active partition
More than one partition is marked 'active' in the partition table.
There are some boot programs that do not complain about more than one
active partition - they will just use the first one. If you have such
a program in your root sector and the PC boots normally, you may ignore
this message. Otherwise use fdisk to correct the error.
Invalid active flag
The 'active' flag of a partition should be either 80h or 0.
By modifying the active flag and the boot program it is theoretically
possible to boot from the second harddrive. If you happen to have such
a configuration, ignore this message. Otherwise you can delete the flag
now.
Partition table inconsistency
FIPS has detected that the 'physical' start or end sector (head/cylinder/
sector) do not match with the 'logical' start/end sector. This is not
an error since the 'physical' values are redundant and not used anyway.
There are many configurations where the values differ. This message is
meant only to inform you that FIPS has adapted the 'physical' values
according to the current drive geometry. So don't be alarmed by an unex-
pected cylinder range.
Invalid partition entry
The partition entry contains data, but the system indicator is 0 (empty).
Attention: FIPS will possibly overwrite this entry. Make sure this is no
valid Partition (temporarily disabled etc.)
No active partition
No partition in the partition table is marked active. Normally you will
not be able to boot from this disk. Use fdisk to correct that.
Partition does not end on cylinder boundary
All partitions should end on a cylinder boundary
Partition does not begin on cylinder boundary
Normally, all partitions except the first one should begin on head 0,
sector 1 of a cylinder. This is not required by DOS, however.
Free space between partitions
There is free space on the harddisk that is not covered by a partition
Number of reserved sectors should be 1
The boot sector uses only 1 sector, so the number of reserved sector
is usually 1. If you can access your drive, do not attempt to change this.
Number of root directory entries must be multiple of 16
One sector of the root directory contains 16 entries. An invalid number
of root directory entries is accepted by DOS but causes problems.
Wrong media descriptor byte in boot sector
The media descriptor byte should be F8h for a harddisk, but other values
like FCh are accepted by DOS (perhaps used for removable media ?).
FAT too large
Since the number of sectors per FAT is a 2 byte number, it is theoretically
possible to have up to 65535 sectors per FAT. A number of FAT sectors
greater than 256 is accepted by DOS, but not useful, since the largest
possible FAT has 2 bytes * 64K entries = 128K = 256 * 512 bytes. If you can
access the drive, do not attempt to change this.
FAT too small
If the number of clusters in the partition is larger than there are entries
in the FAT, DOS uses only part of the partition. Something has gone *very*
wrong with this partition, but all is not lost - reduce the partition to a
size that can be properly managed.
Sectors per track incorrect
The number of sectors per track in the boot sector does not match the actual
drive geometry reported by the BIOS
Number of drive heads incorrect
The number of drive heads in the boot sector does not match the actual
drive geometry reported by the BIOS
Wrong system indicator byte
For BIGDOS Partitions the System Indicator Byte should be 6; for DOS16
Partitions it should be 4
Wrong signature
Partitions with 32-bit sector numbers (since DOS 4.0+) have an 'extended
Bios Parameter Block' in the boot sector, its signature byte is 29h. This
is however totally ignored by DOS.
Drive number in boot sector does not match actual drive number
The drive number in the boot sector does not match the drive number by which
the drive is accessed
Wrong media descriptor byte in FAT
The first byte of each FAT is the Media Descriptor - it should be F8h
for a hard disk, but other values like FCh are accepted by DOS (perhaps
used for removable media ?).
Wrong FAT entries 1 & 2
A 16-bit FAT should start with F8 FF FF FF
Can't open debug file
The debug file is created in the current directory - make sure it is
writable

View File

@@ -0,0 +1,523 @@
Welcome to FIPS
The First nondestructive Interactive Partition Splitting program
Version 1.5
august 22, 1995
Copyright 1993-95 by Arno Schaefer
0. What you need to use FIPS
1. Introduction
2. What FIPS does
3. Safety
4. Restrictions
5. Before you start
6. Use with a multitasking OS
7. Using FIPS
8. After splitting the partition
9. Commandline Switches
10. Troubleshooting
11. Credits
In file SPECIAL.DOC:
S1. Use with Stacker/SuperStor/Doublespace etc.
S2. Use with OS/2
S3. Use with OnTrack Disk Manager and similar drivers
FIPS is a program designed to split an existing DOS partition without deleting
the data on it.
FIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
FIPS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FIPS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
0. What you need to use FIPS
You need a defragmentation program in order to move all data to the beginning
of the hard disk. FIPS will only split your partition if you have enough free
space at the end. DOS 6.0 and later contains DEFRAG, which is suitable for
this purpose. Other suitable programs are Norton Speedisk (actually DEFRAG
is speedisk with less functions, licensed from Norton), PCTools' Compress,
DISKOPT in Novell DOS 7, or the shareware programs ORG, DOG or SAFPAK
(available by anonymous FTP from any SimTel mirror in the diskutil directory).
I did not test these however, so don't blame me if they don't work for you.
You may also want to use a program like Norton Disk Doctor (or 'scandisk'
in DOS 6.2) to check your harddisk before and after using FIPS.
FIPS was developed under DOS 5.0. It should work fine with anything above
3.0, perhaps even with 2.0. However it will not be of much use with older
DOS versions, since the large partition sizes are only available since DOS 4.
It has been reported to work with DOS 6.0 and 6.2 and Novell DOS 7. I have
also received reports about successful use with Windows95 partitions. Note
that the long filenames are no problem for FIPS, because it works on a
lower level where directory structure is of no concern. It is probably
sensible to boot from a DOS disk before using FIPS in such a setup (see 6.)
1. Introduction
The program was inspired by the Linux Project. When installing Linux on a
PC that was used for DOS / Windows, many people want to retain a smaller
partition for their DOS software. However, since most Harddisks contain
only one large partition, you would normally be required to do a complete
backup, erase the partition and build two (or more) new partitions. Then you
would restore the backup to one of the new partitions. On today's systems
with hard disk capacities of usually 500MB or more, a complete backup becomes
practically infeasible without large media like streamer tapes once the
drive has filled up to some considerable fraction. Even though many people
backup their most valuable date (a practice which I would highly recommend
in any case), the process of reinstalling all the software packages takes
many hours or even days.
FIPS was written to remedy this problem. You can now split a partition
without losing any data, provided there is enough free space for the new
partition at the end of the old one.
2. What FIPS does
FIPS reduces the size of a partition by changing some values in the
partition table and boot sector. It does not change the formatting of
the partition, especially not the cluster size and the size of the file
allocation table (FAT). Therefore the reduced partition will have a FAT
that is in part unused, but this is not a problem for DOS.
From the free space that is won by this, FIPS creates a new _primary_ DOS
partition.
If you want to use the new partition under a different OS (e.g. Linux), use
its supplied fdisk program to make any necessary changes (refer to the OS
manuals).
If you want to use the new partition under DOS/Windows, you can use it as
it is (after formatting!), but be aware of the following:
According to the official references, DOS can only have one primary
partition. All DOS versions (at least from v5.0 on) will happily work with
multiple primary partitions, but this is an 'undocumented feature'. If
you want to follow the official rules, you can delete the new partition with
fdisk and create an extended partition in its place.
There are reasons for having multiple primary partitions, among them the
possibility to boot from different partitions by changing the active par-
tition with fdisk.
Known problems with multiple primary partitions are:
- If you accidentally delete one primary partition with fdisk, you can not
easily recreate it, since fdisk will refuse to. There may be other fdisk
programs around that work, and if all else fails you can boot from a
Linux boot disk to run Linux' fdisk, but it is always a hassle.
- There exist some software packages that work with the partition table and
which may be confused by multiple primary partitions. Among them was SFS,
the 'Secure file system' by Peter Gutmann. I think Peter has made a change
to his program to accept some unusual configuration, but there may exist
other software packages that will have problems.
3. Safety
FIPS was specifically designed to provide a maximum of safety. On startup
it checks the Partition Table, Boot Sector and FAT for any inconsistencies.
If it finds anything suspicious, it will tell you so. If there are errors,
FIPS will not proceed.
You have the possibility to write backup copies of your root and boot sector
to a floppy disk before proceeding. If something goes wrong, you may restore
these with the program 'restorrb.exe' (see section 5). I strongly recommend
making use of this feature. It will also enable you to reverse the partition
split afterwards, so it might be a good idea to save the root/boot sector
image in a safe place.
FIPS checks for free space on the partition and will let you choose the
new start cylinder accordingly.
After having calculated the new partition table and boot sector, FIPS will
check everything again, so that possible bugs in the calculation may be
detected. Only if everything is ok, FIPS will ask for permission to write
the new root and boot sector.
4. Restrictions
FIPS will only work with Hard Disk BIOSes that use interrupt 13h for low
level harddisk access. This is true for almost all PCs. I have received
a report that an older Adaptec SCSI controller had a software driver
that worked on a higher level. In this case you can only hope to get a
new driver from Adaptec. This is no problem any more for all newer
Adaptecs (I personally use one).
FIPS will only work on disks with a sector size of 512 bytes.
It seems that DOS is prepared to deal with different sector sizes, but
so far I have never seen this.
FIPS will not split partitions with 12 bit FATs (you would not want to split
partitions with less than 10 MB, would you?).
FIPS will only split DOS partitions. Partition pable and boot sector must
conform to the MSDOS 3.0+ conventions. This is marked by the system
indicator byte in the partition table, it must have the value 4 (16 bit
sector number) or 6 (32 bit sector number).
It will especially *not* split Linux partitions.
FIPS does not yet work on extended DOS partitions. Support for these has
been planned for a long time, but I can't say when it will come.
FIPS will not work if you already have four partitions, since it needs one
free partition entry.
FIPS will not reduce the original partition to a size with less than 4085
clusters, because this would imply rewriting the 16 bit FAT to a 12 bit FAT.
5. Before you start
Run CHKDSK or (under DOS 6.2) SCANDISK on the partition you want to split.
If you have Norton Disk Doctor or something similar, you may use it alter-
natively. Make sure there remain no 'dead' clusters on the disk.
Prepare a bootable floppy disk in drive A:. Under DOS this is usually done
by giving the command 'sys a:' or 'format a:/s'. Under Windows NT or OS/2
this may be different, if in doubt check your manual or boot from a boot
disk from a DOS PC.
Copy the FIPS files RESTORRB.EXE, FIPS.EXE and ERRORS.TXT to this disk.
Test booting from the prepared floppy disk. Read you manual or ask a local
guru if you can't boot from floppy disk or if you can not access your hard
disk after booting (test this by giving the command 'dir c:', you should
see your hard disk's root directory). If all else fails, try using FIPS
after booting normally from the hard disk (a bit more risky, but sometimes
the last resort).
When you start FIPS (later!), you will be given the opportunity to write
backup copies of your root and boot sector to a file on drive A: called
ROOTBOOT.00x (where x stands for a digit from 0 to 9). If anything goes wrong
while using FIPS, you can restore the original configuration by booting from
the floppy and running RESTORRB. Please note: if you use FIPS more than once
(this is normally not necessary, but it may happen), more than one ROOTBOOT
file is written to the floppy disk. RESTORRB lets you choose which configu-
ration file to restore. The file RESTORRB.000 contains your original confi-
guration. Try not to confuse the versions.
You will need this backup file (ROOTBOOT.00x) if you want to undo the
partition split later.
But before starting FIPS you _must_ now defragment your Harddisk. All of the
space that will be used for the new partition must be free. Be aware that the
Windows Swapfile will not be moved by most defragmentation programs. You must
uninstall it (in the 386enhanced part of the Windows Control Panel) and rein-
stall it after using FIPS.
If you use IMAGE or MIRROR, the last sector of the hard disk contains a
hidden system file with a pointer to your mirror files. You _must_ delete this
file before using FIPS (it will be recreated the next time you run mirror).
Do 'attrib -r -s -h image.idx' or 'attrib -r -s -h mirorsav.fil' in the root
directory, then delete the file.
If FIPS does not offer as much disk space for creation of the new partition
as you would expect it to have, this may mean that
a. You still have too much data in the remaining partition. Consider making
the new partition smaller or deleting some of the data.
b. There are hidden files in the space of the new partition that have not
been moved by the defragmentation program. You can find the hidden files
on the disk by typeing the command 'dir /a:h /s' (and 'dir /a:s /s' for
the system files). Make sure to which program they belong. If a file is
a swap file of some program (e.g. NDOS) it is possible that it can be
safely deleted (and will be recreated automatically later when the need
arises). See your manual for details.
If the file belongs to some sort of copy protection, you must uninstall
the program to which it belongs and reinstall it after repartitioning.
I can't give you more aid in this - if you really can't figure out what
to do, contact me directly.
Attention! Do _not_ try to move DOS' hidden system files (ibmbio.com &
ibmdos.com or something similar). You may end up with a hard disk that
will not boot any more. Since these files are already in the first sectors
of the partition, it is not necessary to move them. In DOS 5.0 and later,
at least one of the system files _may_ be moved, but it is nevertheless a
good idea to leave it alone.
When you have run FIPS, you must reboot, so make sure to disable any
programs in the config.sys and autoexec.bat that write to the disk, in
particular mirror or image. Consider temporarily renaming these files.
Be aware that the location of your DOS partitions in the partition table may
change after using FIPS. If you use the new partition under DOS _and_ you
have an extended partition and/or two drives, this means that the names of
the partitions may change (e.g. D: may become E:). I have taken care that C:
always remains C:, so that you will still be able to boot.
Also if you have a CD-ROM, it will in most cases change its drive letter.
If you use the /L switch to explicitly specify the drive letter in the call
to MSCDEX in the autoexec.bat file, you might have to change it accordingly.
If you don't use the /L switch, MSCDEX will automatically choose the first
free letter, so that you do not need to change anything.
Apropos drive letters: DOS uses the following order to assign them:
1. The first primary partition on each drive
2. The volumes inside the extended partitions on all drives
3. The remaining primary partitions on all drives
Example:
C: first primary partition on first HD
D: first primary partition on second HD
E: first volume in extended partition on first HD
F: second volume in extended partition on first HD
G: first volume in extended partition on second HD
H: second primary partition on second HD
I: CD ROM
I am not aware of an easy way to change this scheme. In particular you
can not assign an arbitrary drive letter to a partition. You can however
influence the ordering by changing a primary partition into an extended one.
For Linux users:
The possible change of the location of the DOS paritition in the partition
table also means that the device number of the DOS partition under Linux may
change (e.g. /dev/hda3 may become /dev/hda1). Any existing Linux partitions
will not change, so that you will have no trouble booting. You just need to
edit your /etc/fstab file if you mount your DOS partition on bootup.
6. Use with a multitasking OS
You should not use FIPS in multitasking environments like OS/2, Desqview,
Windows, Novell Task Manager or the Linux DOS Emulator. These systems might
still write to the disk after FIPS has changed the hard disk structure,
which may result in corrupting the disk. This is not necessarily so, I'd
suppose that in most cases it would work nevertheless. But since safety is my
first concern with FIPS, I would recommend booting from a DOS boot disk and
then running FIPS, that should be safe.
In version 1.0 I added some code by Dave McCaldon to detect Windows and
Desqview (thanks, Dave!). OS/2 and Novell Task Manager are not yet detected.
I had to remove the code for detecting the Linux DOS emulator because it
caused a hangup on many machines.
7. Using FIPS
If you have prepared a bootable floppy disk as described in section 5,
boot from it now.
Important! Make sure not to have a disk cache program like Smartdrive
running. It has been reported that in some cases the changes FIPS made
were only written to the disk in part, which resulted in hard disk
corruption later. I think this may be caused by the use of Smartdrive,
which in the default configuration delays the disk writes for some seconds.
If you reboot too fast, some of the changes may be lost.
You start FIPS by typing FIPS at the DOS prompt, followed by <ENTER>.
You may exit from the program at any time by pressing <CTRL-C>.
FIPS will first try to detect under which OS it is running. If it is
Windows or Desqview, it will complain and tell you to boot from a floppy
disk. You can proceed nevertheless, but this is at your own risk (see
section 8).
Then FIPS will detect your hard disks, if you have more than one, it will
ask you which one you want to work on.
In previous releases, FIPS failed to detect the correct number of hard disks
with some BIOSes (esp. in Gateway Pentium machines). I hope to have corrected
this. If FIPS fails to detect the correct number of disks, please let me
know. In the meantime you may use the '-n' switch to select the drive
by hand (see below).
FIPS then reads the root sector of the hard disk and displays the partition
table.
Example:
| | Start | | End | Start |Number of|
Part.|bootable|Head Cyl. Sector|System|Head Cyl. Sector| Sector |Sectors | MB
-----+--------+----------------+------+----------------+--------+---------+----
1 | yes | 0 148 1| 83h| 15 295 63| 149184| 149184| 72
2 | no | 1 0 1| 06h| 15 139 63| 63| 141057| 68
3 | no | 0 140 1| 06h| 15 147 63| 141120| 8064| 3
4 | no | 0 0 0| 00h| 0 0 0| 0| 0| 0
If you don't know what to make of this, don't worry too much. You may just use
the number of Megabytes to identify your partitions.
The root sector is then checked for errors.
If you have more than one partition on the disk, you will be asked which one
you want to split.
The boot sector of the chosen partition is read and some information is dis-
played.
Example:
Bytes per sector: 512
Sectors per cluster: 8
Reserved sectors: 1
Number of FATs: 2
Number of rootdirectory entries: 512
Number of sectors (short): 0
Media descriptor byte: f8h
Sectors per FAT: 145
Sectors per track: 63
Drive heads: 16
Hidden sectors: 63
Number of sectors (long): 141057
Physical drive number: 80h
Signature: 29h
FIPS checks if this information is consistent with the partition table and
tries to detect other errors.
It then verifies if the two copies of the FAT are identical, if they are not,
FIPS will exit with an error message.
If everything checks out ok, FIPS now looks for free space at the end of
the partition. The new partition must have at least one cylinder, so if
the last cylinder is not free, you have no chance of splitting the
partition: FIPS will exit with an error message. Probably you forgot
to remove a mirror or image file (see above).
You must now enter on which cylinder the new partition should start.
Use the cursor keys right/left to increase or decrease the cylinder
count. The size of the remaining partition and the new partition are
displayed in the process, so you will have no trouble choosing the
right cylinder. With cursor up/down you can change the count in steps
of 10. When ready, press enter to continue.
FIPS will check again if the space for the new partition is empty -
this is an additional security measure and should never show an error,
since the free space was already determined before.
After this, FIPS will calculate the changes to the root sector, check the
changes and display the new partition table. You may now choose to reedit the
partition table (this will return you to the point where you select the par-
tition) or to continue. If you type 'c', FIPS will calculate the changed
boot sector, check it again and prompt you if you want to proceed. If you type
'y' then, FIPS will write the changes to the disk and exit.
8. After splitting the partition
Make sure that the changes have been written to the disk. If you used
a disk cache like Smartdrive (despite my explicit recommendation not
to use it :-), wait for some seconds so that the cache is flushed to disk.
Your new partition will be recognized by DOS after you rebooted. DO NOT
WRITE ANYTHING TO THE DISK BEFORE REBOOTING. After rebooting, use CHKDSK
or Norton Disk Doctor to make sure your old (now smaller) partition is ok.
There have been cases where the changes made by FIPS were not correctly
written. To make sure that this is not the case, run FIPS again with the
-t (test mode) switch after rebooting. Select the drive and partition that
you were splitting. If FIPS displays no error until the cylinder selection
dialogue, there is no problem and you can stop the program with CTRL-C.
Otherwise you should undo the changes with 'restorrb' and contact me by
email.
If you don't find any errors, you may now reboot with your normal config.sys
and autoexec.bat. Start some programs and make sure you can still read your
data.
If you want to use your new partition under DOS, you must format it. If you
have multiple partitions, make sure to format the right one, the drive names
may have changed!
If you want to use the partition under Linux, you may now change the system
indicator byte with Linux' fdisk, then use MKFS.
If you want to split the new partition again in two smaller ones, you must
first format it under DOS, otherwise FIPS will complain.
9. Commandline Switches
Here is the explanation of FIPS' commandline switches. If you prefer the DOS
style, you may use '/' instead of '-' as the switch character. The switches
may be arbitrarily combined. Type 'FIPS -help' to get a list of the switches.
Here is a more detailed explanation:
-t or -test : test mode (no writes to disk)
This doesn't need much explanation.
-d or -debug : debug mode
In this mode, a complete transcript of your session along with some additio-
nal information is written to the file FIPSINFO.DBG in the current directory.
You can send this file to me in case of trouble (see below).
-h or -help or -? : help page
A short summary of the switches
-n<num> : select drive <num>
Preselect the drive number with this switch. Valid numbers are 128 to 255.
This may also be used to override the automatic drive detection - if for any
reason the drive is not found by FIPS, you may try this switch.
10. Troubleshooting
FIPS is still somewhat experimental, although it has been used by many
people successfully and without serious problems.
When in doubt I usually decided to stay safe and display error messages
when encountering suspicious configurations. Some of the minor errors may
be overridden.
Please make sure you have read this doc carefully and also look in the file
FIPS.FAQ that covers some frequently asked questions.
If you can't resolve a problem yourself, or have a configuration not sup-
ported by FIPS, or if you suspect a bug in FIPS, make a transcript of your
session using the -d switch and send the full FIPSINFO.DBG file along with a
short comment to schaefer@rbg.informatik.th-darmstadt.de. Possibly your
problem has already been solved.
11. Credits
FIPS is based on the procedure described by Drew Eckhardt in Linux digest132.
Most of what I know about Harddisk structures comes from the excellent german
book 'Scheibenkleister II' by Claus Brod and Anton Stepper. It is for the
Atari ST, but much of it applies to PCs also.
Information on the Harddisk Interrupts was drawn from Ralf Brown's Interrupt
List. Thanks to Hamish Coleman for some useful info and to Paul Smith for
his good suggestions. Gunnar Hilmarsson suggested the procedure for stacked
drives, and Miguel Alvarez helped me improve the partition ordering. Chetan
Patil, Rand Phares and Eric Jung pointed me at bugs in the program and
documentation. Stefan Andreasen provided important informations about OS/2.
Keith Crews suggested some additions to the documentation concerning the
preparation of the boot disk and new features of DOS 6.x. Dave McCaldon
wrote the code for detecting the OS FIPS is running under. Scott Ellentuch
and Billy Patton provided info about OnTrack Disk Manager.
A very valuable piece of info on EIDE drives and address translation is the
Linux EIDE-Mini-HOWTO by Patrick LoPresti.
Thanks to all others who sent me feedback and suggestions. FIPS would not be
the same program without the innumerable emails I received.
Arno Schaefer
schaefer@rbg.informatik.th-darmstadt.de

Binary file not shown.

View File

@@ -0,0 +1,368 @@
FIPS Frequently Asked Questions
-------------------------------
Here are some questions that people asked me by email. This file may
help you with some common problems. Please read it carefully before sending
mail. If you want to know what FIPS is all about, read the file README.1ST.
There are answers to the following questions:
Q01. Since you can split partitions with FIPS, it should also be possible
to merge partitions, right?
Q02. Can I reverse the changes that FIPS made to my harddisk?
Q03. What if I did not keep the root and boot sector? Can I still undo the
partition split?
Q04. I heard that the cluster size depends on the partition size and that
space usage is better with a small cluster size. Can I use FIPS to
decrease the cluster size of my hard disk?
Q05. I want to split a large partition into three or four smaller ones.
Can I use FIPS multiple times?
Q06. FIPS creates a second primary DOS partition by default. Is this allowed?
Q07. What does the message "Info: Partition table inconsistency" mean?
Q08. FIPS displays an error message and refuses to work. What should I do?
Q09. FIPS does not recognize my SCSI disk.
Q10. FIPS finds a partition with partition type 56h.
Q11. FIPS seems to work fine, and DOS sees the new partition, but Linux
fdisk sees only one partition.
Q12. Does FIPS work with Windows 95?
------------------------------------------------------------------------------
Q01. Since you can split partitions with FIPS, it should also be possible
to merge partitions, right?
A01.a
-----
NOT IN GENERAL. I don't want to go into technical details, just so much:
Every DOS formatted partition has a file allocation table (FAT) that holds
entries for every cluster of the partition. Usually one FAT is not large
enough to hold the information for both partitions, so that partitions can
not be easily joined. It is feasible, but I'm probably not going to incor-
porate this into FIPS.
So far I have heard of two software packages that claim to expand partitions.
One is a free program called "Partition Resizer" (look for a file called
presz???.zip on you favorite BBS or FTP server), the other is a commercial
product called PartitionMagic by Powerquest. I did not try these yet.
A01.b
-----
YES, if you split the partitions with FIPS before. As you may expect,
the problem with the FAT does not exist in that case, since it was origi-
nally formatted large enough. In fact the only thing required is resto-
ring the original root and boot sector (it does not matter how the data
on the partition changed in the meantime). This can be done with the
program 'restorrb' which comes with FIPS. Please consider the following:
- You must have the original image of the root and boot sector. For this
you _must_ save them to a floppy disk when FIPS offers that.
- You must not format the first partition in the meantime (because then
a new FAT is generated which is probably too small).
- The data on the second partition (the one that was generated by FIPS)
is lost, of course. The data on the first partition is preserved.
---------
Q02. Can I reverse the changes that FIPS made to my harddisk?
A02.
----
Yes, see answer A01.b. Make sure that you keep the original root and boot
sectors that you can save to floppy disk with FIPS.
---------
Q03. What if I did not keep the root and boot sector? Can I still undo the
partition split?
A03.
----
Difficult. For the moment, your only option is to read the file TECHINFO.TXT
to learn about the hard disk structures, recalculate the old partition
and format info by hand and use a disk editor the change them. You must
roughly proceed as follows (I will call the partition that was split off
of the original partition the 'second' partition, the remaining part of
the original partition the 'first' one):
1. Make sure there is no important data left on the second partition,
since it will be deleted. Make copies of all root and boot sectors
(on floppy disk!) in case you make a mistake. Also make sure that
you have a bootable DOS floppy with the disk editor on it. Backup
your data!
2. Choose 'edit physical drive' and 'edit partition table' in the disk
editor menu (assuming that your disk editor supports this).
3. Examine the table to make sure which two partitions you want to merge.
4. Take end head, cylinder, sector from the second partition and enter the
values in the corresponding fields of the first partition.
5. Add the number of sectors of the first partition to the number of sectors
of the second and enter the new value in the number of sectors field
of the first partition.
6. Delete the entry for the second partition completely (overwrite with
zeroes).
7. Look for the boot sector of the first partition and enter the new no.
of sectors in the no. of sectors field in the boot sector.
Please make sure you know what you are doing. I can't take any responsibi-
lity if you mess up your hard disk. Read the TECHINFO.TXT file carefully.
---------
Q04. I heard that the cluster size depends on the partition size and that
space usage is better with a small cluster size. Can I use FIPS to
decrease the cluster size of my hard disk?
A04.
----
In the partition that you split off of the original partition, the cluster
size is automatically adapted to the new size when you format it. In the
original partition, you can not change the cluster size without reformat-
ting and thereby deleting all data.
If your new partition is big enough, you might copy the data to the new
partition and format the old one, but be aware of two things:
1. You will not be able to reverse the partition split afterwards (see A1.a).
2. Newer format programs check to see if the partition has already been
formatted and in this case will preserve the format (to make data re-
covery easier in case the formatting was a mistake). You might have
to trick the format program into thinking that the partition is new.
Possibly the /u switch will do this (I have no possibility to check
this, please let me know if it works), but if not, you might have to use
a disk editor and overwrite the boot sector of the partition with zeroes
to invalidate it.
Note: I received a report that even overwriting the boot sector was not
enough. I can only imagine that there was still information in the
BIOS tables about the old format - I suggest to reboot after overwriting
the boot sector to clear all tables. Sometimes the DOS tools are just
too intelligent :-(
If you experience problems here, drop me a line.
The usual cluster size of a partition is roughly as follows:
0 - 32MB 512 Bytes
32 - 64MB 1024 Bytes
64 - 128MB 2048 Bytes
128 - 256MB 4096 Bytes
256 - 512MB 8192 Bytes
512 -1024MB 16384 Bytes
---------
Q05. I want to split a large partition into three or four smaller ones.
Can I use FIPS multiple times?
A05.
----
Yes. You must format the newly created partitions between successive uses
of FIPS. Regarding the cluster size, consider the following example:
- Suppose you want to split a 1GB hard disk into four partitions of
256K each.
- The original partition is formatted with a cluster size of 16KB.
- The first split is into 256KB / 768KB. The cluster size of the first
partition remains 16KB, although 4KB would be enough. It can only be
changed by reformatting, see A04.
- The new partition of 768KB is formatted, still with a cluster size of 16KB.
- The second split is made into 256KB / 256KB / 512KB.
- The third partition is formatted with a cluster size of 8KB.
- The third split is made into 256KB / 256KB / 256KB / 256KB.
- The fourth partition is formatted with a cluster size of 4KB.
- So now you have the cluster sizes 16K - 16K - 8K - 4K.
- Since the second and third partition are still empty, it is possible
to reformat them to a cluster size of 4K. See A04. for details on
reformatting.
---------
Q06. FIPS creates a second primary DOS partition by default. Is this allowed?
A06.
----
See the section 'What FIPS does' in FIPS.DOC for a discussion of this
issue.
---------
Q07. What does the message "Info: Partition table inconsistency" mean?
A07.
----
The partition table in the master boot record (root sector) consists of
four entries with several fields each. The strange thing about this table
is that some of the fields are redundant. Look here:
| | Start | | End | Start |Number of|
Part.|bootable|Head Cyl. Sector|System|Head Cyl. Sector| Sector |Sectors | MB
-----+--------+----------------+------+----------------+--------+---------+----
1 | yes | 0 148 1| 83h| 15 295 63| 149184| 149184| 72
2 | no | 1 0 1| 06h| 15 139 63| 63| 141057| 68
3 | no | 0 140 1| 06h| 15 147 63| 141120| 8064| 3
4 | no | 0 0 0| 00h| 0 0 0| 0| 0| 0
The start and end (head/cylinder/sector) values can be calculated from the
start sector and number of sectors (after inquiring the BIOS about the number
of heads and number of sectors per track), and in fact that's exactly what
DOS does. These field are completely unused by DOS (and every other OS that
I know of), so they could as well be set to all zeroes. It does however not
hurt to keep them in a consistent state.
When fdisk creates a partition table entry, it should enter the correct
values in these fields. Now how can there be an inconsistency? There are
at least two possibilities:
1. Some fdisk programs seem to write incorrect values, especially end
cylinders that are off by one or two.
2. You have an EIDE drive that uses address translation. Modern hard disks
usually have more than 1024 cylinders, but DOS does not allow for cylinder
numbers greater than 1024. This caused the hard disk controller manufacturers
to implement a trick: they decrease the number of cylinders and increase
the number of heads that DOS is told when asking for the drive geometry.
So DOS thinks it has a drive with e.g. 63 sectors, 32 heads and 1000
cylinders, whereas the correct values are 63 sectors, 16 heads, 2000
cylinders. Now if DOS asks for the first sector on cylinder 500, it
really gets the first sector on cylinder 1000. This trick is called
address translation.
Some newer EIDE drives allow the address translation to be switched
on and off in the BIOS. In some cases this is changed after the disk
is formatted. This means that the drive geometry that DOS gets when
querying the disk controller differs from the geometry that the drive
was formatted with and which is reflected in the partition table. This
is no problem for DOS, but it was a problem for FIPS until release 1.4.
In the current release, if FIPS detects this kind of problem, it will
adapt the partition table to the changed disk geometry.
The bottomline is that you need not worry about this message, it is
perfectly normal.
---------
Q08. FIPS displays an error message and refuses to work. What should I do?
A08.
----
Although this is already addressed in FIPS.DOC, I can not emphasize it
enough: If you send me email, please include the _DEBUG SCRIPT_ that you can
produce with the -d switch. If you don't, I will have to ask you for it,
and it will take longer to solve your problem.
---------
Q09. FIPS does not recognize my SCSI disk.
A09.
----
There exist older SCSI adapters (an Adaptec 1524 was reported to have that
'feature') that need a device driver that is loaded from the config.sys
before the disk can be accessed (i.e. the system must be booted from a
second hard disk or floppy). This device driver does not provide a 'BIOS
level' interface but a 'DOS level' interface to the hard disk (for the
technicians: it hooks into the DOS interrupt 21h instead of the BIOS inter-
rupt 13h). This means that the partition table can only be accessed via a
special fdisk program that knows about the adapters' internals. FIPS will
not work on these drives (and in fact even DOS' fdisk won't either).
Possibly there exists a newer driver for that adapter that will provide a
BIOS level interface - ask the manufacturer.
---------
Q10. FIPS only finds a partition with partition type 56h, no DOS partition.
A10.
----
You have OnTrack Disk Manager installed. Read the relevant section in
SPECIAL.DOC.
---------
Q11. FIPS seems to work fine, and DOS sees the new partition, but Linux
fdisk sees only one partition.
A11.
----
Somehow DOS loads a different partition table than the one in the master
boot record.
There are two possible causes:
1. You use a device driver like OnTrack Disk Manager. See the file
SPECIAL.DOC
2. You have a virus in the master boot record. This does not happen often,
but it is quite possible. Some viruses install themselves in the MBR and
copy the original MBR to some other place. When DOS tries to access the
partition table, the virus intercepts the BIOS call and returns the backup
copy, in order to hide from possible detection. Check this with a virus
scanner after booting from a clean DOS boot disk. You can remove a virus
from the MBR by using DOS fdisk with the /mbr option, but be aware that
in this case the 'backup' partition table is not restored. Thus the boot
sector will contain the new info as changed by FIPS, but the partition table
will contain the original (single partition) setup. This inconsistency
must be corrected (e.g. with a disk editor).
---------
Q12. Does FIPS work with Windows 95?
A12.
----
Yes. The file system of Windows 95 is the same as that of DOS. The only
difference are the long file names, but FIPS works on a level below the
directory level, so this is not a problem. Several people reported that
FIPS worked flawlessly on a Win 95 partition.

View File

@@ -0,0 +1,175 @@
Revision History of FIPS
------------------------
Version 1.5 - august 22, 1995
- Moved some of the special topics (use with OS/2, OnTrack, Stacker) from
FIPS.DOC to SPECIAL.DOC
- Revised the doc, added some info and tips
- Changed -d<num> switch to -n<num>
Version 1.4 - january 18, 1995 (not publicly released)
- FIPS can now correct a number of errors and inconsistencies on-the-fly
- Support for drives with configurable address translation - this should
finally eliminiate the 'inconsistent partition table' error.
Version 1.3 - january 6, 1995 (not publicly released)
- Replaced override switches by questions in the program
- Some errors of the hard disk structure can now be corrected by FIPS,
especially wrong end cylinder/head/sector numbers in the partition
table
- Revised error messages, minor corrections in the doc
- Added information about the common problem of 'invalid start/end head'
or 'inconsistent/corrupt partition table' to the file FIPS.FAQ.
- Cylinder numbers above 1024 are now shown without the 1024 modulus in
the partition table
Version 1.2 - october 20, 1994
- Added information about OnTrack Disk Manager to the doc.
- Added file FIPS.FAQ that covers frequently asked questions.
Version 1.1.1 - october 13, 1994 (not publicly released)
- Added support for hard disks with > 1024 logical cylinders.
Version 1.1 - may 26, 1994
- Bugfix: Removed the code for detecting the Linux DOS Emulator because
it caused a hangup on some machines.
Version 1.0 - may 3, 1994
- Added code to detect the OS FIPS is running under (thanks to Dave
McCaldon). This is to make sure that FIPS is not run in a multitasking
OS. Does not yet detect OS/2 and Novell Task Manager.
- First official release. There have been few bug reports in the test phase
and only one serious problem (with OS/2 dual boot). It is addressed in
detail in the doc.
Version 0.9.3 beta - march 31, 1994 (not publicly released)
- Some minor corrections for compatibility with Borland C++ 4.0
- Bugfix: "FAT too small" error with some configurations corrected
Version 0.9.2 beta - march 25, 1994 (not publicly released)
- Documentation revised, information about use with OS/2 added, features
of DOS 6.x taken into account
- -quiet and -s switches removed
- Drive detection code changed, this hopefully solves the problem with
the 'Too many drives found' error
Version 0.9.1 beta - january 21, 1994 (not publicly released)
- Select the start cylinder for the new partition with the cursor keys
- Automatically check for free space even before prompting for the
new start sector
- A nasty bug in the partition reordering procedure that caused FIPS to
fail in some cases was removed
- Slight bug in class definition corrected
Version 0.9 beta - november 7, 1993
- Save files on floppy (root and boot sector) are not overwritten -
there may be up to ten save files on a disk.
- Verbose error messages are now displayed by default, -verbose switch
has been removed.
- A minor error resulting in a 'division by zero' error with some invalid
bootsectors has been corrected
Version 0.8 beta - july 23, 1993
- A minor correction to the documentation
- No changes in the program from version 0.3. This is the first beta re-
lease. It is intended to be available to a wider audience.
Version 0.3 alpha - june 8, 1993
- FIPS is now completely translated to C++ (for easier maintenance and
programming experience)
- Explanation of the calculation of the new starting cylinder improved
- FIPS was reported to work with Stacker and SuperStor
Version 0.2.2 alpha - may 26, 1993 (not publicly released)
- partition table reordering improved - non-dos partitions remain in their
slots
- all necessary header files now included (sorry about that, my compiler
does not complain about missing prototypes)
Version 0.2.1 alpha - may 5, 1993 (not publicly released)
- bugfix: minimal cylinder number for start of new partition now calculated
correctly on drives with 16 sectors per cluster
- some improvements/simplifications to the code
Version 0.2 alpha - april 27, 1993
- added commandline switches to override certain error messages and
use FIPS non-interactively
- test mode without writing added
- debug mode added (writes a session transcript + additional info to a file)
- more informative error messages
- display of verbose error messages may be selected
- error checking is now more 'dos-like' (more unusual configurations
accepted)
- possibility to reedit the partition table without restarting the program
- added the number of megabytes to the partition table display
- now works correctly with drives that only have one free partition
- now supports more than two harddisks on a PC
- some minor fixes
Version 0.1 alpha - april 12, 1993
- Initial Release

View File

@@ -0,0 +1,115 @@
This is FIPS v1.5
FIPS is a program for non-destructive splitting of harddisk partitions.
IMPORTANT:
Please _carefully_ read the file FIPS.DOC for instructions on the use of
FIPS. FIPS is _not_ self documenting. I urge you to read at least sections
2, 5, 7 and 8. In case of problems read 4, 9 and 10 and the file FIPS.FAQ.
Muto Toshihisa has been so kind as to translate the docs into japanese.
They are available in Japan from NIFTY-Serve as FPCUPRO LIB1 #463.
Japanese users will hopefully know what this means.
One frequent problem people encounter is that their defragmentation program
leaves unmovable sectors at the end of the partition. It is addressed in
detail in FIPS.DOC. Other frequently asked questions are answered in the
file FIPS.FAQ.
If you use OS/2, a disk driver like OnTrack Disk Manager or a disk com-
pressor like Stacker, please read the relevant sections in the file
SPECIAL.DOC.
The changes from previous version are listed in the file HISTORY.TXT.
The latest version is available from my FIPS WWW page at
http://www.student.informatik.th-darmstadt.de/~schaefer/fips.html
FIPS has been out for about two years by now. It has been used by many
people on the Internet successfully. No serious bugs have been reported.
Nevertheless one can never be sure one hundred percent. FIPS reads and writes
the essential harddisk sectors, so an undiscovered bug may still corrupt your
harddisk. Use at your own risk!
If you want to make sure not to lose any data, make a complete backup before
using it (in this case you at least save yourself the time needed for re-
storing if it works).
However, every effort has been made to provide a maximum of safety. When
there is anything suspicious with the hard disk, the program will typically
exit with an error message, even if DOS doesn't complain.
If an error occurs, an error message is displayed together with a short
explanation. If you don't know what to make of it, read FIPS.DOC and
FIPS.FAQ.
If you still can't resolve the problem, make a transcript of your session
using the -d switch and send it to me at schaefer@rbg.informatik.
th-darmstadt.de. I usually try to answer within two or three days. Please
understand that the support for FIPS takes a considerable amount of time,
so that it may happen that I put back some of the harder problems and then
forget about them. In this case it may help to send another mail.
If you want to know how FIPS works, read the file TECHINFO.TXT. If you have
additions or corrections to make, please let me know.
FIPS is free under the GNU GENERAL PUBLIC LICENSE (GPL). See the file COPYING.
You may freely redistribute FIPS under the condition that you include all of
the files listed below without changes. If you modify it, you must follow
the conditions of the GPL.
I hold the copyright of FIPS. If you want to use parts of the source code in
your programs, you may do so under the conditions of the GPL. Of course I
would like to hear about it. If you want to use the code in a program that
is not covered by the GPL (shareware or commercial), I will probably agree
also, but you must ask me first.
You should have received the following files in this archive:
CALCULAT.CPP - calculation of the new root-/bootsector
CHECK.CPP - checking of the root-/bootsector
CMDL_ARG.CPP - evaluation of commandline arguments
DISK_IO.CPP - low level disk io
FAT.CPP - some operations on the FAT
GLOBAL.CPP - global procedures
HDSTRUCT.CPP - harddisk specific code
FIPSSPEC.CPP - FIPS-specific adaption of harddisk classes
INPUT.CPP - User input
LOGDR_ST.CPP - operations on logical drive
MAIN.CPP - main()
SAVE.CPP - saving root- and bootsector
HOST_OS.CPP - OS detection
DISK_IO.H - low level disk io classes
FAT.H - FAT classes
GLOBAL.H - global definitions
HDSTRUCT.H - harddisk specific classes
FIPSSPEC.H - FIPS-specific adaption of harddisk classes
INPUT.H - user input prototypes
LOGDR_ST.H - logical drive classes
TYPES.H - global type definitions
HOST_OS.H - The class host_os
PRIMPART.H - class for primary partitions
GETOPT.C - Simple UNIX getopt clone for commandline parsing
GETOPT.H - prototypes etc. for for GETOPT.C
VERSION.H - FIPS version
RTYPES.H - type definitions for RESTORRB
RESTORRB.C - a program that restores root and boot sector
RVERSION.H - RESTORRB version
FIPS.EXE - the executable of FIPS
RESTORRB.EXE - the executable of RESTORRB
COPYING - the GNU general public license
README.1ST - this file
FIPS.DOC - the documentation of FIPS
SPECIAL.DOC - special topics: OS/2, Stacker, OnTrack Disk Manager
FIPS.FAQ - some frequently asked questions with answers
TECHINFO.TXT - technical info on FIPS
ERRORS.TXT - a brief explanation of FIPS' error messages
HISTORY.TXT - the revision history
If you lack any of these files, try to get the original archive. If you can't
find it, contact me.
Arno Schaefer
schaefer@rbg.informatik.th-darmstadt.de

View File

@@ -0,0 +1,8 @@
FIPS is a program to split an MS-DOS partition in two. If your hard disk
contains only one partition, for MS-DOS/Windows, you will have to split it
to run MINIX. First run scandisk to repair any errors in the file system.
Then run defrag to compact the partition. Then you can use fips to split
the partition.
Before starting, please read README.1st, FIPS.DOC, FIPS,FAQ, and SPECIAL.DOC.

Binary file not shown.

View File

@@ -0,0 +1,239 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module restorrb.c
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <dos.h>
#include <bios.h>
#include <alloc.h>
#include <conio.h>
#include <ctype.h>
#include "rtypes.h"
#include "rversion.h"
#define DISK_INT 0x13
#define RESET_DISK 0
#define WRITE_SECTOR 3
#define VERIFY_SECTOR 4
#define DISK1 0x80
/* ----------------------------------------------------------------------- */
/* Copyright notice and version number */
/* ----------------------------------------------------------------------- */
void notice (void)
{
printf ("\nFIPS version " FIPS_VERSION ", Copyright (C) 1993/94 Arno Schaefer\n");
printf ("Module RESTORRB.EXE - Please read the file README.1ST\n");
printf ("FIPS comes with ABSOLUTELY NO WARRANTY, see file COPYING for details\n");
printf ("This is free software, and you are welcome to redistribute it\n");
printf ("under certain conditions; again see file COPYING for details.\n\n");
}
/* ----------------------------------------------------------------------- */
/* Error Handling */
/* ----------------------------------------------------------------------- */
int getx (void)
{
int character = getch();
if (character == 3)
{
printf ("\n");
exit (0);
}
return (character);
}
void error (char *message)
{
fprintf (stderr,"\nError: %s!\n",message);
exit (-1);
}
/* ----------------------------------------------------------------------- */
/* BIOS calls */
/* ----------------------------------------------------------------------- */
int reset_drives (void)
{
union REGS regs;
regs.h.ah = RESET_DISK;
regs.h.dl = DISK1;
int86 (DISK_INT,&regs,&regs);
if (regs.x.cflag) return (-1);
return 0;
}
/* ----------------------------------------------------------------------- */
/* read / write sectors */
/* ----------------------------------------------------------------------- */
int verify_sector (int drive_number,dword head,dword cylinder,dword sector,byte *buffer)
{
if (biosdisk (VERIFY_SECTOR,drive_number,head,cylinder,sector,1,buffer)) return (-1);
return 0;
}
int write_sector (int drive_number,dword head,dword cylinder,dword sector,byte *buffer)
{
int i;
boolean done=false;
for (i=0;i<3;i++)
{
if (!biosdisk (WRITE_SECTOR,drive_number,head,cylinder,sector,1,buffer))
{
done=true;
break;
}
reset_drives();
}
if (!done) return (-1);
return (verify_sector (drive_number,head,cylinder,sector,buffer));
}
int write_root_sector (int drive_number,byte *buffer)
{
return (write_sector (drive_number,0,0,1,buffer));
}
/* ----------------------------------------------------------------------- */
/* User Input */
/* ----------------------------------------------------------------------- */
void ask_for_write_permission (char *filename)
{
int character = 'x';
printf ("\nReady to write old root- and bootsector from file %s to disk\n", filename);
printf ("Do you want to proceed (y/n): ");
while ((character != 'y') && (character != 'n')) character = getx();
printf ("%c\n",character);
if (character == 'n') exit (0);
}
/* ----------------------------------------------------------------------- */
/* Main */
/* ----------------------------------------------------------------------- */
void main (void)
{
byte rootsector[512];
byte bootsector[512];
int drive_number,partition_number,i;
FILE *handle;
dword head,cylinder,sector;
char *filename = "a:\\rootboot.000";
int no_of_savefiles = 0;
char first = 'x';
char list[10];
notice();
if (reset_drives ()) error ("Drive Initialization Failure");
for (i='0';i<='9';i++)
{
filename[14] = i;
if (access (filename,0) == 0)
{
if (first == 'x') first = i;
list[no_of_savefiles++] = i;
printf ("Found save file %s\n",filename);
}
}
if (no_of_savefiles == 0) error ("No savefile ROOTBOOT.00? found on disk A:");
if (no_of_savefiles > 1)
{
printf ("\nWhich file do you want to restore (");
for (i = 0; i < no_of_savefiles; i++)
{
printf ("%c/", list[i]);
}
printf ("\b)? ");
while (true)
{
int c;
if (isdigit (c = getx()))
{
boolean found = false;
for (i = 0; i < no_of_savefiles; i++)
{
if (c == list[i]) found = true;
}
if (found)
{
printf ("%c\n", c);
filename[14] = c;
break;
}
}
}
}
else
{
filename[14] = first;
}
if ((handle = fopen (filename,"rb")) == NULL)
error ("Can't open file");
for (i=0;i<512;i++)
{
int character = fgetc (handle);
if (character == EOF) error ("Error reading file from disk");
*(rootsector + i) = character;
}
for (i=0;i<512;i++)
{
int character = fgetc (handle);
if (character == EOF) error ("Error reading file from disk");
*(bootsector + i) = character;
}
if ((drive_number = fgetc (handle)) == EOF) error ("Error reading file from disk");
if ((partition_number = fgetc (handle)) == EOF) error ("Error reading file from disk");
if (fclose (handle)) error ("Error closing file");
head = (dword) rootsector[0x1be+16*partition_number+1];
cylinder = (((dword) rootsector[0x1be+16*partition_number+2] << 2) & 0x300)
| (dword) rootsector[0x1be+16*partition_number+3];
sector = (dword) rootsector[0x1be+16*partition_number+2] & 0x3f;
ask_for_write_permission(filename);
if (write_root_sector (drive_number,rootsector))
error ("Error writing rootsector");
if (write_sector (drive_number,head,cylinder,sector,bootsector))
error ("Error writing bootsector");
}

View File

@@ -0,0 +1,79 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module types.h
RCS - Header:
$Header: c:/daten/c/fips/source/RCS/types.h%v 2.0 1993/04/28 03:32:20 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long dword;
typedef enum {false,true} boolean;
struct drive_geometry
{
dword heads;
dword cylinders;
dword sectors;
};
struct physical_sector
{
dword head;
dword cylinder;
dword sector;
};
struct partition_info
{
byte bootable; /* 80h or 0 */
byte start_head; /* location of first sector (bootsector) */
word start_cylinder;
byte start_sector;
byte system; /* 1 = 12-bit FAT, 4 = 16-bit FAT & 16-bit sector number */
/* 6 = 16-bit FAT & 32-bit sector number (BIGDOS) */
byte end_head; /* location of last sector */
word end_cylinder;
byte end_sector;
dword start_sector_abs; /* = start_cylinder * heads * sectors + start_head * sectors */
/* + start_sector - 1 */
dword no_of_sectors_abs; /* = end_cylinder * heads * sectors + end_head * sectors */
/* + end_sector - start_sector_abs */
};
struct bootsector_info
{
word bytes_per_sector; /* usually 512 */
byte sectors_per_cluster; /* may differ */
word reserved_sectors; /* usually 1 (bootsector) */
byte no_of_fats; /* usually 2 */
word no_of_rootdir_entries; /* usually 512 (?) */
word no_of_sectors; /* 0 on BIGDOS partitions */
byte media_descriptor; /* usually F8h */
word sectors_per_fat; /* depends on partition size */
word sectors_per_track; /* = sectors */
word drive_heads; /* = heads */
dword hidden_sectors; /* first sector of partition */
dword no_of_sectors_long; /* number of sectors on BIGDOS partitions */
byte phys_drive_no; /* 80h or 81h */
byte signature; /* usually 29h */
};

View File

@@ -0,0 +1 @@
#define FIPS_VERSION "1.5"

View File

@@ -0,0 +1,138 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module calculat.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/calculat.cpp 1.4 1995/01/19 00:00:49 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include "hdstruct.h"
#include "fipsspec.h"
/* ----------------------------------------------------------------------- */
/* Some calculations */
/* ----------------------------------------------------------------------- */
void fips_partition_table::calculate_new_root
(
dword new_start_cylinder,
partition *partition,
const drive_geometry &geometry
)
{
for (int i = 0; i < 3; i++) if (!partition_info[i].system)
// move DOS partitions to the beginning of the partition table
{
for (int j = i + 1; j < 4; j++) if
(
(partition_info[j].system == 1) ||
(partition_info[j].system == 4) ||
(partition_info[j].system == 6)
)
{
struct partition_info tmppart = partition_info[i];
partition_info[i] = partition_info[j];
partition_info[j] = tmppart;
if (partition->number == j) partition->number = i;
break;
}
}
int partition_no = partition->number;
partition->partition_info = &partition_info[partition_no];
for (i=0;i<4;i++) if (!partition_info[i].system) break;
// search for first empty slot
struct partition_info *newpart = &partition_info[i];
struct partition_info *oldpart = &partition_info[partition_no];
newpart->bootable = 0;
newpart->start_sector_abs =
new_start_cylinder *
geometry.heads *
geometry.sectors;
newpart->no_of_sectors_abs =
oldpart->start_sector_abs +
oldpart->no_of_sectors_abs -
newpart->start_sector_abs;
if
(
(newpart->no_of_sectors_abs > 0xffff) ||
(newpart->start_sector_abs > 0xffff)
)
{
newpart->system = 6;
}
else if
(
newpart->no_of_sectors_abs >= 20740
)
{
newpart->system = 4;
}
else
{
newpart->system = 1;
}
oldpart->no_of_sectors_abs =
newpart->start_sector_abs -
oldpart->start_sector_abs;
if
(
(oldpart->no_of_sectors_abs > 0xffff) ||
(oldpart->start_sector_abs > 0xffff)
)
{
oldpart->system = 6;
}
else
{
oldpart->system = 4;
}
correct_physical (geometry);
}
void fips_bpb::calculate_new_boot (const partition_info &partition_info)
{
if ((partition_info.no_of_sectors_abs > 0xffff) || (partition_info.start_sector_abs > 0xffff))
{
no_of_sectors = 0;
no_of_sectors_long = partition_info.no_of_sectors_abs;
}
else
{
no_of_sectors_long = 0;
no_of_sectors = partition_info.no_of_sectors_abs;
}
}

View File

@@ -0,0 +1,361 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module check.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/check.cpp 1.4 1995/01/19 00:20:41 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdlib.h>
#include "hdstruct.h"
#include "global.h"
#include "fipsspec.h"
#include "input.h"
/* ----------------------------------------------------------------------- */
/* Consistency check of root sector / partition table */
/* ----------------------------------------------------------------------- */
void fips_partition_table::correct_physical (const drive_geometry &geometry)
{
for (int i = 0; i < 4; i++)
{
if (partition_info[i].system)
{
physical_sector_no start
(
partition_info[i].start_sector_abs,
geometry
);
partition_info[i].start_cylinder = start.cylinder;
partition_info[i].start_head = start.head;
partition_info[i].start_sector = start.sector;
// recalculate 'physical' start sector
physical_sector_no end
(
partition_info[i].start_sector_abs
+ partition_info[i].no_of_sectors_abs
- 1,
geometry
);
partition_info[i].end_cylinder = end.cylinder;
partition_info[i].end_head = end.head;
partition_info[i].end_sector = end.sector;
// recalculate 'physical' end sector
}
}
}
void fips_harddrive::check (boolean final_check)
{
int i,j,k;
boolean bootable = false;
boolean do_correct = false;
byte *root_sector = harddrive::root_sector->data;
partition_info *parts = partition_table().partition_info;
int order[4] = {-1,-1,-1,-1};
printx ("\nChecking root sector ... ");
if ((root_sector[510] != 0x55) || (root_sector[511] != 0xaa))
error ("Invalid root sector signature: %02X %02X", root_sector[510], root_sector[511]);
for (i = 0; i < 4; i++)
{
if (parts[i].bootable == 0x80)
{
if (bootable)
{
warning (false, "More than one active partition");
printx ("Continue (y/n)? ");
if (ask_yes_no () == 'n') exit (-1);
}
else bootable = true;
}
else if (parts[i].bootable != 0)
{
warning (false, "Invalid active flag: partition %u: %02Xh",i+1,parts[i].bootable);
// must be 0 or 80h
printx ("Do you want to set the flag to zero (y/n)? ");
if (ask_yes_no () == 'y') parts[i].bootable = 0;
}
if (parts[i].system)
{
if ((parts[i].start_sector == 0) || (parts[i].start_sector > geometry.sectors))
{
if (final_check)
error ("Calculation error: Invalid start sector partition %u: %u", i + 1, parts[i].start_sector);
infomsg ("Partition table inconsistency");
do_correct = true;
}
if ((parts[i].end_sector == 0) || (parts[i].end_sector > geometry.sectors))
{
if (final_check)
error ("Calculation error: Invalid end sector partition %u: %u", i + 1, parts[i].end_sector);
if (!do_correct)
{
infomsg ("Partition table inconsistency");
do_correct = true;
}
}
if
(
(parts[i].start_head > (geometry.heads - 1)) ||
(parts[i].end_head > (geometry.heads - 1)) ||
(parts[i].start_sector_abs !=
(parts[i].start_cylinder * geometry.heads * geometry.sectors +
parts[i].start_head * geometry.sectors + parts[i].start_sector - 1)) ||
// physical start sector does not match logical start sector
((parts[i].start_sector_abs + parts[i].no_of_sectors_abs - 1) !=
(parts[i].end_cylinder * geometry.heads * geometry.sectors +
parts[i].end_head * geometry.sectors + parts[i].end_sector - 1))
// physical end sector does not match logical end sector
)
{
if (final_check)
error ("Calculation error: Inconsistent table entry for partition %u", i + 1);
if (!do_correct)
{
infomsg ("Partition table inconsistency");
do_correct = true;
}
}
for (j = 0; j < 4; j++) // insert partition in ordered table
{
if (order[j] == -1)
{
order[j] = i;
break;
}
else if (parts[i].start_sector_abs < parts[order[j]].start_sector_abs)
{
for (k=3;k>j;k--) order[k] = order[k-1];
order[j] = i;
break;
}
}
}
else // system = 0
{
for (j = 0; j < 16; j++)
{
if (root_sector[0x1be + 16 * i + j] != 0)
{
warning (false, "Invalid partition entry: partition %u", i+1);
printx ("Do you want to delete this entry (y/n)? ");
if (ask_yes_no () == 'y')
{
parts[i].bootable = 0;
parts[i].start_head = 0;
parts[i].start_cylinder = 0;
parts[i].start_sector = 0;
parts[i].end_head = 0;
parts[i].end_cylinder = 0;
parts[i].end_sector = 0;
parts[i].start_sector_abs = 0;
parts[i].no_of_sectors_abs = 0;
}
break;
}
}
}
}
if (do_correct)
{
pr_partition_table.correct_physical (geometry);
printx ("\nPartition table adapted to the current drive geometry:\n\n");
pr_partition_table.print();
}
if (!bootable && number == 0x80) warning (true, "No active partition");
for (i = 0; i < 4; i++)
{
if ((k = order[i]) != -1) // valid partition
{
if ((parts[k].end_sector != geometry.sectors) || (parts[k].end_head != (geometry.heads - 1)))
warning (true, "Partition does not end on cylinder boundary: partition %u", k + 1);
if (i != 0) if ((parts[k].start_sector != 1) || (parts[k].start_head != 0))
warning (true, "Partition does not begin on cylinder boundary: partition %u", k + 1);
if (i < 3) if ((j = order[i + 1]) != -1) // following valid partition
{
if ((parts[k].start_sector_abs + parts[k].no_of_sectors_abs) > parts[j].start_sector_abs)
error ("Overlapping partitions: %u and %u", k + 1, j + 1);
if ((parts[k].start_sector_abs + parts[k].no_of_sectors_abs) < parts[j].start_sector_abs)
warning (true, "Free space between partitions: %u and %u", k + 1, j + 1);
}
}
}
printx ("OK\n");
}
void fips_partition::check (void)
{
printx ("Checking boot sector ... ");
byte *boot_sector = partition::boot_sector->data;
if (boot_sector[0] == 0xeb)
{
if (boot_sector[2] != 0x90)
error ("Invalid jump instruction in boot sector: %02X %02X %02X", boot_sector[0], boot_sector[1], boot_sector[2]);
}
else if (boot_sector[0] != 0xe9)
error ("Invalid jump instruction in boot sector: %02X %02X %02X", boot_sector[0], boot_sector[1], boot_sector[2]);
if ((boot_sector[510] != 0x55) || (boot_sector[511] != 0xaa))
error ("Invalid boot sector: %02X %02X", boot_sector[510], boot_sector[511]);
if (bpb().bytes_per_sector != 512)
error ("Can't handle number of bytes per sector: %u",bpb().bytes_per_sector);
switch (bpb().sectors_per_cluster)
{
case 1:case 2:case 4:case 8:case 16:case 32:case 64:case 128: break;
default:
error ("Number of sectors per cluster must be a power of 2: actually it is %u",bpb().sectors_per_cluster);
}
if (bpb().reserved_sectors != 1)
{
warning (false, "Number of reserved sectors should be 1: actually it is %u",bpb().reserved_sectors);
if (ask_correction () == 'y') bpb().reserved_sectors = 1;
}
if (bpb().no_of_fats != 2)
error ("Partition must have 2 FATs: actually it has %u",bpb().no_of_fats);
if (bpb().no_of_rootdir_entries % 16)
{
warning (false, "Number of root directory entries must be multiple of 16: actually it is %u",bpb().no_of_rootdir_entries);
printx ("Do you want to set the number to the next multiple of 16 (y/n)? ");
if (ask_yes_no () == 'y')
bpb().no_of_rootdir_entries += (16 - bpb().no_of_rootdir_entries % 16);
}
if (bpb().no_of_rootdir_entries == 0)
error ("Number of root directory entries must not be zero");
if (bpb().media_descriptor != 0xf8)
{
warning (false, "Wrong media descriptor byte in boot sector: %02X",bpb().media_descriptor);
if (ask_correction () == 'y') bpb().media_descriptor = 0xf8;
}
if (bpb().sectors_per_fat > 256)
{
warning (false, "FAT too large: %u sectors",bpb().sectors_per_fat);
printx ("Continue (y/n)? ");
if (ask_yes_no () == 'n') exit (-1);
}
if (bpb().sectors_per_fat < (info().no_of_clusters + 1) / 256 + 1)
{
warning (false, "FAT too small: %u sectors (should be %u)",bpb().sectors_per_fat, (unsigned int) ((info().no_of_clusters + 1) / 256 + 1));
printx ("Continue (y/n)? ");
if (ask_yes_no () == 'n') exit (-1);
}
if (bpb().sectors_per_track != drive->geometry.sectors)
{
warning (false, "Sectors per track incorrect: %u instead of %u",bpb().sectors_per_track,(int) drive->geometry.sectors);
if (ask_correction () == 'y') bpb().sectors_per_track = drive->geometry.sectors;
}
if (bpb().drive_heads != drive->geometry.heads)
{
warning (false, "Number of drive heads incorrect: %u instead of %u",bpb().drive_heads,(int) drive->geometry.heads);
if (ask_correction () == 'y') bpb().drive_heads = drive->geometry.heads;
}
if (bpb().hidden_sectors != partition_info->start_sector_abs)
error ("Number of hidden sectors incorrect: %lu instead of %lu",bpb().hidden_sectors,partition_info->start_sector_abs);
if (info().no_of_clusters <= 4084)
error ("12-bit FAT not supported: number of clusters is %u",(int) info().no_of_clusters);
if (bpb().no_of_sectors)
{
if (partition_info->no_of_sectors_abs > 0xffff)
error ("Number of sectors (short) must be zero");
if (bpb().no_of_sectors != partition_info->no_of_sectors_abs)
error ("Number of sectors (short) does not match partition info:\n%u instead of %lu",bpb().no_of_sectors,partition_info->no_of_sectors_abs);
if (partition_info->system != 4)
{
warning (true, "Wrong system indicator byte: %u instead of 4",partition_info->system);
if (ask_correction () == 'y') partition_info->system = 4;
}
}
else
{
if (bpb().no_of_sectors_long != partition_info->no_of_sectors_abs)
error ("Number of sectors (long) does not match partition info:\n%lu instead of %lu",bpb().no_of_sectors_long,partition_info->no_of_sectors_abs);
if (bpb().signature != 0x29)
{
warning (false, "Wrong signature: %02Xh",bpb().signature);
if (ask_correction () == 'y') bpb().signature = 0x29;
}
if (partition_info->system != 6)
{
warning (true, "Wrong system indicator byte: %u instead of 6",partition_info->system);
if (ask_correction () == 'y') partition_info->system = 6;
}
}
printx ("OK\n");
}

View File

@@ -0,0 +1,138 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module cmdl_arg.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/cmdl_arg.cpp 1.4 1995/01/19 00:00:51 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "global.h"
#include "getopt.h"
/* ----------------------------------------------------------------------- */
/* Replacement for atoi */
/* ----------------------------------------------------------------------- */
static int atoint (char *string)
{
long int value = 0;
while (isdigit (*string))
{
value = value * 10 + (*string - '0');
if (value > 32767) return (-1);
string++;
}
if (*string != '\0') return (-1);
return (int) value;
}
/* ----------------------------------------------------------------------- */
/* Usage instructions */
/* ----------------------------------------------------------------------- */
static void usage (void)
{
printf ("\nFIPS [-t] [-d] [-h|-?] [-n<num>]:\n\n");
printf ("-t : test mode (no writes to disk)\n");
printf ("-d : debug mode\n");
printf ("-h/-? : this help page\n");
printf ("-n<num> : select drive <num> - valid values: 128 to 255\n");
}
/* ----------------------------------------------------------------------- */
/* Process commandline parameters */
/* ----------------------------------------------------------------------- */
void evaluate_argument_vector (int argc, char *argv[])
{
int c;
opterr = 0;
while ((c = getopt (argc, argv, ":htdn:")) >= 0)
{
switch (c)
{
case 't':
global.test_mode = true;
break;
case 'd':
global.debug_mode = true;
break;
case 'h':
usage ();
exit (1);
case 'n':
global.drive_number_cmdline = atoint (optarg);
if
(
global.drive_number_cmdline < 0x80
|| global.drive_number_cmdline > 0xff
)
{
fprintf
(
stderr,
"\nInvalid argument: %s\n",
optarg
);
usage ();
exit (-1);
}
break;
case ':':
fprintf
(
stderr,
"\nSwitch %c requires an argument\n",
optopt
);
usage ();
exit (-1);
case '?':
if (optopt != '?')
fprintf
(
stderr,
"\nInvalid Commandline Parameter: %s\n",
argv[optind - 1]
);
usage ();
exit (-1);
} /* switch */
} /* while */
}

View File

@@ -0,0 +1,267 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module disk_io.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/disk_io.cpp 1.4 1995/01/19 00:00:51 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include "disk_io.h"
#include <dos.h>
#include <bios.h>
#define DISK_INT 0x13
#define RESET_DISK 0
#define READ_SECTOR 2
#define WRITE_SECTOR 3
#define VERIFY_SECTOR 4
#define GET_DRIVE_PARAMS 8
#define GET_DISK_TYPE 0x15
/* ----------------------------------------------------------------------- */
/* Bios call to get the number of drives attached */
/* ----------------------------------------------------------------------- */
int get_no_of_drives (void)
{
union REGS regs;
regs.h.ah = GET_DRIVE_PARAMS;
regs.h.dl = 0x80;
int86 (DISK_INT, &regs, &regs);
if (regs.h.ah != 0) return (1); // will be checked again
return (regs.h.dl);
}
/* ----------------------------------------------------------------------- */
/* Calculates physical sector number (Head, Cylinder, Sector). */
/* Log_sector is absolute logical sector number (0 = master boot record). */
/* ----------------------------------------------------------------------- */
physical_sector_no::physical_sector_no
(
dword logical_sector,
const drive_geometry &geometry
)
{
cylinder =
logical_sector
/ (geometry.heads * geometry.sectors);
head =
(
logical_sector
- (cylinder * geometry.heads * geometry.sectors)
)
/ geometry.sectors;
sector =
logical_sector
- (cylinder * geometry.heads * geometry.sectors)
- (head * geometry.sectors)
+ 1;
}
/* ----------------------------------------------------------------------- */
/* Bios call get_drive_geometry, returns error status in var errorcode */
/* ----------------------------------------------------------------------- */
void physical_drive::get_geometry (void)
{
union REGS regs;
regs.h.ah = GET_DRIVE_PARAMS;
regs.h.dl = number;
int86 (DISK_INT, &regs, &regs);
if ((errorcode = regs.h.ah) != 0) return;
geometry.heads = (dword) regs.h.dh + 1;
geometry.sectors = (dword) regs.h.cl & 0x3f;
geometry.cylinders =
(
(dword) regs.h.ch
| (((dword) regs.h.cl << 2) & 0x300)
) + 1;
}
/* ----------------------------------------------------------------------- */
/* Bios call reset_drive, returns error status in var errorcode */
/* ----------------------------------------------------------------------- */
void physical_drive::reset (void)
{
union REGS regs;
regs.h.ah = RESET_DISK;
regs.h.dl = number;
int86 (DISK_INT, &regs, &regs);
errorcode = regs.h.ah;
}
/* ----------------------------------------------------------------------- */
/* Initialization physical_drive, requires drive number. */
/* Calls get_drive_geometry, errorcode contains return status */
/* ----------------------------------------------------------------------- */
physical_drive::physical_drive (int number)
{
physical_drive::number = number;
get_geometry ();
};
/* ----------------------------------------------------------------------- */
/* Initialization physical_drive with physical_drive object */
/* ----------------------------------------------------------------------- */
physical_drive::physical_drive (physical_drive &pd)
{
number = pd.number;
errorcode = pd.errorcode;
geometry = pd.geometry;
}
/* ----------------------------------------------------------------------- */
/* Assignment operator for physical drive */
/* ----------------------------------------------------------------------- */
void physical_drive::operator= (physical_drive &pd)
{
number = pd.number;
errorcode = pd.errorcode;
geometry = pd.geometry;
}
/* ----------------------------------------------------------------------- */
/* Read sector */
/* ----------------------------------------------------------------------- */
int physical_drive::read_sector (struct sector *sector, dword sector_number)
{
physical_sector_no p (sector_number, geometry);
boolean done = false;
for (int i=0; i<3; i++)
{
if (biosdisk
(
READ_SECTOR,
number,
p.head,
p.cylinder,
p.sector,
1,
sector->data
) == 0)
{
done=true;
break;
}
reset ();
}
if (!done) return (-1);
return 0;
}
/* ----------------------------------------------------------------------- */
/* Write sector with verify */
/* ----------------------------------------------------------------------- */
int physical_drive::write_sector (struct sector *sector, dword sector_number)
{
physical_sector_no p (sector_number,geometry);
boolean done = false;
for (int i=0; i<3; i++)
{
if (biosdisk
(
WRITE_SECTOR,
number,
p.head,
p.cylinder,
p.sector,
1,
sector->data
) == 0)
{
done=true;
break;
}
reset ();
}
if (!done) return (-1);
if (biosdisk
(
VERIFY_SECTOR,
number,
p.head,
p.cylinder,
p.sector,
1,
sector->data
) != 0) return (-1);
return 0;
}
/* ----------------------------------------------------------------------- */
/* Bios call get_disk_type - returns 0 if drive not present. */
/* Valid drive numbers: 0 - 255, result: 1 - floppy without disk change */
/* detection, 2 - floppy with disk change detection, 3 - harddisk */
/* ----------------------------------------------------------------------- */
int get_disk_type (int drive_number)
{
union REGS regs;
regs.h.ah = GET_DISK_TYPE;
regs.h.dl = drive_number;
int86 (DISK_INT, &regs, &regs);
if (regs.x.cflag) return 0;
return (regs.h.ah); // disk type
}

View File

@@ -0,0 +1,138 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module disk_io.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/disk_io.h 1.4 1995/01/19 00:01:25 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef DISK_IO_H
#define DISK_IO_H
#include "types.h"
/* ----------------------------------------------------------------------- */
/* Structure to hold information about the drive geometry */
/* ----------------------------------------------------------------------- */
struct drive_geometry
{
dword heads;
dword cylinders;
dword sectors;
};
/* ----------------------------------------------------------------------- */
/* Low level structure physical_drive, contains drive number and geometry, */
/* as well as low level sector read and write routines */
/* Geometry is determined on initialization, errorcode contains error */
/* number after call to get_geometry() and reset(). */
/* Initialization requires number (e.g. physical_drive drive1 (0x80);). */
/* */
/* Read and write are called max. 3 times in case of failure, return code */
/* contains 0 if successful. Sector CRC is verified after write. */
/* sector_number is absolute logical sector number (0 = master boot record)*/
/* ----------------------------------------------------------------------- */
class physical_drive
{
protected:
virtual void get_geometry (void);
public:
// constructors & operators
physical_drive (int number);
physical_drive (physical_drive &pd);
void operator= (physical_drive &pd);
// public data
int number;
int errorcode;
drive_geometry geometry;
// functions
virtual void reset (void);
int read_sector (struct sector* sector, dword sector_number);
int write_sector (struct sector* sector, dword sector_number);
};
/* ----------------------------------------------------------------------- */
/* Physical_sector_no holds and calculates physical sector number (Head, */
/* Cylinder, Sector). Number is calculated on initialization. Log_sector */
/* is absolute logical sector number (0 = master boot record). Usage: */
/* physical_sector_no mbr (0,geometry); */
/* physical_sector_no mbr (0,0,1); */
/* ----------------------------------------------------------------------- */
struct physical_sector_no
{
// public data
dword head;
dword cylinder;
dword sector;
// constructors
physical_sector_no (dword logical_sector, const drive_geometry &geometry);
physical_sector_no (dword head, dword cylinder, dword sector)
{
physical_sector_no::head = head;
physical_sector_no::cylinder = cylinder;
physical_sector_no::sector = sector;
}
};
/* ----------------------------------------------------------------------- */
/* Structure sector - contains only sector data */
/* ----------------------------------------------------------------------- */
struct sector
{
byte data[512];
};
/* ----------------------------------------------------------------------- */
/* Prototype for bios call get_disk_type - returns 0 if drive not present. */
/* Valid drive numbers: 0 - 255, result: 1 - floppy without disk change */
/* detection, 2 - floppy with disk change detection, 3 - harddisk */
/* ----------------------------------------------------------------------- */
int get_disk_type (int drive_number);
/* Bios call get_no_of_drives */
int get_no_of_drives (void);
#endif

View File

@@ -0,0 +1,161 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module fat.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/fat.cpp 1.4 1995/01/19 00:00:51 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdlib.h>
#include "logdr_st.h"
#include "global.h"
#include "fat.h"
#include "input.h"
fat::fat (class logical_drive *logical_drive,int number)
{
fat::logical_drive = logical_drive;
fat::number = number;
buffer = new sector;
start_sector = (number == 1) ? logical_drive->info().start_fat1 : logical_drive->info().start_fat2;
sector_in_buffer = -1;
}
dword fat16::next_cluster (dword cluster_number)
{
dword sector = cluster_number / 256;
int offset = (cluster_number % 256) * 2;
if (sector != sector_in_buffer)
{
read_sector (sector);
}
return ((dword) buffer->data[offset] | ((dword) buffer->data[offset + 1] << 8));
}
void fat::read_sector (dword sector)
{
if (logical_drive->read_sector (sector + start_sector,buffer))
if (number == 1)
error ("Error reading FAT 1");
else
error ("Error reading FAT 2");
sector_in_buffer = sector;
}
void fat16::check_against (class fat16 *fat2)
{
printx ("Checking FAT ... ");
for (int i=0;i<logical_drive->bpb().sectors_per_fat;i++)
{
read_sector (i);
fat2->read_sector (i);
for (int j=0;j<512;j++) if (buffer->data[j] != fat2->buffer->data[j])
error ("FAT copies differ: FAT 1 -> %02Xh, FAT 2 -> %02Xh in sector %u, byte %u",buffer->data[j],fat2->buffer->data[j],i,j);
if (i == 0)
{
if (buffer->data[0] != 0xf8)
{
warning (false, "Wrong media descriptor byte in FAT: %02Xh",buffer->data[0]);
printx ("Continue (y/n)? ");
if (ask_yes_no () == 'n') exit (-1);
}
if ((buffer->data[1] != 0xff) || (buffer->data[2] != 0xff) || (buffer->data[3] != 0xff))
warning (true, "Wrong FAT entries 1 & 2: %02X %02X %02X %02X",buffer->data[0],buffer->data[1],buffer->data[2],buffer->data[3]);
}
}
printx ("OK\n");
}
void fat16::check_empty (dword new_start_sector)
{
dword first_cluster = (new_start_sector - logical_drive->info().start_data) / logical_drive->bpb().sectors_per_cluster + 2;
dword last_cluster = logical_drive->info().no_of_clusters + 1;
if (last_cluster > ((dword) 256 * logical_drive->bpb().sectors_per_fat - 1)) last_cluster = (dword) 256 * logical_drive->bpb().sectors_per_fat - 1;
printx ("First Cluster: %lu\nLast Cluster: %lu\n\n",first_cluster,last_cluster);
printx ("Testing if empty ... ");
for (dword i=first_cluster;i <= last_cluster;i++)
{
dword fat_entry = next_cluster (i);
if (fat_entry != 0) if (fat_entry != 0xfff7)
{
if (fat_entry == 0xffff)
{
error ("New partition not empty: cluster %lu ( FAT entry: <EOF> )",i);
}
else
{
error ("New partition not empty: cluster %lu ( FAT entry: %lu )",i,fat_entry);
}
}
}
printx ("OK\n");
}
dword fat16::min_free_cluster (void)
{
dword first_cluster = 2;
dword last_cluster = logical_drive->info().no_of_clusters + 1;
if (last_cluster > ((dword) 256 * logical_drive->bpb().sectors_per_fat - 1)) last_cluster = (dword) 256 * logical_drive->bpb().sectors_per_fat - 1;
printx ("Searching for free space ... ");
dword i;
for (i=last_cluster;i >= first_cluster;i--)
{
dword fat_entry = next_cluster (i);
if (fat_entry != 0) if (fat_entry != 0xfff7)
{
i++;
break;
}
}
printx ("OK\n\n");
return (i);
}

View File

@@ -0,0 +1,65 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module fat.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/fat.h 1.4 1995/01/19 00:01:25 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef FAT_H
#define FAT_H
#include "types.h"
#include "disk_io.h"
#include "logdr_st.h"
class fat
{
protected:
logical_drive *logical_drive;
int number;
dword start_sector;
sector *buffer;
dword sector_in_buffer;
void read_sector (dword sector);
public:
virtual dword next_cluster (dword cluster_number) = 0;
fat (class logical_drive *logical_drive,int number);
~fat (void) { delete buffer; }
};
class fat16:public fat
{
public:
dword next_cluster (dword cluster_number);
void check_empty (dword new_start_cluster);
void check_against (class fat16 *fat2);
dword min_free_cluster (void);
fat16 (class logical_drive *logical_drive,int number):fat (logical_drive,number) {}
};
#endif

View File

@@ -0,0 +1,285 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module fipsspec.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/fipsspec.cpp 1.4 1995/01/19 00:00:53 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <dos.h>
#include "fipsspec.h"
#include "global.h"
#include "input.h"
#define FIRST_CHECK false
#define FINAL_CHECK true
#define DISK_INT 0x13
#define RESET_DISK 0
#define GET_DRIVE_PARAMS 8
void fips_bpb::print (void)
{
printx ("Bytes per sector: %u\n",bytes_per_sector);
printx ("Sectors per cluster: %u\n",sectors_per_cluster);
printx ("Reserved sectors: %u\n",reserved_sectors);
printx ("Number of FATs: %u\n",no_of_fats);
printx ("Number of rootdirectory entries: %u\n",no_of_rootdir_entries);
printx ("Number of sectors (short): %u\n",no_of_sectors);
printx ("Media descriptor byte: %02Xh\n",media_descriptor);
printx ("Sectors per FAT: %u\n",sectors_per_fat);
printx ("Sectors per track: %u\n",sectors_per_track);
printx ("Drive heads: %u\n",drive_heads);
printx ("Hidden sectors: %lu\n",hidden_sectors);
printx ("Number of sectors (long): %lu\n",no_of_sectors_long);
printx ("Physical drive number: %02Xh\n",phys_drive_no);
printx ("Signature: %02Xh\n\n",signature);
}
void fips_partition_table::print (void)
{
printx (" | | Start | | End | Start |Number of|\n");
printx ("Part.|bootable|Head Cyl. Sector|System|Head Cyl. Sector| Sector |Sectors | MB\n");
printx ("-----+--------+----------------+------+----------------+--------+---------+----\n");
for (int i=0;i<4;i++)
{
printx ("%u | %s |%4u %4u %4u| %02Xh|%4u %4u %4u|%8lu| %8lu|%4lu\n",i+1,
partition_info[i].bootable ? "yes" : " no",
partition_info[i].start_head,partition_info[i].start_cylinder,partition_info[i].start_sector,
partition_info[i].system,partition_info[i].end_head,partition_info[i].end_cylinder,partition_info[i].end_sector,
partition_info[i].start_sector_abs,partition_info[i].no_of_sectors_abs,partition_info[i].no_of_sectors_abs / 2048);
}
}
void fips_harddrive::get_geometry (void)
{
union REGS regs;
regs.h.ah = GET_DRIVE_PARAMS;
regs.h.dl = number;
int86 (DISK_INT,&regs,&regs);
if (global.debug_mode)
{
fprintf (global.debugfile,"\nRegisters after call to int 13h 08h (drive %02Xh):\n\n",number);
fprintf (global.debugfile," 00 sc/cl hd\n");
fprintf (global.debugfile,"al ah bl bh cl ch dl dh si di cflgs flags\n");
hexwrite ((byte *) &regs,16,global.debugfile);
}
if ((errorcode = regs.h.ah) != 0) return;
geometry.heads = (dword) regs.h.dh + 1;
geometry.sectors = (dword) regs.h.cl & 0x3f;
geometry.cylinders = ((dword) regs.h.ch | (((dword) regs.h.cl << 2) & 0x300)) + 1;
if (global.debug_mode)
{
fprintf (global.debugfile, "\nGeometry reported by BIOS:\n");
fprintf
(
global.debugfile,
"%ld cylinders, %ld heads, %ld sectors\n",
geometry.cylinders,
geometry.heads,
geometry.sectors
);
}
}
void fips_harddrive::reset (void)
{
union REGS regs;
regs.h.ah = RESET_DISK;
regs.h.dl = number;
int86 (DISK_INT,&regs,&regs);
if (global.debug_mode)
{
fprintf (global.debugfile,"\nRegisters after call to int 13h 00h (drive %02Xh):\n\n",number);
fprintf (global.debugfile,"al ah bl bh cl ch dl dh si di cflgs flags\n");
hexwrite ((byte *) &regs,16,global.debugfile);
}
errorcode = regs.h.ah;
}
void fips_logdrive_info::put_debug_info (void)
{
fprintf (global.debugfile,"Calculated Partition Characteristica:\n\n");
fprintf (global.debugfile,"Start of FAT 1: %lu\n",start_fat1);
fprintf (global.debugfile,"Start of FAT 2: %lu\n",start_fat2);
fprintf (global.debugfile,"Start of Rootdirectory: %lu\n",start_rootdir);
fprintf (global.debugfile,"Start of Data: %lu\n",start_data);
fprintf (global.debugfile,"Number of Clusters: %lu\n",no_of_clusters);
}
dword fips_partition::min_cylinder (fat16 fat, drive_geometry geometry)
{
dword new_part_min_sector =
info().start_data
+ (dword) 4085
* bpb().sectors_per_cluster;
dword new_part_min_cylinder =
(
new_part_min_sector
+ partition_info->start_sector_abs
- 1
)
/ (geometry.heads * geometry.sectors)
+ 1;
if (new_part_min_cylinder > partition_info->end_cylinder)
error ("Partition too small - can't split");
dword min_free_cluster = fat.min_free_cluster ();
dword min_free_sector =
info().start_data
+ (min_free_cluster - 2)
* (dword) bpb().sectors_per_cluster;
dword min_free_cylinder =
(
min_free_sector
+ partition_info->start_sector_abs
- 1
)
/ (geometry.heads * geometry.sectors)
+ 1;
if (min_free_cylinder > partition_info->end_cylinder)
error ("Last cylinder is not free");
if (new_part_min_cylinder < min_free_cylinder)
new_part_min_cylinder = min_free_cylinder;
return (new_part_min_cylinder);
}
boolean fips_partition::split (fips_harddrive hd)
{
if (read_boot_sector ())
error ("Error reading boot sector");
if (global.debug_mode)
{
fprintf
(
global.debugfile,
"\nBoot sector drive %02Xh, partition %u:\n\n",
hd.number,
number + 1
);
hexwrite
(
boot_sector->data,
512,
global.debugfile
);
}
get_bpb ();
printx ("\nBoot sector:\n\n");
print_bpb ();
get_info ();
if (global.debug_mode)
write_info_debugfile ();
check ();
fat16 fat1 (this,1);
fat16 fat2 (this,2);
fat1.check_against (&fat2);
dword new_part_min_cylinder =
min_cylinder (fat2, hd.geometry);
if (ask_if_save()) save_root_and_boot(&hd,this);
dword new_start_cylinder =
ask_for_new_start_cylinder
(
partition_info->start_cylinder,
new_part_min_cylinder,
partition_info->end_cylinder,
hd.geometry.heads * hd.geometry.sectors
);
fat2.check_empty
(
new_start_cylinder
* hd.geometry.heads
* hd.geometry.sectors
- partition_info->start_sector_abs
);
hd.calculate_new_root (new_start_cylinder, this);
hd.put_partition_table();
hd.get_partition_table();
printx ("\nNew partition table:\n\n");
hd.print_partition_table ();
hd.check (FINAL_CHECK);
if (ask_if_continue () == false)
{
return (false);
}
calculate_new_boot ();
put_bpb ();
get_bpb ();
printx ("\nNew boot sector:\n\n");
print_bpb ();
get_info ();
if (global.debug_mode)
write_info_debugfile ();
check();
if (!global.test_mode)
{
ask_for_write_permission ();
if (hd.write_root_sector ())
error ("Error writing root sector");
if (write_boot_sector ())
error ("Error writing boot sector");
printx ("Repartitioning complete\n");
}
return (true);
}

View File

@@ -0,0 +1,120 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module fipsspec.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/fipsspec.h 1.4 1995/01/19 00:01:26 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef FIPSSPEC_H
#define FIPSSPEC_H
#include "logdr_st.h"
#include "hdstruct.h"
#include "primpart.h"
#include "fat.h"
#include "disk_io.h"
class fips_bpb:public bios_parameter_block
{
public:
void print (void);
void calculate_new_boot (const partition_info &partition_info);
};
class fips_partition_table:public partition_table
{
public:
void print (void);
void calculate_new_root (dword new_start_cylinder,partition *partition,const drive_geometry &geometry);
void correct_physical (const drive_geometry &geometry);
int select (void);
};
class fips_harddrive:public harddrive
{
fips_partition_table pr_partition_table;
protected:
void get_geometry (void);
public:
void reset (void);
class partition_table &partition_table() { return pr_partition_table; }
void print_partition_table (void) { pr_partition_table.print(); }
void calculate_new_root (dword new_start_cylinder, partition *partition)
{
pr_partition_table.calculate_new_root (new_start_cylinder,partition,geometry);
}
void check (boolean final_check);
fips_harddrive (int number)
:harddrive (number)
{
get_geometry ();
// to write register info to debugfile
}
fips_harddrive (fips_harddrive &hd):harddrive (hd)
{
harddrive::operator= (hd);
// in constructor of base class virtual functions are not yet
// accessible => assign again so that partition_table() is
// copied correctly
}
void operator= (fips_harddrive &hd)
{
harddrive::operator= (hd);
}
};
class fips_logdrive_info:public logical_drive_info
{
public:
void put_debug_info (void);
};
class fips_partition:public partition
{
fips_bpb pr_bpb;
fips_logdrive_info pr_info;
public:
bios_parameter_block &bpb() { return pr_bpb; }
logical_drive_info &info() { return pr_info; }
void print_bpb (void) { pr_bpb.print(); }
void write_info_debugfile (void) { pr_info.put_debug_info(); }
void calculate_new_boot (void)
{
pr_bpb.calculate_new_boot (*partition_info);
}
void check (void);
fips_partition (class fips_harddrive *drive,int number):partition(drive,number) {}
dword min_cylinder (fat16 fat, drive_geometry geometry);
boolean split (fips_harddrive hd);
};
#endif

View File

@@ -0,0 +1,205 @@
/*
* $Header$
*
* Copyright (C) 1994 Arno Schaefer
*
* AU: Auswertung der Kommandozeile, der POSIX-Version von getopt ()
* nachempfunden.
*
* PO: ANSI C
*/
#include <stdio.h>
#include <string.h>
#include "getopt.h"
/* Globale Variablen */
char *optarg;
int optind = 1;
int opterr = 1;
int optopt;
static char *nextarg = NULL;
/* Funktion */
int getopt (int argc, char *argv[], char *optstring)
/*
* AU: Auswertung der Kommandozeile
*
* VB: argc und argv sind die Parameter, die an main () uebergeben werden.
* optstring ist ein String, der die Zeichen enthaelt, die als
* Optionen erkannt werden. Wenn ein Zeichen von einem Doppelpunkt
* gefolgt wird, hat die Option ein Argument, das direkt auf das Zeichen
* folgt oder durch Space davon getrennt ist. Gueltige Optionszeichen
* sind alle druckbaren Zeichen ausser '?', ' ' und ':'.
*
* optind ist der Index auf das naechste Element von argv[], das
* bearbeitet wird.
*
* opterr ist ein Flag, das festlegt, ob bei Fehlern Fehlermeldungen
* ausgegeben werden.
*
* optarg ist ein Zeiger auf das Argument, wenn eine Option ein
* Argument hat.
*
* optopt enthaelt bei Fehlern das Optionszeichen, das den Fehler aus-
* geloest hat.
*
* NB: Rueckgabewert ist das jeweils naechste Optionszeichen, oder -1 am
* Ende der Optionsliste.
*
* Die Optionsliste ist zu Ende, wenn argv[optind] NULL ist, oder
* argv[optind] nicht mit '-' (oder '/') beginnt, oder argv[optind]
* ein einzelnes "-" ist. In diesem Fall wird optind nicht erhoeht.
* Das Ende der Optionsliste kann mit "--" erzwungen werden, dann ist
* argv[optind] das erste Argument nach "--".
*
* FB: Ein '?' wird zurueckgegeben, wenn ein Optionszeichen nicht in
* optstring enthalten war oder ein ungueltiges Optionszeichen
* uebergeben wurde ('?' oder ':'). Ausserdem bei einem fehlenden
* Argument, wenn das erste Zeichen von optstring kein ':' ist.
*
* Ein ':' wird zurueckgegeben bei einem fehlenden Argument, wenn
* das erste Zeichen von optstring ein ':' ist.
*/
{
char *search;
optarg = NULL;
if (nextarg == NULL)
{
nextarg = argv[optind];
if (nextarg == NULL)
{
return (-1);
}
#ifdef __MSDOS__
if (*nextarg != '-' && *nextarg != '/')
#else
if (*nextarg != '-')
#endif
{
return (-1);
}
nextarg++;
} /* if */
optopt = *nextarg++;
if (optopt == 0)
{
return (-1);
}
optind++;
if (optopt == '-' && *nextarg == 0)
{
return (-1);
}
if (optopt == ':' || optopt == '?')
{
if (opterr)
{
fprintf
(
stderr,
"%s: illegal option -- %c\n",
argv[0],
optopt
);
}
return ('?');
} /* if */
search = strchr (optstring, optopt);
if (search == NULL)
{
if (opterr)
{
fprintf
(
stderr,
"%s: illegal option -- %c\n",
argv[0],
optopt
);
}
return ('?');
} /* if */
if (*nextarg == 0)
{
nextarg = NULL;
}
if (search[1] != ':')
{
if (nextarg != NULL)
{
optind--;
}
return (optopt);
}
if (nextarg != NULL)
{
optarg = nextarg;
nextarg = NULL;
return (optopt);
}
optarg = argv[optind];
if (optind == argc)
{
if (opterr)
{
fprintf
(
stderr,
"%s: option requires an argument -- %c\n",
argv[0],
optopt
);
} /* if */
if (optstring[0] == ':')
{
return (':');
}
else
{
return ('?');
}
} /* if */
else
{
optind++;
}
return (optopt);
} /* getopt () */

View File

@@ -0,0 +1,29 @@
/*
* $Header$
*
* Copyright (C) 1994 Arno Schaefer
*
* AU: Prototypen und externe Variablen fuer getopt ()
*
* PO: ANSI C
*/
#ifndef GETOPT_H
#define GETOPT_H
#ifdef __cplusplus
extern "C" {
#endif
extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;
int getopt (int argc, char *argv[], char *optstring);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,257 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module global.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/global.cpp 1.4 1995/01/19 00:00:52 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdarg.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include "version.h"
#include "global.h"
#define CTRL_C 3
global_vars global;
/* ----------------------------------------------------------------------- */
/* Initialization of global variables */
/* ----------------------------------------------------------------------- */
global_vars::global_vars (void)
{
test_mode = false;
verbose_mode = true;
debug_mode = false;
drive_number_cmdline = 0;
}
global_vars::~global_vars (void)
{
if (debug_mode) fclose (debugfile);
}
void exit_function (void)
{
printx ("\nBye!\n");
}
void global_vars::open_debugfile (int argc,char *argv[])
{
if ((debugfile = fopen ("fipsinfo.dbg","wt")) == NULL)
{
global.debug_mode = false;
warning (true, "Can't open debug file");
}
else
{
fprintf (debugfile,"FIPS debug file\n\n");
fprintf (debugfile,"The command was: ");
while (argc--) fprintf (debugfile,argc ? "%s " : "%s", *argv++);
fprintf (debugfile,"\n\nTranscript of session:\n");
}
}
/* ----------------------------------------------------------------------- */
/* Replacement for printf - prints to screen and debugfile */
/* ----------------------------------------------------------------------- */
void printx (char *fmt,...)
{
va_list ap;
va_start (ap,fmt);
vprintf (fmt,ap);
if (global.debug_mode) vfprintf (global.debugfile,fmt,ap);
va_end (ap);
}
/* ----------------------------------------------------------------------- */
/* Replacement for getch - exit when CTRL-C is pressed */
/* ----------------------------------------------------------------------- */
int getx (void)
{
int character = getch();
if (character == CTRL_C)
{
printx ("\n");
exit (0);
}
return (character);
}
/* ----------------------------------------------------------------------- */
/* Copyright notice and version number */
/* ----------------------------------------------------------------------- */
void notice (void)
{
printx ("\nFIPS version " FIPS_VERSION ", Copyright (C) 1993/94 Arno Schaefer\n\n");
printx ("DO NOT use FIPS in a multitasking environment like Windows, OS/2, Desqview,\n");
printx ("Novell Task manager or the Linux DOS emulator: boot from a DOS boot disk first.\n\n");
printx ("If you use OS/2 or a disk compressor, read the relevant sections in FIPS.DOC.\n\n");
printx ("FIPS comes with ABSOLUTELY NO WARRANTY, see file COPYING for details\n");
printx ("This is free software, and you are welcome to redistribute it\n");
printx ("under certain conditions; again see file COPYING for details.\n");
printx ("\nPress any Key\n");
getx();
}
/* ----------------------------------------------------------------------- */
/* Hexdump binary data into a file */
/* ----------------------------------------------------------------------- */
void hexwrite (byte *buffer,int number,FILE *file)
{
for (int i=0;i<number;i++)
{
fprintf (file,"%02X ",*(buffer+i));
if ((i+1)%16 == 0) fprintf (file,"\n");
else if ((i+1)%8 == 0) fprintf (file,"- ");
}
fprintf (file,"\n");
}
/* ----------------------------------------------------------------------- */
/* Error Handling */
/* ----------------------------------------------------------------------- */
static void print_verbose_message (char *message)
{
char line[256];
int length = 0;
FILE *error_msg_file;
fprintf (stderr,"\n");
if (global.debug_mode) fprintf (global.debugfile,"\n");
if ((error_msg_file = fopen ("errors.txt","rt")) == NULL)
{
fprintf (stderr,"File ERRORS.TXT not found - no verbose messages available\n");
if (global.debug_mode) fprintf (global.debugfile,"File ERRORS.TXT not found - no verbose messages available\n");
global.verbose_mode = false;
return;
}
while (message[length] != 0 && message[length] != ':') length++;
fgets (line,255,error_msg_file);
while (strncmp(message,line,length)) if (fgets (line,255,error_msg_file) == NULL) return;
fgets (line,255,error_msg_file);
while (!strncmp(" ",line,2))
{
fprintf (stderr,"%s",line+2);
if (global.debug_mode) fprintf (global.debugfile,"%s",line+2);
if (fgets (line,255,error_msg_file) == NULL) return;
}
fclose (error_msg_file);
}
void error (char *message,...)
{
va_list ap;
va_start (ap,message);
fprintf (stderr,"\nError: ");
vfprintf (stderr,message,ap);
fprintf (stderr,"\n");
if (global.debug_mode)
{
fprintf (global.debugfile,"\nError: ");
vfprintf (global.debugfile,message,ap);
fprintf (global.debugfile,"\n");
}
va_end (ap);
if (global.verbose_mode) print_verbose_message (message);
exit (-1);
}
void warning (boolean wait_key, char *message,...)
{
va_list ap;
va_start (ap,message);
fprintf (stderr,"\nWarning: ");
vfprintf (stderr,message,ap);
fprintf (stderr,"\n");
if (global.debug_mode)
{
fprintf (global.debugfile,"\nWarning: ");
vfprintf (global.debugfile,message,ap);
fprintf (global.debugfile,"\n");
}
va_end (ap);
if (global.verbose_mode) print_verbose_message (message);
if (wait_key)
{
fprintf (stderr,"\nPress any key\n");
if (global.debug_mode) fprintf (global.debugfile,"\nPress any key\n");
getx ();
}
}
void infomsg (char *message,...)
{
va_list ap;
va_start (ap,message);
fprintf (stderr,"\nInfo: ");
vfprintf (stderr,message,ap);
fprintf (stderr,"\n");
if (global.debug_mode)
{
fprintf (global.debugfile,"\nInfo: ");
vfprintf (global.debugfile,message,ap);
fprintf (global.debugfile,"\n");
}
va_end (ap);
if (global.verbose_mode) print_verbose_message (message);
fprintf (stderr,"\nPress any key\n");
if (global.debug_mode) fprintf (global.debugfile,"\nPress any key\n");
getx ();
}

View File

@@ -0,0 +1,70 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module disk_io.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/global.h 1.4 1995/01/19 00:01:25 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef GLOBAL_H
#define GLOBAL_H
#include <stdio.h>
#include "types.h"
#include "hdstruct.h"
#include "primpart.h"
struct global_vars
{
boolean test_mode;
boolean verbose_mode;
boolean debug_mode;
int drive_number_cmdline;
FILE *debugfile;
void open_debugfile (int argc,char *argv[]);
global_vars (void);
~global_vars (void);
};
extern global_vars global;
void printx (char *fmt,...);
int getx (void);
void error (char *message,...);
void warning (boolean wait_key, char *message,...);
void infomsg (char *message,...);
void hexwrite (byte *buffer,int number,FILE *file);
void exit_function (void);
void notice (void);
void evaluate_argument_vector (int argc,char *argv[]);
void save_root_and_boot (harddrive *drive,partition *partition);
#endif

View File

@@ -0,0 +1,154 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module hdstruct.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/hdstruct.cpp 1.4 1995/01/19 00:20:01 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include "types.h"
#include "hdstruct.h"
root_sector::root_sector (root_sector &rs)
{
drive = rs.drive;
for (int i=0; i<512; i++) data[i] = rs.data[i];
}
void root_sector::operator= (root_sector &rs)
{
drive = rs.drive;
for (int i=0; i<512; i++) data[i] = rs.data[i];
}
void harddrive::operator= (harddrive &hd)
{
physical_drive::operator= (hd);
*root_sector = *(hd.root_sector);
partition_table () = hd.partition_table ();
}
void harddrive::get_partition_table (void)
{
partition_table().get (root_sector);
for (int i = 0; i < 4; i++)
{
class partition_info* p
= &(partition_table().partition_info[i]);
if (p->system == 0) continue;
while
(
p->start_sector_abs
> (
(p->start_cylinder + 1000UL)
* geometry.heads
* geometry.sectors
+ p->start_head
* geometry.sectors
+ p->start_sector
- 1
)
)
{
p->start_cylinder += 1024; // more than 1024 cylinders
}
while
(
(p->start_sector_abs + p->no_of_sectors_abs - 1)
> (
(p->end_cylinder + 1000UL)
* geometry.heads
* geometry.sectors
+ p->end_head
* geometry.sectors
+ p->end_sector
- 1
)
)
{
p->end_cylinder += 1024; // more than 1024 cylinders
}
}
}
/* ----------------------------------------------------------------------- */
/* Extract Partition Table from root sector */
/* ----------------------------------------------------------------------- */
void partition_table::get (root_sector *root_sector)
{
for (int i=0;i<4;i++)
{
class partition_info *p = &partition_info[i];
byte *pi = &(root_sector->data[0x1be+16*i]);
p->bootable = *pi;
p->start_head = *(pi+1);
p->start_cylinder = *(pi+3) | ((*(pi+2) << 2) & 0x300);
p->start_sector = *(pi+2) & 0x3f;
p->system = *(pi+4);
p->end_head = *(pi+5);
p->end_cylinder = *(pi+7) | ((*(pi+6) << 2) & 0x300);
p->end_sector = *(pi+6) & 0x3f;
p->start_sector_abs = (dword) *(pi+8) | ((dword) *(pi+9) << 8) | ((dword) *(pi+10) << 16) | ((dword) *(pi+11) << 24);
p->no_of_sectors_abs = (dword) *(pi+12) | ((dword) *(pi+13) << 8) | ((dword) *(pi+14) << 16) | ((dword) *(pi+15) << 24);
}
}
/* ----------------------------------------------------------------------- */
/* Write Partition Table back into root sector */
/* ----------------------------------------------------------------------- */
void partition_table::put (root_sector *root_sector)
{
for (int i=0; i<4; i++)
{
class partition_info p = partition_info[i];
byte *pi = &(root_sector->data[0x1be+16*i]);
*pi = p.bootable;
*(pi+1) = p.start_head;
*(pi+2) = ((p.start_cylinder >> 2) & 0xc0) | (p.start_sector & 0x3f);
*(pi+3) = p.start_cylinder & 0xff;
*(pi+4) = p.system;
*(pi+5) = p.end_head;
*(pi+6) = ((p.end_cylinder >> 2) & 0xc0) | (p.end_sector & 0x3f);
*(pi+7) = p.end_cylinder & 0xff;
*(pi+8) = p.start_sector_abs & 0xff;
*(pi+9) = (p.start_sector_abs >> 8) & 0xff;
*(pi+10) = (p.start_sector_abs >> 16) & 0xff;
*(pi+11) = (p.start_sector_abs >> 24) & 0xff;
*(pi+12) = p.no_of_sectors_abs & 0xff;
*(pi+13) = (p.no_of_sectors_abs >> 8) & 0xff;
*(pi+14) = (p.no_of_sectors_abs >> 16) & 0xff;
*(pi+15) = (p.no_of_sectors_abs >> 24) & 0xff;
}
}

View File

@@ -0,0 +1,144 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module hdstruct.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/hdstruct.h 1.4 1995/01/19 00:01:26 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef HDSTRUCT_H
#define HDSTRUCT_H
#include "types.h"
#include "disk_io.h"
/* ----------------------------------------------------------------------- */
/* Class root_sector - derived from structure sector */
/* Must be initialized with a pointer to a physical_drive object */
/* Read() and Write() read/write sector 0 of physical drive */
/* ----------------------------------------------------------------------- */
class root_sector:public sector
{
physical_drive *drive;
public:
// constructors and operators
root_sector (physical_drive *drive) { root_sector::drive = drive; }
root_sector (root_sector &rs);
void operator= (root_sector &rs);
// functions
int read (void) { return drive->read_sector (this, 0); }
int write (void) { return drive->write_sector (this, 0); }
};
/* ----------------------------------------------------------------------- */
/* Partition Info Structure */
/* Each entry in the partition table contains this information */
/* ----------------------------------------------------------------------- */
struct partition_info
{
byte bootable; // 80h or 0
byte start_head; // location of first sector (boot_sector)
word start_cylinder;
byte start_sector;
byte system; // 1 = 12-bit FAT
// 4 = 16-bit FAT & 16-bit sector number
// 6 = 16-bit FAT & 32-bit sector number (BIGDOS)
byte end_head; // location of last sector
word end_cylinder;
byte end_sector;
dword start_sector_abs; // = start_cylinder * heads * sectors
// + start_head * sectors + start_sector - 1
dword no_of_sectors_abs; // = end_cylinder * heads * sectors + end_head * sectors
// + end_sector - start_sector_abs
};
/* ----------------------------------------------------------------------- */
/* Partition Table Structure */
/* The partition table consists of 4 entries for the 4 possible partitions */
/* Get() reads the partition table from the root_sector, put() writes the */
/* data back into the root_sector buffer */
/* ----------------------------------------------------------------------- */
struct partition_table
{
partition_info partition_info[4];
void get (root_sector *root_sector);
void put (root_sector *root_sector);
};
/* ----------------------------------------------------------------------- */
/* Harddrive Class, derived from physical_drive */
/* Represents one physical harddrive. Must be initialized with the drive */
/* number (0x80 for 1st HDD). Contains the root_sector and partition table. */
/* ----------------------------------------------------------------------- */
class harddrive:public physical_drive
{
partition_table pr_partition_table;
public:
// constructors, destructors, operators
harddrive (int number):physical_drive (number)
{
root_sector = new class root_sector (this);
}
harddrive (harddrive &hd):physical_drive (hd)
{
root_sector = new class root_sector (*(hd.root_sector));
partition_table () = hd.partition_table ();
}
void operator= (harddrive &hd);
~harddrive (void) { delete root_sector; }
// public data
root_sector *root_sector;
// member access functions
virtual partition_table &partition_table() { return pr_partition_table; }
// functions
int read_root_sector (void) { return (root_sector->read ()); }
int write_root_sector (void) { return (root_sector->write ()); }
void get_partition_table (void); // extract pt data from root sector
void put_partition_table (void) // put pt data into root sector
{partition_table().put (root_sector);}
};
#endif

View File

@@ -0,0 +1,114 @@
// host_os.cpp host operating system classes
// dave mccaldon (d.mccalden@staffordshire.ac.uk)
#include "host_os.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
char *msdos_info (void)
{
return ("MS-DOS version %d.%d");
};
char *dosemu_info (void)
{
return ("Linux dosemu version %d.%d");
};
char *mswindows_info (void)
{
return ("MS-Windows version %d.%d");
};
char *desqview_info (void)
{
return ("Desq-View version %d.%d");
};
host_os::host_os (void)
{
status = NOT_OK;
if (mswindows_detect () == true) format = mswindows_info;
// else if (dosemu_detect () == true) format = dosemu_info;
else if (desqview_detect () == true) format = desqview_info;
else
{
status = OK;
msdos_version ();
format = msdos_info;
}
}
char *host_os::information( char *p )
{
if( p == NULL )
p = (char *) malloc( strlen( format() ) + 12 );
sprintf( p, format(), ver_major, ver_minor );
return p;
}
void host_os::msdos_version()
{
ver_major = _osmajor; // borlandc constants
ver_minor = _osminor;
}
boolean host_os::mswindows_detect()
{
union REGS r;
r.x.ax = 0x1600;
int86( 0x2F, &r, &r );
if( r.h.al & 0x7F )
{
ver_major = r.h.al;
ver_minor = r.h.ah;
return (true);
}
return (false);
}
boolean host_os::dosemu_detect()
{
union REGS r;
// this is slightly more difficult than just calling the dosemu
// interrupt (0xE5), we need to check if the interrupt has a
// handler, as DOS and BIOS don't establish a default handler
if( getvect( 0xE5 ) == NULL )
return (false);
r.x.ax = 0;
int86( 0xE5, &r, &r );
if( r.x.ax == 0xAA55 ) // check signature
{
ver_major = r.h.bh;
ver_minor = r.h.bl;
return (true);
}
return (false);
}
boolean host_os::desqview_detect()
{
union REGS r;
r.x.ax = 0x2B01; // AL=01 => get desqview version
r.x.cx = 0x4445; // CX = 'DE'
r.x.dx = 0x5351; // DX = 'SQ'
int86( 0x21, &r, &r );
if( r.h.al != 0xFF )
{
ver_major = r.h.bh;
ver_minor = r.h.bl;
return (true);
}
return (false);
}

View File

@@ -0,0 +1,34 @@
// host_os.h host operating system classes
// dave mccaldon (d.mccalden@staffordshire.ac.uk)
#ifndef HOST_OS_H
#define HOST_OS_H
#include "types.h"
#define NOT_OK 0 // NOT_OK for FIPS to run
#define OK 1 // OK for FIPS to run
#define UNKNOWN 2
class host_os
{
public:
host_os(); // constructor
virtual int ok () { return status; };
virtual char *information( char * );
protected:
char* (*format)();
void msdos_version ();
boolean mswindows_detect ();
boolean dosemu_detect ();
boolean desqview_detect ();
int status; // status value
int ver_major; // major version number
int ver_minor; // minor version number
};
#endif

View File

@@ -0,0 +1,232 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module input.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/input.cpp 1.4 1995/01/19 00:00:54 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <ctype.h>
#include <stdlib.h>
#include "types.h"
#include "disk_io.h"
#include "global.h"
#include "input.h"
/* ----------------------------------------------------------------------- */
/* User Input */
/* ----------------------------------------------------------------------- */
static void wait_for_key (void)
{
printx ("\nPress any Key\n");
getx();
}
int ask_for_drive_number (void)
/*
* Find Disk Drives - if more than one, ask for drive number. If no drive
* was found, issue warning, try drive 0x80 anyway
*/
{
int drives_found = 0;
int drive_table[] = {0,0,0,0,0,0,0,0,0};
int no_of_drives = get_no_of_drives ();
for (int i=0x80; i < 0x80 + no_of_drives; i++)
{
if (get_disk_type (i) == 3)
{
drive_table[drives_found++] = i;
if (drives_found == 9)
break;
}
}
if (drives_found == 0)
{
warning (false, "No compatible hard disk found");
ask_if_continue ();
return (0x80);
}
if (drives_found == 1)
return (drive_table[0]);
printx ("Which Drive (");
for (i=0; i<drives_found; i++)
printx ("%u=0x%02X/", i+1, drive_table[i]);
printx ("\b)? ");
while (true)
{
i = getx ();
if (i >= '1' && i <= '9')
if (drive_table[i - '1'] != 0) break;
}
printx ("%c\n",i);
return (drive_table[i - '1']);
}
int ask_for_partition_number (partition_info parts[])
{
int number_of_partitions = (parts[0].system != 0) + (parts[1].system != 0) +
(parts[2].system != 0) + (parts[3].system != 0);
if (number_of_partitions == 0)
error ("No valid partition found");
if (number_of_partitions == 4)
error ("No free partition");
if (number_of_partitions == 1)
{
wait_for_key();
for (int i = 0; i < 4; i++) if (parts[i].system) return i;
}
printx ("\nWhich Partition do you want to split (");
for (int i = 0; i < 4; i++) if (parts[i].system) printx ("%u/", i + 1);
printx ("\b)? ");
while (true)
{
i = getx ();
if (isdigit (i)) if (('0' < i) && (i <= '4')) if (parts[i - '1'].system) break;
}
printx ("%c\n", i);
return (i - '1');
}
dword ask_for_new_start_cylinder (int start_cylinder, int min_cylinder, int max_cylinder, int sectors_per_cylinder)
{
int akt_cylinder = min_cylinder;
printx ("\nEnter start cylinder for new partition (%u - %u):\n\n",min_cylinder,max_cylinder);
printx ("Use the cursor keys to choose the cylinder, <enter> to continue\n\n");
printx ("Old partition Cylinder New Partition\n");
while (true)
{
double oldsize = (akt_cylinder - start_cylinder) * (double) sectors_per_cylinder / 2048;
double newsize = (max_cylinder - akt_cylinder + 1) * (double) sectors_per_cylinder / 2048;
printf (" %6.1f MB %4u %6.1f MB\r", oldsize, akt_cylinder, newsize);
int input = getx ();
if (input == '\r')
{
printx (" %6.1f MB %4u %6.1f MB\n\n", oldsize, akt_cylinder, newsize);
return (akt_cylinder);
}
else if (input != 0) continue;
input = getx ();
switch (input)
{
case 75:
if (akt_cylinder > min_cylinder) akt_cylinder--;
break;
case 77:
if (akt_cylinder < max_cylinder) akt_cylinder++;
break;
case 72:
if (akt_cylinder - 10 >= min_cylinder) akt_cylinder -= 10;
break;
case 80:
if (akt_cylinder + 10 <= max_cylinder) akt_cylinder += 10;
break;
}
}
}
char ask_yes_no (void)
{
int character;
do character = getx(); while ((character != 'y') && (character != 'n'));
printx ("%c\n",character);
return (character);
}
char ask_correction (void)
{
printx ("Do you want to correct this (y/n) ");
return (ask_yes_no ());
}
void ask_for_write_permission (void)
{
printx ("\nReady to write new partition scheme to disk\n");
printx ("Do you want to proceed (y/n)? ");
if (ask_yes_no () == 'n') exit (0);
}
boolean ask_if_continue (void)
{
printx ("\nDo you want to continue or reedit the partition table (c/r)? ");
int character;
do character = getx(); while ((character != 'c') && (character != 'r'));
printx ("%c\n",character);
if (character == 'r') return (false);
return (true);
}
boolean ask_if_save (void)
{
int character;
printx ("Do you want to make a backup copy of your root and boot sector before\nproceeding (y/n)? ");
if (ask_yes_no () == 'n') return (false);
printx ("Do you have a bootable floppy disk in drive A: as described in the\ndocumentation (y/n)? ");
if (ask_yes_no () == 'n')
{
printx ("Please read the file FIPS.DOC!\n");
exit (0);
}
return (true);
}
void ask_if_proceed (void)
{
printx ("Do you want to proceed (y/n)? ");
if (ask_yes_no () == 'n') exit (0);
}

View File

@@ -0,0 +1,47 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module input.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/input.h 1.4 1995/01/19 00:01:27 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef INPUT_H
#define INPUT_H
#include "types.h"
#include "hdstruct.h"
int ask_for_drive_number (void);
int ask_for_partition_number (partition_info parts[]);
dword ask_for_new_start_cylinder (int start_cylinder, int min_cylinder,int max_cylinder, int sectors_per_cylinder);
void ask_for_write_permission (void);
boolean ask_if_continue (void);
boolean ask_if_save (void);
void ask_if_proceed (void);
char ask_yes_no (void);
char ask_correction (void);
#endif

View File

@@ -0,0 +1,126 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module logdr_st.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/logdr_str.cpp 1.4 1995/01/19 00:00:54 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <string.h>
#include "types.h"
#include "logdr_st.h"
/* ----------------------------------------------------------------------- */
/* Extract Bios Parameter Block from boot sector */
/* ----------------------------------------------------------------------- */
void bios_parameter_block::get (boot_sector *boot_sector)
{
byte *bp = boot_sector->data;
memcpy (jump_instruction,bp,3);
memcpy (oem_name,bp+3,8);
oem_name[8]=0;
bytes_per_sector = *(bp+0xb) | (*(bp+0xc) << 8);
sectors_per_cluster = *(bp+0xd);
reserved_sectors = *(bp+0xe) | (*(bp+0xf) << 8);
no_of_fats = *(bp+0x10);
no_of_rootdir_entries = *(bp+0x11) | (*(bp+0x12) << 8);
no_of_sectors = *(bp+0x13) | (*(bp+0x14) << 8);
media_descriptor = *(bp+0x15);
sectors_per_fat = *(bp+0x16) | (*(bp+0x17) << 8);
sectors_per_track = *(bp+0x18) | (*(bp+0x19) << 8);
drive_heads = *(bp+0x1a) | (*(bp+0x1b) << 8);
hidden_sectors = (dword) *(bp+0x1c) | ((dword) *(bp+0x1d) << 8) | ((dword) *(bp+0x1e) << 16) | ((dword) *(bp+0x1f) << 24);
no_of_sectors_long = (dword) *(bp+0x20) | ((dword) *(bp+0x21) << 8) | ((dword) *(bp+0x22) << 16) | ((dword) *(bp+0x23) << 24);
phys_drive_no = *(bp+0x24);
signature = *(bp+0x26);
serial_number = (dword) *(bp+0x27) | ((dword) *(bp+0x28) << 8) | ((dword) *(bp+0x29) << 16) | ((dword) *(bp+0x2a) << 24);
memcpy (volume_label,bp+0x2b,11);
volume_label[11] = 0;
memcpy (file_system_id,bp+0x36,8);
file_system_id[8] = 0;
}
/* ----------------------------------------------------------------------- */
/* Write Bios Parameter Block back into boot sector */
/* ----------------------------------------------------------------------- */
void bios_parameter_block::put (boot_sector *boot_sector)
{
byte *bp = boot_sector->data;
memcpy (bp,jump_instruction,3);
memcpy (bp+3,oem_name,8);
*(bp+0xb) = bytes_per_sector & 0xff;
*(bp+0xc) = (bytes_per_sector >> 8) & 0xff;
*(bp+0xd) = sectors_per_cluster;
*(bp+0xe) = reserved_sectors & 0xff;
*(bp+0xf) = (reserved_sectors >> 8) & 0xff;
*(bp+0x10) = no_of_fats;
*(bp+0x11) = no_of_rootdir_entries & 0xff;
*(bp+0x12) = (no_of_rootdir_entries >> 8) & 0xff;
*(bp+0x13) = no_of_sectors & 0xff;
*(bp+0x14) = (no_of_sectors >> 8) & 0xff;
*(bp+0x15) = media_descriptor;
*(bp+0x16) = sectors_per_fat & 0xff;
*(bp+0x17) = (sectors_per_fat >> 8) & 0xff;
*(bp+0x18) = sectors_per_track & 0xff;
*(bp+0x19) = (sectors_per_track >> 8) & 0xff;
*(bp+0x1a) = drive_heads & 0xff;
*(bp+0x1b) = (drive_heads >> 8) & 0xff;
*(bp+0x1c) = hidden_sectors & 0xff;
*(bp+0x1d) = (hidden_sectors >> 8) & 0xff;
*(bp+0x1e) = (hidden_sectors >> 16) & 0xff;
*(bp+0x1f) = (hidden_sectors >> 24) & 0xff;
*(bp+0x20) = no_of_sectors_long & 0xff;
*(bp+0x21) = (no_of_sectors_long >> 8) & 0xff;
*(bp+0x22) = (no_of_sectors_long >> 16) & 0xff;
*(bp+0x23) = (no_of_sectors_long >> 24) & 0xff;
*(bp+0x24) = phys_drive_no;
*(bp+0x26) = signature;
*(bp+0x27) = serial_number & 0xff;
*(bp+0x28) = (serial_number >> 8) & 0xff;
*(bp+0x29) = (serial_number >> 16) & 0xff;
*(bp+0x2a) = (serial_number >> 24) & 0xff;
memcpy (bp+0x2b,volume_label,11);
memcpy (bp+0x36,file_system_id,8);
}
/* ----------------------------------------------------------------------- */
/* Extract some misc. drive parameters from BPB */
/* ----------------------------------------------------------------------- */
void logical_drive_info::get (const bios_parameter_block &bpb)
{
start_fat1 = bpb.reserved_sectors;
start_fat2 = start_fat1 + bpb.sectors_per_fat;
start_rootdir = start_fat2 + bpb.sectors_per_fat;
if (bpb.no_of_rootdir_entries == 0) start_data = start_rootdir;
else start_data = start_rootdir + (bpb.no_of_rootdir_entries - 1) / 16 + 1;
if (bpb.sectors_per_cluster == 0) no_of_clusters = 0;
else no_of_clusters = ((bpb.no_of_sectors ? bpb.no_of_sectors : bpb.no_of_sectors_long) - start_data) / bpb.sectors_per_cluster;
};

View File

@@ -0,0 +1,174 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module logdr_st.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/logdr_st.h 1.4 1995/01/19 00:01:27 schaefer Exp $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef LOGDR_ST_H
#define LOGDR_ST_H
#include "types.h"
#include "disk_io.h"
/* ----------------------------------------------------------------------- */
/* Class boot_sector - derived from structure sector */
/* Must be initialized with pointer to logical drive object */
/* Read() and write() read/write sector 0 of logical drive */
/* ----------------------------------------------------------------------- */
class boot_sector:public sector
{
class logical_drive *logical_drive;
public:
// constructor
boot_sector (class logical_drive *logical_drive)
{ boot_sector::logical_drive = logical_drive; }
// functions
int read (void);
int write (void);
};
/* ------------------------------------------------------------------------ */
/* Bios Parameter Block structure */
/* This is not exactly the BPB as understood by DOS, because it contains */
/* the additional fields that are in the boot_sector like jump_instruction, */
/* oem_name etc. Get() extracts info from the boot_sector, put() writes the */
/* info back into the boot_sector buffer. */
/* ------------------------------------------------------------------------ */
struct bios_parameter_block
{
byte jump_instruction[3]; // EB xx 90 or E9 xx xx
char oem_name[9];
word bytes_per_sector; // usually 512
byte sectors_per_cluster; // may differ
word reserved_sectors; // usually 1 (boot_sector)
byte no_of_fats; // usually 2
word no_of_rootdir_entries; // usually 512 for HDs (?), 224 for
// HD-Floppies, 112 for DD-Floppies
word no_of_sectors; // 0 on BIGDOS partitions
byte media_descriptor; // usually F8h
word sectors_per_fat; // depends on partition size
word sectors_per_track; // depends on drive
word drive_heads; // dto.
dword hidden_sectors; // first sector of partition or 0 for FDs
dword no_of_sectors_long; // number of sectors on BIGDOS partitions
byte phys_drive_no; // usually 80h
byte signature; // usually 29h
dword serial_number; // random
char volume_label[12];
char file_system_id[9];
void get (boot_sector *boot_sector);
void put (boot_sector *boot_sector);
};
/* ----------------------------------------------------------------------- */
/* Some miscellaneous figures about the drive */
/* Get() extracts this info from the BPB */
/* ----------------------------------------------------------------------- */
struct logical_drive_info
{
dword start_fat1;
dword start_fat2;
dword start_rootdir;
dword start_data;
dword no_of_clusters;
virtual void get (const bios_parameter_block &bpb);
};
/* ----------------------------------------------------------------------- */
/* Abstract Class logical_drive. This can be any DOS drive that allows */
/* direct reading and writing of sectors, like Harddisk Partitions, Floppy */
/* disks or Ramdisks */
/* ----------------------------------------------------------------------- */
class logical_drive
{
// private data
struct bios_parameter_block pr_bpb;
struct logical_drive_info pr_info;
public:
// public data
class boot_sector *boot_sector;
// member access functions
virtual bios_parameter_block &bpb() { return pr_bpb; }
virtual logical_drive_info &info() { return pr_info; }
// functions
virtual int read_sector (dword number,sector *sector) = 0;
virtual int write_sector (dword number,sector *sector) = 0;
// pure virtual functions
int read_boot_sector (void) { return (boot_sector->read ()); }
int write_boot_sector (void) { return (boot_sector->write ()); }
void get_bpb (void) { bpb().get (boot_sector); }
void put_bpb (void) { bpb().put (boot_sector); }
void get_info (void) { info().get (bpb ()); }
};
/* ----------------------------------------------------------------------- */
/* Function to read boot_sector from logical drive */
/* It must be in the header file because it is inline */
/* ----------------------------------------------------------------------- */
inline int boot_sector::read (void)
{
return logical_drive->read_sector (0,this);
}
/* ----------------------------------------------------------------------- */
/* Function to write boot_sector to logical drive */
/* ----------------------------------------------------------------------- */
inline int boot_sector::write (void)
{
return logical_drive->write_sector (0,this);
}
#endif

View File

@@ -0,0 +1,171 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module main.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/main.cpp 1.4 1995/01/19 00:00:55 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdlib.h>
#include "logdr_st.h"
#include "global.h"
#include "input.h"
#include "fat.h"
#include "fipsspec.h"
#include "host_os.h"
#define FIRST_CHECK false
#define FINAL_CHECK true
extern unsigned _stklen = 20000U;
int main (int argc, char *argv[])
{
// *********************************************************
// Initialize Program
// *********************************************************
evaluate_argument_vector (argc, argv);
atexit (exit_function);
if (global.debug_mode)
global.open_debugfile (argc,argv);
notice ();
host_os os;
char infostring[256];
if (os.ok () != OK)
{
printx ("\nWARNING: FIPS has detected that it is running under %s\n"
"FIPS should not be used under a multitasking OS. If possible, boot from a DOS\n"
"disk and then run FIPS. Read FIPS.DOC for more information.\n\n",
os.information (infostring));
ask_if_proceed ();
}
// *********************************************************
// Select Drive
// *********************************************************
int drive_number;
if (global.drive_number_cmdline != 0)
drive_number = global.drive_number_cmdline;
else
drive_number = ask_for_drive_number ();
fips_harddrive harddrive (drive_number); // reads geometry
if (harddrive.errorcode)
error
(
"Error reading drive geometry: Errorcode %u",
harddrive.errorcode
);
harddrive.reset ();
if (harddrive.errorcode)
{
warning
(
false,
"Drive initialization failure: Errorcode %u",
harddrive.errorcode
);
ask_if_proceed ();
}
// *********************************************************
// Select partition
// *********************************************************
if (harddrive.read_root_sector () != 0)
error ("Error reading root sector");
if (global.debug_mode)
{
fprintf
(
global.debugfile,
"\nRoot sector drive %02Xh:\n\n",
drive_number
);
hexwrite (harddrive.root_sector->data, 512, global.debugfile);
}
while (true)
{
fips_harddrive hd = harddrive;
hd.get_partition_table();
printx ("\nPartition table:\n\n");
hd.print_partition_table ();
hd.check (FIRST_CHECK);
int partition_number =
ask_for_partition_number
(
hd.partition_table().partition_info
);
int system = hd.partition_table()
.partition_info[partition_number].system;
switch (system)
{
case 5:
error ("Can't split extended partitions");
break;
case 1: case 4: case 6:
{
fips_partition* partition =
new fips_partition (&hd, partition_number);
if (partition->split (hd) == true)
return (0);
delete partition;
}
break;
default:
error ("Unknown file system: %02Xh", system);
break;
}
}
}

View File

@@ -0,0 +1,83 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module hdstruct.h
RCS - Header:
$Id$
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
/* ----------------------------------------------------------------------- */
/* Partition Class, derived from logical_drive and raw_partition */
/* Represents one primary DOS partition. Read_sector() and write_sector() */
/* are instances of the virtual functions in the logical_drive class */
/* ----------------------------------------------------------------------- */
#ifndef PRIMPART_H
#define PRIMPART_H
#include "types.h"
#include "disk_io.h"
#include "logdr_st.h"
#include "hdstruct.h"
class partition:public logical_drive
{
public:
int number;
physical_drive *drive;
partition_info *partition_info;
int read_sector (dword number, sector *sector)
{
return (drive->read_sector
(
sector,
partition_info->start_sector_abs
+ number
));
}
int write_sector (dword number, sector *sector)
{
return (drive->write_sector
(
sector,
partition_info->start_sector_abs
+ number
));
}
partition (class harddrive *drive, int number)
{
partition::number = number;
partition::drive = drive;
partition_info =
&(drive->partition_table().partition_info[number]);
boot_sector = new class boot_sector (this);
}
~partition (void) { delete boot_sector; }
};
#endif

View File

@@ -0,0 +1,68 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module save.cpp
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/save.cpp 1.4 1995/01/19 00:01:24 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#include <stdio.h>
#include <io.h>
#include "global.h"
#include "hdstruct.h"
/* ----------------------------------------------------------------------- */
/* Save root- and boot sector to floppy disk */
/* ----------------------------------------------------------------------- */
void save_root_and_boot (harddrive *drive,partition *partition)
{
FILE *save_file;
char *filename = "a:\\rootboot.000";
while (access (filename,0) == 0)
{
if (++filename[14] > '9')
error ("Too many save files on disk");
}
if ((save_file = fopen (filename,"wb")) == NULL)
error ("Can't open file: %s",filename);
printx ("\nWriting file %s\n", filename);
if (fwrite (drive->root_sector->data,1,512,save_file) != 512)
error ("Error writing file: %s",filename);
if (fwrite (partition->boot_sector->data,1,512,save_file) != 512)
error ("Error writing file: %s",filename);
if (fputc (drive->number,save_file) != drive->number)
error ("Error writing file: %s",filename);
if (fputc (partition->number,save_file) != partition->number)
error ("Error writing file: %s",filename);
if (fclose (save_file))
error ("Error closing file: %s",filename);
}

View File

@@ -0,0 +1,40 @@
/*
FIPS - the First nondestructive Interactive Partition Splitting program
Module disk_io.h
RCS - Header:
$Header: c:/daten/fips/source/main/RCS/types.h 1.4 1995/01/19 00:01:28 schaefer Exp schaefer $
Copyright (C) 1993 Arno Schaefer
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Report problems and direct all questions to:
schaefer@rbg.informatik.th-darmstadt.de
*/
#ifndef TYPES_H
#define TYPES_H
typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long dword;
typedef enum {false,true} boolean;
#endif

View File

@@ -0,0 +1 @@
#define FIPS_VERSION "1.5"

View File

@@ -0,0 +1,142 @@
FIPS 1.5 - file SPECIAL.DOC
---------------------------
S1. Use with Stacker/SuperStor/Doublespace etc.
S2. Use with OS/2
S3. Use with OnTrack Disk Manager and similar drivers
------------------------------------------------------------------------------
S1. Use with Stacker/SuperStor/Doublespace etc.
These programs are used to increase disk space by compressing files. They
all work similarly. When installed, they create a compressed volume on the
disk, into which all the files are moved. This compressed volume is a big
file that fills up almost all space on the disk. After booting with the
compression driver, the previous drive C: that contains the compressed
volume is renamed to D:, and the compressed volume itself becomes C:.
From reports I received from users of Stacker and DoubleSpace, I distilled
the following scheme. If you have difficulties, please let me know.
a. Make sure that there is enough space on the compressed partition to be
split.
b. Use the Checkdisk program that comes with the compression software.
c. Remove the Windows swapfile if you have one.
d. Decrease the size of the compressed volume with the utilities that come
with the compression software.
e. Defragment the uncompressed drive that contains the compressed volume
(in most cases drive D:)
f. use FIPS as described in FIPS.DOC
If your system will not let you defragment the uncompressed drive or if
the compressed volume can not be defragmented because it has the hidden
attribute set, FIPS might not offer as much space for the new partition
as is shown in the directory listing of the uncompressed drive. You should
add the following steps:
e1. Copy the defragmentation program (e.g. diskopt.exe, defrag.exe) of the
system to the boot disk
e2. Boot without the compression device driver. This may be tricky, since in
some systems the driver is part of the system files on the boot disk. Try
using a boot disk from an older DOS version, or consult your manuals.
e3. Remove Hidden, Readonly and System attributes from compressed volume
(use dir /a:h to find the name of the the compressed volume)
e4. Defragment the partition.
It was reported that you can use FIPS either with or without the compression
driver loaded.
S2. Use with OS/2
FIPS is known to have problems with OS/2, especially with the dual boot
feature. This is partly due to the fact that OS/2 dual boot uses two copies
of the boot sector - if only one copy is changed by FIPS, OS/2 will not
work properly.
But even when taking this into consideration, some people have reported
strange error messages by OS/2. I encourage you to give FIPS a try, but
make sure to save the root and boot sector to floppy disk with FIPS before
making any changes. FIPS might work if you
a. Remove dual boot from the partition if you use it. I don't know if and
how this is possible, please consult your manual or call IBM. If you
find out, please let me know, so that I can include this info.
b. Boot from a bootable DOS disk
c. Run FIPS (make sure to make FIPS save the root and boot sector to floppy)
d. Reboot, check if everything is ok under DOS
e. Boot from your OS/2 installation disk and reinstall dual boot if
necessary.
f. Boot to OS/2 and look if everything works as expected.
If e. does not work (OS/2 complains with 'hardware error' or something
similar), use RESTORRB to undo the changes FIPS made, reboot again and
reinstall dual boot (if necessary).
So far I did not find out what OS/2 complains about. Since I do not use
OS/2, I have to rely on user reports. If you try FIPS with OS/2,
I would like to hear about it. Any information is welcome, even if it
is just "it worked" or "it did not work". If you have an idea what might
be the problem or any technical information, please tell me about it.
S3. Use with OnTrack Disk Manager and similar drivers
Note: Everything said here also applies to similar device drivers that
perform the same functions as OnTrack. OnTrack is just the most widely
used such system.
I'll try to start at the beginning:
Older BIOSes have a limit on the 'drive geometry' built in, i.e. they
can only properly handle disk drives of up to 1024 cylinders, 16 heads
and 63 sectors. Given a sector size of 512, this results in a total
limit of 504 MB. Most hard drives are far larger nowadays, especially
in the number of cylinders. So a method for accessing these large drives
had to be devised. For compatibility reasons, the cylinder and sector
count could not be extended, but there was still room in the number of
heads value - up to 256 heads.
Modern BIOSes (i.e. BIOSes prepared for EIDE drives) do exactly this,
they trick DOS into thinking that the disk has less than 1024 cylinders,
but more than 16 heads (this is indicated by 'extended sector translation'
or 'logical block addressing' in the BIOS setup). The same is true for
SCSI disks - in this case the translation is done by the BIOS of the
SCSI controller. If you have one of these, you will probably not be using
OnTrack anyway.
OnTrack Disk Manager is a special program that does the translation in
software. It installs its own boot program in the hard disk's master
boot record, so that it is loaded before any other disk access is
done. This means that you can not access the hard disk without loading
the OnTrack device driver first.
This is also true for FIPS. If you just boot from a floppy disk, you will
not be able to access the C: drive, and FIPS will not work. As far as
I know, you _must_ boot from the hard disk, after which FIPS will work
properly.
Note to Linux users: You can NOT use this scheme to create a Linux
partition. This is because the partitioning information that FIPS modifies
is on a level above the OTDM driver, so you can only access them after
having loaded the driver. Since Linux does not use DOS drivers, it can
not access the new partition. The only thing that Linux will see is a
large non-DOS partition: the OnTrack partition (system indicator byte
54h or 56h).
Unfortunately, I currently know of no way to get rid of the OnTrack
device driver or to split off a partition for use under Linux without
completely reformatting and thus losing all data. It might be possible,
given sufficient technical information, but since I personally don't
use it, I can't investigate further into this.
If you are prepared to reformat the disk (after backing up all your data),
you can just delete the OnTrack partition with Linux fdisk and create
new partitions as you require. Note that you can create a DOS partition
at the beginning of the disk. You won't need OnTrack to use it, as
long as its last cylinder is less than 1024. Linux of course has no
problems accessing the cylinders beyond 1024, so you can use all the rest
of the disk for Linux partitions. In case of problems, read the EIDE-
Mini-HOWTO, it contains some more information on this from the Linux
point of view.

View File

@@ -0,0 +1,226 @@
Technical Info on FIPS
----------------------
FIPS was written in C++ V2.0 with the Turbo C++ 1.0 and Borland C++ 3.1
compilers.
It should compile with any newer C++ compiler (perhaps after minor changes
to the BIOS calls).
If you're a C++ wizard, don't look too closely at the code, this is my first
C++ program, so it is far from acceptable (too much public data, some ini-
tializers and assignment operators are missing etc.). Constructive critizism
is always welcome however.
How FIPS works:
FIPS uses the BIOS interrupts 13h 00h (reset disks), 13h 02h (read sector),
13h 08h (get drive parameters), 13h 03h (write sector) and 13h 04h (verify
sector).
Here is the sequence of function calls in main:
evaluate_argument_vector
read the commandline arguments and set the global variables accordingly
notice
display copyright notice and version number
ask_for_drive_number
let the user choose the drive (if more than 1)
harddrive.reset
reset harddrive
harddrive.rootsector->read
read the sector 0,0,1 of the chosen drive into an array of unsigned char
hd.partition_table().get
extract the necessary information from the root sector (see below - The
root sector)
hd.print_partition_table
print the information
hd.check
check if everything is ok (see below - The root sector)
ask_for_partition_number
let the user choose the partition
partition->bootsector->read
read the first sector of the chosen partition to another array
partition->bpb().get
extract info from the boot sector (see below - The boot sector)
partition->print_bpb
print the info
partition->info().get
calculate no. of clusters, starting sector of FATs etc.
partition->check
check boot sector (see below - The boot sector)
fat1.check_against(fat2)
check if FAT 1 is identical to FAT 2 (see below - The FAT)
save_root_and_boot
write root- and boot sector to floppy disk (optional)
ask_for_new_start_cylinder
ask the user for the first cylinder of the new partition
fat2.check_empty
check if chosen part of partition is empty (see below - The FAT)
hd.calculate_new_root
from the chosen start cylinder calculate the new partition table
Note that the partition entries will be moved to the beginning of the par-
tition table, so that the new partition will be the last one and the drive
names will not change.
hd.partition_table.put
write the new partition table into the root sector buffer
hd.partition_table.get,hd.print_partition_table,hd.check
check if new root sector is ok
partition->calculate_new_boot
put new number of sectors in boot sector info
partition->bpb()->put
write new boot sector info into boot sector buffer
partition->bpb()->get,partition->print_bpb,partition->check
check if new boot sector is ok
ask_for_write_permission
ask if user wants to proceed
harddrive.rootsector->write
write the changed root sector to the disk
partition->bootsector->write
write the changed boot sector to the disk
The root sector
---------------
The root sector is the first sector on every hard disk. It contains the
program that loads the boot sector of the bootable partition and the
partition table. The last two bytes of the root sector must be 55 aa (hex).
The partition table begins at 1be. It contains 4 * 16 Bytes for the four
possible partitions.
All numbers are zero based except the start/end-sector number (may be 1-63).
One partition entry contains the following:
1 Byte - Bootable Flag. Must be 0 (not bootable) or 80h (bootable).
At most one Partition may be bootable at a time.
(somewhere I read the bootable flag may also be 81h for the
second drive - does anybody know anything about that?)
1 Byte - Start Head. The number of the head of the first sector of the
partition.
2 Bytes - Start Sector + Cylinder. The Bits are as follows:
CCSSSSSS CCCCCCCC
where the first byte contains the sector number (1 - 63), and
the high two bits of the cylinder number. The second byte con-
tains the low eight bits of the cylinder number.
1 Byte - System Indicator. For DOS this may be:
1 - 12-bit FAT, 16-bit sector number
4 - 16-bit FAT, 16-bit sector number
5 - Extended Partition
6 - 16-bit FAT, 32-bit sector number
1 Byte - End Head. Head Number of the last sector of the partition
2 Bytes - End Sector + Cylinder. Same format as Start Sector + Cylinder
4 Bytes - First Sector. Number of the first sector of the partition. This
corresponds to the Start Head, Sector + Cylinder. High Byte
comes first.
4 Bytes - Total number of Sectors.
The function check_rootsector_validity checks the following:
- Signature Bytes (55 aa) in the last two bytes of the sector
- not more than one bootable partition
- Bootable flag is 0 or 80h
- Start/End sector of a partition is not 0
- Start/End sector & head are not greater than drive geometry allows
- Start cylinder * sectors * heads + start head * sectors + start sector - 1
= first sector (where sectors is no. of sectors per track, heads is
no. of heads of the drive)
- End cylinder * sectors * heads + end head * sector + end sector = first
sector + number of sectors
- if System Indicator is 0, all other bytes of partition entry are 0
- all partitions except the first begin on cylinder boundaries (head = 0,
sectors = 1)
- all partition end on cylinder boundaries
- partitions don't overlap
- no free space between partitions
The boot sector
---------------
The boot sector is the first sector of every partition. It contains the
program that boots the operating system and the bios parameter block.
The last two bytes must again contain 55 aa. The information in the
boot sector is the following:
00 3 bytes jump instruction ('eb xx 90' or 'e9 xx xx')
03 8 bytes OEM name and version - e.g. MSDOS5.0
0b 2 bytes bytes per sector - should be 512
0d 1 byte sectors per cluster - power of two
0e 2 bytes reserved sectors - typically 1 (boot sector)
10 1 byte number of FATs - must be 2
11 2 bytes number of rootdirectory entries - typically 512
13 2 bytes number of sectors (short) - 0, if BIGDOS partition
15 1 byte media descriptor - typically f8h
16 2 bytes sectors per FAT - varies
18 2 bytes sectors per track
1a 2 bytes number of heads
1c 2 bytes number of hidden sectors (low)
- extended BPB since DOS 4.0 -
1e 2 bytes number of hidden sectors (high)
20 4 bytes number of sectors (long)
24 1 byte physical drive number - 80h or 81h
25 1 byte reserved
26 1 byte signature - 29h
The function check_bootsector_validity checks the following:
- correct jump instruction
- signature bytes 55 aa in the last two bytes of the sector
- bytes per sector = 512
- sectors per cluster is power of two
- reserved sectors = 1
- number of FATs = 2
- number of rootdirectory entries is multiple of 16
- media descriptor = f8h
- sectors per fat <= 256
- sectors per fat big enough to hold complete FAT
- sectors per track matches BIOS info
- number of heads matches BIOS info
- hidden sectors = start sector
- signature = 29h, if BIGDOS
- physical drive number = actual drive number
- number of sectors matches partition info
- system indicator byte in root sector matches partition type
The FAT
-------
The File Allocation Table contains the information how the clusters of the
disk are linked to files. Every directory entry contains a pointer to the
first cluster of the file. The corresponding cluster entry in the FAT con-
tains a pointer to the next cluster, or an EOF marker (FFFF for 16-bit FATs,
FFF for 12-bit FATs) if the cluster is the last one of the file.
Bad clusters are marked with FFF7 or FF7. Empty clusters are marked with 0.
The first cluster on the disk is cluster number 2, it begins at the first
sector after the root directory. The FAT entries for the clusters 0 and 1
contain the media descriptor byte (usually F8h for harddisk) and two or
three FFh bytes.
There exist two copies of the FAT on a normal DOS partition, these two
copies must be identical. FAT 2 is the primary FAT.
The function check_fat_validity checks if the two FATs are identical and if
the entries 0 and 1 contain what they are supposed to.
The function check_fat_empty checks if the cluster entries that cover the
new partition contain either 0 (empty) or FFF7 (Bad cluster).
------------------------------------------------------------------------------
I hope you find this information useful. If you found anything not to be
exact or if you have additions, please let me know asap.
Arno Schaefer
schaefer@rbg.informatik.th-darmstadt.de

Binary file not shown.

View File

@@ -0,0 +1,68 @@
RaWrite 1.3
------------
Disclaimer of Warrenty
----------------------
Users of this software must accept this disclaimer of warranty: "This
software is supplied AS IS. Mark Becker disclaims all warranties, expressed
or implied, including, without limitation, the warranties of merchantability
and of fitness for any purpose. Mark Becker assumes no liability for
damages, direct or consequential, which may result from the use of this
software."
Purpose
-------
Write a disk image file to a floppy disk.
Equipment/Software Requirements
-------------------------------
* PC/XT/AT or 100% compatible with at least 256K of RAM and a floppy disk
drive.
* MS-DOS version 3.21 or greater.
* A formatted diskette.
This program uses well-documented generic low-level DOS and BIOS functions.
It should run on nearly every PC in existance. PS/2's should be able to run
RaWrite but this has not been tested.
CAVEAT
------
This program will write ANY disk file to a floppy, overwriting any previous
information that may have been present. If you wish to re-use a diskette
that has been written to by RaWrite then that diskette will probably need to
be reformatted; all MS-DOS specific information will have been erased.
Usage
-----
C> RAWRITE
And follow the prompts. All arguments are case-insensitive.
If the source and destination drives are the same, RaWrite will ask the user
to swap diskettes as required. Rawrite allocates a large buffer in RAM to
reduce the number of disk swaps.
RaWrite may be aborted at any time by typing ^C or CTRL-Break.
Errors
------
RaWrite attempts to determine if the diskette is a 1.44M, 1.2M, 720K, or 360K
diskette by reading sectors 18, 15, and 9 in that order. If the inserted
diskette is not one of the these types, then RaWrite will abort with an error
message.
Errors such as write protect, door open, bad disk, bad sector, etc. cause a
program abort with a short error message.

Binary file not shown.

View File

@@ -0,0 +1,139 @@
WRTDSK v0.90 readme file
DISCLAIMER
==========
WRTDSK is careware: anyone who uses it is obliged (by one's conscience) to
help the local Red-Cross organization. And, of course, it is distributed as
it is, with no warranty. In no event shall author, or his family and pets,
be liable for any incidental, indirect, special or consequential damages made
by use of this software. Anyway, don't get frightened. It is not much worse
than the similar utilities.
DESCRIPTION
===========
WRTDSK is an utility primarily written for copying image files on floppies.
It is intended to be used with formatted DOS floppies with capacity of 360,
720, 1200 or 1440 K. Data read from the file is written onto 'raw device'.
It is very important to use floppies without any bad sectors. You can
determine this by unconditional formatting with MS-DOS FORMAT (use /U switch)
and then running CHKDSK. If you have DOS version 6.20 or newer, you can use
SCANDISK utility to examine floppies that are allready formatted. To prevent
possibility of writing on bad sectors WRTDSK has the ability to verify the
data written.
The length of an image file has to be multiple of 512 bytes (DOS sector
size). If it is not, WRTDSK writes all the data, but last sector data is
overwritten entirely. This has an effect only if more files are specified to
be written on the same floppy.
If anything goes wrong, WRTDSK can be stopped by pressing Ctrl-Break.
USAGE and PARAMETERS
====================
Display of short help that is available with WRTDSK /? follows:
Writes DOS files to raw floppy device.
WRTDSK [drive:] {file [file...] | @filelist} [/F:size] [/V:level] [/A:attempts]
drive Floppy drive (default A:)
file DOS file name (wildcards allowed)
filelist File containing list of files to copy
size Floppy disk capacity in Kbytes (default CMOS data)
level Verify level: 0 = none, 1 = CRC, 2 = Read + CRC (default 1)
attempts Number of write attempts after failure (default 4)
drive:
------
Floppy drive letter, if specified, has to be the first parameter. If it is
not the default is drive A:.
filenames (or @filelist)
------------------------
Specifies file(s) to be written on floppy disk(s). Source files may not
reside on disk that is specified as the destination. There are two ways to
specify files: one is to count all the filenames on the command line and the
other is to enter these filenames in separate list file and specify list file
(preceded by sign '@'). Examples are:
> WRTDSK source.* bin.*
> WRTDSK b: one.dsk two.dsk three.dsk
> WRTDSK a: @dir.lst
Wildcards are allowed: first example above will copy all files beggining
with "source." and then all files beginning with "bin.". Note that if there
is a file named "source", it will not be copied. Files will be sorted in
the alphabetical order before being written to disks.
If that order of disks isn't suitable, the use of list file can greatly
simplify the copying. Supposing that one wants to copy all the files starting
with "disk", he (she) could write:
> DIR /B /O disk*.* > dir.lst
edit "dir.lst", sort files manually and than use the third example shown
above. File names in list file must not contain wildcards.
/F:size
-------
Specifies floppy capacity in Kbytes. Optional, but recommended. If you use
floppy with capacity smaller than the drive (360K floppy in 1200K drive)
the use of this parameter will suppress probing for disk formatting. If disk
formatting cannot be recognized, the user has to restart WRTDSK and then use
/F switch.
File size and disk capacity do not have to match. More small images can be
written on one or more large floppies and also spanned from one to another.
The choice to span or not is entered at the prompt. Also, large image files
can be stretched onto several floppies.
/V:level
--------
Optional parameter, specifies the verification level. The possibilites are
V:0, means no verification; V:1, verification via BIOS call that verifies data
written by its checksum; and V:2 verification by reading data just written,
comparing it with original and after that doing BIOS checksum verification.
Verification level 2 greatly reduces speed, while level 1 does it much less.
Default level is 1.
/A:attempts
-----------
Number of attempts to write data on floppy before an error is reported.
This parameter is optional, the default is 4.
CREDITS
=======
The author wishes to thank Croatian Red Cross (RedCross@hck.hr) for
understanding him being late to the job after long nights of programming,
Igor Bujanovic (igor@srce.hr) for inspiration of WRTDSK, Kees J. Bot
(kjb@cs.vu.nl) for his help and support in developing this utility and
finally everyone who uses it and helps Red-Cross.
BUG REPORTS and COMPATIBILITY LIST
==================================
Any documented bug reports sent by e-mail will be appreciated. Machine
type, including BIOS, bus, FDD controller, drive and floppy types should
be noted. Also, feedback about successful use will be welcome to create a
compatibility list. Please note the WRTDSK version too.
Hrvoje Stipetic, hs@hck.hr