Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

272 lines
6.2 KiB

/*****************************************************************************
* *
* 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());
}