http://bugs.winehq.org/show_bug.cgi?id=824
--- Comment #11 from Michal Piaskowski piaskal+wine@gmail.com 2008-01-04 18:04:55 --- Created an attachment (id=10039) --> (http://bugs.winehq.org/attachment.cgi?id=10039) Change the way REG_MULTI_SZ is saved
As it have been said already the problem is that wine stores REG_MULTI_SZ as null terminated string and sometimes looses information about data length. Without this information wine can't tell if the original string was null terminated or not.
To make things more complicated Windows XP (as well as wine) whenever RegSetValueEx( HKEY hkey, LPCSTR name, DWORD reserved, DWORD type, CONST BYTE *data, DWORD count ) is called with data pointing to a string which isn't null terminated system will check if data[count] is null. If it is then it will assume that the user forgot about the ending /0 and will save count+1 bytes, but if data[count] isn't null it will save only count bytes.
I have tested following calls on windows xp and wine:
RegSetValueEx(myKey,"321\0 len=4",0,REG_MULTI_SZ,(const BYTE *)"321",4); RegSetValueEx(myKey,"321\0 len=3",0,REG_MULTI_SZ,(const BYTE *)"321",3); RegSetValueEx(myKey,"321\0 len=2",0,REG_MULTI_SZ,(const BYTE *)"321",2); RegSetValueEx(myKey,"321\0 len=1",0,REG_MULTI_SZ,(const BYTE *)"321",1); RegSetValueEx(myKey,"321\0 len=0",0,REG_MULTI_SZ,(const BYTE *)"321",0);
This is the result of exporting these keys on Windows XP
"321\0 len=4"=hex(7):33,00,32,00,31,00,00,00 "321\0 len=3"=hex(7):33,00,32,00,31,00,00,00 "321\0 len=2"=hex(7):33,00,32,00 "321\0 len=1"=hex(7):33,00 "321\0 len=0"=hex(7):
This is how wine stores it in ~/.wine/user.reg
"321\0 len=0"=str(7):"" "321\0 len=1"=str(7):"3" "321\0 len=2"=str(7):"32" "321\0 len=3"=str(7):"321" "321\0 len=4"=str(7):"321"
And this is how wine exports it:
"321\0 len=0"=hex(7):00
"321\0 len=1"=hex(7):33,00
"321\0 len=2"=hex(7):33,32,00
"321\0 len=3"=hex(7):33,32,31,00
"321\0 len=4"=hex(7):33,32,31,00
I made a simple patch that changes the way wine stores REG_MULTI_SZ from str(7) to hex(7).
After applying that patch Wine stores those values as:
"321\0 len=0"=hex(7): "321\0 len=1"=hex(7):33,00 "321\0 len=2"=hex(7):33,00,32,00 "321\0 len=3"=hex(7):33,00,32,00,31,00,00,00 "321\0 len=4"=hex(7):33,00,32,00,31,00,00,00
And regedit exports it this way:
"321\0 len=0"=hex(7):
"321\0 len=1"=hex(7):33
"321\0 len=2"=hex(7):33,32
"321\0 len=3"=hex(7):33,32,31,00
"321\0 len=4"=hex(7):33,32,31,00