I've submitted the rest of the review as an MR form: https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs.
1. server: Ensure that object capacity does not overflow "int". [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- Winstations are not subject to USER object count limit, and each winstation can have multiple desktops.
Explicitly guard against a faulty application that tries to create winstations and desktops indefinitely instead of crashing in a subtle failure mode (due to int overflow wraparound or negative index).
1. win32u: No longer retry until the session has enough capacity in map_shared_session_section. [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- The retry-until-capacity-logic was necessary because the shared object acquisition logic didn't check for out-of-bounds index (it checked the shared mapping ID instead.)
Now that get_thread_session_object() explicitly checks for OOB index, this is now redundant.
1. server: Remove object_capacity from session_shm_t. [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- Move it back to server session structure.
The client no longer needs this information; a conservative approximation (which is good enough) can always be inferred from the mapping size, and if the client side view is too small it will attempt to remap anyway.
1. server: Remove session_shm_t, replace with simple session_obj_t array. [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- We removed object_capacity from session_shm_t. We won't need any kind of other metadata for session mapping in the future, either.
(In case we want metadata for session *itself*, it can be its own session object type).
1. server: Ensure all newly mapped blocks are marked as "free." [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- This allows catching accidental access to unallocated object slots.
Also, this makes "never-allocated" object slots (currently zero-filled) consistent with "allocated-and-then-freed" object slots (0xFE-filled).
1. server: Make `struct object_info` a protocol type (objshm_loc_t). [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- This simplifies object info transport for future object types (queue and input).
Note that UINT64 is required so that PE and Unix agrees on its alignment consistency.
1. server: Remove object header from desktop_shm_t. [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- Make object_shm_t hold the object payload instead (replacing session_obj_t).
1. server: Compute shared object capacity independent of mapping size. [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- Also, calculate the mmap() size solely based on the object capacity, not the mapping size.
This decouples session.objects mmap size from the shared mapping size, which simplifies the case when mmap() fails and the VMA size is decoupled from the actual mapping (due to the old mmap being retained).
This prepares refactoring with simplified mmap() error handling.
1. server: Always set session mapping size even on mmap failure. [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- Prepare for grow_session_mapping() refactoring.
1. server: Factor out resize_anonymous_mapping() from grow_session_mapping(). [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- Prepare for grow_session_mapping() refactoring.
1. server: Deduplicate shared session mmap()-ing logic. [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- update_session_mapping_capacity() contains logic that set_session_mapping() and grow_session_mapping() have in common.
1. server: Make next_object_index more intuitive. [(commit)](https://gitlab.winehq.org/iamahuman/wine/-/merge_requests/15/diffs?commit_id...)
- next_object_index doesn't actually mean the next index. last_object_index actually means the last index.
While we're at it, introduce an assert() that the newly allocated index is indeed less than the (potentially just grown) capacity.
Also, make sure to keep "index < capacity" hold at all times. This not only prevents potential integer overflows that happens before modulo operation, but makes the meaning of "index" straightforward by not overloading it to mean "index plus some multiple of capacity."