aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--Makefile.nmake2
-rw-r--r--gtk/Makefile.am4
-rw-r--r--gtk/Makefile.nmake3
-rw-r--r--gtk/file_dlg.c97
-rw-r--r--gtk/print_dlg.c47
-rw-r--r--gtk/proto_draw.c50
-rwxr-xr-xgtk/win32-file-dlg.c1453
-rwxr-xr-xgtk/win32-file-dlg.h133
-rw-r--r--image/ethereal.rc.in2
-rwxr-xr-ximage/win32-file-dlg.rc135
11 files changed, 1864 insertions, 63 deletions
diff --git a/Makefile.am b/Makefile.am
index 40f2ffc2b2..921a778d40 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -662,6 +662,7 @@ EXTRA_DIST = \
image/icon_layout_4.xpm \
image/icon_layout_5.xpm \
image/icon_layout_6.xpm \
+ image/win32-file-dlg.rc \
image/wiretap.rc.in \
make-authors-format.pl \
make-authors-short.pl \
diff --git a/Makefile.nmake b/Makefile.nmake
index 24507787ee..1268f2b1dd 100644
--- a/Makefile.nmake
+++ b/Makefile.nmake
@@ -46,7 +46,7 @@ EXTRA_OBJECTS = \
strptime.obj
ethereal_LIBS= wiretap\wiretap-$(WTAP_VERSION).lib \
- wsock32.lib user32.lib shell32.lib \
+ wsock32.lib user32.lib shell32.lib comctl32.lib \
$(NET_SNMP_DIR)\win32\lib\release\netsnmp.lib \
!IFDEF ENABLE_LIBETHEREAL
epan\libethereal.lib \
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index c4286fa44d..8e26b978b0 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -127,7 +127,9 @@ EXTRA_DIST = \
Makefile.common \
Makefile.nmake \
print_mswin.c \
- print_mswin.h
+ print_mswin.h \
+ win32-file-dlg.c \
+ win32-file-dlg.h
# Common headers
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/wiretap
diff --git a/gtk/Makefile.nmake b/gtk/Makefile.nmake
index f7039d6ddf..e4a1bdce45 100644
--- a/gtk/Makefile.nmake
+++ b/gtk/Makefile.nmake
@@ -28,7 +28,8 @@ include Makefile.common
# if you add files here, be sure to include them also in Makefile.am EXTRA_DIST
ETHEREAL_WIN32_GTK_SRC = \
$(ETHEREAL_GTK_SRC) \
- print_mswin.c
+ print_mswin.c \
+ win32-file-dlg.c
ETHEREAL_TAP_OBJECTS = $(ETHEREAL_TAP_SRC:.c=.obj)
diff --git a/gtk/file_dlg.c b/gtk/file_dlg.c
index 5943bcb00c..c3b31b265f 100644
--- a/gtk/file_dlg.c
+++ b/gtk/file_dlg.c
@@ -63,6 +63,12 @@
#include <unistd.h>
#endif
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+#include <gdk/gdkwin32.h>
+#include <windows.h>
+#include "win32-file-dlg.h"
+#endif
+
static void file_open_ok_cb(GtkWidget *w, gpointer fs);
static void file_open_destroy_cb(GtkWidget *win, gpointer user_data);
static void file_merge_ok_cb(GtkWidget *w, gpointer fs);
@@ -209,7 +215,7 @@ preview_do(GtkWidget *prev, wtap *wth)
time(&time_preview);
while ( (wtap_read(wth, &err, &err_info, &data_offset)) ) {
- phdr = wtap_phdr(wth);
+ phdr = wtap_phdr(wth);
cur_time = nstime_to_sec( (const nstime_t *) &phdr->ts );
if(packets == 0) {
start_time = cur_time;
@@ -271,10 +277,10 @@ preview_do(GtkWidget *prev, wtap *wth)
/* elapsed time */
elapsed_time = (unsigned int)(stop_time-start_time);
if(elapsed_time/86400) {
- g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u days %02u:%02u:%02u",
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u days %02u:%02u:%02u",
elapsed_time/86400, elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
} else {
- g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u:%02u:%02u",
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u:%02u:%02u",
elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
}
if(is_breaked) {
@@ -426,6 +432,7 @@ file_open_cmd(GtkWidget *w)
#if GTK_MAJOR_VERSION < 2
GtkAccelGroup *accel_group;
#endif
+
/* No Apply button, and "OK" just sets our text widget, it doesn't
activate it (i.e., it doesn't cause us to try to open the file). */
static construct_args_t args = {
@@ -435,6 +442,11 @@ file_open_cmd(GtkWidget *w)
TRUE
};
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_open_file(GDK_WINDOW_HWND(top_level->window));
+ return;
+#endif
+
if (file_open_w != NULL) {
/* There's already an "Open Capture File" dialog box; reactivate it. */
reactivate_window(file_open_w);
@@ -444,7 +456,7 @@ file_open_cmd(GtkWidget *w)
file_open_w = file_selection_new("Ethereal: Open Capture File",
FILE_SELECTION_OPEN);
#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
- /* it's annoying, that the file chooser dialog is already shown here,
+ /* it's annoying, that the file chooser dialog is already shown here,
so we cannot use the correct gtk_window_set_default_size() to resize it */
WIDGET_SET_SIZE(GTK_WINDOW(file_open_w), DEF_WIDTH, DEF_HEIGHT);
#else
@@ -479,7 +491,7 @@ file_open_cmd(GtkWidget *w)
break;
}
-
+
main_hb = gtk_hbox_new(FALSE, 3);
file_selection_set_extra_widget(file_open_w, main_hb);
gtk_widget_show(main_hb);
@@ -563,7 +575,7 @@ file_open_cmd(GtkWidget *w)
gtk_box_pack_start(GTK_BOX(main_hb), prev, TRUE, TRUE, 0);
#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
- SIGNAL_CONNECT(GTK_FILE_CHOOSER(file_open_w), "selection-changed",
+ SIGNAL_CONNECT(GTK_FILE_CHOOSER(file_open_w), "selection-changed",
file_open_entry_changed, file_open_w);
file_open_entry_changed(file_open_w, file_open_w);
@@ -575,7 +587,7 @@ file_open_cmd(GtkWidget *w)
}
else window_destroy(file_open_w);
#else
- SIGNAL_CONNECT(GTK_FILE_SELECTION(file_open_w)->selection_entry, "changed",
+ SIGNAL_CONNECT(GTK_FILE_SELECTION(file_open_w)->selection_entry, "changed",
file_open_entry_changed, file_open_w);
/* Connect the ok_button to file_open_ok_cb function and pass along a
@@ -587,7 +599,7 @@ file_open_cmd(GtkWidget *w)
E_DFILTER_TE_KEY, OBJECT_GET_DATA(w, E_DFILTER_TE_KEY));
/* Connect the cancel_button to destroy the widget */
- window_set_cancel_button(file_open_w,
+ window_set_cancel_button(file_open_w,
GTK_FILE_SELECTION(file_open_w)->cancel_button, window_cancel_button_cb);
SIGNAL_CONNECT(file_open_w, "delete_event", window_delete_event_cb, NULL);
@@ -765,6 +777,11 @@ file_merge_cmd(GtkWidget *w)
TRUE
};
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_merge_file(GDK_WINDOW_HWND(top_level->window));
+ return;
+#endif
+
if (file_merge_w != NULL) {
/* There's already an "Merge Capture File" dialog box; reactivate it. */
reactivate_window(file_merge_w);
@@ -777,7 +794,7 @@ file_merge_cmd(GtkWidget *w)
file_merge_w = file_selection_new("Ethereal: Merge with Capture File",
FILE_SELECTION_OPEN);
#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
- /* it's annoying, that the file chooser dialog is already shown here,
+ /* it's annoying, that the file chooser dialog is already shown here,
so we cannot use the correct gtk_window_set_default_size() to resize it */
WIDGET_SET_SIZE(GTK_WINDOW(file_merge_w), DEF_WIDTH, DEF_HEIGHT);
#else
@@ -811,7 +828,7 @@ file_merge_cmd(GtkWidget *w)
file_selection_set_current_folder(file_merge_w, prefs.gui_fileopen_dir);
break;
}
-
+
main_hb = gtk_hbox_new(FALSE, 3);
file_selection_set_extra_widget(file_merge_w, main_hb);
gtk_widget_show(main_hb);
@@ -864,7 +881,7 @@ file_merge_cmd(GtkWidget *w)
#endif
prepend_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL, "Prepend packets to existing file", accel_group);
- gtk_tooltips_set_tip(tooltips, prepend_rb,
+ gtk_tooltips_set_tip(tooltips, prepend_rb,
"The resulting file contains the packets from the selected, followed by the packets from the currently loaded file,"
" the packet timestamps will be ignored.", NULL);
gtk_box_pack_start(GTK_BOX(main_vb), prepend_rb, FALSE, FALSE, 0);
@@ -878,7 +895,7 @@ file_merge_cmd(GtkWidget *w)
gtk_widget_show(prepend_rb);
chrono_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(prepend_rb, "Merge packets chronologically", accel_group);
- gtk_tooltips_set_tip(tooltips, chrono_rb,
+ gtk_tooltips_set_tip(tooltips, chrono_rb,
"The resulting file contains all the packets from the currently loaded and the selected file,"
" sorted by the packet timestamps.", NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chrono_rb), TRUE);
@@ -892,7 +909,7 @@ file_merge_cmd(GtkWidget *w)
#endif
append_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(prepend_rb, "Append packets to existing file", accel_group);
- gtk_tooltips_set_tip(tooltips, append_rb,
+ gtk_tooltips_set_tip(tooltips, append_rb,
"The resulting file contains the packets from the currently loaded, followed by the packets from the selected file,"
" the packet timestamps will be ignored.", NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(append_rb),
@@ -916,7 +933,7 @@ file_merge_cmd(GtkWidget *w)
gtk_box_pack_start(GTK_BOX(main_hb), prev, TRUE, TRUE, 0);
#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
- SIGNAL_CONNECT(GTK_FILE_CHOOSER(file_merge_w), "selection-changed",
+ SIGNAL_CONNECT(GTK_FILE_CHOOSER(file_merge_w), "selection-changed",
file_open_entry_changed, file_merge_w);
file_open_entry_changed(file_merge_w, file_merge_w);
@@ -928,7 +945,7 @@ file_merge_cmd(GtkWidget *w)
}
else window_destroy(file_merge_w);
#else
- SIGNAL_CONNECT(GTK_FILE_SELECTION(file_merge_w)->selection_entry, "changed",
+ SIGNAL_CONNECT(GTK_FILE_SELECTION(file_merge_w)->selection_entry, "changed",
file_open_entry_changed, file_merge_w);
/* Connect the ok_button to file_merge_ok_cb function and pass along a
@@ -940,7 +957,7 @@ file_merge_cmd(GtkWidget *w)
E_DFILTER_TE_KEY, OBJECT_GET_DATA(w, E_DFILTER_TE_KEY));
/* Connect the cancel_button to destroy the widget */
- window_set_cancel_button(file_merge_w,
+ window_set_cancel_button(file_merge_w,
GTK_FILE_SELECTION(file_merge_w)->cancel_button, window_cancel_button_cb);
SIGNAL_CONNECT(file_merge_w, "delete_event", window_delete_event_cb, NULL);
@@ -1042,7 +1059,7 @@ file_merge_ok_cb(GtkWidget *w, gpointer fs) {
}
g_free(cf_name);
-
+
if (merge_status != CF_OK) {
if (rfcode != NULL)
dfilter_free(rfcode);
@@ -1224,7 +1241,7 @@ file_save_update_dynamics(void)
/* We don't currently have a "Save As..." dialog box up. */
return;
}
-
+
range_update_dynamics(range_tb);
}
@@ -1242,7 +1259,12 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa
#if GTK_MAJOR_VERSION < 2
GtkAccelGroup *accel_group;
#endif
-
+
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_save_as_file(GDK_WINDOW_HWND(top_level->window), action_after_save, action_after_save_data);
+ return;
+#endif
+
if (file_save_as_w != NULL) {
/* There's already an "Save Capture File As" dialog box; reactivate it. */
reactivate_window(file_save_as_w);
@@ -1257,7 +1279,7 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa
/* Enable tooltips */
tooltips = gtk_tooltips_new();
-
+
/* build the file selection */
file_save_as_w = file_selection_new ("Ethereal: Save Capture File As",
FILE_SELECTION_SAVE);
@@ -1271,19 +1293,19 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa
accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(file_save_as_w), accel_group);
#endif
-
+
/* Container for each row of widgets */
-
+
main_vb = gtk_vbox_new(FALSE, 5);
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
file_selection_set_extra_widget(file_save_as_w, main_vb);
- gtk_widget_show(main_vb);
-
+ gtk_widget_show(main_vb);
+
/*** Packet Range frame ***/
range_fr = gtk_frame_new("Packet Range");
gtk_box_pack_start(GTK_BOX(main_vb), range_fr, FALSE, FALSE, 0);
gtk_widget_show(range_fr);
-
+
/* range table */
range_tb = range_new(&range
#if GTK_MAJOR_VERSION < 2
@@ -1315,7 +1337,7 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa
/* compressed */
compressed_cb = gtk_check_button_new_with_label("Compress with gzip");
gtk_container_add(GTK_CONTAINER(ft_hb), compressed_cb);
- /* XXX - disable output compression for now, as this doesn't work with the
+ /* XXX - disable output compression for now, as this doesn't work with the
* current optimization to simply copy a capture file if it's using the same
* encapsulation ... */
/* the rest of the implementation is just working fine :-( */
@@ -1337,7 +1359,7 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa
SIGNAL_CONNECT(GTK_FILE_SELECTION (file_save_as_w)->ok_button, "clicked",
file_save_as_ok_cb, file_save_as_w);
- window_set_cancel_button(file_save_as_w,
+ window_set_cancel_button(file_save_as_w,
GTK_FILE_SELECTION(file_save_as_w)->cancel_button, window_cancel_button_cb);
SIGNAL_CONNECT(file_save_as_w, "delete_event", window_delete_event_cb, NULL);
@@ -1373,7 +1395,7 @@ file_save_as_cb(GtkWidget *w _U_, gpointer fs) {
/* Write out the packets (all, or only the ones from the current
range) to the file with the specified name. */
- if (cf_save(&cfile, cf_name, &range, filetype,
+ if (cf_save(&cfile, cf_name, &range, filetype,
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compressed_cb))) != CF_OK) {
/* The write failed; don't dismiss the open dialog box,
just leave it around so that the user can, after they
@@ -1465,7 +1487,7 @@ static void
file_save_as_ok_cb(GtkWidget *w _U_, gpointer fs) {
gchar *cf_name;
gpointer dialog;
-
+
#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
cf_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)));
#else
@@ -1602,6 +1624,12 @@ file_color_import_cmd_cb(GtkWidget *w _U_, gpointer data)
#if GTK_MAJOR_VERSION < 2
GtkAccelGroup *accel_group;
#endif
+
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_import_color_file(GDK_WINDOW_HWND(top_level->window));
+ return;
+#endif
+
/* No Apply button, and "OK" just sets our text widget, it doesn't
activate it (i.e., it doesn't cause us to try to open the file). */
@@ -1653,7 +1681,7 @@ file_color_import_cmd_cb(GtkWidget *w _U_, gpointer data)
OBJECT_SET_DATA(GTK_FILE_SELECTION(file_color_import_w)->ok_button,
ARGUMENT_CL, data);
- window_set_cancel_button(file_color_import_w,
+ window_set_cancel_button(file_color_import_w,
GTK_FILE_SELECTION(file_color_import_w)->cancel_button, window_cancel_button_cb);
SIGNAL_CONNECT(file_color_import_w, "delete_event", window_delete_event_cb, NULL);
@@ -1670,7 +1698,7 @@ file_color_import_ok_cb(GtkWidget *w, gpointer fs) {
gpointer argument;
argument = OBJECT_GET_DATA(w, ARGUMENT_CL); /* to be passed back into color_filters_import */
-
+
#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
cf_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)));
#else
@@ -1758,6 +1786,11 @@ file_color_export_cmd_cb(GtkWidget *w _U_, gpointer data _U_)
{
GtkWidget *main_vb, *cfglobal_but;
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_export_color_file(GDK_WINDOW_HWND(top_level->window));
+ return;
+#endif
+
if (file_color_export_w != NULL) {
/* There's already an "Color Filter Export" dialog box; reactivate it. */
reactivate_window(file_color_export_w);
@@ -1803,7 +1836,7 @@ file_color_export_cmd_cb(GtkWidget *w _U_, gpointer data _U_)
SIGNAL_CONNECT(GTK_FILE_SELECTION (file_color_export_w)->ok_button, "clicked",
file_color_export_ok_cb, file_color_export_w);
- window_set_cancel_button(file_color_export_w,
+ window_set_cancel_button(file_color_export_w,
GTK_FILE_SELECTION(file_color_export_w)->cancel_button, window_cancel_button_cb);
SIGNAL_CONNECT(file_color_export_w, "delete_event", window_delete_event_cb, NULL);
diff --git a/gtk/print_dlg.c b/gtk/print_dlg.c
index fd63f4b8fe..a301b35e25 100644
--- a/gtk/print_dlg.c
+++ b/gtk/print_dlg.c
@@ -31,6 +31,7 @@
#include <gtk/gtk.h>
#include "globals.h"
+#include "gtkglobals.h"
#include "keys.h"
#include "print.h"
#include <epan/prefs.h>
@@ -51,6 +52,11 @@
#include "file_util.h"
#include "util.h"
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+#include <gdk/gdkwin32.h>
+#include <windows.h>
+#include "win32-file-dlg.h"
+#endif
/* dialog output action */
typedef enum {
@@ -144,7 +150,7 @@ file_print_cmd(gboolean print_selected)
if(print_selected) {
args->range.process = range_process_selected;
}
-
+
print_win = open_print_dialog("Ethereal: Print", output_action_print, args);
SIGNAL_CONNECT(print_win, "destroy", print_destroy_cb, &print_win);
}
@@ -178,6 +184,11 @@ export_text_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
{
print_args_t *args = &export_text_args;
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_text);
+ return;
+#endif
+
if (export_text_win != NULL) {
/* There's already a "Export text" dialog box; reactivate it. */
reactivate_window(export_text_win);
@@ -196,7 +207,7 @@ export_text_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
args->print_hex = FALSE;
args->print_formfeed = FALSE;
}
-
+
/* init the printing range */
packet_range_init(&args->range);
@@ -222,6 +233,11 @@ export_ps_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
{
print_args_t *args = &export_ps_args;
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_ps);
+ return;
+#endif
+
if (export_ps_win != NULL) {
/* There's already a "Export ps" dialog box; reactivate it. */
reactivate_window(export_ps_win);
@@ -240,7 +256,7 @@ export_ps_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
args->print_hex = FALSE;
args->print_formfeed = FALSE;
}
-
+
/* init the printing range */
packet_range_init(&args->range);
@@ -266,6 +282,11 @@ export_psml_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
{
print_args_t *args = &export_psml_args;
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_psml);
+ return;
+#endif
+
if (export_psml_win != NULL) {
/* There's already a "Export psml" dialog box; reactivate it. */
reactivate_window(export_psml_win);
@@ -284,7 +305,7 @@ export_psml_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
args->print_hex = FALSE;
args->print_formfeed = FALSE;
}
-
+
/* init the printing range */
packet_range_init(&args->range);
@@ -310,6 +331,11 @@ export_pdml_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
{
print_args_t *args = &export_pdml_args;
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_pdml);
+ return;
+#endif
+
if (export_pdml_win != NULL) {
/* There's already a "Export pdml" dialog box; reactivate it. */
reactivate_window(export_pdml_win);
@@ -328,7 +354,7 @@ export_pdml_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
args->print_hex = FALSE;
args->print_formfeed = FALSE;
}
-
+
/* init the printing range */
packet_range_init(&args->range);
@@ -352,6 +378,11 @@ export_csv_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
{
print_args_t *args = &export_csv_args;
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_csv);
+ return;
+#endif
+
if (export_csv_win != NULL) {
/* There's already a "Export csv" dialog box; reactivate it. */
reactivate_window(export_csv_win);
@@ -522,7 +553,7 @@ open_print_dialog(const char *title, output_action_e action, print_args_t *args)
gtk_table_attach_defaults(GTK_TABLE(printer_tb), dest_cb, 0, 1, 0, 1);
if(action == output_action_print)
gtk_widget_show(dest_cb);
-
+
/* File text entry */
file_te = gtk_entry_new();
OBJECT_SET_DATA(dest_cb, PRINT_FILE_TE_KEY, file_te);
@@ -597,7 +628,7 @@ open_print_dialog(const char *title, output_action_e action, print_args_t *args)
/*** packet format frame ***/
format_fr = gtk_frame_new("Packet Format");
gtk_box_pack_start(GTK_BOX(packet_hb), format_fr, TRUE, TRUE, 0);
- if( action == output_action_print ||
+ if( action == output_action_print ||
action == output_action_export_text ||
action == output_action_export_ps)
gtk_widget_show(format_fr);
@@ -805,7 +836,7 @@ print_cmd_toggle_detail(GtkWidget *widget _U_, gpointer data)
gtk_widget_set_sensitive(expand_all_rb, print_detail);
/* if user selected nothing to print at all, disable the "ok" button */
- gtk_widget_set_sensitive(print_bt,
+ gtk_widget_set_sensitive(print_bt,
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (summary_cb)) ||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (details_cb)) ||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (hex_cb)));
diff --git a/gtk/proto_draw.c b/gtk/proto_draw.c
index 5ef7d99fc5..745c55c0e1 100644
--- a/gtk/proto_draw.c
+++ b/gtk/proto_draw.c
@@ -71,6 +71,12 @@
#include "../ui_util.h"
#include "file_util.h"
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+#include <gdk/gdkwin32.h>
+#include <windows.h>
+#include "win32-file-dlg.h"
+#endif
+
#define BYTE_VIEW_WIDTH 16
#define BYTE_VIEW_SEP 8
@@ -223,9 +229,9 @@ redraw_hex_dump_all(void)
#if GTK_MAJOR_VERSION >= 2
/* XXX - this is a hack, to workaround a bug in GTK2.x!
- when changing the font size, even refilling of the corresponding
- gtk_text_buffer doesn't seem to trigger an update.
- The only workaround is to freshly select the frame, which will remove any
+ when changing the font size, even refilling of the corresponding
+ gtk_text_buffer doesn't seem to trigger an update.
+ The only workaround is to freshly select the frame, which will remove any
existing notebook tabs and "restart" the whole byte view again. */
if (cfile.current_frame != NULL)
cf_goto_frame(&cfile, cfile.current_frame->num);
@@ -698,7 +704,7 @@ add_byte_tab(GtkWidget *byte_nb, const char *name, tvbuff_t *tvb,
/* Horizontal */GTK_POLICY_NEVER,
/* Vertical*/ GTK_POLICY_ALWAYS);
#else
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(byte_scrollw),
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(byte_scrollw),
GTK_SHADOW_IN);
#endif
/* Add scrolled pane to tabbed window */
@@ -745,7 +751,7 @@ add_byte_tab(GtkWidget *byte_nb, const char *name, tvbuff_t *tvb,
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(byte_nb), TRUE);
/* set this page (this will print the packet data) */
- gtk_notebook_set_page(GTK_NOTEBOOK(byte_nb),
+ gtk_notebook_set_page(GTK_NOTEBOOK(byte_nb),
gtk_notebook_page_num(GTK_NOTEBOOK(byte_nb), byte_nb));
return byte_view;
@@ -797,7 +803,7 @@ savehex_dlg_destroy_cb(void)
}
void
-copy_hex_cb(GtkWidget * w _U_, gpointer data _U_)
+copy_hex_cb(GtkWidget * w _U_, gpointer data _U_)
{
GtkWidget *bv;
int len;
@@ -805,16 +811,16 @@ copy_hex_cb(GtkWidget * w _U_, gpointer data _U_)
const guint8 *data_p = NULL;
GString *ASCII_representation = g_string_new("");
GString *byte_str = g_string_new("");
-
+
bv = get_notebook_bv_ptr(byte_nb_ptr);
if (bv == NULL) {
- /* shouldn't happen */
+ /* shouldn't happen */
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not find the corresponding text window!");
return;
}
-
+
data_p = get_byte_view_data_and_length(GTK_WIDGET(bv), &len);
-
+
g_string_sprintfa(byte_str,"%04x ",i); /* Offset 0000 */
for (i=0; i<len; i++){
g_string_sprintfa(ASCII_representation,"%c",isprint(*data_p) ? *data_p : '.');
@@ -824,7 +830,7 @@ copy_hex_cb(GtkWidget * w _U_, gpointer data _U_)
g_string_assign (ASCII_representation,"");
}
}
-
+
if(ASCII_representation->len){
for (i=ASCII_representation->len; i<16; i++){
g_string_sprintfa(byte_str," ");
@@ -866,7 +872,7 @@ savehex_save_clicked_cb(GtkWidget * w _U_, gpointer data _U_)
return;
}
/*
- * Retrieve the info we need
+ * Retrieve the info we need
*/
end = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_START_KEY));
start = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_END_KEY));
@@ -902,11 +908,15 @@ void savehex_cb(GtkWidget * w _U_, gpointer data _U_)
{
int start, end, len;
const guint8 *data_p = NULL;
- gchar *label;
+ gchar *label;
- GtkWidget *bv;
+ GtkWidget *bv;
GtkWidget *dlg_lb;
+#if GTK_MAJOR_VERSION >= 2 && _WIN32
+ win32_export_raw_file(GDK_WINDOW_HWND(top_level->window));
+ return;
+#endif
/* don't show up the dialog, if no data has to be saved */
bv = get_notebook_bv_ptr(byte_nb_ptr);
@@ -936,7 +946,7 @@ void savehex_cb(GtkWidget * w _U_, gpointer data _U_)
savehex_dlg = file_selection_new("Ethereal: Export Selected Packet Bytes", FILE_SELECTION_SAVE);
/* label */
- label = g_strdup_printf("Will save %u %s of raw binary data to specified file.",
+ label = g_strdup_printf("Will save %u %s of raw binary data to specified file.",
end - start, plurality(end - start, "byte", "bytes"));
dlg_lb = gtk_label_new(label);
g_free(label);
@@ -957,7 +967,7 @@ void savehex_cb(GtkWidget * w _U_, gpointer data _U_)
SIGNAL_CONNECT(GTK_FILE_SELECTION (savehex_dlg)->ok_button, "clicked",
savehex_save_clicked_cb, savehex_dlg);
- window_set_cancel_button(savehex_dlg,
+ window_set_cancel_button(savehex_dlg,
GTK_FILE_SELECTION(savehex_dlg)->cancel_button, window_cancel_button_cb);
SIGNAL_CONNECT(savehex_dlg, "delete_event", window_delete_event_cb, NULL);
@@ -1607,7 +1617,7 @@ GdkColor expert_color_note = { 0, 0xa000, 0xff00, 0xff00 }; /* a bright turquois
GdkColor expert_color_warn = { 0, 0xff00, 0xff00, 0 }; /* yellow */
GdkColor expert_color_error = { 0, 0xff00, 0x5c00, 0x5c00 }; /* pale red */
-void proto_draw_colors_init(void)
+void proto_draw_colors_init(void)
{
if(colors_ok) {
return;
@@ -1643,7 +1653,7 @@ static void tree_cell_renderer(GtkTreeViewColumn *tree_column _U_,
* color definitions can be found at:
* http://cvs.gnome.org/viewcvs/gtk+/gdk-pixbuf/io-xpm.c?rev=1.42
* (a good color overview: http://www.computerhope.com/htmcolor.htm)
- *
+ *
* some experiences:
* background-gdk: doesn't seem to work (probably the GdkColor must be allocated)
* weight/style: doesn't take any effect
@@ -1788,7 +1798,7 @@ main_tree_view_new(e_prefs *prefs, GtkWidget **tree_view_p)
/* Tree view */
tv_scrollw = scrolled_window_new(NULL, NULL);
#if GTK_MAJOR_VERSION >= 2
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(tv_scrollw),
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(tv_scrollw),
GTK_SHADOW_IN);
#endif
@@ -1920,7 +1930,7 @@ tree_view_select(GtkWidget *widget, GdkEventButton *event)
field_info *fi;
- if(gtk_clist_get_selection_info(GTK_CLIST(widget),
+ if(gtk_clist_get_selection_info(GTK_CLIST(widget),
(gint) (((GdkEventButton *)event)->x),
(gint) (((GdkEventButton *)event)->y),
&row, &column))
diff --git a/gtk/win32-file-dlg.c b/gtk/win32-file-dlg.c
new file mode 100755
index 0000000000..a539c754a0
--- /dev/null
+++ b/gtk/win32-file-dlg.c
@@ -0,0 +1,1453 @@
+/* win32-file-dlg.c
+ * Native Windows file dialog routines
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 2004 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "globals.h"
+
+#include <glib.h>
+
+#include <stdio.h>
+
+#include <windows.h>
+#include <windowsx.h>
+#include <commdlg.h>
+#include <commctrl.h>
+#include <richedit.h>
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <fcntl.h>
+
+#include "alert_box.h"
+#include "color.h"
+#include "color_filters.h"
+#include "epan/filesystem.h"
+#include "epan/addr_resolv.h"
+#include "merge.h"
+#include "epan/prefs.h"
+#include "print.h"
+#include "simple_dialog.h"
+#include "util.h"
+
+// XXX - declarations from gtk/file_dlg.h. These should be moved
+// somewhere less GTK-specific.
+/** the action to take, after save has been done */
+typedef enum {
+ after_save_no_action, /**< no action to take */
+ after_save_close_file, /**< close the file */
+ after_save_open_dialog, /**< open the file open dialog */
+ after_save_open_recent_file, /**< open the specified recent file */
+ after_save_open_dnd_file, /**< open the specified file from drag and drop */
+ after_save_merge_dialog, /**< open the file merge dialog */
+ after_save_capture_dialog, /**< open the capture dialog */
+ after_save_exit /**< exit program */
+} action_after_save_e;
+
+#include "win32-file-dlg.h"
+
+// XXX - declarations from gtk/dlg_utils.h. These should be moved
+// somewhere less GTK-specific.
+extern void set_last_open_dir(char *dirname);
+
+// XXX - declarations from gtk/capture_dlg.h. These should be moved
+// somewhere less GTK-specific.
+/* capture start confirmed by "Save unsaved capture", so do it now */
+void capture_start_confirmed(void);
+
+// gtk/main.h:
+extern gboolean main_do_quit(void);
+
+
+
+
+typedef enum {
+ merge_append,
+ merge_chrono,
+ merge_prepend
+} merge_action_e;
+
+#define FILE_TYPE_LIST \
+ "Accellent 5Views (*.5vw)\0" "*.5vw\0" \
+ "Ethereal/tcpdump (*.cap, *.pcap)\0" "*.cap;*.pcap\0" \
+ "Novell LANalyzer (*.tr1)\0" "*.tr1\0" \
+ "NG/NAI Sniffer (*.cap, *.enc, *.trc)\0" "*.cap;*.enc;*.trc\0" \
+ "Sun snoop (*.snoop)\0" "*.snoop\0" \
+ "WildPackets EtherPeek (*.pkt)\0" "*.pkt\0" \
+ "All Files (*.*)\0" "*.*\0" \
+ "\0"
+
+#define FILE_TYPE_DEFAULT 2 /* Ethereal/tcpdump */
+
+
+static UINT CALLBACK open_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
+static UINT CALLBACK save_as_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
+static UINT CALLBACK merge_file_hook_proc(HWND mf_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
+static UINT CALLBACK export_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
+static UINT CALLBACK export_raw_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
+static void range_update_dynamics(HWND sf_hwnd, packet_range_t *range);
+static void range_handle_wm_initdialog(HWND dlg_hwnd, packet_range_t *range);
+static void range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, packet_range_t *range);
+
+static gboolean initialized = FALSE;
+static int filetype;
+static packet_range_t range;
+static merge_action_e merge_action;
+static print_args_t print_args;
+/* XXX - The reason g_sf_hwnd exists is so that we can call
+ * file_set_save_marked_sensitive() from anywhere. However, the
+ * save file dialog hogs the foreground, so this may not be
+ * necessary.
+ */
+static HWND g_sf_hwnd = NULL;
+
+static void
+win32_file_init() {
+ INITCOMMONCONTROLSEX comm_ctrl;
+
+ if (initialized)
+ return;
+ initialized = TRUE;
+
+ /* Initialize our controls. */
+ memset (&comm_ctrl, 0, sizeof(comm_ctrl));
+ comm_ctrl.dwSize = sizeof(comm_ctrl);
+ /* Includes the animate, header, hot key, list view, progress bar,
+ * status bar, tab, tooltip, toolbar, trackbar, tree view, and
+ * up-down controls
+ */
+ comm_ctrl.dwICC = ICC_WIN95_CLASSES;
+ InitCommonControlsEx(&comm_ctrl);
+
+ /* RichEd20.DLL is needed for filter entries. */
+ LoadLibrary("riched20.dll");
+}
+
+gboolean
+win32_open_file (HWND h_wnd) {
+ static OPENFILENAME ofn;
+ gchar file_name[MAX_PATH] = "";
+ int err;
+ char *dirname;
+
+ win32_file_init();
+
+ /* XXX - Check for version and set OPENFILENAME_SIZE_VERSION_400
+ where appropriate */
+ ZeroMemory(&ofn, sizeof(ofn));
+#ifdef OPENFILENAME_SIZE_VERSION_400
+ of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+#else
+ ofn.lStructSize = sizeof(ofn);
+#endif
+ ofn.hwndOwner = h_wnd;
+ ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
+ /* XXX - Grab the rest of the extension list from ethereal.nsi. */
+ ofn.lpstrFilter = FILE_TYPE_LIST;
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.nFilterIndex = FILE_TYPE_DEFAULT;
+ ofn.lpstrFile = file_name;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') {
+ ofn.lpstrInitialDir = prefs.gui_fileopen_dir;
+ } else {
+ ofn.lpstrInitialDir = NULL;
+ }
+ ofn.lpstrTitle = "Ethereal: Select a capture file";
+ ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
+ OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
+ OFN_ENABLEHOOK;
+ ofn.lpstrDefExt = NULL;
+ ofn.lpfnHook = open_file_hook_proc;
+ ofn.lpTemplateName = "ETHEREAL_OPENFILENAME_TEMPLATE";
+
+ /* XXX - Get our filter */
+
+ if (GetOpenFileName(&ofn)) {
+ if (cf_open(&cfile, file_name, FALSE, &err) != CF_OK) {
+ epan_cleanup();
+ exit(2);
+ }
+ switch (cf_read(&cfile)) {
+ case CF_READ_OK:
+ case CF_READ_ERROR:
+ dirname = get_dirname(file_name);
+ set_last_open_dir(dirname);
+// menu_name_resolution_changed(h_wnd);
+ return TRUE;
+ break;
+ }
+ }
+ return FALSE;
+}
+
+
+void
+win32_save_as_file(HWND h_wnd, action_after_save_e action_after_save, gpointer action_after_save_data) {
+ static OPENFILENAME ofn;
+ gchar file_name[MAX_PATH] = "";
+ gchar *dirname;
+
+ /* XXX - Check for version and set OPENFILENAME_SIZE_VERSION_400
+ where appropriate */
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = h_wnd;
+ ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
+ /* XXX - Grab the rest of the extension list from ethereal.nsi. */
+ ofn.lpstrFilter = FILE_TYPE_LIST;
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.nFilterIndex = FILE_TYPE_DEFAULT;
+ ofn.lpstrFile = file_name;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') {
+ ofn.lpstrInitialDir = prefs.gui_fileopen_dir;
+ } else {
+ ofn.lpstrInitialDir = NULL;
+ }
+ ofn.lpstrTitle = "Ethereal: Save file as";
+ ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
+ OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
+ OFN_PATHMUSTEXIST | OFN_ENABLEHOOK;
+ ofn.lpstrDefExt = NULL;
+ ofn.lpfnHook = save_as_file_hook_proc;
+ ofn.lpTemplateName = "ETHEREAL_SAVEFILENAME_TEMPLATE";
+
+ if (GetSaveFileName(&ofn)) {
+ g_sf_hwnd = NULL;
+ /* Write out the packets (all, or only the ones from the current
+ range) to the file with the specified name. */
+ /* XXX - If we're overwriting a file, GetSaveFileName does the
+ standard windows confirmation. cf_save() then rejects the overwrite. */
+ if (cf_save(&cfile, file_name, &range, filetype, FALSE) != CF_OK) {
+ /* The write failed. Try again. */
+ win32_save_as_file(h_wnd, action_after_save, action_after_save_data);
+ return;
+ }
+
+ /* Save the directory name for future file dialogs. */
+ dirname = get_dirname(file_name); /* Overwrites cf_name */
+ set_last_open_dir(dirname);
+
+ /* we have finished saving, do we have pending things to do? */
+ switch(action_after_save) {
+ case(after_save_no_action):
+ break;
+ case(after_save_open_dialog):
+ win32_open_file(h_wnd);
+ break;
+ case(after_save_open_recent_file):
+// menu_open_recent_file_cmd(action_after_save_data_g);
+ break;
+ case(after_save_open_dnd_file):
+// dnd_open_file_cmd(action_after_save_data_g);
+ break;
+ case(after_save_merge_dialog):
+// file_merge_cmd(action_after_save_data_g);
+ break;
+#ifdef HAVE_LIBPCAP
+ case(after_save_capture_dialog):
+ capture_start_confirmed();
+ break;
+#endif
+ case(after_save_close_file):
+ cf_close(&cfile);
+ break;
+ case(after_save_exit):
+ main_do_quit();
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ }
+ g_sf_hwnd = NULL;
+}
+
+
+void
+win32_merge_file (HWND h_wnd) {
+ static OPENFILENAME ofn;
+ gchar file_name[MAX_PATH] = "";
+ char *dirname;
+ cf_status_t merge_status;
+ char *in_filenames[2];
+ int err;
+ char *tmpname;
+
+ /* XXX - Check for temp file and prompt accordingly */
+
+ /* XXX - Check for version and set OPENFILENAME_SIZE_VERSION_400
+ where appropriate */
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = h_wnd;
+ ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
+ /* XXX - Grab the rest of the extension list from ethereal.nsi. */
+ ofn.lpstrFilter = FILE_TYPE_LIST;
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.nFilterIndex = FILE_TYPE_DEFAULT;
+ ofn.lpstrFile = file_name;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') {
+ ofn.lpstrInitialDir = prefs.gui_fileopen_dir;
+ } else {
+ ofn.lpstrInitialDir = NULL;
+ }
+ ofn.lpstrTitle = "Ethereal: Merge with capture file";
+ ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
+ OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
+ OFN_ENABLEHOOK;
+ ofn.lpstrDefExt = NULL;
+ ofn.lpfnHook = merge_file_hook_proc;
+ ofn.lpTemplateName = "ETHEREAL_MERGEFILENAME_TEMPLATE";
+
+ if (GetOpenFileName(&ofn)) {
+ filetype = cfile.cd_t;
+
+ /* merge or append the two files */
+
+ tmpname = NULL;
+ switch (merge_action) {
+ case merge_append:
+ /* append file */
+ in_filenames[0] = file_name;
+ in_filenames[1] = cfile.filename;
+ merge_status = cf_merge_files(&tmpname, 2, in_filenames, filetype, TRUE);
+ break;
+ case merge_chrono:
+ /* chonological order */
+ in_filenames[0] = cfile.filename;
+ in_filenames[1] = file_name;
+ merge_status = cf_merge_files(&tmpname, 2, in_filenames, filetype, FALSE);
+ break;
+ case merge_prepend:
+ /* prepend file */
+ in_filenames[0] = cfile.filename;
+ in_filenames[1] = file_name;
+ merge_status = cf_merge_files(&tmpname, 2, in_filenames, filetype, TRUE);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if(merge_status != CF_OK) {
+ /* merge failed */
+ g_free(tmpname);
+// if (rfcode != NULL)
+// dfilter_free(rfcode);
+ return;
+ }
+
+ cf_close(&cfile);
+
+ /* Try to open the merged capture file. */
+ if (cf_open(&cfile, tmpname, TRUE /* temporary file */, &err) != CF_OK) {
+ /* We couldn't open it; don't dismiss the open dialog box,
+ just leave it around so that the user can, after they
+ dismiss the alert box popped up for the open error,
+ try again. */
+// if (rfcode != NULL)
+// dfilter_free(rfcode);
+ return;
+ }
+
+ /* Attach the new read filter to "cf" ("cf_open()" succeeded, so
+ it closed the previous capture file, and thus destroyed any
+ previous read filter attached to "cf"). */
+// cfile.rfcode = rfcode;
+
+ switch (cf_read(&cfile)) {
+ case CF_READ_OK:
+ case CF_READ_ERROR:
+ dirname = get_dirname(file_name);
+ set_last_open_dir(dirname);
+// menu_name_resolution_changed(h_wnd);
+ break;
+ case CF_READ_ABORTED:
+ break;
+ }
+
+ } else if (CommDlgExtendedError() != 0) {
+ sprintf(file_name, "failed: %d/%d (%p)", CommDlgExtendedError(), GetLastError(), h_wnd);
+ MessageBox(NULL, file_name, "Eth", MB_OK);
+ }
+}
+
+void
+win32_export_file(HWND h_wnd, export_type_e export_type) {
+ static OPENFILENAME ofn;
+ gchar file_name[MAX_PATH] = "";
+ char *dirname;
+ cf_print_status_t status;
+
+ /* XXX - Check for version and set OPENFILENAME_SIZE_VERSION_400
+ where appropriate */
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = h_wnd;
+ ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
+ ofn.lpstrFilter =
+ "Plain text (*.txt)\0" "*.txt\0"
+ "PostScript (*.ps)\0" "*.ps\0"
+ "CSV (Comma Separated Values summary (*.csv)\0" "*.csv\0"
+ "PSML (XML packet summary) (*.psml)\0" "*.psml\0"
+ "PDML (XML packet detail) (*.pdml)\0" "*.pdml\0"
+ "\0";
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.nFilterIndex = export_type;
+ ofn.lpstrFile = file_name;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') {
+ ofn.lpstrInitialDir = prefs.gui_fileopen_dir;
+ } else {
+ ofn.lpstrInitialDir = NULL;
+ }
+ ofn.lpstrTitle = "Ethereal: Export";
+ ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
+ OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
+ OFN_PATHMUSTEXIST | OFN_ENABLEHOOK;
+ ofn.lpstrDefExt = NULL;
+ ofn.lpfnHook = export_file_hook_proc;
+ ofn.lpTemplateName = "ETHEREAL_EXPORTFILENAME_TEMPLATE";
+
+ /* Fill in our print (and export) args */
+
+ print_args.format = PR_FMT_TEXT;
+ print_args.to_file = TRUE;
+ print_args.file = file_name;
+ print_args.cmd = NULL;
+ print_args.print_summary = TRUE;
+ print_args.print_dissections = print_dissections_as_displayed;
+ print_args.print_hex = FALSE;
+ print_args.print_formfeed = FALSE;
+
+ if (GetSaveFileName(&ofn)) {
+ switch (ofn.nFilterIndex) {
+ case export_type_text: /* Text */
+ print_args.stream = print_stream_text_new(TRUE, print_args.file);
+ if (print_args.stream == NULL) {
+ open_failure_alert_box(print_args.file, errno, TRUE);
+ return;
+ }
+ status = cf_print_packets(&cfile, &print_args);
+ break;
+ case export_type_ps: /* PostScript (r) */
+ print_args.stream = print_stream_ps_new(TRUE, print_args.file);
+ if (print_args.stream == NULL) {
+ open_failure_alert_box(print_args.file, errno, TRUE);
+ return;
+ }
+ status = cf_print_packets(&cfile, &print_args);
+ break;
+ case export_type_csv: /* CSV */
+ status = cf_write_csv_packets(&cfile, &print_args);
+ break;
+ case export_type_psml: /* PSML */
+ status = cf_write_psml_packets(&cfile, &print_args);
+ break;
+ case export_type_pdml: /* PDML */
+ status = cf_write_pdml_packets(&cfile, &print_args);
+ break;
+ default:
+ return;
+ }
+
+ switch (status) {
+ case CF_PRINT_OK:
+ break;
+ case CF_PRINT_OPEN_ERROR:
+ open_failure_alert_box(print_args.file, errno, TRUE);
+ break;
+ case CF_PRINT_WRITE_ERROR:
+ write_failure_alert_box(print_args.file, errno);
+ break;
+ }
+ /* Save the directory name for future file dialogs. */
+ dirname = get_dirname(file_name); /* Overwrites cf_name */
+ set_last_open_dir(dirname);
+ }
+}
+
+void
+win32_export_raw_file(HWND h_wnd) {
+ static OPENFILENAME ofn;
+ gchar file_name[MAX_PATH] = "";
+ char *dirname;
+ const guint8 *data_p = NULL;
+ const char *file = NULL;
+ int fd;
+
+ if (!cfile.finfo_selected) {
+ /* This shouldn't happen */
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No bytes were selected.");
+ return;
+ }
+
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = h_wnd;
+ ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
+ /* XXX - Grab the rest of the extension list from ethereal.nsi. */
+ ofn.lpstrFilter =
+ "Raw data (*.bin, *.dat, *.raw)\0" "*.bin;*.dat;*.raw\0"
+ "All Files (*.*)\0" "*.*\0"
+ "\0";
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFile = file_name;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') {
+ ofn.lpstrInitialDir = prefs.gui_fileopen_dir;
+ } else {
+ ofn.lpstrInitialDir = NULL;
+ }
+ ofn.lpstrTitle = "Ethereal: Export Raw Data";
+ ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
+ OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
+ OFN_PATHMUSTEXIST | OFN_ENABLEHOOK;
+ ofn.lpstrDefExt = NULL;
+ ofn.lCustData = cfile.finfo_selected->length;
+ ofn.lpfnHook = export_raw_file_hook_proc;
+ ofn.lpTemplateName = "ETHEREAL_EXPORTRAWFILENAME_TEMPLATE";
+
+ /*
+ * XXX - The GTK+ code uses get_byte_view_data_and_length(). We just
+ * grab the info from cfile.finfo_selected. Which is more "correct"?
+ */
+
+ if (GetSaveFileName(&ofn)) {
+
+ data_p = tvb_get_ptr(cfile.finfo_selected->ds_tvb, 0, -1) +
+ cfile.finfo_selected->start;
+ fd = open(file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
+ if (fd == -1) {
+ open_failure_alert_box(file, errno, TRUE);
+ return;
+ }
+ if (write(fd, data_p, cfile.finfo_selected->length) < 0) {
+ write_failure_alert_box(file, errno);
+ close(fd);
+ return;
+ }
+ if (close(fd) < 0) {
+ write_failure_alert_box(file, errno);
+ return;
+ }
+
+ /* Save the directory name for future file dialogs. */
+ dirname = get_dirname(file_name); /* Overwrites cf_name */
+ set_last_open_dir(dirname);
+ }
+}
+
+void
+win32_export_color_file(HWND h_wnd) {
+ static OPENFILENAME ofn;
+ gchar file_name[MAX_PATH] = "";
+ char *dirname;
+
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = h_wnd;
+ ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
+ /* XXX - Grab the rest of the extension list from ethereal.nsi. */
+ ofn.lpstrFilter =
+ "Text Files (*.txt)\0" "*.txt\0"
+ "All Files (*.*)\0" "*.*\0"
+ "\0";
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.nFilterIndex = 2;
+ ofn.lpstrFile = file_name;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.lpstrTitle = "Ethereal: Export Color Filters";
+ ofn.Flags = OFN_ENABLESIZING | OFN_EXPLORER |
+ OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
+ OFN_PATHMUSTEXIST | OFN_ENABLEHOOK;
+ ofn.lpstrDefExt = NULL;
+ ofn.lpfnHook = NULL;
+ ofn.lpTemplateName = NULL;
+
+ filetype = cfile.cd_t;
+
+ /* XXX - Support marked filters */
+ if (GetSaveFileName(&ofn)) {
+ if (!color_filters_export(file_name, FALSE))
+ return;
+
+ /* Save the directory name for future file dialogs. */
+ dirname = get_dirname(file_name); /* Overwrites cf_name */
+ set_last_open_dir(dirname);
+ }
+}
+
+void
+win32_import_color_file(HWND h_wnd) {
+ static OPENFILENAME ofn;
+ gchar file_name[MAX_PATH] = "";
+ char *dirname;
+
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = h_wnd;
+ ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
+ /* XXX - Grab the rest of the extension list from ethereal.nsi. */
+ ofn.lpstrFilter =
+ "Text Files (*.txt)\0" "*.txt\0"
+ "All Files (*.*)\0" "*.*\0"
+ "\0";
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.nFilterIndex = 2;
+ ofn.lpstrFile = file_name;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.lpstrTitle = "Ethereal: Import Color Filters";
+ ofn.Flags = OFN_ENABLESIZING | OFN_EXPLORER |
+ OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
+ OFN_PATHMUSTEXIST | OFN_ENABLEHOOK;
+ ofn.lpstrDefExt = NULL;
+ ofn.lpfnHook = NULL;
+ ofn.lpTemplateName = NULL;
+
+ /* XXX - Support marked filters */
+ if (GetOpenFileName(&ofn)) {
+ if (!color_filters_import(file_name, NULL))
+ return;
+
+ /* Save the directory name for future file dialogs. */
+ dirname = get_dirname(file_name); /* Overwrites cf_name */
+ set_last_open_dir(dirname);
+ }
+}
+
+
+/*
+ * Private routines
+ */
+static void
+format_handle_wm_initdialog(HWND dlg_hwnd, print_args_t *args) {
+ HWND cur_ctrl;
+
+ /* Set the "Packet summary" box */
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_SUMMARY_CB);
+ SendMessage(cur_ctrl, BM_SETCHECK, args->print_summary, 0);
+
+ /* Set the "Packet details" box */
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_CB);
+ SendMessage(cur_ctrl, BM_SETCHECK, args->print_dissections != print_dissections_none, 0);
+
+ /* Set the "Packet details" combo */
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_COMBO);
+ SendMessage(cur_ctrl, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "All collapsed");
+ SendMessage(cur_ctrl, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "As displayed");
+ SendMessage(cur_ctrl, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "All expanded");
+
+ switch (args->print_dissections) {
+ case print_dissections_none:
+ case print_dissections_collapsed:
+ SendMessage(cur_ctrl, CB_SETCURSEL, 0, 0);
+ break;
+ case print_dissections_as_displayed:
+ SendMessage(cur_ctrl, CB_SETCURSEL, 1, 0);
+ break;
+ case print_dissections_expanded:
+ SendMessage(cur_ctrl, CB_SETCURSEL, 2, 0);
+ default:
+ g_assert_not_reached();
+ }
+
+ /* Set the "Packet bytes" box */
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_BYTES_CB);
+ SendMessage(cur_ctrl, BM_SETCHECK, args->print_hex, 0);
+
+ /* Set the "Each packet on a new page" box */
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_NEW_PAGE_CB);
+ SendMessage(cur_ctrl, BM_SETCHECK, args->print_formfeed, 0);
+
+ print_update_dynamic(dlg_hwnd, args);
+}
+
+static void
+print_update_dynamic(HWND dlg_hwnd, print_args_t *args) {
+ HWND cur_ctrl;
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_SUMMARY_CB);
+ if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ args->print_summary = TRUE;
+ else
+ args->print_summary = FALSE;
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_CB);
+ if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
+ switch (SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0)) {
+ case 0:
+ args->print_dissections = print_dissections_collapsed;
+ break;
+ case 1:
+ args->print_dissections = print_dissections_as_displayed;
+ break;
+ case 2:
+ args->print_dissections = print_dissections_expanded;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_COMBO);
+ EnableWindow(cur_ctrl, TRUE);
+ } else {
+ args->print_dissections = print_dissections_none;
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_COMBO);
+ EnableWindow(cur_ctrl, FALSE);
+ }
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_BYTES_CB);
+ if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ args->print_hex = TRUE;
+ else
+ args->print_hex = FALSE;
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_NEW_PAGE_CB);
+ if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ args->print_formfeed = TRUE;
+ else
+ args->print_formfeed = FALSE;
+}
+
+
+/*
+ * Private routines
+ */
+
+#define PREVIEW_STR_MAX 200
+#define PREVIEW_TIMEOUT_SECS 3
+
+
+/* If preview_file is NULL, disable the elements. If not, enable and
+ * show the preview info. */
+static gboolean
+preview_set_filename(HWND of_hwnd, gchar *preview_file) {
+ HWND cur_ctrl;
+ int i;
+ gboolean enable = FALSE;
+ wtap *wth;
+ const struct wtap_pkthdr *phdr;
+ int err = 0;
+ gchar *err_info;
+ long data_offset;
+ gchar string_buff[PREVIEW_STR_MAX];
+ guint packet = 0;
+ guint64 filesize;
+ time_t ti_time;
+ struct tm *ti_tm;
+ guint elapsed_time;
+ time_t time_preview;
+ time_t time_current;
+ double start_time = 0;
+ double stop_time = 0;
+ double cur_time;
+ gboolean is_breaked = FALSE;
+
+ if (preview_file != NULL && strlen(preview_file) > 0) {
+ enable = TRUE;
+ }
+
+ for (i = EWFD_PT_FILENAME; i <= EWFD_PTX_ELAPSED; i++) {
+ cur_ctrl = GetDlgItem(of_hwnd, i);
+ if (cur_ctrl) {
+ EnableWindow(cur_ctrl, enable);
+ }
+ }
+
+ for (i = EWFD_PTX_FILENAME; i <= EWFD_PTX_ELAPSED; i++) {
+ cur_ctrl = GetDlgItem(of_hwnd, i);
+ if (cur_ctrl) {
+ SetWindowText(cur_ctrl, "-");
+ }
+ }
+
+ if (enable) {
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FILENAME);
+ SetWindowText(cur_ctrl, get_basename(preview_file));
+
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FORMAT);
+ wth = wtap_open_offline(preview_file, &err, &err_info, TRUE);
+ if (cur_ctrl && wth == NULL) {
+ if(err == WTAP_ERR_FILE_UNKNOWN_FORMAT) {
+ SetWindowText(cur_ctrl, "unknown file format");
+ } else {
+ SetWindowText(cur_ctrl, "error opening file");
+ }
+ return FALSE;
+ }
+
+ /* size */
+ filesize = wtap_file_size(wth, &err);
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "%" PRIu64 " bytes", filesize);
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_SIZE);
+ SetWindowText(cur_ctrl, string_buff);
+
+ /* type */
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "%s", wtap_file_type_string(wtap_file_type(wth)));
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FORMAT);
+ SetWindowText(cur_ctrl, string_buff);
+
+ time(&time_preview);
+ while ( (wtap_read(wth, &err, &err_info, &data_offset)) ) {
+ phdr = wtap_phdr(wth);
+ cur_time = nstime_to_sec( (const nstime_t *) &phdr->ts );
+ if(packet == 0) {
+ start_time = cur_time;
+ stop_time = cur_time;
+ }
+ if (cur_time < start_time) {
+ start_time = cur_time;
+ }
+ if (cur_time > stop_time){
+ stop_time = cur_time;
+ }
+ packet++;
+ if(packet%100) {
+ time(&time_current);
+ if(time_current-time_preview >= PREVIEW_TIMEOUT_SECS) {
+ is_breaked = TRUE;
+ break;
+ }
+ }
+ }
+
+ if(err != 0) {
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "error after reading %u packets", packet);
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_PACKETS);
+ SetWindowText(cur_ctrl, string_buff);
+ wtap_close(wth);
+ return TRUE;
+ }
+
+ /* packet count */
+ if(is_breaked) {
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "more than %u packets (preview timeout)", packet);
+ } else {
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "%u", packet);
+ }
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_PACKETS);
+ SetWindowText(cur_ctrl, string_buff);
+
+ /* first packet */
+ ti_time = (long)start_time;
+ ti_tm = localtime( &ti_time );
+ g_snprintf(string_buff, PREVIEW_STR_MAX,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ ti_tm->tm_year + 1900,
+ ti_tm->tm_mon + 1,
+ ti_tm->tm_mday,
+ ti_tm->tm_hour,
+ ti_tm->tm_min,
+ ti_tm->tm_sec);
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FIRST_PKT);
+ SetWindowText(cur_ctrl, string_buff);
+
+ /* elapsed time */
+ elapsed_time = (unsigned int)(stop_time-start_time);
+ if(elapsed_time/86400) {
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u days %02u:%02u:%02u",
+ elapsed_time/86400, elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
+ } else {
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u:%02u:%02u",
+ elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
+ }
+ if(is_breaked) {
+ g_snprintf(string_buff, PREVIEW_STR_MAX, "unknown");
+ }
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_ELAPSED);
+ SetWindowText(cur_ctrl, string_buff);
+
+ wtap_close(wth);
+ }
+
+ return TRUE;
+
+}
+
+// XXX - Copied from "filter-util.c" in the ethereal-win32 branch
+/* XXX - The only reason for the "filter_text" parameter is to be able to feed
+ * in the "real" filter string in the case of a CBN_SELCHANGE notification message.
+ */
+void
+filter_tb_syntax_check(HWND hwnd, gchar *filter_text) {
+ gchar *strval = NULL;
+ gint len;
+ dfilter_t *dfp;
+
+ /* If filter_text is non-NULL, use it. Otherwise, grab the text from
+ * the window */
+ if (filter_text) {
+ strval = g_strdup(filter_text);
+ len = lstrlen(filter_text);
+ } else {
+ len = GetWindowTextLength(hwnd);
+ if (len > 0) {
+ len++;
+ strval = g_malloc(len);
+ GetWindowText(hwnd, strval, len);
+ }
+ }
+
+ if (len == 0) {
+ /* Default window background */
+ SendMessage(hwnd, EM_SETBKGNDCOLOR, (WPARAM) 1, COLOR_WINDOW);
+ return;
+ } else if (dfilter_compile(strval, &dfp)) { /* colorize filter string entry */
+ if (dfp != NULL)
+ dfilter_free(dfp);
+ /* Valid (light green) */
+ SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, 0x00afffaf);
+ } else {
+ /* Invalid (light red) */
+ SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, 0x00afafff);
+ }
+
+ if (strval) g_free(strval);
+}
+
+
+static UINT CALLBACK
+open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
+ HWND cur_ctrl, parent;
+ OFNOTIFY *notify = (OFNOTIFY *) l_param;
+ gchar sel_name[MAX_PATH];
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ /* XXX - Retain the filter text, and fill it in. */
+
+ /* Fill in our resolution values */
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_MAC_NR_CB);
+ SendMessage(cur_ctrl, BM_SETCHECK, g_resolv_flags & RESOLV_MAC, 0);
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_NET_NR_CB);
+ SendMessage(cur_ctrl, BM_SETCHECK, g_resolv_flags & RESOLV_NETWORK, 0);
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_TRANS_NR_CB);
+ SendMessage(cur_ctrl, BM_SETCHECK, g_resolv_flags & RESOLV_TRANSPORT, 0);
+
+ preview_set_filename(of_hwnd, NULL);
+ break;
+ case WM_NOTIFY:
+ switch (notify->hdr.code) {
+ case CDN_FILEOK:
+ /* XXX - Fetch the read filter */
+ /* Fetch our resolution values */
+ g_resolv_flags = prefs.name_resolve & RESOLV_CONCURRENT;
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_MAC_NR_CB);
+ if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ g_resolv_flags |= RESOLV_MAC;
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_NET_NR_CB);
+ if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ g_resolv_flags |= RESOLV_NETWORK;
+ cur_ctrl = GetDlgItem(of_hwnd, EWFD_TRANS_NR_CB);
+ if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ g_resolv_flags |= RESOLV_TRANSPORT;
+ break;
+ case CDN_SELCHANGE:
+ /* This _almost_ works correctly. We need to handle directory
+ selections, etc. */
+ parent = GetParent(of_hwnd);
+ CommDlg_OpenSave_GetSpec(parent, sel_name, MAX_PATH);
+ preview_set_filename(of_hwnd, sel_name);
+ break;
+ default:
+ break;
+ }
+ break;
+ case WM_COMMAND:
+ cur_ctrl = (HWND) l_param;
+ switch(w_param) {
+ case (EN_UPDATE << 16) | EWFD_FILTER_EDIT:
+ filter_tb_syntax_check(cur_ctrl, NULL);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* XXX - Copied verbatim from gtk/file_dlg.c. Perhaps it
+ * should be in wiretap instead?
+ */
+
+static gboolean
+can_save_with_wiretap(int ft)
+{
+ /* To save a file with Wiretap, Wiretap has to handle that format,
+ and its code to handle that format must be able to write a file
+ with this file's encapsulation type. */
+ return wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cfile.lnk_t);
+}
+
+/* Generate a list of the file types we can save this file as.
+
+ "filetype" is the type it has now.
+
+ "encap" is the encapsulation for its packets (which could be
+ "unknown" or "per-packet").
+
+ "filtered" is TRUE if we're to save only the packets that passed
+ the display filter (in which case we have to save it using Wiretap)
+ and FALSE if we're to save the entire file (in which case, if we're
+ saving it in the type it has already, we can just copy it).
+
+ The same applies for sel_curr, sel_all, sel_m_only, sel_m_range and sel_man_range
+*/
+
+static void
+build_file_format_list(HWND sf_hwnd) {
+ HWND format_cb;
+ int ft;
+ guint index;
+ guint item_to_select;
+
+ /* Default to the first supported file type, if the file's current
+ type isn't supported. */
+ item_to_select = 0;
+
+ format_cb = GetDlgItem(sf_hwnd, EWFD_FILE_TYPE_COMBO);
+ SendMessage(format_cb, CB_RESETCONTENT, 0, 0);
+
+ /* Check all file types. */
+ index = 0;
+ for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
+ if (!packet_range_process_all(&range) || ft != cfile.cd_t) {
+ /* not all unfiltered packets or a different file type. We have to use Wiretap. */
+ if (!can_save_with_wiretap(ft))
+ continue; /* We can't. */
+ }
+
+ /* OK, we can write it out in this type. */
+ SendMessage(format_cb, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) wtap_file_type_string(ft));
+ SendMessage(format_cb, CB_SETITEMDATA, (LPARAM) index, (WPARAM) ft);
+ if (ft == filetype) {
+ /* Default to the same format as the file, if it's supported. */
+ item_to_select = index;
+ }
+ index++;
+ }
+
+ SendMessage(format_cb, CB_SETCURSEL, (WPARAM) item_to_select, 0);
+}
+
+#define RANGE_TEXT_MAX 128
+static UINT CALLBACK
+save_as_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
+ HWND cur_ctrl;
+ OFNOTIFY *notify = (OFNOTIFY *) l_param;
+ int new_filetype, index;
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ g_sf_hwnd = sf_hwnd;
+
+ /* Default to saving all packets, in the file's current format. */
+ filetype = cfile.cd_t;
+
+ /* init the packet range */
+ packet_range_init(&range);
+
+ /* Fill in the file format list */
+ build_file_format_list(sf_hwnd);
+
+ range_handle_wm_initdialog(sf_hwnd, &range);
+
+ break;
+ case WM_COMMAND:
+ cur_ctrl = (HWND) l_param;
+
+ switch (w_param) {
+ case (CBN_SELCHANGE << 16) | EWFD_FILE_TYPE_COMBO:
+ index = SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0);
+ if (index != CB_ERR) {
+ new_filetype = SendMessage(cur_ctrl, CB_GETITEMDATA, (WPARAM) index, 0);
+ if (new_filetype != CB_ERR) {
+ if (filetype != new_filetype) {
+ if (can_save_with_wiretap(new_filetype)) {
+ cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN);
+ EnableWindow(cur_ctrl, TRUE);
+ cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
+ EnableWindow(cur_ctrl, TRUE);
+ } else {
+ cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN);
+ SendMessage(cur_ctrl, BM_SETCHECK, 0, 0);
+ EnableWindow(cur_ctrl, FALSE);
+ cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
+ EnableWindow(cur_ctrl, FALSE);
+ }
+ filetype = new_filetype;
+ }
+ }
+ }
+ break;
+ default:
+ range_handle_wm_command(sf_hwnd, cur_ctrl, w_param, &range);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+
+/* For each range static control, fill in its value and enable/disable it. */
+static void
+range_update_dynamics(HWND dlg_hwnd, packet_range_t *range) {
+ HWND cur_ctrl;
+ gboolean filtered_active = FALSE;
+ gchar static_val[100];
+ gint selected_num;
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_DISPLAYED_BTN);
+ if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ filtered_active = TRUE;
+
+ /* RANGE_SELECT_ALL */
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_CAP);
+ EnableWindow(cur_ctrl, !filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", cfile.count);
+ SetWindowText(cur_ctrl, static_val);
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_DISP);
+ EnableWindow(cur_ctrl, filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", range->displayed_cnt);
+ SetWindowText(cur_ctrl, static_val);
+
+ /* RANGE_SELECT_CURR */
+ selected_num = (cfile.current_frame) ? cfile.current_frame->num : 0;
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_CAP);
+ EnableWindow(cur_ctrl, selected_num && !filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", selected_num ? 1 : 0);
+ SetWindowText(cur_ctrl, static_val);
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_DISP);
+ EnableWindow(cur_ctrl, selected_num && filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", selected_num ? 1 : 0);
+ SetWindowText(cur_ctrl, static_val);
+
+ /* RANGE_SELECT_MARKED */
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_BTN);
+ EnableWindow(cur_ctrl, cfile.marked_count);
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_CAP);
+ EnableWindow(cur_ctrl, cfile.marked_count && !filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", cfile.marked_count);
+ SetWindowText(cur_ctrl, static_val);
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_DISP);
+ EnableWindow(cur_ctrl, cfile.marked_count && filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", range->displayed_marked_cnt);
+ SetWindowText(cur_ctrl, static_val);
+
+ /* RANGE_SELECT_MARKED_RANGE */
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_BTN);
+ EnableWindow(cur_ctrl, range->mark_range_cnt);
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_CAP);
+ EnableWindow(cur_ctrl, range->mark_range_cnt && !filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", range->mark_range_cnt);
+ SetWindowText(cur_ctrl, static_val);
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_DISP);
+ EnableWindow(cur_ctrl, range->displayed_mark_range_cnt && filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", range->displayed_mark_range_cnt);
+ SetWindowText(cur_ctrl, static_val);
+
+ /* RANGE_SELECT_USER */
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_CAP);
+ EnableWindow(cur_ctrl, !filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", range->user_range_cnt);
+ SetWindowText(cur_ctrl, static_val);
+
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_DISP);
+ EnableWindow(cur_ctrl, filtered_active);
+ g_snprintf(static_val, sizeof(static_val), "%u", range->displayed_user_range_cnt);
+ SetWindowText(cur_ctrl, static_val);
+}
+
+static void
+range_handle_wm_initdialog(HWND dlg_hwnd, packet_range_t *range) {
+ HWND cur_ctrl;
+
+ /* Set the appropriate captured/displayed radio */
+ if (range->process_filtered)
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_DISPLAYED_BTN);
+ else
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_CAPTURED_BTN);
+ SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0);
+
+ /* dynamic values in the range frame */
+ range_update_dynamics(dlg_hwnd, range);
+
+ /* Set the appropriate range radio */
+ switch(range->process) {
+ case(range_process_all):
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_BTN);
+ break;
+ case(range_process_selected):
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_BTN);
+ break;
+ case(range_process_marked):
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_BTN);
+ break;
+ case(range_process_marked_range):
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_BTN);
+ break;
+ case(range_process_user_range):
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_BTN);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0);
+}
+
+static void
+range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, packet_range_t *range) {
+ HWND cur_ctrl;
+ gchar range_text[RANGE_TEXT_MAX];
+
+ switch(w_param) {
+ case (BN_CLICKED << 16) | EWFD_CAPTURED_BTN:
+ case (BN_CLICKED << 16) | EWFD_DISPLAYED_BTN:
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_CAPTURED_BTN);
+ if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ range->process_filtered = FALSE;
+ else
+ range->process_filtered = TRUE;
+ range_update_dynamics(dlg_hwnd, range);
+ break;
+ case (BN_CLICKED << 16) | EWFD_ALL_PKTS_BTN:
+ if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
+ range->process = range_process_all;
+ range_update_dynamics(dlg_hwnd, range);
+ }
+ break;
+ case (BN_CLICKED << 16) | EWFD_SEL_PKT_BTN:
+ if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
+ range->process = range_process_selected;
+ range_update_dynamics(dlg_hwnd, range);
+ }
+ break;
+ case (BN_CLICKED << 16) | EWFD_MARKED_BTN:
+ if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
+ range->process = range_process_marked;
+ range_update_dynamics(dlg_hwnd, range);
+ }
+ break;
+ case (BN_CLICKED << 16) | EWFD_FIRST_LAST_BTN:
+ if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
+ range->process = range_process_marked_range;
+ range_update_dynamics(dlg_hwnd, range);
+ }
+ break;
+ case (BN_CLICKED << 16) | EWFD_RANGE_BTN:
+ if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
+ range->process = range_process_user_range;
+ range_update_dynamics(dlg_hwnd, range);
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
+ SetFocus(cur_ctrl);
+ }
+ break;
+ case (EN_SETFOCUS << 16) | EWFD_RANGE_EDIT:
+ cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_BTN);
+ SendMessage(cur_ctrl, BM_CLICK, 0, 0);
+ break;
+ case (EN_CHANGE << 16) | EWFD_RANGE_EDIT:
+ SendMessage(ctrl, WM_GETTEXT, (WPARAM) RANGE_TEXT_MAX, (LPARAM) range_text);
+ packet_range_convert_str(range, range_text);
+ range_update_dynamics(dlg_hwnd, range);
+ break;
+ }
+}
+
+static UINT CALLBACK
+merge_file_hook_proc(HWND mf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
+ HWND cur_ctrl, parent;
+ OFNOTIFY *notify = (OFNOTIFY *) l_param;
+ gchar sel_name[MAX_PATH];
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ /* XXX - Retain the filter text, and fill it in. */
+
+ /* Append by default */
+ cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_PREPEND_BTN);
+ SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0);
+ merge_action = merge_append;
+
+ preview_set_filename(mf_hwnd, NULL);
+ break;
+ case WM_NOTIFY:
+ switch (notify->hdr.code) {
+ case CDN_FILEOK:
+ /* XXX - Fetch the read filter */
+
+ cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_CHRONO_BTN);
+ if(SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
+ merge_action = merge_chrono;
+ } else {
+ cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_PREPEND_BTN);
+ if(SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
+ merge_action = merge_prepend;
+ }
+ }
+
+ break;
+ case CDN_SELCHANGE:
+ /* This _almost_ works correctly. We need to handle directory
+ selections, etc. */
+ parent = GetParent(mf_hwnd);
+ CommDlg_OpenSave_GetSpec(parent, sel_name, MAX_PATH);
+ preview_set_filename(mf_hwnd, sel_name);
+ break;
+ default:
+ break;
+ }
+ break;
+ case WM_COMMAND:
+ cur_ctrl = (HWND) l_param;
+ switch(w_param) {
+ case (EN_UPDATE << 16) | EWFD_FILTER_EDIT:
+ filter_tb_syntax_check(cur_ctrl, NULL);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+static UINT CALLBACK
+export_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
+ HWND cur_ctrl;
+ OFNOTIFY *notify = (OFNOTIFY *) l_param;
+ gboolean pkt_fmt_enable;
+ int i, index;
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ /* init the printing range */
+ packet_range_init(&print_args.range);
+ range_handle_wm_initdialog(ef_hwnd, &print_args.range);
+ format_handle_wm_initdialog(ef_hwnd, &print_args);
+
+ break;
+ case WM_COMMAND:
+ cur_ctrl = (HWND) l_param;
+ switch (w_param) {
+// case (CBN_SELCHANGE << 16) | EWFD_FILE_TYPE_COMBO:
+// break;
+ default:
+ range_handle_wm_command(ef_hwnd, cur_ctrl, w_param, &print_args.range);
+ print_update_dynamic(ef_hwnd, &print_args);
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch (notify->hdr.code) {
+ case CDN_FILEOK:
+ break;
+ case CDN_TYPECHANGE:
+ index = notify->lpOFN->nFilterIndex;
+
+ if (index == 2) /* PostScript */
+ print_args.format = PR_FMT_TEXT;
+ else
+ print_args.format = PR_FMT_PS;
+ if (index == 3 || index == 4)
+ pkt_fmt_enable = FALSE;
+ else
+ pkt_fmt_enable = TRUE;
+ for (i = EWFD_PKT_FORMAT_GB; i <= EWFD_PKT_NEW_PAGE_CB; i++) {
+ cur_ctrl = GetDlgItem(ef_hwnd, i);
+ EnableWindow(cur_ctrl, pkt_fmt_enable);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static UINT CALLBACK
+export_raw_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
+ HWND cur_ctrl;
+ OPENFILENAME *ofnp = (OPENFILENAME *) l_param;
+ gchar raw_msg[100];
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ g_snprintf(raw_msg, sizeof(raw_msg), "%d byte%s of raw binary data will be written",
+ ofnp->lCustData, plurality(ofnp->lCustData, "", "s"));
+ cur_ctrl = GetDlgItem(ef_hwnd, EWFD_EXPORTRAW_ST);
+ SetWindowText(cur_ctrl, raw_msg);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/gtk/win32-file-dlg.h b/gtk/win32-file-dlg.h
new file mode 100755
index 0000000000..d5a35ea092
--- /dev/null
+++ b/gtk/win32-file-dlg.h
@@ -0,0 +1,133 @@
+#ifndef __WIN32_FILE_DLG_H__
+#define __WIN32_FILE_DLG_H__
+
+typedef enum {
+ export_type_text = 1,
+ export_type_ps,
+ export_type_csv,
+ export_type_psml,
+ export_type_pdml
+} export_type_e;
+
+/** Open the "Open" dialog box.
+ *
+ * @param h_wnd HWND of the parent window.
+ */
+gboolean win32_open_file (HWND h_wnd);
+
+/** Open the "Save As" dialog box.
+ *
+ * @param h_wnd HWND of the parent window.
+ * @param action_after_save The action to take, when save completed
+ * @param action_after_save_data Data for action_after_save
+ */
+void win32_save_as_file(HWND h_wnd, action_after_save_e action_after_save, gpointer action_after_save_data);
+
+/** Open the "Merge" dialog box.
+ *
+ * @param h_wnd HWND of the parent window.
+ */
+void win32_merge_file (HWND h_wnd);
+
+/** Open the "Export" dialog box.
+ *
+ * @param h_wnd HWND of the parent window.
+ */
+void win32_export_file (HWND h_wnd, export_type_e export_type);
+
+/** Open the "Export raw bytes" dialog box.
+ *
+ * @param h_wnd HWND of the parent window.
+ */
+void win32_export_raw_file (HWND h_wnd);
+
+/** Open the "Export Color Filters" dialog box
+ *
+ * @param h_wnd HWND of the parent window
+ */
+void win32_export_color_file(HWND h_wnd);
+
+/** Open the "Import Color Filters" dialog box
+ *
+ * @param h_wnd HWND of the parent window
+ */
+void win32_import_color_file(HWND h_wnd);
+
+/** Given a print_args_t struct, update a set of print/export format controls
+ * accordingly.
+ *
+ * @param dlg_hwnd HWND of the dialog in question.
+ * @args Pointer to a print args struct.
+ */
+/* XXX - This should be moved to win32-print.c, maybe? */
+void print_update_dynamic(HWND dlg_hwnd, print_args_t *args);
+
+void file_set_save_marked_sensitive();
+
+/* Open dialog defines */
+#define EWFD_FILTER_BTN 1000
+#define EWFD_FILTER_EDIT 1001
+
+#define EWFD_MAC_NR_CB 1002
+#define EWFD_NET_NR_CB 1003
+#define EWFD_TRANS_NR_CB 1004
+
+/* Note: The preview title (PT) and text (PTX) MUST have sequential IDs;
+ they're used in a for loop. EWFD_PT_FILENAME MUST be first, and
+ EWFD_PTX_ELAPSED MUST be last. (so why don't we just use an enum? */
+#define EWFD_PT_FILENAME 1005
+#define EWFD_PT_FORMAT 1006
+#define EWFD_PT_SIZE 1007
+#define EWFD_PT_PACKETS 1008
+#define EWFD_PT_FIRST_PKT 1009
+#define EWFD_PT_ELAPSED 1010
+
+#define EWFD_PTX_FILENAME 1011
+#define EWFD_PTX_FORMAT 1012
+#define EWFD_PTX_SIZE 1013
+#define EWFD_PTX_PACKETS 1014
+#define EWFD_PTX_FIRST_PKT 1015
+#define EWFD_PTX_ELAPSED 1016
+
+
+/* Save dialog defines */
+#define EWFD_CAPTURED_BTN 1000
+#define EWFD_DISPLAYED_BTN 1001
+#define EWFD_ALL_PKTS_BTN 1002
+#define EWFD_SEL_PKT_BTN 1003
+#define EWFD_MARKED_BTN 1004
+#define EWFD_FIRST_LAST_BTN 1005
+#define EWFD_RANGE_BTN 1006
+#define EWFD_RANGE_EDIT 1007
+#define EWFD_FILE_TYPE_COMBO 1008
+
+#define EWFD_ALL_PKTS_CAP 1009
+#define EWFD_SEL_PKT_CAP 1010
+#define EWFD_MARKED_CAP 1011
+#define EWFD_FIRST_LAST_CAP 1012
+#define EWFD_RANGE_CAP 1013
+
+#define EWFD_ALL_PKTS_DISP 1014
+#define EWFD_SEL_PKT_DISP 1015
+#define EWFD_MARKED_DISP 1016
+#define EWFD_FIRST_LAST_DISP 1017
+#define EWFD_RANGE_DISP 1018
+
+/* Export raw dialog defines. */
+#define EWFD_EXPORTRAW_ST 1000
+
+/* Merge dialog defines. Overlays Open dialog defines above. */
+#define EWFD_MERGE_PREPEND_BTN 1050
+#define EWFD_MERGE_CHRONO_BTN 1051
+#define EWFD_MERGE_APPEND_BTN 1052
+
+/* Export dialog defines. Overlays Save dialog defines above. */
+/* These MUST be contiguous */
+#define EWFD_PKT_FORMAT_GB 1050
+#define EWFD_PKT_SUMMARY_CB 1051
+#define EWFD_PKT_DETAIL_CB 1052
+#define EWFD_PKT_DETAIL_COMBO 1053
+#define EWFD_PKT_BYTES_CB 1054
+#define EWFD_PKT_NEW_PAGE_CB 1055
+
+#endif /* win32-file-dlg.h */
diff --git a/image/ethereal.rc.in b/image/ethereal.rc.in
index 3542775fb5..65b0cc616f 100644
--- a/image/ethereal.rc.in
+++ b/image/ethereal.rc.in
@@ -1,5 +1,7 @@
#include "winver.h"
+#include "image/win32-file-dlg.rc"
+
ETHEREAL_ICON ICON "ethereal.ico"
VS_VERSION_INFO VERSIONINFO
diff --git a/image/win32-file-dlg.rc b/image/win32-file-dlg.rc
new file mode 100755
index 0000000000..02babb0152
--- /dev/null
+++ b/image/win32-file-dlg.rc
@@ -0,0 +1,135 @@
+#include <windows.h>
+#include "richedit.h"
+#include "gtk/win32-file-dlg.h"
+
+ETHEREAL_OPENFILENAME_TEMPLATE DIALOG 0, 0, 368, 94
+STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL
+FONT 8, "MS Shell Dlg"
+{
+ // Filter button/entry
+ PUSHBUTTON "Filter:", EWFD_FILTER_BTN, 7, 4, 35, 14
+ CONTROL "", EWFD_FILTER_EDIT, RICHEDIT_CLASS, ES_AUTOHSCROLL, 49, 5, 101, 12, WS_EX_CLIENTEDGE
+
+ CHECKBOX "MAC name resolution", EWFD_MAC_NR_CB, 7, 32, 100, 8, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Network name resolution", EWFD_NET_NR_CB, 7, 47, 100, 8, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Transport name resolution", EWFD_TRANS_NR_CB, 7, 62, 100, 8, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+
+ LTEXT "Filename:", EWFD_PT_FILENAME, 164, 4, 40, 8
+ LTEXT "-", EWFD_PTX_FILENAME, 211, 4, 150, 8
+ LTEXT "Format:", EWFD_PT_FORMAT, 164, 19, 40, 8
+ LTEXT "-", EWFD_PTX_FORMAT, 211, 19, 150, 8
+ LTEXT "Size:", EWFD_PT_SIZE, 164, 34, 40, 8
+ LTEXT "-", EWFD_PTX_SIZE, 211, 34, 150, 8, SS_RIGHT
+ LTEXT "Packets:", EWFD_PT_PACKETS, 164, 49, 40, 8
+ LTEXT "-", EWFD_PTX_PACKETS, 211, 49, 150, 8, SS_RIGHT
+ LTEXT "First Packet:", EWFD_PT_FIRST_PKT, 164, 64, 40, 8
+ LTEXT "-", EWFD_PTX_FIRST_PKT, 211, 64, 150, 8, SS_RIGHT
+ LTEXT "Elapsed Time:", EWFD_PT_ELAPSED, 164, 79, 40, 8
+ LTEXT "-", EWFD_PTX_ELAPSED, 211, 79, 150, 8
+}
+
+ETHEREAL_SAVEFILENAME_TEMPLATE DIALOG 0, 0, 368, 116
+STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL
+FONT 8, "MS Shell Dlg"
+{
+ // XXX - We need to come up with something less confusing than separate
+ // "Save as type" (which is built-in) and "File format" combos.
+ LTEXT "File format:", -1, 5, 3, 35, 8
+ COMBOBOX EWFD_FILE_TYPE_COMBO, 54, 2, 155, 51, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+ GROUPBOX "Packet Range", -1, 5, 21, 210, 90
+
+ CONTROL "Captured", EWFD_CAPTURED_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 110, 32, 45, 10
+ CONTROL "Displayed", EWFD_DISPLAYED_BTN, "Button", BS_AUTORADIOBUTTON, 160, 32, 47, 10
+
+ CONTROL "All packets", EWFD_ALL_PKTS_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 16, 44, 51, 10
+ CONTROL "Selected packet", EWFD_SEL_PKT_BTN, "Button", BS_AUTORADIOBUTTON, 16, 56, 68, 10
+ CONTROL "Marked packets", EWFD_MARKED_BTN, "Button", BS_AUTORADIOBUTTON, 16, 68, 67, 10
+ CONTROL "First to last marked", EWFD_FIRST_LAST_BTN, "Button", BS_AUTORADIOBUTTON, 16, 80, 75, 10
+ CONTROL "Range:", EWFD_RANGE_BTN, "Button", BS_AUTORADIOBUTTON, 16, 92, 35, 10
+ EDITTEXT EWFD_RANGE_EDIT, 53, 91, 30, 12, ES_AUTOHSCROLL
+
+ LTEXT "0", EWFD_ALL_PKTS_CAP, 110, 45, 39, 8, SS_RIGHT
+ LTEXT "0", EWFD_SEL_PKT_CAP, 110, 57, 39, 8, SS_RIGHT
+ LTEXT "0", EWFD_MARKED_CAP, 110, 69, 39, 8, SS_RIGHT
+ LTEXT "0", EWFD_FIRST_LAST_CAP, 110, 81, 39, 8, SS_RIGHT
+ LTEXT "0", EWFD_RANGE_CAP, 110, 93, 39, 8, SS_RIGHT
+
+ LTEXT "0", EWFD_ALL_PKTS_DISP, 160, 45, 41, 8, SS_RIGHT
+ LTEXT "0", EWFD_SEL_PKT_DISP, 160, 57, 41, 8, SS_RIGHT
+ LTEXT "0", EWFD_MARKED_DISP, 160, 69, 41, 8, SS_RIGHT
+ LTEXT "0", EWFD_FIRST_LAST_DISP, 160, 81, 41, 8, SS_RIGHT
+ LTEXT "0", EWFD_RANGE_DISP, 160, 93, 41, 8, SS_RIGHT
+}
+
+ETHEREAL_MERGEFILENAME_TEMPLATE DIALOG 0, 0, 368, 94
+STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL
+FONT 8, "MS Shell Dlg"
+{
+ // Filter button/entry
+ PUSHBUTTON "Filter:", EWFD_FILTER_BTN, 7, 4, 35, 14
+ CONTROL "", EWFD_FILTER_EDIT, RICHEDIT_CLASS, ES_AUTOHSCROLL, 49, 5, 101, 12, WS_EX_CLIENTEDGE
+
+ CONTROL "Prepend packets to existing file", EWFD_MERGE_PREPEND_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 7, 32, 120, 8
+ CONTROL "Merge packets chronologically", EWFD_MERGE_CHRONO_BTN, "Button", BS_AUTORADIOBUTTON, 7, 47, 120, 8
+ CONTROL "Append packets to existing file", EWFD_MERGE_APPEND_BTN, "Button", BS_AUTORADIOBUTTON, 7, 62, 120, 8
+
+ LTEXT "Filename:", EWFD_PT_FILENAME, 164, 4, 40, 8
+ LTEXT "-", EWFD_PTX_FILENAME, 211, 4, 150, 8
+ LTEXT "Format:", EWFD_PT_FORMAT, 164, 19, 40, 8
+ LTEXT "-", EWFD_PTX_FORMAT, 211, 19, 150, 8
+ LTEXT "Size:", EWFD_PT_SIZE, 164, 34, 40, 8
+ LTEXT "-", EWFD_PTX_SIZE, 211, 34, 150, 8, SS_RIGHT
+ LTEXT "Packets:", EWFD_PT_PACKETS, 164, 49, 40, 8
+ LTEXT "-", EWFD_PTX_PACKETS, 211, 49, 150, 8, SS_RIGHT
+ LTEXT "First Packet:", EWFD_PT_FIRST_PKT, 164, 64, 40, 8
+ LTEXT "-", EWFD_PTX_FIRST_PKT, 211, 64, 150, 8, SS_RIGHT
+ LTEXT "Elapsed Time:", EWFD_PT_ELAPSED, 164, 79, 40, 8
+ LTEXT "-", EWFD_PTX_ELAPSED, 211, 79, 150, 8
+}
+
+// XXX - The width value appears to have no effect, at least on Windows XP.
+ETHEREAL_EXPORTFILENAME_TEMPLATE DIALOG 0, 0, 5000, 97
+STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL
+FONT 8, "MS Shell Dlg"
+{
+ GROUPBOX "Packet Range", -1, 5, 2, 210, 90
+
+ CONTROL "Captured", EWFD_CAPTURED_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 110, 13, 45, 10
+ CONTROL "Displayed", EWFD_DISPLAYED_BTN, "Button", BS_AUTORADIOBUTTON, 160, 13, 47, 10
+
+ CONTROL "All packets", EWFD_ALL_PKTS_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 16, 25, 51, 10
+ CONTROL "Selected packet", EWFD_SEL_PKT_BTN, "Button", BS_AUTORADIOBUTTON, 16, 37, 68, 10
+ CONTROL "Marked packets", EWFD_MARKED_BTN, "Button", BS_AUTORADIOBUTTON, 16, 49, 67, 10
+ CONTROL "First to last marked", EWFD_FIRST_LAST_BTN, "Button", BS_AUTORADIOBUTTON, 16, 61, 75, 10
+ CONTROL "Range:", EWFD_RANGE_BTN, "Button", BS_AUTORADIOBUTTON, 16, 73, 35, 10
+ EDITTEXT EWFD_RANGE_EDIT, 53, 72, 30, 12, ES_AUTOHSCROLL
+
+ LTEXT "0", EWFD_ALL_PKTS_CAP, 110, 26, 39, 8, SS_RIGHT
+ LTEXT "0", EWFD_SEL_PKT_CAP, 110, 38, 39, 8, SS_RIGHT
+ LTEXT "0", EWFD_MARKED_CAP, 110, 50, 39, 8, SS_RIGHT
+ LTEXT "0", EWFD_FIRST_LAST_CAP, 110, 62, 39, 8, SS_RIGHT
+ LTEXT "0", EWFD_RANGE_CAP, 110, 74, 39, 8, SS_RIGHT
+
+ LTEXT "0", EWFD_ALL_PKTS_DISP, 160, 26, 41, 8, SS_RIGHT
+ LTEXT "0", EWFD_SEL_PKT_DISP, 160, 38, 41, 8, SS_RIGHT
+ LTEXT "0", EWFD_MARKED_DISP, 160, 50, 41, 8, SS_RIGHT
+ LTEXT "0", EWFD_FIRST_LAST_DISP, 160, 62, 41, 8, SS_RIGHT
+ LTEXT "0", EWFD_RANGE_DISP, 160, 74, 41, 8, SS_RIGHT
+
+ GROUPBOX "Packet Format", EWFD_PKT_FORMAT_GB, 224, 2, 119, 90
+ CONTROL "Packet summary line", EWFD_PKT_SUMMARY_CB, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 235, 15, 84, 10
+ CONTROL "Packet details:", EWFD_PKT_DETAIL_CB, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 235, 27, 95, 10
+ COMBOBOX EWFD_PKT_DETAIL_COMBO, 247, 39, 74, 45, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Packet Bytes", EWFD_PKT_BYTES_CB, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 235, 56, 80, 10
+ CONTROL "Each packet on a new page", EWFD_PKT_NEW_PAGE_CB, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 235, 70, 106, 10
+
+}
+
+
+ETHEREAL_EXPORTRAWFILENAME_TEMPLATE DIALOG 0, 0, 200, 18
+STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "-", EWFD_EXPORTRAW_ST, 5, 5, 180, 8
+}