ReactOS  0.4.14-dev-52-g6116262
muireg.c
Go to the documentation of this file.
1 #include "desk.h"
2 
3 /******************************************************************************
4  * load_string [Internal]
5  *
6  * This is basically a copy of user32/resource.c's LoadStringW. Necessary to
7  * avoid importing user32, which is higher level than advapi32. Helper for
8  * RegLoadMUIString.
9  */
10 static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
11 {
12  HGLOBAL hMemory;
13  HRSRC hResource;
14  WCHAR *pString;
15  int idxString;
16 
17  /* Negative values have to be inverted. */
18  if (HIWORD(resId) == 0xffff)
19  resId = (UINT)(-((INT)resId));
20 
21  /* Load the resource into memory and get a pointer to it. */
22  hResource = FindResourceW(hModule, MAKEINTRESOURCEW(LOWORD(resId >> 4) + 1), (LPWSTR)RT_STRING);
23  if (!hResource) return 0;
24  hMemory = LoadResource(hModule, hResource);
25  if (!hMemory) return 0;
26  pString = LockResource(hMemory);
27 
28  /* Strings are length-prefixed. Lowest nibble of resId is an index. */
29  idxString = resId & 0xf;
30  while (idxString--) pString += *pString + 1;
31 
32  /* If no buffer is given, return length of the string. */
33  if (!pwszBuffer) return *pString;
34 
35  /* Else copy over the string, respecting the buffer size. */
36  cMaxChars = (*pString < cMaxChars) ? *pString : (cMaxChars - 1);
37  if (cMaxChars >= 0)
38  {
39  memcpy(pwszBuffer, pString+1, cMaxChars * sizeof(WCHAR));
40  pwszBuffer[cMaxChars] = L'\0';
41  }
42 
43  return cMaxChars;
44 }
45 
46 
47 /************************************************************************
48  * RegLoadMUIStringW
49  *
50  * @implemented
51  */
52 LONG
54  IN LPCWSTR pszValue OPTIONAL,
55  OUT LPWSTR pszOutBuf,
56  IN DWORD cbOutBuf,
58  IN DWORD Flags,
59  IN LPCWSTR pszDirectory OPTIONAL)
60 {
61  DWORD dwValueType, cbData;
62  LPWSTR pwszTempBuffer = NULL, pwszExpandedBuffer = NULL;
63  LONG result;
64 
65  /* Parameter sanity checks. */
66  if (!hKey || !pszOutBuf)
68 
69  if (pszDirectory && *pszDirectory)
70  {
71  //FIXME("BaseDir parameter not yet supported!\n");
73  }
74 
75  /* Check for value existence and correctness of it's type, allocate a buffer and load it. */
76  result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, NULL, &cbData);
77  if (result != ERROR_SUCCESS) goto cleanup;
78  if (!(dwValueType == REG_SZ || dwValueType == REG_EXPAND_SZ) || !cbData)
79  {
81  goto cleanup;
82  }
83  pwszTempBuffer = HeapAlloc(GetProcessHeap(), 0, cbData);
84  if (!pwszTempBuffer)
85  {
87  goto cleanup;
88  }
89  result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, (LPBYTE)pwszTempBuffer, &cbData);
90  if (result != ERROR_SUCCESS) goto cleanup;
91 
92  /* Expand environment variables, if appropriate, or copy the original string over. */
93  if (dwValueType == REG_EXPAND_SZ)
94  {
95  cbData = ExpandEnvironmentStringsW(pwszTempBuffer, NULL, 0) * sizeof(WCHAR);
96  if (!cbData) goto cleanup;
97  pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData);
98  if (!pwszExpandedBuffer)
99  {
101  goto cleanup;
102  }
103  ExpandEnvironmentStringsW(pwszTempBuffer, pwszExpandedBuffer, cbData);
104  }
105  else
106  {
107  pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData);
108  memcpy(pwszExpandedBuffer, pwszTempBuffer, cbData);
109  }
110 
111  /* If the value references a resource based string, parse the value and load the string.
112  * Else just copy over the original value. */
114  if (*pwszExpandedBuffer != L'@') /* '@' is the prefix for resource based string entries. */
115  {
116  lstrcpynW(pszOutBuf, pwszExpandedBuffer, cbOutBuf / sizeof(WCHAR));
117  }
118  else
119  {
120  WCHAR *pComma = wcsrchr(pwszExpandedBuffer, L',');
121  UINT uiStringId;
123 
124  /* Format of the expanded value is 'path_to_dll,-resId' */
125  if (!pComma || pComma[1] != L'-')
126  {
128  goto cleanup;
129  }
130 
131  uiStringId = _wtoi(pComma+2);
132  *pComma = L'\0';
133 
134  hModule = LoadLibraryExW(pwszExpandedBuffer + 1, NULL, LOAD_LIBRARY_AS_DATAFILE);
135  if (!hModule || !load_string(hModule, uiStringId, pszOutBuf, cbOutBuf / sizeof(WCHAR)))
138  }
139 
140 cleanup:
141  HeapFree(GetProcessHeap(), 0, pwszTempBuffer);
142  HeapFree(GetProcessHeap(), 0, pwszExpandedBuffer);
143  return result;
144 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define IN
Definition: typedefs.h:38
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
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
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
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)
LONG 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)
Definition: muireg.c:53
#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
unsigned long DWORD
Definition: ntddk_ex.h:95
#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 load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
Definition: muireg.c:10
#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
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:394
_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