Access denied fro GetShortPathName in Windows Vista

  • Thread starter Thread starter tuma
  • Start date Start date
T

tuma

I have a win32 application that creates a directory in Users's Application
Data directory (Example: c:\users\<username>\Local Settings\Application
Data\MyFolder) and writing application specific data there. Thinks are
working fine. But when I use GetShortPathName to get the short path for the
above path, it fails with Access denied error. I need it to pass the short
path to other application which only understands the short path.

I don't understand why this API should throw Access denied when I ask short
path for the folder that I created from the same application.

Any workaround for this issue?
 
I have a win32 application that creates a directory in Users's Application
Data directory (Example: c:\users\<username>\Local Settings\Application
Data\MyFolder) and writing application specific data there. Thinks are
working fine. But when I use GetShortPathName to get the short path for the
above path, it fails with Access denied error. I need it to pass the short
path to other application which only understands the short path.

I don't understand why this API should throw Access denied when I ask short
path for the folder that I created from the same application.

Your results do seem odd - do you have a short code (ideally a console
application) example that reproduces the issue?

Dave
 
SHGetSpecialFolderPath(NULL, profilePath, CSIDL_PROFILE, 0);

//some code here

_tcscat_s(profilePath, MAX_BUFFER, _T("\\Local Settings\\Application
Data\\MyAPPFolder"));
if(PathFileExists(profilePath) == FALSE )
{
err = MyCreateDirectory(profilePath);
if (err != kAMCPErrorNone)
{
return err;
}
}


if (GetShortPathName(profilePath, gMyAppDataPath, MAX_PATH) == 0)
{
DispalyOSError(profilePath); // Access Denied error is the result
exit(0);
}
 
//some code here

Can you knock it into something stand-alone that anyone could paste
into a console project and compile cleanly.

Thanks
Dave
 
//***********************************************
// It has dependency with shlwapi.lib. Add it in your project settings.
//
//***********************************************

#include <windows.h>
#include <tchar.h>
#include <shlobj.h>
#include <shlwapi.h>

#define MAX_BUFFER 1000

_TCHAR gMyAppDataPath[MAX_PATH];
BOOL MyCreateDirectory(_TCHAR *path);
void DispalyOSError();

void main()
{
_TCHAR profilePath[MAX_BUFFER];

SHGetSpecialFolderPath(NULL, profilePath, CSIDL_PROFILE, 0);

//some code here

_tcscat_s(profilePath, MAX_BUFFER, _T("\\Local Settings\\Application
Data\\MyAPPFolder"));
if(PathFileExists(profilePath) == FALSE )
{
if (MyCreateDirectory(profilePath) != TRUE)
exit(0);
}


if (GetShortPathName(profilePath, gMyAppDataPath, MAX_PATH) == 0)
{
DispalyOSError(); // Access Denied error is the result
exit(0);
}
}

BOOL MyCreateDirectory(_TCHAR *dirName)
{
BOOL error = TRUE;

if (CreateDirectory(dirName,NULL) == FALSE)
{
_TCHAR temp[MAX_PATH], *ptr = NULL;
_tcscpy_s(temp, MAX_PATH, dirName);
ptr = _tcsrchr(temp, _T('\\'));
if (ptr)
{
*ptr = 0;
error = MyCreateDirectory(temp);
if (error != TRUE) return error;
}

error = CreateDirectory(dirName,NULL);
}

return error;
}

void DispalyOSError()
{
LPVOID lpMsgBuf;
DWORD dw = GetLastError();

FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );

MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK);
}
 
// It has dependency with shlwapi.lib. Add it in your project settings.

FWIW...

#include <shlwapi.h>
#pragma comment( lib, "shlwapi.lib" )
.... neatly sorts that out :)


Thanks for the example. I can reproduce the issue with your code under
Vista. If you change your code to:

SHGetSpecialFolderPath(NULL, profilePath, CSIDL_LOCAL_APPDATA , 0);

_tcscat_s(profilePath, MAX_BUFFER, _T("\\MyAPPFolder"));

.... it'll use the correct directory under Vista (and XP)

Dave
 
Thanks. It works. But I am very curious to know why the “Access Deniedâ€
error when I hard code the path.
 
Hi tuma,
Thanks. It works. But I am very curious to know why the “Access
Denied†error when I hard code the path.

Compare your hard coded path and the path returned from
CSIDL_LOCAL_APPDATA. They are not identical, right?
Vista uses hard links to "support" the old (pre-Vista) directory
names in a limited way. Those hard links have a different
default security compared with what you get through the
above CSIDL. That might bight you.

In short: never use hard coded paths as different Windows
versions and languages will have slightly varying paths.
 
Thanks. It works. But I am very curious to know why the “Access Denied”
error when I hard code the path.

As Sven has pointed out, it's not really the same path under Vista.

Dave
 
Back
Top