Loading bundle from memory is possible by NSCreateObjectFileImageFromMemory function. Does anyone have successful experience in this area? Does anyone have working sample for this function?
My code is as:
text srcPath = "/Applications/TextEdit.app/Contents/MacOS/TextEdit";
data_t data;
data.loadFromFile(srcPath);
void *addr;
kern_return_t err;
NSObjectFileImage img = nil;
NSObjectFileImageReturnCode dyld_err;
err = vm_allocate(mach_task_self(), (vm_address_t *)&addr,
data.length(), true);
if(err == 0)
{
//err = vm_write(mach_task_self(), (vm_address_t)addr,
//(vm_address_t)(char*)data, data.length());
memcpy(addr, (char*)data, data.length());
if(err == 0)
dyld_err =
NSCreateObjectFileImageFromMemory(addr, data.length(), &img);
// error is NSObjectFileImageFailure
}
The img variable is null (error is NSObjectFileImageFailure). Why?
Thankyou.
From the manpage, it looks like only MH_BUNDLE files can be loaded with NSCreateObjectFileImageFromMemory() and friends.
MH_BUNDLE files are explained here.
The MH_BUNDLE file type is the type typically used by code that you
load at runtime (typically called bundles or plug-ins). By convention,
the file name extension for this format is .bundle.
Note that that manpage is for 10.4 and there does not appear to be a newer version available.
Related
I'm looking for the best possible approach to incorporate a batch file to send arguments to the MFC application rather than relying on the GUI interface. Does anyone know the best method to go about doing this?
I use the following code in my InitInstance method of my app class:
LPWSTR *szArglist = nullptr;
int iNumArgs = 0;
szArglist = CommandLineToArgvW(GetCommandLine(), &iNumArgs);
if (iNumArgs > 0 && szArglist != nullptr)
{
for (int iArg = 0; iArg < iNumArgs; iArg++)
{
CString strArg(szArglist[iArg]);
int iDelim = strArg.Find(_T("="));
if (iDelim != -1)
{
CString strParamName = strArg.Left(iDelim);
CString strParamValue = strArg.Mid(iDelim + 1);
if (strParamName.CollateNoCase(_T("/lang")) == 0)
{
m_strPathLanguageResourceOverride.Format(_T("%sMeetSchedAssist%s.dll"),
(LPCTSTR)GetProgramPath(), (LPCTSTR)strParamValue.MakeUpper());
if (!PathFileExists(m_strPathLanguageResourceOverride))
m_strPathLanguageResourceOverride = _T("");
}
}
}
// Free memory allocated for CommandLineToArgvW arguments.
LocalFree(szArglist);
}
As you can see, I use the CommandLineToArgvW method to extract and process the command line arguments.
A GUI program can receive command line arguments just like a command line program can.
Your Application class (CWinApp, if memory serves) contains a member named m_lpCmdLine that contains the command line arguments (if any) in a CString.
If you also want to deal with shell parameters, you'll probably also want to look at WinApp::ParseCommandLine and CCommandLineInfo (note, if you're dealing with a Wizard-generated program, chances are that WinApp::ParseCommandLine is already being called by default).
There was this great function in the old MoreFilesX, FSExchangeObjectsCompat, that "exchanges the data between two files". It was typically used as part of a safe-save approach, where a temp file was written out, then FSExchangeObjectsCompat was called to exchange the newly-saved temp file with the old "original" file. It preserved all the metadata, privileges, etc.
I'm seeing a failure with this function on High Sierra, on APFS volumes, which never failed on HFS+ volumes. Not a big surprise -- many of those calls are deprecated.
But what is the Cocoa NSFileManager method of doing the same thing?
You want -[NSFileManager replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:].
You can do something similar using lower-level functions. Here's code I wrote to be used with a pre-10.12 SDK. You can make it somewhat simpler if you compile against the 10.12 SDK or later, and even simpler if you have a deployment target that is 10.12 or later.
#ifndef RENAME_SWAP
#define RENAME_SWAP 0x00000002
#endif
/*!
#function ExchangeFiles
#abstract Given full paths to two files on the same volume,
swap their contents.
#discussion This is often part of a safe-save strategy.
#param inOldFile Full path to a file.
#param inNewFile Full path to a file.
#result 0 if all went well, -1 otherwise.
*/
int ExchangeFiles( const char* inOldFile, const char* inNewFile )
{
int result = -1;
static dispatch_once_t sOnce = 0;
static renameFuncType sRenameFunc = NULL;
// Try to get a function pointer to renamex_np, which is available in OS 10.12 and later.
dispatch_once( &sOnce,
^{
sRenameFunc = (renameFuncType) dlsym( RTLD_DEFAULT, "renamex_np" );
});
// renamex_np is only available on OS 10.12 and later, and does not work on HFS+ volumes
// but does work on APFS volumes. Being the latest and greatest, we try it first.
if (sRenameFunc != NULL)
{
result = (*sRenameFunc)( inOldFile, inNewFile, RENAME_SWAP );
}
if (result != 0)
{
// exchangedata is an older function that works on HFS+ but not APFS.
result = exchangedata( inOldFile, inNewFile, 0 );
}
if (result != 0)
{
// Neither function worked, we must go old school.
std::string nameTemplate( inOldFile );
nameTemplate += "-swapXXXX";
// Make a mutable copy of the template
std::vector<char> workPath( nameTemplate.size() + 1 );
memcpy( &workPath[0], nameTemplate.c_str(), nameTemplate.size() + 1 );
mktemp( &workPath[0] );
std::string tempPath( &workPath[0] );
// Make the old file have a temporary name
result = rename( inOldFile, tempPath.c_str() );
// Put the new file data under the old name.
if (result == 0)
{
result = rename( inNewFile, inOldFile );
}
// Put the old data under the new name.
if (result == 0)
{
result = rename( tempPath.c_str(), inNewFile );
}
}
return result;
}
I just git libnet project from https://github.com/sam-github/libnet/tree/master/libnet and i have been looking over the example source provided with it.the example obtain a cmd arg called "device" to initialize libnet. I figured out "eth0" is the proper value on Linux OS but I'm using windows 7 and my question is what can i use as value for device on windows.
l = libnet_init(
LIBNET_RAW4, /* injection type */
device, /* network interface */
errbuf); /* errbuf */
I tried a lots of values like adaptor name, device index, etc... but every time i got this error:
libnet_init() failed: libnet_link_win32.c(): unable to open the driver, error Code : 14
I was confused by the same problem.
It can be solve like this.
in lib wpcap
there is a function named pcap_findalldevs();
use it like this and you will succuss
int Value = pcap_findalldevs(&alldevs,errbuf);
if( Value == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
char *device = NULL;
device = alldevs->name; //get the first Card name
libnet_t *l
l = libnet_init(
LIBNET_LINK_ADV,
device,//use it here
error_information);
may this help you. good luck!
i'm trying to read a CAF-file on OSX, using AudioToolbox's Extended Audio File API.
opening the file works fine, however, i need to access the UUID chunk, and i cannot find any reference on how to do that (or how to access any header-chunk of the file)
surely there must be a way to do this without parsing the file on my own.
PS: i can already do this with libsndfile, but i want to find a way to do this with only components that come with OSX.
i already tried calling ExtAudioFileGetProperty() with the ExtAudioFilePropertyID set to 'uuid' but this doesn't seem to work.
it turned out that the trick is not to use the ExtAudio API for accessing low-level functionality like the UUID chunk. (if you need to access the file via ExtAudio API, it's possible to create an ExtAudioHandle from an AudioFileID.)
in the end i used something like this:
AudioFileID fileID;
ExtAudioFileRef extFile;
OSStatus err = AudioFileOpenURL((CFURLRef)inURL, kAudioFileReadPermission, 0, &fileID);
if(noErr!=err)return;
err = ExtAudioFileWrapAudioFileID (fileID, false, &extFile); // in case we *also* want to access the file via ExtAudio
if(noErr!=err)return;
for(index=0; ; index++) {
UInt32 size=0;
char*data=NULL;
OSStatus err = AudioFileGetUserDataSize (fileID,'uuid',index,&size);
if(noErr!=err)break; // check whether we were able to read the chunksize
if(0==size)continue; // check whether there is some payload in the uuid chunk
data=calloc(size, 1);
if(!data)continue;
err = AudioFileGetUserData (fileID, 'uuid', index, &size, data);
if(noErr!=err){free(data); break;} // check whether we were able to read the chunksize
/* ... */
free(data);
}
ExtAudioFileDispose(extFile);
AudioFileClose(fileID);
Is there a programmatic way to find out what architecture another process is running as on Mac OS X 10.5 and later?
Examining the process's image file is not a solution, as the image is likely to contain multiple architectures, and between arch(1) and the “Open in Rosetta” and “Open in 32-bit mode” checkboxes, there's no way to tell from the image alone which architecture is actually running.
Can you use NSRunningApplication on OSes where it is available, and fall back to sysctl stuff when it isn't? I don't think sysctl stuff is supportable API the way most stuff is, but if you're only using it on old OSes you should be okay.
Try this to get the CPU type of the process:
cpu_type_t cpuType
size_t cpuTypeSize;
int mib[CTL_MAXNAME];
size_t mibLen;
mibLen = CTL_MAXNAME;
err = sysctlnametomib("sysctl.proc_cputype", mib, &mibLen);
if (err == -1) {
err = errno;
}
if (err == 0) {
assert(mibLen < CTL_MAXNAME);
mib[mibLen] = pid;
mibLen += 1;
cpuTypeSize = sizeof(cpuType);
err = sysctl(mib, mibLen, &cpuType, &cpuTypeSize, 0, 0);
if (err == -1) {
err = errno;
}
}
And test CPU_ARCH_ABI64 to check for 64-bit.
You don't say what your requirements are, but the NSRunningApplication class introduced in 10.6 offers a really easy interface for this. The docs are currently a little off, but it is there.