From 86dd00505bce78e2a3c6f133453c89b1a831c08d Mon Sep 17 00:00:00 2001 From: Oliver Palmer Date: Sun, 24 Jan 2016 22:20:16 -0500 Subject: [PATCH 1/9] adding GetCurrentProcess --- pywincffi/core/cdefs/headers/functions.h | 1 + 1 file changed, 1 insertion(+) diff --git a/pywincffi/core/cdefs/headers/functions.h b/pywincffi/core/cdefs/headers/functions.h index badfe61..7e8ddae 100644 --- a/pywincffi/core/cdefs/headers/functions.h +++ b/pywincffi/core/cdefs/headers/functions.h @@ -10,6 +10,7 @@ VOID SetLastError(DWORD); // Processes HANDLE OpenProcess(DWORD, BOOL, DWORD); +HANDLE GetCurrentProcess(); // Pipes BOOL CreatePipe(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD); From 32ba21dc6ec38fc655c4da376f88f59eb22bf076 Mon Sep 17 00:00:00 2001 From: Oliver Palmer Date: Sun, 24 Jan 2016 22:22:31 -0500 Subject: [PATCH 2/9] python side of GetCurrentProcess --- pywincffi/kernel32/process.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pywincffi/kernel32/process.py b/pywincffi/kernel32/process.py index 654f7b5..8f33764 100644 --- a/pywincffi/kernel32/process.py +++ b/pywincffi/kernel32/process.py @@ -56,3 +56,23 @@ def OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId): error_check("OpenProcess") return ffi.new_handle(handle_id) + + +def GetCurrentProcess(): + """ + Returns a handle to the current thread. + + .. seealso:: + + https://msdn.microsoft.com/en-us/library/ms683179 + + .. note:: + + Calling :func:`pywincffi.kernel32.io.CloseHandle` on the handle + produced by this function will produce an exception. + + :returns: + The handle to the current process. + """ + _, library = dist.load() + return library.GetCurrentProcess() From fb6a09ac6f04b8139df4e5f71336be1c39f301f3 Mon Sep 17 00:00:00 2001 From: Oliver Palmer Date: Sun, 24 Jan 2016 22:32:51 -0500 Subject: [PATCH 3/9] tests for GetCurrentProcess --- tests/test_kernel32/test_process.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/test_kernel32/test_process.py b/tests/test_kernel32/test_process.py index e458eb2..0eb50dc 100644 --- a/tests/test_kernel32/test_process.py +++ b/tests/test_kernel32/test_process.py @@ -3,7 +3,7 @@ from pywincffi.core import dist from pywincffi.dev.testutil import TestCase from pywincffi.exceptions import WindowsAPIError -from pywincffi.kernel32.process import OpenProcess +from pywincffi.kernel32.process import OpenProcess, GetCurrentProcess class TestOpenProcess(TestCase): @@ -29,3 +29,23 @@ def test_access_denied_for_null_desired_access(self): OpenProcess(0, False, os.getpid()) self.assertEqual(error.exception.code, 5) + + +class TestGetCurrentProcess(TestCase): + """ + Tests for :func:`pywincffi.kernel32.GetCurrentProcess` + """ + def test_returns_handle(self): + ffi, library = dist.load() + handle = GetCurrentProcess() + typeof = ffi.typeof(handle) + self.assertEqual(typeof.kind, "pointer") + self.assertEqual(typeof.cname, "void *") + + def test_returns_same_handle(self): + # GetCurrentProcess is somewhat special in that it will + # always return a handle to the same object. However, __eq__ is not + # opaque so the string representation of the two handles + # should always match since it contains the address of the object + # in memory. + self.assertEqual(repr(GetCurrentProcess()), repr(GetCurrentProcess())) From 98878baa4645669c3f69d7ae757925ba23dbc27e Mon Sep 17 00:00:00 2001 From: Oliver Palmer Date: Sun, 24 Jan 2016 22:33:34 -0500 Subject: [PATCH 4/9] doc string fix --- tests/test_kernel32/test_process.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_kernel32/test_process.py b/tests/test_kernel32/test_process.py index 0eb50dc..cdc8c81 100644 --- a/tests/test_kernel32/test_process.py +++ b/tests/test_kernel32/test_process.py @@ -8,7 +8,7 @@ class TestOpenProcess(TestCase): """ - Tests for :func:`pywincffi.kernel32.OpenProcess` + Tests for :func:`pywincffi.kernel32.process.OpenProcess` """ def test_returns_handle(self): ffi, library = dist.load() @@ -33,7 +33,7 @@ def test_access_denied_for_null_desired_access(self): class TestGetCurrentProcess(TestCase): """ - Tests for :func:`pywincffi.kernel32.GetCurrentProcess` + Tests for :func:`pywincffi.kernel32.process.GetCurrentProcess` """ def test_returns_handle(self): ffi, library = dist.load() From cc1ac476270f2500aeb5cb6aab472bfbe80de4a6 Mon Sep 17 00:00:00 2001 From: Oliver Palmer Date: Sun, 24 Jan 2016 22:41:43 -0500 Subject: [PATCH 5/9] implement GetProcessId --- pywincffi/core/cdefs/headers/functions.h | 1 + pywincffi/kernel32/process.py | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/pywincffi/core/cdefs/headers/functions.h b/pywincffi/core/cdefs/headers/functions.h index 7e8ddae..d1c4c42 100644 --- a/pywincffi/core/cdefs/headers/functions.h +++ b/pywincffi/core/cdefs/headers/functions.h @@ -11,6 +11,7 @@ VOID SetLastError(DWORD); // Processes HANDLE OpenProcess(DWORD, BOOL, DWORD); HANDLE GetCurrentProcess(); +DWORD GetProcessId(HANDLE); // Pipes BOOL CreatePipe(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD); diff --git a/pywincffi/kernel32/process.py b/pywincffi/kernel32/process.py index 8f33764..db16e6e 100644 --- a/pywincffi/kernel32/process.py +++ b/pywincffi/kernel32/process.py @@ -18,7 +18,7 @@ import six from pywincffi.core import dist -from pywincffi.core.checks import input_check, error_check +from pywincffi.core.checks import Enums, input_check, error_check def OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId): @@ -76,3 +76,25 @@ def GetCurrentProcess(): """ _, library = dist.load() return library.GetCurrentProcess() + + +def GetProcessId(Process): + """ + Returns the pid of the process handle provided in ``Process``. + + .. seealso:: + + https://msdn.microsoft.com/en-us/library/ms683215 + + :param handle Process: + The handle of the process to re + + :return: + Returns an integer which represents the pid of the given + process handle. + """ + input_check("Process", Process, Enums.HANDLE) + _, library = dist.load() + pid = library.GetProcessId(Process) + error_check("GetProcessId") + return pid From 50eb57705baf0312e32189318cd0245a6d725759 Mon Sep 17 00:00:00 2001 From: Oliver Palmer Date: Sun, 24 Jan 2016 22:44:49 -0500 Subject: [PATCH 6/9] check to see if the current handle is for the current process --- tests/test_kernel32/test_process.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_kernel32/test_process.py b/tests/test_kernel32/test_process.py index cdc8c81..6d15d9d 100644 --- a/tests/test_kernel32/test_process.py +++ b/tests/test_kernel32/test_process.py @@ -3,7 +3,8 @@ from pywincffi.core import dist from pywincffi.dev.testutil import TestCase from pywincffi.exceptions import WindowsAPIError -from pywincffi.kernel32.process import OpenProcess, GetCurrentProcess +from pywincffi.kernel32.process import ( + OpenProcess, GetCurrentProcess, GetProcessId) class TestOpenProcess(TestCase): @@ -49,3 +50,7 @@ def test_returns_same_handle(self): # should always match since it contains the address of the object # in memory. self.assertEqual(repr(GetCurrentProcess()), repr(GetCurrentProcess())) + + def test_handle_is_current_process(self): + handle = GetCurrentProcess() + self.assertEqual(GetProcessId(handle), os.getpid()) From 3ef793c0fa2052c793b013269fd64efb679aef39 Mon Sep 17 00:00:00 2001 From: Oliver Palmer Date: Sun, 24 Jan 2016 22:48:50 -0500 Subject: [PATCH 7/9] make sure we can query the pid from the handle we returned from OpenProcess --- tests/test_kernel32/test_process.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_kernel32/test_process.py b/tests/test_kernel32/test_process.py index ed8b6bb..a38fbb8 100644 --- a/tests/test_kernel32/test_process.py +++ b/tests/test_kernel32/test_process.py @@ -32,6 +32,18 @@ def test_access_denied_for_null_desired_access(self): self.assertEqual(error.exception.code, 5) + def test_get_process_id_current_process(self): + # We should be able to access the pid of the process + # we created a handle to. + ffi, library = dist.load() + + handle = OpenProcess( + library.PROCESS_QUERY_INFORMATION, + False, + os.getpid() + ) + self.assertEqual(GetProcessId(handle), os.getpid()) + class TestGetCurrentProcess(TestCase): """ From 4133e838a4d4b063a758f87e3f8c48c657ff3d03 Mon Sep 17 00:00:00 2001 From: Oliver Palmer Date: Sun, 24 Jan 2016 22:56:14 -0500 Subject: [PATCH 8/9] add test to ensure we can get the pid of using the handle of another process --- tests/test_kernel32/test_process.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_kernel32/test_process.py b/tests/test_kernel32/test_process.py index a38fbb8..06edc17 100644 --- a/tests/test_kernel32/test_process.py +++ b/tests/test_kernel32/test_process.py @@ -1,4 +1,6 @@ import os +import subprocess +import sys from pywincffi.core import dist from pywincffi.dev.testutil import TestCase @@ -43,6 +45,7 @@ def test_get_process_id_current_process(self): os.getpid() ) self.assertEqual(GetProcessId(handle), os.getpid()) + CloseHandle(handle) class TestGetCurrentProcess(TestCase): @@ -75,3 +78,20 @@ def test_handle_is_valid(self): # If the handle were invalid, this would fail. CloseHandle(handle) + + +class TestGetProcessId(TestCase): + """ + Tests for :func:`pywincffi.kernel32.process.GetProcessId` + """ + def test_get_pid_of_external_process(self): + _, library = dist.load() + python = subprocess.Popen( + [sys.executable, "-c", "import time; time.sleep(3)"] + ) + self.addCleanup(python.terminate) + expected_pid = python.pid + handle = OpenProcess( + library.PROCESS_QUERY_INFORMATION, False, expected_pid) + self.assertEqual(GetProcessId(handle), expected_pid) + CloseHandle(handle) From 0c762aac4b852e9aa845c6d8408ea69b084c8f86 Mon Sep 17 00:00:00 2001 From: Oliver Palmer Date: Sun, 24 Jan 2016 22:59:26 -0500 Subject: [PATCH 9/9] lint fixes --- pywincffi/kernel32/process.py | 2 +- tests/test_kernel32/test_process.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pywincffi/kernel32/process.py b/pywincffi/kernel32/process.py index 8bf2a1b..bcda742 100644 --- a/pywincffi/kernel32/process.py +++ b/pywincffi/kernel32/process.py @@ -77,7 +77,7 @@ def GetCurrentProcess(): return library.GetCurrentProcess() -def GetProcessId(Process): +def GetProcessId(Process): # pylint: disable=invalid-name """ Returns the pid of the process handle provided in ``Process``. diff --git a/tests/test_kernel32/test_process.py b/tests/test_kernel32/test_process.py index 06edc17..e261671 100644 --- a/tests/test_kernel32/test_process.py +++ b/tests/test_kernel32/test_process.py @@ -37,7 +37,7 @@ def test_access_denied_for_null_desired_access(self): def test_get_process_id_current_process(self): # We should be able to access the pid of the process # we created a handle to. - ffi, library = dist.load() + _, library = dist.load() handle = OpenProcess( library.PROCESS_QUERY_INFORMATION, @@ -53,7 +53,7 @@ class TestGetCurrentProcess(TestCase): Tests for :func:`pywincffi.kernel32.process.GetCurrentProcess` """ def test_returns_handle(self): - ffi, library = dist.load() + ffi, _ = dist.load() handle = GetCurrentProcess() typeof = ffi.typeof(handle) self.assertEqual(typeof.kind, "pointer")