windirs.pp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. unit windirs;
  2. {$mode objfpc}
  3. {$H+}
  4. interface
  5. uses
  6. windows;
  7. Const
  8. CSIDL_PROGRAMS = $0002; { %SYSTEMDRIVE%\Program Files }
  9. CSIDL_PERSONAL = $0005; { %USERPROFILE%\My Documents }
  10. CSIDL_FAVORITES = $0006; { %USERPROFILE%\Favorites }
  11. CSIDL_STARTUP = $0007; { %USERPROFILE%\Start menu\Programs\Startup }
  12. CSIDL_RECENT = $0008; { %USERPROFILE%\Recent }
  13. CSIDL_SENDTO = $0009; { %USERPROFILE%\Sendto }
  14. CSIDL_STARTMENU = $000B; { %USERPROFILE%\Start menu }
  15. CSIDL_MYMUSIC = $000D; { %USERPROFILE%\Documents\My Music }
  16. CSIDL_MYVIDEO = $000E; { %USERPROFILE%\Documents\My Videos }
  17. CSIDL_DESKTOPDIRECTORY = $0010; { %USERPROFILE%\Desktop }
  18. CSIDL_NETHOOD = $0013; { %USERPROFILE%\NetHood }
  19. CSIDL_TEMPLATES = $0015; { %USERPROFILE%\Templates }
  20. CSIDL_COMMON_STARTMENU = $0016; { %PROFILEPATH%\All users\Start menu }
  21. CSIDL_COMMON_PROGRAMS = $0017; { %PROFILEPATH%\All users\Start menu\Programs }
  22. CSIDL_COMMON_STARTUP = $0018; { %PROFILEPATH%\All users\Start menu\Programs\Startup }
  23. CSIDL_COMMON_DESKTOPDIRECTORY = $0019; { %PROFILEPATH%\All users\Desktop }
  24. CSIDL_APPDATA = $001A; { %USERPROFILE%\Application Data (roaming) }
  25. CSIDL_PRINTHOOD = $001B; { %USERPROFILE%\Printhood }
  26. CSIDL_LOCAL_APPDATA = $001C; { %USERPROFILE%\Local Settings\Application Data (non roaming) }
  27. CSIDL_COMMON_FAVORITES = $001F; { %PROFILEPATH%\All users\Favorites }
  28. CSIDL_INTERNET_CACHE = $0020; { %USERPROFILE%\Local Settings\Temporary Internet Files }
  29. CSIDL_COOKIES = $0021; { %USERPROFILE%\Cookies }
  30. CSIDL_HISTORY = $0022; { %USERPROFILE%\Local settings\History }
  31. CSIDL_COMMON_APPDATA = $0023; { %PROFILESPATH%\All Users\Application Data }
  32. CSIDL_WINDOWS = $0024; { %SYSTEMROOT% }
  33. CSIDL_SYSTEM = $0025; { %SYSTEMROOT%\SYSTEM32 (may be system on 95/98/ME) }
  34. CSIDL_PROGRAM_FILES = $0026; { %SYSTEMDRIVE%\Program Files }
  35. CSIDL_MYPICTURES = $0027; { %USERPROFILE%\My Documents\My Pictures }
  36. CSIDL_PROFILE = $0028; { %USERPROFILE% }
  37. CSIDL_PROGRAM_FILES_COMMON = $002B; { %SYSTEMDRIVE%\Program Files\Common }
  38. CSIDL_COMMON_TEMPLATES = $002D; { %PROFILEPATH%\All Users\Templates }
  39. CSIDL_COMMON_DOCUMENTS = $002E; { %PROFILEPATH%\All Users\Documents }
  40. CSIDL_COMMON_ADMINTOOLS = $002F; { %PROFILEPATH%\All Users\Start Menu\Programs\Administrative Tools }
  41. CSIDL_ADMINTOOLS = $0030; { %USERPROFILE%\Start Menu\Programs\Administrative Tools }
  42. CSIDL_COMMON_MUSIC = $0035; { %PROFILEPATH%\All Users\Documents\my music }
  43. CSIDL_COMMON_PICTURES = $0036; { %PROFILEPATH%\All Users\Documents\my pictures }
  44. CSIDL_COMMON_VIDEO = $0037; { %PROFILEPATH%\All Users\Documents\my videos }
  45. CSIDL_CDBURN_AREA = $003B; { %USERPROFILE%\Local Settings\Application Data\Microsoft\CD Burning }
  46. CSIDL_PROFILES = $003E; { %PROFILEPATH% }
  47. CSIDL_FLAG_CREATE = $8000; { (force creation of requested folder if it doesn't exist yet) }
  48. Function GetWindowsSpecialDir(ID : Integer) : String;
  49. implementation
  50. uses
  51. sysutils;
  52. Type
  53. PFNSHGetFolderPath = Function(Ahwnd: HWND; Csidl: Integer; Token: THandle; Flags: DWord; Path: {$ifdef FPC_UNICODE_RTL}PWideChar{$ELSE}PChar{$ENDIF}): HRESULT; stdcall;
  54. var
  55. SHGetFolderPath : PFNSHGetFolderPath = Nil;
  56. CFGDLLHandle : THandle = 0;
  57. Procedure InitDLL;
  58. Var
  59. pathBuf: array[0..MAX_PATH-1] of {$ifdef FPC_UNICODE_RTL}WideChar{$else}Ansichar{$endif};
  60. pathLength: Integer;
  61. begin
  62. { Load shfolder.dll using a full path, in order to prevent spoofing (Mantis #18185)
  63. Don't bother loading shell32.dll because shfolder.dll itself redirects SHGetFolderPath
  64. to shell32.dll whenever possible. }
  65. pathLength:=GetSystemDirectory(pathBuf, MAX_PATH);
  66. if (pathLength>0) and (pathLength<MAX_PATH-14) then { 14=length('\shfolder.dll'#0) }
  67. begin
  68. StrLCopy(@pathBuf[pathLength],'\shfolder.dll',MAX_PATH-pathLength-1);
  69. CFGDLLHandle:=LoadLibrary(pathBuf);
  70. if (CFGDLLHandle<>0) then
  71. begin
  72. Pointer(ShGetFolderPath):=GetProcAddress(CFGDLLHandle,{$ifdef FPC_UNICODE_RTL}'SHGetFolderPathW'{$else}'SHGetFolderPathA'{$endif});
  73. If @ShGetFolderPath=nil then
  74. begin
  75. FreeLibrary(CFGDLLHandle);
  76. CFGDllHandle:=0;
  77. end;
  78. end;
  79. end;
  80. If (@ShGetFolderPath=Nil) then
  81. Raise Exception.Create('Could not determine SHGetFolderPath Function');
  82. end;
  83. Function GetWindowsSpecialDir(ID : Integer) : String;
  84. Var
  85. APath : Array[0..MAX_PATH] of char;
  86. begin
  87. Result:='';
  88. if (CFGDLLHandle=0) then
  89. InitDLL;
  90. If (SHGetFolderPath<>Nil) then
  91. begin
  92. if SHGetFolderPath(0,ID or CSIDL_FLAG_CREATE,0,0,@APATH[0])=S_OK then
  93. Result:=IncludeTrailingPathDelimiter(StrPas(@APath[0]));
  94. end;
  95. end;
  96. Initialization
  97. Finalization
  98. if CFGDLLHandle<>0 then
  99. FreeLibrary(CFGDllHandle);
  100. end.