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