CString::Replace not working with values from registry










0















I'm trying to implement something where I need to change values in the registry where what I'm removing and what I'm adding is only decided at run time.
my test code:



CString test_string, change_from, change_to;
test_string.Format(_T("Communications Port (COM1)"));
change_from.Format(_T("COM1"));
change_to.Format(_T("COM2"));
test_string.Replace(change_from, change_to);
MessageBox(test_string, _T("Test"), MB_OK);


works as expected.



but when test_string and change_from are populated from the registry it does not.



CRegKey serenum_key;
serenum_key.Open(HKEY_LOCAL_MACHINE, _T("System\CurrentControlSet\services\Serenum\Enum"), KEY_READ);
CRegKey sysenum_key;
sysenum_key.Open(HKEY_LOCAL_MACHINE, _T("System\CurrentControlSet\Enum"), KEY_READ);
DWORD count = 0;
serenum_key.QueryDWORDValue(_T("Count"), count);

CString keyname, keypath, friendlyname, portname;
const ULONG max_len = 256;
ULONG len;
keypath.Preallocate(max_len);
friendlyname.Preallocate(max_len);
portname.Preallocate(max_len);
for (DWORD i = 0; i < count; i++)
keyname.Format(_T("%d"), i);
len = max_len;
serenum_key.QueryStringValue(keyname, keypath.GetBuffer(), &len);
CRegKey dev_key;
dev_key.Open(sysenum_key, keypath.GetBuffer(), KEY_READ);
len = max_len;
dev_key.QueryStringValue(_T("FriendlyName"), friendlyname.GetBuffer(), &len);
CRegKey devparams_key;
devparams_key.Open(dev_key, _T("Device Parameters"), KEY_READ);
len = max_len;
devparams_key.QueryStringValue(_T("PortName"), portname.GetBuffer(), &len);
ATLTRACE(friendlyname);
ATLTRACE(portname);
CString newname;
newname.Format(_T("COM%d"), 50);
ATLTRACE(newname);
friendlyname.Replace(portname, newname);
ATLTRACE(friendlyname);

devparams_key.Close();
dev_key.Close();

sysenum_key.Close();
serenum_key.Close();
}


the traces I'm getting show what I expect to see coming from the registry key, and the new name, but the friendly name remains unchanged:



Communications Port (COM1)
COM1
COM50
Communications Port (COM1)


why does Replace work in the first instance but not with the registry key values?
for note I'm working with visual studio community 2017, platform toolset v141, Unicode, x64










share|improve this question
























  • Try to step into MFC's Replace method. You'll see what happens.

    – Jabberwocky
    Nov 13 '18 at 10:24











  • still getting to grips with using a debugger, tried that and found that it was not able to see the new or old strings for replacement, I tried changing them to use GetBuffer() on those two arguments which replaced something, but unfortunately with gibberish.

    – James Kent
    Nov 13 '18 at 10:46






  • 2





    You are missing CString::ReleaseBuffer() calls, so the string length won't be set to the actual length of the strings read from the registry.

    – zett42
    Nov 13 '18 at 11:47











  • thank you. this was the hint I needed.

    – James Kent
    Nov 13 '18 at 11:58















0















I'm trying to implement something where I need to change values in the registry where what I'm removing and what I'm adding is only decided at run time.
my test code:



CString test_string, change_from, change_to;
test_string.Format(_T("Communications Port (COM1)"));
change_from.Format(_T("COM1"));
change_to.Format(_T("COM2"));
test_string.Replace(change_from, change_to);
MessageBox(test_string, _T("Test"), MB_OK);


works as expected.



but when test_string and change_from are populated from the registry it does not.



CRegKey serenum_key;
serenum_key.Open(HKEY_LOCAL_MACHINE, _T("System\CurrentControlSet\services\Serenum\Enum"), KEY_READ);
CRegKey sysenum_key;
sysenum_key.Open(HKEY_LOCAL_MACHINE, _T("System\CurrentControlSet\Enum"), KEY_READ);
DWORD count = 0;
serenum_key.QueryDWORDValue(_T("Count"), count);

CString keyname, keypath, friendlyname, portname;
const ULONG max_len = 256;
ULONG len;
keypath.Preallocate(max_len);
friendlyname.Preallocate(max_len);
portname.Preallocate(max_len);
for (DWORD i = 0; i < count; i++)
keyname.Format(_T("%d"), i);
len = max_len;
serenum_key.QueryStringValue(keyname, keypath.GetBuffer(), &len);
CRegKey dev_key;
dev_key.Open(sysenum_key, keypath.GetBuffer(), KEY_READ);
len = max_len;
dev_key.QueryStringValue(_T("FriendlyName"), friendlyname.GetBuffer(), &len);
CRegKey devparams_key;
devparams_key.Open(dev_key, _T("Device Parameters"), KEY_READ);
len = max_len;
devparams_key.QueryStringValue(_T("PortName"), portname.GetBuffer(), &len);
ATLTRACE(friendlyname);
ATLTRACE(portname);
CString newname;
newname.Format(_T("COM%d"), 50);
ATLTRACE(newname);
friendlyname.Replace(portname, newname);
ATLTRACE(friendlyname);

devparams_key.Close();
dev_key.Close();

sysenum_key.Close();
serenum_key.Close();
}


the traces I'm getting show what I expect to see coming from the registry key, and the new name, but the friendly name remains unchanged:



Communications Port (COM1)
COM1
COM50
Communications Port (COM1)


why does Replace work in the first instance but not with the registry key values?
for note I'm working with visual studio community 2017, platform toolset v141, Unicode, x64










share|improve this question
























  • Try to step into MFC's Replace method. You'll see what happens.

    – Jabberwocky
    Nov 13 '18 at 10:24











  • still getting to grips with using a debugger, tried that and found that it was not able to see the new or old strings for replacement, I tried changing them to use GetBuffer() on those two arguments which replaced something, but unfortunately with gibberish.

    – James Kent
    Nov 13 '18 at 10:46






  • 2





    You are missing CString::ReleaseBuffer() calls, so the string length won't be set to the actual length of the strings read from the registry.

    – zett42
    Nov 13 '18 at 11:47











  • thank you. this was the hint I needed.

    – James Kent
    Nov 13 '18 at 11:58













0












0








0








I'm trying to implement something where I need to change values in the registry where what I'm removing and what I'm adding is only decided at run time.
my test code:



CString test_string, change_from, change_to;
test_string.Format(_T("Communications Port (COM1)"));
change_from.Format(_T("COM1"));
change_to.Format(_T("COM2"));
test_string.Replace(change_from, change_to);
MessageBox(test_string, _T("Test"), MB_OK);


works as expected.



but when test_string and change_from are populated from the registry it does not.



CRegKey serenum_key;
serenum_key.Open(HKEY_LOCAL_MACHINE, _T("System\CurrentControlSet\services\Serenum\Enum"), KEY_READ);
CRegKey sysenum_key;
sysenum_key.Open(HKEY_LOCAL_MACHINE, _T("System\CurrentControlSet\Enum"), KEY_READ);
DWORD count = 0;
serenum_key.QueryDWORDValue(_T("Count"), count);

CString keyname, keypath, friendlyname, portname;
const ULONG max_len = 256;
ULONG len;
keypath.Preallocate(max_len);
friendlyname.Preallocate(max_len);
portname.Preallocate(max_len);
for (DWORD i = 0; i < count; i++)
keyname.Format(_T("%d"), i);
len = max_len;
serenum_key.QueryStringValue(keyname, keypath.GetBuffer(), &len);
CRegKey dev_key;
dev_key.Open(sysenum_key, keypath.GetBuffer(), KEY_READ);
len = max_len;
dev_key.QueryStringValue(_T("FriendlyName"), friendlyname.GetBuffer(), &len);
CRegKey devparams_key;
devparams_key.Open(dev_key, _T("Device Parameters"), KEY_READ);
len = max_len;
devparams_key.QueryStringValue(_T("PortName"), portname.GetBuffer(), &len);
ATLTRACE(friendlyname);
ATLTRACE(portname);
CString newname;
newname.Format(_T("COM%d"), 50);
ATLTRACE(newname);
friendlyname.Replace(portname, newname);
ATLTRACE(friendlyname);

devparams_key.Close();
dev_key.Close();

sysenum_key.Close();
serenum_key.Close();
}


the traces I'm getting show what I expect to see coming from the registry key, and the new name, but the friendly name remains unchanged:



Communications Port (COM1)
COM1
COM50
Communications Port (COM1)


why does Replace work in the first instance but not with the registry key values?
for note I'm working with visual studio community 2017, platform toolset v141, Unicode, x64










share|improve this question
















I'm trying to implement something where I need to change values in the registry where what I'm removing and what I'm adding is only decided at run time.
my test code:



CString test_string, change_from, change_to;
test_string.Format(_T("Communications Port (COM1)"));
change_from.Format(_T("COM1"));
change_to.Format(_T("COM2"));
test_string.Replace(change_from, change_to);
MessageBox(test_string, _T("Test"), MB_OK);


works as expected.



but when test_string and change_from are populated from the registry it does not.



CRegKey serenum_key;
serenum_key.Open(HKEY_LOCAL_MACHINE, _T("System\CurrentControlSet\services\Serenum\Enum"), KEY_READ);
CRegKey sysenum_key;
sysenum_key.Open(HKEY_LOCAL_MACHINE, _T("System\CurrentControlSet\Enum"), KEY_READ);
DWORD count = 0;
serenum_key.QueryDWORDValue(_T("Count"), count);

CString keyname, keypath, friendlyname, portname;
const ULONG max_len = 256;
ULONG len;
keypath.Preallocate(max_len);
friendlyname.Preallocate(max_len);
portname.Preallocate(max_len);
for (DWORD i = 0; i < count; i++)
keyname.Format(_T("%d"), i);
len = max_len;
serenum_key.QueryStringValue(keyname, keypath.GetBuffer(), &len);
CRegKey dev_key;
dev_key.Open(sysenum_key, keypath.GetBuffer(), KEY_READ);
len = max_len;
dev_key.QueryStringValue(_T("FriendlyName"), friendlyname.GetBuffer(), &len);
CRegKey devparams_key;
devparams_key.Open(dev_key, _T("Device Parameters"), KEY_READ);
len = max_len;
devparams_key.QueryStringValue(_T("PortName"), portname.GetBuffer(), &len);
ATLTRACE(friendlyname);
ATLTRACE(portname);
CString newname;
newname.Format(_T("COM%d"), 50);
ATLTRACE(newname);
friendlyname.Replace(portname, newname);
ATLTRACE(friendlyname);

devparams_key.Close();
dev_key.Close();

sysenum_key.Close();
serenum_key.Close();
}


the traces I'm getting show what I expect to see coming from the registry key, and the new name, but the friendly name remains unchanged:



Communications Port (COM1)
COM1
COM50
Communications Port (COM1)


why does Replace work in the first instance but not with the registry key values?
for note I'm working with visual studio community 2017, platform toolset v141, Unicode, x64







visual-c++ mfc






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 10:25









Jabberwocky

26.6k93770




26.6k93770










asked Nov 13 '18 at 10:03









James KentJames Kent

3,715831




3,715831












  • Try to step into MFC's Replace method. You'll see what happens.

    – Jabberwocky
    Nov 13 '18 at 10:24











  • still getting to grips with using a debugger, tried that and found that it was not able to see the new or old strings for replacement, I tried changing them to use GetBuffer() on those two arguments which replaced something, but unfortunately with gibberish.

    – James Kent
    Nov 13 '18 at 10:46






  • 2





    You are missing CString::ReleaseBuffer() calls, so the string length won't be set to the actual length of the strings read from the registry.

    – zett42
    Nov 13 '18 at 11:47











  • thank you. this was the hint I needed.

    – James Kent
    Nov 13 '18 at 11:58

















  • Try to step into MFC's Replace method. You'll see what happens.

    – Jabberwocky
    Nov 13 '18 at 10:24











  • still getting to grips with using a debugger, tried that and found that it was not able to see the new or old strings for replacement, I tried changing them to use GetBuffer() on those two arguments which replaced something, but unfortunately with gibberish.

    – James Kent
    Nov 13 '18 at 10:46






  • 2





    You are missing CString::ReleaseBuffer() calls, so the string length won't be set to the actual length of the strings read from the registry.

    – zett42
    Nov 13 '18 at 11:47











  • thank you. this was the hint I needed.

    – James Kent
    Nov 13 '18 at 11:58
















Try to step into MFC's Replace method. You'll see what happens.

– Jabberwocky
Nov 13 '18 at 10:24





Try to step into MFC's Replace method. You'll see what happens.

– Jabberwocky
Nov 13 '18 at 10:24













still getting to grips with using a debugger, tried that and found that it was not able to see the new or old strings for replacement, I tried changing them to use GetBuffer() on those two arguments which replaced something, but unfortunately with gibberish.

– James Kent
Nov 13 '18 at 10:46





still getting to grips with using a debugger, tried that and found that it was not able to see the new or old strings for replacement, I tried changing them to use GetBuffer() on those two arguments which replaced something, but unfortunately with gibberish.

– James Kent
Nov 13 '18 at 10:46




2




2





You are missing CString::ReleaseBuffer() calls, so the string length won't be set to the actual length of the strings read from the registry.

– zett42
Nov 13 '18 at 11:47





You are missing CString::ReleaseBuffer() calls, so the string length won't be set to the actual length of the strings read from the registry.

– zett42
Nov 13 '18 at 11:47













thank you. this was the hint I needed.

– James Kent
Nov 13 '18 at 11:58





thank you. this was the hint I needed.

– James Kent
Nov 13 '18 at 11:58












1 Answer
1






active

oldest

votes


















3














The documentation on CString::GetBuffer explains, how to use this class member:




If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before you use any other CSimpleStringT member methods.




If you don't, the internal state of the CString object is not valid. The GetBuffer/ReleaseBuffer family of class members are useful, when you need to attach non-CString string data to CString instances. The former temporarily disable class invariants, where the latter re-establishes them, so they always need to be called in tandem.






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53278437%2fcstringreplace-not-working-with-values-from-registry%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    The documentation on CString::GetBuffer explains, how to use this class member:




    If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before you use any other CSimpleStringT member methods.




    If you don't, the internal state of the CString object is not valid. The GetBuffer/ReleaseBuffer family of class members are useful, when you need to attach non-CString string data to CString instances. The former temporarily disable class invariants, where the latter re-establishes them, so they always need to be called in tandem.






    share|improve this answer



























      3














      The documentation on CString::GetBuffer explains, how to use this class member:




      If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before you use any other CSimpleStringT member methods.




      If you don't, the internal state of the CString object is not valid. The GetBuffer/ReleaseBuffer family of class members are useful, when you need to attach non-CString string data to CString instances. The former temporarily disable class invariants, where the latter re-establishes them, so they always need to be called in tandem.






      share|improve this answer

























        3












        3








        3







        The documentation on CString::GetBuffer explains, how to use this class member:




        If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before you use any other CSimpleStringT member methods.




        If you don't, the internal state of the CString object is not valid. The GetBuffer/ReleaseBuffer family of class members are useful, when you need to attach non-CString string data to CString instances. The former temporarily disable class invariants, where the latter re-establishes them, so they always need to be called in tandem.






        share|improve this answer













        The documentation on CString::GetBuffer explains, how to use this class member:




        If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before you use any other CSimpleStringT member methods.




        If you don't, the internal state of the CString object is not valid. The GetBuffer/ReleaseBuffer family of class members are useful, when you need to attach non-CString string data to CString instances. The former temporarily disable class invariants, where the latter re-establishes them, so they always need to be called in tandem.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 13 '18 at 12:29









        IInspectableIInspectable

        26k54396




        26k54396



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53278437%2fcstringreplace-not-working-with-values-from-registry%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Barbados

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3