[Forensics-changes] [SCM] debian-forensics/guymager branch, debian, updated. debian/0.5.7beta1-1-15-g9323d54
Michael Prokop
mika at debian.org
Sun Jul 10 15:34:59 UTC 2011
The following commit has been merged in the debian branch:
commit dfa65a9ccd957787df1eb756dc609781f5713d79
Author: Michael Prokop <mika at debian.org>
Date: Wed Jul 6 18:24:37 2011 +0200
Merging upstream version 0.5.8.
diff --git a/.kdbgrc.guymager b/.kdbgrc.guymager
new file mode 100644
index 0000000..67b13b5
--- /dev/null
+++ b/.kdbgrc.guymager
@@ -0,0 +1,20 @@
+[General]
+DebuggerCmdStr=
+DriverName=GDB
+FileVersion=1
+OptionsSelected=
+ProgramArgs=cfg=./guymager.cfg SignalHandling=off
+TTYLevel=7
+WorkingDirectory=
+
+[Memory]
+ColumnWidths=80,0
+NumExprs=0
+
+[Watches]
+Expr0=pDlgAcquireRule
+Expr1=pLineEdit
+Expr2=pLineEditDest
+Expr3=pDlgAcquireFields
+Expr4=i
+Expr5=Row
diff --git a/.kdev4/trunk.kdev4 b/.kdev4/trunk.kdev4
new file mode 100644
index 0000000..d06d7b3
--- /dev/null
+++ b/.kdev4/trunk.kdev4
@@ -0,0 +1,9 @@
+[Buildset]
+BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x00)
+
+[MakeBuilder]
+Abort on First Error=false
+Number Of Jobs=7
+
+[Project]
+VersionControlSupport=kdevsubversion
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/CREDITS b/CREDITS
new file mode 100644
index 0000000..f9ed512
--- /dev/null
+++ b/CREDITS
@@ -0,0 +1,7 @@
+
+Joachim Metz <joachim.metz at gmail.com>
+ Guymager uses Joachim's libewf for writing EWF image files. Without
+ Joachim's work on the EWF format, the Guymager project would probably
+ never have been started. Special thanks to Joachim as well for
+ believing in the idea of parallelised compression and adding the
+ necessary extra functions to libewf for Guymager.
diff --git a/aaff.cpp b/aaff.cpp
index 6ff4994..6ddb702 100644
--- a/aaff.cpp
+++ b/aaff.cpp
@@ -9,6 +9,23 @@
// Module: Multithreaded AFF (AAFF = Avanced AFF)
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include "common.h"
#include "compileinfo.h"
diff --git a/aaff.h b/aaff.h
index 160de1f..3950ccd 100644
--- a/aaff.h
+++ b/aaff.h
@@ -9,6 +9,23 @@
// Module: Multithreaded AFF (AAFF = Avanced AFF)
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __AAFF_H__
#define __AAFF_H__
@@ -23,10 +40,10 @@ typedef struct
#define AAFF_SEGNAME_COMMAND_LINE "acquisition_commandline"
#define AAFF_SEGNAME_MACADDR "acquisition_macaddr"
-#define AAFF_SEGNAME_DATE "acquisition_date" // Format: YYYY-MM-DD HH:MM:SS TZT
-#define AAFF_SEGNAME_DEVICE "acquisition_device"
-#define AAFF_SEGNAME_MODEL "device_model"
-#define AAFF_SEGNAME_SN "device_sn"
+#define AAFF_SEGNAME_DATE "acquisition_date" // Format: YYYY-MM-DD HH:MM:SS TZT
+#define AAFF_SEGNAME_DEVICE "acquisition_device"
+#define AAFF_SEGNAME_MODEL "device_model"
+#define AAFF_SEGNAME_SN "device_sn"
// ------------------------------------
// Functions
diff --git a/aewf.cpp b/aewf.cpp
new file mode 100644
index 0000000..a2e7e5a
--- /dev/null
+++ b/aewf.cpp
@@ -0,0 +1,142 @@
+// ****************************************************************************
+// Project: GUYMAGER
+// ****************************************************************************
+// Programmer: Guy Voncken
+// Police Grand-Ducale
+// Service de Police Judiciaire
+// Section Nouvelles Technologies
+// ****************************************************************************
+// Module: Multithreaded AEWF (AEWF = Avanced EWF)
+// ****************************************************************************
+
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
+#include "common.h"
+#include "compileinfo.h"
+
+#include <netinet/in.h>
+#include <string.h>
+#include <time.h> //lint !e537 repeated include file
+#include <stdlib.h>
+#include <zlib.h>
+
+#include <QString>
+
+#include "util.h"
+#include "config.h"
+#include "aewf.h"
+
+// -----------------
+// EWF definitions
+// -----------------
+
+#define EWF_ xx
+
+// ------------------
+// Aewf definitions
+// ------------------
+
+typedef struct _t_Aewf
+{
+} t_Aewf;
+
+// ----------------
+// Error handling
+// ----------------
+
+#define CHK_FWRITE(Fn) \
+ if ((Fn) != 1) \
+ CHK (ERROR_AEWF_CANNOT_WRITE_FILE)
+
+
+// -------------------
+// Utility functions
+// -------------------
+
+
+// -------------------
+// Segment functions
+// -------------------
+
+// ---------------
+// API functions
+// ---------------
+
+
+// ---------------------
+// API write functions
+// ---------------------
+
+APIRET AewfOpen (t_pAewf */*ppAewf*/, const char */*pFilename*/, unsigned long long /*DeviceSize*/, unsigned int /*SectorSize*/, unsigned int /*ChunkSize*/)
+{
+ return NO_ERROR;
+}
+
+
+APIRET AewfClose (t_pAewf */*ppAewf*/, unsigned long long /*BadSectors*/, const unsigned char */*pMD5*/, const unsigned char */*pSHA256*/, int /*Duration*/)
+{
+ return NO_ERROR;
+}
+
+
+APIRET AewfPreprocess (t_pAewfPreprocess */*ppPreprocess*/, unsigned char */*pDataIn*/, unsigned int /*DataLenIn*/, unsigned char */*pDataOut*/, unsigned int /*DataLenOut*/)
+{
+ return NO_ERROR;
+}
+
+
+APIRET AewfWrite (t_pAewf /*pAewf*/, t_pAewfPreprocess /*pPreprocess*/, const unsigned char */*pData*/, unsigned int /*DataLen*/)
+{
+ return NO_ERROR;
+}
+
+// ---------------------
+// API read functions
+// ---------------------
+
+APIRET AewfOpen (t_pAewf */*ppAewf*/, const char */*pFilename*/)
+{
+ return NO_ERROR;
+}
+
+APIRET AewfClose (t_pAewf */*ppAewf*/)
+{
+ return NO_ERROR;
+}
+
+APIRET AewfReadNextChunk (t_pAewf /*pAewf*/, unsigned char */*pData*/, unsigned int */*pDataLen*/)
+{
+ return NO_ERROR;
+}
+
+// -----------------------
+// Module initialisation
+// -----------------------
+
+APIRET AewfInit (void)
+{
+ CHK (TOOL_ERROR_REGISTER_CODE (ERROR_AEWF_MEMALLOC_FAILED ))
+ CHK (TOOL_ERROR_REGISTER_CODE (ERROR_AEWF_CANNOT_WRITE_FILE ))
+
+ return NO_ERROR;
+}
+
+APIRET AewfDeInit (void)
+{
+ return NO_ERROR;
+}
diff --git a/aewf.h b/aewf.h
new file mode 100644
index 0000000..5aa6bec
--- /dev/null
+++ b/aewf.h
@@ -0,0 +1,74 @@
+// ****************************************************************************
+// Project: GUYMAGER
+// ****************************************************************************
+// Programmer: Guy Voncken
+// Police Grand-Ducale
+// Service de Police Judiciaire
+// Section Nouvelles Technologies
+// ****************************************************************************
+// Module: Multithreaded AEWF (AEWF = Avanced EWF)
+// ****************************************************************************
+
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef __AEWF_H__
+#define __AEWF_H__
+
+typedef struct _t_Aewf *t_pAewf;
+
+typedef struct
+{
+ bool Dummy;
+} t_AewfPreprocess, *t_pAewfPreprocess;
+
+// ------------------------------------
+// Functions
+// ------------------------------------
+
+// Write access functions
+APIRET AewfOpen (t_pAewf *ppAewf, const char *pFilename, unsigned long long DeviceSize, unsigned int SectorSize, unsigned int ChunkSize);
+APIRET AewfPreprocess (t_pAewfPreprocess *ppPreprocess, unsigned char *pDataIn, unsigned int DataLenIn, unsigned char *pDataOut, unsigned int DataLenOut);
+APIRET AewfWrite (t_pAewf pAewf, t_pAewfPreprocess pPreprocess, const unsigned char *pData, unsigned int DataLen);
+APIRET AewfClose (t_pAewf *ppAewf, unsigned long long BadSectors, const unsigned char *pMD5, const unsigned char *pSHA256, int Duration);
+
+// Read access functions
+APIRET AewfOpen (t_pAewf *ppAewf, const char *pFilename);
+APIRET AewfReadNextChunk (t_pAewf pAewf, unsigned char *pData, unsigned int *pDataLen);
+APIRET AewfClose (t_pAewf *ppAewf);
+
+
+APIRET AewfWriteSegmentStr (t_pAewf pAewf, const char *pName, unsigned int Argument, const char *pStr);
+
+APIRET AewfCopyBadSectorMarker (unsigned char *pBuffer, unsigned int Len);
+
+APIRET AewfInit (void);
+APIRET AewfDeInit (void);
+
+
+// ------------------------------------
+// Error codes
+// ------------------------------------
+
+enum
+{
+ ERROR_AEWF_MEMALLOC_FAILED = ERROR_BASE_AEWF + 1,
+ ERROR_AEWF_CANNOT_WRITE_FILE
+};
+
+#endif
+
diff --git a/common.h b/common.h
index 9163936..51300ea 100644
--- a/common.h
+++ b/common.h
@@ -9,6 +9,23 @@
// Module: Standard include file
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __COMMON_H__
#define __COMMON_H__
@@ -34,6 +51,8 @@
#include <stdio.h>
#endif
+#include <limits.h>
+
#include "toolglobalid.h"
#include "toolerror.h"
#include "toollog.h"
@@ -57,8 +76,16 @@ typedef t_Device *t_pDevice; // all the time, it is easiest to declare i
typedef t_Device const *t_pcDevice; // like that style too much, but we won't change C++ at this time).
#define EWF_MULTITHREADED_COMPRESSION_CHUNK_SIZE 32768
-#define EWF_MAX_SEGMENT_SIZE 2047 // in MiB
-#define EWF_MIN_SEGMENT_SIZE 20 // in MiB
+
+const unsigned long long BYTES_PER_MiB = 1ULL << 20;
+const unsigned long long BYTES_PER_GiB = 1ULL << 30;
+const unsigned long long BYTES_PER_TiB = 1ULL << 40;
+const unsigned long long BYTES_PER_PiB = 1ULL << 50;
+const unsigned long long BYTES_PER_EiB = 1ULL << 60;
+
+const unsigned long long EWF_MIN_SEGMENT_SIZE = 20 * BYTES_PER_MiB;
+const unsigned long long EWF_MAX_SEGMENT_SIZE = 2047 * BYTES_PER_MiB;
+const unsigned long long EWF_MAX_SEGMENT_SIZE_EXT = LONG_LONG_MAX - 10 * BYTES_PER_PiB; // Let's keep some distance from the absolute maximum - just for safety.
#define GETMAX(a,b) ((a)>(b)?(a):(b))
#define GETMIN(a,b) ((a)<(b)?(a):(b))
diff --git a/compileinfo.cpp b/compileinfo.cpp
new file mode 100644
index 0000000..d6678a4
--- /dev/null
+++ b/compileinfo.cpp
@@ -0,0 +1,3 @@
+// Automatically generated file. See project file and compileinfo.sh for further information.
+const char *pCompileInfoTimestamp = "2011-07-01-12.11.49";
+const char *pCompileInfoVersion = "0.5.8beta9-1";
diff --git a/compileinfo.h b/compileinfo.h
index 0fef085..7bc27b1 100644
--- a/compileinfo.h
+++ b/compileinfo.h
@@ -12,6 +12,23 @@
// See .pro file as well.
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
extern const char *pCompileInfoTimestamp;
extern const char *pCompileInfoVersion;
diff --git a/config.cpp b/config.cpp
index 1a3550a..8318d76 100644
--- a/config.cpp
+++ b/config.cpp
@@ -9,6 +9,23 @@
// Module: Application configuration data
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include "common.h"
#include <limits.h>
@@ -306,6 +323,9 @@ static t_ToolCfgParamDesc CfgParamDescArr[] =
{CFGASSIGN_BOTH_MULTIPLE, NULL , {"ScreenRefreshInterval" , CFGTYPE_INTEGER, ELT(ScreenRefreshInterval ), 0, 1, 8640000, NULL }, CFG_FILLUP_FORLINT},
{CFGASSIGN_BOTH_MULTIPLE, NULL , {"UseFileDialogFromQt" , CFGTYPE_SET , ELT(UseFileDialogFromQt) , 0, 0, 0, INIARR(SetArrBoolean) }, CFG_FILLUP_FORLINT},
+ {CFGASSIGN_BOTH_MULTIPLE, NULL , {"AutoExit" , CFGTYPE_SET , ELT(AutoExit) , 0, 0, 0, INIARR(SetArrBoolean) }, CFG_FILLUP_FORLINT},
+ {CFGASSIGN_BOTH_MULTIPLE, NULL , {"AutoExitCountdown" , CFGTYPE_INTEGER, ELT(AutoExitCountdown) , 0, 3, 864000, NULL }, CFG_FILLUP_FORLINT},
+
{CFGASSIGN_BOTH_MULTIPLE, NULL , {"DefaultFormat" , CFGTYPE_SET , ELT(DefaultFormat) , 0, 0, 0, INIARR(SetArrFormat) }, CFG_FILLUP_FORLINT},
{CFGASSIGN_BOTH_MULTIPLE, NULL , {"EwfFormat" , CFGTYPE_SET , ELT(EwfFormat ) , 0, 0, 0, INIARR(SetArrEwfFormat ) }, CFG_FILLUP_FORLINT},
{CFGASSIGN_BOTH_MULTIPLE, NULL , {"EwfCompression" , CFGTYPE_SET , ELT(EwfCompression) , 0, 0, 0, INIARR(SetArrEwfCompression) }, CFG_FILLUP_FORLINT},
@@ -928,6 +948,7 @@ static APIRET CfgInitializeDlgAcquireFieldNames (void)
{
CfgLocal.DlgAcquireFieldNames += CFG_DLGACQUIRE_SPLITFILESWITCH;
CfgLocal.DlgAcquireFieldNames += CFG_DLGACQUIRE_SPLITFILESIZE;
+ CfgLocal.DlgAcquireFieldNames += CFG_DLGACQUIRE_SPLITFILEUNIT;
CfgLocal.DlgAcquireFieldNames += CFG_DLGACQUIRE_EWF_CASENUMBER;
CfgLocal.DlgAcquireFieldNames += CFG_DLGACQUIRE_EWF_EVIDENCENUMBER;
CfgLocal.DlgAcquireFieldNames += CFG_DLGACQUIRE_EWF_EXAMINER;
@@ -996,6 +1017,7 @@ static APIRET CfgDlgAcquireFieldSaveAndNext (long *pBaseAddr, t_pcchar *ppErrorT
pField->DefaultValue = pBuff->DefaultValue;
pField->pLineEdit = NULL;
pField->pCheckBox = NULL;
+ pField->pComboBox = NULL;
}
else
{
diff --git a/config.h b/config.h
index cd05f72..de15270 100644
--- a/config.h
+++ b/config.h
@@ -7,6 +7,23 @@
// Section Nouvelles Technologies
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __CONFIG_H__
#define __CONFIG_H__
@@ -105,6 +122,9 @@ typedef struct
t_CfgNumberStyle NumberStyle;
int ScreenRefreshInterval;
int UseFileDialogFromQt;
+
+ int AutoExit;
+ int AutoExitCountdown;
t_CfgScanMethod DeviceScanMethod;
int ScanInterval;
@@ -179,6 +199,7 @@ typedef struct
#define CFG_DLGACQUIRE_SPLITFILESWITCH QT_TRANSLATE_NOOP("t_DlgAcquire", "SplitFileSwitch" )
#define CFG_DLGACQUIRE_SPLITFILESIZE QT_TRANSLATE_NOOP("t_DlgAcquire", "SplitFileSize" )
+#define CFG_DLGACQUIRE_SPLITFILEUNIT QT_TRANSLATE_NOOP("t_DlgAcquire", "SplitFileUnit" )
#define CFG_DLGACQUIRE_EWF_CASENUMBER QT_TRANSLATE_NOOP("t_DlgAcquire", "EwfCaseNumber" )
#define CFG_DLGACQUIRE_EWF_EVIDENCENUMBER QT_TRANSLATE_NOOP("t_DlgAcquire", "EwfEvidenceNumber" )
#define CFG_DLGACQUIRE_EWF_EXAMINER QT_TRANSLATE_NOOP("t_DlgAcquire", "EwfExaminer" )
@@ -209,6 +230,7 @@ typedef struct
} t_CfgBuffDlgAcquireRule, *t_pCfgBuffDlgAcquireRule;
class QCheckBox;
+class QComboBox;
class QLabel;
class t_DlgAcquireLineEdit;
class t_CfgDlgAcquireField
@@ -225,6 +247,7 @@ class t_CfgDlgAcquireField
bool DirField; // This is a directory field with a browse button
t_DlgAcquireLineEdit *pLineEdit;
QCheckBox *pCheckBox;
+ QComboBox *pComboBox;
QLabel *pLabel;
};
typedef t_CfgDlgAcquireField *t_pCfgDlgAcquireField;
diff --git a/device.cpp b/device.cpp
index 7094b23..8d4a3fb 100644
--- a/device.cpp
+++ b/device.cpp
@@ -11,6 +11,23 @@
// window.
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <float.h>
#include <QString>
@@ -128,8 +145,14 @@ void t_Device::InitialiseDeviceSpecific (const QString &SerialNumber, const QStr
this->SectorSize = SectorSize;
this->SectorSizePhys = SectorSizePhys;
this->Size = Size;
-// this->Size = GETMIN (10737418240ULL, Size; // For faster testing (we make guymager believe that the device is smaller)
-// this->Size = GETMIN (1073741824ULL, Size); // For faster testing (we make guymager believe that the device is smaller)
+
+ #ifdef FAKE_DEVICE_SIZE
+ // this->Size = GETMIN (10737418240ULL, Size); // 10 GiB For faster testing (we make guymager believe that the device is smaller)
+ // this->Size = GETMIN ( 20485760ULL, Size); // 20 MiB
+ // this->Size = GETMIN ( 1000000000ULL, Size); // 1 GB
+ // this->Size = 3ULL*1024ULL*1024ULL*1024ULL*1024ULL; // 3 TB
+ printf ("\nSize of all devices faked to %llu bytes", this->Size);
+ #endif
}
t_Device::t_Device (const QString &SerialNumber, const QString &LinuxDevice, const QString &Model,
@@ -510,25 +533,30 @@ QVariant t_Device::GetFifoStatus (t_pDevice pDevice)
if ((pDevice->State == Acquire) || // Don't display anything if no acquisition is running
(pDevice->State == Verify ))
{
+ int FifoUsageWrite = 0; // The write thread gets a lot of dummy blocks into its Fifo (from SlotThreadCompressFinished), but
+ // only 1 of them is taken out (then, the write already exits its loop). If image verification is on
+ if (pDevice->State != Verify) // then these dummy blocks remain the in the write fifo, leading to an ugly fifo usage display on the
+ FifoUsageWrite = DeviceFifoUsage(pDevice->pFifoWrite); // GUI. As I do not like to add code for remove dummy blocks (and waiting until they all have been
+ // received etc.) I decided to zero them artificially here.
if (!pDevice->HasHashThread() && !pDevice->HasCompressionThreads())
{
- Result = QString ("r %1 w") .arg (DeviceFifoUsage(pDevice->pFifoRead));
+ Result = QString ("r %1 w") .arg (FifoUsageWrite);
}
else if (!pDevice->HasHashThread() && pDevice->HasCompressionThreads())
{
Result = QString ("r %1 c %2 w") .arg (DeviceFifoUsage(pDevice->pFifoRead ))
- .arg (DeviceFifoUsage(pDevice->pFifoCompressOut));
+ .arg (FifoUsageWrite);
}
else if (pDevice->HasHashThread() && !pDevice->HasCompressionThreads())
{
Result = QString ("r %1 m %2 w") .arg (DeviceFifoUsage(pDevice->pFifoRead ))
- .arg (DeviceFifoUsage(pDevice->pFifoHashOut));
+ .arg (FifoUsageWrite);
}
else if (pDevice->HasHashThread() && pDevice->HasCompressionThreads())
{
Result = QString ("r %1 h %2 c %3 w") .arg (DeviceFifoUsage(pDevice->pFifoRead ))
.arg (DeviceFifoUsage(pDevice->pFifoHashOut ))
- .arg (DeviceFifoUsage(pDevice->pFifoCompressOut));
+ .arg (FifoUsageWrite);
}
}
diff --git a/device.h b/device.h
index 1200289..523686a 100644
--- a/device.h
+++ b/device.h
@@ -7,12 +7,28 @@
// Section Nouvelles Technologies
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __DEVICE_H__
#define __DEVICE_H__
#include "hash.h"
-
#include <parted/parted.h>
#include <QMetaType>
#include <QReadWriteLock>
diff --git a/devicelistmodel.h b/devicelistmodel.h
index 280cbda..6ccf19c 100644
--- a/devicelistmodel.h
+++ b/devicelistmodel.h
@@ -10,7 +10,22 @@
// screen
// ****************************************************************************
-
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __DEVICELISTMODEL_H__
#define __DEVICELISTMODEL_H__
diff --git a/dlgabort.cpp b/dlgabort.cpp
index faeb067..9eccef7 100644
--- a/dlgabort.cpp
+++ b/dlgabort.cpp
@@ -9,9 +9,24 @@
// Module: Dialog that is opened when aborting an acquisition
// ****************************************************************************
-#include "dlgabort.h"
-
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+#include "dlgabort.h"
// -----------------------------
// Constants
diff --git a/dlgabort.h b/dlgabort.h
index 2cc6de9..a7eec57 100644
--- a/dlgabort.h
+++ b/dlgabort.h
@@ -9,6 +9,22 @@
// Module: Dialog that is opened when aborting an acquisition
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __DLGABORT_H__
#define __DLGABORT_H__
diff --git a/dlgacquire.cpp b/dlgacquire.cpp
index c735d67..5d8fef5 100644
--- a/dlgacquire.cpp
+++ b/dlgacquire.cpp
@@ -9,6 +9,23 @@
// Module: Acquisition dialog
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <QtGui>
#include <QDesktopWidget>
#include <QX11Info>
@@ -58,6 +75,34 @@ class t_DlgAcquireLocal
static t_File::Format DlgAcquireLastUsedFormat = t_File::NotSet; // For remembering the format that was used for the last acquisition
// -----------------------------
+// Unit conversion
+// -----------------------------
+
+const QStringList UnitStrings = QStringList() << "MiB" << "GiB" << "TiB" << "PiB" << "EiB";
+
+static int UnitStringToIndex (QString &Str)
+{
+ if (Str.contains ('M', Qt::CaseInsensitive)) return 0;
+ else if (Str.contains ('G', Qt::CaseInsensitive)) return 1;
+ else if (Str.contains ('T', Qt::CaseInsensitive)) return 2;
+ else if (Str.contains ('P', Qt::CaseInsensitive)) return 3;
+ else if (Str.contains ('E', Qt::CaseInsensitive)) return 4;
+ LOG_ERROR ("Unknown Unit %s", QSTR_TO_PSZ(Str))
+ return 0;
+}
+
+static unsigned long long UnitIndexToMultiplier (int Index)
+{
+ unsigned long long Mul = 1024*1024;
+
+ if ((Index < 0) || (Index > 4))
+ LOG_ERROR ("Unit index out of range: %d", Index)
+ else Mul <<= (Index*10);
+
+ return Mul;
+}
+
+// -----------------------------
// Field utility functions
// -----------------------------
@@ -208,11 +253,13 @@ APIRET t_DlgAcquire::AddField (t_pDevice pDevice, t_pCfgDlgAcquireField pField,
{
t_pDlgAcquireLineEdit pLineEdit = NULL;
QCheckBox *pCheckBox = NULL;
+ QComboBox *pComboBox = NULL;
QLabel *pLabel = NULL;
QWidget *pEntryWidget = NULL;
QPushButton *pButtonBrowse = NULL;
QString Set;
QSize MinButtonSize;
+ bool Ok;
// Create field
// ------------
@@ -220,6 +267,11 @@ APIRET t_DlgAcquire::AddField (t_pDevice pDevice, t_pCfgDlgAcquireField pField,
{
pEntryWidget = pCheckBox = new QCheckBox (tr(QSTR_TO_PSZ(pField->FieldName)), this);
}
+ else if (pField->FieldName == CFG_DLGACQUIRE_SPLITFILEUNIT)
+ {
+ pEntryWidget = pComboBox = new QComboBox (this);
+ pComboBox->addItems (UnitStrings);
+ }
else
{
pEntryWidget = pLineEdit = new t_DlgAcquireLineEdit (this, pField->FieldName);
@@ -233,6 +285,7 @@ APIRET t_DlgAcquire::AddField (t_pDevice pDevice, t_pCfgDlgAcquireField pField,
// --------------
pField->pLineEdit = pLineEdit;
pField->pCheckBox = pCheckBox;
+ pField->pComboBox = pComboBox;
pField->pLabel = pLabel;
if (EntryMode(pField) == CFG_ENTRYMODE_HIDE)
{
@@ -290,6 +343,10 @@ APIRET t_DlgAcquire::AddField (t_pDevice pDevice, t_pCfgDlgAcquireField pField,
(*pRow)++;
}
}
+ if (pComboBox)
+ {
+ pLayout->addWidget (pComboBox, *pRow, 3);
+ }
}
}
@@ -315,6 +372,12 @@ APIRET t_DlgAcquire::AddField (t_pDevice pDevice, t_pCfgDlgAcquireField pField,
if (pCheckBox)
pCheckBox->setChecked (DlgAcquireStrToBool(Set));
+ if (pComboBox)
+ {
+ pComboBox->setCurrentIndex(Set.toInt(&Ok));
+ if (!Ok)
+ LOG_ERROR ("Invalid set value for ComboBox: %s", QSTR_TO_PSZ(Set));
+ }
if (pButtonBrowse)
{
(void) pButtonBrowse->setProperty (DLGACQUIRE_PROPERTY_SENDER_LINEEDIT, qVariantFromValue ((void *)pLineEdit));
@@ -498,6 +561,9 @@ t_DlgAcquire::t_DlgAcquire (t_pDevice pDevice, bool Clone, t_pDeviceList pDevice
CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_DLGACQUIRE_INVALID_ENTRYMODE))
CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_DLGACQUIRE_INVALID_FORMAT))
CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_DLGACQUIRE_INVALID_SELECTION))
+
+ pDlgAcquireField = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILEUNIT); // This initialisation needs to be done only once, as the user writes text (MiB, GiB, ...)
+ pDlgAcquireField->DefaultValue = QString::number (UnitStringToIndex(pDlgAcquireField->DefaultValue)); // in the configuration file, but we internally work with the ComboBox index numbers
}
if (Clone)
@@ -569,17 +635,19 @@ t_DlgAcquire::t_DlgAcquire (t_pDevice pDevice, bool Clone, t_pDeviceList pDevice
// Split file controls
// -------------------
- t_pCfgDlgAcquireField pFieldSplitSwitch = DlgAcquireGetField ("SplitFileSwitch");
- t_pCfgDlgAcquireField pFieldSplitSize = DlgAcquireGetField ("SplitFileSize" );
-
- if ((EntryMode(pFieldSplitSwitch) == CFG_ENTRYMODE_HIDE) &&
- (EntryMode(pFieldSplitSize ) == CFG_ENTRYMODE_HIDE))
- pSeparator->hide();
-
+ t_pCfgDlgAcquireField pFieldSplitFileSwitch = DlgAcquireGetField ("SplitFileSwitch");
+ t_pCfgDlgAcquireField pFieldSplitFileSize = DlgAcquireGetField ("SplitFileSize" );
+ t_pCfgDlgAcquireField pFieldSplitFileUnit = DlgAcquireGetField ("SplitFileUnit" );
+
+ if ((EntryMode(pFieldSplitFileSwitch) == CFG_ENTRYMODE_HIDE) &&
+ (EntryMode(pFieldSplitFileSize ) == CFG_ENTRYMODE_HIDE) &&
+ (EntryMode(pFieldSplitFileUnit ) == CFG_ENTRYMODE_HIDE))
+ pSeparator->hide();
Row = 0;
Col = 1;
- CHK_EXIT (AddField (pDevice, pFieldSplitSwitch, pLayoutSplit, &Row, &Col))
- CHK_EXIT (AddField (pDevice, pFieldSplitSize , pLayoutSplit, &Row, &Col))
+ CHK_EXIT (AddField (pDevice, pFieldSplitFileSwitch, pLayoutSplit, &Row, &Col))
+ CHK_EXIT (AddField (pDevice, pFieldSplitFileSize , pLayoutSplit, &Row, &Col))
+ CHK_EXIT (AddField (pDevice, pFieldSplitFileUnit , pLayoutSplit, &Row, &Col))
Row = Col = 0;
for (i=0; i<pDlgAcquireFields->count(); i++)
@@ -812,42 +880,46 @@ void t_DlgAcquire::UpdateFieldState (void)
// Split file fields
// -----------------
- static bool OldSplitSwitch = false; // should be replaced
+ static bool OldSplitFileSwitch = false; // should be replaced
- t_pCfgDlgAcquireField pFieldSplitSwitch = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILESWITCH);
- t_pCfgDlgAcquireField pFieldSplitSize = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILESIZE );
+ t_pCfgDlgAcquireField pFieldSplitFileSwitch = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILESWITCH);
+ t_pCfgDlgAcquireField pFieldSplitFileSize = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILESIZE );
+ t_pCfgDlgAcquireField pFieldSplitFileUnit = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILEUNIT );
if (pOwn->pRadioButtonFormatDD->isChecked())
{
- pFieldSplitSwitch->pCheckBox->setChecked (OldSplitSwitch);
- pFieldSplitSwitch->pCheckBox->setEnabled (true);
+ pFieldSplitFileSwitch->pCheckBox->setChecked (OldSplitFileSwitch);
+ pFieldSplitFileSwitch->pCheckBox->setEnabled (true);
}
else if (pOwn->pRadioButtonFormatEWF->isChecked())
{
- if (pFieldSplitSwitch->pCheckBox->isEnabled())
- OldSplitSwitch = pFieldSplitSwitch->pCheckBox->isChecked();
- pFieldSplitSwitch->pCheckBox->setChecked (true);
- pFieldSplitSwitch->pCheckBox->setEnabled (false);
+ if (pFieldSplitFileSwitch->pCheckBox->isEnabled())
+ OldSplitFileSwitch = pFieldSplitFileSwitch->pCheckBox->isChecked();
+ pFieldSplitFileSwitch->pCheckBox->setChecked (true);
+ pFieldSplitFileSwitch->pCheckBox->setEnabled (false);
}
else if (pOwn->pRadioButtonFormatAFF->isChecked())
{
- if (pFieldSplitSwitch->pCheckBox->isEnabled())
- OldSplitSwitch = pFieldSplitSwitch->pCheckBox->isChecked();
- pFieldSplitSwitch->pCheckBox->setChecked (false);
- pFieldSplitSwitch->pCheckBox->setEnabled (false);
+ if (pFieldSplitFileSwitch->pCheckBox->isEnabled())
+ OldSplitFileSwitch = pFieldSplitFileSwitch->pCheckBox->isChecked();
+ pFieldSplitFileSwitch->pCheckBox->setChecked (false);
+ pFieldSplitFileSwitch->pCheckBox->setEnabled (false);
}
- Enabled = pFieldSplitSwitch->pCheckBox->isChecked();
- pFieldSplitSize->pLineEdit->setEnabled (Enabled);
- pFieldSplitSize->pLabel ->setEnabled (Enabled);
+ Enabled = pFieldSplitFileSwitch->pCheckBox->isChecked();
+ pFieldSplitFileSize->pLineEdit->setEnabled (Enabled);
+ pFieldSplitFileSize->pLabel ->setEnabled (Enabled);
+ pFieldSplitFileUnit->pComboBox->setEnabled (Enabled);
}
void t_DlgAcquire::UpdateFileSplitState (void)
{
- t_pCfgDlgAcquireField pFieldSplitSwitch = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILESWITCH);
- t_pCfgDlgAcquireField pFieldSplitSize = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILESIZE );
-
- bool Enabled = pFieldSplitSwitch->pCheckBox->isChecked();
- pFieldSplitSize->pLineEdit->setEnabled (Enabled);
- pFieldSplitSize->pLabel ->setEnabled (Enabled);
+ t_pCfgDlgAcquireField pFieldSplitFileSwitch = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILESWITCH);
+ t_pCfgDlgAcquireField pFieldSplitFileSize = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILESIZE );
+ t_pCfgDlgAcquireField pFieldSplitFileUnit = DlgAcquireGetField (CFG_DLGACQUIRE_SPLITFILEUNIT );
+
+ bool Enabled = pFieldSplitFileSwitch->pCheckBox->isChecked();
+ pFieldSplitFileSize->pLineEdit->setEnabled (Enabled);
+ pFieldSplitFileSize->pLabel ->setEnabled (Enabled);
+ pFieldSplitFileUnit->pComboBox->setEnabled (Enabled);
}
void t_DlgAcquire::SlotBrowse (void)
@@ -947,20 +1019,41 @@ APIRET t_DlgAcquire::CheckWriteAccess (const QString &Path, const QString &Filen
const int StrLen = strlen (pStr);
QString TestFileName = Path + Filename + ".test";
int wr;
+ bool DirOk;
+
+ // Create directory if it doesn't exist
+ // ------------------------------------
+ QDir Dir(Path);
- LOG_INFO ("Trying write access to test file %s.", QSTR_TO_PSZ(TestFileName))
+ if (Dir.exists())
+ {
+ LOG_INFO ("Directory %s exists", QSTR_TO_PSZ(Path))
+ }
+ else
+ {
+ LOG_INFO ("Directory %s doesn't exist, trying to create it", QSTR_TO_PSZ(Path))
+ DirOk = Dir.mkpath(Path);
+ if (DirOk)
+ DirOk = Dir.exists();
+
+ if (DirOk)
+ LOG_INFO ("Directory %s created successfully", QSTR_TO_PSZ(Path))
+ else LOG_INFO ("Error while creating directory %s", QSTR_TO_PSZ(Path))
+ }
+
+ LOG_INFO ("Trying write access to test file %s", QSTR_TO_PSZ(TestFileName))
pFile = fopen (QSTR_TO_PSZ(TestFileName), "w");
Ok = (pFile != NULL);
if (!Ok)
{
- LOG_INFO ("Opening test file %s failed.", QSTR_TO_PSZ(TestFileName))
+ LOG_INFO ("Opening test file %s failed", QSTR_TO_PSZ(TestFileName))
}
else
{
if ((wr = fprintf (pFile, "%s", pStr)) != StrLen)
{
Ok = false;
- LOG_INFO ("Writing to test file %s failed, %d of %d bytes written.", QSTR_TO_PSZ(TestFileName), wr, StrLen)
+ LOG_INFO ("Writing to test file %s failed, %d of %d bytes written", QSTR_TO_PSZ(TestFileName), wr, StrLen)
}
if (fclose (pFile) != 0)
@@ -980,7 +1073,7 @@ APIRET t_DlgAcquire::CheckWriteAccess (const QString &Path, const QString &Filen
if (!QFile::remove (TestFileName))
{
Ok = false;
- LOG_INFO ("Removing the test file %s failed.", QSTR_TO_PSZ(TestFileName))
+ LOG_INFO ("Removing the test file %s failed", QSTR_TO_PSZ(TestFileName))
}
}
@@ -1013,25 +1106,48 @@ void t_DlgAcquire::SlotAccept (void)
{
if (DlgAcquireGetField(CFG_DLGACQUIRE_SPLITFILESWITCH)->pCheckBox->isChecked())
{
- QString StrValue;
- quint64 NumValue;
- bool Ok;
+ QString StrValue;
+ double NumValue;
+ unsigned long long SplitSize;
+ bool Ok;
StrValue = DlgAcquireGetField(CFG_DLGACQUIRE_SPLITFILESIZE)->pLineEdit->text();
- NumValue = StrValue.toULongLong(&Ok);
+ NumValue = StrValue.toDouble(&Ok);
if (!Ok)
{
QMessageBox::information (this, tr ("Incorrect value", "Dialog title"),
tr ("The split file size \"%1\" is not valid. Only positive numbers can be entered.").arg(StrValue), QMessageBox::Ok);
return;
}
- if (pOwn->pRadioButtonFormatEWF->isChecked() && ((NumValue > EWF_MAX_SEGMENT_SIZE) ||
- (NumValue < EWF_MIN_SEGMENT_SIZE)))
+ SplitSize = NumValue * UnitIndexToMultiplier (DlgAcquireGetField(CFG_DLGACQUIRE_SPLITFILEUNIT)->pComboBox->currentIndex());
+ #if (LIBEWF_VERSION != 20100226)
+ #error "Please check EWF documentation for newer Encase formats and adjust following code"
+ #endif
+ if (pOwn->pRadioButtonFormatEWF->isChecked())
{
- QMessageBox::information (this, tr ("Incorrect value", "Dialog title"),
- tr ("The split size for EWF files must be in the range %1 - %2 MiB.")
- .arg(EWF_MIN_SEGMENT_SIZE) .arg(EWF_MAX_SEGMENT_SIZE), QMessageBox::Ok);
- return;
+ if (CONFIG(EwfFormat) == LIBEWF_FORMAT_ENCASE6)
+ {
+ if ((SplitSize > EWF_MAX_SEGMENT_SIZE_EXT) || (SplitSize < EWF_MIN_SEGMENT_SIZE))
+ {
+ QMessageBox::information (this, tr ("Incorrect value", "Dialog title"),
+ tr ("The split size for the selected image format must be in the range %1MiB - %2EiB.")
+ .arg(EWF_MIN_SEGMENT_SIZE / (1024*1024))
+ .arg(EWF_MAX_SEGMENT_SIZE_EXT/ (double)BYTES_PER_EiB, 0, 'f', 2), QMessageBox::Ok);
+ return;
+ }
+ }
+ else
+ {
+ if ((NumValue > EWF_MAX_SEGMENT_SIZE) || (NumValue < EWF_MIN_SEGMENT_SIZE))
+ {
+ QMessageBox::information (this, tr ("Incorrect value", "Dialog title"),
+ tr ("The split size for the configured EWF format must be in the range %1 - %2 MiB."
+ "For bigger files, switch to ""Encase6"" format or later (see Guymager configuration file, parameter EwfFormat).")
+ .arg(EWF_MIN_SEGMENT_SIZE/(1024*1024))
+ .arg(EWF_MAX_SEGMENT_SIZE/(1024*1024)), QMessageBox::Ok);
+ return;
+ }
+ }
}
}
}
@@ -1177,8 +1293,17 @@ APIRET t_DlgAcquire::GetParameters (t_Device::t_Acquisition &Acquisition, bool R
pDlgAcquireField->LastEnteredValue = Acq ? "1" : "0"; \
}
+ #define COPY_COMBOBOX(Acq, FieldName, Remember) \
+ { \
+ pDlgAcquireField = DlgAcquireGetField (FieldName); \
+ Acq = pDlgAcquireField->pComboBox->currentIndex(); \
+ if (Remember) \
+ pDlgAcquireField->LastEnteredValue = QString::number (Acq); \
+ }
+
if (!pOwn->Clone)
{
+ Acquisition.SplitFileSize = 0;
COPY_LINEENTRY (Acquisition.CaseNumber , CFG_DLGACQUIRE_EWF_CASENUMBER , RememberLastUsedValues)
COPY_LINEENTRY (Acquisition.EvidenceNumber, CFG_DLGACQUIRE_EWF_EVIDENCENUMBER , RememberLastUsedValues)
COPY_LINEENTRY (Acquisition.Examiner , CFG_DLGACQUIRE_EWF_EXAMINER , RememberLastUsedValues)
@@ -1186,8 +1311,12 @@ APIRET t_DlgAcquire::GetParameters (t_Device::t_Acquisition &Acquisition, bool R
COPY_LINEENTRY (Acquisition.Notes , CFG_DLGACQUIRE_EWF_NOTES , RememberLastUsedValues)
COPY_CHECKBOX (SplitFileSwitch, CFG_DLGACQUIRE_SPLITFILESWITCH )
if (SplitFileSwitch)
+ {
+ int UnitIndex;
COPY_LINEENTRY (SplitFileSize, CFG_DLGACQUIRE_SPLITFILESIZE, RememberLastUsedValues)
- Acquisition.SplitFileSize = SplitFileSize.toULongLong() * BYTES_PER_MEGABYTE;
+ COPY_COMBOBOX (UnitIndex , CFG_DLGACQUIRE_SPLITFILEUNIT, RememberLastUsedValues)
+ Acquisition.SplitFileSize = SplitFileSize.toULongLong() * UnitIndexToMultiplier(UnitIndex);
+ }
}
COPY_LINEENTRY (Acquisition.ImagePath , CFG_DLGACQUIRE_DEST_IMAGEDIRECTORY, pOwn->Clone ? false : RememberLastUsedValues)
COPY_LINEENTRY (Acquisition.ImageFilename , CFG_DLGACQUIRE_DEST_IMAGEFILENAME , pOwn->Clone ? false : RememberLastUsedValues)
diff --git a/dlgacquire.h b/dlgacquire.h
index cb4381d..9cf334b 100644
--- a/dlgacquire.h
+++ b/dlgacquire.h
@@ -9,6 +9,22 @@
// Module: Acquisition dialog
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __DLGACQUIRE_H__
#define __DLGACQUIRE_H__
diff --git a/dlgacquire_private.h b/dlgacquire_private.h
index c28ab22..5d92b3c 100755
--- a/dlgacquire_private.h
+++ b/dlgacquire_private.h
@@ -9,6 +9,22 @@
// Module: Private definitions of acquisition dialog
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __DLGACQUIRE_PRIVATE_H__
#define __DLGACQUIRE_PRIVATE_H__
diff --git a/dlgautoexit.cpp b/dlgautoexit.cpp
new file mode 100644
index 0000000..4dc97ad
--- /dev/null
+++ b/dlgautoexit.cpp
@@ -0,0 +1,130 @@
+// ****************************************************************************
+// Project: GUYMAGER
+// ****************************************************************************
+// Programmer: Guy Voncken
+// Police Grand-Ducale
+// Service de Police Judiciaire
+// Section Nouvelles Technologies
+// ****************************************************************************
+// Module: Auto exit dialog
+// ****************************************************************************
+
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
+#include <QtGui>
+
+#include "common.h"
+#include "config.h"
+#include "dlgautoexit.h"
+
+// -----------------------------
+// Constants
+// -----------------------------
+
+
+// -----------------------------
+// Classes
+// -----------------------------
+
+class t_DlgAutoExitLocal
+{
+ public:
+ QLabel *pLabel;
+ int Seconds;
+};
+
+t_DlgAutoExit::t_DlgAutoExit ()
+{
+ CHK_EXIT (ERROR_DLGAUTOEXIT_CONSTRUCTOR_NOT_SUPPORTED)
+} //lint !e1401 pOwn not initialised
+
+t_DlgAutoExit::t_DlgAutoExit (QWidget *pParent, Qt::WFlags Flags)
+ :QDialog (pParent, Flags)
+{
+ static bool Initialised = false;
+ QSize MaxSize;
+ QVBoxLayout *pMainLayout;
+ QDialogButtonBox *pButtonBox;
+ QPushButton *pButtonAbort;
+ QPushButton *pButtonExit;
+
+ if (!Initialised)
+ {
+ Initialised = true;
+ CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_DLGAUTOEXIT_CONSTRUCTOR_NOT_SUPPORTED))
+ }
+
+ pOwn = new t_DlgAutoExitLocal;
+ pOwn->Seconds = CONFIG (AutoExitCountdown);
+
+ pMainLayout = new QVBoxLayout ();
+ pOwn->pLabel = new QLabel (this);
+ pMainLayout->addWidget (pOwn->pLabel);
+
+ pButtonAbort = new QPushButton (tr("Abort"), this);
+ pButtonExit = new QPushButton (tr("Exit now"), this);
+ pButtonAbort->setDefault (true);
+
+ pButtonBox = new QDialogButtonBox (this);
+ pButtonBox->addButton(pButtonAbort, QDialogButtonBox::RejectRole);
+ pButtonBox->addButton(pButtonExit , QDialogButtonBox::AcceptRole);
+ pMainLayout->addWidget (pButtonBox);
+
+ connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ SlotCountdown();
+
+ setLayout (pMainLayout);
+ setWindowTitle ("test");
+
+ QTimer *pTimer = new QTimer(this);
+ connect(pTimer, SIGNAL(timeout()), this, SLOT(SlotCountdown()));
+ pTimer->start(1000);
+
+// CHK_QT_EXIT (connect (pOwn->pButtonClose, SIGNAL (released()), this, SLOT(accept())))
+}
+
+t_DlgAutoExit::~t_DlgAutoExit ()
+{
+ delete pOwn;
+}
+
+void t_DlgAutoExit::SlotCountdown (void)
+{
+ pOwn->pLabel->setText (tr("All acquisitions have ended.\nGuymager will exit automatically in %1 seconds.") .arg (pOwn->Seconds));
+ if (pOwn->Seconds == 0)
+ accept();
+ pOwn->Seconds--;
+}
+
+APIRET t_DlgAutoExit::Show (bool *pAutoExit)
+{
+ t_DlgAutoExit *pDlg;
+ int Result;
+
+ pDlg = new t_DlgAutoExit (NULL);
+ pDlg->setModal (true);
+ pDlg->show ();
+ Result = pDlg->exec ();
+ delete pDlg;
+ *pAutoExit = (Result == QDialog::Accepted);
+
+ return NO_ERROR;
+}
+
diff --git a/dlgautoexit.h b/dlgautoexit.h
new file mode 100644
index 0000000..0d12c32
--- /dev/null
+++ b/dlgautoexit.h
@@ -0,0 +1,64 @@
+// ****************************************************************************
+// Project: GUYMAGER
+// ****************************************************************************
+// Programmer: Guy Voncken
+// Police Grand-Ducale
+// Service de Police Judiciaire
+// Section Nouvelles Technologies
+// ****************************************************************************
+// Module: Auto exit dialog
+// ****************************************************************************
+
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef __DLGAUTOEXIT_H__
+#define __DLGAUTOEXIT_H__
+
+#include <QtGui> //lint !e537 Repeated include
+
+#ifndef __COMMON_H__
+ #include "common.h"
+#endif
+
+class t_DlgAutoExitLocal;
+
+class t_DlgAutoExit: public QDialog
+{
+ Q_OBJECT
+
+ public:
+ t_DlgAutoExit ();
+ t_DlgAutoExit (QWidget *pParent=NULL, Qt::WFlags Flags=0);
+ ~t_DlgAutoExit ();
+
+ static APIRET Show (bool *pAutoExit);
+
+ private slots:
+ void SlotCountdown (void);
+
+ private:
+ t_DlgAutoExitLocal *pOwn;
+};
+
+enum
+{
+ ERROR_DLGAUTOEXIT_CONSTRUCTOR_NOT_SUPPORTED = ERROR_BASE_DLGAUTOEXIT + 1,
+};
+
+#endif
+
diff --git a/dlgdirsel.cpp b/dlgdirsel.cpp
index 7c60a45..35b5d2a 100644
--- a/dlgdirsel.cpp
+++ b/dlgdirsel.cpp
@@ -9,6 +9,23 @@
// Module: Directory selection dialog
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <QtGui>
#include "common.h"
diff --git a/dlgdirsel.h b/dlgdirsel.h
index a2c4715..3cb7246 100644
--- a/dlgdirsel.h
+++ b/dlgdirsel.h
@@ -9,6 +9,22 @@
// Module: Directory selection dialog
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __DLGDIRSEL_H__
#define __DLGDIRSEL_H__
diff --git a/dlgdirsel_private.h b/dlgdirsel_private.h
index 81fabe1..2a38900 100644
--- a/dlgdirsel_private.h
+++ b/dlgdirsel_private.h
@@ -9,6 +9,22 @@
// Module: Private definitions of directory selection dialog
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __DLGDIRSEL_PRIVATE_H__
#define __DLGDIRSEL_PRIVATE_H__
diff --git a/dlgmessage.cpp b/dlgmessage.cpp
index 6a50b19..4962c3c 100644
--- a/dlgmessage.cpp
+++ b/dlgmessage.cpp
@@ -9,6 +9,23 @@
// Module: Different message boxes we need all the time
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include "dlgmessage.h"
// -----------------------------
diff --git a/dlgmessage.h b/dlgmessage.h
index c14d28f..d5797d1 100644
--- a/dlgmessage.h
+++ b/dlgmessage.h
@@ -9,6 +9,22 @@
// Module: Different message boxes we need all the time
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __DLGMESSAGE_H__
#define __DLGMESSAGE_H__
diff --git a/dlgwait.cpp b/dlgwait.cpp
index 818a5a7..599bb0e 100644
--- a/dlgwait.cpp
+++ b/dlgwait.cpp
@@ -9,6 +9,23 @@
// Module: Wait dialog
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include "dlgwait.h"
// -----------------------------
diff --git a/dlgwait.h b/dlgwait.h
index 21ab2d8..c0b375d 100644
--- a/dlgwait.h
+++ b/dlgwait.h
@@ -9,6 +9,22 @@
// Module: Wait dialog
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __DLGWAIT_H__
#define __DLGWAIT_H__
diff --git a/error.cpp b/error.cpp
index 74ab7e3..420e6e8 100644
--- a/error.cpp
+++ b/error.cpp
@@ -9,6 +9,22 @@
// Module: Error handling utilities
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#include <stdarg.h>
#include <stdlib.h>
@@ -18,7 +34,6 @@
#include "common.h"
#include "qtutil.h"
-
// -----------------------
// Constants
// -----------------------
diff --git a/error.h b/error.h
index 9a95904..805320d 100644
--- a/error.h
+++ b/error.h
@@ -9,6 +9,23 @@
// Module: Error handling utilities
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __ERROR_H__
#define __ERROR_H__
@@ -17,9 +34,10 @@
// -----------------------
static const int EXIT_NO_ERROR = 0;
-static const int EXIT_INTERNAL_ERROR = 1;
-static const int EXIT_QT_FATAL = 2;
-static const int EXIT_SIGNAL_RECEIVED = 3;
+static const int EXIT_AUTOEXIT = 1;
+static const int EXIT_INTERNAL_ERROR = 10;
+static const int EXIT_QT_FATAL = 11;
+static const int EXIT_SIGNAL_RECEIVED = 12;
// -----------------------
// Prototypes
diff --git a/fifo.cpp b/fifo.cpp
index 5af266f..1203f64 100644
--- a/fifo.cpp
+++ b/fifo.cpp
@@ -9,6 +9,23 @@
// Module: The central queues for pipelined data processing
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include "common.h"
#include "unistd.h"
@@ -151,11 +168,22 @@ void t_FifoMemory::LogBlock (char *pBlock, char Marker) // For debugging purpose
APIRET FifoMemoryAlloc (t_pFifoMemory *ppFifoMemory, unsigned int TotalBlocks, unsigned int AllocBlockSize)
{
+ if (*ppFifoMemory)
+ CHK_EXIT (ERROR_FIFO_MEMORY_ALREADY_ALLOCATED)
*ppFifoMemory = new t_FifoMemory (TotalBlocks, AllocBlockSize);
return NO_ERROR;
}
+APIRET FifoMemoryFree (t_pFifoMemory *ppFifoMemory)
+{
+ if (*ppFifoMemory == NULL)
+ CHK_EXIT (ERROR_FIFO_MEMORY_NOT_ALLOCATED)
+ delete *ppFifoMemory;
+ *ppFifoMemory = NULL;
+
+ return NO_ERROR;
+}
// ----------------------------
// FIFO
@@ -184,6 +212,7 @@ APIRET t_Fifo::Create (t_pFifoMemory pFifoMemory, t_pFifoBlock &pBlock, unsigned
pBlock->EwfWriteCRC = 0;
pBlock->pAaffPreprocess = NULL;
+ pBlock->pAewfPreprocess = NULL;
pBlock->Nr = FIFO_NR_NOTSET;
@@ -262,6 +291,8 @@ t_FifoStd::t_FifoStd (t_pFifoMemory pFifoMemory, int MaxBlocks)
CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_FIFO_MEMORY_UNDERUN ))
CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_FIFO_MEMORY_ALLOC_FAILED ))
CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_FIFO_MEMORY_INVALID_BLOCKSIZE))
+ CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_FIFO_MEMORY_ALREADY_ALLOCATED))
+ CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_FIFO_MEMORY_NOT_ALLOCATED ))
CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_FIFO_POINTER_TOO_LOW ))
CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_FIFO_POINTER_NOT_ON_BOUNDARY ))
CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_FIFO_POINTER_TOO_HIGH ))
diff --git a/fifo.h b/fifo.h
index e3450cc..ec14ab1 100644
--- a/fifo.h
+++ b/fifo.h
@@ -6,7 +6,25 @@
// Service de Police Judiciaire
// Section Nouvelles Technologies
// ****************************************************************************
+// Module: The central queues for pipelined data processing
+// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __FIFO_H__
#define __FIFO_H__
@@ -22,6 +40,7 @@
#endif
#include "aaff.h"
+#include "aewf.h"
@@ -29,6 +48,7 @@ class t_FifoMemory;
typedef t_FifoMemory *t_pFifoMemory;
APIRET FifoMemoryAlloc (t_pFifoMemory *ppFifoMemory, unsigned int TotalBlocks, unsigned int BlockSize);
+APIRET FifoMemoryFree (t_pFifoMemory *ppFifoMemory);
APIRET FifoGetStatistics (quint64 &AllocCalls, quint64 &FreeCalls, qint64 &AllocatedMemory);
@@ -53,6 +73,7 @@ typedef struct
int8_t EwfWriteCRC; // For libewf
t_pAaffPreprocess pAaffPreprocess;
+ t_pAewfPreprocess pAewfPreprocess;
qulonglong Nr; // Set to FIFO_NR_NOTSET if nr is not known yet
unsigned char Buffer[]; //lint !e1501 Has zero size
@@ -166,6 +187,8 @@ typedef t_FifoCompressOut *t_pFifoCompressOut;
ERROR_FIFO_CONSTRUCTOR_NOT_SUPPORTED,
ERROR_FIFO_MEMORY_ALLOC_FAILED,
ERROR_FIFO_MEMORY_INVALID_BLOCKSIZE,
+ ERROR_FIFO_MEMORY_ALREADY_ALLOCATED,
+ ERROR_FIFO_MEMORY_NOT_ALLOCATED,
ERROR_FIFO_POINTER_TOO_LOW,
ERROR_FIFO_POINTER_NOT_ON_BOUNDARY,
ERROR_FIFO_POINTER_TOO_HIGH
diff --git a/file.cpp b/file.cpp
index 91243b3..f333b4b 100644
--- a/file.cpp
+++ b/file.cpp
@@ -1,4 +1,3 @@
-
// ****************************************************************************
// Project: GUYMAGER
// ****************************************************************************
@@ -10,6 +9,22 @@
// Module: Everything related to file names, extension names, paths...
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#include "common.h"
diff --git a/file.h b/file.h
index 74fb304..351f373 100644
--- a/file.h
+++ b/file.h
@@ -10,6 +10,22 @@
// etc
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __FILE_H__
#define __FILE_H__
diff --git a/guymager.cfg b/guymager.cfg
index d25a426..0487f20 100644
--- a/guymager.cfg
+++ b/guymager.cfg
@@ -64,6 +64,14 @@ REM the alternative programmed by the author of guymager
REM Adjusting the dialog size (see configuration parameters FileDialogSize,
REM FileDialogSizeManualDx and FileDialogSizeManualDy) only works with the
REM alternative dialog.
+REM
+REM AutoExit This parameter controls the default setting of the menu point "Misc/Exit after
+REM all acquisitions have completed".
+REM
+REM AutoExitCountdown = 60 If the autoexit eaturebecomes active (i.e. the menu flag is set and the acquisition
+REM ends), a popup appears with a countdown. AutoExitCountdown allows to set start value
+REM of the countdown (in seconds).
+
Language='auto'
@@ -83,6 +91,8 @@ ScreenRefreshInterval = 1500
UseFileDialogFromQt = Yes
+AutoExit = Off
+AutoExitCountdown = 60
REM Table Fonts
REM Not in use yet. Will be used later on for adjusting the fonts used by guymager.
@@ -138,6 +148,7 @@ REM EwfFormat The EWF format (alias E01 format) differs depending on
REM it. With this parameter, you can control which style guymager should follow.
REM Possible values are: Encase1, Encase2, Encase3, Encase4, Encase5, Encase6, Smart,
REM FTK, Linen5, Linen6 and LVF. See libewf for more information.
+REM Select Encase6 in order to be able to produce segment files bigger than 2GiB.
REM
REM EwfCompression The compression level for EWF images. Possible values are: None, Fast, Best.
REM See ewflib for more information.
@@ -158,7 +169,7 @@ REM that your destination file system can handle them, you
REM the parameter SpecialFilenameChars. Example: SpecialFilenameChars = '.- '
REM would allow you to use the characters . and - as well as spaces.
-EwfFormat = Encase5
+EwfFormat = Encase6
EwfCompression = FAST
AffCompression = 1
AffMarkBadSectors = TRUE
@@ -292,6 +303,7 @@ TABLE DlgAcquireField NoName
REM ------------------------------------------------------------------------------------
'SplitFileSwitch' ShowLast Hide '1'
'SplitFileSize' ShowLast Hide '2047'
+ 'SplitFileUnit' ShowLast Hide 'MiB'
'EwfCaseNumber' ShowLast Hide ''
'EwfEvidenceNumber' ShowDefault Hide ''
'EwfExaminer' ShowLast Hide ''
@@ -383,11 +395,12 @@ REM DeviceScanMethod Guymager knows 3 methods for getting the list of the
REM that uses libparted, the new one that uses DBUS/HAL and the even newer one that uses
REM DeviceKit-Disks. Select your method by setting this parameter to:
REM
-REM DBusDevKit or UDisks Use the newest method. You need a Linux supporting UDisks for
-REM this setting (for example Ubuntu 10.04). In older versions, UDisks
-REM was named DeviceKit (in Ubuntu 9.10 for instance). Both are the same.
+REM DBusDevKit or UDisks Use the newest method (recommended for Ubuntu >= 9.04). You need a Linux
+REM supporting UDisks for this setting. In older versions, UDisks was named
+REM DeviceKit (in Ubuntu 9.04 and 9.10 for instance). From guymager's point
+REM view, UDisks and DeviceKit are both the same.
REM
-REM DBusHAL Use the new method (recommended).
+REM DBusHAL Use the new method (recommended for systems like Ubuntu 8.10).
REM
REM libparted Use the old method. It was observed that the internal scan function hung
REM while an acquisition was running. This leads to the problem that the devices
@@ -398,7 +411,7 @@ REM each device (not really el
REM When chossing an unsupported scan method, Guymager shows the user a dialog asking to fall back
REM to a supported one.
REM
-REM CommandGetSerialNumber is used to extract the serial number from a device when setting ScanUsingDbusHal to 0 (not
+REM CommandGetSerialNumber is used to extract the serial number from a device when setting DeviceScanMethod to libparted (not
REM recommended). The placeholder %dev in the command string will be replaced by the device
REM (/dev/hda or /dev/sdc for instance). Examples:
REM CommandGetSerialNumber = 'bash -c "smartctl -i %dev | grep -i serial | awk ''{print $3 $4 $5 $6 $7 $8 $9}'' "'
@@ -425,9 +438,9 @@ REM with a block size of 10 kilobyte, specify 10240 (instead of 10000).
REM
REM FifoBlockSizeDD The block size for dd images (in bytes). Recommended value: 262144 (256K).
REM
-REM FifoBlockSizeEWF The block size for dd images (in bytes). Recommended value: 32768 (32K).
+REM FifoBlockSizeEWF The block size for EWF images (in bytes). Recommended value: 32768 (32K).
REM
-REM FifoBlockSizeAFF The block size for dd images (in bytes). Recommended value: 10485760 (10MB).
+REM FifoBlockSizeAFF The block size for AFF images (in bytes). Recommended value: 65536 (64K).
REM
REM FifoMaxMem The amount of memory used for the internal FIFO queues of an acquisition. The value is indicated in
REM Megabytes. If you set it to 0, Guymager uses 1/8 of the available RAM, maximally 64MB per acquisition.
@@ -452,7 +465,7 @@ REM
FifoBlockSizeDD = 262144
FifoBlockSizeEWF = 32768
-FifoBlockSizeAFF = 10485760
+FifoBlockSizeAFF = 65536
FifoMaxMem = 0
FifoMemoryManager = On
diff --git a/guymager.desktop b/guymager.desktop
new file mode 100644
index 0000000..d7b6e8e
--- /dev/null
+++ b/guymager.desktop
@@ -0,0 +1,18 @@
+[Desktop Entry]
+# Guymager
+# The format of this file is specified at
+# http://freedesktop.org/Standards/desktop-entry-spec
+# The entries are in the order they are listed in version 1.0
+Type=Application
+Version=1.0
+Name=Guymager
+Name[vi]=Wireshark
+GenericName=Imager
+Comment=Fast forensic imager
+Icon=guymager_128.png
+TryExec=guymager
+Exec=gksudo guymager
+Terminal=false
+# Categorie entry according to version 1.0 of
+# http://www.freedesktop.org/wiki/Specifications/menu-spec
+Categories=Qt;System
diff --git a/guymager.pro b/guymager.pro
index 8e26e50..569b512 100644
--- a/guymager.pro
+++ b/guymager.pro
@@ -12,8 +12,8 @@
# Command line configuration options
# ----------------------------------
# These options are thought to behave like the classical ./configure options, i.e. they
-# allow for using different paths and such things. Currently, there's only one pre-compiler
-# definition:
+# allow for using different paths and such things. Currently, there are the following
+# pre-compiler definitions:
# SPLASH_DIR Defines where to look for the splash image (splash.png)
# Example:
# qmake DEFINES+="SPLASH_DIR=\'\\\"/usr/share/guymager\\\"\'"
@@ -60,11 +60,13 @@ OBJECTS += compileinfo.o
SOURCES += aaff.cpp
+SOURCES += aewf.cpp
SOURCES += config.cpp
SOURCES += device.cpp
SOURCES += dlgabort.cpp
SOURCES += dlgacquire.cpp
SOURCES += dlgdirsel.cpp
+SOURCES += dlgautoexit.cpp
SOURCES += dlgmessage.cpp
SOURCES += dlgwait.cpp
SOURCES += error.cpp
@@ -78,7 +80,6 @@ SOURCES += main.cpp
SOURCES += mainwindow.cpp
SOURCES += md5.c
SOURCES += media.cpp
-SOURCES += memwatch.c
SOURCES += qtutil.cpp
#SOURCES += sha256.cpp
SOURCES += table.cpp
@@ -93,6 +94,7 @@ HEADERS += config.h
HEADERS += devicelistmodel.h
HEADERS += dlgabort.h
HEADERS += dlgacquire.h
+HEADERS += dlgautoexit.h
HEADERS += dlgacquire_private.h
HEADERS += dlgdirsel.h
HEADERS += dlgdirsel_private.h
@@ -102,7 +104,6 @@ HEADERS += infofield.h
HEADERS += itemdelegate.h
HEADERS += mainwindow.h
HEADERS += media.h
-HEADERS += memwatch.h
HEADERS += table.h
HEADERS += threadcompress.h
HEADERS += threadhash.h
diff --git a/guymager_128.png b/guymager_128.png
new file mode 100644
index 0000000..0585fae
Binary files /dev/null and b/guymager_128.png differ
diff --git a/guymager_de.ts b/guymager_de.ts
index ed95b7f..6a0912d 100644
--- a/guymager_de.ts
+++ b/guymager_de.ts
@@ -325,7 +325,7 @@ Sind Sie mit diesen Änderungen einverstanden?</translation>
</message>
<message>
<source>SplitFileSize</source>
- <translation>Splitgröße (MiB)</translation>
+ <translation>Splitgröße</translation>
</message>
<message>
<source>SplitFileSwitch</source>
@@ -350,7 +350,36 @@ Sind Sie mit diesen Änderungen einverstanden?</translation>
</message>
<message>
<source>The split size for EWF files must be in the range %1 - %2 MiB.</source>
- <translation>Die Split-Grösse von EWF-Dateien muss im Bereich %1 - %2 MiB liegen.</translation>
+ <translation type="obsolete">Die Split-Grösse von EWF-Dateien muss im Bereich %1 - %2 MiB liegen.</translation>
+ </message>
+ <message>
+ <source>SplitFileUnit</source>
+ <translation> </translation>
+ </message>
+ <message>
+ <source>The split size for the selected image format must be in the range %1MiB - %2EiB.</source>
+ <translation>Die Split-Grösse für das gewählte Datei-Format muss im Bereich %1 MiB - %2 EiB liegen.</translation>
+ </message>
+ <message>
+ <source>The split size for the configured EWF format must be in the range %1 - %2 MiB.For bigger files, switch to Encase6 format or later (see Guymager configuration file, parameter EwfFormat).</source>
+ <translation>Die Split-Grösse für das konfigurierte EWF-Format muss im Bereich %1 MiB - %2 MiB liegen. Grössere Dateien sind ab dem Format Encase6 möglich (siehe Guymager Konfigurationsdatei, Parameter EwfFormat).</translation>
+ </message>
+</context>
+<context>
+ <name>t_DlgAutoExit</name>
+ <message>
+ <source>Abort</source>
+ <translation>Abbruch</translation>
+ </message>
+ <message>
+ <source>Exit now</source>
+ <translation>Jetzt beenden</translation>
+ </message>
+ <message>
+ <source>All acquisitions have ended.
+Guymager will exit automatically in %1 seconds.</source>
+ <translation>Alle Akquisitionen wurden abgeschlossen.
+Guymager beendet sich automatisch in %1 Sekunden.</translation>
</message>
</context>
<context>
@@ -678,6 +707,10 @@ Benutzt libguytools %5</translation>
<comment>column hidden areas</comment>
<translation>nicht feststellbar</translation>
</message>
+ <message>
+ <source>Exit after acquisitions completed</source>
+ <translation>Guymager nach Abschluss aller Akquisitionen beenden</translation>
+ </message>
</context>
<context>
<name>t_Table</name>
diff --git a/guymager_en.ts b/guymager_en.ts
index 69cfafe..979bf37 100644
--- a/guymager_en.ts
+++ b/guymager_en.ts
@@ -312,7 +312,7 @@ Do you accept these changes?</source>
</message>
<message>
<source>SplitFileSize</source>
- <translation>Split size (MiB)</translation>
+ <translation>Split size</translation>
</message>
<message>
<source>SplitFileSwitch</source>
@@ -336,7 +336,31 @@ Do you accept these changes?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The split size for EWF files must be in the range %1 - %2 MiB.</source>
+ <source>SplitFileUnit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The split size for the selected image format must be in the range %1MiB - %2EiB.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The split size for the configured EWF format must be in the range %1 - %2 MiB.For bigger files, switch to Encase6 format or later (see Guymager configuration file, parameter EwfFormat).</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>t_DlgAutoExit</name>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Exit now</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All acquisitions have ended.
+Guymager will exit automatically in %1 seconds.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -659,6 +683,10 @@ Using libguytools %5</source>
<comment>column hidden areas</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Exit after acquisitions completed</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>t_Table</name>
@@ -924,7 +952,7 @@ Using libguytools %5</source>
</message>
<message>
<source>Image verification OK. The image contains exactely the data that was written.</source>
- <translation type="unfinished"></translation>
+ <translation>Image verification OK. The image contains exactly the data that was written.</translation>
</message>
<message>
<source>Image verification FAILED. The data in the image is different from what was written.</source>
diff --git a/guymager_fr.ts b/guymager_fr.ts
index 2401fb8..9bea00f 100644
--- a/guymager_fr.ts
+++ b/guymager_fr.ts
@@ -329,7 +329,7 @@ Acceptez-vous ces changement?</translation>
</message>
<message>
<source>SplitFileSize</source>
- <translation>Taille des fragments (MiB)</translation>
+ <translation>Taille des fragments</translation>
</message>
<message>
<source>SplitFileSwitch</source>
@@ -354,7 +354,36 @@ Acceptez-vous ces changement?</translation>
</message>
<message>
<source>The split size for EWF files must be in the range %1 - %2 MiB.</source>
- <translation>La taille des fragments d'une image EWF doit être comprise entre %1 - %2 MiB.</translation>
+ <translation type="obsolete">La taille des fragments d'une image EWF doit être comprise entre %1 - %2 MiB.</translation>
+ </message>
+ <message>
+ <source>SplitFileUnit</source>
+ <translation> </translation>
+ </message>
+ <message>
+ <source>The split size for the selected image format must be in the range %1MiB - %2EiB.</source>
+ <translation>La taille des fragments du format selectionné doit être comprise entre %1 MiB - %2 EiB.</translation>
+ </message>
+ <message>
+ <source>The split size for the configured EWF format must be in the range %1 - %2 MiB.For bigger files, switch to Encase6 format or later (see Guymager configuration file, parameter EwfFormat).</source>
+ <translation>La taille des fragments pour le format EWF configuré doit être comprise entre %1 - %2 MiB. Des fichiers plus grands sont possibles à partir du format Encase6 (voir fichier de configuration, paramètre EwfFormat).</translation>
+ </message>
+</context>
+<context>
+ <name>t_DlgAutoExit</name>
+ <message>
+ <source>Abort</source>
+ <translation>Annuler</translation>
+ </message>
+ <message>
+ <source>Exit now</source>
+ <translation>Terminer</translation>
+ </message>
+ <message>
+ <source>All acquisitions have ended.
+Guymager will exit automatically in %1 seconds.</source>
+ <translation>Toutes les tâches d'acquisitions ont été accomplies.
+Guymager set terminera automatiquement dans %1 secondes.</translation>
</message>
</context>
<context>
@@ -682,6 +711,10 @@ Utilise libguytools %5</translation>
<comment>column hidden areas</comment>
<translation>non-détectable</translation>
</message>
+ <message>
+ <source>Exit after acquisitions completed</source>
+ <translation>Terminer Guymager à la fin des acquisitions</translation>
+ </message>
</context>
<context>
<name>t_Table</name>
@@ -692,7 +725,7 @@ Utilise libguytools %5</translation>
</message>
<message>
<source>Local Device - cannot be acquired</source>
- <translation>Média local - ne peut être acquéré</translation>
+ <translation>Média local - ne peut être acquis</translation>
</message>
<message>
<source>Device info</source>
diff --git a/guymager_it.ts b/guymager_it.ts
index 1012f86..aa94654 100644
--- a/guymager_it.ts
+++ b/guymager_it.ts
@@ -336,7 +336,31 @@ Do you accept these changes?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The split size for EWF files must be in the range %1 - %2 MiB.</source>
+ <source>SplitFileUnit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The split size for the selected image format must be in the range %1MiB - %2EiB.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The split size for the configured EWF format must be in the range %1 - %2 MiB.For bigger files, switch to Encase6 format or later (see Guymager configuration file, parameter EwfFormat).</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>t_DlgAutoExit</name>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Exit now</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All acquisitions have ended.
+Guymager will exit automatically in %1 seconds.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -659,6 +683,10 @@ Using libguytools %5</source>
<comment>column hidden areas</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Exit after acquisitions completed</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>t_Table</name>
diff --git a/guymager_nl.ts b/guymager_nl.ts
index 5510106..f5ab2cf 100644
--- a/guymager_nl.ts
+++ b/guymager_nl.ts
@@ -336,7 +336,31 @@ Do you accept these changes?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The split size for EWF files must be in the range %1 - %2 MiB.</source>
+ <source>SplitFileUnit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The split size for the selected image format must be in the range %1MiB - %2EiB.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The split size for the configured EWF format must be in the range %1 - %2 MiB.For bigger files, switch to Encase6 format or later (see Guymager configuration file, parameter EwfFormat).</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>t_DlgAutoExit</name>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Exit now</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All acquisitions have ended.
+Guymager will exit automatically in %1 seconds.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -659,6 +683,10 @@ Using libguytools %5</source>
<comment>column hidden areas</comment>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Exit after acquisitions completed</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>t_Table</name>
diff --git a/hash.cpp b/hash.cpp
old mode 100644
new mode 100755
index 9525b0d..2050f8c
--- a/hash.cpp
+++ b/hash.cpp
@@ -9,13 +9,28 @@
// Module: Hash wrapper functions for uniform hash interface
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#include "common.h"
#include <QtCore>
#include "hash.h"
-
// ------------------------------------
// MD5 Functions
// ------------------------------------
diff --git a/hash.h b/hash.h
old mode 100644
new mode 100755
index 26977bf..a12db1e
--- a/hash.h
+++ b/hash.h
@@ -9,6 +9,23 @@
// Module: Hash wrapper functions for uniform hash interface
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __HASH_H__
#define __HASH_H__
diff --git a/info.cpp b/info.cpp
index 8c41a27..ac14722 100644
--- a/info.cpp
+++ b/info.cpp
@@ -9,6 +9,23 @@
// Module: Information about the acquisition, creates the info file
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <errno.h>
#include <QtCore>
diff --git a/info.h b/info.h
index 6eafd22..ee52350 100644
--- a/info.h
+++ b/info.h
@@ -9,12 +9,26 @@
// Module: Information about the acquisition, creates the info file
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __INFO_H__
#define __INFO_H__
-
-
class t_InfoLocal;
class t_Info: public QObject
diff --git a/infofield.cpp b/infofield.cpp
index fc59f6d..cc8407b 100644
--- a/infofield.cpp
+++ b/infofield.cpp
@@ -9,6 +9,23 @@
// Module: The info field area
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <QtGui>
#include "toolconstants.h"
diff --git a/infofield.h b/infofield.h
index 079b36c..6e552f6 100644
--- a/infofield.h
+++ b/infofield.h
@@ -9,7 +9,22 @@
// Module: The info field area
// ****************************************************************************
-
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __INFOFIELD_H__
#define __INFOFIELD_H__
diff --git a/itemdelegate.cpp b/itemdelegate.cpp
index a7ba131..5a6510d 100644
--- a/itemdelegate.cpp
+++ b/itemdelegate.cpp
@@ -10,6 +10,23 @@
// in t_Table.
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <QtGui>
#include "common.h"
diff --git a/itemdelegate.h b/itemdelegate.h
index d1838c3..02ee379 100644
--- a/itemdelegate.h
+++ b/itemdelegate.h
@@ -10,6 +10,23 @@
// in t_Table.
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __ITEMDELEGATE_H__
#define __ITEMDELEGATE_H__
diff --git a/local.cfg b/local.cfg
new file mode 100644
index 0000000..45ce147
--- /dev/null
+++ b/local.cfg
@@ -0,0 +1,42 @@
+
+StartupSizeManualX = 150
+StartupSizeManualY = 250
+StartupSizeManualDx = 1500
+StartupSizeManualDy = 700
+
+TABLE DlgAcquireField NoName
+ REM Field Entry mode Entry mode Default
+ REM name image clone value
+ REM --------------------------------------------------------------------------------------------------------
+ 'SplitFileSize' ShowLast Hide '4'
+ 'SplitFileUnit' ShowLast Hide 'EiB'
+ 'EwfCaseNumber' ShowLast Hide '1'
+ 'EwfEvidenceNumber' ShowDefault Hide '--'
+ 'EwfExaminer' ShowLast Hide 'VOGU / PGD-SPJ-SNT'
+ 'EwfDescription' Hide Hide 'Acquisition of "%model%" started on %dd%.%MM%.%yyyy% at %hh%:%mm%'
+ 'EwfNotes' ShowLast Hide '%serial%'
+ 'DestImageDirectory' ShowLast Hide '/data/xxx/yyy'
+ 'DestInfoDirectory' Hide ShowLast '/data/xxx/yyy'
+ 'DestImageFilename' ShowDefault Hide '%serial%_%size%'
+ 'DestInfoFilename' ShowDefault ShowDefault '%serial%_%size%'
+ENDTABLE
+
+TABLE DlgAcquireRule NoName
+ REM Trigger Destination Value
+ REM field name field name
+ REM ----------------------------------------------------------------------------------------
+REM 'EwfExaminer' 'EwfNotes' 'Acquired by %EwfExaminer% for case %EwfCaseNumber% on %d%.%MM%.%yyyy%'
+REM 'EwfCaseNumber' 'EwfNotes' 'Acquired by %EwfExaminer% for case %EwfCaseNumber% on %d%.%MM%.%yyyy%'
+ 'EwfDescription' 'DestImageFilename' '%EwfDescription%'
+ 'EwfDescription' 'DestInfoFilename' '%EwfDescription%'
+ 'DestImageDirectory' 'DestInfoDirectory' '%DestImageDirectory%'
+ 'DestImageFilename' 'DestInfoFilename' '%DestImageFilename%'
+ENDTABLE
+
+
+SECTION MACADDR_000FEACE580D
+
+ENDSECTION
+
+
+
diff --git a/main.cpp b/main.cpp
index 28c1ef8..9a60413 100644
--- a/main.cpp
+++ b/main.cpp
@@ -11,6 +11,24 @@
// deinitialisation.
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
+#include <mcheck.h>
#include <limits.h>
#include <signal.h>
#include <locale.h>
@@ -22,12 +40,6 @@
#include "common.h"
-#define MEMWATCH
-#define MEMWATCH_NOCPP
-#include "memwatch.h"
-#undef malloc // These have been defined in memwatch.h. We must undefine them
-#undef free // in order to be able to access std::malloc and std::free
-
#include "toolconstants.h"
#include "toolsignal.h"
#include "toolsysinfo.h"
@@ -41,6 +53,7 @@
#include "qtutil.h"
#include "hash.h"
#include "aaff.h"
+#include "aewf.h"
#include "mainwindow.h"
#include "main.h"
@@ -49,6 +62,7 @@
// Macros
// ------------------------------------
+#define MAIN_ENVVAR_MALLOC_TRACE "MALLOC_TRACE"
// ------------------------------------
// Constants
@@ -71,7 +85,9 @@ enum
#define MAIN_LANGUAGE_FILENAME_QT "qt_"
#define MAIN_DEFAULT_MISCFILES_DIR "/usr/share/guymager/"
#define MAIN_DEFAULT_LANGUAGE_DIR_QT "/usr/share/qt4/translations/"
-#define SPLASH_DIR MAIN_DEFAULT_MISCFILES_DIR
+#ifndef SPLASH_DIR
+ #define SPLASH_DIR MAIN_DEFAULT_MISCFILES_DIR
+#endif
// ------------------------------------
// Application-wide global variables
@@ -99,11 +115,6 @@ static t_MainLocal MainLocal;
// Signal & error handling
// ------------------------------------
-static void MainLogMemMessage (int Ch)
-{
- printf ("%c", Ch);
-}
-
static void MainLogQtMessage (QtMsgType MsgType, const char *pMsg)
{
const char *pMsgType;
@@ -171,7 +182,7 @@ static APIRET MainWindowAdjustSize (t_MainWindow *pMainWindow)
if ((MainLocal.pMainWindow->width () > ScreenDx) ||
(MainLocal.pMainWindow->height() > ScreenDy))
{
- LOG_ERROR ("The window manager gave the application a size that's too big: %d x %d (maximum size is %d x %d)",
+ LOG_INFO ("The window manager gave the application a size that's too big: %d x %d (maximum size is %d x %d)",
MainLocal.pMainWindow->width (), MainLocal.pMainWindow->height(), ScreenDx, ScreenDy)
// CHK_CONST (ERROR_MAIN_INVALID_WINDOW_SIZE)
}
@@ -211,7 +222,7 @@ APIRET MainPocessEvents (void)
return NO_ERROR;
}
-static APIRET MainGo (int argc, char *argv[])
+static APIRET MainGo (int argc, char *argv[], bool *pAutoExit)
{
QSplashScreen *pSplashScreen = NULL;
QPixmap *pSplashPixmap;
@@ -264,7 +275,7 @@ static APIRET MainGo (int argc, char *argv[])
LOG_INFO ("Libewf version installed on this PC: %s", pLibEwfVersionInstalled)
meminfo();
LOG_INFO ("Total amount of memory installed: %lu KB", kb_main_total)
-
+
// pLibEwfVersionCompiled = LIBEWF_VERSION_STRING;
//
// LOG_INFO ("Compiled for libewf version: %s", pLibEwfVersionCompiled)
@@ -421,11 +432,6 @@ static APIRET MainGo (int argc, char *argv[])
}
}
- // Initialise MemWatch
- // -------------------
- if (CONFIG(UseMemWatch))
- mwSetOutFunc (MainLogMemMessage);
-
// Initialise signal handler
// -------------------------
if (CONFIG (SignalHandling))
@@ -439,6 +445,7 @@ static APIRET MainGo (int argc, char *argv[])
CHK (QtUtilInit ())
CHK (t_File::Init())
CHK (AaffInit ())
+ CHK (AewfInit ())
switch (CONFIG(NumberStyle))
{
@@ -450,7 +457,7 @@ static APIRET MainGo (int argc, char *argv[])
// Initialise libewf
// -----------------
- libewf_set_notify_values (stderr, CONFIG (VerboseLibewf) ? 1 : 0);
+ libewf_set_notify_values (stderr, CONFIG (VerboseLibewf) ? 1 : 0);
// Create central data structures
// ------------------------------
@@ -460,6 +467,7 @@ static APIRET MainGo (int argc, char *argv[])
// -----------------------------------------------------------
MainLocal.pMainWindow = new t_MainWindow (MainLocal.pDeviceList);
+ CHK_QT_EXIT (MainLocal.pApp->connect(MainLocal.pMainWindow, SIGNAL(SignalAutoExit(void)), MainLocal.pApp, SLOT(quit(void))))
CHK (MainWindowAdjustSize (MainLocal.pMainWindow))
if (pSplashScreen)
@@ -474,6 +482,7 @@ static APIRET MainGo (int argc, char *argv[])
FifoRemaining = FifoAllocs - FifoFrees;
LOG_INFO ("FIFO buffer statistics: %llu allocated - %llu freed = %lld remaining (%lld bytes)", FifoAllocs, FifoFrees, FifoRemaining, FifoAllocated)
+ *pAutoExit = MainLocal.pMainWindow->AutoExit();
// Deinitialise and exit the program
// ---------------------------------
@@ -484,6 +493,7 @@ static APIRET MainGo (int argc, char *argv[])
MainLocal.pDeviceList = NULL;
MainLocal.pNumberLocale = NULL;
+ CHK (AewfDeInit ())
CHK (AaffDeInit ())
CHK (QtUtilDeInit())
CHK (HashDeInit ())
@@ -515,10 +525,19 @@ QLocale *MainGetpNumberLocale (void)
int main (int argc, char *argv[])
{
- APIRET rc;
- int i;
- int Len=0;
-
+ APIRET rc;
+ int i;
+ int Len=0;
+ int ExitCode = EXIT_NO_ERROR;
+ bool AutoExit;
+ const char *pFilenameMallocTracing;
+
+ pFilenameMallocTracing = getenv (MAIN_ENVVAR_MALLOC_TRACE);
+ if (pFilenameMallocTracing != NULL) // Switch on memory allocation tracing,
+ {
+ printf ("\nSwitching malloc tracing on, output file is %s", pFilenameMallocTracing);
+ mtrace(); // see tracing functionality in GNU C lib
+ }
setbuf(stdout, NULL);
setbuf(stderr, NULL);
setlocale (LC_ALL, "");
@@ -540,7 +559,9 @@ int main (int argc, char *argv[])
strcat (MainLocal.pCommandLine, argv[i]);
}
- rc = MainGo (argc, argv);
+ rc = MainGo (argc, argv, &AutoExit);
+ if (AutoExit)
+ ExitCode = EXIT_AUTOEXIT;
free (MainLocal.pCommandLine);
@@ -549,7 +570,7 @@ int main (int argc, char *argv[])
printf ("Error in configuration file. See log file for details.\n");
else CHK_EXIT (rc)
- return rc;
+ return ExitCode;
}
t_pDeviceList MainGetDeviceList (void)
diff --git a/main.h b/main.h
index f2d6325..96d0385 100644
--- a/main.h
+++ b/main.h
@@ -9,6 +9,22 @@
// Module: Main
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
APIRET MainPocessEvents (void);
APIRET MainGetCommandLine (char **ppCommandLine);
diff --git a/mainwindow.cpp b/mainwindow.cpp
index d7226c8..030dd6a 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -10,6 +10,22 @@
// widget
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#include <QtGui>
@@ -27,6 +43,7 @@
#include "infofield.h"
#include "table.h"
#include "dlgmessage.h"
+#include "dlgautoexit.h"
// -----------------------------
@@ -35,7 +52,6 @@
const int MAINWINDOW_WAIT_FOR_THREADS_TO_ABORT = 5000;
-
// -----------------------------
// Table model for device list
// -----------------------------
@@ -185,8 +201,11 @@ class t_MainWindowLocal
t_pInfoField pInfoField;
t_ThreadScan *pThreadScan;
QAction *pActionRescan;
+ QAction *pActionAutoExit;
t_ThreadScanWorker *pScanWorker;
QTimer *pTimerRefresh;
+ bool AutoExit;
+ bool AllAbortedByUser;
};
static APIRET MainWindowRegisterErrorCodes (void)
@@ -218,6 +237,9 @@ APIRET t_MainWindow::CreateMenu (void)
pMenu->addAction (tr("Add special device", "Menu entry"), this, SLOT(SlotAddSpecialDevice()));
pMenu = pMenuBar->addMenu (tr("&Misc", "Menu entry"));
+ pOwn->pActionAutoExit = pMenu->addAction (tr("Exit after acquisitions completed"));
+ pOwn->pActionAutoExit->setCheckable(true);
+ pOwn->pActionAutoExit->setChecked ((CONFIG(AutoExit)!=0));
pMenu->addAction (tr("Debug", "Menu entry"), this, SLOT(SlotDebug()));
pMenu = pMenuBar->addMenu (tr("&Help", "Menu entry"));
@@ -252,6 +274,8 @@ t_MainWindow::t_MainWindow (t_pDeviceList pDeviceList, QWidget *pParent, Qt::WFl
pOwn = new t_MainWindowLocal;
pOwn->pDeviceList = pDeviceList;
+ pOwn->AutoExit = false;
+ pOwn->AllAbortedByUser = false;
CHK_EXIT (CreateMenu ())
setWindowTitle ("GUYMAGER");
@@ -276,8 +300,9 @@ t_MainWindow::t_MainWindow (t_pDeviceList pDeviceList, QWidget *pParent, Qt::WFl
pLayout->addWidget (pOwn->pTable);
pLayout->addWidget (pOwn->pInfoField);
- CHK_QT_EXIT (connect (pOwn->pTable->horizontalHeader(), SIGNAL(sectionClicked (int )), pOwn->pTable , SLOT(sortByColumn (int ))))
- CHK_QT_EXIT (connect (pOwn->pTable , SIGNAL(SignalDeviceSelected(t_pDevice)), pOwn->pInfoField, SLOT (SlotShowInfo (t_pDevice))))
+ CHK_QT_EXIT (connect (pOwn->pTable->horizontalHeader(), SIGNAL(sectionClicked (int )), pOwn->pTable , SLOT(sortByColumn (int ))))
+ CHK_QT_EXIT (connect (pOwn->pTable , SIGNAL(SignalDeviceSelected (t_pDevice)), pOwn->pInfoField, SLOT (SlotShowInfo (t_pDevice))))
+ CHK_QT_EXIT (connect (pOwn->pTable , SIGNAL(SignalAllAcquisitionsEnded(void )), this , SLOT (SlotAutoExit (void ))))
setCentralWidget (pOwn->pCentralWidget);
@@ -366,7 +391,6 @@ void t_MainWindow::SlotAddSpecialDevice (void)
pOwn->pTable->resizeColumnsToContents();
}
-
APIRET t_MainWindow::RemoveSpecialDevice (t_pDevice pDevice)
{
int i;
@@ -402,6 +426,7 @@ void t_MainWindow::SlotScanFinished (t_pDeviceList pNewDeviceList)
t_pDevice pDev, pNewDev;
int i;
+// LOG_INFO ("%d devices found", pNewDeviceList->count())
pDeviceList = pOwn->pDeviceList;
for (i=0; i<pDeviceList->count(); i++)
{
@@ -415,7 +440,16 @@ void t_MainWindow::SlotScanFinished (t_pDeviceList pNewDeviceList)
{
pNewDev = pNewDeviceList->at (i);
CHK_EXIT (pDeviceList->MatchDevice (pNewDev, pDev))
-// LOG_INFO ("Result of match for %s: %s", QSTR_TO_PSZ (pNewDev->LinuxDevice), pDev ? "Match" : "NoMatch")
+// if (pDev)
+// {
+// LOG_INFO ("device %s %s %s %llu matches %s %s %s %llu",
+// QSTR_TO_PSZ (pNewDev->LinuxDevice), QSTR_TO_PSZ (pNewDev->Model), QSTR_TO_PSZ (pNewDev->SerialNumber), pNewDev->Size,
+// QSTR_TO_PSZ ( pDev->LinuxDevice), QSTR_TO_PSZ ( pDev->Model), QSTR_TO_PSZ ( pDev->SerialNumber), pNewDev->Size)
+// }
+// else
+// {
+// LOG_INFO ("No match for device %s %s %s %llu", QSTR_TO_PSZ (pNewDev->LinuxDevice), QSTR_TO_PSZ (pNewDev->Model), QSTR_TO_PSZ (pNewDev->SerialNumber), pNewDev->Size)
+// }
if (pDev)
{
@@ -486,6 +520,7 @@ void t_MainWindow::closeEvent (QCloseEvent *pEvent)
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
if (Button == QMessageBox::Yes)
{ // stop acquisitions
+ pOwn->AllAbortedByUser = true;
LOG_INFO ("User confirms abortion in order to quit")
CHK_EXIT (pOwn->pTable->AbortAllAcquisitions ())
CHK_EXIT (QtUtilSleep (MAINWINDOW_WAIT_FOR_THREADS_TO_ABORT))
@@ -545,6 +580,39 @@ void t_MainWindow::SlotAboutQt (void)
QMessageBox::aboutQt (this, tr("About Qt", "Dialog title"));
}
+void t_MainWindow::SlotAutoExit (void)
+{
+ bool AutoExit;
+
+ if (!pOwn->AllAbortedByUser)
+ {
+ if (pOwn->pActionAutoExit->isChecked())
+ {
+ LOG_INFO ("Showing autoexit countdown dialog (%d seconds)", CONFIG(AutoExitCountdown))
+ CHK_EXIT (t_DlgAutoExit::Show (&AutoExit))
+ if (AutoExit)
+ {
+ LOG_INFO ("Autoexit is becoming active, Guymager is exiting automatically now.")
+ pOwn->AutoExit = true;
+ emit SignalAutoExit();
+ }
+ else
+ {
+ LOG_INFO ("Autoexit coutdown has been stopped. Guymager will continue to run.")
+ }
+ }
+ else
+ {
+ LOG_INFO ("Signal \"all acquisitions ended\" received, but autoexit flag is off, doing nothing.")
+ }
+ }
+}
+
+bool t_MainWindow::AutoExit (void)
+{
+ return pOwn->AutoExit;
+}
+
t_MainWindow::~t_MainWindow ()
{
CHK_EXIT (pOwn->pThreadScan->Stop ())
diff --git a/mainwindow.h b/mainwindow.h
index a011f2c..f8f1a3a 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -7,6 +7,22 @@
// Section Nouvelles Technologies
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __MAINWINDOW_H__
#define __MAINWINDOW_H__
@@ -32,6 +48,7 @@ class t_MainWindow: public QMainWindow
~t_MainWindow ();
APIRET RemoveSpecialDevice (t_pDevice pDevice);
+ bool AutoExit (void);
private:
APIRET CreateMenu (void);
@@ -44,9 +61,13 @@ class t_MainWindow: public QMainWindow
void SlotDebug (void);
void SlotAboutGuymager (void);
void SlotAboutQt (void);
+ void SlotAutoExit (void);
void SlotScanFinished (t_pDeviceList);
void SlotRefresh ();
+ signals:
+ void SignalAutoExit (void);
+
private:
t_MainWindowLocal *pOwn;
};
diff --git a/manuals/guymager_body.1 b/manuals/guymager.1
similarity index 74%
copy from manuals/guymager_body.1
copy to manuals/guymager.1
index 27a7cfe..c5c0c78 100644
--- a/manuals/guymager_body.1
+++ b/manuals/guymager.1
@@ -1,3 +1,4 @@
+.TH guymager 1 "2011-07-01" "version 0.5.8beta9-1" "guymager manual pages"
.SH NAME
guymager \- a forensic acquisition program
.SH SYNOPSIS
@@ -6,13 +7,13 @@ guymager \- a forensic acquisition program
[\fBcfg=\fIconfiguration_file\fR]
[options]
.SH DESCRIPTION
-Guymager is a Qt-based forensic imager. It is capable of producing image files in EWF
-and dd format. Its main strenghs are the easy user interface, the extended acquisition
-info file and the high imaging speed.
+Guymager is a Qt-based forensic imager. It is capable of producing image files in EWF, AFF
+and dd format. Its main strenghs are the easy user interface, the high imaging speed and the
+extended acquisition info file.
.PP
-The internal structure is based on separate threads for reading, MD5 calculation, writing
-and includes a parallelised compression engine, thus making full usage of multi\-processor
-and hyper\-threading machines.
+The internal structure is based on separate threads for reading, hash calculation (MD5 and
+SHA256), writing and includes a parallelised compression engine, thus making full usage of
+multi\-processor and hyper\-threading machines.
.PP
Guymager should be run with root privileges, as other users do not have access to physical
devices normally.
@@ -33,6 +34,9 @@ All other configuration options may be specified on the command line and/or in t
configuration file. See /etc/guymager/guymager.cfg for a description of all possible
options. In case an option is specified in the configuration file and on the command
line, the command line dominates.
+.SH EXIT CODES
+.TP
+Guymager normally returns an exit code of 0. Exit code 1 means that Guymager terminated because the AutoExit function became active. All other exit codes are related to internal Guymager or Qt errors.
.SH EXAMPLES
.TP
Write all log entries to ./my.log:
diff --git a/manuals/guymager_body.1 b/manuals/guymager_body.1
index 27a7cfe..cdf1a45 100644
--- a/manuals/guymager_body.1
+++ b/manuals/guymager_body.1
@@ -6,13 +6,13 @@ guymager \- a forensic acquisition program
[\fBcfg=\fIconfiguration_file\fR]
[options]
.SH DESCRIPTION
-Guymager is a Qt-based forensic imager. It is capable of producing image files in EWF
-and dd format. Its main strenghs are the easy user interface, the extended acquisition
-info file and the high imaging speed.
+Guymager is a Qt-based forensic imager. It is capable of producing image files in EWF, AFF
+and dd format. Its main strenghs are the easy user interface, the high imaging speed and the
+extended acquisition info file.
.PP
-The internal structure is based on separate threads for reading, MD5 calculation, writing
-and includes a parallelised compression engine, thus making full usage of multi\-processor
-and hyper\-threading machines.
+The internal structure is based on separate threads for reading, hash calculation (MD5 and
+SHA256), writing and includes a parallelised compression engine, thus making full usage of
+multi\-processor and hyper\-threading machines.
.PP
Guymager should be run with root privileges, as other users do not have access to physical
devices normally.
@@ -33,6 +33,9 @@ All other configuration options may be specified on the command line and/or in t
configuration file. See /etc/guymager/guymager.cfg for a description of all possible
options. In case an option is specified in the configuration file and on the command
line, the command line dominates.
+.SH EXIT CODES
+.TP
+Guymager normally returns an exit code of 0. Exit code 1 means that Guymager terminated because the AutoExit function became active. All other exit codes are related to internal Guymager or Qt errors.
.SH EXAMPLES
.TP
Write all log entries to ./my.log:
diff --git a/md5.h b/md5.h
index 38a0a2a..504dee3 100644
--- a/md5.h
+++ b/md5.h
@@ -1,5 +1,5 @@
// This file has been copied 1:1 from the source of the Debian fdupes package into Guymager.
-// Only has been added this comment, no other changes.
+// Only have been added these 2 comment lines, no other changes.
/*
Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
diff --git a/media.h b/media.h
index c94cc89..eb8bba1 100644
--- a/media.h
+++ b/media.h
@@ -9,6 +9,23 @@
// Module: Module for special media function, like HPA/DCO and others
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __MEDIA_H__
#define __MEDIA_H__
diff --git a/memwatch.c b/memwatch.c
deleted file mode 100644
index 08c5f39..0000000
--- a/memwatch.c
+++ /dev/null
@@ -1,2664 +0,0 @@
-/*
-** MEMWATCH.C
-** Nonintrusive ANSI C memory leak / overwrite detection
-** Copyright (C) 1992-2003 Johan Lindh
-** All rights reserved.
-** Version 2.71
-
- This file is part of MEMWATCH.
-
- MEMWATCH is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- MEMWATCH is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with MEMWATCH; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-**
-** 920810 JLI [1.00]
-** 920830 JLI [1.10 double-free detection]
-** 920912 JLI [1.15 mwPuts, mwGrab/Drop, mwLimit]
-** 921022 JLI [1.20 ASSERT and VERIFY]
-** 921105 JLI [1.30 C++ support and TRACE]
-** 921116 JLI [1.40 mwSetOutFunc]
-** 930215 JLI [1.50 modified ASSERT/VERIFY]
-** 930327 JLI [1.51 better auto-init & PC-lint support]
-** 930506 JLI [1.55 MemWatch class, improved C++ support]
-** 930507 JLI [1.60 mwTest & CHECK()]
-** 930809 JLI [1.65 Abort/Retry/Ignore]
-** 930820 JLI [1.70 data dump when unfreed]
-** 931016 JLI [1.72 modified C++ new/delete handling]
-** 931108 JLI [1.77 mwSetAssertAction() & some small changes]
-** 940110 JLI [1.80 no-mans-land alloc/checking]
-** 940328 JLI [2.00 version 2.0 rewrite]
-** Improved NML (no-mans-land) support.
-** Improved performance (especially for free()ing!).
-** Support for 'read-only' buffers (checksums)
-** ^^ NOTE: I never did this... maybe I should?
-** FBI (free'd block info) tagged before freed blocks
-** Exporting of the mwCounter variable
-** mwBreakOut() localizes debugger support
-** Allocation statistics (global, per-module, per-line)
-** Self-repair ability with relinking
-** 950913 JLI [2.10 improved garbage handling]
-** 951201 JLI [2.11 improved auto-free in emergencies]
-** 960125 JLI [X.01 implemented auto-checking using mwAutoCheck()]
-** 960514 JLI [2.12 undefining of existing macros]
-** 960515 JLI [2.13 possibility to use default new() & delete()]
-** 960516 JLI [2.20 suppression of file flushing on unfreed msgs]
-** 960516 JLI [2.21 better support for using MEMWATCH with DLL's]
-** 960710 JLI [X.02 multiple logs and mwFlushNow()]
-** 960801 JLI [2.22 merged X.01 version with current]
-** 960805 JLI [2.30 mwIsXXXXAddr() to avoid unneeded GP's]
-** 960805 JLI [2.31 merged X.02 version with current]
-** 961002 JLI [2.32 support for realloc() + fixed STDERR bug]
-** 961222 JLI [2.40 added mwMark() & mwUnmark()]
-** 970101 JLI [2.41 added over/underflow checking after failed ASSERT/VERIFY]
-** 970113 JLI [2.42 added support for PC-Lint 7.00g]
-** 970207 JLI [2.43 added support for strdup()]
-** 970209 JLI [2.44 changed default filename to lowercase]
-** 970405 JLI [2.45 fixed bug related with atexit() and some C++ compilers]
-** 970723 JLI [2.46 added MW_ARI_NULLREAD flag]
-** 970813 JLI [2.47 stabilized marker handling]
-** 980317 JLI [2.48 ripped out C++ support; wasn't working good anyway]
-** 980318 JLI [2.50 improved self-repair facilities & SIGSEGV support]
-** 980417 JLI [2.51 more checks for invalid addresses]
-** 980512 JLI [2.52 moved MW_ARI_NULLREAD to occur before aborting]
-** 990112 JLI [2.53 added check for empty heap to mwIsOwned]
-** 990217 JLI [2.55 improved the emergency repairs diagnostics and NML]
-** 990224 JLI [2.56 changed ordering of members in structures]
-** 990303 JLI [2.57 first maybe-fixit-for-hpux test]
-** 990516 JLI [2.58 added 'static' to the definition of mwAutoInit]
-** 990517 JLI [2.59 fixed some high-sensitivity warnings]
-** 990610 JLI [2.60 fixed some more high-sensitivity warnings]
-** 990715 JLI [2.61 changed TRACE/ASSERT/VERIFY macro names]
-** 991001 JLI [2.62 added CHECK_BUFFER() and mwTestBuffer()]
-** 991007 JLI [2.63 first shot at a 64-bit compatible version]
-** 991009 JLI [2.64 undef's strdup() if defined, mwStrdup made const]
-** 000704 JLI [2.65 added some more detection for 64-bits]
-** 010502 JLI [2.66 incorporated some user fixes]
-** [mwRelink() could print out garbage pointer (thanks mac at phobos.ca)]
-** [added array destructor for C++ (thanks rdasilva at connecttel.com)]
-** [added mutex support (thanks rdasilva at connecttel.com)]
-** 010531 JLI [2.67 fix: mwMutexXXX() was declared even if MW_HAVE_MUTEX was not defined]
-** 010619 JLI [2.68 fix: mwRealloc() could leave the mutex locked]
-** 020918 JLI [2.69 changed to GPL, added C++ array allocation by Howard Cohen]
-** 030212 JLI [2.70 mwMalloc() bug for very large allocations (4GB on 32bits)]
-** 030520 JLI [2.71 added ULONG_LONG_MAX as a 64-bit detector (thanks Sami Salonen)]
-*/
-
-#define __MEMWATCH_C 1
-
-#ifdef MW_NOCPP
-#define MEMWATCH_NOCPP
-#endif
-#ifdef MW_STDIO
-#define MEMWATCH_STDIO
-#endif
-
-/***********************************************************************
-** Include files
-***********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <time.h>
-#include <limits.h>
-#include "memwatch.h"
-
-#ifndef toupper
-#include <ctype.h>
-#endif
-
-#if defined(WIN32) || defined(__WIN32__)
-#define MW_HAVE_MUTEX 1
-#include <windows.h>
-#endif
-
-#if defined(MW_PTHREADS) || defined(HAVE_PTHREAD_H)
-#define MW_HAVE_MUTEX 1
-#include <pthread.h>
-#endif
-
-/***********************************************************************
-** Defines & other weird stuff
-***********************************************************************/
-
-/*lint -save -e767 */
-#define VERSION "2.71" /* the current version number */
-#define CHKVAL(mw) (0xFE0180L^(long)mw->count^(long)mw->size^(long)mw->line)
-#define FLUSH() mwFlush()
-#define TESTS(f,l) if(mwTestAlways) (void)mwTestNow(f,l,1)
-#define PRECHK 0x01234567L
-#define POSTCHK 0x76543210L
-#define mwBUFFER_TO_MW(p) ( (mwData*) (void*) ( ((char*)p)-mwDataSize-mwOverflowZoneSize ) )
-/*lint -restore */
-
-#define MW_NML 0x0001
-
-#ifdef _MSC_VER
-#define COMMIT "c" /* Microsoft C requires the 'c' to perform as desired */
-#else
-#define COMMIT "" /* Normal ANSI */
-#endif /* _MSC_VER */
-
-#ifdef __cplusplus
-#define CPPTEXT "++"
-#else
-#define CPPTEXT ""
-#endif /* __cplusplus */
-
-#ifdef MEMWATCH_STDIO
-#define mwSTDERR stderr
-#else
-#define mwSTDERR mwLog
-#endif
-
-#ifdef MW_HAVE_MUTEX
-#define MW_MUTEX_INIT() mwMutexInit()
-#define MW_MUTEX_TERM() mwMutexTerm()
-#define MW_MUTEX_LOCK() mwMutexLock()
-#define MW_MUTEX_UNLOCK() mwMutexUnlock()
-#else
-#define MW_MUTEX_INIT()
-#define MW_MUTEX_TERM()
-#define MW_MUTEX_LOCK()
-#define MW_MUTEX_UNLOCK()
-#endif
-
-/***********************************************************************
-** If you really, really know what you're doing,
-** you can predefine these things yourself.
-***********************************************************************/
-
-#ifndef mwBYTE_DEFINED
-# if CHAR_BIT != 8
-# error need CHAR_BIT to be 8!
-# else
-typedef unsigned char mwBYTE;
-# define mwBYTE_DEFINED 1
-# endif
-#endif
-
-#if defined(ULONGLONG_MAX) || defined(ULLONG_MAX) || defined(_UI64_MAX) || defined(ULONG_LONG_MAX)
-# define mw64BIT 1
-# define mwROUNDALLOC_DEFAULT 8
-#else
-# if UINT_MAX <= 0xFFFFUL
-# define mw16BIT 1
-# define mwROUNDALLOC_DEFAULT 2
-# else
-# if ULONG_MAX > 0xFFFFFFFFUL
-# define mw64BIT 1
-# define mwROUNDALLOC_DEFAULT 8
-# else
-# define mw32BIT 1
-# define mwROUNDALLOC_DEFAULT 4
-# endif
-# endif
-#endif
-
-/* mwROUNDALLOC is the number of bytes to */
-/* round up to, to ensure that the end of */
-/* the buffer is suitable for storage of */
-/* any kind of object */
-#ifndef mwROUNDALLOC
-# define mwROUNDALLOC mwROUNDALLOC_DEFAULT
-#endif
-
-#ifndef mwDWORD_DEFINED
-#if ULONG_MAX == 0xFFFFFFFFUL
-typedef unsigned long mwDWORD;
-#define mwDWORD_DEFINED "unsigned long"
-#endif
-#endif
-
-#ifndef mwDWORD_DEFINED
-#if UINT_MAX == 0xFFFFFFFFUL
-typedef unsigned int mwDWORD;
-#define mwDWORD_DEFINED "unsigned int"
-#endif
-#endif
-
-#ifndef mwDWORD_DEFINED
-#if USHRT_MAX == 0xFFFFFFFFUL
-typedef unsigned short mwDWORD;
-#define mwDWORD_DEFINED "unsigned short"
-#endif
-#endif
-
-#ifndef mwBYTE_DEFINED
-#error "can't find out the correct type for a 8 bit scalar"
-#endif
-
-#ifndef mwDWORD_DEFINED
-#error "can't find out the correct type for a 32 bit scalar"
-#endif
-
-/***********************************************************************
-** Typedefs & structures
-***********************************************************************/
-
-/* main data holding area, precedes actual allocation */
-typedef struct mwData_ mwData;
-struct mwData_ {
- mwData* prev; /* previous allocation in chain */
- mwData* next; /* next allocation in chain */
- const char* file; /* file name where allocated */
- long count; /* action count */
- long check; /* integrity check value */
-#if 0
- long crc; /* data crc value */
-#endif
- size_t size; /* size of allocation */
- int line; /* line number where allocated */
- unsigned flag; /* flag word */
- };
-
-/* statistics structure */
-typedef struct mwStat_ mwStat;
-struct mwStat_ {
- mwStat* next; /* next statistic buffer */
- const char* file;
- long total; /* total bytes allocated */
- long num; /* total number of allocations */
- long max; /* max allocated at one time */
- long curr; /* current allocations */
- int line;
- };
-
-/* grabbing structure, 1K in size */
-typedef struct mwGrabData_ mwGrabData;
-struct mwGrabData_ {
- mwGrabData* next;
- int type;
- char blob[ 1024 - sizeof(mwGrabData*) - sizeof(int) ];
- };
-
-typedef struct mwMarker_ mwMarker;
-struct mwMarker_ {
- void *host;
- char *text;
- mwMarker *next;
- int level;
- };
-
-#if defined(WIN32) || defined(__WIN32__)
-typedef HANDLE mwMutex;
-#endif
-
-#if defined(MW_PTHREADS) || defined(HAVE_PTHREAD_H)
-typedef pthread_mutex_t mwMutex;
-#endif
-
-/***********************************************************************
-** Static variables
-***********************************************************************/
-
-static int mwInited = 0;
-static int mwInfoWritten = 0;
-static int mwUseAtexit = 0;
-static FILE* mwLog = NULL;
-static int mwFlushing = 0;
-static int mwStatLevel = MW_STAT_DEFAULT;
-static int mwNML = MW_NML_DEFAULT;
-static int mwFBI = 0;
-static long mwAllocLimit = 0L;
-static int mwUseLimit = 0;
-
-static long mwNumCurAlloc = 0L;
-static mwData* mwHead = NULL;
-static mwData* mwTail = NULL;
-static int mwDataSize = 0;
-static unsigned char mwOverflowZoneTemplate[] = "mEmwAtch";
-static int mwOverflowZoneSize = mwROUNDALLOC;
-
-static void (*mwOutFunction)(int) = NULL;
-static int (*mwAriFunction)(const char*) = NULL;
-static int mwAriAction = MW_ARI_ABORT;
-
-static char mwPrintBuf[MW_TRACE_BUFFER+8];
-
-static unsigned long mwCounter = 0L;
-static long mwErrors = 0L;
-
-static int mwTestFlags = 0;
-static int mwTestAlways = 0;
-
-static FILE* mwLogB1 = NULL;
-static int mwFlushingB1 = 0;
-
-static mwStat* mwStatList = NULL;
-static long mwStatTotAlloc = 0L;
-static long mwStatMaxAlloc = 0L;
-static long mwStatNumAlloc = 0L;
-static long mwStatCurAlloc = 0L;
-static long mwNmlNumAlloc = 0L;
-static long mwNmlCurAlloc = 0L;
-
-static mwGrabData* mwGrabList = NULL;
-static long mwGrabSize = 0L;
-
-static void * mwLastFree[MW_FREE_LIST];
-static const char *mwLFfile[MW_FREE_LIST];
-static int mwLFline[MW_FREE_LIST];
-static int mwLFcur = 0;
-
-static mwMarker* mwFirstMark = NULL;
-
-static FILE* mwLogB2 = NULL;
-static int mwFlushingB2 = 0;
-
-#ifdef MW_HAVE_MUTEX
-static mwMutex mwGlobalMutex;
-#endif
-
-/***********************************************************************
-** Static function declarations
-***********************************************************************/
-
-static void mwAutoInit( void );
-static FILE* mwLogR( void );
-static void mwLogW( FILE* );
-static int mwFlushR( void );
-static void mwFlushW( int );
-static void mwFlush( void );
-static void mwIncErr( void );
-static void mwUnlink( mwData*, const char* file, int line );
-static int mwRelink( mwData*, const char* file, int line );
-static int mwIsHeapOK( mwData *mw );
-static int mwIsOwned( mwData* mw, const char* file, int line );
-static int mwTestBuf( mwData* mw, const char* file, int line );
-static void mwDefaultOutFunc( int );
-static void mwWrite( const char* format, ... );
-static void mwLogFile( const char* name );
-static size_t mwFreeUp( size_t, int );
-static const void *mwTestMem( const void *, unsigned, int );
-static int mwStrCmpI( const char *s1, const char *s2 );
-static int mwTestNow( const char *file, int line, int always_invoked );
-static void mwDropAll( void );
-static const char *mwGrabType( int type );
-static unsigned mwGrab_( unsigned kb, int type, int silent );
-static unsigned mwDrop_( unsigned kb, int type, int silent );
-static int mwARI( const char* text );
-static void mwStatReport( void );
-static mwStat* mwStatGet( const char*, int, int );
-static void mwStatAlloc( size_t, const char*, int );
-static void mwStatFree( size_t, const char*, int );
-static int mwCheckOF( const void * p );
-static void mwWriteOF( void * p );
-static char mwDummy( char c );
-#ifdef MW_HAVE_MUTEX
-static void mwMutexInit( void );
-static void mwMutexTerm( void );
-static void mwMutexLock( void );
-static void mwMutexUnlock( void );
-#endif
-
-/***********************************************************************
-** System functions
-***********************************************************************/
-
-void mwInit( void ) {
- time_t tid;
-
- if( mwInited++ > 0 ) return;
-
- MW_MUTEX_INIT();
-
- /* start a log if none is running */
- if( mwLogR() == NULL ) mwLogFile( "memwatch.log" );
- if( mwLogR() == NULL ) {
- int i;
- char buf[32];
- /* oops, could not open it! */
- /* probably because it's already open */
- /* so we try some other names */
- for( i=1; i<100; i++ ) {
- sprintf( buf, "memwat%02d.log", i );
- mwLogFile( buf );
- if( mwLogR() != NULL ) break;
- }
- }
-
- /* initialize the statistics */
- mwStatList = NULL;
- mwStatTotAlloc = 0L;
- mwStatCurAlloc = 0L;
- mwStatMaxAlloc = 0L;
- mwStatNumAlloc = 0L;
- mwNmlCurAlloc = 0L;
- mwNmlNumAlloc = 0L;
-
- /* calculate the buffer size to use for a mwData */
- mwDataSize = sizeof(mwData);
- while( mwDataSize % mwROUNDALLOC ) mwDataSize ++;
-
- /* write informational header if needed */
- if( !mwInfoWritten ) {
- mwInfoWritten = 1;
- (void) time( &tid );
- mwWrite(
- "\n============="
- " MEMWATCH " VERSION " Copyright (C) 1992-1999 Johan Lindh "
- "=============\n");
- mwWrite( "\nStarted at %s\n", ctime( &tid ) );
-
-/**************************************************************** Generic */
- mwWrite( "Modes: " );
-#ifdef mwNew
- mwWrite( "C++ " );
-#endif /* mwNew */
-#ifdef __STDC__
- mwWrite( "__STDC__ " );
-#endif /* __STDC__ */
-#ifdef mw16BIT
- mwWrite( "16-bit " );
-#endif
-#ifdef mw32BIT
- mwWrite( "32-bit " );
-#endif
-#ifdef mw64BIT
- mwWrite( "64-bit " );
-#endif
- mwWrite( "mwDWORD==(" mwDWORD_DEFINED ")\n" );
- mwWrite( "mwROUNDALLOC==%d sizeof(mwData)==%d mwDataSize==%d\n",
- mwROUNDALLOC, sizeof(mwData), mwDataSize );
-/**************************************************************** Generic */
-
-/************************************************************ Microsoft C */
-#ifdef _MSC_VER
- mwWrite( "Compiled using Microsoft C" CPPTEXT
- " %d.%02d\n", _MSC_VER / 100, _MSC_VER % 100 );
-#endif /* _MSC_VER */
-/************************************************************ Microsoft C */
-
-/************************************************************** Borland C */
-#ifdef __BORLANDC__
- mwWrite( "Compiled using Borland C"
-#ifdef __cplusplus
- "++ %d.%01d\n", __BCPLUSPLUS__/0x100, (__BCPLUSPLUS__%0x100)/0x10 );
-#else
- " %d.%01d\n", __BORLANDC__/0x100, (__BORLANDC__%0x100)/0x10 );
-#endif /* __cplusplus */
-#endif /* __BORLANDC__ */
-/************************************************************** Borland C */
-
-/************************************************************** Watcom C */
-#ifdef __WATCOMC__
- mwWrite( "Compiled using Watcom C %d.%02d ",
- __WATCOMC__/100, __WATCOMC__%100 );
-#ifdef __FLAT__
- mwWrite( "(32-bit flat model)" );
-#endif /* __FLAT__ */
- mwWrite( "\n" );
-#endif /* __WATCOMC__ */
-/************************************************************** Watcom C */
-
- mwWrite( "\n" );
- FLUSH();
- }
-
- if( mwUseAtexit ) (void) atexit( mwAbort );
- return;
- }
-
-void mwAbort( void ) {
- mwData *mw;
- mwMarker *mrk;
- char *data;
- time_t tid;
- int c, i, j;
- int errors;
-
- tid = time( NULL );
- mwWrite( "\nStopped at %s\n", ctime( &tid) );
-
- if( !mwInited )
- mwWrite( "internal: mwAbort(): MEMWATCH not initialized!\n" );
-
- /* release the grab list */
- mwDropAll();
-
- /* report mwMarked items */
- while( mwFirstMark ) {
- mrk = mwFirstMark->next;
- mwWrite( "mark: %p: %s\n", mwFirstMark->host, mwFirstMark->text );
- free( mwFirstMark->text );
- free( mwFirstMark );
- mwFirstMark = mrk;
- mwErrors ++;
- }
-
- /* release all still allocated memory */
- errors = 0;
- while( mwHead != NULL && errors < 3 ) {
- if( !mwIsOwned(mwHead, __FILE__, __LINE__ ) ) {
- if( errors < 3 )
- {
- errors ++;
- mwWrite( "internal: NML/unfreed scan restarting\n" );
- FLUSH();
- mwHead = mwHead;
- continue;
- }
- mwWrite( "internal: NML/unfreed scan aborted, heap too damaged\n" );
- FLUSH();
- break;
- }
- mwFlushW(0);
- if( !(mwHead->flag & MW_NML) ) {
- mwErrors++;
- data = ((char*)mwHead)+mwDataSize;
- mwWrite( "unfreed: <%ld> %s(%d), %ld bytes at %p ",
- mwHead->count, mwHead->file, mwHead->line, (long)mwHead->size, data+mwOverflowZoneSize );
- if( mwCheckOF( data ) ) {
- mwWrite( "[underflowed] ");
- FLUSH();
- }
- if( mwCheckOF( (data+mwOverflowZoneSize+mwHead->size) ) ) {
- mwWrite( "[overflowed] ");
- FLUSH();
- }
- mwWrite( " \t{" );
- j = 16; if( mwHead->size < 16 ) j = (int) mwHead->size;
- for( i=0;i<16;i++ ) {
- if( i<j ) mwWrite( "%02X ",
- (unsigned char) *(data+mwOverflowZoneSize+i) );
- else mwWrite( ".. " );
- }
- for( i=0;i<j;i++ ) {
- c = *(data+mwOverflowZoneSize+i);
- if( c < 32 || c > 126 ) c = '.';
- mwWrite( "%c", c );
- }
- mwWrite( "}\n" );
- mw = mwHead;
- mwUnlink( mw, __FILE__, __LINE__ );
- free( mw );
- }
- else {
- data = ((char*)mwHead) + mwDataSize + mwOverflowZoneSize;
- if( mwTestMem( data, mwHead->size, MW_VAL_NML ) ) {
- mwErrors++;
- mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n",
- mwHead->count, data + mwOverflowZoneSize, mwHead->file, mwHead->line );
- FLUSH();
- }
- mwNmlNumAlloc --;
- mwNmlCurAlloc -= mwHead->size;
- mw = mwHead;
- mwUnlink( mw, __FILE__, __LINE__ );
- free( mw );
- }
- }
-
- if( mwNmlNumAlloc ) mwWrite("internal: NoMansLand block counter %ld, not zero\n", mwNmlNumAlloc );
- if( mwNmlCurAlloc ) mwWrite("internal: NoMansLand byte counter %ld, not zero\n", mwNmlCurAlloc );
-
- /* report statistics */
- mwStatReport();
- FLUSH();
-
- mwInited = 0;
- mwHead = mwTail = NULL;
- if( mwErrors )
- fprintf(mwSTDERR,"MEMWATCH detected %ld anomalies\n",mwErrors);
- mwLogFile( NULL );
- mwErrors = 0;
-
- MW_MUTEX_TERM();
-
- }
-
-void mwTerm( void ) {
- if( mwInited == 1 )
- {
- mwAbort();
- return;
- }
- if( !mwInited )
- mwWrite("internal: mwTerm(): MEMWATCH has not been started!\n");
- else
- mwInited --;
- }
-
-void mwStatistics( int level )
-{
- mwAutoInit();
- if( level<0 ) level=0;
- if( mwStatLevel != level )
- {
- mwWrite( "statistics: now collecting on a %s basis\n",
- level<1?"global":(level<2?"module":"line") );
- mwStatLevel = level;
- }
-}
-
-void mwAutoCheck( int onoff ) {
- mwAutoInit();
- mwTestAlways = onoff;
- if( onoff ) mwTestFlags = MW_TEST_ALL;
- }
-
-void mwSetOutFunc( void (*func)(int) ) {
- mwAutoInit();
- mwOutFunction = func;
- }
-
-static void mwWriteOF( void *p )
-{
- int i;
- unsigned char *ptr;
- ptr = (unsigned char*) p;
- for( i=0; i<mwOverflowZoneSize; i++ )
- {
- *(ptr+i) = mwOverflowZoneTemplate[i%8];
- }
- return;
-}
-
-static int mwCheckOF( const void *p )
-{
- int i;
- const unsigned char *ptr;
- ptr = (const unsigned char *) p;
- for( i=0; i<mwOverflowZoneSize; i++ )
- {
- if( *(ptr+i) != mwOverflowZoneTemplate[i%8] )
- return 1; /* errors found */
- }
- return 0; /* no errors */
-}
-
-int mwTest( const char *file, int line, int items ) {
- mwAutoInit();
- mwTestFlags = items;
- return mwTestNow( file, line, 0 );
- }
-
-/*
-** Returns zero if there are no errors.
-** Returns nonzero if there are errors.
-*/
-int mwTestBuffer( const char *file, int line, void *p ) {
- mwData* mw;
-
- mwAutoInit();
-
- /* do the quick ownership test */
- mw = (mwData*) mwBUFFER_TO_MW( p );
-
- if( mwIsOwned( mw, file, line ) ) {
- return mwTestBuf( mw, file, line );
- }
- return 1;
- }
-
-void mwBreakOut( const char* cause ) {
- fprintf(mwSTDERR, "breakout: %s\n", cause);
- mwWrite("breakout: %s\n", cause );
- return;
- }
-
-/*
-** 981217 JLI: is it possible that ->next is not always set?
-*/
-void * mwMark( void *p, const char *desc, const char *file, unsigned line ) {
- mwMarker *mrk;
- unsigned n, isnew;
- char *buf;
- int tot, oflow = 0;
- char wherebuf[128];
-
- mwAutoInit();
- TESTS(NULL,0);
-
- if( desc == NULL ) desc = "unknown";
- if( file == NULL ) file = "unknown";
-
- tot = sprintf( wherebuf, "%.48s called from %s(%d)", desc, file, line );
- if( tot >= (int)sizeof(wherebuf) ) { wherebuf[sizeof(wherebuf)-1] = 0; oflow = 1; }
-
- if( p == NULL ) {
- mwWrite("mark: %s(%d), no mark for NULL:'%s' may be set\n", file, line, desc );
- return p;
- }
-
- if( mwFirstMark != NULL && !mwIsReadAddr( mwFirstMark, sizeof( mwMarker ) ) )
- {
- mwWrite("mark: %s(%d), mwFirstMark (%p) is trashed, can't mark for %s\n",
- file, line, mwFirstMark, desc );
- return p;
- }
-
- for( mrk=mwFirstMark; mrk; mrk=mrk->next )
- {
- if( mrk->next != NULL && !mwIsReadAddr( mrk->next, sizeof( mwMarker ) ) )
- {
- mwWrite("mark: %s(%d), mark(%p)->next(%p) is trashed, can't mark for %s\n",
- file, line, mrk, mrk->next, desc );
- return p;
- }
- if( mrk->host == p ) break;
- }
-
- if( mrk == NULL ) {
- isnew = 1;
- mrk = (mwMarker*) malloc( sizeof( mwMarker ) );
- if( mrk == NULL ) {
- mwWrite("mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc );
- return p;
- }
- mrk->next = NULL;
- n = 0;
- }
- else {
- isnew = 0;
- n = strlen( mrk->text );
- }
-
- n += strlen( wherebuf );
- buf = (char*) malloc( n+3 );
- if( buf == NULL ) {
- if( isnew ) free( mrk );
- mwWrite("mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc );
- return p;
- }
-
- if( isnew ) {
- memcpy( buf, wherebuf, n+1 );
- mrk->next = mwFirstMark;
- mrk->host = p;
- mrk->text = buf;
- mrk->level = 1;
- mwFirstMark = mrk;
- }
- else {
- strcpy( buf, mrk->text );
- strcat( buf, ", " );
- strcat( buf, wherebuf );
- free( mrk->text );
- mrk->text = buf;
- mrk->level ++;
- }
-
- if( oflow ) {
- mwIncErr();
- mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" );
- }
- return p;
- }
-
-void* mwUnmark( void *p, const char *file, unsigned line ) {
- mwMarker *mrk, *prv;
- mrk = mwFirstMark;
- prv = NULL;
- while( mrk ) {
- if( mrk->host == p ) {
- if( mrk->level < 2 ) {
- if( prv ) prv->next = mrk->next;
- else mwFirstMark = mrk->next;
- free( mrk->text );
- free( mrk );
- return p;
- }
- mrk->level --;
- return p;
- }
- prv = mrk;
- mrk = mrk->next;
- }
- mwWrite("mark: %s(%d), no mark found for %p\n", file, line, p );
- return p;
- }
-
-
-/***********************************************************************
-** Abort/Retry/Ignore handlers
-***********************************************************************/
-
-static int mwARI( const char *estr ) {
- char inbuf[81];
- int c;
- fprintf(mwSTDERR, "\n%s\nMEMWATCH: Abort, Retry or Ignore? ", estr);
- (void) fgets(inbuf,sizeof(inbuf),stdin);
- for( c=0; inbuf[c] && inbuf[c] <= ' '; c++ ) ;
- c = inbuf[c];
- if( c == 'R' || c == 'r' ) {
- mwBreakOut( estr );
- return MW_ARI_RETRY;
- }
- if( c == 'I' || c == 'i' ) return MW_ARI_IGNORE;
- return MW_ARI_ABORT;
- }
-
-/* standard ARI handler (exported) */
-int mwAriHandler( const char *estr ) {
- mwAutoInit();
- return mwARI( estr );
- }
-
-/* used to set the ARI function */
-void mwSetAriFunc( int (*func)(const char *) ) {
- mwAutoInit();
- mwAriFunction = func;
- }
-
-/***********************************************************************
-** Allocation handlers
-***********************************************************************/
-
-void* mwMalloc( size_t size, const char* file, int line) {
- size_t needed;
- mwData *mw;
- char *ptr;
- void *p;
-
- mwAutoInit();
-
- MW_MUTEX_LOCK();
-
- TESTS(file,line);
-
- mwCounter ++;
- needed = mwDataSize + mwOverflowZoneSize*2 + size;
- if( needed < size )
- {
- /* theoretical case: req size + mw overhead exceeded size_t limits */
- return NULL;
- }
-
- /* if this allocation would violate the limit, fail it */
- if( mwUseLimit && ((long)size + mwStatCurAlloc > mwAllocLimit) ) {
- mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n",
- mwCounter, file, line, (long)size, mwAllocLimit - mwStatCurAlloc );
- mwIncErr();
- FLUSH();
- MW_MUTEX_UNLOCK();
- return NULL;
- }
-
- mw = (mwData*) malloc( needed );
- if( mw == NULL ) {
- if( mwFreeUp(needed,0) >= needed ) {
- mw = (mwData*) malloc(needed);
- if( mw == NULL ) {
- mwWrite( "internal: mwFreeUp(%u) reported success, but malloc() fails\n", needed );
- mwIncErr();
- FLUSH();
- }
- }
- if( mw == NULL ) {
- mwWrite( "fail: <%ld> %s(%d), %ld wanted %ld allocated\n",
- mwCounter, file, line, (long)size, mwStatCurAlloc );
- mwIncErr();
- FLUSH();
- MW_MUTEX_UNLOCK();
- return NULL;
- }
- }
-
- mw->count = mwCounter;
- mw->prev = NULL;
- mw->next = mwHead;
- mw->file = file;
- mw->size = size;
- mw->line = line;
- mw->flag = 0;
- mw->check = CHKVAL(mw);
-
- if( mwHead ) mwHead->prev = mw;
- mwHead = mw;
- if( mwTail == NULL ) mwTail = mw;
-
- ptr = ((char*)mw) + mwDataSize;
- mwWriteOF( ptr ); /* '*(long*)ptr = PRECHK;' */
- ptr += mwOverflowZoneSize;
- p = ptr;
- memset( ptr, MW_VAL_NEW, size );
- ptr += size;
- mwWriteOF( ptr ); /* '*(long*)ptr = POSTCHK;' */
-
- mwNumCurAlloc ++;
- mwStatCurAlloc += (long) size;
- mwStatTotAlloc += (long) size;
- if( mwStatCurAlloc > mwStatMaxAlloc )
- mwStatMaxAlloc = mwStatCurAlloc;
- mwStatNumAlloc ++;
-
- if( mwStatLevel ) mwStatAlloc( size, file, line );
-
- MW_MUTEX_UNLOCK();
- return p;
- }
-
-void* mwRealloc( void *p, size_t size, const char* file, int line) {
- int oldUseLimit, i;
- mwData *mw;
- char *ptr;
-
- mwAutoInit();
-
- if( p == NULL ) return mwMalloc( size, file, line );
- if( size == 0 ) { mwFree( p, file, line ); return NULL; }
-
- MW_MUTEX_LOCK();
-
- /* do the quick ownership test */
- mw = (mwData*) mwBUFFER_TO_MW( p );
- if( mwIsOwned( mw, file, line ) ) {
-
- /* if the buffer is an NML, treat this as a double-free */
- if( mw->flag & MW_NML )
- {
- mwIncErr();
- if( *((unsigned char*)(mw)+mwDataSize+mwOverflowZoneSize) != MW_VAL_NML )
- {
- mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n",
- mwCounter, file, line, mw );
- }
- goto check_dbl_free;
- }
-
- /* if this allocation would violate the limit, fail it */
- if( mwUseLimit && ((long)size + mwStatCurAlloc - (long)mw->size > mwAllocLimit) ) {
- TESTS(file,line);
- mwCounter ++;
- mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n",
- mwCounter, file, line, (unsigned long)size - mw->size, mwAllocLimit - mwStatCurAlloc );
- mwIncErr();
- FLUSH();
- MW_MUTEX_UNLOCK();
- return NULL;
- }
-
- /* fake realloc operation */
- oldUseLimit = mwUseLimit;
- mwUseLimit = 0;
- ptr = (char*) mwMalloc( size, file, line );
- if( ptr != NULL ) {
- if( size < mw->size )
- memcpy( ptr, p, size );
- else
- memcpy( ptr, p, mw->size );
- mwFree( p, file, line );
- }
- mwUseLimit = oldUseLimit;
- MW_MUTEX_UNLOCK();
- return (void*) ptr;
- }
-
- /* Unknown pointer! */
-
- /* using free'd pointer? */
-check_dbl_free:
- for(i=0;i<MW_FREE_LIST;i++) {
- if( mwLastFree[i] == p ) {
- mwIncErr();
- mwWrite( "realloc: <%ld> %s(%d), %p was"
- " freed from %s(%d)\n",
- mwCounter, file, line, p,
- mwLFfile[i], mwLFline[i] );
- FLUSH();
- MW_MUTEX_UNLOCK();
- return NULL;
- }
- }
-
- /* some weird pointer */
- mwIncErr();
- mwWrite( "realloc: <%ld> %s(%d), unknown pointer %p\n",
- mwCounter, file, line, p );
- FLUSH();
- MW_MUTEX_UNLOCK();
- return NULL;
- }
-
-char *mwStrdup( const char* str, const char* file, int line ) {
- size_t len;
- char *newstring;
-
- MW_MUTEX_LOCK();
-
- if( str == NULL ) {
- mwIncErr();
- mwWrite( "strdup: <%ld> %s(%d), strdup(NULL) called\n",
- mwCounter, file, line );
- FLUSH();
- MW_MUTEX_UNLOCK();
- return NULL;
- }
-
- len = strlen( str ) + 1;
- newstring = (char*) mwMalloc( len, file, line );
- if( newstring != NULL ) memcpy( newstring, str, len );
- MW_MUTEX_UNLOCK();
- return newstring;
- }
-
-void mwFree( void* p, const char* file, int line ) {
- int i;
- mwData* mw;
- char buffer[ sizeof(mwData) + (mwROUNDALLOC*3) + 64 ];
-
- /* this code is in support of C++ delete */
- if( file == NULL ) {
- mwFree_( p );
- MW_MUTEX_UNLOCK();
- return;
- }
-
- mwAutoInit();
-
- MW_MUTEX_LOCK();
- TESTS(file,line);
- mwCounter ++;
-
- /* on NULL free, write a warning and return */
- if( p == NULL ) {
- mwWrite( "NULL free: <%ld> %s(%d), NULL pointer free'd\n",
- mwCounter, file, line );
- FLUSH();
- MW_MUTEX_UNLOCK();
- return;
- }
-
- /* do the quick ownership test */
- mw = (mwData*) mwBUFFER_TO_MW( p );
-
- if( mwIsOwned( mw, file, line ) ) {
- (void) mwTestBuf( mw, file, line );
-
- /* if the buffer is an NML, treat this as a double-free */
- if( mw->flag & MW_NML )
- {
- if( *(((unsigned char*)mw)+mwDataSize+mwOverflowZoneSize) != MW_VAL_NML )
- {
- mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n",
- mwCounter, file, line, mw );
- }
- goto check_dbl_free;
- }
-
- /* update the statistics */
- mwNumCurAlloc --;
- mwStatCurAlloc -= (long) mw->size;
- if( mwStatLevel ) mwStatFree( mw->size, mw->file, mw->line );
-
- /* we should either free the allocation or keep it as NML */
- if( mwNML ) {
- mw->flag |= MW_NML;
- mwNmlNumAlloc ++;
- mwNmlCurAlloc += (long) mw->size;
- memset( ((char*)mw)+mwDataSize+mwOverflowZoneSize, MW_VAL_NML, mw->size );
- }
- else {
- /* unlink the allocation, and enter the post-free data */
- mwUnlink( mw, file, line );
- memset( mw, MW_VAL_DEL,
- mw->size + mwDataSize+mwOverflowZoneSize+mwOverflowZoneSize );
- if( mwFBI ) {
- memset( mw, '.', mwDataSize + mwOverflowZoneSize );
- sprintf( buffer, "FBI<%ld>%s(%d)", mwCounter, file, line );
- strncpy( (char*)(void*)mw, buffer, mwDataSize + mwOverflowZoneSize );
- }
- free( mw );
- }
-
- /* add the pointer to the last-free track */
- mwLFfile[ mwLFcur ] = file;
- mwLFline[ mwLFcur ] = line;
- mwLastFree[ mwLFcur++ ] = p;
- if( mwLFcur == MW_FREE_LIST ) mwLFcur = 0;
-
- MW_MUTEX_UNLOCK();
- return;
- }
-
- /* check for double-freeing */
-check_dbl_free:
- for(i=0;i<MW_FREE_LIST;i++) {
- if( mwLastFree[i] == p ) {
- mwIncErr();
- mwWrite( "double-free: <%ld> %s(%d), %p was"
- " freed from %s(%d)\n",
- mwCounter, file, line, p,
- mwLFfile[i], mwLFline[i] );
- FLUSH();
- MW_MUTEX_UNLOCK();
- return;
- }
- }
-
- /* some weird pointer... block the free */
- mwIncErr();
- mwWrite( "WILD free: <%ld> %s(%d), unknown pointer %p\n",
- mwCounter, file, line, p );
- FLUSH();
- MW_MUTEX_UNLOCK();
- return;
- }
-
-void* mwCalloc( size_t a, size_t b, const char *file, int line ) {
- void *p;
- size_t size = a * b;
- p = mwMalloc( size, file, line );
- if( p == NULL ) return NULL;
- memset( p, 0, size );
- return p;
- }
-
-void mwFree_( void *p ) {
- MW_MUTEX_LOCK();
- TESTS(NULL,0);
- MW_MUTEX_UNLOCK();
- free(p);
- }
-
-void* mwMalloc_( size_t size ) {
- MW_MUTEX_LOCK();
- TESTS(NULL,0);
- MW_MUTEX_UNLOCK();
- return malloc( size );
- }
-
-void* mwRealloc_( void *p, size_t size ) {
- MW_MUTEX_LOCK();
- TESTS(NULL,0);
- MW_MUTEX_UNLOCK();
- return realloc( p, size );
- }
-
-void* mwCalloc_( size_t a, size_t b ) {
- MW_MUTEX_LOCK();
- TESTS(NULL,0);
- MW_MUTEX_UNLOCK();
- return calloc( a, b );
- }
-
-void mwFlushNow( void ) {
- if( mwLogR() ) fflush( mwLogR() );
- return;
- }
-
-void mwDoFlush( int onoff ) {
- mwFlushW( onoff<1?0:onoff );
- if( onoff ) if( mwLogR() ) fflush( mwLogR() );
- return;
- }
-
-void mwLimit( long lim ) {
- TESTS(NULL,0);
- mwWrite("limit: old limit = ");
- if( !mwAllocLimit ) mwWrite( "none" );
- else mwWrite( "%ld bytes", mwAllocLimit );
- mwWrite( ", new limit = ");
- if( !lim ) {
- mwWrite( "none\n" );
- mwUseLimit = 0;
- }
- else {
- mwWrite( "%ld bytes\n", lim );
- mwUseLimit = 1;
- }
- mwAllocLimit = lim;
- FLUSH();
- }
-
-void mwSetAriAction( int action ) {
- MW_MUTEX_LOCK();
- TESTS(NULL,0);
- mwAriAction = action;
- MW_MUTEX_UNLOCK();
- return;
- }
-
-int mwAssert( int exp, const char *exps, const char *fn, int ln ) {
- int i;
- char buffer[MW_TRACE_BUFFER+8];
- if( exp ) {
- return 0;
- }
- mwAutoInit();
- MW_MUTEX_LOCK();
- TESTS(fn,ln);
- mwIncErr();
- mwCounter++;
- mwWrite( "assert trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps );
- if( mwAriFunction != NULL ) {
- sprintf( buffer, "MEMWATCH: assert trap: %s(%d), %s", fn, ln, exps );
- i = (*mwAriFunction)(buffer);
- switch( i ) {
- case MW_ARI_IGNORE:
- mwWrite( "assert trap: <%ld> IGNORED - execution continues\n", mwCounter );
- MW_MUTEX_UNLOCK();
- return 0;
- case MW_ARI_RETRY:
- mwWrite( "assert trap: <%ld> RETRY - executing again\n", mwCounter );
- MW_MUTEX_UNLOCK();
- return 1;
- }
- }
- else {
- if( mwAriAction & MW_ARI_IGNORE ) {
- mwWrite( "assert trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter );
- MW_MUTEX_UNLOCK();
- return 0;
- }
- fprintf(mwSTDERR,"\nMEMWATCH: assert trap: %s(%d), %s\n", fn, ln, exps );
- }
-
- FLUSH();
- (void) mwTestNow( fn, ln, 1 );
- FLUSH();
-
- if( mwAriAction & MW_ARI_NULLREAD ) {
- /* This is made in an attempt to kick in */
- /* any debuggers or OS stack traces */
- FLUSH();
- /*lint -save -e413 */
- i = *((int*)NULL);
- mwDummy( (char)i );
- /*lint -restore */
- }
-
- MW_MUTEX_UNLOCK();
- exit(255);
- /* NOT REACHED - the return statement is in to keep */
- /* stupid compilers from squeaking about differing return modes. */
- /* Smart compilers instead say 'code unreachable...' */
- /*lint -save -e527 */
- return 0;
- /*lint -restore */
- }
-
-int mwVerify( int exp, const char *exps, const char *fn, int ln ) {
- int i;
- char buffer[MW_TRACE_BUFFER+8];
- if( exp ) {
- return 0;
- }
- mwAutoInit();
- MW_MUTEX_LOCK();
- TESTS(fn,ln);
- mwIncErr();
- mwCounter++;
- mwWrite( "verify trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps );
- if( mwAriFunction != NULL ) {
- sprintf( buffer, "MEMWATCH: verify trap: %s(%d), %s", fn, ln, exps );
- i = (*mwAriFunction)(buffer);
- if( i == 0 ) {
- mwWrite( "verify trap: <%ld> IGNORED - execution continues\n", mwCounter );
- MW_MUTEX_UNLOCK();
- return 0;
- }
- if( i == 1 ) {
- mwWrite( "verify trap: <%ld> RETRY - executing again\n", mwCounter );
- MW_MUTEX_UNLOCK();
- return 1;
- }
- }
- else {
- if( mwAriAction & MW_ARI_NULLREAD ) {
- /* This is made in an attempt to kick in */
- /* any debuggers or OS stack traces */
- FLUSH();
- /*lint -save -e413 */
- i = *((int*)NULL);
- mwDummy( (char)i );
- /*lint -restore */
- }
- if( mwAriAction & MW_ARI_IGNORE ) {
- mwWrite( "verify trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter );
- MW_MUTEX_UNLOCK();
- return 0;
- }
- fprintf(mwSTDERR,"\nMEMWATCH: verify trap: %s(%d), %s\n", fn, ln, exps );
- }
- FLUSH();
- (void) mwTestNow( fn, ln, 1 );
- FLUSH();
- MW_MUTEX_UNLOCK();
- exit(255);
- /* NOT REACHED - the return statement is in to keep */
- /* stupid compilers from squeaking about differing return modes. */
- /* Smart compilers instead say 'code unreachable...' */
- /*lint -save -e527 */
- return 0;
- /*lint -restore */
- }
-
-void mwTrace( const char *format, ... ) {
- int tot, oflow = 0;
- va_list mark;
-
- mwAutoInit();
- MW_MUTEX_LOCK();
- TESTS(NULL,0);
- if( mwOutFunction == NULL ) mwOutFunction = mwDefaultOutFunc;
-
- va_start( mark, format );
- tot = vsprintf( mwPrintBuf, format, mark );
- va_end( mark );
- if( tot >= MW_TRACE_BUFFER ) { mwPrintBuf[MW_TRACE_BUFFER] = 0; oflow = 1; }
- for(tot=0;mwPrintBuf[tot];tot++)
- (*mwOutFunction)( mwPrintBuf[tot] );
- if( oflow ) {
- mwIncErr();
- mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" );
- }
-
- FLUSH();
- MW_MUTEX_UNLOCK();
- }
-
-
-/***********************************************************************
-** Grab & Drop
-***********************************************************************/
-
-unsigned mwGrab( unsigned kb ) {
- TESTS(NULL,0);
- return mwGrab_( kb, MW_VAL_GRB, 0 );
- }
-
-unsigned mwDrop( unsigned kb ) {
- TESTS(NULL,0);
- return mwDrop_( kb, MW_VAL_GRB, 0 );
- }
-
-static void mwDropAll() {
- TESTS(NULL,0);
- (void) mwDrop_( 0, MW_VAL_GRB, 0 );
- (void) mwDrop_( 0, MW_VAL_NML, 0 );
- if( mwGrabList != NULL )
- mwWrite( "internal: the grab list is not empty after mwDropAll()\n");
- }
-
-static const char *mwGrabType( int type ) {
- switch( type ) {
- case MW_VAL_GRB:
- return "grabbed";
- case MW_VAL_NML:
- return "no-mans-land";
- default:
- /* do nothing */
- ;
- }
- return "<unknown type>";
- }
-
-static unsigned mwGrab_( unsigned kb, int type, int silent ) {
- unsigned i = kb;
- mwGrabData *gd;
- if( !kb ) i = kb = 65000U;
-
- for(;kb;kb--) {
- if( mwUseLimit &&
- (mwStatCurAlloc + mwGrabSize + (long)sizeof(mwGrabData) > mwAllocLimit) ) {
- if( !silent ) {
- mwWrite("grabbed: all allowed memory to %s (%u kb)\n",
- mwGrabType(type), i-kb);
- FLUSH();
- }
- return i-kb;
- }
- gd = (mwGrabData*) malloc( sizeof(mwGrabData) );
- if( gd == NULL ) {
- if( !silent ) {
- mwWrite("grabbed: all available memory to %s (%u kb)\n",
- mwGrabType(type), i-kb);
- FLUSH();
- }
- return i-kb;
- }
- mwGrabSize += (long) sizeof(mwGrabData);
- gd->next = mwGrabList;
- memset( gd->blob, type, sizeof(gd->blob) );
- gd->type = type;
- mwGrabList = gd;
- }
- if( !silent ) {
- mwWrite("grabbed: %u kilobytes of %s memory\n", i, mwGrabType(type) );
- FLUSH();
- }
- return i;
- }
-
-static unsigned mwDrop_( unsigned kb, int type, int silent ) {
- unsigned i = kb;
- mwGrabData *gd,*tmp,*pr;
- const void *p;
-
- if( mwGrabList == NULL && kb == 0 ) return 0;
- if( !kb ) i = kb = 60000U;
-
- pr = NULL;
- gd = mwGrabList;
- for(;kb;) {
- if( gd == NULL ) {
- if( i-kb > 0 && !silent ) {
- mwWrite("dropped: all %s memory (%u kb)\n", mwGrabType(type), i-kb);
- FLUSH();
- }
- return i-kb;
- }
- if( gd->type == type ) {
- if( pr ) pr->next = gd->next;
- kb --;
- tmp = gd;
- if( mwGrabList == gd ) mwGrabList = gd->next;
- gd = gd->next;
- p = mwTestMem( tmp->blob, sizeof( tmp->blob ), type );
- if( p != NULL ) {
- mwWrite( "wild pointer: <%ld> %s memory hit at %p\n",
- mwCounter, mwGrabType(type), p );
- FLUSH();
- }
- mwGrabSize -= (long) sizeof(mwGrabData);
- free( tmp );
- }
- else {
- pr = gd;
- gd = gd->next;
- }
- }
- if( !silent ) {
- mwWrite("dropped: %u kilobytes of %s memory\n", i, mwGrabType(type) );
- FLUSH();
- }
- return i;
- }
-
-/***********************************************************************
-** No-Mans-Land
-***********************************************************************/
-
-void mwNoMansLand( int level ) {
- mwAutoInit();
- TESTS(NULL,0);
- switch( level ) {
- case MW_NML_NONE:
- (void) mwDrop_( 0, MW_VAL_NML, 0 );
- break;
- case MW_NML_FREE:
- break;
- case MW_NML_ALL:
- (void) mwGrab_( 0, MW_VAL_NML, 0 );
- break;
- default:
- return;
- }
- mwNML = level;
- }
-
-/***********************************************************************
-** Static functions
-***********************************************************************/
-
-static void mwAutoInit( void )
-{
- if( mwInited ) return;
- mwUseAtexit = 1;
- mwInit();
- return;
-}
-
-static FILE *mwLogR() {
- if( (mwLog == mwLogB1) && (mwLog == mwLogB2) ) return mwLog;
- if( mwLog == mwLogB1 ) mwLogB2 = mwLog;
- if( mwLog == mwLogB2 ) mwLogB1 = mwLog;
- if( mwLogB1 == mwLogB2 ) mwLog = mwLogB1;
- if( (mwLog == mwLogB1) && (mwLog == mwLogB2) ) {
- mwWrite("internal: log file handle damaged and recovered\n");
- FLUSH();
- return mwLog;
- }
- fprintf(mwSTDERR,"\nMEMWATCH: log file handle destroyed, using mwSTDERR\n" );
- mwLog = mwLogB1 = mwLogB2 = mwSTDERR;
- return mwSTDERR;
- }
-
-static void mwLogW( FILE *p ) {
- mwLog = mwLogB1 = mwLogB2 = p;
- }
-
-static int mwFlushR() {
- if( (mwFlushing == mwFlushingB1) && (mwFlushing == mwFlushingB2) ) return mwFlushing;
- if( mwFlushing == mwFlushingB1 ) mwFlushingB2 = mwFlushing;
- if( mwFlushing == mwFlushingB2 ) mwFlushingB1 = mwFlushing;
- if( mwFlushingB1 == mwFlushingB2 ) mwFlushing = mwFlushingB1;
- if( (mwFlushing == mwFlushingB1) && (mwFlushing == mwFlushingB2) ) {
- mwWrite("internal: flushing flag damaged and recovered\n");
- FLUSH();
- return mwFlushing;
- }
- mwWrite("internal: flushing flag destroyed, so set to true\n");
- mwFlushing = mwFlushingB1 = mwFlushingB2 = 1;
- return 1;
- }
-
-static void mwFlushW( int n ) {
- mwFlushing = mwFlushingB1 = mwFlushingB2 = n;
- }
-
-static void mwIncErr() {
- mwErrors++;
- mwFlushW( mwFlushR()+1 );
- FLUSH();
- }
-
-static void mwFlush() {
- if( mwLogR() == NULL ) return;
-#ifdef MW_FLUSH
- fflush( mwLogR() );
-#else
- if( mwFlushR() ) fflush( mwLogR() );
-#endif
- return;
- }
-
-static void mwUnlink( mwData* mw, const char* file, int line ) {
- if( mw->prev == NULL ) {
- if( mwHead != mw )
- mwWrite( "internal: <%ld> %s(%d), MW-%p: link1 NULL, but not head\n",
- mwCounter, file, line, mw );
- mwHead = mw->next;
- }
- else {
- if( mw->prev->next != mw )
- mwWrite( "internal: <%ld> %s(%d), MW-%p: link1 failure\n",
- mwCounter, file, line, mw );
- else mw->prev->next = mw->next;
- }
- if( mw->next == NULL ) {
- if( mwTail != mw )
- mwWrite( "internal: <%ld> %s(%d), MW-%p: link2 NULL, but not tail\n",
- mwCounter, file, line, mw );
- mwTail = mw->prev;
- }
- else {
- if( mw->next->prev != mw )
- mwWrite( "internal: <%ld> %s(%d), MW-%p: link2 failure\n",
- mwCounter, file, line, mw );
- else mw->next->prev = mw->prev;
- }
- }
-
-/*
-** Relinking tries to repair a damaged mw block.
-** Returns nonzero if it thinks it successfully
-** repaired the heap chain.
-*/
-static int mwRelink( mwData* mw, const char* file, int line ) {
- int fails;
- mwData *mw1, *mw2;
- long count, size;
- mwStat *ms;
-
- if( file == NULL ) file = "unknown";
-
- if( mw == NULL ) {
- mwWrite("relink: cannot repair MW at NULL\n");
- FLUSH();
- goto emergency;
- }
-
- if( !mwIsSafeAddr(mw, mwDataSize) ) {
- mwWrite("relink: MW-%p is a garbage pointer\n", mw);
- FLUSH();
- goto emergency;
- }
-
- mwWrite("relink: <%ld> %s(%d) attempting to repair MW-%p...\n", mwCounter, file, line, mw );
- FLUSH();
- fails = 0;
-
- /* Repair from head */
- if( mwHead != mw ) {
- if( !mwIsSafeAddr( mwHead, mwDataSize ) ) {
- mwWrite("relink: failed for MW-%p; head pointer destroyed\n", mw );
- FLUSH();
- goto emergency;
- }
- for( mw1=mwHead; mw1; mw1=mw1->next ) {
- if( mw1->next == mw ) {
- mw->prev = mw1;
- break;
- }
- if( mw1->next &&
- ( !mwIsSafeAddr(mw1->next, mwDataSize ) || mw1->next->prev != mw1) ) {
- mwWrite("relink: failed for MW-%p; forward chain fragmented at MW-%p: 'next' is %p\n", mw, mw1, mw1->next );
- FLUSH();
- goto emergency;
- }
- }
- if( mw1 == NULL ) {
- mwWrite("relink: MW-%p not found in forward chain search\n", mw );
- FLUSH();
- fails ++;
- }
- }
- else
- {
- mwWrite( "relink: MW-%p is the head (first) allocation\n", mw );
- if( mw->prev != NULL )
- {
- mwWrite( "relink: MW-%p prev pointer is non-NULL, you have a wild pointer\n", mw );
- mw->prev = NULL;
- }
- }
-
- /* Repair from tail */
- if( mwTail != mw ) {
- if( !mwIsSafeAddr( mwTail, mwDataSize ) ) {
- mwWrite("relink: failed for MW-%p; tail pointer destroyed\n", mw );
- FLUSH();
- goto emergency;
- }
- for( mw1=mwTail; mw1; mw1=mw1->prev ) {
- if( mw1->prev == mw ) {
- mw->next = mw1;
- break;
- }
- if( mw1->prev && (!mwIsSafeAddr(mw1->prev, mwDataSize ) || mw1->prev->next != mw1) ) {
- mwWrite("relink: failed for MW-%p; reverse chain fragmented at MW-%p, 'prev' is %p\n", mw, mw1, mw1->prev );
- FLUSH();
- goto emergency;
- }
- }
- if( mw1 == NULL ) {
- mwWrite("relink: MW-%p not found in reverse chain search\n", mw );
- FLUSH();
- fails ++;
- }
- }
- else
- {
- mwWrite( "relink: MW-%p is the tail (last) allocation\n", mw );
- if( mw->next != NULL )
- {
- mwWrite( "relink: MW-%p next pointer is non-NULL, you have a wild pointer\n", mw );
- mw->next = NULL;
- }
- }
-
- if( fails > 1 ) {
- mwWrite("relink: heap appears intact, MW-%p probably garbage pointer\n", mw );
- FLUSH();
- goto verifyok;
- }
-
- /* restore MW info where possible */
- if( mwIsReadAddr( mw->file, 1 ) ) {
- ms = mwStatGet( mw->file, -1, 0 );
- if( ms == NULL ) mw->file = "<relinked>";
- }
- mw->check = CHKVAL(mw);
- goto verifyok;
-
- /* Emergency repair */
- emergency:
-
- if( mwHead == NULL && mwTail == NULL )
- {
- if( mwStatCurAlloc == 0 )
- mwWrite("relink: <%ld> %s(%d) heap is empty, nothing to repair\n", mwCounter, file, line );
- else
- mwWrite("relink: <%ld> %s(%d) heap damaged beyond repair\n", mwCounter, file, line );
- FLUSH();
- return 0;
- }
-
- mwWrite("relink: <%ld> %s(%d) attempting emergency repairs...\n", mwCounter, file, line );
- FLUSH();
-
- if( mwHead == NULL || mwTail == NULL )
- {
- if( mwHead == NULL ) mwWrite("relink: mwHead is NULL, but mwTail is %p\n", mwTail );
- else mwWrite("relink: mwTail is NULL, but mwHead is %p\n", mwHead );
- }
-
- mw1=NULL;
- if( mwHead != NULL )
- {
- if( !mwIsReadAddr( mwHead, mwDataSize ) || mwHead->check != CHKVAL(mwHead) )
- {
- mwWrite("relink: mwHead (MW-%p) is damaged, skipping forward scan\n", mwHead );
- mwHead = NULL;
- goto scan_reverse;
- }
- if( mwHead->prev != NULL )
- {
- mwWrite("relink: the mwHead pointer's 'prev' member is %p, not NULL\n", mwHead->prev );
- }
- for( mw1=mwHead; mw1; mw1=mw1->next )
- {
- if( mw1->next )
- {
- if( !mwIsReadAddr(mw1->next,mwDataSize) ||
- !mw1->next->check != CHKVAL(mw1) ||
- mw1->next->prev != mw1 )
- {
- mwWrite("relink: forward chain's last intact MW is MW-%p, %ld %sbytes at %s(%d)\n",
- mw1, mw1->size, (mw->flag & MW_NML)?"NoMansLand ":"", mw1->file, mw1->line );
- if( mwIsReadAddr(mw1->next,mwDataSize ) )
- {
- mwWrite("relink: forward chain's first damaged MW is MW-%p, %ld %sbytes at %s(%d)\n",
- mw1->next, mw1->size, (mw->flag & MW_NML)?"NoMansLand ":"",
- mwIsReadAddr(mw1->file,16)?mw1->file:"<garbage-pointer>", mw1->line );
- }
- else
- {
- mwWrite("relink: the 'next' pointer of this MW points to %p, which is out-of-legal-access\n",
- mw1->next );
- }
- break;
- }
- }
- }
- }
-
-
-scan_reverse:
- mw2=NULL;
- if( mwTail != NULL )
- {
- if( !mwIsReadAddr(mwTail,mwDataSize) || mwTail->check != CHKVAL(mwTail) )
- {
- mwWrite("relink: mwTail (%p) is damaged, skipping reverse scan\n", mwTail );
- mwTail = NULL;
- goto analyze;
- }
- if( mwTail->next != NULL )
- {
- mwWrite("relink: the mwTail pointer's 'next' member is %p, not NULL\n", mwTail->next );
- }
- for( mw2=mwTail; mw2; mw2=mw2->prev )
- {
- if( mw2->prev )
- {
- if( !mwIsReadAddr(mw2->prev,mwDataSize) ||
- !mw2->prev->check != CHKVAL(mw2) ||
- mw2->prev->next != mw2 )
- {
- mwWrite("relink: reverse chain's last intact MW is MW-%p, %ld %sbytes at %s(%d)\n",
- mw2, mw2->size, (mw->flag & MW_NML)?"NoMansLand ":"", mw2->file, mw2->line );
- if( mwIsReadAddr(mw2->prev,mwDataSize ) )
- {
- mwWrite("relink: reverse chain's first damaged MW is MW-%p, %ld %sbytes at %s(%d)\n",
- mw2->prev, mw2->size, (mw->flag & MW_NML)?"NoMansLand ":"",
- mwIsReadAddr(mw2->file,16)?mw2->file:"<garbage-pointer>", mw2->line );
- }
- else
- {
- mwWrite("relink: the 'prev' pointer of this MW points to %p, which is out-of-legal-access\n",
- mw2->prev );
- }
- break;
- }
- }
- }
- }
-
-analyze:
- if( mwHead == NULL && mwTail == NULL )
- {
- mwWrite("relink: both head and tail pointers damaged, aborting program\n");
- mwFlushW(1);
- FLUSH();
- abort();
- }
- if( mwHead == NULL )
- {
- mwHead = mw2;
- mwWrite("relink: heap truncated, MW-%p designated as new mwHead\n", mw2 );
- mw2->prev = NULL;
- mw1 = mw2 = NULL;
- }
- if( mwTail == NULL )
- {
- mwTail = mw1;
- mwWrite("relink: heap truncated, MW-%p designated as new mwTail\n", mw1 );
- mw1->next = NULL;
- mw1 = mw2 = NULL;
- }
- if( mw1 == NULL && mw2 == NULL &&
- mwHead->prev == NULL && mwTail->next == NULL ) {
- mwWrite("relink: verifying heap integrity...\n" );
- FLUSH();
- goto verifyok;
- }
- if( mw1 && mw2 && mw1 != mw2 ) {
- mw1->next = mw2;
- mw2->prev = mw1;
- mwWrite("relink: emergency repairs successful, assessing damage...\n");
- FLUSH();
- }
- else {
- mwWrite("relink: heap totally destroyed, aborting program\n");
- mwFlushW(1);
- FLUSH();
- abort();
- }
-
- /* Verify by checking that the number of active allocations */
- /* match the number of entries in the chain */
-verifyok:
- if( !mwIsHeapOK( NULL ) ) {
- mwWrite("relink: heap verification FAILS - aborting program\n");
- mwFlushW(1);
- FLUSH();
- abort();
- }
- for( size=count=0, mw1=mwHead; mw1; mw1=mw1->next ) {
- count ++;
- size += (long) mw1->size;
- }
- if( count == mwNumCurAlloc ) {
- mwWrite("relink: successful, ");
- if( size == mwStatCurAlloc ) {
- mwWrite("no allocations lost\n");
- }
- else {
- if( mw != NULL ) {
- mwWrite("size information lost for MW-%p\n", mw);
- mw->size = 0;
- }
- }
- }
- else {
- mwWrite("relink: partial, %ld MW-blocks of %ld bytes lost\n",
- mwNmlNumAlloc+mwNumCurAlloc-count, mwNmlCurAlloc+mwStatCurAlloc-size );
- return 0;
- }
-
- return 1;
- }
-
-/*
-** If mwData* is NULL:
-** Returns 0 if heap chain is broken.
-** Returns 1 if heap chain is intact.
-** If mwData* is not NULL:
-** Returns 0 if mwData* is missing or if chain is broken.
-** Returns 1 if chain is intact and mwData* is found.
-*/
-static int mwIsHeapOK( mwData *includes_mw ) {
- int found = 0;
- mwData *mw;
-
- for( mw = mwHead; mw; mw=mw->next ) {
- if( includes_mw == mw ) found++;
- if( !mwIsSafeAddr( mw, mwDataSize ) ) return 0;
- if( mw->prev ) {
- if( !mwIsSafeAddr( mw->prev, mwDataSize ) ) return 0;
- if( mw==mwHead || mw->prev->next != mw ) return 0;
- }
- if( mw->next ) {
- if( !mwIsSafeAddr( mw->next, mwDataSize ) ) return 0;
- if( mw==mwTail || mw->next->prev != mw ) return 0;
- }
- else if( mw!=mwTail ) return 0;
- }
-
- if( includes_mw != NULL && !found ) return 0;
-
- return 1;
- }
-
-static int mwIsOwned( mwData* mw, const char *file, int line ) {
- int retv;
- mwStat *ms;
-
- /* see if the address is legal according to OS */
- if( !mwIsSafeAddr( mw, mwDataSize ) ) return 0;
-
- /* make sure we have _anything_ allocated */
- if( mwHead == NULL && mwTail == NULL && mwStatCurAlloc == 0 )
- return 0;
-
- /* calculate checksum */
- if( mw->check != CHKVAL(mw) ) {
- /* may be damaged checksum, see if block is in heap */
- if( mwIsHeapOK( mw ) ) {
- /* damaged checksum, repair it */
- mwWrite( "internal: <%ld> %s(%d), checksum for MW-%p is incorrect\n",
- mwCounter, file, line, mw );
- mwIncErr();
- if( mwIsReadAddr( mw->file, 1 ) ) {
- ms = mwStatGet( mw->file, -1, 0 );
- if( ms == NULL ) mw->file = "<relinked>";
- }
- else mw->file = "<unknown>";
- mw->size = 0;
- mw->check = CHKVAL(mw);
- return 1;
- }
- /* no, it's just some garbage data */
- return 0;
- }
-
- /* check that the non-NULL pointers are safe */
- if( mw->prev && !mwIsSafeAddr( mw->prev, mwDataSize ) ) mwRelink( mw, file, line );
- if( mw->next && !mwIsSafeAddr( mw->next, mwDataSize ) ) mwRelink( mw, file, line );
-
- /* safe address, checksum OK, proceed with heap checks */
-
- /* see if the block is in the heap */
- retv = 0;
- if( mw->prev ) { if( mw->prev->next == mw ) retv ++; }
- else { if( mwHead == mw ) retv++; }
- if( mw->next ) { if( mw->next->prev == mw ) retv ++; }
- else { if( mwTail == mw ) retv++; }
- if( mw->check == CHKVAL(mw) ) retv ++;
- if( retv > 2 ) return 1;
-
- /* block not in heap, check heap for corruption */
-
- if( !mwIsHeapOK( mw ) ) {
- if( mwRelink( mw, file, line ) )
- return 1;
- }
-
- /* unable to repair */
- mwWrite( "internal: <%ld> %s(%d), mwIsOwned fails for MW-%p\n",
- mwCounter, file, line, mw );
- mwIncErr();
-
- return 0;
- }
-
-/*
-** mwTestBuf:
-** Checks a buffers links and pre/postfixes.
-** Writes errors found to the log.
-** Returns zero if no errors found.
-*/
-static int mwTestBuf( mwData* mw, const char* file, int line ) {
- int retv = 0;
- char *p;
-
- if( file == NULL ) file = "unknown";
-
- if( !mwIsSafeAddr( mw, mwDataSize + mwOverflowZoneSize ) ) {
- mwWrite( "internal: <%ld> %s(%d): pointer MW-%p is invalid\n",
- mwCounter, file, line, mw );
- mwIncErr();
- return 2;
- }
-
- if( mw->check != CHKVAL(mw) ) {
- mwWrite( "internal: <%ld> %s(%d), info trashed; relinking\n",
- mwCounter, file, line );
- mwIncErr();
- if( !mwRelink( mw, file, line ) ) return 2;
- }
-
- if( mw->prev && mw->prev->next != mw ) {
- mwWrite( "internal: <%ld> %s(%d), buffer <%ld> %s(%d) link1 broken\n",
- mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line );
- mwIncErr();
- if( !mwRelink( mw, file, line ) ) retv = 2;
- }
- if( mw->next && mw->next->prev != mw ) {
- mwWrite( "internal: <%ld> %s(%d), buffer <%ld> %s(%d) link2 broken\n",
- mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line );
- mwIncErr();
- if( !mwRelink( mw, file, line ) ) retv = 2;
- }
-
- p = ((char*)mw) + mwDataSize;
- if( mwCheckOF( p ) ) {
- mwWrite( "underflow: <%ld> %s(%d), %ld bytes alloc'd at <%ld> %s(%d)\n",
- mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line );
- mwIncErr();
- retv = 1;
- }
- p += mwOverflowZoneSize + mw->size;
- if( mwIsReadAddr( p, mwOverflowZoneSize ) && mwCheckOF( p ) ) {
- mwWrite( "overflow: <%ld> %s(%d), %ld bytes alloc'd at <%ld> %s(%d)\n",
- mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line );
- mwIncErr();
- retv = 1;
- }
-
- return retv;
- }
-
-static void mwDefaultOutFunc( int c ) {
- if( mwLogR() ) fputc( c, mwLogR() );
- }
-
-static void mwWrite( const char *format, ... ) {
- int tot, oflow = 0;
- va_list mark;
- mwAutoInit();
- if( mwOutFunction == NULL ) mwOutFunction = mwDefaultOutFunc;
- va_start( mark, format );
- tot = vsprintf( mwPrintBuf, format, mark );
- va_end( mark );
- if( tot >= MW_TRACE_BUFFER ) { mwPrintBuf[MW_TRACE_BUFFER] = 0; oflow = 1; }
- for(tot=0;mwPrintBuf[tot];tot++)
- (*mwOutFunction)( mwPrintBuf[tot] );
- if( oflow ) {
- mwWrite( "\ninternal: mwWrite(): WARNING! OUTPUT EXCEEDED %u CHARS: SYSTEM UNSTABLE\n", MW_TRACE_BUFFER-1 );
- FLUSH();
- }
- return;
- }
-
-static void mwLogFile( const char *name ) {
- time_t tid;
- (void) time( &tid );
- if( mwLogR() != NULL ) {
- fclose( mwLogR() );
- mwLogW( NULL );
- }
- if( name == NULL ) return;
- mwLogW( fopen( name, "a" COMMIT ) );
- if( mwLogR() == NULL )
- mwWrite( "logfile: failed to open/create file '%s'\n", name );
- }
-
-/*
-** Try to free NML memory until a contiguous allocation of
-** 'needed' bytes can be satisfied. If this is not enough
-** and the 'urgent' parameter is nonzero, grabbed memory is
-** also freed.
-*/
-static size_t mwFreeUp( size_t needed, int urgent ) {
- void *p;
- mwData *mw, *mw2;
- char *data;
-
- /* free grabbed NML memory */
- for(;;) {
- if( mwDrop_( 1, MW_VAL_NML, 1 ) == 0 ) break;
- p = malloc( needed );
- if( p == NULL ) continue;
- free( p );
- return needed;
- }
-
- /* free normal NML memory */
- mw = mwHead;
- while( mw != NULL ) {
- if( !(mw->flag & MW_NML) ) mw = mw->next;
- else {
- data = ((char*)mw)+mwDataSize+mwOverflowZoneSize;
- if( mwTestMem( data, mw->size, MW_VAL_NML ) ) {
- mwIncErr();
- mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n",
- mw->count, data + mwOverflowZoneSize, mw->file, mw->line );
- }
- mw2 = mw->next;
- mwUnlink( mw, "mwFreeUp", 0 );
- free( mw );
- mw = mw2;
- p = malloc( needed );
- if( p == NULL ) continue;
- free( p );
- return needed;
- }
- }
-
- /* if not urgent (for internal purposes), fail */
- if( !urgent ) return 0;
-
- /* free grabbed memory */
- for(;;) {
- if( mwDrop_( 1, MW_VAL_GRB, 1 ) == 0 ) break;
- p = malloc( needed );
- if( p == NULL ) continue;
- free( p );
- return needed;
- }
-
- return 0;
- }
-
-static const void * mwTestMem( const void *p, unsigned len, int c ) {
- const unsigned char *ptr;
- ptr = (const unsigned char *) p;
- while( len-- ) {
- if( *ptr != (unsigned char)c ) return (const void*)ptr;
- ptr ++;
- }
- return NULL;
- }
-
-static int mwStrCmpI( const char *s1, const char *s2 ) {
- if( s1 == NULL || s2 == NULL ) return 0;
- while( *s1 ) {
- if( toupper(*s2) == toupper(*s1) ) { s1++; s2++; continue; }
- return 1;
- }
- return 0;
- }
-
-#define AIPH() if( always_invoked ) { mwWrite("autocheck: <%ld> %s(%d) ", mwCounter, file, line ); always_invoked = 0; }
-
-static int mwTestNow( const char *file, int line, int always_invoked ) {
- int retv = 0;
- mwData *mw;
- char *data;
-
- if( file && !always_invoked )
- mwWrite("check: <%ld> %s(%d), checking %s%s%s\n",
- mwCounter, file, line,
- (mwTestFlags & MW_TEST_CHAIN) ? "chain ": "",
- (mwTestFlags & MW_TEST_ALLOC) ? "alloc ": "",
- (mwTestFlags & MW_TEST_NML) ? "nomansland ": ""
- );
-
- if( mwTestFlags & MW_TEST_CHAIN ) {
- for( mw = mwHead; mw; mw=mw->next ) {
- if( !mwIsSafeAddr(mw, mwDataSize) ) {
- AIPH();
- mwWrite("check: heap corruption detected\n");
- mwIncErr();
- return retv + 1;
- }
- if( mw->prev ) {
- if( !mwIsSafeAddr(mw->prev, mwDataSize) ) {
- AIPH();
- mwWrite("check: heap corruption detected\n");
- mwIncErr();
- return retv + 1;
- }
- if( mw==mwHead || mw->prev->next != mw ) {
- AIPH();
- mwWrite("check: heap chain broken, prev link incorrect\n");
- mwIncErr();
- retv ++;
- }
- }
- if( mw->next ) {
- if( !mwIsSafeAddr(mw->next, mwDataSize) ) {
- AIPH();
- mwWrite("check: heap corruption detected\n");
- mwIncErr();
- return retv + 1;
- }
- if( mw==mwTail || mw->next->prev != mw ) {
- AIPH();
- mwWrite("check: heap chain broken, next link incorrect\n");
- mwIncErr();
- retv ++;
- }
- }
- else if( mw!=mwTail ) {
- AIPH();
- mwWrite("check: heap chain broken, tail incorrect\n");
- mwIncErr();
- retv ++;
- }
- }
- }
- if( mwTestFlags & MW_TEST_ALLOC ) {
- for( mw = mwHead; mw; mw=mw->next ) {
- if( mwTestBuf( mw, file, line ) ) retv ++;
- }
- }
- if( mwTestFlags & MW_TEST_NML ) {
- for( mw = mwHead; mw; mw=mw->next ) {
- if( (mw->flag & MW_NML) ) {
- data = ((char*)mw)+mwDataSize+mwOverflowZoneSize;
- if( mwTestMem( data, mw->size, MW_VAL_NML ) ) {
- mwIncErr();
- mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n",
- mw->count, data + mwOverflowZoneSize, mw->file, mw->line );
- }
- }
- }
- }
-
-
- if( file && !always_invoked && !retv )
- mwWrite("check: <%ld> %s(%d), complete; no errors\n",
- mwCounter, file, line );
- return retv;
- }
-
-/**********************************************************************
-** Statistics
-**********************************************************************/
-
-static void mwStatReport()
-{
- mwStat* ms, *ms2;
- const char *modname;
- int modnamelen;
-
- /* global statistics report */
- mwWrite( "\nMemory usage statistics (global):\n" );
- mwWrite( " N)amber of allocations made: %ld\n", mwStatNumAlloc );
- mwWrite( " L)argest memory usage : %ld\n", mwStatMaxAlloc );
- mwWrite( " T)otal of all alloc() calls: %ld\n", mwStatTotAlloc );
- mwWrite( " U)nfreed bytes totals : %ld\n", mwStatCurAlloc );
- FLUSH();
-
- if( mwStatLevel < 1 ) return;
-
- /* on a per-module basis */
- mwWrite( "\nMemory usage statistics (detailed):\n");
- mwWrite( " Module/Line Number Largest Total Unfreed \n");
- for( ms=mwStatList; ms; ms=ms->next )
- {
- if( ms->line == -1 )
- {
- if( ms->file == NULL || !mwIsReadAddr(ms->file,22) ) modname = "<unknown>";
- else modname = ms->file;
- modnamelen = strlen(modname);
- if( modnamelen > 42 )
- {
- modname = modname + modnamelen - 42;
- }
-
- mwWrite(" %-42s %-8ld %-8ld %-8ld %-8ld\n",
- modname, ms->num, ms->max, ms->total, ms->curr );
- if( ms->file && mwStatLevel > 1 )
- {
- for( ms2=mwStatList; ms2; ms2=ms2->next )
- {
- if( ms2->line!=-1 && ms2->file!=NULL && !mwStrCmpI( ms2->file, ms->file ) )
- {
- mwWrite( " %-8d %-8ld %-8ld %-8ld %-8ld\n",
- ms2->line, ms2->num, ms2->max, ms2->total, ms2->curr );
- }
- }
- }
- }
- }
-}
-
-static mwStat* mwStatGet( const char *file, int line, int makenew ) {
- mwStat* ms;
-
- if( mwStatLevel < 2 ) line = -1;
-
- for( ms=mwStatList; ms!=NULL; ms=ms->next ) {
- if( line != ms->line ) continue;
- if( file==NULL ) {
- if( ms->file == NULL ) break;
- continue;
- }
- if( ms->file == NULL ) continue;
- if( !strcmp( ms->file, file ) ) break;
- }
-
- if( ms != NULL ) return ms;
-
- if( !makenew ) return NULL;
-
- ms = (mwStat*) malloc( sizeof(mwStat) );
- if( ms == NULL ) {
- if( mwFreeUp( sizeof(mwStat), 0 ) < sizeof(mwStat) ||
- (ms=(mwStat*)malloc(sizeof(mwStat))) == NULL ) {
- mwWrite("internal: memory low, statistics incomplete for '%s'\n", file );
- return NULL;
- }
- }
- ms->file = file;
- ms->line = line;
- ms->total = 0L;
- ms->max = 0L;
- ms->num = 0L;
- ms->curr = 0L;
- ms->next = mwStatList;
- mwStatList = ms;
- return ms;
- }
-
-static void mwStatAlloc( size_t size, const char* file, int line ) {
- mwStat* ms;
-
- /* update the module statistics */
- ms = mwStatGet( file, -1, 1 );
- if( ms != NULL ) {
- ms->total += (long) size;
- ms->curr += (long) size;
- ms->num ++;
- if( ms->curr > ms->max ) ms->max = ms->curr;
- }
-
- /* update the line statistics */
- if( mwStatLevel > 1 && line != -1 && file ) {
- ms = mwStatGet( file, line, 1 );
- if( ms != NULL ) {
- ms->total += (long) size;
- ms->curr += (long) size;
- ms->num ++;
- if( ms->curr > ms->max ) ms->max = ms->curr;
- }
- }
-
- }
-
-static void mwStatFree( size_t size, const char* file, int line ) {
- mwStat* ms;
-
- /* update the module statistics */
- ms = mwStatGet( file, -1, 1 );
- if( ms != NULL ) ms->curr -= (long) size;
-
- /* update the line statistics */
- if( mwStatLevel > 1 && line != -1 && file ) {
- ms = mwStatGet( file, line, 1 );
- if( ms != NULL ) ms->curr -= (long) size;
- }
- }
-
-/***********************************************************************
-** Safe memory checkers
-**
-** Using ifdefs, implement the operating-system specific mechanism
-** of identifying a piece of memory as legal to access with read
-** and write priviliges. Default: return nonzero for non-NULL pointers.
-***********************************************************************/
-
-static char mwDummy( char c )
-{
- return c;
-}
-
-#ifndef MW_SAFEADDR
-#ifdef WIN32
-#define MW_SAFEADDR
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-int mwIsReadAddr( const void *p, unsigned len )
-{
- if( p == NULL ) return 0;
- if( IsBadReadPtr(p,len) ) return 0;
- return 1;
-}
-int mwIsSafeAddr( void *p, unsigned len )
-{
- /* NOTE: For some reason, under Win95 the IsBad... */
- /* can return false for invalid pointers. */
- if( p == NULL ) return 0;
- if( IsBadReadPtr(p,len) || IsBadWritePtr(p,len) ) return 0;
- return 1;
-}
-#endif /* WIN32 */
-#endif /* MW_SAFEADDR */
-
-#ifndef MW_SAFEADDR
-#ifdef SIGSEGV
-#define MW_SAFEADDR
-
-typedef void (*mwSignalHandlerPtr)( int );
-mwSignalHandlerPtr mwOldSIGSEGV = (mwSignalHandlerPtr) 0;
-jmp_buf mwSIGSEGVjump;
-static void mwSIGSEGV( int n );
-
-static void mwSIGSEGV( int n )
-{
- n = n;
- longjmp( mwSIGSEGVjump, 1 );
-}
-
-int mwIsReadAddr( const void *p, unsigned len )
-{
- const char *ptr;
-
- if( p == NULL ) return 0;
- if( !len ) return 1;
-
- /* set up to catch the SIGSEGV signal */
- mwOldSIGSEGV = signal( SIGSEGV, mwSIGSEGV );
-
- if( setjmp( mwSIGSEGVjump ) )
- {
- signal( SIGSEGV, mwOldSIGSEGV );
- return 0;
- }
-
- /* read all the bytes in the range */
- ptr = (const char *)p;
- ptr += len;
-
- /* the reason for this rather strange construct is that */
- /* we want to keep the number of used parameters and locals */
- /* to a minimum. if we use len for a counter gcc will complain */
- /* it may get clobbered by longjmp() at high warning levels. */
- /* it's a harmless warning, but this way we don't have to see it. */
- do
- {
- ptr --;
- if( *ptr == 0x7C ) (void) mwDummy( (char)0 );
- } while( (const void*) ptr != p );
-
- /* remove the handler */
- signal( SIGSEGV, mwOldSIGSEGV );
-
- return 1;
-}
-int mwIsSafeAddr( void *p, unsigned len )
-{
- char *ptr;
-
- if( p == NULL ) return 0;
- if( !len ) return 1;
-
- /* set up to catch the SIGSEGV signal */
- mwOldSIGSEGV = signal( SIGSEGV, mwSIGSEGV );
-
- if( setjmp( mwSIGSEGVjump ) )
- {
- signal( SIGSEGV, mwOldSIGSEGV );
- return 0;
- }
-
- /* read and write-back all the bytes in the range */
- ptr = (char *)p;
- ptr += len;
-
- /* the reason for this rather strange construct is that */
- /* we want to keep the number of used parameters and locals */
- /* to a minimum. if we use len for a counter gcc will complain */
- /* it may get clobbered by longjmp() at high warning levels. */
- /* it's a harmless warning, but this way we don't have to see it. */
- do
- {
- ptr --;
- *ptr = mwDummy( *ptr );
- } while( (void*) ptr != p );
-
- /* remove the handler */
- signal( SIGSEGV, mwOldSIGSEGV );
-
- return 1;
-}
-#endif /* SIGSEGV */
-#endif /* MW_SAFEADDR */
-
-#ifndef MW_SAFEADDR
-int mwIsReadAddr( const void *p, unsigned len )
-{
- if( p == NULL ) return 0;
- if( len == 0 ) return 1;
- return 1;
-}
-int mwIsSafeAddr( void *p, unsigned len )
-{
- if( p == NULL ) return 0;
- if( len == 0 ) return 1;
- return 1;
-}
-#endif
-
-/**********************************************************************
-** Mutex handling
-**********************************************************************/
-
-#if defined(WIN32) || defined(__WIN32__)
-
-static void mwMutexInit( void )
-{
- mwGlobalMutex = CreateMutex( NULL, FALSE, NULL);
- return;
-}
-
-static void mwMutexTerm( void )
-{
- CloseHandle( mwGlobalMutex );
- return;
-}
-
-static void mwMutexLock( void )
-{
- if( WaitForSingleObject(mwGlobalMutex, 1000 ) == WAIT_TIMEOUT )
- {
- mwWrite( "mwMutexLock: timed out, possible deadlock\n" );
- }
- return;
-}
-
-static void mwMutexUnlock( void )
-{
- ReleaseMutex( mwGlobalMutex );
- return;
-}
-
-#endif
-
-#if defined(MW_PTHREADS) || defined(HAVE_PTHREAD_H)
-
-static void mwMutexInit( void )
-{
- pthread_mutex_init( &mwGlobalMutex, NULL );
- return;
-}
-
-static void mwMutexTerm( void )
-{
- pthread_mutex_destroy( &mwGlobalMutex );
- return;
-}
-
-static void mwMutexLock( void )
-{
- pthread_mutex_lock(&mwGlobalMutex);
- return;
-}
-
-static void mwMutexUnlock( void )
-{
- pthread_mutex_unlock(&mwGlobalMutex);
- return;
-}
-
-#endif
-
-/**********************************************************************
-** C++ new & delete
-**********************************************************************/
-
-#if 0 /* 980317: disabled C++ */
-
-#ifdef __cplusplus
-#ifndef MEMWATCH_NOCPP
-
-int mwNCur = 0;
-const char *mwNFile = NULL;
-int mwNLine = 0;
-
-class MemWatch {
-public:
- MemWatch();
- ~MemWatch();
- };
-
-MemWatch::MemWatch() {
- if( mwInited ) return;
- mwUseAtexit = 0;
- mwInit();
- }
-
-MemWatch::~MemWatch() {
- if( mwUseAtexit ) return;
- mwTerm();
- }
-
-/*
-** This global new will catch all 'new' calls where MEMWATCH is
-** not active.
-*/
-void* operator new( unsigned size ) {
- mwNCur = 0;
- return mwMalloc( size, "<unknown>", 0 );
- }
-
-/*
-** This is the new operator that's called when a module uses mwNew.
-*/
-void* operator new( unsigned size, const char *file, int line ) {
- mwNCur = 0;
- return mwMalloc( size, file, line );
- }
-
-/*
-** This is the new operator that's called when a module uses mwNew[].
-** -- hjc 07/16/02
-*/
-void* operator new[] ( unsigned size, const char *file, int line ) {
- mwNCur = 0;
- return mwMalloc( size, file, line );
- }
-
-/*
-** Since this delete operator will recieve ALL delete's
-** even those from within libraries, we must accept
-** delete's before we've been initialized. Nor can we
-** reliably check for wild free's if the mwNCur variable
-** is not set.
-*/
-void operator delete( void *p ) {
- if( p == NULL ) return;
- if( !mwInited ) {
- free( p );
- return;
- }
- if( mwNCur ) {
- mwFree( p, mwNFile, mwNLine );
- mwNCur = 0;
- return;
- }
- mwFree_( p );
- }
-
-void operator delete[]( void *p ) {
- if( p == NULL ) return;
- if( !mwInited ) {
- free( p );
- return;
- }
- if( mwNCur ) {
- mwFree( p, mwNFile, mwNLine );
- mwNCur = 0;
- return;
- }
- mwFree_( p );
- }
-
-#endif /* MEMWATCH_NOCPP */
-#endif /* __cplusplus */
-
-#endif /* 980317: disabled C++ */
-
-/* MEMWATCH.C */
diff --git a/memwatch.h b/memwatch.h
deleted file mode 100644
index d63fd76..0000000
--- a/memwatch.h
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
-** MEMWATCH.H
-** Nonintrusive ANSI C memory leak / overwrite detection
-** Copyright (C) 1992-2002 Johan Lindh
-** All rights reserved.
-** Version 2.71
-**
-************************************************************************
-**
-** PURPOSE:
-**
-** MEMWATCH has been written to allow guys and gals that like to
-** program in C a public-domain memory error control product.
-** I hope you'll find it's as advanced as most commercial packages.
-** The idea is that you use it during the development phase and
-** then remove the MEMWATCH define to produce your final product.
-** MEMWATCH is distributed in source code form in order to allow
-** you to compile it for your platform with your own compiler.
-** It's aim is to be 100% ANSI C, but some compilers are more stingy
-** than others. If it doesn't compile without warnings, please mail
-** me the configuration of operating system and compiler you are using
-** along with a description of how to modify the source, and the version
-** number of MEMWATCH that you are using.
-**
-************************************************************************
-
- This file is part of MEMWATCH.
-
- MEMWATCH is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- MEMWATCH is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with MEMWATCH; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-************************************************************************
-**
-** REVISION HISTORY:
-**
-** 920810 JLI [1.00]
-** 920830 JLI [1.10 double-free detection]
-** 920912 JLI [1.15 mwPuts, mwGrab/Drop, mwLimit]
-** 921022 JLI [1.20 ASSERT and VERIFY]
-** 921105 JLI [1.30 C++ support and TRACE]
-** 921116 JLI [1.40 mwSetOutFunc]
-** 930215 JLI [1.50 modified ASSERT/VERIFY]
-** 930327 JLI [1.51 better auto-init & PC-lint support]
-** 930506 JLI [1.55 MemWatch class, improved C++ support]
-** 930507 JLI [1.60 mwTest & CHECK()]
-** 930809 JLI [1.65 Abort/Retry/Ignore]
-** 930820 JLI [1.70 data dump when unfreed]
-** 931016 JLI [1.72 modified C++ new/delete handling]
-** 931108 JLI [1.77 mwSetAssertAction() & some small changes]
-** 940110 JLI [1.80 no-mans-land alloc/checking]
-** 940328 JLI [2.00 version 2.0 rewrite]
-** Improved NML (no-mans-land) support.
-** Improved performance (especially for free()ing!).
-** Support for 'read-only' buffers (checksums)
-** ^^ NOTE: I never did this... maybe I should?
-** FBI (free'd block info) tagged before freed blocks
-** Exporting of the mwCounter variable
-** mwBreakOut() localizes debugger support
-** Allocation statistics (global, per-module, per-line)
-** Self-repair ability with relinking
-** 950913 JLI [2.10 improved garbage handling]
-** 951201 JLI [2.11 improved auto-free in emergencies]
-** 960125 JLI [X.01 implemented auto-checking using mwAutoCheck()]
-** 960514 JLI [2.12 undefining of existing macros]
-** 960515 JLI [2.13 possibility to use default new() & delete()]
-** 960516 JLI [2.20 suppression of file flushing on unfreed msgs]
-** 960516 JLI [2.21 better support for using MEMWATCH with DLL's]
-** 960710 JLI [X.02 multiple logs and mwFlushNow()]
-** 960801 JLI [2.22 merged X.01 version with current]
-** 960805 JLI [2.30 mwIsXXXXAddr() to avoid unneeded GP's]
-** 960805 JLI [2.31 merged X.02 version with current]
-** 961002 JLI [2.32 support for realloc() + fixed STDERR bug]
-** 961222 JLI [2.40 added mwMark() & mwUnmark()]
-** 970101 JLI [2.41 added over/underflow checking after failed ASSERT/VERIFY]
-** 970113 JLI [2.42 added support for PC-Lint 7.00g]
-** 970207 JLI [2.43 added support for strdup()]
-** 970209 JLI [2.44 changed default filename to lowercase]
-** 970405 JLI [2.45 fixed bug related with atexit() and some C++ compilers]
-** 970723 JLI [2.46 added MW_ARI_NULLREAD flag]
-** 970813 JLI [2.47 stabilized marker handling]
-** 980317 JLI [2.48 ripped out C++ support; wasn't working good anyway]
-** 980318 JLI [2.50 improved self-repair facilities & SIGSEGV support]
-** 980417 JLI [2.51 more checks for invalid addresses]
-** 980512 JLI [2.52 moved MW_ARI_NULLREAD to occur before aborting]
-** 990112 JLI [2.53 added check for empty heap to mwIsOwned]
-** 990217 JLI [2.55 improved the emergency repairs diagnostics and NML]
-** 990224 JLI [2.56 changed ordering of members in structures]
-** 990303 JLI [2.57 first maybe-fixit-for-hpux test]
-** 990516 JLI [2.58 added 'static' to the definition of mwAutoInit]
-** 990517 JLI [2.59 fixed some high-sensitivity warnings]
-** 990610 JLI [2.60 fixed some more high-sensitivity warnings]
-** 990715 JLI [2.61 changed TRACE/ASSERT/VERIFY macro names]
-** 991001 JLI [2.62 added CHECK_BUFFER() and mwTestBuffer()]
-** 991007 JLI [2.63 first shot at a 64-bit compatible version]
-** 991009 JLI [2.64 undef's strdup() if defined, mwStrdup made const]
-** 000704 JLI [2.65 added some more detection for 64-bits]
-** 010502 JLI [2.66 incorporated some user fixes]
-** [mwRelink() could print out garbage pointer (thanks mac at phobos.ca)]
-** [added array destructor for C++ (thanks rdasilva at connecttel.com)]
-** [added mutex support (thanks rdasilva at connecttel.com)]
-** 010531 JLI [2.67 fix: mwMutexXXX() was declared even if MW_HAVE_MUTEX was not defined]
-** 010619 JLI [2.68 fix: mwRealloc() could leave the mutex locked]
-** 020918 JLI [2.69 changed to GPL, added C++ array allocation by Howard Cohen]
-** 030212 JLI [2.70 mwMalloc() bug for very large allocations (4GB on 32bits)]
-** 030520 JLI [2.71 added ULONG_LONG_MAX as a 64-bit detector (thanks Sami Salonen)]
-**
-** To use, simply include 'MEMWATCH.H' as a header file,
-** and add MEMWATCH.C to your list of files, and define the macro
-** 'MEMWATCH'. If this is not defined, MEMWATCH will disable itself.
-**
-** To call the standard C malloc / realloc / calloc / free; use mwMalloc_(),
-** mwCalloc_() and mwFree_(). Note that mwFree_() will correctly
-** free both malloc()'d memory as well as mwMalloc()'d.
-**
-** 980317: C++ support has been disabled.
-** The code remains, but is not compiled.
-**
-** For use with C++, which allows use of inlining in header files
-** and class specific new/delete, you must also define 'new' as
-** 'mwNew' and 'delete' as 'mwDelete'. Do this *after* you include
-** C++ header files from libraries, otherwise you can mess up their
-** class definitions. If you don't define these, the C++ allocations
-** will not have source file and line number information. Also note,
-** most C++ class libraries implement their own C++ memory management,
-** and don't allow anyone to override them. MFC belongs to this crew.
-** In these cases, the only thing to do is to use MEMWATCH_NOCPP.
-**
-** You can capture output from MEMWATCH using mwSetOutFunc().
-** Just give it the adress of a "void myOutFunc(int c)" function,
-** and all characters to be output will be redirected there.
-**
-** A failing ASSERT() or VERIFY() will normally always abort your
-** program. This can be changed using mwSetAriFunc(). Give it a
-** pointer to a "int myAriFunc(const char *)" function. Your function
-** must ask the user whether to Abort, Retry or Ignore the trap.
-** Return 2 to Abort, 1 to Retry or 0 to Ignore. Beware retry; it
-** causes the expression to be evaluated again! MEMWATCH has a
-** default ARI handler. It's disabled by default, but you can enable
-** it by calling 'mwDefaultAri()'. Note that this will STILL abort
-** your program unless you define MEMWATCH_STDIO to allow MEMWATCH
-** to use the standard C I/O streams. Also, setting the ARI function
-** will cause MEMWATCH *NOT* to write the ARI error to stderr. The
-** error string is passed to the ARI function instead, as the
-** 'const char *' parameter.
-**
-** You can disable MEMWATCH's ASSERT/VERIFY and/or TRACE implementations.
-** This can be useful if you're using a debug terminal or smart debugger.
-** Disable them by defining MW_NOASSERT, MW_NOVERIFY or MW_NOTRACE.
-**
-** MEMWATCH fills all allocated memory with the byte 0xFE, so if
-** you're looking at erroneous data which are all 0xFE:s, the
-** data probably was not initialized by you. The exception is
-** calloc(), which will fill with zero's. All freed buffers are
-** zapped with 0xFD. If this is what you look at, you're using
-** data that has been freed. If this is the case, be aware that
-** MEMWATCH places a 'free'd block info' structure immediately
-** before the freed data. This block contains info about where
-** the block was freed. The information is in readable text,
-** in the format "FBI<counter>filename(line)", for example:
-** "FBI<267>test.c(12)". Using FBI's slows down free(), so it's
-** disabled by default. Use mwFreeBufferInfo(1) to enable it.
-**
-** To aid in tracking down wild pointer writes, MEMWATCH can perform
-** no-mans-land allocations. No-mans-land will contain the byte 0xFC.
-** MEMWATCH will, when this is enabled, convert recently free'd memory
-** into NML allocations.
-**
-** MEMWATCH protects it's own data buffers with checksums. If you
-** get an internal error, it means you're overwriting wildly,
-** or using an uninitialized pointer.
-**
-************************************************************************
-**
-** Note when compiling with Microsoft C:
-** - MSC ignores fflush() by default. This is overridden, so that
-** the disk log will always be current.
-**
-** This utility has been tested with:
-** PC-lint 7.0k, passed as 100% ANSI C compatible
-** Microsoft Visual C++ on Win16 and Win32
-** Microsoft C on DOS
-** SAS C on an Amiga 500
-** Gnu C on a PC running Red Hat Linux
-** ...and using an (to me) unknown compiler on an Atari machine.
-**
-************************************************************************
-**
-** Format of error messages in MEMWATCH.LOG:
-** message: <sequence-number> filename(linenumber), information
-**
-** Errors caught by MemWatch, when they are detected, and any
-** actions taken besides writing to the log file MEMWATCH.LOG:
-**
-** Double-freeing:
-** A pointer that was recently freed and has not since been
-** reused was freed again. The place where the previous free()
-** was executed is displayed.
-** Detect: delete or free() using the offending pointer.
-** Action: The delete or free() is cancelled, execution continues.
-** Underflow:
-** You have written just ahead of the allocated memory.
-** The size and place of the allocation is displayed.
-** Detect: delete or free() of the damaged buffer.
-** Action: The buffer is freed, but there may be secondary damage.
-** Overflow:
-** Like underflow, but you've written after the end of the buffer.
-** Detect: see Underflow.
-** Action: see Underflow.
-** WILD free:
-** An unrecognized pointer was passed to delete or free().
-** The pointer may have been returned from a library function;
-** in that case, use mwFree_() to force free() of it.
-** Also, this may be a double-free, but the previous free was
-** too long ago, causing MEMWATCH to 'forget' it.
-** Detect: delete or free() of the offending pointer.
-** Action: The delete or free() is cancelled, execution continues.
-** NULL free:
-** It's unclear to me whether or not freeing of NULL pointers
-** is legal in ANSI C, therefore a warning is written to the log file,
-** but the error counter remains the same. This is legal using C++,
-** so the warning does not appear with delete.
-** Detect: When you free(NULL).
-** Action: The free() is cancelled.
-** Failed:
-** A request to allocate memory failed. If the allocation is
-** small, this may be due to memory depletion, but is more likely
-** to be memory fragmentation problems. The amount of memory
-** allocated so far is displayed also.
-** Detect: When you new, malloc(), realloc() or calloc() memory.
-** Action: NULL is returned.
-** Realloc:
-** A request to re-allocate a memory buffer failed for reasons
-** other than out-of-memory. The specific reason is shown.
-** Detect: When you realloc()
-** Action: realloc() is cancelled, NULL is returned
-** Limit fail:
-** A request to allocate memory failed since it would violate
-** the limit set using mwLimit(). mwLimit() is used to stress-test
-** your code under simulated low memory conditions.
-** Detect: At new, malloc(), realloc() or calloc().
-** Action: NULL is returned.
-** Assert trap:
-** An ASSERT() failed. The ASSERT() macro works like C's assert()
-** macro/function, except that it's interactive. See your C manual.
-** Detect: On the ASSERT().
-** Action: Program ends with an advisory message to stderr, OR
-** Program writes the ASSERT to the log and continues, OR
-** Program asks Abort/Retry/Ignore? and takes that action.
-** Verify trap:
-** A VERIFY() failed. The VERIFY() macro works like ASSERT(),
-** but if MEMWATCH is not defined, it still evaluates the
-** expression, but it does not act upon the result.
-** Detect: On the VERIFY().
-** Action: Program ends with an advisory message to stderr, OR
-** Program writes the VERIFY to the log and continues, OR
-** Program asks Abort/Retry/Ignore? and takes that action.
-** Wild pointer:
-** A no-mans-land buffer has been written into. MEMWATCH can
-** allocate and distribute chunks of memory solely for the
-** purpose of trying to catch random writes into memory.
-** Detect: Always on CHECK(), but can be detected in several places.
-** Action: The error is logged, and if an ARI handler is installed,
-** it is executed, otherwise, execution continues.
-** Unfreed:
-** A memory buffer you allocated has not been freed.
-** You are informed where it was allocated, and whether any
-** over or underflow has occured. MemWatch also displays up to
-** 16 bytes of the data, as much as it can, in hex and text.
-** Detect: When MemWatch terminates.
-** Action: The buffer is freed.
-** Check:
-** An error was detected during a CHECK() operation.
-** The associated pointer is displayed along with
-** the file and line where the CHECK() was executed.
-** Followed immediately by a normal error message.
-** Detect: When you CHECK()
-** Action: Depends on the error
-** Relink:
-** After a MEMWATCH internal control block has been trashed,
-** MEMWATCH tries to repair the damage. If successful, program
-** execution will continue instead of aborting. Some information
-** about the block may be gone permanently, though.
-** Detect: N/A
-** Action: Relink successful: program continues.
-** Relink fails: program aborts.
-** Internal:
-** An internal error is flagged by MEMWATCH when it's control
-** structures have been damaged. You are likely using an uninitialized
-** pointer somewhere in your program, or are zapping memory all over.
-** The message may give you additional diagnostic information.
-** If possible, MEMWATCH will recover and continue execution.
-** Detect: Various actions.
-** Action: Whatever is needed
-** Mark:
-** The program terminated without umarking all marked pointers. Marking
-** can be used to track resources other than memory. mwMark(pointer,text,...)
-** when the resource is allocated, and mwUnmark(pointer) when it's freed.
-** The 'text' is displayed for still marked pointers when the program
-** ends.
-** Detect: When MemWatch terminates.
-** Action: The error is logged.
-**
-**
-************************************************************************
-**
-** The author may be reached by e-mail at the address below. If you
-** mail me about source code changes in MEMWATCH, remember to include
-** MW's version number.
-**
-** Johan Lindh
-** johan at linkdata.se
-**
-** The latest version of MEMWATCH may be downloaded from
-** http://www.linkdata.se/
-*/
-
-#ifndef __MEMWATCH_H
-#define __MEMWATCH_H
-
-/* Make sure that malloc(), realloc(), calloc() and free() are declared. */
-/*lint -save -e537 */
-#include <stdlib.h>
-/*lint -restore */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
-** Constants used
-** All MEMWATCH constants start with the prefix MW_, followed by
-** a short mnemonic which indicates where the constant is used,
-** followed by a descriptive text about it.
-*/
-
-#define MW_ARI_NULLREAD 0x10 /* Null read (to start debugger) */
-#define MW_ARI_ABORT 0x04 /* ARI handler says: abort program! */
-#define MW_ARI_RETRY 0x02 /* ARI handler says: retry action! */
-#define MW_ARI_IGNORE 0x01 /* ARI handler says: ignore error! */
-
-#define MW_VAL_NEW 0xFE /* value in newly allocated memory */
-#define MW_VAL_DEL 0xFD /* value in newly deleted memory */
-#define MW_VAL_NML 0xFC /* value in no-mans-land */
-#define MW_VAL_GRB 0xFB /* value in grabbed memory */
-
-#define MW_TEST_ALL 0xFFFF /* perform all tests */
-#define MW_TEST_CHAIN 0x0001 /* walk the heap chain */
-#define MW_TEST_ALLOC 0x0002 /* test allocations & NML guards */
-#define MW_TEST_NML 0x0004 /* test all-NML areas for modifications */
-
-#define MW_NML_NONE 0 /* no NML */
-#define MW_NML_FREE 1 /* turn FREE'd memory into NML */
-#define MW_NML_ALL 2 /* all unused memory is NML */
-#define MW_NML_DEFAULT 0 /* the default NML setting */
-
-#define MW_STAT_GLOBAL 0 /* only global statistics collected */
-#define MW_STAT_MODULE 1 /* collect statistics on a module basis */
-#define MW_STAT_LINE 2 /* collect statistics on a line basis */
-#define MW_STAT_DEFAULT 0 /* the default statistics setting */
-
-/*
-** MemWatch internal constants
-** You may change these and recompile MemWatch to change the limits
-** of some parameters. Respect the recommended minimums!
-*/
-#define MW_TRACE_BUFFER 2048 /* (min 160) size of TRACE()'s output buffer */
-#define MW_FREE_LIST 64 /* (min 4) number of free()'s to track */
-
-/*
-** Exported variables
-** In case you have to remove the 'const' keyword because your compiler
-** doesn't support it, be aware that changing the values may cause
-** unpredictable behaviour.
-** - mwCounter contains the current action count. You can use this to
-** place breakpoints using a debugger, if you want.
-*/
-#ifndef __MEMWATCH_C
-extern const unsigned long mwCounter;
-#endif
-
-/*
-** System functions
-** Normally, it is not nessecary to call any of these. MEMWATCH will
-** automatically initialize itself on the first MEMWATCH function call,
-** and set up a call to mwAbort() using atexit(). Some C++ implementations
-** run the atexit() chain before the program has terminated, so you
-** may have to use mwInit() or the MemWatch C++ class to get good
-** behaviour.
-** - mwInit() can be called to disable the atexit() usage. If mwInit()
-** is called directly, you must call mwTerm() to end MemWatch, or
-** mwAbort().
-** - mwTerm() is usually not nessecary to call; but if called, it will
-** call mwAbort() if it finds that it is cancelling the 'topmost'
-** mwInit() call.
-** - mwAbort() cleans up after MEMWATCH, reports unfreed buffers, etc.
-*/
-void mwInit( void );
-void mwTerm( void );
-void mwAbort( void );
-
-/*
-** Setup functions
-** These functions control the operation of MEMWATCH's protective features.
-** - mwFlushNow() causes MEMWATCH to flush it's buffers.
-** - mwDoFlush() controls whether MEMWATCH flushes the disk buffers after
-** writes. The default is smart flushing: MEMWATCH will not flush buffers
-** explicitly until memory errors are detected. Then, all writes are
-** flushed until program end or mwDoFlush(0) is called.
-** - mwLimit() sets the allocation limit, an arbitrary limit on how much
-** memory your program may allocate in bytes. Used to stress-test app.
-** Also, in virtual-memory or multitasking environs, puts a limit on
-** how much MW_NML_ALL can eat up.
-** - mwGrab() grabs up X kilobytes of memory. Allocates actual memory,
-** can be used to stress test app & OS both.
-** - mwDrop() drops X kilobytes of grabbed memory.
-** - mwNoMansLand() sets the behaviour of the NML logic. See the
-** MW_NML_xxx for more information. The default is MW_NML_DEFAULT.
-** - mwStatistics() sets the behaviour of the statistics collector. See
-** the MW_STAT_xxx defines for more information. Default MW_STAT_DEFAULT.
-** - mwFreeBufferInfo() enables or disables the tagging of free'd buffers
-** with freeing information. This information is written in text form,
-** using sprintf(), so it's pretty slow. Disabled by default.
-** - mwAutoCheck() performs a CHECK() operation whenever a MemWatch function
-** is used. Slows down performance, of course.
-** - mwCalcCheck() calculates checksums for all data buffers. Slow!
-** - mwDumpCheck() logs buffers where stored & calc'd checksums differ. Slow!!
-** - mwMark() sets a generic marker. Returns the pointer given.
-** - mwUnmark() removes a generic marker. If, at the end of execution, some
-** markers are still in existence, these will be reported as leakage.
-** returns the pointer given.
-*/
-void mwFlushNow( void );
-void mwDoFlush( int onoff );
-void mwLimit( long bytes );
-unsigned mwGrab( unsigned kilobytes );
-unsigned mwDrop( unsigned kilobytes );
-void mwNoMansLand( int mw_nml_level );
-void mwStatistics( int level );
-void mwFreeBufferInfo( int onoff );
-void mwAutoCheck( int onoff );
-void mwCalcCheck( void );
-void mwDumpCheck( void );
-void * mwMark( void *p, const char *description, const char *file, unsigned line );
-void * mwUnmark( void *p, const char *file, unsigned line );
-
-/*
-** Testing/verification/tracing
-** All of these macros except VERIFY() evaluates to a null statement
-** if MEMWATCH is not defined during compilation.
-** - mwIsReadAddr() checks a memory area for read privilige.
-** - mwIsSafeAddr() checks a memory area for both read & write privilige.
-** This function and mwIsReadAddr() is highly system-specific and
-** may not be implemented. If this is the case, they will default
-** to returning nonzero for any non-NULL pointer.
-** - CHECK() does a complete memory integrity test. Slow!
-** - CHECK_THIS() checks only selected components.
-** - CHECK_BUFFER() checks the indicated buffer for errors.
-** - mwASSERT() or ASSERT() If the expression evaluates to nonzero, execution continues.
-** Otherwise, the ARI handler is called, if present. If not present,
-** the default ARI action is taken (set with mwSetAriAction()).
-** ASSERT() can be disabled by defining MW_NOASSERT.
-** - mwVERIFY() or VERIFY() works just like ASSERT(), but when compiling without
-** MEMWATCH the macro evaluates to the expression.
-** VERIFY() can be disabled by defining MW_NOVERIFY.
-** - mwTRACE() or TRACE() writes some text and data to the log. Use like printf().
-** TRACE() can be disabled by defining MW_NOTRACE.
-*/
-int mwIsReadAddr( const void *p, unsigned len );
-int mwIsSafeAddr( void *p, unsigned len );
-int mwTest( const char *file, int line, int mw_test_flags );
-int mwTestBuffer( const char *file, int line, void *p );
-int mwAssert( int, const char*, const char*, int );
-int mwVerify( int, const char*, const char*, int );
-
-/*
-** User I/O functions
-** - mwTrace() works like printf(), but dumps output either to the
-** function specified with mwSetOutFunc(), or the log file.
-** - mwPuts() works like puts(), dumps output like mwTrace().
-** - mwSetOutFunc() allows you to give the adress of a function
-** where all user output will go. (exeption: see mwSetAriFunc)
-** Specifying NULL will direct output to the log file.
-** - mwSetAriFunc() gives MEMWATCH the adress of a function to call
-** when an 'Abort, Retry, Ignore' question is called for. The
-** actual error message is NOT printed when you've set this adress,
-** but instead it is passed as an argument. If you call with NULL
-** for an argument, the ARI handler is disabled again. When the
-** handler is disabled, MEMWATCH will automatically take the
-** action specified by mwSetAriAction().
-** - mwSetAriAction() sets the default ARI return value MEMWATCH should
-** use if no ARI handler is specified. Defaults to MW_ARI_ABORT.
-** - mwAriHandler() is an ANSI ARI handler you can use if you like. It
-** dumps output to stderr, and expects input from stdin.
-** - mwBreakOut() is called in certain cases when MEMWATCH feels it would
-** be nice to break into a debugger. If you feel like MEMWATCH, place
-** an execution breakpoint on this function.
-*/
-void mwTrace( const char* format_string, ... );
-void mwPuts( const char* text );
-void mwSetOutFunc( void (*func)(int) );
-void mwSetAriFunc( int (*func)(const char*) );
-void mwSetAriAction( int mw_ari_value );
-int mwAriHandler( const char* cause );
-void mwBreakOut( const char* cause );
-
-/*
-** Allocation/deallocation functions
-** These functions are the ones actually to perform allocations
-** when running MEMWATCH, for both C and C++ calls.
-** - mwMalloc() debugging allocator
-** - mwMalloc_() always resolves to a clean call of malloc()
-** - mwRealloc() debugging re-allocator
-** - mwRealloc_() always resolves to a clean call of realloc()
-** - mwCalloc() debugging allocator, fills with zeros
-** - mwCalloc_() always resolves to a clean call of calloc()
-** - mwFree() debugging free. Can only free memory which has
-** been allocated by MEMWATCH.
-** - mwFree_() resolves to a) normal free() or b) debugging free.
-** Can free memory allocated by MEMWATCH and malloc() both.
-** Does not generate any runtime errors.
-*/
-void* mwMalloc( size_t, const char*, int );
-void* mwMalloc_( size_t );
-void* mwRealloc( void *, size_t, const char*, int );
-void* mwRealloc_( void *, size_t );
-void* mwCalloc( size_t, size_t, const char*, int );
-void* mwCalloc_( size_t, size_t );
-void mwFree( void*, const char*, int );
-void mwFree_( void* );
-char* mwStrdup( const char *, const char*, int );
-
-/*
-** Enable/disable precompiler block
-** This block of defines and if(n)defs make sure that references
-** to MEMWATCH is completely removed from the code if the MEMWATCH
-** manifest constant is not defined.
-*/
-#ifndef __MEMWATCH_C
-#ifdef MEMWATCH
-
-#define mwASSERT(exp) while(mwAssert((int)(exp),#exp,__FILE__,__LINE__))
-#ifndef MW_NOASSERT
-#ifndef ASSERT
-#define ASSERT mwASSERT
-#endif /* !ASSERT */
-#endif /* !MW_NOASSERT */
-#define mwVERIFY(exp) while(mwVerify((int)(exp),#exp,__FILE__,__LINE__))
-#ifndef MW_NOVERIFY
-#ifndef VERIFY
-#define VERIFY mwVERIFY
-#endif /* !VERIFY */
-#endif /* !MW_NOVERIFY */
-#define mwTRACE mwTrace
-#ifndef MW_NOTRACE
-#ifndef TRACE
-#define TRACE mwTRACE
-#endif /* !TRACE */
-#endif /* !MW_NOTRACE */
-
-/* some compilers use a define and not a function */
-/* for strdup(). */
-#ifdef strdup
-#undef strdup
-#endif
-
-#define malloc(n) mwMalloc(n,__FILE__,__LINE__)
-#define strdup(p) mwStrdup(p,__FILE__,__LINE__)
-#define realloc(p,n) mwRealloc(p,n,__FILE__,__LINE__)
-#define calloc(n,m) mwCalloc(n,m,__FILE__,__LINE__)
-#define free(p) mwFree(p,__FILE__,__LINE__)
-#define CHECK() mwTest(__FILE__,__LINE__,MW_TEST_ALL)
-#define CHECK_THIS(n) mwTest(__FILE__,__LINE__,n)
-#define CHECK_BUFFER(b) mwTestBuffer(__FILE__,__LINE__,b)
-#define MARK(p) mwMark(p,#p,__FILE__,__LINE__)
-#define UNMARK(p) mwUnmark(p,__FILE__,__LINE__)
-
-#else /* MEMWATCH */
-
-#define mwASSERT(exp)
-#ifndef MW_NOASSERT
-#ifndef ASSERT
-#define ASSERT mwASSERT
-#endif /* !ASSERT */
-#endif /* !MW_NOASSERT */
-
-#define mwVERIFY(exp) exp
-#ifndef MW_NOVERIFY
-#ifndef VERIFY
-#define VERIFY mwVERIFY
-#endif /* !VERIFY */
-#endif /* !MW_NOVERIFY */
-
-/*lint -esym(773,mwTRACE) */
-#define mwTRACE /*lint -save -e506 */ 1?(void)0:mwDummyTraceFunction /*lint -restore */
-#ifndef MW_NOTRACE
-#ifndef TRACE
-/*lint -esym(773,TRACE) */
-#define TRACE mwTRACE
-#endif /* !TRACE */
-#endif /* !MW_NOTRACE */
-
-extern void mwDummyTraceFunction(const char *,...);
-/*lint -save -e652 */
-#define mwDoFlush(n)
-#define mwPuts(s)
-#define mwInit()
-#define mwGrab(n)
-#define mwDrop(n)
-#define mwLimit(n)
-#define mwTest(f,l)
-#define mwSetOutFunc(f)
-#define mwSetAriFunc(f)
-#define mwDefaultAri()
-#define mwNomansland()
-#define mwStatistics(f)
-#define mwMark(p,t,f,n) (p)
-#define mwUnmark(p,f,n) (p)
-#define mwMalloc(n,f,l) malloc(n)
-#define mwStrdup(p,f,l) strdup(p)
-#define mwRealloc(p,n,f,l) realloc(p,n)
-#define mwCalloc(n,m,f,l) calloc(n,m)
-#define mwFree(p) free(p)
-#define mwMalloc_(n) malloc(n)
-#define mwRealloc_(p,n) realloc(p,n)
-#define mwCalloc_(n,m) calloc(n,m)
-#define mwFree_(p) free(p)
-#define mwAssert(e,es,f,l)
-#define mwVerify(e,es,f,l) (e)
-#define mwTrace mwDummyTrace
-#define mwTestBuffer(f,l,b) (0)
-#define CHECK()
-#define CHECK_THIS(n)
-#define CHECK_BUFFER(b)
-#define MARK(p) (p)
-#define UNMARK(p) (p)
-/*lint -restore */
-
-#endif /* MEMWATCH */
-#endif /* !__MEMWATCH_C */
-
-#ifdef __cplusplus
- }
-#endif
-
-#if 0 /* 980317: disabled C++ */
-
-/*
-** C++ support section
-** Implements the C++ support. Please note that in order to avoid
-** messing up library classes, C++ support is disabled by default.
-** You must NOT enable it until AFTER the inclusion of all header
-** files belonging to code that are not compiled with MEMWATCH, and
-** possibly for some that are! The reason for this is that a C++
-** class may implement it's own new() function, and the preprocessor
-** would substitute this crucial declaration for MEMWATCH new().
-** You can forcibly deny C++ support by defining MEMWATCH_NOCPP.
-** To enble C++ support, you must be compiling C++, MEMWATCH must
-** be defined, MEMWATCH_NOCPP must not be defined, and finally,
-** you must define 'new' to be 'mwNew', and 'delete' to be 'mwDelete'.
-** Unlike C, C++ code can begin executing *way* before main(), for
-** example if a global variable is created. For this reason, you can
-** declare a global variable of the class 'MemWatch'. If this is
-** is the first variable created, it will then check ALL C++ allocations
-** and deallocations. Unfortunately, this evaluation order is not
-** guaranteed by C++, though the compilers I've tried evaluates them
-** in the order encountered.
-*/
-#ifdef __cplusplus
-#ifndef __MEMWATCH_C
-#ifdef MEMWATCH
-#ifndef MEMWATCH_NOCPP
-extern int mwNCur;
-extern const char *mwNFile;
-extern int mwNLine;
-class MemWatch {
-public:
- MemWatch();
- ~MemWatch();
- };
-void * operator new(size_t);
-void * operator new(size_t,const char *,int);
-void * operator new[] (size_t,const char *,int); // hjc 07/16/02
-void operator delete(void *);
-#define mwNew new(__FILE__,__LINE__)
-#define mwDelete (mwNCur=1,mwNFile=__FILE__,mwNLine=__LINE__),delete
-#endif /* MEMWATCH_NOCPP */
-#endif /* MEMWATCH */
-#endif /* !__MEMWATCH_C */
-#endif /* __cplusplus */
-
-#endif /* 980317: disabled C++ */
-
-#endif /* __MEMWATCH_H */
-
-/* EOF MEMWATCH.H */
diff --git a/modules.h b/modules.h
index 07effd5..7829704 100644
--- a/modules.h
+++ b/modules.h
@@ -9,6 +9,23 @@
// Module: Central application error code managment
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __MODULES_H__
#define __MODULES_H__
@@ -37,13 +54,15 @@ CREATE_MODULE_IDS (ITEMDELEGATE , 17)
CREATE_MODULE_IDS (INFO , 18)
CREATE_MODULE_IDS (INFOFIELD , 19)
CREATE_MODULE_IDS (DLGACQUIRE , 20)
-CREATE_MODULE_IDS (DLGMESSAGE , 21)
-CREATE_MODULE_IDS (DLGABORT , 22)
-CREATE_MODULE_IDS (DLGDIRSEL , 23)
-CREATE_MODULE_IDS (DLGWAIT , 24)
-CREATE_MODULE_IDS (HASH , 25)
-CREATE_MODULE_IDS (AAFF , 26)
-CREATE_MODULE_IDS (MEDIA , 27)
+CREATE_MODULE_IDS (DLGAUTOEXIT , 21)
+CREATE_MODULE_IDS (DLGMESSAGE , 22)
+CREATE_MODULE_IDS (DLGABORT , 23)
+CREATE_MODULE_IDS (DLGDIRSEL , 24)
+CREATE_MODULE_IDS (DLGWAIT , 25)
+CREATE_MODULE_IDS (HASH , 26)
+CREATE_MODULE_IDS (AAFF , 27)
+CREATE_MODULE_IDS (AEWF , 28)
+CREATE_MODULE_IDS (MEDIA , 29)
CREATE_MODULE_IDS (QT , 99)
diff --git a/package.sh b/package.sh
deleted file mode 100755
index 48b5d1e..0000000
--- a/package.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# package.sh - automated packaging in Guy's developer environment.
-#
-# You may use a command like
-# dpkg-buildpackage -B -uc -rfakeroot
-# or similar instead
-
-if [ -e ../../scripts/package.sh ]; then
- ../../scripts/package.sh guymager-beta
-else
- ../../../scripts/package.sh guymager-beta # when called from the branches or tags directories
-fi
-
-./compileinfo.sh | grep Version | awk -F\" ' { print "Version "$2 } '
-
diff --git a/qtutil.cpp b/qtutil.cpp
index 7a775f4..2545ac8 100644
--- a/qtutil.cpp
+++ b/qtutil.cpp
@@ -9,6 +9,23 @@
// Module: Different Qt utility functions
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include "common.h"
#include <algorithm>
diff --git a/qtutil.h b/qtutil.h
index 85d4842..deb1284 100644
--- a/qtutil.h
+++ b/qtutil.h
@@ -9,6 +9,22 @@
// Module: Different Qt utility functions
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __QTUTIL_H__
#define __QTUTIL_H__
diff --git a/sha256.cpp b/sha256.cpp
index 390ff54..b463050 100644
--- a/sha256.cpp
+++ b/sha256.cpp
@@ -1,11 +1,9 @@
-// Guy: This file has been downloaded from www.spale.com/download/scrypt/scrypt1.0/sha256.c. It
-// has been optimised for speed on i386 and amd64 architecture and corrected for powerpc.
-
// sha256 calculation on i386 and amd64 processors.
/*
* FIPS-180-2 compliant SHA-256 implementation
*
* Copyright (C) 2001-2003 Christophe Devine
+ * Copyright (C) 2010,2011 Guy Voncken <vogu00 at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +20,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+// This file has initially been downloaded from
+// www.spale.com/download/scrypt/scrypt1.0/sha256.c
+//
+// The following optimisation and debugging work has been done by Guy Voncken:
+// - The CPU intensive parts have been rewritten in assembler for better
+// performance on i386 and amd64 machines.
+// - The code has been corrected for big endian machines. The corrections
+// have been tested on a PowerPC machine.
+
+
#include <string.h>
#include <netinet/in.h>
@@ -32,10 +40,10 @@
#endif
-// Guy: The original GET_UINT32 and PUT_UINT32 are
+// Guy: The original GET_UINT32 and PUT_UINT32 macros are
// - too slow
// - not working on powerpc
-// They have been replaced by the powerful htonl/ntohl functions.
+// I replaced them by the powerful htonl/ntohl functions.
/*
#define GET_UINT32(n,b,i) \
@@ -389,70 +397,70 @@ void sha256_process( sha256_context *ctx, uint8 data[64] )
G = ctx->state[6];
H = ctx->state[7];
- P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
- P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
- P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
- P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
- P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
- P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
- P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
- P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
- P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
- P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
- P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
- P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
- P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
- P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
- P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
- P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
- PR(A, B, C, D, E, F, G, H, 16 , 0xE49B69C1 );
- PR(H, A, B, C, D, E, F, G, 17 , 0xEFBE4786 );
- PR(G, H, A, B, C, D, E, F, 18 , 0x0FC19DC6 );
- PR(F, G, H, A, B, C, D, E, 19 , 0x240CA1CC );
- PR(E, F, G, H, A, B, C, D, 20 , 0x2DE92C6F );
- PR(D, E, F, G, H, A, B, C, 21 , 0x4A7484AA );
- PR(C, D, E, F, G, H, A, B, 22 , 0x5CB0A9DC );
- PR(B, C, D, E, F, G, H, A, 23 , 0x76F988DA );
- PR(A, B, C, D, E, F, G, H, 24 , 0x983E5152 );
- PR(H, A, B, C, D, E, F, G, 25 , 0xA831C66D );
- PR(G, H, A, B, C, D, E, F, 26 , 0xB00327C8 );
- PR(F, G, H, A, B, C, D, E, 27 , 0xBF597FC7 );
- PR(E, F, G, H, A, B, C, D, 28 , 0xC6E00BF3 );
- PR(D, E, F, G, H, A, B, C, 29 , 0xD5A79147 );
- PR(C, D, E, F, G, H, A, B, 30 , 0x06CA6351 );
- PR(B, C, D, E, F, G, H, A, 31 , 0x14292967 );
- PR(A, B, C, D, E, F, G, H, 32 , 0x27B70A85 );
- PR(H, A, B, C, D, E, F, G, 33 , 0x2E1B2138 );
- PR(G, H, A, B, C, D, E, F, 34 , 0x4D2C6DFC );
- PR(F, G, H, A, B, C, D, E, 35 , 0x53380D13 );
- PR(E, F, G, H, A, B, C, D, 36 , 0x650A7354 );
- PR(D, E, F, G, H, A, B, C, 37 , 0x766A0ABB );
- PR(C, D, E, F, G, H, A, B, 38 , 0x81C2C92E );
- PR(B, C, D, E, F, G, H, A, 39 , 0x92722C85 );
- PR(A, B, C, D, E, F, G, H, 40 , 0xA2BFE8A1 );
- PR(H, A, B, C, D, E, F, G, 41 , 0xA81A664B );
- PR(G, H, A, B, C, D, E, F, 42 , 0xC24B8B70 );
- PR(F, G, H, A, B, C, D, E, 43 , 0xC76C51A3 );
- PR(E, F, G, H, A, B, C, D, 44 , 0xD192E819 );
- PR(D, E, F, G, H, A, B, C, 45 , 0xD6990624 );
- PR(C, D, E, F, G, H, A, B, 46 , 0xF40E3585 );
- PR(B, C, D, E, F, G, H, A, 47 , 0x106AA070 );
- PR(A, B, C, D, E, F, G, H, 48 , 0x19A4C116 );
- PR(H, A, B, C, D, E, F, G, 49 , 0x1E376C08 );
- PR(G, H, A, B, C, D, E, F, 50 , 0x2748774C );
- PR(F, G, H, A, B, C, D, E, 51 , 0x34B0BCB5 );
- PR(E, F, G, H, A, B, C, D, 52 , 0x391C0CB3 );
- PR(D, E, F, G, H, A, B, C, 53 , 0x4ED8AA4A );
- PR(C, D, E, F, G, H, A, B, 54 , 0x5B9CCA4F );
- PR(B, C, D, E, F, G, H, A, 55 , 0x682E6FF3 );
- PR(A, B, C, D, E, F, G, H, 56 , 0x748F82EE );
- PR(H, A, B, C, D, E, F, G, 57 , 0x78A5636F );
- PR(G, H, A, B, C, D, E, F, 58 , 0x84C87814 );
- PR(F, G, H, A, B, C, D, E, 59 , 0x8CC70208 );
- PR(E, F, G, H, A, B, C, D, 60 , 0x90BEFFFA );
- PR(D, E, F, G, H, A, B, C, 61 , 0xA4506CEB );
- PR(C, D, E, F, G, H, A, B, 62 , 0xBEF9A3F7 );
- PR(B, C, D, E, F, G, H, A, 63 , 0xC67178F2 );
+ P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
+ P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
+ P( G, H, A, B, C, D, E, F, W[ 2], -0x4A3F0431 );
+ P( F, G, H, A, B, C, D, E, W[ 3], -0x164A245B );
+ P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
+ P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
+ P( C, D, E, F, G, H, A, B, W[ 6], -0x6DC07D5C );
+ P( B, C, D, E, F, G, H, A, W[ 7], -0x54E3A12B );
+ P( A, B, C, D, E, F, G, H, W[ 8], -0x27F85568 );
+ P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
+ P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
+ P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
+ P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
+ P( D, E, F, G, H, A, B, C, W[13], -0x7F214E02 );
+ P( C, D, E, F, G, H, A, B, W[14], -0x6423F959 );
+ P( B, C, D, E, F, G, H, A, W[15], -0x3E640E8C );
+ PR(A, B, C, D, E, F, G, H, 16 , -0x1B64963F );
+ PR(H, A, B, C, D, E, F, G, 17 , -0x1041B87A );
+ PR(G, H, A, B, C, D, E, F, 18 , 0x0FC19DC6 );
+ PR(F, G, H, A, B, C, D, E, 19 , 0x240CA1CC );
+ PR(E, F, G, H, A, B, C, D, 20 , 0x2DE92C6F );
+ PR(D, E, F, G, H, A, B, C, 21 , 0x4A7484AA );
+ PR(C, D, E, F, G, H, A, B, 22 , 0x5CB0A9DC );
+ PR(B, C, D, E, F, G, H, A, 23 , 0x76F988DA );
+ PR(A, B, C, D, E, F, G, H, 24 , -0x67C1AEAE );
+ PR(H, A, B, C, D, E, F, G, 25 , -0x57CE3993 );
+ PR(G, H, A, B, C, D, E, F, 26 , -0x4FFCD838 );
+ PR(F, G, H, A, B, C, D, E, 27 , -0x40A68039 );
+ PR(E, F, G, H, A, B, C, D, 28 , -0x391FF40D );
+ PR(D, E, F, G, H, A, B, C, 29 , -0x2A586EB9 );
+ PR(C, D, E, F, G, H, A, B, 30 , 0x06CA6351 );
+ PR(B, C, D, E, F, G, H, A, 31 , 0x14292967 );
+ PR(A, B, C, D, E, F, G, H, 32 , 0x27B70A85 );
+ PR(H, A, B, C, D, E, F, G, 33 , 0x2E1B2138 );
+ PR(G, H, A, B, C, D, E, F, 34 , 0x4D2C6DFC );
+ PR(F, G, H, A, B, C, D, E, 35 , 0x53380D13 );
+ PR(E, F, G, H, A, B, C, D, 36 , 0x650A7354 );
+ PR(D, E, F, G, H, A, B, C, 37 , 0x766A0ABB );
+ PR(C, D, E, F, G, H, A, B, 38 , -0x7E3D36D2 );
+ PR(B, C, D, E, F, G, H, A, 39 , -0x6D8DD37B );
+ PR(A, B, C, D, E, F, G, H, 40 , -0x5D40175F );
+ PR(H, A, B, C, D, E, F, G, 41 , -0x57E599B5 );
+ PR(G, H, A, B, C, D, E, F, 42 , -0x3DB47490 );
+ PR(F, G, H, A, B, C, D, E, 43 , -0x3893AE5D );
+ PR(E, F, G, H, A, B, C, D, 44 , -0x2E6D17E7 );
+ PR(D, E, F, G, H, A, B, C, 45 , -0x2966F9DC );
+ PR(C, D, E, F, G, H, A, B, 46 , -0x0BF1CA7B );
+ PR(B, C, D, E, F, G, H, A, 47 , 0x106AA070 );
+ PR(A, B, C, D, E, F, G, H, 48 , 0x19A4C116 );
+ PR(H, A, B, C, D, E, F, G, 49 , 0x1E376C08 );
+ PR(G, H, A, B, C, D, E, F, 50 , 0x2748774C );
+ PR(F, G, H, A, B, C, D, E, 51 , 0x34B0BCB5 );
+ PR(E, F, G, H, A, B, C, D, 52 , 0x391C0CB3 );
+ PR(D, E, F, G, H, A, B, C, 53 , 0x4ED8AA4A );
+ PR(C, D, E, F, G, H, A, B, 54 , 0x5B9CCA4F );
+ PR(B, C, D, E, F, G, H, A, 55 , 0x682E6FF3 );
+ PR(A, B, C, D, E, F, G, H, 56 , 0x748F82EE );
+ PR(H, A, B, C, D, E, F, G, 57 , 0x78A5636F );
+ PR(G, H, A, B, C, D, E, F, 58 , -0x7B3787EC );
+ PR(F, G, H, A, B, C, D, E, 59 , -0x7338FDF8 );
+ PR(E, F, G, H, A, B, C, D, 60 , -0x6F410006 );
+ PR(D, E, F, G, H, A, B, C, 61 , -0x5BAF9315 );
+ PR(C, D, E, F, G, H, A, B, 62 , -0x41065C09 );
+ PR(B, C, D, E, F, G, H, A, 63 , -0x398E870E );
ctx->state[0] += A;
ctx->state[1] += B;
diff --git a/sha256.h b/sha256.h
index 1248aca..dfb90d9 100644
--- a/sha256.h
+++ b/sha256.h
@@ -1,5 +1,5 @@
// This file has been copied 1:1 from www.spale.com/download/scrypt/scrypt1.0/sha256.c
-// Besides these 2 comment lines, nothing has been changed.
+// Besides these 2 comment lines and the correction of uint32 (see below) nothing has been changed.
#ifndef _SHA256_H
#define _SHA256_H
diff --git a/shatest/cc.sh b/shatest/cc.sh
deleted file mode 100755
index 33244ba..0000000
--- a/shatest/cc.sh
+++ /dev/null
@@ -1 +0,0 @@
-g++ -ggdb -O1 -DTEST sha256.cpp -o o1.out 2>&1 | grep -vE "matching constraint does not allow a register|In function |At global scope:"
diff --git a/table.cpp b/table.cpp
index bf05caf..f2bb881 100644
--- a/table.cpp
+++ b/table.cpp
@@ -9,6 +9,23 @@
// Module: The table widget (central widget of the application)
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <QtGui>
#include "toolconstants.h"
@@ -218,8 +235,6 @@ APIRET t_Table::ShowDeviceInfo (t_pcDevice pDevice)
//
// ----------------------------------------------------------------------------------------------------------------
-
-
APIRET t_Table::InfoAcquisitionStart (t_pDevice pDevice)
{
const char *pLibGuyToolsVersionInstalled;
@@ -750,7 +765,7 @@ APIRET t_Table::InfoAcquisitionEnd (t_pDevice pDevice)
APIRET t_Table::FinaliseThreadStructs (t_pDevice pDevice)
{
- if ((pDevice->pThreadRead == NULL) && // TableCleanupThreadStructs is called upon every thread's end,
+ if ((pDevice->pThreadRead == NULL) && // t_Table::FinaliseThreadStructs is called upon every thread's end,
(pDevice->pThreadWrite == NULL) && // but its core only is executed after the last thread ended (as
(pDevice->pThreadHash == NULL) && // we must not kill vital structures as long as any threads are
(pDevice->ThreadCompressList.isEmpty())) // still running).
@@ -785,6 +800,10 @@ APIRET t_Table::FinaliseThreadStructs (t_pDevice pDevice)
pDevice->pFifoCompressIn = NULL;
pDevice->pFifoCompressOut = NULL;
+
+ if (CONFIG (FifoMemoryManager))
+ CHK (FifoMemoryFree (&pDevice->pFifoMemory))
+
// LibEwfGetMemStats (&LibEwfAllocs, &LibEwfFrees);
// LOG_INFO ("LIBEWF mem statistics: %d allocated - %d freed = %d remaining", LibEwfAllocs, LibEwfFrees, LibEwfAllocs - LibEwfFrees)
@@ -796,8 +815,24 @@ APIRET t_Table::FinaliseThreadStructs (t_pDevice pDevice)
if (!pDevice->DeleteAfterAbort)
CHK_EXIT (InfoAcquisitionEnd (pDevice))
- }
+ // Check if all acqusitions have completed now (for AutoExit)
+ // ----------------------------------------------------------
+ t_Device::t_State State;
+ int i;
+ bool AllCompleted = true;
+
+ for (i=0; i<pOwn->pDeviceList->count() && AllCompleted; i++)
+ {
+ State = pOwn->pDeviceList->at(i)->State;
+ AllCompleted = (State == t_Device::Idle ) ||
+ (State == t_Device::Finished) ||
+ ((State == t_Device::Aborted ) && (pOwn->pDeviceList->at(i)->AbortReason == t_Device::UserRequest));
+ }
+ if (AllCompleted)
+ emit (SignalAllAcquisitionsEnded());
+ }
+
return NO_ERROR;
}
diff --git a/table.h b/table.h
index 2102965..10143cc 100644
--- a/table.h
+++ b/table.h
@@ -9,7 +9,22 @@
// Module: The table widget (central widget of the application)
// ****************************************************************************
-
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __TABLE_H__
#define __TABLE_H__
@@ -62,7 +77,8 @@ class t_Table: public QTableView
void SlotThreadWriteWakeThreads (t_pDevice pDevice);
signals:
- void SignalDeviceSelected (t_pDevice pDevice);
+ void SignalDeviceSelected (t_pDevice pDevice);
+ void SignalAllAcquisitionsEnded (void);
private:
t_TableLocal *pOwn;
diff --git a/threadcompress.cpp b/threadcompress.cpp
index a1cd1c2..f4f009d 100644
--- a/threadcompress.cpp
+++ b/threadcompress.cpp
@@ -9,6 +9,22 @@
// Module: Multi-threaded compression
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#include <QtCore>
diff --git a/threadcompress.h b/threadcompress.h
index be9422e..ac124a0 100644
--- a/threadcompress.h
+++ b/threadcompress.h
@@ -9,6 +9,22 @@
// Module: Multi-threaded compression
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __THREADCOMPRESS_H__
#define __THREADCOMPRESS_H__
diff --git a/threadhash.cpp b/threadhash.cpp
index 0ed966c..0bc0137 100644
--- a/threadhash.cpp
+++ b/threadhash.cpp
@@ -9,6 +9,23 @@
// Module: Thread for calculating hashes
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <QtCore>
#include "common.h"
diff --git a/threadhash.h b/threadhash.h
index 194aa32..b589c02 100644
--- a/threadhash.h
+++ b/threadhash.h
@@ -9,6 +9,22 @@
// Module: Thread for calculating hashes
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __THREADHASH_H__
#define __THREADHASH_H__
diff --git a/threadread.cpp b/threadread.cpp
index a851b91..8651e57 100644
--- a/threadread.cpp
+++ b/threadread.cpp
@@ -9,6 +9,23 @@
// Module: Thread for reading data.
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <errno.h>
#include <QtCore>
diff --git a/threadread.h b/threadread.h
index 4000f0e..4f56ced 100644
--- a/threadread.h
+++ b/threadread.h
@@ -9,6 +9,22 @@
// Module: Thread for reading data.
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __THREADREAD_H__
#define __THREADREAD_H__
diff --git a/threadscan.cpp b/threadscan.cpp
index af2c2bd..7b992b2 100644
--- a/threadscan.cpp
+++ b/threadscan.cpp
@@ -9,6 +9,23 @@
// Module: Thread for scanning the connected devices
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <QtCore>
#include <QtDBus/QtDBus>
@@ -27,7 +44,9 @@
// Constants
// --------------------------
-const int THREADSCAN_WAIT_MAX = 5000;
+// #define DEBUG_SERNR
+
+const int THREADSCAN_WAIT_MAX = 10000;
const int THREADSCAN_WAIT_GRANULARITY = 100;
const QString ThreadScanLibPartedSearchDirs = "/lib,/usr/lib,/usr/local/lib"; // Separate directories by commas
@@ -228,6 +247,16 @@ void t_ThreadScanWorkerParted::SlotRescan (void)
delete pDeviceList;
return;
}
+ #ifdef DEBUG_SERNR
+ printf ("\n----- libparted device info ---------");
+ printf ("\nPath: [%s]", pPedDev->path );
+ printf ("\nModel: [%s]", pPedDev->model);
+ printf ("\nSectorSize: %lld", pPedDev->sector_size);
+ printf ("\nSectorSizePhys: %lld", pPedDev->phys_sector_size);
+ printf ("\nLength (Sectors): %lld", pPedDev->length);
+ printf ("\nSerial number: [%s] -- read out by command %s" , QSTR_TO_PSZ(SerialNumber), CONFIG (CommandGetSerialNumber));
+ printf ("\n");
+ #endif
pDevice = pDeviceList->AppendNew (SerialNumber, pPedDev);
if (pDevice->LinuxDevice.startsWith ("/dev/fd", Qt::CaseSensitive)) // Not a good way for checking this, but I don't know how to extract the information from
pDevice->Removable = true; // PedDevice. BTW, this won't work with other removable devices, for instance memory sticks.
@@ -451,16 +480,27 @@ void t_ThreadScanWorkerHAL::SlotRescan (void)
CHK_EXIT (GetPropertySingle (HalDevice, "storage.serial", SerialNumber))
CHK_EXIT (GetPropertySingle (HalDevice, "info.vendor" , Vendor ))
CHK_EXIT (GetPropertySingle (HalDevice, "info.product" , Product ))
+
+ #ifdef DEBUG_SERNR
+ #define VARIANT_TO_STRING_INFO(Var) \
+ Var.isValid() ? Var.canConvert(QVariant::String) ? QSTR_TO_PSZ(Var.toString()) : "--CANNOT CONVERT--" : "--INVALID DATA--"
+
+ printf ("\n----- DBus/HAL device info ---------");
+ printf ("\nblock.device: [%s]", VARIANT_TO_STRING_INFO (LinuxDevice ));
+ printf ("\nstorage.serial: [%s]", VARIANT_TO_STRING_INFO (SerialNumber));
+ printf ("\ninfo.vendor: [%s]", VARIANT_TO_STRING_INFO (Vendor ));
+ printf ("\ninfo.product: [%s]", VARIANT_TO_STRING_INFO (Product ));
+ printf ("\nstorage.removable.media_size: %llu", Size.toULongLong());
+ printf ("\n");
+ #endif
+
if (!SerialNumber.isValid())
SerialNumber = ""; // Attention: Empty string must be used, else t_DeviceList::MatchDevice doesn't work
if (!Vendor.isValid() && !Product.isValid())
Model = "--";
else Model = Vendor.toString() + " " + Product.toString();
Model = Model.trimmed();
-
-// if (SerialNumber.toString().contains("Hitachi", Qt::CaseInsensitive))
-// Size = QVariant ((qulonglong)1024*1024*1024*32); // for test purposes
-// Size = QVariant ((qulonglong)283 + 1024*1024*50); printf ("\nATTENTION: TEST CODE activated");
+
pDevice = pDeviceList->AppendNew (SerialNumber.toString(), LinuxDevice.toString(), Model,
DEVICE_DEFAULT_SECTOR_SIZE, DEVICE_DEFAULT_SECTOR_SIZE, Size.toULongLong());
pDevice->Removable = Removable.toBool();
@@ -528,6 +568,10 @@ class t_ThreadScanWorkerDevKitLocal
t_ThreadScanWorkerDevKit::t_ThreadScanWorkerDevKit (APIRET &rc)
{
+ QDBusMessage Message;
+
+ // Check DBUS
+ // ----------
pOwn = new t_ThreadScanWorkerDevKitLocal;
if (!pOwn->pDBusConnection->isConnected())
{
@@ -536,6 +580,23 @@ t_ThreadScanWorkerDevKit::t_ThreadScanWorkerDevKit (APIRET &rc)
return;
}
+ // Do a UDisks method call first
+ // -----------------------------
+ // The reason is, that Kubuntu only starts its udisks daemon when needed: "udisks-daemon provides the
+ // org.freedesktop.UDisks service on the system message bus. Users or administrators should never need to start
+ // this daemon as it will automatically started by dbus-daemon(1) whenever an application calls into the
+ // org.freedesktop.UDisks service." They only forgot that a good program first asks if it's there before accessing
+ // it... BTW, the ipod program "clementine" faced the same problem.
+
+ pOwn->pPaths = &UDisksPaths;
+ Message = QDBusMessage::createMethodCall (pOwn->pPaths->pService, pOwn->pPaths->pDisksPath, pOwn->pPaths->pDisksIf, "EnumerateDevices");
+ QDBusReply<QDBusArgument> Reply = pOwn->pDBusConnection->call(Message);
+ if (!Reply.isValid())
+ LOG_INFO ("Test method call for starting udisks daemon didn't seem to work")
+
+
+ // Check if either UDisks or DeviceKit is alive
+ // --------------------------------------------
pOwn->pDBusInterface = pOwn->pDBusConnection->interface();
pOwn->pPaths = &UDisksPaths;
if (!pOwn->pDBusInterface->isServiceRegistered (pOwn->pPaths->pService))
@@ -549,6 +610,7 @@ t_ThreadScanWorkerDevKit::t_ThreadScanWorkerDevKit (APIRET &rc)
return;
}
}
+
LOG_INFO ("Using %s", pOwn->pPaths->pService)
rc = NO_ERROR;
}
@@ -620,6 +682,7 @@ void t_ThreadScanWorkerDevKit::SlotRescan (void)
QVariant Vendor;
QVariant Product;
QVariant Size;
+ QVariant BlockSize;
QVariant Drive;
QVariant Removable;
QVariant RemovableAvailable;
@@ -673,10 +736,23 @@ void t_ThreadScanWorkerDevKit::SlotRescan (void)
continue;
}
- CHK_EXIT (GetProperty (DevKitDevice, "device-size" , Size ))
- CHK_EXIT (GetProperty (DevKitDevice, "drive-serial", SerialNumber))
- CHK_EXIT (GetProperty (DevKitDevice, "drive-vendor", Vendor ))
- CHK_EXIT (GetProperty (DevKitDevice, "drive-model" , Product ))
+ CHK_EXIT (GetProperty (DevKitDevice, "device-size" , Size ))
+ CHK_EXIT (GetProperty (DevKitDevice, "drive-serial" , SerialNumber))
+ CHK_EXIT (GetProperty (DevKitDevice, "drive-vendor" , Vendor ))
+ CHK_EXIT (GetProperty (DevKitDevice, "drive-model" , Product ))
+ CHK_EXIT (GetProperty (DevKitDevice, "device-block-size", BlockSize ))
+
+ #ifdef DEBUG_SERNR
+ printf ("\n----- DBus/DevKit-UDisks device info ---------");
+ printf ("\ndevice-file: [%s]", VARIANT_TO_STRING_INFO (LinuxDevice ));
+ printf ("\ndrive-serial: [%s]", VARIANT_TO_STRING_INFO (SerialNumber));
+ printf ("\ndrive-vendor: [%s]", VARIANT_TO_STRING_INFO (Vendor ));
+ printf ("\ndrive-model: [%s]", VARIANT_TO_STRING_INFO (Product ));
+ printf ("\ndevice-size: %llu", Size .toULongLong());
+ printf ("\ndevice-block-size: %llu", BlockSize.toULongLong());
+ printf ("\n");
+ #endif
+
if (!SerialNumber.isValid())
SerialNumber = ""; // Attention: Empty string must be used, else t_DeviceList::MatchDevice doesn't work
if (!Vendor.isValid() && !Product.isValid())
@@ -685,7 +761,7 @@ void t_ThreadScanWorkerDevKit::SlotRescan (void)
Model = Model.trimmed();
pDevice = pDeviceList->AppendNew (SerialNumber.toString(), LinuxDevice.toString(), Model,
- DEVICE_DEFAULT_SECTOR_SIZE, DEVICE_DEFAULT_SECTOR_SIZE, Size.toULongLong());
+ BlockSize.toULongLong(), BlockSize.toULongLong(), Size.toULongLong());
pDevice->Removable = Removable.toBool();
}
}
diff --git a/threadscan.h b/threadscan.h
index b471f61..ce7f1a3 100644
--- a/threadscan.h
+++ b/threadscan.h
@@ -7,6 +7,23 @@
// Section Nouvelles Technologies
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include <QObject> //lint !e537 Repeated include
#include <QThread>
diff --git a/threadwrite.cpp b/threadwrite.cpp
index cddec26..6c96756 100644
--- a/threadwrite.cpp
+++ b/threadwrite.cpp
@@ -9,6 +9,23 @@
// Module: Thread for writing data.
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include "common.h"
#include "compileinfo.h"
@@ -193,7 +210,7 @@ class t_OutputFileDD: public t_OutputFile
if (Read < 0)
{
QString Filename = oFilenameList[oCurrentVerifyFileNr-1];
- LOG_ERROR ("read failed, oFile %d [%s], errno=%d '%s'", oFile, QSTR_TO_PSZ (Filename), errno, ToolErrorTranslateErrno (errno))
+ LOG_ERROR ("read failed, oFile %d [%s], seek pos %llu, errno %d '%s'", oFile, QSTR_TO_PSZ (Filename), *pPos, errno, ToolErrorTranslateErrno (errno))
return ERROR_THREADWRITE_VERIFY_FAILED;
}
oRemainingFileSize -= Read;
@@ -345,14 +362,14 @@ class t_OutputFileEWF: public t_OutputFile
#define STR_AND_LEN(QStr) QStr.toAscii().data(), strlen(QStr.toAscii().data())
libewf_set_notify_values(stderr, 1);
+ CHK_LIBEWF (libewf_set_format (pFile, (uint8_t) CONFIG (EwfFormat)))
CHK_LIBEWF (libewf_set_media_size (pFile, pDevice->Size))
- CHK_LIBEWF (libewf_set_bytes_per_sector (pFile, pDevice->SectorSize))
+ CHK_LIBEWF (libewf_set_bytes_per_sector (pFile, (unsigned int) pDevice->SectorSize))
CHK_LIBEWF (libewf_set_sectors_per_chunk (pFile, 64))
- CHK_LIBEWF (libewf_set_segment_file_size (pFile, (unsigned int) (pDevice->Acquisition.SplitFileSize)))
+ CHK_LIBEWF (libewf_set_segment_file_size (pFile, pDevice->Acquisition.SplitFileSize))
CHK_LIBEWF (libewf_set_compression_values (pFile, CONFIG (EwfCompression), 1))
CHK_LIBEWF (libewf_set_media_type (pFile, pDevice->Removable ? LIBEWF_MEDIA_TYPE_REMOVABLE : LIBEWF_MEDIA_TYPE_FIXED))
CHK_LIBEWF (libewf_set_volume_type (pFile, LIBEWF_VOLUME_TYPE_PHYSICAL))
- CHK_LIBEWF (libewf_set_format (pFile, (uint8_t) CONFIG (EwfFormat)))
CHK_LIBEWF (libewf_set_header_value (pFile, (char *)"case_number" , STR_AND_LEN(pDevice->Acquisition.CaseNumber )))
CHK_LIBEWF (libewf_set_header_value (pFile, (char *)"description" , STR_AND_LEN(pDevice->Acquisition.Description )))
@@ -532,7 +549,7 @@ class t_OutputFileAFF: public t_OutputFile
}
else
{
- CHK (AaffOpen (&pFile, QSTR_TO_PSZ(FileName), pDevice->Size, pDevice->SectorSizePhys, pDevice->FifoBlockSize))
+ CHK (AaffOpen (&pFile, QSTR_TO_PSZ(FileName), pDevice->Size, pDevice->SectorSize, pDevice->FifoBlockSize))
rc = ToolSysInfoGetMacAddr (&MacAddr);
if (rc == TOOLSYSINFO_ERROR_NO_ADDR)
diff --git a/threadwrite.h b/threadwrite.h
index 9c9b520..4c43e94 100644
--- a/threadwrite.h
+++ b/threadwrite.h
@@ -9,6 +9,22 @@
// Module: Thread for writing data.
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
#ifndef __THREADWRITE_H__
#define __THREADWRITE_H__
diff --git a/util.cpp b/util.cpp
index 06e12cb..fd7acb6 100644
--- a/util.cpp
+++ b/util.cpp
@@ -9,53 +9,38 @@
// Module: Different utility functions
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#include "common.h"
#include <QtGui>
#include "config.h"
-
-#define MEMWATCH
-#define MEMWATCH_NOCPP
-#include "memwatch.h"
-#undef malloc // These have been defined in memwatch.h. We must undefine them
-#undef free // in order to be able to access std::malloc and std::free
-
#include "util.h"
-static QMutex MutexMemAccess;
-
-
-void *UtilMemAlloc (size_t Size, const char *pFile, int Line)
+void *UtilMemAlloc (size_t Size, const char */*pFile*/, int /*Line*/)
{
- void *pMem;
-
- if (CONFIG(UseMemWatch))
- {
- MutexMemAccess.lock();
- pMem = mwMalloc (Size, pFile, Line);
- MutexMemAccess.unlock();
- }
- else
- {
- pMem = malloc(Size);
- }
-
- return pMem;
+ return malloc(Size);
}
-void UtilMemFree (void *pMem, const char *pFile, int Line)
+void UtilMemFree (void *pMem, const char */*pFile*/, int /*Line*/)
{
- if (CONFIG(UseMemWatch))
- {
- MutexMemAccess.lock();
- mwFree (pMem, pFile, Line);
- MutexMemAccess.unlock();
- }
- else
- {
- free (pMem);
- }
+ free (pMem);
}
int UtilCalcDecimals (t_uint64 Value)
diff --git a/util.h b/util.h
index 37bdaa5..b74b794 100644
--- a/util.h
+++ b/util.h
@@ -9,6 +9,23 @@
// Module: Different utility functions
// ****************************************************************************
+// Copyright 2008, 2009, 2010 Guy Voncken
+//
+// This file is part of guymager.
+//
+// guymager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// guymager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with guymager. If not, see <http://www.gnu.org/licenses/>.
+
#ifndef __UTIL_H__
#define __UTIL_H__
--
debian-forensics/guymager
More information about the forensics-changes
mailing list