Access path not valid error when trying to create a partition with C# through MSFT_Disk

Niels Koomans 21 Reputation points
2022-03-02T19:10:11.363+00:00

To clarify some details: I'm building a Windows Setup app that can be used with Windows-To-Go USB sticks, to make it able to install Windows straight from that session onto a local storage unit, like Linux's Live CD's.

I automatically had these classes made using the mgmtclassgen.exe

Now i'm trying to create a partition on a disk, and make it return a MSFT_Partition class object through the OUT parameters.

This is the code for the app:

        private async Task<(Partition Boot, Partition Data)> PrepareDisk(Disk disk)
        {
            lbStatus.Text = "Clearing disk";
            var cleared = await Task.Run(() => disk.Clear(
                 RemoveData: true,
                 RemoveOEM: true,
                 RunAsJob: true,
                 Sanitize: false,
                 ZeroOutEntireDisk: false,
                 out ManagementBaseObject statusClear));

            await Task.Run(() => disk.ConvertStyle(2, out ManagementBaseObject status));

            lbStatus.Text = "Creating boot partition";

            var ptBoot = new Partition();
            var ptData = new Partition();

            await Task.Run(() =>
            {
                disk.CreatePartition(
                        Alignment: 0,
                        AssignDriveLetter: true,
                        DriveLetter: char.MinValue,
                        GptType: "System Partition",
                        IsActive: true,
                        IsHidden: true,
                        MbrType: 6,
                        Offset: 0,
                        Size: Convert.ToUint64(128 * 1048576),
                        UseMaximumSize: false,
                        out ManagementBaseObject partBoot,
                        out ManagementBaseObject statusBoot);

                Task.WaitAll();
                ptBoot = new Partition(partBoot);
            });

            lbStatus.Text = "Creating data partition";

            await Task.Run(() =>
            {
                disk.CreatePartition(
                        Alignment: 0,
                        AssignDriveLetter: true,
                        DriveLetter: default,
                        GptType: "Basic data",
                        IsActive: true,
                        IsHidden: true,
                        MbrType: 7,
                        Offset: Convert.ToUInt64(128 * 1048576),
                        Size: disk.LargestFreeExtent,
                        UseMaximumSize: false,
                        out ManagementBaseObject partData,
                        out ManagementBaseObject statusData);

                Task.WaitAll();
                ptData = new Partition(partData);
            });

            return (ptBoot, ptData);
        }

This is the code that was generated through mgmtclassgen.exe:

   public uint CreatePartition(uint Alignment, bool AssignDriveLetter, char DriveLetter, string GptType, bool IsActive, bool IsHidden, ushort MbrType, ulong Offset, ulong Size, bool UseMaximumSize, out System.Management.ManagementBaseObject CreatedPartition, out System.Management.ManagementBaseObject ExtendedStatus)
        {
            if ((isEmbedded == false))
            {
                System.Management.ManagementBaseObject inParams = null;
                inParams = PrivateLateBoundObject.GetMethodParameters("CreatePartition");
                inParams["Alignment"] = ((uint)(Alignment));
                inParams["AssignDriveLetter"] = ((bool)(AssignDriveLetter));
                inParams["DriveLetter"] = ((char)(DriveLetter));
                inParams["GptType"] = ((string)(GptType));
                inParams["IsActive"] = ((bool)(IsActive));
                inParams["IsHidden"] = ((bool)(IsHidden));
                inParams["MbrType"] = ((ushort)(MbrType));
                inParams["Offset"] = ((ulong)(Offset));
                inParams["Size"] = ((ulong)(Size));
                inParams["UseMaximumSize"] = ((bool)(UseMaximumSize));
                System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("CreatePartition", inParams, null);
                CreatedPartition = ((System.Management.ManagementBaseObject)(outParams.Properties["CreatedPartition"].Value));
                ExtendedStatus = ((System.Management.ManagementBaseObject)(outParams.Properties["ExtendedStatus"].Value));
                return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value);
            }
            else
            {
                CreatedPartition = null;
                ExtendedStatus = null;
                return System.Convert.ToUInt32(0);
            }
        }

Now I found out that AssignDriveLetter, and DriveLetter don't work in coallition with each other. If I assign both at the same time, I get a 'Access Path Not Valid' error.

My question is: how can I NOT assign (or use/specify) the DriveLetter property in the parameters used for CreatePartition?

Developer technologies | C#
Developer technologies | C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
0 comments No comments
{count} votes

Answer accepted by question author
  1. Michael Taylor 61,106 Reputation points
    2022-03-02T19:15:28.327+00:00

    The documentation for CreatePartition says this.

    DriveLetter [in]

    The drive letter to be assigned to the partition at the time of creation. This parameter cannot be used with AssignDriveLetter. If both parameters are specified, an Invalid Parameter error will be returned. If the drive letter is not available, the partition will be created, but error '42002' will be returned.

    AssignDriveLetter [in]

    If TRUE, the next available drive letter will be assigned to the created partition. If no more drive letters are available, the partition will be created with no drive letter. This parameter cannot be used with DriveLetter. If both parameters are specified, an Invalid Parameter error will be returned.

    So if you want to assign a drive letter using DriveLetter then set AssignDriveLetter to false. Setting it to true indicates that you want the next available drive letter to be auto-assigned to it. Since you also specify the actual letter you want previously this would conflict. Set this parameter to true if you aren't assigning an explicit driver letter.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.