windows-nt/Source/XPSP1/NT/com/ole32/stg/ref/funcs.cxx
2020-09-26 16:20:57 +08:00

391 lines
10 KiB
C++

//+--------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: funcs.cxx
//
// Contents: Generic DocFile support functions
//
// Functions: ModeToTFlags
// CheckName
// wcsdup
// VerifyPerms
//
//---------------------------------------------------------------
#include "dfhead.cxx"
//+--------------------------------------------------------------
//
// Function: ModeToDFlags, private
//
// Synopsis: Translates STGM flags to DF flags
//
// Arguments: [dwModeFlags]
//
// Returns: DF_*
//
//---------------------------------------------------------------
DFLAGS ModeToDFlags(DWORD const dwModeFlags)
{
DFLAGS df;
olDebugOut((DEB_ITRACE, "In ModeToDFlags(%lX)\n", dwModeFlags));
if ((dwModeFlags & STGM_TRANSACTED) == 0)
df = DF_DIRECT;
else
df = DF_TRANSACTED;
if ((dwModeFlags & STGM_TRANSACTED) &&
(dwModeFlags & STGM_PRIORITY) == 0 &&
(dwModeFlags & STGM_DENY) != STGM_SHARE_DENY_WRITE &&
(dwModeFlags & STGM_DENY) != STGM_SHARE_EXCLUSIVE)
df |= DF_INDEPENDENT;
switch(dwModeFlags & STGM_RDWR)
{
case STGM_READ:
df |= DF_READ;
break;
case STGM_WRITE:
df |= DF_WRITE;
break;
case STGM_READWRITE:
df |= DF_READWRITE;
break;
default:
olAssert(FALSE);
break;
}
switch(dwModeFlags & STGM_DENY)
{
case STGM_SHARE_DENY_READ:
df |= DF_DENYREAD;
break;
case STGM_SHARE_DENY_WRITE:
df |= DF_DENYWRITE;
break;
case STGM_SHARE_EXCLUSIVE:
df |= DF_DENYALL;
break;
// Default is deny none
}
if (dwModeFlags & STGM_PRIORITY)
df |= DF_PRIORITY;
olDebugOut((DEB_ITRACE, "Out ModeToDFlags => %lX\n", df));
return df;
}
//+--------------------------------------------------------------
//
// Function: DFlagsToMode, private
//
// Synopsis: Converts the read/write/denials/transacted/priority
// to STGM flags
//
// Arguments: [df] - DFlags
//
// Returns: STGM flags
//
//---------------------------------------------------------------
DWORD DFlagsToMode(DFLAGS const df)
{
DWORD dwMode;
olDebugOut((DEB_ITRACE, "In DFlagsToMode(%X)\n", df));
if (P_READ(df))
if (P_WRITE(df))
dwMode = STGM_READWRITE;
else
dwMode = STGM_READ;
else if (P_WRITE(df))
dwMode = STGM_WRITE;
// Must have either read or write, so no else
if (P_DENYREAD(df))
if (P_DENYWRITE(df))
dwMode |= STGM_SHARE_EXCLUSIVE;
else
dwMode |= STGM_SHARE_DENY_READ;
else if (P_DENYWRITE(df))
dwMode |= STGM_SHARE_DENY_WRITE;
else
dwMode |= STGM_SHARE_DENY_NONE;
if (P_TRANSACTED(df))
dwMode |= STGM_TRANSACTED;
if (P_PRIORITY(df))
dwMode |= STGM_PRIORITY;
olDebugOut((DEB_ITRACE, "Out DFlagsToMode\n"));
return dwMode;
}
//+--------------------------------------------------------------
//
// Function: VerifyPerms, private
//
// Synopsis: Checks flags to see if they are valid
//
// Arguments: [grfMode] - Permissions
//
// Returns: Appropriate status code
//
//---------------------------------------------------------------
SCODE VerifyPerms(DWORD grfMode)
{
SCODE sc = S_OK;
olDebugOut((DEB_ITRACE, "In VerifyPerms(%lX)\n", grfMode));
// Check for valid flags
if ((grfMode & STGM_RDWR) > STGM_READWRITE ||
(grfMode & STGM_DENY) > STGM_SHARE_DENY_NONE ||
(grfMode & ~(STGM_RDWR | STGM_DENY | STGM_DIRECT | STGM_TRANSACTED |
STGM_PRIORITY | STGM_CREATE | STGM_CONVERT |
STGM_FAILIFTHERE | STGM_DELETEONRELEASE)))
olErr(EH_Err, STG_E_INVALIDFLAG);
// We don't support these modes
if (grfMode & (STGM_PRIORITY|STGM_TRANSACTED|STGM_SIMPLE))
{
olAssert( FALSE &&
aMsg("Unsupported feature of reference implemention called"));
return STG_E_INVALIDFUNCTION;
}
// Check to make sure only one existence flag is specified
// FAILIFTHERE is zero so it can't be checked
if ((grfMode & (STGM_CREATE | STGM_CONVERT)) ==
(STGM_CREATE | STGM_CONVERT))
olErr(EH_Err, STG_E_INVALIDFLAG);
// If not transacted and not priority, you can either be
// read-only deny write or read-write deny all
if ((grfMode & (STGM_TRANSACTED | STGM_PRIORITY)) == 0)
{
if ((grfMode & STGM_RDWR) == STGM_READ)
{
// we're asking for read-only access
if ((grfMode & STGM_DENY) != STGM_SHARE_EXCLUSIVE &&
(grfMode & STGM_DENY) != STGM_SHARE_DENY_WRITE)
{
// Can't allow others to have write access
olErr(EH_Err, STG_E_INVALIDFLAG);
}
}
else
{
// we're asking for write access
if ((grfMode & STGM_DENY) != STGM_SHARE_EXCLUSIVE)
{
// Can't allow others to have any access
olErr(EH_Err, STG_E_INVALIDFLAG);
}
}
}
olDebugOut((DEB_ITRACE, "Out VerifyPerms\n"));
// Fall through
EH_Err:
return sc;
}
//+--------------------------------------------------------------
//
// Function: wcsdup, public
//
// Synopsis: Duplicates a WCHAR string
//
// Arguments: [pwcs] - String
//
// Returns: Pointer to new string or Appropriate status code
//
//---------------------------------------------------------------
WCHAR * __cdecl wcsdup(WCHAR const *pwcs)
{
WCHAR *pwcsNew;
olDebugOut((DEB_ITRACE, "In wcsdup(%ws)\n", pwcs));
pwcsNew = new WCHAR[wcslen(pwcs)+1];
if (pwcsNew == NULL)
return NULL;
wcscpy(pwcsNew, pwcs);
olDebugOut((DEB_ITRACE, "Out wcsdup => %p\n", pwcsNew));
return pwcsNew;
}
//+--------------------------------------------------------------
//
// Function: ValidateSNBW
//
// Synopsis: Validates SNB memory
//
// Arguments: [snb] - SNB
//
// Returns: Appropriate status code
//
//---------------------------------------------------------------
#ifdef _UNICODE
SCODE ValidateSNBW(SNBW snb)
{
SCODE sc;
olDebugOut((DEB_ITRACE, "In ValidateSNB(%p)\n", snb));
for (;;)
{
olChk(ValidatePtrBuffer(snb));
if (*snb == NULL)
break;
olChk(ValidateNameW(*snb, CWCMAXPATHCOMPLEN));
snb++;
}
olDebugOut((DEB_ITRACE, "Out ValidateSNB\n"));
return S_OK;
EH_Err:
return sc;
}
#endif // ifdef _UNICODE
//+--------------------------------------------------------------
//
// Function: CheckWName, public
//
// Synopsis: Checks name for illegal characters and length
//
// Arguments: [pwcsName] - Name
//
// Returns: Appropriate status code
//
//---------------------------------------------------------------
#ifdef _UNICODE
WCHAR wcsInvalid[] = { '\\', '/', ':', '!','\0' };
SCODE CheckWName(WCHAR const *pwcsName)
{
SCODE sc;
olDebugOut((DEB_ITRACE, "In CheckWName(%s)\n", pwcsName));
if (FAILED(sc = ValidateNameW(pwcsName, CBMAXPATHCOMPLEN)))
return sc;
// >= is used because the max len includes the null terminator
if (wcslen(pwcsName) >= CWCMAXPATHCOMPLEN)
return STG_E_INVALIDNAME;
for (; *pwcsName; pwcsName++)
{
if ( wcschr(wcsInvalid, *pwcsName) )
return STG_E_INVALIDNAME;
}
olDebugOut((DEB_ITRACE, "Out CheckWName\n"));
return S_OK;
}
#else // validation done in ascii layer already
#define CheckWName(pwcsName) (S_OK)
#endif // ifdef _UNICODE
//+--------------------------------------------------------------
//
// Function: CopyDStreamToDStream
//
// Synopsis: Copies the contents of a stream to another stream
//
// Arguments: [pstFrom] - Stream to copy from
// [pstTo] - Stream to copy to
//
// Returns: Appropriate status code
//
// Notes: This function may fail due to out of memory. It
// may not be used by callers who must not fail due
// to out of memory.
//
// This function does not check permissions
// for write in the to streams.
//
//---------------------------------------------------------------
SCODE CopyStreamToStream(CDirectStream *pstFrom,
CDirectStream *pstTo)
{
BYTE *pbBuffer;
SCODE sc;
ULONG cbRead, cbWritten, cbSize, cbPos;
// Set destination size for contiguity
pstFrom->GetSize(&cbSize);
olChk(pstTo->SetSize(cbSize));
// We're allowed to fail due to out of memory
olMem(pbBuffer = new BYTE[STREAMBUFFERSIZE]);
// Copy between streams
cbPos = 0;
for (;;)
{
olChkTo(EH_pbBuffer,
pstFrom->ReadAt(cbPos, pbBuffer, STREAMBUFFERSIZE,
(ULONG STACKBASED *)&cbRead));
if (cbRead == 0) // EOF
break;
olChkTo(EH_pbBuffer,
pstTo->WriteAt(cbPos, pbBuffer, cbRead,
(ULONG STACKBASED *)&cbWritten));
if (cbRead != cbWritten)
olErr(EH_Err, STG_E_WRITEFAULT);
cbPos += cbWritten;
}
delete pbBuffer;
return S_OK;
EH_pbBuffer:
delete pbBuffer;
EH_Err:
return sc;
}
//+--------------------------------------------------------------
//
// Function: NameInSNB, private
//
// Synopsis: Determines whether the given name is in the SNB
//
// Arguments: [dfn] - Name
// [snb] - SNB
//
// Returns: S_OK or S_FALSE
//
//---------------------------------------------------------------
SCODE NameInSNB(CDfName const *dfn, SNBW snb)
{
SCODE sc = S_FALSE;
olDebugOut((DEB_ITRACE, "In NameInSNB(%ws, %p)\n", dfn, snb));
TRY
{
for (; *snb; snb++)
if (dfwcsnicmp((WCHAR *)dfn->GetBuffer(), (WCHAR *)*snb,
dfn->GetLength()) == 0)
{
sc = S_OK;
break;
}
}
CATCH(CException, e)
{
sc = e.GetErrorCode();
}
END_CATCH
olDebugOut((DEB_ITRACE, "Out NameInSNB\n"));
return sc;
}