我目前正在使用Netapi32访问Windows Netapi32.lib,当前正在使用c++访问api。我在检索计算机名称时遇到麻烦,当前是NetFileEnum结构here上的FILE_INFO_3 here。在文档中说:



现在,运行此脚本的网络确实具有共享级别的安全性,但我不确定如何列出计算机名称。

相关代码

图书馆包括:

#pragma comment(lib, "Netapi32.lib")
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <lm.h>

启动结构:
fstatus在我的代码中定义为NET_API_STATUS fStatus,它是I / O结构。文档here

如果fstatus成功,则返回值NERR_Success

如果函数失败,则返回值可以是以下错误代码之一。
  • ERROR_ACCESS_DENIED用户无权访问所请求的
    信息。
  • ERROR_INVALID_LEVEL为level参数指定的值为
    无效。
  • ERROR_INVALID_PARAMETER指定的参数无效。
  • ERROR_MORE_DATA More条目可用。指定足够大的缓冲区以接收所有条目。
  • ....

  • 更多here

    为了解决这个问题,我使用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级(文档here)缓冲区对象,



    该缓冲区以这种格式返回数据,
    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
    

    最佳答案

    如果有人对解决方案感到疑惑,我想通了。要查询与Computer相关的文件数,而不仅仅是User,必须使用NetFileEnum函数here文档。 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)来检索计算机名称,这将返回网络中的所有计算机名称,文档here),并且查询基于DWORD level返回文件详细信息,FILE_INFO_3文档hereFILE_INFO_2文档here

    关于c++ - Windows Netapi32,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15888794/

    10-15 16:58