#include <stdio.h> #include <windows.h> #include <fcntl.h> #include <io.h> #include <ios> #include <math.h>
#include <nsComponentManagerUtils.h> #include <nsServiceManagerUtils.h> #include <nsIInterfaceInfoManager.h> #include <nsIInterfaceInfo.h> #include <nsIXPConnect.h> #include <jsapi.h> using namespace mozilla; nsCOMPtr<nsIInterfaceInfoManager> iim = do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID); nsCOMPtr<nsIXPConnect> xpconnect = do_GetService(nsIXPConnect::GetCID()); #define SHELL_EXPORT extern "C" NS_EXPORT // https://github.com/ivansafrin/Polycode/blob/master/Core/Contents/PolycodeView/MSVC/PolycodeView.cpp#L16 SHELL_EXPORT void OpenConsole(bool create) { int outHandle, errHandle, inHandle; FILE *outFile, *errFile, *inFile; bool hasConsole = AttachConsole(ATTACH_PARENT_PROCESS); if (!hasConsole) { if (!create) { return; } FreeConsole(); AllocConsole(); } CONSOLE_SCREEN_BUFFER_INFO coninfo; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); coninfo.dwSize.Y = 9999; SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); outHandle = _open_osfhandle((intptr_t)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT); errHandle = _open_osfhandle((intptr_t)GetStdHandle(STD_ERROR_HANDLE), _O_TEXT); inHandle = _open_osfhandle((intptr_t)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT); outFile = _fdopen(outHandle, "w"); errFile = _fdopen(errHandle, "w"); inFile = _fdopen(inHandle, "r"); *stdout = *outFile; *stderr = *errFile; *stdin = *inFile; setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); setvbuf(stdin, NULL, _IONBF, 0); std::ios::sync_with_stdio(); } struct thread_data { uint32_t sleep_time; int32_t exit_code; thread_data(uint32_t sleep_time, int32_t exit_code) : sleep_time(sleep_time), exit_code(exit_code) { } }; DWORD WINAPI thread_func(LPVOID lpParameter) { thread_data *td = (thread_data*)lpParameter; Sleep(td->sleep_time); ExitProcess(td->exit_code); return 0; } SHELL_EXPORT void ForceExit(uint32_t sleep_time, int32_t exit_code) { CreateThread(NULL, 0, thread_func, new thread_data(sleep_time, exit_code), 0, 0); } SHELL_EXPORT uint32_t CopyStringWithFree(char* sourceString, char*destString, uint32_t destLength) { uint32_t tmpLength = strlen(sourceString); if (tmpLength <= destLength) { memcpy(destString, sourceString, tmpLength); } NS_Free(sourceString); return tmpLength; } SHELL_EXPORT void XPCOM_GetIIDForName(char* name, nsIID* iid) { nsIID* newIID; *iid = { 0 }; if (iim->GetIIDForName(name, &newIID) == NS_OK) { *iid = *newIID; } } SHELL_EXPORT uint32_t XPCOM_GetNameForIID(char* name, uint32_t length, nsIID* iid) { *name = '\0'; char* tmpName; if (iim->GetNameForIID(iid, &tmpName) == NS_OK) { return CopyStringWithFree(tmpName, name, length); } return 0; } SHELL_EXPORT void* XPCOM_GetInterfaceInfo(nsIID *iid) { nsIInterfaceInfo *info = nullptr; if (iim->GetInfoForIID(iid, &info) != NS_OK) { info = nullptr; } return info; } SHELL_EXPORT uint16_t XPCOM_GetInterfaceMethodCount(nsIInterfaceInfo *info) { uint16_t result = 0; if (info && info->GetMethodCount(&result) == NS_OK) { return result; } return 0; } SHELL_EXPORT uint16_t XPCOM_GetInterfaceConstantCount(nsIInterfaceInfo *info) { uint16_t result = 0; if (info && info->GetConstantCount(&result) == NS_OK) { return result; } return 0; } // TODO: implement the full XPCOM_GetInterfaceConstant */ SHELL_EXPORT uint32_t XPCOM_GetInterfaceConstant(nsIInterfaceInfo *info, uint16_t index, char* name, uint32_t length, int64_t* valuePtr) { uint16_t result = 0; char* tmpName; /* TODO: Retrieve the JSContext for the current thread */ JSContext* cx = xpconnect->GetCurrentJSContext(); JS::RootedValue rvalue(cx); JS::MutableHandleValue mvalue(&rvalue); if (info && info->GetConstant(index, mvalue, &tmpName) == NS_OK) { JS::Value * value = &mvalue.get(); if (value->isNumber()) { *valuePtr = value->payloadAsRawUint32(); } else if (value->isInt32()) { *valuePtr = value->getInt32Ref(); } return CopyStringWithFree(tmpName, name, length); } return 0; } SHELL_EXPORT void* XPCOM_GetClassObject(char* contractID, nsIID* iid) { void *result = nullptr; if (CallGetClassObject(contractID, *iid, &result) != NS_OK) { result = nullptr; } return result; } SHELL_EXPORT void* XPCOM_GetClassObjectCID(nsCID *cid, nsIID* iid) { void *result = nullptr; if (CallGetClassObject(*cid, *iid, &result) != NS_OK) { result = nullptr; } return result; } SHELL_EXPORT void* XPCOM_CreateInstance(char* contractID) { nsISupports* result = nullptr; if (CallCreateInstance<nsISupports>(contractID, &result) != NS_OK) { result = nullptr; } if (result != nullptr) { result->AddRef(); } return result; } SHELL_EXPORT void* XPCOM_CreateInstanceCID(nsCID* cid) { nsISupports* result = nullptr; if (CallGetService(*cid, NS_ISUPPORTS_IID, reinterpret_cast<void**>(&result)) != NS_OK) { result = nullptr; } if (result != nullptr) { result->AddRef(); } return result; } SHELL_EXPORT void* XPCOM_GetService(char* contractID) { nsISupports* result = nullptr; if (CallGetService(contractID, NS_ISUPPORTS_IID, reinterpret_cast<void**>(&result)) != NS_OK) { result = nullptr; } return result; } SHELL_EXPORT void* XPCOM_GetServiceCID(nsCID* cid) { nsISupports* result = nullptr; if (CallGetService(*cid, NS_ISUPPORTS_IID, reinterpret_cast<void**>(&result)) != NS_OK) { result = nullptr; } return result; } SHELL_EXPORT void* XPCOM_QueryInterface(nsISupports* instance, nsIID *iid) { void *result = nullptr; if (instance->QueryInterface(*iid, &result) != NS_OK) { result = nullptr; } return result; } SHELL_EXPORT void XPCOM_AddRef(nsISupports* instance) { instance->AddRef(); } SHELL_EXPORT void XPCOM_Release(nsISupports* instance) { instance->Release(); } DWORD tId = 0; BOOL WINAPI DllMain(HINSTANCE aInstance, DWORD aReason, LPVOID aReserved) { switch (aReason) { case DLL_PROCESS_ATTACH: tId = TlsAlloc(); if (tId == 0xFFFFFFFF) return FALSE; break; case DLL_PROCESS_DETACH: TlsFree(tId); break; } return TRUE; } -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform