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
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 2009
----- 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
26 participants
641 discussions
Start a n
N
ew thread
[fireball] 43649: - Fix dgorbachev's copypasta.
by fireball@svn.reactos.org
Author: fireball Date: Tue Oct 20 16:46:02 2009 New Revision: 43649 URL:
http://svn.reactos.org/svn/reactos?rev=43649&view=rev
Log: - Fix dgorbachev's copypasta. Modified: trunk/reactos/lib/atl/atlbase.h Modified: trunk/reactos/lib/atl/atlbase.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlbase.h?rev=4364…
============================================================================== --- trunk/reactos/lib/atl/atlbase.h [iso-8859-1] (original) +++ trunk/reactos/lib/atl/atlbase.h [iso-8859-1] Tue Oct 20 16:46:02 2009 @@ -248,9 +248,9 @@ { return ( ((unsigned long *)&rguid1)[0] == ((unsigned long *)&rguid2)[0] && - ((unsigned long *)&rguid1)[1] == ((unsigned long *)&rguid1)[1] && - ((unsigned long *)&rguid1)[2] == ((unsigned long *)&rguid1)[2] && - ((unsigned long *)&rguid1)[3] == ((unsigned long *)&rguid1)[3]); + ((unsigned long *)&rguid1)[1] == ((unsigned long *)&rguid2)[1] && + ((unsigned long *)&rguid1)[2] == ((unsigned long *)&rguid2)[2] && + ((unsigned long *)&rguid1)[3] == ((unsigned long *)&rguid2)[3]); } class CComMultiThreadModelNoCS
14 years, 11 months
1
0
0
0
[gadamopoulos] 43648: Fix two user32 resource tests
by gadamopoulos@svn.reactos.org
Author: gadamopoulos Date: Tue Oct 20 16:42:08 2009 New Revision: 43648 URL:
http://svn.reactos.org/svn/reactos?rev=43648&view=rev
Log: Fix two user32 resource tests Modified: trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c Modified: trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c [iso-8859-1] Tue Oct 20 16:42:08 2009 @@ -384,6 +384,15 @@ { Accel->Table[Index].key = Entries[Index].key; } + else + { + RtlMultiByteToUnicodeN(&Accel->Table[Index].key, + sizeof(WCHAR), + NULL, + (PCSTR)&Entries[Index].key, + sizeof(CHAR)); + } + Accel->Table[Index].cmd = Entries[Index].cmd; }
14 years, 11 months
1
0
0
0
[dgorbachev] 43647: Fix build.
by dgorbachev@svn.reactos.org
Author: dgorbachev Date: Tue Oct 20 16:33:31 2009 New Revision: 43647 URL:
http://svn.reactos.org/svn/reactos?rev=43647&view=rev
Log: Fix build. Modified: trunk/reactos/lib/atl/atlbase.h Modified: trunk/reactos/lib/atl/atlbase.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlbase.h?rev=4364…
============================================================================== --- trunk/reactos/lib/atl/atlbase.h [iso-8859-1] (original) +++ trunk/reactos/lib/atl/atlbase.h [iso-8859-1] Tue Oct 20 16:33:31 2009 @@ -244,6 +244,15 @@ ((unsigned long *)&rguid1)[3] == 0x46000000); } +inline BOOL WINAPI InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2) +{ + return ( + ((unsigned long *)&rguid1)[0] == ((unsigned long *)&rguid2)[0] && + ((unsigned long *)&rguid1)[1] == ((unsigned long *)&rguid1)[1] && + ((unsigned long *)&rguid1)[2] == ((unsigned long *)&rguid1)[2] && + ((unsigned long *)&rguid1)[3] == ((unsigned long *)&rguid1)[3]); +} + class CComMultiThreadModelNoCS { public:
14 years, 11 months
1
0
0
0
[fireball] 43646: [fastfat_new] - Implement root directory open operation. - Add OpenCount counter to FCB.
by fireball@svn.reactos.org
Author: fireball Date: Tue Oct 20 14:51:13 2009 New Revision: 43646 URL:
http://svn.reactos.org/svn/reactos?rev=43646&view=rev
Log: [fastfat_new] - Implement root directory open operation. - Add OpenCount counter to FCB. Modified: trunk/reactos/drivers/filesystems/fastfat_new/create.c trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h Modified: trunk/reactos/drivers/filesystems/fastfat_new/create.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] Tue Oct 20 14:51:13 2009 @@ -23,10 +23,64 @@ IN ULONG CreateDisposition) { IO_STATUS_BLOCK Iosb; - - DPRINT1("Opening root directory\n"); - - Iosb.Status = STATUS_NOT_IMPLEMENTED; + PFCB Dcb; + NTSTATUS Status; + PCCB Ccb; + + /* Reference our DCB */ + Dcb = Vcb->RootDcb; + + DPRINT("Opening root directory\n"); + + /* Exclusively lock this DCB */ + (VOID)FatAcquireExclusiveFcb(IrpContext, Dcb); + + do + { + /* Validate parameters */ + if (CreateDisposition != FILE_OPEN && + CreateDisposition != FILE_OPEN_IF) + { + Iosb.Status = STATUS_ACCESS_DENIED; + break; + } + + // TODO: Check file access + + /* Is it a first time open? */ + if (Dcb->OpenCount == 0) + { + /* Set share access */ + IoSetShareAccess(*DesiredAccess, + ShareAccess, + FileObject, + &Dcb->ShareAccess); + } + else + { + /* Check share access */ + Status = IoCheckShareAccess(*DesiredAccess, + ShareAccess, + FileObject, + &Dcb->ShareAccess, + TRUE); + } + + /* Set file object pointers */ + Ccb = FatCreateCcb(IrpContext); + FatSetFileObject(FileObject, UserDirectoryOpen, Dcb, Ccb); + + /* Increment counters */ + Dcb->OpenCount++; + Vcb->OpenFileCount++; + + /* Set success statuses */ + Iosb.Status = STATUS_SUCCESS; + Iosb.Information = FILE_OPENED; + } while (FALSE); + + /* Release the DCB lock */ + FatReleaseFcb(IrpContext, Dcb); return Iosb; } Modified: trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] Tue Oct 20 14:51:13 2009 @@ -305,6 +305,8 @@ ULONG OutstandingAsyncWrites; /* The outstanding async writes sync event */ PKEVENT OutstandingAsyncEvent; + /* Counters */ + ULONG OpenCount; union { struct
14 years, 11 months
1
0
0
0
[ahill] 43645: [atlnew] - Initial checkin of minimal atl library - To prevent conflicts with wine atl dll, this library is named atlnew
by ahill@svn.reactos.org
Author: ahill Date: Tue Oct 20 14:26:51 2009 New Revision: 43645 URL:
http://svn.reactos.org/svn/reactos?rev=43645&view=rev
Log: [atlnew] - Initial checkin of minimal atl library - To prevent conflicts with wine atl dll, this library is named atlnew Added: trunk/reactos/lib/atl/ trunk/reactos/lib/atl/atl.rbuild (with props) trunk/reactos/lib/atl/atlbase.cpp (with props) trunk/reactos/lib/atl/atlbase.h (with props) trunk/reactos/lib/atl/atlcom.h (with props) trunk/reactos/lib/atl/atlcore.cpp (with props) trunk/reactos/lib/atl/atlcore.h (with props) trunk/reactos/lib/atl/atlwin.h (with props) trunk/reactos/lib/atl/statreg.h (with props) Modified: trunk/reactos/lib/lib.rbuild Added: trunk/reactos/lib/atl/atl.rbuild URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atl.rbuild?rev=436…
============================================================================== --- trunk/reactos/lib/atl/atl.rbuild (added) +++ trunk/reactos/lib/atl/atl.rbuild [iso-8859-1] Tue Oct 20 14:26:51 2009 @@ -1,0 +1,10 @@ +<?xml version="1.0"?> +<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd"> +<module name="atlnew" type="staticlibrary"> + <include base="atlnew">.</include> + <define name="UNICODE" /> + <define name="_UNICODE" /> + <define name="ROS_Headers" /> + <file>atlbase.cpp</file> + <file>atlcore.cpp</file> +</module> Propchange: trunk/reactos/lib/atl/atl.rbuild ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/lib/atl/atlbase.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlbase.cpp?rev=43…
============================================================================== --- trunk/reactos/lib/atl/atlbase.cpp (added) +++ trunk/reactos/lib/atl/atlbase.cpp [iso-8859-1] Tue Oct 20 14:26:51 2009 @@ -1,0 +1,33 @@ +/* + * ReactOS ATL + * + * Copyright 2009 Andrew Hill <ash77(a)reactos.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <windows.h> +#include <tchar.h> +#include <ocidl.h> +#include "atlbase.h" + +namespace ATL +{ + +CAtlBaseModule _AtlBaseModule; +CAtlWinModule _AtlWinModule = CAtlWinModule(); +CAtlComModule _AtlComModule; + +}; // namespace ATL Propchange: trunk/reactos/lib/atl/atlbase.cpp ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/lib/atl/atlbase.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlbase.h?rev=4364…
============================================================================== --- trunk/reactos/lib/atl/atlbase.h (added) +++ trunk/reactos/lib/atl/atlbase.h [iso-8859-1] Tue Oct 20 14:26:51 2009 @@ -1,0 +1,965 @@ +/* + * ReactOS ATL + * + * Copyright 2009 Andrew Hill <ash77(a)reactos.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _atlbase_h +#define _atlbase_h + +#include "atlcore.h" +#include "statreg.h" + +#ifdef _MSC_VER +// It is common to use this in ATL constructors. They only store this for later use, so the usage is safe. +#pragma warning(disable:4355) +#endif + +#ifndef _ATL_PACKING +#define _ATL_PACKING 8 +#endif + +#ifndef _ATL_FREE_THREADED +#ifndef _ATL_APARTMENT_THREADED +#ifndef _ATL_SINGLE_THREADED +#define _ATL_FREE_THREADED +#endif +#endif +#endif + +#ifndef ATLTRY +#define ATLTRY(x) x; +#endif + +#ifdef _ATL_DISABLE_NO_VTABLE +#define ATL_NO_VTABLE +#else +#define ATL_NO_VTABLE __declspec(novtable) +#endif + +#define offsetofclass(base, derived) (reinterpret_cast<DWORD_PTR>(static_cast<base *>(reinterpret_cast<derived *>(_ATL_PACKING))) - _ATL_PACKING) + +extern "C" IMAGE_DOS_HEADER __ImageBase; + +namespace ATL +{ + +class CAtlModule; +class CComModule; +class CAtlComModule; +__declspec(selectany) CAtlModule *_pAtlModule = NULL; +__declspec(selectany) CComModule *_pModule = NULL; +extern CAtlComModule _AtlComModule; + +typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void *pv, REFIID riid, LPVOID *ppv); +typedef LPCTSTR (WINAPI _ATL_DESCRIPTIONFUNC)(); +typedef const struct _ATL_CATMAP_ENTRY * (_ATL_CATMAPFUNC)(); + +struct _ATL_OBJMAP_ENTRY30 +{ + const CLSID *pclsid; + HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister); + _ATL_CREATORFUNC *pfnGetClassObject; + _ATL_CREATORFUNC *pfnCreateInstance; + IUnknown *pCF; + DWORD dwRegister; + _ATL_DESCRIPTIONFUNC *pfnGetObjectDescription; + _ATL_CATMAPFUNC *pfnGetCategoryMap; + void (WINAPI *pfnObjectMain)(bool bStarting); + + HRESULT WINAPI RevokeClassObject() + { + if (dwRegister == 0) + return S_OK; + return CoRevokeClassObject(dwRegister); + } + + HRESULT WINAPI RegisterClassObject(DWORD dwClsContext, DWORD dwFlags) + { + IUnknown *p; + HRESULT hResult; + + p = NULL; + if (pfnGetClassObject == NULL) + return S_OK; + + hResult = pfnGetClassObject(reinterpret_cast<LPVOID *>(pfnCreateInstance), IID_IUnknown, reinterpret_cast<LPVOID *>(&p)); + if (SUCCEEDED(hResult)) + hResult = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister); + + if (p != NULL) + p->Release(); + + return hResult; + } +}; + +typedef _ATL_OBJMAP_ENTRY30 _ATL_OBJMAP_ENTRY; + +typedef void (__stdcall _ATL_TERMFUNC)(DWORD_PTR dw); + +struct _ATL_TERMFUNC_ELEM +{ + _ATL_TERMFUNC *pFunc; + DWORD_PTR dw; + _ATL_TERMFUNC_ELEM *pNext; +}; + +struct _ATL_MODULE70 +{ + UINT cbSize; + LONG m_nLockCnt; + _ATL_TERMFUNC_ELEM *m_pTermFuncs; + CComCriticalSection m_csStaticDataInitAndTypeInfo; +}; +typedef _ATL_MODULE70 _ATL_MODULE; + +typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)(void *pv, REFIID riid, LPVOID *ppv, DWORD_PTR dw); + +#define _ATL_SIMPLEMAPENTRY ((ATL::_ATL_CREATORARGFUNC *)1) + +struct _ATL_INTMAP_ENTRY +{ + const IID *piid; + DWORD_PTR dw; + _ATL_CREATORARGFUNC *pFunc; +}; + +struct _AtlCreateWndData +{ + void *m_pThis; + DWORD m_dwThreadID; + _AtlCreateWndData *m_pNext; +}; + +struct _ATL_COM_MODULE70 +{ + UINT cbSize; + HINSTANCE m_hInstTypeLib; + _ATL_OBJMAP_ENTRY **m_ppAutoObjMapFirst; + _ATL_OBJMAP_ENTRY **m_ppAutoObjMapLast; + CComCriticalSection m_csObjMap; +}; +typedef _ATL_COM_MODULE70 _ATL_COM_MODULE; + +struct _ATL_WIN_MODULE70 +{ + UINT cbSize; + CComCriticalSection m_csWindowCreate; + _AtlCreateWndData *m_pCreateWndList; +#ifdef NOTYET + CSimpleArray<ATOM> m_rgWindowClassAtoms; +#endif +}; +typedef _ATL_WIN_MODULE70 _ATL_WIN_MODULE; + +struct _ATL_REGMAP_ENTRY +{ + LPCOLESTR szKey; + LPCOLESTR szData; +}; + +HRESULT __stdcall AtlWinModuleInit(_ATL_WIN_MODULE *pWinModule); +HRESULT __stdcall AtlWinModuleTerm(_ATL_WIN_MODULE *pWinModule, HINSTANCE hInst); +HRESULT __stdcall AtlInternalQueryInterface(void *pThis, const _ATL_INTMAP_ENTRY *pEntries, REFIID iid, void **ppvObject); +void __stdcall AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE *pWinModule, _AtlCreateWndData *pData, void *pObject); +void *__stdcall AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE *pWinModule); +HRESULT __stdcall AtlComModuleGetClassObject(_ATL_COM_MODULE *pComModule, REFCLSID rclsid, REFIID riid, LPVOID *ppv); + +template<class TLock> +class CComCritSecLock +{ +private: + bool m_bLocked; + TLock &m_cs; +public: + CComCritSecLock(TLock &cs, bool bInitialLock = true) : m_cs(cs) + { + HRESULT hResult; + + m_bLocked = false; + if (bInitialLock) + { + hResult = Lock(); + if (FAILED(hResult)) + { + ATLASSERT(false); + } + } + } + + ~CComCritSecLock() + { + if (m_bLocked) + Unlock(); + } + + HRESULT Lock() + { + HRESULT hResult; + + ATLASSERT(!m_bLocked); + hResult = m_cs.Lock(); + if (FAILED(hResult)) + return hResult; + m_bLocked = true; + + return S_OK; + } + + void Unlock() + { + HRESULT hResult; + + ATLASSERT(m_bLocked); + hResult = m_cs.Unlock(); + if (FAILED(hResult)) + { + ATLASSERT(false); + } + m_bLocked = false; + } +}; + +inline BOOL WINAPI InlineIsEqualUnknown(REFGUID rguid1) +{ + return ( + ((unsigned long *)&rguid1)[0] == 0 && + ((unsigned long *)&rguid1)[1] == 0 && + ((unsigned long *)&rguid1)[2] == 0x000000C0 && + ((unsigned long *)&rguid1)[3] == 0x46000000); +} + +class CComMultiThreadModelNoCS +{ +public: + typedef CComFakeCriticalSection AutoCriticalSection; + typedef CComFakeCriticalSection CriticalSection; + typedef CComMultiThreadModelNoCS ThreadModelNoCS; + typedef CComFakeCriticalSection AutoDeleteCriticalSection; + + static ULONG WINAPI Increment(LPLONG p) + { + return InterlockedIncrement(p); + } + + static ULONG WINAPI Decrement(LPLONG p) + { + return InterlockedDecrement(p); + } +}; + +class CComMultiThreadModel +{ +public: + typedef CComAutoCriticalSection AutoCriticalSection; + typedef CComCriticalSection CriticalSection; + typedef CComMultiThreadModelNoCS ThreadModelNoCS; + typedef CComAutoDeleteCriticalSection AutoDeleteCriticalSection; + + static ULONG WINAPI Increment(LPLONG p) + { + return InterlockedIncrement(p); + } + + static ULONG WINAPI Decrement(LPLONG p) + { + return InterlockedDecrement(p); + } +}; + +class CComSingleThreadModel +{ +public: + typedef CComFakeCriticalSection AutoCriticalSection; + typedef CComFakeCriticalSection CriticalSection; + typedef CComSingleThreadModel ThreadModelNoCS; + typedef CComFakeCriticalSection AutoDeleteCriticalSection; + + static ULONG WINAPI Increment(LPLONG p) + { + return ++*p; + } + + static ULONG WINAPI Decrement(LPLONG p) + { + return --*p; + } +}; + +#if defined(_ATL_FREE_THREADED) + + typedef CComMultiThreadModel CComObjectThreadModel; + typedef CComMultiThreadModel CComGlobalsThreadModel; + +#elif defined(_ATL_APARTMENT_THREADED) + + typedef CComSingleThreadModel CComObjectThreadModel; + typedef CComMultiThreadModel CComGlobalsThreadModel; + +#elif defined(_ATL_SINGLE_THREADED) + + typedef CComSingleThreadModel CComObjectThreadModel; + typedef CComSingleThreadModel CComGlobalsThreadModel; + +#else +#error No threading model +#endif + +class CAtlModule : public _ATL_MODULE +{ +public: + CAtlModule() + { + ATLASSERT(_pAtlModule == NULL); + _pAtlModule = this; + cbSize = sizeof(_ATL_MODULE); + m_nLockCnt = 0; + } + + virtual LONG GetLockCount() + { + return m_nLockCnt; + } + + virtual LONG Lock() + { + return CComGlobalsThreadModel::Increment(&m_nLockCnt); + } + + virtual LONG Unlock() + { + return CComGlobalsThreadModel::Decrement(&m_nLockCnt); + } + + virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* /*pRegistrar*/) = 0; + + HRESULT WINAPI UpdateRegistryFromResource(LPCTSTR lpszRes, BOOL bRegister, struct _ATL_REGMAP_ENTRY *pMapEntries = NULL) + { + CRegObject registrar; + TCHAR modulePath[MAX_PATH]; + HRESULT hResult; + + hResult = CommonInitRegistrar(registrar, modulePath, sizeof(modulePath) / sizeof(modulePath[0]), pMapEntries); + if (FAILED(hResult)) + return hResult; + + if (bRegister != FALSE) + hResult = registrar.ResourceRegisterSz(modulePath, lpszRes, _T("REGISTRY")); + else + hResult = registrar.ResourceUnregisterSz(modulePath, lpszRes, _T("REGISTRY")); + + return hResult; + } + + HRESULT WINAPI UpdateRegistryFromResource(UINT nResID, BOOL bRegister, struct _ATL_REGMAP_ENTRY *pMapEntries = NULL) + { + CRegObject registrar; + TCHAR modulePath[MAX_PATH]; + HRESULT hResult; + + hResult = CommonInitRegistrar(registrar, modulePath, sizeof(modulePath) / sizeof(modulePath[0]), pMapEntries); + if (FAILED(hResult)) + return hResult; + + if (bRegister != FALSE) + hResult = registrar.ResourceRegister(modulePath, nResID, _T("REGISTRY")); + else + hResult = registrar.ResourceRegister(modulePath, nResID, _T("REGISTRY")); + + return hResult; + } + +private: + HRESULT CommonInitRegistrar(CRegObject ®istrar, TCHAR *modulePath, DWORD modulePathCount, struct _ATL_REGMAP_ENTRY *pMapEntries) + { + HINSTANCE hInstance; + DWORD dwFLen; + HRESULT hResult; + + hInstance = _AtlBaseModule.GetModuleInstance(); + dwFLen = GetModuleFileName(hInstance, modulePath, modulePathCount); + if (dwFLen == modulePathCount) + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + else if (dwFLen == 0) + return HRESULT_FROM_WIN32(GetLastError()); + + if (pMapEntries != NULL) + { + while (pMapEntries->szKey != NULL) + { + ATLASSERT(pMapEntries->szData != NULL); + hResult = registrar.AddReplacement(pMapEntries->szKey, pMapEntries->szData); + if (FAILED(hResult)) + return hResult; + pMapEntries++; + } + } + + hResult = AddCommonRGSReplacements(®istrar); + if (FAILED(hResult)) + return hResult; + + hResult = registrar.AddReplacement(_T("Module"), modulePath); + if (FAILED(hResult)) + return hResult; + + hResult = registrar.AddReplacement(_T("Module_Raw"), modulePath); + if (FAILED(hResult)) + return hResult; + + return S_OK; + } +}; + +template <class T> +class CAtlModuleT : public CAtlModule +{ +public: + + virtual HRESULT AddCommonRGSReplacements(IRegistrarBase *pRegistrar) + { + return pRegistrar->AddReplacement(L"APPID", T::GetAppId()); + } + + static LPCOLESTR GetAppId() + { + return L""; + } +}; + +class CAtlComModule : public _ATL_COM_MODULE +{ +public: + CAtlComModule() + { + m_hInstTypeLib = reinterpret_cast<HINSTANCE>(&__ImageBase); + m_ppAutoObjMapFirst = NULL; + m_ppAutoObjMapLast = NULL; + if (FAILED(m_csObjMap.Init())) + { + ATLASSERT(0); + CAtlBaseModule::m_bInitFailed = true; + return; + } + cbSize = sizeof(_ATL_COM_MODULE); + } + + ~CAtlComModule() + { + Term(); + } + + void Term() + { + if (cbSize != 0) + { + ATLASSERT(m_ppAutoObjMapFirst == NULL); + ATLASSERT(m_ppAutoObjMapLast == NULL); + m_csObjMap.Term(); + cbSize = 0; + } + } +}; + +template <class T> +class CAtlDllModuleT : public CAtlModuleT<T> +{ +public: + CAtlDllModuleT() + { + } + + HRESULT DllCanUnloadNow() + { + T *pThis; + + pThis = static_cast<T *>(this); + if (pThis->GetLockCount() == 0) + return S_OK; + return S_FALSE; + } + + HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) + { + T *pThis; + + pThis = static_cast<T *>(this); + return pThis->GetClassObject(rclsid, riid, ppv); + } + + HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) + { + T *pThis; + HRESULT hResult; + + pThis = static_cast<T *>(this); + hResult = pThis->RegisterServer(bRegTypeLib); + return hResult; + } + + HRESULT DllUnregisterServer(BOOL bUnRegTypeLib = TRUE) + { + T *pThis; + HRESULT hResult; + + pThis = static_cast<T *>(this); + hResult = pThis->UnregisterServer(bUnRegTypeLib); + return hResult; + } + + HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) + { + return AtlComModuleGetClassObject(&_AtlComModule, rclsid, riid, ppv); + } +}; + +class CComModule : public CAtlModuleT<CComModule> +{ +public: + _ATL_OBJMAP_ENTRY *m_pObjMap; +public: + CComModule() + { + ATLASSERT(_pModule == NULL); + _pModule = this; + } + + ~CComModule() + { + _pModule = NULL; + } + + HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) + { + _ATL_OBJMAP_ENTRY *objectMapEntry; + HRESULT hResult; + + ATLASSERT(ppv != NULL); + if (ppv == NULL) + return E_POINTER; + hResult = S_OK; + if (m_pObjMap != NULL) + { + objectMapEntry = m_pObjMap; + while (objectMapEntry->pclsid != NULL) + { + if (objectMapEntry->pfnGetClassObject != NULL && InlineIsEqualGUID(rclsid, *objectMapEntry->pclsid) != FALSE) + { + if (objectMapEntry->pCF == NULL) + { + CComCritSecLock<CComCriticalSection> lock(_AtlComModule.m_csObjMap, true); + + if (objectMapEntry->pCF == NULL) + hResult = objectMapEntry->pfnGetClassObject(reinterpret_cast<void *>(objectMapEntry->pfnCreateInstance), IID_IUnknown, reinterpret_cast<LPVOID *>(&objectMapEntry->pCF)); + } + if (objectMapEntry->pCF != NULL) + hResult = objectMapEntry->pCF->QueryInterface(riid, ppv); + break; + } + objectMapEntry++; + } + } + return hResult; + } + + HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID *pCLSID = NULL) + { + _ATL_OBJMAP_ENTRY *objectMapEntry; + HRESULT hResult; + + hResult = S_OK; + objectMapEntry = m_pObjMap; + if (objectMapEntry != NULL) + { + while (objectMapEntry->pclsid != NULL) + { + if (pCLSID == NULL || IsEqualGUID(*pCLSID, *objectMapEntry->pclsid) != FALSE) + { + hResult = objectMapEntry->pfnUpdateRegistry(TRUE); + if (FAILED(hResult)) + break; + } + objectMapEntry++; + } + } + return hResult; + } + + HRESULT UnregisterServer(BOOL bUnRegTypeLib, const CLSID *pCLSID = NULL) + { + _ATL_OBJMAP_ENTRY *objectMapEntry; + HRESULT hResult; + + hResult = S_OK; + objectMapEntry = m_pObjMap; + if (objectMapEntry != NULL) + { + while (objectMapEntry->pclsid != NULL) + { + if (pCLSID == NULL || IsEqualGUID(*pCLSID, *objectMapEntry->pclsid) != FALSE) + { + hResult = objectMapEntry->pfnUpdateRegistry(FALSE); //unregister + if (FAILED(hResult)) + break; + } + objectMapEntry++; + } + } + return hResult; + } + + HRESULT DllCanUnloadNow() + { + if (GetLockCount() == 0) + return S_OK; + return S_FALSE; + } + + HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) + { + return GetClassObject(rclsid, riid, ppv); + } + + HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) + { + return RegisterServer(bRegTypeLib); + } + + HRESULT DllUnregisterServer(BOOL bUnRegTypeLib = TRUE) + { + return UnregisterServer(bUnRegTypeLib); + } + +}; + +class CAtlWinModule : public _ATL_WIN_MODULE +{ +public: + CAtlWinModule() + { + HRESULT hResult; + + hResult = AtlWinModuleInit(this); + if (FAILED(hResult)) + { + CAtlBaseModule::m_bInitFailed = true; + ATLASSERT(0); + } + } + + ~CAtlWinModule() + { + Term(); + } + + void Term() + { + AtlWinModuleTerm(this, _AtlBaseModule.GetModuleInstance()); + } + + void AddCreateWndData(_AtlCreateWndData *pData, void *pObject) + { + AtlWinModuleAddCreateWndData(this, pData, pObject); + } + + void *ExtractCreateWndData() + { + return AtlWinModuleExtractCreateWndData(this); + } +}; + +extern CAtlWinModule _AtlWinModule; + +template<class T> +class CComPtr +{ +public: + T *p; +public: + CComPtr() + { + p = NULL; + } + + CComPtr(T *lp) + { + p = lp; + if (p != NULL) + p->AddRef(); + } + + CComPtr(const CComPtr<T> &lp) + { + p = lp.p; + if (p != NULL) + p->AddRef(); + } + + ~CComPtr() + { + if (p != NULL) + p->Release(); + } + + T *operator = (T *lp) + { + if (p != NULL) + p->Release(); + p = lp; + if (p != NULL) + p->AddRef(); + return *this; + } + + T *operator = (const CComPtr<T> &lp) + { + if (p != NULL) + p->Release(); + p = lp.p; + if (p != NULL) + p->AddRef(); + return *this; + } + + void Release() + { + if (p != NULL) + { + p->Release(); + p = NULL; + } + } + + void Attach(T *lp) + { + if (p != NULL) + p->Release(); + p = lp; + } + + T *Detach() + { + T *saveP; + + saveP = p; + p = NULL; + return saveP; + } + + T **operator & () + { + ATLASSERT(p == NULL); + return &p; + } + + operator T * () + { + return p; + } + + T *operator -> () + { + ATLASSERT(p != NULL); + return p; + } +}; + +class CComBSTR +{ +public: + BSTR m_str; +public: + CComBSTR(LPCOLESTR pSrc) + { + if (pSrc == NULL) + m_str = NULL; + else + m_str = ::SysAllocString(pSrc); + } + ~CComBSTR() + { + ::SysFreeString(m_str); + m_str = NULL; + } +}; + +class CComVariant : public tagVARIANT +{ +public: + CComVariant() + { + ::VariantInit(this); + } + + ~CComVariant() + { + Clear(); + } + + HRESULT Clear() + { + return ::VariantClear(this); + } +}; + +inline HRESULT __stdcall AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID &iid, LPDWORD pdw) +{ + CComPtr<IConnectionPointContainer> container; + CComPtr<IConnectionPoint> connectionPoint; + HRESULT hResult; + + if (pUnkCP == NULL) + return E_INVALIDARG; + hResult = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void **)&container); + if (FAILED(hResult)) + return hResult; + hResult = container->FindConnectionPoint(iid, &connectionPoint); + if (FAILED(hResult)) + return hResult; + return connectionPoint->Advise(pUnk, pdw); +} + +inline HRESULT __stdcall AtlUnadvise(IUnknown *pUnkCP, const IID &iid, DWORD dw) +{ + CComPtr<IConnectionPointContainer> container; + CComPtr<IConnectionPoint> connectionPoint; + HRESULT hResult; + + if (pUnkCP == NULL) + return E_INVALIDARG; + hResult = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void **)&container); + if (FAILED(hResult)) + return hResult; + hResult = container->FindConnectionPoint(iid, &connectionPoint); + if (FAILED(hResult)) + return hResult; + return connectionPoint->Unadvise(dw); +} + +inline HRESULT __stdcall AtlInternalQueryInterface(void *pThis, const _ATL_INTMAP_ENTRY *pEntries, REFIID iid, void **ppvObject) +{ + int i; + IUnknown *resultInterface; + HRESULT hResult; + + ATLASSERT(pThis != NULL && pEntries != NULL); + if (pThis == NULL || pEntries == NULL) + return E_INVALIDARG; + ATLASSERT(ppvObject != NULL); + if (ppvObject == NULL) + return E_POINTER; + + if (InlineIsEqualUnknown(iid)) + { + resultInterface = reinterpret_cast<IUnknown *>(reinterpret_cast<char *>(pThis) + pEntries[0].dw); + *ppvObject = resultInterface; + resultInterface->AddRef(); + return S_OK; + } + + i = 0; + while (pEntries[i].pFunc != 0) + { + if (pEntries[i].piid == NULL || InlineIsEqualGUID(iid, *pEntries[i].piid)) + { + if (pEntries[i].pFunc == reinterpret_cast<_ATL_CREATORARGFUNC *>(1)) + { + ATLASSERT(pEntries[i].piid != NULL); + resultInterface = reinterpret_cast<IUnknown *>(reinterpret_cast<char *>(pThis) + pEntries[i].dw); + *ppvObject = resultInterface; + resultInterface->AddRef(); + return S_OK; + } + else + { + hResult = pEntries[i].pFunc(pThis, iid, ppvObject, 0); + if (hResult == S_OK || (FAILED(hResult) && pEntries[i].piid != NULL)) + return hResult; + } + break; + } + i++; + } + *ppvObject = NULL; + return E_NOINTERFACE; +} + +inline HRESULT __stdcall AtlWinModuleInit(_ATL_WIN_MODULE *pWinModule) +{ + if (pWinModule == NULL) + return E_INVALIDARG; + pWinModule->m_pCreateWndList = NULL; + return pWinModule->m_csWindowCreate.Init(); +} + +inline HRESULT __stdcall AtlWinModuleTerm(_ATL_WIN_MODULE *pWinModule, HINSTANCE hInst) +{ + if (pWinModule == NULL) + return E_INVALIDARG; + pWinModule->m_csWindowCreate.Term(); + return S_OK; +} + +inline void __stdcall AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE *pWinModule, _AtlCreateWndData *pData, void *pObject) +{ + CComCritSecLock<CComCriticalSection> lock(pWinModule->m_csWindowCreate, true); + + ATLASSERT(pWinModule != NULL); + ATLASSERT(pObject != NULL); + + pData->m_pThis = pObject; + pData->m_dwThreadID = ::GetCurrentThreadId(); + pData->m_pNext = pWinModule->m_pCreateWndList; + pWinModule->m_pCreateWndList = pData; +} + +inline void *__stdcall AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE *pWinModule) +{ + CComCritSecLock<CComCriticalSection> lock(pWinModule->m_csWindowCreate, true); + void *result; + _AtlCreateWndData *currentEntry; + _AtlCreateWndData **previousLink; + DWORD threadID; + + ATLASSERT(pWinModule != NULL); + + result = NULL; + threadID = GetCurrentThreadId(); + currentEntry = pWinModule->m_pCreateWndList; + previousLink = &pWinModule->m_pCreateWndList; + while (currentEntry != NULL) + { + if (currentEntry->m_dwThreadID == threadID) + { + *previousLink = currentEntry->m_pNext; + result = currentEntry->m_pThis; + break; + } + previousLink = ¤tEntry->m_pNext; + currentEntry = currentEntry->m_pNext; + } + return result; +} + +}; // namespace ATL + +#ifndef _ATL_NO_AUTOMATIC_NAMESPACE +using namespace ATL; +#endif //!_ATL_NO_AUTOMATIC_NAMESPACE + +#endif // _atlbase_h Propchange: trunk/reactos/lib/atl/atlbase.h ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/lib/atl/atlcom.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlcom.h?rev=43645…
============================================================================== --- trunk/reactos/lib/atl/atlcom.h (added) +++ trunk/reactos/lib/atl/atlcom.h [iso-8859-1] Tue Oct 20 14:26:51 2009 @@ -1,0 +1,1133 @@ +/* + * ReactOS ATL + * + * Copyright 2009 Andrew Hill <ash77(a)reactos.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _atlcom_h +#define _atlcom_h + +namespace ATL +{ + +template <class Base, const IID *piid, class T, class Copy, class ThreadModel = CComObjectThreadModel> +class CComEnum; + +#define DECLARE_CLASSFACTORY_EX(cf) typedef ATL::CComCreator<ATL::CComObjectCached<cf> > _ClassFactoryCreatorClass; +#define DECLARE_CLASSFACTORY() DECLARE_CLASSFACTORY_EX(ATL::CComClassFactory) + +class CComObjectRootBase +{ +public: + long m_dwRef; +public: + CComObjectRootBase() + { + m_dwRef = 0; + } + + ~CComObjectRootBase() + { + } + + void SetVoid(void *) + { + } + + HRESULT _AtlFinalConstruct() + { + return S_OK; + } + + HRESULT FinalConstruct() + { + return S_OK; + } + + void InternalFinalConstructAddRef() + { + } + + void InternalFinalConstructRelease() + { + } + + void FinalRelease() + { + } + + static void WINAPI ObjectMain(bool) + { + } + + static const struct _ATL_CATMAP_ENTRY *GetCategoryMap() + { + return NULL; + } + + static HRESULT WINAPI InternalQueryInterface(void *pThis, const _ATL_INTMAP_ENTRY *pEntries, REFIID iid, void **ppvObject) + { + return AtlInternalQueryInterface(pThis, pEntries, iid, ppvObject); + } + +}; + +template <class ThreadModel> +class CComObjectRootEx : public CComObjectRootBase +{ +private: + typename ThreadModel::AutoDeleteCriticalSection m_critsec; +public: + ~CComObjectRootEx() + { + } + + ULONG InternalAddRef() + { + ATLASSERT(m_dwRef >= 0); + return ThreadModel::Increment(reinterpret_cast<int *>(&m_dwRef)); + } + + ULONG InternalRelease() + { + ATLASSERT(m_dwRef > 0); + return ThreadModel::Decrement(reinterpret_cast<int *>(&m_dwRef)); + } + + void Lock() + { + m_critsec.Lock(); + } + + void Unlock() + { + m_critsec.Unlock(); + } + + HRESULT _AtlInitialConstruct() + { + return m_critsec.Init(); + } +}; + +template <class Base> +class CComObject : public Base +{ +public: + CComObject(void * = NULL) + { + _pAtlModule->Lock(); + } + + virtual ~CComObject() + { + CComObject<Base> *pThis; + + pThis = reinterpret_cast<CComObject<Base> *>(this); + pThis->FinalRelease(); + _pAtlModule->Unlock(); + } + + STDMETHOD_(ULONG, AddRef)() + { + CComObject<Base> *pThis; + + pThis = reinterpret_cast<CComObject<Base> *>(this); + return pThis->InternalAddRef(); + } + + STDMETHOD_(ULONG, Release)() + { + CComObject<Base> *pThis; + ULONG l; + + pThis = reinterpret_cast<CComObject<Base> *>(this); + l = pThis->InternalRelease(); + if (l == 0) + delete this; + return l; + } + + STDMETHOD(QueryInterface)(REFIID iid, void **ppvObject) + { + CComObject<Base> *pThis; + + pThis = reinterpret_cast<CComObject<Base> *>(this); + return pThis->_InternalQueryInterface(iid, ppvObject); + } + + static HRESULT WINAPI CreateInstance(CComObject<Base> **pp) + { + CComObject<Base> *newInstance; + HRESULT hResult; + + ATLASSERT(pp != NULL); + if (pp == NULL) + return E_POINTER; + + hResult = E_OUTOFMEMORY; + newInstance = NULL; + ATLTRY(newInstance = new CComObject<Base>()) + if (newInstance != NULL) + { + newInstance->SetVoid(NULL); + newInstance->InternalFinalConstructAddRef(); + hResult = newInstance->_AtlInitialConstruct(); + if (SUCCEEDED(hResult)) + hResult = newInstance->FinalConstruct(); + if (SUCCEEDED(hResult)) + hResult = newInstance->_AtlFinalConstruct(); + newInstance->InternalFinalConstructRelease(); + if (hResult != S_OK) + { + delete newInstance; + newInstance = NULL; + } + } + *pp = newInstance; + return hResult; + } + + +}; + +template <HRESULT hResult> +class CComFailCreator +{ +public: + static HRESULT WINAPI CreateInstance(void *, REFIID, LPVOID *ppv) + { + ATLASSERT(ppv != NULL); + if (ppv == NULL) + return E_POINTER; + *ppv = NULL; + + return hResult; + } +}; + +template <class T1> +class CComCreator +{ +public: + static HRESULT WINAPI CreateInstance(void *pv, REFIID riid, LPVOID *ppv) + { + T1 *newInstance; + HRESULT hResult; + + ATLASSERT(ppv != NULL); + if (ppv == NULL) + return E_POINTER; + *ppv = NULL; + + hResult = E_OUTOFMEMORY; + newInstance = NULL; + ATLTRY(newInstance = new T1()) + if (newInstance != NULL) + { + newInstance->SetVoid(pv); + newInstance->InternalFinalConstructAddRef(); + hResult = newInstance->_AtlInitialConstruct(); + if (SUCCEEDED(hResult)) + hResult = newInstance->FinalConstruct(); + if (SUCCEEDED(hResult)) + hResult = newInstance->_AtlFinalConstruct(); + newInstance->InternalFinalConstructRelease(); + if (SUCCEEDED(hResult)) + hResult = newInstance->QueryInterface(riid, ppv); + if (FAILED(hResult)) + { + delete newInstance; + newInstance = NULL; + } + } + return hResult; + } +}; + +template <class T1, class T2> +class CComCreator2 +{ +public: + static HRESULT WINAPI CreateInstance(void *pv, REFIID riid, LPVOID *ppv) + { + ATLASSERT(ppv != NULL && ppv != NULL); + + if (pv == NULL) + return T1::CreateInstance(NULL, riid, ppv); + else + return T2::CreateInstance(pv, riid, ppv); + } +}; + +template <class Base> +class CComObjectCached : public Base +{ +public: + CComObjectCached(void * = NULL) + { + } + + STDMETHOD_(ULONG, AddRef)() + { + CComObjectCached<Base> *pThis; + ULONG newRefCount; + + pThis = reinterpret_cast<CComObjectCached<Base>*>(this); + newRefCount = pThis->InternalAddRef(); + if (newRefCount == 2) + _pAtlModule->Lock(); + return newRefCount; + } + + STDMETHOD_(ULONG, Release)() + { + CComObjectCached<Base> *pThis; + ULONG newRefCount; + + pThis = reinterpret_cast<CComObjectCached<Base>*>(this); + newRefCount = pThis->InternalRelease(); + if (newRefCount == 0) + delete this; + else if (newRefCount == 1) + _pAtlModule->Unlock(); + return newRefCount; + } + + STDMETHOD(QueryInterface)(REFIID iid, void **ppvObject) + { + CComObjectCached<Base> *pThis; + + pThis = reinterpret_cast<CComObjectCached<Base>*>(this); + return pThis->_InternalQueryInterface(iid, ppvObject); + } +}; + +#define BEGIN_COM_MAP(x) \ +public: \ + typedef x _ComMapClass; \ + HRESULT _InternalQueryInterface(REFIID iid, void **ppvObject) \ + { \ + return InternalQueryInterface(this, _GetEntries(), iid, ppvObject); \ + } \ + const static ATL::_ATL_INTMAP_ENTRY *WINAPI _GetEntries() \ + { \ + static const ATL::_ATL_INTMAP_ENTRY _entries[] = { + +#define END_COM_MAP() \ + {NULL, 0, 0} \ + }; \ + return _entries; \ + } \ + virtual ULONG STDMETHODCALLTYPE AddRef() = 0; \ + virtual ULONG STDMETHODCALLTYPE Release() = 0; \ + STDMETHOD(QueryInterface)(REFIID, void **) = 0; + +#define COM_INTERFACE_ENTRY_IID(iid, x) \ + {&iid, offsetofclass(x, _ComMapClass), _ATL_SIMPLEMAPENTRY}, + +#define COM_INTERFACE_ENTRY2_IID(iid, x, x2) \ + {&iid, \ + reinterpret_cast<DWORD_PTR>(static_cast<x *>(static_cast<x2 *>(reinterpret_cast<_ComMapClass *>(_ATL_PACKING)))) - _ATL_PACKING, \ + _ATL_SIMPLEMAPENTRY}, + +#define COM_INTERFACE_ENTRY_BREAK(x) \ + {&_ATL_IIDOF(x), \ + NULL, \ + _Break}, // Break is a function that issues int 3. + +#define COM_INTERFACE_ENTRY_NOINTERFACE(x) \ + {&_ATL_IIDOF(x), \ + NULL, \ + _NoInterface}, // NoInterface returns E_NOINTERFACE. + +#define COM_INTERFACE_ENTRY_FUNC(iid, dw, func) \ + {&iid, \ + dw, \ + func}, + +#define COM_INTERFACE_ENTRY_FUNC_BLIND(dw, func) \ + {NULL, \ + dw, \ + func}, + +#define COM_INTERFACE_ENTRY_CHAIN(classname) \ + {NULL, \ + reinterpret_cast<DWORD>(&_CComChainData<classname, _ComMapClass>::data), \ + _Chain}, + +#define DECLARE_REGISTRY_RESOURCEID(x)\ + static HRESULT WINAPI UpdateRegistry(BOOL bRegister)\ + {\ + return ATL::_pAtlModule->UpdateRegistryFromResource(x, bRegister); \ + } + +#define DECLARE_NOT_AGGREGATABLE(x) \ +public: \ + typedef ATL::CComCreator2<ATL::CComCreator<ATL::CComObject<x> >, ATL::CComFailCreator<CLASS_E_NOAGGREGATION> > _CreatorClass; + +#define DECLARE_AGGREGATABLE(x) \ +public: \ + typedef CComCreator2<CComCreator<CComObject<x> >, CComCreator<CComAggObject<x> > > _CreatorClass; + +#define DECLARE_ONLY_AGGREGATABLE(x) \ +public: \ + typedef CComCreator2<CComFailCreator<E_FAIL>, CComCreator<CComAggObject<x> > > _CreatorClass; + +#define DECLARE_POLY_AGGREGATABLE(x) \ +public: \ + typedef CComCreator<CComPolyObject<x> > _CreatorClass; + +#define DECLARE_GET_CONTROLLING_UNKNOWN() \ +public: \ + virtual IUnknown *GetControllingUnknown() \ + { \ + return GetUnknown(); \ + } + +#define DECLARE_PROTECT_FINAL_CONSTRUCT() \ + void InternalFinalConstructAddRef() \ + { \ + InternalAddRef(); \ + } \ + void InternalFinalConstructRelease() \ + { \ + InternalRelease(); \ + } + +#define BEGIN_OBJECT_MAP(x) static ATL::_ATL_OBJMAP_ENTRY x[] = { + +#define END_OBJECT_MAP() {NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL}}; + +#define OBJECT_ENTRY(clsid, class) \ +{ \ + &clsid, \ + class::UpdateRegistry, \ + class::_ClassFactoryCreatorClass::CreateInstance, \ + class::_CreatorClass::CreateInstance, \ + NULL, \ + 0, \ + class::GetObjectDescription, \ + class::GetCategoryMap, \ + class::ObjectMain }, + +class CComClassFactory : + public IClassFactory, + public CComObjectRootEx<CComGlobalsThreadModel> +{ +public: + _ATL_CREATORFUNC *m_pfnCreateInstance; +public: + STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void **ppvObj) + { + HRESULT hResult; + + ATLASSERT(m_pfnCreateInstance != NULL); + + if (ppvObj == NULL) + return E_POINTER; + *ppvObj = NULL; + + if (pUnkOuter != NULL && InlineIsEqualUnknown(riid) == FALSE) + hResult = CLASS_E_NOAGGREGATION; + else + hResult = m_pfnCreateInstance(pUnkOuter, riid, ppvObj); + return hResult; + } + + STDMETHOD(LockServer)(BOOL fLock) + { + if (fLock) + _pAtlModule->Lock(); + else + _pAtlModule->Unlock(); + return S_OK; + } + + void SetVoid(void *pv) + { + m_pfnCreateInstance = (_ATL_CREATORFUNC *)pv; + } + + BEGIN_COM_MAP(CComClassFactory) + COM_INTERFACE_ENTRY_IID(IID_IClassFactory, IClassFactory) + END_COM_MAP() +}; + +template <class T, const CLSID *pclsid = &CLSID_NULL> +class CComCoClass +{ +public: + DECLARE_CLASSFACTORY() + + static LPCTSTR WINAPI GetObjectDescription() + { + return NULL; + } +}; + +template <class T> +class _Copy +{ +public: + static HRESULT copy(T *pTo, const T *pFrom) + { + memcpy(pTo, pFrom, sizeof(T)); + return S_OK; + } + + static void init(T *) + { + } + + static void destroy(T *) + { + } +}; + +template<> +class _Copy<CONNECTDATA> +{ +public: + static HRESULT copy(CONNECTDATA *pTo, const CONNECTDATA *pFrom) + { + *pTo = *pFrom; + if (pTo->pUnk) + pTo->pUnk->AddRef(); + return S_OK; + } + + static void init(CONNECTDATA *) + { + } + + static void destroy(CONNECTDATA *p) + { + if (p->pUnk) + p->pUnk->Release(); + } +}; + +template <class T> +class _CopyInterface +{ +public: + static HRESULT copy(T **pTo, T **pFrom) + { + *pTo = *pFrom; + if (*pTo) + (*pTo)->AddRef(); + return S_OK; + } + + static void init(T **) + { + } + + static void destroy(T **p) + { + if (*p) + (*p)->Release(); + } +}; + +enum CComEnumFlags +{ + AtlFlagNoCopy = 0, + AtlFlagTakeOwnership = 2, // BitOwn + AtlFlagCopy = 3 // BitOwn | BitCopy +}; + +template <class Base, const IID *piid, class T, class Copy> +class CComEnumImpl : public Base +{ +private: + typedef CComObject<CComEnum<Base, piid, T, Copy> > enumeratorClass; +public: + CComPtr<IUnknown> m_spUnk; + DWORD m_dwFlags; + T *m_begin; + T *m_end; + T *m_iter; +public: + CComEnumImpl() + { + m_dwFlags = 0; + m_begin = NULL; + m_end = NULL; + m_iter = NULL; + } + + virtual ~CComEnumImpl() + { + T *x; + + if ((m_dwFlags & BitOwn) != 0) + { + for (x = m_begin; x != m_end; x++) + Copy::destroy(x); + delete [] m_begin; + } + } + + HRESULT Init(T *begin, T *end, IUnknown *pUnk, CComEnumFlags flags = AtlFlagNoCopy) + { + T *newBuffer; + T *sourcePtr; + T *destPtr; + T *cleanupPtr; + HRESULT hResult; + + if (flags == AtlFlagCopy) + { + ATLTRY(newBuffer = new T[end - begin]) + if (newBuffer == NULL) + return E_OUTOFMEMORY; + destPtr = newBuffer; + for (sourcePtr = begin; sourcePtr != end; sourcePtr++) + { + Copy::init(destPtr); + hResult = Copy::copy(destPtr, sourcePtr); + if (FAILED(hResult)) + { + cleanupPtr = m_begin; + while (cleanupPtr < destPtr) + Copy::destroy(cleanupPtr++); + delete [] newBuffer; + return hResult; + } + destPtr++; + } + m_begin = newBuffer; + m_end = m_begin + (end - begin); + } + else + { + m_begin = begin; + m_end = end; + } + m_spUnk = pUnk; + m_dwFlags = flags; + m_iter = m_begin; + return S_OK; + } + + STDMETHOD(Next)(ULONG celt, T *rgelt, ULONG *pceltFetched) + { + ULONG numAvailable; + ULONG numToFetch; + T *rgeltTemp; + HRESULT hResult; + + if (pceltFetched != NULL) + *pceltFetched = 0; + if (celt == 0) + return E_INVALIDARG; + if (rgelt == NULL || (celt != 1 && pceltFetched == NULL)) + return E_POINTER; + if (m_begin == NULL || m_end == NULL || m_iter == NULL) + return E_FAIL; + + numAvailable = static_cast<ULONG>(m_end - m_iter); + if (celt < numAvailable) + numToFetch = celt; + else + numToFetch = numAvailable; + if (pceltFetched != NULL) + *pceltFetched = numToFetch; + rgeltTemp = rgelt; + while (numToFetch != 0) + { + hResult = Copy::copy(rgeltTemp, m_iter); + if (FAILED(hResult)) + { + while (rgelt < rgeltTemp) + Copy::destroy(rgelt++); + if (pceltFetched != NULL) + *pceltFetched = 0; + return hResult; + } + rgeltTemp++; + m_iter++; + numToFetch--; + } + if (numAvailable < celt) + return S_FALSE; + return S_OK; + } + + STDMETHOD(Skip)(ULONG celt) + { + ULONG numAvailable; + ULONG numToSkip; + + if (celt == 0) + return E_INVALIDARG; + + numAvailable = static_cast<ULONG>(m_end - m_iter); + if (celt < numAvailable) + numToSkip = celt; + else + numToSkip = numAvailable; + m_iter += numToSkip; + if (numAvailable < celt) + return S_FALSE; + return S_OK; + } + + STDMETHOD(Reset)() + { + m_iter = m_begin; + return S_OK; + } + + STDMETHOD(Clone)(Base **ppEnum) + { + enumeratorClass *newInstance; + HRESULT hResult; + + hResult = E_POINTER; + if (ppEnum != NULL) + { + *ppEnum = NULL; + hResult = enumeratorClass::CreateInstance(&newInstance); + if (SUCCEEDED(hResult)) + { + hResult = newInstance->Init(m_begin, m_end, (m_dwFlags & BitOwn) ? this : m_spUnk); + if (SUCCEEDED(hResult)) + { + newInstance->m_iter = m_iter; + hResult = newInstance->_InternalQueryInterface(*piid, (void **)ppEnum); + } + if (FAILED(hResult)) + delete newInstance; + } + } + return hResult; + } + +protected: + enum FlagBits + { + BitCopy = 1, + BitOwn = 2 + }; +}; + +template <class Base, const IID *piid, class T, class Copy, class ThreadModel> +class CComEnum : + public CComEnumImpl<Base, piid, T, Copy>, + public CComObjectRootEx<ThreadModel> +{ +public: + typedef CComEnum<Base, piid, T, Copy > _CComEnum; + typedef CComEnumImpl<Base, piid, T, Copy > _CComEnumBase; + + BEGIN_COM_MAP(_CComEnum) + COM_INTERFACE_ENTRY_IID(*piid, _CComEnumBase) + END_COM_MAP() +}; + +#ifndef _DEFAULT_VECTORLENGTH +#define _DEFAULT_VECTORLENGTH 4 +#endif + +class CComDynamicUnkArray +{ +public: + int m_nSize; + IUnknown **m_ppUnk; +public: + CComDynamicUnkArray() + { + m_nSize = 0; + m_ppUnk = NULL; + } + + ~CComDynamicUnkArray() + { + free(m_ppUnk); + } + + IUnknown **begin() + { + return m_ppUnk; + } + + IUnknown **end() + { + return &m_ppUnk[m_nSize]; + } + + IUnknown *GetAt(int nIndex) + { + ATLASSERT(nIndex >= 0 && nIndex < m_nSize); + if (nIndex >= 0 && nIndex < m_nSize) + return m_ppUnk[nIndex]; + else + return NULL; + } + + IUnknown *WINAPI GetUnknown(DWORD dwCookie) + { + ATLASSERT(dwCookie != 0 && dwCookie <= static_cast<DWORD>(m_nSize)); + if (dwCookie != 0 && dwCookie <= static_cast<DWORD>(m_nSize)) + return GetAt(dwCookie - 1); + else + return NULL; + } + + DWORD WINAPI GetCookie(IUnknown **ppFind) + { + IUnknown **x; + DWORD curCookie; + + ATLASSERT(ppFind != NULL && *ppFind != NULL); + if (ppFind != NULL && *ppFind != NULL) + { + curCookie = 1; + for (x = begin(); x < end(); x++) + { + if (*x == *ppFind) + return curCookie; + curCookie++; + } + } + return 0; + } + + DWORD Add(IUnknown *pUnk) + { + IUnknown **x; + IUnknown **newArray; + int newSize; + DWORD curCookie; + + ATLASSERT(pUnk != NULL); + if (m_nSize == 0) + { + newSize = _DEFAULT_VECTORLENGTH * sizeof(IUnknown *); + ATLTRY(newArray = reinterpret_cast<IUnknown **>(malloc(newSize))); + if (newArray == NULL) + return 0; + memset(newArray, 0, newSize); + m_ppUnk = newArray; + m_nSize = _DEFAULT_VECTORLENGTH; + } + curCookie = 1; + for (x = begin(); x < end(); x++) + { + if (*x == NULL) + { + *x = pUnk; + return curCookie; + } + curCookie++; + } + newSize = m_nSize * 2; + newArray = reinterpret_cast<IUnknown **>(realloc(m_ppUnk, newSize * sizeof(IUnknown *))); + if (newArray == NULL) + return 0; + memset(&m_ppUnk[m_nSize], 0, (newSize - m_nSize) * sizeof(IUnknown *)); + m_ppUnk = newArray; + m_nSize = newSize; + m_ppUnk[m_nSize] = pUnk; + return m_nSize + 1; + } + + BOOL Remove(DWORD dwCookie) + { + DWORD index; + + index = dwCookie - 1; + ATLASSERT(index < dwCookie && index < static_cast<DWORD>(m_nSize)); + if (index < dwCookie && index < static_cast<DWORD>(m_nSize) && m_ppUnk[index] != NULL) + { + m_ppUnk[index] = NULL; + return TRUE; + } + return FALSE; + } + +}; + +struct _ATL_CONNMAP_ENTRY +{ + DWORD_PTR dwOffset; +}; + +template <const IID *piid> +class _ICPLocator +{ +public: + STDMETHOD(_LocCPQueryInterface)(REFIID riid, void **ppvObject) = 0; + virtual ULONG STDMETHODCALLTYPE AddRef() = 0; + virtual ULONG STDMETHODCALLTYPE Release() = 0; +}; + +template<class T, const IID *piid, class CDV = CComDynamicUnkArray> +class IConnectionPointImpl : public _ICPLocator<piid> +{ + typedef CComEnum<IEnumConnections, &IID_IEnumConnections, CONNECTDATA, _Copy<CONNECTDATA> > CComEnumConnections; +public: + CDV m_vec; +public: + ~IConnectionPointImpl() + { + IUnknown **x; + + for (x = m_vec.begin(); x < m_vec.end(); x++) + if (*x != NULL) + (*x)->Release(); + } + + STDMETHOD(_LocCPQueryInterface)(REFIID riid, void **ppvObject) + { + IConnectionPointImpl<T, piid, CDV> *pThis; + + pThis = reinterpret_cast<IConnectionPointImpl<T, piid, CDV>*>(this); + + ATLASSERT(ppvObject != NULL); + if (ppvObject == NULL) + return E_POINTER; + + if (InlineIsEqualGUID(riid, IID_IConnectionPoint) || InlineIsEqualUnknown(riid)) + { + *ppvObject = this; + pThis->AddRef(); + return S_OK; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + } + + STDMETHOD(GetConnectionInterface)(IID *piid2) + { + if (piid2 == NULL) + return E_POINTER; + *piid2 = *piid; + return S_OK; + } + + STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer **ppCPC) + { + T *pThis; + + pThis = static_cast<T *>(this); + return pThis->QueryInterface(IID_IConnectionPointContainer, reinterpret_cast<void **>(ppCPC)); + } + + STDMETHOD(Advise)(IUnknown *pUnkSink, DWORD *pdwCookie) + { + IUnknown *adviseTarget; + IID interfaceID; + HRESULT hResult; + + if (pdwCookie != NULL) + *pdwCookie = 0; + if (pUnkSink == NULL || pdwCookie == NULL) + return E_POINTER; + GetConnectionInterface(&interfaceID); // can't fail + hResult = pUnkSink->QueryInterface(interfaceID, reinterpret_cast<void **>(&adviseTarget)); + if (SUCCEEDED(hResult)) + { + *pdwCookie = m_vec.Add(adviseTarget); + if (*pdwCookie != 0) + hResult = S_OK; + else + { + adviseTarget->Release(); + hResult = CONNECT_E_ADVISELIMIT; + } + } + else if (hResult == E_NOINTERFACE) + hResult = CONNECT_E_CANNOTCONNECT; + return hResult; + } + + STDMETHOD(Unadvise)(DWORD dwCookie) + { + IUnknown *adviseTarget; + HRESULT hResult; + + adviseTarget = m_vec.GetUnknown(dwCookie); + if (m_vec.Remove(dwCookie)) + { + if (adviseTarget != NULL) + adviseTarget->Release(); + hResult = S_OK; + } + else + hResult = CONNECT_E_NOCONNECTION; + return hResult; + } + + STDMETHOD(EnumConnections)(IEnumConnections **ppEnum) + { + CComObject<CComEnumConnections> *newEnumerator; + CONNECTDATA *itemBuffer; + CONNECTDATA *itemBufferEnd; + IUnknown **x; + HRESULT hResult; + + ATLASSERT(ppEnum != NULL); + if (ppEnum == NULL) + return E_POINTER; + *ppEnum = NULL; + + ATLTRY(itemBuffer = new CONNECTDATA[m_vec.end() - m_vec.begin()]) + if (itemBuffer == NULL) + return E_OUTOFMEMORY; + itemBufferEnd = itemBuffer; + for (x = m_vec.begin(); x < m_vec.end(); x++) + { + if (*x != NULL) + { + (*x)->AddRef(); + itemBufferEnd->pUnk = *x; + itemBufferEnd->dwCookie = m_vec.GetCookie(x); + itemBufferEnd++; + } + } + ATLTRY(newEnumerator = new CComObject<CComEnumConnections>) + if (newEnumerator == NULL) + return E_OUTOFMEMORY; + newEnumerator->Init(itemBuffer, itemBufferEnd, NULL, AtlFlagTakeOwnership); // can't fail + hResult = newEnumerator->_InternalQueryInterface(IID_IEnumConnections, (void **)ppEnum); + if (FAILED(hResult)) + delete newEnumerator; + return hResult; + } +}; + +template <class T> +class IConnectionPointContainerImpl : public IConnectionPointContainer +{ + typedef const _ATL_CONNMAP_ENTRY * (*handlerFunctionType)(int *); + typedef CComEnum<IEnumConnectionPoints, &IID_IEnumConnectionPoints, IConnectionPoint *, _CopyInterface<IConnectionPoint> > + CComEnumConnectionPoints; + +public: + STDMETHOD(EnumConnectionPoints)(IEnumConnectionPoints **ppEnum) + { + const _ATL_CONNMAP_ENTRY *entryPtr; + int connectionPointCount; + IConnectionPoint **itemBuffer; + int destIndex; + handlerFunctionType handlerFunction; + CComEnumConnectionPoints *newEnumerator; + HRESULT hResult; + + ATLASSERT(ppEnum != NULL); + if (ppEnum == NULL) + return E_POINTER; + *ppEnum = NULL; + + entryPtr = T::GetConnMap(&connectionPointCount); + ATLTRY(itemBuffer = new IConnectionPoint * [connectionPointCount]) + if (itemBuffer == NULL) + return E_OUTOFMEMORY; + + destIndex = 0; + while (entryPtr->dwOffset != static_cast<DWORD_PTR>(-1)) + { + if (entryPtr->dwOffset == static_cast<DWORD_PTR>(-2)) + { + entryPtr++; + handlerFunction = reinterpret_cast<handlerFunctionType>(entryPtr->dwOffset); + entryPtr = handlerFunction(NULL); + } + else + { + itemBuffer[destIndex++] = reinterpret_cast<IConnectionPoint *>((char *)this + entryPtr->dwOffset); + entryPtr++; + } + } + + ATLTRY(newEnumerator = new CComObject<CComEnumConnectionPoints>) + if (newEnumerator == NULL) + { + delete [] itemBuffer; + return E_OUTOFMEMORY; + } + + newEnumerator->Init(&itemBuffer[0], &itemBuffer[destIndex], NULL, AtlFlagTakeOwnership); // can't fail + hResult = newEnumerator->QueryInterface(IID_IEnumConnectionPoints, (void**)ppEnum); + if (FAILED(hResult)) + delete newEnumerator; + return hResult; + } + + STDMETHOD(FindConnectionPoint)(REFIID riid, IConnectionPoint **ppCP) + { + IID interfaceID; + const _ATL_CONNMAP_ENTRY *entryPtr; + handlerFunctionType handlerFunction; + IConnectionPoint *connectionPoint; + HRESULT hResult; + + if (ppCP == NULL) + return E_POINTER; + *ppCP = NULL; + hResult = CONNECT_E_NOCONNECTION; + entryPtr = T::GetConnMap(NULL); + while (entryPtr->dwOffset != static_cast<DWORD_PTR>(-1)) + { + if (entryPtr->dwOffset == static_cast<DWORD_PTR>(-2)) + { + entryPtr++; + handlerFunction = reinterpret_cast<handlerFunctionType>(entryPtr->dwOffset); + entryPtr = handlerFunction(NULL); + } + else + { + connectionPoint = reinterpret_cast<IConnectionPoint *>(reinterpret_cast<char *>(this) + entryPtr->dwOffset); + if (SUCCEEDED(connectionPoint->GetConnectionInterface(&interfaceID)) && InlineIsEqualGUID(riid, interfaceID)) + { + *ppCP = connectionPoint; + connectionPoint->AddRef(); + hResult = S_OK; + break; + } + entryPtr++; + } + } + return hResult; + } +}; + +#define BEGIN_CONNECTION_POINT_MAP(x) \ + typedef x _atl_conn_classtype; \ + static const ATL::_ATL_CONNMAP_ENTRY *GetConnMap(int *pnEntries) { \ + static const ATL::_ATL_CONNMAP_ENTRY _entries[] = { + +#define END_CONNECTION_POINT_MAP() \ + {(DWORD_PTR)-1} }; \ + if (pnEntries) \ + *pnEntries = sizeof(_entries) / sizeof(ATL::_ATL_CONNMAP_ENTRY) - 1; \ + return _entries;} + +#define CONNECTION_POINT_ENTRY(iid) \ + {offsetofclass(ATL::_ICPLocator<&iid>, _atl_conn_classtype) - \ + offsetofclass(ATL::IConnectionPointContainerImpl<_atl_conn_classtype>, _atl_conn_classtype)}, + +}; // namespace ATL + +#endif // _atlcom_h Propchange: trunk/reactos/lib/atl/atlcom.h ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/lib/atl/atlcore.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlcore.cpp?rev=43…
============================================================================== --- trunk/reactos/lib/atl/atlcore.cpp (added) +++ trunk/reactos/lib/atl/atlcore.cpp [iso-8859-1] Tue Oct 20 14:26:51 2009 @@ -1,0 +1,30 @@ +/* + * ReactOS ATL + * + * Copyright 2009 Andrew Hill <ash77(a)reactos.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <windows.h> +#include <ocidl.h> +#include "atlcore.h" + +namespace ATL +{ + +bool CAtlBaseModule::m_bInitFailed = false; + +}; // namespace ATL Propchange: trunk/reactos/lib/atl/atlcore.cpp ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/lib/atl/atlcore.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlcore.h?rev=4364…
============================================================================== --- trunk/reactos/lib/atl/atlcore.h (added) +++ trunk/reactos/lib/atl/atlcore.h [iso-8859-1] Tue Oct 20 14:26:51 2009 @@ -1,0 +1,199 @@ +/* + * ReactOS ATL + * + * Copyright 2009 Andrew Hill <ash77(a)reactos.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _atlcore_h +#define _atlcore_h + +#include <malloc.h> +#include <olectl.h> +#include <ocidl.h> + +#include <crtdbg.h> + +#ifndef ATLASSERT +#define ATLASSERT(expr) _ASSERTE(expr) +#endif // ATLASSERT + +namespace ATL +{ + +class CComCriticalSection +{ +public: + CRITICAL_SECTION m_sec; +public: + CComCriticalSection() + { + memset(&m_sec, 0, sizeof(CRITICAL_SECTION)); + } + + ~CComCriticalSection() + { + } + + HRESULT Lock() + { + EnterCriticalSection(&m_sec); + return S_OK; + } + + HRESULT Unlock() + { + LeaveCriticalSection(&m_sec); + return S_OK; + } + + HRESULT Init() + { + InitializeCriticalSection(&m_sec); + return S_OK; + } + + HRESULT Term() + { + DeleteCriticalSection(&m_sec); + return S_OK; + } +}; + +class CComFakeCriticalSection +{ +public: + HRESULT Lock() + { + return S_OK; + } + + HRESULT Unlock() + { + return S_OK; + } + + HRESULT Init() + { + return S_OK; + } + + HRESULT Term() + { + return S_OK; + } +}; + +class CComAutoCriticalSection : public CComCriticalSection +{ +public: + CComAutoCriticalSection() + { + HRESULT hResult; + + hResult = CComCriticalSection::Init(); + ATLASSERT(SUCCEEDED(hResult)); + } + ~CComAutoCriticalSection() + { + CComCriticalSection::Term(); + } +}; + +class CComSafeDeleteCriticalSection : public CComCriticalSection +{ +private: + bool m_bInitialized; +public: + CComSafeDeleteCriticalSection() + { + m_bInitialized = false; + } + + ~CComSafeDeleteCriticalSection() + { + Term(); + } + + HRESULT Lock() + { + ATLASSERT(m_bInitialized); + return CComCriticalSection::Lock(); + } + + HRESULT Init() + { + HRESULT hResult; + + ATLASSERT(!m_bInitialized); + hResult = CComCriticalSection::Init(); + if (SUCCEEDED(hResult)) + m_bInitialized = true; + return hResult; + } + + HRESULT Term() + { + if (!m_bInitialized) + return S_OK; + m_bInitialized = false; + return CComCriticalSection::Term(); + } +}; + +class CComAutoDeleteCriticalSection : public CComSafeDeleteCriticalSection +{ +private: + // CComAutoDeleteCriticalSection::Term should never be called + HRESULT Term(); +}; + +struct _ATL_BASE_MODULE70 +{ + UINT cbSize; + HINSTANCE m_hInst; + HINSTANCE m_hInstResource; + bool m_bNT5orWin98; + DWORD dwAtlBuildVer; + GUID *pguidVer; + CRITICAL_SECTION m_csResource; +#ifdef NOTYET + CSimpleArray<HINSTANCE> m_rgResourceInstance; +#endif +}; +typedef _ATL_BASE_MODULE70 _ATL_BASE_MODULE; + +class CAtlBaseModule : public _ATL_BASE_MODULE +{ +public : + static bool m_bInitFailed; +public: + HINSTANCE GetModuleInstance() + { + return m_hInst; + } + + HINSTANCE GetResourceInstance() + { + return m_hInstResource; + } +}; + +extern CAtlBaseModule _AtlBaseModule; + +}; // namespace ATL + +#endif // _atlcore_h Propchange: trunk/reactos/lib/atl/atlcore.h ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/lib/atl/atlwin.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlwin.h?rev=43645…
============================================================================== --- trunk/reactos/lib/atl/atlwin.h (added) +++ trunk/reactos/lib/atl/atlwin.h [iso-8859-1] Tue Oct 20 14:26:51 2009 @@ -1,0 +1,751 @@ +/* + * ReactOS ATL + * + * Copyright 2009 Andrew Hill <ash77(a)reactos.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _atlin_h +#define _atlwin_h + +#ifdef __GNUC__ +#define GCCU(x) x __attribute__((unused)) +#define Unused(x) +#else +#define GCCU(x) +#define Unused(x) (x); +#endif // __GNUC__ + +#ifdef SetWindowLongPtr +#undef SetWindowLongPtr +inline LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong) +{ + return SetWindowLong(hWnd, nIndex, (LONG)dwNewLong); +} +#endif + +#ifdef GetWindowLongPtr +#undef GetWindowLongPtr +inline LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex) +{ + return (LONG_PTR)GetWindowLong(hWnd, nIndex); +} +#endif + +namespace ATL +{ + +struct _ATL_WNDCLASSINFOW; +typedef _ATL_WNDCLASSINFOW CWndClassInfo; + +template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0> +class CWinTraits +{ +public: + static DWORD GetWndStyle(DWORD dwStyle) + { + if (dwStyle == 0) + return t_dwStyle; + return dwStyle; + } + + static DWORD GetWndExStyle(DWORD dwExStyle) + { + if (dwExStyle == 0) + return t_dwExStyle; + return dwExStyle; + } +}; + +typedef CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0> CControlWinTraits; +typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE> CFrameWinTraits; +typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_MDICHILD> CMDIChildWinTraits; + +template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0, class TWinTraits = CControlWinTraits> +class CWinTraitsOR +{ +public: + static DWORD GetWndStyle(DWORD dwStyle) + { + return dwStyle | t_dwStyle | TWinTraits::GetWndStyle(dwStyle); + } + + static DWORD GetWndExStyle(DWORD dwExStyle) + { + return dwExStyle | t_dwExStyle | TWinTraits::GetWndExStyle(dwExStyle); + } +}; + +class _U_MENUorID +{ +public: + HMENU m_hMenu; +public: + _U_MENUorID(HMENU hMenu) + { + m_hMenu = hMenu; + } + + _U_MENUorID(UINT nID) + { + m_hMenu = (HMENU)(UINT_PTR)nID; + } +}; + +class _U_RECT +{ +public: + LPRECT m_lpRect; +public: + _U_RECT(LPRECT lpRect) + { + m_lpRect = lpRect; + } + + _U_RECT(RECT &rc) + { + m_lpRect = &rc; + } +}; + +struct _ATL_MSG : public MSG +{ +public: + BOOL bHandled; +public: + _ATL_MSG(HWND hWnd, UINT uMsg, WPARAM wParamIn, LPARAM lParamIn, BOOL bHandledIn = TRUE) + { + hwnd = hWnd; + message = uMsg; + wParam = wParamIn; + lParam = lParamIn; + time = 0; + pt.x = 0; + pt.y = 0; + bHandled = bHandledIn; + } +}; + +#if defined(_M_IX86) + +#pragma pack(push,1) +struct thunkCode +{ + DWORD m_mov; + DWORD m_this; + BYTE m_jmp; + DWORD m_relproc; +}; +#pragma pack(pop) + +class CWndProcThunk +{ +public: + thunkCode m_thunk; + _AtlCreateWndData cd; +public: + BOOL Init(WNDPROC proc, void *pThis) + { + m_thunk.m_mov = 0x042444C7; + m_thunk.m_this = PtrToUlong(pThis); + m_thunk.m_jmp = 0xe9; + m_thunk.m_relproc = DWORD(reinterpret_cast<char *>(proc) - (reinterpret_cast<char *>(this) + sizeof(thunkCode))); + return TRUE; + } + + WNDPROC GetWNDPROC() + { + return reinterpret_cast<WNDPROC>(&m_thunk); + } +}; + +#else +#error Only X86 supported +#endif + +class CMessageMap +{ +public: + virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID) = 0; +}; + +class CWindow +{ +public: + HWND m_hWnd; + static RECT rcDefault; +public: + CWindow(HWND hWnd = NULL) + { + m_hWnd = hWnd; + } + + operator HWND() const + { + return m_hWnd; + } + + static LPCTSTR GetWndClassName() + { + return NULL; + } + + HDC BeginPaint(LPPAINTSTRUCT lpPaint) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::BeginPaint(m_hWnd, lpPaint); + } + + BOOL DestroyWindow() + { + ATLASSERT(::IsWindow(m_hWnd)); + + if (!::DestroyWindow(m_hWnd)) + return FALSE; + + m_hWnd = NULL; + return TRUE; + } + + void EndPaint(LPPAINTSTRUCT lpPaint) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::EndPaint(m_hWnd, lpPaint); + } + + BOOL GetClientRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::GetClientRect(m_hWnd, lpRect); + } + + CWindow GetParent() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CWindow(::GetParent(m_hWnd)); + } + + BOOL Invalidate(BOOL bErase = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::InvalidateRect(m_hWnd, NULL, bErase); + } + + BOOL InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::InvalidateRect(m_hWnd, lpRect, bErase); + } + + BOOL IsWindow() const + { + return ::IsWindow(m_hWnd); + } + + BOOL KillTimer(UINT_PTR nIDEvent) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::KillTimer(m_hWnd, nIDEvent); + } + + BOOL LockWindowUpdate(BOOL bLock = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + if (bLock) + return ::LockWindowUpdate(m_hWnd); + return ::LockWindowUpdate(NULL); + } + + BOOL ScreenToClient(LPPOINT lpPoint) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::ScreenToClient(m_hWnd, lpPoint); + } + + LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SendMessage(m_hWnd, message, wParam, lParam); + } + + static LRESULT SendMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) + { + ATLASSERT(::IsWindow(hWnd)); + return ::SendMessage(hWnd, message, wParam, lParam); + } + + HWND SetCapture() + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SetCapture(m_hWnd); + } + + HWND SetFocus() + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SetFocus(m_hWnd); + } + + UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT nElapse, void (CALLBACK *lpfnTimer)(HWND, UINT, UINT_PTR, DWORD) = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SetTimer(m_hWnd, nIDEvent, nElapse, reinterpret_cast<TIMERPROC>(lpfnTimer)); + } + + BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SetWindowPos(m_hWnd, hWndInsertAfter, x, y, cx, cy, nFlags); + } + + BOOL SetWindowText(LPCTSTR lpszString) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SetWindowText(m_hWnd, lpszString); + } + + BOOL ShowWindow(int nCmdShow) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::ShowWindow(m_hWnd, nCmdShow); + } + +}; + +_declspec(selectany) RECT CWindow::rcDefault = { CW_USEDEFAULT, CW_USEDEFAULT, 0, 0 }; + +template <class TBase = CWindow, class TWinTraits = CControlWinTraits> +class CWindowImplBaseT : public TBase, public CMessageMap +{ +public: + enum { WINSTATE_DESTROYED = 0x00000001 }; + DWORD m_dwState; + const _ATL_MSG *m_pCurrentMsg; + CWndProcThunk m_thunk; + WNDPROC m_pfnSuperWindowProc; +public: + CWindowImplBaseT() + { + m_dwState = 0; + m_pCurrentMsg = NULL; + m_pfnSuperWindowProc = ::DefWindowProc; + } + + virtual void OnFinalMessage(HWND /* hWnd */) + { + } + + BOOL SubclassWindow(HWND hWnd) + { + CWindowImplBaseT<TBase, TWinTraits> *pThis; + WNDPROC newWindowProc; + WNDPROC oldWindowProc; + BOOL result; + + ATLASSERT(m_hWnd == NULL); + ATLASSERT(::IsWindow(hWnd)); + + pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this); + + result = m_thunk.Init(GetWindowProc(), this); + if (result == FALSE) + return FALSE; + newWindowProc = m_thunk.GetWNDPROC(); + oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc))); + if (oldWindowProc == NULL) + return FALSE; + m_pfnSuperWindowProc = oldWindowProc; + pThis->m_hWnd = hWnd; + return TRUE; + } + + virtual WNDPROC GetWindowProc() + { + return WindowProc; + } + + static DWORD GetWndStyle(DWORD dwStyle) + { + return TWinTraits::GetWndStyle(dwStyle); + } + + static DWORD GetWndExStyle(DWORD dwExStyle) + { + return TWinTraits::GetWndExStyle(dwExStyle); + } + + LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + CWindowImplBaseT<TBase, TWinTraits> *pThis; + + pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(this); + return ::CallWindowProc(m_pfnSuperWindowProc, pThis->m_hWnd, uMsg, wParam, lParam); + } + + static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + CWindowImplBaseT<TBase, TWinTraits> *pThis; + WNDPROC newWindowProc; + WNDPROC GCCU(pOldProc); + + pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(_AtlWinModule.ExtractCreateWndData()); + ATLASSERT(pThis != NULL); + if (pThis == NULL) + return 0; + pThis->m_thunk.Init(pThis->GetWindowProc(), pThis); + newWindowProc = pThis->m_thunk.GetWNDPROC(); + pOldProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc))); + Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass + pThis->m_hWnd = hWnd; + return newWindowProc(hWnd, uMsg, wParam, lParam); + } + + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + CWindowImplBaseT<TBase, TWinTraits> *pThis = reinterpret_cast<CWindowImplBaseT< TBase, TWinTraits> *>(hWnd); + _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam); + LRESULT lResult; + const _ATL_MSG *previousMessage; + BOOL handled; + LONG_PTR saveWindowProc; + + ATLASSERT(pThis != NULL && (pThis->m_dwState & WINSTATE_DESTROYED) == 0 && pThis->m_hWnd != NULL); + if (pThis == NULL || (pThis->m_dwState & WINSTATE_DESTROYED) != 0 || pThis->m_hWnd == NULL) + return 0; + + hWnd = pThis->m_hWnd; + previousMessage = pThis->m_pCurrentMsg; + pThis->m_pCurrentMsg = &msg; + + handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0); + ATLASSERT(pThis->m_pCurrentMsg == &msg); + + if (handled == FALSE) + { + if (uMsg == WM_NCDESTROY) + { + saveWindowProc = ::GetWindowLongPtr(hWnd, GWLP_WNDPROC); + lResult = pThis->DefWindowProc(uMsg, wParam, lParam); + if (pThis->m_pfnSuperWindowProc != ::DefWindowProc && saveWindowProc == ::GetWindowLongPtr(hWnd, GWLP_WNDPROC)) + ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(pThis->m_pfnSuperWindowProc)); + pThis->m_dwState |= WINSTATE_DESTROYED; + } + else + lResult = pThis->DefWindowProc(uMsg, wParam, lParam); + } + ATLASSERT(pThis->m_pCurrentMsg == &msg); + pThis->m_pCurrentMsg = previousMessage; + if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0) + { + pThis->m_dwState &= ~WINSTATE_DESTROYED; + pThis->m_hWnd = NULL; + pThis->OnFinalMessage(hWnd); + } + return lResult; + } + + HWND Create(HWND hWndParent, _U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle, + _U_MENUorID MenuOrID, ATOM atom, LPVOID lpCreateParam) + { + HWND hWnd; + + ATLASSERT(m_hWnd == NULL); + ATLASSERT(atom != 0); + if (atom == 0) + return NULL; + if (m_thunk.Init(NULL, NULL) == FALSE) + { + SetLastError(ERROR_OUTOFMEMORY); + return NULL; + } + + _AtlWinModule.AddCreateWndData(&m_thunk.cd, this); + if (MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD) != 0) + MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this; + if (rect.m_lpRect == NULL) + rect.m_lpRect = &TBase::rcDefault; + hWnd = ::CreateWindowEx(dwExStyle, reinterpret_cast<LPCWSTR>(MAKEINTATOM(atom)), szWindowName, dwStyle, rect.m_lpRect->left, + rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left, rect.m_lpRect->bottom - rect.m_lpRect->top, + hWndParent, MenuOrID.m_hMenu, _AtlBaseModule.GetModuleInstance(), lpCreateParam); + + ATLASSERT(m_hWnd == hWnd); + + return hWnd; + } +}; + +template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits> +class CWindowImpl : public CWindowImplBaseT<TBase, TWinTraits> +{ +public: + static LPCTSTR GetWndCaption() + { + return NULL; + } + + HWND Create(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0, + DWORD dwExStyle = 0, _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + CWindowImplBaseT<TBase, TWinTraits> *pThis; + ATOM atom; + + ATLASSERT(m_hWnd == NULL); + pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this); + + if (T::GetWndClassInfo().m_lpszOrigName == NULL) + T::GetWndClassInfo().m_lpszOrigName = pThis->GetWndClassName(); + atom = T::GetWndClassInfo().Register(&pThis->m_pfnSuperWindowProc); + + if (szWindowName == NULL) + szWindowName = T::GetWndCaption(); + dwStyle = T::GetWndStyle(dwStyle); + dwExStyle = T::GetWndExStyle(dwExStyle); + + return CWindowImplBaseT<TBase, TWinTraits>::Create(hWndParent, rect, szWindowName, dwStyle, + dwExStyle, MenuOrID, atom, lpCreateParam); + } +}; + +template <class TBase = CWindow, class TWinTraits = CControlWinTraits> +class CContainedWindowT : public TBase +{ +public: + CWndProcThunk m_thunk; + LPCTSTR m_lpszClassName; + WNDPROC m_pfnSuperWindowProc; + CMessageMap *m_pObject; + DWORD m_dwMsgMapID; + const _ATL_MSG *m_pCurrentMsg; +public: + CContainedWindowT(CMessageMap *pObject, DWORD dwMsgMapID = 0) + { + m_lpszClassName = TBase::GetWndClassName(); + m_pfnSuperWindowProc = ::DefWindowProc; + m_pObject = pObject; + m_dwMsgMapID = dwMsgMapID; + m_pCurrentMsg = NULL; + } + + CContainedWindowT(LPTSTR lpszClassName, CMessageMap *pObject, DWORD dwMsgMapID = 0) + { + m_lpszClassName = lpszClassName; + m_pfnSuperWindowProc = ::DefWindowProc; + m_pObject = pObject; + m_dwMsgMapID = dwMsgMapID; + m_pCurrentMsg = NULL; + } + + LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + CWindowImplBaseT<TBase, TWinTraits> *pThis; + + pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(this); + return ::CallWindowProc(m_pfnSuperWindowProc, pThis->m_hWnd, uMsg, wParam, lParam); + } + + BOOL SubclassWindow(HWND hWnd) + { + CContainedWindowT<TBase> *pThis; + WNDPROC newWindowProc; + WNDPROC oldWindowProc; + BOOL result; + + ATLASSERT(m_hWnd == NULL); + ATLASSERT(::IsWindow(hWnd)); + + pThis = reinterpret_cast<CContainedWindowT<TBase> *>(this); + + result = m_thunk.Init(WindowProc, pThis); + if (result == FALSE) + return FALSE; + newWindowProc = m_thunk.GetWNDPROC(); + oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc))); + if (oldWindowProc == NULL) + return FALSE; + m_pfnSuperWindowProc = oldWindowProc; + pThis->m_hWnd = hWnd; + return TRUE; + } + + static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + CContainedWindowT<TBase> *pThis; + WNDPROC newWindowProc; + WNDPROC GCCU(pOldProc); + + pThis = reinterpret_cast<CContainedWindowT<TBase> *>(_AtlWinModule.ExtractCreateWndData()); + ATLASSERT(pThis != NULL); + if (pThis == NULL) + return 0; + pThis->m_thunk.Init(WindowProc, pThis); + newWindowProc = pThis->m_thunk.GetWNDPROC(); + pOldProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc))); + Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass + pThis->m_hWnd = hWnd; + return newWindowProc(hWnd, uMsg, wParam, lParam); + } + + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + CContainedWindowT<TBase> *pThis = reinterpret_cast<CContainedWindowT<TBase> *>(hWnd); + _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam); + LRESULT lResult; + const _ATL_MSG *previousMessage; + BOOL handled; + LONG_PTR saveWindowProc; + + ATLASSERT(pThis != NULL && pThis->m_hWnd != NULL && pThis->m_pObject != NULL); + if (pThis == NULL || pThis->m_hWnd == NULL || pThis->m_pObject == NULL) + return 0; + + hWnd = pThis->m_hWnd; + previousMessage = pThis->m_pCurrentMsg; + pThis->m_pCurrentMsg = &msg; + + handled = pThis->m_pObject->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, pThis->m_dwMsgMapID); + ATLASSERT(pThis->m_pCurrentMsg == &msg); + + pThis->m_pCurrentMsg = previousMessage; + if (handled == FALSE) + { + if (uMsg == WM_NCDESTROY) + { + saveWindowProc = ::GetWindowLongPtr(hWnd, GWLP_WNDPROC); + lResult = pThis->DefWindowProc(uMsg, wParam, lParam); + if (pThis->m_pfnSuperWindowProc != ::DefWindowProc && saveWindowProc == ::GetWindowLongPtr(hWnd, GWLP_WNDPROC)) + ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(pThis->m_pfnSuperWindowProc)); + pThis->m_hWnd = NULL; + } + else + lResult = pThis->DefWindowProc(uMsg, wParam, lParam); + } + return lResult; + } + +}; +typedef CContainedWindowT<CWindow> CContainedWindow; + +#define BEGIN_MSG_MAP(theClass) \ +public: \ + BOOL ProcessWindowMessage(HWND GCCU(hWnd), UINT GCCU(uMsg), WPARAM GCCU(wParam), LPARAM GCCU(lParam), LRESULT &GCCU(lResult), DWORD dwMsgMapID = 0) \ + { \ + BOOL GCCU(bHandled) = TRUE; \ + Unused(hWnd); \ + Unused(uMsg); \ + Unused(wParam); \ + Unused(lParam); \ + Unused(lResult); \ + Unused(bHandled); \ + switch(dwMsgMapID) \ + { \ + case 0: + +#define END_MSG_MAP() \ + break; \ + default: \ + ATLASSERT(FALSE); \ + break; \ + } \ + return FALSE; \ + } + +#define MESSAGE_HANDLER(msg, func) \ + if (uMsg == msg) \ + { \ + bHandled = TRUE; \ + lResult = func(uMsg, wParam, lParam, bHandled); \ + if (bHandled) \ + return TRUE; \ + } + +#define MESSAGE_RANGE_HANDLER(msgFirst, msgLast, func) \ + if (uMsg >= msgFirst && uMsg <= msgLast) \ + { \ + bHandled = TRUE; \ + lResult = func(uMsg, wParam, lParam, bHandled); \ + if (bHandled) \ + return TRUE; \ + } + +#define COMMAND_ID_HANDLER(id, func) \ + if (uMsg == WM_COMMAND && id == LOWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if (bHandled) \ + return TRUE; \ + } + +#define COMMAND_RANGE_HANDLER(idFirst, idLast, func) \ + if (uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if (bHandled) \ + return TRUE; \ + } + +#define NOTIFY_CODE_HANDLER(cd, func) \ + if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if (bHandled) \ + return TRUE; \ + } + +#define NOTIFY_HANDLER(id, cd, func) \ + if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if (bHandled) \ + return TRUE; \ + } + +#define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \ +static ATL::CWndClassInfo& GetWndClassInfo() \ +{ \ + static ATL::CWndClassInfo wc = \ + { \ + { sizeof(WNDCLASSEX), style, StartWindowProc, \ + 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \ + NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \ + }; \ + return wc; \ +} + +struct _ATL_WNDCLASSINFOW +{ + WNDCLASSEXW m_wc; + LPCWSTR m_lpszOrigName; + WNDPROC pWndProc; + LPCWSTR m_lpszCursorID; + BOOL m_bSystemCursor; + ATOM m_atom; + WCHAR m_szAutoName[5 + sizeof(void *)]; + + ATOM Register(WNDPROC *p) + { + if (m_atom == 0) + m_atom = RegisterClassEx(&m_wc); + return m_atom; + } +}; + +}; // namespace ATL + +#endif // _atlwin_h Propchange: trunk/reactos/lib/atl/atlwin.h ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/lib/atl/statreg.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/statreg.h?rev=4364…
============================================================================== --- trunk/reactos/lib/atl/statreg.h (added) +++ trunk/reactos/lib/atl/statreg.h [iso-8859-1] Tue Oct 20 14:26:51 2009 @@ -1,0 +1,679 @@ +/* + * ReactOS ATL + * + * Copyright 2005 Jacek Caban + * Copyright 2009 Andrew Hill <ash77(a)reactos.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _statreg_h +#define _statreg_h + +class IRegistrarBase : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE AddReplacement(LPCOLESTR key, LPCOLESTR item) = 0; + virtual HRESULT STDMETHODCALLTYPE ClearReplacements() = 0; +}; + +namespace ATL +{ + +class CRegObject : public IRegistrarBase +{ +public: + typedef struct rep_list_str + { + LPOLESTR key; + LPOLESTR item; + int key_len; + struct rep_list_str *next; + } rep_list; + + typedef struct + { + LPOLESTR str; + DWORD alloc; + DWORD len; + } strbuf; + + rep_list *m_rep; + +public: + CRegObject() + { + m_rep = NULL; + } + + ~CRegObject() + { + HRESULT hResult; + + hResult = ClearReplacements(); + ATLASSERT(SUCCEEDED(hResult)); + } + + HRESULT STDMETHODCALLTYPE QueryInterface(const IID & /* riid */, void ** /* ppvObject */ ) + { + ATLASSERT(_T("statically linked in CRegObject is not a com object. Do not callthis function")); + return E_NOTIMPL; + } + + ULONG STDMETHODCALLTYPE AddRef() + { + ATLASSERT(_T("statically linked in CRegObject is not a com object. Do not callthis function")); + return 1; + } + + ULONG STDMETHODCALLTYPE Release() + { + ATLASSERT(_T("statically linked in CRegObject is not a com object. Do not callthis function")); + return 0; + } + + HRESULT STDMETHODCALLTYPE AddReplacement(LPCOLESTR key, LPCOLESTR item) + { + int len; + rep_list *new_rep; + + new_rep = reinterpret_cast<rep_list *>(HeapAlloc(GetProcessHeap(), 0, sizeof(rep_list))); + + new_rep->key_len = lstrlenW(key); + new_rep->key = reinterpret_cast<OLECHAR *>(HeapAlloc(GetProcessHeap(), 0, (new_rep->key_len + 1) * sizeof(OLECHAR))); + memcpy(new_rep->key, key, (new_rep->key_len + 1) * sizeof(OLECHAR)); + + len = lstrlenW(item) + 1; + new_rep->item = reinterpret_cast<OLECHAR *>(HeapAlloc(GetProcessHeap(), 0, len * sizeof(OLECHAR))); + memcpy(new_rep->item, item, len * sizeof(OLECHAR)); + + new_rep->next = m_rep; + m_rep = new_rep; + + return S_OK; + } + + HRESULT STDMETHODCALLTYPE ClearReplacements() + { + rep_list *iter; + rep_list *iter2; + + iter = m_rep; + while (iter) + { + iter2 = iter->next; + HeapFree(GetProcessHeap(), 0, iter->key); + HeapFree(GetProcessHeap(), 0, iter->item); + HeapFree(GetProcessHeap(), 0, iter); + iter = iter2; + } + + m_rep = NULL; + return S_OK; + } + + HRESULT STDMETHODCALLTYPE ResourceRegisterSz(LPCOLESTR resFileName, LPCOLESTR szID, LPCOLESTR szType) + { + return RegisterWithResource(resFileName, szID, szType, TRUE); + } + + HRESULT STDMETHODCALLTYPE ResourceUnregisterSz(LPCOLESTR resFileName, LPCOLESTR szID, LPCOLESTR szType) + { + return RegisterWithResource(resFileName, szID, szType, FALSE); + } + + HRESULT STDMETHODCALLTYPE FileRegister(LPCOLESTR fileName) + { + return RegisterWithFile(fileName, TRUE); + } + + HRESULT STDMETHODCALLTYPE FileUnregister(LPCOLESTR fileName) + { + return RegisterWithFile(fileName, FALSE); + } + + HRESULT STDMETHODCALLTYPE StringRegister(LPCOLESTR data) + { + return RegisterWithString(data, TRUE); + } + + HRESULT STDMETHODCALLTYPE StringUnregister(LPCOLESTR data) + { + return RegisterWithString(data, FALSE); + } + + HRESULT STDMETHODCALLTYPE ResourceRegister(LPCOLESTR resFileName, UINT nID, LPCOLESTR szType) + { + return ResourceRegisterSz(resFileName, MAKEINTRESOURCEW(nID), szType); + } + + HRESULT STDMETHODCALLTYPE ResourceUnregister(LPCOLESTR resFileName, UINT nID, LPCOLESTR szType) + { + return ResourceRegisterSz(resFileName, MAKEINTRESOURCEW(nID), szType); + } + +protected: + HRESULT STDMETHODCALLTYPE RegisterWithResource(LPCOLESTR resFileName, LPCOLESTR szID, LPCOLESTR szType, BOOL doRegister) + { + return resource_register(resFileName, szID, szType, doRegister); + } + + HRESULT STDMETHODCALLTYPE RegisterWithFile(LPCOLESTR fileName, BOOL doRegister) + { + return file_register(fileName, doRegister); + } + + HRESULT STDMETHODCALLTYPE RegisterWithString(LPCOLESTR data, BOOL doRegister) + { + return string_register(data, doRegister); + } + +private: + inline LONG RegDeleteTreeX(HKEY parentKey, LPCTSTR subKeyName) + { + wchar_t szBuffer[256]; + DWORD dwSize; + FILETIME time; + HKEY childKey; + LONG lRes; + + ATLASSERT(parentKey != NULL); + lRes = RegOpenKeyEx(parentKey, subKeyName, 0, KEY_READ | KEY_WRITE, &childKey); + if (lRes != ERROR_SUCCESS) + return lRes; + + dwSize = sizeof(szBuffer) / sizeof(szBuffer[0]); + while (RegEnumKeyExW(parentKey, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time) == ERROR_SUCCESS) + { + lRes = RegDeleteTreeX(childKey, szBuffer); + if (lRes != ERROR_SUCCESS) + return lRes; + dwSize = sizeof(szBuffer) / sizeof(szBuffer[0]); + } + RegCloseKey(childKey); + return RegDeleteKey(parentKey, subKeyName); + } + + void strbuf_init(strbuf *buf) + { + buf->str = reinterpret_cast<LPOLESTR>(HeapAlloc(GetProcessHeap(), 0, 128 * sizeof(WCHAR))); + buf->alloc = 128; + buf->len = 0; + } + + void strbuf_write(LPCOLESTR str, strbuf *buf, int len) + { + if (len == -1) + len = lstrlenW(str); + if (buf->len+len+1 >= buf->alloc) + { + buf->alloc = (buf->len + len) * 2; + buf->str = reinterpret_cast<LPOLESTR>(HeapReAlloc(GetProcessHeap(), 0, buf->str, buf->alloc * sizeof(WCHAR))); + } + memcpy(buf->str + buf->len, str, len * sizeof(OLECHAR)); + buf->len += len; + buf->str[buf->len] = '\0'; + } + + + HRESULT file_register(LPCOLESTR fileName, BOOL do_register) + { + HANDLE file; + DWORD filelen; + DWORD len; + LPWSTR regstrw; + LPSTR regstra; + LRESULT lres; + HRESULT hResult; + + file = CreateFileW(fileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); + if (file != INVALID_HANDLE_VALUE) + { + filelen = GetFileSize(file, NULL); + regstra = reinterpret_cast<LPSTR>(HeapAlloc(GetProcessHeap(), 0, filelen)); + lres = ReadFile(file, regstra, filelen, NULL, NULL); + if (lres == ERROR_SUCCESS) + { + len = MultiByteToWideChar(CP_ACP, 0, regstra, filelen, NULL, 0) + 1; + regstrw = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR))); + MultiByteToWideChar(CP_ACP, 0, regstra, filelen, regstrw, len); + regstrw[len - 1] = '\0'; + + hResult = string_register(regstrw, do_register); + + HeapFree(GetProcessHeap(), 0, regstrw); + } + else + { + hResult = HRESULT_FROM_WIN32(lres); + } + HeapFree(GetProcessHeap(), 0, regstra); + CloseHandle(file); + } + else + { + hResult = HRESULT_FROM_WIN32(GetLastError()); + } + + return hResult; + } + + HRESULT resource_register(LPCOLESTR resFileName, LPCOLESTR szID, LPCOLESTR szType, BOOL do_register) + { + HINSTANCE hins; + HRSRC src; + HGLOBAL regstra; + LPWSTR regstrw; + DWORD len; + DWORD reslen; + HRESULT hResult; + + hins = LoadLibraryExW(resFileName, NULL, LOAD_LIBRARY_AS_DATAFILE); + if (hins) + { + src = FindResourceW(hins, szID, szType); + if (src) + { + regstra = LoadResource(hins, src); + reslen = SizeofResource(hins, src); + if (regstra) + { + len = MultiByteToWideChar(CP_ACP, 0, reinterpret_cast<LPCSTR>(regstra), reslen, NULL, 0) + 1; + regstrw = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR))); + MultiByteToWideChar(CP_ACP, 0, reinterpret_cast<LPCSTR>(regstra), reslen, regstrw, len); + regstrw[len - 1] = '\0'; + + hResult = string_register(regstrw, do_register); + + HeapFree(GetProcessHeap(), 0, regstrw); + } + else + hResult = HRESULT_FROM_WIN32(GetLastError()); + } + else + hResult = HRESULT_FROM_WIN32(GetLastError()); + FreeLibrary(hins); + } + else + hResult = HRESULT_FROM_WIN32(GetLastError()); + + return hResult; + } + + HRESULT string_register(LPCOLESTR data, BOOL do_register) + { + strbuf buf; + HRESULT hResult; + + strbuf_init(&buf); + hResult = do_preprocess(data, &buf); + if (SUCCEEDED(hResult)) + { + hResult = do_process_root_key(buf.str, do_register); + if (FAILED(hResult) && do_register) + do_process_root_key(buf.str, FALSE); + } + + HeapFree(GetProcessHeap(), 0, buf.str); + return hResult; + } + + HRESULT do_preprocess(LPCOLESTR data, strbuf *buf) + { + LPCOLESTR iter; + LPCOLESTR iter2; + rep_list *rep_iter; + + iter2 = data; + iter = wcschr(data, '%'); + while (iter) + { + strbuf_write(iter2, buf, static_cast<int>(iter - iter2)); + + iter2 = ++iter; + if (!*iter2) + return DISP_E_EXCEPTION; + iter = wcschr(iter2, '%'); + if (!iter) + return DISP_E_EXCEPTION; + + if (iter == iter2) + strbuf_write(_T("%"), buf, 1); + else + { + for (rep_iter = m_rep; rep_iter; rep_iter = rep_iter->next) + { + if (rep_iter->key_len == iter - iter2 && !_memicmp(iter2, rep_iter->key, rep_iter->key_len * sizeof(wchar_t))) + break; + } + if (!rep_iter) + return DISP_E_EXCEPTION; + + strbuf_write(rep_iter->item, buf, -1); + } + + iter2 = ++iter; + iter = wcschr(iter, '%'); + } + + strbuf_write(iter2, buf, -1); + + return S_OK; + } + + HRESULT get_word(LPCOLESTR *str, strbuf *buf) + { + LPCOLESTR iter; + LPCOLESTR iter2; + + iter2 = *str; + buf->len = 0; + buf->str[0] = '\0'; + + while (iswspace (*iter2)) + iter2++; + iter = iter2; + if (!*iter) + { + *str = iter; + return S_OK; + } + + if (*iter == '}' || *iter == '=') + { + strbuf_write(iter++, buf, 1); + } + else if (*iter == '\'') + { + iter2 = ++iter; + iter = wcschr(iter, '\''); + if (!iter) + { + *str = iter; + return DISP_E_EXCEPTION; + } + strbuf_write(iter2, buf, static_cast<int>(iter - iter2)); + iter++; + } + else + { + while (*iter && !iswspace(*iter)) + iter++; + strbuf_write(iter2, buf, static_cast<int>(iter - iter2)); + } + + while (iswspace(*iter)) + iter++; + *str = iter; + return S_OK; + } + + HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register) + { + LPCOLESTR iter; + HRESULT hres; + LONG lres; + HKEY hkey; + strbuf name; + + enum { + NORMAL, + NO_REMOVE, + IS_VAL, + FORCE_REMOVE, + DO_DELETE + } key_type = NORMAL; + + static const wchar_t *wstrNoRemove = _T("NoRemove"); + static const wchar_t *wstrForceRemove = _T("ForceRemove"); + static const wchar_t *wstrDelete = _T("Delete"); + static const wchar_t *wstrval = _T("val"); + + iter = *pstr; + hkey = NULL; + iter = *pstr; + hres = get_word(&iter, buf); + if (FAILED(hres)) + return hres; + strbuf_init(&name); + + while(buf->str[1] || buf->str[0] != '}') + { + key_type = NORMAL; + if (!lstrcmpiW(buf->str, wstrNoRemove)) + key_type = NO_REMOVE; + else if (!lstrcmpiW(buf->str, wstrForceRemove)) + key_type = FORCE_REMOVE; + else if (!lstrcmpiW(buf->str, wstrval)) + key_type = IS_VAL; + else if (!lstrcmpiW(buf->str, wstrDelete)) + key_type = DO_DELETE; + + if (key_type != NORMAL) + { + hres = get_word(&iter, buf); + if(FAILED(hres)) + break; + } + + if (do_register) + { + if (key_type == IS_VAL) + { + hkey = parent_key; + strbuf_write(buf->str, &name, -1); + } + else if (key_type == DO_DELETE) + { + RegDeleteTreeX(parent_key, buf->str); + } + else + { + if (key_type == FORCE_REMOVE) + RegDeleteTreeX(parent_key, buf->str); + lres = RegCreateKey(parent_key, buf->str, &hkey); + if (lres != ERROR_SUCCESS) + { + hres = HRESULT_FROM_WIN32(lres); + break; + } + } + } + else if (key_type != IS_VAL && key_type != DO_DELETE) + { + strbuf_write(buf->str, &name, -1); + lres = RegOpenKey(parent_key, buf->str, &hkey); + if (lres != ERROR_SUCCESS) + { + } + } + + if (key_type != DO_DELETE && *iter == '=') + { + iter++; + hres = get_word(&iter, buf); + if (FAILED(hres)) + break; + if (buf->len != 1) + { + hres = DISP_E_EXCEPTION; + break; + } + if (do_register) + { + switch(buf->str[0]) + { + case 's': + hres = get_word(&iter, buf); + if (FAILED(hres)) + break; + lres = RegSetValueEx(hkey, name.len ? name.str : NULL, 0, REG_SZ, (PBYTE)buf->str, + (lstrlenW(buf->str) + 1) * sizeof(WCHAR)); + if (lres != ERROR_SUCCESS) + { + hres = HRESULT_FROM_WIN32(lres); + break; + } + break; + case 'd': + { + WCHAR *end; + DWORD dw; + if(*iter == '0' && iter[1] == 'x') + { + iter += 2; + dw = wcstol(iter, &end, 16); + } + else + { + dw = wcstol(iter, &end, 10); + } + iter = end; + lres = RegSetValueEx(hkey, name.len ? name.str : NULL, 0, REG_DWORD, (PBYTE)&dw, sizeof(dw)); + if (lres != ERROR_SUCCESS) + { + hres = HRESULT_FROM_WIN32(lres); + break; + } + break; + } + default: + hres = DISP_E_EXCEPTION; + } + if (FAILED(hres)) + break; + } + else + { + if (*iter == '-') + iter++; + hres = get_word(&iter, buf); + if (FAILED(hres)) + break; + } + } + else if(key_type == IS_VAL) + { + hres = DISP_E_EXCEPTION; + break; + } + + if (key_type != IS_VAL && key_type != DO_DELETE && *iter == '{' && iswspace(iter[1])) + { + hres = get_word(&iter, buf); + if (FAILED(hres)) + break; + hres = do_process_key(&iter, hkey, buf, do_register); + if (FAILED(hres)) + break; + } + + if (!do_register && (key_type == NORMAL || key_type == FORCE_REMOVE)) + { + RegDeleteKey(parent_key, name.str); + } + + if (hkey && key_type != IS_VAL) + RegCloseKey(hkey); + hkey = 0; + name.len = 0; + + hres = get_word(&iter, buf); + if (FAILED(hres)) + break; + } + + HeapFree(GetProcessHeap(), 0, name.str); + if (hkey && key_type != IS_VAL) + RegCloseKey(hkey); + *pstr = iter; + return hres; + } + + HRESULT do_process_root_key(LPCOLESTR data, BOOL do_register) + { + LPCOLESTR iter; + strbuf buf; + unsigned int i; + HRESULT hResult; + static const struct { + wchar_t *name; + HKEY key; + } root_keys[] = { + {_T("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT}, + {_T("HKEY_CURRENT_USER"), HKEY_CURRENT_USER}, + {_T("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE}, + {_T("HKEY_USERS"), HKEY_USERS}, + {_T("HKEY_PERFORMANCE_DATA"), HKEY_PERFORMANCE_DATA}, + {_T("HKEY_DYN_DATA"), HKEY_DYN_DATA}, + {_T("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG}, + {_T("HKCR"), HKEY_CLASSES_ROOT}, + {_T("HKCU"), HKEY_CURRENT_USER}, + {_T("HKLM"), HKEY_LOCAL_MACHINE}, + {_T("HKU"), HKEY_USERS}, + {_T("HKPD"), HKEY_PERFORMANCE_DATA}, + {_T("HKDD"), HKEY_DYN_DATA}, + {_T("HKCC"), HKEY_CURRENT_CONFIG}, + }; + + iter = data; + hResult = S_OK; + + strbuf_init(&buf); + hResult = get_word(&iter, &buf); + if (FAILED(hResult)) + return hResult; + + while (*iter) + { + if (!buf.len) + { + hResult = DISP_E_EXCEPTION; + break; + } + for (i = 0; i < sizeof(root_keys) / sizeof(root_keys[0]); i++) + { + if (!lstrcmpiW(buf.str, root_keys[i].name)) + break; + } + if (i == sizeof(root_keys) / sizeof(root_keys[0])) + { + hResult = DISP_E_EXCEPTION; + break; + } + hResult = get_word(&iter, &buf); + if (FAILED(hResult)) + break; + if (buf.str[1] || buf.str[0] != '{') + { + hResult = DISP_E_EXCEPTION; + break; + } + hResult = do_process_key(&iter, root_keys[i].key, &buf, do_register); + if (FAILED(hResult)) + break; + hResult = get_word(&iter, &buf); + if (FAILED(hResult)) + break; + } + HeapFree(GetProcessHeap(), 0, buf.str); + return hResult; + } + +}; + +}; //namespace ATL + +#endif // _statreg_h Propchange: trunk/reactos/lib/atl/statreg.h ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/reactos/lib/lib.rbuild URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/lib.rbuild?rev=43645&r…
============================================================================== --- trunk/reactos/lib/lib.rbuild [iso-8859-1] (original) +++ trunk/reactos/lib/lib.rbuild [iso-8859-1] Tue Oct 20 14:26:51 2009 @@ -6,6 +6,9 @@ </directory> <directory name="sdk"> <xi:include href="sdk/sdk.rbuild" /> + </directory> + <directory name="atl"> + <xi:include href="atl/atl.rbuild" /> </directory> <directory name="cmlib"> <xi:include href="cmlib/cmlib.rbuild" />
14 years, 11 months
1
0
0
0
[fireball] 43644: [fastfat_new] - Fix an incorrectly placed closing bracket which resulted in ignoring almost all actions when performing relative open. This results in a massive reformatting of FatiCreate.
by fireball@svn.reactos.org
Author: fireball Date: Tue Oct 20 14:03:51 2009 New Revision: 43644 URL:
http://svn.reactos.org/svn/reactos?rev=43644&view=rev
Log: [fastfat_new] - Fix an incorrectly placed closing bracket which resulted in ignoring almost all actions when performing relative open. This results in a massive reformatting of FatiCreate. Modified: trunk/reactos/drivers/filesystems/fastfat_new/create.c Modified: trunk/reactos/drivers/filesystems/fastfat_new/create.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] Tue Oct 20 14:03:51 2009 @@ -605,262 +605,47 @@ ParentDcb = Vcb->RootDcb; DPRINT("ParentDcb %p\n", ParentDcb); } - - /* Check for backslash at the end */ - if (FileName.Length && - FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1] == L'\\') - { - /* Cut it out */ - FileName.Length -= sizeof(WCHAR); - - /* Remember we cut it */ - EndBackslash = TRUE; - } - - /* Ensure the name is set */ - if (!ParentDcb->FullFileName.Buffer) - { - /* Set it if it's missing */ - FatSetFullFileNameInFcb(IrpContext, ParentDcb); - } - - /* Check max path length */ - if (ParentDcb->FullFileName.Length + FileName.Length + sizeof(WCHAR) <= FileName.Length) - { - DPRINT1("Max length is way off\n"); - Iosb.Status = STATUS_OBJECT_NAME_INVALID; - ASSERT(FALSE); - } - - /* Loop through FCBs to find a good one */ - while (TRUE) - { - Fcb = ParentDcb; - - /* Dissect the name */ - RemainingPart = FileName; - while (RemainingPart.Length) - { - FsRtlDissectName(RemainingPart, &FirstName, &NextName); - - /* Check for validity */ - if ((NextName.Length && NextName.Buffer[0] == L'\\') || - (NextName.Length > 255 * sizeof(WCHAR))) - { - /* The name is invalid */ - DPRINT1("Invalid name found\n"); - Iosb.Status = STATUS_OBJECT_NAME_INVALID; - ASSERT(FALSE); - } - - /* Convert the name to ANSI */ - AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length); - AnsiFirstName.Length = 0; - AnsiFirstName.MaximumLength = FirstName.Length; - Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlUpcaseUnicodeStringToCountedOemString() failed with 0x%08x\n", Status); - ASSERT(FALSE); - NextFcb = NULL; - AnsiFirstName.Length = 0; - } - else - { - /* Find the coresponding FCB */ - NextFcb = FatFindFcb(IrpContext, - &Fcb->Dcb.SplayLinksAnsi, - (PSTRING)&AnsiFirstName, - &OpenedAsDos); - } - - /* If nothing found - try with unicode */ - if (!NextFcb && Fcb->Dcb.SplayLinksUnicode) - { - FileNameUpcased.Buffer = FsRtlAllocatePool(PagedPool, FirstName.Length); - FileNameUpcased.Length = 0; - FileNameUpcased.MaximumLength = FirstName.Length; - - /* Downcase and then upcase to normalize it */ - Status = RtlDowncaseUnicodeString(&FileNameUpcased, &FirstName, FALSE); - Status = RtlUpcaseUnicodeString(&FileNameUpcased, &FileNameUpcased, FALSE); - - /* Try to find FCB again using unicode name */ - NextFcb = FatFindFcb(IrpContext, - &Fcb->Dcb.SplayLinksUnicode, - (PSTRING)&FileNameUpcased, - &OpenedAsDos); - } - - /* Move to the next FCB */ - if (NextFcb) - { - Fcb = NextFcb; - RemainingPart = NextName; - } - - /* Break out of this loop if nothing can be found */ - if (!NextFcb || - NextName.Length == 0 || - FatNodeType(NextFcb) == FAT_NTC_FCB) - { - break; - } - } - - /* Ensure remaining name doesn't start from a backslash */ - if (RemainingPart.Length && - RemainingPart.Buffer[0] == L'\\') - { - /* Cut it */ - RemainingPart.Buffer++; - RemainingPart.Length -= sizeof(WCHAR); - } - - if (Fcb->Condition == FcbGood) - { - /* Good FCB, break out of the loop */ - break; - } - else - { - ASSERT(FALSE); - } - } - - /* We have a valid FCB now */ - if (!RemainingPart.Length) - { - /* Check for target dir open */ - if (OpenTargetDirectory) - { - DPRINT1("Opening target dir is missing\n"); - ASSERT(FALSE); - } - - /* Check this FCB's type */ - if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB || - FatNodeType(Fcb) == FAT_NTC_DCB) - { - /* Open a directory */ - if (NonDirectoryFile) - { - /* Forbidden */ - Iosb.Status = STATUS_FILE_IS_A_DIRECTORY; - ASSERT(FALSE); - return Iosb.Status; - } - - /* Open existing DCB */ - Iosb = FatiOpenExistingDcb(IrpContext, - FileObject, - Vcb, - Fcb, - DesiredAccess, - ShareAccess, - CreateDisposition, - NoEaKnowledge, - DeleteOnClose); - - /* Save information */ - Irp->IoStatus.Information = Iosb.Information; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - - return Iosb.Status; - } - else if (FatNodeType(Fcb) == FAT_NTC_FCB) - { - /* Open a file */ - if (OpenDirectory) - { - /* Forbidden */ - Iosb.Status = STATUS_NOT_A_DIRECTORY; - ASSERT(FALSE); - return Iosb.Status; - } - - /* Check for trailing backslash */ - if (EndBackslash) - { - /* Forbidden */ - Iosb.Status = STATUS_OBJECT_NAME_INVALID; - ASSERT(FALSE); - return Iosb.Status; - } - - Iosb = FatiOpenExistingFcb(IrpContext, - FileObject, - Vcb, - Fcb, - DesiredAccess, - ShareAccess, - AllocationSize, - EaBuffer, - EaLength, - FileAttributes, - CreateDisposition, - NoEaKnowledge, - DeleteOnClose, - OpenedAsDos, - &OplockPostIrp); - - /* Check if it's pending */ - if (Iosb.Status != STATUS_PENDING) - { - /* In case of success set cache supported flag */ - if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering) - { - SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED); - } - - /* Save information */ - Irp->IoStatus.Information = Iosb.Information; - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - - return Iosb.Status; - } - else - { - /* Queue this IRP */ - UNIMPLEMENTED; - ASSERT(FALSE); - } - } - else - { - /* Unexpected FCB type */ - KeBugCheckEx(/*FAT_FILE_SYSTEM*/0x23, __LINE__, (ULONG_PTR)Fcb, 0, 0); - } - } - - /* During parsing we encountered a part which has no attached FCB/DCB. - Check that the parent is really DCB and not FCB */ - if (FatNodeType(Fcb) != FAT_NTC_ROOT_DCB && - FatNodeType(Fcb) != FAT_NTC_DCB) - { - DPRINT1("Weird FCB node type %x, expected DCB or root DCB\n", FatNodeType(Fcb)); - ASSERT(FALSE); - } - - /* Create additional DCBs for all path items */ - ParentDcb = Fcb; - while (TRUE) - { - FsRtlDissectName(RemainingPart, &FirstName, &RemainingPart); + } + + /* Check for backslash at the end */ + if (FileName.Length && + FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1] == L'\\') + { + /* Cut it out */ + FileName.Length -= sizeof(WCHAR); + + /* Remember we cut it */ + EndBackslash = TRUE; + } + + /* Ensure the name is set */ + if (!ParentDcb->FullFileName.Buffer) + { + /* Set it if it's missing */ + FatSetFullFileNameInFcb(IrpContext, ParentDcb); + } + + /* Check max path length */ + if (ParentDcb->FullFileName.Length + FileName.Length + sizeof(WCHAR) <= FileName.Length) + { + DPRINT1("Max length is way off\n"); + Iosb.Status = STATUS_OBJECT_NAME_INVALID; + ASSERT(FALSE); + } + + /* Loop through FCBs to find a good one */ + while (TRUE) + { + Fcb = ParentDcb; + + /* Dissect the name */ + RemainingPart = FileName; + while (RemainingPart.Length) + { + FsRtlDissectName(RemainingPart, &FirstName, &NextName); /* Check for validity */ - if ((RemainingPart.Length && RemainingPart.Buffer[0] == L'\\') || + if ((NextName.Length && NextName.Buffer[0] == L'\\') || (NextName.Length > 255 * sizeof(WCHAR))) { /* The name is invalid */ @@ -877,55 +662,143 @@ if (!NT_SUCCESS(Status)) { + DPRINT1("RtlUpcaseUnicodeStringToCountedOemString() failed with 0x%08x\n", Status); ASSERT(FALSE); - } - - DPRINT("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart); - - /* Break if came to the end */ - if (!RemainingPart.Length) break; - - /* Create a DCB for this entry */ - ParentDcb = FatCreateDcb(IrpContext, - Vcb, - ParentDcb, - NULL); - - /* Set its name */ - FatSetFullNameInFcb(ParentDcb, &FirstName); - } - - /* Try to open it and get a result, saying if this is a dir or a file */ - FfError = FatiTryToOpen(FileObject, Vcb); - - /* Check if we need to open target directory */ + NextFcb = NULL; + AnsiFirstName.Length = 0; + } + else + { + /* Find the coresponding FCB */ + NextFcb = FatFindFcb(IrpContext, + &Fcb->Dcb.SplayLinksAnsi, + (PSTRING)&AnsiFirstName, + &OpenedAsDos); + } + + /* If nothing found - try with unicode */ + if (!NextFcb && Fcb->Dcb.SplayLinksUnicode) + { + FileNameUpcased.Buffer = FsRtlAllocatePool(PagedPool, FirstName.Length); + FileNameUpcased.Length = 0; + FileNameUpcased.MaximumLength = FirstName.Length; + + /* Downcase and then upcase to normalize it */ + Status = RtlDowncaseUnicodeString(&FileNameUpcased, &FirstName, FALSE); + Status = RtlUpcaseUnicodeString(&FileNameUpcased, &FileNameUpcased, FALSE); + + /* Try to find FCB again using unicode name */ + NextFcb = FatFindFcb(IrpContext, + &Fcb->Dcb.SplayLinksUnicode, + (PSTRING)&FileNameUpcased, + &OpenedAsDos); + } + + /* Move to the next FCB */ + if (NextFcb) + { + Fcb = NextFcb; + RemainingPart = NextName; + } + + /* Break out of this loop if nothing can be found */ + if (!NextFcb || + NextName.Length == 0 || + FatNodeType(NextFcb) == FAT_NTC_FCB) + { + break; + } + } + + /* Ensure remaining name doesn't start from a backslash */ + if (RemainingPart.Length && + RemainingPart.Buffer[0] == L'\\') + { + /* Cut it */ + RemainingPart.Buffer++; + RemainingPart.Length -= sizeof(WCHAR); + } + + if (Fcb->Condition == FcbGood) + { + /* Good FCB, break out of the loop */ + break; + } + else + { + ASSERT(FALSE); + } + } + + /* We have a valid FCB now */ + if (!RemainingPart.Length) + { + /* Check for target dir open */ if (OpenTargetDirectory) { - // TODO: Open target directory - UNIMPLEMENTED; - } - - /* Check, if path is a directory or a file */ - if (FfError == FF_ERR_FILE_OBJECT_IS_A_DIR) - { + DPRINT1("Opening target dir is missing\n"); + ASSERT(FALSE); + } + + /* Check this FCB's type */ + if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB || + FatNodeType(Fcb) == FAT_NTC_DCB) + { + /* Open a directory */ if (NonDirectoryFile) { - DPRINT1("Can't open dir as a file\n"); - - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ + /* Forbidden */ Iosb.Status = STATUS_FILE_IS_A_DIRECTORY; - FatCompleteRequest(IrpContext, Irp, Iosb.Status); + ASSERT(FALSE); return Iosb.Status; } - /* Open this directory */ - Iosb = FatiOpenExistingDir(IrpContext, + /* Open existing DCB */ + Iosb = FatiOpenExistingDcb(IrpContext, FileObject, Vcb, - ParentDcb, + Fcb, + DesiredAccess, + ShareAccess, + CreateDisposition, + NoEaKnowledge, + DeleteOnClose); + + /* Save information */ + Irp->IoStatus.Information = Iosb.Information; + + /* Unlock VCB */ + FatReleaseVcb(IrpContext, Vcb); + + /* Complete the request */ + FatCompleteRequest(IrpContext, Irp, Iosb.Status); + + return Iosb.Status; + } + else if (FatNodeType(Fcb) == FAT_NTC_FCB) + { + /* Open a file */ + if (OpenDirectory) + { + /* Forbidden */ + Iosb.Status = STATUS_NOT_A_DIRECTORY; + ASSERT(FALSE); + return Iosb.Status; + } + + /* Check for trailing backslash */ + if (EndBackslash) + { + /* Forbidden */ + Iosb.Status = STATUS_OBJECT_NAME_INVALID; + ASSERT(FALSE); + return Iosb.Status; + } + + Iosb = FatiOpenExistingFcb(IrpContext, + FileObject, + Vcb, + Fcb, DesiredAccess, ShareAccess, AllocationSize, @@ -933,50 +806,177 @@ EaLength, FileAttributes, CreateDisposition, - DeleteOnClose); - - Irp->IoStatus.Information = Iosb.Information; + NoEaKnowledge, + DeleteOnClose, + OpenedAsDos, + &OplockPostIrp); + + /* Check if it's pending */ + if (Iosb.Status != STATUS_PENDING) + { + /* In case of success set cache supported flag */ + if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering) + { + SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED); + } + + /* Save information */ + Irp->IoStatus.Information = Iosb.Information; + + /* Unlock VCB */ + FatReleaseVcb(IrpContext, Vcb); + + /* Complete the request */ + FatCompleteRequest(IrpContext, Irp, Iosb.Status); + + return Iosb.Status; + } + else + { + /* Queue this IRP */ + UNIMPLEMENTED; + ASSERT(FALSE); + } + } + else + { + /* Unexpected FCB type */ + KeBugCheckEx(/*FAT_FILE_SYSTEM*/0x23, __LINE__, (ULONG_PTR)Fcb, 0, 0); + } + } + + /* During parsing we encountered a part which has no attached FCB/DCB. + Check that the parent is really DCB and not FCB */ + if (FatNodeType(Fcb) != FAT_NTC_ROOT_DCB && + FatNodeType(Fcb) != FAT_NTC_DCB) + { + DPRINT1("Weird FCB node type %x, expected DCB or root DCB\n", FatNodeType(Fcb)); + ASSERT(FALSE); + } + + /* Create additional DCBs for all path items */ + ParentDcb = Fcb; + while (TRUE) + { + FsRtlDissectName(RemainingPart, &FirstName, &RemainingPart); + + /* Check for validity */ + if ((RemainingPart.Length && RemainingPart.Buffer[0] == L'\\') || + (NextName.Length > 255 * sizeof(WCHAR))) + { + /* The name is invalid */ + DPRINT1("Invalid name found\n"); + Iosb.Status = STATUS_OBJECT_NAME_INVALID; + ASSERT(FALSE); + } + + /* Convert the name to ANSI */ + AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length); + AnsiFirstName.Length = 0; + AnsiFirstName.MaximumLength = FirstName.Length; + Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE); + + if (!NT_SUCCESS(Status)) + { + ASSERT(FALSE); + } + + DPRINT("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart); + + /* Break if came to the end */ + if (!RemainingPart.Length) break; + + /* Create a DCB for this entry */ + ParentDcb = FatCreateDcb(IrpContext, + Vcb, + ParentDcb, + NULL); + + /* Set its name */ + FatSetFullNameInFcb(ParentDcb, &FirstName); + } + + /* Try to open it and get a result, saying if this is a dir or a file */ + FfError = FatiTryToOpen(FileObject, Vcb); + + /* Check if we need to open target directory */ + if (OpenTargetDirectory) + { + // TODO: Open target directory + UNIMPLEMENTED; + } + + /* Check, if path is a directory or a file */ + if (FfError == FF_ERR_FILE_OBJECT_IS_A_DIR) + { + if (NonDirectoryFile) + { + DPRINT1("Can't open dir as a file\n"); /* Unlock VCB */ FatReleaseVcb(IrpContext, Vcb); /* Complete the request */ - FatCompleteRequest(IrpContext, Irp, Iosb.Status); - - return Iosb.Status; - } - - /* If end backslash here, then it's definately not permitted, - since we're opening files here */ - if (EndBackslash) - { - /* Unlock VCB */ - FatReleaseVcb(IrpContext, Vcb); - - /* Complete the request */ - Iosb.Status = STATUS_OBJECT_NAME_INVALID; + Iosb.Status = STATUS_FILE_IS_A_DIRECTORY; FatCompleteRequest(IrpContext, Irp, Iosb.Status); return Iosb.Status; } - /* Try to open the file */ - Iosb = FatiOpenExistingFile(IrpContext, - FileObject, - Vcb, - ParentDcb, - DesiredAccess, - ShareAccess, - AllocationSize, - EaBuffer, - EaLength, - FileAttributes, - CreateDisposition, - FALSE, - DeleteOnClose, - OpenedAsDos); + /* Open this directory */ + Iosb = FatiOpenExistingDir(IrpContext, + FileObject, + Vcb, + ParentDcb, + DesiredAccess, + ShareAccess, + AllocationSize, + EaBuffer, + EaLength, + FileAttributes, + CreateDisposition, + DeleteOnClose); Irp->IoStatus.Information = Iosb.Information; - } + + /* Unlock VCB */ + FatReleaseVcb(IrpContext, Vcb); + + /* Complete the request */ + FatCompleteRequest(IrpContext, Irp, Iosb.Status); + + return Iosb.Status; + } + + /* If end backslash here, then it's definately not permitted, + since we're opening files here */ + if (EndBackslash) + { + /* Unlock VCB */ + FatReleaseVcb(IrpContext, Vcb); + + /* Complete the request */ + Iosb.Status = STATUS_OBJECT_NAME_INVALID; + FatCompleteRequest(IrpContext, Irp, Iosb.Status); + return Iosb.Status; + } + + /* Try to open the file */ + Iosb = FatiOpenExistingFile(IrpContext, + FileObject, + Vcb, + ParentDcb, + DesiredAccess, + ShareAccess, + AllocationSize, + EaBuffer, + EaLength, + FileAttributes, + CreateDisposition, + FALSE, + DeleteOnClose, + OpenedAsDos); + + Irp->IoStatus.Information = Iosb.Information; /* Unlock VCB */ FatReleaseVcb(IrpContext, Vcb);
14 years, 11 months
1
0
0
0
[fireball] 43643: [fastfat_new] - When creating a DCB with a known file handle, always build a full file name, because FullFAT opening code always needs a full name. - Fix debug prints (%Z -> %wZ).
by fireball@svn.reactos.org
Author: fireball Date: Tue Oct 20 12:32:37 2009 New Revision: 43643 URL:
http://svn.reactos.org/svn/reactos?rev=43643&view=rev
Log: [fastfat_new] - When creating a DCB with a known file handle, always build a full file name, because FullFAT opening code always needs a full name. - Fix debug prints (%Z -> %wZ). Modified: trunk/reactos/drivers/filesystems/fastfat_new/dir.c trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c Modified: trunk/reactos/drivers/filesystems/fastfat_new/dir.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/dir.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/dir.c [iso-8859-1] Tue Oct 20 12:32:37 2009 @@ -168,7 +168,12 @@ /* Set names */ if (FileHandle) + { FatSetFcbNames(IrpContext, Fcb); + + /* Ensure the full name is set */ + FatSetFullFileNameInFcb(IrpContext, Fcb); + } return Fcb; } Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c [iso-8859-1] Tue Oct 20 12:32:37 2009 @@ -317,7 +317,7 @@ TypeOfOpen = (*Ccb == NULL ? DirectoryFile : UserDirectoryOpen); - DPRINT1("Referencing a directory: %Z\n", &(*FcbOrDcb)->FullFileName); + DPRINT1("Referencing a directory: %wZ\n", &(*FcbOrDcb)->FullFileName); break; /* File */ @@ -327,7 +327,7 @@ TypeOfOpen = (*Ccb == NULL ? EaFile : UserFileOpen); - DPRINT("Referencing a file: %Z\n", &(*FcbOrDcb)->FullFileName); + DPRINT("Referencing a file: %wZ\n", &(*FcbOrDcb)->FullFileName); break;
14 years, 11 months
1
0
0
0
[fireball] 43642: [fastfat_new] - From the moment of statically linking to FullFAT library this driver is infected by GPLv3. Fix headers accordingly.
by fireball@svn.reactos.org
Author: fireball Date: Tue Oct 20 12:12:49 2009 New Revision: 43642 URL:
http://svn.reactos.org/svn/reactos?rev=43642&view=rev
Log: [fastfat_new] - From the moment of statically linking to FullFAT library this driver is infected by GPLv3. Fix headers accordingly. Modified: trunk/reactos/drivers/filesystems/fastfat_new/cleanup.c trunk/reactos/drivers/filesystems/fastfat_new/close.c trunk/reactos/drivers/filesystems/fastfat_new/create.c trunk/reactos/drivers/filesystems/fastfat_new/device.c trunk/reactos/drivers/filesystems/fastfat_new/dir.c trunk/reactos/drivers/filesystems/fastfat_new/ea.c trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c trunk/reactos/drivers/filesystems/fastfat_new/fastio.c trunk/reactos/drivers/filesystems/fastfat_new/fat.c trunk/reactos/drivers/filesystems/fastfat_new/fcb.c trunk/reactos/drivers/filesystems/fastfat_new/finfo.c trunk/reactos/drivers/filesystems/fastfat_new/flush.c trunk/reactos/drivers/filesystems/fastfat_new/fsctl.c trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c trunk/reactos/drivers/filesystems/fastfat_new/lock.c trunk/reactos/drivers/filesystems/fastfat_new/rw.c trunk/reactos/drivers/filesystems/fastfat_new/shutdown.c trunk/reactos/drivers/filesystems/fastfat_new/volume.c Modified: trunk/reactos/drivers/filesystems/fastfat_new/cleanup.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/cleanup.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/cleanup.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/cleanup.c * PURPOSE: Cleanup routines * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/close.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/close.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/close.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/filesystems/fastfat/cleanup.c + * LICENSE: GNU GPLv3 as published by the Free Software Foundation + * FILE: drivers/filesystems/fastfat/close.c * PURPOSE: Closing routines * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) */ Modified: trunk/reactos/drivers/filesystems/fastfat_new/create.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/create.c * PURPOSE: Create routines * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/device.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/device.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/device.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/device.c * PURPOSE: Device control * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/dir.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/dir.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/dir.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/dir.c * PURPOSE: Directory Control * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/ea.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/ea.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/ea.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/ea.c * PURPOSE: Extended Attributes support * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/fastfat.c * PURPOSE: Initialization routines * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastio.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fastio.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fastio.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/fastio.c * PURPOSE: Fast IO routines * PROGRAMMERS: Herve Poussineau (hpoussin(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/fat.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/fat.c * PURPOSE: FAT support routines * PROGRAMMERS: Aleksey Bragin <aleksey(a)reactos.org> Modified: trunk/reactos/drivers/filesystems/fastfat_new/fcb.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fcb.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fcb.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/fcb.c * PURPOSE: FCB manipulation routines. * PROGRAMMERS: Aleksey Bragin <aleksey(a)reactos.org> Modified: trunk/reactos/drivers/filesystems/fastfat_new/finfo.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/finfo.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/finfo.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/finfo.c * PURPOSE: File Information support routines * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/flush.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/flush.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/flush.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/flush.c * PURPOSE: Flushing routines * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/fsctl.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fsctl.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fsctl.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/fsctl.c * PURPOSE: Filesystem control * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/fullfat.c * PURPOSE: FullFAT integration routines * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/lock.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/lock.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/lock.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/lock.c * PURPOSE: Lock support routines * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/rw.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/rw.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/rw.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/rw.c * PURPOSE: Read/write support * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/shutdown.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/shutdown.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/shutdown.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/shutdown.c * PURPOSE: Shutdown support routines * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) Modified: trunk/reactos/drivers/filesystems/fastfat_new/volume.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/volume.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/volume.c [iso-8859-1] Tue Oct 20 12:12:49 2009 @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GNU GPLv3 as published by the Free Software Foundation * FILE: drivers/filesystems/fastfat/volume.c * PURPOSE: Volume information * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org)
14 years, 11 months
1
0
0
0
[fireball] 43641: [fastfat_new] - Cleanup the source code from parts which aren't needed anymore (after switching to FullFAT library usage). About 40kb of source code removed.
by fireball@svn.reactos.org
Author: fireball Date: Tue Oct 20 12:02:27 2009 New Revision: 43641 URL:
http://svn.reactos.org/svn/reactos?rev=43641&view=rev
Log: [fastfat_new] - Cleanup the source code from parts which aren't needed anymore (after switching to FullFAT library usage). About 40kb of source code removed. Removed: trunk/reactos/drivers/filesystems/fastfat_new/blockdev.c trunk/reactos/drivers/filesystems/fastfat_new/direntry.c Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h trunk/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild trunk/reactos/drivers/filesystems/fastfat_new/fat.c trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c trunk/reactos/drivers/filesystems/fastfat_new/rw.c Removed: trunk/reactos/drivers/filesystems/fastfat_new/blockdev.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/blockdev.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/blockdev.c (removed) @@ -1,447 +1,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/filesystems/fastfat/blockdev.c - * PURPOSE: Temporary sector reading support - * PROGRAMMERS: Alexey Vlasov - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* FUNCTIONS ***************************************************************/ -//FIXME: There is a conflicting function FatPerformDevIoCtrl doing same thing! -NTSTATUS -FatDiskIoControl_( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG IoCtlCode, - IN PVOID InputBuffer, - IN ULONG InputBufferSize, - IN OUT PVOID OutputBuffer, - IN OUT PULONG OutputBufferSize OPTIONAL) -{ - PIRP Irp; - KEVENT Event; - NTSTATUS Status; - ULONG OutBufferSize; - IO_STATUS_BLOCK IoStatus; - - /* Set out buffer size if it was supplied. */ - OutBufferSize = (ARGUMENT_PRESENT(OutputBufferSize) - ? 0 : *OutputBufferSize); - - /* Initialize event if the operation will be pended. */ - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - /* Build the Irp. */ - Irp = IoBuildDeviceIoControlRequest(IoCtlCode, DeviceObject, - InputBuffer, InputBufferSize, OutputBuffer, OutBufferSize, - FALSE, &Event, &IoStatus); - if (Irp == NULL) - return STATUS_INSUFFICIENT_RESOURCES; - - /* Send IRP to Disk Device */ - Status = IoCallDriver(DeviceObject, Irp); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = IoStatus.Status; - } - - /* Return output buffer length if required. */ - if (ARGUMENT_PRESENT(OutputBufferSize)) - *OutputBufferSize = IoStatus.Information; - return Status; -} - -NTSTATUS -FatLockUserBuffer ( - IN PFAT_IRP_CONTEXT IrpContext, - IN LOCK_OPERATION Operation, - IN ULONG BufferLength) -/* - * FUNCTION: - * - * - * ARGUMENTS: - * IrpContext = Pointer to FCB structure for the file. - * Operation = Type of lock operation. - * BufferLength = Buffer length to be locked. - * RETURNS: Status Value. - * NOTES: - */ -{ - PMDL Mdl; - PIRP Irp; - NTSTATUS Status; - - Mdl = NULL; - Irp = IrpContext->Irp; - Status = STATUS_SUCCESS; - if (Irp->MdlAddress == NULL) - { - NTSTATUS Status; - Mdl = IoAllocateMdl(Irp->UserBuffer, - BufferLength, FALSE, FALSE, Irp); - if (Mdl == NULL) - return STATUS_INSUFFICIENT_RESOURCES; - _SEH2_TRY - { - MmProbeAndLockPages(Mdl, - Irp->RequestorMode, Operation); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - IoFreeMdl( Mdl ); - Irp->MdlAddress = NULL; - } _SEH2_END - } - return Status; -} - -NTSTATUS -FatIoSyncCompletionRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context) -{ - PFAT_IO_CONTEXT IoContext; - - IoContext = (PFAT_IO_CONTEXT) Context; - - /* Check if this is an associated irp. */ - if (Irp != IoContext->Irp) - { - if (!NT_SUCCESS(Irp->IoStatus.Status)) - IoContext->Irp->IoStatus = Irp->IoStatus; - IoFreeMdl(Irp->MdlAddress); - IoFreeIrp(Irp); - if (InterlockedDecrement(&IoContext->RunCount) != 0) - return STATUS_MORE_PROCESSING_REQUIRED; - /* This was the last run, update master irp. */ - if (NT_SUCCESS(IoContext->Irp->IoStatus.Status)) - IoContext->Irp->IoStatus.Information = IoContext->Length; - } - - /* This is the last associated irp or a single irp IO. */ - if (NT_SUCCESS(IoContext->Irp->IoStatus.Status) && - !FlagOn(IoContext->Irp->Flags, IRP_PAGING_IO)) - { - /* Maintain FileObject CurrentByteOffset */ - IoContext->FileObject->CurrentByteOffset.QuadPart = - IoContext->Offset + IoContext->Irp->IoStatus.Information; - } - - /* Signal about completion. */ - KeSetEvent(&IoContext->Wait.SyncEvent, 0, FALSE); - return STATUS_MORE_PROCESSING_REQUIRED; -} - -NTSTATUS -FatIoAsyncCompletionRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context) -{ - PFAT_IO_CONTEXT IoContext; - - IoContext = (PFAT_IO_CONTEXT) Context; - - /* Check if this is an associated irp. */ - if (Irp != IoContext->Irp) - { - if (!NT_SUCCESS(Irp->IoStatus.Status)) - IoContext->Irp->IoStatus = Irp->IoStatus; - IoFreeMdl(Irp->MdlAddress); - IoFreeIrp(Irp); - if (InterlockedDecrement(&IoContext->RunCount) != 0) - return STATUS_MORE_PROCESSING_REQUIRED; - /* This was the last run, update master irp. */ - if (NT_SUCCESS(IoContext->Irp->IoStatus.Status)) - IoContext->Irp->IoStatus.Information = IoContext->Length; - } - - - /* This is the last associated irp or a single irp IO. */ - if (NT_SUCCESS(IoContext->Irp->IoStatus.Status) && - !FlagOn(IoContext->Irp->Flags, IRP_PAGING_IO)) - { - /* Maintain FileObject Flags */ - if (IoGetCurrentIrpStackLocation(IoContext->Irp)->MajorFunction - == IRP_MJ_READ) - { - SetFlag(IoContext->FileObject->Flags, FO_FILE_FAST_IO_READ); - } - else - { - SetFlag(IoContext->FileObject->Flags, FO_FILE_MODIFIED); - } - } - if (IoContext->Wait.Async.Resource != NULL) - ExReleaseResourceForThreadLite( - IoContext->Wait.Async.Resource, - IoContext->Wait.Async.ResourceThreadId); - - if (IoContext->Wait.Async.PagingIoResource != NULL) - ExReleaseResourceForThreadLite( - IoContext->Wait.Async.PagingIoResource, - IoContext->Wait.Async.ResourceThreadId); - - IoMarkIrpPending(Irp); - ExFreePool(Context); - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -FatPerformLboIo( - IN PFAT_IRP_CONTEXT IrpContext, - IN PLARGE_INTEGER Offset, - IN SIZE_T Length) -{ - BOOLEAN CanWait, ReadOperation; - PIO_STACK_LOCATION IoStack; - - CanWait = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT); - ReadOperation = (IrpContext->Stack->MajorFunction == IRP_MJ_READ); - - /* Allocate completion context */ - IrpContext->FatIoContext = FsRtlAllocatePoolWithTag( - NonPagedPool, sizeof(FAT_IO_CONTEXT), (ULONG) 'xCoI'); - - if (IrpContext->FatIoContext == NULL) - return STATUS_INSUFFICIENT_RESOURCES; - - RtlZeroMemory(IrpContext->FatIoContext, - sizeof(FAT_IO_CONTEXT)); - - /* Initialize event if we are supposed to wait. */ - if (CanWait) - { - KeInitializeEvent( - &IrpContext->FatIoContext->Wait.SyncEvent, - NotificationEvent, FALSE); - } - - /* Set the completion routine depending on wait semantics. */ - IoSetCompletionRoutine(IrpContext->Irp, - (CanWait - ? FatIoSyncCompletionRoutine - : FatIoAsyncCompletionRoutine), - IrpContext->FatIoContext, TRUE, TRUE, TRUE); - - /* Setup stack location. */ - IoStack = IoGetNextIrpStackLocation(IrpContext->Irp); - IoStack->MajorFunction = IrpContext->MajorFunction; - IoStack->Parameters.Read.Length = (ULONG) Length; - IoStack->Parameters.Read.ByteOffset = *Offset; - if (FlagOn(IrpContext->Flags, IRPCONTEXT_WRITETHROUGH)) - SetFlag(IoStack->Flags, SL_WRITE_THROUGH); - - IoCallDriver( - IrpContext->Vcb->TargetDeviceObject, - IrpContext->Irp); - if (CanWait) - { - KeWaitForSingleObject( - &IrpContext->FatIoContext->Wait.SyncEvent, - Executive, KernelMode, FALSE, NULL); - return IrpContext->Irp->IoStatus.Status; - } - SetFlag(IrpContext->Flags, IRPCONTEXT_STACK_IO_CONTEXT); - return STATUS_PENDING; -} - - - -NTSTATUS -FatPerformVirtualNonCachedIo( - IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PLARGE_INTEGER Offset, - IN SIZE_T Length) -{ - NTSTATUS Status; - PIO_STACK_LOCATION IoStack; - LONGLONG Vbo, Lbo, RunLength; - ULONG RunCount, CleanupIndex, FirstIndex, BeyoundLastIndex; - BOOLEAN CanWait, ReadOperation; - PIRP* RunIrp; - PMDL Mdl; - - ASSERT(IrpContext->FatIoContext == NULL); - - - FirstIndex = CleanupIndex = 0; - CanWait = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT); - ReadOperation = (IrpContext->Stack->MajorFunction == IRP_MJ_READ); - Status = FatLockUserBuffer(IrpContext, - (ReadOperation ? IoWriteAccess : IoReadAccess), - Length); - if (!NT_SUCCESS(Status)) - goto FatIoPerformNonCachedCleanup; - Vbo = Offset->QuadPart; - RunLength = Length; - _SEH2_TRY - { - BeyoundLastIndex = FatScanFat(Fcb, Vbo, - &Lbo, &RunLength, &FirstIndex, CanWait); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - _SEH2_YIELD(goto FatIoPerformNonCachedCleanup;) - }_SEH2_END - RunCount = BeyoundLastIndex - FirstIndex; - if (RunCount == 0) - { - Status = STATUS_END_OF_FILE; - goto FatIoPerformNonCachedCleanup; - } - Length = sizeof(FAT_IO_CONTEXT); - if (RunCount > 0x1) - Length += RunCount * sizeof(PIRP); - IrpContext->FatIoContext = FsRtlAllocatePoolWithTag( - NonPagedPool, Length, (ULONG) 'xCoI'); - if (IrpContext->FatIoContext == NULL) - { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto FatIoPerformNonCachedCleanup; - } - RtlZeroMemory(IrpContext->FatIoContext, Length); - if (CanWait) - { - KeInitializeEvent( - &IrpContext->FatIoContext->Wait.SyncEvent, - NotificationEvent, FALSE); - } - if (RunCount == 0x1) - { - IoSetCompletionRoutine(IrpContext->Irp, - (CanWait ? FatIoSyncCompletionRoutine - : FatIoAsyncCompletionRoutine), - IrpContext->FatIoContext, TRUE, TRUE, TRUE); - IoStack = IoGetNextIrpStackLocation(IrpContext->Irp); - IoStack->MajorFunction = IrpContext->Stack->MajorFunction; - IoStack->Parameters.Read.Length = (ULONG) RunLength; - IoStack->Parameters.Read.ByteOffset.QuadPart = Lbo; - IoStack->Flags = FlagOn( - IrpContext->Stack->Flags, - SL_WRITE_THROUGH); - Status = IoCallDriver( - IrpContext->Vcb->TargetDeviceObject, - IrpContext->Irp); - goto FatIoPerformNonCachedComplete; - } - /* - * We already have the first run retrieved by FatiScanFat. - */ - for (RunIrp = &IrpContext->FatIoContext->Irp, - CleanupIndex = FirstIndex; - CleanupIndex < BeyoundLastIndex; - CleanupIndex ++, RunIrp ++) - { -#if DBG - LONGLONG NextVbo = Vbo + RunLength; - BOOLEAN RunExists; -#endif - /* - * Allocate Irp for the run. - */ - *RunIrp = IoMakeAssociatedIrp(IrpContext->Irp, - (CCHAR)(IrpContext->Vcb->TargetDeviceObject->StackSize + 1)); - if (*RunIrp == NULL) - { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto FatIoPerformNonCachedCleanup; - } - CleanupIndex ++; - /* - * Build Mdl for the run range. - */ - Mdl = IoAllocateMdl( - Add2Ptr(IrpContext->Irp->UserBuffer, Vbo, PVOID), - (ULONG) RunLength, FALSE, FALSE, *RunIrp); - if (Mdl == NULL) - { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto FatIoPerformNonCachedCleanup; - } - IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Mdl, - Add2Ptr(IrpContext->Irp->UserBuffer, Vbo, PVOID), - (ULONG) RunLength); - /* - * Setup IRP for each run. - */ - IoSetCompletionRoutine(IrpContext->Irp, - (CanWait ? FatIoSyncCompletionRoutine - : FatIoAsyncCompletionRoutine), - IrpContext->FatIoContext, TRUE, TRUE, TRUE); - IoStack = IoGetNextIrpStackLocation(*RunIrp); - IoStack->MajorFunction = IrpContext->Stack->MajorFunction; - IoStack->Parameters.Read.Length = (ULONG) RunLength; - IoStack->Parameters.Read.ByteOffset.QuadPart = Lbo; - - /* - * Propagate write-through to the associated IRPs - */ - if (FlagOn(IrpContext->Flags, IRPCONTEXT_WRITETHROUGH)) - SetFlag(IoStack->Flags, SL_WRITE_THROUGH); - /* - * Prepare for next iteration: - */ - #if DBG - RunExists = - #endif - FsRtlGetNextLargeMcbEntry(&Fcb->Mcb, CleanupIndex, &Vbo, &Lbo, &RunLength); - ASSERT(RunExists); - ASSERT(NextVbo == Vbo); - } - /* - * Send all IRPs to the volume device, we don't need to check - * status code because cleanup will be done - * by the completion routine in any case. - */ - for (RunIrp = &IrpContext->FatIoContext->Irp, - CleanupIndex = FirstIndex; - CleanupIndex < BeyoundLastIndex; - CleanupIndex ++, RunIrp ++) - { - IoCallDriver(IrpContext->Vcb->TargetDeviceObject, *RunIrp); - } - -FatIoPerformNonCachedComplete: - if (CanWait) - { - KeWaitForSingleObject( - &IrpContext->FatIoContext->Wait.SyncEvent, - Executive, KernelMode, FALSE, NULL); - return IrpContext->Irp->IoStatus.Status; - } - SetFlag(IrpContext->Flags, IRPCONTEXT_STACK_IO_CONTEXT); - return STATUS_PENDING; - /* - * The following block of code implements unwind logic - */ -FatIoPerformNonCachedCleanup: - if (IrpContext->FatIoContext != NULL) - { - RunIrp = &IrpContext->FatIoContext->Irp; - while (FirstIndex < CleanupIndex) - { - if ((*RunIrp)->MdlAddress != NULL) - IoFreeMdl((*RunIrp)->MdlAddress); - IoFreeIrp(*RunIrp); - FirstIndex ++; - RunIrp ++; - } - ExFreePool(IrpContext->FatIoContext); - IrpContext->FatIoContext = NULL; - } - return Status; -} - -/* EOF */ Removed: trunk/reactos/drivers/filesystems/fastfat_new/direntry.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/direntry.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/direntry.c (removed) @@ -1,775 +1,0 @@ -/* - * PROJECT: ReactOS FAT file system driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/filesystems/fastfat/direntry.c - * PURPOSE: Directory entries - * PROGRAMMERS: Alexey Vlasov - */ - -/* INCLUDES *****************************************************************/ - -#define NDEBUG -#include "fastfat.h" - -/* PROTOTYPES ***************************************************************/ - -typedef enum _FILE_TIME_INDEX -{ - FileCreationTime = 0, - FileLastAccessTime, - FileLastWriteTime, - FileChangeTime -} FILE_TIME_INDEX; - - -VOID -Fat8dot3ToUnicodeString(OUT PUNICODE_STRING FileName, - IN PUCHAR ShortName, - IN UCHAR Flags); - -ULONG -FatDirentToDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer); - -ULONG -FatDirentToFullDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer); - -ULONG -FatDirentToIdFullDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer); - -ULONG -FatDirentToBothDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer); - -ULONG -FatDirentToIdBothDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer); - -ULONG -FatDirentToNamesInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer); - -ULONG -FatDirentToObjectIdInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer); - -/* FUNCTIONS *****************************************************************/ - -#define FatQueryFileName(xInfo, xDirent) \ -{ \ - UNICODE_STRING FileName; \ - if (Info->FileNameLength == 0) \ - { \ - FileName.Buffer = Info->FileName; \ - FileName.MaximumLength = 0x18; \ - Fat8dot3ToUnicodeString(&FileName, \ - (xDirent)->FileName, (xDirent)->Case); \ - Info->FileNameLength = FileName.Length; \ - } \ -} - -#define FatQueryBothFileName(xInfo, xDirent) \ -{ \ - UNICODE_STRING FileName; \ - FileName.MaximumLength = 0x18; \ - if (Info->FileNameLength == 0) \ - { \ - FileName.Buffer = Info->FileName; \ - Fat8dot3ToUnicodeString(&FileName, \ - (xDirent)->FileName, (xDirent)->Case); \ - Info->FileNameLength = FileName.Length; \ - Info->ShortNameLength = 0; \ - } \ - else \ - { \ - FileName.Buffer = Info->ShortName; \ - Fat8dot3ToUnicodeString(&FileName, \ - (xDirent)->FileName, (xDirent)->Case); \ - Info->ShortNameLength = (CCHAR) FileName.Length; \ - } \ -} - -FORCEINLINE -UCHAR -FatLfnChecksum( - PUCHAR Buffer -) -{ - UCHAR Index, Chksum; - - for (Index = 0x1, Chksum = *Buffer; - Index < RTL_FIELD_SIZE(DIR_ENTRY, FileName); - Index ++) - { - Chksum = (((Chksum & 0x1) << 0x7) | (Chksum >> 0x1)) - + Buffer[Index]; - } - return Chksum; -} - -VOID -FatFindDirent(IN OUT PFAT_FIND_DIRENT_CONTEXT Context, - OUT PDIR_ENTRY* Dirent, - OUT PUNICODE_STRING LongFileName OPTIONAL) -{ - PDIR_ENTRY Entry, EndOfPage; - UCHAR SeqNum = 0, Checksum = 0; - PUNICODE_STRING FileName; - - /* Pin first page. */ - Entry = (PDIR_ENTRY) FatPinPage(&Context->Page, 0); - EndOfPage = FatPinEndOfPage(&Context->Page, PDIR_ENTRY); - - /* Run dirents. */ - FileName = NULL; - while (TRUE) - { - /* Check if we have entered the area of never used dirents */ - if (Entry->FileName[0] == FAT_DIRENT_NEVER_USED) - ExRaiseStatus(STATUS_OBJECT_NAME_NOT_FOUND); - - /* Just ignore entries marked as deleted */ - if (Entry->FileName[0] == FAT_DIRENT_DELETED) - goto FatFindDirentNext; - - /* Check if it's an lfn */ - if (Entry->Attributes == FAT_DIRENT_ATTR_LFN) - { - PLONG_FILE_NAME_ENTRY LfnEntry; - - FileName = LongFileName; - LfnEntry = (PLONG_FILE_NAME_ENTRY) Entry; - - /* Run lfns and collect file name if required */ - do { - PWSTR Lfn; - - /* Check if we just running lfn */ - if (FileName == NULL) - goto FatFindDirentRunLfn; - - /* Check for cluster index to be zero. */ - if (LfnEntry->Reserved != 0) - { - FileName = NULL; - goto FatFindDirentRunLfn; - } - - /* Check if this is the last lfn entry. */ - if (FlagOn(LfnEntry->SeqNum, FAT_FN_DIR_ENTRY_LAST)) - { - SeqNum = (LfnEntry->SeqNum & ~FAT_FN_DIR_ENTRY_LAST); - Checksum = LfnEntry->Checksum; - - /* Check if we exceed max number of lfns */ - if (SeqNum > (FAT_FN_MAX_DIR_ENTIES + 1)) - { - FileName = NULL; - goto FatFindDirentRunLfn; - } - - /* Setup maximal expected lfn length */ - FileName->Length = (SeqNum * FAT_LFN_NAME_LENGTH); - - /* Extend lfn buffer if needed */ - if (FileName->Length > FileName->MaximumLength) - { - Lfn = ExAllocatePoolWithTag(PagedPool, - LongFileName->Length, TAG_VFAT); - if (Lfn == NULL) - ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); - if (FileName->Buffer != NULL) - ExFreePool(FileName->Buffer); - FileName->Buffer = Lfn; - FileName->MaximumLength = FileName->Length; - } - } - else if (!(LfnEntry->SeqNum == SeqNum - && LfnEntry->Checksum == Checksum)) - { - /* Wrong SeqNum or CheckSum. */ - FileName = NULL; - goto FatFindDirentRunLfn; - } - /* Gather file name */ - Lfn = Add2Ptr(FileName->Buffer, (SeqNum * FAT_LFN_NAME_LENGTH) - - sizeof(LfnEntry->NameC), PWSTR); - RtlCopyMemory(Lfn, LfnEntry->NameC, sizeof(LfnEntry->NameC)); - Lfn -= (sizeof(LfnEntry->NameB) / sizeof(WCHAR)); - RtlCopyMemory(Lfn, LfnEntry->NameB, sizeof(LfnEntry->NameB)); - Lfn -= (sizeof(LfnEntry->NameA) / sizeof(WCHAR)); - RtlCopyMemory(Lfn, LfnEntry->NameA, sizeof(LfnEntry->NameA)); - - /* If last lfn determine exact lfn length. */ - if (FlagOn(LfnEntry->SeqNum, FAT_FN_DIR_ENTRY_LAST)) - { - PWSTR LfnEnd = Add2Ptr(FileName->Buffer, - (FileName->Length - sizeof(WCHAR)), PWSTR); - - /* Trim trailing 0xffff's */ - while (LfnEnd > Lfn && *LfnEnd == 0xffff) --LfnEnd; - - /* Trim 0 terminator is the one is there. */ - if (*LfnEnd == 0x0) --LfnEnd; - - /* Set correct lfn size */ - FileName->Length = (USHORT)PtrOffset(FileName->Buffer, LfnEnd); - } - /* Setup validation for the next iteration */ - SeqNum = LfnEntry->SeqNum - 0x1; - Checksum = LfnEntry->Checksum; - -FatFindDirentRunLfn: - /* Get next dirent */ - LfnEntry ++; - if (LfnEntry > (PLONG_FILE_NAME_ENTRY) EndOfPage) - { - if (FatPinIsLastPage(&Context->Page)) - ExRaiseStatus(STATUS_OBJECT_NAME_NOT_FOUND); - LfnEntry = (PLONG_FILE_NAME_ENTRY) FatPinNextPage(&Context->Page); - EndOfPage = FatPinEndOfPage(&Context->Page, PDIR_ENTRY); - } - } - while (LfnEntry->Attributes == FAT_DIRENT_ATTR_LFN); - Entry = (PDIR_ENTRY) LfnEntry; - continue; - } - - /* If we've got here then this is a normal dirent */ - if (FileName != NULL && FileName->Length > 0) - { - /* Check if we have a correct lfn collected. */ - if (FatLfnChecksum(Entry->FileName) != Checksum) - { - FileName = NULL; - } - else - { - /* See if we were looking for this dirent. */ - if (!Context->Valid8dot3Name && - FsRtlAreNamesEqual(FileName, Context->FileName, TRUE, NULL)) - { - Fat8dot3ToUnicodeString(&Context->ShortName, Entry->FileName, Entry->Case); - *Dirent = Entry; - return; - } - } - } - - /* We surely have a short name, check if we were looking for that. */ - if (Context->Valid8dot3Name) - { - Fat8dot3ToUnicodeString(&Context->ShortName, - Entry->FileName, Entry->Case); - if (FsRtlAreNamesEqual(&Context->ShortName, Context->FileName, TRUE, NULL)) - { - if (ARGUMENT_PRESENT(LongFileName) && FileName == NULL) - LongFileName->Length = 0; - *Dirent = Entry; - return; - } - } - FileName = NULL; - -FatFindDirentNext: - Entry ++; - if (Entry > EndOfPage) - { - if (FatPinIsLastPage(&Context->Page)) - ExRaiseStatus(STATUS_OBJECT_NAME_NOT_FOUND); - Entry = (PDIR_ENTRY) FatPinNextPage(&Context->Page); - EndOfPage = FatPinEndOfPage(&Context->Page, PDIR_ENTRY); - } - } - /* Should never get here! */ - ASSERT(TRUE); -} - -VOID -FatEnumerateDirents(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN SIZE_T Offset) -{ - PUCHAR Entry, EndOfPage; - PWSTR FileName; - USHORT FileNameLength; - USHORT FileNameMaximumLength; - PVOID InfoEntry; - UCHAR SeqNum = 0; - UCHAR Checksum = 0; - - /* Pin first page. */ - Entry = (PUCHAR)FatPinPage(&Context->Page, Offset); - EndOfPage = FatPinEndOfPage(&Context->Page, PUCHAR); - - /* Iterate dirents. */ - while (TRUE) - { - /* Check if we have entered the area of never used dirents */ - if (*Entry == FAT_DIRENT_NEVER_USED) - ExRaiseStatus(STATUS_NO_MORE_FILES); - - /* Just ignore entries marked as deleted */ - if (*Entry == FAT_DIRENT_DELETED) - goto FatEnumerateDirentsNext; - - /* Get info pointer. */ - InfoEntry = Add2Ptr(Context->Buffer, Context->Offset, PVOID); - - /* Check if info class has file name */ - if (Context->NameOffset == Context->LengthOffset) - { - FileName = NULL; - FileNameMaximumLength = 0; - } - else - { - FileName = Add2Ptr(InfoEntry, Context->NameOffset, PWSTR); - FileNameMaximumLength = (USHORT) (Context->Length - - Context->Offset + Context->NameOffset); - } - FileNameLength = 0; - - /* Check if it's an lfn */ - while (Entry[0xb] == FAT_DIRENT_ATTR_LFN) - { - PWSTR Lfn; - PLONG_FILE_NAME_ENTRY LfnEntry; - - /* Check if we just running lfn */ - if (FileNameMaximumLength == 0) - goto FatEnumerateDirentsRunLfn; - - LfnEntry = (PLONG_FILE_NAME_ENTRY) Entry; - - /* Check for cluster index to be zero. */ - if (LfnEntry->Reserved != 0) - { - FileNameMaximumLength = 0; - goto FatEnumerateDirentsRunLfn; - } - - /* Check if this is the last lfn entry. */ - if (FlagOn(LfnEntry->SeqNum, FAT_FN_DIR_ENTRY_LAST)) - { - SeqNum = (LfnEntry->SeqNum & ~FAT_FN_DIR_ENTRY_LAST); - Checksum = LfnEntry->Checksum; - - /* Check if we exceed max number of lfns */ - if (SeqNum > (FAT_FN_MAX_DIR_ENTIES + 1)) - { - FileNameMaximumLength = 0; - goto FatEnumerateDirentsRunLfn; - } - - /* Setup maximal expected lfn length */ - FileNameLength = SeqNum * FAT_LFN_NAME_LENGTH; - - /* Validate the maximal expected lfn length */ - if (FileNameLength > FileNameMaximumLength) - goto FatEnumerateDirentsRunLfn; - } - else if (!(LfnEntry->SeqNum == SeqNum - && LfnEntry->Checksum == Checksum)) - { - /* Wrong SeqNum or CheckSum. */ - FileNameMaximumLength = 0; - goto FatEnumerateDirentsRunLfn; - } - /* Gather file name */ - Lfn = Add2Ptr(FileName, (SeqNum * FAT_LFN_NAME_LENGTH) - - sizeof(LfnEntry->NameC), PWSTR); - RtlCopyMemory(Lfn, LfnEntry->NameC, sizeof(LfnEntry->NameC)); - Lfn -= (sizeof(LfnEntry->NameB) / sizeof(WCHAR)); - RtlCopyMemory(Lfn, LfnEntry->NameB, sizeof(LfnEntry->NameB)); - Lfn -= (sizeof(LfnEntry->NameA) / sizeof(WCHAR)); - RtlCopyMemory(Lfn, LfnEntry->NameA, sizeof(LfnEntry->NameA)); - - /* If last lfn determine exact lfn length. */ - if (FlagOn(LfnEntry->SeqNum, FAT_FN_DIR_ENTRY_LAST)) - { - PWSTR LfnEnd = Add2Ptr(FileName, FileNameLength - - sizeof(WCHAR), PWSTR); - - /* Trim trailing 0xffff's */ - while (LfnEnd > Lfn && *LfnEnd == 0xffff) --LfnEnd; - - /* Trim 0 terminator is the one is there. */ - if (*LfnEnd == 0x0) --LfnEnd; - - /* Set correct lfn size */ - FileNameLength = (USHORT)PtrOffset(FileName, LfnEnd); - } - /* Setup vaidation for the next iteration */ - SeqNum = LfnEntry->SeqNum - 0x1; - Checksum = LfnEntry->Checksum; -FatEnumerateDirentsRunLfn: - Entry = Add2Ptr(Entry, sizeof(DIR_ENTRY), PUCHAR); - if (Entry > EndOfPage) - { - if (FatPinIsLastPage(&Context->Page)) - ExRaiseStatus(STATUS_NO_MORE_FILES); - Entry = (PUCHAR) FatPinNextPage(&Context->Page); - EndOfPage = FatPinEndOfPage(&Context->Page, PUCHAR); - } - } - - /* if lfn was found, validate and commit. */ - if (FileNameLength > 0 && FatLfnChecksum(Entry) == Checksum) - { - *Add2Ptr(InfoEntry, Context->LengthOffset, PULONG) = FileNameLength; - } - else - { - *Add2Ptr(InfoEntry, Context->LengthOffset, PULONG) = 0; - } - /* TODO: Implement Filtering using Context->FileName & Context->CcbFlags. */ - - /* Copy the entry values. */ - Context->Offset += Context->CopyDirent((PFAT_ENUM_DIR_CONTEXT)Context, (PDIR_ENTRY) Entry, InfoEntry); - -FatEnumerateDirentsNext: - /* Get next entry */ - Entry = Add2Ptr(Entry, sizeof(DIR_ENTRY), PUCHAR); - if (Entry > EndOfPage) - { - if (FatPinIsLastPage(&Context->Page)) - ExRaiseStatus(STATUS_NO_MORE_FILES); - Entry = (PUCHAR) FatPinNextPage(&Context->Page); - EndOfPage = FatPinEndOfPage(&Context->Page, PUCHAR); - } - } -} - -FORCEINLINE -VOID -FatDateTimeToSystemTime(OUT PLARGE_INTEGER SystemTime, - IN PFAT_DATETIME FatDateTime, - IN UCHAR TenMs OPTIONAL) -{ - TIME_FIELDS TimeFields; - - /* Setup time fields */ - TimeFields.Year = FatDateTime->Date.Year + 1980; - TimeFields.Month = FatDateTime->Date.Month; - TimeFields.Day = FatDateTime->Date.Day; - TimeFields.Hour = FatDateTime->Time.Hour; - TimeFields.Minute = FatDateTime->Time.Minute; - TimeFields.Second = (FatDateTime->Time.DoubleSeconds << 1); - - /* Adjust up to 10 milliseconds - * if the parameter was supplied - */ - if (ARGUMENT_PRESENT(TenMs)) - { - TimeFields.Second += TenMs / 100; - TimeFields.Milliseconds = (TenMs % 100) * 10; - } - else - { - TimeFields.Milliseconds = 0; - } - - /* Fix seconds value that might get beyoud the bound */ - if (TimeFields.Second > 59) TimeFields.Second = 0; - - /* Perform ceonversion to system time if possible */ - if (RtlTimeFieldsToTime(&TimeFields, SystemTime)) - { - /* Convert to system time */ - ExLocalTimeToSystemTime(SystemTime, SystemTime); - } - else - { - /* Set to default time if conversion failed */ - *SystemTime = FatGlobalData.DefaultFileTime; - } -} - -VOID -FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes, - IN PDIR_ENTRY Dirent) -{ - /* Convert LastWriteTime */ - FatDateTimeToSystemTime(&FileTimes[FileLastWriteTime], - &Dirent->LastWriteDateTime, - 0); - /* All other time fileds are valid (according to MS) - * only if Win31 compatability mode is set. - */ - if (FatGlobalData.Win31FileSystem) - { - /* We can avoid calling conversion routine - * if time in dirent is 0 or equals to already - * known time (LastWriteTime). - */ - if (Dirent->CreationDateTime.Value == 0) - { - /* Set it to default time */ - FileTimes[FileCreationTime] = FatGlobalData.DefaultFileTime; - } - else if (Dirent->CreationDateTime.Value - == Dirent->LastWriteDateTime.Value) - { - /* Assign the already known time */ - FileTimes[FileCreationTime] = FileTimes[FileLastWriteTime]; - /* Adjust milliseconds from extra dirent field */ - FileTimes[FileCreationTime].QuadPart - += (ULONG) Dirent->CreationTimeTenMs * 100000; - } - else - { - /* Perform conversion */ - FatDateTimeToSystemTime(&FileTimes[FileCreationTime], - &Dirent->CreationDateTime, - Dirent->CreationTimeTenMs); - } - if (Dirent->LastAccessDate.Value == 0) - { - /* Set it to default time */ - FileTimes[FileLastAccessTime] = FatGlobalData.DefaultFileTime; - } - else if (Dirent->LastAccessDate.Value - == Dirent->LastWriteDateTime.Date.Value) - { - /* Assign the already known time */ - FileTimes[FileLastAccessTime] = FileTimes[FileLastWriteTime]; - } - else - { - /* Perform conversion */ - FAT_DATETIME LastAccessDateTime; - - LastAccessDateTime.Date.Value = Dirent->LastAccessDate.Value; - LastAccessDateTime.Time.Value = 0; - FatDateTimeToSystemTime(&FileTimes[FileLastAccessTime], - &LastAccessDateTime, - 0); - } - } -} - -VOID -Fat8dot3ToUnicodeString(OUT PUNICODE_STRING FileName, - IN PUCHAR ShortName, - IN UCHAR Flags) -{ - PCHAR Name; - UCHAR Index, Ext = 0; - OEM_STRING Oem; - - Name = Add2Ptr(FileName->Buffer, 0x0c, PCHAR); - RtlCopyMemory(Name, ShortName, 0x0b); - - /* Restore the name byte used to mark deleted entries */ - if (Name[0] == 0x05) - Name[0] |= 0xe0; - - /* Locate the end of name part */ - for (Index = 0; Index < 0x08 - && Name[Index] != 0x20; Index++); - - /* Locate the end of extension part */ - if (Name[0x08] != 0x20) - { - Ext = 0x2; - Name[Index++] = 0x2e; - Name[Index++] = Name[0x08]; - if ((Name[Index] = Name[0x09]) != 0x20) - { - Index ++; Ext ++; - } - if ((Name[Index] = Name[0x0a]) != 0x20) - { - Index ++; Ext ++; - } - } - - /* Perform Oem to Unicode conversion. */ - Oem.Buffer = Name; - Oem.Length = Index; - Oem.MaximumLength = Index; - RtlOemStringToUnicodeString(FileName, &Oem, FALSE); - Index = FlagOn(Flags, FAT_CASE_LOWER_BASE|FAT_CASE_LOWER_EXT); - if (Index > 0) - { - /* Downcase the whole name */ - if (Index == (FAT_CASE_LOWER_BASE|FAT_CASE_LOWER_EXT)) - { - RtlUpcaseUnicodeString(FileName, FileName, FALSE); - } - else - { - if (Index == FAT_CASE_LOWER_EXT) - { - /* Set extension for downcase */ - Oem.Length = Ext * sizeof(WCHAR); - Oem.Buffer = Add2Ptr(FileName->Buffer, - FileName->Length - Oem.Length, - PSTR); - } - else - { - /* Set base name for downcase */ - Oem.Buffer = (PSTR) FileName->Buffer; - Oem.Length = FileName->Length - Ext * sizeof(WCHAR); - } - Oem.MaximumLength = Oem.Length; - RtlUpcaseUnicodeString((PUNICODE_STRING)&Oem, - (PUNICODE_STRING)&Oem, - FALSE); - } - } -} - -ULONG -FatDirentToDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer) -{ - PFILE_DIRECTORY_INFORMATION Info; - Info = (PFILE_DIRECTORY_INFORMATION) Buffer; - Info->FileIndex = 0; - /* Setup Attributes */ - Info->FileAttributes = Dirent->Attributes; - /* Setup times */ - FatQueryFileTimes(&Info->CreationTime, Dirent); - /* Setup sizes */ - Info->EndOfFile.QuadPart = Dirent->FileSize; - Info->AllocationSize.QuadPart = - (Context->BytesPerClusterMask + Dirent->FileSize) - & ~(Context->BytesPerClusterMask); - FatQueryFileName(Info, Dirent); - Info->NextEntryOffset = sizeof(*Info); - return Info->NextEntryOffset + Info->FileNameLength; -} - -ULONG -FatDirentToFullDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer) -{ - PFILE_FULL_DIR_INFORMATION Info; - Info = (PFILE_FULL_DIR_INFORMATION) Buffer; - Info->FileIndex = 0; - Info->EaSize = 0; - /* Setup Attributes */ - Info->FileAttributes = Dirent->Attributes; - /* Setup times */ - FatQueryFileTimes(&Info->CreationTime, Dirent); - /* Setup sizes */ - Info->EndOfFile.QuadPart = Dirent->FileSize; - Info->AllocationSize.QuadPart = - (Context->BytesPerClusterMask + Dirent->FileSize) - & ~(Context->BytesPerClusterMask); - FatQueryFileName(Info, Dirent); - Info->NextEntryOffset = sizeof(*Info); - return Info->NextEntryOffset + Info->FileNameLength; -} - -ULONG -FatDirentToIdFullDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer) -{ - PFILE_ID_FULL_DIR_INFORMATION Info; - Info = (PFILE_ID_FULL_DIR_INFORMATION) Buffer; - Info->FileId.QuadPart = 0; - Info->FileIndex = 0; - Info->EaSize = 0; - /* Setup Attributes */ - Info->FileAttributes = Dirent->Attributes; - /* Setup times */ - FatQueryFileTimes(&Info->CreationTime, Dirent); - /* Setup sizes */ - Info->EndOfFile.QuadPart = Dirent->FileSize; - Info->AllocationSize.QuadPart = - (Context->BytesPerClusterMask + Dirent->FileSize) - & ~(Context->BytesPerClusterMask); - FatQueryFileName(Info, Dirent); - Info->NextEntryOffset = sizeof(*Info); - return Info->NextEntryOffset + Info->FileNameLength; -} - -ULONG -FatDirentToBothDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer) -{ - PFILE_BOTH_DIR_INFORMATION Info; - Info = (PFILE_BOTH_DIR_INFORMATION) Buffer; - Info->FileIndex = 0; - Info->EaSize = 0; - /* Setup Attributes */ - Info->FileAttributes = Dirent->Attributes; - /* Setup times */ - FatQueryFileTimes(&Info->CreationTime, Dirent); - /* Setup sizes */ - Info->EndOfFile.QuadPart = Dirent->FileSize; - Info->AllocationSize.QuadPart = - (Context->BytesPerClusterMask + Dirent->FileSize) - & ~(Context->BytesPerClusterMask); - FatQueryBothFileName(Info, Dirent); - Info->NextEntryOffset = sizeof(*Info); - return Info->NextEntryOffset + Info->FileNameLength; -} - -ULONG -FatDirentToIdBothDirInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer) -{ - PFILE_ID_BOTH_DIR_INFORMATION Info; - Info = (PFILE_ID_BOTH_DIR_INFORMATION) Buffer; - Info->FileId.QuadPart = 0; - Info->FileIndex = 0; - Info->EaSize = 0; - /* Setup Attributes */ - Info->FileAttributes = Dirent->Attributes; - /* Setup times */ - FatQueryFileTimes(&Info->CreationTime, Dirent); - /* Setup sizes */ - Info->EndOfFile.QuadPart = Dirent->FileSize; - Info->AllocationSize.QuadPart = - (Context->BytesPerClusterMask + Dirent->FileSize) - & ~(Context->BytesPerClusterMask); - FatQueryBothFileName(Info, Dirent); - Info->NextEntryOffset = sizeof(*Info); - return Info->NextEntryOffset + Info->FileNameLength; -} - -ULONG -FatDirentToNamesInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer) -{ - PFILE_NAMES_INFORMATION Info; - Info = (PFILE_NAMES_INFORMATION) Buffer; - Info->FileIndex = 0; - FatQueryFileName(Info, Dirent); - Info->NextEntryOffset = sizeof(*Info); - return Info->NextEntryOffset + Info->FileNameLength; -} - -ULONG -FatDirentToObjectIdInfo(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN PDIR_ENTRY Dirent, - IN PVOID Buffer) -{ - PFILE_OBJECTID_INFORMATION Info; - Info = (PFILE_OBJECTID_INFORMATION) Buffer; - Info->FileReference = 0; - ((PLONGLONG)Info->ObjectId)[0] = 0LL; - ((PLONGLONG)Info->ObjectId)[1] = 0LL; - return sizeof(*Info); -} - -/* EOF */ Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] Tue Oct 20 12:02:27 2009 @@ -65,21 +65,6 @@ ULONG ByteSize, PBCB *Bcb, PVOID *Buffer); - -/* ------------------------------------------------------ blockdev.c */ -NTSTATUS -NTAPI -FatPerformLboIo( - IN PFAT_IRP_CONTEXT IrpContext, - IN PLARGE_INTEGER Offset, - IN SIZE_T Length); - -NTSTATUS -FatPerformVirtualNonCachedIo( - IN PFAT_IRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PLARGE_INTEGER Offset, - IN SIZE_T Length); /* ----------------------------------------------------------- dir.c */ @@ -215,6 +200,10 @@ FF_T_SINT32 FatReadBlocks(FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void *pParam); +VOID NTAPI +FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes, + IN PDIR_ENTRY Dirent); + /* --------------------------------------------------------- lock.c */ NTSTATUS NTAPI @@ -249,33 +238,16 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); /* ----------------------------------------------------------- fat.c */ -PVOID -FatPinPage( - PFAT_PAGE_CONTEXT Context, - LONGLONG ByteOffset); - -PVOID -FatPinNextPage( - PFAT_PAGE_CONTEXT Context); - -NTSTATUS +NTSTATUS NTAPI FatInitializeVcb( IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb, IN PDEVICE_OBJECT TargetDeviceObject, IN PVPB Vpb); -VOID +VOID NTAPI FatUninitializeVcb( IN PVCB Vcb); - -ULONG -FatScanFat( - IN PFCB Fcb, - IN LONGLONG Vbo, OUT PLONGLONG Lbo, - IN OUT PLONGLONG Length, - OUT PULONG Index, - IN BOOLEAN CanWait); /* ------------------------------------------------------ device.c */ @@ -291,36 +263,7 @@ ULONG OutputBufferSize, BOOLEAN Override); -/* ------------------------------------------------------ direntry.c */ -VOID -FatFindDirent(IN OUT PFAT_FIND_DIRENT_CONTEXT Context, - OUT PDIR_ENTRY* Dirent, - OUT PUNICODE_STRING LongFileName OPTIONAL); - -VOID -FatEnumerateDirents(IN OUT PFAT_ENUM_DIRENT_CONTEXT Context, - IN SIZE_T Offset); - -VOID -FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes, - IN PDIR_ENTRY Dirent); - /* ----------------------------------------------------------- fcb.c */ -PFCB -FatLookupFcbByName( - IN PFCB ParentFcb, - IN PUNICODE_STRING Name); - -BOOLEAN -FatLinkFcbNames( - IN PFCB ParentFcb, - IN PFCB Fcb); - -VOID -FatUnlinkFcbNames( - IN PFCB ParentFcb, - IN PFCB Fcb); - PFCB NTAPI FatCreateFcb( IN PFAT_IRP_CONTEXT IrpContext, Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.rbuild [iso-8859-1] Tue Oct 20 12:02:27 2009 @@ -8,13 +8,11 @@ <library>ntoskrnl</library> <library>hal</library> <library>pseh</library> - <file>blockdev.c</file> <file>cleanup.c</file> <file>close.c</file> <file>create.c</file> <file>device.c</file> <file>dir.c</file> - <file>direntry.c</file> <file>ea.c</file> <file>fastfat.c</file> <file>fat.c</file> Modified: trunk/reactos/drivers/filesystems/fastfat_new/fat.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] Tue Oct 20 12:02:27 2009 @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: drivers/filesystems/fastfat/fat.c * PURPOSE: FAT support routines - * PROGRAMMERS: Alexey Vlasov + * PROGRAMMERS: Aleksey Bragin <aleksey(a)reactos.org> */ /* INCLUDES *****************************************************************/ @@ -12,370 +12,12 @@ #include "fastfat.h" /* PROTOTYPES ***************************************************************/ -typedef struct _FAT_SCAN_CONTEXT -{ - PFILE_OBJECT FileObject; - LARGE_INTEGER PageOffset; - LONGLONG BeyondLastEntryOffset; - PVOID PageBuffer; - PBCB PageBcb; -} FAT_SCAN_CONTEXT; - -#define FatEntryToDataOffset(xEntry, xVcb) \ - ((xVcb)->DataArea + (((LONGLONG) ((xEntry) - 0x02)) << (xVcb)->BytesPerClusterLog)) - -#define FatDataOffsetToEntry(xOffset, xVcb) \ - ((ULONG) ((xOffset - (xVcb)->DataArea) >> (xVcb)->BytesPerClusterLog) + 0x02) - -ULONG -FatScanFat32ForContinousRun(IN OUT PFAT_PAGE_CONTEXT Context, - IN OUT PULONG Index, - IN BOOLEAN CanWait); BOOLEAN NTAPI FatValidBpb(IN PBIOS_PARAMETER_BLOCK Bpb); /* VARIABLES ****************************************************************/ -FAT_METHODS Fat12Methods = { - NULL, - NULL, - NULL, - NULL -}; - -FAT_METHODS Fat16Methods = { - NULL, - NULL, - NULL, - NULL -}; - -FAT_METHODS Fat32Methods = { - FatScanFat32ForContinousRun, - NULL, - NULL, - NULL -}; - -/* FUNCTIONS ****************************************************************/ - -/** - * Pins the page containing ByteOffset byte. - * - * @param Context - * Keeps current BCB, Buffer pointer - * and maintains current and next page offset. - * - * @param ByteOffset - * Offset from the beginning of the data stream to be pinned. - * - * @return - * Pointer to the buffer starting with the specified ByteOffset. - */ -PVOID -FatPinPage( - PFAT_PAGE_CONTEXT Context, - LONGLONG ByteOffset) -{ - SIZE_T OffsetWithinPage; - - OffsetWithinPage = (SIZE_T) (ByteOffset & (PAGE_SIZE - 1)); - ByteOffset -= OffsetWithinPage; - if (ByteOffset != Context->Offset.QuadPart) - { - Context->Offset.QuadPart = ByteOffset; - if (Context->Bcb != NULL) - { - CcUnpinData(Context->Bcb); - Context->Bcb = NULL; - } - if (!CcMapData(Context->FileObject, - &Context->Offset, - PAGE_SIZE, - Context->CanWait, - &Context->Bcb, - &Context->Buffer)) - { - Context->Offset.QuadPart = 0LL; - ExRaiseStatus(STATUS_CANT_WAIT); - } - } - Context->EndOfPage.QuadPart = - Context->Offset.QuadPart + PAGE_SIZE; - if (Context->EndOfPage.QuadPart - > Context->EndOfData.QuadPart) - { - Context->ValidLength = (SIZE_T) - (Context->EndOfData.QuadPart - - Context->Offset.QuadPart); - } - else - { - Context->ValidLength = PAGE_SIZE; - } - return Add2Ptr(Context->Buffer, OffsetWithinPage, PVOID); -} - -/** - * Pins the next page of data stream. - * - * @param Context - * Keeps current BCB, Buffer pointer - * and maintains current and next page offset. - * - * @return - * Pointer to the buffer starting with the beginning of the next page. - */ -PVOID -FatPinNextPage( - PFAT_PAGE_CONTEXT Context) -{ - ASSERT ((Context->Offset.QuadPart % PAGE_SIZE) - != (Context->EndOfPage.QuadPart % PAGE_SIZE) - && Context->Bcb != NULL); - - ASSERT (Context->ValidLength == PAGE_SIZE); - - Context->Offset = Context->EndOfPage; - CcUnpinData(Context->Bcb); - if (!CcMapData(Context->FileObject, - &Context->Offset, - PAGE_SIZE, - Context->CanWait, - &Context->Bcb, - &Context->Buffer)) - { - Context->Bcb = NULL; - Context->Offset.QuadPart = 0LL; - ExRaiseStatus(STATUS_CANT_WAIT); - } - Context->EndOfPage.QuadPart = - Context->Offset.QuadPart + PAGE_SIZE; - return Context->Buffer; -} - -/** - * Determines the index of the set bit. - * - * @param Number - * Number having a single bit set. - * - * @return - * Index of the set bit. - */ -FORCEINLINE -ULONG -FatPowerOfTwo( - ULONG Number) -{ - ULONG Temp; - Temp = Number - - ((Number >> 1) & 033333333333) - - ((Number >> 2) & 011111111111); - return (((Temp + (Temp >> 3)) & 030707070707) % 63); -} - -/** - * Scans FAT32 for continous chain of clusters - * - * @param Context - * Pointer to FAT_PAGE_CONTEXT. - * - * @param Index - * Supplies the Index of the first cluster - * and receves the last index after the last - * cluster in the chain. - * - * @param CanWait - * Indicates if the context allows blocking. - * - * @return - * Value of the last claster terminated the scan. - * - * @note - * Raises STATUS_CANT_WAIT race condition. - */ -ULONG -FatScanFat32ForContinousRun(IN OUT PFAT_PAGE_CONTEXT Context, - IN OUT PULONG Index, - IN BOOLEAN CanWait) -{ - PULONG Entry, EndOfPage; - - Entry = FatPinPage(Context, ((LONGLONG) *Index) << 0x2); - EndOfPage = FatPinEndOfPage(Context, PULONG); - while (TRUE) - { - do - { - if ((*Entry & FAT_CLUSTER_LAST) != ++(*Index)) - return (*Entry & FAT_CLUSTER_LAST); - } while (++Entry < EndOfPage); - /* Check if this is the last available entry */ - if (FatPinIsLastPage(Context)) - break; - Entry = (PULONG) FatPinNextPage(Context); - EndOfPage = FatPinEndOfPage(Context, PULONG); - } - return (*Index - 1); -} - -ULONG -FatSetFat32ContinousRun(IN OUT PFAT_SCAN_CONTEXT Context, - IN ULONG Index, - IN ULONG Length, - IN BOOLEAN CanWait) -{ - ExRaiseStatus(STATUS_NOT_IMPLEMENTED); -} - -ULONG -FatScanFat32ForValueRun(IN OUT PFAT_SCAN_CONTEXT Context, - IN OUT PULONG Index, - IN ULONG IndexValue, - IN BOOLEAN CanWait) -{ - ExRaiseStatus(STATUS_NOT_IMPLEMENTED); -} - -ULONG -FatSetFat32ValueRun(IN OUT PFAT_SCAN_CONTEXT Context, - IN ULONG Index, - IN ULONG Length, - IN ULONG IndexValue, - IN BOOLEAN CanWait) -{ - ExRaiseStatus(STATUS_NOT_IMPLEMENTED); -} - -/** - * Queries file MCB for the specified region [Vbo, Vbo + Length], - * returns the number of runs in the region as well as the first - * run of the range itself. - * If the specified region is not fully cached in MCB the routine - * scans FAT for the file and fills the MCB until the file offset - * (defined as Vbo + Length) is reached. - * - * @param Fcb - * Pointer to FCB structure for the file. - * - * @param Vbo - * Virtual Byte Offset in the file. - * - * @param Lbo - * Receives the Value of Logical Byte offset corresponding - * to supplied Vbo Value. - * - * @param Length - * Supplies file range length to be examined and receives - * the length of first run. - * - * @param OutIndex - * Receives the index (in MCB cache) of first run. - * - * @return - * Incremented index of the last run (+1). - * - * @note - * Should be called by I/O routines to split the I/O operation - * into sequential or parallel I/O operations. - */ -ULONG -FatScanFat(IN PFCB Fcb, - IN LONGLONG Vbo, - OUT PLONGLONG Lbo, - IN OUT PLONGLONG Length, - OUT PULONG Index, - IN BOOLEAN CanWait) -{ - LONGLONG CurrentLbo, CurrentVbo, BeyondLastVbo, CurrentLength; - ULONG Entry, NextEntry, NumberOfEntries, CurrentIndex; - FAT_PAGE_CONTEXT Context; - PVCB Vcb; - - /* Some often used values */ - Vcb = Fcb->Vcb; - CurrentIndex = 0; - BeyondLastVbo = Vbo + *Length; - CurrentLength = ((LONGLONG) Vcb->Clusters) << Vcb->BytesPerClusterLog; - if (BeyondLastVbo > CurrentLength) - BeyondLastVbo = CurrentLength; - /* Try to locate first run */ - if (FsRtlLookupLargeMcbEntry(&Fcb->Mcb, Vbo, Lbo, Length, NULL, NULL, Index)) - { - /* Check if we have a single mapped run */ - if (Vbo >= BeyondLastVbo) - goto FatScanFcbFatExit; - } else { - *Length = 0L; - } - /* Get the first scan startup values */ - if (FsRtlLookupLastLargeMcbEntryAndIndex( - &Fcb->Mcb, &CurrentVbo, &CurrentLbo, &CurrentIndex)) - { - Entry = FatDataOffsetToEntry(CurrentLbo, Vcb); - } - else - { - /* Map is empty, set up initial values */ - Entry = Fcb->FirstCluster; - if (Entry <= 0x2) - ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR); - if (Entry >= Vcb->Clusters) - { - if (Entry < FAT_CLUSTER_LAST) - ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR); - BeyondLastVbo = 0LL; - } - CurrentIndex = 0L; - CurrentVbo = 0LL; - } - /* Initialize Context */ - RtlZeroMemory(&Context, sizeof(Context)); - Context.FileObject = Vcb->StreamFileObject; - Context.EndOfData.QuadPart = Vcb->BeyondLastClusterInFat; - - while (CurrentVbo < BeyondLastVbo) - { - /* Locate Continous run starting with the current entry */ - NumberOfEntries = Entry; - NextEntry = Vcb->Methods.ScanContinousRun( - &Context, &NumberOfEntries, CanWait); - NumberOfEntries -= Entry; - /* Check value that terminated the for being valid for FAT */ - if (NextEntry <= 0x2) - ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR); - if (NextEntry >= Vcb->Clusters) - { - if (NextEntry < FAT_CLUSTER_LAST) - ExRaiseStatus(STATUS_FILE_CORRUPT_ERROR); - break; - } - /* Add new run */ - CurrentLength = ((LONGLONG) NumberOfEntries) - << Vcb->BytesPerClusterLog; - FsRtlAddLargeMcbEntry(&Fcb->Mcb, - CurrentVbo, - FatEntryToDataOffset(Entry, Vcb), - CurrentLength); - /* Setup next iteration */ - Entry = NextEntry; - CurrentVbo += CurrentLength; - CurrentIndex ++; - } - if (*Length == 0LL && CurrentIndex > 0) - { - if (!FsRtlLookupLargeMcbEntry(&Fcb->Mcb, - Vbo, Lbo, Length, NULL, NULL, Index)) - { - *Index = 0L; - *Lbo = 0LL; - } - } -FatScanFcbFatExit: - return CurrentIndex; -} BOOLEAN NTAPI @@ -400,7 +42,29 @@ && (Bpb->SectorsPerFat > 0 || !Bpb->MirrorDisabled)); } +/** + * Determines the index of the set bit. + * + * @param Number + * Number having a single bit set. + * + * @return + * Index of the set bit. + */ +FORCEINLINE +ULONG +FatPowerOfTwo( + ULONG Number) +{ + ULONG Temp; + Temp = Number + - ((Number >> 1) & 033333333333) + - ((Number >> 2) & 011111111111); + return (((Temp + (Temp >> 3)) & 030707070707) % 63); +} + VOID +NTAPI FatiInitializeVcb(PVCB Vcb) { ULONG ClustersCapacity; @@ -420,17 +84,17 @@ if (Vcb->BytesPerClusterLog < 4087) { Vcb->IndexDepth = 0x0c; - Vcb->Methods = Fat12Methods; + //Vcb->Methods = Fat12Methods; } else { Vcb->IndexDepth = 0x10; - Vcb->Methods = Fat16Methods; + //Vcb->Methods = Fat16Methods; } /* Large Sectors are used for FAT32 */ if (Vcb->Bpb.Sectors == 0) { Vcb->IndexDepth = 0x20; - Vcb->Methods = Fat32Methods; + //Vcb->Methods = Fat32Methods; } ClustersCapacity = (SectorsToBytes(Vcb, Vcb->Sectors) * 0x8 / Vcb->IndexDepth) - 1; if (Vcb->Clusters > ClustersCapacity) @@ -445,6 +109,7 @@ } NTSTATUS +NTAPI FatInitializeVcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb, IN PDEVICE_OBJECT TargetDeviceObject, @@ -558,6 +223,7 @@ } VOID +NTAPI FatUninitializeVcb(IN PVCB Vcb) { LARGE_INTEGER ZeroSize; Modified: trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] Tue Oct 20 12:02:27 2009 @@ -388,6 +388,14 @@ EaFile } TYPE_OF_OPEN; +typedef enum _FILE_TIME_INDEX +{ + FileCreationTime = 0, + FileLastAccessTime, + FileLastWriteTime, + FileChangeTime +} FILE_TIME_INDEX; + #define CCB_SEARCH_RETURN_SINGLE_ENTRY 0x01 #define CCB_SEARCH_PATTERN_LEGAL_8DOT3 0x02 #define CCB_SEARCH_PATTERN_HAS_WILD_CARD 0x04 Modified: trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fullfat.c [iso-8859-1] Tue Oct 20 12:02:27 2009 @@ -100,4 +100,114 @@ return FF_Open(pIoman, AnsiName.Buffer, Mode, pError); } +FORCEINLINE +VOID +FatDateTimeToSystemTime(OUT PLARGE_INTEGER SystemTime, + IN PFAT_DATETIME FatDateTime, + IN UCHAR TenMs OPTIONAL) +{ + TIME_FIELDS TimeFields; + + /* Setup time fields */ + TimeFields.Year = FatDateTime->Date.Year + 1980; + TimeFields.Month = FatDateTime->Date.Month; + TimeFields.Day = FatDateTime->Date.Day; + TimeFields.Hour = FatDateTime->Time.Hour; + TimeFields.Minute = FatDateTime->Time.Minute; + TimeFields.Second = (FatDateTime->Time.DoubleSeconds << 1); + + /* Adjust up to 10 milliseconds + * if the parameter was supplied + */ + if (ARGUMENT_PRESENT(TenMs)) + { + TimeFields.Second += TenMs / 100; + TimeFields.Milliseconds = (TenMs % 100) * 10; + } + else + { + TimeFields.Milliseconds = 0; + } + + /* Fix seconds value that might get beyoud the bound */ + if (TimeFields.Second > 59) TimeFields.Second = 0; + + /* Perform ceonversion to system time if possible */ + if (RtlTimeFieldsToTime(&TimeFields, SystemTime)) + { + /* Convert to system time */ + ExLocalTimeToSystemTime(SystemTime, SystemTime); + } + else + { + /* Set to default time if conversion failed */ + *SystemTime = FatGlobalData.DefaultFileTime; + } +} + +// TODO: Make it a helper around FullFAT library +VOID +NTAPI +FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes, + IN PDIR_ENTRY Dirent) +{ + /* Convert LastWriteTime */ + FatDateTimeToSystemTime(&FileTimes[FileLastWriteTime], + &Dirent->LastWriteDateTime, + 0); + /* All other time fileds are valid (according to MS) + * only if Win31 compatability mode is set. + */ + if (FatGlobalData.Win31FileSystem) + { + /* We can avoid calling conversion routine + * if time in dirent is 0 or equals to already + * known time (LastWriteTime). + */ + if (Dirent->CreationDateTime.Value == 0) + { + /* Set it to default time */ + FileTimes[FileCreationTime] = FatGlobalData.DefaultFileTime; + } + else if (Dirent->CreationDateTime.Value + == Dirent->LastWriteDateTime.Value) + { + /* Assign the already known time */ + FileTimes[FileCreationTime] = FileTimes[FileLastWriteTime]; + /* Adjust milliseconds from extra dirent field */ + FileTimes[FileCreationTime].QuadPart + += (ULONG) Dirent->CreationTimeTenMs * 100000; + } + else + { + /* Perform conversion */ + FatDateTimeToSystemTime(&FileTimes[FileCreationTime], + &Dirent->CreationDateTime, + Dirent->CreationTimeTenMs); + } + if (Dirent->LastAccessDate.Value == 0) + { + /* Set it to default time */ + FileTimes[FileLastAccessTime] = FatGlobalData.DefaultFileTime; + } + else if (Dirent->LastAccessDate.Value + == Dirent->LastWriteDateTime.Date.Value) + { + /* Assign the already known time */ + FileTimes[FileLastAccessTime] = FileTimes[FileLastWriteTime]; + } + else + { + /* Perform conversion */ + FAT_DATETIME LastAccessDateTime; + + LastAccessDateTime.Date.Value = Dirent->LastAccessDate.Value; + LastAccessDateTime.Time.Value = 0; + FatDateTimeToSystemTime(&FileTimes[FileLastAccessTime], + &LastAccessDateTime, + 0); + } + } +} + /* EOF */ Modified: trunk/reactos/drivers/filesystems/fastfat_new/rw.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/rw.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/rw.c [iso-8859-1] Tue Oct 20 12:02:27 2009 @@ -4,7 +4,6 @@ * FILE: drivers/filesystems/fastfat/rw.c * PURPOSE: Read/write support * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org) - * Alexey Vlasov */ /* INCLUDES *****************************************************************/
14 years, 11 months
1
0
0
0
[fireball] 43640: [ntoskrnl/mm/ARM3] - Rewrite MmPageEntireDriver in a better way, fix bugs.
by fireball@svn.reactos.org
Author: fireball Date: Tue Oct 20 11:53:29 2009 New Revision: 43640 URL:
http://svn.reactos.org/svn/reactos?rev=43640&view=rev
Log: [ntoskrnl/mm/ARM3] - Rewrite MmPageEntireDriver in a better way, fix bugs. Modified: trunk/reactos/ntoskrnl/mm/ARM3/drvmgmt.c Modified: trunk/reactos/ntoskrnl/mm/ARM3/drvmgmt.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/drvmgmt.c…
============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/drvmgmt.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/drvmgmt.c [iso-8859-1] Tue Oct 20 11:53:29 2009 @@ -116,32 +116,40 @@ NTAPI MmPageEntireDriver(IN PVOID AddressWithinSection) { + PAGED_CODE(); // // We should find the driver loader entry and return its base address // - //PMMPTE Pte; - PLDR_DATA_TABLE_ENTRY pLdrDataTabEntry = MiLookupDataTableEntry(AddressWithinSection); + //PMMPTE StartPte, EndPte; + PLDR_DATA_TABLE_ENTRY pLdrDataTabEntry = + MiLookupDataTableEntry(AddressWithinSection); if (pLdrDataTabEntry) { // - // Is Paging Disabled or Check if we had already mapped it in for this section - // - if ( (MmDisablePagingExecutive & 1) || pLdrDataTabEntry->SectionPointer ) - { + // Is Paging disabled or it's mapped as an image + // + if ((MmDisablePagingExecutive & 1) || pLdrDataTabEntry->SectionPointer) return pLdrDataTabEntry->DllBase; - } + // // Flush all queued DPCs. // KeFlushQueuedDpcs(); - // - // Get the PTE for this section - // - //Pte = MiGetPteAddress(pLdrDataTabEntry->DllBase); - // - //MiSetPagingOfDriver( (Pte & (4,194,304 - 4) ) - 0x40000000 , - // (Pte & (4,194,304 - 4) ) - 0x40000000 + 4 * - // pLdrDataTabEntry->SizeOfImage >> PAGE_SHIFT - 4 ); + + // + // Get PTE range for this section + // + //StartPte = MiGetPteAddress(pLdrDataTabEntry->DllBase); + //EndPte = MiGetPteAddress(pLdrDataTabEntry->DllBase + + // pLdrDataTabEntry->SizeOfImage); + + // + // Set paging for specified PTE range + // + //MiSetPagingOfDriver(StartPte, EndPte); + + // + // Return base address // return pLdrDataTabEntry->DllBase; }
14 years, 11 months
1
0
0
0
← Newer
1
...
22
23
24
25
26
27
28
...
65
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
Results per page:
10
25
50
100
200