The MASM Forum Archive 2004 to 2012

Project Support Forums => IDE Development and Support => Easy Code => Topic started by: Bieb on January 19, 2005, 10:57:41 PM

Title: File Shredder
Post by: Bieb on January 19, 2005, 10:57:41 PM
Okay, I'm working on a simple file shredder program.  Currently, all it does is take a filename in an EditBox, fill the file with useless data, close the file, and delete the file.  However, my code is just crashing, not doing anything useful.

The code, taken out of on Easy Code project with an Edit Box (IDC_WINDOW1_FILEBOX) and a button (IDC_WINDOW1_SHREDBUTTON) is as follows.


.Const

.Data?
FilePath Byte 200 Dup (?)
hFile DWord ?
FileBoxHandle HWND ?
hWord Word ?
lWord Word ?
.Data
DataByte DB 01010101B
.Code

Window1Procedure Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
.If uMsg == WM_CREATE
Invoke GetWindowItem, hWnd, IDC_WINDOW1_FILEBOX
Mov Eax, FileBoxHandle

.ElseIf uMsg == WM_COMMAND
Mov Eax, wParam
.If Ax == IDC_WINDOW1_SHREDBUTTON
Shr Eax, 16
.If Ax == BN_CLICKED
Invoke GetText, FileBoxHandle, Addr FilePath
Invoke CreateFile, Addr FilePath, GENERIC_READ Or GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
Mov hFile, Eax
Invoke GetFileSize, hFile, hWord
Mov Ebx, Eax
LoopLabel:
Invoke WriteFile, hFile, DataByte, 1, NULL, NULL
Dec Ebx
Jnz LoopLabel
Invoke CloseHandle, hFile
Invoke DeleteFile, Addr FilePath

.EndIf
.EndIf

.ElseIf uMsg == WM_CLOSE
Invoke IsModal, hWnd
.If Eax
Invoke EndModal, hWnd, IDCANCEL
Return TRUE
.EndIf
.Endif
Return FALSE
Window1Procedure EndP



Window1FileBox Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
Return FALSE
Window1FileBox EndP


If it's of any help, I've also attached the entire project.

[attachment deleted by admin]
Title: Re: File Shredder
Post by: petezl on January 20, 2005, 12:12:53 AM
Hi Bleb,
Sorry, I don't understand that easycode stuff but you seem to have a missing value "PassWord="
Peter.
Title: Re: File Shredder
Post by: pbrennick on January 20, 2005, 12:30:38 AM
Bieb,
At a quick glance, shouldn't

Mov  Eax, FileBoxHandle

be

Mov   FileBoxHandle, Eax

Paul
Title: Re: File Shredder
Post by: Relvinian on January 20, 2005, 01:06:47 AM
The things I noticed which may or may not cause problems are:

Not checking return values on API calls (specifically, CreateFile).  If the filename specifiy doesn't exist, you are still trying to write data to it.
Once you open the file for writing, usuallly, it is best to always set the file position before writing unless you ALWAYS want to write at the beginning.

You are using the EBX register without preserving it.

At the top of your code, you are trying to move the FileBoxHandle into EAX.  Should be the other way around

Your buffer for the filename is only 200 bytes -- is that enoug.  Should be big enough to hold MAX_PATH (which is 260 btw).


Hope this helps.

Relvinian

Title: Re: File Shredder
Post by: Bieb on January 20, 2005, 02:19:38 AM
Okay, for anyone who doesn't know, the purpose of this code is to delete a file in such a way that it can't be recovered.  This doesn't do a very good job of it, but I can take care of that once I have the groundwork done.  I fixed the inverted Mov operands, and used Ecx instead of Ebx, and I ended up with this code.


.Const

.Data?
FilePath Byte 200 Dup (?)
hFile DWord ?
FileBoxHandle HWND ?
hWord Word ?
lWord Word ?
.Data
DataByte DB 01010101B
mbText DB "The file has been shredded", 0
mbCaption DB "Done", 0
.Code

Window1Procedure Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
.If uMsg == WM_CREATE
Invoke GetWindowItem, hWnd, IDC_WINDOW1_FILEBOX
Mov FileBoxHandle, Eax

.ElseIf uMsg == WM_COMMAND
Mov Eax, wParam
.If Ax == IDC_WINDOW1_SHREDBUTTON
Shr Eax, 16
.If Ax == BN_CLICKED
Invoke GetText, FileBoxHandle, Addr FilePath
Invoke MessageBox, NULL, Addr FilePath, Addr FilePath, MB_OK
Invoke CreateFile, Addr FilePath, GENERIC_READ Or GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
Mov hFile, Eax
Invoke GetFileSize, hFile, hWord
Mov Ecx, Eax
Dec Ecx
LoopLabel:
Invoke WriteFile, hFile, DataByte, 1, NULL, NULL
Dec Ecx
Jnz LoopLabel
Invoke CloseHandle, hFile
Invoke DeleteFile, Addr FilePath
Invoke MessageBox, NULL, Addr mbText, Addr mbCaption, MB_OK

.EndIf
.EndIf

.ElseIf uMsg == WM_CLOSE
Invoke IsModal, hWnd
.If Eax
Invoke EndModal, hWnd, IDCANCEL
Return TRUE
.EndIf
.Endif
Return FALSE
Window1Procedure EndP



Window1FileBox Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
Return FALSE
Window1FileBox EndP


In this, I added two message boxes to confirm the program's operation.  The first to verify that it got the file name alright, and the second to notify me it has finished it's work.  I gave it a valid file name, and I get that back in the first confirmation message box, but the program crashes somewhere between the first and second message boxes, with no changes having been made to the file.  Any ideas?
Title: Re: File Shredder
Post by: tenkey on January 20, 2005, 02:51:41 AM
Now that you're using ECX, you've got the other register preservation problem. WriteFile doesn't guarantee that ECX will remain unchanged.

WriteFile requires the address of a data buffer. But you are passing the actual data (+ extra bytes), and it's being treated as an address. Add the ADDR operator. I believe you also need to provide a valid address for the lpNumberOfBytesWritten argument.

Invoke WriteFile, hFile, Addr DataByte, 1, Addr dwBytesWritten, NULL

.data?
dwBytesWritten DWord ?
Title: Re: File Shredder
Post by: hutch-- on January 20, 2005, 03:00:16 AM
Bieb,

You buy yourself a lot of grief trying to use registers as variables mixed with HLL API calls. You would bother if there was some gain but in this context there is not, its a technique best used in algo design where you are mainly working in registers and instructions only.

What I would suggest is simply make some LOCAL variables that hold the return values and then you don't have the register overwrite problem. Also note that if you are only using a variable within one procedure, there is no point putting it in the .DATA(?) section and you keep the procedure self contained by using a LOCAL where you can.
Title: Re: File Shredder
Post by: Bieb on January 20, 2005, 03:31:18 AM
Alright, I'll go and do all that LOCAL stuff once I've gotten the basic concept working.  Here's a version that works with only two flaws


.Const

.Data?
FilePath Byte 200 Dup (?)
hFile DWord ?
FileBoxHandle HWND ?
hWord Word ?
lWord Word ?
ByteWrite DWord ?
.Data
DataByte DB 01010101B
mbText DB "The file has been shredded", 0
mbCaption DB "Done", 0
.Code

Window1Procedure Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
.If uMsg == WM_CREATE
Invoke GetWindowItem, hWnd, IDC_WINDOW1_FILEBOX
Mov FileBoxHandle, Eax

.ElseIf uMsg == WM_COMMAND
Mov Eax, wParam
.If Ax == IDC_WINDOW1_SHREDBUTTON
Shr Eax, 16
.If Ax == BN_CLICKED
Invoke GetText, FileBoxHandle, Addr FilePath
Invoke MessageBox, NULL, Addr FilePath, Addr FilePath, MB_OK
Invoke CreateFile, Addr FilePath, GENERIC_READ Or GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
.If Eax == INVALID_HANDLE_VALUE
Invoke MessageBox, NULL, Addr FilePath, Addr FilePath, MB_OK
.EndIf
Mov hFile, Eax
Invoke GetFileSize, hFile, hWord
Mov Ecx, 53 ; Hard coded file length
Dec Ecx
LoopLabel:
Push Ecx
Invoke WriteFile, hFile, Addr DataByte, 1, Addr ByteWrite, NULL
Pop Ecx
Dec Ecx
Jnz LoopLabel
Invoke CloseHandle, hFile
Invoke DeleteFile, Addr FilePath
Invoke MessageBox, NULL, Addr mbText, Addr mbCaption, MB_OK

.EndIf
.EndIf

.ElseIf uMsg == WM_CLOSE
Invoke IsModal, hWnd
.If Eax
Invoke EndModal, hWnd, IDCANCEL
Return TRUE
.EndIf
.Endif
Return FALSE
Window1Procedure EndP



Window1FileBox Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
Return FALSE
Window1FileBox EndP


The most important one is that my GetFileLength call isn't working right.  Unless I hard code the length of the file into the program, it goes into an endless loop, and the file just keeps getting bigger.  The other is, once it's finished it all, the call to DeleteFile isn't doing anything.
Title: Re: File Shredder
Post by: pbrennick on January 20, 2005, 04:53:35 AM
Bieb,
In reference to the GetFileSize call, iif it fails Eax will contain 0xFFFFFFFFh, that is why the file keeps growing.  If this is happening then the problem has to be with hFile.
Paul
Title: Re: File Shredder
Post by: pbrennick on January 20, 2005, 05:02:42 AM
I also think that

FilePath Byte 200 Dup (?)

should be

FilePath Byte 200 Dup (0)  (and move it from the .Data? section to the .Data  section)

That makes sure that there is a null terminator at the end of the filename, this is probably why DeleteFile is not working.

Paul
Title: Re: File Shredder
Post by: Ramon Sala on January 20, 2005, 10:59:04 AM
Hi Bieb,

I found the problem in your code. Here's the code that works (file is attached):


.Const

.Data?
FilePath Byte 200 Dup (?)
hFile DWord ?
FileBoxHandle HWND ?
hWord DWord ?
lWord DWord ?
ByteWrite DWord ?
.Data
DataByte DB 01010101B
mbText DB "The file has been shredded", 0
mbCaption DB "Done", 0
.Code

Window1Procedure Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
   .If uMsg == WM_CREATE
      Invoke GetWindowItem, hWnd, IDC_WINDOW1_FILEBOX
      Mov FileBoxHandle, Eax
   
   .ElseIf uMsg == WM_COMMAND
      Mov Eax, wParam
      .If Ax == IDC_WINDOW1_SHREDBUTTON
         Shr Eax, 16
         .If Ax == BN_CLICKED
            Invoke GetText, FileBoxHandle, Addr FilePath
            Invoke MessageBox, NULL, Addr FilePath, Addr FilePath, MB_OK
            ;Invoke CreateFile, Addr FilePath, GENERIC_READ Or GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
            Invoke CreateFile, Addr FilePath, GENERIC_READ Or GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
            .If Eax == INVALID_HANDLE_VALUE
               Invoke MessageBox, NULL, Addr FilePath, Addr FilePath, MB_OK
               Return TRUE
            .EndIf
            Mov hFile, Eax
            Invoke GetFileSize, hFile, Addr hWord ;hWord
            Mov Ecx, 53 ; Hard coded file length
            Dec Ecx
LoopLabel:
            Push Ecx
            Invoke WriteFile, hFile, Addr DataByte, 1, Addr ByteWrite, NULL
            Pop Ecx
            Dec Ecx
            Jnz LoopLabel
            Invoke CloseHandle, hFile
            Invoke DeleteFile, Addr FilePath
            Invoke MessageBox, NULL, Addr mbText, Addr mbCaption, MB_OK
           
         .EndIf
      .EndIf   
     
   .ElseIf uMsg == WM_CLOSE
      Invoke IsModal, hWnd
      .If Eax
         Invoke EndModal, hWnd, IDCANCEL
         Return TRUE
      .EndIf
   .Endif
   Return FALSE
Window1Procedure EndP



The  second parameter in GetFileSize function (line 35) must be the address of a DWord value (not the value but the address and not Word but DWord). So, the hWord i lWord variables has been changed to DWord values (lines 7 and 8) and the parameter passed to the function has been changed to Addr hWord. This parameter can also be NULL if you know the file is not large enough.

The CreateFile function (line 28) has the flag OPEN_EXISTING which means that the file you're going to open has to exist. If not, an INVALID_HANDLE_VALUE error is returned. If you want to open (create) a file that does not exist, this flag should be CREATE_ALWAYS (I commented that line an added another one which creates the file).

Finally, and just as a precaution, if an INVALID_HANDLE_VALUE error is returned from CreateFile function, we should return TRUE (line 32) in order to avoid the code below to be executed. In fact, we should return at that point (TRUE or FALSE are valid). Returning TRUE means no further processing.

Regards,

Ramon


[attachment deleted by admin]
Title: Re: File Shredder
Post by: Ramon Sala on January 20, 2005, 01:42:56 PM
Bieb,

After posting my replay for the "File Shredder" problem, I realized that you wanted to obtain the low and high words of the high-order DWord of the file size (GetFileSize function). As that DWord value can be divided into two words, your original code in .Data? section was right:

hWord    Word    ?
lWord    Word    ?


But you have to pass the address of a DWord variable using Addr operator (Addr hWord), not its value. Anyway, in most cases, you can pass a NULL value instead, as that DWord address has only sense for very large files (more then 2^32 bytes).

To avoid errors in API calls needing an address to be passed, watch the context help for Windows API appearing under the line your writing. When a parameter refers to an address, it is shown in the context help with the Addr operator.

About CreateFile function, you can use the OPEN_EXISTING flag only if the file you're going to open exists. I changed it to CREATE_ALWAYS just for testing.


Regards,

Ramon
Title: Re: File Shredder
Post by: Ramon Sala on January 20, 2005, 02:19:16 PM
Hi Bieb,

Paul E. Brennnick and I saw another thing which might cause problems. When calling the GetFileSize function, if it returns 0 or INVALID_HANDLE_VALUE (which is -1), your program would crash when entering the loop. It doesn't happen now beacuse you directly move the value 53 to Ecx:


    Invoke GetFileSize, hFile, Addr hWord ;hWord
    Mov Ecx, 53 ; Hard coded file length
    Dec Ecx


But if you get the value returned by GetFileSize function and it was 0 or -1, your program would crash. So the right code for this part is the following:

            Invoke GetFileSize, hFile, Addr hWord   ;hWord
            Cmp Eax,0
            Jle @F
            Mov Ecx, Eax ; 53 ; Hard coded file length
LoopLabel:
            Push Ecx
            Invoke WriteFile, hFile, Addr DataByte, 1, Addr ByteWrite, NULL
            Pop Ecx
            Dec Ecx
            Jnz LoopLabel
@@:         Invoke CloseHandle, hFile
            Invoke DeleteFile, Addr FilePath



If the file is not found the -1 value (INVALID_HANDLE_VALUE) will be returned. When the file is found but it's empty (0 bytes), the 0 value is returned, so you have to take this into account. That's why the returned value is checked before entering the loop (see the code above). If it is lower or equal than 0, then the loop is not executed.


Regards,

Ramon
Title: Some considerations
Post by: Ramon Sala on January 20, 2005, 06:21:05 PM
Hi,

For everything said in this topic I would to make clear some considerations in order to use the Easy Code IDE properly and avoiding undesired behaviors:


- When calling any Easy Code method returning a string (i.e. GetText method), an ASCIIZ string is returned in the specified buffer, that is, it includes the final zero. So, you do not need to initialize the buffer contents to zero before the call. To prevent errors, always make this buffer 256 bytes long unless you know the exact text length (plus a byte for the zero character). There is no Easy Code method for retreiving the text length of an object, but you can send a WM_GETTEXTLENGTH message to find it out.

- Registers Eax, Ebx, Ecx, Edx, Edi and Esi can be used freely inside the window procedure of an Easy Code object, as they are preserved before entering the procedure and restored after leaving it. You just have to take care of registers along your code according to your needs.

- For any call to a Windows API function, remember that only Ebx, Edi and Esi registers are preserved (but not Ecx and Edx).

- All Easy Code methods preserve Ebx, Ecx, Edx, Edi and Esi registers. Only the Eax register changes as it is used for the return value.

- The defaut return value (FALSE) for an object procedure (Window or Control) has never to be removed or changed in order to avoid crashes. If you process a message and do not want any further processing for it, just return TRUE (only for that message).

- When the procedure for a Control object is not used because you can do all work in the WM_COMMAND and/or WM_NOTIFY messages received by its owner window (that's all you need in most cases), remove the entire Control procedure in order to save some bytes in the final executable file.

- .Code directive must always exist and be after .Const, .Data? and .Data in order the IDE to work properly (controlling variables, structures, macros and procedures). All code being before the .Code directive, is considered to be data.


Regards,

Ramon
Title: Re: File Shredder
Post by: Bieb on January 20, 2005, 11:22:47 PM
Thanks.  If I end up with a very large file length in a qword, will the dec instruction work with it?
Title: Re: File Shredder
Post by: Ramon Sala on January 20, 2005, 11:58:11 PM
Hi Bieb,

No, the Dec instruction only decrements a 32-bit value (register or variable). If you deal with a QWord value, decrement and check the low-order DWord. Each time its value is 0FFFFFFFFH, you have to decrement the high-order DWord and then repeat this operation until they both, high and low DWords are zero.

Ramon
Title: Re: File Shredder
Post by: Relvinian on January 21, 2005, 06:14:49 PM
Bieb,

Attached is a very simple program to take a file and "munge" it.  You can use this code to your liking for your own purposes.  I have included a build.bat so you can test out my code. In the .const section, there is a default filename the exe looks for.

Hope this helps you with your efforts.

Relvinian


[attachment deleted by admin]
Title: Re: File Shredder
Post by: Bieb on January 22, 2005, 03:51:32 PM
Thanks for all the help.  The utility will be freeware, and I'll put y'alls names in the comments section of the EXE.
Title: Re: File Shredder
Post by: Bieb on January 22, 2005, 04:38:17 PM
Okay, I think I have a nearly complete version of the code.  But I'm getting three compile errors that don't seem to make any sense.  I put the errors in as comments on the lines that the errors were for.  If anyone can figure out the problem, it would be a great help.
This version is meant to go through thirty passes, rotating the garbage byte it uses right one bit each pass.


.Const

.Data?
FileBoxHandle HWND ?
hDWord DWord ?
lDWord DWord ?
ByteWrite DWord ?
.Data
FilePath Byte 257 Dup (0)
DataByte Byte 01010101B
mbText DB "The file has been shredded", 0
mbCaption DB "Done", 0
mbError DB "Error", 0
.Code

ShredFile Proto

Window1Procedure Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
.If uMsg == WM_CREATE
;Retrieve and store handle to the edit box
Invoke GetWindowItem, hWnd, IDC_WINDOW1_FILEBOX
Mov FileBoxHandle, Eax

.ElseIf uMsg == WM_COMMAND
Mov Eax, wParam
.If Ax == IDC_WINDOW1_SHREDBUTTON
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if the shred button has been clicked
Invoke GetWindowText, FileBoxHandle, Addr FilePath, 256
Invoke ShredFile
.EndIf
.EndIf

.ElseIf uMsg == WM_CLOSE
Invoke IsModal, hWnd
.If Eax
Invoke EndModal, hWnd, IDCANCEL
Return TRUE
.EndIf
.Endif
Return FALSE
Window1Procedure EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

ShredFile Proc Private
Local lDWORD:DWord
Local hDWORD:DWord
Local hFile:DWord
Local Pass:Byte
Local BytesLeft:Byte
Invoke CreateFile, Addr FilePath, GENERIC_READ Or GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
Cmp Eax, INVALID_HANDLE_VALUE
Je ExitProcError
Mov hFile, Eax
Invoke GetFileSize, hFile, Addr hDWORD
Cmp Eax, INVALID_HANDLE_VALUE
Je ExitProcError
Cmp Eax, 0
Je ExitProcError
Mov lDWORD, Eax
Mov Pass, 31
Mov Ecx, lDWORD
Mov BytesLeft, Ecx ;Window1.asm(78) : error A2070: invalid instruction operands?
PassLabel:
Dec Pass
ByteLabel:
Invoke WriteFile, hFile, Addr DataByte, 1, Addr ByteWrite, NULL
Dec BytesLeft
Ror DataByte ;Window1.asm(71) : error A2008: syntax error : in instruction?
Cmp BytesLeft, 0
Jne ByteLabel
Cmp Pass, 0
Je ExitProc
Invoke SetFilePointer, hFile, 0, NULL, FILE_BEGIN
Mov Ecx, lDWORD
Mov BytesLeft, Ecx ;Window1.asm(78) : error A2070: invalid instruction operands?
Jmp PassLabel
Invoke CloseHandle, hFile
Invoke MessageBox, NULL, Addr mbText, Addr mbCaption, MB_OK
Jmp ExitProc
ExitProcError:
Invoke MessageBox, NULL, Addr mbError, NULL, MB_OK
ExitProc:
Ret
ShredFile EndP
Title: Re: File Shredder
Post by: Relvinian on January 23, 2005, 12:16:46 AM
Bieb,

The compiling errors you are receiving are because you are trying to move a DWORD into a BYTE location.

mov BytesLeft, ecx


BytesLeft is defined as a BYTE.  Change this define to a DWORD or move CL instead of ECX.

The ROR instruction needs a extra param to tell how many bits to rotate to the right.

Relvinian
Title: Re: File Shredder
Post by: Bieb on January 23, 2005, 12:53:51 AM
Oh!  Thanks. 
Title: Re: File Shredder
Post by: Bieb on January 23, 2005, 02:23:45 AM
Yay!  It's working now.  Just a few UI tweaks, support for bigger files, and an implementation of the Gutmann Algorithm, and I'll have finished my first complete project in Win32 ASM!   :bg
Title: Re: File Shredder
Post by: pbrennick on January 23, 2005, 05:36:36 PM
Bieb,
Congratulations!  It is a good feeling when you stick to it through to the end, is it not?  BTW:  Thank you for your support of Easy Code.  Since it is freeware and it is such a useful project, why don't you consider adding it to the Easy Code project.

Paul
Title: Re: File Shredder
Post by: pbrennick on January 23, 2005, 06:26:43 PM
Bieb,
Don't forget to change CREATE_ALWAYS to OPEN_EXISTING in the CreateFile line.  That was something that Ramon had done for testing purposes and when you think about it, no sense creating a file just to delete it.  He had told you this but with everything going on you might have missed it.  He already included the trap code to exit the procedure if the file doesn't exist.  It just keeps the housekeeping up to date.

Paul
Title: Re: File Shredder
Post by: Ramon Sala on January 23, 2005, 07:21:58 PM
Hi Bieb,

Congratulations! Thanks for using Easy Code and all your support of the project. As Paul suggested, why don't you consider to add it to the Easy Code project? It would be included as an example project.

Regards,

Ramon


BTW: When testing your program, I changed OPEN_EXISTING to CREATE_ALWAYS in order to avoid deleting any file, but as Paul said you should change it to OPEN_EXISTING again.
Title: Re: File Shredder
Post by: Bieb on January 23, 2005, 08:08:24 PM
I'd be glad to let y'all use it as an example.  I should have the time to finish it all up in a few days. 
Title: Re: File Shredder
Post by: Bieb on January 23, 2005, 10:57:43 PM
Okay, it's complete now.  I've added progress bars and a slider bar to control the number of passes it goes through.  You can do whatever you want with the code now.  If you're using it as example code, you might want to replace some of my cmp/conditional jump sequences with .if's.

Edit - Someone showed me a bug in the error handling I hadn't noticed before.  I've updated the attachment with the bug fixed.

[attachment deleted by admin]
Title: Re: File Shredder
Post by: pbrennick on January 24, 2005, 05:43:41 AM
Bieb,
Very nicely done.  I am confused by the Passes thing, though.  I moved it halfway up and then shredded a file.  I got some activity in the Overall progressbar but it never emptied and the Pass progressbar repeated a little more than three times.  Is this expected behavior?

It does do the job, though.
Paul
Title: Re: File Shredder
Post by: Ramon Sala on January 24, 2005, 11:43:08 AM
Hi Bieb,

I've been testing your File Shredder program and it really works! Congratulations! Anyway, I made some little changes in order the progress bar to work properly. You must take into account that the MinValue and MaxValue properties for a progress bar are two-byte values, that is, from 0 to 65535. As files are usually larger than 65535, the best you can do is working with the percentage done.

Also, if you specified a file name that didn't exist, and after the error message box appeared, the shredder button remained disabled. I fixed that in the ExitProcError label, by enabling the button again.

Finally, I added a call to DoEvents method inside the loop writing the file. This Easy Code method makes the message queue to be checked and allows the application to be repainted when it becomes active (if you switch to other tasks and come back to file shredder). In fact, it only would be necessary, for example, if you added a cancel button allowing the user to interrupt the deleting process. If not, you can remove it.

I attached the modified project. Thanks for using Easy Code.

Good work!

Ramon


[attachment deleted by admin]
Title: Re: File Shredder
Post by: pbrennick on January 24, 2005, 01:30:24 PM
Ramon,
That definitely clears up the 'Passes' problem.  I really like this app, it can be an excellent addition to anyone's toolbox and is already in mine.  Thanks Bieb!
Paul
Title: Re: File Shredder
Post by: Bieb on January 24, 2005, 04:11:05 PM
The passes slider controls the number of times the data is overwritten.  One time should be fine for preventing recovery by commercially available software, but the more you do, the less chance it can be recovered using more advanced techniques.

Thanks for all the help, people.  Can't wait to see my code included with Easy Code!

Edit - Well, I just decided to go and size up the competition.  Using Google, I was able to quickly find three other file shredders.  They ranged in size from 250k - 600k, and not a single one of them was freeware.  Mine, with the icon included, (I now have the release version with an icon hosted at http://original.bieberworks.com/BieberWorksFileShredder.exe) weighs in at a whopping 21.5 K, and anyone who wants can use and/or modify it to their heart's content.  Looks like I've managed to render a service to mankind :)

Edit - Hmm, I've managed to find a few free ones, but they're all still several hundred K.  I've even found a few that are several MB!
Title: Re: File Shredder
Post by: pbrennick on January 25, 2005, 05:08:54 PM
Bieb,
They will never be able to compete with yours.  Welcome to the EasyCode team!  Remember, if you have suggestions to better our product, please continue to help.
Paul
Title: Re: File Shredder
Post by: Darrel on April 28, 2005, 05:58:13 AM
Hi there,  :8)

FYI

Was searching for something else and found this thread.  Anyhow a couple months back I noticed some one working on this concept, so I gave him the correct code for overwriting a file, then developed a working application "DigitalShredder" filesize 5.0 KB with Icon and VersionInfo. It works by placing a shortcut in the SendTo folder and then you can right-click a single file or folder and select SendTo DigitalShredder and it overwrites all files "if a folder is selected" with zeroes and deletes all files and subdirectories before deleting the selected folder.

It was completed on April 1, 2005 and has no user interface.

Regards,

Darrel
Title: Re: File Shredder
Post by: QvasiModo on April 28, 2005, 06:53:02 PM
Hi, I'll add my 2 cents to this topic... :)

Quote from: pbrennick on January 20, 2005, 05:02:42 AM
I also think that

FilePath Byte 200 Dup (?)

should be

FilePath Byte 200 Dup (0)  (and move it from the .Data? section to the .Data  section)

That makes sure that there is a null terminator at the end of the filename, this is probably why DeleteFile is not working.

Paul

No, that's not so. The .bss section (uninitialized data) is always initialized to zero by the PE loader. Moving that array to the .data section just makes the file 200 bytes larger, with no change to it's behavior at all.

Hope that helps! :U
Title: Re: File Shredder
Post by: AeroASM on April 28, 2005, 07:44:11 PM
Quote from: Robert Bieber on January 20, 2005, 11:22:47 PM
Thanks.  If I end up with a very large file length in a qword, will the dec instruction work with it?

Being trigger-happy, I would just dec the lower dword and take the 0.000000023283064365386962890625% chance that it screws up.

(please don't take me seriously on this one)
Title: Re: File Shredder
Post by: pbrennick on April 28, 2005, 07:59:49 PM
QvasiModo,
Thanks for your clarification on this issue.  Knowledge of how the PE loader functions is not one of my strong points.  I will say this however:  I don't like the idea of leaving such things to be handled by the OS because you then have to hope that it never changes when a new flavor of windows pops up.  This also applies to closing handles, etc.  It is my belief that the proper way to code is to do your own housekeeping.  Still, your point is well taken and is nice to know.  Thank you.

Paul
Title: Re: File Shredder
Post by: Ramon Sala on April 28, 2005, 08:26:09 PM
Hi,

I think Paul is wright. It is better not to rely on the O.S. will fill that data with zeros. If it is true now, maybe it won't be in the future.

Ramon