diff --git a/meshcore/agentcore.c b/meshcore/agentcore.c index 83da004..ff76a36 100644 --- a/meshcore/agentcore.c +++ b/meshcore/agentcore.c @@ -2648,8 +2648,10 @@ void MeshServer_selfupdate_continue(MeshAgentHostContainer *agent) ILibUTF8ToWideEx(agent->exePath, (int)strnlen_s(agent->exePath, 4096), w_exepath, 4096); swprintf_s(cmd, MAX_PATH, L"%s\\system32\\cmd.exe", env); - swprintf_s(parms, 65535, L"/C wmic service \"%s\" call stopservice & copy \"%s\" \"%s\" & wmic service \"%s\" call startservice & erase \"%s\"", - w_meshservicename, w_updatefile, w_exepath, w_meshservicename, w_updatefile); + swprintf_s(parms, 65535, L"/C wmic service \"%s\" call stopservice & \"%s\" -b64exec %s \"%s\" & copy \"%s\" \"%s\" & wmic service \"%s\" call startservice & erase \"%s\"", + w_meshservicename, + w_updatefile, L"dHJ5CnsKICAgIHZhciBzZXJ2aWNlTG9jYXRpb24gPSBwcm9jZXNzLmFyZ3YucG9wKCk7CiAgICByZXF1aXJlKCdwcm9jZXNzLW1hbmFnZXInKS5lbnVtZXJhdGVQcm9jZXNzZXMoKS50aGVuKGZ1bmN0aW9uIChwcm9jKQogICAgewogICAgICAgIGZvciAodmFyIHAgaW4gcHJvYykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcm9jW3BdLnBhdGggPT0gc2VydmljZUxvY2F0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwcm9jZXNzLmtpbGwocHJvY1twXS5waWQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByb2Nlc3MuZXhpdCgpOwogICAgfSk7Cn0KY2F0Y2goZSkKewogICAgcHJvY2Vzcy5leGl0KCk7Cn0=", w_exepath, + w_updatefile, w_exepath, w_meshservicename, w_updatefile); ILIBLOGMESSAGEX("SelfUpdate -> Updating and restarting service..."); _wexecve(cmd, (WCHAR*[]) { L"cmd", parms, NULL }, NULL); diff --git a/microscript/ILibDuktape_ScriptContainer.c b/microscript/ILibDuktape_ScriptContainer.c index 7374d05..513696f 100644 --- a/microscript/ILibDuktape_ScriptContainer.c +++ b/microscript/ILibDuktape_ScriptContainer.c @@ -2563,6 +2563,83 @@ int ILibDuktape_ScriptContainer_DebuggingOK(duk_context *ctx) duk_pop(ctx); return(retVal); } + +duk_ret_t ILibDuktape_Polyfills_promise_wait_impl_res(duk_context *ctx) +{ + duk_push_current_function(ctx); // [func] + duk_get_prop_string(ctx, -1, "obj"); // [func][obj] + duk_dup(ctx, 0); // [func][obj][resolvedValue] + duk_put_prop_string(ctx, -2, "return"); // [func][obj] + ILibChain_EndContinue(duk_ctx_chain(ctx)); + return(0); +} +duk_ret_t ILibDuktape_Polyfills_promise_wait_impl_rej(duk_context *ctx) +{ + duk_push_current_function(ctx); // [func] + duk_get_prop_string(ctx, -1, "obj"); // [func][obj] + duk_dup(ctx, 0); // [func][obj][rejectedValue] + duk_put_prop_string(ctx, -2, "error"); // [func][obj] + ILibChain_EndContinue(duk_ctx_chain(ctx)); + return(0); +} +duk_ret_t ILibDuktape_Polyfills_promise_wait_impl(duk_context *ctx) +{ + ILibChain_Continue_Result continueResult; + int timeout = duk_is_number(ctx, 1) ? duk_require_int(ctx, 1) : -1; + int timerInfo = ILibChain_GetMinimumTimer(duk_ctx_chain(ctx)); + int ret; + if (timeout < 0 && timerInfo > 0) { timeout = 60000; } + + duk_push_object(ctx); // [obj] + duk_prepare_method_call(ctx, 0, "then"); // [obj][then][this] + duk_push_c_function(ctx, ILibDuktape_Polyfills_promise_wait_impl_res, DUK_VARARGS); // [obj][then][this][res] + duk_dup(ctx, -4); duk_put_prop_string(ctx, -2, "obj"); + duk_push_c_function(ctx, ILibDuktape_Polyfills_promise_wait_impl_rej, DUK_VARARGS); // [obj][then][this][res][rej] + duk_dup(ctx, -5); duk_put_prop_string(ctx, -2, "obj"); + duk_call_method(ctx, 2); // [obj][retpromise] + + ILibChain_Link **modules = ILibChain_GetModules(duk_ctx_chain(ctx)); + int count = (int)(ILibMemory_Size(modules) / sizeof(ILibChain_Link*)); + continueResult = ILibChain_Continue(duk_ctx_chain(ctx), modules, count, timeout, NULL); + ILibMemory_Free(modules); + + switch (continueResult) + { + case ILibChain_Continue_Result_ERROR_INVALID_STATE: + ret = ILibDuktape_Error(ctx, "wait() already in progress"); + break; + case ILibChain_Continue_Result_ERROR_CHAIN_EXITING: + ret = ILibDuktape_Error(ctx, "wait() aborted because thread is exiting"); + break; + case ILibChain_Continue_Result_ERROR_EMPTY_SET: + ret = ILibDuktape_Error(ctx, "wait() cannot wait on empty set"); + break; + case ILibChain_Continue_Result_TIMEOUT: + ret = ILibDuktape_Error(ctx, "wait() timeout"); + break; + default: + ret = 1; + break; + } + + if (duk_has_prop_string(ctx, -2, "return")) + { + duk_get_prop_string(ctx, -2, "return"); + } + else + { + duk_get_prop_string(ctx, -2, "error"); + duk_throw(ctx); + } + return(ret); +} +void ILibDuktape_Polyfills_promise_wait(duk_context *ctx) +{ + duk_eval_string(ctx, "require('promise');"); // [promise] + ILibDuktape_CreateInstanceMethod(ctx, "wait", ILibDuktape_Polyfills_promise_wait_impl, DUK_VARARGS); + duk_pop(ctx); // ... +} + duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(duk_context *ctx, SCRIPT_ENGINE_SECURITY_FLAGS securityFlags, unsigned int executionTimeout, void *chain, char **argList, ILibSimpleDataStore *db, char *exePath, ILibProcessPipe_Manager pipeManager, ILibDuktape_HelperEvent exitHandler, void *exitUser) { void **timeoutKey = executionTimeout > 0 ? (void**)ILibMemory_Allocate(sizeof(void*), 0, NULL, NULL) : NULL; @@ -2661,6 +2738,7 @@ duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(duk_conte } ILibDuktape_Polyfills_JS_Init(ctx); + ILibDuktape_Polyfills_promise_wait(ctx); return ctx; } diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index 4871fc7..e2cd787 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -2478,7 +2478,7 @@ ILibExportMethod ILibChain_Continue_Result ILibChain_Continue(void *Chain, ILibC chain->currentWaitTimeout = 0; ILibChain_SetupWindowsWaitObject(chain->WaitHandles, &x, &tv, &(chain->currentWaitTimeout), &readset, &writeset, &errorset, chain->auxSelectHandles, handles); - if (x == 0) + if (x == 0 && maxTimeout < 0) { root->continuationState = ILibChain_ContinuationState_END_CONTINUE; ret = ILibChain_Continue_Result_ERROR_EMPTY_SET; @@ -3126,6 +3126,26 @@ void ILibChain_DisableWatchDog(void *chain) ((ILibBaseChain*)chain)->nowatchdog = 1; } +ILibChain_Link **ILibChain_GetModules(void *chain) +{ + ILibChain_Link **ret = NULL; + int count = 0; + void *node = ILibLinkedList_GetNode_Head(((ILibBaseChain*)chain)->Links); + while (node != NULL) + { + ++count; + node = ILibLinkedList_GetNextNode(node); + } + ret = (ILibChain_Link**)ILibMemory_SmartAllocate(count* sizeof(ILibChain_Link*)); + count = 0; + node = ILibLinkedList_GetNode_Head(((ILibBaseChain*)chain)->Links); + while (node != NULL) + { + ret[count++] = ILibLinkedList_GetDataFromNode(node); + node = ILibLinkedList_GetNextNode(node); + } + return(ret); +} char *ILibChain_GetMetaDataFromDescriptorSet(void *chain, fd_set *inr, fd_set *inw, fd_set *ine) { char *ret = NULL; @@ -3299,6 +3319,29 @@ char *ILibChain_GetMetaDataFromDescriptorSetEx(void *chain, fd_set *inr, fd_set return(retStr); } +int ILibChain_GetMinimumTimer(void *chain) +{ + int minimum = -1; + void *node; + struct LifeTimeMonitorData *Temp = NULL; + struct ILibLifeTime *LifeTimeMonitor = (struct ILibLifeTime*)ILibGetBaseTimer(chain); + int64_t current = ILibGetUptime(); + + ILibLinkedList_Lock(LifeTimeMonitor->ObjectList); + node = ILibLinkedList_GetNode_Head(LifeTimeMonitor->ObjectList); + while (node != NULL) + { + if ((Temp = (struct LifeTimeMonitorData*)ILibLinkedList_GetDataFromNode(node)) == NULL) + { + node = ILibLinkedList_GetNextNode(node); + continue; + } + minimum = (int)(Temp->ExpirationTick - current); + node = NULL; + } + ILibLinkedList_UnLock(LifeTimeMonitor->ObjectList); + return(minimum); +} char *ILibChain_GetMetadataForTimers(void *chain) { void *node; diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index f986649..f5c7dcc 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -1068,6 +1068,8 @@ int ILibIsRunningOnChainThread(void* chain); char *ILibChain_GetMetaDataFromDescriptorSet(void *chain, fd_set *inr, fd_set *inw, fd_set *ine); char *ILibChain_GetMetaDataFromDescriptorSetEx(void *chain, fd_set *inr, fd_set *inw, fd_set *ine); char *ILibChain_GetMetadataForTimers(void *chain); + int ILibChain_GetMinimumTimer(void *chain); + ILibChain_Link **ILibChain_GetModules(void *chain); #ifdef WIN32 typedef void(*ILib_GenericReadHandler)(char *buffer, int bufferLen, DWORD* bytesConsumed, void* user1, void *user2); typedef BOOL(*ILibChain_ReadEx_Handler)(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus status, char *buffer, DWORD bytesRead, void* user);