/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Steve Dagley <sdagley@netscape.com>
* John R. McMullen
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsMemory.h"
#include "nsXPIDLString.h"
#include "nsLocalFile.h"
#include "nsNativeCharsetUtils.h"
#include "nsISimpleEnumerator.h"
#include "nsIComponentManager.h"
#include "nsIInternetConfigService.h"
#include "nsIMIMEInfo.h"
#include "prtypes.h"
#include "prerror.h"
#include "nsReadableUtils.h"
#include "nsITimelineService.h"
#ifdef XP_MACOSX
#include "nsXPIDLString.h"
#else
#endif
#include "prmem.h"
#include "plbase64.h"
#include "FullPath.h"
#include "FileCopy.h"
#include "MoreFilesExtras.h"
#include "DirectoryCopy.h"
#include <Script.h>
#include <Processes.h>
#include <StringCompare.h>
#include <Resources.h>
#include <AppleEvents.h>
#include <AEDataModel.h>
#include <AERegistry.h>
#include <Gestalt.h>
#include <Math64.h>
#include <Aliases.h>
#include <Folders.h>
#include <Gestalt.h>
#include "macDirectoryCopy.h"
#include <limits.h>
// Stupid @#$% header looks like its got extern mojo but it doesn't really
extern "C"
{
#ifndef XP_MACOSX
// BADPINK - this MSL header doesn't exist under macosx :-(
#include <FSp_fopen.h>
#endif
}
#if TARGET_CARBON
#include <CodeFragments.h> // Needed for definition of kUnresolvedCFragSymbolAddress
#include <LaunchServices.h>
#endif
#pragma mark -
#pragma mark [nsPathParser]
class nsPathParser
{
public:
~nsPathParser()
{
if (mAllocatedBuffer)
}
const char* First()
{
}
const char* Next()
{
}
const char* Remainder()
{
return mNewString;
}
private:
char *mAllocatedBuffer;
};
{
if (inPathLen >= sizeof(mAutoBuffer)) {
}
else
// copy inPath into mBuffer
}
}
#pragma mark -
{
}
// Simple func to map Mac OS errors into nsresults
{
switch (inErr)
{
case noErr:
break;
case fnfErr:
break;
case dupFNErr:
break;
case dskFulErr:
break;
case fLckdErr:
break;
// Can't find good map for some
case bdNamErr:
break;
default:
break;
}
return outErr;
}
/*----------------------------------------------------------------------------
IsEqualFSSpec
Compare two canonical FSSpec records.
Entry: file1 = pointer to first FSSpec record.
file2 = pointer to second FSSpec record.
Exit: function result = true if the FSSpec records are equal.
----------------------------------------------------------------------------*/
{
return
}
/*----------------------------------------------------------------------------
GetParentFolderSpec
Given an FSSpec to a (possibly non-existent) file, get an FSSpec for its
parent directory.
----------------------------------------------------------------------------*/
{
parentDirSpec.name[0] = 0;
return err;
}
/*----------------------------------------------------------------------------
VolHasDesktopDB
Check to see if a volume supports the new desktop database.
Entry: vRefNum = vol ref num of volumn
Exit: function result = error code.
*hasDesktop = true if volume has the new desktop database.
----------------------------------------------------------------------------*/
{
return err;
}
/*----------------------------------------------------------------------------
GetLastModDateTime
Get the last mod date and time of a file.
Entry: fSpec = pointer to file spec.
Exit: function result = error code.
*lastModDateTime = last mod date and time.
----------------------------------------------------------------------------*/
{
return noErr;
}
/*----------------------------------------------------------------------------
FindAppOnVolume
Find an application on a volume.
Entry: sig = application signature.
vRefNum = vol ref num
Exit: function result = error code
= afpItemNotFound if app not found on vol.
*file = file spec for application on volume.
----------------------------------------------------------------------------*/
{
short ioDTRefNum, i;
i = 1;
maxLastModDateTime = 0;
while (true)
{
if (lastModDateTime > maxLastModDateTime) {
}
}
i++;
}
}
/*----------------------------------------------------------------------------
GetIndVolume
Get a volume reference number by volume index.
Entry: index = volume index
Exit: function result = error code.
*vRefNum = vol ref num of indexed volume.
----------------------------------------------------------------------------*/
{
return err;
}
// Private NSPR functions
static unsigned long gJanuaryFirst1970Seconds = 0;
/*
* The geographic location and time zone information of a Mac
* are stored in extended parameter RAM. The ReadLocation
* produdure uses the geographic location record, MachineLocation,
* to read the geographic location and time zone information in
* extended parameter RAM.
*
* Because serial port and SLIP conflict with ReadXPram calls,
* we cache the call here.
*
* Caveat: this caching will give the wrong result if a session
* extend across the DST changeover time.
*/
{
if (!didReadLocation) {
didReadLocation = true;
}
}
static long GMTDelta(void)
{
long gmtDelta;
gmtDelta |= 0xff000000;
}
return gmtDelta;
}
static void MacintoshInitializeTime(void)
{
/*
* The NSPR epoch is midnight, Jan. 1, 1970 GMT.
*
* At midnight Jan. 1, 1970 GMT, the local time was
* midnight Jan. 1, 1970 + GMTDelta().
*
* Midnight Jan. 1, 1970 is 86400 * (365 * (1970 - 1904) + 17)
* = 2082844800 seconds since the Mac epoch.
* (There were 17 leap years from 1904 to 1970.)
*
* So the NSPR epoch is 2082844800 + GMTDelta() seconds since
* the Mac epoch. Whew! :-)
*/
}
{
if ( gJanuaryFirst1970Seconds == 0)
return NS_OK;
}
{
return NS_OK;
}
{
if (srcLength > 255)
srcLength = 255;
}
{
}
/*
NS_TruncNodeName
Utility routine to do a mid-trunc on a potential file name so that it is
no longer than 31 characters. Until we move to the HFS+ APIs we need this
to come up with legal Mac file names.
Entry: aNode = initial file name
outBuf = scratch buffer for the truncated name (MUST be >= 32 characters)
Exit: function result = pointer to truncated name. Will be either aNode or outBuf.
*/
{
{
// Init to "..." in case we fail to get the ellipsis token
if (!sInitialized)
{
// Entries in the table are:
// 0 == 1 byte char
// 1 == 2 byte char
if (itl4ResHandle)
{
{
sEllipsisTokenLen = tokenStr[0];
}
}
}
return outBuf;
}
return aNode;
}
/**
* HFSPlusGetRawPath returns the path for an FSSpec as a unicode string.
*
* The reason for this routine instead of just calling FSRefMakePath is
* (1) inSpec does not have to exist
* (2) FSRefMakePath uses '/' as the separator under OSX and ':' under OS9
*/
{
catalogInfo.parentDirID = 0;
}
}
&nodeName,
&parentRef);
{
}
}
return err;
}
// The R**co FSSpec resolver -
// it slices, it dices, it juliannes fries and it even creates FSSpecs out of whatever you feed it
// This function will take a path and a starting FSSpec and generate a FSSpec to represent
// the target of the two. If the intial FSSpec is null the path alone will be resolved
static OSErr ResolvePathAndSpec(const char * filePath, FSSpec *inSpec, PRBool createDirs, FSSpec *outSpec)
{
if (isRelative && inSpec)
{
{
long theDirID;
{
}
}
}
else
{
}
if (err)
return err;
// Try making an FSSpec from the path
if (inLength < 255)
{
// Use tempSpec as dest because if FSMakeFSSpec returns dirNFErr, it
// will reset the dest spec and we'll lose what we determined above.
}
else if (!isRelative)
{
}
else
{ // If the path is relative and >255 characters we need to manually walk the
// path appending each node to the initial FSSpec so to reach that code we
// set the err to bdNamErr and fall into the code below
}
// If we successfully created a spec then leave
return err;
// We get here when the directory hierarchy needs to be created or we're resolving
// a relative path >255 characters long
{
if (!isRelative) // If path is relative, we still need vRefNum & parID.
{
}
do
{
// Locate the colon that terminates the node.
// But if we've a partial path (starting with a colon), find the second one.
// Well, if there are no more colons, point to the end of the string.
if (!nextColon)
// Make a pascal string out of this node. Include initial
// and final colon, if any!
// Use this string as a relative path using the directory created
// on the previous round (or directory 0,0 on the first round).
// If this was the leaf node, then we are done.
if (!*nextColon)
break;
// Since there's more to go, we have to get the directory ID, which becomes
// the parID for the next round.
{
// The directory (or perhaps a file) exists. Find its dirID.
long dirID;
if (!isDirectory)
break; // bail if we've got an error
}
{
// If we got "file not found" and we're allowed to create directories
// then we need to create one
// For some reason, this usually returns fnfErr, even though it works.
}
break;
} while (true);
}
return err;
}
#pragma mark -
#pragma mark [StFollowLinksState]
class StFollowLinksState
{
public:
{
if (mFile)
}
{
if (mFile) {
}
}
{
if (mFile)
}
private:
};
#pragma mark -
#pragma mark [nsDirEnumerator]
{
public:
{
}
{
return rv;
if (err || !isDirectory)
return NS_ERROR_FILE_NOT_DIRECTORY;
mItemIndex = 1;
return NS_OK;
}
{
{
mItemName[0] = 0;
{
// end of dir entries
return NS_OK;
}
// Make a new nsILocalFile for the new element
return rv;
}
return NS_OK;
}
{
++mItemIndex;
return NS_OK;
}
private:
~nsDirEnumerator() {}
protected:
short mItemIndex;
long mDirID;
};
#pragma mark -
mType('TEXT'),
{
if (sCurrentProcessSignature != 0)
}
{
*this = srcFile;
}
mType('TEXT'),
{
if (sCurrentProcessSignature != 0)
}
{
if (!rhs.mCatInfoDirty)
return *this;
}
#pragma mark -
{
return NS_ERROR_OUT_OF_MEMORY;
{
delete inst;
return rv;
}
return NS_OK;
}
// This function resets any cached information about the file.
void
{
}
/* attribute PRBool followLinks; */
{
return NS_OK;
}
{
if (aFollowLinks != mFollowLinks)
{
}
return NS_OK;
}
{
// fnfErr means target spec is valid but doesn't exist.
// If the end result is fnfErr, we're cleanly resolved.
if (mSpecDirty)
{
if (mAppendedPath.Length())
{
}
else
{
}
}
{
if (mFollowLinks)
{
// Resolve the alias to the original file.
}
}
else
{
mTargetSpec = mSpec;
}
}
return (MacErrorMapper(err));
}
{
// Just copy-construct ourselves
*file = new nsLocalFile(*this);
if (!*file)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
{
// The incoming path must be a FULL path
return NS_ERROR_INVALID_ARG;
MakeDirty();
// If it starts with a colon, it's invalid
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
// The first component must be an existing volume
if (err)
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
// Build as much of a spec as possible from the rest of the path
// What doesn't exist will be left over in mAppendedPath
const char *nextNode;
long dirID;
break;
break;
}
return NS_OK;
}
{
return rv;
}
{
if (!asLocalFile)
return NS_ERROR_NO_INTERFACE; // Well, sort of.
*this = *asLocalFile;
return NS_OK;
}
{
// Macintosh doesn't really have mode bits, just drop them
rv = ResolveAndStat();
if (flags & PR_CREATE_FILE) {
/* If opening with the PR_EXCL flag the existence of the file prior to opening is an error */
return rv;
}
return rv;
perm = fsRdWrPerm;
else
short refnum;
return MacErrorMapper(err);
return NS_OK;
}
{
rv = ResolveAndStat();
return rv;
{
if (rv == NS_ERROR_FILE_NOT_FOUND) {
return rv;
}
}
return rv;
#ifdef MACOSX
// FSp_fopen() doesn't exist under macosx :-(
return rv;
#else
#endif
if (*_retval)
return NS_OK;
return NS_ERROR_FAILURE;
}
{
return NS_ERROR_FILE_UNKNOWN_TYPE;
if (mAppendedPath.Length())
{ // We've got an FSSpec and an appended path so pass 'em both to ResolvePathAndSpec
}
else
{
}
return (MacErrorMapper(err));
switch (type)
{
case NORMAL_FILE_TYPE:
break;
case DIRECTORY_TYPE:
{
long newDirID;
// For some reason, this usually returns fnfErr, even though it works.
}
break;
default:
return NS_ERROR_FILE_UNKNOWN_TYPE;
break;
}
{
}
return (MacErrorMapper(err));
}
{
return NS_OK;
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
MakeDirty();
if (!mAppendedPath.Length())
{
{
long dirID;
if (!resolvedWasFolder)
return NS_ERROR_FILE_NOT_DIRECTORY;
return MacErrorMapper(err);
return MacErrorMapper(err);
}
else
return MacErrorMapper(err);
}
else
{
}
return NS_OK;
}
{
return rv;
}
{
return NS_ERROR_INVALID_ARG;
while (node)
{
return rv;
}
return NS_OK;
}
{
return rv;
}
{
// See if we've had a path appended
if (mAppendedPath.Length())
{
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
// if the working path is just a node without any directory delimeters.
else
leaf++;
}
else
{
// We don't have an appended path so grab the leaf name from the FSSpec
// Convert the Pascal string to a C string
if (!leafName) return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
{
return rv;
}
{
return NS_ERROR_INVALID_ARG;
MakeDirty();
if (mAppendedPath.Length())
{ // Lop off the end of the appended path and replace it with the new leaf name
{
}
}
else
{
// We don't have an appended path so directly modify the FSSpec
}
return NS_OK;
}
{
return rv;
}
{
#if TARGET_CARBON
if (sHasHFSPlusAPIs) // should always be true under Carbon, but in case...
{
return MacErrorMapper(err);
return rv;
}
else
#endif
{
// Now would be a good time to call the code that makes an FSSpec into a path
short fullPathLen;
if (!fullPathHandle)
return NS_ERROR_OUT_OF_MEMORY;
::HLock(fullPathHandle);
}
// We need to make sure that even if we have a path to a
// directory we don't return the trailing colon. It breaks
// the component manager. (Bugzilla bug #26102)
// Now, tack on mAppendedPath. It never ends in a colon.
if (mAppendedPath.Length())
{
}
return NS_OK;
}
{
#if TARGET_CARBON
if (sHasHFSPlusAPIs) // should always be true under Carbon, but in case...
{
return MacErrorMapper(err);
// We need to make sure that even if we have a path to a
// directory we don't return the trailing colon. It breaks
// the component manager. (Bugzilla bug #26102)
// Now, tack on mAppendedPath. It never ends in a colon.
if (mAppendedPath.Length())
{
return rv;
}
}
else
#endif
{
}
}
return rv;
}
nsresult nsLocalFile::MoveCopy( nsIFile* newParentDir, const nsACString &newName, PRBool isCopy, PRBool followLinks )
{
return rv;
// If newParentDir == nsnull, it's a simple rename
if ( !newParentDir )
{
return MacErrorMapper( macErr );
}
return rv;
long dirID;
if ( macErr || !isDirectory )
else
if ( isCopy )
{
{
const PRInt32 kCopyBufferSize = (1024 * 512); // allocate our own buffer to speed file copies. Bug #103202
// it's OK if the allocated failed; FSpFileCopy will just fall back on its own internal 16k buffer
if (copyBufferHand)
{
::HLock(copyBufferHand);
}
if ( isDirectory )
macErr = MacFSpDirectoryCopyRename( &srcSpec, &destSpec, newPascalName, copyBuffer, copyBufferSize, true, NULL );
else
if (copyBufferHand)
}
}
else
{
if ( macErr == diffVolErr)
{
// On a different Volume so go for Copy and then delete
return rv;
}
}
return MacErrorMapper( macErr );
}
{
}
{
return rv;
}
{
}
{
return rv;
}
{
}
{
return rv;
}
{
return rv;
if (! isFile)
return NS_ERROR_FILE_IS_DIRECTORY;
NS_TIMELINE_START_TIMER("PR_LoadLibrary");
#if !TARGET_CARBON
// This call to SystemTask is here to give the OS time to grow its
// FCB (file control block) list, which it seems to be unable to
// do unless we yield some time to the OS. See bugs 64978 & 70543
// for the whole story.
::SystemTask();
#endif
// Use the new PR_LoadLibraryWithFlags which allows us to use a FSSpec
NS_TIMELINE_STOP_TIMER("PR_LoadLibrary");
NS_TIMELINE_MARK_TIMER("PR_LoadLibrary");
if (*_retval)
return NS_OK;
return NS_ERROR_NULL_POINTER;
}
{
StFollowLinksState(this, PR_FALSE);
return rv;
return rv;
else
return MacErrorMapper( err );
}
{
*aLastModifiedTime = 0;
return rv;
return rv;
// The mod date is in the same spot for files and dirs.
}
{
return rv;
{
{
}
else
{
}
return MacErrorMapper(err);
}
return rv;
}
{
return rv;
if (!isLink)
return NS_ERROR_FAILURE;
return GetLastModifiedTime(aLastModifiedTime);
}
{
return rv;
if (!isLink)
return NS_ERROR_FAILURE;
return SetLastModifiedTime(aLastModifiedTime);
}
{
{
{
// For now we've only got 32 bits of file size info
// WARNING!!!!!!
//
// For now we do NOT add the data and resource fork sizes as there are several
// assumptions in the code (notably in form submit) that only the data fork is
// used.
// LL_I2L(resInt64, resSize);
}
// leave size at zero for dirs
}
return rv;
}
{
return rv;
short refNum;
// Need to open the file to set the size
return NS_ERROR_FILE_ACCESS_DENIED;
// Close the file unless we got an error that it was already closed
return MacErrorMapper(err);
return MacErrorMapper(err);
}
{
return GetFileSize(aFileSize);
}
{
return rv;
pb.ioVolIndex = 0;
// we should check if this call is available
{
#ifdef HAVE_LONG_LONG
#else
#endif
}
return NS_OK;
}
{
{
rv = ResolveAndStat();
//if the file does not exist, does not mean that the parent does not.
return rv;
CInfoPBRec pBlock = {0};
parentFolderSpec.name[0] = 0;
return MacErrorMapper(err);
localFile = new nsLocalFile;
if (!localFile)
return NS_ERROR_OUT_OF_MEMORY;
return rv;
}
else
{
// trim off the last component of the appended path
// construct a new file from our spec + trimmed path
else
if (!localFile)
return NS_ERROR_OUT_OF_MEMORY;
}
return rv;
}
{
if (NS_SUCCEEDED(rv)) {
}
return NS_OK;
}
{
*outIsPackage = PR_FALSE;
// Note: IsDirectory() calls ResolveAndStat() & UpdateCachedCatInfo
if ((!*outIsPackage) && isDir)
{
// Believe it or not, folders ending with ".app" are also considered
// to be packages, even if the top-level folder doesn't have bundle set
{
if (extPtr)
{
{
*outIsPackage = PR_TRUE;
}
}
}
}
return NS_OK;
}
{
*outIsWritable = PR_TRUE;
return NS_OK;
}
{
// is it ever not readable on Mac?
return NS_OK;
}
{
#if TARGET_CARBON
// If we're running under OS X ask LaunchServices if we're executable
if (sRunningOSX)
{
{
{
{
}
}
}
}
else
#endif
{
}
return NS_OK;
}
{
return NS_OK;
}
{
return NS_OK;
}
{
if (sRunningOSX)
{
// on Mac OS X, also follow Unix "convention" where files
// beginning with a period are considered to be hidden
{
{
}
}
}
return NS_OK;
}
{
return NS_OK;
}
{
// Building paths is expensive. If we can get the FSSpecs of
// both (they or their parents exist) just compare the specs.
if (NS_SUCCEEDED(GetFSSpec(&fileSpec)) && inMacFile && NS_SUCCEEDED(inMacFile->GetFSSpec(&inFileSpec)))
else
{
}
return NS_OK;
}
{
/* Note here that we make no attempt to deal with the problem
of folder aliases. Doing a 'Contains' test and dealing with
folder aliases is Hard. Think about it.
*/
*outContains = PR_FALSE;
// NOTE: we're not resolving inFile if it was an alias
// if they are on different volumes, bail
return NS_OK;
// if recur == true, test every parent, otherwise just test the first one
// (yes, recur does not get set in this loop)
do
{
{
*outContains = PR_TRUE;
break;
}
} while (recur);
return NS_OK;
}
{
return rv;
if (!symLink)
return NS_ERROR_FILE_INVALID_PATH;
return GetNativePath(_retval);
}
{
}
return rv;
}
{
return rv;
if (!isDir)
return NS_ERROR_FILE_NOT_DIRECTORY;
return NS_ERROR_OUT_OF_MEMORY;
{
return rv;
}
return NS_OK;
}
{
return rv;
return MacErrorMapper(err);
char* buf = PL_Base64Encode((const char*)*aliasH, bytes, nsnull); // Passing nsnull for dest makes NULL-term string
return NS_OK;
}
{
if (aPersistentDescriptor.IsEmpty())
return NS_ERROR_INVALID_ARG;
char* decodedData = PL_Base64Decode(PromiseFlatCString(aPersistentDescriptor).get(), dataSize, nsnull);
// Cast to an alias record and resolve.
return InitWithFSSpec(&resolvedSpec);
}
#pragma mark -
// a stack-based, exception safe class for an AEDesc
#pragma mark
{
public:
StAEDesc()
{
dataHandle = nil;
}
~StAEDesc()
{
::AEDisposeDesc(this);
}
void Clear()
{
::AEDisposeDesc(this);
dataHandle = nil;
}
private:
// disallow copies and assigns
};
#pragma mark -
{
if (!mCatInfoDirty && !forceUpdate)
return NS_OK;
{
return NS_OK;
}
return MacErrorMapper(err);
}
nsresult nsLocalFile::FindRunningAppBySignature (OSType aAppSig, FSSpec& outSpec, ProcessSerialNumber& outPsn)
{
outPsn.highLongOfPSN = 0;
while (PR_TRUE)
{
if (err == procNotFound) break;
{
return NS_OK;
}
}
return NS_ERROR_FILE_NOT_FOUND; // really process not found
}
{
outPsn.highLongOfPSN = 0;
while (PR_TRUE)
{
if (err == procNotFound) break;
{
return NS_OK;
}
}
return NS_ERROR_FILE_NOT_FOUND; // really process not found
}
{
// get the system volume
long systemFolderDirID;
short sysVRefNum;
short index = 0;
while (true)
{
{
// should we avoid AppleShare volumes?
if (hasDesktopDB)
{
}
}
index++;
}
return NS_OK;
}
{
// for launching a file, we'll use mTargetSpec (which is both a resolved spec and a resolved alias)
#if TARGET_CARBON
if (sRunningOSX)
{ // We're running under Mac OS X, LaunchServices here we come
// First we make sure the LaunchServices routine we want is implemented
{
{
}
}
}
else
#endif
{ // We're running under Mac OS 8.x/9.x, use the Finder Luke
if (NS_SUCCEEDED(rv))
{
errorResult = AECreateDesc(typeProcessSerialNumber, (Ptr)&process, sizeof(process), &myAddressDesc);
if (errorResult == noErr)
{
/* Create the FinderEvent */
errorResult = AECreateAppleEvent(kFinderType, kAEOpenSelection, &myAddressDesc, kAutoGenerateReturnID, kAnyTransactionID,
&aeEvent);
if (errorResult == noErr)
{
/* Create alias for file */
/* Create the file list */
/* create the folder descriptor */
if (errorResult == noErr)
{
if ( errorResult == noErr)
{
/* create the file descriptor and add to aliasList */
errorResult = AECreateDesc(typeAlias, (Ptr)*FileAlias, GetHandleSize((Handle)FileAlias), &listElem);
if (errorResult == noErr)
{
if (errorResult == noErr)
{
/* Add the file alias list to the event */
if (errorResult == noErr)
}
}
}
}
}
}
}
}
return NS_OK;
}
{
return rv;
return rv;
if (NS_SUCCEEDED(rv))
{
errorResult = AECreateDesc(typeProcessSerialNumber, (Ptr)&process, sizeof(process), &myAddressDesc);
if (errorResult == noErr)
{
/* Create the FinderEvent */
#if TARGET_CARBON
// The Finder under OS X uses a different event to reveal
if (sRunningOSX)
errorResult = AECreateAppleEvent(kAEMiscStandards, kAEMakeObjectsVisible, &myAddressDesc, kAutoGenerateReturnID, kAnyTransactionID,
&aeEvent);
else
#endif
errorResult = AECreateAppleEvent(kFinderType, kAERevealSelection, &myAddressDesc, kAutoGenerateReturnID, kAnyTransactionID,
&aeEvent);
if (errorResult == noErr)
{
/* Create the file list */
if (errorResult == noErr)
{
if (errorResult == noErr)
{
#if TARGET_CARBON
// When we're sending the event under OS X the FSSpec must be a keyDirectObject
if (sRunningOSX)
else
#endif
if (errorResult == noErr)
{
errorResult = AESend(&aeEvent, &aeReply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, nil, nil);
if (errorResult == noErr)
}
}
}
}
}
}
return NS_OK;
}
nsresult nsLocalFile::MyLaunchAppWithDoc(const FSSpec& appSpec, const FSSpec* aDocToLoad, PRBool aLaunchInBackground)
{
#if TARGET_CARBON
if (sRunningOSX)
{ // Under Mac OS X we'll use LaunchServices
// First we make sure the LaunchServices routine we want is implemented
{
return NS_ERROR_FAILURE;
if (aDocToLoad)
return NS_ERROR_FAILURE;
if (aLaunchInBackground)
if (aDocToLoad)
{
}
}
}
else
#endif
{ // The old fashioned way for Mac OS 8.x/9.x
err = AECreateAppleEvent(kCoreEventClass, aDocToLoad ? kAEOpenDocuments : kAEOpenApplication, &target,
if (aDocToLoad)
{
}
if (running)
{
if (!aLaunchInBackground)
{
}
}
else
{
if (aLaunchInBackground)
::AEGetDescData(&launchDesc, &launchThis.launchAppParameters, sizeof(launchThis.launchAppParameters));
#else
// no need to lock this handle.
#endif
// let's be nice and wait until it's running
do
{
}
}
return NS_OK;
}
#pragma mark -
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
#pragma mark -
#pragma mark [nsILocalFileMac]
// Implementation of Mac specific finctions from nsILocalFileMac
{
#if TARGET_CARBON
// CFURLGetFSRef can only succeed if the entire path exists.
else
{
if (!parentURL)
return NS_ERROR_FAILURE;
// Get the FSRef from the parent and the FSSpec from that
{
// Get the leaf name of the file and turn it into a string HFS can use.
if (fileNameRef)
{
NULL,
&theEncoding) != noErr)
{
MakeDirty();
}
::CFRelease(fileNameRef);
}
}
}
#endif
return rv;
}
{
#if TARGET_CARBON
else
#endif
return rv;
}
{
MakeDirty();
mTargetSpec = *fileSpec;
mAppendedPath = "";
return NS_OK;
}
{
#if TARGET_CARBON
if (sRunningOSX)
{ // If we're running under OS X use LaunchServices to determine the app
// corresponding to the creator code
{
{
return InitWithFSSpec(&appSpec);
}
// If we get here we didn't find an app
return NS_ERROR_FILE_NOT_FOUND;
}
}
#endif
// is the app running?
if (rv == NS_ERROR_FILE_NOT_FOUND)
{
// we have to look on disk
}
return rv;
// init with the spec here
return InitWithFSSpec(&appSpec);
}
{
#if TARGET_CARBON
{
{
if (*_retval)
return NS_OK;
}
}
else
{
{
CFStringRef pathStrRef = ::CFStringCreateWithCString(NULL, tempPath.get(), kCFStringEncodingMacRoman);
if (!pathStrRef)
return NS_ERROR_FAILURE;
::CFRelease(pathStrRef);
if (*_retval)
return NS_OK;
}
}
#endif
return rv;
}
{
#if TARGET_CARBON
if (NS_SUCCEEDED(rv))
#endif
return rv;
}
{
if (rv == NS_ERROR_FILE_NOT_FOUND)
if (NS_SUCCEEDED(rv))
return NS_OK;
}
{
{
return NS_ERROR_FILE_NOT_FOUND;
}
return NS_OK;
}
{
return NS_ERROR_FILE_NOT_FOUND;
return NS_ERROR_FILE_ACCESS_DENIED;
return NS_OK;
}
{
{
return NS_ERROR_FILE_NOT_FOUND;
}
return NS_OK;
}
{
if (aCreator == CURRENT_PROCESS_CREATOR)
return NS_ERROR_FILE_NOT_FOUND;
return NS_ERROR_FILE_ACCESS_DENIED;
return NS_OK;
}
{
}
{
if (NS_SUCCEEDED(rv))
{
if (NS_SUCCEEDED(rv))
if (NS_SUCCEEDED(rv))
if (NS_SUCCEEDED(rv))
if (NS_SUCCEEDED(rv))
}
return rv;
}
{
long dataSize = 0;
long resSize = 0;
return MacErrorMapper(err);
// For now we've only got 32 bits of file size info
// Combine the size of the resource and data forks
return NS_OK;
}
// this nsLocalFile points to the app. We want to launch it, optionally with the document.
{
// are we launchable?
if (!isExecutable) return NS_ERROR_FILE_EXECUTION_FAILED;
if (macDoc)
{
docSpecPtr = &docSpec;
}
return rv;
}
{
// if aAppToOpenWith is nil, we have to find the app from the creator code
// of the document
if (aAppToOpenWith)
{
if (!appFileMac) return rv;
// is it launchable?
if (!isExecutable) return NS_ERROR_FILE_EXECUTION_FAILED;
}
else
{
// look for one
// just make one on the stack
}
return rv;
}
{
const char *extPtr;
if (!extension)
{
if (!extPtr)
return NS_ERROR_FAILURE;
++extPtr;
}
else
{
if (*extPtr == '.')
++extPtr;
}
if (NS_SUCCEEDED(rv))
{
if (NS_SUCCEEDED(rv))
{
if (NS_SUCCEEDED(rv))
{
if (NS_SUCCEEDED(rv))
}
}
}
return rv;
}
{
// Probably want to make a global list somewhere in the future
// for now, just check for "html" and "htm"
return NS_OK;
}
{
if (sCurrentProcessSignature == 0)
{
psn.highLongOfPSN = 0;
// Try again next time if error
}
if (!didHFSPlusCheck)
{
long response;
}
if (!didOSXCheck)
{
long version;
}
}
#pragma mark -
// Handy dandy utility create routine for something or the other
{
return NS_ERROR_OUT_OF_MEMORY;
return rv;
}
}
return NS_OK;
}
{
return rv;
}
{
return NS_ERROR_OUT_OF_MEMORY;
return rv;
}
return NS_OK;
}
void
{
}
void
{
}