Beispiel #1
0
/*++

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;
}
Beispiel #2
0
/*++

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;
}
Beispiel #3
0
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;
}