diff options
Diffstat (limited to 'private/ole32/stg/fsstg/utest/fstest.cxx')
-rw-r--r-- | private/ole32/stg/fsstg/utest/fstest.cxx | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/private/ole32/stg/fsstg/utest/fstest.cxx b/private/ole32/stg/fsstg/utest/fstest.cxx new file mode 100644 index 000000000..cb637b1d1 --- /dev/null +++ b/private/ole32/stg/fsstg/utest/fstest.cxx @@ -0,0 +1,465 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1993. +// +// File: fstest.cxx +// +// History: 30-Jun-93 DrewB Created +// 1-Jun-94 BillMo Changed share mode for MoveElementTo +// Added test for: +// Cross volume copy with id +// Cross volume move with id +// +//---------------------------------------------------------------------------- + +#include "pch.cxx" +#pragma hdrstop + +void EndTest(int rc) +{ + if (rc == 0) + printf("Test SUCCEEDED\n"); + else + printf("Test FAILED\n"); + CoUninitialize(); + exit(rc); +} + +void PrintStat(STATSTG *pstat, BOOL fEnum) +{ + printf("%s: '%ws'\n", pstat->type == STGTY_STORAGE ? "Storage" : "Stream", + pstat->pwcsName); + printf("Type: %lu, %lu\n", pstat->type, pstat->dwStgFmt); + if (!fEnum) + printf("Mode: %lX\n", pstat->grfMode); + if (pstat->type == STGTY_STREAM) + { + printf("Size: %lu:%lu\n", pstat->cbSize.HighPart, + pstat->cbSize.LowPart); + if (!fEnum) + printf("Locks: %lX\n", pstat->grfLocksSupported); + } + else + { + if (pstat->ctime.dwHighDateTime != 0 || + pstat->ctime.dwLowDateTime != 0) + printf("Ctime: %s\n", FileTimeText(&pstat->ctime)); + if (pstat->mtime.dwHighDateTime != 0 || + pstat->mtime.dwLowDateTime != 0) + printf("Mtime: %s\n", FileTimeText(&pstat->mtime)); + if (pstat->atime.dwHighDateTime != 0 || + pstat->atime.dwLowDateTime != 0) + printf("Atime: %s\n", FileTimeText(&pstat->atime)); + } + if (!fEnum) + printf("Clsid: %s\n", GuidText(&pstat->clsid)); +} + +void t_enum(IStorage *pstg) +{ + IEnumSTATSTG *penm, *penm2; + STATSTG stat; + HRESULT hr; + + hr = pstg->EnumElements(0, 0, 0, &penm); + Result(hr, "Enum"); + + for (;;) + { + hr = penm->Next(1, &stat, NULL); + Result(hr, "Next"); + if (GetScode(hr) == S_FALSE) + break; + + PrintStat(&stat, TRUE); + CoMemFree(stat.pwcsName); + } + + hr = penm->Skip(1); + Result(hr, "Skip"); + hr = penm->Reset(); + Result(hr, "Reset"); + hr = penm->Clone(&penm2); + Result(hr, "Clone"); + + penm2->Release(); + penm->Release(); +} + +void t_dirstg(IStorage *pstg) +{ + HRESULT hr; + IStream *pstm; + STATSTG stat; + IStorage *pstg2, *pstg3; + WCHAR wfn[MAX_PATH]; + SYSTEMTIME stm; + FILETIME ftm; + + hr = pstg->Stat(&stat, 0); + Result(hr, "Stat"); + PrintStat(&stat, FALSE); + CoMemFree(stat.pwcsName); + + hr = pstg->CreateStream(L"Stream", STGM_READWRITE, 0, 0, &pstm); + if (hr != STG_E_INVALIDFUNCTION) + Fail("CreateStream returned %lX\n", hr); + hr = pstg->OpenStream(L"Stream", 0, STGM_READWRITE, 0, &pstm); + if (hr != STG_E_FILENOTFOUND) + Fail("OpenStream returned %lX\n", hr); + + hr = pstg->CreateStorage(L"file!", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, + STGFMT_FILE, NULL, &pstg2); + Result(hr, "Create file 'file!'"); + pstg2->Release(); + hr = pstg->CreateStorage(L"docfile", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, + STGFMT_DOCUMENT, NULL, &pstg2); + Result(hr, "Create document"); + pstg2->Release(); + hr = pstg->CreateStorage(L"dir", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, + STGFMT_DIRECTORY, NULL, &pstg2); + Result(hr, "Create directory"); + pstg2->Release(); + + hr = pstg->Commit(0); + Result(hr, "Commit"); + hr = pstg->Revert(); + Result(hr, "Revert"); + + t_enum(pstg); + + hr = pstg->OpenStorage(L"file!", NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, + NULL, &pstg2); + Result(hr, "Open file 'file!'"); + pstg2->Release(); + hr = pstg->OpenStorage(L"docfile", NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, + NULL, &pstg2); + Result(hr, "Open docfile"); + pstg2->Release(); + hr = pstg->OpenStorage(L"dir", NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, + NULL, &pstg2); + Result(hr, "Open directory"); + hr = pstg2->CreateStorage(L"child", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, + STGFMT_DIRECTORY, NULL, &pstg3); + Result(hr, "Create child directory"); + pstg3->Release(); + pstg2->Release(); + + TestFile(wfn, "stg2"); + hr = StgCreateStorage(wfn, STGM_READWRITE, + /* BUGBUG: review. Took off share exclusive */ + /* for MoveElementTo | STGM_SHARE_EXCLUSIVE */ + STGFMT_DIRECTORY, NULL, &pstg2); + Result(hr, "Create sibling dir"); + hr = pstg->CopyTo(0, NULL, NULL, pstg2); + Result(hr, "CopyTo"); + t_enum(pstg2); + + hr = pstg2->DestroyElement(L"dir"); + Result(hr, "Destroy dest dir -- contains child"); + hr = pstg->MoveElementTo(L"dir", pstg2, L"dest", STGMOVE_MOVE); + Result(hr, "MoveElementTo"); + t_enum(pstg2); + pstg2->Release(); + + char *pszOtherDrive = getenv("FSTEST_OTHER"); + if (pszOtherDrive) + { + WCHAR wszBuf[16]; + mbstowcs(wszBuf, pszOtherDrive, 1); + wcscpy(wszBuf+1, ":\\"); + hr = StgOpenStorage(wszBuf, STGM_READWRITE, STGMFT_DIRECTORY, NULL, NULL, &pstg3); + hr = pstg2->MoveElementTo(L"dest", pstg3, L"new"); + } + else + { + printf("Skipping cross volume move test because FSTEST_OTHER not defined\n"); + } + hr = pstg->OpenStorage(L"dir", NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, + NULL, &pstg2); + if (hr != STG_E_FILENOTFOUND) + Fail("Opened non-existent storage, %lX\n", hr); + + hr = pstg->RenameElement(L"docfile", L"stg3"); + Result(hr, "RenameElement"); + hr = pstg->DestroyElement(L"stg3"); + Result(hr, "DestroyElement"); + t_enum(pstg); + + Sleep(3); + GetLocalTime(&stm); + SystemTimeToFileTime(&stm, &ftm); + printf("Set time to %s\n", FileTimeText(&ftm)); + hr = pstg->SetElementTimes(L"file!", NULL, NULL, &ftm); + Result(hr, "SetElementTimes"); + t_enum(pstg); + + hr = pstg->SetClass(IID_IStorage); + if (hr != STG_E_INVALIDFUNCTION) + Fail("SetClass returned %lX\n", hr); + hr = pstg->SetStateBits(0xffffffff, 0xf0f0f0f0); + if (hr != STG_E_INVALIDFUNCTION) + Fail("SetStateBits returned %lX\n", hr); +} + +void t_filstg(IStorage *pstg) +{ + HRESULT hr; + STATSTG stat; + IStream *pstm; + IStorage *pstg2; + WCHAR wfn[MAX_PATH]; + + hr = pstg->Stat(&stat, 0); + Result(hr, "Stat"); + PrintStat(&stat, FALSE); + CoMemFree(stat.pwcsName); + + hr = pstg->CreateStream(L"Stream", STGM_READWRITE, 0, 0, &pstm); + if (hr != STG_E_INVALIDFUNCTION) + Fail("CreateStream succeeded for non-CONTENTS %lX\n", hr); + hr = pstg->OpenStream(L"Stream", 0, STGM_READWRITE, 0, &pstm); + if (hr != STG_E_FILENOTFOUND) + Fail("OpenStream succeeded for non-CONTENTS %lX\n", hr); + + hr = pstg->CreateStorage(L"file", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, + STGFMT_FILE, NULL, &pstg2); + if (hr != STG_E_INVALIDFUNCTION) + Fail("CreateStorage succeeded %lX\n", hr); + hr = pstg->OpenStorage(L"file", NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, + NULL, &pstg2); + if (hr != STG_E_FILENOTFOUND) + Fail("OpenStorage succeeded %lX\n", hr); + + hr = pstg->Commit(0); + Result(hr, "Commit"); + hr = pstg->Revert(); + Result(hr, "Revert"); + + t_enum(pstg); + + TestFile(wfn, "stg3"); + hr = StgCreateStorage(wfn, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, + STGFMT_DOCUMENT, NULL, &pstg2); + Result(hr, "Open target docfile"); + hr = pstg->CopyTo(0, NULL, NULL, pstg2); + Result(hr, "CopyTo"); + t_enum(pstg2); + + hr = pstg2->DestroyElement(L"CONTENTS"); + Result(hr, "Destroy dest CONTENTS"); + hr = pstg->MoveElementTo(L"CONTENTS", pstg2, L"dest", STGMOVE_COPY); + Result(hr, "MoveElementTo"); + t_enum(pstg2); + pstg2->Release(); + + hr = pstg->RenameElement(L"stg2", L"stg3"); + if (hr != STG_E_FILENOTFOUND) + Fail("RenameElement returned %lX\n", hr); + hr = pstg->DestroyElement(L"stg3"); + if (hr != STG_E_FILENOTFOUND) + Fail("DestroyElement returned %lX\n", hr); + hr = pstg->SetElementTimes(L"file", NULL, NULL, NULL); + if (hr != STG_E_FILENOTFOUND) + Fail("SetElementTimes returned %lX\n", hr); + hr = pstg->SetClass(CLSID_NULL); + if (hr != STG_E_INVALIDFUNCTION) + Fail("SetClass returned %lX\n", hr); + hr = pstg->SetStateBits(0, 0); + if (hr != STG_E_INVALIDFUNCTION) + Fail("SetStateBits returned %lX\n", hr); +} + +static char NUMBERS[] = "12345678901234567890123456789012345678901234567890"; + +void t_stream(IStream *pstm) +{ + IStream *pstmC; + char buf[sizeof(NUMBERS)*2]; + ULONG cb; + HRESULT hr; + ULARGE_INTEGER ulPos, uli; + LARGE_INTEGER li; + STATSTG stat; + + hr = pstm->Stat(&stat, 0); + Result(hr, "Stat"); + PrintStat(&stat, FALSE); + CoMemFree(stat.pwcsName); + + uli.HighPart = 0; + uli.LowPart = 0; + hr = pstm->SetSize(uli); + Result(hr, "SetSize"); + + hr = pstm->Write(NUMBERS, sizeof(NUMBERS), &cb); + Result(hr, "Write"); + hr = pstm->Commit(0); + Result(hr, "Commit"); + hr = pstm->Revert(); + Result(hr, "Revert"); + + li.HighPart = -1; + li.LowPart = (ULONG)(-((LONG)sizeof(NUMBERS)/2)); + hr = pstm->Seek(li, STREAM_SEEK_END, &ulPos); + Result(hr, "Seek"); + if (ulPos.HighPart != 0 || + ulPos.LowPart != sizeof(NUMBERS)-sizeof(NUMBERS)/2) + Fail("Incorrect seek, %lu:%lu\n", ulPos.HighPart, ulPos.LowPart); + + li.HighPart = 0; + li.LowPart = sizeof(NUMBERS)/2; + hr = pstm->Seek(li, STREAM_SEEK_CUR, &ulPos); + Result(hr, "Seek"); + if (ulPos.HighPart != 0 || + ulPos.LowPart != sizeof(NUMBERS)) + Fail("Incorrect seek, %lu:%lu\n", ulPos.HighPart, ulPos.LowPart); + + li.HighPart = li.LowPart = 0; + hr = pstm->Seek(li, STREAM_SEEK_SET, &ulPos); + Result(hr, "Seek"); + if (ulPos.LowPart != 0 || ulPos.HighPart != 0) + Fail("Incorrect seek, %lu:%lu\n", ulPos.HighPart, ulPos.LowPart); + + hr = pstm->Read(buf, sizeof(NUMBERS), &cb); + Result(hr, "Read"); + if (strcmp(buf, NUMBERS)) + Fail("Incorrect stream contents\n"); + + uli.HighPart = 0; + uli.LowPart = sizeof(NUMBERS)/2; + hr = pstm->SetSize(uli); + Result(hr, "SetSize"); + hr = pstm->Seek(li, STREAM_SEEK_SET, NULL); + Result(hr, "Seek"); + hr = pstm->Read(buf, sizeof(NUMBERS), &cb); + Result(hr, "Read"); + if (cb != sizeof(NUMBERS)/2) + Fail("SetSize failed to size stream properly\n"); + if (memcmp(buf, NUMBERS, sizeof(NUMBERS)/2)) + Fail("SetSize corrupted contents\n"); + + hr = pstm->Clone(&pstmC); + Result(hr, "Clone"); + hr = pstm->Seek(li, STREAM_SEEK_SET, NULL); + Result(hr, "Seek"); + hr = pstm->CopyTo(pstmC, uli, NULL, NULL); + Result(hr, "CopyTo"); + hr = pstm->Seek(li, STREAM_SEEK_SET, NULL); + Result(hr, "Seek"); + uli.LowPart = sizeof(NUMBERS) & ~1; + hr = pstm->CopyTo(pstmC, uli, NULL, NULL); + Result(hr, "CopyTo"); + hr = pstm->Seek(li, STREAM_SEEK_SET, NULL); + Result(hr, "Seek"); + hr = pstm->Read(buf, (sizeof(NUMBERS)&~1)*2, &cb); + Result(hr, "Read"); + if (memcmp(buf, NUMBERS, sizeof(NUMBERS)/2) || + memcmp(buf+sizeof(NUMBERS)/2, NUMBERS, sizeof(NUMBERS)/2) || + memcmp(buf+(sizeof(NUMBERS)&~1), NUMBERS, sizeof(NUMBERS)/2) || + memcmp(buf+3*(sizeof(NUMBERS)/2), NUMBERS, sizeof(NUMBERS)/2)) + Fail("Stream contents incorrect\n"); + pstmC->Release(); + + ulPos.HighPart = 0xffffffff; + ulPos.LowPart = 0x10000; + uli.HighPart = 0; + uli.LowPart = 0x100; + hr = pstm->LockRegion(ulPos, uli, LOCK_ONLYONCE); + Result(hr, "LockRegion"); + ulPos.LowPart = 0x10080; + hr = pstm->LockRegion(ulPos, uli, LOCK_ONLYONCE); + if (hr != STG_E_LOCKVIOLATION) + Fail("Illegal LockRegion returned 0x%lX\n", hr); + ulPos.LowPart = 0x10000; + hr = pstm->UnlockRegion(ulPos, uli, LOCK_ONLYONCE); + Result(hr, "UnlockRegion"); +} + +DWORD fmts[] = {STGFMT_DOCUMENT, STGFMT_FILE}; +char *fmt_names[] = {"hdoc", "hfile"}; +#define NFMTS (sizeof(fmts)/sizeof(fmts[0])) + +void _CRTAPI1 main(int argc, char **argv) +{ + IStorage *pstg, *pstgFile; + IStream *pstm; + HRESULT hr; + WCHAR wfn[MAX_PATH]; + +#if WIN32 == 300 + hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); +#else + hr = CoInitialize(NULL); +#endif + Result(hr, "CoInitialize"); + + TestFile(wfn, "stg"); + hr = StgCreateStorage(wfn, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, + STGFMT_DIRECTORY, NULL, &pstg); + Result(hr, "Open root directory"); + + t_dirstg(pstg); + + hr = pstg->CreateStorage(L"file", STGM_READWRITE | STGM_SHARE_EXCLUSIVE | + STGM_CREATE, STGFMT_FILE, NULL, &pstgFile); + Result(hr, "Create file"); + + t_filstg(pstgFile); + + hr = pstgFile->OpenStream(L"CONTENTS", NULL, STGM_READWRITE, + NULL, &pstm); + Result(hr, "Open stream"); + + t_stream(pstm); + + pstm->Release(); + pstgFile->Release(); + pstg->Release(); + + hr = StgOpenStorage(wfn, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, + NULL, NULL, &pstg); + Result(hr, "Open root directory"); + pstg->Release(); + + HANDLE h; + DWORD dwStgFmt, grfMode; + int i; + STATSTG stat; + + grfMode = STGM_READWRITE | STGM_SHARE_EXCLUSIVE; + for (i = 0; i < NFMTS; i++) + { + dwStgFmt = fmts[i]; + TestFile(wfn, fmt_names[i]); + h = CreateFile(wfn, GENERIC_READ | GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE) + Fail("Unable to create file\n"); + hr = StgCreateStorageOnHandle(h, grfMode, dwStgFmt, &pstg); + Result(hr, "StgCreateStorageOnHandle fmt %lu", dwStgFmt); + pstg->Release(); + CloseHandle(h); + + h = CreateFile(wfn, GENERIC_READ | GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE) + Fail("Unable to open file\n"); + hr = StgOpenStorageOnHandle(h, grfMode, &pstg); + Result(hr, "StgOpenStorageOnHandle fmt %lu", dwStgFmt); + pstg->Stat(&stat, STATFLAG_NONAME); + if (stat.dwStgFmt != dwStgFmt) + Fail("Stat returned fmt %lu rather than %lu\n", stat.dwStgFmt, + dwStgFmt); + pstg->Release(); + CloseHandle(h); + } + + EndTest(0); +} |