kernel32: Implement GetNamedPipeClient/ServerProcessId.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d0671ed7b9
commit
dedd450689
|
@ -22,8 +22,8 @@
|
||||||
@ stdcall GetConsoleWindow() kernel32.GetConsoleWindow
|
@ stdcall GetConsoleWindow() kernel32.GetConsoleWindow
|
||||||
@ stub GetDurationFormatEx
|
@ stub GetDurationFormatEx
|
||||||
@ stub GetMaximumProcessorGroupCount
|
@ stub GetMaximumProcessorGroupCount
|
||||||
@ stub GetNamedPipeClientProcessId
|
@ stdcall GetNamedPipeClientProcessId(long ptr) kernel32.GetNamedPipeClientProcessId
|
||||||
@ stub GetNamedPipeServerProcessId
|
@ stdcall GetNamedPipeServerProcessId(long ptr) kernel32.GetNamedPipeServerProcessId
|
||||||
@ stdcall GetShortPathNameA(str ptr long) kernel32.GetShortPathNameA
|
@ stdcall GetShortPathNameA(str ptr long) kernel32.GetShortPathNameA
|
||||||
@ stdcall GetStartupInfoA(ptr) kernel32.GetStartupInfoA
|
@ stdcall GetStartupInfoA(ptr) kernel32.GetStartupInfoA
|
||||||
@ stdcall GetStringTypeExA(long long str long ptr) kernel32.GetStringTypeExA
|
@ stdcall GetStringTypeExA(long long str long ptr) kernel32.GetStringTypeExA
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
@ stub GetFileAttributesTransactedW
|
@ stub GetFileAttributesTransactedW
|
||||||
@ stub GetFirmwareType
|
@ stub GetFirmwareType
|
||||||
@ stub GetMaximumProcessorGroupCount
|
@ stub GetMaximumProcessorGroupCount
|
||||||
@ stub GetNamedPipeClientProcessId
|
@ stdcall GetNamedPipeClientProcessId(long ptr) kernel32.GetNamedPipeClientProcessId
|
||||||
@ stub GetNamedPipeServerProcessId
|
@ stdcall GetNamedPipeServerProcessId(long ptr) kernel32.GetNamedPipeServerProcessId
|
||||||
@ stub GetNumaAvailableMemoryNodeEx
|
@ stub GetNumaAvailableMemoryNodeEx
|
||||||
@ stdcall GetNumaNodeProcessorMask(long ptr) kernel32.GetNumaNodeProcessorMask
|
@ stdcall GetNumaNodeProcessorMask(long ptr) kernel32.GetNumaNodeProcessorMask
|
||||||
@ stub GetNumaProcessorNodeEx
|
@ stub GetNumaProcessorNodeEx
|
||||||
|
|
|
@ -727,12 +727,12 @@
|
||||||
# @ stub GetNamedPipeAttribute
|
# @ stub GetNamedPipeAttribute
|
||||||
# @ stub GetNamedPipeClientComputerNameA
|
# @ stub GetNamedPipeClientComputerNameA
|
||||||
# @ stub GetNamedPipeClientComputerNameW
|
# @ stub GetNamedPipeClientComputerNameW
|
||||||
# @ stub GetNamedPipeClientProcessId
|
@ stdcall GetNamedPipeClientProcessId(long ptr)
|
||||||
# @ stub GetNamedPipeClientSessionId
|
# @ stub GetNamedPipeClientSessionId
|
||||||
@ stdcall GetNamedPipeHandleStateA(long ptr ptr ptr ptr str long)
|
@ stdcall GetNamedPipeHandleStateA(long ptr ptr ptr ptr str long)
|
||||||
@ stdcall GetNamedPipeHandleStateW(long ptr ptr ptr ptr wstr long)
|
@ stdcall GetNamedPipeHandleStateW(long ptr ptr ptr ptr wstr long)
|
||||||
@ stdcall GetNamedPipeInfo(long ptr ptr ptr ptr)
|
@ stdcall GetNamedPipeInfo(long ptr ptr ptr ptr)
|
||||||
# @ stub GetNamedPipeServerProcessId
|
@ stdcall GetNamedPipeServerProcessId(long ptr)
|
||||||
# @ stub GetNamedPipeServerSessionId
|
# @ stub GetNamedPipeServerSessionId
|
||||||
@ stdcall GetNativeSystemInfo(ptr)
|
@ stdcall GetNativeSystemInfo(ptr)
|
||||||
@ stdcall -arch=x86_64 GetNextUmsListItem(ptr)
|
@ stdcall -arch=x86_64 GetNextUmsListItem(ptr)
|
||||||
|
|
|
@ -1786,6 +1786,46 @@ BOOL WINAPI GetNamedPipeInfo(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetNamedPipeClientProcessId (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI GetNamedPipeClientProcessId( HANDLE pipe, ULONG *id )
|
||||||
|
{
|
||||||
|
IO_STATUS_BLOCK iosb;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
TRACE( "%p %p\n", pipe, id );
|
||||||
|
|
||||||
|
status = NtFsControlFile( pipe, NULL, NULL, NULL, &iosb, FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE,
|
||||||
|
(void *)"ClientProcessId", sizeof("ClientProcessId"), id, sizeof(*id) );
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetNamedPipeServerProcessId (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI GetNamedPipeServerProcessId( HANDLE pipe, ULONG *id )
|
||||||
|
{
|
||||||
|
IO_STATUS_BLOCK iosb;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
TRACE( "%p, %p\n", pipe, id );
|
||||||
|
|
||||||
|
status = NtFsControlFile( pipe, NULL, NULL, NULL, &iosb, FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE,
|
||||||
|
(void *)"ServerProcessId", sizeof("ServerProcessId"), id, sizeof(*id) );
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GetNamedPipeHandleStateA (KERNEL32.@)
|
* GetNamedPipeHandleStateA (KERNEL32.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -38,6 +38,8 @@ static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,
|
||||||
SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE);
|
SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE);
|
||||||
static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
|
static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
|
||||||
static BOOL (WINAPI *pCancelIoEx)(HANDLE handle, LPOVERLAPPED lpOverlapped);
|
static BOOL (WINAPI *pCancelIoEx)(HANDLE handle, LPOVERLAPPED lpOverlapped);
|
||||||
|
static BOOL (WINAPI *pGetNamedPipeClientProcessId)(HANDLE,ULONG*);
|
||||||
|
static BOOL (WINAPI *pGetNamedPipeServerProcessId)(HANDLE,ULONG*);
|
||||||
|
|
||||||
static BOOL user_apc_ran;
|
static BOOL user_apc_ran;
|
||||||
static void CALLBACK user_apc(ULONG_PTR param)
|
static void CALLBACK user_apc(ULONG_PTR param)
|
||||||
|
@ -3283,6 +3285,170 @@ static void test_TransactNamedPipe(void)
|
||||||
CloseHandle(server);
|
CloseHandle(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HANDLE create_overlapped_server( OVERLAPPED *overlapped )
|
||||||
|
{
|
||||||
|
HANDLE pipe;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
pipe = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||||
|
1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT, NULL);
|
||||||
|
ok(pipe != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
|
||||||
|
ret = ConnectNamedPipe(pipe, overlapped);
|
||||||
|
ok(!ret && GetLastError() == ERROR_IO_PENDING, "got %u\n", GetLastError());
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void child_process_check_pid(DWORD server_pid)
|
||||||
|
{
|
||||||
|
DWORD current = GetProcessId(GetCurrentProcess());
|
||||||
|
HANDLE pipe;
|
||||||
|
ULONG pid;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
pipe = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ok(pipe != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeClientProcessId(pipe, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x\n", pid);
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeServerProcessId(pipe, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == server_pid, "got %04x expected %04x\n", pid, server_pid);
|
||||||
|
CloseHandle(pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE create_check_id_process(const char *verb, DWORD id)
|
||||||
|
{
|
||||||
|
STARTUPINFOA si = {sizeof(si)};
|
||||||
|
PROCESS_INFORMATION info;
|
||||||
|
char **argv, buf[MAX_PATH];
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
winetest_get_mainargs(&argv);
|
||||||
|
sprintf(buf, "\"%s\" pipe %s %x", argv[0], verb, id);
|
||||||
|
ret = CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0, NULL, NULL, &si, &info);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
CloseHandle(info.hThread);
|
||||||
|
return info.hProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_namedpipe_process_id(void)
|
||||||
|
{
|
||||||
|
HANDLE client, server, process;
|
||||||
|
DWORD current = GetProcessId(GetCurrentProcess());
|
||||||
|
OVERLAPPED overlapped;
|
||||||
|
ULONG pid;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
if (!pGetNamedPipeClientProcessId)
|
||||||
|
{
|
||||||
|
win_skip("GetNamedPipeClientProcessId not available\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetNamedPipeClientProcessId(server, NULL);
|
||||||
|
ok(!ret, "success\n");
|
||||||
|
todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeClientProcessId(server, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x expected %04x\n", pid, current);
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeClientProcessId(client, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x expected %04x\n", pid, current);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetNamedPipeServerProcessId(server, NULL);
|
||||||
|
ok(!ret, "success\n");
|
||||||
|
todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeServerProcessId(client, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x expected %04x\n", pid, current);
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeServerProcessId(server, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x expected %04x\n", pid, current);
|
||||||
|
|
||||||
|
/* closed client handle */
|
||||||
|
CloseHandle(client);
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeClientProcessId(server, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x expected %04x\n", pid, current);
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeServerProcessId(server, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x expected %04x\n", pid, current);
|
||||||
|
CloseHandle(server);
|
||||||
|
|
||||||
|
/* disconnected server */
|
||||||
|
create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
|
||||||
|
DisconnectNamedPipe(server);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetNamedPipeClientProcessId(server, &pid);
|
||||||
|
todo_wine ok(!ret, "success\n");
|
||||||
|
todo_wine ok(GetLastError() == ERROR_NOT_FOUND, "got %u\n", GetLastError());
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeServerProcessId(server, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x expected %04x\n", pid, current);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetNamedPipeClientProcessId(client, &pid);
|
||||||
|
todo_wine ok(!ret, "success\n");
|
||||||
|
todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %u\n", GetLastError());
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetNamedPipeServerProcessId(client, &pid);
|
||||||
|
todo_wine ok(!ret, "success\n");
|
||||||
|
todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %u\n", GetLastError());
|
||||||
|
CloseHandle(client);
|
||||||
|
CloseHandle(server);
|
||||||
|
|
||||||
|
/* closed server handle */
|
||||||
|
create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
|
||||||
|
CloseHandle(server);
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeClientProcessId(client, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x expected %04x\n", pid, current);
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
|
ret = pGetNamedPipeServerProcessId(client, &pid);
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
ok(pid == current, "got %04x expected %04x\n", pid, current);
|
||||||
|
CloseHandle(client);
|
||||||
|
|
||||||
|
/* different process */
|
||||||
|
memset(&overlapped, 0, sizeof(overlapped));
|
||||||
|
overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
|
server = create_overlapped_server( &overlapped );
|
||||||
|
ok(server != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
|
||||||
|
|
||||||
|
process = create_check_id_process("checkpid", GetProcessId(GetCurrentProcess()));
|
||||||
|
winetest_wait_child_process(process);
|
||||||
|
|
||||||
|
CloseHandle(overlapped.hEvent);
|
||||||
|
CloseHandle(process);
|
||||||
|
CloseHandle(server);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(pipe)
|
START_TEST(pipe)
|
||||||
{
|
{
|
||||||
char **argv;
|
char **argv;
|
||||||
|
@ -3294,15 +3460,27 @@ START_TEST(pipe)
|
||||||
hmod = GetModuleHandleA("kernel32.dll");
|
hmod = GetModuleHandleA("kernel32.dll");
|
||||||
pQueueUserAPC = (void *) GetProcAddress(hmod, "QueueUserAPC");
|
pQueueUserAPC = (void *) GetProcAddress(hmod, "QueueUserAPC");
|
||||||
pCancelIoEx = (void *) GetProcAddress(hmod, "CancelIoEx");
|
pCancelIoEx = (void *) GetProcAddress(hmod, "CancelIoEx");
|
||||||
|
pGetNamedPipeClientProcessId = (void *) GetProcAddress(hmod, "GetNamedPipeClientProcessId");
|
||||||
|
pGetNamedPipeServerProcessId = (void *) GetProcAddress(hmod, "GetNamedPipeServerProcessId");
|
||||||
|
|
||||||
argc = winetest_get_mainargs(&argv);
|
argc = winetest_get_mainargs(&argv);
|
||||||
|
|
||||||
if (argc > 3 && !strcmp(argv[2], "writepipe"))
|
if (argc > 3)
|
||||||
{
|
{
|
||||||
UINT_PTR handle;
|
if (!strcmp(argv[2], "writepipe"))
|
||||||
sscanf(argv[3], "%lx", &handle);
|
{
|
||||||
child_process_write_pipe((HANDLE)handle);
|
UINT_PTR handle;
|
||||||
return;
|
sscanf(argv[3], "%lx", &handle);
|
||||||
|
child_process_write_pipe((HANDLE)handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!strcmp(argv[2], "checkpid"))
|
||||||
|
{
|
||||||
|
DWORD pid = GetProcessId(GetCurrentProcess());
|
||||||
|
sscanf(argv[3], "%x", &pid);
|
||||||
|
child_process_check_pid(pid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_DisconnectNamedPipe())
|
if (test_DisconnectNamedPipe())
|
||||||
|
@ -3324,4 +3502,5 @@ START_TEST(pipe)
|
||||||
test_overlapped_transport(TRUE, TRUE);
|
test_overlapped_transport(TRUE, TRUE);
|
||||||
test_overlapped_transport(FALSE, FALSE);
|
test_overlapped_transport(FALSE, FALSE);
|
||||||
test_TransactNamedPipe();
|
test_TransactNamedPipe();
|
||||||
|
test_namedpipe_process_id();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2141,11 +2141,14 @@ WINBASEAPI HMODULE WINAPI GetModuleHandleW(LPCWSTR);
|
||||||
WINBASEAPI BOOL WINAPI GetModuleHandleExA(DWORD,LPCSTR,HMODULE*);
|
WINBASEAPI BOOL WINAPI GetModuleHandleExA(DWORD,LPCSTR,HMODULE*);
|
||||||
WINBASEAPI BOOL WINAPI GetModuleHandleExW(DWORD,LPCWSTR,HMODULE*);
|
WINBASEAPI BOOL WINAPI GetModuleHandleExW(DWORD,LPCWSTR,HMODULE*);
|
||||||
#define GetModuleHandleEx WINELIB_NAME_AW(GetModuleHandleEx)
|
#define GetModuleHandleEx WINELIB_NAME_AW(GetModuleHandleEx)
|
||||||
|
WINBASEAPI BOOL WINAPI GetNamedPipeClientProcessId(HANDLE,PULONG);
|
||||||
|
WINBASEAPI BOOL WINAPI GetNamedPipeClientSessionId(HANDLE,PULONG);
|
||||||
WINBASEAPI BOOL WINAPI GetNamedPipeHandleStateA(HANDLE,LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPSTR,DWORD);
|
WINBASEAPI BOOL WINAPI GetNamedPipeHandleStateA(HANDLE,LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPSTR,DWORD);
|
||||||
WINBASEAPI BOOL WINAPI GetNamedPipeHandleStateW(HANDLE,LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR,DWORD);
|
WINBASEAPI BOOL WINAPI GetNamedPipeHandleStateW(HANDLE,LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR,DWORD);
|
||||||
#define GetNamedPipeHandleState WINELIB_NAME_AW(GetNamedPipeHandleState)
|
#define GetNamedPipeHandleState WINELIB_NAME_AW(GetNamedPipeHandleState)
|
||||||
WINBASEAPI BOOL WINAPI GetNamedPipeInfo(HANDLE,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
|
WINBASEAPI BOOL WINAPI GetNamedPipeInfo(HANDLE,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
|
||||||
WINBASEAPI BOOL WINAPI GetNamedPipeClientProcessId(HANDLE,PULONG);
|
WINBASEAPI BOOL WINAPI GetNamedPipeServerProcessId(HANDLE,PULONG);
|
||||||
|
WINBASEAPI BOOL WINAPI GetNamedPipeServerSessionId(HANDLE,PULONG);
|
||||||
WINBASEAPI VOID WINAPI GetNativeSystemInfo(LPSYSTEM_INFO);
|
WINBASEAPI VOID WINAPI GetNativeSystemInfo(LPSYSTEM_INFO);
|
||||||
WINBASEAPI PUMS_CONTEXT WINAPI GetNextUmsListItem(PUMS_CONTEXT);
|
WINBASEAPI PUMS_CONTEXT WINAPI GetNextUmsListItem(PUMS_CONTEXT);
|
||||||
WINBASEAPI BOOL WINAPI GetNumaProcessorNode(UCHAR,PUCHAR);
|
WINBASEAPI BOOL WINAPI GetNumaProcessorNode(UCHAR,PUCHAR);
|
||||||
|
|
|
@ -200,6 +200,7 @@
|
||||||
#define FSCTL_PIPE_IMPERSONATE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
#define FSCTL_PIPE_IMPERSONATE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSCTL_PIPE_SET_CLIENT_PROCESS CTL_CODE(FILE_DEVICE_NAMED_PIPE, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
#define FSCTL_PIPE_SET_CLIENT_PROCESS CTL_CODE(FILE_DEVICE_NAMED_PIPE, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSCTL_PIPE_QUERY_CLIENT_PROCESS CTL_CODE(FILE_DEVICE_NAMED_PIPE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
#define FSCTL_PIPE_QUERY_CLIENT_PROCESS CTL_CODE(FILE_DEVICE_NAMED_PIPE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSCTL_PIPE_INTERNAL_READ CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2045, METHOD_BUFFERED, FILE_READ_DATA)
|
#define FSCTL_PIPE_INTERNAL_READ CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2045, METHOD_BUFFERED, FILE_READ_DATA)
|
||||||
#define FSCTL_PIPE_INTERNAL_WRITE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2046, METHOD_BUFFERED, FILE_WRITE_DATA)
|
#define FSCTL_PIPE_INTERNAL_WRITE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2046, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||||
#define FSCTL_PIPE_INTERNAL_TRANSCEIVE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2047, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
|
#define FSCTL_PIPE_INTERNAL_TRANSCEIVE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2047, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
enum pipe_state
|
enum pipe_state
|
||||||
{
|
{
|
||||||
|
@ -66,6 +67,8 @@ struct pipe_end
|
||||||
struct fd *fd; /* pipe file descriptor */
|
struct fd *fd; /* pipe file descriptor */
|
||||||
unsigned int flags; /* pipe flags */
|
unsigned int flags; /* pipe flags */
|
||||||
struct pipe_end *connection; /* the other end of the 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 */
|
||||||
data_size_t buffer_size;/* size of buffered data that doesn't block caller */
|
data_size_t buffer_size;/* size of buffered data that doesn't block caller */
|
||||||
struct list message_queue;
|
struct list message_queue;
|
||||||
struct async_queue read_q; /* read queue */
|
struct async_queue read_q; /* read queue */
|
||||||
|
@ -940,10 +943,45 @@ static int pipe_end_transceive( struct pipe_end *pipe_end, struct async *async )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pipe_end_get_connection_attribute( struct pipe_end *pipe_end )
|
||||||
|
{
|
||||||
|
const char *attr = get_req_data();
|
||||||
|
data_size_t value_size, attr_size = get_req_data_size();
|
||||||
|
void *value;
|
||||||
|
|
||||||
|
if (attr_size == sizeof("ClientProcessId") && !memcmp( attr, "ClientProcessId", attr_size ))
|
||||||
|
{
|
||||||
|
value = &pipe_end->client_pid;
|
||||||
|
value_size = sizeof(pipe_end->client_pid);
|
||||||
|
}
|
||||||
|
else if (attr_size == sizeof("ServerProcessId") && !memcmp( attr, "ServerProcessId", attr_size ))
|
||||||
|
{
|
||||||
|
value = &pipe_end->server_pid;
|
||||||
|
value_size = sizeof(pipe_end->server_pid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_error( STATUS_ILLEGAL_FUNCTION );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_reply_max_size() < value_size)
|
||||||
|
{
|
||||||
|
set_error( STATUS_INFO_LENGTH_MISMATCH );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_reply_data( value, value_size );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int pipe_end_ioctl( struct pipe_end *pipe_end, ioctl_code_t code, struct async *async )
|
static int pipe_end_ioctl( struct pipe_end *pipe_end, ioctl_code_t code, struct async *async )
|
||||||
{
|
{
|
||||||
switch(code)
|
switch(code)
|
||||||
{
|
{
|
||||||
|
case FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE:
|
||||||
|
return pipe_end_get_connection_attribute( pipe_end );
|
||||||
|
|
||||||
case FSCTL_PIPE_PEEK:
|
case FSCTL_PIPE_PEEK:
|
||||||
return pipe_end_peek( pipe_end );
|
return pipe_end_peek( pipe_end );
|
||||||
|
|
||||||
|
@ -1062,6 +1100,7 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned
|
||||||
server->client = NULL;
|
server->client = NULL;
|
||||||
server->options = options;
|
server->options = options;
|
||||||
init_pipe_end( &server->pipe_end, pipe_flags, pipe->insize );
|
init_pipe_end( &server->pipe_end, pipe_flags, pipe->insize );
|
||||||
|
server->pipe_end.server_pid = get_process_id( current->process );
|
||||||
|
|
||||||
list_add_head( &pipe->servers, &server->entry );
|
list_add_head( &pipe->servers, &server->entry );
|
||||||
grab_object( pipe );
|
grab_object( pipe );
|
||||||
|
@ -1087,6 +1126,7 @@ static struct pipe_client *create_pipe_client( unsigned int flags, unsigned int
|
||||||
client->server = NULL;
|
client->server = NULL;
|
||||||
client->flags = flags;
|
client->flags = flags;
|
||||||
init_pipe_end( &client->pipe_end, pipe_flags, buffer_size );
|
init_pipe_end( &client->pipe_end, pipe_flags, buffer_size );
|
||||||
|
client->pipe_end.client_pid = get_process_id( current->process );
|
||||||
|
|
||||||
client->pipe_end.fd = alloc_pseudo_fd( &pipe_client_fd_ops, &client->pipe_end.obj, options );
|
client->pipe_end.fd = alloc_pseudo_fd( &pipe_client_fd_ops, &client->pipe_end.obj, options );
|
||||||
if (!client->pipe_end.fd)
|
if (!client->pipe_end.fd)
|
||||||
|
@ -1169,6 +1209,8 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
|
||||||
client->server = server;
|
client->server = server;
|
||||||
server->pipe_end.connection = &client->pipe_end;
|
server->pipe_end.connection = &client->pipe_end;
|
||||||
client->pipe_end.connection = &server->pipe_end;
|
client->pipe_end.connection = &server->pipe_end;
|
||||||
|
server->pipe_end.client_pid = client->pipe_end.client_pid;
|
||||||
|
client->pipe_end.server_pid = server->pipe_end.server_pid;
|
||||||
}
|
}
|
||||||
release_object( server );
|
release_object( server );
|
||||||
return &client->pipe_end.obj;
|
return &client->pipe_end.obj;
|
||||||
|
|
Loading…
Reference in New Issue