Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Completely delete a file

Completely delete a file

Scheduled Pinned Locked Moved C#
questionloungelearning
16 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Johan Martensson

    Wiping the last sector might help, but I'm not sure how I would implement such a thing. I have only worked with filestreams and I have no idea how to read/write directly to the sectors, so could you point me in a direction of how to do that? I guess what I'm looking for now is a way to get the exact sectors that a file occupies and write to those. From what I understand I should probably look at the W32 API functions ReadFile/WriteFile but I havent been able to find any C# examples.

    http://johanmartensson.se - Home of MPEG4Watcher

    P Offline
    P Offline
    PIEBALDconsult
    wrote on last edited by
    #7

    double sectors = System.Math.Ceiling ( filelength / 512 ) ; ought to work. Whoops, I mean 512.0

    modified on Friday, January 04, 2008 12:17:33 PM

    J 1 Reply Last reply
    0
    • P PIEBALDconsult

      double sectors = System.Math.Ceiling ( filelength / 512 ) ; ought to work. Whoops, I mean 512.0

      modified on Friday, January 04, 2008 12:17:33 PM

      J Offline
      J Offline
      Johan Martensson
      wrote on last edited by
      #8

      That gives me the total number of sectors a file occupies, right? So I should still find a way to figure out which sectors the file occupies and find out how to write some random data do those specific sectors?

      http://johanmartensson.se - Home of MPEG4Watcher

      P 1 Reply Last reply
      0
      • J Johan Martensson

        That gives me the total number of sectors a file occupies, right? So I should still find a way to figure out which sectors the file occupies and find out how to write some random data do those specific sectors?

        http://johanmartensson.se - Home of MPEG4Watcher

        P Offline
        P Offline
        PIEBALDconsult
        wrote on last edited by
        #9

        No, the operating system knows them.

        J 1 Reply Last reply
        0
        • P PIEBALDconsult

          No, the operating system knows them.

          J Offline
          J Offline
          Johan Martensson
          wrote on last edited by
          #10

          So I have cleaned up the code a bit and created a fixed buffer instead (which I should have done from the start :)) The wiping of the entire last sector works fine, a text-file that was 18 bytes showed up as 512 bytes when recovered, with garbage data in it of course, so thanks for that one. But then again, having the lines below before deleting the file, it shows up as 0 bytes when recovered.

          FileStream tmpStream = new FileStream(filename, FileMode.Create);
          tmpStream.Close();

          Now I only have to get rid of the filename that shows up when trying to recover the file. I did try to rename it but that didn't work, I think it has to do with the fact that it's moved, is there really no other way of renaming files in C#? Current code:

          private void WipeFile(string filename, int timesToWrite)
          {
          if(File.Exists(filename))
          {
          byte[] dummyBuffer = new byte[512];
          RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
          rng.GetBytes(dummyBuffer);

              double filelength = new FileInfo(filename).Length;
              double sectors = System.Math.Ceiling(filelength / 512);
          
              for (int timesWritten = 0; timesWritten < timesToWrite; timesWritten++)
              {
                  FileStream inputStream = new FileStream(filename, FileMode.Open, FileAccess.Write, FileShare.None);                                         
          
                  int sectorsWritten = 0;
                  while (sectorsWritten < sectors)
                  {
                      inputStream.Write(dummyBuffer, 0, dummyBuffer.Length);
                      rng.GetBytes(dummyBuffer);
                      sectorsWritten++;
                  }
          
                  inputStream.Close();
              }
          
              FileStream tmpStream = new FileStream(filename, FileMode.Create);
              tmpStream.Close();
          
              File.Delete(filename);
          }
          

          }

          http://johanmartensson.se - Home of MPEG4Watcher

          modified on Friday, January 04, 2008 6:33:34 PM

          P 1 Reply Last reply
          0
          • J Johan Martensson

            So I have cleaned up the code a bit and created a fixed buffer instead (which I should have done from the start :)) The wiping of the entire last sector works fine, a text-file that was 18 bytes showed up as 512 bytes when recovered, with garbage data in it of course, so thanks for that one. But then again, having the lines below before deleting the file, it shows up as 0 bytes when recovered.

            FileStream tmpStream = new FileStream(filename, FileMode.Create);
            tmpStream.Close();

            Now I only have to get rid of the filename that shows up when trying to recover the file. I did try to rename it but that didn't work, I think it has to do with the fact that it's moved, is there really no other way of renaming files in C#? Current code:

            private void WipeFile(string filename, int timesToWrite)
            {
            if(File.Exists(filename))
            {
            byte[] dummyBuffer = new byte[512];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(dummyBuffer);

                double filelength = new FileInfo(filename).Length;
                double sectors = System.Math.Ceiling(filelength / 512);
            
                for (int timesWritten = 0; timesWritten < timesToWrite; timesWritten++)
                {
                    FileStream inputStream = new FileStream(filename, FileMode.Open, FileAccess.Write, FileShare.None);                                         
            
                    int sectorsWritten = 0;
                    while (sectorsWritten < sectors)
                    {
                        inputStream.Write(dummyBuffer, 0, dummyBuffer.Length);
                        rng.GetBytes(dummyBuffer);
                        sectorsWritten++;
                    }
            
                    inputStream.Close();
                }
            
                FileStream tmpStream = new FileStream(filename, FileMode.Create);
                tmpStream.Close();
            
                File.Delete(filename);
            }
            

            }

            http://johanmartensson.se - Home of MPEG4Watcher

            modified on Friday, January 04, 2008 6:33:34 PM

            P Offline
            P Offline
            PIEBALDconsult
            wrote on last edited by
            #11

            Better. Rather than opening and closing the stream each time you could set the Position back to 0. (Flushing might be required.) I'd eliminate the needless local variable filelength (but maybe that's just me). Shouldn't there be a way to truncate a file? As to the filename; I suspect anyone snooping for data will bypass the FAT (or whatever) and access the disk more directly so I wouldn't be too concerned about it. At one point I wanted to recover some files from a 5.25" floppy with a corrupted FAT. Using DOS 6 and "Function 440Dh Minor Code 61h Read Track on Logical Drive" I was able to do so. That article to which I gave you a link talks about more advanced snooping techniquse than that.

            J 1 Reply Last reply
            0
            • P PIEBALDconsult

              Better. Rather than opening and closing the stream each time you could set the Position back to 0. (Flushing might be required.) I'd eliminate the needless local variable filelength (but maybe that's just me). Shouldn't there be a way to truncate a file? As to the filename; I suspect anyone snooping for data will bypass the FAT (or whatever) and access the disk more directly so I wouldn't be too concerned about it. At one point I wanted to recover some files from a 5.25" floppy with a corrupted FAT. Using DOS 6 and "Function 440Dh Minor Code 61h Read Track on Logical Drive" I was able to do so. That article to which I gave you a link talks about more advanced snooping techniquse than that.

              J Offline
              J Offline
              Johan Martensson
              wrote on last edited by
              #12

              The filestream has the ability to truncate...

              FileStream tmpStream = new FileStream(filename, FileMode.Truncate);
              tmpStream.Close();

              but I get the same result using

              FileStream tmpStream = new FileStream(filename, FileMode.Create);
              tmpStream.Close();

              I'm not really sure what the difference is, they booth create a zero-byte file.

              http://johanmartensson.se - Home of MPEG4Watcher

              P 1 Reply Last reply
              0
              • J Johan Martensson

                The filestream has the ability to truncate...

                FileStream tmpStream = new FileStream(filename, FileMode.Truncate);
                tmpStream.Close();

                but I get the same result using

                FileStream tmpStream = new FileStream(filename, FileMode.Create);
                tmpStream.Close();

                I'm not really sure what the difference is, they booth create a zero-byte file.

                http://johanmartensson.se - Home of MPEG4Watcher

                P Offline
                P Offline
                PIEBALDconsult
                wrote on last edited by
                #13

                I was hoping it could be truncated after it's been opened. That second one will (may?) create the new file in a different spot on the disk.

                J 1 Reply Last reply
                0
                • P PIEBALDconsult

                  I was hoping it could be truncated after it's been opened. That second one will (may?) create the new file in a different spot on the disk.

                  J Offline
                  J Offline
                  Johan Martensson
                  wrote on last edited by
                  #14

                  After a little digging I found the FileStream.SetLength Method which truncates the file if the given value is less than the current length. After using the code below, when trying to recover the file, I end up with a zero-byte file with the dates set to January 2037 and the space on the disc where the file used to be is filled with garbage. So what's accomplished now is, the file is overwritten with garbage data n times, the original filesize and dates removed. Even though the filename will keep haunting me and I'll keep looking for a solution, I believe the file is pretty much wiped out and can't be recovered with any standard methods.

                  private void WipeFile(string filename, int timesToWrite)
                  {
                  if(File.Exists(filename))
                  {
                  File.SetAttributes(filename, FileAttributes.Normal);

                      double sectors = System.Math.Ceiling(new FileInfo(filename).Length / 512.0);
                      byte\[\] dummyBuffer = new byte\[512\];
                  
                      RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                      rng.GetBytes(dummyBuffer);
                  
                      FileStream inputStream = new FileStream(filename, FileMode.Open);
                      for (int timesWritten = 0; timesWritten < timesToWrite; timesWritten++)
                      {
                          inputStream.Position = 0;
                          int sectorsWritten = 0;
                          while (sectorsWritten < sectors)
                          {
                              inputStream.Write(dummyBuffer, 0, dummyBuffer.Length);
                              rng.GetBytes(dummyBuffer);
                              sectorsWritten++;
                          }
                      }
                      inputStream.SetLength(0);
                      inputStream.Close();
                  
                      DateTime dt = new DateTime(2037, 1, 1, 0, 0, 0);
                      File.SetCreationTime(filename, dt);
                      File.SetLastAccessTime(filename, dt);
                      File.SetLastWriteTime(filename, dt);
                  
                      File.Delete(filename);
                  }
                  

                  }

                  http://johanmartensson.se - Home of MPEG4Watcher

                  P 1 Reply Last reply
                  0
                  • J Johan Martensson

                    After a little digging I found the FileStream.SetLength Method which truncates the file if the given value is less than the current length. After using the code below, when trying to recover the file, I end up with a zero-byte file with the dates set to January 2037 and the space on the disc where the file used to be is filled with garbage. So what's accomplished now is, the file is overwritten with garbage data n times, the original filesize and dates removed. Even though the filename will keep haunting me and I'll keep looking for a solution, I believe the file is pretty much wiped out and can't be recovered with any standard methods.

                    private void WipeFile(string filename, int timesToWrite)
                    {
                    if(File.Exists(filename))
                    {
                    File.SetAttributes(filename, FileAttributes.Normal);

                        double sectors = System.Math.Ceiling(new FileInfo(filename).Length / 512.0);
                        byte\[\] dummyBuffer = new byte\[512\];
                    
                        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                        rng.GetBytes(dummyBuffer);
                    
                        FileStream inputStream = new FileStream(filename, FileMode.Open);
                        for (int timesWritten = 0; timesWritten < timesToWrite; timesWritten++)
                        {
                            inputStream.Position = 0;
                            int sectorsWritten = 0;
                            while (sectorsWritten < sectors)
                            {
                                inputStream.Write(dummyBuffer, 0, dummyBuffer.Length);
                                rng.GetBytes(dummyBuffer);
                                sectorsWritten++;
                            }
                        }
                        inputStream.SetLength(0);
                        inputStream.Close();
                    
                        DateTime dt = new DateTime(2037, 1, 1, 0, 0, 0);
                        File.SetCreationTime(filename, dt);
                        File.SetLastAccessTime(filename, dt);
                        File.SetLastWriteTime(filename, dt);
                    
                        File.Delete(filename);
                    }
                    

                    }

                    http://johanmartensson.se - Home of MPEG4Watcher

                    P Offline
                    P Offline
                    PIEBALDconsult
                    wrote on last edited by
                    #15

                    Excellent! Now I've learned something too. :-D Now, remove the first rng.GetBytes(dummyBuffer); and swap the lines: inputStream.Write(dummyBuffer, 0, dummyBuffer.Length); rng.GetBytes(dummyBuffer); Perhaps use a for loop rather than a while loop (both loops might as well be the same type as they do similar things).

                    J 1 Reply Last reply
                    0
                    • P PIEBALDconsult

                      Excellent! Now I've learned something too. :-D Now, remove the first rng.GetBytes(dummyBuffer); and swap the lines: inputStream.Write(dummyBuffer, 0, dummyBuffer.Length); rng.GetBytes(dummyBuffer); Perhaps use a for loop rather than a while loop (both loops might as well be the same type as they do similar things).

                      J Offline
                      J Offline
                      Johan Martensson
                      wrote on last edited by
                      #16

                      I just wanted to say thanks for your help... I have put together an article in case someone else have any use for this function. http://www.codeproject.com/KB/cs/SharpWipe.aspx[^]

                      http://johanmartensson.se - Home of MPEG4Watcher

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups