Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

667 lines
13 KiB

/********************************************************************
WRAPSTOR.CPP
Owner: ErinFox
Created: 28-Feb-1997
Description: This file contains file system calls that are wrapped
with the InfoTech IStorage implementation
*********************************************************************/
// For IStorage support
#define INITGUID
#include <windows.h>
#include <basetyps.h>
#include <comdef.h>
#include <MSITStg.h>
// InfoTech includes
#include <mvopsys.h>
#include <_mvutil.h>
#include <wrapstor.h>
#include "iofts.h"
// DOSFILE support
#include <io.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#define RESERVED 0
// I "borrowed" these from Tome code
#define PLI_To_PFO(PLI) ((FILEOFFSET *) PLI)
#define LI_To_FO(LI) (*PLI_To_PFO(&LI))
#define PFO_To_PLI(PFO) ((LARGE_INTEGER *) PFO)
#define FO_To_LI(FO) (*PFO_To_PLI(&FO))
// was in iofts.c
#ifdef _DEBUG
static char s_aszModule[] = __FILE__; // Used by error return functions.
#endif
// was in iofts.c
#define OPENED_HFS (BYTE)0x80
// was in iofts.c
PRIVATE HANDLE NEAR PASCAL IoftsWin32Create(LPCSTR lpstr, DWORD w);
PRIVATE HANDLE NEAR PASCAL IoftsWin32Open(LPCSTR lpstr, DWORD w);
// was in iofts.c
#define CREAT(sz, w) IoftsWin32Create(sz, w)
#define OPEN(sz, w) IoftsWin32Open(sz, w)
//
// These functions came from subfile.c
//
PUBLIC HF PASCAL FAR EXPORT_API HfOpenHfs(HFS hfs, LPCWSTR wsz,
BYTE bFlags, LPERRB lperrb)
{
HF hf;
DWORD grfMode;
HRESULT hr;
// TODO: find out how big this really should be
// OLECHAR wsz[_MAX_PATH];
// MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, wsz, _MAX_PATH);
if (bFlags & HFOPEN_READWRITE)
grfMode = STGM_READWRITE;
else if (bFlags & HFOPEN_READ)
grfMode = STGM_READ;
if (!(bFlags & HFOPEN_CREATE))
{
hr = hfs->OpenStream(wsz, NULL, grfMode, RESERVED, &hf);
}
else
{
hr = hfs->CreateStream(wsz, grfMode, RESERVED, RESERVED, &hf);
}
// make sure we pass back a NULL if open/create failed
if (!SUCCEEDED(hr))
hf = NULL;
// sometimes we get passed NULL for lperrb
if (lperrb)
*lperrb = hr;
return hf;
}
PUBLIC HF PASCAL FAR EXPORT_API HfCreateFileHfs(HFS hfs, LPCSTR sz,
BYTE bFlags, LPERRB lperrb)
{
HF hf;
DWORD grfMode;
HRESULT hr;
// TODO: find out how big this really should be
OLECHAR wsz[_MAX_PATH];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, wsz, _MAX_PATH);
if (bFlags & HFOPEN_READWRITE)
grfMode = STGM_READWRITE;
else if (bFlags & HFOPEN_READ)
grfMode = STGM_READ;
hr = hfs->CreateStream(wsz, grfMode, RESERVED, RESERVED, &hf);
// make sure we pass back NULL if failure
if (!SUCCEEDED(hr))
hf = NULL;
if (lperrb)
*lperrb = hr;
return hf;
}
// This is currently the same as HfOpenHfs, but once we have Ron's
// enhancements to Tome we will be able to set the size on the file
PUBLIC HF PASCAL FAR EXPORT_API HfOpenHfsReserve(HFS hfs, LPCSTR sz,
BYTE bFlags, FILEOFFSET foReserve, LPERRB lperrb)
{
HF hf;
DWORD grfMode;
HRESULT hr;
// TODO: find out how big this really should be
OLECHAR wsz[_MAX_PATH];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, wsz, _MAX_PATH);
if (bFlags & HFOPEN_READWRITE)
grfMode = STGM_READWRITE;
else if (bFlags & HFOPEN_READ)
grfMode = STGM_READ;
if (!(bFlags & HFOPEN_CREATE))
{
hr = hfs->OpenStream(wsz, NULL, grfMode, RESERVED, &hf);
}
else
{
hr = hfs->CreateStream(wsz, grfMode, RESERVED, RESERVED, &hf);
}
if (!SUCCEEDED(hr))
hf = NULL;
if (lperrb)
*lperrb = hr;
return hf;
}
PUBLIC LONG PASCAL FAR EXPORT_API LcbReadHf(HF hf, LPVOID lpvBuffer,
LONG lcb, LPERRB lperrb)
{
ULONG cbRead;
HRESULT hr;
hr = hf->Read(lpvBuffer, lcb, &cbRead);
if (lperrb)
*lperrb = hr;
return cbRead;
}
PUBLIC LONG PASCAL FAR EXPORT_API LcbWriteHf(HF hf, LPVOID lpvBuffer,
LONG lcb, LPERRB lperrb)
{
ULONG cbWrote;
HRESULT hr;
hr = hf->Write(lpvBuffer, lcb, &cbWrote);
if (lperrb)
*lperrb = hr;
return cbWrote;
}
PUBLIC FILEOFFSET PASCAL FAR EXPORT_API FoSeekHf(HF hf, FILEOFFSET foOffset,
WORD wOrigin, LPERRB lperrb)
{
HRESULT hr;
ULARGE_INTEGER liNewPos;
LARGE_INTEGER liOffset = FO_To_LI(foOffset);
hr = hf->Seek(liOffset, (DWORD)wOrigin, &liNewPos);
if (lperrb)
*lperrb = hr;
return LI_To_FO(liNewPos);
}
PUBLIC RC PASCAL FAR EXPORT_API RcCloseHf(HF hf)
{
if (hf)
hf->Release();
return S_OK;
}
PUBLIC BOOL PASCAL FAR EXPORT_API FAccessHfs( HFS hfs, LPCSTR szName, BYTE bFlags, LPERRB lperrb)
{
HRESULT hr;
HF hf = NULL;
BOOL fRet = FALSE;
if (lperrb)
*lperrb = S_OK; // for now
// TODO: find out how big this really should be
OLECHAR wszName[_MAX_PATH];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szName, -1, wszName, _MAX_PATH);
hr = hfs->OpenStream(wszName, NULL, STGM_READWRITE, RESERVED, &hf);
if (S_OK == hr)
{
if (bFlags & FACCESS_EXISTS)
fRet = TRUE;
}
else if (STG_E_FILENOTFOUND == hr)
{
SetErrCode (lperrb, E_FILENOTFOUND);
}
// else
// {
// Need to set error if anything but NOTFOUND
// }
if (hf)
hf->Release();
return fRet;
}
PUBLIC FILEOFFSET PASCAL FAR EXPORT_API FoSizeHf(HF hf, LPERRB lperrb)
{
STATSTG stat;
HRESULT hr;
FILEOFFSET foSize;
hr = hf->Stat(&stat, STATFLAG_NONAME);
if (S_OK == hr)
foSize = LI_To_FO(stat.cbSize);
else
foSize = foNil;
if (lperrb)
*lperrb = hr;
return foSize;
}
///////////////////////////////////////////////////////////////////
// These functions came from iofts.c
///////////////////////////////////////////////////////////////////
PUBLIC HFPB FAR PASCAL FileCreate (HFPB hfpbSysFile, LPCSTR lszFilename,
int fFileType, LPERRB lperrb)
{
LPFPB lpfpb; /* Pointer to file parameter block */
HANDLE hMem;
HFPB hfpb;
HRESULT hr;
OLECHAR wszFileName[_MAX_PATH];
FM fm;
HFS hfs;
/* Check for valid filename */
if (lszFilename == NULL )
{
SetErrCode (lperrb, E_INVALIDARG);
return 0;
}
/* Allocate a file's parameter block */
if (!(hMem = _GLOBALALLOC(GMEM_ZEROINIT, sizeof(FPB))))
{
SetErrCode(lperrb, E_OUTOFMEMORY);
return NULL;
}
if (!(lpfpb = (LPFPB)_GLOBALLOCK(hMem)))
{
_GLOBALUNLOCK(hMem);
SetErrCode(lperrb,E_OUTOFMEMORY);
return NULL;
}
_INITIALIZECRITICALSECTION(&lpfpb->cs);
lpfpb->hStruct = hMem;
switch (fFileType)
{
case FS_SYSTEMFILE:
IClassFactory* pCF;
hr = CoGetClassObject(CLSID_ITStorage, CLSCTX_INPROC_SERVER, NULL,
IID_IClassFactory, (VOID **)&pCF);
// Error check!
IITStorage* pITStorage;
hr = pCF->CreateInstance(NULL, IID_ITStorage,
(VOID **)&pITStorage);
if (pCF)
pCF->Release();
fm = FmNewSzDir((LPSTR)lszFilename, dirCurrent, NULL);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fm, -1, wszFileName, _MAX_PATH);
hr = pITStorage->StgCreateDocfile(wszFileName, STGM_READWRITE, RESERVED, &hfs);
// if call failed, make sure to set hfs NULL
if (!SUCCEEDED(hr))
{
hfs = NULL;
SetErrCode(lperrb, hr);
}
lpfpb->fs.hfs = hfs;
if (pITStorage)
pITStorage->Release();
DisposeFm(fm);
break;
case FS_SUBFILE:
hfs = GetHfs(hfpbSysFile,lszFilename,TRUE,lperrb);
if (hfs)
{
lpfpb->fs.hf = HfCreateFileHfs(hfs,GetSubFilename(lszFilename,
NULL),HFOPEN_READWRITE,lperrb);
lpfpb->ioMode = OF_READWRITE;
if (lpfpb->fs.hf == NULL)
{
if (!hfpbSysFile)
RcCloseHfs(hfs);
goto ErrorExit;
}
else
{
if (!hfpbSysFile)
lpfpb->ioMode |= OPENED_HFS;
}
}
else
{
goto ErrorExit;
}
break;
case REGULAR_FILE:
// Create the file
if ((lpfpb->fs.hFile = (HFILE_GENERIC)CREAT (lszFilename, 0))
== HFILE_GENERIC_ERROR)
{
SetErrCode(lperrb,E_FILECREATE);
goto ErrorExit;
}
lpfpb->ioMode = OF_READWRITE;
break;
}
// Set the filetype
lpfpb->fFileType = (BYTE) fFileType;
_GLOBALUNLOCK(hfpb = lpfpb->hStruct);
return hfpb;
ErrorExit:
_DELETECRITICALSECTION(&lpfpb->cs);
_GLOBALFREE(hMem);
return 0;
}
PUBLIC HFPB FAR PASCAL FileOpen (HFPB hfpbSysFile, LPCSTR lszFilename,
int fFileType, int ioMode, LPERRB lperrb)
{
LPFPB lpfpb; /* Pointer to file parameter block */
HANDLE hMem;
HFPB hfpb;
FM fm;
OLECHAR wszFileName[_MAX_PATH];
HFS hfs;
HRESULT hr;
/* Check for valid filename */
if (lszFilename == NULL )
{
SetErrCode (lperrb, E_INVALIDARG);
return 0;
}
/* Allocate a file's parameter block */
if (!(hMem = _GLOBALALLOC(GMEM_ZEROINIT, sizeof(FPB))))
{
SetErrCode(lperrb,E_OUTOFMEMORY);
return NULL;
}
if (!(lpfpb = (LPFPB)_GLOBALLOCK(hMem)))
{
_GLOBALUNLOCK(hMem);
SetErrCode(lperrb,E_OUTOFMEMORY);
return NULL;
}
_INITIALIZECRITICALSECTION(&lpfpb->cs);
lpfpb->hStruct = hMem;
switch (fFileType)
{
case FS_SYSTEMFILE:
IClassFactory* pCF;
hr = CoGetClassObject(CLSID_ITStorage, CLSCTX_INPROC_SERVER, NULL,
IID_IClassFactory, (VOID **)&pCF);
// Error check!
IITStorage* pITStorage;
hr = pCF->CreateInstance(NULL, IID_ITStorage,
(VOID **)&pITStorage);
if (pCF)
pCF->Release();
fm = FmNewSzDir((LPSTR)lszFilename, dirCurrent, NULL);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fm, -1, wszFileName, _MAX_PATH);
hr = pITStorage->StgOpenStorage(wszFileName, NULL, (ioMode==READ) ? STGM_READ:STGM_READWRITE,
NULL, RESERVED, &hfs);
if (!SUCCEEDED(hr))
{
hfs = NULL;
SetErrCode(lperrb, hr);
}
lpfpb->fs.hfs = hfs;
if (pITStorage)
pITStorage->Release();
DisposeFm(fm);
break;
case FS_SUBFILE:
hfs = GetHfs(hfpbSysFile,lszFilename,FALSE,lperrb);
if (hfs)
{
OLECHAR wsz[_MAX_PATH];
LPCSTR sz = GetSubFilename(lszFilename, NULL);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, wsz, _MAX_PATH);
lpfpb->fs.hf = HfOpenHfs(hfs, wsz,
(BYTE)((ioMode==READ)?HFOPEN_READ:HFOPEN_READWRITE),lperrb);
lpfpb->ioMode = (BYTE) ioMode;
if (lpfpb->fs.hf == 0)
{
if (!hfpbSysFile)
RcCloseHfs(hfs);
SetErrCode (lperrb, E_NOTEXIST);
goto ErrorExit;
}
else
{
if (!hfpbSysFile)
lpfpb->ioMode|=OPENED_HFS;
}
}
else
{
SetErrCode (lperrb, E_NOTEXIST);
goto ErrorExit;
}
break;
case REGULAR_FILE:
/* Set the IO mode and appropriate error messages */
if (ioMode == READ)
{
/* Open the file */
if ((lpfpb->fs.hFile = (HFILE_GENERIC)OPEN (lszFilename,
ioMode)) == HFILE_GENERIC_ERROR)
{
SetErrCode(lperrb,E_NOTEXIST);
goto ErrorExit;
}
}
else
{
ioMode = OF_READWRITE;
/* Open the file */
if ((lpfpb->fs.hFile = (HFILE_GENERIC)OPEN(lszFilename, ioMode))
== HFILE_GENERIC_ERROR)
{
SetErrCode(lperrb,E_FILECREATE);
goto ErrorExit;
}
}
lpfpb->ioMode = (BYTE) ioMode;
break;
}
// set filetype
lpfpb->fFileType = (BYTE) fFileType;
_GLOBALUNLOCK(hfpb = lpfpb->hStruct);
return hfpb;
ErrorExit:
_DELETECRITICALSECTION(&lpfpb->cs);
_GLOBALFREE(hMem);
return 0;
}
PUBLIC RC FAR PASCAL FileClose(HFPB hfpb)
{
RC rc;
LPFPB lpfpb;
if (hfpb == NULL)
return E_HANDLE;
lpfpb = (LPFPB)_GLOBALLOCK(hfpb);
_ENTERCRITICALSECTION(&lpfpb->cs);
rc = S_OK;
switch (lpfpb->fFileType)
{
case FS_SYSTEMFILE:
if (lpfpb->fs.hfs)
lpfpb->fs.hfs->Release();
break;
case FS_SUBFILE:
if (lpfpb->fs.hf)
lpfpb->fs.hf->Release();
break;
case REGULAR_FILE:
if (lpfpb->fs.hFile)
rc = (!CloseHandle(lpfpb->fs.hFile))?E_FILECLOSE:S_OK;
break;
}
/* Free the file parameter block structure */
_LEAVECRITICALSECTION(&lpfpb->cs);
_DELETECRITICALSECTION(&lpfpb->cs);
_GLOBALUNLOCK(hfpb);
_GLOBALFREE(hfpb);
return rc;
}
// These are verbatim from iofts.c. I put them here so we can compile
PRIVATE HANDLE NEAR PASCAL IoftsWin32Create(LPCSTR lpstr, DWORD w)
{
SECURITY_ATTRIBUTES sa;
HANDLE hfile;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = 0;
hfile= CreateFile(lpstr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
&sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
return hfile;
}
PRIVATE HANDLE NEAR PASCAL IoftsWin32Open(LPCSTR lpstr, DWORD w)
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = 0;
return CreateFile(lpstr, (w == READ) ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, &sa,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
#if 0
// This is new functionality
PUBLIC FM EXPORT_API FAR PASCAL FmFromHfs(HFS hfs)
{
char szStoreName[_MAX_PATH];
FM fm;
ERRB errb;
STATSTG StoreStat;
HRESULT hr;
// get storage name
// Turns out this isn't IMPLEMENTED yet!
hr = hfs->Stat(&StoreStat, STATFLAG_DEFAULT);
if (S_OK == hr)
{
// and convert it since FMs aren't Unicode
WideCharToMultiByte(CP_ACP, 0, StoreStat.pwcsName, -1,
szStoreName, _MAX_PATH, NULL, NULL);
// free memory associated with pwcsName
CoTaskMemFree(StoreStat.pwcsName);
// create new FM
fm = FmNew(szStoreName, &errb);
}
else
fm = NULL;
return fm;
}
#endif