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.

191 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. mmapstm.c
  5. Abstract:
  6. IStream over a memory-mapped file, derived (in the C++ sense) from
  7. RTL_MEMORY_STREAM. Note the semantics and implementation here
  8. of IStream::Stat are specialized for use by sxs.
  9. Author:
  10. Jay Krell (a-JayK) June 2000
  11. Revision History:
  12. --*/
  13. #include "basesrv.h"
  14. #include "nturtl.h"
  15. #include "mmapstm.h"
  16. // REVIEW
  17. #define BASE_SRV_HRESULT_FROM_STATUS(x) HRESULT_FROM_WIN32(RtlNtStatusToDosErrorNoTeb(x))
  18. //#define BASE_SRV_HRESULT_FROM_STATUS(x) HRESULT_FROM_WIN32(RtlNtStatusToDosError(x))
  19. //#define BASE_SRV_HRESULT_FROM_STATUS(x) HRESULT_FROM_NT(x)
  20. #define DPFLTR_LEVEL_HRESULT(x) (SUCCEEDED(x) ? DPFLTR_TRACE_LEVEL : DPFLTR_ERROR_LEVEL)
  21. #define DPFLTR_LEVEL_STATUS(x) ((NT_SUCCESS(x) || x == STATUS_SXS_CANT_GEN_ACTCTX) ? DPFLTR_TRACE_LEVEL : DPFLTR_ERROR_LEVEL)
  22. const static RTL_STREAM_VTABLE_TEMPLATE(BASE_SRV_MEMORY_MAPPED_STREAM_WITH_VTABLE)
  23. MmapStreamVTable =
  24. {
  25. BaseSrvQueryInterfaceMemoryMappedStream,
  26. BaseSrvAddRefMemoryMappedStream,
  27. BaseSrvReleaseMemoryMappedStream,
  28. BaseSrvReadMemoryMappedStream,
  29. BaseSrvWriteMemoryMappedStream,
  30. BaseSrvSeekMemoryMappedStream,
  31. BaseSrvSetMemoryMappedStreamSize,
  32. BaseSrvCopyMemoryMappedStreamTo,
  33. BaseSrvCommitMemoryMappedStream,
  34. BaseSrvRevertMemoryMappedStream,
  35. BaseSrvLockMemoryMappedStreamRegion,
  36. BaseSrvUnlockMemoryMappedStreamRegion,
  37. BaseSrvStatMemoryMappedStream,
  38. BaseSrvCloneMemoryMappedStream
  39. };
  40. VOID
  41. STDMETHODCALLTYPE
  42. BaseSrvInitMemoryMappedStream(
  43. PBASE_SRV_MEMORY_MAPPED_STREAM_WITH_VTABLE MmapStream
  44. )
  45. {
  46. KdPrintEx((DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() beginning\n", __FUNCTION__));
  47. // call the base class constructor
  48. RtlInitMemoryStream(&MmapStream->MemStream);
  49. // replace the base vtable with our own
  50. MmapStream->MemStream.StreamVTable = (IStreamVtbl*)&MmapStreamVTable;
  51. // replace the virtual destructor with our own
  52. MmapStream->MemStream.Data.FinalRelease = BaseSrvFinalReleaseMemoryMappedStream;
  53. // initialize our extra data
  54. MmapStream->FileHandle = NULL;
  55. KdPrintEx((DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() exiting\n", __FUNCTION__));
  56. }
  57. HRESULT
  58. STDMETHODCALLTYPE
  59. BaseSrvStatMemoryMappedStream(
  60. PBASE_SRV_MEMORY_MAPPED_STREAM_WITH_VTABLE MmapStream,
  61. STATSTG* Stat,
  62. DWORD Flags
  63. )
  64. {
  65. //
  66. // We should be able to merge RTL_FILE_STREAM and RTL_MEMORY_STREAM somehow,
  67. // but RTL_FILE_STREAM so far we aren't using and it doesn't implement Stat, so..
  68. //
  69. NTSTATUS Status = STATUS_SUCCESS;
  70. HRESULT Hr = NOERROR;
  71. FILE_BASIC_INFORMATION FileBasicInfo;
  72. IO_STATUS_BLOCK IoStatusBlock;
  73. KdPrintEx((DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() beginning\n", __FUNCTION__));
  74. if (Stat == NULL) {
  75. // You would expect this to be E_INVALIDARG,
  76. // but IStream docs say to return STG_E_INVALIDPOINTER.
  77. Hr = STG_E_INVALIDPOINTER;
  78. goto Exit;
  79. }
  80. // we don't support returning the string because
  81. // we don't have ole32.dll for CoTaskMem*
  82. Stat->pwcsName = NULL;
  83. ASSERT(Flags & STATFLAG_NONAME);
  84. if (MmapStream->FileHandle != NULL) {
  85. Status = NtQueryInformationFile(
  86. MmapStream->FileHandle,
  87. &IoStatusBlock,
  88. &FileBasicInfo,
  89. sizeof(FileBasicInfo),
  90. FileBasicInformation
  91. );
  92. if (!NT_SUCCESS(Status)) {
  93. Hr = BASE_SRV_HRESULT_FROM_STATUS(Status);
  94. goto Exit;
  95. }
  96. } else {
  97. // NOTE: This is acceptable for the sxs consumer.
  98. // It is not necessarily acceptable to everyone.
  99. // Do not change it without consulting sxs.
  100. RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
  101. }
  102. Stat->type = STGTY_LOCKBYTES;
  103. // NOTE we do not report the size of the file, but the size
  104. // of the mapped view; if we implemented IStream::Stat for RTL_MEMORY_STREAM,
  105. // it would return the same thing here.
  106. // (to get file times and size, use FileNetworkOpenInformation)
  107. Stat->cbSize.QuadPart = (MmapStream->MemStream.Data.End - MmapStream->MemStream.Data.Begin);
  108. Stat->mtime.dwLowDateTime = FileBasicInfo.LastWriteTime.LowPart;
  109. Stat->mtime.dwHighDateTime = FileBasicInfo.LastWriteTime.HighPart;
  110. Stat->ctime.dwLowDateTime = FileBasicInfo.CreationTime.LowPart;
  111. Stat->ctime.dwHighDateTime = FileBasicInfo.CreationTime.HighPart;
  112. Stat->atime.dwLowDateTime = FileBasicInfo.LastAccessTime.LowPart;
  113. Stat->atime.dwHighDateTime = FileBasicInfo.LastAccessTime.HighPart;
  114. // there is FileAccessInformation, but this hardcoding should suffice
  115. Stat->grfMode = STGM_DIRECT | STGM_READ | STGM_SHARE_DENY_WRITE;
  116. Stat->grfLocksSupported = 0;
  117. Stat->clsid = CLSID_NULL;
  118. Stat->grfStateBits = 0;
  119. Stat->reserved = 0;
  120. Hr = NOERROR;
  121. Exit:
  122. #if !DBG
  123. if (DPFLTR_LEVEL_STATUS(Status) == DPFLTR_ERROR_LEVEL)
  124. #endif
  125. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_HRESULT(Hr), "SXS: %s() exiting 0x%08lx\n", __FUNCTION__, Hr);
  126. return Hr;
  127. }
  128. VOID
  129. STDMETHODCALLTYPE
  130. BaseSrvFinalReleaseMemoryMappedStream(
  131. PRTL_MEMORY_STREAM_WITH_VTABLE MemStream
  132. )
  133. {
  134. NTSTATUS Status;
  135. PBASE_SRV_MEMORY_MAPPED_STREAM_WITH_VTABLE MmapStream;
  136. KdPrintEx((DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() beginning\n", __FUNCTION__));
  137. MmapStream = CONTAINING_RECORD(MemStream, BASE_SRV_MEMORY_MAPPED_STREAM_WITH_VTABLE, MemStream);
  138. if (MemStream->Data.Begin != NULL) {
  139. Status = NtUnmapViewOfSection(NtCurrentProcess(), MemStream->Data.Begin);
  140. RTL_SOFT_ASSERT(NT_SUCCESS(Status));
  141. // REVIEW Should we provide RtlFinalReleaseMemoryStream and move these
  142. // lines there?
  143. MemStream->Data.Begin = NULL;
  144. MemStream->Data.End = NULL;
  145. MemStream->Data.Current = NULL;
  146. }
  147. if (MmapStream->FileHandle != NULL) {
  148. Status = NtClose(MmapStream->FileHandle);
  149. RTL_SOFT_ASSERT(NT_SUCCESS(Status));
  150. MmapStream->FileHandle = NULL;
  151. }
  152. // RtlFinalReleaseMemoryStream(MemStream);
  153. KdPrintEx((DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() exiting\n", __FUNCTION__));
  154. }