' ========================================================================================================================
' ____,__, __, ____,_, _, ____ ____,__, ,____,____,
' (-/_|(-| (-| (-|_,(-|\ | (-|__|-/_|( |_/(-|_,(-|__)
' _/ |,_|__,_|__,_|__,_| \|, _|__)/ |,_| \,_|__,_| \,
'
' Copyright 2011 Allen Baker
'
' ------------------------------------------------------------------------------------------------------------------------
' File: M023_SpecialDirectories
' Originator: Allen Baker (2011.03.10 23:21)
' ------------------------------------------------------------------------------------------------------------------------
' $RCSfile$
' $Revision$
' $Date$
' ========================================================================================================================
'
Option Explicit
' ========================================================================================================================
' Description
' This module provides definitions for finding and using Windows' "special" folders such as "Application Data",
' "Documents", "Favorites", etc. These URLs provide additional info:
' http://support.microsoft.com/kb/252652
' http://msdn.microsoft.com/en-us/library/bb762181(v=VS.85).aspx
' http://msdn.microsoft.com/en-us/library/bb762494(v=VS.85).aspx
' ========================================================================================================================
' =====================================================================================================================
' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Constants ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
' =====================================================================================================================
'
' ==============================================================================================
' SHGetFolderPath function return codes
' ----------------------------------------------------------------------------------------------
Private Const cSuccess As Long = &H0 ' Success
Private Const cDoesNotExist As Long = &H1 ' The Folder is valid, but does not exist
Private Const cInvalidCSIDL As Long = &H80070057 ' Invalid CSIDL Value
'
' ==============================================================================================
' Flags that specify the path to be returned. This value is used in cases where the folder
' associated with a KNOWNFOLDERID (or CSIDL) can be moved, renamed, redirected, or roamed
' across languages by a user or administrator.
'
' The known folder system that underlies SHGetFolderPath allows users or administrators to
' redirect a known folder to a location that suits their needs. This is achieved by calling
' IKnownFolderManager::Redirect, which sets the "current" value of the folder associated with
' the SHGFP_TYPE_CURRENT flag.
'
' The default value of the folder, which is the location of the folder if a user or
' administrator had not redirected it elsewhere, is retrieved by specifying the
' SHGFP_TYPE_DEFAULT flag. This value can be used to implement a "restore defaults" feature for
' a known folder.
'
' For example, the default value (SHGFP_TYPE_DEFAULT) for FOLDERID_Music (CSIDL_MYMUSIC) is
' "C:\Users\user name\Music". If the folder was redirected, the current value
' (SHGFP_TYPE_CURRENT) might be "D:\Music". If the folder has not been redirected, then
' SHGFP_TYPE_DEFAULT and SHGFP_TYPE_CURRENT retrieve the same path.
'
' SHGFP_TYPE_CURRENT - Retrieve the folder's current path.
'
' SHGFP_TYPE_DEFAULT - Retrieve the folder's default path.
' ----------------------------------------------------------------------------------------------
Private Const SHGFP_TYPE_CURRENT = 0
Private Const SHGFP_TYPE_DEFAULT = 1
'
' ==============================================================================================
' the maximum length of a path name in Windows.
' ----------------------------------------------------------------------------------------------
Private Const MAX_PATH = 260
'
' ==============================================================================================
' The source of these CSIDL constants is the MS C/C++ include file shlobj.h
'
' A CSIDL is used in conjunction with one of four Shell functions, SHGetFolderLocation,
' SHGetFolderPath, SHGetSpecialFolderLocation, and SHGetSpecialFolderPath, to retrieve a
' special folder's path or pointer to an item identifier list (PIDL).
'
' Combine CSIDL_FLAG_CREATE with any of the other CSIDLs, except for CSIDL_FLAG_DONT_VERIFY, to
' force the creation of the associated folder. The remaining CSIDLs correspond to either file
' system folders or virtual folders. Where the CSIDL identifies a file system folder, a
' commonly used path is given as an example. Other paths may be used. Some CSIDLs can be mapped
' to an equivalent %VariableName% environment variable. CSIDLs are more reliable, however, and
' should be used if possible.
' ----------------------------------------------------------------------------------------------
Private Const CSIDL_DESKTOP As Long = 0
Private Const CSIDL_INTERNET As Long = 1
Private Const CSIDL_PROGRAMS As Long = 2
Private Const CSIDL_CONTROLS As Long = 3
Private Const CSIDL_PRINTERS As Long = 4
Private Const CSIDL_PERSONAL As Long = 5
Private Const CSIDL_FAVORITES As Long = 6
Private Const CSIDL_STARTUP As Long = 7
Private Const CSIDL_RECENT As Long = 8
Private Const CSIDL_SENDTO As Long = 9
Private Const CSIDL_BITBUCKET As Long = 10
Private Const CSIDL_STARTMENU As Long = 11
Private Const CSIDL_DESKTOPDIRECTORY As Long = 16
Private Const CSIDL_DRIVES As Long = 17
Private Const CSIDL_NETWORK As Long = 18
Private Const CSIDL_NETHOOD As Long = 19
Private Const CSIDL_FONTS As Long = 20
Private Const CSIDL_TEMPLATES As Long = 21
Private Const CSIDL_COMMON_STARTMENU As Long = 22
Private Const CSIDL_COMMON_PROGRAMS As Long = 23
Private Const CSIDL_COMMON_STARTUP As Long = 24
Private Const CSIDL_COMMON_DESKTOPDIRECTORY As Long = 25
Private Const CSIDL_APPDATA As Long = 26
Private Const CSIDL_PRINTHOOD As Long = 27
Private Const CSIDL_LOCAL_APPDATA As Long = 28
Private Const CSIDL_ALTSTARTUP As Long = 29
Private Const CSIDL_COMMON_ALTSTARTUP As Long = 30
Private Const CSIDL_COMMON_FAVORITES As Long = 31
Private Const CSIDL_INTERNET_CACHE As Long = 32
Private Const CSIDL_COOKIES As Long = 33
Private Const CSIDL_HISTORY As Long = 34
Private Const CSIDL_COMMON_APPDATA As Long = 35
Private Const CSIDL_WINDOWS As Long = 36
Private Const CSIDL_SYSTEM As Long = 37
Private Const CSIDL_PROGRAM_FILES As Long = 38
Private Const CSIDL_MYPICTURES As Long = 39
Private Const CSIDL_PROFILE As Long = 40
Private Const CSIDL_SYSTEMX86 As Long = 41
Private Const CSIDL_PROGRAM_FILESX86 As Long = 42
Private Const CSIDL_PROGRAM_FILES_COMMON As Long = 43
Private Const CSIDL_PROGRAM_FILES_COMMONX86 As Long = 44
Private Const CSIDL_COMMON_TEMPLATES As Long = 45
Private Const CSIDL_COMMON_DOCUMENTS As Long = 46
Private Const CSIDL_COMMON_ADMINTOOLS As Long = 47
Private Const CSIDL_ADMINTOOLS As Long = 48
Private Const CSIDL_CONNECTIONS As Long = 49
Private Const CSIDL_COMMON_MUSIC As Long = 53
Private Const CSIDL_COMMON_PICTURES As Long = 54
Private Const CSIDL_COMMON_VIDEO As Long = 55
Private Const CSIDL_RESOURCES As Long = 56
Private Const CSIDL_RESOURCES_LOCALIZED As Long = 57
Private Const CSIDL_COMMON_OEM_LINKS As Long = 58
Private Const CSIDL_CDBURN_AREA As Long = 59
Private Const CSIDL_COMPUTERSNEARME As Long = 61
Private Const CSIDL_FLAG_DONT_VERIFY As Long = &H4000
Private Const CSIDL_FLAG_CREATE As Long = &H8000
Private Const CSIDL_FLAG_MASK As Long = &HFF00
' =====================================================================================================================
' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Module Variables ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
' =====================================================================================================================
' =====================================================================================================================
' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Externals ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
' =====================================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' This function declaration identifies the Win32 API function that gets special directory path names.
' -----------------------------------------------------------------------------------------------------------
Private Declare Function SHGetFolderPath Lib "shfolder" Alias "SHGetFolderPathA" _
( _
ByVal hwndOwner As Long, _
ByVal nFolder As Long, _
ByVal hToken As Long, _
ByVal dwFlags As Long, _
ByVal pszPath As String _
) As Long
' =====================================================================================================================
' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Public Routines ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
' =====================================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' This function gets the path name of the current user's favorites directory.
'
' return
' this function returns True if the favorites directory path name can be found. Otherwise, it returns
' False. If this function returns True, then the path name of the favorites directory is stored in the
' string pointed to by pPath when the function returns.
'
' param (output)
' pPath is the string location to which the favorites directory path name is written.
' param (Optional)
' pCreate is a boolean that if set to True will cause the requested directory to be created if it does
' not already exist. By default, this parameter is set to False and no directory is created.
' -----------------------------------------------------------------------------------------------------------
Public Function favoritesDirectory(pPath As String, Optional pCreate As Boolean = False) As Boolean
favoritesDirectory = specialDirectory(CSIDL_FAVORITES, pPath)
if Not favoritesDirectory Then gMsg(1) = "favoritesDirectory:" & gMsg(1)
End Function
' ===========================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' This function gets the path name of the current user's common favorites directory.
'
' return
' this function returns True if the common favorites directory path name can be found. Otherwise, it
' returns False. If this function returns True, then the path name of the common favorites directory is
' stored in the string pointed to by pPath when the function returns.
'
' param (output)
' pPath is the string location to which the common favorites directory path name is written.
' param (Optional)
' pCreate is a boolean that if set to True will cause the requested directory to be created if it does
' not already exist. By default, this parameter is set to False and no directory is created.
' -----------------------------------------------------------------------------------------------------------
Public Function commonFavoritesDirectory(pPath As String, Optional pCreate As Boolean = False) As Boolean
commonFavoritesDirectory = specialDirectory(CSIDL_COMMON_FAVORITES, pPath)
if Not commonFavoritesDirectory Then gMsg(1) = "commonFavoritesDirectory:" & gMsg(1)
End Function
' ===========================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' This function gets the path name of the current user's application data directory.
'
' return
' this function returns True if the application data directory path name can be found. Otherwise, it
' returns False. If this function returns True, then the path name of the application data directory is
' stored in the string pointed to by pPath when the function returns.
'
' param (output)
' pPath is the string location to which the application data directory path name is written.
' param (Optional)
' pCreate is a boolean that if set to True will cause the requested directory to be created if it does
' not already exist. By default, this parameter is set to False and no directory is created.
' -----------------------------------------------------------------------------------------------------------
Public Function appdataDirectory(pPath As String, Optional pCreate As Boolean = False) As Boolean
appdataDirectory = specialDirectory(CSIDL_APPDATA, pPath)
if Not appdataDirectory Then gMsg(1) = "appdataDirectory:" & gMsg(1)
End Function
' ===========================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' This function gets the path name of the current user's common application data directory.
'
' return
' this function returns True if the common application data directory path name can be found. Otherwise,
' it returns False. If this function returns True, then the path name of the common application data
' directory is stored in the string pointed to by pPath when the function returns.
'
' param (output)
' pPath is the string location to which the common application data directory path name is written.
' param (Optional)
' pCreate is a boolean that if set to True will cause the requested directory to be created if it does
' not already exist. By default, this parameter is set to False and no directory is created.
' -----------------------------------------------------------------------------------------------------------
Public Function commonAppdataDirectory(pPath As String, Optional pCreate As Boolean = False) As Boolean
commonAppdataDirectory = specialDirectory(CSIDL_COMMON_APPDATA, pPath)
if Not commonAppdataDirectory Then gMsg(1) = "commonAppdataDirectory:" & gMsg(1)
End Function
' ===========================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' This function gets the path name of the current user's local application data directory.
'
' return
' this function returns True if the local application data directory path name can be found. Otherwise,
' it returns False. If this function returns True, then the path name of the local application data
' directory is stored in the string pointed to by pPath when the function returns.
'
' param (output)
' pPath is the string location to which the local application data directory path name is written.
' param (Optional)
' pCreate is a boolean that if set to True will cause the requested directory to be created if it does
' not already exist. By default, this parameter is set to False and no directory is created.
' -----------------------------------------------------------------------------------------------------------
Public Function localAppdataDirectory(pPath As String, Optional pCreate As Boolean = False) As Boolean
localAppdataDirectory = specialDirectory(CSIDL_LOCAL_APPDATA, pPath)
if Not localAppdataDirectory Then gMsg(1) = "localAppdataDirectory:" & gMsg(1)
End Function
' ===========================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' This function gets the path name of the current user's documents directory.
'
' return
' this function returns True if the documents directory path name can be found. Otherwise, it returns
' False. If this function returns True, then the path name of the documents directory is stored in the
' string pointed to by pPath when the function returns.
'
' param (output)
' pPath is the string location to which the documents directory path name is written.
' param (Optional)
' pCreate is a boolean that if set to True will cause the requested directory to be created if it does
' not already exist. By default, this parameter is set to False and no directory is created.
' -----------------------------------------------------------------------------------------------------------
Public Function documentsDirectory(pPath As String, Optional pCreate As Boolean = False) As Boolean
documentsDirectory = specialDirectory(CSIDL_PERSONAL, pPath)
if Not documentsDirectory Then gMsg(1) = "documentsDirectory:" & gMsg(1)
End Function
' ===========================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' This function gets the path name of the current user's common documents directory.
'
' return
' this function returns True if the common documents directory path name can be found. Otherwise, it
' returns False. If this function returns True, then the path name of the common documents directory is
' stored in the string pointed to by pPath when the function returns.
'
' param (output)
' pPath is the string location to which the common documents directory path name is written.
' param (Optional)
' pCreate is a boolean that if set to True will cause the requested directory to be created if it does
' not already exist. By default, this parameter is set to False and no directory is created.
' -----------------------------------------------------------------------------------------------------------
Public Function commonDocumentsDirectory(pPath As String, Optional pCreate As Boolean = False) As Boolean
commonDocumentsDirectory = specialDirectory(CSIDL_COMMON_DOCUMENTS, pPath)
if Not commonDocumentsDirectory Then gMsg(1) = "commonDocumentsDirectory:" & gMsg(1)
End Function
' ===========================================================================================================
' ===========================================================================================================
' ===========================================================================================================
' This function gets the path name of the special directory specified by the argument passed in through the
' CSIDL parameter.
'
' return
' this function returns True if the specified directory path name can be found. Otherwise, it returns
' False. If this function returns True, then the path name of the requestid directory is stored in the
' string pointed to by pPath when the function returns.
'
' param
' pDirectoryCSIDL is the CSIDL code that identifies the directory to get the path name of.
' param (output)
' pPath is the string location to which the special directory path name is written.
' param (Optional)
' pCreate is a boolean that if set to True will cause the requested directory to be created if it does
' not already exist. By default, this parameter is set to False and no directory is created.
' -----------------------------------------------------------------------------------------------------------
Public Function specialDirectory(pDirectoryCSIDL As Long, pPath As String, Optional pCreate As Boolean = False) As Boolean
Dim retVal As Long
Dim flag As Long
'
' ==============================================================================================
' make sure the return message string is cleared out so no garbage is accidentally returned.
' ----------------------------------------------------------------------------------------------
gMsg(1) = ""
'
' ==============================================================================================
' if the directory doesn't exist the user can request that it be created by setting the
' argument passed through the pCreate parameter to True.
' ----------------------------------------------------------------------------------------------
If pCreate Then
flag = CSIDL_FLAG_CREATE
Else
flag = 0
End If
'
' ==============================================================================================
' Fill our string buffer and go get the path name
' ----------------------------------------------------------------------------------------------
pPath = String(MAX_PATH, 0)
retVal = SHGetFolderPath(0, pDirectoryCSIDL Or flag, 0, SHGFP_TYPE_CURRENT, pPath)
Select Case retVal
'
' ==============================================================================================
' We retrieved the folder successfully All C strings are null terminated, so we need to return
' the string upto the first null character
' ----------------------------------------------------------------------------------------------
Case cSuccess
pPath = Left(pPath, InStr(1, pPath, Chr(0)) - 1)
specialDirectory = True
'
' ==============================================================================================
' The CSIDL in pDirectoryCSIDL is valid, but the folder does not exist. Use CSIDL_FLAG_CREATE
' to have it created automatically
' ----------------------------------------------------------------------------------------------
Case cDoesNotExist
gMsg(1) = "specialDirectory: Directory does not exist and it's creation was not requested."
specialDirectory = False
'
' ==============================================================================================
' pDirectoryCSIDL is invalid
' ----------------------------------------------------------------------------------------------
Case cInvalidCSIDL
gMsg(1) = "specialDirectory: Invalid special directory."
specialDirectory = False
End Select
End Function