[ros-diffs] [tkreuzer] 26929: undocumented behavior of LoadStringW: 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.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Fri Jun 8 17:28:25 CEST 2007


Author: tkreuzer
Date: Mon May 28 04:35:55 2007
New Revision: 26929

URL: http://svn.reactos.org/svn/reactos?rev=26929&view=rev
Log:
undocumented behavior of LoadStringW: 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.

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/resources.c?rev=26929&r1=26928&r2=26929&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/misc/resources.c (original)
+++ trunk/reactos/dll/win32/user32/misc/resources.c Mon May 28 04:35:55 2007
@@ -98,63 +98,71 @@
  int nBufferMax
 )
 {
- UNICODE_STRING wstrResStr;
- ANSI_STRING strBuf;
- INT retSize;
-
- /* parameter validation */
- if
- (
-  (nBufferMax < 1) ||
-  (IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0])))
- )
- {
-  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;
-
- /*
-  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);
- }
+  UNICODE_STRING wstrResStr;
+  ANSI_STRING strBuf;
+  INT retSize;
+
+  /* parameter validation */
+  if
+  (
+    (nBufferMax < 1) ||
+    (IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0])))
+  )
+  {
+    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;
+  }
+
+  /*
+   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);
+  }
 }
 
 
@@ -169,41 +177,55 @@
  int nBufferMax
 )
 {
- UNICODE_STRING wstrResStr;
- int nStringLen;
-
- /* parameter validation */
- if
- (
-  (nBufferMax < 1) ||
-  (IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0])))
- )
- {
-  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);
-
- /* 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;
-
- /* success */
- return nStringLen;
+  UNICODE_STRING wstrResStr;
+  int nStringLen;
+
+  /* parameter validation */
+  if
+  (
+    (nBufferMax < 1) ||
+    ((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;
 }
 
 /* EOF */




More information about the Ros-diffs mailing list