IVdsSubSystem::CreateLun method

[Beginning with Windows 8 and Windows Server 2012, the Virtual Disk Service COM interface is superseded by the Windows Storage Management API.]

The CreateLun method creates a logical unit number (LUN).


HRESULT CreateLun(
  [in]  VDS_LUN_TYPE  type,
  [in]  ULONGLONG     ullSizeInBytes,
  [in]  VDS_OBJECT_ID *pDriveIdArray,
  [in]  LONG          lNumberOfDrives,
  [in]  LPWSTR        pwszUnmaskingList,
  [in]  VDS_HINTS     *pHints,
  [out] IVdsAsync     **ppAsync


type [in]

A VDS_LUN_TYPE enumeration value that specifies the LUN type. The new LUN can be an automagic type or a specific RAID type, but not both. If the caller specifies an automagic type, one or more automagic hints should be specified in the pHints parameter.

The interface pointer for the new LUN object can be retrieved by calling the IVdsAsync::Wait method on the interface pointer returned in the ppAsync parameter. The VDS_ASYNC_OUTPUT structure returned by Wait contains the LUN object interface pointer in the cl.pLunUnk member.

ullSizeInBytes [in]

The size, in bytes, of the new LUN. The provider can round the size up or down to meet alignment requirements or other restrictions. (In most cases, the provider rounds up, ensuring that, with rare exceptions, the LUN is at least as large as requested.)

After the LUN is created, the caller can determine the actual size of the LUN by calling the IVdsLun::GetProperties method.

pDriveIdArray [in]

A pointer to an array that contains a VDS_OBJECT_ID for each of the drives to be used to create the LUN. By specifying a non-NULL value for this parameter, the caller is requesting that the provider use all of the drives, in the order provided, using all of the extents on one drive before moving on to the next, and stopping when the LUN has reached the requested size.

Alternatively, the caller can direct the provider to select the drives automatically by passing NULL in this parameter and 0 in lNumberOfDrives. (Pass NULL if and only if lNumberOfDrives is 0.)

If the type parameter specifies an automagic type, this parameter should be NULL.

lNumberOfDrives [in]

The number of drives specified in pDriveIdArray. If the caller passes 0, the provider selects the drives.

If the type parameter specifies an automagic type, this parameter should be 0.

After the LUN is created, the caller can determine which drives are in use by calling the IVdsLunPlex::QueryExtents method.

pwszUnmaskingList [in]

A list specifying the computers to be granted access the LUN. The list is a semicolon-delimited, NULL-terminated, human-readable string.

If the value is "*", all computers that have an HBA port attached to the storage subsystem are to be granted access to the LUN. If the value is "", no computers are to be granted access to the LUN.

Note  In practice, if the value is "*", most hardware providers only grant the ports and initiators on the local computer access to the LUN.

If "*" or "" is specified, no other value can be specified.

For Fibre Channel networks and serial attached SCSI (SAS) networks, each entry is a 64-bit World-Wide Name (WWN) of each port to which the LUN is unmasked, formatted as a hexadecimal string (16 characters long), most significant byte first. For example, a WWN address of 01:23:45:67:89:AB:CD:EF is represented as "0123456789ABCDEF". For more information, see the T10 specifications for Fibre Channel and SAS.

For iSCSI networks, each entry is an iSCSI qualified name (IQN) of each initiator to which the LUN is unmasked. A LUN unmasked to a particular initiator is considered to be associated with that initiator.

Note  The unmasking list can contain the same WWN or IQN more than once. The caller is not expected to remove duplicates from the list or to validate the format of the WWN or IQN.

After the LUN is created, the caller can determine the actual unmasking list by calling the IVdsLun::GetProperties method.

pHints [in]

Pointer to a VDS_HINTS structure that specifies the hints to be used in creating the LUN. The provider is not required to apply the hints to the LUN. The hints specified in the VDS_HINTS structure are only a request to the provider.

After the LUN is created, the caller can determine the hints that the provider applied by calling either the IVdsLun::QueryHints method or the IVdsLunPlex::QueryHints method.

If the type parameter specifies a non-automagic type, this parameter should be NULL.

ppAsync [out]

The address of an IVdsAsync interface pointer, which VDS initializes on return. Callers must release the interface. Use this interface to cancel, wait for, or query the status of the operation.

If IVdsAsync::Wait is called on the returned interface pointer and a success HRESULT value is returned, the interfaces returned in the VDS_ASYNC_OUTPUT structure must be released by calling the IUnknown::Release method on each interface pointer. However, if Wait returns a failure HRESULT value, or if the pHrResult parameter of Wait receives a failure HRESULT value, the interface pointers in the VDS_ASYNC_OUTPUT structure are NULL and do not need to be released. You can test for success or failure HRESULT values by using the SUCCEEDED and FAILED macros defined in Winerror.h.

Return value

This method can return standard HRESULT values, such as E_INVALIDARG or E_OUTOFMEMORY, and VDS-specific return values. It can also return converted system error codes using the HRESULT_FROM_WIN32 macro. Errors can originate from VDS itself or from the underlying VDS provider that is being used. Possible return values include the following.

Return code/valueDescription

This return value signals a software or communication problem inside a provider that caches information about the array. Use the IVdsHwProvider::Reenumerate method followed by the IVdsHwProvider::Refresh method to restore the cache.


The subsystem object is no longer present.


The subsystem is in a failed state and is unable to perform the requested operation.


Another operation is in progress; this operation cannot proceed until the previous operation or operations are complete.


Can be returned from any method that takes a VDS_OBJECT_ID constant. This return value indicates that the identifier does not refer to an existing object.


This operation or combination of parameters is not supported by this provider.


There is not enough usable space for this operation.


Too few free drives are present in the subsystem to complete this operation.



By choosing appropriate values for the type and pHints parameters, the caller can specify the attributes of the LUN wholly, partially, or minimally. The provider can automatically include unspecified attributes, based on the automagic hints specified in the VDS_HINTS structure that the pHints parameter points to.

If the VDS provider supports only simple target configurations, the subsystem should automatically associate the newly created LUN object with an iSCSI target object. See the VDS_SF_SUPPORTS_SIMPLE_TARGET_CONFIG value of the VDS_SUB_SYSTEM_FLAG enumeration.

The list of WWNs and IQNs in the pwszUnmaskingList parameter may contain duplicate names. It is the provider's responsibility to validate all names in the list and remove duplicates if necessary.

The hardware provider is responsible for removing the LUN's partition information so that the LUN can be reused. If the LUN is an MBR disk, this is accomplished by writing zeros to the first and last 1 MB of the disk. For a GPT disk, zeros must be written to the first and last 16 KB of the disk.

There is a subtle difference between the E_INVALIDARG and VDS_E_NOT_SUPPORTED return values. Providers are not expected to implement every feature that the VDS API can present to a client. For example, the CreateLun method exposes the ability to create many different types of LUNs (for example, simple, mirror, striped, and parity). However, providers are not required to support all types of LUNs. If the caller specifies a value for the type parameter that is not a valid VDS_LUN_TYPE enumeration value, the provider should return E_INVALIDARG. If the caller specifies a valid type value that the provider does not support, the provider should return VDS_E_NOT_SUPPORTED.

Notes to implementers:  The provider must return an IVdsAsync interface pointer in the ppAsync parameter, even if the call to this method does not initiate an asynchronous operation.


Minimum supported client

Windows Vista [desktop apps only]

Minimum supported server

Windows Server 2003 [desktop apps only]


VdsHwPrv.h (for hardware providers)



See also