| 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 Mller. | 
|---|
| 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 |  | 
|---|
| 78 | APIRET xprfCopyKey(HINI hiniSource,       // in: source profile (can be HINI_USER or HINI_SYSTEM) | 
|---|
| 79 | PCSZ pszSourceApp,     // in: source application | 
|---|
| 80 | PCSZ pszKey,           // in: source/target key | 
|---|
| 81 | PXINI hiniTarget,      // in: target profile opened with xprfOpenProfile | 
|---|
| 82 | PCSZ pszTargetApp)     // in: target app | 
|---|
| 83 | { | 
|---|
| 84 | ULONG   ulSizeOfData = 0; | 
|---|
| 85 | APIRET  arc = NO_ERROR; | 
|---|
| 86 |  | 
|---|
| 87 | if (PrfQueryProfileSize(hiniSource, | 
|---|
| 88 | (PSZ)pszSourceApp, | 
|---|
| 89 | (PSZ)pszKey, | 
|---|
| 90 | &ulSizeOfData)) | 
|---|
| 91 | { | 
|---|
| 92 | PSZ pData = 0; | 
|---|
| 93 |  | 
|---|
| 94 | // copy data | 
|---|
| 95 | if (ulSizeOfData == 0) | 
|---|
| 96 | { | 
|---|
| 97 | // data size == 0: this shouldn't really happen, | 
|---|
| 98 | // but if it does, we'll just create a NULL string. | 
|---|
| 99 | // Users have reported that some INI files seem to | 
|---|
| 100 | // contain those "empty" keys. I don't see how these | 
|---|
| 101 | // can exist, but they seem to... | 
|---|
| 102 | pData = (PSZ)malloc(1); | 
|---|
| 103 | *pData = 0; | 
|---|
| 104 | } | 
|---|
| 105 | else | 
|---|
| 106 | pData = (PSZ)malloc(ulSizeOfData); | 
|---|
| 107 |  | 
|---|
| 108 | if (pData) | 
|---|
| 109 | { | 
|---|
| 110 | fflush(stdout); | 
|---|
| 111 | if (PrfQueryProfileData(hiniSource, | 
|---|
| 112 | (PSZ)pszSourceApp, | 
|---|
| 113 | (PSZ)pszKey, | 
|---|
| 114 | pData, | 
|---|
| 115 | &ulSizeOfData)) | 
|---|
| 116 | { | 
|---|
| 117 | arc = xprfWriteProfileData(hiniTarget, | 
|---|
| 118 | pszTargetApp, | 
|---|
| 119 | pszKey, | 
|---|
| 120 | pData, | 
|---|
| 121 | ulSizeOfData); | 
|---|
| 122 | } | 
|---|
| 123 | else | 
|---|
| 124 | arc = PRFERR_READ; | 
|---|
| 125 |  | 
|---|
| 126 | free(pData); | 
|---|
| 127 | } | 
|---|
| 128 | else | 
|---|
| 129 | arc = ERROR_NOT_ENOUGH_MEMORY; | 
|---|
| 130 | } | 
|---|
| 131 | else | 
|---|
| 132 | arc = PRFERR_DATASIZE; | 
|---|
| 133 |  | 
|---|
| 134 | return arc; | 
|---|
| 135 | } | 
|---|
| 136 |  | 
|---|
| 137 | /* | 
|---|
| 138 | *@@ xprfCopyKey2: | 
|---|
| 139 | *      copies a single key from an xprf* PXINI to a Prf* HINI. | 
|---|
| 140 | *      hiniSource must therefore have been opened using | 
|---|
| 141 | *      xprfOpenProfile. | 
|---|
| 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 | *@@added V1.0.0 (2002-09-17) [umoeller] | 
|---|
| 148 | */ | 
|---|
| 149 |  | 
|---|
| 150 | APIRET xprfCopyKey2(PXINI hiniSource,   // in: source profile (can be HINI_USER or HINI_SYSTEM) | 
|---|
| 151 | PCSZ pszSourceApp,  // in: source application | 
|---|
| 152 | PCSZ pszKey,        // in: source/target key | 
|---|
| 153 | HINI hiniTarget,    // in: target profile opened with xprfOpenProfile | 
|---|
| 154 | PCSZ pszTargetApp)  // in: target app | 
|---|
| 155 | { | 
|---|
| 156 | ULONG   ulSizeOfData = 0; | 
|---|
| 157 | APIRET  arc = NO_ERROR; | 
|---|
| 158 |  | 
|---|
| 159 | if (xprfQueryProfileSize(hiniSource, pszSourceApp, pszKey, &ulSizeOfData)) | 
|---|
| 160 | { | 
|---|
| 161 | PSZ pData = 0; | 
|---|
| 162 |  | 
|---|
| 163 | // copy data | 
|---|
| 164 | if (ulSizeOfData == 0) | 
|---|
| 165 | { | 
|---|
| 166 | // data size == 0: this shouldn't really happen, | 
|---|
| 167 | // but if it does, we'll just create a NULL string. | 
|---|
| 168 | // Users have reported that some INI files seem to | 
|---|
| 169 | // contain those "empty" keys. I don't see how these | 
|---|
| 170 | // can exist, but they seem to... | 
|---|
| 171 | pData = (PSZ)malloc(1); | 
|---|
| 172 | *pData = 0; | 
|---|
| 173 | } | 
|---|
| 174 | else | 
|---|
| 175 | pData = (PSZ)malloc(ulSizeOfData); | 
|---|
| 176 |  | 
|---|
| 177 | if (pData) | 
|---|
| 178 | { | 
|---|
| 179 | fflush(stdout); | 
|---|
| 180 | if (xprfQueryProfileData(hiniSource, | 
|---|
| 181 | pszSourceApp, | 
|---|
| 182 | pszKey, | 
|---|
| 183 | pData, | 
|---|
| 184 | &ulSizeOfData)) | 
|---|
| 185 | { | 
|---|
| 186 | if (!PrfWriteProfileData(hiniTarget, | 
|---|
| 187 | (PSZ)pszTargetApp, | 
|---|
| 188 | (PSZ)pszKey, | 
|---|
| 189 | pData, | 
|---|
| 190 | ulSizeOfData)) | 
|---|
| 191 | arc = PRFERR_WRITE; | 
|---|
| 192 | } | 
|---|
| 193 | else | 
|---|
| 194 | arc = PRFERR_READ; | 
|---|
| 195 |  | 
|---|
| 196 | free(pData); | 
|---|
| 197 | } | 
|---|
| 198 | else | 
|---|
| 199 | arc = ERROR_NOT_ENOUGH_MEMORY; | 
|---|
| 200 | } | 
|---|
| 201 | else | 
|---|
| 202 | arc = PRFERR_DATASIZE; | 
|---|
| 203 |  | 
|---|
| 204 | return arc; | 
|---|
| 205 | } | 
|---|
| 206 |  | 
|---|
| 207 | /* | 
|---|
| 208 | *@@ xprfCopyApp: | 
|---|
| 209 | *      copies a single application from a Prf* HINI to an xprf* PXINI. | 
|---|
| 210 | *      hiniTarget must therefore have been opened using | 
|---|
| 211 | *      xprfOpenProfile. | 
|---|
| 212 | * | 
|---|
| 213 | *      This calls xprfCopyKey for each key in the application. | 
|---|
| 214 | * | 
|---|
| 215 | *      This returns 0 (NO_ERROR) if copying succeeded. Otherwise either | 
|---|
| 216 | *      an OS/2 error code (ERROR_*) or one of the profile error | 
|---|
| 217 | *      codes defined in prfh.h is returned. | 
|---|
| 218 | */ | 
|---|
| 219 |  | 
|---|
| 220 | APIRET xprfCopyApp(HINI hiniSource,     // in: source profile (can be HINI_USER or HINI_SYSTEM) | 
|---|
| 221 | PCSZ pszSourceApp,   // in: source application | 
|---|
| 222 | PXINI hiniTarget,    // in: target profile opened with xprfOpenProfile | 
|---|
| 223 | PCSZ pszTargetApp,   // in: name of pszSourceApp in hiniTarget | 
|---|
| 224 | PSZ pszErrorKey)     // out: failing key in case of error; ptr can be NULL | 
|---|
| 225 | { | 
|---|
| 226 | APIRET arc = NO_ERROR; | 
|---|
| 227 | PSZ pszKeysList = NULL; | 
|---|
| 228 |  | 
|---|
| 229 | if (pszErrorKey) | 
|---|
| 230 | *pszErrorKey = 0; | 
|---|
| 231 |  | 
|---|
| 232 | if (!(arc = prfhQueryKeysForApp(hiniSource, | 
|---|
| 233 | pszSourceApp, | 
|---|
| 234 | &pszKeysList))) | 
|---|
| 235 | { | 
|---|
| 236 | PSZ pKey2 = pszKeysList; | 
|---|
| 237 |  | 
|---|
| 238 | while (*pKey2 != 0) | 
|---|
| 239 | { | 
|---|
| 240 | // copy this key | 
|---|
| 241 | if (arc = xprfCopyKey(hiniSource, | 
|---|
| 242 | pszSourceApp, | 
|---|
| 243 | pKey2, | 
|---|
| 244 | hiniTarget, | 
|---|
| 245 | pszTargetApp)) | 
|---|
| 246 | { | 
|---|
| 247 | // error: copy failing key to buffer | 
|---|
| 248 | if (pszErrorKey) | 
|---|
| 249 | strcpy(pszErrorKey, pKey2); | 
|---|
| 250 | break; | 
|---|
| 251 | } | 
|---|
| 252 |  | 
|---|
| 253 | pKey2 += strlen(pKey2)+1; | 
|---|
| 254 | } // end while (*pKey2 != 0) | 
|---|
| 255 |  | 
|---|
| 256 | free (pszKeysList); | 
|---|
| 257 | } | 
|---|
| 258 | else | 
|---|
| 259 | arc = PRFERR_KEYSLIST; | 
|---|
| 260 |  | 
|---|
| 261 | return arc; | 
|---|
| 262 | } | 
|---|
| 263 |  | 
|---|
| 264 | /* | 
|---|
| 265 | *@@ xprfCopyApp2: | 
|---|
| 266 | *      copies a single application from an xprf* PXINI to a Prf* HINI. | 
|---|
| 267 | *      hiniTarget must therefore have been opened using | 
|---|
| 268 | *      xprfOpenProfile. | 
|---|
| 269 | * | 
|---|
| 270 | *      This calls xprfCopyKey2 for each key in the application. | 
|---|
| 271 | * | 
|---|
| 272 | *      This returns 0 (NO_ERROR) if copying succeeded. Otherwise either | 
|---|
| 273 | *      an OS/2 error code (ERROR_*) or one of the profile error | 
|---|
| 274 | *      codes defined in prfh.h is returned. | 
|---|
| 275 | * | 
|---|
| 276 | *@@added V1.0.0 (2002-09-17) [umoeller] | 
|---|
| 277 | */ | 
|---|
| 278 |  | 
|---|
| 279 | APIRET xprfCopyApp2(PXINI hiniSource,   // in: source profile (can be HINI_USER or HINI_SYSTEM) | 
|---|
| 280 | PCSZ pszSourceApp,  // in: source application | 
|---|
| 281 | HINI hiniTarget,    // in: target profile opened with xprfOpenProfile | 
|---|
| 282 | PCSZ pszTargetApp,  // in: name of pszSourceApp in hiniTarget | 
|---|
| 283 | PSZ pszErrorKey)    // out: failing key in case of error; ptr can be NULL | 
|---|
| 284 | { | 
|---|
| 285 | APIRET arc = NO_ERROR; | 
|---|
| 286 | PSZ pszKeysList = NULL; | 
|---|
| 287 |  | 
|---|
| 288 | if (pszErrorKey) | 
|---|
| 289 | *pszErrorKey = 0; | 
|---|
| 290 |  | 
|---|
| 291 | if (!(arc = xprfQueryKeysForApp(hiniSource, | 
|---|
| 292 | pszSourceApp, | 
|---|
| 293 | &pszKeysList))) | 
|---|
| 294 | { | 
|---|
| 295 | PSZ pKey2 = pszKeysList; | 
|---|
| 296 |  | 
|---|
| 297 | while (*pKey2 != 0) | 
|---|
| 298 | { | 
|---|
| 299 | // copy this key | 
|---|
| 300 | if (arc = xprfCopyKey2(hiniSource, | 
|---|
| 301 | pszSourceApp, | 
|---|
| 302 | pKey2, | 
|---|
| 303 | hiniTarget, | 
|---|
| 304 | pszTargetApp)) | 
|---|
| 305 | { | 
|---|
| 306 | // error: copy failing key to buffer | 
|---|
| 307 | if (pszErrorKey) | 
|---|
| 308 | strcpy(pszErrorKey, pKey2); | 
|---|
| 309 | break; | 
|---|
| 310 | } | 
|---|
| 311 |  | 
|---|
| 312 | pKey2 += strlen(pKey2)+1; | 
|---|
| 313 | } // end while (*pKey2 != 0) | 
|---|
| 314 |  | 
|---|
| 315 | free (pszKeysList); | 
|---|
| 316 | } | 
|---|
| 317 | else | 
|---|
| 318 | arc = PRFERR_KEYSLIST; | 
|---|
| 319 |  | 
|---|
| 320 | return arc; | 
|---|
| 321 | } | 
|---|
| 322 |  | 
|---|
| 323 | /* | 
|---|
| 324 | *@@ xprfCopyProfile: | 
|---|
| 325 | *      this copies an entire profile. | 
|---|
| 326 | * | 
|---|
| 327 | *      The source profile must have been opened using the | 
|---|
| 328 | *      regular OS/2 PrfOpenProfile. You can also specify | 
|---|
| 329 | *      HINI_USER or HINI_SYSTEM. | 
|---|
| 330 | * | 
|---|
| 331 | *      pszNew specifies the file name for the new profile. | 
|---|
| 332 | *      This must end in *.INI. The new profile is opened | 
|---|
| 333 | *      using xprfOpenProfile, so see additional remarks there. | 
|---|
| 334 | * | 
|---|
| 335 | *      This returns 0 (NO_ERROR) on success. Otherwise either | 
|---|
| 336 | *      an OS/2 error code (ERROR_*) or one of the profile error | 
|---|
| 337 | *      codes defined in prfh.h is returned. | 
|---|
| 338 | */ | 
|---|
| 339 |  | 
|---|
| 340 | APIRET xprfCopyProfile(HINI hOld,           // in: source profile (can be HINI_USER or HINI_SYSTEM) | 
|---|
| 341 | PCSZ pszNew,         // in: new filename (can be fully qualified) | 
|---|
| 342 | PFN_PRF_PROGRESS pfnProgressCallback, | 
|---|
| 343 | ULONG ulUser,        // in: passed to pfnProgressCallback | 
|---|
| 344 | ULONG ulCount,       // in: index of INI being copied (0 <= ulCount <= ulMax) | 
|---|
| 345 | ULONG ulMax,         // in: maximum index (for progress); 0 means 1 INI, 1 means 2 INIs, ... | 
|---|
| 346 | PSZ pszFailingApp)   // out: failing app on error | 
|---|
| 347 | { | 
|---|
| 348 | APIRET  arc = NO_ERROR; | 
|---|
| 349 | PXINI   pxiniNew = NULL; | 
|---|
| 350 | ULONG   ulSizeOfAppsList; | 
|---|
| 351 |  | 
|---|
| 352 | if (pszFailingApp) | 
|---|
| 353 | *pszFailingApp = 0; | 
|---|
| 354 |  | 
|---|
| 355 | if (!pszNew) | 
|---|
| 356 | arc = ERROR_INVALID_PARAMETER; | 
|---|
| 357 | else | 
|---|
| 358 | { | 
|---|
| 359 | DosDelete((PSZ)pszNew); | 
|---|
| 360 |  | 
|---|
| 361 | // open new profile | 
|---|
| 362 | if (!(arc = xprfOpenProfile(pszNew, | 
|---|
| 363 | &pxiniNew))) | 
|---|
| 364 | { | 
|---|
| 365 | // get size of applications list | 
|---|
| 366 | if (!PrfQueryProfileSize(hOld, NULL, NULL, &ulSizeOfAppsList)) | 
|---|
| 367 | arc = PRFERR_APPSLIST; | 
|---|
| 368 | else | 
|---|
| 369 | if (ulSizeOfAppsList == 0) | 
|---|
| 370 | arc = PRFERR_APPSLIST; | 
|---|
| 371 |  | 
|---|
| 372 | if (arc == NO_ERROR) | 
|---|
| 373 | { | 
|---|
| 374 | // get applications list | 
|---|
| 375 | PSZ pApps = (PSZ)malloc(ulSizeOfAppsList); | 
|---|
| 376 | PSZ pApp2 = pApps; | 
|---|
| 377 | if (!PrfQueryProfileData(hOld, | 
|---|
| 378 | NULL, | 
|---|
| 379 | NULL, | 
|---|
| 380 | pApps, | 
|---|
| 381 | &ulSizeOfAppsList)) | 
|---|
| 382 | arc = PRFERR_APPSLIST; | 
|---|
| 383 |  | 
|---|
| 384 | // applications loop | 
|---|
| 385 |  | 
|---|
| 386 | while (   (*pApp2 != 0) | 
|---|
| 387 | && (arc == NO_ERROR) | 
|---|
| 388 | ) | 
|---|
| 389 | { | 
|---|
| 390 | CHAR szErrorKey[1000]; | 
|---|
| 391 |  | 
|---|
| 392 | // copy application (this will call prfhCopyKey in turn) | 
|---|
| 393 | if (arc = xprfCopyApp(hOld, | 
|---|
| 394 | pApp2, | 
|---|
| 395 | pxiniNew, | 
|---|
| 396 | pApp2, | 
|---|
| 397 | szErrorKey)) | 
|---|
| 398 | { | 
|---|
| 399 | if (pszFailingApp) | 
|---|
| 400 | strhncpy0(pszFailingApp, pApp2, CCHMAXPATH); | 
|---|
| 401 | } | 
|---|
| 402 | else if (pfnProgressCallback) | 
|---|
| 403 | { | 
|---|
| 404 | ULONG ulNow2, ulMax2; | 
|---|
| 405 | ulNow2 = ((1000*(pApp2-pApps)) / ulSizeOfAppsList) + (ulCount*1000); | 
|---|
| 406 | ulMax2 = (ulMax+1)*1000; | 
|---|
| 407 | if (!pfnProgressCallback(ulUser, ulNow2, ulMax2)) | 
|---|
| 408 | // aborted: | 
|---|
| 409 | arc = PRFERR_ABORTED; | 
|---|
| 410 | } | 
|---|
| 411 |  | 
|---|
| 412 | // go for next app | 
|---|
| 413 | pApp2 += strlen(pApp2)+1; | 
|---|
| 414 |  | 
|---|
| 415 | } // end while (*pApp2 != 0) && MBID_NOERROR | 
|---|
| 416 |  | 
|---|
| 417 | if (pApps) | 
|---|
| 418 | free(pApps); | 
|---|
| 419 | } | 
|---|
| 420 |  | 
|---|
| 421 | xprfCloseProfile(pxiniNew); | 
|---|
| 422 |  | 
|---|
| 423 | // progress | 
|---|
| 424 | if (pfnProgressCallback) | 
|---|
| 425 | pfnProgressCallback(ulUser, (ulCount+1) * 1000, (ulMax+1) * 1000); | 
|---|
| 426 | } | 
|---|
| 427 | } | 
|---|
| 428 |  | 
|---|
| 429 | return arc; | 
|---|
| 430 | } | 
|---|
| 431 |  | 
|---|
| 432 | /* | 
|---|
| 433 | *@@ xprfSaveINIs: | 
|---|
| 434 | *      this rewrites the OS/2 user and system profiles | 
|---|
| 435 | *      (OS2.INI and OS2SYS.INI) to disk. This is done | 
|---|
| 436 | *      by doing the following: | 
|---|
| 437 | * | 
|---|
| 438 | *      -- First, both profiles are dumped into two temporary | 
|---|
| 439 | *         profiles (using xprfCopyProfile on each of them). | 
|---|
| 440 | *         These are put into the same directory as the source | 
|---|
| 441 | *         profiles (?:\OS2 normally) with a file name extension | 
|---|
| 442 | *         of OS2*.XFL. | 
|---|
| 443 | * | 
|---|
| 444 | *      -- Only if that succeeded, the original profiles are | 
|---|
| 445 | *         renamed to OS2*.BAK. Existing OS2*.BAK files are | 
|---|
| 446 | *         deleted. | 
|---|
| 447 | * | 
|---|
| 448 | *      -- If that succeded, the temporary OS2*.XFL files are | 
|---|
| 449 | *         renamed to OS2*.INI. | 
|---|
| 450 | * | 
|---|
| 451 | *      This is now used during XShutdown to dump the system | 
|---|
| 452 | *      profiles before shutting down the system. As opposed to | 
|---|
| 453 | *      prfhSaveINIs, which was previously used, this does not | 
|---|
| 454 | *      use the Prf* functions for the target profiles so that | 
|---|
| 455 | *      those ugly "Error saving INI files" errors are less likely. | 
|---|
| 456 | * | 
|---|
| 457 | *      This returns 0 (NO_ERROR) if copying succeeded. Otherwise either | 
|---|
| 458 | *      an OS/2 error code (ERROR_*) or one of the profile error | 
|---|
| 459 | *      codes defined in prfh.h is returned. | 
|---|
| 460 | */ | 
|---|
| 461 |  | 
|---|
| 462 | APIRET xprfSaveINIs(HAB hab,               // in:  anchor block | 
|---|
| 463 | PFN_PRF_PROGRESS pfnProgressCallback, | 
|---|
| 464 | ULONG ulUser, | 
|---|
| 465 | PSZ pszFailingINI, | 
|---|
| 466 | PSZ pszFailingApp, | 
|---|
| 467 | PSZ pszFailingKey) | 
|---|
| 468 | { | 
|---|
| 469 | PRFPROFILE Profiles; | 
|---|
| 470 | APIRET  arc = NO_ERROR; | 
|---|
| 471 |  | 
|---|
| 472 | // FILESTATUS3 fs3; | 
|---|
| 473 | CHAR    szSysNew[CCHMAXPATH], | 
|---|
| 474 | szUserNew[CCHMAXPATH], | 
|---|
| 475 | szSysBackup[CCHMAXPATH], | 
|---|
| 476 | szUserBackup[CCHMAXPATH]; | 
|---|
| 477 |  | 
|---|
| 478 | /* | 
|---|
| 479 | * get system profiles: | 
|---|
| 480 | * | 
|---|
| 481 | */ | 
|---|
| 482 |  | 
|---|
| 483 | Profiles.cchUserName = Profiles.cchSysName = 0; | 
|---|
| 484 | if (!PrfQueryProfile(hab, &Profiles)) | 
|---|
| 485 | arc = PRFERR_QUERY; | 
|---|
| 486 | else | 
|---|
| 487 | { | 
|---|
| 488 | Profiles.pszUserName  = (PSZ)malloc(Profiles.cchUserName); | 
|---|
| 489 | Profiles.pszSysName  = (PSZ)malloc(Profiles.cchSysName); | 
|---|
| 490 | if (    (Profiles.pszSysName == NULL) | 
|---|
| 491 | || (Profiles.pszUserName == NULL) | 
|---|
| 492 | ) | 
|---|
| 493 | arc = PRFERR_QUERY; | 
|---|
| 494 | else | 
|---|
| 495 | if (!PrfQueryProfile(hab, &Profiles)) | 
|---|
| 496 | arc = PRFERR_QUERY; | 
|---|
| 497 | } | 
|---|
| 498 |  | 
|---|
| 499 | if (arc == NO_ERROR) | 
|---|
| 500 | { | 
|---|
| 501 | PSZ _p; | 
|---|
| 502 |  | 
|---|
| 503 | /* | 
|---|
| 504 | * create new profile names: | 
|---|
| 505 | *      same as old profiles, but with *.XFL ext. | 
|---|
| 506 | */ | 
|---|
| 507 |  | 
|---|
| 508 | // system INI | 
|---|
| 509 | strcpy(szSysBackup, Profiles.pszSysName); | 
|---|
| 510 | strcpy(szSysNew, Profiles.pszSysName); | 
|---|
| 511 | _p = strhistr(szSysBackup, ".INI"); | 
|---|
| 512 | if (!_p) | 
|---|
| 513 | arc = PRFERR_INVALID_FILE_NAME; | 
|---|
| 514 | else | 
|---|
| 515 | strcpy(_p, ".BAK"); | 
|---|
| 516 | _p = strhistr(szSysNew, ".INI"); | 
|---|
| 517 | if (!_p) | 
|---|
| 518 | arc = PRFERR_INVALID_FILE_NAME; | 
|---|
| 519 | else | 
|---|
| 520 | strcpy(_p, ".XFL"); | 
|---|
| 521 |  | 
|---|
| 522 | // user INI | 
|---|
| 523 | strcpy(szUserBackup, Profiles.pszUserName); | 
|---|
| 524 | strcpy(szUserNew, Profiles.pszUserName); | 
|---|
| 525 | _p = strhistr(szUserBackup, ".INI"); | 
|---|
| 526 | if (!_p) | 
|---|
| 527 | arc = PRFERR_INVALID_FILE_NAME; | 
|---|
| 528 | else | 
|---|
| 529 | strcpy(_p, ".BAK"); | 
|---|
| 530 | _p = strhistr(szUserNew, ".INI"); | 
|---|
| 531 | if (!_p) | 
|---|
| 532 | arc = PRFERR_INVALID_FILE_NAME; | 
|---|
| 533 | else | 
|---|
| 534 | strcpy(_p, ".XFL"); | 
|---|
| 535 |  | 
|---|
| 536 | /* | 
|---|
| 537 | * create OS2SYS.XFL: | 
|---|
| 538 | * | 
|---|
| 539 | */ | 
|---|
| 540 |  | 
|---|
| 541 | if (arc == NO_ERROR) | 
|---|
| 542 | { | 
|---|
| 543 | if (pszFailingINI) | 
|---|
| 544 | strcpy(pszFailingINI, | 
|---|
| 545 | szSysNew); | 
|---|
| 546 |  | 
|---|
| 547 | arc = xprfCopyProfile(HINI_SYSTEM, | 
|---|
| 548 | szSysNew,              // new filename | 
|---|
| 549 | pfnProgressCallback, | 
|---|
| 550 | ulUser, | 
|---|
| 551 | 0, | 
|---|
| 552 | 1, | 
|---|
| 553 | pszFailingApp); | 
|---|
| 554 | } | 
|---|
| 555 |  | 
|---|
| 556 | /* | 
|---|
| 557 | * create OS2SYS.XFL: | 
|---|
| 558 | * | 
|---|
| 559 | */ | 
|---|
| 560 |  | 
|---|
| 561 | if (arc == NO_ERROR) | 
|---|
| 562 | { | 
|---|
| 563 | if (pszFailingINI) | 
|---|
| 564 | strcpy(pszFailingINI, | 
|---|
| 565 | szUserNew); | 
|---|
| 566 |  | 
|---|
| 567 | arc = xprfCopyProfile(HINI_USER, | 
|---|
| 568 | szUserNew,              // new filename | 
|---|
| 569 | pfnProgressCallback, | 
|---|
| 570 | ulUser, | 
|---|
| 571 | 1, | 
|---|
| 572 | 1, | 
|---|
| 573 | pszFailingApp); | 
|---|
| 574 | } | 
|---|
| 575 | } | 
|---|
| 576 |  | 
|---|
| 577 | /* | 
|---|
| 578 | * renaming stuff for OS2SYS.INI | 
|---|
| 579 | * | 
|---|
| 580 | */ | 
|---|
| 581 |  | 
|---|
| 582 | if (arc == NO_ERROR) | 
|---|
| 583 | { | 
|---|
| 584 | // attrib -r -s -h -a OS2SYS.BAK | 
|---|
| 585 | doshSetPathAttr(szSysBackup, FILE_NORMAL); | 
|---|
| 586 | // delete OS2SYS.BAK | 
|---|
| 587 | DosDelete(szSysBackup); | 
|---|
| 588 | // attrib -r -s -h -a OS2SYS.INI | 
|---|
| 589 | doshSetPathAttr(Profiles.pszSysName, FILE_NORMAL); | 
|---|
| 590 | // REN OS2SYS.INI OS2SYS.BAK | 
|---|
| 591 | DosMove(Profiles.pszSysName, szSysBackup); | 
|---|
| 592 | } | 
|---|
| 593 |  | 
|---|
| 594 | /* | 
|---|
| 595 | * renaming stuff for OS2.INI | 
|---|
| 596 | * | 
|---|
| 597 | */ | 
|---|
| 598 |  | 
|---|
| 599 | if (arc == NO_ERROR) | 
|---|
| 600 | { | 
|---|
| 601 | // attrib -r -s -h -a OS2SYS.BAK | 
|---|
| 602 | doshSetPathAttr(szUserBackup, FILE_NORMAL); | 
|---|
| 603 | // delete OS2SYS.BAK | 
|---|
| 604 | DosDelete(szUserBackup); | 
|---|
| 605 | // attrib -r -s -h -a OS2SYS.INI | 
|---|
| 606 | doshSetPathAttr(Profiles.pszUserName, FILE_NORMAL); | 
|---|
| 607 | // REN OS2SYS.INI OS2SYS.BAK | 
|---|
| 608 | DosMove(Profiles.pszUserName, szUserBackup); | 
|---|
| 609 | } | 
|---|
| 610 |  | 
|---|
| 611 | if (arc == NO_ERROR) | 
|---|
| 612 | { | 
|---|
| 613 | // finally, replace system profiles | 
|---|
| 614 | if (!(arc = DosMove(szSysNew, Profiles.pszSysName))) | 
|---|
| 615 | { | 
|---|
| 616 | if (arc = DosMove(szUserNew, Profiles.pszUserName)) | 
|---|
| 617 | { | 
|---|
| 618 | if (pszFailingINI) | 
|---|
| 619 | strcpy(pszFailingINI, | 
|---|
| 620 | szUserNew); | 
|---|
| 621 | } | 
|---|
| 622 | } | 
|---|
| 623 | else | 
|---|
| 624 | { | 
|---|
| 625 | if (pszFailingINI) | 
|---|
| 626 | strcpy(pszFailingINI, | 
|---|
| 627 | szSysNew); | 
|---|
| 628 | } | 
|---|
| 629 | } | 
|---|
| 630 |  | 
|---|
| 631 | if (Profiles.pszSysName) | 
|---|
| 632 | free(Profiles.pszSysName); | 
|---|
| 633 | if (Profiles.pszUserName) | 
|---|
| 634 | free(Profiles.pszUserName); | 
|---|
| 635 |  | 
|---|
| 636 | return arc; | 
|---|
| 637 | } | 
|---|
| 638 |  | 
|---|
| 639 | // testing | 
|---|
| 640 |  | 
|---|
| 641 | #ifdef __BUILD_XPRF2_MAIN__ | 
|---|
| 642 |  | 
|---|
| 643 | BOOL _Optlink fnCallback(ULONG ulUser, ULONG ulNow, ULONG ulMax) | 
|---|
| 644 | { | 
|---|
| 645 | printf("\r done %03d%%", ulNow * 100 / ulMax); | 
|---|
| 646 | return (TRUE); | 
|---|
| 647 | } | 
|---|
| 648 |  | 
|---|
| 649 | int main(int argc, char* argv[]) | 
|---|
| 650 | { | 
|---|
| 651 | APIRET  arc = 2; | 
|---|
| 652 |  | 
|---|
| 653 | HAB     hab = WinInitialize(0); | 
|---|
| 654 |  | 
|---|
| 655 | CHAR    szFailingINI[CCHMAXPATH] = "", | 
|---|
| 656 | szFailingApp[CCHMAXPATH] = "", | 
|---|
| 657 | szFailingKey[CCHMAXPATH] = ""; | 
|---|
| 658 |  | 
|---|
| 659 | arc = xprfSaveINIs(hab, | 
|---|
| 660 | NULL, | 
|---|
| 661 | 0, | 
|---|
| 662 | szFailingINI, | 
|---|
| 663 | szFailingApp, | 
|---|
| 664 | szFailingKey); | 
|---|
| 665 |  | 
|---|
| 666 | printf("xprfCopyProfile returned %d ('%s', '%s', '%s'.\n", | 
|---|
| 667 | arc, | 
|---|
| 668 | szFailingINI, | 
|---|
| 669 | szFailingApp, | 
|---|
| 670 | szFailingKey); | 
|---|
| 671 |  | 
|---|
| 672 | WinTerminate(hab); | 
|---|
| 673 |  | 
|---|
| 674 | return arc; | 
|---|
| 675 | } | 
|---|
| 676 |  | 
|---|
| 677 | #endif | 
|---|
| 678 |  | 
|---|