WriteFile with Windows Sockets returns invalid parameter error

有些话、适合烂在心里 提交于 2019-12-06 11:22:53

from WriteFile documentation

lpOverlapped [in, out, optional]

A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can be NULL.

but are socket function create file (socket this is file handle, it point to FILE_OBJECT structure) with FILE_FLAG_OVERLAPPED ? this is undocumented and you cannot control this. so you need use OVERLAPPED as parameter for WriteFile.

if use WSASocket we already here have dwFlags option and can set or not set WSA_FLAG_OVERLAPPED (which is equivalent of FILE_FLAG_OVERLAPPED for CreateFile)

why OVERLAPPED structure is required when we use hFile opened with FILE_FLAG_OVERLAPPED flag (no FO_SYNCHRONOUS_IO flag in FILE_OBJECT) ?

WriteFile call ZwWriteFile

look for

PLARGE_INTEGER ByteOffset [in, optional] parameter of ZwWriteFile - but it optional only if we open file as synchronous. if file opened in asynchronous i/o mode - this parameter is mandatory.

from wrk source code

if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
}
else if (!ARGUMENT_PRESENT( ByteOffset ) && !(fileObject->Flags & (FO_NAMED_PIPE | FO_MAILSLOT))) {

        //
        // The file is not open for synchronous I/O operations, but the
        // caller did not specify a ByteOffset parameter.  This is an error
        // situation, so cleanup and return with the appropriate status.
        //

        if (eventObject) {
            ObDereferenceObject( eventObject );
        }
        ObDereferenceObject( fileObject );
        return STATUS_INVALID_PARAMETER;

    }

this is exactly your case when you call

WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10,NULL,NULL);

NtWriteFile return to you STATUS_INVALID_PARAMETER which converted to win32 error ERROR_INVALID_PARAMETER

but next code will be worked ok.

OVERLAPPED ov = {};
BOOL isSent = WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10, 0, &ov);

because in this case ByteOffset will be point to &ov.Offset

however for send data to socket much more better use WSASend

MSDN says it should be possible.

Does it really? The socket handles documentation states:

A socket handle can optionally be a file handle in Windows Sockets 2. A socket handle from a Winsock provider can be used with other non-Winsock functions such as ReadFile, WriteFile, ReadFileEx, and WriteFileEx.

Note the word "optionally".

Per this discussion:

WriteFile with SocketHandle Fails

...

Not sure how you can read that page and think that it is a good idea to use a socket handle with ReadFile et al.

Let's start with this sentence "A socket handle can optionally be a file handle in Windows Sockets 2". That can be read two different ways:

  1. You can optionally use any socket handle as a file handle for ReadFile and friends

  2. A socket provider can optionally provide dual-use sockets that work with ReadFile as well as the socket functions.

Unfortunately there is not enough information in that article to conclusively decide whether #1 or #2 is correct. However the fact that ReadFile returns ERROR_INVALID_PARAMETER (per Mike Danes' comment) I am going to assume that #2 is the correct interpretation and your network socket is not also a file handle. (Note that frequently the MSDN documentation is written more from the perspective of the team that implemented API than from a consumer of the API. If you look at it in that light, #2 is the more likely interpretation -- I will agree that it is annoying because a consumer of the API is more likely to understand the sentence as #1)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!