Announcement

Collapse
No announcement yet.

Am I Doing Get Special Folders Right?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Am I Doing Get Special Folders Right?

    Want to ensure that this works across all platforms, all I got to test with is w2k platforms:
    Code:
    FUNCTION GetSpecialFolderPath(hWindow AS DWORD, nFolder AS LONG) AS STRING
    LOCAL pidl          AS LONG
    LOCAL SpecialPath   AS ASCIIZ * %MAX_PATH
    
      ON ERROR GOTO NotExported
    
      SHGetSpecialFolderPath hWindow, SpecialPath, nFolder, 0
      IF INSTR(SpecialPath, $NUL) > 1 THEN
        GetSpecialFolderPath = SpecialPath
        #DEBUG PRINT "SHGetSpecialFolderPath Success"
        EXIT FUNCTION
      END IF
    
    NotExported:
    
      IF SHGetSpecialFolderLocation(hWindow, nFolder, pidl) = %NOERROR THEN
        IF pidl THEN
            #DEBUG PRINT "SHGetSpecialFolderLocation Success"
          IF SHGetPathFromIDList(BYVAL pidl, SpecialPath) THEN
            GetSpecialFolderPath = SpecialPath
            #DEBUG PRINT "SHGetPathFromIDList Success"
          END IF
          CoTaskMemFree pidl
          EXIT FUNCTION
        END IF
      END IF
        #DEBUG PRINT "GetSpecialFolderPath Failure"
    END FUNCTION
    Simple test code, the function it calls just returns the %ID and the commentary from the left side of the definitions from the wind32api file:
    Code:
    LOCAL sFolder AS STRING, sIndex AS LONG
        FOR sIndex = %CSIDL_DESKTOP TO %CSIDL_RESOURCES
            sFolder = GetSpecialFolderPath(CB.HNDL, sIndex)
            #DEBUG PRINT HEX$(sIndex, 2) &" / "& GetFolderAlias(sIndex)
            #DEBUG PRINT " = "& sFolder
            #DEBUG PRINT ""
        NEXT sIndex
    And on my machine here, this returns:
    Code:
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    00 / %CSIDL_DESKTOP ' <desktop>
     = F:\mug\Desktop
    
    SHGetSpecialFolderLocation Success
    01 / %CSIDL_INTERNET ' Internet Explorer (icon on desktop)
     = 
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    02 / %CSIDL_PROGRAMS ' Start Menu\Programs
     = F:\mug\Start Menu\Programs
    
    SHGetSpecialFolderLocation Success
    03 / %CSIDL_CONTROLS ' My Computer\Control Panel
     = 
    
    SHGetSpecialFolderLocation Success
    04 / %CSIDL_PRINTERS ' My Computer\Printers
     = 
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    05 / %CSIDL_PERSONAL ' My Documents
     = F:\mug\My Documents
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    06 / %CSIDL_FAVORITES ' <user name>\Favorites
     = F:\mug\Favorites
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    07 / %CSIDL_STARTUP ' Start Menu\Programs\Startup
     = F:\mug\Start Menu\Programs\Startup
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    08 / %CSIDL_RECENT ' <user name>\Recent
     = F:\mug\Recent
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    09 / %CSIDL_SENDTO ' <user name>\SendTo
     = F:\mug\SendTo
    
    SHGetSpecialFolderLocation Success
    0A / %CSIDL_BITBUCKET ' <desktop>\Recycle Bin
     = 
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    0B / %CSIDL_STARTMENU ' <user name>\Start Menu
     = F:\mug\Start Menu
    
    GetSpecialFolderPath Failure
    0C / %CSIDL_MYDOCUMENTS  logical 'My Documents' desktop icon
     = 
    
    GetSpecialFolderPath Failure
    0D / %CSIDL_MYMUSIC  'My Music' folder
     = 
    
    GetSpecialFolderPath Failure
    0E / %CSIDL_MYVIDEO  'My Videos' folder
     = 
    
    GetSpecialFolderPath Failure
    0F / 
     = 
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    10 / %CSIDL_DESKTOPDIRECTORY ' <user name>\Desktop
     = F:\mug\Desktop
    
    SHGetSpecialFolderLocation Success
    11 / %CSIDL_DRIVES ' My Computer
     = 
    
    SHGetSpecialFolderLocation Success
    12 / %CSIDL_NETWORK ' Network Neighborhood
     = 
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    13 / %CSIDL_NETHOOD ' <user name>\nethood
     = F:\mug\NetHood
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    14 / %CSIDL_FONTS ' windows\fonts
     = C:\winnt\Fonts
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    15 / %CSIDL_TEMPLATES 
     = F:\mug\Templates
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    16 / %CSIDL_COMMON_STARTMENU ' All Users\Start Menu
     = F:\All Users\Start Menu
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    17 / %CSIDL_COMMON_PROGRAMS ' All Users\Programs
     = F:\All Users\Start Menu\Programs
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    18 / %CSIDL_COMMON_STARTUP ' All Users\Startup
     = F:\All Users\Start Menu\Programs\Startup
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    19 / %CSIDL_COMMON_DESKTOPDIRECTORY ' All Users\Desktop
     = F:\All Users\Desktop
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    1A / %CSIDL_APPDATA ' <user name>\Application Data
     = F:\mug\Application Data
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    1B / %CSIDL_PRINTHOOD ' <user name>\PrintHood
     = F:\mug\PrintHood
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    1C / %CSIDL_LOCAL_APPDATA ' <user name>\Local Settings\Application Data (non roaming)
     = F:\mug\Local Settings\Application Data
    
    GetSpecialFolderPath Failure
    1D / %CSIDL_ALTSTARTUP ' non localized startup
     = 
    
    GetSpecialFolderPath Failure
    1E / %CSIDL_COMMON_ALTSTARTUP ' non localized common startup
     = 
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    1F / %CSIDL_COMMON_FAVORITES 
     = F:\All Users\Favorites
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    20 / %CSIDL_INTERNET_CACHE 
     = F:\mug\Local Settings\Temporary Internet Files
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    21 / %CSIDL_COOKIES 
     = F:\mug\Cookies
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    22 / %CSIDL_HISTORY 
     = F:\mug\Local Settings\History
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    23 / %CSIDL_COMMON_APPDATA ' All Users\Application Data
     = F:\All Users\Application Data
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    24 / %CSIDL_WINDOWS ' GetWindowsDirectory()
     = C:\winnt
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    25 / %CSIDL_SYSTEM ' GetSystemDirectory()
     = C:\winnt\system32
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    26 / %CSIDL_PROGRAM_FILES ' C:\Program Files
     = C:\Program Files
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    27 / %CSIDL_MYPICTURES ' C:\Program Files\My Pictures
     = F:\mug\My Documents\My Pictures
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    28 / %CSIDL_PROFILE ' USERPROFILE
     = F:\mug
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    29 / %CSIDL_SYSTEMX86 ' x86 system directory on RISC
     = C:\winnt\system32
    
    GetSpecialFolderPath Failure
    2A / %CSIDL_PROGRAM_FILESX86 ' x86 C:\Program Files on RISC
     = 
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    2B / %CSIDL_PROGRAM_FILES_COMMON ' C:\Program Files\Common
     = C:\Program Files\Common Files
    
    GetSpecialFolderPath Failure
    2C / %CSIDL_PROGRAM_FILES_COMMONX86 ' x86 Program Files\Common on RISC
     = 
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    2D / %CSIDL_COMMON_TEMPLATES ' All Users\Templates
     = F:\All Users\Templates
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    2E / %CSIDL_COMMON_DOCUMENTS ' All Users\Documents
     = F:\All Users\Documents
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    2F / %CSIDL_COMMON_ADMINTOOLS ' All Users\Start Menu\Programs\Administrative Tools
     = F:\All Users\Start Menu\Programs\Accessories\Administrative Tools
    
    SHGetSpecialFolderLocation Success
    SHGetPathFromIDList Success
    30 / %CSIDL_ADMINTOOLS ' <user name>\Start Menu\Programs\Administrative Tools
     = F:\All Users\Start Menu\Programs\Accessories\Administrative Tools
    
    SHGetSpecialFolderLocation Success
    31 / %CSIDL_CONNECTIONS ' Network and Dial-up Connections
     = 
    
    GetSpecialFolderPath Failure
    32 / 
     = 
    
    GetSpecialFolderPath Failure
    33 / 
     = 
    
    GetSpecialFolderPath Failure
    34 / 
     = 
    
    GetSpecialFolderPath Failure
    35 / %CSIDL_COMMON_MUSIC ' All Users\My Music
     = 
    
    GetSpecialFolderPath Failure
    36 / %CSIDL_COMMON_PICTURES ' All Users\My Pictures
     = 
    
    GetSpecialFolderPath Failure
    37 / %CSIDL_COMMON_VIDEO ' All Users\My Video
     = 
    
    GetSpecialFolderPath Failure
    38 / %CSIDL_RESOURCES ' Resource Direcotry
     =
    Notation: Yes, on this machine, my Documents & Settings has been hashed to point to another hard drive, this was done when installing windows, before creating any user accounts, by editing the value at:
    HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
    ProfilesDirectory = VALUE
    Then copying ALL USERS and DEFAULT USER to the drive.

    There might of been more involved stuff in whacking the registry, don't remember, it's been years since I've needed to install w2k on a machine.

    Shouldn't bother going off on a tangent about that, now everyone will start discussing different means to do that, ...
    Furcadia, an interesting online MMORPG in which you can create and program your own content.

  • #2
    >Am I Doing Get Special Folders Right>

    Not really.

    You need to interrogate the return from ShGetSpecialFolderPath.
    Code:
      iRet = ShGetSpecialFolderPath  (params) 
      IF ISTRUE iRet THEN 
         ' call succeeded, so now you can parse out the return data buffer
      ELSE
        ' call failed
         LE = GetLastError()     ' get Windows error code for the error.
         FormatMessage.....    ' get text of Windows error for display 
     .....
    PB's ERR system variable does not return any data for direct calls to Windows API functions, that is, the ON ERROR in your code will never be executed because the call failed, although it could be executed because one of the PB verbs failed.

    Here's some code which may or may not be useful...
    Move That INI File! and Get That Ini File Name!

    MCM
    Michael Mattias
    Tal Systems Inc. (retired)
    Racine WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      >Want to ensure that this works across all platforms...

      If you mean using the WinAPI calls with the %CSIDL_xxxx constants to locate special folders, it does, at least on systems from Win/98 thru Vista/32. I don't have any clients on Win/95 or Vista/64 so I can't speak to those.
      Michael Mattias
      Tal Systems Inc. (retired)
      Racine WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        Looking at the documentation and the examples, I really don't need to try the SHGetSpecialFolderPath at all it seems. And considering that I'm wanting to put my ini file in an existing %CSIDL_LOCAL_APPDATA folder, I really don't need all the extensive testing and creation code either. Thanks for the tip.
        Furcadia, an interesting online MMORPG in which you can create and program your own content.

        Comment


        • #5
          really don't need to try the SHGetSpecialFolderPath at all it seems. And considering that I'm wanting to put my ini file in an existing %CSIDL_LOCAL_APPDATA folder, I
          ????

          If you want to put your data in CSIDL_LOCAL_APPDATA, you need to use "some" system call to get the name of that folder, unless you hard-code it for a specific system.

          Real Men don't hardcode special folder names, they use CSIDL_* equates and one of the system API functions to get the name.

          Note also, those folders ARE user-moveable (But I have never seen that actually done).

          I really don't need all the extensive testing and creation code either. Thanks for the tip.
          What extensive testing and creation? It's a one-line call to "GetIniFileName" (post #2) after you set your equates.

          MCM
          Michael Mattias
          Tal Systems Inc. (retired)
          Racine WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            I'm sorry Michael, I am saying all that really wrong, what I mean is that all I needed was this as a matter of fact:
            Code:
                iRet = ShGetFolderPath (BYVAL %NULL, _             ' hWnd, "typically null"
                                        %CSIDL_LOCAL_APPDATA, _    ' (supported) CSIDL value
                                        BYVAL %NULL, _             ' hToken for security, null  = Default
                                        BYVAL 0, _                 ' above
                                        szBaseFolder)
            Some times I don't explain the reasoning why, but the deal is that I'm writing, (or rather porting from VB), a file editor for an online game. If you don't have the game installed, there's not much sense in using the editor. After getting the back this particular folder, I tack on a specific path and check for the presence of the game's data folder, and if it's not there, not much sense in going further because my editor's fairly useless without the game data files.

            BTW: Why break down the folder path to be created when you can use SHCreateDirectoryEx to create the whole thing in one action?
            Furcadia, an interesting online MMORPG in which you can create and program your own content.

            Comment


            • #7
              What I was trying to point out was that your original test...
              Code:
               IF INSTR(SpecialPath, $NUL) > 1 THEN
              ... is not the correct test for the success or failure of the call to ShGetSpecialFolderPath. The correct test is the value of the function's return value.

              After that succeeds, you can parse out or modify or do whatever you want with the data now in the variable 'SpecialPath.'

              MCM
              Michael Mattias
              Tal Systems Inc. (retired)
              Racine WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                I realize that now, forgive me with some strange quirks from the code, a lot of it is cut and paste from one of 2 VB projects which contain a lot of strange eXtreme coding actions to make the API call work in VB. The prefix for that particular line was preloading the return string with String$(MaxPath, 0), ...
                Furcadia, an interesting online MMORPG in which you can create and program your own content.

                Comment


                • #9
                  It would have been the wrong test in VB, too.

                  Just as a general rule.....

                  When a WinAPI function returns failure, you cannot use the contents of any variable that function would have filled had it succeeded.

                  MCM
                  Michael Mattias
                  Tal Systems Inc. (retired)
                  Racine WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment

                  Working...
                  X