зеркало из https://github.com/mozilla/pjs.git
xpcom/io changes,
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:
Родитель
39eb3bc816
Коммит
b9b159a38c
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче