Mikołaj Zalewski : shell32: Show the original file name and deletion date in the Trash folder.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Aug 18 05:40:37 CDT 2006


Module: wine
Branch: master
Commit: 47b40c58792b8aa818e9bcac18573e97248e401b
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=47b40c58792b8aa818e9bcac18573e97248e401b

Author: Mikołaj Zalewski <mikolaj at zalewski.pl>
Date:   Thu Aug 17 18:29:58 2006 +0200

shell32: Show the original file name and deletion date in the Trash folder.

---

 dlls/shell32/trash.c |   85 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 76 insertions(+), 9 deletions(-)

diff --git a/dlls/shell32/trash.c b/dlls/shell32/trash.c
index c7e4bb8..fc0ce42 100644
--- a/dlls/shell32/trash.c
+++ b/dlls/shell32/trash.c
@@ -55,6 +55,7 @@ static CRITICAL_SECTION TRASH_Creating =
 
 static const char trashinfo_suffix[] = ".trashinfo";
 static const char trashinfo_header[] = "[Trash Info]\n";
+static const char trashinfo_group[] = "Trash Info";
 
 typedef struct
 {
@@ -382,30 +383,96 @@ void TRASH_DisposeElement(TRASH_ELEMENT 
 
 HRESULT TRASH_GetDetails(const TRASH_ELEMENT *element, WIN32_FIND_DATAW *data)
 {
-    LPSTR path;
+    LPSTR path = NULL;
+    XDG_PARSED_FILE *parsed = NULL;
+    char *original_file_name = NULL;
+    char *deletion_date = NULL;
+    int fd = -1;
     struct stat stats;
+    HRESULT ret = S_FALSE;
+    LPWSTR original_dos_name;
     int suffix_length = lstrlenA(trashinfo_suffix);
     int filename_length = lstrlenA(element->filename);
-    int path_length = lstrlenA(element->bucket->files_dir);
-    static const WCHAR fmt[] = {'T','O','D','O','\\','(','%','h','s',')',0};
+    int files_length = lstrlenA(element->bucket->files_dir);
+    int path_length = max(lstrlenA(element->bucket->info_dir), files_length);
     
     path = SHAlloc(path_length + filename_length + 1);
     if (path == NULL) return E_OUTOFMEMORY;
-    lstrcpyA(path, element->bucket->files_dir);
-    lstrcpyA(path+path_length, element->filename);
-    path[path_length + filename_length - suffix_length] = 0;  /* remove the '.trashinfo' */
+    wsprintfA(path, "%s%s", element->bucket->files_dir, element->filename);
+    path[path_length + filename_length - suffix_length] = 0;  /* remove the '.trashinfo' */    
     if (lstat(path, &stats) == -1)
     {
         ERR("Error accessing data file for trashinfo %s (errno=%d)\n", element->filename, errno);
-        return S_FALSE;
+        goto failed;
+    }
+    
+    wsprintfA(path, "%s%s", element->bucket->info_dir, element->filename);
+    fd = open(path, O_RDONLY);
+    if (fd == -1)
+    {
+        ERR("Couldn't open trashinfo file %s (errno=%d)\n", path, errno);
+        goto failed;
+    }
+    
+    parsed = XDG_ParseDesktopFile(fd);
+    if (parsed == NULL)
+    {
+        ERR("Parse error in trashinfo file %s\n", path);
+        goto failed;
+    }
+    
+    original_file_name = XDG_GetStringValue(parsed, trashinfo_group, "Path", XDG_URLENCODE);
+    if (original_file_name == NULL)
+    {
+        ERR("No 'Path' entry in trashinfo file\n");
+        goto failed;
     }
     
     ZeroMemory(data, sizeof(*data));
     data->nFileSizeHigh = (DWORD)((LONGLONG)stats.st_size>>32);
     data->nFileSizeLow = stats.st_size & 0xffffffff;
     RtlSecondsSince1970ToTime(stats.st_mtime, (LARGE_INTEGER *)&data->ftLastWriteTime);
-    wnsprintfW(data->cFileName, MAX_PATH, fmt, element->filename);
-    return S_OK;
+    
+    original_dos_name = wine_get_dos_file_name(original_file_name);
+    if (original_dos_name != NULL)
+    {
+        lstrcpynW(data->cFileName, original_dos_name, MAX_PATH);
+        SHFree(original_dos_name);
+    }
+    else
+    {
+        /* show only the file name */
+        char *filename = strrchr(original_file_name, '/');
+        if (filename == NULL)
+            filename = original_file_name;
+        MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, data->cFileName, MAX_PATH);
+    }
+    
+    deletion_date = XDG_GetStringValue(parsed, trashinfo_group, "DeletionDate", 0);
+    if (deletion_date)
+    {
+        struct tm del_time;
+        time_t del_secs;
+        
+        sscanf(deletion_date, "%d-%d-%dT%d:%d:%d",
+            &del_time.tm_year, &del_time.tm_mon, &del_time.tm_mday,
+            &del_time.tm_hour, &del_time.tm_min, &del_time.tm_sec);
+        del_time.tm_year -= 1900;
+        del_time.tm_mon--;
+        del_secs = mktime(&del_time);
+        
+        RtlSecondsSince1970ToTime(del_secs, (LARGE_INTEGER *)&data->ftLastAccessTime);
+    }
+    
+    ret = S_OK;
+failed:
+    SHFree(path);
+    SHFree(original_file_name);
+    SHFree(deletion_date);
+    if (fd != -1)
+        close(fd);
+    XDG_FreeParsedFile(parsed);
+    return ret;
 }
 
 INT CALLBACK free_item_callback(void *item, void *lParam)




More information about the wine-cvs mailing list