示例#1
0
  static OSErr
  FT_FSPathMakeRes( const UInt8*  pathname,
                    short*        res )
  {

#if HAVE_FSREF

    OSErr  err;
    FSRef  ref;


    if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )
      return FT_Err_Cannot_Open_Resource;

    /* at present, no support for dfont format */
    err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res );
    if ( noErr == err )
      return err;

    /* fallback to original resource-fork font */
    *res = FSOpenResFile( &ref, fsRdPerm );
    err  = ResError();

#else

    OSErr   err;
    FSSpec  spec;


    if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) )
      return FT_Err_Cannot_Open_Resource;

    /* at present, no support for dfont format without FSRef */
    /* (see above), try original resource-fork font          */
    *res = FSpOpenResFile( &spec, fsRdPerm );
    err  = ResError();

#endif /* HAVE_FSREF */

    return err;
  }
示例#2
0
文件: dirmac.cpp 项目: Duion/Torsion
wxDirData::wxDirData(const wxString& dirname)
         : m_dirname(dirname)
{
    m_ok = false;

    OSErr err;

    // throw away the trailing slashes
    size_t n = m_dirname.length();
    wxCHECK_RET( n, _T("empty dir name in wxDir") );

    while ( n > 0 && wxIsPathSeparator(m_dirname[--n]) )
        ;

    m_dirname.Truncate(n + 1);

#ifdef __DARWIN__
    FSRef theRef;

    // get the FSRef associated with the POSIX path
    err = FSPathMakeRef((const UInt8 *) m_dirname.c_str(), &theRef, NULL);
    FSGetVRefNum(&theRef, &(m_CPB.hFileInfo.ioVRefNum));

    err = FSGetNodeID( &theRef , &m_dirId , &m_isDir ) ;
#else
    FSSpec fsspec ;

    wxMacFilename2FSSpec( m_dirname , &fsspec ) ;
    m_CPB.hFileInfo.ioVRefNum = fsspec.vRefNum ;

    err = FSpGetDirectoryID( &fsspec , &m_dirId , &m_isDir ) ;
#endif
    //wxASSERT_MSG( (err == noErr) || (err == nsvErr) , wxT("Error accessing directory " + m_dirname)) ;
    if ( (err == noErr) || (err == nsvErr))
        m_ok = true;
    else
        wxLogError(wxString(wxT("Error accessing directory ")) + m_dirname);

    m_CPB.hFileInfo.ioNamePtr = m_name ;
    m_index = 0 ;
}
示例#3
0
char* promptForFolder(const char *prompt, const char *defaultPath, char* folderPath, int folderPathLen)
{
	char		path[PATH_MAX];
	OSStatus	err;
	Boolean		isDirectory;
	int			len;
	FSRef		ref;
	
	/* Display the prompt. */
	if (prompt == NULL)
		prompt = "Please enter the path to a folder:";
	printf("%s ", prompt);
	if (defaultPath != NULL)
		printf("[%s] ",defaultPath);
	fflush(stdout);
	
	/* Get user input, and trim trailing newlines. */
	fgets(path,sizeof(path),stdin);
	for (len = strlen(path); len > 0 && path[len-1] == '\n';)
		path[--len] = 0;
	if (path[0] == 0)
		strcpy(path,defaultPath);
	
	/* Expand magic characters just like a shell (mostly so ~ will work) */
	expandPathname(path);
	
	/* Convert the path into an FSRef, which is what the burn engine needs. */
	err = FSPathMakeRef((const UInt8*)path,&ref,&isDirectory);
	if (err != noErr)
	{
		printf("Bad path. Aborting. (%d)\n", (int)err);
		exit(1);
	}
	if (!isDirectory)
	{
		printf("That's a file, not a directory!  Aborting.\n");
		exit(1);
	}
	
	return strncpy(folderPath, path, folderPathLen);
}
示例#4
0
bool 
isLink(const bfs::path& path)
{
    if (isSymlink(path)) {
        return true;
    }

#ifdef MACOSX
    // aliases appear as regular files
    if (isRegularFile(path)) {
        FSRef ref;
        if (FSPathMakeRef((const UInt8*)path.c_str(), &ref, NULL) == noErr) {
            Boolean isAlias = false, isFolder = false;
            if (FSIsAliasFile(&ref, &isAlias, &isFolder) == noErr) {
                return isAlias;
            }
        }
    }
#endif
    return false;	
}
示例#5
0
文件: vsthost.cpp 项目: Angeldude/pd
OSStatus FSPathMakeFSSpec(const UInt8 *path,FSSpec *spec,Boolean *isDirectory)  /* can be NULL */
{
    OSStatus  result;
    FSRef    ref;

    /* check parameters */
    require_action(NULL != spec, BadParameter, result = paramErr);

    /* convert the POSIX path to an FSRef */
    result = FSPathMakeRef(path, &ref, isDirectory);
    require_noerr(result, FSPathMakeRef);

    /* and then convert the FSRef to an FSSpec */
    result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
    require_noerr(result, FSGetCatalogInfo);
  
FSGetCatalogInfo:
FSPathMakeRef:
BadParameter:
    return result;
}
void		CResourceFile::LoadFile( const std::string& fpath )
{
	FSRef		fileRef;
	mResRefNum = -1;
	
	OSStatus	resErr = FSPathMakeRef( (const UInt8*) fpath.c_str(), &fileRef, NULL );
	if( resErr == noErr )
	{
		mResRefNum = FSOpenResFile( &fileRef, fsRdPerm );
		if( mResRefNum < 0 )
		{
			fprintf( stderr, "Warning: No Mac resource fork to import.\n" );
			resErr = fnfErr;
		}
	}
	else
	{
		fprintf( stderr, "Error: Error %d locating input file's resource fork.\n", (int)resErr );
		mResRefNum = -1;
	}
}
示例#7
0
AudioFileReader::AudioFileReader(const char* filePath)
    : m_data(0)
    , m_dataSize(0)
    , m_filePath(filePath)
    , m_audioFileID(0)
    , m_extAudioFileRef(0)
{
    FSRef fsref;
    OSStatus result = FSPathMakeRef((UInt8*)filePath, &fsref, 0);
    if (result != noErr)
        return;

    CFURLRef urlRef = CFURLCreateFromFSRef(0, &fsref);
    if (!urlRef)
        return;

    ExtAudioFileOpenURL(urlRef, &m_extAudioFileRef);

    if (urlRef)
        CFRelease(urlRef);
}
示例#8
0
/* Finish the current audio track. */
int PortBurn_EndTrack(void *handle)
{
   PBHandle *h = (PBHandle *)handle;
   DRAudioTrackRef track;
   Boolean isDirectory;
   const char *filename;
   FSRef fsref;
   int index;

   if (!h)
      return pbErrNoHandle;

   if (!h->staging)
      return pbErrMustCallStartStaging;

   if (0 != PortBurn_EndStagingTrack(h->staging))
      return pbErrCannotStageTrack;

   index = PortBurn_GetNumStagedTracks(h->staging);
   if (index <= 0)
      return pbErrCannotStageTrack;

   filename = PortBurn_GetStagedFilename(h->staging, index - 1);
   printf("Filename: '%s'\n", filename);
   h->err = FSPathMakeRef((const UInt8*)filename, &fsref, &isDirectory);
   if (h->err != noErr)
      return pbErrCannotAccessStagedFile;
   if (isDirectory)
      return pbErrCannotAccessStagedFile;

   track = DRAudioTrackCreate(&fsref);

   CFArrayAppendValue(h->trackArray, track);
   CFRelease(track);

   if (track)
      return pbSuccess;
   else
      return pbErrCannotUseStagedFileForBurning;
}
示例#9
0
文件: trash.c 项目: ccpgames/wine
BOOL TRASH_CanTrashFile(LPCWSTR wszPath)
{
    char *unix_path;
    OSStatus status;
    FSRef ref;
    FSCatalogInfo catalogInfo;

    TRACE("(%s)\n", debugstr_w(wszPath));
    if (!(unix_path = wine_get_unix_file_name(wszPath)))
        return FALSE;

    status = FSPathMakeRef((UInt8*)unix_path, &ref, NULL);
    heap_free(unix_path);
    if (status == noErr)
        status = FSGetCatalogInfo(&ref, kFSCatInfoVolume, &catalogInfo, NULL,
                                  NULL, NULL);
    if (status == noErr)
        status = FSFindFolder(catalogInfo.volume, kTrashFolderType,
                              kCreateFolder, &ref);

    return (status == noErr);
}
示例#10
0
int wd_apple_resolve_alias(char *dst, char *src, size_t size) {
	FSRef		fsPath;
	Boolean		isDir, isAlias;
	
	strlcpy(dst, src, size);
	
	if(!wd_chroot) {
		if(FSPathMakeRef(src, &fsPath, NULL) != 0)
			return -1;
			
		if(FSIsAliasFile(&fsPath, &isAlias, &isDir) != 0)
			return -1;
	
		if(FSResolveAliasFile(&fsPath, true, &isDir, &isAlias) != 0)
			return -1;
	
		if(FSRefMakePath(&fsPath, dst, size) != 0)
			return -1;
	}

	return 1;
}
示例#11
0
std::unique_ptr<ImportFileHandle> QTImportPlugin::Open(const wxString & Filename)
{
   OSErr err;
   FSRef inRef;
   Movie theMovie = NULL;
   Handle dataRef = NULL;
   OSType dataRefType = 0;
   short resID = 0;

#if defined(__WXMAC__)
   err = wxMacPathToFSRef(Filename, &inRef);
#else
   // LLL:  This will not work for pathnames with Unicode characters...find
   //       another method.
   err = FSPathMakeRef((UInt8 *)OSFILENAME(Filename), &inRef, NULL);
#endif

   if (err != noErr) {
      return nullptr;
   }

   err = QTNewDataReferenceFromFSRef(&inRef, 0, &dataRef, &dataRefType);
   if (err != noErr) {
      return nullptr;
   }

   // instantiate the movie
   err = NewMovieFromDataRef(&theMovie,
                             newMovieActive | newMovieDontAskUnresolvedDataRefs,
                             &resID,
                             dataRef,
                             dataRefType);
   DisposeHandle(dataRef);
   if (err != noErr) {
      return nullptr;
   }

   return std::make_unique<QTImportFileHandle>(Filename, theMovie);
}
示例#12
0
文件: ftmac.c 项目: 32767/libgdx
  static OSErr
  FT_FSPathMakeRes( const UInt8*    pathname,
                    ResFileRefNum*  res )
  {
    OSErr  err;
    FSRef  ref;


    if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )
      return FT_Err_Cannot_Open_Resource;

    /* at present, no support for dfont format */
    err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res );
    if ( noErr == err )
      return err;

    /* fallback to original resource-fork font */
    *res = FSOpenResFile( &ref, fsRdPerm );
    err  = ResError();

    return err;
  }
示例#13
0
/*AudioFile::AudioFile( shared_ptr<IStream> aStream ) : mStream( aStream )
{
	setup();
}*/
AudioFile::AudioFile( const std::string &aFilePath )
{
#if defined( FLI_MAC )
	FSRef fsref;
	OSStatus fileRefError = FSPathMakeRef( (const UInt8 *)aFilePath.c_str(), &fsref, NULL );
	if( fileRefError ) {
		//handle error
		std::cout << "Input file not found" << std::endl;
		return;
	}
	
	OSStatus audioFileOpenError = AudioFileOpen(&fsref, fsRdPerm, 0, &mNativeFileRef);
	if( audioFileOpenError ) {
		//handle error
		std::cout << "AudioFileOpen failed" << std::endl;
		return;
	}
	
	loadHeader();
	load();
#endif
}
示例#14
0
文件: main.c 项目: c0sco/lookupid
int main (int argc, const char *argv[]) {
	SInt32 fileID;
	FSRef ref, volRef;
	FSCatalogInfo volCatInfo;
	OSErr result;
	unsigned char pathName[255];

	// Exit if anything more or less than two arguments are passed in
	if (argc != 3) {
		printf("Usage: %s <HFS ID> <volume mount point>\n", argv[0]);
		return 0;
	}

	result = FSPathMakeRef(argv[2], &volRef, NULL);
	if (result != noErr) {
		printf("Error %d\n", result);
		return 10;
	}
	result = FSGetCatalogInfo(&volRef, kFSCatInfoVolume, &volCatInfo, NULL, NULL, NULL);
	if (result != noErr) {
		printf("Error %d\n", result);
		return 10;
	}

	fileID = atoi(argv[1]);
	result = FSResolveFileIDRef(volCatInfo.volume, fileID, &ref);
	if (result != noErr) {
		printf("Error %d\n", result);
		return 10;
	}
	result = FSRefMakePath(&ref, pathName, sizeof(pathName));
	if (result != noErr) {
		printf("Error %d\n", result);
		return 10;
	}

	printf("%s\n", pathName);
	return 0;
}
示例#15
0
static OSErr myFSCreateResFile(const char *path, OSType creator, OSType fileType, FSRef *outRef) {
  int fd = open(path, O_CREAT | O_WRONLY, 0666);
  if (fd == -1) {
    perror("opening destination:");
    return bdNamErr;
  }
  close(fd);

  FSRef ref;

  OSErr err = FSPathMakeRef((const UInt8*)path, &ref, NULL);
  if (err != noErr)
    return err;

  HFSUniStr255 rname;
  FSGetResourceForkName(&rname);

  err = FSCreateResourceFork(&ref, rname.length, rname.unicode, 0);
  if (err != noErr)
    return err;

  FInfo finfo;

  err = FSGetFInfo(&ref, &finfo);
  if (err != noErr)
    return err;

  finfo.fdCreator = creator;
  finfo.fdType = fileType;

  err = FSSetFInfo(&ref, &finfo);
  if (err != noErr)
      return err;

  *outRef = ref;

  return noErr;
}
示例#16
0
/********** HELPER FUNCTIONS ***********/
static const char *GetSpecialPathName(const char *Path)
{
    if(GetProductIsAppBundle(cur_info))
    {
        FSRef Ref;
        HFSUniStr255 SpecialPathHFS;

        FSPathMakeRef(Path, &Ref, NULL);
        FSGetCatalogInfo(&Ref, kFSCatInfoNone, NULL, &SpecialPathHFS, NULL, NULL);
        CFStringRef cfs = CFStringCreateWithCharacters(kCFAllocatorDefault, SpecialPathHFS.unicode, SpecialPathHFS.length);
        CFStringGetCString(cfs, SpecialPath, 1024, kCFStringEncodingASCII);
        CFRelease(cfs);
        return SpecialPath;
        /*//  Otherwise, it'll show /Users/joeshmo/Desktop.
        if(strstr(Path, DesktopName) != NULL)
            return DesktopName;
        else if(strstr(Path, DocumentsName) != NULL)
            return DocumentsName;
        else if(strstr(Path, ApplicationsName) != NULL)
            return ApplicationsName;*/
    }
    return Path;
}
//static
pascal void LLFilePickerBase::doNavCallbackEvent(NavEventCallbackMessage callBackSelector,
                                         NavCBRecPtr callBackParms, void* callBackUD)
{
    switch(callBackSelector)
    {
        case kNavCBStart:
        {
			LLFilePickerBase* picker = reinterpret_cast<LLFilePickerBase*>(callBackUD);
            if (picker->getFolder().empty()) break;

            OSStatus error = noErr;
            AEDesc theLocation = {typeNull, NULL};
            FSSpec outFSSpec;

            //Convert string to a FSSpec
            FSRef myFSRef;

            const char* folder = picker->getFolder().c_str();

            error = FSPathMakeRef ((UInt8*)folder,  &myFSRef,   NULL);

            if (error != noErr) break;

            error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL);

            if (error != noErr) break;

            error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation);

            if (error != noErr) break;

            error = NavCustomControl(callBackParms->context,
                            kNavCtlSetLocation, (void*)&theLocation);

        }
    }
}
示例#18
0
static bool _q_isMacHidden(const QString &path)
{
    OSErr err = noErr;

    FSRef fsRef;

#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
        err = FSPathMakeRefWithOptions(reinterpret_cast<const UInt8 *>(QFile::encodeName(QDir::cleanPath(path)).constData()),
                                        kFSPathMakeRefDoNotFollowLeafSymlink, &fsRef, 0);
    } else
#endif
    {
        QFileInfo fi(path);
        FSRef parentRef;
        err = FSPathMakeRef(reinterpret_cast<const UInt8 *>(fi.absoluteDir().absolutePath().toUtf8().constData()),
                            &parentRef, 0);
        if (err == noErr) {
            QString fileName = fi.fileName();
            err = FSMakeFSRefUnicode(&parentRef, fileName.length(),
                                     reinterpret_cast<const UniChar *>(fileName.unicode()),
                                     kTextEncodingUnknown, &fsRef);
        }
    }
    if (err != noErr)
        return false;

    FSCatalogInfo catInfo;
    err = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &catInfo, NULL, NULL, NULL);
    if (err != noErr)
        return false;

    FileInfo * const fileInfo = reinterpret_cast<FileInfo*>(&catInfo.finderInfo);
    bool result = (fileInfo->finderFlags & kIsInvisible);
    return result;
}
示例#19
0
static void show_macos_type(const char *filename)
{
  int err;
  FSRef ref;
  FSCatalogInfo info;
  FInfo *finfo;

  err = FSPathMakeRef(filename, &ref, NULL);
  if (err == 0) {
    err = FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo,
			   &info, NULL, NULL, NULL);
  }

  if (err == 0) {
    finfo = (FInfo *)(info.finderInfo);
    if (finfo->fdType != 0 || finfo->fdCreator != 0) {
      char typecode[5], creatorcode[5], s1[256], s2[256];

      memcpy(typecode, &finfo->fdType, 4);
      typecode[4] = 0;
      format_ascii(typecode, s1);

      memcpy(creatorcode, &finfo->fdCreator, 4);
      creatorcode[4] = 0;
      format_ascii(creatorcode, s2);

      print_line(0, "Type code \"%s\", creator code \"%s\"",
		 s1, s2);
    } else {
      print_line(0, "No type and creator code");
    }
  }
  if (err) {
    print_line(0, "Type and creator code unknown (error %d)", err);
  }
}
示例#20
0
  /* Return the file type for given pathname */
  static OSType
  get_file_type_from_path( const UInt8*  pathname )
  {

#if HAVE_FSREF

    FSRef          ref;
    FSCatalogInfo  info;


    if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )
      return ( OSType ) 0;

    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info,
                                    NULL, NULL, NULL ) )
      return ( OSType ) 0;

    return ((FInfo *)(info.finderInfo))->fdType;

#else

    FSSpec  spec;
    FInfo   finfo;


    if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) )
      return ( OSType ) 0;

    if ( noErr != FSpGetFInfo( &spec, &finfo ) )
      return ( OSType ) 0;

    return finfo.fdType;

#endif /* HAVE_FSREF */

  }
示例#21
0
static OSStatus FindCustomFolder (FSRef *folderRef, char *folderPath, const char *folderName)
{
	OSStatus	err;
	CFStringRef	fstr;
	FSRef		pref;
	UniChar		buffer[PATH_MAX + 1];
	char		s[PATH_MAX + 1];

	if (saveFolderPath == NULL)
		return (-1);

	err = CFStringGetCString(saveFolderPath, s, PATH_MAX, kCFStringEncodingUTF8) ? noErr : -1;
	if (err == noErr)
		err = FSPathMakeRef((unsigned char *) s, &pref, NULL);

	if (err)
		return (err);

	fstr = CFStringCreateWithCString(kCFAllocatorDefault, folderName, CFStringGetSystemEncoding());
	CFStringGetCharacters(fstr, CFRangeMake(0, CFStringGetLength(fstr)), buffer);

	err = FSMakeFSRefUnicode(&pref, CFStringGetLength(fstr), buffer, kTextEncodingUnicodeDefault, folderRef);
	if (err == dirNFErr || err == fnfErr)
	{
		err = FSCreateDirectoryUnicode(&pref, CFStringGetLength(fstr), buffer, kFSCatInfoNone, NULL, folderRef, NULL, NULL);
		if (err == noErr)
			AddFolderIcon(folderRef, folderName);
	}

	if (err == noErr)
		err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX);

	CFRelease(fstr);

	return (err);
}
示例#22
0
void nglDataFilesObject::SetDragItemFlavorData(DragRef dragRef, DragItemRef& itemRef, FlavorType flavorType)
{
  OSErr err = noErr;
  nglString file;
  std::list<DragItemRef>::iterator iRef = mItemRefs.begin();
  for (std::list<nglString>::const_iterator i = GetFiles().begin(); i != GetFiles().end() && iRef != mItemRefs.end(); ++i, ++iRef)
  {
    if (itemRef == *iRef)
    {
      HFSFlavor hfsInfo;
      FSRef fileRef;
      int32 start = 0;
      int32 len = 1023;
      char str[1024];
      memset(str, 0, 1024);
      i->Export(start, str, len, eUTF8);
      err = FSPathMakeRef((const UInt8*)str, &fileRef, NULL);
      NGL_ASSERT(!err);
      
      FSCatalogInfo catInfo;
      err = FSGetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &catInfo, NULL, &(hfsInfo.fileSpec), NULL);
      NGL_ASSERT(!err);
      
      FileInfo* finfo = (FileInfo*) &catInfo.finderInfo;
      hfsInfo.fdFlags = finfo->finderFlags;
      hfsInfo.fileType = finfo->fileType;
      hfsInfo.fileCreator = finfo->fileCreator;
        
      err = ::SetDragItemFlavorData(dragRef, itemRef, kDragFlavorTypeHFS, &hfsInfo, sizeof (hfsInfo), 0);
      NGL_ASSERT(!err);
        
      //NGL_OUT("Adding file to drag data, itemRef is %d: %s\n", itemRef, (*i).GetChars());
      return;
    }
  }
}
示例#23
0
//static
pascal void LLDirPicker::doNavCallbackEvent(NavEventCallbackMessage callBackSelector,
										 NavCBRecPtr callBackParms, void* callBackUD)
{
	switch(callBackSelector)
	{
		case kNavCBStart:
		{
			if (!sInstance.mFileName) break;
 
			OSStatus error = noErr; 
			AEDesc theLocation = {typeNull, NULL};
			FSSpec outFSSpec;
			
			//Convert string to a FSSpec
			FSRef myFSRef;
			
			const char* filename=sInstance.mFileName->c_str();
			
			error = FSPathMakeRef ((UInt8*)filename,	&myFSRef, 	NULL); 
			
			if (error != noErr) break;

			error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL);

			if (error != noErr) break;
	
			error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation);

			if (error != noErr) break;

			error = NavCustomControl(callBackParms->context,
							kNavCtlSetLocation, (void*)&theLocation);

		}
	}
}
示例#24
0
bool path_to_fsspec(const char *p_filename, FSSpec* r_fsspec)
{
	bool t_success;
	t_success = true;
	
	FSRef t_ref;
	if (t_success)
	{
		OSStatus t_status;
		t_status = FSPathMakeRef((const UInt8 *)p_filename, &t_ref, NULL);
		if (t_status != noErr)
			t_success = false;
	}
	
	if (t_success)
	{
		OSErr t_error;
		t_error = FSGetCatalogInfo(&t_ref, kFSCatInfoNone, NULL, NULL, r_fsspec, NULL);
		if (t_error != noErr)
			t_success = false;
	}
	
	return t_success;
}
示例#25
0
文件: ftmac.c 项目: dikerex/theqvd
  /* Given a pathname, fill in a file spec. */
  static int
  file_spec_from_path( const char*  pathname,
                       FSSpec*      spec )
  {
#if TARGET_API_MAC_CARBON

    OSErr  e;
    FSRef  ref;


    e = FSPathMakeRef( (UInt8 *)pathname, &ref, false /* not a directory */ );
    if ( e == noErr )
      e = FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, spec, NULL );

    return ( e == noErr ) ? 0 : (-1);

#else

    Str255    p_path;
    FT_ULong  path_len;


    /* convert path to a pascal string */
    path_len = ft_strlen( pathname );
    if ( path_len > 255 )
      return -1;
    p_path[0] = (unsigned char)path_len;
    ft_strncpy( (char*)p_path + 1, pathname, path_len );

    if ( FSMakeFSSpec( 0, 0, p_path, spec ) != noErr )
      return -1;
    else
      return 0;

#endif
  }
示例#26
0
void filecontainer_doopen(t_filecontainer *x, t_symbol *arg)
{
    t_atom			a[4];
    int				err = 0;
    char			filename[256];
    short			path;
    t_fourcc		outtype = 0;
    t_fourcc		type = 'cO0p';
#ifdef MAC_VERSION
    char			*temppath;
    FSRef			ref;
    Boolean			isDir;
    FSCatalogInfo	catalogInfo;
#else // WIN_VERSION
    char			temppath[512];
#endif
    char			fullpath[512];
    t_object		*result = NULL;
    t_object		*result2 = NULL;
    char			**record = NULL;		// sqlite records
    char			**record2 = NULL;		// sqlite records
    t_filehandle	file_handle;
    t_ptr_size		len = 0;
    char			*blob;
    char			sql[512];

    if(!arg || !arg->s_name[0]) {
        if(open_dialog(filename, &path, &outtype, NULL, -1))			// Returns 0 if successful
            return;
    }
    else {
        t_fourcc typelist[1];
        typelist[0] = 'cO0p';
        strcpy(filename, arg->s_name);
        path = 0;
        locatefile_extended(filename, &path, &type, typelist, 0);
    }
    path_topotentialname(path, filename, fullpath, 0);
#ifdef MAC_VERSION
    temppath = strchr(fullpath, ':');
    temppath += 1;
#else // WIN_VERSION
    path_nameconform(fullpath, temppath, PATH_STYLE_NATIVE_WIN, PATH_TYPE_ABSOLUTE);
#endif
    x->name = gensym(temppath);

    // Create our temp folder for extracted files
    filecontainer_gettemppath(x);

    // Create the SQLite instance
    atom_setsym(&a[0], gensym("@rambased"));
    atom_setlong(&a[1], 0);
    atom_setsym(&a[2], gensym("@db"));
    atom_setsym(&a[3], x->name);
    x->sqlite = object_new_typed(CLASS_NOBOX, _sym_sqlite, 4, a);

    // Operate on the open DB
    if(x->sqlite) {
        object_method(x->sqlite, ps_starttransaction);
        object_method(x->sqlite, _sym_execstring, TABLEDEF_FILES, NULL);
        object_method(x->sqlite, _sym_execstring, TABLEDEF_ATTRS, NULL);

        object_method(x->sqlite, _sym_execstring, "UPDATE files SET valid = 1", NULL);
        object_method(x->sqlite, _sym_execstring, "SELECT file_id, filename, moddate FROM files", &result);
        while(record = (char **)object_method(result, _sym_nextrecord)) {
            // Here we check for the optional 'platform' attr for this file.
            // If a flag exists for the other platform, but not for the current platform, then we ignore this file.
#ifdef MAC_VERSION
            sprintf(sql, "SELECT file_id_ext FROM attrs \
							WHERE attr_name = 'platform' AND attr_value = 'windows' AND file_id_ext = %s ", record[0]);
            object_method(x->sqlite, _sym_execstring, sql, &result2);
            record2 = (char **)object_method(result2, _sym_nextrecord);
            if(record2) {
                sprintf(sql, "SELECT file_id_ext FROM attrs \
								WHERE attr_name = 'platform' AND attr_value = 'mac' AND file_id_ext = %s ", record[0]);
                object_method(x->sqlite, _sym_execstring, sql, &result2);
                record2 = (char **)object_method(result2, _sym_nextrecord);
                if(!record2) {
                    sprintf(sql, "UPDATE files SET valid = 0 WHERE file_id = %s ", record[0]);
                    object_method(x->sqlite, _sym_execstring, sql, NULL);
                    continue;
                }
            }
#else // WIN_VERSION
            snprintf(sql, 512, "SELECT file_id_ext FROM attrs \
							WHERE attr_name = 'platform' AND attr_value = 'mac' AND file_id_ext = %s ", record[0]);
            object_method(x->sqlite, _sym_execstring, sql, &result2);
            record2 = (char **)object_method(result2, _sym_nextrecord);
            if(record2) {
                snprintf(sql, 512, "SELECT file_id_ext FROM attrs \
								WHERE attr_name = 'platform' AND attr_value = 'windows' AND file_id_ext = %s ", record[0]);
                object_method(x->sqlite, _sym_execstring, sql, &result2);
                record2 = (char **)object_method(result2, _sym_nextrecord);
                if(!record2) {
                    snprintf(sql, 512, "UPDATE files SET valid = 0 WHERE file_id = %s ", record[0]);
                    object_method(x->sqlite, _sym_execstring, sql, NULL);
                    continue;
                }
            }
#endif
            // At this point we have a file (record[0]), and we have determined that it is indeed a file we want to cache
            // So cache it to a new file in our temp path
            err = path_createsysfile(record[1], x->temp_path, type, &file_handle);
            if(err) {																// Handle any errors that occur
                object_error((t_object *)x, "%s - error %d creating file", filename, err);
            }
            else {
                snprintf(sql, 512, "SELECT content FROM files WHERE file_id = %s", record[0]);
                object_method(x->sqlite, ps_getblob, sql, &blob, &len);
                err = sysfile_write(file_handle, &len, blob);
                if(err) {
                    object_error((t_object *)x, "sysfile_write error (%d)", err);
                }
            }
            err = sysfile_seteof(file_handle, len);
            if(err) {
                object_error((t_object *)x, "%s - error %d setting EOF", filename, err);
            }
            sysfile_close(file_handle);		// close file reference
            sysmem_freeptr(blob);
            blob = NULL;

            // Set the moddate
#ifdef MAC_VERSION
//			FSCatalogInfo		catalogInfo;
//			Boolean             status;
            CFGregorianDate     gdate;
            CFAbsoluteTime      abstime;
            CFTimeZoneRef		tz;
            UTCDateTime			utc;

            sscanf(record[2], "%4ld-%02hd-%02hd %02hd:%02hd:%02lf", &gdate.year, (signed short*)&gdate.month, (signed short*)&gdate.day,
                   (signed short*)&gdate.hour, (signed short*)&gdate.minute, &gdate.second);
            tz = CFTimeZoneCopySystem();
            abstime = CFGregorianDateGetAbsoluteTime(gdate, tz);
            UCConvertCFAbsoluteTimeToUTCDateTime(abstime, &utc);
            catalogInfo.contentModDate = utc;

            strcpy(s_tempstr, x->temp_fullpath->s_name);
            temppath = strchr(s_tempstr, ':');
            temppath++;
            strcat(temppath, "/");
            strcat(temppath, record[1]);
            FSPathMakeRef((UInt8*)temppath, &ref, &isDir);
            err = FSSetCatalogInfo(&ref, kFSCatInfoContentMod, &catalogInfo);

#else // WIN_VERSION
            char				winpath[512];
            HANDLE				hFile;
            FILETIME			fileTime;
            SYSTEMTIME			systemTime;

            sscanf(record[2], "%4lu-%02lu-%02lu %02lu:%02lu:%02lu", &systemTime.wYear, &systemTime.wMonth, &systemTime.wDay,
                   &systemTime.wHour, &systemTime.wMinute, &systemTime.wSecond);
            err = SystemTimeToFileTime(&systemTime, &fileTime);

            strcpy(s_tempstr, x->temp_fullpath->s_name);
            path_nameconform(s_tempstr, winpath, PATH_STYLE_NATIVE_WIN, PATH_TYPE_ABSOLUTE);
            strcat(winpath, "\\");
            strcat(winpath, record[1]);
            hFile = CreateFile((LPCSTR)winpath , GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
            if(hFile == INVALID_HANDLE_VALUE) {
                object_error((t_object *)x, "invalid handle value");
                goto out;
            }
            err = SetFileTime(hFile, &fileTime, &fileTime, &fileTime);
            if(err == 0) {
                err = GetLastError();
                object_error((t_object *)x, "Error setting date: %i", err);
            }
            CloseHandle(hFile);
out:
            ;
#endif
        }
        object_method(x->sqlite, ps_endtransaction);
    }
void ofQtVideoSaver::setup( int width , int height, string movieName){

	w = width;
	h = height;
    
   
    fileName = (ofToDataPath(movieName));
    //pszFlatFilename = flatFileName;
    
    initializeQuicktime();
    	/*  Load the FSSpec structure to describe the receiving file.  For a 
    description of this and related calls see 
    http://developer.apple.com/quicktime/icefloe/dispatch004.html.
    ================================================================  */


	#ifdef TARGET_WIN32
		//FILE * pFile = NULL;
		//pFile = fopen (fileName.c_str(),"w");
		//fclose (pFile);
		char fileNameStr[255];
		sprintf(fileNameStr, "%s", fileName.c_str());
		osErr = NativePathNameToFSSpec (fileNameStr, &fsSpec, 0);
		
	#endif
	#ifdef TARGET_OSX
	
		/// kill a file and make a new one if needed:		
		FILE * pFile;
		pFile = fopen (fileName.c_str(),"w");
		fclose (pFile);
	
		Boolean isdir;
		osErr = FSPathMakeRef((const UInt8*)fileName.c_str(), &fsref, &isdir);
		osErr = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &fsSpec, NULL);
	#endif

    if (osErr && (osErr != fnfErr))    /* File-not-found error is ok         */
      { 
      printf ("getting FSS spec failed %d\n", osErr); 
      goto bail; 
     }
	 

	/*  Step 1:  Create a new, empty movie file and a movie that references that 
    file (CreateMovieFile).  
    ======================================================================== */
            
    osErr = CreateMovieFile 
      (
      &fsSpec,                         /* FSSpec specifier                   */
      FOUR_CHAR_CODE('TVOD'),          /* file creator type, TVOD = QT player*/
      smCurrentScript,                 /* movie script system to use         */
      createMovieFileDeleteCurFile     /* movie file creation flags          */
        | createMovieFileDontCreateResFile,
      &sResRefNum,                     /* returned file ref num to data fork */
      &movie                           /* returned handle to open empty movie*/
                                       /*   that references the created file */
      );
    if (osErr) 
      { 
      printf ("CreateMovieFile failed %d\n", osErr); 
      goto bail; 
      }


	/*  Step 2:  Add a new track to that movie (NewMovieTrack).
    =======================================================  */

    track = NewMovieTrack 
      (
      movie,                           /* the movie to add track to          */
      ((long) w << 16),              /* width of track in pixels (Fixed)   */
      FixRatio (h, 1),               /* height of track in pixels (Fixed)  */ 
      kNoVolume                        /* default volume level               */
      );
    osErr = GetMoviesError ();
    if (osErr) 
      { 
      printf ("NewMovieTrack failed %d\n", osErr); 
      goto bail; 
      }
    

	/*  Step 3:  Add a new media to that track (NewTrackMedia).
    =======================================================  */
    
    media = NewTrackMedia 
      (
      track,                           /* the track to add the media to      */
      VideoMediaType,                  /* media type, e.g. SoundMediaType    */
      600,                             /* num media time units that elapse/sec*/
      NULL,                            /* ptr to file that holds media sampls*/
      0                                /* type of ptr to media samples       */
      );
    osErr = GetMoviesError ();
    if (osErr) 
      { 
      printf ("NewTrackMedia failed %d\n", osErr); 
      goto bail; 
      }

	/*  Step 4:  Add media samples to the media. 
    ========================================  */
    
    BeginMediaEdits (media);           /* Inform the Movie Toolbox that we   */
                                       /*   want to change the media samples */
                                       /*   referenced by a track's media.   */
                                       /*   This opens the media container   */
                                       /*   and makes it ready to receive    */
                                       /*   and/or remove sample data.       */
    
    
    

    // Step 5: setup graphics port for qt movie and compression type ---
    
    /*  Create a new offscreen graphics world that will hold the movie's
    drawing surface.  draw_image() copies the image of IceFlow to this
    surface with varying amounts of transparency.
    =================================================================  */
    
    MacSetRect (&rect, 0, 0, w, h);

    osErr = NewGWorld 
      (
      &pMovieGWorld,                   /* receives the new GWorld.           */
      24,                              /* pixel depth in bits/pixel          */
      &rect,                           /* desired size of the GWorld.        */
      NULL, 
      NULL, 
      (GWorldFlags) 0
      );
    if (osErr != noErr) 
      { 
      printf ("NewGWorld 1 failed %d\n", osErr); 
      goto bail; 
      }


/*  Retrieve the pixel map associated with that graphics world and lock 
    the pixel map in memory.  GetMaxCompressionSize() and CompressImage()
    only operate on pixel maps, not graphics worlds.
    =====================================================================  */
    
    pixMapHandle = GetGWorldPixMap (pMovieGWorld);
    if (pixMapHandle == NULL) 
      { 
      printf ("GetGWorldPixMap failed\n"); 
      goto bail; 
      }
    LockPixels (pixMapHandle);


/*  Get the maximum number of bytes required to hold an image having the 
    specified characteristics compressed using the specified compressor.
    ====================================================================  */

     
    osErr = GetMaxCompressionSize 
      (
      pixMapHandle,							/* the pixel map to compress from.    */
      &rect,								/* the image rectangle.               */
      0,									/* let ICM choose image bit depth.    */
      codecHighQuality,						/* compression quality specifier.     */
      kRawCodecType,						/* desired compression type           */   // < set to RAW in case we set to a new compression type...
      (CompressorComponent) anyCodec,		/* codec specifier.                   */
      &lMaxCompressionSize					/* receives max bytes needed for cmp. */
      );
    if (osErr != noErr) 
      { 
      printf ("GetMaxCompressionSize failed %d\n", osErr); 
      goto bail; 
      }


/*  Allocate a buffer to hold the compressed image data by creating a new
    handle.
    =====================================================================  */
    hCompressedData = NewHandle (lMaxCompressionSize);
    if (hCompressedData == NULL) 
      { 
      printf ("NewHandle(%ld) failed\n", lMaxCompressionSize); 
      goto bail; 
      }

/*  Lock the handle and then dereference it to obtain a pointer to the data 
    buffer because CompressImage() wants us to pass it a pointer, not a 
    handle. 
    =======================================================================  */

    HLockHi (hCompressedData);
    pCompressedData = *hCompressedData;

/*  Create an image description object in memory of minimum size to pass 
    to CompressImage().  CompressImage() will resize the memory as 
    necessary so create it small here.
    ====================================================================  */
    
    hImageDescription = (ImageDescriptionHandle) NewHandle (4);
    if (hImageDescription == NULL) 
      { 
      printf ("NewHandle(4) failed\n"); 
      goto bail; 
      }
	
	
	
	bSetupForRecordingMovie = true;
    return;
    
    
    
    
  bail:    
	printf("got to bail somehows \n");
    if (sResRefNum != 0) CloseMovieFile (sResRefNum);
    if (movie     != NULL) DisposeMovie (movie);

    //ExitMovies ();                     /* Finalize Quicktime                 */
    
    return;
}
示例#28
0
QString QFSFileEngine::fileName(FileName file) const
{
    Q_D(const QFSFileEngine);
    if (file == BundleName) {
#if !defined(QWS) && defined(Q_OS_MAC)
        QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath),
                                                              kCFURLPOSIXPathStyle, true);
        if(CFDictionaryRef dict = CFBundleCopyInfoDictionaryForURL(url)) {
            if(CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) {
                if(CFGetTypeID(name) == CFStringGetTypeID())
                    return QCFString::toQString((CFStringRef)name);
            }
        }
#endif
        return QString();
    } else if (file == BaseName) {
        int slash = d->filePath.lastIndexOf(QLatin1Char('/'));
        if (slash != -1)
            return d->filePath.mid(slash + 1);
    } else if (file == PathName) {
        int slash = d->filePath.lastIndexOf(QLatin1Char('/'));
        if (slash == -1)
            return QLatin1String(".");
        else if (!slash)
            return QLatin1String("/");
        return d->filePath.left(slash);
    } else if (file == AbsoluteName || file == AbsolutePathName) {
        QString ret;
        if (d->filePath.isEmpty() || !d->filePath.startsWith(QLatin1Char('/')))
            ret = QDir::currentPath();
        if (!d->filePath.isEmpty() && d->filePath != QLatin1String(".")) {
            if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
                ret += QLatin1Char('/');
            ret += d->filePath;
        }
        if (ret == QLatin1String("/"))
            return ret;
        bool isDir = ret.endsWith(QLatin1Char('/'));
        ret = QDir::cleanPath(ret);
        if (isDir)
            ret += QLatin1String("/");
        if (file == AbsolutePathName) {
            int slash = ret.lastIndexOf(QLatin1Char('/'));
            if (slash == -1)
                return QDir::currentPath();
            else if (!slash)
                return QLatin1String("/");
            return ret.left(slash);
        }
        return ret;
    } else if (file == CanonicalName || file == CanonicalPathName) {
        if (!(fileFlags(ExistsFlag) & ExistsFlag))
            return QString();

        QString ret = QFSFileEnginePrivate::canonicalized(fileName(AbsoluteName));
        if (!ret.isEmpty() && file == CanonicalPathName) {
            int slash = ret.lastIndexOf(QLatin1Char('/'));
            if (slash == -1)
                ret = QDir::currentPath();
            else if (slash == 0)
                ret = QLatin1String("/");
            ret = ret.left(slash);
        }
        return ret;
    } else if (file == LinkName) {
        if (d->isSymlink()) {
#if defined(__GLIBC__) && !defined(PATH_MAX)
#define PATH_CHUNK_SIZE 256
            char *s = 0;
            int len = -1;
            int size = PATH_CHUNK_SIZE;

            while (1) {
                s = (char *) ::realloc(s, size);
                if (s == 0) {
                    len = -1;
                    break;
                }
                len = ::readlink(d->nativeFilePath.constData(), s, size);
                if (len < 0) {
                    ::free(s);
                    break;
                }
                if (len < size) {
                    break;
                }
                size *= 2;
            }
#else
            char s[PATH_MAX+1];
            int len = readlink(d->nativeFilePath.constData(), s, PATH_MAX);
#endif
            if (len > 0) {
                QString ret;
                if (S_ISDIR(d->st.st_mode) && s[0] != '/') {
                    QDir parent(d->filePath);
                    parent.cdUp();
                    ret = parent.path();
                    if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
                        ret += QLatin1Char('/');
                }
                s[len] = '\0';
                ret += QFile::decodeName(QByteArray(s));
#if defined(__GLIBC__) && !defined(PATH_MAX)
		::free(s);
#endif

                if (!ret.startsWith(QLatin1Char('/'))) {
                    if (d->filePath.startsWith(QLatin1Char('/'))) {
                        ret.prepend(d->filePath.left(d->filePath.lastIndexOf(QLatin1Char('/')))
                                    + QLatin1Char('/'));
                    } else {
                        ret.prepend(QDir::currentPath() + QLatin1Char('/'));
                    }
                }
                ret = QDir::cleanPath(ret);
                if (ret.size() > 1 && ret.endsWith(QLatin1Char('/')))
                    ret.chop(1);
                return ret;
            }
        }
#if !defined(QWS) && defined(Q_OS_MAC)
        {
            FSRef fref;
            if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->filePath)).data(), &fref, 0) == noErr) {
                Boolean isAlias, isFolder;
                if (FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) {
                    AliasHandle alias;
                    if (FSNewAlias(0, &fref, &alias) == noErr && alias) {
                        CFStringRef cfstr;
                        if (FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr)
                            return QCFString::toQString(cfstr);
                    }
                }
            }
        }
#endif
        return QString();
    }
    return d->filePath;
}
示例#29
0
/*!
    \reimp
*/
QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
{
    Q_D(const QFSFileEngine);
    // Force a stat, so that we're guaranteed to get up-to-date results
    if (type & QAbstractFileEngine::FileFlag(QAbstractFileEngine::Refresh)) {
        d->tried_stat = 0;
        d->need_lstat = 1;
    }

    QAbstractFileEngine::FileFlags ret = 0;
    bool exists = d->doStat();
    if (!exists && !d->isSymlink())
        return ret;

    if (exists && (type & PermsMask)) {
        if (d->st.st_mode & S_IRUSR)
            ret |= ReadOwnerPerm;
        if (d->st.st_mode & S_IWUSR)
            ret |= WriteOwnerPerm;
        if (d->st.st_mode & S_IXUSR)
            ret |= ExeOwnerPerm;
        if (d->st.st_mode & S_IRUSR)
            ret |= ReadUserPerm;
        if (d->st.st_mode & S_IWUSR)
            ret |= WriteUserPerm;
        if (d->st.st_mode & S_IXUSR)
            ret |= ExeUserPerm;
        if (d->st.st_mode & S_IRGRP)
            ret |= ReadGroupPerm;
        if (d->st.st_mode & S_IWGRP)
            ret |= WriteGroupPerm;
        if (d->st.st_mode & S_IXGRP)
            ret |= ExeGroupPerm;
        if (d->st.st_mode & S_IROTH)
            ret |= ReadOtherPerm;
        if (d->st.st_mode & S_IWOTH)
            ret |= WriteOtherPerm;
        if (d->st.st_mode & S_IXOTH)
            ret |= ExeOtherPerm;
    }
    if (type & TypesMask) {
#if !defined(QWS) && defined(Q_OS_MAC)
        bool foundAlias = false;
        {
            FSRef fref;
            if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->filePath)).data(),
                             &fref, NULL) == noErr) {
                Boolean isAlias, isFolder;
                if (FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr && isAlias) {
                    foundAlias = true;
                    ret |= LinkType;
                }
            }
        }
        if (!foundAlias)
#endif
        {
            if ((type & LinkType) && d->isSymlink())
                ret |= LinkType;
            if (exists && (d->st.st_mode & S_IFMT) == S_IFREG)
                ret |= FileType;
            else if (exists && (d->st.st_mode & S_IFMT) == S_IFDIR)
                ret |= DirectoryType;
#if !defined(QWS) && defined(Q_OS_MAC)
            if((ret & DirectoryType) && (type & BundleType)) {
                QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath),
                                                                      kCFURLPOSIXPathStyle, true);
                UInt32 type, creator;
                if(CFBundleGetPackageInfoInDirectory(url, &type, &creator))
                    ret |= BundleType;
            }
#endif
        }
    }
    if (type & FlagsMask) {
        ret |= LocalDiskFlag;
        if (exists)
            ret |= ExistsFlag;
        if (fileName(BaseName)[0] == QLatin1Char('.')
#if !defined(QWS) && defined(Q_OS_MAC)
            || _q_isMacHidden(d->filePath)
#endif
        )
            ret |= HiddenFlag;
        if (d->filePath == QLatin1String("/"))
            ret |= RootFlag;
    }
    return ret;
}
示例#30
0
int process_spawn( process_t* proc )
{
	static char unescaped[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.:/\\";
	int i, num_args;
	int size;
#if FOUNDATION_PLATFORM_WINDOWS
	wchar_t* wcmdline;
	wchar_t* wwd;
	char* cmdline = 0;
#endif

	if( !proc )
		return PROCESS_INVALID_ARGS;
	
	proc->code = PROCESS_INVALID_ARGS;

	if( !string_length( proc->path ) )
		return proc->code;

	//Always escape path on Windows platforms
#if FOUNDATION_PLATFORM_POSIX
	if( string_find_first_not_of( proc->path, unescaped, 0 ) != STRING_NPOS )
#endif
	{
		if( proc->path[0] != '"' )
			proc->path = string_prepend( proc->path, "\"" );
		if( proc->path[ string_length( proc->path ) - 1 ] != '"' )
			proc->path = string_append( proc->path, "\"" );
	}

	size = array_size( proc->args );
	for( i = 0, num_args = 0; i < size; ++i )
	{
		char* arg = proc->args[i];
		
		if( !string_length( arg ) )
			continue;
		
		++num_args;
		
		if( string_find_first_not_of( arg, unescaped, 0 ) != STRING_NPOS )
		{
			if( arg[0] != '"' )
			{
				//Check if we need to escape " characters
				unsigned int pos = string_find( arg, '"', 0 );
				while( pos != STRING_NPOS )
				{
					if( arg[ pos - 1 ] != '\\' )
					{
						char* escarg = string_substr( arg, 0, pos );
						char* left = string_substr( arg, pos, STRING_NPOS );
						escarg = string_append( escarg, "\\" );
						escarg = string_append( escarg, left );
						string_deallocate( left );
						string_deallocate( arg );
						arg = escarg;
					}
					pos = string_find( arg, '"', pos + 2 );
				}
				arg = string_prepend( arg, "\"" );
				arg = string_append( arg, "\"" );

				proc->args[i] = arg;
			}
		}
	}

#if FOUNDATION_PLATFORM_WINDOWS

#  ifndef SEE_MASK_NOASYNC
#    define SEE_MASK_NOASYNC           0x00000100
#  endif

	if( !( proc->flags & PROCESS_WINDOWS_USE_SHELLEXECUTE ) ) //Don't prepend exe path to parameters if using ShellExecute
		cmdline = string_clone( proc->path );
	
	//Build command line string
	for( i = 0; i < size; ++i )
	{
		char* arg = proc->args[i];
		
		if( !string_length( arg ) )
			continue;

		if( cmdline )
			cmdline = string_append( cmdline, " " );
		cmdline = string_append( cmdline, arg );
	}
	
	if( !string_length( proc->wd ) )
		proc->wd = string_clone( environment_current_working_directory() );

	wcmdline = wstring_allocate_from_string( cmdline, 0 );
	wwd = wstring_allocate_from_string( proc->wd, 0 );
	
	if( proc->flags & PROCESS_WINDOWS_USE_SHELLEXECUTE )
	{
		SHELLEXECUTEINFOW sei;
		wchar_t* wverb;
		wchar_t* wpath;

		wverb = ( proc->verb && string_length( proc->verb ) ) ? wstring_allocate_from_string( proc->verb, 0 ) : 0;
		wpath = wstring_allocate_from_string( proc->path, 0 );

		ZeroMemory( &sei, sizeof( sei ) );

		sei.cbSize          = sizeof(SHELLEXECUTEINFOW);
		sei.hwnd            = 0;
		sei.fMask           = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS;
		sei.lpVerb          = wverb;
		sei.lpFile          = wpath;
		sei.lpParameters    = wcmdline;
		sei.lpDirectory     = wwd;
		sei.nShow           = SW_SHOWNORMAL;

		if( !( proc->flags & PROCESS_CONSOLE ) )
			sei.fMask      |= SEE_MASK_NO_CONSOLE;

		if( proc->flags & PROCESS_STDSTREAMS )
			log_warnf( 0, WARNING_UNSUPPORTED, "Unable to redirect standard in/out through pipes when using ShellExecute for process spawning" );

		log_debugf( 0, "Spawn process (ShellExecute): %s %s", proc->path, cmdline );

		if( !ShellExecuteExW( &sei ) )
		{
			log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to spawn process (ShellExecute) for executable '%s': %s", proc->path, system_error_message( GetLastError() ) );
		}
		else
		{
			proc->hp   = sei.hProcess;
			proc->ht   = 0;
			proc->code = 0;
		}

		wstring_deallocate( wverb );
		wstring_deallocate( wpath );
	}
	else
	{
		STARTUPINFOW si;
		PROCESS_INFORMATION pi;
		BOOL inherit_handles = FALSE;

		memset( &si, 0, sizeof( si ) );
		memset( &pi, 0, sizeof( pi ) );
		si.cb = sizeof( si );

		if( proc->flags & PROCESS_STDSTREAMS )
		{
			proc->pipeout = pipe_allocate();
			proc->pipein = pipe_allocate();

			si.dwFlags |= STARTF_USESTDHANDLES;
			si.hStdOutput = pipe_write_handle( proc->pipeout );
			si.hStdError = pipe_write_handle( proc->pipeout );
			si.hStdInput = pipe_read_handle( proc->pipein );

			//Don't inherit wrong ends of pipes
			SetHandleInformation( pipe_read_handle( proc->pipeout ), HANDLE_FLAG_INHERIT, 0 );
			SetHandleInformation( pipe_write_handle( proc->pipein ), HANDLE_FLAG_INHERIT, 0 );

			inherit_handles = TRUE;
		}

		log_debugf( 0, "Spawn process (CreateProcess): %s %s", proc->path, cmdline );

		if( !CreateProcessW( 0/*wpath*/, wcmdline, 0, 0, inherit_handles, ( proc->flags & PROCESS_CONSOLE ) ? CREATE_NEW_CONSOLE : 0, 0, wwd, &si, &pi ) )
		{
			log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to spawn process (CreateProcess) for executable '%s': %s", proc->path, system_error_message( GetLastError() ) );

			stream_deallocate( proc->pipeout );
			stream_deallocate( proc->pipein );

			proc->pipeout = 0;
			proc->pipein = 0;
		}
		else
		{
			proc->hp = pi.hProcess;
			proc->ht = pi.hThread;
			proc->code = 0;
		}

		if( proc->pipeout )
			pipe_close_write( proc->pipeout );
		if( proc->pipein )
			pipe_close_read( proc->pipein );
	}

	wstring_deallocate( wcmdline );
	wstring_deallocate( wwd );
	string_deallocate( cmdline );
	
	if( proc->code < 0 )
		return proc->code; //Error

#endif

#if FOUNDATION_PLATFORM_MACOSX
	
	if( proc->flags & PROCESS_OSX_USE_OPENAPPLICATION )
	{
		proc->pid = 0;
		
		LSApplicationParameters params;
		ProcessSerialNumber psn;
		FSRef* fsref = memory_allocate( 0, sizeof( FSRef ), 0, MEMORY_TEMPORARY | MEMORY_ZERO_INITIALIZED );
		
		memset( &params, 0, sizeof( LSApplicationParameters ) );
		memset( &psn, 0, sizeof( ProcessSerialNumber ) );
		
		char* pathstripped = string_strip( string_clone( proc->path ), "\"" );
		
		OSStatus status = 0;
		status = FSPathMakeRef( (uint8_t*)pathstripped, fsref, 0 );
		if( status < 0 )
		{
			pathstripped = string_append( pathstripped, ".app" );
			status = FSPathMakeRef( (uint8_t*)pathstripped, fsref, 0 );
		}
		
		CFStringRef* args = 0;
		for( i = 0, size = array_size( proc->args ); i < size; ++i ) //App gets executable path automatically, don't include
			array_push( args, CFStringCreateWithCString( 0, proc->args[i], kCFStringEncodingUTF8 ) );
		
		CFArrayRef argvref = CFArrayCreate( 0, (const void**)args, (CFIndex)array_size( args ), 0 );
		
		params.flags = kLSLaunchDefaults;
		params.application = fsref;
		params.argv = argvref;

		log_debugf( 0, "Spawn process (LSOpenApplication): %s", pathstripped );
		
		status = LSOpenApplication( &params, &psn );
		if( status != 0 )
		{
			proc->code = status;
			log_warnf( 0, WARNING_BAD_DATA, "Unable to spawn process for executable '%s': %s", proc->path, system_error_message( status ) );
		}
		
		CFRelease( argvref );
		for( i = 0, size = array_size( args ); i < size; ++i )
			CFRelease( args[i] );
		
		memory_deallocate( fsref );
		string_deallocate( pathstripped );
		
		if( status == 0 )
		{
			pid_t pid = 0;
			GetProcessPID( &psn, &pid );
			
			proc->pid = pid;

			//Always "detached" with LSOpenApplication, not a child process at all
			//Setup a kqueue to watch when process terminates so we can emulate a wait
			proc->kq = kqueue();
			if( proc->kq < 0 )
			{
				log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to create kqueue for process watch: %s (%d)", proc->kq, system_error_message( proc->kq ) );
				proc->kq = 0;
			}
			else
			{
				struct kevent changes;
				EV_SET( &changes, (pid_t)pid, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, 0 );
				int ret = kevent( proc->kq, &changes, 1, &changes, 1, 0 );
				if( ret != 1 )
				{
					log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to setup kqueue for process watch, failed to add event to kqueue (%d)", ret );
					close( proc->kq );
					proc->kq = 0;
				}
			}
		}
		
		goto exit;
	}
#endif

#if FOUNDATION_PLATFORM_POSIX

	//Insert executable arg at start and null ptr at end
	int argc = array_size( proc->args ) + 1;
	array_grow( proc->args, 2 );
	for( int arg = argc - 1; arg > 0; --arg )
		proc->args[arg] = proc->args[arg-1];
	proc->args[0] = string_clone( proc->path );
	proc->args[argc] = 0;

	if( proc->flags & PROCESS_STDSTREAMS )
	{
		proc->pipeout = pipe_allocate();
		proc->pipein = pipe_allocate();
	}
	
	proc->pid = 0;	
	pid_t pid = fork();

	if( pid == 0 )
	{
		//Child
		if( string_length( proc->wd ) )
		{
			log_debugf( 0, "Spawned child process, setting working directory to %s", proc->wd );
			environment_set_current_working_directory( proc->wd );
		}

		log_debugf( 0, "Child process executing: %s", proc->path );

		if( proc->flags & PROCESS_STDSTREAMS )
		{
			pipe_close_read( proc->pipeout );
			dup2( pipe_write_fd( proc->pipeout ), STDOUT_FILENO );

			pipe_close_write( proc->pipein );
			dup2( pipe_read_fd( proc->pipein ), STDIN_FILENO );
		}

		int code = execv( proc->path, proc->args );
		if( code < 0 ) //Will always be true since this point will never be reached if execve() is successful
			log_warnf( 0, WARNING_BAD_DATA, "Child process failed execve() : %s : %s", proc->path, system_error_message( errno ) );
		
		//Error
		process_exit( -1 );
	}

	if( pid > 0 )
	{		
		log_debugf( 0, "Child process forked, pid %d", pid );

		proc->pid = pid;

		if( proc->pipeout )
			pipe_close_write( proc->pipeout );
		if( proc->pipein )
			pipe_close_read( proc->pipein );
		
		if( proc->flags & PROCESS_DETACHED )
		{
			int cstatus = 0;
			pid_t err = waitpid( pid, &cstatus, WNOHANG );
			if( err == 0 )
			{
				//TODO: Ugly wait to make sure process spawned correctly
				thread_sleep( 500 );
				err = waitpid( pid, &cstatus, WNOHANG );
			}
			if( err > 0 )
			{
				//Process exited, check code
				proc->code = (int)((char)WEXITSTATUS( cstatus ));
				log_debugf( 0, "Child process returned: %d", proc->code );
				return proc->code;
			}
		}
	}
	else
	{
		//Error
		proc->code = errno;
		log_warnf( 0, WARNING_BAD_DATA, "Unable to spawn process: %s : %s", proc->path, system_error_message( proc->code ) );

		if( proc->pipeout )
			stream_deallocate( proc->pipeout );
		if( proc->pipein )
			stream_deallocate( proc->pipein );

		proc->pipeout = 0;
		proc->pipein = 0;
		
		return proc->code;
	}	

#endif

#if !FOUNDATION_PLATFORM_WINDOWS && !FOUNDATION_PLATFORM_POSIX
	FOUNDATION_ASSERT_FAIL( "Process spawning not supported on platform" );
#endif
	
#if FOUNDATION_PLATFORM_MACOSX
exit:
#endif

	if( proc->flags & PROCESS_DETACHED )
		return PROCESS_STILL_ACTIVE;

	return process_wait( proc );
}