⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wincfg.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * 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.1  2006/06/29 04:18:40  joegenbaclor
 * *** empty log message ***
 *
 * Revision 1.17  2006/04/09 11:04:00  csoutheren
 * Remove warnings on VS.net 2005
 *
 * Revision 1.16  2005/11/30 12:47:42  csoutheren
 * Removed tabs, reformatted some code, and changed tags for Doxygen
 *
 * Revision 1.15  2005/09/24 09:11:42  dominance
 * use unix-style slashes to not confuse mingw on win32
 *
 * 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 PNEW


const char LocalMachineStr[] = "HKEY_LOCAL_MACHINE\\";
const char CurrentUserStr[] = "HKEY_CURRENT_USER\\";

///////////////////////////////////////////////////////////////////////////////
// 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);
    }

    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_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;

  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) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -