Forum > Windows

The declaration of WriteFile, ReadFile win32 api may be incorrect.

<< < (2/7) > >>

tetrastes:

--- Quote from: marunguy on May 19, 2022, 10:25:54 am ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Windows.WriteFile(my_hdl, buf, buf_len, written_bytes, nil)Windows.ReadFile(my_hdl, buf, buf_len, read_bytes, nil);
Invalid Buffer value is passed in win64 build mode.
The access viloation exception occurs in win32 build mode when ReadFile is called.

--- End quote ---

You didn't write what were your parameters, and how you passed them exactly.
This is how it is done e.g. in synaser.pas:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---varFHandle: THandle;Buffer: pointer;Length: longint;Result: longint;Overlapped: TOverlapped; ... WriteFile(FHandle, Buffer^, Length, DWord(Result), @Overlapped);ReadFile(FHandle, Buffer^, Length, Dword(Result), @Overlapped);
and it works for more than twenty years without any problem.

440bx:

--- Quote from: tetrastes on May 19, 2022, 02:08:53 pm ---and it works for more than twenty years without any problem.

--- End quote ---
and, it could work for 20,000 years and it would still be wrong because it should NOT be necessary to dereference the Buffer variable.

Also, since the variable Buffer is just a "pointer", what is Buffer^ supposed to be pointing to ?... a byte ?.. a word ?... a qword ?... mother Theresa ?... the neighbor's dog ? ... semantically, dereferencing a generic pointer is meaningless since it doesn't point to a known type.

@Trev,

yes, an overload (using the correct definition) would definitely be a good thing in this case and, it seems its presence would not break any existing code.

tetrastes:

--- Quote from: 440bx on May 19, 2022, 02:40:00 pm ---
--- Quote from: tetrastes on May 19, 2022, 02:08:53 pm ---and it works for more than twenty years without any problem.

--- End quote ---
and, it could work for 20,000 years and it would still be wrong because it should NOT be necessary to dereference the Buffer variable.

Also, since the variable Buffer is just a "pointer", what is Buffer^ supposed to be pointing to ?... a byte ?.. a word ?... a qword ?... mother Theresa ?... the neighbor's dog ? ... semantically, dereferencing a generic pointer is meaningless since it doesn't point to a known type.

--- End quote ---
OP started this thread because he got errors, and supposed that these errors were due to incorrect declarations. I simply gave him example of code (from heavily used library) using these declarations without errors.
I can hardly suppose that you don't know, that you can use these declarations without explicit dereferencing. You think that such declaration is wrong because it leads to some overhead in compiled code? It depends on compiler, I think, and doesn't mean that it is wrong, at least in Pascal.

And of course Buffer points to something valid somewhere in the real code. This is not complete compilable example, as you may guess.  ;)

marcov:

--- Quote from: 440bx on May 19, 2022, 02:40:00 pm ---
--- Quote from: tetrastes on May 19, 2022, 02:08:53 pm ---and it works for more than twenty years without any problem.

--- End quote ---
and, it could work for 20,000 years and it would still be wrong because it should NOT be necessary to dereference the Buffer variable.

--- End quote ---

"wrong" is a relative term here. Code that hits this is wrong, since it is incompatible with both FPC and Delphi declarations. So the original code is simply wrong, or from a very deviant Pascal dialect.


--- Quote ---Also, since the variable Buffer is just a "pointer", what is Buffer^ supposed to be pointing to ?... a byte ?..
a word ?... a qword ?... mother Theresa ?... the neighbor's dog ? ... semantically, dereferencing a generic pointer is meaningless since it doesn't point to a known type.

--- End quote ---

The equivalent of void, which is easy to see as sizeof(p^)=0 if you print it in both FPC and Delphi. Though in this case it never really is dereferenced, but passed to a formal parameter (which is byref).

So please don't deref Mother Theressa and let her rest :-)


--- Quote ---a word ?... a qword ?... mother Theresa ?... the neighbor's dog ? ... semantically, dereferencing a generic pointer is meaningless since it doesn't point to a known type.

--- End quote ---

Can you do it in C ?  * a void* ?     But I assume it is less useful there as C has no formal parameters. But keep in mind that pascal's  move() also has formal parameters, as do blockread/write etc.


--- Quote ---yes, an overload (using the correct definition) would definitely be a good thing in this case and, it seems its presence would not break any existing code.

--- End quote ---

Overloading more than one difference is somewhat dangerous, because people get weird errormessages if they pass e.g. a pointer and don't @ the other etc. 

Normally I wouldn't mind, but by such a core procedure I get a tad conservative. It has the potential to cause problems without much gain.

marunguy:
Windows.WriteFile sample source

Windows 10 64bit, Lazarus 2.2.2 64bit, FPC 3.2.2

I'm a lazarus beginner and there may be mistakes in my sample code.

When use Windows.WriteFile, garbage values are written to the file.
When use MyWriteFile, correct values are written to the file.

* hexdump test.txt - Windows.WriteFile

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---80 5E 03 00 01 00 00 00 2C 01
* hexdump test.txt - MyWriteFile

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---30 31 32 33 34 35 36 37 38 39
* sample code

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit unitmain; {$mode ObjFPC}{$H+} interface uses    Classes, SysUtils, Windows; function MyWriteFile(hFile: THandle; const Buffer: Pointer; const nNumberOfBytesToWrite: DWORD; lpNumberOfBytesWritten: PDWORD; lpOverlapped: POverlapped): BOOL; stdcall; external 'kernel32' name 'WriteFile'; procedure test_writefile(); implementation procedure test_writefile();var    file_hdl: HANDLE = 0;    buffer: PChar = '0123456789';    written: DWORD = 0;begin    file_hdl := Windows.CreateFileW(PWideChar(UnicodeString('test.txt')), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);    if file_hdl = INVALID_HANDLE_VALUE then    begin        WriteLn(Format('failed to CreateFileW, LE=%d', [GetLastError()]));        exit;    end;     try        if not Windows.WriteFile(file_hdl, buffer, Length(buffer), written, nil) then        // if not MyWriteFile(file_hdl, buffer, Length(buffer), @written, nil) then        begin            WriteLn(Format('failed to WriteFile, LE=%d', [GetLastError()]));            exit;        end;    finally        Windows.CloseHandle(file_hdl);    end; end; initialization test_writefile(); end. 

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version