private void SvcUnmapSharedMemory(CpuThreadState ThreadState) { int Handle = (int)ThreadState.X0; ulong Address = ThreadState.X1; ulong Size = ThreadState.X2; if (!PageAligned(Address)) { Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); return; } if (!PageAligned(Size) || Size == 0) { Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{Size:x16} is not page aligned or is zero!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize); return; } if (Address + Size <= Address) { Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return; } KProcess CurrentProcess = System.Scheduler.GetCurrentProcess(); KSharedMemory SharedMemory = CurrentProcess.HandleTable.GetObject <KSharedMemory>(Handle); if (SharedMemory == null) { Logger.PrintWarning(LogClass.KernelSvc, $"Invalid shared memory handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); return; } if (CurrentProcess.MemoryManager.IsInvalidRegion(Address, Size) || CurrentProcess.MemoryManager.InsideHeapRegion(Address, Size) || CurrentProcess.MemoryManager.InsideAliasRegion(Address, Size)) { Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} out of range!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return; } KernelResult Result = SharedMemory.UnmapFromProcess( CurrentProcess.MemoryManager, Address, Size, CurrentProcess); if (Result != KernelResult.Success) { Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{Result}\"."); } ThreadState.X0 = (ulong)Result; }
private void SvcUnmapSharedMemory(CpuThreadState threadState) { int handle = (int)threadState.X0; ulong address = threadState.X1; ulong size = threadState.X2; if (!PageAligned(address)) { Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{address:x16} is not page aligned!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); return; } if (!PageAligned(size) || size == 0) { Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize); return; } if (address + size <= address) { Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{address:x16} / size 0x{size:x16}!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return; } KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); KSharedMemory sharedMemory = currentProcess.HandleTable.GetObject <KSharedMemory>(handle); if (sharedMemory == null) { Logger.PrintWarning(LogClass.KernelSvc, $"Invalid shared memory handle 0x{handle:x8}!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); return; } if (currentProcess.MemoryManager.IsInvalidRegion(address, size) || currentProcess.MemoryManager.InsideHeapRegion(address, size) || currentProcess.MemoryManager.InsideAliasRegion(address, size)) { Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{address:x16} out of range!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return; } KernelResult result = sharedMemory.UnmapFromProcess( currentProcess.MemoryManager, address, size, currentProcess); if (result != KernelResult.Success) { Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{result}\"."); } threadState.X0 = (ulong)result; }