1

The following code works well in Python 2:

import ctypes

def test():
    OpenSCManager      = ctypes.windll.advapi32.OpenSCManagerA
    CloseServiceHandle = ctypes.windll.advapi32.CloseServiceHandle

    handle = OpenSCManager(None, None, 0)
    print(hex(handle))
    assert handle, ctypes.GetLastError()
    assert CloseServiceHandle(handle), ctypes.GetLastError()

test()

It does not work in Python 3:

0x40d88f90
Traceback (most recent call last):
  File ".\test1.py", line 12, in <module>
    test()
  File ".\test1.py", line 10, in test
    assert CloseServiceHandle(handle), ctypes.GetLastError()
AssertionError: 6

6 means invalid handle.

It seems that in addition, the handles retrieved in Python 2 are smaller numbers, such as 0x100ffc0. It isn't something specific with CloseServiceHandle. This handle cannot be used with any service function.

Both Python versions are 64 bit native Windows Python.

1
  • 1
    Seems much more likely that the real difference is 32 and 64 bit. Anyway, make sure you specify argtypes and restype. Commented Mar 17, 2019 at 21:12

2 Answers 2

4

You should use argtypes and restype otherwise all argument default to int and are truncated in 64-bit. Also you shouldn't call GetLastError directly but use ctypes.get_last_error()which cache the last error code (there might have been windows APIs called by the interpreter after you perform a call, you can't be sure).

Here's a working example:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import ctypes


def test():
    advapi32 = ctypes.WinDLL("advapi32", use_last_error=True)
    OpenSCManager = advapi32.OpenSCManagerA
    OpenSCManager.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_ulong]
    OpenSCManager.restype = ctypes.c_void_p

    CloseServiceHandle = advapi32.CloseServiceHandle
    CloseServiceHandle.argtypes = [ctypes.c_void_p]
    CloseServiceHandle.restype = ctypes.c_long

    handle = OpenSCManager(None, None, 0)
    if not handle:
        raise ctypes.WinError(ctypes.get_last_error())
    print(f"handle: {handle:#x}")

    result = CloseServiceHandle(handle)
    if result == 0:
        raise ctypes.WinError(ctypes.get_last_error())

def main():
    test()


if __name__ == "__main__":
    sys.exit(main())
Sign up to request clarification or add additional context in comments.

Comments

0

Try using ctypes.windll.Advapi32 instead of ctypes.windll.advapi32

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.