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 terminée par null correspondante doit être établi.
Conversion d’un jeu de propriétés à partir 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 connue, répertoriée dans le tableau suivant. Dans ce cas, utilisez le nom de chaîne connu correspondant.
FMTID | Nom de 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 du document Office et propriétés définies par l’utilisateur. |
Note
Le jeu de propriétés DocumentSummaryInformation et UserDefined est unique dans lequel 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 de jeu de propriétés sérialisées de stockage structuré, et Les ensembles de propriétés DocumentSummaryInformation et UserDefined. La première section a été définie dans com ; la seconde a été définie par Microsoft Office.
Si le FMTID n’est pas une valeur connue, utilisez la procédure suivante pour former de façon algorithmique un nom de chaîne.
Former de façon algorithmique un nom de chaîne
- Convertissez le FMTID en ordre d’octet petit-endian, si nécessaire.
- Prenez les 128 bits de la FMTID et considérez-les comme une chaîne de bits longue en concaténant chacun des octets ensemble. Le premier bit de la valeur 128 bits est le bit le moins significatif du premier octet en mémoire de la FMTID ; le dernier bit de la valeur 128 bits est le bit le plus significatif du dernier octet en mémoire de la FMTID. Étendez ces 128 bits à 130 bits en ajoutant deux bits zéro à la fin.
- Divisez les 130 bits en groupes de cinq bits ; il y aura 26 groupes de ce genre. Considérez chaque groupe comme un entier avec priorité de bits inversée. 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.
- Mappez chacun de ces entiers en tant qu’index dans le tableau de trente-deux caractères : ABCDEFGHIJKLMNOPQRSTUVWXYZ012345. Cela génère une séquence de 26 caractères Unicode qui utilisent uniquement des caractères majuscules et des chiffres. Les considérations sensibles à la casse et non sensibles à la casse ne s’appliquent pas, ce qui entraîne l’unicité de chaque caractère dans 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 à partir d’un nom de chaîne en FMTID
Les convertisseurs de noms de chaîne de propriété en GUID doivent accepter des lettres minuscules comme synonymes de leurs équivalents majuscules.
L’exemple de code suivant montre comment mapper à partir 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);
}
Lors de la tentative d’ouverture d’un jeu de propriétés existant, dans IPropertySetStorage ::Open, la fmTID (racine) est convertie 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é.