2010. 12. 10. 17:14

어떤 계정에서도 읽고 쓸수 있는 경로 구하기

Windows 2K, XP, Vista, Win7에서 아무 계정에서도 권한에 구애 받지 않고 쓸 수 있는 경로를 구하는 함수를 공유합니다.
자세한건 코드로 확인하세요.
view plain 하시면 좀더 편리하게 확인가능 합니다.

// 아무 계정이나 읽고 쓸수 있는 경로를 리턴한다.
CString GetPublicFolder(VOID)
{
	typedef HRESULT (WINAPI* LPFN_SHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
	TCHAR						szPath[MAX_PATH]		= {0,};
	PWSTR						lpwPath					= NULL;
	LPFN_SHGetKnownFolderPath	pfnSHGetKnownFolderPath	= NULL;
	CString						strRtnValue;

	if (TRUE == IsVistaOrLater())
	{
		pfnSHGetKnownFolderPath = (LPFN_SHGetKnownFolderPath)::GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), "SHGetKnownFolderPath");
		if (NULL != pfnSHGetKnownFolderPath)
		{
			(*pfnSHGetKnownFolderPath)(FOLDERID_Public, 0, NULL, &lpwPath);
			if ((NULL != lpwPath) && (TEXT('\0') != lpwPath[0]))
			{
				if (INVALID_FILE_ATTRIBUTES != ::GetFileAttributes(lpwPath))
				{
					// 폴더 존재... 성공~!!!
					strRtnValue = lpwPath;
					goto FINAL;
				}
				else
				{
					ASSERT(FALSE);
					::SHCreateDirectory(NULL, lpwPath);
					strRtnValue = lpwPath;
					goto FINAL;
				}
			}
		}

		// GetProcAddress가 실패했거나, SHGetKnownFolderPath 결과가 좋지 않다.
		ASSERT(FALSE);
		strRtnValue = TEXT("C:\\Users\\Public");
		if (INVALID_FILE_ATTRIBUTES == ::GetFileAttributes(strRtnValue))
		{
			::SHCreateDirectory(NULL, strRtnValue);
		}
		goto FINAL;
	}

	// Vista 이하,... XP, 2K
	::SHGetSpecialFolderPath(NULL, szPath, CSIDL_COMMON_APPDATA, TRUE);
	strRtnValue = szPath;

FINAL:
	if (NULL != lpwPath)
	{
		::CoTaskMemFree(lpwPath);
		lpwPath = NULL;
	}
	return strRtnValue;
}

BOOL IsVistaOrLater(VOID)
{
	BOOL			bRtnValue	= TRUE;
	OSVERSIONINFO	osvi		= {0,};

	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	::GetVersionEx(&osvi);

	// major version이 6보다 크면, vista보다 이후에 나온 OS 이겠지? ㅎㅎ
	if (osvi.dwMajorVersion >= 6)
	{
		bRtnValue = TRUE;
	}
	else
	{
		bRtnValue = FALSE;
	}

	return bRtnValue;
}