Bug 837932 - Update dir svc media paths for Win7 and up - media dirs should point to Library default save locations. r=bsmedberg

This commit is contained in:
Jim Mathies 2013-02-11 13:03:54 -06:00
parent df9dd9145d
commit 206885bb40
5 changed files with 95 additions and 10 deletions

View File

@ -6,6 +6,7 @@
#include "SpecialSystemDirectory.h"
#include "nsString.h"
#include "nsDependentString.h"
#include "nsAutoPtr.h"
#if defined(XP_WIN)
@ -15,6 +16,9 @@
#include <stdio.h>
#include <string.h>
#include <direct.h>
#include <shlobj.h>
#include <knownfolders.h>
#include <guiddef.h>
#elif defined(XP_OS2)
@ -101,9 +105,8 @@ static nsresult GetKnownFolder(GUID* guid, nsIFile** aFile)
return rv;
}
//----------------------------------------------------------------------------------------
static nsresult GetWindowsFolder(int folder, nsIFile** aFile)
//----------------------------------------------------------------------------------------
static nsresult
GetWindowsFolder(int folder, nsIFile** aFile)
{
WCHAR path_orig[MAX_PATH + 3];
WCHAR *path = path_orig+1;
@ -123,6 +126,65 @@ static nsresult GetWindowsFolder(int folder, nsIFile** aFile)
return NS_NewLocalFile(nsDependentString(path, len), true, aFile);
}
__inline HRESULT
SHLoadLibraryFromKnownFolder(REFKNOWNFOLDERID aFolderId, DWORD aMode,
REFIID riid, void **ppv)
{
*ppv = NULL;
IShellLibrary *plib;
HRESULT hr = CoCreateInstance(CLSID_ShellLibrary, NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&plib));
if (SUCCEEDED(hr)) {
hr = plib->LoadLibraryFromKnownFolder(aFolderId, aMode);
if (SUCCEEDED(hr)) {
hr = plib->QueryInterface(riid, ppv);
}
plib->Release();
}
return hr;
}
/*
* Check to see if we're on Win7 and up, and if so, returns the default
* save-to location for the Windows Library passed in through aFolderId.
* Otherwise falls back on pre-win7 GetWindowsFolder.
*/
static nsresult
GetLibrarySaveToPath(int aFallbackFolderId, REFKNOWNFOLDERID aFolderId,
nsIFile** aFile)
{
// Skip off checking for library support if the os is Vista or lower.
DWORD dwVersion = GetVersion();
if ((DWORD)(LOBYTE(LOWORD(dwVersion))) < 6 ||
((DWORD)(LOBYTE(LOWORD(dwVersion))) == 6 &&
(DWORD)(HIBYTE(LOWORD(dwVersion))) == 0))
return GetWindowsFolder(aFallbackFolderId, aFile);
nsRefPtr<IShellLibrary> shellLib;
nsRefPtr<IShellItem> savePath;
HRESULT hr =
SHLoadLibraryFromKnownFolder(aFolderId, STGM_READ,
IID_IShellLibrary, getter_AddRefs(shellLib));
if (shellLib &&
SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
getter_AddRefs(savePath)))) {
PRUnichar* str = nullptr;
if (SUCCEEDED(savePath->GetDisplayName(SIGDN_FILESYSPATH, &str))) {
nsAutoString path;
path.Assign(str);
path.AppendLiteral("\\");
nsresult rv =
NS_NewLocalFile(path, false, aFile);
CoTaskMemFree(str);
return rv;
}
}
return GetWindowsFolder(aFallbackFolderId, aFile);
}
/**
* Provides a fallback for getting the path to APPDATA or LOCALAPPDATA by
* querying the registry when the call to SHGetSpecialFolderPathW is unable to
@ -747,17 +809,29 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
rv = GetRegWindowsAppDataFolder(true, aFile);
return rv;
}
case Win_Documents:
{
return GetLibrarySaveToPath(CSIDL_MYDOCUMENTS,
FOLDERID_DocumentsLibrary,
aFile);
}
case Win_Pictures:
{
return GetWindowsFolder(CSIDL_MYPICTURES, aFile);
return GetLibrarySaveToPath(CSIDL_MYPICTURES,
FOLDERID_PicturesLibrary,
aFile);
}
case Win_Music:
{
return GetWindowsFolder(CSIDL_MYMUSIC, aFile);
return GetLibrarySaveToPath(CSIDL_MYMUSIC,
FOLDERID_MusicLibrary,
aFile);
}
case Win_Videos:
{
return GetWindowsFolder(CSIDL_MYVIDEO, aFile);
return GetLibrarySaveToPath(CSIDL_MYVIDEO,
FOLDERID_VideosLibrary,
aFile);
}
#endif // XP_WIN

View File

@ -74,10 +74,11 @@ enum SystemDirectories {
Win_ProgramFiles = 229,
Win_Downloads = 230,
Win_Common_AppData = 231,
Win_Pictures = 232,
Win_Music = 233,
Win_Videos = 234,
Win_Documents = 232,
Win_Pictures = 233,
Win_Music = 234,
Win_Videos = 235,
Unix_LocalDirectory = 301,
Unix_LibDirectory = 302,
Unix_HomeDirectory = 303,

View File

@ -823,6 +823,10 @@ nsDirectoryService::GetFile(const char *prop, bool *persistent, nsIFile **_retva
{
rv = GetSpecialSystemDirectory(Win_Downloads, getter_AddRefs(localFile));
}
else if (inAtom == nsDirectoryService::sDocs)
{
rv = GetSpecialSystemDirectory(Win_Documents, getter_AddRefs(localFile));
}
else if (inAtom == nsDirectoryService::sPictures)
{
rv = GetSpecialSystemDirectory(Win_Pictures, getter_AddRefs(localFile));

View File

@ -73,6 +73,7 @@ DIR_ATOM(sLocalAppdata, NS_WIN_LOCAL_APPDATA_DIR)
DIR_ATOM(sPrinthood, NS_WIN_PRINTHOOD)
DIR_ATOM(sWinCookiesDirectory, NS_WIN_COOKIES_DIR)
DIR_ATOM(sDefaultDownloadDirectory, NS_WIN_DEFAULT_DOWNLOAD_DIR)
DIR_ATOM(sDocs, NS_WIN_DOCUMENTS_DIR)
DIR_ATOM(sPictures, NS_WIN_PICTURES_DIR)
DIR_ATOM(sMusic, NS_WIN_MUSIC_DIR)
DIR_ATOM(sVideos, NS_WIN_VIDEOS_DIR)

View File

@ -122,6 +122,11 @@
#define NS_WIN_PRINTHOOD "PrntHd"
#define NS_WIN_COOKIES_DIR "CookD"
#define NS_WIN_DEFAULT_DOWNLOAD_DIR "DfltDwnld"
// On Win7 and up these ids will return the default save-to location for
// Windows Libraries associated with the specific content type. For other
// os they return the local user folder. Note these can return network file
// paths which can jank the ui thread so be careful how you access them.
#define NS_WIN_DOCUMENTS_DIR "Docs"
#define NS_WIN_PICTURES_DIR "Pict"
#define NS_WIN_MUSIC_DIR "Music"
#define NS_WIN_VIDEOS_DIR "Vids"