add parameter dcerpc_info to PIDL_dissect_ipv?address()
[wireshark-wip.git] / ui / win32 / file_dlg_win32.c
blobb53ef90562319969045c8790b49b2cd6460067d5
1 /* win32-file-dlg.c
2 * Native Windows file dialog routines
4 * $Id$
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 2004 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "config.h"
27 #include <stdio.h>
28 #include <tchar.h>
29 #include <wchar.h>
30 #include <stdlib.h>
31 #include <sys/stat.h>
32 #include <io.h>
33 #include <fcntl.h>
35 #include <windows.h>
36 #include <windowsx.h>
37 #include <commdlg.h>
38 #include <richedit.h>
39 #include <strsafe.h>
41 #include "file.h"
43 #include "wsutil/file_util.h"
44 #include "wsutil/unicode-utils.h"
46 #include "wiretap/merge.h"
48 #include "epan/filesystem.h"
49 #include "epan/addr_resolv.h"
50 #include "epan/prefs.h"
51 #include "epan/print.h"
53 #include "color.h"
54 #include "color_filters.h"
56 #include "ui/alert_box.h"
57 #include "ui/help_url.h"
58 #include "ui/file_dialog.h"
59 #include "ui/last_open_dir.h"
60 #include "ui/simple_dialog.h"
61 #include "ui/ssl_key_export.h"
62 #include "ui/util.h"
64 #include "file_dlg_win32.h"
66 #define FILE_OPEN_DEFAULT 1 /* All Files */
68 #define FILE_MERGE_DEFAULT FILE_OPEN_DEFAULT
70 #define FILE_TYPES_EXPORT \
71 _T("Plain text (*.txt)\0") _T("*.txt\0") \
72 _T("PostScript (*.ps)\0") _T("*.ps\0") \
73 _T("CSV (Comma Separated Values summary) (*.csv)\0") _T("*.csv\0") \
74 _T("PSML (XML packet summary) (*.psml)\0") _T("*.psml\0") \
75 _T("PDML (XML packet detail) (*.pdml)\0") _T("*.pdml\0") \
76 _T("C Arrays (packet bytes) (*.c)\0") _T("*.c\0")
78 #define FILE_TYPES_RAW \
79 _T("Raw data (*.bin, *.dat, *.raw)\0") _T("*.bin;*.dat;*.raw\0") \
80 _T("All Files (*.*)\0") _T("*.*\0")
82 #define FILE_RAW_DEFAULT 1
84 #define FILE_TYPES_SSLKEYS \
85 _T("SSL Session Keys (*.keys)\0") _T("*.keys\0") \
86 _T("All Files (*.*)\0") _T("*.*\0")
88 #define FILE_SSLKEYS_DEFAULT 1
90 #define FILE_TYPES_COLOR \
91 _T("Text Files (*.txt)\0") _T("*.txt\0") \
92 _T("All Files (*.*)\0") _T("*.*\0")
94 #define FILE_DEFAULT_COLOR 2
96 static UINT_PTR CALLBACK open_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
97 static UINT_PTR CALLBACK save_as_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
98 static UINT_PTR CALLBACK export_specified_packets_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
99 static UINT_PTR CALLBACK merge_file_hook_proc(HWND mf_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
100 static UINT_PTR CALLBACK export_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
101 static UINT_PTR CALLBACK export_raw_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
102 static UINT_PTR CALLBACK export_sslkeys_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
103 static void range_update_dynamics(HWND sf_hwnd, packet_range_t *range);
104 static void range_handle_wm_initdialog(HWND dlg_hwnd, packet_range_t *range);
105 static void range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, packet_range_t *range);
107 static TCHAR *build_file_open_type_list(void);
108 static TCHAR *build_file_save_type_list(GArray *savable_file_types);
110 static int g_filetype;
111 static gboolean g_compressed;
112 static packet_range_t *g_range;
113 static capture_file *g_cf;
114 static merge_action_e g_merge_action;
115 static print_args_t print_args;
116 /* XXX - The reason g_sf_hwnd exists is so that we can call
117 * range_update_dynamics() from anywhere; it's currently
118 * static, but if we move to using the native Windows
119 * print dialog and put range widgets in it as well,
120 * it might be moved to a separate file.
122 * However, the save file dialog hogs the foreground, so
123 * this may not be necessary (and, in fact, the file dialogs
124 * should arguably be modal to the window for the file
125 * being opened/saved/etc.).
127 static HWND g_sf_hwnd = NULL;
128 static char *g_dfilter_str = NULL;
130 static int
131 win32_get_ofnsize()
133 gboolean bVerGE5 = FALSE;
134 int ofnsize;
135 /* Remarks on OPENFILENAME_SIZE_VERSION_400:
137 * MSDN states that OPENFILENAME_SIZE_VERSION_400 should be used with
138 * WINVER and _WIN32_WINNT >= 0x0500.
139 * Unfortunately all these are compiler constants, while the underlying is a
140 * problem based is a length check of the runtime version used.
142 * Instead of using OPENFILENAME_SIZE_VERSION_400, just malloc
143 * the OPENFILENAME size plus 12 bytes.
144 * These 12 bytes are the difference between the two versions of this struct.
146 * Interestingly this fixes a bug, so the places bar e.g. "My Documents"
147 * is displayed - which wasn't the case with the former implementation.
149 * XXX - It's unclear if this length+12 works on all supported platforms,
150 * NT4 is the question here. However, even if it fails, we must calculate
151 * the length based on the runtime, not the compiler version anyway ...
153 /* This assumption does not work when compiling with MSVC2008EE as
154 * the open dialog window does not appear.
155 * Instead detect Windows version at runtime and choose size accordingly */
156 #if (_MSC_VER >= 1500)
158 * On VS2103, GetVersionEx is deprecated. Microsoft recommend to
159 * use VerifyVersionInfo instead
161 #if (_MSC_VER >= 1800)
162 OSVERSIONINFOEX osvi;
163 DWORDLONG dwlConditionMask = 0;
164 int op = VER_GREATER_EQUAL;
165 /* Initialize the OSVERSIONINFOEX structure. */
166 SecureZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
167 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
168 osvi.dwMajorVersion = 5;
169 /* Initialize the condition mask. */
170 VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
171 /* Perform the test. */
172 bVerGE5=VerifyVersionInfo(
173 &osvi,
174 VER_MAJORVERSION,
175 dwlConditionMask);
176 #else
177 OSVERSIONINFO osvi;
178 SecureZeroMemory(&osvi, sizeof(OSVERSIONINFO));
179 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
180 GetVersionEx(&osvi);
181 bVerGE5 = (osvi.dwMajorVersion >= 5);
182 #endif /* _MSC_VER >= 1800 */
183 ofnsize = (bVerGE5)?sizeof(OPENFILENAME):OPENFILENAME_SIZE_VERSION_400;
184 #else
185 ofnsize = sizeof(OPENFILENAME)+12;
186 #endif /* _MSC_VER >= 1500 */
187 return ofnsize;
190 * According to http://msdn.microsoft.com/en-us/library/bb776913.aspx
191 * we should use IFileOpenDialog and IFileSaveDialog on Windows Vista
192 * and later.
195 gboolean
196 win32_open_file (HWND h_wnd, GString *file_name, GString *display_filter) {
197 OPENFILENAME *ofn;
198 TCHAR file_name16[MAX_PATH] = _T("");
199 int ofnsize;
200 gboolean gofn_ok;
202 if (!file_name || !display_filter)
203 return FALSE;
205 if (file_name->len > 0) {
206 StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
209 if (display_filter->len > 0) {
210 g_dfilter_str = g_strdup(display_filter->str);
211 } else if (g_dfilter_str) {
212 g_free(g_dfilter_str);
213 g_dfilter_str = NULL;
215 ofnsize = win32_get_ofnsize();
216 ofn = g_malloc0(ofnsize);
218 ofn->lStructSize = ofnsize;
219 ofn->hwndOwner = h_wnd;
220 ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
221 ofn->lpstrFilter = build_file_open_type_list();
222 ofn->lpstrCustomFilter = NULL;
223 ofn->nMaxCustFilter = 0;
224 ofn->nFilterIndex = FILE_OPEN_DEFAULT;
225 ofn->lpstrFile = file_name16;
226 ofn->nMaxFile = MAX_PATH;
227 ofn->lpstrFileTitle = NULL;
228 ofn->nMaxFileTitle = 0;
229 if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') {
230 ofn->lpstrInitialDir = utf_8to16(prefs.gui_fileopen_dir);
231 } else {
232 ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
234 ofn->lpstrTitle = _T("Wireshark: Open Capture File");
235 ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
236 OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
237 OFN_ENABLEHOOK | OFN_SHOWHELP;
238 ofn->lpstrDefExt = NULL;
239 ofn->lpfnHook = open_file_hook_proc;
240 ofn->lpTemplateName = _T("WIRESHARK_OPENFILENAME_TEMPLATE");
242 gofn_ok = GetOpenFileName(ofn);
244 if (gofn_ok) {
245 g_string_printf(file_name, "%s", utf_16to8(file_name16));
246 g_string_printf(display_filter, "%s", g_dfilter_str ? g_dfilter_str : "");
249 g_free( (void *) ofn->lpstrFilter);
250 g_free( (void *) ofn);
251 g_free(g_dfilter_str);
252 g_dfilter_str = NULL;
253 return gofn_ok;
256 check_savability_t
257 win32_check_save_as_with_comments(HWND parent, capture_file *cf, int file_type)
259 guint32 comment_types;
260 gint response;
262 /* What types of comments do we have? */
263 comment_types = cf_comment_types(cf);
265 /* Does the file's format support all the comments we have? */
266 if (wtap_dump_supports_comment_types(cf->cd_t, comment_types)) {
267 /* Yes. Let the save happen; we can save all the comments, so
268 there's no need to delete them. */
269 return SAVE;
272 /* No. Are there formats in which we can write this file that
273 supports all the comments in this file? */
274 if (wtap_dump_can_write(cf->linktypes, comment_types)) {
275 /* Yes. Offer the user a choice of "Save in a format that
276 supports comments", "Discard comments and save in the
277 format you selected", or "Cancel", meaning "don't bother
278 saving the file at all".
280 XXX - sadly, customizing buttons in a MessageBox() is
281 Really Painful; there are tricks out there to do it
282 with a "computer-based training" hook that gets called
283 before the window is activated and sets the text of the
284 buttons, but if you change the text of the buttons you
285 also have to make the buttons bigger. There *has* to
286 be a better way of doing that, given that Microsoft's
287 own UI guidelines have examples of dialog boxes with
288 action buttons that have custom labels, but maybe we'd
289 have to go with Windows Forms or XAML or whatever the
290 heck the technology of the week is.
292 Therefore, we ask a yes-or-no question - "do you want
293 to discard the comments and save in the format you
294 chose?" - and have "no" mean "I want to save the
295 file but I don't want to discard the comments, meaning
296 we should reopen the dialog and not offer the user any
297 choices that would involve discarding the comments. */
298 response = MessageBox(parent,
299 _T("The capture has comments, but the file format you chose ")
300 _T("doesn't support comments. Do you want to discard the comments ")
301 _T("and save in the format you chose?"),
302 _T("Wireshark: Save File As"),
303 MB_YESNOCANCEL|MB_ICONWARNING|MB_DEFBUTTON2);
304 } else {
305 /* No. Offer the user a choice of "Discard comments and
306 save in the format you selected" or "Cancel".
308 XXX - see rant above. */
309 response = MessageBox(parent,
310 _T("The capture has comments, but no file format in which it ")
311 _T("can be saved supports comments. Do you want to discard ")
312 _T("the comments and save in the format you chose?"),
313 _T("Wireshark: Save File As"),
314 MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2);
317 switch (response) {
319 case IDNO: /* "No" means "Save in another format" in the first dialog */
320 /* OK, the only other format we support is pcap-ng. Make that
321 the one and only format in the combo box, and return to
322 let the user continue with the dialog.
324 XXX - removing all the formats from the combo box will clear
325 the compressed checkbox; get the current value and restore
328 XXX - we know pcap-ng can be compressed; if we ever end up
329 supporting saving comments in a format that *can't* be
330 compressed, such as NetMon format, we must check this. */
331 /* XXX - need a compressed checkbox here! */
332 return SAVE_IN_ANOTHER_FORMAT;
334 case IDYES: /* "Yes" means "Discard comments and save" in the first dialog */
335 case IDOK: /* "OK" means "Discard comments and save" in the second dialog */
336 /* Save without the comments and, if that succeeds, delete the
337 comments. */
338 return SAVE_WITHOUT_COMMENTS;
340 case IDCANCEL:
341 default:
342 /* Just give up. */
343 return CANCELLED;
347 gboolean
348 win32_save_as_file(HWND h_wnd, capture_file *cf, GString *file_name, int *file_type,
349 gboolean *compressed, gboolean must_support_all_comments)
351 guint32 required_comment_types;
352 GArray *savable_file_types;
353 OPENFILENAME *ofn;
354 TCHAR file_name16[MAX_PATH] = _T("");
355 int ofnsize;
356 gboolean gsfn_ok;
357 gboolean discard_comments = FALSE;
359 if (!file_name || !file_type || !compressed)
360 return FALSE;
362 if (file_name->len > 0) {
363 StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
366 /* What types of comments do we have to support? */
367 if (must_support_all_comments)
368 required_comment_types = cf_comment_types(cf); /* all the ones the file has */
369 else
370 required_comment_types = 0; /* none of them */
372 savable_file_types = wtap_get_savable_file_types_subtypes(cf->cd_t,
373 cf->linktypes,
374 required_comment_types);
375 if (savable_file_types == NULL)
376 return FALSE; /* shouldn't happen - the "Save As..." item should be disabled if we can't save the file */
377 g_compressed = FALSE;
379 ofnsize = win32_get_ofnsize();
380 ofn = g_malloc0(ofnsize);
382 ofn->lStructSize = ofnsize;
383 ofn->hwndOwner = h_wnd;
384 ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
385 ofn->lpstrFilter = build_file_save_type_list(savable_file_types);
386 ofn->lpstrCustomFilter = NULL;
387 ofn->nMaxCustFilter = 0;
388 ofn->nFilterIndex = 1; /* the first entry is the best match; 1-origin indexing */
389 ofn->lpstrFile = file_name16;
390 ofn->nMaxFile = MAX_PATH;
391 ofn->lpstrFileTitle = NULL;
392 ofn->nMaxFileTitle = 0;
393 ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
394 ofn->lpstrTitle = _T("Wireshark: Save file as");
395 ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
396 OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
397 OFN_PATHMUSTEXIST | OFN_ENABLEHOOK | OFN_SHOWHELP;
398 ofn->lpstrDefExt = NULL;
399 ofn->lCustData = (LPARAM) cf;
400 ofn->lpfnHook = save_as_file_hook_proc;
401 ofn->lpTemplateName = _T("WIRESHARK_SAVEASFILENAME_TEMPLATE");
403 gsfn_ok = GetSaveFileName(ofn);
405 if (gsfn_ok) {
406 g_string_printf(file_name, "%s", utf_16to8(file_name16));
407 /* What file format was specified? */
408 *file_type = g_array_index(savable_file_types, int, ofn->nFilterIndex - 1);
409 *compressed = g_compressed;
410 } else {
411 /* User cancelled or closed the dialog, or an error occurred. */
412 if (CommDlgExtendedError() != 0) {
413 /* XXX - pop up some error here. FNERR_INVALIDFILENAME
414 * might be a user error; if so, they should know about
415 * it. For now we force a do-over.
417 g_string_truncate(file_name, 0);
418 gsfn_ok = TRUE;
422 g_sf_hwnd = NULL;
423 g_array_free(savable_file_types, TRUE);
424 g_free( (void *) ofn->lpstrFilter);
425 g_free( (void *) ofn);
426 return gsfn_ok;
429 gboolean
430 win32_export_specified_packets_file(HWND h_wnd, capture_file *cf,
431 GString *file_name,
432 int *file_type,
433 gboolean *compressed,
434 packet_range_t *range) {
435 GArray *savable_file_types;
436 OPENFILENAME *ofn;
437 TCHAR file_name16[MAX_PATH] = _T("");
438 int ofnsize;
439 gboolean gsfn_ok;
441 if (!file_name || !file_type || !compressed || !range)
442 return FALSE;
444 if (file_name->len > 0) {
445 StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
448 savable_file_types = wtap_get_savable_file_types_subtypes(cf->cd_t,
449 cf->linktypes, 0);
450 if (savable_file_types == NULL)
451 return FALSE; /* shouldn't happen - the "Save As..." item should be disabled if we can't save the file */
453 g_range = range;
454 g_cf = cf;
455 g_compressed = FALSE;
457 ofnsize = win32_get_ofnsize();
458 ofn = g_malloc0(ofnsize);
460 ofn->lStructSize = ofnsize;
461 ofn->hwndOwner = h_wnd;
462 ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
463 ofn->lpstrFilter = build_file_save_type_list(savable_file_types);
464 ofn->lpstrCustomFilter = NULL;
465 ofn->nMaxCustFilter = 0;
466 ofn->nFilterIndex = 1; /* the first entry is the best match; 1-origin indexing */
467 ofn->lpstrFile = file_name16;
468 ofn->nMaxFile = MAX_PATH;
469 ofn->lpstrFileTitle = NULL;
470 ofn->nMaxFileTitle = 0;
471 ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
472 ofn->lpstrTitle = _T("Wireshark: Export Specified Packets");
473 ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
474 OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
475 OFN_PATHMUSTEXIST | OFN_ENABLEHOOK | OFN_SHOWHELP;
476 ofn->lpstrDefExt = NULL;
477 ofn->lCustData = (LPARAM) cf;
478 ofn->lpfnHook = export_specified_packets_file_hook_proc;
479 ofn->lpTemplateName = _T("WIRESHARK_EXPORT_SPECIFIED_PACKETS_FILENAME_TEMPLATE");
481 gsfn_ok = GetSaveFileName(ofn);
483 if (gsfn_ok) {
484 g_string_printf(file_name, "%s", utf_16to8(file_name16));
485 /* What file format was specified? */
486 *file_type = g_array_index(savable_file_types, int, ofn->nFilterIndex - 1);
487 *compressed = g_compressed;
488 } else {
489 /* User cancelled or closed the dialog, or an error occurred. */
490 if (CommDlgExtendedError() != 0) {
491 /* XXX - pop up some error here. FNERR_INVALIDFILENAME
492 * might be a user error; if so, they should know about
493 * it. For now we force a do-over.
495 g_string_truncate(file_name, 0);
496 gsfn_ok = TRUE;
500 g_sf_hwnd = NULL;
501 g_range = NULL;
502 g_cf = NULL;
503 g_array_free(savable_file_types, TRUE);
504 g_free( (void *) ofn->lpstrFilter);
505 g_free( (void *) ofn);
506 return gsfn_ok;
510 gboolean
511 win32_merge_file (HWND h_wnd, GString *file_name, GString *display_filter, int *merge_type) {
512 OPENFILENAME *ofn;
513 TCHAR file_name16[MAX_PATH] = _T("");
514 int ofnsize;
515 gboolean gofn_ok;
517 if (!file_name || !display_filter || !merge_type)
518 return FALSE;
520 if (file_name->len > 0) {
521 StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
524 if (display_filter->len > 0) {
525 g_dfilter_str = g_strdup(display_filter->str);
526 } else if (g_dfilter_str) {
527 g_free(g_dfilter_str);
528 g_dfilter_str = NULL;
531 ofnsize = win32_get_ofnsize();
532 ofn = g_malloc0(ofnsize);
534 ofn->lStructSize = ofnsize;
535 ofn->hwndOwner = h_wnd;
536 ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
537 ofn->lpstrFilter = build_file_open_type_list();
538 ofn->lpstrCustomFilter = NULL;
539 ofn->nMaxCustFilter = 0;
540 ofn->nFilterIndex = FILE_MERGE_DEFAULT;
541 ofn->lpstrFile = file_name16;
542 ofn->nMaxFile = MAX_PATH;
543 ofn->lpstrFileTitle = NULL;
544 ofn->nMaxFileTitle = 0;
545 if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') {
546 ofn->lpstrInitialDir = utf_8to16(prefs.gui_fileopen_dir);
547 } else {
548 ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
550 ofn->lpstrTitle = _T("Wireshark: Merge with capture file");
551 ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
552 OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
553 OFN_ENABLEHOOK | OFN_SHOWHELP;
554 ofn->lpstrDefExt = NULL;
555 ofn->lpfnHook = merge_file_hook_proc;
556 ofn->lpTemplateName = _T("WIRESHARK_MERGEFILENAME_TEMPLATE");
558 gofn_ok = GetOpenFileName(ofn);
560 if (gofn_ok) {
561 g_string_printf(file_name, "%s", utf_16to8(file_name16));
562 g_string_printf(display_filter, "%s", g_dfilter_str ? g_dfilter_str : "");
564 switch (g_merge_action) {
565 case merge_append:
566 *merge_type = 1;
567 break;
568 case merge_chrono:
569 *merge_type = 0;
570 break;
571 case merge_prepend:
572 *merge_type = -1;
573 break;
574 default:
575 g_assert_not_reached();
579 g_free( (void *) ofn->lpstrFilter);
580 g_free( (void *) ofn);
581 g_free(g_dfilter_str);
582 g_dfilter_str = NULL;
583 return gofn_ok;
586 void
587 win32_export_file(HWND h_wnd, capture_file *cf, export_type_e export_type) {
588 OPENFILENAME *ofn;
589 TCHAR file_name[MAX_PATH] = _T("");
590 char *dirname;
591 cf_print_status_t status;
592 int ofnsize;
594 g_cf = cf;
596 ofnsize = win32_get_ofnsize();
597 ofn = g_malloc0(ofnsize);
599 ofn->lStructSize = ofnsize;
600 ofn->hwndOwner = h_wnd;
601 ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
602 ofn->lpstrFilter = FILE_TYPES_EXPORT;
603 ofn->lpstrCustomFilter = NULL;
604 ofn->nMaxCustFilter = 0;
605 ofn->nFilterIndex = export_type;
606 ofn->lpstrFile = file_name;
607 ofn->nMaxFile = MAX_PATH;
608 ofn->lpstrFileTitle = NULL;
609 ofn->nMaxFileTitle = 0;
610 ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
611 ofn->lpstrTitle = _T("Wireshark: Export File");
612 ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
613 OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
614 OFN_PATHMUSTEXIST | OFN_ENABLEHOOK | OFN_SHOWHELP;
615 ofn->lpstrDefExt = NULL;
616 ofn->lCustData = (LPARAM) cf;
617 ofn->lpfnHook = export_file_hook_proc;
618 ofn->lpTemplateName = _T("WIRESHARK_EXPORTFILENAME_TEMPLATE");
620 /* Fill in our print (and export) args */
622 print_args.format = PR_FMT_TEXT;
623 print_args.to_file = TRUE;
624 print_args.cmd = NULL;
625 print_args.print_summary = TRUE;
626 print_args.print_col_headings = TRUE;
627 print_args.print_dissections = print_dissections_as_displayed;
628 print_args.print_hex = FALSE;
629 print_args.print_formfeed = FALSE;
631 if (GetSaveFileName(ofn)) {
632 print_args.file = utf_16to8(file_name);
633 switch (ofn->nFilterIndex) {
634 case export_type_text: /* Text */
635 print_args.stream = print_stream_text_new(TRUE, print_args.file);
636 if (print_args.stream == NULL) {
637 open_failure_alert_box(print_args.file, errno, TRUE);
638 g_free( (void *) ofn);
639 return;
641 status = cf_print_packets(cf, &print_args);
642 break;
643 case export_type_ps: /* PostScript (r) */
644 print_args.stream = print_stream_ps_new(TRUE, print_args.file);
645 if (print_args.stream == NULL) {
646 open_failure_alert_box(print_args.file, errno, TRUE);
647 g_free( (void *) ofn);
648 return;
650 status = cf_print_packets(cf, &print_args);
651 break;
652 case export_type_csv: /* CSV */
653 status = cf_write_csv_packets(cf, &print_args);
654 break;
655 case export_type_carrays: /* C Arrays */
656 status = cf_write_carrays_packets(cf, &print_args);
657 break;
658 case export_type_psml: /* PSML */
659 status = cf_write_psml_packets(cf, &print_args);
660 break;
661 case export_type_pdml: /* PDML */
662 status = cf_write_pdml_packets(cf, &print_args);
663 break;
664 default:
665 g_free( (void *) ofn);
666 return;
669 switch (status) {
670 case CF_PRINT_OK:
671 break;
672 case CF_PRINT_OPEN_ERROR:
673 open_failure_alert_box(print_args.file, errno, TRUE);
674 break;
675 case CF_PRINT_WRITE_ERROR:
676 write_failure_alert_box(print_args.file, errno);
677 break;
679 /* Save the directory name for future file dialogs. */
680 dirname = get_dirname(utf_16to8(file_name)); /* Overwrites cf_name */
681 set_last_open_dir(dirname);
684 g_cf = NULL;
685 g_free( (void *) ofn);
688 void
689 win32_export_raw_file(HWND h_wnd, capture_file *cf) {
690 OPENFILENAME *ofn;
691 TCHAR file_name[MAX_PATH] = _T("");
692 char *dirname;
693 const guint8 *data_p;
694 char *file_name8;
695 int fd;
696 int ofnsize;
698 if (!cf->finfo_selected) {
699 /* This shouldn't happen */
700 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No bytes were selected.");
701 return;
704 ofnsize = win32_get_ofnsize();
705 ofn = g_malloc0(ofnsize);
707 ofn->lStructSize = ofnsize;
708 ofn->hwndOwner = h_wnd;
709 ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
710 ofn->lpstrFilter = FILE_TYPES_RAW;
711 ofn->lpstrCustomFilter = NULL;
712 ofn->nMaxCustFilter = 0;
713 ofn->nFilterIndex = FILE_RAW_DEFAULT;
714 ofn->lpstrFile = file_name;
715 ofn->nMaxFile = MAX_PATH;
716 ofn->lpstrFileTitle = NULL;
717 ofn->nMaxFileTitle = 0;
718 ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
719 ofn->lpstrTitle = _T("Wireshark: Export Raw Data");
720 ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
721 OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
722 OFN_PATHMUSTEXIST | OFN_ENABLEHOOK | OFN_SHOWHELP;
723 ofn->lpstrDefExt = NULL;
724 ofn->lCustData = cf->finfo_selected->length;
725 ofn->lpfnHook = export_raw_file_hook_proc;
726 ofn->lpTemplateName = _T("WIRESHARK_EXPORTRAWFILENAME_TEMPLATE");
729 * XXX - The GTK+ code uses get_byte_view_data_and_length(). We just
730 * grab the info from cf->finfo_selected. Which is more "correct"?
733 if (GetSaveFileName(ofn)) {
734 g_free( (void *) ofn);
735 file_name8 = utf_16to8(file_name);
736 data_p = tvb_get_ptr(cf->finfo_selected->ds_tvb, 0, -1) +
737 cf->finfo_selected->start;
738 fd = ws_open(file_name8, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
739 if (fd == -1) {
740 open_failure_alert_box(file_name8, errno, TRUE);
741 return;
743 if (write(fd, data_p, cf->finfo_selected->length) < 0) {
744 write_failure_alert_box(file_name8, errno);
745 close(fd);
746 return;
748 if (close(fd) < 0) {
749 write_failure_alert_box(file_name8, errno);
750 return;
753 /* Save the directory name for future file dialogs. */
754 dirname = get_dirname(file_name8); /* Overwrites cf_name */
755 set_last_open_dir(dirname);
756 } else {
757 g_free( (void *) ofn);
761 void
762 win32_export_sslkeys_file(HWND h_wnd) {
763 OPENFILENAME *ofn;
764 TCHAR file_name[MAX_PATH] = _T("");
765 char *dirname;
766 gchar *keylist;
767 char *file_name8;
768 int fd;
769 int ofnsize;
770 int keylist_size;
772 keylist_size = ssl_session_key_count();
773 if (keylist_size==0) {
774 /* This shouldn't happen */
775 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No SSL Session Keys to export.");
776 return;
779 ofnsize = win32_get_ofnsize();
780 ofn = g_malloc0(ofnsize);
782 ofn->lStructSize = ofnsize;
783 ofn->hwndOwner = h_wnd;
784 ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
785 ofn->lpstrFilter = FILE_TYPES_SSLKEYS;
786 ofn->lpstrCustomFilter = NULL;
787 ofn->nMaxCustFilter = 0;
788 ofn->nFilterIndex = FILE_SSLKEYS_DEFAULT;
789 ofn->lpstrFile = file_name;
790 ofn->nMaxFile = MAX_PATH;
791 ofn->lpstrFileTitle = NULL;
792 ofn->nMaxFileTitle = 0;
793 ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
794 ofn->lpstrTitle = _T("Wireshark: Export SSL Session Keys");
795 ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
796 OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
797 OFN_PATHMUSTEXIST | OFN_ENABLEHOOK | OFN_SHOWHELP;
798 ofn->lpstrDefExt = NULL;
799 ofn->lCustData = keylist_size;
800 ofn->lpfnHook = export_sslkeys_file_hook_proc;
801 ofn->lpTemplateName = _T("WIRESHARK_EXPORTSSLKEYSFILENAME_TEMPLATE");
803 if (GetSaveFileName(ofn)) {
804 g_free( (void *) ofn);
805 file_name8 = utf_16to8(file_name);
806 keylist = ssl_export_sessions();
807 fd = ws_open(file_name8, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
808 if (fd == -1) {
809 open_failure_alert_box(file_name8, errno, TRUE);
810 g_free(keylist);
811 return;
814 * Thanks, Microsoft, for not using size_t for the third argument to
815 * _write(). Presumably this string will be <= 4GiB long....
817 if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) {
818 write_failure_alert_box(file_name8, errno);
819 ws_close(fd);
820 g_free(keylist);
821 return;
823 if (ws_close(fd) < 0) {
824 write_failure_alert_box(file_name8, errno);
825 g_free(keylist);
826 return;
829 /* Save the directory name for future file dialogs. */
830 dirname = get_dirname(file_name8); /* Overwrites cf_name */
831 set_last_open_dir(dirname);
832 } else {
833 g_free( (void *) ofn);
835 g_free(keylist);
838 void
839 win32_export_color_file(HWND h_wnd, capture_file *cf, gpointer filter_list) {
840 OPENFILENAME *ofn;
841 TCHAR file_name[MAX_PATH] = _T("");
842 gchar *dirname;
843 int ofnsize;
845 ofnsize = win32_get_ofnsize();
846 ofn = g_malloc0(ofnsize);
848 ofn->lStructSize = ofnsize;
849 ofn->hwndOwner = h_wnd;
850 ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
851 ofn->lpstrFilter = FILE_TYPES_COLOR;
852 ofn->lpstrCustomFilter = NULL;
853 ofn->nMaxCustFilter = 0;
854 ofn->nFilterIndex = FILE_DEFAULT_COLOR;
855 ofn->lpstrFile = file_name;
856 ofn->nMaxFile = MAX_PATH;
857 ofn->lpstrFileTitle = NULL;
858 ofn->nMaxFileTitle = 0;
859 ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
860 ofn->lpstrTitle = _T("Wireshark: Export Color Filters");
861 ofn->Flags = OFN_ENABLESIZING | OFN_EXPLORER |
862 OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
863 OFN_PATHMUSTEXIST | OFN_ENABLEHOOK;
864 ofn->lpstrDefExt = NULL;
865 ofn->lpfnHook = NULL;
866 ofn->lpTemplateName = NULL;
868 g_filetype = cf->cd_t;
870 /* XXX - Support marked filters */
871 if (GetSaveFileName(ofn)) {
872 g_free( (void *) ofn);
873 if (!color_filters_export(utf_16to8(file_name), filter_list, FALSE /* all filters */))
874 return;
876 /* Save the directory name for future file dialogs. */
877 dirname = get_dirname(utf_16to8(file_name)); /* Overwrites cf_name */
878 set_last_open_dir(dirname);
879 } else {
880 g_free( (void *) ofn);
884 void
885 win32_import_color_file(HWND h_wnd, gpointer color_filters) {
886 OPENFILENAME *ofn;
887 TCHAR file_name[MAX_PATH] = _T("");
888 gchar *dirname;
889 int ofnsize;
891 ofnsize = win32_get_ofnsize();
892 ofn = g_malloc0(ofnsize);
894 ofn->lStructSize = ofnsize;
895 ofn->hwndOwner = h_wnd;
896 ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
897 ofn->lpstrFilter = FILE_TYPES_COLOR;
898 ofn->lpstrCustomFilter = NULL;
899 ofn->nMaxCustFilter = 0;
900 ofn->nFilterIndex = FILE_DEFAULT_COLOR;
901 ofn->lpstrFile = file_name;
902 ofn->nMaxFile = MAX_PATH;
903 ofn->lpstrFileTitle = NULL;
904 ofn->nMaxFileTitle = 0;
905 ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
906 ofn->lpstrTitle = _T("Wireshark: Import Color Filters");
907 ofn->Flags = OFN_ENABLESIZING | OFN_EXPLORER |
908 OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
909 OFN_PATHMUSTEXIST | OFN_ENABLEHOOK;
910 ofn->lpstrDefExt = NULL;
911 ofn->lpfnHook = NULL;
912 ofn->lpTemplateName = NULL;
914 /* XXX - Support export limited to selected filters */
915 if (GetOpenFileName(ofn)) {
916 g_free( (void *) ofn);
917 if (!color_filters_import(utf_16to8(file_name), color_filters))
918 return;
920 /* Save the directory name for future file dialogs. */
921 dirname = get_dirname(utf_16to8(file_name)); /* Overwrites cf_name */
922 set_last_open_dir(dirname);
923 } else {
924 g_free( (void *) ofn);
930 * Private routines
933 /** Given a print_args_t struct, update a set of print/export format controls
934 * accordingly.
936 * @param dlg_hwnd HWND of the dialog in question.
937 * @param args Pointer to a print args struct.
939 static void
940 print_update_dynamic(HWND dlg_hwnd, print_args_t *args) {
941 HWND cur_ctrl;
943 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_SUMMARY_CB);
944 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
945 args->print_summary = TRUE;
946 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_COL_HEADINGS_CB);
947 EnableWindow(cur_ctrl, TRUE);
948 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
949 args->print_col_headings = TRUE;
950 else
951 args->print_col_headings = FALSE;
952 } else {
953 args->print_summary = FALSE;
954 args->print_col_headings = FALSE;
955 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_COL_HEADINGS_CB);
956 EnableWindow(cur_ctrl, FALSE);
959 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_CB);
960 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
961 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_COMBO);
962 switch (SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0)) {
963 case 0:
964 args->print_dissections = print_dissections_collapsed;
965 break;
966 case 1:
967 args->print_dissections = print_dissections_as_displayed;
968 break;
969 case 2:
970 args->print_dissections = print_dissections_expanded;
971 break;
972 default:
973 g_assert_not_reached();
975 EnableWindow(cur_ctrl, TRUE);
976 } else {
977 args->print_dissections = print_dissections_none;
978 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_COMBO);
979 EnableWindow(cur_ctrl, FALSE);
982 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_BYTES_CB);
983 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
984 args->print_hex = TRUE;
985 else
986 args->print_hex = FALSE;
988 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_NEW_PAGE_CB);
989 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
990 args->print_formfeed = TRUE;
991 else
992 args->print_formfeed = FALSE;
995 static void
996 format_handle_wm_initdialog(HWND dlg_hwnd, print_args_t *args) {
997 HWND cur_ctrl;
999 /* Set the "Packet summary" and "Include column headings" boxes */
1000 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_SUMMARY_CB);
1001 SendMessage(cur_ctrl, BM_SETCHECK, args->print_summary, 0);
1002 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_COL_HEADINGS_CB);
1003 SendMessage(cur_ctrl, BM_SETCHECK, args->print_col_headings, 0);
1005 /* Set the "Packet details" box */
1006 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_CB);
1007 SendMessage(cur_ctrl, BM_SETCHECK, args->print_dissections != print_dissections_none, 0);
1009 /* Set the "Packet details" combo */
1010 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_COMBO);
1011 SendMessage(cur_ctrl, CB_ADDSTRING, 0, (WPARAM) _T("All collapsed"));
1012 SendMessage(cur_ctrl, CB_ADDSTRING, 0, (WPARAM) _T("As displayed"));
1013 SendMessage(cur_ctrl, CB_ADDSTRING, 0, (WPARAM) _T("All expanded"));
1015 switch (args->print_dissections) {
1016 case print_dissections_none:
1017 case print_dissections_collapsed:
1018 SendMessage(cur_ctrl, CB_SETCURSEL, 0, 0);
1019 break;
1020 case print_dissections_as_displayed:
1021 SendMessage(cur_ctrl, CB_SETCURSEL, 1, 0);
1022 break;
1023 case print_dissections_expanded:
1024 SendMessage(cur_ctrl, CB_SETCURSEL, 2, 0);
1025 default:
1026 g_assert_not_reached();
1029 /* Set the "Packet bytes" box */
1030 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_BYTES_CB);
1031 SendMessage(cur_ctrl, BM_SETCHECK, args->print_hex, 0);
1033 /* Set the "Each packet on a new page" box */
1034 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_NEW_PAGE_CB);
1035 SendMessage(cur_ctrl, BM_SETCHECK, args->print_formfeed, 0);
1037 print_update_dynamic(dlg_hwnd, args);
1041 #define PREVIEW_STR_MAX 200
1043 /* If preview_file is NULL, disable the elements. If not, enable and
1044 * show the preview info. */
1045 static gboolean
1046 preview_set_file_info(HWND of_hwnd, gchar *preview_file) {
1047 HWND cur_ctrl;
1048 int i;
1049 gboolean enable = FALSE;
1050 wtap *wth;
1051 const struct wtap_pkthdr *phdr;
1052 int err = 0;
1053 gchar *err_info;
1054 TCHAR string_buff[PREVIEW_STR_MAX];
1055 gint64 data_offset;
1056 guint packet = 0;
1057 gint64 filesize;
1058 time_t ti_time;
1059 struct tm *ti_tm;
1060 guint elapsed_time;
1061 time_t time_preview;
1062 time_t time_current;
1063 double start_time = 0;
1064 double stop_time = 0;
1065 double cur_time;
1066 gboolean is_breaked = FALSE;
1068 for (i = EWFD_PTX_FORMAT; i <= EWFD_PTX_ELAPSED; i++) {
1069 cur_ctrl = GetDlgItem(of_hwnd, i);
1070 if (cur_ctrl) {
1071 EnableWindow(cur_ctrl, FALSE);
1075 for (i = EWFD_PTX_FORMAT; i <= EWFD_PTX_ELAPSED; i++) {
1076 cur_ctrl = GetDlgItem(of_hwnd, i);
1077 if (cur_ctrl) {
1078 SetWindowText(cur_ctrl, _T("-"));
1082 if (preview_file == NULL || strlen(preview_file) < 1) {
1083 return FALSE;
1086 /* Format: directory */
1087 cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FORMAT);
1088 if (test_for_directory(preview_file) == EISDIR) {
1089 SetWindowText(cur_ctrl, _T("directory"));
1090 return FALSE;
1093 wth = wtap_open_offline(preview_file, &err, &err_info, TRUE);
1094 if (cur_ctrl && wth == NULL) {
1095 if(err == WTAP_ERR_FILE_UNKNOWN_FORMAT) {
1096 SetWindowText(cur_ctrl, _T("unknown file format"));
1097 } else {
1098 SetWindowText(cur_ctrl, _T("error opening file"));
1100 return FALSE;
1103 /* Success! */
1104 for (i = EWFD_PT_FORMAT; i <= EWFD_PTX_ELAPSED; i++) {
1105 cur_ctrl = GetDlgItem(of_hwnd, i);
1106 if (cur_ctrl) {
1107 EnableWindow(cur_ctrl, TRUE);
1111 /* Format */
1112 cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FORMAT);
1113 SetWindowText(cur_ctrl, utf_8to16(wtap_file_type_subtype_string(wtap_file_type_subtype(wth))));
1115 /* Size */
1116 filesize = wtap_file_size(wth, &err);
1117 utf_8to16_snprintf(string_buff, PREVIEW_STR_MAX, "%" G_GINT64_FORMAT " bytes", filesize);
1118 cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_SIZE);
1119 SetWindowText(cur_ctrl, string_buff);
1121 time(&time_preview);
1122 while ( (wtap_read(wth, &err, &err_info, &data_offset)) ) {
1123 phdr = wtap_phdr(wth);
1124 cur_time = nstime_to_sec( (const nstime_t *) &phdr->ts );
1125 if(packet == 0) {
1126 start_time = cur_time;
1127 stop_time = cur_time;
1129 if (cur_time < start_time) {
1130 start_time = cur_time;
1132 if (cur_time > stop_time){
1133 stop_time = cur_time;
1135 packet++;
1136 if(packet%100 == 0) {
1137 time(&time_current);
1138 if(time_current-time_preview >= (time_t) prefs.gui_fileopen_preview) {
1139 is_breaked = TRUE;
1140 break;
1145 if(err != 0) {
1146 StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("error after reading %u packets"), packet);
1147 cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_PACKETS);
1148 SetWindowText(cur_ctrl, string_buff);
1149 wtap_close(wth);
1150 return TRUE;
1153 /* Packets */
1154 if(is_breaked) {
1155 StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("more than %u packets (preview timeout)"), packet);
1156 } else {
1157 StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("%u"), packet);
1159 cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_PACKETS);
1160 SetWindowText(cur_ctrl, string_buff);
1162 /* First packet */
1163 ti_time = (long)start_time;
1164 ti_tm = localtime( &ti_time );
1165 if(ti_tm) {
1166 StringCchPrintf(string_buff, PREVIEW_STR_MAX,
1167 _T("%04d-%02d-%02d %02d:%02d:%02d"),
1168 ti_tm->tm_year + 1900,
1169 ti_tm->tm_mon + 1,
1170 ti_tm->tm_mday,
1171 ti_tm->tm_hour,
1172 ti_tm->tm_min,
1173 ti_tm->tm_sec);
1174 } else {
1175 StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("?"));
1177 cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FIRST_PKT);
1178 SetWindowText(cur_ctrl, string_buff);
1180 /* Elapsed time */
1181 elapsed_time = (unsigned int)(stop_time-start_time);
1182 if(elapsed_time/86400) {
1183 StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("%02u days %02u:%02u:%02u"),
1184 elapsed_time/86400, elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
1185 } else {
1186 StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("%02u:%02u:%02u"),
1187 elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
1189 if(is_breaked) {
1190 StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("unknown"));
1192 cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_ELAPSED);
1193 SetWindowText(cur_ctrl, string_buff);
1195 wtap_close(wth);
1197 return TRUE;
1202 static char *
1203 filter_tb_get(HWND hwnd) {
1204 TCHAR *strval = NULL;
1205 gint len;
1206 char *ret;
1208 /* If filter_text is non-NULL, use it. Otherwise, grab the text from
1209 * the window */
1210 len = GetWindowTextLength(hwnd);
1211 if (len > 0) {
1212 len++;
1213 strval = g_malloc(len*sizeof(TCHAR));
1214 len = GetWindowText(hwnd, strval, len);
1215 ret = g_utf16_to_utf8(strval, -1, NULL, NULL, NULL);
1216 g_free(strval);
1217 return ret;
1218 } else {
1219 return NULL;
1224 /* XXX - Copied from "filter-util.c" in the wireshark-win32 branch */
1225 /* XXX - The only reason for the "filter_text" parameter is to be able to feed
1226 * in the "real" filter string in the case of a CBN_SELCHANGE notification message.
1228 static void
1229 filter_tb_syntax_check(HWND hwnd, TCHAR *filter_text) {
1230 TCHAR *strval = NULL;
1231 gint len;
1232 dfilter_t *dfp;
1234 /* If filter_text is non-NULL, use it. Otherwise, grab the text from
1235 * the window */
1236 if (filter_text) {
1237 len = (lstrlen(filter_text) + 1) * sizeof(TCHAR);
1238 strval = g_malloc(len);
1239 memcpy(strval, filter_text, len);
1240 } else {
1241 len = GetWindowTextLength(hwnd);
1242 if (len > 0) {
1243 len++;
1244 strval = g_malloc(len*sizeof(TCHAR));
1245 len = GetWindowText(hwnd, strval, len);
1249 if (len == 0) {
1250 /* Default window background */
1251 SendMessage(hwnd, EM_SETBKGNDCOLOR, (WPARAM) 1, COLOR_WINDOW);
1252 return;
1253 } else if (dfilter_compile(utf_16to8(strval), &dfp)) { /* colorize filter string entry */
1254 if (dfp != NULL)
1255 dfilter_free(dfp);
1256 /* Valid (light green) */
1257 SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, RGB(0xe4, 0xff, 0xc7)); /* tango_chameleon_1 */
1258 } else {
1259 /* Invalid (light red) */
1260 SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, RGB(0xff, 0xcc, 0xcc)); /* tango_scarlet_red_1 */
1263 if (strval) g_free(strval);
1267 static UINT_PTR CALLBACK
1268 open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
1269 HWND cur_ctrl, parent;
1270 OFNOTIFY *notify = (OFNOTIFY *) l_param;
1271 TCHAR sel_name[MAX_PATH];
1273 switch(msg) {
1274 case WM_INITDIALOG:
1275 /* Retain the filter text, and fill it in. */
1276 if(g_dfilter_str != NULL) {
1277 cur_ctrl = GetDlgItem(of_hwnd, EWFD_FILTER_EDIT);
1278 SetWindowText(cur_ctrl, utf_8to16(g_dfilter_str));
1281 /* Fill in our resolution values */
1282 cur_ctrl = GetDlgItem(of_hwnd, EWFD_MAC_NR_CB);
1283 SendMessage(cur_ctrl, BM_SETCHECK, gbl_resolv_flags.mac_name, 0);
1284 cur_ctrl = GetDlgItem(of_hwnd, EWFD_NET_NR_CB);
1285 SendMessage(cur_ctrl, BM_SETCHECK, gbl_resolv_flags.network_name, 0);
1286 cur_ctrl = GetDlgItem(of_hwnd, EWFD_TRANS_NR_CB);
1287 SendMessage(cur_ctrl, BM_SETCHECK, gbl_resolv_flags.transport_name, 0);
1288 cur_ctrl = GetDlgItem(of_hwnd, EWFD_EXTERNAL_NR_CB);
1289 SendMessage(cur_ctrl, BM_SETCHECK, gbl_resolv_flags.use_external_net_name_resolver, 0);
1291 preview_set_file_info(of_hwnd, NULL);
1292 break;
1293 case WM_NOTIFY:
1294 switch (notify->hdr.code) {
1295 case CDN_FILEOK:
1296 /* Fetch the read filter */
1297 cur_ctrl = GetDlgItem(of_hwnd, EWFD_FILTER_EDIT);
1298 if (g_dfilter_str)
1299 g_free(g_dfilter_str);
1300 g_dfilter_str = filter_tb_get(cur_ctrl);
1302 /* Fetch our resolution values */
1303 cur_ctrl = GetDlgItem(of_hwnd, EWFD_MAC_NR_CB);
1304 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
1305 gbl_resolv_flags.mac_name = TRUE;
1306 cur_ctrl = GetDlgItem(of_hwnd, EWFD_NET_NR_CB);
1307 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
1308 gbl_resolv_flags.network_name = TRUE;
1309 cur_ctrl = GetDlgItem(of_hwnd, EWFD_TRANS_NR_CB);
1310 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
1311 gbl_resolv_flags.transport_name = TRUE;
1312 cur_ctrl = GetDlgItem(of_hwnd, EWFD_EXTERNAL_NR_CB);
1313 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
1314 gbl_resolv_flags.use_external_net_name_resolver = TRUE;
1315 break;
1316 case CDN_SELCHANGE:
1317 /* This _almost_ works correctly. We need to handle directory
1318 selections, etc. */
1319 parent = GetParent(of_hwnd);
1320 CommDlg_OpenSave_GetFilePath(parent, sel_name, MAX_PATH);
1321 preview_set_file_info(of_hwnd, utf_16to8(sel_name));
1322 break;
1323 case CDN_HELP:
1324 topic_action(HELP_OPEN_WIN32_DIALOG);
1325 break;
1326 default:
1327 break;
1329 break;
1330 case WM_COMMAND:
1331 cur_ctrl = (HWND) l_param;
1332 switch(w_param) {
1333 case (EN_UPDATE << 16) | EWFD_FILTER_EDIT:
1334 filter_tb_syntax_check(cur_ctrl, NULL);
1335 break;
1337 * If we ever figure out a way to integrate the Windows
1338 * and GTK+ event loops (or make a native filter dialog),
1339 * we can re-enable the "Filter" button.
1342 case EWFD_FILTER_BTN:
1343 break;
1345 default:
1346 break;
1348 break;
1349 default:
1350 break;
1352 return 0;
1355 /* Generate a list of the file types we can filter for in the open dialog. */
1356 static void
1357 append_file_extension_type(GArray *sa, int et)
1359 GString* pattern_str = g_string_new("");
1360 GString* description_str = g_string_new("");
1361 gchar sep;
1362 GSList *extensions_list, *extension;
1363 TCHAR *str16;
1364 guint16 zero = 0;
1366 /* Construct the list of patterns. */
1367 extensions_list = wtap_get_file_extension_type_extensions(et);
1368 g_string_printf(pattern_str, "");
1369 sep = '\0';
1370 for (extension = extensions_list; extension != NULL;
1371 extension = g_slist_next(extension)) {
1372 if (sep != '\0')
1373 g_string_append_c(pattern_str, sep);
1374 g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
1375 sep = ';';
1377 wtap_free_extensions_list(extensions_list);
1379 /* Construct the description. */
1380 g_string_printf(description_str, "%s (%s)",
1381 wtap_get_file_extension_type_name(et),
1382 pattern_str->str);
1383 str16 = utf_8to16(description_str->str);
1384 sa = g_array_append_vals(sa, str16, (guint) strlen(description_str->str));
1385 sa = g_array_append_val(sa, zero);
1386 g_string_free(description_str, TRUE);
1388 str16 = utf_8to16(pattern_str->str);
1389 sa = g_array_append_vals(sa, str16, (guint) strlen(pattern_str->str));
1390 sa = g_array_append_val(sa, zero);
1391 g_string_free(pattern_str, TRUE);
1394 static TCHAR *
1395 build_file_open_type_list(void) {
1396 TCHAR *str16;
1397 int et;
1398 GArray* sa;
1399 static const guint16 zero = 0;
1400 GString* pattern_str;
1401 gchar sep;
1402 GSList *extensions_list, *extension;
1405 * Microsoft's UI guidelines say, of the file filters in open and
1406 * save dialogs:
1408 * For meta-filters, remove the file extension list to eliminate
1409 * clutter. Examples: "All files," "All pictures," "All music,"
1410 * and "All videos."
1412 * so we omit them (for "All Capture Files", the filter would be
1413 * *really* long). On both Windows XP and Windows 7, Wordpad doesn't
1414 * do that, but Paint does.
1418 * Array of hexadectets used as a sequence of null-terminated
1419 * UTF-16 strings.
1421 sa = g_array_new(FALSE /*zero_terminated*/, FALSE /*clear_*/,2 /*element_size*/);
1423 /* Add the "All Files" entry. */
1424 str16 = utf_8to16("All Files");
1425 sa = g_array_append_vals(sa, str16, (guint) strlen("All Files"));
1426 sa = g_array_append_val(sa, zero);
1427 str16 = utf_8to16("*.*");
1428 sa = g_array_append_vals(sa, str16, (guint) strlen("*.*"));
1429 sa = g_array_append_val(sa, zero);
1432 * Add an "All Capture Files" entry, with all the extensions we
1433 * know about.
1435 str16 = utf_8to16("All Capture Files");
1436 sa = g_array_append_vals(sa, str16, (guint) strlen("All Capture Files"));
1437 sa = g_array_append_val(sa, zero);
1440 * Construct its list of patterns from a list of all extensions
1441 * we support.
1443 pattern_str = g_string_new("");
1444 extensions_list = wtap_get_all_file_extensions_list();
1445 sep = '\0';
1446 for (extension = extensions_list; extension != NULL;
1447 extension = g_slist_next(extension)) {
1448 if (sep != '\0')
1449 g_string_append_c(pattern_str, sep);
1450 g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
1451 sep = ';';
1453 wtap_free_extensions_list(extensions_list);
1454 str16 = utf_8to16(pattern_str->str);
1455 sa = g_array_append_vals(sa, str16, (guint) strlen(pattern_str->str));
1456 sa = g_array_append_val(sa, zero);
1458 /* Include all the file type extensions Wireshark supports. */
1459 for (et = 0; et < wtap_get_num_file_type_extensions(); et++) {
1460 append_file_extension_type(sa, et);
1463 /* terminate the array */
1464 sa = g_array_append_val(sa, zero);
1466 return (TCHAR *) g_array_free(sa, FALSE /*free_segment*/);
1469 /* Generate a list of the file types we can save this file as.
1471 "g_filetype" is the type it has now.
1473 "encap" is the encapsulation for its packets (which could be
1474 "unknown" or "per-packet").
1476 "filtered" is TRUE if we're to save only the packets that passed
1477 the display filter (in which case we have to save it using Wiretap)
1478 and FALSE if we're to save the entire file (in which case, if we're
1479 saving it in the type it has already, we can just copy it).
1481 The same applies for sel_curr, sel_all, sel_m_only, sel_m_range and sel_man_range
1483 static void
1484 append_file_type(GArray *sa, int ft)
1486 GString* pattern_str = g_string_new("");
1487 GString* description_str = g_string_new("");
1488 gchar sep;
1489 GSList *extensions_list, *extension;
1490 TCHAR *str16;
1491 guint16 zero = 0;
1493 extensions_list = wtap_get_file_extensions_list(ft, TRUE);
1494 if (extensions_list == NULL) {
1495 /* This file type doesn't have any particular extension
1496 conventionally used for it, so we'll just use "*.*"
1497 as the pattern; on Windows, that matches all file names
1498 - even those with no extension - so we don't need to
1499 worry about compressed file extensions. (It does not
1500 do so on UN*X; the right pattern on UN*X would just
1501 be "*".) */
1502 g_string_printf(pattern_str, "*.*");
1503 } else {
1504 /* Construct the list of patterns. */
1505 g_string_printf(pattern_str, "");
1506 sep = '\0';
1507 for (extension = extensions_list; extension != NULL;
1508 extension = g_slist_next(extension)) {
1509 if (sep != '\0')
1510 g_string_append_c(pattern_str, sep);
1511 g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
1512 sep = ';';
1514 wtap_free_extensions_list(extensions_list);
1517 /* Construct the description. */
1518 g_string_printf(description_str, "%s (%s)", wtap_file_type_subtype_string(ft),
1519 pattern_str->str);
1520 str16 = utf_8to16(description_str->str);
1521 sa = g_array_append_vals(sa, str16, (guint) strlen(description_str->str));
1522 sa = g_array_append_val(sa, zero);
1523 g_string_free(description_str, TRUE);
1525 str16 = utf_8to16(pattern_str->str);
1526 sa = g_array_append_vals(sa, str16, (guint) strlen(pattern_str->str));
1527 sa = g_array_append_val(sa, zero);
1528 g_string_free(pattern_str, TRUE);
1531 static TCHAR *
1532 build_file_save_type_list(GArray *savable_file_types) {
1533 guint i;
1534 int ft;
1535 GArray* sa = g_array_new(FALSE /*zero_terminated*/, FALSE /*clear_*/,2 /*element_size*/);
1536 guint16 zero = 0;
1538 /* Get only the file types as which we can save this file. */
1539 for (i = 0; i < savable_file_types->len; i++) {
1540 ft = g_array_index(savable_file_types, int, i);
1541 append_file_type(sa, ft);
1544 /* terminate the array */
1545 sa = g_array_append_val(sa, zero);
1547 return (TCHAR *) g_array_free(sa, FALSE /*free_segment*/);
1551 #if 0
1552 static void
1553 build_file_format_list(HWND sf_hwnd) {
1554 HWND format_cb;
1555 int ft;
1556 guint index;
1557 guint item_to_select;
1558 gchar *s;
1560 /* Default to the first supported file type, if the file's current
1561 type isn't supported. */
1562 item_to_select = 0;
1564 format_cb = GetDlgItem(sf_hwnd, EWFD_FILE_TYPE_COMBO);
1565 SendMessage(format_cb, CB_RESETCONTENT, 0, 0);
1567 /* Check all file types. */
1568 index = 0;
1569 for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
1570 if (ft == WTAP_FILE_UNKNOWN)
1571 continue; /* not a real file type */
1573 if (!packet_range_process_all(g_range) || ft != cfile.cd_t) {
1574 /* not all unfiltered packets or a different file type. We have to use Wiretap. */
1575 if (!wtap_can_save_with_wiretap(ft, cfile.linktypes))
1576 continue; /* We can't. */
1579 /* OK, we can write it out in this type. */
1580 if(wtap_file_extensions_string(ft) != NULL) {
1581 s = g_strdup_printf("%s (%s)", wtap_file_type_string(ft), wtap_file_extensions_string(ft));
1582 } else {
1583 s = g_strdup_printf("%s (*.*)", wtap_file_type_string(ft));
1585 SendMessage(format_cb, CB_ADDSTRING, 0, (LPARAM) utf_8to16(s));
1586 g_free(s);
1587 SendMessage(format_cb, CB_SETITEMDATA, (LPARAM) index, (WPARAM) ft);
1588 if (ft == g_filetype) {
1589 /* Default to the same format as the file, if it's supported. */
1590 item_to_select = index;
1592 index++;
1595 SendMessage(format_cb, CB_SETCURSEL, (WPARAM) item_to_select, 0);
1597 #endif
1599 static UINT_PTR CALLBACK
1600 save_as_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
1601 HWND cur_ctrl;
1602 OFNOTIFY *notify = (OFNOTIFY *) l_param;
1603 /*int new_filetype, index;*/
1605 switch(msg) {
1606 case WM_INITDIALOG: {
1607 OPENFILENAME *ofnp = (OPENFILENAME *) l_param;
1608 capture_file *cf = (capture_file *) ofnp->lCustData;
1609 g_sf_hwnd = sf_hwnd;
1611 /* Default to saving in the file's current format. */
1612 g_filetype = cf->cd_t;
1614 /* Fill in the file format list */
1615 /*build_file_format_list(sf_hwnd);*/
1616 /* Fill in the compression checkbox */
1617 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
1618 SendMessage(cur_ctrl, BM_SETCHECK, g_compressed, 0);
1620 break;
1622 case WM_COMMAND:
1623 cur_ctrl = (HWND) l_param;
1625 switch (w_param) {
1626 #if 0
1627 case (CBN_SELCHANGE << 16) | EWFD_FILE_TYPE_COMBO:
1628 index = SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0);
1629 if (index != CB_ERR) {
1630 new_filetype = SendMessage(cur_ctrl, CB_GETITEMDATA, (WPARAM) index, 0);
1631 if (new_filetype != CB_ERR) {
1632 if (g_filetype != new_filetype) {
1633 if (wtap_can_save_with_wiretap(new_filetype, cfile.linktypes)) {
1634 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN);
1635 EnableWindow(cur_ctrl, TRUE);
1636 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
1637 EnableWindow(cur_ctrl, TRUE);
1638 } else {
1639 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN);
1640 SendMessage(cur_ctrl, BM_SETCHECK, 0, 0);
1641 EnableWindow(cur_ctrl, FALSE);
1642 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
1643 EnableWindow(cur_ctrl, FALSE);
1645 g_filetype = new_filetype;
1646 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
1647 if (wtap_dump_can_compress(file_type) {
1648 EnableWindow(cur_ctrl);
1649 } else {
1650 g_compressed = FALSE;
1651 DisableWindow(cur_ctrl);
1653 SendMessage(cur_ctrl, BM_SETCHECK, g_compressed, 0);
1658 break;
1659 #endif
1660 default:
1661 break;
1663 break;
1664 case WM_NOTIFY:
1665 switch (notify->hdr.code) {
1666 case CDN_HELP:
1667 topic_action(HELP_SAVE_WIN32_DIALOG);
1668 break;
1669 case CDN_FILEOK: {
1670 HWND parent;
1671 char *file_name8;
1672 OPENFILENAME *ofnp = (OPENFILENAME *) notify->lpOFN;
1673 capture_file *cf = (capture_file *) ofnp->lCustData;
1675 /* Fetch our compression value */
1676 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
1677 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
1678 g_compressed = TRUE;
1679 else
1680 g_compressed = FALSE;
1682 /* Check if we're trying to overwrite the currently open file */
1683 parent = GetParent(sf_hwnd);
1684 file_name8 = utf_16to8(notify->lpOFN->lpstrFile);
1685 if (files_identical(cf->filename, file_name8)) {
1686 /* XXX: Is MessageBox the best way to pop up an error ? How to make text bold ? */
1687 gchar *str = g_strdup_printf(
1688 "Capture File \"%s\" identical to loaded file.\n\n"
1689 "Please choose a different filename.",
1690 file_name8);
1691 MessageBox( parent, utf_8to16(str), _T("Error"), MB_ICONERROR | MB_APPLMODAL | MB_OK);
1692 g_free(str);
1693 SetWindowLongPtr(sf_hwnd, DWLP_MSGRESULT, 1L); /* Don't allow ! */
1694 return 1;
1697 break;
1698 default:
1699 break;
1701 break;
1702 default:
1703 break;
1705 return 0;
1708 #define RANGE_TEXT_MAX 128
1709 static UINT_PTR CALLBACK
1710 export_specified_packets_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
1711 HWND cur_ctrl;
1712 OFNOTIFY *notify = (OFNOTIFY *) l_param;
1713 /*int new_filetype, index;*/
1715 switch(msg) {
1716 case WM_INITDIALOG: {
1717 g_sf_hwnd = sf_hwnd;
1719 /* Default to saving all packets, in the file's current format. */
1720 g_filetype = g_cf->cd_t;
1722 /* Fill in the file format list */
1723 /*build_file_format_list(sf_hwnd);*/
1725 range_handle_wm_initdialog(sf_hwnd, g_range);
1727 /* Fill in the compression checkbox */
1728 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
1729 SendMessage(cur_ctrl, BM_SETCHECK, g_compressed, 0);
1731 break;
1733 case WM_COMMAND:
1734 cur_ctrl = (HWND) l_param;
1736 switch (w_param) {
1737 #if 0
1738 case (CBN_SELCHANGE << 16) | EWFD_FILE_TYPE_COMBO:
1739 index = SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0);
1740 if (index != CB_ERR) {
1741 new_filetype = SendMessage(cur_ctrl, CB_GETITEMDATA, (WPARAM) index, 0);
1742 if (new_filetype != CB_ERR) {
1743 if (g_filetype != new_filetype) {
1744 if (wtap_can_save_with_wiretap(new_filetype, cfile.linktypes)) {
1745 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN);
1746 EnableWindow(cur_ctrl, TRUE);
1747 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
1748 EnableWindow(cur_ctrl, TRUE);
1749 } else {
1750 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN);
1751 SendMessage(cur_ctrl, BM_SETCHECK, 0, 0);
1752 EnableWindow(cur_ctrl, FALSE);
1753 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
1754 EnableWindow(cur_ctrl, FALSE);
1756 g_filetype = new_filetype;
1760 break;
1761 #endif
1762 default:
1763 range_handle_wm_command(sf_hwnd, cur_ctrl, w_param, g_range);
1764 break;
1766 break;
1767 case WM_NOTIFY:
1768 switch (notify->hdr.code) {
1769 case CDN_HELP:
1770 topic_action(HELP_SAVE_WIN32_DIALOG);
1771 break;
1772 case CDN_FILEOK: {
1773 HWND parent;
1774 char *file_name8;
1775 OPENFILENAME *ofnp = (OPENFILENAME *) notify->lpOFN;
1776 capture_file *cf = (capture_file *) ofnp->lCustData;
1778 /* Fetch our compression value */
1779 cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
1780 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
1781 g_compressed = TRUE;
1782 else
1783 g_compressed = FALSE;
1785 /* Check if we're trying to overwrite the currently open file */
1786 parent = GetParent(sf_hwnd);
1787 file_name8 = utf_16to8(notify->lpOFN->lpstrFile);
1788 if (files_identical(cf->filename, file_name8)) {
1789 /* XXX: Is MessageBox the best way to pop up an error ? How to make text bold ? */
1790 gchar *str = g_strdup_printf(
1791 "Capture File \"%s\" identical to loaded file.\n\n"
1792 "Please choose a different filename.",
1793 file_name8);
1794 MessageBox( parent, utf_8to16(str), _T("Error"), MB_ICONERROR | MB_APPLMODAL | MB_OK);
1795 g_free(str);
1796 SetWindowLongPtr(sf_hwnd, DWLP_MSGRESULT, 1L); /* Don't allow ! */
1797 return 1;
1800 break;
1801 default:
1802 break;
1804 break;
1805 default:
1806 break;
1808 return 0;
1812 #define STATIC_LABEL_CHARS 100
1813 /* For each range static control, fill in its value and enable/disable it. */
1814 static void
1815 range_update_dynamics(HWND dlg_hwnd, packet_range_t *range) {
1816 HWND cur_ctrl;
1817 gboolean filtered_active = FALSE;
1818 TCHAR static_val[STATIC_LABEL_CHARS];
1819 gint selected_num;
1820 guint32 ignored_cnt = 0, displayed_ignored_cnt = 0;
1821 guint32 displayed_cnt;
1822 gboolean range_valid = TRUE;
1824 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_DISPLAYED_BTN);
1825 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
1826 filtered_active = TRUE;
1828 /* RANGE_SELECT_ALL */
1829 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_CAP);
1830 EnableWindow(cur_ctrl, !filtered_active);
1831 if (range->remove_ignored) {
1832 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), g_cf->count - range->ignored_cnt);
1833 } else {
1834 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), g_cf->count);
1836 SetWindowText(cur_ctrl, static_val);
1838 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_DISP);
1839 EnableWindow(cur_ctrl, filtered_active);
1840 if (range->include_dependents)
1841 displayed_cnt = range->displayed_plus_dependents_cnt;
1842 else
1843 displayed_cnt = range->displayed_cnt;
1844 if (range->remove_ignored) {
1845 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), displayed_cnt - range->displayed_ignored_cnt);
1846 } else {
1847 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), displayed_cnt);
1849 SetWindowText(cur_ctrl, static_val);
1851 /* RANGE_SELECT_CURR */
1852 selected_num = (g_cf->current_frame) ? g_cf->current_frame->num : 0;
1853 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_CAP);
1854 EnableWindow(cur_ctrl, selected_num && !filtered_active);
1855 if (range->remove_ignored && g_cf->current_frame && g_cf->current_frame->flags.ignored) {
1856 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("0"));
1857 } else {
1858 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), selected_num ? 1 : 0);
1860 SetWindowText(cur_ctrl, static_val);
1862 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_DISP);
1863 EnableWindow(cur_ctrl, selected_num && filtered_active);
1864 if (range->remove_ignored && g_cf->current_frame && g_cf->current_frame->flags.ignored) {
1865 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("0"));
1866 } else {
1867 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), selected_num ? 1 : 0);
1869 SetWindowText(cur_ctrl, static_val);
1871 /* RANGE_SELECT_MARKED */
1872 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_BTN);
1873 EnableWindow(cur_ctrl, g_cf->marked_count);
1875 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_CAP);
1876 EnableWindow(cur_ctrl, g_cf->marked_count && !filtered_active);
1877 if (range->remove_ignored) {
1878 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), g_cf->marked_count - range->ignored_marked_cnt);
1879 } else {
1880 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), g_cf->marked_count);
1882 SetWindowText(cur_ctrl, static_val);
1884 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_DISP);
1885 EnableWindow(cur_ctrl, g_cf->marked_count && filtered_active);
1886 if (range->remove_ignored) {
1887 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_marked_cnt - range->displayed_ignored_marked_cnt);
1888 } else {
1889 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_marked_cnt);
1891 SetWindowText(cur_ctrl, static_val);
1893 /* RANGE_SELECT_MARKED_RANGE */
1894 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_BTN);
1895 EnableWindow(cur_ctrl, range->mark_range_cnt);
1897 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_CAP);
1898 EnableWindow(cur_ctrl, range->mark_range_cnt && !filtered_active);
1899 if (range->remove_ignored) {
1900 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->mark_range_cnt - range->ignored_mark_range_cnt);
1901 } else {
1902 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->mark_range_cnt);
1904 SetWindowText(cur_ctrl, static_val);
1906 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_DISP);
1907 EnableWindow(cur_ctrl, range->displayed_mark_range_cnt && filtered_active);
1908 if (range->remove_ignored) {
1909 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_mark_range_cnt - range->displayed_ignored_mark_range_cnt);
1910 } else {
1911 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_mark_range_cnt);
1913 SetWindowText(cur_ctrl, static_val);
1915 /* RANGE_SELECT_USER */
1916 switch (packet_range_check(range)) {
1917 case CVT_NO_ERROR:
1918 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
1919 SendMessage(cur_ctrl, EM_SETBKGNDCOLOR, (WPARAM) 1, COLOR_WINDOW);
1921 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_CAP);
1922 EnableWindow(cur_ctrl, !filtered_active);
1923 if (range->remove_ignored) {
1924 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->user_range_cnt - range->ignored_user_range_cnt);
1925 } else {
1926 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->user_range_cnt);
1928 SetWindowText(cur_ctrl, static_val);
1930 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_DISP);
1931 EnableWindow(cur_ctrl, filtered_active);
1932 if (range->remove_ignored) {
1933 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_user_range_cnt - range->displayed_ignored_user_range_cnt);
1934 } else {
1935 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_user_range_cnt);
1937 SetWindowText(cur_ctrl, static_val);
1938 break;
1939 case CVT_SYNTAX_ERROR:
1940 if (range->process == range_process_user_range) range_valid = FALSE;
1941 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
1942 SendMessage(cur_ctrl, EM_SETBKGNDCOLOR, 0, RGB(0xff, 0xcc, 0xcc));
1943 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_CAP);
1944 SetWindowText(cur_ctrl, _T("Bad range"));
1945 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_DISP);
1946 SetWindowText(cur_ctrl, _T("-"));
1947 break;
1948 case CVT_NUMBER_TOO_BIG:
1949 if (range->process == range_process_user_range) range_valid = FALSE;
1950 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
1951 SendMessage(cur_ctrl, EM_SETBKGNDCOLOR, 0, RGB(0xff, 0xcc, 0xcc));
1952 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_CAP);
1953 SetWindowText(cur_ctrl, _T("Too large"));
1954 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_DISP);
1955 SetWindowText(cur_ctrl, _T("-"));
1956 break;
1958 default:
1959 g_assert_not_reached();
1962 /* RANGE_REMOVE_IGNORED_PACKETS */
1963 switch(range->process) {
1964 case(range_process_all):
1965 ignored_cnt = range->ignored_cnt;
1966 displayed_ignored_cnt = range->displayed_ignored_cnt;
1967 break;
1968 case(range_process_selected):
1969 ignored_cnt = (g_cf->current_frame && g_cf->current_frame->flags.ignored) ? 1 : 0;
1970 displayed_ignored_cnt = ignored_cnt;
1971 break;
1972 case(range_process_marked):
1973 ignored_cnt = range->ignored_marked_cnt;
1974 displayed_ignored_cnt = range->displayed_ignored_marked_cnt;
1975 break;
1976 case(range_process_marked_range):
1977 ignored_cnt = range->ignored_mark_range_cnt;
1978 displayed_ignored_cnt = range->displayed_ignored_mark_range_cnt;
1979 break;
1980 case(range_process_user_range):
1981 ignored_cnt = range->ignored_user_range_cnt;
1982 displayed_ignored_cnt = range->displayed_ignored_user_range_cnt;
1983 break;
1984 default:
1985 g_assert_not_reached();
1988 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_REMOVE_IGN_CB);
1989 EnableWindow(cur_ctrl, ignored_cnt);
1991 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_IGNORED_CAP);
1992 EnableWindow(cur_ctrl, ignored_cnt && !filtered_active);
1993 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), ignored_cnt);
1994 SetWindowText(cur_ctrl, static_val);
1996 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_IGNORED_DISP);
1997 EnableWindow(cur_ctrl, displayed_ignored_cnt && filtered_active);
1998 StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), displayed_ignored_cnt);
1999 SetWindowText(cur_ctrl, static_val);
2001 cur_ctrl = GetDlgItem(GetParent(dlg_hwnd), IDOK);
2002 EnableWindow(cur_ctrl, range_valid);
2005 static void
2006 range_handle_wm_initdialog(HWND dlg_hwnd, packet_range_t *range) {
2007 HWND cur_ctrl;
2009 /* Set the appropriate captured/displayed radio */
2010 if (range->process_filtered)
2011 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_DISPLAYED_BTN);
2012 else
2013 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_CAPTURED_BTN);
2014 SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0);
2016 /* Retain the filter text, and fill it in. */
2017 if(range->user_range != NULL) {
2018 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
2019 SetWindowText(cur_ctrl, utf_8to16(range_convert_range(range->user_range)));
2022 /* dynamic values in the range frame */
2023 range_update_dynamics(dlg_hwnd, range);
2025 /* Set the appropriate range radio */
2026 switch(range->process) {
2027 case(range_process_all):
2028 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_BTN);
2029 break;
2030 case(range_process_selected):
2031 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_BTN);
2032 break;
2033 case(range_process_marked):
2034 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_BTN);
2035 break;
2036 case(range_process_marked_range):
2037 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_BTN);
2038 break;
2039 case(range_process_user_range):
2040 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_BTN);
2041 break;
2042 default:
2043 g_assert_not_reached();
2045 SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0);
2048 static void
2049 range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, packet_range_t *range) {
2050 HWND cur_ctrl;
2051 TCHAR range_text[RANGE_TEXT_MAX];
2053 if (!range) return;
2055 switch(w_param) {
2056 case (BN_CLICKED << 16) | EWFD_CAPTURED_BTN:
2057 case (BN_CLICKED << 16) | EWFD_DISPLAYED_BTN:
2058 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_CAPTURED_BTN);
2059 if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
2060 range->process_filtered = FALSE;
2061 else
2062 range->process_filtered = TRUE;
2063 range_update_dynamics(dlg_hwnd, range);
2064 break;
2065 case (BN_CLICKED << 16) | EWFD_ALL_PKTS_BTN:
2066 if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
2067 range->process = range_process_all;
2068 range_update_dynamics(dlg_hwnd, range);
2070 break;
2071 case (BN_CLICKED << 16) | EWFD_SEL_PKT_BTN:
2072 if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
2073 range->process = range_process_selected;
2074 range_update_dynamics(dlg_hwnd, range);
2076 break;
2077 case (BN_CLICKED << 16) | EWFD_MARKED_BTN:
2078 if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
2079 range->process = range_process_marked;
2080 range_update_dynamics(dlg_hwnd, range);
2082 break;
2083 case (BN_CLICKED << 16) | EWFD_FIRST_LAST_BTN:
2084 if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
2085 range->process = range_process_marked_range;
2086 range_update_dynamics(dlg_hwnd, range);
2088 break;
2089 case (BN_CLICKED << 16) | EWFD_RANGE_BTN:
2090 if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
2091 range->process = range_process_user_range;
2092 range_update_dynamics(dlg_hwnd, range);
2093 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
2094 SetFocus(cur_ctrl);
2096 break;
2097 case (EN_SETFOCUS << 16) | EWFD_RANGE_EDIT:
2098 cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_BTN);
2099 SendMessage(cur_ctrl, BM_CLICK, 0, 0);
2100 break;
2101 case (EN_UPDATE << 16) | EWFD_RANGE_EDIT:
2102 SendMessage(ctrl, WM_GETTEXT, (WPARAM) RANGE_TEXT_MAX, (LPARAM) range_text);
2103 packet_range_convert_str(range, utf_16to8(range_text));
2104 range_update_dynamics(dlg_hwnd, range);
2105 break;
2106 case (BN_CLICKED << 16) | EWFD_REMOVE_IGN_CB:
2107 if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
2108 range->remove_ignored = TRUE;
2109 } else {
2110 range->remove_ignored = FALSE;
2112 range_update_dynamics(dlg_hwnd, range);
2113 break;
2117 static UINT_PTR CALLBACK
2118 merge_file_hook_proc(HWND mf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
2119 HWND cur_ctrl, parent;
2120 OFNOTIFY *notify = (OFNOTIFY *) l_param;
2121 TCHAR sel_name[MAX_PATH];
2123 switch(msg) {
2124 case WM_INITDIALOG:
2125 /* Retain the filter text, and fill it in. */
2126 if(g_dfilter_str != NULL) {
2127 cur_ctrl = GetDlgItem(mf_hwnd, EWFD_FILTER_EDIT);
2128 SetWindowText(cur_ctrl, utf_8to16(g_dfilter_str));
2131 /* Chrono by default */
2132 cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_CHRONO_BTN);
2133 SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0);
2134 g_merge_action = merge_append;
2136 preview_set_file_info(mf_hwnd, NULL);
2137 break;
2138 case WM_NOTIFY:
2139 switch (notify->hdr.code) {
2140 case CDN_FILEOK:
2141 /* Fetch the read filter */
2142 cur_ctrl = GetDlgItem(mf_hwnd, EWFD_FILTER_EDIT);
2143 if (g_dfilter_str)
2144 g_free(g_dfilter_str);
2145 g_dfilter_str = filter_tb_get(cur_ctrl);
2147 cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_CHRONO_BTN);
2148 if(SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
2149 g_merge_action = merge_chrono;
2150 } else {
2151 cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_PREPEND_BTN);
2152 if(SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
2153 g_merge_action = merge_prepend;
2157 break;
2158 case CDN_SELCHANGE:
2159 /* This _almost_ works correctly. We need to handle directory
2160 selections, etc. */
2161 parent = GetParent(mf_hwnd);
2162 CommDlg_OpenSave_GetFilePath(parent, sel_name, MAX_PATH);
2163 preview_set_file_info(mf_hwnd, utf_16to8(sel_name));
2164 break;
2165 case CDN_HELP:
2166 topic_action(HELP_MERGE_WIN32_DIALOG);
2167 break;
2168 default:
2169 break;
2171 break;
2172 case WM_COMMAND:
2173 cur_ctrl = (HWND) l_param;
2174 switch(w_param) {
2175 case (EN_UPDATE << 16) | EWFD_FILTER_EDIT:
2176 filter_tb_syntax_check(cur_ctrl, NULL);
2177 break;
2178 default:
2179 break;
2181 break;
2182 default:
2183 break;
2185 return 0;
2189 static UINT_PTR CALLBACK
2190 export_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
2191 HWND cur_ctrl;
2192 OFNOTIFY *notify = (OFNOTIFY *) l_param;
2193 gboolean pkt_fmt_enable;
2194 int i, index;
2196 switch(msg) {
2197 case WM_INITDIALOG: {
2198 OPENFILENAME *ofnp = (OPENFILENAME *) l_param;
2199 capture_file *cf = (capture_file *) ofnp->lCustData;
2201 /* init the printing range */
2202 packet_range_init(&print_args.range, cf);
2203 /* default to displayed packets */
2204 print_args.range.process_filtered = TRUE;
2205 range_handle_wm_initdialog(ef_hwnd, &print_args.range);
2206 format_handle_wm_initdialog(ef_hwnd, &print_args);
2208 break;
2210 case WM_COMMAND:
2211 cur_ctrl = (HWND) l_param;
2212 switch (w_param) {
2213 case (CBN_SELCHANGE << 16) | EWFD_PKT_DETAIL_COMBO:
2214 default:
2215 range_handle_wm_command(ef_hwnd, cur_ctrl, w_param, &print_args.range);
2216 print_update_dynamic(ef_hwnd, &print_args);
2217 break;
2219 break;
2220 case WM_NOTIFY:
2221 switch (notify->hdr.code) {
2222 case CDN_FILEOK:
2223 break;
2224 case CDN_TYPECHANGE:
2225 index = notify->lpOFN->nFilterIndex;
2227 if (index == 2) /* PostScript */
2228 print_args.format = PR_FMT_TEXT;
2229 else
2230 print_args.format = PR_FMT_PS;
2231 if (index == 3 || index == 4 || index == 5 || index == 6)
2232 pkt_fmt_enable = FALSE;
2233 else
2234 pkt_fmt_enable = TRUE;
2235 for (i = EWFD_PKT_FORMAT_GB; i <= EWFD_PKT_NEW_PAGE_CB; i++) {
2236 cur_ctrl = GetDlgItem(ef_hwnd, i);
2237 EnableWindow(cur_ctrl, pkt_fmt_enable);
2239 break;
2240 case CDN_HELP:
2241 topic_action(HELP_EXPORT_FILE_WIN32_DIALOG);
2242 break;
2243 default:
2244 break;
2246 break;
2247 default:
2248 break;
2250 return 0;
2253 static UINT_PTR CALLBACK
2254 export_raw_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
2255 HWND cur_ctrl;
2256 OPENFILENAME *ofnp = (OPENFILENAME *) l_param;
2257 TCHAR raw_msg[STATIC_LABEL_CHARS];
2258 OFNOTIFY *notify = (OFNOTIFY *) l_param;
2260 switch(msg) {
2261 case WM_INITDIALOG:
2262 StringCchPrintf(raw_msg, STATIC_LABEL_CHARS, _T("%d byte%s of raw binary data will be written"),
2263 ofnp->lCustData, utf_8to16(plurality(ofnp->lCustData, "", "s")));
2264 cur_ctrl = GetDlgItem(ef_hwnd, EWFD_EXPORTRAW_ST);
2265 SetWindowText(cur_ctrl, raw_msg);
2266 break;
2267 case WM_NOTIFY:
2268 switch (notify->hdr.code) {
2269 case CDN_HELP:
2270 topic_action(HELP_EXPORT_BYTES_WIN32_DIALOG);
2271 break;
2272 default:
2273 break;
2275 default:
2276 break;
2278 return 0;
2281 static UINT_PTR CALLBACK
2282 export_sslkeys_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
2283 HWND cur_ctrl;
2284 OPENFILENAME *ofnp = (OPENFILENAME *) l_param;
2285 TCHAR sslkeys_msg[STATIC_LABEL_CHARS];
2286 OFNOTIFY *notify = (OFNOTIFY *) l_param;
2288 switch(msg) {
2289 case WM_INITDIALOG:
2290 StringCchPrintf(sslkeys_msg, STATIC_LABEL_CHARS, _T("%d SSL Session Key%s will be written"),
2291 ofnp->lCustData, utf_8to16(plurality(ofnp->lCustData, "", "s")));
2292 cur_ctrl = GetDlgItem(ef_hwnd, EWFD_EXPORTSSLKEYS_ST);
2293 SetWindowText(cur_ctrl, sslkeys_msg);
2294 break;
2295 case WM_NOTIFY:
2296 switch (notify->hdr.code) {
2297 case CDN_HELP:
2298 topic_action(HELP_EXPORT_BYTES_WIN32_DIALOG);
2299 break;
2300 default:
2301 break;
2303 default:
2304 break;
2306 return 0;
2310 * Editor modelines
2312 * Local Variables:
2313 * c-basic-offset: 4
2314 * tab-width: 8
2315 * indent-tabs-mode: nil
2316 * End:
2318 * ex: set shiftwidth=4 tabstop=8 expandtab:
2319 * :indentSize=4:tabSize=8:noTabs=true: