273 lines
6.2 KiB
C++
273 lines
6.2 KiB
C++
|
/*****************************************************************************
|
||
|
* *
|
||
|
* FSCREATE.C *
|
||
|
* *
|
||
|
* Copyright (C) Microsoft Corporation 1990. *
|
||
|
* All Rights reserved. *
|
||
|
* *
|
||
|
******************************************************************************
|
||
|
* *
|
||
|
* Module Intent *
|
||
|
* *
|
||
|
* FS functions for creating and destroying File Systems and Files. *
|
||
|
* *
|
||
|
*****************************************************************************/
|
||
|
#include "stdafx.h"
|
||
|
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "fspriv.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
/***************************************************************************
|
||
|
|
||
|
FUNCTION: HfsCreateFileSysFm
|
||
|
|
||
|
PURPOSE: create and open a new file system
|
||
|
|
||
|
PARAMETERS:
|
||
|
fm handle of file name
|
||
|
|
||
|
RETURNS: Handle to a file system
|
||
|
|
||
|
COMMENTS: You may dispose of the FM you pass in.
|
||
|
|
||
|
MODIFICATION DATES:
|
||
|
18-Sep-1993 [ralphw]
|
||
|
|
||
|
***************************************************************************/
|
||
|
|
||
|
HFS STDCALL HfsCreateFileSysFm(FM fm)
|
||
|
{
|
||
|
BTREE_PARAMS btp;
|
||
|
|
||
|
// make file system header
|
||
|
|
||
|
QFSHR qfshr = (QFSHR) lcCalloc(sizeof(FSHR));
|
||
|
|
||
|
qfshr->fsh.wMagic = wFileSysMagic;
|
||
|
qfshr->fsh.bVersion = FILESYSVERSION;
|
||
|
qfshr->fsh.bFlags = FS_DIRTY; // >>>> for now not R/O
|
||
|
qfshr->fsh.lifFirstFree = lifNil;
|
||
|
qfshr->fsh.lifEof = sizeof(FSH); // first free is after header
|
||
|
qfshr->fm = lcStrDup(fm);
|
||
|
|
||
|
qfshr->fid = _lcreat(fm, 0);
|
||
|
|
||
|
if (qfshr->fid == HFILE_ERROR) {
|
||
|
lcFree(qfshr);
|
||
|
lcFree(qfshr->fm);
|
||
|
SetFSErrorRc(RcGetLastError());
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// build directory
|
||
|
|
||
|
btp.hfs = (HFS) qfshr;
|
||
|
btp.bFlags = FS_IS_DIRECTORY;
|
||
|
btp.cbBlock = CBBTREEBLOCKDEFAULT;
|
||
|
btp.rgchFormat[0] = KT_SZ;
|
||
|
btp.rgchFormat[1] = '4';
|
||
|
btp.rgchFormat[2] = '\0';
|
||
|
|
||
|
// Create the FS directory btree
|
||
|
|
||
|
qfshr->qbthr = HbtCreateBtreeSz(NULL, &btp);
|
||
|
|
||
|
if (!qfshr->qbthr) {
|
||
|
RcCloseFid(qfshr->fid);
|
||
|
lcFree(qfshr->fm);
|
||
|
lcFree(qfshr);
|
||
|
SetFSErrorRc(RcGetBtreeError());
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// return handle to file system
|
||
|
|
||
|
SetFSErrorRc(RC_Success);
|
||
|
return (HFS) qfshr;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************
|
||
|
|
||
|
FUNCTION: HfCreateFileHfs
|
||
|
|
||
|
PURPOSE: Create and open a file within a specified file system.
|
||
|
|
||
|
PARAMETERS:
|
||
|
hfs - handle to an open file system
|
||
|
pszFile - name of file to open (any valid key)
|
||
|
bFlags - FS_IS_DIRECTORY to create the FS directory
|
||
|
other flags (readonly) are ignored
|
||
|
|
||
|
RETURNS: Handle to the file -- doesn't return on failure
|
||
|
|
||
|
COMMENTS:
|
||
|
Allocate the handle struct and fill it in. Create the temp file and
|
||
|
put a header into it. Don't make btree entry: that happens when
|
||
|
the file is closed. Do test for permission, though.
|
||
|
|
||
|
MODIFICATION DATES:
|
||
|
27-Mar-1994 [ralphw]
|
||
|
|
||
|
***************************************************************************/
|
||
|
|
||
|
HF STDCALL HfCreateFileHfs(HFS hfs, PCSTR pszFile, DWORD bFlags)
|
||
|
{
|
||
|
ASSERT(hfs);
|
||
|
QFSHR qfshr = (QFSHR) hfs;
|
||
|
|
||
|
// make sure file system is writable
|
||
|
|
||
|
ASSERT(!(qfshr->fsh.bFlags & FS_OPEN_READ_ONLY));
|
||
|
|
||
|
QRWFO qrwfo = (QRWFO) lcCalloc(sizeof(RWFO) +
|
||
|
(pszFile == NULL ? 0 : strlen(pszFile)));
|
||
|
|
||
|
// if they are trying to create a fs dir, make sure thats ok
|
||
|
|
||
|
if (bFlags & FS_IS_DIRECTORY) {
|
||
|
ConfirmOrDie(!(qfshr->fsh.bFlags & FS_IS_DIRECTORY));
|
||
|
qfshr->fsh.bFlags |= FS_IS_DIRECTORY;
|
||
|
}
|
||
|
else
|
||
|
strcpy(qrwfo->rgchKey, pszFile);
|
||
|
|
||
|
// fill in the open file struct
|
||
|
|
||
|
qrwfo->hfs = hfs;
|
||
|
|
||
|
qrwfo->bFlags = bFlags | FS_NO_BLOCK | FS_DIRTY;
|
||
|
|
||
|
qrwfo->pTmpFile = new CTmpFile();
|
||
|
|
||
|
// stick the header in it
|
||
|
|
||
|
FH fh;
|
||
|
|
||
|
fh.lcbBlock = sizeof(FH);
|
||
|
fh.lcbFile = 0;
|
||
|
fh.bPerms = (BYTE) bFlags;
|
||
|
|
||
|
qrwfo->pTmpFile->write(&fh, sizeof(FH));
|
||
|
|
||
|
return (HF) qrwfo;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
*
|
||
|
- Function: RcUnlinkFileHfs( hfs, sz )
|
||
|
-
|
||
|
* Purpose: Unlink a file within a file system
|
||
|
*
|
||
|
* ASSUMES
|
||
|
* args IN: hfs - handle to file system
|
||
|
* sz - name (key) of file to unlink
|
||
|
* state IN: The FS file speced by sz should be closed. (if it wasn't,
|
||
|
* changes won't be saved and temp file may not be deleted)
|
||
|
*
|
||
|
* PROMISES
|
||
|
* returns: standard return code
|
||
|
*
|
||
|
* BUGS: shouldn't this check if the file is ReadOnly?
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
RC_TYPE STDCALL RcUnlinkFileHfs(HFS hfs, PCSTR pszFile)
|
||
|
{
|
||
|
QFSHR qfshr;
|
||
|
FILE_REC fr;
|
||
|
|
||
|
ASSERT(hfs);
|
||
|
qfshr = (QFSHR) hfs;
|
||
|
|
||
|
if (qfshr->fsh.bFlags & FS_OPEN_READ_ONLY)
|
||
|
return SetFSErrorRc(RC_NoPermission);
|
||
|
|
||
|
// look it up to get the file base offset
|
||
|
|
||
|
if (SetFSErrorRc(RcLookupByKey(qfshr->qbthr, (KEY) pszFile, NULL, &fr))
|
||
|
!= RC_Success)
|
||
|
return rcFSError;
|
||
|
|
||
|
if (SetFSErrorRc(RcDeleteHbt(qfshr->qbthr, (KEY) pszFile)) == RC_Success) {
|
||
|
|
||
|
// put the file block on the free list
|
||
|
|
||
|
if (FPlungeQfshr(qfshr))
|
||
|
FFreeBlock(qfshr, fr.lifBase);
|
||
|
}
|
||
|
|
||
|
return rcFSError;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
*
|
||
|
- Function: RcAbandonHf( hf )
|
||
|
-
|
||
|
* Purpose: Abandon an open file. All changes since file was opened
|
||
|
* will be lost. If file was opened with a create, it is
|
||
|
* as if the create never happened.
|
||
|
*
|
||
|
* ASSUMES
|
||
|
* args IN: hf
|
||
|
*
|
||
|
* PROMISES
|
||
|
* returns: rc
|
||
|
*
|
||
|
* globals OUT: rcFSError
|
||
|
* +++
|
||
|
*
|
||
|
* Method: Close and unlink the temp file, then unlock and free
|
||
|
* the open file struct. We depend on not saving the
|
||
|
* filename in the directory until the file is closed.
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
RC_TYPE STDCALL RcAbandonHf(HF hf)
|
||
|
{
|
||
|
SetFSErrorRc(RC_Success);
|
||
|
|
||
|
ASSERT(hf);
|
||
|
QRWFO qrwfo = (QRWFO) hf;
|
||
|
|
||
|
if (qrwfo->pTmpFile) {
|
||
|
delete qrwfo->pTmpFile;
|
||
|
qrwfo->pTmpFile = NULL;
|
||
|
}
|
||
|
lcFree(hf);
|
||
|
|
||
|
return rcFSError;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************
|
||
|
|
||
|
FUNCTION: ForceFSError
|
||
|
|
||
|
PURPOSE: Set File System error -- even if RcGetIOError returns
|
||
|
RC_Success
|
||
|
|
||
|
PARAMETERS:
|
||
|
void
|
||
|
|
||
|
RETURNS:
|
||
|
|
||
|
COMMENTS:
|
||
|
|
||
|
MODIFICATION DATES:
|
||
|
18-Sep-1993 [ralphw]
|
||
|
|
||
|
***************************************************************************/
|
||
|
|
||
|
void STDCALL ForceFSError(void)
|
||
|
{
|
||
|
if (RcGetIOError() == RC_Success)
|
||
|
SetFSErrorRc(RC_Invalid);
|
||
|
else
|
||
|
SetFSErrorRc(RcGetIOError());
|
||
|
}
|