Good evening all. I am hoping that the community maybe able to help in my little C# programming issue. I will say here that I am very new to programming in C# and that it is a very steep learning curve from Borland Pascal!
I am currently trying to use the Virtual Disk API (as mentioned on here on the MSDN Website), translating to c# (hopefully keeping within the managed context).
I have managed to get OpenVirtualDisk() to accept the first parameter, but it fails on the second (file path of the said ISO that I would like to open and attach.) From a lot of research I am declaring the param "Path" as string, to allow the CLR to best fit with the function signature.
The Application is currently being run under elivated rights (via Visual Studio 2017)
The following is my dllImport:
[DllImport("VirtDisk.dll", EntryPoint = "OpenVirtualDisk", CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true ,SetLastError = true)]
public extern static Int64 OpenVirtualDisk(
[In] ref _VIRTUAL_STORAGE_TYPE PVIRTUAL_STORAGE_TYPE,
string Path,
_VIRTUAL_DISK_ACCESS_MASK LVIRTUAL_DISK_ACCESS_MASK,
long OPEN_VIRTUAL_DISK_FLAG,
[In, Optional] ref OPEN_VIRTUAL_DISK_PARAMTERS POPEN_VIRTUAL_DISK_PARAMTERS,
ref IntPtr pHandle);
All other constants, enums and Structs are declared as provided by VirtDisk.h, can be provided if required.
Here is all the code I am using to call OpenVirtualDisk (as you can see, I am using File.Exists() to ensure that the file exists before starting any work):
private void button1_Click(object sender, EventArgs e)
{
IntPtr pHandle = IntPtr.Zero;
Int64 RetVal = 0;
string VirtualDiskPath = @"F:\Images\Windows10.ISO";
_VIRTUAL_DISK_ACCESS_MASK VIRTUAL_DISK_ACCESS;
Int64 VIRTUAL_DISK_FLAG;
_VIRTUAL_STORAGE_TYPE VIRTUAL_STORAGE_TYPE;
if (File.Exists(VirtualDiskPath))
{
VIRTUAL_DISK_ACCESS = _VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_ATTACH_ALL;
VIRTUAL_DISK_FLAG = OPEN_VIRTUAL_DISK_FLAG_NONE;
VIRTUAL_STORAGE_TYPE.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_ISO;
VIRTUAL_STORAGE_TYPE.VendorId = VENDORMICROSOFT;
IntPtr VirtualStorPtr = IntPtr.Zero;
VirtualStorPtr = Marshal.AllocHGlobal(Marshal.SizeOf(VIRTUAL_STORAGE_TYPE));
Marshal.StructureToPtr(VIRTUAL_STORAGE_TYPE, VirtualStorPtr, true);
IntPtr VirtualDiskVer = IntPtr.Zero;
OPEN_VIRTUAL_DISK_PARAMTERS OPEN_VIRTUAL_DISK_PARAM;
OPEN_VIRTUAL_DISK_PARAM = new OPEN_VIRTUAL_DISK_PARAMTERS
{
version = OPEN_VIRTUAL_DISK_VERSION.OPEN_VIRTUAL_DISK_VERSION_1,
version1 = new OPEN_VIRTUAL_DISK_PARAMTERS1
{
RWDepth = 0
}
};
VirtualDiskVer = Marshal.AllocHGlobal(Marshal.SizeOf(OPEN_VIRTUAL_DISK_PARAM));
Marshal.StructureToPtr(OPEN_VIRTUAL_DISK_PARAM, VirtualDiskVer, true);
RetVal = OpenVirtualDisk(ref VIRTUAL_STORAGE_TYPE,
VirtualDiskPath,
VIRTUAL_DISK_ACCESS,
VIRTUAL_DISK_FLAG,
ref OPEN_VIRTUAL_DISK_PARAM,
ref pHandle);
if ((RetVal == 0))
{
MessageBox.Show("OpenVirtualDisk() has succeded in opening the file: \r\n" +
VirtualDiskPath + "\r\nWith the file Handle: " + pHandle.ToString());
}
else
{
MessageBox.Show("OpenVirtualDisk() failed to open the file: " +
VirtualDiskPath + ",\r\nWith Error Code: " + Marshal.GetLastWin32Error().ToString() +
"\r\nReturn Value: " + RetVal.ToString());
}
Marshal.FreeHGlobal(VirtualStorPtr);
}
}
Every attempt so far has either had a RetVal of 87 "Invalid Parameter" with GetLastWin32Error reporting 1008 "Invalid Token", or RetVal of 2 "File Not Found" with GetLastWin32Error reporting the same.
Can anyone spot where I am going wrong?
Thanks in advance.
Richie
N.B this is part of a recovery suite that I have been building in c#, based on the Windows Imaging API (Wimgapi.h). This is to allow installing Windows (any version as long as it is 64bit) if so desired. It will run on WinPE (Windows 10, .Net Version 5.4.2) I have even tried using FileIOPermssion to allow that process full access to the file.
The fault has been sorted, as below comments. The FILE_ACCESS_MASK needed to be changed to FILE_ACCESS_MASK_RO, but the DLLimport declaration also needed to be adapted. The DLLImport now reads:
[DllImport("virtdisk.dll" CharSet = CharSet.UNICODE, ThrowOnUnmappableChar = true ,SetLastError = true)] public extern static Int64 OpenVirtualDisk( [In] ref _VIRTUAL_STORAGE_TYPE PVIRTUAL_STORAGE_TYPE, string Path, [In] _VIRTUAL_DISK_ACCESS_MASK LVIRTUAL_DISK_ACCESS_MASK, [In] long OPEN_VIRTUAL_DISK_FLAG, [In, Optional] ref OPEN_VIRTUAL_DISK_PARAMTERS POPEN_VIRTUAL_DISK_PARAMTERS, [In] ref IntPtr pHandle);