Fixes bug 25028.
Added new dirty flag so that resolutions can be purged.
checked in VC5 fix from pollmann and jband
checked in fix from colin@theblakes.com for VMS.

r= valeski, pollmann, colin@theblakes
This commit is contained in:
dougt%netscape.com 2000-01-26 21:55:13 +00:00
Родитель 39eb3bc816
Коммит b9b159a38c
4 изменённых файлов: 103 добавлений и 50 удалений

Просмотреть файл

@ -1023,7 +1023,11 @@ PRBool nsFileSpec::operator == (const nsFileSpec& inOther) const
#define DIR_STRCMP _stricmp
#else
#define DIR_SEPARATOR '/'
#if defined(VMS)
#define DIR_STRCMP strcasecmp
#else
#define DIR_STRCMP strcmp
#endif
#endif
if(str[strLast] == DIR_SEPARATOR)

Просмотреть файл

@ -33,7 +33,6 @@
#include "windows.h"
#if (_MSC_VER == 1100)
#define INITGUID
#include "objbase.h"
DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0);
#endif

Просмотреть файл

@ -116,6 +116,70 @@ myLL_L2II(PRInt64 result, PRInt32 *hi, PRInt32 *lo )
}
nsresult
MyGetFileAttributesEx(const char* file, WIN32_FILE_ATTRIBUTE_DATA* data)
{
BOOL okay;
if (!data || !file)
return NS_ERROR_FAILURE;
#ifdef WIN95
okay = PR_FALSE;
memset(data, 0, sizeof(WIN32_FILE_ATTRIBUTE_DATA));
data->dwFileAttributes = GetFileAttributes(file);
if(! (data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
HANDLE hFile = CreateFile(file,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
okay = GetFileTime(hFile,
&data->ftCreationTime,
&data->ftLastAccessTime,
&data->ftLastWriteTime);
if (okay)
{
// Try to obtain hFile's huge size.
data->nFileSizeLow = GetFileSize (hFile,
&data->nFileSizeHigh);
if (data->nFileSizeLow == 0xFFFFFFFF &&
GetLastError() != NO_ERROR )
{
//error in getting filesize
okay = PR_FALSE;
}
else
{
okay = PR_TRUE;
}
}
CloseHandle(hFile);
}
}
else
{
// it is a directory,
okay = PR_TRUE;
}
#else
okay = GetFileAttributesEx(file,GetFileExInforStandard,data);
#endif
if (!okay)
return ConvertWinError(GetLastError());
return NS_OK;
}
class nsDirEnumerator : public nsISimpleEnumerator
{
public:
@ -228,7 +292,7 @@ nsLocalFile::nsLocalFile()
mPersistFile = nsnull;
mShellLink = nsnull;
mLastResolution = PR_FALSE;
MakeDirty();
}
@ -280,6 +344,7 @@ nsLocalFile::MakeDirty()
mDirty = PR_TRUE;
}
//----------------------------------------------------------------------------------------
//
// ResolvePath
@ -487,64 +552,56 @@ nsLocalFile::ResolvePath(const char* workingPath, PRBool resolveTerminal, char**
nsresult
nsLocalFile::ResolveAndStat(PRBool resolveTerminal)
{
if (!mDirty)
if (!mDirty && mLastResolution == resolveTerminal)
{
return NS_OK;
}
mLastResolution = resolveTerminal;
const char *workingFilePath = mWorkingPath.GetBuffer();
BOOL result;
nsresult result;
// First we will see if the workingPath exists. If it does, then we
// can simply use that as the resolved path. This simplification can
// be done on windows cause its symlinks (shortcuts) use the .lnk
// file extension.
// We are going to be checking the last error.
// Lets make sure that we clear it first.
SetLastError(0);
result = GetFileAttributesEx( workingFilePath, GetFileExInfoStandard, &mFileAttrData);
if ( 0 != result )
result = MyGetFileAttributesEx( workingFilePath, &mFileAttrData);
if ( NS_SUCCEEDED(result) )
{
mResolvedPath.SetString(workingFilePath);
mDirty = PR_FALSE;
return NS_OK;
}
else
{
// okay, something is wrong with the working path. We will try to resolve it.
char *resolvePath;
nsresult rv = ResolvePath(workingFilePath, resolveTerminal, &resolvePath);
if (NS_FAILED(rv))
return rv;
mResolvedPath.SetString(resolvePath);
nsAllocator::Free(resolvePath);
// okay, something is wrong with the working path. We will try to resolve it.
char *resolvePath;
// if we are not resolving the terminal node, we have to "fake" windows
// out and append the ".lnk" file extension before getting any information
// about the shortcut. If resoveTerminal was TRUE, than it the shortcut was
// resolved by the call to ResolvePath above.
result = ResolvePath(workingFilePath, resolveTerminal, &resolvePath);
if (NS_FAILED(result))
return result;
mResolvedPath.SetString(resolvePath);
nsAllocator::Free(resolvePath);
if (resolveTerminal == false)
{
char linkStr[MAX_PATH];
strcpy(linkStr, mResolvedPath.GetBuffer());
strcat(linkStr, ".lnk");
result = GetFileAttributesEx( linkStr, GetFileExInfoStandard, &mFileAttrData);
// if we are not resolving the terminal node, we have to "fake" windows
// out and append the ".lnk" file extension before getting any information
// about the shortcut. If resoveTerminal was TRUE, than it the shortcut was
// resolved by the call to ResolvePath above.
if ( 0 == result)
{
return ConvertWinError(GetLastError());
}
}
return ConvertWinError(GetLastError());
}
char linkStr[MAX_PATH];
strcpy(linkStr, mResolvedPath.GetBuffer());
strcat(linkStr, ".lnk");
result = MyGetFileAttributesEx(linkStr, &mFileAttrData);
if (NS_SUCCEEDED(result))
mDirty = PR_FALSE;
mDirty = PR_FALSE;
return NS_OK;
return result;
}
NS_IMETHODIMP
@ -795,11 +852,6 @@ nsLocalFile::CopySingleFile(nsIFile *sourceFile, nsIFile *destParent, const char
return rv;
int copyOK;
// We are going to be checking the last error.
// Lets make sure that we clear it first.
SetLastError(0);
if (!move)
copyOK = CopyFile(filePath, destPath, PR_TRUE);
@ -1319,7 +1371,7 @@ nsLocalFile::SetFileSize(PRInt64 aFileSize)
MakeDirty();
return NS_ERROR_FAILURE;
}
// Seek to new, desired end of file
PRInt32 hi, lo;
myLL_L2II(aFileSize, &hi, &lo );

Просмотреть файл

@ -70,6 +70,7 @@ private:
// this is the flag which indicates if I can used cached information about the file
PRBool mDirty;
PRBool mLastResolution;
// this string will alway be in native format!
nsCString mWorkingPath;
@ -80,11 +81,8 @@ private:
IPersistFile* mPersistFile;
IShellLink* mShellLink;
WIN32_FILE_ATTRIBUTE_DATA mFileAttrData;
void MakeDirty();
nsresult ResolveAndStat(PRBool resolveTerminal);
nsresult ResolvePath(const char* workingPath, PRBool resolveTerminal, char** resolvedPath);