Discussion:
Problem with double byte
(too old to reply)
s***@gmail.com
2007-12-03 08:14:11 UTC
Permalink
Hi All,

The following sample code works well on single byte languages and
prints the list of running processes in the box. But on double byte
languages like chinese, korean etc, it doesn't print the full process
name and it prints partially on a process which have space in the
process name.

// TestApp.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE 1
#endif
#define tmain wmain
#else
#define tmain main
#endif



#include <windows.h>
#include <winperf.h>
#include <malloc.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <stdlib.h>


int tmain ()
{
PDH_STATUS pdhStatus = ERROR_SUCCESS;
LPTSTR szCounterListBuffer = NULL;
DWORD dwCounterListSize = 0;
LPTSTR szInstanceListBuffer = NULL;
DWORD dwInstanceListSize = 0;
LPCSTR szThisInstance = NULL;




// Determine the required buffer size for the data.
pdhStatus = PdhEnumObjectItems (
NULL, // real time source
NULL, // local machine
TEXT("Process"), // object to enumerate
szCounterListBuffer, // pass NULL and 0
&dwCounterListSize, // to get length required
szInstanceListBuffer, // buffer size
&dwInstanceListSize, //
PERF_DETAIL_WIZARD, // counter detail level
0);

if (pdhStatus == PDH_MORE_DATA || pdhStatus == ERROR_SUCCESS)
{
// Allocate the buffers and try the call again.
szCounterListBuffer = (LPTSTR)malloc (
(dwCounterListSize * sizeof (TCHAR)));
szInstanceListBuffer = (LPTSTR)malloc (
(dwInstanceListSize * sizeof (TCHAR)));

if ((szCounterListBuffer != NULL) &&
(szInstanceListBuffer != NULL))
{
pdhStatus = PdhEnumObjectItems (
NULL, // real time source
NULL, // local machine
TEXT("Process"), // object to enumerate
szCounterListBuffer, // buffer to receive counter
list
&dwCounterListSize,
szInstanceListBuffer, // buffer to receive instance
list
&dwInstanceListSize,
PERF_DETAIL_WIZARD, // counter detail level
0);

if (pdhStatus == ERROR_SUCCESS)
{
_tprintf (TEXT("\nEnumerating Processes:"));

// Walk the instance list. The list can contain one
// or more null-terminated strings. The last string
// is followed by a second null-terminator.
szThisInstance = szInstanceListBuffer;
while(*szThisInstance)
{
_tprintf(TEXT("\n%s"),szThisInstance);
szThisInstance = szThisInstance + _tcslen(szThisInstance) *
sizeof(TCHAR);
szThisInstance = _tcsinc(szThisInstance);
}


}
else
{
_tprintf(TEXT("\nPdhEnumObjectItems failed1 with
%ld."), pdhStatus);
}
}
else
{
_tprintf (TEXT("\nUnable to allocate buffers"));
pdhStatus = ERROR_OUTOFMEMORY;
}

if (szCounterListBuffer != NULL)
free (szCounterListBuffer);

if (szInstanceListBuffer != NULL)
free (szInstanceListBuffer);
}
else
{

//_tprintf(TEXT("\nPdhEnumObjectItems failed2 with %ld."),
pdhStatus);
}

return pdhStatus;
}


Please help me to solve the issue.
Mihai N.
2007-12-04 02:57:39 UTC
Permalink
Fixes the thing:
in the while(*szThisInstance) loop change
szThisInstance = szThisInstance + _tcslen(szThisInstance) * sizeof(TCHAR);
to
szThisInstance = szThisInstance + _tcslen(szThisInstance);

When you add a number to a pointer, the number is automatically multiplied
with the size of the type.


Other things that you might cleanup:
- Build your project with UNICODE defined
- Usually you define both UNICODE and _UNICODE
http://www.mihai-nita.net/article.php?artID=20060723a
Defining _UNICODE before including stdafx.h, because stuff
declared in stdafx.h might be affected
- No need for tmain, just include <tchar.h> and use _tmain.
- Change szThisInstance to LPCTSTR
--
Mihai Nita [Microsoft MVP, Windows - SDK]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email
s***@gmail.com
2007-12-04 04:52:04 UTC
Permalink
Hi

Thanks for your reply.

Changed the settings and code as you said. The modified code is given
below

// TestApp.cpp : Defines the entry point for the console application.
//


#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE 1
#endif

#include "stdafx.h"
#include <windows.h>
#include <winperf.h>
#include <malloc.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <stdlib.h>



int _tmain()
{
PDH_STATUS pdhStatus = ERROR_SUCCESS;
LPTSTR szCounterListBuffer = NULL;
DWORD dwCounterListSize = 0;
LPTSTR szInstanceListBuffer = NULL;
DWORD dwInstanceListSize = 0;
LPCTSTR szThisInstance = NULL;




// Determine the required buffer size for the data.
pdhStatus = PdhEnumObjectItems (
NULL, // real time source
NULL, // local machine
TEXT("Process"), // object to enumerate
szCounterListBuffer, // pass NULL and 0
&dwCounterListSize, // to get length required
szInstanceListBuffer, // buffer size
&dwInstanceListSize, //
PERF_DETAIL_WIZARD, // counter detail level
0);

if (pdhStatus == PDH_MORE_DATA || pdhStatus == ERROR_SUCCESS)
{
// Allocate the buffers and try the call again.
szCounterListBuffer = (LPTSTR)malloc (
(dwCounterListSize * sizeof (TCHAR)));
szInstanceListBuffer = (LPTSTR)malloc (
(dwInstanceListSize * sizeof (TCHAR)));

if ((szCounterListBuffer != NULL) &&
(szInstanceListBuffer != NULL))
{
pdhStatus = PdhEnumObjectItems (
NULL, // real time source
NULL, // local machine
TEXT("Process"), // object to enumerate
szCounterListBuffer, // buffer to receive counter
list
&dwCounterListSize,
szInstanceListBuffer, // buffer to receive instance
list
&dwInstanceListSize,
PERF_DETAIL_WIZARD, // counter detail level
0);

if (pdhStatus == ERROR_SUCCESS)
{

_tprintf (TEXT("\nEnumerating Processes:"));

// Walk the instance list. The list can contain one
// or more null-terminated strings. The last string
// is followed by a second null-terminator.
szThisInstance = szInstanceListBuffer;
while(*szThisInstance)
{
_tprintf(TEXT("\n%s"),szThisInstance);
szThisInstance = szThisInstance + _tcslen(szThisInstance);
szThisInstance = _tcsinc(szThisInstance);
}

}
else
{
_tprintf(TEXT("\nPdhEnumObjectItems failed1 with
%ld."), pdhStatus);
}
}
else
{
_tprintf (TEXT("\nUnable to allocate buffers"));
pdhStatus = ERROR_OUTOFMEMORY;
}

if (szCounterListBuffer != NULL)
free (szCounterListBuffer);

if (szInstanceListBuffer != NULL)
free (szInstanceListBuffer);
}
else
{

//_tprintf(TEXT("\nPdhEnumObjectItems failed2 with %ld."),
pdhStatus);
}

return pdhStatus;
}


My project settings under "all configurations" is given below

_UNICODE,UNICODE,WIN32,_CONSOLE

The code compiles and links successfully. But i'm not able to see the
korean process names in the output. Instead, a empty line is coming.

Please help me to solve the issue.
Post by Mihai N.
in the while(*szThisInstance) loop change
szThisInstance = szThisInstance + _tcslen(szThisInstance) * sizeof(TCHAR);
to
szThisInstance = szThisInstance + _tcslen(szThisInstance);
When you add a number to a pointer, the number is automatically multiplied
with the size of the type.
- Build your project with UNICODE defined
- Usually you define both UNICODE and _UNICODE
http://www.mihai-nita.net/article.php?artID=20060723a
Defining _UNICODE before including stdafx.h, because stuff
declared in stdafx.h might be affected
- No need for tmain, just include <tchar.h> and use _tmain.
- Change szThisInstance to LPCTSTR
--
Mihai Nita [Microsoft MVP, Windows - SDK]http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email
Mihai N.
2007-12-04 06:47:50 UTC
Permalink
Post by s***@gmail.com
The code compiles and links successfully. But i'm not able to see the
korean process names in the output. Instead, a empty line is coming.
Is the system code page set to Korean, or just the process name is Korean?
Because the console cannot display all the languages you throw at it,
even if the application is Unicode. It is just a dumb console.

Try replacing
_tprintf(TEXT("\n%s"),szThisInstance);
with
MessageBox( NULL, szThisInstance, TEXT("Test"), MB_OK );
If the string in the message box looks ok, then that is the problem.

And there is no real solution.
You just can't display all strings in the console.
Still, Korean will work on a Korean system, Japanese on a Japanese system,
and so on.
--
Mihai Nita [Microsoft MVP, Windows - SDK]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email
Loading...