diff options
Diffstat (limited to 'system')
-rw-r--r-- | system/graphics/2d/BaseRect.h | 58 | ||||
-rw-r--r-- | system/interface/windows/nsFilePicker.cpp | 350 | ||||
-rw-r--r-- | system/interface/windows/nsFilePicker.h | 32 |
3 files changed, 165 insertions, 275 deletions
diff --git a/system/graphics/2d/BaseRect.h b/system/graphics/2d/BaseRect.h index b1eed9ddb..a4e5e4c1d 100644 --- a/system/graphics/2d/BaseRect.h +++ b/system/graphics/2d/BaseRect.h @@ -107,6 +107,10 @@ struct BaseRect { // (including edges) of *this and aRect. If there are no points in that // intersection, returns an empty rectangle with x/y set to the std::max of the x/y // of *this and aRect. + // + // Intersection with an empty Rect may not produce an empty Rect if overflow + // occurs. e.g. {INT_MIN, 0, 0, 20} Intersect { 5000, 0, 500, 20 } gives: + // the non-emtpy {5000, 0, 500, 20 } instead of {5000, 0, 0, 0} MOZ_MUST_USE Sub Intersect(const Sub& aRect) const { Sub result; @@ -119,6 +123,26 @@ struct BaseRect { } return result; } + // Gives the same results as Intersect() but handles integer overflow + // better. This comes at a tiny cost in performance. + // e.g. {INT_MIN, 0, 0, 20} Intersect { 5000, 0, 500, 20 } gives: + // {5000, 0, 0, 0} + MOZ_MUST_USE Sub SafeIntersect(const Sub& aRect) const + { + Sub result; + result.x = std::max<T>(x, aRect.x); + result.y = std::max<T>(y, aRect.y); + T right = std::min<T>(x + width, aRect.x + aRect.width); + T bottom = std::min<T>(y + height, aRect.y + aRect.height); + if (right < result.x || bottom < result.y) { + result.width = 0; + result.height = 0; + } else { + result.width = right - result.x; + result.height = bottom - result.y; + } + return result; + } // Sets *this to be the rectangle containing the intersection of the points // (including edges) of *this and aRect. If there are no points in that // intersection, sets *this to be an empty rectangle with x/y set to the std::max @@ -211,6 +235,40 @@ struct BaseRect { void MoveTo(const Point& aPoint) { x = aPoint.x; y = aPoint.y; } void MoveBy(T aDx, T aDy) { x += aDx; y += aDy; } void MoveBy(const Point& aPoint) { x += aPoint.x; y += aPoint.y; } + + // Variant of MoveBy that ensures that even after translation by a point that + // the rectangle coordinates will still fit within numeric limits. The origin + // and size will be clipped within numeric limits to ensure this. + void SafeMoveByX(T aDx) { + T x2 = XMost(); + if (aDx >= T(0)) { + T limit = std::numeric_limits<T>::max(); + x = limit - aDx < x ? limit : x + aDx; + width = (limit - aDx < x2 ? limit : x2 + aDx) - x; + } else { + T limit = std::numeric_limits<T>::min(); + x = limit - aDx > x ? limit : x + aDx; + width = (limit - aDx > x2 ? limit : x2 + aDx) - x; + } + } + void SafeMoveByY(T aDy) { + T y2 = YMost(); + if (aDy >= T(0)) { + T limit = std::numeric_limits<T>::max(); + y = limit - aDy < y ? limit : y + aDy; + height = (limit - aDy < y2 ? limit : y2 + aDy) - y; + } else { + T limit = std::numeric_limits<T>::min(); + y = limit - aDy > y ? limit : y + aDy; + height = (limit - aDy > y2 ? limit : y2 + aDy) - y; + } + } + void SafeMoveBy(T aDx, T aDy) { + SafeMoveByX(aDx); + SafeMoveByY(aDy); + } + void SafeMoveBy(const Point& aPoint) { SafeMoveBy(aPoint.x, aPoint.y); } + void SizeTo(T aWidth, T aHeight) { width = aWidth; height = aHeight; } void SizeTo(const SizeT& aSize) { width = aSize.width; height = aSize.height; } diff --git a/system/interface/windows/nsFilePicker.cpp b/system/interface/windows/nsFilePicker.cpp index 59ae152ec..3d733fcb7 100644 --- a/system/interface/windows/nsFilePicker.cpp +++ b/system/interface/windows/nsFilePicker.cpp @@ -35,12 +35,14 @@ using mozilla::mscom::EnsureMTA; using mozilla::UniquePtr; using namespace mozilla::widget; -char16_t *nsFilePicker::mLastUsedUnicodeDirectory; +UniquePtr<char16_t[], nsFilePicker::FreeDeleter> + nsFilePicker::sLastUsedUnicodeDirectory; + char nsFilePicker::mLastUsedDirectory[MAX_PATH+1] = { 0 }; static const wchar_t kDialogPtrProp[] = L"DialogPtrProperty"; static const DWORD kDialogTimerID = 9999; -static const unsigned long kDialogTimerTimeout = 300; + #define MAX_EXTENSION_LENGTH 10 #define FILE_BUFFER_SIZE 4096 @@ -71,31 +73,6 @@ private: RefPtr<nsWindow> mWindow; }; -// Manages the current working path. -class AutoRestoreWorkingPath -{ -public: - AutoRestoreWorkingPath() { - DWORD bufferLength = GetCurrentDirectoryW(0, nullptr); - mWorkingPath = MakeUnique<wchar_t[]>(bufferLength); - if (GetCurrentDirectoryW(bufferLength, mWorkingPath.get()) == 0) { - mWorkingPath = nullptr; - } - } - - ~AutoRestoreWorkingPath() { - if (HasWorkingPath()) { - ::SetCurrentDirectoryW(mWorkingPath.get()); - } - } - - inline bool HasWorkingPath() const { - return mWorkingPath != nullptr; - } -private: - UniquePtr<wchar_t[]> mWorkingPath; -}; - // Manages NS_NATIVE_TMP_WINDOW child windows. NS_NATIVE_TMP_WINDOWs are // temporary child windows of mParentWidget created to address RTL issues // in picker dialogs. We are responsible for destroying these. @@ -140,57 +117,11 @@ private: RefPtr<nsWindow> mWindow; }; -// Manages a simple callback timer -class AutoTimerCallbackCancel -{ -public: - AutoTimerCallbackCancel(nsFilePicker* aTarget, - nsTimerCallbackFunc aCallbackFunc) { - Init(aTarget, aCallbackFunc); - } - - ~AutoTimerCallbackCancel() { - if (mPickerCallbackTimer) { - mPickerCallbackTimer->Cancel(); - } - } - -private: - void Init(nsFilePicker* aTarget, - nsTimerCallbackFunc aCallbackFunc) { - mPickerCallbackTimer = do_CreateInstance("@mozilla.org/timer;1"); - if (!mPickerCallbackTimer) { - NS_WARNING("do_CreateInstance for timer failed??"); - return; - } - mPickerCallbackTimer->InitWithFuncCallback(aCallbackFunc, - aTarget, - kDialogTimerTimeout, - nsITimer::TYPE_REPEATING_SLACK); - } - nsCOMPtr<nsITimer> mPickerCallbackTimer; - -}; - /////////////////////////////////////////////////////////////////////////////// // nsIFilePicker -nsFilePicker::nsFilePicker() : - mSelectedType(1) - , mDlgWnd(nullptr) - , mFDECookie(0) -{ - CoInitialize(nullptr); -} - -nsFilePicker::~nsFilePicker() -{ - if (mLastUsedUnicodeDirectory) { - free(mLastUsedUnicodeDirectory); - mLastUsedUnicodeDirectory = nullptr; - } - CoUninitialize(); -} +nsFilePicker::nsFilePicker() + : mSelectedType(1) {} NS_IMPL_ISUPPORTS(nsFilePicker, nsIFilePicker) @@ -205,130 +136,6 @@ NS_IMETHODIMP nsFilePicker::Init(mozIDOMWindowProxy *aParent, const nsAString& a return nsBaseFilePicker::Init(aParent, aTitle, aMode); } -STDMETHODIMP nsFilePicker::QueryInterface(REFIID refiid, void** ppvResult) -{ - *ppvResult = nullptr; - if (IID_IUnknown == refiid || - refiid == IID_IFileDialogEvents) { - *ppvResult = this; - } - - if (nullptr != *ppvResult) { - ((LPUNKNOWN)*ppvResult)->AddRef(); - return S_OK; - } - - return E_NOINTERFACE; -} - - -/* - * Callbacks - */ - -HRESULT -nsFilePicker::OnFileOk(IFileDialog *pfd) -{ - return S_OK; -} - -HRESULT -nsFilePicker::OnFolderChanging(IFileDialog *pfd, - IShellItem *psiFolder) -{ - return S_OK; -} - -HRESULT -nsFilePicker::OnFolderChange(IFileDialog *pfd) -{ - return S_OK; -} - -HRESULT -nsFilePicker::OnSelectionChange(IFileDialog *pfd) -{ - return S_OK; -} - -HRESULT -nsFilePicker::OnShareViolation(IFileDialog *pfd, - IShellItem *psi, - FDE_SHAREVIOLATION_RESPONSE *pResponse) -{ - return S_OK; -} - -HRESULT -nsFilePicker::OnTypeChange(IFileDialog *pfd) -{ - // Failures here result in errors due to security concerns. - RefPtr<IOleWindow> win; - pfd->QueryInterface(IID_IOleWindow, getter_AddRefs(win)); - if (!win) { - NS_ERROR("Could not retrieve the IOleWindow interface for IFileDialog."); - return S_OK; - } - HWND hwnd = nullptr; - win->GetWindow(&hwnd); - if (!hwnd) { - NS_ERROR("Could not retrieve the HWND for IFileDialog."); - return S_OK; - } - - SetDialogHandle(hwnd); - return S_OK; -} - -HRESULT -nsFilePicker::OnOverwrite(IFileDialog *pfd, - IShellItem *psi, - FDE_OVERWRITE_RESPONSE *pResponse) -{ - return S_OK; -} - -/* - * Close on parent close logic - */ - -bool -nsFilePicker::ClosePickerIfNeeded() -{ - if (!mParentWidget || !mDlgWnd) - return false; - - nsWindow *win = static_cast<nsWindow *>(mParentWidget.get()); - if (IsWindow(mDlgWnd) && IsWindowVisible(mDlgWnd) && win->DestroyCalled()) { - wchar_t className[64]; - // Make sure we have the right window - if (GetClassNameW(mDlgWnd, className, mozilla::ArrayLength(className)) && - !wcscmp(className, L"#32770") && - DestroyWindow(mDlgWnd)) { - mDlgWnd = nullptr; - return true; - } - } - return false; -} - -void -nsFilePicker::PickerCallbackTimerFunc(nsITimer *aTimer, void *aCtx) -{ - nsFilePicker* picker = (nsFilePicker*)aCtx; - if (picker->ClosePickerIfNeeded()) { - aTimer->Cancel(); - } -} - -void -nsFilePicker::SetDialogHandle(HWND aWnd) -{ - if (!aWnd || mDlgWnd) - return; - mDlgWnd = aWnd; -} - /* * Folder picker invocation */ @@ -353,15 +160,14 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir) } RefPtr<IFileOpenDialog> dialog; - if (FAILED(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC, + if (FAILED(CoCreateInstance(CLSID_FileOpenDialog, + nullptr, + CLSCTX_INPROC_SERVER, IID_IFileOpenDialog, getter_AddRefs(dialog)))) { return false; } - // hook up event callbacks - dialog->Advise(this, &mFDECookie); - // options FILEOPENDIALOGOPTIONS fos = FOS_PICKFOLDERS; // Require interaction if the folder picker is triggered by an element that @@ -371,13 +177,22 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir) fos |= FOS_OKBUTTONNEEDSINTERACTION; } - dialog->SetOptions(fos); + HRESULT hr = dialog->SetOptions(fos); + if (FAILED(hr)) { + return false; + } // initial strings - dialog->SetTitle(mTitle.get()); + hr = dialog->SetTitle(mTitle.get()); + if (FAILED(hr)) { + return false; + } if (!mOkButtonLabel.IsEmpty()) { - dialog->SetOkButtonLabel(mOkButtonLabel.get()); + hr = dialog->SetOkButtonLabel(mOkButtonLabel.get()); + if (FAILED(hr)) { + return false; + } } if (!aInitialDir.IsEmpty()) { @@ -386,7 +201,10 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir) WinUtils::SHCreateItemFromParsingName(aInitialDir.get(), nullptr, IID_IShellItem, getter_AddRefs(folder)))) { - dialog->SetFolder(folder); + hr = dialog->SetFolder(folder); + if (FAILED(hr)) { + return false; + } } } @@ -398,10 +216,8 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir) if (FAILED(dialog->Show(adtw.get())) || FAILED(dialog->GetResult(getter_AddRefs(item))) || !item) { - dialog->Unadvise(mFDECookie); return false; } - dialog->Unadvise(mFDECookie); // results @@ -409,8 +225,14 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir) // default save folder. RefPtr<IShellItem> folderPath; RefPtr<IShellLibrary> shellLib; - CoCreateInstance(CLSID_ShellLibrary, nullptr, CLSCTX_INPROC, - IID_IShellLibrary, getter_AddRefs(shellLib)); + if (FAILED(CoCreateInstance(CLSID_ShellLibrary, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IShellLibrary, + getter_AddRefs(shellLib)))) { + return false; + } + if (shellLib && SUCCEEDED(shellLib->LoadLibraryFromItem(item, STGM_READ)) && SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem, @@ -449,22 +271,23 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir) RefPtr<IFileDialog> dialog; if (mMode != modeSave) { - if (FAILED(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC, + if (FAILED(CoCreateInstance(CLSID_FileOpenDialog, + nullptr, + CLSCTX_INPROC_SERVER, IID_IFileOpenDialog, getter_AddRefs(dialog)))) { return false; } } else { - if (FAILED(CoCreateInstance(CLSID_FileSaveDialog, nullptr, CLSCTX_INPROC, + if (FAILED(CoCreateInstance(CLSID_FileSaveDialog, + nullptr, + CLSCTX_INPROC_SERVER, IID_IFileSaveDialog, getter_AddRefs(dialog)))) { return false; } } - // hook up event callbacks - dialog->Advise(this, &mFDECookie); - // options FILEOPENDIALOGOPTIONS fos = 0; @@ -483,10 +306,6 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir) fos |= FOS_DONTADDTORECENT; } - // Msdn claims FOS_NOCHANGEDIR is not needed. We'll add this - // just in case. - AutoRestoreWorkingPath arw; - // mode specific switch(mMode) { case modeOpen: @@ -506,25 +325,45 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir) break; } - dialog->SetOptions(fos); + HRESULT hr = dialog->SetOptions(fos); + if (FAILED(hr)) { + return false; + } // initial strings // title - dialog->SetTitle(mTitle.get()); + hr = dialog->SetTitle(mTitle.get()); + if (FAILED(hr)) { + return false; + } // default filename if (!mDefaultFilename.IsEmpty()) { - dialog->SetFileName(mDefaultFilename.get()); + // Prevent the shell from expanding environment variables by removing + // the % characters that are used to delimit them. + nsAutoString sanitizedFilename(mDefaultFilename); + sanitizedFilename.ReplaceChar('%', '_'); + + hr = dialog->SetFileName(sanitizedFilename.get()); + if (FAILED(hr)) { + return false; + } } NS_NAMED_LITERAL_STRING(htmExt, "html"); // default extension to append to new files if (!mDefaultExtension.IsEmpty()) { - dialog->SetDefaultExtension(mDefaultExtension.get()); + hr = dialog->SetDefaultExtension(mDefaultExtension.get()); + if (FAILED(hr)) { + return false; + } } else if (IsDefaultPathHtml()) { - dialog->SetDefaultExtension(htmExt.get()); + hr = dialog->SetDefaultExtension(htmExt.get()); + if (FAILED(hr)) { + return false; + } } // initial location @@ -534,14 +373,24 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir) WinUtils::SHCreateItemFromParsingName(aInitialDir.get(), nullptr, IID_IShellItem, getter_AddRefs(folder)))) { - dialog->SetFolder(folder); + hr = dialog->SetFolder(folder); + if (FAILED(hr)) { + return false; + } } } // filter types and the default index if (!mComFilterList.IsEmpty()) { - dialog->SetFileTypes(mComFilterList.Length(), mComFilterList.get()); - dialog->SetFileTypeIndex(mSelectedType); + hr = dialog->SetFileTypes(mComFilterList.Length(), mComFilterList.get()); + if (FAILED(hr)) { + return false; + } + + hr = dialog->SetFileTypeIndex(mSelectedType); + if (FAILED(hr)) { + return false; + } } // display @@ -549,14 +398,11 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir) { AutoDestroyTmpWindow adtw((HWND)(mParentWidget.get() ? mParentWidget->GetNativeData(NS_NATIVE_TMP_WINDOW) : nullptr)); - AutoTimerCallbackCancel atcc(this, PickerCallbackTimerFunc); AutoWidgetPickerState awps(mParentWidget); if (FAILED(dialog->Show(adtw.get()))) { - dialog->Unadvise(mFDECookie); return false; } - dialog->Unadvise(mFDECookie); } // results @@ -596,9 +442,10 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir) if (SUCCEEDED(items->GetItemAt(idx, getter_AddRefs(item)))) { if (!WinUtils::GetShellItemPath(item, str)) continue; - nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1"); - if (file && NS_SUCCEEDED(file->InitWithPath(str))) + nsCOMPtr<nsIFile> file; + if (NS_SUCCEEDED(NS_NewLocalFile(str, false, getter_AddRefs(file)))) { mFiles.AppendObject(file); + } } } return true; @@ -623,7 +470,7 @@ nsFilePicker::ShowW(int16_t *aReturnVal) // If no display directory, re-use the last one. if(initialDir.IsEmpty()) { // Allocate copy of last used dir. - initialDir = mLastUsedUnicodeDirectory; + initialDir = sLastUsedUnicodeDirectory.get(); } // Clear previous file selections @@ -651,10 +498,11 @@ nsFilePicker::ShowW(int16_t *aReturnVal) if (mMode == modeSave) { // Windows does not return resultReplace, we must check if file // already exists. - nsCOMPtr<nsIFile> file(do_CreateInstance("@mozilla.org/file/local;1")); + nsCOMPtr<nsIFile> file; + nsresult rv = NS_NewLocalFile(mUnicodeFile, false, getter_AddRefs(file)); + bool flag = false; - if (file && NS_SUCCEEDED(file->InitWithPath(mUnicodeFile)) && - NS_SUCCEEDED(file->Exists(&flag)) && flag) { + if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(file->Exists(&flag)) && flag) { retValue = returnReplace; } } @@ -678,14 +526,13 @@ nsFilePicker::GetFile(nsIFile **aFile) if (mUnicodeFile.IsEmpty()) return NS_OK; - nsCOMPtr<nsIFile> file(do_CreateInstance("@mozilla.org/file/local;1")); - - NS_ENSURE_TRUE(file, NS_ERROR_FAILURE); - - file->InitWithPath(mUnicodeFile); - - NS_ADDREF(*aFile = file); + nsCOMPtr<nsIFile> file; + nsresult rv = NS_NewLocalFile(mUnicodeFile, false, getter_AddRefs(file)); + if (NS_FAILED(rv)) { + return rv; + } + file.forget(aFile); return NS_OK; } @@ -800,8 +647,13 @@ nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter) void nsFilePicker::RememberLastUsedDirectory() { - nsCOMPtr<nsIFile> file(do_CreateInstance("@mozilla.org/file/local;1")); - if (!file || NS_FAILED(file->InitWithPath(mUnicodeFile))) { + if (IsPrivacyModeEnabled()) { + // Don't remember the directory if private browsing was in effect + return; + } + + nsCOMPtr<nsIFile> file; + if (NS_FAILED(NS_NewLocalFile(mUnicodeFile, false, getter_AddRefs(file)))) { NS_WARNING("RememberLastUsedDirectory failed to init file path."); return; } @@ -816,11 +668,7 @@ nsFilePicker::RememberLastUsedDirectory() return; } - if (mLastUsedUnicodeDirectory) { - free(mLastUsedUnicodeDirectory); - mLastUsedUnicodeDirectory = nullptr; - } - mLastUsedUnicodeDirectory = ToNewUnicode(newDir); + sLastUsedUnicodeDirectory.reset(ToNewUnicode(newDir)); } bool diff --git a/system/interface/windows/nsFilePicker.h b/system/interface/windows/nsFilePicker.h index 7a3fbbe07..050b6acaf 100644 --- a/system/interface/windows/nsFilePicker.h +++ b/system/interface/windows/nsFilePicker.h @@ -10,7 +10,6 @@ #include <windows.h> #include "nsIFile.h" -#include "nsITimer.h" #include "nsISimpleEnumerator.h" #include "nsCOMArray.h" #include "nsBaseFilePicker.h" @@ -41,11 +40,9 @@ protected: * Native Windows FileSelector wrapper */ -class nsFilePicker : - public IFileDialogEvents, - public nsBaseWinFilePicker -{ - virtual ~nsFilePicker(); +class nsFilePicker : public nsBaseWinFilePicker { + virtual ~nsFilePicker() = default; + public: nsFilePicker(); @@ -54,9 +51,6 @@ public: NS_DECL_ISUPPORTS - // IUnknown's QueryInterface - STDMETHODIMP QueryInterface(REFIID refiid, void** ppvResult); - // nsIFilePicker (less what's in nsBaseFilePicker and nsBaseWinFilePicker) NS_IMETHOD GetFilterIndex(int32_t *aFilterIndex); NS_IMETHOD SetFilterIndex(int32_t aFilterIndex); @@ -67,15 +61,6 @@ public: NS_IMETHOD ShowW(int16_t *aReturnVal); NS_IMETHOD AppendFilter(const nsAString& aTitle, const nsAString& aFilter); - // IFileDialogEvents - HRESULT STDMETHODCALLTYPE OnFileOk(IFileDialog *pfd); - HRESULT STDMETHODCALLTYPE OnFolderChanging(IFileDialog *pfd, IShellItem *psiFolder); - HRESULT STDMETHODCALLTYPE OnFolderChange(IFileDialog *pfd); - HRESULT STDMETHODCALLTYPE OnSelectionChange(IFileDialog *pfd); - HRESULT STDMETHODCALLTYPE OnShareViolation(IFileDialog *pfd, IShellItem *psi, FDE_SHAREVIOLATION_RESPONSE *pResponse); - HRESULT STDMETHODCALLTYPE OnTypeChange(IFileDialog *pfd); - HRESULT STDMETHODCALLTYPE OnOverwrite(IFileDialog *pfd, IShellItem *psi, FDE_OVERWRITE_RESPONSE *pResponse); - protected: /* method from nsBaseFilePicker */ virtual void InitNative(nsIWidget *aParent, @@ -87,9 +72,6 @@ protected: bool IsPrivacyModeEnabled(); bool IsDefaultPathLink(); bool IsDefaultPathHtml(); - void SetDialogHandle(HWND aWnd); - bool ClosePickerIfNeeded(); - static void PickerCallbackTimerFunc(nsITimer *aTimer, void *aPicker); nsCOMPtr<nsILoadContext> mLoadContext; nsCOMPtr<nsIWidget> mParentWidget; @@ -100,10 +82,13 @@ protected: nsCOMArray<nsIFile> mFiles; static char mLastUsedDirectory[]; nsString mUnicodeFile; - static char16_t *mLastUsedUnicodeDirectory; - HWND mDlgWnd; bool mRequireInteraction; + struct FreeDeleter { + void operator()(void* aPtr) { ::free(aPtr); } + }; + static mozilla::UniquePtr<char16_t[], FreeDeleter> sLastUsedUnicodeDirectory; + class ComDlgFilterSpec { public: @@ -129,7 +114,6 @@ protected: }; ComDlgFilterSpec mComFilterList; - DWORD mFDECookie; }; #endif // nsFilePicker_h__ |