@@ -561,7 +561,7 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
561
561
{
562
562
Py_ssize_t i ,j ;
563
563
switch (typ ) {
564
- case REG_DWORD :
564
+ case REG_DWORD :
565
565
{
566
566
if (value != Py_None && !PyLong_Check (value )) {
567
567
return FALSE;
@@ -585,7 +585,7 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
585
585
* retDataSize = sizeof (DWORD );
586
586
break ;
587
587
}
588
- case REG_QWORD :
588
+ case REG_QWORD :
589
589
{
590
590
if (value != Py_None && !PyLong_Check (value )) {
591
591
return FALSE;
@@ -1488,53 +1488,77 @@ static PyObject *
1488
1488
winreg_QueryValue_impl (PyObject * module , HKEY key , const Py_UNICODE * sub_key )
1489
1489
/*[clinic end generated code: output=c655810ae50c63a9 input=41cafbbf423b21d6]*/
1490
1490
{
1491
- long rc ;
1492
- PyObject * retStr ;
1493
- wchar_t * retBuf ;
1494
- DWORD bufSize = 0 ;
1495
- DWORD retSize = 0 ;
1496
- wchar_t * tmp ;
1491
+ LONG rc ;
1492
+ HKEY childKey = key ;
1493
+ WCHAR buf [256 ], * pbuf = buf ;
1494
+ DWORD size = sizeof (buf );
1495
+ DWORD type ;
1496
+ Py_ssize_t length ;
1497
+ PyObject * result = NULL ;
1497
1498
1498
1499
if (PySys_Audit ("winreg.QueryValue" , "nuu" ,
1499
- (Py_ssize_t )key , sub_key , NULL ) < 0 ) {
1500
+ (Py_ssize_t )key , sub_key , NULL ) < 0 )
1501
+ {
1500
1502
return NULL ;
1501
1503
}
1502
- rc = RegQueryValueW (key , sub_key , NULL , & retSize );
1503
- if (rc == ERROR_MORE_DATA )
1504
- retSize = 256 ;
1505
- else if (rc != ERROR_SUCCESS )
1506
- return PyErr_SetFromWindowsErrWithFunction (rc ,
1504
+
1505
+ if (key == HKEY_PERFORMANCE_DATA ) {
1506
+ return PyErr_SetFromWindowsErrWithFunction (ERROR_INVALID_HANDLE ,
1507
1507
"RegQueryValue" );
1508
+ }
1508
1509
1509
- bufSize = retSize ;
1510
- retBuf = (wchar_t * ) PyMem_Malloc (bufSize );
1511
- if (retBuf == NULL )
1512
- return PyErr_NoMemory ();
1510
+ if (sub_key && sub_key [0 ]) {
1511
+ Py_BEGIN_ALLOW_THREADS
1512
+ rc = RegOpenKeyExW (key , sub_key , 0 , KEY_QUERY_VALUE , & childKey );
1513
+ Py_END_ALLOW_THREADS
1514
+ if (rc != ERROR_SUCCESS ) {
1515
+ return PyErr_SetFromWindowsErrWithFunction (rc , "RegOpenKeyEx" );
1516
+ }
1517
+ }
1513
1518
1514
1519
while (1 ) {
1515
- retSize = bufSize ;
1516
- rc = RegQueryValueW (key , sub_key , retBuf , & retSize );
1517
- if (rc != ERROR_MORE_DATA )
1520
+ Py_BEGIN_ALLOW_THREADS
1521
+ rc = RegQueryValueExW (childKey , NULL , NULL , & type , (LPBYTE )pbuf ,
1522
+ & size );
1523
+ Py_END_ALLOW_THREADS
1524
+ if (rc != ERROR_MORE_DATA ) {
1518
1525
break ;
1519
-
1520
- bufSize *= 2 ;
1521
- tmp = (wchar_t * ) PyMem_Realloc (retBuf , bufSize );
1526
+ }
1527
+ void * tmp = PyMem_Realloc (pbuf != buf ? pbuf : NULL , size );
1522
1528
if (tmp == NULL ) {
1523
- PyMem_Free ( retBuf );
1524
- return PyErr_NoMemory () ;
1529
+ PyErr_NoMemory ( );
1530
+ goto exit ;
1525
1531
}
1526
- retBuf = tmp ;
1532
+ pbuf = tmp ;
1527
1533
}
1528
1534
1529
- if (rc != ERROR_SUCCESS ) {
1530
- PyMem_Free (retBuf );
1531
- return PyErr_SetFromWindowsErrWithFunction (rc ,
1532
- "RegQueryValue" );
1535
+ if (rc == ERROR_SUCCESS ) {
1536
+ if (type != REG_SZ ) {
1537
+ PyErr_SetFromWindowsErrWithFunction (ERROR_INVALID_DATA ,
1538
+ "RegQueryValue" );
1539
+ goto exit ;
1540
+ }
1541
+ length = wcsnlen (pbuf , size / sizeof (WCHAR ));
1542
+ }
1543
+ else if (rc == ERROR_FILE_NOT_FOUND ) {
1544
+ // Return an empty string if there's no default value.
1545
+ length = 0 ;
1546
+ }
1547
+ else {
1548
+ PyErr_SetFromWindowsErrWithFunction (rc , "RegQueryValueEx" );
1549
+ goto exit ;
1533
1550
}
1534
1551
1535
- retStr = PyUnicode_FromWideChar (retBuf , wcslen (retBuf ));
1536
- PyMem_Free (retBuf );
1537
- return retStr ;
1552
+ result = PyUnicode_FromWideChar (pbuf , length );
1553
+
1554
+ exit :
1555
+ if (pbuf != buf ) {
1556
+ PyMem_Free (pbuf );
1557
+ }
1558
+ if (childKey != key ) {
1559
+ RegCloseKey (childKey );
1560
+ }
1561
+ return result ;
1538
1562
}
1539
1563
1540
1564
@@ -1687,38 +1711,69 @@ winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
1687
1711
DWORD type , PyObject * value_obj )
1688
1712
/*[clinic end generated code: output=d4773dc9c372311a input=bf088494ae2d24fd]*/
1689
1713
{
1690
- Py_ssize_t value_length ;
1691
- long rc ;
1714
+ LONG rc ;
1715
+ HKEY childKey = key ;
1716
+ LPWSTR value ;
1717
+ Py_ssize_t size ;
1718
+ Py_ssize_t length ;
1719
+ PyObject * result = NULL ;
1692
1720
1693
1721
if (type != REG_SZ ) {
1694
1722
PyErr_SetString (PyExc_TypeError , "type must be winreg.REG_SZ" );
1695
1723
return NULL ;
1696
1724
}
1697
1725
1698
- wchar_t * value = PyUnicode_AsWideCharString (value_obj , & value_length );
1726
+ value = PyUnicode_AsWideCharString (value_obj , & length );
1699
1727
if (value == NULL ) {
1700
1728
return NULL ;
1701
1729
}
1702
- if ((Py_ssize_t )(DWORD )value_length != value_length ) {
1730
+
1731
+ size = (length + 1 ) * sizeof (WCHAR );
1732
+ if ((Py_ssize_t )(DWORD )size != size ) {
1703
1733
PyErr_SetString (PyExc_OverflowError , "value is too long" );
1704
- PyMem_Free (value );
1705
- return NULL ;
1734
+ goto exit ;
1706
1735
}
1707
1736
1708
1737
if (PySys_Audit ("winreg.SetValue" , "nunu#" ,
1709
1738
(Py_ssize_t )key , sub_key , (Py_ssize_t )type ,
1710
- value , value_length ) < 0 ) {
1711
- PyMem_Free (value );
1712
- return NULL ;
1739
+ value , length ) < 0 )
1740
+ {
1741
+ goto exit ;
1742
+ }
1743
+
1744
+ if (key == HKEY_PERFORMANCE_DATA ) {
1745
+ PyErr_SetFromWindowsErrWithFunction (ERROR_INVALID_HANDLE ,
1746
+ "RegSetValue" );
1747
+ goto exit ;
1748
+ }
1749
+
1750
+ if (sub_key && sub_key [0 ]) {
1751
+ Py_BEGIN_ALLOW_THREADS
1752
+ rc = RegCreateKeyExW (key , sub_key , 0 , NULL , 0 , KEY_SET_VALUE , NULL ,
1753
+ & childKey , NULL );
1754
+ Py_END_ALLOW_THREADS
1755
+ if (rc != ERROR_SUCCESS ) {
1756
+ PyErr_SetFromWindowsErrWithFunction (rc , "RegCreateKeyEx" );
1757
+ goto exit ;
1758
+ }
1713
1759
}
1714
1760
1715
1761
Py_BEGIN_ALLOW_THREADS
1716
- rc = RegSetValueW ( key , sub_key , REG_SZ , value , (DWORD )( value_length + 1 ) );
1762
+ rc = RegSetValueExW ( childKey , NULL , 0 , REG_SZ , ( LPBYTE ) value , (DWORD )size );
1717
1763
Py_END_ALLOW_THREADS
1764
+ if (rc == ERROR_SUCCESS ) {
1765
+ result = Py_NewRef (Py_None );
1766
+ }
1767
+ else {
1768
+ PyErr_SetFromWindowsErrWithFunction (rc , "RegSetValueEx" );
1769
+ }
1770
+
1771
+ exit :
1718
1772
PyMem_Free (value );
1719
- if (rc != ERROR_SUCCESS )
1720
- return PyErr_SetFromWindowsErrWithFunction (rc , "RegSetValue" );
1721
- Py_RETURN_NONE ;
1773
+ if (childKey != key ) {
1774
+ RegCloseKey (childKey );
1775
+ }
1776
+ return result ;
1722
1777
}
1723
1778
1724
1779
/*[clinic input]
@@ -1771,32 +1826,39 @@ winreg_SetValueEx_impl(PyObject *module, HKEY key,
1771
1826
DWORD type , PyObject * value )
1772
1827
/*[clinic end generated code: output=811b769a66ae11b7 input=900a9e3990bfb196]*/
1773
1828
{
1774
- BYTE * data ;
1775
- DWORD len ;
1776
-
1777
1829
LONG rc ;
1830
+ BYTE * data = NULL ;
1831
+ DWORD size ;
1832
+ PyObject * result = NULL ;
1778
1833
1779
- if (!Py2Reg (value , type , & data , & len ))
1834
+ if (!Py2Reg (value , type , & data , & size ))
1780
1835
{
1781
- if (!PyErr_Occurred ())
1836
+ if (!PyErr_Occurred ()) {
1782
1837
PyErr_SetString (PyExc_ValueError ,
1783
1838
"Could not convert the data to the specified type." );
1839
+ }
1784
1840
return NULL ;
1785
1841
}
1786
1842
if (PySys_Audit ("winreg.SetValue" , "nunO" ,
1787
1843
(Py_ssize_t )key , value_name , (Py_ssize_t )type ,
1788
- value ) < 0 ) {
1789
- PyMem_Free ( data );
1790
- return NULL ;
1844
+ value ) < 0 )
1845
+ {
1846
+ goto exit ;
1791
1847
}
1848
+
1792
1849
Py_BEGIN_ALLOW_THREADS
1793
- rc = RegSetValueExW (key , value_name , 0 , type , data , len );
1850
+ rc = RegSetValueExW (key , value_name , 0 , type , data , size );
1794
1851
Py_END_ALLOW_THREADS
1852
+ if (rc == ERROR_SUCCESS ) {
1853
+ result = Py_NewRef (Py_None );
1854
+ }
1855
+ else {
1856
+ PyErr_SetFromWindowsErrWithFunction (rc , "RegSetValueEx" );
1857
+ }
1858
+
1859
+ exit :
1795
1860
PyMem_Free (data );
1796
- if (rc != ERROR_SUCCESS )
1797
- return PyErr_SetFromWindowsErrWithFunction (rc ,
1798
- "RegSetValueEx" );
1799
- Py_RETURN_NONE ;
1861
+ return result ;
1800
1862
}
1801
1863
1802
1864
/*[clinic input]
0 commit comments