|
|
#region License
|
|
|
/* FNA - XNA4 Reimplementation for Desktop Platforms
|
|
|
* Copyright 2009-2020 Ethan Lee and the MonoGame Team
|
|
|
*
|
|
|
* Released under the Microsoft Public License.
|
|
|
* See LICENSE for details.
|
|
|
*/
|
|
|
#endregion
|
|
|
|
|
|
#region Using Statements
|
|
|
using System;
|
|
|
using System.IO;
|
|
|
using System.Threading;
|
|
|
#endregion
|
|
|
|
|
|
namespace Microsoft.Xna.Framework.Storage
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// Exposes a storage device for storing user data.
|
|
|
/// </summary>
|
|
|
/// <remarks>
|
|
|
/// MSDN documentation contains related conceptual article:
|
|
|
/// http://msdn.microsoft.com/en-us/library/bb200105.aspx
|
|
|
/// </remarks>
|
|
|
public sealed class StorageDevice
|
|
|
{
|
|
|
#region Public Properties
|
|
|
|
|
|
/// <summary>
|
|
|
/// Returns the amount of free space.
|
|
|
/// </summary>
|
|
|
public long FreeSpace
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// null drive means the OS denied info, so we get to guess!
|
|
|
if (drive == null)
|
|
|
{
|
|
|
return long.MaxValue;
|
|
|
}
|
|
|
return drive.AvailableFreeSpace;
|
|
|
}
|
|
|
catch(Exception e)
|
|
|
{
|
|
|
// Storage root was invalid or unavailable.
|
|
|
throw new StorageDeviceNotConnectedException(
|
|
|
"The storage device bound to the container is not connected.",
|
|
|
e
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Returns true if this StorageDevice path is accessible, false otherwise.
|
|
|
/// </summary>
|
|
|
public bool IsConnected
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// null drive means the OS denied info, so we get to guess!
|
|
|
if (drive == null)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
return drive.IsReady;
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
// The storageRoot path is invalid / has been removed.
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Returns the total size of device.
|
|
|
/// </summary>
|
|
|
public long TotalSpace
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// null drive means the OS denied info, so we get to guess!
|
|
|
if (drive == null)
|
|
|
{
|
|
|
return long.MaxValue;
|
|
|
}
|
|
|
return drive.TotalSize;
|
|
|
}
|
|
|
catch(Exception e)
|
|
|
{
|
|
|
// Storage root was invalid or unavailable.
|
|
|
throw new StorageDeviceNotConnectedException(
|
|
|
"The storage device bound to the container is not connected.",
|
|
|
e
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Private Variables
|
|
|
|
|
|
private PlayerIndex? devicePlayer;
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Private Static Variables
|
|
|
|
|
|
private static readonly string storageRoot = FNAPlatform.GetStorageRoot();
|
|
|
private static readonly DriveInfo drive = FNAPlatform.GetDriveInfo(storageRoot);
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Events
|
|
|
|
|
|
/// <summary>
|
|
|
/// Fired when a device is removed or inserted.
|
|
|
/// </summary>
|
|
|
public static event EventHandler<EventArgs> DeviceChanged;
|
|
|
|
|
|
private void OnDeviceChanged()
|
|
|
{
|
|
|
if (DeviceChanged != null)
|
|
|
{
|
|
|
DeviceChanged(this, null);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Private XNA Lies
|
|
|
|
|
|
private class NotAsyncLie : IAsyncResult
|
|
|
{
|
|
|
public object AsyncState
|
|
|
{
|
|
|
get;
|
|
|
private set;
|
|
|
}
|
|
|
|
|
|
public bool CompletedSynchronously
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public bool IsCompleted
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public WaitHandle AsyncWaitHandle
|
|
|
{
|
|
|
get;
|
|
|
private set;
|
|
|
}
|
|
|
|
|
|
public NotAsyncLie(object state)
|
|
|
{
|
|
|
AsyncState = state;
|
|
|
AsyncWaitHandle = new ManualResetEvent(true);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private class ShowSelectorLie : NotAsyncLie
|
|
|
{
|
|
|
public readonly PlayerIndex? PlayerIndex;
|
|
|
|
|
|
public ShowSelectorLie(object state, PlayerIndex? playerIndex) : base(state)
|
|
|
{
|
|
|
PlayerIndex = playerIndex;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private class OpenContainerLie : NotAsyncLie
|
|
|
{
|
|
|
public readonly string DisplayName;
|
|
|
|
|
|
public OpenContainerLie(object state, string displayName) : base(state)
|
|
|
{
|
|
|
DisplayName = displayName;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Internal Constructors
|
|
|
|
|
|
internal StorageDevice(PlayerIndex? player)
|
|
|
{
|
|
|
devicePlayer = player;
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Public OpenContainer Methods
|
|
|
|
|
|
/// <summary>
|
|
|
/// Begins the open for a StorageContainer.
|
|
|
/// </summary>
|
|
|
/// <returns>The open StorageContainer.</returns>
|
|
|
/// <param name="displayName">Name of file.</param>
|
|
|
/// <param name="callback">Method to call on completion.</param>
|
|
|
/// <param name="state">Request identifier object for callback (can be null).</param>
|
|
|
public IAsyncResult BeginOpenContainer(
|
|
|
string displayName,
|
|
|
AsyncCallback callback,
|
|
|
object state
|
|
|
) {
|
|
|
IAsyncResult result = new OpenContainerLie(state, displayName);
|
|
|
if (callback != null)
|
|
|
{
|
|
|
callback(result);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Ends the open container process.
|
|
|
/// </summary>
|
|
|
/// <returns>The open StorageContainer.</returns>
|
|
|
/// <param name="result">Result of BeginOpenContainer.</param>
|
|
|
public StorageContainer EndOpenContainer(IAsyncResult result)
|
|
|
{
|
|
|
return new StorageContainer(
|
|
|
this,
|
|
|
(result as OpenContainerLie).DisplayName,
|
|
|
storageRoot,
|
|
|
devicePlayer
|
|
|
);
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Public ShowSelector Methods
|
|
|
|
|
|
/// <summary>
|
|
|
/// Begin process to display the StorageDevice selector UI.
|
|
|
/// </summary>
|
|
|
/// <returns>The show selector.</returns>
|
|
|
/// <param name="callback">Method to invoke when device is selected by player.</param>
|
|
|
/// <param name="state">Request identifier object for callback (can be null).</param>
|
|
|
public static IAsyncResult BeginShowSelector(
|
|
|
AsyncCallback callback,
|
|
|
object state
|
|
|
) {
|
|
|
return BeginShowSelector(
|
|
|
0,
|
|
|
0,
|
|
|
callback,
|
|
|
state
|
|
|
);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Begin process to display the StorageDevice selector UI.
|
|
|
/// </summary>
|
|
|
/// <returns>The show selector.</returns>
|
|
|
/// <param name="player">The PlayerIndex. Only PlayerIndex.One is valid on Windows.</param>
|
|
|
/// <param name="callback">Method to invoke when device is selected by player.</param>
|
|
|
/// <param name="state">Request identifier object for callback (can be null).</param>
|
|
|
public static IAsyncResult BeginShowSelector(
|
|
|
PlayerIndex player,
|
|
|
AsyncCallback callback,
|
|
|
object state
|
|
|
) {
|
|
|
return BeginShowSelector(
|
|
|
player,
|
|
|
0,
|
|
|
0,
|
|
|
callback,
|
|
|
state
|
|
|
);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Begin process to display the StorageDevice selector UI.
|
|
|
/// </summary>
|
|
|
/// <returns>The show selector.</returns>
|
|
|
/// <param name="sizeInBytes">Size (in bytes) of data to write.</param>
|
|
|
/// <param name="directoryCount">Number of directories to write.</param>
|
|
|
/// <param name="callback">Method to invoke when device is selected by player.</param>
|
|
|
/// <param name="state">Request identifier object for callback (can be null).</param>
|
|
|
public static IAsyncResult BeginShowSelector(
|
|
|
int sizeInBytes,
|
|
|
int directoryCount,
|
|
|
AsyncCallback callback,
|
|
|
object state
|
|
|
) {
|
|
|
IAsyncResult result = new ShowSelectorLie(state, null);
|
|
|
if (callback != null)
|
|
|
{
|
|
|
callback(result);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Begin process to display the StorageDevice selector UI.
|
|
|
/// </summary>
|
|
|
/// <returns>The show selector.</returns>
|
|
|
/// <param name="player">The PlayerIndex. Only PlayerIndex.One is valid on Windows.</param>
|
|
|
/// <param name="sizeInBytes">Size (in bytes) of data to write.</param>
|
|
|
/// <param name="directoryCount">Number of directories to write.</param>
|
|
|
/// <param name="callback">Method to invoke when device is selected by player.</param>
|
|
|
/// <param name="state">Request identifier object for callback (can be null).</param>
|
|
|
public static IAsyncResult BeginShowSelector(
|
|
|
PlayerIndex player,
|
|
|
int sizeInBytes,
|
|
|
int directoryCount,
|
|
|
AsyncCallback callback,
|
|
|
object state
|
|
|
) {
|
|
|
IAsyncResult result = new ShowSelectorLie(state, player);
|
|
|
if (callback != null)
|
|
|
{
|
|
|
callback(result);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Ends the show selector user interface display.
|
|
|
/// </summary>
|
|
|
/// <returns>The storage device.</returns>
|
|
|
/// <param name="result">The result of BeginShowSelector.</param>
|
|
|
public static StorageDevice EndShowSelector(IAsyncResult result)
|
|
|
{
|
|
|
return new StorageDevice((result as ShowSelectorLie).PlayerIndex);
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Public StorageContainer Delete Method
|
|
|
|
|
|
public void DeleteContainer(string titleName)
|
|
|
{
|
|
|
throw new NotImplementedException();
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
}
|
|
|
}
|
|
|
|