MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Получить список дисков через WINAPI на удаленном сервере"
Answer 922784
Физические диски можно получить через Setup API. Как-то так (С++):
#include <stdlib.h> #include <stdio.h> #include <tchar.h> #include <locale.h> #include <windows.h> #include <Setupapi.h> #include <LM.h> #define INITGUID #include <Devpkey.h> #pragma comment(lib,"Setupapi.lib") #pragma comment(lib,"Netapi32.lib") void ErrorMes(LPCTSTR lpszFunction) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); // Display the error message lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen(lpszFunction) + 40) * sizeof(TCHAR)); wprintf(L"%s failed with error %d: %s", lpszFunction, dw, (LPSTR)lpMsgBuf); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); } void PrintDisks(const GUID * guidInterface) { DEVPROPTYPE dpt = 0; wchar_t buffer[1024] = L""; DWORD RequiredSize = 0; SP_DEVINFO_DATA devinfo = { 0 }; SP_DEVICE_INTERFACE_DATA deviceInterface = { 0 }; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail = NULL; BOOL res; USE_INFO_2 info; info.ui2_asg_type = USE_WILDCARD; info.ui2_local = NULL; info.ui2_domainname = (LPWSTR)L"DOMEN"; info.ui2_username = (LPWSTR)L"User"; info.ui2_password = (LPWSTR)L"123"; info.ui2_remote = (LPWSTR)L"\\\\server\\IPC$"; DWORD parm = 0; DWORD dwRes = NetUseAdd(NULL, 2, (LPBYTE)&info, &parm); if(dwRes != NERR_Success)printf("NetUseAdd failed: %u (%u)\n",dwRes,parm); HDEVINFO deviceInfoHandle = SetupDiGetClassDevsEx(guidInterface, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE, NULL, L"\\\\server",NULL); if (deviceInfoHandle != INVALID_HANDLE_VALUE) { int deviceIndex = 0; while (true) { ZeroMemory(&deviceInterface, sizeof(deviceInterface)); deviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); //получение всех дисков if (SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, guidInterface, deviceIndex, &deviceInterface)) { DWORD cbRequired = 0; SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, 0, 0, &cbRequired, 0); if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { deviceInterfaceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)(new char[cbRequired]); memset(deviceInterfaceDetail, 0, cbRequired); deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, deviceInterfaceDetail, cbRequired, &cbRequired, 0)) { goto Next; } // Initialize the structure before using it. memset(deviceInterfaceDetail, 0, cbRequired); deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // Call the API a second time to retrieve the actual // device path string. BOOL status = SetupDiGetDeviceInterfaceDetail( deviceInfoHandle, // Handle to device information set &deviceInterface, // Pointer to current node in devinfo set deviceInterfaceDetail, // Pointer to buffer to receive device path cbRequired, // Length of user-allocated buffer &cbRequired, // Pointer to arg to receive required buffer length NULL); // Not interested in additional data //получение информации о устройстве ZeroMemory(&devinfo, sizeof(devinfo)); devinfo.cbSize = sizeof(SP_DEVINFO_DATA); BOOL success = SetupDiEnumDeviceInfo(deviceInfoHandle, deviceIndex, &devinfo); if (success == FALSE) { ErrorMes(L"SetupDiEnumDeviceInfo"); goto Next; } res = SetupDiGetDeviceProperty(deviceInfoHandle, &devinfo, &DEVPKEY_NAME, &dpt, (PBYTE)buffer, 1000, NULL, 0); if (res == FALSE) { ErrorMes(L"SetupDiGetDeviceProperty"); goto Next; } wprintf(L"%s: %s\n", buffer, deviceInterfaceDetail->DevicePath); } } else { break; } Next: if (deviceInterfaceDetail != NULL) { delete[] deviceInterfaceDetail; deviceInterfaceDetail = NULL; } deviceIndex++; //следующее устройство } SetupDiDestroyDeviceInfoList(deviceInfoHandle); } else ErrorMes(L"SetupDiGetClassDevsEx"); } int __cdecl main(int argc, char **argv) { setlocale(LC_ALL, "Russian"); PrintDisks(&GUID_DEVINTERFACE_DISK); PrintDisks(&GUID_DEVINTERFACE_CDROM); getchar(); return 0; }
Однако, этот способ не работает на Windows 10. Удаленный диспетчер устройств в ней был исключен, а вместе с ним и используемые им API.
Список букв разделов можно получить, подключившись к удаленному реестру, он хранится в ветке
HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices
. Способа получить метки разделов для удаленного компьютера вроде нет.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.