wincfg.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:22k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * wincfg.cxx
  3.  *
  4.  * Miscellaneous implementation of classes for Win32
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: wincfg.cxx,v $
  30.  * Revision 1.4  2000/05/25 11:08:46  robertj
  31.  * Added PConfig::HasKey() function to determine if value actually set.
  32.  * Fixed "system" PConfig to use the win.ini file in correct directory.
  33.  *
  34.  * Revision 1.3  1999/12/30 00:32:48  robertj
  35.  * Allowed absolute registry paths in PConfig::Application instances.
  36.  *
  37.  * Revision 1.2  1998/12/04 10:10:48  robertj
  38.  * Added virtual for determining if process is a service. Fixes linkage problem.
  39.  *
  40.  * Revision 1.1  1998/11/30 05:35:28  robertj
  41.  * Initial revision
  42.  *
  43.  */
  44. #include <ptlib.h>
  45. #include <winuser.h>
  46. #include <winnls.h>
  47. #include <process.h>
  48. #include <fcntl.h>
  49. #include <errno.h>
  50. #include <sysstat.h>
  51. #define new PNEW
  52. ///////////////////////////////////////////////////////////////////////////////
  53. // Configuration files
  54. class SecurityID
  55. {
  56.   public:
  57.     SecurityID(PSID_IDENTIFIER_AUTHORITY  pIdentifierAuthority, // pointer to identifier authority
  58.                BYTE nSubAuthorityCount, // count of subauthorities
  59.                DWORD dwSubAuthority0, // subauthority 0
  60.                DWORD dwSubAuthority1, // subauthority 1
  61.                DWORD dwSubAuthority2, // subauthority 2
  62.                DWORD dwSubAuthority3, // subauthority 3
  63.                DWORD dwSubAuthority4, // subauthority 4
  64.                DWORD dwSubAuthority5, // subauthority 5
  65.                DWORD dwSubAuthority6, // subauthority 6
  66.                DWORD dwSubAuthority7 // subauthority 7
  67.               )
  68.     {
  69.       if (!AllocateAndInitializeSid(pIdentifierAuthority, // pointer to identifier authority
  70.                                     nSubAuthorityCount, // count of subauthorities
  71.                                     dwSubAuthority0, // subauthority 0
  72.                                     dwSubAuthority1, // subauthority 1
  73.                                     dwSubAuthority2, // subauthority 2
  74.                                     dwSubAuthority3, // subauthority 3
  75.                                     dwSubAuthority4, // subauthority 4
  76.                                     dwSubAuthority5, // subauthority 5
  77.                                     dwSubAuthority6, // subauthority 6
  78.                                     dwSubAuthority7, // subauthority 7
  79.                                     &sidptr))
  80.         sidptr = NULL;
  81.     }
  82.     SecurityID(LPCTSTR lpSystemName, // address of string for system name
  83.                LPCTSTR lpAccountName, // address of string for account name
  84.                LPTSTR ReferencedDomainName, // address of string for referenced domain 
  85.                LPDWORD cbReferencedDomainName, // address of size of domain string
  86.                PSID_NAME_USE peUse  // address of SID-type indicator
  87.               )
  88.     {
  89.       DWORD len = 1024;
  90.       sidptr = (PSID)LocalAlloc(LPTR, len);
  91.       if (sidptr != NULL) {
  92.         if (!LookupAccountName(lpSystemName, // address of string for system name
  93.                                lpAccountName, // address of string for account name
  94.                                sidptr, // address of security identifier
  95.                                &len, // address of size of security identifier
  96.                                ReferencedDomainName, // address of string for referenced domain 
  97.                                cbReferencedDomainName, // address of size of domain string
  98.                                peUse  // address of SID-type indicator
  99.                               )) {
  100.           LocalFree(sidptr);
  101.           sidptr = NULL;
  102.         }
  103.       }
  104.     }
  105.     ~SecurityID()
  106.     {
  107.       FreeSid(sidptr);
  108.     }
  109.     operator PSID() const
  110.     {
  111.       return sidptr;
  112.     }
  113.     DWORD GetLength() const
  114.     {
  115.       return GetLengthSid(sidptr);
  116.     }
  117.     BOOL IsValid() const
  118.     {
  119.       return sidptr != NULL && IsValidSid(sidptr);
  120.     }
  121.   private:
  122.     PSID sidptr;
  123. };
  124. static DWORD SecureCreateKey(HKEY rootKey, const PString & subkey, HKEY & key)
  125. {
  126.   SECURITY_DESCRIPTOR secdesc;
  127.   if (!InitializeSecurityDescriptor(&secdesc, SECURITY_DESCRIPTOR_REVISION))
  128.     return GetLastError();
  129.   static SID_IDENTIFIER_AUTHORITY siaNTAuthority = SECURITY_NT_AUTHORITY;
  130.   SecurityID adminID(&siaNTAuthority, 2,
  131.                      SECURITY_BUILTIN_DOMAIN_RID,
  132.                      DOMAIN_ALIAS_RID_ADMINS, 
  133.                      0, 0, 0, 0, 0, 0);
  134.   if (!adminID.IsValid())
  135.     return GetLastError();
  136.   static SID_IDENTIFIER_AUTHORITY siaSystemAuthority = SECURITY_NT_AUTHORITY;
  137.   SecurityID systemID(&siaSystemAuthority, 1,
  138.                       SECURITY_LOCAL_SYSTEM_RID,
  139.                       0, 0, 0, 0, 0, 0, 0);
  140.   if (!systemID.IsValid())
  141.     return GetLastError();
  142.   static SID_IDENTIFIER_AUTHORITY siaCreatorAuthority = SECURITY_CREATOR_SID_AUTHORITY;
  143.   SecurityID creatorID(&siaCreatorAuthority, 1,
  144.                        SECURITY_CREATOR_OWNER_RID,
  145.                        0, 0, 0, 0, 0, 0, 0);
  146.   if (!creatorID.IsValid())
  147.     return GetLastError();
  148.   SID_NAME_USE snuType;
  149.   char szDomain[100];
  150.   DWORD cchDomainName = sizeof(szDomain);
  151.   SecurityID userID(NULL, PProcess::Current().GetUserName(),
  152.                     szDomain, &cchDomainName, &snuType);
  153.   if (!userID.IsValid())
  154.     return GetLastError();
  155.   DWORD acl_len = sizeof(ACL) + 4*sizeof(ACCESS_ALLOWED_ACE) +
  156.                     adminID.GetLength() + creatorID.GetLength() +
  157.                     systemID.GetLength() + userID.GetLength();
  158.   PBYTEArray dacl_buf(acl_len);
  159.   PACL dacl = (PACL)dacl_buf.GetPointer(acl_len);
  160.   if (!InitializeAcl(dacl, acl_len, ACL_REVISION2))
  161.     return GetLastError();
  162.   if (!AddAccessAllowedAce(dacl, ACL_REVISION2, KEY_ALL_ACCESS, adminID))
  163.     return GetLastError();
  164.   if (!AddAccessAllowedAce(dacl, ACL_REVISION2, KEY_ALL_ACCESS, systemID))
  165.     return GetLastError();
  166.   if (!AddAccessAllowedAce(dacl, ACL_REVISION2, KEY_ALL_ACCESS, creatorID))
  167.     return GetLastError();
  168.   if (!AddAccessAllowedAce(dacl, ACL_REVISION2, KEY_ALL_ACCESS, userID))
  169.     return GetLastError();
  170.   if (!SetSecurityDescriptorDacl(&secdesc, TRUE, dacl, FALSE))
  171.     return GetLastError();
  172.   SECURITY_ATTRIBUTES secattr;
  173.   secattr.nLength = sizeof(secattr);
  174.   secattr.lpSecurityDescriptor = &secdesc;
  175.   secattr.bInheritHandle = FALSE;
  176.   DWORD disposition;
  177.   return RegCreateKeyEx(rootKey, subkey, 0, "", REG_OPTION_NON_VOLATILE,
  178.                         KEY_ALL_ACCESS, &secattr, &key, &disposition);
  179. }
  180. RegistryKey::RegistryKey(const PString & subkeyname, OpenMode mode)
  181. {
  182.   PAssert(!subkeyname.IsEmpty(), PInvalidParameter);
  183.   PProcess & proc = PProcess::Current();
  184.   DWORD access = mode == ReadOnly ? KEY_READ : KEY_ALL_ACCESS;
  185.   DWORD error;
  186.   PString subkey;
  187.   HKEY basekey;
  188.   if (subkeyname.Find("HKEY_LOCAL_MACHINE\") == 0) {
  189.     subkey = subkeyname.Mid(19);
  190.     basekey = HKEY_LOCAL_MACHINE;
  191.   }
  192.   else if (subkeyname.Find("HKEY_CURRENT_USER\") == 0) {
  193.     subkey = subkeyname.Mid(18);
  194.     basekey = HKEY_CURRENT_USER;
  195.   }
  196.   else {
  197.     subkey = subkeyname;
  198.     PINDEX lastCharPos = subkey.GetLength()-1;
  199.     while (lastCharPos > 0 && subkey[lastCharPos] == '\')
  200.       subkey.Delete(lastCharPos--, 1);
  201.     basekey = NULL;
  202.     if (!proc.GetVersion(FALSE).IsEmpty()) {
  203.       PString keyname = subkey;
  204.       keyname.Replace("CurrentVersion", proc.GetVersion(FALSE));
  205.       error = RegOpenKeyEx(HKEY_CURRENT_USER, keyname, 0, access, &key);
  206.       if (error == ERROR_SUCCESS)
  207.         return;
  208.       PAssert(error != ERROR_ACCESS_DENIED, "Access denied accessing registry entry.");
  209.       error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, access, &key);
  210.       if (error == ERROR_SUCCESS)
  211.         return;
  212.       PAssert(error != ERROR_ACCESS_DENIED, "Access denied accessing registry entry.");
  213.     }
  214.     error = RegOpenKeyEx(HKEY_CURRENT_USER, subkey, 0, access, &key);
  215.     if (error == ERROR_SUCCESS)
  216.       return;
  217.     PAssert(error != ERROR_ACCESS_DENIED, "Access denied accessing registry entry.");
  218.   }
  219.   error = RegOpenKeyEx(basekey != NULL ? basekey : HKEY_LOCAL_MACHINE,
  220.                        subkey, 0, access, &key);
  221.   if (error == ERROR_SUCCESS)
  222.     return;
  223.   PAssert(error != ERROR_ACCESS_DENIED, "Access denied accessing registry entry.");
  224.   key = NULL;
  225.   if (mode != Create)
  226.     return;
  227.   if (basekey == NULL) {
  228.     if (PProcess::Current().IsServiceProcess())
  229.       basekey = HKEY_LOCAL_MACHINE;
  230.     else
  231.       basekey = HKEY_CURRENT_USER;
  232.   }
  233.   error = SecureCreateKey(basekey, subkey, key);
  234.   if (error != ERROR_SUCCESS) {
  235.     DWORD disposition;
  236.     error = RegCreateKeyEx(basekey, subkey, 0, "", REG_OPTION_NON_VOLATILE,
  237.                            KEY_ALL_ACCESS, NULL, &key, &disposition);
  238.     if (error != ERROR_SUCCESS)
  239.       key = NULL;
  240.   }
  241. }
  242. RegistryKey::~RegistryKey()
  243. {
  244.   if (key != NULL)
  245.     RegCloseKey(key);
  246. }
  247. BOOL RegistryKey::EnumKey(PINDEX idx, PString & str)
  248. {
  249.   if (key == NULL)
  250.     return FALSE;
  251.   if (RegEnumKey(key, idx, str.GetPointer(MAX_PATH),MAX_PATH) != ERROR_SUCCESS)
  252.     return FALSE;
  253.   str.MakeMinimumSize();
  254.   return TRUE;
  255. }
  256. BOOL RegistryKey::EnumValue(PINDEX idx, PString & str)
  257. {
  258.   if (key == NULL)
  259.     return FALSE;
  260.   DWORD sizeofname = MAX_PATH;
  261.   if (RegEnumValue(key, idx, str.GetPointer(sizeofname),
  262.                          &sizeofname, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
  263.     return FALSE;
  264.   str.MakeMinimumSize();
  265.   return TRUE;
  266. }
  267. BOOL RegistryKey::DeleteKey(const PString & subkey)
  268. {
  269.   if (key == NULL)
  270.     return TRUE;
  271.   return RegDeleteKey(key, subkey) == ERROR_SUCCESS;
  272. }
  273. BOOL RegistryKey::DeleteValue(const PString & value)
  274. {
  275.   if (key == NULL)
  276.     return TRUE;
  277.   return RegDeleteValue(key, (char *)(const char *)value) == ERROR_SUCCESS;
  278. }
  279. BOOL RegistryKey::QueryValue(const PString & value, PString & str)
  280. {
  281.   if (key == NULL)
  282.     return FALSE;
  283.   DWORD type, size;
  284.   if (RegQueryValueEx(key, (char *)(const char *)value,
  285.                                     NULL, &type, NULL, &size) != ERROR_SUCCESS)
  286.     return FALSE;
  287.   switch (type) {
  288.     case REG_SZ :
  289.     case REG_MULTI_SZ :
  290.     case REG_EXPAND_SZ :
  291.     case REG_BINARY :
  292.       return RegQueryValueEx(key, (char *)(const char *)value, NULL,
  293.                   &type, (LPBYTE)str.GetPointer(size), &size) == ERROR_SUCCESS;
  294.     case REG_DWORD : {
  295.       DWORD num;
  296.       size = sizeof(num);
  297.       if (RegQueryValueEx(key, (char *)(const char *)value, NULL,
  298.                                 &type, (LPBYTE)&num, &size) == ERROR_SUCCESS) {
  299.         str = PString(PString::Signed, num);
  300.         return TRUE;
  301.       }
  302.     }
  303.     default :
  304.       PAssertAlways("Unsupported registry type.");
  305.   }
  306.   return FALSE;
  307. }
  308. BOOL RegistryKey::QueryValue(const PString & value, DWORD & num, BOOL boolean)
  309. {
  310.   if (key == NULL)
  311.     return FALSE;
  312.   DWORD type, size;
  313.   if (RegQueryValueEx(key, (char *)(const char *)value,
  314.                                     NULL, &type, NULL, &size) != ERROR_SUCCESS)
  315.     return FALSE;
  316.   switch (type) {
  317.     case REG_BINARY :
  318.       if (size > sizeof(DWORD))
  319.         return FALSE;
  320.       num = 0;
  321.       // Do REG_DWORD case
  322.     case REG_DWORD :
  323.       return RegQueryValueEx(key, (char *)(const char *)value, NULL,
  324.                                   &type, (LPBYTE)&num, &size) == ERROR_SUCCESS;
  325.     case REG_SZ : {
  326.       PString str;
  327.       if (RegQueryValueEx(key, (char *)(const char *)value, NULL,
  328.                 &type, (LPBYTE)str.GetPointer(size), &size) == ERROR_SUCCESS) {
  329.         num = str.AsInteger();
  330.         if (num == 0 && boolean) {
  331.           int c = toupper(str[0]);
  332.           num = c == 'T' || c == 'Y';
  333.         }
  334.         return TRUE;
  335.       }
  336.       break;
  337.     }
  338.     default :
  339.       PAssertAlways("Unsupported registry type.");
  340.   }
  341.   return FALSE;
  342. }
  343. BOOL RegistryKey::SetValue(const PString & value, const PString & str)
  344. {
  345.   if (key == NULL)
  346.     return FALSE;
  347.   return RegSetValueEx(key, (char *)(const char *)value, 0, REG_SZ,
  348.                 (LPBYTE)(const char *)str, str.GetLength()+1) == ERROR_SUCCESS;
  349. }
  350. BOOL RegistryKey::SetValue(const PString & value, DWORD num)
  351. {
  352.   if (key == NULL)
  353.     return FALSE;
  354.   return RegSetValueEx(key, (char *)(const char *)value,
  355.                      0, REG_DWORD, (LPBYTE)&num, sizeof(num)) == ERROR_SUCCESS;
  356. }
  357. void PConfig::Construct(Source src, const PString & appname, const PString & manuf)
  358. {
  359.   switch (src) {
  360.     case System :
  361.       source = Application;
  362.       if (appname.Find("HKEY_LOCAL_MACHINE\") == 0)
  363.         location = appname;
  364.       else if (appname.Find("HKEY_CURRENT_USER\") == 0)
  365.         location = appname;
  366.       else {
  367.         PString dir;
  368.         GetWindowsDirectory(dir.GetPointer(_MAX_PATH), _MAX_PATH);
  369.         Construct(PDirectory(dir)+"WIN.INI");
  370.       }
  371.       break;
  372.     case Application :
  373.       if (defaultSection.Find("HKEY_LOCAL_MACHINE\") == 0 || 
  374.           defaultSection.Find("HKEY_CURRENT_USER\") == 0)
  375.         source = Application;
  376.       else {
  377.         PProcess & proc = PProcess::Current();
  378.         PFilePath appFile = proc.GetFile();
  379.         PFilePath cfgFile = appFile.GetVolume() + appFile.GetPath() + appFile.GetTitle() + ".INI";
  380.         if (PFile::Exists(cfgFile))
  381.           Construct(cfgFile); // Make a file based config
  382.         else {
  383.           location = "SOFTWARE\";
  384.           if (!manuf)
  385.             location += manuf;
  386.           else if (!proc.GetManufacturer())
  387.             location += proc.GetManufacturer();
  388.           else
  389.             location += "PWLib";
  390.           location += PDIR_SEPARATOR;
  391.           if (appname.IsEmpty())
  392.             location += proc.GetName();
  393.           else
  394.             location += appname;
  395.           location += "\CurrentVersion\";
  396.           source = Application;
  397.         }
  398.       }
  399.       break;
  400.     default :
  401.       source = src;
  402.   }
  403. }
  404. void PConfig::Construct(const PFilePath & filename)
  405. {
  406.   location = filename;
  407.   source = NumSources;
  408. }
  409. static void RecurseRegistryKeys(const PString & location,
  410.                                 PINDEX baseLength,
  411.                                 PStringList &sections)
  412. {
  413.   RegistryKey registry(location, RegistryKey::ReadOnly);
  414.   PString name;
  415.   for (PINDEX idx = 0; registry.EnumKey(idx, name); idx++) {
  416.     RecurseRegistryKeys(location + name + '\', baseLength, sections);
  417.     sections.AppendString(location.Mid(baseLength) + name);
  418.   }
  419. }
  420. PStringList PConfig::GetSections() const
  421. {
  422.   PStringList sections;
  423.   switch (source) {
  424.     case Application :
  425.       RecurseRegistryKeys(location, location.GetLength(), sections);
  426.       break;
  427.     case NumSources :
  428.       PString buf;
  429.       char * ptr = buf.GetPointer(10000);
  430.       GetPrivateProfileString(NULL, NULL, "", ptr, 9999, location);
  431.       while (*ptr != '') {
  432.         sections.AppendString(ptr);
  433.         ptr += strlen(ptr)+1;
  434.       }
  435.       break;
  436.   }
  437.   return sections;
  438. }
  439. PStringList PConfig::GetKeys(const PString & section) const
  440. {
  441.   PStringList keys;
  442.   switch (source) {
  443.     case Environment : {
  444.       char ** ptr = _environ;
  445.       while (*ptr != NULL) {
  446.         PString buf = *ptr++;
  447.         keys.AppendString(buf.Left(buf.Find('=')));
  448.       }
  449.       break;
  450.     }
  451.     case Application : {
  452.       PAssert(!section.IsEmpty(), PInvalidParameter);
  453.       RegistryKey registry(location + section, RegistryKey::ReadOnly);
  454.       PString name;
  455.       for (PINDEX idx = 0; registry.EnumValue(idx, name); idx++)
  456.         keys.AppendString(name);
  457.       break;
  458.     }
  459.     case NumSources :
  460.       PAssert(!section.IsEmpty(), PInvalidParameter);
  461.       PString buf;
  462.       char * ptr = buf.GetPointer(10000);
  463.       GetPrivateProfileString(section, NULL, "", ptr, 9999, location);
  464.       while (*ptr != '') {
  465.         keys.AppendString(ptr);
  466.         ptr += strlen(ptr)+1;
  467.       }
  468.   }
  469.   return keys;
  470. }
  471. void PConfig::DeleteSection(const PString & section)
  472. {
  473.   switch (source) {
  474.     case Application : {
  475.       PAssert(!section.IsEmpty(), PInvalidParameter);
  476.       RegistryKey registry(location, RegistryKey::ReadWrite);
  477.       registry.DeleteKey(section);
  478.       break;
  479.     }
  480.     case NumSources :
  481.       PAssert(!section.IsEmpty(), PInvalidParameter);
  482.       PAssertOS(WritePrivateProfileString(section, NULL, NULL, location));
  483.   }
  484. }
  485. void PConfig::DeleteKey(const PString & section, const PString & key)
  486. {
  487.   PAssert(!key.IsEmpty(), PInvalidParameter);
  488.   switch (source) {
  489.     case Environment :
  490.       PAssert(key.Find('=') == P_MAX_INDEX, PInvalidParameter);
  491.       putenv(key + "=");
  492.       break;
  493.     case Application : {
  494.       PAssert(!section.IsEmpty(), PInvalidParameter);
  495.       RegistryKey registry(location + section, RegistryKey::ReadWrite);
  496.       registry.DeleteValue(key);
  497.       break;
  498.     }
  499.     case NumSources :
  500.       PAssert(!section.IsEmpty(), PInvalidParameter);
  501.       PAssertOS(WritePrivateProfileString(section, key, NULL, location));
  502.   }
  503. }
  504. BOOL PConfig::HasKey(const PString & section, const PString & key) const
  505. {
  506.   PAssert(!key.IsEmpty(), PInvalidParameter);
  507.   switch (source) {
  508.     case Environment :
  509.       return getenv(key) != NULL;
  510.     case Application : {
  511.       PAssert(!section.IsEmpty(), PInvalidParameter);
  512.       RegistryKey registry(location + section, RegistryKey::ReadOnly);
  513.       PString dummy;
  514.       return registry.QueryValue(key, dummy);
  515.     }
  516.     case NumSources :
  517.       PAssert(!section.IsEmpty(), PInvalidParameter);
  518.       static const char dflt[] = "<<<<<====---PConfig::DefaultValueString---====>>>>>";
  519.       PString str;
  520.       GetPrivateProfileString(section, key, dflt,
  521.                                         str.GetPointer(1000), 999, location);
  522.       return str != dflt;
  523.   }
  524.   return FALSE;
  525. }
  526. PString PConfig::GetString(const PString & section,
  527.                                const PString & key, const PString & dflt) const
  528. {
  529.   PAssert(!key.IsEmpty(), PInvalidParameter);
  530.   PString str;
  531.   switch (source) {
  532.     case Environment : {
  533.       PAssert(key.Find('=') == P_MAX_INDEX, PInvalidParameter);
  534.       char * env = getenv(key);
  535.       if (env != NULL)
  536.         str = env;
  537.       else
  538.         str = dflt;
  539.       break;
  540.     }
  541.     case Application : {
  542.       PAssert(!section.IsEmpty(), PInvalidParameter);
  543.       RegistryKey registry(location + section, RegistryKey::ReadOnly);
  544.       if (!registry.QueryValue(key, str))
  545.         str = dflt;
  546.       break;
  547.     }
  548.     case NumSources :
  549.       PAssert(!section.IsEmpty(), PInvalidParameter);
  550.       GetPrivateProfileString(section, key, dflt,
  551.                                         str.GetPointer(1000), 999, location);
  552.       str.MakeMinimumSize();
  553.   }
  554.   return str;
  555. }
  556. void PConfig::SetString(const PString & section,
  557.                                     const PString & key, const PString & value)
  558. {
  559.   PAssert(!key.IsEmpty(), PInvalidParameter);
  560.   switch (source) {
  561.     case Environment :
  562.       PAssert(key.Find('=') == P_MAX_INDEX, PInvalidParameter);
  563.       putenv(key + "=" + value);
  564.       break;
  565.     case Application : {
  566.       PAssert(!section.IsEmpty(), PInvalidParameter);
  567.       RegistryKey registry(location + section, RegistryKey::Create);
  568.       registry.SetValue(key, value);
  569.       break;
  570.     }
  571.     case NumSources :
  572.       PAssert(!section.IsEmpty(), PInvalidParameter);
  573.       PAssertOS(WritePrivateProfileString(section, key, value, location));
  574.   }
  575. }
  576. BOOL PConfig::GetBoolean(const PString & section,
  577.                                           const PString & key, BOOL dflt) const
  578. {
  579.   if (source != Application) {
  580.     PString str = GetString(section, key, dflt ? "T" : "F").ToUpper();
  581.     int c = toupper(str[0]);
  582.     return c == 'T' || c == 'Y' || str.AsInteger() != 0;
  583.   }
  584.   PAssert(!section.IsEmpty(), PInvalidParameter);
  585.   RegistryKey registry(location + section, RegistryKey::ReadOnly);
  586.   DWORD value;
  587.   if (!registry.QueryValue(key, value, TRUE))
  588.     return dflt;
  589.   return value != 0;
  590. }
  591. void PConfig::SetBoolean(const PString & section, const PString & key, BOOL value)
  592. {
  593.   if (source != Application)
  594.     SetString(section, key, value ? "True" : "False");
  595.   else {
  596.     PAssert(!section.IsEmpty(), PInvalidParameter);
  597.     RegistryKey registry(location + section, RegistryKey::Create);
  598.     registry.SetValue(key, value ? 1 : 0);
  599.   }
  600. }
  601. long PConfig::GetInteger(const PString & section,
  602.                                           const PString & key, long dflt) const
  603. {
  604.   if (source != Application) {
  605.     PString str(PString::Signed, dflt);
  606.     return GetString(section, key, str).AsInteger();
  607.   }
  608.   PAssert(!section.IsEmpty(), PInvalidParameter);
  609.   RegistryKey registry(location + section, RegistryKey::ReadOnly);
  610.   DWORD value;
  611.   if (!registry.QueryValue(key, value, FALSE))
  612.     return dflt;
  613.   return value;
  614. }
  615. void PConfig::SetInteger(const PString & section, const PString & key, long value)
  616. {
  617.   if (source != Application) {
  618.     PString str(PString::Signed, value);
  619.     SetString(section, key, str);
  620.   }
  621.   else {
  622.     PAssert(!section.IsEmpty(), PInvalidParameter);
  623.     RegistryKey registry(location + section, RegistryKey::Create);
  624.     registry.SetValue(key, value);
  625.   }
  626. }
  627. // End Of File ///////////////////////////////////////////////////////////////