source: trunk/src/helpers/prfh.c@ 22

Last change on this file since 22 was 22, checked in by umoeller, 25 years ago

Misc. updates.

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 16.4 KB
Line 
1
2/*
3 *@@sourcefile prfh.c:
4 * contains those Presentation Manager helper functions
5 * which deal with Profile (Prf*) functions.
6 * This file is new with V0.82.
7 *
8 * Usage: All OS/2 programs.
9 *
10 * Function prefixes:
11 * -- prfh* Prf (profile, INI) helper functions
12 *
13 * Note: Version numbering in this file relates to XWorkplace version
14 * numbering.
15 *
16 *@@header "helpers\prfh.h"
17 */
18
19/*
20 * Copyright (C) 1997-2000 Ulrich M”ller.
21 * This file is part of the "XWorkplace helpers" source package.
22 * This is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License as published
24 * by the Free Software Foundation, in version 2 as it comes in the
25 * "COPYING" file of the XWorkplace main distribution.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 */
31
32#define OS2EMX_PLAIN_CHAR
33 // this is needed for "os2emx.h"; if this is defined,
34 // emx will define PSZ as _signed_ char, otherwise
35 // as unsigned char
36
37#define INCL_DOSERRORS
38#define INCL_WINSHELLDATA
39#include <os2.h>
40
41#include <stdlib.h>
42#include <stdio.h>
43#include <string.h>
44
45#include "setup.h" // code generation and debugging options
46
47#include "helpers\prfh.h"
48
49#pragma hdrstop
50
51/*
52 *@@category: Helpers\Profile (INI) helpers
53 */
54
55/*
56 *@@ prfhQueryKeysForApp:
57 * returns the keys list for an INI application. This
58 * list is copied into a newly allocated buffer, of which
59 * the address is returned.
60 *
61 * Returns NULL upon errors.
62 *
63 * If the return value is != NULL, the PSZ points to a new
64 * buffer which contains all the keys within the pszApp
65 * application. Each key name in the list is terminated with
66 * a null character. The last string in the list is terminated
67 * with two null characters.
68 *
69 * The returned buffer should be freed later using free().
70 *
71 * <B>Example</B> for iterating over a keys list:
72 + PSZ pszKeysList = prfhQueryKeysForApp(...);
73 + if (pszKeysList)
74 + {
75 + PSZ pKey2 = pszKeysList;
76 +
77 + while (*pKey2 != 0)
78 + {
79 + ... // pKey2 has the current key now
80 + pKey2 += strlen(pKey2)+1; // next key
81 + }
82 + free(pszKeysList);
83 + }
84 *
85 * You can also use this function to query the applications
86 * list for hIni, if you specifiy pszApp as NULL.
87 */
88
89PSZ prfhQueryKeysForApp(HINI hIni, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
90 const char *pcszApp) // in: application to query list for (or NULL for applications list)
91{
92 PSZ pKeys = NULL;
93 ULONG ulSizeOfKeysList = 0;
94
95 // get size of keys list for pszApp
96 if (PrfQueryProfileSize(hIni, (PSZ)pcszApp, NULL, &ulSizeOfKeysList))
97 {
98 pKeys = (PSZ)malloc(ulSizeOfKeysList);
99 if (!PrfQueryProfileData(hIni, (PSZ)pcszApp, NULL, pKeys, &ulSizeOfKeysList))
100 {
101 free(pKeys);
102 pKeys = NULL;
103 }
104 }
105 return (pKeys);
106}
107
108#ifdef __XWPMEMDEBUG__ // setup.h, helpers\memdebug.c
109
110/*
111 *@@ prfhQueryProfileDataDebug:
112 * debug version of prfhQueryProfileData, which is
113 * automatically mapped to if __XWPMEMDEBUG__ is defined.
114 *
115 *@@added V0.9.1 (99-12-20) [umoeller]
116 *@@changed V0.9.3 (2000-04-20) [umoeller]: this called malloc(0) if the key existed, but was empty. Fixed.
117 */
118
119PSZ prfhQueryProfileDataDebug(HINI hIni, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
120 const char *pcszApp, // in: application to query
121 const char *pcszKey, // in: key to query
122 PULONG pcbBuf, // out: size of the returned buffer
123 const char *file,
124 unsigned long line,
125 const char *function)
126{
127 PSZ pData = NULL;
128 ULONG ulSizeOfData = 0;
129
130 // get size of data for pszApp/pszKey
131 if (PrfQueryProfileSize(hIni, (PSZ)pcszApp, (PSZ)pcszKey, &ulSizeOfData))
132 {
133 if (ulSizeOfData)
134 {
135 pData = (PSZ)memdMalloc(ulSizeOfData, file, line, function);
136 if (!PrfQueryProfileData(hIni, (PSZ)pcszApp, (PSZ)pcszKey, pData, &ulSizeOfData))
137 {
138 free(pData);
139 pData = NULL;
140 }
141 }
142 }
143
144 if (pcbBuf)
145 *pcbBuf = ulSizeOfData;
146
147 return (pData);
148}
149
150#else
151
152/*
153 *@@ prfhQueryProfileData:
154 * similar to PrfQueryProfileData, but this one copies
155 * the data into a newly allocated buffer, of which the
156 * address is returned.
157 *
158 * Returns NULL upon errors, for example if the specified
159 * key doesn't exist or doesn't contain any data.
160 *
161 * If pcbBuf != NULL, this func will write the size of
162 * the allocated buffer into *pcbBuf.
163 *
164 * The returned buffer should be freed later using free().
165 *
166 *@@added V0.9.0 [umoeller]
167 *@@changed V0.9.3 (2000-04-20) [umoeller]: this called malloc(0) if the key existed, but was empty. Fixed.
168 */
169
170PSZ prfhQueryProfileData(HINI hIni, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
171 const char *pcszApp, // in: application to query
172 const char *pcszKey, // in: key to query
173 PULONG pcbBuf) // out: size of the returned buffer; ptr can be NULL
174{
175 PSZ pData = NULL;
176 ULONG ulSizeOfData = 0;
177
178 // get size of data for pszApp/pszKey
179 if (PrfQueryProfileSize(hIni, (PSZ)pcszApp, (PSZ)pcszKey, &ulSizeOfData))
180 {
181 if (ulSizeOfData)
182 {
183 pData = (PSZ)malloc(ulSizeOfData);
184 if (!PrfQueryProfileData(hIni, (PSZ)pcszApp, (PSZ)pcszKey, pData, &ulSizeOfData))
185 {
186 free(pData);
187 pData = NULL;
188 }
189 }
190 }
191
192 if (pcbBuf)
193 *pcbBuf = ulSizeOfData;
194
195 return (pData);
196}
197
198#endif
199
200/*
201 *@@ prfhQueryProfileChar:
202 * this query the first character of profile data.
203 * This is mostly useful with the PM country settings
204 * in OS2.INI:
205 * -- date separator: "PM_National", "sDate"
206 * -- time separator: "PM_National", "sTime"
207 */
208
209CHAR prfhQueryProfileChar(HINI hini, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
210 const char *pcszApp, // in: application to query
211 const char *pcszKey, // in: key to query
212 CHAR cDefault) // in: default to return if not found
213{
214 // CHAR crc = 0;
215 CHAR szTemp[5],
216 szDefault[5];
217 szDefault[0] = cDefault;
218 szDefault[1] = 0;
219 PrfQueryProfileString(HINI_USER, (PSZ)pcszApp, (PSZ)pcszKey,
220 szDefault,
221 szTemp, sizeof(szTemp)-1);
222 return (szTemp[0]);
223}
224
225/*
226 *@@ prfhQueryCountrySettings:
227 * this returns the most frequently used country settings
228 * all at once into a COUNTRYSETTINGS structure (prfh.h).
229 * This data corresponds to the user settings in the
230 * WPS "Country" object (which writes the data in "PM_National"
231 * in OS2.INI).
232 *
233 * In case a key cannot be found, the following (English)
234 * default values are set:
235 * -- ulDateFormat = 0 (English date format, mm.dd.yyyy);
236 * -- ulTimeFormat = 0 (12-hour clock);
237 * -- cDateSep = '/' (date separator);
238 * -- cTimeSep = ':' (time separator);
239 * -- cDecimal = '.' (decimal separator).
240 * -- cThousands = ',' (thousands separator).
241 *
242 *@@added V0.9.0 [umoeller]
243 *@@changed V0.9.7 (2000-12-02) [umoeller]: added cDecimal
244 */
245
246VOID prfhQueryCountrySettings(PCOUNTRYSETTINGS pcs)
247{
248 if (pcs)
249 {
250 const char *pcszApp = "PM_National";
251 pcs->ulDateFormat = PrfQueryProfileInt(HINI_USER, (PSZ)pcszApp, "iDate", 0);
252 pcs->ulTimeFormat = PrfQueryProfileInt(HINI_USER, (PSZ)pcszApp, "iTime", 0);
253 pcs->cDateSep = prfhQueryProfileChar(HINI_USER, (PSZ)pcszApp, "sDate", '/');
254 pcs->cTimeSep = prfhQueryProfileChar(HINI_USER, (PSZ)pcszApp, "sTime", ':');
255 pcs->cDecimal = prfhQueryProfileChar(HINI_USER, (PSZ)pcszApp, "sDecimal", '.');
256 pcs->cThousands = prfhQueryProfileChar(HINI_USER, (PSZ)pcszApp, "sThousand", ',');
257 }
258}
259
260/*
261 *@@ prfhQueryColor:
262 * returns a system color in OS2.INI's PM_Colors as a LONG.
263 */
264
265LONG prfhQueryColor(const char *pcszKeyName,
266 const char *pcszDefault)
267{
268 CHAR szColor[30];
269 ULONG r, g, b;
270 PrfQueryProfileString(
271 HINI_USER,
272 "PM_Colors",
273 (PSZ)pcszKeyName,
274 (PSZ)pcszDefault,
275 szColor,
276 sizeof(szColor)-1);
277 sscanf(szColor, "%lu %lu %lu ", &r, &g, &b);
278 return (LONG)(r*0x10000 + g*0x100 + b);
279}
280
281/*
282 *@@ prfhCopyKey:
283 * this copies one key from the given profile and application
284 * to another one.
285 *
286 * pszTargetApp may be in the same profile (and must be
287 * different from pszSourceApp then) or in a different
288 * profile (and can be the same then).
289 *
290 * You must specify all parameters. You cannot specify pszKey
291 * as NULL to have a whole application copied. Use prfhCopyApp
292 * for that.
293 * No check is made for this.
294 *
295 * Returns:
296 * -- 0: no error
297 * -- PRFERR_DATASIZE: couldn't query data size for key
298 * -- PRFERR_MEMORY: couldn't allocate memory
299 * -- PRFERR_READ: couldn't read data from source (PrfQueryProfileData error)
300 * -- PRFERR_WRITE: couldn't write data to target (PrfWriteProfileData error)
301 *
302 *@@added V0.9.0 [umoeller]
303 */
304
305ULONG prfhCopyKey(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
306 const char *pcszSourceApp, // in: source application
307 const char *pcszKey, // in: source/target key
308 HINI hiniTarget, // in: target profile (can be HINI_USER or HINI_SYSTEM)
309 const char *pcszTargetApp) // in: target app
310{
311 ULONG ulSizeOfData = 0,
312 ulrc = 0; // return: no error
313
314 if (PrfQueryProfileSize(hiniSource, (PSZ)pcszSourceApp, (PSZ)pcszKey, &ulSizeOfData))
315 {
316 PSZ pData = 0;
317
318 // copy data
319 if (ulSizeOfData == 0)
320 {
321 // data size == 0: this shouldn't really happen,
322 // but if it does, we'll just create a NULL string.
323 // Users have reported that some INI files seem to
324 // contain those "empty" keys. I don't see how these
325 // can exist, but they seem to...
326 pData = (PSZ)malloc(1);
327 *pData = 0;
328 }
329 else
330 pData = (PSZ)malloc(ulSizeOfData);
331
332 if (pData)
333 {
334 if (PrfQueryProfileData(hiniSource,
335 (PSZ)pcszSourceApp,
336 (PSZ)pcszKey,
337 pData,
338 &ulSizeOfData))
339 {
340 if (!PrfWriteProfileData(hiniTarget,
341 (PSZ)pcszTargetApp,
342 (PSZ)pcszKey,
343 pData,
344 ulSizeOfData))
345 ulrc = PRFERR_WRITE;
346 }
347 else
348 ulrc = PRFERR_READ;
349
350 free(pData);
351 }
352 else
353 ulrc = ERROR_NOT_ENOUGH_MEMORY;
354 }
355 else
356 ulrc = PRFERR_DATASIZE;
357
358 return (ulrc);
359}
360
361/*
362 *@@ prfhCopyApp:
363 * this copies one key from the given profile and application
364 * to another one.
365 *
366 * You can use this function in several contexts:
367 * -- copy one application within the same profile
368 * (i.e. hiniSource == hiniTarget);
369 * in this case, pszSourceApp must be != pszTargetApp;
370 * -- copy an application from one profile to another
371 * (i.e. hiniSource != hiniTarget);
372 * in this case, pszSourceApp can be == pszTargetApp
373 * (but can be different also).
374 *
375 * WARNING: This does _not_ check for whether the target
376 * application exists already. This has two consequences:
377 * -- existing data will be overwritten without warning;
378 * -- if the existing target application has keys that are
379 * not in the source application, they are not deleted.
380 * As a result, you might end up with more keys than
381 * in the source application.
382 *
383 * So you should delete the target application before
384 * calling this function, like this:
385 + PrfWriteProfileString(hiniTarget, pszTargetApp, NULL, NULL);
386 *
387 * You must specify all parameters. You cannot specify pszApp
388 * as NULL to have a whole profile copied. Use prfhCopyProfile
389 * for that.
390 * No check is made for this.
391 *
392 * Returns:
393 * -- 0: no error
394 * -- PRFERR_KEYSLIST: couldn't query keys for pszSourceApp
395 * -- PRFERR_DATASIZE: couldn't query data size for key
396 * -- PRFERR_MEMORY: couldn't allocate memory
397 * -- PRFERR_READ: couldn't read data from source (PrfQueryProfileData error)
398 * -- PRFERR_WRITE: couldn't write data to target (PrfWriteProfileData error)
399 *
400 *@@added V0.9.0 [umoeller]
401 */
402
403ULONG prfhCopyApp(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
404 const char *pcszSourceApp, // in: source application
405 HINI hiniTarget, // in: target profile (can be HINI_USER or HINI_SYSTEM)
406 const char *pcszTargetApp, // in: name of pszSourceApp in hiniTarget
407 PSZ pszErrorKey) // out: failing key in case of error; ptr can be NULL
408{
409 ULONG ulrc;
410 PSZ pszKeysList;
411
412 if (pszErrorKey)
413 *pszErrorKey = 0;
414
415 pszKeysList = prfhQueryKeysForApp(hiniSource, (PSZ)pcszSourceApp);
416 if (pszKeysList)
417 {
418 PSZ pKey2 = pszKeysList;
419
420 while (*pKey2 != 0)
421 {
422 // copy this key
423 ulrc = prfhCopyKey(hiniSource,
424 pcszSourceApp,
425 pKey2,
426 hiniTarget,
427 pcszTargetApp);
428 if (ulrc)
429 {
430 // error: copy failing key to buffer
431 if (pszErrorKey)
432 strcpy(pszErrorKey, pKey2);
433 break;
434 }
435 pKey2 += strlen(pKey2)+1;
436 } // end while (*pKey2 != 0)
437
438 free (pszKeysList);
439 }
440 else
441 ulrc = PRFERR_KEYSLIST;
442
443 return (ulrc);
444}
445
446/*
447 *@@ prfhSetUserProfile:
448 * calls PrfReset to change the current user
449 * profile (normally OS2.INI) to the specified
450 * INI file.
451 *
452 *@@added V0.9.4 (2000-07-19) [umoeller]
453 */
454
455BOOL prfhSetUserProfile(HAB hab,
456 const char *pcszUserProfile) // in: new user profile (.INI)
457{
458 BOOL brc = FALSE;
459 // find out current profile names
460 PRFPROFILE Profiles;
461 Profiles.cchUserName = Profiles.cchSysName = 0;
462 // first query their file name lengths
463 if (PrfQueryProfile(hab, &Profiles))
464 {
465 // allocate memory for filenames
466 Profiles.pszUserName = (PSZ)malloc(Profiles.cchUserName);
467 Profiles.pszSysName = (PSZ)malloc(Profiles.cchSysName);
468
469 if ((Profiles.pszSysName) && (Profiles.pszUserName))
470 {
471 // get filenames
472 if (PrfQueryProfile(hab, &Profiles))
473 {
474 // _Pmpf(("Old user profile: %s", Profiles.pszUserName));
475
476 // change INIs
477 free(Profiles.pszUserName);
478 Profiles.pszUserName = (PSZ)pcszUserProfile;
479 Profiles.cchUserName = strlen(pcszUserProfile) + 1;
480 brc = PrfReset(hab, &Profiles);
481 free(Profiles.pszSysName);
482 }
483 }
484 }
485
486 return (brc);
487}
488
489
Note: See TracBrowser for help on using the repository browser.