Nomi in IStorage
Un set di proprietà viene identificato con un identificatore di formato (FMTID) nell'interfaccia IPropertySetStorage . Nell'interfaccia IStorage , un set di proprietà viene denominato con una stringa Unicode con terminazione Null con una lunghezza massima di 32 caratteri. Per abilitare l'interoperabilità, è necessario stabilire un mapping tra un FMTID e una stringa Unicode con terminazione Null corrispondente.
Conversione di un set di proprietà da un FMTID a un nome stringa
Quando si esegue la conversione da un FMTID a un nome stringa Unicode corrispondente, verificare innanzitutto che FMTID sia un valore noto, elencato nella tabella seguente. In tal caso, usare il nome di stringa noto corrispondente.
FMTID | Nome della stringa | Semantica |
---|---|---|
F29F85E0-4FF9-1068-AB91-08002B27B3D9 | "\005SummaryInformation" | Informazioni di riepilogo COM2 |
D5CDD502-2E9C-101B-9397-08002B2CF9AE D5CDD505-2E9C-101B-9397-08002B2CF9AE |
"\005DocumentSummaryInformation" | Informazioni di riepilogo del documento di Office e proprietà definite dall'utente. |
Nota
Il set di proprietà DocumentSummaryInformation e UserDefined è univoco in quanto contiene due sezioni. In nessun altro set di proprietà non sono consentite più sezioni. Per altre informazioni, vedere Structured Storage Serialized Property Set Format e i set di proprietà DocumentSummaryInformation e UserDefined. La prima sezione è stata definita come parte di COM; il secondo è stato definito da Microsoft Office.
Se FMTID non è un valore noto, utilizzare la procedura seguente per formare in modo algoritmico un nome di stringa.
Per formare in modo algoritmico un nome stringa
- Convertire l'FMTID in ordine di byte little-endian, se necessario.
- Prendere i 128 bit di FMTID e considerarli come una stringa di bit lunga concatenando ognuno dei byte insieme. Il primo bit del valore a 128 bit è il bit meno significativo del primo byte in memoria dell'FMTID; l'ultimo bit del valore a 128 bit è il bit più significativo dell'ultimo byte in memoria dell'FMTID. Estendere questi 128 bit a 130 bit aggiungendo due bit zero alla fine.
- Dividere i 130 bit in gruppi di cinque bit; ci saranno 26 gruppi di questo tipo. Considerare ogni gruppo come intero con precedenza di bit invertita. Ad esempio, il primo dei 128 bit è il bit meno significativo del primo gruppo di cinque bit; il quinto dei 128 bit è il bit più significativo del primo gruppo.
- Eseguire il mapping di ognuno di questi interi come indice nella matrice di trentadue caratteri: ABCDEFGHIJKLMNOPQRSTUVWXYZ012345. In questo modo viene restituita una sequenza di 26 caratteri Unicode che usa solo caratteri maiuscoli e numeri. Le considerazioni di distinzione tra maiuscole e minuscole e senza distinzione tra maiuscole e minuscole non si applicano, causando l'univocità di ogni carattere in tutte le impostazioni locali.
- Creare la stringa finale concatenando la stringa "\005" nella parte anteriore di questi 26 caratteri, per una lunghezza totale di 27 caratteri.
Il codice di esempio seguente illustra come eseguire il mapping da un FMTID a una stringa di proprietà.
#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';
}
Conversione di un set di proprietà da un nome stringa a un FMTID
I convertitori di nomi di stringhe di proprietà in GUID devono accettare lettere minuscole come sinonimi delle rispettive controparti maiuscole.
Il codice di esempio seguente illustra come eseguire il mapping da una stringa di proprietà a 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);
}
Quando si tenta di aprire un set di proprietà esistente, in IPropertySetStorage::Open, fmTID (radice) viene convertito in una stringa come descritto in precedenza. Se esiste un elemento dell'oggetto IStorage di tale nome, viene usato. In caso contrario, l'apertura ha esito negativo.
Quando si crea un nuovo set di proprietà, il mapping precedente determina il nome della stringa usato.