[DXDIAG]
[reactos.git] / reactos / base / applications / dxdiag / network.c
1 /*
2 * PROJECT: ReactX Diagnosis Application
3 * LICENSE: LGPL - See COPYING in the top level directory
4 * FILE: base/applications/dxdiag/dxdiag.c
5 * PURPOSE: ReactX diagnosis network page
6 * COPYRIGHT: Copyright 2008 Johannes Anderwald
7 *
8 */
9
10 #include "precomp.h"
11
12 #include <winver.h>
13
14 typedef struct
15 {
16 WCHAR Guid[40];
17 UINT ResourceID;
18 }DIRECTPLAY_GUID;
19
20 typedef struct _LANGANDCODEPAGE_
21 {
22 WORD lang;
23 WORD code;
24 } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
25
26 static DIRECTPLAY_GUID DirectPlay8SP[] =
27 {
28 {
29 L"{6D4A3650-628D-11D2-AE0F-006097B01411}",
30 IDS_DIRECTPLAY8_MODEMSP
31 },
32 {
33 L"{743B5D60-628D-11D2-AE0F-006097B01411}",
34 IDS_DIRECTPLAY8_SERIALSP
35 },
36 {
37 L"{53934290-628D-11D2-AE0F-006097B01411}",
38 IDS_DIRECTPLAY8_IPXSP
39 },
40 {
41 L"{EBFE7BA0-628D-11D2-AE0F-006097B01411}",
42 IDS_DIRECTPLAY8_TCPSP
43 }
44 };
45
46 static DIRECTPLAY_GUID DirectPlaySP[] =
47 {
48 {
49 L"{36E95EE0-8577-11cf-960C-0080C7534E82}",
50 IDS_DIRECTPLAY_TCPCONN
51 },
52 {
53 L"685BC400-9D2C-11cf-A9CD-00AA006886E3",
54 IDS_DIRECTPLAY_IPXCONN
55 },
56 {
57 L"{44EAA760-CB68-11cf-9C4E-00A0C905425E}",
58 IDS_DIRECTPLAY_MODEMCONN
59 },
60 {
61 L"{0F1D6860-88D9-11cf-9C4E-00A0C905425E}",
62 IDS_DIRECTPLAY_SERIALCONN
63 }
64 };
65
66 static
67 VOID
68 InitListViewColumns(HWND hDlgCtrl)
69 {
70 WCHAR szText[256];
71 LVCOLUMNW lvcolumn;
72 INT Index;
73
74 ZeroMemory(&lvcolumn, sizeof(LVCOLUMNW));
75 lvcolumn.pszText = szText;
76 lvcolumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
77 lvcolumn.fmt = LVCFMT_LEFT;
78 lvcolumn.cx = 200;
79
80 for(Index = 0; Index < 4; Index++)
81 {
82 szText[0] = L'\0';
83 LoadStringW(hInst, IDS_DIRECTPLAY_COL_NAME1 + Index, szText, sizeof(szText) / sizeof(WCHAR));
84 szText[(sizeof(szText) / sizeof(WCHAR))-1] = L'\0';
85 if (Index)
86 lvcolumn.cx = 98;
87 if (SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, Index, (LPARAM)&lvcolumn) == -1)
88 return;
89 }
90 }
91
92 UINT
93 FindProviderIndex(LPCWSTR szGuid, DIRECTPLAY_GUID * PreDefProviders)
94 {
95 UINT Index;
96 for(Index = 0; Index < 4; Index++)
97 {
98 if (!wcsncmp(PreDefProviders[Index].Guid, szGuid, 40))
99 return Index;
100 }
101 return UINT_MAX;
102 }
103
104 BOOL
105 GetFileVersion(LPCWSTR szAppName, WCHAR * szVer, DWORD szVerSize)
106 {
107 UINT VerSize;
108 DWORD DummyHandle;
109 LPVOID pBuf;
110 WORD lang = 0;
111 WORD code = 0;
112 LPLANGANDCODEPAGE lplangcode;
113 WCHAR szBuffer[100];
114 WCHAR * pResult;
115 BOOL bResult = FALSE;
116 BOOL bVer;
117
118 static const WCHAR wFormat[] = L"\\StringFileInfo\\%04x%04x\\FileVersion";
119 static const WCHAR wTranslation[] = L"VarFileInfo\\Translation";
120
121 /* query version info size */
122 VerSize = GetFileVersionInfoSizeW(szAppName, &DummyHandle);
123 if (!VerSize)
124 return FALSE;
125
126
127 /* allocate buffer */
128 pBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, VerSize);
129 if (!pBuf)
130 return FALSE;
131
132
133 /* query version info */
134 if(!GetFileVersionInfoW(szAppName, 0, VerSize, pBuf))
135 {
136 HeapFree(GetProcessHeap(), 0, pBuf);
137 return FALSE;
138 }
139
140 /* query lang code */
141 if(VerQueryValueW(pBuf, wTranslation, (LPVOID *)&lplangcode, &VerSize))
142 {
143 /* FIXME find language from current locale / if not available,
144 * default to english
145 * for now default to first available language
146 */
147 lang = lplangcode->lang;
148 code = lplangcode->code;
149 }
150 /* set up format */
151 wsprintfW(szBuffer, wFormat, lang, code);
152 /* query manufacturer */
153 pResult = NULL;
154 bVer = VerQueryValueW(pBuf, szBuffer, (LPVOID *)&pResult, &VerSize);
155
156 if (VerSize < szVerSize && bVer && pResult)
157 {
158 wcscpy(szVer, pResult);
159 pResult = wcschr(szVer, L' ');
160 if (pResult)
161 {
162 /* cut off build info */
163 VerSize = (pResult - szVer);
164 }
165 if (GetLocaleInfoW(MAKELCID(lang, SORT_DEFAULT), LOCALE_SLANGUAGE, &szVer[VerSize], szVerSize-VerSize))
166 {
167 szVer[VerSize-1] = L' ';
168 szVer[szVerSize-1] = L'\0';
169 }
170 bResult = TRUE;
171 }
172
173 HeapFree(GetProcessHeap(), 0, pBuf);
174 return bResult;
175 }
176
177 static
178 BOOL
179 EnumerateServiceProviders(HKEY hKey, HWND hDlgCtrl, DIRECTPLAY_GUID * PreDefProviders)
180 {
181 DWORD dwIndex = 0;
182 LONG result;
183 WCHAR szName[50];
184 WCHAR szGUID[40];
185 WCHAR szTemp[63];
186 WCHAR szResult[MAX_PATH+20] = {0};
187 DWORD RegProviders = 0;
188 DWORD ProviderIndex;
189 DWORD dwName;
190 LVITEMW Item;
191 INT ItemCount;
192 LRESULT lResult;
193
194
195 ItemCount = ListView_GetItemCount(hDlgCtrl);
196 ZeroMemory(&Item, sizeof(LVITEMW));
197 Item.mask = LVIF_TEXT;
198 Item.pszText = szResult;
199 Item.iItem = ItemCount;
200 /* insert all predefined items first */
201 for(dwIndex = 0; dwIndex < 4; dwIndex++)
202 {
203 Item.iItem = ItemCount + dwIndex;
204 Item.iSubItem = 0;
205 szResult[0] = L'\0';
206 LoadStringW(hInst, PreDefProviders[dwIndex].ResourceID, szResult, sizeof(szResult)/sizeof(WCHAR));
207 szResult[(sizeof(szResult)/sizeof(WCHAR))-1] = L'\0';
208 Item.iItem = SendMessageW(hDlgCtrl, LVM_INSERTITEM, 0, (LPARAM)&Item);
209 Item.iSubItem = 1;
210 szResult[0] = L'\0';
211 LoadStringW(hInst, IDS_REG_FAIL, szResult, sizeof(szResult)/sizeof(WCHAR));
212 szResult[(sizeof(szResult)/sizeof(WCHAR))-1] = L'\0';
213 SendMessageW(hDlgCtrl, LVM_SETITEM, 0, (LPARAM)&Item);
214 }
215
216 dwIndex = 0;
217 do
218 {
219 dwName = sizeof(szName) / sizeof(WCHAR);
220 result = RegEnumKeyEx(hKey, dwIndex, szName, &dwName, NULL, NULL, NULL, NULL);
221 if (result == ERROR_SUCCESS)
222 {
223 szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0';
224
225 ProviderIndex = UINT_MAX;
226 if (GetRegValue(hKey, szName, L"GUID", REG_SZ, szGUID, sizeof(szGUID)))
227 ProviderIndex = FindProviderIndex(szGUID, PreDefProviders);
228
229 if (ProviderIndex == UINT_MAX)
230 {
231 /* a custom service provider was found */
232 Item.iItem = ListView_GetItemCount(hDlgCtrl);
233
234 /* FIXME
235 * on Windows Vista we need to use RegLoadMUIString which is not available for older systems
236 */
237 if (!GetRegValue(hKey, szName, L"Friendly Name", REG_SZ, szResult, sizeof(szResult)))
238 if (!GetRegValue(hKey, szName, L"DescriptionW", REG_SZ, szResult, sizeof(szResult)))
239 szResult[0] = L'\0';
240
241 /* insert the new provider */
242 Item.iSubItem = 0;
243 lResult = SendMessageW(hDlgCtrl, LVM_INSERTITEM, 0, (LPARAM)&Item);
244 /* adjust index */
245 ProviderIndex = lResult - ItemCount;
246 }
247
248 szResult[0] = L'\0';
249 /* check if the 'Path' key is available */
250 if (!GetRegValue(hKey, szName, L"Path", REG_SZ, szResult, sizeof(szResult)))
251 {
252 /* retrieve the path by lookup the CLSID */
253 wcscpy(szTemp, L"CLSID\\");
254 wcscpy(&szTemp[6], szGUID);
255 wcscpy(&szTemp[44], L"\\InProcServer32");
256 if (!GetRegValue(HKEY_CLASSES_ROOT, szTemp, NULL, REG_SZ, szResult, sizeof(szResult)))
257 {
258 szResult[0] = L'\0';
259 ProviderIndex = UINT_MAX;
260 }
261 }
262 if (szResult[0])
263 {
264 /* insert path name */
265 Item.iSubItem = 2;
266 Item.iItem = ProviderIndex + ItemCount;
267 SendMessageW(hDlgCtrl, LVM_SETITEM, 0, (LPARAM)&Item);
268 /* retrieve file version */
269 if (!GetFileVersion(szResult, szTemp, sizeof(szTemp)/sizeof(WCHAR)))
270 {
271 szTemp[0] = L'\0';
272 LoadStringW(hInst, IDS_VERSION_UNKNOWN, szTemp, sizeof(szTemp)/sizeof(WCHAR));
273 szTemp[(sizeof(szTemp)/sizeof(WCHAR))-1] = L'\0';
274 }
275 Item.iSubItem = 3;
276 Item.pszText = szTemp;
277 SendMessageW(hDlgCtrl, LVM_SETITEM, 0, (LPARAM)&Item);
278 Item.pszText = szResult;
279 }
280
281 if (ProviderIndex != UINT_MAX)
282 {
283 RegProviders |= (1 << ProviderIndex);
284 szResult[0] = L'\0';
285 LoadStringW(hInst, IDS_REG_SUCCESS, szResult, sizeof(szResult));
286 Item.iSubItem = 1;
287
288 Item.iItem = ProviderIndex + ItemCount;
289 szResult[(sizeof(szResult)/sizeof(WCHAR))-1] = L'\0';
290 SendMessageW(hDlgCtrl, LVM_SETITEM, 0, (LPARAM)&Item);
291 }
292 }
293 dwIndex++;
294 }while(result != ERROR_NO_MORE_ITEMS);
295
296 /* check if all providers have been registered */
297 // if (RegProviders == 15)
298 return TRUE;
299 return FALSE;
300 }
301
302
303
304 static
305 void
306 InitializeDirectPlayDialog(HWND hwndDlg)
307 {
308 HKEY hKey;
309 LONG result;
310 HWND hDlgCtrl;
311
312 /* open DirectPlay8 key */
313 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\DirectPlay8\\Service Providers", 0, KEY_READ, &hKey);
314 if (result != ERROR_SUCCESS)
315 return;
316
317 hDlgCtrl = GetDlgItem(hwndDlg, IDC_LIST_PROVIDER);
318 /* initialize list ctrl */
319 InitListViewColumns(hDlgCtrl);
320
321 /* enumerate providers */
322 result = EnumerateServiceProviders(hKey, hDlgCtrl, DirectPlay8SP);
323 RegCloseKey(hKey);
324 if (!result)
325 return;
326
327 /* open DirectPlay key */
328 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\DirectPlay\\Service Providers", 0, KEY_READ, &hKey);
329 if (result != ERROR_SUCCESS)
330 return;
331
332 /* enumerate providers */
333 EnumerateServiceProviders(hKey, hDlgCtrl, DirectPlaySP);
334 RegCloseKey(hKey);
335 }
336
337 INT_PTR CALLBACK
338 NetworkPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
339 {
340 UNREFERENCED_PARAMETER(lParam);
341 UNREFERENCED_PARAMETER(wParam);
342 switch (message) {
343 case WM_INITDIALOG:
344 {
345 SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
346 InitializeDirectPlayDialog(hDlg);
347 return TRUE;
348 }
349 }
350
351 return FALSE;
352 }