Ignore:
Timestamp:
Oct 2, 2001, 8:28:47 PM (24 years ago)
Author:
umoeller
Message:

Misc helpers updates.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/wphandle.c

    r21 r106  
    1212 *      --  wph*   WPS object helper functions
    1313 *
    14  *      This code is mostly written by Henk Kelder and published
    15  *      with his kind permission.
     14 *      Thanks go out to Henk Kelder for telling me the
     15 *      format of the WPS INI data. With V0.9.16, this
     16 *      file was completely rewritten and no longer uses
     17 *      his code though.
    1618 *
    1719 *      Note: Version numbering in this file relates to XWorkplace version
     
    2224
    2325/*
    24  *      This file Copyright (C) 1997-2000 Ulrich M”ller,
    25  *                                        Henk Kelder.
     26 *      This file Copyright (C) 1997-2001 Ulrich M”ller,
    2627 *      This file is part of the "XWorkplace helpers" source package.
    2728 *      This is free software; you can redistribute it and/or modify
     
    4041    // as unsigned char
    4142
     43#define INCL_DOSEXCEPTIONS
     44#define INCL_DOSPROCESS
     45#define INCL_DOSERRORS
     46
    4247#define INCL_WINSHELLDATA
    4348#include <os2.h>
    44 
    45 #define OPTIONS_SIZE 32767
    4649
    4750#include <stdio.h>
     
    4952#include <stdlib.h>
    5053#include <io.h>
     54#include <setjmp.h>
    5155
    5256#include "setup.h"                      // code generation and debugging options
    5357
     58#include "helpers\except.h"
     59#include "helpers\prfh.h"
     60#include "helpers\standards.h"
     61#include "helpers\stringh.h"
     62#define INCLUDE_WPHANDLE_PRIVATE
    5463#include "helpers\wphandle.h"
    55 
    56 /****************************************************
    57  *                                                  *
    58  *  helper functions                                *
    59  *                                                  *
    60  ****************************************************/
    61 
    62 static USHORT wphSearchBufferForHandle(PBYTE pHandlesBuffer, ULONG ulBufSize, USHORT usParent, PSZ pszFname);
    63 PNODE wphFindPartName(PBYTE pHandlesBuffer, ULONG ulBufSize, USHORT usID, PSZ pszFname, USHORT usMax);
    64 
    65 #define MakeDiskHandle(usObjID) (usObjID | 0x30000)
    66 
    67 #define IsObjectDisk(hObject) ((hObject & 0x30000) == 0x30000)
     64#include "helpers\xstring.h"
    6865
    6966/*
     
    7471/* ******************************************************************
    7572 *
    76  *   Helper functions
     73 *   Load handles functions
    7774 *
    7875 ********************************************************************/
    7976
    8077/*
    81  *@@ wphQueryProfileData:
    82  *      like PrfQueryProfileData, but allocates sufficient
    83  *      memory and returns a pointer to that buffer.
    84  *      pulSize must point to a ULONG which will then
    85  *      contain the no. of copied bytes.
    86  */
    87 
    88 PBYTE wphQueryProfileData(HINI hIniSystem,    // in: can be HINI_USER or HINI_SYSTEM
    89                           PSZ pApp, PSZ pKey, // in: load what?
    90                           PULONG pulSize)     // out: bytes loaded
    91 {
    92     PBYTE pData = NULL;
    93     if (PrfQueryProfileSize(hIniSystem, pApp, pKey, pulSize))
    94     {
    95         pData = (PBYTE)malloc(*pulSize);
    96         PrfQueryProfileData(hIniSystem, pApp, pKey, pData, pulSize);
    97     }
    98     // _Pmpf(("  wphQueryProfileData(%lX, %s, %s, %d)", hIniSystem, pApp, pKey, *pulSize));
    99     return (pData);
    100 }
    101 
    102 /*
    103  *@@ wphEnumProfileKeys:
    104  *      allocates memory for a buffer and copies the keys
    105  *      for pApp into it.
    106  *      Returns the pointer to the buffer.
    107  *      pulKeysSize must point to a ULONG which will then
    108  *      contain the size of the returned buffer.
    109  */
    110 
    111 PBYTE wphEnumProfileKeys(HINI hIniSystem,       // in: can be HINI_USER or HINI_SYSTEM
    112                          PSZ pApp,              // in: app to query
    113                          PULONG pulKeysSize)    // out: sizeof(return buffer)
    114 {
    115     PBYTE pszKeys = NULL;
    116     if (PrfQueryProfileSize(hIniSystem, pApp, NULL, pulKeysSize))
    117     {
    118         pszKeys = (PBYTE)malloc(*pulKeysSize);
    119         if (pszKeys)
    120             PrfQueryProfileData(hIniSystem, pApp, NULL, pszKeys, pulKeysSize);
    121     }
    122     return (pszKeys);
    123 }
    124 
    125 /*
    126  * wphResetBlockBuffer:
    127  *      Reset the block buffer, make sure the buffer is re-read.
    128  */
    129 
    130 /* VOID wphResetBlockBuffer(VOID)
    131 {
    132    if (pHandlesBuffer)
    133    {
    134        free(pHandlesBuffer);
    135        pHandlesBuffer = NULL;
    136    }
    137 } */
    138 
    139 /*
    14078 *@@ wphQueryActiveHandles:
    141  *      this copies the contents of PM_Workplace:ActiveHandles
    142  *      in OS2SYS.INI into a given buffer. There are always two
    143  *      buffers in OS2SYS.INI for object handles, called
    144  *      "PM_Workplace:HandlesX" with "X" either being "0" or "1".
     79 *      returns the value of PM_Workplace:ActiveHandles
     80 *      in OS2SYS.INI as a new buffer.
     81 *
     82 *      There are always two buffers in OS2SYS.INI for object
     83 *      handles, called "PM_Workplace:HandlesX" with "X" either
     84 *      being "0" or "1".
     85 *
    14586 *      It seems that every time the WPS does something in the
    14687 *      handles section, it writes the data to the inactive
     
    14990 *      by creating a shadow on your Desktop.
    15091 *
    151  *      This function copies the key only, but not the actual
    152  *      handles blocks (use wphReadAllBlocks for that).
     92 *      This returns a new PSZ which the caller must free()
     93 *      after use.
    15394 *
    15495 *      This gets called by the one-shot function
    15596 *      wphQueryHandleFromPath.
    156  */
    157 
    158 BOOL wphQueryActiveHandles(HINI hIniSystem,       // in: can be HINI_USER or HINI_SYSTEM
    159                            PSZ pszHandlesAppName, // out: active handles buffer.
    160                            USHORT usMax)          // in:  sizeof(pszHandlesAppName)
    161 {
    162     PBYTE pszHandles;
    163     ULONG ulProfileSize;
    164 
    165     pszHandles = wphQueryProfileData(hIniSystem,
    166                                      ACTIVEHANDLES, HANDLESAPP,
    167                                      &ulProfileSize);
    168     if (!pszHandles)
    169     {
    170         strncpy(pszHandlesAppName, HANDLES, usMax-1);
    171         return TRUE;
    172     }
    173     // fNewFormat = TRUE;
    174     strncpy(pszHandlesAppName, pszHandles, usMax-1);
    175     free(pszHandles);
    176     return TRUE;
     97 *
     98 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten
     99 */
     100
     101APIRET wphQueryActiveHandles(HINI hiniSystem,
     102                             PSZ *ppszActiveHandles)
     103{
     104    PSZ pszActiveHandles;
     105    if (pszActiveHandles = prfhQueryProfileData(hiniSystem,
     106                                                WPINIAPP_ACTIVEHANDLES,
     107                                                WPINIAPP_HANDLESAPP,
     108                                                NULL))
     109    {
     110        *ppszActiveHandles = pszActiveHandles;
     111        return (NO_ERROR);
     112    }
     113
     114    return (ERROR_WPH_NO_ACTIVEHANDLES_DATA);
     115}
     116
     117/*
     118 *@@ wphQueryBaseClassesHiwords:
     119 *      returns the hiwords for the WPS base
     120 *      classes. Unless the user's system is
     121 *      really badly configured, this should
     122 *      set
     123 *
     124 *      --  pusHiwordAbstract to 2;
     125 *      --  pusHiwordFileSystem to 3.
     126 *
     127 *      Returns:
     128 *
     129 *      --  NO_ERROR
     130 *
     131 *      --  ERROR_WPH_NO_BASECLASS_DATA
     132 *
     133 *      --  ERROR_WPH_INCOMPLETE_BASECLASS_DATA
     134 *
     135 *      This gets called automatically from wphLoadHandles.
     136 *
     137 *@@added V0.9.16 (2001-10-02) [umoeller]
     138 */
     139
     140APIRET wphQueryBaseClassesHiwords(HINI hiniUser,
     141                                  PUSHORT pusHiwordAbstract,
     142                                  PUSHORT pusHiwordFileSystem)
     143{
     144    APIRET arc = NO_ERROR;
     145
     146    // get the index of WPFileSystem from the base classes list...
     147    // we need this to determine the hiword for file-system handles
     148    // properly. Normally, this should be 3.
     149    ULONG cbBaseClasses = 0;
     150    PSZ pszBaseClasses;
     151    if (pszBaseClasses = prfhQueryProfileData(hiniUser,
     152                                              "PM_Workplace:BaseClass",
     153                                              "ClassList",
     154                                              &cbBaseClasses))
     155    {
     156        // parse that buffer... these has the base class names,
     157        // separated by 0. List is terminated by two zeroes.
     158        PSZ     pszClassThis = pszBaseClasses;
     159        ULONG   ulHiwordThis = 1;
     160        while (    (*pszClassThis)
     161                && (pszClassThis - pszBaseClasses < cbBaseClasses)
     162              )
     163        {
     164            if (!strcmp(pszClassThis, "WPFileSystem"))
     165                *pusHiwordFileSystem = ulHiwordThis;
     166            else if (!strcmp(pszClassThis, "WPAbstract"))
     167                *pusHiwordAbstract = ulHiwordThis;
     168
     169            ulHiwordThis++;
     170            pszClassThis += strlen(pszClassThis) + 1;
     171        }
     172
     173        // now check if we found both
     174        if (    (!(*pusHiwordFileSystem))
     175             || (!(*pusHiwordAbstract))
     176           )
     177            arc = ERROR_WPH_INCOMPLETE_BASECLASS_DATA;
     178
     179        free(pszBaseClasses);
     180    }
     181    else
     182        arc = ERROR_WPH_NO_BASECLASS_DATA;
     183
     184    return (arc);
     185}
     186
     187/*
     188 *@@ wphRebuildNodeHashTable:
     189 *
     190 *      Returns:
     191 *
     192 *      --  NO_ERROR
     193 *
     194 *      --  ERROR_INVALID_PARAMETER
     195 *
     196 *      --  ERROR_WPH_CORRUPT_HANDLES_DATA
     197 *
     198 *@@added V0.9.16 (2001-10-02) [umoeller]
     199 */
     200
     201APIRET wphRebuildNodeHashTable(PHANDLESBUF pHandlesBuf)
     202{
     203    APIRET arc = NO_ERROR;
     204
     205    if (    (!pHandlesBuf)
     206         || (!pHandlesBuf->pbData)
     207         || (!pHandlesBuf->cbData)
     208       )
     209        arc = ERROR_INVALID_PARAMETER;
     210    else
     211    {
     212        // start at beginning of buffer
     213        PBYTE pCur = pHandlesBuf->pbData + 4;
     214        PBYTE pEnd = pHandlesBuf->pbData + pHandlesBuf->cbData;
     215
     216        memset(pHandlesBuf->NodeHashTable, 0, sizeof(pHandlesBuf->NodeHashTable));
     217
     218        // now set up hash table
     219        while (pCur < pEnd)
     220        {
     221            if (!memicmp(pCur, "DRIV", 4))
     222            {
     223                // pCur points to a DRIVE node:
     224                // these never have handles, so skip this
     225                PDRIV pDriv = (PDRIV)pCur;
     226                pCur += sizeof(DRIV) + strlen(pDriv->szName);
     227            }
     228            else if (!memicmp(pCur, "NODE", 4))
     229            {
     230                // pCur points to a regular NODE: offset pointer first
     231                PNODE pNode = (PNODE)pCur;
     232                // store PNODE in hash table
     233                pHandlesBuf->NodeHashTable[pNode->usHandle] = pNode;
     234                pCur += sizeof (NODE) + pNode->usNameSize;
     235            }
     236            else
     237            {
     238                arc = ERROR_WPH_CORRUPT_HANDLES_DATA;
     239                break;
     240            }
     241        }
     242    }
     243
     244    if (!arc)
     245        pHandlesBuf->fNodeHashTableValid = TRUE;
     246
     247    return (arc);
     248}
     249
     250/*
     251 *@@ wphLoadHandles:
     252 *      returns a HANDLESBUF structure which will hold
     253 *      all the handles from OS2SYS.INI. In addition,
     254 *      this calls wphQueryBaseClassesHiwords and puts
     255 *      the hiwords for WPAbstract and WPFileSystem into
     256 *      the HANDLESBUF as well.
     257 *
     258 *      Prerequisite before using any of the other wph*
     259 *      functions.
     260 *
     261 *      Call wphFreeHandles to free all data allocated
     262 *      by this function.
     263 *
     264 *      Returns:
     265 *
     266 *      --  NO_ERROR
     267 *
     268 *      --  ERROR_NOT_ENOUGH_MEMORY
     269 *
     270 *      --  ERROR_INVALID_PARAMETER
     271 *
     272 *      --  ERROR_WPH_NO_HANDLES_DATA: cannot read handle blocks.
     273 *
     274 *      --  ERROR_WPH_CORRUPT_HANDLES_DATA: cannot read handle blocks.
     275 *
     276 *@@added V0.9.16 (2001-10-02) [umoeller]
     277 */
     278
     279APIRET wphLoadHandles(HINI hiniUser,      // in: HINI_USER or other INI handle
     280                      HINI hiniSystem,    // in: HINI_SYSTEM or other INI handle
     281                      const char *pcszActiveHandles,
     282                      PHANDLESBUF *ppHandlesBuf)
     283{
     284    APIRET arc = NO_ERROR;
     285
     286    if (!ppHandlesBuf)
     287        arc = ERROR_INVALID_PARAMETER;
     288    else
     289    {
     290        PSZ pszKeysList;
     291        if (!(arc = prfhQueryKeysForApp(hiniSystem,
     292                                        pcszActiveHandles,
     293                                        &pszKeysList)))
     294        {
     295            PHANDLESBUF pReturn = NULL;
     296
     297            ULONG   ulHighestBlock = 0,
     298                    ul,
     299                    cbTotal;
     300            PBYTE   pbData;
     301
     302            const char *pKey2 = pszKeysList;
     303            while (*pKey2)
     304            {
     305                if (!memicmp((PVOID)pKey2, "BLOCK", 5))
     306                {
     307                    ULONG ulBlockThis = atoi(pKey2 + 5);
     308                    if (ulBlockThis > ulHighestBlock)
     309                        ulHighestBlock = ulBlockThis;
     310                }
     311
     312                pKey2 += strlen(pKey2)+1; // next key
     313            }
     314
     315            free(pszKeysList);
     316
     317            if (!ulHighestBlock)
     318                arc = ERROR_WPH_NO_HANDLES_DATA;
     319            else
     320            {
     321                // now go read the data
     322                // (BLOCK1, BLOCK2, ..., BLOCKn)
     323                cbTotal = 0;
     324                pbData = NULL;
     325                for (ul = 1;
     326                     ul <= ulHighestBlock;
     327                     ul++)
     328                {
     329                    ULONG   cbBlockThis;
     330                    CHAR    szBlockThis[10];
     331                    sprintf(szBlockThis, "BLOCK%d", ul);
     332                    if (!PrfQueryProfileSize(hiniSystem,
     333                                             (PSZ)pcszActiveHandles,
     334                                             szBlockThis,
     335                                             &cbBlockThis))
     336                    {
     337                        arc = ERROR_WPH_CORRUPT_HANDLES_DATA;
     338                        break;
     339                    }
     340                    else
     341                    {
     342                        ULONG   cbTotalOld = cbTotal;
     343                        cbTotal += cbBlockThis;
     344                        if (!(pbData = realloc(pbData, cbTotal)))
     345                                // on first call, pbData is NULL and this
     346                                // behaves like malloc()
     347                        {
     348                            arc = ERROR_NOT_ENOUGH_MEMORY;
     349                            break;
     350                        }
     351
     352                        if (!PrfQueryProfileData(hiniSystem,
     353                                                 (PSZ)pcszActiveHandles,
     354                                                 szBlockThis,
     355                                                 pbData + cbTotalOld,
     356                                                 &cbBlockThis))
     357                        {
     358                            arc = ERROR_WPH_CORRUPT_HANDLES_DATA;
     359                            break;
     360                        }
     361                    }
     362                }
     363            }
     364
     365            if (!arc)
     366            {
     367                // all went OK:
     368                if (pReturn = NEW(HANDLESBUF))
     369                {
     370                    ZERO(pReturn);
     371
     372                    pReturn->pbData = pbData;
     373                    pReturn->cbData = cbTotal;
     374
     375                    // and load the hiwords too
     376                    if (!(arc = wphQueryBaseClassesHiwords(hiniUser,
     377                                                           &pReturn->usHiwordAbstract,
     378                                                           &pReturn->usHiwordFileSystem)))
     379                        *ppHandlesBuf = pReturn;
     380                }
     381                else
     382                    arc = ERROR_NOT_ENOUGH_MEMORY;
     383            }
     384
     385            if (arc)
     386                // error:
     387                wphFreeHandles(&pReturn);
     388        }
     389    }
     390
     391    return (arc);
     392}
     393
     394/*
     395 *@@ wphFreeHandles:
     396 *      frees all data allocated by wphLoadHandles
     397 *      and sets *ppHandlesBuf to NULL, for safety.
     398 *
     399 *@@added V0.9.16 (2001-10-02) [umoeller]
     400 */
     401
     402APIRET wphFreeHandles(PHANDLESBUF *ppHandlesBuf)
     403{
     404    APIRET arc = NO_ERROR;
     405
     406    if (ppHandlesBuf && *ppHandlesBuf)
     407    {
     408        PBYTE pbData;
     409        if (pbData = (*ppHandlesBuf)->pbData)
     410            free(pbData);
     411
     412        free(*ppHandlesBuf);
     413        *ppHandlesBuf = NULL;
     414    }
     415    else
     416        arc = ERROR_INVALID_PARAMETER;
     417
     418    return (arc);
    177419}
    178420
     
    195437 */
    196438
    197 BOOL wphReadAllBlocks(HINI hiniSystem,       // in: can be HINI_USER or HINI_SYSTEM
     439/* BOOL wphReadAllBlocks(HINI hiniSystem,       // in: can be HINI_USER or HINI_SYSTEM
    198440                      PSZ pszActiveHandles,  // in: active handles section
    199441                      PBYTE* ppBlock,        // in/out: pointer to buffer, which
     
    246488    if (!(*ppBlock))
    247489    {
    248        /* MessageBox("wphReadAllBlocks", "Not enough memory for profile data!"); */
    249490         free(pbAllBlocks);
    250491         return FALSE;
     
    278519    free(pbAllBlocks);
    279520    return TRUE;
    280 }
     521} */
    281522
    282523/* ******************************************************************
     
    289530 *@@ wphSearchBufferForHandle:
    290531 *      returns the four-digit object handle which corresponds
    291  *      to pszFname, searching pHandlesBuffer. Note that you
     532 *      to pszFilename, searching pHandlesBuffer. Note that you
    292533 *      must OR the return value with 0x30000 to make this
    293534 *      a valid WPS file-system handle.
     
    304545                                USHORT usParent,      // in: parent NODE ID;
    305546                                                      //     must be 0 initially
    306                                 PSZ pszFname) // in: fully qlf'd filename to search for
     547                                PSZ pszFilename) // in: fully qlf'd filename to search for
    307548{
    308549    PDRIV pDriv;
     
    313554    USHORT usPartSize;
    314555
    315     // _Pmpf(("Entering wphSearchBufferForHandle for %s", pszFname));
     556    // _Pmpf(("Entering wphSearchBufferForHandle for %s", pszFilename));
    316557
    317558    // The composed BLOCKs in the handles buffer make up a tree of
     
    334575    // So first find the length of the first filename part (which
    335576    // should be 2 for the drive letter, "C:")
    336     p = strchr(pszFname, '\\');
     577    p = strchr(pszFilename, '\\');
    337578    if (p)
    338579        // backslash found:
    339         usPartSize = p - pszFname;      // extract first part
     580        usPartSize = p - pszFilename;      // extract first part
    340581    else
    341         usPartSize = strlen(pszFname);
     582        usPartSize = strlen(pszFilename);
    342583
    343584    // now set the pointer for the end of the BLOCKs buffer
     
    348589    pCur = pHandlesBuffer + 4;
    349590
    350     // _Pmpf(("  Searching for: %s, usPartSize: %d", pszFname, usPartSize));
     591    // _Pmpf(("  Searching for: %s, usPartSize: %d", pszFilename, usPartSize));
    351592
    352593    // go!
     
    386627
    387628                    // do the partnames match too?
    388                     if (memicmp(pszFname, pNode->szName, usPartSize) == 0)
     629                    if (memicmp(pszFilename, pNode->szName, usPartSize) == 0)
    389630                    {
    390631                        // OK!! proper NODE found!
     
    393634                        // now check if this was the last NODE
    394635                        // we were looking for
    395                         if (strlen(pszFname) == usPartSize)
     636                        if (strlen(pszFilename) == usPartSize)
    396637                           // yes: return ID
    397638                           return (pNode->usHandle);
     
    399640                        // else: update our status;
    400641                        // get next partname
    401                         pszFname += usPartSize + 1;
     642                        pszFilename += usPartSize + 1;
    402643                        // calc next partname length
    403                         p = strchr(pszFname, '\\');
     644                        p = strchr(pszFilename, '\\');
    404645                        if (p)
    405                            usPartSize = p - pszFname;
     646                            usPartSize = p - pszFilename;
    406647                        else
    407                            usPartSize = strlen(pszFname);
     648                            usPartSize = strlen(pszFilename);
    408649
    409650                        // get next parent to search for
     
    426667/*
    427668 *@@ wphQueryHandleFromPath:
    428  *      find the object handle for pszName; this
    429  *      can either be an object ID ("<WP_DESKTOP>")
    430  *      or a fully qualified filename.
     669 *      finds the object handle for the given fully qualified
     670 *      filename.
    431671 *      This is a one-shot function, using wphQueryActiveHandles,
    432672 *      wphReadAllBlocks, and wphSearchBufferForHandle.
    433673 *
    434674 *      Returns:
    435  *      --  -1:     file does not exist
    436  *      --  -2:     error querying handles buffer
    437  *      --  0:      object handle not found; might not exist
    438  *      --  other:  found object handle
    439  *
    440  *      NOTE: This function uses C runtime library
    441  *      string comparison functions. These only work
    442  *      properly if you have set the locale for the
    443  *      C runtime properly. This is, for example, a
    444  *      problem with file names containing German umlauts,
    445  *      which are not found properly.
    446  *      You should put some
    447  +          setlocale(LC_ALL, "");
    448  *      statement somewhere, which reacts to the LANG
    449  *      variable which OS/2 puts into CONFIG.SYS per
    450  *      default.
    451  */
    452 
    453 HOBJECT wphQueryHandleFromPath(HINI hIniUser,   // in: user ini file
    454                                HINI hIniSystem, // in: system ini file
    455                                PSZ pszName)     // in: fully qlf'd filename
    456 {
    457     PBYTE       pHandlesBuffer = NULL;
    458     ULONG       cbHandlesBuffer = 0,
    459                 cbLocation = 0;
    460     USHORT      usObjID;
     675 *
     676 *      --  NO_ERROR: *phobj has received the object handle.
     677 *
     678 *      --  ERROR_FILE_NOT_FOUND: file does not exist.
     679 *
     680 *      plus the error codes of the other wph* functions called.
     681 *
     682 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten
     683 */
     684
     685APIRET wphQueryHandleFromPath(HINI hiniUser,      // in: HINI_USER or other INI handle
     686                              HINI hiniSystem,    // in: HINI_SYSTEM or other INI handle
     687                              const char *pcszName,    // in: fully qlf'd filename
     688                              HOBJECT *phobj)      // out: object handle found if NO_ERROR
     689{
     690    APIRET      arc = NO_ERROR;
    461691    PVOID       pvData;
    462     HOBJECT     hObject = 0L;
    463     BYTE        szFullPath[300];
    464     CHAR        szActiveHandles[100];
    465 
    466     // _Pmpf(("wphQueryHandleFromPath: %s", pszName));
    467 
    468     // try to get the objectID via PM_Workplace:Location, since
    469     // pszName might also be a "<WP_DESKTOP>" like thingy
    470     pvData = wphQueryProfileData(hIniUser,
    471                                  LOCATION,   // "PM_Workplace:Location" (<WP_DESKTOP> etc.)
    472                                  pszName,
    473                                  &cbLocation);
    474     if (pvData)
    475     {
    476         // found there:
    477         if (cbLocation >= sizeof(HOBJECT))
    478             hObject = *(PULONG)pvData;
    479         free(pvData);
    480         // _Pmpf(("  object ID found, hObject: %lX", hObject));
    481     }
    482     if (hObject)
    483         return (hObject);
    484 
    485     // not found there: is pszName an existing pathname?
    486     if (access(pszName, 0))  // check existence
    487     {
    488         // == -1: file does not exist
    489         // _Pmpf(("  path not found, returning -1"));
    490         return (-1);
    491     }
    492 
    493     // else: make full path for pszName
    494     _fullpath(szFullPath, pszName, sizeof(szFullPath));
    495 
    496     // check if the HandlesBlock is valid
    497     wphQueryActiveHandles(hIniSystem, szActiveHandles, sizeof(szActiveHandles));
    498     // _Pmpf(("  szActiveHandles: %s", szActiveHandles));
    499 
    500     // now load all the BLOCKs into a common buffer
    501     if (!wphReadAllBlocks(hIniSystem,
    502                            szActiveHandles,
    503                            &pHandlesBuffer, &cbHandlesBuffer))
    504         // error:
    505         return (-2);
    506 
    507     // and search that buffer
    508     usObjID = wphSearchBufferForHandle(pHandlesBuffer,
    509                                        cbHandlesBuffer,
    510                                        0,                  // usParent
    511                                        szFullPath);
    512 
    513     if (usObjID)
    514         // found: OR 0x30000
    515         hObject = MakeDiskHandle(usObjID);
    516 
    517     free(pHandlesBuffer);
    518 
    519     return (hObject);
     692
     693    TRY_LOUD(excpt1)
     694    {
     695        // not found there: check the handles then
     696        PSZ pszActiveHandles;
     697        if (arc = wphQueryActiveHandles(hiniSystem, &pszActiveHandles))
     698            _Pmpf((__FUNCTION__ ": wphQueryActiveHandles returned %d", arc));
     699        else
     700        {
     701            PHANDLESBUF pHandlesBuf;
     702            if (arc = wphLoadHandles(hiniUser,
     703                                     hiniSystem,
     704                                     pszActiveHandles,
     705                                     &pHandlesBuf))
     706                _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc));
     707            else
     708            {
     709                USHORT      usObjID;
     710                CHAR        szFullPath[2*CCHMAXPATH];
     711                _fullpath(szFullPath, (PSZ)pcszName, sizeof(szFullPath));
     712
     713                // search that buffer
     714                if (usObjID = wphSearchBufferForHandle(pHandlesBuf->pbData,
     715                                                       pHandlesBuf->cbData,
     716                                                       0,                  // usParent
     717                                                       szFullPath))
     718                    // found: OR 0x30000
     719                    *phobj = usObjID | (pHandlesBuf->usHiwordFileSystem << 16);
     720                else
     721                    arc = ERROR_FILE_NOT_FOUND;
     722
     723                wphFreeHandles(&pHandlesBuf);
     724            }
     725
     726            free(pszActiveHandles);
     727        }
     728    }
     729    CATCH(excpt1)
     730    {
     731        arc = ERROR_WPH_CRASHED;
     732    } END_CATCH();
     733
     734    return (arc);
    520735}
    521736
     
    527742
    528743/*
    529  *@@ wphFindPartName:
    530  *      this searches pHandlesBuffer for usHandle and, if found,
    531  *      appends the object partname to pszFname.
    532  *      This function recurses, if neccessary.
    533  *
    534  *      This gets called by the one-shot function
    535  *      wphQueryPathFromHandle.
    536  */
    537 
    538 PNODE wphFindPartName(PBYTE pHandlesBuffer, // in: handles buffer
    539                       ULONG ulBufSize,      // in: buffer size
    540                       USHORT usHandle,      // in: handle to search for
    541                       PSZ pszFname,         // out: object partname
    542                       USHORT usMax)         // in: sizeof(pszFname)
    543 {
    544     PDRIV pDriv;
     744 *@@ ComposeThis:
     745 *      helper for wphComposePath recursion.
     746 *
     747 *@@added V0.9.16 (2001-10-02) [umoeller]
     748 */
     749
     750APIRET ComposeThis(PHANDLESBUF pHandlesBuf,
     751                   USHORT usHandle,         // in: handle to search for
     752                   PXSTRING pstrFilename,   // in/out: filename
     753                   PNODE *ppNode)           // out: node found (ptr can be NULL)
     754{
     755    APIRET arc = NO_ERROR;
    545756    PNODE pNode;
    546     PBYTE p, pEnd;
    547     USHORT usSize;
    548 
    549     pEnd = pHandlesBuffer + ulBufSize;
    550     p = pHandlesBuffer + 4;
    551     while (p < pEnd)
    552     {
    553         if (!memicmp(p, "DRIV", 4))
    554         {
    555             pDriv = (PDRIV)p;
    556             p += sizeof(DRIV) + strlen(pDriv->szName);
    557         }
    558         else if (!memicmp(p, "NODE", 4))
    559         {
    560             pNode = (PNODE)p;
    561             p += sizeof (NODE) + pNode->usNameSize;
    562             if (pNode->usHandle == usHandle)
    563             {
    564                 usSize = usMax - strlen(pszFname);
    565                 if (usSize > pNode->usNameSize)
    566                     usSize = pNode->usNameSize;
    567                 if (pNode->usParentHandle)
    568                 {
    569                     if (!wphFindPartName(pHandlesBuffer, ulBufSize,
    570                                          pNode->usParentHandle,
    571                                          pszFname,
    572                                          usMax))
    573                        return (NULL);
    574                     strcat(pszFname, "\\");
    575                     strncat(pszFname, pNode->szName, usSize);
    576                     return pNode;
    577                 }
     757    if (pNode = pHandlesBuf->NodeHashTable[usHandle])
     758    {
     759        // handle exists:
     760        if (pNode->usParentHandle)
     761        {
     762            // node has parent:
     763            // recurse first
     764            if (arc = ComposeThis(pHandlesBuf,
     765                                  pNode->usParentHandle,
     766                                  pstrFilename,
     767                                  ppNode))
     768            {
     769                if (arc == ERROR_INVALID_HANDLE)
     770                    // parent handle not found:
     771                    arc = ERROR_WPH_INVALID_PARENT_HANDLE;
     772                // else leave the APIRET, this might be dangerous
     773            }
     774            else
     775            {
     776                // no error:
     777                xstrcatc(pstrFilename, '\\');
     778                xstrcat(pstrFilename, pNode->szName, pNode->usNameSize);
     779            }
     780        }
     781        else
     782            // no parent:
     783            xstrcpy(pstrFilename, pNode->szName, pNode->usNameSize);
     784    }
     785    else
     786        arc = ERROR_INVALID_HANDLE;
     787
     788    if (!arc)
     789        if (ppNode)
     790            *ppNode = pNode;
     791
     792    return (arc);
     793}
     794
     795/*
     796 *@@ wphComposePath:
     797 *      returns the fully qualified path name for the specified
     798 *      file-system handle. This function is very fast because
     799 *      it uses a hash table for all the handles internally.
     800 *
     801 *      Warning: This calls a helper, which recurses.
     802 *
     803 *      This returns:
     804 *
     805 *      --  NO_ERROR
     806 *
     807 *      --  ERROR_WPH_CORRUPT_HANDLES_DATA: buffer data cannot be parsed.
     808 *
     809 *      --  ERROR_WPH_INVALID_HANDLE: usHandle cannot be found.
     810 *
     811 *      --  ERROR_WPH_INVALID_PARENT_HANDLE: a handle was found
     812 *          that has a broken parent handle.
     813 *
     814 *      --  ERROR_BUFFER_OVERFLOW: cbFilename is too small to
     815 *          hold the full path that was composed.
     816 *
     817 *@@added V0.9.16 (2001-10-02) [umoeller]
     818 */
     819
     820APIRET wphComposePath(PHANDLESBUF pHandlesBuf,
     821                      USHORT usHandle,      // in: loword of handle to search for
     822                      PSZ pszFilename,
     823                      ULONG cbFilename,
     824                      PNODE *ppNode)        // out: node found (ptr can be NULL)
     825{
     826    APIRET arc = NO_ERROR;
     827
     828    TRY_LOUD(excpt1)
     829    {
     830        if (!pHandlesBuf->fNodeHashTableValid)
     831            arc = wphRebuildNodeHashTable(pHandlesBuf);
     832
     833        if (!arc)
     834        {
     835            XSTRING str;
     836            xstrInit(&str, CCHMAXPATH);
     837            if (!(arc = ComposeThis(pHandlesBuf,
     838                                    usHandle,
     839                                    &str,
     840                                    ppNode)))
     841                if (str.ulLength > cbFilename - 1)
     842                    arc = ERROR_BUFFER_OVERFLOW;
    578843                else
    579                 {
    580                     strncpy(pszFname, pNode->szName, usSize);
    581                     return pNode;
    582                 }
    583             }
    584         }
    585         else
    586            return (NULL);
    587     }
    588     return (NULL);
     844                    memcpy(pszFilename,
     845                           str.psz,
     846                           str.ulLength + 1);
     847        }
     848    }
     849    CATCH(excpt1)
     850    {
     851        arc = ERROR_WPH_CRASHED;
     852    } END_CATCH();
     853
     854    return (arc);
    589855}
    590856
     
    596862 *      wphReadAllBlocks, and wphFindPartName.
    597863 *
    598  *@@changed V0.9.4 (2000-08-03) [umoeller]: now returning BOOL
    599  */
    600 
    601 BOOL wphQueryPathFromHandle(HINI hIniSystem,    // in: HINI_SYSTEM or other INI handle
    602                             HOBJECT hObject,    // in: five-digit object handle
    603                             PSZ pszFname,       // out: filename, if found
    604                             USHORT usMax)       // in: sizeof(*pszFname)
    605 {
    606     BOOL        brc = FALSE;
    607 
    608     if (IsObjectDisk(hObject))
    609     {
    610         // use lower byte only
    611         USHORT      usObjID = LOUSHORT(hObject);
    612 
    613         PBYTE       pHandlesBuffer = NULL;
    614         ULONG       cbHandlesBuffer = 0;
    615 
    616         CHAR        szActiveHandles[100];
    617         // PNODE       pReturnNode = 0;
    618 
    619         wphQueryActiveHandles(hIniSystem, szActiveHandles, sizeof(szActiveHandles));
    620 
    621         if (wphReadAllBlocks(hIniSystem,
    622                              szActiveHandles,
    623                              &pHandlesBuffer,
    624                              &cbHandlesBuffer))
    625         {
    626             memset(pszFname, 0, usMax);
    627             if (wphFindPartName(pHandlesBuffer,
    628                                 cbHandlesBuffer,
    629                                 usObjID,
    630                                 pszFname,
    631                                 usMax))
    632                 brc = TRUE;
    633 
    634             free(pHandlesBuffer);
    635         }
    636     }
    637 
    638     return (brc);
     864 *      Returns:
     865 *
     866 *      --  NO_ERROR
     867 *
     868 *      --  ERROR_INVALID_HANDLE: hObject is invalid.
     869 *
     870 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten
     871 */
     872
     873APIRET wphQueryPathFromHandle(HINI hiniUser,      // in: HINI_USER or other INI handle
     874                              HINI hiniSystem,    // in: HINI_SYSTEM or other INI handle
     875                              HOBJECT hObject,    // in: 32-bit object handle
     876                              PSZ pszFilename,    // out: filename, if found
     877                              ULONG cbFilename)   // in: sizeof(*pszFilename)
     878{
     879    APIRET arc = NO_ERROR;
     880
     881    TRY_LOUD(excpt1)
     882    {
     883        PSZ pszActiveHandles;
     884        if (arc = wphQueryActiveHandles(hiniSystem, &pszActiveHandles))
     885            _Pmpf((__FUNCTION__ ": wphQueryActiveHandles returned %d", arc));
     886        else
     887        {
     888            PHANDLESBUF pHandlesBuf;
     889            if (arc = wphLoadHandles(hiniUser,
     890                                     hiniSystem,
     891                                     pszActiveHandles,
     892                                     &pHandlesBuf))
     893                _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc));
     894            else
     895            {
     896                // is this really a file-system object?
     897                if (HIUSHORT(hObject) == pHandlesBuf->usHiwordFileSystem)
     898                {
     899                    // use loword only
     900                    USHORT      usObjID = LOUSHORT(hObject);
     901
     902                    memset(pszFilename, 0, cbFilename);
     903                    arc = wphComposePath(pHandlesBuf,
     904                                         usObjID,
     905                                         pszFilename,
     906                                         cbFilename,
     907                                         NULL);
     908
     909                    _Pmpf((__FUNCTION__ ": wphFindPartName returned %d", arc));
     910                }
     911
     912                wphFreeHandles(&pHandlesBuf);
     913            }
     914
     915            free(pszActiveHandles);
     916        }
     917    }
     918    CATCH(excpt1)
     919    {
     920        arc = ERROR_WPH_CRASHED;
     921    } END_CATCH();
     922
     923    return (arc);
    639924}
    640925
    641 /* ******************************************************************
    642  *
    643  *   Manipulation functions
    644  *
    645  ********************************************************************/
    646 
    647 /*
    648  *@@ WriteAllBlocks:
    649  *      writes all blocks back to OS2SYS.INI.
    650  *
    651  *@@added V0.9.5 (2000-08-20) [umoeller]
    652  */
    653 
    654 BOOL WriteAllBlocks(HINI hini, PSZ pszHandles, PBYTE pBuffer, ULONG ulSize)
    655 {
    656     PSZ     p,
    657             pEnd;
    658     BYTE    szBlockName[10];
    659     INT     iCurBlock;
    660     ULONG   ulCurSize;
    661     PBYTE   pStart;
    662     PDRIV   pDriv;
    663     PNODE   pNode;
    664 
    665     pStart    = pBuffer;
    666     ulCurSize = 4;
    667     p    = pBuffer + 4;
    668     pEnd = pBuffer + ulSize;
    669     iCurBlock = 1;
    670     while (p < pEnd)
    671     {
    672         // ULONG   cbWrite = 0;
    673         while (p < pEnd)
    674         {
    675             ULONG   ulPartSize = 0;
    676             if (!memicmp(p, "DRIV", 4))
    677             {
    678                 pDriv = (PDRIV)p;
    679                 ulPartSize = sizeof(DRIV) + strlen(pDriv->szName);
    680             }
    681             else if (!memicmp(p, "NODE", 4))
    682             {
    683                 pNode = (PNODE)p;
    684                 ulPartSize = sizeof (NODE) + pNode->usNameSize;
    685             }
    686 
    687             if (ulCurSize + ulPartSize > 0x0000FFFF)
    688                 break;
    689 
    690             ulCurSize += ulPartSize;
    691             p         += ulPartSize;
    692         }
    693         sprintf(szBlockName, "BLOCK%d", iCurBlock++);
    694 
    695         PrfWriteProfileData(hini,
    696                             pszHandles,     // app
    697                             szBlockName,    // key
    698                             pStart,
    699                             ulCurSize);
    700         pStart    = p;
    701         ulCurSize = 0;
    702     }
    703 
    704     while (iCurBlock < 20)
    705     {
    706         ULONG ulBlockSize;
    707 
    708         sprintf(szBlockName, "BLOCK%d", iCurBlock++);
    709 
    710         if (PrfQueryProfileSize(hini,
    711                                 pszHandles,
    712                                 szBlockName,
    713                                 &ulBlockSize)
    714                 && ulBlockSize > 0)
    715             // delete block:
    716             PrfWriteProfileData(hini,
    717                                 pszHandles,
    718                                 szBlockName,
    719                                 NULL, 0);       // delete
    720             // WriteProfileData(pszHandles, szBlockName, hini, NULL, 0);
    721     }
    722 
    723     return TRUE;
    724 }
    725 
    726 /*
    727  *@@ DeleteNode:
    728  *      deletes a NODE in the specified buffer.
    729  *
    730  *@@added V0.9.5 (2000-08-20) [umoeller]
    731  */
    732 
    733 ULONG DeleteNode(PBYTE pBuffer, PNODE pNode, ULONG ulSize)
    734 {
    735     ULONG ulDelSize = sizeof (NODE) + pNode->usNameSize;
    736     USHORT usID = pNode->usHandle; // pNode->usID;
    737     ULONG ulMoveSize;
    738 
    739     if (memcmp(pNode->chName, "NODE", 4))
    740         return ulSize;
    741 
    742     ulMoveSize = (pBuffer + ulSize) - ((PBYTE)pNode + ulDelSize);
    743     ulSize -= ulDelSize;
    744 
    745     memmove(pNode, (PBYTE)pNode + ulDelSize, ulMoveSize);
    746 
    747     while (     (PBYTE)pNode < pBuffer + ulSize
    748              && !memcmp(pNode->chName, "NODE", 4)
    749              && pNode->usParentHandle == usID)
    750         ulSize = DeleteNode(pBuffer, pNode, ulSize);
    751 
    752     return ulSize;
    753  }
    754 
    755 /*
    756  *@@ DeleteDrive:
    757  *      delete all information about a drive.
    758  *      in the specified buffer.
    759  *
    760  *@@added V0.9.5 (2000-08-20) [umoeller]
    761  */
    762 
    763 ULONG DeleteDrive(PBYTE pBuffer, PDRIV pDriv, ULONG ulSize)
    764 {
    765     ULONG ulDelSize;
    766     ULONG ulMoveSize;
    767 
    768     if (memcmp(pDriv->chName, "DRIV", 4))
    769         return ulSize;
    770 
    771     ulDelSize = sizeof (DRIV) + strlen(pDriv->szName);
    772     ulMoveSize = (pBuffer + ulSize) - ((PBYTE)pDriv + ulDelSize);
    773     ulSize -= ulDelSize;
    774 
    775     memmove(pDriv, (PBYTE)pDriv + ulDelSize, ulMoveSize);
    776     return ulSize;
    777 }
    778 
    779 
    780 
     926
     927
Note: See TracChangeset for help on using the changeset viewer.