Link to home
Start Free TrialLog in
Avatar of yarabati
yarabatiFlag for India

asked on

PWSTR Comparision fails!

Hi there,

Please excuse me if I am so silly asking in this question, I am a Java guy and newbie to this CPP stuff.

I am facing some problem when I do compare two PWSTR variables, please see the code:

Sample Output received with below code:
pszValidUser=TESTUSER1
pCred->pszUserName=TESTUSER1

even if both are same, validation says it's not equal...

Types defined:
pCred->userName: PWSTR_WLX_CLIENT_CREDENTIALS_INFO::pszUserName
PWSTR pszValidUser = (PWSTR)(LocalLock(LocalAlloc(LHND,userName.Length + 2)));
memcpy(pszValidUser,userName.Buffer, userName.Length);
pszValidUser[ (userName.Length / 2) ] = 0;
 
SysMessage(Event,"SUCCESS","pszValidUser:%S, with old user:%S",                             pszValidUser, pCred->pszUserName);
 
if (wcsicmp(pszValidUser, pCred->pszUserName)== 0)
        {
             SysMessage(Event,"SUCCESS","Match user %S\\%S with %S  at Client %s .",
                                pCred->pszDomain,
                                pCred->pszUserName,
                                pszValidUser,
                                szClientAddress);             
        }
        else
        {
           SysMessage(FatalError,"EXCEPTION","Client %s mismatch for user %S\\%S with %S.",
                                szClientAddress,
                                pCred->pszDomain,
                                pCred->pszUserName,
                                pszValidUser);
		    return FALSE;
        }

Open in new window

Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

>> PWSTR pszValidUser = (PWSTR)(LocalLock(LocalAlloc(LHND,userName.Length + 2)
Since LocalAlloc allocates bytes and userName.length is (I'm guessing) the number of wide chars in the username shouldn't this actually be...

PWSTR pszValidUser = (PWSTR)(LocalLock(LocalAlloc(LHND,userName.Length * sizeof(wchar_t) + sizeof(wchar_t))

...?

Same issue for memcpy(pszValidUser,userName.Buffer, userName.Length); since memcpy copies bytes

Also, why don't you copy use wcsncpy?
http://msdn.microsoft.com/en-us/library/xdsywd25(VS.80).aspx

wcsncpy(pszValidUser,userName.Buffer, userName.Length);

Avatar of yarabati

ASKER

Thanks a lot for the reply:

 if (wcsicmp(pszValidUser, pCred->pszUserName)== 0)
        {
             SysMessage(Event,"SUCCESS","Security alert: Match user %S\\%S with %S  at Client %s .",
                                pCred->pszDomain,
                                pCred->pszUserName,
                                pszValidUser,
                                szClientAddress);            
        }
        else
        {
           SysMessage(FatalError,"EXCEPTION","Security alert: Client %s mismatch for user %S\\%S with %S.",
                                szClientAddress,
                                pCred->pszDomain,
                                pCred->pszUserName,
                                pszValidUser);
                return FALSE;
        }

for below condition:
Security alert: Client <clientmachine>mismatch for user \domain1\VIAADMIN(THIS IS OLD VARIABLE) with VIAADMIN (NEW VARIABLE WHICH WE CREATED). More information is available at <link removed>


And before comparision, in the logs:

Comparing new user:VIAADMIN, with old user: domain1\VIAADMIN More information is available at <LINK>


I clearly see that new variable is not with the domain appended...

Sorry, I see variables are matching.. both contains same value say, VIAADMIN in above...


Can you please help me with if condition block?
>> Can you please help me with if condition block?
I'm sorry but I don't follow what you're asking for help with.
Code:  if (wcsicmp(pszValidUser, pCred->pszUserName)== 0)

Both variables contain same value but this condition is failing and executing code under else block.
I don't know I am I doing correct or not, can you see is this the correct way to compare each other.

Any other option to check both are equal??
>> is this the correct way to compare each other.
Yes, that is correct.

How do you know they are identical? Have you tried looking at them both in the debugger? Often, when I've looked into these types of problem it's usually there is a very subtle difference (does one of them contain an embedded null maybe?). Also, try looking at the memory both of the pointers point to (again in the debugger).

Also, did you make the changes I suggested? The original code you posted is not really correct and as such might be the cause of your problem. Can you make those changes, test and if still an issue try looking using the debugger. If you still can't get it to work please post all the code, verbatim, back here for review.
Thanks a lot for swift responses.

I have added your code, please see the code:

And Output I received is :

Comparing new user:VIAADMIN, with old user:domain1\VIAADMIN More information is available at <SOME LINK>

Security alert: Client LOANER2-LHR2 mismatch for user \domain1\VIAADMIN with VIAADMIN. More information is available at <SOME LINK>


You are right, both variables are not identical. But we copied it in right way, confused :(



		PWSTR pszValidUser = (PWSTR)(LocalLock(LocalAlloc(LHND,userName.Length * sizeof(wchar_t) + sizeof(wchar_t))));
		wcsncpy(pszValidUser,userName.Buffer, userName.Length);
        pszValidUser[ (userName.Length / 2) ] = 0;
 
		SysMessage(Event,"SUCCESS","Comparing new user:%S, with old user:%S",
                                pszValidUser,
								pCred->pszUserName);
 
        if (wcsicmp(pszValidUser, pCred->pszUserName)== 0)
        {
             SysMessage(Event,"SUCCESS","Security alert: Match user %S\\%S with %S  at Client %s .",
                                pCred->pszDomain,
                                pCred->pszUserName,
                                pszValidUser,
                                szClientAddress);             
        }
        else
        {
           SysMessage(FatalError,"EXCEPTION","Security alert: Client %s mismatch for user %S\\%S with %S.",
                                szClientAddress,
                                pCred->pszDomain,
                                pCred->pszUserName,
                                pszValidUser);
		    return FALSE;
        }

Open in new window

>>>> you are right, both variables are not identical. But we copied it in right way, confused :(

    pszValidUser[ (userName.Length / 2) ] = 0;

That stament is wrong. It should be

     pszValidUser[userName.Length] = 0;

Or better do

  wcscpy(pszValidUser,userName.Buffer);

what would copy the binary zero at end of string.



BTW, why do you need a copy of the wide string? The userName obviously is a string class type. So you can do


     if (userName == pszUserName)
     {
         ...



If I change code to:      pszValidUser[userName.Length] = 0;
I am getting value as - VIAADMINVIAADMIN :(


For below Code:
            PWSTR pszValidUser = (PWSTR)(LocalLock(LocalAlloc(LHND,userName.Length * sizeof(wchar_t) + sizeof(wchar_t))));
            wcsncpy(pszValidUser,userName.Buffer, userName.Length);
        pszValidUser[ (userName.Length / 2) ] = 0;

            PWSTR tmpDomain = (PWSTR)(LocalLock(LocalAlloc(LHND,domainName.Length + 2)));
            memcpy(tmpDomain,domainName.Buffer, domainName.Length);
            tmpDomain[ (domainName.Length / 2) ] = 0


I will get two variables pszValidUser & tmpDomain with their user names and domain names.
I would like to append tmpDomain value infront of pszValidUser.

Say if pszValidUser=shashi and tmpDomain=mydomain

I need newUser=mydomain\shashi, any help from you?
Re:
BTW, why do you need a copy of the wide string? The userName obviously is a string class type. So you can do


     if (userName == pszUserName)
     {
         ...

pszUserName - It contains some user name before one function runs. We know even this returns same user name.
After that function runs we will get new user name. Then we will override pszUserName with new user name.
We want to check whether the function returned user name is same as pszUserName. If not throw error.

So, here what I am doing is Iam taking the new user name to another variable pszValidUser and checking with it's old value before do overriding...


Any help from any one, for below question?

For below Code:

            PWSTR pszValidUser = (PWSTR)(LocalLock(LocalAlloc(LHND,userName.Length * sizeof(wchar_t) + sizeof(wchar_t))));
            wcsncpy(pszValidUser,userName.Buffer, userName.Length);
        pszValidUser[ (userName.Length / 2) ] = 0;

            PWSTR tmpDomain = (PWSTR)(LocalLock(LocalAlloc(LHND,domainName.Length + 2)));
            memcpy(tmpDomain,domainName.Buffer, domainName.Length);
            tmpDomain[ (domainName.Length / 2) ] = 0


I will get two variables pszValidUser & tmpDomain with their user names and domain names.
I would like to append tmpDomain value infront of pszValidUser.

Say if pszValidUser=shashi and tmpDomain=mydomain

I need newUser=mydomain\shashi, any help from you?
ASKER CERTIFIED SOLUTION
Avatar of itsmeandnobodyelse
itsmeandnobodyelse
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
BTW, what string class is the username and domainName?

If it has a substring function you may do all things I did using the original string class. That isn't a vote against wstring class but only a vote to keep things simple as long as there are no invincible restrictions.
I am sorry for slight delay in getting back to you:

I have below variable declared and used:
PAE_UNICODE_STRING userName;

I want to have that to be converted to PWSTR, so that comparison& validation work makes easy to me?
Any ideas?

Here is the declaration:

typedef struct _PAE_UNICODE_STRING {
            USHORT Length;
            USHORT MaximumLength;
            [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
      } PAE_UNICODE_STRING;

The Buffer member of the structure PAE_UNICODE_STRING is a PWSTR. No conversion necessary. You best use a wstring as a temporary as I showed in the aabove code.
Thanks itsmeannobodyelse.

I tried with below source code:

wstring prevUser = userName.Buffer;
            int le = (int)prevUser.length() ;
            prevUser = prevUser.substr(0, le/2);
            PWSTR prevUserPWSTR = new wchar_t[prevUser.size()+1];

Tried printing the value prevUserPWSTR, but see in the output as nothing means no string inside :(

Any help?

I am really sorry guys, if I sound so silly. I am completely newbie to this C++ stuff. I have bit understanding from academic background, but as you know that's not worthy in real time...

I would really appreciate your help from here, and many thanks for that!
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks a lot itsmeannobody else....

Finally it got resolved now... thanks a lot for your help!
Points well earned I think Alex :)