1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2026-01-05 18:13:38 +00:00

Merge branch 'Branch_pathfix'

This commit is contained in:
Bryan Roe
2020-05-17 18:08:55 -07:00
31 changed files with 2654 additions and 2130 deletions

View File

@@ -110,38 +110,15 @@ void ILibDuktape_ChildProcess_SubProcess_ExitHandler(ILibProcessPipe_Process sen
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
if (!ILibMemory_CanaryOK(p)) { return; }
#ifdef WIN32
if (duk_ctx_context_data(p->ctx)->apc_flags == 0 && p->dispatchFlags == 0)
{
// This method was called with an APC, but this thread was running an unknown alertable method when it was interrupted
// So we must unwind the stack, and use a non-apc method to re-dispatch to this thread, becuase we can't risk
// calling a winsock method, in case this thread was inside winsock when it was interrupted, because otherwise, it
// will corrupt memory, resulting in a possible crash.
//
// We had to do the APC first, becuase otherwise child_process.waitExit() will not work, becuase that method is blocking
// the event loop thread with an alertable wait object, so APC is the only way to propagate this event
p->exitCode = exitCode;
p->dispatchFlags = 1;
Duktape_RunOnEventLoop(p->chain, duk_ctx_nonce(p->ctx), p->ctx, ILibDuktape_ChildProcess_SubProcess_ExitHandler_sink1, NULL, p);
}
#endif
p->exitCode = exitCode;
p->childProcess = NULL;
duk_push_heapptr(p->ctx, p->subProcess); // [childProcess]
#ifdef WIN32
HANDLE exitptr = (HANDLE)Duktape_GetPointerProperty(p->ctx, -1, "\xFF_WaitExit");
if (exitptr != NULL)
{
SetEvent(exitptr);
}
#else
if (Duktape_GetIntPropertyValue(p->ctx, -1, "\xFF_WaitExit", 0) != 0)
{
ILibChain_EndContinue(Duktape_GetChain(p->ctx));
}
#endif
duk_get_prop_string(p->ctx, -1, "emit"); // [childProcess][emit]
duk_swap_top(p->ctx, -2); // [emit][this]
duk_push_string(p->ctx, "exit"); // [emit][this][exit]
@@ -185,6 +162,7 @@ duk_ret_t ILibDuktape_ChildProcess_Kill(duk_context *ctx)
}
duk_ret_t ILibDuktape_ChildProcess_waitExit(duk_context *ctx)
{
int timeout = duk_is_number(ctx, 0) ? duk_require_int(ctx, 0) : -1;
void *chain = Duktape_GetChain(ctx);
if (ILibIsChainBeingDestroyed(chain))
{
@@ -192,29 +170,23 @@ duk_ret_t ILibDuktape_ChildProcess_waitExit(duk_context *ctx)
}
duk_push_this(ctx); // [spawnedProcess]
char *_target = Duktape_GetStringPropertyValue(ctx, -1, "_target", NULL);
if (!ILibChain_IsLinkAlive(Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager)))
{
return(ILibDuktape_Error(ctx, "Cannot waitExit() because JS Engine is exiting"));
}
#ifdef WIN32
DWORD result;
HANDLE eptr = CreateEventA(NULL, TRUE, FALSE, NULL);
duk_push_pointer(ctx, (void*)eptr);
#else
duk_push_int(ctx, 1); // [spawnedProcess][flag]
#endif
duk_put_prop_string(ctx, -2, "\xFF_WaitExit"); // [spawnedProcess]
#ifdef WIN32
duk_ctx_context_data(ctx)->apc_flags = 1;
while ((result=WaitForSingleObjectEx(eptr, duk_is_number(ctx, 0) ? duk_require_int(ctx, 0) : INFINITE, TRUE)) != WAIT_OBJECT_0 && result != WAIT_TIMEOUT);
duk_ctx_context_data(ctx)->apc_flags = 0;
CloseHandle(eptr);
if (result == WAIT_TIMEOUT) { return(ILibDuktape_Error(ctx, "timeout")); }
#else
void *mods[] = { ILibGetBaseTimer(Duktape_GetChain(ctx)), Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager) };
ILibChain_Continue(chain, (ILibChain_Link**)mods, 2, -1);
#ifdef WIN32
HANDLE handles[] = { NULL, NULL, NULL, NULL, NULL };
ILibProcessPipe_Process p = Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Process);
ILibProcessPipe_Process_GetWaitHandles(p, &(handles[0]), &(handles[1]), &(handles[2]), &(handles[3]));
ILibChain_Continue(chain, (ILibChain_Link**)mods, 2, timeout, (HANDLE**)handles);
#else
ILibChain_Continue(chain, (ILibChain_Link**)mods, 2, timeout);
#endif
return(0);
@@ -432,6 +404,7 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
return(ILibDuktape_Error(ctx, "child_process.execFile(): Could not exec [%s]", target));
}
ILibDuktape_ChildProcess_SpawnedProcess_PUSH(ctx, p, callback);
duk_push_string(ctx, target); duk_put_prop_string(ctx, -2, "_target");
duk_push_pointer(ctx, manager); duk_put_prop_string(ctx, -2, ILibDuktape_ChildProcess_Manager);
return(1);
}

View File

@@ -160,6 +160,8 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteHandler_Process(ILibDuktap
extern int ILibDuktape_HECI_Debug;
#ifdef WIN32
BOOL ILibDuktape_HECI_Session_ReceiveSink(void *chain, HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user);
HANDLE ILibDuktape_HECI_windowsInit()
{
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetail = NULL;
@@ -284,7 +286,7 @@ void ILibDuktape_HECI_Session_EmitStreamReady(void *chain, void *session)
}
#ifdef WIN32
BOOL ILibDuktape_HECI_Session_WriteHandler_Ready(HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user)
BOOL ILibDuktape_HECI_Session_WriteHandler_Ready(void *chain, HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user)
{
if (errors != ILibWaitHandle_ErrorStatus_NONE) { return(FALSE); }
@@ -293,8 +295,8 @@ BOOL ILibDuktape_HECI_Session_WriteHandler_Ready(HANDLE event, ILibWaitHandle_Er
if (!ILibMemory_CanaryOK(session)) { return(FALSE); }
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->wv.hEvent);
ILibChain_RemoveWaitHandle(session->chain, session->wv.hEvent);
if (session->noPipelining == 0)
{
ILibDuktape_HECI_WriteState *state = (ILibDuktape_HECI_WriteState*)ILibQueue_DeQueue(session->PendingWrites);
@@ -378,7 +380,7 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteHandler_Process(ILibDuktap
{
// Not done writing
retVal = ILibTransport_DoneState_INCOMPLETE;
ILibProcessPipe_WaitHandle_Add(session->mgr, session->wv.hEvent, session, ILibDuktape_HECI_Session_WriteHandler_Ready);
ILibChain_AddWaitHandle(session->chain, session->wv.hEvent, -1, ILibDuktape_HECI_Session_WriteHandler_Ready, session);
}
else
{
@@ -471,7 +473,7 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteSink(ILibDuktape_DuplexStr
{
#if defined(WIN32)
state->returnIgnored = 1;
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_WriteHandler, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)state);
ILibDuktape_HECI_Session_WriteHandler((ULONG_PTR)state);
#elif defined(_POSIX)
if (ILibIsRunningOnChainThread(stream->readableStream->chain) != 0)
{
@@ -520,20 +522,6 @@ void ILibDuktape_HECI_Session_PauseSink(ILibDuktape_DuplexStream *sender, void *
UNREFERENCED_PARAMETER(user);
#endif
}
#ifdef WIN32
BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user);
void __stdcall ILibDuktape_HECI_Session_ResumeSink2(ULONG_PTR obj)
{
//if (ILibDuktape_HECI_Debug) { printf("ILibDuktape_HECI_Session_ResumeSink2()\n"); }
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)obj;
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &(session->bytesRead), &(session->v));
if (result == TRUE || GetLastError() == ERROR_IO_PENDING)
{
//if (ILibDuktape_HECI_Debug) { printf("...[Wait Handle Added]\n"); }
ILibProcessPipe_WaitHandle_Add(session->mgr, session->v.hEvent, session, ILibDuktape_HECI_Session_ReceiveSink);
}
}
#endif
void ILibDuktape_HECI_Session_ResumeSink_NoPipeline(void *chain, void *user)
{
// This is always called from the Microstack Thread
@@ -555,13 +543,16 @@ void ILibDuktape_HECI_Session_ResumeSink(ILibDuktape_DuplexStream *sender, void
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
if (session->noPipelining != 0)
{
Duktape_RunOnEventLoop(sender->readableStream->chain, duk_ctx_nonce(sender->readableStream->ctx), sender->readableStream->ctx, ILibDuktape_HECI_Session_ResumeSink_NoPipeline, NULL, session);
// Note: DO NOT 'return' here, because we still need to QueueUserAPC, to resume the stream on Windows
ILibDuktape_HECI_Session_ResumeSink_NoPipeline(sender->readableStream->chain, session);
}
#ifdef WIN32
// To Resume, we need to first context switch to the Windows Thread
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_ResumeSink2, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session);
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &(session->bytesRead), &(session->v));
if (result == TRUE || GetLastError() == ERROR_IO_PENDING)
{
//if (ILibDuktape_HECI_Debug) { printf("...[Wait Handle Added]\n"); }
ILibChain_AddWaitHandle(session->chain, session->v.hEvent, -1, ILibDuktape_HECI_Session_ReceiveSink, session);
}
#endif
}
#ifdef WIN32
@@ -576,7 +567,7 @@ void ILibDuktape_HECI_Session_ReceiveSink2(void *chain, void *user)
ILibDuktape_HECI_Session_ResumeSink(session->stream, session->stream->user);
}
}
BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user)
BOOL ILibDuktape_HECI_Session_ReceiveSink(void *chain, HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user)
{
//if (ILibDuktape_HECI_Debug) { printf("ILibDuktape_HECI_Session_ReceiveSink\n"); }
if (errors != ILibWaitHandle_ErrorStatus_NONE)
@@ -589,7 +580,14 @@ BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, ILibWaitHandle_ErrorStat
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
if (ILibMemory_CanaryOK(session))
{
if (GetOverlappedResult(session->descriptor, &(session->v), &(session->bytesRead), FALSE) == TRUE) { Duktape_RunOnEventLoop(session->chain, duk_ctx_nonce(session->stream->readableStream->ctx), session->stream->readableStream->ctx, ILibDuktape_HECI_Session_ReceiveSink2, NULL, session); }
if (GetOverlappedResult(session->descriptor, &(session->v), &(session->bytesRead), FALSE) == TRUE)
{
ILibDuktape_DuplexStream_WriteData(session->stream, session->buffer, session->bytesRead);
if (session->stream != NULL && !session->stream->readableStream->paused)
{
ILibDuktape_HECI_Session_ResumeSink(session->stream, session->stream->user);
}
}
}
return(FALSE);
}
@@ -601,7 +599,7 @@ void __stdcall ILibDuktape_HECI_Session_Start(ULONG_PTR obj)
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &bytesRead, &(session->v));
//if (ILibDuktape_HECI_Debug) { printf("...[WaitHandle Added]\n"); }
ILibProcessPipe_WaitHandle_Add(session->mgr, session->v.hEvent, session, ILibDuktape_HECI_Session_ReceiveSink);
ILibChain_AddWaitHandle(session->chain, session->v.hEvent, -1, ILibDuktape_HECI_Session_ReceiveSink, session);
}
#endif
@@ -677,7 +675,7 @@ duk_ret_t ILibDuktape_HECI_create_OnClientConnect(duk_context *ctx)
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_ChildProcess); // [HECI][childProcess]
duk_get_prop_string(ctx, -1, ILibDuktape_ChildProcess_Manager); // [HECI][childProcess][manager]
session->mgr = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_Start, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session);
ILibDuktape_HECI_Session_Start((ULONG_PTR)session);
#else
duk_push_this(ctx); // [HECI]
session->descriptor = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_HECI_Descriptor, -1);
@@ -756,10 +754,10 @@ duk_ret_t ILibDuktape_HECI_Session_close(duk_context *ctx)
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_SessionMemPtr); // [HECI][SESSION]
session = (ILibDuktape_HECI_Session*)Duktape_GetBuffer(ctx, -1, NULL);
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->v.hEvent);
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->wv.hEvent);
ILibChain_RemoveWaitHandle(session->chain, session->v.hEvent);
ILibChain_RemoveWaitHandle(session->chain, session->wv.hEvent);
session->stream = NULL;
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_CloseSink2, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session->descriptor);
CloseHandle(session->descriptor);
}
#else
int d = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_HECI_Descriptor, -1);
@@ -851,7 +849,7 @@ void ILibDuktape_HECI_IoctlHandler_Dispatch(void *chain, void *user)
}
#ifdef WIN32
void ILibDuktape_HECI_NextIoctl(ILibQueue q);
BOOL ILibDuktape_HECI_IoctlHandler(HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
BOOL ILibDuktape_HECI_IoctlHandler(void * chain, HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
{
if (errors == ILibWaitHandle_ErrorStatus_INVALID_HANDLE || errors == ILibWaitHandle_ErrorStatus_REMOVED) { return(FALSE); }
if (!ILibMemory_CanaryOK(user)) { return(FALSE); }
@@ -870,7 +868,7 @@ BOOL ILibDuktape_HECI_IoctlHandler(HANDLE h, ILibWaitHandle_ErrorStatus errors,
}
ILibQueue_DeQueue(data->Q);
ILibProcessPipe_WaitHandle_Remove(data->pipeManager, h);
ILibChain_RemoveWaitHandle(data->chain, h);
if (data->abort != 0 || !ILibMemory_CanaryOK(data->reserved))
{
@@ -888,7 +886,7 @@ BOOL ILibDuktape_HECI_IoctlHandler(HANDLE h, ILibWaitHandle_ErrorStatus errors,
return(FALSE);
}
Duktape_RunOnEventLoop(data->chain, data->ctxnonce, data->ctx, ILibDuktape_HECI_IoctlHandler_Dispatch, NULL, data);
ILibDuktape_HECI_IoctlHandler_Dispatch(data->chain, data);
if (ILibQueue_GetCount(Q) > 0)
{
@@ -906,8 +904,7 @@ void ILibDuktape_HECI_NextIoctl(ILibQueue q)
ResetEvent(data->v.hEvent);
res = DeviceIoControl(data->device, (DWORD)data->code, data->buffer, (DWORD)data->bufferLen, data->outBuffer, (DWORD)data->outBufferLen, &(data->bytesReceived), &(data->v));
ILibProcessPipe_WaitHandle_Add_WithNonZeroTimeout(data->pipeManager, data->v.hEvent, 2000, data, ILibDuktape_HECI_IoctlHandler);
ILibChain_AddWaitHandle(data->chain, data->v.hEvent, 2000, ILibDuktape_HECI_IoctlHandler, data);
}
void __stdcall ILibDuktape_HECI_apc_AddIoctl(ULONG_PTR obj)
{
@@ -1031,7 +1028,8 @@ duk_ret_t ILibDuktape_HECI_doIoctl(duk_context *ctx)
duk_get_prop_string(ctx, -2, ILibDuktape_HECI_ChildProcess); // [heci][stash][childProcess]
duk_get_prop_string(ctx, -1, ILibDuktape_ChildProcess_Manager); // [heci][stash][childProcess][manager]
data->pipeManager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_apc_AddIoctl, ILibProcessPipe_Manager_GetWorkerThread(data->pipeManager), (ULONG_PTR)data);
ILibDuktape_HECI_apc_AddIoctl((ULONG_PTR)data);
#elif defined(_POSIX)
ILibDuktape_HECI_AddIoctl(data);
#endif
@@ -1074,8 +1072,8 @@ duk_ret_t ILibDuktape_HECI_Finalizer(duk_context *ctx)
#ifdef WIN32
ILibQueue Q = (ILibQueue)Duktape_GetPointerProperty(ctx, 0, ILibDuktape_HECI_Q);
duk_get_prop_string(ctx, 0, ILibDuktape_HECI_ChildProcess);
ILibProcessPipe_Manager mgr = (ILibProcessPipe_Manager)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager);
if (mgr != NULL) { QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Finalizer2, ILibProcessPipe_Manager_GetWorkerThread(mgr), (ULONG_PTR)Q); }
ILibProcessPipe_Manager mgr = (ILibProcessPipe_Manager)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager);
ILibDuktape_HECI_Finalizer2((ULONG_PTR)Q);
#else
duk_get_prop_string(ctx, 0, ILibDuktape_HECI_Q);
ILibQueue_Destroy((ILibQueue)duk_get_pointer(ctx, -1));

View File

@@ -93,6 +93,9 @@ void *Duktape_Duplicate_GetBufferPropertyEx(duk_context *ctx, duk_idx_t i, char*
char *Duktape_Duplicate_GetStringEx(duk_context *ctx, duk_idx_t i, duk_size_t *len);
#define Duktape_Duplicate_GetString(ctx, i) Duktape_Duplicate_GetStringEx(ctx, i, NULL)
#define duk_array_shift(ctx, i) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "shift");duk_swap_top(ctx, -2);duk_call_method(ctx, 0);
#define duk_array_pop(ctx, i) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "pop");duk_swap_top(ctx, -2);duk_call_method(ctx, 0);
int Duktape_GetBooleanProperty(duk_context *ctx, duk_idx_t i, char *propertyName, int defaultValue);
struct sockaddr_in6* Duktape_IPAddress4_FromString(char* address, unsigned short port);
struct sockaddr_in6* Duktape_IPAddress6_FromString(char* address, unsigned short port);

File diff suppressed because one or more lines are too long

View File

@@ -260,7 +260,7 @@ void ILibDuktape_ScriptContainer_GetEmbeddedJS_Raw(char *exePath, char **script,
int integratedJavaScriptLen = 0;
FILE* tmpFile = NULL;
fopen_s(&tmpFile, exePath, "rb");
_wfopen_s(&tmpFile, ILibUTF8ToWide(exePath, -1), L"rb");
if (tmpFile != NULL)
{
// Read the PE Headers, to determine where to look for the Embedded JS
@@ -338,7 +338,7 @@ void ILibDuktape_ScriptContainer_CheckEmbeddedEx(char *exePath, char **script, i
{
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s_", exePath);
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s.exe", exePath);
fopen_s(&tmpFile, ILibScratchPad, "rb");
_wfopen_s(&tmpFile, ILibUTF8ToWide(ILibScratchPad, -1), L"rb");
}
else
{
@@ -373,7 +373,7 @@ void ILibDuktape_ScriptContainer_CheckEmbeddedEx(char *exePath, char **script, i
}
#ifdef WIN32
fopen_s(&tmpFile, exePath, "rb");
_wfopen_s(&tmpFile, ILibUTF8ToWide(exePath, -1), L"rb");
#else
tmpFile = fopen(exePath, "rb");
#endif
@@ -465,13 +465,15 @@ void ILibDuktape_ScriptContainer_CheckEmbedded(char **script, int *scriptLen)
// Check if .JS file is integrated with executable
#ifndef __APPLE__
char exePath[_MAX_PATH];
char exePath[_MAX_PATH*2];
#else
char exePath[PATH_MAX+1];
#endif
#ifdef WIN32
GetModuleFileName(NULL, exePath, sizeof(exePath));
WCHAR tmpExePath[_MAX_PATH];
GetModuleFileNameW(NULL, tmpExePath, sizeof(tmpExePath)/2);
WideCharToMultiByte(CP_UTF8, 0, tmpExePath, -1, exePath, sizeof(exePath), NULL, NULL);
#elif defined(__APPLE__)
uint32_t len = sizeof(exePath);
if (_NSGetExecutablePath(exePath, &len) != 0) ILIBCRITICALEXIT(247);
@@ -500,6 +502,18 @@ void ILibDuktape_ScriptContainer_Process_ExitCallback(void *obj)
Duktape_SafeDestroyHeap(ctx);
}
}
duk_ret_t ILibDuktape_ScriptContainer_Process_ExitEx(duk_context *ctx)
{
if (duk_is_number(ctx, 0))
{
exit(duk_require_int(ctx, 0));
}
else
{
exit(0);
}
return(0);
}
duk_ret_t ILibDuktape_ScriptContainer_Process_Exit(duk_context *ctx)
{
void **tmp;
@@ -861,16 +875,23 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_Kill(duk_context *ctx)
duk_ret_t ILibDuktape_Process_cwd(duk_context *ctx)
{
#ifdef WIN32
GetCurrentDirectoryA((DWORD)sizeof(ILibScratchPad), ILibScratchPad);
duk_push_string(ctx, ILibScratchPad);
return(1);
#elif defined(_POSIX)
GetCurrentDirectoryW((DWORD)sizeof(ILibScratchPad)/2, (LPWSTR)ILibScratchPad);
ILibDuktape_String_PushWideString(ctx, ILibScratchPad, 0);
#else
ignore_result((uintptr_t)getcwd(ILibScratchPad, sizeof(ILibScratchPad)));
duk_push_string(ctx, ILibScratchPad);
return(1);
#else
return(ILibDuktape_Error(ctx, "Error"));
#endif
duk_get_prop_string(ctx, -1, "concat"); // [string][concat]
duk_swap_top(ctx, -2); // [concat][this]
#ifdef WIN32
duk_push_string(ctx, "\\");
#else
duk_push_string(ctx, "/");
#endif
duk_call_method(ctx, 1);
return(1);
}
#ifdef _POSIX
@@ -1236,6 +1257,7 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "exit");
ILibDuktape_CreateProperty_InstanceMethod(ctx, "exit", ILibDuktape_ScriptContainer_Process_Exit, DUK_VARARGS);
ILibDuktape_CreateProperty_InstanceMethod(ctx, "_exit", ILibDuktape_ScriptContainer_Process_ExitEx, DUK_VARARGS);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "uncaughtException");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "SIGTERM");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "SIGCHLD");
@@ -1577,9 +1599,7 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_networkInterfaces(duk_context *ctx)
ILibDuktape_CreateReadonlyProperty(ctx, "interfaceIndexes");
char fqdn[4096];
size_t fqdnLen;
int i = 0;
size_t converted;
char tmpBuffer[32768];
DWORD tmpBufferSize = sizeof(tmpBuffer);
IP_ADAPTER_ADDRESSES *padapters = (IP_ADAPTER_ADDRESSES*)tmpBuffer;
@@ -1603,7 +1623,7 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_networkInterfaces(duk_context *ctx)
duk_put_prop_string(ctx, -2, "gateway");
}
wcstombs_s(&fqdnLen, fqdn, sizeof(fqdn), (const wchar_t*)padapters->DnsSuffix, wcsnlen_s(padapters->DnsSuffix, sizeof(fqdn)));
ILibWideToUTF8Ex((wchar_t*)padapters->DnsSuffix, -1, fqdn, (int)sizeof(fqdn));
duk_push_string(ctx, fqdn);
duk_put_prop_string(ctx, -2, "fqdn");
@@ -1654,7 +1674,7 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_networkInterfaces(duk_context *ctx)
duk_put_prop_index(ctx, -2, i++);
addr = addr->Next;
}
wcstombs_s(&converted, ILibScratchPad, sizeof(ILibScratchPad), padapters->FriendlyName, sizeof(ILibScratchPad));
ILibWideToUTF8Ex(padapters->FriendlyName, -1, ILibScratchPad, (int)sizeof(ILibScratchPad));
duk_put_prop_string(ctx, -2, ILibScratchPad);
duk_push_heapptr(ctx, indexTable); // [table]
@@ -1815,6 +1835,22 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_hostname(duk_context *ctx)
}
return(1);
}
duk_ret_t ILibDuktape_tmpdir(duk_context *ctx)
{
#ifdef WIN32
WCHAR tmp[1024];
if (GetTempPathW(sizeof(tmp) / 2, (LPWSTR)tmp) == 0) { return(ILibDuktape_Error(ctx, "Error getting temp folder")); }
ILibDuktape_String_PushWideString(ctx, (char*)tmp, 0);
#elif defined (_POSIX)
#if defined(__APPLE__)
duk_eval_string(ctx, "process.env['TMPDIR']");
if (duk_is_undefined(ctx, -1)) { duk_push_string(ctx, "/private/tmp/"); }
#else
duk_push_string(ctx, "/var/tmp/");
#endif
#endif
return(1);
}
void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [os]
@@ -1834,6 +1870,7 @@ void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethod(ctx, "networkInterfaces", ILibDuktape_ScriptContainer_OS_networkInterfaces, 0);
#endif
ILibDuktape_CreateInstanceMethod(ctx, "hostname", ILibDuktape_ScriptContainer_OS_hostname, 0);
ILibDuktape_CreateInstanceMethod(ctx, "tmpdir", ILibDuktape_tmpdir, 0);
char jsExtras[] = "exports.getPrimaryDnsSuffix = function getPrimaryDnsSuffix()\
{\
@@ -2161,34 +2198,31 @@ void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
exports.Name = (function Name()\
{\
var child;\
switch (process.platform)\
if(process.platform!='win32')\
{\
case 'freebsd':\
case 'linux':\
case 'darwin':\
child = require('child_process').execFile('/bin/sh', ['sh']);\
break;\
case 'win32':\
child = require('child_process').execFile('%windir%\\\\system32\\\\cmd.exe');\
break;\
switch (process.platform)\
{\
case 'freebsd':\
case 'linux':\
case 'darwin':\
child = require('child_process').execFile('/bin/sh', ['sh']);\
break;\
}\
child.stdout.str=''; child.stdout.on('data', function(chunk) { this.str += chunk.toString(); });\
switch (process.platform)\
{\
case 'linux':\
child.stdin.write('cat /etc/*release\\nexit\\n');\
break;\
case 'darwin':\
child.stdin.write('sw_vers\\nexit\\n');\
break;\
case 'freebsd':\
child.stdin.write('uname -mrs\\nexit\\n');\
break;\
}\
child.waitExit();\
}\
child.stdout.str=''; child.stdout.on('data', function(chunk) { this.str += chunk.toString(); });\
switch (process.platform)\
{\
case 'linux':\
child.stdin.write('cat /etc/*release\\nexit\\n');\
break;\
case 'darwin':\
child.stdin.write('sw_vers\\nexit\\n');\
break;\
case 'win32':\
child.stdin.write('exit\\r\\n');\
break;\
case 'freebsd':\
child.stdin.write('uname -mrs\\nexit\\n');\
break;\
}\
child.waitExit();\
var ret=null;\
var lines;\
var tokens;\
@@ -2196,17 +2230,15 @@ void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
switch (process.platform)\
{\
case 'win32':\
var winstr = child.stdout.str.split('\\r\\n')[0];\
if(require('user-sessions').isRoot())\
{\
try\
{\
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName') + ' - ' +\
require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ReleaseID') + ' ' + winstr.substring(winstr.indexOf('['));\
require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ReleaseID');\
}\
catch(xx)\
{\
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName') + ' ' + winstr.substring(winstr.indexOf('['));\
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName');\
}\
}\
ret = winstr;\
@@ -2255,97 +2287,7 @@ void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
{\
var promise = require('promise');\
var p = new promise(function(acc, rej) { this._acc = acc; this._rej = rej; });\
switch (process.platform)\
{\
case 'freebsd':\
case 'linux':\
case 'darwin':\
p.child = require('child_process').execFile('/bin/sh', ['sh']);\
break;\
case 'win32':\
p.child = require('child_process').execFile('%windir%\\\\system32\\\\cmd.exe');\
break;\
}\
p.child.promise = p;\
p.child.stdout.str = '';\
p.child.stdout.on('data', function(chunk) { this.str += chunk.toString(); });\
p.child.on('exit', function(code)\
{\
var lines;\
var tokens;\
var i, j;\
switch (process.platform)\
{\
case 'win32':\
var winstr = this.stdout.str.split('\\r\\n')[0];\
if(require('user-sessions').isRoot())\
{\
try\
{\
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName') + ' - ' +\
require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ReleaseID') + ' ' + winstr.substring(winstr.indexOf('['));\
}\
catch(xx)\
{\
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName') + ' ' + winstr.substring(winstr.indexOf('['));\
}\
}\
this.promise._acc(winstr);\
break;\
case 'linux':\
lines = this.stdout.str.split('\\n');\
for (i in lines)\
{\
tokens = lines[i].split('=');\
if (tokens[0] == 'PRETTY_NAME')\
{\
this.promise._acc(tokens[1].substring(1, tokens[1].length - 1));\
break;\
}\
}\
for (i in lines)\
{\
tokens = lines[i].split('=');\
if (tokens[0] == 'DISTRIB_DESCRIPTION')\
{\
this.promise._acc(tokens[1].substring(1, tokens[1].length - 1));\
break;\
}\
}\
this.promise._acc(lines[0]);\
break;\
case 'darwin':\
var OSNAME = '';\
var OSVERSION = '';\
lines = this.stdout.str.split('\\n');\
for (i in lines)\
{\
tokens = lines[i].split(':');\
if (tokens[0] == 'ProductName') { OSNAME = tokens[1].trim(); }\
if (tokens[0] == 'ProductVersion') { OSVERSION = tokens[1].trim(); }\
}\
this.promise._acc(OSNAME + ' ' + OSVERSION);\
break;\
case 'freebsd':\
this.promise._acc(this.stdout.str.trim());\
break;\
}\
});\
switch (process.platform)\
{\
case 'linux':\
p.child.stdin.write('cat /etc/*release\\nexit\\n');\
break;\
case 'darwin':\
p.child.stdin.write('sw_vers\\nexit\\n');\
break;\
case 'win32':\
p.child.stdin.write('exit\\r\\n');\
break;\
case 'freebsd':\
p.child.stdin.write('uname -mrs\\nexit\\n');\
break;\
}\
p._acc(this.Name);\
return (p);\
};\
if(process.platform=='freebsd')\
@@ -3144,6 +3086,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
int bufferLen = ((int*)buffer)[0];
void *ptr;
int i;
duk_context *ctx = master->ctx;
if (ILibDuktape_ScriptContainer_DecodeJSON(master->ctx, buffer+4, bufferLen-4) == 0)
{
@@ -3160,7 +3103,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
duk_push_string(master->ctx, json); // [emit][this][data][str]
duk_json_decode(master->ctx, -1); // [emit][this][data][json]
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer.OnData(): "); }
duk_pop(master->ctx);
duk_pop(ctx);
}
}
break;
@@ -3181,7 +3124,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
ILibDuktape_EventEmitter_SetupEmit(master->ctx, master->emitter->object, "error"); // [emit][this][error]
duk_get_prop_string(master->ctx, -4, "error"); // [emit][this][error][errorObj]
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnError_Dispatch(): "); }
duk_pop(master->ctx); // ...
duk_pop(ctx); // ...
}
else
{
@@ -3193,7 +3136,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
duk_push_false(master->ctx); // [func][this][false]
duk_get_prop_string(master->ctx, -4, "error"); // [func][this][false][error]
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnError_Dispatch(): "); }
duk_pop(master->ctx); // ...
duk_pop(ctx); // ...
}
}
}
@@ -3215,7 +3158,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
duk_push_undefined(master->ctx); // [func][this][true][undefined]
}
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnExec_Dispatch(): "); }
duk_pop(master->ctx); // ...
duk_pop(ctx); // ...
}
}
break;
@@ -3223,11 +3166,14 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
default:
break;
}
duk_pop(master->ctx); // ...
duk_pop(ctx); // ...
}
#ifdef WIN32
if (master->child != NULL) { ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdErr(master->child)); }
if (ILibMemory_CanaryOK(master))
{
if (master->child != NULL) { ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdErr(master->child)); }
}
#endif
}
void ILibDuktape_ScriptContainer_StdErrSink(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
@@ -3243,6 +3189,7 @@ void ILibDuktape_ScriptContainer_StdErrSink(ILibProcessPipe_Process sender, char
void **ptr = (void**)ILibMemory_Extra(ILibProcessPipe_Process_GetStdErr(sender));
ptr[0] = master;
ptr[1] = buffer;
ILibProcessPipe_Pipe_Pause(ILibProcessPipe_Process_GetStdErr(sender));
Duktape_RunOnEventLoop(master->chain, duk_ctx_nonce(master->ctx), master->ctx, ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread, NULL, ptr);
}

View File

@@ -922,7 +922,7 @@ duk_ret_t ILibDuktape_fs_watcher_close(duk_context *ctx)
#if defined(WIN32)
int r = CancelIo(data->h);
ILibProcessPipe_WaitHandle_Remove(data->pipeManager, data->overlapped.hEvent);
ILibChain_RemoveWaitHandle(data->chain, data->overlapped.hEvent);
CloseHandle(data->h);
data->h = NULL;
#elif defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD)
@@ -959,52 +959,50 @@ duk_ret_t ILibDuktape_fs_watcher_close(duk_context *ctx)
#endif
#ifdef WIN32
BOOL ILibDuktape_fs_watch_iocompletion(HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user);
void ILibDuktape_fs_watch_iocompletionEx(void *chain, void *user)
BOOL ILibDuktape_fs_watch_iocompletion(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
{
if (errors != ILibWaitHandle_ErrorStatus_NONE || !ILibMemory_CanaryOK(user)) { return(FALSE); }
ILibDuktape_fs_watcherData *data = (ILibDuktape_fs_watcherData*)user;
FILE_NOTIFY_INFORMATION *n = (FILE_NOTIFY_INFORMATION*)data->results;
char filename[4096];
size_t filenameLen;
int changed = 0, renamed = 0;
BOOL ret = FALSE;
duk_push_object(data->ctx); // [detail]
while (n != NULL)
{
wcstombs_s(&filenameLen, filename, sizeof(filename), n->FileName, n->FileNameLength);
ILibWideToUTF8_stupidEx(n->FileName, n->FileNameLength, filename, (int)sizeof(filename));
switch (n->Action)
{
case FILE_ACTION_RENAMED_OLD_NAME:
duk_push_lstring(data->ctx, filename, filenameLen-1);
duk_push_string(data->ctx, filename);
duk_put_prop_string(data->ctx, -2, "oldname");
renamed = 1;
break;
case FILE_ACTION_RENAMED_NEW_NAME:
duk_push_lstring(data->ctx, filename, filenameLen - 1);
duk_push_string(data->ctx, filename);
duk_put_prop_string(data->ctx, -2, "newname");
renamed = 1;
break;
case FILE_ACTION_ADDED:
duk_push_string(data->ctx, "ADDED");
duk_put_prop_string(data->ctx, -2, "changeType");
duk_push_lstring(data->ctx, filename, filenameLen - 1);
duk_push_string(data->ctx, filename);
duk_put_prop_string(data->ctx, -2, "\xFF_FileName");
changed = 1;
break;
case FILE_ACTION_REMOVED:
duk_push_string(data->ctx, "REMOVED");
duk_put_prop_string(data->ctx, -2, "changeType");
duk_push_lstring(data->ctx, filename, filenameLen - 1);
duk_push_string(data->ctx, filename);
duk_put_prop_string(data->ctx, -2, "\xFF_FileName");
changed = 1;
break;
case FILE_ACTION_MODIFIED:
duk_push_string(data->ctx, "MODIFIED");
duk_put_prop_string(data->ctx, -2, "changeType");
duk_push_lstring(data->ctx, filename, filenameLen - 1);
duk_push_string(data->ctx, filename);
duk_put_prop_string(data->ctx, -2, "\xFF_FileName");
changed = 1;
break;
@@ -1041,18 +1039,10 @@ void ILibDuktape_fs_watch_iocompletionEx(void *chain, void *user)
}
else
{
ILibProcessPipe_WaitHandle_Add(data->pipeManager, data->overlapped.hEvent, data, ILibDuktape_fs_watch_iocompletion);
ret = TRUE;
}
}
}
BOOL ILibDuktape_fs_watch_iocompletion(HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
{
if (errors != ILibWaitHandle_ErrorStatus_NONE || !ILibMemory_CanaryOK(user)) { return(FALSE); }
ILibDuktape_fs_watcherData *data = (ILibDuktape_fs_watcherData*)user;
ILibProcessPipe_WaitHandle_Remove(data->pipeManager, h);
Duktape_RunOnEventLoop(data->chain, duk_ctx_nonce(data->ctx), data->ctx, ILibDuktape_fs_watch_iocompletionEx, NULL, data);
return(TRUE);
return(ret);
}
#endif
@@ -1287,7 +1277,7 @@ void ILibduktape_fs_watch_appleWorker(void *obj)
duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
{
#ifdef WIN32
char *path = (char*)duk_require_string(ctx, 0);
WCHAR *path = (WCHAR*)ILibDuktape_String_AsWide(ctx, 0, NULL);
#else
char *path = ILibDuktape_fs_fixLinuxPath((char*)duk_require_string(ctx, 0));
#endif
@@ -1408,14 +1398,14 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
#if defined(WIN32)
if ((data->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { return(ILibDuktape_Error(ctx, "Could not create handle")); }
data->h = CreateFile(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
data->h = CreateFileW(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
if (data->h == INVALID_HANDLE_VALUE) { return(ILibDuktape_Error(ctx, "fs.watch(): Invalid Path or Access Denied")); }
if (ReadDirectoryChangesW(data->h, data->results, sizeof(data->results), recursive, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS, NULL, &(data->overlapped), NULL) == 0)
{
return(ILibDuktape_Error(ctx, "fs.watch(): Error creating watcher"));
}
ILibProcessPipe_WaitHandle_Add(pipeMgr, data->overlapped.hEvent, data, ILibDuktape_fs_watch_iocompletion);
ILibChain_AddWaitHandle(data->chain, data->overlapped.hEvent, -1, ILibDuktape_fs_watch_iocompletion, data);
#elif defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD)
data->wd.i = inotify_add_watch(data->linuxWatcher->fd, path, IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO);
if (data->wd.i < 0)

View File

@@ -82,18 +82,21 @@ int ILibDuktape_TLS_ctx2server = -1;
#define ILibDuktape_net_IPC_BUFFERSIZE 4096
typedef struct ILibDuktape_net_WindowsIPC
{
ILibProcessPipe_Manager manager;
duk_context *ctx;
void *mServer, *mSocket, *mChain;
HANDLE mPipeHandle;
ILibProcessPipe_Pipe mPipe;
int paused;
int totalRead;
void *user1;
OVERLAPPED read_overlapped;
OVERLAPPED write_overlapped;
OVERLAPPED overlapped;
ILibDuktape_DuplexStream *ds;
BOOL clientConnected;
ULONG_PTR _reserved[5];
int processingRead;
char *buffer;
int bufferLength;
int bufferOffset;
@@ -378,13 +381,12 @@ duk_ret_t ILibDuktape_net_socket_connect(duk_context *ctx)
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_net_WindowsIPC));
duk_put_prop_string(ctx, -2, ILibDuktape_net_WindowsIPC_Buffer);
winIPC->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
winIPC->read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
winIPC->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
winIPC->ctx = ctx;
winIPC->mSocket = duk_get_heapptr(ctx, -1);
winIPC->mChain = Duktape_GetChain(ctx);
duk_eval_string(ctx, "require('child_process');");
winIPC->manager = (ILibProcessPipe_Manager)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager);
duk_pop(ctx);
winIPC->mChain = duk_ctx_chain(ctx);
winIPC->paused = 1;
if ((winIPC->mPipeHandle = CreateFileA(path, GENERIC_READ | FILE_WRITE_DATA, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0)) == INVALID_HANDLE_VALUE)
{
@@ -395,7 +397,6 @@ duk_ret_t ILibDuktape_net_socket_connect(duk_context *ctx)
{
// SUCCESS
winIPC->ds = ILibDuktape_DuplexStream_InitEx(winIPC->ctx, ILibDuktape_net_server_IPC_WriteSink, ILibDuktape_net_server_IPC_EndSink, ILibDuktape_net_server_IPC_PauseSink, ILibDuktape_net_server_IPC_ResumeSink, ILibDuktape_net_server_IPC_unshiftSink, winIPC);
winIPC->mPipe = ILibProcessPipe_Pipe_CreateFromExisting(winIPC->manager, winIPC->mPipeHandle, ILibProcessPipe_Pipe_ReaderHandleType_Overlapped);
winIPC->ds->readableStream->paused = 1;
ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter_GetEmitter(winIPC->ctx, -1), "data", ILibDuktape_net_socket_ipc_dataHookCallback);
ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter_GetEmitter(winIPC->ctx, -1), "end", ILibDuktape_net_socket_ipc_dataHookCallback);
@@ -838,7 +839,99 @@ void ILibDuktape_net_server_OnSendOK(ILibAsyncServerSocket_ServerModule AsyncSer
}
#ifdef WIN32
extern void ILibProcessPipe_FreePipe(ILibProcessPipe_Pipe pipeObject);
BOOL ILibDuktape_server_ipc_ReadSink(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus status, char *buffer, int bytesRead, void* user)
{
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
int consumed = 0;
if (status == ILibWaitHandle_ErrorStatus_NONE)
{
winIPC->totalRead += bytesRead;
do
{
winIPC->unshiftedBytes = 0;
if (winIPC->totalRead > 0)
{
ILibDuktape_DuplexStream_WriteData(winIPC->ds, winIPC->buffer + winIPC->bufferOffset, winIPC->totalRead);
}
if (winIPC->unshiftedBytes > winIPC->totalRead) { winIPC->unshiftedBytes = winIPC->totalRead; }
winIPC->bufferOffset += (winIPC->totalRead - winIPC->unshiftedBytes);
winIPC->totalRead -= (winIPC->totalRead - winIPC->unshiftedBytes);
} while (winIPC->paused == 0 && consumed != 0 && winIPC->totalRead > 0);
if (winIPC->totalRead == 0) { winIPC->bufferOffset = 0; }
if (winIPC->paused == 0)
{
if (winIPC->bufferOffset > 0)
{
memmove_s(winIPC->buffer, winIPC->bufferLength, winIPC->buffer + winIPC->bufferOffset, winIPC->totalRead);
winIPC->bufferOffset = 0;
}
else if (winIPC->totalRead == winIPC->bufferLength)
{
ILibMemory_ReallocateRaw(&(winIPC->buffer), winIPC->bufferLength == 0 ? ILibDuktape_net_IPC_BUFFERSIZE : winIPC->bufferLength * 2);
winIPC->bufferLength = winIPC->bufferLength == 0 ? ILibDuktape_net_IPC_BUFFERSIZE : winIPC->bufferLength * 2;
}
ILibChain_ReadEx(chain, h, &(winIPC->read_overlapped), winIPC->buffer + winIPC->bufferOffset + winIPC->totalRead, winIPC->bufferLength - winIPC->totalRead, ILibDuktape_server_ipc_ReadSink, winIPC);
return(TRUE);
}
else
{
return(FALSE);
}
}
else
{
// I/O Errors
ILibDuktape_DuplexStream_Closed(winIPC->ds);
return(FALSE);
}
}
BOOL ILibDuktape_server_ipc_WriteSink(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus status, int bytesWritten, void* user)
{
if (!ILibMemory_CanaryOK(user)) { return(FALSE); }
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
duk_idx_t top = duk_get_top(winIPC->ctx);
duk_size_t bufLen;
char *buf;
ILibTransport_DoneState d = ILibTransport_DoneState_COMPLETE;
BOOL ret;
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [obj]
duk_get_prop_string(winIPC->ctx, -1, ILibDuktape_net_WindowsIPC_PendingArray); // [obj][array]
while (d == ILibTransport_DoneState_COMPLETE)
{
duk_dup(winIPC->ctx, -1); // [obj][array][array]
duk_get_prop_string(winIPC->ctx, -1, "shift"); // [obj][array][array][shift]
duk_swap_top(winIPC->ctx, -2); // [obj][array][shift][this]
if (duk_pcall_method(winIPC->ctx, 0) != 0) { duk_set_top(winIPC->ctx, top); return(FALSE); } // [obj][array][buffer]
duk_pop(winIPC->ctx); // [obj][array]
if (duk_get_length(winIPC->ctx, -1) == 0) { break; }
duk_get_prop_index(winIPC->ctx, -1, 0); // [obj][array][buffer]
buf = Duktape_GetBuffer(winIPC->ctx, -1, &bufLen);
d = ILibChain_WriteEx(chain, h, &(winIPC->write_overlapped), buf, (int)bufLen, ILibDuktape_server_ipc_WriteSink, winIPC);
duk_pop(winIPC->ctx); // [obj][array]
}
switch (d)
{
case ILibTransport_DoneState_COMPLETE:
// No more pending writes, so we can emit drain
ILibDuktape_DuplexStream_Ready(winIPC->ds);
ret = FALSE;
break;
case ILibTransport_DoneState_INCOMPLETE:
// Still pending writes, so return TRUE, so we can get evented later
ret = TRUE;
break;
case ILibTransport_DoneState_ERROR:
ret = FALSE;
break;
}
duk_set_top(winIPC->ctx, top); // ...
return(ret);
}
int ILibDuktape_net_server_IPC_unshiftSink(ILibDuktape_DuplexStream *sender, int unshiftBytes, void *user)
{
@@ -847,184 +940,29 @@ int ILibDuktape_net_server_IPC_unshiftSink(ILibDuktape_DuplexStream *sender, int
winIPC->unshiftedBytes = unshiftBytes;
return(unshiftBytes);
}
void ILibDuktape_net_server_IPC_readsink_safe(void *chain, void *user)
{
if (!ILibMemory_CanaryOK(user)) { return; }
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
ILibProcessPipe_Pipe sender = (ILibProcessPipe_Pipe)winIPC->_reserved[0];
DWORD dwErrorCode = (DWORD)winIPC->_reserved[2];
char *buffer = (char*)winIPC->_reserved[3];
int bufferLen = (int)winIPC->_reserved[4];
if (dwErrorCode == 0)
{
winIPC->bytesLeft += bufferLen;
ILibDuktape_net_server_IPC_ResumeSink(winIPC->ds, winIPC);
}
else
{
ILibDuktape_DuplexStream_Closed(winIPC->ds);
ILibProcessPipe_FreePipe(winIPC->mPipe);
winIPC->mPipe = NULL; winIPC->mPipeHandle = NULL;
if (winIPC->mServer != NULL)
{
// Server IPC, so we can create a new Instance, and listen for a connection
duk_context *ctx = winIPC->ctx; // We need to dereference this, because winIPC will go out of scope when we call listen
CloseHandle(winIPC->overlapped.hEvent); winIPC->overlapped.hEvent = NULL;
if (winIPC->buffer != NULL) { free(winIPC->buffer); winIPC->buffer = NULL; }
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [connection]
duk_del_prop_string(ctx, -1, ILibDuktape_net_WindowsIPC_Buffer); duk_pop(winIPC->ctx); // ...
duk_push_heapptr(ctx, winIPC->mServer); // [server]
if (Duktape_GetBooleanProperty(ctx, -1, ILibDuktape_net_server_closed, 0) == 0)
{
duk_get_prop_string(ctx, -1, "listen"); // [server][listen]
duk_swap_top(ctx, -2); // [listen][this]
duk_get_prop_string(ctx, -1, ILibDuktape_SERVER2LISTENOPTIONS); // [listen][this][options]
duk_pcall_method(ctx, 1); // [ret]
}
else if (Duktape_GetBooleanProperty(ctx, -1, ILibDuktape_net_server_closed_needEmit, 0) != 0)
{
duk_push_false(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_net_server_closed_needEmit);
ILibDuktape_EventEmitter_SetupEmit(ctx, winIPC->mServer, "close"); // [emit][this][closed]
duk_pcall_method(ctx, 1); // [ret]
}
duk_pop(ctx); // ...
}
}
}
void ILibDuktape_net_server_IPC_readsink(ILibProcessPipe_Pipe sender, void *user, DWORD dwErrorCode, char *buffer, int bufferLen)
{
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
if (!ILibMemory_CanaryOK(user)) { return; }
winIPC->_reserved[0] = (ULONG_PTR)sender;
winIPC->_reserved[1] = (ULONG_PTR)user;
winIPC->_reserved[2] = (ULONG_PTR)dwErrorCode;
winIPC->_reserved[3] = (ULONG_PTR)buffer;
winIPC->_reserved[4] = (ULONG_PTR)bufferLen;
Duktape_RunOnEventLoop(winIPC->mChain, duk_ctx_nonce(winIPC->ctx), winIPC->ctx, ILibDuktape_net_server_IPC_readsink_safe, NULL, winIPC);
}
void ILibDuktape_net_server_IPC_PauseSink(ILibDuktape_DuplexStream *sender, void *user)
{
// No-OP, becuase all we need to so is set Paused flag, which is already the case when we get here
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
winIPC->paused = 1;
}
void ILibDuktape_net_server_IPC_ResumeSink(ILibDuktape_DuplexStream *sender, void *user)
{
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
if (winIPC->processingRead != 0 || winIPC->mPipeHandle == NULL) { return; }
winIPC->processingRead = 1;
if (winIPC->buffer == NULL)
{
winIPC->buffer = ILibMemory_Allocate(ILibDuktape_net_IPC_BUFFERSIZE, 0, NULL, NULL);
winIPC->bufferLength = ILibDuktape_net_IPC_BUFFERSIZE;
winIPC->bufferOffset = 0;
winIPC->bytesLeft = 0;
}
if (winIPC->bytesLeft <= 0)
{
winIPC->bytesLeft = 0;
winIPC->bufferOffset = 0;
if (ILibProcessPipe_Pipe_ReadEx(winIPC->mPipe, winIPC->buffer, winIPC->bufferLength, winIPC, ILibDuktape_net_server_IPC_readsink) != 0)
{
ILibDuktape_net_server_IPC_readsink(winIPC->mPipe, winIPC, 1, NULL, 0);
}
}
else
{
// Check to see if we can drain any of the buffer first
while (winIPC->ds->readableStream->paused == 0)
{
winIPC->unshiftedBytes = 0;
ILibDuktape_DuplexStream_WriteData(winIPC->ds, winIPC->buffer + winIPC->bufferOffset, winIPC->bytesLeft);
if (winIPC->unshiftedBytes > 0)
{
if (winIPC->unshiftedBytes == winIPC->bytesLeft)
{
// Unshift the entire buffer
winIPC->unshiftedBytes = 0;
}
else
{
// Unshift some of the buffer
winIPC->bufferOffset += (winIPC->bytesLeft - winIPC->unshiftedBytes);
if (winIPC->bytesLeft == winIPC->unshiftedBytes)
{
winIPC->unshiftedBytes = 0;
}
winIPC->bytesLeft = winIPC->unshiftedBytes;
}
}
else
{
winIPC->bufferOffset = winIPC->bytesLeft = 0;
}
if (winIPC->ds->readableStream->paused == 0 && (winIPC->bytesLeft == 0 || (winIPC->bytesLeft > 0 && winIPC->unshiftedBytes == 0)))
{
if (winIPC->bufferLength - winIPC->bufferOffset - winIPC->bytesLeft == 0)
{
// We need to grow the buffer
ILibMemory_ReallocateRaw(&(winIPC->buffer), winIPC->bufferLength + ILibDuktape_net_IPC_BUFFERSIZE);
winIPC->bufferLength += ILibDuktape_net_IPC_BUFFERSIZE;
}
if (ILibProcessPipe_Pipe_ReadEx(winIPC->mPipe, winIPC->buffer + winIPC->bufferOffset + winIPC->bytesLeft, winIPC->bufferLength - winIPC->bufferOffset - winIPC->bytesLeft, winIPC, ILibDuktape_net_server_IPC_readsink) != 0)
{
ILibDuktape_net_server_IPC_readsink(winIPC->mPipe, winIPC, 1, NULL, 0);
}
break;
}
}
}
winIPC->processingRead = 0;
winIPC->paused = 0;
ILibDuktape_server_ipc_ReadSink(winIPC->mChain, winIPC->mPipeHandle, ILibWaitHandle_ErrorStatus_NONE, NULL, 0, winIPC);
}
void ILibDuktape_net_server_IPC_WriteCompletionEvent(ILibProcessPipe_Pipe sender, void *user, DWORD errorCode, int bytesWritten)
{
if (!ILibMemory_CanaryOK(user) || errorCode != 0) { return; }
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
duk_idx_t top = duk_get_top(winIPC->ctx);
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [obj]
duk_get_prop_string(winIPC->ctx, -1, ILibDuktape_net_WindowsIPC_PendingArray); // [obj][array]
duk_get_prop_string(winIPC->ctx, -1, "shift"); // [obj][array][shift]
duk_dup(winIPC->ctx, -2); // [obj][array][shift][this]
if (duk_pcall_method(winIPC->ctx, 0) != 0) // [obj][array][buffer]
{
ILibDuktape_Process_UncaughtExceptionEx(winIPC->ctx, "Internal Error: net.socket.ipc.writeCompletionEvent");
duk_set_top(winIPC->ctx, top); // ...
return;
}
duk_pop(winIPC->ctx); // [obj][array]
if (duk_get_length(winIPC->ctx, -1) > 0)
{
// Still pending Writes
duk_get_prop_index(winIPC->ctx, -1, 0); // [obj][array][buffer]
duk_size_t bufLen;
char *buf = (char*)Duktape_GetBuffer(winIPC->ctx, -1, &bufLen);
duk_set_top(winIPC->ctx, top); // ...
ILibProcessPipe_Pipe_WriteEx(winIPC->mPipe, buf, (int)bufLen, winIPC, ILibDuktape_net_server_IPC_WriteCompletionEvent);
}
else
{
// No more pending writes, so we can emit drain
duk_set_top(winIPC->ctx, top); // ...
ILibDuktape_DuplexStream_Ready(winIPC->ds);
}
}
ILibTransport_DoneState ILibDuktape_net_server_IPC_WriteSink(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
{
if (!ILibMemory_CanaryOK(user)) { return(ILibTransport_DoneState_ERROR); }
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
if (!duk_ctx_is_alive(winIPC->ctx) || winIPC->mPipeHandle == NULL) { return(ILibTransport_DoneState_ERROR); }
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [obj]
duk_get_prop_string(winIPC->ctx, -1, ILibDuktape_net_WindowsIPC_PendingArray); // [obj][array]
char *q = duk_push_fixed_buffer(winIPC->ctx, bufferLen); // [obj][array][buffer]
duk_size_t len = duk_get_length(winIPC->ctx, -2);
duk_put_prop_index(winIPC->ctx, -2, (duk_uarridx_t)len); // [obj][array]
@@ -1034,7 +972,15 @@ ILibTransport_DoneState ILibDuktape_net_server_IPC_WriteSink(ILibDuktape_DuplexS
if (len == 0)
{
// No Pending Writes
ILibProcessPipe_Pipe_WriteEx(winIPC->mPipe, q, bufferLen, winIPC, ILibDuktape_net_server_IPC_WriteCompletionEvent);
ILibTransport_DoneState ret = ILibChain_WriteEx(winIPC->mChain, winIPC->mPipeHandle, &(winIPC->write_overlapped), q, bufferLen, ILibDuktape_server_ipc_WriteSink, winIPC);
if (ret != ILibTransport_DoneState_INCOMPLETE)
{
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [obj]
duk_get_prop_string(winIPC->ctx, -1, ILibDuktape_net_WindowsIPC_PendingArray); // [obj][array]
duk_array_shift(winIPC->ctx, -1); // [obj][array][val]
duk_pop_3(winIPC->ctx); // ...
}
return(ret);
}
return(ILibTransport_DoneState_INCOMPLETE);
@@ -1044,22 +990,21 @@ void ILibDuktape_net_server_IPC_EndSink(ILibDuktape_DuplexStream *stream, void *
if (!ILibMemory_CanaryOK(user)) { return; }
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
if (ILibProcessPipe_Pipe_CancelEx(winIPC->mPipe) == 0)
{
ILibProcessPipe_FreePipe(winIPC->mPipe);
winIPC->mPipe = NULL; winIPC->mPipeHandle = NULL;
if (winIPC->mServer != NULL)
{
// Server IPC, so we can create a new Instance, and listen for a connection
duk_context *ctx = winIPC->ctx; // We need to dereference this, because winIPC will go out of scope when we call listen
CloseHandle(winIPC->overlapped.hEvent); winIPC->overlapped.hEvent = NULL;
if (winIPC->mPipeHandle != NULL) { CloseHandle(winIPC->mPipeHandle); winIPC->mPipeHandle = NULL; }
if (winIPC->read_overlapped.hEvent != NULL) { CloseHandle(winIPC->read_overlapped.hEvent); winIPC->read_overlapped.hEvent = NULL; }
if (winIPC->write_overlapped.hEvent != NULL) { CloseHandle(winIPC->write_overlapped.hEvent); winIPC->write_overlapped.hEvent = NULL; }
duk_push_heapptr(ctx, winIPC->mServer); // [server]
duk_get_prop_string(ctx, -1, "listen"); // [server][listen]
duk_swap_top(ctx, -2); // [listen][this]
duk_get_prop_string(ctx, -1, ILibDuktape_SERVER2LISTENOPTIONS); // [listen][this][options]
duk_pcall_method(ctx, 1); duk_pop(ctx); // ...
}
if (winIPC->mServer != NULL)
{
// Server IPC, so we can create a new Instance, and listen for a connection
duk_context *ctx = winIPC->ctx; // We need to dereference this, because winIPC will go out of scope when we call listen
CloseHandle(winIPC->overlapped.hEvent); winIPC->overlapped.hEvent = NULL;
duk_push_heapptr(ctx, winIPC->mServer); // [server]
duk_get_prop_string(ctx, -1, "listen"); // [server][listen]
duk_swap_top(ctx, -2); // [listen][this]
duk_get_prop_string(ctx, -1, ILibDuktape_SERVER2LISTENOPTIONS); // [listen][this][options]
duk_pcall_method(ctx, 1); duk_pop(ctx); // ...
}
}
duk_ret_t ILibDuktape_net_server_IPC_ConnectSink_Finalizer(duk_context *ctx)
@@ -1067,22 +1012,35 @@ duk_ret_t ILibDuktape_net_server_IPC_ConnectSink_Finalizer(duk_context *ctx)
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)Duktape_GetBufferProperty(ctx, 0, ILibDuktape_net_WindowsIPC_Buffer);
if (winIPC != NULL)
{
if (winIPC->mPipe != NULL && winIPC->mPipeHandle != NULL)
if (winIPC->mPipeHandle != NULL)
{
// It's ok to do this, becuase the CancelEx happens on the same thread, and the completion routine will use an APC Queue, so the Canary will fail before it tries to deref
ILibProcessPipe_Pipe_CancelEx(winIPC->mPipe);
ILibProcessPipe_FreePipe(winIPC->mPipe);
winIPC->mPipe = NULL; winIPC->mPipeHandle = NULL;
CloseHandle(winIPC->mPipeHandle);
winIPC->mPipeHandle = NULL;
}
if (winIPC->buffer != NULL) { free(winIPC->buffer); winIPC->buffer = NULL; }
if (winIPC->read_overlapped.hEvent != NULL)
{
ILibChain_RemoveWaitHandle(duk_ctx_chain(ctx), winIPC->read_overlapped.hEvent);
CloseHandle(winIPC->read_overlapped.hEvent);
winIPC->read_overlapped.hEvent = NULL;
}
if (winIPC->write_overlapped.hEvent != NULL)
{
ILibChain_RemoveWaitHandle(duk_ctx_chain(ctx), winIPC->write_overlapped.hEvent);
CloseHandle(winIPC->write_overlapped.hEvent);
winIPC->write_overlapped.hEvent = NULL;
}
if (winIPC->buffer != NULL) { free(winIPC->buffer); }
}
return(0);
}
BOOL ILibDuktape_net_server_IPC_ConnectSink(HANDLE event, ILibWaitHandle_ErrorStatus status, void* user)
//BOOL ILibDuktape_net_server_IPC_ConnectSink(HANDLE event, ILibWaitHandle_ErrorStatus status, void* user)
BOOL ILibDuktape_net_server_IPC_ConnectSink(void *chain, HANDLE event, ILibWaitHandle_ErrorStatus status, void* user)
{
if (ILibMemory_CanaryOK(user))
if (ILibMemory_CanaryOK(user) && status == ILibWaitHandle_ErrorStatus_NONE)
{
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
winIPC->clientConnected = TRUE;
ILibDuktape_EventEmitter_SetupEmit(winIPC->ctx, winIPC->mServer, "connection"); // [emit][this][connection]
duk_push_object(winIPC->ctx); // [emit][this][connection][socket]
ILibDuktape_WriteID(winIPC->ctx, "net.socket.ipc");
@@ -1095,8 +1053,9 @@ BOOL ILibDuktape_net_server_IPC_ConnectSink(HANDLE event, ILibWaitHandle_ErrorSt
duk_push_array(winIPC->ctx); duk_put_prop_string(winIPC->ctx, -2, ILibDuktape_net_WindowsIPC_PendingArray);
winIPC->mSocket = duk_get_heapptr(winIPC->ctx, -1);
winIPC->ds = ILibDuktape_DuplexStream_InitEx(winIPC->ctx, ILibDuktape_net_server_IPC_WriteSink, ILibDuktape_net_server_IPC_EndSink, ILibDuktape_net_server_IPC_PauseSink, ILibDuktape_net_server_IPC_ResumeSink, ILibDuktape_net_server_IPC_unshiftSink, winIPC);
winIPC->mPipe = ILibProcessPipe_Pipe_CreateFromExisting(winIPC->manager, winIPC->mPipeHandle, ILibProcessPipe_Pipe_ReaderHandleType_Overlapped);
winIPC->ds->readableStream->paused = 1;
winIPC->paused = 1;
ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter_GetEmitter(winIPC->ctx, -1), "data", ILibDuktape_net_socket_ipc_dataHookCallback);
ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter_GetEmitter(winIPC->ctx, -1), "end", ILibDuktape_net_socket_ipc_dataHookCallback);
@@ -1210,12 +1169,14 @@ duk_ret_t ILibDuktape_net_server_listen(duk_context *ctx)
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_net_WindowsIPC));
duk_put_prop_string(ctx, -2, ILibDuktape_net_WindowsIPC_Buffer);
winIPC->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
winIPC->read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
winIPC->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
winIPC->ctx = ctx;
winIPC->mServer = duk_get_heapptr(ctx, -1);
winIPC->mChain = Duktape_GetChain(ctx);
winIPC->mChain = duk_ctx_chain(ctx);
winIPC->clientConnected = FALSE;
duk_eval_string(ctx, "require('child_process');");
winIPC->manager = (ILibProcessPipe_Manager)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager);
duk_pop(ctx);
if (Duktape_GetBooleanProperty(ctx, 0, "writableAll", 0) != 0)
@@ -1252,9 +1213,9 @@ duk_ret_t ILibDuktape_net_server_listen(duk_context *ctx)
duk_del_prop_string(ctx, -1, ILibDuktape_net_WindowsIPC_Buffer);
return(ILibDuktape_Error(ctx, "Error Creating Named Pipe: %s", ipc));
}
//printf("ConnectNamedPipe(%s)\n", ipc);
ConnectNamedPipe(winIPC->mPipeHandle, &winIPC->overlapped);
ILibProcessPipe_WaitHandle_Add2(winIPC->manager, winIPC->overlapped.hEvent, winIPC, ILibDuktape_net_server_IPC_ConnectSink);
ILibChain_AddWaitHandle(duk_ctx_chain(ctx), winIPC->overlapped.hEvent, -1, ILibDuktape_net_server_IPC_ConnectSink, winIPC);
if (pIPC_SA != NULL) { LocalFree(IPC_ACL); }
return(1);
@@ -1334,7 +1295,7 @@ duk_ret_t ILibDuktape_net_server_Finalizer(duk_context *ctx)
ILibDuktape_net_WindowsIPC *ipc = Duktape_GetBufferProperty(ctx, 0, ILibDuktape_net_WindowsIPC_Buffer);
if (ipc != NULL && ipc->overlapped.hEvent != NULL)
{
ILibProcessPipe_WaitHandle_Remove(ipc->manager, ipc->overlapped.hEvent);
ILibChain_RemoveWaitHandle(duk_ctx_chain(ctx), ipc->overlapped.hEvent);
if (ipc->mPipeHandle != NULL) { CloseHandle(ipc->mPipeHandle); ipc->mPipeHandle = NULL; }
if (ipc->overlapped.hEvent != NULL) { CloseHandle(ipc->overlapped.hEvent); ipc->overlapped.hEvent = NULL; }
}
@@ -1399,7 +1360,7 @@ duk_ret_t ILibDuktape_net_server_close(duk_context *ctx)
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)Duktape_GetBufferProperty(ctx, -1, ILibDuktape_net_WindowsIPC_Buffer);
if (winIPC != NULL && winIPC->mPipeHandle != NULL)
{
if (winIPC->mPipe == NULL)
if (winIPC->clientConnected == FALSE)
{
// Listening
DisconnectNamedPipe(winIPC->mPipeHandle);