/*++ GetVolumeInfo Retrieves information about a volume. Arguments: interp - Interpreter to use for error reporting. volumePath - A pointer to a string that specifies the volume. volumeInfo - A pointer to a 'VolumeInfo' structure. Return Value: A standard Tcl result. --*/ int GetVolumeInfo( Tcl_Interp *interp, char *volumePath, VolumeInfo *volumeInfo ) { struct STATFS_T fsInfo; if (STATFS_FN(volumePath, &fsInfo) != 0) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "unable to retrieve mount information for \"", volumePath, "\": ", Tcl_PosixError(interp), NULL); return TCL_ERROR; } // Free and total space. volumeInfo->free = (Tcl_WideUInt)fsInfo.f_bsize * (Tcl_WideUInt)fsInfo.f_bfree; volumeInfo->total = (Tcl_WideUInt)fsInfo.f_bsize * (Tcl_WideUInt)fsInfo.f_blocks; volumeInfo->id = (unsigned long)F_FSID(fsInfo); volumeInfo->flags = (unsigned long)F_FLAGS(fsInfo); volumeInfo->length = (unsigned long)F_NAMELEN(fsInfo); // Not supported. volumeInfo->name[0] = '\0'; // File system type. strncpy(volumeInfo->type, F_TYPENAME(fsInfo), ARRAYSIZE(volumeInfo->type)); volumeInfo->type[ARRAYSIZE(volumeInfo->type)-1] = '\0'; return TCL_OK; }
/*++ GetVolumeInfo Retrieves information about a volume. Arguments: interp - Interpreter to use for error reporting. pathObj - A pointer to an object that specifies the volume. volumeInfo - A pointer to a "VolumeInfo" structure. Return Value: A standard Tcl result. --*/ int GetVolumeInfo( Tcl_Interp *interp, Tcl_Obj *pathObj, VolumeInfo *volumeInfo ) { char *path; Tcl_DString buffer; struct STATFS_T fsInfo; assert(interp != NULL); assert(pathObj != NULL); assert(volumeInfo != NULL); if (TranslatePathFromObj(interp, pathObj, &buffer) != TCL_OK) { return TCL_ERROR; } path = Tcl_DStringValue(&buffer); if (STATFS_FN(path, &fsInfo) != 0) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "unable to retrieve mount information for \"", Tcl_GetString(pathObj), "\": ", Tcl_PosixError(interp), NULL); Tcl_DStringFree(&buffer); return TCL_ERROR; } // Free and total space. volumeInfo->free = (Tcl_WideUInt)fsInfo.f_bsize * (Tcl_WideUInt)fsInfo.f_bfree; volumeInfo->total = (Tcl_WideUInt)fsInfo.f_bsize * (Tcl_WideUInt)fsInfo.f_blocks; volumeInfo->id = (unsigned long)F_FSID(fsInfo); volumeInfo->flags = (unsigned long)F_FLAGS(fsInfo); volumeInfo->length = (unsigned long)F_NAMELEN(fsInfo); // Not supported. volumeInfo->name[0] = '\0'; // File system type. strncpy(volumeInfo->type, F_TYPENAME(fsInfo), ARRAYSIZE(volumeInfo->type)); volumeInfo->type[ARRAYSIZE(volumeInfo->type)-1] = '\0'; Tcl_DStringFree(&buffer); return TCL_OK; }
static uint32 disk_query_volume_info(IRP * irp) { FILE_INFO * finfo; struct STATFS_T stat_fs; uint32 status; int size; char * buf; int len; LLOGLN(10, ("disk_query_volume_info: class=%d id=%d", irp->infoClass, irp->fileID)); finfo = disk_get_file_info(irp->dev, irp->fileID); if (finfo == NULL) { LLOGLN(0, ("disk_query_volume_info: invalid file id")); return RD_STATUS_INVALID_HANDLE; } if (STATFS_FN(finfo->fullpath, &stat_fs) != 0) { LLOGLN(0, ("disk_query_volume_info: statfs failed")); return RD_STATUS_ACCESS_DENIED; } size = 0; buf = NULL; status = RD_STATUS_SUCCESS; switch (irp->infoClass) { case FileFsVolumeInformation: buf = malloc(256); memset(buf, 0, 256); SET_UINT64(buf, 0, 0); /* VolumeCreationTime */ SET_UINT32(buf, 8, 0); /* VolumeSerialNumber */ len = freerdp_set_wstr(buf + 17, size - 17, "FREERDP", strlen("FREERDP") + 1); SET_UINT32(buf, 12, len); /* VolumeLabelLength */ SET_UINT8(buf, 16, 0); /* SupportsObjects */ size = 17 + len; break; case FileFsSizeInformation: size = 24; buf = malloc(size); memset(buf, 0, size); SET_UINT64(buf, 0, stat_fs.f_blocks); /* TotalAllocationUnits */ SET_UINT64(buf, 8, stat_fs.f_bfree); /* AvailableAllocationUnits */ SET_UINT32(buf, 16, stat_fs.f_bsize / 0x200); /* SectorsPerAllocationUnit */ SET_UINT32(buf, 20, 0x200); /* BytesPerSector */ break; case FileFsAttributeInformation: buf = malloc(256); memset(buf, 0, 256); SET_UINT32(buf, 0, FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ SET_UINT32(buf, 4, F_NAMELEN(stat_fs)); /* MaximumComponentNameLength */ len = freerdp_set_wstr(buf + 12, 256 - 12, "FREERDP", 8); SET_UINT32(buf, 8, len); /* FileSystemNameLength */ size = 12 + len; break; case FileFsFullSizeInformation: size = 32; buf = malloc(size); memset(buf, 0, size); SET_UINT64(buf, 0, stat_fs.f_blocks); /* TotalAllocationUnits */ SET_UINT64(buf, 8, stat_fs.f_bfree); /* CallerAvailableAllocationUnits */ SET_UINT64(buf, 16, stat_fs.f_bfree); /* ActualAvailableAllocationUnits */ SET_UINT32(buf, 24, stat_fs.f_bsize / 0x200); /* SectorsPerAllocationUnit */ SET_UINT32(buf, 28, 0x200); /* BytesPerSector */ break; case FileFsDeviceInformation: size = 8; buf = malloc(size); memset(buf, 0, size); SET_UINT32(buf, 0, FILE_DEVICE_DISK); /* DeviceType */ SET_UINT32(buf, 4, 0); /* BytesPerSector */ break; default: LLOGLN(0, ("disk_query_volume_info: invalid info class")); status = RD_STATUS_NOT_SUPPORTED; break; } irp->outputBuffer = buf; irp->outputBufferLength = size; return status; }