我目前正在使用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
文档。