📄 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): ______________________________________.
*
* $Revision: 19643 $
* $Author: csoutheren $
* $Date: 2008-02-29 13:19:22 +0000 (Fri, 29 Feb 2008) $
*/
#include <ptlib.h>
#include <ptlib/pprocess.h>
#include <winuser.h>
#include <winnls.h>
#define new PNEW
const char LocalMachineStr[] = "HKEY_LOCAL_MACHINE\\";
const char CurrentUserStr[] = "HKEY_CURRENT_USER\\";
const char ClassesRootStr[] = "HKEY_CLASSES_ROOT\\";
///////////////////////////////////////////////////////////////////////////////
// Configuration files
#ifndef _WIN32_WCE
class 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);
}
PBoolean 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, PTrue, dacl, PFalse))
return GetLastError();
SECURITY_ATTRIBUTES secattr;
secattr.nLength = sizeof(secattr);
secattr.lpSecurityDescriptor = &secdesc;
secattr.bInheritHandle = PFalse;
DWORD disposition;
return RegCreateKeyEx(rootKey, subkey, 0, (char*) "", REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, &secattr, &key, &disposition);
}
#endif // _WIN32_WCE
RegistryKey::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;
PVarString 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 if (subkeyname.Find(ClassesRootStr) == 0) {
subkey = subkeyname.Mid(18);
basekey = HKEY_CLASSES_ROOT;
}
else {
PString adjustedSubkey = subkeyname;
PINDEX lastCharPos = adjustedSubkey.GetLength()-1;
while (lastCharPos > 0 && adjustedSubkey[lastCharPos] == '\\')
adjustedSubkey.Delete(lastCharPos--, 1);
basekey = NULL;
subkey = adjustedSubkey;
if (!proc.GetVersion(PFalse).IsEmpty()) {
adjustedSubkey.Replace("CurrentVersion", proc.GetVersion(PFalse));
PVarString keyname = adjustedSubkey;
error = RegOpenKeyEx(HKEY_CURRENT_USER, keyname, 0, access, &key);
if (error == ERROR_SUCCESS)
return;
PTRACE_IF(1, error == ERROR_ACCESS_DENIED, "PTLib\tAccess denied accessing registry entry HKEY_CURRENT_USER\\" << keyname);
error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, access, &key);
if (error == ERROR_SUCCESS)
return;
PTRACE_IF(1, error == ERROR_ACCESS_DENIED, "PTLib\tAccess denied accessing registry entry HKEY_LOCAL_MACHINE\\" << keyname);
}
error = RegOpenKeyEx(HKEY_CURRENT_USER, subkey, 0, access, &key);
if (error == ERROR_SUCCESS)
return;
PTRACE_IF(1, error == ERROR_ACCESS_DENIED, "PTLib\tAccess denied accessing registry entry HKEY_CURRENT_USER\\" << subkey);
}
error = RegOpenKeyEx(basekey != NULL ? basekey : HKEY_LOCAL_MACHINE, subkey, 0, access, &key);
if (error == ERROR_SUCCESS)
return;
PTRACE_IF(1, error == ERROR_ACCESS_DENIED, "PTLib\tAccess denied accessing registry entry "
<< (basekey != NULL ? "" : LocalMachineStr) << subkey);
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;
TCHAR empty[1];
empty[0] = 0;
error = RegCreateKeyEx(basekey, subkey, 0, empty, 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;
}
}
}
RegistryKey::~RegistryKey()
{
if (key != NULL)
RegCloseKey(key);
}
BOOL RegistryKey::EnumKey(PINDEX idx, PString & str)
{
if (key == NULL)
return PFalse;
#ifndef _WIN32_WCE
if( RegEnumKey(key, idx, str.GetPointer(MAX_PATH),MAX_PATH) != ERROR_SUCCESS)
#else // CE has only Unicode based API
WCHAR wcsKey[MAX_PATH] = {0};
LONG lResult = RegEnumKey(key, idx, wcsKey, MAX_PATH);
int size = wcslen(wcsKey);
if( size )
{
wcstombs( (char*) str.GetPointer(size), wcsKey, size );
str.SetSize(size + 1);
str.SetAt(size, 0);
}
if( lResult != ERROR_SUCCESS )
#endif
return PFalse;
str.MakeMinimumSize();
return PTrue;
}
BOOL RegistryKey::EnumValue(PINDEX idx, PString & str)
{
if (key == NULL)
return PFalse;
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
WCHAR wcsValue[MAX_PATH] = {0};
LONG lResult = RegEnumValue(key, idx, wcsValue,
&sizeofname, NULL, NULL, NULL, NULL);
sizeofname = wcslen(wcsValue);
if( sizeofname )
{
wcstombs( (char*) str.GetPointer(sizeofname), wcsValue, sizeofname );
str.SetSize(sizeofname + 1);
str.SetAt(sizeofname, 0);
}
if( lResult != ERROR_SUCCESS )
#endif
return PFalse;
str.MakeMinimumSize();
return PTrue;
}
BOOL RegistryKey::DeleteKey(const PString & subkey)
{
if (key == NULL)
return PTrue;
return RegDeleteKey(key, PVarString(subkey)) == ERROR_SUCCESS;
}
BOOL RegistryKey::DeleteValue(const PString & value)
{
if (key == NULL)
return PTrue;
return RegDeleteValue(key, PVarString(value)) == ERROR_SUCCESS;
}
BOOL RegistryKey::QueryValue(const PString & value, PString & str)
{
if (key == NULL)
return PFalse;
DWORD type, size;
#ifndef _WIN32_WCE
if (RegQueryValueEx(key, (char *)(const char *)value,
NULL, &type, NULL, &size) != ERROR_SUCCESS)
#else
// WINCE has only Unicode based API
LONG lResult = ERROR_SUCCESS;
{
WCHAR wcsValue[MAX_PATH];
mbstowcs(wcsValue, value, MAX_PATH);
lResult = RegQueryValueEx(key, wcsValue, NULL,
&type, NULL, &size );
}
if( lResult != ERROR_SUCCESS )
#endif
return PFalse;
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
{
// WINCE strings are Unicode
WCHAR wcsValue[MAX_PATH];
mbstowcs(wcsValue, value, MAX_PATH);
// Expand receiving buffer to accomodate wchars
str.SetSize( str.GetSize() * sizeof (short) );
if( RegQueryValueEx(key, wcsValue, NULL,
&type, (LPBYTE) str.GetPointer(size), &size ) != ERROR_SUCCESS )
return PFalse;
else
{
if( type != REG_BINARY )
{
// Convert to char* string
wcsncpy( wcsValue, (LPCWSTR) str.GetPointer(), MAX_PATH );
size = wcslen(wcsValue);
if( size )
{
wcstombs( (char*) str.GetPointer(size), wcsValue, size );
str.SetSize(size + 1);
str.SetAt(size, 0);
}
}
return PTrue;
}
}
#endif // _WIN32_WCE
case REG_DWORD : {
DWORD num;
size = sizeof(num);
#ifndef _WIN32_WCE
if (RegQueryValueEx(key, (char *)(const char *)value, NULL,
&type, (LPBYTE)&num, &size) == ERROR_SUCCESS) {
str = PString(PString::Signed, num);
#else
// WINCE strings are Unicode
WCHAR wcsValue[MAX_PATH];
mbstowcs(wcsValue, value, MAX_PATH);
if (RegQueryValueEx(key, wcsValue, NULL,
&type, (LPBYTE)&num, &size) == ERROR_SUCCESS) {
str = PString(PString::Signed, num);
#endif
return PTrue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -