source: trunk/eastring.c@ 82

Last change on this file since 82 was 82, checked in by Gregg Young, 10 years ago

This commit is to allow me acces to my bleeding edge code at warpstock. Don't build this commit unless you are very familiar with lswitcher. It will work but is not ready for prime time.

File size: 7.5 KB
Line 
1/* Taken from an excellent article by Roger Orr dating back to 1993 */
2/* EAString.c - functions to read and write single-valued ASCII EA */
3
4#define INCL_DOS
5#define INCL_DOSERRORS
6#include <os2.h>
7
8#include <stdlib.h>
9#include <string.h>
10
11#include "EAString.h"
12#define __PMPRINTF__
13#include "PMPRINTF.H"
14
15#pragma pack(1)
16
17/* Header for a single-valued ASCII EA data item */
18typedef struct _EA_ASCII_header
19{
20 USHORT usAttr; /* value: EAT_ASCII */
21 USHORT usLen; /* length of data */
22 /* ASCII data fits in here ... */
23}
24EA_ASCII_HEADER, *PEA_ASCII_HEADER;
25
26#pragma pack()
27
28/*****************************************************************************/
29/* EAQueryData: query EA data using supplied 'get' EA list into supplied */
30/* 'full' EA buffer - which need NOT be initialised first */
31/*****************************************************************************/
32
33static APIRET EAQueryData(PSZ pszPathName, PGEA2LIST pGEA2List,
34 ULONG cbBuf, PFEA2LIST pFEA2List)
35{
36 EAOP2 eaop2 = { NULL, NULL, 0 }; /* EA 'root' data structure */
37
38 eaop2.fpGEA2List = pGEA2List;
39 eaop2.fpFEA2List = pFEA2List;
40 pFEA2List->cbList = cbBuf; /* Inform OS/2 how big our FEA2List is */
41
42 return DosQueryPathInfo(pszPathName, FIL_QUERYEASFROMLIST,
43 (PBYTE) & eaop2, sizeof(eaop2));
44}
45
46/*****************************************************************************/
47/* EASetData: set EA data using supplied 'full' EA buffer */
48/*****************************************************************************/
49
50static APIRET EASetData(PSZ pszPathName, PFEA2LIST pFEA2List)
51{
52 EAOP2 eaop2 = { NULL, NULL, 0 }; /* EA 'root' data structure */
53
54 eaop2.fpFEA2List = pFEA2List;
55
56 return DosSetPathInfo(pszPathName, FIL_QUERYEASIZE,
57 (PBYTE) & eaop2, sizeof(eaop2), DSPI_WRTTHRU);
58}
59
60/*****************************************************************************/
61/* EAQueryString: query EA ASCII data into a supplied buffer as a NUL */
62/* terminated string. */
63/* */
64/* Note: the NUL terminator is NOT required in the data itself - it will be */
65/* added if required. (Some ASCII EAs include a NUL, some don't !) */
66/*****************************************************************************/
67
68APIRET EAQueryString(PSZ pszPathName, PSZ pszEAName, USHORT cbBuf, PSZ pszBuf)
69{
70 APIRET rc = ERROR_NOT_ENOUGH_MEMORY; /* return code */
71 PFEA2LIST pFEA2List = NULL; /* pointer to returned EA data */
72 PGEA2LIST pGEA2List = NULL; /* pointer to list of EAs requested */
73 PEA_ASCII_HEADER pEAData = NULL; /* pointer to data item itself */
74 size_t GEAlen = 0; /* length of GEA list */
75 size_t FEAlen = 0; /* length of FEA list */
76 PSZ pszAscii = NULL; /* pointer to ASCII data itself */
77
78 /*
79 * Build an FEA2 list buffer with enough space for cbBuf data items
80 * The length is obtained by:
81 * size for FEA2LIST header and one FEA2 item
82 * + room for the EA name (the NUL is included in size of FEA2! )
83 * + EAT_ASCII header
84 * + up to cbBuf bytes of EAT_ASCII data (may or may not end with a NUL)
85 */
86 FEAlen = sizeof(FEA2LIST) + strlen(pszEAName) +
87 sizeof(EA_ASCII_HEADER) + cbBuf;
88
89 /* FEAlen MUST be rounded up to a doubleword boundary since
90 OS/2 may use buffer space up to this boundary */
91 FEAlen = ((FEAlen + 3) / 4) * 4;
92
93 pFEA2List = (PFEA2LIST) malloc(FEAlen);
94 if (pFEA2List != NULL) {
95 /*
96 * Build a GEA2 list for the EA we require
97 * The length is obtained by:
98 * size for GEA2LIST header and one GEA2 item
99 * + room for the EA name (the NUL is included in the size of GEA2 !)
100 */
101 GEAlen = sizeof(GEA2LIST) + strlen(pszEAName);
102 pGEA2List = (PGEA2LIST) malloc(GEAlen);
103 if (pGEA2List != NULL) {
104 pGEA2List->cbList = GEAlen;
105 pGEA2List->list[0].oNextEntryOffset = 0;
106 pGEA2List->list[0].cbName = (BYTE) strlen(pszEAName);
107 strcpy(pGEA2List->list[0].szName, pszEAName);
108
109 rc = EAQueryData(pszPathName, pGEA2List, FEAlen, pFEA2List);
110 if (rc == 0) {
111 if (pFEA2List->list[0].cbValue == 0) {
112 /* THere is no data for this EA, return an error */
113 rc = EA_ERROR_NOT_FOUND;
114 }
115 else {
116 /* Verify the data type is what we're expecting */
117 pEAData =
118 (PEA_ASCII_HEADER) ((PSZ) pFEA2List->list[0].szName +
119 pFEA2List->list[0].cbName + 1);
120 if (pEAData->usAttr == EAT_ASCII) {
121 /* skip ASCII header to point to ASCII data */
122 pszAscii = (PSZ) (pEAData + 1);
123
124 /* If a trailing NUL is present, ignore it */
125 if (pszAscii[pEAData->usLen - 1] == '\0')
126 pEAData->usLen--;
127
128 if (pEAData->usLen < cbBuf) {
129 /* Give the user the data as a NUL terminated string */
130 memcpy(pszBuf, pEAData + 1, pEAData->usLen);
131 pszBuf[pEAData->usLen] = '\0';
132 }
133 else {
134 /* data read is too long for user's buffer */
135 rc = ERROR_BUFFER_OVERFLOW;
136 }
137 }
138 else {
139 /* This function only processes EAT_ASCII ! */
140 rc = EA_ERROR_WRONG_TYPE;
141 }
142 }
143 }
144
145 free(pGEA2List);
146 }
147
148 free(pFEA2List);
149 }
150
151 return rc;
152}
153
154/*****************************************************************************/
155/* EASetString: set EA ASCII data from a NUL terminated string */
156/* */
157/* Note1: the NUL terminator is NOT stored since the EAT_ASCII type already */
158/* includes a length field. */
159/* Note2: setting a string consisting only of the NUL character will delete */
160/* the EA. */
161/*****************************************************************************/
162
163APIRET EASetString(PSZ pszPathName, PSZ pszEAName, PSZ pszBuf)
164{
165 APIRET rc = ERROR_NOT_ENOUGH_MEMORY; /* return code */
166 PFEA2LIST pFEA2List = NULL;
167 PFEA2 pFEA2 = NULL;
168 PEA_ASCII_HEADER pEAData = NULL;
169 size_t len = 0;
170 size_t cbBuf = 0;
171
172 /* Build an FEA2LIST buffer of the right size (see EAQueryString above) */
173 len = sizeof(FEA2LIST) + strlen(pszEAName);
174 cbBuf = strlen(pszBuf);
175 if (cbBuf != 0)
176 len += sizeof(EA_ASCII_HEADER) + cbBuf;
177
178 pFEA2List = (PFEA2LIST) malloc(len);
179 if (pFEA2List != NULL) {
180 pFEA2List->cbList = len;
181
182 pFEA2 = pFEA2List->list;
183 pFEA2->oNextEntryOffset = 0; /* no more fields */
184 pFEA2->fEA = 0; /* no flags */
185 pFEA2->cbName = (BYTE) strlen(pszEAName);
186 strcpy(pFEA2->szName, pszEAName);
187
188 if (cbBuf == 0)
189 pFEA2->cbValue = 0; /* this will delete the EA! */
190 else {
191 pFEA2->cbValue = (USHORT) (sizeof(EA_ASCII_HEADER) + cbBuf);
192
193 /* Fill in the EA data area using an ASCII EA template */
194 pEAData = (PEA_ASCII_HEADER) ((PSZ) pFEA2List->list[0].szName
195 + pFEA2List->list[0].cbName + 1);
196 pEAData->usAttr = EAT_ASCII;
197 pEAData->usLen = (USHORT) cbBuf;
198 memcpy(pEAData + 1, pszBuf, cbBuf);
199 }
200
201 rc = EASetData(pszPathName, pFEA2List);
202
203 free(pFEA2List);
204 }
205
206 return rc;
207}
Note: See TracBrowser for help on using the repository browser.