GlobalAllo c вместо другого метода распределения - PullRequest
0 голосов
/ 09 июля 2020

При просмотре кода в MSDN для поиска владельца данного файлового объекта программа использует GlobalAlloc() для выделения памяти для AcctName. Поскольку я новичок в использовании Win32 API, мое любопытство заставило меня поинтересоваться, почему мы используем GlobalAlloc() вместо других методов распределения. Если существуют другие лучшие методы распределения, как использовать их в данном коде?

#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "accctrl.h"
#include "aclapi.h"
#pragma comment(lib, "advapi32.lib")

int main(void)
{
DWORD dwRtnCode = 0;
PSID pSidOwner = NULL;
BOOL bRtnBool = TRUE;
LPTSTR AcctName = NULL;
LPTSTR DomainName = NULL;
DWORD dwAcctName = 1, dwDomainName = 1;
SID_NAME_USE eUse = SidTypeUnknown;
HANDLE hFile;
PSECURITY_DESCRIPTOR pSD = NULL;


// Get the handle of the file object.
hFile = CreateFile(
                  TEXT("myfile.txt"),
                  GENERIC_READ,
                  FILE_SHARE_READ,
                  NULL,
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL,
                  NULL);

// Check GetLastError for CreateFile error code.
if (hFile == INVALID_HANDLE_VALUE) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();
          _tprintf(TEXT("CreateFile error = %d\n"), dwErrorCode);
          return -1;
}



// Get the owner SID of the file.
dwRtnCode = GetSecurityInfo(
                  hFile,
                  SE_FILE_OBJECT,
                  OWNER_SECURITY_INFORMATION,
                  &pSidOwner,
                  NULL,
                  NULL,
                  NULL,
                  &pSD);

// Check GetLastError for GetSecurityInfo error condition.
if (dwRtnCode != ERROR_SUCCESS) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();
          _tprintf(TEXT("GetSecurityInfo error = %d\n"), dwErrorCode);
          return -1;
}

// First call to LookupAccountSid to get the buffer sizes.
bRtnBool = LookupAccountSid(
                  NULL,           // local computer
                  pSidOwner,
                  AcctName,
                  (LPDWORD)&dwAcctName,
                  DomainName,
                  (LPDWORD)&dwDomainName,
                  &eUse);

// Reallocate memory for the buffers.
AcctName = (LPTSTR)GlobalAlloc(
          GMEM_FIXED,
          dwAcctName);

// Check GetLastError for GlobalAlloc error condition.
if (AcctName == NULL) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();
          _tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
          return -1;
}

    DomainName = (LPTSTR)GlobalAlloc(
           GMEM_FIXED,
           dwDomainName);

    // Check GetLastError for GlobalAlloc error condition.
    if (DomainName == NULL) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();
          _tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
          return -1;

    }

    // Second call to LookupAccountSid to get the account name.
    bRtnBool = LookupAccountSid(
          NULL,                   // name of local or remote computer
          pSidOwner,              // security identifier
          AcctName,               // account name buffer
          (LPDWORD)&dwAcctName,   // size of account name buffer 
          DomainName,             // domain name
          (LPDWORD)&dwDomainName, // size of domain name buffer
          &eUse);                 // SID type

    // Check GetLastError for LookupAccountSid error condition.
    if (bRtnBool == FALSE) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();

          if (dwErrorCode == ERROR_NONE_MAPPED)
              _tprintf(TEXT
                  ("Account owner not found for specified SID.\n"));
          else 
              _tprintf(TEXT("Error in LookupAccountSid.\n"));
          return -1;

    } else if (bRtnBool == TRUE) 

        // Print the account name.
        _tprintf(TEXT("Account owner = %s\n"), AcctName);

    return 0;
}

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

Спасибо всем. Я только что изменил свой код, используя malloc.

    AccountBuff = (LPSTR)malloc(AccountBufflength * sizeof(LPSTR));
    DomainBuff = (LPSTR)malloc(DomainBufflength * sizeof(LPSTR));
0 голосов
/ 09 июля 2020

См. на этой странице документации Microsoft для обзора различных функций распределения памяти, которые в настоящее время существуют в Microsoft Windows.

По сути, GlobalAlloc является остатком 16-битный Windows. В 32-битных и 64-битных Windows больше нет различия между GlobalAlloc и LocalAlloc, поскольку современные операционные системы используют модель плоской памяти . Если вам интересно, какое значение имели эти функции в 16-битном Windows, вы можете прочитать эту статью блогера Microsoft Раймонда Чена.

Как указано в официальной документации функции GlobalAlloc, эту функцию, как правило, не следует использовать в современных 32-битных или 64-битных приложениях, за исключением ситуаций, когда в документации специально указано это делать.

Поскольку официальная документация по функции LookupAccountSid не указывает, что какой-либо из переданных буферов должен быть выделен с помощью GlobalAlloc, нет причин использовать эту функцию. Было бы более подходящим, например, использовать функцию HeapAlloc, поскольку эта функция имеет меньшие накладные расходы, чем GlobalAlloc. В качестве альтернативы вы можете использовать обычные распределения памяти C ++ (например, new или std::vector), которые, в зависимости от реализации, вероятно, косвенно вызывают функцию HeapAlloc.

...