зеркало из https://github.com/mozilla/gecko-dev.git
Bug 69114 go to the target of a .url file, instead of showing its contents, when
opening such a file in mozilla r=darin sr=bz
This commit is contained in:
Родитель
a5ebcc2be2
Коммит
3ece6a2483
|
@ -40,7 +40,7 @@
|
|||
|
||||
interface nsIFile;
|
||||
|
||||
[scriptable, uuid(987fb083-d7ff-46dc-9ee3-ab6e52501d53)]
|
||||
[scriptable, uuid(255602ea-c31f-4d29-8f35-905ead3f76f4)]
|
||||
interface nsIFileProtocolHandler : nsIProtocolHandler
|
||||
{
|
||||
/**
|
||||
|
@ -66,4 +66,15 @@ interface nsIFileProtocolHandler : nsIProtocolHandler
|
|||
* A local file will be created if the URL string begins with file://.
|
||||
*/
|
||||
nsIFile getFileFromURLSpec(in AUTF8String url);
|
||||
|
||||
/**
|
||||
* Takes a local file and tries to interpret it as an internet shortcut
|
||||
* (e.g. .url files on windows).
|
||||
* @param file The local file to read
|
||||
* @return The URI the file refers to
|
||||
*
|
||||
* @throw NS_ERROR_NOT_AVAILABLE if the OS does not support such files.
|
||||
* @throw NS_ERROR_NOT_AVAILABLE if this file is not an internet shortcut.
|
||||
*/
|
||||
nsIURI readURLFile(in nsIFile file);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
// vim:ts=4 sw=4 sts=4 et cin:
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -43,6 +44,18 @@
|
|||
#include "nsNetCID.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIURL.h"
|
||||
|
||||
// URL file handling, copied and modified from xpfe/components/bookmarks/src/nsBookmarksService.cpp
|
||||
#ifdef XP_WIN
|
||||
#include <shlobj.h>
|
||||
#include <intshcut.h>
|
||||
#include "nsIFileURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
#ifdef CompareString
|
||||
#undef CompareString
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -64,6 +77,62 @@ NS_IMPL_THREADSAFE_ISUPPORTS3(nsFileProtocolHandler,
|
|||
//-----------------------------------------------------------------------------
|
||||
// nsIProtocolHandler methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileProtocolHandler::ReadURLFile(nsIFile* aFile, nsIURI** aURI)
|
||||
{
|
||||
// IUniformResourceLocator isn't supported by VC5 (bless its little heart)
|
||||
#if !defined(XP_WIN) || _MSC_VER < 1200
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
#else
|
||||
nsAutoString path;
|
||||
rv = aFile->GetPath(path);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (path.Length() < 4)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
if (!StringTail(path, 4).LowerCaseEqualsLiteral(".url"))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
HRESULT result;
|
||||
|
||||
rv = NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
IUniformResourceLocator* urlLink = nsnull;
|
||||
result = ::CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_IUniformResourceLocator, (void**)&urlLink);
|
||||
if (SUCCEEDED(result) && urlLink) {
|
||||
IPersistFile* urlFile = nsnull;
|
||||
result = urlLink->QueryInterface(IID_IPersistFile, (void**)&urlFile);
|
||||
if (SUCCEEDED(result) && urlFile) {
|
||||
result = urlFile->Load(path.get(), STGM_READ);
|
||||
if (SUCCEEDED(result) ) {
|
||||
LPSTR lpTemp = nsnull;
|
||||
|
||||
// The URL this method will give us back seems to be already
|
||||
// escaped. Hence, do not do escaping of our own.
|
||||
result = urlLink->GetURL(&lpTemp);
|
||||
if (SUCCEEDED(result) && lpTemp) {
|
||||
rv = NS_NewURI(aURI, lpTemp);
|
||||
|
||||
// free the string that GetURL alloc'd
|
||||
IMalloc* pMalloc;
|
||||
result = SHGetMalloc(&pMalloc);
|
||||
if (SUCCEEDED(result)) {
|
||||
pMalloc->Free(lpTemp);
|
||||
pMalloc->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
urlFile->Release();
|
||||
}
|
||||
urlLink->Release();
|
||||
}
|
||||
return rv;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileProtocolHandler::GetScheme(nsACString &result)
|
||||
{
|
||||
|
@ -105,6 +174,22 @@ nsFileProtocolHandler::NewURI(const nsACString &spec,
|
|||
NS_IMETHODIMP
|
||||
nsFileProtocolHandler::NewChannel(nsIURI *uri, nsIChannel **result)
|
||||
{
|
||||
// This file may be a url file
|
||||
nsCOMPtr<nsIFileURL> url(do_QueryInterface(uri));
|
||||
if (url) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = url->GetFile(getter_AddRefs(file));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = ReadURLFile(file, getter_AddRefs(uri));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = NS_NewChannel(result, uri);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsFileChannel *chan = new nsFileChannel();
|
||||
if (!chan)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
|
|
@ -738,38 +738,35 @@ nsClipboard :: FindURLFromLocalFile ( IDataObject* inDataObject, UINT inIndex, v
|
|||
|
||||
nsresult loadResult = GetNativeDataOffClipboard(inDataObject, inIndex, GetFormat(kFileMime), outData, outDataLen);
|
||||
if ( NS_SUCCEEDED(loadResult) && *outData ) {
|
||||
// we have a file path in |data|. Is it an internet shortcut or a normal file?
|
||||
char* filepath = NS_REINTERPRET_CAST(char*, *outData);
|
||||
if ( IsInternetShortcut(filepath) ) {
|
||||
char* buffer = nsnull;
|
||||
// we have a file path in |data|. Is it an internet shortcut or a normal file?
|
||||
const char* filepath = NS_REINTERPRET_CAST(char*, *outData);
|
||||
nsCOMPtr<nsILocalFile> file;
|
||||
nsresult rv = NS_NewNativeLocalFile(nsDependentCString(filepath), PR_TRUE, getter_AddRefs(file));
|
||||
if (NS_FAILED(rv))
|
||||
return dataFound;
|
||||
|
||||
ResolveShortcut ( filepath, &buffer );
|
||||
if ( buffer ) {
|
||||
if ( IsInternetShortcut(filepath) ) {
|
||||
nsCAutoString url;
|
||||
ResolveShortcut( file, url );
|
||||
if ( !url.IsEmpty() ) {
|
||||
// convert it to unicode and pass it out
|
||||
nsMemory::Free(*outData);
|
||||
nsAutoString urlUnicode;
|
||||
urlUnicode.AssignWithConversion( buffer );
|
||||
*outData = ToNewUnicode(urlUnicode);
|
||||
*outDataLen = strlen(buffer) * sizeof(PRUnichar);
|
||||
nsMemory::Free(buffer);
|
||||
*outData = UTF8ToNewUnicode(url);
|
||||
*outDataLen = nsCRT::strlen(NS_STATIC_CAST(PRUnichar*, *outData));
|
||||
|
||||
dataFound = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// we have a normal file, use some Necko objects to get our file path
|
||||
nsCOMPtr<nsILocalFile> file;
|
||||
if ( NS_SUCCEEDED(NS_NewNativeLocalFile(nsDependentCString(filepath), PR_TRUE, getter_AddRefs(file))) ) {
|
||||
nsCAutoString urlSpec;
|
||||
NS_GetURLSpecFromFile(file, urlSpec);
|
||||
nsCAutoString urlSpec;
|
||||
NS_GetURLSpecFromFile(file, urlSpec);
|
||||
|
||||
// convert it to unicode and pass it out
|
||||
nsMemory::Free(*outData);
|
||||
*outData = ToNewUnicode(NS_ConvertUTF8toUCS2(urlSpec));
|
||||
*outDataLen = strlen(urlSpec.get()) * sizeof(PRUnichar);
|
||||
dataFound = PR_TRUE;
|
||||
|
||||
}
|
||||
// convert it to unicode and pass it out
|
||||
nsMemory::Free(*outData);
|
||||
*outData = UTF8ToNewUnicode(urlSpec);
|
||||
*outDataLen = nsCRT::strlen(NS_STATIC_CAST(PRUnichar*, *outData));
|
||||
dataFound = PR_TRUE;
|
||||
} // else regular file
|
||||
}
|
||||
|
||||
|
@ -780,48 +777,20 @@ nsClipboard :: FindURLFromLocalFile ( IDataObject* inDataObject, UINT inIndex, v
|
|||
//
|
||||
// ResolveShortcut
|
||||
//
|
||||
// Use some Win32 mumbo-jumbo to read in the shortcut file and parse out the URL
|
||||
// in references
|
||||
//
|
||||
void
|
||||
nsClipboard :: ResolveShortcut ( const char* inFileName, char** outURL )
|
||||
nsClipboard :: ResolveShortcut ( nsILocalFile* aFile, nsACString& outURL )
|
||||
{
|
||||
// IUniformResourceLocator isn't supported by VC5 (bless its little heart)
|
||||
#if _MSC_VER >= 1200
|
||||
HRESULT result;
|
||||
nsCOMPtr<nsIFileProtocolHandler> fph;
|
||||
nsresult rv = NS_GetFileProtocolHandler(getter_AddRefs(fph));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
IUniformResourceLocator* urlLink = nsnull;
|
||||
result = ::CoCreateInstance ( CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_IUniformResourceLocator, (void**)&urlLink );
|
||||
if ( SUCCEEDED(result) && urlLink ) {
|
||||
IPersistFile* urlFile = nsnull;
|
||||
result = urlLink->QueryInterface (IID_IPersistFile, (void**)&urlFile );
|
||||
if ( SUCCEEDED(result) && urlFile ) {
|
||||
WORD wideFileName[MAX_PATH];
|
||||
::MultiByteToWideChar ( CP_ACP, 0, inFileName, -1, wideFileName, MAX_PATH );
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = fph->ReadURLFile(aFile, getter_AddRefs(uri));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
result = urlFile->Load(wideFileName, STGM_READ);
|
||||
if (SUCCEEDED(result) ) {
|
||||
LPSTR lpTemp = nsnull;
|
||||
|
||||
result = urlLink->GetURL(&lpTemp);
|
||||
if ( SUCCEEDED(result) && lpTemp ) {
|
||||
*outURL = PL_strdup (lpTemp);
|
||||
|
||||
// free the string that GetURL alloc'd
|
||||
IMalloc* pMalloc;
|
||||
result = SHGetMalloc(&pMalloc);
|
||||
if ( SUCCEEDED(result) ) {
|
||||
pMalloc->Free(lpTemp);
|
||||
pMalloc->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
urlFile->Release();
|
||||
}
|
||||
urlLink->Release();
|
||||
}
|
||||
#endif
|
||||
uri->GetSpec(outURL);
|
||||
} // ResolveShortcut
|
||||
|
||||
|
||||
|
@ -835,9 +804,8 @@ nsClipboard :: IsInternetShortcut ( const char* inFileName )
|
|||
{
|
||||
if ( strstr(inFileName, ".URL") || strstr(inFileName, ".url") )
|
||||
return PR_TRUE;
|
||||
else
|
||||
return PR_FALSE;
|
||||
|
||||
|
||||
return PR_FALSE;
|
||||
} // IsInternetShortcut
|
||||
|
||||
|
||||
|
|
|
@ -3741,46 +3741,20 @@ nsBookmarksService::ResolveKeyword(const PRUnichar *aUserInput, char **aShortcut
|
|||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// *** code copied from widget/src/windows/nsClipboard.cpp
|
||||
// Determines the URL for a shortcut file
|
||||
|
||||
static void ResolveShortcut(const nsAFlatString &aFileName, char** aOutURL)
|
||||
static void ResolveShortcut(nsIFile* aFile, nsACString& aURI)
|
||||
{
|
||||
nsCOMPtr<nsIFileProtocolHandler> fph;
|
||||
nsresult rv = NS_GetFileProtocolHandler(getter_AddRefs(fph));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
// IUniformResourceLocator isn't supported by VC5 (bless its little heart)
|
||||
#if _MSC_VER >= 1200
|
||||
HRESULT result;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = fph->ReadURLFile(aFile, getter_AddRefs(uri));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
IUniformResourceLocator* urlLink = nsnull;
|
||||
result = ::CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_IUniformResourceLocator, (void**)&urlLink);
|
||||
if (SUCCEEDED(result) && urlLink) {
|
||||
IPersistFile* urlFile = nsnull;
|
||||
result = urlLink->QueryInterface(IID_IPersistFile, (void**)&urlFile);
|
||||
if (SUCCEEDED(result) && urlFile) {
|
||||
|
||||
result = urlFile->Load(aFileName.get(), STGM_READ);
|
||||
if (SUCCEEDED(result) ) {
|
||||
LPSTR lpTemp = nsnull;
|
||||
|
||||
result = urlLink->GetURL(&lpTemp);
|
||||
if (SUCCEEDED(result) && lpTemp) {
|
||||
*aOutURL = PL_strdup(lpTemp);
|
||||
|
||||
// free the string that GetURL alloc'd
|
||||
IMalloc* pMalloc;
|
||||
result = SHGetMalloc(&pMalloc);
|
||||
if (SUCCEEDED(result)) {
|
||||
pMalloc->Free(lpTemp);
|
||||
pMalloc->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
urlFile->Release();
|
||||
}
|
||||
urlLink->Release();
|
||||
}
|
||||
#endif
|
||||
uri->GetSpec(aURI);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -3888,25 +3862,18 @@ nsBookmarksService::ParseFavoritesFolder(nsIFile* aDirectory, nsIRDFResource* aP
|
|||
nsCAutoString extension;
|
||||
|
||||
url->GetFileExtension(extension);
|
||||
if (!extension.Equals(NS_LITERAL_CSTRING("url"),
|
||||
nsCaseInsensitiveCStringComparator()))
|
||||
if (!extension.LowerCaseEqualsLiteral("url"))
|
||||
continue;
|
||||
|
||||
nsAutoString name(Substring(bookmarkName, 0,
|
||||
bookmarkName.Length() - extension.Length() - 1));
|
||||
|
||||
nsAutoString path;
|
||||
currFile->GetPath(path);
|
||||
|
||||
nsXPIDLCString resolvedURL;
|
||||
ResolveShortcut(path, getter_Copies(resolvedURL));
|
||||
nsCAutoString resolvedURL;
|
||||
ResolveShortcut(currFile, resolvedURL);
|
||||
|
||||
nsCOMPtr<nsIRDFResource> bookmark;
|
||||
// As far as I can tell, IUniformResourceLocator::GetURL()
|
||||
// returns the URL in pure ASCII. However, it could be UTF-8 (I'm
|
||||
// almost sure that it's not in any legacy encoding) so that I'm
|
||||
// assuming it's in UTF-8.
|
||||
// http://msdn.microsoft.com/library/default.asp?url=/workshop/misc/shortcuts/reference/iuniformresourcelocator.asp
|
||||
// ResolveShortcut gives us a UTF8 string (uri->GetSpec)
|
||||
rv = CreateBookmarkInContainer(name.get(),
|
||||
NS_ConvertUTF8toUTF16(resolvedURL).get(),
|
||||
nsnull, nsnull, nsnull, aParentResource, -1,
|
||||
|
|
Загрузка…
Ссылка в новой задаче