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