source: branches/branch-1-0/src/helpers/prfh.c@ 297

Last change on this file since 297 was 194, checked in by umoeller, 23 years ago

Misc fixes.

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 18.3 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#define INCLUDE_PRFH_PRIVATE
48#include "helpers\prfh.h"
49
50#pragma hdrstop
51
52/*
53 *@@category: Helpers\Profile (INI) helpers
54 */
55
56/*
57 *@@ prfhQueryKeysForApp:
58 * returns the keys list for an INI application. This
59 * list is copied into a newly allocated buffer, of which
60 * the address is returned.
61 *
62 * Returns NULL upon errors.
63 *
64 * If the return value is != NULL, the PSZ points to a new
65 * buffer which contains all the keys within the pszApp
66 * application. Each key name in the list is terminated with
67 * a null character. The last string in the list is terminated
68 * with two null characters.
69 *
70 * The returned buffer should be freed later using free().
71 *
72 * <B>Example</B> for iterating over a keys list:
73 *
74 + PSZ pszKeysList = prfhQueryKeysForApp(...);
75 + if (pszKeysList)
76 + {
77 + PSZ pKey2 = pszKeysList;
78 +
79 + while (*pKey2 != 0)
80 + {
81 + ... // pKey2 has the current key now
82 + pKey2 += strlen(pKey2)+1; // next key
83 + }
84 + free(pszKeysList);
85 + }
86 *
87 * You can also use this function to query the applications
88 * list for hIni, if you specifiy pszApp as NULL.
89 *
90 *@@changed V0.9.12 (2001-05-12) [umoeller]: changed prototypes to return APIRET now
91 *@@changed V0.9.19 (2002-04-11) [pr]: Fixed app. with no keys
92 */
93
94APIRET prfhQueryKeysForApp(HINI hIni, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
95 const char *pcszApp, // in: application to query list for (or NULL for applications list)
96 PSZ *ppszKeys) // out: keys list (newly allocated)
97{
98 APIRET arc = NO_ERROR;
99 PSZ pKeys = NULL;
100 ULONG ulSizeOfKeysList = 0;
101
102 // get size of keys list for pszApp
103 if (!PrfQueryProfileSize(hIni, (PSZ)pcszApp, NULL, &ulSizeOfKeysList))
104 arc = PRFERR_KEYSLIST;
105 else
106 {
107 if (ulSizeOfKeysList == 0)
108 ulSizeOfKeysList = 1; // V0.9.19 (2002-04-11) [pr]
109
110 if (!(pKeys = (PSZ)malloc(ulSizeOfKeysList)))
111 arc = ERROR_NOT_ENOUGH_MEMORY;
112 else
113 {
114 *pKeys = 0;
115 if (!PrfQueryProfileData(hIni, (PSZ)pcszApp, NULL, pKeys, &ulSizeOfKeysList))
116 arc = PRFERR_KEYSLIST;
117 }
118 }
119
120 if (!arc) // V0.9.12 (2001-05-12) [umoeller]
121 *ppszKeys = pKeys;
122 else
123 if (pKeys)
124 free(pKeys);
125
126 return arc;
127}
128
129#ifdef __DEBUG_MALLOC_ENABLED__ // setup.h, helpers\memdebug.c
130
131/*
132 *@@ prfhQueryProfileDataDebug:
133 * debug version of prfhQueryProfileData, which is
134 * automatically mapped to if __XWPMEMDEBUG__ is defined.
135 *
136 *@@added V0.9.1 (99-12-20) [umoeller]
137 *@@changed V0.9.3 (2000-04-20) [umoeller]: this called malloc(0) if the key existed, but was empty. Fixed.
138 */
139
140PSZ (prfhQueryProfileDataDebug)(HINI hIni, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
141 const char *pcszApp, // in: application to query
142 const char *pcszKey, // in: key to query
143 PULONG pcbBuf, // out: size of the returned buffer
144 const char *file,
145 unsigned long line,
146 const char *function)
147{
148 PSZ pData = NULL;
149 ULONG ulSizeOfData = 0;
150
151 // get size of data for pszApp/pszKey
152 if (PrfQueryProfileSize(hIni, (PSZ)pcszApp, (PSZ)pcszKey, &ulSizeOfData))
153 {
154 if (ulSizeOfData)
155 {
156 pData = (PSZ)memdMalloc(ulSizeOfData, file, line, function);
157 if (!PrfQueryProfileData(hIni, (PSZ)pcszApp, (PSZ)pcszKey, pData, &ulSizeOfData))
158 {
159 free(pData);
160 pData = NULL;
161 }
162 }
163 }
164
165 if (pcbBuf)
166 *pcbBuf = ulSizeOfData;
167
168 return (pData);
169}
170
171#else
172
173/*
174 *@@ prfhQueryProfileData:
175 * similar to PrfQueryProfileData, but this one copies
176 * the data into a newly allocated buffer, of which the
177 * address is returned.
178 *
179 * Returns NULL upon errors, for example if the specified
180 * key doesn't exist or doesn't contain any data.
181 *
182 * If pcbBuf != NULL, this func will write the size of
183 * the allocated buffer into *pcbBuf.
184 *
185 * The returned buffer should be freed later using free().
186 *
187 *@@added V0.9.0 [umoeller]
188 *@@changed V0.9.3 (2000-04-20) [umoeller]: this called malloc(0) if the key existed, but was empty. Fixed.
189 */
190
191PSZ (prfhQueryProfileData)(HINI hIni, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
192 const char *pcszApp, // in: application to query
193 const char *pcszKey, // in: key to query
194 PULONG pcbBuf) // out: size of the returned buffer; ptr can be NULL
195{
196 PSZ pData = NULL;
197 ULONG ulSizeOfData;
198
199 // get size of data for pszApp/pszKey
200 if ( (PrfQueryProfileSize(hIni, (PSZ)pcszApp, (PSZ)pcszKey, &ulSizeOfData))
201 && (ulSizeOfData)
202 && (pData = (PSZ)malloc(ulSizeOfData))
203 )
204 {
205 if (!PrfQueryProfileData(hIni, (PSZ)pcszApp, (PSZ)pcszKey, pData, &ulSizeOfData))
206 {
207 free(pData);
208 pData = NULL;
209 }
210 }
211
212 if (pcbBuf)
213 *pcbBuf = ulSizeOfData;
214
215 return (pData);
216}
217
218#endif
219
220/*
221 *@@ prfhQueryProfileChar:
222 * this query the first character of profile data.
223 * This is mostly useful with the PM country settings
224 * in OS2.INI:
225 * -- date separator: "PM_National", "sDate"
226 * -- time separator: "PM_National", "sTime"
227 */
228
229CHAR prfhQueryProfileChar(HINI hini, // in: INI handle (can be HINI_USER or HINI_SYSTEM)
230 const char *pcszApp, // in: application to query
231 const char *pcszKey, // in: key to query
232 CHAR cDefault) // in: default to return if not found
233{
234 CHAR szTemp[5],
235 szDefault[5];
236 szDefault[0] = cDefault;
237 szDefault[1] = 0;
238 PrfQueryProfileString(HINI_USER, (PSZ)pcszApp, (PSZ)pcszKey,
239 szDefault,
240 szTemp, sizeof(szTemp)-1);
241 return (szTemp[0]);
242}
243
244/*
245 *@@ prfhQueryColor:
246 * returns a system color in OS2.INI's PM_Colors as a LONG.
247 */
248
249LONG prfhQueryColor(const char *pcszKeyName,
250 const char *pcszDefault)
251{
252 CHAR szColor[30];
253 ULONG r, g, b;
254 PrfQueryProfileString(
255 HINI_USER,
256 "PM_Colors",
257 (PSZ)pcszKeyName,
258 (PSZ)pcszDefault,
259 szColor,
260 sizeof(szColor)-1);
261 sscanf(szColor, "%lu %lu %lu ", &r, &g, &b);
262 return (LONG)(r*0x10000 + g*0x100 + b);
263}
264
265/*
266 *@@ prfhCopyKey:
267 * this copies one key from the given profile and application
268 * to another one.
269 *
270 * pszTargetApp may be in the same profile (and must be
271 * different from pszSourceApp then) or in a different
272 * profile (and can be the same then).
273 *
274 * You must specify all parameters. You cannot specify pszKey
275 * as NULL to have a whole application copied. Use prfhCopyApp
276 * for that.
277 * No check is made for this.
278 *
279 * Returns:
280 * -- 0: no error
281 *
282 * -- PRFERR_DATASIZE: couldn't query data size for key
283 *
284 * -- PRFERR_MEMORY: couldn't allocate memory
285 *
286 * -- PRFERR_READ: couldn't read data from source (PrfQueryProfileData error)
287 *
288 * -- PRFERR_WRITE: couldn't write data to target (PrfWriteProfileData error)
289 *
290 *@@added V0.9.0 [umoeller]
291 */
292
293APIRET prfhCopyKey(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
294 const char *pcszSourceApp, // in: source application
295 const char *pcszKey, // in: source/target key
296 HINI hiniTarget, // in: target profile (can be HINI_USER or HINI_SYSTEM)
297 const char *pcszTargetApp) // in: target app
298{
299 ULONG ulSizeOfData = 0,
300 ulrc = 0; // return: no error
301
302 if (PrfQueryProfileSize(hiniSource, (PSZ)pcszSourceApp, (PSZ)pcszKey, &ulSizeOfData))
303 {
304 PSZ pData = 0;
305
306 // copy data
307 if (ulSizeOfData == 0)
308 {
309 // data size == 0: this shouldn't really happen,
310 // but if it does, we'll just create a NULL string.
311 // Users have reported that some INI files seem to
312 // contain those "empty" keys. I don't see how these
313 // can exist, but they seem to...
314 pData = (PSZ)malloc(1);
315 *pData = 0;
316 }
317 else
318 pData = (PSZ)malloc(ulSizeOfData);
319
320 if (pData)
321 {
322 if (PrfQueryProfileData(hiniSource,
323 (PSZ)pcszSourceApp,
324 (PSZ)pcszKey,
325 pData,
326 &ulSizeOfData))
327 {
328 if (!PrfWriteProfileData(hiniTarget,
329 (PSZ)pcszTargetApp,
330 (PSZ)pcszKey,
331 pData,
332 ulSizeOfData))
333 ulrc = PRFERR_WRITE;
334 }
335 else
336 ulrc = PRFERR_READ;
337
338 free(pData);
339 }
340 else
341 ulrc = ERROR_NOT_ENOUGH_MEMORY;
342 }
343 else
344 ulrc = PRFERR_DATASIZE;
345
346 return (ulrc);
347}
348
349/*
350 *@@ prfhCopyApp:
351 * this copies one key from the given profile and application
352 * to another one.
353 *
354 * You can use this function in several contexts:
355 *
356 * -- copy one application within the same profile
357 * (i.e. hiniSource == hiniTarget);
358 * in this case, pszSourceApp must be != pszTargetApp;
359 *
360 * -- copy an application from one profile to another
361 * (i.e. hiniSource != hiniTarget);
362 * in this case, pszSourceApp can be == pszTargetApp
363 * (but can be different also).
364 *
365 * WARNING: This does _not_ check for whether the target
366 * application exists already. This has two consequences:
367 *
368 * -- existing data will be overwritten without warning;
369 *
370 * -- if the existing target application has keys that are
371 * not in the source application, they are not deleted.
372 * As a result, you might end up with more keys than
373 * in the source application.
374 *
375 * So you should delete the target application before
376 * calling this function, like this:
377 *
378 + PrfWriteProfileString(hiniTarget, pszTargetApp, NULL, NULL);
379 *
380 * You must specify all parameters. You cannot specify pszApp
381 * as NULL to have a whole profile copied. Use prfhCopyProfile
382 * for that.
383 * No check is made for this.
384 *
385 * Returns:
386 *
387 * -- 0: no error
388 *
389 * -- PRFERR_KEYSLIST: couldn't query keys for pszSourceApp
390 *
391 * -- PRFERR_DATASIZE: couldn't query data size for key
392 *
393 * -- PRFERR_MEMORY: couldn't allocate memory
394 *
395 * -- PRFERR_READ: couldn't read data from source (PrfQueryProfileData error)
396 *
397 * -- PRFERR_WRITE: couldn't write data to target (PrfWriteProfileData error)
398 *
399 *@@added V0.9.0 [umoeller]
400 */
401
402APIRET prfhCopyApp(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
403 const char *pcszSourceApp, // in: source application
404 HINI hiniTarget, // in: target profile (can be HINI_USER or HINI_SYSTEM)
405 const char *pcszTargetApp, // in: name of pszSourceApp in hiniTarget
406 PSZ pszErrorKey) // out: failing key in case of error; ptr can be NULL
407{
408 APIRET arc = NO_ERROR;
409 PSZ pszKeysList = NULL;
410
411 if (pszErrorKey)
412 *pszErrorKey = 0;
413
414 if (!(arc = prfhQueryKeysForApp(hiniSource,
415 (PSZ)pcszSourceApp,
416 &pszKeysList)))
417 {
418 PSZ pKey2 = pszKeysList;
419
420 while (*pKey2 != 0)
421 {
422 // copy this key
423 arc = prfhCopyKey(hiniSource,
424 pcszSourceApp,
425 pKey2,
426 hiniTarget,
427 pcszTargetApp);
428 if (arc)
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
441 return arc;
442}
443
444/*
445 *@@ prfhRenameKey:
446 * renames a key in an INI file.
447 *
448 * Since there's no such thing as a PrfRename,
449 * what we do here is load the old data, write
450 * it under a new key, and delete the old data.
451 *
452 * Returns:
453 *
454 * -- 0: no error
455 *
456 * -- PRFERR_INVALID_KEY: pcszApp or pcszOldKey do not exist.
457 *
458 * -- PRFERR_KEY_EXISTS: pcszNewApp/pcszNewKey is already occupied.
459 *
460 * -- PRFERR_WRITE: couldn't write data to target (PrfWriteProfileData error)
461 *
462 *@@added V0.9.9 (2001-02-06) [umoeller]
463 */
464
465ULONG prfhRenameKey(HINI hini,
466 const char *pcszOldApp,
467 const char *pcszOldKey, // in: key to rename
468 const char *pcszNewApp, // in: new app (if NULL, pcszOldApp is used)
469 const char *pcszNewKey) // in: new name for pcszOldKey
470{
471 ULONG ulrc = 0;
472
473 ULONG cbData = 0;
474 PSZ pszData = prfhQueryProfileData(hini,
475 pcszOldApp,
476 pcszOldKey,
477 &cbData);
478 if (!pszData)
479 // not found:
480 ulrc = PRFERR_INVALID_KEY;
481 else
482 {
483 ULONG cb;
484
485 if (!pcszNewApp)
486 // is NULL:
487 pcszNewApp = pcszOldApp;
488
489 // make sure target doesn't exist
490 if ( (PrfQueryProfileSize(hini,
491 (PSZ)pcszNewApp,
492 (PSZ)pcszNewKey,
493 &cb))
494 && (cb)
495 )
496 ulrc = PRFERR_KEY_EXISTS;
497 else
498 {
499 if (!PrfWriteProfileData(hini,
500 (PSZ)pcszNewApp,
501 (PSZ)pcszNewKey,
502 pszData,
503 cbData))
504 ulrc = PRFERR_WRITE;
505 else
506 {
507 // success writing:
508 // delete old
509 PrfWriteProfileData(hini,
510 (PSZ)pcszOldApp,
511 (PSZ)pcszOldKey,
512 NULL,
513 0);
514 }
515 }
516
517 free(pszData);
518 }
519
520 return (ulrc);
521}
522
523/*
524 *@@ prfhSetUserProfile:
525 * calls PrfReset to change the current user
526 * profile (normally OS2.INI) to the specified
527 * INI file.
528 *
529 *@@added V0.9.4 (2000-07-19) [umoeller]
530 *@@changed V0.9.19 (2002-04-02) [umoeller]: now returning APIRET
531 */
532
533APIRET prfhSetUserProfile(HAB hab,
534 const char *pcszUserProfile) // in: new user profile (.INI)
535{
536 APIRET arc = NO_ERROR;
537
538 // find out current profile names
539 PRFPROFILE Profiles;
540 Profiles.cchUserName = Profiles.cchSysName = 0;
541 // first query their file name lengths
542 if (PrfQueryProfile(hab, &Profiles))
543 {
544 // allocate memory for filenames
545 Profiles.pszUserName = (PSZ)malloc(Profiles.cchUserName);
546 Profiles.pszSysName = (PSZ)malloc(Profiles.cchSysName);
547
548 if ((Profiles.pszSysName) && (Profiles.pszUserName))
549 {
550 // get filenames
551 if (PrfQueryProfile(hab, &Profiles))
552 {
553 // _Pmpf(("Old user profile: %s", Profiles.pszUserName));
554
555 // change INIs
556 free(Profiles.pszUserName);
557 Profiles.pszUserName = (PSZ)pcszUserProfile;
558 Profiles.cchUserName = strlen(pcszUserProfile) + 1;
559 if (!PrfReset(hab, &Profiles))
560 arc = PRFERR_RESET;
561 free(Profiles.pszSysName);
562 }
563 else
564 arc = PRFERR_QUERY;
565 }
566 else
567 arc = PRFERR_QUERY;
568 }
569 else
570 arc = PRFERR_QUERY;
571
572 return arc;
573}
574
575
Note: See TracBrowser for help on using the repository browser.