Windows Netapi32
Я сейчас получаю доступ к Windows Netapi32
с помощью Netapi32.lib
В настоящее время я использую c++
чтобы получить доступ к API. У меня проблемы с получением имени компьютера, в настоящее время NetFileEnum
здесь на FILE_INFO_3
структура здесь. В документации сказано:
fi3_username
Указатель на строку, которая указывает, какой пользователь (на серверах с безопасностью на уровне пользователей) или какой компьютер (на серверах с безопасностью на уровне общих ресурсов) открыл ресурс. Обратите внимание, что Windows не поддерживает безопасность на уровне общего ресурса. Эта строка является Unicode, если определены _WIN32_WINNT или FORCE_UNICODE.
Теперь сеть, в которой я запускаю этот скрипт, действительно имеет безопасность на уровне общего ресурса, я просто не знаю, как указать имя компьютера.
Соответствующий код
Библиотека включает в себя:
#pragma comment(lib, "Netapi32.lib")
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <lm.h>
Начальная структура:
fstatus
определяется в моем коде как, NET_API_STATUS fStatus
это структура ввода / вывода. Документация здесь
если fstatus
Успешно возвращаемое значение NERR_Success
,
Если функция завершается ошибкой, возвращаемое значение может быть одним из следующих кодов ошибок.
ERROR_ACCESS_DENIED
Пользователь не имеет доступа к запрашиваемой информации.ERROR_INVALID_LEVEL
Значение, указанное для параметра уровня, недопустимо.ERROR_INVALID_PARAMETER
Указанный параметр недействителен.ERROR_MORE_DATA More
Записи доступны. Укажите достаточно большой буфер для получения всех записей.- ....
больше здесь
Чтобы справиться с этим я использую if ((fStatus == NERR_Success) || (fStatus == ERROR_MORE_DATA))
Имя пользователя не может быть найдено.
fStatus = NetFileEnum(
flServerName, //Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is NULL, the local computer is used.
flBasePath, //Pointer to a string that specifies a qualifier for the returned information. If this parameter is NULL, all open resources are enumerated.
flUserName, //Pointer to a string that specifies the name of the user or the name of the connection.
dfLevel, //Pointer to a string that specifies the name of the user or the name of the connection. Can be either 2 or 3, I am using 3
(LPBYTE*)&pFile, //Pointer to the address of the buffer that receives the information. The format of this data depends on the value of the level parameter.
fwPrefMaxLen, //pecifies the preferred maximum length of returned data, in bytes.
&fwEntriesRead, //Pointer to a value that receives the count of elements actually enumerated.
&fwTotalEntries, //Pointer to a value that receives the total number of entries that could have been enumerated from the current resume position.
&fwResumeHandle); //Pointer to a value that contains a resume handle which is used to continue an existing file search.
NET_API_STATUS NetFileEnum(
_In_ LMSTR servername,
_In_ LMSTR basepath,
_In_ LMSTR username,
_In_ DWORD level,
_Out_ LPBYTE *bufptr,
_In_ DWORD prefmaxlen,
_Out_ LPDWORD entriesread,
_Out_ LPDWORD totalentries,
_Inout_ PDWORD_PTR resume_handle
);
RAW значения для вышеупомянутого:
NET_API_STATUS fStatus;
LPFILE_INFO_3 pFile = NULL;
LPFILE_INFO_3 pTmpFile;
DWORD dfLevel = 3;
LPTSTR flServerName = NULL;
LPTSTR flUserName = NULL;
LPTSTR flBasePath = NULL;
DWORD fwPrefMaxLen = MAX_PREFERRED_LENGTH;
DWORD fwEntriesRead = 0;
DWORD fwTotalEntries = 0;
DWORD fwResumeHandle = 0;
pTmpfile
является буферным объектом уровня 3 (документация здесь),
bufptr [out]
Pointer to the address of the buffer that receives the information. The format of this data depends on the value of the levelparameter.
Этот буфер возвращает данные в этом формате,
typedef struct _FILE_INFO_3 {
DWORD fi3_id;
DWORD fi3_permissions;
DWORD fi3_num_locks;
LMSTR fi3_pathname;
LMSTR fi3_username;
} FILE_INFO_3, *PFILE_INFO_3, *LPFILE_INFO_3;
Получить данные:
printf("\n\tComputer: %S\n", pTmpFile->fi3_username); //how do I retrieve computer name???
printf("\n\tid: %D\n", pTmpFile->fi3_id);
printf("\n\tpath: %S\n", pTmpFile->fi3_pathname);
** Важно отметить, что я пробовал это с помощью vbnet, и это работает, но как-то не могу понять, как это сделать на C++.
Полная программа испытаний:
#ifndef UNICODE
#define UNICODE
#endif
//Initialize the NetAPI Library
#pragma comment(lib, "Netapi32.lib")
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <lm.h>
int wmain(int argc, wchar_t *argv[])
{
//NetFile Enum, using 3 Level.
NET_API_STATUS fStatus;
LPFILE_INFO_3 pFile = NULL;
LPFILE_INFO_3 pTmpFile;
DWORD dfLevel = 3;
LPTSTR flServerName = NULL;
LPTSTR flUserName = NULL;
LPTSTR flBasePath = NULL;
DWORD fwPrefMaxLen = MAX_PREFERRED_LENGTH;
DWORD fwEntriesRead = 0;
DWORD fwTotalEntries = 0;
DWORD fwResumeHandle = 0;
DWORD fi;
//
// Check command line arguments.
// Dont need this currently.
//
do
{
fStatus = NetFileEnum(flServerName,
flBasePath,
flUserName,
dfLevel,
(LPBYTE*)&pFile,
fwPrefMaxLen,
&fwEntriesRead,
&fwTotalEntries,
&fwResumeHandle);
if ((fStatus == NERR_Success) || (fStatus == ERROR_MORE_DATA))
{
if ((pTmpFile = pFile) != NULL)
{
for (fi=0; fi < fwEntriesRead; fi++)
{
assert(pTmpFile != NULL);
if (pTmpFile == NULL)
{
fprintf(stderr, "An access violation has occurred\n");
break;
}
printf("\n\tComputer: %S", pTmpFile->fi3_username);
printf("\n\tid: %d", pTmpFile->fi3_id);
printf("\n\tpath: %s", pTmpFile->fi3_pathname);
printf("\n\tLocks: %d\n", pTmpFile->fi3_num_locks);
pTmpFile++;
fwTotalEntries++;
}
}
}
else
fprintf(stderr, "A system error has occurred: %d\n", fStatus);
//
// Free the allocated memory.
//
if (pFile != NULL)
{
NetApiBufferFree(pFile);
pFile = NULL;
}
}
//
// Continue to call NetFilEnum while
// there are more entries.
//
while (fStatus == ERROR_MORE_DATA);
if (pFile != NULL)
NetApiBufferFree(pFile);
return 0;
}
Выход:
Из сборки:
1>------ Build started: Project: Perfmon, Configuration: Release Win32 ------
1>Compiling...
1>file_enumerate.cpp
1>Linking...
1>Generating code
1>Finished generating code
1>Embedding manifest...
1>Build log was saved at "file://...."
1>Perfmon - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Бежать:
Computer: User1 //prints only username, not computername (in our system, each user has the same username)
id: 1005687
path: c:\fips\library
Computer: User2 //prints only username, not computername (in our system, each user has the same username)
id: 1005689
path: c:\fips\library\util
1 ответ
Если кто-то еще задается вопросом о решении, я понял это. Для запроса количества файлов, связанных с Computer
и не только User
, NetFileEnum
Функция должна быть использована, документация здесь. NetFileEnum
синтаксис показан ниже,
NET_API_STATUS NetFileEnum(
_In_ LMSTR servername,
_In_ LMSTR basepath,
_In_ LMSTR username,
_In_ DWORD level,
_Out_ LPBYTE *bufptr,
_In_ DWORD prefmaxlen,
_Out_ LPDWORD entriesread,
_Out_ LPDWORD totalentries,
_Inout_ PDWORD_PTR resume_handle
);
Где вы должны пройти Computer Name
как LMSTR username
(вы можете получить имя компьютера по запросу NetSessionEnum(502)
который будет возвращать все имена компьютеров в сети, документацию здесь), а запрос возвращает сведения о файле на основе DWORD level
, или FILE_INFO_3
документация здесь и FILE_INFO_2
документация здесь.