Question:
I am trying to list the connections to shared resources. I would like to return a std::vector with this information but it seems that when I call NetApiBufferFree this information is eliminated and I don't understand why since in theory I copy the content, but it is clear that something is wrong.
Here I leave the function to see if you can help me.
const std::vector<USE_INFO_2>
getConnections2shared() {
typedef std::unique_ptr<USE_INFO_2, std::function<void(USE_INFO_2 *)> > USE_INFO_2_uptr_type;
NET_API_STATUS result;
DWORD EntriesRead, TotalEntries;
USE_INFO_2_uptr_type uptrinfo(nullptr, [](USE_INFO_2 *f) {
NetApiBufferFree(static_cast<LPVOID> (f));
});
USE_INFO_2 * puinfo;
std::vector<USE_INFO_2> _ret;
if ((result = NetUseEnum(
NULL,
2,
reinterpret_cast<LPBYTE*> (&puinfo),
MAX_PREFERRED_LENGTH,
&EntriesRead,
&TotalEntries,
NULL
)) == NERR_Success) {
uptrinfo.reset(puinfo);
_ret.insert(_ret.end(), puinfo, &puinfo[TotalEntries]);
/* Tampoco funciona así */
//_ret.resize(TotalEntries);
//memcpy(&_ret[0], puinfo, TotalEntries * sizeof (USE_INFO_2));
}
/* Aquí la información es mostrada correcta*/
for (USE_INFO_2 ui2 : _ret) {
std::wcout << ":" << ui2.ui2_remote << std::endl;
}
return _ret;
}
And I intend to use it like this:
const std::vector<USE_INFO_2> connections = getConnections2shared();
But once NetApiBufferFree is called the vector content gets corrupted. Note that within the function, it correctly displays the information. I have tried removing the call to NetApiBufferFree and then the behavior outside the function is as expected.
Any ideas?
Thanks!
Answer:
It is very normal for you to fail. Let's review USE_INFO_2
:
typedef struct _USE_INFO_2 {
USE_INFO_1 ui2_useinfo;
wchar_t* ui2_username;
wchar_t* ui2_domainname;
} USE_INFO_2,
ui2_useinfo: A pointer to the USE_INFO_1 (section 2.2.5.22) structure entries returned by the method.
ui2_username: A pointer to a string that contains the name of the user who initiated the connection.
ui2_domainname: A pointer to a string that contains the domain name of the remote resource.
Y ahora, USE_INFO_1:
typedef struct _USE_INFO_1 {
wchar_t* ui1_local;
wchar_t* ui1_remote;
wchar_t* ui1_password;
long ui1_status;
unsigned long ui1_asg_type;
unsigned long ui1_refcount;
unsigned long ui1_usecount;
} USE_INFO_1,
As you can see, 3/4 of the same: more pointers.
By themselves, those structures only contain pointers , which become invalid as soon as you call NetApiBufferFree( )
.
You have several options. Personally, I would use my own MyUseInfo2
class with a constructor that takes care of copying the important data:
example:
struct MyUseInfo {
std::wstring local;
std::wstring remote;
std::wstring password;
long status;
...
std::wstring user;
std::wstring domain;
MyUseInfo( USE_INFO_2 * ) { ... }
};
And then you could easily use it in your code, by changing your std::vector<USE_INFO_2>
to std::vector< MyUseInfo >
.