2015-04-03 24 views
0

我一直在使用從過濾器驅動程序接收消息的應用程序。驅動程序完美工作,但是我的內存管理存在問題,可能是LPTSTR 用戶 & 使用兩個LPTSTR時發生堆損壞

在調試,我得到的消息有關堆損壞,他們通常指向到兩個免費 S或第二執行LookupAccountSid調用。我在這裏做錯了什麼?

#include "stdafx.h" 
#include "myapp-service.h" 
#include <Windows.h> 
#include <fltUser.h> 
#include <string> 
#include <sddl.h> 

BOOL 
getUser(
_In_ WCHAR* sidstr, 
_Inout_ LPTSTR* AcctName, 
_Inout_ LPTSTR* DomainName 
) 
{ 
    PSID sid; 
    DWORD dwAcctName = 1; 
    DWORD dwDomainName = 1; 
    SID_NAME_USE eUse = SidTypeUnknown; 
    bool success; 

    if (!ConvertStringSidToSidW(sidstr, &sid)) 
    { 
     printf_s("ConvertStringSidToSid failed with 0x%08x\n", GetLastError); 
     return false; 
    } 

    // Lookup! 
    LookupAccountSid(
     NULL, 
     sid, 
     *AcctName, 
     (LPDWORD)&dwAcctName, 
     *DomainName, 
     (LPDWORD)&dwDomainName, 
     &eUse); 

    *AcctName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwAcctName); 
    *DomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwDomainName); 

    success = LookupAccountSid(
     NULL, 
     sid, 
     *AcctName, 
     (LPDWORD)&dwAcctName, 
     *DomainName, 
     (LPDWORD)&dwDomainName, 
     &eUse); 

    if (success) { 
     _tprintf(TEXT("Username %[email protected]%s\n"), *AcctName, *DomainName); 
    } 
    else { 
     printf_s("LookupAccountSid failed with 0x%08x\n", GetLastError); 
     return false; 
    } 

    return true; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HRESULT status; 
    HANDLE port; 
    myapp_USER_MESSAGE msg; 

    // 
    // Open a communication channel to the filter 
    // 

    printf("myapp-service: Connecting to the filter ...\n"); 

    status = FilterConnectCommunicationPort(myappPortName, 
     0, 
     NULL, 
     0, 
     NULL, 
     &port); 

    if (IS_ERROR(status)) { 

     printf("ERROR: Connecting to filter port: 0x%08x\n", status); 
     return 2; 
    } 

    // 
    // Fetch messages & handle them 
    // 

    while (TRUE) { 
     status = FilterGetMessage(port, 
      &msg.MessageHeader, 
      sizeof(msg), 
      NULL 
      ); 

     if (status == S_OK) { 
      // Got a message successfully! 

      // The problem is most likely with these two 
      LPTSTR user = NULL; 
      LPTSTR domain = NULL; 

      if (getUser(msg.Message.Sid, &user, &domain)) { 
       _tprintf(TEXT("Username %[email protected]%s accessed %ls at %ls\n"), user, domain, &msg.Message.FileName, &msg.Message.TimeStamp); 
      } 
      else { 
       printf("Unable to get user data!"); 
      }; 

      if (user) { 
       GlobalFree(user); 
      } 
      if (domain) { 
       GlobalFree(domain); 
      } 

     } 
     else { 
      printf("ERROR: GetMessage: 0x%08x\n", status); 
     } 

     printf("\n\n"); 
    } 

    // 
    // Close the communication channel to the filter 
    // 

    printf("myapp-service: Closing connection ...\n"); 

    CloseHandle(&port); 

    return 0; 
} 

回答

2

參數cchNameLookupAccountSidcchReferenceDomainNamecch(即字符計數)前綴。你必須考慮到的是分配內存時,因爲GlobalAlloc需要的字節數:

*AcctName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwAcctName * sizeof(TCHAR)); 
*DomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwDomainName * sizeof(TCHAR)); 

你應該也首次呼叫優先於零初始化尺寸參數:

DWORD dwAcctName = 0x0; 
DWORD dwDomainName = 0x0; 

如果因爲緩衝區太小或如果函數失敗:

本文檔中概述cchName爲零,cchName接收所需的緩衝區大小,包括終止空字符。


順便說一句:無論你 printf_s通話將打印 地址GetLastError,而不是它的返回值。你必須添加圓括號( GetLastError())來調用函數調用。

1
*AcctName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwAcctName*sizeof(TCHAR)); 
*DomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwDomainName*sizeof(TCHAR)); 

因爲在TCHARS返回執行LookupAccountSid尺寸,而不是在字節