winehq.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
September
August
July
June
May
April
March
February
January
2001
December
November
October
September
August
July
June
May
April
March
February
List overview
wine-commits
August 2018
----- 2025 -----
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
2 participants
618 discussions
Start a n
N
ew thread
Jacek Caban : server: Store named_pipe reference in pipe_end struct.
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: ba40a0db8a7bd05b2e6e2763041875bcbc5af1b8 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=ba40a0db8a7bd05b2e6e2763…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Thu Aug 16 15:10:33 2018 +0200 server: Store named_pipe reference in pipe_end struct. Allows pipe clients to access named_pipe object after server is closed without disconnecting. Signed-off-by: Jacek Caban <jacek(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- server/named_pipe.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/server/named_pipe.c b/server/named_pipe.c index 768567f..ab71f36 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -67,6 +67,7 @@ struct pipe_end struct fd *fd; /* pipe file descriptor */ unsigned int flags; /* pipe flags */ unsigned int state; /* pipe state */ + struct named_pipe *pipe; struct pipe_end *connection; /* the other end of the pipe */ process_id_t client_pid; /* process that created the client */ process_id_t server_pid; /* process that created the server */ @@ -416,14 +417,20 @@ static void pipe_end_destroy( struct pipe_end *pipe_end ) free_async_queue( &pipe_end->read_q ); free_async_queue( &pipe_end->write_q ); if (pipe_end->fd) release_object( pipe_end->fd ); + if (pipe_end->pipe) release_object( pipe_end->pipe ); } static void pipe_server_destroy( struct object *obj) { struct pipe_server *server = (struct pipe_server *)obj; + struct named_pipe *pipe = server->pipe_end.pipe; assert( obj->ops == &pipe_server_ops ); + assert( pipe->instances ); + if (!--pipe->instances) unlink_named_object( &pipe->obj ); + list_remove( &server->entry ); + pipe_end_disconnect( &server->pipe_end, STATUS_PIPE_BROKEN ); pipe_end_destroy( &server->pipe_end ); @@ -433,11 +440,7 @@ static void pipe_server_destroy( struct object *obj) server->client = NULL; } - assert( server->pipe->instances ); - server->pipe->instances--; - - list_remove( &server->entry ); - release_object( server->pipe ); + release_object( pipe ); } static void pipe_client_destroy( struct object *obj) @@ -573,6 +576,12 @@ static void pipe_end_get_file_info( struct fd *fd, struct named_pipe *pipe, unsi } name = get_object_name( &pipe->obj, &name_len ); + /* FIXME: We should be able to return on unlinked pipe */ + if (!name) + { + set_error( STATUS_PIPE_DISCONNECTED ); + return; + } reply_size = offsetof( FILE_NAME_INFORMATION, FileName[name_len/sizeof(WCHAR) + 1] ); if (reply_size > get_reply_max_size()) { @@ -1043,7 +1052,10 @@ static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *as case ps_connected_server: assert( server->client ); - /* dump the client and server fds - client loses all waiting data */ + /* dump the client connection - all data is lost */ + release_object( server->pipe_end.connection->pipe ); + server->pipe_end.connection->pipe = NULL; + pipe_end_disconnect( &server->pipe_end, STATUS_PIPE_DISCONNECTED ); server->client->server = NULL; server->client = NULL; @@ -1092,8 +1104,10 @@ static struct pipe_server *get_pipe_server_obj( struct process *process, return (struct pipe_server *) obj; } -static void init_pipe_end( struct pipe_end *pipe_end, unsigned int pipe_flags, data_size_t buffer_size ) +static void init_pipe_end( struct pipe_end *pipe_end, struct named_pipe *pipe, + unsigned int pipe_flags, data_size_t buffer_size ) { + pipe_end->pipe = (struct named_pipe *)grab_object( pipe ); pipe_end->fd = NULL; pipe_end->flags = pipe_flags; pipe_end->connection = NULL; @@ -1115,7 +1129,7 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned server->pipe = pipe; server->client = NULL; server->options = options; - init_pipe_end( &server->pipe_end, pipe_flags, pipe->insize ); + init_pipe_end( &server->pipe_end, pipe, pipe_flags, pipe->insize ); server->pipe_end.state = FILE_PIPE_LISTENING_STATE; server->pipe_end.server_pid = get_process_id( current->process ); @@ -1132,7 +1146,7 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned return server; } -static struct pipe_client *create_pipe_client( unsigned int flags, unsigned int pipe_flags, +static struct pipe_client *create_pipe_client( unsigned int flags, struct named_pipe *pipe, data_size_t buffer_size, unsigned int options ) { struct pipe_client *client; @@ -1143,7 +1157,7 @@ static struct pipe_client *create_pipe_client( unsigned int flags, unsigned int client->server = NULL; client->flags = flags; - init_pipe_end( &client->pipe_end, pipe_flags, buffer_size ); + init_pipe_end( &client->pipe_end, pipe, pipe->flags, buffer_size ); client->pipe_end.state = FILE_PIPE_CONNECTED_STATE; client->pipe_end.client_pid = get_process_id( current->process ); @@ -1217,7 +1231,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc return NULL; } - if ((client = create_pipe_client( options, pipe->flags, pipe->outsize, options ))) + if ((client = create_pipe_client( options, pipe, pipe->outsize, options ))) { if (server->state == ps_wait_open) fd_async_wake_up( server->pipe_end.fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
1
0
0
0
Jacek Caban : ntdll/tests: Add more NtQueryInformationFile tests.
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: 59dd8baeac54f0739ba9bbb089ab037298e04775 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=59dd8baeac54f0739ba9bbb0…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Thu Aug 16 15:10:15 2018 +0200 ntdll/tests: Add more NtQueryInformationFile tests. Signed-off-by: Jacek Caban <jacek(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntdll/tests/pipe.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index cb31956..e28628b 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -1349,7 +1349,7 @@ static void test_pipe_with_data_state(HANDLE pipe, BOOL is_server, DWORD state) FILE_PIPE_INFORMATION pipe_info; FILE_PIPE_PEEK_BUFFER peek_buf; IO_STATUS_BLOCK io; - char buf[] = "test"; + char buf[256] = "test"; NTSTATUS status, expected_status; memset(&io, 0xcc, sizeof(io)); @@ -1379,6 +1379,15 @@ static void test_pipe_with_data_state(HANDLE pipe, BOOL is_server, DWORD state) "NtQueryInformationFile(FilePipeInformation) failed in %s state %u: %x\n", is_server ? "server" : "client", state, status); + status = NtQueryInformationFile(pipe, &io, buf, sizeof(buf), FileNameInformation); + if (!is_server && state == FILE_PIPE_DISCONNECTED_STATE) + ok(status == STATUS_PIPE_DISCONNECTED, + "NtQueryInformationFile(FileNameInformation) failed: %x\n", status); + else + todo_wine_if(!is_server && state == FILE_PIPE_CLOSING_STATE) + ok(status == STATUS_SUCCESS, + "NtQueryInformationFile(FileNameInformation) failed: %x\n", status); + memset(&peek_buf, 0xcc, sizeof(peek_buf)); memset(&io, 0xcc, sizeof(io)); status = NtFsControlFile(pipe, NULL, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0, &peek_buf, sizeof(peek_buf)); @@ -1492,6 +1501,154 @@ static void pipe_for_each_state(HANDLE (*create_server)(void), CloseHandle(event); } +static HANDLE create_local_info_test_pipe(void) +{ + IO_STATUS_BLOCK iosb; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING name; + LARGE_INTEGER timeout; + HANDLE pipe; + NTSTATUS status; + + pRtlInitUnicodeString(&name, testpipe_nt); + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &name; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + timeout.QuadPart = -100000000; + + status = pNtCreateNamedPipeFile(&pipe, FILE_READ_ATTRIBUTES | SYNCHRONIZE | GENERIC_WRITE, + &attr, &iosb, FILE_SHARE_READ, FILE_CREATE, 0, 1, 0, 0, 1, + 100, 200, &timeout); + ok(status == STATUS_SUCCESS, "NtCreateNamedPipeFile failed: %x\n", status); + + return pipe; +} + +static HANDLE connect_pipe_reader(HANDLE server) +{ + HANDLE client; + + client = CreateFileW(testpipe, GENERIC_READ, 0, 0, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, 0); + ok(client != INVALID_HANDLE_VALUE, "can't open pipe: %u\n", GetLastError()); + + return client; +} + +static void test_pipe_local_info(HANDLE pipe, BOOL is_server, DWORD state) +{ + FILE_PIPE_LOCAL_INFORMATION local_info; + FILE_PIPE_INFORMATION pipe_info; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING name; + LARGE_INTEGER timeout; + HANDLE new_pipe; + IO_STATUS_BLOCK iosb; + NTSTATUS status; + + memset(&iosb, 0xcc, sizeof(iosb)); + memset(&local_info, 0xcc, sizeof(local_info)); + status = pNtQueryInformationFile(pipe, &iosb, &local_info, sizeof(local_info), FilePipeLocalInformation); + if (!is_server && state == FILE_PIPE_DISCONNECTED_STATE) + todo_wine + ok(status == STATUS_PIPE_DISCONNECTED, + "NtQueryInformationFile(FilePipeLocalInformation) failed in %s state %u: %x\n", + is_server ? "server" : "client", state, status); + else + ok(status == STATUS_SUCCESS, + "NtQueryInformationFile(FilePipeLocalInformation) failed in %s state %u: %x\n", + is_server ? "server" : "client", state, status); + if (!status) + { + ok(local_info.NamedPipeType == 1, "NamedPipeType = %u\n", local_info.NamedPipeType); + todo_wine_if(!is_server && (state == FILE_PIPE_CLOSING_STATE || state == FILE_PIPE_DISCONNECTED_STATE)) + ok(local_info.NamedPipeConfiguration == 1, "NamedPipeConfiguration = %u\n", + local_info.NamedPipeConfiguration); + todo_wine_if(!is_server && (state == FILE_PIPE_CLOSING_STATE || state == FILE_PIPE_DISCONNECTED_STATE)) + ok(local_info.MaximumInstances == 1, "MaximumInstances = %u\n", local_info.MaximumInstances); + if (!is_server && state == FILE_PIPE_CLOSING_STATE) + ok(local_info.CurrentInstances == 0 || broken(local_info.CurrentInstances == 1 /* winxp */), + "CurrentInstances = %u\n", local_info.CurrentInstances); + else + todo_wine_if(!is_server && state == FILE_PIPE_DISCONNECTED_STATE) + ok(local_info.CurrentInstances == 1, + "CurrentInstances = %u\n", local_info.CurrentInstances); + todo_wine_if(!is_server && (state == FILE_PIPE_CLOSING_STATE || state == FILE_PIPE_DISCONNECTED_STATE)) + ok(local_info.InboundQuota == 100, "InboundQuota = %u\n", local_info.InboundQuota); + ok(local_info.ReadDataAvailable == 0, "ReadDataAvailable = %u\n", + local_info.ReadDataAvailable); + todo_wine_if(!is_server && (state == FILE_PIPE_CLOSING_STATE || state == FILE_PIPE_DISCONNECTED_STATE)) + ok(local_info.OutboundQuota == 200, "OutboundQuota = %u\n", local_info.OutboundQuota); + todo_wine + ok(local_info.WriteQuotaAvailable == (is_server ? 200 : 100), "WriteQuotaAvailable = %u\n", + local_info.WriteQuotaAvailable); + todo_wine + ok(local_info.NamedPipeState == state, "%s NamedPipeState = %u, expected %u\n", + is_server ? "server" : "client", local_info.NamedPipeState, state); + ok(local_info.NamedPipeEnd == is_server, "NamedPipeEnd = %u\n", local_info.NamedPipeEnd); + + /* try to create another, incompatible, instance of pipe */ + pRtlInitUnicodeString(&name, testpipe_nt); + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &name; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + timeout.QuadPart = -100000000; + + status = pNtCreateNamedPipeFile(&new_pipe, FILE_READ_ATTRIBUTES | SYNCHRONIZE | GENERIC_READ, + &attr, &iosb, FILE_SHARE_WRITE, FILE_CREATE, 0, 0, 0, 0, 1, + 100, 200, &timeout); + if (!local_info.CurrentInstances) + todo_wine_if(status) /* FIXME */ + ok(status == STATUS_SUCCESS, "NtCreateNamedPipeFile failed: %x\n", status); + else + ok(status == STATUS_INSTANCE_NOT_AVAILABLE, "NtCreateNamedPipeFile failed: %x\n", status); + if (!status) CloseHandle(new_pipe); + + memset(&iosb, 0xcc, sizeof(iosb)); + status = pNtQueryInformationFile(pipe, &iosb, &local_info, sizeof(local_info), + FilePipeLocalInformation); + ok(status == STATUS_SUCCESS, + "NtQueryInformationFile(FilePipeLocalInformation) failed in %s state %u: %x\n", + is_server ? "server" : "client", state, status); + + if (!is_server && state == FILE_PIPE_CLOSING_STATE) + ok(local_info.CurrentInstances == 0 || broken(local_info.CurrentInstances == 1 /* winxp */), + "CurrentInstances = %u\n", local_info.CurrentInstances); + else + todo_wine_if(!is_server && state == FILE_PIPE_DISCONNECTED_STATE) + ok(local_info.CurrentInstances == 1, + "CurrentInstances = %u\n", local_info.CurrentInstances); + } + + memset(&iosb, 0xcc, sizeof(iosb)); + status = pNtQueryInformationFile(pipe, &iosb, &pipe_info, sizeof(pipe_info), FilePipeInformation); + if (!is_server && state == FILE_PIPE_DISCONNECTED_STATE) + todo_wine + ok(status == STATUS_PIPE_DISCONNECTED, + "NtQueryInformationFile(FilePipeLocalInformation) failed in %s state %u: %x\n", + is_server ? "server" : "client", state, status); + else + ok(status == STATUS_SUCCESS, + "NtQueryInformationFile(FilePipeLocalInformation) failed in %s state %u: %x\n", + is_server ? "server" : "client", state, status); + + if (!status) + { + ok(pipe_info.ReadMode == 0, "ReadMode = %u\n", pipe_info.ReadMode); + ok(pipe_info.CompletionMode == 0, "CompletionMode = %u\n", pipe_info.CompletionMode); + } +} + static void test_file_info(void) { HANDLE server, client; @@ -1771,4 +1928,5 @@ START_TEST(pipe) pipe_for_each_state(create_pipe_server, connect_pipe, test_pipe_state); pipe_for_each_state(create_pipe_server, connect_and_write_pipe, test_pipe_with_data_state); + pipe_for_each_state(create_local_info_test_pipe, connect_pipe_reader, test_pipe_local_info); }
1
0
0
0
Jacek Caban : kernel32/tests: Add more pipe tests.
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: a9ef1dd5dc31199683d23618b54e241f30ed4485 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=a9ef1dd5dc31199683d23618…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Thu Aug 16 15:09:49 2018 +0200 kernel32/tests: Add more pipe tests. Signed-off-by: Jacek Caban <jacek(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/kernel32/tests/pipe.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index d724e00..3c7fcd1 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -1448,6 +1448,11 @@ static int test_DisconnectNamedPipe(void) ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe while messages waiting\n"); ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL) == 0 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe\n"); + ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0 + && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe\n"); + ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL) == 0 + && GetLastError() == ERROR_PIPE_NOT_CONNECTED, + "ReadFile from disconnected pipe with bytes waiting\n"); ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile from disconnected pipe with bytes waiting\n");
1
0
0
0
Nikolay Sivov : dwrite: Multiply run analysis transform by dpi scale factor.
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: 7e0d10250c17457d9b73118ef6eba066e9e71daa URL:
https://source.winehq.org/git/wine.git/?a=commit;h=7e0d10250c17457d9b73118e…
Author: Nikolay Sivov <nsivov(a)codeweavers.com> Date: Thu Aug 16 13:34:44 2018 +0300 dwrite: Multiply run analysis transform by dpi scale factor. Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dwrite/dwrite_private.h | 4 +-- dlls/dwrite/font.c | 17 ++++++----- dlls/dwrite/main.c | 67 +++++++++++++++++++++++++++----------------- 3 files changed, 50 insertions(+), 38 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 31b977a..a19380a 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -117,9 +117,7 @@ struct glyphrunanalysis_desc DWRITE_MEASURING_MODE measuring_mode; DWRITE_GRID_FIT_MODE gridfit_mode; DWRITE_TEXT_ANTIALIAS_MODE aa_mode; - FLOAT origin_x; - FLOAT origin_y; - FLOAT ppdip; + D2D_POINT_2F origin; }; struct fontface_desc diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 9556fd3..5fc0de7 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -5397,7 +5397,6 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit analysis->max_glyph_bitmap_size = 0; SetRectEmpty(&analysis->bounds); analysis->run = *desc->run; - analysis->run.fontEmSize *= desc->ppdip; IDWriteFontFace_AddRef(analysis->run.fontFace); analysis->glyphs = heap_alloc(desc->run->glyphCount * sizeof(*analysis->glyphs)); analysis->origins = heap_alloc(desc->run->glyphCount * sizeof(*analysis->origins)); @@ -5433,14 +5432,14 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit if (FAILED(hr = IDWriteFontFace_QueryInterface(desc->run->fontFace, &IID_IDWriteFontFace1, (void **)&fontface1))) WARN("Failed to get IDWriteFontFace1, %#x.\n", hr); - origin.x = desc->origin_x * desc->ppdip; - origin.y = desc->origin_y * desc->ppdip; + origin.x = desc->origin.x; + origin.y = desc->origin.y; for (i = 0; i < desc->run->glyphCount; i++) { FLOAT advance; /* Use nominal advances if not provided by caller. */ if (desc->run->glyphAdvances) - advance = rtl_factor * desc->run->glyphAdvances[i] * desc->ppdip; + advance = rtl_factor * desc->run->glyphAdvances[i]; else { INT32 a; @@ -5450,14 +5449,14 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit case DWRITE_MEASURING_MODE_NATURAL: if (SUCCEEDED(IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, desc->run->glyphIndices + i, &a, desc->run->isSideways))) - advance = rtl_factor * get_scaled_advance_width(a, desc->run->fontEmSize, &metrics) * desc->ppdip; + advance = rtl_factor * get_scaled_advance_width(a, desc->run->fontEmSize, &metrics); break; case DWRITE_MEASURING_MODE_GDI_CLASSIC: case DWRITE_MEASURING_MODE_GDI_NATURAL: if (SUCCEEDED(IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, desc->run->fontEmSize, - desc->ppdip, desc->transform, desc->measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, + 1.0f, desc->transform, desc->measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, desc->run->isSideways, 1, desc->run->glyphIndices + i, &a))) - advance = rtl_factor * floorf(a * desc->run->fontEmSize * desc->ppdip / metrics.designUnitsPerEm + 0.5f); + advance = rtl_factor * floorf(a * desc->run->fontEmSize / metrics.designUnitsPerEm + 0.5f); break; default: ; @@ -5468,8 +5467,8 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit /* Offsets are optional, appled to pre-transformed origin. */ if (desc->run->glyphOffsets) { - FLOAT advanceoffset = rtl_factor * desc->run->glyphOffsets[i].advanceOffset * desc->ppdip; - FLOAT ascenderoffset = -desc->run->glyphOffsets[i].ascenderOffset * desc->ppdip; + FLOAT advanceoffset = rtl_factor * desc->run->glyphOffsets[i].advanceOffset; + FLOAT ascenderoffset = -desc->run->glyphOffsets[i].ascenderOffset; if (desc->run->isSideways) { analysis->origins[i].x += ascenderoffset; diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index c4d2a5f..522bac8 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1222,12 +1222,25 @@ static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory5 *if return create_numbersubstitution(method, locale, ignore_user_override, substitution); } +static inline void dwrite_matrix_multiply(DWRITE_MATRIX *a, const DWRITE_MATRIX *b) +{ + DWRITE_MATRIX tmp = *a; + + a->m11 = tmp.m11 * b->m11 + tmp.m12 * b->m21; + a->m12 = tmp.m11 * b->m12 + tmp.m12 * b->m22; + a->m21 = tmp.m21 * b->m11 + tmp.m22 * b->m21; + a->m22 = tmp.m21 * b->m12 + tmp.m22 * b->m22; + a->dx = tmp.dx * b->m11 + tmp.dy * b->m21 + b->dx; + a->dy = tmp.dy * b->m12 + tmp.dy * b->m22 + b->dx; +} + static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory5 *iface, DWRITE_GLYPH_RUN const *run, FLOAT ppdip, DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis) { struct dwritefactory *This = impl_from_IDWriteFactory5(iface); struct glyphrunanalysis_desc desc; + DWRITE_MATRIX m, scale = { 0 }; TRACE("(%p)->(%p %.2f %p %d %d %.2f %.2f %p)\n", This, run, ppdip, transform, rendering_mode, measuring_mode, originX, originY, analysis); @@ -1237,15 +1250,18 @@ static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory5 *ifac return E_INVALIDARG; } + m = transform ? *transform : identity; + scale.m11 = ppdip; + scale.m22 = ppdip; + dwrite_matrix_multiply(&m, &scale); desc.run = run; - desc.ppdip = ppdip; - desc.transform = transform; + desc.transform = &m; desc.rendering_mode = (DWRITE_RENDERING_MODE1)rendering_mode; desc.measuring_mode = measuring_mode; desc.gridfit_mode = DWRITE_GRID_FIT_MODE_DEFAULT; desc.aa_mode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE; - desc.origin_x = originX; - desc.origin_y = originY; + desc.origin.x = originX; + desc.origin.y = originY; return create_glyphrunanalysis(&desc, analysis); } @@ -1363,27 +1379,35 @@ static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory5 return hr; } +static HRESULT factory_create_glyphrun_analysis(const DWRITE_GLYPH_RUN *run, const DWRITE_MATRIX *transform, + DWRITE_RENDERING_MODE1 rendering_mode, DWRITE_MEASURING_MODE measuring_mode, DWRITE_GRID_FIT_MODE gridfit_mode, + DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis) +{ + struct glyphrunanalysis_desc desc; + + desc.run = run; + desc.transform = transform; + desc.rendering_mode = rendering_mode; + desc.measuring_mode = measuring_mode; + desc.gridfit_mode = gridfit_mode; + desc.aa_mode = aa_mode; + desc.origin.x = originX; + desc.origin.y = originY; + return create_glyphrunanalysis(&desc, analysis); +} + static HRESULT WINAPI dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory5 *iface, const DWRITE_GLYPH_RUN *run, const DWRITE_MATRIX *transform, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, DWRITE_GRID_FIT_MODE gridfit_mode, DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis) { struct dwritefactory *This = impl_from_IDWriteFactory5(iface); - struct glyphrunanalysis_desc desc; TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This, run, transform, rendering_mode, measuring_mode, gridfit_mode, aa_mode, originX, originY, analysis); - desc.run = run; - desc.ppdip = 1.0f; - desc.transform = transform; - desc.rendering_mode = (DWRITE_RENDERING_MODE1)rendering_mode; - desc.measuring_mode = measuring_mode; - desc.gridfit_mode = gridfit_mode; - desc.aa_mode = aa_mode; - desc.origin_x = originX; - desc.origin_y = originY; - return create_glyphrunanalysis(&desc, analysis); + return factory_create_glyphrun_analysis(run, transform, (DWRITE_RENDERING_MODE1)rendering_mode, measuring_mode, + gridfit_mode, aa_mode, originX, originY, analysis); } static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory5 *iface, DWRITE_GLYPH_RUN const *run, @@ -1392,21 +1416,12 @@ static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory5 *ifa IDWriteGlyphRunAnalysis **analysis) { struct dwritefactory *This = impl_from_IDWriteFactory5(iface); - struct glyphrunanalysis_desc desc; TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This, run, transform, rendering_mode, measuring_mode, gridfit_mode, aa_mode, originX, originY, analysis); - desc.run = run; - desc.ppdip = 1.0f; - desc.transform = transform; - desc.rendering_mode = rendering_mode; - desc.measuring_mode = measuring_mode; - desc.gridfit_mode = gridfit_mode; - desc.aa_mode = aa_mode; - desc.origin_x = originX; - desc.origin_y = originY; - return create_glyphrunanalysis(&desc, analysis); + return factory_create_glyphrun_analysis(run, transform, rendering_mode, measuring_mode, gridfit_mode, + aa_mode, originX, originY, analysis); } static HRESULT WINAPI dwritefactory3_CreateCustomRenderingParams(IDWriteFactory5 *iface, FLOAT gamma, FLOAT contrast,
1
0
0
0
Nikolay Sivov : d2d1: Fix scaling when rendering text in bitmap mode.
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: 32b35f8000c03de7ca4e30be4d1b54605530562a URL:
https://source.winehq.org/git/wine.git/?a=commit;h=32b35f8000c03de7ca4e30be…
Author: Nikolay Sivov <nsivov(a)codeweavers.com> Date: Thu Aug 16 16:43:28 2018 +0430 d2d1: Fix scaling when rendering text in bitmap mode. Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/d2d1/device.c | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 67b3fab..cb7e8a5 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -1107,10 +1107,9 @@ static void d2d_rt_draw_glyph_run_outline(struct d2d_d3d_render_target *render_t static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_target, D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush, - float ppd, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, + DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, DWRITE_TEXT_ANTIALIAS_MODE antialias_mode) { - D2D1_MATRIX_3X2_F prev_transform, *transform; ID2D1RectangleGeometry *geometry = NULL; ID2D1BitmapBrush *opacity_brush = NULL; D2D1_BITMAP_PROPERTIES bitmap_desc; @@ -1119,10 +1118,11 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta DWRITE_TEXTURE_TYPE texture_type; D2D1_BRUSH_PROPERTIES brush_desc; IDWriteFactory2 *dwrite_factory; - DWRITE_GLYPH_RUN scaled_run; + D2D1_MATRIX_3X2_F *transform, m; void *opacity_values = NULL; size_t opacity_values_size; D2D1_SIZE_U bitmap_size; + float scale_x, scale_y; D2D1_RECT_F run_rect; RECT bounds; HRESULT hr; @@ -1134,12 +1134,21 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta return; } - scaled_run = *glyph_run; - scaled_run.fontEmSize *= ppd; - hr = IDWriteFactory2_CreateGlyphRunAnalysis(dwrite_factory, &scaled_run, - (DWRITE_MATRIX *)&render_target->drawing_state.transform, rendering_mode, measuring_mode, - DWRITE_GRID_FIT_MODE_DEFAULT, antialias_mode, baseline_origin.x, - baseline_origin.y, &analysis); + transform = &render_target->drawing_state.transform; + + scale_x = render_target->desc.dpiX / 96.0f; + m._11 = transform->_11 * scale_x; + m._21 = transform->_21 * scale_x; + m._31 = transform->_31 * scale_x; + + scale_y = render_target->desc.dpiY / 96.0f; + m._12 = transform->_12 * scale_y; + m._22 = transform->_22 * scale_y; + m._32 = transform->_32 * scale_y; + + hr = IDWriteFactory2_CreateGlyphRunAnalysis(dwrite_factory, glyph_run, (DWRITE_MATRIX *)&m, + rendering_mode, measuring_mode, DWRITE_GRID_FIT_MODE_DEFAULT, antialias_mode, + baseline_origin.x, baseline_origin.y, &analysis); IDWriteFactory2_Release(dwrite_factory); if (FAILED(hr)) { @@ -1194,13 +1203,16 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta goto done; } + d2d_rect_set(&run_rect, bounds.left / scale_x, bounds.top / scale_y, + bounds.right / scale_x, bounds.bottom / scale_y); + brush_desc.opacity = 1.0f; brush_desc.transform._11 = 1.0f; brush_desc.transform._12 = 0.0f; brush_desc.transform._21 = 0.0f; brush_desc.transform._22 = 1.0f; - brush_desc.transform._31 = bounds.left; - brush_desc.transform._32 = bounds.top; + brush_desc.transform._31 = run_rect.left; + brush_desc.transform._32 = run_rect.top; if (FAILED(hr = d2d_d3d_render_target_CreateBitmapBrush(&render_target->ID2D1RenderTarget_iface, opacity_bitmap, NULL, &brush_desc, &opacity_brush))) { @@ -1208,19 +1220,17 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta goto done; } - d2d_rect_set(&run_rect, bounds.left, bounds.top, bounds.right, bounds.bottom); if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(render_target->factory, &run_rect, &geometry))) { ERR("Failed to create geometry, hr %#x.\n", hr); goto done; } - transform = &render_target->drawing_state.transform; - prev_transform = *transform; + m = *transform; *transform = identity; d2d_rt_fill_geometry(render_target, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry *)geometry), unsafe_impl_from_ID2D1Brush(brush), unsafe_impl_from_ID2D1Brush((ID2D1Brush *)opacity_brush)); - *transform = prev_transform; + *transform = m; done: if (geometry) @@ -1242,7 +1252,6 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarg IDWriteRenderingParams *rendering_params; DWRITE_RENDERING_MODE rendering_mode; HRESULT hr; - float ppd; TRACE("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x.\n", iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode); @@ -1298,11 +1307,11 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarg ; } - ppd = max(render_target->desc.dpiX, render_target->desc.dpiY) / 96.0f; if (rendering_mode == DWRITE_RENDERING_MODE_DEFAULT) { if (FAILED(hr = IDWriteFontFace_GetRecommendedRenderingMode(glyph_run->fontFace, glyph_run->fontEmSize, - ppd, measuring_mode, rendering_params, &rendering_mode))) + max(render_target->desc.dpiX, render_target->desc.dpiY) / 96.0f, + measuring_mode, rendering_params, &rendering_mode))) { ERR("Failed to get recommended rendering mode, hr %#x.\n", hr); rendering_mode = DWRITE_RENDERING_MODE_OUTLINE; @@ -1313,7 +1322,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarg d2d_rt_draw_glyph_run_outline(render_target, baseline_origin, glyph_run, brush); else d2d_rt_draw_glyph_run_bitmap(render_target, baseline_origin, glyph_run, brush, - ppd, rendering_mode, measuring_mode, antialias_mode); + rendering_mode, measuring_mode, antialias_mode); } static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTransform(ID2D1RenderTarget *iface,
1
0
0
0
Jacek Caban : kernel32: Add AttachConsole implementation.
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: 57212f64f8e4fef0c63c633940e13d407c0f2069 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=57212f64f8e4fef0c63c6339…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Thu Aug 9 18:40:49 2018 +0200 kernel32: Add AttachConsole implementation. Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=41573
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=43910
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/kernel32/console.c | 19 +++++- dlls/kernel32/tests/console.c | 131 ++++++++++++++++++++++++++++++++++++++--- include/wine/server_protocol.h | 21 ++++++- server/console.c | 43 ++++++++++++++ server/protocol.def | 10 ++++ server/request.h | 8 +++ server/trace.c | 17 ++++++ 7 files changed, 238 insertions(+), 11 deletions(-) Diff:
https://source.winehq.org/git/wine.git/?a=commitdiff;h=57212f64f8e4fef0c63c…
1
0
0
0
Fabian Maurer : cmd: Handle quotes when parsing the folders in the PATH environment variable.
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: d175419f0b52550d2a8126e6221428fdb9992980 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=d175419f0b52550d2a8126e6…
Author: Fabian Maurer <dark.shadow4(a)web.de> Date: Thu Aug 2 19:48:59 2018 +0200 cmd: Handle quotes when parsing the folders in the PATH environment variable. Semicolons are also allowed inside a path, as long as they are quoted. Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=45552
Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- programs/cmd/tests/test_builtins.cmd | 17 +++++++++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 3 +++ programs/cmd/wcmdmain.c | 27 ++++++++++++++++++++++----- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index b9e9b25..775f21b 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -507,6 +507,23 @@ rem Only the final quote ends the string set "WINE_FOO=apple"banana"grape"orange echo '%WINE_FOO%' set WINE_FOO= +rem set PATH must work with quotes +set PATH_BACKUP=%PATH% +mkdir folder +mkdir "fol;der" +echo echo I'm here! > "fol;der\sub1.bat" +echo echo I'm here! > folder\sub1.bat +set PATH=nothing;"fol;der" +call sub1 +set PATH="folder +call sub1 +set PATH=folder" +call sub1 +del "fol;der\sub1.bat" +del folder\sub1.bat +rmdir "fol;der" +rmdir folder +PATH=%PATH_BACKUP% echo ------------ Testing variable expansion ------------ call :setError 0 diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 3118359..ea4157c 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -475,6 +475,9 @@ foo 'jim fred' 'jim' 'apple"banana"grape' +I'm here!@space@ +I'm here!@space@ +I'm here!@space@ ------------ Testing variable expansion ------------ ~p0 should be path containing batch file @path@ diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 8fe2d57..5135be4 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1099,24 +1099,41 @@ void WCMD_run_program (WCHAR *command, BOOL called) wine_dbgstr_w(stemofsearch)); while (pathposn) { WCHAR thisDir[MAX_PATH] = {'\0'}; + int length = 0; WCHAR *pos = NULL; BOOL found = FALSE; + BOOL inside_quotes = FALSE; /* Work on the first directory on the search path */ - pos = strchrW(pathposn, ';'); - if (pos) { + pos = pathposn; + while ((inside_quotes || *pos != ';') && *pos != 0) + { + if (*pos == '"') + inside_quotes = !inside_quotes; + pos++; + } + + if (*pos) { /* Reached semicolon */ memcpy(thisDir, pathposn, (pos-pathposn) * sizeof(WCHAR)); thisDir[(pos-pathposn)] = 0x00; pathposn = pos+1; - - } else { + } else { /* Reached string end */ strcpyW(thisDir, pathposn); pathposn = NULL; } + /* Remove quotes */ + length = strlenW(thisDir); + if (thisDir[length - 1] == '"') + thisDir[length - 1] = 0; + + if (*thisDir != '"') + strcpyW(temp, thisDir); + else + strcpyW(temp, thisDir + 1); + /* Since you can have eg. ..\.. on the path, need to expand to full information */ - strcpyW(temp, thisDir); GetFullPathNameW(temp, MAX_PATH, thisDir, NULL); /* 1. If extension supplied, see if that file exists */
1
0
0
0
Chip Davis : libwine: Use getsegmentdata(3) on Mac OS to find the end of the __TEXT segment.
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: bdca749f7ba4f434ac326481cf4fe0a059887f5d URL:
https://source.winehq.org/git/wine.git/?a=commit;h=bdca749f7ba4f434ac326481…
Author: Chip Davis <cdavis(a)codeweavers.com> Date: Wed Aug 1 15:46:09 2018 -0500 libwine: Use getsegmentdata(3) on Mac OS to find the end of the __TEXT segment. Don't assume it ends with the fake PE header. This assumption doesn't hold on Mac OS: the __data section where it was placed is located after several other sections, all in the __DATA segment. Unfortunately, this causes Wine, when DEP/NX is turned off, to override the page protections for the start of the __DATA segment, removing write permission from them, leading to a crash when winemac.drv attempted to use an Objective-C class for the first time. Also, be sure to include the zero-fill (i.e. BSS) sections in the total size of the .data section. This should fix some tests that use large uninitialized arrays. Signed-off-by: Chip Davis <cdavis(a)codeweavers.com> Signed-off-by: Ken Thomases <ken(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- libs/wine/loader.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libs/wine/loader.c b/libs/wine/loader.c index c07042a..0af3b8e 100644 --- a/libs/wine/loader.c +++ b/libs/wine/loader.c @@ -49,6 +49,7 @@ #undef LoadResource #undef GetCurrentThread #include <pthread.h> +#include <mach-o/getsect.h> #else extern char **environ; #endif @@ -387,11 +388,15 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr ) IMAGE_NT_HEADERS *nt; IMAGE_SECTION_HEADER *sec; BYTE *addr; - DWORD code_start, data_start, data_end; + DWORD code_start, code_end, data_start, data_end; const size_t page_size = sysconf( _SC_PAGESIZE ); const size_t page_mask = page_size - 1; int delta, nb_sections = 2; /* code + data */ unsigned int i; +#ifdef __APPLE__ + Dl_info dli; + unsigned long data_size; +#endif size_t size = (sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) @@ -425,7 +430,15 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr ) delta = (const BYTE *)nt_descr - addr; code_start = page_size; data_start = delta & ~page_mask; +#ifdef __APPLE__ + /* Need the mach_header, not the PE header, to give to getsegmentdata(3) */ + dladdr(addr, &dli); + code_end = getsegmentdata(dli.dli_fbase, "__DATA", &data_size) - addr; + data_end = (code_end + data_size + page_mask) & ~page_mask; +#else + code_end = data_start; data_end = (nt->OptionalHeader.SizeOfImage + delta + page_mask) & ~page_mask; +#endif fixup_rva_ptrs( &nt->OptionalHeader.AddressOfEntryPoint, addr, 1 ); @@ -434,7 +447,7 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr ) #ifndef _WIN64 nt->OptionalHeader.BaseOfData = data_start; #endif - nt->OptionalHeader.SizeOfCode = data_start - code_start; + nt->OptionalHeader.SizeOfCode = code_end - code_start; nt->OptionalHeader.SizeOfInitializedData = data_end - data_start; nt->OptionalHeader.SizeOfUninitializedData = 0; nt->OptionalHeader.SizeOfImage = data_end; @@ -443,7 +456,7 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr ) /* Build the code section */ memcpy( sec->Name, ".text", sizeof(".text") ); - sec->SizeOfRawData = data_start - code_start; + sec->SizeOfRawData = code_end - code_start; sec->Misc.VirtualSize = sec->SizeOfRawData; sec->VirtualAddress = code_start; sec->PointerToRawData = code_start;
1
0
0
0
Zebediah Figura : setupapi: Correctly implement SetupDiDeleteDeviceInterfaceRegKey().
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: 9b767ad6bb4139b3465e7c43f5dbdebc21aa7654 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=9b767ad6bb4139b3465e7c43…
Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Sun Jul 29 20:26:29 2018 -0500 setupapi: Correctly implement SetupDiDeleteDeviceInterfaceRegKey(). Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/setupapi/devinst.c | 88 ++++++++++++++++--------------------------- dlls/setupapi/tests/devinst.c | 2 - 2 files changed, 33 insertions(+), 57 deletions(-) diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 44d2cb9..9f77669 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -2531,32 +2531,6 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyA( return key; } -static PWSTR SETUPDI_GetInstancePath(struct device_iface *iface) -{ - static const WCHAR hash[] = {'#',0}; - PWSTR instancePath = NULL; - - if (iface->refstr) - { - instancePath = heap_alloc((lstrlenW(iface->refstr) + 2) * sizeof(WCHAR)); - if (instancePath) - { - lstrcpyW(instancePath, hash); - lstrcatW(instancePath, iface->refstr); - } - else - SetLastError(ERROR_OUTOFMEMORY); - } - else - { - instancePath = HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(hash) + 1) * sizeof(WCHAR)); - if (instancePath) - lstrcpyW(instancePath, hash); - } - return instancePath; -} - /*********************************************************************** * SetupDiCreateDeviceInterfaceRegKeyW (SETUPAPI.@) */ @@ -2622,51 +2596,55 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(HDEVINFO devinfo, /*********************************************************************** * SetupDiDeleteDeviceInterfaceRegKey (SETUPAPI.@) */ -BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey( - HDEVINFO DeviceInfoSet, - PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, - DWORD Reserved) +BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey(HDEVINFO devinfo, + SP_DEVICE_INTERFACE_DATA *iface_data, DWORD reserved) { - struct DeviceInfoSet *set = DeviceInfoSet; - HKEY parent; - BOOL ret = FALSE; + struct DeviceInfoSet *set = devinfo; + struct device_iface *iface; + HKEY refstr_key; + WCHAR *path; + LONG ret; - TRACE("%p %p %d\n", DeviceInfoSet, DeviceInterfaceData, Reserved); + TRACE("%p %p %d\n", devinfo, iface_data, reserved); - if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE || + if (!devinfo || devinfo == INVALID_HANDLE_VALUE || set->magic != SETUP_DEVICE_INFO_SET_MAGIC) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } - if (!DeviceInterfaceData || - DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) || - !DeviceInterfaceData->Reserved) + if (!iface_data || iface_data->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) || + !iface_data->Reserved) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - parent = SetupDiOpenClassRegKeyExW(&DeviceInterfaceData->InterfaceClassGuid, - KEY_ALL_ACCESS, DIOCR_INTERFACE, NULL, NULL); - if (parent != INVALID_HANDLE_VALUE) + + iface = (struct device_iface *)iface_data->Reserved; + if (!(path = get_refstr_key_path(iface))) { - struct device_iface *ifaceInfo = - (struct device_iface *)DeviceInterfaceData->Reserved; - PWSTR instancePath = SETUPDI_GetInstancePath(ifaceInfo); + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } - if (instancePath) - { - LONG l = RegDeleteKeyW(parent, instancePath); + ret = RegCreateKeyExW(HKEY_LOCAL_MACHINE, path, 0, NULL, 0, 0, NULL, + &refstr_key, NULL); + heap_free(path); + if (ret) + { + SetLastError(ret); + return FALSE; + } - if (l) - SetLastError(l); - else - ret = TRUE; - HeapFree(GetProcessHeap(), 0, instancePath); - } - RegCloseKey(parent); + ret = RegDeleteKeyW(refstr_key, DeviceParameters); + RegCloseKey(refstr_key); + if (ret) + { + SetLastError(ret); + return FALSE; } - return ret; + + return TRUE; } /*********************************************************************** diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 95d0dc4..9a8ecbc 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -1419,11 +1419,9 @@ static void test_device_interface_key(void) RegCloseKey(key); ret = SetupDiDeleteDeviceInterfaceRegKey(set, &iface, 0); -todo_wine ok(ret, "got error %u\n", GetLastError()); ret = RegOpenKeyA(parent, "#\\Device Parameters", &key); -todo_wine ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n"); RegCloseKey(parent);
1
0
0
0
Zebediah Figura : setupapi: Correctly implement SetupDiCreateDeviceInterfaceRegKey().
by Alexandre Julliard
16 Aug '18
16 Aug '18
Module: wine Branch: master Commit: 1d17352ce275492554bb2fc06a227060017876e5 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=1d17352ce275492554bb2fc0…
Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Sun Jul 29 20:26:28 2018 -0500 setupapi: Correctly implement SetupDiCreateDeviceInterfaceRegKey(). This family of functions manipulates the "Device Parameters" subkey, not its parent. Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/setupapi/devinst.c | 123 +++++++++++++----------------------------- dlls/setupapi/tests/devinst.c | 57 ++++++++++++++++++++ 2 files changed, 95 insertions(+), 85 deletions(-) diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 8b97eb5..44d2cb9 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -76,6 +76,7 @@ static const WCHAR Enum[] = {'S','y','s','t','e','m','\\', 'E','n','u','m',0}; static const WCHAR DeviceDesc[] = {'D','e','v','i','c','e','D','e','s','c',0}; static const WCHAR DeviceInstance[] = {'D','e','v','i','c','e','I','n','s','t','a','n','c','e',0}; +static const WCHAR DeviceParameters[] = {'D','e','v','i','c','e',' ','P','a','r','a','m','e','t','e','r','s',0}; static const WCHAR HardwareId[] = {'H','a','r','d','w','a','r','e','I','D',0}; static const WCHAR CompatibleIDs[] = {'C','o','m','p','a','t','i','b','l','e','I','d','s',0}; static const WCHAR Service[] = {'S','e','r','v','i','c','e',0}; @@ -2559,111 +2560,63 @@ static PWSTR SETUPDI_GetInstancePath(struct device_iface *iface) /*********************************************************************** * SetupDiCreateDeviceInterfaceRegKeyW (SETUPAPI.@) */ -HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW( - HDEVINFO DeviceInfoSet, - PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, - DWORD Reserved, - REGSAM samDesired, - HINF InfHandle, - PCWSTR InfSectionName) +HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(HDEVINFO devinfo, + SP_DEVICE_INTERFACE_DATA *iface_data, DWORD reserved, REGSAM access, + HINF hinf, const WCHAR *section) { - struct DeviceInfoSet *set = DeviceInfoSet; - HKEY key = INVALID_HANDLE_VALUE, interfacesKey; - LONG l; + struct DeviceInfoSet *set = devinfo; + struct device_iface *iface; + HKEY refstr_key, params_key; + WCHAR *path; + LONG ret; - TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved, - samDesired, InfHandle, InfSectionName); + TRACE("%p %p %d %#x %p %s\n", devinfo, iface_data, reserved, access, hinf, + debugstr_w(section)); - if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE || + if (!devinfo || devinfo == INVALID_HANDLE_VALUE || set->magic != SETUP_DEVICE_INFO_SET_MAGIC) { SetLastError(ERROR_INVALID_HANDLE); return INVALID_HANDLE_VALUE; } - if (!DeviceInterfaceData || - DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) || - !DeviceInterfaceData->Reserved) + if (!iface_data || iface_data->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) || + !iface_data->Reserved) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } - if (InfHandle && !InfSectionName) + if (hinf && !section) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } - if (!(l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, DeviceClasses, 0, NULL, 0, - samDesired, NULL, &interfacesKey, NULL))) - { - HKEY parent; - WCHAR bracedGuidString[39]; - SETUPDI_GuidToString(&DeviceInterfaceData->InterfaceClassGuid, - bracedGuidString); - if (!(l = RegCreateKeyExW(interfacesKey, bracedGuidString, 0, NULL, 0, - samDesired, NULL, &parent, NULL))) - { - struct device_iface *ifaceInfo = - (struct device_iface *)DeviceInterfaceData->Reserved; - PWSTR instancePath = SETUPDI_GetInstancePath(ifaceInfo); - PWSTR interfKeyName = HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(ifaceInfo->symlink) + 1) * sizeof(WCHAR)); - HKEY interfKey; - WCHAR *ptr; - - lstrcpyW(interfKeyName, ifaceInfo->symlink); - if (lstrlenW(ifaceInfo->symlink) > 3) - { - interfKeyName[0] = '#'; - interfKeyName[1] = '#'; - interfKeyName[3] = '#'; - } - ptr = strchrW(interfKeyName, '\\'); - if (ptr) - *ptr = 0; - l = RegCreateKeyExW(parent, interfKeyName, 0, NULL, 0, - samDesired, NULL, &interfKey, NULL); - if (!l) - { - struct device *device = ifaceInfo->device; + iface = (struct device_iface *)iface_data->Reserved; + if (!(path = get_refstr_key_path(iface))) + { + SetLastError(ERROR_OUTOFMEMORY); + return INVALID_HANDLE_VALUE; + } - l = RegSetValueExW(interfKey, DeviceInstance, 0, REG_SZ, - (BYTE *)device->instanceId, - (lstrlenW(device->instanceId) + 1) * sizeof(WCHAR)); - if (!l) - { - if (instancePath) - { - LONG l; + ret = RegCreateKeyExW(HKEY_LOCAL_MACHINE, path, 0, NULL, 0, 0, NULL, + &refstr_key, NULL); + heap_free(path); + if (ret) + { + SetLastError(ret); + return INVALID_HANDLE_VALUE; + } - l = RegCreateKeyExW(interfKey, instancePath, 0, NULL, 0, - samDesired, NULL, &key, NULL); - if (l) - { - SetLastError(l); - key = INVALID_HANDLE_VALUE; - } - else if (InfHandle) - FIXME("INF section installation unsupported\n"); - } - } - else - SetLastError(l); - RegCloseKey(interfKey); - } - else - SetLastError(l); - HeapFree(GetProcessHeap(), 0, interfKeyName); - HeapFree(GetProcessHeap(), 0, instancePath); - RegCloseKey(parent); - } - else - SetLastError(l); - RegCloseKey(interfacesKey); + ret = RegCreateKeyExW(refstr_key, DeviceParameters, 0, NULL, 0, access, + NULL, ¶ms_key, NULL); + RegCloseKey(refstr_key); + if (ret) + { + SetLastError(ret); + return INVALID_HANDLE_VALUE; } - else - SetLastError(l); - return key; + + return params_key; } /*********************************************************************** diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 2bb8027..95d0dc4 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -1376,6 +1376,62 @@ static void test_devnode(void) SetupDiDestroyDeviceInfoList(set); } +static void test_device_interface_key(void) +{ + const char keypath[] = "System\\CurrentControlSet\\Control\\DeviceClasses\\" + "{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\" + "##?#ROOT#LEGACY_BOGUS#0001#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"; + SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) }; + SP_DEVINFO_DATA devinfo = { sizeof(devinfo) }; + HKEY parent, key, dikey; + char buffer[5]; + HDEVINFO set; + LONG sz, ret; + + set = SetupDiGetClassDevsA(NULL, NULL, 0, DIGCF_ALLCLASSES); + ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &devinfo); + ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError()); + + ret = SetupDiCreateDeviceInterfaceA(set, &devinfo, &guid, NULL, 0, &iface); + ok(ret, "SetupDiCreateDeviceInterface failed: %#x\n", GetLastError()); + + ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &parent); + ok(!ret, "failed to open device parent key: %u\n", ret); + + ret = RegOpenKeyA(parent, "#\\Device Parameters", &key); + ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n"); + + dikey = SetupDiCreateDeviceInterfaceRegKeyA(set, &iface, 0, KEY_ALL_ACCESS, NULL, NULL); + ok(dikey != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + ret = RegOpenKeyA(parent, "#\\Device Parameters", &key); + ok(!ret, "key should exist: %u\n", ret); + + ret = RegSetValueA(key, NULL, REG_SZ, "test", 5); + sz = sizeof(buffer); + ret = RegQueryValueA(dikey, NULL, buffer, &sz); + ok(!ret, "RegQueryValue failed: %u\n", ret); + ok(!strcmp(buffer, "test"), "got wrong data %s\n", buffer); + + RegCloseKey(dikey); + RegCloseKey(key); + + ret = SetupDiDeleteDeviceInterfaceRegKey(set, &iface, 0); +todo_wine + ok(ret, "got error %u\n", GetLastError()); + + ret = RegOpenKeyA(parent, "#\\Device Parameters", &key); +todo_wine + ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n"); + + RegCloseKey(parent); + SetupDiRemoveDeviceInterface(set, &iface); + SetupDiRemoveDevice(set, &devinfo); + SetupDiDestroyDeviceInfoList(set); +} + START_TEST(devinst) { HKEY hkey; @@ -1414,4 +1470,5 @@ START_TEST(devinst) testDeviceRegistryPropertyW(); testSetupDiGetINFClassA(); test_devnode(); + test_device_interface_key(); }
1
0
0
0
← Newer
1
...
46
47
48
49
50
51
52
...
62
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Results per page:
10
25
50
100
200