michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set sw=2 ts=8 et tw=80 : */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "RemoteOpenFileChild.h" michael@0: michael@0: #include "mozilla/unused.h" michael@0: #include "mozilla/ipc/FileDescriptor.h" michael@0: #include "mozilla/ipc/FileDescriptorUtils.h" michael@0: #include "mozilla/ipc/URIUtils.h" michael@0: #include "mozilla/net/NeckoChild.h" michael@0: #include "nsThreadUtils.h" michael@0: #include "nsJARProtocolHandler.h" michael@0: #include "nsIRemoteOpenFileListener.h" michael@0: #include "nsProxyRelease.h" michael@0: michael@0: // needed to alloc/free NSPR file descriptors michael@0: #include "private/pprio.h" michael@0: michael@0: using namespace mozilla::ipc; michael@0: michael@0: namespace mozilla { michael@0: namespace net { michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // Helper class to dispatch events async on windows/OSX michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: class CallsListenerInNewEvent : public nsRunnable michael@0: { michael@0: public: michael@0: CallsListenerInNewEvent(nsIRemoteOpenFileListener *aListener, nsresult aRv) michael@0: : mListener(aListener), mRV(aRv) michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: MOZ_ASSERT(aListener); michael@0: } michael@0: michael@0: void Dispatch() michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: michael@0: nsresult rv = NS_DispatchToCurrentThread(this); michael@0: NS_ENSURE_SUCCESS_VOID(rv); michael@0: } michael@0: michael@0: private: michael@0: NS_IMETHOD Run() michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: MOZ_ASSERT(mListener); michael@0: michael@0: mListener->OnRemoteFileOpenComplete(mRV); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsCOMPtr mListener; michael@0: nsresult mRV; michael@0: }; michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // RemoteOpenFileChild michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: NS_IMPL_ISUPPORTS(RemoteOpenFileChild, michael@0: nsIFile, michael@0: nsIHashable, michael@0: nsICachedFileDescriptorListener) michael@0: michael@0: RemoteOpenFileChild::RemoteOpenFileChild(const RemoteOpenFileChild& other) michael@0: : mTabChild(other.mTabChild) michael@0: , mNSPRFileDesc(other.mNSPRFileDesc) michael@0: , mAsyncOpenCalled(other.mAsyncOpenCalled) michael@0: , mNSPROpenCalled(other.mNSPROpenCalled) michael@0: { michael@0: // Note: don't clone mListener or we'll have a refcount leak. michael@0: other.mURI->Clone(getter_AddRefs(mURI)); michael@0: if (other.mAppURI) { michael@0: other.mAppURI->Clone(getter_AddRefs(mAppURI)); michael@0: } michael@0: other.mFile->Clone(getter_AddRefs(mFile)); michael@0: } michael@0: michael@0: RemoteOpenFileChild::~RemoteOpenFileChild() michael@0: { michael@0: if (NS_IsMainThread()) { michael@0: if (mListener) { michael@0: NotifyListener(NS_ERROR_UNEXPECTED); michael@0: } michael@0: } else { michael@0: nsCOMPtr mainThread = do_GetMainThread(); michael@0: if (mainThread) { michael@0: MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mURI, true))); michael@0: MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mAppURI, true))); michael@0: MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mListener, michael@0: true))); michael@0: michael@0: TabChild* tabChild; michael@0: mTabChild.forget(&tabChild); michael@0: michael@0: if (tabChild) { michael@0: nsCOMPtr runnable = michael@0: NS_NewNonOwningRunnableMethod(tabChild, &TabChild::Release); michael@0: MOZ_ASSERT(runnable); michael@0: michael@0: MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mainThread->Dispatch(runnable, michael@0: NS_DISPATCH_NORMAL))); michael@0: } michael@0: } else { michael@0: using mozilla::unused; michael@0: michael@0: NS_WARNING("RemoteOpenFileChild released after thread shutdown, leaking " michael@0: "its members!"); michael@0: michael@0: unused << mURI.forget(); michael@0: unused << mAppURI.forget(); michael@0: unused << mListener.forget(); michael@0: unused << mTabChild.forget(); michael@0: } michael@0: } michael@0: michael@0: if (mNSPRFileDesc) { michael@0: // If we handed out fd we shouldn't have pointer to it any more. michael@0: MOZ_ASSERT(!mNSPROpenCalled); michael@0: // PR_Close both closes the file and deallocates the PRFileDesc michael@0: PR_Close(mNSPRFileDesc); michael@0: } michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::Init(nsIURI* aRemoteOpenUri, nsIURI* aAppUri) michael@0: { michael@0: if (!aRemoteOpenUri) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: if (aAppUri) { michael@0: aAppUri->Clone(getter_AddRefs(mAppURI)); michael@0: } michael@0: michael@0: nsAutoCString scheme; michael@0: nsresult rv = aRemoteOpenUri->GetScheme(scheme); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (!scheme.EqualsLiteral("remoteopenfile")) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: // scheme of URI is not file:// so this is not a nsIFileURL. Convert to one. michael@0: nsCOMPtr clonedURI; michael@0: rv = aRemoteOpenUri->Clone(getter_AddRefs(clonedURI)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: clonedURI->SetScheme(NS_LITERAL_CSTRING("file")); michael@0: nsAutoCString spec; michael@0: clonedURI->GetSpec(spec); michael@0: michael@0: rv = NS_NewURI(getter_AddRefs(mURI), spec); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // Get nsIFile michael@0: nsCOMPtr fileURL = do_QueryInterface(mURI); michael@0: if (!fileURL) { michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: rv = fileURL->GetFile(getter_AddRefs(mFile)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::AsyncRemoteFileOpen(int32_t aFlags, michael@0: nsIRemoteOpenFileListener* aListener, michael@0: nsITabChild* aTabChild) michael@0: { michael@0: if (!mFile) { michael@0: return NS_ERROR_NOT_INITIALIZED; michael@0: } michael@0: michael@0: if (!aListener) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: if (mAsyncOpenCalled) { michael@0: return NS_ERROR_ALREADY_OPENED; michael@0: } michael@0: michael@0: if (aFlags != PR_RDONLY) { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: mTabChild = static_cast(aTabChild); michael@0: michael@0: if (MissingRequiredTabChild(mTabChild, "remoteopenfile")) { michael@0: return NS_ERROR_ILLEGAL_VALUE; michael@0: } michael@0: michael@0: #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) michael@0: // Windows/OSX desktop builds skip remoting, and just open file in child michael@0: // process when asked for NSPR handle michael@0: nsRefPtr runnable = michael@0: new CallsListenerInNewEvent(aListener, NS_OK); michael@0: runnable->Dispatch(); michael@0: michael@0: mAsyncOpenCalled = true; michael@0: return NS_OK; michael@0: #else michael@0: nsString path; michael@0: if (NS_FAILED(mFile->GetPath(path))) { michael@0: MOZ_CRASH("Couldn't get path from file!"); michael@0: } michael@0: michael@0: if (mTabChild) { michael@0: if (mTabChild->GetCachedFileDescriptor(path, this)) { michael@0: // The file descriptor was found in the cache and OnCachedFileDescriptor() michael@0: // will be called with it. michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: URIParams uri; michael@0: SerializeURI(mURI, uri); michael@0: OptionalURIParams appUri; michael@0: SerializeURI(mAppURI, appUri); michael@0: michael@0: gNeckoChild->SendPRemoteOpenFileConstructor(this, uri, appUri); michael@0: michael@0: // The chrome process now has a logical ref to us until it calls Send__delete. michael@0: AddIPDLReference(); michael@0: michael@0: mListener = aListener; michael@0: mAsyncOpenCalled = true; michael@0: return NS_OK; michael@0: #endif michael@0: } michael@0: michael@0: void michael@0: RemoteOpenFileChild::OnCachedFileDescriptor(const nsAString& aPath, michael@0: const FileDescriptor& aFD) michael@0: { michael@0: #ifdef DEBUG michael@0: if (!aPath.IsEmpty()) { michael@0: MOZ_ASSERT(mFile); michael@0: michael@0: nsString path; michael@0: MOZ_ASSERT(NS_SUCCEEDED(mFile->GetPath(path))); michael@0: MOZ_ASSERT(path == aPath, "Paths don't match!"); michael@0: } michael@0: #endif michael@0: michael@0: HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvDelete */ false); michael@0: } michael@0: michael@0: void michael@0: RemoteOpenFileChild::HandleFileDescriptorAndNotifyListener( michael@0: const FileDescriptor& aFD, michael@0: bool aFromRecvDelete) michael@0: { michael@0: #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) michael@0: MOZ_CRASH("OS X and Windows shouldn't be doing IPDL here"); michael@0: #else michael@0: if (!mListener) { michael@0: // We already notified our listener (either in response to a cached file michael@0: // descriptor callback or through the normal messaging mechanism). Close the michael@0: // file descriptor if it is valid. michael@0: if (aFD.IsValid()) { michael@0: nsRefPtr runnable = new CloseFileRunnable(aFD); michael@0: runnable->Dispatch(); michael@0: } michael@0: return; michael@0: } michael@0: michael@0: MOZ_ASSERT(!mNSPRFileDesc); michael@0: michael@0: nsRefPtr tabChild; michael@0: mTabChild.swap(tabChild); michael@0: michael@0: // If RemoteOpenFile reply (Recv__delete__) for app's application.zip comes michael@0: // back sooner than the parent-pushed fd (TabChild::RecvCacheFileDescriptor()) michael@0: // have TabChild cancel running callbacks, since we'll call them in michael@0: // NotifyListener. michael@0: if (tabChild && aFromRecvDelete) { michael@0: nsString path; michael@0: if (NS_FAILED(mFile->GetPath(path))) { michael@0: MOZ_CRASH("Couldn't get path from file!"); michael@0: } michael@0: michael@0: tabChild->CancelCachedFileDescriptorCallback(path, this); michael@0: } michael@0: michael@0: if (aFD.IsValid()) { michael@0: mNSPRFileDesc = PR_ImportFile(aFD.PlatformHandle()); michael@0: if (!mNSPRFileDesc) { michael@0: NS_WARNING("Failed to import file handle!"); michael@0: } michael@0: } michael@0: michael@0: NotifyListener(mNSPRFileDesc ? NS_OK : NS_ERROR_FILE_NOT_FOUND); michael@0: #endif michael@0: } michael@0: michael@0: void michael@0: RemoteOpenFileChild::NotifyListener(nsresult aResult) michael@0: { michael@0: MOZ_ASSERT(mListener); michael@0: mListener->OnRemoteFileOpenComplete(aResult); michael@0: mListener = nullptr; // release ref to listener michael@0: michael@0: nsRefPtr handler(gJarHandler); michael@0: NS_WARN_IF_FALSE(handler, "nsJARProtocolHandler is already gone!"); michael@0: michael@0: if (handler) { michael@0: handler->RemoteOpenFileComplete(this, aResult); michael@0: } michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // RemoteOpenFileChild::PRemoteOpenFileChild michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: bool michael@0: RemoteOpenFileChild::Recv__delete__(const FileDescriptor& aFD) michael@0: { michael@0: #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) michael@0: NS_NOTREACHED("OS X and Windows shouldn't be doing IPDL here"); michael@0: #else michael@0: HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvDelete */ true); michael@0: #endif michael@0: michael@0: return true; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // RemoteOpenFileChild::nsIFile functions that we override logic for michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Clone(nsIFile **file) michael@0: { michael@0: *file = new RemoteOpenFileChild(*this); michael@0: NS_ADDREF(*file); michael@0: michael@0: // if we transferred ownership of file to clone, forget our pointer. michael@0: if (mNSPRFileDesc) { michael@0: mNSPRFileDesc = nullptr; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* The main event: get file descriptor from parent process michael@0: */ michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::OpenNSPRFileDesc(int32_t aFlags, int32_t aMode, michael@0: PRFileDesc **aRetval) michael@0: { michael@0: #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) michael@0: // Windows and OSX builds: just open nsIFile locally. michael@0: return mFile->OpenNSPRFileDesc(aFlags, aMode, aRetval); michael@0: michael@0: #else michael@0: if (aFlags != PR_RDONLY) { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: // Unlike regular nsIFile we can't (easily) support multiple open()s. michael@0: if (mNSPROpenCalled) { michael@0: return NS_ERROR_ALREADY_OPENED; michael@0: } michael@0: michael@0: if (!mNSPRFileDesc) { michael@0: // client skipped AsyncRemoteFileOpen() or didn't wait for result, or this michael@0: // object has been cloned michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: // hand off ownership (i.e responsibility to PR_Close() file handle) to caller michael@0: *aRetval = mNSPRFileDesc; michael@0: mNSPRFileDesc = nullptr; michael@0: mNSPROpenCalled = true; michael@0: michael@0: return NS_OK; michael@0: #endif michael@0: } michael@0: michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // RemoteOpenFileChild::nsIFile functions that we delegate to underlying nsIFile michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::GetLeafName(nsAString &aLeafName) michael@0: { michael@0: return mFile->GetLeafName(aLeafName); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetNativeLeafName(nsACString &aLeafName) michael@0: { michael@0: return mFile->GetNativeLeafName(aLeafName); michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::GetTarget(nsAString &_retval) michael@0: { michael@0: return mFile->GetTarget(_retval); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetNativeTarget(nsACString &_retval) michael@0: { michael@0: return mFile->GetNativeTarget(_retval); michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::GetPath(nsAString &_retval) michael@0: { michael@0: return mFile->GetPath(_retval); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetNativePath(nsACString &_retval) michael@0: { michael@0: return mFile->GetNativePath(_retval); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Equals(nsIFile *inFile, bool *_retval) michael@0: { michael@0: return mFile->Equals(inFile, _retval); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Contains(nsIFile *inFile, bool recur, bool *_retval) michael@0: { michael@0: return mFile->Contains(inFile, recur, _retval); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetParent(nsIFile **aParent) michael@0: { michael@0: return mFile->GetParent(aParent); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetFollowLinks(bool *aFollowLinks) michael@0: { michael@0: return mFile->GetFollowLinks(aFollowLinks); michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // RemoteOpenFileChild::nsIFile functions that are not currently supported michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::Append(const nsAString &node) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::AppendNative(const nsACString &fragment) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Normalize() michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Create(uint32_t type, uint32_t permissions) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::SetLeafName(const nsAString &aLeafName) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::SetNativeLeafName(const nsACString &aLeafName) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::InitWithPath(const nsAString &filePath) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::InitWithNativePath(const nsACString &filePath) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::InitWithFile(nsIFile *aFile) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::SetFollowLinks(bool aFollowLinks) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::AppendRelativePath(const nsAString &node) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::AppendRelativeNativePath(const nsACString &fragment) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetPersistentDescriptor(nsACString &aPersistentDescriptor) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::SetPersistentDescriptor(const nsACString &aPersistentDescriptor) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetRelativeDescriptor(nsIFile *fromFile, nsACString& _retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::SetRelativeDescriptor(nsIFile *fromFile, michael@0: const nsACString& relativeDesc) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::CopyTo(nsIFile *newParentDir, const nsAString &newName) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::CopyToNative(nsIFile *newParent, const nsACString &newName) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::CopyToFollowingLinks(nsIFile *newParentDir, michael@0: const nsAString &newName) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::CopyToFollowingLinksNative(nsIFile *newParent, michael@0: const nsACString &newName) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsresult michael@0: RemoteOpenFileChild::MoveTo(nsIFile *newParentDir, const nsAString &newName) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::MoveToNative(nsIFile *newParent, const nsACString &newName) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::RenameTo(nsIFile *newParentDir, const nsAString &newName) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Remove(bool recursive) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetPermissions(uint32_t *aPermissions) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::SetPermissions(uint32_t aPermissions) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetPermissionsOfLink(uint32_t *aPermissionsOfLink) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::SetPermissionsOfLink(uint32_t aPermissions) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetLastModifiedTime(PRTime *aLastModTime) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::SetLastModifiedTime(PRTime aLastModTime) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetLastModifiedTimeOfLink(PRTime *aLastModTimeOfLink) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::SetLastModifiedTimeOfLink(PRTime aLastModTimeOfLink) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetFileSize(int64_t *aFileSize) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::SetFileSize(int64_t aFileSize) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetFileSizeOfLink(int64_t *aFileSize) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Exists(bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::IsWritable(bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::IsReadable(bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::IsExecutable(bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::IsHidden(bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::IsDirectory(bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::IsFile(bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::IsSymlink(bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::IsSpecial(bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::CreateUnique(uint32_t type, uint32_t attributes) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetDirectoryEntries(nsISimpleEnumerator **entries) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::OpenANSIFileDesc(const char *mode, FILE **_retval) michael@0: { michael@0: // TODO: can implement using fdopen()? michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Load(PRLibrary **_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetDiskSpaceAvailable(int64_t *aDiskSpaceAvailable) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Reveal() michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Launch() michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // RemoteOpenFileChild::nsIHashable functions that we delegate to underlying nsIFile michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::Equals(nsIHashable* aOther, bool *aResult) michael@0: { michael@0: nsCOMPtr hashable = do_QueryInterface(mFile); michael@0: michael@0: MOZ_ASSERT(hashable); michael@0: michael@0: if (hashable) { michael@0: return hashable->Equals(aOther, aResult); michael@0: } michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RemoteOpenFileChild::GetHashCode(uint32_t *aResult) michael@0: { michael@0: nsCOMPtr hashable = do_QueryInterface(mFile); michael@0: michael@0: MOZ_ASSERT(hashable); michael@0: michael@0: if (hashable) { michael@0: return hashable->GetHashCode(aResult); michael@0: } michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: } // namespace net michael@0: } // namespace mozilla