Re: Retrieving information about loaded kernel extensions
Re: Retrieving information about loaded kernel extensions
- Subject: Re: Retrieving information about loaded kernel extensions
- From: Terry Lambert <email@hidden>
- Date: Wed, 10 Nov 2010 11:30:14 -0800
On Nov 10, 2010, at 2:52 AM, nithesh salian wrote:
> Bug ID# 6974408
>
> On Fri, Oct 1, 2010 at 8:59 PM, Andrew Myrick <email@hidden> wrote:
>> There is no supported API for accessing information about loaded kexts. If you need one, please file a bug report.
>>
>> -Andrew
>>
>> On Oct 1, 2010, at 6:39 AM, nithesh salian wrote:
>>
>>> Kexstat is command line tool for accessing the loaded module info.
>>>
>>> However, I have to access the information inside a user level application. How can i do that? Are there any interfaces supported in Snow leopard.
>>>
>>> kmod_get_info also doesnt work on Snow Leopard. Kindly help.
>>>
>>>
>>>
>>> On Wed, Sep 29, 2010 at 6:54 PM, Alexander von Below <email@hidden> wrote:
>>> kextstat 8
>>>
>>> I would just pipe and parse that. That way you are completely independent of the system you are running on.
>>>
>>> For more details, look in http://opensource.apple.com/source/IOKitUser/IOKitUser-502.0.3/kext.subproj/OSKext.c
>>>
>>> As an aside: A lot of people read darwin-dev AND darwin-drivers. Please do NOT crosspost
>>>
>>> Alex
Nithesh, this is an incredibly trivial coding problem which you should not need to solve if you are writing your code with the correct mindset.
Here is a possible implementation of what Alex was talking about; this took me half an hour to write and debug. Comment out the definition of TEST, add a header, and you have an API. I was lazy about the version parsing, since version numbers are actually strings from a plist, not really numbers, and I left the linkages (when they exist) as space separated lists of ID numbers, since I can't possibly see their use except for debugging, and for that you have kextstat.
Again, you should not ever be writing code that needs this information in this format in the first place, so I encourage you to rethink your problem solution.
-- Terry
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
// -l option is to omit the header line
#define CMD_KEXTSTAT "/usr/sbin/kextstat -l"
struct kextinfo {
struct kextinfo *ki_next;
int ki_index;
int ki_refs;
unsigned long long ki_addr;
unsigned long long ki_size;
unsigned long long ki_wired;
char *ki_name;
char *ki_version;
char *ki_links; // Note: may validly be NULL
};
void
kextinfo_free(struct kextinfo *head)
{
struct kextinfo *kip;
for (kip = head; kip != NULL;) {
struct kextinfo *kidel = kip;
kip = kip->ki_next;
if (kidel->ki_name != NULL)
free(kidel->ki_name);
if (kidel->ki_version != NULL)
free(kidel->ki_version);
if (kidel->ki_links != NULL)
free(kidel->ki_links);
free(kidel);
}
}
struct kextinfo *
kextinfo(void)
{
FILE *fp; // pipe to kextstat
struct kextinfo *rv = NULL; // default return
struct kextinfo **mallocpp = &rv; // chaining
struct kextinfo staging; // staging buffer
char linebuf[1024]; // MAXPATHLEN for input line
char namebuf[1024]; // KEXT name
char versionbuf[1024]; // KEXT version
char linkbuf[1024]; // KEXT linkages
int count;
if ((fp = popen(CMD_KEXTSTAT, "r")) != NULL) {
while(fgets( linebuf, sizeof(linebuf), fp) != NULL) {
// line too long for buffer or bad kextstat ouput?
if (linebuf[strlen(linebuf) - 1] != '\n')
goto bad;
memset(&staging, 0, sizeof(struct kextinfo));
count = sscanf(linebuf,
"%d %d %llx %llx %llx %s %s <%s>",
&staging.ki_index,
&staging.ki_refs,
&staging.ki_addr,
&staging.ki_size,
&staging.ki_wired,
namebuf,
versionbuf,
linkbuf);
*mallocpp = malloc(sizeof(struct kextinfo));
if (*mallocpp == NULL)
goto bad;
**mallocpp = staging;
if (((*mallocpp)->ki_name = strdup(namebuf)) == NULL)
goto bad;
if (((*mallocpp)->ki_version = strdup(versionbuf)) == NULL)
goto bad;
// cheat; only do links if we saw one...
if (count == 8 &&
((*mallocpp)->ki_links = strdup(linkbuf)) == NULL)
goto bad;
mallocpp = &(*mallocpp)->ki_next;
}
pclose(fp);
}
return (rv);
bad:
// Unwind progress so far...
kextinfo_free(rv);
return(NULL);
}
#define TEST 1
#ifdef TEST
int
main(int ac, char *av[])
{
struct kextinfo *kilist = kextinfo();
struct kextinfo *kip;
if (kilist == NULL) {
printf("kextinfo() failed\n");
exit(1);
}
for (kip = kilist; kip != NULL; kip = kip->ki_next) {
printf("KEXT %d name %s\n", kip->ki_index, kip->ki_name);
}
kextinfo_free(kilist);
exit(0);
}
#endif // TEST
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden