symbian-qemu-0.9.1-12/python-2.6.1/PC/_winreg.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 
       
    20 static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK);
       
    21 static PyObject *PyHKEY_FromHKEY(HKEY h);
       
    22 static BOOL PyHKEY_Close(PyObject *obHandle);
       
    23 
       
    24 static 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 dont
       
    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 */
       
    37 PyDoc_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 
       
    75 PyDoc_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 
       
    83 PyDoc_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 
       
    94 PyDoc_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 
       
   107 PyDoc_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 
       
   119 PyDoc_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 
       
   125 PyDoc_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 
       
   135 PyDoc_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 
       
   150 PyDoc_STRVAR(ExpandEnvironmentStrings_doc,
       
   151 "string = ExpandEnvironmentStrings(string) - Expand environment vars.\n");
       
   152 
       
   153 PyDoc_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 
       
   166 PyDoc_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 
       
   185 PyDoc_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 
       
   197 PyDoc_STRVAR(OpenKeyEx_doc, "See OpenKey()");
       
   198 
       
   199 PyDoc_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 
       
   210 PyDoc_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 
       
   222 PyDoc_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 
       
   228 PyDoc_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 
       
   242 PyDoc_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 
       
   261 PyDoc_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 
       
   293 PyDoc_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 
       
   300 PyDoc_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 
       
   305 PyDoc_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 */
       
   310 PyDoc_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 
       
   333 PyDoc_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 
       
   338 PyDoc_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 ************************************************************************/
       
   356 typedef struct {
       
   357 	PyObject_VAR_HEAD
       
   358 	HKEY hkey;
       
   359 } PyHKEYObject;
       
   360 
       
   361 #define PyHKEY_Check(op) ((op)->ob_type == &PyHKEY_Type)
       
   362 
       
   363 static char *failMsg = "bad operand type";
       
   364 
       
   365 static PyObject *
       
   366 PyHKEY_unaryFailureFunc(PyObject *ob)
       
   367 {
       
   368 	PyErr_SetString(PyExc_TypeError, failMsg);
       
   369 	return NULL;
       
   370 }
       
   371 static PyObject *
       
   372 PyHKEY_binaryFailureFunc(PyObject *ob1, PyObject *ob2)
       
   373 {
       
   374 	PyErr_SetString(PyExc_TypeError, failMsg);
       
   375 	return NULL;
       
   376 }
       
   377 static PyObject *
       
   378 PyHKEY_ternaryFailureFunc(PyObject *ob1, PyObject *ob2, PyObject *ob3)
       
   379 {
       
   380 	PyErr_SetString(PyExc_TypeError, failMsg);
       
   381 	return NULL;
       
   382 }
       
   383 
       
   384 static void
       
   385 PyHKEY_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 
       
   397 static int
       
   398 PyHKEY_nonzeroFunc(PyObject *ob)
       
   399 {
       
   400 	return ((PyHKEYObject *)ob)->hkey != 0;
       
   401 }
       
   402 
       
   403 static PyObject *
       
   404 PyHKEY_intFunc(PyObject *ob)
       
   405 {
       
   406 	PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
       
   407 	return PyLong_FromVoidPtr(pyhkey->hkey);
       
   408 }
       
   409 
       
   410 static int
       
   411 PyHKEY_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 
       
   421 static PyObject *
       
   422 PyHKEY_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 
       
   430 static int
       
   431 PyHKEY_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 
       
   439 static long
       
   440 PyHKEY_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 
       
   449 static 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__ */
       
   478 static PyObject *PyHKEY_getattr(PyObject *self, const char *name);
       
   479 
       
   480 /* The type itself */
       
   481 PyTypeObject 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 
       
   508 static struct memberlist PyHKEY_memberlist[] = {
       
   509 	{"handle",      T_INT,      OFF(hkey)},
       
   510 	{NULL}    /* Sentinel */
       
   511 };
       
   512 
       
   513 /************************************************************************
       
   514 
       
   515   The PyHKEY object methods
       
   516 
       
   517 ************************************************************************/
       
   518 static PyObject *
       
   519 PyHKEY_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 
       
   529 static PyObject *
       
   530 PyHKEY_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 
       
   541 static PyObject *
       
   542 PyHKEY_Enter(PyObject *self)
       
   543 {
       
   544 	Py_XINCREF(self);
       
   545 	return self;
       
   546 }
       
   547 
       
   548 static PyObject *
       
   549 PyHKEY_Exit(PyObject *self, PyObject *args)
       
   550 {
       
   551 	if (!PyHKEY_Close(self))
       
   552 		return NULL;
       
   553 	Py_RETURN_NONE;
       
   554 }
       
   555 
       
   556 
       
   557 static 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 *
       
   566 PyHKEY_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 ************************************************************************/
       
   582 PyObject *
       
   583 PyHKEY_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 
       
   591 BOOL
       
   592 PyHKEY_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 
       
   609 BOOL
       
   610 PyHKEY_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 
       
   641 PyObject *
       
   642 PyHKEY_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 ************************************************************************/
       
   659 BOOL
       
   660 PyWinObject_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 dont conform,
       
   698 ** causing this code to fail - however, "regedit" etc still work
       
   699 ** with these strings (ie only we dont!).
       
   700 */
       
   701 static void
       
   702 fixupMultiSZ(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 
       
   716 static int
       
   717 countStrings(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. */
       
   731 static BOOL
       
   732 Py2Reg(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*/
       
   893 static PyObject *
       
   894 Reg2Py(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 
       
   976 static PyObject *
       
   977 PyCloseKey(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 
       
   988 static PyObject *
       
   989 PyConnectRegistry(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 
       
  1009 static PyObject *
       
  1010 PyCreateKey(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 
       
  1027 static PyObject *
       
  1028 PyDeleteKey(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 
       
  1045 static PyObject *
       
  1046 PyDeleteValue(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 
       
  1066 static PyObject *
       
  1067 PyEnumKey(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 
       
  1092 static PyObject *
       
  1093 PyEnumValue(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 
       
  1158 static PyObject *
       
  1159 PyExpandEnvironmentStrings(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 
       
  1191 static PyObject *
       
  1192 PyFlushKey(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 }
       
  1209 static PyObject *
       
  1210 PyLoadKey(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 
       
  1231 static PyObject *
       
  1232 PyOpenKey(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 
       
  1257 static PyObject *
       
  1258 PyQueryInfoKey(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 
       
  1286 static PyObject *
       
  1287 PyQueryValue(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 
       
  1320 static PyObject *
       
  1321 PyQueryValueEx(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 
       
  1365 static PyObject *
       
  1366 PySaveKey(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 
       
  1391 static PyObject *
       
  1392 PySetValue(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 
       
  1437 static PyObject *
       
  1438 PySetValueEx(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 
       
  1478 static PyObject *
       
  1479 PyDisableReflectionKey(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 
       
  1514 static PyObject *
       
  1515 PyEnableReflectionKey(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 
       
  1550 static PyObject *
       
  1551 PyQueryReflectionKey(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 
       
  1586 static 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 
       
  1612 static void
       
  1613 insint(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 
       
  1623 static void
       
  1624 inskey(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 
       
  1634 PyMODINIT_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