Skip to content

kernel32: add the lstr* string API family#141

Open
Luminger wants to merge 1 commit into
decompals:mainfrom
Luminger:pr-lstr-family
Open

kernel32: add the lstr* string API family#141
Luminger wants to merge 1 commit into
decompals:mainfrom
Luminger:pr-lstr-family

Conversation

@Luminger

@Luminger Luminger commented Jul 17, 2026

Copy link
Copy Markdown

Adds the legacy lstr{cpy,cat,len,cmp,cmpi}{A,W} + lstrcpynW family to kernel32 (lstrcpynA already exists since #124 and is kept as-is).

Why

wibo's own embedded msvcrt40 (the encounter/winedll build, WIBO_ENABLE_WINE_DLLS) imports this family from kernel32. Hosting MSVC 4.x's cl.exe currently stops at the first missing lstr* import inside c1.exe:

wibo: call reached missing import lstrcpyW from KERNEL32.dll

With this patch, clean cl.exe + link.exe + nmake.exe pipelines (MSVC 4.00 and 4.20, the mid-90s toolchains used by several matching-decompilation projects) run end-to-end under wibo and produce output byte-identical to the equivalent Wine-hosted builds.

Behaviour notes

  • lstrcpyn copies up to iMaxLength-1 chars and ALWAYS writes a terminating nul (unlike strncpy); iMaxLength is treated as unsigned per Windows' historical behaviour.
  • lstrcmp(i) returns -1/0/+1 (not strcmp's arbitrary delta). Windows defers to CompareString with the thread locale; a byte-wise compare is used here since the consumers exercised (cl/link/nmake/msvcrt) only feed ASCII.
  • The documented access-violation behaviour (SetLastError + return 0) is emulated only for the NULL case — wibo has no SEH dispatcher, so other bad pointers fault the guest as on real Windows.

Testing

  • full test suite green (48/48, includes upstream's test_lstrcpyn)
  • MSVC 4.00/4.20 cl.exe/link.exe/nmake.exe end-to-end; compile output byte-identical to Wine-hosted reference builds across a 40-TU corpus

Adds the legacy lstr{cpy,cat,len,cmp,cmpi}{A,W} + lstrcpynW functions
to kernel32, declared in dll/kernel32/winbase.h with implementations in
dll/kernel32/winbase.cpp.  (lstrcpynA already exists since decompals#124 and is
kept as-is.)

These are a documented Win32 1.x / Win95-era surface that wibo does not
yet cover, and wibo's own embedded msvcrt40 (the encounter/winedll
build, WIBO_ENABLE_WINE_DLLS) imports the family from kernel32: hosting
MSVC 4.x's cl.exe stops at the first missing lstr* import inside c1.exe
without them.  With this patch a clean cl.exe + link.exe + nmake.exe
pipeline (MSVC 4.00 and 4.20) runs end-to-end and produces output
byte-identical to the equivalent Wine-hosted build.

Behavioural notes:
* lstrcpyn copies up to iMaxLength-1 chars and ALWAYS writes a
  terminating nul, unlike strncpy.  iMaxLength is declared int but is
  treated as unsigned per Windows' historical behaviour.
* lstrcmp(i) returns -1 / 0 / +1 (not strcmp's arbitrary delta).  The
  official implementation defers to CompareString with the thread
  locale; a byte-wise compare is used here because the consumers
  exercised (cl.exe, link.exe, nmake.exe, msvcrt) only feed ASCII.
* Access-violation behaviour (SetLastError + return 0) is emulated only
  for the obvious NULL case -- wibo has no SEH dispatcher, so arbitrary
  bad pointers fault the guest as they would on a real Windows.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant