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             if (value != Py_None && !PyLong_Check(value))
569                 return FALSE;
570             *retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1);
571             if (*retDataBuf == NULL){
572                 PyErr_NoMemory();
573                 return FALSE;
574             }
575             *retDataSize = sizeof(DWORD);
576             if (value == Py_None) {
577                 DWORD zero = 0;
578                 memcpy(*retDataBuf, &zero, sizeof(DWORD));
579             }
580             else {
581                 DWORD d = PyLong_AsUnsignedLong(value);
582                 memcpy(*retDataBuf, &d, sizeof(DWORD));
583             }
584             break;
585         case REG_QWORD:
586           if (value != Py_None && !PyLong_Check(value))
587                 return FALSE;
588             *retDataBuf = (BYTE *)PyMem_NEW(DWORD64, 1);
589             if (*retDataBuf == NULL){
590                 PyErr_NoMemory();
591                 return FALSE;
592             }
593             *retDataSize = sizeof(DWORD64);
594             if (value == Py_None) {
595                 DWORD64 zero = 0;
596                 memcpy(*retDataBuf, &zero, sizeof(DWORD64));
597             }
598             else {
599                 DWORD64 d = PyLong_AsUnsignedLongLong(value);
600                 memcpy(*retDataBuf, &d, sizeof(DWORD64));
601             }
602             break;
603         case REG_SZ:
604         case REG_EXPAND_SZ:
605             {
606                 if (value != Py_None) {
607                     Py_ssize_t len;
608                     if (!PyUnicode_Check(value))
609                         return FALSE;
610                     *retDataBuf = (BYTE*)PyUnicode_AsWideCharString(value, &len);
611                     if (*retDataBuf == NULL)
612                         return FALSE;
613                     *retDataSize = Py_SAFE_DOWNCAST(
614                         (len + 1) * sizeof(wchar_t),
615                         Py_ssize_t, DWORD);
616                 }
617                 else {
618                     *retDataBuf = (BYTE *)PyMem_NEW(wchar_t, 1);
619                     if (*retDataBuf == NULL) {
620                         PyErr_NoMemory();
621                         return FALSE;
622                     }
623                     ((wchar_t *)*retDataBuf)[0] = L'\0';
624                     *retDataSize = 1 * sizeof(wchar_t);
625                 }
626                 break;
627             }
628         case REG_MULTI_SZ:
629             {
630                 DWORD size = 0;
631                 wchar_t *P;
632 
633                 if (value == Py_None)
634                     i = 0;
635                 else {
636                     if (!PyList_Check(value))
637                         return FALSE;
638                     i = PyList_Size(value);
639                 }
640                 for (j = 0; j < i; j++)
641                 {
642                     PyObject *t;
643                     Py_ssize_t len;
644 
645                     t = PyList_GET_ITEM(value, j);
646                     if (!PyUnicode_Check(t))
647                         return FALSE;
648 #if USE_UNICODE_WCHAR_CACHE
649 _Py_COMP_DIAG_PUSH
650 _Py_COMP_DIAG_IGNORE_DEPR_DECLS
651                     len = PyUnicode_GetSize(t);
652                     if (len < 0)
653                         return FALSE;
654                     len++;
655 _Py_COMP_DIAG_POP
656 #else /* USE_UNICODE_WCHAR_CACHE */
657                     len = PyUnicode_AsWideChar(t, NULL, 0);
658                     if (len < 0)
659                         return FALSE;
660 #endif /* USE_UNICODE_WCHAR_CACHE */
661                     size += Py_SAFE_DOWNCAST(len * sizeof(wchar_t),
662                                              size_t, DWORD);
663                 }
664 
665                 *retDataSize = size + 2;
666                 *retDataBuf = (BYTE *)PyMem_NEW(char,
667                                                 *retDataSize);
668                 if (*retDataBuf == NULL){
669                     PyErr_NoMemory();
670                     return FALSE;
671                 }
672                 P = (wchar_t *)*retDataBuf;
673 
674                 for (j = 0; j < i; j++)
675                 {
676                     PyObject *t;
677                     Py_ssize_t len;
678 
679                     t = PyList_GET_ITEM(value, j);
680                     assert(size > 0);
681                     len = PyUnicode_AsWideChar(t, P, size);
682                     assert(len >= 0);
683                     assert((unsigned)len < size);
684                     size -= (DWORD)len + 1;
685                     P += len + 1;
686                 }
687                 /* And doubly-terminate the list... */
688                 *P = L'\0';
689                 break;
690             }
691         case REG_BINARY:
692         /* ALSO handle ALL unknown data types here.  Even if we can't
693            support it natively, we should handle the bits. */
694         default:
695             if (value == Py_None) {
696                 *retDataSize = 0;
697                 *retDataBuf = NULL;
698             }
699             else {
700                 Py_buffer view;
701 
702                 if (!PyObject_CheckBuffer(value)) {
703                     PyErr_Format(PyExc_TypeError,
704                         "Objects of type '%s' can not "
705                         "be used as binary registry values",
706                         Py_TYPE(value)->tp_name);
707                     return FALSE;
708                 }
709 
710                 if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
711                     return FALSE;
712 
713                 *retDataBuf = (BYTE *)PyMem_NEW(char, view.len);
714                 if (*retDataBuf == NULL){
715                     PyBuffer_Release(&view);
716                     PyErr_NoMemory();
717                     return FALSE;
718                 }
719                 *retDataSize = Py_SAFE_DOWNCAST(view.len, Py_ssize_t, DWORD);
720                 memcpy(*retDataBuf, view.buf, view.len);
721                 PyBuffer_Release(&view);
722             }
723             break;
724     }
725     return TRUE;
726 }
727 
728 /* Convert Registry data into PyObject*/
729 static PyObject *
Reg2Py(BYTE * retDataBuf,DWORD retDataSize,DWORD typ)730 Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ)
731 {
732     PyObject *obData;
733 
734     switch (typ) {
735         case REG_DWORD:
736             if (retDataSize == 0)
737                 obData = PyLong_FromUnsignedLong(0);
738             else
739                 obData = PyLong_FromUnsignedLong(*(DWORD *)retDataBuf);
740             break;
741         case REG_QWORD:
742             if (retDataSize == 0)
743                 obData = PyLong_FromUnsignedLongLong(0);
744             else
745                 obData = PyLong_FromUnsignedLongLong(*(DWORD64 *)retDataBuf);
746             break;
747         case REG_SZ:
748         case REG_EXPAND_SZ:
749             {
750                 /* REG_SZ should be a NUL terminated string, but only by
751                  * convention. The buffer may have been saved without a NUL
752                  * or with embedded NULs. To be consistent with reg.exe and
753                  * regedit.exe, consume only up to the first NUL. */
754                 wchar_t *data = (wchar_t *)retDataBuf;
755                 size_t len = wcsnlen(data, retDataSize / sizeof(wchar_t));
756                 obData = PyUnicode_FromWideChar(data, len);
757                 break;
758             }
759         case REG_MULTI_SZ:
760             if (retDataSize == 0)
761                 obData = PyList_New(0);
762             else
763             {
764                 int index = 0;
765                 wchar_t *data = (wchar_t *)retDataBuf;
766                 int len = retDataSize / 2;
767                 int s = countStrings(data, len);
768                 wchar_t **str = PyMem_New(wchar_t *, s);
769                 if (str == NULL)
770                     return PyErr_NoMemory();
771 
772                 fixupMultiSZ(str, data, len);
773                 obData = PyList_New(s);
774                 if (obData == NULL) {
775                     PyMem_Free(str);
776                     return NULL;
777                 }
778                 for (index = 0; index < s; index++)
779                 {
780                     size_t slen = wcsnlen(str[index], len);
781                     PyObject *uni = PyUnicode_FromWideChar(str[index], slen);
782                     if (uni == NULL) {
783                         Py_DECREF(obData);
784                         PyMem_Free(str);
785                         return NULL;
786                     }
787                     PyList_SET_ITEM(obData, index, uni);
788                     len -= Py_SAFE_DOWNCAST(slen + 1, size_t, int);
789                 }
790                 PyMem_Free(str);
791 
792                 break;
793             }
794         case REG_BINARY:
795         /* ALSO handle ALL unknown data types here.  Even if we can't
796            support it natively, we should handle the bits. */
797         default:
798             if (retDataSize == 0) {
799                 Py_INCREF(Py_None);
800                 obData = Py_None;
801             }
802             else
803                 obData = PyBytes_FromStringAndSize(
804                              (char *)retDataBuf, retDataSize);
805             break;
806     }
807     return obData;
808 }
809 
810 /* The Python methods */
811 
812 /*[clinic input]
813 winreg.CloseKey
814 
815     hkey: object
816         A previously opened key.
817     /
818 
819 Closes a previously opened registry key.
820 
821 Note that if the key is not closed using this method, it will be
822 closed when the hkey object is destroyed by Python.
823 [clinic start generated code]*/
824 
825 static PyObject *
winreg_CloseKey(PyObject * module,PyObject * hkey)826 winreg_CloseKey(PyObject *module, PyObject *hkey)
827 /*[clinic end generated code: output=a4fa537019a80d15 input=5b1aac65ba5127ad]*/
828 {
829     if (!PyHKEY_Close(hkey))
830         return NULL;
831     Py_RETURN_NONE;
832 }
833 
834 /*[clinic input]
835 winreg.ConnectRegistry -> HKEY
836 
837     computer_name: Py_UNICODE(accept={str, NoneType})
838         The name of the remote computer, of the form r"\\computername".  If
839         None, the local computer is used.
840     key: HKEY
841         The predefined key to connect to.
842     /
843 
844 Establishes a connection to the registry on another computer.
845 
846 The return value is the handle of the opened key.
847 If the function fails, an OSError exception is raised.
848 [clinic start generated code]*/
849 
850 static HKEY
winreg_ConnectRegistry_impl(PyObject * module,const Py_UNICODE * computer_name,HKEY key)851 winreg_ConnectRegistry_impl(PyObject *module,
852                             const Py_UNICODE *computer_name, HKEY key)
853 /*[clinic end generated code: output=cd4f70fb9ec901fb input=5f98a891a347e68e]*/
854 {
855     HKEY retKey;
856     long rc;
857     if (PySys_Audit("winreg.ConnectRegistry", "un",
858                     computer_name, (Py_ssize_t)key) < 0) {
859         return NULL;
860     }
861     Py_BEGIN_ALLOW_THREADS
862     rc = RegConnectRegistryW(computer_name, key, &retKey);
863     Py_END_ALLOW_THREADS
864     if (rc != ERROR_SUCCESS) {
865         PyErr_SetFromWindowsErrWithFunction(rc, "ConnectRegistry");
866         return NULL;
867     }
868     return retKey;
869 }
870 
871 /*[clinic input]
872 winreg.CreateKey -> HKEY
873 
874     key: HKEY
875         An already open key, or one of the predefined HKEY_* constants.
876     sub_key: Py_UNICODE(accept={str, NoneType})
877         The name of the key this method opens or creates.
878     /
879 
880 Creates or opens the specified key.
881 
882 If key is one of the predefined keys, sub_key may be None. In that case,
883 the handle returned is the same key handle passed in to the function.
884 
885 If the key already exists, this function opens the existing key.
886 
887 The return value is the handle of the opened key.
888 If the function fails, an OSError exception is raised.
889 [clinic start generated code]*/
890 
891 static HKEY
winreg_CreateKey_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key)892 winreg_CreateKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
893 /*[clinic end generated code: output=2af13910d56eae26 input=3cdd1622488acea2]*/
894 {
895     HKEY retKey;
896     long rc;
897 
898     if (PySys_Audit("winreg.CreateKey", "nun",
899                     (Py_ssize_t)key, sub_key,
900                     (Py_ssize_t)KEY_WRITE) < 0) {
901         return NULL;
902     }
903     rc = RegCreateKeyW(key, sub_key, &retKey);
904     if (rc != ERROR_SUCCESS) {
905         PyErr_SetFromWindowsErrWithFunction(rc, "CreateKey");
906         return NULL;
907     }
908     if (PySys_Audit("winreg.OpenKey/result", "n",
909                     (Py_ssize_t)retKey) < 0) {
910         return NULL;
911     }
912     return retKey;
913 }
914 
915 /*[clinic input]
916 winreg.CreateKeyEx -> HKEY
917 
918     key: HKEY
919         An already open key, or one of the predefined HKEY_* constants.
920     sub_key: Py_UNICODE(accept={str, NoneType})
921         The name of the key this method opens or creates.
922     reserved: int = 0
923         A reserved integer, and must be zero.  Default is zero.
924     access: REGSAM(c_default='KEY_WRITE') = winreg.KEY_WRITE
925         An integer that specifies an access mask that describes the
926         desired security access for the key. Default is KEY_WRITE.
927 
928 Creates or opens the specified key.
929 
930 If key is one of the predefined keys, sub_key may be None. In that case,
931 the handle returned is the same key handle passed in to the function.
932 
933 If the key already exists, this function opens the existing key
934 
935 The return value is the handle of the opened key.
936 If the function fails, an OSError exception is raised.
937 [clinic start generated code]*/
938 
939 static HKEY
winreg_CreateKeyEx_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key,int reserved,REGSAM access)940 winreg_CreateKeyEx_impl(PyObject *module, HKEY key,
941                         const Py_UNICODE *sub_key, int reserved,
942                         REGSAM access)
943 /*[clinic end generated code: output=643a70ad6a361a97 input=42c2b03f98406b66]*/
944 {
945     HKEY retKey;
946     long rc;
947 
948     if (PySys_Audit("winreg.CreateKey", "nun",
949                     (Py_ssize_t)key, sub_key,
950                     (Py_ssize_t)access) < 0) {
951         return NULL;
952     }
953     rc = RegCreateKeyExW(key, sub_key, reserved, NULL, 0,
954                          access, NULL, &retKey, NULL);
955     if (rc != ERROR_SUCCESS) {
956         PyErr_SetFromWindowsErrWithFunction(rc, "CreateKeyEx");
957         return NULL;
958     }
959     if (PySys_Audit("winreg.OpenKey/result", "n",
960                     (Py_ssize_t)retKey) < 0) {
961         return NULL;
962     }
963     return retKey;
964 }
965 
966 /*[clinic input]
967 winreg.DeleteKey
968     key: HKEY
969         An already open key, or any one of the predefined HKEY_* constants.
970     sub_key: Py_UNICODE
971         A string that must be the name of a subkey of the key identified by
972         the key parameter. This value must not be None, and the key may not
973         have subkeys.
974     /
975 
976 Deletes the specified key.
977 
978 This method can not delete keys with subkeys.
979 
980 If the function succeeds, the entire key, including all of its values,
981 is removed.  If the function fails, an OSError exception is raised.
982 [clinic start generated code]*/
983 
984 static PyObject *
winreg_DeleteKey_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key)985 winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
986 /*[clinic end generated code: output=d2652a84f70e0862 input=b31d225b935e4211]*/
987 {
988     long rc;
989     if (PySys_Audit("winreg.DeleteKey", "nun",
990                     (Py_ssize_t)key, sub_key,
991                     (Py_ssize_t)0) < 0) {
992         return NULL;
993     }
994     rc = RegDeleteKeyW(key, sub_key );
995     if (rc != ERROR_SUCCESS)
996         return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey");
997     Py_RETURN_NONE;
998 }
999 
1000 /*[clinic input]
1001 winreg.DeleteKeyEx
1002 
1003     key: HKEY
1004         An already open key, or any one of the predefined HKEY_* constants.
1005     sub_key: Py_UNICODE
1006         A string that must be the name of a subkey of the key identified by
1007         the key parameter. This value must not be None, and the key may not
1008         have subkeys.
1009     access: REGSAM(c_default='KEY_WOW64_64KEY') = winreg.KEY_WOW64_64KEY
1010         An integer that specifies an access mask that describes the
1011         desired security access for the key. Default is KEY_WOW64_64KEY.
1012     reserved: int = 0
1013         A reserved integer, and must be zero.  Default is zero.
1014 
1015 Deletes the specified key (64-bit OS only).
1016 
1017 This method can not delete keys with subkeys.
1018 
1019 If the function succeeds, the entire key, including all of its values,
1020 is removed.  If the function fails, an OSError exception is raised.
1021 On unsupported Windows versions, NotImplementedError is raised.
1022 [clinic start generated code]*/
1023 
1024 static PyObject *
winreg_DeleteKeyEx_impl(PyObject * module,HKEY key,const Py_UNICODE * sub_key,REGSAM access,int reserved)1025 winreg_DeleteKeyEx_impl(PyObject *module, HKEY key,
1026                         const Py_UNICODE *sub_key, REGSAM access,
1027                         int reserved)
1028 /*[clinic end generated code: output=52a1c8b374ebc003 input=711d9d89e7ecbed7]*/
1029 {
1030     HMODULE hMod;
1031     typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int);
1032     RDKEFunc pfn = NULL;
1033     long rc;
1034 
1035     if (PySys_Audit("winreg.DeleteKey", "nun",
1036                     (Py_ssize_t)key, sub_key,
1037                     (Py_ssize_t)access) < 0) {
1038         return NULL;
1039     }
1040     /* Only available on 64bit platforms, so we must load it
1041        dynamically. */
1042     Py_BEGIN_ALLOW_THREADS
1043     hMod = GetModuleHandleW(L"advapi32.dll");
1044     if (hMod)
1045         pfn = (RDKEFunc)GetProcAddress(hMod, "RegDeleteKeyExW");
1046     Py_END_ALLOW_THREADS
1047     if (!pfn) {
1048         PyErr_SetString(PyExc_NotImplementedError,
1049                                         "not implemented on this platform");
1050         return NULL;
1051     }
1052     Py_BEGIN_ALLOW_THREADS
1053     rc = (*pfn)(key, sub_key, access, reserved);
1054     Py_END_ALLOW_THREADS
1055 
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     Py_INCREF(&PyHKEY_Type);
2050     if (PyDict_SetItemString(d, "HKEYType",
2051                              (PyObject *)&PyHKEY_Type) != 0)
2052         return NULL;
2053     Py_INCREF(PyExc_OSError);
2054     if (PyDict_SetItemString(d, "error",
2055                              PyExc_OSError) != 0)
2056         return NULL;
2057 
2058     /* Add the relevant constants */
2059     ADD_KEY(HKEY_CLASSES_ROOT);
2060     ADD_KEY(HKEY_CURRENT_USER);
2061     ADD_KEY(HKEY_LOCAL_MACHINE);
2062     ADD_KEY(HKEY_USERS);
2063     ADD_KEY(HKEY_PERFORMANCE_DATA);
2064 #ifdef HKEY_CURRENT_CONFIG
2065     ADD_KEY(HKEY_CURRENT_CONFIG);
2066 #endif
2067 #ifdef HKEY_DYN_DATA
2068     ADD_KEY(HKEY_DYN_DATA);
2069 #endif
2070     ADD_INT(KEY_QUERY_VALUE);
2071     ADD_INT(KEY_SET_VALUE);
2072     ADD_INT(KEY_CREATE_SUB_KEY);
2073     ADD_INT(KEY_ENUMERATE_SUB_KEYS);
2074     ADD_INT(KEY_NOTIFY);
2075     ADD_INT(KEY_CREATE_LINK);
2076     ADD_INT(KEY_READ);
2077     ADD_INT(KEY_WRITE);
2078     ADD_INT(KEY_EXECUTE);
2079     ADD_INT(KEY_ALL_ACCESS);
2080 #ifdef KEY_WOW64_64KEY
2081     ADD_INT(KEY_WOW64_64KEY);
2082 #endif
2083 #ifdef KEY_WOW64_32KEY
2084     ADD_INT(KEY_WOW64_32KEY);
2085 #endif
2086     ADD_INT(REG_OPTION_RESERVED);
2087     ADD_INT(REG_OPTION_NON_VOLATILE);
2088     ADD_INT(REG_OPTION_VOLATILE);
2089     ADD_INT(REG_OPTION_CREATE_LINK);
2090     ADD_INT(REG_OPTION_BACKUP_RESTORE);
2091     ADD_INT(REG_OPTION_OPEN_LINK);
2092     ADD_INT(REG_LEGAL_OPTION);
2093     ADD_INT(REG_CREATED_NEW_KEY);
2094     ADD_INT(REG_OPENED_EXISTING_KEY);
2095     ADD_INT(REG_WHOLE_HIVE_VOLATILE);
2096     ADD_INT(REG_REFRESH_HIVE);
2097     ADD_INT(REG_NO_LAZY_FLUSH);
2098     ADD_INT(REG_NOTIFY_CHANGE_NAME);
2099     ADD_INT(REG_NOTIFY_CHANGE_ATTRIBUTES);
2100     ADD_INT(REG_NOTIFY_CHANGE_LAST_SET);
2101     ADD_INT(REG_NOTIFY_CHANGE_SECURITY);
2102     ADD_INT(REG_LEGAL_CHANGE_FILTER);
2103     ADD_INT(REG_NONE);
2104     ADD_INT(REG_SZ);
2105     ADD_INT(REG_EXPAND_SZ);
2106     ADD_INT(REG_BINARY);
2107     ADD_INT(REG_DWORD);
2108     ADD_INT(REG_DWORD_LITTLE_ENDIAN);
2109     ADD_INT(REG_DWORD_BIG_ENDIAN);
2110     ADD_INT(REG_QWORD);
2111     ADD_INT(REG_QWORD_LITTLE_ENDIAN);
2112     ADD_INT(REG_LINK);
2113     ADD_INT(REG_MULTI_SZ);
2114     ADD_INT(REG_RESOURCE_LIST);
2115     ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR);
2116     ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST);
2117     return m;
2118 }
2119 
2120 
2121