Author: mjansen Date: Wed Aug 10 19:34:38 2016 New Revision: 72191 URL: http://svn.reactos.org/svn/reactos?rev=72191&view=rev Log: [ATL][ATL_APITEST] Partially implement CRegKey + add tests. CORE-11746
Added: trunk/rostests/apitests/atl/CRegKey.cpp (with props) Modified: trunk/reactos/sdk/lib/atl/atlbase.cpp trunk/reactos/sdk/lib/atl/atlbase.h trunk/rostests/apitests/atl/CMakeLists.txt trunk/rostests/apitests/atl/testlist.c Modified: trunk/reactos/sdk/lib/atl/atlbase.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/atl/atlbase.cpp?rev=72191&r1=72190&r2=72191&view=diff ============================================================================== --- trunk/reactos/sdk/lib/atl/atlbase.cpp [iso-8859-1] (original) +++ trunk/reactos/sdk/lib/atl/atlbase.cpp [iso-8859-1] Wed Aug 10 19:34:38 2016 @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <tchar.h> #include "atlbase.h" namespace ATL Modified: trunk/reactos/sdk/lib/atl/atlbase.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/atl/atlbase.h?rev=72191&r1=72190&r2=72191&view=diff ============================================================================== --- trunk/reactos/sdk/lib/atl/atlbase.h [iso-8859-1] (original) +++ trunk/reactos/sdk/lib/atl/atlbase.h [iso-8859-1] Wed Aug 10 19:34:38 2016 @@ -25,6 +25,7 @@ #include "atlcomcli.h" #include "atlalloc.h" #include "comcat.h" +#include "tchar.h" #ifdef _MSC_VER // It is common to use this in ATL constructors. They only store this for later use, so the usage is safe. @@ -886,6 +887,218 @@ } }; +class CRegKey +{ +public: + HKEY m_hKey; + +public: + + CRegKey() throw() + : m_hKey(NULL) + { + } + + CRegKey(CRegKey& key) throw() + { + Attach(key.Detach()); + } + + explicit CRegKey(HKEY hKey) throw() + :m_hKey(hKey) + { + } + + ~CRegKey() throw() + { + } + + void Attach(HKEY hKey) throw() + { + m_hKey = hKey; + } + + LONG Close() throw() + { + if (m_hKey) + { + HKEY hKey = Detach(); + return RegCloseKey(hKey); + } + return ERROR_SUCCESS; + } + + HKEY Detach() throw() + { + HKEY hKey = m_hKey; + m_hKey = NULL; + return hKey; + } + + LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired = KEY_READ | KEY_WRITE) throw() + { + HKEY hKey = NULL; + + LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyName, NULL, samDesired, &hKey); + if (lRes == ERROR_SUCCESS) + { + Close(); + m_hKey = hKey; + } + return lRes; + } + + LONG Create(HKEY hKeyParent, LPCTSTR lpszKeyName, LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE, REGSAM samDesired = KEY_READ | KEY_WRITE, LPSECURITY_ATTRIBUTES lpSecAttr = NULL, LPDWORD lpdwDisposition = NULL) throw() + { + HKEY hKey = NULL; + + LONG lRes = RegCreateKeyEx(hKeyParent, lpszKeyName, NULL, lpszClass, dwOptions, samDesired, lpSecAttr, &hKey, lpdwDisposition); + if (lRes == ERROR_SUCCESS) + { + Close(); + m_hKey = hKey; + } + return lRes; + } + + + LONG QueryValue(LPCTSTR pszValueName, DWORD* pdwType, void* pData, ULONG* pnBytes) throw() + { + return RegQueryValueEx(m_hKey, pszValueName, NULL, pdwType, (LPBYTE)pData, pnBytes); + } + + LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD& dwValue) throw() + { + ULONG size = sizeof(DWORD); + DWORD type = 0; + LONG lRet = QueryValue(pszValueName, &type, &dwValue, &size); + + if (lRet == ERROR_SUCCESS && type != REG_DWORD) + lRet = ERROR_INVALID_DATA; + + return lRet; + } + + LONG QueryBinaryValue(LPCTSTR pszValueName, void* pValue, ULONG* pnBytes) throw() + { + DWORD type = 0; + LONG lRet = QueryValue(pszValueName, &type, pValue, pnBytes); + + if (lRet == ERROR_SUCCESS && type != REG_BINARY) + lRet = ERROR_INVALID_DATA; + + return lRet; + } + + LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars) throw() + { + ULONG size = (*pnChars) * sizeof(TCHAR); + DWORD type = 0; + LONG lRet = QueryValue(pszValueName, &type, pszValue, &size); + + if (lRet == ERROR_SUCCESS && type != REG_SZ) + lRet = ERROR_INVALID_DATA; + + *pnChars = size / sizeof(TCHAR); + return lRet; + } + + LONG QueryGUIDValue(LPCTSTR pszValueName, GUID& guidValue) throw() + { + OLECHAR buf[40] = {0}; + ULONG nChars = 39; + LONG lRet; + +#ifdef UNICODE + lRet = QueryStringValue(pszValueName, buf, &nChars); +#else + CHAR bufA[40] = {0}; + lRet = QueryStringValue(pszValueName, bufA, &nChars); + if (lRet != ERROR_SUCCESS) + return lRet; + if (!::MultiByteToWideChar(CP_THREAD_ACP, 0, bufA, -1, buf, 39)) + lRet = ERROR_INVALID_DATA; +#endif + if (lRet != ERROR_SUCCESS) + return lRet; + + if (!SUCCEEDED(CLSIDFromString(buf, &guidValue))) + return ERROR_INVALID_DATA; + + return lRet; + } + + LONG SetValue(LPCTSTR pszValueName, DWORD dwType, const void* pValue, ULONG nBytes) throw() + { + return RegSetValueEx(m_hKey, pszValueName, NULL, dwType, (const BYTE*)pValue, nBytes); + } + + LONG SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue) throw() + { + return SetValue(pszValueName, REG_DWORD, &dwValue, sizeof(DWORD)); + } + + LONG SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType = REG_SZ) throw() + { + if (dwType != REG_SZ) + return ERROR_INVALID_DATA; // not implemented yet. + + ULONG length = (_tcslen(pszValue) + 1) * sizeof(TCHAR); + return SetValue(pszValueName, dwType, pszValue, length); + } + + LONG SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue) throw() + { + OLECHAR buf[40] = {0}; + StringFromGUID2(guidValue, buf, 39); +#ifdef UNICODE + return SetStringValue(pszValueName, buf); +#else + CHAR bufA[40] = {0}; + ::WideCharToMultiByte(CP_THREAD_ACP, 0, buf, -1, bufA, 40, NULL, NULL); + return SetStringValue(pszValueName, bufA); +#endif + } + + LONG SetBinaryValue(LPCTSTR pszValueName, const void* pValue, ULONG nBytes) throw() + { + return SetValue(pszValueName, REG_BINARY, pValue, nBytes); + } + + LONG SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL) throw() + { + CRegKey key; + LONG lRet = key.Create(m_hKey, lpszKeyName); + if (lRet == ERROR_SUCCESS) + { + lRet = key.SetStringValue(lpszValueName, lpszValue); + } + return lRet; + } + + LONG DeleteValue(LPCTSTR lpszValue) throw() + { + return RegDeleteValue(m_hKey, lpszValue); + } + + LONG DeleteSubKey(LPCTSTR lpszSubKey) throw() + { + return RegDeleteKey(m_hKey, lpszSubKey); + } + + operator HKEY() const throw() + { + return m_hKey; + } + + CRegKey& operator =(CRegKey& key) throw() + { + Attach(Detach()); + return *this; + } + +}; + template<class T> class CComHeapPtr : public CHeapPtr<T, CComAllocator> Modified: trunk/rostests/apitests/atl/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/CMakeLists.txt?rev=72191&r1=72190&r2=72191&view=diff ============================================================================== --- trunk/rostests/apitests/atl/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/apitests/atl/CMakeLists.txt [iso-8859-1] Wed Aug 10 19:34:38 2016 @@ -7,11 +7,12 @@ atltypes.cpp CComBSTR.cpp CComHeapPtr.cpp + CRegKey.cpp CString.cpp testlist.c atl_apitest.rc) target_link_libraries(atl_apitest wine uuid) set_module_type(atl_apitest win32cui) -add_importlibs(atl_apitest ole32 oleaut32 user32 msvcrt kernel32) +add_importlibs(atl_apitest ole32 oleaut32 advapi32 user32 msvcrt kernel32) add_cd_file(TARGET atl_apitest DESTINATION reactos/bin FOR all) Added: trunk/rostests/apitests/atl/CRegKey.cpp URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/CRegKey.cpp?rev=72191 ============================================================================== --- trunk/rostests/apitests/atl/CRegKey.cpp (added) +++ trunk/rostests/apitests/atl/CRegKey.cpp [iso-8859-1] Wed Aug 10 19:34:38 2016 @@ -0,0 +1,188 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for CRegKey + * PROGRAMMER: Mark Jansen + */ + +#include <apitest.h> +#include <atlbase.h> + +START_TEST(CRegKey) +{ + CRegKey key; + CRegKey key2(HKEY_CURRENT_USER); + + ok(key.m_hKey == NULL, "Expected m_hKey to be initialized to 0, was: %p\n", key.m_hKey); + ok(key2.m_hKey == HKEY_CURRENT_USER, "Expected m_hKey to be initialized to HKEY_CURRENT_USER, was: %p\n", key2.m_hKey); + ok(key2 == HKEY_CURRENT_USER, "Expected operator HKEY() to be implemented\n"); + + // Take ownership + CRegKey key3(key2); + ok(key3.m_hKey == HKEY_CURRENT_USER, "Expected m_hKey to be initialized to HKEY_CURRENT_USER, was: %p\n", key3.m_hKey); + ok(key2.m_hKey == NULL, "Expected m_hKey to be initialized to 0, was: %p\n", key2.m_hKey); + + LSTATUS lret; + + lret = key.Close(); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + lret = key2.Close(); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + lret = key3.Close(); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + // read/write + lret = key.Open(HKEY_CURRENT_USER, _T("Environment")); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(key.m_hKey != NULL, "Expected m_hKey to not be NULL, was: %p\n", key.m_hKey); + + + HKEY tmp = key.m_hKey; + HKEY detached = key.Detach(); + ok(key.m_hKey == NULL, "Expected m_hKey to be 0, was: %p\n", key.m_hKey); + ok(detached == tmp, "Expected detached to be %p, was: %p\n", tmp, detached); + key.Attach(detached); + ok(key.m_hKey == tmp, "Expected m_hKey to be %p, was: %p\n", tmp, key.m_hKey); + + lret = key2.Open(HKEY_CURRENT_USER, _T("Environment"), KEY_READ); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + lret = key3.Open(HKEY_CURRENT_USER, _T("Environment"), KEY_WRITE); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + TCHAR testdata[] = _T("XX-XX"); + lret = key.SetValue(_T("APITEST_VALUE_NAME"), REG_SZ, testdata, sizeof(testdata)); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + TCHAR buffer[100]; + ULONG buffer_size = sizeof(buffer); + DWORD type = 0x12345; + memset(buffer, 0, sizeof(buffer)); + + lret = key.QueryValue(_T("APITEST_VALUE_NAME"), &type, buffer, &buffer_size); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(type == REG_SZ, "Expected type to be REG_SZ, was: %lu\n", type); + ok(buffer_size == sizeof(testdata), "Expected buffer_size to be %u, was: %lu\n", sizeof(testdata), buffer_size); + ok(!memcmp(buffer, testdata, sizeof(testdata)), "Expected to get the same input as what was written!\n"); + + + buffer_size = sizeof(buffer); + type = 0x12345; + memset(buffer, 0, sizeof(buffer)); + lret = key2.QueryValue(_T("APITEST_VALUE_NAME"), &type, buffer, &buffer_size); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(type == REG_SZ, "Expected type to be REG_SZ, was: %lu\n", type); + ok(buffer_size == sizeof(testdata), "Expected buffer_size to be %u, was: %lu\n", sizeof(testdata), buffer_size); + ok(!memcmp(buffer, testdata, sizeof(testdata)), "Expected to get the same input as what was written!\n"); + + buffer_size = sizeof(buffer); + type = 0x12345; + memset(buffer, 0, sizeof(buffer)); + lret = key3.QueryValue(_T("APITEST_VALUE_NAME"), &type, buffer, &buffer_size); + ok(lret == ERROR_ACCESS_DENIED, "Expected lret to be ERROR_ACCESS_DENIED, was: %lu\n", lret); + ok(type == 0 || broken(type == 203), "Expected type to be 0, was: %lu\n", type); + ok(buffer_size == sizeof(buffer), "Expected buffer_size to be %u, was: %lu\n", sizeof(buffer), buffer_size); + + + lret = key2.SetValue(_T("APITEST_VALUE_NAME"), REG_SZ, testdata, sizeof(testdata)); + ok(lret == ERROR_ACCESS_DENIED, "Expected lret to be ERROR_ACCESS_DENIED, was: %lu\n", lret); + + lret = key2.DeleteValue(_T("APITEST_VALUE_NAME")); + ok(lret == ERROR_ACCESS_DENIED, "Expected lret to be ERROR_ACCESS_DENIED, was: %lu\n", lret); + + DWORD dword = 0x54321; + lret = key2.QueryDWORDValue(_T("APITEST_VALUE_NAME"), dword); + ok(lret == ERROR_MORE_DATA, "Expected lret to be ERROR_MORE_DATA, was: %lu\n", lret); + ok(dword == 0x54321, "Expected dword to be 0x54321, was: %lu\n", dword); + + lret = key.SetValue(_T("APITEST_VALUE_NAME"), REG_SZ, testdata, sizeof(TCHAR)); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_ACCESS_DENIED, was: %lu\n", lret); + + dword = 0x54321; + lret = key2.QueryDWORDValue(_T("APITEST_VALUE_NAME"), dword); + ok(lret == ERROR_INVALID_DATA, "Expected lret to be ERROR_MORE_DATA, was: %lu\n", lret); + ok(dword != 0x54321, "Expected dword to NOT be 0x54321, was: %lu\n", dword); + + lret = key3.SetDWORDValue(_T("APITEST_VALUE_NAME"), 0x12345); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + dword = 0x54321; + lret = key2.QueryDWORDValue(_T("APITEST_VALUE_NAME"), dword); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(dword == 0x12345, "Expected dword to be 0x12345, was: %lu\n", dword); + + + lret = key3.DeleteValue(_T("APITEST_VALUE_NAME")); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + + lret = key.SetKeyValue(_T("APITEST_KEY_NAME"), _T("APITEST_VALUE")); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + CRegKey qv; + + // COUNTOF, not SIZEOF!!!! + lret = qv.Open(HKEY_CURRENT_USER, _T("Environment\\APITEST_KEY_NAME")); + buffer_size = _countof(buffer); + memset(buffer, 0, sizeof(buffer)); + lret = qv.QueryStringValue(NULL, buffer, &buffer_size); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(buffer_size == _countof("APITEST_VALUE"), "Expected buffer_size to be %u, was: %lu\n", _countof("APITEST_VALUE"), buffer_size); + ok(!_tcscmp(buffer, _T("APITEST_VALUE")), "Expected to get the same input as what was written!\n"); + + lret = key.SetKeyValue(_T("APITEST_KEY_NAME"), _T("APITEST_VALUE2"), _T("APITEST_VALUE_NAME")); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + buffer_size = _countof(buffer); + memset(buffer, 0, sizeof(buffer)); + lret = qv.QueryStringValue(_T("APITEST_VALUE_NAME"), buffer, &buffer_size); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(buffer_size == _countof("APITEST_VALUE2"), "Expected buffer_size to be %u, was: %lu\n", _countof("APITEST_VALUE2"), buffer_size); + ok(!_tcscmp(buffer, _T("APITEST_VALUE2")), "Expected to get the same input as what was written!\n"); + + lret = key.DeleteSubKey(_T("APITEST_KEY_NAME")); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + GUID guid, guid2; + memset(&guid, 56, sizeof(guid)); + + lret = key.SetGUIDValue(_T("GUID_NAME"), guid); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + lret = key.QueryGUIDValue(_T("GUID_NAME"), guid2); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(!memcmp(&guid, &guid2, sizeof(guid)), "Expected guid to equal guid2\n"); + + buffer_size = _countof(buffer); + memset(buffer, 0, sizeof(buffer)); + lret = key2.QueryStringValue(_T("GUID_NAME"), buffer, &buffer_size); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(buffer_size == _countof("{38383838-3838-3838-3838-383838383838}"), + "Expected buffer_size to be %u, was: %lu\n", _countof("{38383838-3838-3838-3838-383838383838}"), buffer_size); + ok(!_tcscmp(buffer, _T("{38383838-3838-3838-3838-383838383838}")), "Expected to get the same input as what was written!\n"); + + memset(&guid, 33, 5); + lret = key.SetBinaryValue(_T("BIN_NAME"), &guid, 5); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + buffer_size = sizeof(buffer); + memset(buffer, 0, sizeof(buffer)); + lret = key.QueryBinaryValue(_T("GUID_NAME"), buffer, &buffer_size); + ok(lret == ERROR_INVALID_DATA, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(buffer_size == sizeof(_T("{38383838-3838-3838-3838-383838383838}")), + "Expected buffer_size to be %u, was: %lu\n", sizeof(_T("{38383838-3838-3838-3838-383838383838}")), buffer_size); + ok(buffer[0] == '{', "Expected buffer[0] to be 123, was: %i\n", (int)buffer[0]); + + buffer_size = sizeof(buffer); + memset(buffer, 0, sizeof(buffer)); + lret = key.QueryBinaryValue(_T("BIN_NAME"), buffer, &buffer_size); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + ok(buffer_size == 5, "Expected buffer_size to be %i, was: %lu\n", 5, buffer_size); + ok(!memcmp(buffer, &guid, 5), "Expected the first 5 bytes of buffer to equal the data in null_guid\n"); + + lret = key.DeleteValue(_T("GUID_NAME")); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); + + lret = key.DeleteValue(_T("BIN_NAME")); + ok(lret == ERROR_SUCCESS, "Expected lret to be ERROR_SUCCESS, was: %lu\n", lret); +} Propchange: trunk/rostests/apitests/atl/CRegKey.cpp ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/rostests/apitests/atl/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/testlist.c?rev=72191&r1=72190&r2=72191&view=diff ============================================================================== --- trunk/rostests/apitests/atl/testlist.c [iso-8859-1] (original) +++ trunk/rostests/apitests/atl/testlist.c [iso-8859-1] Wed Aug 10 19:34:38 2016 @@ -4,6 +4,7 @@ extern void func_atltypes(void); extern void func_CComBSTR(void); extern void func_CComHeapPtr(void); +extern void func_CRegKey(void); extern void func_CString(void); const struct test winetest_testlist[] = @@ -11,6 +12,7 @@ { "atltypes", func_atltypes }, { "CComBSTR", func_CComBSTR }, { "CComHeapPtr", func_CComHeapPtr }, + { "CRegKey", func_CRegKey }, { "CString", func_CString }, { 0, 0 } };