我如何得到一个的Mac OS组件管理器组件是可见的其他进程?
-
13-09-2019 - |
题
这是一个有点深奥,但必须有几个人在这里谁知道OS X的Carbon组件管理器是如何工作的。我做了一些小的应用程序玩弄使得组件(见的这里一些背景)。事实上,应用程序之一,是一个范例程序直接从苹果称为“Fiendishthngs”。它列出了所有的组件管理器正在使用的组件。我的计划是注册一个组件简单的小东西,列出了所有的组件管理器具有的组件,然后等待无限期地左右(以避免清洗,它注册的组件)。
在我的系统,组件管理器正在跟踪873个组件(主要是一个排序的另一个的编解码器)。我的程序,注册一个组件注册,然后计数874个组件,因为它只是一个注册本身,当然)。这里的源:
void RegisterBasicComponent()
{
ComponentDescription desc;
desc.componentType = kMyComponentType;
desc.componentSubType = kMyComponentSubType;
desc.componentManufacturer = kMyComponentManufacturer;
desc.componentFlags = 0;
desc.componentFlagsMask = cmpIsMissing;
ComponentRoutineUPP MyComponentRoutineUPP
= NewComponentRoutineUPP( &MyComponentRoutineProc );
// Handle name_handle = NewHandle( sizeof( kMyComponentName ) );
//strcpy( *(char**)name_handle, kMyComponentName );
//RegisterComponent( &desc, MyComponentRoutineUPP, registerComponentGlobal, name_handle, NULL, NULL );
Component component = RegisterComponent( &desc, MyComponentRoutineUPP, registerComponentGlobal, NULL, NULL, NULL );
if ( NULL != component )
printf("The registration seems to have worked!\n");
else
printf("Nope - didn't work for some reason.\n");
}
int main( void )
{
RegisterBasicComponent();
ComponentDescription looking;
// OSType componentType; /* A unique 4-byte code indentifying the command set */
// OSType componentSubType; /* Particular flavor of this instance */
// OSType componentManufacturer; /* Vendor indentification */
// UInt32 componentFlags; /* 8 each for Component,Type,SubType,Manuf/revision */
// UInt32 componentFlagsMask; /* Mask for specifying which flags to consider in search, zero during registration */
looking.componentType = kAnyComponentType;
looking.componentSubType = kAnyComponentSubType;
// looking.componentSubType = kComponentResourceType
looking.componentManufacturer = kAnyComponentManufacturer;
looking.componentFlags = 0;
looking.componentFlagsMask = cmpIsMissing;
long numComponents = CountComponents ( &looking );
printf("Found %ld components.\n", numComponents);
Component component = 0;
int i = 0;
while (true)
{
component = FindNextComponent(component, &looking);
if ( 0 == component )
break;
ComponentDescription desc;
Handle componentName = NewHandle(256);
Handle componentInfo = NewHandle(1024);
Handle componentIcon = 0;
OSErr err = GetComponentInfo( component,
&desc,
componentName,
componentInfo,
componentIcon );
if ( err != noErr )
{
printf("Couldn't find any info on component %d of %ld in list!\n", i
, numComponents);
break;
}
printf( "%d of %ld: '%c%c%c%c', '%c%c%c%c', '%c%c%c%c', '%s'\n",
i, numComponents,
SPLAT_WORD( desc.componentManufacturer ),
SPLAT_WORD( desc.componentType ),
SPLAT_WORD( desc.componentSubType ),
*componentName );
RecoverHandle( *componentName );
RecoverHandle( *componentInfo );
++i;
}
while (true)
{
printf("Waiting around for someone to use me...\n");
sleep( 3 );
}
}
不管怎么说,当我运行它,保持它运行(这样的组件大概保持与组件管理器注册),然后运行Fiendishthngs,Fiendishthngs不能看到我的测试组件,我注册 - 它只能看到873个组件。该“registerComponentGlobal”标志传递到RegisterComponent()应该使组件可供其它进程,但它看起来似乎是行不通了。
任何想法?
解决方案
好了,我离开了这个问题的背后,自己辞职的事实,OS X的组件管理器可能不支持“全局”选项了。
这将使一个很大的意义,真的。让您的组件从过程到其他进程“全球性”将需要进程外调用编组,像RPC,与OS X中。另一方面,在OS 9和早期,它将使完美的意义,因为所有流程生活在一个共同的地址空间。对于OS 9将是微不足道的,使一个组件全局可用于所有过程。
不管怎么说,今天我被拆卸RegisterComponentFileRefEntries(),其中相关的代码似乎存在,果然,我看到这个在前期缓行的功能(评论是我的):
0x9841a026 <+0018> mov eax, DWORD PTR [ebp+0x8] // load param spec
0x9841a029 <+0021> mov DWORD PTR [ebp-0xdc],eax // local spec = param spec
0x9841a02f <+0027> mov edx,DWORD PTR [ebp+0x10] // load param toRegister
0x9841a032 <+0030> mov DWORD PTR [ebp-0xe0],edx // local toRegister = param toRegister
有RegisterComponentFileRefEntries签名是
extern OSErr
RegisterComponentFileEntries(
const FSSpec * spec,
short global,
const ComponentDescription * toRegister, /* can be NULL */
UInt32 registerCount)
在只有2个参数RegisterComponentFileRefEntries与规格是困扰(在EBP + 0x8中)和toRegister(在EBP +为0x10)。全局(在EBP +位于0xC)和registerCount(在EBP + 0×14)被完全忽略。