Bump cherrypy from 18.8.0 to 18.9.0 (#2266)

* Bump cherrypy from 18.8.0 to 18.9.0

Bumps [cherrypy](https://github.com/cherrypy/cherrypy) from 18.8.0 to 18.9.0.
- [Changelog](https://github.com/cherrypy/cherrypy/blob/main/CHANGES.rst)
- [Commits](https://github.com/cherrypy/cherrypy/compare/v18.8.0...v18.9.0)

---
updated-dependencies:
- dependency-name: cherrypy
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update cherrypy==18.9.0

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>

[skip ci]
This commit is contained in:
dependabot[bot] 2024-03-24 15:25:44 -07:00 committed by GitHub
commit faef9a94c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
673 changed files with 159850 additions and 11583 deletions

View file

@ -0,0 +1,121 @@
## demonstrates using BackupRead and BackupWrite to copy all of a file's data streams
import ntsecuritycon
import pythoncom
import pywintypes
import win32api
import win32con
import win32file
import win32security
from pywin32_testutil import ob2memory, str2bytes
from win32com import storagecon
all_sd_info = (
win32security.DACL_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
)
tempdir = win32api.GetTempPath()
tempfile = win32api.GetTempFileName(tempdir, "bkr")[0]
outfile = win32api.GetTempFileName(tempdir, "out")[0]
print("Filename:", tempfile, "Output file:", outfile)
f = open(tempfile, "w")
f.write("some random junk" + "x" * 100)
f.close()
## add a couple of alternate data streams
f = open(tempfile + ":streamdata", "w")
f.write("data written to alternate stream" + "y" * 100)
f.close()
f = open(tempfile + ":anotherstream", "w")
f.write("z" * 100)
f.close()
## add Summary Information, which is stored as a separate stream
m = storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE | storagecon.STGM_DIRECT
pss = pythoncom.StgOpenStorageEx(
tempfile, m, storagecon.STGFMT_FILE, 0, pythoncom.IID_IPropertySetStorage, None
)
ps = pss.Create(
pythoncom.FMTID_SummaryInformation,
pythoncom.IID_IPropertyStorage,
0,
storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE,
)
ps.WriteMultiple(
(storagecon.PIDSI_KEYWORDS, storagecon.PIDSI_COMMENTS), ("keywords", "comments")
)
ps = None
pss = None
## add a custom security descriptor to make sure we don't
## get a default that would always be the same for both files in temp dir
new_sd = pywintypes.SECURITY_DESCRIPTOR()
sid = win32security.LookupAccountName("", "EveryOne")[0]
acl = pywintypes.ACL()
acl.AddAccessAllowedAce(1, win32con.GENERIC_READ, sid)
acl.AddAccessAllowedAce(1, ntsecuritycon.FILE_APPEND_DATA, sid)
acl.AddAccessAllowedAce(1, win32con.GENERIC_WRITE, sid)
acl.AddAccessAllowedAce(1, ntsecuritycon.FILE_ALL_ACCESS, sid)
new_sd.SetSecurityDescriptorDacl(True, acl, False)
win32security.SetFileSecurity(tempfile, win32security.DACL_SECURITY_INFORMATION, new_sd)
sa = pywintypes.SECURITY_ATTRIBUTES()
sa.bInheritHandle = True
h = win32file.CreateFile(
tempfile,
win32con.GENERIC_ALL,
win32con.FILE_SHARE_READ,
sa,
win32con.OPEN_EXISTING,
win32file.FILE_FLAG_BACKUP_SEMANTICS,
None,
)
outh = win32file.CreateFile(
outfile,
win32con.GENERIC_ALL,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
sa,
win32con.OPEN_EXISTING,
win32file.FILE_FLAG_BACKUP_SEMANTICS,
None,
)
ctxt = 0
outctxt = 0
buf = None
readsize = 100
while 1:
bytes_read, buf, ctxt = win32file.BackupRead(h, readsize, buf, False, True, ctxt)
if bytes_read == 0:
break
bytes_written, outctxt = win32file.BackupWrite(
outh, bytes_read, buf, False, True, outctxt
)
print("Written:", bytes_written, "Context:", outctxt)
win32file.BackupRead(h, 0, buf, True, True, ctxt)
win32file.BackupWrite(outh, 0, str2bytes(""), True, True, outctxt)
win32file.CloseHandle(h)
win32file.CloseHandle(outh)
assert open(tempfile).read() == open(outfile).read(), "File contents differ !"
assert (
open(tempfile + ":streamdata").read() == open(outfile + ":streamdata").read()
), "streamdata contents differ !"
assert (
open(tempfile + ":anotherstream").read() == open(outfile + ":anotherstream").read()
), "anotherstream contents differ !"
assert (
ob2memory(win32security.GetFileSecurity(tempfile, all_sd_info))[:]
== ob2memory(win32security.GetFileSecurity(outfile, all_sd_info))[:]
), "Security descriptors are different !"
## also should check Summary Info programatically

View file

@ -0,0 +1,137 @@
## demonstrates using BackupSeek to enumerate data streams for a file
import struct
import pythoncom
import pywintypes
import win32api
import win32con
import win32file
from win32com import storagecon
stream_types = {
win32con.BACKUP_DATA: "Standard data",
win32con.BACKUP_EA_DATA: "Extended attribute data",
win32con.BACKUP_SECURITY_DATA: "Security descriptor data",
win32con.BACKUP_ALTERNATE_DATA: "Alternative data streams",
win32con.BACKUP_LINK: "Hard link information",
win32con.BACKUP_PROPERTY_DATA: "Property data",
win32con.BACKUP_OBJECT_ID: "Objects identifiers",
win32con.BACKUP_REPARSE_DATA: "Reparse points",
win32con.BACKUP_SPARSE_BLOCK: "Sparse file",
}
tempdir = win32api.GetTempPath()
tempfile = win32api.GetTempFileName(tempdir, "bkr")[0]
print("Filename:", tempfile)
f = open(tempfile, "w")
f.write("some random junk" + "x" * 100)
f.close()
f = open(tempfile + ":streamdata", "w")
f.write("data written to alternate stream" + "y" * 100)
f.close()
f = open(tempfile + ":anotherstream", "w")
f.write("z" * 200)
f.close()
## add Summary Information, which is stored as a separate stream
m = storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE | storagecon.STGM_DIRECT
pss = pythoncom.StgOpenStorageEx(
tempfile, m, storagecon.STGFMT_FILE, 0, pythoncom.IID_IPropertySetStorage, None
)
ps = pss.Create(
pythoncom.FMTID_SummaryInformation,
pythoncom.IID_IPropertyStorage,
0,
storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE,
)
ps.WriteMultiple(
(storagecon.PIDSI_KEYWORDS, storagecon.PIDSI_COMMENTS), ("keywords", "comments")
)
ps = None
pss = None
sa = pywintypes.SECURITY_ATTRIBUTES()
sa.bInheritHandle = False
h = win32file.CreateFile(
tempfile,
win32con.GENERIC_ALL,
win32con.FILE_SHARE_READ,
sa,
win32con.OPEN_EXISTING,
win32file.FILE_FLAG_BACKUP_SEMANTICS,
None,
)
""" stream header:
typedef struct _WIN32_STREAM_ID {
DWORD dwStreamId; DWORD dwStreamAttributes; LARGE_INTEGER Size;
DWORD dwStreamNameSize; WCHAR cStreamName[ANYSIZE_ARRAY];
}
"""
win32_stream_id_format = "LLQL"
win32_stream_id_size = struct.calcsize(win32_stream_id_format)
def parse_stream_header(h, ctxt, data):
stream_type, stream_attributes, stream_size, stream_name_size = struct.unpack(
win32_stream_id_format, data
)
print(
"\nType:",
stream_type,
stream_types[stream_type],
"Attributes:",
stream_attributes,
"Size:",
stream_size,
"Name len:",
stream_name_size,
)
if stream_name_size > 0:
## ??? sdk says this size is in characters, but it appears to be number of bytes ???
bytes_read, stream_name_buf, ctxt = win32file.BackupRead(
h, stream_name_size, None, False, True, ctxt
)
stream_name = pywintypes.UnicodeFromRaw(stream_name_buf[:])
else:
stream_name = "Unnamed"
print("Name:" + stream_name)
return (
ctxt,
stream_type,
stream_attributes,
stream_size,
stream_name_size,
stream_name,
)
ctxt = 0
win32_stream_id_buf = (
None ## gets rebound to a writable buffer on first call and reused
)
while 1:
bytes_read, win32_stream_id_buf, ctxt = win32file.BackupRead(
h, win32_stream_id_size, win32_stream_id_buf, False, True, ctxt
)
if bytes_read == 0:
break
(
ctxt,
stream_type,
stream_attributes,
stream_size,
stream_name_size,
stream_name,
) = parse_stream_header(h, ctxt, win32_stream_id_buf[:])
if stream_size > 0:
bytes_moved = win32file.BackupSeek(h, stream_size, ctxt)
print("Moved: ", bytes_moved)
win32file.BackupRead(h, win32_stream_id_size, win32_stream_id_buf, True, True, ctxt)
win32file.CloseHandle(h)

View file

@ -0,0 +1,57 @@
import win32api
import win32file
def ProgressRoutine(
TotalFileSize,
TotalBytesTransferred,
StreamSize,
StreamBytesTransferred,
StreamNumber,
CallbackReason,
SourceFile,
DestinationFile,
Data,
):
print(Data)
print(
TotalFileSize,
TotalBytesTransferred,
StreamSize,
StreamBytesTransferred,
StreamNumber,
CallbackReason,
SourceFile,
DestinationFile,
)
##if TotalBytesTransferred > 100000:
## return win32file.PROGRESS_STOP
return win32file.PROGRESS_CONTINUE
temp_dir = win32api.GetTempPath()
fsrc = win32api.GetTempFileName(temp_dir, "cfe")[0]
fdst = win32api.GetTempFileName(temp_dir, "cfe")[0]
print(fsrc, fdst)
f = open(fsrc, "w")
f.write("xxxxxxxxxxxxxxxx\n" * 32768)
f.close()
## add a couple of extra data streams
f = open(fsrc + ":stream_y", "w")
f.write("yyyyyyyyyyyyyyyy\n" * 32768)
f.close()
f = open(fsrc + ":stream_z", "w")
f.write("zzzzzzzzzzzzzzzz\n" * 32768)
f.close()
operation_desc = "Copying " + fsrc + " to " + fdst
win32file.CopyFileEx(
fsrc,
fdst,
ProgressRoutine,
Data=operation_desc,
Cancel=False,
CopyFlags=win32file.COPY_FILE_RESTARTABLE,
Transaction=None,
)

View file

@ -0,0 +1,123 @@
"""
This demonstrates the creation of miniversions of a file during a transaction.
The FSCTL_TXFS_CREATE_MINIVERSION control code saves any changes to a new
miniversion (effectively a savepoint within a transaction).
"""
import os
import struct
import win32api
import win32con
import win32file
import win32transaction
import winerror
import winioctlcon
from pywin32_testutil import str2bytes # py3k-friendly helper
def demo():
"""
Definition of buffer used with FSCTL_TXFS_CREATE_MINIVERSION:
typedef struct _TXFS_CREATE_MINIVERSION_INFO{
USHORT StructureVersion;
USHORT StructureLength;
ULONG BaseVersion;
USHORT MiniVersion;}
"""
buf_fmt = "HHLH0L" ## buffer size must include struct padding
buf_size = struct.calcsize(buf_fmt)
tempdir = win32api.GetTempPath()
tempfile = win32api.GetTempFileName(tempdir, "cft")[0]
print("Demonstrating transactions on tempfile", tempfile)
f = open(tempfile, "w")
f.write("This is original file.\n")
f.close()
trans = win32transaction.CreateTransaction(
Description="Test creating miniversions of a file"
)
hfile = win32file.CreateFileW(
tempfile,
win32con.GENERIC_READ | win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
0,
None,
Transaction=trans,
)
win32file.WriteFile(hfile, str2bytes("This is first miniversion.\n"))
buf = win32file.DeviceIoControl(
hfile, winioctlcon.FSCTL_TXFS_CREATE_MINIVERSION, None, buf_size, None
)
struct_ver, struct_len, base_ver, ver_1 = struct.unpack(buf_fmt, buf)
win32file.SetFilePointer(hfile, 0, win32con.FILE_BEGIN)
win32file.WriteFile(hfile, str2bytes("This is second miniversion!\n"))
buf = win32file.DeviceIoControl(
hfile, winioctlcon.FSCTL_TXFS_CREATE_MINIVERSION, None, buf_size, None
)
struct_ver, struct_len, base_ver, ver_2 = struct.unpack(buf_fmt, buf)
hfile.Close()
## miniversions can't be opened with write access
hfile_0 = win32file.CreateFileW(
tempfile,
win32con.GENERIC_READ,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
0,
None,
Transaction=trans,
MiniVersion=base_ver,
)
print("version:", base_ver, win32file.ReadFile(hfile_0, 100))
hfile_0.Close()
hfile_1 = win32file.CreateFileW(
tempfile,
win32con.GENERIC_READ,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
0,
None,
Transaction=trans,
MiniVersion=ver_1,
)
print("version:", ver_1, win32file.ReadFile(hfile_1, 100))
hfile_1.Close()
hfile_2 = win32file.CreateFileW(
tempfile,
win32con.GENERIC_READ,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
0,
None,
Transaction=trans,
MiniVersion=ver_2,
)
print("version:", ver_2, win32file.ReadFile(hfile_2, 100))
hfile_2.Close()
## MiniVersions are destroyed when transaction is committed or rolled back
win32transaction.CommitTransaction(trans)
os.unlink(tempfile)
if __name__ == "__main__":
# When run on CI, this fails with NOT_SUPPORTED, so don't have that cause "failure"
try:
demo()
except win32file.error as e:
if e.winerror == winerror.ERROR_NOT_SUPPORTED:
print("These features are not supported by this filesystem.")
else:
raise

View file

@ -0,0 +1,83 @@
import sys
import win32evtlog
def main():
path = "System"
num_events = 5
if len(sys.argv) > 2:
path = sys.argv[1]
num_events = int(sys.argv[2])
elif len(sys.argv) > 1:
path = sys.argv[1]
query = win32evtlog.EvtQuery(path, win32evtlog.EvtQueryForwardDirection)
events = win32evtlog.EvtNext(query, num_events)
context = win32evtlog.EvtCreateRenderContext(win32evtlog.EvtRenderContextSystem)
for i, event in enumerate(events, 1):
result = win32evtlog.EvtRender(
event, win32evtlog.EvtRenderEventValues, Context=context
)
print("Event {}".format(i))
level_value, level_variant = result[win32evtlog.EvtSystemLevel]
if level_variant != win32evtlog.EvtVarTypeNull:
if level_value == 1:
print(" Level: CRITICAL")
elif level_value == 2:
print(" Level: ERROR")
elif level_value == 3:
print(" Level: WARNING")
elif level_value == 4:
print(" Level: INFO")
elif level_value == 5:
print(" Level: VERBOSE")
else:
print(" Level: UNKNOWN")
time_created_value, time_created_variant = result[
win32evtlog.EvtSystemTimeCreated
]
if time_created_variant != win32evtlog.EvtVarTypeNull:
print(" Timestamp: {}".format(time_created_value.isoformat()))
computer_value, computer_variant = result[win32evtlog.EvtSystemComputer]
if computer_variant != win32evtlog.EvtVarTypeNull:
print(" FQDN: {}".format(computer_value))
provider_name_value, provider_name_variant = result[
win32evtlog.EvtSystemProviderName
]
if provider_name_variant != win32evtlog.EvtVarTypeNull:
print(" Provider: {}".format(provider_name_value))
try:
metadata = win32evtlog.EvtOpenPublisherMetadata(provider_name_value)
# pywintypes.error: (2, 'EvtOpenPublisherMetadata', 'The system cannot find the file specified.')
except Exception:
pass
else:
try:
message = win32evtlog.EvtFormatMessage(
metadata, event, win32evtlog.EvtFormatMessageEvent
)
# pywintypes.error: (15027, 'EvtFormatMessage: allocated 0, need buffer of size 0', 'The message resource is present but the message was not found in the message table.')
except Exception:
pass
else:
try:
print(" Message: {}".format(message))
except UnicodeEncodeError:
# Obscure error when run under subprocess.Popen(), presumably due to
# not knowing the correct encoding for the console.
# > UnicodeEncodeError: \'charmap\' codec can\'t encode character \'\\u200e\' in position 57: character maps to <undefined>\r\n'
# Can't reproduce when running manually, so it seems more a subprocess.Popen()
# than ours:
print(" Failed to decode:", repr(message))
if __name__ == "__main__":
main()

View file

@ -0,0 +1,28 @@
## Demonstrates how to create a "pull" subscription
import win32con
import win32event
import win32evtlog
query_text = '*[System[Provider[@Name="Microsoft-Windows-Winlogon"]]]'
h = win32event.CreateEvent(None, 0, 0, None)
s = win32evtlog.EvtSubscribe(
"System",
win32evtlog.EvtSubscribeStartAtOldestRecord,
SignalEvent=h,
Query=query_text,
)
while 1:
while 1:
events = win32evtlog.EvtNext(s, 10)
if len(events) == 0:
break
##for event in events:
## print(win32evtlog.EvtRender(event, win32evtlog.EvtRenderEventXml))
print("retrieved %s events" % len(events))
while 1:
print("waiting...")
w = win32event.WaitForSingleObjectEx(h, 2000, True)
if w == win32con.WAIT_OBJECT_0:
break

View file

@ -0,0 +1,25 @@
## Demonstrates a "push" subscription with a callback function
import win32evtlog
query_text = '*[System[Provider[@Name="Microsoft-Windows-Winlogon"]]]'
def c(reason, context, evt):
if reason == win32evtlog.EvtSubscribeActionError:
print("EvtSubscribeActionError")
elif reason == win32evtlog.EvtSubscribeActionDeliver:
print("EvtSubscribeActionDeliver")
else:
print("??? Unknown action ???", reason)
context.append(win32evtlog.EvtRender(evt, win32evtlog.EvtRenderEventXml))
return 0
evttext = []
s = win32evtlog.EvtSubscribe(
"System",
win32evtlog.EvtSubscribeStartAtOldestRecord,
Query="*",
Callback=c,
Context=evttext,
)

View file

@ -0,0 +1,137 @@
# Contributed by Kelly Kranabetter.
import os
import sys
import ntsecuritycon
import pywintypes
import win32security
import winerror
# get security information
# name=r"c:\autoexec.bat"
# name= r"g:\!workgrp\lim"
name = sys.argv[0]
if not os.path.exists(name):
print(name, "does not exist!")
sys.exit()
print("On file ", name, "\n")
# get owner SID
print("OWNER")
try:
sd = win32security.GetFileSecurity(name, win32security.OWNER_SECURITY_INFORMATION)
sid = sd.GetSecurityDescriptorOwner()
print(" ", win32security.LookupAccountSid(None, sid))
except pywintypes.error as exc:
# in automation and network shares we see:
# pywintypes.error: (1332, 'LookupAccountName', 'No mapping between account names and security IDs was done.')
if exc.winerror != winerror.ERROR_NONE_MAPPED:
raise
print("No owner information is available")
# get group SID
try:
print("GROUP")
sd = win32security.GetFileSecurity(name, win32security.GROUP_SECURITY_INFORMATION)
sid = sd.GetSecurityDescriptorGroup()
print(" ", win32security.LookupAccountSid(None, sid))
except pywintypes.error as exc:
if exc.winerror != winerror.ERROR_NONE_MAPPED:
raise
print("No group information is available")
# get ACEs
sd = win32security.GetFileSecurity(name, win32security.DACL_SECURITY_INFORMATION)
dacl = sd.GetSecurityDescriptorDacl()
if dacl == None:
print("No Discretionary ACL")
else:
for ace_no in range(0, dacl.GetAceCount()):
ace = dacl.GetAce(ace_no)
print("ACE", ace_no)
print(" -Type")
for i in (
"ACCESS_ALLOWED_ACE_TYPE",
"ACCESS_DENIED_ACE_TYPE",
"SYSTEM_AUDIT_ACE_TYPE",
"SYSTEM_ALARM_ACE_TYPE",
):
if getattr(ntsecuritycon, i) == ace[0][0]:
print(" ", i)
print(" -Flags", hex(ace[0][1]))
for i in (
"OBJECT_INHERIT_ACE",
"CONTAINER_INHERIT_ACE",
"NO_PROPAGATE_INHERIT_ACE",
"INHERIT_ONLY_ACE",
"SUCCESSFUL_ACCESS_ACE_FLAG",
"FAILED_ACCESS_ACE_FLAG",
):
if getattr(ntsecuritycon, i) & ace[0][1] == getattr(ntsecuritycon, i):
print(" ", i)
print(" -mask", hex(ace[1]))
# files and directories do permissions differently
permissions_file = (
"DELETE",
"READ_CONTROL",
"WRITE_DAC",
"WRITE_OWNER",
"SYNCHRONIZE",
"FILE_GENERIC_READ",
"FILE_GENERIC_WRITE",
"FILE_GENERIC_EXECUTE",
"FILE_DELETE_CHILD",
)
permissions_dir = (
"DELETE",
"READ_CONTROL",
"WRITE_DAC",
"WRITE_OWNER",
"SYNCHRONIZE",
"FILE_ADD_SUBDIRECTORY",
"FILE_ADD_FILE",
"FILE_DELETE_CHILD",
"FILE_LIST_DIRECTORY",
"FILE_TRAVERSE",
"FILE_READ_ATTRIBUTES",
"FILE_WRITE_ATTRIBUTES",
"FILE_READ_EA",
"FILE_WRITE_EA",
)
permissions_dir_inherit = (
"DELETE",
"READ_CONTROL",
"WRITE_DAC",
"WRITE_OWNER",
"SYNCHRONIZE",
"GENERIC_READ",
"GENERIC_WRITE",
"GENERIC_EXECUTE",
"GENERIC_ALL",
)
if os.path.isfile(name):
permissions = permissions_file
else:
permissions = permissions_dir
# directories also contain an ACE that is inherited by children (files) within them
if (
ace[0][1] & ntsecuritycon.OBJECT_INHERIT_ACE
== ntsecuritycon.OBJECT_INHERIT_ACE
and ace[0][1] & ntsecuritycon.INHERIT_ONLY_ACE
== ntsecuritycon.INHERIT_ONLY_ACE
):
permissions = permissions_dir_inherit
calc_mask = 0 # calculate the mask so we can see if we are printing all of the permissions
for i in permissions:
if getattr(ntsecuritycon, i) & ace[1] == getattr(ntsecuritycon, i):
calc_mask = calc_mask | getattr(ntsecuritycon, i)
print(" ", i)
print(" ", "Calculated Check Mask=", hex(calc_mask))
print(" -SID\n ", win32security.LookupAccountSid(None, ace[2]))

View file

@ -0,0 +1,43 @@
import os
import win32con
import win32gui
filter = "Python Scripts\0*.py;*.pyw;*.pys\0Text files\0*.txt\0"
customfilter = "Other file types\0*.*\0"
fname, customfilter, flags = win32gui.GetSaveFileNameW(
InitialDir=os.environ["temp"],
Flags=win32con.OFN_ALLOWMULTISELECT | win32con.OFN_EXPLORER,
File="somefilename",
DefExt="py",
Title="GetSaveFileNameW",
Filter=filter,
CustomFilter=customfilter,
FilterIndex=1,
)
print("save file names:", repr(fname))
print("filter used:", repr(customfilter))
print("Flags:", flags)
for k, v in list(win32con.__dict__.items()):
if k.startswith("OFN_") and flags & v:
print("\t" + k)
fname, customfilter, flags = win32gui.GetOpenFileNameW(
InitialDir=os.environ["temp"],
Flags=win32con.OFN_ALLOWMULTISELECT | win32con.OFN_EXPLORER,
File="somefilename",
DefExt="py",
Title="GetOpenFileNameW",
Filter=filter,
CustomFilter=customfilter,
FilterIndex=0,
)
print("open file names:", repr(fname))
print("filter used:", repr(customfilter))
print("Flags:", flags)
for k, v in list(win32con.__dict__.items()):
if k.startswith("OFN_") and flags & v:
print("\t" + k)

View file

@ -0,0 +1,127 @@
"""A demo of using win32net.NetValidatePasswordPolicy.
Example usage:
% NetValidatePasswordPolicy.py --password=foo change
which might return:
> Result of 'change' validation is 0: The operation completed successfully.
or depending on the policy:
> Result of 'change' validation is 2245: The password does not meet the
> password policy requirements. Check the minimum password length,
> password complexity and password history requirements.
Adding --user doesn't seem to change the output (even the PasswordLastSet seen
when '-f' is used doesn't depend on the username), but theoretically it will
also check the password history for the specified user.
% NetValidatePasswordPolicy.py auth
which always (with and without '-m') seems to return:
> Result of 'auth' validation is 2701: Password must change at next logon
"""
import optparse
import sys
from pprint import pprint
import win32api
import win32net
import win32netcon
def main():
parser = optparse.OptionParser(
"%prog [options] auth|change ...",
description="A win32net.NetValidatePasswordPolicy demo.",
)
parser.add_option(
"-u",
"--username",
action="store",
help="The username to pass to the function (only for the " "change command",
)
parser.add_option(
"-p",
"--password",
action="store",
help="The clear-text password to pass to the function "
"(only for the 'change' command)",
)
parser.add_option(
"-m",
"--password-matched",
action="store_false",
default=True,
help="Used to specify the password does NOT match (ie, "
"uses False for the PasswordMatch/PasswordMatched "
"arg, both 'auth' and 'change' commands)",
)
parser.add_option(
"-s",
"--server",
action="store",
help="The name of the server to execute the command on",
)
parser.add_option(
"-f",
"--show_fields",
action="store_true",
default=False,
help="Print the NET_VALIDATE_PERSISTED_FIELDS returned",
)
options, args = parser.parse_args()
if not args:
args = ["auth"]
for arg in args:
if arg == "auth":
input = {
"PasswordMatched": options.password_matched,
}
val_type = win32netcon.NetValidateAuthentication
elif arg == "change":
input = {
"ClearPassword": options.password,
"PasswordMatch": options.password_matched,
"UserAccountName": options.username,
}
val_type = win32netcon.NetValidatePasswordChange
else:
parser.error("Invalid arg - must be 'auth' or 'change'")
try:
fields, status = win32net.NetValidatePasswordPolicy(
options.server, None, val_type, input
)
except NotImplementedError:
print("NetValidatePasswordPolicy not implemented on this platform.")
return 1
except win32net.error as exc:
print("NetValidatePasswordPolicy failed: ", exc)
return 1
if options.show_fields:
print("NET_VALIDATE_PERSISTED_FIELDS fields:")
pprint(fields)
print(
"Result of %r validation is %d: %s"
% (arg, status, win32api.FormatMessage(status).strip())
)
return 0
if __name__ == "__main__":
sys.exit(main())

View file

@ -0,0 +1,67 @@
import os
import win32api
import win32file
import winerror
def ReadCallback(input_buffer, data, buflen):
fnamein, fnameout, f = data
## print fnamein, fnameout, buflen
f.write(input_buffer)
## python 2.3 throws an error if return value is a plain int
return winerror.ERROR_SUCCESS
def WriteCallback(output_buffer, data, buflen):
fnamebackup, fnameout, f = data
file_data = f.read(buflen)
## returning 0 as len terminates WriteEncryptedFileRaw
output_len = len(file_data)
output_buffer[:output_len] = file_data
return winerror.ERROR_SUCCESS, output_len
tmp_dir = win32api.GetTempPath()
dst_dir = win32api.GetTempFileName(tmp_dir, "oef")[0]
os.remove(dst_dir)
os.mkdir(dst_dir)
print("Destination dir:", dst_dir)
## create an encrypted file
fname = win32api.GetTempFileName(dst_dir, "ref")[0]
print("orig file:", fname)
f = open(fname, "w")
f.write("xxxxxxxxxxxxxxxx\n" * 32768)
f.close()
## add a couple of extra data streams
f = open(fname + ":stream_y", "w")
f.write("yyyyyyyyyyyyyyyy\n" * 32768)
f.close()
f = open(fname + ":stream_z", "w")
f.write("zzzzzzzzzzzzzzzz\n" * 32768)
f.close()
win32file.EncryptFile(fname)
## backup raw data of encrypted file
bkup_fname = win32api.GetTempFileName(dst_dir, "bef")[0]
print("backup file:", bkup_fname)
f = open(bkup_fname, "wb")
ctxt = win32file.OpenEncryptedFileRaw(fname, 0)
try:
win32file.ReadEncryptedFileRaw(ReadCallback, (fname, bkup_fname, f), ctxt)
finally:
## if context is not closed, file remains locked even if calling process is killed
win32file.CloseEncryptedFileRaw(ctxt)
f.close()
## restore data from backup to new encrypted file
dst_fname = win32api.GetTempFileName(dst_dir, "wef")[0]
print("restored file:", dst_fname)
f = open(bkup_fname, "rb")
ctxtout = win32file.OpenEncryptedFileRaw(dst_fname, win32file.CREATE_FOR_IMPORT)
try:
win32file.WriteEncryptedFileRaw(WriteCallback, (bkup_fname, dst_fname, f), ctxtout)
finally:
win32file.CloseEncryptedFileRaw(ctxtout)
f.close()

View file

@ -0,0 +1,60 @@
import win32api
import win32con
import win32transaction
keyname = "Pywin32 test transacted registry functions"
subkeyname = "test transacted subkey"
classname = "Transacted Class"
trans = win32transaction.CreateTransaction(Description="test RegCreateKeyTransacted")
key, disp = win32api.RegCreateKeyEx(
win32con.HKEY_CURRENT_USER,
keyname,
samDesired=win32con.KEY_ALL_ACCESS,
Class=classname,
)
## clean up any existing keys
for subk in win32api.RegEnumKeyExW(key):
win32api.RegDeleteKey(key, subk[0])
## reopen key in transacted mode
transacted_key = win32api.RegOpenKeyTransacted(
Key=win32con.HKEY_CURRENT_USER,
SubKey=keyname,
Transaction=trans,
samDesired=win32con.KEY_ALL_ACCESS,
)
subkey, disp = win32api.RegCreateKeyEx(
transacted_key,
subkeyname,
Transaction=trans,
samDesired=win32con.KEY_ALL_ACCESS,
Class=classname,
)
## Newly created key should not be visible from non-transacted handle
subkeys = [s[0] for s in win32api.RegEnumKeyExW(key)]
assert subkeyname not in subkeys
transacted_subkeys = [s[0] for s in win32api.RegEnumKeyExW(transacted_key)]
assert subkeyname in transacted_subkeys
## Key should be visible to non-transacted handle after commit
win32transaction.CommitTransaction(trans)
subkeys = [s[0] for s in win32api.RegEnumKeyExW(key)]
assert subkeyname in subkeys
## test transacted delete
del_trans = win32transaction.CreateTransaction(
Description="test RegDeleteKeyTransacted"
)
win32api.RegDeleteKeyEx(key, subkeyname, Transaction=del_trans)
## subkey should still show up for non-transacted handle
subkeys = [s[0] for s in win32api.RegEnumKeyExW(key)]
assert subkeyname in subkeys
## ... and should be gone after commit
win32transaction.CommitTransaction(del_trans)
subkeys = [s[0] for s in win32api.RegEnumKeyExW(key)]
assert subkeyname not in subkeys
win32api.RegDeleteKey(win32con.HKEY_CURRENT_USER, keyname)

View file

@ -0,0 +1,71 @@
import os
import ntsecuritycon
import win32api
import win32con
import win32security
import winnt
temp_dir = win32api.GetTempPath()
fname = win32api.GetTempFileName(temp_dir, "rsk")[0]
print(fname)
## file can't exist
os.remove(fname)
## enable backup and restore privs
required_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_BACKUP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32con.TOKEN_READ | win32con.TOKEN_ADJUST_PRIVILEGES
)
adjusted_privs = win32security.AdjustTokenPrivileges(th, 0, required_privs)
try:
sa = win32security.SECURITY_ATTRIBUTES()
my_sid = win32security.GetTokenInformation(th, ntsecuritycon.TokenUser)[0]
sa.SECURITY_DESCRIPTOR.SetSecurityDescriptorOwner(my_sid, 0)
k, disp = win32api.RegCreateKeyEx(
win32con.HKEY_CURRENT_USER,
"Python test key",
SecurityAttributes=sa,
samDesired=win32con.KEY_ALL_ACCESS,
Class="some class",
Options=0,
)
win32api.RegSetValue(k, None, win32con.REG_SZ, "Default value for python test key")
subk, disp = win32api.RegCreateKeyEx(
k,
"python test subkey",
SecurityAttributes=sa,
samDesired=win32con.KEY_ALL_ACCESS,
Class="some other class",
Options=0,
)
win32api.RegSetValue(subk, None, win32con.REG_SZ, "Default value for subkey")
win32api.RegSaveKeyEx(
k, fname, Flags=winnt.REG_STANDARD_FORMAT, SecurityAttributes=sa
)
restored_key, disp = win32api.RegCreateKeyEx(
win32con.HKEY_CURRENT_USER,
"Python test key(restored)",
SecurityAttributes=sa,
samDesired=win32con.KEY_ALL_ACCESS,
Class="restored class",
Options=0,
)
win32api.RegRestoreKey(restored_key, fname)
finally:
win32security.AdjustTokenPrivileges(th, 0, adjusted_privs)

View file

@ -0,0 +1,210 @@
import glob
import os
import time
import win32api
import win32con
import win32gui
## some of these tests will fail for systems prior to XP
for pname in (
## Set actions all take an unsigned int in pvParam
"SPI_GETMOUSESPEED",
"SPI_GETACTIVEWNDTRKTIMEOUT",
"SPI_GETCARETWIDTH",
"SPI_GETFOREGROUNDFLASHCOUNT",
"SPI_GETFOREGROUNDLOCKTIMEOUT",
## Set actions all take an unsigned int in uiParam
"SPI_GETWHEELSCROLLLINES",
"SPI_GETKEYBOARDDELAY",
"SPI_GETKEYBOARDSPEED",
"SPI_GETMOUSEHOVERHEIGHT",
"SPI_GETMOUSEHOVERWIDTH",
"SPI_GETMOUSEHOVERTIME",
"SPI_GETSCREENSAVETIMEOUT",
"SPI_GETMENUSHOWDELAY",
"SPI_GETLOWPOWERTIMEOUT",
"SPI_GETPOWEROFFTIMEOUT",
"SPI_GETBORDER",
## below are winxp only:
"SPI_GETFONTSMOOTHINGCONTRAST",
"SPI_GETFONTSMOOTHINGTYPE",
"SPI_GETFOCUSBORDERHEIGHT",
"SPI_GETFOCUSBORDERWIDTH",
"SPI_GETMOUSECLICKLOCKTIME",
):
print(pname)
cget = getattr(win32con, pname)
cset = getattr(win32con, pname.replace("_GET", "_SET"))
orig_value = win32gui.SystemParametersInfo(cget)
print("\toriginal setting:", orig_value)
win32gui.SystemParametersInfo(cset, orig_value + 1)
new_value = win32gui.SystemParametersInfo(cget)
print("\tnew value:", new_value)
# On Vista, some of these values seem to be ignored. So only "fail" if
# the new value isn't what we set or the original
if new_value != orig_value + 1:
assert new_value == orig_value
print("Strange - setting %s seems to have been ignored" % (pname,))
win32gui.SystemParametersInfo(cset, orig_value)
assert win32gui.SystemParametersInfo(cget) == orig_value
# these take a boolean value in pvParam
# change to opposite, check that it was changed and change back
for pname in (
"SPI_GETFLATMENU",
"SPI_GETDROPSHADOW",
"SPI_GETKEYBOARDCUES",
"SPI_GETMENUFADE",
"SPI_GETCOMBOBOXANIMATION",
"SPI_GETCURSORSHADOW",
"SPI_GETGRADIENTCAPTIONS",
"SPI_GETHOTTRACKING",
"SPI_GETLISTBOXSMOOTHSCROLLING",
"SPI_GETMENUANIMATION",
"SPI_GETSELECTIONFADE",
"SPI_GETTOOLTIPANIMATION",
"SPI_GETTOOLTIPFADE",
"SPI_GETUIEFFECTS",
"SPI_GETACTIVEWINDOWTRACKING",
"SPI_GETACTIVEWNDTRKZORDER",
):
print(pname)
cget = getattr(win32con, pname)
cset = getattr(win32con, pname.replace("_GET", "_SET"))
orig_value = win32gui.SystemParametersInfo(cget)
print(orig_value)
win32gui.SystemParametersInfo(cset, not orig_value)
new_value = win32gui.SystemParametersInfo(cget)
print(new_value)
assert orig_value != new_value
win32gui.SystemParametersInfo(cset, orig_value)
assert win32gui.SystemParametersInfo(cget) == orig_value
# these take a boolean in uiParam
# could combine with above section now that SystemParametersInfo only takes a single parameter
for pname in (
"SPI_GETFONTSMOOTHING",
"SPI_GETICONTITLEWRAP",
"SPI_GETBEEP",
"SPI_GETBLOCKSENDINPUTRESETS",
"SPI_GETKEYBOARDPREF",
"SPI_GETSCREENSAVEACTIVE",
"SPI_GETMENUDROPALIGNMENT",
"SPI_GETDRAGFULLWINDOWS",
"SPI_GETSHOWIMEUI",
):
cget = getattr(win32con, pname)
cset = getattr(win32con, pname.replace("_GET", "_SET"))
orig_value = win32gui.SystemParametersInfo(cget)
win32gui.SystemParametersInfo(cset, not orig_value)
new_value = win32gui.SystemParametersInfo(cget)
# Some of these also can't be changed (eg, SPI_GETSCREENSAVEACTIVE) so
# don't actually get upset.
if orig_value != new_value:
print("successfully toggled", pname, "from", orig_value, "to", new_value)
else:
print("couldn't toggle", pname, "from", orig_value)
win32gui.SystemParametersInfo(cset, orig_value)
assert win32gui.SystemParametersInfo(cget) == orig_value
print("SPI_GETICONTITLELOGFONT")
lf = win32gui.SystemParametersInfo(win32con.SPI_GETICONTITLELOGFONT)
orig_height = lf.lfHeight
orig_italic = lf.lfItalic
print("Height:", orig_height, "Italic:", orig_italic)
lf.lfHeight += 2
lf.lfItalic = not lf.lfItalic
win32gui.SystemParametersInfo(win32con.SPI_SETICONTITLELOGFONT, lf)
new_lf = win32gui.SystemParametersInfo(win32con.SPI_GETICONTITLELOGFONT)
print("New Height:", new_lf.lfHeight, "New Italic:", new_lf.lfItalic)
assert new_lf.lfHeight == orig_height + 2
assert new_lf.lfItalic != orig_italic
lf.lfHeight = orig_height
lf.lfItalic = orig_italic
win32gui.SystemParametersInfo(win32con.SPI_SETICONTITLELOGFONT, lf)
new_lf = win32gui.SystemParametersInfo(win32con.SPI_GETICONTITLELOGFONT)
assert new_lf.lfHeight == orig_height
assert new_lf.lfItalic == orig_italic
print("SPI_GETMOUSEHOVERWIDTH, SPI_GETMOUSEHOVERHEIGHT, SPI_GETMOUSEHOVERTIME")
w = win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERWIDTH)
h = win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERHEIGHT)
t = win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERTIME)
print("w,h,t:", w, h, t)
win32gui.SystemParametersInfo(win32con.SPI_SETMOUSEHOVERWIDTH, w + 1)
win32gui.SystemParametersInfo(win32con.SPI_SETMOUSEHOVERHEIGHT, h + 2)
win32gui.SystemParametersInfo(win32con.SPI_SETMOUSEHOVERTIME, t + 3)
new_w = win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERWIDTH)
new_h = win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERHEIGHT)
new_t = win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERTIME)
print("new w,h,t:", new_w, new_h, new_t)
assert new_w == w + 1
assert new_h == h + 2
assert new_t == t + 3
win32gui.SystemParametersInfo(win32con.SPI_SETMOUSEHOVERWIDTH, w)
win32gui.SystemParametersInfo(win32con.SPI_SETMOUSEHOVERHEIGHT, h)
win32gui.SystemParametersInfo(win32con.SPI_SETMOUSEHOVERTIME, t)
new_w = win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERWIDTH)
new_h = win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERHEIGHT)
new_t = win32gui.SystemParametersInfo(win32con.SPI_GETMOUSEHOVERTIME)
assert new_w == w
assert new_h == h
assert new_t == t
print("SPI_SETDOUBLECLKWIDTH, SPI_SETDOUBLECLKHEIGHT")
x = win32api.GetSystemMetrics(win32con.SM_CXDOUBLECLK)
y = win32api.GetSystemMetrics(win32con.SM_CYDOUBLECLK)
print("x,y:", x, y)
win32gui.SystemParametersInfo(win32con.SPI_SETDOUBLECLKWIDTH, x + 1)
win32gui.SystemParametersInfo(win32con.SPI_SETDOUBLECLKHEIGHT, y + 2)
new_x = win32api.GetSystemMetrics(win32con.SM_CXDOUBLECLK)
new_y = win32api.GetSystemMetrics(win32con.SM_CYDOUBLECLK)
print("new x,y:", new_x, new_y)
assert new_x == x + 1
assert new_y == y + 2
win32gui.SystemParametersInfo(win32con.SPI_SETDOUBLECLKWIDTH, x)
win32gui.SystemParametersInfo(win32con.SPI_SETDOUBLECLKHEIGHT, y)
new_x = win32api.GetSystemMetrics(win32con.SM_CXDOUBLECLK)
new_y = win32api.GetSystemMetrics(win32con.SM_CYDOUBLECLK)
assert new_x == x
assert new_y == y
print("SPI_SETDRAGWIDTH, SPI_SETDRAGHEIGHT")
dw = win32api.GetSystemMetrics(win32con.SM_CXDRAG)
dh = win32api.GetSystemMetrics(win32con.SM_CYDRAG)
print("dw,dh:", dw, dh)
win32gui.SystemParametersInfo(win32con.SPI_SETDRAGWIDTH, dw + 1)
win32gui.SystemParametersInfo(win32con.SPI_SETDRAGHEIGHT, dh + 2)
new_dw = win32api.GetSystemMetrics(win32con.SM_CXDRAG)
new_dh = win32api.GetSystemMetrics(win32con.SM_CYDRAG)
print("new dw,dh:", new_dw, new_dh)
assert new_dw == dw + 1
assert new_dh == dh + 2
win32gui.SystemParametersInfo(win32con.SPI_SETDRAGWIDTH, dw)
win32gui.SystemParametersInfo(win32con.SPI_SETDRAGHEIGHT, dh)
new_dw = win32api.GetSystemMetrics(win32con.SM_CXDRAG)
new_dh = win32api.GetSystemMetrics(win32con.SM_CYDRAG)
assert new_dw == dw
assert new_dh == dh
orig_wallpaper = win32gui.SystemParametersInfo(Action=win32con.SPI_GETDESKWALLPAPER)
print("Original: ", orig_wallpaper)
for bmp in glob.glob(os.path.join(os.environ["windir"], "*.bmp")):
print(bmp)
win32gui.SystemParametersInfo(win32con.SPI_SETDESKWALLPAPER, Param=bmp)
print(win32gui.SystemParametersInfo(Action=win32con.SPI_GETDESKWALLPAPER))
time.sleep(1)
win32gui.SystemParametersInfo(win32con.SPI_SETDESKWALLPAPER, Param=orig_wallpaper)

View file

@ -0,0 +1,26 @@
# A sample distutils script to show to build your own
# extension module which extends pywintypes or pythoncom.
#
# Use 'python setup.py build' to build this extension.
import os
from distutils.core import Extension, setup
from sysconfig import get_paths
sources = ["win32_extension.cpp"]
lib_dir = get_paths()["platlib"]
# Specify the directory where the PyWin32 .h and .lib files are installed.
# If you are doing a win32com extension, you will also need to add
# win32com\Include and win32com\Libs.
ext = Extension(
"win32_extension",
sources,
include_dirs=[os.path.join(lib_dir, "win32", "include")],
library_dirs=[os.path.join(lib_dir, "win32", "libs")],
)
setup(
name="win32 extension sample",
version="0.1",
ext_modules=[ext],
)

254
lib/win32/Demos/cerapi.py Normal file
View file

@ -0,0 +1,254 @@
# A demo of the Windows CE Remote API
#
# This connects to a CE device, and interacts with it.
import getopt
import os
import sys
import win32api
import win32con
import win32event
import wincerapi
def DumpPythonRegistry():
try:
h = wincerapi.CeRegOpenKeyEx(
win32con.HKEY_LOCAL_MACHINE,
"Software\\Python\\PythonCore\\%s\\PythonPath" % sys.winver,
)
except win32api.error:
print("The remote device does not appear to have Python installed")
return 0
path, typ = wincerapi.CeRegQueryValueEx(h, None)
print("The remote PythonPath is '%s'" % (str(path),))
h.Close()
return 1
def DumpRegistry(root, level=0):
# A recursive dump of the remote registry to test most functions.
h = wincerapi.CeRegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, None)
level_prefix = " " * level
index = 0
# Enumerate values.
while 1:
try:
name, data, typ = wincerapi.CeRegEnumValue(root, index)
except win32api.error:
break
print("%s%s=%s" % (level_prefix, name, repr(str(data))))
index = index + 1
# Now enumerate all keys.
index = 0
while 1:
try:
name, klass = wincerapi.CeRegEnumKeyEx(root, index)
except win32api.error:
break
print("%s%s\\" % (level_prefix, name))
subkey = wincerapi.CeRegOpenKeyEx(root, name)
DumpRegistry(subkey, level + 1)
index = index + 1
def DemoCopyFile():
# Create a file on the device, and write a string.
cefile = wincerapi.CeCreateFile(
"TestPython", win32con.GENERIC_WRITE, 0, None, win32con.OPEN_ALWAYS, 0, None
)
wincerapi.CeWriteFile(cefile, "Hello from Python")
cefile.Close()
# reopen the file and check the data.
cefile = wincerapi.CeCreateFile(
"TestPython", win32con.GENERIC_READ, 0, None, win32con.OPEN_EXISTING, 0, None
)
if wincerapi.CeReadFile(cefile, 100) != "Hello from Python":
print("Couldnt read the data from the device!")
cefile.Close()
# Delete the test file
wincerapi.CeDeleteFile("TestPython")
print("Created, wrote to, read from and deleted a test file!")
def DemoCreateProcess():
try:
hp, ht, pid, tid = wincerapi.CeCreateProcess(
"Windows\\Python.exe", "", None, None, 0, 0, None, "", None
)
# Not necessary, except to see if handle closing raises an exception
# (if auto-closed, the error is suppressed)
hp.Close()
ht.Close()
print("Python is running on the remote device!")
except win32api.error as xxx_todo_changeme1:
(hr, fn, msg) = xxx_todo_changeme1.args
print("Couldnt execute remote process -", msg)
def DumpRemoteMachineStatus():
(
ACLineStatus,
BatteryFlag,
BatteryLifePercent,
BatteryLifeTime,
BatteryFullLifeTime,
BackupBatteryFlag,
BackupBatteryLifePercent,
BackupBatteryLifeTime,
BackupBatteryLifeTime,
) = wincerapi.CeGetSystemPowerStatusEx()
if ACLineStatus:
power = "AC"
else:
power = "battery"
if BatteryLifePercent == 255:
batPerc = "unknown"
else:
batPerc = BatteryLifePercent
print(
"The batteries are at %s%%, and is currently being powered by %s"
% (batPerc, power)
)
(
memLoad,
totalPhys,
availPhys,
totalPage,
availPage,
totalVirt,
availVirt,
) = wincerapi.CeGlobalMemoryStatus()
print("The memory is %d%% utilized." % (memLoad))
print("%-20s%-10s%-10s" % ("", "Total", "Avail"))
print("%-20s%-10s%-10s" % ("Physical Memory", totalPhys, availPhys))
print("%-20s%-10s%-10s" % ("Virtual Memory", totalVirt, availVirt))
print("%-20s%-10s%-10s" % ("Paging file", totalPage, availPage))
storeSize, freeSize = wincerapi.CeGetStoreInformation()
print("%-20s%-10s%-10s" % ("File store", storeSize, freeSize))
print("The CE temp path is", wincerapi.CeGetTempPath())
print("The system info for the device is", wincerapi.CeGetSystemInfo())
def DumpRemoteFolders():
# Dump all special folders possible.
for name, val in list(wincerapi.__dict__.items()):
if name[:6] == "CSIDL_":
try:
loc = str(wincerapi.CeGetSpecialFolderPath(val))
print("Folder %s is at %s" % (name, loc))
except win32api.error as details:
pass
# Get the shortcut targets for the "Start Menu"
print("Dumping start menu shortcuts...")
try:
startMenu = str(wincerapi.CeGetSpecialFolderPath(wincerapi.CSIDL_STARTMENU))
except win32api.error as details:
print("This device has no start menu!", details)
startMenu = None
if startMenu:
for fileAttr in wincerapi.CeFindFiles(os.path.join(startMenu, "*")):
fileName = fileAttr[8]
fullPath = os.path.join(startMenu, str(fileName))
try:
resolved = wincerapi.CeSHGetShortcutTarget(fullPath)
except win32api.error as xxx_todo_changeme:
(rc, fn, msg) = xxx_todo_changeme.args
resolved = "#Error - %s" % msg
print("%s->%s" % (fileName, resolved))
# print "The start menu is at",
# print wincerapi.CeSHGetShortcutTarget("\\Windows\\Start Menu\\Shortcut to Python.exe.lnk")
def usage():
print("Options:")
print("-a - Execute all demos")
print("-p - Execute Python process on remote device")
print("-r - Dump the remote registry")
print("-f - Dump all remote special folder locations")
print("-s - Dont dump machine status")
print("-y - Perform asynch init of CE connection")
def main():
async_init = bStartPython = bDumpRegistry = bDumpFolders = 0
bDumpStatus = 1
try:
opts, args = getopt.getopt(sys.argv[1:], "apr")
except getopt.error as why:
print("Invalid usage:", why)
usage()
return
for o, v in opts:
if o == "-a":
bStartPython = bDumpRegistry = bDumpStatus = bDumpFolders = asynch_init = 1
if o == "-p":
bStartPython = 1
if o == "-r":
bDumpRegistry = 1
if o == "-s":
bDumpStatus = 0
if o == "-f":
bDumpFolders = 1
if o == "-y":
print("Doing asynch init of CE connection")
async_init = 1
if async_init:
event, rc = wincerapi.CeRapiInitEx()
while 1:
rc = win32event.WaitForSingleObject(event, 500)
if rc == win32event.WAIT_OBJECT_0:
# We connected.
break
else:
print(
"Waiting for Initialize to complete (picture a Cancel button here :)"
)
else:
wincerapi.CeRapiInit()
print("Connected to remote CE device.")
try:
verinfo = wincerapi.CeGetVersionEx()
print(
"The device is running windows CE version %d.%d - %s"
% (verinfo[0], verinfo[1], verinfo[4])
)
if bDumpStatus:
print("Dumping remote machine status")
DumpRemoteMachineStatus()
if bDumpRegistry:
print("Dumping remote registry...")
DumpRegistry(win32con.HKEY_LOCAL_MACHINE)
if bDumpFolders:
print("Dumping remote folder information")
DumpRemoteFolders()
DemoCopyFile()
if bStartPython:
print("Starting remote Python process")
if DumpPythonRegistry():
DemoCreateProcess()
else:
print("Not trying to start Python, as it's not installed")
finally:
wincerapi.CeRapiUninit()
print("Disconnected")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,18 @@
# 'Request' example added jjk 11/20/98
import dde
import win32ui
server = dde.CreateServer()
server.Create("TestClient")
conversation = dde.CreateConversation(server)
conversation.ConnectTo("RunAny", "RunAnyCommand")
conversation.Exec("DoSomething")
conversation.Exec("DoSomethingElse")
conversation.ConnectTo("RunAny", "ComputeStringLength")
s = "abcdefghi"
sl = conversation.Request(s)
print('length of "%s" is %s' % (s, sl))

View file

@ -0,0 +1,42 @@
# 'Request' example added jjk 11/20/98
import dde
import win32ui
from pywin.mfc import object
class MySystemTopic(object.Object):
def __init__(self):
object.Object.__init__(self, dde.CreateServerSystemTopic())
def Exec(self, cmd):
print("System Topic asked to exec", cmd)
class MyOtherTopic(object.Object):
def __init__(self, topicName):
object.Object.__init__(self, dde.CreateTopic(topicName))
def Exec(self, cmd):
print("Other Topic asked to exec", cmd)
class MyRequestTopic(object.Object):
def __init__(self, topicName):
topic = dde.CreateTopic(topicName)
topic.AddItem(dde.CreateStringItem(""))
object.Object.__init__(self, topic)
def Request(self, aString):
print("Request Topic asked to compute length of:", aString)
return str(len(aString))
server = dde.CreateServer()
server.AddTopic(MySystemTopic())
server.AddTopic(MyOtherTopic("RunAnyCommand"))
server.AddTopic(MyRequestTopic("ComputeStringLength"))
server.Create("RunAny")
while 1:
win32ui.PumpWaitingMessages(0, -1)

View file

@ -0,0 +1,246 @@
# Demonstrates using a taskbar icon to create and navigate between desktops
import _thread
import io
import time
import traceback
import pywintypes
import win32api
import win32con
import win32gui
import win32process
import win32service
## "Shell_TrayWnd" is class of system tray window, broadcasts "TaskbarCreated" when initialized
def desktop_name_dlgproc(hwnd, msg, wparam, lparam):
"""Handles messages from the desktop name dialog box"""
if msg in (win32con.WM_CLOSE, win32con.WM_DESTROY):
win32gui.DestroyWindow(hwnd)
elif msg == win32con.WM_COMMAND:
if wparam == win32con.IDOK:
desktop_name = win32gui.GetDlgItemText(hwnd, 72)
print("new desktop name: ", desktop_name)
win32gui.DestroyWindow(hwnd)
create_desktop(desktop_name)
elif wparam == win32con.IDCANCEL:
win32gui.DestroyWindow(hwnd)
def get_new_desktop_name(parent_hwnd):
"""Create a dialog box to ask the user for name of desktop to be created"""
msgs = {
win32con.WM_COMMAND: desktop_name_dlgproc,
win32con.WM_CLOSE: desktop_name_dlgproc,
win32con.WM_DESTROY: desktop_name_dlgproc,
}
# dlg item [type, caption, id, (x,y,cx,cy), style, ex style
style = (
win32con.WS_BORDER
| win32con.WS_VISIBLE
| win32con.WS_CAPTION
| win32con.WS_SYSMENU
) ## |win32con.DS_SYSMODAL
h = win32gui.CreateDialogIndirect(
win32api.GetModuleHandle(None),
[
["One ugly dialog box !", (100, 100, 200, 100), style, 0],
[
"Button",
"Create",
win32con.IDOK,
(10, 10, 30, 20),
win32con.WS_VISIBLE
| win32con.WS_TABSTOP
| win32con.BS_HOLLOW
| win32con.BS_DEFPUSHBUTTON,
],
[
"Button",
"Never mind",
win32con.IDCANCEL,
(45, 10, 50, 20),
win32con.WS_VISIBLE | win32con.WS_TABSTOP | win32con.BS_HOLLOW,
],
["Static", "Desktop name:", 71, (10, 40, 70, 10), win32con.WS_VISIBLE],
["Edit", "", 72, (75, 40, 90, 10), win32con.WS_VISIBLE],
],
parent_hwnd,
msgs,
) ## parent_hwnd, msgs)
win32gui.EnableWindow(h, True)
hcontrol = win32gui.GetDlgItem(h, 72)
win32gui.EnableWindow(hcontrol, True)
win32gui.SetFocus(hcontrol)
def new_icon(hdesk, desktop_name):
"""Runs as a thread on each desktop to create a new tray icon and handle its messages"""
global id
id = id + 1
hdesk.SetThreadDesktop()
## apparently the threads can't use same hinst, so each needs its own window class
windowclassname = "PythonDesktopManager" + desktop_name
wc = win32gui.WNDCLASS()
wc.hInstance = win32api.GetModuleHandle(None)
wc.lpszClassName = windowclassname
wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW | win32con.CS_GLOBALCLASS
wc.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)
wc.hbrBackground = win32con.COLOR_WINDOW
wc.lpfnWndProc = icon_wndproc
windowclass = win32gui.RegisterClass(wc)
style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
hwnd = win32gui.CreateWindow(
windowclass,
"dm_" + desktop_name,
win32con.WS_SYSMENU,
0,
0,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
wc.hInstance,
None,
)
win32gui.UpdateWindow(hwnd)
flags = win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP
notify_info = (
hwnd,
id,
flags,
win32con.WM_USER + 20,
hicon,
"Desktop Manager (%s)" % desktop_name,
)
window_info[hwnd] = notify_info
## wait for explorer to initialize system tray for new desktop
tray_found = 0
while not tray_found:
try:
tray_found = win32gui.FindWindow("Shell_TrayWnd", None)
except win32gui.error:
traceback.print_exc
time.sleep(0.5)
win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, notify_info)
win32gui.PumpMessages()
def create_desktop(desktop_name, start_explorer=1):
"""Creates a new desktop and spawns a thread running on it
Will also start a new icon thread on an existing desktop
"""
sa = pywintypes.SECURITY_ATTRIBUTES()
sa.bInheritHandle = 1
try:
hdesk = win32service.CreateDesktop(
desktop_name, 0, win32con.MAXIMUM_ALLOWED, sa
)
except win32service.error:
traceback.print_exc()
errbuf = io.StringIO()
traceback.print_exc(None, errbuf)
win32api.MessageBox(0, errbuf.getvalue(), "Desktop creation failed")
return
if start_explorer:
s = win32process.STARTUPINFO()
s.lpDesktop = desktop_name
prc_info = win32process.CreateProcess(
None,
"Explorer.exe",
None,
None,
True,
win32con.CREATE_NEW_CONSOLE,
None,
"c:\\",
s,
)
th = _thread.start_new_thread(new_icon, (hdesk, desktop_name))
hdesk.SwitchDesktop()
def icon_wndproc(hwnd, msg, wp, lp):
"""Window proc for the tray icons"""
if lp == win32con.WM_LBUTTONDOWN:
## popup menu won't disappear if you don't do this
win32gui.SetForegroundWindow(hwnd)
curr_desktop = win32service.OpenInputDesktop(0, True, win32con.MAXIMUM_ALLOWED)
curr_desktop_name = win32service.GetUserObjectInformation(
curr_desktop, win32con.UOI_NAME
)
winsta = win32service.GetProcessWindowStation()
desktops = winsta.EnumDesktops()
m = win32gui.CreatePopupMenu()
desktop_cnt = len(desktops)
## *don't* create an item 0
for d in range(1, desktop_cnt + 1):
mf_flags = win32con.MF_STRING
## if you switch to winlogon yourself, there's nothing there and you're stuck
if desktops[d - 1].lower() in ("winlogon", "disconnect"):
mf_flags = mf_flags | win32con.MF_GRAYED | win32con.MF_DISABLED
if desktops[d - 1] == curr_desktop_name:
mf_flags = mf_flags | win32con.MF_CHECKED
win32gui.AppendMenu(m, mf_flags, d, desktops[d - 1])
win32gui.AppendMenu(m, win32con.MF_STRING, desktop_cnt + 1, "Create new ...")
win32gui.AppendMenu(m, win32con.MF_STRING, desktop_cnt + 2, "Exit")
x, y = win32gui.GetCursorPos()
d = win32gui.TrackPopupMenu(
m,
win32con.TPM_LEFTBUTTON | win32con.TPM_RETURNCMD | win32con.TPM_NONOTIFY,
x,
y,
0,
hwnd,
None,
)
win32gui.PumpWaitingMessages()
win32gui.DestroyMenu(m)
if d == desktop_cnt + 1: ## Create new
get_new_desktop_name(hwnd)
elif d == desktop_cnt + 2: ## Exit
win32gui.PostQuitMessage(0)
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, window_info[hwnd])
del window_info[hwnd]
origin_desktop.SwitchDesktop()
elif d > 0:
hdesk = win32service.OpenDesktop(
desktops[d - 1], 0, 0, win32con.MAXIMUM_ALLOWED
)
hdesk.SwitchDesktop()
return 0
else:
return win32gui.DefWindowProc(hwnd, msg, wp, lp)
window_info = {}
origin_desktop = win32service.OpenInputDesktop(0, True, win32con.MAXIMUM_ALLOWED)
origin_desktop_name = win32service.GetUserObjectInformation(
origin_desktop, win32service.UOI_NAME
)
hinst = win32api.GetModuleHandle(None)
try:
hicon = win32gui.LoadIcon(hinst, 1) ## python.exe and pythonw.exe
except win32gui.error:
hicon = win32gui.LoadIcon(hinst, 135) ## pythonwin's icon
id = 0
create_desktop(str(origin_desktop_name), 0)
## wait for first thread to initialize its icon
while not window_info:
time.sleep(1)
## exit when last tray icon goes away
while window_info:
win32gui.PumpWaitingMessages()
time.sleep(3)

View file

@ -0,0 +1,142 @@
import win32api # To translate NT Sids to account names.
import win32con
import win32evtlog
import win32evtlogutil
import win32security
def ReadLog(computer, logType="Application", dumpEachRecord=0):
# read the entire log back.
h = win32evtlog.OpenEventLog(computer, logType)
numRecords = win32evtlog.GetNumberOfEventLogRecords(h)
# print "There are %d records" % numRecords
num = 0
while 1:
objects = win32evtlog.ReadEventLog(
h,
win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ,
0,
)
if not objects:
break
for object in objects:
# get it for testing purposes, but dont print it.
msg = win32evtlogutil.SafeFormatMessage(object, logType)
if object.Sid is not None:
try:
domain, user, typ = win32security.LookupAccountSid(
computer, object.Sid
)
sidDesc = "%s/%s" % (domain, user)
except win32security.error:
sidDesc = str(object.Sid)
user_desc = "Event associated with user %s" % (sidDesc,)
else:
user_desc = None
if dumpEachRecord:
print(
"Event record from %r generated at %s"
% (object.SourceName, object.TimeGenerated.Format())
)
if user_desc:
print(user_desc)
try:
print(msg)
except UnicodeError:
print("(unicode error printing message: repr() follows...)")
print(repr(msg))
num = num + len(objects)
if numRecords == num:
print("Successfully read all", numRecords, "records")
else:
print(
"Couldn't get all records - reported %d, but found %d" % (numRecords, num)
)
print(
"(Note that some other app may have written records while we were running!)"
)
win32evtlog.CloseEventLog(h)
def usage():
print("Writes an event to the event log.")
print("-w : Dont write any test records.")
print("-r : Dont read the event log")
print("-c : computerName : Process the log on the specified computer")
print("-v : Verbose")
print("-t : LogType - Use the specified log - default = 'Application'")
def test():
# check if running on Windows NT, if not, display notice and terminate
if win32api.GetVersion() & 0x80000000:
print("This sample only runs on NT")
return
import getopt
import sys
opts, args = getopt.getopt(sys.argv[1:], "rwh?c:t:v")
computer = None
do_read = do_write = 1
logType = "Application"
verbose = 0
if len(args) > 0:
print("Invalid args")
usage()
return 1
for opt, val in opts:
if opt == "-t":
logType = val
if opt == "-c":
computer = val
if opt in ["-h", "-?"]:
usage()
return
if opt == "-r":
do_read = 0
if opt == "-w":
do_write = 0
if opt == "-v":
verbose = verbose + 1
if do_write:
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(ph, win32con.TOKEN_READ)
my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
win32evtlogutil.ReportEvent(
logType,
2,
strings=["The message text for event 2", "Another insert"],
data="Raw\0Data".encode("ascii"),
sid=my_sid,
)
win32evtlogutil.ReportEvent(
logType,
1,
eventType=win32evtlog.EVENTLOG_WARNING_TYPE,
strings=["A warning", "An even more dire warning"],
data="Raw\0Data".encode("ascii"),
sid=my_sid,
)
win32evtlogutil.ReportEvent(
logType,
1,
eventType=win32evtlog.EVENTLOG_INFORMATION_TYPE,
strings=["An info", "Too much info"],
data="Raw\0Data".encode("ascii"),
sid=my_sid,
)
print("Successfully wrote 3 records to the log")
if do_read:
ReadLog(computer, logType, verbose > 0)
if __name__ == "__main__":
test()

View file

@ -0,0 +1,33 @@
import os
import win32api
ver_strings = (
"Comments",
"InternalName",
"ProductName",
"CompanyName",
"LegalCopyright",
"ProductVersion",
"FileDescription",
"LegalTrademarks",
"PrivateBuild",
"FileVersion",
"OriginalFilename",
"SpecialBuild",
)
fname = os.environ["comspec"]
d = win32api.GetFileVersionInfo(fname, "\\")
## backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc
for n, v in d.items():
print(n, v)
pairs = win32api.GetFileVersionInfo(fname, "\\VarFileInfo\\Translation")
## \VarFileInfo\Translation returns list of available (language, codepage) pairs that can be used to retreive string info
## any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle two are language/codepage pair returned from above
for lang, codepage in pairs:
print("lang: ", lang, "codepage:", codepage)
for ver_string in ver_strings:
str_info = "\\StringFileInfo\\%04X%04X\\%s" % (lang, codepage, ver_string)
## print str_info
print(ver_string, repr(win32api.GetFileVersionInfo(fname, str_info)))

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -0,0 +1,102 @@
import os
import tempfile
import mmapfile
import win32api
import winerror
from pywin32_testutil import str2bytes
system_info = win32api.GetSystemInfo()
page_size = system_info[1]
alloc_size = system_info[7]
fname = tempfile.mktemp()
mapping_name = os.path.split(fname)[1]
fsize = 8 * page_size
print(fname, fsize, mapping_name)
m1 = mmapfile.mmapfile(File=fname, Name=mapping_name, MaximumSize=fsize)
m1.seek(100)
m1.write_byte(str2bytes("?"))
m1.seek(-1, 1)
assert m1.read_byte() == str2bytes("?")
## A reopened named mapping should have exact same size as original mapping
m2 = mmapfile.mmapfile(Name=mapping_name, File=None, MaximumSize=fsize * 2)
assert m2.size() == m1.size()
m1.seek(0, 0)
m1.write(fsize * str2bytes("s"))
assert m2.read(fsize) == fsize * str2bytes("s")
move_src = 100
move_dest = 500
move_size = 150
m2.seek(move_src, 0)
assert m2.tell() == move_src
m2.write(str2bytes("m") * move_size)
m2.move(move_dest, move_src, move_size)
m2.seek(move_dest, 0)
assert m2.read(move_size) == str2bytes("m") * move_size
## m2.write('x'* (fsize+1))
m2.close()
m1.resize(fsize * 2)
assert m1.size() == fsize * 2
m1.seek(fsize)
m1.write(str2bytes("w") * fsize)
m1.flush()
m1.close()
os.remove(fname)
## Test a file with size larger than 32 bits
## need 10 GB free on drive where your temp folder lives
fname_large = tempfile.mktemp()
mapping_name = "Pywin32_large_mmap"
offsetdata = str2bytes("This is start of offset")
## Deliberately use odd numbers to test rounding logic
fsize = (1024 * 1024 * 1024 * 10) + 333
offset = (1024 * 1024 * 32) + 42
view_size = (1024 * 1024 * 16) + 111
## round mapping size and view size up to multiple of system page size
if fsize % page_size:
fsize += page_size - (fsize % page_size)
if view_size % page_size:
view_size += page_size - (view_size % page_size)
## round offset down to multiple of allocation granularity
offset -= offset % alloc_size
m1 = None
m2 = None
try:
try:
m1 = mmapfile.mmapfile(fname_large, mapping_name, fsize, 0, offset * 2)
except mmapfile.error as exc:
# if we don't have enough disk-space, that's OK.
if exc.winerror != winerror.ERROR_DISK_FULL:
raise
print("skipping large file test - need", fsize, "available bytes.")
else:
m1.seek(offset)
m1.write(offsetdata)
## When reopening an existing mapping without passing a file handle, you have
## to specify a positive size even though it's ignored
m2 = mmapfile.mmapfile(
File=None,
Name=mapping_name,
MaximumSize=1,
FileOffset=offset,
NumberOfBytesToMap=view_size,
)
assert m2.read(len(offsetdata)) == offsetdata
finally:
if m1 is not None:
m1.close()
if m2 is not None:
m2.close()
if os.path.exists(fname_large):
os.remove(fname_large)

View file

@ -0,0 +1,17 @@
"""cat.py
a version of unix cat, tweaked to show off runproc.py
"""
import sys
data = sys.stdin.read(1)
sys.stdout.write(data)
sys.stdout.flush()
while data:
data = sys.stdin.read(1)
sys.stdout.write(data)
sys.stdout.flush()
# Just here to have something to read from stderr.
sys.stderr.write("Blah...")
# end of cat.py

View file

@ -0,0 +1,114 @@
"""runproc.py
start a process with three inherited pipes.
Try to write to and read from those.
"""
import msvcrt
import os
import win32api
import win32con
import win32file
import win32pipe
import win32process
import win32security
class Process:
def run(self, cmdline):
# security attributes for pipes
sAttrs = win32security.SECURITY_ATTRIBUTES()
sAttrs.bInheritHandle = 1
# create pipes
hStdin_r, self.hStdin_w = win32pipe.CreatePipe(sAttrs, 0)
self.hStdout_r, hStdout_w = win32pipe.CreatePipe(sAttrs, 0)
self.hStderr_r, hStderr_w = win32pipe.CreatePipe(sAttrs, 0)
# set the info structure for the new process.
StartupInfo = win32process.STARTUPINFO()
StartupInfo.hStdInput = hStdin_r
StartupInfo.hStdOutput = hStdout_w
StartupInfo.hStdError = hStderr_w
StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES
# Mark doesn't support wShowWindow yet.
# StartupInfo.dwFlags = StartupInfo.dwFlags | win32process.STARTF_USESHOWWINDOW
# StartupInfo.wShowWindow = win32con.SW_HIDE
# Create new output read handles and the input write handle. Set
# the inheritance properties to FALSE. Otherwise, the child inherits
# the these handles; resulting in non-closeable handles to the pipes
# being created.
pid = win32api.GetCurrentProcess()
tmp = win32api.DuplicateHandle(
pid,
self.hStdin_w,
pid,
0,
0, # non-inheritable!!
win32con.DUPLICATE_SAME_ACCESS,
)
# Close the inhertible version of the handle
win32file.CloseHandle(self.hStdin_w)
self.hStdin_w = tmp
tmp = win32api.DuplicateHandle(
pid,
self.hStdout_r,
pid,
0,
0, # non-inheritable!
win32con.DUPLICATE_SAME_ACCESS,
)
# Close the inhertible version of the handle
win32file.CloseHandle(self.hStdout_r)
self.hStdout_r = tmp
# start the process.
hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(
None, # program
cmdline, # command line
None, # process security attributes
None, # thread attributes
1, # inherit handles, or USESTDHANDLES won't work.
# creation flags. Don't access the console.
0, # Don't need anything here.
# If you're in a GUI app, you should use
# CREATE_NEW_CONSOLE here, or any subprocesses
# might fall victim to the problem described in:
# KB article: Q156755, cmd.exe requires
# an NT console in order to perform redirection..
None, # no new environment
None, # current directory (stay where we are)
StartupInfo,
)
# normally, we would save the pid etc. here...
# Child is launched. Close the parents copy of those pipe handles
# that only the child should have open.
# You need to make sure that no handles to the write end of the
# output pipe are maintained in this process or else the pipe will
# not close when the child process exits and the ReadFile will hang.
win32file.CloseHandle(hStderr_w)
win32file.CloseHandle(hStdout_w)
win32file.CloseHandle(hStdin_r)
self.stdin = os.fdopen(msvcrt.open_osfhandle(self.hStdin_w, 0), "wb")
self.stdin.write("hmmmmm\r\n")
self.stdin.flush()
self.stdin.close()
self.stdout = os.fdopen(msvcrt.open_osfhandle(self.hStdout_r, 0), "rb")
print("Read on stdout: ", repr(self.stdout.read()))
self.stderr = os.fdopen(msvcrt.open_osfhandle(self.hStderr_r, 0), "rb")
print("Read on stderr: ", repr(self.stderr.read()))
if __name__ == "__main__":
p = Process()
exe = win32api.GetModuleFileName(0)
p.run(exe + " cat.py")
# end of runproc.py

View file

@ -0,0 +1,113 @@
import pywintypes
import win32api
import win32con
import win32gui
import win32print
pname = win32print.GetDefaultPrinter()
print(pname)
p = win32print.OpenPrinter(pname)
print("Printer handle: ", p)
print_processor = win32print.GetPrinter(p, 2)["pPrintProcessor"]
## call with last parm set to 0 to get total size needed for printer's DEVMODE
dmsize = win32print.DocumentProperties(0, p, pname, None, None, 0)
## dmDriverExtra should be total size - fixed size
driverextra = (
dmsize - pywintypes.DEVMODEType().Size
) ## need a better way to get DEVMODE.dmSize
dm = pywintypes.DEVMODEType(driverextra)
dm.Fields = dm.Fields | win32con.DM_ORIENTATION | win32con.DM_COPIES
dm.Orientation = win32con.DMORIENT_LANDSCAPE
dm.Copies = 2
win32print.DocumentProperties(
0, p, pname, dm, dm, win32con.DM_IN_BUFFER | win32con.DM_OUT_BUFFER
)
pDC = win32gui.CreateDC(print_processor, pname, dm)
printerwidth = win32print.GetDeviceCaps(pDC, win32con.PHYSICALWIDTH)
printerheight = win32print.GetDeviceCaps(pDC, win32con.PHYSICALHEIGHT)
hwnd = win32gui.GetDesktopWindow()
l, t, r, b = win32gui.GetWindowRect(hwnd)
desktopheight = b - t
desktopwidth = r - l
dDC = win32gui.GetWindowDC(hwnd)
dcDC = win32gui.CreateCompatibleDC(dDC)
dcBM = win32gui.CreateCompatibleBitmap(dDC, desktopwidth, desktopheight)
win32gui.SelectObject(dcDC, dcBM)
win32gui.StretchBlt(
dcDC,
0,
0,
desktopwidth,
desktopheight,
dDC,
0,
0,
desktopwidth,
desktopheight,
win32con.SRCCOPY,
)
pcDC = win32gui.CreateCompatibleDC(pDC)
pcBM = win32gui.CreateCompatibleBitmap(pDC, printerwidth, printerheight)
win32gui.SelectObject(pcDC, pcBM)
win32gui.StretchBlt(
pcDC,
0,
0,
printerwidth,
printerheight,
dcDC,
0,
0,
desktopwidth,
desktopheight,
win32con.SRCCOPY,
)
win32print.StartDoc(pDC, ("desktop.bmp", None, None, 0))
win32print.StartPage(pDC)
win32gui.StretchBlt(
pDC,
0,
0,
int(printerwidth * 0.9),
int(printerheight * 0.9),
pcDC,
0,
0,
printerwidth,
printerheight,
win32con.SRCCOPY,
)
font = win32gui.LOGFONT()
font.lfHeight = int(printerheight / 20)
font.lfWidth = font.lfHeight
font.lfWeight = 150
font.lfItalic = 1
font.lfUnderline = 1
hf = win32gui.CreateFontIndirect(font)
win32gui.SelectObject(pDC, hf)
win32gui.SetBkMode(pDC, win32con.TRANSPARENT)
win32gui.SetTextColor(pDC, win32api.RGB(0, 255, 0))
win32gui.DrawText(
pDC,
"Printed by Python!",
-1,
(0, 0, int(printerwidth * 0.9), int(printerheight * 0.9)),
win32con.DT_RIGHT | win32con.DT_BOTTOM | win32con.DT_SINGLELINE,
)
win32print.EndPage(pDC)
win32print.EndDoc(pDC)
win32print.ClosePrinter(p)
win32gui.DeleteObject(dcBM)
win32gui.DeleteObject(pcBM)
win32gui.DeleteObject(hf)
win32gui.DeleteDC(dDC)
win32gui.DeleteDC(dcDC)
win32gui.DeleteDC(pDC)
win32gui.DeleteDC(pcDC)

168
lib/win32/Demos/rastest.py Normal file
View file

@ -0,0 +1,168 @@
# rastest.py - test/demonstrate the win32ras module.
# Much of the code here contributed by Jethro Wright.
import os
import sys
import win32ras
# Build a little dictionary of RAS states to decent strings.
# eg win32ras.RASCS_OpenPort -> "OpenPort"
stateMap = {}
for name, val in list(win32ras.__dict__.items()):
if name[:6] == "RASCS_":
stateMap[val] = name[6:]
# Use a lock so the callback can tell the main thread when it is finished.
import win32event
callbackEvent = win32event.CreateEvent(None, 0, 0, None)
def Callback(hras, msg, state, error, exterror):
# print "Callback called with ", hras, msg, state, error, exterror
stateName = stateMap.get(state, "Unknown state?")
print("Status is %s (%04lx), error code is %d" % (stateName, state, error))
finished = state in [win32ras.RASCS_Connected]
if finished:
win32event.SetEvent(callbackEvent)
if error != 0 or int(state) == win32ras.RASCS_Disconnected:
# we know for sure this is a good place to hangup....
print("Detected call failure: %s" % win32ras.GetErrorString(error))
HangUp(hras)
win32event.SetEvent(callbackEvent)
def ShowConnections():
print("All phone-book entries:")
for (name,) in win32ras.EnumEntries():
print(" ", name)
print("Current Connections:")
for con in win32ras.EnumConnections():
print(" ", con)
def EditEntry(entryName):
try:
win32ras.EditPhonebookEntry(0, None, entryName)
except win32ras.error as xxx_todo_changeme:
(rc, function, msg) = xxx_todo_changeme.args
print("Can not edit/find the RAS entry -", msg)
def HangUp(hras):
# trap potential, irrelevant errors from win32ras....
try:
win32ras.HangUp(hras)
except:
print("Tried to hang up gracefully on error, but didn't work....")
return None
def Connect(entryName, bUseCallback):
if bUseCallback:
theCallback = Callback
win32event.ResetEvent(callbackEvent)
else:
theCallback = None
# in order to *use* the username/password of a particular dun entry, one must
# explicitly get those params under win95....
try:
dp, b = win32ras.GetEntryDialParams(None, entryName)
except:
print("Couldn't find DUN entry: %s" % entryName)
else:
hras, rc = win32ras.Dial(
None, None, (entryName, "", "", dp[3], dp[4], ""), theCallback
)
# hras, rc = win32ras.Dial(None, None, (entryName, ),theCallback)
# print hras, rc
if not bUseCallback and rc != 0:
print("Could not dial the RAS connection:", win32ras.GetErrorString(rc))
hras = HangUp(hras)
# don't wait here if there's no need to....
elif (
bUseCallback
and win32event.WaitForSingleObject(callbackEvent, 60000)
!= win32event.WAIT_OBJECT_0
):
print("Gave up waiting for the process to complete!")
# sdk docs state one must explcitly hangup, even if there's an error....
try:
cs = win32ras.GetConnectStatus(hras)
except:
# on error, attempt a hang up anyway....
hras = HangUp(hras)
else:
if int(cs[0]) == win32ras.RASCS_Disconnected:
hras = HangUp(hras)
return hras, rc
def Disconnect(rasEntry):
# Need to find the entry
name = rasEntry.lower()
for hcon, entryName, devName, devType in win32ras.EnumConnections():
if entryName.lower() == name:
win32ras.HangUp(hcon)
print("Disconnected from", rasEntry)
break
else:
print("Could not find an open connection to", entryName)
usage = """
Usage: %s [-s] [-l] [-c connection] [-d connection]
-l : List phone-book entries and current connections.
-s : Show status while connecting/disconnecting (uses callbacks)
-c : Connect to the specified phonebook name.
-d : Disconnect from the specified phonebook name.
-e : Edit the specified phonebook entry.
"""
def main():
import getopt
try:
opts, args = getopt.getopt(sys.argv[1:], "slc:d:e:")
except getopt.error as why:
print(why)
print(
usage
% (
os.path.basename(
sys.argv[0],
)
)
)
return
bCallback = 0
if args or not opts:
print(
usage
% (
os.path.basename(
sys.argv[0],
)
)
)
return
for opt, val in opts:
if opt == "-s":
bCallback = 1
if opt == "-l":
ShowConnections()
if opt == "-c":
hras, rc = Connect(val, bCallback)
if hras != None:
print("hras: 0x%8lx, rc: 0x%04x" % (hras, rc))
if opt == "-d":
Disconnect(val)
if opt == "-e":
EditEntry(val)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,110 @@
""" Lists various types of information about current user's access token,
including UAC status on Vista
"""
import pywintypes
import win32api
import win32con
import win32security
import winerror
from security_enums import (
SECURITY_IMPERSONATION_LEVEL,
TOKEN_ELEVATION_TYPE,
TOKEN_GROUP_ATTRIBUTES,
TOKEN_PRIVILEGE_ATTRIBUTES,
TOKEN_TYPE,
)
def dump_token(th):
token_type = win32security.GetTokenInformation(th, win32security.TokenType)
print("TokenType:", token_type, TOKEN_TYPE.lookup_name(token_type))
if token_type == win32security.TokenImpersonation:
imp_lvl = win32security.GetTokenInformation(
th, win32security.TokenImpersonationLevel
)
print(
"TokenImpersonationLevel:",
imp_lvl,
SECURITY_IMPERSONATION_LEVEL.lookup_name(imp_lvl),
)
print(
"TokenSessionId:",
win32security.GetTokenInformation(th, win32security.TokenSessionId),
)
privs = win32security.GetTokenInformation(th, win32security.TokenPrivileges)
print("TokenPrivileges:")
for priv_luid, priv_flags in privs:
flag_names, unk = TOKEN_PRIVILEGE_ATTRIBUTES.lookup_flags(priv_flags)
flag_desc = " ".join(flag_names)
if unk:
flag_desc += "(" + str(unk) + ")"
priv_name = win32security.LookupPrivilegeName("", priv_luid)
priv_desc = win32security.LookupPrivilegeDisplayName("", priv_name)
print("\t", priv_name, priv_desc, priv_flags, flag_desc)
print("TokenGroups:")
groups = win32security.GetTokenInformation(th, win32security.TokenGroups)
for group_sid, group_attr in groups:
flag_names, unk = TOKEN_GROUP_ATTRIBUTES.lookup_flags(group_attr)
flag_desc = " ".join(flag_names)
if unk:
flag_desc += "(" + str(unk) + ")"
if group_attr & TOKEN_GROUP_ATTRIBUTES.SE_GROUP_LOGON_ID:
sid_desc = "Logon sid"
else:
sid_desc = win32security.LookupAccountSid("", group_sid)
print("\t", group_sid, sid_desc, group_attr, flag_desc)
## Vista token information types, will throw (87, 'GetTokenInformation', 'The parameter is incorrect.') on earier OS
try:
is_elevated = win32security.GetTokenInformation(
th, win32security.TokenElevation
)
print("TokenElevation:", is_elevated)
except pywintypes.error as details:
if details.winerror != winerror.ERROR_INVALID_PARAMETER:
raise
return None
print(
"TokenHasRestrictions:",
win32security.GetTokenInformation(th, win32security.TokenHasRestrictions),
)
print(
"TokenMandatoryPolicy",
win32security.GetTokenInformation(th, win32security.TokenMandatoryPolicy),
)
print(
"TokenVirtualizationAllowed:",
win32security.GetTokenInformation(th, win32security.TokenVirtualizationAllowed),
)
print(
"TokenVirtualizationEnabled:",
win32security.GetTokenInformation(th, win32security.TokenVirtualizationEnabled),
)
elevation_type = win32security.GetTokenInformation(
th, win32security.TokenElevationType
)
print(
"TokenElevationType:",
elevation_type,
TOKEN_ELEVATION_TYPE.lookup_name(elevation_type),
)
if elevation_type != win32security.TokenElevationTypeDefault:
lt = win32security.GetTokenInformation(th, win32security.TokenLinkedToken)
print("TokenLinkedToken:", lt)
else:
lt = None
return lt
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(ph, win32con.MAXIMUM_ALLOWED)
lt = dump_token(th)
if lt:
print("\n\nlinked token info:")
dump_token(lt)

View file

@ -0,0 +1,51 @@
import ntsecuritycon
import win32api
import win32con
import win32file
import win32security
from security_enums import ACCESS_MODE, ACE_FLAGS, TRUSTEE_FORM, TRUSTEE_TYPE
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", "SeEnableDelegationPrivilege"),
win32con.SE_PRIVILEGE_ENABLED,
), ##doesn't seem to be in ntsecuritycon.py ?
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
policy_handle = win32security.GetPolicyHandle("", win32security.POLICY_ALL_ACCESS)
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
privs = [
ntsecuritycon.SE_DEBUG_NAME,
ntsecuritycon.SE_TCB_NAME,
ntsecuritycon.SE_RESTORE_NAME,
ntsecuritycon.SE_REMOTE_SHUTDOWN_NAME,
]
win32security.LsaAddAccountRights(policy_handle, tmp_sid, privs)
privlist = win32security.LsaEnumerateAccountRights(policy_handle, tmp_sid)
for priv in privlist:
print(priv)
privs = [ntsecuritycon.SE_DEBUG_NAME, ntsecuritycon.SE_TCB_NAME]
win32security.LsaRemoveAccountRights(policy_handle, tmp_sid, 0, privs)
privlist = win32security.LsaEnumerateAccountRights(policy_handle, tmp_sid)
for priv in privlist:
print(priv)
win32security.LsaClose(policy_handle)

View file

@ -0,0 +1,171 @@
import os
import ntsecuritycon
import win32api
import win32con
import win32file
import win32security
from security_enums import ACCESS_MODE, ACE_FLAGS, TRUSTEE_FORM, TRUSTEE_TYPE
fname = os.path.join(win32api.GetTempPath(), "win32security_test.txt")
f = open(fname, "w")
f.write("Hello from Python\n")
f.close()
print("Testing on file", fname)
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", "SeEnableDelegationPrivilege"),
win32con.SE_PRIVILEGE_ENABLED,
), ##doesn't seem to be in ntsecuritycon.py ?
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
all_security_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
sd = win32security.GetFileSecurity(fname, all_security_info)
old_sacl = sd.GetSecurityDescriptorSacl()
if old_sacl == None:
old_sacl = win32security.ACL()
old_dacl = sd.GetSecurityDescriptorDacl()
if old_dacl == None:
old_dacl = win32security.ACL()
my_sid = win32security.GetTokenInformation(th, ntsecuritycon.TokenUser)[0]
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
## MultipleTrustee,MultipleTrusteeOperation,TrusteeForm,TrusteeType,Identifier
## first two are ignored
my_trustee = {}
my_trustee["MultipleTrustee"] = None
my_trustee["MultipleTrusteeOperation"] = 0
my_trustee["TrusteeForm"] = TRUSTEE_FORM.TRUSTEE_IS_SID
my_trustee["TrusteeType"] = TRUSTEE_TYPE.TRUSTEE_IS_USER
my_trustee["Identifier"] = my_sid
tmp_trustee = {}
tmp_trustee["MultipleTrustee"] = None
tmp_trustee["MultipleTrusteeOperation"] = 0
tmp_trustee["TrusteeForm"] = TRUSTEE_FORM.TRUSTEE_IS_NAME
tmp_trustee["TrusteeType"] = TRUSTEE_TYPE.TRUSTEE_IS_USER
tmp_trustee["Identifier"] = "rupole\\tmp"
pwr_trustee = {}
pwr_trustee["MultipleTrustee"] = None
pwr_trustee["MultipleTrusteeOperation"] = 0
pwr_trustee["TrusteeForm"] = TRUSTEE_FORM.TRUSTEE_IS_SID
pwr_trustee["TrusteeType"] = TRUSTEE_TYPE.TRUSTEE_IS_USER
pwr_trustee["Identifier"] = pwr_sid
expl_list = []
expl_list.append(
{
"Trustee": my_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.SET_AUDIT_SUCCESS, ##|ACCESS_MODE.SET_AUDIT_FAILURE,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
expl_list.append(
{
"Trustee": my_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.SET_AUDIT_FAILURE,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
expl_list.append(
{
"Trustee": tmp_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.SET_AUDIT_SUCCESS,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
expl_list.append(
{
"Trustee": tmp_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.SET_AUDIT_FAILURE,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
old_sacl.SetEntriesInAcl(expl_list)
expl_list = []
expl_list.append(
{
"Trustee": tmp_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.DENY_ACCESS,
"AccessPermissions": win32con.DELETE,
}
)
expl_list.append(
{
"Trustee": tmp_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.GRANT_ACCESS,
"AccessPermissions": win32con.WRITE_OWNER,
}
)
expl_list.append(
{
"Trustee": pwr_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.GRANT_ACCESS,
"AccessPermissions": win32con.GENERIC_READ,
}
)
expl_list.append(
{
"Trustee": my_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.GRANT_ACCESS,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
old_dacl.SetEntriesInAcl(expl_list)
sd.SetSecurityDescriptorSacl(1, old_sacl, 1)
sd.SetSecurityDescriptorDacl(1, old_dacl, 1)
sd.SetSecurityDescriptorOwner(pwr_sid, 1)
win32security.SetFileSecurity(fname, all_security_info, sd)

View file

@ -0,0 +1,42 @@
import ntsecuritycon
import win32api
import win32file
import win32security
policy_handle = win32security.GetPolicyHandle("rupole", win32security.POLICY_ALL_ACCESS)
## mod_nbr, mod_time = win32security.LsaQueryInformationPolicy(policy_handle,win32security.PolicyModificationInformation)
## print mod_nbr, mod_time
(
domain_name,
dns_domain_name,
dns_forest_name,
domain_guid,
domain_sid,
) = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyDnsDomainInformation
)
print(domain_name, dns_domain_name, dns_forest_name, domain_guid, domain_sid)
event_audit_info = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyAuditEventsInformation
)
print(event_audit_info)
domain_name, sid = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyPrimaryDomainInformation
)
print(domain_name, sid)
domain_name, sid = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyAccountDomainInformation
)
print(domain_name, sid)
server_role = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyLsaServerRoleInformation
)
print("server role: ", server_role)
win32security.LsaClose(policy_handle)

View file

@ -0,0 +1,37 @@
import ntsecuritycon
import win32api
import win32con
import win32file
import win32security
from security_enums import ACCESS_MODE, ACE_FLAGS, TRUSTEE_FORM, TRUSTEE_TYPE
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", "SeEnableDelegationPrivilege"),
win32con.SE_PRIVILEGE_ENABLED,
), ##doesn't seem to be in ntsecuritycon.py ?
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
policy_handle = win32security.GetPolicyHandle("", win32security.POLICY_ALL_ACCESS)
sidlist = win32security.LsaEnumerateAccountsWithUserRight(
policy_handle, ntsecuritycon.SE_RESTORE_NAME
)
for sid in sidlist:
print(win32security.LookupAccountSid("", sid))
win32security.LsaClose(policy_handle)

View file

@ -0,0 +1,65 @@
# A Python port of the MS knowledge base article Q157234
# "How to deal with localized and renamed user and group names"
# http://support.microsoft.com/default.aspx?kbid=157234
import sys
import pywintypes
from ntsecuritycon import *
from win32net import NetUserModalsGet
from win32security import LookupAccountSid
def LookupAliasFromRid(TargetComputer, Rid):
# Sid is the same regardless of machine, since the well-known
# BUILTIN domain is referenced.
sid = pywintypes.SID()
sid.Initialize(SECURITY_NT_AUTHORITY, 2)
for i, r in enumerate((SECURITY_BUILTIN_DOMAIN_RID, Rid)):
sid.SetSubAuthority(i, r)
name, domain, typ = LookupAccountSid(TargetComputer, sid)
return name
def LookupUserGroupFromRid(TargetComputer, Rid):
# get the account domain Sid on the target machine
# note: if you were looking up multiple sids based on the same
# account domain, only need to call this once.
umi2 = NetUserModalsGet(TargetComputer, 2)
domain_sid = umi2["domain_id"]
SubAuthorityCount = domain_sid.GetSubAuthorityCount()
# create and init new sid with acct domain Sid + acct Rid
sid = pywintypes.SID()
sid.Initialize(domain_sid.GetSidIdentifierAuthority(), SubAuthorityCount + 1)
# copy existing subauthorities from account domain Sid into
# new Sid
for i in range(SubAuthorityCount):
sid.SetSubAuthority(i, domain_sid.GetSubAuthority(i))
# append Rid to new Sid
sid.SetSubAuthority(SubAuthorityCount, Rid)
name, domain, typ = LookupAccountSid(TargetComputer, sid)
return name
def main():
if len(sys.argv) == 2:
targetComputer = sys.argv[1]
else:
targetComputer = None
name = LookupUserGroupFromRid(targetComputer, DOMAIN_USER_RID_ADMIN)
print("'Administrator' user name = %s" % (name,))
name = LookupAliasFromRid(targetComputer, DOMAIN_ALIAS_RID_ADMINS)
print("'Administrators' local group/alias name = %s" % (name,))
if __name__ == "__main__":
main()

View file

@ -0,0 +1,14 @@
import win32event
import win32security
evt = win32event.CreateEvent(None, 0, 0, None)
win32security.LsaRegisterPolicyChangeNotification(
win32security.PolicyNotifyAuditEventsInformation, evt
)
print("Waiting for you change Audit policy in Management console ...")
ret_code = win32event.WaitForSingleObject(evt, 1000000000)
## should come back when you change Audit policy in Management console ...
print(ret_code)
win32security.LsaUnregisterPolicyChangeNotification(
win32security.PolicyNotifyAuditEventsInformation, evt
)

View file

@ -0,0 +1,12 @@
import win32security
policy_handle = win32security.GetPolicyHandle("", win32security.POLICY_ALL_ACCESS)
privatedata = "some sensitive data"
keyname = "tmp"
win32security.LsaStorePrivateData(policy_handle, keyname, privatedata)
retrieveddata = win32security.LsaRetrievePrivateData(policy_handle, keyname)
assert retrieveddata == privatedata
## passing None deletes key
win32security.LsaStorePrivateData(policy_handle, keyname, None)
win32security.LsaClose(policy_handle)

View file

@ -0,0 +1,25 @@
import win32api
import win32security
import winerror
from ntsecuritycon import *
# This is a Python implementation of win32api.GetDomainName()
def GetDomainName():
try:
tok = win32security.OpenThreadToken(win32api.GetCurrentThread(), TOKEN_QUERY, 1)
except win32api.error as details:
if details[0] != winerror.ERROR_NO_TOKEN:
raise
# attempt to open the process token, since no thread token
# exists
tok = win32security.OpenProcessToken(win32api.GetCurrentProcess(), TOKEN_QUERY)
sid, attr = win32security.GetTokenInformation(tok, TokenUser)
win32api.CloseHandle(tok)
name, dom, typ = win32security.LookupAccountSid(None, sid)
return dom
if __name__ == "__main__":
print("Domain name is", GetDomainName())

View file

@ -0,0 +1,61 @@
fname = "h:\\tmp.reg"
import os
import ntsecuritycon
import pywintypes
import win32api
import win32con
import win32security
## regsave will not overwrite a file
if os.path.isfile(fname):
os.remove(fname)
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_BACKUP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS | win32con.TOKEN_ADJUST_PRIVILEGES
)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
my_sid = win32security.GetTokenInformation(th, ntsecuritycon.TokenUser)[0]
hklm = win32api.RegOpenKey(
win32con.HKEY_LOCAL_MACHINE, None, 0, win32con.KEY_ALL_ACCESS
)
skey = win32api.RegOpenKey(hklm, "SYSTEM", 0, win32con.KEY_ALL_ACCESS)
sa = pywintypes.SECURITY_ATTRIBUTES()
sd = pywintypes.SECURITY_DESCRIPTOR()
sa.SECURITY_DESCRIPTOR = sd
acl = pywintypes.ACL()
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
acl.AddAccessAllowedAce(
win32con.ACL_REVISION,
win32con.GENERIC_READ | win32con.ACCESS_SYSTEM_SECURITY,
my_sid,
)
sd.SetSecurityDescriptorDacl(1, acl, 0)
sd.SetSecurityDescriptorOwner(pwr_sid, 0)
sa.bInheritHandle = 1
assert sa.SECURITY_DESCRIPTOR is sd
win32api.RegSaveKey(skey, fname, sa)

View file

@ -0,0 +1,36 @@
import ntsecuritycon
import win32api
import win32con
import win32security
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS | win32con.TOKEN_ADJUST_PRIVILEGES
)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
hkey = win32api.RegOpenKey(
win32con.HKEY_LOCAL_MACHINE, None, 0, win32con.KEY_ALL_ACCESS
)
win32api.RegCreateKey(hkey, "SYSTEM\\NOTMP")
notmpkey = win32api.RegOpenKey(
hkey, "SYSTEM\\notmp", 0, win32con.ACCESS_SYSTEM_SECURITY
)
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
sacl = win32security.ACL()
sacl.AddAuditAccessAce(win32security.ACL_REVISION, win32con.GENERIC_ALL, tmp_sid, 1, 1)
sd = win32security.SECURITY_DESCRIPTOR()
sd.SetSecurityDescriptorSacl(1, sacl, 1)
win32api.RegSetKeySecurity(notmpkey, win32con.SACL_SECURITY_INFORMATION, sd)

View file

@ -0,0 +1,8 @@
import pywintypes
import win32security
sa = pywintypes.SECURITY_ATTRIBUTES()
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
sa.SetSecurityDescriptorOwner(tmp_sid, 0)
sid = sa.SECURITY_DESCRIPTOR.GetSecurityDescriptorOwner()
print(win32security.LookupAccountSid("", sid))

View file

@ -0,0 +1,336 @@
import ntsecuritycon
import win32security
import winnt
class Enum:
def __init__(self, *const_names):
"""Accepts variable number of constant names that can be found in either
win32security, ntsecuritycon, or winnt."""
for const_name in const_names:
try:
const_val = getattr(win32security, const_name)
except AttributeError:
try:
const_val = getattr(ntsecuritycon, const_name)
except AttributeError:
try:
const_val = getattr(winnt, const_name)
except AttributeError:
raise AttributeError(
'Constant "%s" not found in win32security, ntsecuritycon, or winnt.'
% const_name
)
setattr(self, const_name, const_val)
def lookup_name(self, const_val):
"""Looks up the name of a particular value."""
for k, v in self.__dict__.items():
if v == const_val:
return k
raise AttributeError("Value %s not found in enum" % const_val)
def lookup_flags(self, flags):
"""Returns the names of all recognized flags in input, and any flags not found in the enum."""
flag_names = []
unknown_flags = flags
for k, v in self.__dict__.items():
if flags & v == v:
flag_names.append(k)
unknown_flags = unknown_flags & ~v
return flag_names, unknown_flags
TOKEN_INFORMATION_CLASS = Enum(
"TokenUser",
"TokenGroups",
"TokenPrivileges",
"TokenOwner",
"TokenPrimaryGroup",
"TokenDefaultDacl",
"TokenSource",
"TokenType",
"TokenImpersonationLevel",
"TokenStatistics",
"TokenRestrictedSids",
"TokenSessionId",
"TokenGroupsAndPrivileges",
"TokenSessionReference",
"TokenSandBoxInert",
"TokenAuditPolicy",
"TokenOrigin",
"TokenElevationType",
"TokenLinkedToken",
"TokenElevation",
"TokenHasRestrictions",
"TokenAccessInformation",
"TokenVirtualizationAllowed",
"TokenVirtualizationEnabled",
"TokenIntegrityLevel",
"TokenUIAccess",
"TokenMandatoryPolicy",
"TokenLogonSid",
)
TOKEN_TYPE = Enum("TokenPrimary", "TokenImpersonation")
TOKEN_ELEVATION_TYPE = Enum(
"TokenElevationTypeDefault", "TokenElevationTypeFull", "TokenElevationTypeLimited"
)
POLICY_AUDIT_EVENT_TYPE = Enum(
"AuditCategorySystem",
"AuditCategoryLogon",
"AuditCategoryObjectAccess",
"AuditCategoryPrivilegeUse",
"AuditCategoryDetailedTracking",
"AuditCategoryPolicyChange",
"AuditCategoryAccountManagement",
"AuditCategoryDirectoryServiceAccess",
"AuditCategoryAccountLogon",
)
POLICY_INFORMATION_CLASS = Enum(
"PolicyAuditLogInformation",
"PolicyAuditEventsInformation",
"PolicyPrimaryDomainInformation",
"PolicyPdAccountInformation",
"PolicyAccountDomainInformation",
"PolicyLsaServerRoleInformation",
"PolicyReplicaSourceInformation",
"PolicyDefaultQuotaInformation",
"PolicyModificationInformation",
"PolicyAuditFullSetInformation",
"PolicyAuditFullQueryInformation",
"PolicyDnsDomainInformation",
)
POLICY_LSA_SERVER_ROLE = Enum("PolicyServerRoleBackup", "PolicyServerRolePrimary")
## access modes for opening a policy handle - this is not a real enum
POLICY_ACCESS_MODES = Enum(
"POLICY_VIEW_LOCAL_INFORMATION",
"POLICY_VIEW_AUDIT_INFORMATION",
"POLICY_GET_PRIVATE_INFORMATION",
"POLICY_TRUST_ADMIN",
"POLICY_CREATE_ACCOUNT",
"POLICY_CREATE_SECRET",
"POLICY_CREATE_PRIVILEGE",
"POLICY_SET_DEFAULT_QUOTA_LIMITS",
"POLICY_SET_AUDIT_REQUIREMENTS",
"POLICY_AUDIT_LOG_ADMIN",
"POLICY_SERVER_ADMIN",
"POLICY_LOOKUP_NAMES",
"POLICY_NOTIFICATION",
"POLICY_ALL_ACCESS",
"POLICY_READ",
"POLICY_WRITE",
"POLICY_EXECUTE",
)
## EventAuditingOptions flags - not a real enum
POLICY_AUDIT_EVENT_OPTIONS_FLAGS = Enum(
"POLICY_AUDIT_EVENT_UNCHANGED",
"POLICY_AUDIT_EVENT_SUCCESS",
"POLICY_AUDIT_EVENT_FAILURE",
"POLICY_AUDIT_EVENT_NONE",
)
# AceType in ACE_HEADER - not a real enum
ACE_TYPE = Enum(
"ACCESS_MIN_MS_ACE_TYPE",
"ACCESS_ALLOWED_ACE_TYPE",
"ACCESS_DENIED_ACE_TYPE",
"SYSTEM_AUDIT_ACE_TYPE",
"SYSTEM_ALARM_ACE_TYPE",
"ACCESS_MAX_MS_V2_ACE_TYPE",
"ACCESS_ALLOWED_COMPOUND_ACE_TYPE",
"ACCESS_MAX_MS_V3_ACE_TYPE",
"ACCESS_MIN_MS_OBJECT_ACE_TYPE",
"ACCESS_ALLOWED_OBJECT_ACE_TYPE",
"ACCESS_DENIED_OBJECT_ACE_TYPE",
"SYSTEM_AUDIT_OBJECT_ACE_TYPE",
"SYSTEM_ALARM_OBJECT_ACE_TYPE",
"ACCESS_MAX_MS_OBJECT_ACE_TYPE",
"ACCESS_MAX_MS_V4_ACE_TYPE",
"ACCESS_MAX_MS_ACE_TYPE",
"ACCESS_ALLOWED_CALLBACK_ACE_TYPE",
"ACCESS_DENIED_CALLBACK_ACE_TYPE",
"ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE",
"ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE",
"SYSTEM_AUDIT_CALLBACK_ACE_TYPE",
"SYSTEM_ALARM_CALLBACK_ACE_TYPE",
"SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE",
"SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE",
"SYSTEM_MANDATORY_LABEL_ACE_TYPE",
"ACCESS_MAX_MS_V5_ACE_TYPE",
)
# bit flags for AceFlags - not a real enum
ACE_FLAGS = Enum(
"CONTAINER_INHERIT_ACE",
"FAILED_ACCESS_ACE_FLAG",
"INHERIT_ONLY_ACE",
"INHERITED_ACE",
"NO_PROPAGATE_INHERIT_ACE",
"OBJECT_INHERIT_ACE",
"SUCCESSFUL_ACCESS_ACE_FLAG",
"NO_INHERITANCE",
"SUB_CONTAINERS_AND_OBJECTS_INHERIT",
"SUB_CONTAINERS_ONLY_INHERIT",
"SUB_OBJECTS_ONLY_INHERIT",
)
# used in SetEntriesInAcl - very similar to ACE_TYPE
ACCESS_MODE = Enum(
"NOT_USED_ACCESS",
"GRANT_ACCESS",
"SET_ACCESS",
"DENY_ACCESS",
"REVOKE_ACCESS",
"SET_AUDIT_SUCCESS",
"SET_AUDIT_FAILURE",
)
# Bit flags in PSECURITY_DESCRIPTOR->Control - not a real enum
SECURITY_DESCRIPTOR_CONTROL_FLAGS = Enum(
"SE_DACL_AUTO_INHERITED", ## win2k and up
"SE_SACL_AUTO_INHERITED", ## win2k and up
"SE_DACL_PROTECTED", ## win2k and up
"SE_SACL_PROTECTED", ## win2k and up
"SE_DACL_DEFAULTED",
"SE_DACL_PRESENT",
"SE_GROUP_DEFAULTED",
"SE_OWNER_DEFAULTED",
"SE_SACL_PRESENT",
"SE_SELF_RELATIVE",
"SE_SACL_DEFAULTED",
)
# types of SID
SID_NAME_USE = Enum(
"SidTypeUser",
"SidTypeGroup",
"SidTypeDomain",
"SidTypeAlias",
"SidTypeWellKnownGroup",
"SidTypeDeletedAccount",
"SidTypeInvalid",
"SidTypeUnknown",
"SidTypeComputer",
"SidTypeLabel",
)
## bit flags, not a real enum
TOKEN_ACCESS_PRIVILEGES = Enum(
"TOKEN_ADJUST_DEFAULT",
"TOKEN_ADJUST_GROUPS",
"TOKEN_ADJUST_PRIVILEGES",
"TOKEN_ALL_ACCESS",
"TOKEN_ASSIGN_PRIMARY",
"TOKEN_DUPLICATE",
"TOKEN_EXECUTE",
"TOKEN_IMPERSONATE",
"TOKEN_QUERY",
"TOKEN_QUERY_SOURCE",
"TOKEN_READ",
"TOKEN_WRITE",
)
SECURITY_IMPERSONATION_LEVEL = Enum(
"SecurityAnonymous",
"SecurityIdentification",
"SecurityImpersonation",
"SecurityDelegation",
)
POLICY_SERVER_ENABLE_STATE = Enum("PolicyServerEnabled", "PolicyServerDisabled")
POLICY_NOTIFICATION_INFORMATION_CLASS = Enum(
"PolicyNotifyAuditEventsInformation",
"PolicyNotifyAccountDomainInformation",
"PolicyNotifyServerRoleInformation",
"PolicyNotifyDnsDomainInformation",
"PolicyNotifyDomainEfsInformation",
"PolicyNotifyDomainKerberosTicketInformation",
"PolicyNotifyMachineAccountPasswordInformation",
)
TRUSTED_INFORMATION_CLASS = Enum(
"TrustedDomainNameInformation",
"TrustedControllersInformation",
"TrustedPosixOffsetInformation",
"TrustedPasswordInformation",
"TrustedDomainInformationBasic",
"TrustedDomainInformationEx",
"TrustedDomainAuthInformation",
"TrustedDomainFullInformation",
"TrustedDomainAuthInformationInternal",
"TrustedDomainFullInformationInternal",
"TrustedDomainInformationEx2Internal",
"TrustedDomainFullInformation2Internal",
)
TRUSTEE_FORM = Enum(
"TRUSTEE_IS_SID",
"TRUSTEE_IS_NAME",
"TRUSTEE_BAD_FORM",
"TRUSTEE_IS_OBJECTS_AND_SID",
"TRUSTEE_IS_OBJECTS_AND_NAME",
)
TRUSTEE_TYPE = Enum(
"TRUSTEE_IS_UNKNOWN",
"TRUSTEE_IS_USER",
"TRUSTEE_IS_GROUP",
"TRUSTEE_IS_DOMAIN",
"TRUSTEE_IS_ALIAS",
"TRUSTEE_IS_WELL_KNOWN_GROUP",
"TRUSTEE_IS_DELETED",
"TRUSTEE_IS_INVALID",
"TRUSTEE_IS_COMPUTER",
)
## SE_OBJECT_TYPE - securable objects
SE_OBJECT_TYPE = Enum(
"SE_UNKNOWN_OBJECT_TYPE",
"SE_FILE_OBJECT",
"SE_SERVICE",
"SE_PRINTER",
"SE_REGISTRY_KEY",
"SE_LMSHARE",
"SE_KERNEL_OBJECT",
"SE_WINDOW_OBJECT",
"SE_DS_OBJECT",
"SE_DS_OBJECT_ALL",
"SE_PROVIDER_DEFINED_OBJECT",
"SE_WMIGUID_OBJECT",
"SE_REGISTRY_WOW64_32KEY",
)
PRIVILEGE_FLAGS = Enum(
"SE_PRIVILEGE_ENABLED_BY_DEFAULT",
"SE_PRIVILEGE_ENABLED",
"SE_PRIVILEGE_USED_FOR_ACCESS",
)
# Group flags used with TokenGroups
TOKEN_GROUP_ATTRIBUTES = Enum(
"SE_GROUP_MANDATORY",
"SE_GROUP_ENABLED_BY_DEFAULT",
"SE_GROUP_ENABLED",
"SE_GROUP_OWNER",
"SE_GROUP_USE_FOR_DENY_ONLY",
"SE_GROUP_INTEGRITY",
"SE_GROUP_INTEGRITY_ENABLED",
"SE_GROUP_LOGON_ID",
"SE_GROUP_RESOURCE",
)
# Privilege flags returned by TokenPrivileges
TOKEN_PRIVILEGE_ATTRIBUTES = Enum(
"SE_PRIVILEGE_ENABLED_BY_DEFAULT",
"SE_PRIVILEGE_ENABLED",
"SE_PRIVILEGE_REMOVED",
"SE_PRIVILEGE_USED_FOR_ACCESS",
)

View file

@ -0,0 +1,107 @@
import os
import ntsecuritycon
import win32api
import win32con
import win32file
import win32security
from win32security import (
ACL_REVISION_DS,
CONTAINER_INHERIT_ACE,
DACL_SECURITY_INFORMATION,
GROUP_SECURITY_INFORMATION,
OBJECT_INHERIT_ACE,
OWNER_SECURITY_INFORMATION,
PROTECTED_DACL_SECURITY_INFORMATION,
SACL_SECURITY_INFORMATION,
SE_FILE_OBJECT,
)
## SE_SECURITY_NAME needed to access SACL, SE_RESTORE_NAME needed to change owner to someone other than yourself
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS | win32con.TOKEN_ADJUST_PRIVILEGES
)
modified_privs = win32security.AdjustTokenPrivileges(th, 0, new_privs)
## look up a few sids that should be available on most systems
my_sid = win32security.GetTokenInformation(th, ntsecuritycon.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
admin_sid = win32security.LookupAccountName("", "Administrators")[0]
everyone_sid = win32security.LookupAccountName("", "EveryOne")[0]
## create a dir and set security so Everyone has read permissions, and all files and subdirs inherit its ACLs
temp_dir = win32api.GetTempPath()
dir_name = win32api.GetTempFileName(temp_dir, "sfa")[0]
os.remove(dir_name)
os.mkdir(dir_name)
dir_dacl = win32security.ACL()
dir_dacl.AddAccessAllowedAceEx(
ACL_REVISION_DS,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
win32con.GENERIC_READ,
everyone_sid,
)
## make sure current user has permissions on dir
dir_dacl.AddAccessAllowedAceEx(
ACL_REVISION_DS,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
win32con.GENERIC_ALL,
my_sid,
)
## keep dir from inheriting any permissions so it only has ACEs explicitely set here
win32security.SetNamedSecurityInfo(
dir_name,
SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
| PROTECTED_DACL_SECURITY_INFORMATION,
pwr_sid,
pwr_sid,
dir_dacl,
None,
)
## Create a file in the dir and add some specific permissions to it
fname = win32api.GetTempFileName(dir_name, "sfa")[0]
print(fname)
file_sd = win32security.GetNamedSecurityInfo(
fname, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION
)
file_dacl = file_sd.GetSecurityDescriptorDacl()
file_sacl = file_sd.GetSecurityDescriptorSacl()
if file_dacl is None:
file_dacl = win32security.ACL()
if file_sacl is None:
file_sacl = win32security.ACL()
file_dacl.AddAccessDeniedAce(file_dacl.GetAclRevision(), win32con.DELETE, admin_sid)
file_dacl.AddAccessDeniedAce(file_dacl.GetAclRevision(), win32con.DELETE, my_sid)
file_dacl.AddAccessAllowedAce(file_dacl.GetAclRevision(), win32con.GENERIC_ALL, pwr_sid)
file_sacl.AddAuditAccessAce(
file_dacl.GetAclRevision(), win32con.GENERIC_ALL, my_sid, True, True
)
win32security.SetNamedSecurityInfo(
fname,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
None,
None,
file_dacl,
file_sacl,
)
win32security.AdjustTokenPrivileges(th, 0, modified_privs)

View file

@ -0,0 +1,74 @@
fname = r"h:\tmp.txt"
import ntsecuritycon
import win32api
import win32con
import win32file
import win32security
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", "SeEnableDelegationPrivilege"),
win32con.SE_PRIVILEGE_ENABLED,
), ##doesn't seem to be in ntsecuritycon.py ?
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS | win32con.TOKEN_ADJUST_PRIVILEGES
)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
all_security_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
sd = win32security.GetFileSecurity(fname, all_security_info)
old_dacl = sd.GetSecurityDescriptorDacl()
old_sacl = sd.GetSecurityDescriptorSacl()
old_group = sd.GetSecurityDescriptorGroup()
new_sd = win32security.SECURITY_DESCRIPTOR()
print(
"relative, valid, size: ",
new_sd.IsSelfRelative(),
new_sd.IsValid(),
new_sd.GetLength(),
)
my_sid = win32security.GetTokenInformation(th, ntsecuritycon.TokenUser)[0]
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
new_sd.SetSecurityDescriptorSacl(1, old_sacl, 1)
new_sd.SetSecurityDescriptorDacl(1, old_dacl, 1)
new_sd.SetSecurityDescriptorOwner(tmp_sid, 0)
new_sd.SetSecurityDescriptorGroup(old_group, 0)
win32security.SetFileSecurity(fname, all_security_info, new_sd)

View file

@ -0,0 +1,28 @@
import ntsecuritycon
import win32api
import win32file
import win32security
policy_handle = win32security.GetPolicyHandle("rupole", win32security.POLICY_ALL_ACCESS)
event_audit_info = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyAuditEventsInformation
)
print(event_audit_info)
new_audit_info = list(event_audit_info[1])
new_audit_info[win32security.AuditCategoryPolicyChange] = (
win32security.POLICY_AUDIT_EVENT_SUCCESS | win32security.POLICY_AUDIT_EVENT_FAILURE
)
new_audit_info[win32security.AuditCategoryAccountLogon] = (
win32security.POLICY_AUDIT_EVENT_SUCCESS | win32security.POLICY_AUDIT_EVENT_FAILURE
)
new_audit_info[win32security.AuditCategoryLogon] = (
win32security.POLICY_AUDIT_EVENT_SUCCESS | win32security.POLICY_AUDIT_EVENT_FAILURE
)
win32security.LsaSetInformationPolicy(
policy_handle, win32security.PolicyAuditEventsInformation, (1, new_audit_info)
)
win32security.LsaClose(policy_handle)

View file

@ -0,0 +1,135 @@
import win32api
import win32con
import win32process
import win32security
## You need SE_RESTORE_NAME to be able to set the owner of a security descriptor to anybody
## other than yourself or your primary group. Most admin logins don't have it by default, so
## enabling it may fail
new_privs = (
(
win32security.LookupPrivilegeValue("", win32security.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_ENABLE_DELEGATION_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CHANGE_NOTIFY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_DEBUG_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue(
"", win32security.SE_PROF_SINGLE_PROCESS_NAME
),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SYSTEM_PROFILE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_LOCK_MEMORY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
all_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
pid = win32api.GetCurrentProcessId()
ph = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid)
## PROCESS_ALL_ACCESS does not contain ACCESS_SYSTEM_SECURITY (neccessy to do SACLs)
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
old_privs = win32security.GetTokenInformation(th, win32security.TokenPrivileges)
desired_privs = tuple((e[0], win32con.SE_PRIVILEGE_ENABLED) for e in old_privs)
modified_privs = win32security.AdjustTokenPrivileges(
th, 0, desired_privs
) # Will (partially) fail for new_privs (unless they are a subset of current ones)
gle = win32api.GetLastError()
if gle != 0:
print("AdjustTokenPrivileges error:", gle)
# print(modified_privs)
my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
## reopen process with ACCESS_SYSTEM_SECURITY now that sufficent privs are enabled
ph = win32api.OpenProcess(
win32con.PROCESS_ALL_ACCESS | win32con.ACCESS_SYSTEM_SECURITY, 0, pid
)
sd = win32security.GetKernelObjectSecurity(ph, all_info)
dacl = sd.GetSecurityDescriptorDacl()
if dacl is None:
dacl = win32security.ACL()
sacl = sd.GetSecurityDescriptorSacl()
if sacl is None:
sacl = win32security.ACL()
dacl_ace_cnt = dacl.GetAceCount()
sacl_ace_cnt = sacl.GetAceCount()
dacl.AddAccessAllowedAce(
dacl.GetAclRevision(), win32con.ACCESS_SYSTEM_SECURITY | win32con.WRITE_DAC, my_sid
)
sacl.AddAuditAccessAce(sacl.GetAclRevision(), win32con.GENERIC_ALL, my_sid, 1, 1)
sd.SetSecurityDescriptorDacl(1, dacl, 0)
sd.SetSecurityDescriptorSacl(1, sacl, 0)
sd.SetSecurityDescriptorGroup(pwr_sid, 0)
sd.SetSecurityDescriptorOwner(pwr_sid, 0)
win32security.SetKernelObjectSecurity(ph, all_info, sd)
new_sd = win32security.GetKernelObjectSecurity(ph, all_info)
if new_sd.GetSecurityDescriptorDacl().GetAceCount() != dacl_ace_cnt + 1:
print("New dacl doesn" "t contain extra ace ????")
if new_sd.GetSecurityDescriptorSacl().GetAceCount() != sacl_ace_cnt + 1:
print("New Sacl doesn" "t contain extra ace ????")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorOwner())[0]
!= "Power Users"
):
print("Owner not successfully set to Power Users !!!!!")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorGroup())[0]
!= "Power Users"
):
print("Group not successfully set to Power Users !!!!!")
sd.SetSecurityDescriptorSacl(0, None, 0)
win32security.SetKernelObjectSecurity(ph, win32security.SACL_SECURITY_INFORMATION, sd)
new_sd_1 = win32security.GetKernelObjectSecurity(
ph, win32security.SACL_SECURITY_INFORMATION
)
if new_sd_1.GetSecurityDescriptorSacl() is not None:
print("Unable to set Sacl to NULL !!!!!!!!")

View file

@ -0,0 +1,131 @@
import win32api
import win32con
import win32process
import win32security
fname, tmp = win32api.GetTempFileName(win32api.GetTempPath(), "tmp")
print(fname)
## You need SE_RESTORE_NAME to be able to set the owner of a security descriptor to anybody
## other than yourself or your primary group. Most admin logins don't have it by default, so
## enabling it may fail
new_privs = (
(
win32security.LookupPrivilegeValue("", win32security.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_ENABLE_DELEGATION_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CHANGE_NOTIFY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_DEBUG_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue(
"", win32security.SE_PROF_SINGLE_PROCESS_NAME
),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SYSTEM_PROFILE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_LOCK_MEMORY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
all_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
ph = win32process.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
sd = win32security.GetNamedSecurityInfo(fname, win32security.SE_FILE_OBJECT, all_info)
dacl = sd.GetSecurityDescriptorDacl()
if dacl is None:
dacl = win32security.ACL()
sacl = sd.GetSecurityDescriptorSacl()
if sacl is None:
sacl = win32security.ACL()
dacl_ace_cnt = dacl.GetAceCount()
sacl_ace_cnt = sacl.GetAceCount()
dacl.AddAccessAllowedAce(
dacl.GetAclRevision(), win32con.ACCESS_SYSTEM_SECURITY | win32con.WRITE_DAC, my_sid
)
sacl.AddAuditAccessAce(sacl.GetAclRevision(), win32con.GENERIC_ALL, my_sid, 1, 1)
win32security.SetNamedSecurityInfo(
fname, win32security.SE_FILE_OBJECT, all_info, pwr_sid, pwr_sid, dacl, sacl
)
new_sd = win32security.GetNamedSecurityInfo(
fname, win32security.SE_FILE_OBJECT, all_info
)
## could do additional checking to make sure added ACE contains expected info
if new_sd.GetSecurityDescriptorDacl().GetAceCount() != dacl_ace_cnt + 1:
print("New dacl doesn" "t contain extra ace ????")
if new_sd.GetSecurityDescriptorSacl().GetAceCount() != sacl_ace_cnt + 1:
print("New Sacl doesn" "t contain extra ace ????")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorOwner())[0]
!= "Power Users"
):
print("Owner not successfully set to Power Users !!!!!")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorGroup())[0]
!= "Power Users"
):
print("Group not successfully set to Power Users !!!!!")
win32security.SetNamedSecurityInfo(
fname,
win32security.SE_FILE_OBJECT,
win32security.SACL_SECURITY_INFORMATION,
None,
None,
None,
None,
)
new_sd_1 = win32security.GetNamedSecurityInfo(
fname, win32security.SE_FILE_OBJECT, win32security.SACL_SECURITY_INFORMATION
)
if new_sd_1.GetSecurityDescriptorSacl() is not None:
print("Unable to set Sacl to NULL !!!!!!!!")

View file

@ -0,0 +1,132 @@
import win32api
import win32con
import win32process
import win32security
## You need SE_RESTORE_NAME to be able to set the owner of a security descriptor to anybody
## other than yourself or your primary group. Most admin logins don't have it by default, so
## enabling it may fail
new_privs = (
(
win32security.LookupPrivilegeValue("", win32security.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_ENABLE_DELEGATION_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CHANGE_NOTIFY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_DEBUG_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue(
"", win32security.SE_PROF_SINGLE_PROCESS_NAME
),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SYSTEM_PROFILE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_LOCK_MEMORY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
all_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
pid = win32api.GetCurrentProcessId()
ph = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid)
## PROCESS_ALL_ACCESS does not contain ACCESS_SYSTEM_SECURITY (neccessy to do SACLs)
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
old_privs = win32security.AdjustTokenPrivileges(th, 0, new_privs)
my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
## reopen process with ACCESS_SYSTEM_SECURITY now that sufficent privs are enabled
ph = win32api.OpenProcess(
win32con.PROCESS_ALL_ACCESS | win32con.ACCESS_SYSTEM_SECURITY, 0, pid
)
sd = win32security.GetSecurityInfo(ph, win32security.SE_KERNEL_OBJECT, all_info)
dacl = sd.GetSecurityDescriptorDacl()
if dacl is None:
dacl = win32security.ACL()
sacl = sd.GetSecurityDescriptorSacl()
if sacl is None:
sacl = win32security.ACL()
dacl_ace_cnt = dacl.GetAceCount()
sacl_ace_cnt = sacl.GetAceCount()
dacl.AddAccessAllowedAce(
dacl.GetAclRevision(), win32con.ACCESS_SYSTEM_SECURITY | win32con.WRITE_DAC, my_sid
)
sacl.AddAuditAccessAce(sacl.GetAclRevision(), win32con.GENERIC_ALL, my_sid, 1, 1)
win32security.SetSecurityInfo(
ph, win32security.SE_KERNEL_OBJECT, all_info, pwr_sid, pwr_sid, dacl, sacl
)
new_sd = win32security.GetSecurityInfo(ph, win32security.SE_KERNEL_OBJECT, all_info)
if new_sd.GetSecurityDescriptorDacl().GetAceCount() != dacl_ace_cnt + 1:
print("New dacl doesn" "t contain extra ace ????")
if new_sd.GetSecurityDescriptorSacl().GetAceCount() != sacl_ace_cnt + 1:
print("New Sacl doesn" "t contain extra ace ????")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorOwner())[0]
!= "Power Users"
):
print("Owner not successfully set to Power Users !!!!!")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorGroup())[0]
!= "Power Users"
):
print("Group not successfully set to Power Users !!!!!")
win32security.SetSecurityInfo(
ph,
win32security.SE_KERNEL_OBJECT,
win32security.SACL_SECURITY_INFORMATION,
None,
None,
None,
None,
)
new_sd_1 = win32security.GetSecurityInfo(
ph, win32security.SE_KERNEL_OBJECT, win32security.SACL_SECURITY_INFORMATION
)
if new_sd_1.GetSecurityDescriptorSacl() is not None:
print("Unable to set Sacl to NULL !!!!!!!!")

View file

@ -0,0 +1,103 @@
import win32api
import win32con
import win32process
import win32security
new_privs = (
(
win32security.LookupPrivilegeValue("", win32security.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_ENABLE_DELEGATION_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CHANGE_NOTIFY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_DEBUG_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue(
"", win32security.SE_PROF_SINGLE_PROCESS_NAME
),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SYSTEM_PROFILE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_LOCK_MEMORY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
all_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
)
ph = win32process.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
h = win32process.GetProcessWindowStation()
sd = win32security.GetUserObjectSecurity(h, info)
dacl = sd.GetSecurityDescriptorDacl()
ace_cnt = dacl.GetAceCount()
dacl.AddAccessAllowedAce(
dacl.GetAclRevision(), win32con.ACCESS_SYSTEM_SECURITY | win32con.WRITE_DAC, my_sid
)
sd.SetSecurityDescriptorDacl(1, dacl, 0)
sd.SetSecurityDescriptorGroup(pwr_sid, 0)
sd.SetSecurityDescriptorOwner(pwr_sid, 0)
win32security.SetUserObjectSecurity(h, info, sd)
new_sd = win32security.GetUserObjectSecurity(h, info)
assert (
new_sd.GetSecurityDescriptorDacl().GetAceCount() == ace_cnt + 1
), "Did not add an ace to the Dacl !!!!!!"
assert (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorOwner())[0]
== "Power Users"
), "Owner not successfully set to Power Users !!!!!"
assert (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorGroup())[0]
== "Power Users"
), "Group not successfully set to Power Users !!!!!"

View file

@ -0,0 +1,160 @@
"""
Fetches a URL from a web-server supporting NTLM authentication
eg, IIS.
If no arguments are specified, a default of http://localhost/localstart.asp
is used. This script does follow simple 302 redirections, so pointing at the
root of an IIS server is should work.
"""
import http.client # sorry, this demo needs 2.3+
import optparse
import urllib.error
import urllib.parse
import urllib.request
from base64 import decodestring, encodestring
from sspi import ClientAuth
options = None # set to optparse options object
def open_url(host, url):
h = http.client.HTTPConnection(host)
# h.set_debuglevel(9)
h.putrequest("GET", url)
h.endheaders()
resp = h.getresponse()
print("Initial response is", resp.status, resp.reason)
body = resp.read()
if resp.status == 302: # object moved
url = "/" + resp.msg["location"]
resp.close()
h.putrequest("GET", url)
h.endheaders()
resp = h.getresponse()
print("After redirect response is", resp.status, resp.reason)
if options.show_headers:
print("Initial response headers:")
for name, val in list(resp.msg.items()):
print(" %s: %s" % (name, val))
if options.show_body:
print(body)
if resp.status == 401:
# 401: Unauthorized - here is where the real work starts
auth_info = None
if options.user or options.domain or options.password:
auth_info = options.user, options.domain, options.password
ca = ClientAuth("NTLM", auth_info=auth_info)
auth_scheme = ca.pkg_info["Name"]
data = None
while 1:
err, out_buf = ca.authorize(data)
data = out_buf[0].Buffer
# Encode it as base64 as required by HTTP
auth = encodestring(data).replace("\012", "")
h.putrequest("GET", url)
h.putheader("Authorization", auth_scheme + " " + auth)
h.putheader("Content-Length", "0")
h.endheaders()
resp = h.getresponse()
if options.show_headers:
print("Token dance headers:")
for name, val in list(resp.msg.items()):
print(" %s: %s" % (name, val))
if err == 0:
break
else:
if resp.status != 401:
print("Eeek - got response", resp.status)
cl = resp.msg.get("content-length")
if cl:
print(repr(resp.read(int(cl))))
else:
print("no content!")
assert resp.status == 401, resp.status
assert not resp.will_close, "NTLM is per-connection - must not close"
schemes = [
s.strip() for s in resp.msg.get("WWW-Authenticate", "").split(",")
]
for scheme in schemes:
if scheme.startswith(auth_scheme):
data = decodestring(scheme[len(auth_scheme) + 1 :])
break
else:
print(
"Could not find scheme '%s' in schemes %r" % (auth_scheme, schemes)
)
break
resp.read()
print("Final response status is", resp.status, resp.reason)
if resp.status == 200:
# Worked!
# Check we can read it again without re-authenticating.
if resp.will_close:
print(
"EEEK - response will close, but NTLM is per connection - it must stay open"
)
body = resp.read()
if options.show_body:
print("Final response body:")
print(body)
h.putrequest("GET", url)
h.endheaders()
resp = h.getresponse()
print("Second fetch response is", resp.status, resp.reason)
if options.show_headers:
print("Second response headers:")
for name, val in list(resp.msg.items()):
print(" %s: %s" % (name, val))
resp.read(int(resp.msg.get("content-length", 0)))
elif resp.status == 500:
print("Error text")
print(resp.read())
else:
if options.show_body:
cl = resp.msg.get("content-length")
print(resp.read(int(cl)))
if __name__ == "__main__":
parser = optparse.OptionParser(description=__doc__)
parser.add_option(
"",
"--show-body",
action="store_true",
help="print the body of each response as it is received",
)
parser.add_option(
"",
"--show-headers",
action="store_true",
help="print the headers of each response as it is received",
)
parser.add_option("", "--user", action="store", help="The username to login with")
parser.add_option(
"", "--password", action="store", help="The password to login with"
)
parser.add_option("", "--domain", action="store", help="The domain to login to")
options, args = parser.parse_args()
if not args:
print("Run with --help for usage details")
args = ["http://localhost/localstart.asp"]
for url in args:
scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(url)
if (scheme != "http") or params or query or fragment:
parser.error("Scheme must be http, URL must be simple")
print("Opening '%s' from '%s'" % (path, netloc))
r = open_url(netloc, path)

View file

@ -0,0 +1,72 @@
# A demo of basic SSPI authentication.
# There is a 'client' context and a 'server' context - typically these will
# be on different machines (here they are in the same process, but the same
# concepts apply)
import sspi
import sspicon
import win32api
import win32security
def lookup_ret_code(err):
for k, v in list(sspicon.__dict__.items()):
if k[0:6] in ("SEC_I_", "SEC_E_") and v == err:
return k
"""
pkg_name='Kerberos'
sspiclient=SSPIClient(pkg_name, win32api.GetUserName(), ## target spn is ourself
None, None, ## use none for client name and authentication information for current context
## u'username', (u'username',u'domain.com',u'passwd'),
sspicon.ISC_REQ_INTEGRITY|sspicon.ISC_REQ_SEQUENCE_DETECT|sspicon.ISC_REQ_REPLAY_DETECT| \
sspicon.ISC_REQ_DELEGATE|sspicon.ISC_REQ_CONFIDENTIALITY|sspicon.ISC_REQ_USE_SESSION_KEY)
sspiserver=SSPIServer(pkg_name, None,
sspicon.ASC_REQ_INTEGRITY|sspicon.ASC_REQ_SEQUENCE_DETECT|sspicon.ASC_REQ_REPLAY_DETECT| \
sspicon.ASC_REQ_DELEGATE|sspicon.ASC_REQ_CONFIDENTIALITY|sspicon.ASC_REQ_STREAM|sspicon.ASC_REQ_USE_SESSION_KEY)
"""
pkg_name = "NTLM"
# Setup the 2 contexts.
sspiclient = sspi.ClientAuth(pkg_name)
sspiserver = sspi.ServerAuth(pkg_name)
# Perform the authentication dance, each loop exchanging more information
# on the way to completing authentication.
sec_buffer = None
while 1:
err, sec_buffer = sspiclient.authorize(sec_buffer)
err, sec_buffer = sspiserver.authorize(sec_buffer)
if err == 0:
break
# The server can now impersonate the client. In this demo the 2 users will
# always be the same.
sspiserver.ctxt.ImpersonateSecurityContext()
print("Impersonated user: ", win32api.GetUserNameEx(win32api.NameSamCompatible))
sspiserver.ctxt.RevertSecurityContext()
print("Reverted to self: ", win32api.GetUserName())
pkg_size_info = sspiclient.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES)
# Now sign some data
msg = "some data to be encrypted ......"
sigsize = pkg_size_info["MaxSignature"]
sigbuf = win32security.PySecBufferDescType()
sigbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
sigbuf.append(win32security.PySecBufferType(sigsize, sspicon.SECBUFFER_TOKEN))
sigbuf[0].Buffer = msg
sspiclient.ctxt.MakeSignature(0, sigbuf, 1)
sspiserver.ctxt.VerifySignature(sigbuf, 1)
# And finally encrypt some.
trailersize = pkg_size_info["SecurityTrailer"]
encbuf = win32security.PySecBufferDescType()
encbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
encbuf.append(win32security.PySecBufferType(trailersize, sspicon.SECBUFFER_TOKEN))
encbuf[0].Buffer = msg
sspiclient.ctxt.EncryptMessage(0, encbuf, 1)
print("Encrypted data:", repr(encbuf[0].Buffer))
sspiserver.ctxt.DecryptMessage(encbuf, 1)
print("Unencrypted data:", encbuf[0].Buffer)

View file

@ -0,0 +1,201 @@
"""A sample socket server and client using SSPI authentication and encryption.
You must run with either 'client' or 'server' as arguments. A server must be
running before a client can connect.
To use with Kerberos you should include in the client options
--target-spn=username, where 'username' is the user under which the server is
being run.
Running either the client or server as a different user can be informative.
A command-line such as the following may be useful:
`runas /user:{user} {fqp}\python.exe {fqp}\socket_server.py --wait client|server`
{fqp} should specify the relevant fully-qualified path names.
To use 'runas' with Kerberos, the client program will need to
specify --target-spn with the username under which the *server* is running.
See the SSPI documentation for more details.
"""
import http.client # sorry, this demo needs 2.3+
import optparse
import socketserver
import struct
import traceback
import sspi
import win32api
import win32security
options = None # set to optparse object.
def GetUserName():
try:
return win32api.GetUserName()
except win32api.error as details:
# Seeing 'access denied' errors here for non-local users (presumably
# without permission to login locally). Get the fully-qualified
# username, although a side-effect of these permission-denied errors
# is a lack of Python codecs - so printing the Unicode value fails.
# So just return the repr(), and avoid codecs completely.
return repr(win32api.GetUserNameEx(win32api.NameSamCompatible))
# Send a simple "message" over a socket - send the number of bytes first,
# then the string. Ditto for receive.
def _send_msg(s, m):
s.send(struct.pack("i", len(m)))
s.send(m)
def _get_msg(s):
size_data = s.recv(struct.calcsize("i"))
if not size_data:
return None
cb = struct.unpack("i", size_data)[0]
return s.recv(cb)
class SSPISocketServer(socketserver.TCPServer):
def __init__(self, *args, **kw):
socketserver.TCPServer.__init__(self, *args, **kw)
self.sa = sspi.ServerAuth(options.package)
def verify_request(self, sock, ca):
# Do the sspi auth dance
self.sa.reset()
while 1:
data = _get_msg(sock)
if data is None:
return False
try:
err, sec_buffer = self.sa.authorize(data)
except sspi.error as details:
print("FAILED to authorize client:", details)
return False
if err == 0:
break
_send_msg(sock, sec_buffer[0].Buffer)
return True
def process_request(self, request, client_address):
# An example using the connection once it is established.
print("The server is running as user", GetUserName())
self.sa.ctxt.ImpersonateSecurityContext()
try:
print("Having conversation with client as user", GetUserName())
while 1:
# we need to grab 2 bits of data - the encrypted data, and the
# 'key'
data = _get_msg(request)
key = _get_msg(request)
if data is None or key is None:
break
data = self.sa.decrypt(data, key)
print("Client sent:", repr(data))
finally:
self.sa.ctxt.RevertSecurityContext()
self.close_request(request)
print("The server is back to user", GetUserName())
def serve():
s = SSPISocketServer(("localhost", options.port), None)
print("Running test server...")
s.serve_forever()
def sspi_client():
c = http.client.HTTPConnection("localhost", options.port)
c.connect()
# Do the auth dance.
ca = sspi.ClientAuth(options.package, targetspn=options.target_spn)
data = None
while 1:
err, out_buf = ca.authorize(data)
_send_msg(c.sock, out_buf[0].Buffer)
if err == 0:
break
data = _get_msg(c.sock)
print("Auth dance complete - sending a few encryted messages")
# Assume out data is sensitive - encrypt the message.
for data in "Hello from the client".split():
blob, key = ca.encrypt(data)
_send_msg(c.sock, blob)
_send_msg(c.sock, key)
c.sock.close()
print("Client completed.")
if __name__ == "__main__":
parser = optparse.OptionParser("%prog [options] client|server", description=__doc__)
parser.add_option(
"",
"--package",
action="store",
default="NTLM",
help="The SSPI package to use (eg, Kerberos) - default is NTLM",
)
parser.add_option(
"",
"--target-spn",
action="store",
help="""The target security provider name to use. The
string contents are security-package specific. For
example, 'Kerberos' or 'Negotiate' require the server
principal name (SPN) (ie, the username) of the remote
process. For NTLM this must be blank.""",
)
parser.add_option(
"",
"--port",
action="store",
default="8181",
help="The port number to use (default=8181)",
)
parser.add_option(
"",
"--wait",
action="store_true",
help="""Cause the program to wait for input just before
terminating. Useful when using via runas to see
any error messages before termination.
""",
)
options, args = parser.parse_args()
try:
options.port = int(options.port)
except (ValueError, TypeError):
parser.error("--port must be an integer")
try:
try:
if not args:
args = [""]
if args[0] == "client":
sspi_client()
elif args[0] == "server":
serve()
else:
parser.error(
"You must supply 'client' or 'server' - " "use --help for details"
)
except KeyboardInterrupt:
pass
except SystemExit:
pass
except:
traceback.print_exc()
finally:
if options.wait:
input("Press enter to continue")

View file

@ -0,0 +1,41 @@
# Demonstrates how to validate a password.
# See also MSKB article Q180548
#
# To use with Kerberos you need to jump through the 'targetspn' hoops.
import sys
import win32security
from sspi import ClientAuth, ServerAuth
def validate(username, password, domain=""):
auth_info = username, domain, password
ca = ClientAuth("NTLM", auth_info=auth_info)
sa = ServerAuth("NTLM")
data = err = None
while err != 0:
err, data = ca.authorize(data)
err, data = sa.authorize(data)
# If we get here without exception, we worked!
if __name__ == "__main__":
if len(sys.argv) not in [2, 3, 4]:
print("Usage: %s username [password [domain]]" % (__file__,))
sys.exit(1)
# password and domain are optional!
password = None
if len(sys.argv) >= 3:
password = sys.argv[2]
domain = ""
if len(sys.argv) >= 4:
domain = sys.argv[3]
try:
validate(sys.argv[1], password, domain)
print("Validated OK")
except win32security.error as details:
hr, func, msg = details
print("Validation failed: %s (%d)" % (msg, hr))

View file

@ -0,0 +1,63 @@
# This is an example of a service hosted by python.exe rather than
# pythonservice.exe.
# Note that it is very rare that using python.exe is a better option
# than the default pythonservice.exe - the latter has better error handling
# so that if Python itself can't be initialized or there are very early
# import errors, you will get error details written to the event log. When
# using python.exe instead, you are forced to wait for the interpreter startup
# and imports to succeed before you are able to effectively setup your own
# error handling.
# So in short, please make sure you *really* want to do this, otherwise just
# stick with the default.
import os
import sys
import servicemanager
import win32serviceutil
from pipeTestService import TestPipeService
class NativeTestPipeService(TestPipeService):
_svc_name_ = "PyNativePipeTestService"
_svc_display_name_ = "Python Native Pipe Test Service"
_svc_description_ = "Tests Python.exe hosted services"
# tell win32serviceutil we have a custom executable and custom args
# so registration does the right thing.
_exe_name_ = sys.executable
_exe_args_ = '"' + os.path.abspath(sys.argv[0]) + '"'
def main():
if len(sys.argv) == 1:
# service must be starting...
print("service is starting...")
print("(execute this script with '--help' if that isn't what you want)")
# for the sake of debugging etc, we use win32traceutil to see
# any unhandled exceptions and print statements.
import win32traceutil
print("service is still starting...")
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(NativeTestPipeService)
# Now ask the service manager to fire things up for us...
servicemanager.StartServiceCtrlDispatcher()
print("service done!")
else:
win32serviceutil.HandleCommandLine(NativeTestPipeService)
if __name__ == "__main__":
try:
main()
except (SystemExit, KeyboardInterrupt):
raise
except:
print("Something went bad!")
import traceback
traceback.print_exc()

View file

@ -0,0 +1,184 @@
# A Demo of services and named pipes.
# A multi-threaded service that simply echos back its input.
# * Install as a service using "pipeTestService.py install"
# * Use Control Panel to change the user name of the service
# to a real user name (ie, NOT the SystemAccount)
# * Start the service.
# * Run the "pipeTestServiceClient.py" program as the client pipe side.
import _thread
import traceback
# Old versions of the service framework would not let you import this
# module at the top-level. Now you can, and can check 'Debugging()' and
# 'RunningAsService()' to check your context.
import pywintypes
import servicemanager
import win32con
import win32service
import win32serviceutil
import winerror
from ntsecuritycon import *
from win32api import *
# Use "import *" to keep this looking as much as a "normal" service
# as possible. Real code shouldn't do this.
from win32event import *
from win32file import *
from win32pipe import *
def ApplyIgnoreError(fn, args):
try:
return fn(*args)
except error: # Ignore win32api errors.
return None
class TestPipeService(win32serviceutil.ServiceFramework):
_svc_name_ = "PyPipeTestService"
_svc_display_name_ = "Python Pipe Test Service"
_svc_description_ = "Tests Python service framework by receiving and echoing messages over a named pipe"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = CreateEvent(None, 0, 0, None)
self.overlapped = pywintypes.OVERLAPPED()
self.overlapped.hEvent = CreateEvent(None, 0, 0, None)
self.thread_handles = []
def CreatePipeSecurityObject(self):
# Create a security object giving World read/write access,
# but only "Owner" modify access.
sa = pywintypes.SECURITY_ATTRIBUTES()
sidEveryone = pywintypes.SID()
sidEveryone.Initialize(SECURITY_WORLD_SID_AUTHORITY, 1)
sidEveryone.SetSubAuthority(0, SECURITY_WORLD_RID)
sidCreator = pywintypes.SID()
sidCreator.Initialize(SECURITY_CREATOR_SID_AUTHORITY, 1)
sidCreator.SetSubAuthority(0, SECURITY_CREATOR_OWNER_RID)
acl = pywintypes.ACL()
acl.AddAccessAllowedAce(FILE_GENERIC_READ | FILE_GENERIC_WRITE, sidEveryone)
acl.AddAccessAllowedAce(FILE_ALL_ACCESS, sidCreator)
sa.SetSecurityDescriptorDacl(1, acl, 0)
return sa
# The functions executed in their own thread to process a client request.
def DoProcessClient(self, pipeHandle, tid):
try:
try:
# Create a loop, reading large data. If we knew the data stream was
# was small, a simple ReadFile would do.
d = "".encode("ascii") # ensure bytes on py2k and py3k...
hr = winerror.ERROR_MORE_DATA
while hr == winerror.ERROR_MORE_DATA:
hr, thisd = ReadFile(pipeHandle, 256)
d = d + thisd
print("Read", d)
ok = 1
except error:
# Client disconnection - do nothing
ok = 0
# A secure service would handle (and ignore!) errors writing to the
# pipe, but for the sake of this demo we dont (if only to see what errors
# we can get when our clients break at strange times :-)
if ok:
msg = (
"%s (on thread %d) sent me %s"
% (GetNamedPipeHandleState(pipeHandle, False, True)[4], tid, d)
).encode("ascii")
WriteFile(pipeHandle, msg)
finally:
ApplyIgnoreError(DisconnectNamedPipe, (pipeHandle,))
ApplyIgnoreError(CloseHandle, (pipeHandle,))
def ProcessClient(self, pipeHandle):
try:
procHandle = GetCurrentProcess()
th = DuplicateHandle(
procHandle,
GetCurrentThread(),
procHandle,
0,
0,
win32con.DUPLICATE_SAME_ACCESS,
)
try:
self.thread_handles.append(th)
try:
return self.DoProcessClient(pipeHandle, th)
except:
traceback.print_exc()
finally:
self.thread_handles.remove(th)
except:
traceback.print_exc()
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
SetEvent(self.hWaitStop)
def SvcDoRun(self):
# Write an event log record - in debug mode we will also
# see this message printed.
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ""),
)
num_connections = 0
while 1:
pipeHandle = CreateNamedPipe(
"\\\\.\\pipe\\PyPipeTest",
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE,
PIPE_UNLIMITED_INSTANCES, # max instances
0,
0,
6000,
self.CreatePipeSecurityObject(),
)
try:
hr = ConnectNamedPipe(pipeHandle, self.overlapped)
except error as details:
print("Error connecting pipe!", details)
CloseHandle(pipeHandle)
break
if hr == winerror.ERROR_PIPE_CONNECTED:
# Client is already connected - signal event
SetEvent(self.overlapped.hEvent)
rc = WaitForMultipleObjects(
(self.hWaitStop, self.overlapped.hEvent), 0, INFINITE
)
if rc == WAIT_OBJECT_0:
# Stop event
break
else:
# Pipe event - spawn thread to deal with it.
_thread.start_new_thread(self.ProcessClient, (pipeHandle,))
num_connections = num_connections + 1
# Sleep to ensure that any new threads are in the list, and then
# wait for all current threads to finish.
# What is a better way?
Sleep(500)
while self.thread_handles:
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)
print("Waiting for %d threads to finish..." % (len(self.thread_handles)))
WaitForMultipleObjects(self.thread_handles, 1, 3000)
# Write another event log record.
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, " after processing %d connections" % (num_connections,)),
)
if __name__ == "__main__":
win32serviceutil.HandleCommandLine(TestPipeService)

View file

@ -0,0 +1,156 @@
# A Test Program for pipeTestService.py
#
# Install and start the Pipe Test service, then run this test
# either from the same machine, or from another using the "-s" param.
#
# Eg: pipeTestServiceClient.py -s server_name Hi There
# Should work.
import os
import sys
import traceback
import pywintypes
import win32api
import winerror
from win32event import *
from win32file import *
from win32pipe import *
verbose = 0
# def ReadFromPipe(pipeName):
# Could (Should?) use CallNamedPipe, but this technique allows variable size
# messages (whereas you must supply a buffer size for CallNamedPipe!
# hPipe = CreateFile(pipeName, GENERIC_WRITE, 0, None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
# more = 1
# while more:
# hr = ReadFile(hPipe, 256)
# if hr==0:
# more = 0
# except win32api.error (hr, fn, desc):
# if hr==winerror.ERROR_MORE_DATA:
# data = dat
#
def CallPipe(fn, args):
ret = None
retryCount = 0
while retryCount < 8: # Keep looping until user cancels.
retryCount = retryCount + 1
try:
return fn(*args)
except win32api.error as exc:
if exc.winerror == winerror.ERROR_PIPE_BUSY:
win32api.Sleep(5000)
continue
else:
raise
raise RuntimeError("Could not make a connection to the server")
def testClient(server, msg):
if verbose:
print("Sending", msg)
data = CallPipe(
CallNamedPipe,
("\\\\%s\\pipe\\PyPipeTest" % server, msg, 256, NMPWAIT_WAIT_FOREVER),
)
if verbose:
print("Server sent back '%s'" % data)
print("Sent and received a message!")
def testLargeMessage(server, size=4096):
if verbose:
print("Sending message of size %d" % (size))
msg = "*" * size
data = CallPipe(
CallNamedPipe,
("\\\\%s\\pipe\\PyPipeTest" % server, msg, 512, NMPWAIT_WAIT_FOREVER),
)
if len(data) - size:
print("Sizes are all wrong - send %d, got back %d" % (size, len(data)))
def stressThread(server, numMessages, wait):
try:
try:
for i in range(numMessages):
r = CallPipe(
CallNamedPipe,
(
"\\\\%s\\pipe\\PyPipeTest" % server,
"#" * 512,
1024,
NMPWAIT_WAIT_FOREVER,
),
)
except:
traceback.print_exc()
print("Failed after %d messages" % i)
finally:
SetEvent(wait)
def stressTestClient(server, numThreads, numMessages):
import _thread
thread_waits = []
for t_num in range(numThreads):
# Note I could just wait on thread handles (after calling DuplicateHandle)
# See the service itself for an example of waiting for the clients...
wait = CreateEvent(None, 0, 0, None)
thread_waits.append(wait)
_thread.start_new_thread(stressThread, (server, numMessages, wait))
# Wait for all threads to finish.
WaitForMultipleObjects(thread_waits, 1, INFINITE)
def main():
import getopt
import sys
server = "."
thread_count = 0
msg_count = 500
try:
opts, args = getopt.getopt(sys.argv[1:], "s:t:m:vl")
for o, a in opts:
if o == "-s":
server = a
if o == "-m":
msg_count = int(a)
if o == "-t":
thread_count = int(a)
if o == "-v":
global verbose
verbose = 1
if o == "-l":
testLargeMessage(server)
msg = " ".join(args).encode("mbcs")
except getopt.error as msg:
print(msg)
my_name = os.path.split(sys.argv[0])[1]
print(
"Usage: %s [-v] [-s server] [-t thread_count=0] [-m msg_count=500] msg ..."
% my_name
)
print(" -v = verbose")
print(
" Specifying a value for -t will stress test using that many threads."
)
return
testClient(server, msg)
if thread_count > 0:
print(
"Spawning %d threads each sending %d messages..."
% (thread_count, msg_count)
)
stressTestClient(server, thread_count, msg_count)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,98 @@
# A Demo of a service that takes advantage of the additional notifications
# available in later Windows versions.
# Note that all output is written as event log entries - so you must install
# and start the service, then look at the event log for messages as events
# are generated.
# Events are generated for USB device insertion and removal, power state
# changes and hardware profile events - so try putting your computer to
# sleep and waking it, inserting a memory stick, etc then check the event log
# Most event notification support lives around win32gui
import servicemanager
import win32con
import win32event
import win32gui
import win32gui_struct
import win32service
import win32serviceutil
GUID_DEVINTERFACE_USB_DEVICE = "{A5DCBF10-6530-11D2-901F-00C04FB951ED}"
class EventDemoService(win32serviceutil.ServiceFramework):
_svc_name_ = "PyServiceEventDemo"
_svc_display_name_ = "Python Service Event Demo"
_svc_description_ = (
"Demonstrates a Python service which takes advantage of the extra notifications"
)
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
# register for a device notification - we pass our service handle
# instead of a window handle.
filter = win32gui_struct.PackDEV_BROADCAST_DEVICEINTERFACE(
GUID_DEVINTERFACE_USB_DEVICE
)
self.hdn = win32gui.RegisterDeviceNotification(
self.ssh, filter, win32con.DEVICE_NOTIFY_SERVICE_HANDLE
)
# Override the base class so we can accept additional events.
def GetAcceptedControls(self):
# say we accept them all.
rc = win32serviceutil.ServiceFramework.GetAcceptedControls(self)
rc |= (
win32service.SERVICE_ACCEPT_PARAMCHANGE
| win32service.SERVICE_ACCEPT_NETBINDCHANGE
| win32service.SERVICE_CONTROL_DEVICEEVENT
| win32service.SERVICE_ACCEPT_HARDWAREPROFILECHANGE
| win32service.SERVICE_ACCEPT_POWEREVENT
| win32service.SERVICE_ACCEPT_SESSIONCHANGE
)
return rc
# All extra events are sent via SvcOtherEx (SvcOther remains as a
# function taking only the first args for backwards compat)
def SvcOtherEx(self, control, event_type, data):
# This is only showing a few of the extra events - see the MSDN
# docs for "HandlerEx callback" for more info.
if control == win32service.SERVICE_CONTROL_DEVICEEVENT:
info = win32gui_struct.UnpackDEV_BROADCAST(data)
msg = "A device event occurred: %x - %s" % (event_type, info)
elif control == win32service.SERVICE_CONTROL_HARDWAREPROFILECHANGE:
msg = "A hardware profile changed: type=%s, data=%s" % (event_type, data)
elif control == win32service.SERVICE_CONTROL_POWEREVENT:
msg = "A power event: setting %s" % data
elif control == win32service.SERVICE_CONTROL_SESSIONCHANGE:
# data is a single elt tuple, but this could potentially grow
# in the future if the win32 struct does
msg = "Session event: type=%s, data=%s" % (event_type, data)
else:
msg = "Other event: code=%d, type=%s, data=%s" % (control, event_type, data)
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
0xF000, # generic message
(msg, ""),
)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
# do nothing at all - just wait to be stopped
win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
# Write a stop message.
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ""),
)
if __name__ == "__main__":
win32serviceutil.HandleCommandLine(EventDemoService)

View file

@ -0,0 +1,72 @@
# -*- Mode: Python; tab-width: 4 -*-
#
# This module, and the timer.pyd core timer support, were written by
# Sam Rushing (rushing@nightmare.com)
import time
# Timers are based on Windows messages. So we need
# to do the event-loop thing!
import timer
import win32event
import win32gui
# glork holds a simple counter for us.
class glork:
def __init__(self, delay=1000, max=10):
self.x = 0
self.max = max
self.id = timer.set_timer(delay, self.increment)
# Could use the threading module, but this is
# a win32 extension test after all! :-)
self.event = win32event.CreateEvent(None, 0, 0, None)
def increment(self, id, time):
print("x = %d" % self.x)
self.x = self.x + 1
# if we've reached the max count,
# kill off the timer.
if self.x > self.max:
# we could have used 'self.id' here, too
timer.kill_timer(id)
win32event.SetEvent(self.event)
# create a counter that will count from '1' thru '10', incrementing
# once a second, and then stop.
def demo(delay=1000, stop=10):
g = glork(delay, stop)
# Timers are message based - so we need
# To run a message loop while waiting for our timers
# to expire.
start_time = time.time()
while 1:
# We can't simply give a timeout of 30 seconds, as
# we may continouusly be recieving other input messages,
# and therefore never expire.
rc = win32event.MsgWaitForMultipleObjects(
(g.event,), # list of objects
0, # wait all
500, # timeout
win32event.QS_ALLEVENTS, # type of input
)
if rc == win32event.WAIT_OBJECT_0:
# Event signalled.
break
elif rc == win32event.WAIT_OBJECT_0 + 1:
# Message waiting.
if win32gui.PumpWaitingMessages():
raise RuntimeError("We got an unexpected WM_QUIT message!")
else:
# This wait timed-out.
if time.time() - start_time > 30:
raise RuntimeError("We timed out waiting for the timers to expire!")
if __name__ == "__main__":
demo()

View file

@ -0,0 +1,145 @@
# win32clipboardDemo.py
#
# Demo/test of the win32clipboard module.
import win32con
from pywin32_testutil import str2bytes # py3k-friendly helper
from win32clipboard import *
if not __debug__:
print("WARNING: The test code in this module uses assert")
print("This instance of Python has asserts disabled, so many tests will be skipped")
cf_names = {}
# Build map of CF_* constants to names.
for name, val in list(win32con.__dict__.items()):
if name[:3] == "CF_" and name != "CF_SCREENFONTS": # CF_SCREEN_FONTS==CF_TEXT!?!?
cf_names[val] = name
def TestEmptyClipboard():
OpenClipboard()
try:
EmptyClipboard()
assert (
EnumClipboardFormats(0) == 0
), "Clipboard formats were available after emptying it!"
finally:
CloseClipboard()
def TestText():
OpenClipboard()
try:
text = "Hello from Python"
text_bytes = str2bytes(text)
SetClipboardText(text)
got = GetClipboardData(win32con.CF_TEXT)
# CF_TEXT always gives us 'bytes' back .
assert got == text_bytes, "Didnt get the correct result back - '%r'." % (got,)
finally:
CloseClipboard()
OpenClipboard()
try:
# CF_UNICODE text always gives unicode objects back.
got = GetClipboardData(win32con.CF_UNICODETEXT)
assert got == text, "Didnt get the correct result back - '%r'." % (got,)
assert type(got) == str, "Didnt get the correct result back - '%r'." % (got,)
# CF_OEMTEXT is a bytes-based format.
got = GetClipboardData(win32con.CF_OEMTEXT)
assert got == text_bytes, "Didnt get the correct result back - '%r'." % (got,)
# Unicode tests
EmptyClipboard()
text = "Hello from Python unicode"
text_bytes = str2bytes(text)
# Now set the Unicode value
SetClipboardData(win32con.CF_UNICODETEXT, text)
# Get it in Unicode.
got = GetClipboardData(win32con.CF_UNICODETEXT)
assert got == text, "Didnt get the correct result back - '%r'." % (got,)
assert type(got) == str, "Didnt get the correct result back - '%r'." % (got,)
# Close and open the clipboard to ensure auto-conversions take place.
finally:
CloseClipboard()
OpenClipboard()
try:
# Make sure I can still get the text as bytes
got = GetClipboardData(win32con.CF_TEXT)
assert got == text_bytes, "Didnt get the correct result back - '%r'." % (got,)
# Make sure we get back the correct types.
got = GetClipboardData(win32con.CF_UNICODETEXT)
assert type(got) == str, "Didnt get the correct result back - '%r'." % (got,)
got = GetClipboardData(win32con.CF_OEMTEXT)
assert got == text_bytes, "Didnt get the correct result back - '%r'." % (got,)
print("Clipboard text tests worked correctly")
finally:
CloseClipboard()
def TestClipboardEnum():
OpenClipboard()
try:
# Enumerate over the clipboard types
enum = 0
while 1:
enum = EnumClipboardFormats(enum)
if enum == 0:
break
assert IsClipboardFormatAvailable(
enum
), "Have format, but clipboard says it is not available!"
n = cf_names.get(enum, "")
if not n:
try:
n = GetClipboardFormatName(enum)
except error:
n = "unknown (%s)" % (enum,)
print("Have format", n)
print("Clipboard enumerator tests worked correctly")
finally:
CloseClipboard()
class Foo:
def __init__(self, **kw):
self.__dict__.update(kw)
def __cmp__(self, other):
return cmp(self.__dict__, other.__dict__)
def __eq__(self, other):
return self.__dict__ == other.__dict__
def TestCustomFormat():
OpenClipboard()
try:
# Just for the fun of it pickle Python objects through the clipboard
fmt = RegisterClipboardFormat("Python Pickle Format")
import pickle
pickled_object = Foo(a=1, b=2, Hi=3)
SetClipboardData(fmt, pickle.dumps(pickled_object))
# Now read it back.
data = GetClipboardData(fmt)
loaded_object = pickle.loads(data)
assert pickle.loads(data) == pickled_object, "Didnt get the correct data!"
print("Clipboard custom format tests worked correctly")
finally:
CloseClipboard()
if __name__ == "__main__":
TestEmptyClipboard()
TestText()
TestCustomFormat()
TestClipboardEnum()
# And leave it empty at the end!
TestEmptyClipboard()

View file

@ -0,0 +1,117 @@
import win32api
import win32clipboard
import win32con
import win32gui
class ViewerWindow:
def __init__(self):
self.hwndNextViewer = None
def OnPaint(self, hwnd, msg, wp, lp):
dc, ps = win32gui.BeginPaint(hwnd)
wndrect = win32gui.GetClientRect(hwnd)
wndwidth = wndrect[2] - wndrect[0]
wndheight = wndrect[3] - wndrect[1]
win32clipboard.OpenClipboard()
try:
try:
hbitmap = win32clipboard.GetClipboardData(win32clipboard.CF_BITMAP)
except TypeError:
font = win32gui.LOGFONT()
font.lfHeight = 15 # int(wndheight/20)
font.lfWidth = 15 # font.lfHeight
# font.lfWeight=150
hf = win32gui.CreateFontIndirect(font)
win32gui.SelectObject(dc, hf)
win32gui.SetBkMode(dc, win32con.TRANSPARENT)
win32gui.SetTextColor(dc, win32api.RGB(0, 0, 0))
win32gui.DrawText(
dc,
"No bitmaps are in the clipboard\n(try pressing the PrtScn button)",
-1,
(0, 0, wndwidth, wndheight),
win32con.DT_CENTER,
)
else:
bminfo = win32gui.GetObject(hbitmap)
dcDC = win32gui.CreateCompatibleDC(None)
win32gui.SelectObject(dcDC, hbitmap)
win32gui.StretchBlt(
dc,
0,
0,
wndwidth,
wndheight,
dcDC,
0,
0,
bminfo.bmWidth,
bminfo.bmHeight,
win32con.SRCCOPY,
)
win32gui.DeleteDC(dcDC)
win32gui.EndPaint(hwnd, ps)
finally:
win32clipboard.CloseClipboard()
return 0
def OnDrawClipboard(self, hwnd, msg, wp, lp):
win32gui.InvalidateRect(hwnd, None, True)
def OnChangeCBChain(self, hwnd, msg, wp, lp):
# If the next window is closing, repair the chain.
if wp == self.hwndNextViewer:
self.hwndNextViewer = lp
# Otherwise, pass the message to the next link.
elif self.hwndNextViewer:
win32gui.SendMessage(self.hwndNextViewer, msg, wp, lp)
def OnCreate(self, hwnd, msg, wp, lp):
self.hwndNextViewer = win32gui.SetClipboardViewer(hwnd)
def OnClose(self, hwnd, msg, wp, lp):
win32clipboard.ChangeClipboardChain(hwnd, self.hwndNextViewer)
win32gui.DestroyWindow(hwnd)
win32gui.PostQuitMessage(0)
def go(self):
wndproc = {
win32con.WM_PAINT: self.OnPaint,
win32con.WM_CLOSE: self.OnClose,
win32con.WM_CREATE: self.OnCreate,
win32con.WM_DRAWCLIPBOARD: self.OnDrawClipboard,
win32con.WM_CHANGECBCHAIN: self.OnChangeCBChain,
}
wc = win32gui.WNDCLASS()
wc.lpszClassName = "test_win32clipboard_bmp"
wc.style = win32con.CS_GLOBALCLASS | win32con.CS_VREDRAW | win32con.CS_HREDRAW
wc.hbrBackground = win32con.COLOR_WINDOW + 1
wc.lpfnWndProc = wndproc
class_atom = win32gui.RegisterClass(wc)
hwnd = win32gui.CreateWindowEx(
0,
class_atom,
"ClipboardViewer",
win32con.WS_CAPTION
| win32con.WS_VISIBLE
| win32con.WS_THICKFRAME
| win32con.WS_SYSMENU,
100,
100,
900,
900,
0,
0,
0,
None,
)
win32clipboard.SetClipboardViewer(hwnd)
win32gui.PumpMessages()
win32gui.UnregisterClass(class_atom, None)
if __name__ == "__main__":
w = ViewerWindow()
w.go()

View file

@ -0,0 +1,144 @@
# This is a simple serial port terminal demo.
#
# Its primary purpose is to demonstrate the native serial port access offered via
# win32file.
# It uses 3 threads:
# - The main thread, which cranks up the other 2 threads, then simply waits for them to exit.
# - The user-input thread - blocks waiting for a keyboard character, and when found sends it
# out the COM port. If the character is Ctrl+C, it stops, signalling the COM port thread to stop.
# - The COM port thread is simply listening for input on the COM port, and prints it to the screen.
# This demo uses userlapped IO, so that none of the read or write operations actually block (however,
# in this sample, the very next thing we do _is_ block - so it shows off the concepts even though it
# doesnt exploit them.
import msvcrt # For the getch() function.
import sys
import threading
import win32con # constants.
from win32event import * # We use events and the WaitFor[Multiple]Objects functions.
from win32file import * # The base COM port and file IO functions.
def FindModem():
# Snoop over the comports, seeing if it is likely we have a modem.
for i in range(1, 5):
port = "COM%d" % (i,)
try:
handle = CreateFile(
port,
win32con.GENERIC_READ | win32con.GENERIC_WRITE,
0, # exclusive access
None, # no security
win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL,
None,
)
# It appears that an available COM port will always success here,
# just return 0 for the status flags. We only care that it has _any_ status
# flags (and therefore probably a real modem)
if GetCommModemStatus(handle) != 0:
return port
except error:
pass # No port, or modem status failed.
return None
# A basic synchronous COM port file-like object
class SerialTTY:
def __init__(self, port):
if type(port) == type(0):
port = "COM%d" % (port,)
self.handle = CreateFile(
port,
win32con.GENERIC_READ | win32con.GENERIC_WRITE,
0, # exclusive access
None, # no security
win32con.OPEN_EXISTING,
win32con.FILE_ATTRIBUTE_NORMAL | win32con.FILE_FLAG_OVERLAPPED,
None,
)
# Tell the port we want a notification on each char.
SetCommMask(self.handle, EV_RXCHAR)
# Setup a 4k buffer
SetupComm(self.handle, 4096, 4096)
# Remove anything that was there
PurgeComm(
self.handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR
)
# Setup for overlapped IO.
timeouts = 0xFFFFFFFF, 0, 1000, 0, 1000
SetCommTimeouts(self.handle, timeouts)
# Setup the connection info.
dcb = GetCommState(self.handle)
dcb.BaudRate = CBR_115200
dcb.ByteSize = 8
dcb.Parity = NOPARITY
dcb.StopBits = ONESTOPBIT
SetCommState(self.handle, dcb)
print("Connected to %s at %s baud" % (port, dcb.BaudRate))
def _UserInputReaderThread(self):
overlapped = OVERLAPPED()
overlapped.hEvent = CreateEvent(None, 1, 0, None)
try:
while 1:
ch = msvcrt.getch()
if ord(ch) == 3:
break
WriteFile(self.handle, ch, overlapped)
# Wait for the write to complete.
WaitForSingleObject(overlapped.hEvent, INFINITE)
finally:
SetEvent(self.eventStop)
def _ComPortThread(self):
overlapped = OVERLAPPED()
overlapped.hEvent = CreateEvent(None, 1, 0, None)
while 1:
# XXX - note we could _probably_ just use overlapped IO on the win32file.ReadFile() statement
# XXX but this tests the COM stuff!
rc, mask = WaitCommEvent(self.handle, overlapped)
if rc == 0: # Character already ready!
SetEvent(overlapped.hEvent)
rc = WaitForMultipleObjects(
[overlapped.hEvent, self.eventStop], 0, INFINITE
)
if rc == WAIT_OBJECT_0:
# Some input - read and print it
flags, comstat = ClearCommError(self.handle)
rc, data = ReadFile(self.handle, comstat.cbInQue, overlapped)
WaitForSingleObject(overlapped.hEvent, INFINITE)
sys.stdout.write(data)
else:
# Stop the thread!
# Just incase the user input thread uis still going, close it
sys.stdout.close()
break
def Run(self):
self.eventStop = CreateEvent(None, 0, 0, None)
# Start the reader and writer threads.
user_thread = threading.Thread(target=self._UserInputReaderThread)
user_thread.start()
com_thread = threading.Thread(target=self._ComPortThread)
com_thread.start()
user_thread.join()
com_thread.join()
if __name__ == "__main__":
print("Serial port terminal demo - press Ctrl+C to exit")
if len(sys.argv) <= 1:
port = FindModem()
if port is None:
print("No COM port specified, and no modem could be found")
print("Please re-run this script with the name of a COM port (eg COM3)")
sys.exit(1)
else:
port = sys.argv[1]
tty = SerialTTY(port)
tty.Run()

View file

@ -0,0 +1,135 @@
import time
import win32con
import win32console
virtual_keys = {}
for k, v in list(win32con.__dict__.items()):
if k.startswith("VK_"):
virtual_keys[v] = k
free_console = True
try:
win32console.AllocConsole()
except win32console.error as exc:
if exc.winerror != 5:
raise
## only free console if one was created successfully
free_console = False
stdout = win32console.GetStdHandle(win32console.STD_OUTPUT_HANDLE)
stdin = win32console.GetStdHandle(win32console.STD_INPUT_HANDLE)
newbuffer = win32console.CreateConsoleScreenBuffer()
newbuffer.SetConsoleActiveScreenBuffer()
newbuffer.SetConsoleTextAttribute(
win32console.FOREGROUND_RED
| win32console.FOREGROUND_INTENSITY
| win32console.BACKGROUND_GREEN
| win32console.BACKGROUND_INTENSITY
)
newbuffer.WriteConsole("This is a new screen buffer\n")
## test setting screen buffer and window size
## screen buffer size cannot be smaller than window size
window_size = newbuffer.GetConsoleScreenBufferInfo()["Window"]
coord = win32console.PyCOORDType(X=window_size.Right + 20, Y=window_size.Bottom + 20)
newbuffer.SetConsoleScreenBufferSize(coord)
window_size.Right += 10
window_size.Bottom += 10
newbuffer.SetConsoleWindowInfo(Absolute=True, ConsoleWindow=window_size)
## write some records to the input queue
x = win32console.PyINPUT_RECORDType(win32console.KEY_EVENT)
x.Char = "X"
x.KeyDown = True
x.RepeatCount = 1
x.VirtualKeyCode = 0x58
x.ControlKeyState = win32con.SHIFT_PRESSED
z = win32console.PyINPUT_RECORDType(win32console.KEY_EVENT)
z.Char = "Z"
z.KeyDown = True
z.RepeatCount = 1
z.VirtualKeyCode = 0x5A
z.ControlKeyState = win32con.SHIFT_PRESSED
stdin.WriteConsoleInput([x, z, x])
newbuffer.SetConsoleTextAttribute(
win32console.FOREGROUND_RED
| win32console.FOREGROUND_INTENSITY
| win32console.BACKGROUND_GREEN
| win32console.BACKGROUND_INTENSITY
)
newbuffer.WriteConsole("Press some keys, click some characters with the mouse\n")
newbuffer.SetConsoleTextAttribute(
win32console.FOREGROUND_BLUE
| win32console.FOREGROUND_INTENSITY
| win32console.BACKGROUND_RED
| win32console.BACKGROUND_INTENSITY
)
newbuffer.WriteConsole('Hit "End" key to quit\n')
breakout = False
while not breakout:
input_records = stdin.ReadConsoleInput(10)
for input_record in input_records:
if input_record.EventType == win32console.KEY_EVENT:
if input_record.KeyDown:
if input_record.Char == "\0":
newbuffer.WriteConsole(
virtual_keys.get(
input_record.VirtualKeyCode,
"VirtualKeyCode: %s" % input_record.VirtualKeyCode,
)
)
else:
newbuffer.WriteConsole(input_record.Char)
if input_record.VirtualKeyCode == win32con.VK_END:
breakout = True
break
elif input_record.EventType == win32console.MOUSE_EVENT:
if input_record.EventFlags == 0: ## 0 indicates a button event
if input_record.ButtonState != 0: ## exclude button releases
pos = input_record.MousePosition
# switch the foreground and background colors of the character that was clicked
attr = newbuffer.ReadConsoleOutputAttribute(
Length=1, ReadCoord=pos
)[0]
new_attr = attr
if attr & win32console.FOREGROUND_BLUE:
new_attr = (
new_attr & ~win32console.FOREGROUND_BLUE
) | win32console.BACKGROUND_BLUE
if attr & win32console.FOREGROUND_RED:
new_attr = (
new_attr & ~win32console.FOREGROUND_RED
) | win32console.BACKGROUND_RED
if attr & win32console.FOREGROUND_GREEN:
new_attr = (
new_attr & ~win32console.FOREGROUND_GREEN
) | win32console.BACKGROUND_GREEN
if attr & win32console.BACKGROUND_BLUE:
new_attr = (
new_attr & ~win32console.BACKGROUND_BLUE
) | win32console.FOREGROUND_BLUE
if attr & win32console.BACKGROUND_RED:
new_attr = (
new_attr & ~win32console.BACKGROUND_RED
) | win32console.FOREGROUND_RED
if attr & win32console.BACKGROUND_GREEN:
new_attr = (
new_attr & ~win32console.BACKGROUND_GREEN
) | win32console.FOREGROUND_GREEN
newbuffer.WriteConsoleOutputAttribute((new_attr,), pos)
else:
newbuffer.WriteConsole(str(input_record))
time.sleep(0.1)
stdout.SetConsoleActiveScreenBuffer()
newbuffer.Close()
if free_console:
win32console.FreeConsole()

View file

@ -0,0 +1,82 @@
"""
Demonstrates prompting for credentials, saving, and loggging on with marshalled credential.
Also shows how to load user's profile
"""
import win32api
import win32con
import win32cred
import win32net
import win32profile
import win32security
## Prompt for a username/pwd for local computer
uiinfo = {
"MessageText": "Enter credentials for local machine",
"CaptionText": "win32cred_demo.py",
}
target, pwd, save = win32cred.CredUIPromptForCredentials(
TargetName=win32api.GetComputerName(),
AuthError=0,
Flags=win32cred.CREDUI_FLAGS_DO_NOT_PERSIST
| win32cred.CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX,
Save=False,
UiInfo=uiinfo,
)
attrs = [
{"Keyword": "attr1", "Flags": 0, "Value": "unicode data"},
{"Keyword": "attr2", "Flags": 0, "Value": b"character data"},
]
cred = {
"Comment": "Created by win32cred_demo.py",
"UserName": target,
"TargetAlias": None,
"TargetName": target,
"CredentialBlob": pwd,
"Flags": win32cred.CRED_FLAGS_USERNAME_TARGET,
"Persist": win32cred.CRED_PERSIST_ENTERPRISE,
"Type": win32cred.CRED_TYPE_DOMAIN_PASSWORD,
"Attributes": attrs,
}
win32cred.CredWrite(cred)
pwd = None
print(win32cred.CredRead(target, win32cred.CRED_TYPE_DOMAIN_PASSWORD))
## Marshal saved credential and use it to log on
mc = win32cred.CredMarshalCredential(win32cred.UsernameTargetCredential, target)
# As of pywin32 301 this no longer works for markh and unclear when it stopped, or
# even if it ever did! # Fails in Python 2.7 too, so not a 3.x regression.
try:
th = win32security.LogonUser(
mc,
None,
"",
win32con.LOGON32_LOGON_INTERACTIVE,
win32con.LOGON32_PROVIDER_DEFAULT,
)
win32security.ImpersonateLoggedOnUser(th)
print("GetUserName:", win32api.GetUserName())
win32security.RevertToSelf()
## Load user's profile. (first check if user has a roaming profile)
username, domain = win32cred.CredUIParseUserName(target)
user_info_4 = win32net.NetUserGetInfo(None, username, 4)
profilepath = user_info_4["profile"]
## LoadUserProfile apparently doesn't like an empty string
if not profilepath:
profilepath = None
## leave Flags in since 2.3 still chokes on some types of optional keyword args
hk = win32profile.LoadUserProfile(
th, {"UserName": username, "Flags": 0, "ProfilePath": profilepath}
)
## Get user's environment variables in a form that can be passed to win32process.CreateProcessAsUser
env = win32profile.CreateEnvironmentBlock(th, False)
## Cleanup should probably be in a finally block
win32profile.UnloadUserProfile(th, hk)
th.Close()
except win32security.error as exc:
print("Failed to login for some reason", exc)

View file

@ -0,0 +1,41 @@
# This is a "demo" of win32file - it used to be more a test case than a
# demo, so has been moved to the test directory.
import os
# Please contribute your favourite simple little demo.
import win32api
import win32con
import win32file
# A very simple demo - note that this does no more than you can do with
# builtin Python file objects, so for something as simple as this, you
# generally *should* use builtin Python objects. Only use win32file etc
# when you need win32 specific features not available in Python.
def SimpleFileDemo():
testName = os.path.join(win32api.GetTempPath(), "win32file_demo_test_file")
if os.path.exists(testName):
os.unlink(testName)
# Open the file for writing.
handle = win32file.CreateFile(
testName, win32file.GENERIC_WRITE, 0, None, win32con.CREATE_NEW, 0, None
)
test_data = "Hello\0there".encode("ascii")
win32file.WriteFile(handle, test_data)
handle.Close()
# Open it for reading.
handle = win32file.CreateFile(
testName, win32file.GENERIC_READ, 0, None, win32con.OPEN_EXISTING, 0, None
)
rc, data = win32file.ReadFile(handle, 1024)
handle.Close()
if data == test_data:
print("Successfully wrote and read a file")
else:
raise Exception("Got different data back???")
os.unlink(testName)
if __name__ == "__main__":
SimpleFileDemo()

View file

@ -0,0 +1,177 @@
# The start of a win32gui generic demo.
# Feel free to contribute more demos back ;-)
import math
import random
import time
import win32api
import win32con
import win32gui
def _MyCallback(hwnd, extra):
hwnds, classes = extra
hwnds.append(hwnd)
classes[win32gui.GetClassName(hwnd)] = 1
def TestEnumWindows():
windows = []
classes = {}
win32gui.EnumWindows(_MyCallback, (windows, classes))
print(
"Enumerated a total of %d windows with %d classes"
% (len(windows), len(classes))
)
if "tooltips_class32" not in classes:
print("Hrmmmm - I'm very surprised to not find a 'tooltips_class32' class.")
def OnPaint_1(hwnd, msg, wp, lp):
dc, ps = win32gui.BeginPaint(hwnd)
win32gui.SetGraphicsMode(dc, win32con.GM_ADVANCED)
br = win32gui.CreateSolidBrush(win32api.RGB(255, 0, 0))
win32gui.SelectObject(dc, br)
angle = win32gui.GetWindowLong(hwnd, win32con.GWL_USERDATA)
win32gui.SetWindowLong(hwnd, win32con.GWL_USERDATA, angle + 2)
r_angle = angle * (math.pi / 180)
win32gui.SetWorldTransform(
dc,
{
"M11": math.cos(r_angle),
"M12": math.sin(r_angle),
"M21": math.sin(r_angle) * -1,
"M22": math.cos(r_angle),
"Dx": 250,
"Dy": 250,
},
)
win32gui.MoveToEx(dc, 250, 250)
win32gui.BeginPath(dc)
win32gui.Pie(dc, 10, 70, 200, 200, 350, 350, 75, 10)
win32gui.Chord(dc, 200, 200, 850, 0, 350, 350, 75, 10)
win32gui.LineTo(dc, 300, 300)
win32gui.LineTo(dc, 100, 20)
win32gui.LineTo(dc, 20, 100)
win32gui.LineTo(dc, 400, 0)
win32gui.LineTo(dc, 0, 400)
win32gui.EndPath(dc)
win32gui.StrokeAndFillPath(dc)
win32gui.EndPaint(hwnd, ps)
return 0
wndproc_1 = {win32con.WM_PAINT: OnPaint_1}
def OnPaint_2(hwnd, msg, wp, lp):
dc, ps = win32gui.BeginPaint(hwnd)
win32gui.SetGraphicsMode(dc, win32con.GM_ADVANCED)
l, t, r, b = win32gui.GetClientRect(hwnd)
for x in range(25):
vertices = (
{
"x": int(random.random() * r),
"y": int(random.random() * b),
"Red": int(random.random() * 0xFF00),
"Green": 0,
"Blue": 0,
"Alpha": 0,
},
{
"x": int(random.random() * r),
"y": int(random.random() * b),
"Red": 0,
"Green": int(random.random() * 0xFF00),
"Blue": 0,
"Alpha": 0,
},
{
"x": int(random.random() * r),
"y": int(random.random() * b),
"Red": 0,
"Green": 0,
"Blue": int(random.random() * 0xFF00),
"Alpha": 0,
},
)
mesh = ((0, 1, 2),)
win32gui.GradientFill(dc, vertices, mesh, win32con.GRADIENT_FILL_TRIANGLE)
win32gui.EndPaint(hwnd, ps)
return 0
wndproc_2 = {win32con.WM_PAINT: OnPaint_2}
def TestSetWorldTransform():
wc = win32gui.WNDCLASS()
wc.lpszClassName = "test_win32gui_1"
wc.style = win32con.CS_GLOBALCLASS | win32con.CS_VREDRAW | win32con.CS_HREDRAW
wc.hbrBackground = win32con.COLOR_WINDOW + 1
wc.lpfnWndProc = wndproc_1
class_atom = win32gui.RegisterClass(wc)
hwnd = win32gui.CreateWindow(
wc.lpszClassName,
"Spin the Lobster!",
win32con.WS_CAPTION | win32con.WS_VISIBLE,
100,
100,
900,
900,
0,
0,
0,
None,
)
for x in range(500):
win32gui.InvalidateRect(hwnd, None, True)
win32gui.PumpWaitingMessages()
time.sleep(0.01)
win32gui.DestroyWindow(hwnd)
win32gui.UnregisterClass(wc.lpszClassName, None)
def TestGradientFill():
wc = win32gui.WNDCLASS()
wc.lpszClassName = "test_win32gui_2"
wc.style = win32con.CS_GLOBALCLASS | win32con.CS_VREDRAW | win32con.CS_HREDRAW
wc.hbrBackground = win32con.COLOR_WINDOW + 1
wc.lpfnWndProc = wndproc_2
class_atom = win32gui.RegisterClass(wc)
hwnd = win32gui.CreateWindowEx(
0,
class_atom,
"Kaleidoscope",
win32con.WS_CAPTION
| win32con.WS_VISIBLE
| win32con.WS_THICKFRAME
| win32con.WS_SYSMENU,
100,
100,
900,
900,
0,
0,
0,
None,
)
s = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, s | win32con.WS_EX_LAYERED)
win32gui.SetLayeredWindowAttributes(hwnd, 0, 175, win32con.LWA_ALPHA)
for x in range(30):
win32gui.InvalidateRect(hwnd, None, True)
win32gui.PumpWaitingMessages()
time.sleep(0.3)
win32gui.DestroyWindow(hwnd)
win32gui.UnregisterClass(class_atom, None)
print("Enumerating all windows...")
TestEnumWindows()
print("Testing drawing functions ...")
TestSetWorldTransform()
TestGradientFill()
print("All tests done!")

View file

@ -0,0 +1,107 @@
# Demo RegisterDeviceNotification etc. Creates a hidden window to receive
# notifications. See serviceEvents.py for an example of a service doing
# that.
import sys
import time
import win32api
import win32con
import win32file
import win32gui
import win32gui_struct
import winnt
# These device GUIDs are from Ioevent.h in the Windows SDK. Ideally they
# could be collected somewhere for pywin32...
GUID_DEVINTERFACE_USB_DEVICE = "{A5DCBF10-6530-11D2-901F-00C04FB951ED}"
# WM_DEVICECHANGE message handler.
def OnDeviceChange(hwnd, msg, wp, lp):
# Unpack the 'lp' into the appropriate DEV_BROADCAST_* structure,
# using the self-identifying data inside the DEV_BROADCAST_HDR.
info = win32gui_struct.UnpackDEV_BROADCAST(lp)
print("Device change notification:", wp, str(info))
if (
wp == win32con.DBT_DEVICEQUERYREMOVE
and info.devicetype == win32con.DBT_DEVTYP_HANDLE
):
# Our handle is stored away in the structure - just close it
print("Device being removed - closing handle")
win32file.CloseHandle(info.handle)
# and cancel our notifications - if it gets plugged back in we get
# the same notification and try and close the same handle...
win32gui.UnregisterDeviceNotification(info.hdevnotify)
return True
def TestDeviceNotifications(dir_names):
wc = win32gui.WNDCLASS()
wc.lpszClassName = "test_devicenotify"
wc.style = win32con.CS_GLOBALCLASS | win32con.CS_VREDRAW | win32con.CS_HREDRAW
wc.hbrBackground = win32con.COLOR_WINDOW + 1
wc.lpfnWndProc = {win32con.WM_DEVICECHANGE: OnDeviceChange}
class_atom = win32gui.RegisterClass(wc)
hwnd = win32gui.CreateWindow(
wc.lpszClassName,
"Testing some devices",
# no need for it to be visible.
win32con.WS_CAPTION,
100,
100,
900,
900,
0,
0,
0,
None,
)
hdevs = []
# Watch for all USB device notifications
filter = win32gui_struct.PackDEV_BROADCAST_DEVICEINTERFACE(
GUID_DEVINTERFACE_USB_DEVICE
)
hdev = win32gui.RegisterDeviceNotification(
hwnd, filter, win32con.DEVICE_NOTIFY_WINDOW_HANDLE
)
hdevs.append(hdev)
# and create handles for all specified directories
for d in dir_names:
hdir = win32file.CreateFile(
d,
winnt.FILE_LIST_DIRECTORY,
winnt.FILE_SHARE_READ | winnt.FILE_SHARE_WRITE | winnt.FILE_SHARE_DELETE,
None, # security attributes
win32con.OPEN_EXISTING,
win32con.FILE_FLAG_BACKUP_SEMANTICS
| win32con.FILE_FLAG_OVERLAPPED, # required privileges: SE_BACKUP_NAME and SE_RESTORE_NAME.
None,
)
filter = win32gui_struct.PackDEV_BROADCAST_HANDLE(hdir)
hdev = win32gui.RegisterDeviceNotification(
hwnd, filter, win32con.DEVICE_NOTIFY_WINDOW_HANDLE
)
hdevs.append(hdev)
# now start a message pump and wait for messages to be delivered.
print("Watching", len(hdevs), "handles - press Ctrl+C to terminate, or")
print("add and remove some USB devices...")
if not dir_names:
print("(Note you can also pass paths to watch on the command-line - eg,")
print("pass the root of an inserted USB stick to see events specific to")
print("that volume)")
while 1:
win32gui.PumpWaitingMessages()
time.sleep(0.01)
win32gui.DestroyWindow(hwnd)
win32gui.UnregisterClass(wc.lpszClassName, None)
if __name__ == "__main__":
# optionally pass device/directory names to watch for notifications.
# Eg, plug in a USB device - assume it connects as E: - then execute:
# % win32gui_devicenotify.py E:
# Then remove and insert the device.
TestDeviceNotifications(sys.argv[1:])

View file

@ -0,0 +1,458 @@
# A demo of a fairly complex dialog.
#
# Features:
# * Uses a "dynamic dialog resource" to build the dialog.
# * Uses a ListView control.
# * Dynamically resizes content.
# * Uses a second worker thread to fill the list.
# * Demostrates support for windows XP themes.
# If you are on Windows XP, and specify a '--noxp' argument, you will see:
# * alpha-blend issues with icons
# * The buttons are "old" style, rather than based on the XP theme.
# Hence, using:
# import winxpgui as win32gui
# is recommended.
# Please report any problems.
import sys
if "--noxp" in sys.argv:
import win32gui
else:
import winxpgui as win32gui
import array
import os
import queue
import struct
import commctrl
import win32api
import win32con
import win32gui_struct
import winerror
IDC_SEARCHTEXT = 1024
IDC_BUTTON_SEARCH = 1025
IDC_BUTTON_DISPLAY = 1026
IDC_LISTBOX = 1027
WM_SEARCH_RESULT = win32con.WM_USER + 512
WM_SEARCH_FINISHED = win32con.WM_USER + 513
class _WIN32MASKEDSTRUCT:
def __init__(self, **kw):
full_fmt = ""
for name, fmt, default, mask in self._struct_items_:
self.__dict__[name] = None
if fmt == "z":
full_fmt += "pi"
else:
full_fmt += fmt
for name, val in kw.items():
if name not in self.__dict__:
raise ValueError("LVITEM structures do not have an item '%s'" % (name,))
self.__dict__[name] = val
def __setattr__(self, attr, val):
if not attr.startswith("_") and attr not in self.__dict__:
raise AttributeError(attr)
self.__dict__[attr] = val
def toparam(self):
self._buffs = []
full_fmt = ""
vals = []
mask = 0
# calc the mask
for name, fmt, default, this_mask in self._struct_items_:
if this_mask is not None and self.__dict__.get(name) is not None:
mask |= this_mask
self.mask = mask
for name, fmt, default, this_mask in self._struct_items_:
val = self.__dict__[name]
if fmt == "z":
fmt = "Pi"
if val is None:
vals.append(0)
vals.append(0)
else:
# Note this demo still works with byte strings. An
# alternate strategy would be to use unicode natively
# and use the 'W' version of the messages - eg,
# LVM_SETITEMW etc.
val = val + "\0"
if isinstance(val, str):
val = val.encode("mbcs")
str_buf = array.array("b", val)
vals.append(str_buf.buffer_info()[0])
vals.append(len(val))
self._buffs.append(str_buf) # keep alive during the call.
else:
if val is None:
val = default
vals.append(val)
full_fmt += fmt
return struct.pack(*(full_fmt,) + tuple(vals))
# NOTE: See the win32gui_struct module for an alternative way of dealing
# with these structures
class LVITEM(_WIN32MASKEDSTRUCT):
_struct_items_ = [
("mask", "I", 0, None),
("iItem", "i", 0, None),
("iSubItem", "i", 0, None),
("state", "I", 0, commctrl.LVIF_STATE),
("stateMask", "I", 0, None),
("text", "z", None, commctrl.LVIF_TEXT),
("iImage", "i", 0, commctrl.LVIF_IMAGE),
("lParam", "i", 0, commctrl.LVIF_PARAM),
("iIdent", "i", 0, None),
]
class LVCOLUMN(_WIN32MASKEDSTRUCT):
_struct_items_ = [
("mask", "I", 0, None),
("fmt", "i", 0, commctrl.LVCF_FMT),
("cx", "i", 0, commctrl.LVCF_WIDTH),
("text", "z", None, commctrl.LVCF_TEXT),
("iSubItem", "i", 0, commctrl.LVCF_SUBITEM),
("iImage", "i", 0, commctrl.LVCF_IMAGE),
("iOrder", "i", 0, commctrl.LVCF_ORDER),
]
class DemoWindowBase:
def __init__(self):
win32gui.InitCommonControls()
self.hinst = win32gui.dllhandle
self.list_data = {}
def _RegisterWndClass(self):
className = "PythonDocSearch"
message_map = {}
wc = win32gui.WNDCLASS()
wc.SetDialogProc() # Make it a dialog class.
wc.hInstance = self.hinst
wc.lpszClassName = className
wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW
wc.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)
wc.hbrBackground = win32con.COLOR_WINDOW + 1
wc.lpfnWndProc = message_map # could also specify a wndproc.
# C code: wc.cbWndExtra = DLGWINDOWEXTRA + sizeof(HBRUSH) + (sizeof(COLORREF));
wc.cbWndExtra = win32con.DLGWINDOWEXTRA + struct.calcsize("Pi")
icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
## py.ico went away in python 2.5, load from executable instead
this_app = win32api.GetModuleHandle(None)
try:
wc.hIcon = win32gui.LoadIcon(this_app, 1) ## python.exe and pythonw.exe
except win32gui.error:
wc.hIcon = win32gui.LoadIcon(this_app, 135) ## pythonwin's icon
try:
classAtom = win32gui.RegisterClass(wc)
except win32gui.error as err_info:
if err_info.winerror != winerror.ERROR_CLASS_ALREADY_EXISTS:
raise
return className
def _GetDialogTemplate(self, dlgClassName):
style = (
win32con.WS_THICKFRAME
| win32con.WS_POPUP
| win32con.WS_VISIBLE
| win32con.WS_CAPTION
| win32con.WS_SYSMENU
| win32con.DS_SETFONT
| win32con.WS_MINIMIZEBOX
)
cs = win32con.WS_CHILD | win32con.WS_VISIBLE
title = "Dynamic Dialog Demo"
# Window frame and title
dlg = [
[
title,
(0, 0, 210, 250),
style,
None,
(8, "MS Sans Serif"),
None,
dlgClassName,
],
]
# ID label and text box
dlg.append([130, "Enter something", -1, (5, 5, 200, 9), cs | win32con.SS_LEFT])
s = cs | win32con.WS_TABSTOP | win32con.WS_BORDER
dlg.append(["EDIT", None, IDC_SEARCHTEXT, (5, 15, 200, 12), s])
# Search/Display Buttons
# (x positions don't matter here)
s = cs | win32con.WS_TABSTOP
dlg.append(
[
128,
"Fill List",
IDC_BUTTON_SEARCH,
(5, 35, 50, 14),
s | win32con.BS_DEFPUSHBUTTON,
]
)
s = win32con.BS_PUSHBUTTON | s
dlg.append([128, "Display", IDC_BUTTON_DISPLAY, (100, 35, 50, 14), s])
# List control.
# Can't make this work :(
## s = cs | win32con.WS_TABSTOP
## dlg.append(['SysListView32', "Title", IDC_LISTBOX, (5, 505, 200, 200), s])
return dlg
def _DoCreate(self, fn):
message_map = {
win32con.WM_SIZE: self.OnSize,
win32con.WM_COMMAND: self.OnCommand,
win32con.WM_NOTIFY: self.OnNotify,
win32con.WM_INITDIALOG: self.OnInitDialog,
win32con.WM_CLOSE: self.OnClose,
win32con.WM_DESTROY: self.OnDestroy,
WM_SEARCH_RESULT: self.OnSearchResult,
WM_SEARCH_FINISHED: self.OnSearchFinished,
}
dlgClassName = self._RegisterWndClass()
template = self._GetDialogTemplate(dlgClassName)
return fn(self.hinst, template, 0, message_map)
def _SetupList(self):
child_style = (
win32con.WS_CHILD
| win32con.WS_VISIBLE
| win32con.WS_BORDER
| win32con.WS_HSCROLL
| win32con.WS_VSCROLL
)
child_style |= (
commctrl.LVS_SINGLESEL | commctrl.LVS_SHOWSELALWAYS | commctrl.LVS_REPORT
)
self.hwndList = win32gui.CreateWindow(
"SysListView32",
None,
child_style,
0,
0,
100,
100,
self.hwnd,
IDC_LISTBOX,
self.hinst,
None,
)
child_ex_style = win32gui.SendMessage(
self.hwndList, commctrl.LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0
)
child_ex_style |= commctrl.LVS_EX_FULLROWSELECT
win32gui.SendMessage(
self.hwndList, commctrl.LVM_SETEXTENDEDLISTVIEWSTYLE, 0, child_ex_style
)
# Add an image list - use the builtin shell folder icon - this
# demonstrates the problem with alpha-blending of icons on XP if
# winxpgui is not used in place of win32gui.
il = win32gui.ImageList_Create(
win32api.GetSystemMetrics(win32con.SM_CXSMICON),
win32api.GetSystemMetrics(win32con.SM_CYSMICON),
commctrl.ILC_COLOR32 | commctrl.ILC_MASK,
1, # initial size
0,
) # cGrow
shell_dll = os.path.join(win32api.GetSystemDirectory(), "shell32.dll")
large, small = win32gui.ExtractIconEx(shell_dll, 4, 1)
win32gui.ImageList_ReplaceIcon(il, -1, small[0])
win32gui.DestroyIcon(small[0])
win32gui.DestroyIcon(large[0])
win32gui.SendMessage(
self.hwndList, commctrl.LVM_SETIMAGELIST, commctrl.LVSIL_SMALL, il
)
# Setup the list control columns.
lvc = LVCOLUMN(
mask=commctrl.LVCF_FMT
| commctrl.LVCF_WIDTH
| commctrl.LVCF_TEXT
| commctrl.LVCF_SUBITEM
)
lvc.fmt = commctrl.LVCFMT_LEFT
lvc.iSubItem = 1
lvc.text = "Title"
lvc.cx = 200
win32gui.SendMessage(self.hwndList, commctrl.LVM_INSERTCOLUMN, 0, lvc.toparam())
lvc.iSubItem = 0
lvc.text = "Order"
lvc.cx = 50
win32gui.SendMessage(self.hwndList, commctrl.LVM_INSERTCOLUMN, 0, lvc.toparam())
win32gui.UpdateWindow(self.hwnd)
def ClearListItems(self):
win32gui.SendMessage(self.hwndList, commctrl.LVM_DELETEALLITEMS)
self.list_data = {}
def AddListItem(self, data, *columns):
num_items = win32gui.SendMessage(self.hwndList, commctrl.LVM_GETITEMCOUNT)
item = LVITEM(text=columns[0], iItem=num_items)
new_index = win32gui.SendMessage(
self.hwndList, commctrl.LVM_INSERTITEM, 0, item.toparam()
)
col_no = 1
for col in columns[1:]:
item = LVITEM(text=col, iItem=new_index, iSubItem=col_no)
win32gui.SendMessage(self.hwndList, commctrl.LVM_SETITEM, 0, item.toparam())
col_no += 1
self.list_data[new_index] = data
def OnInitDialog(self, hwnd, msg, wparam, lparam):
self.hwnd = hwnd
# centre the dialog
desktop = win32gui.GetDesktopWindow()
l, t, r, b = win32gui.GetWindowRect(self.hwnd)
dt_l, dt_t, dt_r, dt_b = win32gui.GetWindowRect(desktop)
centre_x, centre_y = win32gui.ClientToScreen(
desktop, ((dt_r - dt_l) // 2, (dt_b - dt_t) // 2)
)
win32gui.MoveWindow(
hwnd, centre_x - (r // 2), centre_y - (b // 2), r - l, b - t, 0
)
self._SetupList()
l, t, r, b = win32gui.GetClientRect(self.hwnd)
self._DoSize(r - l, b - t, 1)
def _DoSize(self, cx, cy, repaint=1):
# right-justify the textbox.
ctrl = win32gui.GetDlgItem(self.hwnd, IDC_SEARCHTEXT)
l, t, r, b = win32gui.GetWindowRect(ctrl)
l, t = win32gui.ScreenToClient(self.hwnd, (l, t))
r, b = win32gui.ScreenToClient(self.hwnd, (r, b))
win32gui.MoveWindow(ctrl, l, t, cx - l - 5, b - t, repaint)
# The button.
ctrl = win32gui.GetDlgItem(self.hwnd, IDC_BUTTON_DISPLAY)
l, t, r, b = win32gui.GetWindowRect(ctrl)
l, t = win32gui.ScreenToClient(self.hwnd, (l, t))
r, b = win32gui.ScreenToClient(self.hwnd, (r, b))
list_y = b + 10
w = r - l
win32gui.MoveWindow(ctrl, cx - 5 - w, t, w, b - t, repaint)
# The list control
win32gui.MoveWindow(self.hwndList, 0, list_y, cx, cy - list_y, repaint)
# The last column of the list control.
new_width = cx - win32gui.SendMessage(
self.hwndList, commctrl.LVM_GETCOLUMNWIDTH, 0
)
win32gui.SendMessage(self.hwndList, commctrl.LVM_SETCOLUMNWIDTH, 1, new_width)
def OnSize(self, hwnd, msg, wparam, lparam):
x = win32api.LOWORD(lparam)
y = win32api.HIWORD(lparam)
self._DoSize(x, y)
return 1
def OnSearchResult(self, hwnd, msg, wparam, lparam):
try:
while 1:
params = self.result_queue.get(0)
self.AddListItem(*params)
except queue.Empty:
pass
def OnSearchFinished(self, hwnd, msg, wparam, lparam):
print("OnSearchFinished")
def OnNotify(self, hwnd, msg, wparam, lparam):
info = win32gui_struct.UnpackNMITEMACTIVATE(lparam)
if info.code == commctrl.NM_DBLCLK:
print("Double click on item", info.iItem + 1)
return 1
def OnCommand(self, hwnd, msg, wparam, lparam):
id = win32api.LOWORD(wparam)
if id == IDC_BUTTON_SEARCH:
self.ClearListItems()
def fill_slowly(q, hwnd):
import time
for i in range(20):
q.put(("whatever", str(i + 1), "Search result " + str(i)))
win32gui.PostMessage(hwnd, WM_SEARCH_RESULT, 0, 0)
time.sleep(0.25)
win32gui.PostMessage(hwnd, WM_SEARCH_FINISHED, 0, 0)
import threading
self.result_queue = queue.Queue()
thread = threading.Thread(
target=fill_slowly, args=(self.result_queue, self.hwnd)
)
thread.start()
elif id == IDC_BUTTON_DISPLAY:
print("Display button selected")
sel = win32gui.SendMessage(
self.hwndList, commctrl.LVM_GETNEXTITEM, -1, commctrl.LVNI_SELECTED
)
print("The selected item is", sel + 1)
# These function differ based on how the window is used, so may be overridden
def OnClose(self, hwnd, msg, wparam, lparam):
raise NotImplementedError
def OnDestroy(self, hwnd, msg, wparam, lparam):
pass
# An implementation suitable for use with the Win32 Window functions (ie, not
# a true dialog)
class DemoWindow(DemoWindowBase):
def CreateWindow(self):
# Create the window via CreateDialogBoxIndirect - it can then
# work as a "normal" window, once a message loop is established.
self._DoCreate(win32gui.CreateDialogIndirect)
def OnClose(self, hwnd, msg, wparam, lparam):
win32gui.DestroyWindow(hwnd)
# We need to arrange to a WM_QUIT message to be sent to our
# PumpMessages() loop.
def OnDestroy(self, hwnd, msg, wparam, lparam):
win32gui.PostQuitMessage(0) # Terminate the app.
# An implementation suitable for use with the Win32 Dialog functions.
class DemoDialog(DemoWindowBase):
def DoModal(self):
return self._DoCreate(win32gui.DialogBoxIndirect)
def OnClose(self, hwnd, msg, wparam, lparam):
win32gui.EndDialog(hwnd, 0)
def DemoModal():
w = DemoDialog()
w.DoModal()
def DemoCreateWindow():
w = DemoWindow()
w.CreateWindow()
# PumpMessages runs until PostQuitMessage() is called by someone.
win32gui.PumpMessages()
if __name__ == "__main__":
DemoModal()
DemoCreateWindow()

View file

@ -0,0 +1,420 @@
# Demonstrates some advanced menu concepts using win32gui.
# This creates a taskbar icon which has some fancy menus (but note that
# selecting the menu items does nothing useful - see win32gui_taskbar.py
# for examples of this.
# NOTE: This is a work in progress. Todo:
# * The "Checked" menu items don't work correctly - I'm not sure why.
# * No support for GetMenuItemInfo.
# Based on Andy McKay's demo code.
from win32api import *
# Try and use XP features, so we get alpha-blending etc.
try:
from winxpgui import *
except ImportError:
from win32gui import *
import array
import os
import struct
import sys
import win32con
from win32gui_struct import *
this_dir = os.path.split(sys.argv[0])[0]
class MainWindow:
def __init__(self):
message_map = {
win32con.WM_DESTROY: self.OnDestroy,
win32con.WM_COMMAND: self.OnCommand,
win32con.WM_USER + 20: self.OnTaskbarNotify,
# owner-draw related handlers.
win32con.WM_MEASUREITEM: self.OnMeasureItem,
win32con.WM_DRAWITEM: self.OnDrawItem,
}
# Register the Window class.
wc = WNDCLASS()
hinst = wc.hInstance = GetModuleHandle(None)
wc.lpszClassName = "PythonTaskbarDemo"
wc.lpfnWndProc = message_map # could also specify a wndproc.
classAtom = RegisterClass(wc)
# Create the Window.
style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
self.hwnd = CreateWindow(
classAtom,
"Taskbar Demo",
style,
0,
0,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
hinst,
None,
)
UpdateWindow(self.hwnd)
iconPathName = os.path.abspath(os.path.join(sys.prefix, "pyc.ico"))
# py2.5 includes the .ico files in the DLLs dir for some reason.
if not os.path.isfile(iconPathName):
iconPathName = os.path.abspath(
os.path.join(os.path.split(sys.executable)[0], "DLLs", "pyc.ico")
)
if not os.path.isfile(iconPathName):
# Look in the source tree.
iconPathName = os.path.abspath(
os.path.join(os.path.split(sys.executable)[0], "..\\PC\\pyc.ico")
)
if os.path.isfile(iconPathName):
icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
hicon = LoadImage(
hinst, iconPathName, win32con.IMAGE_ICON, 0, 0, icon_flags
)
else:
iconPathName = None
print("Can't find a Python icon file - using default")
hicon = LoadIcon(0, win32con.IDI_APPLICATION)
self.iconPathName = iconPathName
# Load up some information about menus needed by our owner-draw code.
# The font to use on the menu.
ncm = SystemParametersInfo(win32con.SPI_GETNONCLIENTMETRICS)
self.font_menu = CreateFontIndirect(ncm["lfMenuFont"])
# spacing for our ownerdraw menus - not sure exactly what constants
# should be used (and if you owner-draw all items on the menu, it
# doesn't matter!)
self.menu_icon_height = GetSystemMetrics(win32con.SM_CYMENU) - 4
self.menu_icon_width = self.menu_icon_height
self.icon_x_pad = 8 # space from end of icon to start of text.
# A map we use to stash away data we need for ownerdraw. Keyed
# by integer ID - that ID will be set in dwTypeData of the menu item.
self.menu_item_map = {}
# Finally, create the menu
self.createMenu()
flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
nid = (self.hwnd, 0, flags, win32con.WM_USER + 20, hicon, "Python Demo")
Shell_NotifyIcon(NIM_ADD, nid)
print("Please right-click on the Python icon in the taskbar")
def createMenu(self):
self.hmenu = menu = CreatePopupMenu()
# Create our 'Exit' item with the standard, ugly 'close' icon.
item, extras = PackMENUITEMINFO(
text="Exit", hbmpItem=win32con.HBMMENU_MBAR_CLOSE, wID=1000
)
InsertMenuItem(menu, 0, 1, item)
# Create a 'text only' menu via InsertMenuItem rather then
# AppendMenu, just to prove we can!
item, extras = PackMENUITEMINFO(text="Text only item", wID=1001)
InsertMenuItem(menu, 0, 1, item)
load_bmp_flags = win32con.LR_LOADFROMFILE | win32con.LR_LOADTRANSPARENT
# These images are "over sized", so we load them scaled.
hbmp = LoadImage(
0,
os.path.join(this_dir, "images/smiley.bmp"),
win32con.IMAGE_BITMAP,
20,
20,
load_bmp_flags,
)
# Create a top-level menu with a bitmap
item, extras = PackMENUITEMINFO(
text="Menu with bitmap", hbmpItem=hbmp, wID=1002
)
InsertMenuItem(menu, 0, 1, item)
# Owner-draw menus mainly from:
# http://windowssdk.msdn.microsoft.com/en-us/library/ms647558.aspx
# and:
# http://www.codeguru.com/cpp/controls/menu/bitmappedmenus/article.php/c165
# Create one with an icon - this is *lots* more work - we do it
# owner-draw! The primary reason is to handle transparency better -
# converting to a bitmap causes the background to be incorrect when
# the menu item is selected. I can't see a simpler way.
# First, load the icon we want to use.
ico_x = GetSystemMetrics(win32con.SM_CXSMICON)
ico_y = GetSystemMetrics(win32con.SM_CYSMICON)
if self.iconPathName:
hicon = LoadImage(
0,
self.iconPathName,
win32con.IMAGE_ICON,
ico_x,
ico_y,
win32con.LR_LOADFROMFILE,
)
else:
shell_dll = os.path.join(GetSystemDirectory(), "shell32.dll")
large, small = win32gui.ExtractIconEx(shell_dll, 4, 1)
hicon = small[0]
DestroyIcon(large[0])
# Stash away the text and hicon in our map, and add the owner-draw
# item to the menu.
index = 0
self.menu_item_map[index] = (hicon, "Menu with owner-draw icon")
item, extras = PackMENUITEMINFO(
fType=win32con.MFT_OWNERDRAW, dwItemData=index, wID=1009
)
InsertMenuItem(menu, 0, 1, item)
# Add another icon-based icon - but this time using HBMMENU_CALLBACK
# in the hbmpItem elt, so we only need to draw the icon (ie, not the
# text or checkmark)
index = 1
self.menu_item_map[index] = (hicon, None)
item, extras = PackMENUITEMINFO(
text="Menu with o-d icon 2",
dwItemData=index,
hbmpItem=win32con.HBMMENU_CALLBACK,
wID=1010,
)
InsertMenuItem(menu, 0, 1, item)
# Add another icon-based icon - this time by converting
# via bitmap. Note the icon background when selected is ugly :(
hdcBitmap = CreateCompatibleDC(0)
hdcScreen = GetDC(0)
hbm = CreateCompatibleBitmap(hdcScreen, ico_x, ico_y)
hbmOld = SelectObject(hdcBitmap, hbm)
SetBkMode(hdcBitmap, win32con.TRANSPARENT)
# Fill the background.
brush = GetSysColorBrush(win32con.COLOR_MENU)
FillRect(hdcBitmap, (0, 0, 16, 16), brush)
# unclear if brush needs to be freed. Best clue I can find is:
# "GetSysColorBrush returns a cached brush instead of allocating a new
# one." - implies no DeleteObject.
# draw the icon
DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL)
SelectObject(hdcBitmap, hbmOld)
DeleteDC(hdcBitmap)
item, extras = PackMENUITEMINFO(
text="Menu with icon", hbmpItem=hbm.Detach(), wID=1011
)
InsertMenuItem(menu, 0, 1, item)
# Create a sub-menu, and put a few funky ones there.
self.sub_menu = sub_menu = CreatePopupMenu()
# A 'checkbox' menu.
item, extras = PackMENUITEMINFO(
fState=win32con.MFS_CHECKED, text="Checkbox menu", hbmpItem=hbmp, wID=1003
)
InsertMenuItem(sub_menu, 0, 1, item)
# A 'radio' menu.
InsertMenu(sub_menu, 0, win32con.MF_BYPOSITION, win32con.MF_SEPARATOR, None)
item, extras = PackMENUITEMINFO(
fType=win32con.MFT_RADIOCHECK,
fState=win32con.MFS_CHECKED,
text="Checkbox menu - bullet 1",
hbmpItem=hbmp,
wID=1004,
)
InsertMenuItem(sub_menu, 0, 1, item)
item, extras = PackMENUITEMINFO(
fType=win32con.MFT_RADIOCHECK,
fState=win32con.MFS_UNCHECKED,
text="Checkbox menu - bullet 2",
hbmpItem=hbmp,
wID=1005,
)
InsertMenuItem(sub_menu, 0, 1, item)
# And add the sub-menu to the top-level menu.
item, extras = PackMENUITEMINFO(text="Sub-Menu", hSubMenu=sub_menu)
InsertMenuItem(menu, 0, 1, item)
# Set 'Exit' as the default option.
SetMenuDefaultItem(menu, 1000, 0)
def OnDestroy(self, hwnd, msg, wparam, lparam):
nid = (self.hwnd, 0)
Shell_NotifyIcon(NIM_DELETE, nid)
PostQuitMessage(0) # Terminate the app.
def OnTaskbarNotify(self, hwnd, msg, wparam, lparam):
if lparam == win32con.WM_RBUTTONUP:
print("You right clicked me.")
# display the menu at the cursor pos.
pos = GetCursorPos()
SetForegroundWindow(self.hwnd)
TrackPopupMenu(
self.hmenu, win32con.TPM_LEFTALIGN, pos[0], pos[1], 0, self.hwnd, None
)
PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)
elif lparam == win32con.WM_LBUTTONDBLCLK:
print("You double-clicked me")
# find the default menu item and fire it.
cmd = GetMenuDefaultItem(self.hmenu, False, 0)
if cmd == -1:
print("Can't find a default!")
# and just pretend it came from the menu
self.OnCommand(hwnd, win32con.WM_COMMAND, cmd, 0)
return 1
def OnCommand(self, hwnd, msg, wparam, lparam):
id = LOWORD(wparam)
if id == 1000:
print("Goodbye")
DestroyWindow(self.hwnd)
elif id in (1003, 1004, 1005):
# Our 'checkbox' and 'radio' items
state = GetMenuState(self.sub_menu, id, win32con.MF_BYCOMMAND)
if state == -1:
raise RuntimeError("No item found")
if state & win32con.MF_CHECKED:
check_flags = win32con.MF_UNCHECKED
print("Menu was checked - unchecking")
else:
check_flags = win32con.MF_CHECKED
print("Menu was unchecked - checking")
if id == 1003:
# simple checkbox
rc = CheckMenuItem(
self.sub_menu, id, win32con.MF_BYCOMMAND | check_flags
)
else:
# radio button - must pass the first and last IDs in the
# "group", and the ID in the group that is to be selected.
rc = CheckMenuRadioItem(
self.sub_menu, 1004, 1005, id, win32con.MF_BYCOMMAND
)
# Get and check the new state - first the simple way...
new_state = GetMenuState(self.sub_menu, id, win32con.MF_BYCOMMAND)
if new_state & win32con.MF_CHECKED != check_flags:
raise RuntimeError("The new item didn't get the new checked state!")
# Now the long-winded way via GetMenuItemInfo...
buf, extras = EmptyMENUITEMINFO()
win32gui.GetMenuItemInfo(self.sub_menu, id, False, buf)
(
fType,
fState,
wID,
hSubMenu,
hbmpChecked,
hbmpUnchecked,
dwItemData,
text,
hbmpItem,
) = UnpackMENUITEMINFO(buf)
if fState & win32con.MF_CHECKED != check_flags:
raise RuntimeError("The new item didn't get the new checked state!")
else:
print("OnCommand for ID", id)
# Owner-draw related functions. We only have 1 owner-draw item, but
# we pretend we have more than that :)
def OnMeasureItem(self, hwnd, msg, wparam, lparam):
## Last item of MEASUREITEMSTRUCT is a ULONG_PTR
fmt = "5iP"
buf = PyMakeBuffer(struct.calcsize(fmt), lparam)
data = struct.unpack(fmt, buf)
ctlType, ctlID, itemID, itemWidth, itemHeight, itemData = data
hicon, text = self.menu_item_map[itemData]
if text is None:
# Only drawing icon due to HBMMENU_CALLBACK
cx = self.menu_icon_width
cy = self.menu_icon_height
else:
# drawing the lot!
dc = GetDC(hwnd)
oldFont = SelectObject(dc, self.font_menu)
cx, cy = GetTextExtentPoint32(dc, text)
SelectObject(dc, oldFont)
ReleaseDC(hwnd, dc)
cx += GetSystemMetrics(win32con.SM_CXMENUCHECK)
cx += self.menu_icon_width + self.icon_x_pad
cy = GetSystemMetrics(win32con.SM_CYMENU)
new_data = struct.pack(fmt, ctlType, ctlID, itemID, cx, cy, itemData)
PySetMemory(lparam, new_data)
return True
def OnDrawItem(self, hwnd, msg, wparam, lparam):
## lparam is a DRAWITEMSTRUCT
fmt = "5i2P4iP"
data = struct.unpack(fmt, PyGetMemory(lparam, struct.calcsize(fmt)))
(
ctlType,
ctlID,
itemID,
itemAction,
itemState,
hwndItem,
hDC,
left,
top,
right,
bot,
itemData,
) = data
rect = left, top, right, bot
hicon, text = self.menu_item_map[itemData]
if text is None:
# This means the menu-item had HBMMENU_CALLBACK - so all we
# draw is the icon. rect is the entire area we should use.
DrawIconEx(
hDC, left, top, hicon, right - left, bot - top, 0, 0, win32con.DI_NORMAL
)
else:
# If the user has selected the item, use the selected
# text and background colors to display the item.
selected = itemState & win32con.ODS_SELECTED
if selected:
crText = SetTextColor(hDC, GetSysColor(win32con.COLOR_HIGHLIGHTTEXT))
crBkgnd = SetBkColor(hDC, GetSysColor(win32con.COLOR_HIGHLIGHT))
each_pad = self.icon_x_pad // 2
x_icon = left + GetSystemMetrics(win32con.SM_CXMENUCHECK) + each_pad
x_text = x_icon + self.menu_icon_width + each_pad
# Draw text first, specifying a complete rect to fill - this sets
# up the background (but overwrites anything else already there!)
# Select the font, draw it, and restore the previous font.
hfontOld = SelectObject(hDC, self.font_menu)
ExtTextOut(hDC, x_text, top + 2, win32con.ETO_OPAQUE, rect, text)
SelectObject(hDC, hfontOld)
# Icon image next. Icons are transparent - no need to handle
# selection specially.
DrawIconEx(
hDC,
x_icon,
top + 2,
hicon,
self.menu_icon_width,
self.menu_icon_height,
0,
0,
win32con.DI_NORMAL,
)
# Return the text and background colors to their
# normal state (not selected).
if selected:
SetTextColor(hDC, crText)
SetBkColor(hDC, crBkgnd)
def main():
w = MainWindow()
PumpMessages()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,141 @@
# Creates a task-bar icon. Run from Python.exe to see the
# messages printed.
import os
import sys
import win32api
import win32con
import win32gui
import winerror
class MainWindow:
def __init__(self):
msg_TaskbarRestart = win32gui.RegisterWindowMessage("TaskbarCreated")
message_map = {
msg_TaskbarRestart: self.OnRestart,
win32con.WM_DESTROY: self.OnDestroy,
win32con.WM_COMMAND: self.OnCommand,
win32con.WM_USER + 20: self.OnTaskbarNotify,
}
# Register the Window class.
wc = win32gui.WNDCLASS()
hinst = wc.hInstance = win32api.GetModuleHandle(None)
wc.lpszClassName = "PythonTaskbarDemo"
wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW
wc.hCursor = win32api.LoadCursor(0, win32con.IDC_ARROW)
wc.hbrBackground = win32con.COLOR_WINDOW
wc.lpfnWndProc = message_map # could also specify a wndproc.
# Don't blow up if class already registered to make testing easier
try:
classAtom = win32gui.RegisterClass(wc)
except win32gui.error as err_info:
if err_info.winerror != winerror.ERROR_CLASS_ALREADY_EXISTS:
raise
# Create the Window.
style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
self.hwnd = win32gui.CreateWindow(
wc.lpszClassName,
"Taskbar Demo",
style,
0,
0,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
hinst,
None,
)
win32gui.UpdateWindow(self.hwnd)
self._DoCreateIcons()
def _DoCreateIcons(self):
# Try and find a custom icon
hinst = win32api.GetModuleHandle(None)
iconPathName = os.path.abspath(
os.path.join(os.path.split(sys.executable)[0], "pyc.ico")
)
if not os.path.isfile(iconPathName):
# Look in DLLs dir, a-la py 2.5
iconPathName = os.path.abspath(
os.path.join(os.path.split(sys.executable)[0], "DLLs", "pyc.ico")
)
if not os.path.isfile(iconPathName):
# Look in the source tree.
iconPathName = os.path.abspath(
os.path.join(os.path.split(sys.executable)[0], "..\\PC\\pyc.ico")
)
if os.path.isfile(iconPathName):
icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
hicon = win32gui.LoadImage(
hinst, iconPathName, win32con.IMAGE_ICON, 0, 0, icon_flags
)
else:
print("Can't find a Python icon file - using default")
hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
flags = win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP
nid = (self.hwnd, 0, flags, win32con.WM_USER + 20, hicon, "Python Demo")
try:
win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, nid)
except win32gui.error:
# This is common when windows is starting, and this code is hit
# before the taskbar has been created.
print("Failed to add the taskbar icon - is explorer running?")
# but keep running anyway - when explorer starts, we get the
# TaskbarCreated message.
def OnRestart(self, hwnd, msg, wparam, lparam):
self._DoCreateIcons()
def OnDestroy(self, hwnd, msg, wparam, lparam):
nid = (self.hwnd, 0)
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
win32gui.PostQuitMessage(0) # Terminate the app.
def OnTaskbarNotify(self, hwnd, msg, wparam, lparam):
if lparam == win32con.WM_LBUTTONUP:
print("You clicked me.")
elif lparam == win32con.WM_LBUTTONDBLCLK:
print("You double-clicked me - goodbye")
win32gui.DestroyWindow(self.hwnd)
elif lparam == win32con.WM_RBUTTONUP:
print("You right clicked me.")
menu = win32gui.CreatePopupMenu()
win32gui.AppendMenu(menu, win32con.MF_STRING, 1023, "Display Dialog")
win32gui.AppendMenu(menu, win32con.MF_STRING, 1024, "Say Hello")
win32gui.AppendMenu(menu, win32con.MF_STRING, 1025, "Exit program")
pos = win32gui.GetCursorPos()
# See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp
win32gui.SetForegroundWindow(self.hwnd)
win32gui.TrackPopupMenu(
menu, win32con.TPM_LEFTALIGN, pos[0], pos[1], 0, self.hwnd, None
)
win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)
return 1
def OnCommand(self, hwnd, msg, wparam, lparam):
id = win32api.LOWORD(wparam)
if id == 1023:
import win32gui_dialog
win32gui_dialog.DemoModal()
elif id == 1024:
print("Hello")
elif id == 1025:
print("Goodbye")
win32gui.DestroyWindow(self.hwnd)
else:
print("Unknown command -", id)
def main():
w = MainWindow()
win32gui.PumpMessages()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,274 @@
import getopt
import sys
import traceback
import win32api
import win32net
import win32netcon
import win32security
verbose_level = 0
server = None # Run on local machine.
def verbose(msg):
if verbose_level:
print(msg)
def CreateUser():
"Creates a new test user, then deletes the user"
testName = "PyNetTestUser"
try:
win32net.NetUserDel(server, testName)
print("Warning - deleted user before creating it!")
except win32net.error:
pass
d = {}
d["name"] = testName
d["password"] = "deleteme"
d["priv"] = win32netcon.USER_PRIV_USER
d["comment"] = "Delete me - created by Python test code"
d["flags"] = win32netcon.UF_NORMAL_ACCOUNT | win32netcon.UF_SCRIPT
win32net.NetUserAdd(server, 1, d)
try:
try:
win32net.NetUserChangePassword(server, testName, "wrong", "new")
print("ERROR: NetUserChangePassword worked with a wrong password!")
except win32net.error:
pass
win32net.NetUserChangePassword(server, testName, "deleteme", "new")
finally:
win32net.NetUserDel(server, testName)
print("Created a user, changed their password, and deleted them!")
def UserEnum():
"Enumerates all the local users"
resume = 0
nuser = 0
while 1:
data, total, resume = win32net.NetUserEnum(
server, 3, win32netcon.FILTER_NORMAL_ACCOUNT, resume
)
verbose(
"Call to NetUserEnum obtained %d entries of %d total" % (len(data), total)
)
for user in data:
verbose("Found user %s" % user["name"])
nuser = nuser + 1
if not resume:
break
assert nuser, "Could not find any users!"
print("Enumerated all the local users")
def GroupEnum():
"Enumerates all the domain groups"
nmembers = 0
resume = 0
while 1:
data, total, resume = win32net.NetGroupEnum(server, 1, resume)
# print "Call to NetGroupEnum obtained %d entries of %d total" % (len(data), total)
for group in data:
verbose("Found group %(name)s:%(comment)s " % group)
memberresume = 0
while 1:
memberdata, total, memberresume = win32net.NetGroupGetUsers(
server, group["name"], 0, resume
)
for member in memberdata:
verbose(" Member %(name)s" % member)
nmembers = nmembers + 1
if memberresume == 0:
break
if not resume:
break
assert nmembers, "Couldnt find a single member in a single group!"
print("Enumerated all the groups")
def LocalGroupEnum():
"Enumerates all the local groups"
resume = 0
nmembers = 0
while 1:
data, total, resume = win32net.NetLocalGroupEnum(server, 1, resume)
for group in data:
verbose("Found group %(name)s:%(comment)s " % group)
memberresume = 0
while 1:
memberdata, total, memberresume = win32net.NetLocalGroupGetMembers(
server, group["name"], 2, resume
)
for member in memberdata:
# Just for the sake of it, we convert the SID to a username
username, domain, type = win32security.LookupAccountSid(
server, member["sid"]
)
nmembers = nmembers + 1
verbose(" Member %s (%s)" % (username, member["domainandname"]))
if memberresume == 0:
break
if not resume:
break
assert nmembers, "Couldnt find a single member in a single group!"
print("Enumerated all the local groups")
def ServerEnum():
"Enumerates all servers on the network"
resume = 0
while 1:
data, total, resume = win32net.NetServerEnum(
server, 100, win32netcon.SV_TYPE_ALL, None, resume
)
for s in data:
verbose("Found server %s" % s["name"])
# Now loop over the shares.
shareresume = 0
while 1:
sharedata, total, shareresume = win32net.NetShareEnum(
server, 2, shareresume
)
for share in sharedata:
verbose(
" %(netname)s (%(path)s):%(remark)s - in use by %(current_uses)d users"
% share
)
if not shareresume:
break
if not resume:
break
print("Enumerated all the servers on the network")
def LocalGroup(uname=None):
"Creates a local group, adds some members, deletes them, then removes the group"
level = 3
if uname is None:
uname = win32api.GetUserName()
if uname.find("\\") < 0:
uname = win32api.GetDomainName() + "\\" + uname
group = "python_test_group"
# delete the group if it already exists
try:
win32net.NetLocalGroupDel(server, group)
print("WARNING: existing local group '%s' has been deleted.")
except win32net.error:
pass
group_data = {"name": group}
win32net.NetLocalGroupAdd(server, 1, group_data)
try:
u = {"domainandname": uname}
win32net.NetLocalGroupAddMembers(server, group, level, [u])
mem, tot, res = win32net.NetLocalGroupGetMembers(server, group, level)
print("members are", mem)
if mem[0]["domainandname"] != uname:
print("ERROR: LocalGroup just added %s, but members are %r" % (uname, mem))
# Convert the list of dicts to a list of strings.
win32net.NetLocalGroupDelMembers(
server, group, [m["domainandname"] for m in mem]
)
finally:
win32net.NetLocalGroupDel(server, group)
print("Created a local group, added and removed members, then deleted the group")
def GetInfo(userName=None):
"Dumps level 3 information about the current user"
if userName is None:
userName = win32api.GetUserName()
print("Dumping level 3 information about user")
info = win32net.NetUserGetInfo(server, userName, 3)
for key, val in list(info.items()):
verbose("%s=%s" % (key, val))
def SetInfo(userName=None):
"Attempts to change the current users comment, then set it back"
if userName is None:
userName = win32api.GetUserName()
oldData = win32net.NetUserGetInfo(server, userName, 3)
try:
d = oldData.copy()
d["usr_comment"] = "Test comment"
win32net.NetUserSetInfo(server, userName, 3, d)
new = win32net.NetUserGetInfo(server, userName, 3)["usr_comment"]
if str(new) != "Test comment":
raise RuntimeError("Could not read the same comment back - got %s" % new)
print("Changed the data for the user")
finally:
win32net.NetUserSetInfo(server, userName, 3, oldData)
def SetComputerInfo():
"Doesnt actually change anything, just make sure we could ;-)"
info = win32net.NetWkstaGetInfo(None, 502)
# *sob* - but we can't! Why not!!!
# win32net.NetWkstaSetInfo(None, 502, info)
def usage(tests):
import os
print("Usage: %s [-s server ] [-v] [Test ...]" % os.path.basename(sys.argv[0]))
print(" -v : Verbose - print more information")
print(" -s : server - execute the tests against the named server")
print(" -c : include the CreateUser test by default")
print("where Test is one of:")
for t in tests:
print(t.__name__, ":", t.__doc__)
print()
print("If not tests are specified, all tests are run")
sys.exit(1)
def main():
tests = []
for ob in list(globals().values()):
if type(ob) == type(main) and ob.__doc__:
tests.append(ob)
opts, args = getopt.getopt(sys.argv[1:], "s:hvc")
create_user = False
for opt, val in opts:
if opt == "-s":
global server
server = val
if opt == "-h":
usage(tests)
if opt == "-v":
global verbose_level
verbose_level = verbose_level + 1
if opt == "-c":
create_user = True
if len(args) == 0:
print("Running all tests - use '-h' to see command-line options...")
dotests = tests
if not create_user:
dotests.remove(CreateUser)
else:
dotests = []
for arg in args:
for t in tests:
if t.__name__ == arg:
dotests.append(t)
break
else:
print("Test '%s' unknown - skipping" % arg)
if not len(dotests):
print("Nothing to do!")
usage(tests)
for test in dotests:
try:
test()
except:
print("Test %s failed" % test.__name__)
traceback.print_exc()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,86 @@
# A demo of the win32rcparser module and using win32gui
import os
import commctrl
import win32api
import win32con
import win32gui
import win32rcparser
this_dir = os.path.abspath(os.path.dirname(__file__))
g_rcname = os.path.abspath(
os.path.join(this_dir, "..", "test", "win32rcparser", "test.rc")
)
if not os.path.isfile(g_rcname):
raise RuntimeError("Can't locate test.rc (should be at '%s')" % (g_rcname,))
class DemoWindow:
def __init__(self, dlg_template):
self.dlg_template = dlg_template
def CreateWindow(self):
self._DoCreate(win32gui.CreateDialogIndirect)
def DoModal(self):
return self._DoCreate(win32gui.DialogBoxIndirect)
def _DoCreate(self, fn):
message_map = {
win32con.WM_INITDIALOG: self.OnInitDialog,
win32con.WM_CLOSE: self.OnClose,
win32con.WM_DESTROY: self.OnDestroy,
win32con.WM_COMMAND: self.OnCommand,
}
return fn(0, self.dlg_template, 0, message_map)
def OnInitDialog(self, hwnd, msg, wparam, lparam):
self.hwnd = hwnd
# centre the dialog
desktop = win32gui.GetDesktopWindow()
l, t, r, b = win32gui.GetWindowRect(self.hwnd)
dt_l, dt_t, dt_r, dt_b = win32gui.GetWindowRect(desktop)
centre_x, centre_y = win32gui.ClientToScreen(
desktop, ((dt_r - dt_l) // 2, (dt_b - dt_t) // 2)
)
win32gui.MoveWindow(
hwnd, centre_x - (r // 2), centre_y - (b // 2), r - l, b - t, 0
)
def OnCommand(self, hwnd, msg, wparam, lparam):
# Needed to make OK/Cancel work - no other controls are handled.
id = win32api.LOWORD(wparam)
if id in [win32con.IDOK, win32con.IDCANCEL]:
win32gui.EndDialog(hwnd, id)
def OnClose(self, hwnd, msg, wparam, lparam):
win32gui.EndDialog(hwnd, 0)
def OnDestroy(self, hwnd, msg, wparam, lparam):
pass
def DemoModal():
# Load the .rc file.
resources = win32rcparser.Parse(g_rcname)
for id, ddef in resources.dialogs.items():
print("Displaying dialog", id)
w = DemoWindow(ddef)
w.DoModal()
if __name__ == "__main__":
flags = 0
for flag in """ICC_DATE_CLASSES ICC_ANIMATE_CLASS ICC_ANIMATE_CLASS
ICC_BAR_CLASSES ICC_COOL_CLASSES ICC_DATE_CLASSES
ICC_HOTKEY_CLASS ICC_INTERNET_CLASSES ICC_LISTVIEW_CLASSES
ICC_PAGESCROLLER_CLASS ICC_PROGRESS_CLASS ICC_TAB_CLASSES
ICC_TREEVIEW_CLASSES ICC_UPDOWN_CLASS ICC_USEREX_CLASSES
ICC_WIN95_CLASSES """.split():
flags |= getattr(commctrl, flag)
win32gui.InitCommonControlsEx(flags)
# Need to do this go get rich-edit working.
win32api.LoadLibrary("riched20.dll")
DemoModal()

View file

@ -0,0 +1,23 @@
import win32con
import win32service
def EnumServices():
resume = 0
accessSCM = win32con.GENERIC_READ
accessSrv = win32service.SC_MANAGER_ALL_ACCESS
# Open Service Control Manager
hscm = win32service.OpenSCManager(None, None, accessSCM)
# Enumerate Service Control Manager DB
typeFilter = win32service.SERVICE_WIN32
stateFilter = win32service.SERVICE_STATE_ALL
statuses = win32service.EnumServicesStatus(hscm, typeFilter, stateFilter)
for short_name, desc, status in statuses:
print(short_name, desc, status)
EnumServices()

View file

@ -0,0 +1,24 @@
""" Finds any disconnected terminal service sessions and logs them off"""
import pywintypes
import win32ts
import winerror
sessions = win32ts.WTSEnumerateSessions(win32ts.WTS_CURRENT_SERVER_HANDLE)
for session in sessions:
"""
WTS_CONNECTSTATE_CLASS: WTSActive,WTSConnected,WTSConnectQuery,WTSShadow,WTSDisconnected,
WTSIdle,WTSListen,WTSReset,WTSDown,WTSInit
"""
if session["State"] == win32ts.WTSDisconnected:
sessionid = session["SessionId"]
username = win32ts.WTSQuerySessionInformation(
win32ts.WTS_CURRENT_SERVER_HANDLE, sessionid, win32ts.WTSUserName
)
print("Logging off disconnected user:", username)
try:
win32ts.WTSLogoffSession(win32ts.WTS_CURRENT_SERVER_HANDLE, sessionid, True)
except pywintypes.error as e:
if e.winerror == winerror.ERROR_ACCESS_DENIED:
print("Can't kill that session:", e.strerror)
else:
raise

View file

@ -0,0 +1,125 @@
import os
import win32api
import win32wnet
from winnetwk import *
possible_shares = []
def _doDumpHandle(handle, level=0):
indent = " " * level
while 1:
items = win32wnet.WNetEnumResource(handle, 0)
if len(items) == 0:
break
for item in items:
try:
if item.dwDisplayType == RESOURCEDISPLAYTYPE_SHARE:
print(indent + "Have share with name:", item.lpRemoteName)
possible_shares.append(item)
elif item.dwDisplayType == RESOURCEDISPLAYTYPE_GENERIC:
print(
indent + "Have generic resource with name:", item.lpRemoteName
)
else:
# Try generic!
print(indent + "Enumerating " + item.lpRemoteName, end=" ")
k = win32wnet.WNetOpenEnum(
RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, item
)
print()
_doDumpHandle(k, level + 1)
win32wnet.WNetCloseEnum(
k
) # could do k.Close(), but this is a good test!
except win32wnet.error as details:
print(indent + "Couldn't enumerate this resource: " + details.strerror)
def TestOpenEnum():
print("Enumerating all resources on the network - this may take some time...")
handle = win32wnet.WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, None)
try:
_doDumpHandle(handle)
finally:
handle.Close()
print("Finished dumping all resources.")
def findUnusedDriveLetter():
existing = [
x[0].lower() for x in win32api.GetLogicalDriveStrings().split("\0") if x
]
handle = win32wnet.WNetOpenEnum(RESOURCE_REMEMBERED, RESOURCETYPE_DISK, 0, None)
try:
while 1:
items = win32wnet.WNetEnumResource(handle, 0)
if len(items) == 0:
break
xtra = [i.lpLocalName[0].lower() for i in items if i.lpLocalName]
existing.extend(xtra)
finally:
handle.Close()
for maybe in "defghijklmnopqrstuvwxyz":
if maybe not in existing:
return maybe
raise RuntimeError("All drive mappings are taken?")
def TestConnection():
if len(possible_shares) == 0:
print("Couldn't find any potential shares to connect to")
return
localName = findUnusedDriveLetter() + ":"
for share in possible_shares:
print("Attempting connection of", localName, "to", share.lpRemoteName)
try:
win32wnet.WNetAddConnection2(share.dwType, localName, share.lpRemoteName)
except win32wnet.error as details:
print("Couldn't connect: " + details.strerror)
continue
# Have a connection.
try:
fname = os.path.join(localName + "\\", os.listdir(localName + "\\")[0])
try:
print(
"Universal name of '%s' is '%s'"
% (fname, win32wnet.WNetGetUniversalName(fname))
)
except win32wnet.error as details:
print(
"Couldn't get universal name of '%s': %s"
% (fname, details.strerror)
)
print("User name for this connection is", win32wnet.WNetGetUser(localName))
finally:
win32wnet.WNetCancelConnection2(localName, 0, 0)
# and do it again, but this time by using the more modern
# NETRESOURCE way.
nr = win32wnet.NETRESOURCE()
nr.dwType = share.dwType
nr.lpLocalName = localName
nr.lpRemoteName = share.lpRemoteName
win32wnet.WNetAddConnection2(nr)
win32wnet.WNetCancelConnection2(localName, 0, 0)
# and one more time using WNetAddConnection3
win32wnet.WNetAddConnection3(0, nr)
win32wnet.WNetCancelConnection2(localName, 0, 0)
# Only do the first share that succeeds.
break
def TestGetUser():
u = win32wnet.WNetGetUser()
print("Current global user is", repr(u))
if u != win32wnet.WNetGetUser(None):
raise RuntimeError("Default value didnt seem to work!")
TestGetUser()
TestOpenEnum()
TestConnection()

View file

@ -0,0 +1,100 @@
# Generated by h2py from d:\mssdk\include\winnetwk.h
WNNC_NET_MSNET = 0x00010000
WNNC_NET_LANMAN = 0x00020000
WNNC_NET_NETWARE = 0x00030000
WNNC_NET_VINES = 0x00040000
WNNC_NET_10NET = 0x00050000
WNNC_NET_LOCUS = 0x00060000
WNNC_NET_SUN_PC_NFS = 0x00070000
WNNC_NET_LANSTEP = 0x00080000
WNNC_NET_9TILES = 0x00090000
WNNC_NET_LANTASTIC = 0x000A0000
WNNC_NET_AS400 = 0x000B0000
WNNC_NET_FTP_NFS = 0x000C0000
WNNC_NET_PATHWORKS = 0x000D0000
WNNC_NET_LIFENET = 0x000E0000
WNNC_NET_POWERLAN = 0x000F0000
WNNC_NET_BWNFS = 0x00100000
WNNC_NET_COGENT = 0x00110000
WNNC_NET_FARALLON = 0x00120000
WNNC_NET_APPLETALK = 0x00130000
WNNC_NET_INTERGRAPH = 0x00140000
WNNC_NET_SYMFONET = 0x00150000
WNNC_NET_CLEARCASE = 0x00160000
WNNC_NET_FRONTIER = 0x00170000
WNNC_NET_BMC = 0x00180000
WNNC_NET_DCE = 0x00190000
WNNC_NET_DECORB = 0x00200000
WNNC_NET_PROTSTOR = 0x00210000
WNNC_NET_FJ_REDIR = 0x00220000
WNNC_NET_DISTINCT = 0x00230000
WNNC_NET_TWINS = 0x00240000
WNNC_NET_RDR2SAMPLE = 0x00250000
RESOURCE_CONNECTED = 0x00000001
RESOURCE_GLOBALNET = 0x00000002
RESOURCE_REMEMBERED = 0x00000003
RESOURCE_RECENT = 0x00000004
RESOURCE_CONTEXT = 0x00000005
RESOURCETYPE_ANY = 0x00000000
RESOURCETYPE_DISK = 0x00000001
RESOURCETYPE_PRINT = 0x00000002
RESOURCETYPE_RESERVED = 0x00000008
RESOURCETYPE_UNKNOWN = 0xFFFFFFFF
RESOURCEUSAGE_CONNECTABLE = 0x00000001
RESOURCEUSAGE_CONTAINER = 0x00000002
RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004
RESOURCEUSAGE_SIBLING = 0x00000008
RESOURCEUSAGE_ATTACHED = 0x00000010
RESOURCEUSAGE_ALL = (
RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED
)
RESOURCEUSAGE_RESERVED = 0x80000000
RESOURCEDISPLAYTYPE_GENERIC = 0x00000000
RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001
RESOURCEDISPLAYTYPE_SERVER = 0x00000002
RESOURCEDISPLAYTYPE_SHARE = 0x00000003
RESOURCEDISPLAYTYPE_FILE = 0x00000004
RESOURCEDISPLAYTYPE_GROUP = 0x00000005
RESOURCEDISPLAYTYPE_NETWORK = 0x00000006
RESOURCEDISPLAYTYPE_ROOT = 0x00000007
RESOURCEDISPLAYTYPE_SHAREADMIN = 0x00000008
RESOURCEDISPLAYTYPE_DIRECTORY = 0x00000009
RESOURCEDISPLAYTYPE_TREE = 0x0000000A
RESOURCEDISPLAYTYPE_NDSCONTAINER = 0x0000000B
NETPROPERTY_PERSISTENT = 1
CONNECT_UPDATE_PROFILE = 0x00000001
CONNECT_UPDATE_RECENT = 0x00000002
CONNECT_TEMPORARY = 0x00000004
CONNECT_INTERACTIVE = 0x00000008
CONNECT_PROMPT = 0x00000010
CONNECT_NEED_DRIVE = 0x00000020
CONNECT_REFCOUNT = 0x00000040
CONNECT_REDIRECT = 0x00000080
CONNECT_LOCALDRIVE = 0x00000100
CONNECT_CURRENT_MEDIA = 0x00000200
CONNECT_DEFERRED = 0x00000400
CONNECT_RESERVED = 0xFF000000
CONNDLG_RO_PATH = 0x00000001
CONNDLG_CONN_POINT = 0x00000002
CONNDLG_USE_MRU = 0x00000004
CONNDLG_HIDE_BOX = 0x00000008
CONNDLG_PERSIST = 0x00000010
CONNDLG_NOT_PERSIST = 0x00000020
DISC_UPDATE_PROFILE = 0x00000001
DISC_NO_FORCE = 0x00000040
UNIVERSAL_NAME_INFO_LEVEL = 0x00000001
REMOTE_NAME_INFO_LEVEL = 0x00000002
WNFMT_MULTILINE = 0x01
WNFMT_ABBREVIATED = 0x02
WNFMT_INENUM = 0x10
WNFMT_CONNECTION = 0x20
NETINFO_DLL16 = 0x00000001
NETINFO_DISKRED = 0x00000004
NETINFO_PRINTERRED = 0x00000008
RP_LOGON = 0x01
RP_INIFILE = 0x02
PP_DISPLAYERRORS = 0x01
WNCON_FORNETCARD = 0x00000001
WNCON_NOTROUTED = 0x00000002
WNCON_SLOWLINK = 0x00000004
WNCON_DYNAMIC = 0x00000008

View file

@ -0,0 +1,230 @@
"""
Windows Process Control
winprocess.run launches a child process and returns the exit code.
Optionally, it can:
redirect stdin, stdout & stderr to files
run the command as another user
limit the process's running time
control the process window (location, size, window state, desktop)
Works on Windows NT, 2000 & XP. Requires Mark Hammond's win32
extensions.
This code is free for any purpose, with no warranty of any kind.
-- John B. Dell'Aquila <jbd@alum.mit.edu>
"""
import msvcrt
import os
import win32api
import win32con
import win32event
import win32gui
import win32process
import win32security
def logonUser(loginString):
"""
Login as specified user and return handle.
loginString: 'Domain\nUser\nPassword'; for local
login use . or empty string as domain
e.g. '.\nadministrator\nsecret_password'
"""
domain, user, passwd = loginString.split("\n")
return win32security.LogonUser(
user,
domain,
passwd,
win32con.LOGON32_LOGON_INTERACTIVE,
win32con.LOGON32_PROVIDER_DEFAULT,
)
class Process:
"""
A Windows process.
"""
def __init__(
self,
cmd,
login=None,
hStdin=None,
hStdout=None,
hStderr=None,
show=1,
xy=None,
xySize=None,
desktop=None,
):
"""
Create a Windows process.
cmd: command to run
login: run as user 'Domain\nUser\nPassword'
hStdin, hStdout, hStderr:
handles for process I/O; default is caller's stdin,
stdout & stderr
show: wShowWindow (0=SW_HIDE, 1=SW_NORMAL, ...)
xy: window offset (x, y) of upper left corner in pixels
xySize: window size (width, height) in pixels
desktop: lpDesktop - name of desktop e.g. 'winsta0\\default'
None = inherit current desktop
'' = create new desktop if necessary
User calling login requires additional privileges:
Act as part of the operating system [not needed on Windows XP]
Increase quotas
Replace a process level token
Login string must EITHER be an administrator's account
(ordinary user can't access current desktop - see Microsoft
Q165194) OR use desktop='' to run another desktop invisibly
(may be very slow to startup & finalize).
"""
si = win32process.STARTUPINFO()
si.dwFlags = win32con.STARTF_USESTDHANDLES ^ win32con.STARTF_USESHOWWINDOW
if hStdin is None:
si.hStdInput = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE)
else:
si.hStdInput = hStdin
if hStdout is None:
si.hStdOutput = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE)
else:
si.hStdOutput = hStdout
if hStderr is None:
si.hStdError = win32api.GetStdHandle(win32api.STD_ERROR_HANDLE)
else:
si.hStdError = hStderr
si.wShowWindow = show
if xy is not None:
si.dwX, si.dwY = xy
si.dwFlags ^= win32con.STARTF_USEPOSITION
if xySize is not None:
si.dwXSize, si.dwYSize = xySize
si.dwFlags ^= win32con.STARTF_USESIZE
if desktop is not None:
si.lpDesktop = desktop
procArgs = (
None, # appName
cmd, # commandLine
None, # processAttributes
None, # threadAttributes
1, # bInheritHandles
win32process.CREATE_NEW_CONSOLE, # dwCreationFlags
None, # newEnvironment
None, # currentDirectory
si,
) # startupinfo
if login is not None:
hUser = logonUser(login)
win32security.ImpersonateLoggedOnUser(hUser)
procHandles = win32process.CreateProcessAsUser(hUser, *procArgs)
win32security.RevertToSelf()
else:
procHandles = win32process.CreateProcess(*procArgs)
self.hProcess, self.hThread, self.PId, self.TId = procHandles
def wait(self, mSec=None):
"""
Wait for process to finish or for specified number of
milliseconds to elapse.
"""
if mSec is None:
mSec = win32event.INFINITE
return win32event.WaitForSingleObject(self.hProcess, mSec)
def kill(self, gracePeriod=5000):
"""
Kill process. Try for an orderly shutdown via WM_CLOSE. If
still running after gracePeriod (5 sec. default), terminate.
"""
win32gui.EnumWindows(self.__close__, 0)
if self.wait(gracePeriod) != win32event.WAIT_OBJECT_0:
win32process.TerminateProcess(self.hProcess, 0)
win32api.Sleep(100) # wait for resources to be released
def __close__(self, hwnd, dummy):
"""
EnumWindows callback - sends WM_CLOSE to any window
owned by this process.
"""
TId, PId = win32process.GetWindowThreadProcessId(hwnd)
if PId == self.PId:
win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
def exitCode(self):
"""
Return process exit code.
"""
return win32process.GetExitCodeProcess(self.hProcess)
def run(cmd, mSec=None, stdin=None, stdout=None, stderr=None, **kw):
"""
Run cmd as a child process and return exit code.
mSec: terminate cmd after specified number of milliseconds
stdin, stdout, stderr:
file objects for child I/O (use hStdin etc. to attach
handles instead of files); default is caller's stdin,
stdout & stderr;
kw: see Process.__init__ for more keyword options
"""
if stdin is not None:
kw["hStdin"] = msvcrt.get_osfhandle(stdin.fileno())
if stdout is not None:
kw["hStdout"] = msvcrt.get_osfhandle(stdout.fileno())
if stderr is not None:
kw["hStderr"] = msvcrt.get_osfhandle(stderr.fileno())
child = Process(cmd, **kw)
if child.wait(mSec) != win32event.WAIT_OBJECT_0:
child.kill()
raise WindowsError("process timeout exceeded")
return child.exitCode()
if __name__ == "__main__":
# Pipe commands to a shell and display the output in notepad
print("Testing winprocess.py...")
import tempfile
timeoutSeconds = 15
cmdString = (
"""\
REM Test of winprocess.py piping commands to a shell.\r
REM This 'notepad' process will terminate in %d seconds.\r
vol\r
net user\r
_this_is_a_test_of_stderr_\r
"""
% timeoutSeconds
)
cmd_name = tempfile.mktemp()
out_name = cmd_name + ".txt"
try:
cmd = open(cmd_name, "w+b")
out = open(out_name, "w+b")
cmd.write(cmdString.encode("mbcs"))
cmd.seek(0)
print(
"CMD.EXE exit code:",
run("cmd.exe", show=0, stdin=cmd, stdout=out, stderr=out),
)
cmd.close()
print(
"NOTEPAD exit code:",
run(
"notepad.exe %s" % out.name,
show=win32con.SW_MAXIMIZE,
mSec=timeoutSeconds * 1000,
),
)
out.close()
finally:
for n in (cmd_name, out_name):
try:
os.unlink(cmd_name)
except os.error:
pass

View file

@ -0,0 +1,727 @@
#ifndef __PYWINTYPES_H__
#define __PYWINTYPES_H__
// If building under a GCC, tweak what we need.
#if defined(__GNUC__) && defined(_POSIX_C_SOURCE)
// python.h complains if _POSIX_C_SOURCE is already defined
#undef _POSIX_C_SOURCE
#endif
// windows rpc.h defines "small" as "char" which breaks Python's accu.h,
// so we undefine it before including python.
#ifdef small
#undef small
#endif
#include "Python.h"
#include "structmember.h"
#include "windows.h"
// Helpers for our modules.
// Some macros to help the pywin32 modules co-exist in py2x and py3k.
// Creates and initializes local variables called 'module' and 'dict'.
// Maybe these should all be removed - they existed to help in the py2->3
// transition.
// On one hand: the code would be cleaner if they were all just re-inlined?
// On the other: high confidence everything uses the exact same patterns?
// (Regardless, *some*, eg, PYWIN_MODULE_INIT_RETURN_* should be re-inlined!)
// Use to define the function itself (ie, its name, linkage, params)
#define PYWIN_MODULE_INIT_FUNC(module_name) extern "C" __declspec(dllexport) PyObject *PyInit_##module_name(void)
// If the module needs to early-exit on an error condition.
#define PYWIN_MODULE_INIT_RETURN_ERROR return NULL;
// When the module has successfully initialized.
#define PYWIN_MODULE_INIT_RETURN_SUCCESS return module;
// To setup the module object itself and the module's dictionary.
#define PYWIN_MODULE_INIT_PREPARE(module_name, functions, docstring) \
PyObject *dict, *module; \
static PyModuleDef module_name##_def = {PyModuleDef_HEAD_INIT, #module_name, docstring, -1, functions}; \
if (PyWinGlobals_Ensure() == -1) \
return NULL; \
if (!(module = PyModule_Create(&module_name##_def))) \
return NULL; \
if (!(dict = PyModule_GetDict(module))) \
return NULL;
// Helpers for our types.
// Macro to handle PyObject layout changes in Py3k
#define PYWIN_OBJECT_HEAD PyVarObject_HEAD_INIT(NULL, 0)
/* Attribute names are passed as Unicode in Py3k, so use a macro to
switch between string and unicode conversion. This function is not
documented, but is used extensively in the Python codebase itself,
so it's reasonable to assume it won't disappear anytime soon.
*/
#define PYWIN_ATTR_CONVERT (char *)_PyUnicode_AsString
typedef Py_ssize_t Py_hash_t;
// This only enables runtime checks in debug builds - so we use
// our own so we can enable it always should we desire...
#define PyWin_SAFE_DOWNCAST Py_SAFE_DOWNCAST
// Lars: for WAVEFORMATEX
#include "mmsystem.h"
#ifdef BUILD_PYWINTYPES
/* We are building pywintypesxx.dll */
#define PYWINTYPES_EXPORT __declspec(dllexport)
#else
/* This module uses pywintypesxx.dll */
#define PYWINTYPES_EXPORT __declspec(dllimport)
#if defined(_MSC_VER)
#if defined(DEBUG) || defined(_DEBUG)
#pragma comment(lib, "pywintypes_d.lib")
#else
#pragma comment(lib, "pywintypes.lib")
#endif // DEBUG/_DEBUG
#endif // _MSC_VER
#endif // BUILD_PYWINTYPES
// Py3k uses memoryview object in place of buffer, and we don't yet.
extern PYWINTYPES_EXPORT PyObject *PyBuffer_New(Py_ssize_t size);
extern PYWINTYPES_EXPORT PyObject *PyBuffer_FromMemory(void *buf, Py_ssize_t size);
// Formats a python traceback into a character string - result must be free()ed
PYWINTYPES_EXPORT WCHAR *GetPythonTraceback(PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb);
#include <tchar.h>
/*
** Error/Exception handling
*/
extern PYWINTYPES_EXPORT PyObject *PyWinExc_ApiError;
// Register a Windows DLL that contains the messages in the specified range.
extern PYWINTYPES_EXPORT BOOL PyWin_RegisterErrorMessageModule(DWORD first, DWORD last, HINSTANCE hmod);
// Get the previously registered hmodule for an error code.
extern PYWINTYPES_EXPORT HINSTANCE PyWin_GetErrorMessageModule(DWORD err);
/* A global function that sets an API style error (ie, (code, fn, errTest)) */
PYWINTYPES_EXPORT PyObject *PyWin_SetAPIError(char *fnName, long err = 0);
/* Basic COM Exception handling. The main COM exception object
is actually defined here. However, the most useful functions
for raising the exception are still in the COM package. Therefore,
you can use the fn below to raise a basic COM exception - no fancy error
messages available, just the HRESULT. It will, however, _be_ a COM
exception, and therefore trappable like any other COM exception
*/
extern PYWINTYPES_EXPORT PyObject *PyWinExc_COMError;
PYWINTYPES_EXPORT PyObject *PyWin_SetBasicCOMError(HRESULT hr);
// *************
// strings, which are a bit of a mess!
//
// This has gone from 2.x ascii-only, to 2.x+3.x ascii-or-unicode, to 3.x unicode-only,
// - this baggage means some strange APIs which convert to and from "char *" in various ways.
//
// A sizes/lengths are reported as a `DWORD` rather than a `Py_ssize_t`, that's what the callers
// need. `Py_ssize_t` used as the "in" type.
// (We also use this for UINT and ULONG, all of which are 32bit unsigned ints.)
// Sometimes we need to downcast from a ssize_t to a DWORD
inline bool PyWin_is_ssize_dword(Py_ssize_t val) {
return val <= MAXDWORD;
}
#define PYWIN_CHECK_SSIZE_DWORD(val, failResult) \
if (!PyWin_is_ssize_dword(val)) { \
PyErr_SetString(PyExc_ValueError, "value is larger than a DWORD"); \
return failResult; \
}
// Almost all of these are roughly identical! But start with BSTR
// Given a PyObject (string, Unicode, etc) create a "BSTR" with the value
PYWINTYPES_EXPORT BOOL PyWinObject_AsBstr(PyObject *stringObject, BSTR *pResult, BOOL bNoneOK = FALSE,
DWORD *pResultLen = NULL);
// And free it when finished.
PYWINTYPES_EXPORT void PyWinObject_FreeBstr(BSTR pResult);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromBstr(const BSTR bstr, BOOL takeOwnership = FALSE);
// Given a string or Unicode object, get WCHAR characters.
PYWINTYPES_EXPORT BOOL PyWinObject_AsWCHAR(PyObject *stringObject, WCHAR **pResult, BOOL bNoneOK = FALSE,
DWORD *pResultLen = NULL);
// And free it when finished.
PYWINTYPES_EXPORT void PyWinObject_FreeWCHAR(WCHAR *pResult);
inline BOOL PyWinObject_AsWCHAR(PyObject *stringObject, unsigned short **pResult, BOOL bNoneOK = FALSE,
DWORD *pResultLen = NULL)
{
return PyWinObject_AsWCHAR(stringObject, (WCHAR **)pResult, bNoneOK, pResultLen);
}
inline void PyWinObject_FreeWCHAR(unsigned short *pResult) { PyWinObject_FreeWCHAR((WCHAR *)pResult); }
// A bit unfortunate, but used when we logically want a "string" but only have
// a "char *" to put it in.
// * accepts bytes but boesn't try to accept buffer-like objects.
// * accepts unicode objects and converts via the code-page.
PYWINTYPES_EXPORT BOOL PyWinObject_AsChars(PyObject *stringObject, char **pResult, BOOL bNoneOK = FALSE,
DWORD *pResultLen = NULL);
// And free it when finished.
PYWINTYPES_EXPORT void PyWinObject_FreeChars(char *pResult);
// Automatically freed WCHAR that can be used anywhere WCHAR * is required
class TmpWCHAR {
public:
WCHAR *tmp; // (NULL after conversion error)
Py_ssize_t length; // only set after successful auto-conversion; w/o trailing \0
PyObject *u; // auxiliary slot for u2w()
TmpWCHAR() { tmp = NULL; }
TmpWCHAR(WCHAR *t) { tmp = t; }
TmpWCHAR(PyObject *ob) : tmp(NULL) { *this = ob; }
WCHAR *u2w() { return *this = u; }
WCHAR *operator=(PyObject *ob) {
if (tmp)
PyMem_Free(tmp);
if (ob == NULL)
tmp = NULL; // (exception already has been set in this case)
else
tmp = PyUnicode_AsWideCharString(ob, &length);
return tmp;
}
WCHAR *operator=(WCHAR *t)
{
if (tmp)
PyMem_Free(tmp);
tmp = t;
return t;
}
WCHAR **operator&() { return &tmp; }
boolean operator==(WCHAR *t) { return tmp == t; }
operator WCHAR *() { return tmp; }
~TmpWCHAR() { if (tmp) PyMem_Free(tmp); }
private:
// Block unwanted copy construction
TmpWCHAR(const TmpWCHAR& o); // = delete;
const TmpWCHAR& operator=(const TmpWCHAR& o); // = delete;
};
// More string helpers - how many do we need?
// A couple which should die or be modernized and have some `char *` vs `wchar_t *` confusion.
PYWINTYPES_EXPORT PyObject *PyWinCoreString_FromString(const char *str, Py_ssize_t len = (Py_ssize_t)-1);
PYWINTYPES_EXPORT PyObject *PyWinCoreString_FromString(const WCHAR *str, Py_ssize_t len = (Py_ssize_t)-1);
#define PyWinObject_FromWCHAR PyWinObject_FromOLECHAR
PYWINTYPES_EXPORT PyObject *PyWinObject_FromOLECHAR(const OLECHAR *str);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromOLECHAR(const OLECHAR *str, Py_ssize_t numChars);
#define PyWinObject_AsTCHAR PyWinObject_AsWCHAR
#define PyWinObject_FreeTCHAR PyWinObject_FreeWCHAR
#define PyWinObject_FromTCHAR PyWinObject_FromOLECHAR
// String support for buffers allocated via CoTaskMemAlloc and CoTaskMemFree
PYWINTYPES_EXPORT BOOL PyWinObject_AsTaskAllocatedWCHAR(PyObject *stringObject, WCHAR **ppResult, BOOL bNoneOK = FALSE);
PYWINTYPES_EXPORT void PyWinObject_FreeTaskAllocatedWCHAR(WCHAR *str);
// Copy null terminated string with same allocator as PyWinObject_AsWCHAR, etc
// ? wot?
PYWINTYPES_EXPORT WCHAR *PyWin_CopyString(const WCHAR *input);
PYWINTYPES_EXPORT char *PyWin_CopyString(const char *input);
// Some helpers for arrays of strings.
//
// Converts a series of consecutive null terminated strings into a list
// ??? wot?
PYWINTYPES_EXPORT PyObject *PyWinObject_FromMultipleString(WCHAR *multistring);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromMultipleString(char *multistring);
// Converts a sequence of str/unicode objects into a series of consecutive null-terminated
// wide character strings with extra terminating null
PYWINTYPES_EXPORT BOOL PyWinObject_AsMultipleString(PyObject *ob, WCHAR **pmultistring, BOOL bNoneOK = TRUE,
DWORD *chars_returned = NULL);
PYWINTYPES_EXPORT void PyWinObject_FreeMultipleString(WCHAR *pmultistring);
// Convert a sequence of strings to an array of WCHAR pointers
PYWINTYPES_EXPORT void PyWinObject_FreeWCHARArray(LPWSTR *wchars, DWORD str_cnt);
PYWINTYPES_EXPORT BOOL PyWinObject_AsWCHARArray(PyObject *str_seq, LPWSTR **wchars, DWORD *str_cnt,
BOOL bNoneOK = FALSE);
// Convert a sequence of string or unicode objects to an array of char *
PYWINTYPES_EXPORT void PyWinObject_FreeCharArray(char **pchars, DWORD str_cnt);
PYWINTYPES_EXPORT BOOL PyWinObject_AsCharArray(PyObject *str_seq, char ***pchars, DWORD *str_cnt, BOOL bNoneOK = FALSE);
// Bytes/Buffer helpers.
// replacement for PyWinObject_AsReadBuffer and PyWinObject_AsWriteBuffer
class PYWINTYPES_EXPORT PyWinBufferView
{
public:
PyWinBufferView() { m_view.obj = NULL; }
PyWinBufferView(PyObject *ob, bool bWrite = false, bool bNoneOk = false) {
m_view.obj = NULL;
init(ob, bWrite, bNoneOk);
}
~PyWinBufferView() { release(); }
bool init(PyObject *ob, bool bWrite = false, bool bNoneOk = false);
void release() {
if (m_view.obj != NULL && m_view.obj != Py_None) {
PyBuffer_Release(&m_view); // sets view->obj = NULL
}
}
bool ok() { return m_view.obj != NULL; }
void* ptr() { return m_view.buf; }
DWORD len() { return static_cast<DWORD>(m_view.len); }
private:
Py_buffer m_view;
// don't copy objects and don't use C++ >= 11 -> not implemented private
// copy ctor and assignment operator
PyWinBufferView(const PyWinBufferView& src);
PyWinBufferView& operator=(PyWinBufferView const &);
};
// For 64-bit python compatibility, convert sequence to tuple and check length fits in a DWORD
PYWINTYPES_EXPORT PyObject *PyWinSequence_Tuple(PyObject *obseq, DWORD *len);
// Pointers.
// Substitute for Python's inconsistent PyLong_AsVoidPtr
PYWINTYPES_EXPORT BOOL PyWinLong_AsVoidPtr(PyObject *ob, void **pptr);
PYWINTYPES_EXPORT PyObject *PyWinLong_FromVoidPtr(const void *ptr);
/*
** LARGE_INTEGER objects
*/
// AsLARGE_INTEGER takes either int or long
PYWINTYPES_EXPORT BOOL PyWinObject_AsLARGE_INTEGER(PyObject *ob, LARGE_INTEGER *pResult);
PYWINTYPES_EXPORT BOOL PyWinObject_AsULARGE_INTEGER(PyObject *ob, ULARGE_INTEGER *pResult);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromLARGE_INTEGER(const LARGE_INTEGER &val);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromULARGE_INTEGER(const ULARGE_INTEGER &val);
// Helpers that take a Py_LONG_LONG, but (a) have pywin32 consistent signatures
// and (b) handle int *and* long (where Python only starts doing that in the
// PyLong_* APIs post 2.4)
// We also happen to know a LARGE_INTEGER is an __int64, so do it the easy way
#define PyWinObject_AsPY_LONG_LONG(ob, pResult) PyWinObject_AsLARGE_INTEGER((ob), (LARGE_INTEGER *)(pResult))
#define PyWinObject_AsUPY_LONG_LONG(ob, pResult) PyWinObject_AsULARGE_INTEGER((ob), (ULARGE_INTEGER *)(pResult))
#define PyWinObject_FromPY_LONG_LONG(val) PyWinObject_FromLARGE_INTEGER((LARGE_INTEGER)val)
#define PyWinObject_FromUPY_LONG_LONG(val) PyWinObject_FromULARGE_INTEGER((ULARGE_INTEGER)val)
// A DWORD_PTR and ULONG_PTR appear to mean "integer long enough to hold a pointer"
// It is *not* actually a pointer (but is the same size as a pointer)
inline PyObject *PyWinObject_FromULONG_PTR(ULONG_PTR v) { return PyWinLong_FromVoidPtr((void *)v); }
inline BOOL PyWinLong_AsULONG_PTR(PyObject *ob, ULONG_PTR *r) { return PyWinLong_AsVoidPtr(ob, (void **)r); }
inline PyObject *PyWinObject_FromDWORD_PTR(DWORD_PTR v) { return PyLong_FromVoidPtr((void *)v); }
inline BOOL PyWinLong_AsDWORD_PTR(PyObject *ob, DWORD_PTR *r) { return PyWinLong_AsVoidPtr(ob, (void **)r); }
/*
** OVERLAPPED Object and API
*/
class PyOVERLAPPED; // forward declare
extern PYWINTYPES_EXPORT PyTypeObject PyOVERLAPPEDType; // the Type for PyOVERLAPPED
#define PyOVERLAPPED_Check(ob) ((ob)->ob_type == &PyOVERLAPPEDType)
PYWINTYPES_EXPORT BOOL PyWinObject_AsOVERLAPPED(PyObject *ob, OVERLAPPED **ppOverlapped, BOOL bNoneOK = TRUE);
PYWINTYPES_EXPORT BOOL PyWinObject_AsPyOVERLAPPED(PyObject *ob, PyOVERLAPPED **ppOverlapped, BOOL bNoneOK = TRUE);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromOVERLAPPED(const OVERLAPPED *pOverlapped);
// A global function that can work as a module method for making an OVERLAPPED object.
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewOVERLAPPED(PyObject *self, PyObject *args);
#ifndef NO_PYWINTYPES_IID
/*
** IID/GUID support
*/
extern PYWINTYPES_EXPORT PyTypeObject PyIIDType; // the Type for PyIID
#define PyIID_Check(ob) ((ob)->ob_type == &PyIIDType)
// Given an object repring a CLSID (either PyIID or string), fill the CLSID.
PYWINTYPES_EXPORT BOOL PyWinObject_AsIID(PyObject *obCLSID, CLSID *clsid);
// return a native PyIID object representing an IID
PYWINTYPES_EXPORT PyObject *PyWinObject_FromIID(const IID &riid);
// return a string/Unicode object representing an IID
PYWINTYPES_EXPORT PyObject *PyWinCoreString_FromIID(const IID &riid);
// A global function that can work as a module method for making an IID object.
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewIID(PyObject *self, PyObject *args);
#endif /*NO_PYWINTYPES_IID */
/*
** TIME support
**
** We use a subclass of the builtin datetime.
*/
PYWINTYPES_EXPORT PyObject *PyWinObject_FromSYSTEMTIME(const SYSTEMTIME &t);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromFILETIME(const FILETIME &t);
// Converts a TimeStamp, which is in 100 nanosecond units like a FILETIME
// TimeStamp is actually defined as a LARGE_INTEGER, so this function will also
// accept Windows security "TimeStamp" objects directly - however, we use a
// LARGE_INTEGER prototype to avoid pulling in the windows security headers.
PYWINTYPES_EXPORT PyObject *PyWinObject_FromTimeStamp(const LARGE_INTEGER &t);
PYWINTYPES_EXPORT PyObject *PyWinTimeObject_Fromtime_t(time_t t);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromDATE(DATE t);
PYWINTYPES_EXPORT BOOL PyWinObject_AsDATE(PyObject *ob, DATE *pDate);
PYWINTYPES_EXPORT BOOL PyWinObject_AsFILETIME(PyObject *ob, FILETIME *pDate);
PYWINTYPES_EXPORT BOOL PyWinObject_AsSYSTEMTIME(PyObject *ob, SYSTEMTIME *pDate);
// A global function that can work as a module method for making a time object.
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewTime(PyObject *self, PyObject *args);
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewTimeStamp(PyObject *self, PyObject *args);
PYWINTYPES_EXPORT BOOL PyWinTime_Check(PyObject *ob);
// functions to return WIN32_FIND_DATA tuples, used in shell, win32api, and win32file
PYWINTYPES_EXPORT PyObject *PyObject_FromWIN32_FIND_DATAW(WIN32_FIND_DATAW *pData);
#define PyObject_FromWIN32_FIND_DATA PyObject_FromWIN32_FIND_DATAW
// POINT tuple, used in win32api_display.cpp and win32gui.i
PYWINTYPES_EXPORT BOOL PyWinObject_AsPOINT(PyObject *obpoint, LPPOINT ppoint);
// IO_COUNTERS dict, used in win32process and win32job
PYWINTYPES_EXPORT PyObject *PyWinObject_FromIO_COUNTERS(PIO_COUNTERS pioc);
// Make an array of DWORD's from a sequence of Python ints
PYWINTYPES_EXPORT BOOL PyWinObject_AsDWORDArray(PyObject *obdwords, DWORD **pdwords, DWORD *item_cnt,
BOOL bNoneOk = TRUE);
// Conversion for resource id/name and class atom
PYWINTYPES_EXPORT BOOL PyWinObject_AsResourceIdA(PyObject *ob, char **presource_id, BOOL bNoneOK = FALSE);
PYWINTYPES_EXPORT void PyWinObject_FreeResourceIdA(char *resource_id);
PYWINTYPES_EXPORT BOOL PyWinObject_AsResourceId(PyObject *ob, WCHAR **presource_id, BOOL bNoneOK = FALSE);
PYWINTYPES_EXPORT void PyWinObject_FreeResourceId(WCHAR *resource_id);
// WPARAM and LPARAM conversion.
// Auto-freed WPARAM / LPARAM which ensure any memory referenced remains valid when a String or
// Buffer object is used. Make sure the destructor is called with the GIL held.
class PyWin_PARAMHolder {
protected:
WPARAM _pa;
// Holds *either* a PyWinBufferView (which will auto-free) *or* a "void *" that we
// will auto-free.
void *_pymem;
void _free() {
if (_pymem) {
PyMem_Free(_pymem);
_pymem = NULL;
}
}
public:
PyWinBufferView bufferView;
PyWin_PARAMHolder(WPARAM t=0):_pa(t),_pymem(NULL) {}
~PyWin_PARAMHolder() {
_free();
}
WCHAR *set_allocated(WCHAR *t) {
assert(!bufferView.ok()); // should be one or the other.
_free();
_pymem = t;
_pa = (WPARAM)t;
return t;
}
// When init_buffer() fails, an appropriate Python error has been set too
bool init_buffer(PyObject *ob) {
assert(!_pymem); // should be one or the other!
_free();
if (!bufferView.init(ob)) {
return false;
}
_pa = (WPARAM)bufferView.ptr();
return true;
}
WPARAM operator=(WPARAM t) {
return _pa = t;
}
operator WPARAM() { return _pa; }
operator LPARAM() { return (LPARAM)_pa; }
};
PYWINTYPES_EXPORT BOOL PyWinObject_AsPARAM(PyObject *ob, PyWin_PARAMHolder *pparam);
inline PyObject *PyWinObject_FromPARAM(WPARAM param) { return PyWinObject_FromULONG_PTR(param); }
inline PyObject *PyWinObject_FromPARAM(LPARAM param) { return PyWinObject_FromULONG_PTR(param); }
PYWINTYPES_EXPORT BOOL PyWinObject_AsSimplePARAM(PyObject *ob, WPARAM *pparam);
inline BOOL PyWinObject_AsSimplePARAM(PyObject *ob, LPARAM *pparam) { return PyWinObject_AsSimplePARAM(ob, (WPARAM *)pparam); }
// RECT conversions
// @object PyRECT|Tuple of 4 ints defining a rectangle: (left, top, right, bottom)
PYWINTYPES_EXPORT BOOL PyWinObject_AsRECT(PyObject *obrect, LPRECT prect);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromRECT(LPRECT prect);
/*
** SECURITY_ATTRIBUTES support
*/
extern PYWINTYPES_EXPORT PyTypeObject PySECURITY_ATTRIBUTESType;
#define PySECURITY_ATTRIBUTES_Check(ob) ((ob)->ob_type == &PySECURITY_ATTRIBUTESType)
extern PYWINTYPES_EXPORT PyTypeObject PyDEVMODEWType;
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewSECURITY_ATTRIBUTES(PyObject *self, PyObject *args);
PYWINTYPES_EXPORT BOOL PyWinObject_AsSECURITY_ATTRIBUTES(PyObject *ob, SECURITY_ATTRIBUTES **ppSECURITY_ATTRIBUTES,
BOOL bNoneOK = TRUE);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromSECURITY_ATTRIBUTES(const SECURITY_ATTRIBUTES &sa);
PYWINTYPES_EXPORT BOOL PyWinObject_AsDEVMODE(PyObject *ob, PDEVMODEW *ppDEVMODE, BOOL bNoneOK);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromDEVMODE(PDEVMODEW);
/*
** WAVEFORMATEX support
*/
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewWAVEFORMATEX(PyObject *self, PyObject *args);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromWAVEFROMATEX(const WAVEFORMATEX &wfx);
PYWINTYPES_EXPORT BOOL PyWinObject_AsWAVEFORMATEX(PyObject *ob, WAVEFORMATEX **ppWAVEFORMATEX, BOOL bNoneOK = TRUE);
extern PYWINTYPES_EXPORT PyTypeObject PyWAVEFORMATEXType;
#define PyWAVEFORMATEX_Check(ob) ((ob)->ob_type == &PyWAVEFORMATEXType)
/*
** SECURITY_DESCRIPTOR support
*/
extern PYWINTYPES_EXPORT PyTypeObject PySECURITY_DESCRIPTORType;
#define PySECURITY_DESCRIPTOR_Check(ob) ((ob)->ob_type == &PySECURITY_DESCRIPTORType)
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewSECURITY_DESCRIPTOR(PyObject *self, PyObject *args);
PYWINTYPES_EXPORT BOOL PyWinObject_AsSECURITY_DESCRIPTOR(PyObject *ob, PSECURITY_DESCRIPTOR *ppSECURITY_DESCRIPTOR,
BOOL bNoneOK = TRUE);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromSECURITY_DESCRIPTOR(PSECURITY_DESCRIPTOR psd);
PYWINTYPES_EXPORT BOOL _MakeAbsoluteSD(PSECURITY_DESCRIPTOR psd_relative, PSECURITY_DESCRIPTOR *ppsd_absolute);
PYWINTYPES_EXPORT void FreeAbsoluteSD(PSECURITY_DESCRIPTOR psd);
/*
** SID support
*/
extern PYWINTYPES_EXPORT PyTypeObject PySIDType;
#define PySID_Check(ob) ((ob)->ob_type == &PySIDType)
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewSID(PyObject *self, PyObject *args);
PYWINTYPES_EXPORT BOOL PyWinObject_AsSID(PyObject *ob, PSID *ppSID, BOOL bNoneOK = FALSE);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromSID(PSID pSID);
/*
** ACL support
*/
extern PYWINTYPES_EXPORT PyTypeObject PyACLType;
#define PyACL_Check(ob) ((ob)->ob_type == &PyACLType)
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewACL(PyObject *self, PyObject *args);
PYWINTYPES_EXPORT BOOL PyWinObject_AsACL(PyObject *ob, PACL *ppACL, BOOL bNoneOK = FALSE);
/*
** Win32 HANDLE wrapper - any handle closable by "CloseHandle()"
*/
extern PYWINTYPES_EXPORT PyTypeObject PyHANDLEType; // the Type for PyHANDLE
#define PyHANDLE_Check(ob) ((ob)->ob_type == &PyHANDLEType)
// Convert an object to a HANDLE - None is always OK, as are ints, etc.
PYWINTYPES_EXPORT BOOL PyWinObject_AsHANDLE(PyObject *ob, HANDLE *pRes);
// For handles that use PyHANDLE.
PYWINTYPES_EXPORT PyObject *PyWinObject_FromHANDLE(HANDLE h);
// For handles that aren't returned as PyHANDLE or a subclass thereof (HDC, HWND, etc).
// Return as python ints or longs
PYWINTYPES_EXPORT PyObject *PyWinLong_FromHANDLE(HANDLE h);
// A global function that can work as a module method for making a HANDLE object.
PYWINTYPES_EXPORT PyObject *PyWinMethod_NewHANDLE(PyObject *self, PyObject *args);
// A global function that does the right thing wrt closing a "handle".
// The object can be either a PyHANDLE or an integer.
// If result is FALSE, a Python error is all setup (cf PyHANDLE::Close(), which doesnt set the Python error)
PYWINTYPES_EXPORT BOOL PyWinObject_CloseHANDLE(PyObject *obHandle);
PYWINTYPES_EXPORT BOOL PyWinObject_AsHKEY(PyObject *ob, HKEY *pRes);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromHKEY(HKEY h);
PYWINTYPES_EXPORT BOOL PyWinObject_CloseHKEY(PyObject *obHandle);
// MSG structure keeps coming up...
PYWINTYPES_EXPORT BOOL PyWinObject_AsMSG(PyObject *ob, MSG *pMsg);
PYWINTYPES_EXPORT PyObject *PyWinObject_FromMSG(const MSG *pMsg);
#include "winsock.h"
/*
** SOCKET support.
*/
PYWINTYPES_EXPORT
BOOL PySocket_AsSOCKET
//-------------------------------------------------------------------------
// Helper function for dealing with socket arguments.
(PyObject *obSocket,
// [in] Python object being converted into a SOCKET handle.
SOCKET *ps
// [out] Returned socket handle
);
/*
** Other Utilities
*/
// ----------------------------------------------------------------------
// WARNING - NEVER EVER USE new() ON THIS CLASS
// This class can be used as a local variable, typically in a Python/C
// function, and can be passed whereever a TCHAR/WCHAR is expected.
// Typical Usage:
// PyWin_AutoFreeBstr arg;
// PyArg_ParseTuple("O", &obStr);
// PyWinObject_AsAutoFreeBstr(obStr, &arg);
// CallTheFunction(arg); // Will correctly pass BSTR/OLECHAR
// -- when the function goes out of scope, the string owned by "arg" will
// -- automatically be freed.
// ----------------------------------------------------------------------
class PYWINTYPES_EXPORT PyWin_AutoFreeBstr {
public:
PyWin_AutoFreeBstr(BSTR bstr = NULL);
~PyWin_AutoFreeBstr();
void SetBstr(BSTR bstr);
operator BSTR() { return m_bstr; }
private:
BSTR m_bstr;
};
inline BOOL PyWinObject_AsAutoFreeBstr(PyObject *stringObject, PyWin_AutoFreeBstr *pResult, BOOL bNoneOK = FALSE)
{
if (bNoneOK && stringObject == Py_None) {
pResult->SetBstr(NULL);
return TRUE;
}
BSTR bs;
if (!PyWinObject_AsBstr(stringObject, &bs, bNoneOK))
return FALSE;
pResult->SetBstr(bs);
return TRUE;
}
// ----------------------------------------------------------------------
//
// THREAD MANAGEMENT
//
// ### need to rename the PYCOM_ stuff soon...
// We have 2 discrete locks in use (when no free-threaded is used, anyway).
// The first type of lock is the global Python lock. This is the standard lock
// in use by Python, and must be used as documented by Python. Specifically, no
// 2 threads may _ever_ call _any_ Python code (including INCREF/DECREF) without
// first having this thread lock.
//
// The second type of lock is a "global framework lock". This lock is simply a
// critical section, and used whenever 2 threads of C code need access to global
// data. This is different than the Python lock - this lock is used when no Python
// code can ever be called by the threads, but the C code still needs thread-safety.
// We also supply helper classes which make the usage of these locks a one-liner.
// The "framework" lock, implemented as a critical section.
PYWINTYPES_EXPORT void PyWin_AcquireGlobalLock(void);
PYWINTYPES_EXPORT void PyWin_ReleaseGlobalLock(void);
// Helper class for the DLL global lock.
//
// This class magically waits for the Win32/COM framework global lock, and releases it
// when finished.
// NEVER new one of these objects - only use on the stack!
class CEnterLeaveFramework {
public:
CEnterLeaveFramework() { PyWin_AcquireGlobalLock(); }
~CEnterLeaveFramework() { PyWin_ReleaseGlobalLock(); }
};
// Python thread-lock stuff. Free-threading patches use different semantics, but
// these are abstracted away here...
#ifndef FORCE_NO_FREE_THREAD
#ifdef WITH_FREE_THREAD
#define PYCOM_USE_FREE_THREAD
#endif
#endif
#ifdef PYCOM_USE_FREE_THREAD
#include <threadstate.h>
#else
#include <pystate.h>
#endif
// Helper class for Enter/Leave Python
//
// This class magically waits for the Python global lock, and releases it
// when finished.
// Nested invocations will deadlock, so be careful.
// NEVER new one of these objects - only use on the stack!
#ifndef PYCOM_USE_FREE_THREAD
extern PYWINTYPES_EXPORT PyInterpreterState *PyWin_InterpreterState;
extern PYWINTYPES_EXPORT BOOL PyWinThreadState_Ensure();
extern PYWINTYPES_EXPORT void PyWinThreadState_Free();
extern PYWINTYPES_EXPORT void PyWinThreadState_Clear();
extern PYWINTYPES_EXPORT void PyWinInterpreterLock_Acquire();
extern PYWINTYPES_EXPORT void PyWinInterpreterLock_Release();
extern PYWINTYPES_EXPORT int PyWinGlobals_Ensure();
extern PYWINTYPES_EXPORT void PyWinGlobals_Free();
#else
#define PyWinThreadState_Ensure PyThreadState_Ensure
#define PyWinThreadState_Free PyThreadState_Free
#define PyWinThreadState_Clear PyThreadState_ClearExc
#endif
extern PYWINTYPES_EXPORT void PyWin_MakePendingCalls();
class CEnterLeavePython {
public:
CEnterLeavePython() : released(TRUE) { acquire(); }
void acquire(void)
{
if (!released)
return;
state = PyGILState_Ensure();
released = FALSE;
}
~CEnterLeavePython() { release(); }
void release(void)
{
if (!released) {
PyGILState_Release(state);
released = TRUE;
}
}
private:
PyGILState_STATE state;
BOOL released;
};
// A helper for simple exception handling.
// try/__try
#if defined(__MINGW32__) || defined(MAINWIN)
#define PYWINTYPES_TRY try
#else
#define PYWINTYPES_TRY __try
#endif /* MAINWIN */
// catch/__except
#if defined(__MINGW32__) || defined(MAINWIN)
#define PYWINTYPES_EXCEPT catch (...)
#else
#define PYWINTYPES_EXCEPT __except (EXCEPTION_EXECUTE_HANDLER)
#endif
// End of exception helper macros.
// Class to hold a temporary reference that decrements itself
class TmpPyObject {
public:
PyObject *tmp;
TmpPyObject() { tmp = NULL; }
TmpPyObject(PyObject *ob) { tmp = ob; }
PyObject *operator=(PyObject *ob)
{
Py_XDECREF(tmp);
tmp = ob;
return tmp;
}
boolean operator==(PyObject *ob) { return tmp == ob; }
operator PyObject *() { return tmp; }
~TmpPyObject() { Py_XDECREF(tmp); }
};
#endif // __PYWINTYPES_H__

501
lib/win32/lib/afxres.py Normal file
View file

@ -0,0 +1,501 @@
# Generated by h2py from stdin
TCS_MULTILINE = 0x0200
CBRS_ALIGN_LEFT = 0x1000
CBRS_ALIGN_TOP = 0x2000
CBRS_ALIGN_RIGHT = 0x4000
CBRS_ALIGN_BOTTOM = 0x8000
CBRS_ALIGN_ANY = 0xF000
CBRS_BORDER_LEFT = 0x0100
CBRS_BORDER_TOP = 0x0200
CBRS_BORDER_RIGHT = 0x0400
CBRS_BORDER_BOTTOM = 0x0800
CBRS_BORDER_ANY = 0x0F00
CBRS_TOOLTIPS = 0x0010
CBRS_FLYBY = 0x0020
CBRS_FLOAT_MULTI = 0x0040
CBRS_BORDER_3D = 0x0080
CBRS_HIDE_INPLACE = 0x0008
CBRS_SIZE_DYNAMIC = 0x0004
CBRS_SIZE_FIXED = 0x0002
CBRS_FLOATING = 0x0001
CBRS_GRIPPER = 0x00400000
CBRS_ORIENT_HORZ = CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM
CBRS_ORIENT_VERT = CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT
CBRS_ORIENT_ANY = CBRS_ORIENT_HORZ | CBRS_ORIENT_VERT
CBRS_ALL = 0xFFFF
CBRS_NOALIGN = 0x00000000
CBRS_LEFT = CBRS_ALIGN_LEFT | CBRS_BORDER_RIGHT
CBRS_TOP = CBRS_ALIGN_TOP | CBRS_BORDER_BOTTOM
CBRS_RIGHT = CBRS_ALIGN_RIGHT | CBRS_BORDER_LEFT
CBRS_BOTTOM = CBRS_ALIGN_BOTTOM | CBRS_BORDER_TOP
SBPS_NORMAL = 0x0000
SBPS_NOBORDERS = 0x0100
SBPS_POPOUT = 0x0200
SBPS_OWNERDRAW = 0x1000
SBPS_DISABLED = 0x04000000
SBPS_STRETCH = 0x08000000
ID_INDICATOR_EXT = 0xE700
ID_INDICATOR_CAPS = 0xE701
ID_INDICATOR_NUM = 0xE702
ID_INDICATOR_SCRL = 0xE703
ID_INDICATOR_OVR = 0xE704
ID_INDICATOR_REC = 0xE705
ID_INDICATOR_KANA = 0xE706
ID_SEPARATOR = 0
AFX_IDW_CONTROLBAR_FIRST = 0xE800
AFX_IDW_CONTROLBAR_LAST = 0xE8FF
AFX_IDW_TOOLBAR = 0xE800
AFX_IDW_STATUS_BAR = 0xE801
AFX_IDW_PREVIEW_BAR = 0xE802
AFX_IDW_RESIZE_BAR = 0xE803
AFX_IDW_DOCKBAR_TOP = 0xE81B
AFX_IDW_DOCKBAR_LEFT = 0xE81C
AFX_IDW_DOCKBAR_RIGHT = 0xE81D
AFX_IDW_DOCKBAR_BOTTOM = 0xE81E
AFX_IDW_DOCKBAR_FLOAT = 0xE81F
def AFX_CONTROLBAR_MASK(nIDC):
return 1 << (nIDC - AFX_IDW_CONTROLBAR_FIRST)
AFX_IDW_PANE_FIRST = 0xE900
AFX_IDW_PANE_LAST = 0xE9FF
AFX_IDW_HSCROLL_FIRST = 0xEA00
AFX_IDW_VSCROLL_FIRST = 0xEA10
AFX_IDW_SIZE_BOX = 0xEA20
AFX_IDW_PANE_SAVE = 0xEA21
AFX_IDS_APP_TITLE = 0xE000
AFX_IDS_IDLEMESSAGE = 0xE001
AFX_IDS_HELPMODEMESSAGE = 0xE002
AFX_IDS_APP_TITLE_EMBEDDING = 0xE003
AFX_IDS_COMPANY_NAME = 0xE004
AFX_IDS_OBJ_TITLE_INPLACE = 0xE005
ID_FILE_NEW = 0xE100
ID_FILE_OPEN = 0xE101
ID_FILE_CLOSE = 0xE102
ID_FILE_SAVE = 0xE103
ID_FILE_SAVE_AS = 0xE104
ID_FILE_PAGE_SETUP = 0xE105
ID_FILE_PRINT_SETUP = 0xE106
ID_FILE_PRINT = 0xE107
ID_FILE_PRINT_DIRECT = 0xE108
ID_FILE_PRINT_PREVIEW = 0xE109
ID_FILE_UPDATE = 0xE10A
ID_FILE_SAVE_COPY_AS = 0xE10B
ID_FILE_SEND_MAIL = 0xE10C
ID_FILE_MRU_FIRST = 0xE110
ID_FILE_MRU_FILE1 = 0xE110
ID_FILE_MRU_FILE2 = 0xE111
ID_FILE_MRU_FILE3 = 0xE112
ID_FILE_MRU_FILE4 = 0xE113
ID_FILE_MRU_FILE5 = 0xE114
ID_FILE_MRU_FILE6 = 0xE115
ID_FILE_MRU_FILE7 = 0xE116
ID_FILE_MRU_FILE8 = 0xE117
ID_FILE_MRU_FILE9 = 0xE118
ID_FILE_MRU_FILE10 = 0xE119
ID_FILE_MRU_FILE11 = 0xE11A
ID_FILE_MRU_FILE12 = 0xE11B
ID_FILE_MRU_FILE13 = 0xE11C
ID_FILE_MRU_FILE14 = 0xE11D
ID_FILE_MRU_FILE15 = 0xE11E
ID_FILE_MRU_FILE16 = 0xE11F
ID_FILE_MRU_LAST = 0xE11F
ID_EDIT_CLEAR = 0xE120
ID_EDIT_CLEAR_ALL = 0xE121
ID_EDIT_COPY = 0xE122
ID_EDIT_CUT = 0xE123
ID_EDIT_FIND = 0xE124
ID_EDIT_PASTE = 0xE125
ID_EDIT_PASTE_LINK = 0xE126
ID_EDIT_PASTE_SPECIAL = 0xE127
ID_EDIT_REPEAT = 0xE128
ID_EDIT_REPLACE = 0xE129
ID_EDIT_SELECT_ALL = 0xE12A
ID_EDIT_UNDO = 0xE12B
ID_EDIT_REDO = 0xE12C
ID_WINDOW_NEW = 0xE130
ID_WINDOW_ARRANGE = 0xE131
ID_WINDOW_CASCADE = 0xE132
ID_WINDOW_TILE_HORZ = 0xE133
ID_WINDOW_TILE_VERT = 0xE134
ID_WINDOW_SPLIT = 0xE135
AFX_IDM_WINDOW_FIRST = 0xE130
AFX_IDM_WINDOW_LAST = 0xE13F
AFX_IDM_FIRST_MDICHILD = 0xFF00
ID_APP_ABOUT = 0xE140
ID_APP_EXIT = 0xE141
ID_HELP_INDEX = 0xE142
ID_HELP_FINDER = 0xE143
ID_HELP_USING = 0xE144
ID_CONTEXT_HELP = 0xE145
ID_HELP = 0xE146
ID_DEFAULT_HELP = 0xE147
ID_NEXT_PANE = 0xE150
ID_PREV_PANE = 0xE151
ID_FORMAT_FONT = 0xE160
ID_OLE_INSERT_NEW = 0xE200
ID_OLE_EDIT_LINKS = 0xE201
ID_OLE_EDIT_CONVERT = 0xE202
ID_OLE_EDIT_CHANGE_ICON = 0xE203
ID_OLE_EDIT_PROPERTIES = 0xE204
ID_OLE_VERB_FIRST = 0xE210
ID_OLE_VERB_LAST = 0xE21F
AFX_ID_PREVIEW_CLOSE = 0xE300
AFX_ID_PREVIEW_NUMPAGE = 0xE301
AFX_ID_PREVIEW_NEXT = 0xE302
AFX_ID_PREVIEW_PREV = 0xE303
AFX_ID_PREVIEW_PRINT = 0xE304
AFX_ID_PREVIEW_ZOOMIN = 0xE305
AFX_ID_PREVIEW_ZOOMOUT = 0xE306
ID_VIEW_TOOLBAR = 0xE800
ID_VIEW_STATUS_BAR = 0xE801
ID_RECORD_FIRST = 0xE900
ID_RECORD_LAST = 0xE901
ID_RECORD_NEXT = 0xE902
ID_RECORD_PREV = 0xE903
IDC_STATIC = -1
AFX_IDS_SCFIRST = 0xEF00
AFX_IDS_SCSIZE = 0xEF00
AFX_IDS_SCMOVE = 0xEF01
AFX_IDS_SCMINIMIZE = 0xEF02
AFX_IDS_SCMAXIMIZE = 0xEF03
AFX_IDS_SCNEXTWINDOW = 0xEF04
AFX_IDS_SCPREVWINDOW = 0xEF05
AFX_IDS_SCCLOSE = 0xEF06
AFX_IDS_SCRESTORE = 0xEF12
AFX_IDS_SCTASKLIST = 0xEF13
AFX_IDS_MDICHILD = 0xEF1F
AFX_IDS_DESKACCESSORY = 0xEFDA
AFX_IDS_OPENFILE = 0xF000
AFX_IDS_SAVEFILE = 0xF001
AFX_IDS_ALLFILTER = 0xF002
AFX_IDS_UNTITLED = 0xF003
AFX_IDS_SAVEFILECOPY = 0xF004
AFX_IDS_PREVIEW_CLOSE = 0xF005
AFX_IDS_UNNAMED_FILE = 0xF006
AFX_IDS_ABOUT = 0xF010
AFX_IDS_HIDE = 0xF011
AFX_IDP_NO_ERROR_AVAILABLE = 0xF020
AFX_IDS_NOT_SUPPORTED_EXCEPTION = 0xF021
AFX_IDS_RESOURCE_EXCEPTION = 0xF022
AFX_IDS_MEMORY_EXCEPTION = 0xF023
AFX_IDS_USER_EXCEPTION = 0xF024
AFX_IDS_PRINTONPORT = 0xF040
AFX_IDS_ONEPAGE = 0xF041
AFX_IDS_TWOPAGE = 0xF042
AFX_IDS_PRINTPAGENUM = 0xF043
AFX_IDS_PREVIEWPAGEDESC = 0xF044
AFX_IDS_PRINTDEFAULTEXT = 0xF045
AFX_IDS_PRINTDEFAULT = 0xF046
AFX_IDS_PRINTFILTER = 0xF047
AFX_IDS_PRINTCAPTION = 0xF048
AFX_IDS_PRINTTOFILE = 0xF049
AFX_IDS_OBJECT_MENUITEM = 0xF080
AFX_IDS_EDIT_VERB = 0xF081
AFX_IDS_ACTIVATE_VERB = 0xF082
AFX_IDS_CHANGE_LINK = 0xF083
AFX_IDS_AUTO = 0xF084
AFX_IDS_MANUAL = 0xF085
AFX_IDS_FROZEN = 0xF086
AFX_IDS_ALL_FILES = 0xF087
AFX_IDS_SAVE_MENU = 0xF088
AFX_IDS_UPDATE_MENU = 0xF089
AFX_IDS_SAVE_AS_MENU = 0xF08A
AFX_IDS_SAVE_COPY_AS_MENU = 0xF08B
AFX_IDS_EXIT_MENU = 0xF08C
AFX_IDS_UPDATING_ITEMS = 0xF08D
AFX_IDS_METAFILE_FORMAT = 0xF08E
AFX_IDS_DIB_FORMAT = 0xF08F
AFX_IDS_BITMAP_FORMAT = 0xF090
AFX_IDS_LINKSOURCE_FORMAT = 0xF091
AFX_IDS_EMBED_FORMAT = 0xF092
AFX_IDS_PASTELINKEDTYPE = 0xF094
AFX_IDS_UNKNOWNTYPE = 0xF095
AFX_IDS_RTF_FORMAT = 0xF096
AFX_IDS_TEXT_FORMAT = 0xF097
AFX_IDS_INVALID_CURRENCY = 0xF098
AFX_IDS_INVALID_DATETIME = 0xF099
AFX_IDS_INVALID_DATETIMESPAN = 0xF09A
AFX_IDP_INVALID_FILENAME = 0xF100
AFX_IDP_FAILED_TO_OPEN_DOC = 0xF101
AFX_IDP_FAILED_TO_SAVE_DOC = 0xF102
AFX_IDP_ASK_TO_SAVE = 0xF103
AFX_IDP_FAILED_TO_CREATE_DOC = 0xF104
AFX_IDP_FILE_TOO_LARGE = 0xF105
AFX_IDP_FAILED_TO_START_PRINT = 0xF106
AFX_IDP_FAILED_TO_LAUNCH_HELP = 0xF107
AFX_IDP_INTERNAL_FAILURE = 0xF108
AFX_IDP_COMMAND_FAILURE = 0xF109
AFX_IDP_FAILED_MEMORY_ALLOC = 0xF10A
AFX_IDP_PARSE_INT = 0xF110
AFX_IDP_PARSE_REAL = 0xF111
AFX_IDP_PARSE_INT_RANGE = 0xF112
AFX_IDP_PARSE_REAL_RANGE = 0xF113
AFX_IDP_PARSE_STRING_SIZE = 0xF114
AFX_IDP_PARSE_RADIO_BUTTON = 0xF115
AFX_IDP_PARSE_BYTE = 0xF116
AFX_IDP_PARSE_UINT = 0xF117
AFX_IDP_PARSE_DATETIME = 0xF118
AFX_IDP_PARSE_CURRENCY = 0xF119
AFX_IDP_FAILED_INVALID_FORMAT = 0xF120
AFX_IDP_FAILED_INVALID_PATH = 0xF121
AFX_IDP_FAILED_DISK_FULL = 0xF122
AFX_IDP_FAILED_ACCESS_READ = 0xF123
AFX_IDP_FAILED_ACCESS_WRITE = 0xF124
AFX_IDP_FAILED_IO_ERROR_READ = 0xF125
AFX_IDP_FAILED_IO_ERROR_WRITE = 0xF126
AFX_IDP_STATIC_OBJECT = 0xF180
AFX_IDP_FAILED_TO_CONNECT = 0xF181
AFX_IDP_SERVER_BUSY = 0xF182
AFX_IDP_BAD_VERB = 0xF183
AFX_IDP_FAILED_TO_NOTIFY = 0xF185
AFX_IDP_FAILED_TO_LAUNCH = 0xF186
AFX_IDP_ASK_TO_UPDATE = 0xF187
AFX_IDP_FAILED_TO_UPDATE = 0xF188
AFX_IDP_FAILED_TO_REGISTER = 0xF189
AFX_IDP_FAILED_TO_AUTO_REGISTER = 0xF18A
AFX_IDP_FAILED_TO_CONVERT = 0xF18B
AFX_IDP_GET_NOT_SUPPORTED = 0xF18C
AFX_IDP_SET_NOT_SUPPORTED = 0xF18D
AFX_IDP_ASK_TO_DISCARD = 0xF18E
AFX_IDP_FAILED_TO_CREATE = 0xF18F
AFX_IDP_FAILED_MAPI_LOAD = 0xF190
AFX_IDP_INVALID_MAPI_DLL = 0xF191
AFX_IDP_FAILED_MAPI_SEND = 0xF192
AFX_IDP_FILE_NONE = 0xF1A0
AFX_IDP_FILE_GENERIC = 0xF1A1
AFX_IDP_FILE_NOT_FOUND = 0xF1A2
AFX_IDP_FILE_BAD_PATH = 0xF1A3
AFX_IDP_FILE_TOO_MANY_OPEN = 0xF1A4
AFX_IDP_FILE_ACCESS_DENIED = 0xF1A5
AFX_IDP_FILE_INVALID_FILE = 0xF1A6
AFX_IDP_FILE_REMOVE_CURRENT = 0xF1A7
AFX_IDP_FILE_DIR_FULL = 0xF1A8
AFX_IDP_FILE_BAD_SEEK = 0xF1A9
AFX_IDP_FILE_HARD_IO = 0xF1AA
AFX_IDP_FILE_SHARING = 0xF1AB
AFX_IDP_FILE_LOCKING = 0xF1AC
AFX_IDP_FILE_DISKFULL = 0xF1AD
AFX_IDP_FILE_EOF = 0xF1AE
AFX_IDP_ARCH_NONE = 0xF1B0
AFX_IDP_ARCH_GENERIC = 0xF1B1
AFX_IDP_ARCH_READONLY = 0xF1B2
AFX_IDP_ARCH_ENDOFFILE = 0xF1B3
AFX_IDP_ARCH_WRITEONLY = 0xF1B4
AFX_IDP_ARCH_BADINDEX = 0xF1B5
AFX_IDP_ARCH_BADCLASS = 0xF1B6
AFX_IDP_ARCH_BADSCHEMA = 0xF1B7
AFX_IDS_OCC_SCALEUNITS_PIXELS = 0xF1C0
AFX_IDS_STATUS_FONT = 0xF230
AFX_IDS_TOOLTIP_FONT = 0xF231
AFX_IDS_UNICODE_FONT = 0xF232
AFX_IDS_MINI_FONT = 0xF233
AFX_IDP_SQL_FIRST = 0xF280
AFX_IDP_SQL_CONNECT_FAIL = 0xF281
AFX_IDP_SQL_RECORDSET_FORWARD_ONLY = 0xF282
AFX_IDP_SQL_EMPTY_COLUMN_LIST = 0xF283
AFX_IDP_SQL_FIELD_SCHEMA_MISMATCH = 0xF284
AFX_IDP_SQL_ILLEGAL_MODE = 0xF285
AFX_IDP_SQL_MULTIPLE_ROWS_AFFECTED = 0xF286
AFX_IDP_SQL_NO_CURRENT_RECORD = 0xF287
AFX_IDP_SQL_NO_ROWS_AFFECTED = 0xF288
AFX_IDP_SQL_RECORDSET_READONLY = 0xF289
AFX_IDP_SQL_SQL_NO_TOTAL = 0xF28A
AFX_IDP_SQL_ODBC_LOAD_FAILED = 0xF28B
AFX_IDP_SQL_DYNASET_NOT_SUPPORTED = 0xF28C
AFX_IDP_SQL_SNAPSHOT_NOT_SUPPORTED = 0xF28D
AFX_IDP_SQL_API_CONFORMANCE = 0xF28E
AFX_IDP_SQL_SQL_CONFORMANCE = 0xF28F
AFX_IDP_SQL_NO_DATA_FOUND = 0xF290
AFX_IDP_SQL_ROW_UPDATE_NOT_SUPPORTED = 0xF291
AFX_IDP_SQL_ODBC_V2_REQUIRED = 0xF292
AFX_IDP_SQL_NO_POSITIONED_UPDATES = 0xF293
AFX_IDP_SQL_LOCK_MODE_NOT_SUPPORTED = 0xF294
AFX_IDP_SQL_DATA_TRUNCATED = 0xF295
AFX_IDP_SQL_ROW_FETCH = 0xF296
AFX_IDP_SQL_INCORRECT_ODBC = 0xF297
AFX_IDP_SQL_UPDATE_DELETE_FAILED = 0xF298
AFX_IDP_SQL_DYNAMIC_CURSOR_NOT_SUPPORTED = 0xF299
AFX_IDP_DAO_FIRST = 0xF2A0
AFX_IDP_DAO_ENGINE_INITIALIZATION = 0xF2A0
AFX_IDP_DAO_DFX_BIND = 0xF2A1
AFX_IDP_DAO_OBJECT_NOT_OPEN = 0xF2A2
AFX_IDP_DAO_ROWTOOSHORT = 0xF2A3
AFX_IDP_DAO_BADBINDINFO = 0xF2A4
AFX_IDP_DAO_COLUMNUNAVAILABLE = 0xF2A5
AFX_IDC_LISTBOX = 100
AFX_IDC_CHANGE = 101
AFX_IDC_PRINT_DOCNAME = 201
AFX_IDC_PRINT_PRINTERNAME = 202
AFX_IDC_PRINT_PORTNAME = 203
AFX_IDC_PRINT_PAGENUM = 204
ID_APPLY_NOW = 0x3021
ID_WIZBACK = 0x3023
ID_WIZNEXT = 0x3024
ID_WIZFINISH = 0x3025
AFX_IDC_TAB_CONTROL = 0x3020
AFX_IDD_FILEOPEN = 28676
AFX_IDD_FILESAVE = 28677
AFX_IDD_FONT = 28678
AFX_IDD_COLOR = 28679
AFX_IDD_PRINT = 28680
AFX_IDD_PRINTSETUP = 28681
AFX_IDD_FIND = 28682
AFX_IDD_REPLACE = 28683
AFX_IDD_NEWTYPEDLG = 30721
AFX_IDD_PRINTDLG = 30722
AFX_IDD_PREVIEW_TOOLBAR = 30723
AFX_IDD_PREVIEW_SHORTTOOLBAR = 30731
AFX_IDD_INSERTOBJECT = 30724
AFX_IDD_CHANGEICON = 30725
AFX_IDD_CONVERT = 30726
AFX_IDD_PASTESPECIAL = 30727
AFX_IDD_EDITLINKS = 30728
AFX_IDD_FILEBROWSE = 30729
AFX_IDD_BUSY = 30730
AFX_IDD_OBJECTPROPERTIES = 30732
AFX_IDD_CHANGESOURCE = 30733
AFX_IDC_CONTEXTHELP = 30977
AFX_IDC_MAGNIFY = 30978
AFX_IDC_SMALLARROWS = 30979
AFX_IDC_HSPLITBAR = 30980
AFX_IDC_VSPLITBAR = 30981
AFX_IDC_NODROPCRSR = 30982
AFX_IDC_TRACKNWSE = 30983
AFX_IDC_TRACKNESW = 30984
AFX_IDC_TRACKNS = 30985
AFX_IDC_TRACKWE = 30986
AFX_IDC_TRACK4WAY = 30987
AFX_IDC_MOVE4WAY = 30988
AFX_IDB_MINIFRAME_MENU = 30994
AFX_IDB_CHECKLISTBOX_NT = 30995
AFX_IDB_CHECKLISTBOX_95 = 30996
AFX_IDR_PREVIEW_ACCEL = 30997
AFX_IDI_STD_MDIFRAME = 31233
AFX_IDI_STD_FRAME = 31234
AFX_IDC_FONTPROP = 1000
AFX_IDC_FONTNAMES = 1001
AFX_IDC_FONTSTYLES = 1002
AFX_IDC_FONTSIZES = 1003
AFX_IDC_STRIKEOUT = 1004
AFX_IDC_UNDERLINE = 1005
AFX_IDC_SAMPLEBOX = 1006
AFX_IDC_COLOR_BLACK = 1100
AFX_IDC_COLOR_WHITE = 1101
AFX_IDC_COLOR_RED = 1102
AFX_IDC_COLOR_GREEN = 1103
AFX_IDC_COLOR_BLUE = 1104
AFX_IDC_COLOR_YELLOW = 1105
AFX_IDC_COLOR_MAGENTA = 1106
AFX_IDC_COLOR_CYAN = 1107
AFX_IDC_COLOR_GRAY = 1108
AFX_IDC_COLOR_LIGHTGRAY = 1109
AFX_IDC_COLOR_DARKRED = 1110
AFX_IDC_COLOR_DARKGREEN = 1111
AFX_IDC_COLOR_DARKBLUE = 1112
AFX_IDC_COLOR_LIGHTBROWN = 1113
AFX_IDC_COLOR_DARKMAGENTA = 1114
AFX_IDC_COLOR_DARKCYAN = 1115
AFX_IDC_COLORPROP = 1116
AFX_IDC_SYSTEMCOLORS = 1117
AFX_IDC_PROPNAME = 1201
AFX_IDC_PICTURE = 1202
AFX_IDC_BROWSE = 1203
AFX_IDC_CLEAR = 1204
AFX_IDD_PROPPAGE_COLOR = 32257
AFX_IDD_PROPPAGE_FONT = 32258
AFX_IDD_PROPPAGE_PICTURE = 32259
AFX_IDB_TRUETYPE = 32384
AFX_IDS_PROPPAGE_UNKNOWN = 0xFE01
AFX_IDS_COLOR_DESKTOP = 0xFE04
AFX_IDS_COLOR_APPWORKSPACE = 0xFE05
AFX_IDS_COLOR_WNDBACKGND = 0xFE06
AFX_IDS_COLOR_WNDTEXT = 0xFE07
AFX_IDS_COLOR_MENUBAR = 0xFE08
AFX_IDS_COLOR_MENUTEXT = 0xFE09
AFX_IDS_COLOR_ACTIVEBAR = 0xFE0A
AFX_IDS_COLOR_INACTIVEBAR = 0xFE0B
AFX_IDS_COLOR_ACTIVETEXT = 0xFE0C
AFX_IDS_COLOR_INACTIVETEXT = 0xFE0D
AFX_IDS_COLOR_ACTIVEBORDER = 0xFE0E
AFX_IDS_COLOR_INACTIVEBORDER = 0xFE0F
AFX_IDS_COLOR_WNDFRAME = 0xFE10
AFX_IDS_COLOR_SCROLLBARS = 0xFE11
AFX_IDS_COLOR_BTNFACE = 0xFE12
AFX_IDS_COLOR_BTNSHADOW = 0xFE13
AFX_IDS_COLOR_BTNTEXT = 0xFE14
AFX_IDS_COLOR_BTNHIGHLIGHT = 0xFE15
AFX_IDS_COLOR_DISABLEDTEXT = 0xFE16
AFX_IDS_COLOR_HIGHLIGHT = 0xFE17
AFX_IDS_COLOR_HIGHLIGHTTEXT = 0xFE18
AFX_IDS_REGULAR = 0xFE19
AFX_IDS_BOLD = 0xFE1A
AFX_IDS_ITALIC = 0xFE1B
AFX_IDS_BOLDITALIC = 0xFE1C
AFX_IDS_SAMPLETEXT = 0xFE1D
AFX_IDS_DISPLAYSTRING_FONT = 0xFE1E
AFX_IDS_DISPLAYSTRING_COLOR = 0xFE1F
AFX_IDS_DISPLAYSTRING_PICTURE = 0xFE20
AFX_IDS_PICTUREFILTER = 0xFE21
AFX_IDS_PICTYPE_UNKNOWN = 0xFE22
AFX_IDS_PICTYPE_NONE = 0xFE23
AFX_IDS_PICTYPE_BITMAP = 0xFE24
AFX_IDS_PICTYPE_METAFILE = 0xFE25
AFX_IDS_PICTYPE_ICON = 0xFE26
AFX_IDS_COLOR_PPG = 0xFE28
AFX_IDS_COLOR_PPG_CAPTION = 0xFE29
AFX_IDS_FONT_PPG = 0xFE2A
AFX_IDS_FONT_PPG_CAPTION = 0xFE2B
AFX_IDS_PICTURE_PPG = 0xFE2C
AFX_IDS_PICTURE_PPG_CAPTION = 0xFE2D
AFX_IDS_PICTUREBROWSETITLE = 0xFE30
AFX_IDS_BORDERSTYLE_0 = 0xFE31
AFX_IDS_BORDERSTYLE_1 = 0xFE32
AFX_IDS_VERB_EDIT = 0xFE40
AFX_IDS_VERB_PROPERTIES = 0xFE41
AFX_IDP_PICTURECANTOPEN = 0xFE83
AFX_IDP_PICTURECANTLOAD = 0xFE84
AFX_IDP_PICTURETOOLARGE = 0xFE85
AFX_IDP_PICTUREREADFAILED = 0xFE86
AFX_IDP_E_ILLEGALFUNCTIONCALL = 0xFEA0
AFX_IDP_E_OVERFLOW = 0xFEA1
AFX_IDP_E_OUTOFMEMORY = 0xFEA2
AFX_IDP_E_DIVISIONBYZERO = 0xFEA3
AFX_IDP_E_OUTOFSTRINGSPACE = 0xFEA4
AFX_IDP_E_OUTOFSTACKSPACE = 0xFEA5
AFX_IDP_E_BADFILENAMEORNUMBER = 0xFEA6
AFX_IDP_E_FILENOTFOUND = 0xFEA7
AFX_IDP_E_BADFILEMODE = 0xFEA8
AFX_IDP_E_FILEALREADYOPEN = 0xFEA9
AFX_IDP_E_DEVICEIOERROR = 0xFEAA
AFX_IDP_E_FILEALREADYEXISTS = 0xFEAB
AFX_IDP_E_BADRECORDLENGTH = 0xFEAC
AFX_IDP_E_DISKFULL = 0xFEAD
AFX_IDP_E_BADRECORDNUMBER = 0xFEAE
AFX_IDP_E_BADFILENAME = 0xFEAF
AFX_IDP_E_TOOMANYFILES = 0xFEB0
AFX_IDP_E_DEVICEUNAVAILABLE = 0xFEB1
AFX_IDP_E_PERMISSIONDENIED = 0xFEB2
AFX_IDP_E_DISKNOTREADY = 0xFEB3
AFX_IDP_E_PATHFILEACCESSERROR = 0xFEB4
AFX_IDP_E_PATHNOTFOUND = 0xFEB5
AFX_IDP_E_INVALIDPATTERNSTRING = 0xFEB6
AFX_IDP_E_INVALIDUSEOFNULL = 0xFEB7
AFX_IDP_E_INVALIDFILEFORMAT = 0xFEB8
AFX_IDP_E_INVALIDPROPERTYVALUE = 0xFEB9
AFX_IDP_E_INVALIDPROPERTYARRAYINDEX = 0xFEBA
AFX_IDP_E_SETNOTSUPPORTEDATRUNTIME = 0xFEBB
AFX_IDP_E_SETNOTSUPPORTED = 0xFEBC
AFX_IDP_E_NEEDPROPERTYARRAYINDEX = 0xFEBD
AFX_IDP_E_SETNOTPERMITTED = 0xFEBE
AFX_IDP_E_GETNOTSUPPORTEDATRUNTIME = 0xFEBF
AFX_IDP_E_GETNOTSUPPORTED = 0xFEC0
AFX_IDP_E_PROPERTYNOTFOUND = 0xFEC1
AFX_IDP_E_INVALIDCLIPBOARDFORMAT = 0xFEC2
AFX_IDP_E_INVALIDPICTURE = 0xFEC3
AFX_IDP_E_PRINTERERROR = 0xFEC4
AFX_IDP_E_CANTSAVEFILETOTEMP = 0xFEC5
AFX_IDP_E_SEARCHTEXTNOTFOUND = 0xFEC6
AFX_IDP_E_REPLACEMENTSTOOLONG = 0xFEC7

1551
lib/win32/lib/commctrl.py Normal file

File diff suppressed because it is too large Load diff

27
lib/win32/lib/dbi.py Normal file
View file

@ -0,0 +1,27 @@
"""
Skeleton replacement for removed dbi module.
Use of objects created by this module should be replaced with native Python objects.
Dates are now returned as datetime.datetime objects, but will still accept PyTime
objects also.
Raw data for binary fields should be passed as buffer objects for Python 2.x,
and memoryview objects in Py3k.
"""
import warnings
warnings.warn(
"dbi module is obsolete, code should now use native python datetime and buffer/memoryview objects",
DeprecationWarning,
)
import datetime
dbDate = dbiDate = datetime.datetime
try:
dbRaw = dbiRaw = buffer
except NameError:
dbRaw = dbiRaw = memoryview
# type names are still exported by odbc module
from odbc import *

954
lib/win32/lib/mmsystem.py Normal file
View file

@ -0,0 +1,954 @@
# Generated by h2py from d:/msdev/include/mmsystem.h
MAXPNAMELEN = 32
MAXERRORLENGTH = 256
MAX_JOYSTICKOEMVXDNAME = 260
MM_MICROSOFT = 1
MM_MIDI_MAPPER = 1
MM_WAVE_MAPPER = 2
MM_SNDBLST_MIDIOUT = 3
MM_SNDBLST_MIDIIN = 4
MM_SNDBLST_SYNTH = 5
MM_SNDBLST_WAVEOUT = 6
MM_SNDBLST_WAVEIN = 7
MM_ADLIB = 9
MM_MPU401_MIDIOUT = 10
MM_MPU401_MIDIIN = 11
MM_PC_JOYSTICK = 12
TIME_MS = 0x0001
TIME_SAMPLES = 0x0002
TIME_BYTES = 0x0004
TIME_SMPTE = 0x0008
TIME_MIDI = 0x0010
TIME_TICKS = 0x0020
MM_JOY1MOVE = 0x3A0
MM_JOY2MOVE = 0x3A1
MM_JOY1ZMOVE = 0x3A2
MM_JOY2ZMOVE = 0x3A3
MM_JOY1BUTTONDOWN = 0x3B5
MM_JOY2BUTTONDOWN = 0x3B6
MM_JOY1BUTTONUP = 0x3B7
MM_JOY2BUTTONUP = 0x3B8
MM_MCINOTIFY = 0x3B9
MM_WOM_OPEN = 0x3BB
MM_WOM_CLOSE = 0x3BC
MM_WOM_DONE = 0x3BD
MM_WIM_OPEN = 0x3BE
MM_WIM_CLOSE = 0x3BF
MM_WIM_DATA = 0x3C0
MM_MIM_OPEN = 0x3C1
MM_MIM_CLOSE = 0x3C2
MM_MIM_DATA = 0x3C3
MM_MIM_LONGDATA = 0x3C4
MM_MIM_ERROR = 0x3C5
MM_MIM_LONGERROR = 0x3C6
MM_MOM_OPEN = 0x3C7
MM_MOM_CLOSE = 0x3C8
MM_MOM_DONE = 0x3C9
MM_STREAM_OPEN = 0x3D4
MM_STREAM_CLOSE = 0x3D5
MM_STREAM_DONE = 0x3D6
MM_STREAM_ERROR = 0x3D7
MM_MOM_POSITIONCB = 0x3CA
MM_MIM_MOREDATA = 0x3CC
MM_MIXM_LINE_CHANGE = 0x3D0
MM_MIXM_CONTROL_CHANGE = 0x3D1
MMSYSERR_BASE = 0
WAVERR_BASE = 32
MIDIERR_BASE = 64
TIMERR_BASE = 96
JOYERR_BASE = 160
MCIERR_BASE = 256
MIXERR_BASE = 1024
MCI_STRING_OFFSET = 512
MCI_VD_OFFSET = 1024
MCI_CD_OFFSET = 1088
MCI_WAVE_OFFSET = 1152
MCI_SEQ_OFFSET = 1216
MMSYSERR_NOERROR = 0
MMSYSERR_ERROR = MMSYSERR_BASE + 1
MMSYSERR_BADDEVICEID = MMSYSERR_BASE + 2
MMSYSERR_NOTENABLED = MMSYSERR_BASE + 3
MMSYSERR_ALLOCATED = MMSYSERR_BASE + 4
MMSYSERR_INVALHANDLE = MMSYSERR_BASE + 5
MMSYSERR_NODRIVER = MMSYSERR_BASE + 6
MMSYSERR_NOMEM = MMSYSERR_BASE + 7
MMSYSERR_NOTSUPPORTED = MMSYSERR_BASE + 8
MMSYSERR_BADERRNUM = MMSYSERR_BASE + 9
MMSYSERR_INVALFLAG = MMSYSERR_BASE + 10
MMSYSERR_INVALPARAM = MMSYSERR_BASE + 11
MMSYSERR_HANDLEBUSY = MMSYSERR_BASE + 12
MMSYSERR_INVALIDALIAS = MMSYSERR_BASE + 13
MMSYSERR_BADDB = MMSYSERR_BASE + 14
MMSYSERR_KEYNOTFOUND = MMSYSERR_BASE + 15
MMSYSERR_READERROR = MMSYSERR_BASE + 16
MMSYSERR_WRITEERROR = MMSYSERR_BASE + 17
MMSYSERR_DELETEERROR = MMSYSERR_BASE + 18
MMSYSERR_VALNOTFOUND = MMSYSERR_BASE + 19
MMSYSERR_NODRIVERCB = MMSYSERR_BASE + 20
MMSYSERR_LASTERROR = MMSYSERR_BASE + 20
DRV_LOAD = 0x0001
DRV_ENABLE = 0x0002
DRV_OPEN = 0x0003
DRV_CLOSE = 0x0004
DRV_DISABLE = 0x0005
DRV_FREE = 0x0006
DRV_CONFIGURE = 0x0007
DRV_QUERYCONFIGURE = 0x0008
DRV_INSTALL = 0x0009
DRV_REMOVE = 0x000A
DRV_EXITSESSION = 0x000B
DRV_POWER = 0x000F
DRV_RESERVED = 0x0800
DRV_USER = 0x4000
DRVCNF_CANCEL = 0x0000
DRVCNF_OK = 0x0001
DRVCNF_RESTART = 0x0002
DRV_CANCEL = DRVCNF_CANCEL
DRV_OK = DRVCNF_OK
DRV_RESTART = DRVCNF_RESTART
DRV_MCI_FIRST = DRV_RESERVED
DRV_MCI_LAST = DRV_RESERVED + 0xFFF
CALLBACK_TYPEMASK = 0x00070000
CALLBACK_NULL = 0x00000000
CALLBACK_WINDOW = 0x00010000
CALLBACK_TASK = 0x00020000
CALLBACK_FUNCTION = 0x00030000
CALLBACK_THREAD = CALLBACK_TASK
CALLBACK_EVENT = 0x00050000
SND_SYNC = 0x0000
SND_ASYNC = 0x0001
SND_NODEFAULT = 0x0002
SND_MEMORY = 0x0004
SND_LOOP = 0x0008
SND_NOSTOP = 0x0010
SND_NOWAIT = 0x00002000
SND_ALIAS = 0x00010000
SND_ALIAS_ID = 0x00110000
SND_FILENAME = 0x00020000
SND_RESOURCE = 0x00040004
SND_PURGE = 0x0040
SND_APPLICATION = 0x0080
SND_ALIAS_START = 0
WAVERR_BADFORMAT = WAVERR_BASE + 0
WAVERR_STILLPLAYING = WAVERR_BASE + 1
WAVERR_UNPREPARED = WAVERR_BASE + 2
WAVERR_SYNC = WAVERR_BASE + 3
WAVERR_LASTERROR = WAVERR_BASE + 3
WOM_OPEN = MM_WOM_OPEN
WOM_CLOSE = MM_WOM_CLOSE
WOM_DONE = MM_WOM_DONE
WIM_OPEN = MM_WIM_OPEN
WIM_CLOSE = MM_WIM_CLOSE
WIM_DATA = MM_WIM_DATA
WAVE_MAPPER = -1 # 0xFFFFFFFF
WAVE_FORMAT_QUERY = 0x0001
WAVE_ALLOWSYNC = 0x0002
WAVE_MAPPED = 0x0004
WAVE_FORMAT_DIRECT = 0x0008
WAVE_FORMAT_DIRECT_QUERY = WAVE_FORMAT_QUERY | WAVE_FORMAT_DIRECT
WHDR_DONE = 0x00000001
WHDR_PREPARED = 0x00000002
WHDR_BEGINLOOP = 0x00000004
WHDR_ENDLOOP = 0x00000008
WHDR_INQUEUE = 0x00000010
WAVECAPS_PITCH = 0x0001
WAVECAPS_PLAYBACKRATE = 0x0002
WAVECAPS_VOLUME = 0x0004
WAVECAPS_LRVOLUME = 0x0008
WAVECAPS_SYNC = 0x0010
WAVECAPS_SAMPLEACCURATE = 0x0020
WAVECAPS_DIRECTSOUND = 0x0040
WAVE_INVALIDFORMAT = 0x00000000
WAVE_FORMAT_1M08 = 0x00000001
WAVE_FORMAT_1S08 = 0x00000002
WAVE_FORMAT_1M16 = 0x00000004
WAVE_FORMAT_1S16 = 0x00000008
WAVE_FORMAT_2M08 = 0x00000010
WAVE_FORMAT_2S08 = 0x00000020
WAVE_FORMAT_2M16 = 0x00000040
WAVE_FORMAT_2S16 = 0x00000080
WAVE_FORMAT_4M08 = 0x00000100
WAVE_FORMAT_4S08 = 0x00000200
WAVE_FORMAT_4M16 = 0x00000400
WAVE_FORMAT_4S16 = 0x00000800
WAVE_FORMAT_PCM = 1
WAVE_FORMAT_IEEE_FLOAT = 3
MIDIERR_UNPREPARED = MIDIERR_BASE + 0
MIDIERR_STILLPLAYING = MIDIERR_BASE + 1
MIDIERR_NOMAP = MIDIERR_BASE + 2
MIDIERR_NOTREADY = MIDIERR_BASE + 3
MIDIERR_NODEVICE = MIDIERR_BASE + 4
MIDIERR_INVALIDSETUP = MIDIERR_BASE + 5
MIDIERR_BADOPENMODE = MIDIERR_BASE + 6
MIDIERR_DONT_CONTINUE = MIDIERR_BASE + 7
MIDIERR_LASTERROR = MIDIERR_BASE + 7
MIDIPATCHSIZE = 128
MIM_OPEN = MM_MIM_OPEN
MIM_CLOSE = MM_MIM_CLOSE
MIM_DATA = MM_MIM_DATA
MIM_LONGDATA = MM_MIM_LONGDATA
MIM_ERROR = MM_MIM_ERROR
MIM_LONGERROR = MM_MIM_LONGERROR
MOM_OPEN = MM_MOM_OPEN
MOM_CLOSE = MM_MOM_CLOSE
MOM_DONE = MM_MOM_DONE
MIM_MOREDATA = MM_MIM_MOREDATA
MOM_POSITIONCB = MM_MOM_POSITIONCB
MIDI_IO_STATUS = 0x00000020
MIDI_CACHE_ALL = 1
MIDI_CACHE_BESTFIT = 2
MIDI_CACHE_QUERY = 3
MIDI_UNCACHE = 4
MOD_MIDIPORT = 1
MOD_SYNTH = 2
MOD_SQSYNTH = 3
MOD_FMSYNTH = 4
MOD_MAPPER = 5
MIDICAPS_VOLUME = 0x0001
MIDICAPS_LRVOLUME = 0x0002
MIDICAPS_CACHE = 0x0004
MIDICAPS_STREAM = 0x0008
MHDR_DONE = 0x00000001
MHDR_PREPARED = 0x00000002
MHDR_INQUEUE = 0x00000004
MHDR_ISSTRM = 0x00000008
MEVT_F_SHORT = 0x00000000
MEVT_F_LONG = -2147483648 # 0x80000000
MEVT_F_CALLBACK = 0x40000000
def MEVT_EVENTTYPE(x):
return (BYTE)(((x) >> 24) & 0xFF)
def MEVT_EVENTPARM(x):
return (DWORD)((x) & 0x00FFFFFF)
MIDISTRM_ERROR = -2
MIDIPROP_SET = -2147483648 # 0x80000000
MIDIPROP_GET = 0x40000000
MIDIPROP_TIMEDIV = 0x00000001
MIDIPROP_TEMPO = 0x00000002
AUXCAPS_CDAUDIO = 1
AUXCAPS_AUXIN = 2
AUXCAPS_VOLUME = 0x0001
AUXCAPS_LRVOLUME = 0x0002
MIXER_SHORT_NAME_CHARS = 16
MIXER_LONG_NAME_CHARS = 64
MIXERR_INVALLINE = MIXERR_BASE + 0
MIXERR_INVALCONTROL = MIXERR_BASE + 1
MIXERR_INVALVALUE = MIXERR_BASE + 2
MIXERR_LASTERROR = MIXERR_BASE + 2
MIXER_OBJECTF_HANDLE = -2147483648 # 0x80000000
MIXER_OBJECTF_MIXER = 0x00000000
MIXER_OBJECTF_HMIXER = MIXER_OBJECTF_HANDLE | MIXER_OBJECTF_MIXER
MIXER_OBJECTF_WAVEOUT = 0x10000000
MIXER_OBJECTF_HWAVEOUT = MIXER_OBJECTF_HANDLE | MIXER_OBJECTF_WAVEOUT
MIXER_OBJECTF_WAVEIN = 0x20000000
MIXER_OBJECTF_HWAVEIN = MIXER_OBJECTF_HANDLE | MIXER_OBJECTF_WAVEIN
MIXER_OBJECTF_MIDIOUT = 0x30000000
MIXER_OBJECTF_HMIDIOUT = MIXER_OBJECTF_HANDLE | MIXER_OBJECTF_MIDIOUT
MIXER_OBJECTF_MIDIIN = 0x40000000
MIXER_OBJECTF_HMIDIIN = MIXER_OBJECTF_HANDLE | MIXER_OBJECTF_MIDIIN
MIXER_OBJECTF_AUX = 0x50000000
MIXERLINE_LINEF_ACTIVE = 0x00000001
MIXERLINE_LINEF_DISCONNECTED = 0x00008000
MIXERLINE_LINEF_SOURCE = -2147483648 # 0x80000000
MIXERLINE_COMPONENTTYPE_DST_FIRST = 0x00000000
MIXERLINE_COMPONENTTYPE_DST_UNDEFINED = MIXERLINE_COMPONENTTYPE_DST_FIRST + 0
MIXERLINE_COMPONENTTYPE_DST_DIGITAL = MIXERLINE_COMPONENTTYPE_DST_FIRST + 1
MIXERLINE_COMPONENTTYPE_DST_LINE = MIXERLINE_COMPONENTTYPE_DST_FIRST + 2
MIXERLINE_COMPONENTTYPE_DST_MONITOR = MIXERLINE_COMPONENTTYPE_DST_FIRST + 3
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS = MIXERLINE_COMPONENTTYPE_DST_FIRST + 4
MIXERLINE_COMPONENTTYPE_DST_HEADPHONES = MIXERLINE_COMPONENTTYPE_DST_FIRST + 5
MIXERLINE_COMPONENTTYPE_DST_TELEPHONE = MIXERLINE_COMPONENTTYPE_DST_FIRST + 6
MIXERLINE_COMPONENTTYPE_DST_WAVEIN = MIXERLINE_COMPONENTTYPE_DST_FIRST + 7
MIXERLINE_COMPONENTTYPE_DST_VOICEIN = MIXERLINE_COMPONENTTYPE_DST_FIRST + 8
MIXERLINE_COMPONENTTYPE_DST_LAST = MIXERLINE_COMPONENTTYPE_DST_FIRST + 8
MIXERLINE_COMPONENTTYPE_SRC_FIRST = 0x00001000
MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 0
MIXERLINE_COMPONENTTYPE_SRC_DIGITAL = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 1
MIXERLINE_COMPONENTTYPE_SRC_LINE = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2
MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3
MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 4
MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 5
MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 6
MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 7
MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 8
MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 9
MIXERLINE_COMPONENTTYPE_SRC_ANALOG = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10
MIXERLINE_COMPONENTTYPE_SRC_LAST = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10
MIXERLINE_TARGETTYPE_UNDEFINED = 0
MIXERLINE_TARGETTYPE_WAVEOUT = 1
MIXERLINE_TARGETTYPE_WAVEIN = 2
MIXERLINE_TARGETTYPE_MIDIOUT = 3
MIXERLINE_TARGETTYPE_MIDIIN = 4
MIXERLINE_TARGETTYPE_AUX = 5
MIXER_GETLINEINFOF_DESTINATION = 0x00000000
MIXER_GETLINEINFOF_SOURCE = 0x00000001
MIXER_GETLINEINFOF_LINEID = 0x00000002
MIXER_GETLINEINFOF_COMPONENTTYPE = 0x00000003
MIXER_GETLINEINFOF_TARGETTYPE = 0x00000004
MIXER_GETLINEINFOF_QUERYMASK = 0x0000000F
MIXERCONTROL_CONTROLF_UNIFORM = 0x00000001
MIXERCONTROL_CONTROLF_MULTIPLE = 0x00000002
MIXERCONTROL_CONTROLF_DISABLED = -2147483648 # 0x80000000
MIXERCONTROL_CT_CLASS_MASK = -268435456 # 0xF0000000
MIXERCONTROL_CT_CLASS_CUSTOM = 0x00000000
MIXERCONTROL_CT_CLASS_METER = 0x10000000
MIXERCONTROL_CT_CLASS_SWITCH = 0x20000000
MIXERCONTROL_CT_CLASS_NUMBER = 0x30000000
MIXERCONTROL_CT_CLASS_SLIDER = 0x40000000
MIXERCONTROL_CT_CLASS_FADER = 0x50000000
MIXERCONTROL_CT_CLASS_TIME = 0x60000000
MIXERCONTROL_CT_CLASS_LIST = 0x70000000
MIXERCONTROL_CT_SUBCLASS_MASK = 0x0F000000
MIXERCONTROL_CT_SC_SWITCH_BOOLEAN = 0x00000000
MIXERCONTROL_CT_SC_SWITCH_BUTTON = 0x01000000
MIXERCONTROL_CT_SC_METER_POLLED = 0x00000000
MIXERCONTROL_CT_SC_TIME_MICROSECS = 0x00000000
MIXERCONTROL_CT_SC_TIME_MILLISECS = 0x01000000
MIXERCONTROL_CT_SC_LIST_SINGLE = 0x00000000
MIXERCONTROL_CT_SC_LIST_MULTIPLE = 0x01000000
MIXERCONTROL_CT_UNITS_MASK = 0x00FF0000
MIXERCONTROL_CT_UNITS_CUSTOM = 0x00000000
MIXERCONTROL_CT_UNITS_BOOLEAN = 0x00010000
MIXERCONTROL_CT_UNITS_SIGNED = 0x00020000
MIXERCONTROL_CT_UNITS_UNSIGNED = 0x00030000
MIXERCONTROL_CT_UNITS_DECIBELS = 0x00040000
MIXERCONTROL_CT_UNITS_PERCENT = 0x00050000
MIXERCONTROL_CONTROLTYPE_CUSTOM = (
MIXERCONTROL_CT_CLASS_CUSTOM | MIXERCONTROL_CT_UNITS_CUSTOM
)
MIXERCONTROL_CONTROLTYPE_BOOLEANMETER = (
MIXERCONTROL_CT_CLASS_METER
| MIXERCONTROL_CT_SC_METER_POLLED
| MIXERCONTROL_CT_UNITS_BOOLEAN
)
MIXERCONTROL_CONTROLTYPE_SIGNEDMETER = (
MIXERCONTROL_CT_CLASS_METER
| MIXERCONTROL_CT_SC_METER_POLLED
| MIXERCONTROL_CT_UNITS_SIGNED
)
MIXERCONTROL_CONTROLTYPE_PEAKMETER = MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1
MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER = (
MIXERCONTROL_CT_CLASS_METER
| MIXERCONTROL_CT_SC_METER_POLLED
| MIXERCONTROL_CT_UNITS_UNSIGNED
)
MIXERCONTROL_CONTROLTYPE_BOOLEAN = (
MIXERCONTROL_CT_CLASS_SWITCH
| MIXERCONTROL_CT_SC_SWITCH_BOOLEAN
| MIXERCONTROL_CT_UNITS_BOOLEAN
)
MIXERCONTROL_CONTROLTYPE_ONOFF = MIXERCONTROL_CONTROLTYPE_BOOLEAN + 1
MIXERCONTROL_CONTROLTYPE_MUTE = MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2
MIXERCONTROL_CONTROLTYPE_MONO = MIXERCONTROL_CONTROLTYPE_BOOLEAN + 3
MIXERCONTROL_CONTROLTYPE_LOUDNESS = MIXERCONTROL_CONTROLTYPE_BOOLEAN + 4
MIXERCONTROL_CONTROLTYPE_STEREOENH = MIXERCONTROL_CONTROLTYPE_BOOLEAN + 5
MIXERCONTROL_CONTROLTYPE_BUTTON = (
MIXERCONTROL_CT_CLASS_SWITCH
| MIXERCONTROL_CT_SC_SWITCH_BUTTON
| MIXERCONTROL_CT_UNITS_BOOLEAN
)
MIXERCONTROL_CONTROLTYPE_DECIBELS = (
MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_DECIBELS
)
MIXERCONTROL_CONTROLTYPE_SIGNED = (
MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_SIGNED
)
MIXERCONTROL_CONTROLTYPE_UNSIGNED = (
MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_UNSIGNED
)
MIXERCONTROL_CONTROLTYPE_PERCENT = (
MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_PERCENT
)
MIXERCONTROL_CONTROLTYPE_SLIDER = (
MIXERCONTROL_CT_CLASS_SLIDER | MIXERCONTROL_CT_UNITS_SIGNED
)
MIXERCONTROL_CONTROLTYPE_PAN = MIXERCONTROL_CONTROLTYPE_SLIDER + 1
MIXERCONTROL_CONTROLTYPE_QSOUNDPAN = MIXERCONTROL_CONTROLTYPE_SLIDER + 2
MIXERCONTROL_CONTROLTYPE_FADER = (
MIXERCONTROL_CT_CLASS_FADER | MIXERCONTROL_CT_UNITS_UNSIGNED
)
MIXERCONTROL_CONTROLTYPE_VOLUME = MIXERCONTROL_CONTROLTYPE_FADER + 1
MIXERCONTROL_CONTROLTYPE_BASS = MIXERCONTROL_CONTROLTYPE_FADER + 2
MIXERCONTROL_CONTROLTYPE_TREBLE = MIXERCONTROL_CONTROLTYPE_FADER + 3
MIXERCONTROL_CONTROLTYPE_EQUALIZER = MIXERCONTROL_CONTROLTYPE_FADER + 4
MIXERCONTROL_CONTROLTYPE_SINGLESELECT = (
MIXERCONTROL_CT_CLASS_LIST
| MIXERCONTROL_CT_SC_LIST_SINGLE
| MIXERCONTROL_CT_UNITS_BOOLEAN
)
MIXERCONTROL_CONTROLTYPE_MUX = MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1
MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT = (
MIXERCONTROL_CT_CLASS_LIST
| MIXERCONTROL_CT_SC_LIST_MULTIPLE
| MIXERCONTROL_CT_UNITS_BOOLEAN
)
MIXERCONTROL_CONTROLTYPE_MIXER = MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1
MIXERCONTROL_CONTROLTYPE_MICROTIME = (
MIXERCONTROL_CT_CLASS_TIME
| MIXERCONTROL_CT_SC_TIME_MICROSECS
| MIXERCONTROL_CT_UNITS_UNSIGNED
)
MIXERCONTROL_CONTROLTYPE_MILLITIME = (
MIXERCONTROL_CT_CLASS_TIME
| MIXERCONTROL_CT_SC_TIME_MILLISECS
| MIXERCONTROL_CT_UNITS_UNSIGNED
)
MIXER_GETLINECONTROLSF_ALL = 0x00000000
MIXER_GETLINECONTROLSF_ONEBYID = 0x00000001
MIXER_GETLINECONTROLSF_ONEBYTYPE = 0x00000002
MIXER_GETLINECONTROLSF_QUERYMASK = 0x0000000F
MIXER_GETCONTROLDETAILSF_VALUE = 0x00000000
MIXER_GETCONTROLDETAILSF_LISTTEXT = 0x00000001
MIXER_GETCONTROLDETAILSF_QUERYMASK = 0x0000000F
MIXER_SETCONTROLDETAILSF_VALUE = 0x00000000
MIXER_SETCONTROLDETAILSF_CUSTOM = 0x00000001
MIXER_SETCONTROLDETAILSF_QUERYMASK = 0x0000000F
TIMERR_NOERROR = 0
TIMERR_NOCANDO = TIMERR_BASE + 1
TIMERR_STRUCT = TIMERR_BASE + 33
TIME_ONESHOT = 0x0000
TIME_PERIODIC = 0x0001
TIME_CALLBACK_FUNCTION = 0x0000
TIME_CALLBACK_EVENT_SET = 0x0010
TIME_CALLBACK_EVENT_PULSE = 0x0020
JOYERR_NOERROR = 0
JOYERR_PARMS = JOYERR_BASE + 5
JOYERR_NOCANDO = JOYERR_BASE + 6
JOYERR_UNPLUGGED = JOYERR_BASE + 7
JOY_BUTTON1 = 0x0001
JOY_BUTTON2 = 0x0002
JOY_BUTTON3 = 0x0004
JOY_BUTTON4 = 0x0008
JOY_BUTTON1CHG = 0x0100
JOY_BUTTON2CHG = 0x0200
JOY_BUTTON3CHG = 0x0400
JOY_BUTTON4CHG = 0x0800
JOY_BUTTON5 = 0x00000010
JOY_BUTTON6 = 0x00000020
JOY_BUTTON7 = 0x00000040
JOY_BUTTON8 = 0x00000080
JOY_BUTTON9 = 0x00000100
JOY_BUTTON10 = 0x00000200
JOY_BUTTON11 = 0x00000400
JOY_BUTTON12 = 0x00000800
JOY_BUTTON13 = 0x00001000
JOY_BUTTON14 = 0x00002000
JOY_BUTTON15 = 0x00004000
JOY_BUTTON16 = 0x00008000
JOY_BUTTON17 = 0x00010000
JOY_BUTTON18 = 0x00020000
JOY_BUTTON19 = 0x00040000
JOY_BUTTON20 = 0x00080000
JOY_BUTTON21 = 0x00100000
JOY_BUTTON22 = 0x00200000
JOY_BUTTON23 = 0x00400000
JOY_BUTTON24 = 0x00800000
JOY_BUTTON25 = 0x01000000
JOY_BUTTON26 = 0x02000000
JOY_BUTTON27 = 0x04000000
JOY_BUTTON28 = 0x08000000
JOY_BUTTON29 = 0x10000000
JOY_BUTTON30 = 0x20000000
JOY_BUTTON31 = 0x40000000
JOY_BUTTON32 = -2147483648 # 0x80000000
JOY_POVFORWARD = 0
JOY_POVRIGHT = 9000
JOY_POVBACKWARD = 18000
JOY_POVLEFT = 27000
JOY_RETURNX = 0x00000001
JOY_RETURNY = 0x00000002
JOY_RETURNZ = 0x00000004
JOY_RETURNR = 0x00000008
JOY_RETURNU = 0x00000010
JOY_RETURNV = 0x00000020
JOY_RETURNPOV = 0x00000040
JOY_RETURNBUTTONS = 0x00000080
JOY_RETURNRAWDATA = 0x00000100
JOY_RETURNPOVCTS = 0x00000200
JOY_RETURNCENTERED = 0x00000400
JOY_USEDEADZONE = 0x00000800
JOY_RETURNALL = (
JOY_RETURNX
| JOY_RETURNY
| JOY_RETURNZ
| JOY_RETURNR
| JOY_RETURNU
| JOY_RETURNV
| JOY_RETURNPOV
| JOY_RETURNBUTTONS
)
JOY_CAL_READALWAYS = 0x00010000
JOY_CAL_READXYONLY = 0x00020000
JOY_CAL_READ3 = 0x00040000
JOY_CAL_READ4 = 0x00080000
JOY_CAL_READXONLY = 0x00100000
JOY_CAL_READYONLY = 0x00200000
JOY_CAL_READ5 = 0x00400000
JOY_CAL_READ6 = 0x00800000
JOY_CAL_READZONLY = 0x01000000
JOY_CAL_READRONLY = 0x02000000
JOY_CAL_READUONLY = 0x04000000
JOY_CAL_READVONLY = 0x08000000
JOYSTICKID1 = 0
JOYSTICKID2 = 1
JOYCAPS_HASZ = 0x0001
JOYCAPS_HASR = 0x0002
JOYCAPS_HASU = 0x0004
JOYCAPS_HASV = 0x0008
JOYCAPS_HASPOV = 0x0010
JOYCAPS_POV4DIR = 0x0020
JOYCAPS_POVCTS = 0x0040
MMIOERR_BASE = 256
MMIOERR_FILENOTFOUND = MMIOERR_BASE + 1
MMIOERR_OUTOFMEMORY = MMIOERR_BASE + 2
MMIOERR_CANNOTOPEN = MMIOERR_BASE + 3
MMIOERR_CANNOTCLOSE = MMIOERR_BASE + 4
MMIOERR_CANNOTREAD = MMIOERR_BASE + 5
MMIOERR_CANNOTWRITE = MMIOERR_BASE + 6
MMIOERR_CANNOTSEEK = MMIOERR_BASE + 7
MMIOERR_CANNOTEXPAND = MMIOERR_BASE + 8
MMIOERR_CHUNKNOTFOUND = MMIOERR_BASE + 9
MMIOERR_UNBUFFERED = MMIOERR_BASE + 10
MMIOERR_PATHNOTFOUND = MMIOERR_BASE + 11
MMIOERR_ACCESSDENIED = MMIOERR_BASE + 12
MMIOERR_SHARINGVIOLATION = MMIOERR_BASE + 13
MMIOERR_NETWORKERROR = MMIOERR_BASE + 14
MMIOERR_TOOMANYOPENFILES = MMIOERR_BASE + 15
MMIOERR_INVALIDFILE = MMIOERR_BASE + 16
CFSEPCHAR = ord("+")
MMIO_RWMODE = 0x00000003
MMIO_SHAREMODE = 0x00000070
MMIO_CREATE = 0x00001000
MMIO_PARSE = 0x00000100
MMIO_DELETE = 0x00000200
MMIO_EXIST = 0x00004000
MMIO_ALLOCBUF = 0x00010000
MMIO_GETTEMP = 0x00020000
MMIO_DIRTY = 0x10000000
MMIO_READ = 0x00000000
MMIO_WRITE = 0x00000001
MMIO_READWRITE = 0x00000002
MMIO_COMPAT = 0x00000000
MMIO_EXCLUSIVE = 0x00000010
MMIO_DENYWRITE = 0x00000020
MMIO_DENYREAD = 0x00000030
MMIO_DENYNONE = 0x00000040
MMIO_FHOPEN = 0x0010
MMIO_EMPTYBUF = 0x0010
MMIO_TOUPPER = 0x0010
MMIO_INSTALLPROC = 0x00010000
MMIO_GLOBALPROC = 0x10000000
MMIO_REMOVEPROC = 0x00020000
MMIO_UNICODEPROC = 0x01000000
MMIO_FINDPROC = 0x00040000
MMIO_FINDCHUNK = 0x0010
MMIO_FINDRIFF = 0x0020
MMIO_FINDLIST = 0x0040
MMIO_CREATERIFF = 0x0020
MMIO_CREATELIST = 0x0040
MMIOM_READ = MMIO_READ
MMIOM_WRITE = MMIO_WRITE
MMIOM_SEEK = 2
MMIOM_OPEN = 3
MMIOM_CLOSE = 4
MMIOM_WRITEFLUSH = 5
MMIOM_RENAME = 6
MMIOM_USER = 0x8000
SEEK_SET = 0
SEEK_CUR = 1
SEEK_END = 2
MMIO_DEFAULTBUFFER = 8192
MCIERR_INVALID_DEVICE_ID = MCIERR_BASE + 1
MCIERR_UNRECOGNIZED_KEYWORD = MCIERR_BASE + 3
MCIERR_UNRECOGNIZED_COMMAND = MCIERR_BASE + 5
MCIERR_HARDWARE = MCIERR_BASE + 6
MCIERR_INVALID_DEVICE_NAME = MCIERR_BASE + 7
MCIERR_OUT_OF_MEMORY = MCIERR_BASE + 8
MCIERR_DEVICE_OPEN = MCIERR_BASE + 9
MCIERR_CANNOT_LOAD_DRIVER = MCIERR_BASE + 10
MCIERR_MISSING_COMMAND_STRING = MCIERR_BASE + 11
MCIERR_PARAM_OVERFLOW = MCIERR_BASE + 12
MCIERR_MISSING_STRING_ARGUMENT = MCIERR_BASE + 13
MCIERR_BAD_INTEGER = MCIERR_BASE + 14
MCIERR_PARSER_INTERNAL = MCIERR_BASE + 15
MCIERR_DRIVER_INTERNAL = MCIERR_BASE + 16
MCIERR_MISSING_PARAMETER = MCIERR_BASE + 17
MCIERR_UNSUPPORTED_FUNCTION = MCIERR_BASE + 18
MCIERR_FILE_NOT_FOUND = MCIERR_BASE + 19
MCIERR_DEVICE_NOT_READY = MCIERR_BASE + 20
MCIERR_INTERNAL = MCIERR_BASE + 21
MCIERR_DRIVER = MCIERR_BASE + 22
MCIERR_CANNOT_USE_ALL = MCIERR_BASE + 23
MCIERR_MULTIPLE = MCIERR_BASE + 24
MCIERR_EXTENSION_NOT_FOUND = MCIERR_BASE + 25
MCIERR_OUTOFRANGE = MCIERR_BASE + 26
MCIERR_FLAGS_NOT_COMPATIBLE = MCIERR_BASE + 28
MCIERR_FILE_NOT_SAVED = MCIERR_BASE + 30
MCIERR_DEVICE_TYPE_REQUIRED = MCIERR_BASE + 31
MCIERR_DEVICE_LOCKED = MCIERR_BASE + 32
MCIERR_DUPLICATE_ALIAS = MCIERR_BASE + 33
MCIERR_BAD_CONSTANT = MCIERR_BASE + 34
MCIERR_MUST_USE_SHAREABLE = MCIERR_BASE + 35
MCIERR_MISSING_DEVICE_NAME = MCIERR_BASE + 36
MCIERR_BAD_TIME_FORMAT = MCIERR_BASE + 37
MCIERR_NO_CLOSING_QUOTE = MCIERR_BASE + 38
MCIERR_DUPLICATE_FLAGS = MCIERR_BASE + 39
MCIERR_INVALID_FILE = MCIERR_BASE + 40
MCIERR_NULL_PARAMETER_BLOCK = MCIERR_BASE + 41
MCIERR_UNNAMED_RESOURCE = MCIERR_BASE + 42
MCIERR_NEW_REQUIRES_ALIAS = MCIERR_BASE + 43
MCIERR_NOTIFY_ON_AUTO_OPEN = MCIERR_BASE + 44
MCIERR_NO_ELEMENT_ALLOWED = MCIERR_BASE + 45
MCIERR_NONAPPLICABLE_FUNCTION = MCIERR_BASE + 46
MCIERR_ILLEGAL_FOR_AUTO_OPEN = MCIERR_BASE + 47
MCIERR_FILENAME_REQUIRED = MCIERR_BASE + 48
MCIERR_EXTRA_CHARACTERS = MCIERR_BASE + 49
MCIERR_DEVICE_NOT_INSTALLED = MCIERR_BASE + 50
MCIERR_GET_CD = MCIERR_BASE + 51
MCIERR_SET_CD = MCIERR_BASE + 52
MCIERR_SET_DRIVE = MCIERR_BASE + 53
MCIERR_DEVICE_LENGTH = MCIERR_BASE + 54
MCIERR_DEVICE_ORD_LENGTH = MCIERR_BASE + 55
MCIERR_NO_INTEGER = MCIERR_BASE + 56
MCIERR_WAVE_OUTPUTSINUSE = MCIERR_BASE + 64
MCIERR_WAVE_SETOUTPUTINUSE = MCIERR_BASE + 65
MCIERR_WAVE_INPUTSINUSE = MCIERR_BASE + 66
MCIERR_WAVE_SETINPUTINUSE = MCIERR_BASE + 67
MCIERR_WAVE_OUTPUTUNSPECIFIED = MCIERR_BASE + 68
MCIERR_WAVE_INPUTUNSPECIFIED = MCIERR_BASE + 69
MCIERR_WAVE_OUTPUTSUNSUITABLE = MCIERR_BASE + 70
MCIERR_WAVE_SETOUTPUTUNSUITABLE = MCIERR_BASE + 71
MCIERR_WAVE_INPUTSUNSUITABLE = MCIERR_BASE + 72
MCIERR_WAVE_SETINPUTUNSUITABLE = MCIERR_BASE + 73
MCIERR_SEQ_DIV_INCOMPATIBLE = MCIERR_BASE + 80
MCIERR_SEQ_PORT_INUSE = MCIERR_BASE + 81
MCIERR_SEQ_PORT_NONEXISTENT = MCIERR_BASE + 82
MCIERR_SEQ_PORT_MAPNODEVICE = MCIERR_BASE + 83
MCIERR_SEQ_PORT_MISCERROR = MCIERR_BASE + 84
MCIERR_SEQ_TIMER = MCIERR_BASE + 85
MCIERR_SEQ_PORTUNSPECIFIED = MCIERR_BASE + 86
MCIERR_SEQ_NOMIDIPRESENT = MCIERR_BASE + 87
MCIERR_NO_WINDOW = MCIERR_BASE + 90
MCIERR_CREATEWINDOW = MCIERR_BASE + 91
MCIERR_FILE_READ = MCIERR_BASE + 92
MCIERR_FILE_WRITE = MCIERR_BASE + 93
MCIERR_NO_IDENTITY = MCIERR_BASE + 94
MCIERR_CUSTOM_DRIVER_BASE = MCIERR_BASE + 256
MCI_FIRST = DRV_MCI_FIRST
MCI_OPEN = 0x0803
MCI_CLOSE = 0x0804
MCI_ESCAPE = 0x0805
MCI_PLAY = 0x0806
MCI_SEEK = 0x0807
MCI_STOP = 0x0808
MCI_PAUSE = 0x0809
MCI_INFO = 0x080A
MCI_GETDEVCAPS = 0x080B
MCI_SPIN = 0x080C
MCI_SET = 0x080D
MCI_STEP = 0x080E
MCI_RECORD = 0x080F
MCI_SYSINFO = 0x0810
MCI_BREAK = 0x0811
MCI_SAVE = 0x0813
MCI_STATUS = 0x0814
MCI_CUE = 0x0830
MCI_REALIZE = 0x0840
MCI_WINDOW = 0x0841
MCI_PUT = 0x0842
MCI_WHERE = 0x0843
MCI_FREEZE = 0x0844
MCI_UNFREEZE = 0x0845
MCI_LOAD = 0x0850
MCI_CUT = 0x0851
MCI_COPY = 0x0852
MCI_PASTE = 0x0853
MCI_UPDATE = 0x0854
MCI_RESUME = 0x0855
MCI_DELETE = 0x0856
MCI_USER_MESSAGES = DRV_MCI_FIRST + 0x400
MCI_LAST = 0x0FFF
MCI_DEVTYPE_VCR = 513
MCI_DEVTYPE_VIDEODISC = 514
MCI_DEVTYPE_OVERLAY = 515
MCI_DEVTYPE_CD_AUDIO = 516
MCI_DEVTYPE_DAT = 517
MCI_DEVTYPE_SCANNER = 518
MCI_DEVTYPE_ANIMATION = 519
MCI_DEVTYPE_DIGITAL_VIDEO = 520
MCI_DEVTYPE_OTHER = 521
MCI_DEVTYPE_WAVEFORM_AUDIO = 522
MCI_DEVTYPE_SEQUENCER = 523
MCI_DEVTYPE_FIRST = MCI_DEVTYPE_VCR
MCI_DEVTYPE_LAST = MCI_DEVTYPE_SEQUENCER
MCI_DEVTYPE_FIRST_USER = 0x1000
MCI_MODE_NOT_READY = MCI_STRING_OFFSET + 12
MCI_MODE_STOP = MCI_STRING_OFFSET + 13
MCI_MODE_PLAY = MCI_STRING_OFFSET + 14
MCI_MODE_RECORD = MCI_STRING_OFFSET + 15
MCI_MODE_SEEK = MCI_STRING_OFFSET + 16
MCI_MODE_PAUSE = MCI_STRING_OFFSET + 17
MCI_MODE_OPEN = MCI_STRING_OFFSET + 18
MCI_FORMAT_MILLISECONDS = 0
MCI_FORMAT_HMS = 1
MCI_FORMAT_MSF = 2
MCI_FORMAT_FRAMES = 3
MCI_FORMAT_SMPTE_24 = 4
MCI_FORMAT_SMPTE_25 = 5
MCI_FORMAT_SMPTE_30 = 6
MCI_FORMAT_SMPTE_30DROP = 7
MCI_FORMAT_BYTES = 8
MCI_FORMAT_SAMPLES = 9
MCI_FORMAT_TMSF = 10
def MCI_MSF_MINUTE(msf):
return (BYTE)(msf)
def MCI_MSF_SECOND(msf):
return (BYTE)(((WORD)(msf)) >> 8)
def MCI_MSF_FRAME(msf):
return (BYTE)((msf) >> 16)
def MCI_TMSF_TRACK(tmsf):
return (BYTE)(tmsf)
def MCI_TMSF_MINUTE(tmsf):
return (BYTE)(((WORD)(tmsf)) >> 8)
def MCI_TMSF_SECOND(tmsf):
return (BYTE)((tmsf) >> 16)
def MCI_TMSF_FRAME(tmsf):
return (BYTE)((tmsf) >> 24)
def MCI_HMS_HOUR(hms):
return (BYTE)(hms)
def MCI_HMS_MINUTE(hms):
return (BYTE)(((WORD)(hms)) >> 8)
def MCI_HMS_SECOND(hms):
return (BYTE)((hms) >> 16)
MCI_NOTIFY_SUCCESSFUL = 0x0001
MCI_NOTIFY_SUPERSEDED = 0x0002
MCI_NOTIFY_ABORTED = 0x0004
MCI_NOTIFY_FAILURE = 0x0008
MCI_NOTIFY = 0x00000001
MCI_WAIT = 0x00000002
MCI_FROM = 0x00000004
MCI_TO = 0x00000008
MCI_TRACK = 0x00000010
MCI_OPEN_SHAREABLE = 0x00000100
MCI_OPEN_ELEMENT = 0x00000200
MCI_OPEN_ALIAS = 0x00000400
MCI_OPEN_ELEMENT_ID = 0x00000800
MCI_OPEN_TYPE_ID = 0x00001000
MCI_OPEN_TYPE = 0x00002000
MCI_SEEK_TO_START = 0x00000100
MCI_SEEK_TO_END = 0x00000200
MCI_STATUS_ITEM = 0x00000100
MCI_STATUS_START = 0x00000200
MCI_STATUS_LENGTH = 0x00000001
MCI_STATUS_POSITION = 0x00000002
MCI_STATUS_NUMBER_OF_TRACKS = 0x00000003
MCI_STATUS_MODE = 0x00000004
MCI_STATUS_MEDIA_PRESENT = 0x00000005
MCI_STATUS_TIME_FORMAT = 0x00000006
MCI_STATUS_READY = 0x00000007
MCI_STATUS_CURRENT_TRACK = 0x00000008
MCI_INFO_PRODUCT = 0x00000100
MCI_INFO_FILE = 0x00000200
MCI_INFO_MEDIA_UPC = 0x00000400
MCI_INFO_MEDIA_IDENTITY = 0x00000800
MCI_INFO_NAME = 0x00001000
MCI_INFO_COPYRIGHT = 0x00002000
MCI_GETDEVCAPS_ITEM = 0x00000100
MCI_GETDEVCAPS_CAN_RECORD = 0x00000001
MCI_GETDEVCAPS_HAS_AUDIO = 0x00000002
MCI_GETDEVCAPS_HAS_VIDEO = 0x00000003
MCI_GETDEVCAPS_DEVICE_TYPE = 0x00000004
MCI_GETDEVCAPS_USES_FILES = 0x00000005
MCI_GETDEVCAPS_COMPOUND_DEVICE = 0x00000006
MCI_GETDEVCAPS_CAN_EJECT = 0x00000007
MCI_GETDEVCAPS_CAN_PLAY = 0x00000008
MCI_GETDEVCAPS_CAN_SAVE = 0x00000009
MCI_SYSINFO_QUANTITY = 0x00000100
MCI_SYSINFO_OPEN = 0x00000200
MCI_SYSINFO_NAME = 0x00000400
MCI_SYSINFO_INSTALLNAME = 0x00000800
MCI_SET_DOOR_OPEN = 0x00000100
MCI_SET_DOOR_CLOSED = 0x00000200
MCI_SET_TIME_FORMAT = 0x00000400
MCI_SET_AUDIO = 0x00000800
MCI_SET_VIDEO = 0x00001000
MCI_SET_ON = 0x00002000
MCI_SET_OFF = 0x00004000
MCI_SET_AUDIO_ALL = 0x00000000
MCI_SET_AUDIO_LEFT = 0x00000001
MCI_SET_AUDIO_RIGHT = 0x00000002
MCI_BREAK_KEY = 0x00000100
MCI_BREAK_HWND = 0x00000200
MCI_BREAK_OFF = 0x00000400
MCI_RECORD_INSERT = 0x00000100
MCI_RECORD_OVERWRITE = 0x00000200
MCI_SAVE_FILE = 0x00000100
MCI_LOAD_FILE = 0x00000100
MCI_VD_MODE_PARK = MCI_VD_OFFSET + 1
MCI_VD_MEDIA_CLV = MCI_VD_OFFSET + 2
MCI_VD_MEDIA_CAV = MCI_VD_OFFSET + 3
MCI_VD_MEDIA_OTHER = MCI_VD_OFFSET + 4
MCI_VD_FORMAT_TRACK = 0x4001
MCI_VD_PLAY_REVERSE = 0x00010000
MCI_VD_PLAY_FAST = 0x00020000
MCI_VD_PLAY_SPEED = 0x00040000
MCI_VD_PLAY_SCAN = 0x00080000
MCI_VD_PLAY_SLOW = 0x00100000
MCI_VD_SEEK_REVERSE = 0x00010000
MCI_VD_STATUS_SPEED = 0x00004002
MCI_VD_STATUS_FORWARD = 0x00004003
MCI_VD_STATUS_MEDIA_TYPE = 0x00004004
MCI_VD_STATUS_SIDE = 0x00004005
MCI_VD_STATUS_DISC_SIZE = 0x00004006
MCI_VD_GETDEVCAPS_CLV = 0x00010000
MCI_VD_GETDEVCAPS_CAV = 0x00020000
MCI_VD_SPIN_UP = 0x00010000
MCI_VD_SPIN_DOWN = 0x00020000
MCI_VD_GETDEVCAPS_CAN_REVERSE = 0x00004002
MCI_VD_GETDEVCAPS_FAST_RATE = 0x00004003
MCI_VD_GETDEVCAPS_SLOW_RATE = 0x00004004
MCI_VD_GETDEVCAPS_NORMAL_RATE = 0x00004005
MCI_VD_STEP_FRAMES = 0x00010000
MCI_VD_STEP_REVERSE = 0x00020000
MCI_VD_ESCAPE_STRING = 0x00000100
MCI_CDA_STATUS_TYPE_TRACK = 0x00004001
MCI_CDA_TRACK_AUDIO = MCI_CD_OFFSET + 0
MCI_CDA_TRACK_OTHER = MCI_CD_OFFSET + 1
MCI_WAVE_PCM = MCI_WAVE_OFFSET + 0
MCI_WAVE_MAPPER = MCI_WAVE_OFFSET + 1
MCI_WAVE_OPEN_BUFFER = 0x00010000
MCI_WAVE_SET_FORMATTAG = 0x00010000
MCI_WAVE_SET_CHANNELS = 0x00020000
MCI_WAVE_SET_SAMPLESPERSEC = 0x00040000
MCI_WAVE_SET_AVGBYTESPERSEC = 0x00080000
MCI_WAVE_SET_BLOCKALIGN = 0x00100000
MCI_WAVE_SET_BITSPERSAMPLE = 0x00200000
MCI_WAVE_INPUT = 0x00400000
MCI_WAVE_OUTPUT = 0x00800000
MCI_WAVE_STATUS_FORMATTAG = 0x00004001
MCI_WAVE_STATUS_CHANNELS = 0x00004002
MCI_WAVE_STATUS_SAMPLESPERSEC = 0x00004003
MCI_WAVE_STATUS_AVGBYTESPERSEC = 0x00004004
MCI_WAVE_STATUS_BLOCKALIGN = 0x00004005
MCI_WAVE_STATUS_BITSPERSAMPLE = 0x00004006
MCI_WAVE_STATUS_LEVEL = 0x00004007
MCI_WAVE_SET_ANYINPUT = 0x04000000
MCI_WAVE_SET_ANYOUTPUT = 0x08000000
MCI_WAVE_GETDEVCAPS_INPUTS = 0x00004001
MCI_WAVE_GETDEVCAPS_OUTPUTS = 0x00004002
MCI_SEQ_DIV_PPQN = 0 + MCI_SEQ_OFFSET
MCI_SEQ_DIV_SMPTE_24 = 1 + MCI_SEQ_OFFSET
MCI_SEQ_DIV_SMPTE_25 = 2 + MCI_SEQ_OFFSET
MCI_SEQ_DIV_SMPTE_30DROP = 3 + MCI_SEQ_OFFSET
MCI_SEQ_DIV_SMPTE_30 = 4 + MCI_SEQ_OFFSET
MCI_SEQ_FORMAT_SONGPTR = 0x4001
MCI_SEQ_FILE = 0x4002
MCI_SEQ_MIDI = 0x4003
MCI_SEQ_SMPTE = 0x4004
MCI_SEQ_NONE = 65533
MCI_SEQ_MAPPER = 65535
MCI_SEQ_STATUS_TEMPO = 0x00004002
MCI_SEQ_STATUS_PORT = 0x00004003
MCI_SEQ_STATUS_SLAVE = 0x00004007
MCI_SEQ_STATUS_MASTER = 0x00004008
MCI_SEQ_STATUS_OFFSET = 0x00004009
MCI_SEQ_STATUS_DIVTYPE = 0x0000400A
MCI_SEQ_STATUS_NAME = 0x0000400B
MCI_SEQ_STATUS_COPYRIGHT = 0x0000400C
MCI_SEQ_SET_TEMPO = 0x00010000
MCI_SEQ_SET_PORT = 0x00020000
MCI_SEQ_SET_SLAVE = 0x00040000
MCI_SEQ_SET_MASTER = 0x00080000
MCI_SEQ_SET_OFFSET = 0x01000000
MCI_ANIM_OPEN_WS = 0x00010000
MCI_ANIM_OPEN_PARENT = 0x00020000
MCI_ANIM_OPEN_NOSTATIC = 0x00040000
MCI_ANIM_PLAY_SPEED = 0x00010000
MCI_ANIM_PLAY_REVERSE = 0x00020000
MCI_ANIM_PLAY_FAST = 0x00040000
MCI_ANIM_PLAY_SLOW = 0x00080000
MCI_ANIM_PLAY_SCAN = 0x00100000
MCI_ANIM_STEP_REVERSE = 0x00010000
MCI_ANIM_STEP_FRAMES = 0x00020000
MCI_ANIM_STATUS_SPEED = 0x00004001
MCI_ANIM_STATUS_FORWARD = 0x00004002
MCI_ANIM_STATUS_HWND = 0x00004003
MCI_ANIM_STATUS_HPAL = 0x00004004
MCI_ANIM_STATUS_STRETCH = 0x00004005
MCI_ANIM_INFO_TEXT = 0x00010000
MCI_ANIM_GETDEVCAPS_CAN_REVERSE = 0x00004001
MCI_ANIM_GETDEVCAPS_FAST_RATE = 0x00004002
MCI_ANIM_GETDEVCAPS_SLOW_RATE = 0x00004003
MCI_ANIM_GETDEVCAPS_NORMAL_RATE = 0x00004004
MCI_ANIM_GETDEVCAPS_PALETTES = 0x00004006
MCI_ANIM_GETDEVCAPS_CAN_STRETCH = 0x00004007
MCI_ANIM_GETDEVCAPS_MAX_WINDOWS = 0x00004008
MCI_ANIM_REALIZE_NORM = 0x00010000
MCI_ANIM_REALIZE_BKGD = 0x00020000
MCI_ANIM_WINDOW_HWND = 0x00010000
MCI_ANIM_WINDOW_STATE = 0x00040000
MCI_ANIM_WINDOW_TEXT = 0x00080000
MCI_ANIM_WINDOW_ENABLE_STRETCH = 0x00100000
MCI_ANIM_WINDOW_DISABLE_STRETCH = 0x00200000
MCI_ANIM_WINDOW_DEFAULT = 0x00000000
MCI_ANIM_RECT = 0x00010000
MCI_ANIM_PUT_SOURCE = 0x00020000
MCI_ANIM_PUT_DESTINATION = 0x00040000
MCI_ANIM_WHERE_SOURCE = 0x00020000
MCI_ANIM_WHERE_DESTINATION = 0x00040000
MCI_ANIM_UPDATE_HDC = 0x00020000
MCI_OVLY_OPEN_WS = 0x00010000
MCI_OVLY_OPEN_PARENT = 0x00020000
MCI_OVLY_STATUS_HWND = 0x00004001
MCI_OVLY_STATUS_STRETCH = 0x00004002
MCI_OVLY_INFO_TEXT = 0x00010000
MCI_OVLY_GETDEVCAPS_CAN_STRETCH = 0x00004001
MCI_OVLY_GETDEVCAPS_CAN_FREEZE = 0x00004002
MCI_OVLY_GETDEVCAPS_MAX_WINDOWS = 0x00004003
MCI_OVLY_WINDOW_HWND = 0x00010000
MCI_OVLY_WINDOW_STATE = 0x00040000
MCI_OVLY_WINDOW_TEXT = 0x00080000
MCI_OVLY_WINDOW_ENABLE_STRETCH = 0x00100000
MCI_OVLY_WINDOW_DISABLE_STRETCH = 0x00200000
MCI_OVLY_WINDOW_DEFAULT = 0x00000000
MCI_OVLY_RECT = 0x00010000
MCI_OVLY_PUT_SOURCE = 0x00020000
MCI_OVLY_PUT_DESTINATION = 0x00040000
MCI_OVLY_PUT_FRAME = 0x00080000
MCI_OVLY_PUT_VIDEO = 0x00100000
MCI_OVLY_WHERE_SOURCE = 0x00020000
MCI_OVLY_WHERE_DESTINATION = 0x00040000
MCI_OVLY_WHERE_FRAME = 0x00080000
MCI_OVLY_WHERE_VIDEO = 0x00100000
SELECTDIB = 41
def DIBINDEX(n):
return MAKELONG((n), 0x10FF)

304
lib/win32/lib/netbios.py Normal file
View file

@ -0,0 +1,304 @@
import struct
import sys
import win32wnet
# Constants generated by h2py from nb30.h
NCBNAMSZ = 16
MAX_LANA = 254
NAME_FLAGS_MASK = 0x87
GROUP_NAME = 0x80
UNIQUE_NAME = 0x00
REGISTERING = 0x00
REGISTERED = 0x04
DEREGISTERED = 0x05
DUPLICATE = 0x06
DUPLICATE_DEREG = 0x07
LISTEN_OUTSTANDING = 0x01
CALL_PENDING = 0x02
SESSION_ESTABLISHED = 0x03
HANGUP_PENDING = 0x04
HANGUP_COMPLETE = 0x05
SESSION_ABORTED = 0x06
ALL_TRANSPORTS = "M\0\0\0"
MS_NBF = "MNBF"
NCBCALL = 0x10
NCBLISTEN = 0x11
NCBHANGUP = 0x12
NCBSEND = 0x14
NCBRECV = 0x15
NCBRECVANY = 0x16
NCBCHAINSEND = 0x17
NCBDGSEND = 0x20
NCBDGRECV = 0x21
NCBDGSENDBC = 0x22
NCBDGRECVBC = 0x23
NCBADDNAME = 0x30
NCBDELNAME = 0x31
NCBRESET = 0x32
NCBASTAT = 0x33
NCBSSTAT = 0x34
NCBCANCEL = 0x35
NCBADDGRNAME = 0x36
NCBENUM = 0x37
NCBUNLINK = 0x70
NCBSENDNA = 0x71
NCBCHAINSENDNA = 0x72
NCBLANSTALERT = 0x73
NCBACTION = 0x77
NCBFINDNAME = 0x78
NCBTRACE = 0x79
ASYNCH = 0x80
NRC_GOODRET = 0x00
NRC_BUFLEN = 0x01
NRC_ILLCMD = 0x03
NRC_CMDTMO = 0x05
NRC_INCOMP = 0x06
NRC_BADDR = 0x07
NRC_SNUMOUT = 0x08
NRC_NORES = 0x09
NRC_SCLOSED = 0x0A
NRC_CMDCAN = 0x0B
NRC_DUPNAME = 0x0D
NRC_NAMTFUL = 0x0E
NRC_ACTSES = 0x0F
NRC_LOCTFUL = 0x11
NRC_REMTFUL = 0x12
NRC_ILLNN = 0x13
NRC_NOCALL = 0x14
NRC_NOWILD = 0x15
NRC_INUSE = 0x16
NRC_NAMERR = 0x17
NRC_SABORT = 0x18
NRC_NAMCONF = 0x19
NRC_IFBUSY = 0x21
NRC_TOOMANY = 0x22
NRC_BRIDGE = 0x23
NRC_CANOCCR = 0x24
NRC_CANCEL = 0x26
NRC_DUPENV = 0x30
NRC_ENVNOTDEF = 0x34
NRC_OSRESNOTAV = 0x35
NRC_MAXAPPS = 0x36
NRC_NOSAPS = 0x37
NRC_NORESOURCES = 0x38
NRC_INVADDRESS = 0x39
NRC_INVDDID = 0x3B
NRC_LOCKFAIL = 0x3C
NRC_OPENERR = 0x3F
NRC_SYSTEM = 0x40
NRC_PENDING = 0xFF
UCHAR = "B"
WORD = "H"
DWORD = "I"
USHORT = "H"
ULONG = "I"
ADAPTER_STATUS_ITEMS = [
("6s", "adapter_address"),
(UCHAR, "rev_major"),
(UCHAR, "reserved0"),
(UCHAR, "adapter_type"),
(UCHAR, "rev_minor"),
(WORD, "duration"),
(WORD, "frmr_recv"),
(WORD, "frmr_xmit"),
(WORD, "iframe_recv_err"),
(WORD, "xmit_aborts"),
(DWORD, "xmit_success"),
(DWORD, "recv_success"),
(WORD, "iframe_xmit_err"),
(WORD, "recv_buff_unavail"),
(WORD, "t1_timeouts"),
(WORD, "ti_timeouts"),
(DWORD, "reserved1"),
(WORD, "free_ncbs"),
(WORD, "max_cfg_ncbs"),
(WORD, "max_ncbs"),
(WORD, "xmit_buf_unavail"),
(WORD, "max_dgram_size"),
(WORD, "pending_sess"),
(WORD, "max_cfg_sess"),
(WORD, "max_sess"),
(WORD, "max_sess_pkt_size"),
(WORD, "name_count"),
]
NAME_BUFFER_ITEMS = [
(str(NCBNAMSZ) + "s", "name"),
(UCHAR, "name_num"),
(UCHAR, "name_flags"),
]
SESSION_HEADER_ITEMS = [
(UCHAR, "sess_name"),
(UCHAR, "num_sess"),
(UCHAR, "rcv_dg_outstanding"),
(UCHAR, "rcv_any_outstanding"),
]
SESSION_BUFFER_ITEMS = [
(UCHAR, "lsn"),
(UCHAR, "state"),
(str(NCBNAMSZ) + "s", "local_name"),
(str(NCBNAMSZ) + "s", "remote_name"),
(UCHAR, "rcvs_outstanding"),
(UCHAR, "sends_outstanding"),
]
LANA_ENUM_ITEMS = [
("B", "length"), # Number of valid entries in lana[]
(str(MAX_LANA + 1) + "s", "lana"),
]
FIND_NAME_HEADER_ITEMS = [
(WORD, "node_count"),
(UCHAR, "reserved"),
(UCHAR, "unique_group"),
]
FIND_NAME_BUFFER_ITEMS = [
(UCHAR, "length"),
(UCHAR, "access_control"),
(UCHAR, "frame_control"),
("6s", "destination_addr"),
("6s", "source_addr"),
("18s", "routing_info"),
]
ACTION_HEADER_ITEMS = [
(ULONG, "transport_id"),
(USHORT, "action_code"),
(USHORT, "reserved"),
]
del UCHAR, WORD, DWORD, USHORT, ULONG
NCB = win32wnet.NCB
def Netbios(ncb):
ob = ncb.Buffer
is_ours = hasattr(ob, "_pack")
if is_ours:
ob._pack()
try:
return win32wnet.Netbios(ncb)
finally:
if is_ours:
ob._unpack()
class NCBStruct:
def __init__(self, items):
self._format = "".join([item[0] for item in items])
self._items = items
self._buffer_ = win32wnet.NCBBuffer(struct.calcsize(self._format))
for format, name in self._items:
if len(format) == 1:
if format == "c":
val = "\0"
else:
val = 0
else:
l = int(format[:-1])
val = "\0" * l
self.__dict__[name] = val
def _pack(self):
vals = []
for format, name in self._items:
try:
vals.append(self.__dict__[name])
except KeyError:
vals.append(None)
self._buffer_[:] = struct.pack(*(self._format,) + tuple(vals))
def _unpack(self):
items = struct.unpack(self._format, self._buffer_)
assert len(items) == len(self._items), "unexpected number of items to unpack!"
for (format, name), val in zip(self._items, items):
self.__dict__[name] = val
def __setattr__(self, attr, val):
if attr not in self.__dict__ and attr[0] != "_":
for format, attr_name in self._items:
if attr == attr_name:
break
else:
raise AttributeError(attr)
self.__dict__[attr] = val
def ADAPTER_STATUS():
return NCBStruct(ADAPTER_STATUS_ITEMS)
def NAME_BUFFER():
return NCBStruct(NAME_BUFFER_ITEMS)
def SESSION_HEADER():
return NCBStruct(SESSION_HEADER_ITEMS)
def SESSION_BUFFER():
return NCBStruct(SESSION_BUFFER_ITEMS)
def LANA_ENUM():
return NCBStruct(LANA_ENUM_ITEMS)
def FIND_NAME_HEADER():
return NCBStruct(FIND_NAME_HEADER_ITEMS)
def FIND_NAME_BUFFER():
return NCBStruct(FIND_NAME_BUFFER_ITEMS)
def ACTION_HEADER():
return NCBStruct(ACTION_HEADER_ITEMS)
def byte_to_int(b):
"""Given an element in a binary buffer, return its integer value"""
if sys.version_info >= (3, 0):
# a byte is already an int in py3k
return b
return ord(b) # its a char from a string in py2k.
if __name__ == "__main__":
# code ported from "HOWTO: Get the MAC Address for an Ethernet Adapter"
# MS KB ID: Q118623
ncb = NCB()
ncb.Command = NCBENUM
la_enum = LANA_ENUM()
ncb.Buffer = la_enum
rc = Netbios(ncb)
if rc != 0:
raise RuntimeError("Unexpected result %d" % (rc,))
for i in range(la_enum.length):
ncb.Reset()
ncb.Command = NCBRESET
ncb.Lana_num = byte_to_int(la_enum.lana[i])
rc = Netbios(ncb)
if rc != 0:
raise RuntimeError("Unexpected result %d" % (rc,))
ncb.Reset()
ncb.Command = NCBASTAT
ncb.Lana_num = byte_to_int(la_enum.lana[i])
ncb.Callname = "* ".encode("ascii") # ensure bytes on py2x and 3k
adapter = ADAPTER_STATUS()
ncb.Buffer = adapter
Netbios(ncb)
print("Adapter address:", end=" ")
for ch in adapter.adapter_address:
print("%02x" % (byte_to_int(ch),), end=" ")
print()

View file

@ -0,0 +1,731 @@
# Hacked from winnt.h
DELETE = 65536
READ_CONTROL = 131072
WRITE_DAC = 262144
WRITE_OWNER = 524288
SYNCHRONIZE = 1048576
STANDARD_RIGHTS_REQUIRED = 983040
STANDARD_RIGHTS_READ = READ_CONTROL
STANDARD_RIGHTS_WRITE = READ_CONTROL
STANDARD_RIGHTS_EXECUTE = READ_CONTROL
STANDARD_RIGHTS_ALL = 2031616
SPECIFIC_RIGHTS_ALL = 65535
ACCESS_SYSTEM_SECURITY = 16777216
MAXIMUM_ALLOWED = 33554432
GENERIC_READ = -2147483648
GENERIC_WRITE = 1073741824
GENERIC_EXECUTE = 536870912
GENERIC_ALL = 268435456
# file security permissions
FILE_READ_DATA = 1
FILE_LIST_DIRECTORY = 1
FILE_WRITE_DATA = 2
FILE_ADD_FILE = 2
FILE_APPEND_DATA = 4
FILE_ADD_SUBDIRECTORY = 4
FILE_CREATE_PIPE_INSTANCE = 4
FILE_READ_EA = 8
FILE_WRITE_EA = 16
FILE_EXECUTE = 32
FILE_TRAVERSE = 32
FILE_DELETE_CHILD = 64
FILE_READ_ATTRIBUTES = 128
FILE_WRITE_ATTRIBUTES = 256
FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 511
FILE_GENERIC_READ = (
STANDARD_RIGHTS_READ
| FILE_READ_DATA
| FILE_READ_ATTRIBUTES
| FILE_READ_EA
| SYNCHRONIZE
)
FILE_GENERIC_WRITE = (
STANDARD_RIGHTS_WRITE
| FILE_WRITE_DATA
| FILE_WRITE_ATTRIBUTES
| FILE_WRITE_EA
| FILE_APPEND_DATA
| SYNCHRONIZE
)
FILE_GENERIC_EXECUTE = (
STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE
)
SECURITY_NULL_SID_AUTHORITY = (0, 0, 0, 0, 0, 0)
SECURITY_WORLD_SID_AUTHORITY = (0, 0, 0, 0, 0, 1)
SECURITY_LOCAL_SID_AUTHORITY = (0, 0, 0, 0, 0, 2)
SECURITY_CREATOR_SID_AUTHORITY = (0, 0, 0, 0, 0, 3)
SECURITY_NON_UNIQUE_AUTHORITY = (0, 0, 0, 0, 0, 4)
SECURITY_RESOURCE_MANAGER_AUTHORITY = (0, 0, 0, 0, 0, 9)
SECURITY_NULL_RID = 0
SECURITY_WORLD_RID = 0
SECURITY_LOCAL_RID = 0x00000000
SECURITY_CREATOR_OWNER_RID = 0
SECURITY_CREATOR_GROUP_RID = 1
SECURITY_CREATOR_OWNER_SERVER_RID = 2
SECURITY_CREATOR_GROUP_SERVER_RID = 3
SECURITY_CREATOR_OWNER_RIGHTS_RID = 4
# NT well-known SIDs
SECURITY_NT_AUTHORITY = (0, 0, 0, 0, 0, 5)
SECURITY_DIALUP_RID = 1
SECURITY_NETWORK_RID = 2
SECURITY_BATCH_RID = 3
SECURITY_INTERACTIVE_RID = 4
SECURITY_SERVICE_RID = 6
SECURITY_ANONYMOUS_LOGON_RID = 7
SECURITY_PROXY_RID = 8
SECURITY_SERVER_LOGON_RID = 9
SECURITY_LOGON_IDS_RID = 5
SECURITY_LOGON_IDS_RID_COUNT = 3
SECURITY_LOCAL_SYSTEM_RID = 18
SECURITY_NT_NON_UNIQUE = 21
SECURITY_BUILTIN_DOMAIN_RID = 32
# well-known domain relative sub-authority values (RIDs)...
DOMAIN_USER_RID_ADMIN = 500
DOMAIN_USER_RID_GUEST = 501
DOMAIN_USER_RID_KRBTGT = 502
DOMAIN_USER_RID_MAX = 999
# well-known groups ...
DOMAIN_GROUP_RID_ADMINS = 512
DOMAIN_GROUP_RID_USERS = 513
DOMAIN_GROUP_RID_GUESTS = 514
DOMAIN_GROUP_RID_COMPUTERS = 515
DOMAIN_GROUP_RID_CONTROLLERS = 516
DOMAIN_GROUP_RID_CERT_ADMINS = 517
DOMAIN_GROUP_RID_SCHEMA_ADMINS = 518
DOMAIN_GROUP_RID_ENTERPRISE_ADMINS = 519
DOMAIN_GROUP_RID_POLICY_ADMINS = 520
DOMAIN_GROUP_RID_READONLY_CONTROLLERS = 521
# well-known aliases ...
DOMAIN_ALIAS_RID_ADMINS = 544
DOMAIN_ALIAS_RID_USERS = 545
DOMAIN_ALIAS_RID_GUESTS = 546
DOMAIN_ALIAS_RID_POWER_USERS = 547
DOMAIN_ALIAS_RID_ACCOUNT_OPS = 548
DOMAIN_ALIAS_RID_SYSTEM_OPS = 549
DOMAIN_ALIAS_RID_PRINT_OPS = 550
DOMAIN_ALIAS_RID_BACKUP_OPS = 551
DOMAIN_ALIAS_RID_REPLICATOR = 552
DOMAIN_ALIAS_RID_RAS_SERVERS = 553
DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 554
DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS = 555
DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS = 556
DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 557
DOMAIN_ALIAS_RID_MONITORING_USERS = 558
DOMAIN_ALIAS_RID_LOGGING_USERS = 559
DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS = 560
DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS = 561
DOMAIN_ALIAS_RID_DCOM_USERS = 562
DOMAIN_ALIAS_RID_IUSERS = 568
DOMAIN_ALIAS_RID_CRYPTO_OPERATORS = 569
DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP = 571
DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 572
DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP = 573
SECURITY_MANDATORY_LABEL_AUTHORITY = (0, 0, 0, 0, 0, 16)
SECURITY_MANDATORY_UNTRUSTED_RID = 0x00000000
SECURITY_MANDATORY_LOW_RID = 0x00001000
SECURITY_MANDATORY_MEDIUM_RID = 0x00002000
SECURITY_MANDATORY_HIGH_RID = 0x00003000
SECURITY_MANDATORY_SYSTEM_RID = 0x00004000
SECURITY_MANDATORY_PROTECTED_PROCESS_RID = 0x00005000
SECURITY_MANDATORY_MAXIMUM_USER_RID = SECURITY_MANDATORY_SYSTEM_RID
SYSTEM_LUID = (999, 0)
ANONYMOUS_LOGON_LUID = (998, 0)
LOCALSERVICE_LUID = (997, 0)
NETWORKSERVICE_LUID = (996, 0)
IUSER_LUID = (995, 0)
# Group attributes
SE_GROUP_MANDATORY = 1
SE_GROUP_ENABLED_BY_DEFAULT = 2
SE_GROUP_ENABLED = 4
SE_GROUP_OWNER = 8
SE_GROUP_USE_FOR_DENY_ONLY = 16
SE_GROUP_INTEGRITY = 32
SE_GROUP_INTEGRITY_ENABLED = 64
SE_GROUP_RESOURCE = 536870912
SE_GROUP_LOGON_ID = -1073741824
# User attributes
# (None yet defined.)
# ACE types
ACCESS_MIN_MS_ACE_TYPE = 0
ACCESS_ALLOWED_ACE_TYPE = 0
ACCESS_DENIED_ACE_TYPE = 1
SYSTEM_AUDIT_ACE_TYPE = 2
SYSTEM_ALARM_ACE_TYPE = 3
ACCESS_MAX_MS_V2_ACE_TYPE = 3
ACCESS_ALLOWED_COMPOUND_ACE_TYPE = 4
ACCESS_MAX_MS_V3_ACE_TYPE = 4
ACCESS_MIN_MS_OBJECT_ACE_TYPE = 5
ACCESS_ALLOWED_OBJECT_ACE_TYPE = 5
ACCESS_DENIED_OBJECT_ACE_TYPE = 6
SYSTEM_AUDIT_OBJECT_ACE_TYPE = 7
SYSTEM_ALARM_OBJECT_ACE_TYPE = 8
ACCESS_MAX_MS_OBJECT_ACE_TYPE = 8
ACCESS_MAX_MS_V4_ACE_TYPE = 8
ACCESS_MAX_MS_ACE_TYPE = 8
ACCESS_ALLOWED_CALLBACK_ACE_TYPE = 9
ACCESS_DENIED_CALLBACK_ACE_TYPE = 10
ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE = 11
ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE = 12
SYSTEM_AUDIT_CALLBACK_ACE_TYPE = 13
SYSTEM_ALARM_CALLBACK_ACE_TYPE = 14
SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE = 15
SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE = 16
SYSTEM_MANDATORY_LABEL_ACE_TYPE = 17
ACCESS_MAX_MS_V5_ACE_TYPE = 17
# The following are the inherit flags that go into the AceFlags field
# of an Ace header.
OBJECT_INHERIT_ACE = 1
CONTAINER_INHERIT_ACE = 2
NO_PROPAGATE_INHERIT_ACE = 4
INHERIT_ONLY_ACE = 8
VALID_INHERIT_FLAGS = 15
SUCCESSFUL_ACCESS_ACE_FLAG = 64
FAILED_ACCESS_ACE_FLAG = 128
SE_OWNER_DEFAULTED = 1
SE_GROUP_DEFAULTED = 2
SE_DACL_PRESENT = 4
SE_DACL_DEFAULTED = 8
SE_SACL_PRESENT = 16
SE_SACL_DEFAULTED = 32
SE_SELF_RELATIVE = 32768
SE_PRIVILEGE_ENABLED_BY_DEFAULT = 1
SE_PRIVILEGE_ENABLED = 2
SE_PRIVILEGE_USED_FOR_ACCESS = -2147483648
PRIVILEGE_SET_ALL_NECESSARY = 1
# NT Defined Privileges
SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege"
SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege"
SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege"
SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege"
SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege"
SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege"
SE_TCB_NAME = "SeTcbPrivilege"
SE_SECURITY_NAME = "SeSecurityPrivilege"
SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege"
SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege"
SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege"
SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege"
SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege"
SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege"
SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege"
SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege"
SE_BACKUP_NAME = "SeBackupPrivilege"
SE_RESTORE_NAME = "SeRestorePrivilege"
SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
SE_DEBUG_NAME = "SeDebugPrivilege"
SE_AUDIT_NAME = "SeAuditPrivilege"
SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege"
SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege"
SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege"
# Enum SECURITY_IMPERSONATION_LEVEL:
SecurityAnonymous = 0
SecurityIdentification = 1
SecurityImpersonation = 2
SecurityDelegation = 3
SECURITY_MAX_IMPERSONATION_LEVEL = SecurityDelegation
DEFAULT_IMPERSONATION_LEVEL = SecurityImpersonation
TOKEN_ASSIGN_PRIMARY = 1
TOKEN_DUPLICATE = 2
TOKEN_IMPERSONATE = 4
TOKEN_QUERY = 8
TOKEN_QUERY_SOURCE = 16
TOKEN_ADJUST_PRIVILEGES = 32
TOKEN_ADJUST_GROUPS = 64
TOKEN_ADJUST_DEFAULT = 128
TOKEN_ALL_ACCESS = (
STANDARD_RIGHTS_REQUIRED
| TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_IMPERSONATE
| TOKEN_QUERY
| TOKEN_QUERY_SOURCE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_ADJUST_GROUPS
| TOKEN_ADJUST_DEFAULT
)
TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY
TOKEN_WRITE = (
STANDARD_RIGHTS_WRITE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_ADJUST_GROUPS
| TOKEN_ADJUST_DEFAULT
)
TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
SidTypeUser = 1
SidTypeGroup = 2
SidTypeDomain = 3
SidTypeAlias = 4
SidTypeWellKnownGroup = 5
SidTypeDeletedAccount = 6
SidTypeInvalid = 7
SidTypeUnknown = 8
SidTypeComputer = 9
SidTypeLabel = 10
# Token types
TokenPrimary = 1
TokenImpersonation = 2
# TOKEN_INFORMATION_CLASS, used with Get/SetTokenInformation
TokenUser = 1
TokenGroups = 2
TokenPrivileges = 3
TokenOwner = 4
TokenPrimaryGroup = 5
TokenDefaultDacl = 6
TokenSource = 7
TokenType = 8
TokenImpersonationLevel = 9
TokenStatistics = 10
TokenRestrictedSids = 11
TokenSessionId = 12
TokenGroupsAndPrivileges = 13
TokenSessionReference = 14
TokenSandBoxInert = 15
TokenAuditPolicy = 16
TokenOrigin = 17
TokenElevationType = 18
TokenLinkedToken = 19
TokenElevation = 20
TokenHasRestrictions = 21
TokenAccessInformation = 22
TokenVirtualizationAllowed = 23
TokenVirtualizationEnabled = 24
TokenIntegrityLevel = 25
TokenUIAccess = 26
TokenMandatoryPolicy = 27
TokenLogonSid = 28
# DirectoryService related constants.
# Generated by h2py from NtDsAPI.h
DS_BEHAVIOR_WIN2000 = 0
DS_BEHAVIOR_WIN2003_WITH_MIXED_DOMAINS = 1
DS_BEHAVIOR_WIN2003 = 2
DS_SYNCED_EVENT_NAME = "NTDSInitialSyncsCompleted"
ACTRL_DS_OPEN = 0x00000000
ACTRL_DS_CREATE_CHILD = 0x00000001
ACTRL_DS_DELETE_CHILD = 0x00000002
ACTRL_DS_LIST = 0x00000004
ACTRL_DS_SELF = 0x00000008
ACTRL_DS_READ_PROP = 0x00000010
ACTRL_DS_WRITE_PROP = 0x00000020
ACTRL_DS_DELETE_TREE = 0x00000040
ACTRL_DS_LIST_OBJECT = 0x00000080
ACTRL_DS_CONTROL_ACCESS = 0x00000100
NTDSAPI_BIND_ALLOW_DELEGATION = 0x00000001
DS_REPSYNC_ASYNCHRONOUS_OPERATION = 0x00000001
DS_REPSYNC_WRITEABLE = 0x00000002
DS_REPSYNC_PERIODIC = 0x00000004
DS_REPSYNC_INTERSITE_MESSAGING = 0x00000008
DS_REPSYNC_ALL_SOURCES = 0x00000010
DS_REPSYNC_FULL = 0x00000020
DS_REPSYNC_URGENT = 0x00000040
DS_REPSYNC_NO_DISCARD = 0x00000080
DS_REPSYNC_FORCE = 0x00000100
DS_REPSYNC_ADD_REFERENCE = 0x00000200
DS_REPSYNC_NEVER_COMPLETED = 0x00000400
DS_REPSYNC_TWO_WAY = 0x00000800
DS_REPSYNC_NEVER_NOTIFY = 0x00001000
DS_REPSYNC_INITIAL = 0x00002000
DS_REPSYNC_USE_COMPRESSION = 0x00004000
DS_REPSYNC_ABANDONED = 0x00008000
DS_REPSYNC_INITIAL_IN_PROGRESS = 0x00010000
DS_REPSYNC_PARTIAL_ATTRIBUTE_SET = 0x00020000
DS_REPSYNC_REQUEUE = 0x00040000
DS_REPSYNC_NOTIFICATION = 0x00080000
DS_REPSYNC_ASYNCHRONOUS_REPLICA = 0x00100000
DS_REPSYNC_CRITICAL = 0x00200000
DS_REPSYNC_FULL_IN_PROGRESS = 0x00400000
DS_REPSYNC_PREEMPTED = 0x00800000
DS_REPADD_ASYNCHRONOUS_OPERATION = 0x00000001
DS_REPADD_WRITEABLE = 0x00000002
DS_REPADD_INITIAL = 0x00000004
DS_REPADD_PERIODIC = 0x00000008
DS_REPADD_INTERSITE_MESSAGING = 0x00000010
DS_REPADD_ASYNCHRONOUS_REPLICA = 0x00000020
DS_REPADD_DISABLE_NOTIFICATION = 0x00000040
DS_REPADD_DISABLE_PERIODIC = 0x00000080
DS_REPADD_USE_COMPRESSION = 0x00000100
DS_REPADD_NEVER_NOTIFY = 0x00000200
DS_REPADD_TWO_WAY = 0x00000400
DS_REPADD_CRITICAL = 0x00000800
DS_REPDEL_ASYNCHRONOUS_OPERATION = 0x00000001
DS_REPDEL_WRITEABLE = 0x00000002
DS_REPDEL_INTERSITE_MESSAGING = 0x00000004
DS_REPDEL_IGNORE_ERRORS = 0x00000008
DS_REPDEL_LOCAL_ONLY = 0x00000010
DS_REPDEL_NO_SOURCE = 0x00000020
DS_REPDEL_REF_OK = 0x00000040
DS_REPMOD_ASYNCHRONOUS_OPERATION = 0x00000001
DS_REPMOD_WRITEABLE = 0x00000002
DS_REPMOD_UPDATE_FLAGS = 0x00000001
DS_REPMOD_UPDATE_ADDRESS = 0x00000002
DS_REPMOD_UPDATE_SCHEDULE = 0x00000004
DS_REPMOD_UPDATE_RESULT = 0x00000008
DS_REPMOD_UPDATE_TRANSPORT = 0x00000010
DS_REPUPD_ASYNCHRONOUS_OPERATION = 0x00000001
DS_REPUPD_WRITEABLE = 0x00000002
DS_REPUPD_ADD_REFERENCE = 0x00000004
DS_REPUPD_DELETE_REFERENCE = 0x00000008
DS_INSTANCETYPE_IS_NC_HEAD = 0x00000001
DS_INSTANCETYPE_NC_IS_WRITEABLE = 0x00000004
DS_INSTANCETYPE_NC_COMING = 0x00000010
DS_INSTANCETYPE_NC_GOING = 0x00000020
NTDSDSA_OPT_IS_GC = 1 << 0
NTDSDSA_OPT_DISABLE_INBOUND_REPL = 1 << 1
NTDSDSA_OPT_DISABLE_OUTBOUND_REPL = 1 << 2
NTDSDSA_OPT_DISABLE_NTDSCONN_XLATE = 1 << 3
NTDSCONN_OPT_IS_GENERATED = 1 << 0
NTDSCONN_OPT_TWOWAY_SYNC = 1 << 1
NTDSCONN_OPT_OVERRIDE_NOTIFY_DEFAULT = 1 << 2
NTDSCONN_OPT_USE_NOTIFY = 1 << 3
NTDSCONN_OPT_DISABLE_INTERSITE_COMPRESSION = 1 << 4
NTDSCONN_OPT_USER_OWNED_SCHEDULE = 1 << 5
NTDSCONN_KCC_NO_REASON = 0
NTDSCONN_KCC_GC_TOPOLOGY = 1 << 0
NTDSCONN_KCC_RING_TOPOLOGY = 1 << 1
NTDSCONN_KCC_MINIMIZE_HOPS_TOPOLOGY = 1 << 2
NTDSCONN_KCC_STALE_SERVERS_TOPOLOGY = 1 << 3
NTDSCONN_KCC_OSCILLATING_CONNECTION_TOPOLOGY = 1 << 4
NTDSCONN_KCC_INTERSITE_GC_TOPOLOGY = 1 << 5
NTDSCONN_KCC_INTERSITE_TOPOLOGY = 1 << 6
NTDSCONN_KCC_SERVER_FAILOVER_TOPOLOGY = 1 << 7
NTDSCONN_KCC_SITE_FAILOVER_TOPOLOGY = 1 << 8
NTDSCONN_KCC_REDUNDANT_SERVER_TOPOLOGY = 1 << 9
FRSCONN_PRIORITY_MASK = 0x70000000
FRSCONN_MAX_PRIORITY = 0x8
NTDSCONN_OPT_IGNORE_SCHEDULE_MASK = -2147483648
NTDSSETTINGS_OPT_IS_AUTO_TOPOLOGY_DISABLED = 1 << 0
NTDSSETTINGS_OPT_IS_TOPL_CLEANUP_DISABLED = 1 << 1
NTDSSETTINGS_OPT_IS_TOPL_MIN_HOPS_DISABLED = 1 << 2
NTDSSETTINGS_OPT_IS_TOPL_DETECT_STALE_DISABLED = 1 << 3
NTDSSETTINGS_OPT_IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED = 1 << 4
NTDSSETTINGS_OPT_IS_GROUP_CACHING_ENABLED = 1 << 5
NTDSSETTINGS_OPT_FORCE_KCC_WHISTLER_BEHAVIOR = 1 << 6
NTDSSETTINGS_OPT_FORCE_KCC_W2K_ELECTION = 1 << 7
NTDSSETTINGS_OPT_IS_RAND_BH_SELECTION_DISABLED = 1 << 8
NTDSSETTINGS_OPT_IS_SCHEDULE_HASHING_ENABLED = 1 << 9
NTDSSETTINGS_OPT_IS_REDUNDANT_SERVER_TOPOLOGY_ENABLED = 1 << 10
NTDSSETTINGS_DEFAULT_SERVER_REDUNDANCY = 2
NTDSTRANSPORT_OPT_IGNORE_SCHEDULES = 1 << 0
NTDSTRANSPORT_OPT_BRIDGES_REQUIRED = 1 << 1
NTDSSITECONN_OPT_USE_NOTIFY = 1 << 0
NTDSSITECONN_OPT_TWOWAY_SYNC = 1 << 1
NTDSSITECONN_OPT_DISABLE_COMPRESSION = 1 << 2
NTDSSITELINK_OPT_USE_NOTIFY = 1 << 0
NTDSSITELINK_OPT_TWOWAY_SYNC = 1 << 1
NTDSSITELINK_OPT_DISABLE_COMPRESSION = 1 << 2
GUID_USERS_CONTAINER_A = "a9d1ca15768811d1aded00c04fd8d5cd"
GUID_COMPUTRS_CONTAINER_A = "aa312825768811d1aded00c04fd8d5cd"
GUID_SYSTEMS_CONTAINER_A = "ab1d30f3768811d1aded00c04fd8d5cd"
GUID_DOMAIN_CONTROLLERS_CONTAINER_A = "a361b2ffffd211d1aa4b00c04fd7d83a"
GUID_INFRASTRUCTURE_CONTAINER_A = "2fbac1870ade11d297c400c04fd8d5cd"
GUID_DELETED_OBJECTS_CONTAINER_A = "18e2ea80684f11d2b9aa00c04f79f805"
GUID_LOSTANDFOUND_CONTAINER_A = "ab8153b7768811d1aded00c04fd8d5cd"
GUID_FOREIGNSECURITYPRINCIPALS_CONTAINER_A = "22b70c67d56e4efb91e9300fca3dc1aa"
GUID_PROGRAM_DATA_CONTAINER_A = "09460c08ae1e4a4ea0f64aee7daa1e5a"
GUID_MICROSOFT_PROGRAM_DATA_CONTAINER_A = "f4be92a4c777485e878e9421d53087db"
GUID_NTDS_QUOTAS_CONTAINER_A = "6227f0af1fc2410d8e3bb10615bb5b0f"
GUID_USERS_CONTAINER_BYTE = (
"\xa9\xd1\xca\x15\x76\x88\x11\xd1\xad\xed\x00\xc0\x4f\xd8\xd5\xcd"
)
GUID_COMPUTRS_CONTAINER_BYTE = (
"\xaa\x31\x28\x25\x76\x88\x11\xd1\xad\xed\x00\xc0\x4f\xd8\xd5\xcd"
)
GUID_SYSTEMS_CONTAINER_BYTE = (
"\xab\x1d\x30\xf3\x76\x88\x11\xd1\xad\xed\x00\xc0\x4f\xd8\xd5\xcd"
)
GUID_DOMAIN_CONTROLLERS_CONTAINER_BYTE = (
"\xa3\x61\xb2\xff\xff\xd2\x11\xd1\xaa\x4b\x00\xc0\x4f\xd7\xd8\x3a"
)
GUID_INFRASTRUCTURE_CONTAINER_BYTE = (
"\x2f\xba\xc1\x87\x0a\xde\x11\xd2\x97\xc4\x00\xc0\x4f\xd8\xd5\xcd"
)
GUID_DELETED_OBJECTS_CONTAINER_BYTE = (
"\x18\xe2\xea\x80\x68\x4f\x11\xd2\xb9\xaa\x00\xc0\x4f\x79\xf8\x05"
)
GUID_LOSTANDFOUND_CONTAINER_BYTE = (
"\xab\x81\x53\xb7\x76\x88\x11\xd1\xad\xed\x00\xc0\x4f\xd8\xd5\xcd"
)
GUID_FOREIGNSECURITYPRINCIPALS_CONTAINER_BYTE = (
"\x22\xb7\x0c\x67\xd5\x6e\x4e\xfb\x91\xe9\x30\x0f\xca\x3d\xc1\xaa"
)
GUID_PROGRAM_DATA_CONTAINER_BYTE = (
"\x09\x46\x0c\x08\xae\x1e\x4a\x4e\xa0\xf6\x4a\xee\x7d\xaa\x1e\x5a"
)
GUID_MICROSOFT_PROGRAM_DATA_CONTAINER_BYTE = (
"\xf4\xbe\x92\xa4\xc7\x77\x48\x5e\x87\x8e\x94\x21\xd5\x30\x87\xdb"
)
GUID_NTDS_QUOTAS_CONTAINER_BYTE = (
"\x62\x27\xf0\xaf\x1f\xc2\x41\x0d\x8e\x3b\xb1\x06\x15\xbb\x5b\x0f"
)
DS_REPSYNCALL_NO_OPTIONS = 0x00000000
DS_REPSYNCALL_ABORT_IF_SERVER_UNAVAILABLE = 0x00000001
DS_REPSYNCALL_SYNC_ADJACENT_SERVERS_ONLY = 0x00000002
DS_REPSYNCALL_ID_SERVERS_BY_DN = 0x00000004
DS_REPSYNCALL_DO_NOT_SYNC = 0x00000008
DS_REPSYNCALL_SKIP_INITIAL_CHECK = 0x00000010
DS_REPSYNCALL_PUSH_CHANGES_OUTWARD = 0x00000020
DS_REPSYNCALL_CROSS_SITE_BOUNDARIES = 0x00000040
DS_LIST_DSA_OBJECT_FOR_SERVER = 0
DS_LIST_DNS_HOST_NAME_FOR_SERVER = 1
DS_LIST_ACCOUNT_OBJECT_FOR_SERVER = 2
DS_ROLE_SCHEMA_OWNER = 0
DS_ROLE_DOMAIN_OWNER = 1
DS_ROLE_PDC_OWNER = 2
DS_ROLE_RID_OWNER = 3
DS_ROLE_INFRASTRUCTURE_OWNER = 4
DS_SCHEMA_GUID_NOT_FOUND = 0
DS_SCHEMA_GUID_ATTR = 1
DS_SCHEMA_GUID_ATTR_SET = 2
DS_SCHEMA_GUID_CLASS = 3
DS_SCHEMA_GUID_CONTROL_RIGHT = 4
DS_KCC_FLAG_ASYNC_OP = 1 << 0
DS_KCC_FLAG_DAMPED = 1 << 1
DS_EXIST_ADVISORY_MODE = 0x1
DS_REPL_INFO_FLAG_IMPROVE_LINKED_ATTRS = 0x00000001
DS_REPL_NBR_WRITEABLE = 0x00000010
DS_REPL_NBR_SYNC_ON_STARTUP = 0x00000020
DS_REPL_NBR_DO_SCHEDULED_SYNCS = 0x00000040
DS_REPL_NBR_USE_ASYNC_INTERSITE_TRANSPORT = 0x00000080
DS_REPL_NBR_TWO_WAY_SYNC = 0x00000200
DS_REPL_NBR_RETURN_OBJECT_PARENTS = 0x00000800
DS_REPL_NBR_FULL_SYNC_IN_PROGRESS = 0x00010000
DS_REPL_NBR_FULL_SYNC_NEXT_PACKET = 0x00020000
DS_REPL_NBR_NEVER_SYNCED = 0x00200000
DS_REPL_NBR_PREEMPTED = 0x01000000
DS_REPL_NBR_IGNORE_CHANGE_NOTIFICATIONS = 0x04000000
DS_REPL_NBR_DISABLE_SCHEDULED_SYNC = 0x08000000
DS_REPL_NBR_COMPRESS_CHANGES = 0x10000000
DS_REPL_NBR_NO_CHANGE_NOTIFICATIONS = 0x20000000
DS_REPL_NBR_PARTIAL_ATTRIBUTE_SET = 0x40000000
DS_REPL_NBR_MODIFIABLE_MASK = (
DS_REPL_NBR_SYNC_ON_STARTUP
| DS_REPL_NBR_DO_SCHEDULED_SYNCS
| DS_REPL_NBR_TWO_WAY_SYNC
| DS_REPL_NBR_IGNORE_CHANGE_NOTIFICATIONS
| DS_REPL_NBR_DISABLE_SCHEDULED_SYNC
| DS_REPL_NBR_COMPRESS_CHANGES
| DS_REPL_NBR_NO_CHANGE_NOTIFICATIONS
)
# from enum DS_NAME_FORMAT
DS_UNKNOWN_NAME = 0
DS_FQDN_1779_NAME = 1
DS_NT4_ACCOUNT_NAME = 2
DS_DISPLAY_NAME = 3
DS_UNIQUE_ID_NAME = 6
DS_CANONICAL_NAME = 7
DS_USER_PRINCIPAL_NAME = 8
DS_CANONICAL_NAME_EX = 9
DS_SERVICE_PRINCIPAL_NAME = 10
DS_SID_OR_SID_HISTORY_NAME = 11
DS_DNS_DOMAIN_NAME = 12
DS_DOMAIN_SIMPLE_NAME = DS_USER_PRINCIPAL_NAME
DS_ENTERPRISE_SIMPLE_NAME = DS_USER_PRINCIPAL_NAME
# from enum DS_NAME_FLAGS
DS_NAME_NO_FLAGS = 0x0
DS_NAME_FLAG_SYNTACTICAL_ONLY = 0x1
DS_NAME_FLAG_EVAL_AT_DC = 0x2
DS_NAME_FLAG_GCVERIFY = 0x4
DS_NAME_FLAG_TRUST_REFERRAL = 0x8
# from enum DS_NAME_ERROR
DS_NAME_NO_ERROR = 0
DS_NAME_ERROR_RESOLVING = 1
DS_NAME_ERROR_NOT_FOUND = 2
DS_NAME_ERROR_NOT_UNIQUE = 3
DS_NAME_ERROR_NO_MAPPING = 4
DS_NAME_ERROR_DOMAIN_ONLY = 5
DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 6
DS_NAME_ERROR_TRUST_REFERRAL = 7
# from enum DS_SPN_NAME_TYPE
DS_SPN_DNS_HOST = 0
DS_SPN_DN_HOST = 1
DS_SPN_NB_HOST = 2
DS_SPN_DOMAIN = 3
DS_SPN_NB_DOMAIN = 4
DS_SPN_SERVICE = 5
# from enum DS_SPN_WRITE_OP
DS_SPN_ADD_SPN_OP = 0
DS_SPN_REPLACE_SPN_OP = 1
DS_SPN_DELETE_SPN_OP = 2
# Generated by h2py from DsGetDC.h
DS_FORCE_REDISCOVERY = 0x00000001
DS_DIRECTORY_SERVICE_REQUIRED = 0x00000010
DS_DIRECTORY_SERVICE_PREFERRED = 0x00000020
DS_GC_SERVER_REQUIRED = 0x00000040
DS_PDC_REQUIRED = 0x00000080
DS_BACKGROUND_ONLY = 0x00000100
DS_IP_REQUIRED = 0x00000200
DS_KDC_REQUIRED = 0x00000400
DS_TIMESERV_REQUIRED = 0x00000800
DS_WRITABLE_REQUIRED = 0x00001000
DS_GOOD_TIMESERV_PREFERRED = 0x00002000
DS_AVOID_SELF = 0x00004000
DS_ONLY_LDAP_NEEDED = 0x00008000
DS_IS_FLAT_NAME = 0x00010000
DS_IS_DNS_NAME = 0x00020000
DS_RETURN_DNS_NAME = 0x40000000
DS_RETURN_FLAT_NAME = -2147483648
DSGETDC_VALID_FLAGS = (
DS_FORCE_REDISCOVERY
| DS_DIRECTORY_SERVICE_REQUIRED
| DS_DIRECTORY_SERVICE_PREFERRED
| DS_GC_SERVER_REQUIRED
| DS_PDC_REQUIRED
| DS_BACKGROUND_ONLY
| DS_IP_REQUIRED
| DS_KDC_REQUIRED
| DS_TIMESERV_REQUIRED
| DS_WRITABLE_REQUIRED
| DS_GOOD_TIMESERV_PREFERRED
| DS_AVOID_SELF
| DS_ONLY_LDAP_NEEDED
| DS_IS_FLAT_NAME
| DS_IS_DNS_NAME
| DS_RETURN_FLAT_NAME
| DS_RETURN_DNS_NAME
)
DS_INET_ADDRESS = 1
DS_NETBIOS_ADDRESS = 2
DS_PDC_FLAG = 0x00000001
DS_GC_FLAG = 0x00000004
DS_LDAP_FLAG = 0x00000008
DS_DS_FLAG = 0x00000010
DS_KDC_FLAG = 0x00000020
DS_TIMESERV_FLAG = 0x00000040
DS_CLOSEST_FLAG = 0x00000080
DS_WRITABLE_FLAG = 0x00000100
DS_GOOD_TIMESERV_FLAG = 0x00000200
DS_NDNC_FLAG = 0x00000400
DS_PING_FLAGS = 0x0000FFFF
DS_DNS_CONTROLLER_FLAG = 0x20000000
DS_DNS_DOMAIN_FLAG = 0x40000000
DS_DNS_FOREST_FLAG = -2147483648
DS_DOMAIN_IN_FOREST = 0x0001
DS_DOMAIN_DIRECT_OUTBOUND = 0x0002
DS_DOMAIN_TREE_ROOT = 0x0004
DS_DOMAIN_PRIMARY = 0x0008
DS_DOMAIN_NATIVE_MODE = 0x0010
DS_DOMAIN_DIRECT_INBOUND = 0x0020
DS_DOMAIN_VALID_FLAGS = (
DS_DOMAIN_IN_FOREST
| DS_DOMAIN_DIRECT_OUTBOUND
| DS_DOMAIN_TREE_ROOT
| DS_DOMAIN_PRIMARY
| DS_DOMAIN_NATIVE_MODE
| DS_DOMAIN_DIRECT_INBOUND
)
DS_GFTI_UPDATE_TDO = 0x1
DS_GFTI_VALID_FLAGS = 0x1
DS_ONLY_DO_SITE_NAME = 0x01
DS_NOTIFY_AFTER_SITE_RECORDS = 0x02
DS_OPEN_VALID_OPTION_FLAGS = DS_ONLY_DO_SITE_NAME | DS_NOTIFY_AFTER_SITE_RECORDS
DS_OPEN_VALID_FLAGS = (
DS_FORCE_REDISCOVERY
| DS_ONLY_LDAP_NEEDED
| DS_KDC_REQUIRED
| DS_PDC_REQUIRED
| DS_GC_SERVER_REQUIRED
| DS_WRITABLE_REQUIRED
)
## from aclui.h
# SI_OBJECT_INFO.dwFlags
SI_EDIT_PERMS = 0x00000000
SI_EDIT_OWNER = 0x00000001
SI_EDIT_AUDITS = 0x00000002
SI_CONTAINER = 0x00000004
SI_READONLY = 0x00000008
SI_ADVANCED = 0x00000010
SI_RESET = 0x00000020
SI_OWNER_READONLY = 0x00000040
SI_EDIT_PROPERTIES = 0x00000080
SI_OWNER_RECURSE = 0x00000100
SI_NO_ACL_PROTECT = 0x00000200
SI_NO_TREE_APPLY = 0x00000400
SI_PAGE_TITLE = 0x00000800
SI_SERVER_IS_DC = 0x00001000
SI_RESET_DACL_TREE = 0x00004000
SI_RESET_SACL_TREE = 0x00008000
SI_OBJECT_GUID = 0x00010000
SI_EDIT_EFFECTIVE = 0x00020000
SI_RESET_DACL = 0x00040000
SI_RESET_SACL = 0x00080000
SI_RESET_OWNER = 0x00100000
SI_NO_ADDITIONAL_PERMISSION = 0x00200000
SI_MAY_WRITE = 0x10000000
SI_EDIT_ALL = SI_EDIT_PERMS | SI_EDIT_OWNER | SI_EDIT_AUDITS
SI_AUDITS_ELEVATION_REQUIRED = 0x02000000
SI_VIEW_ONLY = 0x00400000
SI_OWNER_ELEVATION_REQUIRED = 0x04000000
SI_PERMS_ELEVATION_REQUIRED = 0x01000000
# SI_ACCESS.dwFlags
SI_ACCESS_SPECIFIC = 0x00010000
SI_ACCESS_GENERAL = 0x00020000
SI_ACCESS_CONTAINER = 0x00040000
SI_ACCESS_PROPERTY = 0x00080000
# SI_PAGE_TYPE enum
SI_PAGE_PERM = 0
SI_PAGE_ADVPERM = 1
SI_PAGE_AUDIT = 2
SI_PAGE_OWNER = 3
SI_PAGE_EFFECTIVE = 4
CFSTR_ACLUI_SID_INFO_LIST = "CFSTR_ACLUI_SID_INFO_LIST"
PSPCB_SI_INITDIALOG = 1025 ## WM_USER+1

View file

@ -0,0 +1,29 @@
# Imported by pywin32.pth to bootstrap the pywin32 environment in "portable"
# environments or any other case where the post-install script isn't run.
#
# In short, there's a directory installed by pywin32 named 'pywin32_system32'
# with some important DLLs which need to be found by Python when some pywin32
# modules are imported.
# If Python has `os.add_dll_directory()`, we need to call it with this path.
# Otherwise, we add this path to PATH.
try:
import pywin32_system32
except ImportError: # Python ≥3.6: replace ImportError with ModuleNotFoundError
pass
else:
import os
# We're guaranteed only that __path__: Iterable[str]
# https://docs.python.org/3/reference/import.html#__path__
for path in pywin32_system32.__path__:
if os.path.isdir(path):
if hasattr(os, "add_dll_directory"):
os.add_dll_directory(path)
# This is to ensure the pywin32 path is in the beginning to find the
# pywin32 DLLs first and prevent other PATH entries to shadow them
elif not os.environ["PATH"].startswith(path):
os.environ["PATH"] = os.environ["PATH"].replace(os.pathsep + path, "")
os.environ["PATH"] = path + os.pathsep + os.environ["PATH"]
break

View file

@ -0,0 +1,327 @@
# Utilities for the pywin32 tests
import gc
import os
import site
import sys
import unittest
import winerror
##
## General purpose utilities for the test suite.
##
# The test suite has lots of string constants containing binary data, but
# the strings are used in various "bytes" contexts.
def str2bytes(sval):
if sys.version_info < (3, 0) and isinstance(sval, str):
sval = sval.decode("latin1")
return sval.encode("latin1")
# Sometimes we want to pass a string that should explicitly be treated as
# a memory blob.
def str2memory(sval):
if sys.version_info < (3, 0):
return buffer(sval)
# py3k.
return memoryview(sval.encode("latin1"))
# Sometimes we want to pass an object that exposes its memory
def ob2memory(ob):
if sys.version_info < (3, 0):
return buffer(ob)
# py3k.
return memoryview(ob)
##
## unittest related stuff
##
# This is a specialized TestCase adaptor which wraps a real test.
class LeakTestCase(unittest.TestCase):
"""An 'adaptor' which takes another test. In debug builds we execute the
test once to remove one-off side-effects, then capture the total
reference count, then execute the test a few times. If the total
refcount at the end is greater than we first captured, we have a leak!
In release builds the test is executed just once, as normal.
Generally used automatically by the test runner - you can safely
ignore this.
"""
def __init__(self, real_test):
unittest.TestCase.__init__(self)
self.real_test = real_test
self.num_test_cases = 1
self.num_leak_iters = 2 # seems to be enough!
if hasattr(sys, "gettotalrefcount"):
self.num_test_cases = self.num_test_cases + self.num_leak_iters
def countTestCases(self):
return self.num_test_cases
def __call__(self, result=None):
# For the COM suite's sake, always ensure we don't leak
# gateways/interfaces
from pythoncom import _GetGatewayCount, _GetInterfaceCount
gc.collect()
ni = _GetInterfaceCount()
ng = _GetGatewayCount()
self.real_test(result)
# Failed - no point checking anything else
if result.shouldStop or not result.wasSuccessful():
return
self._do_leak_tests(result)
gc.collect()
lost_i = _GetInterfaceCount() - ni
lost_g = _GetGatewayCount() - ng
if lost_i or lost_g:
msg = "%d interface objects and %d gateway objects leaked" % (
lost_i,
lost_g,
)
exc = AssertionError(msg)
result.addFailure(self.real_test, (exc.__class__, exc, None))
def runTest(self):
assert 0, "not used"
def _do_leak_tests(self, result=None):
try:
gtrc = sys.gettotalrefcount
except AttributeError:
return # can't do leak tests in this build
# Assume already called once, to prime any caches etc
gc.collect()
trc = gtrc()
for i in range(self.num_leak_iters):
self.real_test(result)
if result.shouldStop:
break
del i # created after we remembered the refcount!
# int division here means one or 2 stray references won't force
# failure, but one per loop
gc.collect()
lost = (gtrc() - trc) // self.num_leak_iters
if lost < 0:
msg = "LeakTest: %s appeared to gain %d references!!" % (
self.real_test,
-lost,
)
result.addFailure(self.real_test, (AssertionError, msg, None))
if lost > 0:
msg = "LeakTest: %s lost %d references" % (self.real_test, lost)
exc = AssertionError(msg)
result.addFailure(self.real_test, (exc.__class__, exc, None))
class TestLoader(unittest.TestLoader):
def loadTestsFromTestCase(self, testCaseClass):
"""Return a suite of all tests cases contained in testCaseClass"""
leak_tests = []
for name in self.getTestCaseNames(testCaseClass):
real_test = testCaseClass(name)
leak_test = self._getTestWrapper(real_test)
leak_tests.append(leak_test)
return self.suiteClass(leak_tests)
def fixupTestsForLeakTests(self, test):
if isinstance(test, unittest.TestSuite):
test._tests = [self.fixupTestsForLeakTests(t) for t in test._tests]
return test
else:
# just a normal test case.
return self._getTestWrapper(test)
def _getTestWrapper(self, test):
# one or 2 tests in the COM test suite set this...
no_leak_tests = getattr(test, "no_leak_tests", False)
if no_leak_tests:
print("Test says it doesn't want leak tests!")
return test
return LeakTestCase(test)
def loadTestsFromModule(self, mod):
if hasattr(mod, "suite"):
tests = mod.suite()
else:
tests = unittest.TestLoader.loadTestsFromModule(self, mod)
return self.fixupTestsForLeakTests(tests)
def loadTestsFromName(self, name, module=None):
test = unittest.TestLoader.loadTestsFromName(self, name, module)
if isinstance(test, unittest.TestSuite):
pass # hmmm? print "Don't wrap suites yet!", test._tests
elif isinstance(test, unittest.TestCase):
test = self._getTestWrapper(test)
else:
print("XXX - what is", test)
return test
# Lots of classes necessary to support one simple feature: we want a 3rd
# test result state - "SKIPPED" - to indicate that the test wasn't able
# to be executed for various reasons. Inspired by bzr's tests, but it
# has other concepts, such as "Expected Failure", which we don't bother
# with.
# win32 error codes that probably mean we need to be elevated (ie, if we
# aren't elevated, we treat these error codes as 'skipped')
non_admin_error_codes = [
winerror.ERROR_ACCESS_DENIED,
winerror.ERROR_PRIVILEGE_NOT_HELD,
]
_is_admin = None
def check_is_admin():
global _is_admin
if _is_admin is None:
import pythoncom
from win32com.shell.shell import IsUserAnAdmin
try:
_is_admin = IsUserAnAdmin()
except pythoncom.com_error as exc:
if exc.hresult != winerror.E_NOTIMPL:
raise
# not impl on this platform - must be old - assume is admin
_is_admin = True
return _is_admin
# Find a test "fixture" (eg, binary test file) expected to be very close to
# the test being run.
# If the tests are being run from the "installed" version, then these fixtures
# probably don't exist - the test is "skipped".
# But it's fatal if we think we might be running from a pywin32 source tree.
def find_test_fixture(basename, extra_dir="."):
# look for the test file in various places
candidates = [
os.path.dirname(sys.argv[0]),
extra_dir,
".",
]
for candidate in candidates:
fname = os.path.join(candidate, basename)
if os.path.isfile(fname):
return fname
else:
# Can't find it - see if this is expected or not.
# This module is typically always in the installed dir, so use argv[0]
this_file = os.path.normcase(os.path.abspath(sys.argv[0]))
dirs_to_check = site.getsitepackages()[:]
if site.USER_SITE:
dirs_to_check.append(site.USER_SITE)
for d in dirs_to_check:
d = os.path.normcase(d)
if os.path.commonprefix([this_file, d]) == d:
# looks like we are in an installed Python, so skip the text.
raise TestSkipped(f"Can't find test fixture '{fname}'")
# Looks like we are running from source, so this is fatal.
raise RuntimeError(f"Can't find test fixture '{fname}'")
# If this exception is raised by a test, the test is reported as a 'skip'
class TestSkipped(Exception):
pass
# This appears to have been "upgraded" to non-private in 3.11
try:
TextTestResult = unittest._TextTestResult
except AttributeError:
TextTestResult = unittest.TextTestResult
# The 'TestResult' subclass that records the failures and has the special
# handling for the TestSkipped exception.
class TestResult(TextTestResult):
def __init__(self, *args, **kw):
super(TestResult, self).__init__(*args, **kw)
self.skips = {} # count of skips for each reason.
def addError(self, test, err):
"""Called when an error has occurred. 'err' is a tuple of values as
returned by sys.exc_info().
"""
# translate a couple of 'well-known' exceptions into 'skipped'
import pywintypes
exc_val = err[1]
# translate ERROR_ACCESS_DENIED for non-admin users to be skipped.
# (access denied errors for an admin user aren't expected.)
if (
isinstance(exc_val, pywintypes.error)
and exc_val.winerror in non_admin_error_codes
and not check_is_admin()
):
exc_val = TestSkipped(exc_val)
# and COM errors due to objects not being registered (the com test
# suite will attempt to catch this and handle it itself if the user
# is admin)
elif isinstance(exc_val, pywintypes.com_error) and exc_val.hresult in [
winerror.CO_E_CLASSSTRING,
winerror.REGDB_E_CLASSNOTREG,
winerror.TYPE_E_LIBNOTREGISTERED,
]:
exc_val = TestSkipped(exc_val)
# NotImplemented generally means the platform doesn't support the
# functionality.
elif isinstance(exc_val, NotImplementedError):
exc_val = TestSkipped(NotImplementedError)
if isinstance(exc_val, TestSkipped):
reason = exc_val.args[0]
# if the reason itself is another exception, get its args.
try:
reason = tuple(reason.args)
except (AttributeError, TypeError):
pass
self.skips.setdefault(reason, 0)
self.skips[reason] += 1
if self.showAll:
self.stream.writeln("SKIP (%s)" % (reason,))
elif self.dots:
self.stream.write("S")
self.stream.flush()
return
super(TestResult, self).addError(test, err)
def printErrors(self):
super(TestResult, self).printErrors()
for reason, num_skipped in self.skips.items():
self.stream.writeln("SKIPPED: %d tests - %s" % (num_skipped, reason))
# TestRunner subclass necessary just to get our TestResult hooked up.
class TestRunner(unittest.TextTestRunner):
def _makeResult(self):
return TestResult(self.stream, self.descriptions, self.verbosity)
# TestProgream subclass necessary just to get our TestRunner hooked up,
# which is necessary to get our TestResult hooked up *sob*
class TestProgram(unittest.TestProgram):
def runTests(self):
# clobber existing runner - *sob* - it shouldn't be this hard
self.testRunner = TestRunner(verbosity=self.verbosity)
unittest.TestProgram.runTests(self)
# A convenient entry-point - if used, 'SKIPPED' exceptions will be supressed.
def testmain(*args, **kw):
new_kw = kw.copy()
if "testLoader" not in new_kw:
new_kw["testLoader"] = TestLoader()
program_class = new_kw.get("testProgram", TestProgram)
program_class(*args, **new_kw)

126
lib/win32/lib/pywintypes.py Normal file
View file

@ -0,0 +1,126 @@
# Magic utility that "redirects" to pywintypesxx.dll
import importlib.machinery
import importlib.util
import os
import sys
def __import_pywin32_system_module__(modname, globs):
# This has been through a number of iterations. The problem: how to
# locate pywintypesXX.dll when it may be in a number of places, and how
# to avoid ever loading it twice. This problem is compounded by the
# fact that the "right" way to do this requires win32api, but this
# itself requires pywintypesXX.
# And the killer problem is that someone may have done 'import win32api'
# before this code is called. In that case Windows will have already
# loaded pywintypesXX as part of loading win32api - but by the time
# we get here, we may locate a different one. This appears to work, but
# then starts raising bizarre TypeErrors complaining that something
# is not a pywintypes type when it clearly is!
# So in what we hope is the last major iteration of this, we now
# rely on a _win32sysloader module, implemented in C but not relying
# on pywintypesXX.dll. It then can check if the DLL we are looking for
# lib is already loaded.
# See if this is a debug build.
suffix = "_d" if "_d.pyd" in importlib.machinery.EXTENSION_SUFFIXES else ""
filename = "%s%d%d%s.dll" % (
modname,
sys.version_info[0],
sys.version_info[1],
suffix,
)
if hasattr(sys, "frozen"):
# If we are running from a frozen program (py2exe, McMillan, freeze)
# then we try and load the DLL from our sys.path
# XXX - This path may also benefit from _win32sysloader? However,
# MarkH has never seen the DLL load problem with py2exe programs...
for look in sys.path:
# If the sys.path entry is a (presumably) .zip file, use the
# directory
if os.path.isfile(look):
look = os.path.dirname(look)
found = os.path.join(look, filename)
if os.path.isfile(found):
break
else:
raise ImportError(
"Module '%s' isn't in frozen sys.path %s" % (modname, sys.path)
)
else:
# First see if it already in our process - if so, we must use that.
import _win32sysloader
found = _win32sysloader.GetModuleFilename(filename)
if found is None:
# We ask Windows to load it next. This is in an attempt to
# get the exact same module loaded should pywintypes be imported
# first (which is how we are here) or if, eg, win32api was imported
# first thereby implicitly loading the DLL.
# Sadly though, it doesn't quite work - if pywintypesxx.dll
# is in system32 *and* the executable's directory, on XP SP2, an
# import of win32api will cause Windows to load pywintypes
# from system32, where LoadLibrary for that name will
# load the one in the exe's dir.
# That shouldn't really matter though, so long as we only ever
# get one loaded.
found = _win32sysloader.LoadModule(filename)
if found is None:
# Windows can't find it - which although isn't relevent here,
# means that we *must* be the first win32 import, as an attempt
# to import win32api etc would fail when Windows attempts to
# locate the DLL.
# This is most likely to happen for "non-admin" installs, where
# we can't put the files anywhere else on the global path.
# If there is a version in our Python directory, use that
if os.path.isfile(os.path.join(sys.prefix, filename)):
found = os.path.join(sys.prefix, filename)
if found is None:
# Not in the Python directory? Maybe we were installed via
# easy_install...
if os.path.isfile(os.path.join(os.path.dirname(__file__), filename)):
found = os.path.join(os.path.dirname(__file__), filename)
# There are 2 site-packages directories - one "global" and one "user".
# We could be in either, or both (but with different versions!). Factors include
# virtualenvs, post-install script being run or not, `setup.py install` flags, etc.
# In a worst-case, it means, say 'python -c "import win32api"'
# will not work but 'python -c "import pywintypes, win32api"' will,
# but it's better than nothing.
# We use the same logic as pywin32_bootstrap to find potential location for the dll
# Simply import pywin32_system32 and look in the paths in pywin32_system32.__path__
if found is None:
import pywin32_system32
for path in pywin32_system32.__path__:
maybe = os.path.join(path, filename)
if os.path.isfile(maybe):
found = maybe
break
if found is None:
# give up in disgust.
raise ImportError("No system module '%s' (%s)" % (modname, filename))
# After importing the module, sys.modules is updated to the DLL we just
# loaded - which isn't what we want. So we update sys.modules to refer to
# this module, and update our globals from it.
old_mod = sys.modules[modname]
# Load the DLL.
loader = importlib.machinery.ExtensionFileLoader(modname, found)
spec = importlib.machinery.ModuleSpec(name=modname, loader=loader, origin=found)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
# Check the sys.modules[] behaviour we describe above is true...
assert sys.modules[modname] is mod
# as above - re-reset to the *old* module object then update globs.
sys.modules[modname] = old_mod
globs.update(mod.__dict__)
__import_pywin32_system_module__("pywintypes", globals())

40
lib/win32/lib/rasutil.py Normal file
View file

@ -0,0 +1,40 @@
import win32ras
stateStrings = {
win32ras.RASCS_OpenPort: "OpenPort",
win32ras.RASCS_PortOpened: "PortOpened",
win32ras.RASCS_ConnectDevice: "ConnectDevice",
win32ras.RASCS_DeviceConnected: "DeviceConnected",
win32ras.RASCS_AllDevicesConnected: "AllDevicesConnected",
win32ras.RASCS_Authenticate: "Authenticate",
win32ras.RASCS_AuthNotify: "AuthNotify",
win32ras.RASCS_AuthRetry: "AuthRetry",
win32ras.RASCS_AuthCallback: "AuthCallback",
win32ras.RASCS_AuthChangePassword: "AuthChangePassword",
win32ras.RASCS_AuthProject: "AuthProject",
win32ras.RASCS_AuthLinkSpeed: "AuthLinkSpeed",
win32ras.RASCS_AuthAck: "AuthAck",
win32ras.RASCS_ReAuthenticate: "ReAuthenticate",
win32ras.RASCS_Authenticated: "Authenticated",
win32ras.RASCS_PrepareForCallback: "PrepareForCallback",
win32ras.RASCS_WaitForModemReset: "WaitForModemReset",
win32ras.RASCS_WaitForCallback: "WaitForCallback",
win32ras.RASCS_Projected: "Projected",
win32ras.RASCS_StartAuthentication: "StartAuthentication",
win32ras.RASCS_CallbackComplete: "CallbackComplete",
win32ras.RASCS_LogonNetwork: "LogonNetwork",
win32ras.RASCS_Interactive: "Interactive",
win32ras.RASCS_RetryAuthentication: "RetryAuthentication",
win32ras.RASCS_CallbackSetByCaller: "CallbackSetByCaller",
win32ras.RASCS_PasswordExpired: "PasswordExpired",
win32ras.RASCS_Connected: "Connected",
win32ras.RASCS_Disconnected: "Disconnected",
}
def TestCallback(hras, msg, state, error, exterror):
print("Callback called with ", hras, msg, stateStrings[state], error, exterror)
def test(rasName="_ Divert Off"):
return win32ras.Dial(None, None, (rasName,), TestCallback)

162
lib/win32/lib/regcheck.py Normal file
View file

@ -0,0 +1,162 @@
# This module is very old and useless in this day and age! It will be
# removed in a few years (ie, 2009 or so...)
import warnings
warnings.warn(
"The regcheck module has been pending deprecation since build 210",
category=PendingDeprecationWarning,
)
import os
import sys
import regutil
import win32api
import win32con
def CheckRegisteredExe(exename):
try:
os.stat(
win32api.RegQueryValue(
regutil.GetRootKey(), regutil.GetAppPathsKey() + "\\" + exename
)
)
# except SystemError:
except (os.error, win32api.error):
print("Registration of %s - Not registered correctly" % exename)
def CheckPathString(pathString):
for path in pathString.split(";"):
if not os.path.isdir(path):
return "'%s' is not a valid directory!" % path
return None
def CheckPythonPaths(verbose):
if verbose:
print("Python Paths:")
# Check the core path
if verbose:
print("\tCore Path:", end=" ")
try:
appPath = win32api.RegQueryValue(
regutil.GetRootKey(), regutil.BuildDefaultPythonKey() + "\\PythonPath"
)
except win32api.error as exc:
print("** does not exist - ", exc.strerror)
problem = CheckPathString(appPath)
if problem:
print(problem)
else:
if verbose:
print(appPath)
key = win32api.RegOpenKey(
regutil.GetRootKey(),
regutil.BuildDefaultPythonKey() + "\\PythonPath",
0,
win32con.KEY_READ,
)
try:
keyNo = 0
while 1:
try:
appName = win32api.RegEnumKey(key, keyNo)
appPath = win32api.RegQueryValue(key, appName)
if verbose:
print("\t" + appName + ":", end=" ")
if appPath:
problem = CheckPathString(appPath)
if problem:
print(problem)
else:
if verbose:
print(appPath)
else:
if verbose:
print("(empty)")
keyNo = keyNo + 1
except win32api.error:
break
finally:
win32api.RegCloseKey(key)
def CheckHelpFiles(verbose):
if verbose:
print("Help Files:")
try:
key = win32api.RegOpenKey(
regutil.GetRootKey(),
regutil.BuildDefaultPythonKey() + "\\Help",
0,
win32con.KEY_READ,
)
except win32api.error as exc:
import winerror
if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
raise
return
try:
keyNo = 0
while 1:
try:
helpDesc = win32api.RegEnumKey(key, keyNo)
helpFile = win32api.RegQueryValue(key, helpDesc)
if verbose:
print("\t" + helpDesc + ":", end=" ")
# query the os section.
try:
os.stat(helpFile)
if verbose:
print(helpFile)
except os.error:
print("** Help file %s does not exist" % helpFile)
keyNo = keyNo + 1
except win32api.error as exc:
import winerror
if exc.winerror != winerror.ERROR_NO_MORE_ITEMS:
raise
break
finally:
win32api.RegCloseKey(key)
def CheckRegisteredModules(verbose):
# Check out all registered modules.
k = regutil.BuildDefaultPythonKey() + "\\Modules"
try:
keyhandle = win32api.RegOpenKey(regutil.GetRootKey(), k)
print("WARNING: 'Modules' registry entry is deprectated and evil!")
except win32api.error as exc:
import winerror
if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
raise
return
def CheckRegistry(verbose=0):
# check the registered modules
if verbose and "pythonpath" in os.environ:
print("Warning - PythonPath in environment - please check it!")
# Check out all paths on sys.path
CheckPythonPaths(verbose)
CheckHelpFiles(verbose)
CheckRegisteredModules(verbose)
CheckRegisteredExe("Python.exe")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "-q":
verbose = 0
else:
verbose = 1
CheckRegistry(verbose)

397
lib/win32/lib/regutil.py Normal file
View file

@ -0,0 +1,397 @@
# Some registry helpers.
import os
import sys
import win32api
import win32con
error = "Registry utility error"
# A .py file has a CLSID associated with it (why? - dunno!)
CLSIDPyFile = "{b51df050-06ae-11cf-ad3b-524153480001}"
RegistryIDPyFile = "Python.File" # The registry "file type" of a .py file
RegistryIDPycFile = "Python.CompiledFile" # The registry "file type" of a .pyc file
def BuildDefaultPythonKey():
"""Builds a string containing the path to the current registry key.
The Python registry key contains the Python version. This function
uses the version of the DLL used by the current process to get the
registry key currently in use.
"""
return "Software\\Python\\PythonCore\\" + sys.winver
def GetRootKey():
"""Retrieves the Registry root in use by Python."""
keyname = BuildDefaultPythonKey()
try:
k = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, keyname)
k.close()
return win32con.HKEY_CURRENT_USER
except win32api.error:
return win32con.HKEY_LOCAL_MACHINE
def GetRegistryDefaultValue(subkey, rootkey=None):
"""A helper to return the default value for a key in the registry."""
if rootkey is None:
rootkey = GetRootKey()
return win32api.RegQueryValue(rootkey, subkey)
def SetRegistryDefaultValue(subKey, value, rootkey=None):
"""A helper to set the default value for a key in the registry"""
if rootkey is None:
rootkey = GetRootKey()
if type(value) == str:
typeId = win32con.REG_SZ
elif type(value) == int:
typeId = win32con.REG_DWORD
else:
raise TypeError("Value must be string or integer - was passed " + repr(value))
win32api.RegSetValue(rootkey, subKey, typeId, value)
def GetAppPathsKey():
return "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths"
def RegisterPythonExe(exeFullPath, exeAlias=None, exeAppPath=None):
"""Register a .exe file that uses Python.
Registers the .exe with the OS. This allows the specified .exe to
be run from the command-line or start button without using the full path,
and also to setup application specific path (ie, os.environ['PATH']).
Currently the exeAppPath is not supported, so this function is general
purpose, and not specific to Python at all. Later, exeAppPath may provide
a reasonable default that is used.
exeFullPath -- The full path to the .exe
exeAlias = None -- An alias for the exe - if none, the base portion
of the filename is used.
exeAppPath -- Not supported.
"""
# Note - Dont work on win32s (but we dont care anymore!)
if exeAppPath:
raise error("Do not support exeAppPath argument currently")
if exeAlias is None:
exeAlias = os.path.basename(exeFullPath)
win32api.RegSetValue(
GetRootKey(), GetAppPathsKey() + "\\" + exeAlias, win32con.REG_SZ, exeFullPath
)
def GetRegisteredExe(exeAlias):
"""Get a registered .exe"""
return win32api.RegQueryValue(GetRootKey(), GetAppPathsKey() + "\\" + exeAlias)
def UnregisterPythonExe(exeAlias):
"""Unregister a .exe file that uses Python."""
try:
win32api.RegDeleteKey(GetRootKey(), GetAppPathsKey() + "\\" + exeAlias)
except win32api.error as exc:
import winerror
if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
raise
return
def RegisterNamedPath(name, path):
"""Register a named path - ie, a named PythonPath entry."""
keyStr = BuildDefaultPythonKey() + "\\PythonPath"
if name:
keyStr = keyStr + "\\" + name
win32api.RegSetValue(GetRootKey(), keyStr, win32con.REG_SZ, path)
def UnregisterNamedPath(name):
"""Unregister a named path - ie, a named PythonPath entry."""
keyStr = BuildDefaultPythonKey() + "\\PythonPath\\" + name
try:
win32api.RegDeleteKey(GetRootKey(), keyStr)
except win32api.error as exc:
import winerror
if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
raise
return
def GetRegisteredNamedPath(name):
"""Get a registered named path, or None if it doesnt exist."""
keyStr = BuildDefaultPythonKey() + "\\PythonPath"
if name:
keyStr = keyStr + "\\" + name
try:
return win32api.RegQueryValue(GetRootKey(), keyStr)
except win32api.error as exc:
import winerror
if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
raise
return None
def RegisterModule(modName, modPath):
"""Register an explicit module in the registry. This forces the Python import
mechanism to locate this module directly, without a sys.path search. Thus
a registered module need not appear in sys.path at all.
modName -- The name of the module, as used by import.
modPath -- The full path and file name of the module.
"""
try:
import os
os.stat(modPath)
except os.error:
print("Warning: Registering non-existant module %s" % modPath)
win32api.RegSetValue(
GetRootKey(),
BuildDefaultPythonKey() + "\\Modules\\%s" % modName,
win32con.REG_SZ,
modPath,
)
def UnregisterModule(modName):
"""Unregister an explicit module in the registry.
modName -- The name of the module, as used by import.
"""
try:
win32api.RegDeleteKey(
GetRootKey(), BuildDefaultPythonKey() + "\\Modules\\%s" % modName
)
except win32api.error as exc:
import winerror
if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
raise
def GetRegisteredHelpFile(helpDesc):
"""Given a description, return the registered entry."""
try:
return GetRegistryDefaultValue(BuildDefaultPythonKey() + "\\Help\\" + helpDesc)
except win32api.error:
try:
return GetRegistryDefaultValue(
BuildDefaultPythonKey() + "\\Help\\" + helpDesc,
win32con.HKEY_CURRENT_USER,
)
except win32api.error:
pass
return None
def RegisterHelpFile(helpFile, helpPath, helpDesc=None, bCheckFile=1):
"""Register a help file in the registry.
Note that this used to support writing to the Windows Help
key, however this is no longer done, as it seems to be incompatible.
helpFile -- the base name of the help file.
helpPath -- the path to the help file
helpDesc -- A description for the help file. If None, the helpFile param is used.
bCheckFile -- A flag indicating if the file existence should be checked.
"""
if helpDesc is None:
helpDesc = helpFile
fullHelpFile = os.path.join(helpPath, helpFile)
try:
if bCheckFile:
os.stat(fullHelpFile)
except os.error:
raise ValueError("Help file does not exist")
# Now register with Python itself.
win32api.RegSetValue(
GetRootKey(),
BuildDefaultPythonKey() + "\\Help\\%s" % helpDesc,
win32con.REG_SZ,
fullHelpFile,
)
def UnregisterHelpFile(helpFile, helpDesc=None):
"""Unregister a help file in the registry.
helpFile -- the base name of the help file.
helpDesc -- A description for the help file. If None, the helpFile param is used.
"""
key = win32api.RegOpenKey(
win32con.HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\Help",
0,
win32con.KEY_ALL_ACCESS,
)
try:
try:
win32api.RegDeleteValue(key, helpFile)
except win32api.error as exc:
import winerror
if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
raise
finally:
win32api.RegCloseKey(key)
# Now de-register with Python itself.
if helpDesc is None:
helpDesc = helpFile
try:
win32api.RegDeleteKey(
GetRootKey(), BuildDefaultPythonKey() + "\\Help\\%s" % helpDesc
)
except win32api.error as exc:
import winerror
if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
raise
def RegisterCoreDLL(coredllName=None):
"""Registers the core DLL in the registry.
If no params are passed, the name of the Python DLL used in
the current process is used and registered.
"""
if coredllName is None:
coredllName = win32api.GetModuleFileName(sys.dllhandle)
# must exist!
else:
try:
os.stat(coredllName)
except os.error:
print("Warning: Registering non-existant core DLL %s" % coredllName)
hKey = win32api.RegCreateKey(GetRootKey(), BuildDefaultPythonKey())
try:
win32api.RegSetValue(hKey, "Dll", win32con.REG_SZ, coredllName)
finally:
win32api.RegCloseKey(hKey)
# Lastly, setup the current version to point to me.
win32api.RegSetValue(
GetRootKey(),
"Software\\Python\\PythonCore\\CurrentVersion",
win32con.REG_SZ,
sys.winver,
)
def RegisterFileExtensions(defPyIcon, defPycIcon, runCommand):
"""Register the core Python file extensions.
defPyIcon -- The default icon to use for .py files, in 'fname,offset' format.
defPycIcon -- The default icon to use for .pyc files, in 'fname,offset' format.
runCommand -- The command line to use for running .py files
"""
# Register the file extensions.
pythonFileId = RegistryIDPyFile
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT, ".py", win32con.REG_SZ, pythonFileId
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT, pythonFileId, win32con.REG_SZ, "Python File"
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
"%s\\CLSID" % pythonFileId,
win32con.REG_SZ,
CLSIDPyFile,
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
"%s\\DefaultIcon" % pythonFileId,
win32con.REG_SZ,
defPyIcon,
)
base = "%s\\Shell" % RegistryIDPyFile
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT, base + "\\Open", win32con.REG_SZ, "Run"
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
base + "\\Open\\Command",
win32con.REG_SZ,
runCommand,
)
# Register the .PYC.
pythonFileId = RegistryIDPycFile
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT, ".pyc", win32con.REG_SZ, pythonFileId
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
pythonFileId,
win32con.REG_SZ,
"Compiled Python File",
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
"%s\\DefaultIcon" % pythonFileId,
win32con.REG_SZ,
defPycIcon,
)
base = "%s\\Shell" % pythonFileId
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT, base + "\\Open", win32con.REG_SZ, "Run"
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
base + "\\Open\\Command",
win32con.REG_SZ,
runCommand,
)
def RegisterShellCommand(shellCommand, exeCommand, shellUserCommand=None):
# Last param for "Open" - for a .py file to be executed by the command line
# or shell execute (eg, just entering "foo.py"), the Command must be "Open",
# but you may associate a different name for the right-click menu.
# In our case, normally we have "Open=Run"
base = "%s\\Shell" % RegistryIDPyFile
if shellUserCommand:
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
base + "\\%s" % (shellCommand),
win32con.REG_SZ,
shellUserCommand,
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
base + "\\%s\\Command" % (shellCommand),
win32con.REG_SZ,
exeCommand,
)
def RegisterDDECommand(shellCommand, ddeApp, ddeTopic, ddeCommand):
base = "%s\\Shell" % RegistryIDPyFile
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
base + "\\%s\\ddeexec" % (shellCommand),
win32con.REG_SZ,
ddeCommand,
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
base + "\\%s\\ddeexec\\Application" % (shellCommand),
win32con.REG_SZ,
ddeApp,
)
win32api.RegSetValue(
win32con.HKEY_CLASSES_ROOT,
base + "\\%s\\ddeexec\\Topic" % (shellCommand),
win32con.REG_SZ,
ddeTopic,
)

412
lib/win32/lib/sspi.py Normal file
View file

@ -0,0 +1,412 @@
"""
Helper classes for SSPI authentication via the win32security module.
SSPI authentication involves a token-exchange "dance", the exact details
of which depends on the authentication provider used. There are also
a number of complex flags and constants that need to be used - in most
cases, there are reasonable defaults.
These classes attempt to hide these details from you until you really need
to know. They are not designed to handle all cases, just the common ones.
If you need finer control than offered here, just use the win32security
functions directly.
"""
# Based on Roger Upole's sspi demos.
# $Id$
import sspicon
import win32security
error = win32security.error
class _BaseAuth(object):
def __init__(self):
self.reset()
def reset(self):
"""Reset everything to an unauthorized state"""
self.ctxt = None
self.authenticated = False
self.initiator_name = None
self.service_name = None
# The next seq_num for an encrypt/sign operation
self.next_seq_num = 0
def _get_next_seq_num(self):
"""Get the next sequence number for a transmission. Default
implementation is to increment a counter
"""
ret = self.next_seq_num
self.next_seq_num = self.next_seq_num + 1
return ret
def encrypt(self, data):
"""Encrypt a string, returning a tuple of (encrypted_data, trailer).
These can be passed to decrypt to get back the original string.
"""
pkg_size_info = self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES)
trailersize = pkg_size_info["SecurityTrailer"]
encbuf = win32security.PySecBufferDescType()
encbuf.append(win32security.PySecBufferType(len(data), sspicon.SECBUFFER_DATA))
encbuf.append(
win32security.PySecBufferType(trailersize, sspicon.SECBUFFER_TOKEN)
)
encbuf[0].Buffer = data
self.ctxt.EncryptMessage(0, encbuf, self._get_next_seq_num())
return encbuf[0].Buffer, encbuf[1].Buffer
def decrypt(self, data, trailer):
"""Decrypt a previously encrypted string, returning the orignal data"""
encbuf = win32security.PySecBufferDescType()
encbuf.append(win32security.PySecBufferType(len(data), sspicon.SECBUFFER_DATA))
encbuf.append(
win32security.PySecBufferType(len(trailer), sspicon.SECBUFFER_TOKEN)
)
encbuf[0].Buffer = data
encbuf[1].Buffer = trailer
self.ctxt.DecryptMessage(encbuf, self._get_next_seq_num())
return encbuf[0].Buffer
def sign(self, data):
"""sign a string suitable for transmission, returning the signature.
Passing the data and signature to verify will determine if the data
is unchanged.
"""
pkg_size_info = self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES)
sigsize = pkg_size_info["MaxSignature"]
sigbuf = win32security.PySecBufferDescType()
sigbuf.append(win32security.PySecBufferType(len(data), sspicon.SECBUFFER_DATA))
sigbuf.append(win32security.PySecBufferType(sigsize, sspicon.SECBUFFER_TOKEN))
sigbuf[0].Buffer = data
self.ctxt.MakeSignature(0, sigbuf, self._get_next_seq_num())
return sigbuf[1].Buffer
def verify(self, data, sig):
"""Verifies data and its signature. If verification fails, an sspi.error
will be raised.
"""
sigbuf = win32security.PySecBufferDescType()
sigbuf.append(win32security.PySecBufferType(len(data), sspicon.SECBUFFER_DATA))
sigbuf.append(win32security.PySecBufferType(len(sig), sspicon.SECBUFFER_TOKEN))
sigbuf[0].Buffer = data
sigbuf[1].Buffer = sig
self.ctxt.VerifySignature(sigbuf, self._get_next_seq_num())
def unwrap(self, token):
"""
GSSAPI's unwrap with SSPI.
https://docs.microsoft.com/en-us/windows/win32/secauthn/sspi-kerberos-interoperability-with-gssapi
Usable mainly with Kerberos SSPI package, but this is not enforced.
Return the clear text, and a boolean that is True if the token was encrypted.
"""
buffer = win32security.PySecBufferDescType()
# This buffer will contain a "stream", which is the token coming from the other side
buffer.append(
win32security.PySecBufferType(len(token), sspicon.SECBUFFER_STREAM)
)
buffer[0].Buffer = token
# This buffer will receive the clear, or just unwrapped text if no encryption was used.
# Will be resized by the lib.
buffer.append(win32security.PySecBufferType(0, sspicon.SECBUFFER_DATA))
pfQOP = self.ctxt.DecryptMessage(buffer, self._get_next_seq_num())
r = buffer[1].Buffer
return r, not (pfQOP == sspicon.SECQOP_WRAP_NO_ENCRYPT)
def wrap(self, msg, encrypt=False):
"""
GSSAPI's wrap with SSPI.
https://docs.microsoft.com/en-us/windows/win32/secauthn/sspi-kerberos-interoperability-with-gssapi
Usable mainly with Kerberos SSPI package, but this is not enforced.
Wrap a message to be sent to the other side. Encrypted if encrypt is True.
"""
size_info = self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES)
trailer_size = size_info["SecurityTrailer"]
block_size = size_info["BlockSize"]
buffer = win32security.PySecBufferDescType()
# This buffer will contain unencrypted data to wrap, and maybe encrypt.
buffer.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
buffer[0].Buffer = msg
# Will receive the token that forms the beginning of the msg
buffer.append(
win32security.PySecBufferType(trailer_size, sspicon.SECBUFFER_TOKEN)
)
# The trailer is needed in case of block encryption
buffer.append(
win32security.PySecBufferType(block_size, sspicon.SECBUFFER_PADDING)
)
fQOP = 0 if encrypt else sspicon.SECQOP_WRAP_NO_ENCRYPT
self.ctxt.EncryptMessage(fQOP, buffer, self._get_next_seq_num())
# Sec token, then data, then padding
r = buffer[1].Buffer + buffer[0].Buffer + buffer[2].Buffer
return r
def _amend_ctx_name(self):
"""Adds initiator and service names in the security context for ease of use"""
if not self.authenticated:
raise ValueError("Sec context is not completely authenticated")
try:
names = self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_NATIVE_NAMES)
except error:
# The SSP doesn't provide these attributes.
pass
else:
self.initiator_name, self.service_name = names
class ClientAuth(_BaseAuth):
"""Manages the client side of an SSPI authentication handshake"""
def __init__(
self,
pkg_name, # Name of the package to used.
client_name=None, # User for whom credentials are used.
auth_info=None, # or a tuple of (username, domain, password)
targetspn=None, # Target security context provider name.
scflags=None, # security context flags
datarep=sspicon.SECURITY_NETWORK_DREP,
):
if scflags is None:
scflags = (
sspicon.ISC_REQ_INTEGRITY
| sspicon.ISC_REQ_SEQUENCE_DETECT
| sspicon.ISC_REQ_REPLAY_DETECT
| sspicon.ISC_REQ_CONFIDENTIALITY
)
self.scflags = scflags
self.datarep = datarep
self.targetspn = targetspn
self.pkg_info = win32security.QuerySecurityPackageInfo(pkg_name)
(
self.credentials,
self.credentials_expiry,
) = win32security.AcquireCredentialsHandle(
client_name,
self.pkg_info["Name"],
sspicon.SECPKG_CRED_OUTBOUND,
None,
auth_info,
)
_BaseAuth.__init__(self)
def authorize(self, sec_buffer_in):
"""Perform *one* step of the client authentication process. Pass None for the first round"""
if (
sec_buffer_in is not None
and type(sec_buffer_in) != win32security.PySecBufferDescType
):
# User passed us the raw data - wrap it into a SecBufferDesc
sec_buffer_new = win32security.PySecBufferDescType()
tokenbuf = win32security.PySecBufferType(
self.pkg_info["MaxToken"], sspicon.SECBUFFER_TOKEN
)
tokenbuf.Buffer = sec_buffer_in
sec_buffer_new.append(tokenbuf)
sec_buffer_in = sec_buffer_new
sec_buffer_out = win32security.PySecBufferDescType()
tokenbuf = win32security.PySecBufferType(
self.pkg_info["MaxToken"], sspicon.SECBUFFER_TOKEN
)
sec_buffer_out.append(tokenbuf)
## input context handle should be NULL on first call
ctxtin = self.ctxt
if self.ctxt is None:
self.ctxt = win32security.PyCtxtHandleType()
err, attr, exp = win32security.InitializeSecurityContext(
self.credentials,
ctxtin,
self.targetspn,
self.scflags,
self.datarep,
sec_buffer_in,
self.ctxt,
sec_buffer_out,
)
# Stash these away incase someone needs to know the state from the
# final call.
self.ctxt_attr = attr
self.ctxt_expiry = exp
if err in (sspicon.SEC_I_COMPLETE_NEEDED, sspicon.SEC_I_COMPLETE_AND_CONTINUE):
self.ctxt.CompleteAuthToken(sec_buffer_out)
self.authenticated = err == 0
if self.authenticated:
self._amend_ctx_name()
return err, sec_buffer_out
class ServerAuth(_BaseAuth):
"""Manages the server side of an SSPI authentication handshake"""
def __init__(
self, pkg_name, spn=None, scflags=None, datarep=sspicon.SECURITY_NETWORK_DREP
):
self.spn = spn
self.datarep = datarep
if scflags is None:
scflags = (
sspicon.ASC_REQ_INTEGRITY
| sspicon.ASC_REQ_SEQUENCE_DETECT
| sspicon.ASC_REQ_REPLAY_DETECT
| sspicon.ASC_REQ_CONFIDENTIALITY
)
# Should we default to sspicon.KerbAddExtraCredentialsMessage
# if pkg_name=='Kerberos'?
self.scflags = scflags
self.pkg_info = win32security.QuerySecurityPackageInfo(pkg_name)
(
self.credentials,
self.credentials_expiry,
) = win32security.AcquireCredentialsHandle(
spn, self.pkg_info["Name"], sspicon.SECPKG_CRED_INBOUND, None, None
)
_BaseAuth.__init__(self)
def authorize(self, sec_buffer_in):
"""Perform *one* step of the server authentication process."""
if (
sec_buffer_in is not None
and type(sec_buffer_in) != win32security.PySecBufferDescType
):
# User passed us the raw data - wrap it into a SecBufferDesc
sec_buffer_new = win32security.PySecBufferDescType()
tokenbuf = win32security.PySecBufferType(
self.pkg_info["MaxToken"], sspicon.SECBUFFER_TOKEN
)
tokenbuf.Buffer = sec_buffer_in
sec_buffer_new.append(tokenbuf)
sec_buffer_in = sec_buffer_new
sec_buffer_out = win32security.PySecBufferDescType()
tokenbuf = win32security.PySecBufferType(
self.pkg_info["MaxToken"], sspicon.SECBUFFER_TOKEN
)
sec_buffer_out.append(tokenbuf)
## input context handle is None initially, then handle returned from last call thereafter
ctxtin = self.ctxt
if self.ctxt is None:
self.ctxt = win32security.PyCtxtHandleType()
err, attr, exp = win32security.AcceptSecurityContext(
self.credentials,
ctxtin,
sec_buffer_in,
self.scflags,
self.datarep,
self.ctxt,
sec_buffer_out,
)
# Stash these away incase someone needs to know the state from the
# final call.
self.ctxt_attr = attr
self.ctxt_expiry = exp
if err in (sspicon.SEC_I_COMPLETE_NEEDED, sspicon.SEC_I_COMPLETE_AND_CONTINUE):
self.ctxt.CompleteAuthToken(sec_buffer_out)
self.authenticated = err == 0
if self.authenticated:
self._amend_ctx_name()
return err, sec_buffer_out
if __name__ == "__main__":
# This is the security package (the security support provider / the security backend)
# we want to use for this example.
ssp = "Kerberos" # or "NTLM" or "Negotiate" which enable negotiation between
# Kerberos (prefered) and NTLM (if not supported on the other side).
flags = (
sspicon.ISC_REQ_MUTUAL_AUTH
| sspicon.ISC_REQ_INTEGRITY # mutual authentication
| sspicon.ISC_REQ_SEQUENCE_DETECT # check for integrity
| sspicon.ISC_REQ_CONFIDENTIALITY # enable out-of-order messages
| sspicon.ISC_REQ_REPLAY_DETECT # request confidentiality # request replay detection
)
# Get our identity, mandatory for the Kerberos case *for this example*
# Kerberos cannot be used if we don't tell it the target we want
# to authenticate to.
cred_handle, exp = win32security.AcquireCredentialsHandle(
None, ssp, sspicon.SECPKG_CRED_INBOUND, None, None
)
cred = cred_handle.QueryCredentialsAttributes(sspicon.SECPKG_CRED_ATTR_NAMES)
print("We are:", cred)
# Setup the 2 contexts. In real life, only one is needed: the other one is
# created in the process we want to communicate with.
sspiclient = ClientAuth(ssp, scflags=flags, targetspn=cred)
sspiserver = ServerAuth(ssp, scflags=flags)
print(
"SSP : %s (%s)" % (sspiclient.pkg_info["Name"], sspiclient.pkg_info["Comment"])
)
# Perform the authentication dance, each loop exchanging more information
# on the way to completing authentication.
sec_buffer = None
client_step = 0
server_step = 0
while not (sspiclient.authenticated) or len(sec_buffer[0].Buffer):
client_step += 1
err, sec_buffer = sspiclient.authorize(sec_buffer)
print("Client step %s" % client_step)
if sspiserver.authenticated and len(sec_buffer[0].Buffer) == 0:
break
server_step += 1
err, sec_buffer = sspiserver.authorize(sec_buffer)
print("Server step %s" % server_step)
# Authentication process is finished.
print("Initiator name from the service side:", sspiserver.initiator_name)
print("Service name from the client side: ", sspiclient.service_name)
data = "hello".encode("ascii") # py3k-friendly
# Simple signature, not compatible with GSSAPI.
sig = sspiclient.sign(data)
sspiserver.verify(data, sig)
# Encryption
encrypted, sig = sspiclient.encrypt(data)
decrypted = sspiserver.decrypt(encrypted, sig)
assert decrypted == data
# GSSAPI wrapping, no encryption (NTLM always encrypts)
wrapped = sspiclient.wrap(data)
unwrapped, was_encrypted = sspiserver.unwrap(wrapped)
print("encrypted ?", was_encrypted)
assert data == unwrapped
# GSSAPI wrapping, with encryption
wrapped = sspiserver.wrap(data, encrypt=True)
unwrapped, was_encrypted = sspiclient.unwrap(wrapped)
print("encrypted ?", was_encrypted)
assert data == unwrapped
print("cool!")

477
lib/win32/lib/sspicon.py Normal file
View file

@ -0,0 +1,477 @@
# Generated by h2py from c:\microsoft sdk\include\sspi.h
ISSP_LEVEL = 32
ISSP_MODE = 1
def SEC_SUCCESS(Status):
return (Status) >= 0
SECPKG_FLAG_INTEGRITY = 1
SECPKG_FLAG_PRIVACY = 2
SECPKG_FLAG_TOKEN_ONLY = 4
SECPKG_FLAG_DATAGRAM = 8
SECPKG_FLAG_CONNECTION = 16
SECPKG_FLAG_MULTI_REQUIRED = 32
SECPKG_FLAG_CLIENT_ONLY = 64
SECPKG_FLAG_EXTENDED_ERROR = 128
SECPKG_FLAG_IMPERSONATION = 256
SECPKG_FLAG_ACCEPT_WIN32_NAME = 512
SECPKG_FLAG_STREAM = 1024
SECPKG_FLAG_NEGOTIABLE = 2048
SECPKG_FLAG_GSS_COMPATIBLE = 4096
SECPKG_FLAG_LOGON = 8192
SECPKG_FLAG_ASCII_BUFFERS = 16384
SECPKG_FLAG_FRAGMENT = 32768
SECPKG_FLAG_MUTUAL_AUTH = 65536
SECPKG_FLAG_DELEGATION = 131072
SECPKG_FLAG_READONLY_WITH_CHECKSUM = 262144
SECPKG_ID_NONE = 65535
SECBUFFER_VERSION = 0
SECBUFFER_EMPTY = 0
SECBUFFER_DATA = 1
SECBUFFER_TOKEN = 2
SECBUFFER_PKG_PARAMS = 3
SECBUFFER_MISSING = 4
SECBUFFER_EXTRA = 5
SECBUFFER_STREAM_TRAILER = 6
SECBUFFER_STREAM_HEADER = 7
SECBUFFER_NEGOTIATION_INFO = 8
SECBUFFER_PADDING = 9
SECBUFFER_STREAM = 10
SECBUFFER_MECHLIST = 11
SECBUFFER_MECHLIST_SIGNATURE = 12
SECBUFFER_TARGET = 13
SECBUFFER_CHANNEL_BINDINGS = 14
SECBUFFER_ATTRMASK = -268435456
SECBUFFER_READONLY = -2147483648
SECBUFFER_READONLY_WITH_CHECKSUM = 268435456
SECBUFFER_RESERVED = 1610612736
SECURITY_NATIVE_DREP = 16
SECURITY_NETWORK_DREP = 0
SECPKG_CRED_INBOUND = 1
SECPKG_CRED_OUTBOUND = 2
SECPKG_CRED_BOTH = 3
SECPKG_CRED_DEFAULT = 4
SECPKG_CRED_RESERVED = -268435456
ISC_REQ_DELEGATE = 1
ISC_REQ_MUTUAL_AUTH = 2
ISC_REQ_REPLAY_DETECT = 4
ISC_REQ_SEQUENCE_DETECT = 8
ISC_REQ_CONFIDENTIALITY = 16
ISC_REQ_USE_SESSION_KEY = 32
ISC_REQ_PROMPT_FOR_CREDS = 64
ISC_REQ_USE_SUPPLIED_CREDS = 128
ISC_REQ_ALLOCATE_MEMORY = 256
ISC_REQ_USE_DCE_STYLE = 512
ISC_REQ_DATAGRAM = 1024
ISC_REQ_CONNECTION = 2048
ISC_REQ_CALL_LEVEL = 4096
ISC_REQ_FRAGMENT_SUPPLIED = 8192
ISC_REQ_EXTENDED_ERROR = 16384
ISC_REQ_STREAM = 32768
ISC_REQ_INTEGRITY = 65536
ISC_REQ_IDENTIFY = 131072
ISC_REQ_NULL_SESSION = 262144
ISC_REQ_MANUAL_CRED_VALIDATION = 524288
ISC_REQ_RESERVED1 = 1048576
ISC_REQ_FRAGMENT_TO_FIT = 2097152
ISC_REQ_HTTP = 0x10000000
ISC_RET_DELEGATE = 1
ISC_RET_MUTUAL_AUTH = 2
ISC_RET_REPLAY_DETECT = 4
ISC_RET_SEQUENCE_DETECT = 8
ISC_RET_CONFIDENTIALITY = 16
ISC_RET_USE_SESSION_KEY = 32
ISC_RET_USED_COLLECTED_CREDS = 64
ISC_RET_USED_SUPPLIED_CREDS = 128
ISC_RET_ALLOCATED_MEMORY = 256
ISC_RET_USED_DCE_STYLE = 512
ISC_RET_DATAGRAM = 1024
ISC_RET_CONNECTION = 2048
ISC_RET_INTERMEDIATE_RETURN = 4096
ISC_RET_CALL_LEVEL = 8192
ISC_RET_EXTENDED_ERROR = 16384
ISC_RET_STREAM = 32768
ISC_RET_INTEGRITY = 65536
ISC_RET_IDENTIFY = 131072
ISC_RET_NULL_SESSION = 262144
ISC_RET_MANUAL_CRED_VALIDATION = 524288
ISC_RET_RESERVED1 = 1048576
ISC_RET_FRAGMENT_ONLY = 2097152
ASC_REQ_DELEGATE = 1
ASC_REQ_MUTUAL_AUTH = 2
ASC_REQ_REPLAY_DETECT = 4
ASC_REQ_SEQUENCE_DETECT = 8
ASC_REQ_CONFIDENTIALITY = 16
ASC_REQ_USE_SESSION_KEY = 32
ASC_REQ_ALLOCATE_MEMORY = 256
ASC_REQ_USE_DCE_STYLE = 512
ASC_REQ_DATAGRAM = 1024
ASC_REQ_CONNECTION = 2048
ASC_REQ_CALL_LEVEL = 4096
ASC_REQ_EXTENDED_ERROR = 32768
ASC_REQ_STREAM = 65536
ASC_REQ_INTEGRITY = 131072
ASC_REQ_LICENSING = 262144
ASC_REQ_IDENTIFY = 524288
ASC_REQ_ALLOW_NULL_SESSION = 1048576
ASC_REQ_ALLOW_NON_USER_LOGONS = 2097152
ASC_REQ_ALLOW_CONTEXT_REPLAY = 4194304
ASC_REQ_FRAGMENT_TO_FIT = 8388608
ASC_REQ_FRAGMENT_SUPPLIED = 8192
ASC_REQ_NO_TOKEN = 16777216
ASC_RET_DELEGATE = 1
ASC_RET_MUTUAL_AUTH = 2
ASC_RET_REPLAY_DETECT = 4
ASC_RET_SEQUENCE_DETECT = 8
ASC_RET_CONFIDENTIALITY = 16
ASC_RET_USE_SESSION_KEY = 32
ASC_RET_ALLOCATED_MEMORY = 256
ASC_RET_USED_DCE_STYLE = 512
ASC_RET_DATAGRAM = 1024
ASC_RET_CONNECTION = 2048
ASC_RET_CALL_LEVEL = 8192
ASC_RET_THIRD_LEG_FAILED = 16384
ASC_RET_EXTENDED_ERROR = 32768
ASC_RET_STREAM = 65536
ASC_RET_INTEGRITY = 131072
ASC_RET_LICENSING = 262144
ASC_RET_IDENTIFY = 524288
ASC_RET_NULL_SESSION = 1048576
ASC_RET_ALLOW_NON_USER_LOGONS = 2097152
ASC_RET_ALLOW_CONTEXT_REPLAY = 4194304
ASC_RET_FRAGMENT_ONLY = 8388608
SECPKG_CRED_ATTR_NAMES = 1
SECPKG_ATTR_SIZES = 0
SECPKG_ATTR_NAMES = 1
SECPKG_ATTR_LIFESPAN = 2
SECPKG_ATTR_DCE_INFO = 3
SECPKG_ATTR_STREAM_SIZES = 4
SECPKG_ATTR_KEY_INFO = 5
SECPKG_ATTR_AUTHORITY = 6
SECPKG_ATTR_PROTO_INFO = 7
SECPKG_ATTR_PASSWORD_EXPIRY = 8
SECPKG_ATTR_SESSION_KEY = 9
SECPKG_ATTR_PACKAGE_INFO = 10
SECPKG_ATTR_USER_FLAGS = 11
SECPKG_ATTR_NEGOTIATION_INFO = 12
SECPKG_ATTR_NATIVE_NAMES = 13
SECPKG_ATTR_FLAGS = 14
SECPKG_ATTR_USE_VALIDATED = 15
SECPKG_ATTR_CREDENTIAL_NAME = 16
SECPKG_ATTR_TARGET_INFORMATION = 17
SECPKG_ATTR_ACCESS_TOKEN = 18
SECPKG_ATTR_TARGET = 19
SECPKG_ATTR_AUTHENTICATION_ID = 20
## attributes from schannel.h
SECPKG_ATTR_REMOTE_CERT_CONTEXT = 83
SECPKG_ATTR_LOCAL_CERT_CONTEXT = 84
SECPKG_ATTR_ROOT_STORE = 85
SECPKG_ATTR_SUPPORTED_ALGS = 86
SECPKG_ATTR_CIPHER_STRENGTHS = 87
SECPKG_ATTR_SUPPORTED_PROTOCOLS = 88
SECPKG_ATTR_ISSUER_LIST_EX = 89
SECPKG_ATTR_CONNECTION_INFO = 90
SECPKG_ATTR_EAP_KEY_BLOCK = 91
SECPKG_ATTR_MAPPED_CRED_ATTR = 92
SECPKG_ATTR_SESSION_INFO = 93
SECPKG_ATTR_APP_DATA = 94
SECPKG_NEGOTIATION_COMPLETE = 0
SECPKG_NEGOTIATION_OPTIMISTIC = 1
SECPKG_NEGOTIATION_IN_PROGRESS = 2
SECPKG_NEGOTIATION_DIRECT = 3
SECPKG_NEGOTIATION_TRY_MULTICRED = 4
SECPKG_CONTEXT_EXPORT_RESET_NEW = 1
SECPKG_CONTEXT_EXPORT_DELETE_OLD = 2
SECQOP_WRAP_NO_ENCRYPT = -2147483647
SECURITY_ENTRYPOINT_ANSIW = "InitSecurityInterfaceW"
SECURITY_ENTRYPOINT_ANSIA = "InitSecurityInterfaceA"
SECURITY_ENTRYPOINT16 = "INITSECURITYINTERFACEA"
SECURITY_ENTRYPOINT = SECURITY_ENTRYPOINT16
SECURITY_ENTRYPOINT_ANSI = SECURITY_ENTRYPOINT16
SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION = 1
SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_2 = 2
SASL_OPTION_SEND_SIZE = 1
SASL_OPTION_RECV_SIZE = 2
SASL_OPTION_AUTHZ_STRING = 3
SASL_OPTION_AUTHZ_PROCESSING = 4
SEC_WINNT_AUTH_IDENTITY_ANSI = 1
SEC_WINNT_AUTH_IDENTITY_UNICODE = 2
SEC_WINNT_AUTH_IDENTITY_VERSION = 512
SEC_WINNT_AUTH_IDENTITY_MARSHALLED = 4
SEC_WINNT_AUTH_IDENTITY_ONLY = 8
SECPKG_OPTIONS_TYPE_UNKNOWN = 0
SECPKG_OPTIONS_TYPE_LSA = 1
SECPKG_OPTIONS_TYPE_SSPI = 2
SECPKG_OPTIONS_PERMANENT = 1
SEC_E_INSUFFICIENT_MEMORY = -2146893056
SEC_E_INVALID_HANDLE = -2146893055
SEC_E_UNSUPPORTED_FUNCTION = -2146893054
SEC_E_TARGET_UNKNOWN = -2146893053
SEC_E_INTERNAL_ERROR = -2146893052
SEC_E_SECPKG_NOT_FOUND = -2146893051
SEC_E_NOT_OWNER = -2146893050
SEC_E_CANNOT_INSTALL = -2146893049
SEC_E_INVALID_TOKEN = -2146893048
SEC_E_CANNOT_PACK = -2146893047
SEC_E_QOP_NOT_SUPPORTED = -2146893046
SEC_E_NO_IMPERSONATION = -2146893045
SEC_E_LOGON_DENIED = -2146893044
SEC_E_UNKNOWN_CREDENTIALS = -2146893043
SEC_E_NO_CREDENTIALS = -2146893042
SEC_E_MESSAGE_ALTERED = -2146893041
SEC_E_OUT_OF_SEQUENCE = -2146893040
SEC_E_NO_AUTHENTICATING_AUTHORITY = -2146893039
SEC_I_CONTINUE_NEEDED = 590610
SEC_I_COMPLETE_NEEDED = 590611
SEC_I_COMPLETE_AND_CONTINUE = 590612
SEC_I_LOCAL_LOGON = 590613
SEC_E_BAD_PKGID = -2146893034
SEC_E_CONTEXT_EXPIRED = -2146893033
SEC_I_CONTEXT_EXPIRED = 590615
SEC_E_INCOMPLETE_MESSAGE = -2146893032
SEC_E_INCOMPLETE_CREDENTIALS = -2146893024
SEC_E_BUFFER_TOO_SMALL = -2146893023
SEC_I_INCOMPLETE_CREDENTIALS = 590624
SEC_I_RENEGOTIATE = 590625
SEC_E_WRONG_PRINCIPAL = -2146893022
SEC_I_NO_LSA_CONTEXT = 590627
SEC_E_TIME_SKEW = -2146893020
SEC_E_UNTRUSTED_ROOT = -2146893019
SEC_E_ILLEGAL_MESSAGE = -2146893018
SEC_E_CERT_UNKNOWN = -2146893017
SEC_E_CERT_EXPIRED = -2146893016
SEC_E_ENCRYPT_FAILURE = -2146893015
SEC_E_DECRYPT_FAILURE = -2146893008
SEC_E_ALGORITHM_MISMATCH = -2146893007
SEC_E_SECURITY_QOS_FAILED = -2146893006
SEC_E_UNFINISHED_CONTEXT_DELETED = -2146893005
SEC_E_NO_TGT_REPLY = -2146893004
SEC_E_NO_IP_ADDRESSES = -2146893003
SEC_E_WRONG_CREDENTIAL_HANDLE = -2146893002
SEC_E_CRYPTO_SYSTEM_INVALID = -2146893001
SEC_E_MAX_REFERRALS_EXCEEDED = -2146893000
SEC_E_MUST_BE_KDC = -2146892999
SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = -2146892998
SEC_E_TOO_MANY_PRINCIPALS = -2146892997
SEC_E_NO_PA_DATA = -2146892996
SEC_E_PKINIT_NAME_MISMATCH = -2146892995
SEC_E_SMARTCARD_LOGON_REQUIRED = -2146892994
SEC_E_SHUTDOWN_IN_PROGRESS = -2146892993
SEC_E_KDC_INVALID_REQUEST = -2146892992
SEC_E_KDC_UNABLE_TO_REFER = -2146892991
SEC_E_KDC_UNKNOWN_ETYPE = -2146892990
SEC_E_UNSUPPORTED_PREAUTH = -2146892989
SEC_E_DELEGATION_REQUIRED = -2146892987
SEC_E_BAD_BINDINGS = -2146892986
SEC_E_MULTIPLE_ACCOUNTS = -2146892985
SEC_E_NO_KERB_KEY = -2146892984
ERROR_IPSEC_QM_POLICY_EXISTS = 13000
ERROR_IPSEC_QM_POLICY_NOT_FOUND = 13001
ERROR_IPSEC_QM_POLICY_IN_USE = 13002
ERROR_IPSEC_MM_POLICY_EXISTS = 13003
ERROR_IPSEC_MM_POLICY_NOT_FOUND = 13004
ERROR_IPSEC_MM_POLICY_IN_USE = 13005
ERROR_IPSEC_MM_FILTER_EXISTS = 13006
ERROR_IPSEC_MM_FILTER_NOT_FOUND = 13007
ERROR_IPSEC_TRANSPORT_FILTER_EXISTS = 13008
ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND = 13009
ERROR_IPSEC_MM_AUTH_EXISTS = 13010
ERROR_IPSEC_MM_AUTH_NOT_FOUND = 13011
ERROR_IPSEC_MM_AUTH_IN_USE = 13012
ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND = 13013
ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND = 13014
ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND = 13015
ERROR_IPSEC_TUNNEL_FILTER_EXISTS = 13016
ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND = 13017
ERROR_IPSEC_MM_FILTER_PENDING_DELETION = 13018
ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION = 13019
ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION = 13020
ERROR_IPSEC_MM_POLICY_PENDING_DELETION = 13021
ERROR_IPSEC_MM_AUTH_PENDING_DELETION = 13022
ERROR_IPSEC_QM_POLICY_PENDING_DELETION = 13023
WARNING_IPSEC_MM_POLICY_PRUNED = 13024
WARNING_IPSEC_QM_POLICY_PRUNED = 13025
ERROR_IPSEC_IKE_NEG_STATUS_BEGIN = 13800
ERROR_IPSEC_IKE_AUTH_FAIL = 13801
ERROR_IPSEC_IKE_ATTRIB_FAIL = 13802
ERROR_IPSEC_IKE_NEGOTIATION_PENDING = 13803
ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR = 13804
ERROR_IPSEC_IKE_TIMED_OUT = 13805
ERROR_IPSEC_IKE_NO_CERT = 13806
ERROR_IPSEC_IKE_SA_DELETED = 13807
ERROR_IPSEC_IKE_SA_REAPED = 13808
ERROR_IPSEC_IKE_MM_ACQUIRE_DROP = 13809
ERROR_IPSEC_IKE_QM_ACQUIRE_DROP = 13810
ERROR_IPSEC_IKE_QUEUE_DROP_MM = 13811
ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM = 13812
ERROR_IPSEC_IKE_DROP_NO_RESPONSE = 13813
ERROR_IPSEC_IKE_MM_DELAY_DROP = 13814
ERROR_IPSEC_IKE_QM_DELAY_DROP = 13815
ERROR_IPSEC_IKE_ERROR = 13816
ERROR_IPSEC_IKE_CRL_FAILED = 13817
ERROR_IPSEC_IKE_INVALID_KEY_USAGE = 13818
ERROR_IPSEC_IKE_INVALID_CERT_TYPE = 13819
ERROR_IPSEC_IKE_NO_PRIVATE_KEY = 13820
ERROR_IPSEC_IKE_DH_FAIL = 13822
ERROR_IPSEC_IKE_INVALID_HEADER = 13824
ERROR_IPSEC_IKE_NO_POLICY = 13825
ERROR_IPSEC_IKE_INVALID_SIGNATURE = 13826
ERROR_IPSEC_IKE_KERBEROS_ERROR = 13827
ERROR_IPSEC_IKE_NO_PUBLIC_KEY = 13828
ERROR_IPSEC_IKE_PROCESS_ERR = 13829
ERROR_IPSEC_IKE_PROCESS_ERR_SA = 13830
ERROR_IPSEC_IKE_PROCESS_ERR_PROP = 13831
ERROR_IPSEC_IKE_PROCESS_ERR_TRANS = 13832
ERROR_IPSEC_IKE_PROCESS_ERR_KE = 13833
ERROR_IPSEC_IKE_PROCESS_ERR_ID = 13834
ERROR_IPSEC_IKE_PROCESS_ERR_CERT = 13835
ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ = 13836
ERROR_IPSEC_IKE_PROCESS_ERR_HASH = 13837
ERROR_IPSEC_IKE_PROCESS_ERR_SIG = 13838
ERROR_IPSEC_IKE_PROCESS_ERR_NONCE = 13839
ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY = 13840
ERROR_IPSEC_IKE_PROCESS_ERR_DELETE = 13841
ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR = 13842
ERROR_IPSEC_IKE_INVALID_PAYLOAD = 13843
ERROR_IPSEC_IKE_LOAD_SOFT_SA = 13844
ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN = 13845
ERROR_IPSEC_IKE_INVALID_COOKIE = 13846
ERROR_IPSEC_IKE_NO_PEER_CERT = 13847
ERROR_IPSEC_IKE_PEER_CRL_FAILED = 13848
ERROR_IPSEC_IKE_POLICY_CHANGE = 13849
ERROR_IPSEC_IKE_NO_MM_POLICY = 13850
ERROR_IPSEC_IKE_NOTCBPRIV = 13851
ERROR_IPSEC_IKE_SECLOADFAIL = 13852
ERROR_IPSEC_IKE_FAILSSPINIT = 13853
ERROR_IPSEC_IKE_FAILQUERYSSP = 13854
ERROR_IPSEC_IKE_SRVACQFAIL = 13855
ERROR_IPSEC_IKE_SRVQUERYCRED = 13856
ERROR_IPSEC_IKE_GETSPIFAIL = 13857
ERROR_IPSEC_IKE_INVALID_FILTER = 13858
ERROR_IPSEC_IKE_OUT_OF_MEMORY = 13859
ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED = 13860
ERROR_IPSEC_IKE_INVALID_POLICY = 13861
ERROR_IPSEC_IKE_UNKNOWN_DOI = 13862
ERROR_IPSEC_IKE_INVALID_SITUATION = 13863
ERROR_IPSEC_IKE_DH_FAILURE = 13864
ERROR_IPSEC_IKE_INVALID_GROUP = 13865
ERROR_IPSEC_IKE_ENCRYPT = 13866
ERROR_IPSEC_IKE_DECRYPT = 13867
ERROR_IPSEC_IKE_POLICY_MATCH = 13868
ERROR_IPSEC_IKE_UNSUPPORTED_ID = 13869
ERROR_IPSEC_IKE_INVALID_HASH = 13870
ERROR_IPSEC_IKE_INVALID_HASH_ALG = 13871
ERROR_IPSEC_IKE_INVALID_HASH_SIZE = 13872
ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG = 13873
ERROR_IPSEC_IKE_INVALID_AUTH_ALG = 13874
ERROR_IPSEC_IKE_INVALID_SIG = 13875
ERROR_IPSEC_IKE_LOAD_FAILED = 13876
ERROR_IPSEC_IKE_RPC_DELETE = 13877
ERROR_IPSEC_IKE_BENIGN_REINIT = 13878
ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY = 13879
ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN = 13881
ERROR_IPSEC_IKE_MM_LIMIT = 13882
ERROR_IPSEC_IKE_NEGOTIATION_DISABLED = 13883
ERROR_IPSEC_IKE_NEG_STATUS_END = 13884
CRYPT_E_MSG_ERROR = -2146889727
CRYPT_E_UNKNOWN_ALGO = -2146889726
CRYPT_E_OID_FORMAT = -2146889725
CRYPT_E_INVALID_MSG_TYPE = -2146889724
CRYPT_E_UNEXPECTED_ENCODING = -2146889723
CRYPT_E_AUTH_ATTR_MISSING = -2146889722
CRYPT_E_HASH_VALUE = -2146889721
CRYPT_E_INVALID_INDEX = -2146889720
CRYPT_E_ALREADY_DECRYPTED = -2146889719
CRYPT_E_NOT_DECRYPTED = -2146889718
CRYPT_E_RECIPIENT_NOT_FOUND = -2146889717
CRYPT_E_CONTROL_TYPE = -2146889716
CRYPT_E_ISSUER_SERIALNUMBER = -2146889715
CRYPT_E_SIGNER_NOT_FOUND = -2146889714
CRYPT_E_ATTRIBUTES_MISSING = -2146889713
CRYPT_E_STREAM_MSG_NOT_READY = -2146889712
CRYPT_E_STREAM_INSUFFICIENT_DATA = -2146889711
CRYPT_I_NEW_PROTECTION_REQUIRED = 593938
CRYPT_E_BAD_LEN = -2146885631
CRYPT_E_BAD_ENCODE = -2146885630
CRYPT_E_FILE_ERROR = -2146885629
CRYPT_E_NOT_FOUND = -2146885628
CRYPT_E_EXISTS = -2146885627
CRYPT_E_NO_PROVIDER = -2146885626
CRYPT_E_SELF_SIGNED = -2146885625
CRYPT_E_DELETED_PREV = -2146885624
CRYPT_E_NO_MATCH = -2146885623
CRYPT_E_UNEXPECTED_MSG_TYPE = -2146885622
CRYPT_E_NO_KEY_PROPERTY = -2146885621
CRYPT_E_NO_DECRYPT_CERT = -2146885620
CRYPT_E_BAD_MSG = -2146885619
CRYPT_E_NO_SIGNER = -2146885618
CRYPT_E_PENDING_CLOSE = -2146885617
CRYPT_E_REVOKED = -2146885616
CRYPT_E_NO_REVOCATION_DLL = -2146885615
CRYPT_E_NO_REVOCATION_CHECK = -2146885614
CRYPT_E_REVOCATION_OFFLINE = -2146885613
CRYPT_E_NOT_IN_REVOCATION_DATABASE = -2146885612
CRYPT_E_INVALID_NUMERIC_STRING = -2146885600
CRYPT_E_INVALID_PRINTABLE_STRING = -2146885599
CRYPT_E_INVALID_IA5_STRING = -2146885598
CRYPT_E_INVALID_X500_STRING = -2146885597
CRYPT_E_NOT_CHAR_STRING = -2146885596
CRYPT_E_FILERESIZED = -2146885595
CRYPT_E_SECURITY_SETTINGS = -2146885594
CRYPT_E_NO_VERIFY_USAGE_DLL = -2146885593
CRYPT_E_NO_VERIFY_USAGE_CHECK = -2146885592
CRYPT_E_VERIFY_USAGE_OFFLINE = -2146885591
CRYPT_E_NOT_IN_CTL = -2146885590
CRYPT_E_NO_TRUSTED_SIGNER = -2146885589
CRYPT_E_MISSING_PUBKEY_PARA = -2146885588
CRYPT_E_OSS_ERROR = -2146881536
## Kerberos message types for LsaCallAuthenticationPackage (from ntsecapi.h)
KerbDebugRequestMessage = 0
KerbQueryTicketCacheMessage = 1
KerbChangeMachinePasswordMessage = 2
KerbVerifyPacMessage = 3
KerbRetrieveTicketMessage = 4
KerbUpdateAddressesMessage = 5
KerbPurgeTicketCacheMessage = 6
KerbChangePasswordMessage = 7
KerbRetrieveEncodedTicketMessage = 8
KerbDecryptDataMessage = 9
KerbAddBindingCacheEntryMessage = 10
KerbSetPasswordMessage = 11
KerbSetPasswordExMessage = 12
KerbVerifyCredentialsMessage = 13
KerbQueryTicketCacheExMessage = 14
KerbPurgeTicketCacheExMessage = 15
KerbRefreshSmartcardCredentialsMessage = 16
KerbAddExtraCredentialsMessage = 17
KerbQuerySupplementalCredentialsMessage = 18
## messages used with msv1_0 from ntsecapi.h
MsV1_0Lm20ChallengeRequest = 0
MsV1_0Lm20GetChallengeResponse = 1
MsV1_0EnumerateUsers = 2
MsV1_0GetUserInfo = 3
MsV1_0ReLogonUsers = 4
MsV1_0ChangePassword = 5
MsV1_0ChangeCachedPassword = 6
MsV1_0GenericPassthrough = 7
MsV1_0CacheLogon = 8
MsV1_0SubAuth = 9
MsV1_0DeriveCredential = 10
MsV1_0CacheLookup = 11
MsV1_0SetProcessOption = 12
SEC_E_OK = 0

View file

@ -0,0 +1,7 @@
# win2kras used to be an extension module with wrapped the "new" RAS functions
# in Windows 2000, so win32ras could still be used on NT/etc.
# I think in 2021 we can be confident pywin32 is not used on earlier OSs, so
# that functionality is now in win32ras.
#
# This exists just to avoid breaking old scripts.
from win32ras import *

5083
lib/win32/lib/win32con.py Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,229 @@
"""Event Log Utilities - helper for win32evtlog.pyd
"""
import win32api
import win32con
import win32evtlog
import winerror
error = win32api.error # The error the evtlog module raises.
langid = win32api.MAKELANGID(win32con.LANG_NEUTRAL, win32con.SUBLANG_NEUTRAL)
def AddSourceToRegistry(
appName,
msgDLL=None,
eventLogType="Application",
eventLogFlags=None,
categoryDLL=None,
categoryCount=0,
):
"""Add a source of messages to the event log.
Allows Python program to register a custom source of messages in the
registry. You must also provide the DLL name that has the message table, so the
full message text appears in the event log.
Note that the win32evtlog.pyd file has a number of string entries with just "%1"
built in, so many Python programs can simply use this DLL. Disadvantages are that
you do not get language translation, and the full text is stored in the event log,
blowing the size of the log up.
"""
# When an application uses the RegisterEventSource or OpenEventLog
# function to get a handle of an event log, the event logging service
# searches for the specified source name in the registry. You can add a
# new source name to the registry by opening a new registry subkey
# under the Application key and adding registry values to the new
# subkey.
if msgDLL is None:
msgDLL = win32evtlog.__file__
# Create a new key for our application
hkey = win32api.RegCreateKey(
win32con.HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s"
% (eventLogType, appName),
)
# Add the Event-ID message-file name to the subkey.
win32api.RegSetValueEx(
hkey,
"EventMessageFile", # value name \
0, # reserved \
win32con.REG_EXPAND_SZ, # value type \
msgDLL,
)
# Set the supported types flags and add it to the subkey.
if eventLogFlags is None:
eventLogFlags = (
win32evtlog.EVENTLOG_ERROR_TYPE
| win32evtlog.EVENTLOG_WARNING_TYPE
| win32evtlog.EVENTLOG_INFORMATION_TYPE
)
win32api.RegSetValueEx(
hkey, # subkey handle \
"TypesSupported", # value name \
0, # reserved \
win32con.REG_DWORD, # value type \
eventLogFlags,
)
if categoryCount > 0:
# Optionally, you can specify a message file that contains the categories
if categoryDLL is None:
categoryDLL = win32evtlog.__file__
win32api.RegSetValueEx(
hkey, # subkey handle \
"CategoryMessageFile", # value name \
0, # reserved \
win32con.REG_EXPAND_SZ, # value type \
categoryDLL,
)
win32api.RegSetValueEx(
hkey, # subkey handle \
"CategoryCount", # value name \
0, # reserved \
win32con.REG_DWORD, # value type \
categoryCount,
)
win32api.RegCloseKey(hkey)
def RemoveSourceFromRegistry(appName, eventLogType="Application"):
"""Removes a source of messages from the event log."""
# Delete our key
try:
win32api.RegDeleteKey(
win32con.HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s"
% (eventLogType, appName),
)
except win32api.error as exc:
if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
raise
def ReportEvent(
appName,
eventID,
eventCategory=0,
eventType=win32evtlog.EVENTLOG_ERROR_TYPE,
strings=None,
data=None,
sid=None,
):
"""Report an event for a previously added event source."""
# Get a handle to the Application event log
hAppLog = win32evtlog.RegisterEventSource(None, appName)
# Now report the event, which will add this event to the event log */
win32evtlog.ReportEvent(
hAppLog, # event-log handle \
eventType,
eventCategory,
eventID,
sid,
strings,
data,
)
win32evtlog.DeregisterEventSource(hAppLog)
def FormatMessage(eventLogRecord, logType="Application"):
"""Given a tuple from ReadEventLog, and optionally where the event
record came from, load the message, and process message inserts.
Note that this function may raise win32api.error. See also the
function SafeFormatMessage which will return None if the message can
not be processed.
"""
# From the event log source name, we know the name of the registry
# key to look under for the name of the message DLL that contains
# the messages we need to extract with FormatMessage. So first get
# the event log source name...
keyName = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s" % (
logType,
eventLogRecord.SourceName,
)
# Now open this key and get the EventMessageFile value, which is
# the name of the message DLL.
handle = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, keyName)
try:
dllNames = win32api.RegQueryValueEx(handle, "EventMessageFile")[0].split(";")
# Win2k etc appear to allow multiple DLL names
data = None
for dllName in dllNames:
try:
# Expand environment variable strings in the message DLL path name,
# in case any are there.
dllName = win32api.ExpandEnvironmentStrings(dllName)
dllHandle = win32api.LoadLibraryEx(
dllName, 0, win32con.LOAD_LIBRARY_AS_DATAFILE
)
try:
data = win32api.FormatMessageW(
win32con.FORMAT_MESSAGE_FROM_HMODULE,
dllHandle,
eventLogRecord.EventID,
langid,
eventLogRecord.StringInserts,
)
finally:
win32api.FreeLibrary(dllHandle)
except win32api.error:
pass # Not in this DLL - try the next
if data is not None:
break
finally:
win32api.RegCloseKey(handle)
return data or "" # Don't want "None" ever being returned.
def SafeFormatMessage(eventLogRecord, logType=None):
"""As for FormatMessage, except returns an error message if
the message can not be processed.
"""
if logType is None:
logType = "Application"
try:
return FormatMessage(eventLogRecord, logType)
except win32api.error:
if eventLogRecord.StringInserts is None:
desc = ""
else:
desc = ", ".join(eventLogRecord.StringInserts)
return (
"<The description for Event ID ( %d ) in Source ( %r ) could not be found. It contains the following insertion string(s):%r.>"
% (
winerror.HRESULT_CODE(eventLogRecord.EventID),
eventLogRecord.SourceName,
desc,
)
)
def FeedEventLogRecords(
feeder, machineName=None, logName="Application", readFlags=None
):
if readFlags is None:
readFlags = (
win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
)
h = win32evtlog.OpenEventLog(machineName, logName)
try:
while 1:
objects = win32evtlog.ReadEventLog(h, readFlags, 0)
if not objects:
break
map(lambda item, feeder=feeder: feeder(*(item,)), objects)
finally:
win32evtlog.CloseEventLog(h)

View file

@ -0,0 +1,999 @@
# This is a work in progress - see Demos/win32gui_menu.py
# win32gui_struct.py - helpers for working with various win32gui structures.
# As win32gui is "light-weight", it does not define objects for all possible
# win32 structures - in general, "buffer" objects are passed around - it is
# the callers responsibility to pack the buffer in the correct format.
#
# This module defines some helpers for the commonly used structures.
#
# In general, each structure has 3 functions:
#
# buffer, extras = PackSTRUCTURE(items, ...)
# item, ... = UnpackSTRUCTURE(buffer)
# buffer, extras = EmtpySTRUCTURE(...)
#
# 'extras' is always items that must be held along with the buffer, as the
# buffer refers to these object's memory.
# For structures that support a 'mask', this mask is hidden from the user - if
# 'None' is passed, the mask flag will not be set, or on return, None will
# be returned for the value if the mask is not set.
#
# NOTE: I considered making these structures look like real classes, and
# support 'attributes' etc - however, ctypes already has a good structure
# mechanism - I think it makes more sense to support ctype structures
# at the win32gui level, then there will be no need for this module at all.
# XXX - the above makes sense in terms of what is built and passed to
# win32gui (ie, the Pack* functions) - but doesn't make as much sense for
# the Unpack* functions, where the aim is user convenience.
import array
import struct
import sys
import commctrl
import pywintypes
import win32con
import win32gui
is64bit = "64 bit" in sys.version
try:
from collections import namedtuple
def _MakeResult(names_str, values):
names = names_str.split()
nt = namedtuple(names[0], names[1:])
return nt(*values)
except ImportError:
# no namedtuple support - just return the values as a normal tuple.
def _MakeResult(names_str, values):
return values
_nmhdr_fmt = "PPi"
if is64bit:
# When the item past the NMHDR gets aligned (eg, when it is a struct)
# we need this many bytes padding.
_nmhdr_align_padding = "xxxx"
else:
_nmhdr_align_padding = ""
# Encode a string suitable for passing in a win32gui related structure
# If win32gui is built with UNICODE defined (ie, py3k), then functions
# like InsertMenuItem are actually calling InsertMenuItemW etc, so all
# strings will need to be unicode.
if win32gui.UNICODE:
def _make_text_buffer(text):
# XXX - at this stage win32gui.UNICODE is only True in py3k,
# and in py3k is makes sense to reject bytes.
if not isinstance(text, str):
raise TypeError("MENUITEMINFO text must be unicode")
data = (text + "\0").encode("utf-16le")
return array.array("b", data)
else:
def _make_text_buffer(text):
if isinstance(text, str):
text = text.encode("mbcs")
return array.array("b", text + "\0")
# make an 'empty' buffer, ready for filling with cch characters.
def _make_empty_text_buffer(cch):
return _make_text_buffer("\0" * cch)
if sys.version_info < (3, 0):
def _make_memory(ob):
return str(buffer(ob))
def _make_bytes(sval):
return sval
else:
def _make_memory(ob):
return bytes(memoryview(ob))
def _make_bytes(sval):
return sval.encode("ascii")
# Generic WM_NOTIFY unpacking
def UnpackWMNOTIFY(lparam):
format = "PPi"
buf = win32gui.PyGetMemory(lparam, struct.calcsize(format))
return _MakeResult("WMNOTIFY hwndFrom idFrom code", struct.unpack(format, buf))
def UnpackNMITEMACTIVATE(lparam):
format = _nmhdr_fmt + _nmhdr_align_padding
if is64bit:
# the struct module doesn't handle this correctly as some of the items
# are actually structs in structs, which get individually aligned.
format = format + "iiiiiiixxxxP"
else:
format = format + "iiiiiiiP"
buf = win32gui.PyMakeBuffer(struct.calcsize(format), lparam)
return _MakeResult(
"NMITEMACTIVATE hwndFrom idFrom code iItem iSubItem uNewState uOldState uChanged actionx actiony lParam",
struct.unpack(format, buf),
)
# MENUITEMINFO struct
# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/Resources/Menus/MenuReference/MenuStructures/MENUITEMINFO.asp
# We use the struct module to pack and unpack strings as MENUITEMINFO
# structures. We also have special handling for the 'fMask' item in that
# structure to avoid the caller needing to explicitly check validity
# (None is used if the mask excludes/should exclude the value)
_menuiteminfo_fmt = "5i5PiP"
def PackMENUITEMINFO(
fType=None,
fState=None,
wID=None,
hSubMenu=None,
hbmpChecked=None,
hbmpUnchecked=None,
dwItemData=None,
text=None,
hbmpItem=None,
dwTypeData=None,
):
# 'extras' are objects the caller must keep a reference to (as their
# memory is used) for the lifetime of the INFO item.
extras = []
# ack - dwItemData and dwTypeData were confused for a while...
assert (
dwItemData is None or dwTypeData is None
), "sorry - these were confused - you probably want dwItemData"
# if we are a long way past 209, then we can nuke the above...
if dwTypeData is not None:
import warnings
warnings.warn("PackMENUITEMINFO: please use dwItemData instead of dwTypeData")
if dwItemData is None:
dwItemData = dwTypeData or 0
fMask = 0
if fType is None:
fType = 0
else:
fMask |= win32con.MIIM_FTYPE
if fState is None:
fState = 0
else:
fMask |= win32con.MIIM_STATE
if wID is None:
wID = 0
else:
fMask |= win32con.MIIM_ID
if hSubMenu is None:
hSubMenu = 0
else:
fMask |= win32con.MIIM_SUBMENU
if hbmpChecked is None:
assert hbmpUnchecked is None, "neither or both checkmark bmps must be given"
hbmpChecked = hbmpUnchecked = 0
else:
assert hbmpUnchecked is not None, "neither or both checkmark bmps must be given"
fMask |= win32con.MIIM_CHECKMARKS
if dwItemData is None:
dwItemData = 0
else:
fMask |= win32con.MIIM_DATA
if hbmpItem is None:
hbmpItem = 0
else:
fMask |= win32con.MIIM_BITMAP
if text is not None:
fMask |= win32con.MIIM_STRING
str_buf = _make_text_buffer(text)
cch = len(text)
# We are taking address of strbuf - it must not die until windows
# has finished with our structure.
lptext = str_buf.buffer_info()[0]
extras.append(str_buf)
else:
lptext = 0
cch = 0
# Create the struct.
# 'P' format does not accept PyHANDLE's !
item = struct.pack(
_menuiteminfo_fmt,
struct.calcsize(_menuiteminfo_fmt), # cbSize
fMask,
fType,
fState,
wID,
int(hSubMenu),
int(hbmpChecked),
int(hbmpUnchecked),
dwItemData,
lptext,
cch,
int(hbmpItem),
)
# Now copy the string to a writable buffer, so that the result
# could be passed to a 'Get' function
return array.array("b", item), extras
def UnpackMENUITEMINFO(s):
(
cb,
fMask,
fType,
fState,
wID,
hSubMenu,
hbmpChecked,
hbmpUnchecked,
dwItemData,
lptext,
cch,
hbmpItem,
) = struct.unpack(_menuiteminfo_fmt, s)
assert cb == len(s)
if fMask & win32con.MIIM_FTYPE == 0:
fType = None
if fMask & win32con.MIIM_STATE == 0:
fState = None
if fMask & win32con.MIIM_ID == 0:
wID = None
if fMask & win32con.MIIM_SUBMENU == 0:
hSubMenu = None
if fMask & win32con.MIIM_CHECKMARKS == 0:
hbmpChecked = hbmpUnchecked = None
if fMask & win32con.MIIM_DATA == 0:
dwItemData = None
if fMask & win32con.MIIM_BITMAP == 0:
hbmpItem = None
if fMask & win32con.MIIM_STRING:
text = win32gui.PyGetString(lptext, cch)
else:
text = None
return _MakeResult(
"MENUITEMINFO fType fState wID hSubMenu hbmpChecked "
"hbmpUnchecked dwItemData text hbmpItem",
(
fType,
fState,
wID,
hSubMenu,
hbmpChecked,
hbmpUnchecked,
dwItemData,
text,
hbmpItem,
),
)
def EmptyMENUITEMINFO(mask=None, text_buf_size=512):
# text_buf_size is number of *characters* - not necessarily no of bytes.
extra = []
if mask is None:
mask = (
win32con.MIIM_BITMAP
| win32con.MIIM_CHECKMARKS
| win32con.MIIM_DATA
| win32con.MIIM_FTYPE
| win32con.MIIM_ID
| win32con.MIIM_STATE
| win32con.MIIM_STRING
| win32con.MIIM_SUBMENU
)
# Note: No MIIM_TYPE - this screws win2k/98.
if mask & win32con.MIIM_STRING:
text_buffer = _make_empty_text_buffer(text_buf_size)
extra.append(text_buffer)
text_addr, _ = text_buffer.buffer_info()
else:
text_addr = text_buf_size = 0
# Now copy the string to a writable buffer, so that the result
# could be passed to a 'Get' function
buf = struct.pack(
_menuiteminfo_fmt,
struct.calcsize(_menuiteminfo_fmt), # cbSize
mask,
0, # fType,
0, # fState,
0, # wID,
0, # hSubMenu,
0, # hbmpChecked,
0, # hbmpUnchecked,
0, # dwItemData,
text_addr,
text_buf_size,
0, # hbmpItem
)
return array.array("b", buf), extra
# MENUINFO struct
_menuinfo_fmt = "iiiiPiP"
def PackMENUINFO(
dwStyle=None,
cyMax=None,
hbrBack=None,
dwContextHelpID=None,
dwMenuData=None,
fMask=0,
):
if dwStyle is None:
dwStyle = 0
else:
fMask |= win32con.MIM_STYLE
if cyMax is None:
cyMax = 0
else:
fMask |= win32con.MIM_MAXHEIGHT
if hbrBack is None:
hbrBack = 0
else:
fMask |= win32con.MIM_BACKGROUND
if dwContextHelpID is None:
dwContextHelpID = 0
else:
fMask |= win32con.MIM_HELPID
if dwMenuData is None:
dwMenuData = 0
else:
fMask |= win32con.MIM_MENUDATA
# Create the struct.
item = struct.pack(
_menuinfo_fmt,
struct.calcsize(_menuinfo_fmt), # cbSize
fMask,
dwStyle,
cyMax,
hbrBack,
dwContextHelpID,
dwMenuData,
)
return array.array("b", item)
def UnpackMENUINFO(s):
(cb, fMask, dwStyle, cyMax, hbrBack, dwContextHelpID, dwMenuData) = struct.unpack(
_menuinfo_fmt, s
)
assert cb == len(s)
if fMask & win32con.MIM_STYLE == 0:
dwStyle = None
if fMask & win32con.MIM_MAXHEIGHT == 0:
cyMax = None
if fMask & win32con.MIM_BACKGROUND == 0:
hbrBack = None
if fMask & win32con.MIM_HELPID == 0:
dwContextHelpID = None
if fMask & win32con.MIM_MENUDATA == 0:
dwMenuData = None
return _MakeResult(
"MENUINFO dwStyle cyMax hbrBack dwContextHelpID dwMenuData",
(dwStyle, cyMax, hbrBack, dwContextHelpID, dwMenuData),
)
def EmptyMENUINFO(mask=None):
if mask is None:
mask = (
win32con.MIM_STYLE
| win32con.MIM_MAXHEIGHT
| win32con.MIM_BACKGROUND
| win32con.MIM_HELPID
| win32con.MIM_MENUDATA
)
buf = struct.pack(
_menuinfo_fmt,
struct.calcsize(_menuinfo_fmt), # cbSize
mask,
0, # dwStyle
0, # cyMax
0, # hbrBack,
0, # dwContextHelpID,
0, # dwMenuData,
)
return array.array("b", buf)
##########################################################################
#
# Tree View structure support - TVITEM, TVINSERTSTRUCT and TVDISPINFO
#
##########################################################################
# XXX - Note that the following implementation of TreeView structures is ripped
# XXX - from the SpamBayes project. It may not quite work correctly yet - I
# XXX - intend checking them later - but having them is better than not at all!
_tvitem_fmt = "iPiiPiiiiP"
# Helpers for the ugly win32 structure packing/unpacking
# XXX - Note that functions using _GetMaskAndVal run 3x faster if they are
# 'inlined' into the function - see PackLVITEM. If the profiler points at
# _GetMaskAndVal(), you should nuke it (patches welcome once they have been
# tested)
def _GetMaskAndVal(val, default, mask, flag):
if val is None:
return mask, default
else:
if flag is not None:
mask |= flag
return mask, val
def PackTVINSERTSTRUCT(parent, insertAfter, tvitem):
tvitem_buf, extra = PackTVITEM(*tvitem)
tvitem_buf = tvitem_buf.tobytes()
format = "PP%ds" % len(tvitem_buf)
return struct.pack(format, parent, insertAfter, tvitem_buf), extra
def PackTVITEM(hitem, state, stateMask, text, image, selimage, citems, param):
extra = [] # objects we must keep references to
mask = 0
mask, hitem = _GetMaskAndVal(hitem, 0, mask, commctrl.TVIF_HANDLE)
mask, state = _GetMaskAndVal(state, 0, mask, commctrl.TVIF_STATE)
if not mask & commctrl.TVIF_STATE:
stateMask = 0
mask, text = _GetMaskAndVal(text, None, mask, commctrl.TVIF_TEXT)
mask, image = _GetMaskAndVal(image, 0, mask, commctrl.TVIF_IMAGE)
mask, selimage = _GetMaskAndVal(selimage, 0, mask, commctrl.TVIF_SELECTEDIMAGE)
mask, citems = _GetMaskAndVal(citems, 0, mask, commctrl.TVIF_CHILDREN)
mask, param = _GetMaskAndVal(param, 0, mask, commctrl.TVIF_PARAM)
if text is None:
text_addr = text_len = 0
else:
text_buffer = _make_text_buffer(text)
text_len = len(text)
extra.append(text_buffer)
text_addr, _ = text_buffer.buffer_info()
buf = struct.pack(
_tvitem_fmt,
mask,
hitem,
state,
stateMask,
text_addr,
text_len, # text
image,
selimage,
citems,
param,
)
return array.array("b", buf), extra
# Make a new buffer suitable for querying hitem's attributes.
def EmptyTVITEM(hitem, mask=None, text_buf_size=512):
extra = [] # objects we must keep references to
if mask is None:
mask = (
commctrl.TVIF_HANDLE
| commctrl.TVIF_STATE
| commctrl.TVIF_TEXT
| commctrl.TVIF_IMAGE
| commctrl.TVIF_SELECTEDIMAGE
| commctrl.TVIF_CHILDREN
| commctrl.TVIF_PARAM
)
if mask & commctrl.TVIF_TEXT:
text_buffer = _make_empty_text_buffer(text_buf_size)
extra.append(text_buffer)
text_addr, _ = text_buffer.buffer_info()
else:
text_addr = text_buf_size = 0
buf = struct.pack(
_tvitem_fmt, mask, hitem, 0, 0, text_addr, text_buf_size, 0, 0, 0, 0 # text
)
return array.array("b", buf), extra
def UnpackTVITEM(buffer):
(
item_mask,
item_hItem,
item_state,
item_stateMask,
item_textptr,
item_cchText,
item_image,
item_selimage,
item_cChildren,
item_param,
) = struct.unpack(_tvitem_fmt, buffer)
# ensure only items listed by the mask are valid (except we assume the
# handle is always valid - some notifications (eg, TVN_ENDLABELEDIT) set a
# mask that doesn't include the handle, but the docs explicity say it is.)
if not (item_mask & commctrl.TVIF_TEXT):
item_textptr = item_cchText = None
if not (item_mask & commctrl.TVIF_CHILDREN):
item_cChildren = None
if not (item_mask & commctrl.TVIF_IMAGE):
item_image = None
if not (item_mask & commctrl.TVIF_PARAM):
item_param = None
if not (item_mask & commctrl.TVIF_SELECTEDIMAGE):
item_selimage = None
if not (item_mask & commctrl.TVIF_STATE):
item_state = item_stateMask = None
if item_textptr:
text = win32gui.PyGetString(item_textptr)
else:
text = None
return _MakeResult(
"TVITEM item_hItem item_state item_stateMask "
"text item_image item_selimage item_cChildren item_param",
(
item_hItem,
item_state,
item_stateMask,
text,
item_image,
item_selimage,
item_cChildren,
item_param,
),
)
# Unpack the lparm from a "TVNOTIFY" message
def UnpackTVNOTIFY(lparam):
item_size = struct.calcsize(_tvitem_fmt)
format = _nmhdr_fmt + _nmhdr_align_padding
if is64bit:
format = format + "ixxxx"
else:
format = format + "i"
format = format + "%ds%ds" % (item_size, item_size)
buf = win32gui.PyGetMemory(lparam, struct.calcsize(format))
hwndFrom, id, code, action, buf_old, buf_new = struct.unpack(format, buf)
item_old = UnpackTVITEM(buf_old)
item_new = UnpackTVITEM(buf_new)
return _MakeResult(
"TVNOTIFY hwndFrom id code action item_old item_new",
(hwndFrom, id, code, action, item_old, item_new),
)
def UnpackTVDISPINFO(lparam):
item_size = struct.calcsize(_tvitem_fmt)
format = "PPi%ds" % (item_size,)
buf = win32gui.PyGetMemory(lparam, struct.calcsize(format))
hwndFrom, id, code, buf_item = struct.unpack(format, buf)
item = UnpackTVITEM(buf_item)
return _MakeResult("TVDISPINFO hwndFrom id code item", (hwndFrom, id, code, item))
#
# List view items
_lvitem_fmt = "iiiiiPiiPi"
def PackLVITEM(
item=None,
subItem=None,
state=None,
stateMask=None,
text=None,
image=None,
param=None,
indent=None,
):
extra = [] # objects we must keep references to
mask = 0
# _GetMaskAndVal adds quite a bit of overhead to this function.
if item is None:
item = 0 # No mask for item
if subItem is None:
subItem = 0 # No mask for sibItem
if state is None:
state = 0
stateMask = 0
else:
mask |= commctrl.LVIF_STATE
if stateMask is None:
stateMask = state
if image is None:
image = 0
else:
mask |= commctrl.LVIF_IMAGE
if param is None:
param = 0
else:
mask |= commctrl.LVIF_PARAM
if indent is None:
indent = 0
else:
mask |= commctrl.LVIF_INDENT
if text is None:
text_addr = text_len = 0
else:
mask |= commctrl.LVIF_TEXT
text_buffer = _make_text_buffer(text)
text_len = len(text)
extra.append(text_buffer)
text_addr, _ = text_buffer.buffer_info()
buf = struct.pack(
_lvitem_fmt,
mask,
item,
subItem,
state,
stateMask,
text_addr,
text_len, # text
image,
param,
indent,
)
return array.array("b", buf), extra
def UnpackLVITEM(buffer):
(
item_mask,
item_item,
item_subItem,
item_state,
item_stateMask,
item_textptr,
item_cchText,
item_image,
item_param,
item_indent,
) = struct.unpack(_lvitem_fmt, buffer)
# ensure only items listed by the mask are valid
if not (item_mask & commctrl.LVIF_TEXT):
item_textptr = item_cchText = None
if not (item_mask & commctrl.LVIF_IMAGE):
item_image = None
if not (item_mask & commctrl.LVIF_PARAM):
item_param = None
if not (item_mask & commctrl.LVIF_INDENT):
item_indent = None
if not (item_mask & commctrl.LVIF_STATE):
item_state = item_stateMask = None
if item_textptr:
text = win32gui.PyGetString(item_textptr)
else:
text = None
return _MakeResult(
"LVITEM item_item item_subItem item_state "
"item_stateMask text item_image item_param item_indent",
(
item_item,
item_subItem,
item_state,
item_stateMask,
text,
item_image,
item_param,
item_indent,
),
)
# Unpack an "LVNOTIFY" message
def UnpackLVDISPINFO(lparam):
item_size = struct.calcsize(_lvitem_fmt)
format = _nmhdr_fmt + _nmhdr_align_padding + ("%ds" % (item_size,))
buf = win32gui.PyGetMemory(lparam, struct.calcsize(format))
hwndFrom, id, code, buf_item = struct.unpack(format, buf)
item = UnpackLVITEM(buf_item)
return _MakeResult("LVDISPINFO hwndFrom id code item", (hwndFrom, id, code, item))
def UnpackLVNOTIFY(lparam):
format = _nmhdr_fmt + _nmhdr_align_padding + "7i"
if is64bit:
format = format + "xxxx" # point needs padding.
format = format + "P"
buf = win32gui.PyGetMemory(lparam, struct.calcsize(format))
(
hwndFrom,
id,
code,
item,
subitem,
newstate,
oldstate,
changed,
pt_x,
pt_y,
lparam,
) = struct.unpack(format, buf)
return _MakeResult(
"UnpackLVNOTIFY hwndFrom id code item subitem "
"newstate oldstate changed pt lparam",
(
hwndFrom,
id,
code,
item,
subitem,
newstate,
oldstate,
changed,
(pt_x, pt_y),
lparam,
),
)
# Make a new buffer suitable for querying an items attributes.
def EmptyLVITEM(item, subitem, mask=None, text_buf_size=512):
extra = [] # objects we must keep references to
if mask is None:
mask = (
commctrl.LVIF_IMAGE
| commctrl.LVIF_INDENT
| commctrl.LVIF_TEXT
| commctrl.LVIF_PARAM
| commctrl.LVIF_STATE
)
if mask & commctrl.LVIF_TEXT:
text_buffer = _make_empty_text_buffer(text_buf_size)
extra.append(text_buffer)
text_addr, _ = text_buffer.buffer_info()
else:
text_addr = text_buf_size = 0
buf = struct.pack(
_lvitem_fmt,
mask,
item,
subitem,
0,
0,
text_addr,
text_buf_size, # text
0,
0,
0,
)
return array.array("b", buf), extra
# List view column structure
_lvcolumn_fmt = "iiiPiiii"
def PackLVCOLUMN(fmt=None, cx=None, text=None, subItem=None, image=None, order=None):
extra = [] # objects we must keep references to
mask = 0
mask, fmt = _GetMaskAndVal(fmt, 0, mask, commctrl.LVCF_FMT)
mask, cx = _GetMaskAndVal(cx, 0, mask, commctrl.LVCF_WIDTH)
mask, text = _GetMaskAndVal(text, None, mask, commctrl.LVCF_TEXT)
mask, subItem = _GetMaskAndVal(subItem, 0, mask, commctrl.LVCF_SUBITEM)
mask, image = _GetMaskAndVal(image, 0, mask, commctrl.LVCF_IMAGE)
mask, order = _GetMaskAndVal(order, 0, mask, commctrl.LVCF_ORDER)
if text is None:
text_addr = text_len = 0
else:
text_buffer = _make_text_buffer(text)
extra.append(text_buffer)
text_addr, _ = text_buffer.buffer_info()
text_len = len(text)
buf = struct.pack(
_lvcolumn_fmt, mask, fmt, cx, text_addr, text_len, subItem, image, order # text
)
return array.array("b", buf), extra
def UnpackLVCOLUMN(lparam):
mask, fmt, cx, text_addr, text_size, subItem, image, order = struct.unpack(
_lvcolumn_fmt, lparam
)
# ensure only items listed by the mask are valid
if not (mask & commctrl.LVCF_FMT):
fmt = None
if not (mask & commctrl.LVCF_WIDTH):
cx = None
if not (mask & commctrl.LVCF_TEXT):
text_addr = text_size = None
if not (mask & commctrl.LVCF_SUBITEM):
subItem = None
if not (mask & commctrl.LVCF_IMAGE):
image = None
if not (mask & commctrl.LVCF_ORDER):
order = None
if text_addr:
text = win32gui.PyGetString(text_addr)
else:
text = None
return _MakeResult(
"LVCOLUMN fmt cx text subItem image order",
(fmt, cx, text, subItem, image, order),
)
# Make a new buffer suitable for querying an items attributes.
def EmptyLVCOLUMN(mask=None, text_buf_size=512):
extra = [] # objects we must keep references to
if mask is None:
mask = (
commctrl.LVCF_FMT
| commctrl.LVCF_WIDTH
| commctrl.LVCF_TEXT
| commctrl.LVCF_SUBITEM
| commctrl.LVCF_IMAGE
| commctrl.LVCF_ORDER
)
if mask & commctrl.LVCF_TEXT:
text_buffer = _make_empty_text_buffer(text_buf_size)
extra.append(text_buffer)
text_addr, _ = text_buffer.buffer_info()
else:
text_addr = text_buf_size = 0
buf = struct.pack(
_lvcolumn_fmt, mask, 0, 0, text_addr, text_buf_size, 0, 0, 0 # text
)
return array.array("b", buf), extra
# List view hit-test.
def PackLVHITTEST(pt):
format = "iiiii"
buf = struct.pack(format, pt[0], pt[1], 0, 0, 0)
return array.array("b", buf), None
def UnpackLVHITTEST(buf):
format = "iiiii"
x, y, flags, item, subitem = struct.unpack(format, buf)
return _MakeResult(
"LVHITTEST pt flags item subitem", ((x, y), flags, item, subitem)
)
def PackHDITEM(
cxy=None, text=None, hbm=None, fmt=None, param=None, image=None, order=None
):
extra = [] # objects we must keep references to
mask = 0
mask, cxy = _GetMaskAndVal(cxy, 0, mask, commctrl.HDI_HEIGHT)
mask, text = _GetMaskAndVal(text, None, mask, commctrl.LVCF_TEXT)
mask, hbm = _GetMaskAndVal(hbm, 0, mask, commctrl.HDI_BITMAP)
mask, fmt = _GetMaskAndVal(fmt, 0, mask, commctrl.HDI_FORMAT)
mask, param = _GetMaskAndVal(param, 0, mask, commctrl.HDI_LPARAM)
mask, image = _GetMaskAndVal(image, 0, mask, commctrl.HDI_IMAGE)
mask, order = _GetMaskAndVal(order, 0, mask, commctrl.HDI_ORDER)
if text is None:
text_addr = text_len = 0
else:
text_buffer = _make_text_buffer(text)
extra.append(text_buffer)
text_addr, _ = text_buffer.buffer_info()
text_len = len(text)
format = "iiPPiiPiiii"
buf = struct.pack(
format, mask, cxy, text_addr, hbm, text_len, fmt, param, image, order, 0, 0
)
return array.array("b", buf), extra
# Device notification stuff
# Generic function for packing a DEV_BROADCAST_* structure - generally used
# by the other PackDEV_BROADCAST_* functions in this module.
def PackDEV_BROADCAST(devicetype, rest_fmt, rest_data, extra_data=_make_bytes("")):
# It seems a requirement is 4 byte alignment, even for the 'BYTE data[1]'
# field (eg, that would make DEV_BROADCAST_HANDLE 41 bytes, but we must
# be 44.
extra_data += _make_bytes("\0" * (4 - len(extra_data) % 4))
format = "iii" + rest_fmt
full_size = struct.calcsize(format) + len(extra_data)
data = (full_size, devicetype, 0) + rest_data
return struct.pack(format, *data) + extra_data
def PackDEV_BROADCAST_HANDLE(
handle,
hdevnotify=0,
guid=_make_bytes("\0" * 16),
name_offset=0,
data=_make_bytes("\0"),
):
return PackDEV_BROADCAST(
win32con.DBT_DEVTYP_HANDLE,
"PP16sl",
(int(handle), int(hdevnotify), _make_memory(guid), name_offset),
data,
)
def PackDEV_BROADCAST_VOLUME(unitmask, flags):
return PackDEV_BROADCAST(win32con.DBT_DEVTYP_VOLUME, "II", (unitmask, flags))
def PackDEV_BROADCAST_DEVICEINTERFACE(classguid, name=""):
if win32gui.UNICODE:
# This really means "is py3k?" - so not accepting bytes is OK
if not isinstance(name, str):
raise TypeError("Must provide unicode for the name")
name = name.encode("utf-16le")
else:
# py2k was passed a unicode object - encode as mbcs.
if isinstance(name, str):
name = name.encode("mbcs")
# 16 bytes for the IID followed by \0 term'd string.
rest_fmt = "16s%ds" % len(name)
# _make_memory(iid) hoops necessary to get the raw IID bytes.
rest_data = (_make_memory(pywintypes.IID(classguid)), name)
return PackDEV_BROADCAST(win32con.DBT_DEVTYP_DEVICEINTERFACE, rest_fmt, rest_data)
# An object returned by UnpackDEV_BROADCAST.
class DEV_BROADCAST_INFO:
def __init__(self, devicetype, **kw):
self.devicetype = devicetype
self.__dict__.update(kw)
def __str__(self):
return "DEV_BROADCAST_INFO:" + str(self.__dict__)
# Support for unpacking the 'lparam'
def UnpackDEV_BROADCAST(lparam):
if lparam == 0:
return None
hdr_format = "iii"
hdr_size = struct.calcsize(hdr_format)
hdr_buf = win32gui.PyGetMemory(lparam, hdr_size)
size, devtype, reserved = struct.unpack("iii", hdr_buf)
# Due to x64 alignment issues, we need to use the full format string over
# the entire buffer. ie, on x64:
# calcsize('iiiP') != calcsize('iii')+calcsize('P')
buf = win32gui.PyGetMemory(lparam, size)
extra = x = {}
if devtype == win32con.DBT_DEVTYP_HANDLE:
# 2 handles, a GUID, a LONG and possibly an array following...
fmt = hdr_format + "PP16sl"
(
_,
_,
_,
x["handle"],
x["hdevnotify"],
guid_bytes,
x["nameoffset"],
) = struct.unpack(fmt, buf[: struct.calcsize(fmt)])
x["eventguid"] = pywintypes.IID(guid_bytes, True)
elif devtype == win32con.DBT_DEVTYP_DEVICEINTERFACE:
fmt = hdr_format + "16s"
_, _, _, guid_bytes = struct.unpack(fmt, buf[: struct.calcsize(fmt)])
x["classguid"] = pywintypes.IID(guid_bytes, True)
x["name"] = win32gui.PyGetString(lparam + struct.calcsize(fmt))
elif devtype == win32con.DBT_DEVTYP_VOLUME:
# int mask and flags
fmt = hdr_format + "II"
_, _, _, x["unitmask"], x["flags"] = struct.unpack(
fmt, buf[: struct.calcsize(fmt)]
)
else:
raise NotImplementedError("unknown device type %d" % (devtype,))
return DEV_BROADCAST_INFO(devtype, **extra)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,627 @@
# Generated by h2py from lmaccess.h
# Included from lmcons.h
CNLEN = 15
LM20_CNLEN = 15
DNLEN = CNLEN
LM20_DNLEN = LM20_CNLEN
UNCLEN = CNLEN + 2
LM20_UNCLEN = LM20_CNLEN + 2
NNLEN = 80
LM20_NNLEN = 12
RMLEN = UNCLEN + 1 + NNLEN
LM20_RMLEN = LM20_UNCLEN + 1 + LM20_NNLEN
SNLEN = 80
LM20_SNLEN = 15
STXTLEN = 256
LM20_STXTLEN = 63
PATHLEN = 256
LM20_PATHLEN = 256
DEVLEN = 80
LM20_DEVLEN = 8
EVLEN = 16
UNLEN = 256
LM20_UNLEN = 20
GNLEN = UNLEN
LM20_GNLEN = LM20_UNLEN
PWLEN = 256
LM20_PWLEN = 14
SHPWLEN = 8
CLTYPE_LEN = 12
MAXCOMMENTSZ = 256
LM20_MAXCOMMENTSZ = 48
QNLEN = NNLEN
LM20_QNLEN = LM20_NNLEN
ALERTSZ = 128
NETBIOS_NAME_LEN = 16
CRYPT_KEY_LEN = 7
CRYPT_TXT_LEN = 8
ENCRYPTED_PWLEN = 16
SESSION_PWLEN = 24
SESSION_CRYPT_KLEN = 21
PARMNUM_ALL = 0
PARM_ERROR_NONE = 0
PARMNUM_BASE_INFOLEVEL = 1000
NULL = 0
PLATFORM_ID_DOS = 300
PLATFORM_ID_OS2 = 400
PLATFORM_ID_NT = 500
PLATFORM_ID_OSF = 600
PLATFORM_ID_VMS = 700
MAX_LANMAN_MESSAGE_ID = 5799
UF_SCRIPT = 1
UF_ACCOUNTDISABLE = 2
UF_HOMEDIR_REQUIRED = 8
UF_LOCKOUT = 16
UF_PASSWD_NOTREQD = 32
UF_PASSWD_CANT_CHANGE = 64
UF_TEMP_DUPLICATE_ACCOUNT = 256
UF_NORMAL_ACCOUNT = 512
UF_INTERDOMAIN_TRUST_ACCOUNT = 2048
UF_WORKSTATION_TRUST_ACCOUNT = 4096
UF_SERVER_TRUST_ACCOUNT = 8192
UF_MACHINE_ACCOUNT_MASK = (
UF_INTERDOMAIN_TRUST_ACCOUNT
| UF_WORKSTATION_TRUST_ACCOUNT
| UF_SERVER_TRUST_ACCOUNT
)
UF_ACCOUNT_TYPE_MASK = (
UF_TEMP_DUPLICATE_ACCOUNT
| UF_NORMAL_ACCOUNT
| UF_INTERDOMAIN_TRUST_ACCOUNT
| UF_WORKSTATION_TRUST_ACCOUNT
| UF_SERVER_TRUST_ACCOUNT
)
UF_DONT_EXPIRE_PASSWD = 65536
UF_MNS_LOGON_ACCOUNT = 131072
UF_SETTABLE_BITS = (
UF_SCRIPT
| UF_ACCOUNTDISABLE
| UF_LOCKOUT
| UF_HOMEDIR_REQUIRED
| UF_PASSWD_NOTREQD
| UF_PASSWD_CANT_CHANGE
| UF_ACCOUNT_TYPE_MASK
| UF_DONT_EXPIRE_PASSWD
| UF_MNS_LOGON_ACCOUNT
)
FILTER_TEMP_DUPLICATE_ACCOUNT = 1
FILTER_NORMAL_ACCOUNT = 2
FILTER_INTERDOMAIN_TRUST_ACCOUNT = 8
FILTER_WORKSTATION_TRUST_ACCOUNT = 16
FILTER_SERVER_TRUST_ACCOUNT = 32
LG_INCLUDE_INDIRECT = 1
AF_OP_PRINT = 1
AF_OP_COMM = 2
AF_OP_SERVER = 4
AF_OP_ACCOUNTS = 8
AF_SETTABLE_BITS = AF_OP_PRINT | AF_OP_COMM | AF_OP_SERVER | AF_OP_ACCOUNTS
UAS_ROLE_STANDALONE = 0
UAS_ROLE_MEMBER = 1
UAS_ROLE_BACKUP = 2
UAS_ROLE_PRIMARY = 3
USER_NAME_PARMNUM = 1
USER_PASSWORD_PARMNUM = 3
USER_PASSWORD_AGE_PARMNUM = 4
USER_PRIV_PARMNUM = 5
USER_HOME_DIR_PARMNUM = 6
USER_COMMENT_PARMNUM = 7
USER_FLAGS_PARMNUM = 8
USER_SCRIPT_PATH_PARMNUM = 9
USER_AUTH_FLAGS_PARMNUM = 10
USER_FULL_NAME_PARMNUM = 11
USER_USR_COMMENT_PARMNUM = 12
USER_PARMS_PARMNUM = 13
USER_WORKSTATIONS_PARMNUM = 14
USER_LAST_LOGON_PARMNUM = 15
USER_LAST_LOGOFF_PARMNUM = 16
USER_ACCT_EXPIRES_PARMNUM = 17
USER_MAX_STORAGE_PARMNUM = 18
USER_UNITS_PER_WEEK_PARMNUM = 19
USER_LOGON_HOURS_PARMNUM = 20
USER_PAD_PW_COUNT_PARMNUM = 21
USER_NUM_LOGONS_PARMNUM = 22
USER_LOGON_SERVER_PARMNUM = 23
USER_COUNTRY_CODE_PARMNUM = 24
USER_CODE_PAGE_PARMNUM = 25
USER_PRIMARY_GROUP_PARMNUM = 51
USER_PROFILE = 52
USER_PROFILE_PARMNUM = 52
USER_HOME_DIR_DRIVE_PARMNUM = 53
USER_NAME_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_NAME_PARMNUM
USER_PASSWORD_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_PASSWORD_PARMNUM
USER_PASSWORD_AGE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_PASSWORD_AGE_PARMNUM
USER_PRIV_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_PRIV_PARMNUM
USER_HOME_DIR_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_HOME_DIR_PARMNUM
USER_COMMENT_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_COMMENT_PARMNUM
USER_FLAGS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_FLAGS_PARMNUM
USER_SCRIPT_PATH_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_SCRIPT_PATH_PARMNUM
USER_AUTH_FLAGS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_AUTH_FLAGS_PARMNUM
USER_FULL_NAME_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_FULL_NAME_PARMNUM
USER_USR_COMMENT_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_USR_COMMENT_PARMNUM
USER_PARMS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_PARMS_PARMNUM
USER_WORKSTATIONS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_WORKSTATIONS_PARMNUM
USER_LAST_LOGON_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_LAST_LOGON_PARMNUM
USER_LAST_LOGOFF_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_LAST_LOGOFF_PARMNUM
USER_ACCT_EXPIRES_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_ACCT_EXPIRES_PARMNUM
USER_MAX_STORAGE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_MAX_STORAGE_PARMNUM
USER_UNITS_PER_WEEK_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_UNITS_PER_WEEK_PARMNUM
USER_LOGON_HOURS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_LOGON_HOURS_PARMNUM
USER_PAD_PW_COUNT_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_PAD_PW_COUNT_PARMNUM
USER_NUM_LOGONS_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_NUM_LOGONS_PARMNUM
USER_LOGON_SERVER_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_LOGON_SERVER_PARMNUM
USER_COUNTRY_CODE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_COUNTRY_CODE_PARMNUM
USER_CODE_PAGE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_CODE_PAGE_PARMNUM
USER_PRIMARY_GROUP_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_PRIMARY_GROUP_PARMNUM
USER_HOME_DIR_DRIVE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + USER_HOME_DIR_DRIVE_PARMNUM
NULL_USERSETINFO_PASSWD = " "
UNITS_PER_DAY = 24
UNITS_PER_WEEK = UNITS_PER_DAY * 7
USER_PRIV_MASK = 3
USER_PRIV_GUEST = 0
USER_PRIV_USER = 1
USER_PRIV_ADMIN = 2
MAX_PASSWD_LEN = PWLEN
DEF_MIN_PWLEN = 6
DEF_PWUNIQUENESS = 5
DEF_MAX_PWHIST = 8
DEF_MAX_BADPW = 0
VALIDATED_LOGON = 0
PASSWORD_EXPIRED = 2
NON_VALIDATED_LOGON = 3
VALID_LOGOFF = 1
MODALS_MIN_PASSWD_LEN_PARMNUM = 1
MODALS_MAX_PASSWD_AGE_PARMNUM = 2
MODALS_MIN_PASSWD_AGE_PARMNUM = 3
MODALS_FORCE_LOGOFF_PARMNUM = 4
MODALS_PASSWD_HIST_LEN_PARMNUM = 5
MODALS_ROLE_PARMNUM = 6
MODALS_PRIMARY_PARMNUM = 7
MODALS_DOMAIN_NAME_PARMNUM = 8
MODALS_DOMAIN_ID_PARMNUM = 9
MODALS_LOCKOUT_DURATION_PARMNUM = 10
MODALS_LOCKOUT_OBSERVATION_WINDOW_PARMNUM = 11
MODALS_LOCKOUT_THRESHOLD_PARMNUM = 12
MODALS_MIN_PASSWD_LEN_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + MODALS_MIN_PASSWD_LEN_PARMNUM
MODALS_MAX_PASSWD_AGE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + MODALS_MAX_PASSWD_AGE_PARMNUM
MODALS_MIN_PASSWD_AGE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + MODALS_MIN_PASSWD_AGE_PARMNUM
MODALS_FORCE_LOGOFF_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + MODALS_FORCE_LOGOFF_PARMNUM
MODALS_PASSWD_HIST_LEN_INFOLEVEL = (
PARMNUM_BASE_INFOLEVEL + MODALS_PASSWD_HIST_LEN_PARMNUM
)
MODALS_ROLE_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + MODALS_ROLE_PARMNUM
MODALS_PRIMARY_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + MODALS_PRIMARY_PARMNUM
MODALS_DOMAIN_NAME_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + MODALS_DOMAIN_NAME_PARMNUM
MODALS_DOMAIN_ID_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + MODALS_DOMAIN_ID_PARMNUM
GROUPIDMASK = 32768
GROUP_ALL_PARMNUM = 0
GROUP_NAME_PARMNUM = 1
GROUP_COMMENT_PARMNUM = 2
GROUP_ATTRIBUTES_PARMNUM = 3
GROUP_ALL_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + GROUP_ALL_PARMNUM
GROUP_NAME_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + GROUP_NAME_PARMNUM
GROUP_COMMENT_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + GROUP_COMMENT_PARMNUM
GROUP_ATTRIBUTES_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + GROUP_ATTRIBUTES_PARMNUM
LOCALGROUP_NAME_PARMNUM = 1
LOCALGROUP_COMMENT_PARMNUM = 2
MAXPERMENTRIES = 64
ACCESS_NONE = 0
ACCESS_READ = 1
ACCESS_WRITE = 2
ACCESS_CREATE = 4
ACCESS_EXEC = 8
ACCESS_DELETE = 16
ACCESS_ATRIB = 32
ACCESS_PERM = 64
ACCESS_GROUP = 32768
ACCESS_AUDIT = 1
ACCESS_SUCCESS_OPEN = 16
ACCESS_SUCCESS_WRITE = 32
ACCESS_SUCCESS_DELETE = 64
ACCESS_SUCCESS_ACL = 128
ACCESS_SUCCESS_MASK = 240
ACCESS_FAIL_OPEN = 256
ACCESS_FAIL_WRITE = 512
ACCESS_FAIL_DELETE = 1024
ACCESS_FAIL_ACL = 2048
ACCESS_FAIL_MASK = 3840
ACCESS_FAIL_SHIFT = 4
ACCESS_RESOURCE_NAME_PARMNUM = 1
ACCESS_ATTR_PARMNUM = 2
ACCESS_COUNT_PARMNUM = 3
ACCESS_ACCESS_LIST_PARMNUM = 4
ACCESS_RESOURCE_NAME_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + ACCESS_RESOURCE_NAME_PARMNUM
ACCESS_ATTR_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + ACCESS_ATTR_PARMNUM
ACCESS_COUNT_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + ACCESS_COUNT_PARMNUM
ACCESS_ACCESS_LIST_INFOLEVEL = PARMNUM_BASE_INFOLEVEL + ACCESS_ACCESS_LIST_PARMNUM
ACCESS_LETTERS = "RWCXDAP "
NETLOGON_CONTROL_QUERY = 1
NETLOGON_CONTROL_REPLICATE = 2
NETLOGON_CONTROL_SYNCHRONIZE = 3
NETLOGON_CONTROL_PDC_REPLICATE = 4
NETLOGON_CONTROL_REDISCOVER = 5
NETLOGON_CONTROL_TC_QUERY = 6
NETLOGON_CONTROL_TRANSPORT_NOTIFY = 7
NETLOGON_CONTROL_FIND_USER = 8
NETLOGON_CONTROL_UNLOAD_NETLOGON_DLL = 65531
NETLOGON_CONTROL_BACKUP_CHANGE_LOG = 65532
NETLOGON_CONTROL_TRUNCATE_LOG = 65533
NETLOGON_CONTROL_SET_DBFLAG = 65534
NETLOGON_CONTROL_BREAKPOINT = 65535
NETLOGON_REPLICATION_NEEDED = 1
NETLOGON_REPLICATION_IN_PROGRESS = 2
NETLOGON_FULL_SYNC_REPLICATION = 4
NETLOGON_REDO_NEEDED = 8
######################
# Manual stuff
TEXT = lambda x: x
MAX_PREFERRED_LENGTH = -1
PARM_ERROR_UNKNOWN = -1
MESSAGE_FILENAME = TEXT("NETMSG")
OS2MSG_FILENAME = TEXT("BASE")
HELP_MSG_FILENAME = TEXT("NETH")
BACKUP_MSG_FILENAME = TEXT("BAK.MSG")
TIMEQ_FOREVER = -1
USER_MAXSTORAGE_UNLIMITED = -1
USER_NO_LOGOFF = -1
DEF_MAX_PWAGE = TIMEQ_FOREVER
DEF_MIN_PWAGE = 0
DEF_FORCE_LOGOFF = -1
ONE_DAY = 1 * 24 * 3600
GROUP_SPECIALGRP_USERS = "USERS"
GROUP_SPECIALGRP_ADMINS = "ADMINS"
GROUP_SPECIALGRP_GUESTS = "GUESTS"
GROUP_SPECIALGRP_LOCAL = "LOCAL"
ACCESS_ALL = (
ACCESS_READ
| ACCESS_WRITE
| ACCESS_CREATE
| ACCESS_EXEC
| ACCESS_DELETE
| ACCESS_ATRIB
| ACCESS_PERM
)
# From lmserver.h
SV_PLATFORM_ID_OS2 = 400
SV_PLATFORM_ID_NT = 500
MAJOR_VERSION_MASK = 15
SV_TYPE_WORKSTATION = 1
SV_TYPE_SERVER = 2
SV_TYPE_SQLSERVER = 4
SV_TYPE_DOMAIN_CTRL = 8
SV_TYPE_DOMAIN_BAKCTRL = 16
SV_TYPE_TIME_SOURCE = 32
SV_TYPE_AFP = 64
SV_TYPE_NOVELL = 128
SV_TYPE_DOMAIN_MEMBER = 256
SV_TYPE_PRINTQ_SERVER = 512
SV_TYPE_DIALIN_SERVER = 1024
SV_TYPE_XENIX_SERVER = 2048
SV_TYPE_SERVER_UNIX = SV_TYPE_XENIX_SERVER
SV_TYPE_NT = 4096
SV_TYPE_WFW = 8192
SV_TYPE_SERVER_MFPN = 16384
SV_TYPE_SERVER_NT = 32768
SV_TYPE_POTENTIAL_BROWSER = 65536
SV_TYPE_BACKUP_BROWSER = 131072
SV_TYPE_MASTER_BROWSER = 262144
SV_TYPE_DOMAIN_MASTER = 524288
SV_TYPE_SERVER_OSF = 1048576
SV_TYPE_SERVER_VMS = 2097152
SV_TYPE_WINDOWS = 4194304
SV_TYPE_DFS = 8388608
SV_TYPE_CLUSTER_NT = 16777216
SV_TYPE_DCE = 268435456
SV_TYPE_ALTERNATE_XPORT = 536870912
SV_TYPE_LOCAL_LIST_ONLY = 1073741824
SV_TYPE_DOMAIN_ENUM = -2147483648
SV_TYPE_ALL = -1
SV_NODISC = -1
SV_USERSECURITY = 1
SV_SHARESECURITY = 0
SV_HIDDEN = 1
SV_VISIBLE = 0
SV_PLATFORM_ID_PARMNUM = 101
SV_NAME_PARMNUM = 102
SV_VERSION_MAJOR_PARMNUM = 103
SV_VERSION_MINOR_PARMNUM = 104
SV_TYPE_PARMNUM = 105
SV_COMMENT_PARMNUM = 5
SV_USERS_PARMNUM = 107
SV_DISC_PARMNUM = 10
SV_HIDDEN_PARMNUM = 16
SV_ANNOUNCE_PARMNUM = 17
SV_ANNDELTA_PARMNUM = 18
SV_USERPATH_PARMNUM = 112
SV_ULIST_MTIME_PARMNUM = 401
SV_GLIST_MTIME_PARMNUM = 402
SV_ALIST_MTIME_PARMNUM = 403
SV_ALERTS_PARMNUM = 11
SV_SECURITY_PARMNUM = 405
SV_NUMADMIN_PARMNUM = 406
SV_LANMASK_PARMNUM = 407
SV_GUESTACC_PARMNUM = 408
SV_CHDEVQ_PARMNUM = 410
SV_CHDEVJOBS_PARMNUM = 411
SV_CONNECTIONS_PARMNUM = 412
SV_SHARES_PARMNUM = 413
SV_OPENFILES_PARMNUM = 414
SV_SESSREQS_PARMNUM = 417
SV_ACTIVELOCKS_PARMNUM = 419
SV_NUMREQBUF_PARMNUM = 420
SV_NUMBIGBUF_PARMNUM = 422
SV_NUMFILETASKS_PARMNUM = 423
SV_ALERTSCHED_PARMNUM = 37
SV_ERRORALERT_PARMNUM = 38
SV_LOGONALERT_PARMNUM = 39
SV_ACCESSALERT_PARMNUM = 40
SV_DISKALERT_PARMNUM = 41
SV_NETIOALERT_PARMNUM = 42
SV_MAXAUDITSZ_PARMNUM = 43
SV_SRVHEURISTICS_PARMNUM = 431
SV_SESSOPENS_PARMNUM = 501
SV_SESSVCS_PARMNUM = 502
SV_OPENSEARCH_PARMNUM = 503
SV_SIZREQBUF_PARMNUM = 504
SV_INITWORKITEMS_PARMNUM = 505
SV_MAXWORKITEMS_PARMNUM = 506
SV_RAWWORKITEMS_PARMNUM = 507
SV_IRPSTACKSIZE_PARMNUM = 508
SV_MAXRAWBUFLEN_PARMNUM = 509
SV_SESSUSERS_PARMNUM = 510
SV_SESSCONNS_PARMNUM = 511
SV_MAXNONPAGEDMEMORYUSAGE_PARMNUM = 512
SV_MAXPAGEDMEMORYUSAGE_PARMNUM = 513
SV_ENABLESOFTCOMPAT_PARMNUM = 514
SV_ENABLEFORCEDLOGOFF_PARMNUM = 515
SV_TIMESOURCE_PARMNUM = 516
SV_ACCEPTDOWNLEVELAPIS_PARMNUM = 517
SV_LMANNOUNCE_PARMNUM = 518
SV_DOMAIN_PARMNUM = 519
SV_MAXCOPYREADLEN_PARMNUM = 520
SV_MAXCOPYWRITELEN_PARMNUM = 521
SV_MINKEEPSEARCH_PARMNUM = 522
SV_MAXKEEPSEARCH_PARMNUM = 523
SV_MINKEEPCOMPLSEARCH_PARMNUM = 524
SV_MAXKEEPCOMPLSEARCH_PARMNUM = 525
SV_THREADCOUNTADD_PARMNUM = 526
SV_NUMBLOCKTHREADS_PARMNUM = 527
SV_SCAVTIMEOUT_PARMNUM = 528
SV_MINRCVQUEUE_PARMNUM = 529
SV_MINFREEWORKITEMS_PARMNUM = 530
SV_XACTMEMSIZE_PARMNUM = 531
SV_THREADPRIORITY_PARMNUM = 532
SV_MAXMPXCT_PARMNUM = 533
SV_OPLOCKBREAKWAIT_PARMNUM = 534
SV_OPLOCKBREAKRESPONSEWAIT_PARMNUM = 535
SV_ENABLEOPLOCKS_PARMNUM = 536
SV_ENABLEOPLOCKFORCECLOSE_PARMNUM = 537
SV_ENABLEFCBOPENS_PARMNUM = 538
SV_ENABLERAW_PARMNUM = 539
SV_ENABLESHAREDNETDRIVES_PARMNUM = 540
SV_MINFREECONNECTIONS_PARMNUM = 541
SV_MAXFREECONNECTIONS_PARMNUM = 542
SV_INITSESSTABLE_PARMNUM = 543
SV_INITCONNTABLE_PARMNUM = 544
SV_INITFILETABLE_PARMNUM = 545
SV_INITSEARCHTABLE_PARMNUM = 546
SV_ALERTSCHEDULE_PARMNUM = 547
SV_ERRORTHRESHOLD_PARMNUM = 548
SV_NETWORKERRORTHRESHOLD_PARMNUM = 549
SV_DISKSPACETHRESHOLD_PARMNUM = 550
SV_MAXLINKDELAY_PARMNUM = 552
SV_MINLINKTHROUGHPUT_PARMNUM = 553
SV_LINKINFOVALIDTIME_PARMNUM = 554
SV_SCAVQOSINFOUPDATETIME_PARMNUM = 555
SV_MAXWORKITEMIDLETIME_PARMNUM = 556
SV_MAXRAWWORKITEMS_PARMNUM = 557
SV_PRODUCTTYPE_PARMNUM = 560
SV_SERVERSIZE_PARMNUM = 561
SV_CONNECTIONLESSAUTODISC_PARMNUM = 562
SV_SHARINGVIOLATIONRETRIES_PARMNUM = 563
SV_SHARINGVIOLATIONDELAY_PARMNUM = 564
SV_MAXGLOBALOPENSEARCH_PARMNUM = 565
SV_REMOVEDUPLICATESEARCHES_PARMNUM = 566
SV_LOCKVIOLATIONRETRIES_PARMNUM = 567
SV_LOCKVIOLATIONOFFSET_PARMNUM = 568
SV_LOCKVIOLATIONDELAY_PARMNUM = 569
SV_MDLREADSWITCHOVER_PARMNUM = 570
SV_CACHEDOPENLIMIT_PARMNUM = 571
SV_CRITICALTHREADS_PARMNUM = 572
SV_RESTRICTNULLSESSACCESS_PARMNUM = 573
SV_ENABLEWFW311DIRECTIPX_PARMNUM = 574
SV_OTHERQUEUEAFFINITY_PARMNUM = 575
SV_QUEUESAMPLESECS_PARMNUM = 576
SV_BALANCECOUNT_PARMNUM = 577
SV_PREFERREDAFFINITY_PARMNUM = 578
SV_MAXFREERFCBS_PARMNUM = 579
SV_MAXFREEMFCBS_PARMNUM = 580
SV_MAXFREELFCBS_PARMNUM = 581
SV_MAXFREEPAGEDPOOLCHUNKS_PARMNUM = 582
SV_MINPAGEDPOOLCHUNKSIZE_PARMNUM = 583
SV_MAXPAGEDPOOLCHUNKSIZE_PARMNUM = 584
SV_SENDSFROMPREFERREDPROCESSOR_PARMNUM = 585
SV_MAXTHREADSPERQUEUE_PARMNUM = 586
SV_CACHEDDIRECTORYLIMIT_PARMNUM = 587
SV_MAXCOPYLENGTH_PARMNUM = 588
SV_ENABLEBULKTRANSFER_PARMNUM = 589
SV_ENABLECOMPRESSION_PARMNUM = 590
SV_AUTOSHAREWKS_PARMNUM = 591
SV_AUTOSHARESERVER_PARMNUM = 592
SV_ENABLESECURITYSIGNATURE_PARMNUM = 593
SV_REQUIRESECURITYSIGNATURE_PARMNUM = 594
SV_MINCLIENTBUFFERSIZE_PARMNUM = 595
SV_CONNECTIONNOSESSIONSTIMEOUT_PARMNUM = 596
SVI1_NUM_ELEMENTS = 5
SVI2_NUM_ELEMENTS = 40
SVI3_NUM_ELEMENTS = 44
SW_AUTOPROF_LOAD_MASK = 1
SW_AUTOPROF_SAVE_MASK = 2
SV_MAX_SRV_HEUR_LEN = 32
SV_USERS_PER_LICENSE = 5
SVTI2_REMAP_PIPE_NAMES = 2
# Generated by h2py from lmshare.h
SHARE_NETNAME_PARMNUM = 1
SHARE_TYPE_PARMNUM = 3
SHARE_REMARK_PARMNUM = 4
SHARE_PERMISSIONS_PARMNUM = 5
SHARE_MAX_USES_PARMNUM = 6
SHARE_CURRENT_USES_PARMNUM = 7
SHARE_PATH_PARMNUM = 8
SHARE_PASSWD_PARMNUM = 9
SHARE_FILE_SD_PARMNUM = 501
SHI1_NUM_ELEMENTS = 4
SHI2_NUM_ELEMENTS = 10
STYPE_DISKTREE = 0
STYPE_PRINTQ = 1
STYPE_DEVICE = 2
STYPE_IPC = 3
STYPE_SPECIAL = -2147483648
SHI1005_FLAGS_DFS = 1
SHI1005_FLAGS_DFS_ROOT = 2
COW_PERMACHINE = 4
COW_PERUSER = 8
CSC_CACHEABLE = 16
CSC_NOFLOWOPS = 32
CSC_AUTO_INWARD = 64
CSC_AUTO_OUTWARD = 128
SHI1005_VALID_FLAGS_SET = (
CSC_CACHEABLE
| CSC_NOFLOWOPS
| CSC_AUTO_INWARD
| CSC_AUTO_OUTWARD
| COW_PERMACHINE
| COW_PERUSER
)
SHI1007_VALID_FLAGS_SET = SHI1005_VALID_FLAGS_SET
SESS_GUEST = 1
SESS_NOENCRYPTION = 2
SESI1_NUM_ELEMENTS = 8
SESI2_NUM_ELEMENTS = 9
PERM_FILE_READ = 1
PERM_FILE_WRITE = 2
PERM_FILE_CREATE = 4
# Generated by h2py from d:\mssdk\include\winnetwk.h
WNNC_NET_MSNET = 65536
WNNC_NET_LANMAN = 131072
WNNC_NET_NETWARE = 196608
WNNC_NET_VINES = 262144
WNNC_NET_10NET = 327680
WNNC_NET_LOCUS = 393216
WNNC_NET_SUN_PC_NFS = 458752
WNNC_NET_LANSTEP = 524288
WNNC_NET_9TILES = 589824
WNNC_NET_LANTASTIC = 655360
WNNC_NET_AS400 = 720896
WNNC_NET_FTP_NFS = 786432
WNNC_NET_PATHWORKS = 851968
WNNC_NET_LIFENET = 917504
WNNC_NET_POWERLAN = 983040
WNNC_NET_BWNFS = 1048576
WNNC_NET_COGENT = 1114112
WNNC_NET_FARALLON = 1179648
WNNC_NET_APPLETALK = 1245184
WNNC_NET_INTERGRAPH = 1310720
WNNC_NET_SYMFONET = 1376256
WNNC_NET_CLEARCASE = 1441792
WNNC_NET_FRONTIER = 1507328
WNNC_NET_BMC = 1572864
WNNC_NET_DCE = 1638400
WNNC_NET_DECORB = 2097152
WNNC_NET_PROTSTOR = 2162688
WNNC_NET_FJ_REDIR = 2228224
WNNC_NET_DISTINCT = 2293760
WNNC_NET_TWINS = 2359296
WNNC_NET_RDR2SAMPLE = 2424832
RESOURCE_CONNECTED = 1
RESOURCE_GLOBALNET = 2
RESOURCE_REMEMBERED = 3
RESOURCE_RECENT = 4
RESOURCE_CONTEXT = 5
RESOURCETYPE_ANY = 0
RESOURCETYPE_DISK = 1
RESOURCETYPE_PRINT = 2
RESOURCETYPE_RESERVED = 8
RESOURCETYPE_UNKNOWN = -1
RESOURCEUSAGE_CONNECTABLE = 1
RESOURCEUSAGE_CONTAINER = 2
RESOURCEUSAGE_NOLOCALDEVICE = 4
RESOURCEUSAGE_SIBLING = 8
RESOURCEUSAGE_ATTACHED = 16
RESOURCEUSAGE_ALL = (
RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED
)
RESOURCEUSAGE_RESERVED = -2147483648
RESOURCEDISPLAYTYPE_GENERIC = 0
RESOURCEDISPLAYTYPE_DOMAIN = 1
RESOURCEDISPLAYTYPE_SERVER = 2
RESOURCEDISPLAYTYPE_SHARE = 3
RESOURCEDISPLAYTYPE_FILE = 4
RESOURCEDISPLAYTYPE_GROUP = 5
RESOURCEDISPLAYTYPE_NETWORK = 6
RESOURCEDISPLAYTYPE_ROOT = 7
RESOURCEDISPLAYTYPE_SHAREADMIN = 8
RESOURCEDISPLAYTYPE_DIRECTORY = 9
RESOURCEDISPLAYTYPE_TREE = 10
RESOURCEDISPLAYTYPE_NDSCONTAINER = 11
NETPROPERTY_PERSISTENT = 1
CONNECT_UPDATE_PROFILE = 1
CONNECT_UPDATE_RECENT = 2
CONNECT_TEMPORARY = 4
CONNECT_INTERACTIVE = 8
CONNECT_PROMPT = 16
CONNECT_NEED_DRIVE = 32
CONNECT_REFCOUNT = 64
CONNECT_REDIRECT = 128
CONNECT_LOCALDRIVE = 256
CONNECT_CURRENT_MEDIA = 512
CONNECT_DEFERRED = 1024
CONNECT_RESERVED = -16777216
CONNDLG_RO_PATH = 1
CONNDLG_CONN_POINT = 2
CONNDLG_USE_MRU = 4
CONNDLG_HIDE_BOX = 8
CONNDLG_PERSIST = 16
CONNDLG_NOT_PERSIST = 32
DISC_UPDATE_PROFILE = 1
DISC_NO_FORCE = 64
UNIVERSAL_NAME_INFO_LEVEL = 1
REMOTE_NAME_INFO_LEVEL = 2
WNFMT_MULTILINE = 1
WNFMT_ABBREVIATED = 2
WNFMT_INENUM = 16
WNFMT_CONNECTION = 32
NETINFO_DLL16 = 1
NETINFO_DISKRED = 4
NETINFO_PRINTERRED = 8
RP_LOGON = 1
RP_INIFILE = 2
PP_DISPLAYERRORS = 1
WNCON_FORNETCARD = 1
WNCON_NOTROUTED = 2
WNCON_SLOWLINK = 4
WNCON_DYNAMIC = 8
## NETSETUP_NAME_TYPE, used with NetValidateName
NetSetupUnknown = 0
NetSetupMachine = 1
NetSetupWorkgroup = 2
NetSetupDomain = 3
NetSetupNonExistentDomain = 4
NetSetupDnsMachine = 5
## NETSETUP_JOIN_STATUS, use with NetGetJoinInformation
NetSetupUnknownStatus = 0
NetSetupUnjoined = 1
NetSetupWorkgroupName = 2
NetSetupDomainName = 3
NetValidateAuthentication = 1
NetValidatePasswordChange = 2
NetValidatePasswordReset = 3

View file

@ -0,0 +1,571 @@
"""
Performance Data Helper (PDH) Query Classes
Wrapper classes for end-users and high-level access to the PDH query
mechanisms. PDH is a win32-specific mechanism for accessing the
performance data made available by the system. The Python for Windows
PDH module does not implement the "Registry" interface, implementing
the more straightforward Query-based mechanism.
The basic idea of a PDH Query is an object which can query the system
about the status of any number of "counters." The counters are paths
to a particular piece of performance data. For instance, the path
'\\Memory\\Available Bytes' describes just about exactly what it says
it does, the amount of free memory on the default computer expressed
in Bytes. These paths can be considerably more complex than this,
but part of the point of this wrapper module is to hide that
complexity from the end-user/programmer.
EXAMPLE: A more complex Path
'\\\\RAISTLIN\\PhysicalDisk(_Total)\\Avg. Disk Bytes/Read'
Raistlin --> Computer Name
PhysicalDisk --> Object Name
_Total --> The particular Instance (in this case, all instances, i.e. all drives)
Avg. Disk Bytes/Read --> The piece of data being monitored.
EXAMPLE: Collecting Data with a Query
As an example, the following code implements a logger which allows the
user to choose what counters they would like to log, and logs those
counters for 30 seconds, at two-second intervals.
query = Query()
query.addcounterbybrowsing()
query.collectdatafor(30,2)
The data is now stored in a list of lists as:
query.curresults
The counters(paths) which were used to collect the data are:
query.curpaths
You can use the win32pdh.ParseCounterPath(path) utility function
to turn the paths into more easily read values for your task, or
write the data to a file, or do whatever you want with it.
OTHER NOTABLE METHODS:
query.collectdatawhile(period) # start a logging thread for collecting data
query.collectdatawhile_stop() # signal the logging thread to stop logging
query.collectdata() # run the query only once
query.addperfcounter(object, counter, machine=None) # add a standard performance counter
query.addinstcounter(object, counter,machine=None,objtype = 'Process',volatile=1,format = win32pdh.PDH_FMT_LONG) # add a possibly volatile counter
### Known bugs and limitations ###
Due to a problem with threading under the PythonWin interpreter, there
will be no data logged if the PythonWin window is not the foreground
application. Workaround: scripts using threading should be run in the
python.exe interpreter.
The volatile-counter handlers are possibly buggy, they haven't been
tested to any extent. The wrapper Query makes it safe to pass invalid
paths (a -1 will be returned, or the Query will be totally ignored,
depending on the missing element), so you should be able to work around
the error by including all possible paths and filtering out the -1's.
There is no way I know of to stop a thread which is currently sleeping,
so you have to wait until the thread in collectdatawhile is activated
again. This might become a problem in situations where the collection
period is multiple minutes (or hours, or whatever).
Should make the win32pdh.ParseCounter function available to the Query
classes as a method or something similar, so that it can be accessed
by programmes that have just picked up an instance from somewhere.
Should explicitly mention where QueryErrors can be raised, and create a
full test set to see if there are any uncaught win32api.error's still
hanging around.
When using the python.exe interpreter, the addcounterbybrowsing-
generated browser window is often hidden behind other windows. No known
workaround other than Alt-tabing to reach the browser window.
### Other References ###
The win32pdhutil module (which should be in the %pythonroot%/win32/lib
directory) provides quick-and-dirty utilities for one-off access to
variables from the PDH. Almost everything in that module can be done
with a Query object, but it provides task-oriented functions for a
number of common one-off tasks.
If you can access the MS Developers Network Library, you can find
information about the PDH API as MS describes it. For a background article,
try:
http://msdn.microsoft.com/library/en-us/dnperfmo/html/msdn_pdhlib.asp
The reference guide for the PDH API was last spotted at:
http://msdn.microsoft.com/library/en-us/perfmon/base/using_the_pdh_interface.asp
In general the Python version of the API is just a wrapper around the
Query-based version of this API (as far as I can see), so you can learn what
you need to from there. From what I understand, the MSDN Online
resources are available for the price of signing up for them. I can't
guarantee how long that's supposed to last. (Or anything for that
matter).
http://premium.microsoft.com/isapi/devonly/prodinfo/msdnprod/msdnlib.idc?theURL=/msdn/library/sdkdoc/perfdata_4982.htm
The eventual plan is for my (Mike Fletcher's) Starship account to include
a section on NT Administration, and the Query is the first project
in this plan. There should be an article describing the creation of
a simple logger there, but the example above is 90% of the work of
that project, so don't sweat it if you don't find anything there.
(currently the account hasn't been set up).
http://starship.skyport.net/crew/mcfletch/
If you need to contact me immediately, (why I can't imagine), you can
email me at mcfletch@golden.net, or just post your question to the
Python newsgroup with a catchy subject line.
news:comp.lang.python
### Other Stuff ###
The Query classes are by Mike Fletcher, with the working code
being corruptions of Mark Hammonds win32pdhutil module.
Use at your own risk, no warranties, no guarantees, no assurances,
if you use it, you accept the risk of using it, etceteras.
"""
# Feb 12, 98 - MH added "rawaddcounter" so caller can get exception details.
import _thread
import copy
import time
import win32api
import win32pdh
class BaseQuery:
"""
Provides wrapped access to the Performance Data Helper query
objects, generally you should use the child class Query
unless you have need of doing weird things :)
This class supports two major working paradigms. In the first,
you open the query, and run it as many times as you need, closing
the query when you're done with it. This is suitable for static
queries (ones where processes being monitored don't disappear).
In the second, you allow the query to be opened each time and
closed afterward. This causes the base query object to be
destroyed after each call. Suitable for dynamic queries (ones
which watch processes which might be closed while watching.)
"""
def __init__(self, paths=None):
"""
The PDH Query object is initialised with a single, optional
list argument, that must be properly formatted PDH Counter
paths. Generally this list will only be provided by the class
when it is being unpickled (removed from storage). Normal
use is to call the class with no arguments and use the various
addcounter functions (particularly, for end user's, the use of
addcounterbybrowsing is the most common approach) You might
want to provide the list directly if you want to hard-code the
elements with which your query deals (and thereby avoid the
overhead of unpickling the class).
"""
self.counters = []
if paths:
self.paths = paths
else:
self.paths = []
self._base = None
self.active = 0
self.curpaths = []
def addcounterbybrowsing(
self, flags=win32pdh.PERF_DETAIL_WIZARD, windowtitle="Python Browser"
):
"""
Adds possibly multiple paths to the paths attribute of the query,
does this by calling the standard counter browsing dialogue. Within
this dialogue, find the counter you want to log, and click: Add,
repeat for every path you want to log, then click on close. The
paths are appended to the non-volatile paths list for this class,
subclasses may create a function which parses the paths and decides
(via heuristics) whether to add the path to the volatile or non-volatile
path list.
e.g.:
query.addcounter()
"""
win32pdh.BrowseCounters(None, 0, self.paths.append, flags, windowtitle)
def rawaddcounter(self, object, counter, instance=None, inum=-1, machine=None):
"""
Adds a single counter path, without catching any exceptions.
See addcounter for details.
"""
path = win32pdh.MakeCounterPath(
(machine, object, instance, None, inum, counter)
)
self.paths.append(path)
def addcounter(self, object, counter, instance=None, inum=-1, machine=None):
"""
Adds a single counter path to the paths attribute. Normally
this will be called by a child class' speciality functions,
rather than being called directly by the user. (Though it isn't
hard to call manually, since almost everything is given a default)
This method is only functional when the query is closed (or hasn't
yet been opened). This is to prevent conflict in multi-threaded
query applications).
e.g.:
query.addcounter('Memory','Available Bytes')
"""
if not self.active:
try:
self.rawaddcounter(object, counter, instance, inum, machine)
return 0
except win32api.error:
return -1
else:
return -1
def open(self):
"""
Build the base query object for this wrapper,
then add all of the counters required for the query.
Raise a QueryError if we can't complete the functions.
If we are already open, then do nothing.
"""
if not self.active: # to prevent having multiple open queries
# curpaths are made accessible here because of the possibility of volatile paths
# which may be dynamically altered by subclasses.
self.curpaths = copy.copy(self.paths)
try:
base = win32pdh.OpenQuery()
for path in self.paths:
try:
self.counters.append(win32pdh.AddCounter(base, path))
except win32api.error: # we passed a bad path
self.counters.append(0)
pass
self._base = base
self.active = 1
return 0 # open succeeded
except: # if we encounter any errors, kill the Query
try:
self.killbase(base)
except NameError: # failed in creating query
pass
self.active = 0
self.curpaths = []
raise QueryError(self)
return 1 # already open
def killbase(self, base=None):
"""
### This is not a public method
Mission critical function to kill the win32pdh objects held
by this object. User's should generally use the close method
instead of this method, in case a sub-class has overridden
close to provide some special functionality.
"""
# Kill Pythonic references to the objects in this object's namespace
self._base = None
counters = self.counters
self.counters = []
# we don't kill the curpaths for convenience, this allows the
# user to close a query and still access the last paths
self.active = 0
# Now call the delete functions on all of the objects
try:
map(win32pdh.RemoveCounter, counters)
except:
pass
try:
win32pdh.CloseQuery(base)
except:
pass
del counters
del base
def close(self):
"""
Makes certain that the underlying query object has been closed,
and that all counters have been removed from it. This is
important for reference counting.
You should only need to call close if you have previously called
open. The collectdata methods all can handle opening and
closing the query. Calling close multiple times is acceptable.
"""
try:
self.killbase(self._base)
except AttributeError:
self.killbase()
__del__ = close
def collectdata(self, format=win32pdh.PDH_FMT_LONG):
"""
Returns the formatted current values for the Query
"""
if self._base: # we are currently open, don't change this
return self.collectdataslave(format)
else: # need to open and then close the _base, should be used by one-offs and elements tracking application instances
self.open() # will raise QueryError if couldn't open the query
temp = self.collectdataslave(format)
self.close() # will always close
return temp
def collectdataslave(self, format=win32pdh.PDH_FMT_LONG):
"""
### Not a public method
Called only when the Query is known to be open, runs over
the whole set of counters, appending results to the temp,
returns the values as a list.
"""
try:
win32pdh.CollectQueryData(self._base)
temp = []
for counter in self.counters:
ok = 0
try:
if counter:
temp.append(
win32pdh.GetFormattedCounterValue(counter, format)[1]
)
ok = 1
except win32api.error:
pass
if not ok:
temp.append(-1) # a better way to signal failure???
return temp
except (
win32api.error
): # will happen if, for instance, no counters are part of the query and we attempt to collect data for it.
return [-1] * len(self.counters)
# pickle functions
def __getinitargs__(self):
"""
### Not a public method
"""
return (self.paths,)
class Query(BaseQuery):
"""
Performance Data Helper(PDH) Query object:
Provides a wrapper around the native PDH query object which
allows for query reuse, query storage, and general maintenance
functions (adding counter paths in various ways being the most
obvious ones).
"""
def __init__(self, *args, **namedargs):
"""
The PDH Query object is initialised with a single, optional
list argument, that must be properly formatted PDH Counter
paths. Generally this list will only be provided by the class
when it is being unpickled (removed from storage). Normal
use is to call the class with no arguments and use the various
addcounter functions (particularly, for end user's, the use of
addcounterbybrowsing is the most common approach) You might
want to provide the list directly if you want to hard-code the
elements with which your query deals (and thereby avoid the
overhead of unpickling the class).
"""
self.volatilecounters = []
BaseQuery.__init__(*(self,) + args, **namedargs)
def addperfcounter(self, object, counter, machine=None):
"""
A "Performance Counter" is a stable, known, common counter,
such as Memory, or Processor. The use of addperfcounter by
end-users is deprecated, since the use of
addcounterbybrowsing is considerably more flexible and general.
It is provided here to allow the easy development of scripts
which need to access variables so common we know them by name
(such as Memory|Available Bytes), and to provide symmetry with
the add inst counter method.
usage:
query.addperfcounter('Memory', 'Available Bytes')
It is just as easy to access addcounter directly, the following
has an identicle effect.
query.addcounter('Memory', 'Available Bytes')
"""
BaseQuery.addcounter(self, object=object, counter=counter, machine=machine)
def addinstcounter(
self,
object,
counter,
machine=None,
objtype="Process",
volatile=1,
format=win32pdh.PDH_FMT_LONG,
):
"""
The purpose of using an instcounter is to track particular
instances of a counter object (e.g. a single processor, a single
running copy of a process). For instance, to track all python.exe
instances, you would need merely to ask:
query.addinstcounter('python','Virtual Bytes')
You can find the names of the objects and their available counters
by doing an addcounterbybrowsing() call on a query object (or by
looking in performance monitor's add dialog.)
Beyond merely rearranging the call arguments to make more sense,
if the volatile flag is true, the instcounters also recalculate
the paths of the available instances on every call to open the
query.
"""
if volatile:
self.volatilecounters.append((object, counter, machine, objtype, format))
else:
self.paths[len(self.paths) :] = self.getinstpaths(
object, counter, machine, objtype, format
)
def getinstpaths(
self,
object,
counter,
machine=None,
objtype="Process",
format=win32pdh.PDH_FMT_LONG,
):
"""
### Not an end-user function
Calculate the paths for an instance object. Should alter
to allow processing for lists of object-counter pairs.
"""
items, instances = win32pdh.EnumObjectItems(None, None, objtype, -1)
# find out how many instances of this element we have...
instances.sort()
try:
cur = instances.index(object)
except ValueError:
return [] # no instances of this object
temp = [object]
try:
while instances[cur + 1] == object:
temp.append(object)
cur = cur + 1
except IndexError: # if we went over the end
pass
paths = []
for ind in range(len(temp)):
# can this raise an error?
paths.append(
win32pdh.MakeCounterPath(
(machine, "Process", object, None, ind, counter)
)
)
return paths # should also return the number of elements for naming purposes
def open(self, *args, **namedargs):
"""
Explicitly open a query:
When you are needing to make multiple calls to the same query,
it is most efficient to open the query, run all of the calls,
then close the query, instead of having the collectdata method
automatically open and close the query each time it runs.
There are currently no arguments to open.
"""
# do all the normal opening stuff, self._base is now the query object
BaseQuery.open(*(self,) + args, **namedargs)
# should rewrite getinstpaths to take a single tuple
paths = []
for tup in self.volatilecounters:
paths[len(paths) :] = self.getinstpaths(*tup)
for path in paths:
try:
self.counters.append(win32pdh.AddCounter(self._base, path))
self.curpaths.append(
path
) # if we fail on the line above, this path won't be in the table or the counters
except win32api.error:
pass # again, what to do with a malformed path???
def collectdatafor(self, totalperiod, period=1):
"""
Non-threaded collection of performance data:
This method allows you to specify the total period for which you would
like to run the Query, and the time interval between individual
runs. The collected data is stored in query.curresults at the
_end_ of the run. The pathnames for the query are stored in
query.curpaths.
e.g.:
query.collectdatafor(30,2)
Will collect data for 30seconds at 2 second intervals
"""
tempresults = []
try:
self.open()
for ind in range(totalperiod / period):
tempresults.append(self.collectdata())
time.sleep(period)
self.curresults = tempresults
finally:
self.close()
def collectdatawhile(self, period=1):
"""
Threaded collection of performance data:
This method sets up a simple semaphor system for signalling
when you would like to start and stop a threaded data collection
method. The collection runs every period seconds until the
semaphor attribute is set to a non-true value (which normally
should be done by calling query.collectdatawhile_stop() .)
e.g.:
query.collectdatawhile(2)
# starts the query running, returns control to the caller immediately
# is collecting data every two seconds.
# do whatever you want to do while the thread runs, then call:
query.collectdatawhile_stop()
# when you want to deal with the data. It is generally a good idea
# to sleep for period seconds yourself, since the query will not copy
# the required data until the next iteration:
time.sleep(2)
# now you can access the data from the attributes of the query
query.curresults
query.curpaths
"""
self.collectdatawhile_active = 1
_thread.start_new_thread(self.collectdatawhile_slave, (period,))
def collectdatawhile_stop(self):
"""
Signals the collectdatawhile slave thread to stop collecting data
on the next logging iteration.
"""
self.collectdatawhile_active = 0
def collectdatawhile_slave(self, period):
"""
### Not a public function
Does the threaded work of collecting the data and storing it
in an attribute of the class.
"""
tempresults = []
try:
self.open() # also sets active, so can't be changed.
while self.collectdatawhile_active:
tempresults.append(self.collectdata())
time.sleep(period)
self.curresults = tempresults
finally:
self.close()
# pickle functions
def __getinitargs__(self):
return (self.paths,)
def __getstate__(self):
return self.volatilecounters
def __setstate__(self, volatilecounters):
self.volatilecounters = volatilecounters
class QueryError:
def __init__(self, query):
self.query = query
def __repr__(self):
return "<Query Error in %s>" % repr(self.query)
__str__ = __repr__

View file

@ -0,0 +1,210 @@
"""Utilities for the win32 Performance Data Helper module
Example:
To get a single bit of data:
>>> import win32pdhutil
>>> win32pdhutil.GetPerformanceAttributes("Memory", "Available Bytes")
6053888
>>> win32pdhutil.FindPerformanceAttributesByName("python", counter="Virtual Bytes")
[22278144]
First example returns data which is not associated with any specific instance.
The second example reads data for a specific instance - hence the list return -
it would return one result for each instance of Python running.
In general, it can be tricky finding exactly the "name" of the data you wish to query.
Although you can use <om win32pdh.EnumObjectItems>(None,None,(eg)"Memory", -1) to do this,
the easiest way is often to simply use PerfMon to find out the names.
"""
import time
import win32pdh
error = win32pdh.error
# Handle some localization issues.
# see http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q287/1/59.asp&NoWebContent=1
# Build a map of english_counter_name: counter_id
counter_english_map = {}
def find_pdh_counter_localized_name(english_name, machine_name=None):
if not counter_english_map:
import win32api
import win32con
counter_reg_value = win32api.RegQueryValueEx(
win32con.HKEY_PERFORMANCE_DATA, "Counter 009"
)
counter_list = counter_reg_value[0]
for i in range(0, len(counter_list) - 1, 2):
try:
counter_id = int(counter_list[i])
except ValueError:
continue
counter_english_map[counter_list[i + 1].lower()] = counter_id
return win32pdh.LookupPerfNameByIndex(
machine_name, counter_english_map[english_name.lower()]
)
def GetPerformanceAttributes(
object, counter, instance=None, inum=-1, format=win32pdh.PDH_FMT_LONG, machine=None
):
# NOTE: Many counters require 2 samples to give accurate results,
# including "% Processor Time" (as by definition, at any instant, a
# thread's CPU usage is either 0 or 100). To read counters like this,
# you should copy this function, but keep the counter open, and call
# CollectQueryData() each time you need to know.
# See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q262938
# and http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp
# My older explanation for this was that the "AddCounter" process forced
# the CPU to 100%, but the above makes more sense :)
path = win32pdh.MakeCounterPath((machine, object, instance, None, inum, counter))
hq = win32pdh.OpenQuery()
try:
hc = win32pdh.AddCounter(hq, path)
try:
win32pdh.CollectQueryData(hq)
type, val = win32pdh.GetFormattedCounterValue(hc, format)
return val
finally:
win32pdh.RemoveCounter(hc)
finally:
win32pdh.CloseQuery(hq)
def FindPerformanceAttributesByName(
instanceName,
object=None,
counter=None,
format=win32pdh.PDH_FMT_LONG,
machine=None,
bRefresh=0,
):
"""Find performance attributes by (case insensitive) instance name.
Given a process name, return a list with the requested attributes.
Most useful for returning a tuple of PIDs given a process name.
"""
if object is None:
object = find_pdh_counter_localized_name("Process", machine)
if counter is None:
counter = find_pdh_counter_localized_name("ID Process", machine)
if bRefresh: # PDH docs say this is how you do a refresh.
win32pdh.EnumObjects(None, machine, 0, 1)
instanceName = instanceName.lower()
items, instances = win32pdh.EnumObjectItems(None, None, object, -1)
# Track multiple instances.
instance_dict = {}
for instance in instances:
try:
instance_dict[instance] = instance_dict[instance] + 1
except KeyError:
instance_dict[instance] = 0
ret = []
for instance, max_instances in instance_dict.items():
for inum in range(max_instances + 1):
if instance.lower() == instanceName:
ret.append(
GetPerformanceAttributes(
object, counter, instance, inum, format, machine
)
)
return ret
def ShowAllProcesses():
object = find_pdh_counter_localized_name("Process")
items, instances = win32pdh.EnumObjectItems(
None, None, object, win32pdh.PERF_DETAIL_WIZARD
)
# Need to track multiple instances of the same name.
instance_dict = {}
for instance in instances:
try:
instance_dict[instance] = instance_dict[instance] + 1
except KeyError:
instance_dict[instance] = 0
# Bit of a hack to get useful info.
items = [find_pdh_counter_localized_name("ID Process")] + items[:5]
print("Process Name", ",".join(items))
for instance, max_instances in instance_dict.items():
for inum in range(max_instances + 1):
hq = win32pdh.OpenQuery()
hcs = []
for item in items:
path = win32pdh.MakeCounterPath(
(None, object, instance, None, inum, item)
)
hcs.append(win32pdh.AddCounter(hq, path))
win32pdh.CollectQueryData(hq)
# as per http://support.microsoft.com/default.aspx?scid=kb;EN-US;q262938, some "%" based
# counters need two collections
time.sleep(0.01)
win32pdh.CollectQueryData(hq)
print("%-15s\t" % (instance[:15]), end=" ")
for hc in hcs:
type, val = win32pdh.GetFormattedCounterValue(hc, win32pdh.PDH_FMT_LONG)
print("%5d" % (val), end=" ")
win32pdh.RemoveCounter(hc)
print()
win32pdh.CloseQuery(hq)
# NOTE: This BrowseCallback doesn't seem to work on Vista for markh.
# XXX - look at why!?
# Some counters on Vista require elevation, and callback would previously
# clear exceptions without printing them.
def BrowseCallBackDemo(counters):
## BrowseCounters can now return multiple counter paths
for counter in counters:
(
machine,
object,
instance,
parentInstance,
index,
counterName,
) = win32pdh.ParseCounterPath(counter)
result = GetPerformanceAttributes(
object, counterName, instance, index, win32pdh.PDH_FMT_DOUBLE, machine
)
print("Value of '%s' is" % counter, result)
print(
"Added '%s' on object '%s' (machine %s), instance %s(%d)-parent of %s"
% (counterName, object, machine, instance, index, parentInstance)
)
return 0
def browse(
callback=BrowseCallBackDemo,
title="Python Browser",
level=win32pdh.PERF_DETAIL_WIZARD,
):
win32pdh.BrowseCounters(None, 0, callback, level, title, ReturnMultiple=True)
if __name__ == "__main__":
ShowAllProcesses()
# Show how to get a couple of attributes by name.
counter = find_pdh_counter_localized_name("Virtual Bytes")
print(
"Virtual Bytes = ", FindPerformanceAttributesByName("python", counter=counter)
)
print(
"Available Bytes = ",
GetPerformanceAttributes(
find_pdh_counter_localized_name("Memory"),
find_pdh_counter_localized_name("Available Bytes"),
),
)
# And a browser.
print("Browsing for counters...")
browse()

View file

@ -0,0 +1,677 @@
# Windows dialog .RC file parser, by Adam Walker.
# This module was adapted from the spambayes project, and is Copyright
# 2003/2004 The Python Software Foundation and is covered by the Python
# Software Foundation license.
"""
This is a parser for Windows .rc files, which are text files which define
dialogs and other Windows UI resources.
"""
__author__ = "Adam Walker"
__version__ = "0.11"
import os
import pprint
import shlex
import stat
import sys
import commctrl
import win32con
_controlMap = {
"DEFPUSHBUTTON": 0x80,
"PUSHBUTTON": 0x80,
"Button": 0x80,
"GROUPBOX": 0x80,
"Static": 0x82,
"CTEXT": 0x82,
"RTEXT": 0x82,
"LTEXT": 0x82,
"LISTBOX": 0x83,
"SCROLLBAR": 0x84,
"COMBOBOX": 0x85,
"EDITTEXT": 0x81,
"ICON": 0x82,
"RICHEDIT": "RichEdit20A",
}
# These are "default styles" for certain controls - ie, Visual Studio assumes
# the styles will be applied, and emits a "NOT {STYLE_NAME}" if it is to be
# disabled. These defaults have been determined by experimentation, so may
# not be completely accurate (most notably, some styles and/or control-types
# may be missing.
_addDefaults = {
"EDITTEXT": win32con.WS_BORDER | win32con.WS_TABSTOP,
"GROUPBOX": win32con.BS_GROUPBOX,
"LTEXT": win32con.SS_LEFT,
"DEFPUSHBUTTON": win32con.BS_DEFPUSHBUTTON | win32con.WS_TABSTOP,
"PUSHBUTTON": win32con.WS_TABSTOP,
"CTEXT": win32con.SS_CENTER,
"RTEXT": win32con.SS_RIGHT,
"ICON": win32con.SS_ICON,
"LISTBOX": win32con.LBS_NOTIFY,
}
defaultControlStyle = win32con.WS_CHILD | win32con.WS_VISIBLE
defaultControlStyleEx = 0
class DialogDef:
name = ""
id = 0
style = 0
styleEx = None
caption = ""
font = "MS Sans Serif"
fontSize = 8
x = 0
y = 0
w = 0
h = 0
template = None
def __init__(self, n, i):
self.name = n
self.id = i
self.styles = []
self.stylesEx = []
self.controls = []
# print "dialog def for ",self.name, self.id
def createDialogTemplate(self):
t = None
self.template = [
[
self.caption,
(self.x, self.y, self.w, self.h),
self.style,
self.styleEx,
(self.fontSize, self.font),
]
]
# Add the controls
for control in self.controls:
self.template.append(control.createDialogTemplate())
return self.template
class ControlDef:
id = ""
controlType = ""
subType = ""
idNum = 0
style = defaultControlStyle
styleEx = defaultControlStyleEx
label = ""
x = 0
y = 0
w = 0
h = 0
def __init__(self):
self.styles = []
self.stylesEx = []
def toString(self):
s = (
"<Control id:"
+ self.id
+ " controlType:"
+ self.controlType
+ " subType:"
+ self.subType
+ " idNum:"
+ str(self.idNum)
+ " style:"
+ str(self.style)
+ " styles:"
+ str(self.styles)
+ " label:"
+ self.label
+ " x:"
+ str(self.x)
+ " y:"
+ str(self.y)
+ " w:"
+ str(self.w)
+ " h:"
+ str(self.h)
+ ">"
)
return s
def createDialogTemplate(self):
ct = self.controlType
if "CONTROL" == ct:
ct = self.subType
if ct in _controlMap:
ct = _controlMap[ct]
t = [
ct,
self.label,
self.idNum,
(self.x, self.y, self.w, self.h),
self.style,
self.styleEx,
]
# print t
return t
class StringDef:
def __init__(self, id, idNum, value):
self.id = id
self.idNum = idNum
self.value = value
def __repr__(self):
return "StringDef(%r, %r, %r)" % (self.id, self.idNum, self.value)
class RCParser:
next_id = 1001
dialogs = {}
_dialogs = {}
debugEnabled = False
token = ""
def __init__(self):
self.ungot = False
self.ids = {"IDC_STATIC": -1}
self.names = {-1: "IDC_STATIC"}
self.bitmaps = {}
self.stringTable = {}
self.icons = {}
def debug(self, *args):
if self.debugEnabled:
print(args)
def getToken(self):
if self.ungot:
self.ungot = False
self.debug("getToken returns (ungot):", self.token)
return self.token
self.token = self.lex.get_token()
self.debug("getToken returns:", self.token)
if self.token == "":
self.token = None
return self.token
def ungetToken(self):
self.ungot = True
def getCheckToken(self, expected):
tok = self.getToken()
assert tok == expected, "Expected token '%s', but got token '%s'!" % (
expected,
tok,
)
return tok
def getCommaToken(self):
return self.getCheckToken(",")
# Return the *current* token as a number, only consuming a token
# if it is the negative-sign.
def currentNumberToken(self):
mult = 1
if self.token == "-":
mult = -1
self.getToken()
return int(self.token) * mult
# Return the *current* token as a string literal (ie, self.token will be a
# quote. consumes all tokens until the end of the string
def currentQuotedString(self):
# Handle quoted strings - pity shlex doesn't handle it.
assert self.token.startswith('"'), self.token
bits = [self.token]
while 1:
tok = self.getToken()
if not tok.startswith('"'):
self.ungetToken()
break
bits.append(tok)
sval = "".join(bits)[1:-1] # Remove end quotes.
# Fixup quotes in the body, and all (some?) quoted characters back
# to their raw value.
for i, o in ('""', '"'), ("\\r", "\r"), ("\\n", "\n"), ("\\t", "\t"):
sval = sval.replace(i, o)
return sval
def load(self, rcstream):
"""
RCParser.loadDialogs(rcFileName) -> None
Load the dialog information into the parser. Dialog Definations can then be accessed
using the "dialogs" dictionary member (name->DialogDef). The "ids" member contains the dictionary of id->name.
The "names" member contains the dictionary of name->id
"""
self.open(rcstream)
self.getToken()
while self.token != None:
self.parse()
self.getToken()
def open(self, rcstream):
self.lex = shlex.shlex(rcstream)
self.lex.commenters = "//#"
def parseH(self, file):
lex = shlex.shlex(file)
lex.commenters = "//"
token = " "
while token is not None:
token = lex.get_token()
if token == "" or token is None:
token = None
else:
if token == "define":
n = lex.get_token()
i = int(lex.get_token())
self.ids[n] = i
if i in self.names:
# Dupe ID really isn't a problem - most consumers
# want to go from name->id, and this is OK.
# It means you can't go from id->name though.
pass
# ignore AppStudio special ones
# if not n.startswith("_APS_"):
# print "Duplicate id",i,"for",n,"is", self.names[i]
else:
self.names[i] = n
if self.next_id <= i:
self.next_id = i + 1
def parse(self):
noid_parsers = {
"STRINGTABLE": self.parse_stringtable,
}
id_parsers = {
"DIALOG": self.parse_dialog,
"DIALOGEX": self.parse_dialog,
# "TEXTINCLUDE": self.parse_textinclude,
"BITMAP": self.parse_bitmap,
"ICON": self.parse_icon,
}
deep = 0
base_token = self.token
rp = noid_parsers.get(base_token)
if rp is not None:
rp()
else:
# Not something we parse that isn't prefixed by an ID
# See if it is an ID prefixed item - if it is, our token
# is the resource ID.
resource_id = self.token
self.getToken()
if self.token is None:
return
if "BEGIN" == self.token:
# A 'BEGIN' for a structure we don't understand - skip to the
# matching 'END'
deep = 1
while deep != 0 and self.token is not None:
self.getToken()
self.debug("Zooming over", self.token)
if "BEGIN" == self.token:
deep += 1
elif "END" == self.token:
deep -= 1
else:
rp = id_parsers.get(self.token)
if rp is not None:
self.debug("Dispatching '%s'" % (self.token,))
rp(resource_id)
else:
# We don't know what the resource type is, but we
# have already consumed the next, which can cause problems,
# so push it back.
self.debug("Skipping top-level '%s'" % base_token)
self.ungetToken()
def addId(self, id_name):
if id_name in self.ids:
id = self.ids[id_name]
else:
# IDOK, IDCANCEL etc are special - if a real resource has this value
for n in ["IDOK", "IDCANCEL", "IDYES", "IDNO", "IDABORT"]:
if id_name == n:
v = getattr(win32con, n)
self.ids[n] = v
self.names[v] = n
return v
id = self.next_id
self.next_id += 1
self.ids[id_name] = id
self.names[id] = id_name
return id
def lang(self):
while (
self.token[0:4] == "LANG"
or self.token[0:7] == "SUBLANG"
or self.token == ","
):
self.getToken()
def parse_textinclude(self, res_id):
while self.getToken() != "BEGIN":
pass
while 1:
if self.token == "END":
break
s = self.getToken()
def parse_stringtable(self):
while self.getToken() != "BEGIN":
pass
while 1:
self.getToken()
if self.token == "END":
break
sid = self.token
self.getToken()
sd = StringDef(sid, self.addId(sid), self.currentQuotedString())
self.stringTable[sid] = sd
def parse_bitmap(self, name):
return self.parse_bitmap_or_icon(name, self.bitmaps)
def parse_icon(self, name):
return self.parse_bitmap_or_icon(name, self.icons)
def parse_bitmap_or_icon(self, name, dic):
self.getToken()
while not self.token.startswith('"'):
self.getToken()
bmf = self.token[1:-1] # quotes
dic[name] = bmf
def parse_dialog(self, name):
dlg = DialogDef(name, self.addId(name))
assert len(dlg.controls) == 0
self._dialogs[name] = dlg
extras = []
self.getToken()
while not self.token.isdigit():
self.debug("extra", self.token)
extras.append(self.token)
self.getToken()
dlg.x = int(self.token)
self.getCommaToken()
self.getToken() # number
dlg.y = int(self.token)
self.getCommaToken()
self.getToken() # number
dlg.w = int(self.token)
self.getCommaToken()
self.getToken() # number
dlg.h = int(self.token)
self.getToken()
while not (self.token == None or self.token == "" or self.token == "END"):
if self.token == "STYLE":
self.dialogStyle(dlg)
elif self.token == "EXSTYLE":
self.dialogExStyle(dlg)
elif self.token == "CAPTION":
self.dialogCaption(dlg)
elif self.token == "FONT":
self.dialogFont(dlg)
elif self.token == "BEGIN":
self.controls(dlg)
else:
break
self.dialogs[name] = dlg.createDialogTemplate()
def dialogStyle(self, dlg):
dlg.style, dlg.styles = self.styles([], win32con.DS_SETFONT)
def dialogExStyle(self, dlg):
self.getToken()
dlg.styleEx, dlg.stylesEx = self.styles([], 0)
def styles(self, defaults, defaultStyle):
list = defaults
style = defaultStyle
if "STYLE" == self.token:
self.getToken()
i = 0
Not = False
while (
(i % 2 == 1 and ("|" == self.token or "NOT" == self.token)) or (i % 2 == 0)
) and not self.token == None:
Not = False
if "NOT" == self.token:
Not = True
self.getToken()
i += 1
if self.token != "|":
if self.token in win32con.__dict__:
value = getattr(win32con, self.token)
else:
if self.token in commctrl.__dict__:
value = getattr(commctrl, self.token)
else:
value = 0
if Not:
list.append("NOT " + self.token)
self.debug("styles add Not", self.token, value)
style &= ~value
else:
list.append(self.token)
self.debug("styles add", self.token, value)
style |= value
self.getToken()
self.debug("style is ", style)
return style, list
def dialogCaption(self, dlg):
if "CAPTION" == self.token:
self.getToken()
self.token = self.token[1:-1]
self.debug("Caption is:", self.token)
dlg.caption = self.token
self.getToken()
def dialogFont(self, dlg):
if "FONT" == self.token:
self.getToken()
dlg.fontSize = int(self.token)
self.getCommaToken()
self.getToken() # Font name
dlg.font = self.token[1:-1] # it's quoted
self.getToken()
while "BEGIN" != self.token:
self.getToken()
def controls(self, dlg):
if self.token == "BEGIN":
self.getToken()
# All controls look vaguely like:
# TYPE [text, ] Control_id, l, t, r, b [, style]
# .rc parser documents all control types as:
# CHECKBOX, COMBOBOX, CONTROL, CTEXT, DEFPUSHBUTTON, EDITTEXT, GROUPBOX,
# ICON, LISTBOX, LTEXT, PUSHBUTTON, RADIOBUTTON, RTEXT, SCROLLBAR
without_text = ["EDITTEXT", "COMBOBOX", "LISTBOX", "SCROLLBAR"]
while self.token != "END":
control = ControlDef()
control.controlType = self.token
self.getToken()
if control.controlType not in without_text:
if self.token[0:1] == '"':
control.label = self.currentQuotedString()
# Some funny controls, like icons and picture controls use
# the "window text" as extra resource ID (ie, the ID of the
# icon itself). This may be either a literal, or an ID string.
elif self.token == "-" or self.token.isdigit():
control.label = str(self.currentNumberToken())
else:
# An ID - use the numeric equiv.
control.label = str(self.addId(self.token))
self.getCommaToken()
self.getToken()
# Control IDs may be "names" or literal ints
if self.token == "-" or self.token.isdigit():
control.id = self.currentNumberToken()
control.idNum = control.id
else:
# name of an ID
control.id = self.token
control.idNum = self.addId(control.id)
self.getCommaToken()
if control.controlType == "CONTROL":
self.getToken()
control.subType = self.token[1:-1]
thisDefaultStyle = defaultControlStyle | _addDefaults.get(
control.subType, 0
)
# Styles
self.getCommaToken()
self.getToken()
control.style, control.styles = self.styles([], thisDefaultStyle)
else:
thisDefaultStyle = defaultControlStyle | _addDefaults.get(
control.controlType, 0
)
# incase no style is specified.
control.style = thisDefaultStyle
# Rect
control.x = int(self.getToken())
self.getCommaToken()
control.y = int(self.getToken())
self.getCommaToken()
control.w = int(self.getToken())
self.getCommaToken()
self.getToken()
control.h = int(self.token)
self.getToken()
if self.token == ",":
self.getToken()
control.style, control.styles = self.styles([], thisDefaultStyle)
if self.token == ",":
self.getToken()
control.styleEx, control.stylesEx = self.styles(
[], defaultControlStyleEx
)
# print control.toString()
dlg.controls.append(control)
def ParseStreams(rc_file, h_file):
rcp = RCParser()
if h_file:
rcp.parseH(h_file)
try:
rcp.load(rc_file)
except:
lex = getattr(rcp, "lex", None)
if lex:
print("ERROR parsing dialogs at line", lex.lineno)
print("Next 10 tokens are:")
for i in range(10):
print(lex.get_token(), end=" ")
print()
raise
return rcp
def Parse(rc_name, h_name=None):
if h_name:
h_file = open(h_name, "r")
else:
# See if same basename as the .rc
h_name = rc_name[:-2] + "h"
try:
h_file = open(h_name, "r")
except IOError:
# See if MSVC default of 'resource.h' in the same dir.
h_name = os.path.join(os.path.dirname(rc_name), "resource.h")
try:
h_file = open(h_name, "r")
except IOError:
# .h files are optional anyway
h_file = None
rc_file = open(rc_name, "r")
try:
return ParseStreams(rc_file, h_file)
finally:
if h_file is not None:
h_file.close()
rc_file.close()
return rcp
def GenerateFrozenResource(rc_name, output_name, h_name=None):
"""Converts an .rc windows resource source file into a python source file
with the same basic public interface as the rest of this module.
Particularly useful for py2exe or other 'freeze' type solutions,
where a frozen .py file can be used inplace of a real .rc file.
"""
rcp = Parse(rc_name, h_name)
in_stat = os.stat(rc_name)
out = open(output_name, "wt")
out.write("#%s\n" % output_name)
out.write("#This is a generated file. Please edit %s instead.\n" % rc_name)
out.write("__version__=%r\n" % __version__)
out.write(
"_rc_size_=%d\n_rc_mtime_=%d\n"
% (in_stat[stat.ST_SIZE], in_stat[stat.ST_MTIME])
)
out.write("class StringDef:\n")
out.write("\tdef __init__(self, id, idNum, value):\n")
out.write("\t\tself.id = id\n")
out.write("\t\tself.idNum = idNum\n")
out.write("\t\tself.value = value\n")
out.write("\tdef __repr__(self):\n")
out.write(
'\t\treturn "StringDef(%r, %r, %r)" % (self.id, self.idNum, self.value)\n'
)
out.write("class FakeParser:\n")
for name in "dialogs", "ids", "names", "bitmaps", "icons", "stringTable":
out.write("\t%s = \\\n" % (name,))
pprint.pprint(getattr(rcp, name), out)
out.write("\n")
out.write("def Parse(s):\n")
out.write("\treturn FakeParser()\n")
out.close()
if __name__ == "__main__":
if len(sys.argv) <= 1:
print(__doc__)
print()
print("See test_win32rcparser.py, and the win32rcparser directory (both")
print("in the test suite) for an example of this module's usage.")
else:
import pprint
filename = sys.argv[1]
if "-v" in sys.argv:
RCParser.debugEnabled = 1
print("Dumping all resources in '%s'" % filename)
resources = Parse(filename)
for id, ddef in resources.dialogs.items():
print("Dialog %s (%d controls)" % (id, len(ddef)))
pprint.pprint(ddef)
print()
for id, sdef in resources.stringTable.items():
print("String %s=%r" % (id, sdef.value))
print()
for id, sdef in resources.bitmaps.items():
print("Bitmap %s=%r" % (id, sdef))
print()
for id, sdef in resources.icons.items():
print("Icon %s=%r" % (id, sdef))
print()

Some files were not shown because too many files have changed in this diff Show more