The problem is that dwUserNameLen contains the length of the string, including the terminating null terminator. Therefore, when you do:
SetLength(sUserName, dwUserNameLen);
this causes sUserName be set to 'Kobus#0' . At some point, you pass this to the Windows API dialog function, which treats this string as a string with a terminating zero and truncates the string on a random null terminator.
So you fix it like this:
SetLength(sUserName, dwUserNameLen-1);
Note that you should also check the return value of GetUserName if the call fails:
if not GetUserName(PChar(sUserName), dwUserNameLen) then RaiseLastOSError;
or a pretty clear option:
Win32Check(GetUserName(PChar(sUserName), dwUserNameLen));
One last moment. This is the wrong way to get the roaming data folder. For starters, you accept all sorts of implementation details. Your approach will not work on older versions of Windows that use different name patterns. Or in a future version of Windows. Or current versions that were configured differently.
The correct way to do this is to ask the system where the data folder of the roaming application is located. Do this using CSIDL_APPDATA (for older versions of Windows) or FOLDERID_RoamingAppData (for modern versions of Windows).
source share