Windows Netapi32

我目前正在使用Netapi32.lib访问Windows Netapi32 ,目前我正在使用c++来访问api。 我在检索计算机名称时遇到了问题,目前这里是FILE_INFO_3结构中的一个NetFileEnum 。 在文件中说,

fi3_username

指向一个string的指针,该string指定哪个用户(在具有用户级别安全性的服务器上)或哪个计算机(在具有共享级别安全性的服务器上)打开了该资源。 请注意,Windows不支持共享级别的安全性。如果定义了_WIN32_WINNT或FORCE_UNICODE,则此string为Unicode。

现在,我正在运行这个脚本的networking确实拥有共享级别的安全性 ,我只是不知道如何列出计算机名称。

相关的代码

图书馆包括:

 #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 [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 + +

完整的testing程序:

 #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; } 

输出:

从构build:

 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函数,文档在这里 。 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文档。