Yes
>
> `**` is a C pointer that points to another
> C pointer (AAAHHH!)
>
> `HRESULT QueryVolume` is not `HRESULT = QueryVolume(...)`.
> It is not a return value from a function.
QueryVolume is a COM "method" belonging to the IVdsPack interface. OK, so to use COM you should
understand COM basics:
- what is COM
- basic undertanding of COM architecture: COM objects, interfaces and methods
Note: COM does not supply direct C pointers to COM objects - it always provides
pointers to INTERFACES, which have METHODS you call to access the associated
object.
- how interfaces are aquired and released, and at least understand
the IUnknown interface, and how interfaces are resource-counted.
(Otherwise you will leak resources all over the place.)
- how COM reports errors via HRESULT.
For disk-management, you are not forced to use COM. There are surely non-COM APIs that would do
what you are want? Perhaps using those might be easier...
So, you are looking at some documentation at the web link you provided...
HRESULT QueryVolumes(
[out] IEnumVdsObject **ppEnum
);
Best to think of this as a function prototype, descibing/documenting how to use the QueryVolumes
method. So it is not an assignment statement. (Like you said.)
HMMM - have you spotted that the whole VDS COM apis have been superseded by thw
HRESULT is the standard return type used by all COM methods. It is a 32-bit structured value, with
some values indicating success, and some failure. See
<
https://learn.microsoft.com/en-us/windows/win32/com/structure-of-com-error-codes>. So, when you
call QueryVolumes it returns an HRESULT to indicate success/failure. You would of course test this
following any call.
The [out] you can consider to be just documentation, indicating that ppEnum is a pointer to
something that is given back to you by the QueryVolumes function (method), i.e. it's an OUT
parameter for the call.
For the QueryVolumes method, ppEnum points to something of type (IEnumVdsObject *) - this is a new
COM interface pointer, pointing to a COM object implementing the IEnumVdsObject interface. You can
use that pointer to invoke other methods belonging to the IEnumVdsObject interface.
Note: QueryVolumes does not return an array of anything - it returns a new interface you can call
to access the various objects to be enumerated. E.g. it has a Next() method that you would call.
THAT method can indeed fill an array, but (of course) you need to read and understand the
documentation provided for that method...
>
> `HRESULT` is telling me that is the structure of what
> the pointer to a pointer (**ppEnum) points to.
No, it's the (type of the ) return code from calling the QueryVolumes method. The value indicates
primarily whether the method call worked or failed.
HRESULT is the type that all COM methods return. It is a 32 bit value and in particular the high
order bit (bit 31) is the S bit indicating success/failure. Normally you would test this bit by
with the SUCCESS or FAILED macros. Something like
// iVdsPac is obtained elsewhere
HRESULT hr;
IEnumVdsObject* pIEnum = NULL;
hr = iVdsPac->QueryVolumes (&pIEnum);
if (SUCCEEDED(hr))
{
// call succeeded, so pIEnum is a new returned interface pointer.
// Use the interface, then RELEASE it!
// Documentation for the interface (the methods it supports) is at
// <
https://learn.microsoft.com/en-us/windows/win32/api/vdshwprv/nn-vdshwprv-ienumvdsobject>
IUnknown* pIUnknown = NULL;
ULONG cFetched = 0;
hr = pIEnum->Next (1, &pIUnknown, &cFetched);
if (SUCCEEDED(hr))
{
// use AND RELEASE pIUnknown, e.g. call QueryInteface to get required interface type etc.
// Actually using the interface is omitted from this listing!
pIUnknown->Release (); // finished with interface so release it
}
pIEnum->Release ();
)
>
> I am after both
> VDS_E_VOLUME_NOT_HEALTHY (0x8004243EL), and
> VDS_E_VOLUME_NOT_A_MIRROR (0x80042445L)
>
No, those are HRESULT failure return codes, as conventionally indicated by the _E_ in the name, and
also as indicated by bit 31 of the value being 1. You presumably don't want to fail!
What I think you think you want to do is use the IEnumVdsObject interface to step through the
objects it enumerates. You should probably read
<
https://learn.microsoft.com/en-us/windows/win32/vds/working-with-enumeration-objects>
and of course before starting on any of this, you need to properly understand the underlying object
model for the system (disks?) being modelled, so hopefully you have already read
<
https://learn.microsoft.com/en-us/windows/win32/vds/vds-object-model>
...except, you probably shouldn't be doing any of this without understanding what you're doing.
That's why you should go to a suitable Microsoft development forum, explain what you're trying to
do, and follow advice. Or maybe, find an example doing exactly what you want, or get someone to
write the code for you! I don't think you have enough background to get going on whatever you're
trying to achieve with the route you seem to be taking... [Sorry, I don't have suggestions for
specifics for forums etc..]
And this whole API is superseded by newer APIs, so you shouldn't be using any of it! :)
> Does the "L" stand from 32 bit integer? (To me,
> 64 bits is "Long".)
Yes, L defines a "long" integer, that's regular C/C++. In MSVC, long integers are 32 bits. 64 bit
integers are "long long".
>
> And is bit 31 is used for "Severity" it look a
> lot and unsigned integer (cardinal) to me.
Yes, bit 31 is severity as shown in the documentation. HRESULT values are unsigned, BUT that hardly
matters, as they're not manipulated as integer values - you compare them sometimes if you are
checking for one specific error, or you use macros like SUCCEEDED/FAILED to test the bits you need.
Regards,
Mike.