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.
 
 
 
 
 
 

7335 lines
194 KiB

//-------------------------------------------------------------------------
//
// Microsoft OLE
// Copyright (C) Microsoft Corporation, 1994 - 1995.
//
// File: stmtsts.cxx
//
// Contents: storage base tests basically pertaining to IStream interface
//
// Functions:
//
// History: 28-June-1996 NarindK Created.
// 27-Mar-97 SCousens conversionified
//
//--------------------------------------------------------------------------
#include <dfheader.hxx>
#pragma hdrstop
#include "init.hxx"
// externs
extern BOOL g_fDoLargeSeekAndWrite;
extern BOOL g_fUseStdBlk;
extern USHORT ausSIZE_ARRAY[];
#define SECTORSIZE 512
#define SMALL_OBJ_SIZE 4096
//----------------------------------------------------------------------------
//
// Test: STMTEST_100
//
// Synopsis: Creates a root docfile with a random name.
// Creates an IStream in the root docfile and writes and CRCs a
// random number of bytes then releases the IStream. The root
// is then committed and released. The root docfile and child IStream
// are then instantiated. CRC's are compared to verify.
// A random offset is chosen within the child IStream and a random number
// of bytes are written to the IStream, taking care *NOT* to grow the
// length of the IStream. The IStream and root are then released.
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// History: 28-June-1996 NarindK Created.
//
// New Test Notes:
// 1. Old File: LSCHANGE.CXX
// 2. Old name of test : LegitStreamChange test
// New Name of test : STMTEST_100
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-100
// /dfRootMode:dirReadWriteShEx
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-100
// /dfRootMode:xactReadWriteShEx
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-100
// /dfRootMode:xactReadWriteShDenyW
//
// BUGNOTE: Conversion: STMTEST-100
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_100(int argc, char *argv[])
{
HRESULT hr = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualStmNode *pvsnRootNewChildStream = NULL;
LPTSTR pRootNewChildStmName = NULL;
ULONG cb = 0;
LPTSTR ptcsBuffer = NULL;
ULONG culWritten = 0;
ULONG culRandomPos = 0;
ULONG culRemWritten = 0;
DWORD dwRootMode = 0;
BOOL fPass = TRUE;
LARGE_INTEGER liStreamPos;
ULONG cRandomMinSize = 10;
ULONG cRandomMaxSize = 100;
DWCRCSTM dwMemCRC;
DWCRCSTM dwActCRC;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_100"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_100 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt stream change operations")) );
// Initialize CRC values to zero
dwMemCRC.dwCRCSum = dwActCRC.dwCRCSum = 0;
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_100, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu) ;
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi);
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if(S_OK == hr)
{
// Generate random size for stream.
usErr = pdgi->Generate(&cb, cRandomMinSize, cRandomMaxSize);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName,
cb,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream);
DH_HRCHECK(hr, TEXT("AddStream")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
}
// Call VirtualStmNode::Write to create random bytes in the stream. For
// our test purposes, we generate a random string of size 1 to cb using
// GenerateRandomString function.
if(S_OK == hr)
{
hr = GenerateRandomString(pdgu, cb, cb, &ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
cb,
&culWritten);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
}
// Calculate the CRC for stream name and data
if(S_OK == hr)
{
hr = CalculateInMemoryCRCForStm(
pvsnRootNewChildStream,
ptcsBuffer,
cb,
&dwMemCRC);
DH_HRCHECK(hr, TEXT("CalculateInMemoryCRCForStm")) ;
}
// Release stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful, hr=0x%lx.")));
}
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete ptcsBuffer;
ptcsBuffer = NULL;
}
// Commit root. BUGBUG: Use random modes
if(S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit unsuccessful, hr=0x%lx."),
hr));
}
}
// Release root
if (S_OK == hr)
{
hr = pVirtualDFRoot->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
}
// Open root
if (S_OK == hr)
{
hr = pVirtualDFRoot->OpenRoot(
NULL,
dwRootMode,
NULL,
0);
DH_HRCHECK(hr, TEXT("VirtualCtrNode::Open")) ;
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Open completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Open unsuccessful, hr=0x%lx."),
hr));
}
}
// Open stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Open(
NULL,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE ,
0);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Open")) ;
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Open completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Open unsuccessful,hr=0x%lx."),
hr));
}
}
// Read and verify
if(S_OK == hr)
{
hr = ReadAndCalculateDiskCRCForStm(pvsnRootNewChildStream,&dwActCRC);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("ReadAndCalculateDiskCRCForStm function successful.")));
if(dwActCRC.dwCRCSum == dwMemCRC.dwCRCSum)
{
DH_TRACE((DH_LVL_TRACE1, TEXT("CRC's for pvsnNewChildStream match.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("CRC's for pvsnNewChildStream don't match.")));
fPass = FALSE;
}
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("ReadAndCalculateDiskCRCForStm not successful, hr=0x%lx."),
hr));
}
}
// If it is ok till now, then all the bytes were written correctly into
// stream and read correctly from there, so choose any postion b/w 1 and
// culWritten - number of bytes written and therafter read.
if (S_OK == hr)
{
// Generate random size for stream.
usErr = pdgi->Generate(&culRandomPos, 1, culWritten);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
// Now seek to this position
if(S_OK == hr)
{
LISet32(liStreamPos, culRandomPos);
// Position the stream header to the postion from begining
hr = pvsnRootNewChildStream->Seek(liStreamPos, STREAM_SEEK_SET, NULL);
DH_HRCHECK(hr, TEXT("IStream::Seek")) ;
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Seek function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Seek function wasn't successful, hr=0x%lx."),
hr));
}
}
// Now write into this part of stream with random data w/o growing the
// stream
if(S_OK == hr)
{
hr = GenerateRandomString(
pdgu,
culWritten - culRandomPos,
culWritten - culRandomPos,
&ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
culWritten - culRandomPos,
&culRemWritten);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
}
// Check length of stream not grown if stream written to correctly.
if(S_OK == hr)
{
if(culRemWritten == culWritten - culRandomPos)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Stream data changed okay w/o changing stream len.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Stream data change not okay.")));
fPass = FALSE;
}
}
// Commit root. BUGBUG: Use random modes
if(S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit unsuccessful, hr=0x%lx."),
hr));
}
}
// Release stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful, hr=0x%lx."),
hr));
}
}
// Release root
if (S_OK == hr)
{
hr = pVirtualDFRoot->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
}
// if everything goes well, log test as passed else failed.
if ((S_OK == hr) && (TRUE == fPass))
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_100 passed.")) );
}
else
{
DH_LOG((LOG_FAIL,
TEXT("Test variation STMTEST_100 failed, hr=0x%lx."),
hr) );
// test failed. make it look like it failed.
hr = FirstError (hr, E_FAIL);
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Delete strings
if(NULL != pRootNewChildStmName)
{
delete pRootNewChildStmName;
pRootNewChildStmName = NULL;
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete ptcsBuffer;
ptcsBuffer = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_100 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}
//----------------------------------------------------------------------------
//
// Test: STMTEST_101
//
// Synopsis: The test creates a root docfile and a child IStream. A random
// number of bytes are written to the IStream and then the IStream
// is cloned.
// From 1 to 5 times, either the ORIGINAL or CLONE IStream is
// randomly chosen as the operation target. The current seek
// pointer positions of both IStreams are saved. There is then a
// 33% chance each that the target stream will be used for a
// seek, write, or read operation. Next, the stream that was
// *NOT* the target IStream is seeked upon to determine the
// current pointer position. Verify that the *non target*
// IStream pointer hasn't changed. Repeat.
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// History: 28-June-1996 NarindK Created.
//
// New Test Notes:
// 1. Old File: LSCLONE.CXX
// 2. Old name of test : LegitStreamClone test
// New Name of test : STMTEST_101
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-101
// /dfRootMode:dirReadWriteShEx
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-101
// /dfRootMode:xactReadWriteShEx
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-101
// /dfRootMode:xactReadWriteShDenyW
//
// BUGNOTE: Conversion: STMTEST-101
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_101(int argc, char *argv[])
{
HRESULT hr = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualStmNode *pvsnRootNewChildStream = NULL;
LPTSTR pRootNewChildStmName = NULL;
ULONG cb = 0;
LPTSTR ptcsBuffer = NULL;
ULONG culWritten = 0;
DWORD dwRootMode = 0;
BOOL fPass = TRUE;
BOOL fFindSeekPosition = FALSE;
LARGE_INTEGER liStreamPos;
ULONG culRandIOBytes = 0;
ULONG culBytesLeftToWrite = 0;
LPSTREAM pIStreamClone = NULL;
ULONG ulCurPosition[2];
ULONG ulOldPosition[2];
ULONG culRandomVar = 0;
ULONG culRandomPos = 0;
ULONG culRandomCommit = 0;
ULONG cStreamInUse = 0;
ULONG cStreamNotInUse = 0;
ULONG cOpInUse = 0;
ULONG ulRef = 0;
LPSTREAM pIStream[2];
ULARGE_INTEGER uli;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_101"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_101 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt stream clone operations")) );
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_101, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu);
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi) ;
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if (S_OK == hr)
{
// Generate random size for stream between 4L, and MIN_SIZE * 1.5
// (range taken from old test).
usErr = pdgi->Generate(&cb, 4, (ULONG) (MIN_SIZE * 1.5));
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName,
cb,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream);
DH_HRCHECK(hr, TEXT("AddStream")) ;
if(S_OK == hr)
{
culBytesLeftToWrite = cb;
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
}
// Loop to write new IStream in RAND_IO size chunks unless size
// remaining to write is less than RAND_IO, then write the remaining bytes
while((S_OK == hr) && (0 != culBytesLeftToWrite))
{
if (S_OK == hr)
{
// Generate random number of bytes to write b/w RAND_IO_MIN ,
// RAND_IO_MAX (range taken from old test).
usErr = pdgi->Generate(&culRandIOBytes, RAND_IO_MIN, RAND_IO_MAX);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if(culBytesLeftToWrite > culRandIOBytes)
{
culBytesLeftToWrite = culBytesLeftToWrite - culRandIOBytes;
}
else
{
culRandIOBytes = culBytesLeftToWrite;
culBytesLeftToWrite = 0;
}
// Call VirtualStmNode::Write to create random bytes in the stream. For
// our test purposes, we generate a random string of size 1 to cb using
// GenerateRandomString function.
if(S_OK == hr)
{
hr = GenerateRandomString(
pdgu,
culRandIOBytes,
culRandIOBytes,
&ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
culRandIOBytes,
&culWritten);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete ptcsBuffer;
ptcsBuffer = NULL;
}
}
// Commit root. BUGBUG: Use random modes
if(S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit unsuccessful, hr=0x%lx."),
hr));
}
}
// Now seek to the current stream to end of stream
if(S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
// Position the stream header to the postion from begining
hr = pvsnRootNewChildStream->Seek(liStreamPos, STREAM_SEEK_END, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulCurPosition[ORIGINAL] = ULIGetLow(uli);
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
}
// Clone the stream
if(S_OK == hr)
{
hr = pvsnRootNewChildStream->Clone(&pIStreamClone);
DH_HRCHECK(hr, TEXT("IStream::Clone")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Clone completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Clone not successful, hr=0x%lx."),
hr));
}
}
//clone IStream should really already be positioned to the end since
//the original IStream was there. The seek below simply ensures
//this plus gets the seek position into the Clone current position
//array element
if(S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
// Position the stream header to the postion from begining
hr = pIStreamClone->Seek(liStreamPos, STREAM_SEEK_END, &uli);
DH_HRCHECK(hr, TEXT("IStream::Seek")) ;
ulCurPosition[CLONE] = ULIGetLow(uli);
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
}
// Copy the ulCurPosition array to ulOldPosition array. Now in a loop,
// in a random fashion, select either the original stream or Clone stream,
// do either seek, read or write operation on it. Check that the unused
// stream's seek pointer hasn't changed. Update the ulOldPosition array
// with ulCurPostion araay and repeat the loop random number of times.
if (S_OK == hr)
{
// Generate random variations for while loop
usErr = pdgi->Generate(&culRandomVar, 1, 5);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
// Also fill up stream pointer array
pIStream[0] = pvsnRootNewChildStream->GetIStreamPointer();
pIStream[1] = pIStreamClone;
}
while ((S_OK == hr) && (culRandomVar--))
{
//save current seek pointer positions
ulOldPosition[ORIGINAL] = ulCurPosition[ORIGINAL];
ulOldPosition[CLONE] = ulCurPosition[CLONE];
// pick an IStream to use (either ORIGINAL or CLONE) then
// decide whether to seek on it, write it, or read it
usErr = pdgi->Generate(&cStreamInUse, ORIGINAL, CLONE);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
//pick an operation to do on the stream (either SEEK, WRITE, READ)
if(S_OK == hr)
{
usErr = pdgi->Generate(&cOpInUse, SEEK, READ);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if(S_OK == hr)
{
//Seek to a random position in stream
usErr = pdgi->Generate(&culRandomPos, 0, culWritten);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
if(S_OK == hr)
{
LISet32(liStreamPos, culRandomPos);
// Position stream header to the postion from begining
hr = pIStream[cStreamInUse]->Seek(
liStreamPos,
STREAM_SEEK_SET,
&uli);
DH_HRCHECK(hr, TEXT("IStream::Seek")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Seek not successful.")));
}
}
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("cOpInUse %d on cStreamInUse %d"),
cOpInUse,
cStreamInUse));
switch(cOpInUse)
{
case SEEK:
{
ulCurPosition[cStreamInUse] = ULIGetLow(uli);
fFindSeekPosition = FALSE;
break;
}
case WRITE:
{
hr = GenerateRandomString(
pdgu,
0,
STM_BUFLEN,
&ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
if (S_OK == hr)
{
hr = pIStream[cStreamInUse]->Write(
ptcsBuffer,
_tcslen(ptcsBuffer),
NULL);
}
fFindSeekPosition = TRUE;
break;
}
case READ:
{
ptcsBuffer = new TCHAR [STM_BUFLEN];
if (ptcsBuffer == NULL)
{
hr = E_OUTOFMEMORY;
}
if(S_OK == hr)
{
// Initialize buffer
memset(ptcsBuffer, '\0', STM_BUFLEN);
hr = pIStream[cStreamInUse]->Read(
ptcsBuffer,
STM_BUFLEN,
NULL);
}
fFindSeekPosition = TRUE;
break;
}
}
if(S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("cOpInUse %d on cStreamInUse %d failed, hr = 0x%lx"),
cOpInUse,
cStreamInUse,
hr));
fPass = FALSE;
// Break out of while loop
break;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("cOpInUse %d on cStreamInUse %d passed. "),
cOpInUse,
cStreamInUse));
}
}
// Determine current seek position if above operation might have change
// it on the stream operated upon by seeking on it.
if((S_OK == hr) && (TRUE == fFindSeekPosition))
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
hr = pIStream[cStreamInUse]->Seek(
liStreamPos,
STREAM_SEEK_CUR,
&uli);
DH_HRCHECK(hr, TEXT("IStream::Seek")) ;
if(S_OK == hr)
{
ulCurPosition[cStreamInUse] = ULIGetLow(uli);
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful.")));
}
}
// Determine the seek pointer of the stream that was NOT operated upon
// hasn't changed.
if(S_OK == hr)
{
cStreamNotInUse = (cStreamInUse == ORIGINAL) ? CLONE : ORIGINAL;
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
hr = pIStream[cStreamNotInUse]->Seek(
liStreamPos,
STREAM_SEEK_CUR,
&uli);
DH_HRCHECK(hr, TEXT("IStream::Seek")) ;
if(S_OK == hr)
{
ulCurPosition[cStreamNotInUse] = ULIGetLow(uli);
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Seek not successful.")));
}
}
if((S_OK == hr) &&
(ulCurPosition[cStreamNotInUse] == ulOldPosition[cStreamNotInUse]))
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Old & new seek ptr for unused stream same as exp.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Old & new seek ptr for unused stream different unexp")));
fPass = FALSE;
break;
}
// Commit the root storage half of time.
if(S_OK == hr)
{
usErr = pdgi->Generate(&culRandomCommit, 1, 100);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if((S_OK == hr) && (culRandomCommit > 50))
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit not successful.")));
fPass = FALSE;
break;
}
}
}
// Release original stream
if (NULL != pvsnRootNewChildStream)
{
hr = pvsnRootNewChildStream->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful.")));
}
}
// Release Clone stream
if (NULL != pIStreamClone)
{
ulRef = pIStreamClone->Release();
DH_ASSERT(0 == ulRef);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Close unsuccessful.")));
}
}
// Release root
if (NULL != pVirtualDFRoot)
{
hr = pVirtualDFRoot->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful.")));
}
}
// if everything goes well, log test as passed else failed.
if ((S_OK == hr) && (TRUE == fPass))
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_101 passed.")) );
}
else
{
DH_LOG((LOG_FAIL, TEXT("Test variation STMTEST_101 failed.")) );
// test failed. make it look like it failed.
hr = FirstError (hr, E_FAIL);
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Delete strings
if(NULL != pRootNewChildStmName)
{
delete pRootNewChildStmName;
pRootNewChildStmName = NULL;
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete ptcsBuffer;
ptcsBuffer = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_101 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}
//----------------------------------------------------------------------------
//
// Test: STMTEST_102
//
// Synopsis: Create a root docfile with a child IStream. Write a random number
// of bytes to the IStream and commit the root docfile. Do the same
// with a child IStorage inside of the root docfile.
// The root docfile is instantiated and the IStream is instantiated.
// MAX_SIZE_ARRAY SetSize calls are made on the IStream, the size for
// the setsize is a random ulong. After each setsize, there is a 50%
// chance that change will be immediately commited.After all setsizes are
// complete, the IStream is released, the root docfile is commited
// and then the root docfile is deleted.
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// History: 1-July-1996 NarindK Created.
//
// New Test Notes:
// 1. Old File: LSETSIZE.CXX
// 2. Old name of test : LegitStreamSetSize test
// New Name of test : STMTEST_102
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-102
// /dfRootMode:dirReadWriteShEx
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-102
// /dfRootMode:xactReadWriteShEx
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-102
// /dfRootMode:xactReadWriteShDenyW
// d. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-102
// /dfRootMode:dirReadWriteShEx /stdblock
// e. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-102
// /dfRootMode:xactReadWriteShEx /stdblock
// f. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-102
// /dfRootMode:xactReadWriteShDenyW /stdblock
//
// BUGNOTE: Conversion: STMTEST-102
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_102(int argc, char *argv[])
{
HRESULT hr = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualCtrNode *pvcnRootNewChildStorage= NULL;
VirtualStmNode *pvsnRootNewChildStream = NULL;
VirtualStmNode *pvsnChildStgNewChildStm= NULL;
LPTSTR pRootNewChildStgName = NULL;
LPTSTR pRootNewChildStmName = NULL;
LPTSTR pChildStgNewChildStmName= NULL;
LPTSTR ptcsBuffer = NULL;
ULONG culWritten = 0;
DWORD dwRootMode = 0;
ULONG ulThisSetSize = 0;
ULONG culRandIOBytes = 0;
ULONG culBytesLeftToWrite = 0;
ULONG culRandomCommit = 0;
ULONG culArrayIndex = 0;
ULONG i = 0;
ULONG j = 0;
VirtualCtrNode *pvcnInUse = NULL;
VirtualStmNode *pvsnInUse = NULL;
LARGE_INTEGER liStreamPos;
ULARGE_INTEGER uli;
ULARGE_INTEGER uliCopy;
ULARGE_INTEGER uliSet;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_102"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_102 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt stream SetSize operations")) );
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_102, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu) ;
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi) ;
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName,
0,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream);
DH_HRCHECK(hr, TEXT("AddStream")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
}
// Generate a random name for child IStorage
if(S_OK == hr)
{
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStgName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
// ----------- flatfile change ---------------
if(!StorageIsFlat())
{
// ----------- flatfile change ---------------
// Adds a new storage to the root storage.
if(S_OK == hr)
{
hr = AddStorage(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStgName,
pTestChanceDF->GetStgMode()|
STGM_CREATE |
STGM_FAILIFTHERE,
&pvcnRootNewChildStorage);
DH_HRCHECK(hr, TEXT("AddStorage")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::AddStorage completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::AddStorage not successful, hr=0x%lx."),
hr));
}
}
// ----------- flatfile change ---------------
}
else
{
pvcnRootNewChildStorage = pVirtualDFRoot;
}
// ----------- flatfile change ---------------
// Create a stream inside this child storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(
pdgu,
MINLENGTH,
MAXLENGTH,
&pChildStgNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pvcnRootNewChildStorage,
pChildStgNewChildStmName,
0,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnChildStgNewChildStm);
DH_HRCHECK(hr, TEXT("AddStream")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
}
if (S_OK == hr)
{
// Generate random size for stream between 0L, and MIN_SIZE * 1.5
// (range taken from old test).
usErr = pdgi->Generate(&culBytesLeftToWrite, 0,(ULONG)(MIN_SIZE * 1.5));
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
// Loop to write new IStream in RAND_IO size chunks unless size
// remaining to write is less than RAND_IO, then write the remaining bytes
while((S_OK == hr) && (0 != culBytesLeftToWrite))
{
culRandIOBytes = RAND_IO_MIN;
if(culBytesLeftToWrite > culRandIOBytes)
{
culBytesLeftToWrite = culBytesLeftToWrite - culRandIOBytes;
}
else
{
culRandIOBytes = culBytesLeftToWrite;
culBytesLeftToWrite = 0;
}
// Call VirtualStmNode::Write to create random bytes in the stream. For
// our test purposes, we generate a random string of size culRandomBytes
// using GenerateRandomString function.
if(S_OK == hr)
{
hr = GenerateRandomString(
pdgu,
culRandIOBytes,
culRandIOBytes,
&ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
culRandIOBytes,
&culWritten);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete ptcsBuffer;
ptcsBuffer = NULL;
}
}
// Now seek to the start of this stream
if(S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
// Position the stream header to the postion from begining
hr = pvsnRootNewChildStream->Seek(liStreamPos, STREAM_SEEK_SET, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful.")));
}
}
//Copy this stream pvsnRootNewChildStream to pvsnChildStgNewChildStm
if(S_OK == hr)
{
ULISet32(uliCopy, ULONG_MAX);
hr = pvsnRootNewChildStream->CopyTo(
pvsnChildStgNewChildStm,
uliCopy,
0,
0);
DH_HRCHECK(hr, TEXT("VirtualStmNode::CopyTo")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::CopyTo completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::CopyTo not successful.")));
}
}
// Commit child storage. BUGBUG: Use random modes
if(S_OK == hr)
{
hr = pvcnRootNewChildStorage->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit couldn't complete successfully.")));
}
}
// Commit root. BUGBUG: Use random modes
if(S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit couldn't complete successfully.")));
}
}
//do MAX_SIZE_ARRAY setsize calls on just created IStreams. Size
//to use in SetSize call for each iteration through the loop is
//a random ulong.
if(S_OK == hr)
{
for (j=0; j <= 1; j++)
{
if (j == 0)
{
pvsnInUse = pvsnRootNewChildStream;
pvcnInUse = pVirtualDFRoot;
}
else
{
pvsnInUse = pvsnChildStgNewChildStm;
pvcnInUse = pvcnRootNewChildStorage;
}
for(i=0; i<=MAX_SIZE_ARRAY; i++)
{
if(TRUE == g_fUseStdBlk)
{
// Pick up a random array element.
usErr = pdgi->Generate(&culArrayIndex, 0, MAX_SIZE_ARRAY);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
else
{
ulThisSetSize= ausSIZE_ARRAY[culArrayIndex];
}
}
else
{
usErr = pdgi->Generate(&ulThisSetSize, 0, MIN_SIZE * 3);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if(S_OK == hr)
{
ULISet32(uliSet, ulThisSetSize);
hr = pvsnInUse->SetSize(uliSet);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::SetSize completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::SetSize not successful, hr=0x%lx."),
hr));
}
}
// Commit the storage in use, half of time.
if(S_OK == hr)
{
usErr = pdgi->Generate(&culRandomCommit, 1, 100);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if((S_OK == hr) && (culRandomCommit > 50))
{
hr = pvcnInUse->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit not successful, hr =0x%lx"),
hr));
}
}
if (S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
// Position the stream header to the end of stream
hr = pvsnInUse->Seek(liStreamPos, STREAM_SEEK_END, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr = 0x%lx."),
hr));
}
}
if(S_OK != hr)
{
break;
}
}
}
}
// Release root's child stream
if (NULL != pvsnRootNewChildStream)
{
hr = pvsnRootNewChildStream->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful.")));
}
}
// Release child stg's child stream
if (NULL != pvsnChildStgNewChildStm)
{
hr = pvsnChildStgNewChildStm->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful.")));
}
}
// Commit child storage. BUGBUG: Use random modes
if(S_OK == hr)
{
hr = pvcnRootNewChildStorage->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit couldn't complete successfully.")));
}
}
// ----------- flatfile change ---------------
if(!StorageIsFlat())
{
// ----------- flatfile change ---------------
// Release child storage
if (NULL != pvcnRootNewChildStorage)
{
hr = pvcnRootNewChildStorage->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful.")));
}
}
// ----------- flatfile change ---------------
}
// ----------- flatfile change ---------------
// Commit root. BUGBUG: Use random modes
if(S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit couldn't complete successfully.")));
}
}
// Release root
if (NULL != pVirtualDFRoot)
{
hr = pVirtualDFRoot->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful.")));
}
}
// if everything goes well, log test as passed else failed.
if (S_OK == hr)
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_102 passed.")) );
}
else
{
DH_LOG((LOG_FAIL, TEXT("Test variation STMTEST_102 failed.")) );
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Delete strings
if(NULL != pRootNewChildStmName)
{
delete pRootNewChildStmName;
pRootNewChildStmName = NULL;
}
if(NULL != pChildStgNewChildStmName)
{
delete pChildStgNewChildStmName;
pChildStgNewChildStmName = NULL;
}
if(NULL != pRootNewChildStgName)
{
delete pRootNewChildStgName;
pRootNewChildStgName = NULL;
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete ptcsBuffer;
ptcsBuffer = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_102 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}
//----------------------------------------------------------------------------
//
// Test: STMTEST_103
//
// Synopsis: The test create a root docfile with a child IStream. Writes and
// CRCs a random number of bytes to the IStream in random block
// size chunks, or if the /stdblock (use size array) option is
// specified in cmdline, then in random block size from
// ausSIZE_ARRAY[] chunks, then releases the IStream. The root
// docfile is then committed and released.
// The root docfile is instantiated and the IStream is instantiated.
// The IStream is read in same random block size chunks as written,
// and CRCs are compared to verify. The stream and the root docfile
// are then released and the root file is deleted.
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// New Test Notes:
// 1. Old File(s): LSREAD.CXX LSWRITE.CXX
// 2. Old name of test(s) : LegitStreamRead LegitStreamWrite tests
// New Name of test(s) : STMTEST_103
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-103
// /dfRootMode:dirReadWriteShEx
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-103
// /dfRootMode:xactReadWriteShEx
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-103
// /dfRootMode:xactReadWriteShDenyW
// d. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-103
// /dfRootMode:dirReadWriteShEx /stdblock
// e. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-103
// /dfRootMode:xactReadWriteShEx /stdblock
// f. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-103
// /dfRootMode:xactReadWriteShDenyW /stdblock
//
// History: Jiminli 08-July-96 Created
//
// BUGNOTE: Conversion: STMTEST-103
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_103(int argc, char *argv[])
{
HRESULT hr = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualStmNode *pvsnRootNewChildStream = NULL;
LPTSTR pRootNewChildStmName = NULL;
LPTSTR ptcsBuffer = NULL;
ULONG culWritten = 0;
ULONG culRead = 0;
DWORD dwRootMode = 0;
ULONG culRandIOBytes = 0;
ULONG culBytesLeftToWrite = 0;
ULONG culBytesLeftToRead = 0;
ULONG tmpBytes = 0;
ULONG culArrayIndex = 0;
ULONG cStartIndex = 6;
DWCRCSTM *dwMemCRC = NULL;
DWCRCSTM *dwActCRC = NULL;
ULONG numofchunks = 0;
ULONG index = 0;
BOOL fPass = TRUE;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_103"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_103 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt stream Read operations")) );
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_103, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu) ;
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi) ;
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName,
0,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream);
DH_HRCHECK(hr, TEXT("AddStream")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
}
if (S_OK == hr)
{
// Generate random size for stream between 0L, and MIN_SIZE * 2
usErr = pdgi->Generate(&culBytesLeftToWrite, 0, MIN_SIZE * 2);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if (S_OK == hr)
{
// Record for later use.
culBytesLeftToRead = culBytesLeftToWrite;
tmpBytes = culBytesLeftToWrite;
}
if (S_OK == hr)
{
if (TRUE == g_fUseStdBlk)
{
// Pick up a random array element. Choosing cStartIndex of the
// array (with random blocks) as 6 because do not want to write
// byte by byte or in too small chunks a large docfile.
usErr = pdgi->Generate(&culArrayIndex, cStartIndex, MAX_SIZE_ARRAY);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
else
{
culRandIOBytes = ausSIZE_ARRAY[culArrayIndex];
}
}
else
{
// Generate random number of bytes to write per chunk b/w
// RAND_IO_MIN and RAND_IO_MAX.
usErr = pdgi->Generate(&culRandIOBytes, RAND_IO_MIN, RAND_IO_MAX);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
}
// Calculate how many chunks be written, i.e how many CRC's be calculated
if (S_OK == hr)
{
if (0 == culRandIOBytes)
{
hr = E_FAIL;
}
else
{
while (0 != culBytesLeftToWrite)
{
numofchunks++;
if (culBytesLeftToWrite >= culRandIOBytes)
{
culBytesLeftToWrite -= culRandIOBytes;
}
else
{
culBytesLeftToWrite = 0;
}
}
}
}
if (S_OK == hr)
{
culBytesLeftToWrite = tmpBytes;
tmpBytes = culRandIOBytes;
}
// Allocate memory
if (S_OK == hr)
{
dwMemCRC = new DWCRCSTM[numofchunks];
dwActCRC = new DWCRCSTM[numofchunks];
if ((NULL == dwMemCRC) || (NULL == dwActCRC))
{
hr = E_OUTOFMEMORY;
}
}
// Initilize each CRC to zero
if (S_OK == hr)
{
for (index=0; index<numofchunks; index++)
{
(*(dwMemCRC + index)).dwCRCSum = 0;
(*(dwActCRC + index)).dwCRCSum = 0;
}
}
// Loop to write new IStream in RAND_IO size chunks unless size
// remaining to write is less than RAND_IO, then write the remaining bytes
index = 0;
while ((S_OK == hr) && (0 != culBytesLeftToWrite))
{
if (culBytesLeftToWrite > culRandIOBytes)
{
culBytesLeftToWrite = culBytesLeftToWrite - culRandIOBytes;
}
else
{
culRandIOBytes = culBytesLeftToWrite;
culBytesLeftToWrite = 0;
}
// Call VirtualStmNode::Write to create random bytes in the stream. For
// our test purposes, we generate a random string of size culRandIOBytes
// using GenerateRandomString function.
if (S_OK == hr)
{
hr = GenerateRandomString(
pdgu,
culRandIOBytes,
culRandIOBytes,
&ptcsBuffer);
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
culRandIOBytes,
&culWritten);
}
if(S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
// Calculate the CRC for stream name and data
if (S_OK == hr)
{
hr = CalculateInMemoryCRCForStm(
pvsnRootNewChildStream,
ptcsBuffer,
culRandIOBytes,
(dwMemCRC+index));
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
}
index++;
}
// Log while loop result
DH_HRCHECK(hr, TEXT("While loop - GenrateRandomName/IStream::Write,CRC"));
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Write completed successfully.")));
}
// Release stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtulaStmNode::Close unsuccessful, hr=0x%lx."),
hr));
}
}
// Commit root. BUGBUG: Use random modes
if (S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit wasn't successfully, hr=0x%lx."),
hr));
}
}
// Release root
if (S_OK == hr)
{
hr = pVirtualDFRoot->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// Open root
if (S_OK == hr)
{
hr = pVirtualDFRoot->OpenRoot(
NULL,
dwRootMode,
NULL,
0);
DH_HRCHECK(hr, TEXT("VirtualCtrNode::Open")) ;
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Open completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Open wasn't successfully, hr=0x%lx."),
hr));
}
// Open stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Open(
NULL,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE ,
0);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Open")) ;
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Open completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Open wasn't successfully, hr=0x%lx."),
hr));
}
// Read and verify
index = 0;
culRandIOBytes = tmpBytes;
while ((S_OK == hr) && (0 != culBytesLeftToRead))
{
if (culBytesLeftToRead > culRandIOBytes)
{
culBytesLeftToRead = culBytesLeftToRead - culRandIOBytes;
}
else
{
culRandIOBytes = culBytesLeftToRead;
culBytesLeftToRead = 0;
}
// Allocate a buffer of required size
if (S_OK == hr)
{
ptcsBuffer = new TCHAR [culRandIOBytes];
if (NULL == ptcsBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsBuffer, '\0', culRandIOBytes*sizeof(TCHAR));
hr = pvsnRootNewChildStream->Read(
ptcsBuffer,
culRandIOBytes,
&culRead);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Read function wasn't successful, hr=0x%lx."),
hr));
}
// Calculate the CRC for stream name and data
if (S_OK == hr)
{
hr = CalculateInMemoryCRCForStm(
pvsnRootNewChildStream,
ptcsBuffer,
culRandIOBytes,
(dwActCRC+index));
DH_HRCHECK(hr, TEXT("CalculateInMemoryCRCForStm"));
}
// Compare corresponding dwMemCRC and dwActCRC and verify
if (S_OK == hr)
{
if ( (*(dwActCRC+index)).dwCRCSum != (*(dwMemCRC+index)).dwCRCSum )
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("CRC's for pvsnNewChildStream don't match. ")));
fPass = FALSE;
break;
}
}
// Delete temp buffer
if (NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
}
index++;
}
// Log results of while loop
DH_HRCHECK(hr, TEXT("While loop - GenrateRandomName/IStream::Write,CRC"));
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Write completed successfully.")));
}
if (S_OK == hr)
{
if (TRUE == fPass)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("CRC's for pvsnNewChildStream all matched.")));
}
}
// Release stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// Release Root
if (S_OK == hr)
{
hr = pVirtualDFRoot->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// if everything goes well, log test as passed else failed.
if ((S_OK == hr) && (TRUE == fPass))
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_103 passed.")) );
}
else
{
DH_LOG((LOG_FAIL,
TEXT("Test variation STMTEST_103 failed, hr=0x%lx."),
hr));
// test failed. make it look like it failed.
hr = FirstError (hr, E_FAIL);
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Delete strings
if (NULL != pRootNewChildStmName)
{
delete pRootNewChildStmName;
pRootNewChildStmName = NULL;
}
// Delete temp buffer
if (NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
}
if (NULL != dwMemCRC)
{
delete []dwMemCRC;
dwMemCRC = NULL;
}
if (NULL != dwActCRC)
{
delete []dwActCRC;
dwActCRC = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_103 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}
//----------------------------------------------------------------------------
//
// Test: STMTEST_104
//
// Synopsis: Create a root docfile and an IStream in that. Write to IStream.
// The test seeks to the end of the IStream to determine the size
// and then makes 4 seek passes through the IStream:
//
// 1) Seek cumulative offset from STREAM_SEEK_SET (beginning)
// to end, then rewind IStream to beginning
// 2) Seek relative offset from STREAM_SEEK_CUR (current)
// to end, then seek IStream to end
// 3) Seek negative cumulative offset from STREAM_SEEK_END (end)
// to beginning, then seek IStream to end
// 4) Seek negative relative offset from STREAM_SEEK_CUR (current)
// to beginning
// 5) Perform several random large offset seeks from
// STREAM_SEEK_SET (beginning)
// 6) Attempt to write one byte at the current position in stream
//
// The root docfile and stream are then releases and root docfile
// deleted
//
// Note: It is an error to seek before beginning of stream (tested
// in part 4, but it is not an error to seek past end of stream.
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// History: 2-July-1996 NarindK Created.
//
// New Test Notes:
// 1. Old File: LSSEEK.CXX
// 2. Old name of test : LegitStreamSeek test
// New Name of test : STMTEST_104
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-104
// /dfRootMode:dirReadWriteShEx /labmode
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-104
// /dfRootMode:xactReadWriteShEx /labmode
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-104
// /dfRootMode:xactReadWriteShDenyW /labmode
// d. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-104
// /dfRootMode:dirReadWriteShEx /labmode /stdblock
// e. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-104
// /dfRootMode:xactReadWriteShEx /labmode /stdblock
// f. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-104
// /dfRootMode:xactReadWriteShDenyW /labmode /stdblock
// g. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-104
// /dfRootMode:dirReadWriteShEx /labmode /stdblock /lgseekwrite
// h. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-104
// /dfRootMode:xactReadWriteShEx /labmode /stdblock /lgseekwrite
// i. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-104
// /dfRootMode:xactReadWriteShDenyW /labmode /stdblock /lgseekwrite
//
// BUGNOTE: Conversion: STMTEST-104
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_104(int argc, char *argv[])
{
HRESULT hr = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualStmNode *pvsnRootNewChildStream = NULL;
LPTSTR pRootNewChildStmName = NULL;
LPTSTR ptcsBuffer = NULL;
ULONG culWritten = 0;
DWORD dwRootMode = 0;
ULONG culRandIOBytes = 0;
ULONG culBytesLeftToWrite = 0;
ULONG ulStreamSize = 0;
LONG lSeekThisTime = 0;
ULONG cArrayIndex = 0;
ULONG ulCurrentPosition = 0;
ULONG cNumVars = 0;
ULONG cMinVars = 5;
ULONG cMaxVars = 10;
BOOL fPass = TRUE;
LARGE_INTEGER liStreamPos;
LARGE_INTEGER liSeekThisTime;
ULARGE_INTEGER uli;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_104"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_104 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt stream Seek operations")) );
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_104, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu);
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi) ;
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName,
0,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream);
DH_HRCHECK(hr, TEXT("AddStream")) ;
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
// Generate random size for stream between 0L, and MIN_SIZE * 1.5
// (range taken from old test).
usErr = pdgi->Generate(&culBytesLeftToWrite, 0,(ULONG)(MIN_SIZE * 1.5));
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
// Loop to write new IStream in RAND_IO size chunks unless size
// remaining to write is less than RAND_IO, then write the remaining bytes
while((S_OK == hr) && (0 != culBytesLeftToWrite))
{
culRandIOBytes = RAND_IO_MIN;
if(culBytesLeftToWrite > culRandIOBytes)
{
culBytesLeftToWrite = culBytesLeftToWrite - culRandIOBytes;
}
else
{
culRandIOBytes = culBytesLeftToWrite;
culBytesLeftToWrite = 0;
}
// Call VirtualStmNode::Write to create random bytes in the stream. For
// our test purposes, we generate a random string of size culRandomBytes
// using GenerateRandomString function.
if(S_OK == hr)
{
hr = GenerateRandomString(
pdgu,
culRandIOBytes,
culRandIOBytes,
&ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
culRandIOBytes,
&culWritten);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete ptcsBuffer;
ptcsBuffer = NULL;
}
}
// Now seek to the end of this stream and determine its size
if(S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
// Seek to end of stream and determine size of stream
hr = pvsnRootNewChildStream->Seek(liStreamPos, STREAM_SEEK_END, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
}
if(S_OK == hr)
{
ulStreamSize = ULIGetLow(uli);
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
// loop through the entire IStream, each time seeking relative to the
// beginning of the IStream (STREAM_SEEK_SET). The amount to add to
// the offset from the beginning is a random number or a random array
// element of ausSIZE_ARRAY if command line option specifies that.
memset(&uli, 0, sizeof(LARGE_INTEGER));
while ((ulCurrentPosition < ulStreamSize) && (S_OK == hr))
{
hr = GetRandomSeekOffset(&lSeekThisTime, pdgi);
DH_HRCHECK(hr, TEXT("GetRandomSeekOffset")) ;
if(S_OK == hr)
{
LISet32(liSeekThisTime, lSeekThisTime);
hr = pvsnRootNewChildStream->Seek(
liSeekThisTime,
STREAM_SEEK_SET,
&uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulCurrentPosition = ULIGetLow(uli);
}
}
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Current position is now %lu"),
ulCurrentPosition));
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
if(S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
hr = pvsnRootNewChildStream->Seek(
liStreamPos,
STREAM_SEEK_SET,
&uli);
ulCurrentPosition = ULIGetLow(uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
// loop through the entire IStream, each time seeking relative to the
// current seek pointer (STREAM_SEEK_CUR). The distance to seek is a
// random ushort.
lSeekThisTime = 0;
memset(&uli, 0, sizeof(LARGE_INTEGER));
while ((ulCurrentPosition < ulStreamSize) && (S_OK == hr))
{
hr = GetRandomSeekOffset(&lSeekThisTime, pdgi);
DH_HRCHECK(hr, TEXT("GetRandomSeekOffset")) ;
if(S_OK == hr)
{
LISet32(liSeekThisTime, lSeekThisTime);
hr = pvsnRootNewChildStream->Seek(
liSeekThisTime,
STREAM_SEEK_CUR,
&uli);
ulCurrentPosition = ULIGetLow(uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
}
}
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Current position is now %lu"),
ulCurrentPosition));
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
// Seek to the end of Stream. Then we would seek negative cumulative
// offset from the STREAM_SEEK_END.
if(S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
memset(&uli, 0, sizeof(LARGE_INTEGER));
hr = pvsnRootNewChildStream->Seek(
liStreamPos,
STREAM_SEEK_END,
&uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulCurrentPosition = ULIGetLow(uli);
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
// loop through the entire IStream, each time seeking relative to the
// end of the IStream (STREAM_SEEK_END). The amount to add to
// the offset from the end is a random ushort
lSeekThisTime = 0;
memset(&uli, 0, sizeof(LARGE_INTEGER));
while ((ulCurrentPosition != 0) && (S_OK == hr))
{
hr = GetRandomSeekOffset(&lSeekThisTime, pdgi);
DH_HRCHECK(hr, TEXT("GetRandomSeekOffset")) ;
// if generated seek offset would cause a seek to before beginning
// of file, ensure that it won't do that by enforcing to seek to
// the beginnining.
if(S_OK == hr)
{
if(lSeekThisTime > (LONG) ulStreamSize)
{
lSeekThisTime = (LONG) ulStreamSize;
}
// Unary minus opeartion is applied to seek offset to cause a neg
// seek opeartion
LISet32(liSeekThisTime, -lSeekThisTime);
hr = pvsnRootNewChildStream->Seek(
liSeekThisTime,
STREAM_SEEK_END,
&uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulCurrentPosition = ULIGetLow(uli);
}
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
if(S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
memset(&uli, 0, sizeof(LARGE_INTEGER));
hr = pvsnRootNewChildStream->Seek(
liStreamPos,
STREAM_SEEK_END,
&uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulCurrentPosition = ULIGetLow(uli);
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
//loop through the entire IStream, each time seeking relative to the
//current seek pointer (STREAM_SEEK_CUR). The distance to seek is a
//random ushort or a random block size chosen from ausSIZE_ARRAY[].
//This loop seeks in a negative direction.
lSeekThisTime = 0;
memset(&uli, 0, sizeof(LARGE_INTEGER));
while ((ulCurrentPosition != 0) && (S_OK == hr))
{
hr = GetRandomSeekOffset(&lSeekThisTime, pdgi);
DH_HRCHECK(hr, TEXT("GetRandomSeekOffset")) ;
// if generated seek offset would cause a seek to before beginning
// of file, ensure that it won't do that by enforcing to seek to
// the beginnining.
if(S_OK == hr)
{
if(lSeekThisTime > (LONG) ulCurrentPosition)
{
lSeekThisTime = (LONG) ulCurrentPosition;
}
// Unary minus operation is applied to seek offset to cause a neg
// seek opeartion
LISet32(liSeekThisTime, -lSeekThisTime);
hr = pvsnRootNewChildStream->Seek(
liSeekThisTime,
STREAM_SEEK_CUR,
&uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulCurrentPosition = ULIGetLow(uli);
}
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
if(S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
memset(&uli, 0, sizeof(LARGE_INTEGER));
hr = pvsnRootNewChildStream->Seek(
liStreamPos,
STREAM_SEEK_SET,
&uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulCurrentPosition = ULIGetLow(uli);
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
// Peform random number of seeks before beginning of the stream.
if (S_OK == hr)
{
// Generate random number of variations to be done.
usErr = pdgi->Generate(&cNumVars, cMinVars, cMaxVars);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if(S_OK == hr)
{
while((cNumVars--) && (S_OK == hr))
{
hr = GetRandomSeekOffset(&lSeekThisTime, pdgi);
DH_HRCHECK(hr, TEXT("GetRandomSeekOffset")) ;
if(S_OK == hr)
{
// Unary minus operation is applied to seek offset to cause a
// negative seek opeartion
LISet32(liSeekThisTime, -lSeekThisTime);
hr = pvsnRootNewChildStream->Seek(
liSeekThisTime,
STREAM_SEEK_CUR,
&uli);
ulCurrentPosition = ULIGetLow(uli);
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Seek to pos - %ld on IStream should have failed."),
lSeekThisTime));
fPass = FALSE;
break;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Seek pos -%ld on IStream failed as exp, hr=0x%lx."),
lSeekThisTime,
hr));
hr = S_OK;
}
}
}
}
// Now perform large offset seeks on IStream and the try to write 1 byte
// at the last offset if g_fDoLargeSeekAndWrite is set.
if (S_OK == hr)
{
// Generate random number of variations to be done.
usErr = pdgi->Generate(&cNumVars, cMinVars, cMaxVars);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if(S_OK == hr)
{
while((cNumVars--) && (S_OK == hr))
{
hr = GetRandomSeekOffset(&lSeekThisTime, pdgi);
DH_HRCHECK(hr, TEXT("GetRandomSeekOffset")) ;
if(S_OK == hr)
{
LISet32(liSeekThisTime, lSeekThisTime);
hr = pvsnRootNewChildStream->Seek(
liSeekThisTime,
STREAM_SEEK_SET,
&uli);
ulCurrentPosition = ULIGetLow(uli);
}
}
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not successful, hr=0x%lx."),
hr));
}
// Now atempt to write
LPTSTR ptszSample = TEXT("Test");
if((TRUE == g_fDoLargeSeekAndWrite) && (S_OK == hr))
{
hr = pvsnRootNewChildStream->Write(
ptszSample,
1,
NULL);
if((S_OK == hr) ||
(STG_E_MEDIUMFULL == hr) ||
(STG_E_INSUFFICIENTMEMORY == hr))
{
DH_TRACE((DH_LVL_TRACE1,
TEXT("Attempt to write 1 byte at offset %lu, hr = 0x%lx"),
ulCurrentPosition,
hr));
hr = S_OK;
}
else
{
DH_TRACE((DH_LVL_TRACE1,
TEXT("Attempt to write 1 byte ar offset %lu, hr = 0x%lx"),
ulCurrentPosition,
hr));
}
}
// Release root's child stream
if (NULL != pvsnRootNewChildStream)
{
hr = pvsnRootNewChildStream->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful, hr=0x%lx."),
hr));
}
}
// Release root
if (NULL != pVirtualDFRoot)
{
hr = pVirtualDFRoot->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
}
// if everything goes well, log test as passed else failed.
if((S_OK == hr) && (TRUE == fPass))
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_104 passed.")) );
}
else
{
DH_LOG((LOG_FAIL,
TEXT("Test variation STMTEST_104 failed, hr=0x%lx."),
hr) );
// test failed. make it look like it failed.
hr = FirstError (hr, E_FAIL);
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Delete strings
if(NULL != pRootNewChildStmName)
{
delete pRootNewChildStmName;
pRootNewChildStmName = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_104 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}
//----------------------------------------------------------------------------
//
// Test: STMTEST_105
//
// Synopsis: The test create a root docfile with a child IStream. Write a
// random number of bytes to the IStream and commit the root
// docfile.
//
// The test seeks to a position before the end of the IStream,
// SetSizes() the IStream to a size less than the current seek
// pointer position. The root docfile is committed. Verify that
// the seek pointer didn't change during the SetSize() call. Now
// write 0 bytes at the current seek pointer position(which is
// beyond the end of the IStream). The seek pointer still should
// not move and no error should occur. Finally, seek to the end of
// the IStream and verify the correct IStream size, then stream and
// the root docfile are released and the root file is deleted upon
// success.
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// New Test Notes:
// 1. Old File(s): LSETSIZA.CXX
// 2. Old name of test(s) : LegitStreamSetSizeAbandon test
// New Name of test(s) : STMTEST_105
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-105
// /dfRootMode:dirReadWriteShEx
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-105
// /dfRootMode:xactReadWriteShEx
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-105
// /dfRootMode:xactReadWriteShDenyW
//
// History: Jiminli 16-July-96 Created
//
// BUGNOTE: Conversion: STMTEST-105
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_105(int argc, char *argv[])
{
HRESULT hr = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualStmNode *pvsnRootNewChildStream = NULL;
LPTSTR pRootNewChildStmName = NULL;
LPTSTR ptcsBuffer = NULL;
ULONG culBytesLeftToWrite = 0;
ULONG culWritten = 0;
ULONG culRead = 0;
DWORD dwRootMode = 0;
ULONG culRandIOBytes = 0;
ULONG ulRandOffset = 0;
ULONG ulOriginalPosition = 0;
ULONG ulNewPosition = 0;
ULONG ulSizeParam = 0;
BOOL fPass = TRUE;
ULARGE_INTEGER uli;
ULARGE_INTEGER uliOffset;
LARGE_INTEGER liStreamPos;
LARGE_INTEGER liOffset;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_105"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_105 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt SetSize using the IStream interface.")) );
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_105, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu) ;
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi);
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName,
0,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream);
DH_HRCHECK(hr, TEXT("AddStream")) ;
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
// Generate random size for stream between 4L, and MIN_SIZE * 1.5
// (from old test)
usErr = pdgi->Generate(&culBytesLeftToWrite,4L,(ULONG)(MIN_SIZE * 1.5));
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if (S_OK == hr)
{
// Generate random number of bytes to write per chunk b/w
// RAND_IO_MIN and RAND_IO_MAX.
usErr = pdgi->Generate(&culRandIOBytes, RAND_IO_MIN, RAND_IO_MAX);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
// Loop to write new IStream in culRandIOBytes size chunks unless size
// remaining to write is less than culRandIOBytes, then write the
// remaining bytes. CRC is not important for this test, so no check for it.
while ((S_OK == hr) && (0 != culBytesLeftToWrite))
{
if (culBytesLeftToWrite > culRandIOBytes)
{
culBytesLeftToWrite = culBytesLeftToWrite - culRandIOBytes;
}
else
{
culRandIOBytes = culBytesLeftToWrite;
culBytesLeftToWrite = 0;
}
// Call VirtualStmNode::Write to create random bytes in the stream. For
// our test purposes, we generate a random string of size culRandIOBytes
// using GenerateRandomString function.
if (S_OK == hr)
{
hr = GenerateRandomString(
pdgu,
culRandIOBytes,
culRandIOBytes,
&ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
culRandIOBytes,
&culWritten);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
}
}
// Commit root. BUGBUG: Use random modes
if (S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit wasn't successful, hr=0x%lx."),
hr));
}
// Seek to the end of stream
if (S_OK == hr)
{
memset(&liStreamPos, 0, sizeof(LARGE_INTEGER));
hr = pvsnRootNewChildStream->Seek(liStreamPos, STREAM_SEEK_END, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulOriginalPosition = ULIGetLow(uli);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed Ok. EndofStream = %lu"),
ulOriginalPosition));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not Ok, hr=0x%lx. EndofStream = %lu"),
hr,
ulOriginalPosition));
}
// Seeking to a negative value from end
if (S_OK == hr)
{
usErr = pdgi->Generate(&ulRandOffset, 1L, ulOriginalPosition / 2);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Seek to end of IStream - %lu bytes"),
ulRandOffset));
}
}
if(S_OK == hr)
{
LISet32(liOffset, (- (LONG)ulRandOffset));
hr = pvsnRootNewChildStream->Seek(liOffset, STREAM_SEEK_END, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulOriginalPosition = ULIGetLow(uli);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed Ok. New seek ptr=%lu"),
ulOriginalPosition));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Seek wasn't Ok, hr=0x%lx. New seek ptr=%lu"),
hr,
ulOriginalPosition));
}
// Generate number of bytes less than current seek pointer to
// SetSize the stream to.
if (S_OK == hr)
{
usErr = pdgi->Generate(&ulRandOffset, 1L, ulOriginalPosition / 2);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Random offset(i.e. new size of stream) = %lu bytes"),
ulRandOffset));
}
}
if (S_OK == hr)
{
ulSizeParam = ulOriginalPosition - ulRandOffset;
ULISet32(uliOffset, ulSizeParam);
hr = pvsnRootNewChildStream->SetSize(uliOffset);
DH_HRCHECK(hr, TEXT("VirtualStmNode::SetSize")) ;
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::SetSize completed successfully. Size=%lu"),
ulSizeParam));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::SetSize unsuccessful, hr=0x%lx, Size=%lu"),
hr,
ulSizeParam));
}
// Commit root. BUGBUG: Use random modes
if (S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit wasn't successful, hr=0x%lx."),
hr));
}
// Get current seek pointer, should be same as ulOriginalPosition
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Seek(liStreamPos, STREAM_SEEK_CUR, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulNewPosition = ULIGetLow(uli);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully. Seek ptr=%lu"),
ulNewPosition));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not Ok, hr=0x%lx, seek ptr=%lu"),
hr,
ulNewPosition));
}
if (S_OK == hr)
{
if (ulOriginalPosition != ulNewPosition)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::SetSize changed seek ptr position.")));
fPass = FALSE;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Ok, VirtualCtrNode::SetSize not change seek ptr.")));
}
}
// Tset 0 byte write beyond end of IStream, shouldn't move seek pointer
if (S_OK == hr)
{
hr = GenerateRandomString(
pdgu,
0,
0,
&ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
0,
&culWritten);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
// Delete temp buffer
if (NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
}
// Get current seek pointer, should be same as ulOriginalPosition
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Seek(liStreamPos, STREAM_SEEK_CUR, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulNewPosition = ULIGetLow(uli);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully. Seek ptr=%lu"),
ulNewPosition));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not Ok, hr=0x%lx, Seek ptr=%lu"),
hr,
ulNewPosition));
}
if (S_OK == hr)
{
if (ulOriginalPosition != ulNewPosition)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("0 byte write changed seek pointer position.")));
fPass = FALSE;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Ok, 0 byte write not change seek pointer position.")));
}
}
// Verify correct end of IStream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Seek(liStreamPos, STREAM_SEEK_END, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulNewPosition = ULIGetLow(uli);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully. EndofStm=%lu"),
ulNewPosition));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek not Ok, hr=0x%lx, EndofStm=%lu"),
hr,
ulNewPosition));
}
if (S_OK == hr)
{
if (ulSizeParam != ulNewPosition)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Seek to end is not same position as SetSize().")));
fPass = FALSE;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Ok, Seek to end is the same position as SetSize().")));
}
}
// Release stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// Release Root
if (S_OK == hr)
{
hr = pVirtualDFRoot->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// if everything goes well, log test as passed else failed.
if ((S_OK == hr) && (TRUE == fPass))
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_105 passed.")) );
}
else
{
DH_LOG((LOG_FAIL,
TEXT("Test variation STMTEST_105 failed, hr=0x%lx."),
hr));
// test failed. make it look like it failed.
hr = FirstError (hr, E_FAIL);
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Delete strings
if (NULL != pRootNewChildStmName)
{
delete pRootNewChildStmName;
pRootNewChildStmName = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_105 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}
//----------------------------------------------------------------------------
//
// Test: STMTEST_106
//
// Synopsis: The test create a root docfile with a child IStream. 3 random
// SECTORSIZE byte blocks are generated and the CRC is computed.
// The data is written to the IStream. then the IStream is
// rewound and read back, and the CRC returned from the read is
// compared with the CRC when written. The seek pointer is changed
// to an offset somewhere in the first sector, but not the first
// or last byte. A SECTORSIZE block of the in-memory buffer is
// changed starting at the same offset used for the seek. The CRC
// is computed for the entire memory buffer. The block is written
// to the IStream, the IStream is rewound, read, and the CRCs are
// again compared. Finally, the root docfile is committed and the
// read/CRC compare is repeated. Then stream and the root docfile
// are released and the root file is deleted upon success.
//
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// New Test Notes:
// 1. Old File(s): LSECTSPN.CXX
// 2. Old name of test(s) : LegitStreamSectorSpan test
// New Name of test(s) : STMTEST_106
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-106
// /dfRootMode:dirReadWriteShEx
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-106
// /dfRootMode:xactReadWriteShEx
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-106
// /dfRootMode:xactReadWriteShDenyW
//
// History: Jiminli 18-July-96 Created
//
// BUGNOTE: Conversion: STMTEST-106
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_106(int argc, char *argv[])
{
HRESULT hr = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualStmNode *pvsnRootNewChildStream = NULL;
LPTSTR pRootNewChildStmName = NULL;
LPTSTR ptTempBuf1 = NULL;
LPTSTR ptTempBuf2 = NULL;
LPBYTE ptcsBuffer = NULL;
LPBYTE ptcsDataBuffer = NULL;
ULONG culNumBytes = 0;
ULONG culWritten = 0;
ULONG ulRandOffset = 0;
ULONG culRead = 0;
ULONG index1 = 0;
ULONG index2 = 0;
DWORD dwRootMode = 0;
DWORD dwBufCRC = 0;
DWORD dwActCRC = 0;
BOOL fPass = TRUE;
LARGE_INTEGER liZero;
LARGE_INTEGER liOffset;
ULARGE_INTEGER uli;
ULONG ulOriginalPosition = 0;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_106"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_106 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt SectorSpan using the Stm interface.")) );
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_106, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu) ;
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi) ;
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if (S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if (S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName,
0,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream);
DH_HRCHECK(hr, TEXT("AddStream")) ;
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
// Generate three sectors worth of random bytes and compute CRC
// then write the bytes to the IStream, rewind IStream, then read
// back the data and compare CRCs to ensure valid write/read
if (S_OK == hr)
{
// Generate a random string of size culNumBytes
culNumBytes = SECTORSIZE * 3;
hr = GenerateRandomString(
pdgu,
culNumBytes,
culNumBytes,
&ptTempBuf1);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
// Let ptcsBuffer point to temporary buffer(for purpose of
// type casting, because IStream:Seek proceeds by BYTE)
ptcsBuffer = (LPBYTE)ptTempBuf1;
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsBuffer,
culNumBytes,
&dwBufCRC);
DH_HRCHECK(hr, TEXT("CalculateCRCForDataBuffer"));
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
culNumBytes,
&culWritten);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Write function not successful, hr=0x%lx."),
hr));
}
// Allocate required space
if (S_OK == hr)
{
ptcsDataBuffer = new BYTE[culNumBytes];
if (NULL == ptcsDataBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsDataBuffer, '\0', culNumBytes * sizeof(BYTE));
while (culNumBytes--)
{
ptcsDataBuffer[index1] = ptcsBuffer[index1];
index1++;
}
culNumBytes = SECTORSIZE * 3;
}
// delete temp buffer (ptcsBuffer and ptTempBuf1 point to the same memory)
if (NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
ptTempBuf1 = NULL;
}
if (S_OK == hr)
{
LISet32(liZero, 0L);
hr = pvsnRootNewChildStream->Seek(liZero, STREAM_SEEK_SET, NULL);
DH_HRCHECK(hr, TEXT("IStream::Seek")) ;
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek function not successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
ptcsBuffer = new BYTE[culNumBytes];
if (NULL == ptcsBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsBuffer, '\0', culNumBytes * sizeof(BYTE));
hr = pvsnRootNewChildStream->Read(
ptcsBuffer,
culNumBytes,
&culRead);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read function not successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsBuffer,
culNumBytes,
&dwActCRC);
DH_HRCHECK(hr, TEXT("CalculateCRCForDataBuffer"));
}
// Compare CRCs
if (S_OK == hr)
{
if (dwBufCRC != dwActCRC)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream write/read mismatch before change, hr=0x%lx."),
hr));
fPass = FALSE;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream write/read matched before change.")));
}
}
// Delete temp buffer
if (NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
}
// Pick a random offset somewhere in the first sector, but not the first
// or last byte. Seek to the new position. Starting at the same offset in
// the in-memory buffer, replace 1 SECTORSIZE block with new random data.
// After the replace, re-compute the CRC for the entire buffer.
if (S_OK == hr)
{
usErr = pdgi->Generate(&ulRandOffset, 1, (SECTORSIZE - 1));
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Seek to position of the first SECTOR: %lu"),
(ULONG)ulRandOffset));
}
}
if (S_OK == hr)
{
LISet32(liOffset, ulRandOffset);
hr = pvsnRootNewChildStream->Seek(liOffset, STREAM_SEEK_SET, &uli);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek")) ;
ulOriginalPosition = ULIGetLow(uli);
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Seekpos = %lu"),
ulOriginalPosition));
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Seek wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
// Generate a random string of size SECTORSIZE
hr = GenerateRandomString(
pdgu,
SECTORSIZE,
SECTORSIZE,
&ptTempBuf2);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
// Let ptcsBuffer point to the temporary buffer(for purpose of
// typecasting, because IStream::Seek proceeds by BYTE)
ptcsBuffer = (LPBYTE)ptTempBuf2;
// Change the memory buffer ptcsDataBuffer
culNumBytes = SECTORSIZE;
index1 = ulRandOffset;
index2 = 0;
while (culNumBytes--)
{
ptcsDataBuffer[index1++] = ptcsBuffer[index2++];
}
culNumBytes = SECTORSIZE * 3;
// Calculate CRC for the changed buffer
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsDataBuffer,
culNumBytes,
&dwBufCRC);
DH_HRCHECK(hr, TEXT("CalculateCRCForDataBuffer"));
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
SECTORSIZE,
&culWritten);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Write function not successful, hr=0x%lx."),
hr));
}
// delete temp buffer (ptcsBuffer and ptTempBuf2 point to the same memory)
if ( NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
ptTempBuf2 = NULL;
}
if (S_OK == hr)
{
memset(&liZero, 0, sizeof(LARGE_INTEGER));
hr = pvsnRootNewChildStream->Seek(liZero, STREAM_SEEK_SET, NULL);
DH_HRCHECK(hr, TEXT("IStream::Seek")) ;
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek function not successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
ptcsBuffer = new BYTE[culNumBytes];
if (NULL == ptcsBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsBuffer, '\0', culNumBytes * sizeof(BYTE));
hr = pvsnRootNewChildStream->Read(
ptcsBuffer,
culNumBytes,
&culRead);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read function not successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsBuffer,
culNumBytes,
&dwActCRC);
DH_HRCHECK(hr, TEXT("CalculateCRCForDataBuffer"));
}
// Compare CRCs
if (S_OK == hr)
{
if (dwBufCRC != dwActCRC)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream write/read mismatch after change, hr=0x%lx."),
hr));
fPass = FALSE;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream write/read matched after change.")));
}
}
// Commit root. BUGBUG: Use random modes
if (S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit wasn't successful, hr=0x%lx."),
hr));
}
if ( NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
}
if (S_OK == hr)
{
memset(&liZero, 0, sizeof(LARGE_INTEGER));
hr = pvsnRootNewChildStream->Seek(liZero, STREAM_SEEK_SET, NULL);
DH_HRCHECK(hr, TEXT("IStream::Seek")) ;
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek function not successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
ptcsBuffer = new BYTE[culNumBytes];
if (NULL == ptcsBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsBuffer, '\0', culNumBytes * sizeof(BYTE));
hr = pvsnRootNewChildStream->Read(
ptcsBuffer,
culNumBytes,
&culRead);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read function not successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsBuffer,
culNumBytes,
&dwActCRC);
DH_HRCHECK(hr, TEXT("CalculateCRCForDataBuffer"));
}
// Compare CRCs
if (S_OK == hr)
{
if (dwBufCRC != dwActCRC)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream write/read mismatch after commit, hr=0x%lx."),
hr));
fPass = FALSE;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream write/read matched after commit.")));
}
}
// Delete temp buffers
if (NULL != ptcsDataBuffer)
{
delete []ptcsDataBuffer;
ptcsDataBuffer = NULL;
}
if (NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
}
// Release stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// Release Root
if (S_OK == hr)
{
hr = pVirtualDFRoot->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// if everything goes well, log test as passed else failed.
if ((S_OK == hr) && (TRUE == fPass))
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_106 passed.")) );
}
else
{
DH_LOG((LOG_FAIL,
TEXT("Test variation STMTEST_106 failed, hr=0x%lx."),
hr));
// test failed. make it look like it failed.
hr = FirstError (hr, E_FAIL);
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Delete strings
if (NULL != pRootNewChildStmName)
{
delete pRootNewChildStmName;
pRootNewChildStmName = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_106 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}
//----------------------------------------------------------------------------
//
// Test: STMTEST_107
//
// Synopsis: The test create a root docfile with a child IStream. Then perform
// various illegitimate operating using the IStream interface. The
// stream and the root docfile are then released and the root file
// is deleted upon success.
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// New Test Notes:
// 1. Old File(s): ISNORM.CXX
// 2. Old name of test(s) : IllegitStreamNorm test
// New Name of test(s) : STMTEST_107
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-107
// /dfRootMode:dirReadWriteShEx
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-107
// /dfRootMode:xactReadWriteShEx
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-107
// /dfRootMode:xactReadWriteShDenyW
//
// History: Jiminli 14-July-96 Created
//
// BUGNOTE: Conversion: STMTEST-107
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_107(int argc, char *argv[])
{
HRESULT hr = S_OK;
HRESULT hr1 = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualStmNode *pvsnRootNewChildStream0 = NULL;
VirtualStmNode *pvsnRootNewChildStream1 = NULL;
LPSTREAM pstm0 = NULL;
LPSTREAM pstm1 = NULL;
LPSTREAM pCloneStm = NULL;
LPTSTR pRootNewChildStmName0 = NULL;
LPTSTR pRootNewChildStmName1 = NULL;
LPTSTR ptcsBuffer = NULL;
ULONG culWritten = 0;
ULONG culRead = 0;
DWORD dwRootMode = 0;
ULONG culRandIOBytes = 0;
ULONG ulRef = 0;
BOOL fPass = TRUE;
ULARGE_INTEGER uliCopy;
LARGE_INTEGER liOffset;
LARGE_INTEGER liZero;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_107"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_107 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt illegitimate operations on IStream.")) );
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_107, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu) ;
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi);
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(
pdgu,
MINLENGTH,
MAXLENGTH,
&pRootNewChildStmName0);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName0,
0,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream0);
DH_HRCHECK(hr, TEXT("AddFirstStream")) ;
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode0::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode0::AddStream not successful, hr=0x%lx."),
hr));
}
// Generate random number of bytes to write to stream b/w
// RAND_IO_MIN and RAND_IO_MAX.
if (S_OK == hr)
{
usErr = pdgi->Generate(&culRandIOBytes, RAND_IO_MIN, RAND_IO_MAX);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
// Call Virtual::Write to create random bytes in the stream. For our test
// purposes, we generate a random string of size culRandIOBytes using
// GenerateRandomString function.
if (S_OK == hr)
{
hr = GenerateRandomString(
pdgu,
culRandIOBytes,
culRandIOBytes,
&ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString"));
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream0->Write(
ptcsBuffer,
culRandIOBytes,
&culWritten);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
// Delete temp buffer
if (NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
}
// Adds another new stream to the root storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(
pdgu,
MINLENGTH,
MAXLENGTH,
&pRootNewChildStmName1);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName1,
0,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream1);
DH_HRCHECK(hr, TEXT("AddSecondStream")) ;
}
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode1::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode1::AddStream not successful, hr=0x%lx."),
hr));
}
// Pass NULL pv to read call, should fail
if (S_OK == hr)
{
pstm0 = pvsnRootNewChildStream0->GetIStreamPointer();
pstm1 = pvsnRootNewChildStream1->GetIStreamPointer();
DH_ASSERT(NULL != pstm0);
DH_ASSERT(NULL != pstm1);
}
if (S_OK == hr)
{
hr1 = pstm0->Read(
NULL,
culRandIOBytes,
&culRead);
if (STG_E_INVALIDPOINTER != hr1)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Read should return STG_E_INVALIDPOINTER, hr=0x%lx."),
hr1));
fPass = FALSE;
}
else
{
// Reset hr value for other tests
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Read failed as expected, hr=0x%lx."),
hr1));
hr1 = S_OK;
}
}
//
// coverage for bug# 143546
//
//
// commented out to avoid av'ing;
// we should activate it when bug it's fixed
//
/*
if (S_OK == hr)
{
const char *szDummy = "foo"; // readonly
// make stream nonempty
HRESULT hr2 = pstm0->Write(szDummy, strlen(szDummy), &culWritten);
DH_HRCHECK(hr2, TEXT("IStream::Write"));
if (S_OK == hr2)
{
LARGE_INTEGER li;
LISet32(li, 0L);
hr2 = pstm0->Seek(li, SEEK_SET,NULL);
DH_HRCHECK(hr2, TEXT("IStream::Seek SEEK_SET"));
}
if(S_OK == hr2)
{
hr1 = pstm0->Read((void*)szDummy,
strlen(szDummy),
&culRead);
if (STG_E_INVALIDPOINTER != hr1)
{
DH_TRACE((
DH_LVL_ERROR,
TEXT("Read should return STG_E_INVALIDPOINTER when in buffer is readonly, hr=0x%lx."),
hr1));
fPass = FALSE;
}
else
{
// Reset hr value for other tests
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Read failed as expected, hr=0x%lx."),
hr1));
hr1 = S_OK;
}
}
if(S_OK == hr2)
{
// restore empty stream
ULARGE_INTEGER uli;
LISet32(uli, 0L);
hr = pstm1->SetSize(uli);
DH_HRCHECK(hr, TEXT("IStream::SetSize 0"));
}
}
*/
// Pass NULL pv to write call, should fail
if (S_OK == hr)
{
hr1 = pstm1->Write(
NULL,
culRandIOBytes,
&culWritten);
if (STG_E_INVALIDPOINTER != hr1)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Write should return STG_E_INVALIDPOINTER, hr=0x%lx."),
hr1));
fPass = FALSE;
}
else
{
// Reset hr value for other tests
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Write failed as expected, hr=0x%lx."),
hr1));
hr1 = S_OK;
}
}
// Pass NULL ppstm to clone call, should fail
if (S_OK == hr)
{
hr1 = pstm0->Clone(
NULL);
if (STG_E_INVALIDPOINTER != hr1)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Clone should have failed, hr=0x%lx."),
hr1));
fPass = FALSE;
}
else
{
// Reset hr value for other tests
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Clone failed as expected, hr=0x%lx."),
hr1));
hr1 = S_OK;
}
}
// Pass NULL pstm to CopyTo call, should fail
if(S_OK == hr)
{
ULISet32(uliCopy, culRandIOBytes);
hr1 = pstm0->CopyTo(NULL, uliCopy, NULL, NULL);
if (STG_E_INVALIDPOINTER != hr1)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("CopyTo should have failed, hr=0x%lx."),
hr1));
fPass = FALSE;
}
else
{
// Reset hr value for other tests
DH_TRACE((
DH_LVL_TRACE1,
TEXT("CopyTo failed as expected, hr=0x%lx."),
hr1));
hr1 = S_OK;
}
}
// Pass 'cb' > length of stream to CopyTo(), should pass
if (S_OK == hr)
{
ULISet32(uliCopy, ULONG_MAX);
hr1 = pvsnRootNewChildStream0->CopyTo(
pvsnRootNewChildStream1,
uliCopy,
NULL,
NULL);
if (S_OK == hr1)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::CopyTo completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::CopyTo not successful, hr=0x%lx."),
hr1));
}
}
// Release Stream1
if (S_OK == hr)
{
hr = pvsnRootNewChildStream1->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode1::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode1::Close unsuccessful, hr=0x%lx."),
hr));
}
}
// Pass 'cb' > length of stream to CopyTo() w/dest Clone() of Istream,
// should pass
if(S_OK == hr)
{
LISet32(liZero, 0L);
hr1 = pvsnRootNewChildStream0->Seek(liZero, STREAM_SEEK_SET, NULL);
DH_HRCHECK(hr1, TEXT("IStream::Seek")) ;
if (S_OK == hr1)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::Seek function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::Seek function wasn't successful, hr=0x%lx."),
hr1));
}
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream0->Clone(&pCloneStm);
DH_HRCHECK(hr, TEXT("IStream::Clone"));
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Clone function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Clone function wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
hr = pstm0->CopyTo(pCloneStm, uliCopy, NULL, NULL);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::CopyTo completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::CopyTo not successful, hr=0x%lx."),
hr));
}
// Pass 'cb' > length of stream to CopyTo() w/dest Clone() of IStream,
// and seek pointer in source stream past end of file, should pass
// This also tests seek function in case of seeking past end of stream
if(S_OK == hr)
{
LISet32(liOffset, culRandIOBytes);
hr = pvsnRootNewChildStream0->Seek(liOffset, STREAM_SEEK_CUR, NULL);
DH_HRCHECK(hr, TEXT("IStream::Seek")) ;
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::Seeking past the end of stream successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::Seek past end of stream not Ok, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
hr = pstm0->CopyTo(pCloneStm, uliCopy, NULL, NULL);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::CopyTo completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream0::CopyTo not successful, hr=0x%lx."),
hr));
}
// Pass invalid dwOrigin(from old test) to seek call, should fail
if (S_OK == hr)
{
hr1 = pstm0->Seek(
liZero,
STREAM_SEEK_SET | STREAM_SEEK_CUR | STREAM_SEEK_END,
NULL);
if (STG_E_INVALIDFUNCTION != hr1)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Seek should have failed, hr=0x%lx."),
hr1));
fPass = FALSE;
}
else
{
// Reset hr value for other tests
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Seek failed as expected, hr=0x%lx."),
hr1));
hr1 = S_OK;
}
}
// Commit root. BUGBUG: Use random modes
if (S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit wasn't successful, hr=0x%lx."),
hr));
}
//Release streams
if (S_OK == hr)
{
hr = pvsnRootNewChildStream0->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode0::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode0::Close unsuccessful, hr=0x%lx."),
hr));
}
// Release Clone stream
if (NULL != pCloneStm)
{
ulRef = pCloneStm->Release();
DH_ASSERT(0 == ulRef);
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream1::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream1::Close unsuccessful.")));
}
// Release Root
if (S_OK == hr)
{
hr = pVirtualDFRoot->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// if everything goes well, log test as passed else failed.
if ((S_OK == hr) && (TRUE == fPass))
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_107 passed.")) );
}
else
{
DH_LOG((LOG_FAIL,
TEXT("Test variation STMTEST_107 failed, hr=0x%lx."),
hr));
// test failed. make it look like it failed.
hr = FirstError (hr, E_FAIL);
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Delete strings
if (NULL != pRootNewChildStmName0)
{
delete pRootNewChildStmName0;
pRootNewChildStmName0 = NULL;
}
if (NULL != pRootNewChildStmName1)
{
delete pRootNewChildStmName1;
pRootNewChildStmName1 = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_107 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}
//----------------------------------------------------------------------------
//
// Test: STMTEST_108
//
// Synopsis: The test create a root docfile with an IStream inside of it.
// A random block small object size block is generated and the CRC
// is computed. The data is written to the IStream. The IStream is
// rewound and read back. The CRC returned from the read is compared
// with the CRC computed during generation. A new random block bigger
// larger than small object size is generated at a random offset
// in the data buffer, and then the block is written to the IStream
// at that offset. This has the effect of transforming the small
// object into a regular object. The IStream is then rewound, read,
// and the read/write CRCs are compared. After a commit of the root
// docfile, the rewind, read, CRC compare is repeated. A random
// small object size is then chosen and the IStream is SetSized
// back to that size. The CRC is computed for the in-memory data
// buffer up to the new size. The IStream is rewound, read back,
// and CRC'd. The read/write CRCs are again compared to verify
// that the shrink back to small object size retained the correct
// data. After the root docfile is committed, we rewind, read,
// and compare read/write CRCs again. From 10 to 20 small objects
// are processed this way.
// Then stream and the root docfile are released and the root file
// is deleted upon success.
//
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// New Test Notes:
// 1. Old File(s): LSSMALLO.CXX
// 2. Old name of test(s) : LegitStreamSmallObjects test
// New Name of test(s) : STMTEST_108
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-108
// /dfRootMode:dirReadWriteShEx
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-108
// /dfRootMode:xactReadWriteShEx
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-108
// /dfRootMode:xactReadWriteShDenyW
//
// History: Jiminli 23-July-96 Created
//
// BUGNOTE: Conversion: STMTEST-108
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_108(int argc, char *argv[])
{
HRESULT hr = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualStmNode *pvsnRootNewChildStream = NULL;
LPTSTR pRootNewChildStmName = NULL;
LPTSTR ptTempBuf1 = NULL;
LPTSTR ptTempBuf2 = NULL;
LPBYTE ptcsBuffer = NULL;
LPBYTE ptcsReadBuffer = NULL;
LPBYTE ptChangeBuf = NULL;
USHORT cusNumSmallObjects = 0;
USHORT cusMinSmallObjects = 10;
USHORT cusMaxSmallObjects = 20;
ULONG culNumBytes = 0;
ULONG culIOBytes = 0;
ULONG culWritten = 0;
ULONG ulRandOffset = 0;
ULONG culRead = 0;
ULONG index = 0;
DWORD dwRootMode = 0;
DWORD dwBufCRC = 0;
DWORD dwActCRC = 0;
BOOL fPass = TRUE;
LARGE_INTEGER liZero;
LARGE_INTEGER liOffset;
ULARGE_INTEGER uliOffset;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_108"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_108 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt IStream operations on small objects.")) );
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_108, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu) ;
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi) ;
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if (S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if (S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName,
0,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE |
STGM_FAILIFTHERE,
&pvsnRootNewChildStream);
DH_HRCHECK(hr, TEXT("AddStream")) ;
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
// Generate random # of small objects for test between
// cusMinSmallObjects and cusMaxSmallObjects
usErr = pdgi->Generate(
&cusNumSmallObjects,
cusMinSmallObjects,
cusMaxSmallObjects);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Random # of small objects to test is: %d"),
cusNumSmallObjects));
}
// Loop for testing each small object
while ((cusNumSmallObjects--) && (S_OK == hr))
{
// Pick a random size for this small object, generate data to
// write in memory, compute CRC for databuffer, and write it.
usErr = pdgi->Generate(&culIOBytes, 0L, SMALL_OBJ_SIZE);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
if (S_OK == hr)
{
culNumBytes = SMALL_OBJ_SIZE * 4 + 1;
hr = GenerateRandomString(
pdgu,
culNumBytes,
culNumBytes,
&ptTempBuf1);
}
if (S_OK == hr)
{
// Let ptcsBuffer point to temporary buffer(for purpose of
// type casting, because IStream:Seek proceeds by BYTE)
ptcsBuffer = (LPBYTE)ptTempBuf1;
culNumBytes = culIOBytes;
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsBuffer,
culNumBytes,
&dwBufCRC);
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
culNumBytes,
&culWritten);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Write wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
LISet32(liZero, 0L);
hr = pvsnRootNewChildStream->Seek(liZero, STREAM_SEEK_SET, NULL);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek wasn't successful, hr=0x%lx."),
hr));
}
// read all data in the IStream(SMALL_OBJ_SIZE * 4) and compute CRC.
// We attempt to read SMALL_OBJ_SIZE * 4 instead of the number of bytes
// actually written so we catch the case of extra data pegged onto the
// end of the stream. IStream::Read() returns the number of bytes
// actually read, which in this case should be culIOBytes. Next,
// compare r/w CRCs.
if (S_OK == hr)
{
culNumBytes = SMALL_OBJ_SIZE * 4;
ptcsReadBuffer = new BYTE[culNumBytes];
if (NULL == ptcsReadBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsReadBuffer, '\0', culNumBytes * sizeof(BYTE));
hr = pvsnRootNewChildStream->Read(
ptcsReadBuffer,
culNumBytes,
&culRead);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read wasn't successful, hr=0x%lx."),
hr));
}
// culRead is the actual number of bytes read from IStream
if (S_OK == hr)
{
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsReadBuffer,
culRead,
&dwActCRC);
}
// Compare CRCs
if (S_OK == hr)
{
if (dwBufCRC != dwActCRC)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Small object w/r mismatch before grow, hr=0x%lx."),
hr));
fPass = FALSE;
}
}
// Delete temp buffer
if (NULL != ptcsReadBuffer)
{
delete []ptcsReadBuffer;
ptcsReadBuffer = NULL;
}
// Pick a random offset somewhere in the small object to begin changing
// data at. Position the IStream pointer to this location. Generate a
// random number of bytes into the in-memory buffer starting at this
// position, we generate enough new bytes to replace some that were
// already in the IStream and to expand the IStream beyond small object
// size.
if (S_OK == hr)
{
usErr = pdgi->Generate(&ulRandOffset, 0L, culIOBytes);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
// Seek to the random offset
if(S_OK == hr)
{
LISet32(liOffset, ulRandOffset);
hr = pvsnRootNewChildStream->Seek(liOffset, STREAM_SEEK_SET, NULL);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Seek wasn't successful, hr=0x%lx"),
hr));
}
// Generate random nubmer of bytes to grow
if(S_OK == hr)
{
usErr = pdgi->Generate(
&culIOBytes, SMALL_OBJ_SIZE+1, SMALL_OBJ_SIZE*3);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if (S_OK == hr)
{
culNumBytes = culIOBytes;
hr = GenerateRandomString(
pdgu,
culNumBytes,
culNumBytes,
&ptTempBuf2);
}
if (S_OK == hr)
{
ptChangeBuf = (LPBYTE)ptTempBuf2;
for (index = 0; index < culIOBytes; index++)
{
ptcsBuffer[ulRandOffset+index] = ptChangeBuf[index];
}
}
if (S_OK == hr)
{
// Calculate the new length of the object, and compute CRC for the
// whole buffer
culNumBytes = culIOBytes + ulRandOffset;
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsBuffer,
culNumBytes,
&dwBufCRC);
}
if (S_OK == hr)
{
// Write growing data from seek pointer
hr = pvsnRootNewChildStream->Write(
ptChangeBuf,
culIOBytes,
&culWritten);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Write wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
LISet32(liZero, 0L);
hr = pvsnRootNewChildStream->Seek(liZero, STREAM_SEEK_SET, NULL);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek wasn't successful, hr=0x%lx."),
hr));
}
// Read back the entire IStream, compute the CRC, and compare r/w CRCs
// Commit the root docfile and repeat this step
if (S_OK == hr)
{
culNumBytes = SMALL_OBJ_SIZE * 4;
ptcsReadBuffer = new BYTE[culNumBytes];
if (NULL == ptcsReadBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsReadBuffer, '\0', culNumBytes * sizeof(BYTE));
hr = pvsnRootNewChildStream->Read(
ptcsReadBuffer,
culNumBytes,
&culRead);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read wasn't successful, hr=0x%lx."),
hr));
}
// culRead is the actual number of bytes read from IStream
if (S_OK == hr)
{
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsReadBuffer,
culRead,
&dwActCRC);
}
// Compare CRCs
if (S_OK == hr)
{
if (dwBufCRC != dwActCRC)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Small object w/r mismatch after grow, hr=0x%lx."),
hr));
fPass = FALSE;
}
}
// Delete temp buffer
if (NULL != ptcsReadBuffer)
{
delete []ptcsReadBuffer;
ptcsReadBuffer = NULL;
}
// Commit root. BUGBUG: Use random modes
if (S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
memset(&liZero, 0, sizeof(LARGE_INTEGER));
hr = pvsnRootNewChildStream->Seek(liZero, STREAM_SEEK_SET, NULL);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
ptcsReadBuffer = new BYTE[culNumBytes];
if (NULL == ptcsReadBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsReadBuffer, '\0', culNumBytes * sizeof(BYTE));
hr = pvsnRootNewChildStream->Read(
ptcsReadBuffer,
culNumBytes,
&culRead);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsReadBuffer,
culRead,
&dwActCRC);
}
// Compare CRCs
if (S_OK == hr)
{
if (dwBufCRC != dwActCRC)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream w/r mismatch after grow/commit, hr=0x%lx."),
hr));
fPass = FALSE;
}
}
// Delete temp buffers
if (NULL != ptcsReadBuffer)
{
delete []ptcsReadBuffer;
ptcsReadBuffer = NULL;
}
// Pick a random small object size to set the IStream to. Shrink the
// IStream with SetSize. Compute the CRC for the in-memory data buffer
// up to the new size of the IStream.
if(S_OK == hr)
{
usErr = pdgi->Generate(&culIOBytes, 1L, SMALL_OBJ_SIZE);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if (S_OK == hr)
{
ULISet32(uliOffset, culIOBytes);
hr = pvsnRootNewChildStream->SetSize(uliOffset);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::SetSize unsuccessful, hr=0x%lx"),
hr));
}
if (S_OK == hr)
{
culNumBytes = culIOBytes;
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsBuffer,
culNumBytes,
&dwBufCRC);
}
// Seek to beginning of IStream we just shrank, read the whole thing
// back, compute CRC, and compare r/w CRCs. Finally, commit the root
// docfile and repeat this step.
if (S_OK == hr)
{
LISet32(liZero, 0L);
hr = pvsnRootNewChildStream->Seek(liZero, STREAM_SEEK_SET, NULL);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
culNumBytes = SMALL_OBJ_SIZE * 4;
ptcsReadBuffer = new BYTE[culNumBytes];
if (NULL == ptcsReadBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsReadBuffer, '\0', culNumBytes * sizeof(BYTE));
hr = pvsnRootNewChildStream->Read(
ptcsReadBuffer,
culNumBytes,
&culRead);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read wasn't successful, hr=0x%lx."),
hr));
}
// culRead is the actual number of bytes read from IStream
if (S_OK == hr)
{
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsReadBuffer,
culRead,
&dwActCRC);
}
// Compare CRCs
if (S_OK == hr)
{
if (dwBufCRC != dwActCRC)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Small object w/r mismatch after shrink, hr=0x%lx."),
hr));
fPass = FALSE;
}
}
// Delete temp buffer
if (NULL != ptcsReadBuffer)
{
delete []ptcsReadBuffer;
ptcsReadBuffer = NULL;
}
// Commit root. BUGBUG: Use random modes
if (S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
memset(&liZero, 0, sizeof(LARGE_INTEGER));
hr = pvsnRootNewChildStream->Seek(liZero, STREAM_SEEK_SET, NULL);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
ptcsReadBuffer = new BYTE[culNumBytes];
if (NULL == ptcsReadBuffer)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
memset(ptcsReadBuffer, '\0', culNumBytes * sizeof(BYTE));
hr = pvsnRootNewChildStream->Read(
ptcsReadBuffer,
culNumBytes,
&culRead);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Read wasn't successful, hr=0x%lx."),
hr));
}
if (S_OK == hr)
{
hr = CalculateCRCForDataBuffer(
(LPTSTR)ptcsReadBuffer,
culRead,
&dwActCRC);
}
// Compare CRCs
if (S_OK == hr)
{
if (dwBufCRC != dwActCRC)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream w/r mismatch after shrink/commit,hr=0x%lx"),
hr));
fPass = FALSE;
}
}
// Delete temp buffers
// ptcsBuffer and ptTempBuf1 point to the same memory chunk
// ptChangeBuf and ptTempBuf2 point to the same memory chunk
if (NULL != ptcsReadBuffer)
{
delete []ptcsReadBuffer;
ptcsReadBuffer = NULL;
}
if (NULL != ptcsBuffer)
{
delete []ptcsBuffer;
ptcsBuffer = NULL;
ptTempBuf1 = NULL;
}
if (NULL != ptTempBuf1)
{
delete []ptTempBuf1;
ptTempBuf1 = NULL;
ptcsBuffer = NULL;
}
if (NULL != ptTempBuf2)
{
delete []ptTempBuf2;
ptTempBuf2 = NULL;
ptChangeBuf = NULL;
}
// Reset IStream for next iteration of the loop
if (S_OK == hr)
{
ULISet32(uliOffset, 0L);
hr = pvsnRootNewChildStream->SetSize(uliOffset);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::SetSize unsuccessful, hr=0x%lx"),
hr));
}
if (S_OK == hr)
{
LISet32(liOffset, 0L);
hr = pvsnRootNewChildStream->Seek(liOffset, STREAM_SEEK_SET, NULL);
}
if (S_OK != hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Seek unsuccessful, hr=0x%lx"),
hr));
}
if ((S_OK != hr) || (TRUE != fPass))
{
break;
}
}
// Release stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// Release Root
if (S_OK == hr)
{
hr = pVirtualDFRoot->Close();
}
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
// if everything goes well, log test as passed else failed.
if ((S_OK == hr) && (TRUE == fPass))
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_108 passed.")) );
}
else
{
DH_LOG((LOG_FAIL,
TEXT("Test variation STMTEST_108 failed, hr=0x%lx."),
hr));
// test failed. make it look like it failed.
hr = FirstError (hr, E_FAIL);
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Delete strings
if (NULL != pRootNewChildStmName)
{
delete pRootNewChildStmName;
pRootNewChildStmName = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_108 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}
//----------------------------------------------------------------------------
//
// Test: STMTEST_109
//
// Synopsis: Creates a root docfile with a random name. Creates an IStream in
// the root docfile and writes random number of bytes. ILockRegion,
// IUnlockRegion and Stat operations are attempted on stream.
// The IStream and root are then released.
//
// Arguments:[argc]
// [argv]
//
// Returns: HRESULT
//
// Notes: This test runs in direct, transacted, and transacted deny write
// modes
//
// History: 13-Aug-1996 NarindK Created.
//
// New Test Notes:
// 1. Old File: -part of common.cxx-
// 2. Old name of test :
// New Name of test : STMTEST_109
// 3. To run the test, do the following at command prompt.
// a. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-109
// /dfRootMode:dirReadWriteShEx
// b. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-109
// /dfRootMode:xactReadWriteShEx
// c. stgbase /seed:2 /dfdepth:0-0 /dfstg:0-0 /dfstm:0-0 /t:STMTEST-109
// /dfRootMode:xactReadWriteShDenyW
//
// BUGNOTE: Conversion: STMTEST-109
//
//-----------------------------------------------------------------------------
HRESULT STMTEST_109(int argc, char *argv[])
{
HRESULT hr = S_OK;
ChanceDF *pTestChanceDF = NULL;
VirtualDF *pTestVirtualDF = NULL;
VirtualCtrNode *pVirtualDFRoot = NULL;
DG_STRING *pdgu = NULL;
DG_INTEGER *pdgi = NULL;
USHORT usErr = 0;
VirtualStmNode *pvsnRootNewChildStream = NULL;
LPTSTR pRootNewChildStmName = NULL;
ULONG cb = 0;
LPTSTR ptcsBuffer = NULL;
ULONG culWritten = 0;
DWORD dwRootMode = 0;
ULONG cRandomMinSize = 10;
ULONG cRandomMaxSize = 100;
BOOL fPass = TRUE;
LPMALLOC pMalloc = NULL;
STATSTG statStg;
ULARGE_INTEGER uliOffset;
ULARGE_INTEGER uliBytes;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("STMTEST_109"));
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_109 started.")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("Attempt stm LockRegion/UnLockRegion/Stat ops")));
// Create our ChanceDF and VirtualDF
hr = CreateTestDocfile (argc,
argv,
&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF);
// if creating the docfile - bail here
if (NULL != pTestChanceDF && DoingCreate ())
{
UINT ulSeed = pTestChanceDF->GetSeed ();
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
FALSE);
return (HRESULT)ulSeed;
}
if (S_OK == hr)
{
dwRootMode = pTestChanceDF->GetRootMode();
DH_TRACE((
DH_LVL_TRACE1,
TEXT("Run Mode for STMTEST_109, Access mode: %lx"),
dwRootMode));
}
// Get DG_STRING object pointer
if (S_OK == hr)
{
pdgu = pTestVirtualDF->GetDataGenUnicode();
DH_ASSERT(NULL != pdgu) ;
if(NULL == pdgu)
{
hr = E_FAIL;
}
}
// Get DG_INTEGER object pointer
if (S_OK == hr)
{
pdgi = pTestVirtualDF->GetDataGenInteger();
DH_ASSERT(NULL != pdgi);
if(NULL == pdgi)
{
hr = E_FAIL;
}
}
// Adds a new stream to the root storage.
if(S_OK == hr)
{
// Generate random name for stream
hr = GenerateRandomName(pdgu,MINLENGTH,MAXLENGTH,&pRootNewChildStmName);
DH_HRCHECK(hr, TEXT("GenerateRandomName")) ;
}
if (S_OK == hr)
{
// Generate random size for stream.
usErr = pdgi->Generate(&cb, cRandomMinSize, cRandomMaxSize);
if (DG_RC_SUCCESS != usErr)
{
hr = E_FAIL;
}
}
if(S_OK == hr)
{
hr = AddStream(
pTestVirtualDF,
pVirtualDFRoot,
pRootNewChildStmName,
cb,
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE,
&pvsnRootNewChildStream);
DH_HRCHECK(hr, TEXT("AddStream")) ;
if(S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::AddStream not successful, hr=0x%lx."),
hr));
}
}
// Call VirtualStmNode::Write to create random bytes in the stream. For
// our test purposes, we generate a random string of size 1 to cb using
// GenerateRandomString function.
if(S_OK == hr)
{
hr = GenerateRandomString(pdgu, cb, cb, &ptcsBuffer);
DH_HRCHECK(hr, TEXT("GenerateRandomString")) ;
}
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Write(
ptcsBuffer,
cb,
&culWritten);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::Write function wasn't successful, hr=0x%lx."),
hr));
}
}
// Attemp IStream::LockRegion. Ole's implementation doesn't have this
// function implemented and returns STG_E_INVALIDFUNCTION for the call.
if (S_OK == hr)
{
ULISet32(uliOffset, 0);
ULISet32(uliBytes, 20);
hr = pvsnRootNewChildStream->LockRegion(
uliOffset,
uliBytes,
LOCK_WRITE);
// Check STG_E_INVALIDFUNCTION returned as expected.
if (STG_E_INVALIDFUNCTION == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::LockRegion return STG_E_INVALIDFUNCTION as exp")));
hr = S_OK;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::LockRegion didn't return hr as exp, hr=0x%lx."),
hr));
hr = E_FAIL;
}
}
// Attempt IStream::Stat and check the locks supported.
// First get pMalloc that would be used to free up the name string from
// STATSTG.
if ( S_OK == hr )
{
hr = CoGetMalloc(MEMCTX_TASK, &pMalloc);
DH_HRCHECK(hr, TEXT("CoGetMalloc")) ;
}
if (S_OK == hr)
{
statStg.pwcsName = NULL;
hr = pvsnRootNewChildStream->Stat(&statStg, STATFLAG_DEFAULT);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Stat")) ;
}
// Check that locks suupported are zero.
if (S_OK == hr)
{
if(0 == statStg.grfLocksSupported)
{
DH_TRACE((DH_LVL_TRACE1, TEXT("Locks supported zero as exp.")));
}
else
{
DH_TRACE((DH_LVL_TRACE1, TEXT("Locks supported not zero as exp.")));
hr = E_FAIL;
}
}
// Release resources
if (( NULL != statStg.pwcsName) && ( NULL != pMalloc))
{
pMalloc->Free(statStg.pwcsName);
statStg.pwcsName = NULL;
}
// Attempt IStream::UnlockRegion. Ole's implementation doesn't have this
// function implemented and returns STG_E_INVALIDFUNCTION for the call.
if (S_OK == hr)
{
ULISet32(uliOffset, 0);
ULISet32(uliBytes, 20);
hr = pvsnRootNewChildStream->UnlockRegion(
uliOffset,
uliBytes,
LOCK_WRITE);
// Check STG_E_INVALIDFUNCTION returned as expected.
if (STG_E_INVALIDFUNCTION == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStm::UnlockRegion return STG_E_INVALIDFUNCTION as exp")));
hr = S_OK;
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("IStream::UnlockRegion didn't return hr as exp, hr=0x%lx."),
hr));
hr = E_FAIL;
}
}
// Attempt IStream::Stat again and check the locks supported.
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Stat(&statStg, STATFLAG_DEFAULT);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Stat")) ;
}
// Check that locks suupported are zero.
if (S_OK == hr)
{
DH_ASSERT(statStg.type == STGTY_STREAM);
if(0 == statStg.grfLocksSupported)
{
DH_TRACE((DH_LVL_TRACE1, TEXT("Locks supported zero as exp.")));
}
else
{
DH_TRACE((DH_LVL_TRACE1, TEXT("Locks supported not zero as exp.")));
fPass = FALSE;
}
}
// Release resources
if ((NULL != statStg.pwcsName) && (NULL != pMalloc))
{
pMalloc->Free(statStg.pwcsName);
statStg.pwcsName = NULL;
}
// Release stream
if (S_OK == hr)
{
hr = pvsnRootNewChildStream->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualStmNode::Close unsuccessful, hr=0x%lx.")));
}
}
// Commit root.
if(S_OK == hr)
{
hr = pVirtualDFRoot->Commit(STGC_DEFAULT);
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Commit unsuccessful, hr=0x%lx."),
hr));
}
}
// Release root
if (S_OK == hr)
{
hr = pVirtualDFRoot->Close();
if (S_OK == hr)
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close completed successfully.")));
}
else
{
DH_TRACE((
DH_LVL_TRACE1,
TEXT("VirtualCtrNode::Close unsuccessful, hr=0x%lx."),
hr));
}
}
// if everything goes well, log test as passed else failed.
if ((S_OK == hr) && (TRUE == fPass))
{
DH_LOG((LOG_PASS, TEXT("Test variation STMTEST_109 passed.")) );
}
else
{
DH_LOG((LOG_FAIL,
TEXT("Test variation STMTEST_109 failed, hr=0x%lx."),
hr) );
// test failed. make it look like it failed.
hr = FirstError (hr, E_FAIL);
}
// Cleanup
CleanupTestDocfile (&pVirtualDFRoot,
&pTestVirtualDF,
&pTestChanceDF,
S_OK == hr);
// Release pMalloc
if(NULL != pMalloc)
{
pMalloc->Release();
pMalloc = NULL;
}
// Delete strings
if(NULL != pRootNewChildStmName)
{
delete pRootNewChildStmName;
pRootNewChildStmName = NULL;
}
// Delete temp buffer
if(NULL != ptcsBuffer)
{
delete [] ptcsBuffer;
ptcsBuffer = NULL;
}
// Stop logging the test
DH_TRACE((DH_LVL_TRACE1, TEXT("Test variation STMTEST_109 finished")) );
DH_TRACE((DH_LVL_TRACE1, TEXT("--------------------------------------------")) );
return hr;
}