Fixes for 28257, 21628, 27076, 18186, 25584
1) Implement nsDirectoryService. This makes the service extensible so that components can do delayed registration. 2) Fixes windows Append meathod which did not work with . prepended files. 3) Fixes memory leaks in nsDirectoryService 4) Fixes SetPermissions() on Win32. This was in my tree for a while. It basically calls through to chmod just like on unix. 5) Fixes GetModificationDate. Win32 now return PRTime for dates. r = scc, valeski, warren, wtc (suggestions) a = jevering git-svn-id: svn://10.0.0.236/trunk@61389 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -55,6 +55,14 @@
|
||||
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#define COMPONENT_REGISTRY_NAME "Component Registry"
|
||||
#define COMPONENT_DIRECTORY "Components"
|
||||
#else
|
||||
#define COMPONENT_REGISTRY_NAME "component.reg"
|
||||
#define COMPONENT_DIRECTORY "components"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -225,25 +233,31 @@ static nsresult GetCurrentProcessDirectory(nsILocalFile** aFile)
|
||||
|
||||
nsDirectoryService* nsDirectoryService::mService = nsnull;
|
||||
|
||||
nsDirectoryService::nsDirectoryService(nsISupports* outer)
|
||||
nsDirectoryService::nsDirectoryService()
|
||||
{
|
||||
NS_INIT_AGGREGATED(outer);
|
||||
NS_INIT_REFCNT();
|
||||
mHashtable = new nsHashtable(256, PR_TRUE);
|
||||
NS_ASSERTION(mHashtable != NULL, "hashtable null error");
|
||||
|
||||
NS_NewISupportsArray(getter_AddRefs(mProviders));
|
||||
NS_ASSERTION(mProviders != NULL, "providers null error");
|
||||
|
||||
RegisterProvider(NS_STATIC_CAST(nsIDirectoryServiceProvider*, this));
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsDirectoryService::Create(nsISupports *outer, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ENSURE_PROPER_AGGREGATION(outer, aIID);
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
if (mService == nsnull)
|
||||
{
|
||||
mService = new nsDirectoryService(outer);
|
||||
mService = new nsDirectoryService();
|
||||
if (mService == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return mService->AggregatedQueryInterface(aIID, aResult);
|
||||
return mService->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
PRBool
|
||||
@@ -256,102 +270,87 @@ nsDirectoryService::ReleaseValues(nsHashKey* key, void* data, void* closure)
|
||||
|
||||
nsDirectoryService::~nsDirectoryService()
|
||||
{
|
||||
Enumerate(ReleaseValues);
|
||||
if (mHashtable)
|
||||
mHashtable->Enumerate(ReleaseValues);
|
||||
}
|
||||
|
||||
NS_IMPL_AGGREGATED(nsDirectoryService);
|
||||
NS_IMPL_ISUPPORTS3(nsDirectoryService, nsIProperties, nsIDirectoryService, nsIDirectoryServiceProvider)
|
||||
|
||||
NS_METHOD
|
||||
nsDirectoryService::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInstancePtr);
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsISupports)))
|
||||
*aInstancePtr = GetInner();
|
||||
else if (aIID.Equals(NS_GET_IID(nsIProperties)))
|
||||
*aInstancePtr = NS_STATIC_CAST(nsIProperties*, this);
|
||||
else {
|
||||
*aInstancePtr = nsnull;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_ADDREF((nsISupports*)*aInstancePtr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::Define(const char* prop, nsISupports* initialValue)
|
||||
{
|
||||
nsStringKey key(prop);
|
||||
if (Exists(&key))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsISupports* prevValue = (nsISupports*)Put(&key, initialValue);
|
||||
NS_ASSERTION(prevValue == NULL, "hashtable error");
|
||||
NS_IF_ADDREF(initialValue);
|
||||
return NS_OK;
|
||||
return Set(prop, initialValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::Undefine(const char* prop)
|
||||
{
|
||||
nsStringKey key(prop);
|
||||
if (!Exists(&key))
|
||||
if (!mHashtable->Exists(&key))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsISupports* prevValue = (nsISupports*)Remove(&key);
|
||||
nsISupports* prevValue = (nsISupports*)mHashtable->Remove(&key);
|
||||
NS_IF_RELEASE(prevValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
typedef struct FileData
|
||||
|
||||
{
|
||||
const char* property;
|
||||
nsIFile* file;
|
||||
PRBool persistant;
|
||||
|
||||
} FileData;
|
||||
|
||||
static PRBool FindProviderFile(nsISupports* aElement, void *aData)
|
||||
{
|
||||
nsCOMPtr<nsIDirectoryServiceProvider> prov = do_QueryInterface(aElement);
|
||||
if (!prov)
|
||||
return PR_FALSE;
|
||||
|
||||
FileData* fileData = (FileData*)aData;
|
||||
prov->GetFile(fileData->property, &fileData->persistant, &(fileData->file) );
|
||||
if (fileData->file)
|
||||
return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result)
|
||||
{
|
||||
nsStringKey key(prop);
|
||||
if (!Exists(&key))
|
||||
if (!mHashtable->Exists(&key))
|
||||
{
|
||||
// check to see if it is one of our defaults
|
||||
|
||||
if (strncmp(prop, "xpcom.currentProcess.componentRegistry", 38) == 0)
|
||||
{
|
||||
nsILocalFile* localFile;
|
||||
|
||||
nsresult rv = GetCurrentProcessDirectory(&localFile);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
#ifdef XP_MAC
|
||||
localFile->Append("Component Registry");
|
||||
#else
|
||||
localFile->Append("component.reg");
|
||||
#endif /* XP_MAC */
|
||||
|
||||
Set(prop, NS_STATIC_CAST(nsILocalFile*, localFile));
|
||||
}
|
||||
else if (strncmp(prop, "xpcom.currentProcess.componentDirectory", 39) == 0)
|
||||
{
|
||||
nsILocalFile* localFile;
|
||||
// it is not one of our defaults, lets check any providers
|
||||
FileData fileData;
|
||||
fileData.property = prop;
|
||||
fileData.file = nsnull;
|
||||
fileData.persistant = PR_TRUE;
|
||||
|
||||
nsresult rv = GetCurrentProcessDirectory(&localFile);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
#ifdef XP_MAC
|
||||
localFile->Append("Components");
|
||||
#else
|
||||
localFile->Append("components");
|
||||
#endif /* XP_MAC */
|
||||
|
||||
Set(prop, NS_STATIC_CAST(nsILocalFile*, localFile));
|
||||
}
|
||||
mProviders->EnumerateForwards(FindProviderFile, &fileData);
|
||||
|
||||
if (fileData.file)
|
||||
{
|
||||
if (!fileData.persistant)
|
||||
{
|
||||
nsresult rv = (fileData.file)->QueryInterface(uuid, result);
|
||||
NS_RELEASE(fileData.file);
|
||||
return rv;
|
||||
}
|
||||
Set(prop, NS_STATIC_CAST(nsIFile*, fileData.file));
|
||||
NS_RELEASE(fileData.file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now check again to see if it was added above.
|
||||
if (Exists(&key))
|
||||
if (mHashtable->Exists(&key))
|
||||
{
|
||||
nsCOMPtr<nsIFile> ourFile;
|
||||
nsISupports* value = (nsISupports*)nsHashtable::Get(&key);
|
||||
nsISupports* value = (nsISupports*)mHashtable->Get(&key);
|
||||
|
||||
if (value && NS_SUCCEEDED(value->QueryInterface(NS_GET_IID(nsIFile), getter_AddRefs(ourFile))))
|
||||
{
|
||||
@@ -368,7 +367,7 @@ NS_IMETHODIMP
|
||||
nsDirectoryService::Set(const char* prop, nsISupports* value)
|
||||
{
|
||||
nsStringKey key(prop);
|
||||
if (Exists(&key) || value == nsnull)
|
||||
if (mHashtable->Exists(&key) || value == nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIFile> ourFile;
|
||||
@@ -378,7 +377,8 @@ nsDirectoryService::Set(const char* prop, nsISupports* value)
|
||||
nsIFile* cloneFile;
|
||||
ourFile->Clone(&cloneFile);
|
||||
|
||||
nsISupports* prevValue = (nsISupports*)Put(&key, value);
|
||||
nsISupports* prevValue = (nsISupports*)mHashtable->Put(&key,
|
||||
NS_STATIC_CAST(nsISupports*,cloneFile));
|
||||
NS_IF_RELEASE(prevValue);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -401,3 +401,52 @@ nsDirectoryService::Has(const char *prop, PRBool *_retval)
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::RegisterProvider(nsIDirectoryServiceProvider *prov)
|
||||
{
|
||||
if (!prov)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupports> supports = do_QueryInterface(prov);
|
||||
if (supports)
|
||||
return mProviders->AppendElement(supports);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval)
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> localFile;
|
||||
nsresult rv;
|
||||
|
||||
*_retval = nsnull;
|
||||
*persistant = PR_TRUE;
|
||||
|
||||
// check to see if it is one of our defaults
|
||||
|
||||
if (strncmp(prop, "xpcom.currentProcess.componentRegistry", 38) == 0)
|
||||
{
|
||||
rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
localFile->Append(COMPONENT_REGISTRY_NAME);
|
||||
}
|
||||
else if (strncmp(prop, "xpcom.currentProcess.componentDirectory", 39) == 0)
|
||||
{
|
||||
rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
localFile->Append(COMPONENT_DIRECTORY);
|
||||
}
|
||||
|
||||
if (localFile)
|
||||
return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,35 +23,36 @@
|
||||
#ifndef nsDirectoryService_h___
|
||||
#define nsDirectoryService_h___
|
||||
|
||||
#include "nsIProperties.h"
|
||||
#include "nsIDirectoryService.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsAgg.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsISupportsArray.h"
|
||||
class nsDirectoryService : public nsIDirectoryService, public nsIProperties, public nsIDirectoryServiceProvider
|
||||
{
|
||||
public:
|
||||
|
||||
#define NS_DIRECTORY_SERVICE_PROGID "component://netscape/file/directory_service"
|
||||
#define NS_DIRECTORY_SERVICE_CLASSNAME "nsIFile Directory Service"
|
||||
NS_DEFINE_STATIC_CID_ACCESSOR(NS_DIRECTORY_SERVICE_CID);
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
class nsDirectoryService : public nsIProperties, public nsHashtable {
|
||||
public:
|
||||
NS_DECL_NSIPROPERTIES
|
||||
|
||||
NS_DEFINE_STATIC_CID_ACCESSOR(NS_DIRECTORY_SERVICE_CID)
|
||||
NS_DECL_NSIDIRECTORYSERVICE
|
||||
|
||||
NS_DECL_AGGREGATED
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
|
||||
|
||||
NS_DECL_NSIPROPERTIES
|
||||
|
||||
// nsProperties methods:
|
||||
nsDirectoryService(nsISupports* outer);
|
||||
nsDirectoryService();
|
||||
virtual ~nsDirectoryService();
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
static PRBool ReleaseValues(nsHashKey* key, void* data, void* closure);
|
||||
private:
|
||||
static nsDirectoryService* mService;
|
||||
|
||||
static PRBool ReleaseValues(nsHashKey* key, void* data, void* closure);
|
||||
nsHashtable* mHashtable;
|
||||
nsCOMPtr<nsISupportsArray> mProviders;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,9 @@
|
||||
#include "shellapi.h"
|
||||
#include "shlguid.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "prproces.h"
|
||||
|
||||
@@ -117,70 +119,6 @@ myLL_L2II(PRInt64 result, PRInt32 *hi, PRInt32 *lo )
|
||||
LL_L2I(*lo, a64);
|
||||
}
|
||||
|
||||
nsresult
|
||||
MyGetFileAttributesEx(const char* file, WIN32_FILE_ATTRIBUTE_DATA* data)
|
||||
{
|
||||
BOOL okay;
|
||||
if (!data || !file)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
okay = PR_FALSE;
|
||||
|
||||
memset(data, 0, sizeof(WIN32_FILE_ATTRIBUTE_DATA));
|
||||
data->dwFileAttributes = GetFileAttributes(file);
|
||||
|
||||
if(data->dwFileAttributes != 0xFFFFFFFF)
|
||||
{
|
||||
if(! (data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
HANDLE hFile = CreateFile(file,
|
||||
0,
|
||||
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, I dont think that there is a wy to get the time or size.
|
||||
okay = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!okay)
|
||||
return ConvertWinError(GetLastError());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
class nsDirEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
@@ -564,24 +502,24 @@ nsLocalFile::ResolveAndStat(PRBool resolveTerminal)
|
||||
}
|
||||
mLastResolution = resolveTerminal;
|
||||
|
||||
const char *workingFilePath = mWorkingPath.GetBuffer();
|
||||
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.
|
||||
|
||||
result = MyGetFileAttributesEx( workingFilePath, &mFileAttrData);
|
||||
|
||||
if ( NS_SUCCEEDED(result) )
|
||||
const char *workingFilePath = mWorkingPath.GetBuffer();
|
||||
|
||||
PRStatus status = PR_GetFileInfo64(workingFilePath, &mFileInfo64);
|
||||
if ( status == PR_SUCCESS )
|
||||
{
|
||||
mResolvedPath.SetString(workingFilePath);
|
||||
mDirty = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult result;
|
||||
|
||||
// okay, something is wrong with the working path. We will try to resolve it.
|
||||
|
||||
char *resolvePath;
|
||||
@@ -602,10 +540,13 @@ nsLocalFile::ResolveAndStat(PRBool resolveTerminal)
|
||||
char linkStr[MAX_PATH];
|
||||
strcpy(linkStr, mResolvedPath.GetBuffer());
|
||||
strcat(linkStr, ".lnk");
|
||||
result = MyGetFileAttributesEx(linkStr, &mFileAttrData);
|
||||
|
||||
if (NS_SUCCEEDED(result))
|
||||
status = PR_GetFileInfo64(linkStr, &mFileInfo64);
|
||||
|
||||
if ( status == PR_SUCCESS )
|
||||
mDirty = PR_FALSE;
|
||||
else
|
||||
result = NS_ERROR_FAILURE;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -744,7 +685,7 @@ nsLocalFile::Append(const char *node)
|
||||
{
|
||||
if ( (node == nsnull) ||
|
||||
(*node == '/') ||
|
||||
(*node == '.') ||
|
||||
(strstr(node, "..") != nsnull) ||
|
||||
(strchr(node, '\\') != nsnull) ||
|
||||
(strchr(node, '/') != nsnull) )
|
||||
{
|
||||
@@ -1198,60 +1139,10 @@ nsLocalFile::GetLastModificationDate(PRInt64 *aLastModificationDate)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
PRUint32 high = mFileAttrData.ftLastWriteTime.dwHighDateTime;
|
||||
PRUint32 low = mFileAttrData.ftLastWriteTime.dwLowDateTime;
|
||||
|
||||
myLL_II2L(high, low, aLastModificationDate);
|
||||
|
||||
*aLastModificationDate = mFileInfo64.modifyTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::SetLastModificationDate(PRInt64 aLastModificationDate)
|
||||
{
|
||||
nsresult rv = ResolveAndStat(PR_TRUE);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
FILETIME time = mFileAttrData.ftLastWriteTime;
|
||||
|
||||
PRInt32 hi, lo;
|
||||
myLL_L2II(aLastModificationDate, &hi, &lo );
|
||||
|
||||
time.dwHighDateTime = hi;
|
||||
time.dwLowDateTime = lo;
|
||||
|
||||
const char *filePath = mResolvedPath.GetBuffer();
|
||||
|
||||
HANDLE file = CreateFile( filePath, // pointer to name of the file
|
||||
GENERIC_WRITE, // access (write) mode
|
||||
0, // share mode
|
||||
NULL, // pointer to security attributes
|
||||
OPEN_EXISTING, // how to create
|
||||
0, // file attributes (??xxx)
|
||||
NULL);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
// could not open file for writing.
|
||||
MakeDirty();
|
||||
return NS_ERROR_FAILURE; //TODO better error code
|
||||
}
|
||||
|
||||
if ( 0 == SetFileTime(file, NULL, &time, &time) )
|
||||
{
|
||||
// could not set time
|
||||
MakeDirty();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
MakeDirty();
|
||||
|
||||
CloseHandle( file );
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::GetLastModificationDateOfLink(PRInt64 *aLastModificationDate)
|
||||
@@ -1265,26 +1156,42 @@ nsLocalFile::GetLastModificationDateOfLink(PRInt64 *aLastModificationDate)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
FILETIME time = mFileAttrData.ftLastWriteTime;
|
||||
|
||||
myLL_II2L(time.dwHighDateTime, time.dwLowDateTime, aLastModificationDate);
|
||||
|
||||
*aLastModificationDate = mFileInfo64.modifyTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::SetLastModificationDate(PRInt64 aLastModificationDate)
|
||||
{
|
||||
return nsLocalFile::SetModDate(aLastModificationDate, PR_TRUE);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::SetLastModificationDateOfLink(PRInt64 aLastModificationDate)
|
||||
{
|
||||
nsresult rv = ResolveAndStat(PR_FALSE);
|
||||
return nsLocalFile::SetModDate(aLastModificationDate, PR_FALSE);
|
||||
}
|
||||
|
||||
static const PRTime filetime_offset = 116444736000000000i64;
|
||||
nsresult
|
||||
nsLocalFile::SetModDate(PRInt64 aLastModificationDate, PRBool resolveTerminal)
|
||||
{
|
||||
nsresult rv = ResolveAndStat(resolveTerminal);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
PRInt32 hi, lo;
|
||||
myLL_L2II(aLastModificationDate, &hi, &lo );
|
||||
|
||||
FILETIME time = mFileAttrData.ftLastWriteTime;
|
||||
|
||||
PRInt64 windowsTime = aLastModificationDate;
|
||||
|
||||
windowsTime = (windowsTime + filetime_offset) * 10i64;
|
||||
|
||||
PRInt32 hi, lo;
|
||||
myLL_L2II(windowsTime, &hi, &lo );
|
||||
|
||||
FILETIME time;
|
||||
time.dwHighDateTime = hi;
|
||||
time.dwLowDateTime = lo;
|
||||
|
||||
@@ -1298,31 +1205,36 @@ nsLocalFile::SetLastModificationDateOfLink(PRInt64 aLastModificationDate)
|
||||
0, // file attributes (??xxx)
|
||||
NULL);
|
||||
|
||||
MakeDirty();
|
||||
|
||||
if (!file)
|
||||
{
|
||||
// could not open file for writing.
|
||||
MakeDirty();
|
||||
return NS_ERROR_FAILURE; //TODO better error code
|
||||
}
|
||||
|
||||
if ( 0 == SetFileTime(file, NULL, &time, &time) )
|
||||
{
|
||||
// could not set time
|
||||
MakeDirty();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
MakeDirty();
|
||||
|
||||
CloseHandle( file );
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::GetPermissions(PRUint32 *aPermissions)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsresult rv = ResolveAndStat(PR_TRUE);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
const char *filePath = mResolvedPath.GetBuffer();
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@@ -1335,13 +1247,31 @@ nsLocalFile::GetPermissionsOfLink(PRUint32 *aPermissionsOfLink)
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::SetPermissions(PRUint32 aPermissions)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsresult rv = ResolveAndStat(PR_TRUE);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
const char *filePath = mResolvedPath.GetBuffer();
|
||||
if( chmod(filePath, aPermissions) == -1 )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::SetPermissionsOfLink(PRUint32 aPermissions)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsresult rv = ResolveAndStat(PR_FALSE);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
const char *filePath = mResolvedPath.GetBuffer();
|
||||
if( chmod(filePath, aPermissions) == -1 )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1357,8 +1287,8 @@ nsLocalFile::GetFileSize(PRInt64 *aFileSize)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
myLL_II2L(mFileAttrData.nFileSizeHigh, mFileAttrData.nFileSizeLow, aFileSize);
|
||||
|
||||
*aFileSize = mFileInfo64.size;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -1430,7 +1360,7 @@ nsLocalFile::GetFileSizeOfLink(PRInt64 *aFileSize)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
myLL_II2L(mFileAttrData.nFileSizeHigh, mFileAttrData.nFileSizeLow, aFileSize);
|
||||
*aFileSize = mFileInfo64.size;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -1547,7 +1477,10 @@ nsLocalFile::IsWritable(PRBool *_retval)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*_retval = !((mFileAttrData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0);
|
||||
const char *workingFilePath = mWorkingPath.GetBuffer();
|
||||
DWORD word = GetFileAttributes(workingFilePath);
|
||||
|
||||
*_retval = !((word & FILE_ATTRIBUTE_READONLY) != 0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1618,8 +1551,8 @@ nsLocalFile::IsDirectory(PRBool *_retval)
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*_retval = ((mFileAttrData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
|
||||
|
||||
*_retval = (mFileInfo64.type == PR_FILE_DIRECTORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1627,9 +1560,15 @@ nsLocalFile::IsDirectory(PRBool *_retval)
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::IsFile(PRBool *_retval)
|
||||
{
|
||||
nsresult rv = IsDirectory(_retval);
|
||||
*_retval = !*_retval;
|
||||
NS_ENSURE_ARG(_retval);
|
||||
*_retval = PR_FALSE;
|
||||
|
||||
nsresult rv = ResolveAndStat(PR_TRUE);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*_retval = (mFileInfo64.type == PR_FILE_FILE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -1644,7 +1583,10 @@ nsLocalFile::IsHidden(PRBool *_retval)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*_retval = ((mFileAttrData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0);
|
||||
const char *workingFilePath = mWorkingPath.GetBuffer();
|
||||
DWORD word = GetFileAttributes(workingFilePath);
|
||||
|
||||
*_retval = ((word & FILE_ATTRIBUTE_HIDDEN) != 0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1684,7 +1626,10 @@ nsLocalFile::IsSpecial(PRBool *_retval)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*_retval = ((mFileAttrData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0);
|
||||
const char *workingFilePath = mWorkingPath.GetBuffer();
|
||||
DWORD word = GetFileAttributes(workingFilePath);
|
||||
|
||||
*_retval = ((word & FILE_ATTRIBUTE_SYSTEM) != 0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -79,8 +79,8 @@ private:
|
||||
|
||||
IPersistFile* mPersistFile;
|
||||
IShellLink* mShellLink;
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA mFileAttrData;
|
||||
|
||||
PRFileInfo64 mFileInfo64;
|
||||
|
||||
void MakeDirty();
|
||||
nsresult ResolveAndStat(PRBool resolveTerminal);
|
||||
@@ -89,6 +89,7 @@ private:
|
||||
nsresult CopyMove(nsIFile *newParentDir, const char *newName, PRBool followSymlinks, PRBool move);
|
||||
nsresult CopySingleFile(nsIFile *source, nsIFile* dest, const char * newName, PRBool followSymlinks, PRBool move);
|
||||
|
||||
nsresult SetModDate(PRInt64 aLastModificationDate, PRBool resolveTerminal);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user