rogerwux

Password tmpPassword;

CString strVolumePassword = "123456";

// for simplicity

/* Transfer CString into char* */
strcpy_s((char *)tmpPassword.Text, sizeof(tmpPassword.Text), strVolumePassword);

// Where the problem comes from no matter how large I allocated... Strange!!!
Converted2UNICODE((char *)tmpPassword.Text);
tmpPassword.Length = strlen(strVolumePassword);

/* Password struct */

typedef struct
{
int Length;
unsigned char Text[33];
} Password;

/* Converted2UNICODE */

void Converted2UNICODE(char *lpszText)
{
int j = strlen(lpszText);
if(j == 0)
{
//wcscpy((LPWSTR) lpszText,(LPWSTR) WIDE (""));
wcscpy_s((LPWSTR) lpszText,sizeof(lpszText), (LPWSTR) WIDE (""));
return;
}
else
{
LPWSTR lpszNewText = (LPWSTR)ErrorMalloc((j + 1) * 2);
j = MultiByteToWideChar(CP_ACP, 0L, lpszText, -1, lpszNewText, j + 1);
if (j > 0)
wcscpy_s((LPWSTR)lpszText, sizeof(lpszText), lpszNewText);
else
wcscpy_s((LPWSTR)lpszText, sizeof(lpszText), (LPWSTR)"");

free(lpszNewText);
}
}

Any thoughts thank you




Re: Visual C++ General No matter how large I allocated there is always be "Buffer is too small && 0" WHY ???

Chris Csernica

I notice you're using C syntax when you define your struct. In C++ you don't need to declare it in a typedef. So you can write:

struct Password {

int Length;

unsigned char Text[33];

}

Password tmpPassword;

and you should be fine.

I'm fairly new to MS's C++ myself, but it may be worth remembering that a CString isn't really a C-style string but a class. For using RTL functions though, you really want a pointer to a string. So try something like:

strcpy_s( tmpPassword.Text, sizeof(tmpPassword.Text), strVolumePassword.GetString() );

(cast as appropriate)

I understand this is probably just an over-simplified example to illustrate the problem, but if it's representative of your real code, I have to point out that you're not really using any OOP features here. If, for example, Password had a constructor where you could pass in char* and it would convert to Unicode at that point, possibly storing both the original and converted in member variables so that either could be retrieved -- or just the Unicode if you know that's all you're going to want. (Remember the only differences between classes and structs in VC++ is that members are private by default in classes and public in structs.)





Re: Visual C++ General No matter how large I allocated there is always be "Buffer is too small && 0" WHY ???

Giovanni Dicanio (C++ MVP)

Hi,

I don't very well understand what your conversion code does; it seems to me a bit confused and not correct, IMHO...

However, are you sure that you want to store your passwords in ANSI strings

The fact that you use char's to store strings, makes me think that you want to store strings in ANSI format.

I would very much prefer storing strings in Unicode format (so you can also store characters of cultures like the ones of the Far East, etc.).

But, OK, I assume that you want password strings to be ANSI.

CString strings can store both ANSI or Unicode strings (CString is based on TCHAR, and TCHAR can be defined as CHAR [for ANSI] or WCHAR [for Unicode], based on _UNICODE and UNICODE preprocessor #defines).

If you want to convert from CString to ANSI, you might use the ATL conversion helper class CT2A; the name may seem a bit strange, but it is built with the following (good) logic:

1. C = Conversion helper

2. T = generic TCHAR (source string), OK for CString

3. 2 = "to"

4. A = ANSI (destination string format)

So, you can use code like this to convert from CString to ANSI strings:

Code Snippet

// Original CString

// (use _T() decoration to program Unicode-aware)

CString strPassword = _T("123456");

// Convert to ANSI

CT2A ansiPassword( strPassword );

You can use ansiPassword wherever an ANSI string (const char *) is required.

As for your Password structure, you should update its definition, choosing 'char' (and not 'unsigned char') as tha base character to store the ANSI string.

The following code should work for you:

Code Snippet

#define WIN32_LEAN_AND_MEAN

#include <Windows.h>

#include <tchar.h>

#include <strsafe.h>

#include <atlbase.h>

#include <atlstr.h>

struct Password

{

int Length;

char Text[33]; // char, not unsigned char

};

// Convert a CString to Password structure

void CStringToPassword(

const CString & str, // input

Password & pwd // output

)

{

// Convert string to ANSI format (char *)

CT2A ansiPassword( str );

// Copy ANSI string to Password structure field

StringCbCopyA(

pwd.Text,

sizeof(pwd.Text),

ansiPassword

);

// Store length

pwd.Length = strlen( pwd.Text );

}

void Test()

{

// Input password string (use _T() for Unicode-awareness)

CString strVolumePassword = _T("123456");

Password password;

CStringToPassword( strVolumePassword, password );

// Now can use "password"

// ...

Again, I would very much like using Unicode strings and not ANSI strings (note that modern programming languages like C#, Java, Python, etc. use Unicode to store their strings!).

Giovanni





Re: Visual C++ General No matter how large I allocated there is always be "Buffer is too small && 0" WHY ???

rogerwu

Giovanni Dicanio (C++ MVP) wrote:

Hi,

I don't very well understand what your conversion code does; it seems to me a bit confused and not correct, IMHO...

However, are you sure that you want to store your passwords in ANSI strings

The fact that you use char's to store strings, makes me think that you want to store strings in ANSI format.

I would very much prefer storing strings in Unicode format (so you can also store characters of cultures like the ones of the Far East, etc.).

But, OK, I assume that you want password strings to be ANSI.

CString strings can store both ANSI or Unicode strings (CString is based on TCHAR, and TCHAR can be defined as CHAR [for ANSI] or WCHAR [for Unicode], based on _UNICODE and UNICODE preprocessor #defines).

If you want to convert from CString to ANSI, you might use the ATL conversion helper class CT2A; the name may seem a bit strange, but it is built with the following (good) logic:

1. C = Conversion helper

2. T = generic TCHAR (source string), OK for CString

3. 2 = "to"

4. A = ANSI (destination string format)

So, you can use code like this to convert from CString to ANSI strings:

You can use ansiPassword wherever an ANSI string (const char *) is required.

As for your Password structure, you should update its definition, choosing 'char' (and not 'unsigned char') as tha base character to store the ANSI string.

Again, I would very much like using Unicode strings and not ANSI strings (note that modern programming languages like C#, Java, Python, etc. use Unicode to store their strings!).

Giovanni

Thank you so much for your advice and details explanation, it DOES solve my problem and I am

appricated for your effort.

Actually I agree with you that it is better to us Unicode but here the exercise I am doing is using

ANSI, think in the future I will use Unicode instead, thank you again.

RogerSmile






Re: Visual C++ General No matter how large I allocated there is always be "Buffer is too small && 0" WHY ???

Giovanni Dicanio (C++ MVP)

You're welcome

Giovanni