SvcSystem.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. using ChocolArm64.Memory;
  2. using ChocolArm64.State;
  3. using Ryujinx.Common;
  4. using Ryujinx.Common.Logging;
  5. using Ryujinx.HLE.Exceptions;
  6. using Ryujinx.HLE.HOS.Ipc;
  7. using Ryujinx.HLE.HOS.Services;
  8. using System;
  9. using System.Threading;
  10. using static Ryujinx.HLE.HOS.ErrorCode;
  11. namespace Ryujinx.HLE.HOS.Kernel
  12. {
  13. partial class SvcHandler
  14. {
  15. private void SvcExitProcess(CpuThreadState threadState)
  16. {
  17. _system.Scheduler.GetCurrentProcess().Terminate();
  18. }
  19. private void SignalEvent64(CpuThreadState threadState)
  20. {
  21. threadState.X0 = (ulong)SignalEvent((int)threadState.X0);
  22. }
  23. private KernelResult SignalEvent(int handle)
  24. {
  25. KWritableEvent writableEvent = _process.HandleTable.GetObject<KWritableEvent>(handle);
  26. KernelResult result;
  27. if (writableEvent != null)
  28. {
  29. writableEvent.Signal();
  30. result = KernelResult.Success;
  31. }
  32. else
  33. {
  34. result = KernelResult.InvalidHandle;
  35. }
  36. if (result != KernelResult.Success)
  37. {
  38. Logger.PrintWarning(LogClass.KernelSvc, "Operation failed with error: " + result + "!");
  39. }
  40. return result;
  41. }
  42. private void ClearEvent64(CpuThreadState threadState)
  43. {
  44. threadState.X0 = (ulong)ClearEvent((int)threadState.X0);
  45. }
  46. private KernelResult ClearEvent(int handle)
  47. {
  48. KernelResult result;
  49. KWritableEvent writableEvent = _process.HandleTable.GetObject<KWritableEvent>(handle);
  50. if (writableEvent == null)
  51. {
  52. KReadableEvent readableEvent = _process.HandleTable.GetObject<KReadableEvent>(handle);
  53. result = readableEvent?.Clear() ?? KernelResult.InvalidHandle;
  54. }
  55. else
  56. {
  57. result = writableEvent.Clear();
  58. }
  59. if (result != KernelResult.Success)
  60. {
  61. Logger.PrintWarning(LogClass.KernelSvc, "Operation failed with error: " + result + "!");
  62. }
  63. return result;
  64. }
  65. private void SvcCloseHandle(CpuThreadState threadState)
  66. {
  67. int handle = (int)threadState.X0;
  68. object obj = _process.HandleTable.GetObject<object>(handle);
  69. _process.HandleTable.CloseHandle(handle);
  70. if (obj == null)
  71. {
  72. Logger.PrintWarning(LogClass.KernelSvc, $"Invalid handle 0x{handle:x8}!");
  73. threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
  74. return;
  75. }
  76. if (obj is KSession session)
  77. {
  78. session.Dispose();
  79. }
  80. else if (obj is KTransferMemory transferMemory)
  81. {
  82. _process.MemoryManager.ResetTransferMemory(
  83. transferMemory.Address,
  84. transferMemory.Size);
  85. }
  86. threadState.X0 = 0;
  87. }
  88. private void ResetSignal64(CpuThreadState threadState)
  89. {
  90. threadState.X0 = (ulong)ResetSignal((int)threadState.X0);
  91. }
  92. private KernelResult ResetSignal(int handle)
  93. {
  94. KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
  95. KReadableEvent readableEvent = currentProcess.HandleTable.GetObject<KReadableEvent>(handle);
  96. KernelResult result;
  97. if (readableEvent != null)
  98. {
  99. result = readableEvent.ClearIfSignaled();
  100. }
  101. else
  102. {
  103. KProcess process = currentProcess.HandleTable.GetKProcess(handle);
  104. if (process != null)
  105. {
  106. result = process.ClearIfNotExited();
  107. }
  108. else
  109. {
  110. result = KernelResult.InvalidHandle;
  111. }
  112. }
  113. if (result == KernelResult.InvalidState)
  114. {
  115. Logger.PrintDebug(LogClass.KernelSvc, "Operation failed with error: " + result + "!");
  116. }
  117. else if (result != KernelResult.Success)
  118. {
  119. Logger.PrintWarning(LogClass.KernelSvc, "Operation failed with error: " + result + "!");
  120. }
  121. return result;
  122. }
  123. private void SvcGetSystemTick(CpuThreadState threadState)
  124. {
  125. threadState.X0 = threadState.CntpctEl0;
  126. }
  127. private void SvcConnectToNamedPort(CpuThreadState threadState)
  128. {
  129. long stackPtr = (long)threadState.X0;
  130. long namePtr = (long)threadState.X1;
  131. string name = MemoryHelper.ReadAsciiString(_memory, namePtr, 8);
  132. //TODO: Validate that app has perms to access the service, and that the service
  133. //actually exists, return error codes otherwise.
  134. KSession session = new KSession(ServiceFactory.MakeService(_system, name), name);
  135. if (_process.HandleTable.GenerateHandle(session, out int handle) != KernelResult.Success)
  136. {
  137. throw new InvalidOperationException("Out of handles!");
  138. }
  139. threadState.X0 = 0;
  140. threadState.X1 = (uint)handle;
  141. }
  142. private void SvcSendSyncRequest(CpuThreadState threadState)
  143. {
  144. SendSyncRequest(threadState, threadState.Tpidr, 0x100, (int)threadState.X0);
  145. }
  146. private void SvcSendSyncRequestWithUserBuffer(CpuThreadState threadState)
  147. {
  148. SendSyncRequest(
  149. threadState,
  150. (long)threadState.X0,
  151. (long)threadState.X1,
  152. (int)threadState.X2);
  153. }
  154. private void SendSyncRequest(CpuThreadState threadState, long messagePtr, long size, int handle)
  155. {
  156. byte[] messageData = _memory.ReadBytes(messagePtr, size);
  157. KSession session = _process.HandleTable.GetObject<KSession>(handle);
  158. if (session != null)
  159. {
  160. _system.CriticalSection.Enter();
  161. KThread currentThread = _system.Scheduler.GetCurrentThread();
  162. currentThread.SignaledObj = null;
  163. currentThread.ObjSyncResult = 0;
  164. currentThread.Reschedule(ThreadSchedState.Paused);
  165. IpcMessage message = new IpcMessage(messageData, messagePtr);
  166. ThreadPool.QueueUserWorkItem(ProcessIpcRequest, new HleIpcMessage(
  167. currentThread,
  168. session,
  169. message,
  170. messagePtr));
  171. _system.ThreadCounter.AddCount();
  172. _system.CriticalSection.Leave();
  173. threadState.X0 = (ulong)currentThread.ObjSyncResult;
  174. }
  175. else
  176. {
  177. Logger.PrintWarning(LogClass.KernelSvc, $"Invalid session handle 0x{handle:x8}!");
  178. threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
  179. }
  180. }
  181. private void ProcessIpcRequest(object state)
  182. {
  183. HleIpcMessage ipcMessage = (HleIpcMessage)state;
  184. ipcMessage.Thread.ObjSyncResult = (int)IpcHandler.IpcCall(
  185. _device,
  186. _process,
  187. _memory,
  188. ipcMessage.Session,
  189. ipcMessage.Message,
  190. ipcMessage.MessagePtr);
  191. _system.ThreadCounter.Signal();
  192. ipcMessage.Thread.Reschedule(ThreadSchedState.Running);
  193. }
  194. private void GetProcessId64(CpuThreadState threadState)
  195. {
  196. int handle = (int)threadState.X1;
  197. KernelResult result = GetProcessId(handle, out long pid);
  198. threadState.X0 = (ulong)result;
  199. threadState.X1 = (ulong)pid;
  200. }
  201. private KernelResult GetProcessId(int handle, out long pid)
  202. {
  203. KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
  204. KProcess process = currentProcess.HandleTable.GetKProcess(handle);
  205. if (process == null)
  206. {
  207. KThread thread = currentProcess.HandleTable.GetKThread(handle);
  208. if (thread != null)
  209. {
  210. process = thread.Owner;
  211. }
  212. //TODO: KDebugEvent.
  213. }
  214. pid = process?.Pid ?? 0;
  215. return process != null
  216. ? KernelResult.Success
  217. : KernelResult.InvalidHandle;
  218. }
  219. private void SvcBreak(CpuThreadState threadState)
  220. {
  221. long reason = (long)threadState.X0;
  222. long unknown = (long)threadState.X1;
  223. long info = (long)threadState.X2;
  224. KThread currentThread = _system.Scheduler.GetCurrentThread();
  225. if ((reason & (1 << 31)) == 0)
  226. {
  227. currentThread.PrintGuestStackTrace();
  228. throw new GuestBrokeExecutionException();
  229. }
  230. else
  231. {
  232. Logger.PrintInfo(LogClass.KernelSvc, "Debugger triggered.");
  233. currentThread.PrintGuestStackTrace();
  234. }
  235. }
  236. private void SvcOutputDebugString(CpuThreadState threadState)
  237. {
  238. long position = (long)threadState.X0;
  239. long size = (long)threadState.X1;
  240. string str = MemoryHelper.ReadAsciiString(_memory, position, size);
  241. Logger.PrintWarning(LogClass.KernelSvc, str);
  242. threadState.X0 = 0;
  243. }
  244. private void GetInfo64(CpuThreadState threadState)
  245. {
  246. long stackPtr = (long)threadState.X0;
  247. uint id = (uint)threadState.X1;
  248. int handle = (int)threadState.X2;
  249. long subId = (long)threadState.X3;
  250. KernelResult result = GetInfo(id, handle, subId, out long value);
  251. threadState.X0 = (ulong)result;
  252. threadState.X1 = (ulong)value;
  253. }
  254. private KernelResult GetInfo(uint id, int handle, long subId, out long value)
  255. {
  256. value = 0;
  257. switch (id)
  258. {
  259. case 0:
  260. case 1:
  261. case 2:
  262. case 3:
  263. case 4:
  264. case 5:
  265. case 6:
  266. case 7:
  267. case 12:
  268. case 13:
  269. case 14:
  270. case 15:
  271. case 16:
  272. case 17:
  273. case 18:
  274. case 20:
  275. case 21:
  276. case 22:
  277. {
  278. if (subId != 0)
  279. {
  280. return KernelResult.InvalidCombination;
  281. }
  282. KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
  283. KProcess process = currentProcess.HandleTable.GetKProcess(handle);
  284. if (process == null)
  285. {
  286. return KernelResult.InvalidHandle;
  287. }
  288. switch (id)
  289. {
  290. case 0: value = process.Capabilities.AllowedCpuCoresMask; break;
  291. case 1: value = process.Capabilities.AllowedThreadPriosMask; break;
  292. case 2: value = (long)process.MemoryManager.AliasRegionStart; break;
  293. case 3: value = (long)(process.MemoryManager.AliasRegionEnd -
  294. process.MemoryManager.AliasRegionStart); break;
  295. case 4: value = (long)process.MemoryManager.HeapRegionStart; break;
  296. case 5: value = (long)(process.MemoryManager.HeapRegionEnd -
  297. process.MemoryManager.HeapRegionStart); break;
  298. case 6: value = (long)process.GetMemoryCapacity(); break;
  299. case 7: value = (long)process.GetMemoryUsage(); break;
  300. case 12: value = (long)process.MemoryManager.GetAddrSpaceBaseAddr(); break;
  301. case 13: value = (long)process.MemoryManager.GetAddrSpaceSize(); break;
  302. case 14: value = (long)process.MemoryManager.StackRegionStart; break;
  303. case 15: value = (long)(process.MemoryManager.StackRegionEnd -
  304. process.MemoryManager.StackRegionStart); break;
  305. case 16: value = (long)process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break;
  306. case 17:
  307. if (process.PersonalMmHeapPagesCount != 0)
  308. {
  309. value = process.MemoryManager.GetMmUsedPages() * KMemoryManager.PageSize;
  310. }
  311. break;
  312. case 18: value = process.TitleId; break;
  313. case 20: value = (long)process.UserExceptionContextAddress; break;
  314. case 21: value = (long)process.GetMemoryCapacityWithoutPersonalMmHeap(); break;
  315. case 22: value = (long)process.GetMemoryUsageWithoutPersonalMmHeap(); break;
  316. }
  317. break;
  318. }
  319. case 8:
  320. {
  321. if (handle != 0)
  322. {
  323. return KernelResult.InvalidHandle;
  324. }
  325. if (subId != 0)
  326. {
  327. return KernelResult.InvalidCombination;
  328. }
  329. value = _system.Scheduler.GetCurrentProcess().Debug ? 1 : 0;
  330. break;
  331. }
  332. case 9:
  333. {
  334. if (handle != 0)
  335. {
  336. return KernelResult.InvalidHandle;
  337. }
  338. if (subId != 0)
  339. {
  340. return KernelResult.InvalidCombination;
  341. }
  342. KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
  343. if (currentProcess.ResourceLimit != null)
  344. {
  345. KHandleTable handleTable = currentProcess.HandleTable;
  346. KResourceLimit resourceLimit = currentProcess.ResourceLimit;
  347. KernelResult result = handleTable.GenerateHandle(resourceLimit, out int resLimHandle);
  348. if (result != KernelResult.Success)
  349. {
  350. return result;
  351. }
  352. value = (uint)resLimHandle;
  353. }
  354. break;
  355. }
  356. case 10:
  357. {
  358. if (handle != 0)
  359. {
  360. return KernelResult.InvalidHandle;
  361. }
  362. int currentCore = _system.Scheduler.GetCurrentThread().CurrentCore;
  363. if (subId != -1 && subId != currentCore)
  364. {
  365. return KernelResult.InvalidCombination;
  366. }
  367. value = _system.Scheduler.CoreContexts[currentCore].TotalIdleTimeTicks;
  368. break;
  369. }
  370. case 11:
  371. {
  372. if (handle != 0)
  373. {
  374. return KernelResult.InvalidHandle;
  375. }
  376. if ((ulong)subId > 3)
  377. {
  378. return KernelResult.InvalidCombination;
  379. }
  380. KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
  381. value = currentProcess.RandomEntropy[subId];
  382. break;
  383. }
  384. case 0xf0000002u:
  385. {
  386. if (subId < -1 || subId > 3)
  387. {
  388. return KernelResult.InvalidCombination;
  389. }
  390. KThread thread = _system.Scheduler.GetCurrentProcess().HandleTable.GetKThread(handle);
  391. if (thread == null)
  392. {
  393. return KernelResult.InvalidHandle;
  394. }
  395. KThread currentThread = _system.Scheduler.GetCurrentThread();
  396. int currentCore = currentThread.CurrentCore;
  397. if (subId != -1 && subId != currentCore)
  398. {
  399. return KernelResult.Success;
  400. }
  401. KCoreContext coreContext = _system.Scheduler.CoreContexts[currentCore];
  402. long timeDelta = PerformanceCounter.ElapsedMilliseconds - coreContext.LastContextSwitchTime;
  403. if (subId != -1)
  404. {
  405. value = KTimeManager.ConvertMillisecondsToTicks(timeDelta);
  406. }
  407. else
  408. {
  409. long totalTimeRunning = thread.TotalTimeRunning;
  410. if (thread == currentThread)
  411. {
  412. totalTimeRunning += timeDelta;
  413. }
  414. value = KTimeManager.ConvertMillisecondsToTicks(totalTimeRunning);
  415. }
  416. break;
  417. }
  418. default: return KernelResult.InvalidEnumValue;
  419. }
  420. return KernelResult.Success;
  421. }
  422. private void CreateEvent64(CpuThreadState state)
  423. {
  424. KernelResult result = CreateEvent(out int wEventHandle, out int rEventHandle);
  425. state.X0 = (ulong)result;
  426. state.X1 = (ulong)wEventHandle;
  427. state.X2 = (ulong)rEventHandle;
  428. }
  429. private KernelResult CreateEvent(out int wEventHandle, out int rEventHandle)
  430. {
  431. KEvent Event = new KEvent(_system);
  432. KernelResult result = _process.HandleTable.GenerateHandle(Event.WritableEvent, out wEventHandle);
  433. if (result == KernelResult.Success)
  434. {
  435. result = _process.HandleTable.GenerateHandle(Event.ReadableEvent, out rEventHandle);
  436. if (result != KernelResult.Success)
  437. {
  438. _process.HandleTable.CloseHandle(wEventHandle);
  439. }
  440. }
  441. else
  442. {
  443. rEventHandle = 0;
  444. }
  445. return result;
  446. }
  447. private void GetProcessList64(CpuThreadState state)
  448. {
  449. ulong address = state.X1;
  450. int maxOut = (int)state.X2;
  451. KernelResult result = GetProcessList(address, maxOut, out int count);
  452. state.X0 = (ulong)result;
  453. state.X1 = (ulong)count;
  454. }
  455. private KernelResult GetProcessList(ulong address, int maxCount, out int count)
  456. {
  457. count = 0;
  458. if ((maxCount >> 28) != 0)
  459. {
  460. return KernelResult.MaximumExceeded;
  461. }
  462. if (maxCount != 0)
  463. {
  464. KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
  465. ulong copySize = (ulong)maxCount * 8;
  466. if (address + copySize <= address)
  467. {
  468. return KernelResult.InvalidMemState;
  469. }
  470. if (currentProcess.MemoryManager.OutsideAddrSpace(address, copySize))
  471. {
  472. return KernelResult.InvalidMemState;
  473. }
  474. }
  475. int copyCount = 0;
  476. lock (_system.Processes)
  477. {
  478. foreach (KProcess process in _system.Processes.Values)
  479. {
  480. if (copyCount < maxCount)
  481. {
  482. if (!KernelTransfer.KernelToUserInt64(_system, (long)address + copyCount * 8, process.Pid))
  483. {
  484. return KernelResult.UserCopyFailed;
  485. }
  486. }
  487. copyCount++;
  488. }
  489. }
  490. count = copyCount;
  491. return KernelResult.Success;
  492. }
  493. private void GetSystemInfo64(CpuThreadState state)
  494. {
  495. uint id = (uint)state.X1;
  496. int handle = (int)state.X2;
  497. long subId = (long)state.X3;
  498. KernelResult result = GetSystemInfo(id, handle, subId, out long value);
  499. state.X0 = (ulong)result;
  500. state.X1 = (ulong)value;
  501. }
  502. private KernelResult GetSystemInfo(uint id, int handle, long subId, out long value)
  503. {
  504. value = 0;
  505. if (id > 2)
  506. {
  507. return KernelResult.InvalidEnumValue;
  508. }
  509. if (handle != 0)
  510. {
  511. return KernelResult.InvalidHandle;
  512. }
  513. if (id < 2)
  514. {
  515. if ((ulong)subId > 3)
  516. {
  517. return KernelResult.InvalidCombination;
  518. }
  519. KMemoryRegionManager region = _system.MemoryRegions[subId];
  520. switch (id)
  521. {
  522. //Memory region capacity.
  523. case 0: value = (long)region.Size; break;
  524. //Memory region free space.
  525. case 1:
  526. {
  527. ulong freePagesCount = region.GetFreePages();
  528. value = (long)(freePagesCount * KMemoryManager.PageSize);
  529. break;
  530. }
  531. }
  532. }
  533. else /* if (Id == 2) */
  534. {
  535. if ((ulong)subId > 1)
  536. {
  537. return KernelResult.InvalidCombination;
  538. }
  539. switch (subId)
  540. {
  541. case 0: value = _system.PrivilegedProcessLowestId; break;
  542. case 1: value = _system.PrivilegedProcessHighestId; break;
  543. }
  544. }
  545. return KernelResult.Success;
  546. }
  547. private void CreatePort64(CpuThreadState state)
  548. {
  549. int maxSessions = (int)state.X2;
  550. bool isLight = (state.X3 & 1) != 0;
  551. long nameAddress = (long)state.X4;
  552. KernelResult result = CreatePort(
  553. maxSessions,
  554. isLight,
  555. nameAddress,
  556. out int serverPortHandle,
  557. out int clientPortHandle);
  558. state.X0 = (ulong)result;
  559. state.X1 = (ulong)serverPortHandle;
  560. state.X2 = (ulong)clientPortHandle;
  561. }
  562. private KernelResult CreatePort(
  563. int maxSessions,
  564. bool isLight,
  565. long nameAddress,
  566. out int serverPortHandle,
  567. out int clientPortHandle)
  568. {
  569. serverPortHandle = clientPortHandle = 0;
  570. if (maxSessions < 1)
  571. {
  572. return KernelResult.MaximumExceeded;
  573. }
  574. KPort port = new KPort(_system);
  575. port.Initialize(maxSessions, isLight, nameAddress);
  576. KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
  577. KernelResult result = currentProcess.HandleTable.GenerateHandle(port.ClientPort, out clientPortHandle);
  578. if (result != KernelResult.Success)
  579. {
  580. return result;
  581. }
  582. result = currentProcess.HandleTable.GenerateHandle(port.ServerPort, out serverPortHandle);
  583. if (result != KernelResult.Success)
  584. {
  585. currentProcess.HandleTable.CloseHandle(clientPortHandle);
  586. }
  587. return result;
  588. }
  589. private void ManageNamedPort64(CpuThreadState state)
  590. {
  591. long nameAddress = (long)state.X1;
  592. int maxSessions = (int)state.X2;
  593. KernelResult result = ManageNamedPort(nameAddress, maxSessions, out int handle);
  594. state.X0 = (ulong)result;
  595. state.X1 = (ulong)handle;
  596. }
  597. private KernelResult ManageNamedPort(long nameAddress, int maxSessions, out int handle)
  598. {
  599. handle = 0;
  600. if (!KernelTransfer.UserToKernelString(_system, nameAddress, 12, out string name))
  601. {
  602. return KernelResult.UserCopyFailed;
  603. }
  604. if (maxSessions < 0 || name.Length > 11)
  605. {
  606. return KernelResult.MaximumExceeded;
  607. }
  608. if (maxSessions == 0)
  609. {
  610. return KClientPort.RemoveName(_system, name);
  611. }
  612. KPort port = new KPort(_system);
  613. KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
  614. KernelResult result = currentProcess.HandleTable.GenerateHandle(port.ServerPort, out handle);
  615. if (result != KernelResult.Success)
  616. {
  617. return result;
  618. }
  619. port.Initialize(maxSessions, false, 0);
  620. result = port.SetName(name);
  621. if (result != KernelResult.Success)
  622. {
  623. currentProcess.HandleTable.CloseHandle(handle);
  624. }
  625. return result;
  626. }
  627. }
  628. }