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

Last change on this file since 140 was 108, checked in by umoeller, 24 years ago

Lots of updates from the last week for conditional compiles and other stuff.

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