ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
April 2010
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
22 participants
435 discussions
Start a n
N
ew thread
[jimtabor] 46705: [Gdi32] - Adding batch support for ExtSelectClipRgn and update to the batch object structure.
by jimtabor@svn.reactos.org
Author: jimtabor Date: Sun Apr 4 00:05:03 2010 New Revision: 46705 URL:
http://svn.reactos.org/svn/reactos?rev=46705&view=rev
Log: [Gdi32] - Adding batch support for ExtSelectClipRgn and update to the batch object structure. Modified: trunk/reactos/dll/win32/gdi32/objects/region.c trunk/reactos/include/reactos/win32k/ntgdityp.h Modified: trunk/reactos/dll/win32/gdi32/objects/region.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/re…
============================================================================== --- trunk/reactos/dll/win32/gdi32/objects/region.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdi32/objects/region.c [iso-8859-1] Sun Apr 4 00:05:03 2010 @@ -104,7 +104,6 @@ FASTCALL DeleteRegion( HRGN hRgn ) { -//#if 0 PRGN_ATTR Rgn_Attr; if ((GdiGetHandleUserData((HGDIOBJ) hRgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) && @@ -128,7 +127,6 @@ } } } -//#endif return NtGdiDeleteObjectApp((HGDIOBJ) hRgn); } @@ -581,8 +579,110 @@ WINAPI ExtSelectClipRgn( IN HDC hdc, IN HRGN hrgn, IN INT iMode) { - /* FIXME some part need be done on user mode size */ - return NtGdiExtSelectClipRgn(hdc,hrgn, iMode); + INT Ret; + HRGN NewRgn = NULL; + +#if 0 +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC) + return MFDRV_ExtSelectClipRgn( hdc, ); + else + { + PLDC pLDC = GdiGetLDC(hdc); + if ( pLDC ) + { + if (pLDC->iType != LDC_EMFLDC || EMFDRV_ExtSelectClipRgn( hdc, )) + return NtGdiExtSelectClipRgn(hdc, ); + } + else + SetLastError(ERROR_INVALID_HANDLE); + return ERROR; + } + } +#endif +#if 0 + if ( hrgn ) + { + if ( GetLayout(hdc) & LAYOUT_RTL ) + { + if ( MirrorRgnDC(hdc, hrgn, &NewRgn) ) + { + if ( NewRgn ) hrgn = NewRgn; + } + } + } +#endif + /* Batch handles RGN_COPY only! */ + if (iMode == RGN_COPY) + { +#if 0 + PDC_ATTR pDc_Attr; + PRGN_ATTR pRgn_Attr = NULL; + + /* hrgn can be NULL unless the RGN_COPY mode is specified. */ + if (hrgn) + GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr); + + if ( GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &pDc_Attr) && + pDc_Attr ) + { + PGDI_TABLE_ENTRY pEntry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hdc); + PTEB pTeb = NtCurrentTeb(); + + if ( pTeb->Win32ThreadInfo != NULL && + pTeb->GdiTebBatch.HDC == hdc && + !(pDc_Attr->ulDirty_ & DC_DIBSECTION) && + !(pEntry->Flags & GDI_ENTRY_VALIDATE_VIS) ) + { + if (!hrgn || + (hrgn && pRgn_Attr && pRgn_Attr->Flags <= SIMPLEREGION) ) + { + if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSEXTSELCLPRGN)) <= GDIBATCHBUFSIZE) + { + PGDIBSEXTSELCLPRGN pgO = (PGDIBSEXTSELCLPRGN)(&pTeb->GdiTebBatch.Buffer[0] + + pTeb->GdiTebBatch.Offset); + pgO->gbHdr.Cmd = GdiBCExtSelClipRgn; + pgO->gbHdr.Size = sizeof(GDIBSEXTSELCLPRGN); + pgO->fnMode = iMode; + + if ( hrgn && pRgn_Attr ) + { + Ret = pRgn_Attr->Flags; + + if ( pDc_Attr->VisRectRegion.Rect.left >= pRgn_Attr->Rect.right || + pDc_Attr->VisRectRegion.Rect.top >= pRgn_Attr->Rect.bottom || + pDc_Attr->VisRectRegion.Rect.right <= pRgn_Attr->Rect.left || + pDc_Attr->VisRectRegion.Rect.bottom <= pRgn_Attr->Rect.top ) + Ret = NULLREGION; + + pgO->left = pRgn_Attr->Rect.left; + pgO->top = pRgn_Attr->Rect.top; + pgO->right = pRgn_Attr->Rect.right; + pgO->bottom = pRgn_Attr->Rect.bottom; + } + else + { + Ret = pDc_Attr->VisRectRegion.Flags; + pgO->fnMode |= 0x80000000; // Set no hrgn mode. + } + pTeb->GdiTebBatch.Offset += sizeof(GDIBSEXTSELCLPRGN); + pTeb->GdiBatchCount++; + if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush(); + if ( NewRgn ) DeleteObject(NewRgn); + return Ret; + } + } + } + } +#endif + } + Ret = NtGdiExtSelectClipRgn(hdc, hrgn, iMode); + + if ( NewRgn ) DeleteObject(NewRgn); + + return Ret; } /* Modified: trunk/reactos/include/reactos/win32k/ntgdityp.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntg…
============================================================================== --- trunk/reactos/include/reactos/win32k/ntgdityp.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/win32k/ntgdityp.h [iso-8859-1] Sun Apr 4 00:05:03 2010 @@ -523,10 +523,7 @@ { GDIBATCHHDR gbHdr; int fnMode; - LONG right; - LONG bottom; - LONG left; - LONG top; + RECTL; } GDIBSEXTSELCLPRGN, *PGDIBSEXTSELCLPRGN; // // Use with GdiBCSelObj, GdiBCDelObj and GdiBCDelRgn.
14 years, 8 months
1
0
0
0
[sserapion] 46704: Fix x86 build. Forever.
by sserapion@svn.reactos.org
Author: sserapion Date: Sat Apr 3 23:37:46 2010 New Revision: 46704 URL:
http://svn.reactos.org/svn/reactos?rev=46704&view=rev
Log: Fix x86 build. Forever. Removed: branches/ros-amd64-bringup/reactos/drivers/battery/cmbatt/ Modified: branches/ros-amd64-bringup/reactos/boot/bootdata/packages/reactos.dff branches/ros-amd64-bringup/reactos/dll/3rdparty/3rdparty.rbuild branches/ros-amd64-bringup/reactos/drivers/battery/directory.rbuild branches/ros-amd64-bringup/reactos/drivers/bus/acpi/cmbatt/cmbatt.rbuild Modified: branches/ros-amd64-bringup/reactos/boot/bootdata/packages/reactos.dff URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
============================================================================== --- branches/ros-amd64-bringup/reactos/boot/bootdata/packages/reactos.dff [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/bootdata/packages/reactos.dff [iso-8859-1] Sat Apr 3 23:37:46 2010 @@ -487,10 +487,12 @@ drivers\base\null\null.sys 2 drivers\base\nmidebug\nmidebug.sys 2 -drivers\battery\cmbatt\cmbatt.sys 2 drivers\battery\battc\battc.sys 2 drivers\bus\isapnp\isapnp.sys 2 + +drivers\bus\acpi\cmbatt\cmbatt.sys 2 +drivers\bus\acpi\compbatt\compbatt.sys 2 drivers\directx\dxapi\dxapi.sys 2 drivers\directx\dxg\dxg.sys 2 @@ -505,6 +507,7 @@ drivers\input\sermouse\sermouse.sys 2 drivers\ksfilter\ks\ks.sys 2 +drivers\multimedia\bdasup\bdasup.sys 2 drivers\network\afd\afd.sys 2 drivers\network\ndis\ndis.sys 2 @@ -523,7 +526,7 @@ ;drivers\usb\miniport\usbuhci\usbuhci.sys 2 ;drivers\usb\usbhub\usbhub.sys 2 ;drivers\usb\usbport\usbport.sys 2 -drivers\usb\nt4compat\usbdriver\usbdriver.sys 2 +;drivers\usb\nt4compat\usbdriver\usbdriver.sys 2 drivers\video\displays\vga\vgaddi.dll 1 drivers\video\displays\framebuf\framebuf.dll 1 Modified: branches/ros-amd64-bringup/reactos/dll/3rdparty/3rdparty.rbuild URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/dll/3…
============================================================================== --- branches/ros-amd64-bringup/reactos/dll/3rdparty/3rdparty.rbuild [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/dll/3rdparty/3rdparty.rbuild [iso-8859-1] Sat Apr 3 23:37:46 2010 @@ -4,9 +4,9 @@ <directory name="mesa32"> <xi:include href="mesa32/mesa32.rbuild" /> </directory> - <!-- directory name="libjpeg"> + <directory name="libjpeg"> <xi:include href="libjpeg/libjpeg.rbuild" /> - </directory --> + </directory> <directory name="libxslt"> <xi:include href="libxslt/libxslt.rbuild" /> </directory> Modified: branches/ros-amd64-bringup/reactos/drivers/battery/directory.rbuild URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drive…
============================================================================== --- branches/ros-amd64-bringup/reactos/drivers/battery/directory.rbuild [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/drivers/battery/directory.rbuild [iso-8859-1] Sat Apr 3 23:37:46 2010 @@ -4,7 +4,4 @@ <directory name="battc"> <xi:include href="battc/battc.rbuild" /> </directory> -<directory name="cmbatt"> - <xi:include href="cmbatt/cmbatt.rbuild" /> -</directory> </group> Modified: branches/ros-amd64-bringup/reactos/drivers/bus/acpi/cmbatt/cmbatt.rbuild URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drive…
============================================================================== --- branches/ros-amd64-bringup/reactos/drivers/bus/acpi/cmbatt/cmbatt.rbuild [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/drivers/bus/acpi/cmbatt/cmbatt.rbuild [iso-8859-1] Sat Apr 3 23:37:46 2010 @@ -1,6 +1,6 @@ <?xml version="1.0"?> <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd"> -<module name="cmbattx" type="kernelmodedriver" installbase="system32/drivers" installname="cmbattx.sys"> +<module name="cmbatt" type="kernelmodedriver" installbase="system32/drivers" installname="cmbatt.sys"> <library>ntoskrnl</library> <library>hal</library> <library>battc</library>
14 years, 8 months
1
0
0
0
[ekohl] 46703: [NTOSKRNL] - Check access rights according to the DACL. Granted rights are removed from the remaining rights variable. - Return success only if there are no more remaining rights. Return failure otherwise. - Remove outdated code.
by ekohl@svn.reactos.org
Author: ekohl Date: Sat Apr 3 23:21:52 2010 New Revision: 46703 URL:
http://svn.reactos.org/svn/reactos?rev=46703&view=rev
Log: [NTOSKRNL] - Check access rights according to the DACL. Granted rights are removed from the remaining rights variable. - Return success only if there are no more remaining rights. Return failure otherwise. - Remove outdated code. Modified: trunk/reactos/ntoskrnl/se/semgr.c Modified: trunk/reactos/ntoskrnl/se/semgr.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/semgr.c?rev=46…
============================================================================== --- trunk/reactos/ntoskrnl/se/semgr.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/se/semgr.c [iso-8859-1] Sat Apr 3 23:21:52 2010 @@ -389,7 +389,6 @@ OUT PNTSTATUS AccessStatus) { LUID_AND_ATTRIBUTES Privilege; - ACCESS_MASK CurrentAccess, AccessMask; ACCESS_MASK RemainingAccess; ACCESS_MASK TempAccess; ACCESS_MASK TempGrantedAccess = 0; @@ -427,10 +426,8 @@ if (PreviouslyGrantedAccess) RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping); - - CurrentAccess = PreviouslyGrantedAccess; + /* Initialize remaining access rights */ RemainingAccess = DesiredAccess; - Token = SubjectSecurityContext->ClientToken ? SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken; @@ -488,12 +485,10 @@ { *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; } - + *AccessStatus = STATUS_SUCCESS; return TRUE; } - - CurrentAccess = PreviouslyGrantedAccess; /* RULE 2: Check token for 'take ownership' privilege */ if (DesiredAccess & WRITE_OWNER) @@ -510,7 +505,6 @@ /* Adjust access rights */ RemainingAccess &= ~WRITE_OWNER; PreviouslyGrantedAccess |= WRITE_OWNER; - CurrentAccess |= WRITE_OWNER; /* Succeed if there are no more rights to grant */ if (RemainingAccess == 0) @@ -547,7 +541,7 @@ return FALSE; } - /* Determine the MAXIMUM_ALLOWED access rights */ + /* Determine the MAXIMUM_ALLOWED access rights according to the DACL */ if (DesiredAccess & MAXIMUM_ALLOWED) { CurrentAce = (PACE)(Dacl + 1); @@ -583,7 +577,7 @@ DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType); } - /* Get to the next ACE */ + /* Get the next ACE */ CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize); } @@ -619,48 +613,61 @@ { if (SepSidInToken(Token, Sid)) { - *GrantedAccess = 0; - *AccessStatus = STATUS_ACCESS_DENIED; - return FALSE; + /* Map access rights from the ACE */ + TempAccess = CurrentAce->AccessMask; + RtlMapGenericMask(&TempAccess, GenericMapping); + + /* Leave if a remaining right must be denied */ + if (RemainingAccess & TempAccess) + break; } } - else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) { if (SepSidInToken(Token, Sid)) { - AccessMask = CurrentAce->AccessMask; - RtlMapGenericMask(&AccessMask, GenericMapping); - CurrentAccess |= AccessMask; + /* Map access rights from the ACE */ + TempAccess = CurrentAce->AccessMask; + RtlMapGenericMask(&TempAccess, GenericMapping); + + /* Remove granted rights */ + RemainingAccess &= ~TempAccess; } } else { DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType); } + + /* Get the next ACE */ CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize); } - DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n", - CurrentAccess, DesiredAccess); - - *GrantedAccess = CurrentAccess & DesiredAccess; - - if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == - (DesiredAccess & ~VALID_INHERIT_FLAGS)) - { - *AccessStatus = STATUS_SUCCESS; - return TRUE; - } - else - { - DPRINT1("HACK: Should deny access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p).\n", - *GrantedAccess, DesiredAccess, GenericMapping); - //*AccessStatus = STATUS_ACCESS_DENIED; - //return FALSE; - *AccessStatus = STATUS_SUCCESS; - return TRUE; - } + DPRINT("DesiredAccess %08lx\nPreviouslyGrantedAccess %08lx\nRemainingAccess %08lx\n", + DesiredAccess, PreviouslyGrantedAccess, RemainingAccess); + + /* Fail if some rights have not been granted */ + if (RemainingAccess != 0) + { + *GrantedAccess = 0; + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; + } + + /* Set granted access rights */ + *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; + + DPRINT("GrantedAccess %08lx\n", *GrantedAccess); + + /* Fail if no rights have been granted */ + if (*GrantedAccess == 0) + { + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; + } + + *AccessStatus = STATUS_SUCCESS; + return TRUE; } static PSID
14 years, 8 months
1
0
0
0
[fireball] 46702: [NTOSKRNL/CONFIG] - Flusher lock fixes: wrong kind of lock, total mess (and the wrong kind of lock). Properly fixed throughout cmapi.c, but still missing in many other places. - Add support for detecting loading of an already loaded hive. - Start adding calls to CmpReportNotify to support registry callbacks. - Do work needed to flush notifications for a deleted node (but CmpFlushNotify not yet implemented). - Add support for adding each newly loaded hive to the HiveList key in
by fireball@svn.reactos.org
Author: fireball Date: Sat Apr 3 22:22:32 2010 New Revision: 46702 URL:
http://svn.reactos.org/svn/reactos?rev=46702&view=rev
Log: [NTOSKRNL/CONFIG] - Flusher lock fixes: wrong kind of lock,total mess (and the wrong kind of lock). Properly fixed throughout cmapi.c, but still missing in many other places. - Add support for detecting loading of an already loaded hive. - Start adding calls to CmpReportNotify to support registry callbacks. - Do work needed to flush notifications for a deleted node (but CmpFlushNotify not yet implemented). - Add support for adding each newly loaded hive to the HiveList key in the registry (but CmpAddHiveToFileList not yet implemented). - Add some ViewLock acquire/releases where needed. - Load the key in a faster way (Ob vs Zw) - Add checks everywhere for HvMarkCellDirty success. In future (when log/backup file is enabled), it can return FALSE (e.g. when we are out of space). - Change logic in CmpDoFlushAll to only flush a hive if it won't shrink (in the future, flushing may lead to hive shrinkage for efficiency). - Add SEH2 protection to all CmApis that may deal with user-mode data. - Add HvTrackCellRef/HvReleaseCellRef for tracking cell references in scenarios where we might need many GetCell/ReleaseCell calls. For now stubbed to only work with up to 4 static references. - Properly unlock/free in some failure paths in some of the CM APIs. - Add some missing HvReleaseCell in paths where it was missing. - Try to fix hack in enumerate key. - Fix wrong usage of KeQuerySystemTime. It was called twice to save it in 2 different places. Instead, there should be only one call, and then duplicate the value across. - Fix logic in CmpSetValueExistingData/Key. Tested with winetests and .NET framework 1.1 installation which fully completes. Modified: trunk/reactos/lib/cmlib/cmlib.h trunk/reactos/lib/cmlib/hivecell.c trunk/reactos/lib/cmlib/hivewrt.c trunk/reactos/ntoskrnl/config/cmapi.c trunk/reactos/ntoskrnl/config/cmhvlist.c trunk/reactos/ntoskrnl/config/cminit.c trunk/reactos/ntoskrnl/config/cmkcbncb.c trunk/reactos/ntoskrnl/config/cmparse.c Modified: trunk/reactos/lib/cmlib/cmlib.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/cmlib.h?rev=4670…
============================================================================== --- trunk/reactos/lib/cmlib/cmlib.h [iso-8859-1] (original) +++ trunk/reactos/lib/cmlib/cmlib.h [iso-8859-1] Sat Apr 3 22:22:32 2010 @@ -198,6 +198,22 @@ #endif +typedef struct _HV_HIVE_CELL_PAIR +{ + PHHIVE Hive; + HCELL_INDEX Cell; +} HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR; + +#define STATIC_CELL_PAIR_COUNT 4 +typedef struct _HV_TRACK_CELL_REF +{ + USHORT Count; + USHORT Max; + PHV_HIVE_CELL_PAIR CellArray; + HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT]; + USHORT StaticCount; +} HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF; + extern ULONG CmlibTraceLevel; /* @@ -272,6 +288,12 @@ IN HCELL_INDEX Cell ); +BOOLEAN +CMAPI +HvHiveWillShrink( + IN PHHIVE RegistryHive +); + BOOLEAN CMAPI HvSyncHive( PHHIVE RegistryHive); @@ -288,6 +310,21 @@ VOID CMAPI CmPrepareHive( PHHIVE RegistryHive); + + +BOOLEAN +CMAPI +HvTrackCellRef( + PHV_TRACK_CELL_REF CellRef, + PHHIVE Hive, + HCELL_INDEX Cell +); + +VOID +CMAPI +HvReleaseFreeCellRefArray( + PHV_TRACK_CELL_REF CellRef +); /* * Private functions. Modified: trunk/reactos/lib/cmlib/hivecell.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/hivecell.c?rev=4…
============================================================================== --- trunk/reactos/lib/cmlib/hivecell.c [iso-8859-1] (original) +++ trunk/reactos/lib/cmlib/hivecell.c [iso-8859-1] Sat Apr 3 22:22:32 2010 @@ -113,7 +113,7 @@ __FUNCTION__, RegistryHive, CellIndex, HoldingLock); if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != Stable) - return FALSE; + return TRUE; CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; @@ -525,3 +525,56 @@ if (CellType == Stable) HvMarkCellDirty(RegistryHive, CellIndex, FALSE); } + +BOOLEAN +CMAPI +HvTrackCellRef(PHV_TRACK_CELL_REF CellRef, + PHHIVE Hive, + HCELL_INDEX Cell) +{ + /* Sanity checks */ + ASSERT(CellRef); + ASSERT(Hive ); + ASSERT(Cell != HCELL_NIL); + + /* Less than 4? */ + if (CellRef->StaticCount < STATIC_CELL_PAIR_COUNT) + { + /* Add reference */ + CellRef->StaticArray[CellRef->StaticCount].Hive = Hive; + CellRef->StaticArray[CellRef->StaticCount].Cell = Cell; + CellRef->StaticCount++; + return TRUE; + } + + /* FIXME: TODO */ + DPRINT1("ERROR: Too many references\n"); + while (TRUE); + return FALSE; +} + +VOID +CMAPI +HvReleaseFreeCellRefArray(PHV_TRACK_CELL_REF CellRef) +{ + ULONG i; + ASSERT(CellRef); + + /* Any references? */ + if (CellRef->StaticCount > 0) + { + /* Sanity check */ + ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT); + + /* Loop them */ + for (i = 0; i < CellRef->StaticCount;i++) + { + /* Release them */ + HvReleaseCell(CellRef->StaticArray[i].Hive, + CellRef->StaticArray[i].Cell); + } + + /* Free again */ + CellRef->StaticCount = 0; + } +} Modified: trunk/reactos/lib/cmlib/hivewrt.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/hivewrt.c?rev=46…
============================================================================== --- trunk/reactos/lib/cmlib/hivewrt.c [iso-8859-1] (original) +++ trunk/reactos/lib/cmlib/hivewrt.c [iso-8859-1] Sat Apr 3 22:22:32 2010 @@ -265,6 +265,14 @@ return TRUE; } +BOOLEAN +CMAPI +HvHiveWillShrink(IN PHHIVE RegistryHive) +{ + /* No shrinking yet */ + return FALSE; +} + BOOLEAN CMAPI HvWriteHive( PHHIVE RegistryHive) Modified: trunk/reactos/ntoskrnl/config/cmapi.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmapi.c?re…
============================================================================== --- trunk/reactos/ntoskrnl/config/cmapi.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cmapi.c [iso-8859-1] Sat Apr 3 22:22:32 2010 @@ -14,6 +14,67 @@ /* FUNCTIONS *****************************************************************/ +BOOLEAN +NTAPI +CmpIsHiveAlreadyLoaded(IN HANDLE KeyHandle, + IN POBJECT_ATTRIBUTES SourceFile, + OUT PCMHIVE *CmHive) +{ + NTSTATUS Status; + PCM_KEY_BODY KeyBody; + PCMHIVE Hive; + BOOLEAN Loaded = FALSE; + PAGED_CODE(); + + /* Sanity check */ + CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK(); + + /* Reference the handle */ + Status = ObReferenceObjectByHandle(KeyHandle, + 0, + CmpKeyObjectType, + KernelMode, + (PVOID)&KeyBody, + NULL); + if (!NT_SUCCESS(Status)) return Loaded; + + /* Don't touch deleted KCBs */ + if (KeyBody->KeyControlBlock->Delete) return Loaded; + + Hive = CONTAINING_RECORD(KeyBody->KeyControlBlock->KeyHive, CMHIVE, Hive); + + /* Must be the root key */ + if (!(KeyBody->KeyControlBlock->Flags & KEY_HIVE_ENTRY) || + !(Hive->FileUserName.Buffer)) + { + /* It isn't */ + ObDereferenceObject(KeyBody); + return Loaded; + } + + /* Now compare the name of the file */ + if (!RtlCompareUnicodeString(&Hive->FileUserName, + SourceFile->ObjectName, + TRUE)) + { + /* Same file found */ + Loaded = TRUE; + *CmHive = Hive; + + /* If the hive is frozen, not sure what to do */ + if (Hive->Frozen) + { + /* FIXME: TODO */ + DPRINT1("ERROR: Hive is frozen\n"); + while (TRUE); + } + } + + /* Dereference and return result */ + ObDereferenceObject(KeyBody); + return Loaded; + } + BOOLEAN NTAPI CmpDoFlushAll(IN BOOLEAN ForceFlush) @@ -39,16 +100,35 @@ if (!(Hive->Hive.HiveFlags & HIVE_NOLAZYFLUSH)) { /* Acquire the flusher lock */ - ExAcquirePushLockExclusive((PVOID)&Hive->FlusherLock); - - /* Do the sync */ - Status = HvSyncHive(&Hive->Hive); - - /* If something failed - set the flag and continue looping*/ - if (!NT_SUCCESS(Status)) Result = FALSE; + CmpLockHiveFlusherExclusive(Hive); + + /* Check for illegal state */ + if ((ForceFlush) && (Hive->UseCount)) + { + /* Registry needs to be locked down */ + CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK(); + DPRINT1("FIXME: Hive is damaged and needs fixup\n"); + while (TRUE); + } + + /* Only sync if we are forced to or if it won't cause a hive shrink */ + if ((ForceFlush) || (!HvHiveWillShrink(&Hive->Hive))) + { + /* Do the sync */ + Status = HvSyncHive(&Hive->Hive); + + /* If something failed - set the flag and continue looping */ + if (!NT_SUCCESS(Status)) Result = FALSE; + } + else + { + /* We won't flush if the hive might shrink */ + Result = FALSE; + CmpForceForceFlush = TRUE; + } /* Release the flusher lock */ - ExReleasePushLock((PVOID)&Hive->FlusherLock); + CmpUnlockHiveFlusher(Hive); } /* Try the next entry */ @@ -81,10 +161,14 @@ { /* Then make sure it's valid and dirty it */ ASSERT(Parent->ValueList.List != HCELL_NIL); - HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE); - } - - /* Allocate avalue cell */ + if (!HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE)) + { + /* Fail if we're out of space for log changes */ + return STATUS_NO_LOG_SPACE; + } + } + + /* Allocate a value cell */ ValueCell = HvAllocateCell(Hive, FIELD_OFFSET(CM_KEY_VALUE, Name) + CmpNameSize(Hive, ValueName), @@ -102,15 +186,32 @@ /* Set it up and copy the name */ CellData->u.KeyValue.Signature = CM_KEY_VALUE_SIGNATURE; - CellData->u.KeyValue.Flags = 0; - CellData->u.KeyValue.Type = Type; - CellData->u.KeyValue.NameLength = CmpCopyName(Hive, - CellData->u.KeyValue.Name, - ValueName); + _SEH2_TRY + { + /* This can crash since the name is coming from user-mode */ + CellData->u.KeyValue.NameLength = CmpCopyName(Hive, + CellData->u.KeyValue.Name, + ValueName); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail */ + DPRINT1("Invalid user data!\n"); + HvFreeCell(Hive, ValueCell); + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + /* Check for compressed name */ if (CellData->u.KeyValue.NameLength < ValueName->Length) { /* This is a compressed name */ CellData->u.KeyValue.Flags = VALUE_COMP_NAME; + } + else + { + /* No flags to set */ + CellData->u.KeyValue.Flags = 0; } /* Check if this is a normal key */ @@ -140,6 +241,9 @@ CellData->u.KeyValue.DataLength = DataSize + CM_KEY_VALUE_SPECIAL_SIZE; CellData->u.KeyValue.Data = SmallData; } + + /* Set the type now */ + CellData->u.KeyValue.Type = Type; /* Add this value cell to the child list */ Status = CmpAddValueToList(Hive, @@ -149,7 +253,12 @@ &Parent->ValueList); /* If we failed, free the entire cell, including the data */ - if (!NT_SUCCESS(Status)) CmpFreeValue(Hive, ValueCell); + if (!NT_SUCCESS(Status)) + { + /* Overwrite the status with a known one */ + CmpFreeValue(Hive, ValueCell); + Status = STATUS_INSUFFICIENT_RESOURCES; + } /* Return Status */ return Status; @@ -170,9 +279,12 @@ PCELL_DATA CellData; ULONG Length; BOOLEAN WasSmall, IsSmall; + + /* Registry writes must be blocked */ + CMP_ASSERT_FLUSH_LOCK(Hive); /* Mark the old child cell dirty */ - HvMarkCellDirty(Hive, OldChild, FALSE); + if (!HvMarkCellDirty(Hive, OldChild, FALSE)) return STATUS_NO_LOG_SPACE; /* See if this is a small or normal key */ WasSmall = CmpIsKeyValueSmall(&Length, Value->DataLength); @@ -185,7 +297,7 @@ ASSERT_VALUE_BIG(Hive, DataSize); /* Mark the old value dirty */ - CmpMarkValueDataDirty(Hive, Value); + if (!CmpMarkValueDataDirty(Hive, Value)) return STATUS_NO_LOG_SPACE; /* Check if we have a small key */ if (IsSmall) @@ -203,60 +315,273 @@ Value->Type = Type; return STATUS_SUCCESS; } + + /* We have a normal key. Was the old cell also normal and had data? */ + if (!(WasSmall) && (Length > 0)) + { + /* Get the current data cell and actual data inside it */ + DataCell = Value->Data; + ASSERT(DataCell != HCELL_NIL); + CellData = HvGetCell(Hive, DataCell); + if (!CellData) return STATUS_INSUFFICIENT_RESOURCES; + + /* Immediately release the cell */ + HvReleaseCell(Hive, DataCell); + + /* Make sure that the data cell actually has a size */ + ASSERT(HvGetCellSize(Hive, CellData) > 0); + + /* Check if the previous data cell could fit our new data */ + if (DataSize <= (ULONG)(HvGetCellSize(Hive, CellData))) + { + /* Re-use it then */ + NewCell = DataCell; + } + else + { + /* Otherwise, re-allocate the current data cell */ + NewCell = HvReallocateCell(Hive, DataCell, DataSize); + if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; + } + } else { - /* We have a normal key. Was the old cell also normal and had data? */ - if (!(WasSmall) && (Length > 0)) - { - /* Get the current data cell and actual data inside it */ - DataCell = Value->Data; - ASSERT(DataCell != HCELL_NIL); - CellData = HvGetCell(Hive, DataCell); - if (!CellData) return STATUS_INSUFFICIENT_RESOURCES; - - /* Immediately release the cell */ - HvReleaseCell(Hive, DataCell); - - /* Make sure that the data cell actually has a size */ - ASSERT(HvGetCellSize(Hive, CellData) > 0); - - /* Check if the previous data cell could fit our new data */ - if (DataSize <= (ULONG)(HvGetCellSize(Hive, CellData))) - { - /* Re-use it then */ - NewCell = DataCell; + /* This was a small key, or a key with no data, allocate a cell */ + NewCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL); + if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Now get the actual data for our data cell */ + CellData = HvGetCell(Hive, NewCell); + if (!CellData) ASSERT(FALSE); + + /* Release it immediately */ + HvReleaseCell(Hive, NewCell); + + /* Copy our data into the data cell's buffer, and set up the value */ + RtlCopyMemory(CellData, Data, DataSize); + Value->Data = NewCell; + Value->DataLength = DataSize; + Value->Type = Type; + + /* Return success */ + ASSERT(HvIsCellDirty(Hive, NewCell)); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CmpQueryKeyData(IN PHHIVE Hive, + IN PCM_KEY_NODE Node, + IN KEY_INFORMATION_CLASS KeyInformationClass, + IN OUT PVOID KeyInformation, + IN ULONG Length, + IN OUT PULONG ResultLength) +{ + NTSTATUS Status; + ULONG Size, SizeLeft, MinimumSize; + PKEY_INFORMATION Info = (PKEY_INFORMATION)KeyInformation; + USHORT NameLength; + + /* Check if the value is compressed */ + if (Node->Flags & KEY_COMP_NAME) + { + /* Get the compressed name size */ + NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength); + } + else + { + /* Get the real size */ + NameLength = Node->NameLength; + } + + /* Check what kind of information is being requested */ + switch (KeyInformationClass) + { + /* Basic information */ + case KeyBasicInformation: + + /* This is the size we need */ + Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + NameLength; + + /* And this is the minimum we can work with */ + MinimumSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name); + + /* Let the caller know and assume success */ + *ResultLength = Size; + Status = STATUS_SUCCESS; + + /* Check if the bufer we got is too small */ + if (Length < MinimumSize) + { + /* Let the caller know and fail */ + Status = STATUS_BUFFER_TOO_SMALL; + break; + } + + /* Copy the basic information */ + Info->KeyBasicInformation.LastWriteTime = Node->LastWriteTime; + Info->KeyBasicInformation.TitleIndex = 0; + Info->KeyBasicInformation.NameLength = NameLength; + + /* Only the name is left */ + SizeLeft = Length - MinimumSize; + Size = NameLength; + + /* Check if we don't have enough space for the name */ + if (SizeLeft < Size) + { + /* Truncate the name we'll return, and tell the caller */ + Size = SizeLeft; + Status = STATUS_BUFFER_OVERFLOW; + } + + /* Check if this is a compressed key */ + if (Node->Flags & KEY_COMP_NAME) + { + /* Copy the compressed name */ + CmpCopyCompressedName(Info->KeyBasicInformation.Name, + SizeLeft, + Node->Name, + Node->NameLength); } else { - /* Otherwise, re-allocate the current data cell */ - NewCell = HvReallocateCell(Hive, DataCell, DataSize); - if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; - } - } - else - { - /* This was a small key, or a key with no data, allocate a cell */ - NewCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL); - if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Now get the actual data for our data cell */ - CellData = HvGetCell(Hive, NewCell); - if (!CellData) ASSERT(FALSE); - - /* Release it immediately */ - HvReleaseCell(Hive, NewCell); - - /* Copy our data into the data cell's buffer, and set up the value */ - RtlCopyMemory(CellData, Data, DataSize); - Value->Data = NewCell; - Value->DataLength = DataSize; - Value->Type = Type; - - /* Return success */ - ASSERT(HvIsCellDirty(Hive, NewCell)); - return STATUS_SUCCESS; - } + /* Otherwise, copy the raw name */ + RtlCopyMemory(Info->KeyBasicInformation.Name, + Node->Name, + Size); + } + break; + + /* Node information */ + case KeyNodeInformation: + + /* Calculate the size we need */ + Size = FIELD_OFFSET(KEY_NODE_INFORMATION, Name) + + NameLength + + Node->ClassLength; + + /* And the minimum size we can support */ + MinimumSize = FIELD_OFFSET(KEY_NODE_INFORMATION, Name); + + /* Return the size to the caller and assume succes */ + *ResultLength = Size; + Status = STATUS_SUCCESS; + + /* Check if the caller's buffer is too small */ + if (Length < MinimumSize) + { + /* Let them know, and fail */ + Status = STATUS_BUFFER_TOO_SMALL; + break; + } + + /* Copy the basic information */ + Info->KeyNodeInformation.LastWriteTime = Node->LastWriteTime; + Info->KeyNodeInformation.TitleIndex = 0; + Info->KeyNodeInformation.ClassLength = Node->ClassLength; + Info->KeyNodeInformation.NameLength = NameLength; + + /* Now the name is left */ + SizeLeft = Length - MinimumSize; + Size = NameLength; + + /* Check if the name can fit entirely */ + if (SizeLeft < Size) + { + /* It can't, we'll have to truncate. Tell the caller */ + Size = SizeLeft; + Status = STATUS_BUFFER_OVERFLOW; + } + + /* Check if the key node name is compressed */ + if (Node->Flags & KEY_COMP_NAME) + { + /* Copy the compressed name */ + CmpCopyCompressedName(Info->KeyNodeInformation.Name, + SizeLeft, + Node->Name, + Node->NameLength); + } + else + { + /* It isn't, so copy the raw name */ + RtlCopyMemory(Info->KeyNodeInformation.Name, + Node->Name, + Size); + } + + /* Check if the node has a class */ + if (Node->ClassLength > 0) + { + /* It does. We don't support these yet */ + ASSERTMSG("Classes not supported\n", FALSE); + } + else + { + /* It doesn't, so set offset to -1, not 0! */ + Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF; + } + break; + + /* Full information requsted */ + case KeyFullInformation: + + /* This is the size we need */ + Size = FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + + Node->ClassLength; + + /* This is what we can work with */ + MinimumSize = FIELD_OFFSET(KEY_FULL_INFORMATION, Class); + + /* Return it to caller and assume success */ + *ResultLength = Size; + Status = STATUS_SUCCESS; + + /* Check if the caller's buffer is to small */ + if (Length < MinimumSize) + { + /* Let them know and fail */ + Status = STATUS_BUFFER_TOO_SMALL; + break; + } + + /* Now copy all the basic information */ + Info->KeyFullInformation.LastWriteTime = Node->LastWriteTime; + Info->KeyFullInformation.TitleIndex = 0; + Info->KeyFullInformation.ClassLength = Node->ClassLength; + Info->KeyFullInformation.SubKeys = Node->SubKeyCounts[Stable] + + Node->SubKeyCounts[Volatile]; + Info->KeyFullInformation.Values = Node->ValueList.Count; + Info->KeyFullInformation.MaxNameLen = Node->MaxNameLen; + Info->KeyFullInformation.MaxClassLen = Node->MaxClassLen; + Info->KeyFullInformation.MaxValueNameLen = Node->MaxValueNameLen; + Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen; + + /* Check if we have a class */ + if (Node->ClassLength > 0) + { + /* We do, but we currently don't support this */ + ASSERTMSG("Classes not supported\n", FALSE); + } + else + { + /* We don't have a class, so set offset to -1, not 0! */ + Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF; + } + break; + + /* Any other class that got sent here is invalid! */ + default: + + /* Set failure code */ + Status = STATUS_INVALID_PARAMETER; + break; + } + + /* Return status */ + return Status; } NTSTATUS @@ -267,7 +592,7 @@ IN PVOID Data, IN ULONG DataLength) { - PHHIVE Hive; + PHHIVE Hive = NULL; PCM_KEY_NODE Parent; PCM_KEY_VALUE Value = NULL; HCELL_INDEX CurrentChild, Cell; @@ -275,8 +600,10 @@ BOOLEAN Found, Result; ULONG Count, ChildIndex, SmallData, Storage; VALUE_SEARCH_RETURN_TYPE SearchResult; - - /* Acquire hive lock */ + BOOLEAN FirstTry = TRUE, FlusherLocked = FALSE; + HCELL_INDEX ParentCell = HCELL_NIL, ChildCell = HCELL_NIL; + + /* Acquire hive and KCB lock */ CmpLockRegistry(); CmpAcquireKcbLockShared(Kcb); @@ -302,84 +629,119 @@ Status = STATUS_ACCESS_DENIED; goto Quickie; } - - /* Search for the value */ - SearchResult = CmpCompareNewValueDataAgainstKCBCache(Kcb, - ValueName, - Type, - Data, - DataLength); - if (SearchResult == SearchNeedExclusiveLock) - { - /* Try again with the exclusive lock */ - CmpConvertKcbSharedToExclusive(Kcb); + + /* Check if this is the first attempt */ + if (FirstTry) + { + /* Search for the value in the cache */ + SearchResult = CmpCompareNewValueDataAgainstKCBCache(Kcb, + ValueName, + Type, + Data, + DataLength); + if (SearchResult == SearchNeedExclusiveLock) + { + /* Try again with the exclusive lock */ + CmpConvertKcbSharedToExclusive(Kcb); + goto DoAgain; + } + else if (SearchResult == SearchSuccess) + { + /* We don't actually need to do anything! */ + Status = STATUS_SUCCESS; + goto Quickie; + } + + /* We need the exclusive KCB lock now */ + if (!(CmpIsKcbLockedExclusive(Kcb)) && + !(CmpTryToConvertKcbSharedToExclusive(Kcb))) + { + /* Acquire exclusive lock */ + CmpConvertKcbSharedToExclusive(Kcb); + } + + /* Cache lookup failed, so don't try it next time */ + FirstTry = FALSE; + + /* Now grab the flush lock since the key will be modified */ + ASSERT(FlusherLocked == FALSE); + CmpLockHiveFlusherShared((PCMHIVE)Kcb->KeyHive); + FlusherLocked = TRUE; goto DoAgain; } - else if (SearchResult == SearchSuccess) - { - /* We don't actually need to do anything! */ - Status = STATUS_SUCCESS; - goto Quickie; - } - - /* We need the exclusive KCB lock now */ - if (!(CmpIsKcbLockedExclusive(Kcb)) && !(CmpTryToConvertKcbSharedToExclusive(Kcb))) - { - /* Acquire exclusive lock */ - CmpConvertKcbSharedToExclusive(Kcb); - } - - /* Get pointer to key cell */ - Hive = Kcb->KeyHive; - Cell = Kcb->KeyCell; - - /* Prepare to scan the key node */ - Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell); - Count = Parent->ValueList.Count; - Found = FALSE; - if (Count > 0) - { - /* Try to find the existing name */ - Result = CmpFindNameInList(Hive, - &Parent->ValueList, - ValueName, - &ChildIndex, - &CurrentChild); - if (!Result) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Check if we found something */ - if (CurrentChild != HCELL_NIL) - { - /* Get its value */ - Value = (PCM_KEY_VALUE)HvGetCell(Hive, CurrentChild); - if (!Value) + else + { + /* Get pointer to key cell */ + Hive = Kcb->KeyHive; + Cell = Kcb->KeyCell; + + /* Get the parent */ + Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell); + ASSERT(Parent); + ParentCell = Cell; + + /* Prepare to scan the key node */ + Count = Parent->ValueList.Count; + Found = FALSE; + if (Count > 0) + { + /* Try to find the existing name */ + Result = CmpFindNameInList(Hive, + &Parent->ValueList, + ValueName, + &ChildIndex, + &CurrentChild); + if (!Result) { /* Fail */ Status = STATUS_INSUFFICIENT_RESOURCES; goto Quickie; } - /* Remember that we found it */ - Found = TRUE; - } - } - else - { - /* No child list, we'll need to add it */ - ChildIndex = 0; - } + /* Check if we found something */ + if (CurrentChild != HCELL_NIL) + { + /* Release existing child */ + if (ChildCell != HCELL_NIL) + { + HvReleaseCell(Hive, ChildCell); + ChildCell = HCELL_NIL; + } + + /* Get its value */ + Value = (PCM_KEY_VALUE)HvGetCell(Hive, CurrentChild); + if (!Value) + { + /* Fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* Remember that we found it */ + ChildCell = CurrentChild; + Found = TRUE; + } + } + else + { + /* No child list, we'll need to add it */ + ChildIndex = 0; + } + } + + /* Should only get here on the second pass */ + ASSERT(FirstTry == FALSE); /* The KCB must be locked exclusive at this point */ - ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) || - (CmpTestRegistryLockExclusive() == TRUE)); + CMP_ASSERT_KCB_LOCK(Kcb); /* Mark the cell dirty */ - HvMarkCellDirty(Hive, Cell, FALSE); + if (!HvMarkCellDirty(Hive, Cell, FALSE)) + { + /* Not enough log space, fail */ + Status = STATUS_NO_LOG_SPACE; + goto Quickie; + } /* Get the storage type */ Storage = HvGetCellType(Cell); @@ -388,8 +750,19 @@ SmallData = 0; if ((DataLength <= CM_KEY_VALUE_SMALL) && (DataLength > 0)) { - /* Copy it */ - RtlCopyMemory(&SmallData, Data, DataLength); + /* Need SEH because user data may be invalid */ + _SEH2_TRY + { + /* Copy it */ + RtlCopyMemory(&SmallData, Data, DataLength); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return failure code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(goto Quickie); + } + _SEH2_END; } /* Check if we didn't find a matching key */ @@ -442,7 +815,7 @@ /* Save the write time */ KeQuerySystemTime(&Parent->LastWriteTime); - KeQuerySystemTime(&Kcb->KcbLastWriteTime); + Kcb->KcbLastWriteTime = Parent->LastWriteTime; /* Check if the cell is cached */ if ((Found) && (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))) @@ -463,10 +836,21 @@ Kcb->ValueCache.Count = Parent->ValueList.Count; Kcb->ValueCache.ValueList = Parent->ValueList.List; } - } - + + /* Notify registered callbacks */ + CmpReportNotify(Kcb, + Hive, + Kcb->KeyCell, + REG_NOTIFY_CHANGE_LAST_SET); + } + + /* Release the cells */ Quickie: + if ((ParentCell != HCELL_NIL) && (Hive)) HvReleaseCell(Hive, ParentCell); + if ((ChildCell != HCELL_NIL) && (Hive)) HvReleaseCell(Hive, ChildCell); + /* Release the locks */ + if (FlusherLocked) CmpUnlockHiveFlusher((PCMHIVE)Hive); CmpReleaseKcbLock(Kcb); CmpUnlockRegistry(); return Status; @@ -504,15 +888,13 @@ /* Get the hive and the cell index */ Hive = Kcb->KeyHive; Cell = Kcb->KeyCell; + + /* Lock flushes */ + CmpLockHiveFlusherShared((PCMHIVE)Hive); /* Get the parent key node */ Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell); - if (!Parent) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } + ASSERT(Parent); /* Get the value list and check if it has any entries */ ChildList = &Parent->ValueList; @@ -535,16 +917,26 @@ if (ChildCell == HCELL_NIL) goto Quickie; /* We found the value, mark all relevant cells dirty */ - HvMarkCellDirty(Hive, Cell, FALSE); - HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE); - HvMarkCellDirty(Hive, ChildCell, FALSE); + if (!((HvMarkCellDirty(Hive, Cell, FALSE)) && + (HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE)) && + (HvMarkCellDirty(Hive, ChildCell, FALSE)))) + { + /* Not enough log space, fail */ + Status = STATUS_NO_LOG_SPACE; + goto Quickie; + } /* Get the key value */ Value = (PCM_KEY_VALUE)HvGetCell(Hive,ChildCell); - if (!Value) ASSERT(FALSE); + ASSERT(Value); /* Mark it and all related data as dirty */ - CmpMarkValueDataDirty(Hive, Value); + if (!CmpMarkValueDataDirty(Hive, Value)) + { + /* Not enough log space, fail */ + Status = STATUS_NO_LOG_SPACE; + goto Quickie; + } /* Ssanity checks */ ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List)); @@ -552,7 +944,12 @@ /* Remove the value from the child list */ Status = CmpRemoveValueFromList(Hive, ChildIndex, ChildList); - if(!NT_SUCCESS(Status)) goto Quickie; + if (!NT_SUCCESS(Status)) + { + /* Set known error */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } /* Remove the value and its data itself */ if (!CmpFreeValue(Hive, ChildCell)) @@ -564,7 +961,7 @@ /* Set the last write time */ KeQuerySystemTime(&Parent->LastWriteTime); - KeQuerySystemTime(&Kcb->KcbLastWriteTime); + Kcb->KcbLastWriteTime = Parent->LastWriteTime; /* Sanity check */ ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen); @@ -591,6 +988,9 @@ /* Set the value cache */ Kcb->ValueCache.Count = ChildList->Count; Kcb->ValueCache.ValueList = ChildList->List; + + /* Notify registered callbacks */ + CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_LAST_SET); /* Change default Status to success */ Status = STATUS_SUCCESS; @@ -609,6 +1009,7 @@ } /* Release locks */ + CmpUnlockHiveFlusher((PCMHIVE)Hive); CmpReleaseKcbLock(Kcb); CmpUnlockRegistry(); return Status; @@ -683,22 +1084,38 @@ /* Sanity check */ ASSERT(ValueData != NULL); - /* Query the information requested */ - Result = CmpQueryKeyValueData(Kcb, - CachedValue, - ValueData, - ValueCached, - KeyValueInformationClass, - KeyValueInformation, - Length, - ResultLength, - &Status); - if (Result == SearchNeedExclusiveLock) - { - /* Try with exclusive KCB lock */ - CmpConvertKcbSharedToExclusive(Kcb); - goto DoAgain; - } + /* User data, protect against exceptions */ + _SEH2_TRY + { + /* Query the information requested */ + Result = CmpQueryKeyValueData(Kcb, + CachedValue, + ValueData, + ValueCached, + KeyValueInformationClass, + KeyValueInformation, + Length, + ResultLength, + &Status); + if (Result == SearchNeedExclusiveLock) + { + /* Release the value cell */ + if (CellToRelease != HCELL_NIL) + { + HvReleaseCell(Hive, CellToRelease); + CellToRelease = HCELL_NIL; + } + + /* Try with exclusive KCB lock */ + CmpConvertKcbSharedToExclusive(Kcb); + goto DoAgain; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; } else { @@ -754,16 +1171,17 @@ /* Get the hive and parent */ Hive = Kcb->KeyHive; Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); - if (!Parent) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Make sure the index is valid */ - //if (Index >= Kcb->ValueCache.Count) - if (Index >= Parent->ValueList.Count) + ASSERT(Parent); + + /* FIXME: Lack of cache? */ + if (Kcb->ValueCache.Count != Parent->ValueList.Count) + { + DPRINT1("HACK: Overriding value cache count\n"); + Kcb->ValueCache.Count = Parent->ValueList.Count; + } + + /* Make sure the index is valid */ + if (Index >= Kcb->ValueCache.Count) { /* Release the cell and fail */ HvReleaseCell(Hive, Kcb->KeyCell); @@ -787,7 +1205,7 @@ { /* Check if we need an exclusive lock */ ASSERT(CellToRelease == HCELL_NIL); - ASSERT(ValueData == NULL); + HvReleaseCell(Hive, Kcb->KeyCell); /* Try with exclusive KCB lock */ CmpConvertKcbSharedToExclusive(Kcb); @@ -814,6 +1232,15 @@ &CellToRelease2); if (Result == SearchNeedExclusiveLock) { + /* Cleanup state */ + ASSERT(CellToRelease2 == HCELL_NIL); + if (CellToRelease) + { + HvReleaseCell(Hive, CellToRelease); + CellToRelease = HCELL_NIL; + } + HvReleaseCell(Hive, Kcb->KeyCell); + /* Try with exclusive KCB lock */ CmpConvertKcbSharedToExclusive(Kcb); goto DoAgain; @@ -827,23 +1254,38 @@ Status = STATUS_INSUFFICIENT_RESOURCES; goto Quickie; } - - /* Query the information requested */ - Result = CmpQueryKeyValueData(Kcb, - CachedValue, - ValueData, - ValueIsCached, - KeyValueInformationClass, - KeyValueInformation, - Length, - ResultLength, - &Status); - if (Result == SearchNeedExclusiveLock) - { - /* Try with exclusive KCB lock */ - CmpConvertKcbSharedToExclusive(Kcb); - goto DoAgain; - } + + /* User data, need SEH */ + _SEH2_TRY + { + /* Query the information requested */ + Result = CmpQueryKeyValueData(Kcb, + CachedValue, + ValueData, + ValueIsCached, + KeyValueInformationClass, + KeyValueInformation, + Length, + ResultLength, + &Status); + if (Result == SearchNeedExclusiveLock) + { + /* Cleanup state */ + if (CellToRelease2) HvReleaseCell(Hive, CellToRelease2); + HvReleaseCell(Hive, Kcb->KeyCell); + if (CellToRelease) HvReleaseCell(Hive, CellToRelease); + + /* Try with exclusive KCB lock */ + CmpConvertKcbSharedToExclusive(Kcb); + goto DoAgain; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; Quickie: /* If we have a cell to release, do so */ @@ -858,221 +1300,6 @@ /* Release locks */ CmpReleaseKcbLock(Kcb); CmpUnlockRegistry(); - return Status; -} - -NTSTATUS -NTAPI -CmpQueryKeyData(IN PHHIVE Hive, - IN PCM_KEY_NODE Node, - IN KEY_INFORMATION_CLASS KeyInformationClass, - IN OUT PVOID KeyInformation, - IN ULONG Length, - IN OUT PULONG ResultLength) -{ - NTSTATUS Status; - ULONG Size, SizeLeft, MinimumSize; - PKEY_INFORMATION Info = (PKEY_INFORMATION)KeyInformation; - USHORT NameLength; - - /* Check if the value is compressed */ - if (Node->Flags & KEY_COMP_NAME) - { - /* Get the compressed name size */ - NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength); - } - else - { - /* Get the real size */ - NameLength = Node->NameLength; - } - - /* Check what kind of information is being requested */ - switch (KeyInformationClass) - { - /* Basic information */ - case KeyBasicInformation: - - /* This is the size we need */ - Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + NameLength; - - /* And this is the minimum we can work with */ - MinimumSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name); - - /* Let the caller know and assume success */ - *ResultLength = Size; - Status = STATUS_SUCCESS; - - /* Check if the bufer we got is too small */ - if (Length < MinimumSize) - { - /* Let the caller know and fail */ - Status = STATUS_BUFFER_TOO_SMALL; - break; - } - - /* Copy the basic information */ - Info->KeyBasicInformation.LastWriteTime = Node->LastWriteTime; - Info->KeyBasicInformation.TitleIndex = 0; - Info->KeyBasicInformation.NameLength = NameLength; - - /* Only the name is left */ - SizeLeft = Length - MinimumSize; - Size = NameLength; - - /* Check if we don't have enough space for the name */ - if (SizeLeft < Size) - { - /* Truncate the name we'll return, and tell the caller */ - Size = SizeLeft; - Status = STATUS_BUFFER_OVERFLOW; - } - - /* Check if this is a compressed key */ - if (Node->Flags & KEY_COMP_NAME) - { - /* Copy the compressed name */ - CmpCopyCompressedName(Info->KeyBasicInformation.Name, - SizeLeft, - Node->Name, - Node->NameLength); - } - else - { - /* Otherwise, copy the raw name */ - RtlCopyMemory(Info->KeyBasicInformation.Name, - Node->Name, - Size); - } - break; - - /* Node information */ - case KeyNodeInformation: - - /* Calculate the size we need */ - Size = FIELD_OFFSET(KEY_NODE_INFORMATION, Name) + - NameLength + - Node->ClassLength; - - /* And the minimum size we can support */ - MinimumSize = FIELD_OFFSET(KEY_NODE_INFORMATION, Name); - - /* Return the size to the caller and assume succes */ - *ResultLength = Size; - Status = STATUS_SUCCESS; - - /* Check if the caller's buffer is too small */ - if (Length < MinimumSize) - { - /* Let them know, and fail */ - Status = STATUS_BUFFER_TOO_SMALL; - break; - } - - /* Copy the basic information */ - Info->KeyNodeInformation.LastWriteTime = Node->LastWriteTime; - Info->KeyNodeInformation.TitleIndex = 0; - Info->KeyNodeInformation.ClassLength = Node->ClassLength; - Info->KeyNodeInformation.NameLength = NameLength; - - /* Now the name is left */ - SizeLeft = Length - MinimumSize; - Size = NameLength; - - /* Check if the name can fit entirely */ - if (SizeLeft < Size) - { - /* It can't, we'll have to truncate. Tell the caller */ - Size = SizeLeft; - Status = STATUS_BUFFER_OVERFLOW; - } - - /* Check if the key node name is compressed */ - if (Node->Flags & KEY_COMP_NAME) - { - /* Copy the compressed name */ - CmpCopyCompressedName(Info->KeyNodeInformation.Name, - SizeLeft, - Node->Name, - Node->NameLength); - } - else - { - /* It isn't, so copy the raw name */ - RtlCopyMemory(Info->KeyNodeInformation.Name, - Node->Name, - Size); - } - - /* Check if the node has a class */ - if (Node->ClassLength > 0) - { - /* It does. We don't support these yet */ - ASSERTMSG("Classes not supported\n", FALSE); - } - else - { - /* It doesn't, so set offset to -1, not 0! */ - Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF; - } - break; - - /* Full information requsted */ - case KeyFullInformation: - - /* This is the size we need */ - Size = FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + - Node->ClassLength; - - /* This is what we can work with */ - MinimumSize = FIELD_OFFSET(KEY_FULL_INFORMATION, Class); - - /* Return it to caller and assume success */ - *ResultLength = Size; - Status = STATUS_SUCCESS; - - /* Check if the caller's buffer is to small */ - if (Length < MinimumSize) - { - /* Let them know and fail */ - Status = STATUS_BUFFER_TOO_SMALL; - break; - } - - /* Now copy all the basic information */ - Info->KeyFullInformation.LastWriteTime = Node->LastWriteTime; - Info->KeyFullInformation.TitleIndex = 0; - Info->KeyFullInformation.ClassLength = Node->ClassLength; - Info->KeyFullInformation.SubKeys = Node->SubKeyCounts[Stable] + - Node->SubKeyCounts[Volatile]; - Info->KeyFullInformation.Values = Node->ValueList.Count; - Info->KeyFullInformation.MaxNameLen = Node->MaxNameLen; - Info->KeyFullInformation.MaxClassLen = Node->MaxClassLen; - Info->KeyFullInformation.MaxValueNameLen = Node->MaxValueNameLen; - Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen; - - /* Check if we have a class */ - if (Node->ClassLength > 0) - { - /* We do, but we currently don't support this */ - ASSERTMSG("Classes not supported\n", FALSE); - } - else - { - /* We don't have a class, so set offset to -1, not 0! */ - Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF; - } - break; - - /* Any other class that got sent here is invalid! */ - default: - - /* Set failure code */ - Status = STATUS_INVALID_PARAMETER; - break; - } - - /* Return status */ return Status; } @@ -1087,6 +1314,7 @@ NTSTATUS Status; PHHIVE Hive; PCM_KEY_NODE Parent; + HV_TRACK_CELL_REF CellReferences = {0}; /* Acquire hive lock */ CmpLockRegistry(); @@ -1094,16 +1322,6 @@ /* Lock KCB shared */ CmpAcquireKcbLockShared(Kcb); - /* Get the hive and parent */ - Hive = Kcb->KeyHive; - Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); - if (!Parent) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - /* Don't touch deleted keys */ if (Kcb->Delete) { @@ -1120,13 +1338,27 @@ case KeyBasicInformation: case KeyNodeInformation: - /* Call the internal API */ - Status = CmpQueryKeyData(Hive, - Parent, - KeyInformationClass, - KeyInformation, - Length, - ResultLength); + /* Get the hive and parent */ + Hive = Kcb->KeyHive; + Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); + ASSERT(Parent); + + /* Track cell references */ + if (!HvTrackCellRef(&CellReferences, Hive, Kcb->KeyCell)) + { + /* Not enough memory to track references */ + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + /* Call the internal API */ + Status = CmpQueryKeyData(Hive, + Parent, + KeyInformationClass, + KeyInformation, + Length, + ResultLength); + } break; /* Unsupported classes for now */ @@ -1149,6 +1381,9 @@ } Quickie: + /* Release references */ + HvReleaseFreeCellRefArray(&CellReferences); + /* Release locks */ CmpReleaseKcbLock(Kcb); CmpUnlockRegistry(); @@ -1168,6 +1403,7 @@ PHHIVE Hive; PCM_KEY_NODE Parent, Child; HCELL_INDEX ChildCell; + HV_TRACK_CELL_REF CellReferences = {0}; /* Acquire hive lock */ CmpLockRegistry(); @@ -1179,20 +1415,14 @@ if (Kcb->Delete) { /* Undo everything */ - CmpReleaseKcbLock(Kcb); - CmpUnlockRegistry(); - return STATUS_KEY_DELETED; + Status = STATUS_KEY_DELETED; + goto Quickie; } /* Get the hive and parent */ Hive = Kcb->KeyHive; Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); - if (!Parent) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } + ASSERT(Parent); /* Get the child cell */ ChildCell = CmpFindSubKeyByNumber(Hive, Parent, Index); @@ -1210,22 +1440,39 @@ /* Now get the actual child node */ Child = (PCM_KEY_NODE)HvGetCell(Hive, ChildCell); - if (!Child) - { - /* Fail */ + ASSERT(Child); + + /* Track references */ + if (!HvTrackCellRef(&CellReferences, Hive, ChildCell)) + { + /* Can't allocate memory for tracking */ Status = STATUS_INSUFFICIENT_RESOURCES; goto Quickie; } - /* Query the data requested */ - Status = CmpQueryKeyData(Hive, - Child, - KeyInformationClass, - KeyInformation, - Length, - ResultLength); + /* Data can be user-mode, use SEH */ + _SEH2_TRY + { + /* Query the data requested */ + Status = CmpQueryKeyData(Hive, + Child, + KeyInformationClass, + KeyInformation, + Length, + ResultLength); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(goto Quickie); + } + _SEH2_END; Quickie: + /* Release references */ + HvReleaseFreeCellRefArray(&CellReferences); + /* Release locks */ CmpReleaseKcbLock(Kcb); CmpUnlockRegistry(); @@ -1271,14 +1518,12 @@ Hive = Kcb->KeyHive; Cell = Kcb->KeyCell; + /* Lock flushes */ + CmpLockHiveFlusherShared((PCMHIVE)Hive); + /* Get the key node */ Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell); - if (!Node) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } + ASSERT(Node); /* Sanity check */ ASSERT(Node->Flags == Kcb->Flags); @@ -1287,11 +1532,17 @@ if (!(Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile]) && !(Node->Flags & KEY_NO_DELETE)) { + /* Send notification to registered callbacks */ + CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_NAME); + /* Get the parent and free the cell */ ParentCell = Node->Parent; Status = CmpFreeKeyByCell(Hive, Cell, TRUE); if (NT_SUCCESS(Status)) { + /* Flush any notifications */ + CmpFlushNotifiesOnKeyBodyList(Kcb, FALSE); + /* Clean up information we have on the subkey */ CmpCleanUpSubKeyInfo(Kcb->ParentKcb); @@ -1327,10 +1578,12 @@ Status = STATUS_CANNOT_DELETE; } -Quickie: /* Release the cell */ HvReleaseCell(Hive, Cell); - + + /* Release flush lock */ + CmpUnlockHiveFlusher((PCMHIVE)Hive); + /* Release the KCB locks */ Quickie2: CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey); @@ -1364,12 +1617,36 @@ } else { + /* Don't touch the hive */ + CmpLockHiveFlusherExclusive(CmHive); + ASSERT(CmHive->ViewLock); + KeAcquireGuardedMutex(CmHive->ViewLock); + CmHive->ViewLockOwner = KeGetCurrentThread(); + + /* Will the hive shrink? */ + if (HvHiveWillShrink(Hive)) + { + /* I don't believe the current Hv does shrinking */ + ASSERT(FALSE); + } + else + { + /* Now we can release views */ + ASSERT(CmHive->ViewLock); + CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK_OR_LOADING(CmHive); + ASSERT(KeGetCurrentThread() == CmHive->ViewLockOwner); + KeReleaseGuardedMutex(CmHive->ViewLock); + } + /* Flush only this hive */ if (!HvSyncHive(Hive)) { /* Fail */ Status = STATUS_REGISTRY_IO_FAILED; } + + /* Release the flush lock */ + CmpUnlockHiveFlusher((PCMHIVE)Hive); } /* Return the status */ @@ -1387,8 +1664,9 @@ SECURITY_CLIENT_CONTEXT ClientSecurityContext; HANDLE KeyHandle; BOOLEAN Allocate = TRUE; - PCMHIVE CmHive; + PCMHIVE CmHive, LoadedHive; NTSTATUS Status; + CM_PARSE_CONTEXT ParseContext; /* Check if we have a trust key */ if (KeyBody) @@ -1415,9 +1693,21 @@ } /* Open the target key */ +#if 0 Status = ZwOpenKey(&KeyHandle, KEY_READ, TargetKey); +#else + RtlZeroMemory(&ParseContext, sizeof(ParseContext)); + ParseContext.CreateOperation = FALSE; + Status = ObOpenObjectByName(TargetKey, + CmpKeyObjectType, + KernelMode, + NULL, + KEY_READ, + &ParseContext, + &KeyHandle); +#endif if (!NT_SUCCESS(Status)) KeyHandle = NULL; - + /* Open the hive */ Status = CmpCmdHiveOpen(SourceFile, &ClientSecurityContext, @@ -1437,20 +1727,28 @@ /* Lock the registry */ CmpLockRegistryExclusive(); - /* FIXME: Check if we are already loaded */ - + /* Check if we are already loaded */ + if (CmpIsHiveAlreadyLoaded(KeyHandle, SourceFile, &LoadedHive)) + { + /* That's okay then */ + ASSERT(LoadedHive); + Status = STATUS_SUCCESS; + } + /* Release the registry */ CmpUnlockRegistry(); } /* Close the key handle if we had one */ if (KeyHandle) ZwClose(KeyHandle); - DPRINT1("Failed: %lx\n", Status); return Status; } /* Lock the registry shared */ CmpLockRegistry(); + + /* Lock loading */ + ExAcquirePushLockExclusive(&CmpLoadHiveLock); /* Lock the hive to this thread */ CmHive->Hive.HiveFlags |= HIVE_IS_UNLOADING; @@ -1467,23 +1765,37 @@ TargetKey->SecurityDescriptor); if (NT_SUCCESS(Status)) { - /* FIXME: Add to HiveList key */ + /* Add to HiveList key */ + CmpAddToHiveFileList(CmHive); /* Sync the hive if necessary */ if (Allocate) { - /* Sync it */ + /* Sync it under the flusher lock */ + CmpLockHiveFlusherExclusive(CmHive); HvSyncHive(&CmHive->Hive); + CmpUnlockHiveFlusher(CmHive); } /* Release the hive */ CmHive->Hive.HiveFlags &= ~HIVE_IS_UNLOADING; CmHive->CreatorOwner = NULL; + + /* Allow loads */ + ExReleasePushLock(&CmpLoadHiveLock); } else { /* FIXME: TODO */ - + ASSERT(FALSE); + } + + /* Is this first profile load? */ + if (!(CmpProfileLoaded) && !(CmpWasSetupBoot)) + { + /* User is now logged on, set quotas */ + CmpProfileLoaded = TRUE; + CmpSetGlobalQuotaAllowed(); } /* Unlock the registry */ Modified: trunk/reactos/ntoskrnl/config/cmhvlist.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmhvlist.c…
============================================================================== --- trunk/reactos/ntoskrnl/config/cmhvlist.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cmhvlist.c [iso-8859-1] Sat Apr 3 22:22:32 2010 @@ -14,4 +14,11 @@ /* FUNCTIONS *****************************************************************/ +NTSTATUS +NTAPI +CmpAddToHiveFileList(IN PCMHIVE Hive) +{ + return STATUS_SUCCESS; +} + /* EOF */ Modified: trunk/reactos/ntoskrnl/config/cminit.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cminit.c?r…
============================================================================== --- trunk/reactos/ntoskrnl/config/cminit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cminit.c [iso-8859-1] Sat Apr 3 22:22:32 2010 @@ -119,12 +119,10 @@ if (!Hive->ViewLock) return STATUS_INSUFFICIENT_RESOURCES; /* Allocate the flush lock */ -#if 0 Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERESOURCE), TAG_CM); if (!Hive->FlusherLock) return STATUS_INSUFFICIENT_RESOURCES; -#endif /* Setup the handles */ Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary; @@ -136,7 +134,7 @@ Hive->ViewLockOwner = NULL; /* Initialize the flush lock */ - ExInitializePushLock((PULONG_PTR)&Hive->FlusherLock); + ExInitializeResourceLite(Hive->FlusherLock); /* Setup hive locks */ ExInitializePushLock((PULONG_PTR)&Hive->HiveLock); @@ -193,9 +191,7 @@ { /* Clear allocations and fail */ ExFreePool(Hive->ViewLock); -#if 0 ExFreePool(Hive->FlusherLock); -#endif ExFreePool(Hive); return Status; } @@ -211,9 +207,7 @@ { /* Free all alocations */ ExFreePool(Hive->ViewLock); -#if 0 ExFreePool(Hive->FlusherLock); -#endif ExFreePool(Hive); return STATUS_REGISTRY_CORRUPT; } Modified: trunk/reactos/ntoskrnl/config/cmkcbncb.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmkcbncb.c…
============================================================================== --- trunk/reactos/ntoskrnl/config/cmkcbncb.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cmkcbncb.c [iso-8859-1] Sat Apr 3 22:22:32 2010 @@ -1135,3 +1135,62 @@ /* Unlock it it if we did a manual lock */ if (!LockHeld) CmpReleaseKcbLock(KeyBody->KeyControlBlock); } + +VOID +NTAPI +CmpFlushNotifiesOnKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb, + IN BOOLEAN LockHeld) +{ + PLIST_ENTRY NextEntry, ListHead; + PCM_KEY_BODY KeyBody; + + /* Sanity check */ + LockHeld ? CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK() : CmpIsKcbLockedExclusive(Kcb); + while (TRUE) + { + /* Is the list empty? */ + ListHead = &Kcb->KeyBodyListHead; + if (!IsListEmpty(ListHead)) + { + /* Loop the list */ + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the key body */ + KeyBody = CONTAINING_RECORD(NextEntry, CM_KEY_BODY, KeyBodyList); + ASSERT(KeyBody->Type == '20yk'); + + /* Check for notifications */ + if (KeyBody->NotifyBlock) + { + /* Is the lock held? */ + if (LockHeld) + { + /* Flush it */ + CmpFlushNotify(KeyBody, LockHeld); + ASSERT(KeyBody->NotifyBlock == NULL); + continue; + } + + /* Lock isn't held, so we need to take a reference */ + if (ObReferenceObjectSafe(KeyBody)) + { + /* Now we can flush */ + CmpFlushNotify(KeyBody, LockHeld); + ASSERT(KeyBody->NotifyBlock == NULL); + + /* Release the reference we took */ + ObDereferenceObjectDeferDelete(KeyBody); + continue; + } + } + + /* Try the next entry */ + NextEntry = NextEntry->Flink; + } + } + + /* List has been parsed, exit */ + break; + } +} Modified: trunk/reactos/ntoskrnl/config/cmparse.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmparse.c?…
============================================================================== --- trunk/reactos/ntoskrnl/config/cmparse.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cmparse.c [iso-8859-1] Sat Apr 3 22:22:32 2010 @@ -414,15 +414,6 @@ LARGE_INTEGER TimeStamp; PCM_KEY_NODE KeyNode; - /* Sanity check */ -#if 0 - ASSERT((CmpIsKcbLockedExclusive(ParentKcb) == TRUE) || - (CmpTestRegistryLockExclusive() == TRUE)); -#endif - - /* Acquire the flusher lock */ - ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock); - /* Check if the parent is being deleted */ if (ParentKcb->Delete) { @@ -555,7 +546,6 @@ Exit: /* Release the flusher lock and return status */ - ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock); return Status; } @@ -747,9 +737,6 @@ LARGE_INTEGER TimeStamp; PCM_KEY_NODE KeyNode; PCM_KEY_CONTROL_BLOCK Kcb = ParentKcb; -#if 0 - CMP_ASSERT_REGISTRY_LOCK(); -#endif /* Link nodes only allowed on the master */ if (Hive != &CmiVolatileHive->Hive) @@ -759,10 +746,6 @@ return STATUS_ACCESS_DENIED; } - /* Acquire the flusher locks */ - ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock); - ExAcquirePushLockShared((PVOID)&((PCMHIVE)Context->ChildHive.KeyHive)->FlusherLock); - /* Check if the parent is being deleted */ if (ParentKcb->Delete) { @@ -964,8 +947,6 @@ Exit: /* Release the flusher locks and return status */ - ExReleasePushLock((PVOID)&((PCMHIVE)Context->ChildHive.KeyHive)->FlusherLock); - ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock); return Status; }
14 years, 8 months
1
0
0
0
[tkreuzer] 46701: [WIN32K] - use a macro in RegReadDisplaySettings to make things smaller - Send WM_DISPLAYCHANGE to all toplevel windows when changing mode - leave UserChangeDisplaySettings when mode switching failed
by tkreuzer@svn.reactos.org
Author: tkreuzer Date: Sat Apr 3 19:30:00 2010 New Revision: 46701 URL:
http://svn.reactos.org/svn/reactos?rev=46701&view=rev
Log: [WIN32K] - use a macro in RegReadDisplaySettings to make things smaller - Send WM_DISPLAYCHANGE to all toplevel windows when changing mode - leave UserChangeDisplaySettings when mode switching failed Modified: branches/reactos-yarotows/subsystems/win32/win32k/ntuser/display.c Modified: branches/reactos-yarotows/subsystems/win32/win32k/ntuser/display.c URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/ntuser/display.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/ntuser/display.c [iso-8859-1] Sat Apr 3 19:30:00 2010 @@ -78,68 +78,30 @@ { DWORD dwValue; + /* Zero out the structure */ RtlZeroMemory(pdm, sizeof(DEVMODEW)); - if (RegReadDWORD(hkey, L"DefaultSettings.BitsPerPel", &dwValue)) - { - pdm->dmBitsPerPel = dwValue; - pdm->dmFields |= DM_BITSPERPEL; - } - if (RegReadDWORD(hkey, L"DefaultSettings.XResolution", &dwValue)) - { - pdm->dmPelsWidth = dwValue; -// pdm->dmFields |= DM_XRESOLUTION; - } - if (RegReadDWORD(hkey, L"DefaultSettings.YResolution", &dwValue)) - { - pdm->dmPelsHeight = dwValue; - pdm->dmFields |= DM_YRESOLUTION; - } - if (RegReadDWORD(hkey, L"DefaultSettings.Flags", &dwValue)) - { - pdm->dmDisplayFlags = dwValue; - pdm->dmFields |= DM_BITSPERPEL; - } - if (RegReadDWORD(hkey, L"DefaultSettings.VRefresh", &dwValue)) - { - pdm->dmDisplayFrequency = dwValue; - pdm->dmFields |= DM_DISPLAYFREQUENCY; - } - if (RegReadDWORD(hkey, L"DefaultSettings.XPanning", &dwValue)) - { - pdm->dmPanningWidth = dwValue; - pdm->dmFields |= DM_PANNINGWIDTH; - } - if (RegReadDWORD(hkey, L"DefaultSettings.YPanning", &dwValue)) - { - pdm->dmPanningHeight = dwValue; - pdm->dmFields |= DM_PANNINGHEIGHT; - } - if (RegReadDWORD(hkey, L"DefaultSettings.Orientation", &dwValue)) - { - pdm->dmDisplayOrientation = dwValue; - pdm->dmFields |= DM_DISPLAYORIENTATION; - } - if (RegReadDWORD(hkey, L"DefaultSettings.FixedOutput", &dwValue)) - { - pdm->dmDisplayFixedOutput = dwValue; - pdm->dmFields |= DM_BITSPERPEL; - } - if (RegReadDWORD(hkey, L"Attach.RelativeX", &dwValue)) - { - pdm->dmPosition.x = dwValue; - pdm->dmFields |= DM_POSITION; - } - if (RegReadDWORD(hkey, L"Attach.RelativeY", &dwValue)) - { - pdm->dmPosition.y = dwValue; - pdm->dmFields |= DM_POSITION; - } -// RegReadDWORD(hkey, L"Attach.ToDesktop, pdm->dmBitsPerPel", &pdm->); - -} - - +/* Helper macro */ +#define READ(field, str, flag) \ + if (RegReadDWORD(hkey, L##str, &dwValue)) \ + { \ + pdm->field = dwValue; \ + pdm->dmFields |= flag; \ + } + + /* Read all present settings */ + READ(dmBitsPerPel, "DefaultSettings.BitsPerPel", DM_BITSPERPEL); + READ(dmPelsWidth, "DefaultSettings.XResolution", DM_YRESOLUTION); // DM_XRESOLUTION? + READ(dmPelsHeight, "DefaultSettings.YResolution", DM_YRESOLUTION); + READ(dmDisplayFlags, "DefaultSettings.Flags", DM_DISPLAYFLAGS); + READ(dmDisplayFrequency, "DefaultSettings.VRefresh", DM_DISPLAYFREQUENCY); + READ(dmPanningWidth, "DefaultSettings.XPanning", DM_PANNINGWIDTH); + READ(dmPanningHeight, "DefaultSettings.YPanning", DM_PANNINGHEIGHT); + READ(dmDisplayOrientation, "DefaultSettings.Orientation", DM_DISPLAYORIENTATION); + READ(dmDisplayFixedOutput, "DefaultSettings.FixedOutput", DM_DISPLAYFIXEDOUTPUT); + READ(dmPosition.x, "Attach.RelativeX", DM_POSITION); + READ(dmPosition.y, "Attach.RelativeY", DM_POSITION); +} enum @@ -794,6 +756,8 @@ DPRINT1("failed to set mode\n"); lResult = (lResult == DISP_CHANGE_NOTUPDATED) ? DISP_CHANGE_FAILED : DISP_CHANGE_RESTART; + + goto leave; } /* Update the system metrics */ @@ -801,19 +765,27 @@ /* Remove all cursor clipping */ UserClipCursor(NULL); + + //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps); pdesk = IntGetActiveDesktop(); IntHideDesktop(pdesk); co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes); - //UserRedrawDesktop(); - - //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps); - - /* Send message */ - + + UserRedrawDesktop(); + + /* Send WM_DISPLAYCHANGE to all toplevel windows */ + co_IntSendMessageTimeout(HWND_BROADCAST, + WM_DISPLAYCHANGE, + (WPARAM)ppdev->gdiinfo.cBitsPixel, + (LPARAM)(ppdev->gdiinfo.ulHorzRes + (ppdev->gdiinfo.ulHorzRes << 16)), + SMTO_NORMAL, + 100, + &ulResult); } leave: + /* Release the PDEV */ PDEVOBJ_vRelease(ppdev); return lResult; @@ -831,7 +803,7 @@ WCHAR awcDevice[CCHDEVICENAME]; UNICODE_STRING ustrDevice; DEVMODEW dmLocal; - LONG Ret; + LONG lRet; /* Check arguments */ if ((dwflags != CDS_VIDEOPARAMETERS && lParam != NULL) || @@ -864,6 +836,7 @@ } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + /* Set and return error */ SetLastNtError(_SEH2_GetExceptionCode()); _SEH2_YIELD(return DISP_CHANGE_BADPARAM); } @@ -877,35 +850,48 @@ { _SEH2_TRY { + /* Probe the size field of the structure */ ProbeForRead(lpDevMode, sizeof(dmLocal.dmSize), 1); + + /* Calculate usable size */ dmLocal.dmSize = min(sizeof(dmLocal), lpDevMode->dmSize); + + /* Probe and copy the full DEVMODE */ ProbeForRead(lpDevMode, dmLocal.dmSize, 1); RtlCopyMemory(&dmLocal, lpDevMode, dmLocal.dmSize); dmLocal.dmSize = sizeof(dmLocal); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + /* Set and return error */ SetLastNtError(_SEH2_GetExceptionCode()); _SEH2_YIELD(return DISP_CHANGE_BADPARAM); } _SEH2_END + /* Check for extra parameters */ if (dmLocal.dmDriverExtra > 0) { + /* FIXME: TODO */ DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n"); dmLocal.dmDriverExtra = 0; } + + /* Use the local structure */ lpDevMode = &dmLocal; } // FIXME: Copy videoparameters + + /* Acquire global USER lock */ UserEnterExclusive(); /* Call internal function */ - Ret = UserChangeDisplaySettings(pustrDevice, lpDevMode, hwnd, dwflags, NULL); - + lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, hwnd, dwflags, NULL); + + /* Release lock */ UserLeave(); - return Ret; -} - + return lRet; +} +
14 years, 8 months
1
0
0
0
[gschneider] 46700: [cmd] Emit line breaks DOS/Windows style (CRLF), instead of Linux style (LF only) See issue #4509 for more details.
by gschneider@svn.reactos.org
Author: gschneider Date: Sat Apr 3 19:24:10 2010 New Revision: 46700 URL:
http://svn.reactos.org/svn/reactos?rev=46700&view=rev
Log: [cmd] Emit line breaks DOS/Windows style (CRLF), instead of Linux style (LF only) See issue #4509 for more details. Modified: trunk/reactos/base/shell/cmd/console.c Modified: trunk/reactos/base/shell/cmd/console.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/console.c?r…
============================================================================== --- trunk/reactos/base/shell/cmd/console.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/console.c [iso-8859-1] Sat Apr 3 19:24:10 2010 @@ -166,7 +166,7 @@ VOID ConPuts(LPTSTR szText, DWORD nStdHandle) { ConWrite(szText, _tcslen(szText), nStdHandle); - ConWrite(_T("\n"), 1, nStdHandle); + ConWrite(_T("\r\n"), 2, nStdHandle); } VOID ConOutResPaging(BOOL NewPage, UINT resID)
14 years, 8 months
1
0
0
0
[gschneider] 46699: [taskmgr] Hide CPU graph options on single CPU systems See issue #2144 for more details.
by gschneider@svn.reactos.org
Author: gschneider Date: Sat Apr 3 19:23:27 2010 New Revision: 46699 URL:
http://svn.reactos.org/svn/reactos?rev=46699&view=rev
Log: [taskmgr] Hide CPU graph options on single CPU systems See issue #2144 for more details. Modified: trunk/reactos/base/applications/taskmgr/taskmgr.c Modified: trunk/reactos/base/applications/taskmgr/taskmgr.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/taskmgr/…
============================================================================== --- trunk/reactos/base/applications/taskmgr/taskmgr.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/taskmgr/taskmgr.c [iso-8859-1] Sat Apr 3 19:23:27 2010 @@ -869,6 +869,7 @@ HMENU hViewMenu; HMENU hSubMenu; WCHAR szTemp[256]; + SYSTEM_INFO sysInfo; hMenu = GetMenu(hMainWnd); hViewMenu = GetSubMenu(hMenu, 2); @@ -947,16 +948,28 @@ DeleteMenu(hMenu, 3, MF_BYPOSITION); DrawMenuBar(hMainWnd); } - hSubMenu = CreatePopupMenu(); - - LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256); - AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp); - - LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256); - AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp); - - LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256); - AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp); + + GetSystemInfo(&sysInfo); + + /* Hide CPU graph options on single CPU systems */ + if (sysInfo.dwNumberOfProcessors > 1) + { + hSubMenu = CreatePopupMenu(); + + LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256); + AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp); + + LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256); + AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp); + + LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256); + AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp); + + if (TaskManagerSettings.CPUHistory_OneGraphPerCPU) + CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND); + else + CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND); + } LoadStringW(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256); AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp); @@ -965,10 +978,7 @@ CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED); else CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED); - if (TaskManagerSettings.CPUHistory_OneGraphPerCPU) - CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND); - else - CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND); + /* * Give the tab control focus */
14 years, 8 months
1
0
0
0
[jgardou] 46698: [WIN32K] Unlock surface when deleting DC
by jgardou@svn.reactos.org
Author: jgardou Date: Sat Apr 3 18:42:04 2010 New Revision: 46698 URL:
http://svn.reactos.org/svn/reactos?rev=46698&view=rev
Log: [WIN32K] Unlock surface when deleting DC Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c [iso-8859-1] Sat Apr 3 18:42:04 2010 @@ -377,6 +377,9 @@ PATH_Delete(pdc->dclevel.hPath); + if(pdc->dclevel.pSurface) + SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); + PDEVOBJ_vRelease(pdc->ppdev) ; return TRUE;
14 years, 8 months
1
0
0
0
[jgardou] 46697: [WIN32K] Unlock/lock surface when locking DC
by jgardou@svn.reactos.org
Author: jgardou Date: Sat Apr 3 18:32:30 2010 New Revision: 46697 URL:
http://svn.reactos.org/svn/reactos?rev=46697&view=rev
Log: [WIN32K] Unlock/lock surface when locking DC Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/dc.h Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/dc.h URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/include/dc.h [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/include/dc.h [iso-8859-1] Sat Apr 3 18:32:30 2010 @@ -169,15 +169,19 @@ { PDC pdc; pdc = GDIOBJ_LockObj(hdc, GDILoObjType_LO_DC_TYPE); - + /* Direct DC's need PDEV locking */ if(pdc && pdc->dctype == DCTYPE_DIRECT) { /* Acquire shared PDEV lock */ EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock); - - /* Get the current surface */ - pdc->dclevel.pSurface = pdc->ppdev->pSurface; + + /* Update Surface if needed */ + if(pdc->dclevel.pSurface != pdc->ppdev->pSurface) + { + if(pdc->dclevel.pSurface) SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); + pdc->dclevel.pSurface = PDEVOBJ_pSurface(pdc->ppdev); + } } return pdc; }
14 years, 8 months
1
0
0
0
[fireball] 46696: [VENDOR/WINE] - Import Wine-1.1.42 gdi32, user32, winex11.drv, wineserver.
by fireball@svn.reactos.org
Author: fireball Date: Sat Apr 3 15:59:14 2010 New Revision: 46696 URL:
http://svn.reactos.org/svn/reactos?rev=46696&view=rev
Log: [VENDOR/WINE] - Import Wine-1.1.42 gdi32, user32, winex11.drv, wineserver. Modified: vendor/wine/dlls/gdi32/current/driver.c vendor/wine/dlls/gdi32/current/enhmetafile.c vendor/wine/dlls/gdi32/current/freetype.c vendor/wine/dlls/gdi32/current/region.c vendor/wine/dlls/user32/current/cursoricon.c vendor/wine/dlls/user32/current/menu.c vendor/wine/dlls/user32/current/message.c vendor/wine/dlls/user32/current/scroll.c vendor/wine/dlls/user32/current/tests/combo.c vendor/wine/dlls/user32/current/tests/cursoricon.c vendor/wine/dlls/user32/current/tests/scroll.c vendor/wine/dlls/user32/current/tests/win.c vendor/wine/dlls/user32/current/user_main.c vendor/wine/dlls/user32/current/user_private.h vendor/wine/dlls/user32/current/win.c vendor/wine/dlls/winex11.drv/current/dib.c vendor/wine/dlls/winex11.drv/current/graphics.c vendor/wine/dlls/winex11.drv/current/ime.c vendor/wine/dlls/winex11.drv/current/settings.c vendor/wine/dlls/winex11.drv/current/window.c vendor/wine/server/current/debugger.c vendor/wine/server/current/fd.c vendor/wine/server/current/protocol.def vendor/wine/server/current/queue.c vendor/wine/server/current/registry.c vendor/wine/server/current/request.h vendor/wine/server/current/sock.c vendor/wine/server/current/trace.c [This mail would be too long, it was shortened to contain the URLs only.] Modified: vendor/wine/dlls/gdi32/current/driver.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/gdi32/current/driver.c?…
Modified: vendor/wine/dlls/gdi32/current/enhmetafile.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/gdi32/current/enhmetafi…
Modified: vendor/wine/dlls/gdi32/current/freetype.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/gdi32/current/freetype.…
Modified: vendor/wine/dlls/gdi32/current/region.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/gdi32/current/region.c?…
Modified: vendor/wine/dlls/user32/current/cursoricon.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/cursoric…
Modified: vendor/wine/dlls/user32/current/menu.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/menu.c?r…
Modified: vendor/wine/dlls/user32/current/message.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/message.…
Modified: vendor/wine/dlls/user32/current/scroll.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/scroll.c…
Modified: vendor/wine/dlls/user32/current/tests/combo.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/tests/co…
Modified: vendor/wine/dlls/user32/current/tests/cursoricon.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/tests/cu…
Modified: vendor/wine/dlls/user32/current/tests/scroll.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/tests/sc…
Modified: vendor/wine/dlls/user32/current/tests/win.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/tests/wi…
Modified: vendor/wine/dlls/user32/current/user_main.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/user_mai…
Modified: vendor/wine/dlls/user32/current/user_private.h URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/user_pri…
Modified: vendor/wine/dlls/user32/current/win.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/user32/current/win.c?re…
Modified: vendor/wine/dlls/winex11.drv/current/dib.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/winex11.drv/current/dib…
Modified: vendor/wine/dlls/winex11.drv/current/graphics.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/winex11.drv/current/gra…
Modified: vendor/wine/dlls/winex11.drv/current/ime.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/winex11.drv/current/ime…
Modified: vendor/wine/dlls/winex11.drv/current/settings.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/winex11.drv/current/set…
Modified: vendor/wine/dlls/winex11.drv/current/window.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/dlls/winex11.drv/current/win…
Modified: vendor/wine/server/current/debugger.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/server/current/debugger.c?re…
Modified: vendor/wine/server/current/fd.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/server/current/fd.c?rev=4669…
Modified: vendor/wine/server/current/protocol.def URL:
http://svn.reactos.org/svn/reactos/vendor/wine/server/current/protocol.def?…
Modified: vendor/wine/server/current/queue.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/server/current/queue.c?rev=4…
Modified: vendor/wine/server/current/registry.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/server/current/registry.c?re…
Modified: vendor/wine/server/current/request.h URL:
http://svn.reactos.org/svn/reactos/vendor/wine/server/current/request.h?rev…
Modified: vendor/wine/server/current/sock.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/server/current/sock.c?rev=46…
Modified: vendor/wine/server/current/trace.c URL:
http://svn.reactos.org/svn/reactos/vendor/wine/server/current/trace.c?rev=4…
14 years, 8 months
1
0
0
0
← Newer
1
...
34
35
36
37
38
39
40
...
44
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
Results per page:
10
25
50
100
200