1

私は現在、Netapi32を使用して Windows にアクセスしています。現在、API へのアクセスNetapi32.libに使用しています。c++コンピューター名の取得に問題があります。現在、NetFileEnum hereFILE_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_LEVELlevel パラメータに指定された値が無効です。
  • 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
4

1 に答える 1

1

他の誰かが解決策について疑問に思っている場合、私はそれを理解しました. Computerだけでなく に関連付けられているファイルの数を照会するにはUserNetFileEnum関数を使用する必要があります。ドキュメントはこちら. 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 Nameasを渡す必要がある場所(ネットワーク内のすべてのコンピューター名を返すクエリを実行LMSTR usernameしてコンピューター名を取得できます。ドキュメントはこちら)。クエリは に基づいてファイルの詳細を返します(ドキュメントはこちらとドキュメントはこちら) 。NetSessionEnum(502)DWORD levelFILE_INFO_3FILE_INFO_2

于 2013-04-10T21:29:56.977 に答える