私は現在、Netapi32
を使用して Windows にアクセスしています。現在、API へのアクセスNetapi32.lib
に使用しています。c++
コンピューター名の取得に問題があります。現在、NetFileEnum
hereのFILE_INFO_3
構造体hereの 1 つです。ドキュメントには、次のように書かれています。
fi3_ユーザー名
どのユーザー (ユーザー レベルのセキュリティを持つサーバー上) またはどのコンピューター (共有レベルのセキュリティを持つサーバー上) がリソースを開いたかを指定する文字列へのポインター。Windows は共有レベルのセキュリティをサポートしていないことに注意してください。_WIN32_WINNT または FORCE_UNICODE が定義されている場合、この文字列は Unicode です。
現在、このスクリプトを実行しているネットワークには確かに共有レベルのセキュリティがありますが、コンピューター名を一覧表示する方法がわかりません。
関連コード
ライブラリには以下が含まれます:
#pragma comment(lib, "Netapi32.lib")
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <lm.h>
構造を開始する:
fstatus
私のコードでは、 として定義されていますNET_API_STATUS fStatus
。これは I/O 構造です。ドキュメントはこちら
成功した場合fstatus
は戻り値NERR_Success
。
関数が失敗した場合、戻り値は次のエラー コードのいずれかになります。
ERROR_ACCESS_DENIED
ユーザーは要求された情報にアクセスできません。ERROR_INVALID_LEVEL
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 [アウト]
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