1 2 #include "precomp.h" 3 4 /* update NUM_SETTINGS in precomp.h */ 5 LPWSTR lpSettings[NUM_SETTINGS] = 6 { 7 L"desktopwidth", 8 L"desktopheight", 9 L"session bpp", 10 L"full address", 11 L"username", 12 L"screen mode id", 13 }; 14 15 VOID 16 SaveAllSettings(PINFO pInfo) 17 { 18 INT ret; 19 WCHAR szValue[MAXVALUE]; 20 21 /* server */ 22 if (GetDlgItemText(pInfo->hGeneralPage, 23 IDC_SERVERCOMBO, 24 szValue, 25 MAXVALUE)) 26 { 27 SetStringToSettings(pInfo->pRdpSettings, 28 L"full address", 29 szValue); 30 } 31 32 /* resolution and fullscreen*/ 33 ret = SendDlgItemMessage(pInfo->hDisplayPage, 34 IDC_GEOSLIDER, 35 TBM_GETPOS, 36 0, 37 0); 38 if (ret != -1) 39 { 40 SetIntegerToSettings(pInfo->pRdpSettings, 41 L"screen mode id", 42 (ret == SendDlgItemMessageW(pInfo->hDisplayPage, IDC_GEOSLIDER, TBM_GETRANGEMAX, 0, 0)) ? 2 : 1); 43 SetIntegerToSettings(pInfo->pRdpSettings, 44 L"desktopwidth", 45 pInfo->DisplayDeviceList->Resolutions[ret].dmPelsWidth); 46 SetIntegerToSettings(pInfo->pRdpSettings, 47 L"desktopheight", 48 pInfo->DisplayDeviceList->Resolutions[ret].dmPelsHeight); 49 } 50 51 /* bpp */ 52 ret = SendDlgItemMessage(pInfo->hDisplayPage, 53 IDC_BPPCOMBO, 54 CB_GETCURSEL, 55 0, 56 0); 57 if (ret != CB_ERR) 58 { 59 ret = SendDlgItemMessage(pInfo->hDisplayPage, 60 IDC_BPPCOMBO, 61 CB_GETITEMDATA, 62 ret, 63 0); 64 if (ret != CB_ERR) 65 { 66 SetIntegerToSettings(pInfo->pRdpSettings, 67 L"session bpp", 68 ret); 69 } 70 } 71 72 /* user name */ 73 if (GetDlgItemText(pInfo->hGeneralPage, 74 IDC_NAMEEDIT, 75 szValue, 76 MAXVALUE)) 77 { 78 SetStringToSettings(pInfo->pRdpSettings, 79 L"username", 80 szValue); 81 } 82 } 83 84 85 BOOL 86 SetIntegerToSettings(PRDPSETTINGS pRdpSettings, 87 LPWSTR lpKey, 88 INT Value) 89 { 90 BOOL bRet = FALSE; 91 92 if (pRdpSettings) 93 { 94 INT i; 95 96 for (i = 0; i < pRdpSettings->NumSettings; i++) 97 { 98 if (wcscmp(pRdpSettings->pSettings[i].Key, lpKey) == 0) 99 { 100 if (pRdpSettings->pSettings[i].Type == 0) 101 pRdpSettings->pSettings[i].Type = L'i'; 102 103 pRdpSettings->pSettings[i].Value.i = Value; 104 bRet = TRUE; 105 break; 106 } 107 } 108 } 109 110 return bRet; 111 } 112 113 114 BOOL 115 SetStringToSettings(PRDPSETTINGS pRdpSettings, 116 LPWSTR lpKey, 117 LPWSTR lpValue) 118 { 119 BOOL bRet = FALSE; 120 121 if (pRdpSettings) 122 { 123 INT i; 124 125 for (i = 0; i < pRdpSettings->NumSettings; i++) 126 { 127 if (wcscmp(pRdpSettings->pSettings[i].Key, lpKey) == 0) 128 { 129 if (pRdpSettings->pSettings[i].Type == 0) 130 pRdpSettings->pSettings[i].Type = L's'; 131 132 wcscpy(pRdpSettings->pSettings[i].Value.s, lpValue); 133 bRet = TRUE; 134 break; 135 } 136 } 137 } 138 139 return bRet; 140 } 141 142 143 INT 144 GetIntegerFromSettings(PRDPSETTINGS pRdpSettings, 145 LPWSTR lpKey) 146 { 147 INT Value = -1; 148 149 if (pRdpSettings) 150 { 151 INT i; 152 153 for (i = 0; i < pRdpSettings->NumSettings; i++) 154 { 155 if (wcscmp(pRdpSettings->pSettings[i].Key, lpKey) == 0) 156 { 157 if (pRdpSettings->pSettings[i].Type == L'i') 158 { 159 Value = pRdpSettings->pSettings[i].Value.i; 160 break; 161 } 162 } 163 } 164 } 165 166 return Value; 167 } 168 169 170 LPWSTR 171 GetStringFromSettings(PRDPSETTINGS pRdpSettings, 172 LPWSTR lpKey) 173 { 174 LPWSTR lpValue = NULL; 175 176 if (pRdpSettings) 177 { 178 INT i; 179 180 for (i = 0; i < pRdpSettings->NumSettings; i++) 181 { 182 if (wcscmp(pRdpSettings->pSettings[i].Key, lpKey) == 0) 183 { 184 if (pRdpSettings->pSettings[i].Type == L's') 185 { 186 lpValue = pRdpSettings->pSettings[i].Value.s; 187 break; 188 } 189 } 190 } 191 } 192 193 return lpValue; 194 } 195 196 197 static BOOL 198 WriteRdpFile(HANDLE hFile, 199 PRDPSETTINGS pRdpSettings) 200 { 201 WCHAR line[MAXKEY + MAXVALUE + 4]; 202 SIZE_T BytesToWrite; 203 ULONG BytesWritten; 204 BOOL bRet; 205 INT i, k; 206 207 for (i = 0; i < pRdpSettings->NumSettings; i++) 208 { 209 /* only write out values in the lpSettings struct */ 210 for (k = 0; k < NUM_SETTINGS; k++) 211 { 212 if (wcscmp(lpSettings[k], pRdpSettings->pSettings[i].Key) == 0) 213 { 214 if (pRdpSettings->pSettings[i].Type == L'i') 215 { 216 _snwprintf(line, MAXKEY + MAXVALUE + 4, L"%s:i:%d\r\n", 217 pRdpSettings->pSettings[i].Key, 218 pRdpSettings->pSettings[i].Value.i); 219 } 220 else 221 { 222 _snwprintf(line, MAXKEY + MAXVALUE + 4, L"%s:s:%s\r\n", 223 pRdpSettings->pSettings[i].Key, 224 pRdpSettings->pSettings[i].Value.s); 225 } 226 227 BytesToWrite = wcslen(line) * sizeof(WCHAR); 228 229 bRet = WriteFile(hFile, 230 line, 231 BytesToWrite, 232 &BytesWritten, 233 NULL); 234 if (!bRet || BytesWritten == 0) 235 return FALSE; 236 } 237 } 238 } 239 240 return TRUE; 241 } 242 243 244 static VOID 245 ParseSettings(PRDPSETTINGS pRdpSettings, 246 LPWSTR lpBuffer) 247 { 248 LPWSTR lpStr = lpBuffer; 249 WCHAR szSeps[] = L":\r\n"; 250 WCHAR szNewline[] = L"\r\n"; 251 LPWSTR lpToken; 252 BOOL bFound; 253 INT i; 254 255 /* move past unicode byte order */ 256 if (lpStr[0] == 0xFEFF || lpStr[0] == 0xFFFE) 257 lpStr += 1; 258 259 lpToken = wcstok(lpStr, szSeps); 260 while (lpToken) 261 { 262 bFound = FALSE; 263 264 for (i = 0; i < pRdpSettings->NumSettings && !bFound; i++) 265 { 266 if (wcscmp(lpToken, pRdpSettings->pSettings[i].Key) == 0) 267 { 268 lpToken = wcstok(NULL, szSeps); 269 if (lpToken[0] == L'i') 270 { 271 pRdpSettings->pSettings[i].Type = lpToken[0]; 272 lpToken = wcstok(NULL, szSeps); 273 if (lpToken != NULL) 274 pRdpSettings->pSettings[i].Value.i = _wtoi(lpToken); 275 } 276 else if (lpToken[0] == L's') 277 { 278 pRdpSettings->pSettings[i].Type = lpToken[0]; 279 if (lpToken[2] == 13 || lpToken[2] == 10 || lpToken[2] == 0) 280 lpToken[0] = 0; // terminate string 281 else 282 lpToken = wcstok(NULL, szNewline); 283 if (lpToken != NULL) 284 wcscpy(pRdpSettings->pSettings[i].Value.s, lpToken); 285 } 286 bFound = TRUE; 287 } 288 } 289 290 /* move past the type and value */ 291 if (!bFound) 292 lpToken = wcstok(NULL, szNewline); 293 294 /* move to next key */ 295 lpToken = wcstok(NULL, szSeps); 296 } 297 } 298 299 300 static LPWSTR 301 ReadRdpFile(HANDLE hFile) 302 { 303 LPWSTR lpBuffer = NULL; 304 DWORD BytesToRead, BytesRead; 305 BOOL bRes; 306 307 if (hFile) 308 { 309 BytesToRead = GetFileSize(hFile, NULL); 310 if (BytesToRead) 311 { 312 lpBuffer = HeapAlloc(GetProcessHeap(), 313 0, 314 BytesToRead + 2); 315 if (lpBuffer) 316 { 317 bRes = ReadFile(hFile, 318 lpBuffer, 319 BytesToRead, 320 &BytesRead, 321 NULL); 322 if (bRes) 323 { 324 lpBuffer[BytesRead / 2] = 0; 325 } 326 else 327 { 328 HeapFree(GetProcessHeap(), 329 0, 330 lpBuffer); 331 332 lpBuffer = NULL; 333 } 334 } 335 } 336 } 337 338 return lpBuffer; 339 } 340 341 342 static HANDLE 343 OpenRdpFile(LPWSTR path, BOOL bWrite) 344 { 345 HANDLE hFile = NULL; 346 347 if (path) 348 { 349 hFile = CreateFileW(path, 350 bWrite ? GENERIC_WRITE : GENERIC_READ, 351 0, 352 NULL, 353 bWrite ? CREATE_ALWAYS : OPEN_EXISTING, 354 FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_HIDDEN, 355 NULL); 356 } 357 358 return hFile; 359 } 360 361 362 static VOID 363 CloseRdpFile(HANDLE hFile) 364 { 365 if (hFile) 366 CloseHandle(hFile); 367 } 368 369 370 BOOL 371 SaveRdpSettingsToFile(LPWSTR lpFile, 372 PRDPSETTINGS pRdpSettings) 373 { 374 WCHAR pszPath[MAX_PATH]; 375 HANDLE hFile; 376 BOOL bRet = FALSE; 377 378 /* use default file */ 379 if (lpFile == NULL) 380 { 381 HRESULT hr; 382 LPITEMIDLIST lpidl= NULL; 383 384 hr = SHGetFolderLocation(NULL, 385 CSIDL_PERSONAL, 386 NULL, 387 0, 388 &lpidl); 389 if (hr == S_OK) 390 { 391 if (SHGetPathFromIDListW(lpidl, pszPath)) 392 { 393 wcscat(pszPath, L"\\Default.rdp"); 394 lpFile = pszPath; 395 CoTaskMemFree(lpidl); 396 } 397 } 398 } 399 400 if (lpFile) 401 { 402 hFile = OpenRdpFile(lpFile, TRUE); 403 if (hFile) 404 { 405 if (WriteRdpFile(hFile, pRdpSettings)) 406 { 407 bRet = TRUE; 408 } 409 410 CloseRdpFile(hFile); 411 } 412 } 413 414 return bRet; 415 } 416 417 418 BOOL 419 LoadRdpSettingsFromFile(PRDPSETTINGS pRdpSettings, 420 LPWSTR lpFile) 421 { 422 WCHAR pszPath[MAX_PATH]; 423 HANDLE hFile; 424 BOOL bRet = FALSE; 425 426 /* use default file */ 427 if (lpFile == NULL) 428 { 429 HRESULT hr; 430 LPITEMIDLIST lpidl= NULL; 431 432 hr = SHGetFolderLocation(NULL, 433 CSIDL_PERSONAL, 434 NULL, 435 0, 436 &lpidl); 437 if (hr == S_OK) 438 { 439 if (SHGetPathFromIDListW(lpidl, pszPath)) 440 { 441 wcscat(pszPath, L"\\Default.rdp"); 442 lpFile = pszPath; 443 CoTaskMemFree(lpidl); 444 } 445 } 446 } 447 448 if (lpFile) 449 { 450 LPWSTR lpBuffer = NULL; 451 452 hFile = OpenRdpFile(lpFile, FALSE); 453 if (hFile) 454 { 455 lpBuffer = ReadRdpFile(hFile); 456 if (lpBuffer) 457 { 458 ParseSettings(pRdpSettings, lpBuffer); 459 460 HeapFree(GetProcessHeap(), 461 0, 462 lpBuffer); 463 464 bRet = TRUE; 465 } 466 467 CloseRdpFile(hFile); 468 } 469 } 470 471 return bRet; 472 } 473 474 475 BOOL 476 InitRdpSettings(PRDPSETTINGS pRdpSettings) 477 { 478 BOOL bRet = FALSE; 479 480 pRdpSettings->pSettings = HeapAlloc(GetProcessHeap(), 481 0, 482 sizeof(SETTINGS) * NUM_SETTINGS); 483 if (pRdpSettings->pSettings) 484 { 485 INT i; 486 487 for (i = 0; i < NUM_SETTINGS; i++) 488 { 489 wcscpy(pRdpSettings->pSettings[i].Key, lpSettings[i]); 490 pRdpSettings->pSettings[i].Type = (WCHAR)0; 491 pRdpSettings->pSettings[i].Value.i = 0; 492 } 493 494 pRdpSettings->NumSettings = NUM_SETTINGS; 495 496 bRet = TRUE; 497 } 498 499 return bRet; 500 } 501