Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CreateFile to open a file already opened

297 views
Skip to first unread message

Colin B Maharaj

unread,
Jul 2, 2008, 8:17:43 AM7/2/08
to
Hi all I used this function to open a file for read/write share deny
none like this....

FileHandle = FileOpen("MyFile.txt",fmOpenReadWrite|fmShareDenyNone);

then I opened the same file later on like this to read something...
no problem, (Note: I did not close the file handle above)

FileHandle2 = FileOpen("MyFile.txt", fmOpenRead |fmShareDenyNone);
...
FileClose(FileHandle2);

Finally I have this code I am using (not my code)
and is WinAPI and try to open the file similar to the
read operation above BUT IT FAILS!!

HANDLE hf =
CreateFile("MyFile.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);

// returns 0xffffffff


Any suggestions on how to get the 3rd line of code to behave like the
2nd line. Or, is an int FileHandle like what you see in 2nd line the
same as the HANDLE in the third.

Colin B Maharaj


Remy Lebeau (TeamB)

unread,
Jul 2, 2008, 12:14:05 PM7/2/08
to

"Colin B Maharaj" <nor...@myhost.com> wrote in message
news:486b71d7$1...@newsgroups.borland.com...

> Finally I have this code I am using (not my code)
> and is WinAPI and try to open the file similar to the
> read operation above BUT IT FAILS!!

What does GetLastError() return when CreateFile() fails? Since you are
using relative paths, not absolute paths, I ma guessing that the API code is
trying to open a file that does not actually exist.

> Or, is an int FileHandle like what you see in 2nd line the
> same as the HANDLE in the third.

Yes.


Gambit


Colin B Maharaj

unread,
Jul 2, 2008, 1:24:29 PM7/2/08
to
Thanks for responding Remy.
The fact is my actual Code uses absolute paths.
Here is a sample code that I have put together
that actually give the same problem I am experiencing.....
(just put a button on a form and test it)
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString A = ExtractFilePath(ParamStr(0));
A += "MyFile.txt";
ShowMessage(A);

// Create the file myfile.txt in the same place as the EXE.
{
int h = FileCreate(A);
AnsiString SomeText = "The file contents\r\n";
FileWrite(h, SomeText.c_str(), SomeText.Length());
FileClose(h);
}

// open the file...
int FileHandle = FileOpen(A, fmOpenReadWrite|fmShareDenyNone);

// open it again....
int FileHandle2 = FileOpen(A, fmOpenRead |fmShareDenyNone);
FileSeek(FileHandle2, (int)0, 0);
char s[64];
FileRead(FileHandle2, s, 63);
FileClose(FileHandle2);
// close the second instance....
ShowMessage(s);


// open it using the CreateFile Winapi...and handle possible error...
HANDLE hf =
CreateFile(A.c_str(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
if (hf == (HANDLE)0xffffffff)
{
char *lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,NULL,
GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)
&lpMsgBuf,0,NULL);
MessageBox( NULL, lpMsgBuf, "GetLastError",
MB_OK|MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
}
else
{
CloseHandle(hf);
}

// close off the initial handle....
FileClose(FileHandle);

}


//---------------------------------------------------------------------------

Remy Lebeau (TeamB)

unread,
Jul 2, 2008, 3:17:51 PM7/2/08
to

"Colin B Maharaj" <nor...@myhost.com> wrote in message
news:486bb9bd$1...@newsgroups.borland.com...

> if (hf == (HANDLE)0xffffffff)

Use the INVALID_HANDLE_VALUE macro instead:

if (hf == INVALID_HANDLE_VALUE)

> char *lpMsgBuf;
> FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
> FORMAT_MESSAGE_FROM_SYSTEM,NULL,
> GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)
> &lpMsgBuf,0,NULL);

The VCL has a SysErrorMessage() function that does that work for you:

ShowMessage(SysErrorMessage(GetLastError()));

In any case, GetLastError() is returning ERROR_SHARING_VIOLATION (32, "The
process cannot access the file because it is being used by another
process."). Which means your call to CreateFile() is not asking for enough
sharing rights to allow it to succeed.

If you take your second call to FileOpen():

int FileHandle2 = FileOpen(A, fmOpenRead | fmShareDenyNone);

And look at how FileOpen() is implemented in SysUtils.pas (if you have the
VCL source code installed), you will see that it expands to the following
CreateFile() call:

... = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ |
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

Notice the extra FILE_SHARE_WRITE flag? That is the key to making your code
work.

Your first call to FileOpen() specifies the fmOpenReadWrite flag:

int FileHandle = FileOpen(A, fmOpenReadWrite|fmShareDenyNone);

That expands to this:

... = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ
| FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

Since the file is writable, any subsequent opening of the file while the
first handle is still active must specify the FILE_SHARE_WRITE flag or the
opening fails. That is why your second call to FileOpen() succeeds but your
call to CreateFile() fails.


Gambit


Colin B Maharaj

unread,
Jul 2, 2008, 4:25:28 PM7/2/08
to
Remy, my first (or was it 2nd) instinct was to look at the
VCL code implementation. But I was just zogged out ...

Thanks again Remy.

0 new messages