mirror of https://gitlab.com/nakst/essence
basic file copy and paste
This commit is contained in:
parent
d55a73dc5f
commit
35d4f727f9
|
@ -120,6 +120,9 @@ void CommandNewFolder(Instance *instance, EsElement *, EsCommand *) {
|
|||
}
|
||||
|
||||
void CommandCopy(Instance *instance, EsElement *, EsCommand *) {
|
||||
// TODO If copying a single file, copy the data of the file (as well as its path),
|
||||
// so that document can be pasted into other applications.
|
||||
|
||||
uint8_t _buffer[4096];
|
||||
EsBuffer buffer = { .out = _buffer, .bytes = sizeof(_buffer) };
|
||||
buffer.fileStore = EsClipboardOpen(ES_CLIPBOARD_PRIMARY);
|
||||
|
@ -127,9 +130,9 @@ void CommandCopy(Instance *instance, EsElement *, EsCommand *) {
|
|||
for (uintptr_t i = 0; i < instance->listContents.Length() && !buffer.error; i++) {
|
||||
if (instance->listContents[i].selected) {
|
||||
FolderEntry *entry = instance->listContents[i].entry;
|
||||
String name = entry->GetName();
|
||||
EsBufferWrite(&buffer, STRING(instance->path));
|
||||
EsBufferWrite(&buffer, STRING(name));
|
||||
String path = instance->folder->itemHandler->getPathForChild(instance->folder, entry);
|
||||
EsBufferWrite(&buffer, STRING(path));
|
||||
StringDestroy(&path);
|
||||
uint8_t separator = '\n';
|
||||
EsBufferWrite(&buffer, &separator, 1);
|
||||
}
|
||||
|
@ -149,6 +152,66 @@ void CommandCopy(Instance *instance, EsElement *, EsCommand *) {
|
|||
}
|
||||
}
|
||||
|
||||
void CommandPaste(Instance *instance, EsElement *, EsCommand *) {
|
||||
if (EsClipboardHasFormat(ES_CLIPBOARD_PRIMARY, ES_CLIPBOARD_FORMAT_PATH_LIST)) {
|
||||
// TODO Background task.
|
||||
// TODO Renaming.
|
||||
// TODO Recursing into folders.
|
||||
// TODO Reporting errors properly.
|
||||
// TODO Other namespace handlers.
|
||||
// TODO Selecting *all* pasted files.
|
||||
// TODO Update parent folders after copy complete.
|
||||
|
||||
void *copyBuffer = nullptr;
|
||||
|
||||
size_t bytes;
|
||||
char *pathList = EsClipboardReadText(ES_CLIPBOARD_PRIMARY, &bytes);
|
||||
|
||||
if (pathList) {
|
||||
const char *position = pathList;
|
||||
|
||||
while (bytes) {
|
||||
const char *newline = (const char *) EsCRTmemchr(position, '\n', bytes);
|
||||
if (!newline) break;
|
||||
|
||||
String source = StringFromLiteralWithSize(position, newline - position);
|
||||
String name = PathGetName(source);
|
||||
String destination = StringAllocateAndFormat("%s%s", STRFMT(instance->folder->path), STRFMT(name));
|
||||
EsError error = EsFileCopy(STRING(source), STRING(destination), ©Buffer);
|
||||
|
||||
if (error == ES_SUCCESS) {
|
||||
EsMutexAcquire(&instance->folder->modifyEntriesMutex);
|
||||
EsAssert(instance->folder->doneInitialEnumeration);
|
||||
EsDirectoryChild directoryChild;
|
||||
|
||||
if (EsPathQueryInformation(STRING(destination), &directoryChild)) {
|
||||
FolderAddEntryAndUpdateInstances(instance->folder, STRING(name), &directoryChild, instance);
|
||||
} else {
|
||||
// File must have been deleted by the time we got here!
|
||||
}
|
||||
|
||||
EsMutexRelease(&instance->folder->modifyEntriesMutex);
|
||||
} else {
|
||||
goto encounteredError;
|
||||
}
|
||||
|
||||
position += source.bytes + 1;
|
||||
bytes -= source.bytes + 1;
|
||||
StringDestroy(&destination);
|
||||
}
|
||||
} else {
|
||||
encounteredError:;
|
||||
EsPoint point = EsListViewGetAnnouncementPointForSelection(instance->list);
|
||||
EsAnnouncementShow(instance->window, ES_FLAGS_DEFAULT, point.x, point.y, INTERFACE_STRING(CommonAnnouncementPasteErrorOther));
|
||||
}
|
||||
|
||||
EsHeapFree(pathList);
|
||||
EsHeapFree(copyBuffer);
|
||||
} else {
|
||||
// TODO Paste the data into a new file.
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceRegisterCommands(Instance *instance) {
|
||||
uint32_t stableCommandID = 1;
|
||||
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
|
||||
Array<Folder *> loadedFolders;
|
||||
|
||||
// #define MAXIMUM_FOLDERS_WITH_NO_ATTACHED_INSTANCES (20)
|
||||
// TODO Temporary.
|
||||
#define MAXIMUM_FOLDERS_WITH_NO_ATTACHED_INSTANCES (0)
|
||||
#define MAXIMUM_FOLDERS_WITH_NO_ATTACHED_INSTANCES (20)
|
||||
Array<Folder *> foldersWithNoAttachedInstances;
|
||||
|
||||
/////////////////////////////////
|
||||
|
@ -57,7 +55,6 @@ EsError FSDirRenameItem(Folder *folder, String oldName, String newName) {
|
|||
};
|
||||
|
||||
EsError FSDirEnumerate(Folder *folder) {
|
||||
// Get the initial directory children.
|
||||
// TODO Recurse mode.
|
||||
|
||||
EsNodeType type;
|
||||
|
@ -66,6 +63,13 @@ EsError FSDirEnumerate(Folder *folder) {
|
|||
return ES_ERROR_FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
EsVolumeInformation volume;
|
||||
folder->readOnly = true;
|
||||
|
||||
if (EsMountPointGetVolumeInformation(STRING(folder->path), &volume)) {
|
||||
folder->readOnly = volume.flags & ES_VOLUME_READ_ONLY;
|
||||
}
|
||||
|
||||
EsDirectoryChild *buffer = nullptr;
|
||||
ptrdiff_t _entryCount = EsDirectoryEnumerateChildren(STRING(folder->path), &buffer);
|
||||
|
||||
|
@ -90,8 +94,9 @@ void FSDirGetTotalSize(Folder *folder) {
|
|||
}
|
||||
}
|
||||
|
||||
String FSDirGetPathForChildFolder(Folder *folder, String item) {
|
||||
return StringAllocateAndFormat("%s%s/", STRFMT(folder->path), STRFMT(item));
|
||||
String FSDirGetPathForChild(Folder *folder, FolderEntry *entry) {
|
||||
String item = entry->GetInternalName();
|
||||
return StringAllocateAndFormat("%s%s%z", STRFMT(folder->path), STRFMT(item), entry->isFolder ? "/" : "");
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
|
@ -153,7 +158,8 @@ EsError DrivesPageEnumerate(Folder *folder) {
|
|||
return ES_SUCCESS;
|
||||
}
|
||||
|
||||
String DrivesPageGetPathForChildFolder(Folder *, String item) {
|
||||
String DrivesPageGetPathForChild(Folder *, FolderEntry *entry) {
|
||||
String item = entry->GetInternalName();
|
||||
return StringAllocateAndFormat("%s/", STRFMT(item));
|
||||
}
|
||||
|
||||
|
@ -197,7 +203,7 @@ NamespaceHandler namespaceHandlers[] = {
|
|||
.getFileType = DrivesPageGetFileType,
|
||||
.getVisibleName = DrivesPageGetVisibleName,
|
||||
.getTotalSize = DrivesPageGetTotalSize,
|
||||
.getPathForChildFolder = DrivesPageGetPathForChildFolder,
|
||||
.getPathForChild = DrivesPageGetPathForChild,
|
||||
.getDefaultViewSettings = DrivesPageGetDefaultViewSettings,
|
||||
.enumerate = DrivesPageEnumerate,
|
||||
},
|
||||
|
@ -205,11 +211,13 @@ NamespaceHandler namespaceHandlers[] = {
|
|||
{
|
||||
.type = NAMESPACE_HANDLER_FILE_SYSTEM,
|
||||
.rootContainerHandlerType = NAMESPACE_HANDLER_DRIVES_PAGE,
|
||||
.canCopy = true,
|
||||
.canPaste = true,
|
||||
.handlesPath = FSDirHandlesPath,
|
||||
.getFileType = NamespaceDefaultGetFileType,
|
||||
.getVisibleName = NamespaceDefaultGetVisibleName,
|
||||
.getTotalSize = FSDirGetTotalSize,
|
||||
.getPathForChildFolder = FSDirGetPathForChildFolder,
|
||||
.getPathForChild = FSDirGetPathForChild,
|
||||
.createChildFolder = FSDirCreateChildFolder,
|
||||
.renameItem = FSDirRenameItem,
|
||||
.enumerate = FSDirEnumerate,
|
||||
|
|
|
@ -182,12 +182,14 @@ struct NamespaceHandler {
|
|||
uint8_t type;
|
||||
uint8_t rootContainerHandlerType;
|
||||
|
||||
bool canCopy, canPaste;
|
||||
|
||||
bool (*handlesPath)(String path);
|
||||
|
||||
uint32_t (*getFileType)(String path);
|
||||
void (*getVisibleName)(EsBuffer *buffer, String path);
|
||||
void (*getTotalSize)(Folder *folder); // Possibly called on the blocking task thread.
|
||||
String (*getPathForChildFolder)(Folder *folder, String item);
|
||||
String (*getPathForChild)(Folder *folder, FolderEntry *entry);
|
||||
void (*getDefaultViewSettings)(Folder *folder, FolderViewSettings *settings);
|
||||
|
||||
// Called on the blocking task thread:
|
||||
|
@ -207,6 +209,7 @@ struct Folder {
|
|||
bool recurse;
|
||||
bool refreshing;
|
||||
bool driveRemoved;
|
||||
bool readOnly;
|
||||
|
||||
bool doneInitialEnumeration;
|
||||
EsMutex modifyEntriesMutex;
|
||||
|
|
|
@ -199,3 +199,10 @@ String PathRemoveTrailingSlash(String path) {
|
|||
|
||||
return path;
|
||||
}
|
||||
|
||||
String PathGetName(String path) {
|
||||
intptr_t i = path.bytes - 2;
|
||||
while (i >= 0 && path.text[i] != '/') i--;
|
||||
path.text += i + 1, path.bytes -= i + 1;
|
||||
return path;
|
||||
}
|
||||
|
|
|
@ -94,12 +94,12 @@ bool InstanceLoadFolder(Instance *instance, String path /* takes ownership */, i
|
|||
|
||||
// Update commands.
|
||||
|
||||
EsCommandSetDisabled(&instance->commandGoBackwards, !instance->pathBackwardHistory.Length());
|
||||
EsCommandSetDisabled(&instance->commandGoForwards, !instance->pathForwardHistory.Length());
|
||||
EsCommandSetDisabled(&instance->commandGoParent, PathCountSections(folder->path) == 1);
|
||||
EsCommandSetDisabled(&instance->commandNewFolder, !folder->itemHandler->createChildFolder);
|
||||
EsCommandSetDisabled(&instance->commandRename, true);
|
||||
EsCommandSetDisabled(&instance->commandRefresh, false);
|
||||
EsCommandSetEnabled(&instance->commandGoBackwards, instance->pathBackwardHistory.Length());
|
||||
EsCommandSetEnabled(&instance->commandGoForwards, instance->pathForwardHistory.Length());
|
||||
EsCommandSetEnabled(&instance->commandGoParent, PathCountSections(folder->path) > 1);
|
||||
EsCommandSetEnabled(&instance->commandNewFolder, folder->itemHandler->createChildFolder && !folder->readOnly);
|
||||
EsCommandSetEnabled(&instance->commandRename, false);
|
||||
EsCommandSetEnabled(&instance->commandRefresh, true);
|
||||
|
||||
// Load the view settings for the folder.
|
||||
|
||||
|
@ -168,14 +168,15 @@ void InstanceRefreshViewType(Instance *instance) {
|
|||
}
|
||||
|
||||
void InstanceUpdateItemSelectionCountCommands(Instance *instance) {
|
||||
EsCommandSetEnabled(&instance->commandRename, instance->selectedItemCount == 1 && instance->folder->itemHandler->renameItem);
|
||||
EsCommandSetEnabled(&instance->commandRename, instance->selectedItemCount == 1 && instance->folder->itemHandler->renameItem && !instance->folder->readOnly);
|
||||
|
||||
#define COMMAND_SET(id, callback, enabled) \
|
||||
do { EsCommand *command = EsCommandByID(instance, id); \
|
||||
EsCommandSetEnabled(command, enabled); \
|
||||
EsCommandSetCallback(command, callback); } while(0)
|
||||
|
||||
COMMAND_SET(ES_COMMAND_COPY, CommandCopy, instance->selectedItemCount >= 1);
|
||||
COMMAND_SET(ES_COMMAND_COPY, CommandCopy, instance->selectedItemCount >= 1 && instance->folder->itemHandler->canCopy);
|
||||
COMMAND_SET(ES_COMMAND_PASTE, CommandPaste, instance->folder->itemHandler->canPaste && EsClipboardHasData(ES_CLIPBOARD_PRIMARY) && !instance->folder->readOnly);
|
||||
}
|
||||
|
||||
int InstanceCompareFolderEntries(FolderEntry *left, FolderEntry *right, uint16_t sortColumn) {
|
||||
|
@ -758,7 +759,7 @@ int ListCallback(EsElement *element, EsMessage *message) {
|
|||
FolderEntry *entry = listEntry->entry;
|
||||
|
||||
if (entry->isFolder) {
|
||||
String path = instance->folder->itemHandler->getPathForChildFolder(instance->folder, entry->GetInternalName());
|
||||
String path = instance->folder->itemHandler->getPathForChild(instance->folder, entry);
|
||||
InstanceLoadFolder(instance, path);
|
||||
} else {
|
||||
FileType *fileType = FolderEntryGetType(instance->folder, entry);
|
||||
|
|
|
@ -168,6 +168,10 @@ void InitialiseInstance(EsInstance *instance) {
|
|||
EsSyscall(ES_SYSCALL_WAIT, 0x00000FFFFFFFFFFF, 1, 0, 0);
|
||||
});
|
||||
|
||||
EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Crash 6"), [] (EsInstance *, EsElement *, EsCommand *) {
|
||||
EsMemoryCopy(nullptr, nullptr, 1);
|
||||
});
|
||||
|
||||
EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Announcement 1"), [] (EsInstance *, EsElement *element, EsCommand *) {
|
||||
EsRectangle bounds = EsElementGetWindowBounds(element);
|
||||
EsAnnouncementShow(element->window, ES_FLAGS_DEFAULT, (bounds.l + bounds.r) / 2, (bounds.t + bounds.b) / 2, "Hello, world!", -1);
|
||||
|
|
|
@ -1692,6 +1692,8 @@ struct EsListView : EsElement {
|
|||
}
|
||||
|
||||
EsCommandSetCallback(EsCommandByID(instance, ES_COMMAND_SELECT_ALL), nullptr);
|
||||
} else if (message->type == ES_MSG_MOUSE_RIGHT_DOWN) {
|
||||
// Make sure that right clicking will focus the list.
|
||||
} else if (message->type == ES_MSG_MOUSE_LEFT_DOWN) {
|
||||
Select(-1, 0, EsKeyboardIsShiftHeld(), EsKeyboardIsCtrlHeld(), false);
|
||||
} else if (message->type == ES_MSG_MOUSE_LEFT_DRAG) {
|
||||
|
|
|
@ -725,6 +725,8 @@ define ES_DRAW_BITMAP_OPAQUE (0xFFFF)
|
|||
define ES_DRAW_BITMAP_XOR (0xFFFE)
|
||||
define ES_DRAW_BITMAP_BLEND (0)
|
||||
|
||||
define ES_VOLUME_READ_ONLY (1 << 0)
|
||||
|
||||
include desktop/icons.header
|
||||
|
||||
enum EsFatalError {
|
||||
|
@ -1497,6 +1499,7 @@ struct EsVolumeInformation {
|
|||
char label[64];
|
||||
uint8_t labelBytes;
|
||||
uint8_t driveType;
|
||||
uint32_t flags;
|
||||
EsObjectID id;
|
||||
EsFileOffset spaceTotal;
|
||||
EsFileOffset spaceUsed;
|
||||
|
@ -1925,6 +1928,7 @@ function EsError EsFileWriteAllFromHandle(EsHandle handle, const void *data, siz
|
|||
function EsError EsFileWriteAllGather(STRING filePath, const void **data, size_t *fileSize, size_t gatherCount);
|
||||
function EsError EsFileWriteAllGatherFromHandle(EsHandle handle, const void **data, size_t *fileSize, size_t gatherCount);
|
||||
function void *EsFileMap(STRING filePath, size_t *fileSize, uint32_t flags);
|
||||
function EsError EsFileCopy(STRING source, STRING destination, void **copyBuffer); // If you are copying lots of files, you can reuse the temporary copy buffer by storing the output copyBuffer; call EsHeapFree on it after the last copy.
|
||||
|
||||
function EsError EsFileControl(EsHandle file, uint32_t flags);
|
||||
function EsFileInformation EsFileOpen(STRING path, uint32_t flags);
|
||||
|
@ -2223,6 +2227,7 @@ function int EsCRTvsnprintf(char *buffer, size_t bufferSize, const char *format,
|
|||
|
||||
function EsError EsClipboardAddText(EsClipboard clipboard, STRING text = BLANK_STRING);
|
||||
function bool EsClipboardHasFormat(EsClipboard clipboard, EsClipboardFormat format);
|
||||
function bool EsClipboardHasData(EsClipboard clipboard);
|
||||
function char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes); // Free with EsHeapFree.
|
||||
function EsFileStore *EsClipboardOpen(EsClipboard clipboard); // Open the clipboard for writing.
|
||||
function EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format, EsFileStore *fileStore);
|
||||
|
|
|
@ -223,6 +223,41 @@ void *EsFileReadAll(const char *filePath, ptrdiff_t filePathLength, size_t *file
|
|||
return buffer;
|
||||
}
|
||||
|
||||
EsError EsFileCopy(const char *source, ptrdiff_t sourceBytes, const char *destination, ptrdiff_t destinationBytes, void **_copyBuffer) {
|
||||
const size_t copyBufferBytes = 262144;
|
||||
void *copyBuffer = _copyBuffer && *_copyBuffer ? *_copyBuffer : EsHeapAllocate(copyBufferBytes, false);
|
||||
if (_copyBuffer) *_copyBuffer = copyBuffer;
|
||||
|
||||
if (!copyBuffer) {
|
||||
return ES_ERROR_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
EsError error = ES_SUCCESS;
|
||||
|
||||
EsFileInformation sourceFile = EsFileOpen(source, sourceBytes, ES_FILE_READ | ES_NODE_FILE | ES_NODE_FAIL_IF_NOT_FOUND);
|
||||
EsFileInformation destinationFile = EsFileOpen(destination, destinationBytes, ES_FILE_WRITE_EXCLUSIVE | ES_NODE_FILE | ES_NODE_FAIL_IF_FOUND);
|
||||
|
||||
if (sourceFile.error == ES_SUCCESS && destinationFile.error == ES_SUCCESS) {
|
||||
error = EsFileResize(destinationFile.handle, sourceFile.size);
|
||||
|
||||
if (error == ES_SUCCESS) {
|
||||
for (uintptr_t i = 0; i < sourceFile.size; i += copyBufferBytes) {
|
||||
size_t bytesRead = EsFileReadSync(sourceFile.handle, i, copyBufferBytes, copyBuffer);
|
||||
if (ES_CHECK_ERROR(bytesRead)) { error = bytesRead; break; }
|
||||
size_t bytesWritten = EsFileWriteSync(destinationFile.handle, i, bytesRead, copyBuffer);
|
||||
if (ES_CHECK_ERROR(bytesWritten)) { error = bytesWritten; break; }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error = sourceFile.error == ES_SUCCESS ? destinationFile.error : sourceFile.error;
|
||||
}
|
||||
|
||||
if (sourceFile.error == ES_SUCCESS) EsHandleClose(sourceFile.handle);
|
||||
if (destinationFile.error == ES_SUCCESS) EsHandleClose(destinationFile.handle);
|
||||
if (!_copyBuffer) EsHeapFree(copyBuffer);
|
||||
return error;
|
||||
}
|
||||
|
||||
EsHandle EsMemoryOpen(size_t size, const char *name, ptrdiff_t nameLength, unsigned flags) {
|
||||
if (nameLength == -1) nameLength = EsCStringLength(name);
|
||||
return EsSyscall(ES_SYSCALL_MEMORY_OPEN, size, (uintptr_t) name, nameLength, flags);
|
||||
|
@ -759,7 +794,22 @@ bool EsClipboardHasFormat(EsClipboard clipboard, EsClipboardFormat format) {
|
|||
ClipboardInformation information;
|
||||
ClipboardGetInformation(&file, &information);
|
||||
if (file) EsHandleClose(file);
|
||||
return information.error == ES_SUCCESS && information.format == format;
|
||||
if (information.error != ES_SUCCESS) return false;
|
||||
|
||||
if (format == ES_CLIPBOARD_FORMAT_TEXT) {
|
||||
return information.format == ES_CLIPBOARD_FORMAT_TEXT || information.format == ES_CLIPBOARD_FORMAT_PATH_LIST;
|
||||
} else {
|
||||
return information.format == format;
|
||||
}
|
||||
}
|
||||
|
||||
bool EsClipboardHasData(EsClipboard clipboard) {
|
||||
(void) clipboard;
|
||||
EsHandle file;
|
||||
ClipboardInformation information;
|
||||
ClipboardGetInformation(&file, &information);
|
||||
if (file) EsHandleClose(file);
|
||||
return information.error == ES_SUCCESS && information.format != ES_CLIPBOARD_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes) {
|
||||
|
@ -773,7 +823,7 @@ char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes) {
|
|||
ClipboardGetInformation(&file, &information);
|
||||
|
||||
if (file) {
|
||||
if (information.format == ES_CLIPBOARD_FORMAT_TEXT) {
|
||||
if (information.format == ES_CLIPBOARD_FORMAT_TEXT || information.format == ES_CLIPBOARD_FORMAT_PATH_LIST) {
|
||||
result = (char *) EsFileReadAllFromHandle(file, bytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -214,8 +214,6 @@ bool AHCIController::Access(uintptr_t portIndex, uint64_t offsetBytes, size_t co
|
|||
AHCIPort *port = ports + portIndex;
|
||||
|
||||
#if 0
|
||||
// TODO Temporary.
|
||||
|
||||
if (operation == K_ACCESS_WRITE) {
|
||||
KernelPanic("AHCIController::Access - Attempted write.\n");
|
||||
}
|
||||
|
|
|
@ -293,7 +293,6 @@ bool NVMeController::IssueAdminCommand(const void *command, uint32_t *result) {
|
|||
|
||||
bool NVMeController::Access(struct NVMeDrive *drive, uint64_t offsetBytes, size_t countBytes, int operation,
|
||||
KDMABuffer *buffer, uint64_t, KWorkGroup *dispatchGroup) {
|
||||
// TODO Temporary.
|
||||
// if (operation == K_ACCESS_WRITE) KernelPanic("NVMeController::Access - Attempted write.\n");
|
||||
|
||||
// Build the PRPs.
|
||||
|
|
|
@ -794,6 +794,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_VOLUME_GET_INFORMATION) {
|
|||
information.spaceUsed = fileSystem->spaceUsed;
|
||||
information.spaceTotal = fileSystem->spaceTotal;
|
||||
information.id = fileSystem->objectID;
|
||||
information.flags = fileSystem->write ? ES_FLAGS_DEFAULT : ES_VOLUME_READ_ONLY;
|
||||
|
||||
SYSCALL_WRITE(argument1, &information, sizeof(EsVolumeInformation));
|
||||
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||
|
|
|
@ -939,27 +939,22 @@ extern "C" void InterruptHandler(InterruptContext *context) {
|
|||
currentThread->process->cExecutableName,
|
||||
context->rip, local->processorID, context->rsp, context->errorCode, context->cr2);
|
||||
|
||||
#ifndef __OPTIMIZE__
|
||||
EsPrint("Attempting to make a stack trace...\n");
|
||||
|
||||
{
|
||||
// TODO Temporary, may crash kernel.
|
||||
// Attempt to make a stack trace.
|
||||
|
||||
uint64_t *rbp = (uint64_t *) context->rbp;
|
||||
int i = 0;
|
||||
uint64_t rbp = context->rbp;
|
||||
int traceDepth = 0;
|
||||
|
||||
while (rbp && i < 32) {
|
||||
EsPrint("\t%d: %x\n", ++i, rbp[1]);
|
||||
if (!rbp[1]) break;
|
||||
rbp = (uint64_t *) (rbp[0]);
|
||||
while (rbp && traceDepth < 32) {
|
||||
uint64_t value;
|
||||
if (!MMArchSafeCopy((uintptr_t) &value, rbp + 8, sizeof(uint64_t))) break;
|
||||
EsPrint("\t%d: %x\n", ++traceDepth, value);
|
||||
if (!value) break;
|
||||
if (!MMArchSafeCopy((uintptr_t) &rbp, rbp, sizeof(uint64_t))) break;
|
||||
}
|
||||
}
|
||||
|
||||
EsPrint("Stack trace complete.\n");
|
||||
#else
|
||||
EsPrint("Disable optimisations to get a stack trace.\n");
|
||||
#endif
|
||||
|
||||
EsCrashReason crashReason;
|
||||
EsMemoryZero(&crashReason, sizeof(EsCrashReason));
|
||||
|
|
|
@ -63,6 +63,7 @@ DEFINE_INTERFACE_STRING(CommonAnnouncementCopied, "Copied");
|
|||
DEFINE_INTERFACE_STRING(CommonAnnouncementTextCopied, "Text copied");
|
||||
DEFINE_INTERFACE_STRING(CommonAnnouncementCopyErrorResources, "There's not enough space to copy this");
|
||||
DEFINE_INTERFACE_STRING(CommonAnnouncementCopyErrorOther, "Could not copy");
|
||||
DEFINE_INTERFACE_STRING(CommonAnnouncementPasteErrorOther, "Could not paste");
|
||||
|
||||
DEFINE_INTERFACE_STRING(CommonEmpty, "empty");
|
||||
|
||||
|
|
|
@ -428,3 +428,5 @@ EsListViewFixedItemFindIndex=426
|
|||
EsListViewFixedItemSelect=427
|
||||
EsListViewFixedItemGetSelected=428
|
||||
EsClipboardHasFormat=429
|
||||
EsClipboardHasData=430
|
||||
EsFileCopy=431
|
||||
|
|
Loading…
Reference in New Issue