56 |
void (*progress_cb) (void *, DDWORD, DDWORD); |
void (*progress_cb) (void *, DDWORD, DDWORD); |
57 |
static void *progress_cb_value = NULL; |
static void *progress_cb_value = NULL; |
58 |
|
|
59 |
void (*unlink_cb)(void *, const char *, int, unsigned, unsigned) = NULL; |
void (*unlink_cb)(void *, const char *, int, int, int) = NULL; |
60 |
static void *unlink_cb_value = NULL; |
static void *unlink_cb_value = NULL; |
61 |
|
|
62 |
|
/* Use the file handle in the context to overwrite a file |
63 |
|
with prepared buffer contents. */ |
64 |
static void |
static void |
65 |
overwrite (wipe_context_s * ctx) |
overwrite (wipe_context_s *ctx) |
66 |
{ |
{ |
67 |
DDWORD blocks = 0, mod = 0; |
DDWORD blocks = 0, mod = 0; |
68 |
DWORD nwritten = 0; |
DWORD nwritten = 0; |
88 |
} |
} |
89 |
FlushFileBuffers (ctx->fd); |
FlushFileBuffers (ctx->fd); |
90 |
SetFilePointer (ctx->fd, 0, &size_high, FILE_BEGIN); |
SetFilePointer (ctx->fd, 0, &size_high, FILE_BEGIN); |
91 |
} /* overwrite */ |
} |
92 |
|
|
93 |
|
|
94 |
|
/* fill the buffer with random of the given level. */ |
95 |
static void |
static void |
96 |
randomize_buffer (byte * buf, size_t bufsize, int level) |
randomize_buffer (byte *buf, size_t bufsize, int level) |
97 |
{ |
{ |
98 |
const int blocksize = 512; |
const int blocksize = 512; |
99 |
int blocks = bufsize / blocksize; |
int blocks = bufsize / blocksize; |
105 |
} |
} |
106 |
if (mod) |
if (mod) |
107 |
gpg_randomize (buf, mod, level); |
gpg_randomize (buf, mod, level); |
108 |
} /* randomize_buffer */ |
} |
109 |
|
|
110 |
|
|
111 |
static void |
/* performs a random overwrite. */ |
112 |
|
static void |
113 |
overwrite_random (int npasses, wipe_context_s * ctx) |
overwrite_random (int npasses, wipe_context_s * ctx) |
114 |
{ |
{ |
115 |
int i; |
int i; |
118 |
randomize_buffer (ctx->buffer, ctx->buffsize, 0); |
randomize_buffer (ctx->buffer, ctx->buffsize, 0); |
119 |
overwrite (ctx); |
overwrite (ctx); |
120 |
} |
} |
121 |
} /* overwrite_random */ |
} |
122 |
|
|
123 |
|
|
124 |
|
/* perform an overwrite with a specific byte (like 0x00). */ |
125 |
static void |
static void |
126 |
overwrite_byte (int byte, wipe_context_s * ctx) |
overwrite_byte (int byte, wipe_context_s * ctx) |
127 |
{ |
{ |
130 |
} /* overwrite_byte */ |
} /* overwrite_byte */ |
131 |
|
|
132 |
|
|
133 |
|
/* perform an overwrite with a specific byte triple (like 0x00, 0xFF, 0xAA). */ |
134 |
static void |
static void |
135 |
overwrite_bytes (int byte1, int byte2, int byte3, wipe_context_s * ctx) |
overwrite_bytes (int byte1, int byte2, int byte3, wipe_context_s * ctx) |
136 |
{ |
{ |
145 |
} /* overwrite_bytes */ |
} /* overwrite_bytes */ |
146 |
|
|
147 |
|
|
148 |
/** |
/* For the case the file is not a regular file (this is true for |
149 |
* For the case the file is not a regular file (this is true for |
devices or directories) this function tries to rename the file |
150 |
* devices or directories) this function tries to rename the file |
to random pattern and then it will be delete (without random!). */ |
|
* to random pattern and then it will be delete (without random!). |
|
|
**/ |
|
151 |
int |
int |
152 |
rename_unlink (const char * path) |
rename_unlink (const char *path) |
153 |
{ |
{ |
154 |
struct stat statbuf; |
struct stat statbuf; |
155 |
char * new_name = NULL, * p = NULL, c; |
char *new_name = NULL, *p = NULL, c; |
156 |
int i = 0, rc = 0; |
int i = 0, rc = 0; |
157 |
int is_dir = 0; |
int is_dir = 0; |
158 |
|
|
175 |
while (i < 14) { |
while (i < 14) { |
176 |
c = gpg_random_char (1); |
c = gpg_random_char (1); |
177 |
*p = c; |
*p = c; |
178 |
p++; |
p++; |
179 |
i++; |
i++; |
180 |
} |
} |
181 |
*p = '\0'; |
*p = '\0'; |
193 |
leave: |
leave: |
194 |
free_if_alloc (new_name); |
free_if_alloc (new_name); |
195 |
return rc; |
return rc; |
196 |
} /* rename_unlink */ |
} |
197 |
|
|
198 |
|
|
199 |
|
/* return the filesize as an 64-bit integer. */ |
200 |
static __int64 |
static __int64 |
201 |
GetFileSize64 (const char * path) |
GetFileSize64 (const char * path) |
202 |
{ |
{ |
203 |
FILE *fp = fopen (path, "r"); |
FILE *fp = fopen (path, "r"); |
204 |
if (fp) { |
if (fp) { |
205 |
struct _stati64 statbuf; |
struct _stati64 statbuf; |
206 |
_fstati64 (fileno (fp), &statbuf); |
if (_fstati64 (fileno (fp), &statbuf) == -1) |
207 |
|
return -1; |
208 |
fclose (fp); |
fclose (fp); |
209 |
return statbuf.st_size; |
return statbuf.st_size; |
210 |
} |
} |
211 |
return -1; |
return -1; |
212 |
} /* GetFileSize64 */ |
} |
213 |
|
|
214 |
|
|
215 |
static int |
static int |
231 |
ctx.filesize = GetFileSize64 (path); |
ctx.filesize = GetFileSize64 (path); |
232 |
if (!ctx.filesize) { |
if (!ctx.filesize) { |
233 |
free_if_alloc (ctx.buffer); |
free_if_alloc (ctx.buffer); |
234 |
return WPTERR_FILE_ZERO; |
unlink (path); |
235 |
|
return 0; |
236 |
} |
} |
237 |
|
|
238 |
ctx.fd = CreateFile (path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, |
ctx.fd = CreateFile (path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, |
239 |
OPEN_ALWAYS, 0, NULL); |
OPEN_ALWAYS, 0, NULL); |
240 |
if (ctx.fd == INVALID_HANDLE_VALUE) { |
if (ctx.fd == INVALID_HANDLE_VALUE) { |
241 |
free_if_alloc (ctx.buffer); |
free_if_alloc (ctx.buffer); |
313 |
return rename_unlink (path); |
return rename_unlink (path); |
314 |
} |
} |
315 |
|
|
316 |
|
|
317 |
|
/* Delete a file in a secure way with the given mode. */ |
318 |
int |
int |
319 |
secure_unlink (const char *path, int mode) |
secure_unlink (const char *path, int mode) |
320 |
{ |
{ |
321 |
return _secure_unlink (path, mode, NULL); |
return _secure_unlink (path, mode, NULL); |
322 |
} /* secure_unlink */ |
} |
|
|
|
323 |
|
|
324 |
|
|
325 |
|
/* Set the callback @cb for the wipe function. The callback is call every time |
326 |
|
the wipe function writes data to the file. */ |
327 |
void |
void |
328 |
secure_unlink_set_cb (void (*cb)(void *, const char *, int, unsigned, unsigned), |
secure_unlink_set_cb (void (*cb)(void *, const char *, int, int, int), |
329 |
void *cb_value) |
void *cb_value) |
330 |
{ |
{ |
331 |
unlink_cb = cb; |
unlink_cb = cb; |
332 |
unlink_cb_value = cb_value; |
unlink_cb_value = cb_value; |
333 |
} /* secure_unlink_set_cb */ |
} |
|
|
|
|
|
|
|
/* Windows 98 - Q188074 */ |
|
|
#define REGISTRY_FILESYSTEM "System\\CurrentControlSet\\Control\\FileSystem" |
|
|
#define REGISTRY_LOWDISKSPACE "DisableLowDiskSpaceBroadcast" |
|
|
|
|
|
|
|
|
/* disables the annoying warning Windows 98 displays when disk space is low */ |
|
|
static void |
|
|
handle_lowdiskspace_notify( const char * drive, int disable ) |
|
|
{ |
|
|
OSVERSIONINFO ov; |
|
|
HKEY key; |
|
|
DWORD n; |
|
|
|
|
|
memset( &ov, 0, sizeof ov ); |
|
|
ov.dwOSVersionInfoSize = sizeof ov; |
|
|
GetVersionEx( &ov ); |
|
|
if( ov.dwPlatformId == VER_PLATFORM_WIN32_NT ) |
|
|
return; |
|
|
|
|
|
if( disable ) { |
|
|
unsigned newi = (1 << (toupper((unsigned)drive) - (unsigned)'A')); |
|
|
if( RegOpenKey( HKEY_LOCAL_MACHINE, REGISTRY_FILESYSTEM, &key ) ) { |
|
|
n = sizeof newi; |
|
|
RegSetValue( key, REGISTRY_LOWDISKSPACE, REG_DWORD, (LPCTSTR)newi, n ); |
|
|
RegCloseKey( key ); |
|
|
} |
|
|
} |
|
|
else { |
|
|
if( RegOpenKey( HKEY_LOCAL_MACHINE, REGISTRY_FILESYSTEM, &key ) ) { |
|
|
RegDeleteKey( key, REGISTRY_LOWDISKSPACE ); |
|
|
RegCloseKey( key ); |
|
|
} |
|
|
} |
|
|
} /* handle_lowdiskspace_notify */ |
|
334 |
|
|
335 |
|
|
336 |
|
/* wipe all free space of the given drive by creating a temp file |
337 |
|
which has the size of the free space. This file will be then |
338 |
|
overwritten with random and static pattern. */ |
339 |
int |
int |
340 |
wipe_freespace (const char * drive, HANDLE *r_fd, |
wipe_freespace (const char * drive, HANDLE *r_fd, |
341 |
void (*cb)(void *, DDWORD, DDWORD), void * cb_value) |
void (*cb)(void *, DDWORD, DDWORD), void * cb_value) |
350 |
if (disktyp != DRIVE_FIXED && disktyp != DRIVE_REMOVABLE) |
if (disktyp != DRIVE_FIXED && disktyp != DRIVE_REMOVABLE) |
351 |
return -1; |
return -1; |
352 |
if (!GetDiskFreeSpaceEx (drive, &caller, &total, &frees)) |
if (!GetDiskFreeSpaceEx (drive, &caller, &total, &frees)) |
353 |
return -1; |
return -1; |
|
handle_lowdiskspace_notify (drive, 1); |
|
354 |
|
|
355 |
|
/* disk is full */ |
356 |
if (!frees.LowPart) |
if (!frees.LowPart) |
357 |
return WPTERR_FILE_ZERO; |
return 0; |
358 |
file = new char[strlen (drive)+8]; |
file = new char[strlen (drive)+8]; |
359 |
if (!file) |
if (!file) |
360 |
BUG (0); |
BUG (0); |
377 |
progress_cb_value = cb_value; |
progress_cb_value = cb_value; |
378 |
} |
} |
379 |
rc = _secure_unlink (file, WIPE_MODE_FAST, r_fd); |
rc = _secure_unlink (file, WIPE_MODE_FAST, r_fd); |
|
|
|
|
handle_lowdiskspace_notify (drive, 0); |
|
380 |
free_if_alloc (file); |
free_if_alloc (file); |
381 |
return rc; |
return rc; |
382 |
} /* wipe_freespace */ |
} |