HRESULT TRASH_RestoreItem(LPCITEMIDLIST pidl){ int suffix_length = strlen(trashinfo_suffix); LPCSHITEMID id = &(pidl->mkid); const char *bucket_name = (const char*)(id->abID+1+sizeof(WIN32_FIND_DATAW)); const char *filename = (const char*)(id->abID+1+sizeof(WIN32_FIND_DATAW)+strlen(bucket_name)+1); char *restore_path; WIN32_FIND_DATAW data; char *file_path; TRACE("(%p)\n",pidl); if(strcmp(filename+strlen(filename)-suffix_length,trashinfo_suffix)) { ERR("pidl at %p is not a valid recycle bin entry\n",pidl); return E_INVALIDARG; } TRASH_UnpackItemID(id,&data); restore_path = wine_get_unix_file_name(data.cFileName); file_path = SHAlloc(max(strlen(home_trash->files_dir),strlen(home_trash->info_dir))+strlen(filename)+1); sprintf(file_path,"%s%s",home_trash->files_dir,filename); file_path[strlen(home_trash->files_dir)+strlen(filename)-suffix_length] = '\0'; if(!rename(file_path,restore_path)) { sprintf(file_path,"%s%s",home_trash->info_dir,filename); if(unlink(file_path)) WARN("failed to delete the trashinfo file %s\n",filename); } else WARN("could not erase %s from the trash (errno=%i)\n",filename,errno); SHFree(file_path); heap_free(restore_path); return S_OK; }
static BOOL appbundle_init(void) { WCHAR shellDesktopPath[MAX_PATH]; HRESULT hr = SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, shellDesktopPath); if (SUCCEEDED(hr)) mac_desktop_dir = wine_get_unix_file_name(shellDesktopPath); if (mac_desktop_dir == NULL) { WINE_ERR("error looking up the desktop directory\n"); return FALSE; } if (getenv("WINE_APPLICATIONS_DIR")) wine_applications_dir = strdupA(getenv("WINE_APPLICATIONS_DIR")); else wine_applications_dir = heap_printf("%s/Applications/Wine", getenv("HOME")); if (!wine_applications_dir) return FALSE; create_directories(wine_applications_dir); WINE_TRACE("Applications in %s\n", wine_applications_dir); return TRUE; }
/*********************************************************************** * start_dosbox */ static void start_dosbox( const char *appname, const char *args ) { static const WCHAR cfgW[] = {'c','f','g',0}; const char *config_dir = wine_get_config_dir(); WCHAR path[MAX_PATH], config[MAX_PATH]; HANDLE file; char *p, *buffer, app[MAX_PATH]; int i; int ret = 1; DWORD written, drives = GetLogicalDrives(); char *dosbox = find_dosbox(); if (!dosbox) return; if (!GetTempPathW( MAX_PATH, path )) return; if (!GetTempFileNameW( path, cfgW, 0, config )) return; if (!GetCurrentDirectoryW( MAX_PATH, path )) return; if (!GetShortPathNameA( appname, app, MAX_PATH )) return; GetShortPathNameW( path, path, MAX_PATH ); file = CreateFileW( config, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); if (file == INVALID_HANDLE_VALUE) return; buffer = HeapAlloc( GetProcessHeap(), 0, sizeof("[autoexec]") + sizeof("mount -z c") + sizeof("config -securemode") + 25 * (strlen(config_dir) + sizeof("mount c /dosdevices/c:")) + 4 * strlenW( path ) + 6 + strlen( app ) + strlen( args ) + 20 ); p = buffer; p += sprintf( p, "[autoexec]\n" ); for (i = 25; i >= 0; i--) if (!(drives & (1 << i))) { p += sprintf( p, "mount -z %c\n", 'a' + i ); break; } for (i = 0; i <= 25; i++) if (drives & (1 << i)) p += sprintf( p, "mount %c %s/dosdevices/%c:\n", 'a' + i, config_dir, 'a' + i ); p += sprintf( p, "%c:\ncd ", path[0] ); p += WideCharToMultiByte( CP_UNIXCP, 0, path + 2, -1, p, 4 * strlenW(path), NULL, NULL ) - 1; p += sprintf( p, "\nconfig -securemode\n" ); p += sprintf( p, "%s %s\n", app, args ); p += sprintf( p, "exit\n" ); if (WriteFile( file, buffer, strlen(buffer), &written, NULL ) && written == strlen(buffer)) { const char *args[5]; char *config_file = wine_get_unix_file_name( config ); args[0] = dosbox; args[1] = "-userconf"; args[2] = "-conf"; args[3] = config_file; args[4] = NULL; ret = _spawnvp( _P_WAIT, args[0], args ); } CloseHandle( file ); DeleteFileW( config ); HeapFree( GetProcessHeap(), 0, buffer ); ExitProcess( ret ); }
static void apply_shell_folder_changes(void) { WCHAR wszPath[MAX_PATH]; char szBackupPath[FILENAME_MAX], szUnixPath[FILENAME_MAX], *pszUnixPath = NULL; int i; struct stat statPath; HRESULT hr; for (i=0; i<NUM_ELEMS(asfiInfo); i++) { /* Ignore nonexistent link targets */ if (asfiInfo[i].szLinkTarget[0] && stat(asfiInfo[i].szLinkTarget, &statPath)) continue; hr = SHGetFolderPathW(NULL, asfiInfo[i].nFolder|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, wszPath); if (FAILED(hr)) continue; /* Retrieve the corresponding unix path. */ pszUnixPath = wine_get_unix_file_name(wszPath); if (!pszUnixPath) continue; lstrcpyA(szUnixPath, pszUnixPath); HeapFree(GetProcessHeap(), 0, pszUnixPath); /* Derive name for folder backup. */ lstrcpyA(szBackupPath, szUnixPath); lstrcatA(szBackupPath, ".winecfg"); if (lstat(szUnixPath, &statPath)) continue; /* Move old folder/link out of the way. */ if (S_ISLNK(statPath.st_mode)) { if (unlink(szUnixPath)) continue; /* Unable to remove link. */ } else { if (!*asfiInfo[i].szLinkTarget) { continue; /* We are done. Old was real folder, as new shall be. */ } else { if (rename(szUnixPath, szBackupPath)) { /* Move folder out of the way. */ continue; /* Unable to move old folder. */ } } } /* Create new link/folder. */ if (*asfiInfo[i].szLinkTarget) { symlink(asfiInfo[i].szLinkTarget, szUnixPath); } else { /* If there's a backup folder, restore it. Else create new folder. */ if (!lstat(szBackupPath, &statPath) && S_ISDIR(statPath.st_mode)) { rename(szBackupPath, szUnixPath); } else { mkdir(szUnixPath, 0777); } } } }
/*********************************************************************** * start_dosbox */ static void start_dosbox( const char *appname, const char *args ) { static const WCHAR cfgW[] = {'c','f','g',0}; const char *config_dir = wine_get_config_dir(); WCHAR path[MAX_PATH], config[MAX_PATH]; HANDLE file; char *p, *buffer; int i; int ret = 1; DWORD written, drives = GetLogicalDrives(); char *dosbox = find_dosbox(); if (!dosbox) return; if (tolower(appname[0]) == 'z') { WINE_MESSAGE( "winevdm: Cannot start DOS application %s\n", appname ); WINE_MESSAGE( " because DOSBox doesn't support running from the Z: drive.\n" ); ExitProcess(1); } if (!GetTempPathW( MAX_PATH, path )) return; if (!GetTempFileNameW( path, cfgW, 0, config )) return; if (!GetCurrentDirectoryW( MAX_PATH, path )) return; file = CreateFileW( config, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); if (file == INVALID_HANDLE_VALUE) return; buffer = HeapAlloc( GetProcessHeap(), 0, sizeof("[autoexec]") + 25 * (strlen(config_dir) + sizeof("mount c /dosdevices/c:")) + 4 * strlenW( path ) + 6 + strlen( appname ) + strlen( args ) + 20 ); p = buffer; p += sprintf( p, "[autoexec]\n" ); for (i = 0; i < 25; i++) if (drives & (1 << i)) p += sprintf( p, "mount %c %s/dosdevices/%c:\n", 'a' + i, config_dir, 'a' + i ); p += sprintf( p, "%c:\ncd ", path[0] ); p += WideCharToMultiByte( CP_UNIXCP, 0, path + 2, -1, p, 4 * strlenW(path), NULL, NULL ) - 1; p += sprintf( p, "\n%s %s\n", appname, args ); p += sprintf( p, "exit\n" ); if (WriteFile( file, buffer, strlen(buffer), &written, NULL ) && written == strlen(buffer)) { const char *args[4]; char *config_file = wine_get_unix_file_name( config ); args[0] = dosbox; args[1] = "-conf"; args[2] = config_file; args[3] = NULL; ret = spawnvp( _P_WAIT, args[0], args ); } CloseHandle( file ); DeleteFileW( config ); HeapFree( GetProcessHeap(), 0, buffer ); ExitProcess( ret ); }
BOOL TRASH_TrashFile(LPCWSTR wszPath) { char *unix_path; BOOL result; TRACE("(%s)\n", debugstr_w(wszPath)); if (!TRASH_EnsureInitialized()) return FALSE; if (!(unix_path = wine_get_unix_file_name(wszPath))) return FALSE; result = TRASH_MoveFileToBucket(home_trash, unix_path); heap_free(unix_path); return result; }
BOOL TRASH_TrashFile(LPCWSTR wszPath) { char *unix_path; OSStatus status; TRACE("(%s)\n", debugstr_w(wszPath)); if (!(unix_path = wine_get_unix_file_name(wszPath))) return FALSE; status = FSPathMoveObjectToTrashSync(unix_path, NULL, kFSFileOperationSkipPreflight); heap_free(unix_path); return (status == noErr); }
BOOL TRASH_CanTrashFile(LPCWSTR wszPath) { struct stat file_stat; char *unix_path; int ret; TRACE("(%s)\n", debugstr_w(wszPath)); if (!TRASH_EnsureInitialized()) return FALSE; if (!(unix_path = wine_get_unix_file_name(wszPath))) return FALSE; ret = lstat(unix_path, &file_stat); heap_free(unix_path); if (ret == -1) return FALSE; return file_good_for_bucket(home_trash, &file_stat); }
BOOL TRASH_CanTrashFile(LPCWSTR wszPath) { struct stat file_stat; char *unix_path; TRACE("(%s)\n", debugstr_w(wszPath)); if (!TRASH_EnsureInitialized()) return FALSE; if (!(unix_path = wine_get_unix_file_name(wszPath))) return FALSE; if (lstat(unix_path, &file_stat)==-1) { HeapFree(GetProcessHeap(), 0, unix_path); return FALSE; } HeapFree(GetProcessHeap(), 0, unix_path); return file_good_for_bucket(home_trash, &file_stat); }
BOOL TRASH_CanTrashFile(LPCWSTR wszPath) { char *unix_path; OSStatus status; FSRef ref; FSCatalogInfo catalogInfo; TRACE("(%s)\n", debugstr_w(wszPath)); if (!(unix_path = wine_get_unix_file_name(wszPath))) return FALSE; status = FSPathMakeRef((UInt8*)unix_path, &ref, NULL); heap_free(unix_path); if (status == noErr) status = FSGetCatalogInfo(&ref, kFSCatInfoVolume, &catalogInfo, NULL, NULL, NULL); if (status == noErr) status = FSFindFolder(catalogInfo.volume, kTrashFolderType, kCreateFolder, &ref); return (status == noErr); }
/* Reads the currently set shell folder symbol link targets into asfiInfo. */ static void read_shell_folder_link_targets(void) { WCHAR wszPath[MAX_PATH]; HRESULT hr; int i; for (i=0; i<NUM_ELEMS(asfiInfo); i++) { asfiInfo[i].szLinkTarget[0] = '\0'; hr = SHGetFolderPathW(NULL, asfiInfo[i].nFolder|CSIDL_FLAG_DONT_VERIFY, NULL, SHGFP_TYPE_CURRENT, wszPath); if (SUCCEEDED(hr)) { char *pszUnixPath = wine_get_unix_file_name(wszPath); if (pszUnixPath) { struct stat statPath; if (!lstat(pszUnixPath, &statPath) && S_ISLNK(statPath.st_mode)) { int cLen = readlink(pszUnixPath, asfiInfo[i].szLinkTarget, FILENAME_MAX-1); if (cLen >= 0) asfiInfo[i].szLinkTarget[cLen] = '\0'; } HeapFree(GetProcessHeap(), 0, pszUnixPath); } } } }
HRESULT TRASH_EnumItems(const WCHAR *path, LPITEMIDLIST **pidls, int *count) { WCHAR volume_path[MAX_PATH]; char *unix_path, trash_path[MAX_PATH]; FSCatalogInfo catalog_info; OSStatus status; FSRef ref; struct dirent *entry; DIR *dir; LPITEMIDLIST *ret; int i=0, ret_size=8; HRESULT hr; TRACE("(%s %p %p)\n", debugstr_w(path), pidls, count); if(!path) { FIXME("All trashes enumeration not supported\n"); volume_path[0] = 'C'; volume_path[1] = ':'; volume_path[2] = 0; } else { if(!GetVolumePathNameW(path, volume_path, MAX_PATH)) return E_FAIL; } if(!(unix_path = wine_get_unix_file_name(volume_path))) return E_OUTOFMEMORY; status = FSPathMakeRef((UInt8*)unix_path, &ref, NULL); heap_free(unix_path); if(status != noErr) return E_FAIL; status = FSGetCatalogInfo(&ref, kFSCatInfoVolume, &catalog_info, NULL, NULL, NULL); if(status != noErr) return E_FAIL; status = FSFindFolder(catalog_info.volume, kTrashFolderType, kCreateFolder, &ref); if(status != noErr) return E_FAIL; status = FSRefMakePath(&ref, (UInt8*)trash_path, MAX_PATH); if(status != noErr) return E_FAIL; if(!(dir = opendir(trash_path))) return E_FAIL; ret = heap_alloc(ret_size * sizeof(*ret)); if(!ret) { closedir(dir); return E_OUTOFMEMORY; } while((entry = readdir(dir))) { WIN32_FIND_DATAW data; if(!lstrcmpA(entry->d_name, ".") || !lstrcmpA(entry->d_name, ".." ) || !lstrcmpA(entry->d_name, ".DS_Store")) continue; if(i == ret_size) { LPITEMIDLIST *resized; ret_size *= 2; resized = heap_realloc(ret, ret_size * sizeof(*ret)); if(!resized) hr = E_OUTOFMEMORY; else ret = resized; } if(SUCCEEDED(hr)) { hr = TRASH_GetDetails(trash_path, entry->d_name, &data); if(hr == S_FALSE) continue; } if(SUCCEEDED(hr)) hr = TRASH_CreateSimplePIDL(entry->d_name, &data, ret+i); if(FAILED(hr)) { while(i>0) SHFree(ret+(--i)); heap_free(ret); closedir(dir); return hr; } i++; } closedir(dir); *pidls = SHAlloc(sizeof(**pidls) * i); if(!*pidls) { while(i>0) SHFree(ret+(--i)); heap_free(ret); return E_OUTOFMEMORY; } *count = i; for(i--; i>=0; i--) (*pidls)[i] = ret[i]; heap_free(ret); return S_OK; }
static int CreateSpoolFile(LPCSTR pszOutput) { int fd=-1; char psCmd[1024]; char *psCmdP = psCmd; /* TTD convert the 'output device' into a spool file name */ if (pszOutput == NULL || *pszOutput == '\0') return -1; if (!strncmp("LPR:",pszOutput,4)) sprintf(psCmd,"|lpr -P%s",pszOutput+4); else { HKEY hkey; /* default value */ psCmd[0] = 0; if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\spooler", &hkey)) { DWORD type, count = sizeof(psCmd); RegQueryValueExA(hkey, pszOutput, 0, &type, psCmd, &count); RegCloseKey(hkey); } } TRACE("Got printerSpoolCommand '%s' for output device '%s'\n", psCmd, pszOutput); if (!*psCmd) psCmdP = (char *)pszOutput; else { while (*psCmdP && isspace(*psCmdP)) { psCmdP++; }; if (!*psCmdP) return -1; } if (*psCmdP == '|') { int fds[2]; if (pipe(fds)) return -1; if (fork() == 0) { psCmdP++; TRACE("In child need to exec %s\n",psCmdP); close(0); dup2(fds[0],0); close (fds[1]); signal (SIGPIPE, SIG_DFL); signal (SIGCHLD, SIG_DFL); execl ("/bin/sh", "/bin/sh", "-c", psCmdP, NULL); _exit (1); } close (fds[0]); fd = fds[1]; TRACE("Need to execute a cmnd and pipe the output to it\n"); } else { char buffer[MAX_PATH]; TRACE("Just assume it's a file\n"); /** * The file name can be dos based, we have to find its * Unix correspondant file name */ wine_get_unix_file_name(psCmdP, buffer, sizeof(buffer)); if ((fd = open(buffer, O_CREAT | O_TRUNC | O_WRONLY , 0600)) < 0) { ERR("Failed to create spool file '%s' ('%s'). (error %s)\n", buffer, psCmdP, strerror(errno)); } } return fd; }
static int CreateSpoolFile(LPCSTR pszOutput, pid_t *out_pid) { int fd=-1; char psCmd[1024]; const char *psCmdP = psCmd; HKEY hkey; /* TTD convert the 'output device' into a spool file name */ if (pszOutput == NULL || *pszOutput == '\0' || out_pid == NULL) return -1; *out_pid = -1; psCmd[0] = 0; /* @@ Wine registry key: HKCU\Software\Wine\Printing\Spooler */ if(!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Printing\\Spooler", &hkey)) { DWORD type, count = sizeof(psCmd); RegQueryValueExA(hkey, pszOutput, 0, &type, (LPBYTE)psCmd, &count); RegCloseKey(hkey); } if (!psCmd[0] && !strncmp("LPR:",pszOutput,4)) sprintf(psCmd,"|lpr -P'%s'",pszOutput+4); TRACE("Got printerSpoolCommand '%s' for output device '%s'\n", psCmd, pszOutput); if (!*psCmd) psCmdP = pszOutput; else { while (*psCmdP && isspace(*psCmdP)) { psCmdP++; } if (!*psCmdP) return -1; } TRACE("command: '%s'\n", psCmdP); #ifdef HAVE_FORK if (*psCmdP == '|') { int fds[2]; if (pipe(fds)) { ERR("pipe() failed!\n"); return -1; } if ((*out_pid = fork()) == 0) { psCmdP++; TRACE("In child need to exec %s\n",psCmdP); close(0); dup2(fds[0],0); close (fds[1]); /* reset signals that we previously set to SIG_IGN */ signal( SIGPIPE, SIG_DFL ); execl("/bin/sh", "/bin/sh", "-c", psCmdP, NULL); _exit(1); } close (fds[0]); fd = fds[1]; TRACE("Need to execute a cmnd and pipe the output to it\n"); } else #endif { char *buffer; WCHAR psCmdPW[MAX_PATH]; TRACE("Just assume it's a file\n"); /** * The file name can be dos based, we have to find its * corresponding Unix file name. */ MultiByteToWideChar(CP_ACP, 0, psCmdP, -1, psCmdPW, MAX_PATH); if ((buffer = wine_get_unix_file_name(psCmdPW))) { if ((fd = open(buffer, O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0) { ERR("Failed to create spool file '%s' ('%s'). (error %s)\n", buffer, psCmdP, strerror(errno)); } HeapFree(GetProcessHeap(), 0, buffer); } } return fd; }