STATIC mp_obj_t mod_os_statvfs(mp_obj_t path_in) { STRUCT_STATVFS sb; const char *path = mp_obj_str_get_str(path_in); int res = STATVFS(path, &sb); RAISE_ERRNO(res, errno); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); t->items[0] = MP_OBJ_NEW_SMALL_INT(sb.f_bsize); t->items[1] = MP_OBJ_NEW_SMALL_INT(sb.f_frsize); t->items[2] = MP_OBJ_NEW_SMALL_INT(sb.f_blocks); t->items[3] = MP_OBJ_NEW_SMALL_INT(sb.f_bfree); t->items[4] = MP_OBJ_NEW_SMALL_INT(sb.f_bavail); t->items[5] = MP_OBJ_NEW_SMALL_INT(sb.f_files); t->items[6] = MP_OBJ_NEW_SMALL_INT(sb.f_ffree); t->items[7] = MP_OBJ_NEW_SMALL_INT(F_FAVAIL); t->items[8] = MP_OBJ_NEW_SMALL_INT(F_FLAG); t->items[9] = MP_OBJ_NEW_SMALL_INT(F_NAMEMAX); return MP_OBJ_FROM_PTR(t); }
/** * Stat a file (or path) to determine it's filesystem info */ int elio_stat(char *fname, stat_t *statinfo) { struct stat ufs_stat; int bsize; struct STATVFS ufs_statfs; PABLO_start(PABLO_elio_stat); if(stat(fname, &ufs_stat) != 0) ELIO_ERROR(STATFAIL, 1); # if defined(PIOFS) /* fprintf(stderr,"filesystem %d\n",ufs_stat.st_vfstype);*/ /* according to /etc/vfs, "9" means piofs */ if(ufs_stat.st_vfstype == 9) statinfo->fs = ELIO_PIOFS; else # endif statinfo->fs = ELIO_UFS; /* only regular or directory files are OK */ if(!S_ISREG(ufs_stat.st_mode) && !S_ISDIR(ufs_stat.st_mode)) ELIO_ERROR(TYPEFAIL, 1); # if defined(CRAY) if(statfs(fname, &ufs_statfs, sizeof(ufs_statfs), 0) != 0) # else if(STATVFS(fname, &ufs_statfs) != 0) # endif ELIO_ERROR(STATFAIL,1); # if defined(WIN32) get_avail_space(ufs_statfs.st_dev, &(statinfo->avail), &bsize); # else /* get number of available blocks */ # if defined(CRAY) || defined(NEC) /* f_bfree == f_bavail -- naming changes */ # ifdef CRAY if(ufs_statfs.f_secnfree != 0) /* check for secondary partition */ statinfo->avail = (avail_t) ufs_statfs.f_secnfree; else # endif statinfo->avail = (avail_t) ufs_statfs.f_bfree; # else statinfo->avail = (avail_t) ufs_statfs.f_bavail; # endif # ifdef NO_F_FRSIZE /* on some older systems it was f_bsize */ bsize = (int) ufs_statfs.f_bsize; # else /* get block size, fail if bszie is still 0 */ bsize = (int) ufs_statfs.f_frsize; if(bsize==0)bsize =(int) ufs_statfs.f_bsize; if(bsize==0) ELIO_ERROR(STATFAIL, 1); if(DEBUG_) printf("stat: f_frsize=%d f_bsize=%d bsize=%d free blocks=%ld\n", (int) ufs_statfs.f_frsize,(int) ufs_statfs.f_bsize, bsize, statinfo->avail ); # endif # endif /* translate number of available blocks into kilobytes */ switch (bsize) { case 512: statinfo->avail /=2; break; case 1024: break; case 2048: statinfo->avail *=2; break; case 4096: statinfo->avail *=4; break; case 8192: statinfo->avail *=8; break; case 16384: statinfo->avail *=16; break; case 32768: statinfo->avail *=32; break; default: { double avail; double factor = ((double)bsize)/1024.0; avail = factor * (double)statinfo->avail; statinfo->avail = (avail_t) avail; } } PABLO_end(PABLO_elio_stat); return(ELIO_OK); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* irp) { UINT32 FsInformationClass; wStream* output = irp->output; struct STATVFS svfst; struct STAT st; char* volumeLabel = {"FREERDP"}; char* diskType = {"FAT32"}; WCHAR* outStr = NULL; int length; Stream_Read_UINT32(irp->input, FsInformationClass); STATVFS(drive->path, &svfst); STAT(drive->path, &st); switch (FsInformationClass) { case FileFsVolumeInformation: /* http://msdn.microsoft.com/en-us/library/cc232108.aspx */ length = ConvertToUnicode(sys_code_page, 0, volumeLabel, -1, &outStr, 0) * 2; Stream_Write_UINT32(output, 17 + length); /* Length */ if (!Stream_EnsureRemainingCapacity(output, 17 + length)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); free(outStr); return CHANNEL_RC_NO_MEMORY; } Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */ #ifdef ANDROID Stream_Write_UINT32(output, svfst.f_fsid.__val[0]); /* VolumeSerialNumber */ #else Stream_Write_UINT32(output, svfst.f_fsid); /* VolumeSerialNumber */ #endif Stream_Write_UINT32(output, length); /* VolumeLabelLength */ Stream_Write_UINT8(output, 0); /* SupportsObjects */ /* Reserved(1), MUST NOT be added! */ Stream_Write(output, outStr, length); /* VolumeLabel (Unicode) */ free(outStr); break; case FileFsSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232107.aspx */ Stream_Write_UINT32(output, 24); /* Length */ if (!Stream_EnsureRemainingCapacity(output, 24)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_Write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ Stream_Write_UINT64(output, svfst.f_bavail); /* AvailableAllocationUnits */ Stream_Write_UINT32(output, 1); /* SectorsPerAllocationUnit */ Stream_Write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsAttributeInformation: /* http://msdn.microsoft.com/en-us/library/cc232101.aspx */ length = ConvertToUnicode(sys_code_page, 0, diskType, -1, &outStr, 0) * 2; Stream_Write_UINT32(output, 12 + length); /* Length */ if (!Stream_EnsureRemainingCapacity(output, 12 + length)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_Write_UINT32(output, FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ #ifdef ANDROID Stream_Write_UINT32(output, 255); /* MaximumComponentNameLength */ #else Stream_Write_UINT32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */ #endif Stream_Write_UINT32(output, length); /* FileSystemNameLength */ Stream_Write(output, outStr, length); /* FileSystemName (Unicode) */ free(outStr); break; case FileFsFullSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232104.aspx */ Stream_Write_UINT32(output, 32); /* Length */ if (!Stream_EnsureRemainingCapacity(output, 32)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_Write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ Stream_Write_UINT64(output, svfst.f_bavail); /* CallerAvailableAllocationUnits */ Stream_Write_UINT64(output, svfst.f_bfree); /* AvailableAllocationUnits */ Stream_Write_UINT32(output, 1); /* SectorsPerAllocationUnit */ Stream_Write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsDeviceInformation: /* http://msdn.microsoft.com/en-us/library/cc232109.aspx */ Stream_Write_UINT32(output, 8); /* Length */ if (!Stream_EnsureRemainingCapacity(output, 8)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_Write_UINT32(output, FILE_DEVICE_DISK); /* DeviceType */ Stream_Write_UINT32(output, 0); /* Characteristics */ break; default: irp->IoStatus = STATUS_UNSUCCESSFUL; Stream_Write_UINT32(output, 0); /* Length */ break; } return irp->Complete(irp); }
static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP* irp) { UINT32 FsInformationClass; STREAM* output = irp->output; struct STATVFS svfst; struct STAT st; char* volumeLabel = {"FREERDP"}; char* diskType = {"FAT32"}; WCHAR* outStr = NULL; int length; stream_read_UINT32(irp->input, FsInformationClass); STATVFS(disk->path, &svfst); STAT(disk->path, &st); switch (FsInformationClass) { case FileFsVolumeInformation: /* http://msdn.microsoft.com/en-us/library/cc232108.aspx */ length = ConvertToUnicode(CP_UTF8, 0, volumeLabel, -1, &outStr, 0) * 2; stream_write_UINT32(output, 17 + length); /* Length */ stream_check_size(output, 17 + length); stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */ stream_write_UINT32(output, svfst.f_fsid); /* VolumeSerialNumber */ stream_write_UINT32(output, length); /* VolumeLabelLength */ stream_write_BYTE(output, 0); /* SupportsObjects */ /* Reserved(1), MUST NOT be added! */ stream_write(output, outStr, length); /* VolumeLabel (Unicode) */ free(outStr); break; case FileFsSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232107.aspx */ stream_write_UINT32(output, 24); /* Length */ stream_check_size(output, 24); stream_write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ stream_write_UINT64(output, svfst.f_bavail); /* AvailableAllocationUnits */ stream_write_UINT32(output, 1); /* SectorsPerAllocationUnit */ stream_write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsAttributeInformation: /* http://msdn.microsoft.com/en-us/library/cc232101.aspx */ length = ConvertToUnicode(CP_UTF8, 0, diskType, -1, &outStr, 0) * 2; stream_write_UINT32(output, 12 + length); /* Length */ stream_check_size(output, 12 + length); stream_write_UINT32(output, FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ stream_write_UINT32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */ stream_write_UINT32(output, length); /* FileSystemNameLength */ stream_write(output, outStr, length); /* FileSystemName (Unicode) */ free(outStr); break; case FileFsFullSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232104.aspx */ stream_write_UINT32(output, 32); /* Length */ stream_check_size(output, 32); stream_write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ stream_write_UINT64(output, svfst.f_bavail); /* CallerAvailableAllocationUnits */ stream_write_UINT64(output, svfst.f_bfree); /* AvailableAllocationUnits */ stream_write_UINT32(output, 1); /* SectorsPerAllocationUnit */ stream_write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsDeviceInformation: /* http://msdn.microsoft.com/en-us/library/cc232109.aspx */ stream_write_UINT32(output, 8); /* Length */ stream_check_size(output, 8); stream_write_UINT32(output, FILE_DEVICE_DISK); /* DeviceType */ stream_write_UINT32(output, 0); /* Characteristics */ break; default: irp->IoStatus = STATUS_UNSUCCESSFUL; stream_write_UINT32(output, 0); /* Length */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); break; } irp->Complete(irp); }