2025-11-28 00:35:46 +09:00

321 lines
9.5 KiB
C++

//-----------------------------------------------------------------------
// This file is part of the Windows SDK Code Samples.
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// This source code is intended only as a supplement to Microsoft
// Development Tools and/or on-line documentation. See these other
// materials for detailed information regarding Microsoft code samples.
//
// THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//-----------------------------------------------------------------------
#include <ole2.h>
#include <xmllite.h>
#include <stdio.h>
#pragma warning(disable : 4127) // conditional expression is constant
#define CHKHR(stmt) do { hr = (stmt); if (FAILED(hr)) goto CleanUp; } while(0)
#define HR(stmt) do { hr = (stmt); goto CleanUp; } while(0)
#define SAFE_RELEASE(I) do { if (I){ I->Release(); } I = NULL; } while(0)
//implement filestream that derives from IStream
class FileStream : public IStream
{
FileStream(HANDLE hFile)
{
_refcount = 1;
_hFile = hFile;
}
~FileStream()
{
if (_hFile != INVALID_HANDLE_VALUE)
{
::CloseHandle(_hFile);
}
}
public:
HRESULT static OpenFile(LPCWSTR pName, IStream ** ppStream, bool fWrite)
{
HANDLE hFile = ::CreateFileW(pName, fWrite ? GENERIC_WRITE : GENERIC_READ, FILE_SHARE_READ,
NULL, fWrite ? CREATE_ALWAYS : OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return HRESULT_FROM_WIN32(GetLastError());
*ppStream = new FileStream(hFile);
if(*ppStream == NULL)
CloseHandle(hFile);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void __RPC_FAR *__RPC_FAR *ppvObject)
{
if (!ppvObject)
return E_INVALIDARG;
(*ppvObject) = NULL;
if (iid == __uuidof(IUnknown)
|| iid == __uuidof(IStream)
|| iid == __uuidof(ISequentialStream))
{
*ppvObject = static_cast<IStream*>(this);
AddRef();
return S_OK;
} else
return E_NOINTERFACE;
}
virtual ULONG STDMETHODCALLTYPE AddRef(void)
{
return (ULONG)InterlockedIncrement(&_refcount);
}
virtual ULONG STDMETHODCALLTYPE Release(void)
{
ULONG res = (ULONG) InterlockedDecrement(&_refcount);
if (res == 0)
delete this;
return res;
}
// ISequentialStream Interface
public:
virtual HRESULT STDMETHODCALLTYPE Read(_Out_writes_bytes_to_(cb, *pcbRead) void* pv, _In_ ULONG cb, _Out_opt_ ULONG* pcbRead)
{
BOOL rc = ReadFile(_hFile, pv, cb, pcbRead, NULL);
return (rc) ? S_OK : HRESULT_FROM_WIN32(GetLastError());
}
virtual HRESULT STDMETHODCALLTYPE Write(_In_reads_bytes_(cb) const void* pv, _In_ ULONG cb, _Out_opt_ ULONG* pcbWritten)
{
BOOL rc = WriteFile(_hFile, pv, cb, pcbWritten, NULL);
return rc ? S_OK : HRESULT_FROM_WIN32(GetLastError());
}
// IStream Interface
public:
virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE CopyTo(_In_ IStream*, ULARGE_INTEGER, _Out_opt_ ULARGE_INTEGER*, _Out_opt_ ULARGE_INTEGER*)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Commit(DWORD)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Revert(void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Clone(__RPC__deref_out_opt IStream **)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, DWORD dwOrigin, _Out_opt_ ULARGE_INTEGER* lpNewFilePointer)
{
DWORD dwMoveMethod;
switch(dwOrigin)
{
case STREAM_SEEK_SET:
dwMoveMethod = FILE_BEGIN;
break;
case STREAM_SEEK_CUR:
dwMoveMethod = FILE_CURRENT;
break;
case STREAM_SEEK_END:
dwMoveMethod = FILE_END;
break;
default:
return STG_E_INVALIDFUNCTION;
break;
}
if (SetFilePointerEx(_hFile, liDistanceToMove, (PLARGE_INTEGER) lpNewFilePointer,
dwMoveMethod) == 0)
return HRESULT_FROM_WIN32(GetLastError());
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Stat(__RPC__out STATSTG* pStatstg, DWORD )
{
if (GetFileSizeEx(_hFile, (PLARGE_INTEGER) &pStatstg->cbSize) == 0)
return HRESULT_FROM_WIN32(GetLastError());
return S_OK;
}
private:
HANDLE _hFile;
LONG _refcount;
};
HRESULT WriteAttributes(IXmlReader* pReader)
{
const WCHAR* pwszPrefix;
const WCHAR* pwszLocalName;
const WCHAR* pwszValue;
const WCHAR* pwszNamespaceUri;
HRESULT hr = pReader->MoveToFirstAttribute();
if (S_FALSE == hr)
return hr;
if (S_OK != hr)
{
wprintf(L"\nXmlLite Error: %08.8lx\n", hr);
return hr;
}
if (S_OK == hr)
{
for (;;)
{
if (!pReader->IsDefault())
{
UINT cwchPrefix;
if (FAILED(hr = pReader->GetPrefix(&pwszPrefix, &cwchPrefix)))
{
wprintf(L"Error getting prefix, error is %08.8lx", hr);
return hr;
}
if (FAILED(hr = pReader->GetLocalName(&pwszLocalName, NULL)))
{
wprintf(L"Error, Method: GetLocalName, error is %08.8lx", hr);
return hr;
}
if (FAILED(hr = pReader->GetValue(&pwszValue, NULL)))
{
wprintf(L"Error, Method: GetValue, error is %08.8lx", hr);
return hr;
}
if (cwchPrefix > 0)
wprintf(L"%s:%s=\"%s\" ", pwszPrefix, pwszLocalName, pwszValue);
else
wprintf(L"%s=\"%s\" ", pwszLocalName, pwszValue);
if (FAILED(hr = pReader->GetNamespaceUri(&pwszNamespaceUri, NULL)))
{
wprintf(L"Error, Method: GetNamespaceUri, error is %08.8lx", hr);
return hr;
}
wprintf(L"Namespace=%s\n", pwszNamespaceUri);
}
if (S_OK != pReader->MoveToNextAttribute())
break;
}
}
return hr;
}
int __cdecl wmain(int argc, _In_reads_(argc) WCHAR* argv[])
{
HRESULT hr = S_OK;
IStream *pFileStream = NULL;
IXmlReader *pReader = NULL;
XmlNodeType nodetype;
const WCHAR* pwszPrefix;
const WCHAR* pwszLocalName;
const WCHAR* pwszNamespaceUri;
UINT cwchPrefix;
if (argc != 2)
{
wprintf(L"Usage: XmlLiteNamespaceReader.exe name-of-input-file\n");
return 0;
}
//Open read-only input stream
if (FAILED(hr = FileStream::OpenFile(argv[1], &pFileStream, FALSE)))
{
wprintf(L"Error creating file reader, error is %08.8lx", hr);
HR(hr);
}
if (FAILED(hr = CreateXmlReader(__uuidof(IXmlReader), (void**) &pReader, NULL)))
{
wprintf(L"Error creating xml reader, error is %08.8lx", hr);
HR(hr);
}
if (FAILED(hr = pReader->SetInput(pFileStream)))
{
wprintf(L"Error setting input for reader, error is %08.8lx", hr);
HR(hr);
}
while (true)
{
hr = pReader->Read(&nodetype);
if (S_FALSE == hr)
break;
if (S_OK != hr)
{
wprintf(L"\nXmlLite Error: %08.8lx\n", hr);
HR(hr);
}
switch (nodetype)
{
case XmlNodeType_Element:
if (FAILED(hr = pReader->GetPrefix(&pwszPrefix, &cwchPrefix)))
{
wprintf(L"Error, Method: GetPrefix, error is %08.8lx", hr);
HR(hr);
}
if (FAILED(hr = pReader->GetLocalName(&pwszLocalName, NULL)))
{
wprintf(L"Error, Method: GetLocalName, error is %08.8lx", hr);
HR(hr);
}
if (cwchPrefix > 0)
wprintf(L"%s:%s ", pwszPrefix, pwszLocalName);
else
wprintf(L"%s ", pwszLocalName);
if (FAILED(hr = pReader->GetNamespaceUri(&pwszNamespaceUri, NULL)))
{
wprintf(L"Error, Method: GetNamespaceUri, error is %08.8lx", hr);
HR(hr);
}
wprintf(L"Namespace=%s\n", pwszNamespaceUri);
if (FAILED(hr = WriteAttributes(pReader)))
{
wprintf(L"Error, Method: WriteAttributes, error is %08.8lx", hr);
HR(hr);
}
break;
}
}
wprintf(L"\n");
CleanUp:
SAFE_RELEASE(pFileStream);
SAFE_RELEASE(pReader);
return hr;
}