Have the frame_tvbuff.c routines not use the global cfile.
[metze/wireshark/wip.git] / ui / win32 / file_dlg_win32.c
index 7b17b1792f400d4cb9a97059d7e61061ddc3360c..ebfc57590043305a5026409a8391bc4ff9534f5a 100644 (file)
-/* win32-file-dlg.c
+/* file_dlg_win32.c
  * Native Windows file dialog routines
  *
- * $Id$
- *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
  * 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.
+ * SPDX-License-Identifier: GPL-2.0+
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
-#include <stdio.h>
 #include <tchar.h>
-#include <wchar.h>
 #include <stdlib.h>
-#include <sys/stat.h>
-#include <io.h>
 #include <fcntl.h>
 
 #include <windows.h>
-#include <windowsx.h>
 #include <commdlg.h>
 #include <richedit.h>
+#include <strsafe.h>
 
-#include <gtk/gtk.h>
+#include "globals.h"
 
-#include "epan/filesystem.h"
-#include "epan/addr_resolv.h"
-#include "epan/prefs.h"
-#include "epan/dissectors/packet-ssl.h"
-#include "epan/dissectors/packet-ssl-utils.h"
 #include "wsutil/file_util.h"
+#include "wsutil/str_util.h"
 #include "wsutil/unicode-utils.h"
 
-#include "../alert_box.h"
-#include "../color.h"
-#include "../print.h"
-#include "../simple_dialog.h"
-#include "../util.h"
-#include "../color_filters.h"
-#include "../merge.h"
+#include "wsutil/filesystem.h"
+#include "epan/prefs.h"
+
+#include "epan/color_filters.h"
 
+#include "ui/alert_box.h"
+#include "ui/help_url.h"
 #include "ui/last_open_dir.h"
+#include "ui/simple_dialog.h"
+#include "ui/ssl_key_export.h"
+#include "ui/util.h"
+#include "ui/ws_ui_util.h"
+#include "ui/all_files_wildcard.h"
 
-#include "ui/gtk/main.h"
-#include "ui/gtk/file_dlg.h"
-#include "ui/gtk/capture_file_dlg.h"
-#include "ui/gtk/menus.h"
-#include "ui/gtk/drag_and_drop.h"
-#include "ui/gtk/capture_dlg.h"
 #include "file_dlg_win32.h"
-#include "ui/gtk/help_dlg.h"
-#include "ui/gtk/export_sslkeys.h"
-
-typedef enum {
-    merge_append,
-    merge_chrono,
-    merge_prepend
-} merge_action_e;
 
 #define FILE_OPEN_DEFAULT 1 /* All Files */
 
 #define FILE_MERGE_DEFAULT FILE_OPEN_DEFAULT
 
-#define FILE_SAVE_DEFAULT 1 /* Wireshark/tcpdump */
-
 #define FILE_TYPES_EXPORT \
     _T("Plain text (*.txt)\0")                           _T("*.txt\0")   \
     _T("PostScript (*.ps)\0")                            _T("*.ps\0")    \
     _T("CSV (Comma Separated Values summary) (*.csv)\0") _T("*.csv\0")   \
     _T("PSML (XML packet summary) (*.psml)\0")           _T("*.psml\0")  \
     _T("PDML (XML packet detail) (*.pdml)\0")            _T("*.pdml\0")  \
-    _T("C Arrays (packet bytes) (*.c)\0")                _T("*.c\0")
+    _T("C Arrays (packet bytes) (*.c)\0")                _T("*.c\0")     \
+    _T("JSON (*.json)\0")                                _T("*.json\0")
 
 #define FILE_TYPES_RAW \
     _T("Raw data (*.bin, *.dat, *.raw)\0")               _T("*.bin;*.dat;*.raw\0") \
-    _T("All Files (*.*)\0")                              _T("*.*\0")
+    _T("All Files (") _T(ALL_FILES_WILDCARD) _T(")\0")   _T(ALL_FILES_WILDCARD) _T("\0")
 
 #define FILE_RAW_DEFAULT 1
 
 #define FILE_TYPES_SSLKEYS \
     _T("SSL Session Keys (*.keys)\0")                    _T("*.keys\0") \
-    _T("All Files (*.*)\0")                              _T("*.*\0")
+    _T("All Files (") _T(ALL_FILES_WILDCARD) _T(")\0")   _T(ALL_FILES_WILDCARD) _T("\0")
 
 #define FILE_SSLKEYS_DEFAULT 1
 
 #define FILE_TYPES_COLOR \
     _T("Text Files (*.txt)\0")                           _T("*.txt\0")   \
-    _T("All Files (*.*)\0")                              _T("*.*\0")
+    _T("All Files (") _T(ALL_FILES_WILDCARD) _T(")\0")   _T(ALL_FILES_WILDCARD) _T("\0")
 
 #define FILE_DEFAULT_COLOR 2
 
-/*
- * We should probably test the SDK version instead of the compiler version,
- * but this should work for our purposes.
- */
-#if (_MSC_VER <= 1200)
-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 export_specified_packets_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 UINT CALLBACK export_sslkeys_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
-#else
 static UINT_PTR CALLBACK open_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
 static UINT_PTR CALLBACK save_as_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
+static UINT_PTR CALLBACK save_as_statstree_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
 static UINT_PTR CALLBACK export_specified_packets_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
 static UINT_PTR CALLBACK merge_file_hook_proc(HWND mf_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
 static UINT_PTR CALLBACK export_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
 static UINT_PTR CALLBACK export_raw_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
 static UINT_PTR CALLBACK export_sslkeys_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param);
-#endif /* (_MSC_VER <= 1200) */
-
 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);
@@ -136,10 +87,12 @@ static void range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, pa
 static TCHAR *build_file_open_type_list(void);
 static TCHAR *build_file_save_type_list(GArray *savable_file_types);
 
-static int            filetype;
-static packet_range_t g_range;
-static merge_action_e merge_action;
-static print_args_t   print_args;
+static int             g_filetype;
+static gboolean        g_compressed;
+static packet_range_t *g_range;
+static capture_file   *g_cf;
+static merge_action_e  g_merge_action;
+static print_args_t    print_args;
 /* XXX - The reason g_sf_hwnd exists is so that we can call
  *       range_update_dynamics() from anywhere; it's currently
  *       static, but if we move to using the native Windows
@@ -151,9 +104,69 @@ static print_args_t   print_args;
  *       should arguably be modal to the window for the file
  *       being opened/saved/etc.).
  */
-static HWND           g_sf_hwnd = NULL;
-static char *dfilter_str = NULL;
+static HWND  g_sf_hwnd = NULL;
+static char *g_dfilter_str = NULL;
+static unsigned int g_format_type = WTAP_TYPE_AUTO;
 
+static int
+win32_get_ofnsize()
+{
+    gboolean bVerGE5 = FALSE;
+    int ofnsize;
+    /* Remarks on OPENFILENAME_SIZE_VERSION_400:
+    *
+    * MSDN states that OPENFILENAME_SIZE_VERSION_400 should be used with
+    * WINVER and _WIN32_WINNT >= 0x0500.
+    * Unfortunately all these are compiler constants, while the underlying is a
+    * problem based is a length check of the runtime version used.
+    *
+    * Instead of using OPENFILENAME_SIZE_VERSION_400, just malloc
+    * the OPENFILENAME size plus 12 bytes.
+    * These 12 bytes are the difference between the two versions of this struct.
+    *
+    * Interestingly this fixes a bug, so the places bar e.g. "My Documents"
+    * is displayed - which wasn't the case with the former implementation.
+    *
+    * XXX - It's unclear if this length+12 works on all supported platforms,
+    * NT4 is the question here. However, even if it fails, we must calculate
+    * the length based on the runtime, not the compiler version anyway ...
+    */
+    /* This assumption does not work when compiling with MSVC2008EE as
+    * the open dialog window does not appear.
+    * Instead detect Windows version at runtime and choose size accordingly */
+#if (_MSC_VER >= 1500)
+    /*
+    * On VS2103, GetVersionEx is deprecated. Microsoft recommend to
+    * use VerifyVersionInfo instead
+    */
+#if (_MSC_VER >= 1800)
+    OSVERSIONINFOEX osvi;
+    DWORDLONG dwlConditionMask = 0;
+    int op = VER_GREATER_EQUAL;
+    /* Initialize the OSVERSIONINFOEX structure. */
+    SecureZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+    osvi.dwMajorVersion = 5;
+    /* Initialize the condition mask. */
+    VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
+    /* Perform the test. */
+    bVerGE5=VerifyVersionInfo(
+        &osvi,
+        VER_MAJORVERSION,
+        dwlConditionMask);
+#else
+    OSVERSIONINFO osvi;
+    SecureZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    GetVersionEx(&osvi);
+    bVerGE5 = (osvi.dwMajorVersion >= 5);
+#endif /* _MSC_VER >= 1800 */
+    ofnsize = (bVerGE5)?sizeof(OPENFILENAME):OPENFILENAME_SIZE_VERSION_400;
+#else
+    ofnsize = sizeof(OPENFILENAME)+12;
+#endif /* _MSC_VER >= 1500 */
+    return ofnsize;
+}
 /*
  * According to http://msdn.microsoft.com/en-us/library/bb776913.aspx
  * we should use IFileOpenDialog and IFileSaveDialog on Windows Vista
@@ -161,64 +174,36 @@ static char *dfilter_str = NULL;
  */
 
 gboolean
-win32_open_file (HWND h_wnd) {
+win32_open_file (HWND h_wnd, GString *file_name, unsigned int *type, GString *display_filter) {
     OPENFILENAME *ofn;
-    TCHAR  file_name[MAX_PATH] = _T("");
-    int    err;
-    char  *dirname;
-    dfilter_t *dfp;
-    int    ofnsize;
-#if (_MSC_VER >= 1500)
-    OSVERSIONINFO osvi;
-#endif
+    TCHAR file_name16[MAX_PATH] = _T("");
+    int ofnsize;
+    gboolean gofn_ok;
 
-    /* Remarks on OPENFILENAME_SIZE_VERSION_400:
-     *
-     * MSDN states that OPENFILENAME_SIZE_VERSION_400 should be used with
-     * WINVER and _WIN32_WINNT >= 0x0500.
-     * Unfortunately all these are compiler constants, while the underlying is a
-     * problem based is a length check of the runtime version used.
-     *
-     * Instead of using OPENFILENAME_SIZE_VERSION_400, just malloc
-     * the OPENFILENAME size plus 12 bytes.
-     * These 12 bytes are the difference between the two versions of this struct.
-     *
-     * Interestingly this fixes a bug, so the places bar e.g. "My Documents"
-     * is displayed - which wasn't the case with the former implementation.
-     *
-     * XXX - It's unclear if this length+12 works on all supported platforms,
-     * NT4 is the question here. However, even if it fails, we must calculate
-     * the length based on the runtime, not the compiler version anyway ...
-     */
-    /* This assumption does not work when compiling with MSVC2008EE as
-     * the open dialog window does not appear.
-     * Instead detect Windows version at runtime and choose size accordingly */
-#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;
+    if (!file_name || !display_filter)
+        return FALSE;
+
+    if (file_name->len > 0) {
+        StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
     }
-#else
-    ofnsize = sizeof(OPENFILENAME) + 12;
-#endif
+
+    if (display_filter->len > 0) {
+        g_dfilter_str = g_strdup(display_filter->str);
+    } else if (g_dfilter_str) {
+        g_free(g_dfilter_str);
+        g_dfilter_str = NULL;
+    }
+    ofnsize = win32_get_ofnsize();
     ofn = g_malloc0(ofnsize);
 
     ofn->lStructSize = ofnsize;
     ofn->hwndOwner = h_wnd;
-#if (_MSC_VER <= 1200)
-    ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
-#else
     ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
-#endif
     ofn->lpstrFilter = build_file_open_type_list();
     ofn->lpstrCustomFilter = NULL;
     ofn->nMaxCustFilter = 0;
     ofn->nFilterIndex = FILE_OPEN_DEFAULT;
-    ofn->lpstrFile = file_name;
+    ofn->lpstrFile = file_name16;
     ofn->nMaxFile = MAX_PATH;
     ofn->lpstrFileTitle = NULL;
     ofn->nMaxFileTitle = 0;
@@ -235,77 +220,147 @@ win32_open_file (HWND h_wnd) {
     ofn->lpfnHook = open_file_hook_proc;
     ofn->lpTemplateName = _T("WIRESHARK_OPENFILENAME_TEMPLATE");
 
-    if (GetOpenFileName(ofn)) {
-        g_free( (void *) ofn->lpstrFilter);
-        g_free( (void *) ofn);
+    gofn_ok = GetOpenFileName(ofn);
 
-        if (cf_open(&cfile, utf_16to8(file_name), FALSE, &err) != CF_OK) {
-            return FALSE;
-        }
+    if (gofn_ok) {
+        g_string_printf(file_name, "%s", utf_16to8(file_name16));
+        g_string_printf(display_filter, "%s", g_dfilter_str ? g_dfilter_str : "");
+        *type = g_format_type;
+    }
 
-        /* apply our filter */
-        if (dfilter_compile(dfilter_str, &dfp)) {
-            cf_set_rfcode(&cfile, dfp);
-        }
+    g_free( (void *) ofn->lpstrFilter);
+    g_free( (void *) ofn);
+    g_free(g_dfilter_str);
+    g_dfilter_str = NULL;
+    return gofn_ok;
+}
 
-        switch (cf_read(&cfile, FALSE)) {
-            case CF_READ_OK:
-            case CF_READ_ERROR:
-                dirname = get_dirname(utf_16to8(file_name));
-                set_last_open_dir(dirname);
-                return TRUE;
-                break;
-        }
+check_savability_t
+win32_check_save_as_with_comments(HWND parent, capture_file *cf, int file_type)
+{
+    guint32        comment_types;
+    gint           response;
+
+    /* What types of comments do we have? */
+    comment_types = cf_comment_types(cf);
+
+    /* Does the file's format support all the comments we have? */
+    if (wtap_dump_supports_comment_types(file_type, comment_types)) {
+        /* Yes.  Let the save happen; we can save all the comments, so
+           there's no need to delete them. */
+        return SAVE;
+    }
+
+    /* No. Are there formats in which we can write this file that
+       supports all the comments in this file? */
+    if (wtap_dump_can_write(cf->linktypes, comment_types)) {
+        /* Yes.  Offer the user a choice of "Save in a format that
+           supports comments", "Discard comments and save in the
+           format you selected", or "Cancel", meaning "don't bother
+           saving the file at all".
+
+           XXX - given that we no longer support releases prior to
+           Windows Vista, we should use a task dialog:
+
+               https://msdn.microsoft.com/en-us/library/windows/desktop/ff486057(v=vs.85).aspx
+
+           created with TaskDialogIndirect():
+
+               https://msdn.microsoft.com/en-us/library/windows/desktop/bb760544(v=vs.85).aspx
+
+           because the TASKDIALOGCONFIG structure
+
+               https://msdn.microsoft.com/en-us/library/windows/desktop/bb787473(v=vs.85).aspx
+
+           supports adding custom buttons, with custom labels, unlike
+           a MessageBox(), which doesn't appear to offer a clean way to
+           do that. */
+        response = MessageBox(parent,
+  _T("The capture has comments, but the file format you chose ")
+  _T("doesn't support comments.  Do you want to discard the comments ")
+  _T("and save in the format you chose?"),
+                              _T("Wireshark: Save File As"),
+                              MB_YESNOCANCEL|MB_ICONWARNING|MB_DEFBUTTON2);
     } else {
-        g_free( (void *) ofn->lpstrFilter);
-        g_free( (void *) ofn);
+        /* No.  Offer the user a choice of "Discard comments and
+           save in the format you selected" or "Cancel".
+
+           XXX - see rant above. */
+        response = MessageBox(parent,
+  _T("The capture has comments, but no file format in which it ")
+  _T("can be saved supports comments.  Do you want to discard ")
+  _T("the comments and save in the format you chose?"),
+                              _T("Wireshark: Save File As"),
+                              MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2);
     }
-    return FALSE;
-}
 
+    switch (response) {
+
+    case IDNO: /* "No" means "Save in another format" in the first dialog */
+        /* OK, the only other format we support is pcap-ng.  Make that
+           the one and only format in the combo box, and return to
+           let the user continue with the dialog.
+
+           XXX - removing all the formats from the combo box will clear
+           the compressed checkbox; get the current value and restore
+           it.
+
+           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. */
+        /* XXX - need a compressed checkbox here! */
+        return SAVE_IN_ANOTHER_FORMAT;
+
+    case IDYES: /* "Yes" means "Discard comments and save" in the first dialog */
+    case IDOK:  /* "OK" means "Discard comments and save" in the second dialog */
+        /* Save without the comments and, if that succeeds, delete the
+           comments. */
+        return SAVE_WITHOUT_COMMENTS;
+
+    case IDCANCEL:
+    default:
+        /* Just give up. */
+        return CANCELLED;
+    }
+}
 
-void
-win32_save_as_file(HWND h_wnd)
+gboolean
+win32_save_as_file(HWND h_wnd, capture_file *cf, GString *file_name, int *file_type,
+                   gboolean *compressed, gboolean must_support_all_comments)
 {
+    guint32 required_comment_types;
     GArray *savable_file_types;
     OPENFILENAME *ofn;
     TCHAR  file_name16[MAX_PATH] = _T("");
-    GString *file_name8;
-    gchar *file_last_dot;
-    GSList *extensions_list, *extension;
-    gboolean add_extension;
-    gchar *dirname;
     int    ofnsize;
-#if (_MSC_VER >= 1500)
-    OSVERSIONINFO osvi;
-#endif
+    gboolean gsfn_ok;
 
-    savable_file_types = wtap_get_savable_file_types(cfile.cd_t, cfile.linktypes);
-    if (savable_file_types == NULL)
-        return;  /* shouldn't happen - the "Save As..." item should be disabled if we can't save the file */
+    if (!file_name || !file_type || !compressed)
+        return FALSE;
 
-    /* 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;
+    if (file_name->len > 0) {
+        StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
     }
-#else
-    ofnsize = sizeof(OPENFILENAME) + 12;
-#endif
+
+    /* What types of comments do we have to support? */
+    if (must_support_all_comments)
+        required_comment_types = cf_comment_types(cf); /* all the ones the file has */
+    else
+        required_comment_types = 0; /* none of them */
+
+    savable_file_types = wtap_get_savable_file_types_subtypes(cf->cd_t,
+                                                              cf->linktypes,
+                                                              required_comment_types);
+    if (savable_file_types == NULL)
+        return FALSE;  /* shouldn't happen - the "Save As..." item should be disabled if we can't save the file */
+    g_compressed = FALSE;
+
+    ofnsize = win32_get_ofnsize();
     ofn = g_malloc0(ofnsize);
 
     ofn->lStructSize = ofnsize;
     ofn->hwndOwner = h_wnd;
-#if (_MSC_VER <= 1200)
-    ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
-#else
     ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
-#endif
     ofn->lpstrFilter = build_file_save_type_list(savable_file_types);
     ofn->lpstrCustomFilter = NULL;
     ofn->nMaxCustFilter = 0;
@@ -320,105 +375,52 @@ win32_save_as_file(HWND h_wnd)
                  OFN_NOCHANGEDIR   | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
                  OFN_PATHMUSTEXIST | OFN_ENABLEHOOK      | OFN_SHOWHELP;
     ofn->lpstrDefExt = NULL;
+    ofn->lCustData = (LPARAM) cf;
     ofn->lpfnHook = save_as_file_hook_proc;
-    ofn->lpTemplateName = _T("WIRESHARK_SAVEFILENAME_TEMPLATE");
+    ofn->lpTemplateName = _T("WIRESHARK_SAVEASFILENAME_TEMPLATE");
 
-    if (GetSaveFileName(ofn)) {
-        filetype = g_array_index(savable_file_types, int, ofn->nFilterIndex - 1);
+    gsfn_ok = GetSaveFileName(ofn);
 
-        /*
-         * 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_last_dot = strrchr(file_name8->str,'.');
-        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;
-            if (file_last_dot != NULL) {
-                /* Skip past the dot. */
-                file_last_dot++;
-
-                /* OK, see if the file has one of those extensions. */
-                for (extension = extensions_list; extension != NULL;
-                     extension = g_slist_next(extension)) {
-                    if (g_ascii_strcasecmp((char *)extension->data, file_last_dot) == 0) {
-                        /* 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;
-        }
-        if (add_extension) {
-            if (wtap_default_file_extension(filetype) != NULL) {
-                g_string_append_printf(file_name8, ".%s", wtap_default_file_extension(filetype));
-            }
-        }
-
-        g_sf_hwnd = NULL;
-
-        /*
-         * 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 (cf_save_packets(&cfile, file_name8->str, filetype, FALSE, FALSE) != CF_OK) {
-            /* The write failed.  Try again. */
-            g_array_free(savable_file_types, TRUE);
-            g_string_free(file_name8, TRUE /* free_segment */);
-            g_free( (void *) ofn->lpstrFilter);
-            g_free( (void *) ofn);
-            win32_save_as_file(h_wnd);
-            return;
+    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.
+             */
+            g_string_truncate(file_name, 0);
+            gsfn_ok = TRUE;
         }
-
-        /* Save the directory name for future file dialogs. */
-        dirname = get_dirname(file_name8->str);  /* Overwrites cf_name */
-        set_last_open_dir(dirname);
-
-        g_string_free(file_name8, TRUE /* free_segment */);
     }
+
     g_sf_hwnd = NULL;
     g_array_free(savable_file_types, TRUE);
     g_free( (void *) ofn->lpstrFilter);
     g_free( (void *) ofn);
+    return gsfn_ok;
 }
 
-
-void
-win32_export_specified_packets_file(HWND h_wnd) {
-    GArray *savable_file_types;
+gboolean win32_save_as_statstree(HWND h_wnd, GString *file_name, int *file_type)
+{
     OPENFILENAME *ofn;
     TCHAR  file_name16[MAX_PATH] = _T("");
-    GString *file_name8;
-    gchar *file_last_dot;
-    GSList *extensions_list, *extension;
-    gboolean add_extension;
-    gchar *dirname;
     int    ofnsize;
+    gboolean gsfn_ok;
 #if (_MSC_VER >= 1500)
     OSVERSIONINFO osvi;
 #endif
 
-    savable_file_types = wtap_get_savable_file_types(cfile.cd_t, cfile.linktypes);
-    if (savable_file_types == NULL)
-        return;  /* shouldn't happen - the "Save As..." item should be disabled if we can't save the file */
+    if (!file_name || !file_type)
+        return FALSE;
+
+    if (file_name->len > 0) {
+        StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
+    }
 
     /* see OPENFILENAME comment in win32_open_file */
 #if (_MSC_VER >= 1500)
@@ -437,11 +439,72 @@ win32_export_specified_packets_file(HWND h_wnd) {
 
     ofn->lStructSize = ofnsize;
     ofn->hwndOwner = h_wnd;
-#if (_MSC_VER <= 1200)
-    ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
-#else
     ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
-#endif
+    ofn->lpstrFilter = _T("Plain text file (.txt)\0*.txt\0Comma separated values (.csv)\0*.csv\0XML document (.xml)\0*.xml\0YAML document (.yaml)\0*.yaml\0");
+    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 stats tree 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_statstree_hook_proc;
+    ofn->lpTemplateName = _T("WIRESHARK_SAVEASSTATSTREENAME_TEMPLATE");
+
+    gsfn_ok = GetSaveFileName(ofn);
+
+    if (gsfn_ok) {
+        g_string_printf(file_name, "%s", utf_16to8(file_name16));
+        /* What file format was specified? */
+        *file_type = ofn->nFilterIndex - 1;
+    }
+
+    g_sf_hwnd = NULL;
+    g_free( (void *) ofn);
+    return gsfn_ok;
+}
+
+
+gboolean
+win32_export_specified_packets_file(HWND h_wnd, capture_file *cf,
+                                    GString *file_name,
+                                    int *file_type,
+                                    gboolean *compressed,
+                                    packet_range_t *range) {
+    GArray *savable_file_types;
+    OPENFILENAME *ofn;
+    TCHAR  file_name16[MAX_PATH] = _T("");
+    int    ofnsize;
+    gboolean gsfn_ok;
+
+    if (!file_name || !file_type || !compressed || !range)
+        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_subtypes(cf->cd_t,
+                                                              cf->linktypes, 0);
+    if (savable_file_types == NULL)
+        return FALSE;  /* shouldn't happen - the "Save As..." item should be disabled if we can't save the file */
+
+    g_range = range;
+    g_cf = cf;
+    g_compressed = FALSE;
+
+    ofnsize = win32_get_ofnsize();
+    ofn = g_malloc0(ofnsize);
+
+    ofn->lStructSize = ofnsize;
+    ofn->hwndOwner = h_wnd;
+    ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
     ofn->lpstrFilter = build_file_save_type_list(savable_file_types);
     ofn->lpstrCustomFilter = NULL;
     ofn->nMaxCustFilter = 0;
@@ -456,130 +519,71 @@ win32_export_specified_packets_file(HWND h_wnd) {
                  OFN_NOCHANGEDIR   | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
                  OFN_PATHMUSTEXIST | OFN_ENABLEHOOK      | OFN_SHOWHELP;
     ofn->lpstrDefExt = NULL;
+    ofn->lCustData = (LPARAM) cf;
     ofn->lpfnHook = export_specified_packets_file_hook_proc;
     ofn->lpTemplateName = _T("WIRESHARK_EXPORT_SPECIFIED_PACKETS_FILENAME_TEMPLATE");
 
-    if (GetSaveFileName(ofn)) {
-        filetype = g_array_index(savable_file_types, int, ofn->nFilterIndex - 1);
-
-        /*
-         * 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_last_dot = strrchr(file_name8->str,'.');
-        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;
-            if (file_last_dot != NULL) {
-                /* Skip past the dot. */
-                file_last_dot++;
-
-                /* OK, see if the file has one of those extensions. */
-                for (extension = extensions_list; extension != NULL;
-                     extension = g_slist_next(extension)) {
-                    if (g_ascii_strcasecmp((char *)extension->data, file_last_dot) == 0) {
-                        /* 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;
-        }
-        if (add_extension) {
-            if (wtap_default_file_extension(filetype) != NULL) {
-                g_string_append_printf(file_name8, ".%s", wtap_default_file_extension(filetype));
-            }
-        }
-
-        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 the specified packets to the file with the specified
-         * name.
-         *
-         * XXX: if the cf_export_specified_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 (cf_export_specified_packets(&cfile, file_name8->str, &g_range, filetype, FALSE) != CF_OK) {
-            /* The write failed.  Try again. */
-            g_array_free(savable_file_types, TRUE);
-            g_string_free(file_name8, TRUE /* free_segment */);
-            g_free( (void *) ofn->lpstrFilter);
-            g_free( (void *) ofn);
-            win32_export_specified_packets_file(h_wnd);
-            return;
+    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.
+             */
+            g_string_truncate(file_name, 0);
+            gsfn_ok = TRUE;
         }
-
-        /* Save the directory name for future file dialogs. */
-        dirname = get_dirname(file_name8->str);  /* Overwrites cf_name */
-        set_last_open_dir(dirname);
-
-        g_string_free(file_name8, TRUE /* free_segment */);
     }
+
     g_sf_hwnd = NULL;
+    g_range = NULL;
+    g_cf = NULL;
     g_array_free(savable_file_types, TRUE);
     g_free( (void *) ofn->lpstrFilter);
     g_free( (void *) ofn);
+    return gsfn_ok;
 }
 
 
-void
-win32_merge_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[MAX_PATH] = _T("");
-    char       *dirname;
-    cf_status_t merge_status = CF_ERROR;
-    char       *in_filenames[2];
-    int         err;
-    char       *tmpname;
-    dfilter_t  *dfp;
-    int         ofnsize;
-#if (_MSC_VER >= 1500)
-    OSVERSIONINFO osvi;
-#endif
+    TCHAR         file_name16[MAX_PATH] = _T("");
+    int           ofnsize;
+    gboolean gofn_ok;
 
-    /* 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;
+    if (!file_name || !display_filter || !merge_type)
+        return FALSE;
+
+    if (file_name->len > 0) {
+        StringCchCopy(file_name16, MAX_PATH, utf_8to16(file_name->str));
     }
-#else
-    ofnsize = sizeof(OPENFILENAME) + 12;
-#endif
+
+    if (display_filter->len > 0) {
+        g_dfilter_str = g_strdup(display_filter->str);
+    } else if (g_dfilter_str) {
+        g_free(g_dfilter_str);
+        g_dfilter_str = NULL;
+    }
+
+    ofnsize = win32_get_ofnsize();
     ofn = g_malloc0(ofnsize);
 
     ofn->lStructSize = ofnsize;
     ofn->hwndOwner = h_wnd;
-#if (_MSC_VER <= 1200)
-    ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
-#else
     ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
-#endif
     ofn->lpstrFilter = build_file_open_type_list();
     ofn->lpstrCustomFilter = NULL;
     ofn->nMaxCustFilter = 0;
     ofn->nFilterIndex = FILE_MERGE_DEFAULT;
-    ofn->lpstrFile = file_name;
+    ofn->lpstrFile = file_name16;
     ofn->nMaxFile = MAX_PATH;
     ofn->lpstrFileTitle = NULL;
     ofn->nMaxFileTitle = 0;
@@ -596,108 +600,50 @@ win32_merge_file (HWND h_wnd) {
     ofn->lpfnHook = merge_file_hook_proc;
     ofn->lpTemplateName = _T("WIRESHARK_MERGEFILENAME_TEMPLATE");
 
-    if (GetOpenFileName(ofn)) {
-        filetype = cfile.cd_t;
-        g_free( (void *) ofn->lpstrFilter);
-        g_free( (void *) ofn);
+    gofn_ok = GetOpenFileName(ofn);
 
-        /* merge or append the two files */
+    if (gofn_ok) {
+        g_string_printf(file_name, "%s", utf_16to8(file_name16));
+        g_string_printf(display_filter, "%s", g_dfilter_str ? g_dfilter_str : "");
 
-        tmpname = NULL;
-        switch (merge_action) {
+        switch (g_merge_action) {
             case merge_append:
-                /* append file */
-                in_filenames[0] = cfile.filename;
-                in_filenames[1] = utf_16to8(file_name);
-                merge_status = cf_merge_files(&tmpname, 2, in_filenames, filetype, TRUE);
+                *merge_type = 1;
                 break;
             case merge_chrono:
-                /* chonological order */
-                in_filenames[0] = cfile.filename;
-                in_filenames[1] = utf_16to8(file_name);
-                merge_status = cf_merge_files(&tmpname, 2, in_filenames, filetype, FALSE);
+                *merge_type = 0;
                 break;
             case merge_prepend:
-                /* prepend file */
-                in_filenames[0] = utf_16to8(file_name);
-                in_filenames[1] = cfile.filename;
-                merge_status = cf_merge_files(&tmpname, 2, in_filenames, filetype, TRUE);
+                *merge_type = -1;
                 break;
             default:
                 g_assert_not_reached();
         }
-
-        if(merge_status != CF_OK) {
-            /* merge failed */
-            g_free(tmpname);
-            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. */
-            return;
-        }
-
-        /* apply our filter */
-        if (dfilter_compile(dfilter_str, &dfp)) {
-            cf_set_rfcode(&cfile, dfp);
-        }
-
-        switch (cf_read(&cfile, FALSE)) {
-            case CF_READ_OK:
-            case CF_READ_ERROR:
-                dirname = get_dirname(utf_16to8(file_name));
-                set_last_open_dir(dirname);
-                menu_name_resolution_changed();
-                break;
-            case CF_READ_ABORTED:
-                break;
-        }
-    } else {
-        g_free( (void *) ofn->lpstrFilter);
-        g_free( (void *) ofn);
     }
+
+    g_free( (void *) ofn->lpstrFilter);
+    g_free( (void *) ofn);
+    g_free(g_dfilter_str);
+    g_dfilter_str = NULL;
+    return gofn_ok;
 }
 
 void
-win32_export_file(HWND h_wnd, export_type_e export_type) {
+win32_export_file(HWND h_wnd, capture_file *cf, export_type_e export_type) {
     OPENFILENAME     *ofn;
     TCHAR             file_name[MAX_PATH] = _T("");
     char             *dirname;
     cf_print_status_t status;
     int               ofnsize;
-#if (_MSC_VER >= 1500)
-    OSVERSIONINFO osvi;
-#endif
 
-    /* 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;
-    }
-#else
-    ofnsize = sizeof(OPENFILENAME) + 12;
-#endif
+    g_cf = cf;
+
+    ofnsize = win32_get_ofnsize();
     ofn = g_malloc0(ofnsize);
 
     ofn->lStructSize = ofnsize;
     ofn->hwndOwner = h_wnd;
-#if (_MSC_VER <= 1200)
-    ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
-#else
     ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
-#endif
     ofn->lpstrFilter = FILE_TYPES_EXPORT;
     ofn->lpstrCustomFilter = NULL;
     ofn->nMaxCustFilter = 0;
@@ -712,6 +658,7 @@ win32_export_file(HWND h_wnd, export_type_e export_type) {
                  OFN_NOCHANGEDIR   | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
                  OFN_PATHMUSTEXIST | OFN_ENABLEHOOK      | OFN_SHOWHELP;
     ofn->lpstrDefExt = NULL;
+    ofn->lCustData = (LPARAM) cf;
     ofn->lpfnHook = export_file_hook_proc;
     ofn->lpTemplateName = _T("WIRESHARK_EXPORTFILENAME_TEMPLATE");
 
@@ -721,9 +668,11 @@ win32_export_file(HWND h_wnd, export_type_e export_type) {
     print_args.to_file             = TRUE;
     print_args.cmd                 = NULL;
     print_args.print_summary       = TRUE;
+    print_args.print_col_headings  = TRUE;
     print_args.print_dissections   = print_dissections_as_displayed;
     print_args.print_hex           = FALSE;
     print_args.print_formfeed      = FALSE;
+    print_args.stream              = NULL;
 
     if (GetSaveFileName(ofn)) {
         print_args.file = utf_16to8(file_name);
@@ -735,7 +684,7 @@ win32_export_file(HWND h_wnd, export_type_e export_type) {
                     g_free( (void *) ofn);
                     return;
                 }
-                status = cf_print_packets(&cfile, &print_args);
+                status = cf_print_packets(cf, &print_args, TRUE);
                 break;
             case export_type_ps:        /* PostScript (r) */
                 print_args.stream = print_stream_ps_new(TRUE, print_args.file);
@@ -744,19 +693,22 @@ win32_export_file(HWND h_wnd, export_type_e export_type) {
                     g_free( (void *) ofn);
                     return;
                 }
-                status = cf_print_packets(&cfile, &print_args);
+                status = cf_print_packets(cf, &print_args, TRUE);
                 break;
             case export_type_csv:       /* CSV */
-                status = cf_write_csv_packets(&cfile, &print_args);
+                status = cf_write_csv_packets(cf, &print_args);
                 break;
             case export_type_carrays:   /* C Arrays */
-                status = cf_write_carrays_packets(&cfile, &print_args);
+                status = cf_write_carrays_packets(cf, &print_args);
                 break;
             case export_type_psml:      /* PSML */
-                status = cf_write_psml_packets(&cfile, &print_args);
+                status = cf_write_psml_packets(cf, &print_args);
                 break;
             case export_type_pdml:      /* PDML */
-                status = cf_write_pdml_packets(&cfile, &print_args);
+                status = cf_write_pdml_packets(cf, &print_args);
+                break;
+            case export_type_json:      /* JSON */
+                status = cf_write_json_packets(cf, &print_args);
                 break;
             default:
                 g_free( (void *) ofn);
@@ -778,11 +730,12 @@ win32_export_file(HWND h_wnd, export_type_e export_type) {
         set_last_open_dir(dirname);
     }
 
+    g_cf = NULL;
     g_free( (void *) ofn);
 }
 
 void
-win32_export_raw_file(HWND h_wnd) {
+win32_export_raw_file(HWND h_wnd, capture_file *cf) {
     OPENFILENAME *ofn;
     TCHAR         file_name[MAX_PATH] = _T("");
     char         *dirname;
@@ -790,38 +743,19 @@ win32_export_raw_file(HWND h_wnd) {
     char         *file_name8;
     int           fd;
     int           ofnsize;
-#if (_MSC_VER >= 1500)
-    OSVERSIONINFO osvi;
-#endif
 
-    if (!cfile.finfo_selected) {
+    if (!cf->finfo_selected) {
         /* This shouldn't happen */
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No bytes were selected.");
         return;
     }
 
-    /* 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;
-    }
-#else
-    ofnsize = sizeof(OPENFILENAME) + 12;
-#endif
+    ofnsize = win32_get_ofnsize();
     ofn = g_malloc0(ofnsize);
 
     ofn->lStructSize = ofnsize;
     ofn->hwndOwner = h_wnd;
-#if (_MSC_VER <= 1200)
-    ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
-#else
     ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
-#endif
     ofn->lpstrFilter = FILE_TYPES_RAW;
     ofn->lpstrCustomFilter = NULL;
     ofn->nMaxCustFilter = 0;
@@ -836,31 +770,31 @@ win32_export_raw_file(HWND h_wnd) {
                  OFN_NOCHANGEDIR   | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
                  OFN_PATHMUSTEXIST | OFN_ENABLEHOOK      | OFN_SHOWHELP;
     ofn->lpstrDefExt = NULL;
-    ofn->lCustData = cfile.finfo_selected->length;
+    ofn->lCustData = cf->finfo_selected->length;
     ofn->lpfnHook = export_raw_file_hook_proc;
     ofn->lpTemplateName = _T("WIRESHARK_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"?
+     * grab the info from cf->finfo_selected.  Which is more "correct"?
      */
 
     if (GetSaveFileName(ofn)) {
         g_free( (void *) ofn);
         file_name8 = utf_16to8(file_name);
-        data_p = tvb_get_ptr(cfile.finfo_selected->ds_tvb, 0, -1) +
-                cfile.finfo_selected->start;
+        data_p = tvb_get_ptr(cf->finfo_selected->ds_tvb, 0, -1) +
+                cf->finfo_selected->start;
         fd = ws_open(file_name8, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
         if (fd == -1) {
             open_failure_alert_box(file_name8, errno, TRUE);
             return;
         }
-        if (write(fd, data_p, cfile.finfo_selected->length) < 0) {
+        if (ws_write(fd, data_p, cf->finfo_selected->length) < 0) {
             write_failure_alert_box(file_name8, errno);
-            close(fd);
+            ws_close(fd);
             return;
         }
-        if (close(fd) < 0) {
+        if (ws_close(fd) < 0) {
             write_failure_alert_box(file_name8, errno);
             return;
         }
@@ -878,44 +812,25 @@ win32_export_sslkeys_file(HWND h_wnd) {
     OPENFILENAME *ofn;
     TCHAR         file_name[MAX_PATH] = _T("");
     char         *dirname;
-    StringInfo   *keylist;
+    gchar        *keylist = NULL;
     char         *file_name8;
     int           fd;
     int           ofnsize;
     int           keylist_size;
-#if (_MSC_VER >= 1500)
-    OSVERSIONINFO osvi;
-#endif
 
-    keylist_size = g_hash_table_size(ssl_session_hash);
+    keylist_size = ssl_session_key_count();
     if (keylist_size==0) {
         /* This shouldn't happen */
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No SSL Session Keys to export.");
         return;
     }
 
-    /* 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;
-    }
-#else
-    ofnsize = sizeof(OPENFILENAME) + 12;
-#endif
+    ofnsize = win32_get_ofnsize();
     ofn = g_malloc0(ofnsize);
 
     ofn->lStructSize = ofnsize;
     ofn->hwndOwner = h_wnd;
-#if (_MSC_VER <= 1200)
-    ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
-#else
     ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
-#endif
     ofn->lpstrFilter = FILE_TYPES_SSLKEYS;
     ofn->lpstrCustomFilter = NULL;
     ofn->nMaxCustFilter = 0;
@@ -937,7 +852,7 @@ win32_export_sslkeys_file(HWND h_wnd) {
     if (GetSaveFileName(ofn)) {
         g_free( (void *) ofn);
         file_name8 = utf_16to8(file_name);
-        keylist = ssl_export_sessions(ssl_session_hash);
+        keylist = ssl_export_sessions();
         fd = ws_open(file_name8, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
         if (fd == -1) {
             open_failure_alert_box(file_name8, errno, TRUE);
@@ -948,7 +863,7 @@ win32_export_sslkeys_file(HWND h_wnd) {
          * Thanks, Microsoft, for not using size_t for the third argument to
          * _write().  Presumably this string will be <= 4GiB long....
          */
-        if (ws_write(fd, keylist->data, (unsigned int)strlen(keylist->data)) < 0) {
+        if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) {
             write_failure_alert_box(file_name8, errno);
             ws_close(fd);
             g_free(keylist);
@@ -970,37 +885,19 @@ win32_export_sslkeys_file(HWND h_wnd) {
 }
 
 void
-win32_export_color_file(HWND h_wnd, gpointer filter_list) {
+win32_export_color_file(HWND h_wnd, capture_file *cf, gpointer filter_list) {
     OPENFILENAME *ofn;
     TCHAR  file_name[MAX_PATH] = _T("");
     gchar *dirname;
     int    ofnsize;
-#if (_MSC_VER >= 1500)
-    OSVERSIONINFO osvi;
-#endif
+    gchar *err_msg = NULL;
 
-    /* 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;
-    }
-#else
-    ofnsize = sizeof(OPENFILENAME) + 12;
-#endif
+    ofnsize = win32_get_ofnsize();
     ofn = g_malloc0(ofnsize);
 
     ofn->lStructSize = ofnsize;
     ofn->hwndOwner = h_wnd;
-#if (_MSC_VER <= 1200)
-    ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
-#else
     ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
-#endif
     ofn->lpstrFilter = FILE_TYPES_COLOR;
     ofn->lpstrCustomFilter = NULL;
     ofn->nMaxCustFilter = 0;
@@ -1018,13 +915,17 @@ win32_export_color_file(HWND h_wnd, gpointer filter_list) {
     ofn->lpfnHook = NULL;
     ofn->lpTemplateName = NULL;
 
-    filetype = cfile.cd_t;
+    g_filetype = cf->cd_t;
 
     /* XXX - Support marked filters */
     if (GetSaveFileName(ofn)) {
         g_free( (void *) ofn);
-        if (!color_filters_export(utf_16to8(file_name), filter_list, FALSE /* all filters */))
+        if (!color_filters_export(utf_16to8(file_name), filter_list, FALSE /* all filters */, &err_msg))
+        {
+            simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
+            g_free(err_msg);
             return;
+        }
 
         /* Save the directory name for future file dialogs. */
         dirname = get_dirname(utf_16to8(file_name));  /* Overwrites cf_name */
@@ -1040,32 +941,14 @@ win32_import_color_file(HWND h_wnd, gpointer color_filters) {
     TCHAR  file_name[MAX_PATH] = _T("");
     gchar *dirname;
     int    ofnsize;
-#if (_MSC_VER >= 1500)
-    OSVERSIONINFO osvi;
-#endif
+    gchar *err_msg = NULL;
 
-    /* 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;
-    }
-#else
-    ofnsize = sizeof(OPENFILENAME) + 12;
-#endif
+    ofnsize = win32_get_ofnsize();
     ofn = g_malloc0(ofnsize);
 
     ofn->lStructSize = ofnsize;
     ofn->hwndOwner = h_wnd;
-#if (_MSC_VER <= 1200)
-    ofn->hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE);
-#else
     ofn->hInstance = (HINSTANCE) GetWindowLongPtr(h_wnd, GWLP_HINSTANCE);
-#endif
     ofn->lpstrFilter = FILE_TYPES_COLOR;
     ofn->lpstrCustomFilter = NULL;
     ofn->nMaxCustFilter = 0;
@@ -1086,8 +969,11 @@ win32_import_color_file(HWND h_wnd, gpointer color_filters) {
     /* XXX - Support export limited to selected filters */
     if (GetOpenFileName(ofn)) {
         g_free( (void *) ofn);
-        if (!color_filters_import(utf_16to8(file_name), color_filters))
+        if (!color_filters_import(utf_16to8(file_name), color_filters, &err_msg, color_filter_add_cb)) {
+            simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
+            g_free(err_msg);
             return;
+        }
 
         /* Save the directory name for future file dialogs. */
         dirname = get_dirname(utf_16to8(file_name));  /* Overwrites cf_name */
@@ -1113,10 +999,20 @@ 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)
+    if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
         args->print_summary = TRUE;
-    else
+        cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_COL_HEADINGS_CB);
+        EnableWindow(cur_ctrl, TRUE);
+        if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+            args->print_col_headings = TRUE;
+        else
+            args->print_col_headings = FALSE;
+    } else {
         args->print_summary = FALSE;
+        args->print_col_headings = FALSE;
+        cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_COL_HEADINGS_CB);
+        EnableWindow(cur_ctrl, FALSE);
+    }
 
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_CB);
     if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
@@ -1158,9 +1054,11 @@ static void
 format_handle_wm_initdialog(HWND dlg_hwnd, print_args_t *args) {
     HWND cur_ctrl;
 
-    /* Set the "Packet summary" box */
+    /* Set the "Packet summary" and "Include column headings" boxes */
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_SUMMARY_CB);
     SendMessage(cur_ctrl, BM_SETCHECK, args->print_summary, 0);
+    cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_COL_HEADINGS_CB);
+    SendMessage(cur_ctrl, BM_SETCHECK, args->print_col_headings, 0);
 
     /* Set the "Packet details" box */
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_CB);
@@ -1203,18 +1101,19 @@ format_handle_wm_initdialog(HWND dlg_hwnd, print_args_t *args) {
 /* 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) {
+preview_set_file_info(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;
     TCHAR       string_buff[PREVIEW_STR_MAX];
+    TCHAR       first_buff[PREVIEW_STR_MAX];
     gint64      data_offset;
     guint       packet = 0;
     gint64      filesize;
+    gchar      *size_str;
     time_t      ti_time;
     struct tm  *ti_tm;
     guint       elapsed_time;
@@ -1225,126 +1124,136 @@ preview_set_filename(HWND of_hwnd, gchar *preview_file) {
     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++) {
+    for (i = EWFD_PTX_FORMAT; i <= EWFD_PTX_START_ELAPSED; i++) {
         cur_ctrl = GetDlgItem(of_hwnd, i);
         if (cur_ctrl) {
-            EnableWindow(cur_ctrl, enable);
+            EnableWindow(cur_ctrl, FALSE);
         }
     }
 
-    for (i = EWFD_PTX_FILENAME; i <= EWFD_PTX_ELAPSED; i++) {
+    for (i = EWFD_PTX_FORMAT; i <= EWFD_PTX_START_ELAPSED; i++) {
         cur_ctrl = GetDlgItem(of_hwnd, i);
         if (cur_ctrl) {
             SetWindowText(cur_ctrl, _T("-"));
         }
     }
 
-    if (enable) {
-        cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FILENAME);
-        SetWindowText(cur_ctrl, utf_8to16(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, _T("unknown file format"));
-            } else {
-                SetWindowText(cur_ctrl, _T("error opening file"));
-            }
-            return FALSE;
-        }
+    if (preview_file == NULL || strlen(preview_file) < 1) {
+        return FALSE;
+    }
 
-        /* size */
-        filesize = wtap_file_size(wth, &err);
-        utf_8to16_snprintf(string_buff, PREVIEW_STR_MAX, "%" G_GINT64_FORMAT " bytes", filesize);
-        cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_SIZE);
-        SetWindowText(cur_ctrl, string_buff);
+    /* Format: directory */
+    cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FORMAT);
+    if (test_for_directory(preview_file) == EISDIR) {
+        SetWindowText(cur_ctrl, _T("directory"));
+        return FALSE;
+    }
 
-        /* type */
-        cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FORMAT);
-        SetWindowText(cur_ctrl, utf_8to16(wtap_file_type_string(wtap_file_type(wth))));
-
-        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 == 0) {
-                time(&time_current);
-                if(time_current-time_preview >= (time_t) prefs.gui_fileopen_preview) {
-                    is_breaked = TRUE;
-                    break;
-                }
-            }
+    wth = wtap_open_offline(preview_file, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
+    if (cur_ctrl && wth == NULL) {
+        if(err == WTAP_ERR_FILE_UNKNOWN_FORMAT) {
+            SetWindowText(cur_ctrl, _T("unknown file format"));
+        } else {
+            SetWindowText(cur_ctrl, _T("error opening file"));
         }
+        return FALSE;
+    }
 
-        if(err != 0) {
-            _snwprintf(string_buff, PREVIEW_STR_MAX, _T("error after reading %u packets"), packet);
-            cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_PACKETS);
-            SetWindowText(cur_ctrl, string_buff);
-            wtap_close(wth);
-            return TRUE;
+    /* Success! */
+    for (i = EWFD_PT_FORMAT; i <= EWFD_PTX_START_ELAPSED; i++) {
+        cur_ctrl = GetDlgItem(of_hwnd, i);
+        if (cur_ctrl) {
+            EnableWindow(cur_ctrl, TRUE);
         }
+    }
 
-        /* packet count */
-        if(is_breaked) {
-            _snwprintf(string_buff, PREVIEW_STR_MAX, _T("more than %u packets (preview timeout)"), packet);
-        } else {
-            _snwprintf(string_buff, PREVIEW_STR_MAX, _T("%u"), packet);
+    /* Format */
+    cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FORMAT);
+    SetWindowText(cur_ctrl, utf_8to16(wtap_file_type_subtype_string(wtap_file_type_subtype(wth))));
+
+    /* Size */
+    filesize = wtap_file_size(wth, &err);
+    // Windows Explorer uses IEC.
+    size_str = format_size(filesize, format_size_unit_bytes|format_size_prefix_iec);
+
+    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;
         }
-        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 );
-        if(ti_tm) {
-            _snwprintf(string_buff, PREVIEW_STR_MAX,
-                     _T("%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);
-        } else {
-            _snwprintf(string_buff, PREVIEW_STR_MAX, _T("?"));
+        if (cur_time < start_time) {
+            start_time = cur_time;
         }
-        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) {
-            _snwprintf(string_buff, PREVIEW_STR_MAX, _T("%02u days %02u:%02u:%02u"),
-            elapsed_time/86400, elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
-        } else {
-            _snwprintf(string_buff, PREVIEW_STR_MAX, _T("%02u:%02u:%02u"),
-            elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
+        if (cur_time > stop_time){
+            stop_time = cur_time;
         }
-        if(is_breaked) {
-            _snwprintf(string_buff, PREVIEW_STR_MAX, _T("unknown"));
+        packet++;
+        if(packet%100 == 0) {
+            time(&time_current);
+            if(time_current-time_preview >= (time_t) prefs.gui_fileopen_preview) {
+                is_breaked = TRUE;
+                break;
+            }
         }
-        cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_ELAPSED);
-        SetWindowText(cur_ctrl, string_buff);
+    }
 
+    if(err != 0) {
+        utf_8to16_snprintf(string_buff, PREVIEW_STR_MAX, "%s, error after %u packets",
+            size_str, packet);
+        g_free(size_str);
+        cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_SIZE);
+        SetWindowText(cur_ctrl, string_buff);
         wtap_close(wth);
+        return TRUE;
     }
 
+    /* Packets */
+    if(is_breaked) {
+        utf_8to16_snprintf(string_buff, PREVIEW_STR_MAX, "%s, timed out at %u packets",
+            size_str, packet);
+    } else {
+        utf_8to16_snprintf(string_buff, PREVIEW_STR_MAX, "%s, %u packets",
+            size_str, packet);
+    }
+    g_free(size_str);
+    cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_SIZE);
+    SetWindowText(cur_ctrl, string_buff);
+
+    /* First packet / elapsed time */
+    ti_time = (long)start_time;
+    ti_tm = localtime( &ti_time );
+    if(ti_tm) {
+        StringCchPrintf(first_buff, PREVIEW_STR_MAX,
+                 _T("%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);
+    } else {
+        StringCchPrintf(first_buff, PREVIEW_STR_MAX, _T("?"));
+    }
+
+    elapsed_time = (unsigned int)(stop_time-start_time);
+    if(elapsed_time/86400) {
+        StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("%s / %02u days %02u:%02u:%02u"),
+        first_buff, elapsed_time/86400, elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
+    } else {
+        StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("%s / %02u:%02u:%02u"),
+        first_buff, elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60);
+    }
+    if(is_breaked) {
+        StringCchPrintf(string_buff, PREVIEW_STR_MAX, _T("%s / unknown"), first_buff);
+    }
+    cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_START_ELAPSED);
+    SetWindowText(cur_ctrl, string_buff);
+
+    wtap_close(wth);
+
     return TRUE;
 
 }
@@ -1401,78 +1310,64 @@ filter_tb_syntax_check(HWND hwnd, TCHAR *filter_text) {
         /* Default window background */
         SendMessage(hwnd, EM_SETBKGNDCOLOR, (WPARAM) 1, COLOR_WINDOW);
         return;
-    } else if (dfilter_compile(utf_16to8(strval), &dfp)) { /* colorize filter string entry */
-        if (dfp != NULL)
-            dfilter_free(dfp);
+    } else if (dfilter_compile(utf_16to8(strval), &dfp, NULL)) { /* colorize filter string entry */
+        dfilter_free(dfp);
         /* Valid (light green) */
-        SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, 0x00afffaf);
+        SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, RGB(0xe4, 0xff, 0xc7)); /* tango_chameleon_1 */
     } else {
         /* Invalid (light red) */
-        SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, 0x00afafff);
+        SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, RGB(0xff, 0xcc, 0xcc)); /* tango_scarlet_red_1 */
     }
 
-    if (strval) g_free(strval);
+    g_free(strval);
 }
 
 
-#if (_MSC_VER <= 1200)
-static UINT CALLBACK
-#else
 static UINT_PTR CALLBACK
-#endif
 open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
     HWND      cur_ctrl, parent;
     OFNOTIFY *notify = (OFNOTIFY *) l_param;
     TCHAR     sel_name[MAX_PATH];
+    gint      i;
 
     switch(msg) {
         case WM_INITDIALOG:
             /* Retain the filter text, and fill it in. */
-            if(dfilter_str != NULL) {
+            if(g_dfilter_str != NULL) {
                 cur_ctrl = GetDlgItem(of_hwnd, EWFD_FILTER_EDIT);
-                SetWindowText(cur_ctrl, utf_8to16(dfilter_str));
+                SetWindowText(cur_ctrl, utf_8to16(g_dfilter_str));
             }
 
-            /* Fill in our resolution values */
-            cur_ctrl = GetDlgItem(of_hwnd, EWFD_MAC_NR_CB);
-            SendMessage(cur_ctrl, BM_SETCHECK, gbl_resolv_flags & RESOLV_MAC, 0);
-            cur_ctrl = GetDlgItem(of_hwnd, EWFD_NET_NR_CB);
-            SendMessage(cur_ctrl, BM_SETCHECK, gbl_resolv_flags & RESOLV_NETWORK, 0);
-            cur_ctrl = GetDlgItem(of_hwnd, EWFD_TRANS_NR_CB);
-            SendMessage(cur_ctrl, BM_SETCHECK, gbl_resolv_flags & RESOLV_TRANSPORT, 0);
+            cur_ctrl = GetDlgItem(of_hwnd, EWFD_FORMAT_TYPE);
+            SendMessage(cur_ctrl, CB_ADDSTRING, 0, (WPARAM) _T("Automatically detect file type"));
+            for (i = 0; open_routines[i].name != NULL; i += 1) {
+                SendMessage(cur_ctrl, CB_ADDSTRING, 0, (WPARAM) utf_8to16(open_routines[i].name));
+            }
+            SendMessage(cur_ctrl, CB_SETCURSEL, 0, 0);
 
-            preview_set_filename(of_hwnd, NULL);
+            preview_set_file_info(of_hwnd, NULL);
             break;
         case WM_NOTIFY:
             switch (notify->hdr.code) {
                 case CDN_FILEOK:
                     /* Fetch the read filter */
                     cur_ctrl = GetDlgItem(of_hwnd, EWFD_FILTER_EDIT);
-                    if (dfilter_str)
-                        g_free(dfilter_str);
-                    dfilter_str = filter_tb_get(cur_ctrl);
+                    g_free(g_dfilter_str);
+                    g_dfilter_str = filter_tb_get(cur_ctrl);
+
+                    cur_ctrl = GetDlgItem(of_hwnd, EWFD_FORMAT_TYPE);
+                    g_format_type = (unsigned int) SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0);
 
-                    /* Fetch our resolution values */
-                    gbl_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)
-                        gbl_resolv_flags |= RESOLV_MAC;
-                    cur_ctrl = GetDlgItem(of_hwnd, EWFD_NET_NR_CB);
-                    if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
-                        gbl_resolv_flags |= RESOLV_NETWORK;
-                    cur_ctrl = GetDlgItem(of_hwnd, EWFD_TRANS_NR_CB);
-                    if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
-                        gbl_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, utf_16to8(sel_name));
+                    CommDlg_OpenSave_GetFilePath(parent, sel_name, MAX_PATH);
+                    preview_set_file_info(of_hwnd, utf_16to8(sel_name));
                     break;
                 case CDN_HELP:
-                    topic_cb(NULL, HELP_OPEN_WIN32_DIALOG);
+                    topic_action(HELP_OPEN_WIN32_DIALOG);
                     break;
                 default:
                     break;
@@ -1503,22 +1398,122 @@ open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
     return 0;
 }
 
-/* XXX - Copied verbatim from ui/gtk/capture_file_dlg.c.  Perhaps it
- * should be in wiretap instead?
- */
-
-static gboolean
-can_save_with_wiretap(int ft)
+/* Generate a list of the file types we can filter for in the open dialog. */
+static void
+append_file_extension_type(GArray *sa, int et)
 {
-    /* 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);
+    GString* pattern_str = g_string_new("");
+    GString* description_str = g_string_new("");
+    gchar sep;
+    GSList *extensions_list, *extension;
+    const TCHAR *str16;
+    guint16 zero = 0;
+
+    /* Construct the list of patterns. */
+    extensions_list = wtap_get_file_extension_type_extensions(et);
+    g_string_printf(pattern_str, "");
+    sep = '\0';
+    for (extension = extensions_list; extension != NULL;
+         extension = g_slist_next(extension)) {
+        if (sep != '\0')
+            g_string_append_c(pattern_str, sep);
+        g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
+        sep = ';';
+    }
+    wtap_free_extensions_list(extensions_list);
+
+    /* Construct the description. */
+    g_string_printf(description_str, "%s (%s)",
+                    wtap_get_file_extension_type_name(et),
+                    pattern_str->str);
+    str16 = utf_8to16(description_str->str);
+    sa = g_array_append_vals(sa, str16, (guint) strlen(description_str->str));
+    sa = g_array_append_val(sa, zero);
+    g_string_free(description_str, TRUE);
+
+    str16 = utf_8to16(pattern_str->str);
+    sa = g_array_append_vals(sa, str16, (guint) strlen(pattern_str->str));
+    sa = g_array_append_val(sa, zero);
+    g_string_free(pattern_str, TRUE);
+}
+
+static TCHAR *
+build_file_open_type_list(void) {
+    const TCHAR *str16;
+    int et;
+    GArray* sa;
+    static const guint16 zero = 0;
+    GString* pattern_str;
+    gchar sep;
+    GSList *extensions_list, *extension;
+
+    /*
+     * Microsoft's UI guidelines say, of the file filters in open and
+     * save dialogs:
+     *
+     *    For meta-filters, remove the file extension list to eliminate
+     *    clutter. Examples: "All files," "All pictures," "All music,"
+     *    and "All videos."
+     *
+     * so we omit them (for "All Capture Files", the filter would be
+     * *really* long).  On both Windows XP and Windows 7, Wordpad doesn't
+     * do that, but Paint does.
+     */
+
+    /*
+     * Array of hexadectets used as a sequence of null-terminated
+     * UTF-16 strings.
+     */
+    sa = g_array_new(FALSE /*zero_terminated*/, FALSE /*clear_*/,2 /*element_size*/);
+
+    /* Add the "All Files" entry. */
+    str16 = utf_8to16("All Files");
+    sa = g_array_append_vals(sa, str16, (guint) strlen("All Files"));
+    sa = g_array_append_val(sa, zero);
+    str16 = utf_8to16(ALL_FILES_WILDCARD);
+    sa = g_array_append_vals(sa, str16, (guint) strlen(ALL_FILES_WILDCARD));
+    sa = g_array_append_val(sa, zero);
+
+    /*
+     * Add an "All Capture Files" entry, with all the capture file
+     * extensions we know about.
+     */
+    str16 = utf_8to16("All Capture Files");
+    sa = g_array_append_vals(sa, str16, (guint) strlen("All Capture Files"));
+    sa = g_array_append_val(sa, zero);
+
+    /*
+     * Construct its list of patterns.
+     */
+    pattern_str = g_string_new("");
+    extensions_list = wtap_get_all_capture_file_extensions_list();
+    sep = '\0';
+    for (extension = extensions_list; extension != NULL;
+         extension = g_slist_next(extension)) {
+        if (sep != '\0')
+            g_string_append_c(pattern_str, sep);
+        g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
+        sep = ';';
+    }
+    wtap_free_extensions_list(extensions_list);
+    str16 = utf_8to16(pattern_str->str);
+    sa = g_array_append_vals(sa, str16, (guint) strlen(pattern_str->str));
+    sa = g_array_append_val(sa, zero);
+
+    /* Include all the file type extensions Wireshark supports. */
+    for (et = 0; et < wtap_get_num_file_type_extensions(); et++) {
+        append_file_extension_type(sa, et);
+    }
+
+    /* terminate the array */
+    sa = g_array_append_val(sa, zero);
+
+    return (TCHAR *) g_array_free(sa, FALSE /*free_segment*/);
 }
 
 /* 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").
@@ -1537,19 +1532,17 @@ append_file_type(GArray *sa, int ft)
     GString* description_str = g_string_new("");
     gchar sep;
     GSList *extensions_list, *extension;
-    TCHAR *str16;
+    const TCHAR *str16;
     guint16 zero = 0;
 
     extensions_list = wtap_get_file_extensions_list(ft, TRUE);
     if (extensions_list == NULL) {
         /* This file type doesn't have any particular extension
-           conventionally used for it, so we'll just use "*.*"
-           as the pattern; on Windows, that matches all file names
-           - even those with no extension -  so we don't need to
-           worry about compressed file extensions.  (It does not
-           do so on UN*X; the right pattern on UN*X would just
-           be "*".) */
-           g_string_printf(pattern_str, "*.*");
+           conventionally used for it, so we'll just use a
+           wildcard that matches all file names - even those with
+           no extension, so we don't need to worry about compressed
+           file extensions. */
+           g_string_printf(pattern_str, ALL_FILES_WILDCARD);
     } else {
         /* Construct the list of patterns. */
         g_string_printf(pattern_str, "");
@@ -1561,50 +1554,21 @@ append_file_type(GArray *sa, int ft)
             g_string_append_printf(pattern_str, "*.%s", (char *)extension->data);
             sep = ';';
         }
-        wtap_free_file_extensions_list(extensions_list);
+        wtap_free_extensions_list(extensions_list);
     }
 
     /* Construct the description. */
-    g_string_printf(description_str, "%s (%s)", wtap_file_type_string(ft),
+    g_string_printf(description_str, "%s (%s)", wtap_file_type_subtype_string(ft),
                     pattern_str->str);
     str16 = utf_8to16(description_str->str);
     sa = g_array_append_vals(sa, str16, (guint) strlen(description_str->str));
     sa = g_array_append_val(sa, zero);
+    g_string_free(description_str, TRUE);
 
     str16 = utf_8to16(pattern_str->str);
     sa = g_array_append_vals(sa, str16, (guint) strlen(pattern_str->str));
     sa = g_array_append_val(sa, zero);
-
-}
-
-static TCHAR *
-build_file_open_type_list(void) {
-    TCHAR *str16;
-    int   ft;
-    GArray* sa = g_array_new(FALSE /*zero_terminated*/, FALSE /*clear_*/,2 /*element_size*/);
-    guint16 zero = 0;
-
-
-    /* Add the "All Files" entry. */
-    str16 = utf_8to16("All Files (*.*)");
-    sa = g_array_append_vals(sa, str16, (guint) strlen("All Files (*.*)"));
-    sa = g_array_append_val(sa, zero);
-    str16 = utf_8to16("*.*");
-    sa = g_array_append_vals(sa, str16, (guint) strlen("*.*"));
-    sa = g_array_append_val(sa, zero);
-
-    /* Include all the file types Wireshark supports. */
-    for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
-        if (ft == WTAP_FILE_UNKNOWN)
-            continue;  /* not a real file type */
-
-        append_file_type(sa, ft);
-    }
-
-    /* terminate the array */
-    sa = g_array_append_val(sa, zero);
-
-    return (TCHAR *) g_array_free(sa, FALSE /*free_segment*/);
+    g_string_free(pattern_str, TRUE);
 }
 
 static TCHAR *
@@ -1632,7 +1596,7 @@ static void
 build_file_format_list(HWND sf_hwnd) {
     HWND  format_cb;
     int   ft;
-    guint index;
+    guint file_index;
     guint item_to_select;
     gchar *s;
 
@@ -1644,14 +1608,14 @@ build_file_format_list(HWND sf_hwnd) {
     SendMessage(format_cb, CB_RESETCONTENT, 0, 0);
 
     /* Check all file types. */
-    index = 0;
+    file_index = 0;
     for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
         if (ft == WTAP_FILE_UNKNOWN)
             continue;  /* not a real file type */
 
-        if (!packet_range_process_all(&g_range) || ft != cfile.cd_t) {
+        if (!packet_range_process_all(g_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))
+            if (!wtap_can_save_with_wiretap(ft, cfile.linktypes))
                 continue;       /* We can't. */
         }
 
@@ -1659,55 +1623,57 @@ build_file_format_list(HWND sf_hwnd) {
         if(wtap_file_extensions_string(ft) != NULL) {
             s = g_strdup_printf("%s (%s)", wtap_file_type_string(ft), wtap_file_extensions_string(ft));
         } else {
-            s = g_strdup_printf("%s (*.*)", wtap_file_type_string(ft));
+            s = g_strdup_printf("%s (" ALL_FILES_WILDCARD ")", wtap_file_type_string(ft));
         }
         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) {
+        SendMessage(format_cb, CB_SETITEMDATA, (LPARAM) file_index, (WPARAM) ft);
+        if (ft == g_filetype) {
             /* Default to the same format as the file, if it's supported. */
-            item_to_select = index;
+            item_to_select = file_index;
         }
-        index++;
+        file_index++;
     }
 
     SendMessage(format_cb, CB_SETCURSEL, (WPARAM) item_to_select, 0);
 }
 #endif
 
-#if (_MSC_VER <= 1200)
-static UINT CALLBACK
-#else
 static UINT_PTR CALLBACK
-#endif
 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;*/
+    /*int            new_filetype, file_index;*/
 
     switch(msg) {
-        case WM_INITDIALOG:
+        case WM_INITDIALOG: {
+            OPENFILENAME *ofnp = (OPENFILENAME *) l_param;
+            capture_file *cf = (capture_file *) ofnp->lCustData;
             g_sf_hwnd = sf_hwnd;
 
             /* Default to saving in the file's current format. */
-            filetype = cfile.cd_t;
+            g_filetype = cf->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, g_compressed, 0);
 
             break;
+        }
         case WM_COMMAND:
             cur_ctrl = (HWND) l_param;
 
             switch (w_param) {
 #if 0
                 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);
+                    file_index = SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0);
+                    if (file_index != CB_ERR) {
+                        new_filetype = SendMessage(cur_ctrl, CB_GETITEMDATA, (WPARAM) file_index, 0);
                         if (new_filetype != CB_ERR) {
-                            if (filetype != new_filetype) {
-                                if (can_save_with_wiretap(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);
                                     cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
@@ -1719,7 +1685,16 @@ 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 {
+                                    g_compressed = FALSE;
+                                    DisableWindow(cur_ctrl);
+                                }
+                                SendMessage(cur_ctrl, BM_SETCHECK, g_compressed, 0);
+
                             }
                         }
                     }
@@ -1732,30 +1707,34 @@ save_as_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
         case WM_NOTIFY:
             switch (notify->hdr.code) {
                 case CDN_HELP:
-                    topic_cb(NULL, HELP_SAVE_WIN32_DIALOG);
+                    topic_action(HELP_SAVE_WIN32_DIALOG);
                     break;
                 case CDN_FILEOK: {
                     HWND   parent;
-                    TCHAR  file_name16_selected[MAX_PATH];
-                    char  *file_name8_selected;
-                    int    selected_size;
+                    char  *file_name8;
+                    OPENFILENAME *ofnp = (OPENFILENAME *) notify->lpOFN;
+                    capture_file *cf = (capture_file *) ofnp->lCustData;
+
+                    /* Fetch our compression value */
+                    cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
+                    if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        g_compressed = TRUE;
+                    else
+                        g_compressed = FALSE;
 
-                    /* Check if trying to do 'save as' to the currently open file */
+                    /* Check if we're trying to overwrite the currently open file */
                     parent = GetParent(sf_hwnd);
-                    selected_size = CommDlg_OpenSave_GetSpec(parent, file_name16_selected, MAX_PATH);
-                    if (selected_size > 0) {
-                        file_name8_selected = utf_16to8(file_name16_selected);
-                        if (files_identical(cfile.filename, file_name8_selected)) {
-                            /* XXX: Is MessageBox the best way to pop up an error ? How to make text bold ? */
-                            gchar *str = g_strdup_printf(
-                                "Capture File \"%s\" identical to loaded file !!\n\n"
-                                "Please choose a different filename.",
-                                file_name8_selected);
-                            MessageBox( parent, utf_8to16(str), _T("Error"), MB_ICONERROR | MB_APPLMODAL | MB_OK);
-                            g_free(str);
-                            SetWindowLongPtr(sf_hwnd, DWLP_MSGRESULT, 1L); /* Don't allow ! */
-                            return 1;
-                        }
+                    file_name8 = utf_16to8(notify->lpOFN->lpstrFile);
+                    if (files_identical(cf->filename, file_name8)) {
+                        /* XXX: Is MessageBox the best way to pop up an error ? How to make text bold ? */
+                        gchar *str = g_strdup_printf(
+                            "Capture File \"%s\" identical to loaded file.\n\n"
+                            "Please choose a different filename.",
+                            file_name8);
+                        MessageBox( parent, utf_8to16(str), _T("Error"), MB_ICONERROR | MB_APPLMODAL | MB_OK);
+                        g_free(str);
+                        SetWindowLongPtr(sf_hwnd, DWLP_MSGRESULT, 1L); /* Don't allow ! */
+                        return 1;
                     }
                 }
                     break;
@@ -1769,48 +1748,63 @@ save_as_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
     return 0;
 }
 
+static UINT_PTR CALLBACK
+save_as_statstree_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
+
+    switch(msg) {
+        case WM_INITDIALOG:
+            g_sf_hwnd = sf_hwnd;
+            break;
+
+        case WM_COMMAND:
+            break;
+
+        case WM_NOTIFY:
+            break;
+
+        default:
+            break;
+    }
+    return 0;
+}
+
 #define RANGE_TEXT_MAX 128
-#if (_MSC_VER <= 1200)
-static UINT CALLBACK
-#else
 static UINT_PTR CALLBACK
-#endif
 export_specified_packets_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;*/
+    /*int            new_filetype, file_index;*/
 
     switch(msg) {
-        case WM_INITDIALOG:
+        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(&g_range);
-            /* default to displayed packets */
-            g_range.process_filtered   = TRUE;
-            g_range.include_dependents   = TRUE;
+            g_filetype = g_cf->cd_t;
 
             /* Fill in the file format list */
             /*build_file_format_list(sf_hwnd);*/
 
-            range_handle_wm_initdialog(sf_hwnd, &g_range);
+            range_handle_wm_initdialog(sf_hwnd, g_range);
+
+            /* Fill in the compression checkbox */
+            cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
+            SendMessage(cur_ctrl, BM_SETCHECK, g_compressed, 0);
 
             break;
+        }
         case WM_COMMAND:
             cur_ctrl = (HWND) l_param;
 
             switch (w_param) {
 #if 0
                 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);
+                    file_index = SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0);
+                    if (file_index != CB_ERR) {
+                        new_filetype = SendMessage(cur_ctrl, CB_GETITEMDATA, (WPARAM) file_index, 0);
                         if (new_filetype != CB_ERR) {
-                            if (filetype != new_filetype) {
-                                if (can_save_with_wiretap(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);
                                     cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN);
@@ -1822,44 +1816,48 @@ 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;
                             }
                         }
                     }
                     break;
 #endif
                 default:
-                    range_handle_wm_command(sf_hwnd, cur_ctrl, w_param, &g_range);
+                    range_handle_wm_command(sf_hwnd, cur_ctrl, w_param, g_range);
                     break;
             }
             break;
         case WM_NOTIFY:
             switch (notify->hdr.code) {
                 case CDN_HELP:
-                    topic_cb(NULL, HELP_SAVE_WIN32_DIALOG);
+                    topic_action(HELP_SAVE_WIN32_DIALOG);
                     break;
                 case CDN_FILEOK: {
                     HWND   parent;
-                    TCHAR  file_name16_selected[MAX_PATH];
-                    char  *file_name8_selected;
-                    int    selected_size;
+                    char  *file_name8;
+                    OPENFILENAME *ofnp = (OPENFILENAME *) notify->lpOFN;
+                    capture_file *cf = (capture_file *) ofnp->lCustData;
+
+                    /* Fetch our compression value */
+                    cur_ctrl = GetDlgItem(sf_hwnd, EWFD_GZIP_CB);
+                    if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        g_compressed = TRUE;
+                    else
+                        g_compressed = FALSE;
 
-                    /* Check if trying to do 'save as' to the currently open file */
+                    /* Check if we're trying to overwrite the currently open file */
                     parent = GetParent(sf_hwnd);
-                    selected_size = CommDlg_OpenSave_GetSpec(parent, file_name16_selected, MAX_PATH);
-                    if (selected_size > 0) {
-                        file_name8_selected = utf_16to8(file_name16_selected);
-                        if (files_identical(cfile.filename, file_name8_selected)) {
-                            /* XXX: Is MessageBox the best way to pop up an error ? How to make text bold ? */
-                            gchar *str = g_strdup_printf(
-                                "Capture File \"%s\" identical to loaded file !!\n\n"
-                                "Please choose a different filename.",
-                                file_name8_selected);
-                            MessageBox( parent, utf_8to16(str), _T("Error"), MB_ICONERROR | MB_APPLMODAL | MB_OK);
-                            g_free(str);
-                            SetWindowLongPtr(sf_hwnd, DWLP_MSGRESULT, 1L); /* Don't allow ! */
-                            return 1;
-                        }
+                    file_name8 = utf_16to8(notify->lpOFN->lpstrFile);
+                    if (files_identical(cf->filename, file_name8)) {
+                        /* XXX: Is MessageBox the best way to pop up an error ? How to make text bold ? */
+                        gchar *str = g_strdup_printf(
+                            "Capture File \"%s\" identical to loaded file.\n\n"
+                            "Please choose a different filename.",
+                            file_name8);
+                        MessageBox( parent, utf_8to16(str), _T("Error"), MB_ICONERROR | MB_APPLMODAL | MB_OK);
+                        g_free(str);
+                        SetWindowLongPtr(sf_hwnd, DWLP_MSGRESULT, 1L); /* Don't allow ! */
+                        return 1;
                     }
                 }
                     break;
@@ -1883,7 +1881,8 @@ range_update_dynamics(HWND dlg_hwnd, packet_range_t *range) {
     TCHAR    static_val[STATIC_LABEL_CHARS];
     gint     selected_num;
     guint32  ignored_cnt = 0, displayed_ignored_cnt = 0;
-    guint32       displayed_cnt;
+    guint32  displayed_cnt;
+    gboolean range_valid = TRUE;
 
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_DISPLAYED_BTN);
     if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
@@ -1893,9 +1892,9 @@ range_update_dynamics(HWND dlg_hwnd, packet_range_t *range) {
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_CAP);
     EnableWindow(cur_ctrl, !filtered_active);
     if (range->remove_ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), cfile.count - range->ignored_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), g_cf->count - range->ignored_cnt);
     } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), cfile.count);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), g_cf->count);
     }
     SetWindowText(cur_ctrl, static_val);
 
@@ -1906,51 +1905,51 @@ range_update_dynamics(HWND dlg_hwnd, packet_range_t *range) {
     else
       displayed_cnt = range->displayed_cnt;
     if (range->remove_ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), displayed_cnt - range->displayed_ignored_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), displayed_cnt - range->displayed_ignored_cnt);
     } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), displayed_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), displayed_cnt);
     }
     SetWindowText(cur_ctrl, static_val);
 
     /* RANGE_SELECT_CURR */
-    selected_num = (cfile.current_frame) ? cfile.current_frame->num : 0;
+    selected_num = (g_cf->current_frame) ? g_cf->current_frame->num : 0;
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_CAP);
     EnableWindow(cur_ctrl, selected_num && !filtered_active);
-    if (range->remove_ignored && cfile.current_frame && cfile.current_frame->flags.ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("0"));
+    if (range->remove_ignored && g_cf->current_frame && g_cf->current_frame->flags.ignored) {
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("0"));
     } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), selected_num ? 1 : 0);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%d"), 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);
-    if (range->remove_ignored && cfile.current_frame && cfile.current_frame->flags.ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("0"));
+    if (range->remove_ignored && g_cf->current_frame && g_cf->current_frame->flags.ignored) {
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("0"));
     } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), selected_num ? 1 : 0);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%d"), 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);
+    EnableWindow(cur_ctrl, g_cf->marked_count);
 
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_CAP);
-    EnableWindow(cur_ctrl, cfile.marked_count && !filtered_active);
+    EnableWindow(cur_ctrl, g_cf->marked_count && !filtered_active);
     if (range->remove_ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), cfile.marked_count - range->ignored_marked_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), g_cf->marked_count - range->ignored_marked_cnt);
     } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), cfile.marked_count);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), g_cf->marked_count);
     }
     SetWindowText(cur_ctrl, static_val);
 
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_DISP);
-    EnableWindow(cur_ctrl, cfile.marked_count && filtered_active);
+    EnableWindow(cur_ctrl, g_cf->marked_count && filtered_active);
     if (range->remove_ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_marked_cnt - range->displayed_ignored_marked_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_marked_cnt - range->displayed_ignored_marked_cnt);
     } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_marked_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_marked_cnt);
     }
     SetWindowText(cur_ctrl, static_val);
 
@@ -1961,39 +1960,67 @@ range_update_dynamics(HWND dlg_hwnd, packet_range_t *range) {
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_CAP);
     EnableWindow(cur_ctrl, range->mark_range_cnt && !filtered_active);
     if (range->remove_ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->mark_range_cnt - range->ignored_mark_range_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->mark_range_cnt - range->ignored_mark_range_cnt);
     } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->mark_range_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%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);
     if (range->remove_ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_mark_range_cnt - range->displayed_ignored_mark_range_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_mark_range_cnt - range->displayed_ignored_mark_range_cnt);
     } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_mark_range_cnt);
+        StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%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);
-    if (range->remove_ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->user_range_cnt - range->ignored_user_range_cnt);
-    } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->user_range_cnt);
-    }
-    SetWindowText(cur_ctrl, static_val);
+    switch (packet_range_check(range)) {
+        case CVT_NO_ERROR:
+            cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
+            SendMessage(cur_ctrl, EM_SETBKGNDCOLOR, (WPARAM) 1, COLOR_WINDOW);
+
+            cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_CAP);
+            EnableWindow(cur_ctrl, !filtered_active);
+            if (range->remove_ignored) {
+                StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->user_range_cnt - range->ignored_user_range_cnt);
+            } else {
+                StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->user_range_cnt);
+            }
+            SetWindowText(cur_ctrl, static_val);
 
-    cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_DISP);
-    EnableWindow(cur_ctrl, filtered_active);
-    if (range->remove_ignored) {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_user_range_cnt - range->displayed_ignored_user_range_cnt);
-    } else {
-        _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_user_range_cnt);
+            cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_DISP);
+            EnableWindow(cur_ctrl, filtered_active);
+            if (range->remove_ignored) {
+                StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_user_range_cnt - range->displayed_ignored_user_range_cnt);
+            } else {
+                StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), range->displayed_user_range_cnt);
+            }
+            SetWindowText(cur_ctrl, static_val);
+            break;
+        case CVT_SYNTAX_ERROR:
+            if (range->process == range_process_user_range) range_valid = FALSE;
+            cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
+            SendMessage(cur_ctrl, EM_SETBKGNDCOLOR, 0, RGB(0xff, 0xcc, 0xcc));
+            cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_CAP);
+            SetWindowText(cur_ctrl, _T("Bad range"));
+            cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_DISP);
+            SetWindowText(cur_ctrl, _T("-"));
+            break;
+        case CVT_NUMBER_TOO_BIG:
+            if (range->process == range_process_user_range) range_valid = FALSE;
+            cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
+            SendMessage(cur_ctrl, EM_SETBKGNDCOLOR, 0, RGB(0xff, 0xcc, 0xcc));
+            cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_CAP);
+            SetWindowText(cur_ctrl, _T("Too large"));
+            cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_DISP);
+            SetWindowText(cur_ctrl, _T("-"));
+           break;
+
+        default:
+            g_assert_not_reached();
     }
-    SetWindowText(cur_ctrl, static_val);
 
     /* RANGE_REMOVE_IGNORED_PACKETS */
     switch(range->process) {
@@ -2002,7 +2029,7 @@ range_update_dynamics(HWND dlg_hwnd, packet_range_t *range) {
             displayed_ignored_cnt = range->displayed_ignored_cnt;
             break;
         case(range_process_selected):
-            ignored_cnt = (cfile.current_frame && cfile.current_frame->flags.ignored) ? 1 : 0;
+            ignored_cnt = (g_cf->current_frame && g_cf->current_frame->flags.ignored) ? 1 : 0;
             displayed_ignored_cnt = ignored_cnt;
             break;
         case(range_process_marked):
@@ -2026,13 +2053,16 @@ range_update_dynamics(HWND dlg_hwnd, packet_range_t *range) {
 
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_IGNORED_CAP);
     EnableWindow(cur_ctrl, ignored_cnt && !filtered_active);
-    _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), ignored_cnt);
+    StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), ignored_cnt);
     SetWindowText(cur_ctrl, static_val);
 
     cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_IGNORED_DISP);
     EnableWindow(cur_ctrl, displayed_ignored_cnt && filtered_active);
-    _snwprintf(static_val, STATIC_LABEL_CHARS, _T("%u"), displayed_ignored_cnt);
+    StringCchPrintf(static_val, STATIC_LABEL_CHARS, _T("%u"), displayed_ignored_cnt);
     SetWindowText(cur_ctrl, static_val);
+
+    cur_ctrl = GetDlgItem(GetParent(dlg_hwnd), IDOK);
+    EnableWindow(cur_ctrl, range_valid);
 }
 
 static void
@@ -2046,6 +2076,15 @@ range_handle_wm_initdialog(HWND dlg_hwnd, packet_range_t *range) {
         cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_CAPTURED_BTN);
     SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0);
 
+    /* Retain the filter text, and fill it in. */
+    if(range->user_range != NULL) {
+        char* tmp_str;
+        cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT);
+        tmp_str = range_convert_range(NULL, range->user_range);
+        SetWindowText(cur_ctrl, utf_8to16(tmp_str));
+        wmem_free(NULL, tmp_str);
+    }
+
     /* dynamic values in the range frame */
     range_update_dynamics(dlg_hwnd, range);
 
@@ -2077,6 +2116,8 @@ range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, packet_range_t
     HWND  cur_ctrl;
     TCHAR range_text[RANGE_TEXT_MAX];
 
+    if (!range) return;
+
     switch(w_param) {
         case (BN_CLICKED << 16) | EWFD_CAPTURED_BTN:
         case (BN_CLICKED << 16) | EWFD_DISPLAYED_BTN:
@@ -2123,7 +2164,7 @@ range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, packet_range_t
             cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_BTN);
             SendMessage(cur_ctrl, BM_CLICK, 0, 0);
             break;
-        case (EN_CHANGE << 16) | EWFD_RANGE_EDIT:
+        case (EN_UPDATE << 16) | EWFD_RANGE_EDIT:
             SendMessage(ctrl, WM_GETTEXT, (WPARAM) RANGE_TEXT_MAX, (LPARAM) range_text);
             packet_range_convert_str(range, utf_16to8(range_text));
             range_update_dynamics(dlg_hwnd, range);
@@ -2139,11 +2180,7 @@ range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, packet_range_t
     }
 }
 
-#if (_MSC_VER <= 1200)
-static UINT CALLBACK
-#else
 static UINT_PTR CALLBACK
-#endif
 merge_file_hook_proc(HWND mf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
     HWND      cur_ctrl, parent;
     OFNOTIFY *notify = (OFNOTIFY *) l_param;
@@ -2152,34 +2189,33 @@ merge_file_hook_proc(HWND mf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
     switch(msg) {
         case WM_INITDIALOG:
             /* Retain the filter text, and fill it in. */
-            if(dfilter_str != NULL) {
+            if(g_dfilter_str != NULL) {
                 cur_ctrl = GetDlgItem(mf_hwnd, EWFD_FILTER_EDIT);
-                SetWindowText(cur_ctrl, utf_8to16(dfilter_str));
+                SetWindowText(cur_ctrl, utf_8to16(g_dfilter_str));
             }
 
-            /* Append by default */
-            cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_PREPEND_BTN);
+            /* Chrono by default */
+            cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_CHRONO_BTN);
             SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0);
-            merge_action = merge_append;
+            g_merge_action = merge_append;
 
-            preview_set_filename(mf_hwnd, NULL);
+            preview_set_file_info(mf_hwnd, NULL);
             break;
         case WM_NOTIFY:
             switch (notify->hdr.code) {
                 case CDN_FILEOK:
                     /* Fetch the read filter */
                     cur_ctrl = GetDlgItem(mf_hwnd, EWFD_FILTER_EDIT);
-                    if (dfilter_str)
-                        g_free(dfilter_str);
-                    dfilter_str = filter_tb_get(cur_ctrl);
+                    g_free(g_dfilter_str);
+                    g_dfilter_str = filter_tb_get(cur_ctrl);
 
                     cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_CHRONO_BTN);
                     if(SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) {
-                        merge_action = merge_chrono;
+                        g_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;
+                            g_merge_action = merge_prepend;
                         }
                     }
 
@@ -2188,11 +2224,11 @@ merge_file_hook_proc(HWND mf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
                     /* 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, utf_16to8(sel_name));
+                    CommDlg_OpenSave_GetFilePath(parent, sel_name, MAX_PATH);
+                    preview_set_file_info(mf_hwnd, utf_16to8(sel_name));
                     break;
                 case CDN_HELP:
-                    topic_cb(NULL, HELP_MERGE_WIN32_DIALOG);
+                    topic_action(HELP_MERGE_WIN32_DIALOG);
                     break;
                 default:
                     break;
@@ -2215,27 +2251,27 @@ merge_file_hook_proc(HWND mf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
 }
 
 
-#if (_MSC_VER <= 1200)
-static UINT CALLBACK
-#else
 static UINT_PTR CALLBACK
-#endif
 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;
+    int            i, filter_index;
 
     switch(msg) {
-        case WM_INITDIALOG:
+        case WM_INITDIALOG: {
+            OPENFILENAME *ofnp = (OPENFILENAME *) l_param;
+            capture_file *cf = (capture_file *) ofnp->lCustData;
+
             /* init the printing range */
-            packet_range_init(&print_args.range);
+            packet_range_init(&print_args.range, cf);
             /* default to displayed packets */
             print_args.range.process_filtered = TRUE;
             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) {
@@ -2251,13 +2287,13 @@ export_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
                 case CDN_FILEOK:
                     break;
                 case CDN_TYPECHANGE:
-                    index = notify->lpOFN->nFilterIndex;
+                    filter_index = notify->lpOFN->nFilterIndex;
 
-                    if (index == 2)     /* PostScript */
+                    if (filter_index == 2)     /* PostScript */
                         print_args.format = PR_FMT_TEXT;
                     else
                         print_args.format = PR_FMT_PS;
-                    if (index == 3 || index == 4 || index == 5 || index == 6)
+                    if (filter_index == 3 || filter_index == 4 || filter_index == 5 || filter_index == 6)
                         pkt_fmt_enable = FALSE;
                     else
                         pkt_fmt_enable = TRUE;
@@ -2267,7 +2303,7 @@ export_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
                     }
                     break;
                 case CDN_HELP:
-                    topic_cb(NULL, HELP_EXPORT_FILE_WIN32_DIALOG);
+                    topic_action(HELP_EXPORT_FILE_WIN32_DIALOG);
                     break;
                 default:
                     break;
@@ -2279,11 +2315,7 @@ export_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
     return 0;
 }
 
-#if (_MSC_VER <= 1200)
-static UINT CALLBACK
-#else
 static UINT_PTR CALLBACK
-#endif
 export_raw_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
     HWND          cur_ctrl;
     OPENFILENAME *ofnp = (OPENFILENAME *) l_param;
@@ -2292,7 +2324,7 @@ export_raw_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param
 
     switch(msg) {
         case WM_INITDIALOG:
-            _snwprintf(raw_msg, STATIC_LABEL_CHARS, _T("%d byte%s of raw binary data will be written"),
+            StringCchPrintf(raw_msg, STATIC_LABEL_CHARS, _T("%d byte%s of raw binary data will be written"),
                     ofnp->lCustData, utf_8to16(plurality(ofnp->lCustData, "", "s")));
             cur_ctrl = GetDlgItem(ef_hwnd, EWFD_EXPORTRAW_ST);
             SetWindowText(cur_ctrl, raw_msg);
@@ -2300,7 +2332,7 @@ export_raw_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param
         case WM_NOTIFY:
             switch (notify->hdr.code) {
                 case CDN_HELP:
-                    topic_cb(NULL, HELP_EXPORT_BYTES_WIN32_DIALOG);
+                    topic_action(HELP_EXPORT_BYTES_WIN32_DIALOG);
                     break;
                 default:
                     break;
@@ -2311,11 +2343,7 @@ export_raw_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param
     return 0;
 }
 
-#if (_MSC_VER <= 1200)
-static UINT CALLBACK
-#else
 static UINT_PTR CALLBACK
-#endif
 export_sslkeys_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) {
     HWND          cur_ctrl;
     OPENFILENAME *ofnp = (OPENFILENAME *) l_param;
@@ -2324,7 +2352,7 @@ export_sslkeys_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_p
 
     switch(msg) {
         case WM_INITDIALOG:
-            _snwprintf(sslkeys_msg, STATIC_LABEL_CHARS, _T("%d SSL Session Key%s will be written"),
+            StringCchPrintf(sslkeys_msg, STATIC_LABEL_CHARS, _T("%d SSL Session Key%s will be written"),
                     ofnp->lCustData, utf_8to16(plurality(ofnp->lCustData, "", "s")));
             cur_ctrl = GetDlgItem(ef_hwnd, EWFD_EXPORTSSLKEYS_ST);
             SetWindowText(cur_ctrl, sslkeys_msg);
@@ -2332,7 +2360,7 @@ export_sslkeys_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_p
         case WM_NOTIFY:
             switch (notify->hdr.code) {
                 case CDN_HELP:
-                    topic_cb(NULL, HELP_EXPORT_BYTES_WIN32_DIALOG);
+                    topic_action(HELP_EXPORT_BYTES_WIN32_DIALOG);
                     break;
                 default:
                     break;