none
Cannot create file in %USERPROFILE%\AppData\Local with C++ - access denied

    Question

  • Hello,

    I'm trying to create a file within the folder %USERPROFILE%\AppData\Local with the CreateFile function that is provided by the Win32 API. Sadly, this operation always fails with error code 5 (from GetLastError()) - access denied. It even fails when the application is run with admin rights.

    Here is the corresponding code (the file doesn't exist when the program is run):

    TCHAR *filepath;
    if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, NULL, &filepath)))
    {
    	TCHAR path[MAX_PATH + 1];
    	StringCbCopy(path, MAX_PATH + 1, filepath);
    	PathAppend(path, _T("log.txt"));
    
    	_hFile = CreateFile(filepath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
    	if (_hFile == INVALID_HANDLE_VALUE)
    	{
    		TCHAR buffer[1024];
    		wsprintf(buffer, _T("error %lX"), GetLastError());
    		MessageBox(NULL, buffer, _T("error creating file"), MB_OK);
    	}
    	else
    	{
    		// ...
    	}
    	// free memory
    	CoTaskMemFree(filepath);
    }

    What am I doing wrong? If I try to create the file manually in Windows Explorer, everything works fine. I'm using Visual Studio 2010 under Windows 7 Professsional x64. Thanks in advance.

    Regards,

    aesn5

    Friday, May 07, 2010 10:15 PM

Answers

  • The first parameter for CreateFile must be path and not filepath.
    «_Superman_»
    Microsoft MVP (Visual C++)
    • Marked as answer by aesn5 Friday, May 07, 2010 10:51 PM
    Friday, May 07, 2010 10:38 PM
  • 1. You are copying MAX_PATH + 1 bytes from filepath to path.  But (a) the filepath may not be that long, and (b) it might be longer, because you are specifying number of BYTES to copy, not number of characters*sizeof(TCHAR) that are in filepath.

    2. You are attempting to create filepath, not path, in the call to CreateFile.

    • Marked as answer by aesn5 Friday, May 07, 2010 10:51 PM
    Friday, May 07, 2010 10:39 PM

All replies

  • The first parameter for CreateFile must be path and not filepath.
    «_Superman_»
    Microsoft MVP (Visual C++)
    • Marked as answer by aesn5 Friday, May 07, 2010 10:51 PM
    Friday, May 07, 2010 10:38 PM
  • 1. You are copying MAX_PATH + 1 bytes from filepath to path.  But (a) the filepath may not be that long, and (b) it might be longer, because you are specifying number of BYTES to copy, not number of characters*sizeof(TCHAR) that are in filepath.

    2. You are attempting to create filepath, not path, in the call to CreateFile.

    • Marked as answer by aesn5 Friday, May 07, 2010 10:51 PM
    Friday, May 07, 2010 10:39 PM
  • Oh, you're right. I can't believe I didn't notice...

    Yeah, I always tend to forget that "sizeof(TCHAR)".

    Thank you very much!

    Edit: I just looked at the documentation. The second argument of StringCbCopy is the buffer size of the destination buffer, so I think (MAX_PATH + 1) * sizeof(TCHAR) would be correct?

    Friday, May 07, 2010 10:54 PM
  • Use StringCchCopy instead.
    «_Superman_»
    Microsoft MVP (Visual C++)
    Friday, May 07, 2010 11:24 PM