ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
October 2007
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
20 participants
708 discussions
Start a n
N
ew thread
[hpoussin] 30001: Replace drive letter by a root path
by hpoussin@svn.reactos.org
Author: hpoussin Date: Wed Oct 31 12:10:20 2007 New Revision: 30001 URL:
http://svn.reactos.org/svn/reactos?rev=30001&view=rev
Log: Replace drive letter by a root path Modified: trunk/reactos/dll/win32/shell32/recyclebin.c trunk/reactos/lib/recyclebin/recyclebin.c trunk/reactos/lib/recyclebin/recyclebin.h Modified: trunk/reactos/dll/win32/shell32/recyclebin.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/recycleb…
============================================================================== --- trunk/reactos/dll/win32/shell32/recyclebin.c (original) +++ trunk/reactos/dll/win32/shell32/recyclebin.c Wed Oct 31 12:10:20 2007 @@ -273,7 +273,7 @@ { RecycleBin *This = (RecycleBin *)iface; IEnumIDList *list; - static const WCHAR szDrive = L'C'; + static LPCWSTR szDrive = L"C:\\"; TRACE("(%p, %p, %x, %p)\n", This, hwnd, (unsigned int)grfFlags, ppenumIDList); Modified: trunk/reactos/lib/recyclebin/recyclebin.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin.…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin.c (original) +++ trunk/reactos/lib/recyclebin/recyclebin.c Wed Oct 31 12:10:20 2007 @@ -141,16 +141,39 @@ BOOL WINAPI EnumerateRecycleBinA( - IN CHAR driveLetter, + IN LPCSTR pszRoot OPTIONAL, IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PVOID Context OPTIONAL) { - return EnumerateRecycleBinW((WCHAR)driveLetter, pFnCallback, Context); + int len; + LPWSTR szRootW = NULL; + BOOL ret = FALSE; + + if (pszRoot) + { + len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0); + if (len == 0) + goto cleanup; + szRootW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!szRootW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + if (MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, szRootW, len) == 0) + goto cleanup; + } + + ret = EnumerateRecycleBinW(szRootW, pFnCallback, Context); + +cleanup: + HeapFree(GetProcessHeap(), 0, szRootW); + return ret; } BOOL WINAPI EnumerateRecycleBinW( - IN WCHAR driveLetter, + IN LPCWSTR pszRoot OPTIONAL, IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PVOID Context OPTIONAL) { Modified: trunk/reactos/lib/recyclebin/recyclebin.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin.…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin.h (original) +++ trunk/reactos/lib/recyclebin/recyclebin.h Wed Oct 31 12:10:20 2007 @@ -54,10 +54,10 @@ BOOL WINAPI EmptyRecycleBinA( - IN LPCSTR pszRoot); + IN LPCSTR pszRoot OPTIONAL); BOOL WINAPI EmptyRecycleBinW( - IN LPCWSTR pszRoot); + IN LPCWSTR pszRoot OPTIONAL); #ifdef UNICODE #define EmptyRecycleBin EmptyRecycleBinW #else @@ -66,12 +66,12 @@ BOOL WINAPI EnumerateRecycleBinA( - IN CHAR driveLetter, + IN LPCSTR pszRoot OPTIONAL, IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PVOID Context OPTIONAL); BOOL WINAPI EnumerateRecycleBinW( - IN WCHAR driveLetter, + IN LPCWSTR pszRoot OPTIONAL, IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PVOID Context OPTIONAL); #ifdef UNICODE
17 years, 1 month
1
0
0
0
[hpoussin] 30000: Change i8042prt to a PnP driver Support power keys Support ctrl+scroll+scroll on debug builds Add support for driver filters Take care of more registry settings A lot of other changes
by hpoussin@svn.reactos.org
Author: hpoussin Date: Wed Oct 31 11:58:04 2007 New Revision: 30000 URL:
http://svn.reactos.org/svn/reactos?rev=30000&view=rev
Log: Change i8042prt to a PnP driver Support power keys Support ctrl+scroll+scroll on debug builds Add support for driver filters Take care of more registry settings A lot of other changes Added: trunk/reactos/drivers/input/i8042prt/createclose.c (with props) trunk/reactos/drivers/input/i8042prt/misc.c (with props) trunk/reactos/drivers/input/i8042prt/pnp.c (with props) trunk/reactos/drivers/input/i8042prt/readwrite.c (with props) trunk/reactos/drivers/input/i8042prt/setup.c (with props) Modified: trunk/reactos/drivers/input/i8042prt/README.txt (contents, props changed) trunk/reactos/drivers/input/i8042prt/i8042prt.c (contents, props changed) trunk/reactos/drivers/input/i8042prt/i8042prt.h (contents, props changed) trunk/reactos/drivers/input/i8042prt/i8042prt.rbuild trunk/reactos/drivers/input/i8042prt/i8042prt.rc (contents, props changed) trunk/reactos/drivers/input/i8042prt/keyboard.c (contents, props changed) trunk/reactos/drivers/input/i8042prt/mouse.c (contents, props changed) trunk/reactos/drivers/input/i8042prt/ps2pp.c (contents, props changed) trunk/reactos/drivers/input/i8042prt/registry.c (contents, props changed) [This mail would be too long, it was shortened to contain the URLs only.] Modified: trunk/reactos/drivers/input/i8042prt/README.txt URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/REA…
Added: trunk/reactos/drivers/input/i8042prt/createclose.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/cre…
Modified: trunk/reactos/drivers/input/i8042prt/i8042prt.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/i80…
Modified: trunk/reactos/drivers/input/i8042prt/i8042prt.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/i80…
Modified: trunk/reactos/drivers/input/i8042prt/i8042prt.rbuild URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/i80…
Modified: trunk/reactos/drivers/input/i8042prt/i8042prt.rc URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/i80…
Modified: trunk/reactos/drivers/input/i8042prt/keyboard.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/key…
Added: trunk/reactos/drivers/input/i8042prt/misc.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/mis…
Modified: trunk/reactos/drivers/input/i8042prt/mouse.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/mou…
Added: trunk/reactos/drivers/input/i8042prt/pnp.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/pnp…
Modified: trunk/reactos/drivers/input/i8042prt/ps2pp.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/ps2…
Added: trunk/reactos/drivers/input/i8042prt/readwrite.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/rea…
Modified: trunk/reactos/drivers/input/i8042prt/registry.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/reg…
Added: trunk/reactos/drivers/input/i8042prt/setup.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/set…
17 years, 1 month
1
0
0
0
[hpoussin] 29999: Implement SHEmptyRecycleBinA/W Implement SHQueryRecycleBinA
by hpoussin@svn.reactos.org
Author: hpoussin Date: Wed Oct 31 11:57:48 2007 New Revision: 29999 URL:
http://svn.reactos.org/svn/reactos?rev=29999&view=rev
Log: Implement SHEmptyRecycleBinA/W Implement SHQueryRecycleBinA Modified: trunk/reactos/dll/win32/shell32/she_ocmenu.c trunk/reactos/dll/win32/shell32/shellord.c Modified: trunk/reactos/dll/win32/shell32/she_ocmenu.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/she_ocme…
============================================================================== --- trunk/reactos/dll/win32/shell32/she_ocmenu.c (original) +++ trunk/reactos/dll/win32/shell32/she_ocmenu.c Wed Oct 31 11:57:48 2007 @@ -38,6 +38,8 @@ #include "shellfolder.h" #include "shresdef.h" +WINE_DEFAULT_DEBUG_CHANNEL (shell); + const GUID CLSID_OpenWith = { 0x09799AFB, 0xAD67, 0x11d1, {0xAB,0xCD,0x00,0xC0,0x4F,0xC3,0x09,0x36} }; typedef struct Modified: trunk/reactos/dll/win32/shell32/shellord.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shellord…
============================================================================== --- trunk/reactos/dll/win32/shell32/shellord.c (original) +++ trunk/reactos/dll/win32/shell32/shellord.c Wed Oct 31 11:57:48 2007 @@ -45,6 +45,7 @@ #include "pidl.h" #include "shlwapi.h" #include "commdlg.h" +#include "recyclebin.h" WINE_DEFAULT_DEBUG_CHANNEL(shell); WINE_DECLARE_DEBUG_CHANNEL(pidl); @@ -1971,18 +1972,48 @@ HRESULT WINAPI SHEmptyRecycleBinA(HWND hwnd, LPCSTR pszRootPath, DWORD dwFlags) { - FIXME("%p, %s, 0x%08x - stub\n", hwnd, debugstr_a(pszRootPath), dwFlags); - + LPWSTR szRootPathW = NULL; + int len; + HRESULT hr; + + TRACE("%p, %s, 0x%08x\n", hwnd, debugstr_a(pszRootPath), dwFlags); + + if (pszRootPath) + { + len = MultiByteToWideChar(CP_ACP, 0, pszRootPath, -1, NULL, 0); + if (len == 0) + return HRESULT_FROM_WIN32(GetLastError()); + szRootPathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!szRootPathW) + return E_OUTOFMEMORY; + if (MultiByteToWideChar(CP_ACP, 0, pszRootPath, -1, szRootPathW, len) == 0) + { + HeapFree(GetProcessHeap(), 0, szRootPathW); + return HRESULT_FROM_WIN32(GetLastError()); + } + } + + hr = SHEmptyRecycleBinW(hwnd, szRootPathW, dwFlags); + HeapFree(GetProcessHeap(), 0, szRootPathW); + + return hr; +} + +HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags) +{ + BOOL ret; + + TRACE("%p, %s, 0x%08x\n", hwnd, debugstr_w(pszRootPath), dwFlags); + FIXME("0x%08x flags ignored\n", dwFlags); + + ret = EmptyRecycleBinW(pszRootPath); + if (!ret) + return HRESULT_FROM_WIN32(GetLastError()); + + /* FIXME: update icon? */ return S_OK; } -HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags) -{ - FIXME("%p, %s, 0x%08x - stub\n", hwnd, debugstr_w(pszRootPath), dwFlags); - - return S_OK; -} - DWORD WINAPI SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options) { FIXME("%p, 0x%08x, 0x%08x, 0x%08x - stub\n", hwnd, drive, fmtID, options); @@ -1992,7 +2023,36 @@ HRESULT WINAPI SHQueryRecycleBinA(LPCSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo) { - FIXME("%s, %p - stub\n", debugstr_a(pszRootPath), pSHQueryRBInfo); + LPWSTR szRootPathW = NULL; + int len; + HRESULT hr; + + TRACE("%s, %p\n", debugstr_a(pszRootPath), pSHQueryRBInfo); + + if (pszRootPath) + { + len = MultiByteToWideChar(CP_ACP, 0, pszRootPath, -1, NULL, 0); + if (len == 0) + return HRESULT_FROM_WIN32(GetLastError()); + szRootPathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!szRootPathW) + return E_OUTOFMEMORY; + if (MultiByteToWideChar(CP_ACP, 0, pszRootPath, -1, szRootPathW, len) == 0) + { + HeapFree(GetProcessHeap(), 0, szRootPathW); + return HRESULT_FROM_WIN32(GetLastError()); + } + } + + hr = SHQueryRecycleBinW(szRootPathW, pSHQueryRBInfo); + HeapFree(GetProcessHeap(), 0, szRootPathW); + + return hr; +} + +HRESULT WINAPI SHQueryRecycleBinW(LPCWSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo) +{ + FIXME("%s, %p - stub\n", debugstr_w(pszRootPath), pSHQueryRBInfo); pSHQueryRBInfo->i64Size = 0; pSHQueryRBInfo->i64NumItems = 0; @@ -2000,22 +2060,12 @@ return S_OK; } -HRESULT WINAPI SHQueryRecycleBinW(LPCWSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo) -{ - FIXME("%s, %p - stub\n", debugstr_w(pszRootPath), pSHQueryRBInfo); - - pSHQueryRBInfo->i64Size = 0; - pSHQueryRBInfo->i64NumItems = 0; +/************************************************************************* + * SHSetLocalizedName (SHELL32.@) + */ +HRESULT WINAPI SHSetLocalizedName(LPWSTR pszPath, LPCWSTR pszResModule, int idsRes) +{ + FIXME("%p, %s, %d - stub\n", pszPath, debugstr_w(pszResModule), idsRes); return S_OK; } - -/************************************************************************* - * SHSetLocalizedName (SHELL32.@) - */ -HRESULT WINAPI SHSetLocalizedName(LPWSTR pszPath, LPCWSTR pszResModule, int idsRes) -{ - FIXME("%p, %s, %d - stub\n", pszPath, debugstr_w(pszResModule), idsRes); - - return S_OK; -}
17 years, 1 month
1
0
0
0
[hpoussin] 29998: Fix some bugs which were preventing enumeration of all deleted files Add a system-wide recycle bin, which federates all individual recycle bins Add a COM interface to the recycle bin library Use COM ref counting instead of a house-made system
by hpoussin@svn.reactos.org
Author: hpoussin Date: Wed Oct 31 11:57:35 2007 New Revision: 29998 URL:
http://svn.reactos.org/svn/reactos?rev=29998&view=rev
Log: Fix some bugs which were preventing enumeration of all deleted files Add a system-wide recycle bin, which federates all individual recycle bins Add a COM interface to the recycle bin library Use COM ref counting instead of a house-made system Added: trunk/reactos/lib/recyclebin/guid.c (with props) trunk/reactos/lib/recyclebin/recyclebin_generic.c (with props) trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c (with props) trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c (with props) Removed: trunk/reactos/lib/recyclebin/openclose.c trunk/reactos/lib/recyclebin/refcount.c Modified: trunk/reactos/lib/recyclebin/readme.txt trunk/reactos/lib/recyclebin/recyclebin.c trunk/reactos/lib/recyclebin/recyclebin.h trunk/reactos/lib/recyclebin/recyclebin.rbuild trunk/reactos/lib/recyclebin/recyclebin_private.h trunk/reactos/lib/recyclebin/recyclebin_v5.c trunk/reactos/lib/recyclebin/recyclebin_v5.h Added: trunk/reactos/lib/recyclebin/guid.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/guid.c?rev=…
============================================================================== --- trunk/reactos/lib/recyclebin/guid.c (added) +++ trunk/reactos/lib/recyclebin/guid.c Wed Oct 31 11:57:35 2007 @@ -1,0 +1,14 @@ +/* + * PROJECT: Recycle bin management + * LICENSE: GPL v2 - See COPYING in the top level directory + * FILE: lib/recyclebin/guid.c + * PURPOSE: Define GUID values + * PROGRAMMERS: Copyright 2007 Hervé Poussineau (hpoussin(a)reactos.org) + */ + +#define INITGUID +#include <initguid.h> +DEFINE_GUID(IID_IRecycleBin, 0x392ec73a, 0x45e9, 0x43de, 0xa8, 0x41, 0x4f, 0x32, 0x1a, 0xea, 0xa5, 0x80); +DEFINE_GUID(IID_IRecycleBinEnumList, 0x392ec73a, 0x45e9, 0x43de, 0xa8, 0x41, 0x4f, 0x32, 0x1a, 0xea, 0xa5, 0x81); +DEFINE_GUID(IID_IRecycleBinFile, 0x392ec73a, 0x45e9, 0x43de, 0xa8, 0x41, 0x4f, 0x32, 0x1a, 0xea, 0xa5, 0x82); +DEFINE_GUID(IID_IRecycleBin5, 0x392ec73a, 0x45e9, 0x43de, 0xa8, 0x41, 0x4f, 0x32, 0x1a, 0xea, 0xa5, 0x83); Propchange: trunk/reactos/lib/recyclebin/guid.c ------------------------------------------------------------------------------ svn:eol-style = native Removed: trunk/reactos/lib/recyclebin/openclose.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/openclose.c…
============================================================================== --- trunk/reactos/lib/recyclebin/openclose.c (original) +++ trunk/reactos/lib/recyclebin/openclose.c (removed) @@ -1,315 +1,0 @@ -/* - * PROJECT: Recycle bin management - * LICENSE: GPL v2 - See COPYING in the top level directory - * FILE: lib/recyclebin/openclose.c - * PURPOSE: Open/close recycle bins - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin(a)reactos.org) - */ - -#include "recyclebin_private.h" - -BOOL -IntCheckDeletedFileHandle( - IN HANDLE hDeletedFile) -{ - if (hDeletedFile == NULL || hDeletedFile == INVALID_HANDLE_VALUE) - return FALSE; - - if (((PDELETED_FILE_HANDLE)hDeletedFile)->magic != DELETEDFILE_MAGIC) - return FALSE; - - return TRUE; -} - -static BOOL -IntCloseRecycleBinHandle( - IN PREFCOUNT_DATA pData) -{ - PRECYCLE_BIN bin; - - bin = CONTAINING_RECORD(pData, RECYCLE_BIN, refCount); - if (!CloseHandle(bin->hInfo)) - return FALSE; - - RemoveEntryList(&bin->ListEntry); - HeapFree(GetProcessHeap(), 0, bin); - return TRUE; -} - -static BOOL -IntCreateEmptyRecycleBin( - IN PRECYCLE_BIN bin, - IN PSID OwnerSid OPTIONAL) -{ - LPWSTR BufferName = NULL; - LPWSTR Separator; /* Pointer into BufferName buffer */ - LPWSTR FileName; /* Pointer into BufferName buffer */ - LPCSTR DesktopIniContents = "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n"; - DWORD Info2Contents[] = { 5, 0, 0, 0x320, 0 }; - SIZE_T BytesToWrite, BytesWritten, Needed; - HANDLE hFile = INVALID_HANDLE_VALUE; - BOOL ret = FALSE; - - Needed = (wcslen(bin->Folder) + 1 + max(wcslen(RECYCLE_BIN_FILE_NAME), wcslen(L"desktop.ini")) + 1) * sizeof(WCHAR); - BufferName = HeapAlloc(GetProcessHeap(), 0, Needed); - if (!BufferName) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - - wcscpy(BufferName, bin->Folder); - Separator = wcsstr(&BufferName[3], L"\\"); - if (Separator) - *Separator = UNICODE_NULL; - ret = CreateDirectoryW(BufferName, NULL); - if (!ret && GetLastError() != ERROR_ALREADY_EXISTS) - goto cleanup; - SetFileAttributesW(BufferName, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); - if (Separator) - { - *Separator = L'\\'; - ret = CreateDirectoryW(BufferName, NULL); - if (!ret && GetLastError() != ERROR_ALREADY_EXISTS) - goto cleanup; - } - - if (OwnerSid) - { - //DWORD rc; - - /* Add ACL to allow only user/SYSTEM to open it */ - /* FIXME: rc = SetNamedSecurityInfo( - BufferName, - SE_FILE_OBJECT, - ???, - OwnerSid, - NULL, - ???, - ???); - if (rc != ERROR_SUCCESS) - { - SetLastError(rc); - goto cleanup; - } - */ - } - - wcscat(BufferName, L"\\"); - FileName = &BufferName[wcslen(BufferName)]; - - /* Create desktop.ini */ - wcscpy(FileName, L"desktop.ini"); - hFile = CreateFileW(BufferName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, NULL); - if (hFile == INVALID_HANDLE_VALUE) - goto cleanup; - BytesToWrite = strlen(DesktopIniContents); - ret = WriteFile(hFile, DesktopIniContents, (DWORD)BytesToWrite, &BytesWritten, NULL); - if (!ret) - goto cleanup; - if (BytesWritten != BytesToWrite) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - CloseHandle(hFile); - hFile = INVALID_HANDLE_VALUE; - - /* Create empty INFO2 file */ - wcscpy(FileName, RECYCLE_BIN_FILE_NAME); - hFile = CreateFileW(BufferName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL); - if (hFile == INVALID_HANDLE_VALUE) - goto cleanup; - BytesToWrite = sizeof(Info2Contents); - ret = WriteFile(hFile, Info2Contents, (DWORD)BytesToWrite, &BytesWritten, NULL); - if (!ret) - goto cleanup; - if (BytesWritten != BytesToWrite) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - - bin->hInfo = hFile; - ret = TRUE; - -cleanup: - HeapFree(GetProcessHeap(), 0, BufferName); - if (!ret) - { - if (hFile != INVALID_HANDLE_VALUE) - CloseHandle(hFile); - } - return ret; -} - -PRECYCLE_BIN -IntReferenceRecycleBin( - IN WCHAR driveLetter) -{ - PLIST_ENTRY ListEntry; - PRECYCLE_BIN bin = NULL, ret = NULL; - WCHAR RootPath[4]; - DWORD FileSystemFlags; - LPCWSTR RecycleBinDirectory; - HANDLE tokenHandle = INVALID_HANDLE_VALUE; - PTOKEN_USER TokenUserInfo = NULL; - LPWSTR StringSid = NULL; - SIZE_T Needed, DirectoryLength; - INFO2_HEADER Header; - BOOL AlreadyCreated = FALSE; - DWORD bytesRead; - - static LIST_ENTRY ListHead; - static BOOL ListInitialized = FALSE; - - if (!ListInitialized) - { - InitializeListHead(&ListHead); - ListInitialized = TRUE; - } - - /* Search if the recycle bin has already been opened */ - driveLetter = (WCHAR)toupper(driveLetter); - ListEntry = ListHead.Flink; - while (ListEntry != &ListHead) - { - bin = CONTAINING_RECORD(ListEntry, RECYCLE_BIN, ListEntry); - if (bin->Folder[0] == driveLetter) - { - ReferenceHandle(&bin->refCount); - return bin; - } - ListEntry = ListEntry->Flink; - } - bin = NULL; - - /* We need to create a new recycle bin */ - - /* Get information about file system */ - wsprintfW(RootPath, L"%c:\\", driveLetter); - if (!GetVolumeInformationW( - RootPath, - NULL, - 0, - NULL, - NULL, - &FileSystemFlags, - NULL, - 0)) - { - goto cleanup; - } - if (!(FileSystemFlags & FILE_PERSISTENT_ACLS)) - RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITHOUT_ACL; - else - { - RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITH_ACL; - - /* Get user SID */ - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle)) - goto cleanup; - if (GetTokenInformation(tokenHandle, TokenUser, NULL, 0, &Needed)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - goto cleanup; - TokenUserInfo = HeapAlloc(GetProcessHeap(), 0, Needed); - if (!TokenUserInfo) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - if (!GetTokenInformation(tokenHandle, TokenUser, TokenUserInfo, (DWORD)Needed, &Needed)) - goto cleanup; - if (!ConvertSidToStringSidW(TokenUserInfo->User.Sid, &StringSid)) - goto cleanup; - } - - /* Create RECYCLEBIN structure */ -openfile: - DirectoryLength = 3 + wcslen(RecycleBinDirectory) + 1; - if (StringSid) - DirectoryLength += wcslen(StringSid) + 1; - Needed = FIELD_OFFSET(RECYCLE_BIN, Folder) + (2 * DirectoryLength + 2 + wcslen(RECYCLE_BIN_FILE_NAME))* sizeof(WCHAR); - bin = HeapAlloc(GetProcessHeap(), 0, Needed); - if (!bin) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - memset(bin, 0, Needed); - InitializeHandle(&bin->refCount, IntCloseRecycleBinHandle); - bin->magic = RECYCLEBIN_MAGIC; - bin->hInfo = INVALID_HANDLE_VALUE; - bin->InfoFile = &bin->Folder[DirectoryLength]; - bin->Folder[0] = driveLetter; - bin->Folder[1] = '\0'; - wcscat(bin->Folder, L":\\"); - wcscat(bin->Folder, RecycleBinDirectory); - if (StringSid) - { - wcscat(bin->Folder, L"\\"); - wcscat(bin->Folder, StringSid); - } - wcscpy(bin->InfoFile, bin->Folder); - wcscat(bin->InfoFile, L"\\"); - wcscat(bin->InfoFile, RECYCLE_BIN_FILE_NAME); - InsertTailList(&ListHead, &bin->ListEntry); - - /* Open info file */ - bin->hInfo = CreateFileW(bin->InfoFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - if (bin->hInfo == INVALID_HANDLE_VALUE) - { - if (GetLastError() == ERROR_PATH_NOT_FOUND || GetLastError() == ERROR_FILE_NOT_FOUND) - { - if (!IntCreateEmptyRecycleBin(bin, TokenUserInfo ? TokenUserInfo->User.Sid : NULL)) - goto cleanup; - AlreadyCreated = TRUE; - } - } - if (bin->hInfo == INVALID_HANDLE_VALUE) - goto cleanup; - - if (SetFilePointer(bin->hInfo, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!ReadFile(bin->hInfo, &Header, sizeof(INFO2_HEADER), &bytesRead, NULL)) - goto cleanup; - if (bytesRead != sizeof(INFO2_HEADER) && !AlreadyCreated) - { - /* Create a new file */ - if (!DereferenceHandle(&bin->refCount)) - goto cleanup; - if (!DeleteFileW(bin->InfoFile)) - goto cleanup; - goto openfile; - } - switch (Header.dwVersion) - { - case 5: - InitializeCallbacks5(&bin->Callbacks); - break; - default: - /* Unknown recycle bin version */ - SetLastError(ERROR_NOT_SUPPORTED); - goto cleanup; - } - - ret = bin; - -cleanup: - if (tokenHandle != INVALID_HANDLE_VALUE) - CloseHandle(tokenHandle); - HeapFree(GetProcessHeap(), 0, TokenUserInfo); - if (StringSid) - LocalFree(StringSid); - if (!ret) - { - if (bin && bin->hInfo != INVALID_HANDLE_VALUE) - DereferenceHandle(&bin->refCount); - HeapFree(GetProcessHeap(), 0, bin); - } - return ret; -} Modified: trunk/reactos/lib/recyclebin/readme.txt URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/readme.txt?…
============================================================================== --- trunk/reactos/lib/recyclebin/readme.txt (original) +++ trunk/reactos/lib/recyclebin/readme.txt Wed Oct 31 11:57:35 2007 @@ -1,6 +1,5 @@ This library deals with Recycle bin. It is aimed to be compatible with Windows 2000/XP/2003 (at least) on FAT or NTFS volumes. - TODO - Empty a recycle bin containing directories (v5) @@ -9,7 +8,6 @@ - Make the library thread-safe 3 levels -- 1: recyclebin.c: Public interface -- 2a: openclose.c: Open/close recycle bins -- 2b: refcount.c: Do reference counting on objects -- 3: recyclebin_v5.c: Deals with recycle bins of Windows 2000/XP/2003 +- 1: recyclebin.c : Public C interface +- 2: recyclebin_generic.c : 'System-wide' recycle bin, which knows no implementation detail +- 3: recyclebin_v5.c : Deals with recycle bins of Windows 2000/XP/2003 Modified: trunk/reactos/lib/recyclebin/recyclebin.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin.…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin.c (original) +++ trunk/reactos/lib/recyclebin/recyclebin.c Wed Oct 31 11:57:35 2007 @@ -1,35 +1,30 @@ /* * PROJECT: Recycle bin management * LICENSE: GPL v2 - See COPYING in the top level directory - * FILE: lib/recyclebin/openclose.c + * FILE: lib/recyclebin/recyclebin.c * PURPOSE: Public interface - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin(a)reactos.org) + * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin(a)reactos.org) */ +#define COBJMACROS #include "recyclebin_private.h" - -typedef struct _ENUMERATE_RECYCLE_BIN_CONTEXT -{ - PRECYCLE_BIN bin; - PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback; - PVOID Context; -} ENUMERATE_RECYCLE_BIN_CONTEXT, *PENUMERATE_RECYCLE_BIN_CONTEXT; +#include <stdio.h> BOOL WINAPI CloseRecycleBinHandle( IN HANDLE hDeletedFile) { - BOOL ret = FALSE; - - if (!IntCheckDeletedFileHandle(hDeletedFile)) - SetLastError(ERROR_INVALID_HANDLE); - else - { - PDELETED_FILE_HANDLE file = (PDELETED_FILE_HANDLE)hDeletedFile; - ret = DereferenceHandle(&file->refCount); - } - - return ret; + IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; + HRESULT hr; + + hr = IRecycleBinFile_Release(rbf); + if (SUCCEEDED(hr)) + return TRUE; + if (HRESULT_FACILITY(hr) == FACILITY_WIN32) + SetLastError(HRESULT_CODE(hr)); + else + SetLastError(ERROR_GEN_FAILURE); + return FALSE; } BOOL WINAPI @@ -70,89 +65,78 @@ DeleteFileToRecycleBinW( IN LPCWSTR FileName) { - LPWSTR FullFileName = NULL; - DWORD dwBufferLength = 0; - LPWSTR lpFilePart; - DWORD len; - PRECYCLE_BIN bin = NULL; + IRecycleBin *prb; + HRESULT hr; + + hr = GetDefaultRecycleBin(NULL, &prb); + if (!SUCCEEDED(hr)) + goto cleanup; + + hr = IRecycleBin_DeleteFile(prb, FileName); + IRecycleBin_Release(prb); + +cleanup: + if (SUCCEEDED(hr)) + return TRUE; + if (HRESULT_FACILITY(hr) == FACILITY_WIN32) + SetLastError(HRESULT_CODE(hr)); + else + SetLastError(ERROR_GEN_FAILURE); + return FALSE; +} + +BOOL WINAPI +EmptyRecycleBinA( + IN LPCSTR pszRoot OPTIONAL) +{ + int len; + LPWSTR szRootW = NULL; BOOL ret = FALSE; - /* Check parameters */ - if (FileName == NULL) - { - SetLastError(ERROR_INVALID_PARAMETER); - goto cleanup; - } - - /* Get full file name */ - while (TRUE) - { - len = GetFullPathNameW(FileName, dwBufferLength, FullFileName, &lpFilePart); + if (pszRoot) + { + len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0); if (len == 0) goto cleanup; - else if (len < dwBufferLength) - break; - HeapFree(GetProcessHeap(), 0, FullFileName); - dwBufferLength = len; - FullFileName = HeapAlloc(GetProcessHeap(), 0, dwBufferLength * sizeof(WCHAR)); - if (!FullFileName) + szRootW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!szRootW) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } - } - - if (!lpFilePart || dwBufferLength < 2 || FullFileName[1] != ':') - { - /* Only a directory name, or not a local file */ - SetLastError(ERROR_INVALID_NAME); - } - - /* Open recycle bin */ - bin = IntReferenceRecycleBin(FullFileName[0]); - if (!bin) - goto cleanup; - - if (bin->Callbacks.DeleteFile) - ret = bin->Callbacks.DeleteFile(bin, FullFileName, lpFilePart); - else - SetLastError(ERROR_NOT_SUPPORTED); - -cleanup: - HeapFree(GetProcessHeap(), 0, FullFileName); - if (bin) - DereferenceHandle(&bin->refCount); + if (MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, szRootW, len) == 0) + goto cleanup; + } + + ret = EmptyRecycleBinW(szRootW); + +cleanup: + HeapFree(GetProcessHeap(), 0, szRootW); return ret; } BOOL WINAPI -EmptyRecycleBinA( - IN CHAR driveLetter) -{ - return EmptyRecycleBinW((WCHAR)driveLetter); -} - -BOOL WINAPI EmptyRecycleBinW( - IN WCHAR driveLetter) -{ - PRECYCLE_BIN bin = NULL; - BOOL ret = FALSE; - - /* Open recycle bin */ - bin = IntReferenceRecycleBin(driveLetter); - if (!bin) - goto cleanup; - - if (bin->Callbacks.EmptyRecycleBin) - ret = bin->Callbacks.EmptyRecycleBin(&bin); - else - SetLastError(ERROR_NOT_SUPPORTED); - -cleanup: - if (bin) - DereferenceHandle(&bin->refCount); - return ret; + IN LPCWSTR pszRoot OPTIONAL) +{ + IRecycleBin *prb; + HRESULT hr; + + hr = GetDefaultRecycleBin(pszRoot, &prb); + if (!SUCCEEDED(hr)) + goto cleanup; + + hr = IRecycleBin_EmptyRecycleBin(prb); + IRecycleBin_Release(prb); + +cleanup: + if (SUCCEEDED(hr)) + return TRUE; + if (HRESULT_FACILITY(hr) == FACILITY_WIN32) + SetLastError(HRESULT_CODE(hr)); + else + SetLastError(ERROR_GEN_FAILURE); + return FALSE; } BOOL WINAPI @@ -164,92 +148,54 @@ return EnumerateRecycleBinW((WCHAR)driveLetter, pFnCallback, Context); } -static BOOL -IntCloseDeletedFileHandle( - IN PREFCOUNT_DATA pData) -{ - PDELETED_FILE_HANDLE file; - - file = CONTAINING_RECORD(pData, DELETED_FILE_HANDLE, refCount); - if (!DereferenceHandle(&file->bin->refCount)) - return FALSE; - - file->magic = 0; - HeapFree(GetProcessHeap(), 0, file); - return TRUE; -} - -static BOOL -IntEnumerateRecycleBinCallback( - IN PVOID Context, - IN HANDLE hDeletedFile) -{ - PENUMERATE_RECYCLE_BIN_CONTEXT CallbackContext = (PENUMERATE_RECYCLE_BIN_CONTEXT)Context; - PDELETED_FILE_HANDLE DeletedFileHandle = NULL; - BOOL ret = FALSE; - - DeletedFileHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(DELETED_FILE_HANDLE)); - if (!DeletedFileHandle) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - - ReferenceHandle(&CallbackContext->bin->refCount); - InitializeHandle(&DeletedFileHandle->refCount, IntCloseDeletedFileHandle); - DeletedFileHandle->magic = DELETEDFILE_MAGIC; - DeletedFileHandle->bin = CallbackContext->bin; - DeletedFileHandle->hDeletedFile = hDeletedFile; - - ret = CallbackContext->pFnCallback(CallbackContext->Context, DeletedFileHandle); - -cleanup: - if (!ret) - { - if (DeletedFileHandle) - DereferenceHandle(&DeletedFileHandle->refCount); - } - return ret; -} - BOOL WINAPI EnumerateRecycleBinW( IN WCHAR driveLetter, IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PVOID Context OPTIONAL) { - PRECYCLE_BIN bin = NULL; - BOOL ret = FALSE; - - /* Check parameters */ - if (pFnCallback == NULL) - { - SetLastError(ERROR_INVALID_PARAMETER); - goto cleanup; - } - - /* Open recycle bin */ - bin = IntReferenceRecycleBin(driveLetter); - if (!bin) - goto cleanup; - - if (bin->Callbacks.EnumerateFiles) - { - ENUMERATE_RECYCLE_BIN_CONTEXT CallbackContext; - - CallbackContext.bin = bin; - CallbackContext.pFnCallback = pFnCallback; - CallbackContext.Context = Context; - - ret = bin->Callbacks.EnumerateFiles(bin, IntEnumerateRecycleBinCallback, &CallbackContext); - } - else - SetLastError(ERROR_NOT_SUPPORTED); - -cleanup: - if (bin) - DereferenceHandle(&bin->refCount); - return ret; + IRecycleBin *prb = NULL; + IRecycleBinEnumList *prbel = NULL; + IRecycleBinFile *prbf; + HRESULT hr; + + hr = GetDefaultRecycleBin(NULL, &prb); + if (!SUCCEEDED(hr)) + goto cleanup; + + hr = IRecycleBin_EnumObjects(prb, &prbel); + if (!SUCCEEDED(hr)) + goto cleanup; + while (TRUE) + { + hr = IRecycleBinEnumList_Next(prbel, 1, &prbf, NULL); + if (hr == S_FALSE) + { + hr = S_OK; + goto cleanup; + } + else if (!SUCCEEDED(hr)) + goto cleanup; + if (!pFnCallback(Context, (HANDLE)prbf)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + IRecycleBinFile_Release(prbf); + } + +cleanup: + if (prb) + IRecycleBin_Release(prb); + if (prbel) + IRecycleBinEnumList_Release(prb); + if (SUCCEEDED(hr)) + return TRUE; + if (HRESULT_FACILITY(hr) == FACILITY_WIN32) + SetLastError(HRESULT_CODE(hr)); + else + SetLastError(ERROR_GEN_FAILURE); + return FALSE; } BOOL WINAPI @@ -284,7 +230,7 @@ if (FileDetails) { - memcpy(FileDetails, FileDetailsW, FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)); + CopyMemory(FileDetails, FileDetailsW, FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)); if (0 == WideCharToMultiByte(CP_ACP, 0, FileDetailsW->FileName, -1, FileDetails->FileName, BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName), NULL, NULL)) goto cleanup; } @@ -302,38 +248,92 @@ IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL, OUT LPDWORD RequiredSize OPTIONAL) { - BOOL ret = FALSE; - - if (!IntCheckDeletedFileHandle(hDeletedFile)) - SetLastError(ERROR_INVALID_HANDLE); - else - { - PDELETED_FILE_HANDLE DeletedFile = (PDELETED_FILE_HANDLE)hDeletedFile; - if (DeletedFile->bin->Callbacks.GetDetails) - ret = DeletedFile->bin->Callbacks.GetDetails(DeletedFile->bin, DeletedFile->hDeletedFile, BufferSize, FileDetails, RequiredSize); - else - SetLastError(ERROR_NOT_SUPPORTED); - } - - return ret; + IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; + HRESULT hr; + SIZE_T NameSize, Needed; + + hr = IRecycleBinFile_GetFileName(rbf, 0, NULL, &NameSize); + if (!SUCCEEDED(hr)) + goto cleanup; + Needed = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName) + NameSize; + if (RequiredSize) + *RequiredSize = (DWORD)Needed; + if (Needed > BufferSize) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + goto cleanup; + } + hr = IRecycleBinFile_GetFileName(rbf, NameSize, FileDetails->FileName, NULL); + if (!SUCCEEDED(hr)) + goto cleanup; + hr = IRecycleBinFile_GetLastModificationTime(rbf, &FileDetails->LastModification); + if (!SUCCEEDED(hr)) + goto cleanup; + hr = IRecycleBinFile_GetDeletionTime(rbf, &FileDetails->DeletionTime); + if (!SUCCEEDED(hr)) + goto cleanup; + hr = IRecycleBinFile_GetFileSize(rbf, &FileDetails->FileSize); + if (!SUCCEEDED(hr)) + goto cleanup; + hr = IRecycleBinFile_GetPhysicalFileSize(rbf, &FileDetails->PhysicalFileSize); + if (!SUCCEEDED(hr)) + goto cleanup; + hr = IRecycleBinFile_GetAttributes(rbf, &FileDetails->Attributes); + if (!SUCCEEDED(hr)) + goto cleanup; + +cleanup: + if (SUCCEEDED(hr)) + return TRUE; + if (HRESULT_FACILITY(hr) == FACILITY_WIN32) + SetLastError(HRESULT_CODE(hr)); + else + SetLastError(ERROR_GEN_FAILURE); + return FALSE; } BOOL WINAPI RestoreFile( IN HANDLE hDeletedFile) { - BOOL ret = FALSE; - - if (!IntCheckDeletedFileHandle(hDeletedFile)) - SetLastError(ERROR_INVALID_HANDLE); - else - { - PDELETED_FILE_HANDLE DeletedFile = (PDELETED_FILE_HANDLE)hDeletedFile; - if (DeletedFile->bin->Callbacks.RestoreFile) - ret = DeletedFile->bin->Callbacks.RestoreFile(DeletedFile->bin, DeletedFile->hDeletedFile); - else - SetLastError(ERROR_NOT_SUPPORTED); - } - - return ret; -} + IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; + HRESULT hr; + + hr = IRecycleBinFile_Restore(rbf); + if (SUCCEEDED(hr)) + return TRUE; + if (HRESULT_FACILITY(hr) == FACILITY_WIN32) + SetLastError(HRESULT_CODE(hr)); + else + SetLastError(ERROR_GEN_FAILURE); + return FALSE; +} + +HRESULT WINAPI +GetDefaultRecycleBin( + IN LPCWSTR pszVolume OPTIONAL, + OUT IRecycleBin **pprb) +{ + IUnknown *pUnk; + HRESULT hr; + + if (!pprb) + return E_POINTER; + + if (!pszVolume) + hr = RecycleBinGeneric_Constructor(&pUnk); + else + { + /* FIXME: do a better validation! */ + if (wcslen(pszVolume) != 3 || pszVolume[1] != ':' || pszVolume[2] != '\\') + return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); + + /* For now, only support this type of recycle bins... */ + hr = RecycleBin5_Constructor(pszVolume, &pUnk); + } + if (!SUCCEEDED(hr)) + return hr; + hr = IUnknown_QueryInterface(pUnk, &IID_IRecycleBin, (void **)pprb); + IUnknown_Release(pUnk); + return hr; +} Modified: trunk/reactos/lib/recyclebin/recyclebin.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin.…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin.h (original) +++ trunk/reactos/lib/recyclebin/recyclebin.h Wed Oct 31 11:57:35 2007 @@ -54,10 +54,10 @@ BOOL WINAPI EmptyRecycleBinA( - IN CHAR driveLetter); + IN LPCSTR pszRoot); BOOL WINAPI EmptyRecycleBinW( - IN WCHAR driveLetter); + IN LPCWSTR pszRoot); #ifdef UNICODE #define EmptyRecycleBin EmptyRecycleBinW #else @@ -102,6 +102,190 @@ RestoreFile( IN HANDLE hDeletedFile); +/* COM interface */ + +typedef interface IRecycleBinFile IRecycleBinFile; +EXTERN_C const IID IID_IRecycleBinFile; + +typedef struct IRecycleBinFileVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IN IRecycleBinFile *This, + IN REFIID riid, + OUT void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IN IRecycleBinFile *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IN IRecycleBinFile *This); + + HRESULT (STDMETHODCALLTYPE *GetLastModificationTime)( + IN IRecycleBinFile *This, + OUT FILETIME *pLastModificationTime); + + HRESULT (STDMETHODCALLTYPE *GetDeletionTime)( + IN IRecycleBinFile *This, + OUT FILETIME *pDeletionTime); + + HRESULT (STDMETHODCALLTYPE *GetFileSize)( + IN IRecycleBinFile *This, + OUT ULARGE_INTEGER *pFileSize); + + HRESULT (STDMETHODCALLTYPE *GetPhysicalFileSize)( + IN IRecycleBinFile *This, + OUT ULARGE_INTEGER *pPhysicalFileSize); + + HRESULT (STDMETHODCALLTYPE *GetAttributes)( + IN IRecycleBinFile *This, + OUT DWORD *pAttributes); + + HRESULT (STDMETHODCALLTYPE *GetFileName)( + IN IRecycleBinFile *This, + IN SIZE_T BufferSize, + IN OUT LPWSTR Buffer, + OUT SIZE_T *RequiredSize); + + HRESULT (STDMETHODCALLTYPE *Delete)( + IN IRecycleBinFile *This); + + HRESULT (STDMETHODCALLTYPE *Restore)( + IN IRecycleBinFile *This); +} IRecycleBinFileVtbl; + +interface IRecycleBinFile +{ + CONST_VTBL struct IRecycleBinFileVtbl *lpVtbl; +}; + +#ifdef COBJMACROS +#define IRecycleBinFile_QueryInterface(This, riid, ppvObject) \ + (This)->lpVtbl->QueryInterface(This, riid, ppvObject) +#define IRecycleBinFile_AddRef(This) \ + (This)->lpVtbl->AddRef(This) +#define IRecycleBinFile_Release(This) \ + (This)->lpVtbl->Release(This) +#define IRecycleBinFile_GetLastModificationTime(This, pLastModificationTime) \ + (This)->lpVtbl->GetLastModificationTime(This, pLastModificationTime) +#define IRecycleBinFile_GetDeletionTime(This, pDeletionTime) \ + (This)->lpVtbl->GetDeletionTime(This, pDeletionTime) +#define IRecycleBinFile_GetFileSize(This, pFileSize) \ + (This)->lpVtbl->GetFileSize(This, pFileSize) +#define IRecycleBinFile_GetPhysicalFileSize(This, pPhysicalFileSize) \ + (This)->lpVtbl->GetPhysicalFileSize(This, pPhysicalFileSize) +#define IRecycleBinFile_GetAttributes(This, pAttributes) \ + (This)->lpVtbl->GetAttributes(This, pAttributes) +#define IRecycleBinFile_GetFileName(This, BufferSize, Buffer, RequiredSize) \ + (This)->lpVtbl->GetFileName(This, BufferSize, Buffer, RequiredSize) +#define IRecycleBinFile_Delete(This) \ + (This)->lpVtbl->Delete(This) +#define IRecycleBinFile_Restore(This) \ + (This)->lpVtbl->Restore(This) +#endif + +typedef interface IRecycleBinEnumList IRecycleBinEnumList; +EXTERN_C const IID IID_IRecycleBinEnumList; + +typedef struct IRecycleBinEnumListVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IN IRecycleBinEnumList *This, + IN REFIID riid, + OUT void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IN IRecycleBinEnumList *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IN IRecycleBinEnumList *This); + + HRESULT (STDMETHODCALLTYPE *Next)( + IN IRecycleBinEnumList *This, + IN DWORD celt, + IN OUT IRecycleBinFile **rgelt, + OUT DWORD *pceltFetched); + + HRESULT (STDMETHODCALLTYPE *Skip)( + IN IRecycleBinEnumList *This, + IN DWORD celt); + + HRESULT (STDMETHODCALLTYPE *Reset)( + IN IRecycleBinEnumList *This); +} IRecycleBinEnumListVtbl; + +interface IRecycleBinEnumList +{ + CONST_VTBL struct IRecycleBinEnumListVtbl *lpVtbl; +}; + +#ifdef COBJMACROS +#define IRecycleBinEnumList_QueryInterface(This, riid, ppvObject) \ + (This)->lpVtbl->QueryInterface(This, riid, ppvObject) +#define IRecycleBinEnumList_AddRef(This) \ + (This)->lpVtbl->AddRef(This) +#define IRecycleBinEnumList_Release(This) \ + (This)->lpVtbl->Release(This) +#define IRecycleBinEnumList_Next(This, celt, rgelt, pceltFetched) \ + (This)->lpVtbl->Next(This, celt, rgelt, pceltFetched) +#define IRecycleBinEnumList_Skip(This, celt) \ + (This)->lpVtbl->Skip(This, celt) +#define IRecycleBinEnumList_Reset(This) \ + (This)->lpVtbl->Reset(This) +#endif + +typedef interface IRecycleBin IRecycleBin; +EXTERN_C const IID IID_IRecycleBin; + +typedef struct IRecycleBinVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IN IRecycleBin *This, + IN REFIID riid, + OUT void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IN IRecycleBin *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IN IRecycleBin *This); + + HRESULT (STDMETHODCALLTYPE *DeleteFile)( + IN IRecycleBin *This, + IN LPCWSTR szFileName); + + HRESULT (STDMETHODCALLTYPE *EmptyRecycleBin)( + IN IRecycleBin *This); + + HRESULT (STDMETHODCALLTYPE *EnumObjects)( + IN IRecycleBin *This, + OUT IRecycleBinEnumList **ppEnumList); +} IRecycleBinVtbl; + +interface IRecycleBin +{ + CONST_VTBL struct IRecycleBinVtbl *lpVtbl; +}; + +#ifdef COBJMACROS +#define IRecycleBin_QueryInterface(This, riid, ppvObject) \ + (This)->lpVtbl->QueryInterface(This, riid, ppvObject) +#define IRecycleBin_AddRef(This) \ + (This)->lpVtbl->AddRef(This) +#define IRecycleBin_Release(This) \ + (This)->lpVtbl->Release(This) +#define IRecycleBin_DeleteFile(This, szFileName) \ + (This)->lpVtbl->DeleteFile(This, szFileName) +#define IRecycleBin_EmptyRecycleBin(This) \ + (This)->lpVtbl->EmptyRecycleBin(This) +#define IRecycleBin_EnumObjects(This, ppEnumList) \ + (This)->lpVtbl->EnumObjects(This, ppEnumList) +#endif + +HRESULT WINAPI +GetDefaultRecycleBin( + IN LPCWSTR pszVolume OPTIONAL, + OUT IRecycleBin **pprb); + #ifdef __cplusplus } #endif Modified: trunk/reactos/lib/recyclebin/recyclebin.rbuild URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin.…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin.rbuild (original) +++ trunk/reactos/lib/recyclebin/recyclebin.rbuild Wed Oct 31 11:57:35 2007 @@ -1,9 +1,10 @@ <?xml version="1.0"?> <!DOCTYPE module SYSTEM "../../tools/rbuild/project.dtd"> <module name="recyclebin" type="staticlibrary"> - <define name="__USE_W32API" /> - <file>openclose.c</file> + <file>guid.c</file> <file>recyclebin.c</file> + <file>recyclebin_generic.c</file> + <file>recyclebin_generic_enumerator.c</file> <file>recyclebin_v5.c</file> - <file>refcount.c</file> + <file>recyclebin_v5_enumerator.c</file> </module> Added: trunk/reactos/lib/recyclebin/recyclebin_generic.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin_generic.c (added) +++ trunk/reactos/lib/recyclebin/recyclebin_generic.c Wed Oct 31 11:57:35 2007 @@ -1,0 +1,200 @@ +/* + * PROJECT: Recycle bin management + * LICENSE: GPL v2 - See COPYING in the top level directory + * FILE: lib/recyclebin/recyclebin_generic.c + * PURPOSE: Deals with a system-wide recycle bin + * PROGRAMMERS: Copyright 2007 Hervé Poussineau (hpoussin(a)reactos.org) + */ + +#define COBJMACROS +#include "recyclebin_private.h" +#include <stdio.h> + +struct RecycleBinGeneric +{ + ULONG ref; + IRecycleBin recycleBinImpl; +}; + +static HRESULT STDMETHODCALLTYPE +RecycleBinGenericVtbl_RecycleBin_QueryInterface( + IRecycleBin *This, + REFIID riid, + void **ppvObject) +{ + struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl); + + if (!ppvObject) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppvObject = &s->recycleBinImpl; + else if (IsEqualIID(riid, &IID_IRecycleBin)) + *ppvObject = &s->recycleBinImpl; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef(This); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE +RecycleBinGenericVtbl_RecycleBin_AddRef( + IRecycleBin *This) +{ + struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl); + ULONG refCount = InterlockedIncrement((PLONG)&s->ref); + return refCount; +} + +static ULONG STDMETHODCALLTYPE +RecycleBinGenericVtbl_RecycleBin_Release( + IRecycleBin *This) +{ + struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl); + ULONG refCount; + + if (!This) + return E_POINTER; + + refCount = InterlockedDecrement((PLONG)&s->ref); + + if (refCount == 0) + CoTaskMemFree(s); + + return refCount; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBinGenericVtbl_RecycleBin_DeleteFile( + IN IRecycleBin *This, + IN LPCWSTR szFileName) +{ + IRecycleBin *prb; + LPWSTR szFullName = NULL; + DWORD dwBufferLength = 0; + DWORD len; + WCHAR szVolume[MAX_PATH]; + HRESULT hr; + + /* Get full file name */ + while (TRUE) + { + len = GetFullPathNameW(szFileName, dwBufferLength, szFullName, NULL); + if (len == 0) + { + if (szFullName) + CoTaskMemFree(szFullName); + return HRESULT_FROM_WIN32(GetLastError()); + } + else if (len < dwBufferLength) + break; + if (szFullName) + CoTaskMemFree(szFullName); + dwBufferLength = len; + szFullName = CoTaskMemAlloc(dwBufferLength * sizeof(WCHAR)); + if (!szFullName) + return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + } + + /* Get associated volume path */ +#ifndef __REACTOS__ + if (!GetVolumePathNameW(szFullName, szVolume, MAX_PATH)) + { + CoTaskMemFree(szFullName); + return HRESULT_FROM_WIN32(GetLastError()); + } +#else + swprintf(szVolume, L"%c:\\", szFullName[0]); +#endif + + /* Skip namespace (if any) */ + if (szVolume[0] == '\\' + && szVolume[1] == '\\' + && (szVolume[2] == '.' || szVolume[2] == '?') + && szVolume[3] == '\\') + { + MoveMemory(szVolume, &szVolume[4], (MAX_PATH - 4) * sizeof(WCHAR)); + } + + hr = GetDefaultRecycleBin(szVolume, &prb); + if (!SUCCEEDED(hr)) + { + CoTaskMemFree(szFullName); + return hr; + } + + hr = IRecycleBin_DeleteFile(prb, szFullName); + CoTaskMemFree(szFullName); + IRecycleBin_Release(prb); + return hr; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBinGenericVtbl_RecycleBin_EmptyRecycleBin( + IN IRecycleBin *This) +{ + WCHAR szVolumeName[MAX_PATH]; + DWORD dwLogicalDrives, i; + IRecycleBin *prb; + HRESULT hr; + + dwLogicalDrives = GetLogicalDrives(); + if (dwLogicalDrives == 0) + return HRESULT_FROM_WIN32(GetLastError()); + + for (i = 0; i < 26; i++) + { + if (!(dwLogicalDrives & (1 << i))) + continue; + swprintf(szVolumeName, L"%c:\\", 'A' + i); + if (GetDriveTypeW(szVolumeName) != DRIVE_FIXED) + continue; + + hr = GetDefaultRecycleBin(szVolumeName, &prb); + if (!SUCCEEDED(hr)) + return hr; + + hr = IRecycleBin_EmptyRecycleBin(prb); + IRecycleBin_Release(prb); + } + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBinGenericVtbl_RecycleBin_EnumObjects( + IN IRecycleBin *This, + OUT IRecycleBinEnumList **ppEnumList) +{ + return RecycleBinGeneric_Enumerator_Constructor(ppEnumList); +} + +CONST_VTBL struct IRecycleBinVtbl RecycleBinGenericVtbl = +{ + RecycleBinGenericVtbl_RecycleBin_QueryInterface, + RecycleBinGenericVtbl_RecycleBin_AddRef, + RecycleBinGenericVtbl_RecycleBin_Release, + RecycleBinGenericVtbl_RecycleBin_DeleteFile, + RecycleBinGenericVtbl_RecycleBin_EmptyRecycleBin, + RecycleBinGenericVtbl_RecycleBin_EnumObjects, +}; + +HRESULT RecycleBinGeneric_Constructor(OUT IUnknown **ppUnknown) +{ + /* This RecycleBin implementation was introduced to be able to manage all + * drives at once, and instanciate the 'real' implementations when needed */ + struct RecycleBinGeneric *s; + + s = CoTaskMemAlloc(sizeof(struct RecycleBinGeneric)); + if (!s) + return E_OUTOFMEMORY; + s->ref = 1; + s->recycleBinImpl.lpVtbl = &RecycleBinGenericVtbl; + + *ppUnknown = (IUnknown *)&s->recycleBinImpl; + return S_OK; +} Propchange: trunk/reactos/lib/recyclebin/recyclebin_generic.c ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c (added) +++ trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c Wed Oct 31 11:57:35 2007 @@ -1,0 +1,221 @@ +/* + * PROJECT: Recycle bin management + * LICENSE: GPL v2 - See COPYING in the top level directory + * FILE: lib/recyclebin/recyclebin_generic_enumerator.c + * PURPOSE: Enumerates contents of all recycle bins + * PROGRAMMERS: Copyright 2007 Hervé Poussineau (hpoussin(a)reactos.org) + */ + +#define COBJMACROS +#include "recyclebin.h" +#include <stdio.h> + +struct RecycleBinGenericEnum +{ + ULONG ref; + IRecycleBinEnumList recycleBinEnumImpl; + IRecycleBinEnumList *current; + DWORD dwLogicalDrives; + SIZE_T skip; +}; + +static HRESULT STDMETHODCALLTYPE +RecycleBinGenericEnum_RecycleBinEnumList_QueryInterface( + IN IRecycleBinEnumList *This, + IN REFIID riid, + OUT void **ppvObject) +{ + struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl); + + if (!ppvObject) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppvObject = &s->recycleBinEnumImpl; + else if (IsEqualIID(riid, &IID_IRecycleBinEnumList)) + *ppvObject = &s->recycleBinEnumImpl; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef(This); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE +RecycleBinGenericEnum_RecycleBinEnumList_AddRef( + IN IRecycleBinEnumList *This) +{ + struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl); + ULONG refCount = InterlockedIncrement((PLONG)&s->ref); + return refCount; +} + +static ULONG STDMETHODCALLTYPE +RecycleBinGenericEnum_RecycleBinEnumList_Release( + IN IRecycleBinEnumList *This) +{ + struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl); + ULONG refCount; + + if (!This) + return E_POINTER; + + refCount = InterlockedDecrement((PLONG)&s->ref); + + if (refCount == 0) + { + if (s->current) + IRecycleBinEnumList_Release(s->current); + CoTaskMemFree(s); + } + + return refCount; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBinGenericEnum_RecycleBinEnumList_Next( + IN IRecycleBinEnumList *This, + IN DWORD celt, + IN OUT IRecycleBinFile **rgelt, + OUT DWORD *pceltFetched) +{ + struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl); + IRecycleBin *prb; + DWORD i; + DWORD fetched = 0, newFetched; + HRESULT hr; + + if (!rgelt) + return E_POINTER; + if (!pceltFetched && celt > 1) + return E_INVALIDARG; + + while (TRUE) + { + /* Get enumerator implementation */ + if (!s->current && s->dwLogicalDrives) + { + for (i = 0; i < 26; i++) + if (s->dwLogicalDrives & (1 << i)) + { + WCHAR szVolumeName[4]; + szVolumeName[0] = (WCHAR)('A' + i); + szVolumeName[1] = ':'; + szVolumeName[2] = '\\'; + szVolumeName[3] = UNICODE_NULL; + if (GetDriveTypeW(szVolumeName) != DRIVE_FIXED) + { + s->dwLogicalDrives &= ~(1 << i); + continue; + } + hr = GetDefaultRecycleBin(szVolumeName, &prb); + if (!SUCCEEDED(hr)) + return hr; + hr = IRecycleBin_EnumObjects(prb, &s->current); + IRecycleBin_Release(prb); + if (!SUCCEEDED(hr)) + return hr; + s->dwLogicalDrives &= ~(1 << i); + break; + } + } + if (!s->current) + { + /* Nothing more to enumerate */ + if (pceltFetched) + *pceltFetched = fetched; + return S_FALSE; + } + + /* Skip some elements */ + while (s->skip > 0) + { + IRecycleBinFile *rbf; + hr = IRecycleBinEnumList_Next(s->current, 1, &rbf, NULL); + if (hr == S_OK) + hr = IRecycleBinFile_Release(rbf); + else if (hr == S_FALSE) + break; + else if (!SUCCEEDED(hr)) + return hr; + } + if (s->skip > 0) + continue; + + /* Fill area */ + hr = IRecycleBinEnumList_Next(s->current, celt - fetched, &rgelt[fetched], &newFetched); + if (SUCCEEDED(hr)) + fetched += newFetched; + if (hr == S_FALSE || newFetched == 0) + { + hr = IRecycleBinEnumList_Release(s->current); + s->current = NULL; + } + else if (!SUCCEEDED(hr)) + return hr; + if (fetched == celt) + { + if (pceltFetched) + *pceltFetched = fetched; + return S_OK; + } + } + + /* Never go here */ +} + +static HRESULT STDMETHODCALLTYPE +RecycleBinGenericEnum_RecycleBinEnumList_Skip( + IN IRecycleBinEnumList *This, + IN DWORD celt) +{ + struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl); + s->skip += celt; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBinGenericEnum_RecycleBinEnumList_Reset( + IN IRecycleBinEnumList *This) +{ + struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl); + + if (s->current) + { + IRecycleBinEnumList_Release(s->current); + s->current = NULL; + s->skip = 0; + } + s->dwLogicalDrives = GetLogicalDrives(); + return S_OK; +} + +CONST_VTBL struct IRecycleBinEnumListVtbl RecycleBinGenericEnumVtbl = +{ + RecycleBinGenericEnum_RecycleBinEnumList_QueryInterface, + RecycleBinGenericEnum_RecycleBinEnumList_AddRef, + RecycleBinGenericEnum_RecycleBinEnumList_Release, + RecycleBinGenericEnum_RecycleBinEnumList_Next, + RecycleBinGenericEnum_RecycleBinEnumList_Skip, + RecycleBinGenericEnum_RecycleBinEnumList_Reset, +}; + +HRESULT +RecycleBinGeneric_Enumerator_Constructor( + OUT IRecycleBinEnumList **pprbel) +{ + struct RecycleBinGenericEnum *s; + + s = CoTaskMemAlloc(sizeof(struct RecycleBinGenericEnum)); + if (!s) + return E_OUTOFMEMORY; + ZeroMemory(s, sizeof(struct RecycleBinGenericEnum)); + s->ref = 1; + s->recycleBinEnumImpl.lpVtbl = &RecycleBinGenericEnumVtbl; + + *pprbel = &s->recycleBinEnumImpl; + return IRecycleBinEnumList_Reset(*pprbel); +} Propchange: trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/reactos/lib/recyclebin/recyclebin_private.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin_private.h (original) +++ trunk/reactos/lib/recyclebin/recyclebin_private.h Wed Oct 31 11:57:35 2007 @@ -17,55 +17,6 @@ #define RemoveEntryList(Entry) { PLIST_ENTRY _EX_Blink, _EX_Flink; _EX_Flink = (Entry)->Flink; _EX_Blink = (Entry)->Blink; _EX_Blink->Flink = _EX_Flink; _EX_Flink->Blink = _EX_Blink; } /* Typedefs */ -struct _RECYCLE_BIN; -typedef struct _RECYCLE_BIN *PRECYCLE_BIN; -struct _REFCOUNT_DATA; -typedef struct _REFCOUNT_DATA *PREFCOUNT_DATA; - -typedef BOOL (*PINT_ENUMERATE_RECYCLEBIN_CALLBACK)(IN PVOID Context OPTIONAL, IN HANDLE hDeletedFile); -typedef BOOL (*PDESTROY_DATA) (IN PREFCOUNT_DATA pData); - -typedef BOOL (*PCLOSE_HANDLE) (IN HANDLE hHandle); -typedef BOOL (*PDELETE_FILE) (IN PRECYCLE_BIN bin, IN LPCWSTR FullPath, IN LPCWSTR FileName); -typedef BOOL (*PEMPTY_RECYCLEBIN)(IN PRECYCLE_BIN* bin); -typedef BOOL (*PENUMERATE_FILES) (IN PRECYCLE_BIN bin, IN PINT_ENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PVOID Context OPTIONAL); -typedef BOOL (*PGET_DETAILS) (IN PRECYCLE_BIN bin, IN HANDLE hDeletedFile, IN DWORD BufferSize, IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL, OUT LPDWORD RequiredSize OPTIONAL); -typedef BOOL (*PRESTORE_FILE) (IN PRECYCLE_BIN bin, IN HANDLE hDeletedFile); - -typedef struct _RECYCLEBIN_CALLBACKS -{ - PCLOSE_HANDLE CloseHandle; - PDELETE_FILE DeleteFile; - PEMPTY_RECYCLEBIN EmptyRecycleBin; - PENUMERATE_FILES EnumerateFiles; - PGET_DETAILS GetDetails; - PRESTORE_FILE RestoreFile; -} RECYCLEBIN_CALLBACKS, *PRECYCLEBIN_CALLBACKS; - -typedef struct _REFCOUNT_DATA -{ - DWORD ReferenceCount; - PDESTROY_DATA Close; -} REFCOUNT_DATA; - -typedef struct _RECYCLE_BIN -{ - DWORD magic; /* RECYCLEBIN_MAGIC */ - LIST_ENTRY ListEntry; - REFCOUNT_DATA refCount; - HANDLE hInfo; - RECYCLEBIN_CALLBACKS Callbacks; - LPWSTR InfoFile; - WCHAR Folder[ANY_SIZE]; /* [drive]:\[RECYCLE_BIN_DIRECTORY]\{SID} */ -} RECYCLE_BIN; - -typedef struct _DELETED_FILE_HANDLE -{ - DWORD magic; /* DELETEDFILE_MAGIC */ - REFCOUNT_DATA refCount; - PRECYCLE_BIN bin; - HANDLE hDeletedFile; /* specific to recycle bin format */ -} DELETED_FILE_HANDLE, *PDELETED_FILE_HANDLE; /* Structures on disk */ @@ -84,33 +35,14 @@ /* Prototypes */ -/* openclose.c */ +/* recyclebin_generic.c */ -BOOL -IntCheckDeletedFileHandle( - IN HANDLE hDeletedFile); +HRESULT RecycleBinGeneric_Constructor(OUT IUnknown **ppUnknown); -PRECYCLE_BIN -IntReferenceRecycleBin( - IN WCHAR driveLetter); +/* recyclebin_generic_enumerator.c */ + +HRESULT RecycleBinGeneric_Enumerator_Constructor(OUT IRecycleBinEnumList **pprbel); /* recyclebin_v5.c */ -VOID -InitializeCallbacks5( - IN OUT PRECYCLEBIN_CALLBACKS Callbacks); - -/* refcount.c */ - -BOOL -InitializeHandle( - IN PREFCOUNT_DATA pData, - IN PDESTROY_DATA pFnClose OPTIONAL); - -BOOL -ReferenceHandle( - IN PREFCOUNT_DATA pData); - -BOOL -DereferenceHandle( - IN PREFCOUNT_DATA pData); +HRESULT RecycleBin5_Constructor(IN LPCWSTR VolumePath, OUT IUnknown **ppUnknown); Modified: trunk/reactos/lib/recyclebin/recyclebin_v5.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin_v5.c (original) +++ trunk/reactos/lib/recyclebin/recyclebin_v5.c Wed Oct 31 11:57:35 2007 @@ -1,547 +1,726 @@ /* * PROJECT: Recycle bin management * LICENSE: GPL v2 - See COPYING in the top level directory - * FILE: lib/recyclebin/openclose.c + * FILE: lib/recyclebin/recyclebin_v5.c * PURPOSE: Deals with recycle bins of Windows 2000/XP/2003 - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin(a)reactos.org) + * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin(a)reactos.org) */ +#define COBJMACROS #include "recyclebin_v5.h" - -VOID -InitializeCallbacks5( - IN OUT PRECYCLEBIN_CALLBACKS Callbacks) -{ - Callbacks->CloseHandle = CloseHandle5; - Callbacks->DeleteFile = DeleteFile5; - Callbacks->EmptyRecycleBin = EmptyRecycleBin5; - Callbacks->EnumerateFiles = EnumerateFiles5; - Callbacks->GetDetails = GetDetails5; - Callbacks->RestoreFile = RestoreFile5; -} +#include <stdio.h> static BOOL -CloseHandle5( - IN HANDLE hDeletedFile) -{ - UNREFERENCED_PARAMETER(hDeletedFile); - /* Nothing to do, as hDeletedFile is simply a DWORD... */ - return TRUE; -} - -static BOOL -DeleteFile5( - IN PRECYCLE_BIN bin, - IN LPCWSTR FullPath, - IN LPCWSTR FileName) -{ +IntDeleteRecursive( + IN LPCWSTR FullName) +{ + DWORD RemovableAttributes = FILE_ATTRIBUTE_READONLY; + DWORD FileAttributes; + BOOL ret = FALSE; + + FileAttributes = GetFileAttributesW(FullName); + if (FileAttributes == INVALID_FILE_ATTRIBUTES) + { + if (GetLastError() == ERROR_FILE_NOT_FOUND) + ret = TRUE; + goto cleanup; + } + if (FileAttributes & RemovableAttributes) + { + if (!SetFileAttributesW(FullName, FileAttributes & ~RemovableAttributes)) + goto cleanup; + } + if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + /* Recursive deletion */ + /* FIXME: recursive deletion */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + goto cleanup; + + if (!RemoveDirectoryW(FullName)) + goto cleanup; + } + else + { + if (!DeleteFileW(FullName)) + goto cleanup; + } + ret = TRUE; + +cleanup: + return ret; +} + +struct RecycleBin5 +{ + ULONG ref; + IRecycleBin5 recycleBinImpl; + HANDLE hInfo; + HANDLE hInfoMapped; + + DWORD EnumeratorCount; + + LPWSTR VolumePath; + WCHAR Folder[ANY_SIZE]; /* [drive]:\[RECYCLE_BIN_DIRECTORY]\{SID} */ +}; + +static HRESULT STDMETHODCALLTYPE +RecycleBin5_RecycleBin5_QueryInterface( + IRecycleBin5 *This, + REFIID riid, + void **ppvObject) +{ + struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl); + + if (!ppvObject) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppvObject = &s->recycleBinImpl; + else if (IsEqualIID(riid, &IID_IRecycleBin)) + *ppvObject = &s->recycleBinImpl; + else if (IsEqualIID(riid, &IID_IRecycleBin5)) + *ppvObject = &s->recycleBinImpl; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef(This); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE +RecycleBin5_RecycleBin5_AddRef( + IRecycleBin5 *This) +{ + struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl); + ULONG refCount = InterlockedIncrement((PLONG)&s->ref); + return refCount; +} + +static ULONG STDMETHODCALLTYPE +RecycleBin5_RecycleBin5_Release( + IRecycleBin5 *This) +{ + struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl); + ULONG refCount; + + if (!This) + return E_POINTER; + + refCount = InterlockedDecrement((PLONG)&s->ref); + + if (refCount == 0) + { + CloseHandle(s->hInfo); + CloseHandle(s->hInfoMapped); + CoTaskMemFree(s); + } + + return refCount; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5_RecycleBin5_DeleteFile( + IN IRecycleBin5 *This, + IN LPCWSTR szFileName) +{ + struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl); + LPWSTR szFullName = NULL; + DWORD dwBufferLength = 0; + LPWSTR lpFilePart; + LPCWSTR Extension; + WCHAR DeletedFileName[MAX_PATH]; + DWORD len; HANDLE hFile = INVALID_HANDLE_VALUE; - INFO2_HEADER Header; - DELETED_FILE_RECORD DeletedFile; - DWORD bytesRead, bytesWritten; + PINFO2_HEADER pHeader = NULL; + PDELETED_FILE_RECORD pDeletedFile; ULARGE_INTEGER fileSize; + DWORD dwAttributes; SYSTEMTIME SystemTime; - WCHAR RootDir[4]; - WCHAR DeletedFileName[2 * MAX_PATH]; - LPCWSTR Extension; DWORD ClusterSize, BytesPerSector, SectorsPerCluster; - BOOL ret = FALSE; - - if (wcslen(FullPath) >= MAX_PATH) - { - /* Unable to store a too long path in recycle bin */ - SetLastError(ERROR_INVALID_NAME); - goto cleanup; - } - - hFile = CreateFileW(FullPath, 0, 0, NULL, OPEN_EXISTING, 0, NULL); + HRESULT hr; + + if (s->EnumeratorCount != 0) + return E_FAIL; + + /* Get full file name */ + while (TRUE) + { + len = GetFullPathNameW(szFileName, dwBufferLength, szFullName, &lpFilePart); + if (len == 0) + { + if (szFullName) + CoTaskMemFree(szFullName); + return HRESULT_FROM_WIN32(GetLastError()); + } + else if (len < dwBufferLength) + break; + if (szFullName) + CoTaskMemFree(szFullName); + dwBufferLength = len; + szFullName = CoTaskMemAlloc(dwBufferLength * sizeof(WCHAR)); + if (!szFullName) + return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + } + + /* Check if file exists */ + dwAttributes = GetFileAttributesW(szFullName); + if (dwAttributes == INVALID_FILE_ATTRIBUTES) + return HRESULT_FROM_WIN32(GetLastError()); + + if (dwBufferLength < 2 || szFullName[1] != ':') + { + /* Not a local file */ + CoTaskMemFree(szFullName); + return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); + } + + hFile = CreateFileW(szFullName, 0, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) - goto cleanup; - - if (SetFilePointer(bin->hInfo, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!ReadFile(bin->hInfo, &Header, sizeof(INFO2_HEADER), &bytesRead, NULL)) - goto cleanup; - if (bytesRead != sizeof(INFO2_HEADER) || Header.dwRecordSize == 0) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - - if (Header.dwVersion != 5 || Header.dwRecordSize != sizeof(DELETED_FILE_RECORD)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + + /* Increase INFO2 file size */ + CloseHandle(s->hInfoMapped); + SetFilePointer(s->hInfo, sizeof(DELETED_FILE_RECORD), NULL, FILE_END); + SetEndOfFile(s->hInfo); + s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL); + if (!s->hInfoMapped) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + + /* Open INFO2 file */ + pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0); + if (!pHeader) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + pDeletedFile = ((PDELETED_FILE_RECORD)(pHeader + 1)) + pHeader->dwNumberOfEntries; /* Get file size */ #if 0 - if (!GetFileSizeEx(hFile, &fileSize)) - goto cleanup; + if (!GetFileSizeEx(hFile, (PLARGE_INTEGER)&fileSize)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } #else fileSize.u.LowPart = GetFileSize(hFile, &fileSize.u.HighPart); if (fileSize.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) - goto cleanup; + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } #endif /* Check if file size is > 4Gb */ if (fileSize.u.HighPart != 0) { /* FIXME: how to delete files >= 4Gb? */ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - goto cleanup; - } - Header.dwTotalLogicalSize += fileSize.u.LowPart; + hr = E_NOTIMPL; + goto cleanup; + } + pHeader->dwTotalLogicalSize += fileSize.u.LowPart; /* Generate new name */ - Header.dwHighestRecordUniqueId++; - Extension = wcsrchr(FileName, '.'); - wsprintfW(DeletedFileName, L"%s\\D%c%lu%s", bin->Folder, FullPath[0] - 'A' + 'a', Header.dwHighestRecordUniqueId, Extension); + pHeader->dwHighestRecordUniqueId++; + Extension = wcsrchr(szFullName, '.'); + ZeroMemory(pDeletedFile, sizeof(DELETED_FILE_RECORD)); + pDeletedFile->dwRecordUniqueId = pHeader->dwHighestRecordUniqueId; + pDeletedFile->dwDriveNumber = tolower(szFullName[0]) - 'a'; + _snwprintf(DeletedFileName, MAX_PATH, L"%s\\D%c%lu%s", s->Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension); /* Get cluster size */ - wsprintfW(RootDir, L"%c:\\", bin->Folder[0]); - if (!GetDiskFreeSpaceW(RootDir, &SectorsPerCluster, &BytesPerSector, NULL, NULL)) - goto cleanup; + if (!GetDiskFreeSpaceW(s->VolumePath, &SectorsPerCluster, &BytesPerSector, NULL, NULL)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } ClusterSize = BytesPerSector * SectorsPerCluster; /* Get current time */ GetSystemTime(&SystemTime); - if (!SystemTimeToFileTime(&SystemTime, &DeletedFile.DeletionTime)) - goto cleanup; - - /* Update INFO2 */ - memset(&DeletedFile, 0, sizeof(DELETED_FILE_RECORD)); - if (WideCharToMultiByte(CP_ACP, 0, FullPath, -1, DeletedFile.FileNameA, MAX_PATH, NULL, NULL) == 0) - { + if (!SystemTimeToFileTime(&SystemTime, &pDeletedFile->DeletionTime)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + pDeletedFile->dwPhysicalFileSize = ROUND_UP(fileSize.u.LowPart, ClusterSize); + + /* Set name */ + wcscpy(pDeletedFile->FileNameW, szFullName); + if (WideCharToMultiByte(CP_ACP, 0, pDeletedFile->FileNameW, -1, pDeletedFile->FileNameA, MAX_PATH, NULL, NULL) == 0) + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_NAME); SetLastError(ERROR_INVALID_NAME); goto cleanup; } - DeletedFile.dwRecordUniqueId = Header.dwHighestRecordUniqueId; - DeletedFile.dwDriveNumber = tolower(bin->Folder[0]) - 'a'; - DeletedFile.dwPhysicalFileSize = ROUND_UP(fileSize.u.LowPart, ClusterSize); - wcscpy(DeletedFile.FileNameW, FullPath); - - if (!SetFilePointer(bin->hInfo, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!WriteFile(bin->hInfo, &DeletedFile, sizeof(DELETED_FILE_RECORD), &bytesWritten, NULL)) - goto cleanup; - if (bytesWritten != sizeof(DELETED_FILE_RECORD)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - Header.dwNumberOfEntries++; - if (SetFilePointer(bin->hInfo, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - { - goto cleanup; - } - if (!WriteFile(bin->hInfo, &Header, sizeof(INFO2_HEADER), &bytesWritten, NULL)) - goto cleanup; - if (bytesWritten != sizeof(INFO2_HEADER)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } + pHeader->dwNumberOfEntries++; /* Move file */ - if (!MoveFileW(FullPath, DeletedFileName)) - goto cleanup; - - ret = TRUE; + if (MoveFileW(szFullName, DeletedFileName)) + hr = S_OK; + else + hr = HRESULT_FROM_WIN32(GetLastError()); cleanup: + if (pHeader) + UnmapViewOfFile(pHeader); if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); - return ret; -} - -static BOOL -EmptyRecycleBin5( - IN PRECYCLE_BIN* bin) -{ - LPWSTR InfoFile = NULL; - BOOL ret = FALSE; - - InfoFile = HeapAlloc(GetProcessHeap(), 0, wcslen((*bin)->InfoFile) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); - if (!InfoFile) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - wcscpy(InfoFile, (*bin)->InfoFile); - - /* Delete all files in the recycle bin */ - if (!EnumerateFiles5(*bin, IntEmptyRecycleBinCallback, *bin)) - goto cleanup; - - /* Delete INFO2 */ - if (!DereferenceHandle(&(*bin)->refCount)) - goto cleanup; - if (!DeleteFileW(InfoFile)) - goto cleanup; - *bin = NULL; - ret = TRUE; + CoTaskMemFree(szFullName); + return hr; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5_RecycleBin5_EmptyRecycleBin( + IN IRecycleBin5 *This) +{ + IRecycleBinEnumList *prbel; + IRecycleBinFile *prbf; + HRESULT hr; + + while (TRUE) + { + hr = IRecycleBin5_EnumObjects(This, &prbel); + if (!SUCCEEDED(hr)) + return hr; + hr = IRecycleBinEnumList_Next(prbel, 1, &prbf, NULL); + IRecycleBinEnumList_Release(prbel); + if (hr == S_FALSE) + return S_OK; + hr = IRecycleBinFile_Delete(prbf); + IRecycleBinFile_Release(prbf); + if (!SUCCEEDED(hr)) + return hr; + } +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5_RecycleBin5_EnumObjects( + IN IRecycleBin5 *This, + OUT IRecycleBinEnumList **ppEnumList) +{ + struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl); + IRecycleBinEnumList *prbel; + HRESULT hr; + IUnknown *pUnk; + + hr = RecycleBin5_Enumerator_Constructor(This, s->hInfo, s->hInfoMapped, s->Folder, &pUnk); + if (!SUCCEEDED(hr)) + return hr; + + hr = IUnknown_QueryInterface(pUnk, &IID_IRecycleBinEnumList, (void **)&prbel); + if (SUCCEEDED(hr)) + { + s->EnumeratorCount++; + *ppEnumList = prbel; + } + IUnknown_Release(pUnk); + return hr; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5_RecycleBin5_Delete( + IN IRecycleBin5 *This, + IN LPCWSTR pDeletedFileName, + IN DELETED_FILE_RECORD *pDeletedFile) +{ + struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl); + ULARGE_INTEGER FileSize; + PINFO2_HEADER pHeader; + DELETED_FILE_RECORD *pRecord, *pLast; + DWORD dwEntries, i; + + if (s->EnumeratorCount != 0) + return E_FAIL; + + pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0); + if (!pHeader) + return HRESULT_FROM_WIN32(GetLastError()); + + FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart); + if (FileSize.u.LowPart == 0) + { + UnmapViewOfFile(pHeader); + return HRESULT_FROM_WIN32(GetLastError()); + } + dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)); + + pRecord = (DELETED_FILE_RECORD *)(pHeader + 1); + for (i = 0; i < dwEntries; i++) + { + if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId) + { + /* Delete file */ + if (!IntDeleteRecursive(pDeletedFileName)) + { + UnmapViewOfFile(pHeader); + return HRESULT_FROM_WIN32(GetLastError()); + } + + /* Clear last entry in the file */ + MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD)); + pLast = pRecord + (dwEntries - i - 1); + ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD)); + UnmapViewOfFile(pHeader); + + /* Resize file */ + CloseHandle(s->hInfoMapped); + SetFilePointer(s->hInfo, -(LONG)sizeof(DELETED_FILE_RECORD), NULL, FILE_END); + SetEndOfFile(s->hInfo); + s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL); + if (!s->hInfoMapped) + return HRESULT_FROM_WIN32(GetLastError()); + return S_OK; + } + pRecord++; + } + UnmapViewOfFile(pHeader); + return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5_RecycleBin5_Restore( + IN IRecycleBin5 *This, + IN LPCWSTR pDeletedFileName, + IN DELETED_FILE_RECORD *pDeletedFile) +{ + struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl); + ULARGE_INTEGER FileSize; + PINFO2_HEADER pHeader; + DELETED_FILE_RECORD *pRecord, *pLast; + DWORD dwEntries, i; + + if (s->EnumeratorCount != 0) + return E_FAIL; + + pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0); + if (!pHeader) + return HRESULT_FROM_WIN32(GetLastError()); + + FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart); + if (FileSize.u.LowPart == 0) + { + UnmapViewOfFile(pHeader); + return HRESULT_FROM_WIN32(GetLastError()); + } + dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)); + + pRecord = (DELETED_FILE_RECORD *)(pHeader + 1); + for (i = 0; i < dwEntries; i++) + { + if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId) + { + /* Restore file */ + if (!MoveFileW(pDeletedFileName, pDeletedFile->FileNameW)) + { + UnmapViewOfFile(pHeader); + return HRESULT_FROM_WIN32(GetLastError()); + } + + /* Clear last entry in the file */ + MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD)); + pLast = pRecord + (dwEntries - i - 1); + ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD)); + UnmapViewOfFile(pHeader); + + /* Resize file */ + CloseHandle(s->hInfoMapped); + SetFilePointer(s->hInfo, -(LONG)sizeof(DELETED_FILE_RECORD), NULL, FILE_END); + SetEndOfFile(s->hInfo); + s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL); + if (!s->hInfoMapped) + return HRESULT_FROM_WIN32(GetLastError()); + return S_OK; + } + pRecord++; + } + + UnmapViewOfFile(pHeader); + return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5_RecycleBin5_OnClosing( + IN IRecycleBin5 *This, + IN IRecycleBinEnumList *prb5el) +{ + struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl); + s->EnumeratorCount--; + return S_OK; +} + +CONST_VTBL struct IRecycleBin5Vtbl RecycleBin5Vtbl = +{ + RecycleBin5_RecycleBin5_QueryInterface, + RecycleBin5_RecycleBin5_AddRef, + RecycleBin5_RecycleBin5_Release, + RecycleBin5_RecycleBin5_DeleteFile, + RecycleBin5_RecycleBin5_EmptyRecycleBin, + RecycleBin5_RecycleBin5_EnumObjects, + RecycleBin5_RecycleBin5_Delete, + RecycleBin5_RecycleBin5_Restore, + RecycleBin5_RecycleBin5_OnClosing, +}; + +static HRESULT +RecycleBin5_Create( + IN LPCWSTR Folder, + IN PSID OwnerSid OPTIONAL) +{ + LPWSTR BufferName = NULL; + LPWSTR Separator; /* Pointer into BufferName buffer */ + LPWSTR FileName; /* Pointer into BufferName buffer */ + LPCSTR DesktopIniContents = "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n"; + INFO2_HEADER Info2Contents[] = { { 5, 0, 0, 0x320, 0 } }; + SIZE_T BytesToWrite, BytesWritten, Needed; + HANDLE hFile = INVALID_HANDLE_VALUE; + HRESULT hr; + + Needed = (wcslen(Folder) + 1 + max(wcslen(RECYCLE_BIN_FILE_NAME), wcslen(L"desktop.ini")) + 1) * sizeof(WCHAR); + BufferName = HeapAlloc(GetProcessHeap(), 0, Needed); + if (!BufferName) + { + hr = ERROR_NOT_ENOUGH_MEMORY; + goto cleanup; + } + + wcscpy(BufferName, Folder); + Separator = wcsstr(&BufferName[3], L"\\"); + if (Separator) + *Separator = UNICODE_NULL; + if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + SetFileAttributesW(BufferName, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + if (Separator) + { + *Separator = L'\\'; + if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + } + + if (OwnerSid) + { + //DWORD rc; + + /* Add ACL to allow only user/SYSTEM to open it */ + /* FIXME: rc = SetNamedSecurityInfo( + BufferName, + SE_FILE_OBJECT, + ???, + OwnerSid, + NULL, + ???, + ???); + if (rc != ERROR_SUCCESS) + { + hr = HRESULT_FROM_WIN32(rc); + goto cleanup; + } + */ + } + + wcscat(BufferName, L"\\"); + FileName = &BufferName[wcslen(BufferName)]; + + /* Create desktop.ini */ + wcscpy(FileName, L"desktop.ini"); + hFile = CreateFileW(BufferName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + BytesToWrite = strlen(DesktopIniContents); + if (!WriteFile(hFile, DesktopIniContents, (DWORD)BytesToWrite, &BytesWritten, NULL)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + if (BytesWritten != BytesToWrite) + { + hr = E_FAIL; + goto cleanup; + } + CloseHandle(hFile); + hFile = INVALID_HANDLE_VALUE; + + /* Create empty INFO2 file */ + wcscpy(FileName, RECYCLE_BIN_FILE_NAME); + hFile = CreateFileW(BufferName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + BytesToWrite = sizeof(Info2Contents); + if (!WriteFile(hFile, Info2Contents, (DWORD)BytesToWrite, &BytesWritten, NULL)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + if (BytesWritten == BytesToWrite) + hr = S_OK; + else + hr = E_FAIL; cleanup: - HeapFree(GetProcessHeap(), 0, InfoFile); - return ret; -} - -static BOOL -EnumerateFiles5( - IN PRECYCLE_BIN bin, - IN PINT_ENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, - IN PVOID Context OPTIONAL) -{ - INFO2_HEADER Header; - DELETED_FILE_RECORD DeletedFile; - DWORD bytesRead, dwEntries; - BOOL ret = FALSE; - - if (SetFilePointer(bin->hInfo, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!ReadFile(bin->hInfo, &Header, sizeof(INFO2_HEADER), &bytesRead, NULL)) - goto cleanup; - if (bytesRead != sizeof(INFO2_HEADER) || Header.dwRecordSize == 0) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - - if (Header.dwVersion != 5 || Header.dwRecordSize != sizeof(DELETED_FILE_RECORD)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - - SetLastError(ERROR_SUCCESS); - for (dwEntries = 0; dwEntries < Header.dwNumberOfEntries; dwEntries++) - { - if (!ReadFile(bin->hInfo, &DeletedFile, Header.dwRecordSize, &bytesRead, NULL)) - goto cleanup; - if (bytesRead != Header.dwRecordSize) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - if (!pFnCallback(Context, (HANDLE)(ULONG_PTR)DeletedFile.dwRecordUniqueId)) - goto cleanup; - if (SetFilePointer(bin->hInfo, sizeof(INFO2_HEADER) + Header.dwRecordSize * dwEntries, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - goto cleanup; - } - - ret = TRUE; - -cleanup: - return ret; -} - -static BOOL -GetDetails5( - IN PRECYCLE_BIN bin, - IN HANDLE hDeletedFile, - IN DWORD BufferSize, - IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL, - OUT LPDWORD RequiredSize OPTIONAL) -{ - DELETED_FILE_RECORD DeletedFile; - SIZE_T Needed; - LPWSTR FullName = NULL; - HANDLE hFile = INVALID_HANDLE_VALUE; - BOOL ret = FALSE; - - /* Check parameters */ - if (BufferSize > 0 && FileDetails == NULL) - { - SetLastError(ERROR_INVALID_PARAMETER); - goto cleanup; - } - - if (!IntSearchRecord(bin, hDeletedFile, &DeletedFile, NULL)) - goto cleanup; - Needed = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName) + (wcslen(DeletedFile.FileNameW) + 1) * sizeof(WCHAR); - if (RequiredSize) - *RequiredSize = (DWORD)Needed; - if (Needed > BufferSize) - { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - goto cleanup; - } - - if (!IntGetFullName(bin, &DeletedFile, &FullName)) - goto cleanup; - - /* Open file */ - FileDetails->Attributes = GetFileAttributesW(FullName); - if (FileDetails->Attributes == INVALID_FILE_ATTRIBUTES) - goto cleanup; - if (FileDetails->Attributes & FILE_ATTRIBUTE_DIRECTORY) - hFile = CreateFileW(FullName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - else - hFile = CreateFileW(FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if (hFile == INVALID_HANDLE_VALUE) - goto cleanup; - - /* Fill returned structure */ - if (!GetFileTime(hFile, NULL, NULL, &FileDetails->LastModification)) - goto cleanup; - memcpy(&FileDetails->DeletionTime, &DeletedFile.DeletionTime, sizeof(FILETIME)); - FileDetails->FileSize.u.LowPart = GetFileSize(hFile, &FileDetails->FileSize.u.HighPart); - if (FileDetails->FileSize.u.LowPart == INVALID_FILE_SIZE) - goto cleanup; - FileDetails->PhysicalFileSize.u.HighPart = 0; - FileDetails->PhysicalFileSize.u.LowPart = DeletedFile.dwPhysicalFileSize; - wcscpy(FileDetails->FileName, DeletedFile.FileNameW); - - ret = TRUE; - -cleanup: - HeapFree(GetProcessHeap(), 0, FullName); + HeapFree(GetProcessHeap(), 0, BufferName); if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); - return ret; -} - -static BOOL -RestoreFile5( - IN PRECYCLE_BIN bin, - IN HANDLE hDeletedFile) -{ - INFO2_HEADER Header; - DWORD bytesRead, bytesWritten; - LARGE_INTEGER Position; - DELETED_FILE_RECORD DeletedFile, LastFile; - LPWSTR FullName = NULL; - BOOL ret = FALSE; - - if (SetFilePointer(bin->hInfo, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!ReadFile(bin->hInfo, &Header, sizeof(INFO2_HEADER), &bytesRead, NULL)) - goto cleanup; - if (bytesRead != sizeof(INFO2_HEADER) || Header.dwRecordSize == 0) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - - if (Header.dwVersion != 5 || Header.dwRecordSize != sizeof(DELETED_FILE_RECORD)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - - /* Search deleted entry */ - if (!IntSearchRecord(bin, hDeletedFile, &DeletedFile, &Position)) - goto cleanup; - /* Get destination full name */ - if (!IntGetFullName(bin, &DeletedFile, &FullName)) - goto cleanup; - /* Restore file */ - if (!MoveFileW(FullName, DeletedFile.FileNameW)) - goto cleanup; - - /* Update INFO2 */ - /* 1) If not last entry, copy last entry to the current one */ - if (SetFilePointer(bin->hInfo, -(LONG)sizeof(DELETED_FILE_RECORD), NULL, FILE_END) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!ReadFile(bin->hInfo, &LastFile, sizeof(DELETED_FILE_RECORD), &bytesRead, NULL)) - goto cleanup; - if (bytesRead != sizeof(DELETED_FILE_RECORD)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - if (LastFile.dwRecordUniqueId != DeletedFile.dwRecordUniqueId) - { - /* Move the last entry to the current one */ - if (SetFilePointer(bin->hInfo, Position.u.LowPart, &Position.u.HighPart, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!WriteFile(bin->hInfo, &LastFile, sizeof(DELETED_FILE_RECORD), &bytesWritten, NULL)) - goto cleanup; - if (bytesWritten != sizeof(DELETED_FILE_RECORD)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - } - /* 2) Update the header */ - Header.dwNumberOfEntries--; - if (SetFilePointer(bin->hInfo, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!WriteFile(bin->hInfo, &Header, sizeof(INFO2_HEADER), &bytesWritten, NULL)) - goto cleanup; - if (bytesWritten != sizeof(INFO2_HEADER)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - /* 3) Truncate file */ - if (SetFilePointer(bin->hInfo, -(LONG)sizeof(DELETED_FILE_RECORD), NULL, FILE_END) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!SetEndOfFile(bin->hInfo)) - goto cleanup; - ret = TRUE; + return hr; +} + +HRESULT RecycleBin5_Constructor(IN LPCWSTR VolumePath, OUT IUnknown **ppUnknown) +{ + struct RecycleBin5 *s = NULL; + DWORD FileSystemFlags; + LPCWSTR RecycleBinDirectory; + HANDLE tokenHandle = INVALID_HANDLE_VALUE; + PTOKEN_USER TokenUserInfo = NULL; + LPWSTR StringSid = NULL, p; + SIZE_T Needed, DirectoryLength; + INT len; + HRESULT hr; + + if (!ppUnknown) + return E_POINTER; + + /* Get information about file system */ + if (!GetVolumeInformationW( + VolumePath, + NULL, + 0, + NULL, + NULL, + &FileSystemFlags, + NULL, + 0)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + if (!(FileSystemFlags & FILE_PERSISTENT_ACLS)) + RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITHOUT_ACL; + else + { + RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITH_ACL; + + /* Get user SID */ + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + if (GetTokenInformation(tokenHandle, TokenUser, NULL, 0, &Needed)) + { + hr = E_FAIL; + goto cleanup; + } + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + TokenUserInfo = HeapAlloc(GetProcessHeap(), 0, Needed); + if (!TokenUserInfo) + { + hr = E_OUTOFMEMORY; + goto cleanup; + } + if (!GetTokenInformation(tokenHandle, TokenUser, TokenUserInfo, (DWORD)Needed, &Needed)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + if (!ConvertSidToStringSidW(TokenUserInfo->User.Sid, &StringSid)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + } + + DirectoryLength = wcslen(VolumePath) + wcslen(RecycleBinDirectory) + 1; + if (StringSid) + DirectoryLength += wcslen(StringSid) + 1; + DirectoryLength += 1 + wcslen(RECYCLE_BIN_FILE_NAME); + DirectoryLength += wcslen(VolumePath) + 1; + Needed = (DirectoryLength + 1) * sizeof(WCHAR); + + s = CoTaskMemAlloc(sizeof(struct RecycleBin5) + Needed); + if (!s) + { + hr = E_OUTOFMEMORY; + goto cleanup; + } + ZeroMemory(s, sizeof(struct RecycleBin5)); + s->recycleBinImpl.lpVtbl = &RecycleBin5Vtbl; + s->ref = 1; + if (StringSid) + len = swprintf(s->Folder, L"%s%s\\%s", VolumePath, RecycleBinDirectory, StringSid); + else + len = swprintf(s->Folder, L"%s%s", VolumePath, RecycleBinDirectory); + p = &s->Folder[len]; + wcscpy(p, L"\\" RECYCLE_BIN_FILE_NAME); + s->hInfo = CreateFileW(s->Folder, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (s->hInfo == INVALID_HANDLE_VALUE && (GetLastError() == ERROR_PATH_NOT_FOUND || GetLastError() == ERROR_FILE_NOT_FOUND)) + { + *p = UNICODE_NULL; + hr = RecycleBin5_Create(s->Folder, TokenUserInfo ? TokenUserInfo->User.Sid : NULL); + *p = L'\\'; + if (!SUCCEEDED(hr)) + goto cleanup; + s->hInfo = CreateFileW(s->Folder, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + } + if (s->hInfo == INVALID_HANDLE_VALUE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL); + if (!s->hInfoMapped) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto cleanup; + } + *p = UNICODE_NULL; + s->VolumePath = p + 1; + wcscpy(s->VolumePath, VolumePath); + + *ppUnknown = (IUnknown *)&s->recycleBinImpl; + + hr = S_OK; cleanup: - HeapFree(GetProcessHeap(), 0, FullName); - return ret; -} - -static BOOL -IntDeleteRecursive( - IN LPCWSTR FullName) -{ - DWORD RemovableAttributes = FILE_ATTRIBUTE_READONLY; - DWORD FileAttributes; - BOOL ret = FALSE; - - FileAttributes = GetFileAttributesW(FullName); - if (FileAttributes == INVALID_FILE_ATTRIBUTES) - { - if (GetLastError() == ERROR_FILE_NOT_FOUND) - ret = TRUE; - goto cleanup; - } - if (FileAttributes & RemovableAttributes) - { - if (!SetFileAttributesW(FullName, FileAttributes & ~RemovableAttributes)) - goto cleanup; - } - if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - /* Recursive deletion */ - /* FIXME: recursive deletion */ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - goto cleanup; - - if (!RemoveDirectoryW(FullName)) - goto cleanup; - } - else - { - if (!DeleteFileW(FullName)) - goto cleanup; - } - ret = TRUE; - -cleanup: - return ret; -} - -static BOOL -IntEmptyRecycleBinCallback( - IN PVOID Context, - IN HANDLE hDeletedFile) -{ - PRECYCLE_BIN bin = (PRECYCLE_BIN)Context; - DELETED_FILE_RECORD DeletedFile; - LPWSTR FullName = NULL; - BOOL ret = FALSE; - - if (!IntSearchRecord(bin, hDeletedFile, &DeletedFile, NULL)) - goto cleanup; - - if (!IntGetFullName(bin, &DeletedFile, &FullName)) - goto cleanup; - - if (!IntDeleteRecursive(FullName)) - goto cleanup; - ret = TRUE; - -cleanup: - HeapFree(GetProcessHeap(), 0, FullName); - return ret; -} - -static BOOL -IntGetFullName( - IN PRECYCLE_BIN bin, - IN PDELETED_FILE_RECORD pDeletedFile, - OUT LPWSTR* pFullName) -{ - SIZE_T Needed; - LPCWSTR Extension; - LPWSTR FullName = NULL; - BOOL ret = FALSE; - - *pFullName = NULL; - Extension = wcsrchr(pDeletedFile->FileNameW, '.'); - if (Extension < wcsrchr(pDeletedFile->FileNameW, '\\')) - Extension = NULL; - Needed = wcslen(bin->Folder) + 13; - if (Extension) - Needed += wcslen(Extension); - FullName = HeapAlloc(GetProcessHeap(), 0, Needed * sizeof(WCHAR)); - if (!FullName) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - wsprintfW(FullName, L"%s\\D%c%lu%s", bin->Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension); - *pFullName = FullName; - ret = TRUE; - -cleanup: - if (!ret) - HeapFree(GetProcessHeap(), 0, FullName); - return ret; -} - -static BOOL -IntSearchRecord( - IN PRECYCLE_BIN bin, - IN HANDLE hDeletedFile, - OUT PDELETED_FILE_RECORD pDeletedFile, - OUT PLARGE_INTEGER Position OPTIONAL) -{ - INFO2_HEADER Header; - DELETED_FILE_RECORD DeletedFile; - DWORD bytesRead, dwEntries; - BOOL ret = FALSE; - - if (SetFilePointer(bin->hInfo, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - goto cleanup; - if (!ReadFile(bin->hInfo, &Header, sizeof(INFO2_HEADER), &bytesRead, NULL)) - goto cleanup; - if (bytesRead != sizeof(INFO2_HEADER) || Header.dwRecordSize == 0) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - - if (Header.dwVersion != 5 || Header.dwRecordSize != sizeof(DELETED_FILE_RECORD)) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - - SetLastError(ERROR_SUCCESS); - for (dwEntries = 0; dwEntries < Header.dwNumberOfEntries; dwEntries++) - { - if (Position) - { - LARGE_INTEGER Zero; - Zero.QuadPart = 0; - if (!SetFilePointerEx(bin->hInfo, Zero, Position, FILE_CURRENT)) - goto cleanup; - } - if (!ReadFile(bin->hInfo, &DeletedFile, Header.dwRecordSize, &bytesRead, NULL)) - goto cleanup; - if (bytesRead != Header.dwRecordSize) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - if (DeletedFile.dwRecordUniqueId == (DWORD)(ULONG_PTR)hDeletedFile) - { - memcpy(pDeletedFile, &DeletedFile, Header.dwRecordSize); - ret = TRUE; - goto cleanup; - } - } - - /* Entry not found */ - SetLastError(ERROR_INVALID_HANDLE); - -cleanup: - return ret; -} + if (tokenHandle != INVALID_HANDLE_VALUE) + CloseHandle(tokenHandle); + HeapFree(GetProcessHeap(), 0, TokenUserInfo); + if (StringSid) + LocalFree(StringSid); + if (!SUCCEEDED(hr)) + { + if (s) + { + if (s->hInfo && s->hInfo != INVALID_HANDLE_VALUE) + CloseHandle(s->hInfo); + if (s->hInfoMapped) + CloseHandle(s->hInfoMapped); + CoTaskMemFree(s); + } + } + return hr; +} Modified: trunk/reactos/lib/recyclebin/recyclebin_v5.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin_v5.h (original) +++ trunk/reactos/lib/recyclebin/recyclebin_v5.h Wed Oct 31 11:57:35 2007 @@ -4,6 +4,10 @@ */ #include "recyclebin_private.h" + +#ifdef __cplusplus +extern "C" { +#endif #include <pshpack1.h> @@ -20,57 +24,86 @@ #include <poppack.h> -static BOOL -CloseHandle5( - IN HANDLE hDeletedFile); +/* COM interface */ -static BOOL -DeleteFile5( - IN PRECYCLE_BIN bin, - IN LPCWSTR FullPath, - IN LPCWSTR FileName); +typedef interface IRecycleBin5 IRecycleBin5; +EXTERN_C const IID IID_IRecycleBin5; -static BOOL -EmptyRecycleBin5( - IN PRECYCLE_BIN* bin); +typedef struct IRecycleBin5Vtbl +{ + /* IRecycleBin interface */ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IN IRecycleBin5 *This, + IN REFIID riid, + OUT void **ppvObject); -static BOOL -EnumerateFiles5( - IN PRECYCLE_BIN bin, - IN PINT_ENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, - IN PVOID Context OPTIONAL); + ULONG (STDMETHODCALLTYPE *AddRef)( + IN IRecycleBin5 *This); -static BOOL -GetDetails5( - IN PRECYCLE_BIN bin, - IN HANDLE hDeletedFile, - IN DWORD BufferSize, - IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL, - OUT LPDWORD RequiredSize OPTIONAL); + ULONG (STDMETHODCALLTYPE *Release)( + IN IRecycleBin5 *This); -static BOOL -RestoreFile5( - IN PRECYCLE_BIN bin, - IN HANDLE hDeletedFile); + HRESULT (STDMETHODCALLTYPE *DeleteFile)( + IN IRecycleBin5 *This, + IN LPCWSTR szFileName); -static BOOL -IntDeleteRecursive( - IN LPCWSTR FullName); + HRESULT (STDMETHODCALLTYPE *EmptyRecycleBin)( + IN IRecycleBin5 *This); -static BOOL -IntEmptyRecycleBinCallback( - IN PVOID Context, - IN HANDLE hDeletedFile); + HRESULT (STDMETHODCALLTYPE *EnumObjects)( + IN IRecycleBin5 *This, + OUT IRecycleBinEnumList **ppEnumList); -static BOOL -IntGetFullName( - IN PRECYCLE_BIN bin, - IN PDELETED_FILE_RECORD pDeletedFile, - OUT LPWSTR* pFullName); + /* IRecycleBin5 interface */ + HRESULT (STDMETHODCALLTYPE *Delete)( + IN IRecycleBin5 *This, + IN LPCWSTR pDeletedFileName, + IN DELETED_FILE_RECORD *pDeletedFile); -static BOOL -IntSearchRecord( - IN PRECYCLE_BIN bin, - IN HANDLE hDeletedFile, - OUT PDELETED_FILE_RECORD DeletedFile, - OUT PLARGE_INTEGER Position OPTIONAL); + HRESULT (STDMETHODCALLTYPE *Restore)( + IN IRecycleBin5 *This, + IN LPCWSTR pDeletedFileName, + IN DELETED_FILE_RECORD *pDeletedFile); + + HRESULT (STDMETHODCALLTYPE *OnClosing)( + IN IRecycleBin5 *This, + IN IRecycleBinEnumList *prb5el); +} IRecycleBin5Vtbl; + +interface IRecycleBin5 +{ + CONST_VTBL struct IRecycleBin5Vtbl *lpVtbl; +}; + +#ifdef COBJMACROS +#define IRecycleBin5_QueryInterface(This, riid, ppvObject) \ + (This)->lpVtbl->QueryInterface(This, riid, ppvObject) +#define IRecycleBin5_AddRef(This) \ + (This)->lpVtbl->AddRef(This) +#define IRecycleBin5_Release(This) \ + (This)->lpVtbl->Release(This) +#define IRecycleBin5_DeleteFile(This, szFileName) \ + (This)->lpVtbl->DeleteFile(This, szFileName) +#define IRecycleBin5_EmptyRecycleBin(This) \ + (This)->lpVtbl->EmptyRecycleBin(This) +#define IRecycleBin5_EnumObjects(This, ppEnumList) \ + (This)->lpVtbl->EnumObjects(This, ppEnumList) +#define IRecycleBin5_Delete(This, pDeletedFileName, pDeletedFile) \ + (This)->lpVtbl->Delete(This, pDeletedFileName, pDeletedFile) +#define IRecycleBin5_Restore(This, pDeletedFileName, pDeletedFile) \ + (This)->lpVtbl->Restore(This, pDeletedFileName, pDeletedFile) +#define IRecycleBin5_OnClosing(This, prb5el) \ + (This)->lpVtbl->OnClosing(This, prb5el) +#endif + +HRESULT +RecycleBin5_Enumerator_Constructor( + IN IRecycleBin5 *prb, + IN HANDLE hInfo, + IN HANDLE hInfoMapped, + IN LPCWSTR szPrefix, + OUT IUnknown **ppUnknown); + +#ifdef __cplusplus +} +#endif Added: trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_…
============================================================================== --- trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c (added) +++ trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c Wed Oct 31 11:57:35 2007 @@ -1,0 +1,450 @@ +/* + * PROJECT: Recycle bin management + * LICENSE: GPL v2 - See COPYING in the top level directory + * FILE: lib/recyclebin/recyclebin_v5_enumerator.c + * PURPOSE: Enumerates contents of a MS Windows 2000/XP/2003 recyclebin + * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin(a)reactos.org) + */ + +#define COBJMACROS +#include "recyclebin_v5.h" + +struct RecycleBin5File +{ + ULONG ref; + IRecycleBin5 *recycleBin; + DELETED_FILE_RECORD deletedFile; + IRecycleBinFile recycleBinFileImpl; + WCHAR FullName[ANY_SIZE]; +}; + +static HRESULT STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_QueryInterface( + IN IRecycleBinFile *This, + IN REFIID riid, + OUT void **ppvObject) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + + if (!ppvObject) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppvObject = &s->recycleBinFileImpl; + else if (IsEqualIID(riid, &IID_IRecycleBinFile)) + *ppvObject = &s->recycleBinFileImpl; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef(This); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_AddRef( + IN IRecycleBinFile *This) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + ULONG refCount = InterlockedIncrement((PLONG)&s->ref); + return refCount; +} + +static ULONG STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_Release( + IN IRecycleBinFile *This) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + ULONG refCount; + + if (!This) + return E_POINTER; + + refCount = InterlockedDecrement((PLONG)&s->ref); + + if (refCount == 0) + { + IRecycleBin5_Release(s->recycleBin); + CoTaskMemFree(s); + } + + return refCount; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_GetLastModificationTime( + IN IRecycleBinFile *This, + OUT FILETIME *pLastModificationTime) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + HRESULT hr; + DWORD dwAttributes; + HANDLE hFile; + + dwAttributes = GetFileAttributesW(s->FullName); + if (dwAttributes == INVALID_FILE_ATTRIBUTES) + return HRESULT_FROM_WIN32(GetLastError()); + if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) + hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + else + hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return HRESULT_FROM_WIN32(GetLastError()); + + if (GetFileTime(hFile, NULL, NULL, pLastModificationTime)) + hr = S_OK; + else + hr = HRESULT_FROM_WIN32(GetLastError()); + CloseHandle(hFile); + return hr; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_GetDeletionTime( + IN IRecycleBinFile *This, + OUT FILETIME *pDeletionTime) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + *pDeletionTime = s->deletedFile.DeletionTime; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_GetFileSize( + IN IRecycleBinFile *This, + OUT ULARGE_INTEGER *pFileSize) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + HRESULT hr; + DWORD dwAttributes; + HANDLE hFile; + + dwAttributes = GetFileAttributesW(s->FullName); + if (dwAttributes == INVALID_FILE_ATTRIBUTES) + return HRESULT_FROM_WIN32(GetLastError()); + if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + pFileSize->QuadPart = 0; + return S_OK; + } + + hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return HRESULT_FROM_WIN32(GetLastError()); + pFileSize->u.LowPart = GetFileSize(hFile, &pFileSize->u.HighPart); + if (pFileSize->u.LowPart != INVALID_FILE_SIZE) + hr = S_OK; + else + hr = HRESULT_FROM_WIN32(GetLastError()); + CloseHandle(hFile); + return hr; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_GetPhysicalFileSize( + IN IRecycleBinFile *This, + OUT ULARGE_INTEGER *pPhysicalFileSize) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + pPhysicalFileSize->u.HighPart = 0; + pPhysicalFileSize->u.LowPart = s->deletedFile.dwPhysicalFileSize; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_GetAttributes( + IN IRecycleBinFile *This, + OUT DWORD *pAttributes) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + DWORD dwAttributes; + + dwAttributes = GetFileAttributesW(s->FullName); + if (dwAttributes == INVALID_FILE_ATTRIBUTES) + return HRESULT_FROM_WIN32(GetLastError()); + + *pAttributes = dwAttributes; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_GetFileName( + IN IRecycleBinFile *This, + IN DWORD BufferSize, + IN OUT LPWSTR Buffer, + OUT DWORD *RequiredSize) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + DWORD dwRequired; + + dwRequired = (DWORD)(wcslen(s->deletedFile.FileNameW) + 1) * sizeof(WCHAR); + if (RequiredSize) + *RequiredSize = dwRequired; + + if (BufferSize == 0 && !Buffer) + return S_OK; + + if (BufferSize < dwRequired) + return E_OUTOFMEMORY; + CopyMemory(Buffer, s->deletedFile.FileNameW, dwRequired); + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_Delete( + IN IRecycleBinFile *This) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + return IRecycleBin5_Delete(s->recycleBin, s->FullName, &s->deletedFile); +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5File_RecycleBinFile_Restore( + IN IRecycleBinFile *This) +{ + struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); + return IRecycleBin5_Restore(s->recycleBin, s->FullName, &s->deletedFile); +} + +CONST_VTBL struct IRecycleBinFileVtbl RecycleBin5FileVtbl = +{ + RecycleBin5File_RecycleBinFile_QueryInterface, + RecycleBin5File_RecycleBinFile_AddRef, + RecycleBin5File_RecycleBinFile_Release, + RecycleBin5File_RecycleBinFile_GetLastModificationTime, + RecycleBin5File_RecycleBinFile_GetDeletionTime, + RecycleBin5File_RecycleBinFile_GetFileSize, + RecycleBin5File_RecycleBinFile_GetPhysicalFileSize, + RecycleBin5File_RecycleBinFile_GetAttributes, + RecycleBin5File_RecycleBinFile_GetFileName, + RecycleBin5File_RecycleBinFile_Delete, + RecycleBin5File_RecycleBinFile_Restore, +}; + +static HRESULT +RecycleBin5_File_Constructor( + IN IRecycleBin5 *prb, + IN LPCWSTR Folder, + IN PDELETED_FILE_RECORD pDeletedFile, + OUT IRecycleBinFile **ppFile) +{ + struct RecycleBin5File *s = NULL; + LPCWSTR Extension; + SIZE_T Needed; + + if (!ppFile) + return E_POINTER; + + Extension = wcsrchr(pDeletedFile->FileNameW, '.'); + if (Extension < wcsrchr(pDeletedFile->FileNameW, '\\')) + Extension = NULL; + Needed = wcslen(Folder) + 13; + if (Extension) + Needed += wcslen(Extension); + Needed *= sizeof(WCHAR); + + s = CoTaskMemAlloc(sizeof(struct RecycleBin5File) + Needed); + if (!s) + return E_OUTOFMEMORY; + ZeroMemory(s, sizeof(struct RecycleBin5File) + Needed); + s->recycleBinFileImpl.lpVtbl = &RecycleBin5FileVtbl; + s->ref = 1; + s->deletedFile = *pDeletedFile; + s->recycleBin = prb; + IRecycleBin5_AddRef(s->recycleBin); + *ppFile = &s->recycleBinFileImpl; + wsprintfW(s->FullName, L"%s\\D%c%lu%s", Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension); + + return S_OK; +} + +struct RecycleBin5Enum +{ + ULONG ref; + IRecycleBin5 *recycleBin; + HANDLE hInfo; + INFO2_HEADER *pInfo; + DWORD dwCurrent; + IRecycleBinEnumList recycleBinEnumImpl; + WCHAR szPrefix[ANY_SIZE]; +}; + +static HRESULT STDMETHODCALLTYPE +RecycleBin5Enum_RecycleBinEnumList_QueryInterface( + IN IRecycleBinEnumList *This, + IN REFIID riid, + OUT void **ppvObject) +{ + struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); + + if (!ppvObject) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppvObject = &s->recycleBinEnumImpl; + else if (IsEqualIID(riid, &IID_IRecycleBinEnumList)) + *ppvObject = &s->recycleBinEnumImpl; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef(This); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE +RecycleBin5Enum_RecycleBinEnumList_AddRef( + IN IRecycleBinEnumList *This) +{ + struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); + ULONG refCount = InterlockedIncrement((PLONG)&s->ref); + return refCount; +} + +static ULONG STDMETHODCALLTYPE +RecycleBin5Enum_RecycleBinEnumList_Release( + IN IRecycleBinEnumList *This) +{ + struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); + ULONG refCount; + + if (!This) + return E_POINTER; + + refCount = InterlockedDecrement((PLONG)&s->ref); + + if (refCount == 0) + { + IRecycleBin5_OnClosing(s->recycleBin, This); + UnmapViewOfFile(s->pInfo); + IRecycleBin5_Release(s->recycleBin); + CoTaskMemFree(s); + } + + return refCount; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5Enum_RecycleBinEnumList_Next( + IRecycleBinEnumList *This, + IN DWORD celt, + IN OUT IRecycleBinFile **rgelt, + OUT DWORD *pceltFetched) +{ + struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); + ULARGE_INTEGER FileSize; + INFO2_HEADER *pHeader = s->pInfo; + DELETED_FILE_RECORD *pDeletedFile; + DWORD fetched = 0, i; + DWORD dwEntries; + HRESULT hr; + + if (!rgelt) + return E_POINTER; + if (!pceltFetched && celt > 1) + return E_INVALIDARG; + + FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart); + if (FileSize.u.LowPart == 0) + return HRESULT_FROM_WIN32(GetLastError()); + dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)); + + i = s->dwCurrent; + pDeletedFile = (DELETED_FILE_RECORD *)(pHeader + 1) + i; + for (; i < dwEntries && fetched < celt; i++) + { + hr = RecycleBin5_File_Constructor(s->recycleBin, s->szPrefix, pDeletedFile, &rgelt[fetched]); + if (!SUCCEEDED(hr)) + { + for (i = 0; i < fetched; i++) + IRecycleBinFile_Release(rgelt[i]); + return hr; + } + pDeletedFile++; + fetched++; + } + + s->dwCurrent = i; + if (pceltFetched) + *pceltFetched = fetched; + if (fetched == celt) + return S_OK; + else + return S_FALSE; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5Enum_RecycleBinEnumList_Skip( + IN IRecycleBinEnumList *This, + IN DWORD celt) +{ + struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); + s->dwCurrent += celt; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +RecycleBin5Enum_RecycleBinEnumList_Reset( + IN IRecycleBinEnumList *This) +{ + struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); + s->dwCurrent = 0; + return S_OK; +} + +CONST_VTBL struct IRecycleBinEnumListVtbl RecycleBin5EnumVtbl = +{ + RecycleBin5Enum_RecycleBinEnumList_QueryInterface, + RecycleBin5Enum_RecycleBinEnumList_AddRef, + RecycleBin5Enum_RecycleBinEnumList_Release, + RecycleBin5Enum_RecycleBinEnumList_Next, + RecycleBin5Enum_RecycleBinEnumList_Skip, + RecycleBin5Enum_RecycleBinEnumList_Reset, +}; + +HRESULT +RecycleBin5_Enumerator_Constructor( + IN IRecycleBin5 *prb, + IN HANDLE hInfo, + IN HANDLE hInfoMapped, + IN LPCWSTR szPrefix, + OUT IUnknown **ppUnknown) +{ + struct RecycleBin5Enum *s = NULL; + SIZE_T Needed; + + if (!ppUnknown) + return E_POINTER; + + Needed = (wcslen(szPrefix) + 1) * sizeof(WCHAR); + + s = CoTaskMemAlloc(sizeof(struct RecycleBin5Enum) + Needed); + if (!s) + return E_OUTOFMEMORY; + ZeroMemory(s, sizeof(struct RecycleBin5Enum) + Needed); + s->recycleBinEnumImpl.lpVtbl = &RecycleBin5EnumVtbl; + s->ref = 1; + s->recycleBin = prb; + wcscpy(s->szPrefix, szPrefix); + s->hInfo = hInfo; + s->pInfo = MapViewOfFile(hInfoMapped, FILE_MAP_READ, 0, 0, 0); + if (!s->pInfo) + { + CoTaskMemFree(s); + return HRESULT_FROM_WIN32(GetLastError()); + } + if (s->pInfo->dwVersion != 5 || s->pInfo->dwRecordSize != sizeof(DELETED_FILE_RECORD)) + { + UnmapViewOfFile(s->pInfo); + CoTaskMemFree(s); + return E_FAIL; + } + IRecycleBin5_AddRef(s->recycleBin); + *ppUnknown = (IUnknown *)&s->recycleBinEnumImpl; + + return S_OK; +} Propchange: trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c ------------------------------------------------------------------------------ svn:eol-style = native Removed: trunk/reactos/lib/recyclebin/refcount.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/refcount.c?…
============================================================================== --- trunk/reactos/lib/recyclebin/refcount.c (original) +++ trunk/reactos/lib/recyclebin/refcount.c (removed) @@ -1,42 +1,0 @@ -/* - * PROJECT: Recycle bin management - * LICENSE: GPL v2 - See COPYING in the top level directory - * FILE: lib/recyclebin/openclose.c - * PURPOSE: Do reference counting on objects - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin(a)reactos.org) - */ - -#include "recyclebin_private.h" - -BOOL -InitializeHandle( - IN PREFCOUNT_DATA pData, - IN PDESTROY_DATA pFnClose OPTIONAL) -{ - pData->ReferenceCount = 1; - pData->Close = pFnClose; - return TRUE; -} - -BOOL -ReferenceHandle( - IN PREFCOUNT_DATA pData) -{ - pData->ReferenceCount++; - return TRUE; -} - -BOOL -DereferenceHandle( - IN PREFCOUNT_DATA pData) -{ - pData->ReferenceCount--; - if (pData->ReferenceCount == 0) - { - if (pData->Close) - return pData->Close(pData); - else - return TRUE; - } - return TRUE; -}
17 years, 1 month
1
0
0
0
[hpoussin] 29997: Add .ndi extension as it is usually done in network driver .inf files Clean up TCP/IP service installation, by letting setupapi do most of the work
by hpoussin@svn.reactos.org
Author: hpoussin Date: Wed Oct 31 11:57:13 2007 New Revision: 29997 URL:
http://svn.reactos.org/svn/reactos?rev=29997&view=rev
Log: Add .ndi extension as it is usually done in network driver .inf files Clean up TCP/IP service installation, by letting setupapi do most of the work Modified: trunk/reactos/media/inf/netamd.inf trunk/reactos/media/inf/netisa.inf trunk/reactos/media/inf/netrtpnt.inf trunk/reactos/media/inf/nettcpip.inf Modified: trunk/reactos/media/inf/netamd.inf URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/inf/netamd.inf?rev=2…
============================================================================== --- trunk/reactos/media/inf/netamd.inf (original) +++ trunk/reactos/media/inf/netamd.inf Wed Oct 31 11:57:13 2007 @@ -18,11 +18,11 @@ %AMDMfg% = AMDMfg [AMDMfg] -%PCNET.DeviceDesc% = PCNet_Inst,PCI\VEN_1022&DEV_2000 +%PCNET.DeviceDesc% = PCNet_Inst.ndi,PCI\VEN_1022&DEV_2000 ;----------------------------- PCNET DRIVER ----------------------------- -[PCNet_Inst.NT] +[PCNet_Inst.ndi.NT] Characteristics = 0x4 ; NCF_PHYSICAL BusType = 5 ; PCIBus AddReg = PCNet_AddReg.NT @@ -43,7 +43,7 @@ [PCNet_CopyFiles.NT] pcnet.sys -[PCNet_Inst.NT.Services] +[PCNet_Inst.ndi.NT.Services] AddService = PCNet, 0x00000002, PCNet_Service_Inst [PCNet_Service_Inst] Modified: trunk/reactos/media/inf/netisa.inf URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/inf/netisa.inf?rev=2…
============================================================================== --- trunk/reactos/media/inf/netisa.inf (original) +++ trunk/reactos/media/inf/netisa.inf Wed Oct 31 11:57:13 2007 @@ -18,11 +18,11 @@ %GenericMfg% = GenericMfg [GenericMfg] -%*PNP80D6.DeviceDesc% = NE2000_Inst,*PNP80D6 +%*PNP80D6.DeviceDesc% = NE2000_Inst.ndi,*PNP80D6 ;---------------------------- NE2000 DRIVER ----------------------------- -[NE2000_Inst.NT] +[NE2000_Inst.ndi.NT] Characteristics = 0x4 ; NCF_PHYSICAL BusType = 14 ; PNPIsaBus AddReg = NE2000_AddReg.NT @@ -36,7 +36,7 @@ [NE2000_CopyFiles.NT] ne2000.sys -[NE2000_Inst.NT.Services] +[NE2000_Inst.ndi.NT.Services] AddService = ne2000, 0x00000002, ne2000_Service_Inst [ne2000_Service_Inst] Modified: trunk/reactos/media/inf/netrtpnt.inf URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/inf/netrtpnt.inf?rev…
============================================================================== --- trunk/reactos/media/inf/netrtpnt.inf (original) +++ trunk/reactos/media/inf/netrtpnt.inf Wed Oct 31 11:57:13 2007 @@ -18,11 +18,11 @@ %RealtekMfg% = RealtekMfg [RealtekMfg] -%PCI\VEN_10EC&DEV_8029.DeviceDesc% = NE2000_Inst,PCI\VEN_10EC&DEV_8029 +%PCI\VEN_10EC&DEV_8029.DeviceDesc% = NE2000_Inst.ndi,PCI\VEN_10EC&DEV_8029 ;---------------------------- NE2000 DRIVER ----------------------------- -[NE2000_Inst.NT] +[NE2000_Inst.ndi.NT] Characteristics = 0x4 ; NCF_PHYSICAL BusType = 5 ; PCIBus AddReg = NE2000_AddReg.NT @@ -36,7 +36,7 @@ [NE2000_CopyFiles.NT] ne2000.sys -[NE2000_Inst.NT.Services] +[NE2000_Inst.ndi.NT.Services] AddService = ne2000, 0x00000002, ne2000_Service_Inst [ne2000_Service_Inst] Modified: trunk/reactos/media/inf/nettcpip.inf URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/inf/nettcpip.inf?rev…
============================================================================== --- trunk/reactos/media/inf/nettcpip.inf (original) +++ trunk/reactos/media/inf/nettcpip.inf Wed Oct 31 11:57:13 2007 @@ -14,9 +14,9 @@ ;----------------------------- TCP/IP DRIVER ---------------------------- [MS_TCPIP.PrimaryInstall] -AddReg = TCPIP_AddReg.NT +AddReg = TCPIP_AddReg_Global.NT -[TCPIP_AddReg.NT] +[TCPIP_AddReg_Global.NT] ; The following entries should be generated from .inf files during installation ; TCPIP Protocol HKLM,"SYSTEM\CurrentControlSet\Control\Network\{4D36E975-E325-11CE-BFC1-08002BE10318}\{RandomProtocolGUID_TCPIP}","Characteristics",0x00010001,0x00000080 @@ -29,24 +29,10 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Network\{4D36E975-E325-11CE-BFC1-08002BE10318}\{RandomProtocolGUID_TCPIP}\Ndi","Service",0x00000000,"Tcpip" ; TCP/IP driver -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","ErrorControl",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","Group",0x00000000,"PNP_TDI" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","ImagePath",0x00020000,"system32\drivers\tcpip.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","Start",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","Type",0x00010001,0x00000001 ; NOTE: These settings should be added by the network setup ; These bindings are of the windows 2000 type, and will probably need to be ; twiddled to get 3rd-party network-related software to work. ; NT4 puts additional stuff in the Bind, Export, and Route values. -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","DataBasePath",0x00010000,"DataBasePath" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","Domain",0x00010000,"" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","Hostname",0x00010000,"ROSHost" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","NameServer",0x00010000,"0.0.0.0" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","ForwardBroadcasts",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","IPEnableRouter",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","SearchList",0x00010000,"" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","EnableSecurityFilters",0x00010001,0x00000000 -;HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\PersistentRoutes",,0x00000010 HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\WinSock","UseDelayedAcceptance",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\WinSock","MaxSockAddrLength",0x00010001,0x00000010 HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\WinSock","MinSockAddrLength",0x00010001,0x00000010 @@ -54,8 +40,29 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\WinSock","Mapping",0x00000001,0c,00,00,00,03,00,00,00,02,00,00,00,01,00,00,00,06,00,00,00,02,00,00,00,01,00,00,00,00,00,00,00,02,00,00,00,00,00,00,00,06,00,00,00,00,00,00,00,00,00,00,00,06,00,00,00,00,00,00,00,01,00,00,00,06,00,00,00,02,00,00,00,02,00,00,00,11,00,00,00,02,00,00,00,02,00,00,00,00,00,00,00,02,00,00,00,00,00,00,00,11,00,00,00,00,00,00,00,00,00,00,00,11,00,00,00,00,00,00,00,02,00,00,00,11,00,00,00,02,00,00,00,03,00,00,00,00,00,00,00,02,00,00,00,03,00,00,00,01,00,00,00 HKLM,"SYSTEM\CurrentControlSet\Services\Winsock\Parameters","Transports",0x00010000,"Tcpip" +[MS_TCPIP.PrimaryInstall.Services] +AddService = Tcpip, , tcpip_Service_Inst + +[tcpip_Service_Inst] +ServiceType = 1 +StartType = 1 +ErrorControl = 1 +ServiceBinary = %12%\tcpip.sys +LoadOrderGroup = PNP_TDI +AddReg = tcpip_AddReg + +[tcpip_AddReg] +HKR,"Parameters","DataBasePath",0x00010000,"DataBasePath" +HKR,"Parameters","Domain",0x00010000,"" +HKR,"Parameters","Hostname",0x00010000,"ROSHost" +HKR,"Parameters","NameServer",0x00010000,"0.0.0.0" +HKR,"Parameters","ForwardBroadcasts",0x00010001,0x00000000 +HKR,"Parameters","IPEnableRouter",0x00010001,0x00000000 +HKR,"Parameters","SearchList",0x00010000,"" +HKR,"Parameters","EnableSecurityFilters",0x00010001,0x00000000 +;HKR,"Parameters","PersistentRoutes",,0x00000010 + ;-------------------------------- STRINGS ------------------------------- [Strings] ReactOS = "ReactOS Team" -
17 years, 1 month
1
0
0
0
[hpoussin] 29996: Fix typo: "SourceDiskFiles" -> "SourceDisksFiles" Add more drivers to load in txtsetup.sif
by hpoussin@svn.reactos.org
Author: hpoussin Date: Wed Oct 31 11:56:24 2007 New Revision: 29996 URL:
http://svn.reactos.org/svn/reactos?rev=29996&view=rev
Log: Fix typo: "SourceDiskFiles" -> "SourceDisksFiles" Add more drivers to load in txtsetup.sif Modified: trunk/reactos/boot/bootdata/txtsetup.sif trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c Modified: trunk/reactos/boot/bootdata/txtsetup.sif URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/txtsetup.sif…
============================================================================== --- trunk/reactos/boot/bootdata/txtsetup.sif (original) +++ trunk/reactos/boot/bootdata/txtsetup.sif Wed Oct 31 11:56:24 2007 @@ -11,7 +11,9 @@ 6 = media\fonts 7 = bin -[SourceDiskFiles] +[SourceDisksFiles] +atapi.sys=,,,,,,x +buslogic.sys=,,,,,,x ;acpi.sys=,,,,,,x ;isapnp.sys=,,,,,,x ;pci.sys=,,,,,,x Modified: trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/react…
============================================================================== --- trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c (original) +++ trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c Wed Oct 31 11:56:24 2007 @@ -283,9 +283,6 @@ printf("Failed to get load options\n"); return; } -#if 0 - printf("LoadOptions: '%s'\n", LoadOptions); -#endif /* Set kernel command line */ MachDiskGetBootPath(reactos_kernel_cmdline, sizeof(reactos_kernel_cmdline)); @@ -311,13 +308,6 @@ Base = FrLdrCreateModule ("HARDWARE"); RegExportBinaryHive (L"\\Registry\\Machine\\HARDWARE", (PVOID)Base, &Size); FrLdrCloseModule (Base, Size); - -#if 0 - printf("Base: %x\n", Base); - printf("Size: %u\n", Size); - printf("*** System stopped ***\n"); -for(;;); -#endif /* Insert boot disk 2 */ if (MachDiskBootingFromFloppy()) @@ -410,21 +400,13 @@ return; } - /* Load atapi.sys (depends on hardware detection) */ - if (!LoadDriver(SourcePath, "atapi.sys")) - return; - - /* Load buslogic.sys (depends on hardware detection) */ - if (!LoadDriver(SourcePath, "buslogic.sys")) - return; - /* Load vfatfs.sys (could be loaded by the setup prog!) */ if (!LoadDriver(SourcePath, "vfatfs.sys")) return; /* Load additional files specified in txtsetup.inf */ if (InfFindFirstLine(InfHandle, - "SourceDiskFiles", + "SourceDisksFiles", NULL, &InfContext)) {
17 years, 1 month
1
0
0
0
[hpoussin] 29995: Fix indentation
by hpoussin@svn.reactos.org
Author: hpoussin Date: Wed Oct 31 11:40:46 2007 New Revision: 29995 URL:
http://svn.reactos.org/svn/reactos?rev=29995&view=rev
Log: Fix indentation Modified: trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp Modified: trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rbuild/backend/mingw…
============================================================================== --- trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp (original) +++ trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp Wed Oct 31 11:40:46 2007 @@ -947,10 +947,10 @@ NUL ); fp = popen ( versionCommand.c_str () , "r" ); for( i = 0; - ( i < 80 ) && - ( feof ( fp ) == 0 && - ( ( ch = fgetc( fp ) ) != -1 ) ); - i++ ) + ( i < 80 ) && + ( feof ( fp ) == 0 && + ( ( ch = fgetc( fp ) ) != -1 ) ); + i++ ) { buffer[i] = (char) ch; }
17 years, 1 month
1
0
0
0
[hpoussin] 29994: Link xcopy to wine library, as it is using wine debug macros
by hpoussin@svn.reactos.org
Author: hpoussin Date: Wed Oct 31 11:08:00 2007 New Revision: 29994 URL:
http://svn.reactos.org/svn/reactos?rev=29994&view=rev
Log: Link xcopy to wine library, as it is using wine debug macros Modified: trunk/reactos/base/applications/cmdutils/xcopy/xcopy.rbuild Modified: trunk/reactos/base/applications/cmdutils/xcopy/xcopy.rbuild URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
============================================================================== --- trunk/reactos/base/applications/cmdutils/xcopy/xcopy.rbuild (original) +++ trunk/reactos/base/applications/cmdutils/xcopy/xcopy.rbuild Wed Oct 31 11:08:00 2007 @@ -2,6 +2,7 @@ <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd"> <module name="xcopy" type="win32cui" installbase="system32" installname="xcopy.exe" allowwarnings="true" unicode="true"> <include base="xcopy">.</include> + <library>wine</library> <library>kernel32</library> <library>advapi32</library> <library>user32</library>
17 years, 1 month
1
0
0
0
[jimtabor] 29993: Fix gdi init so it can support batch. Used wrong limit source.
by jimtabor@svn.reactos.org
Author: jimtabor Date: Wed Oct 31 05:48:54 2007 New Revision: 29993 URL:
http://svn.reactos.org/svn/reactos?rev=29993&view=rev
Log: Fix gdi init so it can support batch. Used wrong limit source. Modified: trunk/reactos/dll/win32/gdi32/main/dllmain.c trunk/reactos/include/ndk/pstypes.h trunk/reactos/subsystems/win32/win32k/main/dllmain.c Modified: trunk/reactos/dll/win32/gdi32/main/dllmain.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/main/dllma…
============================================================================== --- trunk/reactos/dll/win32/gdi32/main/dllmain.c (original) +++ trunk/reactos/dll/win32/gdi32/main/dllmain.c Wed Oct 31 05:48:54 2007 @@ -37,7 +37,7 @@ /* map the gdi handle table to user space */ GdiHandleTable = NtCurrentTeb()->ProcessEnvironmentBlock->GdiSharedHandleTable; CurrentProcessId = NtCurrentTeb()->Cid.UniqueProcess; - GDI_BatchLimit = NtCurrentTeb()->GdiBatchCount; + GDI_BatchLimit = (DWORD) NtCurrentTeb()->ProcessEnvironmentBlock->GdiDCAttributeList; } @@ -59,23 +59,21 @@ break; case DLL_THREAD_ATTACH: + NtCurrentTeb()->GdiTebBatch.Offset = 0; + NtCurrentTeb()->GdiBatchCount = 0; break; default: return FALSE; } -#if 0 - /* FIXME: working teb handling needed */ - NtCurrentTeb()->GdiTebBatch.Offset = 0; - NtCurrentTeb()->GdiBatchCount = 0; -#endif // Very simple, the list will fill itself as it is needed. if(!SetStockObjects) { RtlZeroMemory( &stock_objects, NB_STOCK_OBJECTS); //Assume Ros is dirty. SetStockObjects = TRUE; } + return TRUE; } Modified: trunk/reactos/include/ndk/pstypes.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/pstypes.h?rev=…
============================================================================== --- trunk/reactos/include/ndk/pstypes.h (original) +++ trunk/reactos/include/ndk/pstypes.h Wed Oct 31 05:48:54 2007 @@ -627,7 +627,7 @@ PVOID* ProcessHeaps; PVOID GdiSharedHandleTable; PVOID ProcessStarterHelper; - PVOID GdiDCAttributeList; + ULONG GdiDCAttributeList; #if (NTDDI_VERSION >= NTDDI_LONGHORN) struct _RTL_CRITICAL_SECTION *LoaderLock; #else Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ma…
============================================================================== --- trunk/reactos/subsystems/win32/win32k/main/dllmain.c (original) +++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c Wed Oct 31 05:48:54 2007 @@ -117,6 +117,7 @@ { /* map the gdi handle table to user land */ Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(GdiTableSection, Process); + Process->Peb->GdiDCAttributeList = 5; } /* setup process flags */
17 years, 1 month
1
0
0
0
[jimtabor] 29992: - Add gdi batching command structures. - Add additional region clipping data types to Dc_Attr.
by jimtabor@svn.reactos.org
Author: jimtabor Date: Wed Oct 31 04:47:54 2007 New Revision: 29992 URL:
http://svn.reactos.org/svn/reactos?rev=29992&view=rev
Log: - Add gdi batching command structures. - Add additional region clipping data types to Dc_Attr. Modified: trunk/reactos/include/reactos/win32k/ntgdihdl.h trunk/reactos/include/reactos/win32k/ntgdityp.h Modified: trunk/reactos/include/reactos/win32k/ntgdihdl.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntg…
============================================================================== --- trunk/reactos/include/reactos/win32k/ntgdihdl.h (original) +++ trunk/reactos/include/reactos/win32k/ntgdihdl.h Wed Oct 31 04:47:54 2007 @@ -281,6 +281,11 @@ SIZEL szlVirtualDeviceSize; POINTL ptlBrushOrigin; RGNATTR VisRectRegion; + FLONG RgnFlags; + COLORREF crRgnBgndClr; + ULONG ulRgnBgndClr; + HANDLE hRgnbrush; + HANDLE hRgnpen; } DC_ATTR, *PDC_ATTR; #endif Modified: trunk/reactos/include/reactos/win32k/ntgdityp.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntg…
============================================================================== --- trunk/reactos/include/reactos/win32k/ntgdityp.h (original) +++ trunk/reactos/include/reactos/win32k/ntgdityp.h Wed Oct 31 04:47:54 2007 @@ -176,5 +176,110 @@ ULONG l; } gxf_long; - +// +// GDI Batch structures. +// +typedef struct _GDIBATCHHDR +{ + SHORT Size; + SHORT Cmd; +} GDIBATCHHDR, *PGDIBATCHHDR; + +typedef struct _GDIBSPATBLT +{ + GDIBATCHHDR gbHdr; + int nXLeft; + int nYLeft; + int nWidth; + int nHeight; + HANDLE hbrush; + DWORD dwRop; + COLORREF crForegroundClr; + COLORREF crBackgroundClr; + COLORREF crBrushClr; + INT IcmBrushColor; + POINTL ptlViewportOrg; + ULONG ulForegroundClr; + ULONG ulBackgroundClr; + ULONG ulBrushClr; +} GDIBSPATBLT, *PGDIBSPATBLT; + +#ifndef _NTUSRTYP_ +typedef struct _PATRECT +{ + RECT r; + HBRUSH hBrush; +} PATRECT, * PPATRECT; #endif + +typedef struct _GDIBSPPATBLT +{ + GDIBATCHHDR gbHdr; + DWORD rop4; + DWORD Mode; + DWORD Count; + COLORREF crForegroundClr; + COLORREF crBackgroundClr; + COLORREF crBrushClr; + ULONG ulForegroundClr; + ULONG ulBackgroundClr; + ULONG ulBrushClr; + POINTL ptlViewportOrg; + PATRECT pRect; // POLYPATBLT +} GDIBSPPATBLT, *PGDIBSPPATBLT; + +typedef struct _GDIBSTEXTOUT +{ + GDIBATCHHDR gbHdr; + COLORREF crForegroundClr; + COLORREF crBackgroundClr; + LONG lmBkMode; + ULONG ulForegroundClr; + ULONG ulBackgroundClr; + int x; + int y; + UINT Options; + RECT Rect; + DWORD iCS_CP; + UINT cbCount; + UINT Size; + HANDLE hlfntNew; + FLONG flTextAlign; + POINTL ptlViewportOrg; + CHAR String[1]; +} GDIBSTEXTOUT, *PGDIBSTEXTOUT; + +typedef struct _GDIBSEXTTEXTOUT +{ + GDIBATCHHDR gbHdr; + UINT Count; + UINT Options; + RECT Rect; + POINTL ptlViewportOrg; + ULONG ulBackgroundClr; +} GDIBSEXTTEXTOUT, *PGDIBSEXTTEXTOUT; + +typedef struct _GDIBSSETBRHORG +{ + GDIBATCHHDR gbHdr; + POINTL ptlBrushOrigin; +} GDIBSSETBRHORG, *PGDIBSSETBRHORG; + +typedef struct _GDIBSEXTSELCLPRGN +{ + GDIBATCHHDR gbHdr; + int fnMode; + HANDLE hbrush; + HANDLE hpen; + COLORREF crBackgroundClr; + ULONG ulBackgroundClr; +} GDIBSEXTSELCLPRGN, *PGDIBSEXTSELCLPRGN; +// +// Use with GdiBCSelObj, GdiBCDelObj and GdiBCDelRgn. +typedef struct _GDIBSOBJECT +{ + GDIBATCHHDR gbHdr; + HGDIOBJ hgdiobj; +} GDIBSOBJJECT, *PGDIBSOBJECT; + +#endif
17 years, 1 month
1
0
0
0
← Newer
1
2
3
4
5
6
7
...
71
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Results per page:
10
25
50
100
200