Of course, it does not replace the string - you get a pointer to the string in which your caller has a value. You replace only the value of your "local variable" (parameter), it does not change anything on the caller’s side.
If you want to change the value on the source pointer (and make sure that you really want it, that’s where the lurk "strange errors" are - it’s very easy to overwrite surrounding variables, forget about the null terminator, etc.), you can use Marshal.Copy , eg:
var bytes = Encoding.Unicode.GetBytes("your string\0"); Marshal.Copy(bytes, 0, lpData, bytes.Length);
Again, this is a very dangerous behavior, and you should not do this. You are breaking several contracts, implied by passing parameters, etc.
Now that I have answered your question, let me talk about how you are mistaken, what you really need to do (and this is very related to your other message about using StringBuilder).
You are trying to change the value passed to you as a parameter. However, the line was highlighted by the caller. You don’t even know how long it takes! If you start copying data to this pointer, you will overwrite the data, for example. completely different variables that were just randomly distributed right after the line. This is considered "very bad."
Instead, you should follow the correct process that RegQueryValueEx has ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms724911(v=vs.85).aspx ). This means that you first need to check the value of lpcbData. If it is large enough to hold all the bytes you want to write, you simply write the data to lpData and set the lpcbData value to the desired length. If not, you install lpcbData anyway, but return ERROR_MORE_DATA. Then the caller must call RegQueryValueEx again with a large buffer.
An example code would be something like this:
string yourString = "Your string"; int RegQueryValueExW_Hooked( IntPtr hKey, string lpValueName, int lpReserved, ref Microsoft.Win32.RegistryValueKind lpType, IntPtr lpData, ref int lpcbData) { var byteCount = Encoding.Unicode.GetByteCount(yourString); if (byteCount > lpcbData) { lpcbData = byteCount; return ERROR_MORE_DATA; } if (lpData == IntPtr.Zero) { return ERROR_SUCCESS; } lpcbData = byteCount; var bytes = Encoding.Unicode.GetBytes(yourString); Marshal.Copy(bytes, 0, lpData, bytes.Length); return ERROR_SUCCESS; }
Please note that this is exactly what I wrote, quickly looking through the documentation - you should continue to research and make sure that you handle all possible cases .. NET does not protect you in this case, you can cause serious problems!