From: Karl E. Peterson on
Eduardo wrote:
>> In some versions of Windows the folders aren't created automatically, so
>> you have to use CSIDL_FLAG_CREATE(In shell32.dll version 5.00 or above).
>
> Did you mean shell32.dll version below 5.00?
> What I understood so far is that with shell32.dll version 5.00 or above the
> folder will exist for sure. Am I wrong?
>
> And seemingly, reading Karl's latest post in this thread, it existed in
> Win95.

Well, no, I don't have a totally "clean" Win95 machine to verify that on. It's
possible that one of those few utility apps I installed might have triggered their
creation. That said, there is no shell32 v5 on that box, either, because that came
at a later version of IE, so there is no CSIDL_FLAG_CREATE option available.
--
..NET: It's About Trust!
http://vfred.mvps.org


From: Karl E. Peterson on
Eduardo wrote:
>> In some versions of Windows the folders aren't created automatically, so
>> you have to use CSIDL_FLAG_CREATE(In shell32.dll version 5.00 or above).
>
> Did you mean shell32.dll version below 5.00?
> What I understood so far is that with shell32.dll version 5.00 or above the
> folder will exist for sure. Am I wrong?
>
> And seemingly, reading Karl's latest post in this thread, it existed in
> Win95.

Here's an interesting datapoint. I just created a totally clean Windows ME virtual
machine. Immediately following the initial boot, both CSIDL_APPDATA and
CSIDL_COMMON_APPDATA existed, but CSIDL_LOCAL_APPDATA wasn't there. At that point,
the API returns the following values:

CSIDL_APPDATA: C:\WINDOWS\Application Data
CSIDL_LOCAL_APPDATA: C:\WINDOWS\Application Data
CSIDL_COMMON_APPDATA: C:\WINDOWS\All Users\Application Data

But, as you saw, on my 95/98 VMs, that LOCAL_APPDATA folder definitely existed. So
I'm thinking, you're pretty danged well off forcing the creation of the folder when
you first create the INI file, otherwise you might have some real difficulties later
when you come back to look for it. (Anyone think I'm reading that situation wrong?)
None of these VMs specifically had multi-user support enabled, either.
--
..NET: It's About Trust!
http://vfred.mvps.org


From: Eduardo on
"Karl E. Peterson" <karl(a)mvps.org> escribi� en el mensaje
news:e83hj8iYJHA.552(a)TK2MSFTNGP06.phx.gbl...

I have to say that I didn't understand this phrase:

> you're pretty danged well off forcing the creation of the folder when you
> first create the INI file, otherwise you might have some real difficulties
> later when you come back to look for it.

On other hand:
I decided not to use the APPDATA folder in not NT systems (95/98/ME), and
just to write to somewhere else on those O.S. versions as I used to do in
the past.

The other question is: do you think that now or in some future time it can
be any trouble with it? I mean, do you think that some firewalls programs
could do the same "nanny" work as Vista does on itself, but on 95/98/ME and
disallow to write to "Programs files\appname" or "Windows\appname" or
wherever?

PS: I see that every time it is more difficult to keep an application
compatible with all Win32 O.S. versions.

PS2: This should be a so usual necessity (to know where to write for all
O.S. versions), that I'm amazed that we are discussing it just now.


From: expvb on
"Karl E. Peterson" <karl(a)mvps.org> wrote in message
news:eDaks5gYJHA.3808(a)TK2MSFTNGP05.phx.gbl...
> For curiosity sake, I just fired up a Win95 (950b; build 1111) VM that's
> *almost* pure. The API returns these folders:
>
> CSIDL_APPDATA: C:\WINDOWS\Application Data
> CSIDL_LOCAL_APPDATA: C:\WINDOWS\Local Settings\Application Data
> CSIDL_COMMON_APPDATA: C:\WINDOWS\All Users\Application Data

You must have installed something that updated the shell, or you are using a
different function. I have the same Windows 95 version that you have
4.00.1111, and the only thing that I installed on it is my standard EXE
application which uses the VB6 runtime and two OCX files: MSCOMCTL.OCX and
MSWINSCK.OCX. The shell version is 4.00, which is what comes with Windows
95. All of the CSIDL values above generate error &H80070057. Here are the
constants and what they returned, followed by the VB6 source I used. To try
the sample, add a TextBox and set MutiLine property to True, and ScrollBar
to Both:

Shell32.dll version: 4.00

CSIDL_DESKTOP: C:\WINDOWS\DESKTOP
CSIDL_INTERNET: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_PROGRAMS: C:\WINDOWS\Start Menu\Programs
CSIDL_CONTROLS:
CSIDL_PRINTERS:
CSIDL_PERSONAL: SHGetSpecialFolderLocation failed with error code(hex):
8007000E, LastDllError = 0
CSIDL_FAVORITES: C:\WINDOWS\Favorites
CSIDL_STARTUP: C:\WINDOWS\Start Menu\Programs\StartUp
CSIDL_RECENT: C:\WINDOWS\Recent
CSIDL_SENDTO: C:\WINDOWS\SendTo
CSIDL_BITBUCKET:
CSIDL_STARTMENU: C:\WINDOWS\Start Menu
CSIDL_DESKTOPDIRECTORY: C:\WINDOWS\DESKTOP
CSIDL_DRIVES:
CSIDL_NETWORK:
CSIDL_NETHOOD: C:\WINDOWS\NetHood
CSIDL_FONTS: C:\WINDOWS\FONTS
CSIDL_TEMPLATES: C:\WINDOWS\ShellNew
CSIDL_COMMON_STARTMENU: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_COMMON_PROGRAMS: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_COMMON_STARTUP: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_COMMON_DESKTOPDIRECTORY: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_APPDATA: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_PRINTHOOD: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_LOCAL_APPDATA: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_ALTSTARTUP: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_COMMON_ALTSTARTUP: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_COMMON_FAVORITES: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_INTERNET_CACHE: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_COOKIES: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_HISTORY: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_COMMON_APPDATA: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_WINDOWS: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_SYSTEM: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_PROGRAM_FILES: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_MYPICTURES: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_PROFILE: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_SYSTEMX86: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0
CSIDL_PROGRAM_FILESX86: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_PROGRAM_FILES_COMMON: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_PROGRAM_FILES_COMMONX86: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_COMMON_TEMPLATES: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_COMMON_DOCUMENTS: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_COMMON_ADMINTOOLS: SHGetSpecialFolderLocation failed with error
code(hex): 80070057, LastDllError = 0
CSIDL_ADMINTOOLS: SHGetSpecialFolderLocation failed with error code(hex):
80070057, LastDllError = 0


' Form1 code ======================


Option Explicit

Private Const CSIDL_DESKTOP = &H0
Private Const CSIDL_INTERNET = &H1
Private Const CSIDL_PROGRAMS = &H2
Private Const CSIDL_CONTROLS = &H3
Private Const CSIDL_PRINTERS = &H4
Private Const CSIDL_PERSONAL = &H5
Private Const CSIDL_FAVORITES = &H6
Private Const CSIDL_STARTUP = &H7
Private Const CSIDL_RECENT = &H8
Private Const CSIDL_SENDTO = &H9
Private Const CSIDL_BITBUCKET = &HA
Private Const CSIDL_STARTMENU = &HB
Private Const CSIDL_DESKTOPDIRECTORY = &H10
Private Const CSIDL_DRIVES = &H11
Private Const CSIDL_NETWORK = &H12
Private Const CSIDL_NETHOOD = &H13
Private Const CSIDL_FONTS = &H14
Private Const CSIDL_TEMPLATES = &H15
Private Const CSIDL_COMMON_STARTMENU = &H16
Private Const CSIDL_COMMON_PROGRAMS = &H17
Private Const CSIDL_COMMON_STARTUP = &H18
Private Const CSIDL_COMMON_DESKTOPDIRECTORY = &H19
Private Const CSIDL_APPDATA = &H1A
Private Const CSIDL_PRINTHOOD = &H1B
Private Const CSIDL_LOCAL_APPDATA = &H1C
Private Const CSIDL_ALTSTARTUP = &H1D
Private Const CSIDL_COMMON_ALTSTARTUP = &H1E
Private Const CSIDL_COMMON_FAVORITES = &H1F
Private Const CSIDL_INTERNET_CACHE = &H20
Private Const CSIDL_COOKIES = &H21
Private Const CSIDL_HISTORY = &H22
Private Const CSIDL_COMMON_APPDATA = &H23
Private Const CSIDL_WINDOWS = &H24
Private Const CSIDL_SYSTEM = &H25
Private Const CSIDL_PROGRAM_FILES = &H26
Private Const CSIDL_MYPICTURES = &H27
Private Const CSIDL_PROFILE = &H28
Private Const CSIDL_SYSTEMX86 = &H29
Private Const CSIDL_PROGRAM_FILESX86 = &H2A
Private Const CSIDL_PROGRAM_FILES_COMMON = &H2B
Private Const CSIDL_PROGRAM_FILES_COMMONX86 = &H2C
Private Const CSIDL_COMMON_TEMPLATES = &H2D
Private Const CSIDL_COMMON_DOCUMENTS = &H2E
Private Const CSIDL_COMMON_ADMINTOOLS = &H2F
Private Const CSIDL_ADMINTOOLS = &H30
Private Const CSIDL_FLAG_CREATE = &H8000&

Private Const CSIDL_FLAG_DONT_VERIFY = &H4000

Private Const CSIDL_FLAG_MASK = &HFF00
Private Const SHGFP_TYPE_CURRENT = &H0
Private Const SHGFP_TYPE_DEFAULT = &H1

Private Const MAX_PATH As Long = 260
Private Const S_OK = 0

'Converts an item identifier list to a file system path.
Private Declare Function SHGetPathFromIDList Lib "shell32" Alias _
"SHGetPathFromIDListA" (ByVal pidl As Long, _
ByVal pszPath As String) As Long

Private Declare Function SHGetSpecialFolderLocation Lib "shell32" ( _
ByVal hwndOwner As Long, ByVal nFolder As Long, pidl As Long) As Long

Private Declare Sub CoTaskMemFree Lib "ole32" (ByVal pv As Long)

Private Declare Function GetFileVersionInfoSize Lib "version.dll" Alias _
"GetFileVersionInfoSizeA" (ByVal lptstrFilename As String, _
lpdwHandle As Long) As Long
Private Declare Function GetFileVersionInfo Lib "version.dll" Alias _
"GetFileVersionInfoA" (ByVal lptstrFilename As String, _
ByVal dwHandle As Long, ByVal dwLen As Long, lpData As Any) As Long
Private Declare Function VerQueryValue Lib "version.dll" Alias _
"VerQueryValueA" (pBlock As Any, ByVal lpSubBlock As String, _
lpBuffer As Any, nVerSize As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
Destination As Any, Source As Any, ByVal Length As Long)

Private Type TCSIDL
lCSIDL As Long
sCSIDL As String
End Type

' Array to hold CSIDL values and text
Dim CSIDL(100) As TCSIDL
Dim CSIDLCount As Long

Private Sub AddCSIDL(ByRef lCSIDL As Long, sCSIDL As String)
CSIDLCount = CSIDLCount + 1
CSIDL(CSIDLCount).lCSIDL = lCSIDL
CSIDL(CSIDLCount).sCSIDL = sCSIDL
End Sub

Private Sub Form_Load()
Dim i As Long

' Fill CSIDL array
AddCSIDL CSIDL_DESKTOP, "CSIDL_DESKTOP"
AddCSIDL CSIDL_INTERNET, "CSIDL_INTERNET"
AddCSIDL CSIDL_PROGRAMS, "CSIDL_PROGRAMS"
AddCSIDL CSIDL_CONTROLS, "CSIDL_CONTROLS"
AddCSIDL CSIDL_PRINTERS, "CSIDL_PRINTERS"
AddCSIDL CSIDL_PERSONAL, "CSIDL_PERSONAL"
AddCSIDL CSIDL_FAVORITES, "CSIDL_FAVORITES"
AddCSIDL CSIDL_STARTUP, "CSIDL_STARTUP"
AddCSIDL CSIDL_RECENT, "CSIDL_RECENT"
AddCSIDL CSIDL_SENDTO, "CSIDL_SENDTO"
AddCSIDL CSIDL_BITBUCKET, "CSIDL_BITBUCKET"
AddCSIDL CSIDL_STARTMENU, "CSIDL_STARTMENU"
AddCSIDL CSIDL_DESKTOPDIRECTORY, "CSIDL_DESKTOPDIRECTORY"
AddCSIDL CSIDL_DRIVES, "CSIDL_DRIVES"
AddCSIDL CSIDL_NETWORK, "CSIDL_NETWORK"
AddCSIDL CSIDL_NETHOOD, "CSIDL_NETHOOD"
AddCSIDL CSIDL_FONTS, "CSIDL_FONTS"
AddCSIDL CSIDL_TEMPLATES, "CSIDL_TEMPLATES"
AddCSIDL CSIDL_COMMON_STARTMENU, "CSIDL_COMMON_STARTMENU"
AddCSIDL CSIDL_COMMON_PROGRAMS, "CSIDL_COMMON_PROGRAMS"
AddCSIDL CSIDL_COMMON_STARTUP, "CSIDL_COMMON_STARTUP"
AddCSIDL CSIDL_COMMON_DESKTOPDIRECTORY, _
"CSIDL_COMMON_DESKTOPDIRECTORY"
AddCSIDL CSIDL_APPDATA, "CSIDL_APPDATA"
AddCSIDL CSIDL_PRINTHOOD, "CSIDL_PRINTHOOD"
AddCSIDL CSIDL_LOCAL_APPDATA, "CSIDL_LOCAL_APPDATA"
AddCSIDL CSIDL_ALTSTARTUP, "CSIDL_ALTSTARTUP"
AddCSIDL CSIDL_COMMON_ALTSTARTUP, "CSIDL_COMMON_ALTSTARTUP"
AddCSIDL CSIDL_COMMON_FAVORITES, "CSIDL_COMMON_FAVORITES"
AddCSIDL CSIDL_INTERNET_CACHE, "CSIDL_INTERNET_CACHE"
AddCSIDL CSIDL_COOKIES, "CSIDL_COOKIES"
AddCSIDL CSIDL_HISTORY, "CSIDL_HISTORY"
AddCSIDL CSIDL_COMMON_APPDATA, "CSIDL_COMMON_APPDATA"
AddCSIDL CSIDL_WINDOWS, "CSIDL_WINDOWS"
AddCSIDL CSIDL_SYSTEM, "CSIDL_SYSTEM"
AddCSIDL CSIDL_PROGRAM_FILES, "CSIDL_PROGRAM_FILES"
AddCSIDL CSIDL_MYPICTURES, "CSIDL_MYPICTURES"
AddCSIDL CSIDL_PROFILE, "CSIDL_PROFILE"
AddCSIDL CSIDL_SYSTEMX86, "CSIDL_SYSTEMX86"
AddCSIDL CSIDL_PROGRAM_FILESX86, "CSIDL_PROGRAM_FILESX86"
AddCSIDL CSIDL_PROGRAM_FILES_COMMON, "CSIDL_PROGRAM_FILES_COMMON"
AddCSIDL CSIDL_PROGRAM_FILES_COMMONX86, _
"CSIDL_PROGRAM_FILES_COMMONX86"
AddCSIDL CSIDL_COMMON_TEMPLATES, "CSIDL_COMMON_TEMPLATES"
AddCSIDL CSIDL_COMMON_DOCUMENTS, "CSIDL_COMMON_DOCUMENTS"
AddCSIDL CSIDL_COMMON_ADMINTOOLS, "CSIDL_COMMON_ADMINTOOLS"
AddCSIDL CSIDL_ADMINTOOLS, "CSIDL_ADMINTOOLS"

' Show the shell version
Text1.Text = "Shell32.dll version: " & Format(GetShellVersion(), _
"0.00") & vbCrLf & vbCrLf

' Call SHGetSpecialFolderLocation for every CSIDL and fill the textbox
For i = 1 To CSIDLCount
Text1.SelStart = 32767
Text1.SelText = CSIDL(i).sCSIDL & ": " & GetSpecialFolderLocation( _
CSIDL(i).lCSIDL) & vbCrLf
Next
End Sub

Private Function GetSpecialFolderLocation(CSIDL As Long) As String
Dim sPath As String
Dim pidl As Long
Dim ret As Long

' Fill the idl structure with the specified folder item
ret = SHGetSpecialFolderLocation(Me.hWnd, CSIDL, pidl)
If ret = S_OK Then

' If the pidl is returned, initialize
' and get the path from the id list
sPath = Space$(MAX_PATH)

If SHGetPathFromIDList(ByVal pidl, ByVal sPath) Then
' Return the path
GetSpecialFolderLocation = Left(sPath, InStr(sPath, _
Chr$(0)) - 1)
End If

' Free pidl
Call CoTaskMemFree(pidl)
Else
' SHGetSpecialFolderLocation failed
GetSpecialFolderLocation = _
"SHGetSpecialFolderLocation failed with error code(hex): " &
Hex( _
ret) & ", LastDllError = " & Err.LastDllError
End If

End Function

' Returns the Shell version (shell32.dll)
Public Function GetShellVersion() As Double
Dim nBufferSize As Long
Dim nUnused As Long
Dim lpBuffer As Long
Dim nVerMajor As Integer
Dim nVerMinor As Integer
Dim bBuffer() As Byte

Const sDLLFile As String = "shell32.dll"

nBufferSize = GetFileVersionInfoSize(sDLLFile, nUnused)

If nBufferSize > 0 Then

ReDim bBuffer(nBufferSize - 1) As Byte

Call GetFileVersionInfo(sDLLFile, 0&, nBufferSize, bBuffer(0))

If VerQueryValue(bBuffer(0), "\", lpBuffer, nUnused) <> 0 Then

CopyMemory nVerMajor, ByVal lpBuffer + 10, 2
CopyMemory nVerMinor, ByVal lpBuffer + 8, 2
GetShellVersion = Val(nVerMajor & "." & nVerMinor)

End If
End If

End Function



From: expvb on
"Karl E. Peterson" <karl(a)mvps.org> wrote in message
news:e83hj8iYJHA.552(a)TK2MSFTNGP06.phx.gbl...
> Eduardo wrote:
>>> In some versions of Windows the folders aren't created automatically, so
>>> you have to use CSIDL_FLAG_CREATE(In shell32.dll version 5.00 or above).
>>
>> Did you mean shell32.dll version below 5.00?
>> What I understood so far is that with shell32.dll version 5.00 or above
>> the
>> folder will exist for sure. Am I wrong?
>>
>> And seemingly, reading Karl's latest post in this thread, it existed in
>> Win95.
>
> Here's an interesting datapoint. I just created a totally clean Windows
> ME virtual machine. Immediately following the initial boot, both
> CSIDL_APPDATA and CSIDL_COMMON_APPDATA existed, but CSIDL_LOCAL_APPDATA
> wasn't there. At that point, the API returns the following values:
>
> CSIDL_APPDATA: C:\WINDOWS\Application Data
> CSIDL_LOCAL_APPDATA: C:\WINDOWS\Application Data
> CSIDL_COMMON_APPDATA: C:\WINDOWS\All Users\Application Data
>
> But, as you saw, on my 95/98 VMs, that LOCAL_APPDATA folder definitely
> existed. So I'm thinking, you're pretty danged well off forcing the
> creation of the folder when you first create the INI file, otherwise you
> might have some real difficulties later when you come back to look for it.
> (Anyone think I'm reading that situation wrong?) None of these VMs
> specifically had multi-user support enabled, either.

In MSDN help for CSDIL values, some of the constants require specific
versions of Shell32.dll. When you click on the version number, you get a
page describing several DLL's, such as Comctl32.dll and Shlwapi.dll. Only
Shell32.dll is important. CSIDL_APPDATA requires version 4.71 of
Shell32.dll, Windows 98 came with version 4.72, so it supports it. Windows
95 shell could be updated with IE4, but only if the user installed it with
the integrated shell option. IE5 and later don't update the shell, so
checking IE version doesn't tell which shell version the user has. All of
this is mentioned in the help page for version numbers.

I think the integrated shell option adds the Quick Launch toolbar, but I am
not sure. The version of IE that came with Windows 95 4.00.1111 is IE
3.0(4.70.1158).

Windows ME/2000 came with Shell version 5.00, so they support many
constants. However, in ME, there is no NTFS security, so you can use the
program folder for Windows 9x, and usually CSIDL_APPDATA for Windows 2000
and after.