You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
5.6 KiB
285 lines
5.6 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
mddmp.cxx
|
|
|
|
Abstract:
|
|
|
|
Meta Data Dump Utility.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 03-Feb-1997
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.hxx"
|
|
#pragma hdrstop
|
|
|
|
|
|
//
|
|
// Private constants.
|
|
//
|
|
|
|
#define TEST_HRESULT(api,hr,fatal) \
|
|
if( FAILED(hr) ) { \
|
|
\
|
|
wprintf( \
|
|
L"%S:%lu failed, error %lx %S\n", \
|
|
(api), \
|
|
__LINE__, \
|
|
(result), \
|
|
(fatal) \
|
|
? "ABORTING" \
|
|
: "CONTINUING" \
|
|
); \
|
|
\
|
|
if( fatal ) { \
|
|
\
|
|
goto cleanup; \
|
|
\
|
|
} \
|
|
\
|
|
} else
|
|
|
|
|
|
//
|
|
// Private types.
|
|
//
|
|
|
|
typedef struct _ENUM_CONTEXT {
|
|
|
|
LPWSTR Leaf;
|
|
WCHAR Path[MAX_PATH];
|
|
|
|
} ENUM_CONTEXT, *PENUM_CONTEXT;
|
|
|
|
|
|
//
|
|
// Private globals.
|
|
//
|
|
|
|
|
|
//
|
|
// Private prototypes.
|
|
//
|
|
|
|
VOID
|
|
DumpTree(
|
|
IMSAdminBase * AdmCom,
|
|
PENUM_CONTEXT Context
|
|
);
|
|
|
|
BOOL
|
|
WINAPI
|
|
EnumCallback(
|
|
IMSAdminBase * AdmCom,
|
|
LPWSTR ObjectName,
|
|
VOID * Context
|
|
);
|
|
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
|
|
INT
|
|
__cdecl
|
|
wmain(
|
|
INT argc,
|
|
LPWSTR argv[]
|
|
)
|
|
{
|
|
|
|
HRESULT result;
|
|
IMSAdminBase * admCom;
|
|
ENUM_CONTEXT context;
|
|
|
|
//
|
|
// Setup locals so we know how to cleanup on exit.
|
|
//
|
|
|
|
admCom = NULL;
|
|
|
|
//
|
|
// Initialize COM.
|
|
//
|
|
|
|
result = CoInitializeEx(
|
|
NULL,
|
|
COINIT_MULTITHREADED
|
|
);
|
|
|
|
TEST_HRESULT( "CoInitializeEx()", result, TRUE );
|
|
|
|
//
|
|
// Get the admin object.
|
|
//
|
|
|
|
result = MdGetAdminObject( &admCom );
|
|
|
|
TEST_HRESULT( "MdGetAdminObject()", result, TRUE );
|
|
|
|
//
|
|
// Dump the metabase tree.
|
|
//
|
|
|
|
wcscpy(
|
|
context.Path,
|
|
L"/"
|
|
);
|
|
|
|
DumpTree(
|
|
admCom,
|
|
&context
|
|
);
|
|
|
|
cleanup:
|
|
|
|
//
|
|
// Release the admin object.
|
|
//
|
|
|
|
if( admCom != NULL ) {
|
|
|
|
result = MdReleaseAdminObject( admCom );
|
|
TEST_HRESULT( "MdReleaseAdminObject()", result, FALSE );
|
|
|
|
}
|
|
|
|
//
|
|
// Shutdown COM.
|
|
//
|
|
|
|
CoUninitialize();
|
|
return 0;
|
|
|
|
} // main
|
|
|
|
|
|
//
|
|
// Private functions.
|
|
//
|
|
|
|
VOID
|
|
DumpTree(
|
|
IMSAdminBase * AdmCom,
|
|
PENUM_CONTEXT Context
|
|
)
|
|
{
|
|
|
|
HRESULT result;
|
|
METADATA_GETALL_RECORD * data;
|
|
METADATA_GETALL_RECORD * scan;
|
|
DWORD numEntries;
|
|
INT pathLen;
|
|
LPWSTR leaf;
|
|
|
|
result = MdGetAllMetaData(
|
|
AdmCom,
|
|
METADATA_MASTER_ROOT_HANDLE,
|
|
Context->Path,
|
|
0,
|
|
&data,
|
|
&numEntries
|
|
);
|
|
|
|
if( FAILED(result) ) {
|
|
|
|
wprintf(
|
|
L"Cannot get metadata for %s, error %lx\n",
|
|
Context->Path,
|
|
result
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if( numEntries > 0 ) {
|
|
wprintf( L"%s\n", Context->Path );
|
|
}
|
|
|
|
pathLen = wcslen( Context->Path );
|
|
|
|
for( scan = data ; numEntries > 0 ; numEntries--, scan++ ) {
|
|
|
|
wprintf( L"%*cIdentifier = %lu\n", pathLen, ' ', scan->dwMDIdentifier );
|
|
wprintf( L"%*cAttributes = %08lx\n", pathLen, ' ', scan->dwMDAttributes );
|
|
wprintf( L"%*cUserType = %lu\n", pathLen, ' ', scan->dwMDUserType );
|
|
wprintf( L"%*cDataType = %lu\n", pathLen, ' ', scan->dwMDDataType );
|
|
wprintf( L"\n" );
|
|
|
|
}
|
|
|
|
MdFreeMetaDataBuffer( (VOID *)data );
|
|
|
|
leaf = Context->Leaf;
|
|
Context->Leaf = Context->Path + wcslen( Context->Path );
|
|
|
|
result = MdEnumMetaObjects(
|
|
AdmCom,
|
|
Context->Path,
|
|
&EnumCallback,
|
|
(VOID *)Context
|
|
);
|
|
|
|
Context->Leaf = leaf;
|
|
|
|
if( FAILED(result) ) {
|
|
|
|
wprintf(
|
|
L"Cannot enumerate meta objects, error %lx\n",
|
|
result
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} // DumpTree
|
|
|
|
BOOL
|
|
WINAPI
|
|
EnumCallback(
|
|
IMSAdminBase * AdmCom,
|
|
LPWSTR ObjectName,
|
|
VOID * Context
|
|
)
|
|
{
|
|
|
|
PENUM_CONTEXT context;
|
|
LPWSTR leaf;
|
|
|
|
if( *ObjectName != '\0' ) {
|
|
|
|
context = (PENUM_CONTEXT)Context;
|
|
|
|
leaf = context->Leaf;
|
|
if( leaf > ( context->Path + 1 ) ) {
|
|
*leaf++ = L'/';
|
|
}
|
|
|
|
wcscpy(
|
|
leaf,
|
|
ObjectName
|
|
);
|
|
|
|
DumpTree(
|
|
AdmCom,
|
|
context
|
|
);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // EnumCallback
|
|
|