• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/amule/wxWidgets-2.8.12/src/mac/corefoundation/
1/////////////////////////////////////////////////////////////////////////////
2// Name:        mac/corefoundation/utilsexc_base.cpp
3// Purpose:     wxMacExecute
4// Author:      Ryan Norton
5// Modified by:
6// Created:     2005-06-21
7// RCS-ID:      $Id: utilsexc_base.cpp 40283 2006-07-24 18:01:39Z VZ $
8// Copyright:   (c) Ryan Norton
9// Licence:     wxWindows licence
10// Notes:       Source was originally in utilsexc_cf.cpp,1.6 then moved
11//              to totally unrelated hid.cpp,1.8.
12/////////////////////////////////////////////////////////////////////////////
13
14//===========================================================================
15//  DECLARATIONS
16//===========================================================================
17
18//---------------------------------------------------------------------------
19// Pre-compiled header stuff
20//---------------------------------------------------------------------------
21
22// For compilers that support precompilation, includes "wx.h".
23#include "wx/wxprec.h"
24
25// WX includes
26#ifndef WX_PRECOMP
27    #include "wx/string.h"
28    #include "wx/log.h"
29    #include "wx/intl.h"
30    #include "wx/utils.h"
31#endif // WX_PRECOMP
32
33// Mac Includes
34#include <CoreFoundation/CoreFoundation.h>
35#include <ApplicationServices/ApplicationServices.h>
36
37// More WX Includes
38#include "wx/filename.h"
39#include "wx/mac/corefoundation/cfstring.h"
40
41// Default path style
42#ifdef __WXMAC_OSX__
43#define kDefaultPathStyle kCFURLPOSIXPathStyle
44#else
45#define kDefaultPathStyle kCFURLHFSPathStyle
46#endif
47
48//===========================================================================
49//  IMPLEMENTATION
50//===========================================================================
51
52//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
53//
54//    wxMacExecute
55//
56// argv is the command line split up, with the application path first
57// flags are the flags from wxExecute
58// process is the process passed from wxExecute for pipe streams etc.
59// returns -1 on error for wxEXEC_SYNC and 0 on error for wxEXEC_ASYNC
60//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
61long wxMacExecute(wxChar **argv,
62               int flags,
63               wxProcess *process)
64{
65    // Semi-macros used for return value of wxMacExecute
66    const long errorCode = ((flags & wxEXEC_SYNC) ? -1 : 0);
67    const long successCode = ((flags & wxEXEC_SYNC) ? 0 : -1); // fake PID
68
69    // Obtains the number of arguments for determining the size of
70    // the CFArray used to hold them
71    CFIndex cfiCount = 0;
72    for(wxChar** argvcopy = argv; *argvcopy != NULL ; ++argvcopy)
73    {
74        ++cfiCount;
75    }
76
77    // If there is not a single argument then there is no application
78    // to launch
79    if(cfiCount == 0)
80    {
81        wxLogDebug(wxT("wxMacExecute No file to launch!"));
82        return errorCode ;
83    }
84
85    // Path to bundle
86    wxString path = *argv++;
87
88    // Create a CFURL for the application path
89    // Created this way because we are opening a bundle which is a directory
90    CFURLRef cfurlApp =
91        CFURLCreateWithFileSystemPath(
92            kCFAllocatorDefault,
93            wxMacCFStringHolder(path),
94            kDefaultPathStyle,
95            true); //false == not a directory
96
97    // Check for error from the CFURL
98    if(!cfurlApp)
99    {
100        wxLogDebug(wxT("wxMacExecute Can't open path: %s"), path.c_str());
101        return errorCode ;
102    }
103
104    // Create a CFBundle from the CFURL created earlier
105    CFBundleRef cfbApp = CFBundleCreate(kCFAllocatorDefault, cfurlApp);
106
107    // Check to see if CFBundleCreate returned an error,
108    // and if it did this was an invalid bundle or not a bundle
109    // at all (maybe a simple directory etc.)
110    if(!cfbApp)
111    {
112        wxLogDebug(wxT("wxMacExecute Bad bundle: %s"), path.c_str());
113        CFRelease(cfurlApp);
114        return errorCode ;
115    }
116
117    // Get the bundle type and make sure its an 'APPL' bundle
118    // Otherwise we're dealing with something else here...
119    UInt32 dwBundleType, dwBundleCreator;
120    CFBundleGetPackageInfo(cfbApp, &dwBundleType, &dwBundleCreator);
121    if(dwBundleType != 'APPL')
122    {
123        wxLogDebug(wxT("wxMacExecute Not an APPL bundle: %s"), path.c_str());
124        CFRelease(cfbApp);
125        CFRelease(cfurlApp);
126        return errorCode ;
127    }
128
129    // Create a CFArray for dealing with the command line
130    // arguments to the bundle
131    CFMutableArrayRef cfaFiles = CFArrayCreateMutable(kCFAllocatorDefault,
132                                    cfiCount-1, &kCFTypeArrayCallBacks);
133    if(!cfaFiles) //This should never happen
134    {
135        wxLogDebug(wxT("wxMacExecute Could not create CFMutableArray"));
136        CFRelease(cfbApp);
137        CFRelease(cfurlApp);
138        return errorCode ;
139    }
140
141    // Loop through command line arguments to the bundle,
142    // turn them into CFURLs and then put them in cfaFiles
143    // For use to launch services call
144        for( ; *argv != NULL ; ++argv)
145        {
146        // Check for '<' as this will ring true for
147        // CFURLCreateWithString but is generally not considered
148        // typical on mac but is usually passed here from wxExecute
149        if (wxStrcmp(*argv, wxT("<")) == 0)
150            continue;
151
152
153        CFURLRef cfurlCurrentFile;    // CFURL to hold file path
154        wxFileName argfn(*argv);     // Filename for path
155
156        if(argfn.DirExists())
157        {
158            // First, try creating as a directory
159            cfurlCurrentFile = CFURLCreateWithFileSystemPath(
160                                kCFAllocatorDefault,
161                                wxMacCFStringHolder(*argv),
162                                kDefaultPathStyle,
163                                true); //true == directory
164        }
165        else if(argfn.FileExists())
166        {
167            // And if it isn't a directory try creating it
168            // as a regular file
169            cfurlCurrentFile = CFURLCreateWithFileSystemPath(
170                                kCFAllocatorDefault,
171                                wxMacCFStringHolder(*argv),
172                                kDefaultPathStyle,
173                                false); //false == regular file
174        }
175        else
176        {
177            // Argument did not refer to
178            // an entry in the local filesystem,
179            // so try creating it through CFURLCreateWithString
180            cfurlCurrentFile = CFURLCreateWithString(
181                                kCFAllocatorDefault,
182                                wxMacCFStringHolder(*argv),
183                                NULL);
184        }
185
186        // Continue in the loop if the CFURL could not be created
187        if(!cfurlCurrentFile)
188        {
189            wxLogDebug(
190                wxT("wxMacExecute Could not create CFURL for argument:%s"),
191                *argv);
192            continue;
193        }
194
195        // Add the valid CFURL to the argument array and then
196        // release it as the CFArray adds a ref count to it
197            CFArrayAppendValue(
198                cfaFiles,
199                cfurlCurrentFile
200                            );
201            CFRelease(cfurlCurrentFile); // array has retained it
202        }
203
204    // Create a LSLaunchURLSpec for use with LSOpenFromURLSpec
205    // Note that there are several flag options (launchFlags) such
206    // as kLSLaunchDontSwitch etc. and maybe we could be more
207    // picky about the flags we choose
208    LSLaunchURLSpec launchspec;
209    launchspec.appURL = cfurlApp;
210    launchspec.itemURLs = cfaFiles;
211    launchspec.passThruParams = NULL; //AEDesc*
212    launchspec.launchFlags = kLSLaunchDefaults;
213    launchspec.asyncRefCon = NULL;
214
215    // Finally, call LSOpenFromURL spec with our arguments
216    // 2nd parameter is a pointer to a CFURL that gets
217    // the actual path launched by the function
218    OSStatus status = LSOpenFromURLSpec(&launchspec, NULL);
219
220    // Cleanup corefoundation references
221    CFRelease(cfbApp);
222    CFRelease(cfurlApp);
223    CFRelease(cfaFiles);
224
225    // Check for error from LSOpenFromURLSpec
226    if(status != noErr)
227    {
228        wxLogDebug(wxT("wxMacExecute LSOpenFromURLSpec Error: %d"),
229                   (int)status);
230        return errorCode ;
231    }
232
233    // No error from LSOpenFromURLSpec, so app was launched
234    return successCode;
235}
236
237