summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ui/Makefile.common1
-rw-r--r--ui/file_dialog.h43
-rw-r--r--ui/gtk/capture_file_dlg.c372
-rw-r--r--ui/win32/file_dlg_win32.c319
-rw-r--r--ui/win32/file_dlg_win32.h16
5 files changed, 346 insertions, 405 deletions
diff --git a/ui/Makefile.common b/ui/Makefile.common
index 9b373a851d..5e5d990e14 100644
--- a/ui/Makefile.common
+++ b/ui/Makefile.common
@@ -54,6 +54,7 @@ noinst_HEADERS = \
alert_box.h \
capture_globals.h \
last_open_dir.h \
+ file_dialog.h \
help_url.h \
iface_lists.h \
main_statusbar.h \
diff --git a/ui/file_dialog.h b/ui/file_dialog.h
new file mode 100644
index 0000000000..1858f43ccc
--- /dev/null
+++ b/ui/file_dialog.h
@@ -0,0 +1,43 @@
+/* file_dialog.h
+ * Common file dialog definitions
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __FILE_DIALOG_H__
+#define __FILE_DIALOG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef enum {
+ SAVE,
+ SAVE_WITHOUT_COMMENTS,
+ SAVE_IN_ANOTHER_FORMAT,
+ CANCELLED
+} check_savability_t;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __FILE_DIALOG_H__ */
diff --git a/ui/gtk/capture_file_dlg.c b/ui/gtk/capture_file_dlg.c
index 6a96efbd2f..51f29e9635 100644
--- a/ui/gtk/capture_file_dlg.c
+++ b/ui/gtk/capture_file_dlg.c
@@ -45,6 +45,7 @@
#include <wsutil/file_util.h>
#include "ui/alert_box.h"
+#include "ui/file_dialog.h"
#include "ui/recent.h"
#include "ui/simple_dialog.h"
#include "ui/ui_util.h"
@@ -78,11 +79,8 @@
#endif
static void do_file_save(capture_file *cf, gboolean dont_reopen);
-static void do_file_save_as(capture_file *cf, gboolean must_support_comments,
+static void file_save_as_cmd(capture_file *cf, gboolean must_support_comments,
gboolean dont_reopen);
-static cf_write_status_t file_save_as_cb(GtkWidget *fs,
- gboolean discard_comments,
- gboolean dont_reopen);
static void file_select_file_type_cb(GtkWidget *w, gpointer data);
static cf_write_status_t file_export_specified_packets_cb(GtkWidget *fs, packet_range_t *range);
static int set_file_type_list(GtkWidget *combo_box, capture_file *cf,
@@ -542,6 +540,7 @@ gtk_open_file(GtkWidget *w, GString *file_name, GString *display_filter)
g_object_get_data(G_OBJECT(w), E_DFILTER_TE_KEY));
cf_name = file_selection_run(file_open_w);
+
if (cf_name == NULL) {
/* User cancelled or closed the dialog. */
return FALSE;
@@ -604,7 +603,7 @@ file_open_cmd(capture_file *cf, GtkWidget *w _U_)
#ifdef USE_WIN32_FILE_DIALOGS
if (win32_open_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level)), file_name, display_filter)) {
#else /* USE_WIN32_FILE_DIALOGS */
- if (gtk_open_file(w, file_name, display_filter)) {
+ if (gtk_open_file(top_level, file_name, display_filter)) {
#endif /* USE_WIN32_FILE_DIALOGS */
/* Only close the old file now that we know we want to open another one. */
@@ -854,7 +853,7 @@ file_merge_cmd(GtkWidget *w _U_)
#ifdef USE_WIN32_FILE_DIALOGS
if (win32_merge_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level)), file_name, display_filter, &merge_type)) {
#else /* USE_WIN32_FILE_DIALOGS */
- if (gtk_merge_file(w, file_name, display_filter, &merge_type)) {
+ if (gtk_merge_file(top_level, file_name, display_filter, &merge_type)) {
#endif /* USE_WIN32_FILE_DIALOGS */
/* Get the specified read filter and try to compile it. */
@@ -1211,13 +1210,6 @@ file_close_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) {
do_file_close(&cfile, FALSE, "");
}
-typedef enum {
- SAVE,
- SAVE_WITHOUT_COMMENTS,
- SAVE_IN_ANOTHER_FORMAT,
- CANCELLED
-} check_savability_t;
-
#define RESPONSE_DISCARD_COMMENTS_AND_SAVE 1
#define RESPONSE_SAVE_IN_ANOTHER_FORMAT 2
@@ -1352,7 +1344,7 @@ do_file_save(capture_file *cf, gboolean dont_reopen)
probably pcap-ng, which supports comments and, if it's
not pcap-ng, let the user decide what they want to do
if they've added comments. */
- do_file_save_as(cf, FALSE, dont_reopen);
+ file_save_as_cmd(cf, FALSE, dont_reopen);
} else {
if (cf->unsaved_changes) {
/* This is not a temporary capture file, but it has unsaved
@@ -1385,7 +1377,7 @@ do_file_save(capture_file *cf, gboolean dont_reopen)
support comments, and the user said not to delete the
comments. Do a "Save As" so the user can select
one of those formats and choose a file name. */
- do_file_save_as(cf, TRUE, dont_reopen);
+ file_save_as_cmd(cf, TRUE, dont_reopen);
return;
case CANCELLED:
@@ -1505,15 +1497,10 @@ file_select_file_type_cb(GtkWidget *w, gpointer parent_arg)
}
static check_savability_t
-check_save_as_with_comments(capture_file *cf, GtkWidget *file_chooser_w,
- GtkWidget *ft_combo_box)
+gtk_check_save_as_with_comments(GtkWidget *w, capture_file *cf, int file_type)
{
- gpointer ptr;
- int selected_file_type;
GtkWidget *msg_dialog;
gint response;
- GtkWidget *compressed_cb;
- gboolean compressed;
/* Do we have any comments? */
if (!cf_has_comments(cf)) {
@@ -1521,19 +1508,12 @@ check_save_as_with_comments(capture_file *cf, GtkWidget *file_chooser_w,
return SAVE;
}
- /* OK, we have comments. Can we write them out in the selected
- format? */
- if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(ft_combo_box), &ptr)) {
- g_assert_not_reached(); /* Programming error: somehow nothing is active */
- }
- selected_file_type = GPOINTER_TO_INT(ptr);
-
/* XXX - for now, we "know" that pcap-ng is the only format for which
we support comments. We should really ask Wiretap what the
format in question supports (and handle different types of
comments, some but not all of which some file formats might
not support). */
- if (selected_file_type == WTAP_FILE_PCAPNG) {
+ if (file_type == WTAP_FILE_PCAPNG) {
/* Yes - they selected pcap-ng. Let the save happen; we can
save the comments, so no need to delete them. */
return SAVE;
@@ -1544,7 +1524,7 @@ check_save_as_with_comments(capture_file *cf, GtkWidget *file_chooser_w,
supports comments", "Discard comments and save in the
format you selected", or "Cancel", meaning "don't bother
saving the file at all". */
- msg_dialog = gtk_message_dialog_new(GTK_WINDOW(file_chooser_w),
+ msg_dialog = gtk_message_dialog_new(GTK_WINDOW(w),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
@@ -1576,7 +1556,7 @@ check_save_as_with_comments(capture_file *cf, GtkWidget *file_chooser_w,
} else {
/* No. Offer the user a choice of "Discard comments and
save in the format you selected" or "Cancel". */
- msg_dialog = gtk_message_dialog_new(GTK_WINDOW(file_chooser_w),
+ msg_dialog = gtk_message_dialog_new(GTK_WINDOW(w),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
@@ -1619,16 +1599,7 @@ check_save_as_with_comments(capture_file *cf, GtkWidget *file_chooser_w,
XXX - we know pcap-ng can be compressed; if we ever end up
supporting saving comments in a format that *can't* be
compressed, such as NetMon format, we must check this. */
- compressed_cb = (GtkWidget *)g_object_get_data(G_OBJECT(file_chooser_w),
- E_COMPRESSED_CB_KEY);
- compressed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compressed_cb));
- ws_combo_box_clear_text_and_pointer(GTK_COMBO_BOX(ft_combo_box));
- ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(ft_combo_box),
- wtap_file_type_string(WTAP_FILE_PCAPNG),
- GINT_TO_POINTER(WTAP_FILE_PCAPNG));
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compressed_cb), compressed);
-
- ws_combo_box_set_active(GTK_COMBO_BOX(ft_combo_box), 0); /* No callback */
+ /* XXX - need a compressed checkbox here! */
return SAVE_IN_ANOTHER_FORMAT;
case RESPONSE_DISCARD_COMMENTS_AND_SAVE:
@@ -1645,23 +1616,20 @@ check_save_as_with_comments(capture_file *cf, GtkWidget *file_chooser_w,
}
}
-static void
-do_file_save_as(capture_file *cf, gboolean must_support_comments,
- gboolean dont_reopen)
+#ifndef USE_WIN32_FILE_DIALOGS
+/* "Save as" */
+static gboolean
+gtk_save_as_file(GtkWidget *w _U_, capture_file *cf, GString *file_name, int *file_type,
+ gboolean *compressed, gboolean must_support_comments)
{
-#ifdef USE_WIN32_FILE_DIALOGS
- if (win32_save_as_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level)),
- cf, must_support_comments, dont_reopen)) {
- /* They discarded comments, so redraw the packet details window
- to reflect any packets that no longer have comments. */
- packet_list_queue_draw();
- }
-#else /* USE_WIN32_FILE_DIALOGS */
GtkWidget *file_save_as_w;
GtkWidget *main_vb, *ft_hb, *ft_lb, *ft_combo_box, *compressed_cb;
int default_ft;
char *cf_name;
- gboolean discard_comments;
+ gpointer ptr;
+
+ if (!file_name || !file_type || !compressed)
+ return FALSE;
/* Default to saving in the file's current format. */
@@ -1708,151 +1676,203 @@ do_file_save_as(capture_file *cf, gboolean must_support_comments,
g_signal_connect(ft_combo_box, "changed", G_CALLBACK(file_select_file_type_cb), file_save_as_w);
ws_combo_box_set_active(GTK_COMBO_BOX(ft_combo_box), 0);
- /*
+ cf_name = file_selection_run(file_save_as_w);
+
+ if (cf_name == NULL) {
+ /* User cancelled or closed the dialog. */
+ return FALSE;
+ }
+
+ if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(ft_combo_box), &ptr)) {
+ g_assert_not_reached(); /* Programming error: somehow nothing is active */
+ }
+ *file_type = GPOINTER_TO_INT(ptr);
+ *compressed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compressed_cb));
+
+ /* We've crossed the Rubicon; get rid of the file selection box. */
+ window_destroy(GTK_WIDGET(file_save_as_w));
+
+ g_string_printf(file_name, "%s", cf_name);
+ g_free(cf_name);
+ return TRUE;
+}
+#endif /* USE_WIN32_FILE_DIALOGS */
+
+/* Save a file with a user-specified name */
+
+/*
+ * <platform/>_save_as_file routines should upon entry...
+ * Set the path and fill in the filename if the path+filename is provided.
+ * ...and upon exit...
+ * Return TRUE on "OK" and "FALSE" on "Cancel".
+ * Close the window.
+ */
+
+static void
+file_save_as_cmd(capture_file *cf, gboolean must_support_comments,
+ gboolean dont_reopen)
+{
+ GString *file_name = g_string_new("");
+ int file_type;
+ gboolean compressed;
+ cf_write_status_t status;
+ gchar *file_name_lower;
+ GString *file_suffix;
+ GSList *extensions_list, *extension;
+ gboolean add_extension;
+ gchar *dirname;
+ gboolean discard_comments = FALSE;
+
+ /*
* Loop until the user either selects a file or gives up.
*/
for (;;) {
- cf_name = file_selection_run(file_save_as_w);
- if (cf_name == NULL) {
- /* User cancelled or closed the dialog. */
- return;
- }
+#ifdef USE_WIN32_FILE_DIALOGS
+ //if (win32_save_as_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level)), cf,
+ // file_name, &file_type, &compressed, must_support_comments)) {
+ /* They discarded comments, so redraw the packet details window
+ to reflect any packets that no longer have comments. */
+ packet_list_queue_draw();
+#else /* USE_WIN32_FILE_DIALOGS */
+ if (gtk_save_as_file(top_level, cf, file_name, &file_type, &compressed, must_support_comments)) {
+#endif /* USE_WIN32_FILE_DIALOGS */
- /* If the file has comments, does the format the user selected
- support them? If not, ask the user whether they want to
- discard the comments or choose a different format. */
- switch (check_save_as_with_comments(cf, file_save_as_w, ft_combo_box)) {
+ /* If the file has comments, does the format the user selected
+ support them? If not, ask the user whether they want to
+ discard the comments or choose a different format. */
+#ifdef USE_WIN32_FILE_DIALOGS
+ //switch (win32_check_save_as_with_comments(GDK_WINDOW_HWND(gtk_widget_get_window(top_level)), cf, file_type) {
+#else /* USE_WIN32_FILE_DIALOGS */
+ switch (gtk_check_save_as_with_comments(top_level, cf, file_type)) {
+#endif /* USE_WIN32_FILE_DIALOGS */
- case SAVE:
- /* The file can be saved in the specified format as is;
- just drive on and save in the format they selected. */
- discard_comments = FALSE;
- break;
+ case SAVE:
+ /* The file can be saved in the specified format as is;
+ just drive on and save in the format they selected. */
+ discard_comments = FALSE;
+ break;
- case SAVE_WITHOUT_COMMENTS:
- /* The file can't be saved in the specified format as is,
- but it can be saved without the comments, and the user
- said "OK, discard the comments", so save it in the
- format they specified without the comments. */
- discard_comments = TRUE;
- break;
+ case SAVE_WITHOUT_COMMENTS:
+ /* The file can't be saved in the specified format as is,
+ but it can be saved without the comments, and the user
+ said "OK, discard the comments", so save it in the
+ format they specified without the comments. */
+ discard_comments = TRUE;
+ break;
- case SAVE_IN_ANOTHER_FORMAT:
- /* There are file formats in which we can save this that
- support comments, and the user said not to delete the
- comments. The combo box of file formats has had the
- formats that don't support comments trimmed from it,
- so run the dialog again, to let the user decide
- whether to save in one of those formats or give up. */
- g_free(cf_name);
- continue;
+ case SAVE_IN_ANOTHER_FORMAT:
+ /* There are file formats in which we can save this that
+ support comments, and the user said not to delete the
+ comments. The combo box of file formats has had the
+ formats that don't support comments trimmed from it,
+ so run the dialog again, to let the user decide
+ whether to save in one of those formats or give up. */
+ discard_comments = FALSE;
+ must_support_comments = TRUE;
+ continue;
- case CANCELLED:
- /* The user said "forget it". Just get rid of the dialog box
- and return. */
- window_destroy(file_save_as_w);
- return;
- }
+ case CANCELLED:
+ /* The user said "forget it". Just get rid of the dialog box
+ and return. */
+ g_string_free(file_name, TRUE);
+ return;
+ }
+
+ /*
+ * Append the default file extension if there's none given by
+ * the user or if they gave one that's not one of the valid
+ * extensions for the file type.
+ */
+ file_name_lower = g_utf8_strdown(file_name->str, -1);
+ file_suffix = g_string_new("");
+ extensions_list = wtap_get_file_extensions_list(file_type, FALSE);
+ if (extensions_list != NULL) {
+ /* We have one or more extensions for this file type.
+ Start out assuming we need to add the default one. */
+ add_extension = TRUE;
+
+ /* OK, see if the file has one of those extensions. */
+ for (extension = extensions_list; extension != NULL;
+ extension = g_slist_next(extension)) {
+ g_string_printf(file_suffix, ".%s", (char *)extension->data);
+ if (g_str_has_suffix(file_name_lower, file_suffix->str)) {
+ /*
+ * The file name has one of the extensions for
+ * this file type.
+ */
+ add_extension = FALSE;
+ break;
+ }
+ g_string_append(file_suffix, ".gz");
+ if (g_str_has_suffix(file_name_lower, file_suffix->str)) {
+ /*
+ * The file name has one of the extensions for
+ * this file type.
+ */
+ add_extension = FALSE;
+ break;
+ }
+ }
+ } else {
+ /* We have no extensions for this file type. Don't add one. */
+ add_extension = FALSE;
+ }
+ g_free(file_name_lower);
+ g_string_free(file_suffix, TRUE);
+ if (add_extension) {
+ if (wtap_default_file_extension(file_type) != NULL) {
+ g_string_append_printf(file_name, ".%s",
+ wtap_default_file_extension(file_type));
+ if (compressed) {
+ g_string_append(file_name, ".gz");
+ }
+ }
+ }
#ifndef _WIN32
- /* If the file exists and it's user-immutable or not writable,
- ask the user whether they want to override that. */
- if (!file_target_unwritable_ui(file_save_as_w, cf_name)) {
- /* They don't. Let them try another file name or cancel. */
- g_free(cf_name);
- continue;
- }
+ /* If the file exists and it's user-immutable or not writable,
+ ask the user whether they want to override that. */
+ if (!file_target_unwritable_ui(top_level, file_name->str)) {
+ /* They don't. Let them try another file name or cancel. */
+ continue;
+ }
#endif
- /* Attempt to save the file */
- g_free(cf_name);
- switch (file_save_as_cb(file_save_as_w, discard_comments, dont_reopen)) {
+ /* Attempt to save the file */
+ status = cf_save_packets(&cfile, file_name->str, file_type, compressed,
+ discard_comments, dont_reopen);
+ switch (status) {
- case CF_WRITE_OK:
- /* The save succeeded; we're done.
- If we discarded comments, redraw the packet list to reflect
- any packets that no longer have comments. */
- if (discard_comments)
- packet_list_queue_draw();
- return;
+ case CF_WRITE_OK:
+ /* The save succeeded; we're done. */
+ /* Save the directory name for future file dialogs. */
+ dirname = get_dirname(file_name->str); /* Overwrites cf_name */
+ set_last_open_dir(dirname);
+ /* If we discarded comments, redraw the packet list to reflect
+ any packets that no longer have comments. */
+ if (discard_comments)
+ packet_list_queue_draw();
+ break;
- case CF_WRITE_ERROR:
- /* The save failed; let the user try again. */
- continue;
+ case CF_WRITE_ERROR:
+ /* The save failed; let the user try again. */
+ continue;
- case CF_WRITE_ABORTED:
- /* The user aborted the save; just return. */
- return;
+ case CF_WRITE_ABORTED:
+ /* The user aborted the save; just return. */
+ g_string_free(file_name, TRUE);
+ return;
+ }
}
+ g_string_free(file_name, TRUE);
+ return;
}
-#endif /* USE_WIN32_FILE_DIALOGS */
}
void
file_save_as_cmd_cb(GtkWidget *w _U_, gpointer data _U_)
{
- do_file_save_as(&cfile, FALSE, FALSE);
-}
-
-/* all tests ok, we only have to save the file */
-/* (and probably continue with a pending operation) */
-static cf_write_status_t
-file_save_as_cb(GtkWidget *fs, gboolean discard_comments,
- gboolean dont_reopen)
-{
- GtkWidget *ft_combo_box;
- GtkWidget *compressed_cb;
- gchar *cf_name;
- gchar *dirname;
- gpointer ptr;
- int file_type;
- gboolean compressed;
- cf_write_status_t status;
-
- /* Hide the file chooser while doing the save. */
- gtk_widget_hide(fs);
-
- cf_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs));
-
- compressed_cb = (GtkWidget *)g_object_get_data(G_OBJECT(fs), E_COMPRESSED_CB_KEY);
- ft_combo_box = (GtkWidget *)g_object_get_data(G_OBJECT(fs), E_FILE_TYPE_COMBO_BOX_KEY);
-
- if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(ft_combo_box), &ptr)) {
- g_assert_not_reached(); /* Programming error: somehow nothing is active */
- }
- file_type = GPOINTER_TO_INT(ptr);
- compressed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compressed_cb));
-
- /* Write out all the packets to the file with the specified name. */
- status = cf_save_packets(&cfile, cf_name, file_type, compressed,
- discard_comments, dont_reopen);
- switch (status) {
-
- case CF_WRITE_OK:
- /* The write succeeded; get rid of the file selection box. */
- /* cf_save_packets() might already closed our dialog! */
- window_destroy(fs);
-
- /* Save the directory name for future file dialogs. */
- dirname = get_dirname(cf_name); /* Overwrites cf_name */
- set_last_open_dir(dirname);
- break;
-
- case CF_WRITE_ERROR:
- /* The write failed.
- just leave the file selection box around so that the user can,
- after they dismiss the alert box popped up for the error, try
- again. */
- break;
-
- case CF_WRITE_ABORTED:
- /* The write was aborted; just get rid of the file selection
- box and return. */
- window_destroy(fs);
- break;
- }
- g_free(cf_name);
- return status;
+ file_save_as_cmd(&cfile, FALSE, FALSE);
}
void
diff --git a/ui/win32/file_dlg_win32.c b/ui/win32/file_dlg_win32.c
index d4c686dcef..ecdf1095bd 100644
--- a/ui/win32/file_dlg_win32.c
+++ b/ui/win32/file_dlg_win32.c
@@ -56,6 +56,7 @@
#include "../color_filters.h"
#include "../merge.h"
+#include "ui/file_dialog.h"
#include "ui/last_open_dir.h"
#include "ui/gtk/main.h"
@@ -136,8 +137,8 @@ static TCHAR *build_file_open_type_list(void);
static TCHAR *build_file_save_type_list(GArray *savable_file_types,
gboolean must_support_comments);
-static int filetype;
-static gboolean use_compression;
+static int g_filetype;
+static gboolean g_compressed;
static packet_range_t g_range;
static merge_action_e g_merge_action;
static print_args_t print_args;
@@ -164,7 +165,7 @@ static char *g_dfilter_str = NULL;
gboolean
win32_open_file (HWND h_wnd, GString *file_name, GString *display_filter) {
OPENFILENAME *ofn;
- TCHAR file_name_w[MAX_PATH] = _T("");
+ TCHAR file_name16[MAX_PATH] = _T("");
int ofnsize;
gboolean gofn_ok;
#if (_MSC_VER >= 1500)
@@ -175,7 +176,7 @@ win32_open_file (HWND h_wnd, GString *file_name, GString *display_filter) {
return FALSE;
if (file_name->len > 0) {
- StringCchCopy(file_name_w, MAX_PATH, utf_8to16(file_name->str));
+ StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
}
if (display_filter->len > 0) {
@@ -231,7 +232,7 @@ win32_open_file (HWND h_wnd, GString *file_name, GString *display_filter) {
ofn->lpstrCustomFilter = NULL;
ofn->nMaxCustFilter = 0;
ofn->nFilterIndex = FILE_OPEN_DEFAULT;
- ofn->lpstrFile = file_name_w;
+ ofn->lpstrFile = file_name16;
ofn->nMaxFile = MAX_PATH;
ofn->lpstrFileTitle = NULL;
ofn->nMaxFileTitle = 0;
@@ -251,7 +252,7 @@ win32_open_file (HWND h_wnd, GString *file_name, GString *display_filter) {
gofn_ok = GetOpenFileName(ofn);
if (gofn_ok) {
- g_string_printf(file_name, "%s", utf_16to8(file_name_w));
+ g_string_printf(file_name, "%s", utf_16to8(file_name16));
g_string_printf(display_filter, "%s", g_dfilter_str ? g_dfilter_str : "");
}
@@ -262,15 +263,8 @@ win32_open_file (HWND h_wnd, GString *file_name, GString *display_filter) {
return gofn_ok;
}
-typedef enum {
- SAVE,
- SAVE_WITHOUT_COMMENTS,
- SAVE_IN_ANOTHER_FORMAT,
- CANCELLED
-} check_savability_t;
-
-static check_savability_t
-check_save_as_with_comments(HWND parent, capture_file *cf)
+check_savability_t
+win32_check_save_as_with_comments(HWND parent, capture_file *cf, int file_type)
{
gint response;
@@ -288,7 +282,7 @@ check_save_as_with_comments(HWND parent, capture_file *cf)
format in question supports (and handle different types of
comments, some but not all of which some file formats might
not support). */
- if (filetype == WTAP_FILE_PCAPNG) {
+ if (file_type == WTAP_FILE_PCAPNG) {
/* Yes - they selected pcap-ng. Let the save happen; we can
save the comments, so no need to delete them. */
return SAVE;
@@ -368,226 +362,97 @@ check_save_as_with_comments(HWND parent, capture_file *cf)
}
gboolean
-win32_save_as_file(HWND h_wnd, capture_file *cf,
- gboolean must_support_comments, gboolean dont_reopen)
+win32_save_as_file(HWND h_wnd, capture_file *cf, GString *file_name, int *file_type,
+ gboolean *compressed, gboolean must_support_comments)
{
GArray *savable_file_types;
OPENFILENAME *ofn;
TCHAR file_name16[MAX_PATH] = _T("");
- GString *file_name8, *file_suffix;
- gchar *file_name_lower;
- GSList *extensions_list, *extension;
- gboolean add_extension;
gchar *dirname;
int ofnsize;
+ gboolean gsfn_ok;
#if (_MSC_VER >= 1500)
OSVERSIONINFO osvi;
#endif
gboolean discard_comments = FALSE;
+ if (!file_name || !file_type || !compressed)
+ return FALSE;
+
+ if (file_name->len > 0) {
+ StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
+ }
+
savable_file_types = wtap_get_savable_file_types(cf->cd_t, cf->linktypes);
if (savable_file_types == NULL)
return FALSE; /* shouldn't happen - the "Save As..." item should be disabled if we can't save the file */
- use_compression = FALSE;
+ g_compressed = FALSE;
- /*
- * Loop until the user either selects a file or gives up.
- */
- for (;;) {
- /* see OPENFILENAME comment in win32_open_file */
+ /* see OPENFILENAME comment in win32_open_file */
#if (_MSC_VER >= 1500)
- SecureZeroMemory(&osvi, sizeof(OSVERSIONINFO));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&osvi);
- if (osvi.dwMajorVersion >= 5) {
- ofnsize = sizeof(OPENFILENAME);
- } else {
- ofnsize = OPENFILENAME_SIZE_VERSION_400;
- }
+ SecureZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+ if (osvi.dwMajorVersion >= 5) {
+ ofnsize = sizeof(OPENFILENAME);
+ } else {
+ ofnsize = OPENFILENAME_SIZE_VERSION_400;
+ }
#else
- ofnsize = sizeof(OPENFILENAME) + 12;
+ ofnsize = sizeof(OPENFILENAME) + 12;
#endif
- ofn = g_malloc0(ofnsize);
+ ofn = g_malloc0(ofnsize);
- ofn->lStructSize = ofnsize;
- ofn->hwndOwner = h_wnd;
+ ofn->lStructSize = ofnsize;
+ ofn->hwndOwner = h_wnd;
#if (_MSC_VER <= 1200)
- ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
+ ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
#else
- ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
+ ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
#endif
- ofn->lpstrFilter = build_file_save_type_list(savable_file_types,
- must_support_comments);
- ofn->lpstrCustomFilter = NULL;
- ofn->nMaxCustFilter = 0;
- ofn->nFilterIndex = 1; /* the first entry is the best match; 1-origin indexing */
- ofn->lpstrFile = file_name16;
- ofn->nMaxFile = MAX_PATH;
- ofn->lpstrFileTitle = NULL;
- ofn->nMaxFileTitle = 0;
- ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
- ofn->lpstrTitle = _T("Wireshark: Save file as");
- ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
- OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
- OFN_PATHMUSTEXIST | OFN_ENABLEHOOK | OFN_SHOWHELP;
- ofn->lpstrDefExt = NULL;
- ofn->lpfnHook = save_as_file_hook_proc;
- ofn->lpTemplateName = _T("WIRESHARK_SAVEASFILENAME_TEMPLATE");
-
- if (!GetSaveFileName(ofn)) {
- /* User cancelled or closed the dialog, or an error occurred. */
- if (CommDlgExtendedError() == 0) {
- /* User cancelled or closed the dialog. */
- return FALSE; /* No save, no comments discarded */
- }
- /* XXX - pop up some error here. FNERR_INVALIDFILENAME
- might be a user error; if so, they should know about
- it. */
- continue;
- }
-
- /* What file format was specified? */
- filetype = g_array_index(savable_file_types, int, ofn->nFilterIndex - 1);
-
- /* If the file has comments, does the format the user selected
- support them? If not, ask the user whether they want to
- discard the comments or choose a different format. */
- switch (check_save_as_with_comments(h_wnd, cf)) {
-
- case SAVE:
- /* The file can be saved in the specified format as is;
- just drive on and save in the format they selected. */
- discard_comments = FALSE;
- break;
-
- case SAVE_WITHOUT_COMMENTS:
- /* The file can't be saved in the specified format as is,
- but it can be saved without the comments, and the user
- said "OK, discard the comments", so save it in the
- format they specified without the comments. */
- discard_comments = TRUE;
- break;
-
- case SAVE_IN_ANOTHER_FORMAT:
- /* There are file formats in which we can save this that
- support comments, and the user said not to delete the
- comments. Reopen the "Save As" dialog, but with the
- list of file formats including only the formats that
- support comments, to let the user decide whether to save
- in one of those formats or give up. */
- discard_comments = FALSE;
- must_support_comments = TRUE;
- g_free( (void *) ofn->lpstrFilter);
- g_free( (void *) ofn);
- continue;
-
- case CANCELLED:
- /* The user said "forget it". Just return. */
- return FALSE; /* No save, no comments discarded */
- }
-
- /*
- * Append the default file extension if there's none given by
- * the user or if they gave one that's not one of the valid
- * extensions for the file type.
- */
- file_name8 = g_string_new(utf_16to8(file_name16));
- file_name_lower = g_utf8_strdown(file_name8->str, -1);
- file_suffix = g_string_new("");
- extensions_list = wtap_get_file_extensions_list(filetype, FALSE);
- if (extensions_list != NULL) {
- /* We have one or more extensions for this file type.
- Start out assuming we need to add the default one. */
- add_extension = TRUE;
-
- /* OK, see if the file has one of those extensions. */
- for (extension = extensions_list; extension != NULL;
- extension = g_slist_next(extension)) {
- g_string_printf(file_suffix, ".%s", extension);
- if (g_str_has_suffix(file_name_lower, file_suffix->str)) {
- /*
- * The file name has one of the extensions for
- * this file type.
- */
- add_extension = FALSE;
- break;
- }
- g_string_append(file_suffix, ".gz");
- if (g_str_has_suffix(file_name_lower, file_suffix->str)) {
- /*
- * The file name has one of the extensions for
- * this file type.
- */
- add_extension = FALSE;
- break;
- }
- }
- } else {
- /* We have no extensions for this file type. Don't add one. */
- add_extension = FALSE;
- }
- g_free(file_name_lower);
- g_string_free(file_suffix, TRUE);
- if (add_extension) {
- if (wtap_default_file_extension(filetype) != NULL) {
- g_string_append_printf(file_name8, ".%s",
- wtap_default_file_extension(filetype));
- if (use_compression) {
- g_string_append(file_name8, ".gz");
- }
- }
- }
+ ofn->lpstrFilter = build_file_save_type_list(savable_file_types,
+ must_support_comments);
+ ofn->lpstrCustomFilter = NULL;
+ ofn->nMaxCustFilter = 0;
+ ofn->nFilterIndex = 1; /* the first entry is the best match; 1-origin indexing */
+ ofn->lpstrFile = file_name16;
+ ofn->nMaxFile = MAX_PATH;
+ ofn->lpstrFileTitle = NULL;
+ ofn->nMaxFileTitle = 0;
+ ofn->lpstrInitialDir = utf_8to16(get_last_open_dir());
+ ofn->lpstrTitle = _T("Wireshark: Save file as");
+ ofn->Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER |
+ OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
+ OFN_PATHMUSTEXIST | OFN_ENABLEHOOK | OFN_SHOWHELP;
+ ofn->lpstrDefExt = NULL;
+ ofn->lpfnHook = save_as_file_hook_proc;
+ ofn->lpTemplateName = _T("WIRESHARK_SAVEASFILENAME_TEMPLATE");
- g_sf_hwnd = NULL;
+ gsfn_ok = GetSaveFileName(ofn);
- /*
- * GetSaveFileName() already asked the user if he wants to
- * overwrite the old file, so if we are here, the user already
- * said "yes". Write out all the packets to the file with the
- * specified name.
- *
- * XXX: if the cf_save_packets() fails, it will do a GTK+
- * simple_dialog(), which is not useful while runing a Windows
- * dialog.
- * (A GTK dialog box will be generated and basically will
- * only appear when the redisplayed Windows 'save_as-file'
- * dialog is dismissed. It will then need to be dismissed.
- * This should be fixed even though the cf_save_packets()
- * presumably should rarely fail in this case.
+ if (gsfn_ok) {
+ g_string_printf(file_name, "%s", utf_16to8(file_name16));
+ /* What file format was specified? */
+ *file_type = g_array_index(savable_file_types, int, ofn->nFilterIndex - 1);
+ *compressed = g_compressed;
+ } else {
+ /* User cancelled or closed the dialog, or an error occurred. */
+ if (CommDlgExtendedError() != 0) {
+ /* XXX - pop up some error here. FNERR_INVALIDFILENAME
+ * might be a user error; if so, they should know about
+ * it. For now we force a do-over.
*/
- switch (cf_save_packets(&cfile, file_name8->str, filetype,
- use_compression,
- discard_comments,
- dont_reopen)) {
- case CF_WRITE_OK:
- /* The save succeeded; we're done.
- Save the directory name for future file dialogs. */
- dirname = get_dirname(file_name8->str); /* Overwrites file_name8->str */
- set_last_open_dir(dirname);
- break;
-
- case CF_WRITE_ERROR:
- /* The save failed; let the user try again. */
- g_string_free(file_name8, TRUE /* free_segment */);
- g_free( (void *) ofn->lpstrFilter);
- g_free( (void *) ofn);
- continue;
-
- case CF_WRITE_ABORTED:
- /* The user aborted the save; just return. */
- break;
- }
- g_string_free(file_name8, TRUE /* free_segment */);
- break;
+ g_string_truncate(file_name, 0);
+ gsfn_ok = TRUE;
}
+
g_sf_hwnd = NULL;
g_array_free(savable_file_types, TRUE);
g_free( (void *) ofn->lpstrFilter);
g_free( (void *) ofn);
- return discard_comments;
+ return gsfn_ok;
}
-
void
win32_export_specified_packets_file(HWND h_wnd) {
GArray *savable_file_types;
@@ -647,7 +512,7 @@ win32_export_specified_packets_file(HWND h_wnd) {
ofn->lpTemplateName = _T("WIRESHARK_EXPORT_SPECIFIED_PACKETS_FILENAME_TEMPLATE");
if (GetSaveFileName(ofn)) {
- filetype = g_array_index(savable_file_types, int, ofn->nFilterIndex - 1);
+ g_filetype = g_array_index(savable_file_types, int, ofn->nFilterIndex - 1);
/*
* Append the default file extension if there's none given by the user
@@ -656,7 +521,7 @@ win32_export_specified_packets_file(HWND h_wnd) {
*/
file_name8 = g_string_new(utf_16to8(file_name16));
file_last_dot = strrchr(file_name8->str,'.');
- extensions_list = wtap_get_file_extensions_list(filetype, FALSE);
+ extensions_list = wtap_get_file_extensions_list(g_filetype, FALSE);
if (extensions_list != NULL) {
/* We have one or more extensions for this file type.
Start out assuming we need to add the default one. */
@@ -680,8 +545,8 @@ win32_export_specified_packets_file(HWND h_wnd) {
add_extension = FALSE;
}
if (add_extension) {
- if (wtap_default_file_extension(filetype) != NULL) {
- g_string_append_printf(file_name8, ".%s", wtap_default_file_extension(filetype));
+ if (wtap_default_file_extension(g_filetype) != NULL) {
+ g_string_append_printf(file_name8, ".%s", wtap_default_file_extension(g_filetype));
}
}
@@ -702,7 +567,7 @@ win32_export_specified_packets_file(HWND h_wnd) {
* This should be fixed even though the cf_save_packets()
* presumably should rarely fail in this case.
*/
- if (cf_export_specified_packets(&cfile, file_name8->str, &g_range, filetype, FALSE) != CF_OK) {
+ if (cf_export_specified_packets(&cfile, file_name8->str, &g_range, g_filetype, FALSE) != CF_OK) {
/* The write failed. Try again. */
g_array_free(savable_file_types, TRUE);
g_string_free(file_name8, TRUE /* free_segment */);
@@ -728,7 +593,7 @@ win32_export_specified_packets_file(HWND h_wnd) {
gboolean
win32_merge_file (HWND h_wnd, GString *file_name, GString *display_filter, int *merge_type) {
OPENFILENAME *ofn;
- TCHAR file_name_w[MAX_PATH] = _T("");
+ TCHAR file_name16[MAX_PATH] = _T("");
int ofnsize;
gboolean gofn_ok;
#if (_MSC_VER >= 1500)
@@ -739,7 +604,7 @@ win32_merge_file (HWND h_wnd, GString *file_name, GString *display_filter, int *
return FALSE;
if (file_name->len > 0) {
- StringCchCopy(file_name_w, MAX_PATH, utf_8to16(file_name->str));
+ StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
}
if (display_filter->len > 0) {
@@ -775,7 +640,7 @@ win32_merge_file (HWND h_wnd, GString *file_name, GString *display_filter, int *
ofn->lpstrCustomFilter = NULL;
ofn->nMaxCustFilter = 0;
ofn->nFilterIndex = FILE_MERGE_DEFAULT;
- ofn->lpstrFile = file_name_w;
+ ofn->lpstrFile = file_name16;
ofn->nMaxFile = MAX_PATH;
ofn->lpstrFileTitle = NULL;
ofn->nMaxFileTitle = 0;
@@ -795,7 +660,7 @@ win32_merge_file (HWND h_wnd, GString *file_name, GString *display_filter, int *
gofn_ok = GetOpenFileName(ofn);
if (gofn_ok) {
- g_string_printf(file_name, "%s", utf_16to8(file_name_w));
+ g_string_printf(file_name, "%s", utf_16to8(file_name16));
g_string_printf(display_filter, "%s", g_dfilter_str ? g_dfilter_str : "");
switch (g_merge_action) {
@@ -1173,7 +1038,7 @@ win32_export_color_file(HWND h_wnd, gpointer filter_list) {
ofn->lpfnHook = NULL;
ofn->lpTemplateName = NULL;
- filetype = cfile.cd_t;
+ g_filetype = cfile.cd_t;
/* XXX - Support marked filters */
if (GetSaveFileName(ofn)) {
@@ -1673,7 +1538,7 @@ open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
/* Generate a list of the file types we can save this file as.
- "filetype" is the type it has now.
+ "g_filetype" is the type it has now.
"encap" is the encapsulation for its packets (which could be
"unknown" or "per-packet").
@@ -1824,7 +1689,7 @@ build_file_format_list(HWND sf_hwnd) {
SendMessage(format_cb, CB_ADDSTRING, 0, (LPARAM) utf_8to16(s));
g_free(s);
SendMessage(format_cb, CB_SETITEMDATA, (LPARAM) index, (WPARAM) ft);
- if (ft == filetype) {
+ if (ft == g_filetype) {
/* Default to the same format as the file, if it's supported. */
item_to_select = index;
}
@@ -1850,13 +1715,13 @@ save_as_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
g_sf_hwnd = sf_hwnd;
/* Default to saving in the file's current format. */
- filetype = cfile.cd_t;
+ g_filetype = cfile.cd_t;
/* Fill in the file format list */
/*build_file_format_list(sf_hwnd);*/
/* Fill in the compression checkbox */
cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
- SendMessage(cur_ctrl, BM_SETCHECK, use_compression, 0);
+ SendMessage(cur_ctrl, BM_SETCHECK, g_compressed, 0);
break;
case WM_COMMAND:
@@ -1869,7 +1734,7 @@ save_as_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
if (index != CB_ERR) {
new_filetype = SendMessage(cur_ctrl, CB_GETITEMDATA, (WPARAM) index, 0);
if (new_filetype != CB_ERR) {
- if (filetype != new_filetype) {
+ if (g_filetype != new_filetype) {
if (wtap_can_save_with_wiretap(new_filetype, cfile.linktypes)) {
cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN);
EnableWindow(cur_ctrl, TRUE);
@@ -1882,15 +1747,15 @@ save_as_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
EnableWindow(cur_ctrl, FALSE);
}
- filetype = new_filetype;
+ g_filetype = new_filetype;
cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
if (wtap_dump_can_compress(file_type) {
EnableWindow(cur_ctrl);
} else {
- use_compression = FALSE;
+ g_compressed = FALSE;
DisableWindow(cur_ctrl);
}
- SendMessage(cur_ctrl, BM_SETCHECK, use_compression, 0);
+ SendMessage(cur_ctrl, BM_SETCHECK, g_compressed, 0);
}
}
@@ -1915,9 +1780,9 @@ save_as_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
/* Fetch our compression value */
cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
- use_compression = TRUE;
+ g_compressed = TRUE;
else
- use_compression = FALSE;
+ g_compressed = FALSE;
/* Check if trying to do 'save as' to the currently open file */
parent = GetParent(sf_hwnd);
@@ -1964,7 +1829,7 @@ export_specified_packets_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param,
g_sf_hwnd = sf_hwnd;
/* Default to saving all packets, in the file's current format. */
- filetype = cfile.cd_t;
+ g_filetype = cfile.cd_t;
/* init the packet range */
packet_range_init(&g_range);
@@ -1988,7 +1853,7 @@ export_specified_packets_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param,
if (index != CB_ERR) {
new_filetype = SendMessage(cur_ctrl, CB_GETITEMDATA, (WPARAM) index, 0);
if (new_filetype != CB_ERR) {
- if (filetype != new_filetype) {
+ if (g_filetype != new_filetype) {
if (wtap_can_save_with_wiretap(new_filetype, cfile.linktypes)) {
cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN);
EnableWindow(cur_ctrl, TRUE);
@@ -2001,7 +1866,7 @@ export_specified_packets_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param,
cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
EnableWindow(cur_ctrl, FALSE);
}
- filetype = new_filetype;
+ g_filetype = new_filetype;
}
}
}
diff --git a/ui/win32/file_dlg_win32.h b/ui/win32/file_dlg_win32.h
index 4131b972c7..44e627dca0 100644
--- a/ui/win32/file_dlg_win32.h
+++ b/ui/win32/file_dlg_win32.h
@@ -44,6 +44,17 @@ typedef enum {
*/
gboolean win32_open_file (HWND h_wnd, GString *file_name, GString *display_filter);
+/** Verify that our proposed capture file format supports comments. If it can't
+ * ask the user what to do and return his or her response.
+ *
+ * @param h_wnd HWND of the parent window.
+ * @param cf Capture file.
+ * @param file_format Proposed file format.
+ *
+ * @return
+ */
+check_savability_t win32_check_save_as_with_comments(HWND parent, capture_file *cf, int file_type);
+
/** Open the "Save As" dialog box.
*
* @param h_wnd HWND of the parent window.
@@ -56,8 +67,9 @@ gboolean win32_open_file (HWND h_wnd, GString *file_name, GString *display_filte
* @return TRUE if packets were discarded when saving, FALSE otherwise
*/
gboolean win32_save_as_file(HWND h_wnd, capture_file *cf,
- gboolean must_support_comments,
- gboolean dont_reopen);
+ GString *file_name, int *file_type,
+ gboolean *compressed,
+ gboolean must_support_comments);
/** Open the "Export Specified Packets" dialog box.
*