📄 wincfg.cxx
字号:
/* * wincfg.cxx * * Miscellaneous implementation of classes for Win32 * * Portable Windows Library * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * $Log: wincfg.cxx,v $ * Revision 1.14 2003/03/19 01:35:42 robertj * Fixed bug getting large private .ini file data, thanks Michal Zygmuntowicz * * Revision 1.13 2003/02/12 01:59:44 robertj * Changed to allow for very large private .INI files. * * Revision 1.12 2001/08/17 20:09:12 yurik * Fixed RegEnumValue name clash with system function * * Revision 1.11 2001/08/14 21:56:39 yurik * More CE Unicode Registry API bug fixes * * Revision 1.10 2001/08/14 15:41:13 yurik * Fixed bug in EnumKey for CE * * Revision 1.9 2001/03/15 23:41:22 robertj * Fixed bug just introduced so can access regisrtry directly again from PConfig. * * Revision 1.8 2001/03/09 05:50:48 robertj * Added ability to set default PConfig file or path to find it. * * Revision 1.7 2001/01/24 06:45:41 yurik * Windows CE port-related changes * * Revision 1.6 2000/09/05 02:28:38 robertj * Removed PAssert with registry access denied error, changed to PTRACE. * * Revision 1.5 2000/08/03 22:47:48 robertj * Removed assert for empty key name so can set registry default key for a section. * * Revision 1.4 2000/05/25 11:08:46 robertj * Added PConfig::HasKey() function to determine if value actually set. * Fixed "system" PConfig to use the win.ini file in correct directory. * * Revision 1.3 1999/12/30 00:32:48 robertj * Allowed absolute registry paths in PConfig::Application instances. * * Revision 1.2 1998/12/04 10:10:48 robertj * Added virtual for determining if process is a service. Fixes linkage problem. * * Revision 1.1 1998/11/30 05:35:28 robertj * Initial revision * */#include <ptlib.h>#include <winuser.h>#include <winnls.h>#include <process.h>#include <fcntl.h>#include <errno.h>#include <sys\stat.h>#define new PNEWconst char LocalMachineStr[] = "HKEY_LOCAL_MACHINE\\";const char CurrentUserStr[] = "HKEY_CURRENT_USER\\";///////////////////////////////////////////////////////////////////////////////// Configuration files#ifndef _WIN32_WCEclass SecurityID{ public: SecurityID(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, // pointer to identifier authority BYTE nSubAuthorityCount, // count of subauthorities DWORD dwSubAuthority0, // subauthority 0 DWORD dwSubAuthority1, // subauthority 1 DWORD dwSubAuthority2, // subauthority 2 DWORD dwSubAuthority3, // subauthority 3 DWORD dwSubAuthority4, // subauthority 4 DWORD dwSubAuthority5, // subauthority 5 DWORD dwSubAuthority6, // subauthority 6 DWORD dwSubAuthority7 // subauthority 7 ) { if (!AllocateAndInitializeSid(pIdentifierAuthority, // pointer to identifier authority nSubAuthorityCount, // count of subauthorities dwSubAuthority0, // subauthority 0 dwSubAuthority1, // subauthority 1 dwSubAuthority2, // subauthority 2 dwSubAuthority3, // subauthority 3 dwSubAuthority4, // subauthority 4 dwSubAuthority5, // subauthority 5 dwSubAuthority6, // subauthority 6 dwSubAuthority7, // subauthority 7 &sidptr)) sidptr = NULL; } SecurityID(LPCTSTR lpSystemName, // address of string for system name LPCTSTR lpAccountName, // address of string for account name LPTSTR ReferencedDomainName, // address of string for referenced domain LPDWORD cbReferencedDomainName, // address of size of domain string PSID_NAME_USE peUse // address of SID-type indicator ) { DWORD len = 1024; sidptr = (PSID)LocalAlloc(LPTR, len); if (sidptr != NULL) { if (!LookupAccountName(lpSystemName, // address of string for system name lpAccountName, // address of string for account name sidptr, // address of security identifier &len, // address of size of security identifier ReferencedDomainName, // address of string for referenced domain cbReferencedDomainName, // address of size of domain string peUse // address of SID-type indicator )) { LocalFree(sidptr); sidptr = NULL; } } } ~SecurityID() { FreeSid(sidptr); } operator PSID() const { return sidptr; } DWORD GetLength() const { return GetLengthSid(sidptr); } BOOL IsValid() const { return sidptr != NULL && IsValidSid(sidptr); } private: PSID sidptr;};static DWORD SecureCreateKey(HKEY rootKey, const PString & subkey, HKEY & key){ SECURITY_DESCRIPTOR secdesc; if (!InitializeSecurityDescriptor(&secdesc, SECURITY_DESCRIPTOR_REVISION)) return GetLastError(); static SID_IDENTIFIER_AUTHORITY siaNTAuthority = SECURITY_NT_AUTHORITY; SecurityID adminID(&siaNTAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0); if (!adminID.IsValid()) return GetLastError(); static SID_IDENTIFIER_AUTHORITY siaSystemAuthority = SECURITY_NT_AUTHORITY; SecurityID systemID(&siaSystemAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0); if (!systemID.IsValid()) return GetLastError(); static SID_IDENTIFIER_AUTHORITY siaCreatorAuthority = SECURITY_CREATOR_SID_AUTHORITY; SecurityID creatorID(&siaCreatorAuthority, 1, SECURITY_CREATOR_OWNER_RID, 0, 0, 0, 0, 0, 0, 0); if (!creatorID.IsValid()) return GetLastError(); SID_NAME_USE snuType; char szDomain[100]; DWORD cchDomainName = sizeof(szDomain); SecurityID userID(NULL, PProcess::Current().GetUserName(), szDomain, &cchDomainName, &snuType); if (!userID.IsValid()) return GetLastError(); DWORD acl_len = sizeof(ACL) + 4*sizeof(ACCESS_ALLOWED_ACE) + adminID.GetLength() + creatorID.GetLength() + systemID.GetLength() + userID.GetLength(); PBYTEArray dacl_buf(acl_len); PACL dacl = (PACL)dacl_buf.GetPointer(acl_len); if (!InitializeAcl(dacl, acl_len, ACL_REVISION2)) return GetLastError(); if (!AddAccessAllowedAce(dacl, ACL_REVISION2, KEY_ALL_ACCESS, adminID)) return GetLastError(); if (!AddAccessAllowedAce(dacl, ACL_REVISION2, KEY_ALL_ACCESS, systemID)) return GetLastError(); if (!AddAccessAllowedAce(dacl, ACL_REVISION2, KEY_ALL_ACCESS, creatorID)) return GetLastError(); if (!AddAccessAllowedAce(dacl, ACL_REVISION2, KEY_ALL_ACCESS, userID)) return GetLastError(); if (!SetSecurityDescriptorDacl(&secdesc, TRUE, dacl, FALSE)) return GetLastError(); SECURITY_ATTRIBUTES secattr; secattr.nLength = sizeof(secattr); secattr.lpSecurityDescriptor = &secdesc; secattr.bInheritHandle = FALSE; DWORD disposition; return RegCreateKeyEx(rootKey, subkey, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, &secattr, &key, &disposition);}#endif // _WIN32_WCERegistryKey::RegistryKey(const PString & subkeyname, OpenMode mode){ PAssert(!subkeyname.IsEmpty(), PInvalidParameter); PProcess & proc = PProcess::Current(); DWORD access = mode == ReadOnly ? KEY_READ : KEY_ALL_ACCESS; DWORD error; PString subkey; HKEY basekey; if (subkeyname.Find(LocalMachineStr) == 0) { subkey = subkeyname.Mid(19); basekey = HKEY_LOCAL_MACHINE; } else if (subkeyname.Find(CurrentUserStr) == 0) { subkey = subkeyname.Mid(18); basekey = HKEY_CURRENT_USER; } else { subkey = subkeyname; PINDEX lastCharPos = subkey.GetLength()-1; while (lastCharPos > 0 && subkey[lastCharPos] == '\\') subkey.Delete(lastCharPos--, 1); basekey = NULL; if (!proc.GetVersion(FALSE).IsEmpty()) { PString keyname = subkey; keyname.Replace("CurrentVersion", proc.GetVersion(FALSE)); error = RegOpenKeyEx(HKEY_CURRENT_USER, keyname, 0, access, &key); if (error == ERROR_SUCCESS) return;#if PTRACING if (error == ERROR_ACCESS_DENIED) PTRACE(1, "PTLib\tAccess denied accessing registry entry HKEY_CURRENT_USER\\" << keyname);#endif error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, access, &key); if (error == ERROR_SUCCESS) return;#if PTRACING if (error == ERROR_ACCESS_DENIED) PTRACE(1, "PTLib\tAccess denied accessing registry entry HKEY_LOCAL_MACHINE\\" << keyname);#endif } error = RegOpenKeyEx(HKEY_CURRENT_USER, subkey, 0, access, &key); if (error == ERROR_SUCCESS) return;#if PTRACING if (error == ERROR_ACCESS_DENIED) PTRACE(1, "PTLib\tAccess denied accessing registry entry HKEY_CURRENT_USER\\" << subkey);#endif } error = RegOpenKeyEx(basekey != NULL ? basekey : HKEY_LOCAL_MACHINE, subkey, 0, access, &key); if (error == ERROR_SUCCESS) return;#if PTRACING if (error == ERROR_ACCESS_DENIED) PTRACE(1, "PTLib\tAccess denied accessing registry entry " << (basekey != NULL ? "" : LocalMachineStr) << subkey);#endif key = NULL; if (mode != Create) return; if (basekey == NULL) { if (PProcess::Current().IsServiceProcess()) basekey = HKEY_LOCAL_MACHINE; else basekey = HKEY_CURRENT_USER; }#ifndef _WIN32_WCE error = SecureCreateKey(basekey, subkey, key); if (error != ERROR_SUCCESS) {#endif DWORD disposition; error = RegCreateKeyEx(basekey, subkey, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &disposition); if (error != ERROR_SUCCESS) { PTRACE(1, "PTLib\tCould not create registry entry " << (basekey != NULL ? "" : LocalMachineStr) << subkey); key = NULL; }#ifndef _WIN32_WCE }#endif // _WIN32_WCE}RegistryKey::~RegistryKey(){ if (key != NULL) RegCloseKey(key);}BOOL RegistryKey::EnumKey(PINDEX idx, PString & str){ if (key == NULL) return FALSE;#ifndef _WIN32_WCE if( RegEnumKey(key, idx, str.GetPointer(MAX_PATH),MAX_PATH) != ERROR_SUCCESS)#else // CE has only Unicode based API USES_CONVERSION; TCHAR tstr[MAX_PATH]; LONG lResult = RegEnumKey(key, idx, tstr, MAX_PATH); str = T2A(tstr); if( lResult != ERROR_SUCCESS )#endif return FALSE; str.MakeMinimumSize(); return TRUE;}BOOL RegistryKey::EnumValue(PINDEX idx, PString & str){ if (key == NULL) return FALSE; DWORD sizeofname = MAX_PATH;#ifndef _WIN32_WCE if (RegEnumValue(key, idx, str.GetPointer(sizeofname), &sizeofname, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)#else // CE has only Unicode based API USES_CONVERSION; TCHAR tstr[MAX_PATH]; LONG lResult = RegEnumValueCe(key, idx, tstr, &sizeofname, NULL, NULL, NULL, NULL); str = T2A(tstr); if( lResult != ERROR_SUCCESS )#endif return FALSE; str.MakeMinimumSize(); return TRUE;}BOOL RegistryKey::DeleteKey(const PString & subkey){ if (key == NULL) return TRUE; return RegDeleteKey(key, subkey) == ERROR_SUCCESS;}BOOL RegistryKey::DeleteValue(const PString & value){ if (key == NULL) return TRUE; return RegDeleteValue(key, (char *)(const char *)value) == ERROR_SUCCESS;}BOOL RegistryKey::QueryValue(const PString & value, PString & str){ if (key == NULL) return FALSE; DWORD type, size; if (RegQueryValueEx(key, (char *)(const char *)value, NULL, &type, NULL, &size) != ERROR_SUCCESS) return FALSE; switch (type) { case REG_SZ : case REG_MULTI_SZ : case REG_EXPAND_SZ : case REG_BINARY :#ifndef _WIN32_WCE return RegQueryValueEx(key, (char *)(const char *)value, NULL, &type, (LPBYTE)str.GetPointer(size), &size) == ERROR_SUCCESS;#else // CE has only Unicode based API { USES_CONVERSION; TCHAR tstr[MAX_PATH]; if( RegQueryValueEx(key, (char *)(const char *)value, NULL, &type, (LPBYTE) tstr, &size) == ERROR_SUCCESS ) { str = T2A(tstr); return TRUE; } }#endif case REG_DWORD : { DWORD num; size = sizeof(num); if (RegQueryValueEx(key, (char *)(const char *)value, NULL, &type, (LPBYTE)&num, &size) == ERROR_SUCCESS) { str = PString(PString::Signed, num); return TRUE; } } default : PAssertAlways("Unsupported registry type.");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -