widget/src/nsMacResources unaware of NS_XPCOM_INIT_CURRENT_PROCESS_DIR

ASSIGNED
Assigned to

Status

()

Core
Widget: Cocoa
ASSIGNED
11 years ago
8 years ago

People

(Reporter: edburns, Assigned: edburns)

Tracking

1.8 Branch
PowerPC
Mac OS X
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(2 obsolete attachments)

(Assignee)

Description

11 years ago
Hello,

I'm embedding xulrunner into java.  I have found that widget/src/mac/nsMacResources::OpenLocalResourceFile(), which is called in either Cocoa or Carbon widget mode, does not correctly handle the case where the xulrunner is being called from Java.  It simply uses the filesystem directory of the binary as the base against which to resolve the libwidget.rsrc file.

I will attach a fix that consults nsDirectoryService to resolve the file if it is not found the other way.
(Assignee)

Comment 1

11 years ago
Here is the patch:

Index: nsMacResources.cpp
===================================================================
RCS file: /cvsroot/mozilla/widget/src/mac/nsMacResources.cpp,v
retrieving revision 1.10
diff -u -r1.10 nsMacResources.cpp
--- nsMacResources.cpp	18 Apr 2004 22:00:27 -0000	1.10
+++ nsMacResources.cpp	10 Jun 2007 16:32:36 -0000
@@ -35,97 +35,126 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "nsIFile.h"
+#include "nsIURI.h"
+#include "nsIIOService.h" // for NewFileURI
 #include "nsMacResources.h"
-#include <Resources.h>
-#include <Processes.h>
+#include "nsDirectoryService.h"
+#include "nsDirectoryServiceUtils.h"
+#include <Carbon/Carbon.h>
 
-short nsMacResources::mRefNum				= kResFileNotOpened;
-short nsMacResources::mSaveResFile	= 0;
-
-#if !defined(XP_MACOSX)
-pascal OSErr __NSInitialize(const CFragInitBlock *theInitBlock);
-pascal OSErr __initializeResources(const CFragInitBlock *theInitBlock);
-
-pascal void __NSTerminate(void);
-pascal void __terminateResources(void);
-
-//----------------------------------------------------------------------------------------
-//
-//----------------------------------------------------------------------------------------
-pascal OSErr __initializeResources(const CFragInitBlock *theInitBlock)
-{
-    OSErr err = __NSInitialize(theInitBlock);
-    if (err)
-    	return err;
-
-	short saveResFile = ::CurResFile();
-
-	short refNum = FSpOpenResFile(theInitBlock->fragLocator.u.onDisk.fileSpec, fsRdPerm);
-	nsMacResources::SetLocalResourceFile(refNum);
-
-	::UseResFile(saveResFile);
-
-	return ::ResError();
-}
 
+short nsMacResources::mRefNum      = kResFileNotOpened;
+short nsMacResources::mSaveResFile = 0;
 
-//----------------------------------------------------------------------------------------
-//
-//----------------------------------------------------------------------------------------
-pascal void __terminateResources(void)
-{
-	::CloseResFile(nsMacResources::GetLocalResourceFile());
-    __NSTerminate();
-}
-#endif /*!XP_MACOSX*/
-
-//----------------------------------------------------------------------------------------
-//
-//----------------------------------------------------------------------------------------
 
 nsresult nsMacResources::OpenLocalResourceFile()
 {
-#ifdef XP_MACOSX
+  nsCOMPtr<nsIFile> mozBinDir;
+  nsCOMPtr<nsIURI> mozBinDirURI;
+  nsCString mozBinDirURISpec;
+  CFStringRef mozBinDirURISpecCFString;
+  nsresult rv = NS_ERROR_FAILURE;
+  OSErr macRv = resFNotFound;
+
   if (mRefNum == kResFileNotOpened) {
-    ProcessSerialNumber PSN;
-    ProcessInfoRec pinfo;
-    FSSpec appSpec;
-
-    PSN.highLongOfPSN = 0;
-    PSN.lowLongOfPSN = kCurrentProcess;
-    pinfo.processInfoLength = sizeof(pinfo);
-    pinfo.processName = NULL;
-    pinfo.processAppSpec = &appSpec;
-
-    if (GetProcessInformation(&PSN, &pinfo) == noErr) {
-      FSSpec resSpec = { appSpec.vRefNum, appSpec.parID, "\plibwidget.rsrc" };
-      FSRef resRef;
-      if (FSpMakeFSRef(&resSpec, &resRef) == noErr)
-        FSOpenResourceFile(&resRef, 0, NULL, fsRdPerm, &mRefNum);
+    CFBundleRef appBundle = ::CFBundleGetMainBundle();
+    if (appBundle) {
+
+      // See nsPluginHostImpl line 3305 for use of nsIDirectoryService
+
+      CFURLRef executable = ::CFBundleCopyExecutableURL(appBundle);
+      if (executable) {
+        CFURLRef binDir = ::CFURLCreateCopyDeletingLastPathComponent(
+                                                                     kCFAllocatorDefault, executable);
+        if (binDir) {
+          CFURLRef resourceFile = ::CFURLCreateCopyAppendingPathComponent(
+                                   kCFAllocatorDefault, binDir,
+                                   CFSTR("libwidget.rsrc"), PR_FALSE);
+          if (resourceFile) {
+            FSRef resourceRef;
+            if (::CFURLGetFSRef(resourceFile, &resourceRef)) {
+              macRv = ::FSOpenResourceFile(&resourceRef, 0, NULL, fsRdPerm, &mRefNum);
+              // Release the previous resourceFile
+              ::CFRelease(resourceFile);
+              
+              // Release the previous binDir
+              ::CFRelease(binDir);
+            }
+            else {
+              // See if we can use NS_XPCOM_INIT_CURRENT_PROCESS_DIR 
+              // to get the resourceFile.
+              
+              // Release the previous resourceFile
+              ::CFRelease(resourceFile);
+
+              // Release the previous binDir
+              ::CFRelease(binDir);
+
+              // Get the binDir from mozilla, instead of from the OS
+              rv = NS_GetSpecialDirectory(NS_XPCOM_INIT_CURRENT_PROCESS_DIR,
+                                          getter_AddRefs(mozBinDir));
+              
+              if (NS_SUCCEEDED(rv)) {
+                nsCOMPtr<nsIIOService> io (do_GetService("@mozilla.org/network/io-service;1"));
+                if (io) {
+                  rv = io->NewFileURI(mozBinDir, getter_AddRefs(mozBinDirURI));
+                  if (NS_SUCCEEDED(rv)) {
+                    rv = mozBinDirURI->GetSpec(mozBinDirURISpec);
+                    if (NS_SUCCEEDED(rv)) {
+                      mozBinDirURISpecCFString = 
+                        ::CFStringCreateWithCString(kCFAllocatorDefault,
+                                                    mozBinDirURISpec.get(),
+                                                    kCFStringEncodingUTF8);
+                      if (mozBinDirURISpecCFString) {
+                        binDir = ::CFURLCreateWithString(kCFAllocatorDefault,
+                                                         mozBinDirURISpecCFString,
+                                                         NULL);
+                        if (binDir) {
+                          resourceFile = 
+                            ::CFURLCreateCopyAppendingPathComponent(
+                                   kCFAllocatorDefault, binDir,
+                                   CFSTR("libwidget.rsrc"), PR_FALSE);
+                          if (resourceFile) {
+                            if (::CFURLGetFSRef(resourceFile, &resourceRef)) {
+                              macRv = ::FSOpenResourceFile(&resourceRef, 0, NULL, fsRdPerm, &mRefNum);
+                              if (noErr == macRv) {
+                              }
+                            }
+                            ::CFRelease(resourceFile);
+                          }
+                          ::CFRelease(binDir);
+                        }
+                        ::CFRelease(mozBinDirURISpecCFString);
+                      }
+                    } // Got spec from URI
+                  } // NewFileURI
+                } // Got nsIIOService
+              } // Got NS_XPCOM_INIT_CURRENT_PROCESS_DIR
+            } // Try NS_XPCOM_INIT_CURRENT_PROCESS_DIR for the resource file
+          }
+        }
+        ::CFRelease(executable);
+      }
     }
   }
-#endif
-	if (mRefNum == kResFileNotOpened)
-		return NS_ERROR_NOT_INITIALIZED;
+  if (mRefNum == kResFileNotOpened)
+    return NS_ERROR_NOT_INITIALIZED;
 
-	mSaveResFile = ::CurResFile();
-	::UseResFile(mRefNum);
+  mSaveResFile = ::CurResFile();
+  ::UseResFile(mRefNum);
 
-	return (::ResError() == noErr ? NS_OK : NS_ERROR_FAILURE);
+  return (::ResError() == noErr ? NS_OK : NS_ERROR_FAILURE);
 }
 
 
-//----------------------------------------------------------------------------------------
-//
-//----------------------------------------------------------------------------------------
-
 nsresult nsMacResources::CloseLocalResourceFile()
 {
-	if (mRefNum == kResFileNotOpened)
-		return NS_ERROR_NOT_INITIALIZED;
+  if (mRefNum == kResFileNotOpened)
+    return NS_ERROR_NOT_INITIALIZED;
 
-	::UseResFile(mSaveResFile);
+  ::UseResFile(mSaveResFile);
 
-	return (::ResError() == noErr ? NS_OK : NS_ERROR_FAILURE);
+  return (::ResError() == noErr ? NS_OK : NS_ERROR_FAILURE);
 }
 
Assignee: nobody → edburns
Status: ASSIGNED → NEW
(Assignee)

Comment 2

11 years ago
Created attachment 267869 [details]
File with patct app/ieh
(Assignee)

Comment 3

11 years ago
Created attachment 267870 [details] [diff] [review]
patch as an attachment
(Assignee)

Updated

11 years ago
Attachment #267870 - Flags: review?(cbarrett)
Assignee: edburns → joshmoz
Component: OS Integration → Widget: Cocoa
Product: Firefox → Core
QA Contact: os.integration → cocoa
(In reply to comment #0)
> I'm embedding xulrunner into java.  I have found that
> widget/src/mac/nsMacResources::OpenLocalResourceFile(), which is called in
> either Cocoa or Carbon widget mode

Are you sure this code is used when building with Cocoa widget enabled? It doesn't seem to be referenced from anywhere within widget/src/cocoa.
Assignee: joshmoz → edburns
(Assignee)

Comment 5

11 years ago
I'll try to produce a stack trace, but I'm pretty sure it is.

Can you tell me what CVS tag to pull that corresponds to the xulrunner contrib 1.8.1.3 build?
(Assignee)

Comment 6

11 years ago
Yes, it does get called.  I built FIREFOX_2_0_0_3_RELEASE with xulrunner and cocoa enabled, and saw that this method was hit here:

#0  nsMacResources::OpenLocalResourceFile () at nsMacResources.cpp:47
#1  0x12d751bc in -[nsResourceCursor setFrame:] (self=0x2cc8bd00, _cmd=0x90ab1b7c, aFrameIndex=2) at /Users/edburns/Projects/mozilla/FIREFOX_2_0_0_3_RELEASE/mozilla/widget/src/cocoa/nsMacCursor.mm:395
#2  0x12d74a14 in -[nsMacCursor spinCursor:] (self=0x2cc8bd00, _cmd=0x130d595c, aTimer=0x2dc9ae70) at /Users/edburns/Projects/mozilla/FIREFOX_2_0_0_3_RELEASE/mozilla/widget/src/cocoa/nsMacCursor.mm:274
#3  0x92be5f68 in __NSFireTimer ()
#4  0x907f2578 in __CFRunLoopDoTimer ()
#5  0x907deef8 in __CFRunLoopRun ()
#6  0x907de4ac in CFRunLoopRunSpecific ()
#7  0x9329bb20 in RunCurrentEventLoopInMode ()
#8  0x9329b1b4 in ReceiveNextEventCommon ()
#9  0x9329b020 in BlockUntilNextEventMatchingListInMode ()
#10 0x937c6ae4 in _DPSNextEvent ()
#11 0x937c67a8 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#12 0x937c2cec in -[NSApplication run] ()
#13 0x9fe4f488 in +[AWTStarter startAWT:] ()
#14 0x92bf0a0c in __NSFireMainThreadPerform ()
#15 0x9080fae0 in __CFRunLoopPerformPerform ()
#16 0x907df4fc in __CFRunLoopDoSources0 ()
#17 0x907dea2c in __CFRunLoopRun ()
#18 0x907de4ac in CFRunLoopRunSpecific ()
#19 0x00004e4c in ?? ()
#20 0x00002728 in ?? ()
#21 0x0000242c in ?? ()

Can you please proceed with a review of my fix?

Thanks for your prompt treatment.

Updated

11 years ago
Version: Trunk → 1.8 Branch
(Assignee)

Updated

11 years ago
Attachment #267870 - Flags: review?(cbarrett)
(Assignee)

Comment 7

11 years ago
I talked with Josh on IRC about this and he wants me to produce a trunk patch, with fewer nested if statements.

I'll do that and re-submit the review request.
Status: NEW → ASSIGNED

Updated

10 years ago
Attachment #267869 - Attachment is obsolete: true

Updated

10 years ago
Attachment #267870 - Attachment is obsolete: true
Ed, do you still need this on 1.9.1 and/or below?  OpenLocalResourceFile (and libwidget.rsrc) is dead and gone on 1.9.2 and up.
You need to log in before you can comment on or make changes to this bug.