|
|
//+--------------------------------------------------------------
//
// 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; ULONGLONG 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; }
|