Leaked source code of windows server 2003
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.

163 lines
4.2 KiB

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