Application Storage Service  
 

The Web Services library provides a private cloud storage API for uploading and downloading shared data files which are available to your application. This is primarily intended for use by developers to store configuration information and other data generated by the application. For example, you may want to store certain application settings, and the next time a user or organization installs your software, those settings can be downloaded and restored.

The connection to the storage service is always secure, using TLS 1.2 and AES-256 bit encryption. There are no third-party services you need to subscribe to, and there are no additional usernames or passwords for you to manage. Access to the service is associated with an account which is created when you purchase a development license, and the security tokens are bound to the runtime license key used when initializing the API. You also have the option to compress and encrypt your data you store using the Encoding, Compression and Encryption APIs.

Terminology

When you get started with the storage API, you'll notice there is some different terminology which is used. This will provide an overview of that terminology, and compare it to common terms used with traditional protocols like FTP. When accessing an FTP server, you generally deal with directories, files, names and types (generally whether the file is binary or text). The storage API has similar concepts, but uses somewhat different terminology.

Application Identifiers

An application identifier (AppId) is a null-terminated string which uniquely identifies your application. This string, used in conjunction with your runtime license key, is used to generate an access token. This token is used to access the storage container which contains the data which you've stored.

It is recommended you use a standard format for the AppId which consists of your company name, application name and optionally a version number. Some examples of an AppId string would be:

  • MyCompany.MyApplication
  • MyCompany.MyApplication.1

It is important to note with these two example IDs, although they are similar, they reference two different applications. Objects stored using the first ID will not be accessible using the second ID. If you want to store objects which should be shared between all versions of the application, it is recommended you use the first form, without the version number. If you want to store objects which should only be accessible to a specific version of your application, then it is recommended you use the second form which includes the version number.

The AppId must only consist of ASCII letters, numbers, the period and underscore character. Whitespace characters and non-ASCII Unicode characters are not permitted. The maximum length of the string is 64 characters, including the terminating null character. It is not required for your application to create a unique AppId. Each storage account has a default internal AppId named SocketTools.Storage.Default. This AppId is used if a NULL pointer or an empty string is specified.

Containers

Storage containers are somewhat analogous to directories or folders in a file system, however they are general purpose and designed to allow you to control how your application accesses the data that's been stored. There are four container types which are defined by the API, and you can think of them as types of boxes or file cabinets which you store your data in.

It is important to keep in mind these containers are available to all users of your application, your program controls who has access to any particular data file. Your users will not be able to "browse" any of the containers unless you specifically provide that capability by implementing it in your own code. There is no public access to any of the data which you upload, and our service does not use an open API accessible by third parties.

WEB_STORAGE_GLOBAL
The global storage container which is available to all users of your application. Any data stored in this container is available to everyone who uses your software. Unless you have a specific need to limit access to the data to a specific user or group of users, this is the recommended container you use to store data.

WEB_STORAGE_DOMAIN
The domain storage container is limited to users in the same local domain, defined either by the name of the domain or workgroup assigned to the computer system. This can provide a kind of organization wide storage, but it does depend on the domain being unique. For example, if you are using domain storage for your application, and you have multiple customers who have systems part of the default "Workgroup" domain, they would all share the same container. If the domain or workgroup name changes, then data stored in the container would no longer be available.

WEB_STORAGE_MACHINE
The local machine storage container is associated with the physical computer system your application is running on. The machine is identified by unique characteristics of the system, including the boot volume GUID. Data stored in this container can only be accessed from the application running on that particular system. If the operating system is reinstalled, the machine ID will change and data stored in this container would no longer be available.

WEB_STORAGE_USER
The current user storage container is associated with the current user who is using your application. The user identifier is based on the Windows Security Identifier (SID) assigned to the account when it's created. If the user account is deleted, the data stored in this container will no longer be available to the application. Another user on the same computer system would not be able to access the data in this container.

If you decide to use anything other than global storage, the data your application stores can be orphaned if the system configuration or user account changes. It's recommended you store critical application data and general configuration information using WEB_STORAGE_GLOBAL and use other non-global storage containers for configuration information which is unique to that system and/or user which is not critical and can be easily recreated. If you're concerned about protecting the data you upload to global storage, you can encrypt it prior to storing it.

Objects

Storage objects are similar to files in a file system. They are discrete blocks of data, associated with a label (name), have attributes and are associated with a particular content type. However, an object does not need to be an actual file on the local system. For example, you could store an object which is a string, a pointer to a structure, or any block of memory. You could also just store a complete file as an object. Unlike files, you cannot perform partial reads of an object or "seek" into certain parts of a stored object. Of course, you can download an object, either in memory or to a local file, and perform whatever operations you require on the data.

Labels

Object labels are similar to file names, and are a way to identify a stored object instead of using its internal object ID.  However, there are some important differences. The most significant difference being labels are case-sensitive, unlike Windows file names. An object with the label "AppConfig" is considered to be different than one with the label "appconfig". Labels can contain Unicode characters, but they cannot contain control characters.

You can also use forward slashes or backslash characters in the label, but it's important to note objects are not stored in a hierarchical structure. Your application can store objects using a folder-like structure, but it's not something which is enforced by the API.

Media Type

Each object your application stores is associated with a media type (also called a content type) which identifies the object's data. This uses the standard MIME media type designations, such as "text/plain" or "application/octet-stream". Your application can explicitly specify the media type you want to associate with the object, or you can have the API choose for you, based on the contents of the object and using the label as a hint for what it may contain. For example, if you create an object with the label "AppConfig.xml" and it contains text, then the API will select "text/xml" as the default media type.

Initialization

The first step your application must take is to initialize the library and then open a storage container. The following functions are available for use by your application:

WebInitialize
Initialize the library for the current process. This must be the first function call the application makes before calling the other service API functions.

WebOpenStorage
Opens a storage container for your application and returns a handle which is used with other functions.

WebCloseStorage
Close the storage container and release the resources allocated for the session.

WebUninitialize
Release all resources which have been allocated for the current process. This is the last function call the application should make prior to terminating.

Data Storage

The library provides functions to upload and download to the storage container. You can store local files, or you can create objects from data in memory. There are also functions which make it easier to store and retrieve textual data using null-terminated strings.

WebGetFile
Download the object data and store in a file on the local system. There is also an extended version of the function named WebGetFileEx which provides additional options, such as the ability to retrieve information about the object downloaded in a single function call.

WebGetObject
Download the object data and store it in a memory buffer provided by the caller. The buffer can either be a pre-allocated block of memory, or reference a global memory handle which will contain the data when the function returns.

WebGetTextObject
Download the object data and store it in a null-terminated string. This function would be used with data which is only textual, and it may contain Unicode text. If the the Unicode version of the function is called, the text is automatically converted from UTF-8 encoded to UTF-16 encoded text.

WebPutFile
Upload the the contents of a local file and store it as an object in the current container. There is also an extended version of the function named WebPutFileEx which provides additional options, such specifying the object attributes, media type and information about the stored object when the function returns.

WebPutObject
Upload the object data from a buffer in memory and store it as an object in the current container. This function would typically be used to store binary data, including compressed or encrypted text.

WebPutTextObject
Upload the contents of a string and store it as an object in the current container. The text is specified as a null-terminated string, and if the Unicode version of the function is used, the text will be converted and stored as UTF-8 encoded text. The WebGetTextObject function will automatically convert the text back to UTF-16 encoding when the text object is retrieved from storage.

Data Management

The data management functions allow you to obtain information about stored objects and perform typical operations such as copying, renaming and deleting objects from the container.

WebGetObjectInformation
Returns information about a specific object stored in the container. This function populates a WEB_STORAGE_OBJECT structure which will contains metadata for the object such as its ID, size, attributes, creation and modification times.

WebGetFirstObject
Enables your application to search for and enumerate objects in a container based on their label and/or their media type. This function is used in conjunction with the WebGetNextObject function to list all matching objects in a container.

WebCompareFile
Compares the contents of a local file with the data in a stored object. This function can be used to determine if the contents of a file have changed since the file was previously stored using the WebPutFile function.

WebCompareObject
Compares the contents of data in memory with the data in a stored object. This function can be used to determine if the contents of the buffer have changed since the data was previously stored using the WebPutObject function.

WebCompareText
Compares the contents of null-terminated string with the text in a stored object. This function can be used to determine if the contents of the string have changed since the data was previously stored using the WebPutTextObject function. If the Unicode version of this function is used, the string is automatically converted to use UTF-8 encoding prior to being compared with the contents of the stored object.

WebCopyObject
Copies the contents of a stored object to a new container, or duplicating the object within the same container using a different label. Information about the newly created object is returned to the caller.

WebMoveObject
Moves the contents of a stored object to a new container. Information about the object which has been moved will be returned to the caller.

WebRenameObject
Changes the label associated with a stored object. The new label for the object cannot already exist in the same container. If you want to change the label to one already assigned to an existing object, the object must first be deleted.

WebDeleteObject
Removes the stored object from the container. This operation is immediate and permanent. Deleted objects cannot be recovered by the application at a later time.

WebGetStorageQuota
Returns information about how much storage space is available. It will populate a WEB_STORAGE_QUOTA structure which will specify how many bytes of storage you're using and how many objects you have created. It is important to note accounts created with an evaluation license have much lower quota limits than a standard account and should be used for testing purposes only. After the evaluation period has ended, all objects stored using the evaluation license will be deleted.

WebResetStorage
Resets the storage container and deletes all objects which were stored there. This function resets the container back to its initial state, deleting all object metadata from the database and removing all stored data. This operation is immediate and the objects stored in the container are permanently deleted. They cannot be recovered by your application.

Other Functions

Several additional utility functions are available as part of the storage API, including functions to register and de-register application identifiers and validate object labels.

WebRegisterAppId
Register a new application identifier (AppId) to be used to access a storage container. It is not required you create a unique application ID, but it can be helpful to distinguish stored content between different versions of your applications.

WebUnregisterAppId
Unregister an application identifier which was previously registered by your application. You should be extremely careful when using this function because it permanently delete all stored objects created using the AppId value. Internally it revokes the access token granted to your application and causes the server to expunge all objects in the container associated with the token.

WebValidateAppId
A utility function which can be used to validate an application identifier, ensuring it is valid and has been registered.

WebValidateLabel
A utility function which can be used to validate an object label to ensure it does not contain any invalid characters. This would be primarily used by applications which allow a user to specify the label names for the objects being stored.