123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223 |
- /*
- winreg.c
- Windows Registry access module for Python.
- * Simple registry access written by Mark Hammond in win32api
- module circa 1995.
- * Bill Tutt expanded the support significantly not long after.
- * Numerous other people have submitted patches since then.
- * Ripped from win32api module 03-Feb-2000 by Mark Hammond, and
- basic Unicode support added.
- */
- #define PY_SSIZE_T_CLEAN
- #include "Python.h"
- #include "pycore_object.h" // _PyObject_Init()
- #include "pycore_moduleobject.h"
- #include "structmember.h" // PyMemberDef
- #include <windows.h>
- #if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)
- typedef struct {
- PyTypeObject *PyHKEY_Type;
- } winreg_state;
- /* Forward declares */
- static BOOL PyHKEY_AsHKEY(winreg_state *st, PyObject *ob, HKEY *pRes, BOOL bNoneOK);
- static BOOL clinic_HKEY_converter(winreg_state *st, PyObject *ob, void *p);
- static PyObject *PyHKEY_FromHKEY(winreg_state *st, HKEY h);
- static BOOL PyHKEY_Close(winreg_state *st, PyObject *obHandle);
- static char errNotAHandle[] = "Object is not a handle";
- /* The win32api module reports the function name that failed,
- but this concept is not in the Python core.
- Hopefully it will one day, and in the meantime I don't
- want to lose this info...
- */
- #define PyErr_SetFromWindowsErrWithFunction(rc, fnname) \
- PyErr_SetFromWindowsErr(rc)
- /* Doc strings */
- PyDoc_STRVAR(module_doc,
- "This module provides access to the Windows registry API.\n"
- "\n"
- "Functions:\n"
- "\n"
- "CloseKey() - Closes a registry key.\n"
- "ConnectRegistry() - Establishes a connection to a predefined registry handle\n"
- " on another computer.\n"
- "CreateKey() - Creates the specified key, or opens it if it already exists.\n"
- "DeleteKey() - Deletes the specified key.\n"
- "DeleteValue() - Removes a named value from the specified registry key.\n"
- "EnumKey() - Enumerates subkeys of the specified open registry key.\n"
- "EnumValue() - Enumerates values of the specified open registry key.\n"
- "ExpandEnvironmentStrings() - Expand the env strings in a REG_EXPAND_SZ\n"
- " string.\n"
- "FlushKey() - Writes all the attributes of the specified key to the registry.\n"
- "LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and\n"
- " stores registration information from a specified file into that\n"
- " subkey.\n"
- "OpenKey() - Opens the specified key.\n"
- "OpenKeyEx() - Alias of OpenKey().\n"
- "QueryValue() - Retrieves the value associated with the unnamed value for a\n"
- " specified key in the registry.\n"
- "QueryValueEx() - Retrieves the type and data for a specified value name\n"
- " associated with an open registry key.\n"
- "QueryInfoKey() - Returns information about the specified key.\n"
- "SaveKey() - Saves the specified key, and all its subkeys a file.\n"
- "SetValue() - Associates a value with a specified key.\n"
- "SetValueEx() - Stores data in the value field of an open registry key.\n"
- "\n"
- "Special objects:\n"
- "\n"
- "HKEYType -- type object for HKEY objects\n"
- "error -- exception raised for Win32 errors\n"
- "\n"
- "Integer constants:\n"
- "Many constants are defined - see the documentation for each function\n"
- "to see what constants are used, and where.");
- /* PyHKEY docstrings */
- PyDoc_STRVAR(PyHKEY_doc,
- "PyHKEY Object - A Python object, representing a win32 registry key.\n"
- "\n"
- "This object wraps a Windows HKEY object, automatically closing it when\n"
- "the object is destroyed. To guarantee cleanup, you can call either\n"
- "the Close() method on the PyHKEY, or the CloseKey() method.\n"
- "\n"
- "All functions which accept a handle object also accept an integer --\n"
- "however, use of the handle object is encouraged.\n"
- "\n"
- "Functions:\n"
- "Close() - Closes the underlying handle.\n"
- "Detach() - Returns the integer Win32 handle, detaching it from the object\n"
- "\n"
- "Properties:\n"
- "handle - The integer Win32 handle.\n"
- "\n"
- "Operations:\n"
- "__bool__ - Handles with an open object return true, otherwise false.\n"
- "__int__ - Converting a handle to an integer returns the Win32 handle.\n"
- "rich comparison - Handle objects are compared using the handle value.");
- /************************************************************************
- The PyHKEY object definition
- ************************************************************************/
- typedef struct {
- PyObject_VAR_HEAD
- HKEY hkey;
- } PyHKEYObject;
- #define PyHKEY_Check(st, op) Py_IS_TYPE(op, st->PyHKEY_Type)
- static char *failMsg = "bad operand type";
- static PyObject *
- PyHKEY_unaryFailureFunc(PyObject *ob)
- {
- PyErr_SetString(PyExc_TypeError, failMsg);
- return NULL;
- }
- static PyObject *
- PyHKEY_binaryFailureFunc(PyObject *ob1, PyObject *ob2)
- {
- PyErr_SetString(PyExc_TypeError, failMsg);
- return NULL;
- }
- static PyObject *
- PyHKEY_ternaryFailureFunc(PyObject *ob1, PyObject *ob2, PyObject *ob3)
- {
- PyErr_SetString(PyExc_TypeError, failMsg);
- return NULL;
- }
- static void
- PyHKEY_deallocFunc(PyObject *ob)
- {
- /* Can not call PyHKEY_Close, as the ob->tp_type
- has already been cleared, thus causing the type
- check to fail!
- */
- PyHKEYObject *obkey = (PyHKEYObject *)ob;
- if (obkey->hkey)
- RegCloseKey((HKEY)obkey->hkey);
- PyTypeObject *tp = Py_TYPE(ob);
- PyObject_GC_UnTrack(ob);
- PyObject_GC_Del(ob);
- Py_DECREF(tp);
- }
- static int
- PyHKEY_traverseFunc(PyHKEYObject *self, visitproc visit, void *arg)
- {
- Py_VISIT(Py_TYPE(self));
- return 0;
- }
- static int
- PyHKEY_boolFunc(PyObject *ob)
- {
- return ((PyHKEYObject *)ob)->hkey != 0;
- }
- static PyObject *
- PyHKEY_intFunc(PyObject *ob)
- {
- PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
- return PyLong_FromVoidPtr(pyhkey->hkey);
- }
- static PyObject *
- PyHKEY_strFunc(PyObject *ob)
- {
- PyHKEYObject *pyhkey = (PyHKEYObject *)ob;
- return PyUnicode_FromFormat("<PyHKEY:%p>", pyhkey->hkey);
- }
- static int
- PyHKEY_compareFunc(PyObject *ob1, PyObject *ob2)
- {
- PyHKEYObject *pyhkey1 = (PyHKEYObject *)ob1;
- PyHKEYObject *pyhkey2 = (PyHKEYObject *)ob2;
- return pyhkey1 == pyhkey2 ? 0 :
- (pyhkey1 < pyhkey2 ? -1 : 1);
- }
- static Py_hash_t
- PyHKEY_hashFunc(PyObject *ob)
- {
- /* Just use the address.
- XXX - should we use the handle value?
- */
- return _Py_HashPointer(ob);
- }
- /*[clinic input]
- module winreg
- class winreg.HKEYType "PyHKEYObject *" "&PyHKEY_Type"
- [clinic start generated code]*/
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=4c964eba3bf914d6]*/
- /*[python input]
- class REGSAM_converter(int_converter):
- type = 'REGSAM'
- class DWORD_converter(unsigned_long_converter):
- type = 'DWORD'
- class HKEY_converter(CConverter):
- type = 'HKEY'
- converter = 'clinic_HKEY_converter'
- def parse_arg(self, argname, displayname):
- return """
- if (!{converter}(_PyModule_GetState(module), {argname}, &{paramname})) {{{{
- goto exit;
- }}}}
- """.format(argname=argname, paramname=self.parser_name,
- converter=self.converter)
- class HKEY_return_converter(CReturnConverter):
- type = 'HKEY'
- def render(self, function, data):
- self.declare(data)
- self.err_occurred_if_null_pointer("_return_value", data)
- data.return_conversion.append(
- 'return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value);\n')
- # HACK: this only works for PyHKEYObjects, nothing else.
- # Should this be generalized and enshrined in clinic.py,
- # destroy this converter with prejudice.
- class self_return_converter(CReturnConverter):
- type = 'PyHKEYObject *'
- def render(self, function, data):
- self.declare(data)
- data.return_conversion.append(
- 'return_value = (PyObject *)_return_value;\n')
- [python start generated code]*/
- /*[python end generated code: output=da39a3ee5e6b4b0d input=17e645060c7b8ae1]*/
- #include "clinic/winreg.c.h"
- /************************************************************************
- The PyHKEY object methods
- ************************************************************************/
- /*[clinic input]
- winreg.HKEYType.Close
- Closes the underlying Windows handle.
- If the handle is already closed, no error is raised.
- [clinic start generated code]*/
- static PyObject *
- winreg_HKEYType_Close_impl(PyHKEYObject *self)
- /*[clinic end generated code: output=fced3a624fb0c344 input=6786ac75f6b89de6]*/
- {
- winreg_state *st = _PyType_GetModuleState(Py_TYPE(self));
- assert(st != NULL);
- if (!PyHKEY_Close(st, (PyObject *)self)) {
- return NULL;
- }
- Py_RETURN_NONE;
- }
- /*[clinic input]
- winreg.HKEYType.Detach
- Detaches the Windows handle from the handle object.
- The result is the value of the handle before it is detached. If the
- handle is already detached, this will return zero.
- After calling this function, the handle is effectively invalidated,
- but the handle is not closed. You would call this function when you
- need the underlying win32 handle to exist beyond the lifetime of the
- handle object.
- [clinic start generated code]*/
- static PyObject *
- winreg_HKEYType_Detach_impl(PyHKEYObject *self)
- /*[clinic end generated code: output=dda5a9e1a01ae78f input=dd2cc09e6c6ba833]*/
- {
- void* ret;
- if (PySys_Audit("winreg.PyHKEY.Detach", "n", (Py_ssize_t)self->hkey) < 0) {
- return NULL;
- }
- ret = (void*)self->hkey;
- self->hkey = 0;
- return PyLong_FromVoidPtr(ret);
- }
- /*[clinic input]
- winreg.HKEYType.__enter__ -> self
- [clinic start generated code]*/
- static PyHKEYObject *
- winreg_HKEYType___enter___impl(PyHKEYObject *self)
- /*[clinic end generated code: output=52c34986dab28990 input=c40fab1f0690a8e2]*/
- {
- return (PyHKEYObject*)Py_XNewRef(self);
- }
- /*[clinic input]
- winreg.HKEYType.__exit__
- exc_type: object
- exc_value: object
- traceback: object
- [clinic start generated code]*/
- static PyObject *
- winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type,
- PyObject *exc_value, PyObject *traceback)
- /*[clinic end generated code: output=923ebe7389e6a263 input=fb32489ee92403c7]*/
- {
- winreg_state *st = _PyType_GetModuleState(Py_TYPE(self));
- assert(st != NULL);
- if (!PyHKEY_Close(st, (PyObject *)self)) {
- return NULL;
- }
- Py_RETURN_NONE;
- }
- /*[clinic input]
- [clinic start generated code]*/
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=da39a3ee5e6b4b0d]*/
- static struct PyMethodDef PyHKEY_methods[] = {
- WINREG_HKEYTYPE_CLOSE_METHODDEF
- WINREG_HKEYTYPE_DETACH_METHODDEF
- WINREG_HKEYTYPE___ENTER___METHODDEF
- WINREG_HKEYTYPE___EXIT___METHODDEF
- {NULL}
- };
- #define OFF(e) offsetof(PyHKEYObject, e)
- static PyMemberDef PyHKEY_memberlist[] = {
- {"handle", T_INT, OFF(hkey), READONLY},
- {NULL} /* Sentinel */
- };
- static PyType_Slot pyhkey_type_slots[] = {
- {Py_tp_dealloc, PyHKEY_deallocFunc},
- {Py_tp_members, PyHKEY_memberlist},
- {Py_tp_methods, PyHKEY_methods},
- {Py_tp_doc, (char *)PyHKEY_doc},
- {Py_tp_traverse, PyHKEY_traverseFunc},
- {Py_tp_hash, PyHKEY_hashFunc},
- {Py_tp_str, PyHKEY_strFunc},
- // Number protocol
- {Py_nb_add, PyHKEY_binaryFailureFunc},
- {Py_nb_subtract, PyHKEY_binaryFailureFunc},
- {Py_nb_multiply, PyHKEY_binaryFailureFunc},
- {Py_nb_remainder, PyHKEY_binaryFailureFunc},
- {Py_nb_divmod, PyHKEY_binaryFailureFunc},
- {Py_nb_power, PyHKEY_ternaryFailureFunc},
- {Py_nb_negative, PyHKEY_unaryFailureFunc},
- {Py_nb_positive, PyHKEY_unaryFailureFunc},
- {Py_nb_absolute, PyHKEY_unaryFailureFunc},
- {Py_nb_bool, PyHKEY_boolFunc},
- {Py_nb_invert, PyHKEY_unaryFailureFunc},
- {Py_nb_lshift, PyHKEY_binaryFailureFunc},
- {Py_nb_rshift, PyHKEY_binaryFailureFunc},
- {Py_nb_and, PyHKEY_binaryFailureFunc},
- {Py_nb_xor, PyHKEY_binaryFailureFunc},
- {Py_nb_or, PyHKEY_binaryFailureFunc},
- {Py_nb_int, PyHKEY_intFunc},
- {Py_nb_float, PyHKEY_unaryFailureFunc},
- {0, NULL},
- };
- static PyType_Spec pyhkey_type_spec = {
- .name = "winreg.PyHKEY",
- .basicsize = sizeof(PyHKEYObject),
- .flags = (Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE |
- Py_TPFLAGS_DISALLOW_INSTANTIATION),
- .slots = pyhkey_type_slots,
- };
- /************************************************************************
- The public PyHKEY API (well, not public yet :-)
- ************************************************************************/
- PyObject *
- PyHKEY_New(PyObject *m, HKEY hInit)
- {
- winreg_state *st = _PyModule_GetState(m);
- PyHKEYObject *key = PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type);
- if (key == NULL) {
- return NULL;
- }
- key->hkey = hInit;
- PyObject_GC_Track(key);
- return (PyObject *)key;
- }
- BOOL
- PyHKEY_Close(winreg_state *st, PyObject *ob_handle)
- {
- LONG rc;
- HKEY key;
- if (!PyHKEY_AsHKEY(st, ob_handle, &key, TRUE)) {
- return FALSE;
- }
- if (PyHKEY_Check(st, ob_handle)) {
- ((PyHKEYObject*)ob_handle)->hkey = 0;
- }
- rc = key ? RegCloseKey(key) : ERROR_SUCCESS;
- if (rc != ERROR_SUCCESS)
- PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
- return rc == ERROR_SUCCESS;
- }
- BOOL
- PyHKEY_AsHKEY(winreg_state *st, PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK)
- {
- if (ob == Py_None) {
- if (!bNoneOK) {
- PyErr_SetString(
- PyExc_TypeError,
- "None is not a valid HKEY in this context");
- return FALSE;
- }
- *pHANDLE = (HKEY)0;
- }
- else if (PyHKEY_Check(st ,ob)) {
- PyHKEYObject *pH = (PyHKEYObject *)ob;
- *pHANDLE = pH->hkey;
- }
- else if (PyLong_Check(ob)) {
- /* We also support integers */
- PyErr_Clear();
- *pHANDLE = (HKEY)PyLong_AsVoidPtr(ob);
- if (PyErr_Occurred())
- return FALSE;
- }
- else {
- PyErr_SetString(
- PyExc_TypeError,
- "The object is not a PyHKEY object");
- return FALSE;
- }
- return TRUE;
- }
- BOOL
- clinic_HKEY_converter(winreg_state *st, PyObject *ob, void *p)
- {
- if (!PyHKEY_AsHKEY(st, ob, (HKEY *)p, FALSE)) {
- return FALSE;
- }
- return TRUE;
- }
- PyObject *
- PyHKEY_FromHKEY(winreg_state *st, HKEY h)
- {
- PyHKEYObject *op = (PyHKEYObject *)PyObject_GC_New(PyHKEYObject,
- st->PyHKEY_Type);
- if (op == NULL) {
- return NULL;
- }
- op->hkey = h;
- PyObject_GC_Track(op);
- return (PyObject *)op;
- }
- /************************************************************************
- The module methods
- ************************************************************************/
- BOOL
- PyWinObject_CloseHKEY(winreg_state *st, PyObject *obHandle)
- {
- BOOL ok;
- if (PyHKEY_Check(st, obHandle)) {
- ok = PyHKEY_Close(st, obHandle);
- }
- #if SIZEOF_LONG >= SIZEOF_HKEY
- else if (PyLong_Check(obHandle)) {
- long rc = RegCloseKey((HKEY)PyLong_AsLong(obHandle));
- ok = (rc == ERROR_SUCCESS);
- if (!ok)
- PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
- }
- #else
- else if (PyLong_Check(obHandle)) {
- long rc = RegCloseKey((HKEY)PyLong_AsVoidPtr(obHandle));
- ok = (rc == ERROR_SUCCESS);
- if (!ok)
- PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
- }
- #endif
- else {
- PyErr_SetString(
- PyExc_TypeError,
- "A handle must be a HKEY object or an integer");
- return FALSE;
- }
- return ok;
- }
- /*
- Private Helper functions for the registry interfaces
- ** Note that fixupMultiSZ and countString have both had changes
- ** made to support "incorrect strings". The registry specification
- ** calls for strings to be terminated with 2 null bytes. It seems
- ** some commercial packages install strings which don't conform,
- ** causing this code to fail - however, "regedit" etc still work
- ** with these strings (ie only we don't!).
- */
- static void
- fixupMultiSZ(wchar_t **str, wchar_t *data, int len)
- {
- wchar_t *P;
- int i;
- wchar_t *Q;
- if (len > 0 && data[len - 1] == '\0') {
- Q = data + len - 1;
- }
- else {
- Q = data + len;
- }
- for (P = data, i = 0; P < Q; P++, i++) {
- str[i] = P;
- for (; P < Q && *P != '\0'; P++) {
- ;
- }
- }
- }
- static int
- countStrings(wchar_t *data, int len)
- {
- int strings;
- wchar_t *P, *Q;
- if (len > 0 && data[len - 1] == '\0') {
- Q = data + len - 1;
- }
- else {
- Q = data + len;
- }
- for (P = data, strings = 0; P < Q; P++, strings++) {
- for (; P < Q && *P != '\0'; P++) {
- ;
- }
- }
- return strings;
- }
- /* Convert PyObject into Registry data.
- Allocates space as needed. */
- static BOOL
- Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
- {
- Py_ssize_t i,j;
- switch (typ) {
- case REG_DWORD:
- {
- if (value != Py_None && !PyLong_Check(value)) {
- return FALSE;
- }
- DWORD d;
- if (value == Py_None) {
- d = 0;
- }
- else if (PyLong_Check(value)) {
- d = PyLong_AsUnsignedLong(value);
- if (d == (DWORD)(-1) && PyErr_Occurred()) {
- return FALSE;
- }
- }
- *retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1);
- if (*retDataBuf == NULL) {
- PyErr_NoMemory();
- return FALSE;
- }
- memcpy(*retDataBuf, &d, sizeof(DWORD));
- *retDataSize = sizeof(DWORD);
- break;
- }
- case REG_QWORD:
- {
- if (value != Py_None && !PyLong_Check(value)) {
- return FALSE;
- }
- DWORD64 d;
- if (value == Py_None) {
- d = 0;
- }
- else if (PyLong_Check(value)) {
- d = PyLong_AsUnsignedLongLong(value);
- if (d == (DWORD64)(-1) && PyErr_Occurred()) {
- return FALSE;
- }
- }
- *retDataBuf = (BYTE *)PyMem_NEW(DWORD64, 1);
- if (*retDataBuf == NULL) {
- PyErr_NoMemory();
- return FALSE;
- }
- memcpy(*retDataBuf, &d, sizeof(DWORD64));
- *retDataSize = sizeof(DWORD64);
- break;
- }
- case REG_SZ:
- case REG_EXPAND_SZ:
- {
- if (value != Py_None) {
- Py_ssize_t len;
- if (!PyUnicode_Check(value))
- return FALSE;
- *retDataBuf = (BYTE*)PyUnicode_AsWideCharString(value, &len);
- if (*retDataBuf == NULL)
- return FALSE;
- *retDataSize = Py_SAFE_DOWNCAST(
- (len + 1) * sizeof(wchar_t),
- Py_ssize_t, DWORD);
- }
- else {
- *retDataBuf = (BYTE *)PyMem_NEW(wchar_t, 1);
- if (*retDataBuf == NULL) {
- PyErr_NoMemory();
- return FALSE;
- }
- ((wchar_t *)*retDataBuf)[0] = L'\0';
- *retDataSize = 1 * sizeof(wchar_t);
- }
- break;
- }
- case REG_MULTI_SZ:
- {
- DWORD size = 0;
- wchar_t *P;
- if (value == Py_None)
- i = 0;
- else {
- if (!PyList_Check(value))
- return FALSE;
- i = PyList_Size(value);
- }
- for (j = 0; j < i; j++)
- {
- PyObject *t;
- Py_ssize_t len;
- t = PyList_GET_ITEM(value, j);
- if (!PyUnicode_Check(t))
- return FALSE;
- len = PyUnicode_AsWideChar(t, NULL, 0);
- if (len < 0)
- return FALSE;
- size += Py_SAFE_DOWNCAST(len * sizeof(wchar_t),
- size_t, DWORD);
- }
- *retDataSize = size + 2;
- *retDataBuf = (BYTE *)PyMem_NEW(char,
- *retDataSize);
- if (*retDataBuf == NULL){
- PyErr_NoMemory();
- return FALSE;
- }
- P = (wchar_t *)*retDataBuf;
- for (j = 0; j < i; j++)
- {
- PyObject *t;
- Py_ssize_t len;
- t = PyList_GET_ITEM(value, j);
- assert(size > 0);
- len = PyUnicode_AsWideChar(t, P, size);
- assert(len >= 0);
- assert((unsigned)len < size);
- size -= (DWORD)len + 1;
- P += len + 1;
- }
- /* And doubly-terminate the list... */
- *P = L'\0';
- break;
- }
- case REG_BINARY:
- /* ALSO handle ALL unknown data types here. Even if we can't
- support it natively, we should handle the bits. */
- default:
- if (value == Py_None) {
- *retDataSize = 0;
- *retDataBuf = NULL;
- }
- else {
- Py_buffer view;
- if (!PyObject_CheckBuffer(value)) {
- PyErr_Format(PyExc_TypeError,
- "Objects of type '%s' can not "
- "be used as binary registry values",
- Py_TYPE(value)->tp_name);
- return FALSE;
- }
- if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
- return FALSE;
- *retDataBuf = (BYTE *)PyMem_NEW(char, view.len);
- if (*retDataBuf == NULL){
- PyBuffer_Release(&view);
- PyErr_NoMemory();
- return FALSE;
- }
- *retDataSize = Py_SAFE_DOWNCAST(view.len, Py_ssize_t, DWORD);
- memcpy(*retDataBuf, view.buf, view.len);
- PyBuffer_Release(&view);
- }
- break;
- }
- return TRUE;
- }
- /* Convert Registry data into PyObject*/
- static PyObject *
- Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ)
- {
- PyObject *obData;
- switch (typ) {
- case REG_DWORD:
- if (retDataSize == 0)
- obData = PyLong_FromUnsignedLong(0);
- else
- obData = PyLong_FromUnsignedLong(*(DWORD *)retDataBuf);
- break;
- case REG_QWORD:
- if (retDataSize == 0)
- obData = PyLong_FromUnsignedLongLong(0);
- else
- obData = PyLong_FromUnsignedLongLong(*(DWORD64 *)retDataBuf);
- break;
- case REG_SZ:
- case REG_EXPAND_SZ:
- {
- /* REG_SZ should be a NUL terminated string, but only by
- * convention. The buffer may have been saved without a NUL
- * or with embedded NULs. To be consistent with reg.exe and
- * regedit.exe, consume only up to the first NUL. */
- wchar_t *data = (wchar_t *)retDataBuf;
- size_t len = wcsnlen(data, retDataSize / sizeof(wchar_t));
- obData = PyUnicode_FromWideChar(data, len);
- break;
- }
- case REG_MULTI_SZ:
- if (retDataSize == 0)
- obData = PyList_New(0);
- else
- {
- int index = 0;
- wchar_t *data = (wchar_t *)retDataBuf;
- int len = retDataSize / 2;
- int s = countStrings(data, len);
- wchar_t **str = PyMem_New(wchar_t *, s);
- if (str == NULL)
- return PyErr_NoMemory();
- fixupMultiSZ(str, data, len);
- obData = PyList_New(s);
- if (obData == NULL) {
- PyMem_Free(str);
- return NULL;
- }
- for (index = 0; index < s; index++)
- {
- size_t slen = wcsnlen(str[index], len);
- PyObject *uni = PyUnicode_FromWideChar(str[index], slen);
- if (uni == NULL) {
- Py_DECREF(obData);
- PyMem_Free(str);
- return NULL;
- }
- PyList_SET_ITEM(obData, index, uni);
- len -= Py_SAFE_DOWNCAST(slen + 1, size_t, int);
- }
- PyMem_Free(str);
- break;
- }
- case REG_BINARY:
- /* ALSO handle ALL unknown data types here. Even if we can't
- support it natively, we should handle the bits. */
- default:
- if (retDataSize == 0) {
- obData = Py_NewRef(Py_None);
- }
- else
- obData = PyBytes_FromStringAndSize(
- (char *)retDataBuf, retDataSize);
- break;
- }
- return obData;
- }
- /* The Python methods */
- /*[clinic input]
- winreg.CloseKey
- hkey: object
- A previously opened key.
- /
- Closes a previously opened registry key.
- Note that if the key is not closed using this method, it will be
- closed when the hkey object is destroyed by Python.
- [clinic start generated code]*/
- static PyObject *
- winreg_CloseKey(PyObject *module, PyObject *hkey)
- /*[clinic end generated code: output=a4fa537019a80d15 input=5b1aac65ba5127ad]*/
- {
- if (!PyHKEY_Close(_PyModule_GetState(module), hkey)) {
- return NULL;
- }
- Py_RETURN_NONE;
- }
- #if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
- /*[clinic input]
- winreg.ConnectRegistry -> HKEY
- computer_name: Py_UNICODE(accept={str, NoneType})
- The name of the remote computer, of the form r"\\computername". If
- None, the local computer is used.
- key: HKEY
- The predefined key to connect to.
- /
- Establishes a connection to the registry on another computer.
- The return value is the handle of the opened key.
- If the function fails, an OSError exception is raised.
- [clinic start generated code]*/
- static HKEY
- winreg_ConnectRegistry_impl(PyObject *module,
- const Py_UNICODE *computer_name, HKEY key)
- /*[clinic end generated code: output=cd4f70fb9ec901fb input=5f98a891a347e68e]*/
- {
- HKEY retKey;
- long rc;
- if (PySys_Audit("winreg.ConnectRegistry", "un",
- computer_name, (Py_ssize_t)key) < 0) {
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = RegConnectRegistryW(computer_name, key, &retKey);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS) {
- PyErr_SetFromWindowsErrWithFunction(rc, "ConnectRegistry");
- return NULL;
- }
- return retKey;
- }
- #endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */
- /*[clinic input]
- winreg.CreateKey -> HKEY
- key: HKEY
- An already open key, or one of the predefined HKEY_* constants.
- sub_key: Py_UNICODE(accept={str, NoneType})
- The name of the key this method opens or creates.
- /
- Creates or opens the specified key.
- If key is one of the predefined keys, sub_key may be None. In that case,
- the handle returned is the same key handle passed in to the function.
- If the key already exists, this function opens the existing key.
- The return value is the handle of the opened key.
- If the function fails, an OSError exception is raised.
- [clinic start generated code]*/
- static HKEY
- winreg_CreateKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
- /*[clinic end generated code: output=2af13910d56eae26 input=3cdd1622488acea2]*/
- {
- HKEY retKey;
- long rc;
- if (PySys_Audit("winreg.CreateKey", "nun",
- (Py_ssize_t)key, sub_key,
- (Py_ssize_t)KEY_WRITE) < 0) {
- return NULL;
- }
- rc = RegCreateKeyW(key, sub_key, &retKey);
- if (rc != ERROR_SUCCESS) {
- PyErr_SetFromWindowsErrWithFunction(rc, "CreateKey");
- return NULL;
- }
- if (PySys_Audit("winreg.OpenKey/result", "n",
- (Py_ssize_t)retKey) < 0) {
- return NULL;
- }
- return retKey;
- }
- /*[clinic input]
- winreg.CreateKeyEx -> HKEY
- key: HKEY
- An already open key, or one of the predefined HKEY_* constants.
- sub_key: Py_UNICODE(accept={str, NoneType})
- The name of the key this method opens or creates.
- reserved: int = 0
- A reserved integer, and must be zero. Default is zero.
- access: REGSAM(c_default='KEY_WRITE') = winreg.KEY_WRITE
- An integer that specifies an access mask that describes the
- desired security access for the key. Default is KEY_WRITE.
- Creates or opens the specified key.
- If key is one of the predefined keys, sub_key may be None. In that case,
- the handle returned is the same key handle passed in to the function.
- If the key already exists, this function opens the existing key
- The return value is the handle of the opened key.
- If the function fails, an OSError exception is raised.
- [clinic start generated code]*/
- static HKEY
- winreg_CreateKeyEx_impl(PyObject *module, HKEY key,
- const Py_UNICODE *sub_key, int reserved,
- REGSAM access)
- /*[clinic end generated code: output=643a70ad6a361a97 input=42c2b03f98406b66]*/
- {
- HKEY retKey;
- long rc;
- if (PySys_Audit("winreg.CreateKey", "nun",
- (Py_ssize_t)key, sub_key,
- (Py_ssize_t)access) < 0) {
- return NULL;
- }
- rc = RegCreateKeyExW(key, sub_key, reserved, NULL, 0,
- access, NULL, &retKey, NULL);
- if (rc != ERROR_SUCCESS) {
- PyErr_SetFromWindowsErrWithFunction(rc, "CreateKeyEx");
- return NULL;
- }
- if (PySys_Audit("winreg.OpenKey/result", "n",
- (Py_ssize_t)retKey) < 0) {
- return NULL;
- }
- return retKey;
- }
- /*[clinic input]
- winreg.DeleteKey
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- sub_key: Py_UNICODE
- A string that must be the name of a subkey of the key identified by
- the key parameter. This value must not be None, and the key may not
- have subkeys.
- /
- Deletes the specified key.
- This method can not delete keys with subkeys.
- If the function succeeds, the entire key, including all of its values,
- is removed. If the function fails, an OSError exception is raised.
- [clinic start generated code]*/
- static PyObject *
- winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
- /*[clinic end generated code: output=d2652a84f70e0862 input=b31d225b935e4211]*/
- {
- long rc;
- if (PySys_Audit("winreg.DeleteKey", "nun",
- (Py_ssize_t)key, sub_key,
- (Py_ssize_t)0) < 0) {
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = RegDeleteKeyW(key, sub_key);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey");
- Py_RETURN_NONE;
- }
- /*[clinic input]
- winreg.DeleteKeyEx
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- sub_key: Py_UNICODE
- A string that must be the name of a subkey of the key identified by
- the key parameter. This value must not be None, and the key may not
- have subkeys.
- access: REGSAM(c_default='KEY_WOW64_64KEY') = winreg.KEY_WOW64_64KEY
- An integer that specifies an access mask that describes the
- desired security access for the key. Default is KEY_WOW64_64KEY.
- reserved: int = 0
- A reserved integer, and must be zero. Default is zero.
- Deletes the specified key (intended for 64-bit OS).
- While this function is intended to be used for 64-bit OS, it is also
- available on 32-bit systems.
- This method can not delete keys with subkeys.
- If the function succeeds, the entire key, including all of its values,
- is removed. If the function fails, an OSError exception is raised.
- On unsupported Windows versions, NotImplementedError is raised.
- [clinic start generated code]*/
- static PyObject *
- winreg_DeleteKeyEx_impl(PyObject *module, HKEY key,
- const Py_UNICODE *sub_key, REGSAM access,
- int reserved)
- /*[clinic end generated code: output=52a1c8b374ebc003 input=a3186db079b3bf85]*/
- {
- long rc;
- if (PySys_Audit("winreg.DeleteKey", "nun",
- (Py_ssize_t)key, sub_key,
- (Py_ssize_t)access) < 0) {
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = RegDeleteKeyExW(key, sub_key, access, reserved);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKeyEx");
- Py_RETURN_NONE;
- }
- /*[clinic input]
- winreg.DeleteValue
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- value: Py_UNICODE(accept={str, NoneType})
- A string that identifies the value to remove.
- /
- Removes a named value from a registry key.
- [clinic start generated code]*/
- static PyObject *
- winreg_DeleteValue_impl(PyObject *module, HKEY key, const Py_UNICODE *value)
- /*[clinic end generated code: output=56fa9d21f3a54371 input=a78d3407a4197b21]*/
- {
- long rc;
- if (PySys_Audit("winreg.DeleteValue", "nu",
- (Py_ssize_t)key, value) < 0) {
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = RegDeleteValueW(key, value);
- Py_END_ALLOW_THREADS
- if (rc !=ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc,
- "RegDeleteValue");
- Py_RETURN_NONE;
- }
- /*[clinic input]
- winreg.EnumKey
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- index: int
- An integer that identifies the index of the key to retrieve.
- /
- Enumerates subkeys of an open registry key.
- The function retrieves the name of one subkey each time it is called.
- It is typically called repeatedly until an OSError exception is
- raised, indicating no more values are available.
- [clinic start generated code]*/
- static PyObject *
- winreg_EnumKey_impl(PyObject *module, HKEY key, int index)
- /*[clinic end generated code: output=25a6ec52cd147bc4 input=fad9a7c00ab0e04b]*/
- {
- long rc;
- PyObject *retStr;
- if (PySys_Audit("winreg.EnumKey", "ni",
- (Py_ssize_t)key, index) < 0) {
- return NULL;
- }
- /* The Windows docs claim that the max key name length is 255
- * characters, plus a terminating nul character. However,
- * empirical testing demonstrates that it is possible to
- * create a 256 character key that is missing the terminating
- * nul. RegEnumKeyEx requires a 257 character buffer to
- * retrieve such a key name. */
- wchar_t tmpbuf[257];
- DWORD len = sizeof(tmpbuf)/sizeof(wchar_t); /* includes NULL terminator */
- Py_BEGIN_ALLOW_THREADS
- rc = RegEnumKeyExW(key, index, tmpbuf, &len, NULL, NULL, NULL, NULL);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc, "RegEnumKeyEx");
- retStr = PyUnicode_FromWideChar(tmpbuf, len);
- return retStr; /* can be NULL */
- }
- /*[clinic input]
- winreg.EnumValue
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- index: int
- An integer that identifies the index of the value to retrieve.
- /
- Enumerates values of an open registry key.
- The function retrieves the name of one subkey each time it is called.
- It is typically called repeatedly, until an OSError exception
- is raised, indicating no more values.
- The result is a tuple of 3 items:
- value_name
- A string that identifies the value.
- value_data
- An object that holds the value data, and whose type depends
- on the underlying registry type.
- data_type
- An integer that identifies the type of the value data.
- [clinic start generated code]*/
- static PyObject *
- winreg_EnumValue_impl(PyObject *module, HKEY key, int index)
- /*[clinic end generated code: output=d363b5a06f8789ac input=4414f47a6fb238b5]*/
- {
- long rc;
- wchar_t *retValueBuf;
- BYTE *tmpBuf;
- BYTE *retDataBuf;
- DWORD retValueSize, bufValueSize;
- DWORD retDataSize, bufDataSize;
- DWORD typ;
- PyObject *obData;
- PyObject *retVal;
- if (PySys_Audit("winreg.EnumValue", "ni",
- (Py_ssize_t)key, index) < 0) {
- return NULL;
- }
- if ((rc = RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL,
- &retValueSize, &retDataSize, NULL, NULL))
- != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc,
- "RegQueryInfoKey");
- ++retValueSize; /* include null terminators */
- ++retDataSize;
- bufDataSize = retDataSize;
- bufValueSize = retValueSize;
- retValueBuf = PyMem_New(wchar_t, retValueSize);
- if (retValueBuf == NULL)
- return PyErr_NoMemory();
- retDataBuf = (BYTE *)PyMem_Malloc(retDataSize);
- if (retDataBuf == NULL) {
- PyMem_Free(retValueBuf);
- return PyErr_NoMemory();
- }
- while (1) {
- Py_BEGIN_ALLOW_THREADS
- rc = RegEnumValueW(key,
- index,
- retValueBuf,
- &retValueSize,
- NULL,
- &typ,
- (BYTE *)retDataBuf,
- &retDataSize);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_MORE_DATA)
- break;
- bufDataSize *= 2;
- tmpBuf = (BYTE *)PyMem_Realloc(retDataBuf, bufDataSize);
- if (tmpBuf == NULL) {
- PyErr_NoMemory();
- retVal = NULL;
- goto fail;
- }
- retDataBuf = tmpBuf;
- retDataSize = bufDataSize;
- retValueSize = bufValueSize;
- }
- if (rc != ERROR_SUCCESS) {
- retVal = PyErr_SetFromWindowsErrWithFunction(rc,
- "PyRegEnumValue");
- goto fail;
- }
- obData = Reg2Py(retDataBuf, retDataSize, typ);
- if (obData == NULL) {
- retVal = NULL;
- goto fail;
- }
- retVal = Py_BuildValue("uOi", retValueBuf, obData, typ);
- Py_DECREF(obData);
- fail:
- PyMem_Free(retValueBuf);
- PyMem_Free(retDataBuf);
- return retVal;
- }
- /*[clinic input]
- winreg.ExpandEnvironmentStrings
- string: Py_UNICODE
- /
- Expand environment vars.
- [clinic start generated code]*/
- static PyObject *
- winreg_ExpandEnvironmentStrings_impl(PyObject *module,
- const Py_UNICODE *string)
- /*[clinic end generated code: output=8fa4e959747a7312 input=b2a9714d2b751aa6]*/
- {
- wchar_t *retValue = NULL;
- DWORD retValueSize;
- DWORD rc;
- PyObject *o;
- if (PySys_Audit("winreg.ExpandEnvironmentStrings", "u",
- string) < 0) {
- return NULL;
- }
- retValueSize = ExpandEnvironmentStringsW(string, retValue, 0);
- if (retValueSize == 0) {
- return PyErr_SetFromWindowsErrWithFunction(retValueSize,
- "ExpandEnvironmentStrings");
- }
- retValue = PyMem_New(wchar_t, retValueSize);
- if (retValue == NULL) {
- return PyErr_NoMemory();
- }
- rc = ExpandEnvironmentStringsW(string, retValue, retValueSize);
- if (rc == 0) {
- PyMem_Free(retValue);
- return PyErr_SetFromWindowsErrWithFunction(retValueSize,
- "ExpandEnvironmentStrings");
- }
- o = PyUnicode_FromWideChar(retValue, wcslen(retValue));
- PyMem_Free(retValue);
- return o;
- }
- #if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
- /*[clinic input]
- winreg.FlushKey
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- /
- Writes all the attributes of a key to the registry.
- It is not necessary to call FlushKey to change a key. Registry changes
- are flushed to disk by the registry using its lazy flusher. Registry
- changes are also flushed to disk at system shutdown. Unlike
- CloseKey(), the FlushKey() method returns only when all the data has
- been written to the registry.
- An application should only call FlushKey() if it requires absolute
- certainty that registry changes are on disk. If you don't know whether
- a FlushKey() call is required, it probably isn't.
- [clinic start generated code]*/
- static PyObject *
- winreg_FlushKey_impl(PyObject *module, HKEY key)
- /*[clinic end generated code: output=e6fc230d4c5dc049 input=f57457c12297d82f]*/
- {
- long rc;
- Py_BEGIN_ALLOW_THREADS
- rc = RegFlushKey(key);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc, "RegFlushKey");
- Py_RETURN_NONE;
- }
- #endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */
- #if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
- /*[clinic input]
- winreg.LoadKey
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- sub_key: Py_UNICODE
- A string that identifies the sub-key to load.
- file_name: Py_UNICODE
- The name of the file to load registry data from. This file must
- have been created with the SaveKey() function. Under the file
- allocation table (FAT) file system, the filename may not have an
- extension.
- /
- Insert data into the registry from a file.
- Creates a subkey under the specified key and stores registration
- information from a specified file into that subkey.
- A call to LoadKey() fails if the calling process does not have the
- SE_RESTORE_PRIVILEGE privilege.
- If key is a handle returned by ConnectRegistry(), then the path
- specified in fileName is relative to the remote computer.
- The MSDN docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE
- tree.
- [clinic start generated code]*/
- static PyObject *
- winreg_LoadKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
- const Py_UNICODE *file_name)
- /*[clinic end generated code: output=65f89f2548cb27c7 input=e3b5b45ade311582]*/
- {
- long rc;
- if (PySys_Audit("winreg.LoadKey", "nuu",
- (Py_ssize_t)key, sub_key, file_name) < 0) {
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = RegLoadKeyW(key, sub_key, file_name );
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc, "RegLoadKey");
- Py_RETURN_NONE;
- }
- #endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */
- /*[clinic input]
- winreg.OpenKey -> HKEY
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- sub_key: Py_UNICODE(accept={str, NoneType})
- A string that identifies the sub_key to open.
- reserved: int = 0
- A reserved integer that must be zero. Default is zero.
- access: REGSAM(c_default='KEY_READ') = winreg.KEY_READ
- An integer that specifies an access mask that describes the desired
- security access for the key. Default is KEY_READ.
- Opens the specified key.
- The result is a new handle to the specified key.
- If the function fails, an OSError exception is raised.
- [clinic start generated code]*/
- static HKEY
- winreg_OpenKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
- int reserved, REGSAM access)
- /*[clinic end generated code: output=8849bff2c30104ad input=098505ac36a9ae28]*/
- {
- HKEY retKey;
- long rc;
- if (PySys_Audit("winreg.OpenKey", "nun",
- (Py_ssize_t)key, sub_key,
- (Py_ssize_t)access) < 0) {
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = RegOpenKeyExW(key, sub_key, reserved, access, &retKey);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS) {
- PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx");
- return NULL;
- }
- if (PySys_Audit("winreg.OpenKey/result", "n",
- (Py_ssize_t)retKey) < 0) {
- return NULL;
- }
- return retKey;
- }
- /*[clinic input]
- winreg.OpenKeyEx = winreg.OpenKey
- Opens the specified key.
- The result is a new handle to the specified key.
- If the function fails, an OSError exception is raised.
- [clinic start generated code]*/
- static HKEY
- winreg_OpenKeyEx_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
- int reserved, REGSAM access)
- /*[clinic end generated code: output=81bc2bd684bc77ae input=c6c4972af8622959]*/
- {
- return winreg_OpenKey_impl(module, key, sub_key, reserved, access);
- }
- /*[clinic input]
- winreg.QueryInfoKey
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- /
- Returns information about a key.
- The result is a tuple of 3 items:
- An integer that identifies the number of sub keys this key has.
- An integer that identifies the number of values this key has.
- An integer that identifies when the key was last modified (if available)
- as 100's of nanoseconds since Jan 1, 1600.
- [clinic start generated code]*/
- static PyObject *
- winreg_QueryInfoKey_impl(PyObject *module, HKEY key)
- /*[clinic end generated code: output=dc657b8356a4f438 input=c3593802390cde1f]*/
- {
- long rc;
- DWORD nSubKeys, nValues;
- FILETIME ft;
- LARGE_INTEGER li;
- PyObject *l;
- PyObject *ret;
- if (PySys_Audit("winreg.QueryInfoKey", "n", (Py_ssize_t)key) < 0) {
- return NULL;
- }
- if ((rc = RegQueryInfoKeyW(key, NULL, NULL, 0, &nSubKeys, NULL, NULL,
- &nValues, NULL, NULL, NULL, &ft))
- != ERROR_SUCCESS) {
- return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryInfoKey");
- }
- li.LowPart = ft.dwLowDateTime;
- li.HighPart = ft.dwHighDateTime;
- l = PyLong_FromLongLong(li.QuadPart);
- if (l == NULL) {
- return NULL;
- }
- ret = Py_BuildValue("iiO", nSubKeys, nValues, l);
- Py_DECREF(l);
- return ret;
- }
- /*[clinic input]
- winreg.QueryValue
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- sub_key: Py_UNICODE(accept={str, NoneType})
- A string that holds the name of the subkey with which the value
- is associated. If this parameter is None or empty, the function
- retrieves the value set by the SetValue() method for the key
- identified by key.
- /
- Retrieves the unnamed value for a key.
- Values in the registry have name, type, and data components. This method
- retrieves the data for a key's first value that has a NULL name.
- But since the underlying API call doesn't return the type, you'll
- probably be happier using QueryValueEx; this function is just here for
- completeness.
- [clinic start generated code]*/
- static PyObject *
- winreg_QueryValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
- /*[clinic end generated code: output=c655810ae50c63a9 input=41cafbbf423b21d6]*/
- {
- LONG rc;
- HKEY childKey = key;
- WCHAR buf[256], *pbuf = buf;
- DWORD size = sizeof(buf);
- DWORD type;
- Py_ssize_t length;
- PyObject *result = NULL;
- if (PySys_Audit("winreg.QueryValue", "nuu",
- (Py_ssize_t)key, sub_key, NULL) < 0)
- {
- return NULL;
- }
- if (key == HKEY_PERFORMANCE_DATA) {
- return PyErr_SetFromWindowsErrWithFunction(ERROR_INVALID_HANDLE,
- "RegQueryValue");
- }
- if (sub_key && sub_key[0]) {
- Py_BEGIN_ALLOW_THREADS
- rc = RegOpenKeyExW(key, sub_key, 0, KEY_QUERY_VALUE, &childKey);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS) {
- return PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx");
- }
- }
- while (1) {
- Py_BEGIN_ALLOW_THREADS
- rc = RegQueryValueExW(childKey, NULL, NULL, &type, (LPBYTE)pbuf,
- &size);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_MORE_DATA) {
- break;
- }
- void *tmp = PyMem_Realloc(pbuf != buf ? pbuf : NULL, size);
- if (tmp == NULL) {
- PyErr_NoMemory();
- goto exit;
- }
- pbuf = tmp;
- }
- if (rc == ERROR_SUCCESS) {
- if (type != REG_SZ) {
- PyErr_SetFromWindowsErrWithFunction(ERROR_INVALID_DATA,
- "RegQueryValue");
- goto exit;
- }
- length = wcsnlen(pbuf, size / sizeof(WCHAR));
- }
- else if (rc == ERROR_FILE_NOT_FOUND) {
- // Return an empty string if there's no default value.
- length = 0;
- }
- else {
- PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValueEx");
- goto exit;
- }
- result = PyUnicode_FromWideChar(pbuf, length);
- exit:
- if (pbuf != buf) {
- PyMem_Free(pbuf);
- }
- if (childKey != key) {
- RegCloseKey(childKey);
- }
- return result;
- }
- /*[clinic input]
- winreg.QueryValueEx
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- name: Py_UNICODE(accept={str, NoneType})
- A string indicating the value to query.
- /
- Retrieves the type and value of a specified sub-key.
- Behaves mostly like QueryValue(), but also returns the type of the
- specified value name associated with the given open registry key.
- The return value is a tuple of the value and the type_id.
- [clinic start generated code]*/
- static PyObject *
- winreg_QueryValueEx_impl(PyObject *module, HKEY key, const Py_UNICODE *name)
- /*[clinic end generated code: output=f1b85b1c3d887ec7 input=cf366cada4836891]*/
- {
- long rc;
- BYTE *retBuf, *tmp;
- DWORD bufSize = 0, retSize;
- DWORD typ;
- PyObject *obData;
- PyObject *result;
- if (PySys_Audit("winreg.QueryValue", "nuu",
- (Py_ssize_t)key, NULL, name) < 0) {
- return NULL;
- }
- rc = RegQueryValueExW(key, name, NULL, NULL, NULL, &bufSize);
- if (rc == ERROR_MORE_DATA)
- bufSize = 256;
- else if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc,
- "RegQueryValueEx");
- retBuf = (BYTE *)PyMem_Malloc(bufSize);
- if (retBuf == NULL)
- return PyErr_NoMemory();
- while (1) {
- retSize = bufSize;
- rc = RegQueryValueExW(key, name, NULL, &typ,
- (BYTE *)retBuf, &retSize);
- if (rc != ERROR_MORE_DATA)
- break;
- bufSize *= 2;
- tmp = (char *) PyMem_Realloc(retBuf, bufSize);
- if (tmp == NULL) {
- PyMem_Free(retBuf);
- return PyErr_NoMemory();
- }
- retBuf = tmp;
- }
- if (rc != ERROR_SUCCESS) {
- PyMem_Free(retBuf);
- return PyErr_SetFromWindowsErrWithFunction(rc,
- "RegQueryValueEx");
- }
- obData = Reg2Py(retBuf, bufSize, typ);
- PyMem_Free(retBuf);
- if (obData == NULL)
- return NULL;
- result = Py_BuildValue("Oi", obData, typ);
- Py_DECREF(obData);
- return result;
- }
- #if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
- /*[clinic input]
- winreg.SaveKey
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- file_name: Py_UNICODE
- The name of the file to save registry data to. This file cannot
- already exist. If this filename includes an extension, it cannot be
- used on file allocation table (FAT) file systems by the LoadKey(),
- ReplaceKey() or RestoreKey() methods.
- /
- Saves the specified key, and all its subkeys to the specified file.
- If key represents a key on a remote computer, the path described by
- file_name is relative to the remote computer.
- The caller of this method must possess the SeBackupPrivilege
- security privilege. This function passes NULL for security_attributes
- to the API.
- [clinic start generated code]*/
- static PyObject *
- winreg_SaveKey_impl(PyObject *module, HKEY key, const Py_UNICODE *file_name)
- /*[clinic end generated code: output=ca94b835c88f112b input=da735241f91ac7a2]*/
- {
- LPSECURITY_ATTRIBUTES pSA = NULL;
- long rc;
- /* One day we may get security into the core?
- if (!PyWinObject_AsSECURITY_ATTRIBUTES(obSA, &pSA, TRUE))
- return NULL;
- */
- if (PySys_Audit("winreg.SaveKey", "nu",
- (Py_ssize_t)key, file_name) < 0) {
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = RegSaveKeyW(key, file_name, pSA );
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc, "RegSaveKey");
- Py_RETURN_NONE;
- }
- #endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */
- /*[clinic input]
- winreg.SetValue
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- sub_key: Py_UNICODE(accept={str, NoneType})
- A string that names the subkey with which the value is associated.
- type: DWORD
- An integer that specifies the type of the data. Currently this must
- be REG_SZ, meaning only strings are supported.
- value as value_obj: unicode
- A string that specifies the new value.
- /
- Associates a value with a specified key.
- If the key specified by the sub_key parameter does not exist, the
- SetValue function creates it.
- Value lengths are limited by available memory. Long values (more than
- 2048 bytes) should be stored as files with the filenames stored in
- the configuration registry to help the registry perform efficiently.
- The key identified by the key parameter must have been opened with
- KEY_SET_VALUE access.
- [clinic start generated code]*/
- static PyObject *
- winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
- DWORD type, PyObject *value_obj)
- /*[clinic end generated code: output=d4773dc9c372311a input=bf088494ae2d24fd]*/
- {
- LONG rc;
- HKEY childKey = key;
- LPWSTR value;
- Py_ssize_t size;
- Py_ssize_t length;
- PyObject *result = NULL;
- if (type != REG_SZ) {
- PyErr_SetString(PyExc_TypeError, "type must be winreg.REG_SZ");
- return NULL;
- }
- value = PyUnicode_AsWideCharString(value_obj, &length);
- if (value == NULL) {
- return NULL;
- }
- size = (length + 1) * sizeof(WCHAR);
- if ((Py_ssize_t)(DWORD)size != size) {
- PyErr_SetString(PyExc_OverflowError, "value is too long");
- goto exit;
- }
- if (PySys_Audit("winreg.SetValue", "nunu#",
- (Py_ssize_t)key, sub_key, (Py_ssize_t)type,
- value, length) < 0)
- {
- goto exit;
- }
- if (key == HKEY_PERFORMANCE_DATA) {
- PyErr_SetFromWindowsErrWithFunction(ERROR_INVALID_HANDLE,
- "RegSetValue");
- goto exit;
- }
- if (sub_key && sub_key[0]) {
- Py_BEGIN_ALLOW_THREADS
- rc = RegCreateKeyExW(key, sub_key, 0, NULL, 0, KEY_SET_VALUE, NULL,
- &childKey, NULL);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS) {
- PyErr_SetFromWindowsErrWithFunction(rc, "RegCreateKeyEx");
- goto exit;
- }
- }
- Py_BEGIN_ALLOW_THREADS
- rc = RegSetValueExW(childKey, NULL, 0, REG_SZ, (LPBYTE)value, (DWORD)size);
- Py_END_ALLOW_THREADS
- if (rc == ERROR_SUCCESS) {
- result = Py_NewRef(Py_None);
- }
- else {
- PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValueEx");
- }
- exit:
- PyMem_Free(value);
- if (childKey != key) {
- RegCloseKey(childKey);
- }
- return result;
- }
- /*[clinic input]
- winreg.SetValueEx
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- value_name: Py_UNICODE(accept={str, NoneType})
- A string containing the name of the value to set, or None.
- reserved: object
- Can be anything - zero is always passed to the API.
- type: DWORD
- An integer that specifies the type of the data, one of:
- REG_BINARY -- Binary data in any form.
- REG_DWORD -- A 32-bit number.
- REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format. Equivalent to REG_DWORD
- REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format.
- REG_EXPAND_SZ -- A null-terminated string that contains unexpanded
- references to environment variables (for example,
- %PATH%).
- REG_LINK -- A Unicode symbolic link.
- REG_MULTI_SZ -- A sequence of null-terminated strings, terminated
- by two null characters. Note that Python handles
- this termination automatically.
- REG_NONE -- No defined value type.
- REG_QWORD -- A 64-bit number.
- REG_QWORD_LITTLE_ENDIAN -- A 64-bit number in little-endian format. Equivalent to REG_QWORD.
- REG_RESOURCE_LIST -- A device-driver resource list.
- REG_SZ -- A null-terminated string.
- value: object
- A string that specifies the new value.
- /
- Stores data in the value field of an open registry key.
- This method can also set additional value and type information for the
- specified key. The key identified by the key parameter must have been
- opened with KEY_SET_VALUE access.
- To open the key, use the CreateKeyEx() or OpenKeyEx() methods.
- Value lengths are limited by available memory. Long values (more than
- 2048 bytes) should be stored as files with the filenames stored in
- the configuration registry to help the registry perform efficiently.
- [clinic start generated code]*/
- static PyObject *
- winreg_SetValueEx_impl(PyObject *module, HKEY key,
- const Py_UNICODE *value_name, PyObject *reserved,
- DWORD type, PyObject *value)
- /*[clinic end generated code: output=811b769a66ae11b7 input=900a9e3990bfb196]*/
- {
- LONG rc;
- BYTE *data = NULL;
- DWORD size;
- PyObject *result = NULL;
- if (!Py2Reg(value, type, &data, &size))
- {
- if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_ValueError,
- "Could not convert the data to the specified type.");
- }
- return NULL;
- }
- if (PySys_Audit("winreg.SetValue", "nunO",
- (Py_ssize_t)key, value_name, (Py_ssize_t)type,
- value) < 0)
- {
- goto exit;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = RegSetValueExW(key, value_name, 0, type, data, size);
- Py_END_ALLOW_THREADS
- if (rc == ERROR_SUCCESS) {
- result = Py_NewRef(Py_None);
- }
- else {
- PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValueEx");
- }
- exit:
- PyMem_Free(data);
- return result;
- }
- #if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
- /*[clinic input]
- winreg.DisableReflectionKey
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- /
- Disables registry reflection for 32bit processes running on a 64bit OS.
- Will generally raise NotImplementedError if executed on a 32bit OS.
- If the key is not on the reflection list, the function succeeds but has
- no effect. Disabling reflection for a key does not affect reflection
- of any subkeys.
- [clinic start generated code]*/
- static PyObject *
- winreg_DisableReflectionKey_impl(PyObject *module, HKEY key)
- /*[clinic end generated code: output=830cce504cc764b4 input=70bece2dee02e073]*/
- {
- HMODULE hMod;
- typedef LONG (WINAPI *RDRKFunc)(HKEY);
- RDRKFunc pfn = NULL;
- LONG rc;
- if (PySys_Audit("winreg.DisableReflectionKey", "n", (Py_ssize_t)key) < 0) {
- return NULL;
- }
- /* Only available on 64bit platforms, so we must load it
- dynamically.*/
- Py_BEGIN_ALLOW_THREADS
- hMod = GetModuleHandleW(L"advapi32.dll");
- if (hMod)
- pfn = (RDRKFunc)GetProcAddress(hMod,
- "RegDisableReflectionKey");
- Py_END_ALLOW_THREADS
- if (!pfn) {
- PyErr_SetString(PyExc_NotImplementedError,
- "not implemented on this platform");
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = (*pfn)(key);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc,
- "RegDisableReflectionKey");
- Py_RETURN_NONE;
- }
- /*[clinic input]
- winreg.EnableReflectionKey
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- /
- Restores registry reflection for the specified disabled key.
- Will generally raise NotImplementedError if executed on a 32bit OS.
- Restoring reflection for a key does not affect reflection of any
- subkeys.
- [clinic start generated code]*/
- static PyObject *
- winreg_EnableReflectionKey_impl(PyObject *module, HKEY key)
- /*[clinic end generated code: output=86fa1385fdd9ce57 input=eeae770c6eb9f559]*/
- {
- HMODULE hMod;
- typedef LONG (WINAPI *RERKFunc)(HKEY);
- RERKFunc pfn = NULL;
- LONG rc;
- if (PySys_Audit("winreg.EnableReflectionKey", "n", (Py_ssize_t)key) < 0) {
- return NULL;
- }
- /* Only available on 64bit platforms, so we must load it
- dynamically.*/
- Py_BEGIN_ALLOW_THREADS
- hMod = GetModuleHandleW(L"advapi32.dll");
- if (hMod)
- pfn = (RERKFunc)GetProcAddress(hMod,
- "RegEnableReflectionKey");
- Py_END_ALLOW_THREADS
- if (!pfn) {
- PyErr_SetString(PyExc_NotImplementedError,
- "not implemented on this platform");
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = (*pfn)(key);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc,
- "RegEnableReflectionKey");
- Py_RETURN_NONE;
- }
- /*[clinic input]
- winreg.QueryReflectionKey
- key: HKEY
- An already open key, or any one of the predefined HKEY_* constants.
- /
- Returns the reflection state for the specified key as a bool.
- Will generally raise NotImplementedError if executed on a 32bit OS.
- [clinic start generated code]*/
- static PyObject *
- winreg_QueryReflectionKey_impl(PyObject *module, HKEY key)
- /*[clinic end generated code: output=4e774af288c3ebb9 input=a98fa51d55ade186]*/
- {
- HMODULE hMod;
- typedef LONG (WINAPI *RQRKFunc)(HKEY, BOOL *);
- RQRKFunc pfn = NULL;
- BOOL result;
- LONG rc;
- if (PySys_Audit("winreg.QueryReflectionKey", "n", (Py_ssize_t)key) < 0) {
- return NULL;
- }
- /* Only available on 64bit platforms, so we must load it
- dynamically.*/
- Py_BEGIN_ALLOW_THREADS
- hMod = GetModuleHandleW(L"advapi32.dll");
- if (hMod)
- pfn = (RQRKFunc)GetProcAddress(hMod,
- "RegQueryReflectionKey");
- Py_END_ALLOW_THREADS
- if (!pfn) {
- PyErr_SetString(PyExc_NotImplementedError,
- "not implemented on this platform");
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = (*pfn)(key, &result);
- Py_END_ALLOW_THREADS
- if (rc != ERROR_SUCCESS)
- return PyErr_SetFromWindowsErrWithFunction(rc,
- "RegQueryReflectionKey");
- return PyBool_FromLong(result);
- }
- #endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */
- static struct PyMethodDef winreg_methods[] = {
- WINREG_CLOSEKEY_METHODDEF
- WINREG_CONNECTREGISTRY_METHODDEF
- WINREG_CREATEKEY_METHODDEF
- WINREG_CREATEKEYEX_METHODDEF
- WINREG_DELETEKEY_METHODDEF
- WINREG_DELETEKEYEX_METHODDEF
- WINREG_DELETEVALUE_METHODDEF
- WINREG_DISABLEREFLECTIONKEY_METHODDEF
- WINREG_ENABLEREFLECTIONKEY_METHODDEF
- WINREG_ENUMKEY_METHODDEF
- WINREG_ENUMVALUE_METHODDEF
- WINREG_EXPANDENVIRONMENTSTRINGS_METHODDEF
- WINREG_FLUSHKEY_METHODDEF
- WINREG_LOADKEY_METHODDEF
- WINREG_OPENKEY_METHODDEF
- WINREG_OPENKEYEX_METHODDEF
- WINREG_QUERYVALUE_METHODDEF
- WINREG_QUERYVALUEEX_METHODDEF
- WINREG_QUERYINFOKEY_METHODDEF
- WINREG_QUERYREFLECTIONKEY_METHODDEF
- WINREG_SAVEKEY_METHODDEF
- WINREG_SETVALUE_METHODDEF
- WINREG_SETVALUEEX_METHODDEF
- NULL,
- };
- #define ADD_INT(VAL) do { \
- if (PyModule_AddIntConstant(m, #VAL, VAL) < 0) { \
- return -1; \
- } \
- } while (0)
- static int
- inskey(PyObject *mod, char *name, HKEY key)
- {
- PyObject *v = PyLong_FromVoidPtr(key);
- if (v == NULL) {
- return -1;
- }
- int rc = PyModule_AddObjectRef(mod, name, v);
- Py_DECREF(v);
- return rc;
- }
- #define ADD_KEY(VAL) do { \
- if (inskey(m, #VAL, VAL) < 0) { \
- return -1; \
- } \
- } while (0)
- static int
- exec_module(PyObject *m)
- {
- winreg_state *st = (winreg_state *)_PyModule_GetState(m);
- st->PyHKEY_Type = (PyTypeObject *)
- PyType_FromModuleAndSpec(m, &pyhkey_type_spec, NULL);
- if (st->PyHKEY_Type == NULL) {
- return -1;
- }
- if (PyModule_AddObjectRef(m, "HKEYType", (PyObject *)st->PyHKEY_Type) < 0) {
- return -1;
- }
- if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) {
- return -1;
- }
- /* Add the relevant constants */
- ADD_KEY(HKEY_CLASSES_ROOT);
- ADD_KEY(HKEY_CURRENT_USER);
- ADD_KEY(HKEY_LOCAL_MACHINE);
- ADD_KEY(HKEY_USERS);
- ADD_KEY(HKEY_PERFORMANCE_DATA);
- #ifdef HKEY_CURRENT_CONFIG
- ADD_KEY(HKEY_CURRENT_CONFIG);
- #endif
- #ifdef HKEY_DYN_DATA
- ADD_KEY(HKEY_DYN_DATA);
- #endif
- ADD_INT(KEY_QUERY_VALUE);
- ADD_INT(KEY_SET_VALUE);
- ADD_INT(KEY_CREATE_SUB_KEY);
- ADD_INT(KEY_ENUMERATE_SUB_KEYS);
- ADD_INT(KEY_NOTIFY);
- ADD_INT(KEY_CREATE_LINK);
- ADD_INT(KEY_READ);
- ADD_INT(KEY_WRITE);
- ADD_INT(KEY_EXECUTE);
- ADD_INT(KEY_ALL_ACCESS);
- #ifdef KEY_WOW64_64KEY
- ADD_INT(KEY_WOW64_64KEY);
- #endif
- #ifdef KEY_WOW64_32KEY
- ADD_INT(KEY_WOW64_32KEY);
- #endif
- ADD_INT(REG_OPTION_RESERVED);
- ADD_INT(REG_OPTION_NON_VOLATILE);
- ADD_INT(REG_OPTION_VOLATILE);
- ADD_INT(REG_OPTION_CREATE_LINK);
- ADD_INT(REG_OPTION_BACKUP_RESTORE);
- ADD_INT(REG_OPTION_OPEN_LINK);
- ADD_INT(REG_LEGAL_OPTION);
- ADD_INT(REG_CREATED_NEW_KEY);
- ADD_INT(REG_OPENED_EXISTING_KEY);
- ADD_INT(REG_WHOLE_HIVE_VOLATILE);
- ADD_INT(REG_REFRESH_HIVE);
- ADD_INT(REG_NO_LAZY_FLUSH);
- ADD_INT(REG_NOTIFY_CHANGE_NAME);
- ADD_INT(REG_NOTIFY_CHANGE_ATTRIBUTES);
- ADD_INT(REG_NOTIFY_CHANGE_LAST_SET);
- ADD_INT(REG_NOTIFY_CHANGE_SECURITY);
- ADD_INT(REG_LEGAL_CHANGE_FILTER);
- ADD_INT(REG_NONE);
- ADD_INT(REG_SZ);
- ADD_INT(REG_EXPAND_SZ);
- ADD_INT(REG_BINARY);
- ADD_INT(REG_DWORD);
- ADD_INT(REG_DWORD_LITTLE_ENDIAN);
- ADD_INT(REG_DWORD_BIG_ENDIAN);
- ADD_INT(REG_QWORD);
- ADD_INT(REG_QWORD_LITTLE_ENDIAN);
- ADD_INT(REG_LINK);
- ADD_INT(REG_MULTI_SZ);
- ADD_INT(REG_RESOURCE_LIST);
- ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR);
- ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST);
- #undef ADD_INT
- return 0;
- }
- static PyModuleDef_Slot winreg_slots[] = {
- {Py_mod_exec, exec_module},
- {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
- {0, NULL}
- };
- static int
- winreg_traverse(PyObject *module, visitproc visit, void *arg)
- {
- winreg_state *state = _PyModule_GetState(module);
- Py_VISIT(state->PyHKEY_Type);
- return 0;
- }
- static int
- winreg_clear(PyObject *module)
- {
- winreg_state *state = _PyModule_GetState(module);
- Py_CLEAR(state->PyHKEY_Type);
- return 0;
- }
- static struct PyModuleDef winregmodule = {
- .m_base = PyModuleDef_HEAD_INIT,
- .m_name = "winreg",
- .m_doc = module_doc,
- .m_size = sizeof(winreg_state),
- .m_methods = winreg_methods,
- .m_slots = winreg_slots,
- .m_traverse = winreg_traverse,
- .m_clear = winreg_clear,
- };
- PyMODINIT_FUNC PyInit_winreg(void)
- {
- return PyModuleDef_Init(&winregmodule);
- }
- #endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM || MS_WINDOWS_GAMES */
|