NT4/private/ole32/stg/fsstg/stgsupp.cxx
2020-09-30 17:12:29 +02:00

253 lines
7.5 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: stgsupp.cxx
//
// Contents: Storage create/open support routines
//
// History: 14-Jul-93 DrewB Created
//
//----------------------------------------------------------------------------
#include "headers.cxx"
#pragma hdrstop
#include <stgutil.hxx>
#include <ntlkb.hxx>
#include <dfentry.hxx>
// Docfiles require read permission on the file so give it
#define PERM_MASK (STGM_READ | STGM_WRITE | STGM_READWRITE)
#define FORCE_READ(grfMode) \
if (((grfMode) & PERM_MASK) == STGM_WRITE) \
(grfMode) = ((grfMode) & ~PERM_MASK) | STGM_READWRITE; \
else 1
//+---------------------------------------------------------------------------
//
// Function: CreateStorageType, public
//
// Synopsis: Creates a storage of the appropriate type
//
// Arguments: [hParent] - Parent handle or NULL
// [pwcsName] - Name or path
// [grfMode] - Mode
// [h] - Handle of storage if already open or NULL
// [dwStgFmt] - Type of storage
// [pssSecurity] - Security
// [ppstg] - New storage return
//
// Returns: Appropriate status code
//
// Modifies: [ppstg]
//
// History: 24-Jun-93 DrewB Created
// 24-Mar-95 HenryLee Save drive letter to correct Stat problem
//
//----------------------------------------------------------------------------
SCODE CreateStorageType(HANDLE hParent,
WCHAR const *pwcsName,
HANDLE *ph,
DWORD grfMode,
DWORD dwStgFmt,
LPSECURITY_ATTRIBUTES pssSecurity,
IStorage **ppstg)
{
SCODE sc;
SafeCDirStorage pds;
#if 0
SafeCFileStorage pfs;
#endif
HANDLE h = (ph == NULL) ? NULL : *ph;
ssDebugOut((DEB_ITRACE, "In CreateStorageType("
"%p, %ws, %p, %lX, %lu, %p, %p)\n",
hParent, pwcsName, h, grfMode, dwStgFmt, pssSecurity, ppstg));
sc = S_OK;
switch(dwStgFmt)
{
case STGFMT_DOCUMENT:
// docfile will reopen the storage will different permissions
if (h)
{
NTSTATUS nts = NtClose(h);
*ph = NULL; // inform caller not to close handle on failure
}
#if WIN32 == 300
sc = DfCreateDocfile (pwcsName, NULL, grfMode, pssSecurity, ppstg);
#else
sc = DfCreateDocfile (pwcsName, NULL, grfMode, 0, ppstg);
#endif
break;
case STGFMT_CATALOG:
// Summary catalogs are only supported on OFS
sc = STG_E_INVALIDFUNCTION;
break;
case STGFMT_DIRECTORY:
pds.Attach(new CDirStorage());
ssMem((CDirStorage *)pds);
if (h != NULL)
{
ssChk(pds->InitFromHandle(h, pwcsName, grfMode));
}
else
{
ssChk(pds->InitFromPath(hParent, pwcsName, grfMode,
CO_CREATE, pssSecurity));
}
TRANSFER_INTERFACE(pds, IStorage, ppstg);
break;
case STGFMT_FILE:
#if 0
pfs.Attach(new CFileStorage());
ssMem((CFileStorage *)pfs);
if (h != NULL)
{
ssChk(pfs->InitFromHandle(h, grfMode));
}
else
{
ssChk(pfs->InitFromPath(hParent, pwcsName, grfMode, CO_CREATE,
pssSecurity));
}
TRANSFER_INTERFACE(pfs, IStorage, ppstg);
#endif
sc = STG_E_INVALIDFUNCTION;
break;
default:
ssAssert(!aMsg("CreateStorageType default hit"));
sc = STG_E_INVALIDPARAMETER;
break;
}
ssDebugOut((DEB_ITRACE, "Out CreateStorageType => %p, 0x%lX\n",
*ppstg, sc));
EH_Err:
return sc;
}
//+---------------------------------------------------------------------------
//
// Function: OpenAnyStorage, public
//
// Synopsis: Opens a storage of the appropriate type
//
// Arguments: [hParent] - Parent handle or NULL
// [pwcsName] - Name or path
// [h] - Handle of storage if already open or NULL
// [dwStgFmt] - Storage format
// [pstgPriority] - Priority mode prior open
// [grfMode] - Mode
// [snbExclude] - Exclusions
// [ppstg] - Storage return
//
// Returns: Appropriate status code
//
// Modifies: [ppstg]
//
// History: 14-Jul-93 DrewB Created
// 24-Mar-95 HenryLee Save drive letter to correct Stat problem
//
//----------------------------------------------------------------------------
SCODE OpenAnyStorage(HANDLE hParent,
WCHAR const *pwcsName,
HANDLE *ph,
DWORD dwStgFmt,
IStorage *pstgPriority,
DWORD grfMode,
SNB snbExclude,
IStorage **ppstg)
{
SCODE sc;
SafeCDirStorage pds;
#if 0
SafeCFileStorage pfs;
#endif
SafeNtHandle hSafe;
HANDLE h = (ph == NULL) ? NULL : *ph;
ssDebugOut((DEB_ITRACE, "In OpenAnyStorage("
"%p, %ws, %p, %lu, %p, %lX, %p, %p)\n", hParent, pwcsName,
h, dwStgFmt, pstgPriority, grfMode, snbExclude, ppstg));
sc = S_OK;
if (h == NULL)
{
ssChk(DetermineStgType(hParent, pwcsName, grfMode,
&dwStgFmt, &hSafe));
h = hSafe;
}
switch(dwStgFmt)
{
case STGFMT_DOCUMENT:
// docfile will reopen the storage will different permissions
if (h)
{
NTSTATUS nts = NtClose(h);
*ph = NULL; // inform caller not to close handle on failure
}
sc = DfOpenDocfile (pwcsName, NULL, pstgPriority, grfMode,
snbExclude, NULL, ppstg);
break;
case STGFMT_CATALOG:
// Summary catalogs are only supported on OFS
sc = STG_E_INVALIDFUNCTION;
break;
case STGFMT_DIRECTORY:
if (pstgPriority != NULL || snbExclude != NULL)
ssErr(EH_Err, STG_E_INVALIDFUNCTION);
pds.Attach(new CDirStorage());
ssMem((CDirStorage *)pds);
ssChk(pds->InitFromHandle(h, pwcsName, grfMode));
TRANSFER_INTERFACE(pds, IStorage, ppstg);
break;
case STGFMT_FILE:
#if 0
// BUGBUG [mikese] "File as an IStorage" behaviour has been disabled,
// because it causes compatibility problems. For example, Excel 5.0
// expects StgOpenStorage on a non-Docfile to fail, not for it to
// return successfully.
// This behaviour may be reenabled, through a different public API
// at a later time.
if (pstgPriority != NULL || snbExclude != NULL)
ssErr(EH_Err, STG_E_INVALIDFUNCTION);
pfs.Attach(new CFileStorage());
ssMem((CFileStorage *)pfs);
ssChk(pfs->InitFromHandle(h, grfMode));
TRANSFER_INTERFACE(pfs, IStorage, ppstg);
#else
// This is the status code returned by Daytona OLE if you attempt to
// open a non-Docfile with StgOpenStorage.
sc = STG_E_FILEALREADYEXISTS;
#endif
break;
default:
sc = STG_E_INVALIDPARAMETER;
}
// If hSafe is set, it will close its handle
// In the error case, this is proper cleanup
// In the success case, the storage has its own reference so this
// drops the refcount to one
ssDebugOut((DEB_ITRACE, "Out OpenAnyStorage => %p, %lX\n", *ppstg, sc));
EH_Err:
return sc;
}