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

891 lines
25 KiB
C++

#include <pch.cxx>
#include <funcs.hxx>
#include <dfentry.hxx>
DECLARE_INFOLEVEL(ol)
#define ntfsChk(a) olChk(a)
#define ntfsErr(a,b) olErr(a,b)
#define ntfsDebugOut(a) olDebugOut(a)
#define ntfsAssert(a) olAssert(a)
//+---------------------------------------------------------------------------
//
// Function: DfOpenStorageEx
//
// Synopsis: Open storage and stream objects
//
// Arguments: [pwcsUsersName] - pathanme of the file
// [fCreateAPI] - create or open
// [grfMode] - open mode flags
// [grfAttrs] - reserved
// [stgfmt] - storage format
// [pSecurity] - reserved
// [pTransaction] - reserved
// [riid] - GUID of interface pointer to return
// [ppObjectOpen] - interface pointer to return
// Returns: Appropriate status code
//
// History: 12-Jul-95 HenryLee Created
//
//----------------------------------------------------------------------------
STDAPI DfOpenStorageEx (
const WCHAR* pwcsUsersName,
BOOL fCreateAPI, // create vs open
DWORD grfMode,
DWORD stgfmt, // enum
DWORD grfAttrs, // reserved
STGOPTIONS *pStgOptions,
void * reserved,
WCHAR * pwcsNameSnapshot,
REFIID riid,
void ** ppObjectOpen)
{
HRESULT sc = S_OK;
DWORD dwFullPathLen;
WCHAR awcsFullName[_MAX_PATH], *pwcsFile;
//
// The ANY and STORAGE formats recursivly call back through here
// for the correct real format (DOCFILE, NATIVE or FILE). We only call
// GetFullPathName on real formats, to avoid redundant calls as we
// recurse.
// This then *requires* that the ANY and STORAGE must recurse (i.e. can't
// call NFFOpen or NSS directly) because the filename has not been
// properly prepared.
//
// For STGFMT_DOCFILE, let the docfile layer handle name checking
//
if(STGFMT_ANY != stgfmt &&
STGFMT_STORAGE != stgfmt &&
STGFMT_DOCFILE != stgfmt)
{
dwFullPathLen = GetFullPathNameW(pwcsUsersName, _MAX_PATH,
awcsFullName,&pwcsFile);
if (dwFullPathLen == 0)
{
DWORD dwErr = GetLastError();
// In some circumstances (name == " ", for instance),
// GetFullPathNameW can return 0 and GetLastError returns 0.
// We want to return STG_E_INVALIDNAME for these.
if (dwErr != NOERROR)
{
ntfsErr(EH_Err, Win32ErrorToScode(dwErr));
}
else
{
ntfsErr(EH_Err, STG_E_INVALIDNAME);
}
}
else if (dwFullPathLen > _MAX_PATH)
ntfsErr(EH_Err, STG_E_PATHNOTFOUND);
}
//-----------------------------------------
// Switch on STGFMT_
// STORAGE, NATIVE, DOCFILE, FILE, ANY
//
switch(stgfmt)
{
case STGFMT_FILE:
{
ntfsChk( NFFOpen( awcsFullName, grfMode, NFFOPEN_NORMAL,
fCreateAPI, riid, ppObjectOpen) );
} // case STGFMT_FILE
break;
case STGFMT_ANY:
{
DWORD stgfmt=STGFMT_STORAGE;
//
// Attempting to CREATE a Storage with STGFMT_ANY is ambiguous,
// On NTFS either STGFMT_NATIVE or STGFMT_FILE could be appropriate,
// and is therefore invalid.
//
if (fCreateAPI)
ntfsChk (STG_E_INVALIDPARAMETER);
//
// If the file is a storage then try STGFMT_STORAGE.
// Otherwise try STGFMT_FILE.
// If StgIsStorageFile() error'ed go ahead into the STGFMT_STORAGE
// for consistant error return values.
//
if( S_OK == CNtfsStorage::IsNffAppropriate( pwcsUsersName ) )
stgfmt = STGFMT_FILE;
sc = DfOpenStorageEx (pwcsUsersName, fCreateAPI, grfMode, stgfmt,
grfAttrs, pStgOptions, reserved,
pwcsNameSnapshot, riid, ppObjectOpen);
ntfsChk(sc);
} // case STGFMT_ANY;
break;
default:
ntfsErr (EH_Err, STG_E_INVALIDPARAMETER);
break;
}
EH_Err:
return sc;
};
//+---------------------------------------------------------------------------
//
// Function: StgCreateStorageEx, public
//
// Synopsis: Creates a storage or stream object
//
// Arguments: [pwcsName] - pathname of file
// [grfMode] - open mode flags
// [stgfmt] - storage format
// [grfAttrs] - reserved
// [pSecurity] - reserved
// [pTransaction] - reserved
// [riid] - GUID of interface pointer to return
// [ppObjectOpen] - interface pointer to return
//
// Returns: Appropriate status code
//
// History: 12-Jul-95 HenryLee Created
//
//----------------------------------------------------------------------------
typedef HRESULT (*PFNStgCreateStorageEx)( const WCHAR* pwcsName, DWORD grfMode, DWORD stgfmt,
DWORD grfAttrs, void *pSecurity, void *pTransaction,
REFIID riid, void **ppObjectOpen );
typedef HRESULT (*PFNStgOpenStorageEx)( const WCHAR *pwcsName, DWORD grfMode, DWORD stgfmt,
DWORD grfAttrs, void *pSecurity, void *pTransaction,
REFIID riid, void **ppObjectOpen );
HINSTANCE HInstOle32()
{
static HINSTANCE hinstOLE32 = NULL;
if( NULL == hinstOLE32 )
hinstOLE32 = LoadLibrary( TEXT("ole32.dll") );
return( hinstOLE32 );
}
WINOLEAPI StgCreateStorageEx (IN const WCHAR* pwcsName,
IN DWORD grfMode,
IN DWORD stgfmt, // enum
IN DWORD grfAttrs, // reserved
IN STGOPTIONS * pStgOptions,
IN void * reserved,
IN REFIID riid,
OUT void ** ppObjectOpen)
{
HRESULT sc = S_OK;
WCHAR awcsTmpPath[_MAX_PATH];
ntfsChk(ValidatePtrBuffer(ppObjectOpen));
*ppObjectOpen = NULL;
if (grfAttrs != 0)
ntfsErr(EH_Err, STG_E_INVALIDFLAG);
if ((grfMode & STGM_RDWR) == STGM_READ ||
(grfMode & (STGM_DELETEONRELEASE | STGM_CONVERT)) ==
(STGM_DELETEONRELEASE | STGM_CONVERT))
ntfsErr(EH_Err, STG_E_INVALIDFLAG);
if( STGFMT_FILE == stgfmt
&&
(IID_IPropertySetStorage == riid || IID_IStorage == riid || IID_IPropertyBagEx == riid)
)
{
ntfsChk (DfOpenStorageEx (pwcsName, TRUE, grfMode, stgfmt, grfAttrs,
pStgOptions, reserved, NULL, riid, ppObjectOpen));
}
else
{
static PFNStgCreateStorageEx pfnStgCreateStorageEx = NULL;
if( NULL == pfnStgCreateStorageEx )
pfnStgCreateStorageEx = (PFNStgCreateStorageEx) GetProcAddress( HInstOle32(), "StgCreateStorageEx" );
if( NULL == pfnStgCreateStorageEx )
ntfsChk( E_FAIL );
ntfsChk( pfnStgCreateStorageEx( pwcsName, grfMode, stgfmt, grfAttrs, pStgOptions, reserved, riid, ppObjectOpen ));
}
ntfsDebugOut((DEB_TRACE, "Out StgCreateStorageEx => %p\n", *ppObjectOpen));
EH_Err:
return sc;
}
//+---------------------------------------------------------------------------
//
// Function: StgOpenStorageEx
//
// Synopsis: Open storage and stream objects
//
// Arguments: [pwcsName] - pathanme of the file
// [grfMode] - open mode flags
// [grfAttrs] - reserved
// [stgfmt] - storage format
// [pSecurity] - reserved
// [pTransaction] - reserved
// [riid] - GUID of interface pointer to return
// [ppObjectOpen] - interface pointer to return
// Returns: Appropriate status code
//
// History: 12-Jul-95 HenryLee Created
//
//----------------------------------------------------------------------------
WINOLEAPI StgOpenStorageEx (IN const WCHAR* pwcsName,
IN DWORD grfMode,
IN DWORD stgfmt, // enum
IN DWORD grfAttrs, // reserved
IN STGOPTIONS * pStgOptions,
IN void * reserved,
IN REFIID riid,
OUT void ** ppObjectOpen)
{
HRESULT sc = S_OK;
WCHAR awcsTmpPath[_MAX_PATH];
WCHAR * pwcsNameSnapshot = NULL;
ntfsDebugOut((DEB_TRACE, "In StgOpenStorageEx(%ws, %p, %p, %p, %p)\n",
pwcsName, grfMode, stgfmt, riid, ppObjectOpen));
ntfsChk(ValidatePtrBuffer(ppObjectOpen));
*ppObjectOpen = NULL;
if (pStgOptions!= NULL || reserved != NULL)
ntfsErr (EH_Err, STG_E_INVALIDPARAMETER);
if (grfAttrs != 0)
ntfsErr(EH_Err, STG_E_INVALIDFLAG);
ntfsChk (ValidateNameW (pwcsName, _MAX_PATH));
if( (IID_IPropertySetStorage == riid || IID_IStorage == riid || IID_IPropertyBagEx == riid)
&&
( STGFMT_FILE == stgfmt
||
STGFMT_ANY == stgfmt && S_OK != StgIsStorageFile(pwcsName)
)
)
{
ntfsChk (DfOpenStorageEx (pwcsName, FALSE, grfMode, stgfmt, grfAttrs,
pStgOptions, reserved, pwcsNameSnapshot, riid, ppObjectOpen));
}
else
{
static PFNStgOpenStorageEx pfnStgOpenStorageEx = NULL;
if( NULL == pfnStgOpenStorageEx )
pfnStgOpenStorageEx = (PFNStgOpenStorageEx) GetProcAddress( HInstOle32(), "StgOpenStorageEx" );
if( NULL == pfnStgOpenStorageEx )
ntfsChk( E_FAIL );
ntfsChk( pfnStgOpenStorageEx( pwcsName, grfMode, stgfmt, grfAttrs, pStgOptions, reserved,
riid, ppObjectOpen ));
}
ntfsDebugOut((DEB_TRACE, "Out StgOpenStorageEx => %p\n", *ppObjectOpen));
EH_Err:
return sc;
}
// Copied from stg\docfile\funcs.cxx
#ifdef WIN32
SCODE Win32ErrorToScode(DWORD dwErr)
{
olAssert((dwErr != NO_ERROR) &&
aMsg("Win32ErrorToScode called on NO_ERROR"));
SCODE sc = STG_E_UNKNOWN;
switch (dwErr)
{
case ERROR_INVALID_FUNCTION:
sc = STG_E_INVALIDFUNCTION;
break;
case ERROR_FILE_NOT_FOUND:
sc = STG_E_FILENOTFOUND;
break;
case ERROR_PATH_NOT_FOUND:
sc = STG_E_PATHNOTFOUND;
break;
case ERROR_TOO_MANY_OPEN_FILES:
sc = STG_E_TOOMANYOPENFILES;
break;
case ERROR_ACCESS_DENIED:
case ERROR_NETWORK_ACCESS_DENIED:
sc = STG_E_ACCESSDENIED;
break;
case ERROR_INVALID_HANDLE:
sc = STG_E_INVALIDHANDLE;
break;
case ERROR_NOT_ENOUGH_MEMORY:
sc = STG_E_INSUFFICIENTMEMORY;
break;
case ERROR_NO_MORE_FILES:
sc = STG_E_NOMOREFILES;
break;
case ERROR_WRITE_PROTECT:
sc = STG_E_DISKISWRITEPROTECTED;
break;
case ERROR_SEEK:
sc = STG_E_SEEKERROR;
break;
case ERROR_WRITE_FAULT:
sc = STG_E_WRITEFAULT;
break;
case ERROR_READ_FAULT:
sc = STG_E_READFAULT;
break;
case ERROR_SHARING_VIOLATION:
sc = STG_E_SHAREVIOLATION;
break;
case ERROR_LOCK_VIOLATION:
sc = STG_E_LOCKVIOLATION;
break;
case ERROR_HANDLE_DISK_FULL:
case ERROR_DISK_FULL:
sc = STG_E_MEDIUMFULL;
break;
case ERROR_FILE_EXISTS:
case ERROR_ALREADY_EXISTS:
sc = STG_E_FILEALREADYEXISTS;
break;
case ERROR_INVALID_PARAMETER:
sc = STG_E_INVALIDPARAMETER;
break;
case ERROR_INVALID_NAME:
case ERROR_BAD_PATHNAME:
case ERROR_FILENAME_EXCED_RANGE:
sc = STG_E_INVALIDNAME;
break;
case ERROR_INVALID_FLAGS:
sc = STG_E_INVALIDFLAG;
break;
default:
sc = WIN32_SCODE(dwErr);
break;
}
return sc;
}
#endif
//+--------------------------------------------------------------
//
// Function: ValidateSNB, private
//
// Synopsis: Validates SNB memory
//
// Arguments: [snb] - SNB
//
// Returns: Appropriate status code
//
// History: 10-Jun-92 DrewB Created
//
//---------------------------------------------------------------
#include <docfilep.hxx>
// ***** From stg\docfile\funcs.cxx
SCODE ValidateSNB(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;
}
//+--------------------------------------------------------------
//
// Function: CheckName, public
//
// Synopsis: Checks name for illegal characters and length
//
// Arguments: [pwcsName] - Name
//
// Returns: Appropriate status code
//
// History: 11-Feb-92 DrewB Created
// 04-Dec-95 SusiA Optimized
//
//---------------------------------------------------------------
// ***** From stg\docfile\funcs.cxx
#ifdef OLEWIDECHAR
SCODE CheckName(WCHAR const *pwcsName)
{
LPCWSTR pChar;
//Each character's position in the array is detrmined by its ascii numeric
//value. ":" is 58, so bit 58 of the array will be 1 if ":" is illegal.
//32bits per position in the array, so 58/32 is in Invalid[1].
//58%32 = 28th bit ( 0x04000000 ) in Invalid[1].
/* Invalid characters: : / ! \ */
static ULONG const Invalid[128/32] =
{0x00000000,0x04008002,0x10000000,0x00000000};
SCODE sc = STG_E_INVALIDNAME;
olDebugOut((DEB_ITRACE, "In CheckName(%ws)\n", pwcsName));
__try
{
for (pChar = (LPCWSTR)pwcsName;
pChar <= (LPCWSTR) &pwcsName[CWCMAXPATHCOMPLEN];
pChar++)
{
if (*pChar == L'\0')
{
sc = S_OK;
break; // Success
}
// Test to see if this is an invalid character
if (*pChar < 128 &&
// All values above 128 are valid
(Invalid[*pChar / 32] & (1 << (*pChar % 32))) != 0)
// check to see if this character's bit is set
{
break; // Failure: invalid Char
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
olDebugOut((DEB_ITRACE, "Out CheckName\n"));
return sc;
}
#endif
/*
// Forwarders to the nt5props.dll version of the property APIs.
EXTERN_C HRESULT
PrivPropVariantCopy ( PROPVARIANT * pvarDest, const PROPVARIANT * pvarSrc )
{
return( PropVariantCopy( pvarDest, pvarSrc ));
}
EXTERN_C HRESULT
PrivPropVariantClear ( PROPVARIANT * pvar )
{
return( PropVariantClear( pvar ));
}
EXTERN_C HRESULT
PrivFreePropVariantArray ( ULONG cVariants, PROPVARIANT * rgvars )
{
return( FreePropVariantArray( cVariants, rgvars ));
}
EXTERN_C ULONG
PrivStgPropertyLengthAsVariant( IN SERIALIZEDPROPERTYVALUE const *pprop,
IN ULONG cbprop, IN USHORT CodePage,
IN BYTE flags )
{
return( StgPropertyLengthAsVariant( pprop, cbprop, CodePage, flags ));
}
EXTERN_C SERIALIZEDPROPERTYVALUE *
PrivStgConvertVariantToProperty(
IN PROPVARIANT const *pvar,
IN USHORT CodePage,
OPTIONAL OUT SERIALIZEDPROPERTYVALUE *pprop,
IN OUT ULONG *pcb,
IN PROPID pid,
IN BOOLEAN fVariantVectorOrArray, // Used for recursive calls
OPTIONAL OUT ULONG *pcIndirect)
{
return( StgConvertVariantToProperty( pvar, CodePage, pprop, pcb, pid, fVariantVectorOrArray, pcIndirect ));
}
*/
//+--------------------------------------------------------------
//
// Function: VerifyPerms, private
//
// Synopsis: Checks flags to see if they are valid
//
// Arguments: [grfMode] - Permissions
// [fRoot] - TRUE if checking root storage
//
// Returns: Appropriate status code
//
// Notes: This routine is called when opening a root storage
// or a subelement. When changing root permissions,
// use the fRoot flag to preserve compatibily for
// return codes when opening subelements
//
// History: 19-Mar-92 DrewB Created
//
//---------------------------------------------------------------
SCODE VerifyPerms(DWORD grfMode, BOOL fRoot)
{
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_NOSCRATCH |
#ifndef DISABLE_NOSNAPSHOT
STGM_NOSNAPSHOT |
#endif
#if WIN32 >= 300
STGM_EDIT_ACCESS_RIGHTS |
#endif
STGM_FAILIFTHERE | STGM_DELETEONRELEASE)))
olErr(EH_Err, STG_E_INVALIDFLAG);
// If priority is specified...
if (grfMode & STGM_PRIORITY)
{
// Make sure no priority-denied permissions are specified
if ((grfMode & STGM_RDWR) == STGM_WRITE ||
(grfMode & STGM_RDWR) == STGM_READWRITE ||
(grfMode & STGM_TRANSACTED))
olErr(EH_Err, STG_E_INVALIDFLAG);
}
// 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 &&
#ifdef DIRECTWRITERLOCK
(!fRoot || (grfMode & STGM_DENY) != STGM_SHARE_DENY_NONE) &&
#endif
(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
#ifdef DIRECTWRITERLOCK
if ((grfMode & STGM_DENY) != STGM_SHARE_EXCLUSIVE &&
(!fRoot || (grfMode & STGM_DENY) != STGM_SHARE_DENY_WRITE))
#else
if ((grfMode & STGM_DENY) != STGM_SHARE_EXCLUSIVE)
#endif
{
// Can't allow others to have any access
olErr(EH_Err, STG_E_INVALIDFLAG);
}
}
}
//If this is not a root open, we can't pass STGM_NOSCRATCH or
// STGM_NOSNAPSHOT
if (!fRoot && (grfMode & (STGM_NOSCRATCH | STGM_NOSNAPSHOT)))
{
olErr(EH_Err, STG_E_INVALIDFLAG);
}
if (grfMode & STGM_NOSCRATCH)
{
if (((grfMode & STGM_RDWR) == STGM_READ) ||
((grfMode & STGM_TRANSACTED) == 0))
{
olErr(EH_Err, STG_E_INVALIDFLAG);
}
}
if (grfMode & STGM_NOSNAPSHOT)
{
if (((grfMode & STGM_DENY) == STGM_SHARE_EXCLUSIVE) ||
((grfMode & STGM_DENY) == STGM_SHARE_DENY_WRITE) ||
((grfMode & STGM_TRANSACTED) == 0) ||
((grfMode & STGM_NOSCRATCH) != 0) ||
((grfMode & STGM_CREATE) != 0) ||
((grfMode & STGM_CONVERT) != 0))
{
olErr(EH_Err, STG_E_INVALIDFLAG);
}
}
olDebugOut((DEB_ITRACE, "Out VerifyPerms\n"));
// Fall through
EH_Err:
return sc;
}
//+--------------------------------------------------------------
//
// Function: StgIsStorageFileHandle, private
//
// Synopsis: Determines whether a handle is open on a storage file.
// Spun off from StgIsStorageFile. Internaly we use this
//
// Arguments: [hf] - Open File Handle (caller must seek it to 0)
//
// Returns: S_OK, S_FALSE or error codes
//
// History: 07-May-98 MikeHill Created
// 05-June-98 BChapman Return Errors not just S_FALSE.
// Add optional Overlapped pointer.
//
//---------------------------------------------------------------
STDAPI StgIsStorageFileHandle( HANDLE hf, LPOVERLAPPED povlp )
{
DWORD cbRead;
BYTE stgHeader[sizeof(SStorageFile)];
SCODE sc;
LONG status;
OVERLAPPED ovlp;
FillMemory( stgHeader, sizeof(SStorageFile), 0xDE );
if (povlp == NULL)
{
ovlp.Offset = 0;
ovlp.OffsetHigh = 0;
ovlp.hEvent = NULL;
}
if( !ReadFile( hf,
&stgHeader,
sizeof( stgHeader ),
&cbRead,
(povlp == NULL) ? &ovlp : povlp ) )
{
if( NULL != povlp )
{
status = GetLastError();
if( ERROR_IO_PENDING == status)
{
status = ERROR_SUCCESS;
if( !GetOverlappedResult( hf, povlp, &cbRead, TRUE ) )
status = GetLastError();
}
if(ERROR_SUCCESS != status && ERROR_HANDLE_EOF != status)
olChk( HRESULT_FROM_WIN32( status ) );
}
else
olErr( EH_Err, LAST_STG_SCODE );
}
// Don't worry about short reads. If the read is short then
// the signature checks will fail.
sc = CheckSignature( ((SStorageFile*)stgHeader)->abSig );
if(S_OK == sc)
goto EH_Err; // Done, return "Yes"
olChk(sc);
// It didn't error. sc != S_OK then it
// Must be S_FALSE.
olAssert(S_FALSE == sc);
EH_Err:
if( (STG_E_OLDFORMAT == sc) || (STG_E_INVALIDHEADER == sc) )
sc = S_FALSE;
return sc;
}
//+---------------------------------------------------------------------------
//
// Function: CheckSignature, private
//
// Synopsis: Checks the given memory against known signatures
//
// Arguments: [pb] - Pointer to memory to check
//
// Returns: S_OK - Current signature
// S_FALSE - Beta 2 signature, but still successful
// Appropriate status code
//
// History: 23-Jul-93 DrewB Created from header.cxx code
//
//----------------------------------------------------------------------------
//Identifier for first bytes of Beta 1 Docfiles
const BYTE SIGSTG_B1[] = {0xd0, 0xcf, 0x11, 0xe0, 0x0e, 0x11, 0xfc, 0x0d};
const USHORT CBSIGSTG_B1 = sizeof(SIGSTG_B1);
//Identifier for first bytes of Beta 2 Docfiles
const BYTE SIGSTG_B2[] = {0x0e, 0x11, 0xfc, 0x0d, 0xd0, 0xcf, 0x11, 0xe0};
const BYTE CBSIGSTG_B2 = sizeof(SIGSTG_B2);
SCODE CheckSignature(BYTE *pb)
{
SCODE sc;
olDebugOut((DEB_ITRACE, "In CheckSignature(%p)\n", pb));
// Check for ship Docfile signature first
if (memcmp(pb, SIGSTG, CBSIGSTG) == 0)
sc = S_OK;
// Check for Beta 2 Docfile signature
else if (memcmp(pb, SIGSTG_B2, CBSIGSTG_B2) == 0)
sc = S_FALSE;
// Check for Beta 1 Docfile signature
else if (memcmp(pb, SIGSTG_B1, CBSIGSTG_B1) == 0)
sc = STG_E_OLDFORMAT;
else
sc = STG_E_INVALIDHEADER;
olDebugOut((DEB_ITRACE, "Out CheckSignature => %lX\n", sc));
return sc;
}
//+---------------------------------------------------------------------------
//
// Function: dfwcsnicmp, public
//
// Synopsis: wide character string compare that interoperates with what
// we did on 16-bit windows.
//
// Arguments: [wcsa] -- First string
// [wcsb] -- Second string
// [len] -- Length to compare to
//
// Returns: > 0 if wcsa > wcsb
// < 0 if wcsa < wcsb
// 0 is wcsa == wcsb
//
// History: 11-May-95 PhilipLa Created
// 22-Nov-95 SusiA Optimize comparisons
//
// Notes: This function is necessary because on 16-bit windows our
// wcsnicmp function converted everything to uppercase and
// compared the strings, whereas the 32-bit runtimes convert
// everything to lowercase and compare. This means that the
// sort order is different for string containing [\]^_`
//
//----------------------------------------------------------------------------
int dfwcsnicmp(const WCHAR *wcsa, const WCHAR *wcsb, size_t len)
{
if (!len)
return 0;
while (--len && *wcsa &&
( *wcsa == *wcsb ||
CharUpperW((LPWSTR)*wcsa) == CharUpperW((LPWSTR)*wcsb)))
{
wcsa++;
wcsb++;
}
return (int)(LONG_PTR)CharUpperW((LPWSTR)*wcsa) -
(int)(LONG_PTR)CharUpperW((LPWSTR)*wcsb);
}
//+---------------------------------------------------------------------------
//
// Member: ValidateNameW, public
//
// Synopsis: Validate that a name is valid and no longer than the
// size specified.
//
// Arguments: [pwcsName] -- Pointer to wide character string
// [cchMax] -- Maximum length for string
//
// Returns: Appropriate status code
//
// History: 23-Nov-98 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
SCODE ValidateNameW(LPCWSTR pwcsName, UINT cchMax)
{
SCODE sc = S_OK;
#if WIN32 == 200
if (IsBadReadPtrW(pwcsName, sizeof(WCHAR)))
sc = STG_E_INVALIDNAME;
#else
if (IsBadStringPtrW(pwcsName, cchMax))
sc = STG_E_INVALIDNAME;
#endif
else
{
__try
{
if ((UINT)lstrlenW(pwcsName) >= cchMax)
sc = STG_E_INVALIDNAME;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
sc = STG_E_INVALIDNAME;
}
}
return sc;
}