3,245
社区成员
发帖
与我相关
我的任务
分享
#include <stdlib.h>
#include <windows.h>
#include <objidl.h>
#pragma comment(lib, "ole32.lib")
WCHAR g_wszFileName[]=L"d:\\temp\\test.doc";
void OutputStgProps(IStorage * pStg);
void DisplayPropStg(REFFMTID fmtid, IPropertyStorage * pPropStg);
void OutputPropString(const PROPVARIANT &pvar, const STATPROPSTG &stat);
void VarientToString( const PROPVARIANT &propvar, WCHAR *pwszValue, ULONG cchValue);
int main(int argc, char* argv[])
{
int rc=0;
HRESULT hr=S_OK;
IStorage *pStg=NULL;
hr=StgOpenStorageEx(g_wszFileName,
STGM_READ | STGM_SHARE_DENY_WRITE,
STGFMT_ANY, 0, NULL, NULL, IID_IStorage, (LPVOID *)&pStg);
if(FAILED(hr)) goto Label_ErrExit;
OutputStgProps(pStg);
pStg->Release();
getchar();
return 0;
Label_ErrExit:
rc=GetLastError();
printf("Error=%ld\r\n", rc);
return rc;
}
void OutputStgProps(IStorage * pStg)
{
HRESULT hr=S_OK;
IPropertySetStorage *pPropSet=NULL;
IPropertyStorage *pPropStg=NULL;
STATPROPSETSTG stat;
IEnumSTATPROPSETSTG *pIEnumStats=NULL;
hr=pStg->QueryInterface(IID_IPropertySetStorage, (LPVOID *)&pPropSet);
if(FAILED(hr))
{
goto Label_ErrExit;
}
// enum PROPSET
hr=pPropSet->Enum(&pIEnumStats);
if(FAILED(hr))
{
goto Label_ErrExit;
}
RtlZeroMemory(&stat, sizeof(STATPROPSETSTG));
hr=pIEnumStats->Next(1, &stat, NULL);
while(S_OK==hr)
{
hr=pPropSet->Open(stat.fmtid, STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStg);
if(FAILED(hr)) goto Label_ErrExit;
DisplayPropStg(stat.fmtid, pPropStg);
pPropStg->Release();
pPropStg=NULL;
hr=pIEnumStats->Next(1, &stat, NULL);
}
pPropSet->Release();
return;
Label_ErrExit:
printf("OutputStgProps Error=%ld\r\n", GetLastError());
if(NULL!=pPropSet) pPropSet->Release();
return;
}
void DisplayPropStg(REFFMTID fmtid, IPropertyStorage * pPropStg)
{
HRESULT hr;
IEnumSTATPROPSTG *pIEnum=NULL;
STATPROPSTG stat;
PROPVARIANT pvar;
PROPSPEC spec;
PROPID propid;
WCHAR *pwszDisplayName=NULL;
WCHAR wszFmtID[64]=L"";
PropVariantInit(&pvar);
StringFromGUID2(fmtid, wszFmtID, sizeof(wszFmtID)/sizeof(wszFmtID[0]));
wprintf(L"%s:\r\n", wszFmtID);
if(FMTID_SummaryInformation==fmtid)
wprintf(L"\t(SummaryInformation)\r\n");
else if(FMTID_DocSummaryInformation==fmtid)
wprintf(L"\t(DocumentSummaryInformation)\r\n");
hr=pPropStg->ReadPropertyNames(1, &propid, &pwszDisplayName);
if(S_OK==hr)
{
wprintf(L"\t[%s]: ", pwszDisplayName);
CoTaskMemFree(pwszDisplayName);
pwszDisplayName=NULL;
}
hr=pPropStg->Enum(&pIEnum);
if(S_OK==hr)
{
hr=pIEnum->Next(1, &stat, NULL);
while(S_OK==hr)
{
PropVariantInit(&pvar);
spec.ulKind=PRSPEC_PROPID;
spec.propid=stat.propid;
hr=pPropStg->ReadMultiple(1, &spec, &pvar);
if(FAILED(hr))
{
pIEnum->Release();
goto Label_ErrExit;
}
OutputPropString(pvar, stat);
PropVariantClear(&pvar);
CoTaskMemFree(stat.lpwstrName);
stat.lpwstrName=NULL;
hr=pIEnum->Next(1, &stat, NULL);
}
if(NULL!=pIEnum) pIEnum->Release();
}
if(NULL!=stat.lpwstrName) CoTaskMemFree(stat.lpwstrName);
PropVariantClear(&pvar);
return;
Label_ErrExit:
return;
}
void OutputPropString(const PROPVARIANT &pvar, const STATPROPSTG &stat)
{
WCHAR wsz[MAX_PATH+1]=L"";
// 查MSDN的参照表,输出id对应的字符串, 此处省略。
// PropIDToString(stat.propid, wsz, MAX_PATH);
// wprintf(L"\t%s: ", wsz);
wprintf(L" (id=%ld) (vartype=%ld)\r\n", stat.propid, stat.vt);
// RtlZeroMemory(wsz,sizeof(wsz));
VarientToString(pvar, wsz, MAX_PATH);
wprintf(L"Value=%s\r\n", wsz);
}
void VarientToString( const PROPVARIANT &propvar, WCHAR *pwszValue, ULONG cchValue )
{
// Ensure that the output string is terminated
pwszValue[ cchValue - 1 ] = L'\0';
--cchValue;
// Based on the type, put the value into pwszValue as a string.
switch( propvar.vt )
{
case VT_EMPTY:
wcsncpy( pwszValue, L"", cchValue );
break;
case VT_NULL:
wcsncpy( pwszValue, L"", cchValue );
break;
case VT_I2:
_snwprintf( pwszValue, cchValue, L"%i", propvar.iVal );
break;
case VT_I4:
case VT_INT:
_snwprintf( pwszValue, cchValue, L"%li", propvar.lVal );
break;
case VT_I8:
_snwprintf( pwszValue, cchValue, L"%I64i", propvar.hVal );
break;
case VT_UI2:
_snwprintf ( pwszValue, cchValue, L"%u", propvar.uiVal );
break;
case VT_UI4:
case VT_UINT:
_snwprintf ( pwszValue, cchValue, L"%lu", propvar.ulVal );
break;
case VT_UI8:
_snwprintf ( pwszValue, cchValue, L"%I64u", propvar.uhVal );
break;
case VT_R4:
_snwprintf ( pwszValue, cchValue, L"%f", propvar.fltVal );
break;
case VT_R8:
_snwprintf ( pwszValue, cchValue, L"%lf", propvar.dblVal );
break;
case VT_BSTR:
_snwprintf ( pwszValue, cchValue, L"\"%s\"",
propvar.bstrVal );
break;
case VT_ERROR:
_snwprintf ( pwszValue, cchValue, L"0x%08X", propvar.scode );
break;
case VT_BOOL:
_snwprintf ( pwszValue, cchValue, L"%s",
VARIANT_TRUE == propvar.boolVal ? L"True" : L"False" );
break;
case VT_I1:
_snwprintf ( pwszValue, cchValue, L"%i", propvar.cVal );
break;
case VT_UI1:
_snwprintf ( pwszValue, cchValue, L"%u", propvar.bVal );
break;
case VT_VOID:
wcsncpy( pwszValue, L"", cchValue );
break;
case VT_LPSTR:
if( 0 > _snwprintf ( pwszValue, cchValue,
L"\"%hs\"", propvar.pszVal ))
// String is too large for pwszValue
wcsncpy( pwszValue, L"...", cchValue );
break;
case VT_LPWSTR:
if( 0 > _snwprintf ( pwszValue, cchValue,
L"\"%s\"", propvar.pwszVal ))
// String is too large for pwszValue
wcsncpy( pwszValue, L"...", cchValue );
break;
case VT_FILETIME:
_snwprintf ( pwszValue, cchValue, L"%08x:%08x",
propvar.filetime.dwHighDateTime,
propvar.filetime.dwLowDateTime );
break;
case VT_CLSID:
pwszValue[0] = L'\0';
StringFromGUID2( *propvar.puuid, pwszValue, cchValue );
break;
default:
wcsncpy( pwszValue, L"...", cchValue );
break;
}
}