Article View: borland.public.cppbuilder.nativeapi
Article #13446Re: File delete question
From: Ed Mulroy [TeamB]
Date: Mon, 13 Oct 2003 01:29
Date: Mon, 13 Oct 2003 01:29
183 lines
6272 bytes
6272 bytes
Ok, so you are overwhelmed by the massive amount of code in Eraser. That's
how application programs are - there is so much user interface and other
detail work that the working part of the program is often burried under the
weight of the other stuff.
Below is C++ file wiping code cut from a program. I have removed calls to
reporting functions and other things not pertainent to the basic task. You
may need to also include tchar.h. The functions OpenWipeFile and
ShowLastError are just helper functions. You may find ShowLastError to be
useful in other programs where you have to call GetLastError to find out
what happened because it reports the error as a message and not as a number.
I do not champion it as any kind of super code, just something that at least
kind of does what you want. If you decide to try it, cut and paste it from
the message instead of copying it by hand.
I had to do a bit of hacking and cutting to remove items extraneous to what
you are looking for here. In return I want you to at least tell me what you
think and how it worked for you.
. Ed
-----------------------
#include <windows.h>
#include <cstdio>
using namespace std;
extern HINSTANCE _hInstance; // the compiler provides this
#define NO_TEMPLATE_FILE NULL
#define NO_SECURITY_ATTRIBS NULL
const DWORD NO_SHARING = 0;
const DWORD WIPE_BUF_SIZE = 128 * 1024UL;
static HANDLE OpenWipeFile(const char *name)
{
return
CreateFile(name,
GENERIC_READ | GENERIC_WRITE,
NO_SHARING,
NO_SECURITY_ATTRIBS,
OPEN_EXISTING,
GetFileAttributes(name),
NO_TEMPLATE_FILE);
}
void ShowLastError(HWND hwnd, const char *title_text)
{
TCHAR *err_msg;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPTSTR>(&err_msg),
0,
NULL);
if (title_text && *title_text)
MessageBox(hwnd, err_msg, title_text, MB_OK);
else
MessageBox(hwnd, err_msg, "Error", MB_OK);
LocalFree(err_msg);
SetLastError(0);
}
int HelpWipe(const char *name)
{
DWORD attrs = GetFileAttributes(name);
if (attrs & FILE_ATTRIBUTE_OFFLINE)
{
printf("file \"%s\" is offline\n", name);
return 1;
}
bool compressed = (attrs & FILE_ATTRIBUTE_COMPRESSED) != 0;
randomize();
srand(rand() + (unsigned) _hInstance);
HANDLE file_hand = OpenWipeFile(name);
if (file_hand != INVALID_HANDLE_VALUE)
{
DWORD numleft; // number of bytes left to write
// these assume the file size is less than 2Gig
if (compressed)
numleft = GetCompressedFileSize(name, NULL);
else
numleft = GetFileSize(file_hand, NULL);
// round numleft + twice wipe buffer size to an integral
// multiple of the wipe buffer size
//
// because WIPE_BUF_SIZE is a power of 2, it has only
// one bit set and (WIPE_BUF_SIZE - 1) will have all
// bits less significant than that one set
numleft =
(numleft + ( 2 * WIPE_BUF_SIZE)) & ~(WIPE_BUF_SIZE - 1);
unsigned char buf[WIPE_BUF_SIZE];
unsigned char *bptr;
while (1)
{
bptr = buf;
// probably one of the slower ways to do such things
for (int i = 0; i < sizeof(buf); ++i)
*bptr++ = rand();
DWORD num_written;
WriteFile(file_hand, buf, sizeof(buf), &num_written, NULL);
if (numleft <= sizeof(buf))
break;
numleft -= num_written;
}
// if this is not done we risk Windows' file buffering scheme
// altering what we do to some of the dir entries
FlushFileBuffers(file_hand);
// set the file to zero length (destroy length info in dir entry)
SetFilePointer(file_hand, 0, NULL, FILE_BEGIN);
SetEndOfFile(file_hand);
// because of paranoia, flush again
FlushFileBuffers(file_hand);
CloseHandle(file_hand);
// destroy file times and dates in dir entry
file_hand = OpenWipeFile(name);
FILETIME ft;
SYSTEMTIME st = { 1990, 1, 1, 1, 1, 1, 1, 1 };
SystemTimeToFileTime(&st, &ft);
SetLastError(0);
if (!SetFileTime(file_hand, &ft, &ft, &ft))
ShowLastError(HWND_DESKTOP, name);
CloseHandle(file_hand);
// rename to a single char (2nd & following char's are
// otherwise left in the deleted directory entry)
char new_name[2];
new_name[1] = '\0';
for (char c = (rand() % 26) + 'A', d = 0; ;
c = (((c + 1) - 'A') % 26) + 'A')
{
*new_name = c;
if (MoveFile(name, new_name))
break;
if (++d >= 26)
{
printf("Unable to rename \"%s\". Is file in use?\n", name);
return 1;
}
}
DeleteFile(new_name); // actually do the delete
}
return 1;
}
-----------------------
> Martin C wrote in message
> news:3f895aff@newsgroups.borland.com...
Technical Details
Message-ID:
<3f89fff9@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-04!sn-xit-06!sn-xit-09!sn-xit-08!supernews.com!easynet-quince!easynet.net!news.tele.dk!news.tele.dk!small.news.tele.dk!lnewsoutpeer01.lnd.ops.eu.uu.net!lnewsinpeer01.lnd.ops.eu.uu.net!emea.uu.net!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailReferences:
<3f88d714@newsgroups.borland.com> <3f892fbb@newsgroups.borland.com> <3f895aff@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 10cc67,39420a342151d176 X-Google-Attributes: gid10cc67,public X-Google-ArrivalTime: 2003-10-12 18:39:08 PST From: "Ed Mulroy [TeamB]" <dont_email_me@bitbuc.ket> Newsgroups: borland.public.cppbuilder.nativeapi References: <3f88d714@newsgroups.borland.com> <3f892fbb@newsgroups.borland.com> <3f895aff@newsgroups.borland.com> Subject: Re: File delete question Date: Sun, 12 Oct 2003 21:29:24 -0400 Lines: 185 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 NNTP-Posting-Host: 24.74.175.102 Message-ID: <3f89fff9@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1066008569 24.74.175.102 (12 Oct 2003 18:29:29 -0700) X-Authenticated-User: edmulroy Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-04!sn-xit-06!sn-xit-09!sn-xit-08!supernews.com!easynet-quince!easynet.net!news.tele.dk!news.tele.dk!small.news.tele.dk!lnewsoutpeer01.lnd.ops.eu.uu.net!lnewsinpeer01.lnd.ops.eu.uu.net!emea.uu.net!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail