#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

Reply via email to