xref: /reactos/base/shell/explorer/util.cpp (revision 8bd071a5)
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 GetRegBool(IN LPCWSTR pszSubKey, IN LPCWSTR pszValueName, IN BOOL bDefaultValue)
144 {
145     return SHRegGetBoolUSValueW(pszSubKey, pszValueName, FALSE, bDefaultValue);
146 }
147 
148 BOOL SetRegDword(IN LPCWSTR pszSubKey, IN LPCWSTR pszValueName, IN DWORD dwValue)
149 {
150     return (SHRegSetUSValueW(pszSubKey, pszValueName, REG_DWORD, &dwValue,
151                              sizeof(dwValue), SHREGSET_FORCE_HKCU) == ERROR_SUCCESS);
152 }
153 
154 #define REGKEY_ADVANCED L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"
155 
156 BOOL GetAdvancedBool(IN LPCWSTR pszValueName, IN BOOL bDefaultValue)
157 {
158     return GetRegBool(REGKEY_ADVANCED, pszValueName, bDefaultValue);
159 }
160 
161 BOOL SetAdvancedDword(IN LPCWSTR pszValueName, IN DWORD dwValue)
162 {
163     return SetRegDword(REGKEY_ADVANCED, pszValueName, dwValue);
164 }
165 
166 BOOL
167 GetVersionInfoString(IN LPCWSTR szFileName,
168                      IN LPCWSTR szVersionInfo,
169                      OUT LPWSTR szBuffer,
170                      IN UINT cbBufLen)
171 {
172     LPVOID lpData = NULL;
173     WCHAR szSubBlock[128];
174     WCHAR *lpszLocalBuf = NULL;
175     LANGID UserLangId;
176     PLANGCODEPAGE lpTranslate = NULL;
177     DWORD dwLen;
178     DWORD dwHandle;
179     UINT cbTranslate;
180     UINT cbLen;
181     BOOL bRet = FALSE;
182     UINT i;
183 
184     dwLen = GetFileVersionInfoSizeW(szFileName, &dwHandle);
185 
186     if (dwLen > 0)
187     {
188         lpData = HeapAlloc(hProcessHeap, 0, dwLen);
189 
190         if (lpData != NULL)
191         {
192             if (GetFileVersionInfoW(szFileName,
193                                     0,
194                                     dwLen,
195                                     lpData) != 0)
196             {
197                 UserLangId = GetUserDefaultLangID();
198 
199                 VerQueryValueW(lpData,
200                                L"\\VarFileInfo\\Translation",
201                                (LPVOID*)&lpTranslate,
202                                &cbTranslate);
203 
204                 for (i = 0; i < cbTranslate / sizeof(LANGCODEPAGE); i++)
205                 {
206                     /* If the bottom eight bits of the language id's
207                     match, use this version information (since this
208                     means that the version information and the users
209                     default language are the same). */
210                     if (LOBYTE(lpTranslate[i].wLanguage) == LOBYTE(UserLangId))
211                     {
212                         wnsprintf(szSubBlock,
213                                   _countof(szSubBlock),
214                                   L"\\StringFileInfo\\%04X%04X\\%s",
215                                   lpTranslate[i].wLanguage,
216                                   lpTranslate[i].wCodePage,
217                                   szVersionInfo);
218 
219                         if (VerQueryValueW(lpData,
220                                            szSubBlock,
221                                            (LPVOID*)&lpszLocalBuf,
222                                            &cbLen) != 0)
223                         {
224                             wcsncpy(szBuffer, lpszLocalBuf, cbBufLen / sizeof(*szBuffer));
225 
226                             bRet = TRUE;
227                             break;
228                         }
229                     }
230                 }
231             }
232 
233             HeapFree(hProcessHeap, 0, lpData);
234             lpData = NULL;
235         }
236     }
237 
238     return bRet;
239 }
240