mirror of https://gitlab.com/nakst/essence
make block device information accessible in API
This commit is contained in:
parent
98cb1c0400
commit
485dbc59e5
|
@ -1,12 +1,24 @@
|
|||
#define INSTALLER
|
||||
|
||||
#define ES_CRT_WITHOUT_PREFIX
|
||||
#include <essence.h>
|
||||
#include <ports/lzma/LzmaDec.c>
|
||||
|
||||
#include <shared/hash.cpp>
|
||||
#include <ports/lzma/LzmaDec.c>
|
||||
|
||||
#include <shared/array.cpp>
|
||||
#define IMPLEMENTATION
|
||||
#include <shared/array.cpp>
|
||||
#undef IMPLEMENTATION
|
||||
|
||||
#define Log(...)
|
||||
#define exit(x) EsThreadTerminate(ES_CURRENT_THREAD)
|
||||
#include <shared/esfs2.h>
|
||||
|
||||
Array<EsMessageDevice> connectedDrives;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
||||
#define BUFFER_SIZE (1048576)
|
||||
#define NAME_MAX (4096)
|
||||
|
||||
|
@ -115,17 +127,55 @@ EsError Extract(const char *pathIn, size_t pathInBytes, const char *pathOut, siz
|
|||
}
|
||||
|
||||
void ReadBlock(uint64_t, uint64_t, void *) {
|
||||
// TODO.
|
||||
}
|
||||
|
||||
void WriteBlock(uint64_t, uint64_t, void *) {
|
||||
// TODO.
|
||||
}
|
||||
|
||||
void WriteBytes(uint64_t, uint64_t, void *) {
|
||||
// TODO.
|
||||
}
|
||||
|
||||
void ConnectedDriveAdd(EsMessageDevice device) {
|
||||
if (device.type != ES_DEVICE_BLOCK) {
|
||||
return;
|
||||
}
|
||||
|
||||
EsBlockDeviceInformation information;
|
||||
EsDeviceControl(device.handle, ES_DEVICE_CONTROL_BLOCK_GET_INFORMATION, 0, &information);
|
||||
|
||||
if (information.nestLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
connectedDrives.Add(device);
|
||||
}
|
||||
|
||||
void ConnectedDriveRemove(EsMessageDevice device) {
|
||||
for (uintptr_t i = 0; i < connectedDrives.Length(); i++) {
|
||||
if (connectedDrives[i].id == device.id) {
|
||||
connectedDrives.Delete(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _start() {
|
||||
_init();
|
||||
EsPerformanceTimerPush();
|
||||
EsAssert(ES_SUCCESS == Extract(EsLiteral("0:/installer_archive.dat"), EsLiteral("0:/extracted")));
|
||||
EsPrint("time: %Fs\n", EsPerformanceTimerPop());
|
||||
|
||||
EsDeviceEnumerate([] (EsMessageDevice device, EsGeneric) {
|
||||
ConnectedDriveAdd(device);
|
||||
}, 0);
|
||||
|
||||
while (true) {
|
||||
EsMessage *message = EsMessageReceive();
|
||||
|
||||
if (message->type == ES_MSG_DEVICE_CONNECTED) {
|
||||
ConnectedDriveAdd(message->device);
|
||||
} else if (message->type == ES_MSG_DEVICE_DISCONNECTED) {
|
||||
ConnectedDriveRemove(message->device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,9 @@ struct Timer {
|
|||
struct {
|
||||
Array<EsSystemConfigurationGroup> systemConfigurationGroups;
|
||||
EsMutex systemConfigurationMutex;
|
||||
|
||||
Array<MountPoint> mountPoints;
|
||||
Array<EsMessageDevice> connectedDevices;
|
||||
bool foundBootFileSystem;
|
||||
EsProcessStartupInformation *startupInformation;
|
||||
GlobalData *global;
|
||||
|
@ -254,12 +256,22 @@ bool EsMountPointGetVolumeInformation(const char *prefix, size_t prefixBytes, Es
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void EsDeviceEnumerate(EsDeviceEnumerationCallback callback, EsGeneric context) {
|
||||
EsMessageMutexCheck();
|
||||
|
||||
for (uintptr_t i = 0; i < api.connectedDevices.Length(); i++) {
|
||||
callback(api.connectedDevices[i], context);
|
||||
}
|
||||
}
|
||||
|
||||
EsError NodeOpen(const char *path, size_t pathBytes, uint32_t flags, _EsNodeInformation *node) {
|
||||
EsMountPoint *mountPoint = NodeFindMountPoint(path, pathBytes);
|
||||
|
||||
|
@ -1060,6 +1072,17 @@ EsMessage *EsMessageReceive() {
|
|||
return &message.message;
|
||||
}
|
||||
}
|
||||
} else if (type == ES_MSG_DEVICE_CONNECTED) {
|
||||
api.connectedDevices.Add(message.message.device);
|
||||
return &message.message;
|
||||
} else if (type == ES_MSG_DEVICE_DISCONNECTED) {
|
||||
for (uintptr_t i = 0; i < api.connectedDevices.Length(); i++) {
|
||||
if (api.connectedDevices[i].id == message.message.device.id) {
|
||||
EsHandleClose(api.connectedDevices[i].handle);
|
||||
api.connectedDevices.Delete(i);
|
||||
return &message.message;
|
||||
}
|
||||
}
|
||||
} else if (type == ES_MSG_INSTANCE_DESTROY) {
|
||||
APIInstance *instance = (APIInstance *) message.message.instanceDestroy.instance->_private;
|
||||
|
||||
|
@ -1263,6 +1286,18 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
|
|||
EsHeapFree(initialMountPoints);
|
||||
EsHandleClose(initialMountPointsBuffer);
|
||||
|
||||
EsHandle initialDevicesBuffer = api.startupInformation->data.initialDevices;
|
||||
size_t initialDevicesCount = EsConstantBufferGetSize(initialDevicesBuffer) / sizeof(EsMessageDevice);
|
||||
EsMessageDevice *initialDevices = (EsMessageDevice *) EsHeapAllocate(initialDevicesCount * sizeof(EsMessageDevice), false);
|
||||
EsConstantBufferRead(initialDevicesBuffer, initialDevices);
|
||||
|
||||
for (uintptr_t i = 0; i < initialDevicesCount; i++) {
|
||||
api.connectedDevices.Add(initialDevices[i]);
|
||||
}
|
||||
|
||||
EsHeapFree(initialDevices);
|
||||
EsHandleClose(initialDevicesBuffer);
|
||||
|
||||
uint8_t m = DESKTOP_MSG_SYSTEM_CONFIGURATION_GET;
|
||||
EsBuffer responseBuffer = { .canGrow = true };
|
||||
MessageDesktop(&m, 1, ES_INVALID_HANDLE, &responseBuffer);
|
||||
|
|
|
@ -175,7 +175,6 @@ struct {
|
|||
Array<InstalledApplication *> installedApplications;
|
||||
Array<ApplicationInstance *> allApplicationInstances;
|
||||
Array<ContainerWindow *> allContainerWindows;
|
||||
Array<EsMessageDevice> connectedDevices;
|
||||
|
||||
InstalledApplication *fileManager;
|
||||
|
||||
|
@ -1233,6 +1232,7 @@ bool ApplicationInstanceStart(int64_t applicationID, EsApplicationStartupInforma
|
|||
arguments.permissions = ES_PERMISSION_WINDOW_MANAGER;
|
||||
|
||||
Array<EsMountPoint> initialMountPoints = {};
|
||||
Array<EsMessageDevice> initialDevices = {};
|
||||
Array<EsHandle> handleDuplicateList = {};
|
||||
Array<uint32_t> handleModeDuplicateList = {};
|
||||
_EsNodeInformation settingsNode = {};
|
||||
|
@ -1270,6 +1270,14 @@ bool ApplicationInstanceStart(int64_t applicationID, EsApplicationStartupInforma
|
|||
handleModeDuplicateList.Add(2 /* prevent write */);
|
||||
}
|
||||
|
||||
if (application->permissions & APPLICATION_PERMISSION_ALL_DEVICES) {
|
||||
for (uintptr_t i = 0; i < api.connectedDevices.Length(); i++) {
|
||||
initialDevices.Add(api.connectedDevices[i]);
|
||||
handleDuplicateList.Add(api.connectedDevices[i].handle);
|
||||
handleModeDuplicateList.Add(0);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
error = NodeOpen(application->settingsPath, application->settingsPathBytes,
|
||||
ES_NODE_DIRECTORY | ES_NODE_CREATE_DIRECTORIES | _ES_NODE_DIRECTORY_WRITE, &settingsNode);
|
||||
|
@ -1291,6 +1299,10 @@ bool ApplicationInstanceStart(int64_t applicationID, EsApplicationStartupInforma
|
|||
handleDuplicateList.Add(arguments.data.initialMountPoints);
|
||||
handleModeDuplicateList.Add(0);
|
||||
|
||||
arguments.data.initialDevices = EsConstantBufferCreate(initialDevices.array, initialDevices.Length() * sizeof(EsMessageDevice), ES_CURRENT_PROCESS);
|
||||
handleDuplicateList.Add(arguments.data.initialDevices);
|
||||
handleModeDuplicateList.Add(0);
|
||||
|
||||
arguments.handles = handleDuplicateList.array;
|
||||
arguments.handleModes = handleModeDuplicateList.array;
|
||||
arguments.handleCount = handleDuplicateList.Length();
|
||||
|
@ -1300,6 +1312,7 @@ bool ApplicationInstanceStart(int64_t applicationID, EsApplicationStartupInforma
|
|||
EsHandleClose(arguments.executable);
|
||||
|
||||
initialMountPoints.Free();
|
||||
initialDevices.Free();
|
||||
handleDuplicateList.Free();
|
||||
handleModeDuplicateList.Free();
|
||||
|
||||
|
@ -1307,6 +1320,14 @@ bool ApplicationInstanceStart(int64_t applicationID, EsApplicationStartupInforma
|
|||
EsHandleClose(settingsNode.handle);
|
||||
}
|
||||
|
||||
if (arguments.data.initialMountPoints) {
|
||||
EsHandleClose(arguments.data.initialMountPoints);
|
||||
}
|
||||
|
||||
if (arguments.data.initialDevices) {
|
||||
EsHandleClose(arguments.data.initialDevices);
|
||||
}
|
||||
|
||||
if (!ES_CHECK_ERROR(error)) {
|
||||
process = information.handle;
|
||||
EsHandleClose(information.mainThread.handle);
|
||||
|
@ -2525,12 +2546,15 @@ void DesktopMessage(EsMessage *message) {
|
|||
for (uintptr_t i = 0; i < desktop.installedApplications.Length(); i++) {
|
||||
desktop.installedApplications[i]->notified = false;
|
||||
}
|
||||
} else if (message->type == ES_MSG_UNREGISTER_FILE_SYSTEM) {
|
||||
} else if (message->type == ES_MSG_DEVICE_CONNECTED) {
|
||||
EsHandle handle = message->device.handle;
|
||||
|
||||
for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) {
|
||||
ApplicationInstance *instance = desktop.allApplicationInstances[i];
|
||||
|
||||
if (instance->application && (instance->application->permissions & APPLICATION_PERMISSION_ALL_FILES)
|
||||
if (instance->application && (instance->application->permissions & APPLICATION_PERMISSION_ALL_DEVICES)
|
||||
&& instance->processHandle && !instance->application->notified) {
|
||||
message->device.handle = EsSyscall(ES_SYSCALL_HANDLE_SHARE, handle, instance->processHandle, 0, 0);
|
||||
EsMessagePostRemote(instance->processHandle, message);
|
||||
if (instance->application->useSingleProcess) instance->application->notified = true;
|
||||
}
|
||||
|
@ -2539,19 +2563,33 @@ void DesktopMessage(EsMessage *message) {
|
|||
for (uintptr_t i = 0; i < desktop.installedApplications.Length(); i++) {
|
||||
desktop.installedApplications[i]->notified = false;
|
||||
}
|
||||
} else if (message->type == ES_MSG_DEVICE_CONNECTED) {
|
||||
desktop.connectedDevices.Add(message->device);
|
||||
// TODO Propagate message.
|
||||
} else if (message->type == ES_MSG_DEVICE_DISCONNECTED) {
|
||||
for (uintptr_t i = 0; i < desktop.connectedDevices.Length(); i++) {
|
||||
if (desktop.connectedDevices[i].id == message->device.id) {
|
||||
EsHandleClose(desktop.connectedDevices[i].handle);
|
||||
desktop.connectedDevices.Delete(i);
|
||||
break;
|
||||
} else if (message->type == ES_MSG_UNREGISTER_FILE_SYSTEM || message->type == ES_MSG_DEVICE_DISCONNECTED) {
|
||||
for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) {
|
||||
ApplicationInstance *instance = desktop.allApplicationInstances[i];
|
||||
|
||||
if (!instance->application) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (message->type == ES_MSG_UNREGISTER_FILE_SYSTEM) {
|
||||
if (~instance->application->permissions & APPLICATION_PERMISSION_ALL_FILES) {
|
||||
continue;
|
||||
}
|
||||
} else if (message->type == ES_MSG_DEVICE_DISCONNECTED) {
|
||||
if (~instance->application->permissions & APPLICATION_PERMISSION_ALL_DEVICES) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->processHandle && !instance->application->notified) {
|
||||
EsMessagePostRemote(instance->processHandle, message);
|
||||
if (instance->application->useSingleProcess) instance->application->notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Propagate message.
|
||||
for (uintptr_t i = 0; i < desktop.installedApplications.Length(); i++) {
|
||||
desktop.installedApplications[i]->notified = false;
|
||||
}
|
||||
} else if (message->type == ES_MSG_SET_SCREEN_RESOLUTION) {
|
||||
if (desktop.setupDesktopUIComplete) {
|
||||
DesktopSetup(); // Refresh desktop UI.
|
||||
|
|
|
@ -827,6 +827,7 @@ enum EsSyscallType {
|
|||
ES_SYSCALL_FILE_CONTROL
|
||||
ES_SYSCALL_DIRECTORY_ENUMERATE
|
||||
ES_SYSCALL_VOLUME_GET_INFORMATION
|
||||
ES_SYSCALL_DEVICE_CONTROL
|
||||
|
||||
// Networking.
|
||||
|
||||
|
@ -1126,6 +1127,10 @@ enum EsClipboardFormat {
|
|||
ES_CLIPBOARD_FORMAT_PATH_LIST
|
||||
}
|
||||
|
||||
enum EsDeviceControlType {
|
||||
ES_DEVICE_CONTROL_BLOCK_GET_INFORMATION
|
||||
}
|
||||
|
||||
function_pointer int EsUICallback(struct EsElement *element, struct EsMessage *message);
|
||||
|
||||
struct EsBuffer {
|
||||
|
@ -1251,7 +1256,7 @@ struct EsMountPoint {
|
|||
};
|
||||
|
||||
struct EsProcessCreateData {
|
||||
EsHandle environment, initialMountPoints;
|
||||
EsHandle environment, initialMountPoints, initialDevices;
|
||||
};
|
||||
|
||||
struct EsProcessStartupInformation {
|
||||
|
@ -1860,6 +1865,17 @@ struct EsFontInformation {
|
|||
uint16_t availableWeightsItalic;
|
||||
};
|
||||
|
||||
struct EsBlockDeviceInformation {
|
||||
size_t sectorSize;
|
||||
EsFileOffset sectorCount;
|
||||
bool noMBR;
|
||||
bool readOnly;
|
||||
uint8_t nestLevel;
|
||||
uint8_t driveType;
|
||||
uint8_t modelBytes;
|
||||
char model[64];
|
||||
};
|
||||
|
||||
// Function pointer types.
|
||||
|
||||
function_pointer void EsThreadEntryCallback(EsGeneric argument);
|
||||
|
@ -1870,6 +1886,7 @@ 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, EsGeneric index);
|
||||
function_pointer void EsFontEnumerationCallback(const EsFontInformation *information, EsGeneric context);
|
||||
function_pointer void EsUserTaskCallback(EsUserTask *task, EsGeneric data);
|
||||
|
@ -1947,6 +1964,9 @@ function bool EsMountPointGetVolumeInformation(const char *prefix, size_t prefix
|
|||
function void EsMountPointEnumerate(EsMountPointEnumerationCallback callback, EsGeneric context);
|
||||
function void _EsPathAnnouncePathMoved(STRING oldPath, STRING newPath);
|
||||
|
||||
function void EsDeviceEnumerate(EsDeviceEnumerationCallback callback, EsGeneric context);
|
||||
function EsError EsDeviceControl(EsHandle handle, EsDeviceControlType type, int32_t di, void *dp);
|
||||
|
||||
// Processes and threads.
|
||||
|
||||
function EsError EsProcessCreate(EsProcessCreationArguments *arguments, EsProcessInformation *information);
|
||||
|
@ -1967,8 +1987,8 @@ function void *EsArenaAllocate(EsArena *arena, bool zero); // Not thread-safe.
|
|||
function void EsArenaFree(EsArena *arena, void *pointer); // Not thread-safe.
|
||||
function void EsArenaInitialise(EsArena *arena, size_t blockSize, size_t itemSize);
|
||||
|
||||
function const void *EsBufferRead(struct EsBuffer *buffer, size_t readBytes);
|
||||
function bool EsBufferReadInto(struct EsBuffer *buffer, void *destination, size_t readBytes);
|
||||
function const void *EsBufferRead(EsBuffer *buffer, size_t readBytes);
|
||||
function bool EsBufferReadInto(EsBuffer *buffer, void *destination, size_t readBytes);
|
||||
function const void *EsBufferReadMany(struct EsBuffer *buffer, size_t a, size_t b);
|
||||
function int32_t EsBufferReadInt32Endian(EsBuffer *buffer, int32_t errorValue);
|
||||
function void *EsBufferWrite(EsBuffer *buffer, const void *source, size_t writeBytes);
|
||||
|
|
|
@ -534,7 +534,7 @@ long EsPOSIXSystemCall(long n, long a1, long a2, long a3, long a4, long a5, long
|
|||
double timeStampMs = EsTimeStampMs();
|
||||
uint64_t ns = timeStampMs * 1e6;
|
||||
tp->tv_sec = ns / 1000000000;
|
||||
tp->tv_nsec = (ns % 1000000000) * 1000;
|
||||
tp->tv_nsec = ns % 1000000000;
|
||||
} break;
|
||||
|
||||
case SYS_wait4: {
|
||||
|
|
|
@ -903,3 +903,7 @@ size_t EsPipeRead(EsHandle pipe, void *buffer, size_t bytes) {
|
|||
size_t EsPipeWrite(EsHandle pipe, const void *buffer, size_t bytes) {
|
||||
return EsSyscall(ES_SYSCALL_PIPE_WRITE, pipe, (uintptr_t) buffer, bytes, 0);
|
||||
}
|
||||
|
||||
EsError EsDeviceControl(EsHandle handle, EsDeviceControlType type, int32_t di, void *dp) {
|
||||
return EsSyscall(ES_SYSCALL_DEVICE_CONTROL, handle, type, di, (uintptr_t) dp);
|
||||
}
|
||||
|
|
|
@ -835,13 +835,15 @@ void AHCIController::Initialise() {
|
|||
device->controller = this;
|
||||
device->port = i;
|
||||
|
||||
device->sectorSize = ports[i].sectorBytes;
|
||||
device->sectorCount = ports[i].sectorCount;
|
||||
device->maxAccessSectorCount = ports[i].atapi ? (65535 / device->sectorSize)
|
||||
: ((PRDT_ENTRY_COUNT - 1 /* need one extra if not page aligned */) * K_PAGE_SIZE / device->sectorSize);
|
||||
device->readOnly = ports[i].atapi;
|
||||
device->cModel = ports[i].model;
|
||||
device->driveType = ports[i].atapi ? ES_DRIVE_TYPE_CDROM : ports[i].ssd ? ES_DRIVE_TYPE_SSD : ES_DRIVE_TYPE_HDD;
|
||||
device->information.sectorSize = ports[i].sectorBytes;
|
||||
device->information.sectorCount = ports[i].sectorCount;
|
||||
device->maxAccessSectorCount = ports[i].atapi ? (65535 / device->information.sectorSize)
|
||||
: ((PRDT_ENTRY_COUNT - 1 /* need one extra if not page aligned */) * K_PAGE_SIZE / device->information.sectorSize);
|
||||
device->information.readOnly = ports[i].atapi;
|
||||
EsAssert(sizeof(ports[i].model) <= sizeof(device->information.model));
|
||||
EsMemoryCopy(device->information.model, ports[i].model, sizeof(ports[i].model));
|
||||
device->information.modelBytes = sizeof(ports[i].model);
|
||||
device->information.driveType = ports[i].atapi ? ES_DRIVE_TYPE_CDROM : ports[i].ssd ? ES_DRIVE_TYPE_SSD : ES_DRIVE_TYPE_HDD;
|
||||
|
||||
device->access = [] (KBlockDeviceAccessRequest request) {
|
||||
AHCIDrive *drive = (AHCIDrive *) request.device;
|
||||
|
|
|
@ -1833,7 +1833,7 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (volume->block->readOnly) {
|
||||
if (volume->block->information.readOnly) {
|
||||
volume->readOnly = true;
|
||||
}
|
||||
|
||||
|
@ -1846,8 +1846,8 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
|
|||
|
||||
ESFS_CHECK_FATAL(0 == EsMemoryCompare(volume->superblock.signature, ESFS_SIGNATURE_STRING, 16), "Invalid superblock signature.");
|
||||
ESFS_CHECK_FATAL(volume->superblock.requiredReadVersion <= ESFS_DRIVER_VERSION, "Incompatible file system version.");
|
||||
ESFS_CHECK_FATAL(superblock->blockSize >= 1024 && superblock->blockSize <= 16384 && (superblock->blockSize % volume->block->sectorSize) == 0, "Invalid block size.");
|
||||
ESFS_CHECK_FATAL(superblock->blockCount * superblock->blockSize / volume->block->sectorSize <= volume->block->sectorCount, "More blocks than drive.");
|
||||
ESFS_CHECK_FATAL(superblock->blockSize >= 1024 && superblock->blockSize <= 16384 && (superblock->blockSize % volume->block->information.sectorSize) == 0, "Invalid block size.");
|
||||
ESFS_CHECK_FATAL(superblock->blockCount * superblock->blockSize / volume->block->information.sectorSize <= volume->block->information.sectorCount, "More blocks than drive.");
|
||||
ESFS_CHECK_FATAL(superblock->blocksUsed <= superblock->blockCount, "More blocks used than exist.");
|
||||
ESFS_CHECK_FATAL(superblock->blocksPerGroup <= 65536 && superblock->blocksPerGroup < superblock->blockCount && superblock->blocksPerGroup >= 1024, "Invalid block group size.");
|
||||
ESFS_CHECK_FATAL((superblock->groupCount - 1) * superblock->blocksPerGroup <= superblock->blockCount, "Invalid number of block groups.");
|
||||
|
|
|
@ -140,16 +140,16 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
// Load the superblock.
|
||||
|
||||
uint8_t *sectorBuffer = (uint8_t *) EsHeapAllocate(volume->block->sectorSize, false, K_FIXED);
|
||||
uint8_t *sectorBuffer = (uint8_t *) EsHeapAllocate(volume->block->information.sectorSize, false, K_FIXED);
|
||||
|
||||
if (!sectorBuffer) {
|
||||
MOUNT_FAILURE("Could not allocate buffer.\n");
|
||||
}
|
||||
|
||||
EsDefer(EsHeapFree(sectorBuffer, volume->block->sectorSize, K_FIXED));
|
||||
EsDefer(EsHeapFree(sectorBuffer, volume->block->information.sectorSize, K_FIXED));
|
||||
|
||||
{
|
||||
if (!volume->Access(1024, volume->block->sectorSize, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access(1024, volume->block->information.sectorSize, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
MOUNT_FAILURE("Could not read boot sector.\n");
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
volume->blockBytes = 1024 << volume->superBlock.blockSizeExponent;
|
||||
|
||||
if (volume->blockBytes < volume->block->sectorSize) {
|
||||
if (volume->blockBytes < volume->block->information.sectorSize) {
|
||||
MOUNT_FAILURE("Block size smaller than drive sector size.\n");
|
||||
}
|
||||
}
|
||||
|
@ -201,14 +201,14 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
uint32_t blockGroup = (inode - 1) / volume->superBlock.inodesPerBlockGroup;
|
||||
uint32_t indexInInodeTable = (inode - 1) % volume->superBlock.inodesPerBlockGroup;
|
||||
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->block->sectorSize;
|
||||
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->block->sectorSize;
|
||||
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->block->information.sectorSize;
|
||||
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->block->information.sectorSize;
|
||||
|
||||
BlockGroupDescriptor *blockGroupDescriptor = volume->blockGroupDescriptorTable + blockGroup;
|
||||
|
||||
if (!volume->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
|
||||
+ sectorInInodeTable * volume->block->sectorSize,
|
||||
volume->block->sectorSize,
|
||||
+ sectorInInodeTable * volume->block->information.sectorSize,
|
||||
volume->block->information.sectorSize,
|
||||
K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
MOUNT_FAILURE("Could not read the inode table.\n");
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ static bool Mount(Volume *volume) {
|
|||
}
|
||||
|
||||
static uint32_t GetDataBlock(Volume *volume, Inode *node, uint64_t blockIndex, uint8_t *blockBuffer) {
|
||||
#define CHECK_BLOCK_INDEX() if (offset == 0 || offset / volume->block->sectorSize > volume->block->sectorCount) { \
|
||||
#define CHECK_BLOCK_INDEX() if (offset == 0 || offset / volume->block->information.sectorSize > volume->block->information.sectorCount) { \
|
||||
KernelLog(LOG_ERROR, "Ext2", "invalid block index", "GetDataBlock - Block out of bounds.\n"); return 0; }
|
||||
#define GET_DATA_BLOCK_ACCESS_FAILURE() do { KernelLog(LOG_ERROR, "Ext2", "block access failure", "GetDataBlock - Could not read block.\n"); return 0; } while (0)
|
||||
|
||||
|
@ -448,14 +448,14 @@ static EsError Load(KNode *_directory, KNode *node, KNodeMetadata *metadata, con
|
|||
|
||||
uint32_t blockGroup = (inode - 1) / volume->superBlock.inodesPerBlockGroup;
|
||||
uint32_t indexInInodeTable = (inode - 1) % volume->superBlock.inodesPerBlockGroup;
|
||||
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->block->sectorSize;
|
||||
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->block->sectorSize;
|
||||
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->block->information.sectorSize;
|
||||
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->block->information.sectorSize;
|
||||
|
||||
BlockGroupDescriptor *blockGroupDescriptor = volume->blockGroupDescriptorTable + blockGroup;
|
||||
|
||||
if (!volume->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
|
||||
+ sectorInInodeTable * volume->block->sectorSize,
|
||||
volume->block->sectorSize,
|
||||
+ sectorInInodeTable * volume->block->information.sectorSize,
|
||||
volume->block->information.sectorSize,
|
||||
K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
|
||||
return ES_ERROR_DRIVE_CONTROLLER_REPORTED;
|
||||
}
|
||||
|
@ -600,9 +600,9 @@ static void DeviceAttach(KDevice *parent) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (volume->block->sectorSize & 0x1FF) {
|
||||
if (volume->block->information.sectorSize & 0x1FF) {
|
||||
KernelLog(LOG_ERROR, "Ext2", "incorrect sector size", "Expected sector size to be a multiple of 512, but drive's sectors are %D.\n",
|
||||
volume->block->sectorSize);
|
||||
volume->block->information.sectorSize);
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -404,7 +404,7 @@ static bool Mount(Volume *volume) {
|
|||
sectorsPerFAT * SECTOR_SIZE, K_ACCESS_READ, volume->fat, ES_FLAGS_DEFAULT)) MOUNT_FAILURE("Could not read FAT.\n");
|
||||
|
||||
volume->spaceUsed = CountUsedClusters(volume) * superBlock->sectorsPerCluster * superBlock->bytesPerSector;
|
||||
volume->spaceTotal = volume->block->sectorSize * volume->block->sectorCount;
|
||||
volume->spaceTotal = volume->block->information.sectorSize * volume->block->information.sectorCount;
|
||||
|
||||
volume->rootDirectory->driverNode = EsHeapAllocate(sizeof(FSNode), true, K_FIXED);
|
||||
if (!volume->rootDirectory->driverNode) MOUNT_FAILURE("Could not allocate root node.\n");
|
||||
|
@ -461,7 +461,7 @@ static void DeviceAttach(KDevice *parent) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (volume->block->sectorSize != SECTOR_SIZE) {
|
||||
if (volume->block->information.sectorSize != SECTOR_SIZE) {
|
||||
KernelLog(LOG_ERROR, "FAT", "mount failure", "DeviceAttach - Unsupported sector size.\n");
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
|
|
|
@ -559,11 +559,11 @@ void ATAController::Initialise() {
|
|||
}
|
||||
|
||||
device->index = i;
|
||||
device->sectorSize = isATAPI[i] ? ATAPI_SECTOR_SIZE : ATA_SECTOR_SIZE;
|
||||
device->sectorCount = sectorCount[i];
|
||||
device->information.sectorSize = isATAPI[i] ? ATAPI_SECTOR_SIZE : ATA_SECTOR_SIZE;
|
||||
device->information.sectorCount = sectorCount[i];
|
||||
device->maxAccessSectorCount = isATAPI[i] ? 31 : 64;
|
||||
device->readOnly = isATAPI[i];
|
||||
device->driveType = isATAPI[i] ? ES_DRIVE_TYPE_CDROM : ES_DRIVE_TYPE_HDD;
|
||||
device->information.readOnly = isATAPI[i];
|
||||
device->information.driveType = isATAPI[i] ? ES_DRIVE_TYPE_CDROM : ES_DRIVE_TYPE_HDD;
|
||||
|
||||
device->access = [] (KBlockDeviceAccessRequest request) {
|
||||
request.dispatchGroup->Start();
|
||||
|
|
|
@ -172,8 +172,8 @@ static bool Mount(Volume *volume) {
|
|||
ScanInternal(EsLiteral("ESSENCE.DAT;1"), volume->rootDirectory, &record);
|
||||
record.extentSize.x = (record.extentSize.x + SECTOR_SIZE - 1) / SECTOR_SIZE;
|
||||
|
||||
if (!record.length || record.extentStart.x >= volume->block->sectorCount
|
||||
|| record.extentSize.x >= volume->block->sectorCount - record.extentStart.x) {
|
||||
if (!record.length || record.extentStart.x >= volume->block->information.sectorCount
|
||||
|| record.extentSize.x >= volume->block->information.sectorCount - record.extentStart.x) {
|
||||
goto notBoot;
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
KernelLog(LOG_INFO, "ISO9660", "found boot disc", "Found boot disc. Image at %d/%d.\n",
|
||||
record.extentStart.x, record.extentSize.x);
|
||||
FSPartitionDeviceCreate(volume->block, record.extentStart.x, record.extentSize.x, ES_FLAGS_DEFAULT, "CD-ROM boot partition");
|
||||
FSPartitionDeviceCreate(volume->block, record.extentStart.x, record.extentSize.x, ES_FLAGS_DEFAULT, EsLiteral("CD-ROM boot partition"));
|
||||
}
|
||||
|
||||
notBoot:;
|
||||
|
@ -495,9 +495,9 @@ static void DeviceAttach(KDevice *parent) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (volume->block->sectorSize != SECTOR_SIZE) {
|
||||
if (volume->block->information.sectorSize != SECTOR_SIZE) {
|
||||
KernelLog(LOG_ERROR, "ISO9660", "incorrect sector size", "DeviceAttach - Expected 2KB sectors, but drive's sectors are %D.\n",
|
||||
volume->block->sectorSize);
|
||||
volume->block->information.sectorSize);
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -317,8 +317,8 @@ bool NVMeController::Access(struct NVMeDrive *drive, uint64_t offsetBytes, size_
|
|||
KernelLog(LOG_VERBOSE, "NVMe", "start access", "Start access of %d, offset %D, count %D, using slot %d.\n",
|
||||
drive->nsid, offsetBytes, countBytes, ioSubmissionQueueTail);
|
||||
|
||||
uint64_t offsetSector = offsetBytes / drive->sectorSize;
|
||||
uint64_t countSectors = countBytes / drive->sectorSize;
|
||||
uint64_t offsetSector = offsetBytes / drive->information.sectorSize;
|
||||
uint64_t countSectors = countBytes / drive->information.sectorSize;
|
||||
|
||||
// Build the PRP list.
|
||||
|
||||
|
@ -801,11 +801,11 @@ void NVMeController::Initialise() {
|
|||
device->controller = this;
|
||||
device->nsid = nsid;
|
||||
|
||||
device->sectorSize = sectorBytes;
|
||||
device->sectorCount = capacity / sectorBytes;
|
||||
device->information.sectorSize = sectorBytes;
|
||||
device->information.sectorCount = capacity / sectorBytes;
|
||||
device->maxAccessSectorCount = maximumDataTransferBytes / sectorBytes;
|
||||
device->readOnly = readOnly;
|
||||
device->driveType = ES_DRIVE_TYPE_SSD;
|
||||
device->information.readOnly = readOnly;
|
||||
device->information.driveType = ES_DRIVE_TYPE_SSD;
|
||||
|
||||
device->access = [] (KBlockDeviceAccessRequest request) {
|
||||
NVMeDrive *drive = (NVMeDrive *) request.device;
|
||||
|
|
|
@ -98,8 +98,8 @@ void DriveAccess(KBlockDeviceAccessRequest request) {
|
|||
Device *device = drive->device;
|
||||
request.dispatchGroup->Start();
|
||||
|
||||
uint32_t offsetSectors = request.offset / drive->sectorSize;
|
||||
uint32_t countSectors = request.count / drive->sectorSize;
|
||||
uint32_t offsetSectors = request.offset / drive->information.sectorSize;
|
||||
uint32_t countSectors = request.count / drive->information.sectorSize;
|
||||
|
||||
CommandBlock command = {
|
||||
.transferBytes = (uint32_t) request.count,
|
||||
|
@ -194,12 +194,12 @@ void Device::Initialise() {
|
|||
|
||||
drive->device = this;
|
||||
drive->lun = i;
|
||||
drive->sectorSize = sectorBytes;
|
||||
drive->sectorCount = sectorCount;
|
||||
drive->information.sectorSize = sectorBytes;
|
||||
drive->information.sectorCount = sectorCount;
|
||||
drive->maxAccessSectorCount = 262144 / sectorBytes; // TODO How to determine this? What does the USB layer support?
|
||||
drive->readOnly = false; // TODO How to detect this?
|
||||
drive->information.readOnly = false; // TODO How to detect this?
|
||||
drive->access = DriveAccess;
|
||||
drive->driveType = ES_DRIVE_TYPE_USB_MASS_STORAGE;
|
||||
drive->information.driveType = ES_DRIVE_TYPE_USB_MASS_STORAGE;
|
||||
|
||||
FSRegisterBlockDevice(drive);
|
||||
}
|
||||
|
|
|
@ -135,6 +135,7 @@ void KDeviceSendConnectedMessage(KDevice *device, EsDeviceType type) {
|
|||
}
|
||||
|
||||
device->flags |= K_DEVICE_VISIBLE_TO_USER;
|
||||
device->type = type;
|
||||
|
||||
KMutexRelease(&deviceTreeMutex);
|
||||
|
||||
|
|
|
@ -1546,16 +1546,16 @@ bool FSBlockDeviceAccess(KBlockDeviceAccessRequest request) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (device->readOnly && request.operation == K_ACCESS_WRITE) {
|
||||
if (device->information.readOnly && request.operation == K_ACCESS_WRITE) {
|
||||
KernelPanic("FSBlockDeviceAccess - Drive %x is read-only.\n", device);
|
||||
}
|
||||
|
||||
if (request.offset / device->sectorSize > device->sectorCount
|
||||
|| (request.offset + request.count) / device->sectorSize > device->sectorCount) {
|
||||
if (request.offset / device->information.sectorSize > device->information.sectorCount
|
||||
|| (request.offset + request.count) / device->information.sectorSize > device->information.sectorCount) {
|
||||
KernelPanic("FSBlockDeviceAccess - Access out of bounds on drive %x.\n", device);
|
||||
}
|
||||
|
||||
if ((request.offset % device->sectorSize) || (request.count % device->sectorSize)) {
|
||||
if ((request.offset % device->information.sectorSize) || (request.count % device->information.sectorSize)) {
|
||||
KernelPanic("FSBlockDeviceAccess - Misaligned access.\n");
|
||||
}
|
||||
|
||||
|
@ -1581,7 +1581,7 @@ bool FSBlockDeviceAccess(KBlockDeviceAccessRequest request) {
|
|||
r.offset = request.offset;
|
||||
|
||||
while (request.count) {
|
||||
r.count = device->maxAccessSectorCount * device->sectorSize;
|
||||
r.count = device->maxAccessSectorCount * device->information.sectorSize;
|
||||
if (r.count > request.count) r.count = request.count;
|
||||
buffer.offsetBytes = 0;
|
||||
buffer.totalByteCount = r.count;
|
||||
|
@ -1669,25 +1669,28 @@ struct PartitionDevice : KBlockDevice {
|
|||
void FSPartitionDeviceAccess(KBlockDeviceAccessRequest request) {
|
||||
PartitionDevice *_device = (PartitionDevice *) request.device;
|
||||
request.device = (KBlockDevice *) _device->parent;
|
||||
request.offset += _device->sectorOffset * _device->sectorSize;
|
||||
request.offset += _device->sectorOffset * _device->information.sectorSize;
|
||||
FSBlockDeviceAccess(request);
|
||||
}
|
||||
|
||||
void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOffset sectorCount, unsigned flags, const char *cName) {
|
||||
PartitionDevice *child = (PartitionDevice *) KDeviceCreate(cName, parent, sizeof(PartitionDevice));
|
||||
void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOffset sectorCount, unsigned flags, const char *model, size_t modelBytes) {
|
||||
PartitionDevice *child = (PartitionDevice *) KDeviceCreate("Partition", parent, sizeof(PartitionDevice));
|
||||
if (!child) return;
|
||||
|
||||
if (modelBytes > sizeof(child->information.model)) modelBytes = sizeof(child->information.model);
|
||||
EsMemoryCopy(child->information.model, model, modelBytes);
|
||||
|
||||
child->parent = parent;
|
||||
child->sectorSize = parent->sectorSize;
|
||||
child->information.sectorSize = parent->information.sectorSize;
|
||||
child->maxAccessSectorCount = parent->maxAccessSectorCount;
|
||||
child->sectorOffset = offset;
|
||||
child->sectorCount = sectorCount;
|
||||
child->noMBR = flags & FS_PARTITION_DEVICE_NO_MBR ? true : false;
|
||||
child->readOnly = parent->readOnly;
|
||||
child->information.sectorCount = sectorCount;
|
||||
child->information.noMBR = flags & FS_PARTITION_DEVICE_NO_MBR ? true : false;
|
||||
child->information.readOnly = parent->information.readOnly;
|
||||
child->access = FSPartitionDeviceAccess;
|
||||
child->cModel = cName;
|
||||
child->nestLevel = parent->nestLevel + 1;
|
||||
child->driveType = parent->driveType;
|
||||
child->information.modelBytes = modelBytes;
|
||||
child->information.nestLevel = parent->information.nestLevel + 1;
|
||||
child->information.driveType = parent->information.driveType;
|
||||
|
||||
FSRegisterBlockDevice(child);
|
||||
}
|
||||
|
@ -1697,7 +1700,7 @@ void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOf
|
|||
//////////////////////////////////////////
|
||||
|
||||
bool FSSignatureCheck(KInstalledDriver *driver, KDevice *device) {
|
||||
uint8_t *block = ((KBlockDevice *) device)->information;
|
||||
uint8_t *block = ((KBlockDevice *) device)->signatureBlock;
|
||||
|
||||
EsINIState s = {};
|
||||
s.buffer = driver->config;
|
||||
|
@ -1723,7 +1726,7 @@ bool FSSignatureCheck(KInstalledDriver *driver, KDevice *device) {
|
|||
}
|
||||
|
||||
bool FSCheckMBR(KBlockDevice *device) {
|
||||
if (device->information[510] != 0x55 || device->information[511] != 0xAA) {
|
||||
if (device->signatureBlock[510] != 0x55 || device->signatureBlock[511] != 0xAA) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1733,23 +1736,23 @@ bool FSCheckMBR(KBlockDevice *device) {
|
|||
bool present[4] = {};
|
||||
|
||||
for (uintptr_t i = 0; i < 4; i++) {
|
||||
if (!device->information[4 + 0x1BE + i * 0x10]) {
|
||||
if (!device->signatureBlock[4 + 0x1BE + i * 0x10]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
offsets[i] =
|
||||
((uint32_t) device->information[0x1BE + i * 0x10 + 8 ] << 0 )
|
||||
+ ((uint32_t) device->information[0x1BE + i * 0x10 + 9 ] << 8 )
|
||||
+ ((uint32_t) device->information[0x1BE + i * 0x10 + 10] << 16)
|
||||
+ ((uint32_t) device->information[0x1BE + i * 0x10 + 11] << 24);
|
||||
((uint32_t) device->signatureBlock[0x1BE + i * 0x10 + 8 ] << 0 )
|
||||
+ ((uint32_t) device->signatureBlock[0x1BE + i * 0x10 + 9 ] << 8 )
|
||||
+ ((uint32_t) device->signatureBlock[0x1BE + i * 0x10 + 10] << 16)
|
||||
+ ((uint32_t) device->signatureBlock[0x1BE + i * 0x10 + 11] << 24);
|
||||
counts[i] =
|
||||
((uint32_t) device->information[0x1BE + i * 0x10 + 12] << 0 )
|
||||
+ ((uint32_t) device->information[0x1BE + i * 0x10 + 13] << 8 )
|
||||
+ ((uint32_t) device->information[0x1BE + i * 0x10 + 14] << 16)
|
||||
+ ((uint32_t) device->information[0x1BE + i * 0x10 + 15] << 24);
|
||||
((uint32_t) device->signatureBlock[0x1BE + i * 0x10 + 12] << 0 )
|
||||
+ ((uint32_t) device->signatureBlock[0x1BE + i * 0x10 + 13] << 8 )
|
||||
+ ((uint32_t) device->signatureBlock[0x1BE + i * 0x10 + 14] << 16)
|
||||
+ ((uint32_t) device->signatureBlock[0x1BE + i * 0x10 + 15] << 24);
|
||||
present[i] = true;
|
||||
|
||||
if (offsets[i] > device->sectorCount || counts[i] > device->sectorCount - offsets[i] || counts[i] < 32) {
|
||||
if (offsets[i] > device->information.sectorCount || counts[i] > device->information.sectorCount - offsets[i] || counts[i] < 32) {
|
||||
KernelLog(LOG_INFO, "FS", "invalid MBR", "Partition %d has offset %d and count %d, which is invalid. Ignoring the rest of the MBR...\n",
|
||||
i, offsets[i], counts[i]);
|
||||
return false;
|
||||
|
@ -1760,7 +1763,7 @@ bool FSCheckMBR(KBlockDevice *device) {
|
|||
if (present[i]) {
|
||||
KernelLog(LOG_INFO, "FS", "MBR partition", "Found MBR partition %d with offset %d and count %d.\n",
|
||||
i, offsets[i], counts[i]);
|
||||
FSPartitionDeviceCreate(device, offsets[i], counts[i], FS_PARTITION_DEVICE_NO_MBR, "MBR partition");
|
||||
FSPartitionDeviceCreate(device, offsets[i], counts[i], FS_PARTITION_DEVICE_NO_MBR, EsLiteral("MBR partition"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1790,31 +1793,31 @@ bool FSFileSystemInitialise(KFileSystem *fileSystem) {
|
|||
}
|
||||
|
||||
void FSDetectFileSystem(KBlockDevice *device) {
|
||||
KernelLog(LOG_INFO, "FS", "detect file system", "Detecting file system on block device '%z'.\n", device->cModel);
|
||||
KernelLog(LOG_INFO, "FS", "detect file system", "Detecting file system on block device '%s'.\n", device->information.modelBytes, device->information.model);
|
||||
|
||||
if (device->nestLevel > 4) {
|
||||
if (device->information.nestLevel > 4) {
|
||||
KernelLog(LOG_ERROR, "FS", "file system nest limit", "Reached file system nest limit (4), ignoring device.\n");
|
||||
}
|
||||
|
||||
uint64_t sectorsToRead = (K_SIGNATURE_BLOCK_SIZE + device->sectorSize - 1) / device->sectorSize;
|
||||
uint64_t sectorsToRead = (K_SIGNATURE_BLOCK_SIZE + device->information.sectorSize - 1) / device->information.sectorSize;
|
||||
|
||||
if (sectorsToRead > device->sectorCount) {
|
||||
if (sectorsToRead > device->information.sectorCount) {
|
||||
KernelLog(LOG_ERROR, "FS", "drive too small", "The drive must be at least %D (K_SIGNATURE_BLOCK_SIZE).\n", K_SIGNATURE_BLOCK_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *information = (uint8_t *) EsHeapAllocate(sectorsToRead * device->sectorSize, false, K_FIXED);
|
||||
uint8_t *signatureBlock = (uint8_t *) EsHeapAllocate(sectorsToRead * device->information.sectorSize, false, K_FIXED);
|
||||
|
||||
if (!information) {
|
||||
if (!signatureBlock) {
|
||||
return;
|
||||
}
|
||||
|
||||
device->information = information;
|
||||
device->signatureBlock = signatureBlock;
|
||||
|
||||
KDMABuffer dmaBuffer = { (uintptr_t) information };
|
||||
KDMABuffer dmaBuffer = { (uintptr_t) signatureBlock };
|
||||
KBlockDeviceAccessRequest request = {};
|
||||
request.device = device;
|
||||
request.count = sectorsToRead * device->sectorSize;
|
||||
request.count = sectorsToRead * device->information.sectorSize;
|
||||
request.operation = K_ACCESS_READ;
|
||||
request.buffer = &dmaBuffer;
|
||||
|
||||
|
@ -1822,14 +1825,14 @@ void FSDetectFileSystem(KBlockDevice *device) {
|
|||
// We could not access the block device.
|
||||
KernelLog(LOG_ERROR, "FS", "detect fileSystem read failure", "The signature block could not be read on block device %x.\n", device);
|
||||
} else {
|
||||
if (!device->noMBR && FSCheckMBR(device)) {
|
||||
if (!device->information.noMBR && FSCheckMBR(device)) {
|
||||
// Found an MBR.
|
||||
} else {
|
||||
KDeviceAttach(device, "Files", FSSignatureCheck);
|
||||
}
|
||||
}
|
||||
|
||||
EsHeapFree(information, sectorsToRead * device->sectorSize, K_FIXED);
|
||||
EsHeapFree(signatureBlock, sectorsToRead * device->information.sectorSize, K_FIXED);
|
||||
KDeviceCloseHandle(device);
|
||||
}
|
||||
|
||||
|
|
|
@ -551,6 +551,7 @@ struct KDevice {
|
|||
#define K_DEVICE_VISIBLE_TO_USER (1 << 1) // A ES_MSG_DEVICE_CONNECTED message was sent to Desktop for this device.
|
||||
uint8_t flags;
|
||||
uint32_t handles;
|
||||
EsDeviceType type;
|
||||
EsObjectID objectID;
|
||||
|
||||
// These callbacks are called with the deviceTreeMutex locked, and are all optional.
|
||||
|
@ -628,21 +629,16 @@ typedef void (*KDeviceAccessCallbackFunction)(KBlockDeviceAccessRequest request)
|
|||
|
||||
struct KBlockDevice : KDevice {
|
||||
KDeviceAccessCallbackFunction access; // Don't call directly; see KFileSystem::Access.
|
||||
size_t sectorSize, maxAccessSectorCount;
|
||||
EsFileOffset sectorCount;
|
||||
bool noMBR; // Set to `true` if this device cannot contain a MBR.
|
||||
bool readOnly;
|
||||
uint8_t nestLevel;
|
||||
uint8_t driveType;
|
||||
const char *cModel;
|
||||
EsBlockDeviceInformation information;
|
||||
size_t maxAccessSectorCount;
|
||||
|
||||
K_PRIVATE
|
||||
|
||||
uint8_t *information; // Signature block. Only valid during fileSystem detection.
|
||||
uint8_t *signatureBlock; // Signature block. Only valid during fileSystem detection.
|
||||
};
|
||||
|
||||
#define FS_PARTITION_DEVICE_NO_MBR (1 << 0)
|
||||
void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOffset sectorCount, unsigned flags, const char *cName);
|
||||
void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOffset sectorCount, unsigned flags, const char *name, size_t nameBytes);
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
// PCI.
|
||||
|
|
|
@ -725,9 +725,14 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_MAP_OBJECT) {
|
|||
|
||||
SYSCALL_IMPLEMENT(ES_SYSCALL_CONSTANT_BUFFER_CREATE) {
|
||||
if (argument2 > SYSCALL_BUFFER_LIMIT) SYSCALL_RETURN(ES_FATAL_ERROR_INVALID_BUFFER, true);
|
||||
SYSCALL_BUFFER(argument0, argument2, 1, false);
|
||||
SYSCALL_HANDLE(argument1, KERNEL_OBJECT_PROCESS, process, Process);
|
||||
SYSCALL_RETURN(MakeConstantBuffer((void *) argument0, argument2, process), false);
|
||||
|
||||
if (argument2) {
|
||||
SYSCALL_BUFFER(argument0, argument2, 1, false);
|
||||
SYSCALL_RETURN(MakeConstantBuffer((void *) argument0, argument2, process), false);
|
||||
} else {
|
||||
SYSCALL_RETURN(MakeConstantBuffer(nullptr, 0, process), false);
|
||||
}
|
||||
}
|
||||
|
||||
SYSCALL_IMPLEMENT(ES_SYSCALL_HANDLE_SHARE) {
|
||||
|
@ -748,7 +753,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_VOLUME_GET_INFORMATION) {
|
|||
EsMemoryZero(&information, sizeof(EsVolumeInformation));
|
||||
EsMemoryCopy(information.label, fileSystem->name, sizeof(fileSystem->name));
|
||||
information.labelBytes = fileSystem->nameBytes;
|
||||
information.driveType = fileSystem->block->driveType;
|
||||
information.driveType = fileSystem->block->information.driveType;
|
||||
information.spaceUsed = fileSystem->spaceUsed;
|
||||
information.spaceTotal = fileSystem->spaceTotal;
|
||||
information.id = fileSystem->objectID;
|
||||
|
@ -1816,6 +1821,24 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_CONNECTION_NOTIFY) {
|
|||
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||
}
|
||||
|
||||
SYSCALL_IMPLEMENT(ES_SYSCALL_DEVICE_CONTROL) {
|
||||
SYSCALL_HANDLE(argument0, KERNEL_OBJECT_DEVICE, device, KDevice);
|
||||
|
||||
if (device->type == ES_DEVICE_BLOCK) {
|
||||
KBlockDevice *block = (KBlockDevice *) device;
|
||||
|
||||
if (argument1 == ES_DEVICE_CONTROL_BLOCK_GET_INFORMATION) {
|
||||
SYSCALL_WRITE(argument3, &block->information, sizeof(EsBlockDeviceInformation));
|
||||
} else {
|
||||
SYSCALL_RETURN(ES_FATAL_ERROR_UNKNOWN_SYSCALL, true);
|
||||
}
|
||||
} else {
|
||||
SYSCALL_RETURN(ES_FATAL_ERROR_UNKNOWN_SYSCALL, true);
|
||||
}
|
||||
|
||||
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||
}
|
||||
|
||||
SYSCALL_IMPLEMENT(ES_SYSCALL_DEBUG_COMMAND) {
|
||||
#ifdef DEBUG_BUILD
|
||||
if (argument0 == 1) {
|
||||
|
|
|
@ -6,6 +6,7 @@ EsPOSIXInitialise=4
|
|||
EsFileStoreReadAll=5
|
||||
EsPOSIXSystemCall=6
|
||||
EsINIParse=7
|
||||
EsDeviceEnumerate=8
|
||||
EsTakeSystemSnapshot=9
|
||||
EsListViewFocusItem=10
|
||||
_EsInstanceCreate=11
|
||||
|
@ -444,3 +445,4 @@ EsColorInterpolate=443
|
|||
EsBufferReadInt32Endian=444
|
||||
EsBufferWriteInt32Endian=445
|
||||
EsSystemGetOptimalWorkQueueThreadCount=446
|
||||
EsDeviceControl=447
|
||||
|
|
Loading…
Reference in New Issue