On Aug 29, 2013, at 6:43 PM, Bruno Jesus wrote: > Hi all, I need some help to continue my current wine work. > > In order to implement SO_PROTOCOL_INFO for getsockopt I need to > retrieve some information from the socket like its family and > protocol. > > I have searched for a few days and ended up with a solution I dislike > so I had a better idea (at least I hope I did). > > Instead of using non-portable SO_DOMAIN and SO_PROTOCOL/SO_PROTOTYPE > to retrieve the socket family and protocol or using non-reliable > guessing using only the socket type I thought it would be better to > ask the server for this information. Using a request just like is used > for several other information in ws2_32 (operation which will work on > every OS). > > So, all I need is a server request that based on the socket fd will > return the socket family, type and protocol. I tried to understand how > requests work but I failed completely. > > Maybe this request can be later improved to return the connection time > so we can finally fix SO_CONNECT_TIME option. > > The current solution is attached, since I sent the tests separated and > they were commited the patch will not apply, it's only for reference. > The idea is to remove the functions get_sock_[family|protocol|type] to > a single server request. > > So, is this a good idea? There's no way I know of to get this information directly on at least Mac OS, so I'd say go for it. (But I can't speak for anyone else on this list, so...) > If yes, how can I create and use the request? To add a new request to the server, you first add a definition to server/protocol.def . This file is processed by the make_requests tool, which generates a bunch of other files from it. The syntax of the server protocol definition file is somewhat like Objective-C (if you've ever used or seen that). A typical server request definition looks like this:
@REQ(request_name) /* input parameters go here */ int input; obj_handle_t handle; /* don't use Windows types */ @REPLY /* output values go here */ int output; @END As with all generated files, the files generated by make_requests shouldn't be included in your patch. After defining a new server call, you define the handler in the server like so: DECL_HANDLER(request_name) { /* implicit parameters: req, reply */ /* use the 'current' global to refer to the process and thread that made the request */ if (req->handle != ((obj_handle_t)-1)) { reply->output = do_something(req->input, req->handle); } else { set_error(STATUS_UNSUCCESSFUL); /* NTSTATUS is returned to client */ } /* no return value */ } Then, in the client DLLs, you make server calls like this: SERVER_START_REQ( request_name ) { /* implicit variables: req, reply */ req->input = 1; req->handle = wine_server_obj_handle( handle ); /* converts Windows HANDLE to a server obj_handle_t */ if (wine_server_call( req ) != STATUS_SUCCESS) { /* SetLastError(), return error code, etc. */ } do_something(reply->output); } SERVER_END_REQ; There's lots of examples throughout Wine of this in action, especially in lower-level DLLs like ntdll and kernel32; I encourage you to look at them. (That's how I figured all this out, after all.) If you have any more questions (and not just because you were too lazy to even look ;), feel free to ask. Chip