Page 1 of 3

Accessing - files in use -

Posted: Fri May 14, 2004 9:02 am
by Max.
Did any of you research why files that are in use by another program or the OS can not be accessed? How does the OS lock a file or determine that it is locked?

Any possiblity to use the API, like CreateFile with a certain combination of the parameters, in order to copy a file?

Posted: Fri May 14, 2004 9:47 am
by gnozal
I think the Purebasic file functions can't open a file allready in use.
You have to use API calls.
GPI made a very nice API file handle purebasic include file.
It's a part of the jaPBe package (API-FileHandle.pbi).

Posted: Fri May 14, 2004 11:04 am
by fweil
Max,

Look at this code and then you may try to use Lock / Unlock functions with the handle of file.

Note that Purebasic ReadFile() returns a compatible handle for API but does not open a file if it's locked. API functions allow to open the file and then, according to security parameters, you may be able to access R/W.

Code: Select all

Directory.s = "C:\RECUP\PureBasic\Design\"
Directory.s = "C:\"
  If ExamineDirectory(0, Directory, "*.*")
      Repeat
        DirectoryEntryType = NextDirectoryEntry()
        Select DirectoryEntryType
          Case 0
            Break
          Case 1
            FileName.s = Directory + DirectoryEntryName()
            hFile = OpenFile_(FileName, OpenFileStruct.OFSTRUCT, #OF_READ)
            If hFile

                GetFileInformationByHandle_(hFile, FileInformation.BY_HANDLE_FILE_INFORMATION)

                sFileAttributes.s = "........"
                If FileInformation\dwFileAttributes & #FILE_ATTRIBUTE_ARCHIVE ; The file is an archive file. Applications use this value To mark files For backup Or removal.
                    PokeB(@sFileAttributes, 'A')
                EndIf
                If FileInformation\dwFileAttributes & #FILE_ATTRIBUTE_COMPRESSED ; The file Or directory is compressed. For a file, this means that all of the Data in the file is compressed. For a directory, this means that compression is the Default For newly created files And subdirectories.
                    PokeB(@sFileAttributes + 1, 'C')
                EndIf
                If FileInformation\dwFileAttributes & #FILE_ATTRIBUTE_DIRECTORY ; The file is a directory.
                    PokeB(@sFileAttributes + 2, 'D')
                EndIf
                If FileInformation\dwFileAttributes & #FILE_ATTRIBUTE_HIDDEN ; The file is hidden. It is not included in an ordinary directory listing.
                    PokeB(@sFileAttributes + 3, 'H')
                EndIf
                If FileInformation\dwFileAttributes & #FILE_ATTRIBUTE_NORMAL ; The file has no other attributes. This value is valid only If used alone.
                    PokeB(@sFileAttributes + 4, 'N')
                EndIf
                If FileInformation\dwFileAttributes & #FILE_ATTRIBUTE_READONLY ; The file is read-only. Applications can Read the file but cannot write To it Or delete it.
                    PokeB(@sFileAttributes + 5, 'R')
                EndIf
                If FileInformation\dwFileAttributes & #FILE_ATTRIBUTE_SYSTEM ; The file is part of the operating system Or is used exclusively by it.
                    PokeB(@sFileAttributes + 6, 'S')
                EndIf
                If FileInformation\dwFileAttributes & #FILE_ATTRIBUTE_TEMPORARY ; The file is being used For temporary storage. Applications should write To the file only If absolutely necessary. Most of the file's data remains in memory without being flushed to the media because the file will soon be deleted.
                    PokeB(@sFileAttributes + 7, 'T')
                EndIf

                FileTimeToLocalFileTime_(@FileInformation\ftCreationTime, @CreationTime.FILETIME)
                FileTimeToSystemTime_(@CreationTime.FILETIME, @sCreationTime.SYSTEMTIME)

                FileTimeToLocalFileTime_(@FileInformation\ftLastAccessTime, @CreationTime.FILETIME)
                FileTimeToSystemTime_(@CreationTime.FILETIME, @sCreationTime.SYSTEMTIME)

                FileTimeToLocalFileTime_(@FileInformation\ftLastWriteTime, @CreationTime.FILETIME)
                FileTimeToSystemTime_(@CreationTime.FILETIME, @sCreationTime.SYSTEMTIME)

                Debug FileName + " " + sFileAttributes + " Created : " + FormatDate("%yyyy %mm %dd %hh:%ii:%ss", Date(sCreationTime\wYear, sCreationTime\wMonth, sCreationTime\wDay, sCreationTime\wHour, sCreationTime\wMinute, sCreationTime\wSecond)) + " Last accessed : " + FormatDate("%yyyy %mm %dd %hh:%ii:%ss", Date(sCreationTime\wYear, sCreationTime\wMonth, sCreationTime\wDay, sCreationTime\wHour, sCreationTime\wMinute, sCreationTime\wSecond)) + " Last written : " + FormatDate("%yyyy %mm %dd %hh:%ii:%ss", Date(sCreationTime\wYear, sCreationTime\wMonth, sCreationTime\wDay, sCreationTime\wHour, sCreationTime\wMinute, sCreationTime\wSecond))

                Debug "Volume serial : " + Hex(FileInformation\dwVolumeSerialNumber)
                Debug "nFileSizeHigh : " + Str(FileInformation\nFileSizeHigh)
                Debug "nFileSizeLow : " + Str(FileInformation\nFileSizeLow)
                Debug "nNumberOfLinks = " + Str(FileInformation\nNumberOfLinks)
                Debug "nFileIndexHigh = "+ Str(FileInformation\nFileIndexHigh)
                Debug "nFileIndexLow = " + Str(FileInformation\nFileIndexLow)
                CloseHandle_(hFile)
            EndIf
          Case 2
            Debug "== Directory entry ==> " + Directory + DirectoryEntryName()
        EndSelect
      ForEver
  EndIf
End
I guess you will have good material here to play with.

Rgrds

Posted: Fri May 14, 2004 11:57 am
by blueznl
yup, it's because pure doesn't add the shared flags when opening a file

i've written x_openfile() etc. for this purpose, using winapi, might need some more testing though...

Posted: Fri May 14, 2004 3:38 pm
by blueb
I'm having trouble in this area. I'm trying to back-up the server nightly, but I want to assure that all files to be backed-up are not in use. (If they are the backup program simply omits them from the backup list... not good!)

So I'd like to test each file to be sure it's not in use. I've tried a variety of things, but nothing concrete yet.

Still hunting for ideas...

blueb

Posted: Fri May 14, 2004 4:08 pm
by fweil
blueb, Kidding or serious ?

Anyway you may try to unlock files ... baaah it's a well known issue but using regular backup software solves this easily, because backup good apps know how to overwritte access read rights.

I have not so much time to write a full backup program so I may have a look only to add my above post unlock feature if asked kindly !

Rgrds

Posted: Sat May 15, 2004 12:30 am
by Max.
Thanks, guys!

I tried GPI's procedures - alone - already with little success, but together with the here mentioned lock/unlock (thanks... Francois?) it seems promising!

Oh, and if one wants to have a go at a backup program, do not forget to include copying the file securities; I'd like to have that to. :wink:

Edit:

Running into the first troubles already - I don't get a file handle if it is in use already; I tried both OpenFile (fweil) as CreateFile (GPI).

Posted: Sat May 15, 2004 1:19 am
by fweil
It seems, by reading Win32 API documentation that there is no known way to access a locked file except by using its handle from the process that locked it !

Well, this does not mean it is not possible, but OpenFile_() or ReadFile_() do not allow to do it.

I am wondering now how do true backup apps ? Like Exchange server backuping apps I know, because Exchange files are all the time openend and locked.

The best now should be to parse Google for VB or C++ code that goes closer to that point.

Rgrds

Posted: Sat May 15, 2004 1:23 am
by Max.
Yes, sadly seems so, also when looking at Sysinternals.com, offering a utility called "Handle.exe.

Another edit:

Found a program called "lcopy" (www.techit.de) which promises to do it. Maybe this can bring one on the right track...

Edit^2:

http://www.codeguru.com/Cpp/W-P/files/f ... php/c1287/

Posted: Sat May 15, 2004 9:19 am
by thefool
you cant just copy the file and then read it?

Posted: Sat May 15, 2004 9:41 am
by fweil
If a file is locked it is not even possible to copy it.

The most simple test is to try to copy pagefile.sys from the file explorer. It's locked.

To use it, it is neceessary to open / create such files with backup prfile (defined in CreateFile_() ).

But there, I can't find the way right now to put all required parameters.

I tried, but no success ATM.

Rgrds

Posted: Sat May 15, 2004 10:03 am
by blueznl
with FILE_FLAG_BACKUP_SEMANTICS ?

Posted: Sat May 15, 2004 10:08 am
by fweil
blueznl,

This what I was looking this morning, but no success right now.

Posted: Sat May 15, 2004 10:09 am
by blueznl
should be possible, lemme see...

Posted: Sat May 15, 2004 10:16 am
by fweil
I hold on :D