source: trunk/src/helpers/xprf2.c@ 108

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

Lotsa fixes from the last two weeks.

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 KB
Line 
1
2/*
3 *@@sourcefile xprf2.c:
4 * copy-profile functions which use the replacement
5 * profile functions in xprf.c.
6 *
7 * This can be used for a bomb-proof "save system profiles"
8 * (see xprfSaveINIs).
9 *
10 * Usage: All OS/2 programs.
11 *
12 * Function prefixes:
13 * -- xprf* replacement profile (INI) functions
14 *
15 * Note: Version numbering in this file relates to XWorkplace version
16 * numbering.
17 *
18 *@@header "helpers\xprf.h"
19 *@@added V0.9.5 (2000-08-10) [umoeller]
20 */
21
22/*
23 * Copyright (C) 2000 Ulrich M”ller.
24 * This file is part of the "XWorkplace helpers" source package.
25 * This is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published
27 * by the Free Software Foundation, in version 2 as it comes in the
28 * "COPYING" file of the XWorkplace main distribution.
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 */
34
35#define OS2EMX_PLAIN_CHAR
36 // this is needed for "os2emx.h"; if this is defined,
37 // emx will define PSZ as _signed_ char, otherwise
38 // as unsigned char
39
40#define INCL_DOSERRORS
41#define INCL_WINSHELLDATA
42#include <os2.h>
43
44#include <stdlib.h>
45#include <stdio.h>
46#include <string.h>
47
48#include "setup.h" // code generation and debugging options
49
50#include "helpers\dosh.h"
51#include "helpers\prfh.h"
52#include "helpers\stringh.h"
53#include "helpers\xprf.h"
54
55#pragma hdrstop
56
57/*
58 *@@category: Helpers\Profile (INI) replacement functions
59 */
60
61/* ******************************************************************
62 *
63 * Copy API Functions
64 *
65 ********************************************************************/
66
67/*
68 *@@ xprfCopyKey:
69 * copies a single key from an Prf* HINI to an xprf* PXINI.
70 * hiniTarget must therefore have been opened using
71 * xprfOpenProfile.
72 *
73 * This returns 0 (NO_ERROR) if copying succeeded. Otherwise either
74 * an OS/2 error code (ERROR_*) or one of the profile error
75 * codes defined in prfh.h is returned.
76 */
77
78APIRET xprfCopyKey(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
79 PSZ pszSourceApp, // in: source application
80 PSZ pszKey, // in: source/target key
81 PXINI hiniTarget, // in: target profile opened with xprfOpenProfile
82 PSZ pszTargetApp) // in: target app
83{
84 ULONG ulSizeOfData = 0;
85 APIRET arc = NO_ERROR;
86
87 if (PrfQueryProfileSize(hiniSource, pszSourceApp, pszKey, &ulSizeOfData))
88 {
89 PSZ pData = 0;
90
91 // copy data
92 if (ulSizeOfData == 0)
93 {
94 // data size == 0: this shouldn't really happen,
95 // but if it does, we'll just create a NULL string.
96 // Users have reported that some INI files seem to
97 // contain those "empty" keys. I don't see how these
98 // can exist, but they seem to...
99 pData = (PSZ)malloc(1);
100 *pData = 0;
101 }
102 else
103 pData = (PSZ)malloc(ulSizeOfData);
104
105 if (pData)
106 {
107 fflush(stdout);
108 if (PrfQueryProfileData(hiniSource,
109 pszSourceApp,
110 pszKey,
111 pData,
112 &ulSizeOfData))
113 {
114 if (!xprfWriteProfileData(hiniTarget,
115 pszTargetApp,
116 pszKey,
117 pData,
118 ulSizeOfData))
119 arc = PRFERR_WRITE;
120 }
121 else
122 arc = PRFERR_READ;
123
124 free(pData);
125 }
126 else
127 arc = ERROR_NOT_ENOUGH_MEMORY;
128 }
129 else
130 arc = PRFERR_DATASIZE;
131
132 return (arc);
133}
134
135/*
136 *@@ xprfCopyApp:
137 * copies a single application from an Prf* HINI to an xprf* PXINI.
138 * hiniTarget must therefore have been opened using
139 * xprfOpenProfile.
140 *
141 * This calls xprfCopyKey for each key in the application.
142 *
143 * This returns 0 (NO_ERROR) if copying succeeded. Otherwise either
144 * an OS/2 error code (ERROR_*) or one of the profile error
145 * codes defined in prfh.h is returned.
146 */
147
148APIRET xprfCopyApp(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
149 PSZ pszSourceApp, // in: source application
150 PXINI hiniTarget, // in: target profile opened with xprfOpenProfile
151 PSZ pszTargetApp, // in: name of pszSourceApp in hiniTarget
152 PSZ pszErrorKey) // out: failing key in case of error; ptr can be NULL
153{
154 APIRET arc = NO_ERROR;
155 PSZ pszKeysList = NULL;
156
157 if (pszErrorKey)
158 *pszErrorKey = 0;
159
160 if (!(arc = prfhQueryKeysForApp(hiniSource,
161 pszSourceApp,
162 &pszKeysList)))
163 {
164 PSZ pKey2 = pszKeysList;
165
166 while (*pKey2 != 0)
167 {
168 // copy this key
169 arc = xprfCopyKey(hiniSource,
170 pszSourceApp,
171 pKey2,
172 hiniTarget,
173 pszTargetApp);
174 if (arc)
175 {
176 // error: copy failing key to buffer
177 if (pszErrorKey)
178 strcpy(pszErrorKey, pKey2);
179 break;
180 }
181 pKey2 += strlen(pKey2)+1;
182 } // end while (*pKey2 != 0)
183
184 free (pszKeysList);
185 }
186 else
187 arc = PRFERR_KEYSLIST;
188
189 return (arc);
190}
191
192/*
193 *@@ xprfCopyProfile:
194 * this copies an entire profile.
195 *
196 * The source profile must have been opened using the
197 * regular OS/2 PrfOpenProfile. You can also specify
198 * HINI_USER or HINI_SYSTEM.
199 *
200 * pszNew specifies the file name for the new profile.
201 * This must end in *.INI. The new profile is opened
202 * using xprfOpenProfile, so see additional remarks there.
203 *
204 * This returns 0 (NO_ERROR) on success. Otherwise either
205 * an OS/2 error code (ERROR_*) or one of the profile error
206 * codes defined in prfh.h is returned.
207 */
208
209APIRET xprfCopyProfile(HINI hOld, // in: source profile (can be HINI_USER or HINI_SYSTEM)
210 PSZ pszNew, // in: new filename (can be fully qualified)
211 PFN_PRF_PROGRESS pfnProgressCallback,
212 ULONG ulUser, // in: passed to pfnProgressCallback
213 ULONG ulCount, // in: index of INI being copied (0 <= ulCount <= ulMax)
214 ULONG ulMax) // in: maximum index (for progress); 0 means 1 INI, 1 means 2 INIs, ...
215{
216 APIRET arc = NO_ERROR;
217 PXINI pxiniNew = NULL;
218 ULONG ulSizeOfAppsList;
219
220 if (!pszNew)
221 arc = ERROR_INVALID_PARAMETER;
222 else
223 {
224 DosDelete(pszNew);
225
226 // open new profile
227 arc = xprfOpenProfile(pszNew,
228 &pxiniNew);
229
230 // get size of applications list
231 if (arc == NO_ERROR)
232 {
233 if (!PrfQueryProfileSize(hOld, NULL, NULL, &ulSizeOfAppsList))
234 arc = PRFERR_APPSLIST;
235 else
236 if (ulSizeOfAppsList == 0)
237 arc = PRFERR_APPSLIST;
238
239 if (arc == NO_ERROR)
240 {
241 // get applications list
242 PSZ pApps = (PSZ)malloc(ulSizeOfAppsList);
243 PSZ pApp2 = pApps;
244 if (!PrfQueryProfileData(hOld,
245 NULL,
246 NULL,
247 pApps,
248 &ulSizeOfAppsList))
249 arc = PRFERR_APPSLIST;
250
251 // applications loop
252
253 while ( (*pApp2 != 0)
254 && (arc == NO_ERROR)
255 )
256 {
257 CHAR szErrorKey[1000];
258 // copy application (this will call prfhCopyKey in turn)
259 arc = xprfCopyApp(hOld,
260 pApp2,
261 pxiniNew,
262 pApp2,
263 szErrorKey);
264
265 if (pfnProgressCallback)
266 {
267 ULONG ulNow2, ulMax2;
268 ulNow2 = ((1000*(pApp2-pApps)) / ulSizeOfAppsList) + (ulCount*1000);
269 ulMax2 = (ulMax+1)*1000;
270 if (!pfnProgressCallback(ulUser, ulNow2, ulMax2))
271 // aborted:
272 arc = PRFERR_ABORTED;
273 }
274
275 // go for next app
276 pApp2 += strlen(pApp2)+1;
277
278 } // end while (*pApp2 != 0) && MBID_NOERROR
279
280 if (pApps)
281 free(pApps);
282 }
283
284 xprfCloseProfile(pxiniNew);
285
286 // progress
287 if (pfnProgressCallback)
288 pfnProgressCallback(ulUser, (ulCount+1) * 1000, (ulMax+1) * 1000);
289 }
290 }
291
292 return (arc);
293}
294
295/*
296 *@@ xprfSaveINIs:
297 * this rewrites the OS/2 user and system profiles
298 * (OS2.INI and OS2SYS.INI) to disk. This is done
299 * by doing the following:
300 *
301 * -- First, both profiles are dumped into two temporary
302 * profiles (using xprfCopyProfile on each of them).
303 * These are put into the same directory as the source
304 * profiles (?:\OS2 normally) with a file name extension
305 * of OS2*.XFL.
306 *
307 * -- Only if that succeeded, the original profiles are
308 * renamed to OS2*.BAK. Existing OS2*.BAK files are
309 * deleted.
310 *
311 * -- If that succeded, the temporary OS2*.XFL files are
312 * renamed to OS2*.INI.
313 *
314 * This is now used during XShutdown to dump the system
315 * profiles before shutting down the system. As opposed to
316 * prfhSaveINIs, which was previously used, this does not
317 * use the Prf* functions for the target profiles so that
318 * those ugly "Error saving INI files" errors are less likely.
319 *
320 * This returns 0 (NO_ERROR) if copying succeeded. Otherwise either
321 * an OS/2 error code (ERROR_*) or one of the profile error
322 * codes defined in prfh.h is returned.
323 */
324
325APIRET xprfSaveINIs(HAB hab, // in: anchor block
326 PFN_PRF_PROGRESS pfnProgressCallback,
327 ULONG ulUser)
328{
329 PRFPROFILE Profiles;
330 APIRET arc = NO_ERROR;
331
332 // FILESTATUS3 fs3;
333 CHAR szSysNew[CCHMAXPATH],
334 szUserNew[CCHMAXPATH],
335 szSysBackup[CCHMAXPATH],
336 szUserBackup[CCHMAXPATH];
337
338 /*
339 * get system profiles:
340 *
341 */
342
343 Profiles.cchUserName = Profiles.cchSysName = 0;
344 if (!PrfQueryProfile(hab, &Profiles))
345 arc = PRFERR_QUERY;
346 else
347 {
348 Profiles.pszUserName = (PSZ)malloc(Profiles.cchUserName);
349 Profiles.pszSysName = (PSZ)malloc(Profiles.cchSysName);
350 if ( (Profiles.pszSysName == NULL)
351 || (Profiles.pszUserName == NULL)
352 )
353 arc = PRFERR_QUERY;
354 else
355 if (!PrfQueryProfile(hab, &Profiles))
356 arc = PRFERR_QUERY;
357 }
358
359 if (arc == NO_ERROR)
360 {
361 PSZ _p;
362
363 /*
364 * create new profile names:
365 * same as old profiles, but with *.XFL ext.
366 */
367
368 // system INI
369 strcpy(szSysBackup, Profiles.pszSysName);
370 strcpy(szSysNew, Profiles.pszSysName);
371 _p = strhistr(szSysBackup, ".INI");
372 if (!_p)
373 arc = PRFERR_INVALID_FILE_NAME;
374 else
375 strcpy(_p, ".BAK");
376 _p = strhistr(szSysNew, ".INI");
377 if (!_p)
378 arc = PRFERR_INVALID_FILE_NAME;
379 else
380 strcpy(_p, ".XFL");
381
382 // user INI
383 strcpy(szUserBackup, Profiles.pszUserName);
384 strcpy(szUserNew, Profiles.pszUserName);
385 _p = strhistr(szUserBackup, ".INI");
386 if (!_p)
387 arc = PRFERR_INVALID_FILE_NAME;
388 else
389 strcpy(_p, ".BAK");
390 _p = strhistr(szUserNew, ".INI");
391 if (!_p)
392 arc = PRFERR_INVALID_FILE_NAME;
393 else
394 strcpy(_p, ".XFL");
395
396 /*
397 * create OS2SYS.XFL:
398 *
399 */
400
401 if (arc == NO_ERROR)
402 arc = xprfCopyProfile(HINI_SYSTEM,
403 szSysNew, // new filename
404 pfnProgressCallback,
405 ulUser, 0, 1);
406 /*
407 * create OS2SYS.XFL:
408 *
409 */
410
411 if (arc == NO_ERROR)
412 arc = xprfCopyProfile(HINI_USER,
413 szUserNew, // new filename
414 pfnProgressCallback,
415 ulUser, 1, 1);
416 }
417
418 /*
419 * renaming stuff for OS2SYS.INI
420 *
421 */
422
423 if (arc == NO_ERROR)
424 {
425 // attrib -r -s -h -a OS2SYS.BAK
426 doshSetPathAttr(szSysBackup, FILE_NORMAL);
427 // delete OS2SYS.BAK
428 DosDelete(szSysBackup);
429 // attrib -r -s -h -a OS2SYS.INI
430 doshSetPathAttr(Profiles.pszSysName, FILE_NORMAL);
431 // REN OS2SYS.INI OS2SYS.BAK
432 DosMove(Profiles.pszSysName, szSysBackup);
433 }
434
435 /*
436 * renaming stuff for OS2.INI
437 *
438 */
439
440 if (arc == NO_ERROR)
441 {
442 // attrib -r -s -h -a OS2SYS.BAK
443 doshSetPathAttr(szUserBackup, FILE_NORMAL);
444 // delete OS2SYS.BAK
445 DosDelete(szUserBackup);
446 // attrib -r -s -h -a OS2SYS.INI
447 doshSetPathAttr(Profiles.pszUserName, FILE_NORMAL);
448 // REN OS2SYS.INI OS2SYS.BAK
449 DosMove(Profiles.pszUserName, szUserBackup);
450 }
451
452 if (arc == NO_ERROR)
453 {
454 // finally, replace system profiles
455 arc = DosMove(szSysNew, Profiles.pszSysName);
456 if (arc == NO_ERROR)
457 arc = DosMove(szUserNew, Profiles.pszUserName);
458 }
459
460 if (Profiles.pszSysName)
461 free(Profiles.pszSysName);
462 if (Profiles.pszUserName)
463 free(Profiles.pszUserName);
464
465 return (arc);
466}
467
468// testing
469
470/* BOOL _Optlink fnCallback(ULONG ulUser, ULONG ulNow, ULONG ulMax)
471{
472 printf("\r done %03d%%", ulNow * 100 / ulMax);
473 return (TRUE);
474}
475
476int main(int argc, char* argv[])
477{
478 if (argc != 3)
479 printf("Syntax: xprf2 <source.ini> <target.ini>\n");
480 else
481 {
482 HAB hab = WinInitialize(0);
483
484 // HINI hiniSource = PrfOpenProfile(hab, argv[1]);
485 // if (hiniSource)
486 {
487 APIRET arc = xprfCopyProfile(hiniSource,
488 argv[2],
489 fnCallback,
490 0, 0, 0);
491 xprfSaveProfiles(hab, NULL, 0);
492// if (arc)
493
494
495 // printf("xprfCopyProfile returned %d.\n", arc);
496 }
497 // else
498 // printf("Cannot open %s\n", argv[1]);
499
500 WinTerminate(hab);
501 }
502
503 return (0);
504} */
505
Note: See TracBrowser for help on using the repository browser.