Thank you for reaching out. Please find the answer below.
You're using CreateStreamOnHGlobal(NULL, TRUE, &pStream)
on the client (Windows 11 24H2) to create an in-memory stream. When this stream is passed to a server (Windows Server 2022), the server tries to seek to the beginning of the stream using:
LARGE_INTEGER lZero = {};
ULARGE_INTEGER lPos;
HRESULT hr = pStream->Seek(lZero, STREAM_SEEK_SET, &lPos);
But this call fails with E_ACCESSDENIED
. This issue does not occur when the client is running Windows 11 23H2.
Why This Happens
CreateStreamOnHGlobal
creates a stream backed by global memory. When passed across processes or machines (e.g., via COM or RPC), the memory handle may not be valid or accessible on the receiving side. Windows 11 24H2 likely introduced stricter security or marshalling behavior, causing the stream to become inaccessible on the server.
Recommended Solution
Instead of using a memory-backed stream, use a file-backed stream. This is more reliable across process and machine boundaries.
Working Example Using SHCreateStreamOnFileEx
#include <windows.h>
#include <shlwapi.h>
#include <shlobj.h>
#include <atlbase.h> // For CComPtr
#pragma comment(lib, "shlwapi.lib")
int main() {
CComPtr<IStream> pStream;
// Create a file-backed stream
HRESULT hr = SHCreateStreamOnFileEx(
L"temp_stream.bin", // File name
STGM_CREATE | STGM_READWRITE, // Create and allow read/write
FILE_ATTRIBUTE_NORMAL, // File attributes
TRUE, // Create file if it doesn't exist
nullptr, // No template stream
&pStream // Output stream
);
if (SUCCEEDED(hr)) {
// Write data to the stream
const char* data = "Hello, stream!";
ULONG written = 0;
pStream->Write(data, (ULONG)strlen(data), &written);
// Seek back to the beginning
LARGE_INTEGER liZero = {};
ULARGE_INTEGER newPos;
hr = pStream->Seek(liZero, STREAM_SEEK_SET, &newPos);
if (SUCCEEDED(hr)) {
char buffer[64] = {};
ULONG read = 0;
pStream->Read(buffer, written, &read);
MessageBoxA(NULL, buffer, "Read from Stream", MB_OK);
}
}
return 0;
}
This example creates a file-backed stream, writes data to it, seeks to the beginning, and reads it back. It avoids the E_ACCESSDENIED
issue and works reliably across client-server boundaries.
Let us know if the issue persists after following these steps. We’ll be happy to assist further if needed.