mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use a little C code to interface with windows for device detection and unicode command line arguments
This commit is contained in:
parent
e854a9ffd5
commit
50add0c72d
@ -253,7 +253,7 @@ _check_symlinks_prescript()
|
||||
print 'Adding plugins'
|
||||
module_dir = os.path.join(resource_dir, 'lib', 'python2.5', 'lib-dynload')
|
||||
print 'Adding fontconfig'
|
||||
for f in glob.glob(os.path.expanduser('~/fontconfig2/*')):
|
||||
for f in glob.glob(os.path.expanduser('~/fontconfig-bundled/*')):
|
||||
os.link(f, os.path.join(frameworks_dir, os.path.basename(f)))
|
||||
dst = os.path.join(resource_dir, 'fonts')
|
||||
if os.path.exists(dst):
|
||||
|
17
setup.py
17
setup.py
@ -56,10 +56,16 @@ if __name__ == '__main__':
|
||||
include_dirs=['src/calibre/utils/lzx'])]
|
||||
if iswindows:
|
||||
ext_modules.append(Extension('calibre.plugins.winutil',
|
||||
sources=['src/calibre/utils/winutil.c'], libraries=['shell32'])
|
||||
sources=['src/calibre/utils/windows/winutil.c'],
|
||||
libraries=['shell32', 'setupapi'],
|
||||
include_dirs=['C:/WinDDK/6001.18001/inc/api/'])
|
||||
)
|
||||
# Build PyQt extensions
|
||||
for path in [(os.path.join('src', 'calibre', 'gui2', 'pictureflow'))]:
|
||||
if isosx:
|
||||
ext_modules.append(Extension('calibre.plugins.usbobserver',
|
||||
sources=['src/calibre/driver/usbobserver/usbobserver.c'])
|
||||
)
|
||||
|
||||
def build_PyQt_extension(path):
|
||||
pro = glob.glob(os.path.join(path, '*.pro'))[0]
|
||||
raw = open(pro).read()
|
||||
base = qtplugin = re.search(r'TARGET\s*=\s*(.*)', raw).group(1)
|
||||
@ -72,7 +78,7 @@ if __name__ == '__main__':
|
||||
os.chdir('.build')
|
||||
subprocess.check_call(( (os.path.expanduser('~/qt/bin/qmake') if isosx else 'qmake'), '..'+os.sep+os.path.basename(pro)))
|
||||
subprocess.check_call(['mingw32-make' if iswindows else 'make'])
|
||||
os.chdir(os.path.join('..'+(os.sep+'..' if iswindows else ''), 'PyQt'))
|
||||
os.chdir(os.path.join('..', 'PyQt'))
|
||||
if not os.path.exists('.build'):
|
||||
os.mkdir('.build')
|
||||
os.chdir('.build')
|
||||
@ -142,5 +148,8 @@ if __name__ == '__main__':
|
||||
]
|
||||
)
|
||||
|
||||
for path in [(os.path.join('src', 'calibre', 'gui2', 'pictureflow'))]:
|
||||
build_PyQt_extension(path)
|
||||
|
||||
if 'develop' in ' '.join(sys.argv) and islinux:
|
||||
subprocess.check_call('calibre_postinstall', shell=True)
|
||||
|
@ -23,6 +23,10 @@ Run an embedded python interpreter.
|
||||
return parser
|
||||
|
||||
def update_zipfile(zipfile, mod, path):
|
||||
if 'win32' in sys.platform:
|
||||
print 'WARNING: On Windows Vista you must run this from a console that has been started in Administrator mode.'
|
||||
print 'Press Enter to continue or Ctrl-C to Cancel'
|
||||
raw_input()
|
||||
pat = re.compile(mod.replace('.', '/')+r'\.py[co]*')
|
||||
name = mod.replace('.', '/') + os.path.splitext(path)[-1]
|
||||
update(zipfile, [pat], [path], [name])
|
||||
|
@ -133,31 +133,7 @@ class KINDLE(Device):
|
||||
|
||||
|
||||
def open_windows(self):
|
||||
drives = []
|
||||
import wmi
|
||||
c = wmi.WMI()
|
||||
for drive in c.Win32_DiskDrive():
|
||||
'''print drive.PNPDeviceID'''
|
||||
if self.__class__.is_device(drive.PNPDeviceID):
|
||||
if drive.Partitions == 0:
|
||||
continue
|
||||
try:
|
||||
partition = drive.associators("Win32_DiskDriveToDiskPartition")[0]
|
||||
logical_disk = partition.associators('Win32_LogicalDiskToPartition')[0]
|
||||
prefix = logical_disk.DeviceID+os.sep
|
||||
drives.append((drive.Index, prefix))
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
|
||||
if not drives:
|
||||
print self.__class__.__name__
|
||||
raise DeviceError('Unable to find %s. Is it connected?'%(self.__class__.__name__,))
|
||||
|
||||
drives.sort(cmp=lambda a, b: cmp(a[0], b[0]))
|
||||
self._main_prefix = drives[0][1]
|
||||
if len(drives) > 1:
|
||||
self._card_prefix = drives[1][1]
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def open_linux(self):
|
||||
|
@ -7,59 +7,48 @@ manner.
|
||||
|
||||
import sys
|
||||
|
||||
from calibre import iswindows, isosx
|
||||
from calibre import iswindows, isosx, plugins
|
||||
from calibre.devices import libusb
|
||||
|
||||
osx_scanner = None
|
||||
osx_scanner = win_scanner = linux_scanner = None
|
||||
|
||||
try:
|
||||
import usbobserver
|
||||
osx_scanner = usbobserver.get_devices
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
linux_scanner = libusb.get_devices
|
||||
if iswindows:
|
||||
try:
|
||||
win_scanner = plugins['winutil'][0].get_usb_devices
|
||||
except:
|
||||
raise RuntimeError('Failed to load the winutil plugin: %s'%plugins['winutil'][1])
|
||||
elif isosx:
|
||||
try:
|
||||
osx_scanner = plugins['usbobserver'][0].get_usb_devices
|
||||
except:
|
||||
raise RuntimeError('Failed to load the usbobserver plugin: %s'%plugins['usbobserver'][1])
|
||||
else:
|
||||
linux_scanner = libusb.get_devices
|
||||
|
||||
class DeviceScanner(object):
|
||||
|
||||
def __init__(self, wmi=None):
|
||||
self.wmi = wmi
|
||||
if iswindows and wmi is None:
|
||||
raise RuntimeError('You must pass a wmi instance to DeviceScanner on windows.')
|
||||
def __init__(self, *args):
|
||||
if isosx and osx_scanner is None:
|
||||
raise RuntimeError('The Python extension usbobserver must be available on OS X.')
|
||||
if not (isosx or iswindows) and not libusb.has_library():
|
||||
raise RuntimeError('DeviceScanner requires libusb to work.')
|
||||
|
||||
self.scanner = win_scanner if iswindows else osx_scanner if isosx else linux_scanner
|
||||
self.devices = []
|
||||
|
||||
def get_devices(self):
|
||||
if iswindows:
|
||||
devices = []
|
||||
for c in self.wmi.USBControllerDevice():
|
||||
devices.append(c.Dependent.DeviceID.upper())
|
||||
return devices
|
||||
if isosx:
|
||||
return osx_scanner()
|
||||
return linux_scanner()
|
||||
|
||||
def scan(self):
|
||||
try: # Windows WMI occasionally and temporarily barfs
|
||||
self.devices = self.get_devices()
|
||||
except Exception, e:
|
||||
if not iswindows and e:
|
||||
raise e
|
||||
|
||||
'''Fetch list of connected USB devices from operating system'''
|
||||
self.devices = self.scanner()
|
||||
|
||||
def is_device_connected(self, device):
|
||||
if iswindows:
|
||||
for device_id in self.devices:
|
||||
if 'VEN_'+device.VENDOR_NAME in device_id and \
|
||||
'PROD_'+device.PRODUCT_NAME in device_id:
|
||||
return True
|
||||
vid, pid = hex(device.VENDOR_ID)[2:], hex(device.PRODUCT_ID)[2:]
|
||||
if len(vid) < 4: vid = '0'+vid
|
||||
if len(pid) < 4: pid = '0'+pid
|
||||
vid, pid = 'VID_'+vid.upper(), 'PID_'+pid.upper()
|
||||
vid, pid = 'vid_%4.4x'%device.VENDOR_ID, 'pid_%4.4x'%device.PRODUCT_ID
|
||||
if vid in device_id and pid in device_id:
|
||||
return True
|
||||
return False
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
|
||||
static PyObject *
|
||||
usbobserver_get_devices(PyObject *self, PyObject *args) {
|
||||
usbobserver_get_usb_devices(PyObject *self, PyObject *args) {
|
||||
|
||||
mach_port_t masterPort;
|
||||
CFMutableDictionaryRef matchingDict;
|
||||
@ -62,7 +62,7 @@ usbobserver_get_devices(PyObject *self, PyObject *args) {
|
||||
PyObject *devices, *device;
|
||||
devices = PyList_New(0);
|
||||
if (devices == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Out of memory allocating list");
|
||||
PyErr_NoMemory();
|
||||
mach_port_deallocate(mach_task_self(), masterPort);
|
||||
return NULL;
|
||||
}
|
||||
@ -112,7 +112,7 @@ usbobserver_get_devices(PyObject *self, PyObject *args) {
|
||||
}
|
||||
|
||||
static PyMethodDef usbobserver_methods[] = {
|
||||
{"get_devices", usbobserver_get_devices, METH_VARARGS,
|
||||
{"get_usb_devices", usbobserver_get_usb_devices, METH_VARARGS,
|
||||
"Get list of connected USB devices. Returns a list of tuples. Each tuple is of the form (vendor_id, product_id)."
|
||||
},
|
||||
{NULL, NULL, 0, NULL}
|
||||
|
@ -131,13 +131,18 @@ Why does |app| show only some of my fonts on OS X?
|
||||
|
||||
The graphical user interface of |app| is not starting on Windows?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
If you've never used the graphical user interface before, try deleting the file library1.db (it will be somewhere under :file:`C:\\Documents and Settings` on Windows XP and :file:`C:\\Users` on Windows Vista. If that doesn't fix the problem, locate the file calibre.log (in the same places as library1.db) and post its contents in a help message on the `Forums <http://calibre.kovidgoyal.net/discussion>`_. If you can't find either file, try using the windows find feature to search for them. If the files dont exist on your system, try the following:
|
||||
|
||||
Start a command prompt (press the windows key and R and type cmd.exe in the run dialog). At the command prompt type the following command and press Enter::
|
||||
There can be several causes for this:
|
||||
|
||||
* **Any windows version**: Search for the files `calibre2.ini` and `calibre.ini` on your computer and delete them. Search for the file `library1.db` and rename it (this file contains all your converted books so deleting it is not a good idea. Now try again.
|
||||
* **Windows Vista**: If the folder :file:`C:\Users\Your User Name\AppData\Local\VirtualStore\Program Files\calibre` exists, delete it. Uninstall |app|. Reboot. Re-install.
|
||||
* **Any windows version**: Search your computer for a folder named :file:`_ipython`. Delete it and try again.
|
||||
|
||||
If it still wont launch, start a command prompt (press the windows key and R; then type :command:`cmd.exe` in the Run dialog that appears). At the command prompt type the following command and press Enter::
|
||||
|
||||
calibre-debug -c "from calibre.gui2.main import main; main()"
|
||||
|
||||
Post any output you see when asking for help.
|
||||
Post any output you see in a help message on the `Forums <http://calibre.kovidgoyal.net/discussion`_.
|
||||
|
||||
|
||||
I want some feature added to |app|. What can I do?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -22,7 +22,7 @@ match to a given font specification. The main functions in this module are:
|
||||
.. autofunction:: match
|
||||
'''
|
||||
|
||||
import sys, os, locale, codecs, platform
|
||||
import sys, os, locale, codecs, ctypes
|
||||
from ctypes import cdll, c_void_p, Structure, c_int, POINTER, c_ubyte, c_char, util, \
|
||||
pointer, byref, create_string_buffer, Union, c_char_p, c_double
|
||||
|
||||
@ -34,14 +34,25 @@ except:
|
||||
|
||||
iswindows = 'win32' in sys.platform or 'win64' in sys.platform
|
||||
isosx = 'darwin' in sys.platform
|
||||
is64bit = '64bit' in platform.architecture()[0]
|
||||
DISABLED = False
|
||||
#if isosx:
|
||||
# libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c'))
|
||||
# size = ctypes.c_uint(0)
|
||||
# ok = libc.sysctlbyname("hw.cpu64bit_capable", None, byref(size), None, 0)
|
||||
# if ok != 0:
|
||||
# is64bit = False
|
||||
# else:
|
||||
# buf = ctypes.c_char_p("\0" * size.value)
|
||||
# ok = libc.sysctlbyname("hw.cpu64bit_capable", buf, byref(size), None, 0)
|
||||
# if ok != 0:
|
||||
# is64bit = False
|
||||
# else:
|
||||
# is64bit = '1' in buf.value
|
||||
# DISABLED = is64bit
|
||||
|
||||
def load_library():
|
||||
if isosx:
|
||||
if os.path.exists('/usr/X11/lib/libfontconfig.1.dylib'): # The fontconfig shipped with calibre doesn't work on Leopard
|
||||
lib = '/usr/X11/lib/libfontconfig.1.dylib'
|
||||
else:
|
||||
lib = os.path.join(getattr(sys, 'frameworks_dir'), 'libfontconfig.1.dylib') \
|
||||
lib = os.path.join(getattr(sys, 'frameworks_dir'), 'libfontconfig.1.dylib') \
|
||||
if hasattr(sys, 'frameworks_dir') else util.find_library('fontconfig')
|
||||
return cdll.LoadLibrary(lib)
|
||||
elif iswindows:
|
||||
@ -160,9 +171,9 @@ class FontScanner(Thread):
|
||||
global _initialized
|
||||
_initialized = True
|
||||
|
||||
|
||||
_scanner = FontScanner()
|
||||
_scanner.start()
|
||||
if not DISABLED:
|
||||
_scanner = FontScanner()
|
||||
_scanner.start()
|
||||
|
||||
def join():
|
||||
_scanner.join(120)
|
||||
@ -178,6 +189,8 @@ def find_font_families(allowed_extensions=['ttf', 'otf']):
|
||||
`allowed_extensions`: A list of allowed extensions for font file types. Defaults to
|
||||
`['ttf', 'otf']`. If it is empty, it is ignored.
|
||||
'''
|
||||
if DISABLED:
|
||||
return []
|
||||
join()
|
||||
allowed_extensions = [i.lower() for i in allowed_extensions]
|
||||
|
||||
@ -220,6 +233,8 @@ def files_for_family(family, normalize=True):
|
||||
they are a tuple (slant, weight) otherwise they are strings from the set
|
||||
`('normal', 'bold', 'italic', 'bi', 'light', 'li')`
|
||||
'''
|
||||
if DISABLED:
|
||||
return {}
|
||||
join()
|
||||
if isinstance(family, unicode):
|
||||
family = family.encode(preferred_encoding)
|
||||
@ -296,6 +311,8 @@ def match(name, sort=False, verbose=False):
|
||||
decreasing closeness of matching.
|
||||
`verbose`: If `True` print debugging information to stdout
|
||||
'''
|
||||
if DISABLED:
|
||||
return []
|
||||
join()
|
||||
if isinstance(name, unicode):
|
||||
name = name.encode(preferred_encoding)
|
||||
|
18
src/calibre/utils/windows/Makefile
Normal file
18
src/calibre/utils/windows/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
# Makefile to test the winutil module
|
||||
# Invoke with nmake /f Makefile.winutil
|
||||
|
||||
test : winutil.pyd
|
||||
python.exe -c "import winutil; winutil.set_debug(True); print winutil.get_usb_devices(); print winutil.get_mounted_volumes_for_usb_device(0x054c, 0x031e)"
|
||||
|
||||
winutil.pyd : winutil.obj
|
||||
link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH:c:\Python25\libs \
|
||||
/LIBPATH:c:\Python25\PCBuild shell32.lib setupapi.lib /EXPORT:initwinutil \
|
||||
winutil.obj /OUT:winutil.pyd
|
||||
|
||||
|
||||
winutil.obj : winutil.c
|
||||
cl.exe /c /nologo /Ox /MD /W3 /GX /DNDEBUG -Ic:\Python25\include \
|
||||
-Ic:\Python25\PC -Ic:\WinDDK\6001.18001\inc\api /Tcwinutil.c /Fowinutil.obj
|
||||
|
||||
clean :
|
||||
del winutil.pyd winutil.obj winutil.exp winutil.lib
|
587
src/calibre/utils/windows/winutil.c
Normal file
587
src/calibre/utils/windows/winutil.c
Normal file
@ -0,0 +1,587 @@
|
||||
/*
|
||||
:mod:`winutil` -- Interface to Windows
|
||||
============================================
|
||||
|
||||
.. module:: winutil
|
||||
:platform: Windows
|
||||
:synopsis: Various methods to interface with the operating system
|
||||
|
||||
.. moduleauthor:: Kovid Goyal <kovid@kovidgoyal.net> Copyright 2008
|
||||
|
||||
This module contains utility functions to interface with the windows operating
|
||||
system. It should be compiled with the same version of VisualStudio used to
|
||||
compile python. It hasn't been tested with MinGW. We try to use unicode
|
||||
wherever possible in this module.
|
||||
|
||||
.. exception:: winutil.DriveError
|
||||
Raised when scanning for mounted volumes fails.
|
||||
|
||||
.. function:: is_usb_device_connected(vid : integer, pid : integer) -> bool
|
||||
Return `True` iff the USB device identified by the VendorID `vid` and
|
||||
ProductID `pid` is connected to the system.
|
||||
|
||||
.. function:: get_usb_devices() -> list of lowercase strings
|
||||
Return a list of all USB devices connected to the system. Each
|
||||
device is represented by a lowercase unicode string whoose format is
|
||||
the windows *Device Identifier* format. See the MSDN documentation.
|
||||
|
||||
.. function:: get_mounted_volumes_for_usb_device(vid : integer, pid : integer) -> dictionary
|
||||
Return a dictionary of the form `volume_id`:`drive_letter` for all
|
||||
volumes mounted from the device specified by `vid` and `pid`.
|
||||
|
||||
:raises: :exception:`winutil.DriveError` if scanning fails.
|
||||
|
||||
.. function:: special_folder_path(csidl_id) -> path
|
||||
Get paths to common system folders.
|
||||
See windows documentation of SHGetFolderPath.
|
||||
The paths are returned as unicode objects. `csidl_id` should be one
|
||||
of the symbolic constants defined in this module. You can also `OR`
|
||||
a symbolic constant with :data:`CSIDL_FLAG_CREATE` to force the operating
|
||||
system to create a folder if it does not exist. For example::
|
||||
|
||||
>>> from winutil import *
|
||||
>>> special_folder_path(CSIDL_APPDATA)
|
||||
u'C:\\Documents and Settings\\Kovid Goyal\\Application Data'
|
||||
>>> special_folder_path(CSIDL_PERSONAL)
|
||||
u'C:\\Documents and Settings\\Kovid Goyal\\My Documents'
|
||||
|
||||
.. function:: argv() -> list of unicode command line arguments
|
||||
Get command line arguments as unicode objects. Note that the
|
||||
first argument will be the path to the interpreter, *not* the
|
||||
script being run. So to replace sys.argv, you should use
|
||||
sys.argv[1:] = winutil.argv()[1:].
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#define UNICODE
|
||||
#include <Windows.h>
|
||||
#include <Python.h>
|
||||
#include <shlobj.h>
|
||||
#include <stdio.h>
|
||||
#include <setupapi.h>
|
||||
#include <devguid.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define BUFSIZE 512
|
||||
#define MAX_DRIVES 26
|
||||
static PyObject *DriveError;
|
||||
static BOOL DEBUG = FALSE;
|
||||
|
||||
//#define debug(fmt, ...) if DEBUG printf(x, __VA_ARGS__);
|
||||
void
|
||||
debug(const char *fmt, ...) {
|
||||
va_list argList;
|
||||
va_start(argList, fmt);
|
||||
if (DEBUG) vprintf(fmt, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
struct tagDrives
|
||||
{
|
||||
WCHAR letter;
|
||||
WCHAR volume[BUFSIZE];
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
winutil_folder_path(PyObject *self, PyObject *args) {
|
||||
int res; DWORD dwFlags;
|
||||
PyObject *ans = NULL;
|
||||
TCHAR wbuf[MAX_PATH]; CHAR buf[4*MAX_PATH];
|
||||
memset(wbuf, 0, sizeof(TCHAR)*MAX_PATH); memset(buf, 0, sizeof(CHAR)*MAX_PATH);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "l", &dwFlags)) return NULL;
|
||||
|
||||
res = SHGetFolderPath(NULL, dwFlags, NULL, 0, wbuf);
|
||||
if (res != S_OK) {
|
||||
if (res == E_FAIL) PyErr_SetString(PyExc_ValueError, "Folder does not exist.");
|
||||
PyErr_SetString(PyExc_ValueError, "Folder not valid");
|
||||
return NULL;
|
||||
}
|
||||
res = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, 4*MAX_PATH, NULL, NULL);
|
||||
ans = PyUnicode_DecodeUTF8(buf, res-1, "strict");
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
winutil_argv(PyObject *self, PyObject *args) {
|
||||
PyObject *argv, *v;
|
||||
LPWSTR *_argv;
|
||||
LPSTR buf;
|
||||
int argc, i, bytes;
|
||||
if (!PyArg_ParseTuple(args, "")) return NULL;
|
||||
_argv = CommandLineToArgvW(GetCommandLine(), &argc);
|
||||
if (_argv == NULL) { PyErr_NoMemory(); return NULL; }
|
||||
argv = PyList_New(argc);
|
||||
if (argv != NULL) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
bytes = WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, NULL, 0, NULL, NULL);
|
||||
buf = (LPSTR)PyMem_Malloc(sizeof(CHAR)*bytes);
|
||||
if (buf == NULL) { Py_DECREF(argv); argv = NULL; break; }
|
||||
WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, buf, bytes, NULL, NULL);
|
||||
v = PyUnicode_DecodeUTF8(buf, bytes-1, "strict");
|
||||
PyMem_Free(buf);
|
||||
if (v == NULL) { Py_DECREF(argv); argv = NULL; break; }
|
||||
PyList_SetItem(argv, i, v);
|
||||
}
|
||||
}
|
||||
LocalFree(_argv);
|
||||
return argv;
|
||||
}
|
||||
|
||||
static LPVOID
|
||||
format_last_error() {
|
||||
/* Format the last error as a string. The returned pointer should
|
||||
be freed with :cfunction:`LocalFree(lpMsgBuf)`. It can be printed with
|
||||
:cfunction:`printf("\n%ws\n", (LPCTSTR)lpMsgBuf)`.
|
||||
*/
|
||||
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
0, // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
return lpMsgBuf;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
winutil_set_debug(PyObject *self, PyObject *args) {
|
||||
PyObject *yes;
|
||||
if (!PyArg_ParseTuple(args, "O", &yes)) return NULL;
|
||||
DEBUG = (BOOL)PyObject_IsTrue(yes);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static LPTSTR
|
||||
get_registry_property(HDEVINFO hDevInfo, DWORD index, DWORD property, BOOL *iterate) {
|
||||
/* Get a the property specified by `property` from the registry for the
|
||||
* device enumerated by `index` in the collection `hDevInfo`. `iterate`
|
||||
* will be set to `FALSE` if `index` points outside `hDevInfo`.
|
||||
* :return: A string allocated on the heap containing the property or
|
||||
* `NULL` if an error occurred.
|
||||
*/
|
||||
SP_DEVINFO_DATA DeviceInfoData;
|
||||
DWORD DataT;
|
||||
LPTSTR buffer = NULL;
|
||||
DWORD buffersize = 0;
|
||||
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
|
||||
if (!SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData)) {
|
||||
*iterate = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while(!SetupDiGetDeviceRegistryProperty(
|
||||
hDevInfo,
|
||||
&DeviceInfoData,
|
||||
property,
|
||||
&DataT,
|
||||
(PBYTE)buffer,
|
||||
buffersize,
|
||||
&buffersize)) {
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
buffer = (LPTSTR)PyMem_Malloc(2*buffersize); // Twice for bug in Win2k
|
||||
} else {
|
||||
PyMem_Free(buffer);
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
buffer = NULL;
|
||||
break;
|
||||
}
|
||||
} //while
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
check_device_id(LPTSTR buffer, unsigned int vid, unsigned int pid) {
|
||||
WCHAR xVid[9], dVid[9], xPid[9], dPid[9];
|
||||
unsigned int j;
|
||||
swprintf(xVid, L"vid_%4.4x", vid);
|
||||
swprintf(dVid, L"vid_%4.4d", vid);
|
||||
swprintf(xPid, L"pid_%4.4x", pid);
|
||||
swprintf(dPid, L"pid_%4.4d", pid);
|
||||
|
||||
for (j = 0; j < wcslen(buffer); j++) buffer[j] = tolower(buffer[j]);
|
||||
|
||||
return ( (wcsstr(buffer, xVid) != NULL || wcsstr(buffer, dVid) != NULL ) &&
|
||||
(wcsstr(buffer, xPid) != NULL || wcsstr(buffer, dPid) != NULL )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
static HDEVINFO
|
||||
create_device_info_set(LPGUID guid, PCTSTR enumerator, HWND parent, DWORD flags) {
|
||||
HDEVINFO hDevInfo;
|
||||
hDevInfo = SetupDiGetClassDevs(
|
||||
guid,
|
||||
enumerator,
|
||||
parent,
|
||||
flags
|
||||
);
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE) {
|
||||
PyErr_SetFromWindowsErr(0);
|
||||
}
|
||||
return hDevInfo;
|
||||
}
|
||||
|
||||
int n;
|
||||
|
||||
BOOL
|
||||
get_all_removable_disks(struct tagDrives *g_drives)
|
||||
{
|
||||
WCHAR caDrive[4];
|
||||
WCHAR volume[BUFSIZE];
|
||||
int nLoopIndex;
|
||||
DWORD dwDriveMask;
|
||||
unsigned int g_count=0;
|
||||
|
||||
|
||||
caDrive[0] = 'A';
|
||||
caDrive[1] = ':';
|
||||
caDrive[2] = '\\';
|
||||
caDrive[3] = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Get all drives in the system.
|
||||
dwDriveMask = GetLogicalDrives();
|
||||
|
||||
|
||||
if(dwDriveMask == 0)
|
||||
{
|
||||
PyErr_SetString(DriveError, "GetLogicalDrives failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Loop for all drives (MAX_DRIVES = 26)
|
||||
|
||||
|
||||
for(nLoopIndex = 0; nLoopIndex< MAX_DRIVES; nLoopIndex++)
|
||||
{
|
||||
// if a drive is present,
|
||||
if(dwDriveMask & 1)
|
||||
{
|
||||
caDrive[0] = 'A' + nLoopIndex;
|
||||
|
||||
|
||||
// If a drive is removable
|
||||
if(GetDriveType(caDrive) == DRIVE_REMOVABLE)
|
||||
{
|
||||
//Get its volume info and store it in the global variable.
|
||||
if(GetVolumeNameForVolumeMountPoint(caDrive, volume, BUFSIZE))
|
||||
{
|
||||
g_drives[g_count].letter = caDrive[0];
|
||||
wcscpy(g_drives[g_count].volume, volume);
|
||||
g_count ++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
dwDriveMask >>= 1;
|
||||
}
|
||||
|
||||
|
||||
// success if atleast one removable drive is found.
|
||||
if(g_count == 0)
|
||||
{
|
||||
PyErr_SetString(DriveError, "No removable drives found");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA
|
||||
get_device_grandparent(HDEVINFO hDevInfo, DWORD index, PWSTR buf, PWSTR volume_id,
|
||||
BOOL *iterate) {
|
||||
SP_DEVICE_INTERFACE_DATA interfaceData;
|
||||
SP_DEVINFO_DATA devInfoData;
|
||||
BOOL status;
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetailData;
|
||||
DWORD interfaceDetailDataSize,
|
||||
reqSize;
|
||||
DEVINST parent;
|
||||
|
||||
interfaceData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);
|
||||
devInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
|
||||
|
||||
status = SetupDiEnumDeviceInterfaces (
|
||||
hDevInfo, // Interface Device Info handle
|
||||
NULL, // Device Info data
|
||||
(LPGUID)&GUID_DEVINTERFACE_VOLUME, // Interface registered by driver
|
||||
index, // Member
|
||||
&interfaceData // Device Interface Data
|
||||
);
|
||||
if ( status == FALSE ) {
|
||||
*iterate = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
SetupDiGetDeviceInterfaceDetail (
|
||||
hDevInfo, // Interface Device info handle
|
||||
&interfaceData, // Interface data for the event class
|
||||
NULL, // Checking for buffer size
|
||||
0, // Checking for buffer size
|
||||
&reqSize, // Buffer size required to get the detail data
|
||||
NULL // Checking for buffer size
|
||||
);
|
||||
|
||||
interfaceDetailDataSize = reqSize;
|
||||
interfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)PyMem_Malloc(interfaceDetailDataSize+10);
|
||||
if ( interfaceDetailData == NULL ) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
interfaceDetailData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);
|
||||
|
||||
status = SetupDiGetDeviceInterfaceDetail (
|
||||
hDevInfo, // Interface Device info handle
|
||||
&interfaceData, // Interface data for the event class
|
||||
interfaceDetailData, // Interface detail data
|
||||
interfaceDetailDataSize, // Interface detail data size
|
||||
&reqSize, // Buffer size required to get the detail data
|
||||
&devInfoData); // Interface device info
|
||||
|
||||
if ( status == FALSE ) {PyErr_SetFromWindowsErr(0); PyMem_Free(interfaceDetailData); return NULL;}
|
||||
|
||||
// Get the device instance of parent. This points to USBSTOR.
|
||||
CM_Get_Parent(&parent, devInfoData.DevInst, 0);
|
||||
// Get the device ID of the USBSTORAGE volume
|
||||
CM_Get_Device_ID(parent, volume_id, BUFSIZE, 0);
|
||||
// Get the device instance of grand parent. This points to USB root.
|
||||
CM_Get_Parent(&parent, parent, 0);
|
||||
// Get the device ID of the USB root.
|
||||
CM_Get_Device_ID(parent, buf, BUFSIZE, 0);
|
||||
|
||||
return interfaceDetailData;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
winutil_get_mounted_volumes_for_usb_device(PyObject *self, PyObject *args) {
|
||||
unsigned int vid, pid, length, j;
|
||||
HDEVINFO hDevInfo;
|
||||
BOOL iterate = TRUE;
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetailData;
|
||||
DWORD i;
|
||||
WCHAR buf[BUFSIZE], volume[BUFSIZE], volume_id[BUFSIZE];
|
||||
struct tagDrives g_drives[MAX_DRIVES];
|
||||
PyObject *volumes, *key, *val;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ii", &vid, &pid)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
volumes = PyDict_New();
|
||||
if (volumes == NULL) return NULL;
|
||||
|
||||
for (j = 0; j < MAX_DRIVES; j++) g_drives[j].letter = 0;
|
||||
|
||||
// Find all removable drives
|
||||
if (!get_all_removable_disks(g_drives)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hDevInfo = create_device_info_set((LPGUID)&GUID_DEVINTERFACE_VOLUME,
|
||||
NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE) return NULL;
|
||||
|
||||
// Enumerate through the set
|
||||
for (i=0; iterate; i++) {
|
||||
interfaceDetailData = get_device_grandparent(hDevInfo, i, buf, volume_id, &iterate);
|
||||
if (interfaceDetailData == NULL) {
|
||||
PyErr_Print(); continue;
|
||||
}
|
||||
debug("Device num: %d Device Id: %ws\n\n", i, buf);
|
||||
if (check_device_id(buf, vid, pid)) {
|
||||
debug("Device matches\n\n");
|
||||
length = wcslen(interfaceDetailData->DevicePath);
|
||||
interfaceDetailData->DevicePath[length] = '\\';
|
||||
interfaceDetailData->DevicePath[length+1] = 0;
|
||||
if(GetVolumeNameForVolumeMountPoint(interfaceDetailData->DevicePath, volume, BUFSIZE)) {
|
||||
|
||||
for(j = 0; j < MAX_DRIVES; j++) {
|
||||
// Compare volume mount point with the one stored earlier.
|
||||
// If both match, return the corresponding drive letter.
|
||||
if(g_drives[j].letter != 0 && wcscmp(g_drives[j].volume, volume)==0)
|
||||
{
|
||||
key = PyUnicode_FromWideChar(volume_id, wcslen(volume_id));
|
||||
val = PyString_FromFormat("%c", (char)g_drives[j].letter);
|
||||
if (key == NULL || val == NULL) {
|
||||
PyErr_NoMemory();
|
||||
PyMem_Free(interfaceDetailData);
|
||||
return NULL;
|
||||
}
|
||||
PyDict_SetItem(volumes, key, val);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
debug("Failed to get volume name for volume mount point:\n");
|
||||
if (DEBUG) debug("%ws\n\n", format_last_error());
|
||||
}
|
||||
|
||||
PyMem_Free(interfaceDetailData);
|
||||
}
|
||||
|
||||
} //for
|
||||
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return volumes;
|
||||
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
winutil_get_usb_devices(PyObject *self, PyObject *args) {
|
||||
unsigned int j, buffersize;
|
||||
HDEVINFO hDevInfo;
|
||||
DWORD i; BOOL iterate = TRUE;
|
||||
PyObject *devices, *temp = (PyObject *)1;
|
||||
LPTSTR buffer;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "")) return NULL;
|
||||
|
||||
devices = PyList_New(0);
|
||||
if (devices == NULL) {PyErr_NoMemory(); return NULL;}
|
||||
|
||||
// Create a Device information set with all USB devices
|
||||
hDevInfo = create_device_info_set(NULL, L"USB", 0,
|
||||
DIGCF_PRESENT | DIGCF_ALLCLASSES);
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE)
|
||||
return NULL;
|
||||
// Enumerate through the set
|
||||
for (i=0; iterate; i++) {
|
||||
buffer = get_registry_property(hDevInfo, i, SPDRP_HARDWAREID, &iterate);
|
||||
if (buffer == NULL) {
|
||||
PyErr_Print(); continue;
|
||||
}
|
||||
buffersize = wcslen(buffer);
|
||||
for (j = 0; j < buffersize; j++) buffer[j] = tolower(buffer[j]);
|
||||
temp = PyUnicode_FromWideChar(buffer, buffersize);
|
||||
PyMem_Free(buffer);
|
||||
if (temp == NULL) {
|
||||
PyErr_NoMemory();
|
||||
break;
|
||||
}
|
||||
PyList_Append(devices, temp);
|
||||
} //for
|
||||
if (temp == NULL) { Py_DECREF(devices); devices = NULL; }
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
winutil_is_usb_device_connected(PyObject *self, PyObject *args) {
|
||||
unsigned int vid, pid;
|
||||
HDEVINFO hDevInfo;
|
||||
DWORD i; BOOL iterate = TRUE;
|
||||
LPTSTR buffer;
|
||||
int found = FALSE;
|
||||
PyObject *ans;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ii", &vid, &pid)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create a Device information set with all USB devices
|
||||
hDevInfo = create_device_info_set(NULL, L"USB", 0,
|
||||
DIGCF_PRESENT | DIGCF_ALLCLASSES);
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE)
|
||||
return NULL;
|
||||
|
||||
// Enumerate through the set
|
||||
for (i=0; iterate && !found; i++) {
|
||||
buffer = get_registry_property(hDevInfo, i, SPDRP_HARDWAREID, &iterate);
|
||||
if (buffer == NULL) {
|
||||
PyErr_Print(); continue;
|
||||
}
|
||||
found = check_device_id(buffer, vid, pid);
|
||||
PyMem_Free(buffer);
|
||||
} // for
|
||||
|
||||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||
ans = (found) ? Py_True : Py_False;
|
||||
Py_INCREF(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef WinutilMethods[] = {
|
||||
{"special_folder_path", winutil_folder_path, METH_VARARGS,
|
||||
"special_folder_path(csidl_id) -> path\n\n"
|
||||
"Get paths to common system folders. "
|
||||
"See windows documentation of SHGetFolderPath. "
|
||||
"The paths are returned as unicode objects. csidl_id should be one "
|
||||
"of the symbolic constants defined in this module. You can also OR "
|
||||
"a symbolic constant with CSIDL_FLAG_CREATE to force the operating "
|
||||
"system to create a folder if it does not exist."},
|
||||
|
||||
{"argv", winutil_argv, METH_VARARGS,
|
||||
"argv() -> list of command line arguments\n\n"
|
||||
"Get command line arguments as unicode objects. Note that the "
|
||||
"first argument will be the path to the interpreter, *not* the "
|
||||
"script being run. So to replace sys.argv, you should use "
|
||||
"sys.argv[1:] = argv()[1:]."},
|
||||
|
||||
{"is_usb_device_connected", winutil_is_usb_device_connected, METH_VARARGS,
|
||||
"is_usb_device_connected(vid, pid) -> bool\n\n"
|
||||
"Check if the USB device identified by VendorID: vid (integer) and"
|
||||
" ProductID: pid (integer) is currently connected."},
|
||||
|
||||
{"get_usb_devices", winutil_get_usb_devices, METH_VARARGS,
|
||||
"get_usb_devices() -> list of strings\n\n"
|
||||
"Return a list of the hardware IDs of all USB devices "
|
||||
"connected to the system."},
|
||||
|
||||
{"get_mounted_volumes_for_usb_device", winutil_get_mounted_volumes_for_usb_device, METH_VARARGS,
|
||||
"get_mounted_volumes_for_usb_device(vid, pid) -> dict\n\n"
|
||||
"Return a dictionary of volume_id:drive_letter for all"
|
||||
"volumes mounted on the system that belong to the"
|
||||
"usb device specified by vid (integer) and pid (integer)."},
|
||||
|
||||
{"set_debug", winutil_set_debug, METH_VARARGS,
|
||||
"set_debug(bool)\n\nSet debugging mode."
|
||||
},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
initwinutil(void) {
|
||||
PyObject *m;
|
||||
m = Py_InitModule3("winutil", WinutilMethods,
|
||||
"Defines utility methods to interface with windows."
|
||||
);
|
||||
if (m == NULL) return;
|
||||
DriveError = PyErr_NewException("winutil.DriveError", NULL, NULL);
|
||||
|
||||
PyModule_AddIntConstant(m, "CSIDL_ADMINTOOLS", CSIDL_ADMINTOOLS);
|
||||
PyModule_AddIntConstant(m, "CSIDL_APPDATA", CSIDL_APPDATA);
|
||||
PyModule_AddIntConstant(m, "CSIDL_COMMON_ADMINTOOLS", CSIDL_COMMON_ADMINTOOLS);
|
||||
PyModule_AddIntConstant(m, "CSIDL_COMMON_APPDATA", CSIDL_COMMON_APPDATA);
|
||||
PyModule_AddIntConstant(m, "CSIDL_COMMON_DOCUMENTS", CSIDL_COMMON_DOCUMENTS);
|
||||
PyModule_AddIntConstant(m, "CSIDL_COOKIES", CSIDL_COOKIES);
|
||||
PyModule_AddIntConstant(m, "CSIDL_FLAG_CREATE", CSIDL_FLAG_CREATE);
|
||||
PyModule_AddIntConstant(m, "CSIDL_FLAG_DONT_VERIFY", CSIDL_FLAG_DONT_VERIFY);
|
||||
PyModule_AddIntConstant(m, "CSIDL_HISTORY", CSIDL_HISTORY);
|
||||
PyModule_AddIntConstant(m, "CSIDL_INTERNET_CACHE", CSIDL_INTERNET_CACHE);
|
||||
PyModule_AddIntConstant(m, "CSIDL_LOCAL_APPDATA", CSIDL_LOCAL_APPDATA);
|
||||
PyModule_AddIntConstant(m, "CSIDL_MYPICTURES", CSIDL_MYPICTURES);
|
||||
PyModule_AddIntConstant(m, "CSIDL_PERSONAL", CSIDL_PERSONAL);
|
||||
PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES", CSIDL_PROGRAM_FILES);
|
||||
PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES_COMMON", CSIDL_PROGRAM_FILES_COMMON);
|
||||
PyModule_AddIntConstant(m, "CSIDL_SYSTEM", CSIDL_SYSTEM);
|
||||
PyModule_AddIntConstant(m, "CSIDL_WINDOWS", CSIDL_WINDOWS);
|
||||
|
||||
}
|
||||
|
@ -1,99 +0,0 @@
|
||||
#define UNICODE
|
||||
#include <shlobj.h>
|
||||
#include <Windows.h>
|
||||
#include <Python.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
static PyObject *
|
||||
winutil_folder_path(PyObject *self, PyObject *args) {
|
||||
int res; DWORD dwFlags;
|
||||
PyObject *ans = NULL;
|
||||
TCHAR wbuf[MAX_PATH]; CHAR buf[4*MAX_PATH];
|
||||
memset(wbuf, 0, sizeof(TCHAR)*MAX_PATH); memset(buf, 0, sizeof(CHAR)*MAX_PATH);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "l", &dwFlags)) return NULL;
|
||||
|
||||
res = SHGetFolderPath(NULL, dwFlags, NULL, 0, wbuf);
|
||||
if (res != S_OK) {
|
||||
if (res == E_FAIL) PyErr_SetString(PyExc_ValueError, "Folder does not exist.");
|
||||
PyErr_SetString(PyExc_ValueError, "Folder not valid");
|
||||
return NULL;
|
||||
}
|
||||
res = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, 4*MAX_PATH, NULL, NULL);
|
||||
ans = PyUnicode_DecodeUTF8(buf, res-1, "strict");
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
winutil_argv(PyObject *self, PyObject *args) {
|
||||
PyObject *argv, *v;
|
||||
LPWSTR *_argv;
|
||||
LPSTR buf;
|
||||
int argc, i, bytes;
|
||||
if (!PyArg_ParseTuple(args, "")) return NULL;
|
||||
_argv = CommandLineToArgvW(GetCommandLine(), &argc);
|
||||
if (_argv == NULL) { PyErr_SetString(PyExc_RuntimeError, "Out of memory."); return NULL; }
|
||||
argv = PyList_New(argc);
|
||||
if (argv != NULL) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
bytes = WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, NULL, 0, NULL, NULL);
|
||||
buf = (LPSTR)PyMem_Malloc(sizeof(CHAR)*bytes);
|
||||
if (buf == NULL) { Py_DECREF(argv); argv = NULL; break; }
|
||||
WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, buf, bytes, NULL, NULL);
|
||||
v = PyUnicode_DecodeUTF8(buf, bytes-1, "strict");
|
||||
PyMem_Free(buf);
|
||||
if (v == NULL) { Py_DECREF(argv); argv = NULL; break; }
|
||||
PyList_SetItem(argv, i, v);
|
||||
}
|
||||
}
|
||||
LocalFree(_argv);
|
||||
return argv;
|
||||
}
|
||||
|
||||
static PyMethodDef WinutilMethods[] = {
|
||||
{"folder_path", winutil_folder_path, METH_VARARGS,
|
||||
"folder_path(csidl_id) -> path\n\n"
|
||||
"Get paths to common system folders. "
|
||||
"See windows documentation of SHGetFolderPath. "
|
||||
"The paths are returned as unicode objects. csidl_id should be one "
|
||||
"of the symbolic constants defined in this module. You can also OR "
|
||||
"a symbolic constant with CSIDL_FLAG_CREATE to force the operating "
|
||||
"system to create a folder if it does not exist."},
|
||||
{"argv", winutil_argv, METH_VARARGS,
|
||||
"argv() -> list of command line arguments\n\n"
|
||||
"Get command line arguments as unicode objects. Note that the "
|
||||
"first argument will be the path to the interpreter, *not* the "
|
||||
"script being run. So to replace sys.argv, you should use "
|
||||
"sys.argv[1:] = argv()[1:]."},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
initwinutil(void) {
|
||||
PyObject *m;
|
||||
m = Py_InitModule3("winutil", WinutilMethods,
|
||||
"Defines utility methods to interface with windows."
|
||||
);
|
||||
if (m == NULL) return;
|
||||
PyModule_AddIntConstant(m, "CSIDL_ADMINTOOLS", CSIDL_ADMINTOOLS);
|
||||
PyModule_AddIntConstant(m, "CSIDL_APPDATA", CSIDL_APPDATA);
|
||||
PyModule_AddIntConstant(m, "CSIDL_COMMON_ADMINTOOLS", CSIDL_COMMON_ADMINTOOLS);
|
||||
PyModule_AddIntConstant(m, "CSIDL_COMMON_APPDATA", CSIDL_COMMON_APPDATA);
|
||||
PyModule_AddIntConstant(m, "CSIDL_COMMON_DOCUMENTS", CSIDL_COMMON_DOCUMENTS);
|
||||
PyModule_AddIntConstant(m, "CSIDL_COOKIES", CSIDL_COOKIES);
|
||||
PyModule_AddIntConstant(m, "CSIDL_FLAG_CREATE", CSIDL_FLAG_CREATE);
|
||||
PyModule_AddIntConstant(m, "CSIDL_FLAG_DONT_VERIFY", CSIDL_FLAG_DONT_VERIFY);
|
||||
PyModule_AddIntConstant(m, "CSIDL_HISTORY", CSIDL_HISTORY);
|
||||
PyModule_AddIntConstant(m, "CSIDL_INTERNET_CACHE", CSIDL_INTERNET_CACHE);
|
||||
PyModule_AddIntConstant(m, "CSIDL_LOCAL_APPDATA", CSIDL_LOCAL_APPDATA);
|
||||
PyModule_AddIntConstant(m, "CSIDL_MYPICTURES", CSIDL_MYPICTURES);
|
||||
PyModule_AddIntConstant(m, "CSIDL_PERSONAL", CSIDL_PERSONAL);
|
||||
PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES", CSIDL_PROGRAM_FILES);
|
||||
PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES_COMMON", CSIDL_PROGRAM_FILES_COMMON);
|
||||
PyModule_AddIntConstant(m, "CSIDL_SYSTEM", CSIDL_SYSTEM);
|
||||
PyModule_AddIntConstant(m, "CSIDL_WINDOWS", CSIDL_WINDOWS);
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user