2020-09-30 17:12:29 +02:00

358 lines
10 KiB
C

/*****************************************************************************
*
* LOCATE.C
*
* Copyright (C) Microsoft Corporation 1992.
* All Rights reserved.
*
******************************************************************************
*
* Module Description: Routine to locate Viewer-related titles and dlls
*
******************************************************************************
*
* Revision History:
* -- May 92 Created DAVIDJES
* 07,Jul 92 Changed RC map[0] to rcBadVersion.
*
*****************************************************************************/
#include <windows.h>
#include <coresh1t.h> // for numerous constants
#include <orkin.h>
#include "_mvfs.h"
#include "imvfs.h"
#define HINSTANCE_ERROR 32
/*****************************************************************************
*
* RcFromLoadLibErr
*
* This table maps errors from Window's LoadLibrary to RC values.
*
*****************************************************************************/
RC RcFromLoadLibErr[HINSTANCE_ERROR] = {
rcBadVersion, //0
rcFailure, //1
rcNoExists, //2
rcNoExists, //3
rcFailure, //4
rcNoPermission, //5
rcFailure, //6
rcFailure, //7
rcOutOfMemory, //8
rcFailure, //9
rcBadVersion, //10
rcBadVersion, //11
rcBadVersion, //12
rcBadVersion, //13
rcBadVersion, //14
rcBadVersion, //15
rcBadVersion, //16
rcFailure, //17
rcFailure, //18
rcBadVersion, //19
rcBadVersion, //20
rcBadVersion, //21
rcFailure, //22
rcFailure, //23
rcFailure, //24
rcFailure, //25
rcFailure, //26
rcFailure, //27
rcFailure, //28
rcFailure, //29
rcFailure, //30
rcFailure //31
};
/*****************************************************************************
*
* LocateViewerDLL
*
* Tries to find the Viewer customization DLL with the specified name.
*
*****************************************************************************/
HANDLE FAR PASCAL LocateViewerDLL(
LPSTR szName,
LPSTR pchEXEName,
LPSTR pchCaption,
LPWORD lperr)
{
FM fm;
HCURSOR hcursor;
HANDLE hmodReturn = 0;
char rgchPath[cchMaxPath];
assert(lperr!=NULL);
*lperr = rcNoExists;
/*------------------------------------------------------------*\
| Look for the DLL in the same directory as WINHELP.EXE
\*------------------------------------------------------------*/
fm = FmNewExistSzDir( szName, dirHelp );
if (fm == fmNil)
{
/*------------------------------------------------------------*\
| Look for the DLL in the directory specified by WINHELP.INI
| or down the path.
\*------------------------------------------------------------*/
fm = FmNewExistSzDir( szName, dirPath );
if (fm==fmNil)
fm = FmNewExistSzIni(szName, (pchEXEName!=NULL?pchEXEName:VWR_EXENAME), (pchCaption!=NULL?pchCaption:VWR_CAPTION));
}
if (fm != fmNil) {
char rgchDirOld[cchMaxPath];
BOOL fSetDir = FALSE;
INT cb;
// Get new directory name from fm
SzPartsFm(fm, rgchPath, cchMaxPath, partDrive | partDir);
// if not the root directory, strip off final '\'
cb = lstrlen(rgchPath);
if (cb > 1
&& (rgchPath[cb-1] == '\\' || rgchPath[cb-1] == '/')
&& rgchPath[cb-2] != ':')
rgchPath[cb-1] = '\0';
// Save old directory and set directory to target directory
// Done for implicit loads of DLL's from same directory
if (!DosCwd(rgchDirOld) && (fSetDir = !DosChDir(rgchPath))) {
// Load module
SzPartsFm(fm, rgchPath, cchMaxPath, partAll);
if ((hcursor = LoadCursor(NULL, IDC_WAIT))!=NULL) SetCursor(hcursor);
hmodReturn = LoadLibrary(rgchPath);
if ((int)hmodReturn < 32) {
*lperr = RcFromLoadLibErr[(int)hmodReturn];
hmodReturn = 0;
} else
*lperr = rcSuccess;
SetCursor(hcursor);
} // endif
DisposeFm( fm );
// Restore old directory
if (fSetDir) {
// ignore failure at this point, have DLL
DosChDir(rgchDirOld);
} // endif
} // endif
return hmodReturn;
} // end LocateViewerDLL
/*****************************************************************************
*
* FilePartsAvail
*
* Returns a set of bits that indicate what parts of a filename were
* specified.
*
*****************************************************************************/
// this is from FM.C. we use it in FilePartsAvail to see which parts
// of a filename were specified in a string.
void FAR PASCAL SnoopPath(
LPSTR sz,
INT far * iDrive,
INT far * iDir,
INT far * iBase,
INT far * iExt);
WORD NEAR PASCAL FilePartsAvail(LPSTR lpstr) {
INT iDrive;
INT iDir;
INT iBase;
INT iExt;
WORD wFlags;
// Snoop the strings and find offsets to the drive, directory, base, and
// extension.
SnoopPath(lpstr, &iDrive, &iDir, &iBase, &iExt);
// determine which parts where specified, set the appropriate flags
wFlags = partNone;
if (*(lpstr+iDrive)!='\0') wFlags |= partDrive;
if (*(lpstr+iDir)!='\0') wFlags |= partDir;
if (*(lpstr+iBase)!='\0') wFlags |= partBase;
if (*(lpstr+iExt)!='\0') wFlags |= partExt;
return(wFlags);
}
/*****************************************************************************
*
* LooseFileCompare
*
* Compares two filenames. Returns TRUE iff they compare favorably
* in a loose sense. Two files are the same if every component
* specified in one filename matches the corresponding component in the
* other filename(*)
*
* (*) with one exception, see comments in code.
*
*****************************************************************************/
// IS_NET_PATH checks if a string starts with a double backslash
#define IS_NET_PATH(sz) \
(*sz=='\\' && *(sz+1)=='\\')
BOOL FAR PASCAL LooseFileCompare(LPSTR lpstr1, LPSTR lpstr2) {
WORD wFlags;
FM fm1, fm2;
WORD part;
char szBuf1[_MAX_PATH];
char szBuf2[_MAX_PATH];
BOOL fRval = FALSE;
// determine which parts the strings have in common
wFlags = FilePartsAvail(lpstr1)&FilePartsAvail(lpstr2);
#if 0 // As per discussion with WayneJ on 7/27/92 we are removing this
// hack. See LilJoe bug 975.
// we must ignore the path in one special case. The special case is
// that a network
// file, such as \\foo\bar\big\bad could also be specifed x:\bad\big
// if x: is assigned to \\foo\bar. In this case the two names have
// different paths and so the comparison would fail where we want
// it to succeed. So if one but not both files have a network path
// then we zero the partDir bit of the flags.
// I can get away with an bitwise XOR instead of a logical XOR because
// IS_NET_PATH returns the result of a logical operation which is
// defined to be 0 or 1 and not 0 and an arbitrary nonzero value. Hee!
// This is some slick C, read it and weep.
wFlags = (IS_NET_PATH(lpstr1)^IS_NET_PATH(lpstr2))?wFlags&~partDir:wFlags;
#endif
// make an FM out of each to normalize and so that we can pull out the
// respective parts. If all respective parts match then we
// have a match.
fm1 = FmNewSzDir(lpstr1, dirCurrent);
fm2 = FmNewSzDir(lpstr2, dirCurrent);
if (fm1!=NULL && fm2!=NULL) {
fRval = TRUE;
for (part = partDrive; part<=partExt; part<<=1) {
fRval = fRval &&
((!(wFlags&part))
|| (lstrcmp(
SzPartsFm(fm1, szBuf1, _MAX_PATH, part),
SzPartsFm(fm2, szBuf2, _MAX_PATH, part)
)==0));
}
}
if (fm1!=NULL) DisposeFm(fm1);
if (fm2!=NULL) DisposeFm(fm2);
return fRval;
}
/*****************************************************************************
*
* LocateViewerFile
*
* Returns a file moniker for a Viewer title specified in a string.
* Looks in all the "right" places.
*
*****************************************************************************/
FM FAR PASCAL LocateViewerFile(
FM fmCurrent,
LPSTR lpstrName,
LPSTR pchEXEName,
LPSTR pchCaption) {
FM fm = NULL; // eventual return value
char szBuf[_MAX_PATH]; // buffer to muck with string
DPF4(" LocateViewerFile looking for %s\n", lpstrName );
// copy the file over to our buffer
lstrcpy(szBuf, lpstrName);
// DougC. This is really stupid code. What we ought to do is rewrite this so we
// use _splitpath to check if we have an extension, and if we don't, set this
// extension immediately to .MVB. I won't make this rewrite now since we are try
// to get to a release candidate.
// first attempt to locate the file in the same directory as the
// "current" fm.
if (fmCurrent) {
// The same dir as the "current" file (interfile jump "source")
fm = FmNewSameDirFmSz(fmCurrent, szBuf);
if (!FExistFm(fm)) {
DisposeFm(fm);
fm = NULL;
// DougC fix to LJ#391: if no fm was found above, then append ".MVB" and try again
lstrcat(szBuf, VIEWER_STD_EXT); // DougC added to fix to LJ#391
fm = FmNewSameDirFmSz(fmCurrent, szBuf); // DougC added to fix to LJ#391
if (!FExistFm(fm)) { // DougC added to fix to LJ#391
DisposeFm(fm); // DougC added to fix to LJ#391
fm = NULL; // DougC added to fix to LJ#391
lstrcpy(szBuf, lpstrName); // DougC added to fix to LJ#391
} // DougC added to fix to LJ#391
}
}
// if no fm was found above, then look in the standard places.
if (fm==NULL) {
// The current, windows, win\system, and path dirs
if ((fm = FmNewExistSzDir(szBuf,
dirCurrent | dirSystem | dirPath ))==NULL)
fm = FmNewExistSzIni(szBuf, (pchEXEName!=NULL?pchEXEName:VWR_EXENAME), (pchCaption!=NULL?pchCaption:VWR_CAPTION));
}
// if no fm was found above, then append ".MVB" and look in the
// standard places.
if (fm==NULL) {
//!!! maybe get from resources? sidOpenExt in Viewer?
lstrcat(szBuf, VIEWER_STD_EXT);
// The current, windows, win\system, and path dirs
if ((fm = FmNewExistSzDir(szBuf,
dirCurrent | dirSystem | dirPath ))==NULL)
fm = FmNewExistSzIni(szBuf, (pchEXEName!=NULL?pchEXEName:VWR_EXENAME), (pchCaption!=NULL?pchCaption:VWR_CAPTION));
}
if (fm!=NULL) {
DPF4(" LocateViewerFile found %s\n",
CPF SzPartsFm( fm, szBuf, sizeof(szBuf), partAll));
}
return fm;
}
#ifdef WIN32
int far pascal DosCwd(QCH q )
{
return GetCurrentDirectory( cchMaxPath, q );
}
int far pascal DosChDir(QCH q)
{
return SetCurrentDirectory( q );
}
WORD FAR CDECL _lunlink (LPBYTE d ) /* from unlink.asm */
{
return (WORD)DeleteFile( d );
}
WORD CDECL WExtendedError( QW a, QB b, QB c, QB d ) /* from dos.asm */
{
return 0;
}
#endif