DickStorey
asked on
ReadFile error ERROR_NOACCESS
I have translated the modified async filter from the DirectShow SDK to Delphi. I have a problem with ReadFile on a local media file opened with GENERIC_READ, FILE_SHARE_READ and FILE_FLAG_OVERLAPPED.
It returns ERROR_NOACCESS. The parameters going into the call are the same in C++ and in Delphi but Delphi returns
ERROR_NOACCESS whereas C++ returns ERROR_IO_PENDING
Any Ideas what the problem might be?
It returns ERROR_NOACCESS. The parameters going into the call are the same in C++ and in Delphi but Delphi returns
ERROR_NOACCESS whereas C++ returns ERROR_IO_PENDING
Any Ideas what the problem might be?
// Create the file
function TFileStream.Initialize(Filename: string): HResult;
begin
if FFileHandle <> INVALID_HANDLE_VALUE then
begin
Result := E_FAIL;
exit;
end;
FFileHandle := CreateFile(PChar(filename), GENERIC_READ, FILE_SHARE_READ,
nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if FFileHandle = INVALID_HANDLE_VALUE then
Result := HResultFromWin32(GetLastError)
else
Result := S_OK;
end;
// Attempt to read it
function TFileStream.StartRead(Buffer: PByte; BytesToRead: Cardinal;
Align: boolean; Overlapped: POverlapped; var Pending: boolean;
var BytesRead: cardinal): HResult;
var
res: BOOL;
err: DWORD;
begin
Pending := false;
Lock;
try
// all these parameters are valid
res := ReadFile(FFileHandle, Buffer, BytesToRead, BytesRead, Overlapped);
if not res then
begin
err := GetLastError;
if (err = ERROR_IO_PENDING) then
begin
Pending := true;
Result := S_OK;
end
else if err = ERROR_NOACCESS then // why does this happen?
begin
Beep;
Result := HResultFromWin32(err);
end
else
Result := HResultFromWin32(err);
end
else
Result := S_OK;
finally
UnLock;
end;
end;
make sure Buffer is allocated and try changing function declaration to:
function TFileStream.StartRead(var Buffer: PByte;...
ziolko.
function TFileStream.StartRead(var Buffer: PByte;...
ziolko.
I'm confused... Doesn't delphi already have a TFileStream class? Why are you creating one?
if you are, in fact using the delphi one, then please paste your call that creaets teh TFileStream
e.g.
var
fs: TFileStream;
begin
fs := TFileStream.Create('file.t xt', fmOpenRead OR fmShareDenyNone);
try
...
finally
fs.free;
end;
end;
fwiw, if you are using this, then I suspect you are not opening it as readonly (you said it was on a media)
if you are, in fact using the delphi one, then please paste your call that creaets teh TFileStream
e.g.
var
fs: TFileStream;
begin
fs := TFileStream.Create('file.t
try
...
finally
fs.free;
end;
end;
fwiw, if you are using this, then I suspect you are not opening it as readonly (you said it was on a media)
@TheRealLoki: looks like he wants asynchrnious read operation (he uses overlapped structure) but indeed class name is a little bit confusing
ziolko.
ziolko.
ASKER
Hi ziolko and TheRealLoki
Sorry, I'm new to using this site and I realise I did not give a detailed enough problem description. I cannot find a means to modify my question so I am adding a comment in the hope you might notice it and tell me how to do so.
I'm aware Delph has a TFileStream class, which I am not using. My code is a direct translation of an improved version of the DirectShow SDK's async filter. The name FileStream may be confusing to a Delphi developer but it describes the function of the class in my code.
The DirectShow filter does indeed use asynchronous reading since it may be accessing media files of several gigabytes on remote storage and starting from any point within the file. I have the C++ version and the Delphi version available to trace. The Buffer comes from an Elecard mpeg demultiplexer and is known to be good. The parameters going into the function, even the address of the buffer, are identical in the C++ version and the Delphi version (which is surprising in itself). The Overlapped structure is initialised in another function and given an event as per the C++ example. The content of the Overlapped structure is alsp the same.
I have tried using a locally generated buffer within the function and the behaviour depends upon the filter read size. For small sizes the function succeeds but there is no data in the buffer, for large sizes, the function fails as it should but with an error of 998(ERROR_NOACCESS) instead of 997 (ERROR_IO_PENDING). Interestingly, the parameters in the Overlapped structure after the ReadFile are the same in the C++ and Delphi versions indicating that the call has behaved similarly in both cases, its just that the outcome is different. Its almost as if the definition of ReadFile in Windows.pas:
function ReadFile(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD;
var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;
{$EXTERNALSYM ReadFile}
is not working as expected. I'm using RADStudio 2007 for my Delphi coding.
Sorry, I'm new to using this site and I realise I did not give a detailed enough problem description. I cannot find a means to modify my question so I am adding a comment in the hope you might notice it and tell me how to do so.
I'm aware Delph has a TFileStream class, which I am not using. My code is a direct translation of an improved version of the DirectShow SDK's async filter. The name FileStream may be confusing to a Delphi developer but it describes the function of the class in my code.
The DirectShow filter does indeed use asynchronous reading since it may be accessing media files of several gigabytes on remote storage and starting from any point within the file. I have the C++ version and the Delphi version available to trace. The Buffer comes from an Elecard mpeg demultiplexer and is known to be good. The parameters going into the function, even the address of the buffer, are identical in the C++ version and the Delphi version (which is surprising in itself). The Overlapped structure is initialised in another function and given an event as per the C++ example. The content of the Overlapped structure is alsp the same.
I have tried using a locally generated buffer within the function and the behaviour depends upon the filter read size. For small sizes the function succeeds but there is no data in the buffer, for large sizes, the function fails as it should but with an error of 998(ERROR_NOACCESS) instead of 997 (ERROR_IO_PENDING). Interestingly, the parameters in the Overlapped structure after the ReadFile are the same in the C++ and Delphi versions indicating that the call has behaved similarly in both cases, its just that the outcome is different. Its almost as if the definition of ReadFile in Windows.pas:
function ReadFile(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD;
var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;
{$EXTERNALSYM ReadFile}
is not working as expected. I'm using RADStudio 2007 for my Delphi coding.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ziolko.