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