Signed-off-by: Roman Pišl rpisl@seznam.cz --- dlls/kernel32/tests/console.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 5443a611f80..5a399768d9e 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -1304,8 +1304,8 @@ static void test_GetConsoleProcessList(void) GetLastError());
/* We should only have 1 process but only for these specific unit tests as - * we created our own console. An AttachConsole(ATTACH_PARENT_PROCESS) would - * give us two processes for example. + * we created our own console. An AttachConsole(ATTACH_PARENT_PROCESS) + * gives us two processes - see test_AttachConsole. */ list = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD));
@@ -4354,6 +4354,27 @@ static void test_AttachConsole_child(DWORD console_pid) res = AttachConsole(ATTACH_PARENT_PROCESS); ok(res, "AttachConsole failed: %u\n", GetLastError());
+ if (pGetConsoleProcessList) + { + DWORD list[2] = { 0xbabebabe }; + DWORD pid = GetCurrentProcessId(); + + SetLastError(0xdeadbeef); + len = pGetConsoleProcessList(list, 1); + todo_wine + ok(len == 2, "Expected 2 processes, got %d\n", len); + ok(list[0] == 0xbabebabe, "Unexpected value in list %u\n", list[0]); + + len = pGetConsoleProcessList(list, 2); + todo_wine + ok(len == 2, "Expected 2 processes, got %d\n", len); + todo_wine + ok(list[0] == console_pid || list[1] == console_pid, "Parent PID not in list\n"); + todo_wine + ok(list[0] == pid || list[1] == pid, "PID not in list\n"); + ok(GetLastError() == 0xdeadbeef, "Unexpected last error: %u\n", GetLastError()); + } + ok(pipe_in != GetStdHandle(STD_INPUT_HANDLE), "std handle not set to console\n"); ok(pipe_out != GetStdHandle(STD_OUTPUT_HANDLE), "std handle not set to console\n");
Signed-off-by: Roman Pišl rpisl@seznam.cz --- include/wine/condrv.h | 1 + server/console.c | 48 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+)
diff --git a/include/wine/condrv.h b/include/wine/condrv.h index b5e294b9401..4515249a673 100644 --- a/include/wine/condrv.h +++ b/include/wine/condrv.h @@ -43,6 +43,7 @@ #define IOCTL_CONDRV_BEEP CTL_CODE(FILE_DEVICE_CONSOLE, 20, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_CONDRV_FLUSH CTL_CODE(FILE_DEVICE_CONSOLE, 21, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_CONDRV_GET_WINDOW CTL_CODE(FILE_DEVICE_CONSOLE, 22, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_CONDRV_GET_PROCESS_LIST CTL_CODE(FILE_DEVICE_CONSOLE, 23, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* console output ioctls */ #define IOCTL_CONDRV_WRITE_CONSOLE CTL_CODE(FILE_DEVICE_CONSOLE, 30, METHOD_BUFFERED, FILE_WRITE_ACCESS) diff --git a/server/console.c b/server/console.c index 5407fba1411..f98175e403c 100644 --- a/server/console.c +++ b/server/console.c @@ -707,6 +707,27 @@ static void propagate_console_signal( struct console *console, enum_processes(propagate_console_signal_cb, &csi); }
+struct console_process_list +{ + unsigned int size; + unsigned int count; + unsigned int *processes; + struct console *console; +}; + +static int console_process_list_cb(struct process *process, void *user) +{ + struct console_process_list *cpl = user; + + if (process->console == cpl->console) + { + if (cpl->count < cpl->size) cpl->processes[cpl->count] = process->id; + cpl->count++; + } + + return 0; +} + /* dumb dump */ static void console_dump( struct object *obj, int verbose ) { @@ -963,6 +984,33 @@ static void console_ioctl( struct fd *fd, ioctl_code_t code, struct async *async return; }
+ case IOCTL_CONDRV_GET_PROCESS_LIST: + { + struct console_process_list cpl; + if (get_reply_max_size() < sizeof(unsigned int)) + { + set_error( STATUS_INVALID_PARAMETER ); + return; + } + + cpl.count = 0; + cpl.size = 0; + cpl.console = console; + enum_processes( console_process_list_cb, &cpl ); + if (cpl.count * sizeof(unsigned int) > get_reply_max_size()) + { + set_reply_data( &cpl.count, sizeof(cpl.count) ); + set_error( STATUS_BUFFER_TOO_SMALL ); + return; + } + + cpl.size = cpl.count; + cpl.count = 0; + if ((cpl.processes = set_reply_data_size( cpl.size * sizeof(unsigned int) ))) + enum_processes( console_process_list_cb, &cpl ); + return; + } + default: if (!console->server || code >> 16 != FILE_DEVICE_CONSOLE) {
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Roman Pišl rpisl@seznam.cz --- dlls/kernel32/console.c | 21 ++++++++++++++++++++- dlls/kernel32/tests/console.c | 6 ------ 2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c index 395d539a5dc..4999b9a760e 100644 --- a/dlls/kernel32/console.c +++ b/dlls/kernel32/console.c @@ -252,7 +252,11 @@ DWORD WINAPI GetConsoleAliasW(LPWSTR lpSource, LPWSTR lpTargetBuffer, */ DWORD WINAPI GetConsoleProcessList(LPDWORD processlist, DWORD processcount) { - FIXME("(%p,%ld): stub\n", processlist, processcount); + DWORD saved; + NTSTATUS status; + IO_STATUS_BLOCK io; + + TRACE("(%p,%ld)\n", processlist, processcount);
if (!processlist || processcount < 1) { @@ -260,6 +264,21 @@ DWORD WINAPI GetConsoleProcessList(LPDWORD processlist, DWORD processcount) return 0; }
+ saved = *processlist; + status = NtDeviceIoControlFile( RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle, + NULL, NULL, NULL, &io, IOCTL_CONDRV_GET_PROCESS_LIST, + NULL, 0, processlist, processcount * sizeof(DWORD) ); + + if (!status) return io.Information / sizeof(DWORD); + if (status == STATUS_BUFFER_TOO_SMALL) + { + DWORD ret = *processlist; + *processlist = saved; + return ret; + } + + *processlist = saved; + SetLastError(RtlNtStatusToDosError(status)); return 0; }
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 5a399768d9e..5f5f0698040 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -1318,7 +1318,6 @@ static void test_GetConsoleProcessList(void)
SetLastError(0xdeadbeef); ret = pGetConsoleProcessList(list, 1); - todo_wine ok(ret == 1, "Expected 1, got %d\n", ret);
HeapFree(GetProcessHeap(), 0, list); @@ -1327,7 +1326,6 @@ static void test_GetConsoleProcessList(void)
SetLastError(0xdeadbeef); ret = pGetConsoleProcessList(list, ret); - todo_wine ok(ret == 1, "Expected 1, got %d\n", ret);
if (ret == 1) @@ -4361,16 +4359,12 @@ static void test_AttachConsole_child(DWORD console_pid)
SetLastError(0xdeadbeef); len = pGetConsoleProcessList(list, 1); - todo_wine ok(len == 2, "Expected 2 processes, got %d\n", len); ok(list[0] == 0xbabebabe, "Unexpected value in list %u\n", list[0]);
len = pGetConsoleProcessList(list, 2); - todo_wine ok(len == 2, "Expected 2 processes, got %d\n", len); - todo_wine ok(list[0] == console_pid || list[1] == console_pid, "Parent PID not in list\n"); - todo_wine ok(list[0] == pid || list[1] == pid, "PID not in list\n"); ok(GetLastError() == 0xdeadbeef, "Unexpected last error: %u\n", GetLastError()); }
Signed-off-by: Jacek Caban jacek@codeweavers.com