implemented the general device information page
[reactos.git] / reactos / lib / devmgr / misc.c
1 /*
2 * ReactOS Device Manager Applet
3 * Copyright (C) 2004 - 2005 ReactOS Team
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /* $Id: devmgr.c 12852 2005-01-06 13:58:04Z mf $
20 *
21 * PROJECT: ReactOS devmgr.dll
22 * FILE: lib/devmgr/misc.c
23 * PURPOSE: ReactOS Device Manager
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
25 * UPDATE HISTORY:
26 * 2005/11/24 Created
27 */
28 #include <precomp.h>
29
30 HINSTANCE hDllInstance = NULL;
31
32
33 static INT
34 LengthOfStrResource(IN HINSTANCE hInst,
35 IN UINT uID)
36 {
37 HRSRC hrSrc;
38 HGLOBAL hRes;
39 LPWSTR lpName, lpStr;
40
41 if (hInst == NULL)
42 {
43 return -1;
44 }
45
46 /* There are always blocks of 16 strings */
47 lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
48
49 /* Find the string table block */
50 if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) &&
51 (hRes = LoadResource(hInst, hrSrc)) &&
52 (lpStr = LockResource(hRes)))
53 {
54 UINT x;
55
56 /* Find the string we're looking for */
57 uID &= 0xF; /* position in the block, same as % 16 */
58 for (x = 0; x < uID; x++)
59 {
60 lpStr += (*lpStr) + 1;
61 }
62
63 /* Found the string */
64 return (int)(*lpStr);
65 }
66 return -1;
67 }
68
69
70 static INT
71 AllocAndLoadString(OUT LPWSTR *lpTarget,
72 IN HINSTANCE hInst,
73 IN UINT uID)
74 {
75 INT ln;
76
77 ln = LengthOfStrResource(hInst,
78 uID);
79 if (ln++ > 0)
80 {
81 (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED,
82 ln * sizeof(WCHAR));
83 if ((*lpTarget) != NULL)
84 {
85 INT Ret;
86 if (!(Ret = LoadStringW(hInst, uID, *lpTarget, ln)))
87 {
88 LocalFree((HLOCAL)(*lpTarget));
89 }
90 return Ret;
91 }
92 }
93 return 0;
94 }
95
96
97 DWORD
98 LoadAndFormatString(IN HINSTANCE hInstance,
99 IN UINT uID,
100 OUT LPWSTR *lpTarget,
101 ...)
102 {
103 DWORD Ret = 0;
104 LPWSTR lpFormat;
105 va_list lArgs;
106
107 if (AllocAndLoadString(&lpFormat,
108 hInstance,
109 uID) > 0)
110 {
111 va_start(lArgs, lpTarget);
112 /* let's use FormatMessage to format it because it has the ability to allocate
113 memory automatically */
114 Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
115 lpFormat,
116 0,
117 0,
118 (LPWSTR)lpTarget,
119 0,
120 &lArgs);
121 va_end(lArgs);
122
123 LocalFree((HLOCAL)lpFormat);
124 }
125
126 return Ret;
127 }
128
129
130 LPARAM
131 ListViewGetSelectedItemData(IN HWND hwnd)
132 {
133 int Index;
134
135 Index = ListView_GetNextItem(hwnd,
136 -1,
137 LVNI_SELECTED);
138 if (Index != -1)
139 {
140 LVITEM li;
141
142 li.mask = LVIF_PARAM;
143 li.iItem = Index;
144 li.iSubItem = 0;
145
146 if (ListView_GetItem(hwnd,
147 &li))
148 {
149 return li.lParam;
150 }
151 }
152
153 return 0;
154 }
155
156
157 LPWSTR
158 ConvertMultiByteToUnicode(IN LPCSTR lpMultiByteStr,
159 IN UINT uCodePage)
160 {
161 LPWSTR lpUnicodeStr;
162 INT nLength;
163
164 nLength = MultiByteToWideChar(uCodePage,
165 0,
166 lpMultiByteStr,
167 -1,
168 NULL,
169 0);
170 if (nLength == 0)
171 return NULL;
172
173 lpUnicodeStr = HeapAlloc(GetProcessHeap(),
174 0,
175 nLength * sizeof(WCHAR));
176 if (lpUnicodeStr == NULL)
177 return NULL;
178
179 if (!MultiByteToWideChar(uCodePage,
180 0,
181 lpMultiByteStr,
182 nLength,
183 lpUnicodeStr,
184 nLength))
185 {
186 HeapFree(GetProcessHeap(),
187 0,
188 lpUnicodeStr);
189 return NULL;
190 }
191
192 return lpUnicodeStr;
193 }
194
195
196 BOOL
197 GetDeviceManufacturerString(IN HDEVINFO DeviceInfoSet,
198 IN PSP_DEVINFO_DATA DeviceInfoData,
199 OUT LPWSTR szBuffer,
200 IN DWORD BufferSize)
201 {
202 DWORD RegDataType;
203 BOOL Ret = FALSE;
204
205 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
206 DeviceInfoData,
207 SPDRP_MFG,
208 &RegDataType,
209 (PBYTE)szBuffer,
210 BufferSize * sizeof(WCHAR),
211 NULL) ||
212 RegDataType != REG_SZ)
213 {
214 szBuffer[0] = L'\0';
215 if (LoadString(hDllInstance,
216 IDS_UNKNOWN,
217 szBuffer,
218 BufferSize))
219 {
220 Ret = TRUE;
221 }
222 }
223 else
224 {
225 /* FIXME - check string for NULL termination! */
226 Ret = TRUE;
227 }
228
229 return Ret;
230 }
231
232
233 BOOL
234 GetDeviceLocationString(IN DEVINST dnDevInst,
235 OUT LPWSTR szBuffer,
236 IN DWORD BufferSize)
237 {
238 DWORD RegDataType;
239 ULONG DataSize;
240 CONFIGRET cRet;
241 BOOL Ret = FALSE;
242
243 DataSize = BufferSize * sizeof(WCHAR);
244 cRet = CM_Get_DevNode_Registry_Property(dnDevInst,
245 CM_DRP_LOCATION_INFORMATION,
246 &RegDataType,
247 szBuffer,
248 &DataSize,
249 0);
250 if (cRet != CR_SUCCESS ||
251 RegDataType != REG_SZ)
252 {
253 szBuffer[0] = L'\0';
254 if (LoadString(hDllInstance,
255 IDS_UNKNOWN,
256 szBuffer,
257 BufferSize))
258 {
259 Ret = TRUE;
260 }
261 }
262 else
263 {
264 /* FIXME - check string for NULL termination! */
265 Ret = TRUE;
266 }
267
268 if (szBuffer[0] >= L'0' && szBuffer[0] <= L'9')
269 {
270 /* convert the string to an integer value and create a
271 formatted string */
272 LPWSTR szFormatted;
273 ULONG ulLocation = (ULONG)wcstoul(szBuffer,
274 NULL,
275 10);
276 if (LoadAndFormatString(hDllInstance,
277 IDS_LOCATIONSTR,
278 &szFormatted,
279 ulLocation,
280 szBuffer) != 0)
281 {
282 wcsncpy(szBuffer,
283 szFormatted,
284 BufferSize - 1);
285 szBuffer[BufferSize - 1] = L'\0';
286 LocalFree((HLOCAL)szFormatted);
287 }
288 else
289 Ret = FALSE;
290 }
291
292 return Ret;
293 }
294
295
296 BOOL
297 GetDeviceStatusString(IN HDEVINFO DeviceInfoSet,
298 IN PSP_DEVINFO_DATA DeviceInfoData,
299 OUT LPWSTR szBuffer,
300 IN DWORD BufferSize)
301 {
302 return LoadString(hDllInstance,
303 IDS_UNKNOWN,
304 szBuffer,
305 BufferSize) != 0;
306 }
307
308
309 BOOL
310 GetDeviceTypeString(IN PSP_DEVINFO_DATA DeviceInfoData,
311 OUT LPWSTR szBuffer,
312 IN DWORD BufferSize)
313 {
314 BOOL Ret = FALSE;
315
316 if (!SetupDiGetClassDescription(&DeviceInfoData->ClassGuid,
317 szBuffer,
318 BufferSize,
319 NULL))
320 {
321 szBuffer[0] = L'\0';
322 if (LoadString(hDllInstance,
323 IDS_UNKNOWN,
324 szBuffer,
325 BufferSize))
326 {
327 Ret = TRUE;
328 }
329 }
330 else
331 {
332 /* FIXME - check string for NULL termination! */
333 Ret = TRUE;
334 }
335
336 return Ret;
337 }
338
339
340 HINSTANCE
341 LoadAndInitComctl32(VOID)
342 {
343 typedef VOID (WINAPI *PINITCOMMONCONTROLS)(VOID);
344 PINITCOMMONCONTROLS pInitCommonControls;
345 HINSTANCE hComCtl32;
346
347 hComCtl32 = LoadLibrary(L"comctl32.dll");
348 if (hComCtl32 != NULL)
349 {
350 /* initialize the common controls */
351 pInitCommonControls = (PINITCOMMONCONTROLS)GetProcAddress(hComCtl32,
352 "InitCommonControls");
353 if (pInitCommonControls == NULL)
354 {
355 FreeLibrary(hComCtl32);
356 return NULL;
357 }
358
359 pInitCommonControls();
360 }
361
362 return hComCtl32;
363 }
364
365
366 BOOL
367 STDCALL
368 DllMain(IN HINSTANCE hinstDLL,
369 IN DWORD dwReason,
370 IN LPVOID lpvReserved)
371 {
372 switch (dwReason)
373 {
374 case DLL_PROCESS_ATTACH:
375 DisableThreadLibraryCalls(hinstDLL);
376 hDllInstance = hinstDLL;
377 break;
378 }
379
380 return TRUE;
381 }