home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / xwphescr.zip / XWPH0208.ZIP / src / helpers / xprf2.c < prev    next >
C/C++ Source or Header  |  2002-06-02  |  16KB  |  506 lines

  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.  
  78. APIRET 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.  
  148. APIRET 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.  
  209. APIRET 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.  
  325. APIRET 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.  
  476. int 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.  
  506.