简体   繁体   English

NetApiBufferFree返回ERROR_INVALID_PARAMETER(错误代码87)

[英]NetApiBufferFree returns ERROR_INVALID_PARAMETER (Error Code 87)

I have been developing an application that uses winapi to get administrator group members. 我一直在开发一个使用winapi来获取管理员组成员的应用程序。 I used NetLocalGroupGetMembers method for that purpose. 我为此目的使用了NetLocalGroupGetMembers方法。 My problem is when i try to free buffer's heap space i get ERROR_INVALID_PARAMETER (Error Code 87) from NetApiBufferFree method. 我的问题是当我尝试释放缓冲区的堆空间时,我从NetApiBufferFree方法获得ERROR_INVALID_PARAMETER(错误代码87)。 I have administrator privileges for the application. 我有应用程序的管理员权限。

Here is the code: 这是代码:

#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <lm.h>
#include <time.h>
#include <assert.h>

#define SLEEP_TIME 2000
#define OS_GROUP_NAME L"administrators"

void createServiceThread();
DWORD WINAPI mainServiceThread( LPVOID lpParam );
char** getUsersByLocalGroup();
void freeNetApiBuffer(LPVOID buffer);

int localGroupUserCount;

int WriteToLog(char* str)
{
    printf("%s\n", str);
    return 0;
}

int main() 
{ 
    createServiceThread();  
}

void createServiceThread(){
    WriteToLog("Application Started...");
    while(TRUE){
        mainServiceThread(NULL);

        Sleep(SLEEP_TIME);
    }
    WriteToLog("Application Closed...");
}

//-------------------------------------------
// A function that represents Main Service Thread
//-------------------------------------------
DWORD WINAPI mainServiceThread( LPVOID lpParam ) 
{
    time_t startTime;
    time (&startTime);
    char startTimeText[30];
    sprintf(startTimeText, "Service Loop Started %s", ctime(&startTime));
    WriteToLog(startTimeText);
    localGroupUserCount = 0;

    char** localGroupUsers = getUsersByLocalGroup();

    WriteToLog("User not found...");

    time_t endTime;
    time (&endTime);
    char endTimeText[30];
    sprintf(endTimeText, "Service Loop Ended %s", ctime(&endTime));
    WriteToLog(endTimeText);
}

char** getUsersByLocalGroup(){
    WriteToLog("getUsersByLocalGroup started");
    LOCALGROUP_MEMBERS_INFO_3 *pBuf;
    DWORD dwLevel = 3;
    DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
    DWORD dwEntriesRead = 0;
    DWORD dwTotalEntries = 0;
    DWORD dwResumeHandle = 0;
    NET_API_STATUS nStatus;

    WriteToLog("Call NetLocalGroupGetMembers"); 
    nStatus = NetLocalGroupGetMembers(
        NULL,
        OS_GROUP_NAME,
        dwLevel,
        (LPBYTE *) &pBuf,
        dwPrefMaxLen,
        &dwEntriesRead,
        &dwTotalEntries,
        NULL
    );  
//  nStatus = ERROR_SUCCESS;
    WriteToLog("NetLocalGroupGetMembers called");
    //
    // If the call succeeds,
    //
    if (nStatus == ERROR_SUCCESS  || nStatus == ERROR_MORE_DATA)
    {
        DWORD i;
        DWORD dwTotalCount = 0;
        WriteToLog("Correct Status");
        if (pBuf != NULL)
        {
            //
            // Loop through the entries.
            //
            for (i = 0; (i < dwEntriesRead); i++)
            {
                assert(pBuf != NULL);

                if (pBuf == NULL)
                {
                    char bufError[] = "";
                    sprintf(bufError, "An access violation has occurred %d", stderr);
                    WriteToLog(bufError);
                    break;
                }
                LPWSTR userNameOnBuffer = pBuf->lgrmi3_domainandname;
                pBuf++;
                dwTotalCount++;     
            }
            localGroupUserCount = dwTotalCount;
            char totalCount[] = "";
            sprintf(totalCount, "Entries enumerated: %d", dwTotalCount);
            WriteToLog(totalCount); 
        }
        //
        // Otherwise, print the system error.
        //
        else{
        char systemError[] = "";
        sprintf(systemError, "An system error has occurred %d - %d", stderr, nStatus);
        WriteToLog(systemError);
        }
    }
    //
    // Free the allocated buffer.
    //  
    if (pBuf != NULL)
    {
        NET_API_STATUS nBufferFreeStatus = NetApiBufferFree((LPVOID)pBuf);
        if(nBufferFreeStatus == NERR_Success){
            WriteToLog("Succesfully freed buffer");
        }
        else{
            WriteToLog("Error occured freeing buffer");
        }
        pBuf = NULL;
    }
    WriteToLog("getUsersByLocalGroup finished");
    return NULL;
}

In your loop you have the line pBuf++; 在你的循环中你有pBuf++;pBuf++; . This modifies pBuf which means that the value you are freeing is not the value that was allocated. 这会修改pBuf ,这意味着您释放的值不是已分配的值。 Hence the invalid parameter. 因此无效参数。

Also, these lines 还有,这些线

char totalCount[] = "";
sprintf(totalCount, "Entries enumerated: %d", dwTotalCount);

create a stack buffer overflow, which is probably corrupting your pBuf variable. 创建堆栈缓冲区溢出,这可能会破坏您的pBuf变量。 There is another instance of it a few lines later. 几行之后还有另一个例子。

In general, here's how you debug it: Set a breakpoint as soon as NetLocalGroupGetMembers returns. 通常,以下是调试方法: NetLocalGroupGetMembers返回后立即设置断点。 Look at the value in pBuf and write it down in a safe place. 查看pBuf中的值并将其写在安全的地方。 Set another breakpoint when you are about to call NetApiBufferFree . 当您打算调用NetApiBufferFree时设置另一个断点。 Look at the value of pBuf you are passing. 看看你传递的pBuf的值。 Is it equal to the value you wrote down earlier? 它等于你之前写下的价值吗? If not, then you have a bug. 如果没有,那么你有一个错误。 Use the debugger to find out why you are passing the wrong value. 使用调试器找出传递错误值的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM