Avatar of SITPL
SITPL
 asked on

Failing to get unicode text from Active Directory in ATL dll project

Hi,
I am facing an issue regarding unicode text.
In a ATL dll project I am using LDAP to get data from Active Directory. Following is the sample code.  

IDirectorySearch *pDSSearch;
ADS_SEARCH_COLUMN col;
hr = pDSSearch->SetSearchPreference(rgSearchPrefs, ARRAYSIZE(rgSearchPrefs));
hr = pDSSearch->ExecuteSearch(strFilter, pszAttr ,dwAttrNameSize, &hSearch );

if(SUCCEEDED(hr))
	{						
		switch(col.dwADsType)
		{ 
			case  ADSTYPE_DN_STRING:
			case ADSTYPE_CASE_IGNORE_STRING:
				{			
					for(size_t x=0; x<col.dwNumValues;x++)
					{
						CString name = col.pADsValues[x].CaseIgnoreString; //fails for unicode text
					}
				}
		}
	}

Open in new window


The line CString name = col.pADsValues[x].CaseIgnoreString; works fine for English text, but returns '???' for other languages. For example if the Active directory contains any user's name in Chinese or Japanese text '邮箱' then CString name shows '???' instead of the actual unicode text.
The same code works properly in another MFC Application project but fails for this ATL dll project.

Project settings are :
Configuration Type : Dynamic Library(.dll)
Use of MFC :      Use MFC in a Static Library
Use of ATL :       Static Link to ATL
Character Set :  Use Unicode Character Set

Cannot trace what I have been missing out. Please help.
* LDAPC++* UnicodeActive Directory* atl

Avatar of undefined
Last Comment
SITPL

8/22/2022 - Mon
sarabande

int wchars_num = MultiByteToWideChar( CP_UTF8 , 0 , col.pADsValues[x].CaseIgnoreString , -1, NULL , 0 );
CString wstr;
MultiByteToWideChar( CP_UTF8 , 0 ,  col.pADsValues[x].CaseIgnoreString, -1, wstr.GetBuffer(wchars_num+1) , wchars_num );
wstr.ReleaseBuffer(-1);

this code would convert from UTF-8 to UTF-16. the latter is a 16-bit layer of UTF-32 called "UNICODE" by microsoft. UTF-8 is a multi-byte character set where a UNICODE character has 1 to 4 bytes and it is mightier than UTF-16 though both cover most common characters used in the word.

Sara
sarabande

col.pADsValues[x].CaseIgnoreString

i assumed that this is a byte buffer. you may have to use an intermediate char buffer if the string you got in col.pADsValues[x].CaseIgnoreString already is converted to a wide character string buffer.

byte buffer[SOME_SIZE+1] = { 0 };
memcpy(buffer, your_byte_array, SOME_SIZE);
// this call checks how many characters are needed for the wide char string
int wchars_num = MultiByteToWideChar( CP_UTF8 , 0 , (const char *)buffer , -1, NULL , 0 );
// the next call retrieves the wide string
MultiByteToWideChar( CP_UTF8 , 0 ,  (const char *)buffer, -1, name.GetBuffer(wchars_num+1) , wchars_num);
name.ReleaseBuffer();

Open in new window


Sara
SITPL

ASKER
Sara, thanks for the suggestion. I tried with the byte buffer but it still shows junk. I am wondering why is this not working only in ATL project when it works fine in another MFC application.
Still stuck on this. Any help would be very much appreciated.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
sarabande

write the byte array you get to a file.

#include <fstream>
...
std::ofstream ofs("c:\\temp\\bytes,bin", std::ios::binary | std::ios::out);
ofs.write((const char *)bytes_arr, num_bytes);
ofs.close();

Open in new window


then open the file "with the binary editor" of visual studio.

make a picture of the contents and post it here.

additionally post the code you made to convert from utf-8 to utf-16. especially the part of the code where you determine the size of the byte array.

finally, show a picture of the error (or garbage) you got.

Sara
ASKER CERTIFIED SOLUTION
SITPL

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.