diff --git a/desktop/api.cpp b/desktop/api.cpp index 6cf2880..37bf94e 100644 --- a/desktop/api.cpp +++ b/desktop/api.cpp @@ -191,6 +191,8 @@ struct { Array systemConfigurationGroups; EsMutex systemConfigurationMutex; + EsHandle desktopRequestPipe, desktopResponsePipe; + Array mountPoints; Array connectedDevices; bool foundBootFileSystem; @@ -1049,7 +1051,7 @@ EsMessage *EsMessageReceive() { } else if (message.message.type == ES_MSG_APPLICATION_EXIT) { if (api.startupInformation->isDesktop) { // Desktop tracks the number of instances it owns, so it needs to know when it exits. - ApplicationProcessTerminated(EsProcessGetID(ES_CURRENT_PROCESS)); + ApplicationProcessTerminated(DesktopGetApplicationProcessForDesktop()); } else { api.workFinish = true; if (api.workAvailable) EsEventSet(api.workAvailable); @@ -1573,6 +1575,8 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) { const SystemStartupDataHeader *header = (const SystemStartupDataHeader *) EsBufferRead(&buffer, sizeof(SystemStartupDataHeader)); theming.cursorData = header->themeCursorData; + api.desktopRequestPipe = header->desktopRequestPipe; + api.desktopResponsePipe = header->desktopResponsePipe; for (uintptr_t i = 0; i < header->initialMountPointCount; i++) { const EsMountPoint *mountPoint = (const EsMountPoint *) EsBufferRead(&buffer, sizeof(EsMountPoint)); diff --git a/desktop/desktop.cpp b/desktop/desktop.cpp index ed8cb96..591c195 100644 --- a/desktop/desktop.cpp +++ b/desktop/desktop.cpp @@ -138,6 +138,7 @@ struct BlankTabInstance : EsInstance { struct ApplicationProcess { EsObjectID id; EsHandle handle; + EsHandle desktopRequestPipe, desktopResponsePipe; InstalledApplication *application; size_t instanceCount; }; @@ -1664,6 +1665,127 @@ void ApplicationTemporaryDestroy(InstalledApplication *application) { EsAssert(false); } +void ApplicationProcessTerminated(ApplicationProcess *process) { + EsMessageMutexCheck(); + + desktop.allApplicationProcesses.FindAndDeleteSwap(process, true /* assert found */); + + for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) { + ApplicationInstance *instance = desktop.allApplicationInstances[i]; + + if (instance->process == process) { + EmbeddedWindowDestroyed(instance->embeddedWindowID); + i--; // EmbeddedWindowDestroyed removes it from the array. + } + } + + InstalledApplication *application = process->application; + + if (application) { + if (application->singleProcess == process) { + application->singleProcess = nullptr; + } + + application->singleInstance = nullptr; + ApplicationTemporaryDestroy(application); + } + + for (uintptr_t i = 0; i < desktop.openDocuments.Count(); i++) { + OpenDocument *document = &desktop.openDocuments[i]; + + if (document->currentWriter == process->id) { + document->currentWriter = 0; + } + } + + if (!desktop.allApplicationProcesses.Length() && desktop.inShutdown) { + EsEventSet(desktop.shutdownReadyEvent); + } + + EsAssert(!process->instanceCount); + EsHandleClose(process->handle); + + if (process->desktopRequestPipe) { + EsHandleClose(process->desktopRequestPipe); + EsHandleClose(process->desktopResponsePipe); + } else { + // This must be a Desktop-owned instance. + } + + EsHeapFree(process); +} + +void DesktopRequestThread(EsGeneric argument) { + ApplicationProcess *process = (ApplicationProcess *) argument.p; + + uint32_t length; + size_t bytes; + EsObjectID embeddedWindowID; + + while (true) { + bytes = EsPipeRead(process->desktopRequestPipe, &length, sizeof(length)); + if (bytes != sizeof(length)) break; // Process has terminated or closed the pipe. + bytes = EsPipeRead(process->desktopRequestPipe, &embeddedWindowID, sizeof(embeddedWindowID)); + if (bytes != sizeof(embeddedWindowID)) break; // Process has terminated or closed the pipe. + + if (length < 1 || length > DESKTOP_MESSAGE_SIZE_LIMIT) { + // Discard the message. + // TODO Crash the process. + EsPipeRead(process->desktopRequestPipe, nullptr, length); + continue; + } + + void *buffer = EsHeapAllocate(length, false); + bytes = EsPipeRead(process->desktopRequestPipe, buffer, length); + if (bytes != length) break; // Process has terminated or closed the pipe. + + if (!buffer) { + // The buffer could not be allocated, and the data read from the pipe was discarded. + continue; + } + + EsBuffer response = { .canGrow = true }; + + EsMessageMutexAcquire(); + + if (!DesktopSyscall(embeddedWindowID, process, (uint8_t *) buffer, length, &response)) { + // TODO Crash the process. + EsPrint("Process %d running application '%z' had a fatal error (this usually means a permission check failed) with desktop request #%d.\n", + process->id, process->application->cName, *(uint8_t *) buffer); + } + + EsMessageMutexRelease(); + + if (!response.error) { + length = response.position; + EsPipeWrite(process->desktopResponsePipe, &length, sizeof(length)); + EsPipeWrite(process->desktopResponsePipe, response.out, response.position); + } else { + length = 0; + EsPipeWrite(process->desktopResponsePipe, &length, sizeof(length)); + } + + EsHeapFree(response.out); + EsHeapFree(buffer); + } + + EsMessageMutexAcquire(); + ApplicationProcessTerminated(process); + EsMessageMutexRelease(); +} + +ApplicationProcess *DesktopGetApplicationProcessForDesktop() { + EsObjectID desktopProcessID = EsProcessGetID(ES_CURRENT_PROCESS); + + for (uintptr_t i = 0; i < desktop.allApplicationProcesses.Length(); i++) { + if (desktop.allApplicationProcesses[i]->id == desktopProcessID) { + return desktop.allApplicationProcesses[i]; + } + } + + return nullptr; +} + bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInformation *startupInformation, ApplicationInstance *instance) { if (desktop.inShutdown) { return false; @@ -1708,19 +1830,12 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform ApplicationProcess *process = application->singleProcess; if (application->createInstance) { - EsObjectID desktopProcessID = EsProcessGetID(ES_CURRENT_PROCESS); - - for (uintptr_t i = 0; i < desktop.allApplicationProcesses.Length(); i++) { - if (desktop.allApplicationProcesses[i]->id == desktopProcessID) { - process = desktop.allApplicationProcesses[i]; - break; - } - } + process = DesktopGetApplicationProcessForDesktop(); if (!process) { process = (ApplicationProcess *) EsHeapAllocate(sizeof(ApplicationProcess), true); process->handle = EsSyscall(ES_SYSCALL_HANDLE_SHARE, ES_CURRENT_PROCESS, ES_CURRENT_PROCESS, 0, 0); - process->id = desktopProcessID; + process->id = EsProcessGetID(ES_CURRENT_PROCESS); desktop.allApplicationProcesses.Add(process); } } else if (!process) { @@ -1810,10 +1925,16 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform } } + EsHandle desktopRequestReadEnd, desktopRequestWriteEnd, desktopResponseReadEnd, desktopResponseWriteEnd; + EsPipeCreate(&desktopRequestReadEnd, &desktopRequestWriteEnd); + EsPipeCreate(&desktopResponseReadEnd, &desktopResponseWriteEnd); + EsBuffer buffer = { .canGrow = true }; header.initialMountPointCount = initialMountPoints.Length(); header.initialDeviceCount = initialDevices.Length(); header.themeCursorData = theming.cursorData; + header.desktopRequestPipe = desktopRequestWriteEnd; + header.desktopResponsePipe = desktopResponseReadEnd; EsBufferWrite(&buffer, &header, sizeof(header)); EsBufferWrite(&buffer, initialMountPoints.array, sizeof(EsMountPoint) * header.initialMountPointCount); EsBufferWrite(&buffer, initialDevices.array, sizeof(EsMessageDevice) * header.initialDeviceCount); @@ -1822,6 +1943,10 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform handleModeDuplicateList.Add(0); handleDuplicateList.Add(header.themeCursorData); handleModeDuplicateList.Add(0); + handleDuplicateList.Add(header.desktopRequestPipe); + handleModeDuplicateList.Add(0); + handleDuplicateList.Add(header.desktopResponsePipe); + handleModeDuplicateList.Add(0); EsHeapFree(buffer.out); arguments.handles = handleDuplicateList.array; @@ -1835,6 +1960,9 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform if (settingsNode.handle) EsHandleClose(settingsNode.handle); if (arguments.data.systemData) EsHandleClose(arguments.data.systemData); + EsHandleClose(desktopResponseReadEnd); + EsHandleClose(desktopRequestWriteEnd); + if (!ES_CHECK_ERROR(error)) { EsHandleClose(information.mainThread.handle); @@ -1842,8 +1970,17 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform process->handle = information.handle; process->id = information.pid; process->application = application; + process->desktopResponsePipe = desktopResponseWriteEnd; + process->desktopRequestPipe = desktopRequestReadEnd; desktop.allApplicationProcesses.Add(process); + + EsThreadInformation information; + EsThreadCreate(DesktopRequestThread, &information, process); + EsHandleClose(information.handle); } else { + EsHandleClose(desktopRequestReadEnd); + EsHandleClose(desktopResponseWriteEnd); + ApplicationTemporaryDestroy(application); _EsApplicationStartupInformation s = {}; s.data = CRASHED_TAB_INVALID_EXECUTABLE; @@ -1931,15 +2068,11 @@ ApplicationInstance *ApplicationInstanceCreate(int64_t id, _EsApplicationStartup } } -ApplicationProcess *ApplicationProcessFindByPID(EsObjectID pid, bool removeIfFound = false) { +ApplicationProcess *ApplicationProcessFindByPID(EsObjectID pid) { for (uintptr_t i = 0; i < desktop.allApplicationProcesses.Length(); i++) { ApplicationProcess *process = desktop.allApplicationProcesses[i]; if (process->id == pid) { - if (removeIfFound) { - desktop.allApplicationProcesses.DeleteSwap(i); - } - return process; } } @@ -1994,48 +2127,6 @@ void ApplicationInstanceCrashed(EsMessage *message) { EsHandleClose(processHandle); } -void ApplicationProcessTerminated(EsObjectID pid) { - for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) { - ApplicationInstance *instance = desktop.allApplicationInstances[i]; - - if (instance->process->id == pid) { - EmbeddedWindowDestroyed(instance->embeddedWindowID); - i--; // EmbeddedWindowDestroyed removes it from the array. - } - } - - ApplicationProcess *process = ApplicationProcessFindByPID(pid, true /* remove from array */); - - if (process) { - InstalledApplication *application = process->application; - - if (application) { - if (application->singleProcess && application->singleProcess->id == pid) { - application->singleProcess = nullptr; - } - - application->singleInstance = nullptr; - ApplicationTemporaryDestroy(application); - } - - EsAssert(!process->instanceCount); - EsHandleClose(process->handle); - EsHeapFree(process); - } - - for (uintptr_t i = 0; i < desktop.openDocuments.Count(); i++) { - OpenDocument *document = &desktop.openDocuments[i]; - - if (document->currentWriter == pid) { - document->currentWriter = 0; - } - } - - if (!desktop.allApplicationProcesses.Length() && desktop.inShutdown) { - EsEventSet(desktop.shutdownReadyEvent); - } -} - ////////////////////////////////////////////////////// // Document management: ////////////////////////////////////////////////////// @@ -2693,60 +2784,61 @@ void DesktopSetup() { desktop.setupDesktopUIComplete = true; } -void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { - ApplicationInstance *instance = ApplicationInstanceFindByWindowID(message->desktop.windowID); +bool /* returns false on fatal error */ DesktopSyscall(EsObjectID windowID, ApplicationProcess *process, uint8_t *buffer, size_t bytes, EsBuffer *pipe) { + EsMessageMutexCheck(); + EsAssert(process); + + ApplicationInstance *instance = ApplicationInstanceFindByWindowID(windowID); + InstalledApplication *application = process->application; + + if (instance && instance->process != process) { + EsPrint("DesktopSyscall - Process %d cannot operate on instance %d.\n", process->id, instance->embeddedWindowID); + return false; + } if (buffer[0] == DESKTOP_MSG_START_APPLICATION) { - InstalledApplication *application = ApplicationFindByPID(message->desktop.processID); + if (~application->permissions & APPLICATION_PERMISSION_START_APPLICATION) return false; - if (application && (application->permissions & APPLICATION_PERMISSION_START_APPLICATION)) { - // TODO Restricting what flags can be requested? - EsBuffer b = { .in = buffer + 1, .bytes = message->desktop.bytes - 1 }; - EsApplicationStartupRequest request = {}; - EsBufferReadInto(&b, &request, sizeof(EsApplicationStartupRequest)); - request.filePath = (const char *) EsBufferRead(&b, request.filePathBytes); + // TODO Restricting what flags can be requested? + EsBuffer b = { .in = buffer + 1, .bytes = bytes - 1 }; + EsApplicationStartupRequest request = {}; + EsBufferReadInto(&b, &request, sizeof(EsApplicationStartupRequest)); + request.filePath = (const char *) EsBufferRead(&b, request.filePathBytes); - if (!b.error) { - ContainerWindow *container = nullptr /* new container */; + if (!b.error) { + ContainerWindow *container = nullptr /* new container */; - if ((request.flags & ES_APPLICATION_STARTUP_IN_SAME_CONTAINER) && instance && instance->tab) { - container = instance->tab->container; - } - - OpenDocumentWithApplication(&request, container); + if ((request.flags & ES_APPLICATION_STARTUP_IN_SAME_CONTAINER) && instance && instance->tab) { + container = instance->tab->container; } + + OpenDocumentWithApplication(&request, container); } } else if (buffer[0] == DESKTOP_MSG_CREATE_CLIPBOARD_FILE && pipe) { - EsHandle processHandle = EsProcessOpen(message->desktop.processID); + EsHandle handle; + char *path; + size_t pathBytes; + EsError error = TemporaryFileCreate(&handle, &path, &pathBytes, ES_FILE_WRITE); - if (processHandle) { - EsHandle handle; - char *path; - size_t pathBytes; - EsError error = TemporaryFileCreate(&handle, &path, &pathBytes, ES_FILE_WRITE); - - if (error == ES_SUCCESS) { - if (desktop.nextClipboardFile) { - EsHandleClose(desktop.nextClipboardFile); - } - - desktop.nextClipboardFile = handle; - desktop.nextClipboardProcessID = message->desktop.processID; - - handle = EsSyscall(ES_SYSCALL_HANDLE_SHARE, handle, processHandle, 0, 0); - - EsHeapFree(path); - } else { - handle = ES_INVALID_HANDLE; + if (error == ES_SUCCESS) { + if (desktop.nextClipboardFile) { + EsHandleClose(desktop.nextClipboardFile); } - EsBufferWrite(pipe, &handle, sizeof(handle)); - EsBufferWrite(pipe, &error, sizeof(error)); + desktop.nextClipboardFile = handle; + desktop.nextClipboardProcessID = process->id; - EsHandleClose(processHandle); + handle = EsSyscall(ES_SYSCALL_HANDLE_SHARE, handle, process->handle, 0, 0); + + EsHeapFree(path); + } else { + handle = ES_INVALID_HANDLE; } - } else if (buffer[0] == DESKTOP_MSG_CLIPBOARD_PUT && message->desktop.bytes == sizeof(ClipboardInformation) - && desktop.nextClipboardFile && desktop.nextClipboardProcessID == message->desktop.processID) { + + EsBufferWrite(pipe, &handle, sizeof(handle)); + EsBufferWrite(pipe, &error, sizeof(error)); + } else if (buffer[0] == DESKTOP_MSG_CLIPBOARD_PUT && bytes == sizeof(ClipboardInformation) + && desktop.nextClipboardFile && desktop.nextClipboardProcessID == process->id) { ClipboardInformation *information = (ClipboardInformation *) buffer; if (information->error == ES_SUCCESS) { @@ -2772,83 +2864,62 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { desktop.nextClipboardFile = ES_INVALID_HANDLE; desktop.nextClipboardProcessID = 0; } else if (buffer[0] == DESKTOP_MSG_CLIPBOARD_GET && pipe) { - EsHandle processHandle = EsProcessOpen(message->desktop.processID); - - if (processHandle) { - EsHandle fileHandle = desktop.clipboardFile - ? EsSyscall(ES_SYSCALL_HANDLE_SHARE, desktop.clipboardFile, processHandle, 1 /* ES_FILE_READ_SHARED */, 0) : ES_INVALID_HANDLE; - EsBufferWrite(pipe, &desktop.clipboardInformation, sizeof(desktop.clipboardInformation)); - EsBufferWrite(pipe, &fileHandle, sizeof(fileHandle)); - EsHandleClose(processHandle); - } + EsHandle fileHandle = desktop.clipboardFile + ? EsSyscall(ES_SYSCALL_HANDLE_SHARE, desktop.clipboardFile, process->handle, 1 /* ES_FILE_READ_SHARED */, 0) : ES_INVALID_HANDLE; + EsBufferWrite(pipe, &desktop.clipboardInformation, sizeof(desktop.clipboardInformation)); + EsBufferWrite(pipe, &fileHandle, sizeof(fileHandle)); } else if (buffer[0] == DESKTOP_MSG_SYSTEM_CONFIGURATION_GET && pipe) { - InstalledApplication *application = ApplicationFindByPID(message->desktop.processID); - ConfigurationWriteSectionsToBuffer("font", nullptr, false, pipe); ConfigurationWriteSectionsToBuffer(nullptr, "ui_fonts", false, pipe); - if (application && (application->permissions & APPLICATION_PERMISSION_ALL_FILES)) { + if (application->permissions & APPLICATION_PERMISSION_ALL_FILES) { ConfigurationWriteSectionsToBuffer(nullptr, "paths", false, pipe); } } else if (buffer[0] == DESKTOP_MSG_REQUEST_SHUTDOWN) { - InstalledApplication *application = ApplicationFindByPID(message->desktop.processID); - - if (application && (application->permissions & APPLICATION_PERMISSION_SHUTDOWN)) { - ShutdownModalCreate(); - } + if (~application->permissions & APPLICATION_PERMISSION_SHUTDOWN) return false; + ShutdownModalCreate(); } else if (buffer[0] == DESKTOP_MSG_FILE_TYPES_GET && pipe) { - InstalledApplication *application = ApplicationFindByPID(message->desktop.processID); + if (~application->permissions & APPLICATION_PERMISSION_VIEW_FILE_TYPES) return false; + ConfigurationWriteSectionsToBuffer("file_type", nullptr, false, pipe); + } else if (buffer[0] == DESKTOP_MSG_ANNOUNCE_PATH_MOVED && bytes > 1 + sizeof(uintptr_t) * 2) { + if (~application->permissions & APPLICATION_PERMISSION_ALL_FILES) return false; - if (application && (application->permissions & APPLICATION_PERMISSION_VIEW_FILE_TYPES)) { - ConfigurationWriteSectionsToBuffer("file_type", nullptr, false, pipe); + uintptr_t oldPathBytes, newPathBytes; + EsMemoryCopy(&oldPathBytes, buffer + 1, sizeof(uintptr_t)); + EsMemoryCopy(&newPathBytes, buffer + 1 + sizeof(uintptr_t), sizeof(uintptr_t)); + + if (oldPathBytes >= 0x4000 || newPathBytes >= 0x4000 + || oldPathBytes + newPathBytes + sizeof(uintptr_t) * 2 + 1 != bytes) { + return true; } - } else if (buffer[0] == DESKTOP_MSG_ANNOUNCE_PATH_MOVED && message->desktop.bytes > 1 + sizeof(uintptr_t) * 2) { - InstalledApplication *application = ApplicationFindByPID(message->desktop.processID); - if (application && (application->permissions & APPLICATION_PERMISSION_ALL_FILES)) { - uintptr_t oldPathBytes, newPathBytes; - EsMemoryCopy(&oldPathBytes, buffer + 1, sizeof(uintptr_t)); - EsMemoryCopy(&newPathBytes, buffer + 1 + sizeof(uintptr_t), sizeof(uintptr_t)); + const char *oldPath = (const char *) buffer + 1 + sizeof(uintptr_t) * 2; + const char *newPath = (const char *) buffer + 1 + sizeof(uintptr_t) * 2 + oldPathBytes; - if (oldPathBytes >= 0x4000 || newPathBytes >= 0x4000 - || oldPathBytes + newPathBytes + sizeof(uintptr_t) * 2 + 1 != message->desktop.bytes) { - return; - } - - const char *oldPath = (const char *) buffer + 1 + sizeof(uintptr_t) * 2; - const char *newPath = (const char *) buffer + 1 + sizeof(uintptr_t) * 2 + oldPathBytes; - - InstanceAnnouncePathMoved(application, oldPath, oldPathBytes, newPath, newPathBytes); - } + InstanceAnnouncePathMoved(application, oldPath, oldPathBytes, newPath, newPathBytes); } else if (buffer[0] == DESKTOP_MSG_START_USER_TASK && pipe) { - ApplicationProcess *process = ApplicationProcessFindByPID(message->desktop.processID); - if (!process || !process->instanceCount) { - return; + return false; } - InstalledApplication *application = process->application; - // HACK User tasks use an embedded window object for IPC. // This allows us to basically treat them like other instances. - EsHandle processHandle = EsProcessOpen(message->desktop.processID); EsHandle windowHandle = EsSyscall(ES_SYSCALL_WINDOW_CREATE, ES_WINDOW_NORMAL, 0, 0, 0); ApplicationInstance *instance = (ApplicationInstance *) EsHeapAllocate(sizeof(ApplicationInstance), true); bool added = false; - if (processHandle && windowHandle && instance) { + if (windowHandle && instance) { added = desktop.allApplicationInstances.Add(instance); } - if (!processHandle || !windowHandle || !instance || !added) { - if (processHandle) EsHandleClose(processHandle); + if (!windowHandle || !instance || !added) { if (windowHandle) EsHandleClose(windowHandle); if (instance) EsHeapFree(instance); EsHandle invalid = ES_INVALID_HANDLE; EsBufferWrite(pipe, &invalid, sizeof(invalid)); - return; + return true; } instance->title[0] = ' '; @@ -2860,99 +2931,94 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { instance->process->instanceCount++; instance->application = application; - EsHandle targetWindowHandle = EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, windowHandle, processHandle, 0, ES_WINDOW_PROPERTY_EMBED_OWNER); + EsHandle targetWindowHandle = EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, windowHandle, process->handle, 0, ES_WINDOW_PROPERTY_EMBED_OWNER); EsBufferWrite(pipe, &targetWindowHandle, sizeof(targetWindowHandle)); desktop.allOngoingUserTasks.Add(instance); TaskBarTasksButtonUpdate(); } else if (buffer[0] == DESKTOP_MSG_QUERY_OPEN_DOCUMENT) { - InstalledApplication *application = ApplicationFindByPID(message->desktop.processID); + if (~application->permissions & APPLICATION_PERMISSION_ALL_FILES) return false; - if (application && (application->permissions & APPLICATION_PERMISSION_ALL_FILES)) { - EsObjectID id = 0; + EsObjectID id = 0; - for (uintptr_t i = 0; i < desktop.openDocuments.Count(); i++) { - OpenDocument *document = &desktop.openDocuments[i]; + for (uintptr_t i = 0; i < desktop.openDocuments.Count(); i++) { + OpenDocument *document = &desktop.openDocuments[i]; - if (0 == EsStringCompare(document->path, document->pathBytes, (char *) buffer + 1, message->desktop.bytes - 1)) { - id = document->id; + if (0 == EsStringCompare(document->path, document->pathBytes, (char *) buffer + 1, bytes - 1)) { + id = document->id; + break; + } + } + + EsOpenDocumentInformation information; + EsMemoryZero(&information, sizeof(information)); + + if (id) { + information.isOpen = true; + + for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) { + ApplicationInstance *instance = desktop.allApplicationInstances[i]; + + if (instance->documentID == id) { + information.isModified = instance->tab && (instance->tab->closeButton->customStyleState & THEME_STATE_CHECKED); + information.applicationNameBytes = MinimumInteger(EsCStringLength(instance->application->cName), + sizeof(information.applicationName)); + EsMemoryCopy(information.applicationName, instance->application->cName, information.applicationNameBytes); break; } } - - EsOpenDocumentInformation information; - EsMemoryZero(&information, sizeof(information)); - - if (id) { - information.isOpen = true; - - for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) { - ApplicationInstance *instance = desktop.allApplicationInstances[i]; - - if (instance->documentID == id) { - information.isModified = instance->tab && (instance->tab->closeButton->customStyleState & THEME_STATE_CHECKED); - information.applicationNameBytes = MinimumInteger(EsCStringLength(instance->application->cName), - sizeof(information.applicationName)); - EsMemoryCopy(information.applicationName, instance->application->cName, information.applicationNameBytes); - break; - } - } - } - - EsBufferWrite(pipe, &information, sizeof(information)); } + + EsBufferWrite(pipe, &information, sizeof(information)); } else if (buffer[0] == DESKTOP_MSG_LIST_OPEN_DOCUMENTS) { - InstalledApplication *application = ApplicationFindByPID(message->desktop.processID); + if (~application->permissions & APPLICATION_PERMISSION_ALL_FILES) return false; - if (application && (application->permissions & APPLICATION_PERMISSION_ALL_FILES)) { - size_t count = desktop.openDocuments.Count(); - EsBufferWrite(pipe, &count, sizeof(size_t)); + size_t count = desktop.openDocuments.Count(); + EsBufferWrite(pipe, &count, sizeof(size_t)); - for (uintptr_t i = 0; i < count; i++) { - OpenDocument *document = &desktop.openDocuments[i]; - EsBufferWrite(pipe, &document->pathBytes, sizeof(size_t)); - EsBufferWrite(pipe, document->path, document->pathBytes); - } + for (uintptr_t i = 0; i < count; i++) { + OpenDocument *document = &desktop.openDocuments[i]; + EsBufferWrite(pipe, &document->pathBytes, sizeof(size_t)); + EsBufferWrite(pipe, document->path, document->pathBytes); } } else if (buffer[0] == DESKTOP_MSG_RUN_TEMPORARY_APPLICATION) { - InstalledApplication *requestingApplication = ApplicationFindByPID(message->desktop.processID); + InstalledApplication *requestingApplication = application; + if (~requestingApplication->permissions & APPLICATION_PERMISSION_RUN_TEMPORARY_APPLICATION) return false; - if (requestingApplication && (requestingApplication->permissions & APPLICATION_PERMISSION_RUN_TEMPORARY_APPLICATION)) { - for (uintptr_t i = 0; i < desktop.installedApplications.Length(); i++) { - if (EsCStringLength(desktop.installedApplications[i]->cExecutable) == message->desktop.bytes - 1 - && 0 == EsMemoryCompare(desktop.installedApplications[i]->cExecutable, buffer + 1, message->desktop.bytes - 1)) { - ApplicationInstanceCreate(desktop.installedApplications[i]->id, nullptr, nullptr); - return; - } + for (uintptr_t i = 0; i < desktop.installedApplications.Length(); i++) { + if (EsCStringLength(desktop.installedApplications[i]->cExecutable) == bytes - 1 + && 0 == EsMemoryCompare(desktop.installedApplications[i]->cExecutable, buffer + 1, bytes - 1)) { + ApplicationInstanceCreate(desktop.installedApplications[i]->id, nullptr, nullptr); + return true; } - - InstalledApplication *application = (InstalledApplication *) EsHeapAllocate(sizeof(InstalledApplication), true); - if (!application) return; - application->temporary = true; - application->hidden = true; - application->useSingleProcess = true; - application->cExecutable = (char *) EsHeapAllocate(message->desktop.bytes, false); - if (!application->cExecutable) { EsHeapFree(application); return; } - EsMemoryCopy(application->cExecutable, buffer + 1, message->desktop.bytes - 1); - application->cExecutable[message->desktop.bytes - 1] = 0; - static int64_t nextTemporaryID = -1; - application->id = nextTemporaryID--; - application->cName = (char *) EsHeapAllocate(32, false); - if (!application->cName) { EsHeapFree(application->cExecutable); EsHeapFree(application); return; } - for (int i = 1; i < 31; i++) application->cName[i] = (EsRandomU8() % 26) + 'a'; - application->cName[0] = '_', application->cName[31] = 0; - EsHandle handle; - EsError error = TemporaryFileCreate(&handle, &application->settingsPath, &application->settingsPathBytes, ES_NODE_DIRECTORY); - if (error == ES_SUCCESS) EsHandleClose(handle); - desktop.installedApplications.Add(application); - ApplicationInstanceCreate(application->id, nullptr, nullptr); } + + InstalledApplication *temporaryApplication = (InstalledApplication *) EsHeapAllocate(sizeof(InstalledApplication), true); + if (!temporaryApplication) return true; + temporaryApplication->temporary = true; + temporaryApplication->hidden = true; + temporaryApplication->useSingleProcess = true; + temporaryApplication->cExecutable = (char *) EsHeapAllocate(bytes, false); + if (!temporaryApplication->cExecutable) { EsHeapFree(temporaryApplication); return true; } + EsMemoryCopy(temporaryApplication->cExecutable, buffer + 1, bytes - 1); + temporaryApplication->cExecutable[bytes - 1] = 0; + static int64_t nextTemporaryID = -1; + temporaryApplication->id = nextTemporaryID--; + temporaryApplication->cName = (char *) EsHeapAllocate(32, false); + if (!temporaryApplication->cName) { EsHeapFree(temporaryApplication->cExecutable); EsHeapFree(temporaryApplication); return true; } + for (int i = 1; i < 31; i++) temporaryApplication->cName[i] = (EsRandomU8() % 26) + 'a'; + temporaryApplication->cName[0] = '_', temporaryApplication->cName[31] = 0; + EsHandle handle; + EsError error = TemporaryFileCreate(&handle, &temporaryApplication->settingsPath, &temporaryApplication->settingsPathBytes, ES_NODE_DIRECTORY); + if (error == ES_SUCCESS) EsHandleClose(handle); + desktop.installedApplications.Add(temporaryApplication); + ApplicationInstanceCreate(temporaryApplication->id, nullptr, nullptr); } else if ((buffer[0] == DESKTOP_MSG_SET_TITLE || buffer[0] == DESKTOP_MSG_SET_ICON) && instance) { if (buffer[0] == DESKTOP_MSG_SET_TITLE) { instance->titleBytes = EsStringFormat(instance->title, sizeof(instance->title), "%s", - message->desktop.bytes - 1, buffer + 1); + bytes - 1, buffer + 1); } else { - if (message->desktop.bytes == 5) { + if (bytes == 5) { EsMemoryCopy(&instance->iconID, buffer + 1, sizeof(uint32_t)); } } @@ -2968,11 +3034,11 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { instance->tab->container->taskBarButton->Repaint(true); } } - } else if (buffer[0] == DESKTOP_MSG_SET_MODIFIED && message->desktop.bytes == 2 && instance) { + } else if (buffer[0] == DESKTOP_MSG_SET_MODIFIED && bytes == 2 && instance) { if (instance->tab) { EsButtonSetCheck(instance->tab->closeButton, buffer[1] ? ES_CHECK_CHECKED : ES_CHECK_UNCHECKED, false); } - } else if (buffer[0] == DESKTOP_MSG_SET_PROGRESS && message->desktop.bytes == 1 + sizeof(double) && instance->isUserTask && instance) { + } else if (buffer[0] == DESKTOP_MSG_SET_PROGRESS && bytes == 1 + sizeof(double) && instance->isUserTask && instance) { double progress; EsMemoryCopy(&progress, buffer + 1, sizeof(double)); @@ -2982,10 +3048,10 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { EsElementRepaint(desktop.tasksButton); } } else if (buffer[0] == DESKTOP_MSG_REQUEST_SAVE && instance) { - ApplicationInstanceRequestSave(instance, (const char *) buffer + 1, message->desktop.bytes - 1, false); + ApplicationInstanceRequestSave(instance, (const char *) buffer + 1, bytes - 1, false); } else if (buffer[0] == DESKTOP_MSG_RENAME && instance) { const char *newName = (const char *) buffer + 1; - size_t newNameBytes = message->desktop.bytes - 1; + size_t newNameBytes = bytes - 1; OpenDocument *document = desktop.openDocuments.Get(&instance->documentID); if (!instance->documentID) { @@ -3033,7 +3099,10 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { } } else { EsPrint("DesktopSyscall - Received unhandled message %d.\n", buffer[0]); + return false; } + + return true; } void EmbeddedWindowDestroyed(EsObjectID id) { @@ -3063,25 +3132,9 @@ void DesktopSendMessage(EsMessage *message) { } if (message->type == ES_MSG_EMBEDDED_WINDOW_DESTROYED) { - EmbeddedWindowDestroyed(message->desktop.windowID); - } else if (message->type == ES_MSG_DESKTOP) { - uint8_t *buffer = (uint8_t *) EsHeapAllocate(message->desktop.bytes, false); - - if (buffer) { - EsConstantBufferRead(message->desktop.buffer, buffer); - EsBuffer pipe = { .canGrow = true }; - DesktopSyscall(message, buffer, &pipe); - if (message->desktop.pipe) EsPipeWrite(message->desktop.pipe, pipe.out, pipe.position); - EsHeapFree(pipe.out); - EsHeapFree(buffer); - } - - EsHandleClose(message->desktop.buffer); - if (message->desktop.pipe) EsHandleClose(message->desktop.pipe); + EmbeddedWindowDestroyed(message->embeddedWindowDestroyedID); } else if (message->type == ES_MSG_APPLICATION_CRASH) { ApplicationInstanceCrashed(message); - } else if (message->type == ES_MSG_PROCESS_TERMINATED) { - ApplicationProcessTerminated(message->crash.pid); } else if (message->type == ES_MSG_REGISTER_FILE_SYSTEM) { EsHandle rootDirectory = message->registerFileSystem.rootDirectory; diff --git a/desktop/os.header b/desktop/os.header index e828822..00335ca 100644 --- a/desktop/os.header +++ b/desktop/os.header @@ -856,8 +856,6 @@ private enum EsSyscallType { ES_SYSCALL_WINDOW_SET_CURSOR ES_SYSCALL_WINDOW_SET_PROPERTY - ES_SYSCALL_MESSAGE_DESKTOP - // IO. ES_SYSCALL_NODE_OPEN @@ -1782,12 +1780,6 @@ struct EsMessageProcessCrash { uintptr_t pid; }; -struct EsMessageDesktop { - EsObjectID windowID, processID; - EsHandle buffer, pipe; - size_t bytes; -}; - struct EsMessageEyedrop { uint32_t color; bool cancelled; @@ -1892,13 +1884,13 @@ struct EsMessage { // Internal messages: void *_argument; EsMessageProcessCrash crash; - EsMessageDesktop desktop; EsMessageEyedrop eyedrop; EsMessageCreateInstance createInstance; EsMessageTabOperation tabOperation; EsMessageRegisterFileSystem registerFileSystem; EsMessageUnregisterFileSystem unregisterFileSystem; EsMessageDevice device; + EsObjectID embeddedWindowDestroyedID; }; } @@ -2247,7 +2239,7 @@ function bool EsMouseIsMiddleHeld(); // Pipes. function void EsPipeCreate(EsHandle *readEnd, EsHandle *writeEnd); -function size_t EsPipeRead(EsHandle pipe, void *buffer, size_t bytes); +function size_t EsPipeRead(EsHandle pipe, void *buffer, size_t bytes); // If buffer is null, then the data is discarded. function size_t EsPipeWrite(EsHandle pipe, const void *buffer, size_t bytes); // Synchronisation and timing. diff --git a/desktop/prefix.h b/desktop/prefix.h index 796b967..c62c28d 100644 --- a/desktop/prefix.h +++ b/desktop/prefix.h @@ -352,6 +352,7 @@ struct SystemStartupDataHeader { size_t initialMountPointCount; size_t initialDeviceCount; uintptr_t themeCursorData; + uintptr_t desktopRequestPipe, desktopResponsePipe; }; #ifdef KERNEL @@ -397,9 +398,9 @@ extern "C" void *EsBufferWrite(EsBuffer *buffer, const void *source, size_t writ #define ES_THEME_CURSORS_WIDTH (264) #define ES_THEME_CURSORS_HEIGHT (128) -/* Desktop messages: */ +/* Messages sent from Kernel to Desktop: */ #define ES_MSG_EMBEDDED_WINDOW_DESTROYED ((EsMessageType) (ES_MSG_SYSTEM_START + 0x001)) -#define ES_MSG_DESKTOP ((EsMessageType) (ES_MSG_SYSTEM_START + 0x005)) +#define ES_MSG_APPLICATION_CRASH ((EsMessageType) (ES_MSG_SYSTEM_START + 0x002)) /* Messages sent from Desktop to application instances: */ #define ES_MSG_TAB_INSPECT_UI ((EsMessageType) (ES_MSG_SYSTEM_START + 0x101)) @@ -409,16 +410,12 @@ extern "C" void *EsBufferWrite(EsBuffer *buffer, const void *source, size_t writ #define ES_MSG_INSTANCE_DOCUMENT_UPDATED ((EsMessageType) (ES_MSG_SYSTEM_START + 0x105)) #define ES_MSG_INSTANCE_RENAME_RESPONSE ((EsMessageType) (ES_MSG_SYSTEM_START + 0x107)) -/* Debugger messages: */ -#define ES_MSG_APPLICATION_CRASH ((EsMessageType) (ES_MSG_SYSTEM_START + 0x201)) -#define ES_MSG_PROCESS_TERMINATED ((EsMessageType) (ES_MSG_SYSTEM_START + 0x202)) - /* Misc messages: */ -#define ES_MSG_EYEDROP_REPORT ((EsMessageType) (ES_MSG_SYSTEM_START + 0x301)) -#define ES_MSG_TIMER ((EsMessageType) (ES_MSG_SYSTEM_START + 0x302)) -#define ES_MSG_PING ((EsMessageType) (ES_MSG_SYSTEM_START + 0x303)) /* Sent by Desktop to check processes are processing messages. */ -#define ES_MSG_WAKEUP ((EsMessageType) (ES_MSG_SYSTEM_START + 0x304)) /* Sent to wakeup the message thread, so that it can process locally posted messages. */ -#define ES_MSG_INSTANCE_OPEN_DELAYED ((EsMessageType) (ES_MSG_SYSTEM_START + 0x305)) +#define ES_MSG_EYEDROP_REPORT ((EsMessageType) (ES_MSG_SYSTEM_START + 0x201)) +#define ES_MSG_TIMER ((EsMessageType) (ES_MSG_SYSTEM_START + 0x202)) +#define ES_MSG_PING ((EsMessageType) (ES_MSG_SYSTEM_START + 0x203)) /* Sent by Desktop to check processes are processing messages. */ +#define ES_MSG_WAKEUP ((EsMessageType) (ES_MSG_SYSTEM_START + 0x204)) /* Sent to wakeup the message thread, so that it can process locally posted messages. */ +#define ES_MSG_INSTANCE_OPEN_DELAYED ((EsMessageType) (ES_MSG_SYSTEM_START + 0x205)) #endif diff --git a/desktop/syscall.cpp b/desktop/syscall.cpp index 4e95afa..0d29d25 100644 --- a/desktop/syscall.cpp +++ b/desktop/syscall.cpp @@ -749,36 +749,36 @@ size_t EsGameControllerStatePoll(EsGameControllerState *buffer) { return EsSyscall(ES_SYSCALL_GAME_CONTROLLER_STATE_POLL, (uintptr_t) buffer, 0, 0, 0); } -void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe); +bool DesktopSyscall(EsObjectID windowID, struct ApplicationProcess *process, uint8_t *buffer, size_t bytes, EsBuffer *pipe); +struct ApplicationProcess *DesktopGetApplicationProcessForDesktop(); void MessageDesktop(void *message, size_t messageBytes, EsHandle embeddedWindow = ES_INVALID_HANDLE, EsBuffer *responseBuffer = nullptr) { + static EsMutex messageDesktopMutex = {}; + + EsObjectID embeddedWindowID = embeddedWindow ? EsSyscall(ES_SYSCALL_WINDOW_GET_ID, embeddedWindow, 0, 0, 0) : 0; + + EsMutexAcquire(&messageDesktopMutex); + if (api.startupInformation->isDesktop) { - EsMessage m = {}; - m.type = ES_MSG_DESKTOP; - m.desktop.windowID = embeddedWindow ? EsSyscall(ES_SYSCALL_WINDOW_GET_ID, embeddedWindow, 0, 0, 0) : 0; - m.desktop.processID = EsProcessGetID(ES_CURRENT_PROCESS); - m.desktop.bytes = messageBytes; - DesktopSyscall(&m, (uint8_t *) message, responseBuffer); + struct ApplicationProcess *process = DesktopGetApplicationProcessForDesktop(); + bool noFatalErrors = DesktopSyscall(embeddedWindowID, process, (uint8_t *) message, messageBytes, responseBuffer); + EsAssert(noFatalErrors); } else { - EsHandle pipeRead = ES_INVALID_HANDLE, pipeWrite = ES_INVALID_HANDLE; + if (messageBytes <= DESKTOP_MESSAGE_SIZE_LIMIT) { + uint32_t length = messageBytes; + EsPipeWrite(api.desktopRequestPipe, &length, sizeof(length)); + EsPipeWrite(api.desktopRequestPipe, &embeddedWindowID, sizeof(embeddedWindowID)); + EsPipeWrite(api.desktopRequestPipe, message, messageBytes); + EsPipeRead(api.desktopResponsePipe, &length, sizeof(length)); + EsAssert((length != 0) == (responseBuffer != 0)); - if (responseBuffer) { - EsPipeCreate(&pipeRead, &pipeWrite); - } - - EsSyscall(ES_SYSCALL_MESSAGE_DESKTOP, (uintptr_t) message, messageBytes, embeddedWindow, pipeWrite); - - if (responseBuffer) { - char buffer[4096]; - EsHandleClose(pipeWrite); - - while (true) { - size_t bytesRead = EsPipeRead(pipeRead, buffer, sizeof(buffer)); + while (length) { + char buffer[4096]; + size_t bytesRead = EsPipeRead(api.desktopResponsePipe, buffer, sizeof(buffer) > length ? length : sizeof(buffer)); if (!bytesRead) break; EsBufferWrite(responseBuffer, buffer, bytesRead); + length -= bytesRead; } - - EsHandleClose(pipeRead); } } @@ -786,6 +786,8 @@ void MessageDesktop(void *message, size_t messageBytes, EsHandle embeddedWindow responseBuffer->bytes = responseBuffer->position; responseBuffer->position = 0; } + + EsMutexRelease(&messageDesktopMutex); } struct ClipboardInformation { diff --git a/kernel/objects.cpp b/kernel/objects.cpp index 0992144..9f95047 100644 --- a/kernel/objects.cpp +++ b/kernel/objects.cpp @@ -607,14 +607,14 @@ size_t Pipe::Access(void *_buffer, size_t bytes, bool write, bool user) { // EsPrint("\tunread: %d; wp: %d\n", unreadData, writePosition); // EsPrint("\t%d, %d, %d, %d, %d\n", spaceAvailable, spaceAvailableRight, toWrite, toWriteRight, toWriteLeft); - EsMemoryCopy((uint8_t *) buffer + writePosition, _buffer, toWriteRight); - EsMemoryCopy((uint8_t *) buffer, (uint8_t *) _buffer + toWriteRight, toWriteLeft); + if (_buffer) EsMemoryCopy((uint8_t *) buffer + writePosition, _buffer, toWriteRight); + if (_buffer) EsMemoryCopy((uint8_t *) buffer, (uint8_t *) _buffer + toWriteRight, toWriteLeft); writePosition += toWrite; writePosition %= PIPE_BUFFER_SIZE; unreadData += toWrite; bytes -= toWrite; - _buffer = (uint8_t *) _buffer + toWrite; + if (_buffer) _buffer = (uint8_t *) _buffer + toWrite; amount += toWrite; KEventSet(&canRead, true); @@ -640,14 +640,14 @@ size_t Pipe::Access(void *_buffer, size_t bytes, bool write, bool user) { // EsPrint("\tunread: %d; rp: %d\n", unreadData, readPosition); // EsPrint("\t%d, %d, %d, %d, %d\n", dataAvailable, spaceAvailableRight, toRead, toReadRight, toReadLeft); - EsMemoryCopy(_buffer, (uint8_t *) buffer + readPosition, toReadRight); - EsMemoryCopy((uint8_t *) _buffer + toReadRight, (uint8_t *) buffer, toReadLeft); + if (_buffer) EsMemoryCopy(_buffer, (uint8_t *) buffer + readPosition, toReadRight); + if (_buffer) EsMemoryCopy((uint8_t *) _buffer + toReadRight, (uint8_t *) buffer, toReadLeft); readPosition += toRead; readPosition %= PIPE_BUFFER_SIZE; unreadData -= toRead; bytes -= toRead; - _buffer = (uint8_t *) _buffer + toRead; + if (_buffer) _buffer = (uint8_t *) _buffer + toRead; amount += toRead; KEventSet(&canWrite, true); diff --git a/kernel/scheduler.cpp b/kernel/scheduler.cpp index 4bc8e02..047d505 100644 --- a/kernel/scheduler.cpp +++ b/kernel/scheduler.cpp @@ -549,15 +549,6 @@ void ProcessKill(Process *process) { // Don't actually deallocate it yet though; that is done on an async task queued by ProcessRemove. // This must be destroyed after the handle table! MMSpaceDestroy(process->vmm); - - // Tell Desktop the process has terminated. - if (!scheduler.shutdown) { - _EsMessageWithObject m; - EsMemoryZero(&m, sizeof(m)); - m.message.type = ES_MSG_PROCESS_TERMINATED; - m.message.crash.pid = process->id; - DesktopSendMessage(&m); - } } void ThreadKill(KAsyncTask *task) { @@ -1089,6 +1080,8 @@ void ProcessPause(Process *process, bool resume) { } void ProcessCrash(Process *process, EsCrashReason *crashReason) { + EsAssert(process == GetCurrentThread()->process); // TODO Test this function when crashing other processes! + if (process == kernelProcess) { KernelPanic("ProcessCrash - Kernel process has crashed (%d).\n", crashReason->errorCode); } @@ -1097,36 +1090,34 @@ void ProcessCrash(Process *process, EsCrashReason *crashReason) { KernelPanic("ProcessCrash - A critical process has crashed (%d).\n", crashReason->errorCode); } - if (GetCurrentThread()->process != process) { - KernelPanic("ProcessCrash - Attempt to crash process from different process.\n"); - } + bool pauseProcess = false; KMutexAcquire(&process->crashMutex); - if (process->crashed) { - KMutexRelease(&process->crashMutex); - return; - } + if (!process->crashed) { + process->crashed = true; + pauseProcess = true; - process->crashed = true; + KernelLog(LOG_ERROR, "Scheduler", "process crashed", "Process %x has crashed! (%d)\n", process, crashReason->errorCode); - KernelLog(LOG_ERROR, "Scheduler", "process crashed", "Process %x has crashed! (%d)\n", process, crashReason->errorCode); + EsMemoryCopy(&process->crashReason, crashReason, sizeof(EsCrashReason)); - EsMemoryCopy(&process->crashReason, crashReason, sizeof(EsCrashReason)); - - if (!scheduler.shutdown) { - _EsMessageWithObject m; - EsMemoryZero(&m, sizeof(m)); - m.message.type = ES_MSG_APPLICATION_CRASH; - m.message.crash.pid = process->id; - EsMemoryCopy(&m.message.crash.reason, crashReason, sizeof(EsCrashReason)); - DesktopSendMessage(&m); + if (!scheduler.shutdown) { + _EsMessageWithObject m; + EsMemoryZero(&m, sizeof(m)); + m.message.type = ES_MSG_APPLICATION_CRASH; + m.message.crash.pid = process->id; + EsMemoryCopy(&m.message.crash.reason, crashReason, sizeof(EsCrashReason)); + DesktopSendMessage(&m); + } } KMutexRelease(&process->crashMutex); - // TODO Shouldn't this be done before sending the desktop message? - ProcessPause(GetCurrentThread()->process, false); + if (pauseProcess) { + // TODO Shouldn't this be done before sending the desktop message? + ProcessPause(process, false); + } } Thread *Scheduler::PickThread(CPULocalStorage *local) { diff --git a/kernel/syscall.cpp b/kernel/syscall.cpp index 9205da7..554b1f5 100644 --- a/kernel/syscall.cpp +++ b/kernel/syscall.cpp @@ -1367,45 +1367,6 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_SCREEN_WORK_AREA_GET) { SYSCALL_RETURN(ES_SUCCESS, false); } -SYSCALL_IMPLEMENT(ES_SYSCALL_MESSAGE_DESKTOP) { - char *buffer; - if (argument1 > DESKTOP_MESSAGE_SIZE_LIMIT) SYSCALL_RETURN(ES_ERROR_INSUFFICIENT_RESOURCES, false); - SYSCALL_READ_HEAP(buffer, argument0, argument1); - - SYSCALL_HANDLE_2(argument2, (KernelObjectType) (KERNEL_OBJECT_EMBEDDED_WINDOW | KERNEL_OBJECT_NONE), _window); - SYSCALL_HANDLE_2(argument3, (KernelObjectType) (KERNEL_OBJECT_PIPE | KERNEL_OBJECT_NONE), _pipe); - - EmbeddedWindow *window = (EmbeddedWindow *) _window.object; - Pipe *pipe = (Pipe *) _pipe.object; - - if (pipe && (~_pipe.flags & PIPE_WRITER)) { - SYSCALL_RETURN(ES_FATAL_ERROR_INCORRECT_FILE_ACCESS, true); - } - - if (!scheduler.shutdown) { - if (pipe) { - OpenHandleToObject(pipe, KERNEL_OBJECT_PIPE, PIPE_WRITER); - } - - void *constantBuffer = ConstantBufferCreate(buffer, argument1); - - _EsMessageWithObject m = {}; - m.message.type = ES_MSG_DESKTOP; - m.message.desktop.buffer = constantBuffer ? DesktopOpenHandle(constantBuffer, ES_FLAGS_DEFAULT, KERNEL_OBJECT_CONSTANT_BUFFER) : ES_INVALID_HANDLE; - m.message.desktop.bytes = argument1; - m.message.desktop.windowID = window ? window->id : 0; - m.message.desktop.processID = currentProcess->id; - m.message.desktop.pipe = pipe ? DesktopOpenHandle(pipe, PIPE_WRITER, KERNEL_OBJECT_PIPE) : ES_INVALID_HANDLE; - - if (!m.message.desktop.buffer || !DesktopSendMessage(&m)) { - DesktopCloseHandle(m.message.desktop.buffer); - DesktopCloseHandle(m.message.desktop.pipe); - } - } - - SYSCALL_RETURN(ES_SUCCESS, false); -} - #ifdef ENABLE_POSIX_SUBSYSTEM SYSCALL_IMPLEMENT(ES_SYSCALL_POSIX) { SYSCALL_PERMISSION(ES_PERMISSION_POSIX_SUBSYSTEM); @@ -1457,8 +1418,14 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_PIPE_READ) { SYSCALL_HANDLE_2(argument0, KERNEL_OBJECT_PIPE, _pipe); Pipe *pipe = (Pipe *) _pipe.object; if ((~_pipe.flags & PIPE_READER)) SYSCALL_RETURN(ES_FATAL_ERROR_INCORRECT_FILE_ACCESS, true); - SYSCALL_BUFFER(argument1, argument2, 2, false); - SYSCALL_RETURN(pipe->Access((void *) argument1, argument2, false, true), false); + + if (argument1) { + SYSCALL_BUFFER(argument1, argument2, 2, false); + SYSCALL_RETURN(pipe->Access((void *) argument1, argument2, false, true), false); + } else { + // Discard data. + SYSCALL_RETURN(pipe->Access(nullptr, argument2, false, true), false); + } } SYSCALL_IMPLEMENT(ES_SYSCALL_PIPE_WRITE) { diff --git a/kernel/windows.cpp b/kernel/windows.cpp index 7da819a..a5d6138 100644 --- a/kernel/windows.cpp +++ b/kernel/windows.cpp @@ -936,7 +936,7 @@ void EmbeddedWindow::Close() { SetEmbedOwner(nullptr); m.object = nullptr; m.message.type = ES_MSG_EMBEDDED_WINDOW_DESTROYED; - m.message.desktop.windowID = id; + m.message.embeddedWindowDestroyedID = id; DesktopSendMessage(&m); if (container && container->embed == this) {