xref: /reactos/base/applications/mstsc/settings.c (revision 40462c92)
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