PageRenderTime 860ms CodeModel.GetById 262ms app.highlight 462ms RepoModel.GetById 121ms app.codeStats 1ms

/PC/_winreg.c

http://unladen-swallow.googlecode.com/
C | 1710 lines | 1491 code | 138 blank | 81 comment | 231 complexity | e64a133d9b6762cb02fa8f0e73a8bd2b MD5 | raw file
   1/*
   2  _winreg.c
   3
   4  Windows Registry access module for Python.
   5
   6  * Simple registry access written by Mark Hammond in win32api
   7	module circa 1995.
   8  * Bill Tutt expanded the support significantly not long after.
   9  * Numerous other people have submitted patches since then.
  10  * Ripped from win32api module 03-Feb-2000 by Mark Hammond, and
  11    basic Unicode support added.
  12
  13*/
  14
  15#include "Python.h"
  16#include "structmember.h"
  17#include "malloc.h" /* for alloca */
  18#include "windows.h"
  19
  20static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK);
  21static PyObject *PyHKEY_FromHKEY(HKEY h);
  22static BOOL PyHKEY_Close(PyObject *obHandle);
  23
  24static char errNotAHandle[] = "Object is not a handle";
  25
  26/* The win32api module reports the function name that failed,
  27   but this concept is not in the Python core.
  28   Hopefully it will one day, and in the meantime I don't
  29   want to lose this info...
  30*/
  31#define PyErr_SetFromWindowsErrWithFunction(rc, fnname) \
  32	PyErr_SetFromWindowsErr(rc)
  33
  34/* Forward declares */
  35
  36/* Doc strings */
  37PyDoc_STRVAR(module_doc,
  38"This module provides access to the Windows registry API.\n"
  39"\n"
  40"Functions:\n"
  41"\n"
  42"CloseKey() - Closes a registry key.\n"
  43"ConnectRegistry() - Establishes a connection to a predefined registry handle\n"
  44"                    on another computer.\n"
  45"CreateKey() - Creates the specified key, or opens it if it already exists.\n"
  46"DeleteKey() - Deletes the specified key.\n"
  47"DeleteValue() - Removes a named value from the specified registry key.\n"
  48"EnumKey() - Enumerates subkeys of the specified open registry key.\n"
  49"EnumValue() - Enumerates values of the specified open registry key.\n"
  50"ExpandEnvironmentStrings() - Expand the env strings in a REG_EXPAND_SZ string.\n"
  51"FlushKey() - Writes all the attributes of the specified key to the registry.\n"
  52"LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and stores\n"
  53"            registration information from a specified file into that subkey.\n"
  54"OpenKey() - Alias for <om win32api.RegOpenKeyEx>\n"
  55"OpenKeyEx() - Opens the specified key.\n"
  56"QueryValue() - Retrieves the value associated with the unnamed value for a\n"
  57"               specified key in the registry.\n"
  58"QueryValueEx() - Retrieves the type and data for a specified value name\n"
  59"                 associated with an open registry key.\n"
  60"QueryInfoKey() - Returns information about the specified key.\n"
  61"SaveKey() - Saves the specified key, and all its subkeys a file.\n"
  62"SetValue() - Associates a value with a specified key.\n"
  63"SetValueEx() - Stores data in the value field of an open registry key.\n"
  64"\n"
  65"Special objects:\n"
  66"\n"
  67"HKEYType -- type object for HKEY objects\n"
  68"error -- exception raised for Win32 errors\n"
  69"\n"
  70"Integer constants:\n"
  71"Many constants are defined - see the documentation for each function\n"
  72"to see what constants are used, and where.");
  73
  74
  75PyDoc_STRVAR(CloseKey_doc,
  76"CloseKey(hkey) - Closes a previously opened registry key.\n"
  77"\n"
  78"The hkey argument specifies a previously opened key.\n"
  79"\n"
  80"Note that if the key is not closed using this method, it will be\n"
  81"closed when the hkey object is destroyed by Python.");
  82
  83PyDoc_STRVAR(ConnectRegistry_doc,
  84"key = ConnectRegistry(computer_name, key) - "
  85"Establishes a connection to a predefined registry handle on another computer.\n"
  86"\n"
  87"computer_name is the name of the remote computer, of the form \\\\computername.\n"
  88" If None, the local computer is used.\n"
  89"key is the predefined handle to connect to.\n"
  90"\n"
  91"The return value is the handle of the opened key.\n"
  92"If the function fails, an EnvironmentError exception is raised.");
  93
  94PyDoc_STRVAR(CreateKey_doc,
  95"key = CreateKey(key, sub_key) - Creates or opens the specified key.\n"
  96"\n"
  97"key is an already open key, or one of the predefined HKEY_* constants\n"
  98"sub_key is a string that names the key this method opens or creates.\n"
  99" If key is one of the predefined keys, sub_key may be None. In that case,\n"
 100" the handle returned is the same key handle passed in to the function.\n"
 101"\n"
 102"If the key already exists, this function opens the existing key\n"
 103"\n"
 104"The return value is the handle of the opened key.\n"
 105"If the function fails, an exception is raised.");
 106
 107PyDoc_STRVAR(DeleteKey_doc,
 108"DeleteKey(key, sub_key) - Deletes the specified key.\n"
 109"\n"
 110"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 111"sub_key is a string that must be a subkey of the key identified by the key parameter.\n"
 112" This value must not be None, and the key may not have subkeys.\n"
 113"\n"
 114"This method can not delete keys with subkeys.\n"
 115"\n"
 116"If the method succeeds, the entire key, including all of its values,\n"
 117"is removed.  If the method fails, an EnvironmentError exception is raised.");
 118
 119PyDoc_STRVAR(DeleteValue_doc,
 120"DeleteValue(key, value) - Removes a named value from a registry key.\n"
 121"\n"
 122"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 123"value is a string that identifies the value to remove.");
 124
 125PyDoc_STRVAR(EnumKey_doc,
 126"string = EnumKey(key, index) - Enumerates subkeys of an open registry key.\n"
 127"\n"
 128"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 129"index is an integer that identifies the index of the key to retrieve.\n"
 130"\n"
 131"The function retrieves the name of one subkey each time it is called.\n"
 132"It is typically called repeatedly until an EnvironmentError exception is\n"
 133"raised, indicating no more values are available.");
 134
 135PyDoc_STRVAR(EnumValue_doc,
 136"tuple = EnumValue(key, index) - Enumerates values of an open registry key.\n"
 137"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 138"index is an integer that identifies the index of the value to retrieve.\n"
 139"\n"
 140"The function retrieves the name of one subkey each time it is called.\n"
 141"It is typically called repeatedly, until an EnvironmentError exception\n"
 142"is raised, indicating no more values.\n"
 143"\n"
 144"The result is a tuple of 3 items:\n"
 145"value_name is a string that identifies the value.\n"
 146"value_data is an object that holds the value data, and whose type depends\n"
 147" on the underlying registry type.\n"
 148"data_type is an integer that identifies the type of the value data.");
 149
 150PyDoc_STRVAR(ExpandEnvironmentStrings_doc,
 151"string = ExpandEnvironmentStrings(string) - Expand environment vars.\n");
 152
 153PyDoc_STRVAR(FlushKey_doc,
 154"FlushKey(key) - Writes all the attributes of a key to the registry.\n"
 155"\n"
 156"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 157"\n"
 158"It is not necessary to call RegFlushKey to change a key.\n"
 159"Registry changes are flushed to disk by the registry using its lazy flusher.\n"
 160"Registry changes are also flushed to disk at system shutdown.\n"
 161"Unlike CloseKey(), the FlushKey() method returns only when all the data has\n"
 162"been written to the registry.\n"
 163"An application should only call FlushKey() if it requires absolute certainty that registry changes are on disk.\n"
 164"If you don't know whether a FlushKey() call is required, it probably isn't.");
 165
 166PyDoc_STRVAR(LoadKey_doc,
 167"LoadKey(key, sub_key, file_name) - Creates a subkey under the specified key\n"
 168"and stores registration information from a specified file into that subkey.\n"
 169"\n"
 170"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 171"sub_key is a string that identifies the sub_key to load\n"
 172"file_name is the name of the file to load registry data from.\n"
 173" This file must have been created with the SaveKey() function.\n"
 174" Under the file allocation table (FAT) file system, the filename may not\n"
 175"have an extension.\n"
 176"\n"
 177"A call to LoadKey() fails if the calling process does not have the\n"
 178"SE_RESTORE_PRIVILEGE privilege.\n"
 179"\n"
 180"If key is a handle returned by ConnectRegistry(), then the path specified\n"
 181"in fileName is relative to the remote computer.\n"
 182"\n"
 183"The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree");
 184
 185PyDoc_STRVAR(OpenKey_doc,
 186"key = OpenKey(key, sub_key, res = 0, sam = KEY_READ) - Opens the specified key.\n"
 187"\n"
 188"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 189"sub_key is a string that identifies the sub_key to open\n"
 190"res is a reserved integer, and must be zero.  Default is zero.\n"
 191"sam is an integer that specifies an access mask that describes the desired\n"
 192" security access for the key.  Default is KEY_READ\n"
 193"\n"
 194"The result is a new handle to the specified key\n"
 195"If the function fails, an EnvironmentError exception is raised.");
 196
 197PyDoc_STRVAR(OpenKeyEx_doc, "See OpenKey()");
 198
 199PyDoc_STRVAR(QueryInfoKey_doc,
 200"tuple = QueryInfoKey(key) - Returns information about a key.\n"
 201"\n"
 202"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 203"\n"
 204"The result is a tuple of 3 items:"
 205"An integer that identifies the number of sub keys this key has.\n"
 206"An integer that identifies the number of values this key has.\n"
 207"A long integer that identifies when the key was last modified (if available)\n"
 208" as 100's of nanoseconds since Jan 1, 1600.");
 209
 210PyDoc_STRVAR(QueryValue_doc,
 211"string = QueryValue(key, sub_key) - retrieves the unnamed value for a key.\n"
 212"\n"
 213"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 214"sub_key is a string that holds the name of the subkey with which the value\n"
 215" is associated.  If this parameter is None or empty, the function retrieves\n"
 216" the value set by the SetValue() method for the key identified by key."
 217"\n"
 218"Values in the registry have name, type, and data components. This method\n"
 219"retrieves the data for a key's first value that has a NULL name.\n"
 220"But the underlying API call doesn't return the type, Lame Lame Lame, DONT USE THIS!!!");
 221
 222PyDoc_STRVAR(QueryValueEx_doc,
 223"value,type_id = QueryValueEx(key, value_name) - Retrieves the type and data for a specified value name associated with an open registry key.\n"
 224"\n"
 225"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 226"value_name is a string indicating the value to query");
 227
 228PyDoc_STRVAR(SaveKey_doc,
 229"SaveKey(key, file_name) - Saves the specified key, and all its subkeys to the specified file.\n"
 230"\n"
 231"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 232"file_name is the name of the file to save registry data to.\n"
 233" This file cannot already exist. If this filename includes an extension,\n"
 234" it cannot be used on file allocation table (FAT) file systems by the\n"
 235" LoadKey(), ReplaceKey() or RestoreKey() methods.\n"
 236"\n"
 237"If key represents a key on a remote computer, the path described by\n"
 238"file_name is relative to the remote computer.\n"
 239"The caller of this method must possess the SeBackupPrivilege security privilege.\n"
 240"This function passes NULL for security_attributes to the API.");
 241
 242PyDoc_STRVAR(SetValue_doc,
 243"SetValue(key, sub_key, type, value) - Associates a value with a specified key.\n"
 244"\n"
 245"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 246"sub_key is a string that names the subkey with which the value is associated.\n"
 247"type is an integer that specifies the type of the data.  Currently this\n"
 248" must be REG_SZ, meaning only strings are supported.\n"
 249"value is a string that specifies the new value.\n"
 250"\n"
 251"If the key specified by the sub_key parameter does not exist, the SetValue\n"
 252"function creates it.\n"
 253"\n"
 254"Value lengths are limited by available memory. Long values (more than\n"
 255"2048 bytes) should be stored as files with the filenames stored in \n"
 256"the configuration registry.  This helps the registry perform efficiently.\n"
 257"\n"
 258"The key identified by the key parameter must have been opened with\n"
 259"KEY_SET_VALUE access.");
 260
 261PyDoc_STRVAR(SetValueEx_doc,
 262"SetValueEx(key, value_name, reserved, type, value) - Stores data in the value field of an open registry key.\n"
 263"\n"
 264"key is an already open key, or any one of the predefined HKEY_* constants.\n"
 265"value_name is a string containing the name of the value to set, or None\n"
 266"type is an integer that specifies the type of the data.  This should be one of:\n"
 267"  REG_BINARY -- Binary data in any form.\n"
 268"  REG_DWORD -- A 32-bit number.\n"
 269"  REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format.\n"
 270"  REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format.\n"
 271"  REG_EXPAND_SZ -- A null-terminated string that contains unexpanded references\n"
 272"                   to environment variables (for example, %PATH%).\n"
 273"  REG_LINK -- A Unicode symbolic link.\n"
 274"  REG_MULTI_SZ -- An sequence of null-terminated strings, terminated by\n"
 275"                  two null characters.  Note that Python handles this\n"
 276"                  termination automatically.\n"
 277"  REG_NONE -- No defined value type.\n"
 278"  REG_RESOURCE_LIST -- A device-driver resource list.\n"
 279"  REG_SZ -- A null-terminated string.\n"
 280"reserved can be anything - zero is always passed to the API.\n"
 281"value is a string that specifies the new value.\n"
 282"\n"
 283"This method can also set additional value and type information for the\n"
 284"specified key.  The key identified by the key parameter must have been\n"
 285"opened with KEY_SET_VALUE access.\n"
 286"\n"
 287"To open the key, use the CreateKeyEx() or OpenKeyEx() methods.\n"
 288"\n"
 289"Value lengths are limited by available memory. Long values (more than\n"
 290"2048 bytes) should be stored as files with the filenames stored in \n"
 291"the configuration registry.  This helps the registry perform efficiently.");
 292
 293PyDoc_STRVAR(DisableReflectionKey_doc,
 294"Disables registry reflection for 32-bit processes running on a 64-bit\n"
 295"Operating System.  Will generally raise NotImplemented if executed on\n"
 296"a 32-bit Operating System.\n"
 297"If the key is not on the reflection list, the function succeeds but has no effect.\n"
 298"Disabling reflection for a key does not affect reflection of any subkeys.");
 299
 300PyDoc_STRVAR(EnableReflectionKey_doc,
 301"Restores registry reflection for the specified disabled key.\n"
 302"Will generally raise NotImplemented if executed on a 32-bit Operating System.\n"
 303"Restoring reflection for a key does not affect reflection of any subkeys.");
 304
 305PyDoc_STRVAR(QueryReflectionKey_doc,
 306"bool = QueryReflectionKey(hkey) - Determines the reflection state for the specified key.\n"
 307"Will generally raise NotImplemented if executed on a 32-bit Operating System.\n");
 308
 309/* PyHKEY docstrings */
 310PyDoc_STRVAR(PyHKEY_doc,
 311"PyHKEY Object - A Python object, representing a win32 registry key.\n"
 312"\n"
 313"This object wraps a Windows HKEY object, automatically closing it when\n"
 314"the object is destroyed.  To guarantee cleanup, you can call either\n"
 315"the Close() method on the PyHKEY, or the CloseKey() method.\n"
 316"\n"
 317"All functions which accept a handle object also accept an integer - \n"
 318"however, use of the handle object is encouraged.\n"
 319"\n"
 320"Functions:\n"
 321"Close() - Closes the underlying handle.\n"
 322"Detach() - Returns the integer Win32 handle, detaching it from the object\n"
 323"\n"
 324"Properties:\n"
 325"handle - The integer Win32 handle.\n"
 326"\n"
 327"Operations:\n"
 328"__nonzero__ - Handles with an open object return true, otherwise false.\n"
 329"__int__ - Converting a handle to an integer returns the Win32 handle.\n"
 330"__cmp__ - Handle objects are compared using the handle value.");
 331
 332
 333PyDoc_STRVAR(PyHKEY_Close_doc,
 334"key.Close() - Closes the underlying Windows handle.\n"
 335"\n"
 336"If the handle is already closed, no error is raised.");
 337
 338PyDoc_STRVAR(PyHKEY_Detach_doc,
 339"int = key.Detach() - Detaches the Windows handle from the handle object.\n"
 340"\n"
 341"The result is the value of the handle before it is detached.  If the\n"
 342"handle is already detached, this will return zero.\n"
 343"\n"
 344"After calling this function, the handle is effectively invalidated,\n"
 345"but the handle is not closed.  You would call this function when you\n"
 346"need the underlying win32 handle to exist beyond the lifetime of the\n"
 347"handle object.\n"
 348"On 64 bit windows, the result of this function is a long integer");
 349
 350
 351/************************************************************************
 352
 353  The PyHKEY object definition
 354
 355************************************************************************/
 356typedef struct {
 357	PyObject_VAR_HEAD
 358	HKEY hkey;
 359} PyHKEYObject;
 360
 361#define PyHKEY_Check(op) ((op)->ob_type == &PyHKEY_Type)
 362
 363static char *failMsg = "bad operand type";
 364
 365static PyObject *
 366PyHKEY_unaryFailureFunc(PyObject *ob)
 367{
 368	PyErr_SetString(PyExc_TypeError, failMsg);
 369	return NULL;
 370}
 371static PyObject *
 372PyHKEY_binaryFailureFunc(PyObject *ob1, PyObject *ob2)
 373{
 374	PyErr_SetString(PyExc_TypeError, failMsg);
 375	return NULL;
 376}
 377static PyObject *
 378PyHKEY_ternaryFailureFunc(PyObject *ob1, PyObject *ob2, PyObject *ob3)
 379{
 380	PyErr_SetString(PyExc_TypeError, failMsg);
 381	return NULL;
 382}
 383
 384static void
 385PyHKEY_deallocFunc(PyObject *ob)
 386{
 387	/* Can not call PyHKEY_Close, as the ob->tp_type
 388	   has already been cleared, thus causing the type
 389	   check to fail!
 390	*/
 391	PyHKEYObject *obkey = (PyHKEYObject *)ob;
 392	if (obkey->hkey)
 393		RegCloseKey((HKEY)obkey->hkey);
 394	PyObject_DEL(ob);
 395}
 396
 397static int
 398PyHKEY_nonzeroFunc(PyObject *ob)
 399{
 400	return ((PyHKEYObject *)ob)->hkey != 0;
 401}
 402
 403static PyObject *
 404PyHKEY_intFunc(PyObject *ob)
 405{
 406	PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
 407	return PyLong_FromVoidPtr(pyhkey->hkey);
 408}
 409
 410static int
 411PyHKEY_printFunc(PyObject *ob, FILE *fp, int flags)
 412{
 413	PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
 414	char resBuf[160];
 415	wsprintf(resBuf, "<PyHKEY at %p (%p)>",
 416		 ob, pyhkey->hkey);
 417	fputs(resBuf, fp);
 418	return 0;
 419}
 420
 421static PyObject *
 422PyHKEY_strFunc(PyObject *ob)
 423{
 424	PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
 425	char resBuf[160];
 426	wsprintf(resBuf, "<PyHKEY:%p>", pyhkey->hkey);
 427	return PyString_FromString(resBuf);
 428}
 429
 430static int
 431PyHKEY_compareFunc(PyObject *ob1, PyObject *ob2)
 432{
 433	PyHKEYObject *pyhkey1 = (PyHKEYObject *)ob1;
 434	PyHKEYObject *pyhkey2 = (PyHKEYObject *)ob2;
 435	return pyhkey1 == pyhkey2 ? 0 :
 436		 (pyhkey1 < pyhkey2 ? -1 : 1);
 437}
 438
 439static long
 440PyHKEY_hashFunc(PyObject *ob)
 441{
 442	/* Just use the address.
 443	   XXX - should we use the handle value?
 444	*/
 445	return _Py_HashPointer(ob);
 446}
 447
 448
 449static PyNumberMethods PyHKEY_NumberMethods =
 450{
 451	PyHKEY_binaryFailureFunc,	/* nb_add */
 452	PyHKEY_binaryFailureFunc,	/* nb_subtract */
 453	PyHKEY_binaryFailureFunc,	/* nb_multiply */
 454	PyHKEY_binaryFailureFunc,	/* nb_divide */
 455	PyHKEY_binaryFailureFunc,	/* nb_remainder */
 456	PyHKEY_binaryFailureFunc,	/* nb_divmod */
 457	PyHKEY_ternaryFailureFunc,	/* nb_power */
 458	PyHKEY_unaryFailureFunc,	/* nb_negative */
 459	PyHKEY_unaryFailureFunc,	/* nb_positive */
 460	PyHKEY_unaryFailureFunc,	/* nb_absolute */
 461	PyHKEY_nonzeroFunc,		/* nb_nonzero */
 462	PyHKEY_unaryFailureFunc,	/* nb_invert */
 463	PyHKEY_binaryFailureFunc,	/* nb_lshift */
 464	PyHKEY_binaryFailureFunc,	/* nb_rshift */
 465	PyHKEY_binaryFailureFunc,	/* nb_and */
 466	PyHKEY_binaryFailureFunc,	/* nb_xor */
 467	PyHKEY_binaryFailureFunc,	/* nb_or */
 468	0,		/* nb_coerce (allowed to be zero) */
 469	PyHKEY_intFunc,			/* nb_int */
 470	PyHKEY_unaryFailureFunc,	/* nb_long */
 471	PyHKEY_unaryFailureFunc,	/* nb_float */
 472	PyHKEY_unaryFailureFunc,	/* nb_oct */
 473	PyHKEY_unaryFailureFunc,	/* nb_hex */
 474};
 475
 476
 477/* fwd declare __getattr__ */
 478static PyObject *PyHKEY_getattr(PyObject *self, const char *name);
 479
 480/* The type itself */
 481PyTypeObject PyHKEY_Type =
 482{
 483	PyVarObject_HEAD_INIT(0, 0) /* fill in type at module init */
 484	"PyHKEY",
 485	sizeof(PyHKEYObject),
 486	0,
 487	PyHKEY_deallocFunc,		/* tp_dealloc */
 488	PyHKEY_printFunc,		/* tp_print */
 489	PyHKEY_getattr,			/* tp_getattr */
 490	0,				/* tp_setattr */
 491	PyHKEY_compareFunc,		/* tp_compare */
 492	0,				/* tp_repr */
 493	&PyHKEY_NumberMethods,		/* tp_as_number */
 494	0,				/* tp_as_sequence */
 495	0,				/* tp_as_mapping */
 496	PyHKEY_hashFunc,		/* tp_hash */
 497	0,				/* tp_call */
 498	PyHKEY_strFunc,			/* tp_str */
 499	0,				/* tp_getattro */
 500	0,				/* tp_setattro */
 501	0,				/* tp_as_buffer */
 502	0,				/* tp_flags */
 503	PyHKEY_doc,			/* tp_doc */
 504};
 505
 506#define OFF(e) offsetof(PyHKEYObject, e)
 507
 508static struct memberlist PyHKEY_memberlist[] = {
 509	{"handle",      T_INT,      OFF(hkey)},
 510	{NULL}    /* Sentinel */
 511};
 512
 513/************************************************************************
 514
 515  The PyHKEY object methods
 516
 517************************************************************************/
 518static PyObject *
 519PyHKEY_CloseMethod(PyObject *self, PyObject *args)
 520{
 521	if (!PyArg_ParseTuple(args, ":Close"))
 522		return NULL;
 523	if (!PyHKEY_Close(self))
 524		return NULL;
 525	Py_INCREF(Py_None);
 526	return Py_None;
 527}
 528
 529static PyObject *
 530PyHKEY_DetachMethod(PyObject *self, PyObject *args)
 531{
 532	void* ret;
 533	PyHKEYObject *pThis = (PyHKEYObject *)self;
 534	if (!PyArg_ParseTuple(args, ":Detach"))
 535		return NULL;
 536	ret = (void*)pThis->hkey;
 537	pThis->hkey = 0;
 538	return PyLong_FromVoidPtr(ret);
 539}
 540
 541static PyObject *
 542PyHKEY_Enter(PyObject *self)
 543{
 544	Py_XINCREF(self);
 545	return self;
 546}
 547
 548static PyObject *
 549PyHKEY_Exit(PyObject *self, PyObject *args)
 550{
 551	if (!PyHKEY_Close(self))
 552		return NULL;
 553	Py_RETURN_NONE;
 554}
 555
 556
 557static struct PyMethodDef PyHKEY_methods[] = {
 558	{"Close",  PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc},
 559	{"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc},
 560	{"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL},
 561	{"__exit__", PyHKEY_Exit, METH_VARARGS, NULL},
 562	{NULL}
 563};
 564
 565/*static*/ PyObject *
 566PyHKEY_getattr(PyObject *self, const char *name)
 567{
 568	PyObject *res;
 569
 570	res = Py_FindMethod(PyHKEY_methods, self, name);
 571	if (res != NULL)
 572		return res;
 573	PyErr_Clear();
 574	if (strcmp(name, "handle") == 0)
 575		return PyLong_FromVoidPtr(((PyHKEYObject *)self)->hkey);
 576	return PyMember_Get((char *)self, PyHKEY_memberlist, name);
 577}
 578
 579/************************************************************************
 580   The public PyHKEY API (well, not public yet :-)
 581************************************************************************/
 582PyObject *
 583PyHKEY_New(HKEY hInit)
 584{
 585	PyHKEYObject *key = PyObject_NEW(PyHKEYObject, &PyHKEY_Type);
 586	if (key)
 587		key->hkey = hInit;
 588	return (PyObject *)key;
 589}
 590
 591BOOL
 592PyHKEY_Close(PyObject *ob_handle)
 593{
 594	LONG rc;
 595	PyHKEYObject *key;
 596
 597	if (!PyHKEY_Check(ob_handle)) {
 598		PyErr_SetString(PyExc_TypeError, "bad operand type");
 599		return FALSE;
 600	}
 601	key = (PyHKEYObject *)ob_handle;
 602	rc = key->hkey ? RegCloseKey((HKEY)key->hkey) : ERROR_SUCCESS;
 603	key->hkey = 0;
 604	if (rc != ERROR_SUCCESS)
 605		PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
 606	return rc == ERROR_SUCCESS;
 607}
 608
 609BOOL
 610PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK)
 611{
 612	if (ob == Py_None) {
 613		if (!bNoneOK) {
 614			PyErr_SetString(
 615				  PyExc_TypeError,
 616				  "None is not a valid HKEY in this context");
 617			return FALSE;
 618		}
 619		*pHANDLE = (HKEY)0;
 620	}
 621	else if (PyHKEY_Check(ob)) {
 622		PyHKEYObject *pH = (PyHKEYObject *)ob;
 623		*pHANDLE = pH->hkey;
 624	}
 625	else if (PyInt_Check(ob) || PyLong_Check(ob)) {
 626		/* We also support integers */
 627		PyErr_Clear();
 628		*pHANDLE = (HKEY)PyLong_AsVoidPtr(ob);
 629		if (PyErr_Occurred())
 630			return FALSE;
 631	}
 632	else {
 633		PyErr_SetString(
 634				PyExc_TypeError,
 635			"The object is not a PyHKEY object");
 636		return FALSE;
 637	}
 638	return TRUE;
 639}
 640
 641PyObject *
 642PyHKEY_FromHKEY(HKEY h)
 643{
 644	PyHKEYObject *op;
 645
 646	/* Inline PyObject_New */
 647	op = (PyHKEYObject *) PyObject_MALLOC(sizeof(PyHKEYObject));
 648	if (op == NULL)
 649		return PyErr_NoMemory();
 650	PyObject_INIT(op, &PyHKEY_Type);
 651	op->hkey = h;
 652	return (PyObject *)op;
 653}
 654
 655
 656/************************************************************************
 657  The module methods
 658************************************************************************/
 659BOOL
 660PyWinObject_CloseHKEY(PyObject *obHandle)
 661{
 662	BOOL ok;
 663	if (PyHKEY_Check(obHandle)) {
 664		ok = PyHKEY_Close(obHandle);
 665	}
 666#if SIZEOF_LONG >= SIZEOF_HKEY
 667	else if (PyInt_Check(obHandle)) {
 668		long rc = RegCloseKey((HKEY)PyInt_AsLong(obHandle));
 669		ok = (rc == ERROR_SUCCESS);
 670		if (!ok)
 671			PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
 672	}
 673#else
 674	else if (PyLong_Check(obHandle)) {
 675		long rc = RegCloseKey((HKEY)PyLong_AsVoidPtr(obHandle));
 676		ok = (rc == ERROR_SUCCESS);
 677		if (!ok)
 678			PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
 679	}
 680#endif
 681	else {
 682		PyErr_SetString(
 683			PyExc_TypeError,
 684			"A handle must be a HKEY object or an integer");
 685		return FALSE;
 686	}
 687	return ok;
 688}
 689
 690
 691/*
 692   Private Helper functions for the registry interfaces
 693
 694** Note that fixupMultiSZ and countString have both had changes
 695** made to support "incorrect strings".  The registry specification
 696** calls for strings to be terminated with 2 null bytes.  It seems
 697** some commercial packages install strings which don't conform,
 698** causing this code to fail - however, "regedit" etc still work
 699** with these strings (ie only we don't!).
 700*/
 701static void
 702fixupMultiSZ(char **str, char *data, int len)
 703{
 704	char *P;
 705	int i;
 706	char *Q;
 707
 708	Q = data + len;
 709	for (P = data, i = 0; P < Q && *P != '\0'; P++, i++) {
 710		str[i] = P;
 711		for(; *P != '\0'; P++)
 712			;
 713	}
 714}
 715
 716static int
 717countStrings(char *data, int len)
 718{
 719	int strings;
 720	char *P;
 721	char *Q = data + len;
 722
 723	for (P = data, strings = 0; P < Q && *P != '\0'; P++, strings++)
 724		for (; P < Q && *P != '\0'; P++)
 725			;
 726	return strings;
 727}
 728
 729/* Convert PyObject into Registry data.
 730   Allocates space as needed. */
 731static BOOL
 732Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
 733{
 734	Py_ssize_t i,j;
 735	switch (typ) {
 736		case REG_DWORD:
 737			if (value != Py_None && !PyInt_Check(value))
 738				return FALSE;
 739			*retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1);
 740			if (*retDataBuf==NULL){
 741				PyErr_NoMemory();
 742				return FALSE;
 743			}
 744			*retDataSize = sizeof(DWORD);
 745			if (value == Py_None) {
 746				DWORD zero = 0;
 747				memcpy(*retDataBuf, &zero, sizeof(DWORD));
 748			}
 749			else
 750				memcpy(*retDataBuf,
 751				       &PyInt_AS_LONG((PyIntObject *)value),
 752				       sizeof(DWORD));
 753			break;
 754		case REG_SZ:
 755		case REG_EXPAND_SZ:
 756			{
 757			int need_decref = 0;
 758			if (value == Py_None)
 759				*retDataSize = 1;
 760			else {
 761				if (PyUnicode_Check(value)) {
 762					value = PyUnicode_AsEncodedString(
 763						      value,
 764						      "mbcs",
 765						      NULL);
 766					if (value==NULL)
 767						return FALSE;
 768					need_decref = 1;
 769				}
 770				if (!PyString_Check(value))
 771					return FALSE;
 772				*retDataSize = 1 + strlen(
 773					PyString_AS_STRING(
 774						(PyStringObject *)value));
 775			}
 776			*retDataBuf = (BYTE *)PyMem_NEW(DWORD, *retDataSize);
 777			if (*retDataBuf==NULL){
 778				PyErr_NoMemory();
 779				return FALSE;
 780			}
 781			if (value == Py_None)
 782				strcpy((char *)*retDataBuf, "");
 783			else
 784				strcpy((char *)*retDataBuf,
 785				       PyString_AS_STRING(
 786				       		(PyStringObject *)value));
 787			if (need_decref)
 788				Py_DECREF(value);
 789			break;
 790			}
 791		case REG_MULTI_SZ:
 792			{
 793				DWORD size = 0;
 794				char *P;
 795				PyObject **obs = NULL;
 796
 797				if (value == Py_None)
 798					i = 0;
 799				else {
 800					if (!PyList_Check(value))
 801						return FALSE;
 802					i = PyList_Size(value);
 803				}
 804				obs = malloc(sizeof(PyObject *) * i);
 805				memset(obs, 0, sizeof(PyObject *) * i);
 806				for (j = 0; j < i; j++)
 807				{
 808					PyObject *t;
 809					t = PyList_GET_ITEM(
 810						(PyListObject *)value,j);
 811					if (PyString_Check(t)) {
 812						obs[j] = t;
 813						Py_INCREF(t);
 814					} else if (PyUnicode_Check(t)) {
 815						obs[j] = PyUnicode_AsEncodedString(
 816								t,
 817								"mbcs",
 818								NULL);
 819						if (obs[j]==NULL)
 820							goto reg_multi_fail;
 821					} else
 822						goto reg_multi_fail;
 823					size += 1 + strlen(
 824						PyString_AS_STRING(
 825							(PyStringObject *)obs[j]));
 826				}
 827
 828				*retDataSize = size + 1;
 829				*retDataBuf = (BYTE *)PyMem_NEW(char,
 830							        *retDataSize);
 831				if (*retDataBuf==NULL){
 832					PyErr_NoMemory();
 833					goto reg_multi_fail;
 834				}
 835				P = (char *)*retDataBuf;
 836
 837				for (j = 0; j < i; j++)
 838				{
 839					PyObject *t;
 840					t = obs[j];
 841					strcpy(P,
 842					       PyString_AS_STRING(
 843					       		(PyStringObject *)t));
 844					P += 1 + strlen(
 845						PyString_AS_STRING(
 846							(PyStringObject *)t));
 847					Py_DECREF(obs[j]);
 848				}
 849				/* And doubly-terminate the list... */
 850				*P = '\0';
 851				free(obs);
 852				break;
 853			reg_multi_fail:
 854				if (obs) {
 855					for (j = 0; j < i; j++)
 856						Py_XDECREF(obs[j]);
 857
 858					free(obs);
 859				}
 860				return FALSE;
 861			}
 862		case REG_BINARY:
 863		/* ALSO handle ALL unknown data types here.  Even if we can't
 864		   support it natively, we should handle the bits. */
 865		default:
 866			if (value == Py_None)
 867				*retDataSize = 0;
 868			else {
 869				void *src_buf;
 870				PyBufferProcs *pb = value->ob_type->tp_as_buffer;
 871				if (pb==NULL) {
 872					PyErr_Format(PyExc_TypeError,
 873						"Objects of type '%s' can not "
 874						"be used as binary registry values",
 875						value->ob_type->tp_name);
 876					return FALSE;
 877				}
 878				*retDataSize = (*pb->bf_getreadbuffer)(value, 0, &src_buf);
 879				*retDataBuf = (BYTE *)PyMem_NEW(char,
 880								*retDataSize);
 881				if (*retDataBuf==NULL){
 882					PyErr_NoMemory();
 883					return FALSE;
 884				}
 885				memcpy(*retDataBuf, src_buf, *retDataSize);
 886			}
 887			break;
 888	}
 889	return TRUE;
 890}
 891
 892/* Convert Registry data into PyObject*/
 893static PyObject *
 894Reg2Py(char *retDataBuf, DWORD retDataSize, DWORD typ)
 895{
 896	PyObject *obData;
 897
 898	switch (typ) {
 899		case REG_DWORD:
 900			if (retDataSize == 0)
 901				obData = Py_BuildValue("i", 0);
 902			else
 903				obData = Py_BuildValue("i",
 904						       *(int *)retDataBuf);
 905			break;
 906		case REG_SZ:
 907		case REG_EXPAND_SZ:
 908			/* retDataBuf may or may not have a trailing NULL in
 909			   the buffer. */
 910			if (retDataSize && retDataBuf[retDataSize-1] == '\0')
 911				--retDataSize;
 912			if (retDataSize ==0)
 913				retDataBuf = "";
 914			obData = PyUnicode_DecodeMBCS(retDataBuf,
 915						      retDataSize,
 916						      NULL);
 917			break;
 918		case REG_MULTI_SZ:
 919			if (retDataSize == 0)
 920				obData = PyList_New(0);
 921			else
 922			{
 923				int index = 0;
 924				int s = countStrings(retDataBuf, retDataSize);
 925				char **str = (char **)malloc(sizeof(char *)*s);
 926				if (str == NULL)
 927					return PyErr_NoMemory();
 928
 929				fixupMultiSZ(str, retDataBuf, retDataSize);
 930				obData = PyList_New(s);
 931				if (obData == NULL)
 932					return NULL;
 933				for (index = 0; index < s; index++)
 934				{
 935					size_t len = _mbstrlen(str[index]);
 936					if (len > INT_MAX) {
 937						PyErr_SetString(PyExc_OverflowError,
 938							"registry string is too long for a Python string");
 939						Py_DECREF(obData);
 940						return NULL;
 941					}
 942					PyList_SetItem(obData,
 943						       index,
 944						       PyUnicode_DecodeMBCS(
 945						            (const char *)str[index],
 946							   (int)len,
 947							    NULL)
 948						       );
 949				}
 950				free(str);
 951
 952				break;
 953			}
 954		case REG_BINARY:
 955		/* ALSO handle ALL unknown data types here.  Even if we can't
 956		   support it natively, we should handle the bits. */
 957		default:
 958			if (retDataSize == 0) {
 959				Py_INCREF(Py_None);
 960				obData = Py_None;
 961			}
 962			else
 963				obData = Py_BuildValue("s#",
 964					 	       (char *)retDataBuf,
 965					 	       retDataSize);
 966			break;
 967	}
 968	if (obData == NULL)
 969		return NULL;
 970	else
 971		return obData;
 972}
 973
 974/* The Python methods */
 975
 976static PyObject *
 977PyCloseKey(PyObject *self, PyObject *args)
 978{
 979	PyObject *obKey;
 980	if (!PyArg_ParseTuple(args, "O:CloseKey", &obKey))
 981		return NULL;
 982	if (!PyHKEY_Close(obKey))
 983		return NULL;
 984	Py_INCREF(Py_None);
 985	return Py_None;
 986}
 987
 988static PyObject *
 989PyConnectRegistry(PyObject *self, PyObject *args)
 990{
 991	HKEY hKey;
 992	PyObject *obKey;
 993	char *szCompName = NULL;
 994	HKEY retKey;
 995	long rc;
 996	if (!PyArg_ParseTuple(args, "zO:ConnectRegistry", &szCompName, &obKey))
 997		return NULL;
 998	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
 999		return NULL;
1000	Py_BEGIN_ALLOW_THREADS
1001	rc = RegConnectRegistry(szCompName, hKey, &retKey);
1002	Py_END_ALLOW_THREADS
1003	if (rc != ERROR_SUCCESS)
1004		return PyErr_SetFromWindowsErrWithFunction(rc,
1005							   "ConnectRegistry");
1006	return PyHKEY_FromHKEY(retKey);
1007}
1008
1009static PyObject *
1010PyCreateKey(PyObject *self, PyObject *args)
1011{
1012	HKEY hKey;
1013	PyObject *obKey;
1014	char *subKey;
1015	HKEY retKey;
1016	long rc;
1017	if (!PyArg_ParseTuple(args, "Oz:CreateKey", &obKey, &subKey))
1018		return NULL;
1019	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1020		return NULL;
1021	rc = RegCreateKey(hKey, subKey, &retKey);
1022	if (rc != ERROR_SUCCESS)
1023		return PyErr_SetFromWindowsErrWithFunction(rc, "CreateKey");
1024	return PyHKEY_FromHKEY(retKey);
1025}
1026
1027static PyObject *
1028PyDeleteKey(PyObject *self, PyObject *args)
1029{
1030	HKEY hKey;
1031	PyObject *obKey;
1032	char *subKey;
1033	long rc;
1034	if (!PyArg_ParseTuple(args, "Os:DeleteKey", &obKey, &subKey))
1035		return NULL;
1036	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1037		return NULL;
1038	rc = RegDeleteKey(hKey, subKey );
1039	if (rc != ERROR_SUCCESS)
1040		return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey");
1041	Py_INCREF(Py_None);
1042	return Py_None;
1043}
1044
1045static PyObject *
1046PyDeleteValue(PyObject *self, PyObject *args)
1047{
1048	HKEY hKey;
1049	PyObject *obKey;
1050	char *subKey;
1051	long rc;
1052	if (!PyArg_ParseTuple(args, "Oz:DeleteValue", &obKey, &subKey))
1053		return NULL;
1054	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1055		return NULL;
1056	Py_BEGIN_ALLOW_THREADS
1057	rc = RegDeleteValue(hKey, subKey);
1058	Py_END_ALLOW_THREADS
1059	if (rc !=ERROR_SUCCESS)
1060		return PyErr_SetFromWindowsErrWithFunction(rc,
1061							   "RegDeleteValue");
1062	Py_INCREF(Py_None);
1063	return Py_None;
1064}
1065
1066static PyObject *
1067PyEnumKey(PyObject *self, PyObject *args)
1068{
1069	HKEY hKey;
1070	PyObject *obKey;
1071	int index;
1072	long rc;
1073	PyObject *retStr;
1074	char tmpbuf[256]; /* max key name length is 255 */
1075	DWORD len = sizeof(tmpbuf); /* includes NULL terminator */
1076
1077	if (!PyArg_ParseTuple(args, "Oi:EnumKey", &obKey, &index))
1078		return NULL;
1079	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1080		return NULL;
1081
1082	Py_BEGIN_ALLOW_THREADS
1083	rc = RegEnumKeyEx(hKey, index, tmpbuf, &len, NULL, NULL, NULL, NULL);
1084	Py_END_ALLOW_THREADS
1085	if (rc != ERROR_SUCCESS)
1086		return PyErr_SetFromWindowsErrWithFunction(rc, "RegEnumKeyEx");
1087
1088	retStr = PyString_FromStringAndSize(tmpbuf, len);
1089	return retStr;  /* can be NULL */
1090}
1091
1092static PyObject *
1093PyEnumValue(PyObject *self, PyObject *args)
1094{
1095	HKEY hKey;
1096	PyObject *obKey;
1097	int index;
1098	long rc;
1099	char *retValueBuf;
1100	char *retDataBuf;
1101	DWORD retValueSize;
1102	DWORD retDataSize;
1103	DWORD typ;
1104	PyObject *obData;
1105	PyObject *retVal;
1106
1107	if (!PyArg_ParseTuple(args, "Oi:EnumValue", &obKey, &index))
1108		return NULL;
1109	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1110		return NULL;
1111
1112	if ((rc = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
1113				  NULL,
1114				  &retValueSize, &retDataSize, NULL, NULL))
1115	    != ERROR_SUCCESS)
1116		return PyErr_SetFromWindowsErrWithFunction(rc,
1117							   "RegQueryInfoKey");
1118	++retValueSize;    /* include null terminators */
1119	++retDataSize;
1120	retValueBuf = (char *)PyMem_Malloc(retValueSize);
1121	if (retValueBuf == NULL)
1122		return PyErr_NoMemory();
1123	retDataBuf = (char *)PyMem_Malloc(retDataSize);
1124	if (retDataBuf == NULL) {
1125		PyMem_Free(retValueBuf);
1126		return PyErr_NoMemory();
1127	}
1128
1129	Py_BEGIN_ALLOW_THREADS
1130	rc = RegEnumValue(hKey,
1131			  index,
1132			  retValueBuf,
1133			  &retValueSize,
1134			  NULL,
1135			  &typ,
1136			  (BYTE *)retDataBuf,
1137			  &retDataSize);
1138	Py_END_ALLOW_THREADS
1139
1140	if (rc != ERROR_SUCCESS) {
1141		retVal = PyErr_SetFromWindowsErrWithFunction(rc,
1142							     "PyRegEnumValue");
1143		goto fail;
1144	}
1145	obData = Reg2Py(retDataBuf, retDataSize, typ);
1146	if (obData == NULL) {
1147		retVal = NULL;
1148		goto fail;
1149	}
1150	retVal = Py_BuildValue("sOi", retValueBuf, obData, typ);
1151	Py_DECREF(obData);
1152  fail:
1153	PyMem_Free(retValueBuf);
1154	PyMem_Free(retDataBuf);
1155	return retVal;
1156}
1157
1158static PyObject *
1159PyExpandEnvironmentStrings(PyObject *self, PyObject *args)
1160{
1161	Py_UNICODE *retValue = NULL;
1162	Py_UNICODE *src;
1163	DWORD retValueSize;
1164	DWORD rc;
1165	PyObject *o;
1166
1167	if (!PyArg_ParseTuple(args, "u:ExpandEnvironmentStrings", &src))
1168		return NULL;
1169
1170	retValueSize = ExpandEnvironmentStringsW(src, retValue, 0);
1171	if (retValueSize == 0) {
1172		return PyErr_SetFromWindowsErrWithFunction(retValueSize,
1173						"ExpandEnvironmentStrings");
1174	}
1175	retValue = (Py_UNICODE *)PyMem_Malloc(retValueSize * sizeof(Py_UNICODE));
1176	if (retValue == NULL) {
1177		return PyErr_NoMemory();
1178	}
1179
1180	rc = ExpandEnvironmentStringsW(src, retValue, retValueSize);
1181	if (rc == 0) {
1182		PyMem_Free(retValue);
1183		return PyErr_SetFromWindowsErrWithFunction(retValueSize,
1184						"ExpandEnvironmentStrings");
1185	}
1186	o = PyUnicode_FromUnicode(retValue, wcslen(retValue));
1187	PyMem_Free(retValue);
1188	return o;
1189}
1190
1191static PyObject *
1192PyFlushKey(PyObject *self, PyObject *args)
1193{
1194	HKEY hKey;
1195	PyObject *obKey;
1196	long rc;
1197	if (!PyArg_ParseTuple(args, "O:FlushKey", &obKey))
1198		return NULL;
1199	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1200		return NULL;
1201	Py_BEGIN_ALLOW_THREADS
1202	rc = RegFlushKey(hKey);
1203	Py_END_ALLOW_THREADS
1204	if (rc != ERROR_SUCCESS)
1205		return PyErr_SetFromWindowsErrWithFunction(rc, "RegFlushKey");
1206	Py_INCREF(Py_None);
1207	return Py_None;
1208}
1209static PyObject *
1210PyLoadKey(PyObject *self, PyObject *args)
1211{
1212	HKEY hKey;
1213	PyObject *obKey;
1214	char *subKey;
1215	char *fileName;
1216
1217	long rc;
1218	if (!PyArg_ParseTuple(args, "Oss:LoadKey", &obKey, &subKey, &fileName))
1219		return NULL;
1220	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1221		return NULL;
1222	Py_BEGIN_ALLOW_THREADS
1223	rc = RegLoadKey(hKey, subKey, fileName );
1224	Py_END_ALLOW_THREADS
1225	if (rc != ERROR_SUCCESS)
1226		return PyErr_SetFromWindowsErrWithFunction(rc, "RegLoadKey");
1227	Py_INCREF(Py_None);
1228	return Py_None;
1229}
1230
1231static PyObject *
1232PyOpenKey(PyObject *self, PyObject *args)
1233{
1234	HKEY hKey;
1235	PyObject *obKey;
1236
1237	char *subKey;
1238	int res = 0;
1239	HKEY retKey;
1240	long rc;
1241	REGSAM sam = KEY_READ;
1242	if (!PyArg_ParseTuple(args, "Oz|ii:OpenKey", &obKey, &subKey,
1243	                      &res, &sam))
1244		return NULL;
1245	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1246		return NULL;
1247
1248	Py_BEGIN_ALLOW_THREADS
1249	rc = RegOpenKeyEx(hKey, subKey, res, sam, &retKey);
1250	Py_END_ALLOW_THREADS
1251	if (rc != ERROR_SUCCESS)
1252		return PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx");
1253	return PyHKEY_FromHKEY(retKey);
1254}
1255
1256
1257static PyObject *
1258PyQueryInfoKey(PyObject *self, PyObject *args)
1259{
1260  HKEY hKey;
1261  PyObject *obKey;
1262  long rc;
1263  DWORD nSubKeys, nValues;
1264  FILETIME ft;
1265  LARGE_INTEGER li;
1266  PyObject *l;
1267  PyObject *ret;
1268  if (!PyArg_ParseTuple(args, "O:QueryInfoKey", &obKey))
1269	return NULL;
1270  if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1271	return NULL;
1272  if ((rc = RegQueryInfoKey(hKey, NULL, NULL, 0, &nSubKeys, NULL, NULL,
1273			    &nValues,  NULL,  NULL, NULL, &ft))
1274      != ERROR_SUCCESS)
1275	return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryInfoKey");
1276  li.LowPart = ft.dwLowDateTime;
1277  li.HighPart = ft.dwHighDateTime;
1278  l = PyLong_FromLongLong(li.QuadPart);
1279  if (l == NULL)
1280	return NULL;
1281  ret = Py_BuildValue("iiO", nSubKeys, nValues, l);
1282  Py_DECREF(l);
1283  return ret;
1284}
1285
1286static PyObject *
1287PyQueryValue(PyObject *self, PyObject *args)
1288{
1289	HKEY hKey;
1290	PyObject *obKey;
1291	char *subKey;
1292	long rc;
1293	PyObject *retStr;
1294	char *retBuf;
1295	long bufSize = 0;
1296
1297	if (!PyArg_ParseTuple(args, "Oz:QueryValue", &obKey, &subKey))
1298		return NULL;
1299
1300	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1301		return NULL;
1302	if ((rc = RegQueryValue(hKey, subKey, NULL, &bufSize))
1303	    != ERROR_SUCCESS)
1304		return PyErr_SetFromWindowsErrWithFunction(rc,
1305							   "RegQueryValue");
1306	retStr = PyString_FromStringAndSize(NULL, bufSize);
1307	if (retStr == NULL)
1308		return NULL;
1309	retBuf = PyString_AS_STRING(retStr);
1310	if ((rc = RegQueryValue(hKey, subKey, retBuf, &bufSize))
1311	    != ERROR_SUCCESS) {
1312		Py_DECREF(retStr);
1313		return PyErr_SetFromWindowsErrWithFunction(rc,
1314							   "RegQueryValue");
1315	}
1316	_PyString_Resize(&retStr, strlen(retBuf));
1317	return retStr;
1318}
1319
1320static PyObject *
1321PyQueryValueEx(PyObject *self, PyObject *args)
1322{
1323	HKEY hKey;
1324	PyObject *obKey;
1325	char *valueName;
1326
1327	long rc;
1328	char *retBuf;
1329	DWORD bufSize = 0;
1330	DWORD typ;
1331	PyObject *obData;
1332	PyObject *result;
1333
1334	if (!PyArg_ParseTuple(args, "Oz:QueryValueEx", &obKey, &valueName))
1335		return NULL;
1336
1337	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1338		return NULL;
1339	if ((rc = RegQueryValueEx(hKey, valueName,
1340				  NULL, NULL, NULL,
1341				  &bufSize))
1342	    != ERROR_SUCCESS)
1343		return PyErr_SetFromWindowsErrWithFunction(rc,
1344							   "RegQueryValueEx");
1345	retBuf = (char *)PyMem_Malloc(bufSize);
1346	if (retBuf == NULL)
1347		return PyErr_NoMemory();
1348	if ((rc = RegQueryValueEx(hKey, valueName, NULL,
1349				  &typ, (BYTE *)retBuf, &bufSize))
1350	    != ERROR_SUCCESS) {
1351		PyMem_Free(retBuf);
1352		return PyErr_SetFromWindowsErrWithFunction(rc,
1353							   "RegQueryValueEx");
1354	}
1355	obData = Reg2Py(retBuf, bufSize, typ);
1356	PyMem_Free((void *)retBuf);
1357	if (obData == NULL)
1358		return NULL;
1359	result = Py_BuildValue("Oi", obData, typ);
1360	Py_DECREF(obData);
1361	return result;
1362}
1363
1364
1365static PyObject *
1366PySaveKey(PyObject *self, PyObject *args)
1367{
1368	HKEY hKey;
1369	PyObject *obKey;
1370	char *fileName;
1371	LPSECURITY_ATTRIBUTES pSA = NULL;
1372
1373	long rc;
1374	if (!PyArg_ParseTuple(args, "Os:SaveKey", &obKey, &fileName))
1375		return NULL;
1376	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1377		return NULL;
1378/*  One day we may get security into the core?
1379	if (!PyWinObject_AsSECURITY_ATTRIBUTES(obSA, &pSA, TRUE))
1380		return NULL;
1381*/
1382	Py_BEGIN_ALLOW_THREADS
1383	rc = RegSaveKey(hKey, fileName, pSA );
1384	Py_END_ALLOW_THREADS
1385	if (rc != ERROR_SUCCESS)
1386		return PyErr_SetFromWindowsErrWithFunction(rc, "RegSaveKey");
1387	Py_INCREF(Py_None);
1388	return Py_None;
1389}
1390
1391static PyObject *
1392PySetValue(PyObject *self, PyObject *args)
1393{
1394	HKEY hKey;
1395	PyObject *obKey;
1396	char *subKey;
1397	char *str;
1398	DWORD typ;
1399	DWORD len;
1400	long rc;
1401	PyObject *obStrVal;
1402	PyObject *obSubKey;
1403	if (!PyArg_ParseTuple(args, "OOiO:SetValue",
1404			      &obKey,
1405			      &obSubKey,
1406			      &typ,
1407			      &obStrVal))
1408		return NULL;
1409	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1410		return NULL;
1411	if (typ != REG_SZ) {
1412		PyErr_SetString(PyExc_TypeError,
1413				"Type must be _winreg.REG_SZ");
1414		return NULL;
1415	}
1416	/* XXX - need Unicode support */
1417	str = PyString_AsString(obStrVal);
1418	if (str == NULL)
1419		return NULL;
1420	len = PyString_Size(obStrVal);
1421	if (obSubKey == Py_None)
1422		subKey = NULL;
1423	else {
1424		subKey = PyString_AsString(obSubKey);
1425		if (subKey == NULL)
1426			return NULL;
1427	}
1428	Py_BEGIN_ALLOW_THREADS
1429	rc = RegSetValue(hKey, subKey, REG_SZ, str, len+1);
1430	Py_END_ALLOW_THREADS
1431	if (rc != ERROR_SUCCESS)
1432		return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue");
1433	Py_INCREF(Py_None);
1434	return Py_None;
1435}
1436
1437static PyObject *
1438PySetValueEx(PyObject *self, PyObject *args)
1439{
1440	HKEY hKey;
1441	PyObject *obKey;
1442	char *valueName;
1443	PyObject *obRes;
1444	PyObject *value;
1445	BYTE *data;
1446	DWORD len;
1447	DWORD typ;
1448
1449	LONG rc;
1450
1451	if (!PyArg_ParseTuple(args, "OzOiO:SetValueEx",
1452			      &obKey,
1453			      &valueName,
1454			      &obRes,
1455			      &typ,
1456			      &value))
1457		return NULL;
1458	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1459		return NULL;
1460	if (!Py2Reg(value, typ, &data, &len))
1461	{
1462		if (!PyErr_Occurred())
1463			PyErr_SetString(PyExc_ValueError,
1464				 "Could not convert the data to the specified type.");
1465		return NULL;
1466	}
1467	Py_BEGIN_ALLOW_THREADS
1468	rc = RegSetValueEx(hKey, valueName, 0, typ, data, len);
1469	Py_END_ALLOW_THREADS
1470	PyMem_DEL(data);
1471	if (rc != ERROR_SUCCESS)
1472		return PyErr_SetFromWindowsErrWithFunction(rc,
1473							   "RegSetValueEx");
1474	Py_INCREF(Py_None);
1475	return Py_None;
1476}
1477
1478static PyObject *
1479PyDisableReflectionKey(PyObject *self, PyObject *args)
1480{
1481	HKEY hKey;
1482	PyObject *obKey;
1483	HMODULE hMod;
1484	typedef LONG (WINAPI *RDRKFunc)(HKEY);
1485	RDRKFunc pfn = NULL;
1486	LONG rc;
1487
1488	if (!PyArg_ParseTuple(args, "O:DisableReflectionKey", &obKey))
1489		return NULL;
1490	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1491		return NULL;
1492
1493	// Only available on 64bit platforms, so we must load it
1494	// dynamically.
1495	hMod = GetModuleHandle("advapi32.dll");
1496	if (hMod)
1497		pfn = (RDRKFunc)GetProcAddress(hMod,
1498		                               "RegDisableReflectionKey");
1499	if (!pfn) {
1500		PyErr_SetString(PyExc_NotImplementedError,
1501		                "not implemented on this platform");
1502		return NULL;
1503	}
1504	Py_BEGIN_ALLOW_THREADS
1505	rc = (*pfn)(hKey);
1506	Py_END_ALLOW_THREADS
1507	if (rc != ERROR_SUCCESS)
1508		return PyErr_SetFromWindowsErrWithFunction(rc,
1509		                                           "RegDisableReflectionKey");
1510	Py_INCREF(Py_None);
1511	return Py_None;
1512}
1513
1514static PyObject *
1515PyEnableReflectionKey(PyObject *self, PyObject *args)
1516{
1517	HKEY hKey;
1518	PyObject *obKey;
1519	HMODULE hMod;
1520	typedef LONG (WINAPI *RERKFunc)(HKEY);
1521	RERKFunc pfn = NULL;
1522	LONG rc;
1523
1524	if (!PyArg_ParseTuple(args, "O:EnableReflectionKey", &obKey))
1525		return NULL;
1526	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1527		return NULL;
1528
1529	// Only available on 64bit platforms, so we must load it
1530	// dynamically.
1531	hMod = GetModuleHandle("advapi32.dll");
1532	if (hMod)
1533		pfn = (RERKFunc)GetProcAddress(hMod,
1534		                               "RegEnableReflectionKey");
1535	if (!pfn) {
1536		PyErr_SetString(PyExc_NotImplementedError,
1537		                "not implemented on this platform");
1538		return NULL;
1539	}
1540	Py_BEGIN_ALLOW_THREADS
1541	rc = (*pfn)(hKey);
1542	Py_END_ALLOW_THREADS
1543	if (rc != ERROR_SUCCESS)
1544		return PyErr_SetFromWindowsErrWithFunction(rc,
1545		                                           "RegEnableReflectionKey");
1546	Py_INCREF(Py_None);
1547	return Py_None;
1548}
1549
1550static PyObject *
1551PyQueryReflectionKey(PyObject *self, PyObject *args)
1552{
1553	HKEY hKey;
1554	PyObject *obKey;
1555	HMODULE hMod;
1556	typedef LONG (WINAPI *RQRKFunc)(HKEY, BOOL *);
1557	RQRKFunc pfn = NULL;
1558	BOOL result;
1559	LONG rc;
1560
1561	if (!PyArg_ParseTuple(args, "O:QueryReflectionKey", &obKey))
1562		return NULL;
1563	if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE))
1564		return NULL;
1565
1566	// Only available on 64bit platforms, so we must load it
1567	// dynamically.
1568	hMod = GetModuleHandle("advapi32.dll");
1569	if (hMod)
1570		pfn = (RQRKFunc)GetProcAddress(hMod,
1571		                               "RegQueryReflectionKey");
1572	if (!pfn) {
1573		PyErr_SetString(PyExc_NotImplementedError,
1574		                "not implemented on this platform");
1575		return NULL;
1576	}
1577	Py_BEGIN_ALLOW_THREADS
1578	rc = (*pfn)(hKey, &result);
1579	Py_END_ALLOW_THREADS
1580	if (rc != ERROR_SUCCESS)
1581		return PyErr_SetFromWindowsErrWithFunction(rc,
1582		                                           "RegQueryReflectionKey");
1583	return PyBool_FromLong(rc);
1584}
1585
1586static struct PyMethodDef winreg_methods[] = {
1587	{"CloseKey",         PyCloseKey,        METH_VARARGS, CloseKey_doc},
1588	{"ConnectRegistry",  PyConnectRegistry, METH_VARARGS, ConnectRegistry_doc},
1589	{"CreateKey",        PyCreateKey,       METH_VARARGS, CreateKey_doc},
1590	{"DeleteKey",        PyDeleteKey,       METH_VARARGS, DeleteKey_doc},
1591	{"DeleteValue",      PyDeleteValue,     METH_VARARGS, DeleteValue_doc},
1592	{"DisableReflectionKey", PyDisableReflectionKey, METH_VARARGS, DisableReflectionKey_doc},
1593	{"EnableReflectionKey",  PyEnableReflectionKey,  METH_VARARGS, EnableReflectionKey_doc},
1594	{"EnumKey",          PyEnumKey,         METH_VARARGS, EnumKey_doc},
1595	{"EnumValue",        PyEnumValue,       METH_VARARGS, EnumValue_doc},
1596	{"ExpandEnvironmentStrings", PyExpandEnvironmentStrings, METH_VARARGS,
1597		ExpandEnvironmentStrings_doc },
1598	{"FlushKey",         PyFlushKey,        METH_VARARGS, FlushKey_doc},
1599	{"LoadKey",          PyLoadKey,         METH_VARARGS, LoadKey_doc},
1600	{"OpenKey",          PyOpenKey,         METH_VARARGS, OpenKey_doc},
1601	{"OpenKeyEx",        PyOpenKey,         METH_VARARGS, OpenKeyEx_doc},
1602	{"QueryValue",       PyQueryValue,      METH_VARARGS, QueryValue_doc},
1603	{"QueryValueEx",     PyQueryValueEx,    METH_VARARGS, QueryValueEx_doc},
1604	{"QueryInfoKey",     PyQueryInfoKey,    METH_VARARGS, QueryInfoKey_doc},
1605	{"QueryReflectionKey",PyQueryReflectionKey,METH_VARARGS, QueryReflectionKey_doc},
1606	{"SaveKey",          PySaveKey,         METH_VARARGS, SaveKey_doc},
1607	{"SetValue",         PySetValue,        METH_VARARGS, SetValue_doc},
1608	{"SetValueEx",       PySetValueEx,      METH_VARARGS, SetValueEx_doc},
1609	NULL,
1610};
1611
1612static void
1613insint(PyObject * d, char * name, long value)
1614{
1615	PyObject *v = PyInt_FromLong(value);
1616	if (!v || PyDict_SetItemString(d, name, v))
1617		PyErr_Clear();
1618	Py_XDECREF(v);
1619}
1620
1621#define ADD_INT(val) insint(d, #val, val)
1622
1623static void
1624inskey(PyObject * d, char * name, HKEY key)
1625{
1626	PyObject *v = PyLong_FromVoidPtr(key);
1627	if (!v || PyDict_SetItemString(d, name, v))
1628		PyErr_Clear();
1629	Py_XDECREF(v);
1630}
1631
1632#define ADD_KEY(val) inskey(d, #val, val)
1633
1634PyMODINIT_FUNC init_winreg(void)
1635{
1636	PyObject *m, *d;
1637	m = Py_InitModule3("_winreg", winreg_methods, module_doc);
1638	if (m == NULL)
1639		return;
1640	d = PyModule_GetDict(m);
1641	PyHKEY_Type.ob_type = &PyType_Type;
1642	PyHKEY_Type.tp_doc = PyHKEY_doc;
1643	Py_INCREF(&PyHKEY_Type);
1644	if (PyDict_SetItemString(d, "HKEYType",
1645				 (PyObject *)&PyHKEY_Type) != 0)
1646		return;
1647	Py_INCREF(PyExc_WindowsError);
1648	if (PyDict_SetItemString(d, "error",
1649				 PyExc_WindowsError) != 0)
1650		return;
1651
1652	/* Add the relevant constants */
1653	ADD_KEY(HKEY_CLASSES_ROOT);
1654	ADD_KEY(HKEY_CURRENT_USER);
1655	ADD_KEY(HKEY_LOCAL_MACHINE);
1656	ADD_KEY(HKEY_USERS);
1657	ADD_KEY(HKEY_PERFORMANCE_DATA);
1658#ifdef HKEY_CURRENT_CONFIG
1659	ADD_KEY(HKEY_CURRENT_CONFIG);
1660#endif
1661#ifdef HKEY_DYN_DATA
1662	ADD_KEY(HKEY_DYN_DATA);
1663#endif
1664	ADD_INT(KEY_QUERY_VALUE);
1665	ADD_INT(KEY_SET_VALUE);
1666	ADD_INT(KEY_CREATE_SUB_KEY);
1667	ADD_INT(KEY_ENUMERATE_SUB_KEYS);
1668	ADD_INT(KEY_NOTIFY);
1669	ADD_INT(KEY_CREATE_LINK);
1670	ADD_INT(KEY_READ);
1671	ADD_INT(KEY_WRITE);
1672	ADD_INT(KEY_EXECUTE);
1673	ADD_INT(KEY_ALL_ACCESS);
1674#ifdef KEY_WOW64_64KEY
1675	ADD_INT(KEY_WOW64_64KEY);
1676#endif
1677#ifdef KEY_WOW64_32KEY
1678	ADD_INT(KEY_WOW64_32KEY);
1679#endif
1680	ADD_INT(REG_OPTION_RESERVED);
1681	ADD_INT(REG_OPTION_NON_VOLATILE);
1682	ADD_INT(REG_OPTION_VOLATILE);
1683	ADD_INT(REG_OPTION_CREATE_LINK);
1684	ADD_INT(REG_OPTION_BACKUP_RESTORE);
1685	ADD_INT(REG_OPTION_OPEN_LINK);
1686	ADD_INT(REG_LEGAL_OPTION);
1687	ADD_INT(REG_CREATED_NEW_KEY);
1688	ADD_INT(REG_OPENED_EXISTING_KEY);
1689	ADD_INT(REG_WHOLE_HIVE_VOLATILE);
1690	ADD_INT(REG_REFRESH_HIVE);
1691	ADD_INT(REG_NO_LAZY_FLUSH);
1692	ADD_INT(REG_NOTIFY_CHANGE_NAME);
1693	ADD_INT(REG_NOTIFY_CHANGE_ATTRIBUTES);
1694	ADD_INT(REG_NOTIFY_CHANGE_LAST_SET);
1695	ADD_INT(REG_NOTIFY_CHANGE_SECURITY);
1696	ADD_INT(REG_LEGAL_CHANGE_FILTER);
1697	ADD_INT(REG_NONE);
1698	ADD_INT(REG_SZ);
1699	ADD_INT(REG_EXPAND_SZ);
1700	ADD_INT(REG_BINARY);
1701	ADD_INT(REG_DWORD);
1702	ADD_INT(REG_DWORD_LITTLE_ENDIAN);
1703	ADD_INT(REG_DWORD_BIG_ENDIAN);
1704	ADD_INT(REG_LINK);
1705	ADD_INT(REG_MULTI_SZ);
1706	ADD_INT(REG_RESOURCE_LIST);
1707	ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR);
1708	ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST);
1709}
1710