Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e68982fc
Commit
e68982fc
authored
Apr 15, 2005
by
Juan Lang
Committed by
Alexandre Julliard
Apr 15, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement FmtIdToPropStgName & PropStgNameToFmtId, with tests.
parent
a3b4e205
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
254 additions
and
75 deletions
+254
-75
ole32.spec
dlls/ole32/ole32.spec
+2
-0
stg_prop.c
dlls/ole32/stg_prop.c
+182
-75
stg_prop.c
dlls/ole32/tests/stg_prop.c
+70
-0
No files found.
dlls/ole32/ole32.spec
View file @
e68982fc
...
...
@@ -96,6 +96,7 @@
@ stdcall -private DllUnregisterServer()
@ stdcall DoDragDrop(ptr ptr long ptr)
@ stub EnableHookObject
@ stdcall FmtIdToPropStgName(ptr wstr)
@ stdcall FreePropVariantArray(long ptr)
@ stdcall GetClassFile(wstr ptr)
@ stdcall GetConvertStg(ptr)
...
...
@@ -212,6 +213,7 @@
@ stdcall OleUninitialize()
@ stub OpenOrCreateStream
@ stdcall ProgIDFromCLSID(ptr ptr)
@ stdcall PropStgNameToFmtId(wstr ptr)
@ stdcall PropSysAllocString(wstr)
@ stdcall PropSysFreeString(wstr)
@ stdcall PropVariantClear(ptr)
...
...
dlls/ole32/stg_prop.c
View file @
e68982fc
...
...
@@ -1796,70 +1796,6 @@ static HRESULT PropertyStorage_ConstructEmpty(IStream *stm,
* Implementation of IPropertySetStorage
*/
#define BITS_PER_BYTE 8
#define CHARMASK 0x1f
#define BITS_IN_CHARMASK 5
/* Converts rfmtid to a string and returns the resulting string. If rfmtid
* is a well-known FMTID, it just returns a static string. Otherwise it
* creates the appropriate string name in str, which must be 27 characters
* in length, and returns str.
* Based on the algorithm described here:
* http://msdn.microsoft.com/library/en-us/stg/stg/names_in_istorage.asp
*/
static
LPCWSTR
format_id_to_name
(
REFFMTID
rfmtid
,
LPWSTR
str
)
{
static
const
char
fmtMap
[]
=
"abcdefghijklmnopqrstuvwxyz012345"
;
static
const
WCHAR
szSummaryInfo
[]
=
{
5
,
'S'
,
'u'
,
'm'
,
'm'
,
'a'
,
'r'
,
'y'
,
'I'
,
'n'
,
'f'
,
'o'
,
'r'
,
'm'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
0
};
static
const
WCHAR
szDocSummaryInfo
[]
=
{
5
,
'D'
,
'o'
,
'c'
,
'u'
,
'm'
,
'e'
,
'n'
,
't'
,
'S'
,
'u'
,
'm'
,
'm'
,
'a'
,
'r'
,
'y'
,
'I'
,
'n'
,
'f'
,
'o'
,
'r'
,
'm'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
0
};
LPCWSTR
ret
;
if
(
IsEqualGUID
(
&
FMTID_SummaryInformation
,
rfmtid
))
ret
=
szSummaryInfo
;
else
if
(
IsEqualGUID
(
&
FMTID_DocSummaryInformation
,
rfmtid
))
ret
=
szDocSummaryInfo
;
else
{
BYTE
*
fmtptr
;
WCHAR
*
pstr
=
str
;
ULONG
bitsRemaining
=
BITS_PER_BYTE
;
*
pstr
++
=
5
;
for
(
fmtptr
=
(
BYTE
*
)
rfmtid
;
fmtptr
<
(
BYTE
*
)
rfmtid
+
sizeof
(
FMTID
);
)
{
ULONG
i
=
*
fmtptr
>>
(
BITS_PER_BYTE
-
bitsRemaining
);
if
(
bitsRemaining
>=
BITS_IN_CHARMASK
)
{
*
pstr
=
(
WCHAR
)(
fmtMap
[
i
&
CHARMASK
]);
if
(
bitsRemaining
==
BITS_PER_BYTE
&&
*
pstr
>=
'a'
&&
*
pstr
<=
'z'
)
*
pstr
+=
'A'
-
'a'
;
pstr
++
;
bitsRemaining
-=
BITS_IN_CHARMASK
;
if
(
bitsRemaining
==
0
)
{
fmtptr
++
;
bitsRemaining
=
BITS_PER_BYTE
;
}
}
else
{
if
(
++
fmtptr
<
(
BYTE
*
)
rfmtid
+
sizeof
(
FMTID
))
i
|=
*
fmtptr
<<
bitsRemaining
;
*
pstr
++
=
(
WCHAR
)(
fmtMap
[
i
&
CHARMASK
]);
}
}
*
pstr
=
0
;
ret
=
str
;
}
TRACE
(
"returning %s
\n
"
,
debugstr_w
(
ret
));
return
ret
;
}
/************************************************************************
* IPropertySetStorage_fnQueryInterface (IUnknown)
*
...
...
@@ -1910,8 +1846,7 @@ static HRESULT WINAPI IPropertySetStorage_fnCreate(
IPropertyStorage
**
ppprstg
)
{
_ICOM_THIS_From_IPropertySetStorage
(
StorageImpl
,
ppstg
);
WCHAR
nameBuf
[
27
];
LPCWSTR
name
=
NULL
;
WCHAR
name
[
CCH_MAX_PROPSTG_NAME
];
IStream
*
stm
=
NULL
;
HRESULT
r
;
...
...
@@ -1941,7 +1876,9 @@ static HRESULT WINAPI IPropertySetStorage_fnCreate(
goto
end
;
}
name
=
format_id_to_name
(
rfmtid
,
nameBuf
);
r
=
FmtIdToPropStgName
(
rfmtid
,
name
);
if
(
FAILED
(
r
))
goto
end
;
r
=
IStorage_CreateStream
(
(
IStorage
*
)
This
,
name
,
grfMode
,
0
,
0
,
&
stm
);
if
(
FAILED
(
r
))
...
...
@@ -1965,8 +1902,7 @@ static HRESULT WINAPI IPropertySetStorage_fnOpen(
{
_ICOM_THIS_From_IPropertySetStorage
(
StorageImpl
,
ppstg
);
IStream
*
stm
=
NULL
;
WCHAR
nameBuf
[
27
];
LPCWSTR
name
=
NULL
;
WCHAR
name
[
CCH_MAX_PROPSTG_NAME
];
HRESULT
r
;
TRACE
(
"%p %s %08lx %p
\n
"
,
This
,
debugstr_guid
(
rfmtid
),
grfMode
,
ppprstg
);
...
...
@@ -1985,7 +1921,9 @@ static HRESULT WINAPI IPropertySetStorage_fnOpen(
goto
end
;
}
name
=
format_id_to_name
(
rfmtid
,
nameBuf
);
r
=
FmtIdToPropStgName
(
rfmtid
,
name
);
if
(
FAILED
(
r
))
goto
end
;
r
=
IStorage_OpenStream
((
IStorage
*
)
This
,
name
,
0
,
grfMode
,
0
,
&
stm
);
if
(
FAILED
(
r
))
...
...
@@ -2007,17 +1945,17 @@ static HRESULT WINAPI IPropertySetStorage_fnDelete(
{
_ICOM_THIS_From_IPropertySetStorage
(
StorageImpl
,
ppstg
);
IStorage
*
stg
=
NULL
;
WCHAR
name
Buf
[
27
];
LPCWSTR
name
=
NULL
;
WCHAR
name
[
CCH_MAX_PROPSTG_NAME
];
HRESULT
r
;
TRACE
(
"%p %s
\n
"
,
This
,
debugstr_guid
(
rfmtid
));
if
(
!
rfmtid
)
return
E_INVALIDARG
;
name
=
format_id_to_name
(
rfmtid
,
nameBuf
);
if
(
!
name
)
return
STG_E_FILENOTFOUND
;
r
=
FmtIdToPropStgName
(
rfmtid
,
name
);
if
(
FAILED
(
r
)
)
return
r
;
stg
=
(
IStorage
*
)
This
;
return
IStorage_DestroyElement
(
stg
,
name
);
...
...
@@ -2068,3 +2006,172 @@ static IPropertyStorageVtbl IPropertyStorage_Vtbl =
IPropertyStorage_fnSetClass
,
IPropertyStorage_fnStat
,
};
/***********************************************************************
* Format ID <-> name conversion
*/
static
const
WCHAR
szSummaryInfo
[]
=
{
5
,
'S'
,
'u'
,
'm'
,
'm'
,
'a'
,
'r'
,
'y'
,
'I'
,
'n'
,
'f'
,
'o'
,
'r'
,
'm'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
0
};
static
const
WCHAR
szDocSummaryInfo
[]
=
{
5
,
'D'
,
'o'
,
'c'
,
'u'
,
'm'
,
'e'
,
'n'
,
't'
,
'S'
,
'u'
,
'm'
,
'm'
,
'a'
,
'r'
,
'y'
,
'I'
,
'n'
,
'f'
,
'o'
,
'r'
,
'm'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
0
};
#define BITS_PER_BYTE 8
#define CHARMASK 0x1f
#define BITS_IN_CHARMASK 5
#define NUM_ALPHA_CHARS 26
/***********************************************************************
* FmtIdToPropStgName [ole32.@]
* Returns the storage name of the format ID rfmtid.
* PARAMS
* rfmtid [I] Format ID for which to return a storage name
* str [O] Storage name associated with rfmtid.
*
* RETURNS
* E_INVALIDARG if rfmtid or str i NULL, S_OK otherwise.
*
* NOTES
* str must be at least CCH_MAX_PROPSTG_NAME characters in length.
* Based on the algorithm described here:
* http://msdn.microsoft.com/library/en-us/stg/stg/names_in_istorage.asp
*/
HRESULT
WINAPI
FmtIdToPropStgName
(
const
FMTID
*
rfmtid
,
LPOLESTR
str
)
{
static
const
char
fmtMap
[]
=
"abcdefghijklmnopqrstuvwxyz012345"
;
TRACE
(
"%s, %p
\n
"
,
debugstr_guid
(
rfmtid
),
str
);
if
(
!
rfmtid
)
return
E_INVALIDARG
;
if
(
!
str
)
return
E_INVALIDARG
;
if
(
IsEqualGUID
(
&
FMTID_SummaryInformation
,
rfmtid
))
lstrcpyW
(
str
,
szSummaryInfo
);
else
if
(
IsEqualGUID
(
&
FMTID_DocSummaryInformation
,
rfmtid
))
lstrcpyW
(
str
,
szDocSummaryInfo
);
else
if
(
IsEqualGUID
(
&
FMTID_UserDefinedProperties
,
rfmtid
))
lstrcpyW
(
str
,
szDocSummaryInfo
);
else
{
BYTE
*
fmtptr
;
WCHAR
*
pstr
=
str
;
ULONG
bitsRemaining
=
BITS_PER_BYTE
;
*
pstr
++
=
5
;
for
(
fmtptr
=
(
BYTE
*
)
rfmtid
;
fmtptr
<
(
BYTE
*
)
rfmtid
+
sizeof
(
FMTID
);
)
{
ULONG
i
=
*
fmtptr
>>
(
BITS_PER_BYTE
-
bitsRemaining
);
if
(
bitsRemaining
>=
BITS_IN_CHARMASK
)
{
*
pstr
=
(
WCHAR
)(
fmtMap
[
i
&
CHARMASK
]);
if
(
bitsRemaining
==
BITS_PER_BYTE
&&
*
pstr
>=
'a'
&&
*
pstr
<=
'z'
)
*
pstr
+=
'A'
-
'a'
;
pstr
++
;
bitsRemaining
-=
BITS_IN_CHARMASK
;
if
(
bitsRemaining
==
0
)
{
fmtptr
++
;
bitsRemaining
=
BITS_PER_BYTE
;
}
}
else
{
if
(
++
fmtptr
<
(
BYTE
*
)
rfmtid
+
sizeof
(
FMTID
))
i
|=
*
fmtptr
<<
bitsRemaining
;
*
pstr
++
=
(
WCHAR
)(
fmtMap
[
i
&
CHARMASK
]);
bitsRemaining
+=
BITS_PER_BYTE
-
BITS_IN_CHARMASK
;
}
}
*
pstr
=
0
;
}
TRACE
(
"returning %s
\n
"
,
debugstr_w
(
str
));
return
S_OK
;
}
/***********************************************************************
* PropStgNameToFmtId [ole32.@]
* Returns the format ID corresponding to the given name.
* PARAMS
* str [I] Storage name to convert to a format ID.
* rfmtid [O] Format ID corresponding to str.
*
* RETURNS
* E_INVALIDARG if rfmtid or str is NULL or if str can't be converted to
* a format ID, S_OK otherwise.
*
* NOTES
* Based on the algorithm described here:
* http://msdn.microsoft.com/library/en-us/stg/stg/names_in_istorage.asp
*/
HRESULT
WINAPI
PropStgNameToFmtId
(
const
LPOLESTR
str
,
FMTID
*
rfmtid
)
{
HRESULT
hr
=
E_INVALIDARG
;
TRACE
(
"%s, %p
\n
"
,
debugstr_w
(
str
),
rfmtid
);
if
(
!
rfmtid
)
return
E_INVALIDARG
;
if
(
!
str
)
return
E_INVALIDARG
;
if
(
!
lstrcmpiW
(
str
,
szDocSummaryInfo
))
{
memcpy
(
rfmtid
,
&
FMTID_DocSummaryInformation
,
sizeof
(
*
rfmtid
));
hr
=
S_OK
;
}
else
if
(
!
lstrcmpiW
(
str
,
szSummaryInfo
))
{
memcpy
(
rfmtid
,
&
FMTID_SummaryInformation
,
sizeof
(
*
rfmtid
));
hr
=
S_OK
;
}
else
{
ULONG
bits
;
BYTE
*
fmtptr
=
(
BYTE
*
)
rfmtid
-
1
;
const
WCHAR
*
pstr
=
str
;
memset
(
rfmtid
,
0
,
sizeof
(
*
rfmtid
));
for
(
bits
=
0
;
bits
<
sizeof
(
FMTID
)
*
BITS_PER_BYTE
;
bits
+=
BITS_IN_CHARMASK
)
{
ULONG
bitsUsed
=
bits
%
BITS_PER_BYTE
,
bitsStored
;
WCHAR
wc
;
if
(
bitsUsed
==
0
)
fmtptr
++
;
wc
=
*++
pstr
-
'A'
;
if
(
wc
>
NUM_ALPHA_CHARS
)
{
wc
+=
'A'
-
'a'
;
if
(
wc
>
NUM_ALPHA_CHARS
)
{
wc
+=
'a'
-
'0'
+
NUM_ALPHA_CHARS
;
if
(
wc
>
CHARMASK
)
{
WARN
(
"invalid character (%d)
\n
"
,
*
pstr
);
goto
end
;
}
}
}
*
fmtptr
|=
wc
<<
bitsUsed
;
bitsStored
=
min
(
BITS_PER_BYTE
-
bitsUsed
,
BITS_IN_CHARMASK
);
if
(
bitsStored
<
BITS_IN_CHARMASK
)
{
wc
>>=
BITS_PER_BYTE
-
bitsUsed
;
if
(
bits
+
bitsStored
==
sizeof
(
FMTID
)
*
BITS_PER_BYTE
)
{
if
(
wc
!=
0
)
{
WARN
(
"extra bits
\n
"
);
goto
end
;
}
break
;
}
fmtptr
++
;
*
fmtptr
|=
(
BYTE
)
wc
;
}
}
hr
=
S_OK
;
}
end:
return
hr
;
}
dlls/ole32/tests/stg_prop.c
View file @
e68982fc
...
...
@@ -244,7 +244,77 @@ static void testProps(void)
DeleteFileW
(
filename
);
}
static
void
testFmtId
(
void
)
{
WCHAR
szSummaryInfo
[]
=
{
5
,
'S'
,
'u'
,
'm'
,
'm'
,
'a'
,
'r'
,
'y'
,
'I'
,
'n'
,
'f'
,
'o'
,
'r'
,
'm'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
0
};
WCHAR
szDocSummaryInfo
[]
=
{
5
,
'D'
,
'o'
,
'c'
,
'u'
,
'm'
,
'e'
,
'n'
,
't'
,
'S'
,
'u'
,
'm'
,
'm'
,
'a'
,
'r'
,
'y'
,
'I'
,
'n'
,
'f'
,
'o'
,
'r'
,
'm'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
0
};
WCHAR
szIID_IPropSetStg
[]
=
{
5
,
'0'
,
'j'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'A'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'd'
,
'a'
,
'A'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'G'
,
'c'
,
0
};
WCHAR
name
[
32
];
FMTID
fmtid
;
HRESULT
hr
;
hr
=
FmtIdToPropStgName
(
NULL
,
name
);
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got 0x%08lx
\n
"
,
hr
);
hr
=
FmtIdToPropStgName
(
&
FMTID_SummaryInformation
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got 0x%08lx
\n
"
,
hr
);
hr
=
FmtIdToPropStgName
(
&
FMTID_SummaryInformation
,
name
);
ok
(
SUCCEEDED
(
hr
),
"FmtIdToPropStgName failed: 0x%08lx
\n
"
,
hr
);
ok
(
!
memcmp
(
name
,
szSummaryInfo
,
(
lstrlenW
(
szSummaryInfo
)
+
1
)
*
sizeof
(
WCHAR
)),
"Got wrong name for FMTID_SummaryInformation
\n
"
);
hr
=
FmtIdToPropStgName
(
&
FMTID_DocSummaryInformation
,
name
);
ok
(
SUCCEEDED
(
hr
),
"FmtIdToPropStgName failed: 0x%08lx
\n
"
,
hr
);
ok
(
!
memcmp
(
name
,
szDocSummaryInfo
,
(
lstrlenW
(
szDocSummaryInfo
)
+
1
)
*
sizeof
(
WCHAR
)),
"Got wrong name for FMTID_DocSummaryInformation
\n
"
);
hr
=
FmtIdToPropStgName
(
&
FMTID_UserDefinedProperties
,
name
);
ok
(
SUCCEEDED
(
hr
),
"FmtIdToPropStgName failed: 0x%08lx
\n
"
,
hr
);
ok
(
!
memcmp
(
name
,
szDocSummaryInfo
,
(
lstrlenW
(
szDocSummaryInfo
)
+
1
)
*
sizeof
(
WCHAR
)),
"Got wrong name for FMTID_DocSummaryInformation
\n
"
);
hr
=
FmtIdToPropStgName
(
&
IID_IPropertySetStorage
,
name
);
ok
(
SUCCEEDED
(
hr
),
"FmtIdToPropStgName failed: 0x%08lx
\n
"
,
hr
);
ok
(
!
memcmp
(
name
,
szIID_IPropSetStg
,
(
lstrlenW
(
szIID_IPropSetStg
)
+
1
)
*
sizeof
(
WCHAR
)),
"Got wrong name for IID_IPropertySetStorage
\n
"
);
/* test args first */
hr
=
PropStgNameToFmtId
(
NULL
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got 0x%08lx
\n
"
,
hr
);
hr
=
PropStgNameToFmtId
(
NULL
,
&
fmtid
);
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got 0x%08lx
\n
"
,
hr
);
hr
=
PropStgNameToFmtId
(
szDocSummaryInfo
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got 0x%08lx
\n
"
,
hr
);
/* test the known format IDs */
hr
=
PropStgNameToFmtId
(
szSummaryInfo
,
&
fmtid
);
ok
(
SUCCEEDED
(
hr
),
"PropStgNameToFmtId failed: 0x%08lx
\n
"
,
hr
);
ok
(
!
memcmp
(
&
fmtid
,
&
FMTID_SummaryInformation
,
sizeof
(
fmtid
)),
"Got unexpected FMTID, expected FMTID_SummaryInformation
\n
"
);
hr
=
PropStgNameToFmtId
(
szDocSummaryInfo
,
&
fmtid
);
ok
(
SUCCEEDED
(
hr
),
"PropStgNameToFmtId failed: 0x%08lx
\n
"
,
hr
);
ok
(
!
memcmp
(
&
fmtid
,
&
FMTID_DocSummaryInformation
,
sizeof
(
fmtid
)),
"Got unexpected FMTID, expected FMTID_DocSummaryInformation
\n
"
);
/* test another GUID */
hr
=
PropStgNameToFmtId
(
szIID_IPropSetStg
,
&
fmtid
);
ok
(
SUCCEEDED
(
hr
),
"PropStgNameToFmtId failed: 0x%08lx
\n
"
,
hr
);
ok
(
!
memcmp
(
&
fmtid
,
&
IID_IPropertySetStorage
,
sizeof
(
fmtid
)),
"Got unexpected FMTID, expected IID_IPropertySetStorage
\n
"
);
/* now check case matching */
CharUpperW
(
szDocSummaryInfo
+
1
);
hr
=
PropStgNameToFmtId
(
szDocSummaryInfo
,
&
fmtid
);
ok
(
SUCCEEDED
(
hr
),
"PropStgNameToFmtId failed: 0x%08lx
\n
"
,
hr
);
ok
(
!
memcmp
(
&
fmtid
,
&
FMTID_DocSummaryInformation
,
sizeof
(
fmtid
)),
"Got unexpected FMTID, expected FMTID_DocSummaryInformation
\n
"
);
CharUpperW
(
szIID_IPropSetStg
+
1
);
hr
=
PropStgNameToFmtId
(
szIID_IPropSetStg
,
&
fmtid
);
ok
(
SUCCEEDED
(
hr
),
"PropStgNameToFmtId failed: 0x%08lx
\n
"
,
hr
);
ok
(
!
memcmp
(
&
fmtid
,
&
IID_IPropertySetStorage
,
sizeof
(
fmtid
)),
"Got unexpected FMTID, expected IID_IPropertySetStorage
\n
"
);
}
START_TEST
(
stg_prop
)
{
testProps
();
testFmtId
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment