how does toByte work while bit manipulation in python - python

The document for bit manipulation in python states
https://wiki.python.org/moin/BitManipulation
as example, the following code
import ctypes
c_uint8 = ctypes.c_uint8
class Flags_bits( ctypes.LittleEndianStructure ):
_fields_ = [
("logout", c_uint8, 1 ), # asByte & 1
("userswitch", c_uint8, 1 ), # asByte & 2
("suspend", c_uint8, 1 ), # asByte & 4
("idle", c_uint8, 1 ), # asByte & 8
]
class Flags( ctypes.Union ):
_anonymous_ = ("bit",)
_fields_ = [
("bit", Flags_bits ),
("asByte", c_uint8 )
]
flags = Flags()
flags.asByte = 0x2 # ->0010
print( "logout: %i" % flags.bit.logout )
# `bit` is defined as anonymous field, so its fields can also be accessed directly:
print( "logout: %i" % flags.logout )
print( "userswitch: %i" % flags.userswitch )
print( "suspend : %i" % flags.suspend )
print( "idle : %i" % flags.idle )
so i figured out that setting the value to asByte is leading to the value being parsed into the c_uint8, but i am unable to understand the logic behind this. When we set the asByte value, does python work back from the asByte value set to update the value for individual components that make the class. Also as a side note, i was not able to find documentation for asByte. If someone can point me to it, it'd be great.

Related

Python tkinter: Getting the number of entries in an OptionMenu dropdown list

The function below creates a nicely formatted list of all attributes of an OptionMenu widget. However a kludge is needed because OptionMenu does not having a "Menu size"' attribute (that holds the number of elements inside the dropdown list).
How do I extract this value from the widget so I can eliminate the kludge (and show the attributes of EVERY entry in the drop-down menu) ?
BTW, The function does not list the contents of the (non-standard) Optionmenu "command" option. For info on this option see the accepted answer to tkinter OptionMenu issue (bug?): GUI and program values not kept in lockstep (python 3.x) )
def OptionMenuConfigLister( OptionMenuWidget ) :
'''
Uncomment this block to see ALL attributes of the widget
#
# Gets the main attributes of the widget (EXCLUDING the attributes for
# the dropdown list and the values in the list)
#
print( " \nOptionMenuWidget.config()\n" )
for i, j in enumerate( sorted( OptionMenuWidget.config().items() ) ) :
print( " {0:<19} |{1}|".format( j[ 0 ], j[ 1 ][ -1 ] ), flush = True )
#
# Gets the attributes of the list portion of the widget (but NOT the entries)
#
print( "\nOptionMenuWidget[ 'menu' ].config().items() :\n" )
for i, j in enumerate( sorted( OptionMenuWidget[ 'menu' ].config().items() ) ) :
print( " {0:<18} |{1}|".format( j[ 0 ], j[ 1 ][ -1 ] ), flush = True )
'''
#
# Get the attributes of each/every entry in the dropdown list
#
# TODO: Determine how to get # of items in list
#
for i in range( 0, 1 ) : ''' <======== KLUDGE '''
print( "\nOptionMenuWidget[ 'menu' ].entryconfig(" + str( i ) + ").items()) :\n" )
for _, j in enumerate( sorted(
OptionMenuWidget[ 'menu' ].entryconfig( i ).items() ) ) :
print( " {0:<16} |{1}|".format( j[ 0 ], j[ 1 ][ -1 ] ), flush = True )
print()
return
EDIT 20180117: Here's the fix, based on the answer by #nae - replace the kludge line with:
ElementCount = OptionMenuWidget[ 'menu' ].index( 'end' ) + 1
for i in range( 0, ElementCount ) :
And as per comment by #furas, sample code now uses [ -1 ] in the formatted print statements.
Based on Menu total index counts and from the source code, the fact that OptionMenu's *values are stored as Menu items:
class OptionMenu(Menubutton):
"""OptionMenu which allows the user to select a value from a menu."""
def __init__(self, master, variable, value, *values, **kwargs):
...
menu.add_command(label=value,
command=_setit(variable, value, callback))
for v in values:
menu.add_command(label=v,
command=_setit(variable, v, callback))
self["menu"] = menu
One can extract the 'Menu Size' using .index('end') for OptionMenu's menu option like the following:
import tkinter as tk
root = tk.Tk()
opt_var = tk.IntVar()
opt = tk.OptionMenu(root, opt_var, 3, 2, 3, 5, 4)
opt.pack()
print(opt['menu'].index('end') + 1) # basically len(*values) + len(value)
root.mainloop()

Simple function that creates multiple emitters in Maya via Python

I'm trying to create a function that creates emitters (emitting from objects), but I'm having trouble getting it to work with multiple objects at the same time.
I want emitter1 to be connected to nParticle1 and emitter2 to nParticle2.
def particalWebSystem(webDensity,genoration):
selectedObject = cmds.ls( selection = True )
print selectedObject
if len(selectedObject)==0:
cmds.confirmDialog( title='Warning', message='Please select at least one object', button=['Close'], defaultButton='Close', cancelButton='Close', dismissString='Close' )
if len(selectedObject)==1:
print "<2"
else:
print ">2"
emitting = cmds.emitter( selectedObject, n='emitter' )
cmds.particle( n = 'nParticle#' )
cmds.connectDynamic( 'nParticle#', em = 'emitter' )
cmds.setAttr( "emitter.emitterType", 2 )
cmds.setAttr( "nParticle#Shape.lifespanMode", 2 )
cmds.setAttr( "nParticle#Shape.maxCount", webDensity )
cmds.setAttr( "nParticle#Shape.lifespanRandom", generation )
You can simplify this problem by making sure you use the name of the emitter you actually create -- you never know what name you'll really get because Maya will rename things. It's best to always capture the names of things you create and work on them instead of hoping you get the names you asked for.
This version makes a function and just calls it on every selected object. It will silently do nothing for empty selections it also returns the objects created in case you need them later.
import maya.cmds as cmds
def setup_emitter(source_object, maxcount, life_random):
source_object, emitting = cmds.emitter( source_object, n=source_object + "_emitter" )
particle, particleshape = cmds.particle( n = source_object + "_particles" )
cmds.connectDynamic( particle, em = emitting)
cmds.setAttr( emitting + ".emitterType", 2 )
cmds.setAttr( particleshape + ".lifespanMode", 2 )
cmds.setAttr( particleshape + ".maxCount", maxcount )
cmds.setAttr( particleshape + ".lifespanRandom", life_random )
return emitting, particleshape
for selection in cmds.ls(sl=True, type='transform'):
print setup_emitter(selection, 100, 100) # your values here

Parse PDB Symbol and Resolve Address

Using a python based disassembler + debugger I've found below instructions(example). Now I want to parse Microsoft provided public symbols to find exact functions its calling.
I want to know what are the available options/ modules to do the same. Can we just simply get the info from a static PDB files or its required to load that in memory while debugging ?
call ntdll!0x33dec
call ntdll!0x22280
call ntdll!0x2df40
call ntdll!0x33cdb
call ntdll!0x2df29
call ntdll!0x325a0
call ntdll!0x32a96
call ntdll!0x32a79
call ntdll!0x220a4
A sample that uses capstone for dis-assembly and dbghelp apis for symbol resolving of an immediate E8 call
import sys #for argv[]
import binascii #for hexlify repr() spits out ugly mix like
#'\xe8y\xff\' instead of '\xe8\x79\xff' :(
from ctypes import *
from capstone import *
class SYMBOL_INFO(Structure):
_fields_ = [
( 'SizeOfStruct', c_ulong ),
( 'TypeIndex', c_ulong ),
( 'Reserved', c_ulonglong * 2 ),
( 'Index', c_ulong ),
( 'Size', c_ulong ),
( 'ModBase', c_ulonglong ),
( 'Flags', c_ulong ),
( 'Value', c_ulonglong ),
( 'Address', c_ulonglong ),
( 'Register', c_ulong ),
( 'Scope', c_ulong ),
( 'Tag' , c_ulong ),
( 'NameLen', c_ulong ),
( 'MaxNameLen', c_ulong ),
( 'Name', c_char * 2001 )
]
modname = sys.argv[1]
offset = long(sys.argv[2],16)
sympath = "xxx:\\yyyyy" # substitute actual path
base = windll.LoadLibrary(modname)._handle
symaddr = c_ulonglong(base + offset)
print "Module name = %s\nModule Base = %s\nSymFromAddr = %s" % \
(modname,hex(base),hex(symaddr.value))
dbghelp = windll.dbghelp
k32 = windll.kernel32
hproc = k32.GetCurrentProcess()
dbghelp.SymInitialize(hproc,sympath,1)
sinfo = SYMBOL_INFO()
sinfo.SizeOfStruct = sizeof(SYMBOL_INFO) - 2000
sinfo.MaxNameLen = 2000
Displacement = c_ulonglong()
dbghelp.SymFromAddr(hproc,symaddr,addressof(Displacement),addressof(sinfo))
print "Sym At Addr = %s + %s" % (sinfo.Name,str(hex(Displacement.value)))
opcodebuff = create_string_buffer(16)
memmove(opcodebuff,symaddr.value,16)
for i in range(0,16,1):
print binascii.hexlify(opcodebuff.raw[i]),
print
MyDisasm = Cs(CS_ARCH_X86, CS_MODE_32)
for i in MyDisasm.disasm(opcodebuff, symaddr,1):
print "0x%x: %s %s %s" % ( i.address ,binascii.hexlify(i.bytes),
i.mnemonic, i.op_str)
if(i.mnemonic == 'call'):
try:
symaddr = c_ulonglong(long(i.op_str,16))
dbghelp.SymFromAddr(hproc,symaddr,addressof(Displacement),addressof(sinfo))
print "(%s+%s)" % (sinfo.Name,str(hex(Displacement.value))),
print "(%s+0x%X)"% (modname ,long(i.op_str,16)-base)
except:
print "Indirect/register Calls Not Handled Yet"
pass
usage as follows
python dumpsym.py ntdll 1041
first argument is a string that represents a module
second argument is a string that represents an offset in the module
so if module is loaded at 0xxxxxxxxx offset 1041 will point to the address
0xxxxxxxxx+0x1041
output
Module name = ntdll
Module Base = 0x7c900000
SymFromAddr = 0x7c901041L
Sym At Addr = RtlEnterCriticalSection + 0x41L
e8 79 a1 01 00 64 8b 0d 18 00 00 00 8b 54 24 04
0x7c901041: e879a10100 call 0x7c91b1bf
(RtlpWaitForCriticalSection+0x0L) (ntdll+0x1B1BF)
You can get symbols from PDB file using DbgHelp API. This is the same API WinDbg uses, and you can use it to debug live processes as well as simply extract symbols based on offset of the loaded module. In your case SymFromAddr function would be easiest to use to get symbol from an address.
One non-automated but quick way to do that would be :
Load ntdll.dll in the debugger as a dump file.
Load the symbols using the public symbol path - or local cache.
Use the ln command. Like: ln ntdll!0x33dec

Python ctypes access violation

I'm trying to access a dll from python, following this guide. The first function I try and call from the dll seems to work fine, so I must be most of the way there, but the second one gives me an access violation.
Python code:
#create open function
openProto = ctypes.WINFUNCTYPE( ctypes.c_int, ctypes.c_void_p )
openParams = ( 1, "handle", 0 ) ,
open = openProto ( ( "SensorOpen", pm ), openParams )
#create zero function
zeroProto = ctypes.WINFUNCTYPE( ctypes.c_int, ctypes.c_int )
zeroParams = ( 1, "handle", 0 ),
zero = zeroProto ( ( "SensorZero", pm ), zeroParams )
handle = ctypes.c_int ( 0 )
status = ctypes.c_int ( 0 )
open( ctypes.byref(handle) )
print handle
zero( handle )
The access violation occurs when I call the zero( handle ).
The C++ code that does this is here:
SENSOR_HANDLE seHandle; // Sensor handle
double power;
char buff[80];
// Get handle for sensor
SensorOpen (&seHandle);
printf ("Sensor connected\nZeroing, please wait...\n");
while (SensorZero (seHandle) == SENSOR_ZERO_FAILED)
{
printf ("Zero failed.\nCheck no power is being applied.\nPress return key to retry ");
gets (buff);
}
Where SENSOR_HANDLE is just a typedef'd int
Any ideas? I assume it's ok not to do anything with the returned value.
Problem solved.
The c++ code was sample code provided with some documentation. Needless to say the sample code and the documentation were incorrect (the zero function still wanted its argument as a pointer).

SendKeys for Python 3.1 on Windows

The latest Python Sendkeys module is for Python 2.6. I can't upgrade it myself as it needs the C module to be recompiled.
Does anyone know of a fairly easy alternative way to send keys to a window?
Using win32ui.FindWindow() I can find the right window, then make it active with PyCWnd.SetActiveWindow(), so all that's needed is a simple way to send keystrokes to the active window.
The purpose is to execute a menu item.
The app was written in Delphi, and doesn't have any inter-process interface that I know about.
Here is a working module that calls user32.SendInput().
Not perfect, but usable.
Edit:
Yesterday I did a version with a class, and am using it in a working tkinter app. Will put it here when i get time to clean it up.
Have added this in the doc string below:
[ It is OK if I work from a folder within my profile.
These problems happened when working on another partition.
File permissions were OK, so do not know what blocked SendInput. ]
SciTE still needs the full exact window title.
#!/usr/bin/python
# -*- coding: utf-8 -*-
''' send_input for python 3, from jh45dev#gmail.com
code from Daniel F is adapted here. The original is at:
http://mail.python.org/pipermail/python-win32/2005-April/003131.html
SendInput sends to the window that has the keyboard focus.
That window must not be minimized.
There seem to be some strange limitations with user32.SendInput()
Here is what happened in my testing (on Vista sp2).
[edit: It is OK if I work from a folder within my profile.
These problems happened when working on another partition.
File permissions were OK, so do not know what blocked SendInput.]
1
I opened Notepad from the Start menu,
then in Notepad opened test.txt,
and all worked fine.
2
I opened Notepad by opening test.txt in Explorer.
find_window() found Notepad, but user32.SendInput() had no effect.
If Notepad was minimized, it did not get restored or focussed.
The same happened with SciTE and Notepad2.
Another strangeness:
For SciTE I had to put in the whole window title, eg "test.txt - SciTE",
but for Notepad and Notepad2, only the app name, eg "Notepad".
'''
import ctypes as ct
from win32con import SW_MINIMIZE, SW_RESTORE
from win32ui import FindWindow, error as ui_err
from time import sleep
class cls_KeyBdInput(ct.Structure):
_fields_ = [
("wVk", ct.c_ushort),
("wScan", ct.c_ushort),
("dwFlags", ct.c_ulong),
("time", ct.c_ulong),
("dwExtraInfo", ct.POINTER(ct.c_ulong) )
]
class cls_HardwareInput(ct.Structure):
_fields_ = [
("uMsg", ct.c_ulong),
("wParamL", ct.c_short),
("wParamH", ct.c_ushort)
]
class cls_MouseInput(ct.Structure):
_fields_ = [
("dx", ct.c_long),
("dy", ct.c_long),
("mouseData", ct.c_ulong),
("dwFlags", ct.c_ulong),
("time", ct.c_ulong),
("dwExtraInfo", ct.POINTER(ct.c_ulong) )
]
class cls_Input_I(ct.Union):
_fields_ = [
("ki", cls_KeyBdInput),
("mi", cls_MouseInput),
("hi", cls_HardwareInput)
]
class cls_Input(ct.Structure):
_fields_ = [
("type", ct.c_ulong),
("ii", cls_Input_I)
]
def find_window( s_app_name ):
try:
window1 = FindWindow( None, s_app_name,)
return window1
except ui_err:
pass
except:
raise
try:
window1 = FindWindow( s_app_name, None, )
return window1
except ui_err:
return None
except:
raise
def make_input_objects( l_keys ):
p_ExtraInfo_0 = ct.pointer(ct.c_ulong(0))
l_inputs = [ ]
for n_key, n_updown in l_keys:
ki = cls_KeyBdInput( n_key, 0, n_updown, 0, p_ExtraInfo_0 )
ii = cls_Input_I()
ii.ki = ki
l_inputs.append( ii )
n_inputs = len(l_inputs)
l_inputs_2=[]
for ndx in range( 0, n_inputs ):
s2 = "(1, l_inputs[%s])" % ndx
l_inputs_2.append(s2)
s_inputs = ', '.join(l_inputs_2)
cls_input_array = cls_Input * n_inputs
o_input_array = eval( "cls_input_array( %s )" % s_inputs )
p_input_array = ct.pointer( o_input_array )
n_size_0 = ct.sizeof( o_input_array[0] )
# these are the args for user32.SendInput()
return ( n_inputs, p_input_array, n_size_0 )
'''It is interesting that o_input_array has gone out of scope
by the time p_input_array is used, but it works.'''
def send_input( window1, t_inputs, b_minimize=True ):
tpl1 = window1.GetWindowPlacement()
was_min = False
if tpl1[1] == 2:
was_min = True
window1.ShowWindow(SW_RESTORE)
sleep(0.2)
window1.SetForegroundWindow()
sleep(0.2)
window1.SetFocus()
sleep(0.2)
rv = ct.windll.user32.SendInput( *t_inputs )
if was_min and b_minimize:
sleep(0.3) # if the last input was Save, it may need time to take effect
window1.ShowWindow(SW_MINIMIZE)
return rv
# define some commonly-used key sequences
t_ctrl_s = ( # save in many apps
( 0x11, 0 ),
( 0x53, 0 ),
( 0x11, 2 ),
)
t_ctrl_r = ( # reload in some apps
( 0x11, 0 ),
( 0x52, 0 ),
( 0x11, 2 ),
)
def test():
# file > open; a non-invasive way to test
t_ctrl_o = ( ( 0x11, 0 ), ( 0x4F, 0 ), ( 0x11, 2 ), )
# writes "Hello\n"
# 0x10 is shift. note that to repeat a key, as with 4C here, you have to release it after the first press
t_hello = ( ( 0x10, 0 ), ( 0x48, 0 ), ( 0x10, 2 ), ( 0x45, 0 ), ( 0x4C, 0 ), ( 0x4C, 2 ), ( 0x4C, 0 ), ( 0x4F, 0 ), ( 0x0D, 0 ), )
l_keys = [ ]
## l_keys.extend( t_ctrl_o )
l_keys.extend( t_hello )
l_keys.extend( t_ctrl_s )
## s_app_name = "SciTE"
## s_app_name = "(Untitled) - SciTE"
s_app_name = "test.txt - SciTE"
## s_app_name = "Notepad2"
## s_app_name = "Notepad"
window1 = find_window( s_app_name )
if window1 == None:
print( "%r has no window." % s_app_name )
input( 'press enter to close' )
exit()
t_inputs = make_input_objects( l_keys )
n = send_input( window1, t_inputs )
## print( "SendInput returned: %r" % n )
## print( "GetLastError: %r" % ct.windll.kernel32.GetLastError() )
## input( 'press enter to close' )
if __name__ == '__main__':
test()
I rewrote the C bits of sendkeys in ctypes a while ago...
https://bitbucket.org/markm/sendkeysctypes
and I see someone else did it too:
http://code.google.com/p/sendkeys-ctypes/
If I remember it should be a drop in replacement for sendkeys (only the import line has to change)
Got something that works, using win32api.keybd_event.
Looks like SendInput would be safer, but pywin32 does not include it.
[ edit: See a SendInput version in the accepted answer below. I leave this message here in case someone prefers to use sendkeys. jh ]
This page helped: http://social.msdn.microsoft.com/Search/en-us/?Query=keybd_event
Code that works:
import win32api;
import win32ui
PyCWnd1 = win32ui.FindWindow( None, "an_app" )
PyCWnd1.SetForegroundWindow()
PyCWnd1.SetFocus()
win32api.keybd_event(0x12, 0, ) # Alt
win32api.keybd_event(0x12, 0, 2 ) # Alt release
win32api.keybd_event(0x46, 0, ) # F
win32api.keybd_event(0x52, 0, ) # R
This does File > Reload in the app. Does not work if the app is minimized
Without releasing Alt, after running this, the keyboard behaved like i was holding the Alt key!
Don't seem to need to release the other keys
You want the keybd_event API. My PushKeys program is syntax compatible with SendKeys and has a sleep function built in. Although it isn't in Python it should be translatable readily enough (its been translated into a lot of languages - at least it should show you the API to use). It is available here in a variety of languages.

Categories

Resources