ReactOS  0.4.14-dev-323-g6fe6a88
RegLoadMUIString.c
Go to the documentation of this file.
1 #include "advapi32_vista.h"
2 
3 #include <winuser.h>
4 #include <wine/debug.h>
5 #include <wine/unicode.h>
6 
8 
9 /******************************************************************************
10  * load_string [Internal]
11  *
12  * This is basically a copy of user32/resource.c's LoadStringW. Necessary to
13  * avoid importing user32, which is higher level than advapi32. Helper for
14  * RegLoadMUIString.
15  */
16 static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
17 {
18  HGLOBAL hMemory;
19  HRSRC hResource;
20  WCHAR *pString;
21  int idxString;
22 
23  /* Negative values have to be inverted. */
24  if (HIWORD(resId) == 0xffff)
25  resId = (UINT)(-((INT)resId));
26 
27  /* Load the resource into memory and get a pointer to it. */
28  hResource = FindResourceW(hModule, MAKEINTRESOURCEW(LOWORD(resId >> 4) + 1), (LPWSTR)RT_STRING);
29  if (!hResource) return 0;
30  hMemory = LoadResource(hModule, hResource);
31  if (!hMemory) return 0;
32  pString = LockResource(hMemory);
33 
34  /* Strings are length-prefixed. Lowest nibble of resId is an index. */
35  idxString = resId & 0xf;
36  while (idxString--) pString += *pString + 1;
37 
38  /* If no buffer is given, return length of the string. */
39  if (!pwszBuffer) return *pString;
40 
41  /* Else copy over the string, respecting the buffer size. */
42  cMaxChars = (*pString < cMaxChars) ? *pString : (cMaxChars - 1);
43  if (cMaxChars >= 0)
44  {
45  memcpy(pwszBuffer, pString+1, cMaxChars * sizeof(WCHAR));
46  pwszBuffer[cMaxChars] = L'\0';
47  }
48 
49  return cMaxChars;
50 }
51 
52 /************************************************************************
53  * RegLoadMUIStringW
54  *
55  * @implemented
56  */
59  IN LPCWSTR pszValue OPTIONAL,
60  OUT LPWSTR pszOutBuf,
61  IN DWORD cbOutBuf,
63  IN DWORD Flags,
64  IN LPCWSTR pszDirectory OPTIONAL)
65 {
66  DWORD dwValueType, cbData;
67  LPWSTR pwszTempBuffer = NULL, pwszExpandedBuffer = NULL;
68  LONG result;
69 
70  /* Parameter sanity checks. */
71  if (!hKey || !pszOutBuf)
73 
74  if (pszDirectory && *pszDirectory)
75  {
76  FIXME("BaseDir parameter not yet supported!\n");
78  }
79 
80  /* Check for value existence and correctness of it's type, allocate a buffer and load it. */
81  result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, NULL, &cbData);
82  if (result != ERROR_SUCCESS) goto cleanup;
83  if (!(dwValueType == REG_SZ || dwValueType == REG_EXPAND_SZ) || !cbData)
84  {
86  goto cleanup;
87  }
88  pwszTempBuffer = HeapAlloc(GetProcessHeap(), 0, cbData);
89  if (!pwszTempBuffer)
90  {
92  goto cleanup;
93  }
94  result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, (LPBYTE)pwszTempBuffer, &cbData);
95  if (result != ERROR_SUCCESS) goto cleanup;
96 
97  /* Expand environment variables, if appropriate, or copy the original string over. */
98  if (dwValueType == REG_EXPAND_SZ)
99  {
100  cbData = ExpandEnvironmentStringsW(pwszTempBuffer, NULL, 0) * sizeof(WCHAR);
101  if (!cbData) goto cleanup;
102  pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData);
103  if (!pwszExpandedBuffer)
104  {
106  goto cleanup;
107  }
108  ExpandEnvironmentStringsW(pwszTempBuffer, pwszExpandedBuffer, cbData);
109  }
110  else
111  {
112  pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData);
113  memcpy(pwszExpandedBuffer, pwszTempBuffer, cbData);
114  }
115 
116  /* If the value references a resource based string, parse the value and load the string.
117  * Else just copy over the original value. */
119  if (*pwszExpandedBuffer != L'@') /* '@' is the prefix for resource based string entries. */
120  {
121  lstrcpynW(pszOutBuf, pwszExpandedBuffer, cbOutBuf / sizeof(WCHAR));
122  }
123  else
124  {
125  WCHAR *pComma = wcsrchr(pwszExpandedBuffer, L',');
126  UINT uiStringId;
128 
129  /* Format of the expanded value is 'path_to_dll,-resId' */
130  if (!pComma || pComma[1] != L'-')
131  {
133  goto cleanup;
134  }
135 
136  uiStringId = _wtoi(pComma+2);
137  *pComma = L'\0';
138 
139  hModule = LoadLibraryExW(pwszExpandedBuffer + 1, NULL, LOAD_LIBRARY_AS_DATAFILE);
140  if (!hModule || !load_string(hModule, uiStringId, pszOutBuf, cbOutBuf / sizeof(WCHAR)))
143  }
144 
145 cleanup:
146  HeapFree(GetProcessHeap(), 0, pwszTempBuffer);
147  HeapFree(GetProcessHeap(), 0, pwszExpandedBuffer);
148  return result;
149 }
150 
151 /************************************************************************
152  * RegLoadMUIStringA
153  *
154  * @implemented
155  */
156 LONG WINAPI
158  IN LPCSTR pszValue OPTIONAL,
159  OUT LPSTR pszOutBuf,
160  IN DWORD cbOutBuf,
162  IN DWORD Flags,
163  IN LPCSTR pszDirectory OPTIONAL)
164 {
165  UNICODE_STRING valueW, baseDirW;
166  WCHAR *pwszBuffer;
167  DWORD cbData = cbOutBuf * sizeof(WCHAR);
168  LONG result;
169 
170  valueW.Buffer = baseDirW.Buffer = pwszBuffer = NULL;
171  if (!RtlCreateUnicodeStringFromAsciiz(&valueW, pszValue) ||
172  !RtlCreateUnicodeStringFromAsciiz(&baseDirW, pszDirectory) ||
173  !(pwszBuffer = HeapAlloc(GetProcessHeap(), 0, cbData)))
174  {
176  goto cleanup;
177  }
178 
179  result = RegLoadMUIStringW(hKey, valueW.Buffer, pwszBuffer, cbData, NULL, Flags,
180  baseDirW.Buffer);
181 
182  if (result == ERROR_SUCCESS)
183  {
184  cbData = WideCharToMultiByte(CP_ACP, 0, pwszBuffer, -1, pszOutBuf, cbOutBuf, NULL, NULL);
185  if (pcbData)
186  *pcbData = cbData;
187  }
188 
189 cleanup:
190  HeapFree(GetProcessHeap(), 0, pwszBuffer);
191  RtlFreeUnicodeString(&baseDirW);
193 
194  return result;
195 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define IN
Definition: typedefs.h:38
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WideCharToMultiByte
Definition: compat.h:101
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define CP_ACP
Definition: compat.h:99
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
_Check_return_ _CRTIMP int __cdecl _wtoi(_In_z_ const wchar_t *_Str)
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
char * LPSTR
Definition: xmlstorage.h:182
int32_t INT
Definition: typedefs.h:56
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
#define lstrcpynW
Definition: compat.h:397
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned char * LPBYTE
Definition: typedefs.h:52
long LONG
Definition: pedump.c:60
LONG WINAPI RegLoadMUIStringW(IN HKEY hKey, IN LPCWSTR pszValue OPTIONAL, OUT LPWSTR pszOutBuf, IN DWORD cbOutBuf, OUT LPDWORD pcbData OPTIONAL, IN DWORD Flags, IN LPCWSTR pszDirectory OPTIONAL)
#define FIXME(fmt,...)
Definition: debug.h:110
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
smooth NULL
Definition: ftsmooth.c:416
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
static const WCHAR valueW[]
Definition: object.c:48
const char * LPCSTR
Definition: xmlstorage.h:183
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define FreeLibrary(x)
Definition: compat.h:405
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
WINE_DEFAULT_DEBUG_CHANNEL(reg)
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define ERROR_BADKEY
Definition: winerror.h:589
static const WCHAR L[]
Definition: oid.c:1250
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define RT_STRING
Definition: pedump.c:368
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:338
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
unsigned int UINT
Definition: ndis.h:50
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
static int reg
Definition: i386-dis.c:1275
#define OUT
Definition: typedefs.h:39
uint32_t * LPDWORD
Definition: typedefs.h:57
#define HIWORD(l)
Definition: typedefs.h:246
char * cleanup(char *str)
Definition: wpickclick.c:99
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
WCHAR * LPWSTR
Definition: xmlstorage.h:184
GLuint64EXT * result
Definition: glext.h:11304
LONG WINAPI RegLoadMUIStringA(IN HKEY hKey, IN LPCSTR pszValue OPTIONAL, OUT LPSTR pszOutBuf, IN DWORD cbOutBuf, OUT LPDWORD pcbData OPTIONAL, IN DWORD Flags, IN LPCSTR pszDirectory OPTIONAL)
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:394
static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4953
HMODULE hModule
Definition: animate.c:44
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68