locked
yet another CreateFile2 returns access denied

    Question

  • I'm porting a native C library to WinRT and I tried all options for CreateFile2 but I always get error with code=5 which means access_denied.

    Here is my call:

    CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
    	extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
    	extendedParameters.dwFileAttributes =FILE_ATTRIBUTE_NORMAL;
    	extendedParameters.dwFileFlags = FILE_ATTRIBUTE_NORMAL;
    	extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
    	extendedParameters.lpSecurityAttributes = NULL;
    	extendedParameters.hTemplateFile = NULL;
    
    	env->hndl= CreateFile2(lpath, GENERIC_READ | GENERIC_WRITE,
    		FILE_SHARE_READ , OPEN_ALWAYS,
    		 &extendedParameters);

    Note that I'm not trying to create the file outside ApplicationData.Current.LocalFolder.

    I want to call the C method that contains code above from C# by DLLImport(...).

     "lpath" value is something like this:

    c:\Users\Cristi\AppData\Local\Packages\73cc829f-f049-43f0-baff-91199eaa902d_xyvvsb6pz0zry\LocalState\myfile.txt

    is built from C# by: ApplicationData.Current.LocalFolder.Path+"\\"+myfile.txt

    So normally I should have write access to that path and still it returns access_denied.

    (I tried all options like 

    FILE_SHARE_READ|FILE_SHARE_WRITE , 0 etc

    and none works)

    Any idea?

    EDITED:

    I tried also suggestion from this post:https://social.msdn.microsoft.com/Forums/windowsapps/en-US/42d19d92-bf59-4859-91e2-78409f2e2ff4/unable-to-create-a-file-in-the-applicationdata-folder-with-createfile2?forum=winappswithnativecode

    CreateFile2(filename,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | 
        FILE_SHARE_WRITE | 
        FILE_SHARE_DELETE,
        OPEN_ALWAYS,
        NULL);

    and I get error code=3 which means ERROR_PATH_NOT_FOUND 

    Thursday, December 04, 2014 2:44 PM

Answers

  • Finally a workaround:

    int mylib_create_file(const char *path)
    {
    	int retCode = 1;
    	
    	TCHAR filename[_MAX_FNAME];
    
    	MultiByteToWideChar(CP_ACP, 0, path, -1, filename, 4096);
    
    
    	HANDLE hnd = CreateFile2(filename,
    		GENERIC_READ | GENERIC_WRITE,
    		FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    		CREATE_ALWAYS,
    		NULL);
    
    	if (hnd == INVALID_HANDLE_VALUE)
    	{
    		retCode = GetLastError();
    	}
    	return retCode;
    }

    Works prefect with return value 1 :)

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Friday, December 19, 2014 6:45 AM
    Moderator

All replies

  • Hi Christian,

    Something interesting:

    "lpath" value is something like this:

    c:\Users\Cristi\AppData\Local\Packages\73cc829f-f049-43f0-baff-91199eaa902d_xyvvsb6pz0zry\LocalState\myfile.txt

    is built from C# by: ApplicationData.Current.LocalFolder.Path+"\\"+myfile.txt

    How could you confirm that your C# app use the same package path with your C++ app? App can only access its own local folder, we cannot access to another app's local folder.

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, December 05, 2014 3:19 AM
    Moderator
  • Thanks James for your reply,

    There is no C++ app, I have only one App which is made in C# and I call via PInvoke a method from a C lib( C lib is compatible with WinRT). So, since I'm writing from same app process I should have access to that path because for this path ApplicationData.Current.LocalFolder.Path app should have write rights.

    (BTW in same way works SQLite accessed from C# on WinRT)

    Friday, December 05, 2014 8:00 AM
  • Could it possible the file path is not correct, as I can see from CreateFile2, looks like you need two double slash, something like \\.\c:\Users\Cristi\AppData\Local\Packages\73cc829f-f049-43f0-baff-91199eaa902d_xyvvsb6pz0zry\LocalState\myfile.txt

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Tuesday, December 09, 2014 7:25 AM
    Moderator
  • I changed it but same result: errorCode=5 (access_denied).

    I will prepare a small repro project...

    Tuesday, December 09, 2014 2:12 PM
  • Please download the  solution with both projects from here: http://1drv.ms/1x1FBgK

    1.The C project is called Win32Project1 and it will generate Win32Project1.dll which will be used by App1 (C# winStore app)

    2.App1- C# WinStore app that call a C function via PInvoke.

    To run the application, just open .sln file in VS and hit F5 and you will see that returned value is 5 which means "access denied". 

    (If you want to debug it, just put .pdb file into App1 project and hit F11 when C method is called).

    Wednesday, December 10, 2014 2:06 PM
  • Thanks for your sample, I will look into it. Any update I will reply here :)

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Thursday, December 11, 2014 3:07 AM
    Moderator
  • Hi Christian,

    Just tested your sample, it works fine on my side, I cannot see the access denied problem.

    I guess the problem might be with your environment instead of the code. Could you also test the sample with another PC?

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, December 15, 2014 9:10 AM
    Moderator
  • Thx James,

    Indeed it returns 5, which is the error_code=5 which means "access denied" take a look here:

    http://msdn.microsoft.com/en-us/library/cc231199.aspx

    If you look in mylib.c file you will see code:

    int retCode = 1;
    	HANDLE hnd = CreateFile2(path, GENERIC_READ | GENERIC_WRITE,
    		FILE_SHARE_READ, OPEN_ALWAYS,
    		NULL);
    
    	if (hnd == INVALID_HANDLE_VALUE)
    	{
    		retCode = GetLastError();
    	}
    	return retCode;

    So in C# you would need to get 1 if it succeeded created the file.

    (see my prev post: "To run the application, just open .sln file in VS and hit F5 and you will see that returned value is 5 which means "access denied". )


    Monday, December 15, 2014 12:50 PM
  • Can somebody confirm this is a bug?

    Is there any workaround?


    Thursday, December 18, 2014 1:06 PM
  • Hi Christian,

    I think its not a bug, I modified a bit for the code by hard code the address like below

    	TCHAR filename[_MAX_FNAME];
    
    	wcscpy_s(filename, MAX_PATH, L"C:\\Users\\USERNAME\\AppData\\Local\\Packages\\PACKAGEID\\LocalState\\");
    	wcscat_s(filename, MAX_PATH, L"\\data\\test.txt");
    
    	HANDLE hnd = CreateFile2(filename,
    		GENERIC_READ | GENERIC_WRITE,
    		FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    		CREATE_ALWAYS,
    		NULL);
    
    	if (hnd == INVALID_HANDLE_VALUE)
    	{
    		retCode = GetLastError();
    	}
    	return retCode;

    Your dll can retrun a int other than 5 and you can successfully create a file on your local folder.

    I found the problem is on covert from CHAR to LPCWSTR, you are passing in a CHAR path but looks like CreateFile2 need a LPCWSTR, in this scenario TCHAR is the suitable format. As I can see from the documentation: 2.2.34 LPCWSTR, LPCWSTR equals wchar_t instead of char, I do think this is the main issue.

    PS: if I set path as TCHAR, the path is incorrect then:

    I will further look into it.

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.




    Friday, December 19, 2014 6:21 AM
    Moderator
  • Also there is some warning:

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, December 19, 2014 6:39 AM
    Moderator
  • Finally a workaround:

    int mylib_create_file(const char *path)
    {
    	int retCode = 1;
    	
    	TCHAR filename[_MAX_FNAME];
    
    	MultiByteToWideChar(CP_ACP, 0, path, -1, filename, 4096);
    
    
    	HANDLE hnd = CreateFile2(filename,
    		GENERIC_READ | GENERIC_WRITE,
    		FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    		CREATE_ALWAYS,
    		NULL);
    
    	if (hnd == INVALID_HANDLE_VALUE)
    	{
    		retCode = GetLastError();
    	}
    	return retCode;
    }

    Works prefect with return value 1 :)

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Friday, December 19, 2014 6:45 AM
    Moderator
  • James,

    You rock! it works thx ;)

    Saturday, December 20, 2014 12:10 PM