/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp) { DRIVE_FILE* file; UINT32 FsInformationClass; UINT32 Length; Stream_Read_UINT32(irp->input, FsInformationClass); Stream_Read_UINT32(irp->input, Length); Stream_Seek(irp->input, 24); /* Padding */ file = drive_get_file_by_id(drive, irp->FileId); if (!file) { irp->IoStatus = STATUS_UNSUCCESSFUL; } else if (!drive_file_set_information(file, FsInformationClass, Length, irp->input)) { irp->IoStatus = STATUS_UNSUCCESSFUL; } if (file && file->is_dir && !dir_empty(file->fullpath)) irp->IoStatus = STATUS_DIRECTORY_NOT_EMPTY; Stream_Write_UINT32(irp->output, Length); return irp->Complete(irp); }
bool Desktop::remove_icon(DesktopIcon *di, bool real_delete) { bool ret = true; if(real_delete) { if(di->get_icon_type() == DESKTOP_ICON_TYPE_FOLDER) { if(!dir_empty(di->get_path())) { alert(_("This folder is not empty. Recursive removal of not empty folders is not yet supported")); return false; } ret = dir_remove(di->get_path()); } else { ret = file_remove(di->get_path()); } } remove(di); redraw(); return ret; }
/* Removes any entry for NAME in DIR. Returns true if successful, false on failure, which occurs only if there is no file with the given NAME. */ bool dir_remove (struct dir *dir, const char *name) { struct dir_entry e; struct inode *inode = NULL; bool success = false; off_t ofs; ASSERT (dir != NULL); ASSERT (name != NULL); /* Find directory entry. */ if (!lookup (dir, name, &e, &ofs)) goto done; /* Open inode. */ inode = inode_open (e.inode_sector); if (inode == NULL) goto done; if(inode->dir && !dir_empty(inode)) goto done; /* Erase directory entry. */ e.in_use = false; if (inode_write_at (dir->inode, &e, sizeof e, ofs) != sizeof e) goto done; /* Remove inode. */ inode_remove (inode); success = true; done: inode_close (inode); return success; }
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input) { char* s = NULL; mode_t m; UINT64 size; int status; char* fullpath; struct STAT st; #if defined(__linux__) && !defined(ANDROID) || defined(sun) struct timespec tv[2]; #else struct timeval tv[2]; #endif UINT64 LastWriteTime; UINT32 FileAttributes; UINT32 FileNameLength; m = 0; switch (FsInformationClass) { case FileBasicInformation: /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */ Stream_Seek_UINT64(input); /* CreationTime */ Stream_Seek_UINT64(input); /* LastAccessTime */ Stream_Read_UINT64(input, LastWriteTime); Stream_Seek_UINT64(input); /* ChangeTime */ Stream_Read_UINT32(input, FileAttributes); if (FSTAT(file->fd, &st) != 0) return FALSE; tv[0].tv_sec = st.st_atime; tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime); #ifndef WIN32 /* TODO on win32 */ #ifdef ANDROID tv[0].tv_usec = 0; tv[1].tv_usec = 0; utimes(file->fullpath, tv); #elif defined (__linux__) || defined (sun) tv[0].tv_nsec = 0; tv[1].tv_nsec = 0; futimens(file->fd, tv); #else tv[0].tv_usec = 0; tv[1].tv_usec = 0; futimes(file->fd, tv); #endif if (FileAttributes > 0) { m = st.st_mode; if ((FileAttributes & FILE_ATTRIBUTE_READONLY) == 0) m |= S_IWUSR; else m &= ~S_IWUSR; if (m != st.st_mode) fchmod(file->fd, st.st_mode); } #endif break; case FileEndOfFileInformation: /* http://msdn.microsoft.com/en-us/library/cc232067.aspx */ case FileAllocationInformation: /* http://msdn.microsoft.com/en-us/library/cc232076.aspx */ Stream_Read_UINT64(input, size); #ifndef _WIN32 if (ftruncate(file->fd, size) != 0) return FALSE; #endif break; case FileDispositionInformation: /* http://msdn.microsoft.com/en-us/library/cc232098.aspx */ /* http://msdn.microsoft.com/en-us/library/cc241371.aspx */ if (file->is_dir && !dir_empty(file->fullpath)) break; if (Length) Stream_Read_UINT8(input, file->delete_pending); else file->delete_pending = 1; break; case FileRenameInformation: /* http://msdn.microsoft.com/en-us/library/cc232085.aspx */ Stream_Seek_UINT8(input); /* ReplaceIfExists */ Stream_Seek_UINT8(input); /* RootDirectory */ Stream_Read_UINT32(input, FileNameLength); status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(input), FileNameLength / 2, &s, 0, NULL, NULL); if (status < 1) if (!(s = (char*) calloc(1, 1))) { WLog_ERR(TAG, "calloc failed!"); return FALSE; } fullpath = drive_file_combine_fullpath(file->basepath, s); if (!fullpath) { WLog_ERR(TAG, "drive_file_combine_fullpath failed!"); free (s); return FALSE; } free(s); #ifdef _WIN32 if (file->fd) close(file->fd); #endif if (rename(file->fullpath, fullpath) == 0) { drive_file_set_fullpath(file, fullpath); #ifdef _WIN32 file->fd = OPEN(fullpath, O_RDWR | O_BINARY); #endif } else { free(fullpath); return FALSE; } break; default: return FALSE; } return TRUE; }