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.
453 lines
11 KiB
453 lines
11 KiB
/***************************************************************************\
|
|
*
|
|
* FSMISC.C
|
|
*
|
|
* Copyright (C) Microsoft Corporation 1990.
|
|
* All Rights reserved.
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* Program Description: File System Manager functions - miscellaneous
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* Revision History: Created 03/12/90 by JohnSc
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* Known Bugs: None
|
|
*
|
|
\***************************************************************************/
|
|
|
|
#include "help.h"
|
|
#include "inc\fspriv.h"
|
|
|
|
#pragma hdrstop
|
|
|
|
// This is hacked in for 3.1 bug #1013.
|
|
|
|
#include <sys/types.h>
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* Function: FAccessHfs( hfs, sz, bFlags )
|
|
*
|
|
* Purpose: Determine existence or legal access to a FS file
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: hfs
|
|
* sz - file name
|
|
* bFlags - ignored
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: TRUE if file exists (is accessible in stated mode),
|
|
* FALSE otherwise
|
|
*
|
|
* Bugs: access mode part is unimplemented
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL STDCALL FAccessHfs(HFS hfs, LPSTR sz)
|
|
{
|
|
QFSHR qfshr;
|
|
FILE_REC fr;
|
|
|
|
ASSERT(hfs != NULL);
|
|
qfshr = PtrFromGh(hfs);
|
|
|
|
if (qfshr->fid == HFILE_ERROR && !FPlungeQfshr(qfshr))
|
|
return FALSE;
|
|
|
|
SetFSErrorRc(RcLookupByKey(qfshr->hbt, (KEY) sz, NULL, &fr));
|
|
|
|
return (rcFSError == rcSuccess);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcLLInfoFromHf( hf, wOption, qfid, qlBase, qlcb )
|
|
-
|
|
* Purpose: Map an HF into low level file info.
|
|
*
|
|
* ASSUMES
|
|
* args IN: hf - an open HF
|
|
* qfid, qlBase, qlcb - pointers to user's variables
|
|
* wOption - wLLSameFid, wLLDupFid, or wLLNewFid
|
|
*
|
|
* PROMISES
|
|
* returns: RcFSError(); rcSuccess on success
|
|
*
|
|
* args OUT: qfid - depending on value of wOption, either
|
|
* the same fid used by hf, a dup() of this fid,
|
|
* or a new fid obtained by reopening the file.
|
|
*
|
|
* qlBase - byte offset of first byte in the file
|
|
* qlcb - size in bytes of the data in the file
|
|
*
|
|
* globals OUT: rcFSError
|
|
*
|
|
* Notes: It is possible to read data outside the range specified
|
|
* by *qlBase and *qlcb. Nothing is guaranteed about what
|
|
* will be found there.
|
|
* If wOption is wLLSameFid or wLLDupFid, and the FS is
|
|
* opened in write mode, this fid will be writable.
|
|
* However, writing is not allowed and may destroy the
|
|
* file system.
|
|
*
|
|
* Fids obtained with the options wLLSameFid and wLLDupFid
|
|
* share a file pointer with the hfs. This file pointer
|
|
* may change after any operation on this FS.
|
|
* The fid obtained with the option wLLSameFid may be closed
|
|
* by FS operations. If it is, your fid is invalid.
|
|
*
|
|
* NULL can be passed for qfid, qlbase, qlcb and this routine
|
|
* will not pass back the information.
|
|
*
|
|
* Bugs: wLLDupFid is unimplemented.
|
|
*
|
|
* +++
|
|
*
|
|
* Method:
|
|
*
|
|
* Notes:
|
|
*
|
|
\***************************************************************************/
|
|
|
|
RC STDCALL RcLLInfoFromHf(HF hf, WORD wOption, FID *qfid, QL qlBase, QL qlcb)
|
|
{
|
|
QRWFO qrwfo = (QRWFO) PtrFromGh(hf);
|
|
QFSHR qfshr = (QFSHR) PtrFromGh(qrwfo->hfs);
|
|
|
|
if (!(qrwfo->bFlags & fFSOpenReadOnly)) {
|
|
SetFSErrorRc(rcNoPermission);
|
|
return rcFSError;
|
|
}
|
|
|
|
if (qfshr->fid == HFILE_ERROR && !FPlungeQfshr(qfshr))
|
|
return rcFSError;
|
|
|
|
if (qlBase != NULL)
|
|
*qlBase = qrwfo->lifBase + sizeof(FH);
|
|
if (qlcb != NULL)
|
|
*qlcb = qrwfo->lcbFile;
|
|
|
|
if (qfid != NULL) {
|
|
switch (wOption) {
|
|
case LLSAMEFID:
|
|
*qfid = qfshr->fid;
|
|
break;
|
|
|
|
case LLDUPFID:
|
|
SetFSErrorRc(rcUnimplemented); // REVIEW
|
|
break;
|
|
|
|
case LLNEWFID:
|
|
*qfid = FidOpenFm(qfshr->fm, OF_READ);
|
|
if (*qfid == HFILE_ERROR)
|
|
SetFSErrorRc(RcGetIOError());
|
|
break;
|
|
|
|
default:
|
|
SetFSErrorRc( rcBadArg );
|
|
break;
|
|
}
|
|
}
|
|
return rcFSError;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcLLInfoFromHfsSz( hfs, sz, wOption, qfid, qlBase, qlcb )
|
|
-
|
|
* Purpose: Map an HF into low level file info.
|
|
*
|
|
* ASSUMES
|
|
* args IN: hfs - an open HFS
|
|
* szName - name of file in FS
|
|
* qfid, qlBase, qlcb - pointers to user's variables
|
|
* wOption - wLLSameFid, wLLDupFid, or wLLNewFid
|
|
*
|
|
* PROMISES
|
|
* returns: RcFSError(); rcSuccess on success
|
|
*
|
|
* args OUT: qfid - depending on value of wOption, either
|
|
* the same fid used by hf, a dup() of this fid,
|
|
* or a new fid obtained by reopening the file.
|
|
*
|
|
* qlBase - byte offset of first byte in the file
|
|
* qlcb - size in bytes of the data in the file
|
|
*
|
|
* globals OUT: rcFSError
|
|
*
|
|
* Notes: It is possible to read data outside the range specified
|
|
* by *qlBase and *qlcb. Nothing is guaranteed about what
|
|
* will be found there.
|
|
* If wOption is wLLSameFid or wLLDupFid, and the FS is
|
|
* opened in write mode, this fid will be writable.
|
|
* However, writing is not allowed and may destroy the
|
|
* file system.
|
|
*
|
|
* Fids obtained with the options wLLSameFid and wLLDupFid
|
|
* share a file pointer with the hfs. This file pointer
|
|
* may change after any operation on this FS.
|
|
* The fid obtained with the option wLLSameFid may be closed
|
|
* by FS operations. If it is, your fid is invalid.
|
|
*
|
|
* NULL can be passed for qfid, qlbase, qlcb and this routine
|
|
* will not pass back the information.
|
|
*
|
|
* Bugs: wLLDupFid is unimplemented.
|
|
*
|
|
* +++
|
|
*
|
|
* Method: Calls RcLLInfoFromHf().
|
|
*
|
|
* Notes:
|
|
*
|
|
\***************************************************************************/
|
|
|
|
RC STDCALL RcLLInfoFromHfsSz(
|
|
HFS hfs,
|
|
LPSTR szFile,
|
|
WORD wOption,
|
|
FID *qfid,
|
|
QL qlBase,
|
|
QL qlcb )
|
|
{
|
|
HF hf = HfOpenHfs(hfs, szFile, fFSOpenReadOnly);
|
|
RC rc;
|
|
|
|
if (!hf)
|
|
return rcFSError;
|
|
|
|
rc = RcLLInfoFromHf(hf, wOption, qfid, qlBase, qlcb);
|
|
|
|
return (rcSuccess == RcCloseHf(hf)) ? rcFSError : rc;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcTimestampHfs( hfs, ql )
|
|
-
|
|
* Purpose: Get the modification time of the FS.
|
|
*
|
|
* ASSUMES
|
|
* args IN: hfs - FS
|
|
* ql - pointer to a long
|
|
*
|
|
* PROMISES
|
|
* returns: rcSuccess or what ever
|
|
* args OUT: ql - contains time of last modification of the
|
|
* file. This will not necessarily reflect
|
|
* writes to open files within the FS.
|
|
*
|
|
* NOTE: This code is WINDOWS specific. The platform
|
|
* independent code is in Winhelp 3.5.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
RC STDCALL RcTimestampHfs(HFS hfs, DWORD* plTime)
|
|
{
|
|
QFSHR qfshr;
|
|
BY_HANDLE_FILE_INFORMATION bhfi;
|
|
|
|
ASSERT(hfs != NULL);
|
|
ASSERT(plTime != NULL);
|
|
|
|
qfshr = (QFSHR) PtrFromGh(hfs);
|
|
|
|
if (qfshr->fid != HFILE_ERROR || FPlungeQfshr(qfshr)) {
|
|
|
|
if (!GetFileInformationByHandle((HANDLE) qfshr->fid, &bhfi)) {
|
|
WIN32_FIND_DATA fd;
|
|
HANDLE hfd;
|
|
|
|
if ((hfd = FindFirstFile(qfshr->fm, &fd)) != INVALID_HANDLE_VALUE) {
|
|
*plTime = fd.ftLastWriteTime.dwLowDateTime;
|
|
FindClose(hfd);
|
|
AdjustForTimeZoneBias(plTime);
|
|
return rcSuccess;
|
|
}
|
|
return rcBadHandle;
|
|
}
|
|
else {
|
|
*plTime = bhfi.ftLastWriteTime.dwLowDateTime;
|
|
AdjustForTimeZoneBias(plTime);
|
|
return rcSuccess;
|
|
}
|
|
}
|
|
|
|
return rcBadHandle;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: MatchTimestamp
|
|
|
|
PURPOSE: Determine if a file has the expected time/date stamp. If the
|
|
file isn't where it is expected, try to find it elsewhere.
|
|
|
|
PARAMETERS:
|
|
pszFile
|
|
lTime
|
|
pfm -- NULL to prevent looking elsewhere for a file
|
|
|
|
RETURNS: TRUE if the dates match, FALSE if file isn't found or dates
|
|
don't match. If the file is in a different location, the
|
|
time/date stamp matches, then pfm will be non-null
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
18-Sep-1994 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
BOOL STDCALL MatchTimestamp(PCSTR pszFile, DWORD lTime, FM* pfm)
|
|
{
|
|
WIN32_FIND_DATA fd;
|
|
HANDLE hfind = FindFirstFile(pszFile, &fd);
|
|
if (hfind == INVALID_HANDLE_VALUE) {
|
|
if (!pfm)
|
|
return FALSE;
|
|
*pfm = FmNewExistSzDir(pszFile,
|
|
DIR_INI | DIR_PATH | DIR_CUR_HELP | DIR_CURRENT | DIR_SILENT_REG);
|
|
if (!*pfm)
|
|
return FALSE;
|
|
hfind = FindFirstFile(*pfm, &fd);
|
|
if (hfind == INVALID_HANDLE_VALUE)
|
|
return FALSE;
|
|
}
|
|
else if (pfm)
|
|
*pfm = NULL; // path is valid
|
|
FindClose(hfind);
|
|
AdjustForTimeZoneBias(&fd.ftLastWriteTime.dwLowDateTime);
|
|
#ifdef _DEBUG
|
|
if ((lTime != fd.ftLastWriteTime.dwLowDateTime)) {
|
|
char szBuf[521];
|
|
wsprintf(szBuf, "Timestamp doesn't match: %s\r\n",
|
|
pszFile);
|
|
SendStringToParent(szBuf);
|
|
}
|
|
#endif
|
|
|
|
return (lTime == fd.ftLastWriteTime.dwLowDateTime);
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: AdjustForTimeZoneBias
|
|
|
|
PURPOSE: Adjusts the given timestamp from local time to UTC using
|
|
the time zone bias from GetTimeZoneInformation.
|
|
|
|
PARAMETERS:
|
|
lpTimestamp
|
|
|
|
RETURNS: none.
|
|
|
|
COMMENTS: All timestamps are assumed to be from FILETIME.dwLowDateTime.
|
|
|
|
MODIFICATION DATES:
|
|
18-Sep-1994 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
// # of 100nSec intervals in 1 minute
|
|
#define T100NSECPERMINUTE (60 * 1000 * 10000)
|
|
|
|
void STDCALL AdjustForTimeZoneBias(LPDWORD lpTimestamp)
|
|
{
|
|
TIME_ZONE_INFORMATION tzi;
|
|
LONG Bias;
|
|
|
|
switch (GetTimeZoneInformation(&tzi)) {
|
|
|
|
case TIME_ZONE_ID_DAYLIGHT:
|
|
Bias = tzi.Bias + tzi.DaylightBias;
|
|
break;
|
|
|
|
case TIME_ZONE_ID_STANDARD:
|
|
Bias = tzi.Bias + tzi.StandardBias;
|
|
break;
|
|
|
|
case TIME_ZONE_ID_UNKNOWN:
|
|
Bias = tzi.Bias;
|
|
break;
|
|
|
|
default:
|
|
Bias = 0;
|
|
break;
|
|
|
|
}
|
|
|
|
*lpTimestamp -= Bias * T100NSECPERMINUTE;
|
|
}
|
|
|
|
#ifndef _X86_
|
|
/***************************************************************************\
|
|
*
|
|
- Function: iSdffFileIdHfs( hfs )
|
|
-
|
|
* Purpose: Obtain the SDFF file id associated with a file.
|
|
*
|
|
* ASSUMES
|
|
* args IN: hfs - valid handle to a file system.
|
|
*
|
|
* PROMISES
|
|
* returns: The sdff file id. All FS files have such an ID, so this
|
|
* function cannot fail.
|
|
*
|
|
* Note: someday this may be a macro.
|
|
*
|
|
\***************************************************************************/
|
|
#if defined(MAC) && defined(QUIT_TUNE)
|
|
#pragma segment quit
|
|
#endif
|
|
|
|
int PASCAL ISdffFileIdHfs( HFS hfs )
|
|
{
|
|
QFSHR qfshr;
|
|
int iFile;
|
|
|
|
ASSERT( hfs != (HFS)-1 );
|
|
qfshr = PtrFromGh( hfs );
|
|
iFile = qfshr->fsh.sdff_file_id;
|
|
//UnlockGh( hfs );
|
|
|
|
return( iFile );
|
|
}
|
|
|
|
#if defined(MAC) && defined(QUIT_TUNE)
|
|
#pragma segment fsmisc
|
|
#endif
|
|
|
|
/* Same thing, but takes an HF rather than HFS: */
|
|
|
|
#if defined(MAC) && defined(QUIT_TUNE)
|
|
#pragma segment quit
|
|
#endif
|
|
|
|
int PASCAL ISdffFileIdHf( HF hf )
|
|
{
|
|
QRWFO qrwfo;
|
|
int iFile;
|
|
|
|
ASSERT( hf != (HFS)-1 );
|
|
qrwfo = PtrFromGh( hf );
|
|
iFile = ISdffFileIdHfs( qrwfo->hfs );
|
|
//UnlockGh( hf );
|
|
|
|
return( iFile );
|
|
}
|
|
#if defined(MAC) && defined(QUIT_TUNE)
|
|
#pragma segment fsmisc
|
|
#endif
|
|
#endif //!_X86_
|
|
|
|
|
|
/* EOF */
|