没有 SMBv1 的 WINAPI 网络发现
WINAPI Network Discovery without SMBv1
我需要获取本地网络上可用共享文件夹的列表,以及它们在文件资源管理器的“网络”选项卡中的显示方式。早些时候,我使用 NetServerEnum/NetShareEnum 函数的组合来获取它,但它们使用的是 SMBv1 协议,该协议现在在 windows 中默认禁用,所以现在我从 NetServerEnum 收到错误 1231。但是文件资源管理器仍然可以获取此列表。我尝试使用 Process Monitor 来确定它使用哪个 API,但失败了。那么,有没有什么方法可以在不使用需要 SMBv1 的 API 的情况下获取本地网络中的可用共享文件夹列表?
您可以使用windows shell api 并使用FOLDERID_NetworkFolder
得到“network”的KNOWNFOLDERID。
以下示例可以获取“网络”文件夹中的文件夹、非文件夹和隐藏项目。
#include <windows.h>
#include <Shobjidl.h>
#include <Shlobj.h>
#include <iostream>
void wmain(int argc, TCHAR* lpszArgv[])
{
IShellItem* pShellItem;
IEnumShellItems* pShellEnum = NULL;
HRESULT hr = S_OK;
hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("CoInitialize error, %x\n", hr);
return;
}
hr = SHGetKnownFolderItem(FOLDERID_NetworkFolder, KF_FLAG_DEFAULT, NULL, IID_PPV_ARGS(&pShellItem));
if (FAILED(hr))
{
printf("SHGetKnownFolderItem error, %x\n", hr);
return;
}
hr = pShellItem->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&pShellEnum));
if (FAILED(hr))
{
printf("BindToHandler error, %x\n", hr);
return;
}
do {
IShellItem* pItem;
LPWSTR szName = NULL;
hr = pShellEnum->Next(1, &pItem, nullptr);
if (hr == S_OK && pItem)
{
HRESULT hres = pItem->GetDisplayName(SIGDN_NORMALDISPLAY, &szName);
std::wcout << szName << std::endl;
CoTaskMemFree(szName);
}
} while (hr == S_OK);
CoUninitialize();
}
我需要获取本地网络上可用共享文件夹的列表,以及它们在文件资源管理器的“网络”选项卡中的显示方式。早些时候,我使用 NetServerEnum/NetShareEnum 函数的组合来获取它,但它们使用的是 SMBv1 协议,该协议现在在 windows 中默认禁用,所以现在我从 NetServerEnum 收到错误 1231。但是文件资源管理器仍然可以获取此列表。我尝试使用 Process Monitor 来确定它使用哪个 API,但失败了。那么,有没有什么方法可以在不使用需要 SMBv1 的 API 的情况下获取本地网络中的可用共享文件夹列表?
您可以使用windows shell api 并使用FOLDERID_NetworkFolder
得到“network”的KNOWNFOLDERID。
以下示例可以获取“网络”文件夹中的文件夹、非文件夹和隐藏项目。
#include <windows.h>
#include <Shobjidl.h>
#include <Shlobj.h>
#include <iostream>
void wmain(int argc, TCHAR* lpszArgv[])
{
IShellItem* pShellItem;
IEnumShellItems* pShellEnum = NULL;
HRESULT hr = S_OK;
hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("CoInitialize error, %x\n", hr);
return;
}
hr = SHGetKnownFolderItem(FOLDERID_NetworkFolder, KF_FLAG_DEFAULT, NULL, IID_PPV_ARGS(&pShellItem));
if (FAILED(hr))
{
printf("SHGetKnownFolderItem error, %x\n", hr);
return;
}
hr = pShellItem->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&pShellEnum));
if (FAILED(hr))
{
printf("BindToHandler error, %x\n", hr);
return;
}
do {
IShellItem* pItem;
LPWSTR szName = NULL;
hr = pShellEnum->Next(1, &pItem, nullptr);
if (hr == S_OK && pItem)
{
HRESULT hres = pItem->GetDisplayName(SIGDN_NORMALDISPLAY, &szName);
std::wcout << szName << std::endl;
CoTaskMemFree(szName);
}
} while (hr == S_OK);
CoUninitialize();
}