The examples are based on the Windows SDK by ToutEnMasm so you need that. You can download it here:
http://luce.yves.pagesperso-orange.fr/sdkrc7.cab.For more information about the Windows SDK search for "windows.sdk" in the old forum and select the subject with the title "Revision of the "ready to use sdk heder's files" and of the masm32 samples".
The examplesThe attached zip-file contains two source files: PrintFileFolders.asm and PrintSysFolders.asm.
PrintFileFolders.asm enumerates files and subfolders of an ordinary file folder e.g. C:\.
PrintSysFolders.asm enumerates files and subfolders of a system/special folder e.g. Desktop, My Computer, Control Panel or Recycle Bin. More precisely folders given by a CSIDL_constant.
The enumaration is done with the methods of the IShellFolder and IEnumIDList interfaces.
The methods of the IShellFolder interface works on
relative PIDL's (pointers to ITEMIDLIST structures, see
http://msdn.microsoft.com/en-us/library/windows/desktop/cc144090(v=vs.85).aspx).
To enumerate a folder get an IShellFolder interface pointer for the folder. Use the EnumObjects method of the interface to get an IEnumIDList interface pointer. Use the Next method of this interface to enumerate the files and subfolders. The Next method provides relative PIDLs. Finally use the IShellFolder interface with the relative PIDLs to get information for the files and subfolders.
The plan to enumerate a folder is:
0. Get a fully qualified PIDL for the folder
1. Get the name of the folder and print it
2. Get the names of the files and print them
3. Get fully qualified PIDLs for the subfolders
4. Repeat step 1 - 4 for the subfolders
This plan is used for both file and system folders. But the implementation is slightly different and that's why there are two source files. An important difference is that to successfully enumerate a
system folder you must
initialize COM.
Step 0 is used to get started. It's only done once. The procedures in the source files to implement step 0 are EnumFileFolder and EnumSystemFolder. A parameter is used to define how many levels to enumerate.
The procedure to implement step 1 - 4 is EnumSubFolder in both source files. Step 4 is done by recursion.
Implementation0. Get a fully qualified PIDL for the folderA
fully qualified PIDL corresponds to a full path. It's used to get an IShellFolder interface pointer for the
parent folder.
File folder:
invoke ILCreateFromPath, FullPath
mov pPidlFQ, eaxhttp://msdn.microsoft.com/en-us/library/windows/desktop/dd378420(v=vs.85).aspxSystem folder:
invoke SHGetFolderLocation, NULL, csidl, NULL, 0, ADDR pPidlFQhttp://msdn.microsoft.com/en-us/library/windows/desktop/bb762180(v=vs.85).aspxpPidlFQ is the fully qualified PIDL.
1. Get the name of the folder and print itWith pPidlFQ get an IShellFolder interface pointer for the
parent folder and a relative PIDL for the folder:
invoke SHBindToParent, pPidlFQ, offset IID_IShellFolder, ADDR ppvIShellFolder, ADDR pPidlRelhttp://msdn.microsoft.com/en-us/library/windows/desktop/bb762114(v=vs.85).aspxGet the name of the folder:
IShellFolder GetDisplayNameOf, pPidlRel, SHGDN_NORMAL, ADDR strrethttp://msdn.microsoft.com/en-us/library/windows/desktop/bb775075(v=vs.85).aspx2. Get the names of the files and print themGet an IShellFolder interface pointer for the folder (not parent):
IShellFolder BindToObject, pPidlRel, NULL, offset IID_IShellFolder, ADDR ppvIShellFolderGet an IEnumIDList interface pointer to enumerate the
files of the folder:
IShellFolder EnumObjects1, 0, SHCONTF_NONFOLDERS+SHCONTF_INCLUDEHIDDEN, ADDR ppvIEnumIDListEnumerate the files:
.while(1)
IEnumIDList Next, 1, ADDR pPidl, NULL
.break .if eax != S_OK
IShellFolder GetDisplayNameOf, pPidl, SHGDN_NORMAL, ADDR strret
.endw(IEnumIDList: see
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761982(v=vs.85).aspx)
3. Get fully qualified PIDLs for the subfoldersGet an IEnumIDList interface pointer to enumerate the
subfolders of the folder:
IShellFolder EnumObjects1, 0, SHCONTF_FOLDERS+SHCONTF_INCLUDEHIDDEN, ADDR ppvIEnumIDListEnumerate the subfolders:
.while(1)
IEnumIDList Next, 1, ADDR pPidl, NULL ; Enumerate the subfolders of the folder associated with pPidlFQ.
.break .if eax != S_OK ; Get a fully qualified PIDL for the subfolder by combining pPidlFQ
invoke ILCombine, pPidlFQ, pPidl ; for the parent folder with pPidl for the subfolder. pPidl is the
mov pPidlSub, eax ; PIDL for the subfolder relative to the parent folder.
invoke EnumSubFolder, pPidlSub, nextLevel ; Enumerate the subfolder (step 4)
.endwLink the obj-filesLink the obj-files as CONSOLE applications.
To be able to link I had to comment out 3 lines in
ShObjIdl.sdk because of "unresolved external symbol" errors:
;SetTextColor comethod2 ?
;PlaySound comethod2 ?
;PlaySound comethod2 ?
My antivirus program (Avira Free Antivirus) detects virus alarms in the exe-files.
Testet on XP SP3.
LarsJ