home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
xwphescr.zip
/
XWPH0208.ZIP
/
src
/
helpers
/
prfh.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-07-28
|
19KB
|
576 lines
/*
*@@sourcefile prfh.c:
* contains those Presentation Manager helper functions
* which deal with Profile (Prf*) functions.
* This file is new with V0.82.
*
* Usage: All OS/2 programs.
*
* Function prefixes:
* -- prfh* Prf (profile, INI) helper functions
*
* Note: Version numbering in this file relates to XWorkplace version
* numbering.
*
*@@header "helpers\prfh.h"
*/
/*
* Copyright (C) 1997-2000 Ulrich Möller.
* This file is part of the "XWorkplace helpers" source package.
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, in version 2 as it comes in the
* "COPYING" file of the XWorkplace main distribution.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define OS2EMX_PLAIN_CHAR
// this is needed for "os2emx.h"; if this is defined,
// emx will define PSZ as _signed_ char, otherwise
// as unsigned char
#define INCL_DOSERRORS
#define INCL_WINSHELLDATA
#include <os2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "setup.h" // code generation and debugging options
#define INCLUDE_PRFH_PRIVATE
#include "helpers\prfh.h"
#pragma hdrstop
/*
*@@category: Helpers\Profile (INI) helpers
*/
/*
*@@ prfhQueryKeysForApp:
* returns the keys list for an INI application. This
* list is copied into a newly allocated buffer, of which
* the address is returned.
*
* Returns NULL upon errors.
*
* If the return value is != NULL, the PSZ points to a new
* buffer which contains all the keys within the pszApp
* application. Each key name in the list is terminated with
* a null character. The last string in the list is terminated
* with two null characters.
*
* The returned buffer should be freed later using free().
*
* <B>Example</B> for iterating over a keys list:
*
+ PSZ pszKeysList = prfhQueryKeysForApp(...);
+ if (pszKeysList)
+ {
+ PSZ pKey2 = pszKeysList;
+
+ while (*pKey2 != 0)
+ {
+ ... // pKey2 has the current key now
+ pKey2 += strlen(pKey2)+1; // next key
+ }
+ free(pszKeysList);
+ }
*
* You can also use this function to query the applications
* list for hIni, if you specifiy pszApp as NULL.
*
*@@changed V0.9.12 (2001-05-12) [umoeller]: changed prototypes to return APIRET now
*@@changed V0.9.19 (2002-04-11) [pr]: Fixed app. with no keys
*/
APIRET prfhQueryKeysForApp(HINI hIni, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
const char *pcszApp, // in: application to query list for (or NULL for applications list)
PSZ *ppszKeys) // out: keys list (newly allocated)
{
APIRET arc = NO_ERROR;
PSZ pKeys = NULL;
ULONG ulSizeOfKeysList = 0;
// get size of keys list for pszApp
if (!PrfQueryProfileSize(hIni, (PSZ)pcszApp, NULL, &ulSizeOfKeysList))
arc = PRFERR_KEYSLIST;
else
{
if (ulSizeOfKeysList == 0)
ulSizeOfKeysList = 1; // V0.9.19 (2002-04-11) [pr]
if (!(pKeys = (PSZ)malloc(ulSizeOfKeysList)))
arc = ERROR_NOT_ENOUGH_MEMORY;
else
{
*pKeys = 0;
if (!PrfQueryProfileData(hIni, (PSZ)pcszApp, NULL, pKeys, &ulSizeOfKeysList))
arc = PRFERR_KEYSLIST;
}
}
if (!arc) // V0.9.12 (2001-05-12) [umoeller]
*ppszKeys = pKeys;
else
if (pKeys)
free(pKeys);
return arc;
}
#ifdef __DEBUG_MALLOC_ENABLED__ // setup.h, helpers\memdebug.c
/*
*@@ prfhQueryProfileDataDebug:
* debug version of prfhQueryProfileData, which is
* automatically mapped to if __XWPMEMDEBUG__ is defined.
*
*@@added V0.9.1 (99-12-20) [umoeller]
*@@changed V0.9.3 (2000-04-20) [umoeller]: this called malloc(0) if the key existed, but was empty. Fixed.
*/
PSZ (prfhQueryProfileDataDebug)(HINI hIni, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
const char *pcszApp, // in: application to query
const char *pcszKey, // in: key to query
PULONG pcbBuf, // out: size of the returned buffer
const char *file,
unsigned long line,
const char *function)
{
PSZ pData = NULL;
ULONG ulSizeOfData = 0;
// get size of data for pszApp/pszKey
if (PrfQueryProfileSize(hIni, (PSZ)pcszApp, (PSZ)pcszKey, &ulSizeOfData))
{
if (ulSizeOfData)
{
pData = (PSZ)memdMalloc(ulSizeOfData, file, line, function);
if (!PrfQueryProfileData(hIni, (PSZ)pcszApp, (PSZ)pcszKey, pData, &ulSizeOfData))
{
free(pData);
pData = NULL;
}
}
}
if (pcbBuf)
*pcbBuf = ulSizeOfData;
return (pData);
}
#else
/*
*@@ prfhQueryProfileData:
* similar to PrfQueryProfileData, but this one copies
* the data into a newly allocated buffer, of which the
* address is returned.
*
* Returns NULL upon errors, for example if the specified
* key doesn't exist or doesn't contain any data.
*
* If pcbBuf != NULL, this func will write the size of
* the allocated buffer into *pcbBuf.
*
* The returned buffer should be freed later using free().
*
*@@added V0.9.0 [umoeller]
*@@changed V0.9.3 (2000-04-20) [umoeller]: this called malloc(0) if the key existed, but was empty. Fixed.
*/
PSZ (prfhQueryProfileData)(HINI hIni, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
const char *pcszApp, // in: application to query
const char *pcszKey, // in: key to query
PULONG pcbBuf) // out: size of the returned buffer; ptr can be NULL
{
PSZ pData = NULL;
ULONG ulSizeOfData;
// get size of data for pszApp/pszKey
if ( (PrfQueryProfileSize(hIni, (PSZ)pcszApp, (PSZ)pcszKey, &ulSizeOfData))
&& (ulSizeOfData)
&& (pData = (PSZ)malloc(ulSizeOfData))
)
{
if (!PrfQueryProfileData(hIni, (PSZ)pcszApp, (PSZ)pcszKey, pData, &ulSizeOfData))
{
free(pData);
pData = NULL;
}
}
if (pcbBuf)
*pcbBuf = ulSizeOfData;
return (pData);
}
#endif
/*
*@@ prfhQueryProfileChar:
* this query the first character of profile data.
* This is mostly useful with the PM country settings
* in OS2.INI:
* -- date separator: "PM_National", "sDate"
* -- time separator: "PM_National", "sTime"
*/
CHAR prfhQueryProfileChar(HINI hini, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
const char *pcszApp, // in: application to query
const char *pcszKey, // in: key to query
CHAR cDefault) // in: default to return if not found
{
CHAR szTemp[5],
szDefault[5];
szDefault[0] = cDefault;
szDefault[1] = 0;
PrfQueryProfileString(HINI_USER, (PSZ)pcszApp, (PSZ)pcszKey,
szDefault,
szTemp, sizeof(szTemp)-1);
return (szTemp[0]);
}
/*
*@@ prfhQueryColor:
* returns a system color in OS2.INI's PM_Colors as a LONG.
*/
LONG prfhQueryColor(const char *pcszKeyName,
const char *pcszDefault)
{
CHAR szColor[30];
ULONG r, g, b;
PrfQueryProfileString(
HINI_USER,
"PM_Colors",
(PSZ)pcszKeyName,
(PSZ)pcszDefault,
szColor,
sizeof(szColor)-1);
sscanf(szColor, "%lu %lu %lu ", &r, &g, &b);
return (LONG)(r*0x10000 + g*0x100 + b);
}
/*
*@@ prfhCopyKey:
* this copies one key from the given profile and application
* to another one.
*
* pszTargetApp may be in the same profile (and must be
* different from pszSourceApp then) or in a different
* profile (and can be the same then).
*
* You must specify all parameters. You cannot specify pszKey
* as NULL to have a whole application copied. Use prfhCopyApp
* for that.
* No check is made for this.
*
* Returns:
* -- 0: no error
*
* -- PRFERR_DATASIZE: couldn't query data size for key
*
* -- PRFERR_MEMORY: couldn't allocate memory
*
* -- PRFERR_READ: couldn't read data from source (PrfQueryProfileData error)
*
* -- PRFERR_WRITE: couldn't write data to target (PrfWriteProfileData error)
*
*@@added V0.9.0 [umoeller]
*/
APIRET prfhCopyKey(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
const char *pcszSourceApp, // in: source application
const char *pcszKey, // in: source/target key
HINI hiniTarget, // in: target profile (can be HINI_USER or HINI_SYSTEM)
const char *pcszTargetApp) // in: target app
{
ULONG ulSizeOfData = 0,
ulrc = 0; // return: no error
if (PrfQueryProfileSize(hiniSource, (PSZ)pcszSourceApp, (PSZ)pcszKey, &ulSizeOfData))
{
PSZ pData = 0;
// copy data
if (ulSizeOfData == 0)
{
// data size == 0: this shouldn't really happen,
// but if it does, we'll just create a NULL string.
// Users have reported that some INI files seem to
// contain those "empty" keys. I don't see how these
// can exist, but they seem to...
pData = (PSZ)malloc(1);
*pData = 0;
}
else
pData = (PSZ)malloc(ulSizeOfData);
if (pData)
{
if (PrfQueryProfileData(hiniSource,
(PSZ)pcszSourceApp,
(PSZ)pcszKey,
pData,
&ulSizeOfData))
{
if (!PrfWriteProfileData(hiniTarget,
(PSZ)pcszTargetApp,
(PSZ)pcszKey,
pData,
ulSizeOfData))
ulrc = PRFERR_WRITE;
}
else
ulrc = PRFERR_READ;
free(pData);
}
else
ulrc = ERROR_NOT_ENOUGH_MEMORY;
}
else
ulrc = PRFERR_DATASIZE;
return (ulrc);
}
/*
*@@ prfhCopyApp:
* this copies one key from the given profile and application
* to another one.
*
* You can use this function in several contexts:
*
* -- copy one application within the same profile
* (i.e. hiniSource == hiniTarget);
* in this case, pszSourceApp must be != pszTargetApp;
*
* -- copy an application from one profile to another
* (i.e. hiniSource != hiniTarget);
* in this case, pszSourceApp can be == pszTargetApp
* (but can be different also).
*
* WARNING: This does _not_ check for whether the target
* application exists already. This has two consequences:
*
* -- existing data will be overwritten without warning;
*
* -- if the existing target application has keys that are
* not in the source application, they are not deleted.
* As a result, you might end up with more keys than
* in the source application.
*
* So you should delete the target application before
* calling this function, like this:
*
+ PrfWriteProfileString(hiniTarget, pszTargetApp, NULL, NULL);
*
* You must specify all parameters. You cannot specify pszApp
* as NULL to have a whole profile copied. Use prfhCopyProfile
* for that.
* No check is made for this.
*
* Returns:
*
* -- 0: no error
*
* -- PRFERR_KEYSLIST: couldn't query keys for pszSourceApp
*
* -- PRFERR_DATASIZE: couldn't query data size for key
*
* -- PRFERR_MEMORY: couldn't allocate memory
*
* -- PRFERR_READ: couldn't read data from source (PrfQueryProfileData error)
*
* -- PRFERR_WRITE: couldn't write data to target (PrfWriteProfileData error)
*
*@@added V0.9.0 [umoeller]
*/
APIRET prfhCopyApp(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
const char *pcszSourceApp, // in: source application
HINI hiniTarget, // in: target profile (can be HINI_USER or HINI_SYSTEM)
const char *pcszTargetApp, // in: name of pszSourceApp in hiniTarget
PSZ pszErrorKey) // out: failing key in case of error; ptr can be NULL
{
APIRET arc = NO_ERROR;
PSZ pszKeysList = NULL;
if (pszErrorKey)
*pszErrorKey = 0;
if (!(arc = prfhQueryKeysForApp(hiniSource,
(PSZ)pcszSourceApp,
&pszKeysList)))
{
PSZ pKey2 = pszKeysList;
while (*pKey2 != 0)
{
// copy this key
arc = prfhCopyKey(hiniSource,
pcszSourceApp,
pKey2,
hiniTarget,
pcszTargetApp);
if (arc)
{
// error: copy failing key to buffer
if (pszErrorKey)
strcpy(pszErrorKey, pKey2);
break;
}
pKey2 += strlen(pKey2)+1;
} // end while (*pKey2 != 0)
free (pszKeysList);
}
return arc;
}
/*
*@@ prfhRenameKey:
* renames a key in an INI file.
*
* Since there's no such thing as a PrfRename,
* what we do here is load the old data, write
* it under a new key, and delete the old data.
*
* Returns:
*
* -- 0: no error
*
* -- PRFERR_INVALID_KEY: pcszApp or pcszOldKey do not exist.
*
* -- PRFERR_KEY_EXISTS: pcszNewApp/pcszNewKey is already occupied.
*
* -- PRFERR_WRITE: couldn't write data to target (PrfWriteProfileData error)
*
*@@added V0.9.9 (2001-02-06) [umoeller]
*/
ULONG prfhRenameKey(HINI hini,
const char *pcszOldApp,
const char *pcszOldKey, // in: key to rename
const char *pcszNewApp, // in: new app (if NULL, pcszOldApp is used)
const char *pcszNewKey) // in: new name for pcszOldKey
{
ULONG ulrc = 0;
ULONG cbData = 0;
PSZ pszData = prfhQueryProfileData(hini,
pcszOldApp,
pcszOldKey,
&cbData);
if (!pszData)
// not found:
ulrc = PRFERR_INVALID_KEY;
else
{
ULONG cb;
if (!pcszNewApp)
// is NULL:
pcszNewApp = pcszOldApp;
// make sure target doesn't exist
if ( (PrfQueryProfileSize(hini,
(PSZ)pcszNewApp,
(PSZ)pcszNewKey,
&cb))
&& (cb)
)
ulrc = PRFERR_KEY_EXISTS;
else
{
if (!PrfWriteProfileData(hini,
(PSZ)pcszNewApp,
(PSZ)pcszNewKey,
pszData,
cbData))
ulrc = PRFERR_WRITE;
else
{
// success writing:
// delete old
PrfWriteProfileData(hini,
(PSZ)pcszOldApp,
(PSZ)pcszOldKey,
NULL,
0);
}
}
free(pszData);
}
return (ulrc);
}
/*
*@@ prfhSetUserProfile:
* calls PrfReset to change the current user
* profile (normally OS2.INI) to the specified
* INI file.
*
*@@added V0.9.4 (2000-07-19) [umoeller]
*@@changed V0.9.19 (2002-04-02) [umoeller]: now returning APIRET
*/
APIRET prfhSetUserProfile(HAB hab,
const char *pcszUserProfile) // in: new user profile (.INI)
{
APIRET arc = NO_ERROR;
// find out current profile names
PRFPROFILE Profiles;
Profiles.cchUserName = Profiles.cchSysName = 0;
// first query their file name lengths
if (PrfQueryProfile(hab, &Profiles))
{
// allocate memory for filenames
Profiles.pszUserName = (PSZ)malloc(Profiles.cchUserName);
Profiles.pszSysName = (PSZ)malloc(Profiles.cchSysName);
if ((Profiles.pszSysName) && (Profiles.pszUserName))
{
// get filenames
if (PrfQueryProfile(hab, &Profiles))
{
// _Pmpf(("Old user profile: %s", Profiles.pszUserName));
// change INIs
free(Profiles.pszUserName);
Profiles.pszUserName = (PSZ)pcszUserProfile;
Profiles.cchUserName = strlen(pcszUserProfile) + 1;
if (!PrfReset(hab, &Profiles))
arc = PRFERR_RESET;
free(Profiles.pszSysName);
}
else
arc = PRFERR_QUERY;
}
else
arc = PRFERR_QUERY;
}
else
arc = PRFERR_QUERY;
return arc;
}