mirror of https://github.com/lianthony/NT4.0
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.
331 lines
7.8 KiB
331 lines
7.8 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1994.
|
|
//
|
|
// File: asyncapi.cxx
|
|
//
|
|
// Contents: APIs for async docfiles
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 19-Dec-95 PhilipLa Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "astghead.cxx"
|
|
#pragma hdrstop
|
|
|
|
#ifndef ASYNC
|
|
#define USE_FILELKB
|
|
#endif
|
|
|
|
|
|
#include "asyncapi.hxx"
|
|
#include "filllkb.hxx"
|
|
#ifdef USE_FILELKB
|
|
#include "filebyte.hxx"
|
|
#endif
|
|
|
|
#ifdef ASYNC
|
|
#include <expdf.hxx>
|
|
#endif
|
|
|
|
|
|
#if DBG == 1
|
|
DECLARE_INFOLEVEL(astg);
|
|
#endif
|
|
|
|
#ifdef ASYNC
|
|
#ifdef COORD
|
|
SCODE DfFromLB(CPerContext *ppc,
|
|
ILockBytes *plst,
|
|
DFLAGS df,
|
|
DWORD dwStartFlags,
|
|
SNBW snbExclude,
|
|
ITransaction *pTransaction,
|
|
CExposedDocFile **ppdfExp,
|
|
CLSID *pcid);
|
|
#else
|
|
SCODE DfFromLB(CPerContext *ppc,
|
|
ILockBytes *plst,
|
|
DFLAGS df,
|
|
DWORD dwStartFlags,
|
|
SNBW snbExclude,
|
|
CExposedDocFile **ppdfExp,
|
|
CLSID *pcid);
|
|
#endif //COORD
|
|
#endif //ASYNC
|
|
|
|
|
|
STDAPI StgOpenAsyncDocfileOnIFillLockBytes(IFillLockBytes *pflb,
|
|
DWORD grfMode,
|
|
DWORD asyncFlags,
|
|
IStorage **ppstgOpen)
|
|
{
|
|
#ifdef ASYNC
|
|
SCODE sc;
|
|
ILockBytes *pilb;
|
|
IStorage *pstg;
|
|
|
|
sc = pflb->QueryInterface(IID_ILockBytes, (void **)&pilb);
|
|
if (FAILED(sc))
|
|
{
|
|
return sc;
|
|
}
|
|
|
|
//Next find out if we're opening on the docfile owned ILockBytes
|
|
// or on something custom. If it's docfile owned, then we can
|
|
// go directly to DfFromLB instead of using StgOpenStorageOnILockBytes
|
|
// which will avoid creating another shared heap.
|
|
|
|
IFileLockBytes *pfl;
|
|
if (SUCCEEDED(pflb->QueryInterface(IID_IFileLockBytes,
|
|
(void **)&pfl)))
|
|
{
|
|
pfl->Release();
|
|
|
|
CFileStream *pfst = (CFileStream *)pflb;
|
|
CPerContext *ppc = pfst->GetContextPointer();
|
|
#ifdef MULTIHEAP
|
|
CSafeMultiHeap smh(ppc);
|
|
#endif
|
|
|
|
#ifdef COORD
|
|
astgChk(DfFromLB(ppc,
|
|
pfst,
|
|
ModeToDFlags(grfMode),
|
|
pfst->GetStartFlags(),
|
|
NULL,
|
|
NULL,
|
|
(CExposedDocFile **)&pstg,
|
|
NULL));
|
|
#else
|
|
astgChk(DfFromLB(ppc,
|
|
pfst,
|
|
ModeToDFlags(grfMode),
|
|
pfst->GetStartFlags(),
|
|
NULL,
|
|
(CExposedDocFile **)&pstg,
|
|
NULL));
|
|
#endif
|
|
//Note: Don't release the ILB reference we got from the QI
|
|
// above, since DfFromLB recorded that pointer but didn't
|
|
// AddRef it.
|
|
}
|
|
else
|
|
{
|
|
IFillLockBytes *pflb2;
|
|
if (SUCCEEDED(pilb->QueryInterface(IID_IDefaultFillLockBytes,
|
|
(void **)&pflb2)))
|
|
{
|
|
CFillLockBytes *pflbDefault = (CFillLockBytes *)pflb;
|
|
CPerContext *ppc;
|
|
pflb2->Release();
|
|
astgChk(StgOpenStorageOnILockBytes(pilb,
|
|
NULL,
|
|
grfMode,
|
|
NULL,
|
|
0,
|
|
&pstg));
|
|
//Get PerContext pointer from pstg
|
|
ppc = ((CExposedDocFile *)pstg)->GetContext();
|
|
pflbDefault->SetContext(ppc);
|
|
}
|
|
else
|
|
{
|
|
astgChk(StgOpenStorageOnILockBytes(pilb,
|
|
NULL,
|
|
grfMode,
|
|
NULL,
|
|
0,
|
|
&pstg));
|
|
}
|
|
pilb->Release();
|
|
}
|
|
astgChkTo(EH_stg, ((CExposedDocFile *)pstg)->InitConnection(NULL));
|
|
((CExposedDocFile *)pstg)->SetAsyncFlags(asyncFlags);
|
|
|
|
|
|
*ppstgOpen = pstg;
|
|
|
|
return NOERROR;
|
|
|
|
EH_stg:
|
|
pstg->Release();
|
|
Err:
|
|
pilb->Release();
|
|
if (sc == STG_E_PENDINGCONTROL)
|
|
{
|
|
sc = E_PENDING;
|
|
}
|
|
return ResultFromScode(sc);
|
|
#else
|
|
HRESULT hr;
|
|
ILockBytes *pilb;
|
|
IStorage *pstg;
|
|
|
|
hr = pflb->QueryInterface(IID_ILockBytes, (void **)&pilb);
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = StgOpenStorageOnILockBytes(pilb,
|
|
NULL,
|
|
grfMode,
|
|
NULL,
|
|
0,
|
|
&pstg);
|
|
|
|
pilb->Release();
|
|
if (FAILED(hr))
|
|
{
|
|
if (hr == STG_E_PENDINGCONTROL)
|
|
{
|
|
hr = E_PENDING;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
BOOL fDefault = FALSE;
|
|
IFillLockBytes *pflbDefault;
|
|
hr = pflb->QueryInterface(IID_IDefaultFillLockBytes,
|
|
(void **)&pflbDefault);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
fDefault = TRUE;
|
|
pflbDefault->Release();
|
|
}
|
|
|
|
*ppstgOpen = new CAsyncRootStorage(pstg, pflb, fDefault);
|
|
if (*ppstgOpen == NULL)
|
|
{
|
|
return STG_E_INSUFFICIENTMEMORY;
|
|
}
|
|
else
|
|
{
|
|
((CAsyncRootStorage *)(*ppstgOpen))->SetAsyncFlags(asyncFlags);
|
|
}
|
|
|
|
return NOERROR;
|
|
#endif //ASYNC
|
|
}
|
|
|
|
STDAPI StgGetIFillLockBytesOnILockBytes( ILockBytes *pilb,
|
|
IFillLockBytes **ppflb)
|
|
{
|
|
SCODE sc = S_OK;
|
|
CFillLockBytes *pflb = NULL;
|
|
pflb = new CFillLockBytes(pilb);
|
|
if (pflb == NULL)
|
|
{
|
|
return STG_E_INSUFFICIENTMEMORY;
|
|
}
|
|
sc = pflb->Init();
|
|
if (FAILED(sc))
|
|
{
|
|
pflb->Release();
|
|
*ppflb = NULL;
|
|
return sc;
|
|
}
|
|
|
|
*ppflb = pflb;
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
STDAPI StgGetIFillLockBytesOnFile(OLECHAR const *pwcsName,
|
|
IFillLockBytes **ppflb)
|
|
{
|
|
#ifndef USE_FILELKB
|
|
SCODE sc;
|
|
IMalloc *pMalloc;
|
|
CFileStream *plst;
|
|
CFillLockBytes *pflb;
|
|
CPerContext *ppc;
|
|
|
|
DfInitSharedMemBase();
|
|
astgHChk(DfCreateSharedAllocator(&pMalloc));
|
|
astgMemTo(EH_Malloc, plst = new (pMalloc) CFileStream(pMalloc));
|
|
astgChkTo(EH_plst, plst->InitFlags(RSF_CREATE,
|
|
DF_DIRECT | DF_READ |
|
|
DF_WRITE | DF_DENYALL));
|
|
astgChkTo(EH_plst, plst->Init(pwcsName));
|
|
|
|
astgMemTo(EH_plstInit, ppc = new (pMalloc) CPerContext(pMalloc));
|
|
astgChkTo(EH_ppc, ppc->InitNewContext());
|
|
//We want 0 normal references on the per context, and one reference
|
|
// to the shared memory.
|
|
ppc->DecRef();
|
|
plst->SetContext(ppc);
|
|
plst->StartAsyncMode();
|
|
astgChkTo(EH_plstInit, ppc->InitNotificationEvent());
|
|
|
|
*ppflb = (IFillLockBytes *)plst;
|
|
|
|
return S_OK;
|
|
|
|
EH_ppc:
|
|
delete ppc;
|
|
EH_plstInit:
|
|
plst->Release();
|
|
goto EH_Malloc;
|
|
EH_plst:
|
|
delete plst;
|
|
EH_Malloc:
|
|
pMalloc->Release();
|
|
Err:
|
|
return sc;
|
|
#else
|
|
SCODE sc;
|
|
CFileLockBytes *pflb = NULL;
|
|
pflb = new CFileLockBytes;
|
|
if (pflb == NULL)
|
|
{
|
|
return STG_E_INSUFFICIENTMEMORY;
|
|
}
|
|
sc = pflb->Init(pwcsName);
|
|
if (SUCCEEDED(sc))
|
|
{
|
|
sc = StgGetIFillLockBytesOnILockBytes(pflb, ppflb);
|
|
}
|
|
return sc;
|
|
#endif // ASYNC
|
|
}
|
|
|
|
|
|
|
|
#if DBG == 1
|
|
STDAPI StgGetDebugFileLockBytes(OLECHAR const *pwcsName, ILockBytes **ppilb)
|
|
{
|
|
#ifdef ASYNC
|
|
//BUGBUG: Implement
|
|
return STG_E_UNIMPLEMENTEDFUNCTION;
|
|
#else
|
|
SCODE sc;
|
|
CFileLockBytes *pflb;
|
|
|
|
*ppilb = NULL;
|
|
|
|
pflb = new CFileLockBytes;
|
|
if (pflb == NULL)
|
|
{
|
|
return STG_E_INSUFFICIENTMEMORY;
|
|
}
|
|
|
|
sc = pflb->Init(pwcsName);
|
|
if (FAILED(sc))
|
|
{
|
|
delete pflb;
|
|
pflb = NULL;
|
|
}
|
|
|
|
*ppilb = pflb;
|
|
|
|
return sc;
|
|
#endif // ASYNC
|
|
}
|
|
#endif
|