Author: dchapyshev
Date: Thu Jan 8 13:47:29 2009
New Revision: 38652
URL:
http://svn.reactos.org/svn/reactos?rev=38652&view=rev
Log:
- Add Wine implementation LoadStringA/W. This is fixed all wine tests for LoadString
Modified:
trunk/reactos/dll/win32/user32/misc/resources.c
Modified: trunk/reactos/dll/win32/user32/misc/resources.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/reso…
==============================================================================
--- trunk/reactos/dll/win32/user32/misc/resources.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/misc/resources.c [iso-8859-1] Thu Jan 8 13:47:29 2009
@@ -20,223 +20,85 @@
static HINSTANCE hSetupApi = NULL;
-BOOL
-WINAPI
-_InternalLoadString(HINSTANCE hInstance,
- UINT uID,
- PUNICODE_STRING pwstrDest)
-{
- HRSRC hrsStringTable;
- HGLOBAL hResource;
- PWCHAR pStringTable;
- unsigned i;
- unsigned l = uID % 16; /* (1) */
-
- /* parameter validation */
- if (IsBadWritePtr(pwstrDest, sizeof(UNICODE_STRING)))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- /*
- find the string table. String tables are created by grouping, 16 by 16, string
- resources whose identifiers, divided by 16, have the same integer quotient.
- Holes in the numbering are filled with zero-length strings. String table ids
- (actual resource ids) start from 1. See (1) and (2)
- */
- /* TODO: some sort of cache, here, would be great */
- hrsStringTable = FindResourceW((HMODULE)hInstance,
- MAKEINTRESOURCEW((uID / 16) + 1), /* (2) */
- RT_STRING);
-
- /* failure */
- if (hrsStringTable == NULL) return FALSE;
-
- /* load the string table into memory */
- hResource = LoadResource((HMODULE)hInstance, hrsStringTable);
-
- /* failure */
- if (hResource == NULL) return FALSE;
-
- /* lock the resource into memory */
- pStringTable = LockResource(hResource);
-
- /* failure */
- if (pStringTable == NULL) return FALSE;
-
- /*
- string tables are packed Unicode Pascal strings. The first WCHAR contains the
- length, in characters, of the current string. Zero-length strings, if any, are
- placeholders for unused slots, and should therefore be considered non-present.
- See also (3). Here, we walk all the strings before that of interest
- */
- for(i = 0; i < l; ++ i)
- {
- /* skip the length and the current string */
- pStringTable += 1 + (*pStringTable);
- }
-
- /* we've reached the string of interest */
- if ((*pStringTable) == 0)
- {
- /* the string is empty (unallocated) */
- SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
- return FALSE; /* 3 */
- }
-
- /* string length in bytes */
- pwstrDest->Length = pwstrDest->MaximumLength = (*pStringTable) *
sizeof(WCHAR);
-
- /* string */
- pwstrDest->Buffer = pStringTable + 1;
-
- /* success */
- return TRUE;
-}
-
-
-/*
- * @implemented
+
+/*
+ * @implemented (Synced with Wine 08.01.2009)
*/
int
WINAPI
-LoadStringA(HINSTANCE hInstance,
- UINT uID,
- LPSTR lpBuffer,
- int nBufferMax)
-{
- UNICODE_STRING wstrResStr;
- ANSI_STRING strBuf;
- INT retSize;
-
- /* parameter validation */
-
- if (nBufferMax < 1)
- {
- return -1;
- }
-
- if (IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0])))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
+LoadStringA(HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen)
+{
+ HGLOBAL hmem;
+ HRSRC hrsrc;
+ DWORD retval = 0;
+
+ if (!buflen) return -1;
+
+ /* Use loword (incremented by 1) as resourceid */
+ if ((hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >>
4) + 1),
+ (LPWSTR)RT_STRING )) &&
+ (hmem = LoadResource( instance, hrsrc )))
+ {
+ const WCHAR *p = LockResource(hmem);
+ unsigned int id = resource_id & 0x000f;
+
+ while (id--) p += *p + 1;
+
+ RtlUnicodeToMultiByteN( buffer, buflen - 1, &retval, (PWSTR)(p + 1), *p *
sizeof(WCHAR) );
+ }
+ buffer[retval] = 0;
+ return retval;
+}
+
+
+/*
+ * @implemented (Synced with Wine 08.01.2009)
+ */
+int
+WINAPI
+LoadStringW(HINSTANCE instance, UINT resource_id, LPWSTR buffer, INT buflen)
+{
+ HGLOBAL hmem;
+ HRSRC hrsrc;
+ WCHAR *p;
+ int string_num;
+ int i;
+
+ if(buffer == NULL)
return 0;
- }
-
- /* get the UNICODE_STRING descriptor of the in-memory image of the string */
- if (!_InternalLoadString(hInstance, uID, &wstrResStr))
- {
- /* failure */
+
+ /* Use loword (incremented by 1) as resourceid */
+ hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) +
1),
+ (LPWSTR)RT_STRING );
+ if (!hrsrc) return 0;
+ hmem = LoadResource( instance, hrsrc );
+ if (!hmem) return 0;
+
+ p = LockResource(hmem);
+ string_num = resource_id & 0x000f;
+ for (i = 0; i < string_num; i++)
+ p += *p + 1;
+
+ /*if buflen == 0, then return a read-only pointer to the resource itself in buffer
+ it is assumed that buffer is actually a (LPWSTR *) */
+ if(buflen == 0)
+ {
+ *((LPWSTR *)buffer) = p + 1;
+ return *p;
+ }
+
+ i = min(buflen - 1, *p);
+ if (i > 0) {
+ memcpy(buffer, p + 1, i * sizeof (WCHAR));
+ buffer[i] = 0;
+ } else {
+ if (buflen > 1) {
+ buffer[0] = 0;
return 0;
}
-
- /*
- convert the string. The Unicode string may be in UTF-16 (multi-byte), so we
- don't alter wstrResStr.Length, and let RtlUnicodeStringToAnsiString truncate
- it, if necessary
- */
- strBuf.Length = 0;
- strBuf.MaximumLength = nBufferMax * sizeof(CHAR);
- strBuf.Buffer = lpBuffer;
-
- retSize = WideCharToMultiByte(CP_ACP,
- 0,
- wstrResStr.Buffer,
- wstrResStr.Length / sizeof(WCHAR),
- strBuf.Buffer,
- strBuf.MaximumLength,
- NULL,
- NULL);
-
- if (!retSize)
- {
- /* failure */
- return 0;
- }
- else
- {
- strBuf.Length = retSize;
- }
-
- /* the ANSI string may not be null-terminated */
- if (strBuf.Length >= strBuf.MaximumLength)
- {
- /* length greater than the buffer? whatever */
- int nStringLen = strBuf.MaximumLength / sizeof(CHAR) - 1;
-
- /* zero the last character in the buffer */
- strBuf.Buffer[nStringLen] = 0;
-
- /* success */
- return nStringLen;
- }
- else
- {
- /* zero the last character in the string */
- strBuf.Buffer[strBuf.Length / sizeof(CHAR)] = 0;
-
- /* success */
- return strBuf.Length / sizeof(CHAR);
- }
-}
-
-
-/*
- * @implemented
- */
-int
-WINAPI
-LoadStringW(HINSTANCE hInstance,
- UINT uID,
- LPWSTR lpBuffer,
- int nBufferMax)
-{
- UNICODE_STRING wstrResStr;
- int nStringLen;
-
- /* parameter validation */
- if ((nBufferMax < 0) || (lpBuffer == NULL) ||
- ((nBufferMax > 0) && IsBadWritePtr(lpBuffer, nBufferMax *
sizeof(lpBuffer[0]))) ||
- /* undocumented: If nBufferMax is 0, LoadStringW will copy a pointer to the
- in-memory image of the string to the specified buffer and return the length
- of the string in WCHARs */
- ((nBufferMax == 0) && IsBadWritePtr(lpBuffer, sizeof(lpBuffer))))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- /* get the UNICODE_STRING descriptor of the in-memory image of the string */
- if (!_InternalLoadString(hInstance, uID, &wstrResStr))
- {
- /* failure */
- return 0;
- }
-
- /* get the length in characters */
- nStringLen = wstrResStr.Length / sizeof(WCHAR);
-
- if (nBufferMax > 0)
- {
- /* the buffer must be enough to contain the string and the null terminator */
- if (nBufferMax < (nStringLen + 1))
- {
- /* otherwise, the string is truncated */
- nStringLen = nBufferMax - 1;
- }
-
- /* copy the string */
- memcpy(lpBuffer, wstrResStr.Buffer, nStringLen * sizeof(WCHAR));
-
- /* null-terminate it */
- lpBuffer[nStringLen] = 0;
- }
- else
- {
- *((LPWSTR*)lpBuffer) = wstrResStr.Buffer;
- }
- /* success */
- return nStringLen;
+ }
+
+ return i;
}