home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / easrc.zip / EA.c < prev    next >
Text File  |  1994-09-28  |  22KB  |  615 lines

  1. /***************************************************************************
  2.  *
  3.  * PROGRAM NAME: EA.C
  4.  * -------------
  5.  *
  6.  * REVISION LEVEL: 1.2
  7.  * ---------------
  8.  *
  9.  * WHAT THIS PROGRAM DOES:
  10.  * -----------------------
  11.  *  Routines for handling EAs.
  12.  *
  13.  * ROUTINES:
  14.  * ---------
  15.  *  CreateGEAList
  16.  *  CreateFEAList
  17.  *  CreateEAOPRd
  18.  *  CreateEAOPWr
  19.  *  EAWriteASCII
  20.  *  EAReadASCII
  21.  *  EAWriteMV
  22.  *  EAReadMV
  23.  *
  24.  * COMPILE REQUIREMENTS:
  25.  * ---------------------
  26.  *  IBM C++ Set/2 Compiler Version 2.0
  27.  *  IBM OS/2 2.1 Programmers Toolkit
  28.  *
  29.  * REQUIRED FILES:
  30.  * ---------------
  31.  *  CUTIL.H
  32.  *
  33.  * REQUIRED LIBRARIES:
  34.  * -------------------
  35.  *  OS2386.LIB    -   OS/2 32-Bit import library
  36.  *
  37.  * CHANGE LOG:
  38.  * -----------
  39.  * 
  40.  *  Ver.    Date      Comment
  41.  *  ----    --------  -------
  42.  *  1.20    02-19-94  First release
  43.  *
  44.  *  Copyright (C) 1994 Noller & Breining Software
  45.  *
  46.  ******************************************************************************/
  47. #define INCL_DOSMEMMGR
  48. #define INCL_DOSFILEMGR
  49. #include <os2.h>
  50.  
  51. #include <string.h>
  52. #include <stdlib.h>
  53. #include <cutil.h>
  54.  
  55. #pragma pack (1)
  56. typedef struct _STRUC_EAT_SV        /* structure for EAT_ASCII */
  57.     {
  58.     USHORT usEAType;
  59.     USHORT uscValue;
  60.     CHAR   cValue[1];
  61.     } STRUC_EAT_SV;
  62. typedef STRUC_EAT_SV *PSTRUC_EAT_SV;
  63.  
  64. typedef struct _STRUC_MVST          /* EA-structure for strucEA */
  65.     {                               /*  in STRUC_EA_MV          */
  66.     USHORT uscValue;                /*  with EAT_MVST           */
  67.     BYTE   bValue[1];
  68.     } STRUC_MVST;
  69. typedef STRUC_MVST *PSTRUC_MVST;
  70.  
  71. typedef struct _STRUC_MVMT          /* EA-structure für strucEA */
  72.     {                               /*  in STRUC_EA_MV          */
  73.     USHORT usEAType;                /*  with EAT_MVMT           */
  74.     USHORT uscValue;
  75.     BYTE   bValue[1];
  76.     } STRUC_MVMT;
  77. typedef STRUC_MVMT *PSTRUC_MVMT;
  78.  
  79. typedef struct _STRUC_EAT_MV        /* strukture for EAT_MVMT/MVST */
  80.     {
  81.     USHORT          usEAType;
  82.     USHORT          usCodepage;
  83.     USHORT          uscEA;
  84.     STRUC_MVMT      strucEA[1];
  85.     } STRUC_EAT_MV;
  86. typedef STRUC_EAT_MV *PSTRUC_EAT_MV;
  87.  
  88. #pragma pack ()
  89.  
  90. /*****************************************************************************
  91.  * --- Internal function only ---
  92.  * Create a Get-EA-Liste (GEAList)
  93.  * The GEAList contains only 1 GEA-Eintrag.
  94.  * Entry:  pszName: Name of EA
  95.  * return: Pointer to GEAList
  96.  *****************************************************************************/
  97. PGEA2LIST CreateGEAList (PCHAR pszName)
  98.     {
  99.     PGEA2LIST pGEAl;
  100.  
  101.     DosAllocMem ((PPVOID)&pGEAl, sizeof (GEA2LIST) + strlen (pszName),
  102.         PAG_COMMIT | PAG_READ | PAG_WRITE);
  103.     pGEAl->cbList = sizeof (GEA2LIST) + strlen (pszName);
  104.     pGEAl->list->oNextEntryOffset = 0;          /* last entry */
  105.     pGEAl->list->cbName = (CHAR) strlen (pszName);
  106.     strcpy (pGEAl->list->szName, pszName);
  107.  
  108.     return pGEAl;
  109.     }
  110.  
  111. /*****************************************************************************
  112.  * --- Internal function only ---
  113.  * Create a Full-EA-Liste (FEAList)
  114.  * The FEAList contains only 1 FEA-Eintrag.
  115.  * Entry:  pszName : Name of EA
  116.  *         pValue  : Value of EA
  117.  *         uscValue: Length of EA value
  118.  * return: Pointer to FEAList
  119.  *****************************************************************************/
  120. PFEA2LIST CreateFEAList (PCHAR pszName, PBYTE pValue, USHORT uscValue)
  121.     {
  122.     PFEA2LIST pFEAl;
  123.  
  124.     DosAllocMem ((PPVOID)&pFEAl, sizeof (FEA2LIST) + strlen (pszName) + uscValue,
  125.         PAG_COMMIT | PAG_READ | PAG_WRITE);
  126.     pFEAl->cbList = sizeof (FEA2LIST) + strlen (pszName) + uscValue;
  127.     pFEAl->list->oNextEntryOffset = 0;          /* last entry */
  128.     pFEAl->list->fEA = 0;                       /* no flags */
  129.     pFEAl->list->cbName = (CHAR) strlen (pszName);
  130.     pFEAl->list->cbValue = uscValue;
  131.     strcpy (pFEAl->list->szName, pszName);
  132.     memcpy ((PBYTE)pFEAl->list->szName+strlen(pszName)+1, pValue, uscValue);
  133.  
  134.     return pFEAl;
  135.     }
  136.  
  137. /*****************************************************************************
  138.  * --- Internal function only ---
  139.  * Create an EAOP-Struktur with FEA-buffer at the end. This buffer may be used
  140.  * for DosFind*, DosGetFileInfo or DosGetPathInfo-calls.
  141.  * Entry:  ulcBuffer: Size of buffer (EAOP2 + FEAList)
  142.  *         pGEAl:     Pointer to GEAList
  143.  * return: Pointer to EAOP-structure
  144.  *****************************************************************************/
  145. PEAOP2 CreateEAOPRd (ULONG ulcBuffer, PGEA2LIST pGEAl)
  146.     {
  147.     PEAOP2 pEAOP;
  148.  
  149.     DosAllocMem ((PPVOID)&pEAOP, ulcBuffer, PAG_COMMIT | PAG_READ | PAG_WRITE);
  150.     pEAOP->fpGEA2List = pGEAl;
  151.     pEAOP->fpFEA2List = (FEA2LIST *)(pEAOP + 1);
  152.     pEAOP->fpFEA2List->cbList = ulcBuffer - sizeof (EAOP2);
  153.  
  154.     return pEAOP;
  155.     }
  156.  
  157. /*****************************************************************************
  158.  * --- Internal function only ---
  159.  * Create an EAOP-Struktur with FEA-buffer at the end. This buffer may be used
  160.  * for DosSetFileInfo or DosSetPathInfo-calls.
  161.  * Entry:  pFEAl:     Pointer to FEAList
  162.  * return: Pointer to EAOP-structure
  163.  *****************************************************************************/
  164. PEAOP2 CreateEAOPWr (PFEA2LIST pFEAl)
  165.     {
  166.     PEAOP2 pEAOP;
  167.  
  168.     DosAllocMem ((PPVOID)&pEAOP, sizeof (PEAOP2), PAG_COMMIT | PAG_READ | PAG_WRITE);
  169.     pEAOP->fpGEA2List = NULL;
  170.     pEAOP->fpFEA2List = pFEAl;
  171.  
  172.     return pEAOP;
  173.     }
  174.  
  175. /*****************************************************************************
  176.  * Write EAT_ASCII-EAs (value of EA is ASCII-string).
  177.  * Entry:  pszPathName: Filename
  178.  *         pszEAName:   Name of EA
  179.  *         pszString:   Value of EA (ASCIIZ-String)
  180.  * return: TRUE:  EA was written
  181.  *         FALSE: Error occured
  182.  *****************************************************************************/
  183. BOOL EAWriteASCII (PCHAR pszPathName, PCHAR pszEAName, PCHAR pszString)
  184.     {
  185.     BOOL          bRC;
  186.     PSTRUC_EAT_SV peaASCII;
  187.     PFEA2LIST     pFEAl;
  188.     PEAOP2        pEAOP;
  189.  
  190.     /* Fill EA structure */
  191.     DosAllocMem ((PPVOID)&peaASCII, sizeof (STRUC_EAT_SV) + strlen (pszString) - 1,
  192.         PAG_COMMIT | PAG_READ | PAG_WRITE);
  193.     peaASCII->usEAType = EAT_ASCII;
  194.     peaASCII->uscValue = (USHORT) strlen (pszString);
  195.     memcpy (peaASCII->cValue, pszString, strlen (pszString));
  196.  
  197.     /* Create FEA-list */
  198.     pFEAl = CreateFEAList (pszEAName, (PBYTE) peaASCII,
  199.         sizeof (STRUC_EAT_SV) + (USHORT) strlen (pszString) - 1);
  200.  
  201.     /* Create EAOP-strukture */
  202.     pEAOP = CreateEAOPWr (pFEAl);
  203.  
  204.     /* Write EA */
  205.     bRC = (DosSetPathInfo (pszPathName, FIL_QUERYEASIZE,
  206.         pEAOP, sizeof (EAOP2), DSPI_WRTTHRU)) ? FALSE : TRUE;
  207.  
  208.     /* Deallocate buffers */
  209.     DosFreeMem (pEAOP);
  210.     DosFreeMem (pFEAl);
  211.     DosFreeMem (peaASCII);
  212.  
  213.     return bRC;
  214.     }
  215.  
  216. /*****************************************************************************
  217.  * Read EAT_ASCII-EAs (value of EA is ASCII-string).
  218.  * Entry:  pszPathName: Filename
  219.  *         pszEAName:   Name of EA
  220.  *         puscValue:   Size of buffer 'pszString'
  221.  * Exit:   pszString:   Value of EA (ASCIIZ)
  222.  *         puscValue:   Length of value of EA (strlen (pszString))
  223.  * return: TRUE:  EA was read
  224.  *         FALSE: Error occured
  225.  *****************************************************************************/
  226. BOOL EAReadASCII (PCHAR pszPathName, PCHAR pszEAName, PCHAR pszString, PUSHORT puscValue)
  227.     {
  228.     BOOL        bRC;
  229.     LONG        lcBytes;
  230.     FILESTATUS4 ffb4;
  231.     PGEA2LIST   pGEAl;
  232.     PEAOP2      pEAOP;
  233.     union _pEA
  234.         {
  235.         PFEA2   pFEA;
  236.         PUSHORT pWord;
  237.         PBYTE   pByte;
  238.         } pEA;
  239.  
  240.     if (*puscValue > 0)             /* Prepare buffer for case of an error */
  241.         *pszString = '\0';
  242.     bRC = FALSE;                    /* Prepare return value for cas of an error */
  243.  
  244.     if (!DosQueryPathInfo (pszPathName, FIL_QUERYEASIZE, &ffb4, sizeof (FILESTATUS4)))
  245.         {
  246.         pGEAl = CreateGEAList (pszEAName);
  247.         pEAOP = CreateEAOPRd (sizeof (EAOP2) + ffb4.cbList, pGEAl);
  248.         if (!DosQueryPathInfo (pszPathName, FIL_QUERYEASFROMLIST,
  249.                 pEAOP, sizeof (EAOP2)))
  250.             {
  251.             pEA.pFEA = pEAOP->fpFEA2List->list;
  252.             if (pEA.pFEA->cbValue != 0)
  253.                 {
  254.                 pEA.pByte = (PBYTE)&(pEA.pFEA->szName) + pEA.pFEA->cbName + 1;
  255.                 if (*pEA.pWord++ == EAT_ASCII)
  256.                     {
  257.                     lcBytes = min (*pEA.pWord, (LONG) *puscValue-1);
  258.                     if (lcBytes > 0)
  259.                         {
  260.                         memcpy (pszString, pEA.pWord + 1, lcBytes);
  261.                         pszString[lcBytes] = '\0';
  262.                         }
  263.                     *puscValue = *pEA.pWord;
  264.                     bRC = TRUE;
  265.                     }
  266.                 }
  267.             else
  268.                 {
  269.                 /* EA not present */
  270.                 *puscValue = 0;
  271.                 bRC = TRUE;
  272.                 }
  273.             }
  274.         DosFreeMem (pEAOP);
  275.         DosFreeMem (pGEAl);
  276.         }
  277.  
  278.     /* In case of an error return 0 as length of string */
  279.     if (!bRC)
  280.         *puscValue = 0;
  281.  
  282.     return bRC;
  283.     }
  284.  
  285. /*****************************************************************************
  286.  * Write single-value-EAs (value of EA may be any type)
  287.  * Entry:  pszPathName: Filename
  288.  *         pszEAName:   Name if EA
  289.  *         pstrucValue: Input data structure (see CUTIL.H)
  290.  * return: TRUE:  EA was written
  291.  *         FALSE: Error occured
  292.  *****************************************************************************/
  293. BOOL EAWrite (PCHAR pszPathName, PCHAR pszEAName, PSTRUC_EAT_DATA pstrucValue)
  294.     {
  295.     BOOL          bRC;
  296.     PSTRUC_EAT_SV peaData;
  297.     PFEA2LIST     pFEAl;
  298.     PEAOP2        pEAOP;
  299.  
  300.     /* Fill EA structure */
  301.     DosAllocMem ((PPVOID)&peaData,
  302.         sizeof (STRUC_EAT_SV) + pstrucValue->uscValue - 1,
  303.         PAG_COMMIT | PAG_READ | PAG_WRITE);
  304.     peaData->usEAType = pstrucValue->usEAType;
  305.     peaData->uscValue = pstrucValue->uscValue;
  306.     memcpy (peaData->cValue, pstrucValue->pValue, pstrucValue->uscValue);
  307.  
  308.     /* Create FEA-list */
  309.     pFEAl = CreateFEAList (pszEAName, (PBYTE) peaData,
  310.         sizeof (STRUC_EAT_SV) + pstrucValue->uscValue - 1);
  311.  
  312.     /* Createt EAOP-structure */
  313.     pEAOP = CreateEAOPWr (pFEAl);
  314.  
  315.     /* Write EA */
  316.     bRC = (DosSetPathInfo (pszPathName, FIL_QUERYEASIZE,
  317.         pEAOP, sizeof (EAOP2), DSPI_WRTTHRU)) ? FALSE : TRUE;
  318.  
  319.     /* Deallocate buffers */
  320.     DosFreeMem (pEAOP);
  321.     DosFreeMem (pFEAl);
  322.     DosFreeMem (peaData);
  323.  
  324.     return bRC;
  325.     }
  326.  
  327. /*****************************************************************************
  328.  * Read single-value-EAs (value of EA may be any type)
  329.  * If pstrucValue->uscValue is larger on return as the value on entry,
  330.  * the buffer is too small to hold the complete EA. The buffer will be
  331.  * filled with the correct value up to the end. EAT_ASCII EAs will be
  332.  * terminated with '\0'.
  333.  * Entry:  pszPathName: Filename
  334.  *         pszEAName:   Name of EA
  335.  *         pstrucValue: Input data structure (see CUTIL.H)
  336.  * Exit:   pstrucValue: Result
  337.  * return: TRUE:  EA was read
  338.  *         FALSE: Error occured
  339.  *****************************************************************************/
  340. BOOL EARead (PCHAR pszPathName, PCHAR pszEAName, PSTRUC_EAT_DATA pstrucValue)
  341.     {
  342.     BOOL        bRC;
  343.     LONG        lcBytes;
  344.     FILESTATUS4 ffb4;
  345.     PGEA2LIST   pGEAl;
  346.     PEAOP2      pEAOP;
  347.     union _pEA
  348.         {
  349.         PFEA2   pFEA;
  350.         PUSHORT pWord;
  351.         PBYTE   pByte;
  352.         } pEA;
  353.  
  354.     bRC = FALSE;                    /* Prepare return value for case of an error */
  355.  
  356.     if (!DosQueryPathInfo (pszPathName, FIL_QUERYEASIZE, &ffb4, sizeof (FILESTATUS4)))
  357.         {
  358.         pGEAl = CreateGEAList (pszEAName);
  359.         pEAOP = CreateEAOPRd (sizeof (EAOP2) + ffb4.cbList, pGEAl);
  360.         if (!DosQueryPathInfo (pszPathName, FIL_QUERYEASFROMLIST,
  361.                 pEAOP, sizeof (EAOP2)))
  362.             {
  363.             pEA.pFEA = pEAOP->fpFEA2List->list;
  364.             if (pEA.pFEA->cbValue != 0)
  365.                 {
  366.                 pEA.pByte = (PBYTE)&(pEA.pFEA->szName) + pEA.pFEA->cbName + 1;
  367.                 pstrucValue->usEAType = *pEA.pWord++;
  368.                 lcBytes = min (*pEA.pWord, (LONG)pstrucValue->uscValue);
  369.                 if (lcBytes > 0)
  370.                     {
  371.                     memcpy (pstrucValue->pValue, pEA.pWord + 1, lcBytes);
  372.                     if (pstrucValue->usEAType == EAT_ASCII)
  373.                         {
  374.                         /* EAT_ASCII-EAs will always be terminated with '\0' */
  375.                         lcBytes = min (*pEA.pWord, (LONG)pstrucValue->uscValue - 1);
  376.                         pstrucValue->pValue[lcBytes] = '\0';
  377.                         }
  378.                     }
  379.                 pstrucValue->uscValue = *pEA.pWord;
  380.                 bRC = TRUE;
  381.                 }
  382.             else
  383.                 {
  384.                 /* EA not present */
  385.                 pstrucValue->uscValue = 0;
  386.                 bRC = TRUE;
  387.                 }
  388.             }
  389.         DosFreeMem (pEAOP);
  390.         DosFreeMem (pGEAl);
  391.         }
  392.  
  393.     /* In case of an error return 0 as length of string */
  394.     if (!bRC)
  395.         pstrucValue->uscValue = 0;
  396.  
  397.     return bRC;
  398.     }
  399.  
  400. /*****************************************************************************
  401.  * Write multi-value EAs (EAT_MVST and EAT_MVMT) (EA may contain more than
  402.  * 1 value. All values may be of same type (EAT_MVST) or different type
  403.  * (EAT_MVMT)).
  404.  * Data is entered in the structure arValue[]. The last entry must
  405.  * contain arValue[].pValue = NULL.
  406.  * If type is EAT_MVST, only the first value arValue[0].usEAType is relevant.
  407.  * Entry:  pszPathName: Filename
  408.  *         pszEAName:   Name of EA
  409.  *         usEAType:    EAT_MVST or EAT_MVMT
  410.  *         arValue:     Entry data structure
  411.  * return: TRUE:  EA was written
  412.  *         FALSE: Error occured
  413.  *****************************************************************************/
  414. BOOL EAWriteMV (PCHAR pszPathName, PCHAR pszEAName,
  415.                 USHORT usEAType, STRUC_EAT_DATA arValue[])
  416.     {
  417.     BOOL            bRC;
  418.     ULONG           ulcValue, ulcBytes, i;
  419.     PSTRUC_EAT_MV   peaMV;
  420.     union _pEA
  421.         {
  422.         PSTRUC_MVMT pMT;                /* Multitype EA  */
  423.         PSTRUC_MVST pST;                /* Singletype EA */
  424.         } pEA;
  425.     PFEA2LIST       pFEAl;
  426.     PEAOP2          pEAOP;
  427.  
  428.     /* Count EA values; Result is in ulcValue */
  429.     for (ulcValue=0; arValue[ulcValue].pValue != NULL; ulcValue++);
  430.     if (ulcValue == 0)
  431.         return TRUE;
  432.  
  433.     /* Allocate memory for attributes; STRUC_EAT_MV contains */
  434.     /* a MVMT-structure on default even at MVST attributes.  */
  435.     ulcBytes = sizeof (STRUC_EAT_MV);
  436.     switch (usEAType)
  437.         {
  438.         case EAT_MVST:
  439.             ulcBytes += (ulcValue-1)*sizeof (STRUC_MVST);
  440.             break;
  441.  
  442.         case EAT_MVMT:
  443.             ulcBytes += (ulcValue-1)*sizeof (STRUC_MVMT);
  444.             break;
  445.  
  446.         default:
  447.             return FALSE;
  448.         }
  449.     for (i=0; i<ulcValue; i++)
  450.         ulcBytes += arValue[i].uscValue - 1;
  451.     DosAllocMem ((PPVOID)&peaMV, ulcBytes, PAG_COMMIT | PAG_READ | PAG_WRITE);
  452.  
  453.     /* Fill EA structure */
  454.     peaMV->usEAType   = usEAType;
  455.     peaMV->usCodepage = 0;
  456.     peaMV->uscEA      = ulcValue;
  457.     pEA.pMT = peaMV->strucEA;
  458.     if (usEAType == EAT_MVST)                       /* For EA_MVST: Type of first */
  459.         {                                           /*  EA is type of all EAs     */
  460.         pEA.pMT->usEAType = arValue[0].usEAType;
  461.         pEA.pMT = (PSTRUC_MVMT)&(peaMV->strucEA[0].uscValue);
  462.         }
  463.     for (i=0; i<ulcValue; i++)
  464.         {
  465.         if (usEAType == EAT_MVMT)
  466.             {
  467.             pEA.pMT->usEAType = arValue[i].usEAType;
  468.             pEA.pST = (PSTRUC_MVST)&(pEA.pMT->uscValue);
  469.             }
  470.         /* for EA_MVMT: usEAType is written. From now on */
  471.         /* pEA is used as PSTRUC_MVST-pointer.           */
  472.         pEA.pST->uscValue  = arValue[i].uscValue;
  473.         memcpy (pEA.pST->bValue, arValue[i].pValue, pEA.pST->uscValue);
  474.         pEA.pST = (PSTRUC_MVST)(pEA.pST->bValue + pEA.pST->uscValue);
  475.         }
  476.  
  477.     /* Create FEA-list */
  478.     pFEAl = CreateFEAList (pszEAName, (PBYTE) peaMV, ulcBytes);
  479.  
  480.     /* Create EAOP-structure */
  481.     pEAOP = CreateEAOPWr (pFEAl);
  482.  
  483.     /* Write EA */
  484.     bRC = (DosSetPathInfo (pszPathName, FIL_QUERYEASIZE,
  485.         pEAOP, sizeof (EAOP2), DSPI_WRTTHRU)) ? FALSE : TRUE;
  486.  
  487.     /* Deallocate buffers */
  488.     DosFreeMem (pEAOP);
  489.     DosFreeMem (pFEAl);
  490.     DosFreeMem (peaMV);
  491.  
  492.     return bRC;
  493.     }
  494.  
  495. /*****************************************************************************
  496.  * Read Multi-Value EAs (EAT_MVST und EAT_MVMT). (EA may contain more than
  497.  * 1 value. All values may be of same type (EAT_MVST) or different type
  498.  * (EAT_MVMT)).
  499.  * Data is entered in the structure arValue[]. The last entry must
  500.  * contain arValue[].pValue = NULL.
  501.  * If type is EAT_MVST, the EA-type is returned in arValue[0].usEAType.
  502.  * If the arValue-structure is too long, all remaining entries of
  503.  * arValue[].uscValue are set to 0 gesetzt.
  504.  * EAT_ASCII-EAs will always be terminated with '\0'. If the buffer is too
  505.  * small (arValue[].uscValue), the string will be cut; but terminated with
  506.  * '\0' nevertheless.
  507.  * Entry:  pszPathName: Filename
  508.  *         pszEAName:   Name of EA
  509.  *         usEAType:    EAT_MVST or EAT_MVMT
  510.  *         arValue:     Entry data structure
  511.  * Exit:   arValue:     Result
  512.  * return: TRUE:  EA was read
  513.  *         FALSE: Error occured
  514.  *****************************************************************************/
  515. BOOL EAReadMV (PCHAR pszPathName, PCHAR pszEAName,
  516.                USHORT usEAType, STRUC_EAT_DATA arValue[])
  517.     {
  518.     USHORT      usEAType2;
  519.     BOOL        bRC;
  520.     ULONG       ulcValue, ulcMaxEA, ulcBytes, i;
  521.     FILESTATUS4 ffb4;
  522.     PGEA2LIST   pGEAl;
  523.     PEAOP2      pEAOP;
  524.     union _pEA
  525.         {
  526.         PFEA2           pFEA;
  527.         PSTRUC_EAT_MV   peaMV;
  528.         PSTRUC_MVST     pST;
  529.         PSTRUC_MVMT     pMT;
  530.         PUSHORT         pWord;
  531.         PBYTE           pByte;
  532.         } pEA;
  533.  
  534.     /* Count ASCII-strings; Result is in ulcValue */
  535.     for (ulcValue=0; arValue[ulcValue].pValue != NULL; ulcValue++);
  536.     if (ulcValue == 0)
  537.         return TRUE;
  538.  
  539.     /* Read der EAs */
  540.     bRC = FALSE;
  541.     if (!DosQueryPathInfo (pszPathName, FIL_QUERYEASIZE, &ffb4, sizeof (FILESTATUS4)))
  542.         {
  543.         pGEAl = CreateGEAList (pszEAName);
  544.         pEAOP = CreateEAOPRd (sizeof (EAOP2) + ffb4.cbList, pGEAl);
  545.         if (!DosQueryPathInfo (pszPathName, FIL_QUERYEASFROMLIST,
  546.                 pEAOP, sizeof (EAOP2)))
  547.             {
  548.             pEA.pFEA = pEAOP->fpFEA2List->list;
  549.             /* Attribute found? */
  550.             if (pEA.pFEA->cbValue != 0)
  551.                 {
  552.                 pEA.pByte = (PBYTE)&(pEA.pFEA->szName) + pEA.pFEA->cbName + 1;
  553.                 /* Attribute types correct? */
  554.                 if (pEA.peaMV->usEAType == usEAType)
  555.                     {
  556.                     ulcMaxEA = pEA.peaMV->uscEA;
  557.                     pEA.pMT = pEA.peaMV->strucEA;
  558.                     if (usEAType == EAT_MVST)
  559.                         {
  560.                         usEAType2 = arValue[0].usEAType = pEA.pMT->usEAType;
  561.                         pEA.pMT = (PSTRUC_MVMT)&(pEA.pMT->uscValue);
  562.                         }
  563.                     for (i=0; i<ulcValue; i++)
  564.                         {
  565.                         if (i<ulcMaxEA)
  566.                             {
  567.                             if (usEAType == EAT_MVMT)
  568.                                 {
  569.                                 arValue[i].usEAType = pEA.pMT->usEAType;
  570.                                 pEA.pST = (PSTRUC_MVST)&(pEA.pMT->uscValue);
  571.                                 }
  572.                             else
  573.                                 arValue[i].usEAType = usEAType2;
  574.                             ulcBytes = min (pEA.pST->uscValue, arValue[i].uscValue);
  575.                             /* EAT_ASCII-EAs will always be terminated with '\0' */
  576.                             if (arValue[i].usEAType == EAT_ASCII)
  577.                                 {
  578.                                 ulcBytes = min (ulcBytes, arValue[i].uscValue-1);
  579.                                 arValue[i].pValue[ulcBytes] = '\0';
  580.                                 }
  581.                             arValue[i].uscValue = ulcBytes;
  582.                             memcpy (arValue[i].pValue, pEA.pST->bValue, ulcBytes);
  583.                             }
  584.                         else
  585.                             arValue[i].uscValue = 0;
  586.                         pEA.pST = (PSTRUC_MVST)(pEA.pST->bValue + pEA.pST->uscValue);
  587.                         }
  588.                     arValue[ulcValue].uscValue = 0;
  589.                     bRC = TRUE;
  590.                     }
  591.                 }
  592.             else
  593.                 {
  594.                 /* EA not present */
  595.                 bRC = TRUE;
  596.                 for (i=0; i<ulcValue; i++)
  597.                     {
  598.                     arValue[i].uscValue = 0;
  599.                     arValue[i].usEAType = 0;
  600.                     }
  601.                 }
  602.             }
  603.  
  604.         DosFreeMem (pEAOP);
  605.         DosFreeMem (pGEAl);
  606.         }
  607.  
  608.     /* In case of an error fill all lengths with 0 */
  609.     if (!bRC)
  610.         for (i=0; i<ulcValue; i++)
  611.             arValue[i].uscValue = 0;
  612.  
  613.     return bRC;
  614.     }
  615.