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