[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

whats up with RegConnectRegistry()?

Posted on 2010-11-30
13
Medium Priority
?
1,074 Views
Last Modified: 2012-05-10
Hi Folks,

I am making a dll that is a plugin to coldfusion application server (cfx)  - it is supposed to permit access to windows registry on a remote computer, and most of it works just fine.  All if, actually, except for the remote computer part!

According to the documentation:
     http://msdn.microsoft.com/en-us/library/ms724840%28VS.85%29.aspx

I just need to pass a LPCTSTR containing the address of the remote server, and it should return a registry handle to the requested collection.

Here are the relevant code snippets:

            LPCSTR lpszServer = pRequest->GetAttribute("SERVER");

GetAttribute() is provided by the application server framework and just returns a pointer to a char string or null if the attribute was not defined in the user script.

I write it back to the user, so that I can be sure that my code is getting the right data:

      ResultText.Format("Writing key \"%s\\%s\" to server %s", lpszBranch, lpszEntry, lpszServer);
      pRequest->Write( ResultText ) ;

(lpzBranch and lpszEntry are just strings I have collected in the same way as lpszServer)

So far, I can confirm that the dll is receiving a server name in the correct forma, displaying it back to the user script as something like "\\server.domain.com"

then later I use the server name to call RegConnect:

      if(RegConnectRegistry(
                  lpszServer, // LPTSTR lpMachineName, // address of name of remote computer
                   RootKey,      // HKEY hKey, // predefined registry handle
                  &RegKey            // PHKEY phkResult // address of buffer for remote registry handle
                   ) == ERROR_SUCCESS)
      {
      // do stuff
      }
      else
      {
      // throw error
      }

The problem is that when I pass the data I got from that GetAttribute function, the function returns zero (success) and executes 'do stuff' which is to write a string value to the registry of the local system - even though I know that the server name field is populated.

The annoying thing is that the behaviour is exactly like what I would expect if the value of lpszServer = null, that is it just opens the localhost registry and 'does work' on that!  I don't think that this problem is permissions or access related, because if that was the case then RegConnectRegistry should return != ERROR_SUCCESS and so execute "throw error" code instead of "do stuff" code.

I suspect that this may have something to do with trying to pass an LPCSTR into a field that expects LPCTSTR, but exactly what the deal is, or how I should do the right conversion has eluded me thus far....

Any suggestions, tips, comments... even solutions(!)... will be most appreciated!

Thanks and regards,  Mike.
0
Comment
Question by:meverest
  • 5
  • 3
  • 2
10 Comments
 
LVL 45

Accepted Solution

by:
AndyAinscow earned 1000 total points
ID: 34238348
LPCSTR is a pointer to a 'narrow' char string
LPCTSTR is a pointer to EITHER a 'narrow' or a 'wide' (UNICODE) string depending on your project settings.

If you do need to convert from wide to narrow chars then look at wcstombs in the help files - there is example code there.
0
 
LVL 37

Author Comment

by:meverest
ID: 34238450
Thanks Andy,

I've been down that path already, but it was screwing my mind and I didn't understand it fully :-}

So I tried changing 'character set' in 'general' category of the project settings to "use unicode" but that causes a whole bunch of compile time errors about non matching string types.

So I change 'character set' to "use multibyte" and I can compile again, so I guess that my LPCSTR is multibyte - so is that narrow or wide, and does it mean I need a wcstombs conversion?

(actually, should it be mbstowcs maybe? I have a LPCSTR and I want to make it into LPCTSTR)

Cheers!
0
 
LVL 45

Assisted Solution

by:AndyAinscow
AndyAinscow earned 1000 total points
ID: 34238511
multibyte means that LPCSTR == LPCTSTR, you should be able to put the mouse onto LPCTSTR and go to the definition
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 37

Author Comment

by:meverest
ID: 34238573
umm yeah, so it is:  typedef LPCSTR LPCTSTR

OK, that helps, but doesn't help much ;-j

Then by my expectation, that RegConnectRegistry call should only do one of two things - it should either connect to the registry on the remote server, as specified by the value contained in lpszServer, OR it should return some value != ERROR_SUCCESS and so 'throw error'

As far as I can tell, it should /never/ 'do stuff' on the local registry at all :-(

Any suggestions on how I can figure out what is really going on?
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 34238638
Not really, network type stuff is really out of my mainstream area
At least one potential cause is now eliminated so it is progress of a sort.
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 1000 total points
ID: 34239698
Here's some sample code taken from 'production code' that reads connection information from a remote registry, maybe that helps a bit:
BOOL LicClntReadRemoteReg (   LPCTSTR         pszServer,  
                              PIRLICRPCCTRL   prpcCtrl
                          )
{
    BOOL        bRC =   TRUE;

    HKEY        hRemoteHKLM;
    HKEY        hKey;
    LONG        lnResult;

    LPCTSTR     pszKey  =   "Software\\Company\\Product\\LicenseServer";

    char    acBuffer    [   1024];

    DWORD   dwType  =   REG_SZ;
    DWORD   dwSize  =   1024;

    char    acServer    [   MAX_COMPUTERNAME_LENGTH + 2];

    //  check UNC naming convention
    if  (       '\\'    ==  *pszServer
            &&  '\\'    ==  *( pszServer + 1)
        )
        {
            lstrcpy (   acServer,   pszServer);
        }
     else
        {
            wsprintf(   acServer,   "\\\\%s",   pszServer);
        }

    DBG1 (   "RegConnectRegistry(), server = %s\n",  acServer);

    if  (   ERROR_SUCCESS   !=  (   lnResult    =   RegConnectRegistry  (   acServer,
                                                                            HKEY_LOCAL_MACHINE,
                                                                            &hRemoteHKLM
                                                                        )
                                )
        )
        {
            DBG1 (   "RegConnectRegistry() failed, reason == %d\n",  lnResult);
            return  (   FALSE);
        }

    if  (   ERROR_SUCCESS   !=  RegOpenKeyEx    (   hRemoteHKLM,
                                                    pszKey,
                                                    0,
                                                    KEY_READ,
                                                    &hKey
                                                )
        )
        {
            RegCloseKey (   hRemoteHKLM);

            return  (   FALSE);
        }

    if  (   ERROR_SUCCESS   !=  RegQueryValueEx (   hKey,
                                                    "ProtSeq",
                                                    0,
                                                    &dwType,
                                                    ( LPBYTE) acBuffer,
                                                    &dwSize
                                                )
        )
        {
            bRC =   FALSE;
        }
     else
        {
            prpcCtrl->pszProtseq    =   new unsigned char   [ dwSize + 1];

            lstrcpy (   ( char*) prpcCtrl->pszProtseq,  acBuffer);
        }

    if  (   ERROR_SUCCESS   !=  RegQueryValueEx (   hKey,
                                                    "NetworkAddress",
                                                    0,
                                                    &dwType,
                                                    ( LPBYTE) acBuffer,
                                                    &dwSize
                                                )
        )
        {
            bRC =   FALSE;
        }
     else
        {
            prpcCtrl->pszNetworkAddress =   new unsigned char   [ dwSize + 1];

            lstrcpy (   ( char*) prpcCtrl->pszNetworkAddress,   acBuffer);
        }

    if  (   ERROR_SUCCESS   !=  RegQueryValueEx (   hKey,
                                                    "Endpoint",
                                                    0,
                                                    &dwType,
                                                    ( LPBYTE) acBuffer,
                                                    &dwSize
                                                )
        )
        {
            bRC =   FALSE;
        }
     else
        {
            prpcCtrl->pszEndpoint   =   new unsigned char   [ dwSize + 1];

            lstrcpy (   ( char*) prpcCtrl->pszEndpoint, acBuffer);
        }

    dwType  =   REG_DWORD;
    dwSize  =   sizeof  (   DWORD);
    if  (   ERROR_SUCCESS   !=  RegQueryValueEx (   hKey,
                                                    "PingInterval",
                                                    0,
                                                    &dwType,
                                                    ( LPBYTE) &prpcCtrl->ulPingInterval,
                                                    &dwSize
                                                )
        )
        {
            prpcCtrl->ulPingInterval    =   5000;
        }

    RegCloseKey (   hKey);
    RegCloseKey (   hRemoteHKLM);

    return  (   bRC);
}

Open in new window

0
 
LVL 37

Author Comment

by:meverest
ID: 34252411
Thanks Andy, your comments have been most helpful :-)

Thanks jkr!  My own code is very similar - the only difference is that your method provides char[] to the RegConnectRegistry() function.  I thought I'd try doing a similar thing, but that caused the entire application server service to crash! :-o

Well, that's a big enough change for me to call it 'progress' of a sort, so I'll play with that for a bit and see if I can make it work! ;-)

Cheers.
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 1000 total points
ID: 34425990
I'm not sure why you'd like to delete this one, I posted a full working example on how to use that API, so I'd tend to object.
0
 
LVL 37

Author Comment

by:meverest
ID: 34426063
Hello - I'm sorry for letting this one slide for too long.  Please give me a few more days to get back on to it - I promise to close it off properly within a week! :-}
0
 
LVL 37

Author Comment

by:meverest
ID: 34448261
OK,

I haven't really found any workable slution (yet) but comments provided by AndyAinscow are most helpful, thank you.

Thanks too jkr for providing a code sample, but it is largely similar to the code I am already using.

I'll close this question now, and maybe come back with further question/s when I get back to this project.

Cheers.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
What do responsible coders do? They don't take detrimental shortcuts. They do take reasonable security precautions, create important automation, implement sufficient logging, fix things they break, and care about users.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question