Add ws_load_library and ws_module_open, which respectively call
[obnox/wireshark/wip.git] / gtk / main.c
index 832556c617b5232e2e3a6c4c0e8f797979cb4444..bb3bbdce6cdb1fa97184c440a056476ea3de9eff 100644 (file)
 #endif
 
 #ifdef NEED_STRERROR_H
-#include "strerror.h"
+#include "wsutil/strerror.h"
 #endif
 
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
 #else
-#include "wsgetopt.h"
+#include "wsutil/wsgetopt.h"
 #endif
 
 #ifdef _WIN32 /* Needed for console I/O */
 #include "../version_info.h"
 #include "../merge.h"
 #include "../alert_box.h"
-#include "../capture_ui_utils.h"
 #include "../log.h"
 #include <wsutil/file_util.h>
 
-
 #ifdef HAVE_LIBPCAP
+#include "../capture_ui_utils.h"
 #include "../capture-pcap-util.h"
 #include "../capture_ifinfo.h"
 #include "../capture.h"
 #include "../capture-wpcap.h"
 #include "../capture_wpcap_packet.h"
 #include <tchar.h> /* Needed for Unicode */
+#include <wsutil/unicode-utils.h>
 #include <commctrl.h>
+#include <shellapi.h>
 #endif /* _WIN32 */
 
 /* GTK related */
 #include "gtk/tap_dfilter_dlg.h"
 #include "gtk/prefs_column.h"
 #include "gtk/prefs_dlg.h"
+#include "gtk/proto_help.h"
 
 #ifdef HAVE_LIBPCAP
 #include "../image/wsicon16.xpm"
 #include "gtk/new_packet_list.h"
 #endif
 
+#ifdef HAVE_GTKOSXAPPLICATION
+#include <igemacintegration/gtkosxapplication.h>
+#endif
+
 /*
  * Files under personal and global preferences directories in which
  * GTK settings for Wireshark are stored.
@@ -216,6 +222,7 @@ guint  tap_update_timer_id;
 static gboolean has_console;   /* TRUE if app has console */
 static void destroy_console(void);
 static gboolean stdin_capture = FALSE; /* Don't grab stdin & stdout if TRUE */
+static gboolean dll_set = FALSE; /* Did we sucessfully trim our DLL path? */
 #endif
 static void console_log_handler(const char *log_domain,
     GLogLevelFlags log_level, const char *message, gpointer user_data);
@@ -520,12 +527,14 @@ GList *
 get_ip_address_list_from_packet_list_row(gpointer data)
 {
     gint    row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
+#ifdef NEW_PACKET_LIST
+    gint    column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
+#else
     gint    column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY));
+#endif
     gint    col;
     frame_data *fdata;
     GList      *addr_list = NULL;
-    int         err;
-    gchar       *err_info;
 
 #ifdef NEW_PACKET_LIST
     fdata = (frame_data *) new_packet_list_get_row_data(row);
@@ -536,13 +545,8 @@ get_ip_address_list_from_packet_list_row(gpointer data)
     if (fdata != NULL) {
         epan_dissect_t edt;
 
-        if (!wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header,
-                   cfile.pd, fdata->cap_len, &err, &err_info))
-       {
-            simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                      cf_read_error_message(err, err_info), cfile.filename);
-            return NULL;
-        }
+        if (!cf_read_frame (&cfile, fdata))
+            return NULL; /* error reading the frame */
 
         epan_dissect_init(&edt, FALSE, FALSE);
         col_custom_prime_edt(&edt, &cfile.cinfo);
@@ -572,11 +576,13 @@ static gchar *
 get_filter_from_packet_list_row_and_column(gpointer data)
 {
     gint    row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
+#ifdef NEW_PACKET_LIST
+    gint    column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
+#else
     gint    column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY));
+#endif
     frame_data *fdata;
     gchar      *buf=NULL;
-    int         err;
-    gchar       *err_info;
 
 #ifdef NEW_PACKET_LIST
     fdata = (frame_data *) new_packet_list_get_row_data(row);
@@ -587,12 +593,8 @@ get_filter_from_packet_list_row_and_column(gpointer data)
     if (fdata != NULL) {
         epan_dissect_t edt;
 
-        if (!wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header,
-                   cfile.pd, fdata->cap_len, &err, &err_info)) {
-            simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                      cf_read_error_message(err, err_info), cfile.filename);
-            return NULL;
-        }
+        if (!cf_read_frame(&cfile, fdata))
+            return NULL; /* error reading the frame */
         /* proto tree, visible. We need a proto tree if there's custom columns */
         epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
         col_custom_prime_edt(&edt, &cfile.cinfo);
@@ -689,17 +691,25 @@ copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E acti
 
 
 /* mark as reference time frame */
-static void
+void
 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
   if (row == -1)
     return;
   if (set) {
     frame->flags.ref_time=1;
+       cfile.ref_time_count++;
   } else {
     frame->flags.ref_time=0;
+    cfile.ref_time_count--;
   }
   cf_reftime_packets(&cfile);
 #ifdef NEW_PACKET_LIST
+  if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
+    new_packet_list_freeze();
+    cfile.displayed_count--;
+    new_packet_list_recreate_visible_rows();
+    new_packet_list_thaw();
+  }
   new_packet_list_queue_draw();
 #endif
 }
@@ -753,10 +763,10 @@ reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
     }
     break;
   case REFTIME_FIND_NEXT:
-    find_previous_next_frame_with_filter("frame.ref_time", FALSE);
+    cf_find_packet_time_reference(&cfile, SD_FORWARD);
     break;
   case REFTIME_FIND_PREV:
-    find_previous_next_frame_with_filter("frame.ref_time", TRUE);
+    cf_find_packet_time_reference(&cfile, SD_BACKWARD);
     break;
   }
 }
@@ -764,13 +774,13 @@ reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
 void
 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
 {
-    find_previous_next_frame_with_filter("frame.marked == TRUE", FALSE);
+    cf_find_packet_marked(&cfile, SD_FORWARD);
 }
 
 void
 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
 {
-    find_previous_next_frame_with_filter("frame.marked == TRUE", TRUE);
+    cf_find_packet_marked(&cfile, SD_BACKWARD);
 }
 
 static void
@@ -806,6 +816,7 @@ tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
         cf_unselect_field(&cfile);
         packet_hex_print(byte_view, byte_data,
                          cfile.current_frame, NULL, byte_len);
+        proto_help_menu_modify(sel, &cfile);
         return;
     }
     gtk_tree_model_get(model, &iter, 1, &finfo, -1);
@@ -869,6 +880,7 @@ tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
     }
     packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
                      byte_len);
+    proto_help_menu_modify(sel, &cfile);
 }
 
 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
@@ -1164,7 +1176,7 @@ print_usage(gboolean print_ver) {
   fprintf(output, "  -S                       update packet display when new packets are captured\n");
   fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-  fprintf(output, "  -B <buffer size>         size of kernel buffer (def: platform-dependent)\n");
+  fprintf(output, "  -B <buffer size>         size of kernel buffer (def: 1MB)\n");
 #endif
   fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
   fprintf(output, "  -D                       print list of interfaces and exit\n");
@@ -1385,8 +1397,10 @@ resolv_update_cb(gpointer data _U_)
 {
   /* Anything new show up? */
   if (host_name_lookup_process(NULL)) {
-    gdk_window_invalidate_rect(pkt_scrollw->window, NULL, TRUE);
-    gdk_window_invalidate_rect(tv_scrollw->window, NULL, TRUE);
+    if (pkt_scrollw->window)
+       gdk_window_invalidate_rect(pkt_scrollw->window, NULL, TRUE);
+    if (tv_scrollw->window)
+       gdk_window_invalidate_rect(tv_scrollw->window, NULL, TRUE);
   }
 
   /* Always check. Even if we don't do async lookups we could still get
@@ -1395,21 +1409,19 @@ resolv_update_cb(gpointer data _U_)
 }
 
 
-/* Set the file name in the name for the main window and in the name for the main window's icon. */
-static void
+/* Set main_window_name and it's icon title to the capture filename */
+void
 set_display_filename(capture_file *cf)
 {
-  gchar       *win_name;
+  gchar *window_name;
 
-  if (!cf->is_tempfile && cf->filename) {
-    /* Add this filename to the list of recent files in the "Recent Files" submenu */
-    add_menu_recent_capture_file(cf->filename);
+  if (cf->filename) {
+    window_name = g_strdup_printf("%s", cf_get_display_name(cf));
+    set_main_window_name(window_name);
+    g_free(window_name);
+  } else {
+    set_main_window_name("The Wireshark Network Analyzer");
   }
-
-  /* window title */
-  win_name = g_strdup_printf("%s - Wireshark", cf_get_display_name(cf));
-  set_main_window_name(win_name);
-  g_free(win_name);
 }
 
 GtkWidget           *close_dlg = NULL;
@@ -1488,6 +1500,17 @@ main_cf_cb_file_read_started(capture_file *cf _U_)
 static void
 main_cf_cb_file_read_finished(capture_file *cf)
 {
+    gchar *dir_path;
+
+    if (!cf->is_tempfile && cf->filename) {
+        /* Add this filename to the list of recent files in the "Recent Files" submenu */
+        add_menu_recent_capture_file(cf->filename);
+
+        /* Remember folder for next Open dialog and save it in recent */
+       dir_path = get_dirname(g_strdup(cf->filename));
+        set_last_open_dir(dir_path);
+        g_free(dir_path);
+    }
     set_display_filename(cf);
 
     /* Enable menu items that make sense if you have a capture file you've
@@ -1548,8 +1571,6 @@ main_capture_set_main_window_title(capture_options *capture_opts)
     if(capture_opts->iface) {
         g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
     }
-    g_string_append(title, "- Wireshark");
-
     set_main_window_name(title->str);
     g_string_free(title, TRUE);
 }
@@ -1599,6 +1620,10 @@ main_capture_cb_capture_update_finished(capture_options *capture_opts)
     capture_file *cf = capture_opts->cf;
     static GList *icon_list = NULL;
 
+    if (!cf->is_tempfile && cf->filename) {
+        /* Add this filename to the list of recent files in the "Recent Files" submenu */
+        add_menu_recent_capture_file(cf->filename);
+    }
     set_display_filename(cf);
 
     /* Enable menu items that make sense if you're not currently running
@@ -1766,6 +1791,9 @@ main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
 static void
 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
 {
+#ifdef HAVE_GTKOSXAPPLICATION
+    GtkOSXApplication *theApp;
+#endif
     switch(event) {
     case(capture_cb_capture_prepared):
         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
@@ -1774,6 +1802,10 @@ main_capture_callback(gint event, capture_options *capture_opts, gpointer user_d
     case(capture_cb_capture_update_started):
         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
         main_capture_cb_capture_update_started(capture_opts);
+#ifdef HAVE_GTKOSXAPPLICATION
+        theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
+        gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
+#endif
         break;
     case(capture_cb_capture_update_continue):
         /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
@@ -1797,6 +1829,10 @@ main_capture_callback(gint event, capture_options *capture_opts, gpointer user_d
         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
         /* Beware: this state won't be called, if the capture child
          * closes the capturing on it's own! */
+#ifdef HAVE_GTKOSXAPPLICATION
+        theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
+        gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
+#endif
         break;
     default:
         g_warning("main_capture_callback: event %u unknown", event);
@@ -1808,7 +1844,7 @@ main_capture_callback(gint event, capture_options *capture_opts, gpointer user_d
 static void
 get_gui_compiled_info(GString *str)
 {
-  get_epan_compiled_version_info(str);
+  epan_get_compiled_version_info(str);
 
   g_string_append(str, ", ");
 #ifdef HAVE_LIBPORTAUDIO
@@ -1828,14 +1864,16 @@ get_gui_compiled_info(GString *str)
 #else
   g_string_append(str, "without AirPcap");
 #endif
-#ifdef NEW_PACKET_LIST
-  g_string_append(str, ", with new_packet_list");
+#ifndef NEW_PACKET_LIST
+  g_string_append(str, ", with old_packet_list");
 #endif
 }
 
 static void
 get_gui_runtime_info(GString *str)
 {
+  epan_get_runtime_version_info(str);
+
 #ifdef HAVE_AIRPCAP
   g_string_append(str, ", ");
   get_runtime_airpcap_version(str);
@@ -1845,7 +1883,6 @@ get_gui_runtime_info(GString *str)
     g_string_append(str, ", ");
     u3_runtime_info(str);
   }
-
 }
 
 static e_prefs *
@@ -2006,6 +2043,8 @@ main(int argc, char *argv[])
 
 #ifdef _WIN32
   WSADATA             wsaData;
+  LPWSTR              *wc_argv;
+  int                  wc_argc, i;
 #endif  /* _WIN32 */
 
   char                *rf_path;
@@ -2034,10 +2073,13 @@ main(int argc, char *argv[])
   GtkWidget           *splash_win = NULL;
   GLogLevelFlags       log_flags;
   guint                go_to_packet = 0;
-  gboolean             jump_backwards = FALSE, saved_bw = FALSE;
+  gboolean             jump_backwards = FALSE;
   dfilter_t           *jump_to_filter = NULL;
   int                  optind_initial;
   int                  status;
+#ifdef HAVE_GTKOSXAPPLICATION
+  GtkOSXApplication   *theApp;
+#endif
 
 #ifdef HAVE_LIBPCAP
 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
@@ -2059,6 +2101,21 @@ main(int argc, char *argv[])
 
   static const char optstring[] = OPTSTRING;
 
+#ifdef _WIN32
+  /* Convert our arg list to UTF-8. */
+  wc_argv = CommandLineToArgvW(GetCommandLineW(), &wc_argc);
+  if (wc_argv && wc_argc == argc) {
+    for (i = 0; i < argc; i++) {
+      argv[i] = g_strdup(utf_16to8(wc_argv[i]));
+    }
+  } /* XXX else bail because something is horribly, horribly wrong? */
+
+  if (!dll_set) {
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "SetDllDirectory failed (%d)!\n", GetLastError());
+    /* XXX - Exit? */
+  }
+#endif /* _WIN32 */
+
   /*
    * Get credential information for later use, and drop privileges
    * before doing anything else.
@@ -2221,7 +2278,24 @@ main(int argc, char *argv[])
 
   /* Init the "Open file" dialog directory */
   /* (do this after the path settings are processed) */
-  set_last_open_dir(get_persdatafile_dir());
+
+  /* Read the profile dependent (static part) of the recent file. */
+  /* Only the static part of it will be read, as we don't have the gui now to fill the */
+  /* recent lists which is done in the dynamic part. */
+  /* We have to do this already here, so command line parameters can overwrite these values. */
+  recent_read_profile_static(&rf_path, &rf_open_errno);
+  if (rf_path != NULL && rf_open_errno != 0) {
+    simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                 "Could not open recent file\n\"%s\": %s.",
+                 rf_path, strerror(rf_open_errno));
+  }
+
+  if (recent.gui_fileopen_remembered_dir &&
+      test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
+    set_last_open_dir(recent.gui_fileopen_remembered_dir);
+  } else {
+    set_last_open_dir(get_persdatafile_dir());
+  }
 
   /* Set getopt index back to initial value, so it will start with the
      first command line parameter again.  Also reset opterr to 1, so that
@@ -2387,19 +2461,7 @@ main(int argc, char *argv[])
 #endif /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
 
   splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
-
-
-  /* Read the profile dependent (static part) of the recent file. */
-  /* Only the static part of it will be read, as we don't have the gui now to fill the */
-  /* recent lists which is done in the dynamic part. */
-  /* We have to do this already here, so command line parameters can overwrite these values. */
-  recent_read_profile_static(&rf_path, &rf_open_errno);
-  if (rf_path != NULL && rf_open_errno != 0) {
-    simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
-                 "Could not open recent file\n\"%s\": %s.",
-                 rf_path, strerror(rf_open_errno));
-  }
-
+  proto_help_init();
   cap_file_init(&cfile);
 
   /* Fill in capture options with values from the preferences */
@@ -2560,12 +2622,7 @@ main(int argc, char *argv[])
        /* We may set "last_open_dir" to "cf_name", and if we change
           "last_open_dir" later, we free the old value, so we have to
           set "cf_name" to something that's been allocated. */
-#if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
-        /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
-        cf_name = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
-#else
         cf_name = g_strdup(optarg);
-#endif
         break;
       case 'R':        /* Read file filter */
         rfilter = optarg;
@@ -2644,19 +2701,12 @@ main(int argc, char *argv[])
        * file - yes, you could have "-r" as the last part of the command,
        * but that's a bit ugly.
        */
-#if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
-      /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
-      cf_name = g_locale_to_utf8(argv[0], -1, NULL, NULL, NULL);
-#else
       cf_name = g_strdup(argv[0]);
-#endif
     }
     argc--;
     argv++;
   }
 
-
-
   if (argc != 0) {
     /*
      * Extra command line arguments were specified; complain.
@@ -2739,22 +2789,22 @@ main(int argc, char *argv[])
 
   if (list_link_layer_types) {
     /* Get the list of link-layer types for the capture device. */
-    GList *lt_list;
-    gchar *err_str;
-
-    lt_list = capture_pcap_linktype_list(global_capture_opts.iface, &err_str);
-    if (lt_list == NULL) {
-      if (err_str != NULL) {
-        cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
-         "Please check to make sure you have sufficient permissions, and that\n"
-         "you have the proper interface or pipe specified.\n", global_capture_opts.iface, err_str);
-        g_free(err_str);
-      } else
-        cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
+    if_capabilities_t *caps;
+
+    caps = capture_get_if_capabilities(global_capture_opts.iface,
+                                       global_capture_opts.monitor_mode,
+                                       &err_str);
+    if (caps == NULL) {
+      cmdarg_err("%s", err_str);
+      g_free(err_str);
       exit(2);
     }
-    capture_opts_print_link_layer_types(lt_list);
-    free_pcap_linktype_list(lt_list);
+    if (caps->data_link_types == NULL) {
+      cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
+      exit(2);
+    }
+    capture_opts_print_if_capabilities(caps, global_capture_opts.monitor_mode);
+    free_if_capabilities(caps);
     exit(0);
   }
 
@@ -2899,15 +2949,11 @@ main(int argc, char *argv[])
             /* try to compile given filter */
             if (!dfilter_compile(jfilter, &jump_to_filter)) {
               bad_dfilter_alert_box(jfilter);
-            } else
-            {
+            } else {
               /* Filter ok, jump to the first packet matching the filter
                  conditions. Default search direction is forward, but if
                  option d was given, search backwards */
-              saved_bw = cfile.sbackward;
-              cfile.sbackward = jump_backwards;
-              cf_find_packet_dfilter(&cfile, jump_to_filter);
-              cfile.sbackward = saved_bw;
+              cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
             }
           }
           break;
@@ -2917,6 +2963,17 @@ main(int argc, char *argv[])
           exit(0);
           break;
         }
+
+       /* If the filename is not the absolute path, prepend the current dir. This happens
+          when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
+       if (!g_path_is_absolute(cf_name)) {
+         char *old_cf_name = cf_name;
+         char *pwd = g_get_current_dir();
+         cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
+         g_free(old_cf_name);
+         g_free(pwd);
+       }
+
         /* Save the name of the containing directory specified in the
            path name, if any; we can write over cf_name, which is a
            good thing, given that "get_dirname()" does write over its
@@ -2983,6 +3040,12 @@ main(int argc, char *argv[])
 
   profile_store_persconffiles (FALSE);
 
+#ifdef HAVE_GTKOSXAPPLICATION
+  theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
+  gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
+  gtk_osxapplication_ready(theApp);
+#endif
+
   g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
 
   /* we'll enter the GTK loop now and hand the control over to GTK ... */
@@ -3002,6 +3065,10 @@ main(int argc, char *argv[])
   /* hide the (unresponsive) main window, while asking the user to close the console window */
   gtk_widget_hide(top_level);
 
+#ifdef HAVE_GTKOSXAPPLICATION
+  g_object_unref(theApp);
+#endif
+
   /* Shutdown windows sockets */
   WSACleanup();
 
@@ -3031,6 +3098,12 @@ WinMain (struct HINSTANCE__ *hInstance,
         int                 nCmdShow)
 {
   INITCOMMONCONTROLSEX comm_ctrl;
+  typedef BOOL (*SetDllDirectoryHandler)(LPCTSTR);
+  SetDllDirectoryHandler PSetDllDirectory;
+
+  if (PSetDllDirectory = (SetDllDirectoryHandler) GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "SetDllDirectoryW")) {
+    dll_set = PSetDllDirectory(_T(""));
+  }
 
   /* Initialize our controls. Required for native Windows file dialogs. */
   memset (&comm_ctrl, 0, sizeof(comm_ctrl));
@@ -3043,7 +3116,7 @@ WinMain (struct HINSTANCE__ *hInstance,
   InitCommonControlsEx(&comm_ctrl);
 
   /* RichEd20.DLL is needed for filter entries. */
-  LoadLibrary(_T("riched20.dll"));
+  ws_load_library("riched20.dll");
 
   has_console = FALSE;
   return main (__argc, __argv);
@@ -3454,7 +3527,7 @@ main_widgets_show_or_hide(void)
 
 
 /* called, when the window state changes (minimized, maximized, ...) */
-static int
+static gboolean
 window_state_event_cb (GtkWidget *widget _U_,
                        GdkEvent *event,
                        gpointer  data _U_)
@@ -3474,7 +3547,7 @@ window_state_event_cb (GtkWidget *widget _U_,
 
 
 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
-static int
+static gboolean
 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
 {
     if (event->keyval == GDK_F8) {
@@ -3514,14 +3587,10 @@ static void
 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
 {
     GtkAccelGroup *accel;
-    gchar         *title;
-
-    /* use user-defined title if preference is set */
-    title = create_user_window_title("The Wireshark Network Analyzer");
 
     /* Main window */
-    top_level = window_new(GTK_WINDOW_TOPLEVEL, title);
-    g_free(title);
+    top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
+    set_main_window_name("The Wireshark Network Analyzer");
 
     gtk_widget_set_name(top_level, "main window");
     g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
@@ -3540,13 +3609,13 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
     /* Menu bar */
     menubar = main_menu_new(&accel);
 
-#ifdef HAVE_IGE_MAC_INTEGRATION
-    /* MacOS X native menus are created and displayed by main_menu_new() */
+#if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
+    /* Mac OS X native menus are created and displayed by main_menu_new() */
     if(!prefs_p->gui_macosx_style) {
 #endif
     gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
     gtk_widget_show(menubar);
-#ifdef HAVE_IGE_MAC_INTEGRATION
+#if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
     }
 #endif
 
@@ -3689,6 +3758,10 @@ void change_configuration_profile (const gchar *profile_name)
                  "Could not open common recent file\n\"%s\": %s.",
                  rf_path, strerror(rf_open_errno));
    }
+   if (recent.gui_fileopen_remembered_dir &&
+       test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
+     set_last_open_dir(recent.gui_fileopen_remembered_dir);
+   }
    timestamp_set_type (recent.gui_time_format);
    timestamp_set_seconds_type (recent.gui_seconds_format);
    color_filters_enable(recent.packet_list_colorize);
@@ -3697,7 +3770,7 @@ void change_configuration_profile (const gchar *profile_name)
    prefs_apply_all();
 
    /* Update window view and redraw the toolbar */
-   update_main_window_name();
+   update_main_window_title();
    toolbar_redraw_all();
 
    /* Enable all protocols and disable from the disabled list */