- userinit, usetup, vmwinst, welcome, winefile, winlogon, winver.
[reactos.git] / reactos / subsys / system / winefile / winefile.c
index 8fb06e2..395876b 100644 (file)
 #ifdef __WINE__
 #include "config.h"
 #include "wine/port.h"
+
+/* for unix filesystem function calls */
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
 #endif
 
+#define COBJMACROS
+
 #include "winefile.h"
 
 #include "resource.h"
@@ -155,52 +162,6 @@ typedef struct {
 
 
 
-#ifdef __WINE__
-
-/* functions in unixcalls.c */
-
-extern void call_getcwd(char* buffer, size_t len);
-extern void* call_opendir(const char* path);
-extern int call_readdir(void* pdir, char* name, unsigned* pinode);
-extern void call_closedir(void* pdir);
-
-extern int call_stat(
-       const char* path, int* pis_dir,
-       unsigned long* psize_low, unsigned long* psize_high,
-       time_t* patime, time_t* pmtime,
-       unsigned long* plinks
-);
-
-/* call vswprintf() in msvcrt.dll */
-int swprintf(wchar_t* buffer, const wchar_t* fmt, ...)
-{
-       static int (__cdecl *vswprintf)(wchar_t*, const wchar_t*, va_list);
-
-       va_list ap;
-       int ret;
-
-       if (!vswprintf) {
-               HMODULE hmod = LoadLibraryA("msvcrt");
-               vswprintf = (int(__cdecl*)(wchar_t*,const wchar_t*,va_list)) GetProcAddress(hmod, "vswprintf");
-       }
-
-       va_start(ap, fmt);
-       ret = vswprintf(buffer, fmt, ap);
-       va_end(ap);
-
-       return 0;
-}
-
-
-#else
-
- // ugly hack to use alloca() while keeping Wine's developers happy
-#define HeapAlloc(h,f,s) alloca(s)
-#define HeapFree(h,f,p)
-
-#endif
-
-
 static void read_directory(Entry* dir, LPCTSTR path, SORT_ORDER sortOrder, HWND hwnd);
 static void set_curdir(ChildWnd* child, Entry* entry, int idx, HWND hwnd);
 static void refresh_child(ChildWnd* child);
@@ -278,6 +239,53 @@ static void display_network_error(HWND hwnd)
 }
 
 
+#ifdef __WINE__
+
+#ifdef UNICODE
+
+/* call vswprintf() in msvcrt.dll */
+/*TODO: fix swprintf() in non-msvcrt mode, so that this dynamic linking function can be removed */
+static int msvcrt_swprintf(WCHAR* buffer, const WCHAR* fmt, ...)
+{
+       static int (__cdecl *pvswprintf)(WCHAR*, const WCHAR*, va_list) = NULL;
+       va_list ap;
+       int ret;
+
+       if (!pvswprintf) {
+               HMODULE hModMsvcrt = LoadLibraryA("msvcrt");
+               pvswprintf = (int(__cdecl*)(WCHAR*,const WCHAR*,va_list)) GetProcAddress(hModMsvcrt, "vswprintf");
+       }
+
+       va_start(ap, fmt);
+       ret = (*pvswprintf)(buffer, fmt, ap);
+       va_end(ap);
+
+       return ret;
+}
+
+static LPCWSTR my_wcsrchr(LPCWSTR str, WCHAR c)
+{
+       LPCWSTR p = str;
+
+       while(*p)
+               ++p;
+
+       do {
+               if (--p < str)
+                       return NULL;
+       } while(*p != c);
+
+       return p;
+}
+
+#define _tcsrchr my_wcsrchr
+#else  /* UNICODE */
+#define _tcsrchr strrchr
+#endif /* UNICODE */
+
+#endif /* __WINE__ */
+
+
 /* allocate and initialise a directory entry */
 static Entry* alloc_entry(void)
 {
@@ -300,10 +308,10 @@ static void free_entry(Entry* entry)
                DestroyIcon(entry->hicon);
 
        if (entry->folder && entry->folder!=Globals.iDesktop)
-               (*entry->folder->lpVtbl->Release)(entry->folder);
+               IShellFolder_Release(entry->folder);
 
        if (entry->pidl)
-               (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, entry->pidl);
+               IMalloc_Free(Globals.iMalloc, entry->pidl);
 #endif
 
        free(entry);
@@ -500,8 +508,9 @@ static void read_directory_unix(Entry* dir, LPCTSTR path)
        Entry* first_entry = NULL;
        Entry* last = NULL;
        Entry* entry;
-       void* pdir;
+       DIR* pdir;
 
+       int level = dir->level + 1;
 #ifdef UNICODE
        char cpath[MAX_PATH];
 
@@ -510,17 +519,13 @@ static void read_directory_unix(Entry* dir, LPCTSTR path)
        const char* cpath = path;
 #endif
 
-       pdir = call_opendir(cpath);
-
-       int level = dir->level + 1;
+       pdir = opendir(cpath);
 
        if (pdir) {
-               char buffer[MAX_PATH];
-               time_t atime, mtime;
-               unsigned inode;
-               int is_dir;
+               struct stat st;
+               struct dirent* ent;
+               char buffer[MAX_PATH], *p;
                const char* s;
-               char* p;
 
                for(p=buffer,s=cpath; *s; )
                        *p++ = *s++;
@@ -528,7 +533,7 @@ static void read_directory_unix(Entry* dir, LPCTSTR path)
                if (p==buffer || p[-1]!='/')
                        *p++ = '/';
 
-               while(call_readdir(pdir, p, &inode)) {
+               while((ent=readdir(pdir))) {
                        entry = alloc_entry();
 
                        if (!first_entry)
@@ -539,28 +544,31 @@ static void read_directory_unix(Entry* dir, LPCTSTR path)
 
                        entry->etype = ET_UNIX;
 
+                       strcpy(p, ent->d_name);
 #ifdef UNICODE
                        MultiByteToWideChar(CP_UNIXCP, 0, p, -1, entry->data.cFileName, MAX_PATH);
 #else
                        lstrcpy(entry->data.cFileName, p);
 #endif
 
-                       entry->data.dwFileAttributes = p[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0;
+                       if (!stat(buffer, &st)) {
+                               entry->data.dwFileAttributes = p[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0;
 
-                       if (!call_stat(buffer, &is_dir,
-                               &entry->data.nFileSizeLow, &entry->data.nFileSizeHigh,
-                               &atime, &mtime, &entry->bhfi.nNumberOfLinks))
-                       {
-                               if (is_dir)
+                               if (S_ISDIR(st.st_mode))
                                        entry->data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
 
+                               entry->data.nFileSizeLow = st.st_size & 0xFFFFFFFF;
+                               entry->data.nFileSizeHigh = st.st_size >> 32;
+
                                memset(&entry->data.ftCreationTime, 0, sizeof(FILETIME));
-                               time_to_filetime(&atime, &entry->data.ftLastAccessTime);
-                               time_to_filetime(&mtime, &entry->data.ftLastWriteTime);
+                               time_to_filetime(&st.st_atime, &entry->data.ftLastAccessTime);
+                               time_to_filetime(&st.st_mtime, &entry->data.ftLastWriteTime);
 
-                               entry->bhfi.nFileIndexLow = inode;
+                               entry->bhfi.nFileIndexLow = ent->d_ino;
                                entry->bhfi.nFileIndexHigh = 0;
 
+                               entry->bhfi.nNumberOfLinks = st.st_nlink;
+
                                entry->bhfi_valid = TRUE;
                        } else {
                                entry->data.nFileSizeLow = 0;
@@ -580,7 +588,7 @@ static void read_directory_unix(Entry* dir, LPCTSTR path)
                if (last)
                        last->next = NULL;
 
-               call_closedir(pdir);
+               closedir(pdir);
        }
 
        dir->down = first_entry;
@@ -647,31 +655,27 @@ static Entry* read_tree_unix(Root* root, LPCTSTR path, SORT_ORDER sortOrder, HWN
 #ifdef _SHELL_FOLDERS
 
 #ifdef UNICODE
-#define        tcscpyn strcpyn
 #define        get_strret get_strretW
 #define        path_from_pidl path_from_pidlW
 #else
-#define        tcscpyn wcscpyn
 #define        get_strret get_strretA
 #define        path_from_pidl path_from_pidlA
 #endif
 
 
-static LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count)
+static void free_strret(STRRET* str)
 {
- LPCSTR s;
- LPSTR d = dest;
+       if (str->uType == STRRET_WSTR)
+               IMalloc_Free(Globals.iMalloc, str->UNION_MEMBER(pOleStr));
+}
 
- for(s=source; count&&(*d++=*s++); )
-  count--;
 
- return dest;
-}
+#ifndef UNICODE
 
-static LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count)
+static LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count)
 {
- LPCWSTR s;
- LPWSTR d = dest;
+ LPCSTR s;
+ LPSTR d = dest;
 
  for(s=source; count&&(*d++=*s++); )
   count--;
@@ -679,7 +683,6 @@ static LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count)
  return dest;
 }
 
-
 static void get_strretA(STRRET* str, const SHITEMID* shiid, LPSTR buffer, int len)
 {
  switch(str->uType) {
@@ -696,6 +699,35 @@ static void get_strretA(STRRET* str, const SHITEMID* shiid, LPSTR buffer, int le
  }
 }
 
+static HRESULT path_from_pidlA(IShellFolder* folder, LPITEMIDLIST pidl, LPSTR buffer, int len)
+{
+       STRRET str;
+
+        /* SHGDN_FORPARSING: get full path of id list */
+       HRESULT hr = IShellFolder_GetDisplayNameOf(folder, pidl, SHGDN_FORPARSING, &str);
+
+       if (SUCCEEDED(hr)) {
+               get_strretA(&str, &pidl->mkid, buffer, len);
+               free_strret(&str);
+       } else
+               buffer[0] = '\0';
+
+       return hr;
+}
+
+#endif
+
+static LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count)
+{
+ LPCWSTR s;
+ LPWSTR d = dest;
+
+ for(s=source; count&&(*d++=*s++); )
+  count--;
+
+ return dest;
+}
+
 static void get_strretW(STRRET* str, const SHITEMID* shiid, LPWSTR buffer, int len)
 {
  switch(str->uType) {
@@ -713,18 +745,11 @@ static void get_strretW(STRRET* str, const SHITEMID* shiid, LPWSTR buffer, int l
 }
 
 
-static void free_strret(STRRET* str)
-{
-       if (str->uType == STRRET_WSTR)
-               (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, str->UNION_MEMBER(pOleStr));
-}
-
-
 static HRESULT name_from_pidl(IShellFolder* folder, LPITEMIDLIST pidl, LPTSTR buffer, int len, SHGDNF flags)
 {
        STRRET str;
 
-       HRESULT hr = (*folder->lpVtbl->GetDisplayNameOf)(folder, pidl, flags, &str);
+       HRESULT hr = IShellFolder_GetDisplayNameOf(folder, pidl, flags, &str);
 
        if (SUCCEEDED(hr)) {
                get_strret(&str, &pidl->mkid, buffer, len);
@@ -736,28 +761,12 @@ static HRESULT name_from_pidl(IShellFolder* folder, LPITEMIDLIST pidl, LPTSTR bu
 }
 
 
-static HRESULT path_from_pidlA(IShellFolder* folder, LPITEMIDLIST pidl, LPSTR buffer, int len)
-{
-       STRRET str;
-
-        /* SHGDN_FORPARSING: get full path of id list */
-       HRESULT hr = (*folder->lpVtbl->GetDisplayNameOf)(folder, pidl, SHGDN_FORPARSING, &str);
-
-       if (SUCCEEDED(hr)) {
-               get_strretA(&str, &pidl->mkid, buffer, len);
-               free_strret(&str);
-       } else
-               buffer[0] = '\0';
-
-       return hr;
-}
-
 static HRESULT path_from_pidlW(IShellFolder* folder, LPITEMIDLIST pidl, LPWSTR buffer, int len)
 {
        STRRET str;
 
         /* SHGDN_FORPARSING: get full path of id list */
-       HRESULT hr = (*folder->lpVtbl->GetDisplayNameOf)(folder, pidl, SHGDN_FORPARSING, &str);
+       HRESULT hr = IShellFolder_GetDisplayNameOf(folder, pidl, SHGDN_FORPARSING, &str);
 
        if (SUCCEEDED(hr)) {
                get_strretW(&str, &pidl->mkid, buffer, len);
@@ -784,7 +793,7 @@ static LPITEMIDLIST get_path_pidl(LPTSTR path, HWND hwnd)
        MultiByteToWideChar(CP_ACP, 0, path, -1, buffer, MAX_PATH);
 #endif
 
-       hr = (*Globals.iDesktop->lpVtbl->ParseDisplayName)(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL);
+       hr = IShellFolder_ParseDisplayName(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL);
        if (FAILED(hr))
                return NULL;
 
@@ -806,7 +815,7 @@ static LPITEMIDLIST get_to_absolute_pidl(Entry* entry, HWND hwnd)
                        LPITEMIDLIST pidl;
                        ULONG len;
 
-                       hr = (*Globals.iDesktop->lpVtbl->ParseDisplayName)(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL);
+                       hr = IShellFolder_ParseDisplayName(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL);
 
                        if (SUCCEEDED(hr))
                                return pidl;
@@ -828,7 +837,7 @@ static HICON extract_icon(IShellFolder* folder, LPCITEMIDLIST pidl)
 {
        IExtractIcon* pExtract;
 
-       if (SUCCEEDED((*folder->lpVtbl->GetUIObjectOf)(folder, 0, 1, (LPCITEMIDLIST*)&pidl, &IID_IExtractIcon, 0, (LPVOID*)&pExtract))) {
+       if (SUCCEEDED(IShellFolder_GetUIObjectOf(folder, 0, 1, (LPCITEMIDLIST*)&pidl, &IID_IExtractIcon, 0, (LPVOID*)&pExtract))) {
                TCHAR path[_MAX_PATH];
                unsigned flags;
                HICON hicon;
@@ -896,11 +905,11 @@ static Entry* read_tree_shell(Root* root, LPITEMIDLIST pidl, SORT_ORDER sortOrde
                        break;
 
                 /* copy first element of item idlist */
-               next_pidl = (*Globals.iMalloc->lpVtbl->Alloc)(Globals.iMalloc, pidl->mkid.cb+sizeof(USHORT));
+               next_pidl = IMalloc_Alloc(Globals.iMalloc, pidl->mkid.cb+sizeof(USHORT));
                memcpy(next_pidl, pidl, pidl->mkid.cb);
                ((LPITEMIDLIST)((LPBYTE)next_pidl+pidl->mkid.cb))->mkid.cb = 0;
 
-               hr = (*folder->lpVtbl->BindToObject)(folder, next_pidl, 0, &IID_IShellFolder, (void**)&child);
+               hr = IShellFolder_BindToObject(folder, next_pidl, 0, &IID_IShellFolder, (void**)&child);
                if (!SUCCEEDED(hr))
                        break;
 
@@ -936,12 +945,12 @@ static void fill_w32fdata_shell(IShellFolder* folder, LPCITEMIDLIST pidl, SFGAOF
                STGMEDIUM medium = {0, {0}, 0};
                FORMATETC fmt = {Globals.cfStrFName, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
 
-               HRESULT hr = (*folder->lpVtbl->GetUIObjectOf)(folder, 0, 1, &pidl, &IID_IDataObject, 0, (LPVOID*)&pDataObj);
+               HRESULT hr = IShellFolder_GetUIObjectOf(folder, 0, 1, &pidl, &IID_IDataObject, 0, (LPVOID*)&pDataObj);
 
                if (SUCCEEDED(hr)) {
-                       hr = (*pDataObj->lpVtbl->GetData)(pDataObj, &fmt, &medium);
+                       hr = IDataObject_GetData(pDataObj, &fmt, &medium);
 
-                       (*pDataObj->lpVtbl->Release)(pDataObj);
+                       IDataObject_Release(pDataObj);
 
                        if (SUCCEEDED(hr)) {
                                LPCTSTR path = (LPCTSTR)GlobalLock(medium.UNION_MEMBER(hGlobal));
@@ -994,7 +1003,7 @@ static void read_directory_shell(Entry* dir, HWND hwnd)
        if (!folder)
                return;
 
-       hr = (*folder->lpVtbl->EnumObjects)(folder, hwnd, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE, &idlist);
+       hr = IShellFolder_EnumObjects(folder, hwnd, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE, &idlist);
 
        if (SUCCEEDED(hr)) {
                for(;;) {
@@ -1006,7 +1015,7 @@ static void read_directory_shell(Entry* dir, HWND hwnd)
 
                        memset(pidls, 0, sizeof(pidls));
 
-                       hr = (*idlist->lpVtbl->Next)(idlist, FETCH_ITEM_COUNT, pidls, &cnt);
+                       hr = IEnumIDList_Next(idlist, FETCH_ITEM_COUNT, pidls, &cnt);
                        if (!SUCCEEDED(hr))
                                break;
 
@@ -1027,7 +1036,7 @@ static void read_directory_shell(Entry* dir, HWND hwnd)
 
                                attribs = ~SFGAO_FILESYSTEM;    /*SFGAO_HASSUBFOLDER|SFGAO_FOLDER; SFGAO_FILESYSTEM sorgt dafür, daß "My Documents" anstatt von "Martin's Documents" angezeigt wird */
 
-                               hr = (*folder->lpVtbl->GetAttributesOf)(folder, 1, (LPCITEMIDLIST*)&pidls[n], &attribs);
+                               hr = IShellFolder_GetAttributesOf(folder, 1, (LPCITEMIDLIST*)&pidls[n], &attribs);
 
                                if (SUCCEEDED(hr)) {
                                        if (attribs != (SFGAOF)~SFGAO_FILESYSTEM) {
@@ -1042,7 +1051,7 @@ static void read_directory_shell(Entry* dir, HWND hwnd)
                                entry->pidl = pidls[n];
 
                                if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-                                       hr = (*folder->lpVtbl->BindToObject)(folder, pidls[n], 0, &IID_IShellFolder, (void**)&child);
+                                       hr = IShellFolder_BindToObject(folder, pidls[n], 0, &IID_IShellFolder, (void**)&child);
 
                                        if (SUCCEEDED(hr))
                                                entry->folder = child;
@@ -1079,7 +1088,7 @@ static void read_directory_shell(Entry* dir, HWND hwnd)
                        }
                }
 
-               (*idlist->lpVtbl->Release)(idlist);
+               IEnumIDList_Release(idlist);
        }
 
        if (last)
@@ -1116,7 +1125,7 @@ static int TypeOrderFromDirname(LPCTSTR name)
 }
 
 /* directories first... */
-static int compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2)
+static int __cdecl compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2)
 {
        int order1 = fd1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY? TO_DIR: TO_FILE;
        int order2 = fd2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY? TO_DIR: TO_FILE;
@@ -1131,7 +1140,7 @@ static int compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2)
 }
 
 
-static int compareName(const void* arg1, const void* arg2)
+static int __cdecl compareName(const void* arg1, const void* arg2)
 {
        const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
        const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
@@ -1143,7 +1152,7 @@ static int compareName(const void* arg1, const void* arg2)
        return lstrcmpi(fd1->cFileName, fd2->cFileName);
 }
 
-static int compareExt(const void* arg1, const void* arg2)
+static int __cdecl compareExt(const void* arg1, const void* arg2)
 {
        const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
        const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
@@ -1176,7 +1185,7 @@ static int compareExt(const void* arg1, const void* arg2)
        return lstrcmpi(name1, name2);
 }
 
-static int compareSize(const void* arg1, const void* arg2)
+static int __cdecl compareSize(const void* arg1, const void* arg2)
 {
        const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
        const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
@@ -1197,7 +1206,7 @@ static int compareSize(const void* arg1, const void* arg2)
        return cmp<0? -1: cmp>0? 1: 0;
 }
 
-static int compareDate(const void* arg1, const void* arg2)
+static int __cdecl compareDate(const void* arg1, const void* arg2)
 {
        const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
        const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
@@ -1210,7 +1219,7 @@ static int compareDate(const void* arg1, const void* arg2)
 }
 
 
-static int (*sortFunctions[])(const void* arg1, const void* arg2) = {
+static int (__cdecl *sortFunctions[])(const void* arg1, const void* arg2) = {
        compareName,    /* SORT_NAME */
        compareExt,             /* SORT_EXT */
        compareSize,    /* SORT_SIZE */
@@ -1433,7 +1442,7 @@ static ChildWnd* alloc_child_window(LPCTSTR path, LPITEMIDLIST pidl, HWND hwnd)
                _tsplitpath(path, drv, dir, name, ext);
        }
 
-       _tcscpy(child->filter_pattern, sAsterics);
+       lstrcpy(child->filter_pattern, sAsterics);
        child->filter_flags = TF_ALL;
 
        root->entry.level = 0;
@@ -1484,7 +1493,7 @@ static void get_path(Entry* dir, PTSTR path)
                attribs = 0;
 
                if (dir->folder)
-                       hr = (*dir->folder->lpVtbl->GetAttributesOf)(dir->folder, 1, (LPCITEMIDLIST*)&dir->pidl, &attribs);
+                       hr = IShellFolder_GetAttributesOf(dir->folder, 1, (LPCITEMIDLIST*)&dir->pidl, &attribs);
 
                if (SUCCEEDED(hr) && (attribs&SFGAO_FILESYSTEM)) {
                        IShellFolder* parent = dir->up? dir->up->folder: Globals.iDesktop;
@@ -1610,7 +1619,7 @@ static LRESULT CALLBACK CBTProc(int code, WPARAM wparam, LPARAM lparam)
                newchild = NULL;
 
                child->hwnd = (HWND) wparam;
-               SetWindowLong(child->hwnd, GWL_USERDATA, (LPARAM)child);
+               SetWindowLongPtr(child->hwnd, GWLP_USERDATA, (LPARAM)child);
        }
 
        return CallNextHookEx(hcbthook, code, wparam, lparam);
@@ -1690,7 +1699,7 @@ static INT_PTR CALLBACK DestinationDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam,
 
        switch(nmsg) {
                case WM_INITDIALOG:
-                       SetWindowLong(hwnd, GWL_USERDATA, lparam);
+                       SetWindowLongPtr(hwnd, GWLP_USERDATA, lparam);
                        SetWindowText(GetDlgItem(hwnd, 201), (LPCTSTR)lparam);
                        return 1;
 
@@ -1699,7 +1708,7 @@ static INT_PTR CALLBACK DestinationDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam,
 
                        switch(id) {
                          case IDOK: {
-                               LPTSTR dest = (LPTSTR) GetWindowLong(hwnd, GWL_USERDATA);
+                               LPTSTR dest = (LPTSTR) GetWindowLongPtr(hwnd, GWLP_USERDATA);
                                GetWindowText(GetDlgItem(hwnd, 201), dest, MAX_PATH);
                                EndDialog(hwnd, id);
                                break;}
@@ -1814,12 +1823,12 @@ static void CheckForFileInfo(struct PropertiesDialog* dlg, HWND hwnd, LPCTSTR st
        static TCHAR sTranslation[] = {'\\','V','a','r','F','i','l','e','I','n','f','o','\\','T','r','a','n','s','l','a','t','i','o','n','\0'};
        static TCHAR sStringFileInfo[] = {'\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o','\\',
                                                                                '%','0','4','x','%','0','4','x','\\','%','s','\0'};
-       DWORD dwVersionDataLen = GetFileVersionInfoSize(strFilename, NULL);
+       DWORD dwVersionDataLen = GetFileVersionInfoSize((LPTSTR)strFilename, NULL);     /* VC6 and MinGW headers use LPTSTR instead of LPCTSTR */
 
        if (dwVersionDataLen) {
                dlg->pVersionData = malloc(dwVersionDataLen);
 
-               if (GetFileVersionInfo(strFilename, 0, dwVersionDataLen, dlg->pVersionData)) {
+               if (GetFileVersionInfo((LPTSTR)strFilename, 0, dwVersionDataLen, dlg->pVersionData)) {  /* VC6 and MinGW headers use LPTSTR instead of LPCTSTR */
                        LPVOID pVal;
                        UINT nValLen;
 
@@ -1901,7 +1910,7 @@ static INT_PTR CALLBACK PropertiesDialogDlgProc(HWND hwnd, UINT nmsg, WPARAM wpa
                        SetWindowText(GetDlgItem(hwnd, IDC_STATIC_PROP_LASTCHANGE), b1);
 
                        size = ((ULONGLONG)pWFD->nFileSizeHigh << 32) | pWFD->nFileSizeLow;
-                       wsprintf(b1, sLongNumFmt, size);
+                       _stprintf(b1, sLongNumFmt, size);
                        wsprintf(b2, sByteFmt, b1);
                        SetWindowText(GetDlgItem(hwnd, IDC_STATIC_PROP_SIZE), b2);
 
@@ -2077,7 +2086,7 @@ static BOOL activate_drive_window(LPCTSTR path)
 
        /* search for a already open window for the same drive */
        for(child_wnd=GetNextWindow(Globals.hmdiclient,GW_CHILD); child_wnd; child_wnd=GetNextWindow(child_wnd, GW_HWNDNEXT)) {
-               ChildWnd* child = (ChildWnd*) GetWindowLong(child_wnd, GWL_USERDATA);
+               ChildWnd* child = (ChildWnd*) GetWindowLongPtr(child_wnd, GWLP_USERDATA);
 
                if (child) {
                        _tsplitpath(child->root.path, drv2, 0, 0, 0);
@@ -2102,7 +2111,7 @@ static BOOL activate_fs_window(LPCTSTR filesys)
 
        /* search for a already open window of the given file system name */
        for(child_wnd=GetNextWindow(Globals.hmdiclient,GW_CHILD); child_wnd; child_wnd=GetNextWindow(child_wnd, GW_HWNDNEXT)) {
-               ChildWnd* child = (ChildWnd*) GetWindowLong(child_wnd, GWL_USERDATA);
+               ChildWnd* child = (ChildWnd*) GetWindowLongPtr(child_wnd, GWLP_USERDATA);
 
                if (child) {
                        if (!lstrcmpi(child->root.fs, filesys)) {
@@ -2137,9 +2146,7 @@ static LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM
                        break;
 
                case WM_DESTROY:
-                        /* don't exit desktop when closing file manager window */
-                       if (!Globals.hwndParent)
-                               PostQuitMessage(0);
+                       PostQuitMessage(0);
                        break;
 
                case WM_INITMENUPOPUP: {
@@ -2240,14 +2247,16 @@ static LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM
 
                                        if (ChooseFont(&chFont)) {
                                                HWND childWnd;
+                                               HFONT hFontOld;
 
+                                               DeleteObject(Globals.hfont);
                                                Globals.hfont = CreateFontIndirect(&lFont);
-                                               SelectFont(hdc, Globals.hfont);
+                                               hFontOld = SelectFont(hdc, Globals.hfont);
                                                GetTextExtentPoint32(hdc, sSpace, 1, &Globals.spaceSize);
 
                                                /* change font in all open child windows */
                                                for(childWnd=GetWindow(Globals.hmdiclient,GW_CHILD); childWnd; childWnd=GetNextWindow(childWnd,GW_HWNDNEXT)) {
-                                                       ChildWnd* child = (ChildWnd*) GetWindowLong(childWnd, GWL_USERDATA);
+                                                       ChildWnd* child = (ChildWnd*) GetWindowLongPtr(childWnd, GWLP_USERDATA);
                                                        SetWindowFont(child->left.hwnd, Globals.hfont, TRUE);
                                                        SetWindowFont(child->right.hwnd, Globals.hfont, TRUE);
                                                        ListBox_SetItemHeight(child->left.hwnd, 1, max(Globals.spaceSize.cy,IMAGE_HEIGHT+3));
@@ -2255,6 +2264,8 @@ static LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM
                                                        InvalidateRect(child->left.hwnd, NULL, TRUE);
                                                        InvalidateRect(child->right.hwnd, NULL, TRUE);
                                                }
+
+                                               SelectFont(hdc, hFontOld);
                                        }
                                        else if (CommDlgExtendedError()) {
                                                LoadString(Globals.hInstance, IDS_FONT_SEL_DLG_NAME, dlg_name, BUFFER_LEN);
@@ -2346,10 +2357,10 @@ static LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM
 
 
 #ifdef UNICODE
-                                       call_getcwd(cpath, MAX_PATH);
+                                       getcwd(cpath, MAX_PATH);
                                        MultiByteToWideChar(CP_UNIXCP, 0, cpath, -1, path, MAX_PATH);
 #else
-                                       call_getcwd(path, MAX_PATH);
+                                       getcwd(path, MAX_PATH);
 #endif
                                        child = alloc_child_window(path, NULL, hwnd);
 
@@ -2699,12 +2710,12 @@ static BOOL pattern_match(LPCTSTR str, LPCTSTR pattern)
                                return TRUE;
 
                        for(; *str; str++)
-                               if (_totupper(*str)==_totupper(*pattern) && pattern_match(str, pattern))
+                               if (*str==*pattern && pattern_match(str, pattern))
                                        return TRUE;
 
                        return FALSE;
                }
-               else if (_totupper(*str)!=_totupper(*pattern) && *pattern!='?')
+               else if (*str!=*pattern && *pattern!='?')
                        return FALSE;
        }
 
@@ -2715,6 +2726,18 @@ static BOOL pattern_match(LPCTSTR str, LPCTSTR pattern)
        return TRUE;
 }
 
+static BOOL pattern_imatch(LPCTSTR str, LPCTSTR pattern)
+{
+       TCHAR b1[BUFFER_LEN], b2[BUFFER_LEN];
+
+       lstrcpy(b1, str);
+       lstrcpy(b2, pattern);
+       CharUpper(b1);
+       CharUpper(b2);
+
+       return pattern_match(b1, b2);
+}
+
 
 enum FILE_TYPE {
        FT_OTHER                = 0,
@@ -2759,7 +2782,7 @@ static int insert_entries(Pane* pane, Entry* dir, LPCTSTR pattern, int filter_fl
 
                /* filter using the file name pattern */
                if (pattern)
-                       if (!pattern_match(entry->data.cFileName, pattern))
+                       if (!pattern_imatch(entry->data.cFileName, pattern))
                                continue;
 
                /* filter system and hidden files */
@@ -2807,12 +2830,21 @@ static void format_bytes(LPTSTR buffer, LONGLONG bytes)
 
        float fBytes = (float)bytes;
 
+#ifdef __WINE__        /* work around for incorrect implementation of wsprintf()/_stprintf() in WINE */
+       if (bytes >= 1073741824)        /* 1 GB */
+               wsprintf(buffer, sFmtGB, fBytes/1073741824.f+.5f);
+       else if (bytes >= 1048576)      /* 1 MB */
+               wsprintf(buffer, sFmtMB, fBytes/1048576.f+.5f);
+       else if (bytes >= 1024)         /* 1 kB */
+               wsprintf(buffer, sFmtkB, fBytes/1024.f+.5f);
+#else
        if (bytes >= 1073741824)        /* 1 GB */
                _stprintf(buffer, sFmtGB, fBytes/1073741824.f+.5f);
        else if (bytes >= 1048576)      /* 1 MB */
                _stprintf(buffer, sFmtMB, fBytes/1048576.f+.5f);
        else if (bytes >= 1024)         /* 1 kB */
                _stprintf(buffer, sFmtkB, fBytes/1024.f+.5f);
+#endif
        else
                _stprintf(buffer, sLongNumFmt, bytes);
 }
@@ -2825,9 +2857,9 @@ static void set_space_status(void)
        if (GetDiskFreeSpaceEx(NULL, &ulFreeBytesToCaller, &ulTotalBytes, &ulFreeBytes)) {
                format_bytes(b1, ulFreeBytesToCaller.QuadPart);
                format_bytes(b2, ulTotalBytes.QuadPart);
-               _stprintf(buffer, RS(fmt,IDS_FREE_SPACE_FMT), b1, b2);
+               wsprintf(buffer, RS(fmt,IDS_FREE_SPACE_FMT), b1, b2);
        } else
-               _tcscpy(buffer, sQMarks);
+               lstrcpy(buffer, sQMarks);
 
        SendMessage(Globals.hstatusbar, SB_SETTEXT, 0, (LPARAM)buffer);
 }
@@ -2846,7 +2878,7 @@ static void create_tree_window(HWND parent, Pane* pane, int id, int id_header, L
                                                                LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY,
                                                                0, 0, 0, 0, parent, (HMENU)id, Globals.hInstance, 0);
 
-       SetWindowLong(pane->hwnd, GWL_USERDATA, (LPARAM)pane);
+       SetWindowLongPtr(pane->hwnd, GWLP_USERDATA, (LPARAM)pane);
        g_orgTreeWndProc = SubclassWindow(pane->hwnd, TreeWndProc);
 
        SetWindowFont(pane->hwnd, Globals.hfont, FALSE);
@@ -2888,7 +2920,7 @@ static void format_date(const FILETIME* ft, TCHAR* buffer, int visible_cols)
                return;
 
        if (!FileTimeToLocalFileTime(ft, &lft))
-               {err: _tcscpy(buffer,sQMarks); return;}
+               {err: lstrcpy(buffer,sQMarks); return;}
 
        if (!FileTimeToSystemTime(&lft, &systime))
                goto err;
@@ -3021,7 +3053,7 @@ static BOOL is_exe_file(LPCTSTR ext)
                d++;
 
        for(p=executable_extensions; (*p)[0]; p++)
-               if (!_tcsicmp(ext_buffer, *p))
+               if (!lstrcmpi(ext_buffer, *p))
                        return TRUE;
 
        return FALSE;
@@ -3193,10 +3225,10 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi
                        textcolor = RGB(0,0,0);
 
                if (dis->itemState & ODS_FOCUS) {
-                       textcolor = RGB(255,255,255);
+                       textcolor = COLOR_SELECTION_TXT;
                        bkcolor = COLOR_SELECTION;
                } else {
-                       bkcolor = RGB(255,255,255);
+                       bkcolor = GetSysColor(COLOR_WINDOW);
                }
 
                hbrush = CreateSolidBrush(bkcolor);
@@ -3325,10 +3357,10 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi
        if (visible_cols & COL_ATTRIBUTES) {
 #ifdef _NO_EXTENSIONS
                const static TCHAR s4Tabs[] = {' ','\t',' ','\t',' ','\t',' ','\t',' ','\0'};
-               _tcscpy(buffer, s4Tabs);
+               lstrcpy(buffer, s4Tabs);
 #else
                const static TCHAR s11Tabs[] = {' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\0'};
-               _tcscpy(buffer, s11Tabs);
+               lstrcpy(buffer, s11Tabs);
 #endif
 
                if (attrs & FILE_ATTRIBUTE_NORMAL)                                      buffer[ 0] = 'N';
@@ -3370,7 +3402,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi
 
                DWORD rights = get_access_mask();
 
-               tcscpy(buffer, sSecTabs);
+               lstrcpy(buffer, sSecTabs);
 
                if (rights & FILE_READ_DATA)                    buffer[ 0] = 'R';
                if (rights & FILE_WRITE_DATA)                   buffer[ 2] = 'W';
@@ -3405,7 +3437,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi
                HPEN lastPen;
                HPEN hpen;
 
-               if (!(GetVersion() & 0x80000000)) {     /* Windows NT? */
+               if (!(GetVersion() & 0x80000000)) {     /* Windows NT or higher? */
                        LOGBRUSH lb = {PS_SOLID, RGB(255,255,255)};
                        hpen = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lb, 0, 0);
                } else
@@ -3677,6 +3709,9 @@ static void set_curdir(ChildWnd* child, Entry* entry, int idx, HWND hwnd)
 {
        TCHAR path[MAX_PATH];
 
+       if (!entry)
+               return;
+
        path[0] = '\0';
 
        child->left.cur = entry;
@@ -3828,20 +3863,6 @@ static BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow)
        return TRUE;
 }
 
-#ifdef UNICODE
-static BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow)
-{
-       HINSTANCE hinst = ShellExecuteA(hwnd, NULL/*operation*/, cmd, NULL/*parameters*/, NULL/*dir*/, nCmdShow);
-
-       if ((int)hinst <= 32) {
-               display_error(hwnd, GetLastError());
-               return FALSE;
-       }
-
-       return TRUE;
-}
-#endif
-
 
 static BOOL launch_entry(Entry* entry, HWND hwnd, UINT nCmdShow)
 {
@@ -3869,7 +3890,7 @@ static BOOL launch_entry(Entry* entry, HWND hwnd, UINT nCmdShow)
                }
 
                if (shexinfo.lpIDList != entry->pidl)
-                       (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, shexinfo.lpIDList);
+                       IMalloc_Free(Globals.iMalloc, shexinfo.lpIDList);
 
                return ret;
        }
@@ -4069,15 +4090,15 @@ static IContextMenu* CtxMenu_query_interfaces(IContextMenu* pcm1)
        CtxMenu_reset();
 
 #ifndef __MINGW32__    /* IContextMenu3 missing in MinGW (as of 6.2.2005) */
-       if ((*pcm1->lpVtbl->QueryInterface)(pcm1, &IID_IContextMenu3, (void**)&pcm) == NOERROR)
+       if (IUnknown_QueryInterface(pcm1, &IID_IContextMenu3, (void**)&pcm) == NOERROR)
                s_pctxmenu3 = (LPCONTEXTMENU3)pcm;
        else
 #endif
-       if ((*pcm1->lpVtbl->QueryInterface)(pcm1, &IID_IContextMenu2, (void**)&pcm) == NOERROR)
+       if (IUnknown_QueryInterface(pcm1, &IID_IContextMenu2, (void**)&pcm) == NOERROR)
                s_pctxmenu2 = (LPCONTEXTMENU2)pcm;
 
        if (pcm) {
-               (*pcm1->lpVtbl->Release)(pcm1);
+               IUnknown_Release(pcm1);
                return pcm;
        } else
                return pcm1;
@@ -4105,7 +4126,7 @@ static HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParen
        IContextMenu* pcm;
        BOOL executed = FALSE;
 
-       HRESULT hr = (*shell_folder->lpVtbl->GetUIObjectOf)(shell_folder, hwndParent, cidl, apidl, &IID_IContextMenu, NULL, (LPVOID*)&pcm);
+       HRESULT hr = IShellFolder_GetUIObjectOf(shell_folder, hwndParent, cidl, apidl, &IID_IContextMenu, NULL, (LPVOID*)&pcm);
 /*     HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm); */
 
        if (SUCCEEDED(hr)) {
@@ -4141,7 +4162,7 @@ static HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParen
                                CtxMenu_reset();
                }
 
-               (*pcm->lpVtbl->Release)(pcm);
+               IUnknown_Release(pcm);
        }
 
        return FAILED(hr)? hr: executed? S_OK: S_FALSE;
@@ -4150,7 +4171,7 @@ static HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParen
 
 static LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
 {
-       ChildWnd* child = (ChildWnd*) GetWindowLong(hwnd, GWL_USERDATA);
+       ChildWnd* child = (ChildWnd*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
        ASSERT(child);
 
        switch(nmsg) {
@@ -4173,7 +4194,7 @@ static LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM
 
                case WM_NCDESTROY:
                        free_child_window(child);
-                       SetWindowLong(hwnd, GWL_USERDATA, 0);
+                       SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
                        break;
 
                case WM_PAINT: {
@@ -4396,11 +4417,11 @@ static LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM
                                        struct FilterDialog dlg;
 
                                        memset(&dlg, 0, sizeof(struct FilterDialog));
-                                       _tcscpy(dlg.pattern, child->filter_pattern);
+                                       lstrcpy(dlg.pattern, child->filter_pattern);
                                        dlg.flags = child->filter_flags;
 
                                        if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_VIEW_TYPE), hwnd, FilterDialogDlgProc, (LPARAM)&dlg) == IDOK) {
-                                               _tcscpy(child->filter_pattern, dlg.pattern);
+                                               lstrcpy(child->filter_pattern, dlg.pattern);
                                                child->filter_flags = dlg.flags;
                                                refresh_right_pane(child);
                                        }
@@ -4482,10 +4503,10 @@ static LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM
                                                if (ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pt.x, pt.y) == S_OK)
                                                        refresh_child(child);
 
-                                               (*parentFolder->lpVtbl->Release)(parentFolder);
+                                               IShellFolder_Release(parentFolder);
                                        }
 
-                                       (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, pidl_abs);
+                                       IMalloc_Free(Globals.iMalloc, pidl_abs);
                                }
                        }
                        break;}
@@ -4534,8 +4555,8 @@ static LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM
 
 static LRESULT CALLBACK TreeWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
 {
-       ChildWnd* child = (ChildWnd*) GetWindowLong(GetParent(hwnd), GWL_USERDATA);
-       Pane* pane = (Pane*) GetWindowLong(hwnd, GWL_USERDATA);
+       ChildWnd* child = (ChildWnd*) GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+       Pane* pane = (Pane*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
        ASSERT(child);
 
        switch(nmsg) {
@@ -4660,11 +4681,11 @@ static void InitInstance(HINSTANCE hinstance)
 }
 
 
-static void show_frame(HWND hwndParent, int cmdshow)
+static void show_frame(HWND hwndParent, int cmdshow, LPCTSTR path)
 {
        const static TCHAR sMDICLIENT[] = {'M','D','I','C','L','I','E','N','T','\0'};
 
-       TCHAR path[MAX_PATH], b1[BUFFER_LEN];
+       TCHAR buffer[MAX_PATH], b1[BUFFER_LEN];
        ChildWnd* child;
        HMENU hMenuFrame, hMenuWindow;
 
@@ -4673,8 +4694,6 @@ static void show_frame(HWND hwndParent, int cmdshow)
        if (Globals.hMainWnd)
                return;
 
-       Globals.hwndParent = hwndParent;
-
        hMenuFrame = LoadMenu(Globals.hInstance, MAKEINTRESOURCE(IDM_WINEFILE));
        hMenuWindow = GetSubMenu(hMenuFrame, GetMenuItemCount(hMenuFrame)-2);
 
@@ -4729,7 +4748,11 @@ static void show_frame(HWND hwndParent, int cmdshow)
                                        Globals.hMainWnd, (HMENU)IDW_STATUSBAR, hinstance, 0);*/
 
        /*TODO: read paths and window placements from registry */
-       GetCurrentDirectory(MAX_PATH, path);
+
+       if (!path || !*path) {
+               GetCurrentDirectory(MAX_PATH, buffer);
+               path = buffer;
+       }
 
        ShowWindow(Globals.hMainWnd, cmdshow);
 
@@ -4761,11 +4784,12 @@ static void show_frame(HWND hwndParent, int cmdshow)
 static void ExitInstance(void)
 {
 #ifdef _SHELL_FOLDERS
-       (*Globals.iDesktop->lpVtbl->Release)(Globals.iDesktop);
-       (*Globals.iMalloc->lpVtbl->Release)(Globals.iMalloc);
+       IShellFolder_Release(Globals.iDesktop);
+       IMalloc_Release(Globals.iMalloc);
        CoUninitialize();
 #endif
 
+       DeleteObject(Globals.hfont);
        ImageList_Destroy(Globals.himl);
 }
 
@@ -4802,7 +4826,7 @@ static int find_window_class(LPCTSTR classname)
 
 #endif
 
-static int winefile_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow)
+static int winefile_main(HINSTANCE hinstance, int cmdshow, LPCTSTR path)
 {
        MSG msg;
 
@@ -4812,7 +4836,7 @@ static int winefile_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow)
                /*TODO: read window placement from registry */
                cmdshow = SW_MAXIMIZE;
 
-       show_frame(hwndParent, cmdshow);
+       show_frame(0, cmdshow, path);
 
        while(GetMessage(&msg, 0, 0, 0)) {
                if (Globals.hmdiclient && TranslateMDISysAccel(Globals.hmdiclient, &msg))
@@ -4831,17 +4855,26 @@ static int winefile_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow)
 }
 
 
-int APIENTRY WinMain(HINSTANCE hinstance,
-                                        HINSTANCE previnstance,
-                                        LPSTR     cmdline,
-                                        int       cmdshow)
+#if defined(UNICODE) && defined(_MSC_VER)
+int APIENTRY wWinMain(HINSTANCE hinstance, HINSTANCE previnstance, LPWSTR cmdline, int cmdshow)
+#else
+int APIENTRY WinMain(HINSTANCE hinstance, HINSTANCE previnstance, LPSTR cmdline, int cmdshow)
+#endif
 {
 #ifdef _NO_EXTENSIONS
        if (find_window_class(sWINEFILEFRAME))
                return 1;
 #endif
 
-       winefile_main(hinstance, 0, cmdshow);
+#if defined(UNICODE) && !defined(_MSC_VER)
+       { /* convert ANSI cmdline into WCS path string */
+       TCHAR buffer[MAX_PATH];
+       MultiByteToWideChar(CP_ACP, 0, cmdline, -1, buffer, MAX_PATH);
+       winefile_main(hinstance, cmdshow, buffer);
+       }
+#else
+       winefile_main(hinstance, cmdshow, cmdline);
+#endif
 
        return 0;
 }