const char * COMgetComponentName (COMclass cClass) { char *name = NULL; nsCID *cid = (nsCID *) cClass; nsCOMPtr<nsIComponentManager> compMgr; nsIEnumerator *contractEnum; nsISupportsCString *cval; nsCID mcid; NS_GetComponentManager (getter_AddRefs (compMgr)); if (!compMgr) abort (); nsCOMPtr<nsIComponentManagerObsolete> compMgrO = do_QueryInterface (compMgr); compMgrO->EnumerateContractIDs (&contractEnum); contractEnum->First (); while (contractEnum->IsDone () == NS_ENUMERATOR_FALSE) { contractEnum->CurrentItem ((nsISupports **) &cval); cval->ToString (&name); compMgrO->ContractIDToClassID (name, &mcid); if (cid->Equals (mcid)) break; else if (name) { nsMemory::Free (name); name = NULL; } contractEnum->Next (); } return name; }
/* static */ nsresult EmbedPrivate::RegisterAppComponents(void) { nsCOMPtr<nsIComponentRegistrar> cr; nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(cr)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIComponentManager> cm; rv = NS_GetComponentManager (getter_AddRefs (cm)); NS_ENSURE_SUCCESS (rv, rv); for (int i = 0; i < sNumAppComps; ++i) { nsCOMPtr<nsIGenericFactory> componentFactory; rv = NS_NewGenericFactory(getter_AddRefs(componentFactory), &(sAppComps[i])); if (NS_FAILED(rv)) { NS_WARNING("Unable to create factory for component"); continue; // don't abort registering other components } rv = cr->RegisterFactory(sAppComps[i].mCID, sAppComps[i].mDescription, sAppComps[i].mContractID, componentFactory); NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to register factory for component"); // Call the registration hook of the component, if any if (sAppComps[i].mRegisterSelfProc) { rv = sAppComps[i].mRegisterSelfProc(cm, nsnull, nsnull, nsnull, &(sAppComps[i])); NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to self-register component"); } } return rv; }
HRESULT GlueCreateInstance(const CLSID &clsid, const nsIID &id, void** ppobj) { nsCOMPtr<nsIComponentManager> manager; HRESULT rc = NS_GetComponentManager(getter_AddRefs(manager)); if (SUCCEEDED(rc)) rc = manager->CreateInstance(clsid, nsnull, id, ppobj); return rc; }
bool VirtualBoxBridge::initXPCOM() { nsresult rc; /* * This is the standard XPCOM init procedure. * What we do is just follow the required steps to get an instance * of our main interface, which is IVirtualBox. * * Note that we scope all nsCOMPtr variables in order to have all XPCOM * objects automatically released before we call NS_ShutdownXPCOM at the * end. This is an XPCOM requirement. */ rc = NS_InitXPCOM2(getter_AddRefs(nsCOM_serviceManager), nsnull, nsnull); if (NS_FAILED(rc)) { std::cerr << "Error: XPCOM could not be initialized! rc=0x" << std::hex << rc << std::dec << std::endl; return false; } /* * Make sure the main event queue is created. This event queue is * responsible for dispatching incoming XPCOM IPC messages. The main * thread should run this event queue's loop during lengthy non-XPCOM * operations to ensure messages from the VirtualBox server and other * XPCOM IPC clients are processed. This use case doesn't perform such * operations so it doesn't run the event loop. */ rc = NS_GetMainEventQ(getter_AddRefs(nsCOM_eventQ)); if (NS_FAILED(rc)) { std::cerr << "Error: could not get main event queue! rc=0x" << std::hex << rc << std::dec << std::endl; return false; } /* * Now XPCOM is ready and we can start to do real work. * All interfaces will be retrieved from the XPCOM component manager. * We use the XPCOM provided smart pointer nsCOMPtr for all objects * because that's very convenient and removes the need deal with * reference counting and freeing. */ rc = NS_GetComponentManager(getter_AddRefs(nsCOM_manager)); if (NS_FAILED(rc)) { std::cerr << "Error: could not get component manager! rc=0x" << std::hex << rc << std::dec << std::endl; return false; } return true; }
nsresult nsCreateInstanceByCID::operator()( const nsIID& aIID, void** aInstancePtr ) const { nsCOMPtr<nsIComponentManager> compMgr; nsresult status = NS_GetComponentManager(getter_AddRefs(compMgr)); if (compMgr) status = compMgr->CreateInstance(mCID, mOuter, aIID, aInstancePtr); else if (NS_SUCCEEDED(status)) status = NS_ERROR_UNEXPECTED; if ( NS_FAILED(status) ) *aInstancePtr = 0; if ( mErrorPtr ) *mErrorPtr = status; return status; }
ns_smartptr<nsISupports> nsCreateInstance(const nsCID& cid) { ns_smartptr<nsISupports> res; static nsIID nsISupportsIID = NS_ISUPPORTS_IID; ns_smartptr<nsIComponentManager> comp_mgr; NS_GetComponentManager(&comp_mgr.p); if (comp_mgr) { comp_mgr->CreateInstance(cid, 0, nsISupportsIID, (void**)&res.p); } return res; }
extern "C" NS_EXPORT jobject JNICALL XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jobject) { // Call XPCOM method nsCOMPtr<nsIComponentManager> cm; nsresult rv = NS_GetComponentManager(getter_AddRefs(cm)); if (NS_SUCCEEDED(rv)) { jobject javaProxy; rv = NativeInterfaceToJavaObject(env, cm, NS_GET_IID(nsIComponentManager), nullptr, &javaProxy); if (NS_SUCCEEDED(rv)) return javaProxy; } ThrowException(env, rv, "Failure in getComponentManager"); return nullptr; }
static nsISupports * createComponentByName (const char *contractID, const char *interfaceName) { nsISupports *obj; nsresult rv; nsIID iid; nsCOMPtr<nsIComponentManager> compMgr; NS_GetComponentManager (getter_AddRefs (compMgr)); if (!compMgr) abort (); iid = getSwarmIID (interfaceName); rv = compMgr->CreateInstanceByContractID (contractID, NULL, iid, (void **) &obj); if (NS_FAILED (rv)) abort (); return obj; }
/* nsISupports createInstance (); */ NS_IMETHODIMP nsJSCID::CreateInstance(const JS::Value& iidval, JSContext* cx, PRUint8 optionalArgc, JS::Value* retval) { if (!mDetails.IsValid()) return NS_ERROR_XPC_BAD_CID; JSObject* obj = GetWrapperObject(); if (!obj) { return NS_ERROR_UNEXPECTED; } // Do the security check if necessary XPCContext* xpcc = XPCContext::GetXPCContext(cx); nsIXPCSecurityManager* sm; sm = xpcc->GetAppropriateSecurityManager(nsIXPCSecurityManager::HOOK_CREATE_INSTANCE); if (sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) { NS_ERROR("how are we not being called from chrome here?"); return NS_OK; } // If an IID was passed in then use it const nsID* iid = GetIIDArg(optionalArgc, iidval, cx); if (!iid) return NS_ERROR_XPC_BAD_IID; nsCOMPtr<nsIComponentManager> compMgr; nsresult rv = NS_GetComponentManager(getter_AddRefs(compMgr)); if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED; nsCOMPtr<nsISupports> inst; rv = compMgr->CreateInstance(mDetails.ID(), nsnull, *iid, getter_AddRefs(inst)); NS_ASSERTION(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!"); if (NS_FAILED(rv) || !inst) return NS_ERROR_XPC_CI_RETURNED_FAILURE; rv = nsXPConnect::GetXPConnect()->WrapNativeToJSVal(cx, obj, inst, nsnull, iid, true, retval, nsnull); if (NS_FAILED(rv) || JSVAL_IS_PRIMITIVE(*retval)) return NS_ERROR_XPC_CANT_CREATE_WN; return NS_OK; }
COMobject COMcreateComponent (COMclass cClass) { const nsCID *cid = (const nsCID *) cClass; nsIID iid; const char *className = COM_get_class_name (cClass); char *interfaceName = NULL; nsCOMPtr<nsIComponentManager> compMgr; NS_GetComponentManager (getter_AddRefs (compMgr)); if (!compMgr) abort (); size_t len; nsISupports *obj; len = PL_strlen (className); if (len > 10) /* swarm + name + Impl */ { if (PL_strcmp (className + len - 4, "Impl") == 0) { interfaceName = PL_strdup (className + 5); interfaceName[len - 4 - 5] = '\0'; } else interfaceName = NULL; } else interfaceName = NULL; iid = getSwarmIID (interfaceName); if (!NS_SUCCEEDED (compMgr->CreateInstance (*cid, nsnull, iid, (void **) &obj))) obj = nsnull; if (obj == nsnull) abort (); if (interfaceName) PL_strfree (interfaceName); return (COMobject) obj; }
COMclass COMfindComponent (const char *className) { const char *prefix = "urn:"; const char *modulePrefix = "swarm/"; size_t prefixLen = PL_strlen (prefix); size_t modulePrefixLen = PL_strlen (modulePrefix); nsCID *cClass = new nsCID (); size_t classNameLen = PL_strlen (className); char *buf = (char *) malloc (prefixLen + classNameLen + 1); if (!buf) abort (); nsresult rv; PL_strcpy (buf, prefix); PL_strcat (buf, className); if (PL_strncmp (className, modulePrefix, modulePrefixLen) == 0) { unsigned i; buf[prefixLen + 5] = ':'; for (i = modulePrefixLen; i < classNameLen; i++) { unsigned pos = prefixLen + i; if (buf[pos] == '/') buf[pos] = '.'; } } nsCOMPtr<nsIComponentManager> compMgr; NS_GetComponentManager (getter_AddRefs (compMgr)); if (!compMgr) abort (); nsCOMPtr<nsIComponentManagerObsolete> compMgrO = do_QueryInterface (compMgr); rv = compMgrO->ContractIDToClassID (buf, cClass); free (buf); if (NS_FAILED (rv)) abort (); return (COMclass) cClass; }
/* nsISupports createInstance (); */ NS_IMETHODIMP nsJSCID::CreateInstance(nsISupports **_retval) { if(!mDetails.IsValid()) return NS_ERROR_XPC_BAD_CID; nsXPConnect* xpc = nsXPConnect::GetXPConnect(); if(!xpc) return NS_ERROR_UNEXPECTED; nsAXPCNativeCallContext *ccxp = nsnull; xpc->GetCurrentNativeCallContext(&ccxp); if(!ccxp) return NS_ERROR_UNEXPECTED; PRUint32 argc; jsval * argv; jsval * vp; JSContext* cx; JSObject* obj; ccxp->GetJSContext(&cx); ccxp->GetArgc(&argc); ccxp->GetArgvPtr(&argv); ccxp->GetRetValPtr(&vp); nsCOMPtr<nsIXPConnectWrappedNative> wrapper; ccxp->GetCalleeWrapper(getter_AddRefs(wrapper)); wrapper->GetJSObject(&obj); // Do the security check if necessary XPCContext* xpcc = XPCContext::GetXPCContext(cx); nsIXPCSecurityManager* sm; sm = xpcc->GetAppropriateSecurityManager( nsIXPCSecurityManager::HOOK_CREATE_INSTANCE); if(sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) { NS_ASSERTION(JS_IsExceptionPending(cx), "security manager vetoed CreateInstance without setting exception"); return NS_OK; } // If an IID was passed in then use it const nsID* iid = GetIIDArg(argc, argv, cx); if (!iid) return NS_ERROR_XPC_BAD_IID; nsCOMPtr<nsIComponentManager> compMgr; nsresult rv = NS_GetComponentManager(getter_AddRefs(compMgr)); if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED; nsCOMPtr<nsISupports> inst; rv = compMgr->CreateInstance(mDetails.ID(), nsnull, *iid, getter_AddRefs(inst)); NS_ASSERTION(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!"); if(NS_FAILED(rv) || !inst) return NS_ERROR_XPC_CI_RETURNED_FAILURE; JSObject* instJSObj; nsCOMPtr<nsIXPConnectJSObjectHolder> holder; rv = xpc->WrapNative(cx, obj, inst, *iid, getter_AddRefs(holder)); if(NS_FAILED(rv) || !holder || NS_FAILED(holder->GetJSObject(&instJSObj))) return NS_ERROR_XPC_CANT_CREATE_WN; *vp = OBJECT_TO_JSVAL(instJSObj); ccxp->SetReturnValueWasSet(JS_TRUE); return NS_OK; }
int main(int argc, char *argv[]) { /* * Check that PRUnichar is equal in size to what compiler composes L"" * strings from; otherwise NS_LITERAL_STRING macros won't work correctly * and we will get a meaningless SIGSEGV. This, of course, must be checked * at compile time in xpcom/string/nsTDependentString.h, but XPCOM lacks * compile-time assert macros and I'm not going to add them now. */ if (sizeof(PRUnichar) != sizeof(wchar_t)) { printf("Error: sizeof(PRUnichar) {%lu} != sizeof(wchar_t) {%lu}!\n" "Probably, you forgot the -fshort-wchar compiler option.\n", (unsigned long) sizeof(PRUnichar), (unsigned long) sizeof(wchar_t)); return -1; } nsresult rc; /* * This is the standard XPCOM init procedure. * What we do is just follow the required steps to get an instance * of our main interface, which is IVirtualBox. */ #if defined(XPCOM_GLUE) XPCOMGlueStartup(nsnull); #endif /* * Note that we scope all nsCOMPtr variables in order to have all XPCOM * objects automatically released before we call NS_ShutdownXPCOM at the * end. This is an XPCOM requirement. */ { nsCOMPtr<nsIServiceManager> serviceManager; rc = NS_InitXPCOM2(getter_AddRefs(serviceManager), nsnull, nsnull); if (NS_FAILED(rc)) { printf("Error: XPCOM could not be initialized! rc=0x%x\n", rc); return -1; } #if 0 /* * Register our components. This step is only necessary if this executable * implements XPCOM components itself which is not the case for this * simple example. */ nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(serviceManager); if (!registrar) { printf("Error: could not query nsIComponentRegistrar interface!\n"); return -1; } registrar->AutoRegister(nsnull); #endif /* * Make sure the main event queue is created. This event queue is * responsible for dispatching incoming XPCOM IPC messages. The main * thread should run this event queue's loop during lengthy non-XPCOM * operations to ensure messages from the VirtualBox server and other * XPCOM IPC clients are processed. This use case doesn't perform such * operations so it doesn't run the event loop. */ nsCOMPtr<nsIEventQueue> eventQ; rc = NS_GetMainEventQ(getter_AddRefs (eventQ)); if (NS_FAILED(rc)) { printf("Error: could not get main event queue! rc=%08X\n", rc); return -1; } /* * Now XPCOM is ready and we can start to do real work. * IVirtualBox is the root interface of VirtualBox and will be * retrieved from the XPCOM component manager. We use the * XPCOM provided smart pointer nsCOMPtr for all objects because * that's very convenient and removes the need deal with reference * counting and freeing. */ nsCOMPtr<nsIComponentManager> manager; rc = NS_GetComponentManager (getter_AddRefs (manager)); if (NS_FAILED(rc)) { printf("Error: could not get component manager! rc=%08X\n", rc); return -1; } nsCOMPtr<IVirtualBox> virtualBox; rc = manager->CreateInstanceByContractID (NS_VIRTUALBOX_CONTRACTID, nsnull, NS_GET_IID(IVirtualBox), getter_AddRefs(virtualBox)); if (NS_FAILED(rc)) { printf("Error, could not instantiate VirtualBox object! rc=0x%x\n", rc); return -1; } printf("VirtualBox object created\n"); //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// listVMs(virtualBox); createVM(virtualBox); //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /* this is enough to free the IVirtualBox instance -- smart pointers rule! */ virtualBox = nsnull; /* * Process events that might have queued up in the XPCOM event * queue. If we don't process them, the server might hang. */ eventQ->ProcessPendingEvents(); } /* * Perform the standard XPCOM shutdown procedure. */ NS_ShutdownXPCOM(nsnull); #if defined(XPCOM_GLUE) XPCOMGlueShutdown(); #endif printf("Done!\n"); return 0; }
/** * Create a sample VM * * @param virtualBox VirtualBox instance object. */ void createVM(IVirtualBox *virtualBox) { nsresult rc; /* * First create a unnamed new VM. It will be unconfigured and not be saved * in the configuration until we explicitely choose to do so. */ nsCOMPtr<IMachine> machine; rc = virtualBox->CreateMachine(NULL, /* settings file */ NS_LITERAL_STRING("A brand new name").get(), 0, nsnull, /* groups (safearray)*/ nsnull, /* ostype */ nsnull, /* create flags */ getter_AddRefs(machine)); if (NS_FAILED(rc)) { printf("Error: could not create machine! rc=%08X\n", rc); return; } /* * Set some properties */ /* alternative to illustrate the use of string classes */ rc = machine->SetName(NS_ConvertUTF8toUTF16("A new name").get()); rc = machine->SetMemorySize(128); /* * Now a more advanced property -- the guest OS type. This is * an object by itself which has to be found first. Note that we * use the ID of the guest OS type here which is an internal * representation (you can find that by configuring the OS type of * a machine in the GUI and then looking at the <Guest ostype=""/> * setting in the XML file. It is also possible to get the OS type from * its description (win2k would be "Windows 2000") by getting the * guest OS type collection and enumerating it. */ nsCOMPtr<IGuestOSType> osType; rc = virtualBox->GetGuestOSType(NS_LITERAL_STRING("win2k").get(), getter_AddRefs(osType)); if (NS_FAILED(rc)) { printf("Error: could not find guest OS type! rc=%08X\n", rc); } else { machine->SetOSTypeId (NS_LITERAL_STRING("win2k").get()); } /* * Register the VM. Note that this call also saves the VM config * to disk. It is also possible to save the VM settings but not * register the VM. * * Also note that due to current VirtualBox limitations, the machine * must be registered *before* we can attach hard disks to it. */ rc = virtualBox->RegisterMachine(machine); if (NS_FAILED(rc)) { printf("Error: could not register machine! rc=%08X\n", rc); printErrorInfo(); return; } /* * In order to manipulate the registered machine, we must open a session * for that machine. Do it now. */ nsCOMPtr<ISession> session; { nsCOMPtr<nsIComponentManager> manager; rc = NS_GetComponentManager (getter_AddRefs (manager)); if (NS_FAILED(rc)) { printf("Error: could not get component manager! rc=%08X\n", rc); return; } rc = manager->CreateInstanceByContractID (NS_SESSION_CONTRACTID, nsnull, NS_GET_IID(ISession), getter_AddRefs(session)); if (NS_FAILED(rc)) { printf("Error, could not instantiate session object! rc=0x%x\n", rc); return; } rc = machine->LockMachine(session, LockType_Write); if (NS_FAILED(rc)) { printf("Error, could not lock the machine for the session! rc=0x%x\n", rc); return; } /* * After the machine is registered, the initial machine object becomes * immutable. In order to get a mutable machine object, we must query * it from the opened session object. */ rc = session->GetMachine(getter_AddRefs(machine)); if (NS_FAILED(rc)) { printf("Error, could not get machine session! rc=0x%x\n", rc); return; } } /* * Create a virtual harddisk */ nsCOMPtr<IMedium> hardDisk = 0; rc = virtualBox->CreateHardDisk(NS_LITERAL_STRING("VDI").get(), NS_LITERAL_STRING("TestHardDisk.vdi").get(), getter_AddRefs(hardDisk)); if (NS_FAILED(rc)) { printf("Failed creating a hard disk object! rc=%08X\n", rc); } else { /* * We have only created an object so far. No on disk representation exists * because none of its properties has been set so far. Let's continue creating * a dynamically expanding image. */ nsCOMPtr <IProgress> progress; com::SafeArray<MediumVariant_T> mediumVariant(sizeof(MediumVariant_T)*8); mediumVariant.push_back(MediumVariant_Standard); rc = hardDisk->CreateBaseStorage(100, // size in megabytes ComSafeArrayAsInParam(mediumVariant), getter_AddRefs(progress)); // optional progress object if (NS_FAILED(rc)) { printf("Failed creating hard disk image! rc=%08X\n", rc); } else { /* * Creating the image is done in the background because it can take quite * some time (at least fixed size images). We have to wait for its completion. * Here we wait forever (timeout -1) which is potentially dangerous. */ rc = progress->WaitForCompletion(-1); PRInt32 resultCode; progress->GetResultCode(&resultCode); if (NS_FAILED(rc) || NS_FAILED(resultCode)) { printf("Error: could not create hard disk! rc=%08X\n", NS_FAILED(rc) ? rc : resultCode); } else { /* * Now that it's created, we can assign it to the VM. */ rc = machine->AttachDevice(NS_LITERAL_STRING("IDE Controller").get(), // controller identifier 0, // channel number on the controller 0, // device number on the controller DeviceType_HardDisk, hardDisk); if (NS_FAILED(rc)) { printf("Error: could not attach hard disk! rc=%08X\n", rc); } } } } /* * It's got a hard disk but that one is new and thus not bootable. Make it * boot from an ISO file. This requires some processing. First the ISO file * has to be registered and then mounted to the VM's DVD drive and selected * as the boot device. */ nsCOMPtr<IMedium> dvdImage; rc = virtualBox->OpenMedium(NS_LITERAL_STRING("/home/vbox/isos/winnt4ger.iso").get(), DeviceType_DVD, AccessMode_ReadOnly, false /* fForceNewUuid */, getter_AddRefs(dvdImage)); if (NS_FAILED(rc)) printf("Error: could not open CD image! rc=%08X\n", rc); else { /* * Now assign it to our VM */ rc = machine->MountMedium(NS_LITERAL_STRING("IDE Controller").get(), // controller identifier 2, // channel number on the controller 0, // device number on the controller dvdImage, PR_FALSE); // aForce if (NS_FAILED(rc)) { printf("Error: could not mount ISO image! rc=%08X\n", rc); } else { /* * Last step: tell the VM to boot from the CD. */ rc = machine->SetBootOrder (1, DeviceType::DVD); if (NS_FAILED(rc)) { printf("Could not set boot device! rc=%08X\n", rc); } } } /* * Save all changes we've just made. */ rc = machine->SaveSettings(); if (NS_FAILED(rc)) { printf("Could not save machine settings! rc=%08X\n", rc); } /* * It is always important to close the open session when it becomes not * necessary any more. */ session->UnlockMachine(); }
NS_IMETHODIMP mozJSComponentLoader::LoadModule(nsILocalFile* aComponentFile, nsIModule* *aResult) { nsresult rv; nsCAutoString leafName; aComponentFile->GetNativeLeafName(leafName); if (!StringTail(leafName, 3).LowerCaseEqualsLiteral(".js")) return NS_ERROR_INVALID_ARG; if (!mInitialized) { rv = ReallyInit(); if (NS_FAILED(rv)) return rv; } nsCOMPtr<nsIHashable> lfhash(do_QueryInterface(aComponentFile)); if (!lfhash) { NS_ERROR("nsLocalFile not implementing nsIHashable"); return NS_NOINTERFACE; } ModuleEntry* mod; if (mModules.Get(lfhash, &mod)) { NS_ASSERTION(mod->module, "Bad hashtable data!"); NS_ADDREF(*aResult = mod->module); return NS_OK; } nsAutoPtr<ModuleEntry> entry(new ModuleEntry); if (!entry) return NS_ERROR_OUT_OF_MEMORY; rv = GlobalForLocation(aComponentFile, &entry->global, &entry->location); if (NS_FAILED(rv)) { #ifdef DEBUG_shaver fprintf(stderr, "GlobalForLocation failed!\n"); #endif return rv; } nsCOMPtr<nsIXPConnect> xpc = do_GetService(kXPConnectServiceContractID, &rv); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIComponentManager> cm; rv = NS_GetComponentManager(getter_AddRefs(cm)); if (NS_FAILED(rv)) return rv; JSCLContextHelper cx(mContext); JSObject* cm_jsobj; nsCOMPtr<nsIXPConnectJSObjectHolder> cm_holder; rv = xpc->WrapNative(cx, entry->global, cm, NS_GET_IID(nsIComponentManager), getter_AddRefs(cm_holder)); if (NS_FAILED(rv)) { #ifdef DEBUG_shaver fprintf(stderr, "WrapNative(%p,%p,nsIComponentManager) failed: %x\n", (void *)(JSContext*)cx, (void *)mCompMgr, rv); #endif return rv; } rv = cm_holder->GetJSObject(&cm_jsobj); if (NS_FAILED(rv)) { #ifdef DEBUG_shaver fprintf(stderr, "GetJSObject of ComponentManager failed\n"); #endif return rv; } JSObject* file_jsobj; nsCOMPtr<nsIXPConnectJSObjectHolder> file_holder; rv = xpc->WrapNative(cx, entry->global, aComponentFile, NS_GET_IID(nsIFile), getter_AddRefs(file_holder)); if (NS_FAILED(rv)) { return rv; } rv = file_holder->GetJSObject(&file_jsobj); if (NS_FAILED(rv)) { return rv; } JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter); jsval argv[2], retval, NSGetModule_val; if (!JS_GetProperty(cx, entry->global, "NSGetModule", &NSGetModule_val) || JSVAL_IS_VOID(NSGetModule_val)) { return NS_ERROR_FAILURE; } if (JS_TypeOfValue(cx, NSGetModule_val) != JSTYPE_FUNCTION) { nsCAutoString path; aComponentFile->GetNativePath(path); JS_ReportError(cx, "%s has NSGetModule property that is not a function", path.get()); return NS_ERROR_FAILURE; } argv[0] = OBJECT_TO_JSVAL(cm_jsobj); argv[1] = OBJECT_TO_JSVAL(file_jsobj); if (!JS_CallFunctionValue(cx, entry->global, NSGetModule_val, 2, argv, &retval)) { return NS_ERROR_FAILURE; } #ifdef DEBUG_shaver_off JSString *s = JS_ValueToString(cx, retval); fprintf(stderr, "mJCL: %s::NSGetModule returned %s\n", registryLocation, JS_GetStringBytes(s)); #endif JSObject *jsModuleObj; if (!JS_ValueToObject(cx, retval, &jsModuleObj)) { /* XXX report error properly */ return NS_ERROR_FAILURE; } rv = xpc->WrapJS(cx, jsModuleObj, NS_GET_IID(nsIModule), getter_AddRefs(entry->module)); if (NS_FAILED(rv)) { /* XXX report error properly */ #ifdef DEBUG fprintf(stderr, "mJCL: couldn't get nsIModule from jsval\n"); #endif return rv; } // Cache this module for later if (!mModules.Put(lfhash, entry)) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(*aResult = entry->module); // The hash owns the ModuleEntry now, forget about it entry.forget(); return NS_OK; }
/** entry point */ int main(int argc, char *argv[]) { const char *uuid = NULL; int c; int listHostModes = 0; int quit = 0; const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "startvm", required_argument, NULL, 's' }, { "fixedres", required_argument, NULL, 'f' }, { "listhostmodes", no_argument, NULL, 'l' }, { "scale", no_argument, NULL, 'c' } }; printf("VirtualBox DirectFB GUI built %s %s\n" "(C) 2004-" VBOX_C_YEAR " " VBOX_VENDOR "\n" "(C) 2004-2005 secunet Security Networks AG\n", __DATE__, __TIME__); for (;;) { c = getopt_long(argc, argv, "s:", options, NULL); if (c == -1) break; switch (c) { case 'h': { showusage(); exit(0); break; } case 's': { // UUID as string, parse it RTUUID buuid; if (!RT_SUCCESS(RTUuidFromStr((PRTUUID)&buuid, optarg))) { printf("Error, invalid UUID format given!\n"); showusage(); exit(-1); } uuid = optarg; break; } case 'f': { if (sscanf(optarg, "%ux%ux%u", &fixedVideoMode.width, &fixedVideoMode.height, &fixedVideoMode.bpp) != 3) { printf("Error, invalid resolution argument!\n"); showusage(); exit(-1); } useFixedVideoMode = 1; break; } case 'l': { listHostModes = 1; break; } case 'c': { scaleGuest = 1; break; } default: break; } } // check if we got a UUID if (!uuid) { printf("Error, no UUID given!\n"); showusage(); exit(-1); } /** * XPCOM setup */ nsresult rc; /* * Note that we scope all nsCOMPtr variables in order to have all XPCOM * objects automatically released before we call NS_ShutdownXPCOM at the * end. This is an XPCOM requirement. */ { nsCOMPtr<nsIServiceManager> serviceManager; rc = NS_InitXPCOM2(getter_AddRefs(serviceManager), nsnull, nsnull); if (NS_FAILED(rc)) { printf("Error: XPCOM could not be initialized! rc=0x%x\n", rc); exit(-1); } // register our component nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(serviceManager); if (!registrar) { printf("Error: could not query nsIComponentRegistrar interface!\n"); exit(-1); } registrar->AutoRegister(nsnull); /* * Make sure the main event queue is created. This event queue is * responsible for dispatching incoming XPCOM IPC messages. The main * thread should run this event queue's loop during lengthy non-XPCOM * operations to ensure messages from the VirtualBox server and other * XPCOM IPC clients are processed. This use case doesn't perform such * operations so it doesn't run the event loop. */ nsCOMPtr<nsIEventQueue> eventQ; rc = NS_GetMainEventQ(getter_AddRefs (eventQ)); if (NS_FAILED(rc)) { printf("Error: could not get main event queue! rc=%08X\n", rc); return -1; } /* * Now XPCOM is ready and we can start to do real work. * IVirtualBox is the root interface of VirtualBox and will be * retrieved from the XPCOM component manager. We use the * XPCOM provided smart pointer nsCOMPtr for all objects because * that's very convenient and removes the need deal with reference * counting and freeing. */ nsCOMPtr<nsIComponentManager> manager; rc = NS_GetComponentManager (getter_AddRefs (manager)); if (NS_FAILED(rc)) { printf("Error: could not get component manager! rc=%08X\n", rc); exit(-1); } nsCOMPtr<IVirtualBox> virtualBox; rc = manager->CreateInstanceByContractID(NS_VIRTUALBOX_CONTRACTID, nsnull, NS_GET_IID(IVirtualBox), getter_AddRefs(virtualBox)); if (NS_FAILED(rc)) { printf("Error, could not instantiate object! rc=0x%x\n", rc); exit(-1); } nsCOMPtr<ISession> session; rc = manager->CreateInstance(CLSID_Session, nsnull, NS_GET_IID(ISession), getter_AddRefs(session)); if (NS_FAILED(rc)) { printf("Error: could not instantiate Session object! rc = %08X\n", rc); exit(-1); } // open session for this VM rc = virtualBox->OpenSession(session, NS_ConvertUTF8toUTF16(uuid).get()); if (NS_FAILED(rc)) { printf("Error: given machine not found!\n"); exit(-1); } nsCOMPtr<IMachine> machine; session->GetMachine(getter_AddRefs(machine)); if (!machine) { printf("Error: given machine not found!\n"); exit(-1); } nsCOMPtr<IConsole> console; session->GetConsole(getter_AddRefs(console)); if (!console) { printf("Error: cannot get console!\n"); exit(-1); } nsCOMPtr<IDisplay> display; console->GetDisplay(getter_AddRefs(display)); if (!display) { printf("Error: could not get display object!\n"); exit(-1); } nsCOMPtr<IKeyboard> keyboard; nsCOMPtr<IMouse> mouse; VBoxDirectFB *frameBuffer = NULL; /** * Init DirectFB */ IDirectFB *dfb = NULL; IDirectFBSurface *surface = NULL; IDirectFBInputDevice *dfbKeyboard = NULL; IDirectFBInputDevice *dfbMouse = NULL; IDirectFBEventBuffer *dfbEventBuffer = NULL; DFBSurfaceDescription dsc; int screen_width, screen_height; DFBCHECK(DirectFBInit(&argc, &argv)); DFBCHECK(DirectFBCreate(&dfb)); DFBCHECK(dfb->SetCooperativeLevel(dfb, DFSCL_FULLSCREEN)); // populate our structure of supported video modes DFBCHECK(dfb->EnumVideoModes(dfb, enumVideoModesHandler, NULL)); if (listHostModes) { printf("*****************************************************\n"); printf("Number of available host video modes: %u\n", numVideoModes); for (uint32_t i = 0; i < numVideoModes; i++) { printf("Mode %u: xres = %u, yres = %u, bpp = %u\n", i, videoModes[i].width, videoModes[i].height, videoModes[i].bpp); } printf("Note: display modes with bpp < have been filtered out\n"); printf("*****************************************************\n"); goto Leave; } if (useFixedVideoMode) { int32_t bestVideoMode = getBestVideoMode(fixedVideoMode.width, fixedVideoMode.height, fixedVideoMode.bpp); // validate the fixed mode if ((bestVideoMode == -1) || ((fixedVideoMode.width != videoModes[bestVideoMode].width) || (fixedVideoMode.height != videoModes[bestVideoMode].height) || (fixedVideoMode.bpp != videoModes[bestVideoMode].bpp))) { printf("Error: the specified fixed video mode is not available!\n"); exit(-1); } } else { initialVideoMode = getBestVideoMode(640, 480, 16); if (initialVideoMode == -1) { printf("Error: initial video mode 640x480x16 is not available!\n"); exit(-1); } } dsc.flags = DSDESC_CAPS; dsc.caps = DSCAPS_PRIMARY; DFBCHECK(dfb->CreateSurface(dfb, &dsc, &surface)); DFBCHECK(surface->Clear(surface, 0, 0, 0, 0)); DFBCHECK(surface->GetSize(surface, &screen_width, &screen_height)); DFBCHECK(dfb->GetInputDevice(dfb, DIDID_KEYBOARD, &dfbKeyboard)); DFBCHECK(dfbKeyboard->CreateEventBuffer(dfbKeyboard, &dfbEventBuffer)); DFBCHECK(dfb->GetInputDevice(dfb, DIDID_MOUSE, &dfbMouse)); DFBCHECK(dfbMouse->AttachEventBuffer(dfbMouse, dfbEventBuffer)); if (useFixedVideoMode) { printf("Information: setting video mode to %ux%ux%u\n", fixedVideoMode.width, fixedVideoMode.height, fixedVideoMode.bpp); DFBCHECK(dfb->SetVideoMode(dfb, fixedVideoMode.width, fixedVideoMode.height, fixedVideoMode.bpp)); } else { printf("Information: starting with default video mode %ux%ux%u\n", videoModes[initialVideoMode].width, videoModes[initialVideoMode].height, videoModes[initialVideoMode].bpp); DFBCHECK(dfb->SetVideoMode(dfb, videoModes[initialVideoMode].width, videoModes[initialVideoMode].height, videoModes[initialVideoMode].bpp)); } // register our framebuffer frameBuffer = new VBoxDirectFB(dfb, surface); display->SetFramebuffer(0, frameBuffer); /** * Start the VM execution thread */ console->PowerUp(NULL); console->GetKeyboard(getter_AddRefs(keyboard)); console->GetMouse(getter_AddRefs(mouse)); /** * Main event loop */ #define MAX_KEYEVENTS 10 PRInt32 keyEvents[MAX_KEYEVENTS]; int numKeyEvents; while (!quit) { DFBInputEvent event; numKeyEvents = 0; DFBCHECK(dfbEventBuffer->WaitForEvent(dfbEventBuffer)); while (dfbEventBuffer->GetEvent(dfbEventBuffer, DFB_EVENT(&event)) == DFB_OK) { int mouseXDelta = 0; int mouseYDelta = 0; int mouseZDelta = 0; switch (event.type) { #define QUEUEEXT() keyEvents[numKeyEvents++] = 0xe0 #define QUEUEKEY(scan) keyEvents[numKeyEvents++] = scan | (event.type == DIET_KEYRELEASE ? 0x80 : 0x00) #define QUEUEKEYRAW(scan) keyEvents[numKeyEvents++] = scan case DIET_KEYPRESS: case DIET_KEYRELEASE: { // @@@AH development hack to get out of it! if ((event.key_id == DIKI_ESCAPE) && (event.modifiers & (DIMM_CONTROL | DIMM_ALT))) quit = 1; if (numKeyEvents < MAX_KEYEVENTS) { //printf("%s: key_code: 0x%x\n", event.type == DIET_KEYPRESS ? "DIET_KEYPRESS" : "DIET_KEYRELEASE", event.key_code); switch ((uint32_t)event.key_id) { case DIKI_CONTROL_R: QUEUEEXT(); QUEUEKEY(0x1d); break; case DIKI_INSERT: QUEUEEXT(); QUEUEKEY(0x52); break; case DIKI_DELETE: QUEUEEXT(); QUEUEKEY(0x53); break; case DIKI_HOME: QUEUEEXT(); QUEUEKEY(0x47); break; case DIKI_END: QUEUEEXT(); QUEUEKEY(0x4f); break; case DIKI_PAGE_UP: QUEUEEXT(); QUEUEKEY(0x49); break; case DIKI_PAGE_DOWN: QUEUEEXT(); QUEUEKEY(0x51); break; case DIKI_LEFT: QUEUEEXT(); QUEUEKEY(0x4b); break; case DIKI_RIGHT: QUEUEEXT(); QUEUEKEY(0x4d); break; case DIKI_UP: QUEUEEXT(); QUEUEKEY(0x48); break; case DIKI_DOWN: QUEUEEXT(); QUEUEKEY(0x50); break; case DIKI_KP_DIV: QUEUEEXT(); QUEUEKEY(0x35); break; case DIKI_KP_ENTER: QUEUEEXT(); QUEUEKEY(0x1c); break; case DIKI_PRINT: // the break code is inverted! if (event.type == DIET_KEYPRESS) { QUEUEEXT(); QUEUEKEY(0x2a); QUEUEEXT(); QUEUEKEY(0x37); } else { QUEUEEXT(); QUEUEKEY(0x37); QUEUEEXT(); QUEUEKEY(0x2a); } break; case DIKI_PAUSE: // This is a super weird key. No break code and a 6 byte // combination. if (event.type == DIET_KEYPRESS) { QUEUEKEY(0xe1); QUEUEKEY(0x1d); QUEUEKEY(0x45); QUEUEKEY(0xe1); QUEUEKEY(0x9d); QUEUEKEY(0xc5); } break; case DIKI_META_L: // the left Windows logo is a bit different if (event.type == DIET_KEYPRESS) { QUEUEEXT(); QUEUEKEYRAW(0x1f); } else { QUEUEEXT(); QUEUEKEYRAW(0xf0); QUEUEKEYRAW(0x1f); } break; case DIKI_META_R: // the right Windows logo is a bit different if (event.type == DIET_KEYPRESS) { QUEUEEXT(); QUEUEKEYRAW(0x27); } else { QUEUEEXT(); QUEUEKEYRAW(0xf0); QUEUEKEYRAW(0x27); } break; case DIKI_SUPER_R: // the popup menu is a bit different if (event.type == DIET_KEYPRESS) { QUEUEEXT(); QUEUEKEYRAW(0x2f); } else { QUEUEEXT(); QUEUEKEYRAW(0xf0); QUEUEKEYRAW(0x2f); } break; default: // check if we got a hardware scancode if (event.key_code != -1) { // take the scancode from DirectFB as is QUEUEKEY(event.key_code); } else { // XXX need extra handling! } } } break; } #undef QUEUEEXT #undef QUEUEKEY #undef QUEUEKEYRAW case DIET_AXISMOTION: { switch (event.axis) { case DIAI_X: mouseXDelta += event.axisrel; break; case DIAI_Y: mouseYDelta += event.axisrel; break; case DIAI_Z: mouseZDelta += event.axisrel; break; default: break; } // fall through } case DIET_BUTTONPRESS: // fall through; case DIET_BUTTONRELEASE: { int buttonState = 0; if (event.buttons & DIBM_LEFT) buttonState |= MouseButtonState::LeftButton; if (event.buttons & DIBM_RIGHT) buttonState |= MouseButtonState::RightButton; if (event.buttons & DIBM_MIDDLE) buttonState |= MouseButtonState::MiddleButton; mouse->PutMouseEvent(mouseXDelta, mouseYDelta, mouseZDelta, buttonState); break; } default: break; } } // did we get any keyboard events? if (numKeyEvents > 0) { uint32_t codesStored; if (numKeyEvents > 1) { keyboard->PutScancodes(numKeyEvents, keyEvents, &codesStored); } else { keyboard->PutScancode(keyEvents[0]); } } } { nsCOMPtr<IProgress> progress; console->PowerDown(getter_AddRefs(progress)); progress->WaitForCompletion(-1); } } Leave: /* * Perform the standard XPCOM shutdown procedure. */ NS_ShutdownXPCOM(nsnull); return 0; }