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.
 
 
 
 
 
 

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 */