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