/[winpt]/trunk/PTD/wptWipeFile.cpp
ViewVC logotype

Diff of /trunk/PTD/wptWipeFile.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by twoaday, Mon Jan 31 11:02:21 2005 UTC revision 46 by werner, Fri Oct 28 12:57:05 2005 UTC
# Line 1  Line 1 
1  /* wptWipeFile.cpp - Secure file removal  /* wptWipeFile.cpp - Secure file removal
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2005 Timo Schulz
3   *      Copyright (C) 2000 Matt Gauthier   *      Copyright (C) 2000 Matt Gauthier
4   *   *
5   * WinPT software; you can redistribute it and/or modify   * WinPT software; you can redistribute it and/or modify
6   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
7   * the Free Software Foundation; either version 2 of the License, or   * the Free Software Foundation; either version 2 of the License, or
8   * (at your option) any later version.   * (at your option) any later version.
9   *   *
10   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.   * GNU General Public License for more details.
14   *   *
15   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
16   * along with WinPT; if not, write to the Free Software   * along with WinPT; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18   *   *
19   **************************************************************************   **************************************************************************
20   * This code based on the sunlink.c file from the SRM project, but        *   * This code based on the sunlink.c file from the SRM project, but        *
21   * it was heavily modified to work with W32 and with added GCRYPT         *   * it was heavily modified to work with W32 and with added GCRYPT         *
22   * support for gathering random bytes.                                    *   * support for gathering random bytes.                                    *
23   *                                                                        *   *                                                                        *
24   * The original code was placed under the GNU Lesser Public License,      *   * The original code was placed under the GNU Lesser Public License,      *
25   * even so I decide to put this file under the GNU General Public License.*   * even so I decide to put this file under the GNU General Public License.*
26   **************************************************************************   **************************************************************************
27   */   */
28    
29  #include <windows.h>  #ifdef HAVE_CONFIG_H
30  #include <stdio.h>  #include <config.h>
31  #include <stdlib.h>  #endif
32  #include <sys/stat.h>  
33  #include <string.h>  #include <windows.h>
34  #include <ctype.h>  #include <windows.h>
35  #include <direct.h>  #include <stdio.h>
36    #include <stdlib.h>
37  #include "openpgp.h"  #include <sys/stat.h>
38  #include "wptW32API.h"  #include <string.h>
39  #include "wptErrors.h"  #include <ctype.h>
40  #include "wptTypes.h"  #include <direct.h>
41    
42    #include "openpgp.h"
43  typedef unsigned __int64 DDWORD;  #include "wptW32API.h"
44    #include "wptErrors.h"
45  typedef struct {  #include "wptTypes.h"
46      HANDLE fd;  #include "wptCrypto.h"
47      DDWORD filesize;  
48      DDWORD offset;  typedef unsigned __int64 DDWORD;
49      BYTE  *buffer;  
50      DWORD  buffsize;  typedef struct {
51      const char *name;      HANDLE fd;
52      int    n_passes;      DDWORD filesize;
53  } wipe_context_s;      DDWORD offset;
54        BYTE  *buffer;
55        DWORD  buffsize;
56  void (*progress_cb) (void *, DDWORD, DDWORD);      const char *name;
57  static void *progress_cb_value = NULL;      int    n_passes;
58    } wipe_context_s;
59  void (*unlink_cb)(void *, const char *, int, unsigned, unsigned) = NULL;  
60  static void *unlink_cb_value = NULL;  
61    void (*progress_cb) (void *, DDWORD, DDWORD);
62  static void  static void *progress_cb_value = NULL;
63  overwrite (wipe_context_s * ctx)  
64  {  void (*unlink_cb)(void *, const char *, int, int, int) = NULL;
65      DDWORD blocks = 0, mod = 0;  static void *unlink_cb_value = NULL;
66      DWORD nwritten = 0;  
67      LONG size_high = 0;  /* Use the file handle in the context to overwrite a file
68       with prepared buffer contents. */
69      blocks = ctx->filesize / ctx->buffsize;  static void
70      mod = ctx->filesize % ctx->buffsize;  overwrite (wipe_context_s *ctx)
71      SetFilePointer (ctx->fd, 0, &size_high, FILE_BEGIN);  {
72      while (blocks--) {      DDWORD blocks = 0, mod = 0;
73          if (!WriteFile (ctx->fd, ctx->buffer, ctx->buffsize, &nwritten, NULL))      DWORD nwritten = 0;
74              break;      LONG size_high = 0;
75          ctx->offset += nwritten;  
76          if (unlink_cb)      blocks = ctx->filesize / ctx->buffsize;
77              unlink_cb (unlink_cb_value, ctx->name, 0, (unsigned)ctx->offset,      mod = ctx->filesize % ctx->buffsize;
78                         (unsigned)ctx->filesize*ctx->n_passes);      SetFilePointer (ctx->fd, 0, &size_high, FILE_BEGIN);
79      }      while (blocks--) {
80      if (mod) {          if (!WriteFile (ctx->fd, ctx->buffer, ctx->buffsize, &nwritten, NULL))
81          WriteFile (ctx->fd, ctx->buffer, (DWORD)mod, &nwritten, NULL);              break;
82          ctx->offset += nwritten;          ctx->offset += nwritten;
83          if (unlink_cb)          if (unlink_cb)
84              unlink_cb (unlink_cb_value, ctx->name, 0, (unsigned)ctx->offset,              unlink_cb (unlink_cb_value, ctx->name, 0, (unsigned)ctx->offset,
85                         (unsigned)ctx->filesize*ctx->n_passes);                         (unsigned)ctx->filesize*ctx->n_passes);
86      }      }
87      FlushFileBuffers (ctx->fd);      if (mod) {
88      SetFilePointer (ctx->fd, 0, &size_high, FILE_BEGIN);          WriteFile (ctx->fd, ctx->buffer, (DWORD)mod, &nwritten, NULL);
89  } /* overwrite */          ctx->offset += nwritten;
90            if (unlink_cb)
91                unlink_cb (unlink_cb_value, ctx->name, 0, (unsigned)ctx->offset,
92  static void                         (unsigned)ctx->filesize*ctx->n_passes);
93  randomize_buffer (byte * buf, size_t bufsize, int level)      }
94  {      FlushFileBuffers (ctx->fd);
95      const int blocksize = 512;      SetFilePointer (ctx->fd, 0, &size_high, FILE_BEGIN);
96      int blocks = bufsize / blocksize;  }
97      int mod = bufsize % blocksize;  
98        
99      while (blocks--) {  /* fill the buffer with random of the given level. */
100          gpg_randomize (buf, blocksize, level);  static void
101          buf += blocksize;  randomize_buffer (byte *buf, size_t bufsize, int level)
102      }  {
103      if (mod)      const int blocksize = 512;
104          gpg_randomize (buf, mod, level);      int blocks = bufsize / blocksize;
105  } /* randomize_buffer */      int mod = bufsize % blocksize;
106        
107        while (blocks--) {
108  static void          gpg_randomize (buf, blocksize, level);
109  overwrite_random (int npasses, wipe_context_s * ctx)          buf += blocksize;
110  {            }
111      int i;      if (mod)
112                gpg_randomize (buf, mod, level);
113      for (i = 0; i < npasses; i++) {  }
114          randomize_buffer (ctx->buffer, ctx->buffsize, 0);  
115          overwrite (ctx);  
116      }  /* performs a random overwrite. */
117  } /* overwrite_random */  static void
118    overwrite_random (int npasses, wipe_context_s * ctx)
119    {      
120  static void      int i;
121  overwrite_byte (int byte, wipe_context_s * ctx)      
122  {      for (i = 0; i < npasses; i++) {
123      memset (ctx->buffer, byte, ctx->buffsize);          randomize_buffer (ctx->buffer, ctx->buffsize, 0);
124      overwrite (ctx);          overwrite (ctx);
125  } /* overwrite_byte */      }
126    }
127    
128  static void  
129  overwrite_bytes (int byte1, int byte2, int byte3, wipe_context_s * ctx)  /* perform an overwrite with a specific byte (like 0x00). */
130  {  static void
131      DWORD i;  overwrite_byte (int byte, wipe_context_s * ctx)
132    {
133      memset (ctx->buffer, byte1, ctx->buffsize);      memset (ctx->buffer, byte, ctx->buffsize);
134      for (i = 1; i < ctx->buffsize; i += 3) {      overwrite (ctx);
135          ctx->buffer[i] = byte2;  } /* overwrite_byte */
136          ctx->buffer[i+1] = byte3;  
137      }  
138      overwrite (ctx);  /* perform an overwrite with a specific byte triple (like 0x00, 0xFF, 0xAA). */
139  } /* overwrite_bytes */  static void
140    overwrite_bytes (int byte1, int byte2, int byte3, wipe_context_s * ctx)
141    {
142  /**      DWORD i;
143   * For the case the file is not a regular file (this is true for  
144   * devices or directories) this function tries to rename the file      memset (ctx->buffer, byte1, ctx->buffsize);
145   * to random pattern and then it will be delete (without random!).      for (i = 1; i < ctx->buffsize; i += 3) {
146   **/          ctx->buffer[i] = byte2;
147  int          ctx->buffer[i+1] = byte3;
148  rename_unlink (const char * path)      }
149  {      overwrite (ctx);
150      struct stat statbuf;  } /* overwrite_bytes */
151      char * new_name = NULL, * p = NULL, c;    
152      int i = 0, rc = 0;  
153      int is_dir = 0;  /* For the case the file is not a regular file (this is true for
154       devices or directories) this function tries to rename the file
155      if (GetFileAttributes (path) & FILE_ATTRIBUTE_DIRECTORY)     to random pattern and then it will be delete (without random!). */
156          is_dir = 1;  extern "C" int
157        rename_unlink (const char *path)
158      new_name = new char[strlen (path)+15];  {
159      if (!new_name)      struct stat statbuf;
160          BUG (0);      char *new_name = NULL, *p = NULL, c;  
161            int i = 0, rc = 0;
162      strcpy (new_name, path);      int is_dir = 0;
163      p = strrchr (new_name, '\\');  
164      if (p != NULL) {      if (GetFileAttributes (path) & FILE_ATTRIBUTE_DIRECTORY)
165          p++;          is_dir = 1;
166          *p = '\0';      
167      }      new_name = new char[strlen (path)+15];
168      else      if (!new_name)
169          p = new_name;          BUG (0);
170      do {      
171          while (i < 14) {      strcpy (new_name, path);
172              c = gpg_random_char (1);      p = strrchr (new_name, '\\');
173              *p = c;      if (p != NULL) {
174              p++;          p++;
175              i++;          *p = '\0';
176          }      }
177          *p = '\0';      else
178      } while (stat (new_name, &statbuf) == 0);          p = new_name;
179            do {
180      if (rename (path, new_name) == -1) {          while (i < 14) {
181          rc = WPTERR_FILE_READ;              c = gpg_random_char (1);
182          goto leave;              *p = c;
183      }              p++;
184      if (is_dir && RemoveDirectory (new_name) == FALSE)              i++;
185          rc = WPTERR_FILE_REMOVE;          }
186      else if (!DeleteFile (new_name))          *p = '\0';
187          rc = WPTERR_FILE_REMOVE;      } while (stat (new_name, &statbuf) == 0);
188            
189  leave:      if (rename (path, new_name) == -1) {
190      free_if_alloc (new_name);          rc = WPTERR_FILE_READ;
191      return rc;          goto leave;
192  } /* rename_unlink */      }
193        if (is_dir && RemoveDirectory (new_name) == FALSE)
194            rc = WPTERR_FILE_REMOVE;
195  static __int64      else if (!DeleteFile (new_name))
196  GetFileSize64 (const char * path)          rc = WPTERR_FILE_REMOVE;
197  {      
198      FILE *fp = fopen (path, "r");  leave:
199      if (fp) {      free_if_alloc (new_name);
200          struct _stati64 statbuf;      return rc;
201          _fstati64 (fileno (fp), &statbuf);  }
202          fclose (fp);  
203          return statbuf.st_size;  
204      }  /* return the filesize as an 64-bit integer. */
205      return -1;  static __int64
206  } /* GetFileSize64 */  GetFileSize64 (const char * path)
207    {
208        FILE *fp = fopen (path, "r");
209  static int      if (fp) {
210  _secure_unlink (const char * path, int mode, HANDLE *r_fd)          struct _stati64 statbuf;
211  {          if (_fstati64 (fileno (fp), &statbuf) == -1)
212      wipe_context_s ctx;              return -1;
213      LONG size_high = 0;          fclose (fp);
214                return statbuf.st_size;
215      if (GetFileAttributes (path) & FILE_ATTRIBUTE_DIRECTORY)      }
216          return rename_unlink (path);      return -1;
217        }
218      memset (&ctx, 0, sizeof (ctx));  
219      ctx.name = path;  
220      ctx.buffsize = 16384;  static int
221      ctx.buffer = new byte[ctx.buffsize];  _secure_unlink (const char * path, int mode, HANDLE *r_fd)
222      if (!ctx.buffer)  {
223          BUG (0);      wipe_context_s ctx;
224            LONG size_high = 0;
225      ctx.filesize = GetFileSize64 (path);      
226      if (!ctx.filesize) {      if (GetFileAttributes (path) & FILE_ATTRIBUTE_DIRECTORY)
227          free_if_alloc (ctx.buffer);          return rename_unlink (path);
228          return WPTERR_FILE_ZERO;      
229      }      memset (&ctx, 0, sizeof (ctx));
230        ctx.name = path;
231      ctx.fd = CreateFile (path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,      ctx.buffsize = 16384;
232                           OPEN_ALWAYS, 0, NULL);      ctx.buffer = new byte[ctx.buffsize];
233      if (ctx.fd == INVALID_HANDLE_VALUE) {      if (!ctx.buffer)
234          free_if_alloc (ctx.buffer);          BUG (0);
235          return WPTERR_FILE_OPEN;      
236      }      ctx.filesize = GetFileSize64 (path);
237      else if (r_fd)      if (!ctx.filesize) {
238          *r_fd = ctx.fd;          free_if_alloc (ctx.buffer);
239                unlink (path);
240      gpg_quick_random_gen (1);          return 0;
241      if (unlink_cb)      }
242          unlink_cb (unlink_cb_value, ctx.name, 0, 0, 0);  
243        ctx.fd = CreateFile (path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
244      switch (mode) {                           OPEN_ALWAYS, 0, NULL);
245      case WIPE_MODE_FAST:      if (ctx.fd == INVALID_HANDLE_VALUE) {
246          ctx.n_passes = 1;          free_if_alloc (ctx.buffer);
247          overwrite_random (1, &ctx);          return WPTERR_FILE_OPEN;
248          break;      }
249        else if (r_fd)
250      case WIPE_MODE_SIMPLE:          *r_fd = ctx.fd;
251          ctx.n_passes = 2;      
252          overwrite_random (2, &ctx);      gpg_quick_random_gen (1);
253          break;      if (unlink_cb)
254                    unlink_cb (unlink_cb_value, ctx.name, 0, 0, 0);
255      case WIPE_MODE_DOD:  
256          ctx.n_passes = 5;      switch (mode) {
257          overwrite_random (1, &ctx);      case WIPE_MODE_FAST:
258          overwrite_byte ((~1) & 0xFF, &ctx);          ctx.n_passes = 1;
259          overwrite_random (1, &ctx);          overwrite_random (1, &ctx);
260          overwrite_byte ((~4) & 0xFF, &ctx);          break;
261          overwrite_random (1, &ctx);  
262          break;      case WIPE_MODE_SIMPLE:
263                    ctx.n_passes = 2;
264      case WIPE_MODE_GUTMANN:          overwrite_random (2, &ctx);
265          ctx.n_passes = 39;          break;
266          overwrite_random (4, &ctx);          
267          overwrite_byte( 0x55, &ctx );      case WIPE_MODE_DOD:
268          overwrite_byte ( 0xAA, &ctx );          ctx.n_passes = 5;
269          overwrite_bytes( 0x92, 0x49, 0x24, &ctx );          overwrite_random (1, &ctx);
270          overwrite_bytes( 0x49, 0x24, 0x92, &ctx );          overwrite_byte ((~1) & 0xFF, &ctx);
271          overwrite_bytes( 0x24, 0x92, 0x49, &ctx );          overwrite_random (1, &ctx);
272          overwrite_byte( 0x00, &ctx );          overwrite_byte ((~4) & 0xFF, &ctx);
273          overwrite_byte( 0x11, &ctx );          overwrite_random (1, &ctx);
274          overwrite_byte( 0x22, &ctx );          break;
275          overwrite_byte( 0x33, &ctx );          
276          overwrite_byte( 0x44, &ctx );      case WIPE_MODE_GUTMANN:
277          overwrite_byte( 0x55, &ctx );          ctx.n_passes = 39;
278          overwrite_byte( 0x66, &ctx );          overwrite_random (4, &ctx);
279          overwrite_byte( 0x77, &ctx );          overwrite_byte( 0x55, &ctx );
280          overwrite_byte( 0x88, &ctx );          overwrite_byte ( 0xAA, &ctx );
281          overwrite_byte( 0x99, &ctx );          overwrite_bytes( 0x92, 0x49, 0x24, &ctx );
282          overwrite_byte( 0xAA, &ctx );          overwrite_bytes( 0x49, 0x24, 0x92, &ctx );
283          overwrite_byte( 0xBB, &ctx );          overwrite_bytes( 0x24, 0x92, 0x49, &ctx );
284          overwrite_byte( 0xCC, &ctx );          overwrite_byte( 0x00, &ctx );
285          overwrite_byte( 0xDD, &ctx );          overwrite_byte( 0x11, &ctx );
286          overwrite_byte( 0xEE, &ctx );          overwrite_byte( 0x22, &ctx );
287          overwrite_byte( 0xFF, &ctx );          overwrite_byte( 0x33, &ctx );
288          overwrite_bytes( 0x92, 0x49, 0x24, &ctx );          overwrite_byte( 0x44, &ctx );
289          overwrite_bytes( 0x49, 0x24, 0x92, &ctx );          overwrite_byte( 0x55, &ctx );
290          overwrite_bytes( 0x24, 0x92, 0x49, &ctx );          overwrite_byte( 0x66, &ctx );
291          overwrite_bytes( 0x6D, 0xB6, 0xDB, &ctx );          overwrite_byte( 0x77, &ctx );
292          overwrite_bytes( 0xB6, 0xDB, 0x6D, &ctx );          overwrite_byte( 0x88, &ctx );
293          overwrite_bytes( 0xDB, 0x6D, 0xB6, &ctx );          overwrite_byte( 0x99, &ctx );
294          overwrite_random( 4, &ctx );          overwrite_byte( 0xAA, &ctx );
295          break;          overwrite_byte( 0xBB, &ctx );
296      }          overwrite_byte( 0xCC, &ctx );
297                    overwrite_byte( 0xDD, &ctx );
298      /* Set file length to zero so allocated clusters cannot be trailed */                overwrite_byte( 0xEE, &ctx );
299      SetFilePointer (ctx.fd, 0, &size_high, FILE_BEGIN);          overwrite_byte( 0xFF, &ctx );
300      SetEndOfFile (ctx.fd);          overwrite_bytes( 0x92, 0x49, 0x24, &ctx );
301      CloseHandle (ctx.fd);          overwrite_bytes( 0x49, 0x24, 0x92, &ctx );
302                overwrite_bytes( 0x24, 0x92, 0x49, &ctx );
303      memset (ctx.buffer, 0, ctx.buffsize); /* burn the last evidence */            overwrite_bytes( 0x6D, 0xB6, 0xDB, &ctx );
304      free_if_alloc (ctx.buffer);          overwrite_bytes( 0xB6, 0xDB, 0x6D, &ctx );
305            overwrite_bytes( 0xDB, 0x6D, 0xB6, &ctx );
306      return rename_unlink (path);          overwrite_random( 4, &ctx );
307  }          break;
308        }
309  int          
310  secure_unlink (const char *path, int mode)      /* Set file length to zero so allocated clusters cannot be trailed */      
311  {      SetFilePointer (ctx.fd, 0, &size_high, FILE_BEGIN);
312      return _secure_unlink (path, mode, NULL);      SetEndOfFile (ctx.fd);
313  } /* secure_unlink */      CloseHandle (ctx.fd);
314        
315        memset (ctx.buffer, 0, ctx.buffsize); /* burn the last evidence */  
316        free_if_alloc (ctx.buffer);
317  void  
318  secure_unlink_set_cb (void (*cb)(void *, const char *, int, unsigned, unsigned),      return rename_unlink (path);
319                        void *cb_value)  }
320  {  
321      unlink_cb = cb;  
322      unlink_cb_value = cb_value;  /* Delete a file in a secure way with the given mode. */
323  } /* secure_unlink_set_cb */  extern "C" int
324    secure_unlink (const char *path, int mode)
325    {
326  /* Windows 98 - Q188074 */      return _secure_unlink (path, mode, NULL);
327  #define REGISTRY_FILESYSTEM "System\\CurrentControlSet\\Control\\FileSystem"  }
328  #define REGISTRY_LOWDISKSPACE "DisableLowDiskSpaceBroadcast"  
329    
330    /* Set the callback @cb for the wipe function. The callback is call every time
331  /* disables the annoying warning Windows 98 displays when disk space is low */     the wipe function writes data to the file. */
332  static void  extern "C" void
333  handle_lowdiskspace_notify( const char * drive, int disable )  secure_unlink_set_cb (void (*cb)(void *, const char *, int, int, int),
334  {                            void *cb_value)
335      OSVERSIONINFO ov;  {
336      HKEY key;      unlink_cb = cb;
337      DWORD n;      unlink_cb_value = cb_value;
338    }
339      memset( &ov, 0, sizeof ov );  
340      ov.dwOSVersionInfoSize = sizeof ov;  
341      GetVersionEx( &ov );  /* wipe all free space of the given drive by creating a temp file
342      if( ov.dwPlatformId == VER_PLATFORM_WIN32_NT )     which has the size of the free space. This file will be then
343          return;     overwritten with random and static pattern. */
344    extern "C" int
345      if( disable ) {  wipe_freespace (const char * drive, HANDLE *r_fd,
346          unsigned newi = (1 << (toupper((unsigned)drive) - (unsigned)'A'));                  void (*cb)(void *, DDWORD, DDWORD), void * cb_value)
347          if( RegOpenKey( HKEY_LOCAL_MACHINE, REGISTRY_FILESYSTEM, &key ) ) {  {
348              n = sizeof newi;      ULARGE_INTEGER caller, total, frees;
349              RegSetValue( key, REGISTRY_LOWDISKSPACE, REG_DWORD, (LPCTSTR)newi, n );      LONG hpart=0;
350              RegCloseKey( key );      HANDLE fd;
351          }      int disktyp = GetDriveType (drive);
352      }      int rc;
353      else {      char * file;
354          if( RegOpenKey( HKEY_LOCAL_MACHINE, REGISTRY_FILESYSTEM, &key ) ) {  
355              RegDeleteKey( key, REGISTRY_LOWDISKSPACE );      if (disktyp != DRIVE_FIXED && disktyp != DRIVE_REMOVABLE)
356              RegCloseKey( key );          return -1;
357          }      if (!GetDiskFreeSpaceEx (drive, &caller, &total, &frees))
358      }          return -1;  
359  } /* handle_lowdiskspace_notify */  
360        /* disk is full */
361        if (!frees.LowPart)
362  int          return 0;
363  wipe_freespace (const char * drive, HANDLE *r_fd,      file = new char[strlen (drive)+8];
364                  void (*cb)(void *, DDWORD, DDWORD), void * cb_value)      if (!file)
365  {          BUG (0);
366      ULARGE_INTEGER caller, total, frees;      sprintf (file, "%stemp_winpt.tmp", drive);
367      LONG hpart=0;      fd = CreateFile (file,
368      HANDLE fd;                      GENERIC_READ|GENERIC_WRITE,
369      int disktyp = GetDriveType (drive);                      FILE_SHARE_READ|FILE_SHARE_WRITE,
370      int rc;                      NULL, CREATE_ALWAYS, 0, NULL);
371      char * file;      if (fd == INVALID_HANDLE_VALUE) {
372            free_if_alloc (file);
373      if (disktyp != DRIVE_FIXED && disktyp != DRIVE_REMOVABLE)          return WPTERR_FILE_OPEN;
374          return -1;      }
375      if (!GetDiskFreeSpaceEx (drive, &caller, &total, &frees))      hpart = frees.HighPart;
376          return -1;      SetFilePointer (fd, frees.LowPart, &hpart, FILE_BEGIN);
377      handle_lowdiskspace_notify (drive, 1);      SetEndOfFile (fd);
378        CloseHandle (fd);
379      if (!frees.LowPart)  
380          return WPTERR_FILE_ZERO;      if (cb && cb_value) {
381      file = new char[strlen (drive)+8];          progress_cb = cb;
382      if (!file)          progress_cb_value = cb_value;
383          BUG (0);      }
384      sprintf (file, "%stemp_winpt.tmp", drive);      rc = _secure_unlink (file, WIPE_MODE_FAST, r_fd);
385      fd = CreateFile (file,      free_if_alloc (file);
386                      GENERIC_READ|GENERIC_WRITE,      return rc;
387                      FILE_SHARE_READ|FILE_SHARE_WRITE,  }
                     NULL, CREATE_ALWAYS, 0, NULL);  
     if (fd == INVALID_HANDLE_VALUE) {  
         free_if_alloc (file);  
         return WPTERR_FILE_OPEN;  
     }  
     hpart = frees.HighPart;  
     SetFilePointer (fd, frees.LowPart, &hpart, FILE_BEGIN);  
     SetEndOfFile (fd);  
     CloseHandle (fd);  
   
     if (cb && cb_value) {  
         progress_cb = cb;  
         progress_cb_value = cb_value;  
     }  
     rc = _secure_unlink (file, WIPE_MODE_FAST, r_fd);  
   
     handle_lowdiskspace_notify (drive, 0);  
     free_if_alloc (file);  
     return rc;  
 } /* wipe_freespace */  

Legend:
Removed from v.2  
changed lines
  Added in v.46

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26