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 #define PY_SSIZE_T_CLEAN
16 #include "Python.h"
17 #include "structmember.h"
18 #include "windows.h"
19 
20 static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK);
21 static BOOL clinic_HKEY_converter(PyObject *ob, void *p);
22 static PyObject *PyHKEY_FromHKEY(HKEY h);
23 static BOOL PyHKEY_Close(PyObject *obHandle);
24 
25 static char errNotAHandle[] = "Object is not a handle";
26 
27 /* The win32api module reports the function name that failed,
28    but this concept is not in the Python core.
29    Hopefully it will one day, and in the meantime I don't
30    want to lose this info...
31 */
32 #define PyErr_SetFromWindowsErrWithFunction(rc, fnname) \
33     PyErr_SetFromWindowsErr(rc)
34 
35 /* Forward declares */
36 
37 /* Doc strings */
38 PyDoc_STRVAR(module_doc,
39 "This module provides access to the Windows registry API.\n"
40 "\n"
41 "Functions:\n"
42 "\n"
43 "CloseKey() - Closes a registry key.\n"
44 "ConnectRegistry() - Establishes a connection to a predefined registry handle\n"
45 "                    on another computer.\n"
46 "CreateKey() - Creates the specified key, or opens it if it already exists.\n"
47 "DeleteKey() - Deletes the specified key.\n"
48 "DeleteValue() - Removes a named value from the specified registry key.\n"
49 "EnumKey() - Enumerates subkeys of the specified open registry key.\n"
50 "EnumValue() - Enumerates values of the specified open registry key.\n"
51 "ExpandEnvironmentStrings() - Expand the env strings in a REG_EXPAND_SZ\n"
52 "                             string.\n"
53 "FlushKey() - Writes all the attributes of the specified key to the registry.\n"
54 "LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and\n"
55 "            stores registration information from a specified file into that\n"
56 "            subkey.\n"
57 "OpenKey() - Opens the specified key.\n"
58 "OpenKeyEx() - Alias of OpenKey().\n"
59 "QueryValue() - Retrieves the value associated with the unnamed value for a\n"
60 "               specified key in the registry.\n"
61 "QueryValueEx() - Retrieves the type and data for a specified value name\n"
62 "                 associated with an open registry key.\n"
63 "QueryInfoKey() - Returns information about the specified key.\n"
64 "SaveKey() - Saves the specified key, and all its subkeys a file.\n"
65 "SetValue() - Associates a value with a specified key.\n"
66 "SetValueEx() - Stores data in the value field of an open registry key.\n"
67 "\n"
68 "Special objects:\n"
69 "\n"
70 "HKEYType -- type object for HKEY objects\n"
71 "error -- exception raised for Win32 errors\n"
72 "\n"
73 "Integer constants:\n"
74 "Many constants are defined - see the documentation for each function\n"
75 "to see what constants are used, and where.");
76 
77 
78 
79 /* PyHKEY docstrings */
80 PyDoc_STRVAR(PyHKEY_doc,
81 "PyHKEY Object - A Python object, representing a win32 registry key.\n"
82 "\n"
83 "This object wraps a Windows HKEY object, automatically closing it when\n"
84 "the object is destroyed.  To guarantee cleanup, you can call either\n"
85 "the Close() method on the PyHKEY, or the CloseKey() method.\n"
86 "\n"
87 "All functions which accept a handle object also accept an integer --\n"
88 "however, use of the handle object is encouraged.\n"
89 "\n"
90 "Functions:\n"
91 "Close() - Closes the underlying handle.\n"
92 "Detach() - Returns the integer Win32 handle, detaching it from the object\n"
93 "\n"
94 "Properties:\n"
95 "handle - The integer Win32 handle.\n"
96 "\n"
97 "Operations:\n"
98 "__bool__ - Handles with an open object return true, otherwise false.\n"
99 "__int__ - Converting a handle to an integer returns the Win32 handle.\n"
100 "rich comparison - Handle objects are compared using the handle value.");
101 
102 
103 
104 /************************************************************************
105 
106   The PyHKEY object definition
107 
108 ************************************************************************/
109 typedef struct {
110     PyObject_VAR_HEAD
111     HKEY hkey;
112 } PyHKEYObject;
113 
114 #define PyHKEY_Check(op) ((op)->ob_type == &PyHKEY_Type)
115 
116 static char *failMsg = "bad operand type";
117 
118 static PyObject *
PyHKEY_unaryFailureFunc(PyObject * ob)119 PyHKEY_unaryFailureFunc(PyObject *ob)
120 {
121     PyErr_SetString(PyExc_TypeError, failMsg);
122     return NULL;
123 }
124 static PyObject *
PyHKEY_binaryFailureFunc(PyObject * ob1,PyObject * ob2)125 PyHKEY_binaryFailureFunc(PyObject *ob1, PyObject *ob2)
126 {
127     PyErr_SetString(PyExc_TypeError, failMsg);
128     return NULL;
129 }
130 static PyObject *
PyHKEY_ternaryFailureFunc(PyObject * ob1,PyObject * ob2,PyObject * ob3)131 PyHKEY_ternaryFailureFunc(PyObject *ob1, PyObject *ob2, PyObject *ob3)
132 {
133     PyErr_SetString(PyExc_TypeError, failMsg);
134     return NULL;
135 }
136 
137 static void
PyHKEY_deallocFunc(PyObject * ob)138 PyHKEY_deallocFunc(PyObject *ob)
139 {
140     /* Can not call PyHKEY_Close, as the ob->tp_type
141        has already been cleared, thus causing the type
142        check to fail!
143     */
144     PyHKEYObject *obkey = (PyHKEYObject *)ob;
145     if (obkey->hkey)
146         RegCloseKey((HKEY)obkey->hkey);
147     PyObject_DEL(ob);
148 }
149 
150 static int
PyHKEY_boolFunc(PyObject * ob)151 PyHKEY_boolFunc(PyObject *ob)
152 {
153     return ((PyHKEYObject *)ob)->hkey != 0;
154 }
155 
156 static PyObject *
PyHKEY_intFunc(PyObject * ob)157 PyHKEY_intFunc(PyObject *ob)
158 {
159     PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
160     return PyLong_FromVoidPtr(pyhkey->hkey);
161 }
162 
163 static PyObject *
PyHKEY_strFunc(PyObject * ob)164 PyHKEY_strFunc(PyObject *ob)
165 {
166     PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
167     return PyUnicode_FromFormat("<PyHKEY:%p>", pyhkey->hkey);
168 }
169 
170 static int
PyHKEY_compareFunc(PyObject * ob1,PyObject * ob2)171 PyHKEY_compareFunc(PyObject *ob1, PyObject *ob2)
172 {
173     PyHKEYObject *pyhkey1 = (PyHKEYObject *)ob1;
174     PyHKEYObject *pyhkey2 = (PyHKEYObject *)ob2;
175     return pyhkey1 == pyhkey2 ? 0 :
176          (pyhkey1 < pyhkey2 ? -1 : 1);
177 }
178 
179 static Py_hash_t
PyHKEY_hashFunc(PyObject * ob)180 PyHKEY_hashFunc(PyObject *ob)
181 {
182     /* Just use the address.
183        XXX - should we use the handle value?
184     */
185     return _Py_HashPointer(ob);
186 }
187 
188 
189 static PyNumberMethods PyHKEY_NumberMethods =
190 {
191     PyHKEY_binaryFailureFunc,           /* nb_add */
192     PyHKEY_binaryFailureFunc,           /* nb_subtract */
193     PyHKEY_binaryFailureFunc,           /* nb_multiply */
194     PyHKEY_binaryFailureFunc,           /* nb_remainder */
195     PyHKEY_binaryFailureFunc,           /* nb_divmod */
196     PyHKEY_ternaryFailureFunc,          /* nb_power */
197     PyHKEY_unaryFailureFunc,            /* nb_negative */
198     PyHKEY_unaryFailureFunc,            /* nb_positive */
199     PyHKEY_unaryFailureFunc,            /* nb_absolute */
200     PyHKEY_boolFunc,                    /* nb_bool */
201     PyHKEY_unaryFailureFunc,            /* nb_invert */
202     PyHKEY_binaryFailureFunc,           /* nb_lshift */
203     PyHKEY_binaryFailureFunc,           /* nb_rshift */
204     PyHKEY_binaryFailureFunc,           /* nb_and */
205     PyHKEY_binaryFailureFunc,           /* nb_xor */
206     PyHKEY_binaryFailureFunc,           /* nb_or */
207     PyHKEY_intFunc,                     /* nb_int */
208     0,                                  /* nb_reserved */
209     PyHKEY_unaryFailureFunc,            /* nb_float */
210 };
211 
212 /*[clinic input]
213 module winreg
214 class winreg.HKEYType "PyHKEYObject *" "&PyHKEY_Type"
215 [clinic start generated code]*/
216 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=4c964eba3bf914d6]*/
217 
218 /*[python input]
219 class REGSAM_converter(CConverter):
220     type = 'REGSAM'
221     format_unit = 'i'
222 
223 class DWORD_converter(CConverter):
224     type = 'DWORD'
225     format_unit = 'k'
226 
227 class HKEY_converter(CConverter):
228     type = 'HKEY'
229     converter = 'clinic_HKEY_converter'
230 
231 class HKEY_return_converter(CReturnConverter):
232     type = 'HKEY'
233 
234     def render(self, function, data):
235         self.declare(data)
236         self.err_occurred_if_null_pointer("_return_value", data)
237         data.return_conversion.append(
238             'return_value = PyHKEY_FromHKEY(_return_value);\n')
239 
240 # HACK: this only works for PyHKEYObjects, nothing else.
241 #       Should this be generalized and enshrined in clinic.py,
242 #       destroy this converter with prejudice.
243 class self_return_converter(CReturnConverter):
244     type = 'PyHKEYObject *'
245 
246     def render(self, function, data):
247         self.declare(data)
248         data.return_conversion.append(
249             'return_value = (PyObject *)_return_value;\n')
250 [python start generated code]*/
251 /*[python end generated code: output=da39a3ee5e6b4b0d input=22f7aedc6d68e80e]*/
252 
253 #include "clinic/winreg.c.h"
254 
255 /************************************************************************
256 
257   The PyHKEY object methods
258 
259 ************************************************************************/
260 /*[clinic input]
261 winreg.HKEYType.Close
262 
263 Closes the underlying Windows handle.
264 
265 If the handle is already closed, no error is raised.
266 [clinic start generated code]*/
267 
268 static PyObject *
winreg_HKEYType_Close_impl(PyHKEYObject * self)269 winreg_HKEYType_Close_impl(PyHKEYObject *self)
270 /*[clinic end generated code: output=fced3a624fb0c344 input=6786ac75f6b89de6]*/
271 {
272     if (!PyHKEY_Close((PyObject *)self))
273         return NULL;
274     Py_RETURN_NONE;
275 }
276 
277 /*[clinic input]
278 winreg.HKEYType.Detach
279 
280 Detaches the Windows handle from the handle object.
281 
282 The result is the value of the handle before it is detached.  If the
283 handle is already detached, this will return zero.
284 
285 After calling this function, the handle is effectively invalidated,
286 but the handle is not closed.  You would call this function when you
287 need the underlying win32 handle to exist beyond the lifetime of the
288 handle object.
289 [clinic start generated code]*/
290 
291 static PyObject *
winreg_HKEYType_Detach_impl(PyHKEYObject * self)292 winreg_HKEYType_Detach_impl(PyHKEYObject *self)
293 /*[clinic end generated code: output=dda5a9e1a01ae78f input=dd2cc09e6c6ba833]*/
294 {
295     void* ret;
296     if (PySys_Audit("winreg.PyHKEY.Detach", "n", (Py_ssize_t)self->hkey) < 0) {
297         return NULL;
298     }
299     ret = (void*)self->hkey;
300     self->hkey = 0;
301     return PyLong_FromVoidPtr(ret);
302 }
303 
304 /*[clinic input]
305 winreg.HKEYType.__enter__ -> self
306 [clinic start generated code]*/
307 
308 static PyHKEYObject *
winreg_HKEYType___enter___impl(PyHKEYObject * self)309 winreg_HKEYType___enter___impl(PyHKEYObject *self)
310 /*[clinic end generated code: output=52c34986dab28990 input=c40fab1f0690a8e2]*/
311 {
312     Py_XINCREF(self);
313     return self;
314 }
315 
316 
317 /*[clinic input]
318 winreg.HKEYType.__exit__
319 
320     exc_type: object
321     exc_value: object
322     traceback: object
323 [clinic start generated code]*/
324 
325 static PyObject *
winreg_HKEYType___exit___impl(PyHKEYObject * self,PyObject * exc_type,PyObject * exc_value,PyObject * traceback)326 winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type,
327                               PyObject *exc_value, PyObject *traceback)
328 /*[clinic end generated code: output=923ebe7389e6a263 input=fb32489ee92403c7]*/
329 {
330     if (!PyHKEY_Close((PyObject *)self))
331         return NULL;
332     Py_RETURN_NONE;
333 }
334 
335 /*[clinic input]
336 [clinic start generated code]*/
337 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=da39a3ee5e6b4b0d]*/
338 
339 static struct PyMethodDef PyHKEY_methods[] = {
340     WINREG_HKEYTYPE_CLOSE_METHODDEF
341     WINREG_HKEYTYPE_DETACH_METHODDEF
342     WINREG_HKEYTYPE___ENTER___METHODDEF
343     WINREG_HKEYTYPE___EXIT___METHODDEF
344     {NULL}
345 };
346 
347 #define OFF(e) offsetof(PyHKEYObject, e)
348 static PyMemberDef PyHKEY_memberlist[] = {
349     {"handle",      T_INT,      OFF(hkey), READONLY},
350     {NULL}    /* Sentinel */
351 };
352 
353 /* The type itself */
354 PyTypeObject PyHKEY_Type =
355 {
356     PyVarObject_HEAD_INIT(0, 0) /* fill in type at module init */
357     "PyHKEY",
358     sizeof(PyHKEYObject),
359     0,
360     PyHKEY_deallocFunc,                 /* tp_dealloc */
361     0,                                  /* tp_vectorcall_offset */
362     0,                                  /* tp_getattr */
363     0,                                  /* tp_setattr */
364     0,                                  /* tp_as_async */
365     0,                                  /* tp_repr */
366     &PyHKEY_NumberMethods,              /* tp_as_number */
367     0,                                  /* tp_as_sequence */
368     0,                                  /* tp_as_mapping */
369     PyHKEY_hashFunc,                    /* tp_hash */
370     0,                                  /* tp_call */
371     PyHKEY_strFunc,                     /* tp_str */
372     0,                                  /* tp_getattro */
373     0,                                  /* tp_setattro */
374     0,                                  /* tp_as_buffer */
375     0,                                  /* tp_flags */
376     PyHKEY_doc,                         /* tp_doc */
377     0,                                  /*tp_traverse*/
378     0,                                  /*tp_clear*/
379     0,                                  /*tp_richcompare*/
380     0,                                  /*tp_weaklistoffset*/
381     0,                                  /*tp_iter*/
382     0,                                  /*tp_iternext*/
383     PyHKEY_methods,                     /*tp_methods*/
384     PyHKEY_memberlist,                  /*tp_members*/
385 };
386 
387 /************************************************************************
388    The public PyHKEY API (well, not public yet :-)
389 ************************************************************************/
390 PyObject *
PyHKEY_New(HKEY hInit)391 PyHKEY_New(HKEY hInit)
392 {
393     PyHKEYObject *key = PyObject_NEW(PyHKEYObject, &PyHKEY_Type);
394     if (key)
395         key->hkey = hInit;
396     return (PyObject *)key;
397 }
398 
399 BOOL
PyHKEY_Close(PyObject * ob_handle)400 PyHKEY_Close(PyObject *ob_handle)
401 {
402     LONG rc;
403     HKEY key;
404 
405     if (!PyHKEY_AsHKEY(ob_handle, &key, TRUE)) {
406         return FALSE;
407     }
408     if (PyHKEY_Check(ob_handle)) {
409         ((PyHKEYObject*)ob_handle)->hkey = 0;
410     }
411     rc = key ? RegCloseKey(key) : ERROR_SUCCESS;
412     if (rc != ERROR_SUCCESS)
413         PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
414     return rc == ERROR_SUCCESS;
415 }
416 
417 BOOL
PyHKEY_AsHKEY(PyObject * ob,HKEY * pHANDLE,BOOL bNoneOK)418 PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK)
419 {
420     if (ob == Py_None) {
421         if (!bNoneOK) {
422             PyErr_SetString(
423                       PyExc_TypeError,
424                       "None is not a valid HKEY in this context");
425             return FALSE;
426         }
427         *pHANDLE = (HKEY)0;
428     }
429     else if (PyHKEY_Check(ob)) {
430         PyHKEYObject *pH = (PyHKEYObject *)ob;
431         *pHANDLE = pH->hkey;
432     }
433     else if (PyLong_Check(ob)) {
434         /* We also support integers */
435         PyErr_Clear();
436         *pHANDLE = (HKEY)PyLong_AsVoidPtr(ob);
437         if (PyErr_Occurred())
438             return FALSE;
439     }
440     else {
441         PyErr_SetString(
442                         PyExc_TypeError,
443             "The object is not a PyHKEY object");
444         return FALSE;
445     }
446     return TRUE;
447 }
448 
449 BOOL
clinic_HKEY_converter(PyObject * ob,void * p)450 clinic_HKEY_converter(PyObject *ob, void *p)
451 {
452     if (!PyHKEY_AsHKEY(ob, (HKEY *)p, FALSE))
453         return FALSE;
454     return TRUE;
455 }
456 
457 PyObject *
PyHKEY_FromHKEY(HKEY h)458 PyHKEY_FromHKEY(HKEY h)
459 {
460     PyHKEYObject *op;
461 
462     /* Inline PyObject_New */
463     op = (PyHKEYObject *) PyObject_MALLOC(sizeof(PyHKEYObject));
464     if (op == NULL)
465         return PyErr_NoMemory();
466     PyObject_INIT(op, &PyHKEY_Type);
467     op->hkey = h;
468     return (PyObject *)op;
469 }
470 
471 
472 /************************************************************************
473   The module methods
474 ************************************************************************/
475 BOOL
PyWinObject_CloseHKEY(PyObject * obHandle)476 PyWinObject_CloseHKEY(PyObject *obHandle)
477 {
478     BOOL ok;
479     if (PyHKEY_Check(obHandle)) {
480         ok = PyHKEY_Close(obHandle);
481     }
482 #if SIZEOF_LONG >= SIZEOF_HKEY
483     else if (PyLong_Check(obHandle)) {
484         long rc = RegCloseKey((HKEY)PyLong_AsLong(obHandle));
485         ok = (rc == ERROR_SUCCESS);
486         if (!ok)
487             PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
488     }
489 #else
490     else if (PyLong_Check(obHandle)) {
491         long rc = RegCloseKey((HKEY)PyLong_AsVoidPtr(obHandle));
492         ok = (rc == ERROR_SUCCESS);
493         if (!ok)
494             PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
495     }
496 #endif
497     else {
498         PyErr_SetString(
499             PyExc_TypeError,
500             "A handle must be a HKEY object or an integer");
501         return FALSE;
502     }
503     return ok;
504 }
505 
506 
507 /*
508    Private Helper functions for the registry interfaces
509 
510 ** Note that fixupMultiSZ and countString have both had changes
511 ** made to support "incorrect strings".  The registry specification
512 ** calls for strings to be terminated with 2 null bytes.  It seems
513 ** some commercial packages install strings which don't conform,
514 ** causing this code to fail - however, "regedit" etc still work
515 ** with these strings (ie only we don't!).
516 */
517 static void
fixupMultiSZ(wchar_t ** str,wchar_t * data,int len)518 fixupMultiSZ(wchar_t **str, wchar_t *data, int len)
519 {
520     wchar_t *P;
521     int i;
522     wchar_t *Q;
523 
524     if (len > 0 && data[len - 1] == '\0') {
525         Q = data + len - 1;
526     }
527     else {
528         Q = data + len;
529     }
530 
531     for (P = data, i = 0; P < Q; P++, i++) {
532         str[i] = P;
533         for (; P < Q && *P != '\0'; P++) {
534             ;
535         }
536     }
537 }
538 
539 static int
countStrings(wchar_t * data,int len)540 countStrings(wchar_t *data, int len)
541 {
542     int strings;
543     wchar_t *P, *Q;
544 
545     if (len > 0 && data[len - 1] == '\0') {
546         Q = data + len - 1;
547     }
548     else {
549         Q = data + len;
550     }
551 
552     for (P = data, strings = 0; P < Q; P++, strings++) {
553         for (; P < Q && *P != '\0'; P++) {
554             ;
555         }
556     }
557     return strings;
558 }
559 
560 /* Convert PyObject into Registry data.
561    Allocates space as needed. */
562 static BOOL
Py2Reg(PyObject * value,DWORD typ,BYTE ** retDataBuf,DWORD * retDataSize)563 Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
564 {
565     Py_ssize_t i,j;
566     switch (typ) {
567         case REG_DWORD:
568             if (value != Py_None && !PyLong_Check(value))
569                 return FALSE;
570             *retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1);
571             if (*retDataBuf == NULL){
572                 PyErr_NoMemory();
573                 return FALSE;
574             }
575             *retDataSize = sizeof(DWORD);
576             if (value == Py_None) {
577                 DWORD zero = 0;
578                 memcpy(*retDataBuf, &zero, sizeof(DWORD));
579             }
580             else {
581                 DWORD d = PyLong_AsUnsignedLong(value);
582                 memcpy(*retDataBuf, &d, sizeof(DWORD));
583             }
584             break;
585         case REG_QWORD:
586           if (value != Py_None && !PyLong_Check(value))
587                 return FALSE;
588             *retDataBuf = (BYTE *)PyMem_NEW(DWORD64, 1);
589             if (*retDataBuf == NULL){
590                 PyErr_NoMemory();
591                 return FALSE;
592             }
593             *retDataSize = sizeof(DWORD64);
594             if (value == Py_None) {
595                 DWORD64 zero = 0;
596                 memcpy(*retDataBuf, &zero, sizeof(DWORD64));
597             }
598             else {
599                 DWORD64 d = PyLong_AsUnsignedLongLong(value);
600                 memcpy(*retDataBuf, &d, sizeof(DWORD64));
601             }
602             break;
603         case REG_SZ:
604         case REG_EXPAND_SZ:
605             {
606                 if (value != Py_None) {
607                     Py_ssize_t len;
608                     if (!PyUnicode_Check(value))
609                         return FALSE;
610                     *retDataBuf = (BYTE*)PyUnicode_AsWideCharString(value, &len);
611                     if (*retDataBuf == NULL)
612                         return FALSE;
613                     *retDataSize = Py_SAFE_DOWNCAST(
614                         (len + 1) * sizeof(wchar_t),
615                         Py_ssize_t, DWORD);
616                 }
617                 else {
618                     *retDataBuf = (BYTE *)PyMem_NEW(wchar_t, 1);
619                     if (*retDataBuf == NULL) {
620                         PyErr_NoMemory();
621                         return FALSE;
622                     }
623                     ((wchar_t *)*retDataBuf)[0] = L'\0';
624                     *retDataSize = 1 * sizeof(wchar_t);
625                 }
626                 break;
627             }
628         case REG_MULTI_SZ:
629             {
630                 DWORD size = 0;
631                 wchar_t *P;
632 
633                 if (value == Py_None)
634                     i = 0;
635                 else {
636                     if (!PyList_Check(value))
637                         return FALSE;
638                     i = PyList_Size(value);
639                 }
640                 for (j = 0; j < i; j++)
641                 {
642                     PyObject *t;
643                     wchar_t *wstr;
644                     Py_ssize_t len;
645 
646                     t = PyList_GET_ITEM(value, j);
647                     if (!PyUnicode_Check(t))
648                         return FALSE;
649                     wstr = PyUnicode_AsUnicodeAndSize(t, &len);
650                     if (wstr == NULL)
651                         return FALSE;
652                     size += Py_SAFE_DOWNCAST((len + 1) * sizeof(wchar_t),
653                                              size_t, DWORD);
654                 }
655 
656                 *retDataSize = size + 2;
657                 *retDataBuf = (BYTE *)PyMem_NEW(char,
658                                                 *retDataSize);
659                 if (*retDataBuf == NULL){
660                     PyErr_NoMemory();
661                     return FALSE;
662                 }
663                 P = (wchar_t *)*retDataBuf;
664 
665                 for (j = 0; j < i; j++)
666                 {
667                     PyObject *t;
668                     wchar_t *wstr;
669                     Py_ssize_t len;
670 
671                     t = PyList_GET_ITEM(value, j);
672                     wstr = PyUnicode_AsUnicodeAndSize(t, &len);
673                     assert(wstr);
674                     wcscpy(P, wstr);
675                     P += (len + 1);
676                 }
677                 /* And doubly-terminate the list... */
678                 *P = '\0';
679                 break;
680             }
681         case REG_BINARY:
682         /* ALSO handle ALL unknown data types here.  Even if we can't
683            support it natively, we should handle the bits. */
684         default:
685             if (value == Py_None) {
686                 *retDataSize = 0;
687                 *retDataBuf = NULL;
688             }
689             else {
690                 Py_buffer view;
691 
692                 if (!PyObject_CheckBuffer(value)) {
693                     PyErr_Format(PyExc_TypeError,
694                         "Objects of type '%s' can not "
695                         "be used as binary registry values",
696                         value->ob_type->tp_name);
697                     return FALSE;
698                 }
699 
700                 if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
701                     return FALSE;
702 
703                 *retDataBuf = (BYTE *)PyMem_NEW(char, view.len);
704                 if (*retDataBuf == NULL){
705                     PyBuffer_Release(&view);
706                     PyErr_NoMemory();
707                     return FALSE;
708                 }
709                 *retDataSize = Py_SAFE_DOWNCAST(view.len, Py_ssize_t, DWORD);
710                 memcpy(*retDataBuf, view.buf, view.len);
711                 PyBuffer_Release(&view);
712             }
713             break;
714     }
715     return TRUE;
716 }
717 
718 /* Convert Registry data into PyObject*/
719 static PyObject *
Reg2Py(BYTE * retDataBuf,DWORD retDataSize,DWORD typ)720 Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ)
721 {
722     PyObject *obData;
723 
724     switch (typ) {
725         case REG_DWORD:
726             if (retDataSize == 0)
727                 obData = PyLong_FromUnsignedLong(0);
728             else
729                 obData = PyLong_FromUnsignedLong(*(DWORD *)retDataBuf);
730             break;
731         case REG_QWORD:
732             if (retDataSize == 0)
733                 obData = PyLong_FromUnsignedLongLong(0);
734             else
735                 obData = PyLong_FromUnsignedLongLong(*(DWORD64 *)retDataBuf);
736             break;
737         case REG_SZ:
738         case REG_EXPAND_SZ:
739             {
740                 /* REG_SZ should be a NUL terminated string, but only by
741                  * convention. The buffer may have been saved without a NUL
742                  * or with embedded NULs. To be consistent with reg.exe and
743                  * regedit.exe, consume only up to the first NUL. */
744                 wchar_t *data = (wchar_t *)retDataBuf;
745                 size_t len = wcsnlen(data, retDataSize / sizeof(wchar_t));
746                 obData = PyUnicode_FromWideChar(data, len);
747                 break;
748             }
749         case REG_MULTI_SZ:
750             if (retDataSize == 0)
751                 obData = PyList_New(0);
752             else
753             {
754                 int index = 0;
755                 wchar_t *data = (wchar_t *)retDataBuf;
756                 int len = retDataSize / 2;
757                 int s = countStrings(data, len);
758                 wchar_t **str = PyMem_New(wchar_t *, s);
759                 if (str == NULL)
760                     return PyErr_NoMemory();
761 
762                 fixupMultiSZ(str, data, len);
763                 obData = PyList_New(s);
764                 if (obData == NULL) {
765                     PyMem_Free(str);
766                     return NULL;
767                 }
768                 for (index = 0; index < s; index++)
769                 {
770                     size_t slen = wcsnlen(str[index], len);
771                     PyObject *uni = PyUnicode_FromWideChar(str[index], slen);
772                     if (uni == NULL) {
773                         Py_DECREF(obData);
774                         PyMem_Free(str);
775                         return NULL;
776                     }
777                     PyList_SET_ITEM(obData, index, uni);
778                     len -= Py_SAFE_DOWNCAST(slen + 1, size_t, int);
779                 }
780                 PyMem_Free(str);
781 
782                 break;
783             }
784         case REG_BINARY:
785         /* ALSO handle ALL unknown data types here.  Even if we can't
786            support it natively, we should handle the bits. */
787         default:
788             if (retDataSize == 0) {
789                 Py_INCREF(Py_None);
790                 obData = Py_None;
791             }
792             else
793                 obData = PyBytes_FromStringAndSize(
794                              (char *)retDataBuf, retDataSize);
795             break;
796     }
797     return obData;
798 }
799 
800 /* The Python methods */
801 
802 /*[clinic input]
803 winreg.CloseKey
804 
805     hkey: object
806         A previously opened key.
807     /
808 
809 Closes a previously opened registry key.
810 
811 Note that if the key is not closed using this method, it will be
812 closed when the hkey object is destroyed by Python.
813 [clinic start generated code]*/
814 
815 static PyObject *
winreg_CloseKey(PyObject * module,PyObject * hkey)816 winreg_CloseKey(PyObject *module, PyObject *hkey)
817 /*[clinic end generated code: output=a4fa537019a80d15 input=5b1aac65ba5127ad]*/
818 {
819     if (!PyHKEY_Close(hkey))
820         return NULL;
821     Py_RETURN_NONE;
822 }
823 
824 /*[clinic input]
825 winreg.ConnectRegistry -> HKEY
826 
827     computer_name: Py_UNICODE(accept={str, NoneType})
828         The name of the remote computer, of the form r"\\computername".  If
829         None, the local computer is used.
830     key: HKEY
831         The predefined key to connect to.
832     /
833 
834 Establishes a connection to the registry on another computer.
835 
836 The return value is the handle of the opened key.
837 If the function fails, an OSError exception is raised.
838 [clinic start generated code]*/
839 
840 static HKEY
winreg_ConnectRegistry_impl(PyObject * module,const Py_UNICODE * computer_name,HKEY key)841 winreg_ConnectRegistry_impl(PyObject *module,
842                             const Py_UNICODE *computer_name, HKEY key)
843 /*[clinic end generated code: output=cd4f70fb9ec901fb input=5f98a891a347e68e]*/
844 {
845     HKEY retKey;
846     long rc;
847     if (PySys_Audit("winreg.ConnectRegistry", "un",
848                     computer_name, (Py_ssize_t)key) < 0) {
849         return NULL;
850     }
851     Py_BEGIN_ALLOW_THREADS
852     rc = RegConnectRegistryW(computer_name, key, &retKey);
853     Py_END_ALLOW_THREADS
854     if (rc != ERROR_SUCCESS) {
855         PyErr_SetFromWindowsErrWithFunction(rc, "ConnectRegistry");
856         return NULL;
857     }
858     return retKey;
859 }
860 
861 /*[clinic input]
862 winreg.CreateKey -> HKEY
863 
864     key: HKEY
865         An already open key, or one of the predefined HKEY_* constants.
866     sub_key: Py_UNICODE(accept={str, NoneType})
867         The name of the key this method opens or creates.
868     /
869 
870 Creates or opens the specified key.
871 
872 If key is one of the predefined keys, sub_key may be None. In that case,
873 the handle returned is the same key handle passed in to the function.
874 
875 If the key already exists, this function opens the existing key.
876 
877 The return value is the handle of the opened key.
878 If the function fails, an OSError exception is raised.
879 [clinic start generated code]*/
880 
881 static HKEY
winreg_CreateKey_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key)882 winreg_CreateKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
883 /*[clinic end generated code: output=2af13910d56eae26 input=3cdd1622488acea2]*/
884 {
885     HKEY retKey;
886     long rc;
887 
888     if (PySys_Audit("winreg.CreateKey", "nun",
889                     (Py_ssize_t)key, sub_key,
890                     (Py_ssize_t)KEY_WRITE) < 0) {
891         return NULL;
892     }
893     rc = RegCreateKeyW(key, sub_key, &retKey);
894     if (rc != ERROR_SUCCESS) {
895         PyErr_SetFromWindowsErrWithFunction(rc, "CreateKey");
896         return NULL;
897     }
898     if (PySys_Audit("winreg.OpenKey/result", "n",
899                     (Py_ssize_t)retKey) < 0) {
900         return NULL;
901     }
902     return retKey;
903 }
904 
905 /*[clinic input]
906 winreg.CreateKeyEx -> HKEY
907 
908     key: HKEY
909         An already open key, or one of the predefined HKEY_* constants.
910     sub_key: Py_UNICODE(accept={str, NoneType})
911         The name of the key this method opens or creates.
912     reserved: int = 0
913         A reserved integer, and must be zero.  Default is zero.
914     access: REGSAM(c_default='KEY_WRITE') = winreg.KEY_WRITE
915         An integer that specifies an access mask that describes the
916         desired security access for the key. Default is KEY_WRITE.
917 
918 Creates or opens the specified key.
919 
920 If key is one of the predefined keys, sub_key may be None. In that case,
921 the handle returned is the same key handle passed in to the function.
922 
923 If the key already exists, this function opens the existing key
924 
925 The return value is the handle of the opened key.
926 If the function fails, an OSError exception is raised.
927 [clinic start generated code]*/
928 
929 static HKEY
winreg_CreateKeyEx_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key,int reserved,REGSAM access)930 winreg_CreateKeyEx_impl(PyObject *module, HKEY key,
931                         const Py_UNICODE *sub_key, int reserved,
932                         REGSAM access)
933 /*[clinic end generated code: output=643a70ad6a361a97 input=42c2b03f98406b66]*/
934 {
935     HKEY retKey;
936     long rc;
937 
938     if (PySys_Audit("winreg.CreateKey", "nun",
939                     (Py_ssize_t)key, sub_key,
940                     (Py_ssize_t)access) < 0) {
941         return NULL;
942     }
943     rc = RegCreateKeyExW(key, sub_key, reserved, NULL, 0,
944                          access, NULL, &retKey, NULL);
945     if (rc != ERROR_SUCCESS) {
946         PyErr_SetFromWindowsErrWithFunction(rc, "CreateKeyEx");
947         return NULL;
948     }
949     if (PySys_Audit("winreg.OpenKey/result", "n",
950                     (Py_ssize_t)retKey) < 0) {
951         return NULL;
952     }
953     return retKey;
954 }
955 
956 /*[clinic input]
957 winreg.DeleteKey
958     key: HKEY
959         An already open key, or any one of the predefined HKEY_* constants.
960     sub_key: Py_UNICODE
961         A string that must be the name of a subkey of the key identified by
962         the key parameter. This value must not be None, and the key may not
963         have subkeys.
964     /
965 
966 Deletes the specified key.
967 
968 This method can not delete keys with subkeys.
969 
970 If the function succeeds, the entire key, including all of its values,
971 is removed.  If the function fails, an OSError exception is raised.
972 [clinic start generated code]*/
973 
974 static PyObject *
winreg_DeleteKey_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key)975 winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
976 /*[clinic end generated code: output=d2652a84f70e0862 input=b31d225b935e4211]*/
977 {
978     long rc;
979     if (PySys_Audit("winreg.DeleteKey", "nun",
980                     (Py_ssize_t)key, sub_key,
981                     (Py_ssize_t)0) < 0) {
982         return NULL;
983     }
984     rc = RegDeleteKeyW(key, sub_key );
985     if (rc != ERROR_SUCCESS)
986         return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey");
987     Py_RETURN_NONE;
988 }
989 
990 /*[clinic input]
991 winreg.DeleteKeyEx
992 
993     key: HKEY
994         An already open key, or any one of the predefined HKEY_* constants.
995     sub_key: Py_UNICODE
996         A string that must be the name of a subkey of the key identified by
997         the key parameter. This value must not be None, and the key may not
998         have subkeys.
999     access: REGSAM(c_default='KEY_WOW64_64KEY') = winreg.KEY_WOW64_64KEY
1000         An integer that specifies an access mask that describes the
1001         desired security access for the key. Default is KEY_WOW64_64KEY.
1002     reserved: int = 0
1003         A reserved integer, and must be zero.  Default is zero.
1004 
1005 Deletes the specified key (64-bit OS only).
1006 
1007 This method can not delete keys with subkeys.
1008 
1009 If the function succeeds, the entire key, including all of its values,
1010 is removed.  If the function fails, an OSError exception is raised.
1011 On unsupported Windows versions, NotImplementedError is raised.
1012 [clinic start generated code]*/
1013 
1014 static PyObject *
winreg_DeleteKeyEx_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key,REGSAM access,int reserved)1015 winreg_DeleteKeyEx_impl(PyObject *module, HKEY key,
1016                         const Py_UNICODE *sub_key, REGSAM access,
1017                         int reserved)
1018 /*[clinic end generated code: output=52a1c8b374ebc003 input=711d9d89e7ecbed7]*/
1019 {
1020     HMODULE hMod;
1021     typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int);
1022     RDKEFunc pfn = NULL;
1023     long rc;
1024 
1025     if (PySys_Audit("winreg.DeleteKey", "nun",
1026                     (Py_ssize_t)key, sub_key,
1027                     (Py_ssize_t)access) < 0) {
1028         return NULL;
1029     }
1030     /* Only available on 64bit platforms, so we must load it
1031        dynamically. */
1032     Py_BEGIN_ALLOW_THREADS
1033     hMod = GetModuleHandleW(L"advapi32.dll");
1034     if (hMod)
1035         pfn = (RDKEFunc)GetProcAddress(hMod, "RegDeleteKeyExW");
1036     Py_END_ALLOW_THREADS
1037     if (!pfn) {
1038         PyErr_SetString(PyExc_NotImplementedError,
1039                                         "not implemented on this platform");
1040         return NULL;
1041     }
1042     Py_BEGIN_ALLOW_THREADS
1043     rc = (*pfn)(key, sub_key, access, reserved);
1044     Py_END_ALLOW_THREADS
1045 
1046     if (rc != ERROR_SUCCESS)
1047         return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKeyEx");
1048     Py_RETURN_NONE;
1049 }
1050 
1051 /*[clinic input]
1052 winreg.DeleteValue
1053 
1054     key: HKEY
1055         An already open key, or any one of the predefined HKEY_* constants.
1056     value: Py_UNICODE(accept={str, NoneType})
1057         A string that identifies the value to remove.
1058     /
1059 
1060 Removes a named value from a registry key.
1061 [clinic start generated code]*/
1062 
1063 static PyObject *
winreg_DeleteValue_impl(PyObject * module,HKEY key,const Py_UNICODE * value)1064 winreg_DeleteValue_impl(PyObject *module, HKEY key, const Py_UNICODE *value)
1065 /*[clinic end generated code: output=56fa9d21f3a54371 input=a78d3407a4197b21]*/
1066 {
1067     long rc;
1068     if (PySys_Audit("winreg.DeleteValue", "nu",
1069                     (Py_ssize_t)key, value) < 0) {
1070         return NULL;
1071     }
1072     Py_BEGIN_ALLOW_THREADS
1073     rc = RegDeleteValueW(key, value);
1074     Py_END_ALLOW_THREADS
1075     if (rc !=ERROR_SUCCESS)
1076         return PyErr_SetFromWindowsErrWithFunction(rc,
1077                                                    "RegDeleteValue");
1078     Py_RETURN_NONE;
1079 }
1080 
1081 /*[clinic input]
1082 winreg.EnumKey
1083 
1084     key: HKEY
1085         An already open key, or any one of the predefined HKEY_* constants.
1086     index: int
1087         An integer that identifies the index of the key to retrieve.
1088     /
1089 
1090 Enumerates subkeys of an open registry key.
1091 
1092 The function retrieves the name of one subkey each time it is called.
1093 It is typically called repeatedly until an OSError exception is
1094 raised, indicating no more values are available.
1095 [clinic start generated code]*/
1096 
1097 static PyObject *
winreg_EnumKey_impl(PyObject * module,HKEY key,int index)1098 winreg_EnumKey_impl(PyObject *module, HKEY key, int index)
1099 /*[clinic end generated code: output=25a6ec52cd147bc4 input=fad9a7c00ab0e04b]*/
1100 {
1101     long rc;
1102     PyObject *retStr;
1103 
1104     if (PySys_Audit("winreg.EnumKey", "ni",
1105                     (Py_ssize_t)key, index) < 0) {
1106         return NULL;
1107     }
1108     /* The Windows docs claim that the max key name length is 255
1109      * characters, plus a terminating nul character.  However,
1110      * empirical testing demonstrates that it is possible to
1111      * create a 256 character key that is missing the terminating
1112      * nul.  RegEnumKeyEx requires a 257 character buffer to
1113      * retrieve such a key name. */
1114     wchar_t tmpbuf[257];
1115     DWORD len = sizeof(tmpbuf)/sizeof(wchar_t); /* includes NULL terminator */
1116 
1117     Py_BEGIN_ALLOW_THREADS
1118     rc = RegEnumKeyExW(key, index, tmpbuf, &len, NULL, NULL, NULL, NULL);
1119     Py_END_ALLOW_THREADS
1120     if (rc != ERROR_SUCCESS)
1121         return PyErr_SetFromWindowsErrWithFunction(rc, "RegEnumKeyEx");
1122 
1123     retStr = PyUnicode_FromWideChar(tmpbuf, len);
1124     return retStr;  /* can be NULL */
1125 }
1126 
1127 /*[clinic input]
1128 winreg.EnumValue
1129 
1130     key: HKEY
1131             An already open key, or any one of the predefined HKEY_* constants.
1132     index: int
1133         An integer that identifies the index of the value to retrieve.
1134     /
1135 
1136 Enumerates values of an open registry key.
1137 
1138 The function retrieves the name of one subkey each time it is called.
1139 It is typically called repeatedly, until an OSError exception
1140 is raised, indicating no more values.
1141 
1142 The result is a tuple of 3 items:
1143   value_name
1144     A string that identifies the value.
1145   value_data
1146     An object that holds the value data, and whose type depends
1147     on the underlying registry type.
1148   data_type
1149     An integer that identifies the type of the value data.
1150 [clinic start generated code]*/
1151 
1152 static PyObject *
winreg_EnumValue_impl(PyObject * module,HKEY key,int index)1153 winreg_EnumValue_impl(PyObject *module, HKEY key, int index)
1154 /*[clinic end generated code: output=d363b5a06f8789ac input=4414f47a6fb238b5]*/
1155 {
1156     long rc;
1157     wchar_t *retValueBuf;
1158     BYTE *tmpBuf;
1159     BYTE *retDataBuf;
1160     DWORD retValueSize, bufValueSize;
1161     DWORD retDataSize, bufDataSize;
1162     DWORD typ;
1163     PyObject *obData;
1164     PyObject *retVal;
1165 
1166     if (PySys_Audit("winreg.EnumValue", "ni",
1167                     (Py_ssize_t)key, index) < 0) {
1168         return NULL;
1169     }
1170     if ((rc = RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, NULL, NULL,
1171                               NULL,
1172                               &retValueSize, &retDataSize, NULL, NULL))
1173         != ERROR_SUCCESS)
1174         return PyErr_SetFromWindowsErrWithFunction(rc,
1175                                                    "RegQueryInfoKey");
1176     ++retValueSize;    /* include null terminators */
1177     ++retDataSize;
1178     bufDataSize = retDataSize;
1179     bufValueSize = retValueSize;
1180     retValueBuf = PyMem_New(wchar_t, retValueSize);
1181     if (retValueBuf == NULL)
1182         return PyErr_NoMemory();
1183     retDataBuf = (BYTE *)PyMem_Malloc(retDataSize);
1184     if (retDataBuf == NULL) {
1185         PyMem_Free(retValueBuf);
1186         return PyErr_NoMemory();
1187     }
1188 
1189     while (1) {
1190         Py_BEGIN_ALLOW_THREADS
1191         rc = RegEnumValueW(key,
1192                   index,
1193                   retValueBuf,
1194                   &retValueSize,
1195                   NULL,
1196                   &typ,
1197                   (BYTE *)retDataBuf,
1198                   &retDataSize);
1199         Py_END_ALLOW_THREADS
1200 
1201         if (rc != ERROR_MORE_DATA)
1202             break;
1203 
1204         bufDataSize *= 2;
1205         tmpBuf = (BYTE *)PyMem_Realloc(retDataBuf, bufDataSize);
1206         if (tmpBuf == NULL) {
1207             PyErr_NoMemory();
1208             retVal = NULL;
1209             goto fail;
1210         }
1211         retDataBuf = tmpBuf;
1212         retDataSize = bufDataSize;
1213         retValueSize = bufValueSize;
1214     }
1215 
1216     if (rc != ERROR_SUCCESS) {
1217         retVal = PyErr_SetFromWindowsErrWithFunction(rc,
1218                                                      "PyRegEnumValue");
1219         goto fail;
1220     }
1221     obData = Reg2Py(retDataBuf, retDataSize, typ);
1222     if (obData == NULL) {
1223         retVal = NULL;
1224         goto fail;
1225     }
1226     retVal = Py_BuildValue("uOi", retValueBuf, obData, typ);
1227     Py_DECREF(obData);
1228   fail:
1229     PyMem_Free(retValueBuf);
1230     PyMem_Free(retDataBuf);
1231     return retVal;
1232 }
1233 
1234 /*[clinic input]
1235 winreg.ExpandEnvironmentStrings
1236 
1237     string: Py_UNICODE
1238     /
1239 
1240 Expand environment vars.
1241 [clinic start generated code]*/
1242 
1243 static PyObject *
winreg_ExpandEnvironmentStrings_impl(PyObject * module,const Py_UNICODE * string)1244 winreg_ExpandEnvironmentStrings_impl(PyObject *module,
1245                                      const Py_UNICODE *string)
1246 /*[clinic end generated code: output=8fa4e959747a7312 input=b2a9714d2b751aa6]*/
1247 {
1248     wchar_t *retValue = NULL;
1249     DWORD retValueSize;
1250     DWORD rc;
1251     PyObject *o;
1252 
1253     if (PySys_Audit("winreg.ExpandEnvironmentStrings", "u",
1254                     string) < 0) {
1255         return NULL;
1256     }
1257 
1258     retValueSize = ExpandEnvironmentStringsW(string, retValue, 0);
1259     if (retValueSize == 0) {
1260         return PyErr_SetFromWindowsErrWithFunction(retValueSize,
1261                                         "ExpandEnvironmentStrings");
1262     }
1263     retValue = PyMem_New(wchar_t, retValueSize);
1264     if (retValue == NULL) {
1265         return PyErr_NoMemory();
1266     }
1267 
1268     rc = ExpandEnvironmentStringsW(string, retValue, retValueSize);
1269     if (rc == 0) {
1270         PyMem_Free(retValue);
1271         return PyErr_SetFromWindowsErrWithFunction(retValueSize,
1272                                         "ExpandEnvironmentStrings");
1273     }
1274     o = PyUnicode_FromWideChar(retValue, wcslen(retValue));
1275     PyMem_Free(retValue);
1276     return o;
1277 }
1278 
1279 /*[clinic input]
1280 winreg.FlushKey
1281 
1282     key: HKEY
1283         An already open key, or any one of the predefined HKEY_* constants.
1284     /
1285 
1286 Writes all the attributes of a key to the registry.
1287 
1288 It is not necessary to call FlushKey to change a key.  Registry changes
1289 are flushed to disk by the registry using its lazy flusher.  Registry
1290 changes are also flushed to disk at system shutdown.  Unlike
1291 CloseKey(), the FlushKey() method returns only when all the data has
1292 been written to the registry.
1293 
1294 An application should only call FlushKey() if it requires absolute
1295 certainty that registry changes are on disk.  If you don't know whether
1296 a FlushKey() call is required, it probably isn't.
1297 [clinic start generated code]*/
1298 
1299 static PyObject *
winreg_FlushKey_impl(PyObject * module,HKEY key)1300 winreg_FlushKey_impl(PyObject *module, HKEY key)
1301 /*[clinic end generated code: output=e6fc230d4c5dc049 input=f57457c12297d82f]*/
1302 {
1303     long rc;
1304     Py_BEGIN_ALLOW_THREADS
1305     rc = RegFlushKey(key);
1306     Py_END_ALLOW_THREADS
1307     if (rc != ERROR_SUCCESS)
1308         return PyErr_SetFromWindowsErrWithFunction(rc, "RegFlushKey");
1309     Py_RETURN_NONE;
1310 }
1311 
1312 
1313 /*[clinic input]
1314 winreg.LoadKey
1315 
1316     key: HKEY
1317         An already open key, or any one of the predefined HKEY_* constants.
1318     sub_key: Py_UNICODE
1319         A string that identifies the sub-key to load.
1320     file_name: Py_UNICODE
1321         The name of the file to load registry data from.  This file must
1322         have been created with the SaveKey() function.  Under the file
1323         allocation table (FAT) file system, the filename may not have an
1324         extension.
1325     /
1326 
1327 Insert data into the registry from a file.
1328 
1329 Creates a subkey under the specified key and stores registration
1330 information from a specified file into that subkey.
1331 
1332 A call to LoadKey() fails if the calling process does not have the
1333 SE_RESTORE_PRIVILEGE privilege.
1334 
1335 If key is a handle returned by ConnectRegistry(), then the path
1336 specified in fileName is relative to the remote computer.
1337 
1338 The MSDN docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE
1339 tree.
1340 [clinic start generated code]*/
1341 
1342 static PyObject *
winreg_LoadKey_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key,const Py_UNICODE * file_name)1343 winreg_LoadKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
1344                     const Py_UNICODE *file_name)
1345 /*[clinic end generated code: output=65f89f2548cb27c7 input=e3b5b45ade311582]*/
1346 {
1347     long rc;
1348 
1349     if (PySys_Audit("winreg.LoadKey", "nuu",
1350                     (Py_ssize_t)key, sub_key, file_name) < 0) {
1351         return NULL;
1352     }
1353     Py_BEGIN_ALLOW_THREADS
1354     rc = RegLoadKeyW(key, sub_key, file_name );
1355     Py_END_ALLOW_THREADS
1356     if (rc != ERROR_SUCCESS)
1357         return PyErr_SetFromWindowsErrWithFunction(rc, "RegLoadKey");
1358     Py_RETURN_NONE;
1359 }
1360 
1361 /*[clinic input]
1362 winreg.OpenKey -> HKEY
1363 
1364     key: HKEY
1365         An already open key, or any one of the predefined HKEY_* constants.
1366     sub_key: Py_UNICODE(accept={str, NoneType})
1367         A string that identifies the sub_key to open.
1368     reserved: int = 0
1369         A reserved integer that must be zero.  Default is zero.
1370     access: REGSAM(c_default='KEY_READ') = winreg.KEY_READ
1371         An integer that specifies an access mask that describes the desired
1372         security access for the key.  Default is KEY_READ.
1373 
1374 Opens the specified key.
1375 
1376 The result is a new handle to the specified key.
1377 If the function fails, an OSError exception is raised.
1378 [clinic start generated code]*/
1379 
1380 static HKEY
winreg_OpenKey_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key,int reserved,REGSAM access)1381 winreg_OpenKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
1382                     int reserved, REGSAM access)
1383 /*[clinic end generated code: output=8849bff2c30104ad input=098505ac36a9ae28]*/
1384 {
1385     HKEY retKey;
1386     long rc;
1387 
1388     if (PySys_Audit("winreg.OpenKey", "nun",
1389                     (Py_ssize_t)key, sub_key,
1390                     (Py_ssize_t)access) < 0) {
1391         return NULL;
1392     }
1393     Py_BEGIN_ALLOW_THREADS
1394     rc = RegOpenKeyExW(key, sub_key, reserved, access, &retKey);
1395     Py_END_ALLOW_THREADS
1396     if (rc != ERROR_SUCCESS) {
1397         PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx");
1398         return NULL;
1399     }
1400     if (PySys_Audit("winreg.OpenKey/result", "n",
1401                     (Py_ssize_t)retKey) < 0) {
1402         return NULL;
1403     }
1404     return retKey;
1405 }
1406 
1407 /*[clinic input]
1408 winreg.OpenKeyEx = winreg.OpenKey
1409 
1410 Opens the specified key.
1411 
1412 The result is a new handle to the specified key.
1413 If the function fails, an OSError exception is raised.
1414 [clinic start generated code]*/
1415 
1416 static HKEY
winreg_OpenKeyEx_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key,int reserved,REGSAM access)1417 winreg_OpenKeyEx_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
1418                       int reserved, REGSAM access)
1419 /*[clinic end generated code: output=81bc2bd684bc77ae input=c6c4972af8622959]*/
1420 {
1421     return winreg_OpenKey_impl(module, key, sub_key, reserved, access);
1422 }
1423 
1424 /*[clinic input]
1425 winreg.QueryInfoKey
1426 
1427     key: HKEY
1428         An already open key, or any one of the predefined HKEY_* constants.
1429     /
1430 
1431 Returns information about a key.
1432 
1433 The result is a tuple of 3 items:
1434 An integer that identifies the number of sub keys this key has.
1435 An integer that identifies the number of values this key has.
1436 An integer that identifies when the key was last modified (if available)
1437 as 100's of nanoseconds since Jan 1, 1600.
1438 [clinic start generated code]*/
1439 
1440 static PyObject *
winreg_QueryInfoKey_impl(PyObject * module,HKEY key)1441 winreg_QueryInfoKey_impl(PyObject *module, HKEY key)
1442 /*[clinic end generated code: output=dc657b8356a4f438 input=c3593802390cde1f]*/
1443 {
1444     long rc;
1445     DWORD nSubKeys, nValues;
1446     FILETIME ft;
1447     LARGE_INTEGER li;
1448     PyObject *l;
1449     PyObject *ret;
1450 
1451     if (PySys_Audit("winreg.QueryInfoKey", "n", (Py_ssize_t)key) < 0) {
1452         return NULL;
1453     }
1454     if ((rc = RegQueryInfoKeyW(key, NULL, NULL, 0, &nSubKeys, NULL, NULL,
1455                                &nValues,  NULL,  NULL, NULL, &ft))
1456                                != ERROR_SUCCESS) {
1457         return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryInfoKey");
1458     }
1459     li.LowPart = ft.dwLowDateTime;
1460     li.HighPart = ft.dwHighDateTime;
1461     l = PyLong_FromLongLong(li.QuadPart);
1462     if (l == NULL) {
1463         return NULL;
1464     }
1465     ret = Py_BuildValue("iiO", nSubKeys, nValues, l);
1466     Py_DECREF(l);
1467     return ret;
1468 }
1469 
1470 /*[clinic input]
1471 winreg.QueryValue
1472 
1473     key: HKEY
1474         An already open key, or any one of the predefined HKEY_* constants.
1475     sub_key: Py_UNICODE(accept={str, NoneType})
1476         A string that holds the name of the subkey with which the value
1477         is associated.  If this parameter is None or empty, the function
1478         retrieves the value set by the SetValue() method for the key
1479         identified by key.
1480     /
1481 
1482 Retrieves the unnamed value for a key.
1483 
1484 Values in the registry have name, type, and data components. This method
1485 retrieves the data for a key's first value that has a NULL name.
1486 But since the underlying API call doesn't return the type, you'll
1487 probably be happier using QueryValueEx; this function is just here for
1488 completeness.
1489 [clinic start generated code]*/
1490 
1491 static PyObject *
winreg_QueryValue_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key)1492 winreg_QueryValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
1493 /*[clinic end generated code: output=c655810ae50c63a9 input=41cafbbf423b21d6]*/
1494 {
1495     long rc;
1496     PyObject *retStr;
1497     wchar_t *retBuf;
1498     DWORD bufSize = 0;
1499     DWORD retSize = 0;
1500     wchar_t *tmp;
1501 
1502     if (PySys_Audit("winreg.QueryValue", "nuu",
1503                     (Py_ssize_t)key, sub_key, NULL) < 0) {
1504         return NULL;
1505     }
1506     rc = RegQueryValueW(key, sub_key, NULL, &retSize);
1507     if (rc == ERROR_MORE_DATA)
1508         retSize = 256;
1509     else if (rc != ERROR_SUCCESS)
1510         return PyErr_SetFromWindowsErrWithFunction(rc,
1511                                                    "RegQueryValue");
1512 
1513     bufSize = retSize;
1514     retBuf = (wchar_t *) PyMem_Malloc(bufSize);
1515     if (retBuf == NULL)
1516         return PyErr_NoMemory();
1517 
1518     while (1) {
1519         retSize = bufSize;
1520         rc = RegQueryValueW(key, sub_key, retBuf, &retSize);
1521         if (rc != ERROR_MORE_DATA)
1522             break;
1523 
1524         bufSize *= 2;
1525         tmp = (wchar_t *) PyMem_Realloc(retBuf, bufSize);
1526         if (tmp == NULL) {
1527             PyMem_Free(retBuf);
1528             return PyErr_NoMemory();
1529         }
1530         retBuf = tmp;
1531     }
1532 
1533     if (rc != ERROR_SUCCESS) {
1534         PyMem_Free(retBuf);
1535         return PyErr_SetFromWindowsErrWithFunction(rc,
1536                                                    "RegQueryValue");
1537     }
1538 
1539     retStr = PyUnicode_FromWideChar(retBuf, wcslen(retBuf));
1540     PyMem_Free(retBuf);
1541     return retStr;
1542 }
1543 
1544 
1545 /*[clinic input]
1546 winreg.QueryValueEx
1547 
1548     key: HKEY
1549         An already open key, or any one of the predefined HKEY_* constants.
1550     name: Py_UNICODE(accept={str, NoneType})
1551         A string indicating the value to query.
1552     /
1553 
1554 Retrieves the type and value of a specified sub-key.
1555 
1556 Behaves mostly like QueryValue(), but also returns the type of the
1557 specified value name associated with the given open registry key.
1558 
1559 The return value is a tuple of the value and the type_id.
1560 [clinic start generated code]*/
1561 
1562 static PyObject *
winreg_QueryValueEx_impl(PyObject * module,HKEY key,const Py_UNICODE * name)1563 winreg_QueryValueEx_impl(PyObject *module, HKEY key, const Py_UNICODE *name)
1564 /*[clinic end generated code: output=f1b85b1c3d887ec7 input=cf366cada4836891]*/
1565 {
1566     long rc;
1567     BYTE *retBuf, *tmp;
1568     DWORD bufSize = 0, retSize;
1569     DWORD typ;
1570     PyObject *obData;
1571     PyObject *result;
1572 
1573     if (PySys_Audit("winreg.QueryValue", "nuu",
1574                     (Py_ssize_t)key, NULL, name) < 0) {
1575         return NULL;
1576     }
1577     rc = RegQueryValueExW(key, name, NULL, NULL, NULL, &bufSize);
1578     if (rc == ERROR_MORE_DATA)
1579         bufSize = 256;
1580     else if (rc != ERROR_SUCCESS)
1581         return PyErr_SetFromWindowsErrWithFunction(rc,
1582                                                    "RegQueryValueEx");
1583     retBuf = (BYTE *)PyMem_Malloc(bufSize);
1584     if (retBuf == NULL)
1585         return PyErr_NoMemory();
1586 
1587     while (1) {
1588         retSize = bufSize;
1589         rc = RegQueryValueExW(key, name, NULL, &typ,
1590                              (BYTE *)retBuf, &retSize);
1591         if (rc != ERROR_MORE_DATA)
1592             break;
1593 
1594         bufSize *= 2;
1595         tmp = (char *) PyMem_Realloc(retBuf, bufSize);
1596         if (tmp == NULL) {
1597             PyMem_Free(retBuf);
1598             return PyErr_NoMemory();
1599         }
1600        retBuf = tmp;
1601     }
1602 
1603     if (rc != ERROR_SUCCESS) {
1604         PyMem_Free(retBuf);
1605         return PyErr_SetFromWindowsErrWithFunction(rc,
1606                                                    "RegQueryValueEx");
1607     }
1608     obData = Reg2Py(retBuf, bufSize, typ);
1609     PyMem_Free(retBuf);
1610     if (obData == NULL)
1611         return NULL;
1612     result = Py_BuildValue("Oi", obData, typ);
1613     Py_DECREF(obData);
1614     return result;
1615 }
1616 
1617 /*[clinic input]
1618 winreg.SaveKey
1619 
1620     key: HKEY
1621         An already open key, or any one of the predefined HKEY_* constants.
1622     file_name: Py_UNICODE
1623         The name of the file to save registry data to.  This file cannot
1624         already exist. If this filename includes an extension, it cannot be
1625         used on file allocation table (FAT) file systems by the LoadKey(),
1626         ReplaceKey() or RestoreKey() methods.
1627     /
1628 
1629 Saves the specified key, and all its subkeys to the specified file.
1630 
1631 If key represents a key on a remote computer, the path described by
1632 file_name is relative to the remote computer.
1633 
1634 The caller of this method must possess the SeBackupPrivilege
1635 security privilege.  This function passes NULL for security_attributes
1636 to the API.
1637 [clinic start generated code]*/
1638 
1639 static PyObject *
winreg_SaveKey_impl(PyObject * module,HKEY key,const Py_UNICODE * file_name)1640 winreg_SaveKey_impl(PyObject *module, HKEY key, const Py_UNICODE *file_name)
1641 /*[clinic end generated code: output=ca94b835c88f112b input=da735241f91ac7a2]*/
1642 {
1643     LPSECURITY_ATTRIBUTES pSA = NULL;
1644 
1645     long rc;
1646 /*  One day we may get security into the core?
1647     if (!PyWinObject_AsSECURITY_ATTRIBUTES(obSA, &pSA, TRUE))
1648         return NULL;
1649 */
1650     if (PySys_Audit("winreg.SaveKey", "nu",
1651                     (Py_ssize_t)key, file_name) < 0) {
1652         return NULL;
1653     }
1654     Py_BEGIN_ALLOW_THREADS
1655     rc = RegSaveKeyW(key, file_name, pSA );
1656     Py_END_ALLOW_THREADS
1657     if (rc != ERROR_SUCCESS)
1658         return PyErr_SetFromWindowsErrWithFunction(rc, "RegSaveKey");
1659     Py_RETURN_NONE;
1660 }
1661 
1662 /*[clinic input]
1663 winreg.SetValue
1664 
1665     key: HKEY
1666         An already open key, or any one of the predefined HKEY_* constants.
1667     sub_key: Py_UNICODE(accept={str, NoneType})
1668         A string that names the subkey with which the value is associated.
1669     type: DWORD
1670         An integer that specifies the type of the data.  Currently this must
1671         be REG_SZ, meaning only strings are supported.
1672     value: Py_UNICODE(zeroes=True)
1673         A string that specifies the new value.
1674     /
1675 
1676 Associates a value with a specified key.
1677 
1678 If the key specified by the sub_key parameter does not exist, the
1679 SetValue function creates it.
1680 
1681 Value lengths are limited by available memory. Long values (more than
1682 2048 bytes) should be stored as files with the filenames stored in
1683 the configuration registry to help the registry perform efficiently.
1684 
1685 The key identified by the key parameter must have been opened with
1686 KEY_SET_VALUE access.
1687 [clinic start generated code]*/
1688 
1689 static PyObject *
winreg_SetValue_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key,DWORD type,const Py_UNICODE * value,Py_ssize_clean_t value_length)1690 winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
1691                      DWORD type, const Py_UNICODE *value,
1692                      Py_ssize_clean_t value_length)
1693 /*[clinic end generated code: output=686bedb1cbb4367b input=2cd2adab79339c53]*/
1694 {
1695     long rc;
1696 
1697     if (type != REG_SZ) {
1698         PyErr_SetString(PyExc_TypeError, "type must be winreg.REG_SZ");
1699         return NULL;
1700     }
1701     if ((size_t)value_length >= PY_DWORD_MAX) {
1702         PyErr_SetString(PyExc_OverflowError, "value is too long");
1703         return NULL;
1704     }
1705 
1706     if (PySys_Audit("winreg.SetValue", "nunu#",
1707                     (Py_ssize_t)key, sub_key, (Py_ssize_t)type,
1708                     value, value_length) < 0) {
1709         return NULL;
1710     }
1711 
1712     Py_BEGIN_ALLOW_THREADS
1713     rc = RegSetValueW(key, sub_key, REG_SZ, value, (DWORD)(value_length + 1));
1714     Py_END_ALLOW_THREADS
1715     if (rc != ERROR_SUCCESS)
1716         return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue");
1717     Py_RETURN_NONE;
1718 }
1719 
1720 /*[clinic input]
1721 winreg.SetValueEx
1722 
1723     key: HKEY
1724         An already open key, or any one of the predefined HKEY_* constants.
1725     value_name: Py_UNICODE(accept={str, NoneType})
1726         A string containing the name of the value to set, or None.
1727     reserved: object
1728         Can be anything - zero is always passed to the API.
1729     type: DWORD
1730         An integer that specifies the type of the data, one of:
1731         REG_BINARY -- Binary data in any form.
1732         REG_DWORD -- A 32-bit number.
1733         REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format. Equivalent to REG_DWORD
1734         REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format.
1735         REG_EXPAND_SZ -- A null-terminated string that contains unexpanded
1736                          references to environment variables (for example,
1737                          %PATH%).
1738         REG_LINK -- A Unicode symbolic link.
1739         REG_MULTI_SZ -- A sequence of null-terminated strings, terminated
1740                         by two null characters.  Note that Python handles
1741                         this termination automatically.
1742         REG_NONE -- No defined value type.
1743         REG_QWORD -- A 64-bit number.
1744         REG_QWORD_LITTLE_ENDIAN -- A 64-bit number in little-endian format. Equivalent to REG_QWORD.
1745         REG_RESOURCE_LIST -- A device-driver resource list.
1746         REG_SZ -- A null-terminated string.
1747     value: object
1748         A string that specifies the new value.
1749     /
1750 
1751 Stores data in the value field of an open registry key.
1752 
1753 This method can also set additional value and type information for the
1754 specified key.  The key identified by the key parameter must have been
1755 opened with KEY_SET_VALUE access.
1756 
1757 To open the key, use the CreateKeyEx() or OpenKeyEx() methods.
1758 
1759 Value lengths are limited by available memory. Long values (more than
1760 2048 bytes) should be stored as files with the filenames stored in
1761 the configuration registry to help the registry perform efficiently.
1762 [clinic start generated code]*/
1763 
1764 static PyObject *
winreg_SetValueEx_impl(PyObject * module,HKEY key,const Py_UNICODE * value_name,PyObject * reserved,DWORD type,PyObject * value)1765 winreg_SetValueEx_impl(PyObject *module, HKEY key,
1766                        const Py_UNICODE *value_name, PyObject *reserved,
1767                        DWORD type, PyObject *value)
1768 /*[clinic end generated code: output=811b769a66ae11b7 input=900a9e3990bfb196]*/
1769 {
1770     BYTE *data;
1771     DWORD len;
1772 
1773     LONG rc;
1774 
1775     if (!Py2Reg(value, type, &data, &len))
1776     {
1777         if (!PyErr_Occurred())
1778             PyErr_SetString(PyExc_ValueError,
1779                      "Could not convert the data to the specified type.");
1780         return NULL;
1781     }
1782     if (PySys_Audit("winreg.SetValue", "nunO",
1783                     (Py_ssize_t)key, value_name, (Py_ssize_t)type,
1784                     value) < 0) {
1785         PyMem_Free(data);
1786         return NULL;
1787     }
1788     Py_BEGIN_ALLOW_THREADS
1789     rc = RegSetValueExW(key, value_name, 0, type, data, len);
1790     Py_END_ALLOW_THREADS
1791     PyMem_DEL(data);
1792     if (rc != ERROR_SUCCESS)
1793         return PyErr_SetFromWindowsErrWithFunction(rc,
1794                                                    "RegSetValueEx");
1795     Py_RETURN_NONE;
1796 }
1797 
1798 /*[clinic input]
1799 winreg.DisableReflectionKey
1800 
1801     key: HKEY
1802         An already open key, or any one of the predefined HKEY_* constants.
1803     /
1804 
1805 Disables registry reflection for 32bit processes running on a 64bit OS.
1806 
1807 Will generally raise NotImplementedError if executed on a 32bit OS.
1808 
1809 If the key is not on the reflection list, the function succeeds but has
1810 no effect.  Disabling reflection for a key does not affect reflection
1811 of any subkeys.
1812 [clinic start generated code]*/
1813 
1814 static PyObject *
winreg_DisableReflectionKey_impl(PyObject * module,HKEY key)1815 winreg_DisableReflectionKey_impl(PyObject *module, HKEY key)
1816 /*[clinic end generated code: output=830cce504cc764b4 input=70bece2dee02e073]*/
1817 {
1818     HMODULE hMod;
1819     typedef LONG (WINAPI *RDRKFunc)(HKEY);
1820     RDRKFunc pfn = NULL;
1821     LONG rc;
1822 
1823     if (PySys_Audit("winreg.DisableReflectionKey", "n", (Py_ssize_t)key) < 0) {
1824         return NULL;
1825     }
1826 
1827     /* Only available on 64bit platforms, so we must load it
1828        dynamically.*/
1829     Py_BEGIN_ALLOW_THREADS
1830     hMod = GetModuleHandleW(L"advapi32.dll");
1831     if (hMod)
1832         pfn = (RDRKFunc)GetProcAddress(hMod,
1833                                        "RegDisableReflectionKey");
1834     Py_END_ALLOW_THREADS
1835     if (!pfn) {
1836         PyErr_SetString(PyExc_NotImplementedError,
1837                         "not implemented on this platform");
1838         return NULL;
1839     }
1840     Py_BEGIN_ALLOW_THREADS
1841     rc = (*pfn)(key);
1842     Py_END_ALLOW_THREADS
1843     if (rc != ERROR_SUCCESS)
1844         return PyErr_SetFromWindowsErrWithFunction(rc,
1845                                                    "RegDisableReflectionKey");
1846     Py_RETURN_NONE;
1847 }
1848 
1849 /*[clinic input]
1850 winreg.EnableReflectionKey
1851 
1852     key: HKEY
1853         An already open key, or any one of the predefined HKEY_* constants.
1854     /
1855 
1856 Restores registry reflection for the specified disabled key.
1857 
1858 Will generally raise NotImplementedError if executed on a 32bit OS.
1859 Restoring reflection for a key does not affect reflection of any
1860 subkeys.
1861 [clinic start generated code]*/
1862 
1863 static PyObject *
winreg_EnableReflectionKey_impl(PyObject * module,HKEY key)1864 winreg_EnableReflectionKey_impl(PyObject *module, HKEY key)
1865 /*[clinic end generated code: output=86fa1385fdd9ce57 input=eeae770c6eb9f559]*/
1866 {
1867     HMODULE hMod;
1868     typedef LONG (WINAPI *RERKFunc)(HKEY);
1869     RERKFunc pfn = NULL;
1870     LONG rc;
1871 
1872     if (PySys_Audit("winreg.EnableReflectionKey", "n", (Py_ssize_t)key) < 0) {
1873         return NULL;
1874     }
1875 
1876     /* Only available on 64bit platforms, so we must load it
1877        dynamically.*/
1878     Py_BEGIN_ALLOW_THREADS
1879     hMod = GetModuleHandleW(L"advapi32.dll");
1880     if (hMod)
1881         pfn = (RERKFunc)GetProcAddress(hMod,
1882                                        "RegEnableReflectionKey");
1883     Py_END_ALLOW_THREADS
1884     if (!pfn) {
1885         PyErr_SetString(PyExc_NotImplementedError,
1886                         "not implemented on this platform");
1887         return NULL;
1888     }
1889     Py_BEGIN_ALLOW_THREADS
1890     rc = (*pfn)(key);
1891     Py_END_ALLOW_THREADS
1892     if (rc != ERROR_SUCCESS)
1893         return PyErr_SetFromWindowsErrWithFunction(rc,
1894                                                    "RegEnableReflectionKey");
1895     Py_RETURN_NONE;
1896 }
1897 
1898 /*[clinic input]
1899 winreg.QueryReflectionKey
1900 
1901     key: HKEY
1902         An already open key, or any one of the predefined HKEY_* constants.
1903     /
1904 
1905 Returns the reflection state for the specified key as a bool.
1906 
1907 Will generally raise NotImplementedError if executed on a 32bit OS.
1908 [clinic start generated code]*/
1909 
1910 static PyObject *
winreg_QueryReflectionKey_impl(PyObject * module,HKEY key)1911 winreg_QueryReflectionKey_impl(PyObject *module, HKEY key)
1912 /*[clinic end generated code: output=4e774af288c3ebb9 input=a98fa51d55ade186]*/
1913 {
1914     HMODULE hMod;
1915     typedef LONG (WINAPI *RQRKFunc)(HKEY, BOOL *);
1916     RQRKFunc pfn = NULL;
1917     BOOL result;
1918     LONG rc;
1919 
1920     if (PySys_Audit("winreg.QueryReflectionKey", "n", (Py_ssize_t)key) < 0) {
1921         return NULL;
1922     }
1923 
1924     /* Only available on 64bit platforms, so we must load it
1925        dynamically.*/
1926     Py_BEGIN_ALLOW_THREADS
1927     hMod = GetModuleHandleW(L"advapi32.dll");
1928     if (hMod)
1929         pfn = (RQRKFunc)GetProcAddress(hMod,
1930                                        "RegQueryReflectionKey");
1931     Py_END_ALLOW_THREADS
1932     if (!pfn) {
1933         PyErr_SetString(PyExc_NotImplementedError,
1934                         "not implemented on this platform");
1935         return NULL;
1936     }
1937     Py_BEGIN_ALLOW_THREADS
1938     rc = (*pfn)(key, &result);
1939     Py_END_ALLOW_THREADS
1940     if (rc != ERROR_SUCCESS)
1941         return PyErr_SetFromWindowsErrWithFunction(rc,
1942                                                    "RegQueryReflectionKey");
1943     return PyBool_FromLong(result);
1944 }
1945 
1946 static struct PyMethodDef winreg_methods[] = {
1947     WINREG_CLOSEKEY_METHODDEF
1948     WINREG_CONNECTREGISTRY_METHODDEF
1949     WINREG_CREATEKEY_METHODDEF
1950     WINREG_CREATEKEYEX_METHODDEF
1951     WINREG_DELETEKEY_METHODDEF
1952     WINREG_DELETEKEYEX_METHODDEF
1953     WINREG_DELETEVALUE_METHODDEF
1954     WINREG_DISABLEREFLECTIONKEY_METHODDEF
1955     WINREG_ENABLEREFLECTIONKEY_METHODDEF
1956     WINREG_ENUMKEY_METHODDEF
1957     WINREG_ENUMVALUE_METHODDEF
1958     WINREG_EXPANDENVIRONMENTSTRINGS_METHODDEF
1959     WINREG_FLUSHKEY_METHODDEF
1960     WINREG_LOADKEY_METHODDEF
1961     WINREG_OPENKEY_METHODDEF
1962     WINREG_OPENKEYEX_METHODDEF
1963     WINREG_QUERYVALUE_METHODDEF
1964     WINREG_QUERYVALUEEX_METHODDEF
1965     WINREG_QUERYINFOKEY_METHODDEF
1966     WINREG_QUERYREFLECTIONKEY_METHODDEF
1967     WINREG_SAVEKEY_METHODDEF
1968     WINREG_SETVALUE_METHODDEF
1969     WINREG_SETVALUEEX_METHODDEF
1970     NULL,
1971 };
1972 
1973 static void
insint(PyObject * d,char * name,long value)1974 insint(PyObject * d, char * name, long value)
1975 {
1976     PyObject *v = PyLong_FromLong(value);
1977     if (!v || PyDict_SetItemString(d, name, v))
1978         PyErr_Clear();
1979     Py_XDECREF(v);
1980 }
1981 
1982 #define ADD_INT(val) insint(d, #val, val)
1983 
1984 static void
inskey(PyObject * d,char * name,HKEY key)1985 inskey(PyObject * d, char * name, HKEY key)
1986 {
1987     PyObject *v = PyLong_FromVoidPtr(key);
1988     if (!v || PyDict_SetItemString(d, name, v))
1989         PyErr_Clear();
1990     Py_XDECREF(v);
1991 }
1992 
1993 #define ADD_KEY(val) inskey(d, #val, val)
1994 
1995 
1996 static struct PyModuleDef winregmodule = {
1997     PyModuleDef_HEAD_INIT,
1998     "winreg",
1999     module_doc,
2000     -1,
2001     winreg_methods,
2002     NULL,
2003     NULL,
2004     NULL,
2005     NULL
2006 };
2007 
PyInit_winreg(void)2008 PyMODINIT_FUNC PyInit_winreg(void)
2009 {
2010     PyObject *m, *d;
2011     m = PyModule_Create(&winregmodule);
2012     if (m == NULL)
2013         return NULL;
2014     d = PyModule_GetDict(m);
2015     PyHKEY_Type.tp_doc = PyHKEY_doc;
2016     if (PyType_Ready(&PyHKEY_Type) < 0)
2017         return NULL;
2018     Py_INCREF(&PyHKEY_Type);
2019     if (PyDict_SetItemString(d, "HKEYType",
2020                              (PyObject *)&PyHKEY_Type) != 0)
2021         return NULL;
2022     Py_INCREF(PyExc_OSError);
2023     if (PyDict_SetItemString(d, "error",
2024                              PyExc_OSError) != 0)
2025         return NULL;
2026 
2027     /* Add the relevant constants */
2028     ADD_KEY(HKEY_CLASSES_ROOT);
2029     ADD_KEY(HKEY_CURRENT_USER);
2030     ADD_KEY(HKEY_LOCAL_MACHINE);
2031     ADD_KEY(HKEY_USERS);
2032     ADD_KEY(HKEY_PERFORMANCE_DATA);
2033 #ifdef HKEY_CURRENT_CONFIG
2034     ADD_KEY(HKEY_CURRENT_CONFIG);
2035 #endif
2036 #ifdef HKEY_DYN_DATA
2037     ADD_KEY(HKEY_DYN_DATA);
2038 #endif
2039     ADD_INT(KEY_QUERY_VALUE);
2040     ADD_INT(KEY_SET_VALUE);
2041     ADD_INT(KEY_CREATE_SUB_KEY);
2042     ADD_INT(KEY_ENUMERATE_SUB_KEYS);
2043     ADD_INT(KEY_NOTIFY);
2044     ADD_INT(KEY_CREATE_LINK);
2045     ADD_INT(KEY_READ);
2046     ADD_INT(KEY_WRITE);
2047     ADD_INT(KEY_EXECUTE);
2048     ADD_INT(KEY_ALL_ACCESS);
2049 #ifdef KEY_WOW64_64KEY
2050     ADD_INT(KEY_WOW64_64KEY);
2051 #endif
2052 #ifdef KEY_WOW64_32KEY
2053     ADD_INT(KEY_WOW64_32KEY);
2054 #endif
2055     ADD_INT(REG_OPTION_RESERVED);
2056     ADD_INT(REG_OPTION_NON_VOLATILE);
2057     ADD_INT(REG_OPTION_VOLATILE);
2058     ADD_INT(REG_OPTION_CREATE_LINK);
2059     ADD_INT(REG_OPTION_BACKUP_RESTORE);
2060     ADD_INT(REG_OPTION_OPEN_LINK);
2061     ADD_INT(REG_LEGAL_OPTION);
2062     ADD_INT(REG_CREATED_NEW_KEY);
2063     ADD_INT(REG_OPENED_EXISTING_KEY);
2064     ADD_INT(REG_WHOLE_HIVE_VOLATILE);
2065     ADD_INT(REG_REFRESH_HIVE);
2066     ADD_INT(REG_NO_LAZY_FLUSH);
2067     ADD_INT(REG_NOTIFY_CHANGE_NAME);
2068     ADD_INT(REG_NOTIFY_CHANGE_ATTRIBUTES);
2069     ADD_INT(REG_NOTIFY_CHANGE_LAST_SET);
2070     ADD_INT(REG_NOTIFY_CHANGE_SECURITY);
2071     ADD_INT(REG_LEGAL_CHANGE_FILTER);
2072     ADD_INT(REG_NONE);
2073     ADD_INT(REG_SZ);
2074     ADD_INT(REG_EXPAND_SZ);
2075     ADD_INT(REG_BINARY);
2076     ADD_INT(REG_DWORD);
2077     ADD_INT(REG_DWORD_LITTLE_ENDIAN);
2078     ADD_INT(REG_DWORD_BIG_ENDIAN);
2079     ADD_INT(REG_QWORD);
2080     ADD_INT(REG_QWORD_LITTLE_ENDIAN);
2081     ADD_INT(REG_LINK);
2082     ADD_INT(REG_MULTI_SZ);
2083     ADD_INT(REG_RESOURCE_LIST);
2084     ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR);
2085     ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST);
2086     return m;
2087 }
2088 
2089 
2090