Page 1 of 2
WriteByte until FreeDiskSpace = 0 byte
Posted: Tue Aug 01, 2006 3:49 pm
by eJan
How to know when WriteByte is reached out of FreeDiskSpace. I have tried with
PB code:
http://www.purebasic.fr/english/viewtop ... 208#129208 but API work very slow - especialy for writing 4-5 gigabytes file (to fill free HD space with 0's for backup image).
Code: Select all
If CreateFile(0, "FREE_SPACE")
For a=1 To 1
Repeat
WriteByte(0, 0) ; Write 0 byte to 'FREE_SPACE' file
ForEver ; Until FreeDiskSpace = 0 byte
Next
CloseFile(0)
EndIf
Posted: Tue Aug 01, 2006 4:08 pm
by Kale
Why do you need to use code like this? Maybe it can be achieved in a nicer way?
Posted: Tue Aug 01, 2006 4:18 pm
by eJan
Kale wrote:Why do you need to use code like this? Maybe it can be achieved in a nicer way?
To fill free disk space with zeroes (most of wipe utilities works in that way: WinHex, SDelete:
http://www.sysinternals.com/Utilities/SDelete.html, nullfile).
Posted: Tue Aug 01, 2006 5:04 pm
by dracflamloc
Why would you do it byte-wise, that will be slow.
You should do it with a large data chunk of zeros to speed it up.
Posted: Tue Aug 01, 2006 8:09 pm
by eJan
dracflamloc wrote:Why would you do it byte-wise, that will be slow.
You should do it with a large data chunk of zeros to speed it up.
Thanks for suggestion. I'm gonna measure the difference with time.
Posted: Tue Aug 01, 2006 8:46 pm
by Dreglor
It's cleaner and probably a lot faster to do something like this
you can modify it to fit with your app
Code: Select all
Procedure CleanFile(Filename.s, FileSize.l, ChunkSize.l = 0)
;Note: if Chunk Size is left zero it will just write the file in one pass.
;in chunk cleaning remeber that the size of the file will exccede by 1 chunk.
Handle = CreateFile(#PB_Any, Filename)
If IsFile(Handle) = #False
ProcedureReturn #False
EndIf
If ChunkSize = 0
ChunkLocation = AllocateMemory(FileSize)
ZeroMemory_(ChunkLocation, FileSize)
WriteData(Handle, ChunkLocation, FileSize)
FreeMemory(ChunkLocation)
Else
NumberOfChunks = Round(ChunkSize / FileSize, 1)
ChunkLocation = AllocateMemory(ChunkSize)
ZeroMemory_(ChunkLocation, ChunkSize)
For Chunk = 0 To NumberOfChunks
If
WriteData(Handle, ChunkLocation, ChunkSize)
Next
FreeMemory(ChunkLocation)
EndIf
CloseFile(Handle)
DeleteFile(Filename)
ProcedureReturn #True
EndProcedure
Posted: Wed Aug 02, 2006 12:36 pm
by b1be
this may help
http://www.purebasic.fr/english/viewtop ... 551#152551
but of course, you must determine how much FREE SPACE do you have on the drive, exceeding size with 1 byte will produce ZeroFile (0 Bytes)
quick test
Code: Select all
Procedure.q GetDiskSpace(drive$,type$)
Value.q=-1
If GetDiskFreeSpaceEx_(drive$,@free.q,@total.q,0)
Select LCase(type$)
Case "t" : Value=total
Case "f" : Value=free
Case "u" : Value=total-free
Default : Value=-1
EndSelect
EndIf
ProcedureReturn Value
EndProcedure
Procedure CreateFilledFile(Name.s, fsize.q)
Protected file.l = CreateFile(#PB_Any, Name)
If file
If fsize<=0
CloseFile(file)
ProcedureReturn #True
Else
FileSeek(file, fsize-1)
WriteByte(file, 0)
CloseFile(file)
ProcedureReturn #True
EndIf
EndIf
EndProcedure
CreateFilledFile("C:\FREE_SPACE",GetDiskSpace("c:","f")-1)
this should fill C:
Posted: Wed Aug 02, 2006 1:14 pm
by eJan
b1be wrote:this may help
http://www.purebasic.fr/english/viewtop ... 551#152551
but of course, you must determine how much FREE SPACE do you have on the drive, exceeding size with 1 byte will produce ZeroFile (0 Bytes)
quick test
Code: Select all
Procedure.q GetDiskSpace(drive$,type$)
Value.q=-1
If GetDiskFreeSpaceEx_(drive$,@free.q,@total.q,0)
Select LCase(type$)
Case "t" : Value=total
Case "f" : Value=free
Case "u" : Value=total-free
Default : Value=-1
EndSelect
EndIf
ProcedureReturn Value
EndProcedure
Procedure CreateFilledFile(Name.s, fsize.q)
Protected file.l = CreateFile(#PB_Any, Name)
If file
If fsize<=0
CloseFile(file)
ProcedureReturn #True
Else
FileSeek(file, fsize-1)
WriteByte(file, 0)
CloseFile(file)
ProcedureReturn #True
EndIf
EndIf
EndProcedure
CreateFilledFile("C:\FREE_SPACE",GetDiskSpace("c:","f")-1)
this should fill C:
Thanks b1be, I can't believe how fast it is - 5,47 GB is filled for 47 milliseconds. Great!!

Posted: Wed Aug 02, 2006 8:55 pm
by Xombie
Okay. I know I've been pretty darn slow lately but that last procedure only looks like it's writing 1 byte. Tell me I haven't caught Fangles-ism and am missing something completely obvious (Hey, Fangles

)
Posted: Wed Aug 02, 2006 9:01 pm
by dracflamloc
Well it will create the file size hes looking for but I'm not too confident it actually writes 0's on that whole 5gb
Posted: Wed Aug 02, 2006 9:37 pm
by Xombie
Ah. Yeah, I am slow. So the idea was to seek to a spot, right a zero and then assume the rest of the area before is also zero - empty space.
Not sure that will actually accomplish securely wiping a disk drive. I thought Windows had some strange ways of allocating files and handling stuffs.
eJan - You mention SDelete - you know they provide the source code, yeah? You could grab it and study it to see how they handle things. It seems they also have a nice little description of the process on the project page.
Posted: Thu Aug 03, 2006 1:35 am
by eJan
Xombie wrote:Ah. Yeah, I am slow. So the idea was to seek to a spot, right a zero and then assume the rest of the area before is also zero - empty space.
Not sure that will actually accomplish securely wiping a disk drive. I thought Windows had some strange ways of allocating files and handling stuffs.
eJan - You mention SDelete - you know they provide the source code, yeah? You could grab it and study it to see how they handle things. It seems they also have a nice little description of the process on the project page.
It is really fast, but doesn't fill the disk. I have to return to do it this way:
Code: Select all
Procedure.q GetDiskSpace(drive.s, type.s)
Value.q=-1
If GetDiskFreeSpaceEx_(drive,@free.q,@total.q,0)
Select LCase(type)
Case "t" : Value=total
Case "f" : Value=free
Case "u" : Value=total-free
Default : Value=-1
EndSelect
EndIf
ProcedureReturn Value
EndProcedure
Procedure FillFreeSpace(drive.s,f_name.s)
Protected file.l=CreateFile(#PB_Any,f_name)
If file
free=GetDiskSpace(drive,"f")
a=0
Repeat
a=a+1
WriteByte(file,0) ; Write 0 byte to 'f_name' file
Until a=free ; free=5.9 Gb, but only 1.9 Gb is written??
CloseFile(file)
DeleteFile(f_name)
EndIf
EndProcedure
FillFreeSpace("C:","FREE_SPACE")
but for some reason this code write to partition until <> 4 Gb is free then stops / or write forever. I can't find out why is that (maybe variable).
Posted: Thu Aug 03, 2006 7:35 pm
by b1be
Code: Select all
Procedure CreateFilledFile(Name.s, fsize.q)
Protected file.l = CreateFile(#PB_Any, Name)
If file
If fsize<=0
CloseFile(file)
ProcedureReturn #True
Else
FileSeek(file, fsize-1)
WriteByte(file, 0)
CloseFile(file)
ProcedureReturn #True
EndIf
EndIf
EndProcedure
CreateFilledFile("C:\Temp.hex",6)
OpenFile(0,"C:\Temp.hex")
FileSeek(0,2) ;replace 3rd byte with "a" 97-ASCII
WriteByte(0,97)
CloseFile(0)
then, open with a hex editor "C:\Temp.hex"
the bytes are written to hdd, you can see the 3rd byte is "a" 97-ASCII 61-HEX
i'm using XPSP2 with NTFS, Cant Test on other OS/FileSystem
dont know what are you looking for exactly tho'
P.S.:@
Xombie ok, it Writes only 1 byte, but it does the job, i think it's a Windows Feature/
Bug
Posted: Thu Aug 03, 2006 8:41 pm
by eJan
b1be wrote:then, open with a hex editor "C:\Temp.hex"
the bytes are written to hdd, you can see the 3rd byte is "a" 97-ASCII 61-HEX
i'm using XPSP2 with NTFS, Cant Test on other OS/FileSystem
dont know what are you looking for exactly tho'
P.S.:@Xombie ok, it Writes only 1 byte, but it does the job, i think it's a Windows Feature/Bug
Yes it does fill free disk space to 0 bytes, but I can't use it because it doesn't fill free disk space with 00's. Only working solution is:
Code: Select all
Procedure.q GetDiskSpace(drive.s, type.s)
Value.q=-1
If GetDiskFreeSpaceEx_(drive,@free.q,@total.q,0)
Select LCase(type)
Case "t" : Value=total
Case "f" : Value=free
Case "u" : Value=total-free
Default : Value=-1
EndSelect
EndIf
ProcedureReturn Value
EndProcedure
Procedure FillFreeSpace(drive.s,f_name.s)
Protected file.l=CreateFile(#PB_Any,f_name)
If file
free=GetDiskSpace(drive,"f")
a=0
Repeat
a=a+1
WriteByte(file,0) ; Write 0 byte to 'f_name' file
Until a=free
CloseFile(file)
DeleteFile(f_name)
EndIf
EndProcedure
FillFreeSpace("C:","FREE_SPACE")
Only one thing is that I don't know how to count more than 1607573504 (1.6 GB) when I have 5 GB:
Code: Select all
a=0
Repeat
a=a+1
Until a=5902540800 ; cannot count more than 1607573504
MessageRequester("",Str(a))
or here 1607573505:
Code: Select all
For a=0 To 5902540800 ; cannot count more than 1607573505
Next
MessageRequester("", Str(a))
Posted: Thu Aug 03, 2006 9:01 pm
by b1be
Make your counter a Quad
Purebasic Help wrote:Quad .q 8 Bytes Length -9223372036854775808 to +9223372036854775807
Code: Select all
a.q=590254079997
Repeat
a=a+1
Debug a
Until a=590254080000
P.S.:
eJan wrote:Yes it does fill free disk space to 0 bytes, but I can't use it because it doesn't fill free disk space with 00's
What is the Difference Between 0's and 00's ? 0 Dec = 00 Hex ?