mirror of https://gitlab.com/nakst/essence
add APIs for applications to add and remove custom mount points
This commit is contained in:
parent
2c79bd4367
commit
e7238c8a52
|
@ -99,6 +99,7 @@ struct HistoryEntry {
|
|||
struct Drive {
|
||||
char *prefix;
|
||||
size_t prefixBytes;
|
||||
EsObjectID deviceID;
|
||||
EsVolumeInformation information;
|
||||
};
|
||||
|
||||
|
@ -424,14 +425,16 @@ void DriveRefreshFolders(bool removed, const char *prefix, size_t prefixBytes) {
|
|||
foldersToRefresh.Free();
|
||||
}
|
||||
|
||||
void DriveRemove(const char *prefix, size_t prefixBytes) {
|
||||
if (!prefixBytes || prefix[0] == '|') return;
|
||||
void DriveRemove(EsObjectID deviceID) {
|
||||
char *prefix = nullptr;
|
||||
size_t prefixBytes = 0;
|
||||
EsMutexAcquire(&drivesMutex);
|
||||
bool found = false;
|
||||
|
||||
for (uintptr_t index = 0; index < drives.Length(); index++) {
|
||||
if (0 == EsStringCompareRaw(prefix, prefixBytes, drives[index].prefix, drives[index].prefixBytes)) {
|
||||
EsHeapFree(drives[index].prefix);
|
||||
if (drives[index].deviceID == deviceID) {
|
||||
prefix = drives[index].prefix;
|
||||
prefixBytes = drives[index].prefixBytes;
|
||||
drives.Delete(index);
|
||||
found = true;
|
||||
|
||||
|
@ -447,17 +450,25 @@ void DriveRemove(const char *prefix, size_t prefixBytes) {
|
|||
EsAssert(found);
|
||||
EsMutexRelease(&drivesMutex);
|
||||
DriveRefreshFolders(true, prefix, prefixBytes);
|
||||
EsHeapFree(prefix);
|
||||
}
|
||||
|
||||
void DriveAdd(const char *prefix, size_t prefixBytes) {
|
||||
if (!prefixBytes || prefix[0] == '|') return;
|
||||
|
||||
void DriveAdd(EsHandle deviceHandle, EsObjectID deviceID) {
|
||||
// TODO Proper prefix allocation algorithm for drives.
|
||||
static int nextPrefix = 1;
|
||||
char prefix[16];
|
||||
bool isBootFileSystem = EsDeviceControl(deviceHandle, ES_DEVICE_CONTROL_FS_IS_BOOT, 0, nullptr) == 1;
|
||||
size_t prefixBytes = EsStringFormat(prefix, sizeof(prefix), "%fd:", ES_STRING_FORMAT_SIMPLE, isBootFileSystem ? 0 : nextPrefix);
|
||||
if (!isBootFileSystem) nextPrefix++;
|
||||
|
||||
EsMutexAcquire(&drivesMutex);
|
||||
|
||||
Drive drive = {};
|
||||
drive.prefix = (char *) EsHeapAllocate(prefixBytes, false);
|
||||
EsMemoryCopy(drive.prefix, prefix, prefixBytes);
|
||||
drive.prefixBytes = prefixBytes;
|
||||
drive.deviceID = deviceID;
|
||||
EsMountPointAdd(prefix, prefixBytes, deviceHandle);
|
||||
EsMountPointGetVolumeInformation(prefix, prefixBytes, &drive.information);
|
||||
drives.Add(drive);
|
||||
|
||||
|
@ -528,8 +539,8 @@ void _start() {
|
|||
|
||||
// Enumerate drives.
|
||||
|
||||
EsMountPointEnumerate([] (const char *prefix, size_t prefixBytes, EsGeneric) {
|
||||
DriveAdd(prefix, prefixBytes);
|
||||
EsDeviceEnumerate([] (EsMessageDevice device, EsGeneric) {
|
||||
if (device.type == ES_DEVICE_FILE_SYSTEM) DriveAdd(device.handle, device.id);
|
||||
}, 0);
|
||||
|
||||
// Process messages.
|
||||
|
@ -585,10 +596,10 @@ void _start() {
|
|||
loadedFolders.Free();
|
||||
thumbnailCache.Free();
|
||||
#endif
|
||||
} else if (message->type == ES_MSG_REGISTER_FILE_SYSTEM) {
|
||||
DriveAdd(message->registerFileSystem.mountPoint->prefix, message->registerFileSystem.mountPoint->prefixBytes);
|
||||
} else if (message->type == ES_MSG_UNREGISTER_FILE_SYSTEM) {
|
||||
DriveRemove(message->unregisterFileSystem.mountPoint->prefix, message->unregisterFileSystem.mountPoint->prefixBytes);
|
||||
} else if (message->type == ES_MSG_DEVICE_CONNECTED && message->device.type == ES_DEVICE_FILE_SYSTEM) {
|
||||
DriveAdd(message->device.handle, message->device.id);
|
||||
} else if (message->type == ES_MSG_DEVICE_DISCONNECTED && message->device.type == ES_DEVICE_FILE_SYSTEM) {
|
||||
DriveRemove(message->device.id);
|
||||
} else if (message->type == ES_MSG_FILE_MANAGER_FILE_MODIFIED) {
|
||||
char *_path = (char *) EsHeapAllocate(message->user.context2.u, false);
|
||||
EsConstantBufferRead(message->user.context1.u, _path);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// It is released under the terms of the MIT license -- see LICENSE.md.
|
||||
// Written by: nakst.
|
||||
|
||||
// TODO Update to use the new mount point APIs.
|
||||
|
||||
#define ES_PRIVATE_APIS
|
||||
#define INSTALLER
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ permission_all_devices=1
|
|||
permission_shutdown=1
|
||||
hidden=1
|
||||
is_installer=1
|
||||
disabled=1
|
||||
|
||||
[build]
|
||||
source=apps/installer.cpp
|
||||
|
|
208
desktop/api.cpp
208
desktop/api.cpp
|
@ -87,11 +87,6 @@ struct ThreadLocalStorage {
|
|||
uint64_t timerAdjustTicks;
|
||||
};
|
||||
|
||||
struct MountPoint : EsMountPoint {
|
||||
EsVolumeInformation information;
|
||||
bool removing;
|
||||
};
|
||||
|
||||
struct Timer {
|
||||
EsTimer id;
|
||||
double afterMs;
|
||||
|
@ -193,7 +188,8 @@ struct {
|
|||
|
||||
EsHandle desktopRequestPipe, desktopResponsePipe;
|
||||
|
||||
Array<MountPoint> mountPoints;
|
||||
EsMutex mountPointsMutex;
|
||||
Array<EsMountPoint> mountPoints2;
|
||||
Array<EsMessageDevice> connectedDevices;
|
||||
bool foundBootFileSystem;
|
||||
EsProcessStartupInformation *startupInformation;
|
||||
|
@ -245,7 +241,8 @@ EsSystemConfigurationGroup *SystemConfigurationGetGroup(const char *section, ptr
|
|||
uint8_t *ApplicationStartupInformationToBuffer(const _EsApplicationStartupInformation *information, size_t *dataBytes = nullptr);
|
||||
char *SystemConfigurationGroupReadString(EsSystemConfigurationGroup *group, const char *key, ptrdiff_t keyBytes, size_t *valueBytes = nullptr);
|
||||
int64_t SystemConfigurationGroupReadInteger(EsSystemConfigurationGroup *group, const char *key, ptrdiff_t keyBytes, int64_t defaultValue = 0);
|
||||
MountPoint *NodeFindMountPoint(const char *prefix, size_t prefixBytes);
|
||||
bool NodeFindMountPoint(const char *prefix, size_t prefixBytes, EsMountPoint *result, bool mutexTaken);
|
||||
EsError MountPointAdd(const char *prefix, size_t prefixBytes, EsHandle base, bool addedByApplication);
|
||||
EsWindow *WindowFromWindowID(EsObjectID id);
|
||||
void POSIXCleanup();
|
||||
extern "C" void _init();
|
||||
|
@ -276,49 +273,101 @@ uintptr_t APISyscallCheckForCrash(uintptr_t argument0, uintptr_t argument1, uint
|
|||
}
|
||||
#endif
|
||||
|
||||
MountPoint *NodeAddMountPoint(const char *prefix, size_t prefixBytes, EsHandle base, bool queryInformation) {
|
||||
MountPoint mountPoint = {};
|
||||
EsAssert(prefixBytes < sizeof(mountPoint.prefix));
|
||||
EsMemoryCopy(mountPoint.prefix, prefix, prefixBytes);
|
||||
mountPoint.base = base;
|
||||
mountPoint.prefixBytes = prefixBytes;
|
||||
EsError MountPointAdd(const char *prefix, size_t prefixBytes, EsHandle base, bool addedByApplication) {
|
||||
EsMutexAcquire(&api.mountPointsMutex);
|
||||
bool duplicate = NodeFindMountPoint(prefix, prefixBytes, nullptr, true);
|
||||
EsError error = ES_SUCCESS;
|
||||
|
||||
if (queryInformation) {
|
||||
EsSyscall(ES_SYSCALL_VOLUME_GET_INFORMATION, base, (uintptr_t) &mountPoint.information, 0, 0);
|
||||
}
|
||||
if (duplicate) {
|
||||
error = ES_ERROR_MOUNT_POINT_ALREADY_EXISTS;
|
||||
} else {
|
||||
EsMountPoint mountPoint = {};
|
||||
EsAssert(prefixBytes < sizeof(mountPoint.prefix));
|
||||
EsMemoryCopy(mountPoint.prefix, prefix, prefixBytes);
|
||||
mountPoint.base = EsSyscall(ES_SYSCALL_HANDLE_SHARE, base, ES_CURRENT_PROCESS, 0, 0);
|
||||
mountPoint.prefixBytes = prefixBytes;
|
||||
mountPoint.addedByApplication = addedByApplication;
|
||||
|
||||
return api.mountPoints.Add(mountPoint);
|
||||
}
|
||||
|
||||
MountPoint *NodeFindMountPoint(const char *prefix, size_t prefixBytes) {
|
||||
for (uintptr_t i = 0; i < api.mountPoints.Length(); i++) {
|
||||
MountPoint *mountPoint = &api.mountPoints[i];
|
||||
|
||||
if (prefixBytes >= mountPoint->prefixBytes
|
||||
&& 0 == EsMemoryCompare(prefix, mountPoint->prefix, mountPoint->prefixBytes)
|
||||
&& !mountPoint->removing) {
|
||||
return mountPoint;
|
||||
if (ES_CHECK_ERROR(mountPoint.base)) {
|
||||
error = ES_ERROR_INSUFFICIENT_RESOURCES;
|
||||
} else {
|
||||
if (!api.mountPoints2.Add(mountPoint)) {
|
||||
EsHandleClose(mountPoint.base);
|
||||
error = ES_ERROR_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
EsMutexRelease(&api.mountPointsMutex);
|
||||
return error;
|
||||
}
|
||||
|
||||
EsError EsMountPointAdd(const char *prefix, size_t prefixBytes, EsHandle base) {
|
||||
return MountPointAdd(prefix, prefixBytes, base, true);
|
||||
}
|
||||
|
||||
bool NodeFindMountPoint(const char *prefix, size_t prefixBytes, EsMountPoint *result, bool mutexTaken) {
|
||||
if (!mutexTaken) EsMutexAcquire(&api.mountPointsMutex);
|
||||
bool found = false;
|
||||
|
||||
for (uintptr_t i = 0; i < api.mountPoints2.Length(); i++) {
|
||||
EsMountPoint *mountPoint = &api.mountPoints2[i];
|
||||
|
||||
if (prefixBytes >= mountPoint->prefixBytes && 0 == EsMemoryCompare(prefix, mountPoint->prefix, mountPoint->prefixBytes)) {
|
||||
// Only permanent mount points can be used retrieved with NodeFindMountPoint when mutexTaken = false,
|
||||
// because mount points added by the application can be removed as soon as we release the mutex,
|
||||
// and the base handle would be closed.
|
||||
EsAssert(mutexTaken || !mountPoint->addedByApplication);
|
||||
if (result) EsMemoryCopy(result, mountPoint, sizeof(EsMountPoint));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mutexTaken) EsMutexRelease(&api.mountPointsMutex);
|
||||
return found;
|
||||
}
|
||||
|
||||
bool EsMountPointRemove(const char *prefix, size_t prefixBytes) {
|
||||
EsMutexAcquire(&api.mountPointsMutex);
|
||||
bool found = false;
|
||||
|
||||
for (uintptr_t i = 0; i < api.mountPoints2.Length(); i++) {
|
||||
EsMountPoint *mountPoint = &api.mountPoints2[i];
|
||||
|
||||
if (prefixBytes >= mountPoint->prefixBytes && 0 == EsMemoryCompare(prefix, mountPoint->prefix, mountPoint->prefixBytes)) {
|
||||
EsAssert(mountPoint->addedByApplication);
|
||||
EsHandleClose(mountPoint->base);
|
||||
api.mountPoints2.Delete(i);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EsMutexRelease(&api.mountPointsMutex);
|
||||
return found;
|
||||
}
|
||||
|
||||
bool EsMountPointGetVolumeInformation(const char *prefix, size_t prefixBytes, EsVolumeInformation *information) {
|
||||
MountPoint *mountPoint = NodeFindMountPoint(prefix, prefixBytes);
|
||||
if (!mountPoint) return false;
|
||||
EsSyscall(ES_SYSCALL_VOLUME_GET_INFORMATION, mountPoint->base, (uintptr_t) &mountPoint->information, 0, 0);
|
||||
EsMemoryCopy(information, &mountPoint->information, sizeof(EsVolumeInformation));
|
||||
return true;
|
||||
}
|
||||
EsMutexAcquire(&api.mountPointsMutex);
|
||||
EsMountPoint mountPoint;
|
||||
bool found = NodeFindMountPoint(prefix, prefixBytes, &mountPoint, true);
|
||||
|
||||
void EsMountPointEnumerate(EsMountPointEnumerationCallback callback, EsGeneric context) {
|
||||
EsMessageMutexCheck();
|
||||
|
||||
for (uintptr_t i = 0; i < api.mountPoints.Length(); i++) {
|
||||
MountPoint *mountPoint = &api.mountPoints[i];
|
||||
callback(mountPoint->prefix, mountPoint->prefixBytes, context);
|
||||
if (found) {
|
||||
_EsNodeInformation node;
|
||||
node.handle = mountPoint.base;
|
||||
EsError error = EsSyscall(ES_SYSCALL_NODE_OPEN, (uintptr_t) "/", 1, ES_NODE_DIRECTORY, (uintptr_t) &node);
|
||||
|
||||
if (error == ES_SUCCESS) {
|
||||
EsSyscall(ES_SYSCALL_VOLUME_GET_INFORMATION, node.handle, (uintptr_t) information, 0, 0);
|
||||
EsHandleClose(node.handle);
|
||||
} else {
|
||||
EsMemoryZero(information, sizeof(EsVolumeInformation));
|
||||
}
|
||||
}
|
||||
|
||||
EsMutexRelease(&api.mountPointsMutex);
|
||||
return found;
|
||||
}
|
||||
|
||||
void EsDeviceEnumerate(EsDeviceEnumerationCallback callback, EsGeneric context) {
|
||||
|
@ -330,17 +379,24 @@ void EsDeviceEnumerate(EsDeviceEnumerationCallback callback, EsGeneric context)
|
|||
}
|
||||
|
||||
EsError NodeOpen(const char *path, size_t pathBytes, uint32_t flags, _EsNodeInformation *node) {
|
||||
EsMountPoint *mountPoint = NodeFindMountPoint(path, pathBytes);
|
||||
// TODO I really don't like having to acquire a mutex to open a node.
|
||||
// This could be replaced with a writer lock!
|
||||
// (...but we don't have writer locks in userland yet.)
|
||||
EsMutexAcquire(&api.mountPointsMutex);
|
||||
|
||||
if (!mountPoint) {
|
||||
return ES_ERROR_PATH_NOT_WITHIN_MOUNTED_VOLUME;
|
||||
EsMountPoint mountPoint;
|
||||
bool found = NodeFindMountPoint(path, pathBytes, &mountPoint, true);
|
||||
EsError error = ES_ERROR_PATH_NOT_WITHIN_MOUNTED_VOLUME;
|
||||
|
||||
if (found) {
|
||||
node->handle = mountPoint.base;
|
||||
path += mountPoint.prefixBytes;
|
||||
pathBytes -= mountPoint.prefixBytes;
|
||||
error = EsSyscall(ES_SYSCALL_NODE_OPEN, (uintptr_t) path, pathBytes, flags, (uintptr_t) node);
|
||||
}
|
||||
|
||||
node->handle = mountPoint->base;
|
||||
path += mountPoint->prefixBytes;
|
||||
pathBytes -= mountPoint->prefixBytes;
|
||||
|
||||
return EsSyscall(ES_SYSCALL_NODE_OPEN, (uintptr_t) path, pathBytes, flags, (uintptr_t) node);
|
||||
EsMutexRelease(&api.mountPointsMutex);
|
||||
return error;
|
||||
}
|
||||
|
||||
EsSystemConfigurationItem *SystemConfigurationGetItem(EsSystemConfigurationGroup *group, const char *key, ptrdiff_t keyBytes, bool createIfNeeded) {
|
||||
|
@ -1069,7 +1125,7 @@ EsMessage *EsMessageReceive() {
|
|||
FreeUnusedStyles(true /* include permanent styles */);
|
||||
theming.loadedStyles.Free();
|
||||
SystemConfigurationUnload();
|
||||
api.mountPoints.Free();
|
||||
api.mountPoints2.Free();
|
||||
api.postBox.Free();
|
||||
api.timers.Free();
|
||||
gui.animatingElements.Free();
|
||||
|
@ -1089,13 +1145,6 @@ EsMessage *EsMessageReceive() {
|
|||
#endif
|
||||
EsProcessTerminateCurrent();
|
||||
}
|
||||
} else if (message.message.type == ES_MSG_UNREGISTER_FILE_SYSTEM) {
|
||||
for (uintptr_t i = 0; i < api.mountPoints.Length(); i++) {
|
||||
if (api.mountPoints[i].information.id == message.message.unregisterFileSystem.id) {
|
||||
EsHandleClose(api.mountPoints[i].base);
|
||||
api.mountPoints.Delete(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EsMessageMutexRelease();
|
||||
|
@ -1291,49 +1340,6 @@ EsMessage *EsMessageReceive() {
|
|||
|
||||
return &message.message;
|
||||
}
|
||||
} else if (type == ES_MSG_REGISTER_FILE_SYSTEM) {
|
||||
EsMessageRegisterFileSystem *m = &message.message.registerFileSystem;
|
||||
|
||||
int64_t index = 1; // TODO This is incorrect!
|
||||
|
||||
while (true) {
|
||||
bool seen = false;
|
||||
|
||||
for (uintptr_t i = 0; i < api.mountPoints.Length(); i++) {
|
||||
if (index == EsIntegerParse(api.mountPoints[i].prefix, api.mountPoints[i].prefixBytes)) {
|
||||
seen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (seen) {
|
||||
index++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool isBootFileSystem = m->isBootFileSystem;
|
||||
char prefix[16];
|
||||
size_t prefixBytes = EsStringFormat(prefix, sizeof(prefix), "%fd:", ES_STRING_FORMAT_SIMPLE, isBootFileSystem ? 0 : index);
|
||||
|
||||
m->mountPoint = NodeAddMountPoint(prefix, prefixBytes, m->rootDirectory, true);
|
||||
|
||||
if (isBootFileSystem) {
|
||||
api.foundBootFileSystem = true;
|
||||
}
|
||||
|
||||
if (m->mountPoint) {
|
||||
return &message.message;
|
||||
}
|
||||
} else if (type == ES_MSG_UNREGISTER_FILE_SYSTEM) {
|
||||
for (uintptr_t i = 0; i < api.mountPoints.Length(); i++) {
|
||||
if (api.mountPoints[i].information.id == message.message.unregisterFileSystem.id) {
|
||||
message.message.unregisterFileSystem.mountPoint = &api.mountPoints[i];
|
||||
api.mountPoints[i].removing = true;
|
||||
return &message.message;
|
||||
}
|
||||
}
|
||||
} else if (type == ES_MSG_DEVICE_CONNECTED) {
|
||||
api.connectedDevices.Add(message.message.device);
|
||||
return &message.message;
|
||||
|
@ -1561,7 +1567,7 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
|
|||
|
||||
path = EsSystemConfigurationReadString(EsLiteral("paths"), EsLiteral("fonts"));
|
||||
NodeOpen(path, EsCStringLength(path), ES_NODE_DIRECTORY, &node);
|
||||
NodeAddMountPoint(EsLiteral("|Fonts:"), node.handle, false);
|
||||
MountPointAdd(EsLiteral("|Fonts:"), node.handle, false);
|
||||
EsHeapFree(path);
|
||||
|
||||
SettingsLoadDefaults();
|
||||
|
@ -1586,7 +1592,7 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
|
|||
|
||||
for (uintptr_t i = 0; i < header->initialMountPointCount; i++) {
|
||||
const EsMountPoint *mountPoint = (const EsMountPoint *) EsBufferRead(&buffer, sizeof(EsMountPoint));
|
||||
NodeAddMountPoint(mountPoint->prefix, mountPoint->prefixBytes, mountPoint->base, true);
|
||||
MountPointAdd(mountPoint->prefix, mountPoint->prefixBytes, mountPoint->base, false);
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < header->initialDeviceCount; i++) {
|
||||
|
|
|
@ -655,6 +655,10 @@ int CursorLocatorMessage(EsElement *element, EsMessage *message) {
|
|||
}
|
||||
|
||||
int ProcessGlobalKeyboardShortcuts(EsElement *, EsMessage *message) {
|
||||
if (!desktop.setupDesktopUIComplete) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (message->type == ES_MSG_KEY_DOWN) {
|
||||
bool ctrlOnly = message->keyboard.modifiers == ES_MODIFIER_CTRL;
|
||||
uint32_t scancode = ScancodeMapToLabel(message->keyboard.scancode);
|
||||
|
@ -1866,7 +1870,8 @@ bool ApplicationInstanceStart(_EsApplicationStartupInformation *startupInformati
|
|||
arguments.permissions |= ES_PERMISSION_PROCESS_OPEN;
|
||||
arguments.permissions |= ES_PERMISSION_POSIX_SUBSYSTEM;
|
||||
|
||||
MountPoint root = *NodeFindMountPoint(EsLiteral("0:"));
|
||||
EsMountPoint root;
|
||||
EsAssert(NodeFindMountPoint(EsLiteral("0:"), &root, false));
|
||||
root.prefixBytes = EsStringFormat(root.prefix, sizeof(root.prefix), "|POSIX:");
|
||||
initialMountPoints.Add(root);
|
||||
|
||||
|
@ -1879,26 +1884,20 @@ bool ApplicationInstanceStart(_EsApplicationStartupInformation *startupInformati
|
|||
}
|
||||
|
||||
if (application->permissions & APPLICATION_PERMISSION_ALL_FILES) {
|
||||
// We will inform the process of new and removed mount points on the message thread,
|
||||
// in response to ES_MSG_REGISTER_FILE_SYSTEM and ES_MSG_UNREGISTER_FILE_SYSTEM.
|
||||
EsMessageMutexCheck();
|
||||
|
||||
for (uintptr_t i = 0; i < api.mountPoints.Length(); i++) {
|
||||
initialMountPoints.Add(api.mountPoints[i]);
|
||||
handleDuplicateList.Add(api.mountPoints[i].base);
|
||||
handleModeDuplicateList.Add(0);
|
||||
}
|
||||
|
||||
arguments.permissions |= ES_PERMISSION_GET_VOLUME_INFORMATION;
|
||||
} else {
|
||||
MountPoint fonts = *NodeFindMountPoint(EsLiteral("|Fonts:"));
|
||||
}
|
||||
|
||||
{
|
||||
EsMountPoint fonts;
|
||||
EsAssert(NodeFindMountPoint(EsLiteral("|Fonts:"), &fonts, false));
|
||||
initialMountPoints.Add(fonts);
|
||||
handleDuplicateList.Add(fonts.base);
|
||||
handleModeDuplicateList.Add(2 /* prevent write */);
|
||||
}
|
||||
|
||||
if (application->permissions & APPLICATION_PERMISSION_ALL_DEVICES) {
|
||||
for (uintptr_t i = 0; i < api.connectedDevices.Length(); i++) {
|
||||
for (uintptr_t i = 0; i < api.connectedDevices.Length(); i++) {
|
||||
if ((application->permissions & APPLICATION_PERMISSION_ALL_DEVICES)
|
||||
|| ((application->permissions & APPLICATION_PERMISSION_ALL_FILES) && api.connectedDevices[i].type == ES_DEVICE_FILE_SYSTEM)) {
|
||||
initialDevices.Add(api.connectedDevices[i]);
|
||||
handleDuplicateList.Add(api.connectedDevices[i].handle);
|
||||
handleModeDuplicateList.Add(0);
|
||||
|
@ -3153,24 +3152,18 @@ void DesktopSendMessage(EsMessage *message) {
|
|||
EmbeddedWindowDestroyed(message->embeddedWindowDestroyedID);
|
||||
} else if (message->type == ES_MSG_APPLICATION_CRASH) {
|
||||
ApplicationInstanceCrashed(message);
|
||||
} else if (message->type == ES_MSG_REGISTER_FILE_SYSTEM) {
|
||||
EsHandle rootDirectory = message->registerFileSystem.rootDirectory;
|
||||
|
||||
for (uintptr_t i = 0; i < desktop.allApplicationProcesses.Length(); i++) {
|
||||
ApplicationProcess *process = desktop.allApplicationProcesses[i];
|
||||
|
||||
if (process->application && (process->application->permissions & APPLICATION_PERMISSION_ALL_FILES)) {
|
||||
message->registerFileSystem.rootDirectory = EsSyscall(ES_SYSCALL_HANDLE_SHARE, rootDirectory, process->handle, 0, 0);
|
||||
EsMessagePostRemote(process->handle, message);
|
||||
}
|
||||
}
|
||||
} else if (message->type == ES_MSG_DEVICE_CONNECTED) {
|
||||
EsHandle handle = message->device.handle;
|
||||
|
||||
EsPrint("Desktop received ES_MSG_DEVICE_CONNECTED with ID %d and type %z.\n",
|
||||
message->device.id, EnumLookupNameFromValue(enumStrings_EsDeviceType, message->device.type));
|
||||
|
||||
for (uintptr_t i = 0; i < desktop.allApplicationProcesses.Length(); i++) {
|
||||
ApplicationProcess *process = desktop.allApplicationProcesses[i];
|
||||
if (!process->application) continue;
|
||||
|
||||
if (process->application && (process->application->permissions & APPLICATION_PERMISSION_ALL_DEVICES)) {
|
||||
if ((process->application->permissions & APPLICATION_PERMISSION_ALL_DEVICES)
|
||||
|| ((process->application->permissions & APPLICATION_PERMISSION_ALL_FILES) && message->device.type == ES_DEVICE_FILE_SYSTEM)) {
|
||||
message->device.handle = EsSyscall(ES_SYSCALL_HANDLE_SHARE, handle, process->handle, 0, 0);
|
||||
EsMessagePostRemote(process->handle, message);
|
||||
}
|
||||
|
@ -3193,26 +3186,22 @@ void DesktopSendMessage(EsMessage *message) {
|
|||
} else {
|
||||
// The screen resolution will be correctly queried in DesktopSetup.
|
||||
}
|
||||
} else if (message->device.type == ES_DEVICE_FILE_SYSTEM) {
|
||||
if (EsDeviceControl(message->device.handle, ES_DEVICE_CONTROL_FS_IS_BOOT, 0, 0) == 1) {
|
||||
// Mount the boot file system at "0:".
|
||||
MountPointAdd("0:", 2, message->device.handle, false);
|
||||
api.foundBootFileSystem = true;
|
||||
}
|
||||
}
|
||||
} else if (message->type == ES_MSG_UNREGISTER_FILE_SYSTEM || message->type == ES_MSG_DEVICE_DISCONNECTED) {
|
||||
} else if (message->type == ES_MSG_DEVICE_DISCONNECTED) {
|
||||
for (uintptr_t i = 0; i < desktop.allApplicationProcesses.Length(); i++) {
|
||||
ApplicationProcess *process = desktop.allApplicationProcesses[i];
|
||||
if (!process->application) continue;
|
||||
|
||||
if (!process->application) {
|
||||
continue;
|
||||
if ((process->application->permissions & APPLICATION_PERMISSION_ALL_DEVICES)
|
||||
|| ((process->application->permissions & APPLICATION_PERMISSION_ALL_FILES) && message->device.type == ES_DEVICE_FILE_SYSTEM)) {
|
||||
EsMessagePostRemote(process->handle, message);
|
||||
}
|
||||
|
||||
if (message->type == ES_MSG_UNREGISTER_FILE_SYSTEM) {
|
||||
if (~process->application->permissions & APPLICATION_PERMISSION_ALL_FILES) {
|
||||
continue;
|
||||
}
|
||||
} else if (message->type == ES_MSG_DEVICE_DISCONNECTED) {
|
||||
if (~process->application->permissions & APPLICATION_PERMISSION_ALL_DEVICES) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
EsMessagePostRemote(process->handle, message);
|
||||
}
|
||||
} else if (message->type == ES_MSG_KEY_DOWN) {
|
||||
ProcessGlobalKeyboardShortcuts(nullptr, message);
|
||||
|
|
|
@ -337,6 +337,7 @@ define ES_ERROR_CANCELLED (-73)
|
|||
define ES_ERROR_BLOCK_ACCESS_INVALID (-74)
|
||||
define ES_ERROR_DEVICE_REMOVED (-75)
|
||||
define ES_ERROR_TOO_MANY_FILES_WITH_NAME (-76)
|
||||
define ES_ERROR_MOUNT_POINT_ALREADY_EXISTS (-77)
|
||||
|
||||
define ES_INVALID_HANDLE ((EsHandle) (0))
|
||||
define ES_CURRENT_THREAD ((EsHandle) (0x10))
|
||||
|
@ -1047,8 +1048,6 @@ enum EsMessageType {
|
|||
ES_MSG_INSTANCE_CREATE = 0x6002
|
||||
ES_MSG_DEVICE_CONNECTED = 0x6003
|
||||
ES_MSG_DEVICE_DISCONNECTED = 0x6004
|
||||
ES_MSG_REGISTER_FILE_SYSTEM = 0x6005
|
||||
ES_MSG_UNREGISTER_FILE_SYSTEM = 0x6006
|
||||
|
||||
// Instance messages:
|
||||
ES_MSG_INSTANCE_OPEN = 0x6800
|
||||
|
@ -1176,6 +1175,8 @@ enum EsDeviceControlType {
|
|||
ES_DEVICE_CONTROL_BLOCK_DETECT_FS = 0x1004 // Detect file systems. All existing file systems must have been unmounted.
|
||||
|
||||
ES_DEVICE_CONTROL_CLOCK_READ = 0x2001
|
||||
|
||||
ES_DEVICE_CONTROL_FS_IS_BOOT = 0x3001
|
||||
}
|
||||
|
||||
function_pointer int EsElementCallback(struct EsElement *element, struct EsMessage *message);
|
||||
|
@ -1297,12 +1298,6 @@ struct EsSnapshotProcesses {
|
|||
EsSnapshotProcessesItem processes[];
|
||||
}
|
||||
|
||||
struct EsMountPoint {
|
||||
char prefix[16];
|
||||
size_t prefixBytes;
|
||||
EsHandle base;
|
||||
};
|
||||
|
||||
struct EsProcessCreateData {
|
||||
EsHandle systemData;
|
||||
EsHandle subsystemData;
|
||||
|
@ -1799,20 +1794,9 @@ struct EsMessageTabOperation {
|
|||
EsError error;
|
||||
};
|
||||
|
||||
struct EsMessageRegisterFileSystem {
|
||||
EsHandle rootDirectory;
|
||||
bool isBootFileSystem;
|
||||
EsMountPoint *mountPoint;
|
||||
};
|
||||
|
||||
struct EsMessageUnregisterFileSystem {
|
||||
EsObjectID id;
|
||||
EsMountPoint *mountPoint;
|
||||
};
|
||||
|
||||
struct EsMessageDevice {
|
||||
EsObjectID id;
|
||||
EsHandle handle;
|
||||
EsHandle handle; // Not set in ES_MSG_DEVICE_DISCONNECTED. This handle is owned by the system, and is closed on receiving the disconnected message within EsMessageReceive.
|
||||
EsDeviceType type;
|
||||
};
|
||||
|
||||
|
@ -1888,8 +1872,6 @@ struct EsMessage {
|
|||
EsMessageEyedrop eyedrop;
|
||||
EsMessageCreateInstance createInstance;
|
||||
EsMessageTabOperation tabOperation;
|
||||
EsMessageRegisterFileSystem registerFileSystem;
|
||||
EsMessageUnregisterFileSystem unregisterFileSystem;
|
||||
EsMessageDevice device;
|
||||
EsObjectID embeddedWindowDestroyedID;
|
||||
};
|
||||
|
@ -1972,6 +1954,13 @@ struct EsListViewEnumString {
|
|||
STRING string;
|
||||
};
|
||||
|
||||
private struct EsMountPoint {
|
||||
char prefix[16];
|
||||
size_t prefixBytes;
|
||||
uintptr_t base;
|
||||
bool addedByApplication;
|
||||
};
|
||||
|
||||
// Function pointer types.
|
||||
|
||||
function_pointer void EsThreadEntryCallback(EsGeneric argument);
|
||||
|
@ -1980,7 +1969,6 @@ function_pointer int EsCRTComparisonCallback(const void *left, const void *right
|
|||
function_pointer void EsTimerCallback(EsGeneric argument);
|
||||
function_pointer void EsMenuCallback(EsMenu *menu, EsGeneric context);
|
||||
function_pointer void EsUndoCallback(const void *item, EsUndoManager *manager, EsMessage *message);
|
||||
function_pointer void EsMountPointEnumerationCallback(const char *prefix, size_t prefixBytes, EsGeneric context);
|
||||
function_pointer void EsDeviceEnumerationCallback(EsMessageDevice device, EsGeneric context);
|
||||
function_pointer void EsListViewEnumerateVisibleItemsCallback(EsListView *view, EsElement *item, uint32_t group, EsListViewIndex index);
|
||||
function_pointer void EsFontEnumerationCallback(const EsFontInformation *information, EsGeneric context);
|
||||
|
@ -2058,7 +2046,8 @@ function void *EsFileStoreMap(EsFileStore *file, size_t *fileSize, uint32_t flag
|
|||
|
||||
// These calls require permission_all_files.
|
||||
function bool EsMountPointGetVolumeInformation(const char *prefix, size_t prefixBytes, EsVolumeInformation *information); // Returns false if the mount point does not exist.
|
||||
function void EsMountPointEnumerate(EsMountPointEnumerationCallback callback, EsGeneric context);
|
||||
function EsError EsMountPointAdd(const char *prefix, size_t prefixBytes, EsHandle base); // The system maintains a duplicate of the base handle.
|
||||
function bool EsMountPointRemove(const char *prefix, size_t prefixBytes); // Returns false if the mount point does not exist. You can only remove mount points you added with EsMountPointAdd.
|
||||
function void EsOpenDocumentQueryInformation(STRING filePath, EsOpenDocumentInformation *information);
|
||||
function void _EsPathAnnouncePathMoved(STRING oldPath, STRING newPath); // Set oldPathBytes = 0 to make the file manager refresh the path.
|
||||
function void _EsOpenDocumentEnumerate(EsBuffer *outputBuffer);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
extern "C" void *ProcessorTLSRead(uintptr_t offset);
|
||||
extern "C" void ProcessorTLSWrite(uintptr_t offset, void *value);
|
||||
extern ptrdiff_t tlsStorageOffset;
|
||||
EsMountPoint *NodeFindMountPoint(const char *prefix, size_t prefixBytes);
|
||||
bool NodeFindMountPoint(const char *prefix, size_t prefixBytes, EsMountPoint *result, bool mutexTaken);
|
||||
EsProcessStartupInformation *ProcessGetStartupInformation();
|
||||
|
||||
#define _POSIX_SOURCE
|
||||
|
@ -50,6 +50,7 @@ struct ChildProcess {
|
|||
char *workingDirectory;
|
||||
Array<ChildProcess> childProcesses;
|
||||
Array<void *> _argv;
|
||||
EsHandle posixMountPointBase;
|
||||
|
||||
#ifdef ES_ARCH_X86_64
|
||||
Elf64_Phdr *tlsHeader;
|
||||
|
@ -165,6 +166,14 @@ long EsPOSIXSystemCall(long n, long a1, long a2, long a3, long a4, long a5, long
|
|||
// EsPrint(":: %z %x %x %x\n", syscallNames[n], a1, a2, a3);
|
||||
}
|
||||
|
||||
if (posixMountPointBase) {
|
||||
// It doesn't matter if multiple threads try to do this at the same time,
|
||||
// they'll all get the same result.
|
||||
EsMountPoint mountPoint;
|
||||
EsAssert(NodeFindMountPoint(EsLiteral("|POSIX:"), &mountPoint, false));
|
||||
posixMountPointBase = mountPoint.base;
|
||||
}
|
||||
|
||||
long returnValue = 0;
|
||||
_EsPOSIXSyscall syscall = { n, a1, a2, a3, a4, a5, a6 };
|
||||
|
||||
|
@ -212,7 +221,7 @@ long EsPOSIXSystemCall(long n, long a1, long a2, long a3, long a4, long a5, long
|
|||
size_t pathBytes;
|
||||
char *path = EsPOSIXConvertPath((const char *) a1, &pathBytes, false);
|
||||
syscall.arguments[0] = (long) path;
|
||||
syscall.arguments[4] = (long) NodeFindMountPoint(EsLiteral("|POSIX:"))->base;
|
||||
syscall.arguments[4] = (long) posixMountPointBase;
|
||||
syscall.arguments[6] = (long) pathBytes;
|
||||
returnValue = EsSyscall(ES_SYSCALL_POSIX, (uintptr_t) &syscall, 0, 0, 0);
|
||||
// EsPrint("SYS_open '%s' with handle %d\n", pathBytes, path, returnValue);
|
||||
|
@ -306,7 +315,7 @@ long EsPOSIXSystemCall(long n, long a1, long a2, long a3, long a4, long a5, long
|
|||
|
||||
case SYS_unlink: {
|
||||
_EsNodeInformation node;
|
||||
node.handle = NodeFindMountPoint(EsLiteral("|POSIX:"))->base;
|
||||
node.handle = posixMountPointBase;
|
||||
size_t pathBytes;
|
||||
char *path = EsPOSIXConvertPath((const char *) a1, &pathBytes, false);
|
||||
EsError error = EsSyscall(ES_SYSCALL_NODE_OPEN, (uintptr_t) path, pathBytes, ES_NODE_FAIL_IF_NOT_FOUND | ES_FILE_WRITE, (uintptr_t) &node);
|
||||
|
@ -326,7 +335,7 @@ long EsPOSIXSystemCall(long n, long a1, long a2, long a3, long a4, long a5, long
|
|||
|
||||
case SYS_truncate: {
|
||||
_EsNodeInformation node;
|
||||
node.handle = NodeFindMountPoint(EsLiteral("|POSIX:"))->base;
|
||||
node.handle = posixMountPointBase;
|
||||
size_t pathBytes;
|
||||
char *path = EsPOSIXConvertPath((const char *) a1, &pathBytes, false);
|
||||
EsError error = EsSyscall(ES_SYSCALL_NODE_OPEN, (uintptr_t) path, pathBytes, ES_NODE_FAIL_IF_NOT_FOUND | ES_FILE_WRITE, (uintptr_t) &node);
|
||||
|
@ -404,7 +413,7 @@ long EsPOSIXSystemCall(long n, long a1, long a2, long a3, long a4, long a5, long
|
|||
syscall.arguments[1] = (long) pathBytes;
|
||||
syscall.arguments[2] = (long) newEnvironment;
|
||||
syscall.arguments[3] = (long) environmentSize;
|
||||
syscall.arguments[4] = (long) NodeFindMountPoint(EsLiteral("|POSIX:"))->base;
|
||||
syscall.arguments[4] = (long) posixMountPointBase;
|
||||
|
||||
returnValue = EsSyscall(ES_SYSCALL_POSIX, (uintptr_t) &syscall, 0, 0, 0);
|
||||
} break;
|
||||
|
|
|
@ -80,14 +80,17 @@ void KDeviceDestroy(KDevice *device) {
|
|||
KMutexRelease(&deviceTreeMutex);
|
||||
}
|
||||
|
||||
void KDeviceOpenHandle(KDevice *device) {
|
||||
void KDeviceOpenHandle(KDevice *device, uint32_t handleFlags) {
|
||||
if (device->trackHandle && (handleFlags & K_DEVICE_HANDLE_TRACKED)) device->trackHandle(device, true);
|
||||
KMutexAcquire(&deviceTreeMutex);
|
||||
if (!device->handles) KernelPanic("KDeviceOpenHandle - Device %s has no handles.\n", device);
|
||||
device->handles++;
|
||||
KMutexRelease(&deviceTreeMutex);
|
||||
}
|
||||
|
||||
void KDeviceCloseHandle(KDevice *device) {
|
||||
void KDeviceCloseHandle(KDevice *device, uint32_t handleFlags) {
|
||||
if (device->trackHandle && (handleFlags & K_DEVICE_HANDLE_TRACKED)) device->trackHandle(device, false);
|
||||
|
||||
KMutexAcquire(&deviceTreeMutex);
|
||||
|
||||
if (!device->handles) KernelPanic("KDeviceCloseHandle - Device %s has no handles.\n", device);
|
||||
|
@ -131,7 +134,7 @@ void DeviceRemovedRecurse(KDevice *device) {
|
|||
}
|
||||
}
|
||||
|
||||
void KDeviceSendConnectedMessage(KDevice *device, EsDeviceType type) {
|
||||
void KDeviceSendConnectedMessage(KDevice *device, EsDeviceType type, uint32_t handleFlags) {
|
||||
KMutexAcquire(&deviceTreeMutex);
|
||||
|
||||
if (device->flags & K_DEVICE_VISIBLE_TO_USER) {
|
||||
|
@ -143,14 +146,14 @@ void KDeviceSendConnectedMessage(KDevice *device, EsDeviceType type) {
|
|||
|
||||
KMutexRelease(&deviceTreeMutex);
|
||||
|
||||
KDeviceOpenHandle(device);
|
||||
KDeviceOpenHandle(device, handleFlags);
|
||||
|
||||
_EsMessageWithObject m;
|
||||
EsMemoryZero(&m, sizeof(m));
|
||||
m.message.type = ES_MSG_DEVICE_CONNECTED;
|
||||
m.message.device.id = device->objectID;
|
||||
m.message.device.type = type;
|
||||
m.message.device.handle = DesktopOpenHandle(device, 0, KERNEL_OBJECT_DEVICE);
|
||||
m.message.device.handle = DesktopOpenHandle(device, handleFlags, KERNEL_OBJECT_DEVICE);
|
||||
|
||||
if (m.message.device.handle) {
|
||||
if (!DesktopSendMessage(&m)) {
|
||||
|
|
|
@ -1881,38 +1881,22 @@ void FSRegisterBootFileSystem(KFileSystem *fileSystem, EsUniqueIdentifier identi
|
|||
FSRegisterFileSystem(fileSystem);
|
||||
}
|
||||
|
||||
void FSFileSystemDeviceRemoved(KDevice *device) {
|
||||
void FSTrackUserFileSystemHandle(KDevice *device, bool opened) {
|
||||
KFileSystem *fileSystem = (KFileSystem *) device;
|
||||
_EsMessageWithObject m;
|
||||
EsMemoryZero(&m, sizeof(m));
|
||||
m.message.type = ES_MSG_UNREGISTER_FILE_SYSTEM;
|
||||
m.message.unregisterFileSystem.id = fileSystem->objectID;
|
||||
DesktopSendMessage(&m);
|
||||
if (opened) FSNodeOpenHandle(fileSystem->rootDirectory, ES_FLAGS_DEFAULT, FS_NODE_OPEN_HANDLE_STANDARD);
|
||||
else FSNodeCloseHandle(fileSystem->rootDirectory, ES_FLAGS_DEFAULT);
|
||||
}
|
||||
|
||||
void FSRegisterFileSystem(KFileSystem *fileSystem) {
|
||||
fileSystem->removed = FSFileSystemDeviceRemoved;
|
||||
|
||||
fileSystem->trackHandle = FSTrackUserFileSystemHandle;
|
||||
MMObjectCacheRegister(&fileSystem->cachedDirectoryEntries, FSTrimCachedDirectoryEntry,
|
||||
sizeof(FSDirectoryEntry) + 16 /* approximate average name bytes */ + fileSystem->directoryEntryDataBytes);
|
||||
MMObjectCacheRegister(&fileSystem->cachedNodes, FSTrimCachedNode,
|
||||
sizeof(FSFile) + fileSystem->nodeDataBytes);
|
||||
fileSystem->rootDirectory->directoryEntry->directoryChildren = fileSystem->rootDirectoryInitialChildren;
|
||||
FSNodeOpenHandle(fileSystem->rootDirectory, ES_FLAGS_DEFAULT, fileSystem->isBootFileSystem ? FS_NODE_OPEN_HANDLE_STANDARD : FS_NODE_OPEN_HANDLE_FIRST);
|
||||
|
||||
_EsMessageWithObject m;
|
||||
EsMemoryZero(&m, sizeof(m));
|
||||
m.message.type = ES_MSG_REGISTER_FILE_SYSTEM;
|
||||
m.message.registerFileSystem.isBootFileSystem = fileSystem->isBootFileSystem;
|
||||
m.message.registerFileSystem.rootDirectory = DesktopOpenHandle(fileSystem->rootDirectory, _ES_NODE_DIRECTORY_WRITE, KERNEL_OBJECT_NODE);
|
||||
|
||||
if (m.message.registerFileSystem.rootDirectory) {
|
||||
if (!DesktopSendMessage(&m)) {
|
||||
DesktopCloseHandle(m.message.registerFileSystem.rootDirectory); // This will check that the handle is still valid.
|
||||
}
|
||||
}
|
||||
|
||||
KDeviceSendConnectedMessage(fileSystem, ES_DEVICE_FILE_SYSTEM);
|
||||
KDeviceSendConnectedMessage(fileSystem, ES_DEVICE_FILE_SYSTEM, K_DEVICE_HANDLE_TRACKED);
|
||||
FSNodeCloseHandle(fileSystem->rootDirectory, ES_FLAGS_DEFAULT);
|
||||
}
|
||||
|
||||
void FSRegisterBlockDevice(KBlockDevice *device) {
|
||||
|
|
|
@ -495,10 +495,13 @@ struct KDevice {
|
|||
EsObjectID objectID;
|
||||
|
||||
// These callbacks are called with the deviceTreeMutex locked, and are all optional.
|
||||
void (*shutdown)(KDevice *device); // Called when the computer is about to shutdown.
|
||||
void (*dumpState)(KDevice *device); // Dump the entire state of the device for debugging.
|
||||
void (*removed)(KDevice *device); // Called when the device is removed. Called after the children are informed.
|
||||
void (*destroy)(KDevice *device); // Called just before the device is destroyed.
|
||||
void (*shutdown)(KDevice *device); // Called when the computer is about to shutdown.
|
||||
void (*dumpState)(KDevice *device); // Dump the entire state of the device for debugging.
|
||||
void (*removed)(KDevice *device); // Called when the device is removed. Called after the children are informed.
|
||||
void (*destroy)(KDevice *device); // Called just before the device is destroyed.
|
||||
void (*trackHandle)(KDevice *device, bool opened); // Called when a handle to the device with K_DEVICE_HANDLE_TRACKED is opened/closed.
|
||||
|
||||
#define K_DEVICE_HANDLE_TRACKED (1 << 0)
|
||||
};
|
||||
|
||||
struct KDriver {
|
||||
|
@ -524,11 +527,11 @@ void KDeviceAttachAll(KDevice *parentDevice, const char *cParentDriver);
|
|||
bool KDeviceAttachByName(KDevice *parentDevice, const char *cName);
|
||||
|
||||
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes /* must be at least the size of a KDevice */);
|
||||
void KDeviceOpenHandle(KDevice *device);
|
||||
void KDeviceOpenHandle(KDevice *device, uint32_t handleFlags = ES_FLAGS_DEFAULT);
|
||||
void KDeviceDestroy(KDevice *device); // Call if initialisation of the device failed. Otherwise use KDeviceCloseHandle.
|
||||
void KDeviceCloseHandle(KDevice *device); // The device creator is responsible for one handle after the creating it. The device is destroyed once all handles are closed.
|
||||
void KDeviceCloseHandle(KDevice *device, uint32_t handleFlags = ES_FLAGS_DEFAULT); // The device creator is responsible for one handle after the creating it. The device is destroyed once all handles are closed.
|
||||
void KDeviceRemoved(KDevice *device); // Call when a child device is removed. Must be called only once!
|
||||
void KDeviceSendConnectedMessage(KDevice *device, EsDeviceType type); // Send a message to Desktop to inform it the device was connected.
|
||||
void KDeviceSendConnectedMessage(KDevice *device, EsDeviceType type, uint32_t handleFlags = ES_FLAGS_DEFAULT); // Send a message to Desktop to inform it the device was connected.
|
||||
|
||||
#include <bin/generated_code/kernel_config.h>
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ bool OpenHandleToObject(void *object, KernelObjectType type, uint32_t flags) {
|
|||
} break;
|
||||
|
||||
case KERNEL_OBJECT_DEVICE: {
|
||||
KDeviceOpenHandle((KDevice *) object);
|
||||
KDeviceOpenHandle((KDevice *) object, flags);
|
||||
} break;
|
||||
|
||||
default: {
|
||||
|
@ -351,7 +351,7 @@ void CloseHandleToObject(void *object, KernelObjectType type, uint32_t flags) {
|
|||
} break;
|
||||
|
||||
case KERNEL_OBJECT_DEVICE: {
|
||||
KDeviceCloseHandle((KDevice *) object);
|
||||
KDeviceCloseHandle((KDevice *) object, flags);
|
||||
} break;
|
||||
|
||||
default: {
|
||||
|
|
|
@ -651,18 +651,37 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_NODE_OPEN) {
|
|||
_EsNodeInformation information;
|
||||
SYSCALL_READ(&information, argument3, sizeof(_EsNodeInformation));
|
||||
|
||||
SYSCALL_HANDLE_2(information.handle, KERNEL_OBJECT_NODE, _directory);
|
||||
KNode *directory = (KNode *) _directory.object;
|
||||
SYSCALL_HANDLE_2(information.handle, (KernelObjectType) (KERNEL_OBJECT_NODE | KERNEL_OBJECT_DEVICE), _directory);
|
||||
|
||||
KNode *directory = nullptr;
|
||||
uint64_t directoryFlags = 0;
|
||||
|
||||
if (_directory.type == KERNEL_OBJECT_DEVICE) {
|
||||
KDevice *device = (KDevice *) _directory.object;
|
||||
|
||||
if (device->type == ES_DEVICE_FILE_SYSTEM) {
|
||||
KFileSystem *fileSystem = (KFileSystem *) device;
|
||||
directory = fileSystem->rootDirectory;
|
||||
directoryFlags = _ES_NODE_DIRECTORY_WRITE;
|
||||
} else {
|
||||
SYSCALL_RETURN(ES_FATAL_ERROR_INCORRECT_NODE_TYPE, true);
|
||||
}
|
||||
} else if (_directory.type == KERNEL_OBJECT_NODE) {
|
||||
directory = (KNode *) _directory.object;
|
||||
directoryFlags = _directory.flags;
|
||||
} else {
|
||||
EsAssert(false);
|
||||
}
|
||||
|
||||
if (directory->directoryEntry->type != ES_NODE_DIRECTORY) {
|
||||
SYSCALL_RETURN(ES_FATAL_ERROR_INCORRECT_NODE_TYPE, true);
|
||||
}
|
||||
|
||||
if ((~_directory.flags & _ES_NODE_DIRECTORY_WRITE) && needWritePermission) {
|
||||
if ((~directoryFlags & _ES_NODE_DIRECTORY_WRITE) && needWritePermission) {
|
||||
SYSCALL_RETURN(ES_ERROR_PERMISSION_NOT_GRANTED, false);
|
||||
}
|
||||
|
||||
if (~_directory.flags & _ES_NODE_DIRECTORY_WRITE) {
|
||||
if (~directoryFlags & _ES_NODE_DIRECTORY_WRITE) {
|
||||
flags |= _ES_NODE_NO_WRITE_BASE;
|
||||
}
|
||||
|
||||
|
@ -1604,6 +1623,14 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_DEVICE_CONTROL) {
|
|||
} else {
|
||||
SYSCALL_RETURN(ES_FATAL_ERROR_UNKNOWN_SYSCALL, true);
|
||||
}
|
||||
} else if (device->type == ES_DEVICE_FILE_SYSTEM) {
|
||||
KFileSystem *fileSystem = (KFileSystem *) device;
|
||||
|
||||
if (type == ES_DEVICE_CONTROL_FS_IS_BOOT) {
|
||||
SYSCALL_RETURN(fileSystem->isBootFileSystem ? 1 : 0, false);
|
||||
} else {
|
||||
SYSCALL_RETURN(ES_FATAL_ERROR_UNKNOWN_SYSCALL, true);
|
||||
}
|
||||
} else {
|
||||
SYSCALL_RETURN(ES_FATAL_ERROR_UNKNOWN_SYSCALL, true);
|
||||
}
|
||||
|
|
|
@ -161,8 +161,10 @@ EsStringFormatTemporary=159
|
|||
EsStringFormatV=160
|
||||
EsStringFormatAppend=161
|
||||
EsStringFormatAppendV=162
|
||||
EsMountPointAdd=163
|
||||
EsSystemConfigurationReadFileTypes=164
|
||||
EsImageLoad=165
|
||||
EsMountPointRemove=166
|
||||
EsCRTabs=168
|
||||
EsCRTacosf=169
|
||||
EsCRTasinf=170
|
||||
|
@ -369,7 +371,6 @@ EsElementRepaintForScroll=372
|
|||
EsMemoryFaultRange=373
|
||||
EsDrawBitmapScaled=374
|
||||
EsRectangleCenter=375
|
||||
EsMountPointEnumerate=376
|
||||
EsMountPointGetVolumeInformation=377
|
||||
EsListViewInvalidateAll=378
|
||||
EsListViewGetFocusedItem=379
|
||||
|
|
Loading…
Reference in New Issue