Ambiguity between 'PACCESS_MASK', why?

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

Ambiguity between 'PACCESS_MASK', why?

Postby mark_c » Tue Apr 24, 2018 6:22 am

Hello,
I need to extract the permissions from some folders and I found this code on the network, but, unfortunately, the compiler show the error below. I looked for any ambiguous statements in the header files but I can not find them. I tried to reverse the order of the include files but it does not change anything; what can it be?

Thank you


[C++ Error] aclapi.h(102): E2015 Ambiguity between 'PACCESS_MASK' and 'Windows::PACCESS_MASK'

Code: Select all
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused

#include <aclapi.h>
#include <stdio.h>

using namespace std;


int main()
{
   PSID owner = NULL;
        PSID group = NULL;
   PSECURITY_DESCRIPTOR psd = NULL;
   LPTSTR file = ("c:\\windows\\system32\\notepad.exe");
   DWORD retval;
   TCHAR* name, * dname;
   DWORD length, dlength;
   SID_NAME_USE su;

   retval = GetNamedSecurityInfo(file, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &owner, &group, NULL, NULL, &psd);
   if(retval != 0)
   {
        printf("GetNamedSecurityInfo failed with error: %d", retval);
        return -1;
   }

   name = new TCHAR[51];
   dname = new TCHAR[51];
   ZeroMemory(name, 51);
   ZeroMemory(dname, 51);
   length = 50;
   dlength = 50;

   if(!LookupAccountSid(NULL, owner, name, &length, dname, &dlength, &su))
   {
      DWORD dwe = GetLastError();

      printf("LookupAccountSid failed wit error: %d", dwe);
      delete[] name;
      delete[] dname;
      LocalFree(psd);
      return -1;
   }

   printf("Owner of file %s", file);
        printf("is %s\n", name);

   delete[] dname;
   delete[] name;

   LocalFree(psd);

   return 0;
}
mark_c
BCBJ Guru
BCBJ Guru
 
Posts: 111
Joined: Thu Jun 21, 2012 1:13 am

Re: Ambiguity between 'PACCESS_MASK', why?

Postby HsiaLin » Tue Apr 24, 2018 9:19 am

I used your code like this and it works perfectly.
Perhaps its the order of the header files.

Code: Select all
//---------------------------------------------------------------------------
#include <aclapi.h>
#include <stdio.h>
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"



TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{

   PSID owner = NULL;
   PSID group = NULL;
   PSECURITY_DESCRIPTOR psd = NULL;
   LPTSTR file = L"c:\\windows\\system32\\notepad.exe";
   DWORD retval;
   TCHAR* name, * dname;
   DWORD length, dlength;
   SID_NAME_USE su;

   retval = GetNamedSecurityInfo(file, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &owner, &group, NULL, NULL, &psd);
   if(retval != 0)
   {
        ShowMessage("GetNamedSecurityInfo failed with error: " + retval);
        return;
   }

   name = new TCHAR[51];
   dname = new TCHAR[51];
   ZeroMemory(name, 51);
   ZeroMemory(dname, 51);
   length = 50;
   dlength = 50;

   if(!LookupAccountSid(NULL, owner, name, &length, dname, &dlength, &su))
   {
      DWORD dwe = GetLastError();
      ShowMessage("LookupAccountSid failed wit error: " + dwe);
      delete[] name;
      delete[] dname;
      LocalFree(psd);
      return;
   }

   ShowMessage("Owner of file " + String(file) + " is " + name);

   delete[] dname;
   delete[] name;

   LocalFree(psd);

   return;
}

//---------------------------------------------------------------------------

HsiaLin
BCBJ Master
BCBJ Master
 
Posts: 297
Joined: Sun Jul 08, 2007 6:29 pm

Re: Ambiguity between 'PACCESS_MASK', why?

Postby rlebeau » Tue Apr 24, 2018 11:36 am

mark_c wrote:I looked for any ambiguous statements in the header files but I can not find them. I tried to reverse the order of the include files but it does not change anything; what can it be?


The error is telling you that there are multiple conflicting declarations of PACCESS_MASK in scope.

One is defined by the Win32 API in winnt.h in the global namespace:

Code: Select all
typedef DWORD ACCESS_MASK;
typedef ACCESS_MASK *PACCESS_MASK;


The other is defined by the RTL in Windows.hpp in the 'Windows' namespace, but is brought into the global namespace via a 'using namespace Windows' statement:

Code: Select all
namespace Windows {
...
typedef unsigned *PACCESS_MASK;
...
}
...
using namespace Windows;


When compiling aclapi.h, if both winnt.h and Windows.hpp are in scope, the compiler doesn't know which definition of PACCESS_MASK to use, hence the ambiguity error. The API is expecting the one from winnt.h.

FYI, this error was fixed in C++Builder 2009 Update 3 (QC #54900):

https://community.embarcadero.com/artic ... ilder-2009

So you must be using an old version of C++Builder

There is no option to disable the definition of PACCESS_MASK in Windows.hpp, unless you modify that file directly. Otherwise, because of the ambiguity, you won't be able to use aclapi.h in the same unit as Windows.hpp, so you will have to separate your ACL code into another unit that doesn't use Windows.hpp at all.

mark_c wrote:
Code: Select all
LPTSTR file = ("c:\\windows\\system32\\notepad.exe");


When declaring a TCHAR-based variable that is assigned a literal value, you need to use the TEXT() macro:

Code: Select all
LPTSTR file = TEXT("c:\\windows\\system32\\notepad.exe");


Also note that string literals are constants, and assigning a string literal to a non-const variable is deprecated in C++11, so you should be using a const variable instead:

Code: Select all
LPCTSTR file = TEXT("c:\\windows\\system32\\notepad.exe");


Although, you really shouldn't be using TCHAR at all nowadays. TCHAR is designed to allow people to write single code that compiles for both Win9x/ME (ANSI) and WinNT4+ (Unicode) systems, but nobody targets Win9x/ME anymore, so you should be using Unicode APIs instead of ANSI/TCHAR APIs.

mark_c wrote:
Code: Select all
name = new TCHAR[51];
dname = new TCHAR[51];
ZeroMemory(name, 51);
ZeroMemory(dname, 51);


ZeroMemory() operates on bytes, but TCHAR can be either 'char' or 'wchar_t', so you should not assume 'sizeof(TCHAR)' is 1, use sizeof() explicitly instead:

Code: Select all
ZeroMemory(name, 51 * sizeof(TCHAR));
ZeroMemory(dname, 51 * sizeof(TCHAR));


mark_c wrote:
Code: Select all
printf("Owner of file %s", file);
printf("is %s\n", name);


Because of the nature of TCHAR, you should be using _tprintf() from tchar.h instead of printf():

Code: Select all
_tprintf(_T("Owner of file %s"), file);
_tprintf(_T("is %s\n"), name);


Otherwise, you would have to do something more like this to ensure proper compatibility with TCHAR:

Code: Select all
#ifdef UNICODE
printf("Owner of file %ls", file);
printf("is %ls\n", name);
#else
printf("Owner of file %hs", file);
printf("is %hs\n", name);


Or:

Code: Select all
#ifdef UNICODE
#define TSTR_PRINTF_SPEC "%ls"
#else
#define TSTR_PRINTF_SPEC "%hs"
#endif

printf("Owner of file " TSTR_PRINTF_SPEC, file);
printf("is " TSTR_PRINTF_SPEC "\n", name);
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1516
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: Ambiguity between 'PACCESS_MASK', why?

Postby mark_c » Wed Apr 25, 2018 12:30 am

thanks Remy, for the detailed explanation
mark_c
BCBJ Guru
BCBJ Guru
 
Posts: 111
Joined: Thu Jun 21, 2012 1:13 am

Re: Ambiguity between 'PACCESS_MASK', why?

Postby mark_c » Sat Apr 28, 2018 3:29 am

after a long meditation, I decided that it is better for me to upgrade all my projects to Embarcadero 10.2; but it is truly a tragedy to migrate all of my faithful Borland Builder 6 into Embarcadero. After numerous failed tests, I'm forced to redesign all the interfaces in the new environment one by one and copy and paste all the code From Builder 6 to Embarcadero, and, to make matters worse, also fixing some declarations that previously worked fine; I can not find another better way.
mark_c
BCBJ Guru
BCBJ Guru
 
Posts: 111
Joined: Thu Jun 21, 2012 1:13 am

Re: Ambiguity between 'PACCESS_MASK', why?

Postby rlebeau » Mon Apr 30, 2018 11:02 am

mark_c wrote:after a long meditation, I decided that it is better for me to upgrade all my projects to Embarcadero 10.2; but it is truly a tragedy to migrate all of my faithful Borland Builder 6 into Embarcadero. After numerous failed tests, I'm forced to redesign all the interfaces in the new environment one by one and copy and paste all the code From Builder 6 to Embarcadero, and, to make matters worse, also fixing some declarations that previously worked fine; I can not find another better way.


That is what happens after 17 years of evolution of the IDE, RTL, and VCL (especially after the Unicode switch-over in 2009, the addition of 64-bit development in 2011 and 2012, the addition of mobile development, etc). Some things just had to change over time to accommodate advances.

I'm in the same boat as you. I have several products that are still being developed in C++Builder 6, and likely never will be migrated to newer IDEs (actually, those products will likely be End-Of-Lifed in the near future, so it won't matter anyway).
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1516
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: Ambiguity between 'PACCESS_MASK', why?

Postby mark_c » Mon Apr 30, 2018 1:24 pm

thanks for the testimony Remy, it means that to upgrade all my old projects, I will continue to row on my boat :)
mark_c
BCBJ Guru
BCBJ Guru
 
Posts: 111
Joined: Thu Jun 21, 2012 1:13 am


Return to Technical

Who is online

Users browsing this forum: Bing [Bot] and 8 guests