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
SaveAllSettings(PINFO pInfo)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
SetIntegerToSettings(PRDPSETTINGS pRdpSettings,LPWSTR lpKey,INT Value)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
SetStringToSettings(PRDPSETTINGS pRdpSettings,LPWSTR lpKey,LPWSTR lpValue)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
GetIntegerFromSettings(PRDPSETTINGS pRdpSettings,LPWSTR lpKey)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
GetStringFromSettings(PRDPSETTINGS pRdpSettings,LPWSTR lpKey)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
WriteRdpFile(HANDLE hFile,PRDPSETTINGS pRdpSettings)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
ParseSettings(PRDPSETTINGS pRdpSettings,LPWSTR lpBuffer)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
ReadRdpFile(HANDLE hFile)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
OpenRdpFile(LPWSTR path,BOOL bWrite)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
CloseRdpFile(HANDLE hFile)363 CloseRdpFile(HANDLE hFile)
364 {
365 if (hFile)
366 CloseHandle(hFile);
367 }
368
369
370 BOOL
SaveRdpSettingsToFile(LPWSTR lpFile,PRDPSETTINGS pRdpSettings)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
LoadRdpSettingsFromFile(PRDPSETTINGS pRdpSettings,LPWSTR lpFile)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
InitRdpSettings(PRDPSETTINGS pRdpSettings)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