|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set sw=2 ts=8 et tw=80 : */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "RemoteOpenFileChild.h" |
|
8 |
|
9 #include "mozilla/unused.h" |
|
10 #include "mozilla/ipc/FileDescriptor.h" |
|
11 #include "mozilla/ipc/FileDescriptorUtils.h" |
|
12 #include "mozilla/ipc/URIUtils.h" |
|
13 #include "mozilla/net/NeckoChild.h" |
|
14 #include "nsThreadUtils.h" |
|
15 #include "nsJARProtocolHandler.h" |
|
16 #include "nsIRemoteOpenFileListener.h" |
|
17 #include "nsProxyRelease.h" |
|
18 |
|
19 // needed to alloc/free NSPR file descriptors |
|
20 #include "private/pprio.h" |
|
21 |
|
22 using namespace mozilla::ipc; |
|
23 |
|
24 namespace mozilla { |
|
25 namespace net { |
|
26 |
|
27 //----------------------------------------------------------------------------- |
|
28 // Helper class to dispatch events async on windows/OSX |
|
29 //----------------------------------------------------------------------------- |
|
30 |
|
31 class CallsListenerInNewEvent : public nsRunnable |
|
32 { |
|
33 public: |
|
34 CallsListenerInNewEvent(nsIRemoteOpenFileListener *aListener, nsresult aRv) |
|
35 : mListener(aListener), mRV(aRv) |
|
36 { |
|
37 MOZ_ASSERT(NS_IsMainThread()); |
|
38 MOZ_ASSERT(aListener); |
|
39 } |
|
40 |
|
41 void Dispatch() |
|
42 { |
|
43 MOZ_ASSERT(NS_IsMainThread()); |
|
44 |
|
45 nsresult rv = NS_DispatchToCurrentThread(this); |
|
46 NS_ENSURE_SUCCESS_VOID(rv); |
|
47 } |
|
48 |
|
49 private: |
|
50 NS_IMETHOD Run() |
|
51 { |
|
52 MOZ_ASSERT(NS_IsMainThread()); |
|
53 MOZ_ASSERT(mListener); |
|
54 |
|
55 mListener->OnRemoteFileOpenComplete(mRV); |
|
56 return NS_OK; |
|
57 } |
|
58 |
|
59 nsCOMPtr<nsIRemoteOpenFileListener> mListener; |
|
60 nsresult mRV; |
|
61 }; |
|
62 |
|
63 //----------------------------------------------------------------------------- |
|
64 // RemoteOpenFileChild |
|
65 //----------------------------------------------------------------------------- |
|
66 |
|
67 NS_IMPL_ISUPPORTS(RemoteOpenFileChild, |
|
68 nsIFile, |
|
69 nsIHashable, |
|
70 nsICachedFileDescriptorListener) |
|
71 |
|
72 RemoteOpenFileChild::RemoteOpenFileChild(const RemoteOpenFileChild& other) |
|
73 : mTabChild(other.mTabChild) |
|
74 , mNSPRFileDesc(other.mNSPRFileDesc) |
|
75 , mAsyncOpenCalled(other.mAsyncOpenCalled) |
|
76 , mNSPROpenCalled(other.mNSPROpenCalled) |
|
77 { |
|
78 // Note: don't clone mListener or we'll have a refcount leak. |
|
79 other.mURI->Clone(getter_AddRefs(mURI)); |
|
80 if (other.mAppURI) { |
|
81 other.mAppURI->Clone(getter_AddRefs(mAppURI)); |
|
82 } |
|
83 other.mFile->Clone(getter_AddRefs(mFile)); |
|
84 } |
|
85 |
|
86 RemoteOpenFileChild::~RemoteOpenFileChild() |
|
87 { |
|
88 if (NS_IsMainThread()) { |
|
89 if (mListener) { |
|
90 NotifyListener(NS_ERROR_UNEXPECTED); |
|
91 } |
|
92 } else { |
|
93 nsCOMPtr<nsIThread> mainThread = do_GetMainThread(); |
|
94 if (mainThread) { |
|
95 MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mURI, true))); |
|
96 MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mAppURI, true))); |
|
97 MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mListener, |
|
98 true))); |
|
99 |
|
100 TabChild* tabChild; |
|
101 mTabChild.forget(&tabChild); |
|
102 |
|
103 if (tabChild) { |
|
104 nsCOMPtr<nsIRunnable> runnable = |
|
105 NS_NewNonOwningRunnableMethod(tabChild, &TabChild::Release); |
|
106 MOZ_ASSERT(runnable); |
|
107 |
|
108 MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mainThread->Dispatch(runnable, |
|
109 NS_DISPATCH_NORMAL))); |
|
110 } |
|
111 } else { |
|
112 using mozilla::unused; |
|
113 |
|
114 NS_WARNING("RemoteOpenFileChild released after thread shutdown, leaking " |
|
115 "its members!"); |
|
116 |
|
117 unused << mURI.forget(); |
|
118 unused << mAppURI.forget(); |
|
119 unused << mListener.forget(); |
|
120 unused << mTabChild.forget(); |
|
121 } |
|
122 } |
|
123 |
|
124 if (mNSPRFileDesc) { |
|
125 // If we handed out fd we shouldn't have pointer to it any more. |
|
126 MOZ_ASSERT(!mNSPROpenCalled); |
|
127 // PR_Close both closes the file and deallocates the PRFileDesc |
|
128 PR_Close(mNSPRFileDesc); |
|
129 } |
|
130 } |
|
131 |
|
132 nsresult |
|
133 RemoteOpenFileChild::Init(nsIURI* aRemoteOpenUri, nsIURI* aAppUri) |
|
134 { |
|
135 if (!aRemoteOpenUri) { |
|
136 return NS_ERROR_INVALID_ARG; |
|
137 } |
|
138 |
|
139 if (aAppUri) { |
|
140 aAppUri->Clone(getter_AddRefs(mAppURI)); |
|
141 } |
|
142 |
|
143 nsAutoCString scheme; |
|
144 nsresult rv = aRemoteOpenUri->GetScheme(scheme); |
|
145 NS_ENSURE_SUCCESS(rv, rv); |
|
146 |
|
147 if (!scheme.EqualsLiteral("remoteopenfile")) { |
|
148 return NS_ERROR_INVALID_ARG; |
|
149 } |
|
150 |
|
151 // scheme of URI is not file:// so this is not a nsIFileURL. Convert to one. |
|
152 nsCOMPtr<nsIURI> clonedURI; |
|
153 rv = aRemoteOpenUri->Clone(getter_AddRefs(clonedURI)); |
|
154 NS_ENSURE_SUCCESS(rv, rv); |
|
155 |
|
156 clonedURI->SetScheme(NS_LITERAL_CSTRING("file")); |
|
157 nsAutoCString spec; |
|
158 clonedURI->GetSpec(spec); |
|
159 |
|
160 rv = NS_NewURI(getter_AddRefs(mURI), spec); |
|
161 NS_ENSURE_SUCCESS(rv, rv); |
|
162 |
|
163 // Get nsIFile |
|
164 nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mURI); |
|
165 if (!fileURL) { |
|
166 return NS_ERROR_UNEXPECTED; |
|
167 } |
|
168 |
|
169 rv = fileURL->GetFile(getter_AddRefs(mFile)); |
|
170 NS_ENSURE_SUCCESS(rv, rv); |
|
171 |
|
172 return NS_OK; |
|
173 } |
|
174 |
|
175 nsresult |
|
176 RemoteOpenFileChild::AsyncRemoteFileOpen(int32_t aFlags, |
|
177 nsIRemoteOpenFileListener* aListener, |
|
178 nsITabChild* aTabChild) |
|
179 { |
|
180 if (!mFile) { |
|
181 return NS_ERROR_NOT_INITIALIZED; |
|
182 } |
|
183 |
|
184 if (!aListener) { |
|
185 return NS_ERROR_INVALID_ARG; |
|
186 } |
|
187 |
|
188 if (mAsyncOpenCalled) { |
|
189 return NS_ERROR_ALREADY_OPENED; |
|
190 } |
|
191 |
|
192 if (aFlags != PR_RDONLY) { |
|
193 return NS_ERROR_NOT_AVAILABLE; |
|
194 } |
|
195 |
|
196 mTabChild = static_cast<TabChild*>(aTabChild); |
|
197 |
|
198 if (MissingRequiredTabChild(mTabChild, "remoteopenfile")) { |
|
199 return NS_ERROR_ILLEGAL_VALUE; |
|
200 } |
|
201 |
|
202 #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) |
|
203 // Windows/OSX desktop builds skip remoting, and just open file in child |
|
204 // process when asked for NSPR handle |
|
205 nsRefPtr<CallsListenerInNewEvent> runnable = |
|
206 new CallsListenerInNewEvent(aListener, NS_OK); |
|
207 runnable->Dispatch(); |
|
208 |
|
209 mAsyncOpenCalled = true; |
|
210 return NS_OK; |
|
211 #else |
|
212 nsString path; |
|
213 if (NS_FAILED(mFile->GetPath(path))) { |
|
214 MOZ_CRASH("Couldn't get path from file!"); |
|
215 } |
|
216 |
|
217 if (mTabChild) { |
|
218 if (mTabChild->GetCachedFileDescriptor(path, this)) { |
|
219 // The file descriptor was found in the cache and OnCachedFileDescriptor() |
|
220 // will be called with it. |
|
221 return NS_OK; |
|
222 } |
|
223 } |
|
224 |
|
225 URIParams uri; |
|
226 SerializeURI(mURI, uri); |
|
227 OptionalURIParams appUri; |
|
228 SerializeURI(mAppURI, appUri); |
|
229 |
|
230 gNeckoChild->SendPRemoteOpenFileConstructor(this, uri, appUri); |
|
231 |
|
232 // The chrome process now has a logical ref to us until it calls Send__delete. |
|
233 AddIPDLReference(); |
|
234 |
|
235 mListener = aListener; |
|
236 mAsyncOpenCalled = true; |
|
237 return NS_OK; |
|
238 #endif |
|
239 } |
|
240 |
|
241 void |
|
242 RemoteOpenFileChild::OnCachedFileDescriptor(const nsAString& aPath, |
|
243 const FileDescriptor& aFD) |
|
244 { |
|
245 #ifdef DEBUG |
|
246 if (!aPath.IsEmpty()) { |
|
247 MOZ_ASSERT(mFile); |
|
248 |
|
249 nsString path; |
|
250 MOZ_ASSERT(NS_SUCCEEDED(mFile->GetPath(path))); |
|
251 MOZ_ASSERT(path == aPath, "Paths don't match!"); |
|
252 } |
|
253 #endif |
|
254 |
|
255 HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvDelete */ false); |
|
256 } |
|
257 |
|
258 void |
|
259 RemoteOpenFileChild::HandleFileDescriptorAndNotifyListener( |
|
260 const FileDescriptor& aFD, |
|
261 bool aFromRecvDelete) |
|
262 { |
|
263 #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) |
|
264 MOZ_CRASH("OS X and Windows shouldn't be doing IPDL here"); |
|
265 #else |
|
266 if (!mListener) { |
|
267 // We already notified our listener (either in response to a cached file |
|
268 // descriptor callback or through the normal messaging mechanism). Close the |
|
269 // file descriptor if it is valid. |
|
270 if (aFD.IsValid()) { |
|
271 nsRefPtr<CloseFileRunnable> runnable = new CloseFileRunnable(aFD); |
|
272 runnable->Dispatch(); |
|
273 } |
|
274 return; |
|
275 } |
|
276 |
|
277 MOZ_ASSERT(!mNSPRFileDesc); |
|
278 |
|
279 nsRefPtr<TabChild> tabChild; |
|
280 mTabChild.swap(tabChild); |
|
281 |
|
282 // If RemoteOpenFile reply (Recv__delete__) for app's application.zip comes |
|
283 // back sooner than the parent-pushed fd (TabChild::RecvCacheFileDescriptor()) |
|
284 // have TabChild cancel running callbacks, since we'll call them in |
|
285 // NotifyListener. |
|
286 if (tabChild && aFromRecvDelete) { |
|
287 nsString path; |
|
288 if (NS_FAILED(mFile->GetPath(path))) { |
|
289 MOZ_CRASH("Couldn't get path from file!"); |
|
290 } |
|
291 |
|
292 tabChild->CancelCachedFileDescriptorCallback(path, this); |
|
293 } |
|
294 |
|
295 if (aFD.IsValid()) { |
|
296 mNSPRFileDesc = PR_ImportFile(aFD.PlatformHandle()); |
|
297 if (!mNSPRFileDesc) { |
|
298 NS_WARNING("Failed to import file handle!"); |
|
299 } |
|
300 } |
|
301 |
|
302 NotifyListener(mNSPRFileDesc ? NS_OK : NS_ERROR_FILE_NOT_FOUND); |
|
303 #endif |
|
304 } |
|
305 |
|
306 void |
|
307 RemoteOpenFileChild::NotifyListener(nsresult aResult) |
|
308 { |
|
309 MOZ_ASSERT(mListener); |
|
310 mListener->OnRemoteFileOpenComplete(aResult); |
|
311 mListener = nullptr; // release ref to listener |
|
312 |
|
313 nsRefPtr<nsJARProtocolHandler> handler(gJarHandler); |
|
314 NS_WARN_IF_FALSE(handler, "nsJARProtocolHandler is already gone!"); |
|
315 |
|
316 if (handler) { |
|
317 handler->RemoteOpenFileComplete(this, aResult); |
|
318 } |
|
319 } |
|
320 |
|
321 //----------------------------------------------------------------------------- |
|
322 // RemoteOpenFileChild::PRemoteOpenFileChild |
|
323 //----------------------------------------------------------------------------- |
|
324 |
|
325 bool |
|
326 RemoteOpenFileChild::Recv__delete__(const FileDescriptor& aFD) |
|
327 { |
|
328 #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) |
|
329 NS_NOTREACHED("OS X and Windows shouldn't be doing IPDL here"); |
|
330 #else |
|
331 HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvDelete */ true); |
|
332 #endif |
|
333 |
|
334 return true; |
|
335 } |
|
336 |
|
337 //----------------------------------------------------------------------------- |
|
338 // RemoteOpenFileChild::nsIFile functions that we override logic for |
|
339 //----------------------------------------------------------------------------- |
|
340 |
|
341 NS_IMETHODIMP |
|
342 RemoteOpenFileChild::Clone(nsIFile **file) |
|
343 { |
|
344 *file = new RemoteOpenFileChild(*this); |
|
345 NS_ADDREF(*file); |
|
346 |
|
347 // if we transferred ownership of file to clone, forget our pointer. |
|
348 if (mNSPRFileDesc) { |
|
349 mNSPRFileDesc = nullptr; |
|
350 } |
|
351 |
|
352 return NS_OK; |
|
353 } |
|
354 |
|
355 /* The main event: get file descriptor from parent process |
|
356 */ |
|
357 NS_IMETHODIMP |
|
358 RemoteOpenFileChild::OpenNSPRFileDesc(int32_t aFlags, int32_t aMode, |
|
359 PRFileDesc **aRetval) |
|
360 { |
|
361 #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) |
|
362 // Windows and OSX builds: just open nsIFile locally. |
|
363 return mFile->OpenNSPRFileDesc(aFlags, aMode, aRetval); |
|
364 |
|
365 #else |
|
366 if (aFlags != PR_RDONLY) { |
|
367 return NS_ERROR_NOT_AVAILABLE; |
|
368 } |
|
369 |
|
370 // Unlike regular nsIFile we can't (easily) support multiple open()s. |
|
371 if (mNSPROpenCalled) { |
|
372 return NS_ERROR_ALREADY_OPENED; |
|
373 } |
|
374 |
|
375 if (!mNSPRFileDesc) { |
|
376 // client skipped AsyncRemoteFileOpen() or didn't wait for result, or this |
|
377 // object has been cloned |
|
378 return NS_ERROR_NOT_AVAILABLE; |
|
379 } |
|
380 |
|
381 // hand off ownership (i.e responsibility to PR_Close() file handle) to caller |
|
382 *aRetval = mNSPRFileDesc; |
|
383 mNSPRFileDesc = nullptr; |
|
384 mNSPROpenCalled = true; |
|
385 |
|
386 return NS_OK; |
|
387 #endif |
|
388 } |
|
389 |
|
390 |
|
391 //----------------------------------------------------------------------------- |
|
392 // RemoteOpenFileChild::nsIFile functions that we delegate to underlying nsIFile |
|
393 //----------------------------------------------------------------------------- |
|
394 |
|
395 nsresult |
|
396 RemoteOpenFileChild::GetLeafName(nsAString &aLeafName) |
|
397 { |
|
398 return mFile->GetLeafName(aLeafName); |
|
399 } |
|
400 |
|
401 NS_IMETHODIMP |
|
402 RemoteOpenFileChild::GetNativeLeafName(nsACString &aLeafName) |
|
403 { |
|
404 return mFile->GetNativeLeafName(aLeafName); |
|
405 } |
|
406 |
|
407 nsresult |
|
408 RemoteOpenFileChild::GetTarget(nsAString &_retval) |
|
409 { |
|
410 return mFile->GetTarget(_retval); |
|
411 } |
|
412 |
|
413 NS_IMETHODIMP |
|
414 RemoteOpenFileChild::GetNativeTarget(nsACString &_retval) |
|
415 { |
|
416 return mFile->GetNativeTarget(_retval); |
|
417 } |
|
418 |
|
419 nsresult |
|
420 RemoteOpenFileChild::GetPath(nsAString &_retval) |
|
421 { |
|
422 return mFile->GetPath(_retval); |
|
423 } |
|
424 |
|
425 NS_IMETHODIMP |
|
426 RemoteOpenFileChild::GetNativePath(nsACString &_retval) |
|
427 { |
|
428 return mFile->GetNativePath(_retval); |
|
429 } |
|
430 |
|
431 NS_IMETHODIMP |
|
432 RemoteOpenFileChild::Equals(nsIFile *inFile, bool *_retval) |
|
433 { |
|
434 return mFile->Equals(inFile, _retval); |
|
435 } |
|
436 |
|
437 NS_IMETHODIMP |
|
438 RemoteOpenFileChild::Contains(nsIFile *inFile, bool recur, bool *_retval) |
|
439 { |
|
440 return mFile->Contains(inFile, recur, _retval); |
|
441 } |
|
442 |
|
443 NS_IMETHODIMP |
|
444 RemoteOpenFileChild::GetParent(nsIFile **aParent) |
|
445 { |
|
446 return mFile->GetParent(aParent); |
|
447 } |
|
448 |
|
449 NS_IMETHODIMP |
|
450 RemoteOpenFileChild::GetFollowLinks(bool *aFollowLinks) |
|
451 { |
|
452 return mFile->GetFollowLinks(aFollowLinks); |
|
453 } |
|
454 |
|
455 //----------------------------------------------------------------------------- |
|
456 // RemoteOpenFileChild::nsIFile functions that are not currently supported |
|
457 //----------------------------------------------------------------------------- |
|
458 |
|
459 nsresult |
|
460 RemoteOpenFileChild::Append(const nsAString &node) |
|
461 { |
|
462 return NS_ERROR_NOT_IMPLEMENTED; |
|
463 } |
|
464 |
|
465 NS_IMETHODIMP |
|
466 RemoteOpenFileChild::AppendNative(const nsACString &fragment) |
|
467 { |
|
468 return NS_ERROR_NOT_IMPLEMENTED; |
|
469 } |
|
470 |
|
471 NS_IMETHODIMP |
|
472 RemoteOpenFileChild::Normalize() |
|
473 { |
|
474 return NS_ERROR_NOT_IMPLEMENTED; |
|
475 } |
|
476 |
|
477 NS_IMETHODIMP |
|
478 RemoteOpenFileChild::Create(uint32_t type, uint32_t permissions) |
|
479 { |
|
480 return NS_ERROR_NOT_IMPLEMENTED; |
|
481 } |
|
482 |
|
483 nsresult |
|
484 RemoteOpenFileChild::SetLeafName(const nsAString &aLeafName) |
|
485 { |
|
486 return NS_ERROR_NOT_IMPLEMENTED; |
|
487 } |
|
488 |
|
489 NS_IMETHODIMP |
|
490 RemoteOpenFileChild::SetNativeLeafName(const nsACString &aLeafName) |
|
491 { |
|
492 return NS_ERROR_NOT_IMPLEMENTED; |
|
493 } |
|
494 |
|
495 nsresult |
|
496 RemoteOpenFileChild::InitWithPath(const nsAString &filePath) |
|
497 { |
|
498 return NS_ERROR_NOT_IMPLEMENTED; |
|
499 } |
|
500 |
|
501 NS_IMETHODIMP |
|
502 RemoteOpenFileChild::InitWithNativePath(const nsACString &filePath) |
|
503 { |
|
504 return NS_ERROR_NOT_IMPLEMENTED; |
|
505 } |
|
506 |
|
507 NS_IMETHODIMP |
|
508 RemoteOpenFileChild::InitWithFile(nsIFile *aFile) |
|
509 { |
|
510 return NS_ERROR_NOT_IMPLEMENTED; |
|
511 } |
|
512 |
|
513 NS_IMETHODIMP |
|
514 RemoteOpenFileChild::SetFollowLinks(bool aFollowLinks) |
|
515 { |
|
516 return NS_ERROR_NOT_IMPLEMENTED; |
|
517 } |
|
518 |
|
519 nsresult |
|
520 RemoteOpenFileChild::AppendRelativePath(const nsAString &node) |
|
521 { |
|
522 return NS_ERROR_NOT_IMPLEMENTED; |
|
523 } |
|
524 |
|
525 NS_IMETHODIMP |
|
526 RemoteOpenFileChild::AppendRelativeNativePath(const nsACString &fragment) |
|
527 { |
|
528 return NS_ERROR_NOT_IMPLEMENTED; |
|
529 } |
|
530 |
|
531 NS_IMETHODIMP |
|
532 RemoteOpenFileChild::GetPersistentDescriptor(nsACString &aPersistentDescriptor) |
|
533 { |
|
534 return NS_ERROR_NOT_IMPLEMENTED; |
|
535 } |
|
536 |
|
537 NS_IMETHODIMP |
|
538 RemoteOpenFileChild::SetPersistentDescriptor(const nsACString &aPersistentDescriptor) |
|
539 { |
|
540 return NS_ERROR_NOT_IMPLEMENTED; |
|
541 } |
|
542 |
|
543 NS_IMETHODIMP |
|
544 RemoteOpenFileChild::GetRelativeDescriptor(nsIFile *fromFile, nsACString& _retval) |
|
545 { |
|
546 return NS_ERROR_NOT_IMPLEMENTED; |
|
547 } |
|
548 |
|
549 NS_IMETHODIMP |
|
550 RemoteOpenFileChild::SetRelativeDescriptor(nsIFile *fromFile, |
|
551 const nsACString& relativeDesc) |
|
552 { |
|
553 return NS_ERROR_NOT_IMPLEMENTED; |
|
554 } |
|
555 |
|
556 nsresult |
|
557 RemoteOpenFileChild::CopyTo(nsIFile *newParentDir, const nsAString &newName) |
|
558 { |
|
559 return NS_ERROR_NOT_IMPLEMENTED; |
|
560 } |
|
561 |
|
562 NS_IMETHODIMP |
|
563 RemoteOpenFileChild::CopyToNative(nsIFile *newParent, const nsACString &newName) |
|
564 { |
|
565 return NS_ERROR_NOT_IMPLEMENTED; |
|
566 } |
|
567 |
|
568 nsresult |
|
569 RemoteOpenFileChild::CopyToFollowingLinks(nsIFile *newParentDir, |
|
570 const nsAString &newName) |
|
571 { |
|
572 return NS_ERROR_NOT_IMPLEMENTED; |
|
573 } |
|
574 |
|
575 NS_IMETHODIMP |
|
576 RemoteOpenFileChild::CopyToFollowingLinksNative(nsIFile *newParent, |
|
577 const nsACString &newName) |
|
578 { |
|
579 return NS_ERROR_NOT_IMPLEMENTED; |
|
580 } |
|
581 |
|
582 nsresult |
|
583 RemoteOpenFileChild::MoveTo(nsIFile *newParentDir, const nsAString &newName) |
|
584 { |
|
585 return NS_ERROR_NOT_IMPLEMENTED; |
|
586 } |
|
587 |
|
588 NS_IMETHODIMP |
|
589 RemoteOpenFileChild::MoveToNative(nsIFile *newParent, const nsACString &newName) |
|
590 { |
|
591 return NS_ERROR_NOT_IMPLEMENTED; |
|
592 } |
|
593 |
|
594 NS_IMETHODIMP |
|
595 RemoteOpenFileChild::RenameTo(nsIFile *newParentDir, const nsAString &newName) |
|
596 { |
|
597 return NS_ERROR_NOT_IMPLEMENTED; |
|
598 } |
|
599 |
|
600 NS_IMETHODIMP |
|
601 RemoteOpenFileChild::Remove(bool recursive) |
|
602 { |
|
603 return NS_ERROR_NOT_IMPLEMENTED; |
|
604 } |
|
605 |
|
606 NS_IMETHODIMP |
|
607 RemoteOpenFileChild::GetPermissions(uint32_t *aPermissions) |
|
608 { |
|
609 return NS_ERROR_NOT_IMPLEMENTED; |
|
610 } |
|
611 |
|
612 NS_IMETHODIMP |
|
613 RemoteOpenFileChild::SetPermissions(uint32_t aPermissions) |
|
614 { |
|
615 return NS_ERROR_NOT_IMPLEMENTED; |
|
616 } |
|
617 |
|
618 NS_IMETHODIMP |
|
619 RemoteOpenFileChild::GetPermissionsOfLink(uint32_t *aPermissionsOfLink) |
|
620 { |
|
621 return NS_ERROR_NOT_IMPLEMENTED; |
|
622 } |
|
623 |
|
624 NS_IMETHODIMP |
|
625 RemoteOpenFileChild::SetPermissionsOfLink(uint32_t aPermissions) |
|
626 { |
|
627 return NS_ERROR_NOT_IMPLEMENTED; |
|
628 } |
|
629 |
|
630 NS_IMETHODIMP |
|
631 RemoteOpenFileChild::GetLastModifiedTime(PRTime *aLastModTime) |
|
632 { |
|
633 return NS_ERROR_NOT_IMPLEMENTED; |
|
634 } |
|
635 |
|
636 NS_IMETHODIMP |
|
637 RemoteOpenFileChild::SetLastModifiedTime(PRTime aLastModTime) |
|
638 { |
|
639 return NS_ERROR_NOT_IMPLEMENTED; |
|
640 } |
|
641 |
|
642 NS_IMETHODIMP |
|
643 RemoteOpenFileChild::GetLastModifiedTimeOfLink(PRTime *aLastModTimeOfLink) |
|
644 { |
|
645 return NS_ERROR_NOT_IMPLEMENTED; |
|
646 } |
|
647 |
|
648 NS_IMETHODIMP |
|
649 RemoteOpenFileChild::SetLastModifiedTimeOfLink(PRTime aLastModTimeOfLink) |
|
650 { |
|
651 return NS_ERROR_NOT_IMPLEMENTED; |
|
652 } |
|
653 |
|
654 NS_IMETHODIMP |
|
655 RemoteOpenFileChild::GetFileSize(int64_t *aFileSize) |
|
656 { |
|
657 return NS_ERROR_NOT_IMPLEMENTED; |
|
658 } |
|
659 |
|
660 NS_IMETHODIMP |
|
661 RemoteOpenFileChild::SetFileSize(int64_t aFileSize) |
|
662 { |
|
663 return NS_ERROR_NOT_IMPLEMENTED; |
|
664 } |
|
665 |
|
666 NS_IMETHODIMP |
|
667 RemoteOpenFileChild::GetFileSizeOfLink(int64_t *aFileSize) |
|
668 { |
|
669 return NS_ERROR_NOT_IMPLEMENTED; |
|
670 } |
|
671 |
|
672 NS_IMETHODIMP |
|
673 RemoteOpenFileChild::Exists(bool *_retval) |
|
674 { |
|
675 return NS_ERROR_NOT_IMPLEMENTED; |
|
676 } |
|
677 |
|
678 NS_IMETHODIMP |
|
679 RemoteOpenFileChild::IsWritable(bool *_retval) |
|
680 { |
|
681 return NS_ERROR_NOT_IMPLEMENTED; |
|
682 } |
|
683 |
|
684 NS_IMETHODIMP |
|
685 RemoteOpenFileChild::IsReadable(bool *_retval) |
|
686 { |
|
687 return NS_ERROR_NOT_IMPLEMENTED; |
|
688 } |
|
689 |
|
690 NS_IMETHODIMP |
|
691 RemoteOpenFileChild::IsExecutable(bool *_retval) |
|
692 { |
|
693 return NS_ERROR_NOT_IMPLEMENTED; |
|
694 } |
|
695 |
|
696 NS_IMETHODIMP |
|
697 RemoteOpenFileChild::IsHidden(bool *_retval) |
|
698 { |
|
699 return NS_ERROR_NOT_IMPLEMENTED; |
|
700 } |
|
701 |
|
702 NS_IMETHODIMP |
|
703 RemoteOpenFileChild::IsDirectory(bool *_retval) |
|
704 { |
|
705 return NS_ERROR_NOT_IMPLEMENTED; |
|
706 } |
|
707 |
|
708 NS_IMETHODIMP |
|
709 RemoteOpenFileChild::IsFile(bool *_retval) |
|
710 { |
|
711 return NS_ERROR_NOT_IMPLEMENTED; |
|
712 } |
|
713 |
|
714 NS_IMETHODIMP |
|
715 RemoteOpenFileChild::IsSymlink(bool *_retval) |
|
716 { |
|
717 return NS_ERROR_NOT_IMPLEMENTED; |
|
718 } |
|
719 |
|
720 NS_IMETHODIMP |
|
721 RemoteOpenFileChild::IsSpecial(bool *_retval) |
|
722 { |
|
723 return NS_ERROR_NOT_IMPLEMENTED; |
|
724 } |
|
725 |
|
726 NS_IMETHODIMP |
|
727 RemoteOpenFileChild::CreateUnique(uint32_t type, uint32_t attributes) |
|
728 { |
|
729 return NS_ERROR_NOT_IMPLEMENTED; |
|
730 } |
|
731 |
|
732 NS_IMETHODIMP |
|
733 RemoteOpenFileChild::GetDirectoryEntries(nsISimpleEnumerator **entries) |
|
734 { |
|
735 return NS_ERROR_NOT_IMPLEMENTED; |
|
736 } |
|
737 |
|
738 NS_IMETHODIMP |
|
739 RemoteOpenFileChild::OpenANSIFileDesc(const char *mode, FILE **_retval) |
|
740 { |
|
741 // TODO: can implement using fdopen()? |
|
742 return NS_ERROR_NOT_IMPLEMENTED; |
|
743 } |
|
744 |
|
745 NS_IMETHODIMP |
|
746 RemoteOpenFileChild::Load(PRLibrary **_retval) |
|
747 { |
|
748 return NS_ERROR_NOT_IMPLEMENTED; |
|
749 } |
|
750 |
|
751 NS_IMETHODIMP |
|
752 RemoteOpenFileChild::GetDiskSpaceAvailable(int64_t *aDiskSpaceAvailable) |
|
753 { |
|
754 return NS_ERROR_NOT_IMPLEMENTED; |
|
755 } |
|
756 |
|
757 NS_IMETHODIMP |
|
758 RemoteOpenFileChild::Reveal() |
|
759 { |
|
760 return NS_ERROR_NOT_IMPLEMENTED; |
|
761 } |
|
762 |
|
763 NS_IMETHODIMP |
|
764 RemoteOpenFileChild::Launch() |
|
765 { |
|
766 return NS_ERROR_NOT_IMPLEMENTED; |
|
767 } |
|
768 |
|
769 //----------------------------------------------------------------------------- |
|
770 // RemoteOpenFileChild::nsIHashable functions that we delegate to underlying nsIFile |
|
771 //----------------------------------------------------------------------------- |
|
772 |
|
773 NS_IMETHODIMP |
|
774 RemoteOpenFileChild::Equals(nsIHashable* aOther, bool *aResult) |
|
775 { |
|
776 nsCOMPtr<nsIHashable> hashable = do_QueryInterface(mFile); |
|
777 |
|
778 MOZ_ASSERT(hashable); |
|
779 |
|
780 if (hashable) { |
|
781 return hashable->Equals(aOther, aResult); |
|
782 } |
|
783 return NS_ERROR_UNEXPECTED; |
|
784 } |
|
785 |
|
786 NS_IMETHODIMP |
|
787 RemoteOpenFileChild::GetHashCode(uint32_t *aResult) |
|
788 { |
|
789 nsCOMPtr<nsIHashable> hashable = do_QueryInterface(mFile); |
|
790 |
|
791 MOZ_ASSERT(hashable); |
|
792 |
|
793 if (hashable) { |
|
794 return hashable->GetHashCode(aResult); |
|
795 } |
|
796 return NS_ERROR_UNEXPECTED; |
|
797 } |
|
798 |
|
799 } // namespace net |
|
800 } // namespace mozilla |