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