path_createfolder() fails on Windows 8


    Apr 25 2014 | 12:07 pm
    In my external for windows I'm trying to create a folder in C:\Program Files (x86)\Common Files
    This root folder exists.
    With my previous win7 installation this wasn't a problem, but now on Windows 8.1 it returns error code -1. I'm thinking it might be because the security settings are more strict, but I tried lowering the UAC (user account control) to the minimum and I still get the same error.
    Here's my code:
    void MyExternal::createPaths(const char* rootname){
    short rootpath; char filename[PATH_MAX];
    if(path_frompathname(rootname, &rootpath, filename)){ object_error((t_object*)this, "path_frompathname failed"); return; }
    DPOST("rootname %s", rootname); DPOST("rootpath %i", rootpath);
    short newpath; int err = path_createfolder(rootpath, "SomeFolder", &newpath); if(err){ object_error((t_object*)this, "create folder SomeFolder failed: %i", err); return; }
    ... and some more }
    This is the output in max:
    rootname C:\Program Files (x86)\Common Files rootpath -361 myexternal: create folder SomeFolder failed: -1
    Any idea why this might be happening?
    So path_frompathname() returns 0 in this case but the rootpath value is set to -361. Is that a valid path identifier?
    Under what type of circumstances can you get a -1 returned from path_createfolder()? I can't find any information in the docs on this subject.

    • Jun 10 2014 | 6:05 pm
      Just for the record. I have figured this out since.
      Yes -361 is a valid path identifier. The problem seemed to be that I was trying to create a folder in the program files directory. Not every user is allowed to do that. I've since used CSIDL_APPDATA instead of CSIDL_PROGRAM_FILES_COMMONX86. I want this to create a common folder for my application that would persist outside the application bundle/folder, so CSIDL_APPDATA seems like the right choice anyway.
      To get the path passed to the createPaths function mentioned in the previous post, I do something like this:
      if(SUCCEEDED(SHGetFolderPath(NULL, 
      			CSIDL_APPDATA | CSIDL_FLAG_CREATE,
      								 NULL, 
      								 0, 
      								 path))) 
      		{
      // do something with path
      
      }
      What I don't quite understand is that SHGetFolderPath returned with success also with CSIDL_PROGRAM_FILES_COMMONX86 | CSIDL_FLAG_CREATE. I would expect that to fail if you're not allowed to create a path.
      Hope this is useful to some one at some point