The minimum OS for IStream_WriteStr() (vista) not for SHCreateStreamOnFileEx() (xp).
None of the them, the string is stored as a unicode char, but
without the NULL, instead a ENQ (enquiry (5) ) word
it is put in front of string and for example the L"Ana", instead
of 65,0, 110,0, 97,0, 0,0 it is stored 5,0, 65,0, 110,0, 97,0.
I wrote this test program
#define UNICODE
#define COBJMACROS
#include <windows.h>
#include <shlwapi.h>
#include <objidl.h>
#include <wchar.h>
//#include <stdio.h>
#pragma comment(lib,"Shlwapi.lib")
void dump_raw_dataW(void *any_kind, unsigned int size, unsigned int n_columns);
int main(void)
{
wchar_t *s = NULL;
LARGE_INTEGER a = { 0 };
ULARGE_INTEGER b;
HRESULT hr;
IStream *istream = NULL;
hr = SHCreateStreamOnFileEx(L"stream", STGM_READWRITE | STGM_FAILIFTHERE, FILE_ATTRIBUTE_NORMAL, FALSE, NULL, &istream);
if (hr) //file(stream) doesn't exist, create one
{
SHCreateStreamOnFileEx(L"stream", STGM_READWRITE | STGM_CREATE, FILE_ATTRIBUTE_NORMAL, FALSE, NULL, &istream);
}
else //use the existing one
{
IStream_Seek(istream, a, STREAM_SEEK_END, &b);
}
IStream_WriteStr(istream, L"test0");
IStream_WriteStr(istream, L"test1");
IStream_WriteStr(istream, L"test2");
IStream_WriteStr(istream, L"test3");
IStream_WriteStr(istream, L"test4");
IStream_Seek(istream, a, STREAM_SEEK_SET, &b);
while (IStream_ReadStr(istream, &s) == S_OK)
wprintf(L"%ls\n", s);
{ //dump the content of stream (a copy) to console
wprintf(L"%\n\n");
unsigned start /*of stream */ ;
unsigned end /*of stream */ ;
IStream_Seek(istream, a, STREAM_SEEK_SET, &b);
start = b.QuadPart;
IStream_Seek(istream, a, STREAM_SEEK_END, &b);
end = b.QuadPart;
size_t size = end - start;
BYTE *content = malloc(size);
if (content)
{
ULONG pcbRead;
IStream_Seek(istream, a, STREAM_SEEK_SET, &b);
if (SUCCEEDED(istream->lpVtbl->Read(istream, content, size, &pcbRead)))
{
dump_raw_dataW(content, size, 12);
wprintf(L"%\n\n");
}
free(content);
}
}
IStream_Release(istream);
return 0;
}
void dump_raw_dataW(void *any_kind, unsigned int size, unsigned int n_columns)
{
if (!any_kind || !size)
return;
unsigned char *p = any_kind, c;
long i, h, t, j, k, i_col, n = size, n_ = n - 1, col = n_columns ? n_columns : 16, stop = 1;
for (i = 0; stop; i += col)
{
wprintf(L" %.8x ", i);
i_col = i + col;
j = 0;
for (h = i; h < i_col; h++)
{
c = p[h];
wprintf(L"%.2x ", c);
j++;
if (h == n_)
{
stop = 0;
break;
}
}
k = col - j;
if (k != 0 && n > col)
{
for (int m = 0; m < k; m++)
wprintf(L" ");
}
wprintf(L" ");
for (t = i; t < i_col; t++)
{
c = p[t];
if (c >= 32 && c < 127)
wprintf(L"%c", c);
else
wprintf(L".");
if (t == n_)
break;
}
wprintf(L"\n");
}
}
but you shouldn't be able to run on your machines so here is
the binary dump after 3 runs.
test0
test1
test2
test3
test4
test0
test1
test2
test3
test4
test0
test1
test2
test3
test4
00000000 05 00 74 00 65 00 73 00 74 00 30 00 05 00 74 00 ..t.e.s.t.0...t.
00000010 65 00 73 00 74 00 31 00 05 00 74 00 65 00 73 00 e.s.t.1...t.e.s.
00000020 74 00 32 00 05 00 74 00 65 00 73 00 74 00 33 00 t.2...t.e.s.t.3.
00000030 05 00 74 00 65 00 73 00 74 00 34 00 05 00 74 00 ..t.e.s.t.4...t.
00000040 65 00 73 00 74 00 30 00 05 00 74 00 65 00 73 00 e.s.t.0...t.e.s.
00000050 74 00 31 00 05 00 74 00 65 00 73 00 74 00 32 00 t.1...t.e.s.t.2.
00000060 05 00 74 00 65 00 73 00 74 00 33 00 05 00 74 00 ..t.e.s.t.3...t.
00000070 65 00 73 00 74 00 34 00 05 00 74 00 65 00 73 00 e.s.t.4...t.e.s.
00000080 74 00 30 00 05 00 74 00 65 00 73 00 74 00 31 00 t.0...t.e.s.t.1.
00000090 05 00 74 00 65 00 73 00 74 00 32 00 05 00 74 00 ..t.e.s.t.2...t.
000000a0 65 00 73 00 74 00 33 00 05 00 74 00 65 00 73 00 e.s.t.3...t.e.s.
000000b0 74 00 34 00 t.4.
Laur