Check directory for write access by current user

How do use MFC to check if the current user has write access to a directory?
steenpatAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

 
jkrCommented:
You can use the following code:
#include <windows.h>
#include <svrapi.h>
#include <stdio.h>
 
BOOL IsAccessPermitted(LPCTSTR pszFolder) {
 
          HANDLE hToken;
	  // AccessCheck() variables
	  DWORD           dwAccessDesired;
	  PRIVILEGE_SET   PrivilegeSet;
	  DWORD           dwPrivSetSize;
	  DWORD           dwAccessGranted;
	  BOOL            fAccessGranted = FALSE;
	  GENERIC_MAPPING GenericMapping;
 
          SECURITY_INFORMATION si = (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
            | GROUP_SECURITY_INFORMATION
            | DACL_SECURITY_INFORMATION);
 
 
	  PSECURITY_DESCRIPTOR psdSD = NULL;
	  DWORD dwNeeded;
 
	  GetFileSecurity(pszFolder,si,NULL,0,&dwNeeded);
 
 
	  psdSD = (PSECURITY_DESCRIPTOR) new BYTE[dwNeeded];
 
	  if (!GetFileSecurity(pszFolder,si,psdSD,dwNeeded,&dwNeeded)) {
 
              printf("GetFileSecurity\n");
          }
 
      // AccessCheck() requires an impersonation token.
      ImpersonateSelf(SecurityImpersonation);
 
      OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, 
            &hToken);
 
      // Using AccessCheck(), there are two different things we could do:
      // 
      // 1. See if we have Read/Write access to the object.
      // 
      dwAccessDesired = ACCESS_READ;
 
      // Initialize generic mapping structure to map all.
      memset(&GenericMapping, 0xff, sizeof(GENERIC_MAPPING));
      GenericMapping.GenericRead = ACCESS_READ;
      GenericMapping.GenericWrite = ACCESS_WRITE;
      GenericMapping.GenericExecute = 0;
      GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;
 
      // This only does something if we want to use generic access
      // rights, like GENERIC_ALL, in our call to AccessCheck().
      MapGenericMask(&dwAccessDesired, &GenericMapping);
 
      dwPrivSetSize = sizeof(PRIVILEGE_SET);
 
      printf("calling 'AccessCheck()'...\n");
 
      // Make the AccessCheck() call.
      if (!AccessCheck(psdSD, hToken, dwAccessDesired, &GenericMapping,
            &PrivilegeSet, &dwPrivSetSize, &dwAccessGranted, 
            &fAccessGranted)){
 
              printf("AccessCheck: %d\n",GetLastError());
          }
 
      printf("... 'AccessCheck()' succeeded\n");
      delete [] psdSD;
 
  return fAccessGranted;
}
 
void main () {
 
    BOOL bRes = IsAccessPermitted("c:\\Windows\\notepad.exe");
 
    printf("permitted: %s\n", bRes ? "Yes" :  "No");
 
}

Open in new window

0

Experts Exchange Solution brought to you by ConnectWise

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
 
waysideCommented:
Quick and dirty method would be to just create a file in the directory. If it succeeds, you have write access; if not, you don't.

CString mydir = "c:/windows/system32";

CString tempName = mydir + "/mytemp.foo";
CFile tempFile;

BOOL bOpenOK = tempFile.Open(tempName, CFile::modeCreate | CFile::modeWrite);
if (bOpenOK == TRUE) {
  // success! clean up.
  tempFile.Close();
  CFile::Remove(tempName);
}

0
 
CSecurityCommented:
try to create a directory using CreateDirectory of try to create a file using CreateFile API function.
if one of above functions failed, check error reason using GetLastError() API to get error code.
if(GetLastError() == ERROR_ACCESS_DENIED) // or if(GetLastError() == 5)
//means that access denied
as "Wayside"s comment: quick and dirty way ;)
Regards
0
 
steenpatAuthor Commented:
I would like to comment that RevertToSelf is necessary at the bottom of this function otherwise it keeps running in the context of the client and this is undesirable. It caused issues with my application until I figured this out. I called RevertToSelf, and then CloseHandle(hToken) and this resolved issues.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.