Hello everybody,

The following code causes error (SHELL32.DLL: C0000005: Access Violation on execution of the indicated line. I haven't been able to find the cause using VC6 to compile and debug under Win2000 os.

.586

.model flat,stdcall
option casemap:none

;********************************
;include files
;********************************
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc
include \masm32\include\shell32.inc

include \masm32\include\userenv.inc
include \masm32\include\shfolder.inc
include \masm32\include\shlwapi.inc

include \masm32\include\ole32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib

includelib \masm32\lib\userenv.lib
includelib \masm32\lib\shfolder.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\shlwapi.lib

includelib \masm32\lib\ole32.lib

.data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ProfilePathBuffer db 256 dup(0)
cbSize dd 0
pMem dd 0

.data?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ppidl ITEMIDLIST <>
Foldershfi SHFILEINFO <>
Recycledshfi SHFILEINFO <>

.const
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SHGFP_TYPE_CURRENT equ 0

.code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:


mov cbSize,1024

invoke CoTaskMemAlloc,cbSize
.if eax!=NULL
mov pMem,eax
.else
mov eax,-1
ret
.endif

invoke SHGetFolderPath,NULL,CSIDL_HISTORY,NULL,SHGFP_TYPE_CURRENT,\
ADDR ProfilePathBuffer
invoke SHGetFolderPath,NULL,CSIDL_COOKIES ,NULL,SHGFP_TYPE_CURRENT,\
ADDR ProfilePathBuffer
invoke SHGetFolderPath,NULL,CSIDL_INTERNET_CACHE ,NULL,SHGFP_TYPE_CURRENT,\
ADDR ProfilePathBuffer
invoke SHGetFolderPath,NULL,CSIDL_RECENT ,NULL,SHGFP_TYPE_CURRENT,\
ADDR ProfilePathBuffer

invoke SHGetSpecialFolderLocation,NULL,CSIDL_BITBUCKET,ADDR ppidl

;;;;;;error on the following line;;;;;;;
invoke SHGetFileInfo,ADDR ppidl,NULL,ADDR Foldershfi,\
SIZEOF Foldershfi,SHGFI_PIDL or SHGFI_DISPLAYNAME

invoke SHGetFileInfo,ADDR ppidl,NULL,ADDR Recycledshfi,\
SIZEOF Recycledshfi,SHGFI_PIDL or SHGFI_TYPENAME

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;add code here to compare
;Foldershfi.szDisplayName
;and Recycledshfi.szTypeName
;if equal then Recycle Bin found
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


invoke CoTaskMemFree,pMem

end start


This code should find the path to the recycle bin. any suggestions or ideas are appreciated.

best regards,

czDrillard
Posted on 2004-12-05 13:55:28 by czDrillard
MSDN tells about the first parameter:

> If the uFlags parameter includes the SHGFI_PIDL flag, this parameter must > be the address of an ITEMIDLIST (PIDL)

This can in fact be misinterpreted as it is done in your code. But the first parameter should be a PIDL only, not a pointer to a PIDL. Just remove the ADDR.
Posted on 2004-12-05 17:28:32 by japheth
Thanks japheth, the following code executes without errors:

invoke SHGetSpecialFolderLocation,NULL,CSIDL_BITBUCKET,ADDR ppidl 


mov esi,offset ppidl
invoke SHGetFileInfo,[esi],NULL,ADDR Foldershfi,\
SIZEOF Foldershfi,SHGFI_PIDL or SHGFI_DISPLAYNAME

mov esi,offset ppidl
invoke SHGetFileInfo,[esi],NULL,ADDR Recycledshfi,\
SIZEOF Recycledshfi,SHGFI_PIDL or SHGFI_TYPENAME


This returns Recycle Bin in the Foldershfi.szDisplayName member and System Folder in the Recycledshfi.szTypeName member.

I was wrong in assuming I could compare these two values and thinking I would extract the path to the Recycle Bin. All I'm getting is the current name of the Recycle Bin and not its location.

Does anyone know of a method to determine the path to the Recycle Bin other than using FindFirst/FindNext? I seem to be getting nowhere here :cry:

best regards,

czDrillard
Posted on 2004-12-05 18:59:32 by czDrillard
The Recycle Bin is not necessarily a single directory. Therefore, you shouldn't assume it has one path.
Posted on 2004-12-05 19:36:49 by death
Hi death, I have two physical hard drives on my computer and 3 virtual drives. However if I use FindFirst/FindNext functions I can find the paths to all the virtual recyle bins. I just didn't want to use that method. Say somebody renamed their recycle bin Trash Bin my search would fail. Using the shell functions and I would get the display name of the trash bin and could do a physical search for it using FindFirst/FindNext.

I just hoped I would be able to find the full path using the shell functions. How does windows explorer find the recycle bin and display its path in the treeview?

best regards,

czDrillard
Posted on 2004-12-05 20:31:47 by czDrillard
Hello czDrillard,

You can determine wether a directory is a Recycle Bin directory by comparing its type name to the Recycle Bin's display name (the one you got in your code).
Posted on 2004-12-05 20:39:37 by death
Hello death,

You are saying what I want to hear but what I don't know how to do. As I wrote in my earlier post:
This returns Recycle Bin in the Foldershfi.szDisplayName member and System Folder in the Recycledshfi.szTypeName member.

Would not TypeName always be System Folder and DisplayName usually be Recycle Bin but never System Folder? If this is true then the comparison would always return false.

Maybe my brain is overworked and I no longer think clearly but there is something here I don't understand.

best regards,

czDrillard
Posted on 2004-12-05 22:34:52 by czDrillard
what about using SHGetPathFromIDList? Doesnt that work with the recycle bin?
Posted on 2004-12-06 01:52:33 by japheth
Hello japheth and thanks,

Unfortunately SHGetPathFromIDList always fails on Recycle Bin. This from the SDK:
If the location specified by the pidl parameter is not part of the file system, this function will fail.

I think what I could do is to first get the DisplayName of the Recycle Bin using SHGetSpecialFolderLocation then get the PIDL from CLSIDL_DESKTOP and enumerate the items until they match DisplayName. I would then have the path to Recycle Bin?? I think the folder is actually called Recycled though. At this point I could start searching with FindFirst/FindNext using the path for the folder Recycled. This would save me recursively going through the entire hard drive.

If anybody has a better idea I'd sure like to hear it.

best regards,

czDrillard
Posted on 2004-12-06 08:47:56 by czDrillard
What is the reason you need a path to the Recycle Bin?
Posted on 2004-12-06 15:55:23 by death
Hello death,

My program shreds files including ones in the Recycle Bin. Otherwise I could just use SHEmptyRecycleBin.

Btw, how that function finds the Recycle Bin? Maybe it would be safe to assume that the Recycled folder is always found in the root directory of every drive.

best regards,

czDrillard
Posted on 2004-12-07 00:31:04 by czDrillard
You might find this interesting...

http://www.pcmag.com/article2/0,1759,1163071,00.asp
Posted on 2004-12-07 02:24:24 by donkey
AFAIK there's no documented way to get the paths to the Recycle Bin folders.

What the author does in the link donkey pasted is the same as what the shell does - it appends either RECYCLED or RECYCLER to the root directory. The shell gets the possible drives and Recycle Bin options using the following key:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\BitBucket

Since this is undocumented, you can't expect it to work in the future. AFAIK it works for all previous and current Windows versions.
Posted on 2004-12-07 03:51:23 by death
Thanks for the link donkey. I agree with what you say death. There is no documented way to find the recycle bin, at least none that I know of.

I will just use the old tried and tested FindFirst/FindNext method.

best regards,

czDrillard
Posted on 2004-12-07 19:40:49 by czDrillard