Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Auto Casting C-types #4

Open
byehack opened this issue Mar 12, 2023 · 11 comments
Open

Feature Request: Auto Casting C-types #4

byehack opened this issue Mar 12, 2023 · 11 comments

Comments

@byehack
Copy link
Contributor

byehack commented Mar 12, 2023

In continue of #2 (comment)

All functions are typed for both arguments and results. but current behavior is, it'll raise if our entered arguments types are not exact same as specified.

proposed behavior is that it should auto casting the types for both arguments and results.

here is current working script:

from Windows.Win32.System.Rpc import RpcStringBindingComposeW
from Windows import UInt16, c_wchar_p
from ctypes import POINTER, cast

strBinding = cast(c_wchar_p(), POINTER(UInt16))
rStatus = RpcStringBindingComposeW(
    cast(c_wchar_p("0767a036-0d22-48aa-ba69-b619480f38cb"), POINTER(UInt16)),
    cast(c_wchar_p("ncalrpc"), POINTER(UInt16)),
    None,
    None,
    None,
    strBinding)
strBinding = cast(strBinding, c_wchar_p)

print(rStatus, strBinding.value)

Auto Casting will remove cast from our side:

from Windows.Win32.System.Rpc import RpcStringBindingComposeW
from Windows import UInt16, c_wchar_p

strBinding = c_wchar_p()
rStatus = RpcStringBindingComposeW(
    c_wchar_p("0767a036-0d22-48aa-ba69-b619480f38cb"),
    c_wchar_p("ncalrpc"),
    None,
    None,
    None,
    strBinding)
print(rStatus, strBinding.value)
@byehack
Copy link
Contributor Author

byehack commented Mar 12, 2023

Auto Casting will remove cast from our side:

from Windows.Win32.System.Rpc import RpcStringBindingComposeW
from Windows import UInt16, c_wchar_p

strBinding = c_wchar_p()
rStatus = RpcStringBindingComposeW(
    c_wchar_p("0767a036-0d22-48aa-ba69-b619480f38cb"),
    c_wchar_p("ncalrpc"),
    None,
    None,
    None,
    strBinding)
print(rStatus, strBinding.value)

And if we assume string object type is c_wchar_p and byte object type is c_char_p, we can have even simpler call:

from Windows.Win32.System.Rpc import RpcStringBindingComposeW
from Windows import c_wchar_p

strBinding = c_wchar_p()
rStatus = RpcStringBindingComposeW("0767a036-0d22-48aa-ba69-b619480f38cb", "ncalrpc", None, None, None, strBinding)
print(rStatus, strBinding.value)

I think this is current behavior in ctypes module when we are calling a typed function.

@ynkdir
Copy link
Owner

ynkdir commented Mar 14, 2023

WIP
I have not confirmed yet that if getting pointer value with byref(c_wchar_p()) is safe.

@ynkdir
Copy link
Owner

ynkdir commented Mar 14, 2023

It seems to work.
I merged fix.
Could you confirm that works for you.

@byehack
Copy link
Contributor Author

byehack commented Mar 14, 2023

That's great, I can confirm both WIP examples above have been tested and passed successfully,

@byehack byehack closed this as completed Mar 14, 2023
@byehack byehack reopened this Mar 14, 2023
@byehack
Copy link
Contributor Author

byehack commented Mar 14, 2023

Reopened bcz still need to work to be complete. Look at this example (you can try to repro):

currently working script:

from Windows.Win32.System.Rpc import RPC_SECURITY_QOS_V3_W
from Windows.Win32.Security import CreateWellKnownSid, WELL_KNOWN_SID_TYPE_WinLocalSystemSid
from ctypes import cast, c_ulong, c_void_p, create_string_buffer

SECURITY_MAX_SID_SIZE = 68
sidSize = c_ulong(SECURITY_MAX_SID_SIZE)
sid = create_string_buffer(SECURITY_MAX_SID_SIZE)
rStatus = CreateWellKnownSid(
    WELL_KNOWN_SID_TYPE_WinLocalSystemSid,
    None,
    sid,
    sidSize)
if not rStatus:
    raise
security = RPC_SECURITY_QOS_V3_W()
security.Sid = cast(sid, c_void_p)

Expected Work with auto casting:

from Windows.Win32.System.Rpc import RPC_SECURITY_QOS_V3_W
from Windows.Win32.Security import CreateWellKnownSid, WELL_KNOWN_SID_TYPE_WinLocalSystemSid
from ctypes import cast, c_ulong, c_void_p, create_string_buffer

SECURITY_MAX_SID_SIZE = 68
sidSize = SECURITY_MAX_SID_SIZE # removed c_ulong
sid = create_string_buffer(SECURITY_MAX_SID_SIZE)
rStatus = CreateWellKnownSid(
    WELL_KNOWN_SID_TYPE_WinLocalSystemSid,
    None,
    sid,
    sidSize) # not work after removed c_ulong
if not rStatus:
    raise
security = RPC_SECURITY_QOS_V3_W()
security.Sid = sid # not work after removed cast

@byehack
Copy link
Contributor Author

byehack commented Mar 15, 2023

^^^ This PR still not able to to cover removed cast(sid, c_void_p)

@byehack
Copy link
Contributor Author

byehack commented Mar 19, 2023

In continue of #8 I decided to create a TODO list to improve auto casting:

  • Parameters Pointers
  • Parameters Unions
  • Other types of Parameters
  • Results Pointers
  • Results Unions
  • Other types of Results

@byehack
Copy link
Contributor Author

byehack commented Mar 19, 2023

def easycast(obj, type_):
if isinstance(obj, str):
if issubclass(type_, (POINTER(Int16), POINTER(UInt16))):
return cast(c_wchar_p(obj), type_)
elif isinstance(obj, c_wchar_p):
if issubclass(type_, (POINTER(Int16), POINTER(UInt16))):
return cast(obj, type_)
elif issubclass(type_, (POINTER(POINTER(Int16)), POINTER(POINTER(UInt16)))):
return cast(pointer(obj), type_)
return obj

the function name is easycast but it has 2 more different abilities:

  1. it's convert related types in python object to c-type object: c_wchar_p(obj) at line 68.
  2. second is pointer(obj) at line 73.

I think these 2 should break into separate functions. if I had time, I'll send a PR for these.

byehack added a commit to byehack/py-win32more that referenced this issue Mar 19, 2023
ynkdir added a commit that referenced this issue Apr 25, 2023
@ynkdir
Copy link
Owner

ynkdir commented Apr 25, 2023

sidSize) # not work after removed c_ulong

For POINTER(c_int) type, it is ambiguous that int should be converted as cast(123, POINTER(c_int)) or pointer(c_int(123)).
I guess it is better to keep as is for now.

@mominshaikhdevs
Copy link

what's the latest update on this?

@ynkdir
Copy link
Owner

ynkdir commented Jul 14, 2024

I am still not sure how it should be.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants