Source code of Windows XP (NT5)
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.

146 lines
3.6 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. filestream.cpp
  5. Abstract:
  6. Minimal implementation of IStream over a Windows PE/COFF resource.
  7. Author:
  8. Jay Krell (a-JayK) May 2000
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include "CResourceStream.h"
  13. static BOOL CALLBACK
  14. EnumResourcesCallback(
  15. HMODULE hModule, // module handle
  16. PCWSTR lpszType, // resource type
  17. PWSTR lpszName, // resource name
  18. LONG_PTR lParam // application-defined parameter
  19. )
  20. {
  21. PWSTR *pname = reinterpret_cast<PWSTR *>(lParam);
  22. *pname = lpszName;
  23. // we would return FALSE here to stop enumerating, but
  24. // that causes an overall FALSE from the API (undocumented)
  25. return TRUE;
  26. }
  27. BOOL
  28. CResourceStream::Initialize(
  29. PCWSTR file,
  30. PCWSTR type
  31. )
  32. {
  33. BOOL fSuccess = FALSE;
  34. FN_TRACE_WIN32(fSuccess);
  35. PWSTR name = NULL;
  36. IFW32FALSE_EXIT(m_buffFilePath.Win32Assign(file, (file != NULL) ? ::wcslen(file) : 0));
  37. IFW32FALSE_EXIT(m_dll.Win32LoadLibrary(file, LOAD_LIBRARY_AS_DATAFILE));
  38. IFW32FALSE_ORIGINATE_AND_EXIT(::EnumResourceNamesW(m_dll, type, EnumResourcesCallback, reinterpret_cast<LONG_PTR>(&name)));
  39. IFW32FALSE_EXIT(this->InitializeAlreadyOpen(type, name));
  40. fSuccess = TRUE;
  41. Exit:
  42. return fSuccess;
  43. }
  44. BOOL
  45. CResourceStream::Initialize(
  46. PCWSTR file,
  47. PCWSTR type,
  48. PCWSTR name,
  49. WORD language
  50. )
  51. {
  52. BOOL fSuccess = FALSE;
  53. FN_TRACE_WIN32(fSuccess);
  54. IFW32FALSE_EXIT(m_buffFilePath.Win32Assign(file, (file != NULL) ? ::wcslen(file) : 0));
  55. IFW32FALSE_EXIT(m_dll.Win32LoadLibrary(file, LOAD_LIBRARY_AS_DATAFILE));
  56. IFW32FALSE_EXIT(this->InitializeAlreadyOpen(type, name, language));
  57. fSuccess = TRUE;
  58. Exit:
  59. return fSuccess;
  60. }
  61. BOOL
  62. CResourceStream::InitializeAlreadyOpen(
  63. PCWSTR type,
  64. PCWSTR name,
  65. WORD language
  66. )
  67. {
  68. BOOL fSuccess = FALSE;
  69. FN_TRACE_WIN32(fSuccess);
  70. HRSRC resource;
  71. HGLOBAL global;
  72. const BYTE *pointer;
  73. DWORD size;
  74. IFW32NULL_EXIT(resource = ::FindResourceExW(m_dll, type, name, language));
  75. IFW32NULL_EXIT(global = ::LoadResource(m_dll, resource));
  76. IFW32NULL_EXIT(pointer = reinterpret_cast<const BYTE *>(::LockResource(global)));
  77. IFW32ZERO_EXIT(size = ::SizeofResource(m_dll, resource));
  78. IFW32FALSE_EXIT(Base::Initialize(pointer, pointer + size));
  79. fSuccess = TRUE;
  80. Exit:
  81. return fSuccess;
  82. }
  83. HRESULT
  84. CResourceStream::Stat(
  85. STATSTG *pstatstg,
  86. DWORD grfStatFlag
  87. )
  88. {
  89. HRESULT hr = E_UNEXPECTED;
  90. FN_TRACE_HR(hr);
  91. WIN32_FILE_ATTRIBUTE_DATA wfad;
  92. if (pstatstg != NULL)
  93. memset(pstatstg, 0, sizeof(*pstatstg));
  94. PARAMETER_CHECK(((grfStatFlag & ~(STATFLAG_NONAME)) == 0));
  95. PARAMETER_CHECK(pstatstg != NULL);
  96. if (!(grfStatFlag & STATFLAG_NONAME))
  97. {
  98. ::FusionpDbgPrintEx(
  99. FUSION_DBG_LEVEL_ERROR,
  100. "SXS.DLL: %s() does not handle STATFLAG_NONE; returning E_NOTIMPL.\n", __FUNCTION__);
  101. hr = E_NOTIMPL;
  102. goto Exit;
  103. }
  104. IFW32FALSE_ORIGINATE_AND_EXIT(::GetFileAttributesExW(m_buffFilePath, GetFileExInfoStandard, &wfad));
  105. pstatstg->pwcsName = NULL;
  106. pstatstg->type = STGTY_STREAM;
  107. pstatstg->cbSize.LowPart = wfad.nFileSizeLow;
  108. pstatstg->cbSize.HighPart = wfad.nFileSizeHigh;
  109. pstatstg->mtime = wfad.ftLastWriteTime;
  110. pstatstg->ctime = wfad.ftCreationTime;
  111. pstatstg->atime = wfad.ftLastAccessTime;
  112. pstatstg->grfMode = STGM_READ | STGM_SHARE_DENY_WRITE;
  113. pstatstg->grfLocksSupported = 0;
  114. pstatstg->clsid = GUID_NULL;
  115. pstatstg->grfStateBits = 0;
  116. pstatstg->reserved = 0;
  117. hr = NOERROR;
  118. Exit:
  119. return hr;
  120. }