"Nikolay Sivov" bunglehead@gmail.com wrote:
+UINT WINAPI GetRoleTextA(DWORD role, LPSTR lpRole, UINT rolemax) +{
- UINT length;
- WCHAR *roletextW;
- CHAR *roletextA;
- TRACE("%u %p %u\n", role, lpRole, rolemax);
- length = GetRoleTextW(role, NULL, 0);
- if(length == 0)
return 0;
- roletextW = HeapAlloc(GetProcessHeap(), 0, (length + 1)*sizeof(WCHAR));
- if(!roletextW)
return 0;
- GetRoleTextW(role, roletextW, length + 1);
- length = WideCharToMultiByte( CP_ACP, 0, roletextW, -1, NULL, 0, NULL, NULL );
- if(!lpRole){
HeapFree(GetProcessHeap(), 0, roletextW);
return length - 1;
- }
- roletextA = HeapAlloc(GetProcessHeap(), 0, length);
- WideCharToMultiByte( CP_ACP, 0, roletextW, -1, roletextA, length, NULL, NULL );
- if(rolemax < length)
length = rolemax;
- memcpy(lpRole, roletextA, length);
- lpRole[length-1] = '\0';
- HeapFree(GetProcessHeap(), 0, roletextA);
- HeapFree(GetProcessHeap(), 0, roletextW);
- return length - 1;
+}
Why do you need to allocate an intermediate roletextA?
Dmitry Timoshkov wrote:
"Nikolay Sivov" bunglehead@gmail.com wrote:
+UINT WINAPI GetRoleTextA(DWORD role, LPSTR lpRole, UINT rolemax) +{
- UINT length;
- WCHAR *roletextW;
- CHAR *roletextA;
- TRACE("%u %p %u\n", role, lpRole, rolemax);
- length = GetRoleTextW(role, NULL, 0);
- if(length == 0)
return 0;
- roletextW = HeapAlloc(GetProcessHeap(), 0, (length +
1)*sizeof(WCHAR));
- if(!roletextW)
return 0;
- GetRoleTextW(role, roletextW, length + 1);
- length = WideCharToMultiByte( CP_ACP, 0, roletextW, -1, NULL, 0,
NULL, NULL );
- if(!lpRole){
HeapFree(GetProcessHeap(), 0, roletextW);
return length - 1;
- }
- roletextA = HeapAlloc(GetProcessHeap(), 0, length);
- WideCharToMultiByte( CP_ACP, 0, roletextW, -1, roletextA,
length, NULL, NULL );
- if(rolemax < length)
length = rolemax;
- memcpy(lpRole, roletextA, length);
- lpRole[length-1] = '\0';
- HeapFree(GetProcessHeap(), 0, roletextA);
- HeapFree(GetProcessHeap(), 0, roletextW);
- return length - 1;
+}
Why do you need to allocate an intermediate roletextA?
WideCharToMultiByte requires to have a sufficient buffer. I think it's the easiest way to allocate necessary buffer instead of using local buffer of some hardcoded length. What do you think?
"Nikolay Sivov" bunglehead@gmail.com wrote:
Why do you need to allocate an intermediate roletextA?
WideCharToMultiByte requires to have a sufficient buffer. I think it's the easiest way to allocate necessary buffer instead of using local buffer of some hardcoded length. What do you think?
And what is the problem with WideCharToMultiByte?
Dmitry Timoshkov wrote:
"Nikolay Sivov" bunglehead@gmail.com wrote:
Why do you need to allocate an intermediate roletextA?
WideCharToMultiByte requires to have a sufficient buffer. I think it's the easiest way to allocate necessary buffer instead of using local buffer of some hardcoded length. What do you think?
And what is the problem with WideCharToMultiByte?
No problems with it. The reason is that I couldn't use rolemax as an WideCharToMultiByte argument cause it could be less then required buffer. After that I don't want to use something like CHAR buff[64] because of unexplainable length, so I allocate it in heap. Why it's wrong?
"Nikolay Sivov" bunglehead@gmail.com wrote:
Why do you need to allocate an intermediate roletextA?
WideCharToMultiByte requires to have a sufficient buffer. I think it's the easiest way to allocate necessary buffer instead of using local buffer of some hardcoded length. What do you think?
And what is the problem with WideCharToMultiByte?
No problems with it. The reason is that I couldn't use rolemax as an WideCharToMultiByte argument cause it could be less then required buffer. After that I don't want to use something like CHAR buff[64] because of unexplainable length, so I allocate it in heap. Why it's wrong?
I still fail to see why you can't use rolemax in WideCharToMultiByte, obviously that's the size of the target buffer.
Dmitry Timoshkov wrote:
"Nikolay Sivov" bunglehead@gmail.com wrote:
Why do you need to allocate an intermediate roletextA?
WideCharToMultiByte requires to have a sufficient buffer. I think it's the easiest way to allocate necessary buffer instead of using local buffer of some hardcoded length. What do you think?
And what is the problem with WideCharToMultiByte?
No problems with it. The reason is that I couldn't use rolemax as an WideCharToMultiByte argument cause it could be less then required buffer. After that I don't want to use something like CHAR buff[64] because of unexplainable length, so I allocate it in heap. Why it's wrong?
I still fail to see why you can't use rolemax in WideCharToMultiByte, obviously that's the size of the target buffer.
The thought that WideCharToMultiByte will not fill buffer of insufficient length, that's where I was wrong. I've just posted a corrected patch. Any feedback will be appreciated.
"Nikolay Sivov" bunglehead@gmail.com wrote:
The thought that WideCharToMultiByte will not fill buffer of insufficient length, that's where I was wrong. I've just posted a corrected patch. Any feedback will be appreciated.
After looking at your patch I don't see much difference with what LoadStringA/W already do. Why don't you use those directly?
Dmitry Timoshkov wrote:
"Nikolay Sivov" bunglehead@gmail.com wrote:
The thought that WideCharToMultiByte will not fill buffer of insufficient length, that's where I was wrong. I've just posted a corrected patch. Any feedback will be appreciated.
After looking at your patch I don't see much difference with what LoadStringA/W already do. Why don't you use those directly?
LoadStringA doesn't return necessary buffer length when called with (buflen = 0) but LoadStringW does. Since I need to return a necessary buffer length from both GetRoleText[A/W] I used LoadStringW in both cases, converting to multibyte in ansi call.
P.S. Is there any documented RT_STRING max length? If it's I could use a local buffer of this length for GetRoleTextA
"Nikolay Sivov" bunglehead@gmail.com wrote:
LoadStringA doesn't return necessary buffer length when called with (buflen = 0) but LoadStringW does. Since I need to return a necessary buffer length from both GetRoleText[A/W] I used LoadStringW in both cases, converting to multibyte in ansi call.
I don't see in your tests that GetRoleText is supposed to return the string length when it's called with buffer length set to 0.
P.S. Is there any documented RT_STRING max length? If it's I could use a local buffer of this length for GetRoleTextA
I'm not aware of such a documentation. The only way to prove/find something is write a test case.
Dmitry Timoshkov wrote:
"Nikolay Sivov" bunglehead@gmail.com wrote:
LoadStringA doesn't return necessary buffer length when called with (buflen = 0) but LoadStringW does. Since I need to return a necessary buffer length from both GetRoleText[A/W] I used LoadStringW in both cases, converting to multibyte in ansi call.
I don't see in your tests that GetRoleText is supposed to return the string length when it's called with buffer length set to 0.
GetRoleText supposed to return string length when buffer is NULL. Cause there's no way to get this length by LoadStringA *without* passing a not-NULL pointer to buffer (I don't now how long should it be) so I used LoadStringW for ansi call too.
"Nikolay Sivov" bunglehead@gmail.com wrote:
LoadStringA doesn't return necessary buffer length when called with (buflen = 0) but LoadStringW does. Since I need to return a necessary buffer length from both GetRoleText[A/W] I used LoadStringW in both cases, converting to multibyte in ansi call.
I don't see in your tests that GetRoleText is supposed to return the string length when it's called with buffer length set to 0.
GetRoleText supposed to return string length when buffer is NULL. Cause there's no way to get this length by LoadStringA *without* passing a not-NULL pointer to buffer (I don't now how long should it be) so I used LoadStringW for ansi call too.
Again, I don't see in your tests that GetRoleText is supposed to return the string length when it's called with buffer length set to 0.
Dmitry Timoshkov wrote:
"Nikolay Sivov" bunglehead@gmail.com wrote:
LoadStringA doesn't return necessary buffer length when called with (buflen = 0) but LoadStringW does. Since I need to return a necessary buffer length from both GetRoleText[A/W] I used LoadStringW in both cases, converting to multibyte in ansi call.
I don't see in your tests that GetRoleText is supposed to return the string length when it's called with buffer length set to 0.
GetRoleText supposed to return string length when buffer is NULL. Cause there's no way to get this length by LoadStringA *without* passing a not-NULL pointer to buffer (I don't now how long should it be) so I used LoadStringW for ansi call too.
Again, I don't see in your tests that GetRoleText is supposed to return the string length when it's called with buffer length set to 0.
I've made these tests but I still don't follow you: - GetRoleTextW returns length when called with NULL buffer (and zero or not-zero buflen) - GetRoleTextA returns length only when called with NULL buffer. On zero buflen it returns 0.
As I understood you want to use LoadStringA in GetRoleTextA and remove all wide->mb conversions. But:
there are 3 last lines of LoadStringA: --- buffer[retval] = 0; TRACE("returning %s\n", debugstr_a(buffer)); return retval; --- It's the only place when length is returned. So it will always write to buffer => I can't get a length with it without writing. And it doesn't matter that GetRoleTextA returns 0 on buflen = 0 cause behavior on NULL buffer still different between LoadStringA (will crash) and LoadStringW (will return length).
"Nikolay Sivov" bunglehead@gmail.com wrote:
I've made these tests but I still don't follow you:
- GetRoleTextW returns length when called with NULL buffer (and zero or
not-zero buflen)
I don't see such a test.
- GetRoleTextA returns length only when called with NULL buffer. On zero
buflen it returns 0.
There is no such a test either.