xref: /reactos/base/shell/explorer/util.cpp (revision 8a978a17)
1 #include "precomp.h"
2 #include <winver.h>
3 
4 typedef struct _LANGCODEPAGE
5 {
6     WORD wLanguage;
7     WORD wCodePage;
8 } LANGCODEPAGE, *PLANGCODEPAGE;
9 
10 HRESULT
11 IsSameObject(IN IUnknown *punk1, IN IUnknown *punk2)
12 {
13     HRESULT hRet;
14 
15     hRet = punk1->QueryInterface(IID_PPV_ARG(IUnknown, &punk1));
16     if (!SUCCEEDED(hRet))
17         return hRet;
18 
19     hRet = punk2->QueryInterface(IID_PPV_ARG(IUnknown, &punk2));
20 
21     punk1->Release();
22 
23     if (!SUCCEEDED(hRet))
24         return hRet;
25 
26     punk2->Release();
27 
28     /* We're dealing with the same object if the IUnknown pointers are equal */
29     return (punk1 == punk2) ? S_OK : S_FALSE;
30 }
31 
32 HMENU
33 LoadPopupMenu(IN HINSTANCE hInstance,
34               IN LPCWSTR lpMenuName)
35 {
36     HMENU hMenu, hSubMenu = NULL;
37 
38     hMenu = LoadMenuW(hInstance, lpMenuName);
39     if (hMenu != NULL)
40     {
41         hSubMenu = GetSubMenu(hMenu, 0);
42         if ((hSubMenu != NULL) &&
43             !RemoveMenu(hMenu, 0, MF_BYPOSITION))
44         {
45             hSubMenu = NULL;
46         }
47 
48         DestroyMenu(hMenu);
49     }
50 
51     return hSubMenu;
52 }
53 
54 HMENU
55 FindSubMenu(IN HMENU hMenu,
56             IN UINT uItem,
57             IN BOOL fByPosition)
58 {
59     MENUITEMINFOW mii;
60 
61     mii.cbSize = sizeof(mii);
62     mii.fMask = MIIM_SUBMENU;
63 
64     if (GetMenuItemInfoW(hMenu, uItem, fByPosition, &mii))
65     {
66         return mii.hSubMenu;
67     }
68 
69     return NULL;
70 }
71 
72 BOOL
73 GetCurrentLoggedOnUserName(OUT LPWSTR szBuffer,
74                            IN DWORD dwBufferSize)
75 {
76     DWORD dwType;
77     DWORD dwSize;
78 
79     /* Query the user name from the registry */
80     dwSize = (dwBufferSize * sizeof(WCHAR)) - 1;
81     if (RegQueryValueExW(hkExplorer,
82                          L"Logon User Name",
83                          0,
84                          &dwType,
85                          (LPBYTE)szBuffer,
86                          &dwSize) == ERROR_SUCCESS &&
87         (dwSize / sizeof(WCHAR)) > 1 &&
88         szBuffer[0] != L'\0')
89     {
90         szBuffer[dwSize / sizeof(WCHAR)] = L'\0';
91         return TRUE;
92     }
93 
94     /* Fall back to GetUserName() */
95     dwSize = dwBufferSize;
96     if (!GetUserNameW(szBuffer, &dwSize))
97     {
98         szBuffer[0] = L'\0';
99         return FALSE;
100     }
101 
102     return TRUE;
103 }
104 
105 BOOL
106 FormatMenuString(IN HMENU hMenu,
107                  IN UINT uPosition,
108                  IN UINT uFlags,
109                  ...)
110 {
111     va_list vl;
112     MENUITEMINFOW mii;
113     WCHAR szBuf[128];
114     WCHAR szBufFmt[128];
115 
116     /* Find the menu item and read the formatting string */
117     mii.cbSize = sizeof(mii);
118     mii.fMask = MIIM_STRING;
119     mii.dwTypeData = szBufFmt;
120     mii.cch = _countof(szBufFmt);
121     if (GetMenuItemInfoW(hMenu, uPosition, uFlags, &mii))
122     {
123         /* Format the string */
124         va_start(vl, uFlags);
125         _vsntprintf(szBuf,
126                     _countof(szBuf) - 1,
127                     szBufFmt,
128                     vl);
129         va_end(vl);
130         szBuf[_countof(szBuf) - 1] = L'\0';
131 
132         /* Update the menu item */
133         mii.dwTypeData = szBuf;
134         if (SetMenuItemInfo(hMenu, uPosition, uFlags, &mii))
135         {
136             return TRUE;
137         }
138     }
139 
140     return FALSE;
141 }
142 
143 BOOL
144 GetExplorerRegValueSet(IN HKEY hKey,
145                        IN LPCWSTR lpSubKey,
146                        IN LPCWSTR lpValue)
147 {
148     WCHAR szBuffer[MAX_PATH];
149     HKEY hkSubKey;
150     DWORD dwType, dwSize;
151     BOOL Ret = FALSE;
152 
153     StringCbCopyW(szBuffer, sizeof(szBuffer),
154                   L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer");
155     if (FAILED_UNEXPECTEDLY(StringCbCatW(szBuffer, sizeof(szBuffer), L"\\")))
156         return FALSE;
157     if (FAILED_UNEXPECTEDLY(StringCbCatW(szBuffer, sizeof(szBuffer), lpSubKey)))
158         return FALSE;
159 
160     dwSize = sizeof(szBuffer);
161     if (RegOpenKeyExW(hKey,
162                       szBuffer,
163                       0,
164                       KEY_QUERY_VALUE,
165                       &hkSubKey) == ERROR_SUCCESS)
166     {
167         ZeroMemory(szBuffer, sizeof(szBuffer));
168 
169         if (RegQueryValueExW(hkSubKey,
170                              lpValue,
171                              0,
172                              &dwType,
173                              (LPBYTE)szBuffer,
174                              &dwSize) == ERROR_SUCCESS)
175         {
176             if ((dwType == REG_DWORD) && (dwSize == sizeof(DWORD)))
177                 Ret = *((PDWORD)szBuffer) != 0;
178             else if (dwSize > 0)
179                 Ret = *((PWCHAR)szBuffer) != 0;
180         }
181 
182         RegCloseKey(hkSubKey);
183     }
184     return Ret;
185 }
186 
187 BOOL
188 GetVersionInfoString(IN LPCWSTR szFileName,
189                      IN LPCWSTR szVersionInfo,
190                      OUT LPWSTR szBuffer,
191                      IN UINT cbBufLen)
192 {
193     LPVOID lpData = NULL;
194     WCHAR szSubBlock[128];
195     WCHAR *lpszLocalBuf = NULL;
196     LANGID UserLangId;
197     PLANGCODEPAGE lpTranslate = NULL;
198     DWORD dwLen;
199     DWORD dwHandle;
200     UINT cbTranslate;
201     UINT cbLen;
202     BOOL bRet = FALSE;
203     UINT i;
204 
205     dwLen = GetFileVersionInfoSizeW(szFileName, &dwHandle);
206 
207     if (dwLen > 0)
208     {
209         lpData = HeapAlloc(hProcessHeap, 0, dwLen);
210 
211         if (lpData != NULL)
212         {
213             if (GetFileVersionInfoW(szFileName,
214                                     0,
215                                     dwLen,
216                                     lpData) != 0)
217             {
218                 UserLangId = GetUserDefaultLangID();
219 
220                 VerQueryValueW(lpData,
221                                L"\\VarFileInfo\\Translation",
222                                (LPVOID*)&lpTranslate,
223                                &cbTranslate);
224 
225                 for (i = 0; i < cbTranslate / sizeof(LANGCODEPAGE); i++)
226                 {
227                     /* If the bottom eight bits of the language id's
228                     match, use this version information (since this
229                     means that the version information and the users
230                     default language are the same). */
231                     if (LOBYTE(lpTranslate[i].wLanguage) == LOBYTE(UserLangId))
232                     {
233                         wnsprintf(szSubBlock,
234                                   _countof(szSubBlock),
235                                   L"\\StringFileInfo\\%04X%04X\\%s",
236                                   lpTranslate[i].wLanguage,
237                                   lpTranslate[i].wCodePage,
238                                   szVersionInfo);
239 
240                         if (VerQueryValueW(lpData,
241                                            szSubBlock,
242                                            (LPVOID*)&lpszLocalBuf,
243                                            &cbLen) != 0)
244                         {
245                             wcsncpy(szBuffer, lpszLocalBuf, cbBufLen / sizeof(*szBuffer));
246 
247                             bRet = TRUE;
248                             break;
249                         }
250                     }
251                 }
252             }
253 
254             HeapFree(hProcessHeap, 0, lpData);
255             lpData = NULL;
256         }
257     }
258 
259     return bRet;
260 }
261