Use default folders.
diff --git a/src/libmtp.c b/src/libmtp.c
index 025aa23..ed8353f 100644
--- a/src/libmtp.c
+++ b/src/libmtp.c
@@ -307,7 +307,6 @@
   LIBMTP_Register_Filetype("Text file", LIBMTP_FILETYPE_TEXT, PTP_OFC_Text,NULL,NULL,NULL);
   LIBMTP_Register_Filetype("HTML file", LIBMTP_FILETYPE_HTML, PTP_OFC_HTML,NULL,NULL,NULL);
   LIBMTP_Register_Filetype("Undefined filetype", LIBMTP_FILETYPE_UNKNOWN, PTP_OFC_Undefined, NULL, NULL, NULL);
-
 }
 
 /**
@@ -754,6 +753,7 @@
   PTPDevicePropDesc dpd;
   uint8_t batteryLevelMax = 100;
   uint16_t ret;
+  uint32_t i;
   LIBMTP_mtpdevice_t *tmpdevice;
 
   // Allocate a parameter block
@@ -808,6 +808,50 @@
   tmpdevice->storage_id = storageID;
   tmpdevice->maximum_battery_level = batteryLevelMax;
 
+  // Set all default folders to 0 == root directory
+  tmpdevice->default_music_folder = 0;
+  tmpdevice->default_playlist_folder = 0;
+  tmpdevice->default_picture_folder = 0;
+  tmpdevice->default_video_folder = 0;
+  tmpdevice->default_organizer_folder = 0;
+  tmpdevice->default_zencast_folder = 0;
+
+  /*
+   * Then get the handles and try to locate the default folders.
+   * This has the desired side effect of cacheing all handles from
+   * the device which speeds up later operations.
+   */
+  flush_handles(tmpdevice);
+  for (i = 0; i < params->handles.n; i++) {
+    PTPObjectInfo oi;
+    if (ptp_getobjectinfo(params, params->handles.Handler[i], &oi) == PTP_RC_OK) {
+      // Ignore non-folders
+      if ( oi.ObjectFormat != PTP_OFC_Association )
+	continue;
+      if (!strcmp(oi.Filename, "Music")) {
+	tmpdevice->default_music_folder = params->handles.Handler[i];
+	continue;
+      } else if (!strcmp(oi.Filename, "My Playlists")) {
+	tmpdevice->default_playlist_folder = params->handles.Handler[i];
+	continue;
+      } else if (!strcmp(oi.Filename, "Pictures")) {
+	tmpdevice->default_picture_folder = params->handles.Handler[i];
+	continue;
+      } else if (!strcmp(oi.Filename, "Video")) {
+	tmpdevice->default_video_folder = params->handles.Handler[i];
+	continue;
+      } else if (!strcmp(oi.Filename, "My Organizer")) {
+	tmpdevice->default_organizer_folder = params->handles.Handler[i];
+	continue;
+      } else if (!strcmp(oi.Filename, "ZENcast")) {
+	tmpdevice->default_zencast_folder = params->handles.Handler[i];
+	continue;
+      }
+    } else {
+      printf("LIBMTP panic: Found a bad handle, trying to ignore it.\n");
+    }
+  }
+
   return tmpdevice;
   
   // Then close it again.
@@ -1801,6 +1845,10 @@
   PTPParams *params = (PTPParams *) device->params;
   uint32_t localph = parenthandle;
 
+  if (localph == 0) {
+    localph = device->default_music_folder;
+  }
+
   // Sanity check, is this really a track?
   if (metadata->filetype != LIBMTP_FILETYPE_WAV &&
       metadata->filetype != LIBMTP_FILETYPE_MP3 &&
@@ -1930,11 +1978,52 @@
   int subcall_ret;
   PTPObjectInfo new_file;
   PTPParams *params = (PTPParams *) device->params;
-  
+
   new_file.Filename = filedata->filename;
   new_file.ObjectCompressedSize = filedata->filesize;
   new_file.ObjectFormat = map_libmtp_type_to_ptp_type(filedata->filetype);
 
+  /* 
+   * If no destination folder was given, look up a default
+   * folder if possible. Perhaps there is some way of retrieveing
+   * the default folder for different forms of content, what
+   * do I know, we use a fixed list in lack of any better method.
+   * Some devices obviously need to have their files in certain
+   * folders in order to find/display them at all (hello Creative), 
+   * so we have to have a method for this.
+   */
+
+  if (localph == 0) {
+    uint16_t of = new_file.ObjectFormat;
+    if (of == PTP_OFC_WAV ||
+	of == PTP_OFC_MP3 ||
+	of == PTP_OFC_MTP_WMA ||
+	of == PTP_OFC_MTP_OGG ||
+	of == PTP_OFC_MTP_MP4 ||
+	of == PTP_OFC_MTP_UndefinedAudio) {
+      localph = device->default_music_folder;
+    } else if (of == PTP_OFC_MTP_WMV ||
+	       of == PTP_OFC_AVI ||
+	       of == PTP_OFC_MPEG ||
+	       of == PTP_OFC_ASF ||
+	       of == PTP_OFC_QT ||
+	       of == PTP_OFC_MTP_UndefinedVideo) {
+      localph = device->default_video_folder;
+    } else if (of == PTP_OFC_EXIF_JPEG ||
+	       of == PTP_OFC_JFIF ||
+	       of == PTP_OFC_TIFF ||
+	       of == PTP_OFC_BMP ||
+	       of == PTP_OFC_GIF ||
+	       of == PTP_OFC_PICT ||
+	       of == PTP_OFC_PNG ||
+	       of == PTP_OFC_MTP_WindowsImageFormat) {
+      localph = device->default_picture_folder;
+    } else if (of == PTP_OFC_MTP_vCalendar1 ||
+	       of == PTP_OFC_MTP_vCalendar2) {
+      localph = device->default_organizer_folder;
+    }
+  }
+
   // Create the object
   ret = ptp_sendobjectinfo(params, &store, &localph, &filedata->item_id, &new_file);
   if (ret != PTP_RC_OK) {
@@ -2623,6 +2712,11 @@
   uint32_t localph = parenthandle;
   char fname[256];
 
+  // Use a default folder if none given
+  if (localph == 0) {
+    localph = device->default_playlist_folder;
+  }
+
   // .zpl is the "abstract audio/video playlist "file" suffix
   new_pl.Filename = NULL;
   if (strlen(metadata->name) > 4) {