Noms dans IStorage
Un jeu de propriétés est identifié avec un identificateur de format (FMTID) dans l’interface IPropertySetStorage . Dans l’interface IStorage , un jeu de propriétés est nommé avec une chaîne Unicode terminée par null avec une longueur maximale de 32 caractères. Pour activer l’interopérabilité, un mappage entre un FMTID et une chaîne Unicode null correspondante doit être établi.
Conversion d’un jeu de propriétés d’un FMTID en nom de chaîne
Lors de la conversion d’un FMTID en nom de chaîne Unicode correspondant, vérifiez d’abord que le FMTID est une valeur bien connue, répertoriée dans le tableau suivant. Si c’est le cas, utilisez le nom de chaîne connu correspondant.
FMTID | Nom de la chaîne | Sémantique |
---|---|---|
F29F85E0-4FF9-1068-AB91-08002B27B3D9 | « \005SummaryInformation » | Informations récapitulatives COM2 |
D5CDD502-2E9C-101B-9397-08002B2CF9AE D5CDD505-2E9C-101B-9397-08002B2CF9AE |
« \005DocumentSummaryInformation » | Informations récapitulatives des documents Office et propriétés définies par l’utilisateur. |
Notes
Le jeu de propriétés DocumentSummaryInformation et UserDefined est unique en ce qu’il contient deux sections. Plusieurs sections ne sont pas autorisées dans un autre jeu de propriétés. Pour plus d’informations, consultez Format d’ensemble de propriétés sérialisées du stockage structuré et Ensembles de propriétés DocumentSummaryInformation et UserDefined. La première section a été définie dans le cadre de COM ; le deuxième a été défini par Microsoft Office.
Si le FMTID n’est pas une valeur bien connue, utilisez la procédure suivante pour former algorithmiquement un nom de chaîne.
Pour former algorithmiquement un nom de chaîne
- Convertissez le FMTID en ordre d’octet petit-endian, si nécessaire.
- Prenez les 128 bits du FMTID et considérez-les comme une chaîne de bits long en concaténant chacun des octets ensemble. Le premier bit de la valeur 128 bits est le bit le moins significatif du premier octet dans la mémoire du FMTID ; le dernier bit de la valeur 128 bits est le bit le plus significatif du dernier octet dans la mémoire du FMTID. Étendez ces 128 bits à 130 bits en ajoutant deux bits zéro à la fin.
- Diviser les 130 bits en groupes de cinq bits ; il y aura 26 groupes de ce type. Considérez chaque groupe comme un entier avec priorité de bits inversés. Par exemple, le premier des 128 bits est le bit le moins significatif du premier groupe de cinq bits ; le cinquième des 128 bits est le bit le plus significatif du premier groupe.
- Mapper chacun de ces entiers sous forme d’index dans le tableau de trente-deux caractères : ABCDEFGHIJKLMNOPQRSTUVWXYZ012345. Cela génère une séquence de 26 caractères Unicode qui utilise uniquement des caractères majuscules et des chiffres. Les considérations respectant la casse et ne respectant pas la casse ne s’appliquent pas, ce qui rend chaque caractère unique dans tous les paramètres régionaux.
- Créez la chaîne finale en concaténant la chaîne « \005 » sur le devant de ces 26 caractères, pour une longueur totale de 27 caractères.
L’exemple de code suivant montre comment mapper d’un FMTID à une chaîne de propriété.
#define CBIT_BYTE 8
#define CBIT_CHARMASK 5
#define CCH_MAP (1 << CBIT_CHARMASK) // 32
#define CHARMASK (CCH_MAP - 1) // 0x1f
CHAR awcMap[CCH_MAP + 1] = "abcdefghijklmnopqrstuvwxyz012345";
WCHAR MapChar(ULONG I) {
return((WCHAR) awcMap[i & CHARMASK]);
}
VOID GuidToPropertyStringName(GUID *pguid, WCHAR awcname[]) {
BYTE *pb = (BYTE *) pguid;
BYTE *pbEnd = pb + sizeof(*pguid);
ULONG cbitRemain = CBIT_BYTE;
WCHAR *pwc = awcname;
*pwc++ = ((WCHAR) 0x0005);
while (pb < pbEnd) {
ULONG i = *pb >> (CBIT_BYTE - cbitRemain);
if (cbitRemain >= CBIT_CHARMASK) {
*pwc = MapChar(i);
if (cbitRemain == CBIT_BYTE &&
*pwc >= L'a' && *pwc <= L'z')
{
*pwc += (WCHAR) (L'A' - L'a');
}
pwc++;
cbitRemain -= CBIT_CHARMASK;
if (cbitRemain == 0) {
pb++;
cbitRemain = CBIT_BYTE;
}
}
else {
if (++pb < pbEnd) {
i |= *pb << cbitRemain;
}
*pwc++ = MapChar(i);
cbitRemain += CBIT_BYTE - CBIT_CHARMASK;
}
}
*pwc = L'\0';
}
Conversion d’un jeu de propriétés d’un nom de chaîne en FMTID
Les convertisseurs de noms de chaîne de propriété en GUID doivent accepter les lettres minuscules comme synonymes de leurs équivalents majuscules.
L’exemple de code suivant montre comment mapper d’une chaîne de propriété à un FMTID.
#include "stdafx.h"
#define _INC_OLE
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define CBIT_CHARMASK 5
#define CBIT_BYTE 8
#define CBIT_GUID (CBIT_BYTE * sizeof(GUID))
#define CWC_PROPSET (1 + (CBIT_GUID + CBIT_CHARMASK-1)/CBIT_CHARMASK)
#define WC_PROPSET0 ((WCHAR) 0x0005)
#define CCH_MAP (1 << CBIT_CHARMASK) // 32
#define CHARMASK (CCH_MAP - 1) // 0x1f
CHAR awcMap[CCH_MAP + 1] = "abcdefghijklmnopqrstuvwxyz012345";
#define CALPHACHARS ('z' - 'a' + 1)
GUID guidSummary =
{ 0xf29f85e0,0x4ff9, 0x1068,
{ 0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9 } };
WCHAR wszSummary[] = L"SummaryInformation";
GUID guidDocumentSummary =
{ 0xd5cdd502,
0x2e9c, 0x101b,
{ 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae } };
WCHAR wszDocumentSummary[] = L"DocumentSummaryInformation";
__inline WCHAR
MapChar(IN ULONG i)
{
return((WCHAR) awcMap[i & CHARMASK]);
}
ULONG PropertySetNameToGuid(
IN ULONG cwcname,
IN WCHAR const awcname[],
OUT GUID *pguid)
{
ULONG Status = ERROR_INVALID_PARAMETER;
WCHAR const *pwc = awcname;
if (pwc[0] == WC_PROPSET0)
{
//Note: cwcname includes the WC_PROPSET0, and
//sizeof(wsz...) includes the trailing L'\0', but
//the comparison excludes both the leading
//WC_PROPSET0 and the trailing L'\0'.
if (cwcname == sizeof(wszSummary)/sizeof(WCHAR) &&
wcsnicmp(&pwc[1], wszSummary, cwcname - 1) == 0)
{
*pguid = guidSummary;
return(NO_ERROR);
}
if (cwcname == CWC_PROPSET)
{
ULONG cbit;
BYTE *pb = (BYTE *) pguid - 1;
ZeroMemory(pguid, sizeof(*pguid));
for (cbit = 0; cbit < CBIT_GUID; cbit +=
CBIT_CHARMASK)
{
ULONG cbitUsed = cbit % CBIT_BYTE;
ULONG cbitStored;
WCHAR wc;
if (cbitUsed == 0)
{
pb++;
}
wc = *++pwc - L'A'; //assume uppercase
if (wc > CALPHACHARS)
{
wc += (WCHAR) (L'A' - L'a'); //try lowercase
if (wc > CALPHACHARS)
{
wc += L'a' - L'0' + CALPHACHARS;
if (wc > CHARMASK)
{
goto fail; //invalid character
}
}
}
*pb |= (BYTE) (wc << cbitUsed);
cbitStored = min(CBIT_BYTE - cbitUsed,
CBIT_CHARMASK);
//If the translated bits will not fit in the
//current byte
if (cbitStored < CBIT_CHARMASK)
{
wc >>= CBIT_BYTE - cbitUsed;
if (cbit + cbitStored == CBIT_GUID)
{
if (wc != 0)
{
goto fail; //extra bits
}
break;
}
pb++;
*pb |= (BYTE) wc;
}
}
Status = NO_ERROR;
}
}
fail:
return(Status);
}
Lorsque vous tentez d’ouvrir un jeu de propriétés existant, dans IPropertySetStorage::Open, le FMTID (racine) est converti en chaîne comme décrit ci-dessus. Si un élément de l’IStorage de ce nom existe, il est utilisé. Sinon, l’ouverture échoue.
Lors de la création d’un jeu de propriétés, le mappage ci-dessus détermine le nom de chaîne utilisé.