windows-nt/Source/XPSP1/NT/base/win32/fusion/sxs/cresourcestream.cpp

147 lines
3.6 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
filestream.cpp
Abstract:
Minimal implementation of IStream over a Windows PE/COFF resource.
Author:
Jay Krell (a-JayK) May 2000
Revision History:
--*/
#include "stdinc.h"
#include "CResourceStream.h"
static BOOL CALLBACK
EnumResourcesCallback(
HMODULE hModule, // module handle
PCWSTR lpszType, // resource type
PWSTR lpszName, // resource name
LONG_PTR lParam // application-defined parameter
)
{
PWSTR *pname = reinterpret_cast<PWSTR *>(lParam);
*pname = lpszName;
// we would return FALSE here to stop enumerating, but
// that causes an overall FALSE from the API (undocumented)
return TRUE;
}
BOOL
CResourceStream::Initialize(
PCWSTR file,
PCWSTR type
)
{
BOOL fSuccess = FALSE;
FN_TRACE_WIN32(fSuccess);
PWSTR name = NULL;
IFW32FALSE_EXIT(m_buffFilePath.Win32Assign(file, (file != NULL) ? ::wcslen(file) : 0));
IFW32FALSE_EXIT(m_dll.Win32LoadLibrary(file, LOAD_LIBRARY_AS_DATAFILE));
IFW32FALSE_ORIGINATE_AND_EXIT(::EnumResourceNamesW(m_dll, type, EnumResourcesCallback, reinterpret_cast<LONG_PTR>(&name)));
IFW32FALSE_EXIT(this->InitializeAlreadyOpen(type, name));
fSuccess = TRUE;
Exit:
return fSuccess;
}
BOOL
CResourceStream::Initialize(
PCWSTR file,
PCWSTR type,
PCWSTR name,
WORD language
)
{
BOOL fSuccess = FALSE;
FN_TRACE_WIN32(fSuccess);
IFW32FALSE_EXIT(m_buffFilePath.Win32Assign(file, (file != NULL) ? ::wcslen(file) : 0));
IFW32FALSE_EXIT(m_dll.Win32LoadLibrary(file, LOAD_LIBRARY_AS_DATAFILE));
IFW32FALSE_EXIT(this->InitializeAlreadyOpen(type, name, language));
fSuccess = TRUE;
Exit:
return fSuccess;
}
BOOL
CResourceStream::InitializeAlreadyOpen(
PCWSTR type,
PCWSTR name,
WORD language
)
{
BOOL fSuccess = FALSE;
FN_TRACE_WIN32(fSuccess);
HRSRC resource;
HGLOBAL global;
const BYTE *pointer;
DWORD size;
IFW32NULL_EXIT(resource = ::FindResourceExW(m_dll, type, name, language));
IFW32NULL_EXIT(global = ::LoadResource(m_dll, resource));
IFW32NULL_EXIT(pointer = reinterpret_cast<const BYTE *>(::LockResource(global)));
IFW32ZERO_EXIT(size = ::SizeofResource(m_dll, resource));
IFW32FALSE_EXIT(Base::Initialize(pointer, pointer + size));
fSuccess = TRUE;
Exit:
return fSuccess;
}
HRESULT
CResourceStream::Stat(
STATSTG *pstatstg,
DWORD grfStatFlag
)
{
HRESULT hr = E_UNEXPECTED;
FN_TRACE_HR(hr);
WIN32_FILE_ATTRIBUTE_DATA wfad;
if (pstatstg != NULL)
memset(pstatstg, 0, sizeof(*pstatstg));
PARAMETER_CHECK(((grfStatFlag & ~(STATFLAG_NONAME)) == 0));
PARAMETER_CHECK(pstatstg != NULL);
if (!(grfStatFlag & STATFLAG_NONAME))
{
::FusionpDbgPrintEx(
FUSION_DBG_LEVEL_ERROR,
"SXS.DLL: %s() does not handle STATFLAG_NONE; returning E_NOTIMPL.\n", __FUNCTION__);
hr = E_NOTIMPL;
goto Exit;
}
IFW32FALSE_ORIGINATE_AND_EXIT(::GetFileAttributesExW(m_buffFilePath, GetFileExInfoStandard, &wfad));
pstatstg->pwcsName = NULL;
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize.LowPart = wfad.nFileSizeLow;
pstatstg->cbSize.HighPart = wfad.nFileSizeHigh;
pstatstg->mtime = wfad.ftLastWriteTime;
pstatstg->ctime = wfad.ftCreationTime;
pstatstg->atime = wfad.ftLastAccessTime;
pstatstg->grfMode = STGM_READ | STGM_SHARE_DENY_WRITE;
pstatstg->grfLocksSupported = 0;
pstatstg->clsid = GUID_NULL;
pstatstg->grfStateBits = 0;
pstatstg->reserved = 0;
hr = NOERROR;
Exit:
return hr;
}