Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/coml2/stg_prop.c
4388 views
1
/*
2
* Compound Storage (32 bit version)
3
* Storage implementation
4
*
5
* This file contains the compound file implementation
6
* of the storage interface.
7
*
8
* Copyright 1999 Francis Beaudet
9
* Copyright 1999 Sylvain St-Germain
10
* Copyright 1999 Thuy Nguyen
11
* Copyright 2005 Mike McCormack
12
* Copyright 2005 Juan Lang
13
* Copyright 2006 Mike McCormack
14
*
15
* This library is free software; you can redistribute it and/or
16
* modify it under the terms of the GNU Lesser General Public
17
* License as published by the Free Software Foundation; either
18
* version 2.1 of the License, or (at your option) any later version.
19
*
20
* This library is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
* Lesser General Public License for more details.
24
*
25
* You should have received a copy of the GNU Lesser General Public
26
* License along with this library; if not, write to the Free Software
27
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28
*
29
* TODO:
30
* - I don't honor the maximum property set size.
31
* - Certain bogus files could result in reading past the end of a buffer.
32
* - Mac-generated files won't be read correctly, even if they're little
33
* endian, because I disregard whether the generator was a Mac. This means
34
* strings will probably be munged (as I don't understand Mac scripts.)
35
* - Not all PROPVARIANT types are supported.
36
* - User defined properties are not supported, see comment in
37
* PropertyStorage_ReadFromStream
38
*/
39
40
#include <assert.h>
41
#include <stdarg.h>
42
#include <stdio.h>
43
#include <stdlib.h>
44
#include <string.h>
45
46
#define COBJMACROS
47
#include "windef.h"
48
#include "winbase.h"
49
#include "winnls.h"
50
#include "winuser.h"
51
#include "wine/asm.h"
52
#include "wine/debug.h"
53
#include "wine/heap.h"
54
#include "oleauto.h"
55
56
WINE_DEFAULT_DEBUG_CHANNEL(storage);
57
58
/***********************************************************************
59
* Format ID <-> name conversion
60
*/
61
static const WCHAR szSummaryInfo[] = L"\5SummaryInformation";
62
static const WCHAR szDocSummaryInfo[] = L"\5DocumentSummaryInformation";
63
64
#define BITS_PER_BYTE 8
65
#define CHARMASK 0x1f
66
#define BITS_IN_CHARMASK 5
67
#define NUM_ALPHA_CHARS 26
68
69
/***********************************************************************
70
* FmtIdToPropStgName [coml2.@]
71
*/
72
HRESULT WINAPI FmtIdToPropStgName(const FMTID *rfmtid, LPOLESTR str)
73
{
74
static const char fmtMap[] = "abcdefghijklmnopqrstuvwxyz012345";
75
76
TRACE("%s, %p\n", debugstr_guid(rfmtid), str);
77
78
if (!rfmtid) return E_INVALIDARG;
79
if (!str) return E_INVALIDARG;
80
81
if (IsEqualGUID(&FMTID_SummaryInformation, rfmtid))
82
lstrcpyW(str, szSummaryInfo);
83
else if (IsEqualGUID(&FMTID_DocSummaryInformation, rfmtid))
84
lstrcpyW(str, szDocSummaryInfo);
85
else if (IsEqualGUID(&FMTID_UserDefinedProperties, rfmtid))
86
lstrcpyW(str, szDocSummaryInfo);
87
else
88
{
89
const BYTE *fmtptr;
90
WCHAR *pstr = str;
91
ULONG bitsRemaining = BITS_PER_BYTE;
92
93
*pstr++ = 5;
94
for (fmtptr = (const BYTE *)rfmtid; fmtptr < (const BYTE *)rfmtid + sizeof(FMTID); )
95
{
96
ULONG i = *fmtptr >> (BITS_PER_BYTE - bitsRemaining);
97
98
if (bitsRemaining >= BITS_IN_CHARMASK)
99
{
100
*pstr = (WCHAR)(fmtMap[i & CHARMASK]);
101
if (bitsRemaining == BITS_PER_BYTE && *pstr >= 'a' &&
102
*pstr <= 'z')
103
*pstr += 'A' - 'a';
104
pstr++;
105
bitsRemaining -= BITS_IN_CHARMASK;
106
if (bitsRemaining == 0)
107
{
108
fmtptr++;
109
bitsRemaining = BITS_PER_BYTE;
110
}
111
}
112
else
113
{
114
if (++fmtptr < (const BYTE *)rfmtid + sizeof(FMTID))
115
i |= *fmtptr << bitsRemaining;
116
*pstr++ = (WCHAR)(fmtMap[i & CHARMASK]);
117
bitsRemaining += BITS_PER_BYTE - BITS_IN_CHARMASK;
118
}
119
}
120
*pstr = 0;
121
}
122
TRACE("returning %s\n", debugstr_w(str));
123
return S_OK;
124
}
125
126
/***********************************************************************
127
* PropStgNameToFmtId [coml2.@]
128
*/
129
HRESULT WINAPI PropStgNameToFmtId(const LPOLESTR str, FMTID *rfmtid)
130
{
131
HRESULT hr = STG_E_INVALIDNAME;
132
133
TRACE("%s, %p\n", debugstr_w(str), rfmtid);
134
135
if (!rfmtid) return E_INVALIDARG;
136
if (!str) return STG_E_INVALIDNAME;
137
138
if (!lstrcmpiW(str, szDocSummaryInfo))
139
{
140
*rfmtid = FMTID_DocSummaryInformation;
141
hr = S_OK;
142
}
143
else if (!lstrcmpiW(str, szSummaryInfo))
144
{
145
*rfmtid = FMTID_SummaryInformation;
146
hr = S_OK;
147
}
148
else
149
{
150
ULONG bits;
151
BYTE *fmtptr = (BYTE *)rfmtid - 1;
152
const WCHAR *pstr = str;
153
154
memset(rfmtid, 0, sizeof(*rfmtid));
155
for (bits = 0; bits < sizeof(FMTID) * BITS_PER_BYTE;
156
bits += BITS_IN_CHARMASK)
157
{
158
ULONG bitsUsed = bits % BITS_PER_BYTE, bitsStored;
159
WCHAR wc;
160
161
if (bitsUsed == 0)
162
fmtptr++;
163
wc = *++pstr - 'A';
164
if (wc > NUM_ALPHA_CHARS)
165
{
166
wc += 'A' - 'a';
167
if (wc > NUM_ALPHA_CHARS)
168
{
169
wc += 'a' - '0' + NUM_ALPHA_CHARS;
170
if (wc > CHARMASK)
171
{
172
WARN("invalid character (%d)\n", *pstr);
173
goto end;
174
}
175
}
176
}
177
*fmtptr |= wc << bitsUsed;
178
bitsStored = min(BITS_PER_BYTE - bitsUsed, BITS_IN_CHARMASK);
179
if (bitsStored < BITS_IN_CHARMASK)
180
{
181
wc >>= BITS_PER_BYTE - bitsUsed;
182
if (bits + bitsStored == sizeof(FMTID) * BITS_PER_BYTE)
183
{
184
if (wc != 0)
185
{
186
WARN("extra bits\n");
187
goto end;
188
}
189
break;
190
}
191
fmtptr++;
192
*fmtptr |= (BYTE)wc;
193
}
194
}
195
hr = S_OK;
196
}
197
end:
198
return hr;
199
}
200
201