Hello, I need to maintain a list of PIDL's (ITEMIDLIST's) between sessions.
The only way I can do it so far is to create a shortcut (.lnk) on the disk for every PIDL... something like this (extended from shell_COM_example.eba):
' ---------------------------------------------------------------------------------------------
' DECLARATIONS
' ---------------------------------------------------------------------------------------------
$INCLUDE "ishelllink.inc"
CONST CSIDLDESKTOP = 0x0000
CONST CSIDLPROGRAMS = 0x0002
CONST CSIDLCONTROLS = 0x0003
CONST CSIDLPRINTERS = 0x0004
CONST CSIDLPERSONAL = 0x0005
CONST CSIDLFAVORITES = 0x0006
CONST CSIDLSTARTUP = 0x0007
CONST CSIDLRECENT = 0x0008
CONST CSIDLSENDTO = 0x0009
CONST CSIDLBITBUCKET = 0x000a
CONST CSIDLSTARTMENU = 0x000b
CONST CSIDLDESKTOPDIRECTORY = 0x0010
CONST CSIDLDRIVES = 0x0011
CONST CSIDLNETWORK = 0x0012
CONST CSIDLNETHOOD = 0x0013
CONST CSIDLFONTS = 0x0014
CONST CSIDLTEMPLATES = 0x0015
CONST CSIDLCMNSTARTMENU = 0x0016
CONST CSIDLCMNPROGRAMS = 0x0017
CONST CSIDLCMNSTARTUP = 0x0018
CONST CSIDLCMNDESKTOPDIRECTORY = 0x0019
CONST CSIDLAPPDATA = 0x001a
CONST CSIDLPRINTHOOD = 0x001b
CONST CP_ACP = 0
CONST CLSCTX_INPROC_SERVER = 1
$define STGM_READ               0x00000000
DECLARE IMPORT,SHGetSpecialFolderLocation(hwnd as UINT,nFolder as INT,ppITEMIDLIST as POINTER),int
DECLARE IMPORT,SHGetPathFromIDList(pITEMIDLIST:POINTER,PATH:STRING),int
DECLARE IMPORT,CoTaskMemFree(pidl:POINTER)
DECLARE IMPORT,MultiByteToWideChar(codepage as UINT,dwFlags as UINT,lpMBS as STRING,cchMB as INT,lpWCS as POINTER,cchWC as INT)
' ---------------------------------------------------------------------------------------------
' MAIN
' ---------------------------------------------------------------------------------------------
OPENCONSOLE
	PRINT "Save and load PIDL's (using shortcuts)..."
	PRINT ""
	
	DoExample()
	PRINT ""
	PRINT "Press any key to close"
	DO:UNTIL INKEY$ <> ""
CLOSECONSOLE
SUB DoExample()
	ISTRING lnkPath[260, 3] 
    pointer pidl[3]
    
	'Make sure COM is active
	CoInitialize(NULL)
	
	'the .lnk target files
	lnkPath[0, 0] = GETSTARTPATH + "my_pidl1.lnk"
	lnkPath[0, 1] = GETSTARTPATH + "my_pidl2.lnk"
	lnkPath[0, 2] = GETSTARTPATH + "my_pidl3.lnk"
	
	' fill the PIDL's with some locations
	SHGetSpecialFolderLocation(0, CSIDLPERSONAL, &pidl[0])
	SHGetSpecialFolderLocation(0, CSIDLFAVORITES, &pidl[1])
	SHGetSpecialFolderLocation(0, CSIDLDESKTOP, &pidl[2])
	
	FOR j = 0 TO 2
		'Save PIDL's to file (.lnk)
		IF SavePIDL(lnkPath[0, j], pidl[j]) = 0 THEN
			CoTaskMemFree(pidl[j])
			
			'Load PIDL's back from the file
			pidl[j] = LoadPIDL(lnkPath[0, j])
			IF pidl[j] THEN
				lnkPath[0, j] = ""
			
				' show to where the PIDL's points to...
				' ... cuz the tree PIDL's have physical address
				' this is just to check
				SHGetPathFromIDList(pidl[j], lnkPath[0, j])
				PRINT "PIDL[" + STR$(j) + " ] points to: " + lnkPath[0, j]
				CoTaskMemFree(pidl[j])
			ENDIF
		ENDIF
	NEXT j
		
	'Shut down COM
	CoUninitialize()
ENDSUB
' ---------------------------------------------------------------------------------------------
' FUNCTIONS
' ---------------------------------------------------------------------------------------------
SUB GetFolderLocation(nFolder:INT),STRING
     ISTRING path[260] = ""
     POINTER pidl = 0
     POINTER ppidl = 0
	 
     ppidl = &pidl
     SHGetSpecialFolderLocation(NULL,nFolder,ppidl)
     SHGetPathFromIDList(pidl,path)
     CoTaskMemFree(pidl)
	 
	RETURN path
ENDSUB
SUB SavePIDL(STRING lpszPathLink, pointer pidl),INT 
    INT hres = 0
    IShellLinkA psl = NULL
 	IPersistFile ppf = NULL
	WORD wsz[260]
	
    'Get a pointer to the IShellLink interface. 
    hres = CoCreateInstance(_CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, _IID_IShellLinkA, psl)
    if (hres = 0)
		'set the PIDL of the IShellLink
		psl->SetIDList(*<ITEMIDLIST>pidl)
       'Query IShellLink for the IPersistFile interface for saving the 
       'shortcut in persistent storage. 
        hres = psl->QueryInterface(_IID_IPersistFile,ppf)
		if (hres = 0)
             'Ensure that the string is ANSI unicode. 
            MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1,wsz, 260)
             'Save the link by calling IPersistFile->Save. 
            hres = ppf->Save(wsz, TRUE) 
            ppf->Release()
        endif 
        psl->Release()
    endif 
    return hres
ENDSUB
SUB LoadPIDL(STRING lpszPathLink), pointer 
    INT hres = 0
    IShellLinkA psl = NULL
 	IPersistFile ppf = NULL
	WORD wsz[260]
	pointer pidl = 0
	
    'Get a pointer to the IShellLink interface. 
    hres = CoCreateInstance(_CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, _IID_IShellLinkA, psl)
    if (hres = 0)
		'set the PIDL of the IShellLink
		psl->SetIDList(*<ITEMIDLIST>pidl)
       'Query IShellLink for the IPersistFile interface for saving the 
       'shortcut in persistent storage. 
        hres = psl->QueryInterface(_IID_IPersistFile,ppf)
		if (hres = 0)
             'Ensure that the string is ANSI unicode. 
            MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1,wsz, 260)
             'load the link by calling IPersistFile->Load. 
            hres = ppf->Load(wsz, STGM_READ) 
			if (hres = 0) THEN psl->GetIDList(&pidl)
            ppf->Release()
        endif 
        psl->Release()
    endif 
    return pidl
ENDSUB
But it would be great to save and load all PIDL's from just one single file. Is it possible?
			
			
			
				Fasecero, an ITEMIDLIST is just a memory block allocated by CoTaskMemAlloc, or Alloc method from IMalloc interface. It contains an array of SHITEMID structures (size+string), and it is well explained here (http://msdn.microsoft.com/en-us/library/cc144090(VS.85).aspx).
Give it a try.
			
			
			
				Iterating through each SHITEMID I get the total size in bytes, then I save the size (as integer) and after all those bytes. 
To read the ITEMIDLIST again, I read the size and with CoTaskMemAlloc(...) I make the allocation again, then I read the bytes. 
It works well, thanks Sapero.