xref: /reactos/base/applications/dxdiag/network.c (revision 1734f297)
1 /*
2  * PROJECT:     ReactX Diagnosis Application
3  * LICENSE:     LGPL - See COPYING in the top level directory
4  * FILE:        base/applications/dxdiag/network.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) / sizeof(WCHAR));
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 
319     /* Highlights the entire row instead of just the selected item in the first column */
320     SendMessage(hDlgCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
321 
322     /* initialize list ctrl */
323     InitListViewColumns(hDlgCtrl);
324 
325     /* enumerate providers */
326     result = EnumerateServiceProviders(hKey, hDlgCtrl, DirectPlay8SP);
327     RegCloseKey(hKey);
328     if (!result)
329         return;
330 
331     /* open DirectPlay key */
332     result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\DirectPlay\\Service Providers", 0, KEY_READ, &hKey);
333     if (result != ERROR_SUCCESS)
334         return;
335 
336     /* enumerate providers */
337     EnumerateServiceProviders(hKey, hDlgCtrl, DirectPlaySP);
338     RegCloseKey(hKey);
339 }
340 
341 INT_PTR CALLBACK
342 NetworkPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
343 {
344     UNREFERENCED_PARAMETER(lParam);
345     UNREFERENCED_PARAMETER(wParam);
346     switch (message) {
347         case WM_INITDIALOG:
348         {
349             SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
350             InitializeDirectPlayDialog(hDlg);
351             return TRUE;
352         }
353     }
354 
355     return FALSE;
356 }
357