Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/RTL/Delphi/File Management    [ Add a report in this area ]  
Report #:  65767   Status: Closed
OpenFile, CreateFile with TFileStream or SysUtils.CreateFile dont honor fmShareDenyWrite, it's impossible to read an already opened File from an other programm!!!!
Project:  Delphi Build #:  11.0.2902.10471
Version:    11.0 Submitted By:   Registered User
Report Type:  Basic functionality failure Date Reported:  8/18/2008 4:07:20 AM
Severity:    Serious / Highly visible problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   264382
Resolution: Fixed (Resolution Comments) Resolved in Build: : 14.0.3467.22472
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 10
Description

FSlockfilehandle := TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite  );

Don't Work!
sysutils.FileOpen(Filename,fmOpenRead or fmShareDenyWrite  );

Don't Work!



...\source\Win32\rtl\sys\Sysutils.pas

There is a function not allready out-programmed!!!



function FileOpen(const FileName: string; Mode: LongWord): Integer;

{ FileCreate creates a new file by the specified name. If the return value
  is positive, the function was successful and the value is the file handle
  of the new file. A return value of -1 indicates that an error occurred.
  On Linux, this calls FileCreate(FileName, DEFFILEMODE) to create
  the file with read and write access for the current user only.  }

function FileCreate(const FileName: string): Integer; overload; inline;

{ This second version of FileCreate lets you specify the access rights to put on the newly
  created file.  The access rights parameter is ignored on Win32 }

function FileCreate(const FileName: string; Rights: Integer): Integer; overload; inline;

{ FileRead reads Count bytes from the file given by Handle into the buffer
  specified by Buffer. The return value is the number of bytes actually
  read; it is less than Count if the end of the file was reached. The return
  value is -1 if an error occurred. }


function FileCreate(const FileName: string): Integer;
{$IFDEF MSWINDOWS}
begin
  Result := Integer(CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE,
    0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0));
end;
{$ENDIF}
{$IFDEF LINUX}
begin
  Result := FileCreate(FileName, FileAccessRights);
end;
{$ENDIF}

function FileCreate(const FileName: string; Rights: Integer): Integer;
{$IFDEF MSWINDOWS}
begin
  Result := FileCreate(FileName);    <<========== HERE IS MISSING CODE!!!
end;
{$ENDIF}
{$IFDEF LINUX}
begin
  Result := Integer(open(PChar(FileName), O_RDWR or O_CREAT or O_TRUNC, Rights));
end;
Steps to Reproduce:
Some Programms look in ONE single file. One Create the file for Writing it, all others can read the file.




Open new file with delph, shared mode deny WRITE , tfilestream or else...
dont close file.
lockfilehandle := TFileStream.Create(s, fmCreate OR fmShareDenyWrite  );   <==== fmShareDeny* will be ignored



Open the same file for READ only with another delphi programm... dont work...


FSlockfilehandle := TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite  );  <=== NO HANDLE!!!!
FSlockfilehandle.Read(macbuffer^,sizeof(macbuffer^))
Workarounds
Use windows.CreateFile() method but than all Delphi Streams not working...
Attachment
None
Comments

Tomohiro Takahashi at 8/18/2008 7:49:17 AM -
I have a question about you 'Steps'.
Before you execute this line 'TFileStream.Create(s, fmCreate OR fmShareDenyWrite);', does the file s already exist?

Registered User at 8/18/2008 8:26:05 AM -
No, the file does not exist befor.

The TFileStream.Create is buggy.



{ TFileStream from Classes }

constructor TFileStream.Create(const AFileName: string; Mode: Word);
begin
{$IFDEF MSWINDOWS}
  Create(AFilename, Mode, 0);     <<=== this calls the routine 6 Lines lower...
{$ELSE}
  Create(AFilename, Mode, FileAccessRights);
{$ENDIF}
end;

constructor TFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal);
begin
  if Mode = fmCreate then
  begin
    inherited Create(FileCreate(AFileName, Rights));  <<=== Missing Mode !!!! Rights == 0
    if FHandle < 0 then
      raise EFCreateError.CreateResFmt(@SFCreateErrorEx, [ExpandFileName(AFileName), SysErrorMessage(GetLastError)]);
  end
  else
  begin
    inherited Create(FileOpen(AFileName, Mode));
    if FHandle < 0 then
      raise EFOpenError.CreateResFmt(@SFOpenErrorEx, [ExpandFileName(AFileName), SysErrorMessage(GetLastError)]);
  end;
  FFileName := AFileName;
end;

====

This TFileStream / Classes calls SysUtils FileCreate...


function FileCreate(const FileName: string): Integer;
{$IFDEF MSWINDOWS}
begin
  Result := Integer(CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE,
    0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0));
end;
{$ENDIF}
{$IFDEF LINUX}
begin
  Result := FileCreate(FileName, FileAccessRights);
end;
{$ENDIF}

function FileCreate(const FileName: string; Rights: Integer): Integer;
{$IFDEF MSWINDOWS}
begin
  Result := FileCreate(FileName);    <<== Rights droped....
end;
{$ENDIF}
{$IFDEF LINUX}
begin
  Result := Integer(open(PChar(FileName), O_RDWR or O_CREAT or O_TRUNC, Rights));
end;
{$ENDIF}



====
Missing Something like

function FileOpen(const FileName: string; Mode: LongWord): Integer;  <<== adaped to CreateFile some code...
{$IFDEF MSWINDOWS}
const
  AccessMode: array[0..2] of LongWord = (
    GENERIC_READ,
    GENERIC_WRITE,
    GENERIC_READ or GENERIC_WRITE);
  ShareMode: array[0..4] of LongWord = (
    0,
    0,
    FILE_SHARE_READ,
    FILE_SHARE_WRITE,
    FILE_SHARE_READ or FILE_SHARE_WRITE);
begin
  Result := -1;
  if ((Mode and 3) <= fmOpenReadWrite) and
    ((Mode and $F0) <= fmShareDenyNone) then
    Result := Integer(CreateFile(PChar(FileName), AccessMode[Mode and 3],
      ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING,  <<== Create_Always or so (?)
      FILE_ATTRIBUTE_NORMAL, 0));
end;



Registered User at 2/20/2009 2:11:27 AM -
Hello? Is there somebody here?

This bug is also in delphi 2009

How's about a new function
TFileStream.CreateEx(Filename, fmCreate, fmShareDenyWrite) to solve this?

fmCreate = $FFFFF or (something) will be ever $FFFFF

fmShareDenyWrite = $0020

Server Response from: ETNACODE01