dropping this defragger in here for safe keeping. It's pretty hard to come by on...
authorGed Murphy <gedmurphy@reactos.org>
Thu, 30 Mar 2006 00:09:09 +0000 (00:09 +0000)
committerGed Murphy <gedmurphy@reactos.org>
Thu, 30 Mar 2006 00:09:09 +0000 (00:09 +0000)
svn path=/trunk/; revision=21411

32 files changed:
rosapps/fraginator/COPYING [new file with mode: 0644]
rosapps/fraginator/DefragDialog.cpp [new file with mode: 0644]
rosapps/fraginator/Defragment.cpp [new file with mode: 0644]
rosapps/fraginator/Defragment.h [new file with mode: 0644]
rosapps/fraginator/DriveVolume.cpp [new file with mode: 0644]
rosapps/fraginator/DriveVolume.h [new file with mode: 0644]
rosapps/fraginator/Fraginator Motif Icon.bmp [new file with mode: 0644]
rosapps/fraginator/Fraginator.cpp [new file with mode: 0644]
rosapps/fraginator/Fraginator.dsp [new file with mode: 0644]
rosapps/fraginator/Fraginator.dsw [new file with mode: 0644]
rosapps/fraginator/Fraginator.exe [new file with mode: 0644]
rosapps/fraginator/Fraginator.h [new file with mode: 0644]
rosapps/fraginator/Fraginator.mak [new file with mode: 0644]
rosapps/fraginator/Fraginator.rc [new file with mode: 0644]
rosapps/fraginator/Fraginator.sln [new file with mode: 0644]
rosapps/fraginator/Fraginator.suo [new file with mode: 0644]
rosapps/fraginator/Fraginator.vcproj [new file with mode: 0644]
rosapps/fraginator/MainDialog.cpp [new file with mode: 0644]
rosapps/fraginator/MainDialog.h [new file with mode: 0644]
rosapps/fraginator/Mutex.h [new file with mode: 0644]
rosapps/fraginator/ReportDialog.cpp [new file with mode: 0644]
rosapps/fraginator/ReportDialog.h [new file with mode: 0644]
rosapps/fraginator/Unfrag.cpp [new file with mode: 0644]
rosapps/fraginator/Unfrag.h [new file with mode: 0644]
rosapps/fraginator/default1.bin [new file with mode: 0644]
rosapps/fraginator/icon1.ico [new file with mode: 0644]
rosapps/fraginator/resource.h [new file with mode: 0644]
rosapps/fraginator/unfrag.dsp [new file with mode: 0644]
rosapps/fraginator/unfrag.exe [new file with mode: 0644]
rosapps/fraginator/unfrag.mak [new file with mode: 0644]
rosapps/fraginator/unfrag.plg [new file with mode: 0644]
rosapps/fraginator/unfrag.vcproj [new file with mode: 0644]

diff --git a/rosapps/fraginator/COPYING b/rosapps/fraginator/COPYING
new file mode 100644 (file)
index 0000000..fbdd65f
--- /dev/null
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE\r
+                      Version 2, June 1991\r
+\r
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.\r
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ Everyone is permitted to copy and distribute verbatim copies\r
+ of this license document, but changing it is not allowed.\r
+\r
+                           Preamble\r
+\r
+  The licenses for most software are designed to take away your\r
+freedom to share and change it.  By contrast, the GNU General Public\r
+License is intended to guarantee your freedom to share and change free\r
+software--to make sure the software is free for all its users.  This\r
+General Public License applies to most of the Free Software\r
+Foundation's software and to any other program whose authors commit to\r
+using it.  (Some other Free Software Foundation software is covered by\r
+the GNU Library General Public License instead.)  You can apply it to\r
+your programs, too.\r
+\r
+  When we speak of free software, we are referring to freedom, not\r
+price.  Our General Public Licenses are designed to make sure that you\r
+have the freedom to distribute copies of free software (and charge for\r
+this service if you wish), that you receive source code or can get it\r
+if you want it, that you can change the software or use pieces of it\r
+in new free programs; and that you know you can do these things.\r
+\r
+  To protect your rights, we need to make restrictions that forbid\r
+anyone to deny you these rights or to ask you to surrender the rights.\r
+These restrictions translate to certain responsibilities for you if you\r
+distribute copies of the software, or if you modify it.\r
+\r
+  For example, if you distribute copies of such a program, whether\r
+gratis or for a fee, you must give the recipients all the rights that\r
+you have.  You must make sure that they, too, receive or can get the\r
+source code.  And you must show them these terms so they know their\r
+rights.\r
+\r
+  We protect your rights with two steps: (1) copyright the software, and\r
+(2) offer you this license which gives you legal permission to copy,\r
+distribute and/or modify the software.\r
+\r
+  Also, for each author's protection and ours, we want to make certain\r
+that everyone understands that there is no warranty for this free\r
+software.  If the software is modified by someone else and passed on, we\r
+want its recipients to know that what they have is not the original, so\r
+that any problems introduced by others will not reflect on the original\r
+authors' reputations.\r
+\r
+  Finally, any free program is threatened constantly by software\r
+patents.  We wish to avoid the danger that redistributors of a free\r
+program will individually obtain patent licenses, in effect making the\r
+program proprietary.  To prevent this, we have made it clear that any\r
+patent must be licensed for everyone's free use or not licensed at all.\r
+\r
+  The precise terms and conditions for copying, distribution and\r
+modification follow.\r
+\f\r
+                   GNU GENERAL PUBLIC LICENSE\r
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r
+\r
+  0. This License applies to any program or other work which contains\r
+a notice placed by the copyright holder saying it may be distributed\r
+under the terms of this General Public License.  The "Program", below,\r
+refers to any such program or work, and a "work based on the Program"\r
+means either the Program or any derivative work under copyright law:\r
+that is to say, a work containing the Program or a portion of it,\r
+either verbatim or with modifications and/or translated into another\r
+language.  (Hereinafter, translation is included without limitation in\r
+the term "modification".)  Each licensee is addressed as "you".\r
+\r
+Activities other than copying, distribution and modification are not\r
+covered by this License; they are outside its scope.  The act of\r
+running the Program is not restricted, and the output from the Program\r
+is covered only if its contents constitute a work based on the\r
+Program (independent of having been made by running the Program).\r
+Whether that is true depends on what the Program does.\r
+\r
+  1. You may copy and distribute verbatim copies of the Program's\r
+source code as you receive it, in any medium, provided that you\r
+conspicuously and appropriately publish on each copy an appropriate\r
+copyright notice and disclaimer of warranty; keep intact all the\r
+notices that refer to this License and to the absence of any warranty;\r
+and give any other recipients of the Program a copy of this License\r
+along with the Program.\r
+\r
+You may charge a fee for the physical act of transferring a copy, and\r
+you may at your option offer warranty protection in exchange for a fee.\r
+\r
+  2. You may modify your copy or copies of the Program or any portion\r
+of it, thus forming a work based on the Program, and copy and\r
+distribute such modifications or work under the terms of Section 1\r
+above, provided that you also meet all of these conditions:\r
+\r
+    a) You must cause the modified files to carry prominent notices\r
+    stating that you changed the files and the date of any change.\r
+\r
+    b) You must cause any work that you distribute or publish, that in\r
+    whole or in part contains or is derived from the Program or any\r
+    part thereof, to be licensed as a whole at no charge to all third\r
+    parties under the terms of this License.\r
+\r
+    c) If the modified program normally reads commands interactively\r
+    when run, you must cause it, when started running for such\r
+    interactive use in the most ordinary way, to print or display an\r
+    announcement including an appropriate copyright notice and a\r
+    notice that there is no warranty (or else, saying that you provide\r
+    a warranty) and that users may redistribute the program under\r
+    these conditions, and telling the user how to view a copy of this\r
+    License.  (Exception: if the Program itself is interactive but\r
+    does not normally print such an announcement, your work based on\r
+    the Program is not required to print an announcement.)\r
+\f\r
+These requirements apply to the modified work as a whole.  If\r
+identifiable sections of that work are not derived from the Program,\r
+and can be reasonably considered independent and separate works in\r
+themselves, then this License, and its terms, do not apply to those\r
+sections when you distribute them as separate works.  But when you\r
+distribute the same sections as part of a whole which is a work based\r
+on the Program, the distribution of the whole must be on the terms of\r
+this License, whose permissions for other licensees extend to the\r
+entire whole, and thus to each and every part regardless of who wrote it.\r
+\r
+Thus, it is not the intent of this section to claim rights or contest\r
+your rights to work written entirely by you; rather, the intent is to\r
+exercise the right to control the distribution of derivative or\r
+collective works based on the Program.\r
+\r
+In addition, mere aggregation of another work not based on the Program\r
+with the Program (or with a work based on the Program) on a volume of\r
+a storage or distribution medium does not bring the other work under\r
+the scope of this License.\r
+\r
+  3. You may copy and distribute the Program (or a work based on it,\r
+under Section 2) in object code or executable form under the terms of\r
+Sections 1 and 2 above provided that you also do one of the following:\r
+\r
+    a) Accompany it with the complete corresponding machine-readable\r
+    source code, which must be distributed under the terms of Sections\r
+    1 and 2 above on a medium customarily used for software interchange; or,\r
+\r
+    b) Accompany it with a written offer, valid for at least three\r
+    years, to give any third party, for a charge no more than your\r
+    cost of physically performing source distribution, a complete\r
+    machine-readable copy of the corresponding source code, to be\r
+    distributed under the terms of Sections 1 and 2 above on a medium\r
+    customarily used for software interchange; or,\r
+\r
+    c) Accompany it with the information you received as to the offer\r
+    to distribute corresponding source code.  (This alternative is\r
+    allowed only for noncommercial distribution and only if you\r
+    received the program in object code or executable form with such\r
+    an offer, in accord with Subsection b above.)\r
+\r
+The source code for a work means the preferred form of the work for\r
+making modifications to it.  For an executable work, complete source\r
+code means all the source code for all modules it contains, plus any\r
+associated interface definition files, plus the scripts used to\r
+control compilation and installation of the executable.  However, as a\r
+special exception, the source code distributed need not include\r
+anything that is normally distributed (in either source or binary\r
+form) with the major components (compiler, kernel, and so on) of the\r
+operating system on which the executable runs, unless that component\r
+itself accompanies the executable.\r
+\r
+If distribution of executable or object code is made by offering\r
+access to copy from a designated place, then offering equivalent\r
+access to copy the source code from the same place counts as\r
+distribution of the source code, even though third parties are not\r
+compelled to copy the source along with the object code.\r
+\f\r
+  4. You may not copy, modify, sublicense, or distribute the Program\r
+except as expressly provided under this License.  Any attempt\r
+otherwise to copy, modify, sublicense or distribute the Program is\r
+void, and will automatically terminate your rights under this License.\r
+However, parties who have received copies, or rights, from you under\r
+this License will not have their licenses terminated so long as such\r
+parties remain in full compliance.\r
+\r
+  5. You are not required to accept this License, since you have not\r
+signed it.  However, nothing else grants you permission to modify or\r
+distribute the Program or its derivative works.  These actions are\r
+prohibited by law if you do not accept this License.  Therefore, by\r
+modifying or distributing the Program (or any work based on the\r
+Program), you indicate your acceptance of this License to do so, and\r
+all its terms and conditions for copying, distributing or modifying\r
+the Program or works based on it.\r
+\r
+  6. Each time you redistribute the Program (or any work based on the\r
+Program), the recipient automatically receives a license from the\r
+original licensor to copy, distribute or modify the Program subject to\r
+these terms and conditions.  You may not impose any further\r
+restrictions on the recipients' exercise of the rights granted herein.\r
+You are not responsible for enforcing compliance by third parties to\r
+this License.\r
+\r
+  7. If, as a consequence of a court judgment or allegation of patent\r
+infringement or for any other reason (not limited to patent issues),\r
+conditions are imposed on you (whether by court order, agreement or\r
+otherwise) that contradict the conditions of this License, they do not\r
+excuse you from the conditions of this License.  If you cannot\r
+distribute so as to satisfy simultaneously your obligations under this\r
+License and any other pertinent obligations, then as a consequence you\r
+may not distribute the Program at all.  For example, if a patent\r
+license would not permit royalty-free redistribution of the Program by\r
+all those who receive copies directly or indirectly through you, then\r
+the only way you could satisfy both it and this License would be to\r
+refrain entirely from distribution of the Program.\r
+\r
+If any portion of this section is held invalid or unenforceable under\r
+any particular circumstance, the balance of the section is intended to\r
+apply and the section as a whole is intended to apply in other\r
+circumstances.\r
+\r
+It is not the purpose of this section to induce you to infringe any\r
+patents or other property right claims or to contest validity of any\r
+such claims; this section has the sole purpose of protecting the\r
+integrity of the free software distribution system, which is\r
+implemented by public license practices.  Many people have made\r
+generous contributions to the wide range of software distributed\r
+through that system in reliance on consistent application of that\r
+system; it is up to the author/donor to decide if he or she is willing\r
+to distribute software through any other system and a licensee cannot\r
+impose that choice.\r
+\r
+This section is intended to make thoroughly clear what is believed to\r
+be a consequence of the rest of this License.\r
+\f\r
+  8. If the distribution and/or use of the Program is restricted in\r
+certain countries either by patents or by copyrighted interfaces, the\r
+original copyright holder who places the Program under this License\r
+may add an explicit geographical distribution limitation excluding\r
+those countries, so that distribution is permitted only in or among\r
+countries not thus excluded.  In such case, this License incorporates\r
+the limitation as if written in the body of this License.\r
+\r
+  9. The Free Software Foundation may publish revised and/or new versions\r
+of the General Public License from time to time.  Such new versions will\r
+be similar in spirit to the present version, but may differ in detail to\r
+address new problems or concerns.\r
+\r
+Each version is given a distinguishing version number.  If the Program\r
+specifies a version number of this License which applies to it and "any\r
+later version", you have the option of following the terms and conditions\r
+either of that version or of any later version published by the Free\r
+Software Foundation.  If the Program does not specify a version number of\r
+this License, you may choose any version ever published by the Free Software\r
+Foundation.\r
+\r
+  10. If you wish to incorporate parts of the Program into other free\r
+programs whose distribution conditions are different, write to the author\r
+to ask for permission.  For software which is copyrighted by the Free\r
+Software Foundation, write to the Free Software Foundation; we sometimes\r
+make exceptions for this.  Our decision will be guided by the two goals\r
+of preserving the free status of all derivatives of our free software and\r
+of promoting the sharing and reuse of software generally.\r
+\r
+                           NO WARRANTY\r
+\r
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\r
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\r
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\r
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\r
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\r
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\r
+REPAIR OR CORRECTION.\r
+\r
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\r
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\r
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\r
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\r
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\r
+POSSIBILITY OF SUCH DAMAGES.\r
+\r
+                    END OF TERMS AND CONDITIONS\r
+\f\r
+           How to Apply These Terms to Your New Programs\r
+\r
+  If you develop a new program, and you want it to be of the greatest\r
+possible use to the public, the best way to achieve this is to make it\r
+free software which everyone can redistribute and change under these terms.\r
+\r
+  To do so, attach the following notices to the program.  It is safest\r
+to attach them to the start of each source file to most effectively\r
+convey the exclusion of warranty; and each file should have at least\r
+the "copyright" line and a pointer to where the full notice is found.\r
+\r
+    <one line to give the program's name and a brief idea of what it does.>\r
+    Copyright (C) <year>  <name of author>\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+\r
+Also add information on how to contact you by electronic and paper mail.\r
+\r
+If the program is interactive, make it output a short notice like this\r
+when it starts in an interactive mode:\r
+\r
+    Gnomovision version 69, Copyright (C) year  name of author\r
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\r
+    This is free software, and you are welcome to redistribute it\r
+    under certain conditions; type `show c' for details.\r
+\r
+The hypothetical commands `show w' and `show c' should show the appropriate\r
+parts of the General Public License.  Of course, the commands you use may\r
+be called something other than `show w' and `show c'; they could even be\r
+mouse-clicks or menu items--whatever suits your program.\r
+\r
+You should also get your employer (if you work as a programmer) or your\r
+school, if any, to sign a "copyright disclaimer" for the program, if\r
+necessary.  Here is a sample; alter the names:\r
+\r
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\r
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.\r
+\r
+  <signature of Ty Coon>, 1 April 1989\r
+  Ty Coon, President of Vice\r
+\r
+This General Public License does not permit incorporating your program into\r
+proprietary programs.  If your program is a subroutine library, you may\r
+consider it more useful to permit linking proprietary applications with the\r
+library.  If this is what you want to do, use the GNU Library General\r
+Public License instead of this License.\r
diff --git a/rosapps/fraginator/DefragDialog.cpp b/rosapps/fraginator/DefragDialog.cpp
new file mode 100644 (file)
index 0000000..cd4b65a
--- /dev/null
@@ -0,0 +1,38 @@
+#include "DefragDialog.h"\r
+#include "Defragment.h"\r
+#include "resource.h"\r
+\r
+\r
+void UpdateDefragInfo (HWND Dlg)\r
+{\r
+    Defragment *Defrag;\r
+    HWND PercentItem;\r
+    char PercentText[100];\r
+\r
+    Defrag = (Defragment *) GetWindowLongPtr (Dlg, GWLP_USERDATA);\r
+    \r
+    sprintf (PercentText, "%6.2f%%", Defrag->GetStatusPercent());\r
+    PercentItem = GetDlgItem (Dlg, IDC_PERCENT);\r
+    SendMessage (GetDlgItem (Dlg, IDC_PERCENT), WM_SETTEXT, 0, (LPARAM) PercentText);\r
+    SendMessage (GetDlgItem (Dlg, IDC_STATUS_TEXT), WM_SETTEXT, 0, (LPARAM) Defrag->GetStatusString().c_str());\r
+\r
+    return;\r
+}\r
+\r
+\r
+INT_PTR CALLBACK DefragDialogProc (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam)\r
+{\r
+    switch (Msg)\r
+    {\r
+        case WM_INITDIALOG:\r
+            SetWindowLongPtr (Dlg, GWLP_USERDATA, (LONG_PTR)LParam);\r
+            UpdateDefragInfo (Dlg);\r
+            return (1);\r
+\r
+        case WM_UPDATEINFO:\r
+            UpdateDefragInfo (Dlg);\r
+            return (1);\r
+    }\r
+\r
+    return (0);\r
+}\r
diff --git a/rosapps/fraginator/Defragment.cpp b/rosapps/fraginator/Defragment.cpp
new file mode 100644 (file)
index 0000000..2b989e0
--- /dev/null
@@ -0,0 +1,459 @@
+#include "Defragment.h"\r
+\r
+\r
+// Ahh yes I ripped this from my old Findupes project :)\r
+// Fits a path name, composed of a path (i.e. "c:\blah\blah\cha\cha") and a filename ("stuff.txt")\r
+// and fits it to a given length. If it has to truncate it will first truncate from the path,\r
+// substituting in periods. So you might end up with something like:\r
+// C:\Program Files\Micro...\Register.exe\r
+int FitName (char *destination, const char *path, const char *filename, uint32 totalWidth)\r
+{\r
+       uint32 pathLen=0;\r
+       uint32 fnLen=0;\r
+       uint32 halfTotLen=0;\r
+       uint32 len4fn=0;     /* number of chars remaining for filename after path is applied */\r
+       uint32 len4path=0;   /* number of chars for path before filename is applied          */\r
+       char fmtStrPath[20]="";\r
+       char fmtStrFile[20]="";\r
+       char fmtString[40]="";\r
+\r
+    /*\r
+       assert (destination != NULL);\r
+       assert (path != NULL);\r
+       assert (filename != NULL);\r
+       assert (totalWidth != 0);\r
+    */\r
+\r
+       pathLen = strlen(path);\r
+       fnLen = strlen(filename);\r
+       if (!(totalWidth % 2))\r
+               halfTotLen=totalWidth / 2;\r
+       else\r
+               halfTotLen=(totalWidth-1) / 2;  /* -1 because otherwise (halfTotLen*2) ==\r
+(totalWidth+1) which wouldn't be good */\r
+\r
+       /* determine how much width the path and filename each get */\r
+       if ( (pathLen >= halfTotLen) && (fnLen < halfTotLen) )\r
+       {\r
+               len4fn = fnLen;\r
+               len4path = (totalWidth - len4fn);\r
+       }\r
+\r
+       if ( (pathLen < halfTotLen) && (fnLen < halfTotLen) )\r
+       {\r
+               len4fn = fnLen;\r
+               len4path = pathLen;\r
+       }\r
+\r
+       if ( (pathLen >= halfTotLen) && (fnLen >= halfTotLen) )\r
+       {\r
+               len4fn = halfTotLen;\r
+               len4path = halfTotLen;\r
+       }\r
+\r
+       if ( (pathLen < halfTotLen) && (fnLen >= halfTotLen) )\r
+       {\r
+               len4path = pathLen;\r
+               len4fn = (totalWidth - len4path);\r
+       }\r
+       /* \r
+               if halfTotLen was adjusted above to avoid a rounding error, give the \r
+               extra char to the filename \r
+       */\r
+       if (halfTotLen < (totalWidth/2)) len4path++; \r
+\r
+       if (pathLen > len4path) sprintf (fmtStrPath, "%%.%ds...\\", len4path-4);\r
+       else\r
+               sprintf (fmtStrPath, "%%s");\r
+       \r
+       if (fnLen > len4fn)     sprintf (fmtStrFile, "%%.%ds...", len4fn-3);\r
+       else\r
+               sprintf (fmtStrFile, "%%s");\r
+\r
+       strcpy (fmtString, fmtStrPath);\r
+       strcat (fmtString, fmtStrFile);\r
+       /*sprintf (fmtString, "%s%s", fmtStrPath, fmtStrFile);*/\r
+       sprintf (destination, fmtString, path,filename);\r
+       \r
+       return (1);     \r
+}\r
+\r
+\r
+Defragment::Defragment (string Name, DefragType DefragMethod)\r
+{\r
+    Method = DefragMethod;\r
+    DoLimitLength = true;\r
+    Error = false;\r
+    Done = false;\r
+    PleaseStop = false;\r
+    PleasePause = false;\r
+    DriveName = Name;\r
+    StatusPercent = 0.0f;\r
+    LastBMPUpdate = GetTickCount ();\r
+\r
+    SetStatusString ("Opening volume " + Name);\r
+    if (!Volume.Open (Name))\r
+    {\r
+        SetStatusString ("Error opening volume " + Name);\r
+        Error = true;\r
+        Done = true;\r
+        StatusPercent = 100.0f;\r
+    }\r
+\r
+    return;\r
+}\r
+\r
+\r
+Defragment::~Defragment ()\r
+{\r
+    if (!IsDoneYet ())\r
+    {\r
+        Stop ();\r
+        while (!IsDoneYet()  &&  !HasError())\r
+        {\r
+            SetStatusString ("Waiting for thread to stop ...");\r
+            Sleep (150);\r
+        }\r
+    }\r
+\r
+    Volume.Close ();\r
+    return;\r
+}\r
+\r
+\r
+void Defragment::SetStatusString (string NewStatus)\r
+{\r
+    Lock ();\r
+    StatusString = NewStatus;\r
+    Unlock ();\r
+\r
+    return;\r
+}\r
+\r
+\r
+string Defragment::GetStatusString (void)\r
+{\r
+    string ReturnVal;\r
+\r
+    Lock ();\r
+    ReturnVal = StatusString;\r
+    Unlock ();\r
+\r
+    return (ReturnVal);\r
+}\r
+\r
+\r
+double Defragment::GetStatusPercent (void)\r
+{\r
+    return (StatusPercent);\r
+}\r
+\r
+\r
+bool Defragment::IsDoneYet (void)\r
+{\r
+    return (Done);\r
+}\r
+\r
+\r
+void Defragment::Start (void)\r
+{\r
+    uint32 i;\r
+    uint64 FirstFreeLCN;\r
+    uint64 TotalClusters;\r
+    uint64 ClustersProgress;\r
+    char PrintName[80];\r
+    int Width = 70;\r
+\r
+    if (Error)\r
+        goto DoneDefrag;\r
+\r
+    // First thing: build a file list.\r
+    SetStatusString ("Getting volume bitmap");\r
+    if (!Volume.GetBitmap())\r
+    {\r
+        SetStatusString ("Could not get volume " + DriveName + " bitmap");\r
+        Error = true;\r
+        goto DoneDefrag;\r
+    }\r
+\r
+    LastBMPUpdate = GetTickCount ();\r
+\r
+    if (PleaseStop)\r
+        goto DoneDefrag;\r
+\r
+    SetStatusString ("Obtaining volume geometry");\r
+    if (!Volume.ObtainInfo ())\r
+    {\r
+        SetStatusString ("Could not obtain volume " + DriveName + " geometry");\r
+        Error = true;\r
+        goto DoneDefrag;\r
+    }\r
+\r
+    if (PleaseStop)\r
+        goto DoneDefrag;\r
+\r
+    SetStatusString ("Building file database for volume " + DriveName);\r
+    if (!Volume.BuildFileList (PleaseStop, StatusPercent))\r
+    {\r
+        SetStatusString ("Could not build file database for volume " + DriveName);\r
+        Error = true;\r
+        goto DoneDefrag;\r
+    }\r
+\r
+    if (PleaseStop)\r
+        goto DoneDefrag;\r
+\r
+    SetStatusString ("Analyzing database for " + DriveName);\r
+    TotalClusters = 0;\r
+    for (i = 0; i < Volume.GetDBFileCount(); i++)\r
+    {\r
+        TotalClusters += Volume.GetDBFile(i).Clusters;\r
+    }\r
+\r
+    // Defragment!\r
+    ClustersProgress = 0;\r
+\r
+    // Find first free LCN for speedier searches ...\r
+    Volume.FindFreeRange (0, 1, FirstFreeLCN);\r
+\r
+    if (PleaseStop)\r
+        goto DoneDefrag;\r
+\r
+    // Analyze?\r
+    if (Method == DefragAnalyze)\r
+    {\r
+        uint32 j;\r
+\r
+        Report.RootPath = Volume.GetRootPath ();\r
+\r
+        Report.FraggedFiles.clear ();\r
+        Report.UnfraggedFiles.clear ();\r
+        Report.UnmovableFiles.clear ();\r
+\r
+        Report.FilesCount = Volume.GetDBFileCount () - Volume.GetDBDirCount ();\r
+        Report.DirsCount = Volume.GetDBDirCount ();\r
+        Report.DiskSizeBytes = Volume.GetVolumeInfo().TotalBytes;\r
+\r
+        Report.FilesSizeClusters = 0;\r
+        Report.FilesSlackBytes = 0;\r
+        Report.FilesSizeBytes = 0;\r
+        Report.FilesFragments = 0;\r
+\r
+        for (j = 0; j < Volume.GetDBFileCount(); j++)\r
+        {\r
+            FileInfo Info;\r
+\r
+            Info = Volume.GetDBFile (j);\r
+\r
+            Report.FilesFragments += max (1, Info.Fragments.size()); // add 1 fragment even for 0 bytes/0 cluster files\r
+\r
+            if (Info.Attributes.Process == 0)\r
+                continue;\r
+\r
+            SetStatusString (Volume.GetDBDir (Info.DirIndice) + Info.Name);\r
+\r
+            Report.FilesSizeClusters += Info.Clusters;\r
+            Report.FilesSizeBytes += Info.Size;\r
+\r
+            if (Info.Attributes.Unmovable == 1)\r
+                Report.UnmovableFiles.push_back (j);\r
+\r
+            if (Info.Fragments.size() > 1)\r
+                Report.FraggedFiles.push_back (j);\r
+            else\r
+                Report.UnfraggedFiles.push_back (j);\r
+\r
+            StatusPercent = ((double)j / (double)Report.FilesCount) * 100.0f;\r
+        }\r
+\r
+        Report.FilesSizeOnDisk = Report.FilesSizeClusters * (uint64)Volume.GetVolumeInfo().ClusterSize;\r
+        Report.FilesSlackBytes = Report.FilesSizeOnDisk - Report.FilesSizeBytes;\r
+        Report.AverageFragments = (double)Report.FilesFragments / (double)Report.FilesCount;\r
+        Report.PercentFragged = 100.0f * ((double)(signed)Report.FraggedFiles.size() / (double)(signed)Report.FilesCount);\r
+\r
+        uint64 Percent;\r
+        Percent = (10000 * Report.FilesSlackBytes) / Report.FilesSizeOnDisk;\r
+        Report.PercentSlack = (double)(signed)Percent / 100.0f;\r
+    }\r
+    else\r
+    // Go through all the files and ... defragment them!\r
+    for (i = 0; i < Volume.GetDBFileCount(); i++)\r
+    {\r
+        FileInfo Info;\r
+        bool Result;\r
+        uint64 TargetLCN;\r
+        uint64 PreviousClusters;\r
+\r
+        // What? They want us to pause? Oh ok.\r
+        if (PleasePause)\r
+        {\r
+            SetStatusString ("Paused");\r
+            PleasePause = false;\r
+\r
+            while (PleasePause == false)\r
+            {\r
+                Sleep (50);\r
+            }\r
+\r
+            PleasePause = false;\r
+        }\r
+\r
+        if (PleaseStop)\r
+        {\r
+            SetStatusString ("Stopping");\r
+            break;\r
+        }\r
+\r
+        // \r
+        Info = Volume.GetDBFile (i);\r
+\r
+        PreviousClusters = ClustersProgress;\r
+        ClustersProgress += Info.Clusters;\r
+\r
+        if (Info.Attributes.Process == 0)\r
+            continue;\r
+\r
+        if (!DoLimitLength)\r
+            SetStatusString (Volume.GetDBDir (Info.DirIndice) + Info.Name);\r
+        else\r
+        {\r
+            FitName (PrintName, Volume.GetDBDir (Info.DirIndice).c_str(), Info.Name.c_str(), Width);\r
+            SetStatusString (PrintName);\r
+        }\r
+\r
+        // Calculate percentage complete\r
+        StatusPercent = 100.0f * double((double)PreviousClusters / (double)TotalClusters);\r
+\r
+        // Can't defrag directories yet\r
+        if (Info.Attributes.Directory == 1)\r
+            continue;\r
+\r
+        // Can't defrag 0 byte files :)\r
+        if (Info.Fragments.size() == 0)\r
+            continue;\r
+\r
+        // If doing fast defrag, skip non-fragmented files\r
+        // Note: This assumes that the extents stored in Info.Fragments\r
+        //       are consolidated. I.e. we assume it is NOT the case that\r
+        //       two extents account for a sequential range of (non-\r
+        //       fragmented) clusters.\r
+        if (Info.Fragments.size() == 1  &&  Method == DefragFast)\r
+            continue;\r
+\r
+        // Otherwise, defrag0rize it!\r
+        int Retry = 3;  // retry a few times\r
+        while (Retry > 0)\r
+        {\r
+            // Find a place that can fit the file\r
+            Result = Volume.FindFreeRange (FirstFreeLCN, Info.Clusters, TargetLCN);\r
+\r
+            // If yes, try moving it\r
+            if (Result)\r
+            {\r
+                // If we're doing an extensive defrag and the file is already defragmented\r
+                // and if its new location would be after its current location, don't\r
+                // move it.\r
+                if (Method == DefragExtensive  &&  Info.Fragments.size() == 1  &&\r
+                    TargetLCN > Info.Fragments[0].StartLCN)\r
+                {\r
+                    Retry = 1;\r
+                }\r
+                else\r
+                {\r
+                    if (Volume.MoveFileDumb (i, TargetLCN))\r
+                    {\r
+                        Retry = 1; // yay, all done with this file.\r
+                        Volume.FindFreeRange (0, 1, FirstFreeLCN);\r
+                    }\r
+                }\r
+            }\r
\r
+            // New: Only update bitmap if it's older than 15 seconds\r
+            if ((GetTickCount() - LastBMPUpdate) < 15000)\r
+                Retry = 1;\r
+            else\r
+            if (!Result  ||  Retry != 1)\r
+            {   // hmm. Wait for a moment, then update the drive bitmap\r
+                //SetStatusString ("(Reobtaining volume " + DriveName + " bitmap)");\r
+\r
+                if (!DoLimitLength)\r
+                {\r
+                    SetStatusString (GetStatusString() + string (" ."));\r
+                }\r
+\r
+                if (Volume.GetBitmap ())\r
+                {\r
+                    LastBMPUpdate = GetTickCount ();\r
+\r
+                    if (!DoLimitLength)\r
+                        SetStatusString (Volume.GetDBDir (Info.DirIndice) + Info.Name);\r
+                    else\r
+                        SetStatusString (PrintName);\r
+\r
+                    Volume.FindFreeRange (0, 1, FirstFreeLCN);\r
+                }\r
+                else\r
+                {\r
+                    SetStatusString ("Could not re-obtain volume " + DriveName + " bitmap");\r
+                    Error = true;\r
+                }\r
+            }\r
+\r
+            Retry--;\r
+        }\r
+\r
+        if (Error == true)\r
+            break;\r
+    }\r
+\r
+DoneDefrag:\r
+    string OldStatus;\r
+\r
+    OldStatus = GetStatusString ();\r
+    StatusPercent = 99.999999f;\r
+    SetStatusString ("Closing volume " + DriveName);\r
+    Volume.Close ();\r
+    StatusPercent = 100.0f;\r
+\r
+    // If there was an error then the string has already been set\r
+    if (Error)\r
+        SetStatusString (OldStatus);\r
+    else\r
+    if (PleaseStop)\r
+        SetStatusString ("Volume " + DriveName + " defragmentation was stopped");\r
+    else\r
+        SetStatusString ("Finished defragmenting " + DriveName);\r
+\r
+    Done = true;\r
+\r
+    return;\r
+}\r
+\r
+\r
+void Defragment::TogglePause (void)\r
+{\r
+    Lock ();\r
+    SetStatusString ("Pausing ...");\r
+    PleasePause = true;\r
+    Unlock ();\r
+\r
+    return;\r
+}\r
+\r
+\r
+void Defragment::Stop (void)\r
+{\r
+    Lock ();\r
+    SetStatusString ("Stopping ...");\r
+    PleaseStop = true;\r
+    Unlock ();\r
+\r
+    return;\r
+}\r
+\r
+\r
+bool Defragment::HasError (void)\r
+{\r
+    return (Error);\r
+}\r
+\r
diff --git a/rosapps/fraginator/Defragment.h b/rosapps/fraginator/Defragment.h
new file mode 100644 (file)
index 0000000..f814234
--- /dev/null
@@ -0,0 +1,92 @@
+/*****************************************************************************\r
+\r
+  Defragment\r
+\r
+*****************************************************************************/\r
+\r
+\r
+#ifndef DEFRAGMENT_H\r
+#define DEFRAGMENT_H\r
+\r
+\r
+#include "Unfrag.h"\r
+#include "DriveVolume.h"\r
+#include "Mutex.h"\r
+\r
+\r
+extern int FitName (char *destination, const char *path, const char *filename, uint32 totalWidth);\r
+\r
+\r
+typedef struct DefragReport\r
+{\r
+    string    RootPath;\r
+    uint64    DiskSizeBytes;\r
+    uint64    DirsCount;\r
+    uint64    FilesCount;\r
+    uint64    FilesSizeBytes;\r
+    uint64    FilesSizeOnDisk;\r
+    uint64    FilesSizeClusters;\r
+    uint64    FilesSlackBytes;\r
+    uint32    FilesFragments;\r
+    double    AverageFragments;  // = FilesFragments / FilesCount\r
+    double    PercentFragged;\r
+    double    PercentSlack;\r
+\r
+    vector<uint32> FraggedFiles;\r
+    vector<uint32> UnfraggedFiles;\r
+    vector<uint32> UnmovableFiles;\r
+} DefragReport;\r
+\r
+\r
+class Defragment\r
+{\r
+public:\r
+    Defragment (string Name, DefragType DefragMethod);\r
+    ~Defragment ();\r
+\r
+    // Commands\r
+    void Start       (void);\r
+    void TogglePause (void);\r
+    void Stop        (void);\r
+\r
+    // Info\r
+    bool          IsDoneYet (void);\r
+    bool          HasError (void);\r
+    string        GetStatusString  (void);\r
+    double         GetStatusPercent (void);\r
+    DefragType    GetDefragType    (void)  { return (Method); }\r
+    DefragReport &GetDefragReport  (void)  { return (Report); }\r
+    DriveVolume  &GetVolume        (void)  { return (Volume); }\r
+\r
+    // Mutex\r
+    void Lock (void)   { DefragMutex.Lock ();   }\r
+    void Unlock (void) { DefragMutex.Unlock (); }\r
+\r
+    // Limit length of status string to 70 chars?\r
+    bool GetDoLimitLength (void)   { return (DoLimitLength); }\r
+    void SetDoLimitLength (bool L) { DoLimitLength = L; }\r
+\r
+private:\r
+    void FastDefrag (void);\r
+    void ExtensiveDefrag (void);\r
+    void SetStatusString (string NewStatus);\r
+\r
+    DWORD        LastBMPUpdate; // Last time volume bitmap was updated\r
+    DefragReport Report;\r
+    bool         DoLimitLength;\r
+    DefragType   Method;\r
+    string       DriveName;\r
+    DriveVolume  Volume;\r
+    string       StatusString;\r
+    string       ErrorString;\r
+    double        StatusPercent;\r
+    Mutex        DefragMutex;\r
+    bool         Error;\r
+    bool         Done;\r
+    bool         PleaseStop;\r
+    bool         PleasePause;\r
+    DefragType   DefragMethod;\r
+};\r
+\r
+\r
+#endif // DEFRAGMENT_H\r
diff --git a/rosapps/fraginator/DriveVolume.cpp b/rosapps/fraginator/DriveVolume.cpp
new file mode 100644 (file)
index 0000000..6845ef4
--- /dev/null
@@ -0,0 +1,806 @@
+#include "DriveVolume.h"\r
+\r
+\r
+DriveVolume::DriveVolume ()\r
+{\r
+    Handle = INVALID_HANDLE_VALUE;\r
+    BitmapDetail = NULL;\r
+    return;\r
+}\r
+\r
+\r
+DriveVolume::~DriveVolume ()\r
+{\r
+    Close ();\r
+    Directories.clear ();\r
+    Files.clear ();\r
+    return;\r
+}\r
+\r
+\r
+void DriveVolume::Close (void)\r
+{\r
+    if (Handle != INVALID_HANDLE_VALUE)\r
+    {\r
+        CloseHandle (Handle);\r
+        Handle = INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    if (BitmapDetail != NULL)\r
+    {\r
+        free (BitmapDetail);\r
+        BitmapDetail = NULL;\r
+    }\r
+\r
+    return;\r
+}\r
+\r
+\r
+// "Name" should be the drive letter followed by a colon. ie, "c:"\r
+// It's a string to allow for further expansion (ie, defragging over the network?)\r
+// or some other baloney reason\r
+bool DriveVolume::Open (string Name)\r
+{\r
+    char FileName[100];\r
+    bool ReturnVal;\r
+\r
+    sprintf (FileName, "\\\\.\\%s", Name.c_str());\r
+    RootPath = Name.c_str();\r
+    RootPath += "\\";\r
+\r
+    Handle = CreateFile \r
+    (\r
+        FileName,\r
+        MAXIMUM_ALLOWED,                          // access\r
+        FILE_SHARE_READ | FILE_SHARE_WRITE,       // share type\r
+        NULL,                                     // security descriptor\r
+        OPEN_EXISTING,                            // open type\r
+        NULL,                                     // attributes (none)\r
+        NULL                                      // template\r
+    );\r
+\r
+    if (Handle == INVALID_HANDLE_VALUE)\r
+        ReturnVal = false;\r
+    else\r
+    {\r
+        char  VolName[64];\r
+        DWORD VolSN;\r
+        DWORD VolMaxFileLen;\r
+        DWORD FSFlags;\r
+        char  FSName[64];\r
+        BOOL  Result;\r
+\r
+        ReturnVal = true;\r
+        Result = GetVolumeInformation\r
+        (\r
+            RootPath.c_str(),\r
+            VolName,\r
+            sizeof (VolName),\r
+            &VolSN,\r
+            &VolMaxFileLen,\r
+            &FSFlags,\r
+            FSName,\r
+            sizeof (FSName)\r
+        );\r
+\r
+        if (Result)\r
+        {\r
+            char SerialText[10];\r
+\r
+            VolInfo.FileSystem = FSName;\r
+            VolInfo.MaxNameLen = VolMaxFileLen;\r
+            VolInfo.Name       = VolName;\r
+\r
+            sprintf (SerialText, "%x-%x", (VolSN & 0xffff0000) >> 16, \r
+                VolSN & 0x0000ffff);\r
+\r
+            strupr (SerialText);\r
+            VolInfo.Serial     = SerialText;\r
+        }\r
+        else\r
+        {\r
+            VolInfo.FileSystem = "(Unknown)";\r
+            VolInfo.MaxNameLen = 255;\r
+            VolInfo.Name       = "(Unknown)";\r
+            VolInfo.Serial     = "(Unknown)";\r
+        }\r
+    }\r
+\r
+    return (ReturnVal);\r
+}\r
+\r
+\r
+bool DriveVolume::ObtainInfo (void)\r
+{\r
+    BOOL Result;\r
+    DWORD BytesGot;\r
+    uint64 nan;\r
+\r
+    BytesGot = 0;\r
+    ZeroMemory (&Geometry, sizeof (Geometry));\r
+    Result = DeviceIoControl\r
+    (\r
+        Handle,\r
+        IOCTL_DISK_GET_DRIVE_GEOMETRY,\r
+        NULL,\r
+        0,\r
+        &Geometry,\r
+        sizeof (Geometry),\r
+        &BytesGot,\r
+        NULL\r
+    );\r
+\r
+    // Call failed? Aww :(\r
+    if (!Result)\r
+        return (false);\r
+\r
+    // Get cluster size\r
+    DWORD SectorsPerCluster;\r
+    DWORD BytesPerSector;\r
+    DWORD FreeClusters;\r
+    DWORD TotalClusters;\r
+\r
+    Result = GetDiskFreeSpace\r
+    (\r
+        RootPath.c_str(),\r
+        &SectorsPerCluster,\r
+        &BytesPerSector,\r
+        &FreeClusters,\r
+        &TotalClusters\r
+    );\r
+\r
+    // Failed? Weird.\r
+    if (!Result)\r
+        return (false);\r
+\r
+    VolInfo.ClusterSize = SectorsPerCluster * BytesPerSector;        \r
+\r
+    Result = GetDiskFreeSpaceEx\r
+    (\r
+        RootPath.c_str(),\r
+        (PULARGE_INTEGER)&nan,\r
+        (PULARGE_INTEGER)&VolInfo.TotalBytes,\r
+        (PULARGE_INTEGER)&VolInfo.FreeBytes\r
+    );\r
+\r
+    return (true);\r
+}\r
+\r
+\r
+// Get bitmap, several clusters at a time ...\r
+#define CLUSTERS 4096\r
+bool DriveVolume::GetBitmap (void)\r
+{\r
+    STARTING_LCN_INPUT_BUFFER StartingLCN;\r
+    VOLUME_BITMAP_BUFFER *Bitmap = NULL;\r
+    uint32 BitmapSize;\r
+    DWORD BytesReturned;\r
+    BOOL Result;\r
+\r
+    StartingLCN.StartingLcn.QuadPart = 0;\r
+\r
+    // Allocate buffer\r
+    // Call FSCTL_GET_VOLUME_BITMAP once with a very small buffer\r
+    // This will leave the total number of clusters in Bitmap->BitmapSize and we can\r
+    // then correctly allocate based off that\r
+    // I suppose this won't work if your drive has only 40 clusters on it or so :)\r
+    BitmapSize = sizeof (VOLUME_BITMAP_BUFFER) + 4;\r
+    Bitmap = (VOLUME_BITMAP_BUFFER *) malloc (BitmapSize);\r
+\r
+    Result = DeviceIoControl\r
+    (\r
+        Handle,\r
+        FSCTL_GET_VOLUME_BITMAP,\r
+        &StartingLCN,\r
+        sizeof (StartingLCN),\r
+        Bitmap,\r
+        BitmapSize,\r
+        &BytesReturned,\r
+        NULL\r
+    );\r
+\r
+    // Bad result?\r
+    if (Result == FALSE  &&  GetLastError () != ERROR_MORE_DATA)\r
+    {\r
+        //printf ("\nDeviceIoControl returned false, GetLastError() was not ERROR_MORE_DATA\n");\r
+        free (Bitmap);\r
+        return (false);\r
+    }\r
+\r
+    // Otherwise, we're good\r
+    BitmapSize = sizeof (VOLUME_BITMAP_BUFFER) + (Bitmap->BitmapSize.QuadPart / 8) + 1;\r
+    Bitmap = (VOLUME_BITMAP_BUFFER *) realloc (Bitmap, BitmapSize);\r
+    Result = DeviceIoControl\r
+    (\r
+        Handle,\r
+        FSCTL_GET_VOLUME_BITMAP,\r
+        &StartingLCN,\r
+        sizeof (StartingLCN),\r
+        Bitmap,\r
+        BitmapSize,\r
+        &BytesReturned,\r
+        NULL\r
+    );\r
+\r
+    DWORD LastError = GetLastError ();\r
+\r
+    if (Result == FALSE)\r
+    {\r
+        printf ("\nCouldn't properly read volume bitmap\n");\r
+        free (Bitmap);\r
+        return (false);\r
+    }\r
+\r
+    // Convert to a 'quick use' bitmap\r
+    //const int BitShift[] = { 1, 2, 4, 8, 16, 32, 64, 128 };\r
+\r
+    VolInfo.ClusterCount = Bitmap->BitmapSize.QuadPart;\r
+\r
+    if (BitmapDetail != NULL)\r
+        free (BitmapDetail);\r
+\r
+    BitmapDetail = (uint32 *) malloc (sizeof(uint32) * (1 + (VolInfo.ClusterCount / 32)));\r
+    memcpy (BitmapDetail, Bitmap->Buffer, sizeof(uint32) * (1 + (VolInfo.ClusterCount / 32)));\r
+\r
+    /*\r
+    BitmapDetail = (Cluster *) malloc (VolInfo.ClusterCount * sizeof (Cluster));\r
+    for (uint64 i = 0; i < VolInfo.ClusterCount; i++)\r
+    {\r
+        if (Bitmap->Buffer[i / 8] & BitShift[i % 8])\r
+            BitmapDetail[i].Allocated = true;\r
+        else\r
+            BitmapDetail[i].Allocated = false;\r
+    }\r
+    */\r
+\r
+    free (Bitmap);\r
+    return (true);\r
+}\r
+\r
+\r
+bool DriveVolume::IsClusterUsed (uint64 Cluster)\r
+{\r
+    return ((BitmapDetail[Cluster / 32] & (1 << (Cluster % 32))) ? true : false);\r
+    //return (BitmapDetail[Cluster].Allocated);\r
+}\r
+\r
+\r
+void DriveVolume::SetClusterUsed (uint64 Cluster, bool Used)\r
+{\r
+    if (Used)\r
+        BitmapDetail[Cluster / 32] |= (1 << (Cluster % 32));\r
+    else\r
+        BitmapDetail[Cluster / 32] &= ~(1 << (Cluster % 32));\r
+\r
+    return;\r
+}\r
+\r
+\r
+typedef struct\r
+{\r
+    DriveVolume *Volume;\r
+    double       *Percent;\r
+    bool        *QuitMonitor;\r
+    uint64       ClusterCount;\r
+    uint64       ClusterProgress;\r
+} BuildDBInfo;\r
+\r
+\r
+bool DriveVolume::BuildFileList (bool &QuitMonitor, double &Percent)\r
+{\r
+    BuildDBInfo Info;\r
+\r
+    Files.clear ();\r
+    Directories.clear ();\r
+    Directories.push_back (RootPath);\r
+\r
+    Info.Volume = this;\r
+    Info.QuitMonitor = &QuitMonitor;\r
+    Info.ClusterCount = (GetVolumeInfo().TotalBytes - GetVolumeInfo().FreeBytes) / (uint64)GetVolumeInfo().ClusterSize;\r
+    Info.ClusterProgress = 0;\r
+    Info.Percent = &Percent;\r
+\r
+    ScanDirectory (RootPath, BuildDBCallback, &Info);\r
+\r
+    if (QuitMonitor == true)\r
+    {\r
+        Directories.resize (0);\r
+        Files.resize (0);\r
+    }\r
+\r
+    return (true);\r
+}\r
+\r
+\r
+// UserData = pointer to BuildDBInfo instance\r
+bool BuildDBCallback (FileInfo &Info, HANDLE &FileHandle, void *UserData)\r
+{\r
+    BuildDBInfo *DBInfo = (BuildDBInfo *) UserData;\r
+    DriveVolume *Vol = DBInfo->Volume;\r
+\r
+    Vol->Files.push_back (Info);\r
+\r
+    if (*(DBInfo->QuitMonitor) == true)\r
+        return (false);\r
+\r
+    DBInfo->ClusterProgress += (uint64)Info.Clusters;\r
+    *(DBInfo->Percent) = \r
+        ((double)DBInfo->ClusterProgress / (double)DBInfo->ClusterCount) * 100.0f;\r
+\r
+    return (true);\r
+}\r
+\r
+\r
+string &DriveVolume::GetDBDir (uint32 Indice)\r
+{\r
+    return (Directories[Indice]);\r
+}\r
+\r
+\r
+uint32 DriveVolume::GetDBDirCount (void)\r
+{\r
+    return (Directories.size());\r
+}\r
+\r
+\r
+FileInfo &DriveVolume::GetDBFile (uint32 Indice)\r
+{\r
+    return (Files[Indice]);\r
+}\r
+\r
+\r
+uint32 DriveVolume::GetDBFileCount (void)\r
+{\r
+    return (Files.size());\r
+}\r
+\r
+\r
+uint32 DriveVolume::RemoveDBFile (uint32 Indice)\r
+{\r
+    vector<FileInfo>::iterator it;\r
+\r
+    it = Files.begin() + Indice;\r
+    Files.erase (it);\r
+    return (GetDBFileCount());\r
+}\r
+\r
+\r
+bool DriveVolume::ScanDirectory (string DirPrefix, ScanCallback Callback, void *UserData)\r
+{\r
+    WIN32_FIND_DATA FindData;\r
+    HANDLE          FindHandle;\r
+    string          SearchString;\r
+    uint32          DirIndice;\r
+\r
+    DirIndice = Directories.size() - 1;\r
+\r
+    SearchString = DirPrefix;\r
+    SearchString += "*.*";\r
+    ZeroMemory (&FindData, sizeof (FindData));\r
+    FindHandle = FindFirstFile (SearchString.c_str(), &FindData);\r
+\r
+    if (FindHandle == INVALID_HANDLE_VALUE)\r
+        return (false);\r
+\r
+    do\r
+    {\r
+        FileInfo Info;\r
+        HANDLE   Handle;\r
+        bool     CallbackResult;\r
+\r
+        Handle = INVALID_HANDLE_VALUE;\r
+\r
+        // First copy over the easy stuff.\r
+        Info.Name = FindData.cFileName;\r
+\r
+        // Don't ever include '.' and '..'\r
+        if (Info.Name == "."  ||  Info.Name == "..")\r
+            continue;\r
+\r
+        //Info.FullName = DirPrefix + Info.Name;\r
+        Info.Size      = (uint64)FindData.nFileSizeLow + ((uint64)FindData.nFileSizeHigh << (uint64)32);\r
+        Info.DirIndice = DirIndice;\r
+\r
+        Info.Attributes.Archive    = (FindData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)       ? 1 : 0;\r
+        Info.Attributes.Compressed = (FindData.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)    ? 1 : 0;\r
+        Info.Attributes.Directory  = (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)     ? 1 : 0;\r
+        Info.Attributes.Encrypted  = (FindData.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED)     ? 1 : 0;\r
+        Info.Attributes.Hidden     = (FindData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)        ? 1 : 0;\r
+        Info.Attributes.Normal     = (FindData.dwFileAttributes & FILE_ATTRIBUTE_NORMAL)        ? 1 : 0;\r
+        Info.Attributes.Offline    = (FindData.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE)       ? 1 : 0;\r
+        Info.Attributes.ReadOnly   = (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)      ? 1 : 0;\r
+        Info.Attributes.Reparse    = (FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ? 1 : 0;\r
+        Info.Attributes.Sparse     = (FindData.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE)   ? 1 : 0;\r
+        Info.Attributes.System     = (FindData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)        ? 1 : 0;\r
+        Info.Attributes.Temporary  = (FindData.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)     ? 1 : 0;\r
+        Info.Attributes.AccessDenied = 0;\r
+        Info.Attributes.Unmovable    = 0;\r
+        Info.Attributes.Process      = 1;\r
+\r
+        Info.Clusters = 0;\r
+        if (GetClusterInfo (Info, Handle))\r
+        {\r
+            uint64 TotalClusters = 0;\r
+\r
+            for (int i = 0; i < Info.Fragments.size(); i++)\r
+            {\r
+                TotalClusters += Info.Fragments[i].Length;\r
+            }\r
+\r
+            Info.Clusters = TotalClusters;\r
+        }\r
+        else\r
+        {\r
+            Info.Attributes.Unmovable = 1;\r
+            Info.Attributes.Process = 0;\r
+        }\r
+\r
+        if (Info.Attributes.Process == 1)\r
+            Info.Attributes.Process = ShouldProcess (Info.Attributes) ? 1 : 0;\r
+\r
+        // Run the user-defined callback function\r
+        CallbackResult = Callback (Info, Handle, UserData);\r
+\r
+        if (Handle != INVALID_HANDLE_VALUE)\r
+            CloseHandle (Handle);\r
+\r
+        if (!CallbackResult)\r
+            break;\r
+\r
+        // If directory, perform recursion\r
+        if (Info.Attributes.Directory == 1)\r
+        {\r
+            string Dir;\r
+\r
+            Dir = GetDBDir (Info.DirIndice);\r
+            Dir += Info.Name;\r
+            Dir += "\\";\r
+\r
+            Directories.push_back (Dir);\r
+            ScanDirectory (Dir, Callback, UserData);\r
+        }\r
+\r
+    } while (FindNextFile (FindHandle, &FindData) == TRUE);\r
+\r
+    FindClose (FindHandle);\r
+    return (false);\r
+}\r
+\r
+\r
+bool DriveVolume::ShouldProcess (FileAttr Attr)\r
+{\r
+    if (Attr.Offline == 1  ||  Attr.Reparse == 1  ||  Attr.Temporary == 1)\r
+    {\r
+        return (false);\r
+    }\r
+\r
+    return (true);\r
+}\r
+\r
+\r
+// Gets info on a file and returns a valid handle for read/write access\r
+// Name, FullName, Clusters, Attributes, and Size should already be filled out.\r
+// This function fills in the Fragments vector\r
+bool DriveVolume::GetClusterInfo (FileInfo &Info, HANDLE &HandleResult)\r
+{\r
+    BOOL     Result;\r
+    HANDLE   Handle;\r
+    string   FullName;\r
+    BY_HANDLE_FILE_INFORMATION FileInfo;\r
+\r
+    Info.Fragments.resize (0);\r
+\r
+    /*\r
+    if (Info.Attributes.Directory == 1)\r
+        return (false);\r
+    */\r
+\r
+    FullName = GetDBDir (Info.DirIndice) + Info.Name;\r
+\r
+    Handle = CreateFile\r
+    (\r
+        FullName.c_str(),\r
+        0, //GENERIC_READ,\r
+        FILE_SHARE_READ,\r
+        NULL,\r
+        OPEN_EXISTING,\r
+        (Info.Attributes.Directory == 1) ? FILE_FLAG_BACKUP_SEMANTICS : 0,\r
+        NULL\r
+    );\r
+\r
+    if (Handle == INVALID_HANDLE_VALUE)\r
+    {\r
+           LPVOID lpMsgBuf;\r
\r
+           FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,\r
+                                           NULL, GetLastError(), \r
+                                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
+                                           (LPTSTR) &lpMsgBuf, 0, NULL );\r
+           \r
+\r
+        Info.Attributes.AccessDenied = 1;\r
+           LocalFree( lpMsgBuf );\r
+        return (false);\r
+    }\r
+\r
+    ZeroMemory (&FileInfo, sizeof (FileInfo));\r
+    Result = GetFileInformationByHandle (Handle, &FileInfo);\r
+\r
+    if (Result == FALSE)\r
+    {\r
+        Info.Attributes.AccessDenied = 1;\r
+        printf ("GetFileInformationByHandle ('%s%s') failed\n", GetDBDir (Info.DirIndice).c_str(), \r
+            Info.Name.c_str());\r
+\r
+        CloseHandle (Handle);\r
+        return (false);\r
+    }\r
+\r
+    // Get cluster allocation information\r
+    STARTING_VCN_INPUT_BUFFER  StartingVCN;\r
+    RETRIEVAL_POINTERS_BUFFER *Retrieval;\r
+    uint64                     RetSize;\r
+    uint64                     Extents;\r
+    DWORD                      BytesReturned;\r
+\r
+    // Grab info one extent at a time, until it's done grabbing all the extent data\r
+    // Yeah, well it doesn't give us a way to ask "how many extents?" that I know of ...\r
+    // btw, the Extents variable tends to only reflect memory usage, so when we have\r
+    // all the extents we look at the structure Win32 gives us for the REAL count!\r
+    Extents = 10;\r
+    Retrieval = NULL;\r
+    RetSize = 0;\r
+    StartingVCN.StartingVcn.QuadPart = 0;\r
+\r
+    do\r
+    {\r
+        Extents *= 2;\r
+        RetSize = sizeof (RETRIEVAL_POINTERS_BUFFER) + ((Extents - 1) * sizeof (LARGE_INTEGER) * 2);\r
+\r
+        if (Retrieval != NULL)\r
+            Retrieval = (RETRIEVAL_POINTERS_BUFFER *) realloc (Retrieval, RetSize);\r
+        else\r
+            Retrieval = (RETRIEVAL_POINTERS_BUFFER *) malloc (RetSize);\r
+\r
+        Result = DeviceIoControl\r
+        (\r
+            Handle,\r
+            FSCTL_GET_RETRIEVAL_POINTERS,\r
+            &StartingVCN,\r
+            sizeof (StartingVCN),\r
+            Retrieval,\r
+            RetSize,\r
+            &BytesReturned,\r
+            NULL\r
+        );\r
+\r
+        if (Result == FALSE)\r
+        {\r
+            if (GetLastError() != ERROR_MORE_DATA)\r
+            {\r
+                Info.Clusters = 0;\r
+                Info.Attributes.AccessDenied = 1;\r
+                Info.Attributes.Process = 0;\r
+                Info.Fragments.clear ();\r
+                CloseHandle (Handle);\r
+                free (Retrieval);\r
+\r
+                return (false);\r
+            }\r
+\r
+            Extents++;\r
+        }\r
+    } while (Result == FALSE);\r
+\r
+    // Readjust extents, as it only reflects how much memory was allocated and may not\r
+    // be accurate\r
+    Extents = Retrieval->ExtentCount;\r
+\r
+    // Ok, we have the info. Now translate it. hrmrmr\r
+    int i;\r
+    Info.Fragments.clear ();\r
+    for (i = 0; i < Extents; i++)\r
+    {\r
+        Extent Add;\r
+\r
+        Add.StartLCN = Retrieval->Extents[i].Lcn.QuadPart;\r
+        if (i != 0)\r
+            Add.Length = Retrieval->Extents[i].NextVcn.QuadPart - Retrieval->Extents[i - 1].NextVcn.QuadPart;\r
+        else\r
+            Add.Length = Retrieval->Extents[i].NextVcn.QuadPart - Retrieval->StartingVcn.QuadPart;\r
+\r
+        Info.Fragments.push_back (Add);\r
+    }\r
+\r
+    free (Retrieval);\r
+    HandleResult = Handle;\r
+    return (true);\r
+}\r
+\r
+\r
+bool DriveVolume::FindFreeRange (uint64 StartLCN, uint64 ReqLength, uint64 &LCNResult)\r
+{\r
+    uint64 Max;\r
+    uint64 i;\r
+    uint64 j;\r
+\r
+    // Make sure we don't spill over our array\r
+    Max = VolInfo.ClusterCount - ReqLength;\r
+\r
+    for (i = StartLCN; i < Max; i++)\r
+    {\r
+        bool Found = true;\r
+\r
+        // First check the first cluster\r
+        if (IsClusterUsed (i))\r
+            Found = false;\r
+        else\r
+        // THen check the last cluster\r
+        if (IsClusterUsed (i + ReqLength - 1))\r
+            Found = false;\r
+        else\r
+        // Check the whole darn range.\r
+        for (j = (i + 1); j < (i + ReqLength - 2); j++)\r
+        {\r
+            if (IsClusterUsed (j) == true)\r
+            {\r
+                Found = false;\r
+                break;\r
+            }\r
+        }\r
+\r
+        if (!Found)\r
+            continue;\r
+        else\r
+        {\r
+            LCNResult = i;\r
+            return (true);\r
+        }\r
+    }\r
+\r
+    return (false);\r
+}\r
+\r
+\r
+// btw we have to move each fragment of the file, as per the Win32 API\r
+bool DriveVolume::MoveFileDumb (uint32 FileIndice, uint64 NewLCN)\r
+{\r
+    bool ReturnVal = false;\r
+    FileInfo Info;\r
+    HANDLE FileHandle;\r
+    string FullName;\r
+    MOVE_FILE_DATA MoveData;\r
+    uint64 CurrentLCN;\r
+    uint64 CurrentVCN;\r
+\r
+    // Set up variables\r
+    Info = GetDBFile (FileIndice);\r
+    FullName = GetDBDir (Info.DirIndice);\r
+    FullName += Info.Name;\r
+    CurrentLCN = NewLCN;\r
+    CurrentVCN = 0;\r
+\r
+    /*\r
+    if (Info.Attributes.Directory == 1)\r
+    {\r
+        //\r
+    }\r
+    */\r
+\r
+    // Open file\r
+    FileHandle = CreateFile\r
+    (\r
+        FullName.c_str (),\r
+        GENERIC_READ,\r
+        FILE_SHARE_READ,\r
+        NULL,\r
+        OPEN_EXISTING,\r
+        (Info.Attributes.Directory == 1) ? FILE_FLAG_BACKUP_SEMANTICS : 0,\r
+        NULL\r
+    );\r
+\r
+    if (FileHandle == INVALID_HANDLE_VALUE)\r
+    {\r
+        //\r
+           LPVOID lpMsgBuf;\r
+\r
+           FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,\r
+                                           NULL, GetLastError(), \r
+                                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
+                                           (LPTSTR) &lpMsgBuf, 0, NULL );\r
+           \r
+\r
+           LocalFree (lpMsgBuf);\r
+        //\r
+\r
+        ReturnVal = false;\r
+    }\r
+    else\r
+    {\r
+        ReturnVal = true; // innocent until proven guilty ...\r
+\r
+        for (uint32 i = 0; i < Info.Fragments.size(); i++)\r
+        {\r
+            BOOL Result;\r
+            DWORD BytesReturned;\r
+\r
+            //printf ("%3u", i);\r
+\r
+            MoveData.ClusterCount = Info.Fragments[i].Length;\r
+            MoveData.StartingLcn.QuadPart = CurrentLCN;\r
+            MoveData.StartingVcn.QuadPart = CurrentVCN;\r
+\r
+            MoveData.FileHandle = FileHandle;\r
+\r
+            /*\r
+            printf ("\n");\r
+            printf ("StartLCN: %I64u\n", MoveData.StartingLcn.QuadPart);\r
+            printf ("StartVCN: %I64u\n", MoveData.StartingVcn.QuadPart);\r
+            printf ("Clusters: %u (%I64u-%I64u --> %I64u-%I64u)\n", MoveData.ClusterCount,\r
+                Info.Fragments[i].StartLCN,\r
+                Info.Fragments[i].StartLCN + MoveData.ClusterCount,\r
+                MoveData.StartingLcn.QuadPart,\r
+                MoveData.StartingLcn.QuadPart + MoveData.ClusterCount - 1);\r
+            printf ("\n");\r
+            */\r
+\r
+            Result = DeviceIoControl\r
+            (\r
+                Handle,\r
+                FSCTL_MOVE_FILE,\r
+                &MoveData,\r
+                sizeof (MoveData),\r
+                NULL,\r
+                0,\r
+                &BytesReturned,\r
+                NULL\r
+            );\r
+\r
+            //printf ("\b\b\b");\r
+\r
+            if (Result == FALSE)\r
+            {\r
+                //\r
+                   LPVOID lpMsgBuf;\r
\r
+                   FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,\r
+                                                   NULL, GetLastError(), \r
+                                                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
+                                                   (LPTSTR) &lpMsgBuf, 0, NULL );\r
+                   \r
+\r
+                   LocalFree( lpMsgBuf );\r
+                //\r
+\r
+                ReturnVal = false;\r
+                goto FinishUp;  // yeah, bite me\r
+            }\r
+\r
+            // Ok good. Now update our drive bitmap and file infos.\r
+            uint64 j;\r
+            for (j = 0; \r
+                 j < Info.Fragments[i].Length;\r
+                 j++)\r
+            {\r
+                SetClusterUsed (Info.Fragments[i].StartLCN + j, false);\r
+                SetClusterUsed (CurrentLCN + j, true);\r
+                //BitmapDetail[Info.Fragments[i].StartLCN + j].Allocated = false;\r
+                //BitmapDetail[CurrentLCN + j].Allocated = true;\r
+            }\r
+\r
+            CurrentLCN += Info.Fragments[i].Length;\r
+            CurrentVCN += Info.Fragments[i].Length;\r
+        }\r
+\r
+        // Update file info either way\r
+    FinishUp:\r
+        CloseHandle (FileHandle);\r
+        FileHandle = INVALID_HANDLE_VALUE;\r
+        GetClusterInfo (Files[FileIndice], FileHandle);\r
+        CloseHandle (FileHandle);\r
+    }\r
+\r
+    return (ReturnVal);\r
+}\r
+\r
+\r
diff --git a/rosapps/fraginator/DriveVolume.h b/rosapps/fraginator/DriveVolume.h
new file mode 100644 (file)
index 0000000..ea9fad0
--- /dev/null
@@ -0,0 +1,157 @@
+/*****************************************************************************\r
+\r
+  DriveVolume\r
+\r
+  Class for opening a volume and getting information on it and defragging it\r
+  and stuff.\r
+\r
+*****************************************************************************/\r
+\r
+\r
+#ifndef DRIVEVOLUME_H\r
+#define DRIVEVOLUME_H\r
+\r
+\r
+#include "Unfrag.h"\r
+#include <vector>\r
+#include <string>\r
+\r
+\r
+using namespace std;\r
+\r
+#pragma pack (push, 1)\r
+typedef struct\r
+{\r
+    unsigned int Archive    : 1;\r
+    unsigned int Compressed : 1;\r
+    unsigned int Directory  : 1;\r
+    unsigned int Encrypted  : 1;\r
+    unsigned int Hidden     : 1;\r
+    unsigned int Normal     : 1;\r
+    unsigned int Offline    : 1;\r
+    unsigned int ReadOnly   : 1;\r
+    unsigned int Reparse    : 1;\r
+    unsigned int Sparse     : 1;\r
+    unsigned int System     : 1;\r
+    unsigned int Temporary  : 1;\r
+\r
+    // For defragmenting purposes and other information\r
+    unsigned int Unmovable    : 1;  // can we even touch it?\r
+    unsigned int Process      : 1;  // should we process it?\r
+    unsigned int AccessDenied : 1;  // could we not open it?\r
+} FileAttr;\r
+\r
+\r
+typedef struct\r
+{\r
+    uint64 StartLCN;\r
+    uint64 Length;\r
+} Extent;\r
+\r
+\r
+typedef struct\r
+{\r
+    string   Name;\r
+    uint32   DirIndice;   // indice into directory list\r
+    uint64   Size;\r
+    uint64   Clusters;\r
+    FileAttr Attributes;\r
+    vector<Extent> Fragments;\r
+} FileInfo;\r
+\r
+\r
+typedef vector<FileInfo> FileList;\r
+\r
+\r
+typedef struct\r
+{\r
+    string Name;\r
+    string Serial;\r
+    DWORD  MaxNameLen;\r
+    string FileSystem;\r
+    uint64 ClusterCount;\r
+    uint32 ClusterSize;\r
+    uint64 TotalBytes;\r
+    uint64 FreeBytes;\r
+} VolumeInfo;\r
+#pragma pack (pop)\r
+\r
+\r
+// Callback function for Scan()\r
+// NOTE: Do *NOT* close the HANDLE given to you. It is provided for convenience,\r
+// and is closed automatically by the function that calls you!\r
+typedef bool (*ScanCallback) (FileInfo &Info, HANDLE &FileHandle, void *UserData);\r
+\r
+\r
+extern bool BuildDBCallback (FileInfo &Info, HANDLE &FileHandle, void *UserData);\r
+\r
+\r
+class DriveVolume\r
+{\r
+public:\r
+    DriveVolume ();\r
+    ~DriveVolume ();\r
+\r
+    bool Open            (string Name);  // opens the volume\r
+    void Close           (void);\r
+    bool ObtainInfo      (void);         // retrieves drive geometry\r
+    bool GetBitmap       (void);         // gets drive bitmap\r
+\r
+    // builds list of files on drive\r
+    // if QuitMonitor ever becomes true (ie from a separate thread) it will clean up and return\r
+    bool BuildFileList   (bool &QuitMonitor, double &Progress); \r
+        \r
+    // Functions for accessing the volume bitmap\r
+    bool IsClusterUsed   (uint64 Cluster);\r
+    void SetClusterUsed  (uint64 Cluster, bool Used);\r
+\r
+    DISK_GEOMETRY GetGeometry (void) { return (Geometry); }\r
+    VolumeInfo GetVolumeInfo (void) { return (VolInfo); }\r
+\r
+    string GetRootPath (void) { return (RootPath); }\r
+\r
+    // Scans drive starting from the root dir and calls a user defined function\r
+    // for each file/directory encountered. void* UserData is passed to this\r
+    // function so you can give it some good ol' fashioned context.\r
+    bool Scan (ScanCallback Callback, void *UserData);\r
+\r
+    // Retrieve a directory string from the file database\r
+    string   &GetDBDir       (uint32 Indice);\r
+    uint32    GetDBDirCount  (void);\r
+    // Retrieve file strings/info from the file database\r
+    FileInfo &GetDBFile      (uint32 Indice);\r
+    uint32    GetDBFileCount (void);\r
+    // Kill it!\r
+    uint32    RemoveDBFile   (uint32 Indice);\r
+\r
+    // This is for actual defragmenting! It will automatically update the drive bitmap.\r
+    // Will not move any other files out of the way.\r
+    // Failure (return value of false) means that something is in the way.\r
+    bool MoveFileDumb (uint32 FileIndice, uint64 NewLCN);\r
+\r
+    // Look for a range of sequential free clusters\r
+    // Returns true if one could be found, false if not\r
+    bool FindFreeRange (uint64 StartLCN, uint64 ReqLength, uint64 &LCNResult);\r
+\r
+private:\r
+    friend bool BuildDBCallback (FileInfo &Info, HANDLE &FileHandle, void *UserData);\r
+\r
+    // DirPrefix should be in the form "drive:\\path\\" ie, C:\CRAP\     .\r
+    bool ScanDirectory (string DirPrefix, ScanCallback Callback, void *UserData);\r
+\r
+    // given a file's attributes, should it be processed or not?\r
+    bool ShouldProcess (FileAttr Attr);\r
+\r
+    bool GetClusterInfo (FileInfo &Info, HANDLE &HandleResult);\r
+\r
+    VolumeInfo               VolInfo;\r
+    FileList                 Files;\r
+    vector<string>           Directories; // Directories[Files[x].DirIndice]\r
+    string                   RootPath;    // ie, C:\    .\r
+    HANDLE                   Handle;\r
+    DISK_GEOMETRY            Geometry;\r
+    uint32                  *BitmapDetail;\r
+};\r
+\r
+\r
+#endif // DRIVEVOLUME_H\r
diff --git a/rosapps/fraginator/Fraginator Motif Icon.bmp b/rosapps/fraginator/Fraginator Motif Icon.bmp
new file mode 100644 (file)
index 0000000..b8d412e
Binary files /dev/null and b/rosapps/fraginator/Fraginator Motif Icon.bmp differ
diff --git a/rosapps/fraginator/Fraginator.cpp b/rosapps/fraginator/Fraginator.cpp
new file mode 100644 (file)
index 0000000..e80bb06
--- /dev/null
@@ -0,0 +1,58 @@
+/*****************************************************************************\r
+\r
+  Fraginator\r
+\r
+*****************************************************************************/\r
+\r
+\r
+#include "Fraginator.h"\r
+#include "Mutex.h"\r
+#include "DriveVolume.h"\r
+#include "Defragment.h"\r
+#include "MainDialog.h"\r
+#include "resource.h"\r
+#include <crtdbg.h>\r
+\r
+\r
+HINSTANCE   GlobalHInstance = NULL;\r
+Defragment *Defrag = NULL;\r
+\r
+\r
+int WINAPI WinMain (HINSTANCE HInstance, HINSTANCE HPrevInstance, LPSTR CmdLine, int ShowCmd)\r
+{\r
+    INITCOMMONCONTROLSEX InitControls;\r
+\r
+    // debugging crap\r
+#ifndef NDEBUG\r
+    _CrtSetDbgFlag (_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag (_CRTDBG_REPORT_FLAG));\r
+    _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE);\r
+    _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDOUT);\r
+    _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);\r
+    _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDOUT);\r
+    _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);\r
+    _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDOUT);\r
+#endif\r
+\r
+    GlobalHInstance = HInstance;\r
+\r
+    // We want our progress bar! NOW!\r
+    InitControls.dwSize = sizeof (InitControls);\r
+    InitControls.dwICC = ICC_WIN95_CLASSES;\r
+    InitCommonControlsEx (&InitControls);\r
+\r
+    if (!CheckWinVer())\r
+    {\r
+        MessageBox (GetDesktopWindow(), "Sorry, this program requires Windows 2000.", "Error", MB_OK);\r
+        return (0);\r
+    }\r
+\r
+    DialogBox (HInstance, MAKEINTRESOURCE (IDD_MAIN), GetDesktopWindow(), MainDialogProc);\r
+\r
+#if 0\r
+    AllocConsole ();\r
+    if (_CrtDumpMemoryLeaks ())\r
+        MessageBox (NULL, "Click OK to quit", "Leaks", MB_OK);\r
+#endif\r
+\r
+    return (0);\r
+}\r
diff --git a/rosapps/fraginator/Fraginator.dsp b/rosapps/fraginator/Fraginator.dsp
new file mode 100644 (file)
index 0000000..66b387b
--- /dev/null
@@ -0,0 +1,186 @@
+# Microsoft Developer Studio Project File - Name="Fraginator" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Application" 0x0101\r
+\r
+CFG=Fraginator - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "Fraginator.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "Fraginator.mak" CFG="Fraginator - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "Fraginator - Win32 Release" (based on "Win32 (x86) Application")\r
+!MESSAGE "Fraginator - Win32 Debug" (based on "Win32 (x86) Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=xicl6.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "Fraginator - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c\r
+# ADD CPP /nologo /G6 /Gr /MT /W3 /GX /Ox /Ot /Og /Oi /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=xilink6.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386\r
+# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386\r
+# Begin Special Build Tool\r
+SOURCE="$(InputPath)"\r
+PostBuild_Desc=Copying to Program Files ...\r
+PostBuild_Cmds=copy Release\Fraginator.exe "c:\Program Files\Fraginator\Fraginator.exe"\r
+# End Special Build Tool\r
+\r
+!ELSEIF  "$(CFG)" == "Fraginator - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=xilink6.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /debug /machine:I386\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "Fraginator - Win32 Release"\r
+# Name "Fraginator - Win32 Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=.\Defragment.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\DriveVolume.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Fraginator.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MainDialog.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\ReportDialog.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Unfrag.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=.\Defragment.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\DriveVolume.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Fraginator.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MainDialog.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Mutex.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\ReportDialog.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\resource.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Unfrag.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# Begin Source File\r
+\r
+SOURCE=.\default1.bin\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=".\Fraginator Help - Fraginator Icon.bmp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=".\Fraginator Motif Icon.bmp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Fraginator.rc\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\icon1.ico\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/rosapps/fraginator/Fraginator.dsw b/rosapps/fraginator/Fraginator.dsw
new file mode 100644 (file)
index 0000000..3bd9b6d
--- /dev/null
@@ -0,0 +1,41 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "Fraginator"=.\Fraginator.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "unfrag"=.\unfrag.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/rosapps/fraginator/Fraginator.exe b/rosapps/fraginator/Fraginator.exe
new file mode 100644 (file)
index 0000000..2ef9389
Binary files /dev/null and b/rosapps/fraginator/Fraginator.exe differ
diff --git a/rosapps/fraginator/Fraginator.h b/rosapps/fraginator/Fraginator.h
new file mode 100644 (file)
index 0000000..7008ca8
--- /dev/null
@@ -0,0 +1,24 @@
+/*****************************************************************************\r
+\r
+  Fraginator !!!\r
+\r
+*****************************************************************************/\r
+\r
+\r
+#ifndef FRAGINATOR_H\r
+#define FRAGINATOR_H\r
+\r
+\r
+#include "unfrag.h"\r
+#include <CommCtrl.h>\r
+\r
+\r
+int WINAPI  WinMain (HINSTANCE HInstance, HINSTANCE HPrevInstance, LPSTR CmdLine, int ShowCmd);\r
+Defragment *StartDefragBox (string Drive, DefragType Method);\r
+\r
+\r
+extern HINSTANCE   GlobalHInstance;\r
+extern Defragment *Defrag;\r
+\r
+\r
+#endif // FRAGINATOR_H
\ No newline at end of file
diff --git a/rosapps/fraginator/Fraginator.mak b/rosapps/fraginator/Fraginator.mak
new file mode 100644 (file)
index 0000000..30cfd62
--- /dev/null
@@ -0,0 +1,224 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on Fraginator.dsp\r
+!IF "$(CFG)" == ""\r
+CFG=Fraginator - Win32 Debug\r
+!MESSAGE No configuration specified. Defaulting to Fraginator - Win32 Debug.\r
+!ENDIF \r
+\r
+!IF "$(CFG)" != "Fraginator - Win32 Release" && "$(CFG)" != "Fraginator - Win32 Debug"\r
+!MESSAGE Invalid configuration "$(CFG)" specified.\r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "Fraginator.mak" CFG="Fraginator - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "Fraginator - Win32 Release" (based on "Win32 (x86) Application")\r
+!MESSAGE "Fraginator - Win32 Debug" (based on "Win32 (x86) Application")\r
+!MESSAGE \r
+!ERROR An invalid configuration is specified.\r
+!ENDIF \r
+\r
+!IF "$(OS)" == "Windows_NT"\r
+NULL=\r
+!ELSE \r
+NULL=nul\r
+!ENDIF \r
+\r
+CPP=xicl6.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "Fraginator - Win32 Release"\r
+\r
+OUTDIR=.\Release\r
+INTDIR=.\Release\r
+# Begin Custom Macros\r
+OutDir=.\Release\r
+# End Custom Macros\r
+\r
+ALL : "$(OUTDIR)\Fraginator.exe"\r
+\r
+\r
+CLEAN :\r
+       -@erase "$(INTDIR)\Defragment.obj"\r
+       -@erase "$(INTDIR)\DriveVolume.obj"\r
+       -@erase "$(INTDIR)\Fraginator.obj"\r
+       -@erase "$(INTDIR)\Fraginator.res"\r
+       -@erase "$(INTDIR)\MainDialog.obj"\r
+       -@erase "$(INTDIR)\ReportDialog.obj"\r
+       -@erase "$(INTDIR)\Unfrag.obj"\r
+       -@erase "$(INTDIR)\vc60.idb"\r
+       -@erase "$(OUTDIR)\Fraginator.exe"\r
+\r
+"$(OUTDIR)" :\r
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"\r
+\r
+CPP_PROJ=/nologo /G6 /Gr /MT /W3 /GX /Ox /Ot /Og /Oi /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\Fraginator.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c \r
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 \r
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Fraginator.res" /d "NDEBUG" \r
+BSC32=bscmake.exe\r
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\Fraginator.bsc" \r
+BSC32_SBRS= \\r
+       \r
+LINK32=xilink6.exe\r
+LINK32_FLAGS=comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"$(OUTDIR)\Fraginator.exe" \r
+LINK32_OBJS= \\r
+       "$(INTDIR)\Defragment.obj" \\r
+       "$(INTDIR)\DriveVolume.obj" \\r
+       "$(INTDIR)\Fraginator.obj" \\r
+       "$(INTDIR)\MainDialog.obj" \\r
+       "$(INTDIR)\ReportDialog.obj" \\r
+       "$(INTDIR)\Unfrag.obj" \\r
+       "$(INTDIR)\Fraginator.res"\r
+\r
+"$(OUTDIR)\Fraginator.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)\r
+    $(LINK32) @<<\r
+  $(LINK32_FLAGS) $(LINK32_OBJS)\r
+<<\r
+\r
+SOURCE="$(InputPath)"\r
+PostBuild_Desc=Copying to Program Files ...\r
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep\r
+\r
+ALL : $(DS_POSTBUILD_DEP)\r
+\r
+# Begin Custom Macros\r
+OutDir=.\Release\r
+# End Custom Macros\r
+\r
+$(DS_POSTBUILD_DEP) : "$(OUTDIR)\Fraginator.exe"\r
+   copy Release\Fraginator.exe "c:\Program Files\Fraginator\Fraginator.exe"\r
+       echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"\r
+\r
+!ELSEIF  "$(CFG)" == "Fraginator - Win32 Debug"\r
+\r
+OUTDIR=.\Debug\r
+INTDIR=.\Debug\r
+# Begin Custom Macros\r
+OutDir=.\Debug\r
+# End Custom Macros\r
+\r
+ALL : "$(OUTDIR)\Fraginator.exe"\r
+\r
+\r
+CLEAN :\r
+       -@erase "$(INTDIR)\Defragment.obj"\r
+       -@erase "$(INTDIR)\DriveVolume.obj"\r
+       -@erase "$(INTDIR)\Fraginator.obj"\r
+       -@erase "$(INTDIR)\Fraginator.res"\r
+       -@erase "$(INTDIR)\MainDialog.obj"\r
+       -@erase "$(INTDIR)\ReportDialog.obj"\r
+       -@erase "$(INTDIR)\Unfrag.obj"\r
+       -@erase "$(INTDIR)\vc60.idb"\r
+       -@erase "$(INTDIR)\vc60.pdb"\r
+       -@erase "$(OUTDIR)\Fraginator.exe"\r
+\r
+"$(OUTDIR)" :\r
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"\r
+\r
+CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\Fraginator.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c \r
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 \r
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Fraginator.res" /d "_DEBUG" \r
+BSC32=bscmake.exe\r
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\Fraginator.bsc" \r
+BSC32_SBRS= \\r
+       \r
+LINK32=xilink6.exe\r
+LINK32_FLAGS=comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /debug /machine:I386 /out:"$(OUTDIR)\Fraginator.exe" \r
+LINK32_OBJS= \\r
+       "$(INTDIR)\Defragment.obj" \\r
+       "$(INTDIR)\DriveVolume.obj" \\r
+       "$(INTDIR)\Fraginator.obj" \\r
+       "$(INTDIR)\MainDialog.obj" \\r
+       "$(INTDIR)\ReportDialog.obj" \\r
+       "$(INTDIR)\Unfrag.obj" \\r
+       "$(INTDIR)\Fraginator.res"\r
+\r
+"$(OUTDIR)\Fraginator.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)\r
+    $(LINK32) @<<\r
+  $(LINK32_FLAGS) $(LINK32_OBJS)\r
+<<\r
+\r
+!ENDIF \r
+\r
+.c{$(INTDIR)}.obj::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.cpp{$(INTDIR)}.obj::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.cxx{$(INTDIR)}.obj::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.c{$(INTDIR)}.sbr::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.cpp{$(INTDIR)}.sbr::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.cxx{$(INTDIR)}.sbr::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+\r
+!IF "$(NO_EXTERNAL_DEPS)" != "1"\r
+!IF EXISTS("Fraginator.dep")\r
+!INCLUDE "Fraginator.dep"\r
+!ELSE \r
+!MESSAGE Warning: cannot find "Fraginator.dep"\r
+!ENDIF \r
+!ENDIF \r
+\r
+\r
+!IF "$(CFG)" == "Fraginator - Win32 Release" || "$(CFG)" == "Fraginator - Win32 Debug"\r
+SOURCE=.\Defragment.cpp\r
+\r
+"$(INTDIR)\Defragment.obj" : $(SOURCE) "$(INTDIR)"\r
+\r
+\r
+SOURCE=.\DriveVolume.cpp\r
+\r
+"$(INTDIR)\DriveVolume.obj" : $(SOURCE) "$(INTDIR)"\r
+\r
+\r
+SOURCE=.\Fraginator.cpp\r
+\r
+"$(INTDIR)\Fraginator.obj" : $(SOURCE) "$(INTDIR)"\r
+\r
+\r
+SOURCE=.\MainDialog.cpp\r
+\r
+"$(INTDIR)\MainDialog.obj" : $(SOURCE) "$(INTDIR)"\r
+\r
+\r
+SOURCE=.\ReportDialog.cpp\r
+\r
+"$(INTDIR)\ReportDialog.obj" : $(SOURCE) "$(INTDIR)"\r
+\r
+\r
+SOURCE=.\Unfrag.cpp\r
+\r
+"$(INTDIR)\Unfrag.obj" : $(SOURCE) "$(INTDIR)"\r
+\r
+\r
+SOURCE=.\Fraginator.rc\r
+\r
+"$(INTDIR)\Fraginator.res" : $(SOURCE) "$(INTDIR)"\r
+       $(RSC) $(RSC_PROJ) $(SOURCE)\r
+\r
+\r
+\r
+!ENDIF \r
+\r
diff --git a/rosapps/fraginator/Fraginator.rc b/rosapps/fraginator/Fraginator.rc
new file mode 100644 (file)
index 0000000..c243fab
--- /dev/null
@@ -0,0 +1,241 @@
+// Microsoft Visual C++ generated resource script.\r
+//\r
+#include "resource.h"\r
+\r
+#define APSTUDIO_READONLY_SYMBOLS\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 2 resource.\r
+//\r
+#include "afxres.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#undef APSTUDIO_READONLY_SYMBOLS\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// English (U.S.) resources\r
+\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+#pragma code_page(1252)\r
+#endif //_WIN32\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Dialog\r
+//\r
+\r
+IDD_MAIN DIALOGEX 0, 0, 346, 103\r
+STYLE DS_SETFONT | DS_CENTERMOUSE | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | \r
+    WS_CAPTION | WS_SYSMENU\r
+FONT 8, "MS Sans Serif", 0, 0, 0x1\r
+BEGIN\r
+    COMBOBOX        IDC_DRIVES_LIST,78,52,29,111,CBS_DROPDOWNLIST | CBS_SORT | \r
+                    WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_METHODS_LIST,135,52,77,79,CBS_DROPDOWNLIST | \r
+                    WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_PRIORITY_LIST,223,52,59,91,CBS_DROPDOWNLIST | \r
+                    WS_VSCROLL | WS_TABSTOP\r
+    PUSHBUTTON      "Start",IDC_STARTSTOP,294,7,45,15\r
+    PUSHBUTTON      "Help",ID_MAIN_HELP,294,28,45,15\r
+    PUSHBUTTON      "Exit",IDC_QUIT,294,49,45,15\r
+    CONTROL         110,IDC_STATIC,"Static",SS_BITMAP | SS_SUNKEN | \r
+                    WS_BORDER,7,7,63,58\r
+    LTEXT           "Choose a drive:",IDC_STATIC,78,40,50,8\r
+    LTEXT           "Choose an action:",IDC_STATIC,135,40,58,8\r
+    CONTROL         "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER | \r
+                    0x1,7,71,299,10\r
+    CONTROL         "Static",IDC_STATUS,"Static",SS_LEFTNOWORDWRAP | \r
+                    SS_SUNKEN | WS_GROUP,7,86,332,10\r
+    LTEXT           "I am a monkey, hear me eeK",IDC_WISECRACKS,78,15,91,8\r
+    LTEXT           "100.00%",IDC_PERCENT,311,71,28,8,0,WS_EX_RIGHT\r
+    LTEXT           "Process Priority:",IDC_STATIC,223,40,51,8\r
+END\r
+\r
+IDD_REPORT DIALOG  0, 0, 391, 169\r
+STYLE DS_SETFONT | WS_POPUP | WS_CAPTION\r
+CAPTION "Report"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN\r
+    DEFPUSHBUTTON   "Bytes",IDC_BYTES,7,148,50,14\r
+    DEFPUSHBUTTON   "Kilobytes",IDC_KILOBYTES,61,148,50,14\r
+    DEFPUSHBUTTON   "Megabytes",IDC_MEGABYTES,115,148,50,14\r
+    DEFPUSHBUTTON   "Gigabytes",IDC_GIGABYTES,169,148,50,14\r
+    DEFPUSHBUTTON   "OK",IDC_REPORTOK,334,148,50,14\r
+    RTEXT           "Volume",IDC_STATIC,7,7,24,8\r
+    LTEXT           "Capacity",IDC_STATIC,7,51,28,8\r
+    RTEXT           "(Drive Letter)",IDC_DRIVELETTER,63,7,117,10,SS_SUNKEN\r
+    RTEXT           "(Disk Size, Bytes)",IDC_DISKSIZEBYTES,63,51,117,10,\r
+                    SS_SUNKEN\r
+    RTEXT           "(Disk Size, Clusters)",IDC_DISKSIZECLUSTERS,63,73,117,\r
+                    10,SS_SUNKEN\r
+    LTEXT           "Total clusters",IDC_STATIC,7,73,43,8\r
+    RTEXT           "(Cluster size)",IDC_DISKCLUSTERSIZE,63,84,117,10,\r
+                    SS_SUNKEN\r
+    LTEXT           "Cluster size",IDC_STATIC,7,84,36,8\r
+    RTEXT           "(Files count)",IDC_FILESCOUNT,267,18,117,10,SS_SUNKEN\r
+    RTEXT           "(Files size, bytes)",IDC_FILESSIZEBYTES,267,29,117,10,\r
+                    SS_SUNKEN\r
+    LTEXT           "# of files",IDC_STATIC,194,18,28,8\r
+    LTEXT           "Total size",IDC_STATIC,194,29,31,8\r
+    LTEXT           "Size on disk",IDC_STATIC,194,40,39,8\r
+    RTEXT           "(Total size, bytes)",IDC_FILESSIZEONDISK,267,40,117,10,\r
+                    SS_SUNKEN\r
+    RTEXT           "(Files slack bytes)",IDC_FILESSLACKBYTES,267,51,117,10,\r
+                    SS_SUNKEN\r
+    LTEXT           "Wasted slack",IDC_STATIC,194,51,44,8\r
+    RTEXT           "(Disk Free, Bytes)",IDC_DISKFREEBYTES,63,62,117,10,\r
+                    SS_SUNKEN\r
+    LTEXT           "Free space",IDC_STATIC,7,62,36,8\r
+    RTEXT           "(Files fragmented, count)",IDC_FILESFRAGGED,267,62,117,\r
+                    10,SS_SUNKEN\r
+    LTEXT           "Fragmented files",IDC_STATIC,194,62,52,8\r
+    RTEXT           "(Dirs count)",IDC_DIRSCOUNT,267,7,117,10,SS_SUNKEN\r
+    LTEXT           "# of directories",IDC_STATIC,194,7,48,8\r
+    RTEXT           "File System",IDC_STATIC,7,40,36,8\r
+    RTEXT           "(File System Name)",IDC_FILESYSTEM,63,40,117,10,\r
+                    SS_SUNKEN\r
+    RTEXT           "Volume Label",IDC_STATIC,7,18,44,8\r
+    RTEXT           "(Volume Name)",IDC_VOLUMELABEL,63,18,117,10,SS_SUNKEN\r
+    RTEXT           "Serial",IDC_STATIC,7,29,18,8\r
+    RTEXT           "(Volume Serial)",IDC_VOLUMESERIAL,63,29,117,10,\r
+                    SS_SUNKEN\r
+    RTEXT           "(Average Frags Per File)",IDC_AVERAGEFRAGS,267,73,117,\r
+                    10,SS_SUNKEN\r
+    LTEXT           "Average fragments per file",IDC_STATIC,194,73,60,20\r
+    LTEXT           "XX.X% of the files on this drive are fragmented. It is recommended that you perform a SSSSSSS defragmentation.",\r
+                    IDC_RECOMMEND,7,106,377,38,SS_SUNKEN\r
+    LTEXT           "Recommendations:",IDC_STATIC,7,96,62,8\r
+END\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// DESIGNINFO\r
+//\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+GUIDELINES DESIGNINFO \r
+BEGIN\r
+    IDD_MAIN, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 339\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 96\r
+    END\r
+\r
+    IDD_REPORT, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 384\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 162\r
+    END\r
+END\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// TEXTINCLUDE\r
+//\r
+\r
+1 TEXTINCLUDE \r
+BEGIN\r
+    "resource.h\0"\r
+END\r
+\r
+2 TEXTINCLUDE \r
+BEGIN\r
+    "#include ""afxres.h""\r\n"\r
+    "\0"\r
+END\r
+\r
+3 TEXTINCLUDE \r
+BEGIN\r
+    "\r\n"\r
+    "\0"\r
+END\r
+\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Version\r
+//\r
+\r
+VS_VERSION_INFO VERSIONINFO\r
+ FILEVERSION 1,3,0,0\r
+ PRODUCTVERSION 1,3,0,0\r
+ FILEFLAGSMASK 0x3fL\r
+#ifdef _DEBUG\r
+ FILEFLAGS 0x1L\r
+#else\r
+ FILEFLAGS 0x0L\r
+#endif\r
+ FILEOS 0x40004L\r
+ FILETYPE 0x1L\r
+ FILESUBTYPE 0x0L\r
+BEGIN\r
+    BLOCK "StringFileInfo"\r
+    BEGIN\r
+        BLOCK "040904b0"\r
+        BEGIN\r
+            VALUE "CompanyName", " "\r
+            VALUE "FileDescription", "Fraginator"\r
+            VALUE "FileVersion", "1.03"\r
+            VALUE "InternalName", "Fraginator"\r
+            VALUE "LegalCopyright", "Copyright Â© 2000-2002 Rick Brewster"\r
+            VALUE "OriginalFilename", "Fraginator.exe"\r
+            VALUE "ProductName", "Fraginator"\r
+            VALUE "ProductVersion", "1.03"\r
+        END\r
+    END\r
+    BLOCK "VarFileInfo"\r
+    BEGIN\r
+        VALUE "Translation", 0x409, 1200\r
+    END\r
+END\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Bitmap\r
+//\r
+\r
+IDB_LOGO                BITMAP                  "Fraginator Motif Icon.bmp"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Icon\r
+//\r
+\r
+// Icon with lowest ID value placed first to ensure application icon\r
+// remains consistent on all systems.\r
+IDI_ICON                ICON                    "icon1.ico"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// RT_MANIFEST\r
+//\r
+\r
+1                       RT_MANIFEST             "default1.bin"\r
+#endif    // English (U.S.) resources\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+\r
+#ifndef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 3 resource.\r
+//\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#endif    // not APSTUDIO_INVOKED\r
+\r
diff --git a/rosapps/fraginator/Fraginator.sln b/rosapps/fraginator/Fraginator.sln
new file mode 100644 (file)
index 0000000..8996ce9
--- /dev/null
@@ -0,0 +1,27 @@
+Microsoft Visual Studio Solution File, Format Version 7.00\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Fraginator", "Fraginator.vcproj", "{7CB0DB3F-D4AB-4A99-807F-C56CC9F0B19C}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unfrag", "unfrag.vcproj", "{8E7E76C1-739B-46E5-99C2-A0504558164B}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfiguration) = preSolution\r
+               ConfigName.0 = Debug\r
+               ConfigName.1 = Release\r
+       EndGlobalSection\r
+       GlobalSection(ProjectDependencies) = postSolution\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfiguration) = postSolution\r
+               {7CB0DB3F-D4AB-4A99-807F-C56CC9F0B19C}.Debug.ActiveCfg = Debug|Win32\r
+               {7CB0DB3F-D4AB-4A99-807F-C56CC9F0B19C}.Debug.Build.0 = Debug|Win32\r
+               {7CB0DB3F-D4AB-4A99-807F-C56CC9F0B19C}.Release.ActiveCfg = Release|Win32\r
+               {7CB0DB3F-D4AB-4A99-807F-C56CC9F0B19C}.Release.Build.0 = Release|Win32\r
+               {8E7E76C1-739B-46E5-99C2-A0504558164B}.Debug.ActiveCfg = Debug|Win32\r
+               {8E7E76C1-739B-46E5-99C2-A0504558164B}.Debug.Build.0 = Debug|Win32\r
+               {8E7E76C1-739B-46E5-99C2-A0504558164B}.Release.ActiveCfg = Release|Win32\r
+               {8E7E76C1-739B-46E5-99C2-A0504558164B}.Release.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityGlobals) = postSolution\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityAddIns) = postSolution\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/rosapps/fraginator/Fraginator.suo b/rosapps/fraginator/Fraginator.suo
new file mode 100644 (file)
index 0000000..c674481
Binary files /dev/null and b/rosapps/fraginator/Fraginator.suo differ
diff --git a/rosapps/fraginator/Fraginator.vcproj b/rosapps/fraginator/Fraginator.vcproj
new file mode 100644 (file)
index 0000000..5d17321
--- /dev/null
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="Fraginator"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\Release"\r
+                       IntermediateDirectory=".\Release"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="3"\r
+                               GlobalOptimizations="TRUE"\r
+                               InlineFunctionExpansion="2"\r
+                               EnableIntrinsicFunctions="TRUE"\r
+                               FavorSizeOrSpeed="1"\r
+                               OptimizeForProcessor="2"\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_WINDOWS"\r
+                               ExceptionHandling="TRUE"\r
+                               RuntimeLibrary="0"\r
+                               StructMemberAlignment="5"\r
+                               BufferSecurityCheck="FALSE"\r
+                               PrecompiledHeaderFile=".\Release/Fraginator.pch"\r
+                               AssemblerListingLocation=".\Release/"\r
+                               ObjectFile=".\Release/"\r
+                               ProgramDataBaseFileName=".\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAsManaged="0"\r
+                               CallingConvention="1"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib"\r
+                               OutputFile=".\Release/Fraginator.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               SubSystem="2"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName=".\Release/Fraginator.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               Description="Copying to Program Files ..."\r
+                               CommandLine="copy Release\Fraginator.exe &quot;c:\Program Files\Fraginator\Fraginator.exe&quot;"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\Debug"\r
+                       IntermediateDirectory=".\Debug"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               PrecompiledHeaderFile=".\Debug/Fraginator.pch"\r
+                               AssemblerListingLocation=".\Debug/"\r
+                               ObjectFile=".\Debug/"\r
+                               ProgramDataBaseFileName=".\Debug/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="4"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib"\r
+                               OutputFile=".\Debug/Fraginator.exe"\r
+                               LinkIncremental="2"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\Debug/Fraginator.pdb"\r
+                               SubSystem="2"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName=".\Debug/Fraginator.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath=".\Defragment.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\DriveVolume.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Fraginator.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\MainDialog.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ReportDialog.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="Unfrag.cpp">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath=".\Defragment.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\DriveVolume.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Fraginator.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\MainDialog.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Mutex.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ReportDialog.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Unfrag.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\resource.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">\r
+                       <File\r
+                               RelativePath=".\Fraginator Help - Fraginator Icon.bmp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Fraginator Motif Icon.bmp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Fraginator.rc">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\default1.bin">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\icon1.ico">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/rosapps/fraginator/MainDialog.cpp b/rosapps/fraginator/MainDialog.cpp
new file mode 100644 (file)
index 0000000..51dc872
--- /dev/null
@@ -0,0 +1,574 @@
+#include "unfrag.h"\r
+#include "MainDialog.h"\r
+#include "resource.h"\r
+#include "Fraginator.h"\r
+#include "Defragment.h"\r
+#include "ReportDialog.h"\r
+\r
+\r
+vector<string> DrivesList;\r
+LRESULT AnalyzeID;\r
+LRESULT FastID;\r
+LRESULT ExtensiveID;\r
+bool QuitWhenDone;\r
+bool Stopping;\r
+\r
+\r
+LRESULT PriHighID;\r
+LRESULT PriAboveNormID;\r
+LRESULT PriNormalID;\r
+LRESULT PriBelowNormID;\r
+LRESULT PriIdleID;\r
+\r
+\r
+void             InitDialog       (HWND Dlg);\r
+void             UpdateDefragInfo (HWND Dlg);\r
+void             UpdatePriority   (HWND Dlg);\r
+string           GetDefaultTitle  (void);\r
+string           GetDefragTitle   (void);\r
+void             SetDisables      (HWND Dlg);\r
+INT_PTR CALLBACK MainDialogProc   (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam);\r
+\r
+\r
+static void InitDialog (HWND Dlg)\r
+{\r
+    // Make internal list\r
+    DWORD DriveMask;\r
+    HWND  DlgItem;\r
+    int d;\r
+\r
+    // Clear out wisecracks line for now\r
+    SetDlgItemText (Dlg, IDC_WISECRACKS, "\"Defrag, baby!\"");\r
+\r
+    // Make list of logical drives\r
+    DrivesList.resize (0);\r
+    DriveMask = GetLogicalDrives ();\r
+\r
+    for (d = 0; d < 26; d++)\r
+    {\r
+        if (DriveMask & (1 << d))\r
+        {\r
+            string Name;\r
+\r
+            Name = (char)('A' + d);\r
+            Name += ':';\r
+            DrivesList.push_back (Name);\r
+        }\r
+    }\r
+\r
+    // Give list to dropdown list\r
+    DlgItem = GetDlgItem (Dlg, IDC_DRIVES_LIST);\r
+    SendMessage (DlgItem, CB_RESETCONTENT, 0, 0);\r
+    for (d = 0; d < DrivesList.size(); d++)\r
+    {\r
+        SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) DrivesList[d].c_str());\r
+    }\r
+\r
+    // Put in defrag methods\r
+    DlgItem = GetDlgItem (Dlg, IDC_METHODS_LIST);\r
+    SendMessage (DlgItem, CB_RESETCONTENT, 0, 0);\r
+    AnalyzeID   = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) "Analyze Only");\r
+    FastID      = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) "Fast Defrag");\r
+    ExtensiveID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) "Extensive Defrag");\r
+\r
+    // Set up process priorities\r
+    DlgItem = GetDlgItem (Dlg, IDC_PRIORITY_LIST);\r
+    SendMessage (Dlg, CB_RESETCONTENT, 0, 0);\r
+    PriHighID      = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) "High");\r
+    PriAboveNormID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) "Above Normal");\r
+    PriNormalID    = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) "Normal");\r
+    PriBelowNormID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) "Below Normal");\r
+    PriIdleID      = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) "Idle");\r
+    UpdatePriority (Dlg);\r
+\r
+    // Reset texts and progress meters\r
+    SendDlgItemMessage (Dlg, IDC_STATUS,   WM_SETTEXT,   0, (LPARAM) "");\r
+    SendDlgItemMessage (Dlg, IDC_PERCENT,  WM_SETTEXT,   0, (LPARAM) "");\r
+    SendDlgItemMessage (Dlg, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM (0, 10000));\r
+    SendDlgItemMessage (Dlg, IDC_PROGRESS, PBM_SETPOS,   0, 0);\r
+\r
+    return;\r
+}\r
+\r
+\r
+void UpdateDefragInfo (HWND Dlg)\r
+{\r
+    char PercentText[100];\r
+    static double OldPercent = 200.0f;\r
+    static string OldStatus = "Non";\r
+    string NewStatus;\r
+    double NewPercent;\r
+\r
+    if (Defrag == NULL)\r
+        return;\r
+   \r
+    NewPercent = Defrag->GetStatusPercent ();\r
+    if (NewPercent > 100.0f) \r
+        NewPercent = 100.0f;\r
+    if (NewPercent < 0.0f)\r
+        NewPercent = 0.0f;\r
+    if (NewPercent != OldPercent)\r
+    {\r
+        sprintf (PercentText, "%6.2f%%", NewPercent);\r
+        SendDlgItemMessage (Dlg, IDC_PERCENT, WM_SETTEXT, 0, (LPARAM) PercentText);\r
+        SendDlgItemMessage (Dlg, IDC_PROGRESS, PBM_SETPOS, \r
+            (WPARAM) (int)(NewPercent * 100.0f), 0);\r
+        OldPercent = NewPercent;\r
+    }\r
+\r
+    NewStatus = Defrag->GetStatusString ();\r
+    if (NewStatus != OldStatus)\r
+    {   // Change & characters to && to avoid underlining\r
+        string Status;\r
+        string::iterator it;\r
+\r
+        Status = NewStatus;\r
+        it = Status.begin ();\r
+        while (it < Status.end())\r
+        {\r
+            if (*it == '&')\r
+            {\r
+                Status.insert (it, 1, '&');\r
+                it++;\r
+            }\r
+\r
+            it++;\r
+        }\r
+\r
+        SendDlgItemMessage (Dlg, IDC_STATUS, WM_SETTEXT, 0, \r
+            (LPARAM) Status.c_str());\r
+\r
+        OldStatus = NewStatus;\r
+    }\r
+\r
+    return;\r
+}\r
+\r
+\r
+string GetDefaultTitle (void)\r
+{\r
+    string DefaultText;\r
+\r
+    DefaultText = string(string(APPNAME_GUI) + string(" v") + string(APPVER_STR) +\r
+                  string(" (C) 2000 by Rick Brewster"));\r
+\r
+    return (DefaultText);\r
+}\r
+\r
+\r
+string GetDefragTitle (void)\r
+{\r
+    string DefragText;\r
+    char Percent[10];\r
+\r
+    sprintf (Percent, "%.2f%%", Defrag->GetStatusPercent());\r
+\r
+    DefragText = GetDefaultTitle ();\r
+    if (Defrag != NULL)\r
+    {\r
+        DefragText = string(Percent) + string (" - ") + Defrag->GetVolume().GetRootPath() + \r
+            string (" - ") + DefragText;\r
+    }\r
+\r
+    return (DefragText);\r
+}\r
+\r
+\r
+void SetDisables (HWND Dlg)\r
+{\r
+    // If a defrag is in process, set 'Start' button to say 'Stop' and disable\r
+    // the Select Drive and Select Action controls\r
+    if (Defrag != NULL  &&  !Defrag->IsDoneYet()  &&  !Defrag->HasError())\r
+    {\r
+        SendMessage (GetDlgItem (Dlg, IDC_STARTSTOP), WM_SETTEXT, 0, (LPARAM) "Stop");\r
+        EnableWindow (GetDlgItem (Dlg, IDC_DRIVES_LIST), FALSE);\r
+        EnableWindow (GetDlgItem (Dlg, IDC_METHODS_LIST), FALSE);\r
+    }\r
+    else\r
+    {\r
+        SendMessage (GetDlgItem (Dlg, IDC_STARTSTOP), WM_SETTEXT, 0, (LPARAM) "Start");\r
+        EnableWindow (GetDlgItem (Dlg, IDC_STARTSTOP), TRUE);\r
+        EnableWindow (GetDlgItem (Dlg, IDC_QUIT), TRUE);\r
+        EnableWindow (GetDlgItem (Dlg, IDC_DRIVES_LIST), TRUE);\r
+        EnableWindow (GetDlgItem (Dlg, IDC_METHODS_LIST), TRUE);\r
+    }\r
+\r
+    return;\r
+}\r
+\r
+\r
+void UpdatePriority (HWND Dlg)\r
+{\r
+    LRESULT Id;\r
+    DWORD Priority;\r
+\r
+    Id = SendDlgItemMessage (Dlg, IDC_PRIORITY_LIST, CB_GETCURSEL, 0, 0);\r
+\r
+    if (Id == PriHighID)\r
+        Priority = HIGH_PRIORITY_CLASS;\r
+    else\r
+    if (Id == PriAboveNormID)\r
+        Priority = ABOVE_NORMAL_PRIORITY_CLASS;\r
+    else\r
+    if (Id == PriNormalID)\r
+        Priority = NORMAL_PRIORITY_CLASS;\r
+    else\r
+    if (Id == PriBelowNormID)\r
+        Priority = BELOW_NORMAL_PRIORITY_CLASS;\r
+    else\r
+    if (Id == PriIdleID)\r
+        Priority = IDLE_PRIORITY_CLASS;\r
+    else\r
+        return;\r
+\r
+    SetPriorityClass (GetCurrentProcess(), Priority);\r
+    return;\r
+}\r
+\r
+\r
+// Save settings (ie, process priority and defrag type options)\r
+bool GetRegKeys (HKEY *RegKeyResult)\r
+{\r
+    HKEY RegKey;\r
+    LONG Error;\r
+\r
+    Error = RegCreateKeyEx\r
+    (\r
+        HKEY_CURRENT_USER,\r
+        "Software\\Fraginator",\r
+        0,\r
+        NULL,\r
+        REG_OPTION_NON_VOLATILE,\r
+        KEY_ALL_ACCESS,\r
+        NULL,\r
+        &RegKey,\r
+        NULL\r
+    );\r
+\r
+    if (Error != ERROR_SUCCESS)\r
+        return (false);\r
+\r
+    *RegKeyResult = RegKey;\r
+    return (true);\r
+}\r
+\r
+\r
+bool DoneRegKey (HKEY RegKey)\r
+{\r
+    RegCloseKey (RegKey);\r
+    return (true);\r
+}\r
+\r
+\r
+void SaveSettings (HWND Dlg)\r
+{\r
+    LRESULT DefragID;\r
+    DWORD   DefragVal;\r
+    LRESULT PriID;\r
+    DWORD   PriVal;\r
+    HKEY    RegKey;\r
+\r
+    DefragID = SendDlgItemMessage (Dlg, IDC_METHODS_LIST, CB_GETCURSEL, 0, 0);\r
+    PriID    = SendDlgItemMessage (Dlg, IDC_PRIORITY_LIST, CB_GETCURSEL, 0, 0);\r
+\r
+    // Action\r
+    if (DefragID == AnalyzeID)\r
+        DefragVal = (DWORD) DefragAnalyze;\r
+    else\r
+    if (DefragID == FastID)\r
+        DefragVal = (DWORD) DefragFast;\r
+    else\r
+    if (DefragID == ExtensiveID)\r
+        DefragVal = (DWORD) DefragExtensive;\r
+\r
+    // Process Priority\r
+    if (PriID == PriHighID)\r
+        PriVal = HIGH_PRIORITY_CLASS;\r
+    else\r
+    if (PriID == PriAboveNormID)\r
+        PriVal = ABOVE_NORMAL_PRIORITY_CLASS;\r
+    else\r
+    if (PriID == PriNormalID)\r
+        PriVal = NORMAL_PRIORITY_CLASS;\r
+    else\r
+    if (PriID == PriBelowNormID)\r
+        PriVal = BELOW_NORMAL_PRIORITY_CLASS;\r
+    else\r
+    if (PriID == PriIdleID)\r
+        PriVal = IDLE_PRIORITY_CLASS;\r
+\r
+    if (!GetRegKeys (&RegKey))\r
+        return;\r
+\r
+    RegSetValueEx\r
+    (\r
+        RegKey,\r
+        "Default Action",\r
+        0,\r
+        REG_DWORD,\r
+        (CONST BYTE *)&DefragVal,\r
+        sizeof (DefragVal)\r
+    );\r
+\r
+    RegSetValueEx\r
+    (\r
+        RegKey,\r
+        "Process Priority",\r
+        0,\r
+        REG_DWORD,\r
+        (CONST BYTE *)&PriVal,\r
+        sizeof (PriVal)\r
+    );\r
+\r
+    DoneRegKey (RegKey);\r
+    return;\r
+}\r
+\r
+\r
+void LoadSettings (HWND Dlg)\r
+{\r
+    DefragType DType;\r
+    DWORD      DTypeVal;\r
+    LRESULT    DefragID;\r
+    DWORD      PriVal;\r
+    LRESULT    PriID;\r
+    HKEY       RegKey;\r
+    DWORD      RegType;\r
+    DWORD      RegSize;\r
+    LONG       Error;\r
+\r
+    if (!GetRegKeys (&RegKey))\r
+        return;\r
+\r
+    RegSize = sizeof (DTypeVal);\r
+    RegType = REG_DWORD;\r
+\r
+    Error = RegQueryValueEx\r
+    (\r
+        RegKey,\r
+        "Default Action",\r
+        0,\r
+        &RegType,\r
+        (BYTE *)&DTypeVal,\r
+        &RegSize\r
+    );\r
+\r
+    if (Error != ERROR_SUCCESS)\r
+        DTypeVal = DefragAnalyze;\r
+\r
+    Error = RegQueryValueEx\r
+    (\r
+        RegKey,\r
+        "Process Priority",\r
+        0,\r
+        &RegType,\r
+        (BYTE *)&PriVal,\r
+        &RegSize\r
+    );\r
+\r
+    DoneRegKey (RegKey);\r
+\r
+    if (Error != ERROR_SUCCESS)\r
+        PriVal = NORMAL_PRIORITY_CLASS;\r
+\r
+    DType = (DefragType) DTypeVal;\r
+    switch (DType)\r
+    {\r
+        default:\r
+        case DefragAnalyze:\r
+            DefragID = AnalyzeID;\r
+            break;\r
+\r
+        case DefragFast:\r
+            DefragID = FastID;\r
+            break;\r
+\r
+        case DefragExtensive:\r
+            DefragID = ExtensiveID;\r
+            break;\r
+    }\r
+\r
+    switch (PriVal)\r
+    {\r
+        case HIGH_PRIORITY_CLASS:\r
+            PriID = PriHighID;\r
+            break;\r
+\r
+        case ABOVE_NORMAL_PRIORITY_CLASS:\r
+            PriID = PriAboveNormID;\r
+            break;\r
+\r
+        default:\r
+        case NORMAL_PRIORITY_CLASS:\r
+            PriID = PriNormalID;\r
+            break;\r
+\r
+        case BELOW_NORMAL_PRIORITY_CLASS:\r
+            PriID = PriBelowNormID;\r
+            break;\r
+\r
+        case IDLE_PRIORITY_CLASS:\r
+            PriID = PriIdleID;\r
+            break;\r
+    }\r
+\r
+    SendDlgItemMessage (Dlg, IDC_PRIORITY_LIST, CB_SETCURSEL, PriID,    0);\r
+    SendDlgItemMessage (Dlg, IDC_METHODS_LIST,  CB_SETCURSEL, DefragID, 0);\r
+    return;\r
+}\r
+\r
+\r
+#define IDLETIME 25\r
+string OldWindowText = "";\r
+\r
+INT_PTR CALLBACK MainDialogProc (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam)\r
+{\r
+    static bool ReEntrance = false;\r
+\r
+    switch (Msg)\r
+    {\r
+        case WM_INITDIALOG:\r
+            Stopping = false;\r
+            SetWindowText (Dlg, GetDefaultTitle().c_str());\r
+            SetDisables (Dlg);\r
+            InitDialog (Dlg);\r
+            SetTimer (Dlg, 1, IDLETIME, NULL);\r
+            SetClassLong (Dlg, GCL_HICON, (LONG) LoadIcon (GlobalHInstance, MAKEINTRESOURCE(IDI_ICON)));\r
+            QuitWhenDone = false;\r
+            LoadSettings (Dlg);\r
+            UpdatePriority (Dlg);\r
+            return (1);\r
+\r
+\r
+        case WM_TIMER:\r
+            if (Defrag != NULL  &&  !ReEntrance)\r
+            {\r
+                string NewTitle;\r
+\r
+                SendMessage (Dlg, WM_UPDATEINFO, 0, 0);\r
+\r
+                NewTitle = GetDefragTitle ();\r
+                if (NewTitle != OldWindowText)\r
+                {\r
+                    OldWindowText = NewTitle;\r
+                    SetWindowText (Dlg, NewTitle.c_str());\r
+                }\r
+\r
+                if (Defrag->IsDoneYet()  ||  Defrag->HasError())\r
+                {   // This is the code executed when defragging is finished (or stopped :)\r
+                    if (Defrag->GetDefragType() == DefragAnalyze  &&  \r
+                        !Defrag->HasError()  &&\r
+                        !Stopping)\r
+                    {   // Show report\r
+                        ReEntrance = true;\r
+\r
+                        DialogBoxParam (GlobalHInstance, MAKEINTRESOURCE (IDD_REPORT),\r
+                            Dlg, ReportDialogProc, (LPARAM) Defrag);\r
+\r
+                        ReEntrance = false;\r
+                    }\r
+\r
+                    delete Defrag;\r
+                    Defrag = NULL;\r
+                    SetDisables (Dlg);\r
+                    SetWindowText (Dlg, GetDefaultTitle().c_str());\r
+\r
+                    Stopping = false;\r
+\r
+                    if (QuitWhenDone)\r
+                        SendMessage (GetDlgItem (Dlg, IDC_QUIT), BM_CLICK, 0, 0);\r
+                }\r
+            }\r
+\r
+            SetTimer (Dlg, 1, IDLETIME, NULL);\r
+            return (0);\r
+\r
+\r
+        case WM_UPDATEINFO:\r
+            UpdateDefragInfo (Dlg);\r
+            return (1);\r
+\r
+\r
+        case WM_CLOSE:\r
+            SendMessage (GetDlgItem (Dlg, IDC_QUIT), BM_CLICK, 0, 0);\r
+            return (1);\r
+\r
+\r
+        case WM_COMMAND:\r
+            switch (LOWORD(WParam))\r
+            {\r
+                case IDC_PRIORITY_LIST:\r
+                    UpdatePriority (Dlg);\r
+                    return (1);\r
+\r
+\r
+                case ID_MAIN_HELP:\r
+                    ShellExecute (Dlg, "open", "Fraginator.chm", "", ".", SW_SHOW);\r
+                    return (1);\r
+\r
+\r
+                case IDC_QUIT:\r
+                    if (Defrag == NULL)\r
+                    {   // This is the code executing when quitting\r
+                        SaveSettings (Dlg);\r
+                        EndDialog (Dlg, 0);\r
+                    }\r
+                    else\r
+                    {   // Tell defragging to finish and disable our button\r
+                        QuitWhenDone = true;\r
+                        SendMessage (GetDlgItem (Dlg, IDC_STARTSTOP), BM_CLICK, 0, 0);\r
+                        EnableWindow (GetDlgItem (Dlg, IDC_QUIT), FALSE);\r
+                    }\r
+                    return (1);\r
+\r
+\r
+                case IDC_STARTSTOP:\r
+                    if (Defrag == NULL)\r
+                    {   // "Start"\r
+                        char Drive[10];\r
+                        LRESULT ID;\r
+                        DefragType Method;\r
+                        HANDLE H;\r
+\r
+                        if (Defrag != NULL)\r
+                            return (1);\r
+\r
+                        SendMessage (GetDlgItem (Dlg, IDC_DRIVES_LIST), WM_GETTEXT, \r
+                            sizeof (Drive) - 1, (LPARAM) Drive);\r
+\r
+                        if (strlen(Drive) != 2  ||  Drive[1] != ':')\r
+                            return (1);\r
+\r
+                        ID = SendMessage (GetDlgItem (Dlg, IDC_METHODS_LIST), CB_GETCURSEL, 0, 0);\r
+                        Method = DefragInvalid;\r
+                        if (ID == AnalyzeID)\r
+                            Method = DefragAnalyze;\r
+                        else\r
+                        if (ID == FastID)\r
+                            Method = DefragFast;\r
+                        else\r
+                        if (ID == ExtensiveID)\r
+                            Method = DefragExtensive;\r
+\r
+                        if (Method != DefragInvalid)\r
+                        {\r
+                            Defrag = StartDefragThread (Drive, Method, H);\r
+                            Defrag->SetDoLimitLength (false);\r
+                            SetWindowText (Dlg, GetDefragTitle().c_str());\r
+                            SetDisables (Dlg);\r
+                        }   \r
+                    }\r
+                    else\r
+                    {   // "Stop"\r
+                        Stopping = true;\r
+                        Defrag->Stop ();\r
+                        EnableWindow (GetDlgItem (Dlg, IDC_STARTSTOP), FALSE);\r
+                        EnableWindow (GetDlgItem (Dlg, IDC_QUIT), FALSE);\r
+                    }\r
+                    return (1);\r
+            }\r
+    }\r
+\r
+    // Otherwise, return 0 to say we did not process the message.\r
+    return (0);\r
+}\r
diff --git a/rosapps/fraginator/MainDialog.h b/rosapps/fraginator/MainDialog.h
new file mode 100644 (file)
index 0000000..88d5496
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef MAINDIALOG_H\r
+#define MAINDIALOG_H\r
+\r
+\r
+#include <windows.h>\r
+\r
+\r
+#define WM_UPDATEINFO (WM_USER + 1)\r
+\r
+\r
+INT_PTR CALLBACK MainDialogProc (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam);\r
+\r
+\r
+#endif // MAINDIALOG_H
\ No newline at end of file
diff --git a/rosapps/fraginator/Mutex.h b/rosapps/fraginator/Mutex.h
new file mode 100644 (file)
index 0000000..5a36c9f
--- /dev/null
@@ -0,0 +1,78 @@
+/*****************************************************************************\r
+\r
+  Mutex\r
+\r
+*****************************************************************************/\r
+\r
+\r
+#ifndef MUTEX_H\r
+#define MUTEX_H\r
+\r
+\r
+#include "Unfrag.h"\r
+\r
+\r
+class Mutex\r
+{\r
+public:\r
+    Mutex ()\r
+    {\r
+       // NT only code begin ... Win9x disregards this part\r
+       SECURITY_ATTRIBUTES MutexAttribs;\r
+\r
+       memset (&MutexAttribs, 0, sizeof (SECURITY_ATTRIBUTES));\r
+\r
+       MutexAttribs.bInheritHandle = false;\r
+       MutexAttribs.nLength = sizeof (SECURITY_ATTRIBUTES);\r
+       MutexAttribs.lpSecurityDescriptor = NULL;\r
+       // NT only code end\r
+\r
+       Locked      = false;\r
+       LockCount   = 0;\r
+       MutexHandle = CreateMutex (&MutexAttribs, Locked, NULL);\r
+\r
+        return;\r
+    }\r
+\r
+    ~Mutex ()\r
+    {\r
+       Lock ();\r
+       CloseHandle (MutexHandle);\r
+    }\r
+\r
+    void Lock (void)\r
+    {\r
+       Locked = true;\r
+       WaitForSingleObject (MutexHandle, INFINITE);\r
+       LockCount += 1;\r
+        return;\r
+    }\r
+\r
+\r
+    void Unlock   (void)\r
+    {\r
+           LockCount -= 1;\r
+           if (LockCount <= 0)\r
+           {\r
+                   LockCount = 0;\r
+                   Locked = false;\r
+       }\r
+\r
+       ReleaseMutex (MutexHandle);\r
+        return;\r
+    }\r
+\r
+\r
+    bool IsLocked (void)  \r
+    { \r
+        return (Locked); \r
+    }\r
+\r
+protected:\r
+    uint32 LockCount;\r
+    HANDLE MutexHandle;\r
+    bool   Locked;\r
+};\r
+\r
+\r
+#endif // MUTEX_H\r
diff --git a/rosapps/fraginator/ReportDialog.cpp b/rosapps/fraginator/ReportDialog.cpp
new file mode 100644 (file)
index 0000000..4ddad62
--- /dev/null
@@ -0,0 +1,231 @@
+#include "ReportDialog.h"\r
+#include "unfrag.h"\r
+#include "Fraginator.h"\r
+#include "DriveVolume.h"\r
+#include "Defragment.h"\r
+#include "resource.h"\r
+\r
+\r
+void SetReportInfo (HWND Dlg, DefragReport &Report, uint32 BytesDivisor, char *BytesUnits, bool Fractional)\r
+{\r
+    char Text[1000];\r
+    char Text2[1000];\r
+    char Text3[1000];\r
+\r
+    memset (Text, 0, sizeof (Text));\r
+\r
+    // Volume name\r
+    SetDlgItemText (Dlg, IDC_DRIVELETTER, Report.RootPath.c_str());\r
+\r
+    // Volume label\r
+    SetDlgItemText (Dlg, IDC_VOLUMELABEL, Defrag->GetVolume().GetVolumeInfo().Name.c_str());\r
+\r
+    // Volume Serial\r
+    SetDlgItemText (Dlg, IDC_VOLUMESERIAL, Defrag->GetVolume().GetVolumeInfo().Serial.c_str());\r
+\r
+    // File System\r
+    SetDlgItemText (Dlg, IDC_FILESYSTEM, Defrag->GetVolume().GetVolumeInfo().FileSystem.c_str());\r
+\r
+    // DiskSizeBytes\r
+    if (Fractional)\r
+    {\r
+        sprintf (Text, "%.2f %s", (double)(signed)(Report.DiskSizeBytes / \r
+            (BytesDivisor / 1024)) / 1024.0, BytesUnits);\r
+    }\r
+    else\r
+    {\r
+        AddCommas (Text, Report.DiskSizeBytes / BytesDivisor);\r
+        strcat (Text, " ");\r
+        strcat (Text, BytesUnits);\r
+    }\r
+\r
+    SetDlgItemText (Dlg, IDC_DISKSIZEBYTES, Text);\r
+\r
+    // DiskFreeBytes\r
+    if (Fractional)\r
+    {\r
+        sprintf (Text, "%.2f %s", (double)(signed)(Defrag->GetVolume().GetVolumeInfo().FreeBytes / \r
+            (BytesDivisor / 1024)) / 1024.0, BytesUnits);\r
+    }\r
+    else\r
+    {\r
+        AddCommas (Text, Defrag->GetVolume().GetVolumeInfo().FreeBytes / BytesDivisor);\r
+        strcat (Text, " ");\r
+        strcat (Text, BytesUnits);\r
+    }\r
+    SetDlgItemText (Dlg, IDC_DISKFREEBYTES, Text);\r
+\r
+    // DiskSizeClusters\r
+    AddCommas (Text, Defrag->GetVolume().GetVolumeInfo().ClusterCount);\r
+    strcat (Text, " clusters");\r
+    SetDlgItemText (Dlg, IDC_DISKSIZECLUSTERS, Text);\r
+\r
+    // DiskClusterSize\r
+    sprintf (Text, "%u bytes", Defrag->GetVolume().GetVolumeInfo().ClusterSize);\r
+    SetDlgItemText (Dlg, IDC_DISKCLUSTERSIZE, Text);\r
+\r
+    // DirsCount\r
+    AddCommas (Text, Report.DirsCount);\r
+    SetDlgItemText (Dlg, IDC_DIRSCOUNT, Text);\r
+\r
+    // FilesCount\r
+    AddCommas (Text, Report.FilesCount);\r
+    SetDlgItemText (Dlg, IDC_FILESCOUNT, Text);\r
+\r
+    // FilesFragged\r
+    sprintf (Text, "(%.2f%%)", Report.PercentFragged);\r
+    AddCommas (Text2, Report.FraggedFiles.size());\r
+    sprintf (Text3, "%s %s", Text, Text2);\r
+    SetDlgItemText (Dlg, IDC_FILESFRAGGED, Text3);\r
+\r
+    // Average Frags\r
+    sprintf (Text, "%.2f", Report.AverageFragments);\r
+    SetDlgItemText (Dlg, IDC_AVERAGEFRAGS, Text);\r
+\r
+    // FilesSizeBytes\r
+    if (Fractional)\r
+    {\r
+        sprintf (Text, "%.2f %s", (double)(signed)(Report.FilesSizeBytes / \r
+            (BytesDivisor / 1024)) / 1024.0, BytesUnits);\r
+    }\r
+    else\r
+    {\r
+        AddCommas (Text, Report.FilesSizeBytes / (uint64)BytesDivisor);\r
+        strcat (Text, " ");\r
+        strcat (Text, BytesUnits);\r
+    }\r
+    SetDlgItemText (Dlg, IDC_FILESSIZEBYTES, Text);\r
+\r
+    // Files SizeOnDisk\r
+    if (Fractional)\r
+    {\r
+        sprintf (Text, "%.2f %s", (double)(signed)((Report.FilesSizeBytes + Report.FilesSlackBytes) / \r
+            (BytesDivisor / 1024)) / 1024.0, BytesUnits);\r
+    }\r
+    else\r
+    {\r
+        AddCommas (Text, (Report.FilesSizeBytes + Report.FilesSlackBytes) / (uint64)BytesDivisor);\r
+        strcat (Text, " ");\r
+        strcat (Text, BytesUnits);\r
+       \r
+    }\r
+    SetDlgItemText (Dlg, IDC_FILESSIZEONDISK, Text);\r
+\r
+    // FilesSlackBytes\r
+    if (Fractional)\r
+    {\r
+        sprintf (Text, "%.2f %s", (double)(signed)(Report.FilesSlackBytes / \r
+            (BytesDivisor / 1024)) / 1024.0, BytesUnits);\r
+    }\r
+    else\r
+    {\r
+        AddCommas (Text, Report.FilesSlackBytes / BytesDivisor);\r
+        strcat (Text, " ");\r
+        strcat (Text, BytesUnits);\r
+    }\r
+    sprintf (Text2, "(%.2f%%)", Report.PercentSlack);\r
+    sprintf (Text3, "%s %s", Text2, Text);\r
+    SetDlgItemText (Dlg, IDC_FILESSLACKBYTES, Text3);\r
+\r
+    // Recommendation\r
+    bool PFRec = false; // Recommend based off percent fragged files?\r
+    bool AFRec = false; // Recommend based off average fragments per file?\r
+\r
+    if (Report.PercentFragged >= 5.0f)\r
+        PFRec = true;\r
+\r
+    if (Report.AverageFragments >= 1.1f)\r
+        AFRec = true;\r
+\r
+    strcpy (Text, "* ");\r
+\r
+    if (PFRec)\r
+    {\r
+        sprintf \r
+        (\r
+            Text2,\r
+            "%.2f%% of the files on this volume are fragmented. ",\r
+            Report.PercentFragged\r
+        );\r
+\r
+        strcat (Text, Text2);\r
+    }\r
+\r
+    if (AFRec)\r
+    {\r
+        sprintf\r
+        (\r
+            Text2,\r
+            "The average fragments per file (%.2f) indicates a high degree of fragmentation. ",\r
+            Report.AverageFragments\r
+        );\r
+\r
+        strcat (Text, Text2);\r
+    }\r
+\r
+    if (Report.PercentFragged <  5.0f  &&  Report.AverageFragments < 1.1f)\r
+        sprintf (Text, "* No defragmentation is necessary at this point.");\r
+    else\r
+    if (Report.PercentFragged < 15.0f  &&  Report.AverageFragments < 1.3f)\r
+        strcat (Text, "It is recommended that you perform a Fast Defrag.");\r
+    else\r
+        strcat (Text, "It is recommended that you perform an Extensive Defrag.");\r
+\r
+    // Should we recommend a smaller cluster size?\r
+    if (Report.PercentSlack >= 10.0f)\r
+    {\r
+        sprintf \r
+        (\r
+            Text2, \r
+            "\n* A large amount of disk space (%.2f%%) is being lost "\r
+            "due to a large (%u bytes) cluster size. It is recommended "\r
+            "that you use a disk utility such as Partition Magic to "\r
+            "reduce the cluster size of this volume.",\r
+            Report.PercentSlack,\r
+            Defrag->GetVolume().GetVolumeInfo().ClusterSize\r
+        );\r
+\r
+        strcat (Text, Text2);\r
+    }\r
+\r
+    SetDlgItemText (Dlg, IDC_RECOMMEND, Text);\r
+\r
+    return;\r
+}\r
+\r
+\r
+INT_PTR CALLBACK ReportDialogProc (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam)\r
+{\r
+    switch (Msg)\r
+    {\r
+        case WM_INITDIALOG:\r
+            SetReportInfo (Dlg, Defrag->GetDefragReport (), 1, "bytes", false);\r
+            return (1);\r
+\r
+        case WM_COMMAND:\r
+            switch (LOWORD(WParam))\r
+            {\r
+                case IDC_REPORTOK:\r
+                    EndDialog (Dlg, 0);\r
+                    return (1);\r
+\r
+                case IDC_GIGABYTES:\r
+                    SetReportInfo (Dlg, Defrag->GetDefragReport (), 1024*1024*1024, "GB", true);\r
+                    return (1);\r
+\r
+                case IDC_MEGABYTES:\r
+                    SetReportInfo (Dlg, Defrag->GetDefragReport (), 1024*1024, "MB", false);\r
+                    return (1);\r
+\r
+                case IDC_KILOBYTES:\r
+                    SetReportInfo (Dlg, Defrag->GetDefragReport (), 1024, "KB", false);\r
+                    return (1);\r
+\r
+                case IDC_BYTES:\r
+                    SetReportInfo (Dlg, Defrag->GetDefragReport (), 1, "bytes", false);\r
+                    return (1);\r
+            }\r
+    }\r
+\r
+    return (0);\r
+}\r
diff --git a/rosapps/fraginator/ReportDialog.h b/rosapps/fraginator/ReportDialog.h
new file mode 100644 (file)
index 0000000..d5de555
--- /dev/null
@@ -0,0 +1,18 @@
+/*****************************************************************************\r
+\r
+  ReportDialog\r
+\r
+*****************************************************************************/\r
+\r
+\r
+#ifndef REPORTDIALOG_H\r
+#define REPORTDIALOG_H\r
+\r
+\r
+#include <windows.h>\r
+\r
+\r
+INT_PTR CALLBACK ReportDialogProc (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam);\r
+\r
+\r
+#endif // REPORTDIALOG_H
\ No newline at end of file
diff --git a/rosapps/fraginator/Unfrag.cpp b/rosapps/fraginator/Unfrag.cpp
new file mode 100644 (file)
index 0000000..23477fd
--- /dev/null
@@ -0,0 +1,464 @@
+/*****************************************************************************\r
+\r
+  Unfrag\r
+\r
+*****************************************************************************/\r
+\r
+\r
+#include "Unfrag.h"\r
+#include "DriveVolume.h"\r
+#include "Defragment.h"\r
+#include <process.h>\r
+\r
+\r
+bool QuietMode = false;\r
+bool VerboseMode = false;\r
+\r
+\r
+// Makes sure we're in Windows 2000\r
+bool CheckWinVer (void)\r
+{\r
+    OSVERSIONINFO OSVersion;\r
+\r
+    ZeroMemory (&OSVersion, sizeof (OSVersion));\r
+    OSVersion.dwOSVersionInfoSize = sizeof (OSVersion);\r
+    GetVersionEx (&OSVersion);\r
+    \r
+    // Need Windows 2000!\r
+\r
+    // Check for NT first\r
+    // Actually what we do is check that we're not on Win31+Win32s and that we're\r
+    // not in Windows 9x. It's possible that there could be more Windows "platforms"\r
+    // in the future and there's no sense in claiming incompatibility.\r
+    if (OSVersion.dwPlatformId == VER_PLATFORM_WIN32s  ||\r
+        OSVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)\r
+    {\r
+        return (false);\r
+    }\r
+\r
+    // Ok we're in Windows NT, now make sure we're in 2000\r
+    if (OSVersion.dwMajorVersion < 5)\r
+        return (false);\r
+\r
+    // Kew, we're in at least Windows 2000 ("NT 5.0")\r
+    return (true);\r
+}\r
+\r
+\r
+char *AddCommas (char *Result, uint64 Number)\r
+{\r
+       char  Temp[128];\r
+       int   TempLen;\r
+       char *p = NULL;\r
+       int   AddCommas = 0;\r
+       char *StrPosResult = NULL;\r
+       char *StrPosOrig = NULL;\r
+\r
+       // we get the string form of the number, then we count down w/ AddCommas\r
+       // while copying the string from Temp1 to Result. when AddCommas % 3  == 1,\r
+       // slap in a commas as well, before the #.\r
+       sprintf (Temp, "%I64u", Number);\r
+       AddCommas = TempLen = strlen (Temp);\r
+       StrPosOrig   = Temp;\r
+       StrPosResult = Result;\r
+       while (AddCommas)\r
+       {\r
+               if ((AddCommas % 3) == 0  &&  AddCommas != TempLen) // avoid stuff like ",345"\r
+               {\r
+                       *StrPosResult = ',';\r
+                       StrPosResult++;\r
+               }\r
+\r
+               *StrPosResult = *StrPosOrig;\r
+               StrPosResult++;\r
+               StrPosOrig++;\r
+\r
+               *StrPosResult = 0;\r
+\r
+               AddCommas--;\r
+       }\r
+\r
+       return (Result);\r
+}\r
+\r
+\r
+void PrintBanner (void)\r
+{\r
+    printf ("%s v%s\n", APPNAME_CLI, APPVER_STR);\r
+    printf ("%s\n", APPCOPYRIGHT);\r
+    printf ("\n");\r
+\r
+    return;\r
+}\r
+\r
+\r
+void FraggerHelp (void)\r
+{\r
+    printf ("Usage: unfrag drive: [...] <-f | -e>\n");\r
+    printf ("\n");\r
+    printf ("drive:  : The drive to defrag. Should be two characters long, ie 'c:' or 'd:'.\n");\r
+    printf ("          Multiple drives may be given, and all will be simultaneously\n");\r
+    printf ("          defragmented using the same options.\n");\r
+    printf ("-f      : Do a fast defragmentation. Files that are not fragmented will not be\n");\r
+    printf ("          moved. Only one pass is made over the file list. Using this option\n");\r
+    printf ("          may result in not all files being defragmented, depending on\n");\r
+    printf ("          available disk space.\n");\r
+    printf ("-e      : Do an extensive defragmention. Files will be moved in an attempt to\n");\r
+    printf ("          defragment both files and free space.\n");\r
+\r
+    if (!CheckWinVer())\r
+    {\r
+        printf ("\n");\r
+        printf ("NOTE: This program requires Windows 2000, which is not presently running on\n");\r
+        printf ("this system.\n");\r
+    }\r
+\r
+    return;\r
+}\r
+\r
+\r
+void __cdecl DefragThread (LPVOID parm)\r
+{\r
+    Defragment *Defrag;\r
+\r
+    Defrag = (Defragment *) parm;\r
+    Defrag->Start ();\r
+\r
+    _endthread ();\r
+    return;\r
+}\r
+\r
+\r
+Defragment *StartDefragThread (string Drive, DefragType Method, HANDLE &Handle)\r
+{\r
+    Defragment *Defragger;\r
+    unsigned long Thread;\r
+\r
+    Defragger = new Defragment (Drive, Method);\r
+    //Thread = /*CreateThread*/ _beginthreadex (NULL, 0, DefragThread, Defragger, 0, &ThreadID);\r
+    Thread = _beginthread (DefragThread, 0, Defragger);\r
+    Handle = *((HANDLE *)&Thread);\r
+    return (Defragger);\r
+}\r
+\r
+\r
+// Main Initialization\r
+int __cdecl main (int argc, char **argv)\r
+{\r
+    vector<string>       Drives;\r
+    vector<Defragment *> Defrags;\r
+    DefragType           DefragMode = DefragInvalid;\r
+    int                  d;\r
+\r
+    PrintBanner ();\r
+\r
+    // Parse command line arguments\r
+    bool ValidCmdLine = false;\r
+    for (int c = 0; c < argc; c++)\r
+    {\r
+        if (strlen(argv[c]) == 2  &&  argv[c][1] == ':')\r
+        {\r
+            Drives.push_back (strupr(argv[c]));\r
+        }\r
+        else\r
+        if (argv[c][0] == '-'  ||  argv[c][0] == '/'  &&  strlen(argv[c]) == 2)\r
+        {\r
+            switch (tolower(argv[c][1]))\r
+            {\r
+                case '?' :\r
+                case 'h' :\r
+                    FraggerHelp ();\r
+                    return (0);\r
+\r
+                case 'f' :\r
+                    if (DefragMode != DefragInvalid)\r
+                    {\r
+                        ValidCmdLine = false;\r
+                        break;\r
+                    }\r
+                    DefragMode = DefragFast;\r
+                    ValidCmdLine = true;\r
+                    break;\r
+\r
+                case 'e' :\r
+                    if (DefragMode != DefragInvalid)\r
+                    {\r
+                        ValidCmdLine = false;\r
+                        break;\r
+                    }\r
+                    DefragMode = DefragExtensive;\r
+                    ValidCmdLine = true;\r
+                    break;\r
+\r
+            }\r
+        }\r
+    }\r
+\r
+    if (DefragMode == DefragInvalid)\r
+        ValidCmdLine = false;\r
+\r
+    if (!ValidCmdLine)\r
+    {\r
+        printf ("Invalid command-line options. Use '%s -?' for help.\n", argv[0]);\r
+        return (0);\r
+    }\r
+\r
+    // Check OS requirements\r
+    if (!CheckWinVer())\r
+    {\r
+        printf ("Fatal Error: This program requires Windows 2000.\n");\r
+        return (0);\r
+    }\r
+\r
+    for (d = 0; d < Drives.size (); d++)\r
+    {\r
+        HANDLE TossMe;\r
+        Defrags.push_back (StartDefragThread (Drives[d], DefragMode, TossMe));\r
+    }\r
+\r
+    for (d = 0; d < Drives.size () - 1; d++)\r
+        printf ("\n ");\r
+\r
+    bool Continue = true;\r
+    HANDLE Screen;\r
+\r
+    Screen = GetStdHandle (STD_OUTPUT_HANDLE);\r
+    while (Continue)\r
+    {\r
+        Sleep (25);\r
+\r
+        // Get current screen coords\r
+        CONSOLE_SCREEN_BUFFER_INFO ScreenInfo;\r
+\r
+        GetConsoleScreenBufferInfo (Screen, &ScreenInfo);\r
+\r
+        // Now set back to the beginning\r
+        ScreenInfo.dwCursorPosition.X = 0;\r
+        ScreenInfo.dwCursorPosition.Y -= Drives.size();\r
+        SetConsoleCursorPosition (Screen, ScreenInfo.dwCursorPosition);\r
+\r
+        for (d = 0; d < Drives.size (); d++)\r
+        {\r
+            printf ("\n%6.2f%% %-70s", Defrags[d]->GetStatusPercent(), Defrags[d]->GetStatusString().c_str());\r
+        }\r
+\r
+        // Determine if we should keep going\r
+        Continue = false;\r
+        for (d = 0; d < Drives.size (); d++)\r
+        {\r
+            if (!Defrags[d]->IsDoneYet()  &&  !Defrags[d]->HasError())\r
+                Continue = true;                \r
+        }\r
+    }\r
+\r
+#if 0\r
+    // Loop through the drives list\r
+    for (int d = 0; d < Drives.size(); d++)\r
+    {\r
+        DriveVolume *Drive;\r
+\r
+        Drive = new DriveVolume;\r
+\r
+        // First thing: build a file list.\r
+        printf ("Opening volume %s ...", Drives[d].c_str());\r
+        if (!Drive->Open (Drives[d]))\r
+        {\r
+            printf ("FAILED\n\n");\r
+            delete Drive;\r
+            continue;\r
+        }\r
+        printf ("\n");\r
+\r
+        printf ("    Getting drive bitmap ...");\r
+        if (!Drive->GetBitmap ())\r
+        {\r
+            printf ("FAILED\n\n");\r
+            delete Drive;\r
+            continue;\r
+        }\r
+        printf ("\n");\r
+\r
+        printf ("    Obtaining drive geometry ...");\r
+        if (!Drive->ObtainInfo ())\r
+        {\r
+            printf ("FAILED\n\n");\r
+            delete Drive;\r
+            continue;\r
+        }\r
+        printf ("\n");\r
+\r
+        printf ("    Building file database for drive %s ...", Drives[d].c_str());\r
+        if (!Drive->BuildFileList ())\r
+        {\r
+            printf ("FAILED\n\n");\r
+            delete Drive;\r
+            continue;\r
+        }\r
+        printf ("\n");\r
+\r
+        printf ("    %u files\n", Drive->GetDBFileCount ());\r
+\r
+        // Analyze only?\r
+        if (DefragMode == DefragAnalyze)\r
+        {\r
+            uint64 UsedBytes  = 0;  // total bytes used, with cluster size considerations\r
+            uint64 TotalBytes = 0;  // total bytes used\r
+            uint64 SlackBytes = 0;  // wasted space due to slack\r
+            uint32 Fragged    = 0;  // fragmented files\r
+\r
+            printf ("    Analyzing ...");\r
+            if (VerboseMode)\r
+                printf ("\n");\r
+\r
+            for (int i = 0; i < Drive->GetDBFileCount(); i++)\r
+            {\r
+                uint64 Used;\r
+                uint64 Slack;\r
+                FileInfo Info;\r
+\r
+                Info = Drive->GetDBFile (i);\r
+\r
+                // Compute total used disk space\r
+                Used = ((Info.Size + Drive->GetClusterSize() - 1) / Drive->GetClusterSize()) * Drive->GetClusterSize();\r
+                Slack = Used - Info.Size;\r
+\r
+                UsedBytes += Used;\r
+                SlackBytes += Slack;\r
+                TotalBytes += Info.Size;\r
+\r
+                if (VerboseMode)\r
+                {\r
+                    printf ("    %s%s, ", Drive->GetDBDir (Info.DirIndice).c_str(), Info.Name.c_str());\r
+\r
+                    if (Info.Attributes.AccessDenied)\r
+                        printf ("access was denied\n");\r
+                    else\r
+                    {\r
+                        if (Info.Attributes.Unmovable == 1)\r
+                            printf ("unmovable, ");\r
+\r
+                        printf ("%I64u bytes, %I64u bytes on disk, %I64u bytes slack, %u fragments\n", \r
+                            Info.Size, Used, Slack, Info.Fragments.size());\r
+                    }\r
+                }\r
+\r
+                if (Info.Fragments.size() > 1)\r
+                    Fragged++;\r
+            }\r
+\r
+            if (!VerboseMode)\r
+                printf ("\n");\r
+\r
+            // TODO: Make it not look like ass\r
+            printf ("\n");\r
+            printf ("    Overall Analysis\n");\r
+            printf ("    ----------------\n");\r
+            printf ("    %u clusters\n", Drive->GetClusterCount ());\r
+            printf ("    %u bytes per cluster\n", Drive->GetClusterSize());\r
+            printf ("    %I64u total bytes on drive\n", (uint64)Drive->GetClusterCount() * (uint64)Drive->GetClusterSize());\r
+            printf ("\n");\r
+            printf ("    %u files\n", Drive->GetDBFileCount ());\r
+            printf ("    %u contiguous files\n", Drive->GetDBFileCount () - Fragged);\r
+            printf ("    %u fragmented files\n", Fragged);\r
+            printf ("\n");\r
+            printf ("    %I64u bytes\n", TotalBytes);\r
+            printf ("    %I64u bytes on disk\n", UsedBytes);\r
+            printf ("    %I64u bytes slack\n", SlackBytes);\r
+        }\r
+\r
+        // Fast defragment!\r
+        if (DefragMode == DefragFast  ||  DefragMode == DefragExtensive)\r
+        {\r
+            uint32 i;\r
+            uint64 FirstFreeLCN;\r
+            char PrintName[80];\r
+            int Width = 66;\r
+\r
+            if (DefragMode == DefragFast)\r
+                printf ("    Performing fast file defragmentation ...\n");\r
+            else\r
+            if (DefragMode == DefragExtensive)\r
+                printf ("    Performing extensive file defragmentation\n");\r
+\r
+            // Find first free LCN for speedier searches ...\r
+            Drive->FindFreeRange (0, 1, FirstFreeLCN);\r
+\r
+            for (i = 0; i < Drive->GetDBFileCount(); i++)\r
+            {\r
+                FileInfo Info;\r
+                bool Result;\r
+                uint64 TargetLCN;\r
+\r
+                printf ("\r");\r
+\r
+                Info = Drive->GetDBFile (i);\r
+\r
+                FitName (PrintName, Drive->GetDBDir (Info.DirIndice).c_str(), Info.Name.c_str(), Width);\r
+                printf ("    %6.2f%% %-66s", (float)i / (float)Drive->GetDBFileCount() * 100.0f, PrintName);\r
+\r
+                // Can't defrag 0 byte files :)\r
+                if (Info.Fragments.size() == 0)\r
+                    continue;\r
+\r
+                // If doing fast defrag, skip non-fragmented files\r
+                if (Info.Fragments.size() == 1  &&  DefragMode == DefragFast)\r
+                    continue;\r
+\r
+                // Find a place that can fit the file\r
+                Result = Drive->FindFreeRange (FirstFreeLCN, Info.Clusters, TargetLCN);\r
+\r
+                // If we're doing an extensive defrag and the file is already defragmented\r
+                // and if its new location would be after its current location, don't\r
+                // move it.\r
+                if (DefragMode == DefragExtensive  &&  Info.Fragments.size() == 1)\r
+                {\r
+                    if (TargetLCN > Info.Fragments[0].StartLCN)\r
+                        continue;\r
+                }\r
+\r
+                // Otherwise, defrag0rize it!\r
+                if (Result)\r
+                {\r
+                    bool Success = false;\r
+\r
+                    if (Drive->MoveFileDumb (i, TargetLCN))\r
+                        Success = true;\r
+                    else\r
+                    {   // hmm, look for another area to move it to\r
+                        Result = Drive->FindFreeRange (TargetLCN + 1, Info.Clusters, TargetLCN);\r
+                        if (Result)\r
+                        {\r
+                            if (Drive->MoveFileDumb (i, TargetLCN))\r
+                                Success = true;\r
+                            else\r
+                            {   // Try updating the drive bitmap\r
+                                if (Drive->GetBitmap ())\r
+                                {\r
+                                    Result = Drive->FindFreeRange (0, Info.Clusters, TargetLCN);\r
+                                    if (Result)\r
+                                    {\r
+                                        if (Drive->MoveFileDumb (i, TargetLCN))\r
+                                            Success = true;\r
+                                    }\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+\r
+                    if (!Success)\r
+                        printf ("\n        -> failed\n");\r
+\r
+                    Drive->FindFreeRange (0, 1, FirstFreeLCN);\r
+                }\r
+            }\r
+\r
+            printf ("\n");\r
+        }\r
+        printf ("Closing volume %s ...", Drives[d].c_str());\r
+        delete Drive;\r
+        printf ("\n");\r
+    }\r
+#endif\r
+\r
+    return (0);\r
+}\r
diff --git a/rosapps/fraginator/Unfrag.h b/rosapps/fraginator/Unfrag.h
new file mode 100644 (file)
index 0000000..877d7cc
--- /dev/null
@@ -0,0 +1,83 @@
+/*****************************************************************************\r
+\r
+  Unfrag\r
+\r
+*****************************************************************************/\r
+\r
+\r
+#ifndef UNFRAG_H\r
+#define UNFRAG_H\r
+\r
+\r
+// Blah blah blah your template name is too long ... SO WHAT\r
+#pragma warning (disable: 4786)\r
+\r
+\r
+// I forget what this disables\r
+#ifdef __ICL\r
+#pragma warning (disable: 268)\r
+#endif\r
+\r
+\r
+// Hello Mr. Platform SDK, please let us use Windows 2000 only features\r
+#ifndef WINVER\r
+#define WINVER 0x0500\r
+#define _WIN32_WINNT 0x0500\r
+#endif\r
+\r
+\r
+#include <windows.h>\r
+#include <string>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+\r
+\r
+#define APPNAME_CLI   "Unfrag"\r
+#define APPNAME_GUI   "Fraginator"\r
+#define APPVER_STR    "1.03"\r
+#define APPVER_NUM     1.03f\r
+#define APPAUTHOR     "Rick Brewster"\r
+#define APPCOPYRIGHT  "Copyright 2000-2002 Rick Brewster"\r
+\r
+\r
+#include <vector>\r
+#include <string>\r
+using namespace std;\r
+\r
+\r
+typedef unsigned __int8  uint8;\r
+typedef signed __int8    sint8;\r
+typedef unsigned __int16 uint16;\r
+typedef signed __int16   sint16;\r
+typedef unsigned __int32 uint32;\r
+typedef signed __int32   sint32;\r
+typedef unsigned __int64 uint64;\r
+typedef signed __int64   sint64;\r
+typedef unsigned char    uchar;\r
+\r
+\r
+extern bool QuietMode;\r
+extern bool VerboseMode;\r
+\r
+\r
+typedef enum\r
+{\r
+    DefragInvalid,\r
+    DefragFast,\r
+    DefragExtensive,\r
+    DefragAnalyze\r
+} DefragType;\r
+\r
+\r
+extern bool CheckWinVer (void);\r
+\r
+\r
+class Defragment;\r
+extern Defragment *StartDefragThread (string Drive, DefragType Method, HANDLE &Handle);\r
+\r
+\r
+extern char *AddCommas (char *Result, uint64 Number);\r
+\r
+\r
+#endif // UNFRAG_H\r
+\r
diff --git a/rosapps/fraginator/default1.bin b/rosapps/fraginator/default1.bin
new file mode 100644 (file)
index 0000000..5d598c0
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?> \r
+<assembly \r
+   xmlns="urn:schemas-microsoft-com:asm.v1" \r
+   manifestVersion="1.0">\r
+<assemblyIdentity \r
+    processorArchitecture="x86" \r
+    version="5.1.0.0"\r
+    type="win32"\r
+    name="Fraginator.exe"/>\r
+    <description>Fraginator</description>\r
+    <dependency>\r
+    <dependentAssembly>\r
+    <assemblyIdentity\r
+         type="win32"\r
+         name="Microsoft.Windows.Common-Controls"\r
+         version="6.0.0.0"\r
+         publicKeyToken="6595b64144ccf1df"\r
+         language="*"\r
+         processorArchitecture="x86"/>\r
+    </dependentAssembly>\r
+    </dependency>\r
+</assembly>\r
diff --git a/rosapps/fraginator/icon1.ico b/rosapps/fraginator/icon1.ico
new file mode 100644 (file)
index 0000000..4acbd2c
Binary files /dev/null and b/rosapps/fraginator/icon1.ico differ
diff --git a/rosapps/fraginator/resource.h b/rosapps/fraginator/resource.h
new file mode 100644 (file)
index 0000000..c98399e
--- /dev/null
@@ -0,0 +1,51 @@
+//{{NO_DEPENDENCIES}}\r
+// Microsoft Developer Studio generated include file.\r
+// Used by Fraginator.rc\r
+//\r
+#define IDD_DIALOG1                     101\r
+#define IDD_MAIN                        101\r
+#define IDD_REPORT                      106\r
+#define IDB_LOGO                        110\r
+#define IDI_ICON                        114\r
+#define IDC_QUIT                        1010\r
+#define IDC_STARTSTOP                   1014\r
+#define IDC_METHODS_LIST                1016\r
+#define IDC_DRIVES_LIST                 1019\r
+#define IDC_PROGRESS                    1021\r
+#define IDC_PERCENT                     1022\r
+#define IDC_STATUS                      1023\r
+#define IDC_DISKSIZEBYTES               1027\r
+#define IDC_DRIVELETTER                 1028\r
+#define IDC_REPORTOK                    1029\r
+#define IDC_DISKSIZECLUSTERS            1030\r
+#define IDC_DISKCLUSTERSIZE             1031\r
+#define IDC_FILESYSTEM                  1032\r
+#define IDC_WISECRACKS                  1033\r
+#define IDC_VOLUMELABEL                 1033\r
+#define IDC_VOLUMESERIAL                1034\r
+#define IDC_BYTES                       1035\r
+#define IDC_KILOBYTES                   1036\r
+#define IDC_RECOMMEND                   1037\r
+#define IDC_FILESCOUNT                  1038\r
+#define IDC_FILESSIZEBYTES              1039\r
+#define IDC_FILESSIZEONDISK             1040\r
+#define IDC_FILESSLACKBYTES             1041\r
+#define IDC_GIGABYTES                   1043\r
+#define IDC_DISKFREEBYTES               1044\r
+#define IDC_MEGABYTES                   1045\r
+#define IDC_FILESFRAGGED                1047\r
+#define IDC_DIRSCOUNT                   1048\r
+#define IDC_AVERAGEFRAGS                1049\r
+#define ID_MAIN_HELP                    1054\r
+#define IDC_PRIORITY_LIST               1057\r
+\r
+// Next default values for new objects\r
+// \r
+#ifdef APSTUDIO_INVOKED\r
+#ifndef APSTUDIO_READONLY_SYMBOLS\r
+#define _APS_NEXT_RESOURCE_VALUE        118\r
+#define _APS_NEXT_COMMAND_VALUE         40001\r
+#define _APS_NEXT_CONTROL_VALUE         1058\r
+#define _APS_NEXT_SYMED_VALUE           101\r
+#endif\r
+#endif\r
diff --git a/rosapps/fraginator/unfrag.dsp b/rosapps/fraginator/unfrag.dsp
new file mode 100644 (file)
index 0000000..fd5e868
--- /dev/null
@@ -0,0 +1,133 @@
+# Microsoft Developer Studio Project File - Name="unfrag" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=unfrag - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "unfrag.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "unfrag.mak" CFG="unfrag - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "unfrag - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "unfrag - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=xicl6.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "unfrag - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /G6 /Gr /MD /W3 /GX /Ox /Ot /Og /Oi /Ob2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=xilink6.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# Begin Special Build Tool\r
+SOURCE="$(InputPath)"\r
+PostBuild_Desc=Copying to Program Files ...\r
+PostBuild_Cmds=copy Release\unfrag.exe "c:\Program Files\Fraginator\unfrag.exe"\r
+# End Special Build Tool\r
+\r
+!ELSEIF  "$(CFG)" == "unfrag - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "unfrag___Win32_Debug"\r
+# PROP BASE Intermediate_Dir "unfrag___Win32_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "unfrag___Win32_Debug"\r
+# PROP Intermediate_Dir "unfrag___Win32_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=xilink6.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "unfrag - Win32 Release"\r
+# Name "unfrag - Win32 Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=.\Defragment.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\DriveVolume.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Unfrag.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=.\Defragment.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\DriveVolume.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Mutex.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\Unfrag.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/rosapps/fraginator/unfrag.exe b/rosapps/fraginator/unfrag.exe
new file mode 100644 (file)
index 0000000..bcb1aef
Binary files /dev/null and b/rosapps/fraginator/unfrag.exe differ
diff --git a/rosapps/fraginator/unfrag.mak b/rosapps/fraginator/unfrag.mak
new file mode 100644 (file)
index 0000000..838fc08
--- /dev/null
@@ -0,0 +1,184 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on unfrag.dsp\r
+!IF "$(CFG)" == ""\r
+CFG=unfrag - Win32 Debug\r
+!MESSAGE No configuration specified. Defaulting to unfrag - Win32 Debug.\r
+!ENDIF \r
+\r
+!IF "$(CFG)" != "unfrag - Win32 Release" && "$(CFG)" != "unfrag - Win32 Debug"\r
+!MESSAGE Invalid configuration "$(CFG)" specified.\r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "unfrag.mak" CFG="unfrag - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "unfrag - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "unfrag - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+!ERROR An invalid configuration is specified.\r
+!ENDIF \r
+\r
+!IF "$(OS)" == "Windows_NT"\r
+NULL=\r
+!ELSE \r
+NULL=nul\r
+!ENDIF \r
+\r
+CPP=xicl6.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "unfrag - Win32 Release"\r
+\r
+OUTDIR=.\Release\r
+INTDIR=.\Release\r
+# Begin Custom Macros\r
+OutDir=.\Release\r
+# End Custom Macros\r
+\r
+ALL : "$(OUTDIR)\unfrag.exe"\r
+\r
+\r
+CLEAN :\r
+       -@erase "$(INTDIR)\Defragment.obj"\r
+       -@erase "$(INTDIR)\DriveVolume.obj"\r
+       -@erase "$(INTDIR)\Unfrag.obj"\r
+       -@erase "$(INTDIR)\vc60.idb"\r
+       -@erase "$(OUTDIR)\unfrag.exe"\r
+\r
+"$(OUTDIR)" :\r
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"\r
+\r
+CPP_PROJ=/nologo /G6 /Gr /MD /W3 /GX /Ox /Ot /Og /Oi /Ob2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\unfrag.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c \r
+BSC32=bscmake.exe\r
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\unfrag.bsc" \r
+BSC32_SBRS= \\r
+       \r
+LINK32=xilink6.exe\r
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\unfrag.pdb" /machine:I386 /out:"$(OUTDIR)\unfrag.exe" \r
+LINK32_OBJS= \\r
+       "$(INTDIR)\Defragment.obj" \\r
+       "$(INTDIR)\DriveVolume.obj" \\r
+       "$(INTDIR)\Unfrag.obj"\r
+\r
+"$(OUTDIR)\unfrag.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)\r
+    $(LINK32) @<<\r
+  $(LINK32_FLAGS) $(LINK32_OBJS)\r
+<<\r
+\r
+SOURCE="$(InputPath)"\r
+PostBuild_Desc=Copying to Program Files ...\r
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep\r
+\r
+ALL : $(DS_POSTBUILD_DEP)\r
+\r
+# Begin Custom Macros\r
+OutDir=.\Release\r
+# End Custom Macros\r
+\r
+$(DS_POSTBUILD_DEP) : "$(OUTDIR)\unfrag.exe"\r
+   copy Release\unfrag.exe "c:\Program Files\Fraginator\unfrag.exe"\r
+       echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"\r
+\r
+!ELSEIF  "$(CFG)" == "unfrag - Win32 Debug"\r
+\r
+OUTDIR=.\unfrag___Win32_Debug\r
+INTDIR=.\unfrag___Win32_Debug\r
+# Begin Custom Macros\r
+OutDir=.\unfrag___Win32_Debug\r
+# End Custom Macros\r
+\r
+ALL : "$(OUTDIR)\unfrag.exe"\r
+\r
+\r
+CLEAN :\r
+       -@erase "$(INTDIR)\Defragment.obj"\r
+       -@erase "$(INTDIR)\DriveVolume.obj"\r
+       -@erase "$(INTDIR)\Unfrag.obj"\r
+       -@erase "$(INTDIR)\vc60.idb"\r
+       -@erase "$(INTDIR)\vc60.pdb"\r
+       -@erase "$(OUTDIR)\unfrag.exe"\r
+       -@erase "$(OUTDIR)\unfrag.ilk"\r
+       -@erase "$(OUTDIR)\unfrag.pdb"\r
+\r
+"$(OUTDIR)" :\r
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"\r
+\r
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\unfrag.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c \r
+BSC32=bscmake.exe\r
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\unfrag.bsc" \r
+BSC32_SBRS= \\r
+       \r
+LINK32=xilink6.exe\r
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\unfrag.pdb" /debug /machine:I386 /out:"$(OUTDIR)\unfrag.exe" /pdbtype:sept \r
+LINK32_OBJS= \\r
+       "$(INTDIR)\Defragment.obj" \\r
+       "$(INTDIR)\DriveVolume.obj" \\r
+       "$(INTDIR)\Unfrag.obj"\r
+\r
+"$(OUTDIR)\unfrag.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)\r
+    $(LINK32) @<<\r
+  $(LINK32_FLAGS) $(LINK32_OBJS)\r
+<<\r
+\r
+!ENDIF \r
+\r
+.c{$(INTDIR)}.obj::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.cpp{$(INTDIR)}.obj::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.cxx{$(INTDIR)}.obj::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.c{$(INTDIR)}.sbr::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.cpp{$(INTDIR)}.sbr::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+.cxx{$(INTDIR)}.sbr::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $< \r
+<<\r
+\r
+\r
+!IF "$(NO_EXTERNAL_DEPS)" != "1"\r
+!IF EXISTS("unfrag.dep")\r
+!INCLUDE "unfrag.dep"\r
+!ELSE \r
+!MESSAGE Warning: cannot find "unfrag.dep"\r
+!ENDIF \r
+!ENDIF \r
+\r
+\r
+!IF "$(CFG)" == "unfrag - Win32 Release" || "$(CFG)" == "unfrag - Win32 Debug"\r
+SOURCE=.\Defragment.cpp\r
+\r
+"$(INTDIR)\Defragment.obj" : $(SOURCE) "$(INTDIR)"\r
+\r
+\r
+SOURCE=.\DriveVolume.cpp\r
+\r
+"$(INTDIR)\DriveVolume.obj" : $(SOURCE) "$(INTDIR)"\r
+\r
+\r
+SOURCE=.\Unfrag.cpp\r
+\r
+"$(INTDIR)\Unfrag.obj" : $(SOURCE) "$(INTDIR)"\r
+\r
+\r
+\r
+!ENDIF \r
+\r
diff --git a/rosapps/fraginator/unfrag.plg b/rosapps/fraginator/unfrag.plg
new file mode 100644 (file)
index 0000000..5e0486e
--- /dev/null
@@ -0,0 +1,48 @@
+<html>\r
+<body>\r
+<pre>\r
+<h1>Build Log</h1>\r
+<h3>\r
+--------------------Configuration: unfrag - Win32 Release--------------------\r
+</h3>\r
+<h3>Command Lines</h3>\r
+Creating temporary file "C:\TEMP\RSP9D8.tmp" with contents\r
+[\r
+/nologo /G6 /Gr /MD /W3 /GX /Ox /Ot /Og /Oi /Ob2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"Release/" /Fd"Release/" /FD /c \r
+"C:\src\Fraginator\Defragment.cpp"\r
+"C:\src\Fraginator\DriveVolume.cpp"\r
+"C:\src\Fraginator\Unfrag.cpp"\r
+]\r
+Creating command line "xicl6.exe @C:\TEMP\RSP9D8.tmp" \r
+Creating temporary file "C:\TEMP\RSP9D9.tmp" with contents\r
+[\r
+kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"Release/unfrag.pdb" /machine:I386 /out:"Release/unfrag.exe" \r
+.\Release\Defragment.obj\r
+.\Release\DriveVolume.obj\r
+.\Release\Unfrag.obj\r
+]\r
+Creating command line "xilink6.exe @C:\TEMP\RSP9D9.tmp"\r
+<h3>Output Window</h3>\r
+Compiling...\r
+Defragment.cpp\r
+DriveVolume.cpp\r
+Unfrag.cpp\r
+Generating Code...\r
+Linking...\r
+xilink6: executing 'C:\PROGRA~1\MIAF9D~1\VC98\Bin\link.exe'\r
+Creating temporary file "C:\TEMP\RSP9DB.bat" with contents\r
+[\r
+@echo off\r
+copy Release\unfrag.exe "c:\Program Files\Fraginator\unfrag.exe"\r
+]\r
+Creating command line "C:\TEMP\RSP9DB.bat"\r
+Copying to Program Files ...\r
+        1 file(s) copied.\r
+\r
+\r
+\r
+<h3>Results</h3>\r
+unfrag.exe - 0 error(s), 0 warning(s)\r
+</pre>\r
+</body>\r
+</html>\r
diff --git a/rosapps/fraginator/unfrag.vcproj b/rosapps/fraginator/unfrag.vcproj
new file mode 100644 (file)
index 0000000..efb793f
--- /dev/null
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="unfrag"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\Release"\r
+                       IntermediateDirectory=".\Release"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="3"\r
+                               GlobalOptimizations="TRUE"\r
+                               InlineFunctionExpansion="2"\r
+                               EnableIntrinsicFunctions="TRUE"\r
+                               FavorSizeOrSpeed="1"\r
+                               OptimizeForProcessor="2"\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"\r
+                               RuntimeLibrary="0"\r
+                               StructMemberAlignment="5"\r
+                               BufferSecurityCheck="FALSE"\r
+                               PrecompiledHeaderFile=".\Release/unfrag.pch"\r
+                               AssemblerListingLocation=".\Release/"\r
+                               ObjectFile=".\Release/"\r
+                               ProgramDataBaseFileName=".\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CallingConvention="1"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile=".\Release/unfrag.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ProgramDatabaseFile=".\Release/unfrag.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\Release/unfrag.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               Description="Copying to Program Files ..."\r
+                               CommandLine="copy Release\unfrag.exe &quot;c:\Program Files\Fraginator\unfrag.exe&quot;"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\unfrag___Win32_Debug"\r
+                       IntermediateDirectory=".\unfrag___Win32_Debug"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               PrecompiledHeaderFile=".\unfrag___Win32_Debug/unfrag.pch"\r
+                               AssemblerListingLocation=".\unfrag___Win32_Debug/"\r
+                               ObjectFile=".\unfrag___Win32_Debug/"\r
+                               ProgramDataBaseFileName=".\unfrag___Win32_Debug/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="4"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile=".\unfrag___Win32_Debug/unfrag.exe"\r
+                               LinkIncremental="2"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\unfrag___Win32_Debug/unfrag.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\unfrag___Win32_Debug/unfrag.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath=".\Defragment.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\DriveVolume.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Unfrag.cpp">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath=".\Defragment.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\DriveVolume.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Mutex.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\Unfrag.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r