Commit in reactos on MAIN
include/rosrtl/string.h+26-11.2 -> 1.3
lib/rosrtl/makefile+3-21.12 -> 1.13
lib/rosrtl/string/resstr.c+225added 1.1
+254-3
1 added + 2 modified, total 3 files
Added a few helper functions for easier usage of strings in resources

reactos/include/rosrtl
string.h 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- string.h	15 Feb 2004 01:08:54 -0000	1.2
+++ string.h	10 Aug 2004 10:57:54 -0000	1.3
@@ -1,4 +1,4 @@
-/* $Id: string.h,v 1.2 2004/02/15 01:08:54 arty Exp $
+/* $Id: string.h,v 1.3 2004/08/10 10:57:54 weiden Exp $
  */
 
 #ifndef ROSRTL_STRING_H__
@@ -46,6 +46,31 @@
 				       PUNICODE_STRING Second,
 				       BOOL Deallocate );
 
+int
+RosLenOfStrResource(HINSTANCE hInst, UINT uID);
+int
+RosAllocAndLoadStringA(LPSTR *lpTarget, HINSTANCE hInst, UINT uID);
+int
+RosAllocAndLoadStringW(LPWSTR *lpTarget, HINSTANCE hInst, UINT uID);
+DWORD
+RosFormatStrA(LPSTR *lpTarget, LPSTR lpFormat, ...);
+DWORD
+RosFormatStrW(LPWSTR *lpTarget, LPWSTR lpFormat, ...);
+DWORD
+RosLoadAndFormatStrA(HINSTANCE hInst, UINT uID, LPSTR *lpTarget, ...);
+DWORD
+RosLoadAndFormatStrW(HINSTANCE hInst, UINT uID, LPWSTR *lpTarget, ...);
+
+#ifdef UNICODE
+# define RosFmtString RosFmtStringW
+# define RosAllocAndLoadString RosAllocAndLoadStringW
+# define RosLoadAndFormatStr RosLoadAndFormatStrW
+#else
+# define RosFmtString RosFmtStringA
+# define RosAllocAndLoadString RosAllocAndLoadStringA
+# define RosLoadAndFormatStr RosLoadAndFormatStrA
+#endif
+
 #ifdef __cplusplus
 }
 #endif

reactos/lib/rosrtl
makefile 1.12 -> 1.13
diff -u -r1.12 -r1.13
--- makefile	15 Feb 2004 00:04:07 -0000	1.12
+++ makefile	10 Aug 2004 10:57:54 -0000	1.13
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.12 2004/02/15 00:04:07 arty Exp $
+# $Id: makefile,v 1.13 2004/08/10 10:57:54 weiden Exp $
 
 PATH_TO_TOP = ../..
 
@@ -16,7 +16,8 @@
  thread/stack.o
 
 STRING_OBJECTS = \
- string/append.o
+ string/append.o \
+ string/resstr.o
 
 REGISTRY_OBJECTS = \
  registry/registry.o

reactos/lib/rosrtl/string
resstr.c added at 1.1
diff -N resstr.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ resstr.c	10 Aug 2004 10:57:54 -0000	1.1
@@ -0,0 +1,225 @@
+#define NTOS_MODE_USER
+#include <ntos.h>
+
+/* 
+ * Utility to measure the length of a string resource
+ *
+ * IN HINSTANCE hInst -> Instance of the module
+ * IN UINT uID        -> ID of the string to measure
+ *
+ * Returns the number of characters not including the null-terminator.
+ * Returns -1 on failure.
+ */
+int
+RosLenOfStrResource(HINSTANCE hInst, UINT uID)
+{
+  HRSRC hrSrc;
+  HGLOBAL hRes;
+  LPWSTR lpName, lpStr;
+  
+  if(hInst == NULL)
+  {
+    return -1;
+  }
+  
+  /* There are always blocks of 16 strings */
+  lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
+
+  /* Find the string table block */
+  if((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) &&
+     (hRes = LoadResource(hInst, hrSrc)) &&
+     (lpStr = LockResource(hRes)))
+  {
+    UINT x;
+
+    /* Find the string we're looking for */
+    uID &= 0xF; /* position in the block, same as % 16 */
+    for(x = 0; x < uID; x++)
+    {
+      lpStr += (*lpStr) + 1;
+    }
+    
+    /* Found the string */
+    return (int)(*lpStr);
+  }
+  return -1;
+}
+
+/*
+ * Utility to allocate and load a string from the string table
+ *
+ * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
+ * IN  HINSTANCE hInst -> Instance of the module
+ * IN  UINT uID        -> ID of the string to measure
+ *
+ * Returns the number of characters not including the null-terminator.
+ * Returns 0 on failure. Use LocalFree() to free the memory allocated.
+ */
+int
+RosAllocAndLoadStringA(LPSTR *lpTarget, HINSTANCE hInst, UINT uID)
+{
+  int ln;
+  
+  ln = RosLenOfStrResource(hInst, uID);
+  if(ln++ > 0)
+  {
+    (*lpTarget) = (LPSTR)LocalAlloc(LHND, ln * sizeof(CHAR));
+    if((*lpTarget) != NULL)
+    {
+      int Ret;
+      if(!(Ret = LoadStringA(hInst, uID, *lpTarget, ln)))
+      {
+        LocalFree((HLOCAL)(*lpTarget));
+      }
+      return Ret;
+    }
+  }
+  return 0;
+}
+
+/*
+ * Utility to allocate and load a string from the string table
+ *
+ * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
+ * IN  HINSTANCE hInst -> Instance of the module
+ * IN  UINT uID        -> ID of the string to measure
+ *
+ * Returns the number of characters not including the null-terminator.
+ * Returns 0 on failure. Use LocalFree() to free the memory allocated.
+ */
+int
+RosAllocAndLoadStringW(LPWSTR *lpTarget, HINSTANCE hInst, UINT uID)
+{
+  int ln;
+
+  ln = RosLenOfStrResource(hInst, uID);
+  if(ln++ > 0)
+  {
+    (*lpTarget) = (LPWSTR)LocalAlloc(LHND, ln * sizeof(WCHAR));
+    if((*lpTarget) != NULL)
+    {
+      int Ret;
+      if(!(Ret = LoadStringW(hInst, uID, *lpTarget, ln)))
+      {
+        LocalFree((HLOCAL)(*lpTarget));
+      }
+      return Ret;
+    }
+  }
+  return 0;
+}
+
+/*
+ * Utility to allocate memory and format a string
+ *
+ * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
+ * IN  LPSTR lpFormat  -> String which is to be formatted with the arguments given
+ *
+ * Returns the number of characters in lpTarget not including the null-terminator.
+ * Returns 0 on failure. Use LocalFree() to free the memory allocated.
+ */
+DWORD
+RosFormatStrA(LPSTR *lpTarget, LPSTR lpFormat, ...)
+{
+  DWORD Ret;
+  va_list lArgs;
+  
+  va_start(lArgs, lpFormat);
+  /* let's use FormatMessage to format it because it has the ability to allocate
+     memory automatically */
+  Ret = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
+                       lpFormat, 0, 0, (LPSTR)lpTarget, 0, &lArgs);
+  va_end(lArgs);
+  
+  return Ret;
+}
+
+/*
+ * Utility to allocate memory and format a string
+ *
+ * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
+ * IN  LPSTR lpFormat  -> String which is to be formatted with the arguments given
+ *
+ * Returns the number of characters in lpTarget not including the null-terminator.
+ * Returns 0 on failure. Use LocalFree() to free the memory allocated.
+ */
+DWORD
+RosFormatStrW(LPWSTR *lpTarget, LPWSTR lpFormat, ...)
+{
+  DWORD Ret;
+  va_list lArgs;
+
+  va_start(lArgs, lpFormat);
+  /* let's use FormatMessage to format it because it has the ability to allocate
+     memory automatically */
+  Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
+                       lpFormat, 0, 0, (LPWSTR)lpTarget, 0, &lArgs);
+  va_end(lArgs);
+
+  return Ret;
+}
+
+/*
+ * Utility to allocate memory, load a string from the resources and format it
+ *
+ * IN  HINSTANCE hInst -> Instance of the module
+ * IN  UINT uID        -> ID of the string to measure
+ * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
+ *
+ * Returns the number of characters in lpTarget not including the null-terminator.
+ * Returns 0 on failure. Use LocalFree() to free the memory allocated.
+ */
+DWORD
+RosLoadAndFormatStrA(HINSTANCE hInst, UINT uID, LPSTR *lpTarget, ...)
+{
+  DWORD Ret = 0;
+  LPSTR lpFormat;
+  va_list lArgs;
+  
+  if(RosAllocAndLoadStringA(&lpFormat, hInst, uID) > 0)
+  {
+    va_start(lArgs, lpTarget);
+    /* let's use FormatMessage to format it because it has the ability to allocate
+       memory automatically */
+    Ret = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
+                         lpFormat, 0, 0, (LPSTR)lpTarget, 0, &lArgs);
+    va_end(lArgs);
+    
+    LocalFree((HLOCAL)lpFormat);
+  }
+  
+  return Ret;
+}
+
+/*
+ * Utility to allocate memory, load a string from the resources and format it
+ *
+ * IN  HINSTANCE hInst -> Instance of the module
+ * IN  UINT uID        -> ID of the string to measure
+ * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
+ *
+ * Returns the number of characters in lpTarget not including the null-terminator.
+ * Returns 0 on failure. Use LocalFree() to free the memory allocated.
+ */
+DWORD
+RosLoadAndFormatStrW(HINSTANCE hInst, UINT uID, LPWSTR *lpTarget, ...)
+{
+  DWORD Ret = 0;
+  LPWSTR lpFormat;
+  va_list lArgs;
+
+  if(RosAllocAndLoadStringW(&lpFormat, hInst, uID) > 0)
+  {
+    va_start(lArgs, lpTarget);
+    /* let's use FormatMessage to format it because it has the ability to allocate
+       memory automatically */
+    Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
+                         lpFormat, 0, 0, (LPWSTR)lpTarget, 0, &lArgs);
+    va_end(lArgs);
+    
+    LocalFree((HLOCAL)lpFormat);
+  }
+  
+  return Ret;
+}
+
CVSspam 0.2.8