-#\r
-# Architecture to build for\r
-#\r
-# Specify one of: i386\r
-# Possible values in the future: alpha,i386,m68k,mips,powerpc\r
-ARCH := i386\r
-\r
-#\r
-# Whether to compile in the kernel debugger\r
-#\r
-KDBG := 0\r
-\r
-#\r
-# Whether to compile for debugging\r
-#\r
-DBG := 0\r
-\r
-#\r
-# Whether to compile a multiprocessor or single processor version\r
-#\r
-MP := 0\r
-\r
-#\r
-# Whether to compile for ACPI compliant systems\r
-#\r
-ACPI := 0\r
-\r
-#\r
-# Whether to use Structured Exception Handling\r
-#\r
-SEH := 0\r
-\r
-\r
-#\r
-# Which version of NDIS do we support up to?\r
-#\r
-#NDISVERSION=NDIS50\r
-\r
+#
+# Architecture to build for
+#
+# Specify one of: i386
+# Possible values in the future: alpha,i386,m68k,mips,powerpc
+ARCH := i386
+
+#
+# Whether to compile in the kernel debugger
+#
+KDBG := 0
+
+#
+# Whether to compile for debugging
+#
+DBG := 0
+
+#
+# Whether to compile a multiprocessor or single processor version
+#
+MP := 0
+
+#
+# Whether to compile for ACPI compliant systems
+#
+ACPI := 0
+
+#
+# Whether to use Structured Exception Handling
+#
+SEH := 0
+
+
+#
+# Which version of NDIS do we support up to?
+#
+#NDISVERSION=NDIS50
+
-#ifdef UNICODE\r
-#undef UNICODE\r
-#endif\r
-\r
-#undef WIN32_LEAN_AND_MEAN\r
-#include <windows.h>\r
-#include <ddk/ntddk.h>\r
-#include <win32k/kapi.h>\r
-#include <debug.h>\r
-\r
-/*\r
- * @implemented\r
- */\r
-BOOL\r
-STDCALL\r
-BitBlt(HDC hDCDest,\r
- INT XDest,\r
- INT YDest,\r
- INT Width,\r
- INT Height,\r
- HDC hDCSrc,\r
- INT XSrc,\r
- INT YSrc,\r
- DWORD ROP)\r
-{\r
- return NtGdiBitBlt(hDCDest, XDest, YDest, Width, Height, hDCSrc, XSrc, YSrc, ROP);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-HBITMAP\r
-STDCALL\r
-CreateBitmap(INT Width,\r
- INT Height,\r
- UINT Planes,\r
- UINT BitsPerPel,\r
- CONST VOID *Bits)\r
-{\r
- return NtGdiCreateBitmap(Width, Height, Planes, BitsPerPel, Bits);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-HBITMAP\r
-STDCALL\r
-CreateBitmapIndirect(CONST BITMAP *BM)\r
-{\r
- return NtGdiCreateBitmapIndirect(BM);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-HBITMAP\r
-STDCALL\r
-CreateCompatibleBitmap(HDC hDC,\r
- INT Width,\r
- INT Height)\r
-{\r
- return NtGdiCreateCompatibleBitmap(hDC, Width, Height);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-HBITMAP\r
-STDCALL\r
-CreateDiscardableBitmap(HDC hDC,\r
- INT Width,\r
- INT Height)\r
-{\r
- return NtGdiCreateDiscardableBitmap(hDC, Width, Height);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-HBITMAP\r
-STDCALL\r
-CreateDIBitmap(HDC hDC,\r
- CONST BITMAPINFOHEADER *bmih,\r
- DWORD Init,\r
- CONST VOID *bInit,\r
- CONST BITMAPINFO *bmi,\r
- UINT Usage)\r
-{\r
- return NtGdiCreateDIBitmap(hDC, bmih, Init, bInit, bmi, Usage);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-LONG\r
-STDCALL\r
-GetBitmapBits(HBITMAP hBitmap,\r
- LONG Count,\r
- LPVOID Bits)\r
-{\r
- return NtGdiGetBitmapBits(hBitmap, Count, Bits);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-BOOL\r
-STDCALL\r
-GetBitmapDimensionEx(HBITMAP hBitmap,\r
- LPSIZE Dimension)\r
-{\r
- return NtGdiGetBitmapDimensionEx(hBitmap, Dimension);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-int\r
-STDCALL\r
-GetDIBits(HDC hDC,\r
- HBITMAP hBitmap,\r
- UINT StartScan,\r
- UINT ScanLines,\r
- LPVOID Bits,\r
- LPBITMAPINFO bi,\r
- UINT Usage)\r
-{\r
- return NtGdiGetDIBits(hDC, hBitmap, StartScan, ScanLines, Bits, bi, Usage);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-BOOL\r
-STDCALL\r
-MaskBlt(HDC hDCDest,\r
- INT XDest,\r
- INT YDest,\r
- INT Width,\r
- INT Height,\r
- HDC hDCSrc,\r
- INT XSrc,\r
- INT YSrc,\r
- HBITMAP hMaskBitmap,\r
- INT xMask,\r
- INT yMask,\r
- DWORD ROP)\r
-{\r
- return NtGdiMaskBlt(hDCDest, XDest, YDest, Width, Height, hDCSrc, XSrc, YSrc, hMaskBitmap, xMask, yMask, ROP);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-BOOL\r
-STDCALL\r
-PlgBlt(HDC hDCDest,\r
- CONST POINT *Point,\r
- HDC hDCSrc, \r
- INT XSrc, \r
- INT YSrc, \r
- INT Width, \r
- INT Height,\r
- HBITMAP hMaskBitmap,\r
- INT xMask, \r
- INT yMask)\r
-{\r
- return NtGdiPlgBlt(hDCDest, Point, hDCSrc, XSrc, YSrc, Width, Height, hMaskBitmap, xMask, yMask);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-LONG\r
-STDCALL\r
-SetBitmapBits(HBITMAP hBitmap,\r
- DWORD Bytes,\r
- CONST VOID *Bits)\r
-{\r
- return NtGdiSetBitmapBits(hBitmap, Bytes, Bits);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-int\r
-STDCALL\r
-SetDIBits(HDC hDC,\r
- HBITMAP hBitmap,\r
- UINT StartScan,\r
- UINT ScanLines,\r
- CONST VOID *Bits,\r
- CONST BITMAPINFO *bmi,\r
- UINT ColorUse)\r
-{\r
- return NtGdiSetDIBits(hDC, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-int\r
-STDCALL\r
-SetDIBitsToDevice(HDC hDC,\r
- INT XDest,\r
- INT YDest,\r
- DWORD Width,\r
- DWORD Height,\r
- INT XSrc,\r
- INT YSrc,\r
- UINT StartScan,\r
- UINT ScanLines,\r
- CONST VOID *Bits,\r
- CONST BITMAPINFO *bmi,\r
- UINT ColorUse)\r
-{\r
- return NtGdiSetDIBitsToDevice(hDC, XDest, YDest, Width, Height, XSrc, YSrc, StartScan, ScanLines,\r
- Bits, bmi, ColorUse);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-BOOL\r
-STDCALL\r
-StretchBlt(\r
- HDC hdcDest, // handle to destination DC\r
- int nXOriginDest, // x-coord of destination upper-left corner\r
- int nYOriginDest, // y-coord of destination upper-left corner\r
- int nWidthDest, // width of destination rectangle\r
- int nHeightDest, // height of destination rectangle\r
- HDC hdcSrc, // handle to source DC\r
- int nXOriginSrc, // x-coord of source upper-left corner\r
- int nYOriginSrc, // y-coord of source upper-left corner\r
- int nWidthSrc, // width of source rectangle\r
- int nHeightSrc, // height of source rectangle\r
- DWORD dwRop // raster operation code\r
- )\r
-{\r
- //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);\r
- if ( (nWidthDest==nWidthSrc) && (nHeightDest==nHeightSrc) )\r
- {\r
- return BitBlt(hdcDest,\r
- nXOriginDest, // x-coord of destination upper-left corner\r
- nYOriginDest, // y-coord of destination upper-left corner\r
- nWidthDest, // width of destination rectangle\r
- nHeightDest, // height of destination rectangle\r
- hdcSrc, // handle to source DC\r
- nXOriginSrc, // x-coordinate of source upper-left corner\r
- nYOriginSrc, // y-coordinate of source upper-left corner\r
- dwRop // raster operation code\r
- );\r
- }\r
- \r
- DPRINT1("FIXME: StretchBlt can only Blt, not Stretch!\n");\r
- return FALSE;\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-int\r
-STDCALL\r
-StretchDIBits(HDC hDC,\r
- INT XDest,\r
- INT YDest,\r
- INT DestWidth,\r
- INT DestHeight,\r
- INT XSrc,\r
- INT YSrc,\r
- INT SrcWidth,\r
- INT SrcHeight,\r
- CONST VOID *Bits,\r
- CONST BITMAPINFO *BitsInfo,\r
- UINT Usage,\r
- DWORD ROP)\r
-{\r
- return NtGdiStretchDIBits(hDC, XDest, YDest, DestWidth, DestHeight, XSrc, YSrc,\r
- SrcWidth, SrcHeight, Bits, BitsInfo, Usage, ROP);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-HBITMAP \r
-STDCALL \r
-CreateDIBSection(HDC hDC,\r
- CONST BITMAPINFO *bmi,\r
- UINT Usage,\r
- VOID *Bits,\r
- HANDLE hSection,\r
- DWORD dwOffset)\r
-{\r
- return NtGdiCreateDIBSection(hDC, bmi, Usage, Bits, hSection, dwOffset);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-COLORREF \r
-STDCALL \r
-SetPixel(HDC hDC,\r
- INT X,\r
- INT Y,\r
- COLORREF Color)\r
-{\r
- return NtGdiSetPixel(hDC, X, Y, Color);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-BOOL STDCALL\r
-PatBlt(HDC hDC, INT Top, INT Left, INT Width, INT Height, ULONG Rop)\r
-{\r
- return(NtGdiPatBlt(hDC, Top, Left, Width, Height, Rop));\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-WINBOOL \r
-STDCALL \r
-PolyPatBlt(HDC hDC,DWORD dwRop,PPATRECT pRects,int cRects,ULONG Reserved)\r
-{\r
- return NtGdiPolyPatBlt(hDC,dwRop,pRects,cRects,Reserved);\r
-}\r
-\r
-\r
-/*\r
-\r
-BOOL STDCALL NtGdiExtFloodFill(HDC hDC, INT XStart, INT YStart, COLORREF Color, UINT FillType)\r
-BOOL STDCALL NtGdiFloodFill(HDC hDC, INT XStart, INT YStart, COLORREF Fill)\r
-UINT STDCALL NtGdiGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors)\r
-COLORREF STDCALL NtGdiGetPixel(HDC hDC,\r
- INT XPos,\r
- INT YPos)\r
-BOOL STDCALL NtGdiSetBitmapDimensionEx(HBITMAP hBitmap,\r
- INT Width,\r
- INT Height,\r
- LPSIZE Size)\r
-UINT STDCALL NtGdiSetDIBColorTable(HDC hDC,\r
- UINT StartIndex,\r
- UINT Entries,\r
- CONST RGBQUAD *Colors)\r
-BOOL STDCALL NtGdiSetPixelV(HDC hDC,\r
- INT X,\r
- INT Y,\r
- COLORREF Color)\r
-BOOL STDCALL NtGdiStretchBlt(HDC hDCDest,\r
- INT XOriginDest,\r
- INT YOriginDest,\r
- INT WidthDest,\r
- INT HeightDest,\r
- HDC hDCSrc,\r
- INT XOriginSrc,\r
- INT YOriginSrc,\r
- INT WidthSrc, \r
- INT HeightSrc, \r
- DWORD ROP)\r
-\r
-INT BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)\r
-HBITMAP BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)\r
-int DIB_GetDIBWidthBytes(int width, int depth)\r
-int DIB_GetDIBImageBytes (int width, int height, int depth)\r
-int DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)\r
-\r
-*/\r
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
+#undef WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <ddk/ntddk.h>
+#include <win32k/kapi.h>
+#include <debug.h>
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+BitBlt(HDC hDCDest,
+ INT XDest,
+ INT YDest,
+ INT Width,
+ INT Height,
+ HDC hDCSrc,
+ INT XSrc,
+ INT YSrc,
+ DWORD ROP)
+{
+ return NtGdiBitBlt(hDCDest, XDest, YDest, Width, Height, hDCSrc, XSrc, YSrc, ROP);
+}
+
+
+/*
+ * @implemented
+ */
+HBITMAP
+STDCALL
+CreateBitmap(INT Width,
+ INT Height,
+ UINT Planes,
+ UINT BitsPerPel,
+ CONST VOID *Bits)
+{
+ return NtGdiCreateBitmap(Width, Height, Planes, BitsPerPel, Bits);
+}
+
+
+/*
+ * @implemented
+ */
+HBITMAP
+STDCALL
+CreateBitmapIndirect(CONST BITMAP *BM)
+{
+ return NtGdiCreateBitmapIndirect(BM);
+}
+
+
+/*
+ * @implemented
+ */
+HBITMAP
+STDCALL
+CreateCompatibleBitmap(HDC hDC,
+ INT Width,
+ INT Height)
+{
+ return NtGdiCreateCompatibleBitmap(hDC, Width, Height);
+}
+
+
+/*
+ * @implemented
+ */
+HBITMAP
+STDCALL
+CreateDiscardableBitmap(HDC hDC,
+ INT Width,
+ INT Height)
+{
+ return NtGdiCreateDiscardableBitmap(hDC, Width, Height);
+}
+
+
+/*
+ * @implemented
+ */
+HBITMAP
+STDCALL
+CreateDIBitmap(HDC hDC,
+ CONST BITMAPINFOHEADER *bmih,
+ DWORD Init,
+ CONST VOID *bInit,
+ CONST BITMAPINFO *bmi,
+ UINT Usage)
+{
+ return NtGdiCreateDIBitmap(hDC, bmih, Init, bInit, bmi, Usage);
+}
+
+
+/*
+ * @implemented
+ */
+LONG
+STDCALL
+GetBitmapBits(HBITMAP hBitmap,
+ LONG Count,
+ LPVOID Bits)
+{
+ return NtGdiGetBitmapBits(hBitmap, Count, Bits);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetBitmapDimensionEx(HBITMAP hBitmap,
+ LPSIZE Dimension)
+{
+ return NtGdiGetBitmapDimensionEx(hBitmap, Dimension);
+}
+
+
+/*
+ * @implemented
+ */
+int
+STDCALL
+GetDIBits(HDC hDC,
+ HBITMAP hBitmap,
+ UINT StartScan,
+ UINT ScanLines,
+ LPVOID Bits,
+ LPBITMAPINFO bi,
+ UINT Usage)
+{
+ return NtGdiGetDIBits(hDC, hBitmap, StartScan, ScanLines, Bits, bi, Usage);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+MaskBlt(HDC hDCDest,
+ INT XDest,
+ INT YDest,
+ INT Width,
+ INT Height,
+ HDC hDCSrc,
+ INT XSrc,
+ INT YSrc,
+ HBITMAP hMaskBitmap,
+ INT xMask,
+ INT yMask,
+ DWORD ROP)
+{
+ return NtGdiMaskBlt(hDCDest, XDest, YDest, Width, Height, hDCSrc, XSrc, YSrc, hMaskBitmap, xMask, yMask, ROP);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+PlgBlt(HDC hDCDest,
+ CONST POINT *Point,
+ HDC hDCSrc,
+ INT XSrc,
+ INT YSrc,
+ INT Width,
+ INT Height,
+ HBITMAP hMaskBitmap,
+ INT xMask,
+ INT yMask)
+{
+ return NtGdiPlgBlt(hDCDest, Point, hDCSrc, XSrc, YSrc, Width, Height, hMaskBitmap, xMask, yMask);
+}
+
+
+/*
+ * @implemented
+ */
+LONG
+STDCALL
+SetBitmapBits(HBITMAP hBitmap,
+ DWORD Bytes,
+ CONST VOID *Bits)
+{
+ return NtGdiSetBitmapBits(hBitmap, Bytes, Bits);
+}
+
+
+/*
+ * @implemented
+ */
+int
+STDCALL
+SetDIBits(HDC hDC,
+ HBITMAP hBitmap,
+ UINT StartScan,
+ UINT ScanLines,
+ CONST VOID *Bits,
+ CONST BITMAPINFO *bmi,
+ UINT ColorUse)
+{
+ return NtGdiSetDIBits(hDC, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
+}
+
+
+/*
+ * @implemented
+ */
+int
+STDCALL
+SetDIBitsToDevice(HDC hDC,
+ INT XDest,
+ INT YDest,
+ DWORD Width,
+ DWORD Height,
+ INT XSrc,
+ INT YSrc,
+ UINT StartScan,
+ UINT ScanLines,
+ CONST VOID *Bits,
+ CONST BITMAPINFO *bmi,
+ UINT ColorUse)
+{
+ return NtGdiSetDIBitsToDevice(hDC, XDest, YDest, Width, Height, XSrc, YSrc, StartScan, ScanLines,
+ Bits, bmi, ColorUse);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+StretchBlt(
+ HDC hdcDest, // handle to destination DC
+ int nXOriginDest, // x-coord of destination upper-left corner
+ int nYOriginDest, // y-coord of destination upper-left corner
+ int nWidthDest, // width of destination rectangle
+ int nHeightDest, // height of destination rectangle
+ HDC hdcSrc, // handle to source DC
+ int nXOriginSrc, // x-coord of source upper-left corner
+ int nYOriginSrc, // y-coord of source upper-left corner
+ int nWidthSrc, // width of source rectangle
+ int nHeightSrc, // height of source rectangle
+ DWORD dwRop // raster operation code
+ )
+{
+ //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ if ( (nWidthDest==nWidthSrc) && (nHeightDest==nHeightSrc) )
+ {
+ return BitBlt(hdcDest,
+ nXOriginDest, // x-coord of destination upper-left corner
+ nYOriginDest, // y-coord of destination upper-left corner
+ nWidthDest, // width of destination rectangle
+ nHeightDest, // height of destination rectangle
+ hdcSrc, // handle to source DC
+ nXOriginSrc, // x-coordinate of source upper-left corner
+ nYOriginSrc, // y-coordinate of source upper-left corner
+ dwRop // raster operation code
+ );
+ }
+
+ DPRINT1("FIXME: StretchBlt can only Blt, not Stretch!\n");
+ return FALSE;
+}
+
+
+/*
+ * @implemented
+ */
+int
+STDCALL
+StretchDIBits(HDC hDC,
+ INT XDest,
+ INT YDest,
+ INT DestWidth,
+ INT DestHeight,
+ INT XSrc,
+ INT YSrc,
+ INT SrcWidth,
+ INT SrcHeight,
+ CONST VOID *Bits,
+ CONST BITMAPINFO *BitsInfo,
+ UINT Usage,
+ DWORD ROP)
+{
+ return NtGdiStretchDIBits(hDC, XDest, YDest, DestWidth, DestHeight, XSrc, YSrc,
+ SrcWidth, SrcHeight, Bits, BitsInfo, Usage, ROP);
+}
+
+
+/*
+ * @implemented
+ */
+HBITMAP
+STDCALL
+CreateDIBSection(HDC hDC,
+ CONST BITMAPINFO *bmi,
+ UINT Usage,
+ VOID *Bits,
+ HANDLE hSection,
+ DWORD dwOffset)
+{
+ return NtGdiCreateDIBSection(hDC, bmi, Usage, Bits, hSection, dwOffset);
+}
+
+
+/*
+ * @implemented
+ */
+COLORREF
+STDCALL
+SetPixel(HDC hDC,
+ INT X,
+ INT Y,
+ COLORREF Color)
+{
+ return NtGdiSetPixel(hDC, X, Y, Color);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+PatBlt(HDC hDC, INT Top, INT Left, INT Width, INT Height, ULONG Rop)
+{
+ return(NtGdiPatBlt(hDC, Top, Left, Width, Height, Rop));
+}
+
+/*
+ * @implemented
+ */
+WINBOOL
+STDCALL
+PolyPatBlt(HDC hDC,DWORD dwRop,PPATRECT pRects,int cRects,ULONG Reserved)
+{
+ return NtGdiPolyPatBlt(hDC,dwRop,pRects,cRects,Reserved);
+}
+
+
+/*
+
+BOOL STDCALL NtGdiExtFloodFill(HDC hDC, INT XStart, INT YStart, COLORREF Color, UINT FillType)
+BOOL STDCALL NtGdiFloodFill(HDC hDC, INT XStart, INT YStart, COLORREF Fill)
+UINT STDCALL NtGdiGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors)
+COLORREF STDCALL NtGdiGetPixel(HDC hDC,
+ INT XPos,
+ INT YPos)
+BOOL STDCALL NtGdiSetBitmapDimensionEx(HBITMAP hBitmap,
+ INT Width,
+ INT Height,
+ LPSIZE Size)
+UINT STDCALL NtGdiSetDIBColorTable(HDC hDC,
+ UINT StartIndex,
+ UINT Entries,
+ CONST RGBQUAD *Colors)
+BOOL STDCALL NtGdiSetPixelV(HDC hDC,
+ INT X,
+ INT Y,
+ COLORREF Color)
+BOOL STDCALL NtGdiStretchBlt(HDC hDCDest,
+ INT XOriginDest,
+ INT YOriginDest,
+ INT WidthDest,
+ INT HeightDest,
+ HDC hDCSrc,
+ INT XOriginSrc,
+ INT YOriginSrc,
+ INT WidthSrc,
+ INT HeightSrc,
+ DWORD ROP)
+
+INT BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
+HBITMAP BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)
+int DIB_GetDIBWidthBytes(int width, int depth)
+int DIB_GetDIBImageBytes (int width, int height, int depth)
+int DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)
+
+*/
-/*\r
- * ReactOS kernel\r
- * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- */\r
-/* $Id: bitmap.c,v 1.16 2003/10/06 18:24:54 navaraf Exp $\r
- *\r
- * PROJECT: ReactOS user32.dll\r
- * FILE: lib/user32/windows/input.c\r
- * PURPOSE: Input\r
- * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)\r
- * UPDATE HISTORY:\r
- * 09-05-2001 CSH Created\r
- */\r
-\r
-/* INCLUDES ******************************************************************/\r
-\r
-#include <string.h>\r
-#include <windows.h>\r
-#include <user32.h>\r
-#include <debug.h>\r
-#include <stdlib.h>\r
-\r
-/*forward declerations... actualy in user32\windows\icon.c but usful here****/\r
-HICON ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot);\r
-CURSORICONDIRENTRY *CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors);\r
-CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors);\r
-\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-/*\r
- * @implemented\r
- */\r
-HANDLE STDCALL\r
-LoadImageA(HINSTANCE hinst,\r
- LPCSTR lpszName,\r
- UINT uType,\r
- int cxDesired,\r
- int cyDesired,\r
- UINT fuLoad)\r
-{\r
- LPWSTR lpszWName;\r
- HANDLE Handle;\r
- UNICODE_STRING NameString;\r
-\r
- if (HIWORD(lpszName))\r
- { \r
- RtlCreateUnicodeStringFromAsciiz(&NameString, (LPSTR)lpszName);\r
- lpszWName = NameString.Buffer;\r
- Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,\r
- cyDesired, fuLoad);\r
- RtlFreeUnicodeString(&NameString);\r
- }\r
- else\r
- {\r
- Handle = LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired,\r
- cyDesired, fuLoad);\r
- }\r
- return(Handle);\r
-}\r
-\r
-\r
-HANDLE STATIC\r
-LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)\r
-{\r
- HANDLE hResource;\r
- HANDLE h2Resource;\r
- HANDLE hFile;\r
- HANDLE hSection;\r
- CURSORICONDIR* IconDIR;\r
- HDC hScreenDc;\r
- HANDLE hIcon;\r
- ULONG HeaderSize;\r
- ULONG ColourCount;\r
- PVOID Data;\r
- CURSORICONDIRENTRY* dirEntry;\r
- ICONIMAGE* SafeIconImage;\r
- GRPCURSORICONDIR* IconResDir;\r
- INT id;\r
- ICONIMAGE *ResIcon;\r
-\r
- if (fuLoad & LR_SHARED)\r
- DbgPrint("FIXME: need LR_SHARED support Loading cursor images\n");\r
-\r
- if (!(fuLoad & LR_LOADFROMFILE))\r
- {\r
- if (hinst == NULL)\r
- {\r
- hinst = GetModuleHandleW(L"USER32");\r
- }\r
- hResource = FindResourceW(hinst, lpszName, RT_GROUP_CURSOR);\r
- if (hResource == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- hResource = LoadResource(hinst, hResource);\r
- if (hResource == NULL)\r
- {\r
- return(NULL);\r
- }\r
- IconResDir = LockResource(hResource);\r
- if (IconResDir == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- //find the best fitting in the IconResDir for this resolution\r
- id = LookupIconIdFromDirectoryEx((PBYTE) IconResDir, TRUE,\r
- 32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));\r
-\r
- h2Resource = FindResourceW(hinst,\r
- MAKEINTRESOURCEW(id),\r
- MAKEINTRESOURCEW(RT_CURSOR));\r
-\r
- hResource = LoadResource(hinst, h2Resource);\r
- if (hResource == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- ResIcon = LockResource(hResource);\r
- if (ResIcon == NULL)\r
- {\r
- return(NULL);\r
- }\r
- return CreateIconFromResourceEx((PBYTE) ResIcon,\r
- SizeofResource(hinst, h2Resource), FALSE, 0x00030000,\r
- 32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));\r
- }\r
- else\r
- {\r
- hFile = CreateFileW(lpszName,\r
- GENERIC_READ,\r
- FILE_SHARE_READ,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL);\r
- if (hFile == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- hSection = CreateFileMappingW(hFile,\r
- NULL,\r
- PAGE_READONLY,\r
- 0,\r
- 0,\r
- NULL);\r
-\r
- CloseHandle(hFile);\r
- if (hSection == NULL)\r
- {\r
- return(NULL);\r
- }\r
- IconDIR = MapViewOfFile(hSection,\r
- FILE_MAP_READ,\r
- 0,\r
- 0,\r
- 0);\r
-\r
- CloseHandle(hSection);\r
- if (IconDIR == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- //pick the best size.\r
- dirEntry = (CURSORICONDIRENTRY *) CURSORICON_FindBestIcon( IconDIR, 32, 32, 1);\r
-\r
-\r
- if (!dirEntry)\r
- {\r
- if (fuLoad & LR_LOADFROMFILE)\r
- {\r
- UnmapViewOfFile(IconDIR);\r
- }\r
- return(NULL);\r
- }\r
-\r
- SafeIconImage = RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry->dwBytesInRes); \r
-\r
- memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);\r
- }\r
-\r
- //at this point we have a copy of the icon image to play with\r
-\r
- SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;\r
-\r
- if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))\r
- {\r
- BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;\r
- ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;\r
- HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);\r
- }\r
- else\r
- {\r
- ColourCount = SafeIconImage->icHeader.biClrUsed;\r
- if (ColourCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)\r
- {\r
- ColourCount = 1 << SafeIconImage->icHeader.biBitCount;\r
- }\r
- HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);\r
- }\r
- \r
- //make data point to the start of the XOR image data\r
- Data = (PBYTE)SafeIconImage + HeaderSize;\r
-\r
-\r
- //get a handle to the screen dc, the icon we create is going to be compatable with this\r
- hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);\r
- if (hScreenDc == NULL)\r
- {\r
- if (fuLoad & LR_LOADFROMFILE)\r
- {\r
- RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);\r
- UnmapViewOfFile(IconDIR);\r
- }\r
- return(NULL);\r
- }\r
-\r
- hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, 32, 32, dirEntry->Info.cursor.wXHotspot, dirEntry->Info.cursor.wYHotspot);\r
- RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);\r
- return hIcon;\r
-}\r
-\r
-\r
-HANDLE STATIC\r
-LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuLoad)\r
-{\r
- HANDLE hResource;\r
- HANDLE h2Resource;\r
- HANDLE hFile;\r
- HANDLE hSection;\r
- CURSORICONDIR* IconDIR;\r
- HDC hScreenDc;\r
- HANDLE hIcon;\r
- ULONG HeaderSize;\r
- ULONG ColourCount;\r
- PVOID Data;\r
- CURSORICONDIRENTRY* dirEntry;\r
- ICONIMAGE* SafeIconImage;\r
- GRPCURSORICONDIR* IconResDir;\r
- INT id;\r
- ICONIMAGE *ResIcon;\r
-\r
- if (fuLoad & LR_SHARED)\r
- DbgPrint("FIXME: need LR_SHARED support Loading icon images\n");\r
-\r
- if (!(fuLoad & LR_LOADFROMFILE))\r
- {\r
- if (hinst == NULL)\r
- {\r
- hinst = GetModuleHandleW(L"USER32");\r
- }\r
- hResource = FindResourceW(hinst, lpszName, RT_GROUP_ICON);\r
- if (hResource == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- hResource = LoadResource(hinst, hResource);\r
- if (hResource == NULL)\r
- {\r
- return(NULL);\r
- }\r
- IconResDir = LockResource(hResource);\r
- if (IconResDir == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- //find the best fitting in the IconResDir for this resolution\r
- id = LookupIconIdFromDirectoryEx((PBYTE) IconResDir, TRUE,\r
- width, height, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));\r
-\r
- h2Resource = FindResourceW(hinst,\r
- MAKEINTRESOURCEW(id),\r
- MAKEINTRESOURCEW(RT_ICON));\r
-\r
- hResource = LoadResource(hinst, h2Resource);\r
- if (hResource == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- ResIcon = LockResource(hResource);\r
- if (ResIcon == NULL)\r
- {\r
- return(NULL);\r
- }\r
- return CreateIconFromResourceEx((PBYTE) ResIcon,\r
- SizeofResource(hinst, h2Resource), TRUE, 0x00030000,\r
- width, height, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));\r
- }\r
- else\r
- {\r
- hFile = CreateFileW(lpszName,\r
- GENERIC_READ,\r
- FILE_SHARE_READ,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL);\r
- if (hFile == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- hSection = CreateFileMappingW(hFile,\r
- NULL,\r
- PAGE_READONLY,\r
- 0,\r
- 0,\r
- NULL);\r
-\r
- CloseHandle(hFile);\r
- if (hSection == NULL)\r
- {\r
- return(NULL);\r
- }\r
- IconDIR = MapViewOfFile(hSection,\r
- FILE_MAP_READ,\r
- 0,\r
- 0,\r
- 0);\r
-\r
- CloseHandle(hSection);\r
- if (IconDIR == NULL)\r
- {\r
- return(NULL);\r
- }\r
-\r
- //pick the best size.\r
- dirEntry = (CURSORICONDIRENTRY *) CURSORICON_FindBestIcon( IconDIR, width, height, 1);\r
-\r
-\r
- if (!dirEntry)\r
- {\r
- if (fuLoad & LR_LOADFROMFILE)\r
- {\r
- UnmapViewOfFile(IconDIR);\r
- }\r
- return(NULL);\r
- }\r
-\r
- SafeIconImage = RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry->dwBytesInRes); \r
-\r
- memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);\r
- }\r
-\r
- //at this point we have a copy of the icon image to play with\r
-\r
- SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;\r
-\r
- if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))\r
- {\r
- BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;\r
- ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;\r
- HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);\r
- }\r
- else\r
- {\r
- ColourCount = SafeIconImage->icHeader.biClrUsed;\r
- if (ColourCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)\r
- {\r
- ColourCount = 1 << SafeIconImage->icHeader.biBitCount;\r
- }\r
- HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);\r
- }\r
- \r
- //make data point to the start of the XOR image data\r
- Data = (PBYTE)SafeIconImage + HeaderSize;\r
-\r
-\r
- //get a handle to the screen dc, the icon we create is going to be compatable with this\r
- hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);\r
- if (hScreenDc == NULL)\r
- {\r
- if (fuLoad & LR_LOADFROMFILE)\r
- {\r
- RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);\r
- UnmapViewOfFile(IconDIR);\r
- }\r
- return(NULL);\r
- }\r
-\r
- hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2);\r
- RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);\r
- return hIcon;\r
-}\r
-\r
-\r
-HANDLE STATIC\r
-LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)\r
-{\r
- HANDLE hResource;\r
- HANDLE hFile;\r
- HANDLE hSection;\r
- BITMAPINFO* BitmapInfo;\r
- BITMAPINFO* PrivateInfo;\r
- HDC hScreenDc;\r
- HANDLE hBitmap;\r
- ULONG HeaderSize;\r
- ULONG ColourCount;\r
- PVOID Data;\r
-\r
- if (!(fuLoad & LR_LOADFROMFILE))\r
- {\r
- if (hInstance == NULL)\r
- {\r
- hInstance = GetModuleHandleW(L"USER32");\r
- }\r
- hResource = FindResourceW(hInstance, lpszName, RT_BITMAP);\r
- if (hResource == NULL)\r
- {\r
- return(NULL);\r
- }\r
- hResource = LoadResource(hInstance, hResource);\r
- if (hResource == NULL)\r
- {\r
- return(NULL);\r
- }\r
- BitmapInfo = LockResource(hResource);\r
- if (BitmapInfo == NULL)\r
- {\r
- return(NULL);\r
- }\r
- }\r
- else\r
- {\r
- hFile = CreateFileW(lpszName,\r
- GENERIC_READ,\r
- FILE_SHARE_READ,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL);\r
- if (hFile == NULL)\r
- {\r
- return(NULL);\r
- }\r
- hSection = CreateFileMappingW(hFile,\r
- NULL,\r
- PAGE_READONLY,\r
- 0,\r
- 0,\r
- NULL);\r
- CloseHandle(hFile);\r
- if (hSection == NULL)\r
- { \r
- return(NULL);\r
- }\r
- BitmapInfo = MapViewOfFile(hSection,\r
- FILE_MAP_READ,\r
- 0,\r
- 0,\r
- 0);\r
- CloseHandle(hSection);\r
- if (BitmapInfo == NULL)\r
- {\r
- return(NULL);\r
- }\r
- /* offset BitmapInfo by 14 bytes to acount for the size of BITMAPFILEHEADER\r
- unfortunatly sizeof(BITMAPFILEHEADER) = 16, but the acutal size should be 14!\r
- */\r
- BitmapInfo = (BITMAPINFO*)(((PBYTE)BitmapInfo) + 14);\r
- }\r
-\r
- if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))\r
- {\r
- BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)BitmapInfo;\r
- ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;\r
- HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);\r
- }\r
- else\r
- {\r
- ColourCount = BitmapInfo->bmiHeader.biClrUsed;\r
- if (ColourCount == 0 && BitmapInfo->bmiHeader.biBitCount <= 8)\r
- {\r
- ColourCount = 1 << BitmapInfo->bmiHeader.biBitCount;\r
- }\r
- HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);\r
- }\r
- Data = (PVOID)BitmapInfo + HeaderSize;\r
-\r
- PrivateInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, HeaderSize);\r
- if (PrivateInfo == NULL)\r
- {\r
- if (fuLoad & LR_LOADFROMFILE)\r
- {\r
- UnmapViewOfFile(BitmapInfo);\r
- }\r
- return(NULL);\r
- }\r
- memcpy(PrivateInfo, BitmapInfo, HeaderSize);\r
-\r
- /* FIXME: Handle colour conversion and transparency. */\r
-\r
- hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);\r
- if (hScreenDc == NULL)\r
- {\r
- if (fuLoad & LR_LOADFROMFILE)\r
- {\r
- UnmapViewOfFile(BitmapInfo);\r
- }\r
- return(NULL);\r
- }\r
-\r
- if (fuLoad & LR_CREATEDIBSECTION)\r
- {\r
- DIBSECTION Dib;\r
-\r
- hBitmap = CreateDIBSection(hScreenDc, PrivateInfo, DIB_RGB_COLORS, NULL, \r
- 0, 0);\r
- GetObjectA(hBitmap, sizeof(DIBSECTION), &Dib);\r
- SetDIBits(hScreenDc, hBitmap, 0, Dib.dsBm.bmHeight, Data, BitmapInfo,\r
- DIB_RGB_COLORS);\r
- }\r
- else\r
- {\r
- hBitmap = CreateDIBitmap(hScreenDc, &PrivateInfo->bmiHeader, CBM_INIT,\r
- Data, PrivateInfo, DIB_RGB_COLORS);\r
- }\r
-\r
- RtlFreeHeap(RtlGetProcessHeap(), 0, PrivateInfo);\r
- /*DeleteDC(hScreenDc);*/\r
- if (fuLoad & LR_LOADFROMFILE)\r
- {\r
- UnmapViewOfFile(BitmapInfo);\r
- }\r
- return(hBitmap);\r
-}\r
-\r
-HANDLE STDCALL\r
-LoadImageW(HINSTANCE hinst,\r
- LPCWSTR lpszName,\r
- UINT uType,\r
- int cxDesired,\r
- int cyDesired,\r
- UINT fuLoad)\r
-{ \r
- if (fuLoad & LR_DEFAULTSIZE)\r
- {\r
- if (uType == IMAGE_ICON)\r
- {\r
- if (cxDesired == 0)\r
- {\r
- cxDesired = GetSystemMetrics(SM_CXICON);\r
- }\r
- if (cyDesired == 0)\r
- {\r
- cyDesired = GetSystemMetrics(SM_CYICON);\r
- }\r
- }\r
- else if (uType == IMAGE_CURSOR)\r
- {\r
- if (cxDesired == 0)\r
- {\r
- cxDesired = GetSystemMetrics(SM_CXCURSOR);\r
- }\r
- if (cyDesired == 0)\r
- {\r
- cyDesired = GetSystemMetrics(SM_CYCURSOR);\r
- }\r
- }\r
- }\r
-\r
- switch (uType)\r
- {\r
- case IMAGE_BITMAP:\r
- {\r
- return(LoadBitmapImage(hinst, lpszName, fuLoad));\r
- }\r
- case IMAGE_CURSOR:\r
- {\r
- return(LoadCursorImage(hinst, lpszName, fuLoad));\r
- }\r
- case IMAGE_ICON:\r
- {\r
- return(LoadIconImage(hinst, lpszName, cxDesired, cyDesired, fuLoad));\r
- }\r
- default:\r
- DbgBreakPoint();\r
- break;\r
- }\r
- return(NULL);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-HBITMAP STDCALL\r
-LoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName)\r
-{\r
- return(LoadImageA(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0));\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-HBITMAP STDCALL\r
-LoadBitmapW(HINSTANCE hInstance, LPCWSTR lpBitmapName)\r
-{\r
- return(LoadImageW(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0));\r
-}\r
+/*
+ * ReactOS kernel
+ * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: bitmap.c,v 1.17 2003/10/06 18:49:49 navaraf Exp $
+ *
+ * PROJECT: ReactOS user32.dll
+ * FILE: lib/user32/windows/input.c
+ * PURPOSE: Input
+ * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * 09-05-2001 CSH Created
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <string.h>
+#include <windows.h>
+#include <user32.h>
+#include <debug.h>
+#include <stdlib.h>
+
+/*forward declerations... actualy in user32\windows\icon.c but usful here****/
+HICON ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot);
+CURSORICONDIRENTRY *CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors);
+CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors);
+
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+LoadImageA(HINSTANCE hinst,
+ LPCSTR lpszName,
+ UINT uType,
+ int cxDesired,
+ int cyDesired,
+ UINT fuLoad)
+{
+ LPWSTR lpszWName;
+ HANDLE Handle;
+ UNICODE_STRING NameString;
+
+ if (HIWORD(lpszName))
+ {
+ RtlCreateUnicodeStringFromAsciiz(&NameString, (LPSTR)lpszName);
+ lpszWName = NameString.Buffer;
+ Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
+ cyDesired, fuLoad);
+ RtlFreeUnicodeString(&NameString);
+ }
+ else
+ {
+ Handle = LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired,
+ cyDesired, fuLoad);
+ }
+ return(Handle);
+}
+
+
+HANDLE STATIC
+LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
+{
+ HANDLE hResource;
+ HANDLE h2Resource;
+ HANDLE hFile;
+ HANDLE hSection;
+ CURSORICONDIR* IconDIR;
+ HDC hScreenDc;
+ HANDLE hIcon;
+ ULONG HeaderSize;
+ ULONG ColourCount;
+ PVOID Data;
+ CURSORICONDIRENTRY* dirEntry;
+ ICONIMAGE* SafeIconImage;
+ GRPCURSORICONDIR* IconResDir;
+ INT id;
+ ICONIMAGE *ResIcon;
+
+ if (fuLoad & LR_SHARED)
+ DbgPrint("FIXME: need LR_SHARED support Loading cursor images\n");
+
+ if (!(fuLoad & LR_LOADFROMFILE))
+ {
+ if (hinst == NULL)
+ {
+ hinst = GetModuleHandleW(L"USER32");
+ }
+ hResource = FindResourceW(hinst, lpszName, RT_GROUP_CURSOR);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+
+ hResource = LoadResource(hinst, hResource);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+ IconResDir = LockResource(hResource);
+ if (IconResDir == NULL)
+ {
+ return(NULL);
+ }
+
+ //find the best fitting in the IconResDir for this resolution
+ id = LookupIconIdFromDirectoryEx((PBYTE) IconResDir, TRUE,
+ 32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
+
+ h2Resource = FindResourceW(hinst,
+ MAKEINTRESOURCEW(id),
+ MAKEINTRESOURCEW(RT_CURSOR));
+
+ hResource = LoadResource(hinst, h2Resource);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+
+ ResIcon = LockResource(hResource);
+ if (ResIcon == NULL)
+ {
+ return(NULL);
+ }
+ return CreateIconFromResourceEx((PBYTE) ResIcon,
+ SizeofResource(hinst, h2Resource), FALSE, 0x00030000,
+ 32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
+ }
+ else
+ {
+ hFile = CreateFileW(lpszName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (hFile == NULL)
+ {
+ return(NULL);
+ }
+
+ hSection = CreateFileMappingW(hFile,
+ NULL,
+ PAGE_READONLY,
+ 0,
+ 0,
+ NULL);
+
+ CloseHandle(hFile);
+ if (hSection == NULL)
+ {
+ return(NULL);
+ }
+ IconDIR = MapViewOfFile(hSection,
+ FILE_MAP_READ,
+ 0,
+ 0,
+ 0);
+
+ CloseHandle(hSection);
+ if (IconDIR == NULL)
+ {
+ return(NULL);
+ }
+
+ //pick the best size.
+ dirEntry = (CURSORICONDIRENTRY *) CURSORICON_FindBestIcon( IconDIR, 32, 32, 1);
+
+
+ if (!dirEntry)
+ {
+ if (fuLoad & LR_LOADFROMFILE)
+ {
+ UnmapViewOfFile(IconDIR);
+ }
+ return(NULL);
+ }
+
+ SafeIconImage = RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry->dwBytesInRes);
+
+ memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
+ }
+
+ //at this point we have a copy of the icon image to play with
+
+ SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;
+
+ if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
+ ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
+ HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
+ }
+ else
+ {
+ ColourCount = SafeIconImage->icHeader.biClrUsed;
+ if (ColourCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)
+ {
+ ColourCount = 1 << SafeIconImage->icHeader.biBitCount;
+ }
+ HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
+ }
+
+ //make data point to the start of the XOR image data
+ Data = (PBYTE)SafeIconImage + HeaderSize;
+
+
+ //get a handle to the screen dc, the icon we create is going to be compatable with this
+ hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
+ if (hScreenDc == NULL)
+ {
+ if (fuLoad & LR_LOADFROMFILE)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
+ UnmapViewOfFile(IconDIR);
+ }
+ return(NULL);
+ }
+
+ hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, 32, 32, dirEntry->Info.cursor.wXHotspot, dirEntry->Info.cursor.wYHotspot);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
+ return hIcon;
+}
+
+
+HANDLE STATIC
+LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuLoad)
+{
+ HANDLE hResource;
+ HANDLE h2Resource;
+ HANDLE hFile;
+ HANDLE hSection;
+ CURSORICONDIR* IconDIR;
+ HDC hScreenDc;
+ HANDLE hIcon;
+ ULONG HeaderSize;
+ ULONG ColourCount;
+ PVOID Data;
+ CURSORICONDIRENTRY* dirEntry;
+ ICONIMAGE* SafeIconImage;
+ GRPCURSORICONDIR* IconResDir;
+ INT id;
+ ICONIMAGE *ResIcon;
+
+ if (fuLoad & LR_SHARED)
+ DbgPrint("FIXME: need LR_SHARED support Loading icon images\n");
+
+ if (!(fuLoad & LR_LOADFROMFILE))
+ {
+ if (hinst == NULL)
+ {
+ hinst = GetModuleHandleW(L"USER32");
+ }
+ hResource = FindResourceW(hinst, lpszName, RT_GROUP_ICON);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+
+ hResource = LoadResource(hinst, hResource);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+ IconResDir = LockResource(hResource);
+ if (IconResDir == NULL)
+ {
+ return(NULL);
+ }
+
+ //find the best fitting in the IconResDir for this resolution
+ id = LookupIconIdFromDirectoryEx((PBYTE) IconResDir, TRUE,
+ width, height, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
+
+ h2Resource = FindResourceW(hinst,
+ MAKEINTRESOURCEW(id),
+ MAKEINTRESOURCEW(RT_ICON));
+
+ hResource = LoadResource(hinst, h2Resource);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+
+ ResIcon = LockResource(hResource);
+ if (ResIcon == NULL)
+ {
+ return(NULL);
+ }
+ return CreateIconFromResourceEx((PBYTE) ResIcon,
+ SizeofResource(hinst, h2Resource), TRUE, 0x00030000,
+ width, height, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
+ }
+ else
+ {
+ hFile = CreateFileW(lpszName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (hFile == NULL)
+ {
+ return(NULL);
+ }
+
+ hSection = CreateFileMappingW(hFile,
+ NULL,
+ PAGE_READONLY,
+ 0,
+ 0,
+ NULL);
+
+ CloseHandle(hFile);
+ if (hSection == NULL)
+ {
+ return(NULL);
+ }
+ IconDIR = MapViewOfFile(hSection,
+ FILE_MAP_READ,
+ 0,
+ 0,
+ 0);
+
+ CloseHandle(hSection);
+ if (IconDIR == NULL)
+ {
+ return(NULL);
+ }
+
+ //pick the best size.
+ dirEntry = (CURSORICONDIRENTRY *) CURSORICON_FindBestIcon( IconDIR, width, height, 1);
+
+
+ if (!dirEntry)
+ {
+ if (fuLoad & LR_LOADFROMFILE)
+ {
+ UnmapViewOfFile(IconDIR);
+ }
+ return(NULL);
+ }
+
+ SafeIconImage = RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry->dwBytesInRes);
+
+ memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
+ }
+
+ //at this point we have a copy of the icon image to play with
+
+ SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;
+
+ if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
+ ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
+ HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
+ }
+ else
+ {
+ ColourCount = SafeIconImage->icHeader.biClrUsed;
+ if (ColourCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)
+ {
+ ColourCount = 1 << SafeIconImage->icHeader.biBitCount;
+ }
+ HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
+ }
+
+ //make data point to the start of the XOR image data
+ Data = (PBYTE)SafeIconImage + HeaderSize;
+
+
+ //get a handle to the screen dc, the icon we create is going to be compatable with this
+ hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
+ if (hScreenDc == NULL)
+ {
+ if (fuLoad & LR_LOADFROMFILE)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
+ UnmapViewOfFile(IconDIR);
+ }
+ return(NULL);
+ }
+
+ hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
+ return hIcon;
+}
+
+
+HANDLE STATIC
+LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
+{
+ HANDLE hResource;
+ HANDLE hFile;
+ HANDLE hSection;
+ BITMAPINFO* BitmapInfo;
+ BITMAPINFO* PrivateInfo;
+ HDC hScreenDc;
+ HANDLE hBitmap;
+ ULONG HeaderSize;
+ ULONG ColourCount;
+ PVOID Data;
+
+ if (!(fuLoad & LR_LOADFROMFILE))
+ {
+ if (hInstance == NULL)
+ {
+ hInstance = GetModuleHandleW(L"USER32");
+ }
+ hResource = FindResourceW(hInstance, lpszName, RT_BITMAP);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+ hResource = LoadResource(hInstance, hResource);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+ BitmapInfo = LockResource(hResource);
+ if (BitmapInfo == NULL)
+ {
+ return(NULL);
+ }
+ }
+ else
+ {
+ hFile = CreateFileW(lpszName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (hFile == NULL)
+ {
+ return(NULL);
+ }
+ hSection = CreateFileMappingW(hFile,
+ NULL,
+ PAGE_READONLY,
+ 0,
+ 0,
+ NULL);
+ CloseHandle(hFile);
+ if (hSection == NULL)
+ {
+ return(NULL);
+ }
+ BitmapInfo = MapViewOfFile(hSection,
+ FILE_MAP_READ,
+ 0,
+ 0,
+ 0);
+ CloseHandle(hSection);
+ if (BitmapInfo == NULL)
+ {
+ return(NULL);
+ }
+ /* offset BitmapInfo by 14 bytes to acount for the size of BITMAPFILEHEADER
+ unfortunatly sizeof(BITMAPFILEHEADER) = 16, but the acutal size should be 14!
+ */
+ BitmapInfo = (BITMAPINFO*)(((PBYTE)BitmapInfo) + 14);
+ }
+
+ if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)BitmapInfo;
+ ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
+ HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
+ }
+ else
+ {
+ ColourCount = BitmapInfo->bmiHeader.biClrUsed;
+ if (ColourCount == 0 && BitmapInfo->bmiHeader.biBitCount <= 8)
+ {
+ ColourCount = 1 << BitmapInfo->bmiHeader.biBitCount;
+ }
+ HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
+ }
+ Data = (PVOID)BitmapInfo + HeaderSize;
+
+ PrivateInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, HeaderSize);
+ if (PrivateInfo == NULL)
+ {
+ if (fuLoad & LR_LOADFROMFILE)
+ {
+ UnmapViewOfFile(BitmapInfo);
+ }
+ return(NULL);
+ }
+ memcpy(PrivateInfo, BitmapInfo, HeaderSize);
+
+ /* FIXME: Handle colour conversion and transparency. */
+
+ hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
+ if (hScreenDc == NULL)
+ {
+ if (fuLoad & LR_LOADFROMFILE)
+ {
+ UnmapViewOfFile(BitmapInfo);
+ }
+ return(NULL);
+ }
+
+ if (fuLoad & LR_CREATEDIBSECTION)
+ {
+ DIBSECTION Dib;
+
+ hBitmap = CreateDIBSection(hScreenDc, PrivateInfo, DIB_RGB_COLORS, NULL,
+ 0, 0);
+ GetObjectA(hBitmap, sizeof(DIBSECTION), &Dib);
+ SetDIBits(hScreenDc, hBitmap, 0, Dib.dsBm.bmHeight, Data, BitmapInfo,
+ DIB_RGB_COLORS);
+ }
+ else
+ {
+ hBitmap = CreateDIBitmap(hScreenDc, &PrivateInfo->bmiHeader, CBM_INIT,
+ Data, PrivateInfo, DIB_RGB_COLORS);
+ }
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, PrivateInfo);
+ /*DeleteDC(hScreenDc);*/
+ if (fuLoad & LR_LOADFROMFILE)
+ {
+ UnmapViewOfFile(BitmapInfo);
+ }
+ return(hBitmap);
+}
+
+HANDLE STDCALL
+LoadImageW(HINSTANCE hinst,
+ LPCWSTR lpszName,
+ UINT uType,
+ int cxDesired,
+ int cyDesired,
+ UINT fuLoad)
+{
+ if (fuLoad & LR_DEFAULTSIZE)
+ {
+ if (uType == IMAGE_ICON)
+ {
+ if (cxDesired == 0)
+ {
+ cxDesired = GetSystemMetrics(SM_CXICON);
+ }
+ if (cyDesired == 0)
+ {
+ cyDesired = GetSystemMetrics(SM_CYICON);
+ }
+ }
+ else if (uType == IMAGE_CURSOR)
+ {
+ if (cxDesired == 0)
+ {
+ cxDesired = GetSystemMetrics(SM_CXCURSOR);
+ }
+ if (cyDesired == 0)
+ {
+ cyDesired = GetSystemMetrics(SM_CYCURSOR);
+ }
+ }
+ }
+
+ switch (uType)
+ {
+ case IMAGE_BITMAP:
+ {
+ return(LoadBitmapImage(hinst, lpszName, fuLoad));
+ }
+ case IMAGE_CURSOR:
+ {
+ return(LoadCursorImage(hinst, lpszName, fuLoad));
+ }
+ case IMAGE_ICON:
+ {
+ return(LoadIconImage(hinst, lpszName, cxDesired, cyDesired, fuLoad));
+ }
+ default:
+ DbgBreakPoint();
+ break;
+ }
+ return(NULL);
+}
+
+
+/*
+ * @implemented
+ */
+HBITMAP STDCALL
+LoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName)
+{
+ return(LoadImageA(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0));
+}
+
+
+/*
+ * @implemented
+ */
+HBITMAP STDCALL
+LoadBitmapW(HINSTANCE hInstance, LPCWSTR lpBitmapName)
+{
+ return(LoadImageW(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0));
+}
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/cm/rtlfunc.c\r
- * PURPOSE: Rtlxxx function for registry access\r
- * UPDATE HISTORY:\r
-*/\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include <ddk/ntddk.h>\r
-#include <roscfg.h>\r
-#include <internal/ob.h>\r
-#include <limits.h>\r
-#include <string.h>\r
-#include <internal/registry.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-#include "cm.h"\r
-\r
-\r
-/* FUNCTIONS ****************************************************************/\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-RtlCheckRegistryKey(IN ULONG RelativeTo,\r
- IN PWSTR Path)\r
-{\r
- HANDLE KeyHandle;\r
- NTSTATUS Status;\r
-\r
- Status = RtlpGetRegistryHandle(RelativeTo,\r
- Path,\r
- FALSE,\r
- &KeyHandle);\r
- if (!NT_SUCCESS(Status))\r
- return(Status);\r
-\r
- NtClose(KeyHandle);\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-RtlCreateRegistryKey(IN ULONG RelativeTo,\r
- IN PWSTR Path)\r
-{\r
- HANDLE KeyHandle;\r
- NTSTATUS Status;\r
-\r
- Status = RtlpGetRegistryHandle(RelativeTo,\r
- Path,\r
- TRUE,\r
- &KeyHandle);\r
- if (!NT_SUCCESS(Status))\r
- return(Status);\r
-\r
- NtClose(KeyHandle);\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-RtlDeleteRegistryValue(IN ULONG RelativeTo,\r
- IN PCWSTR Path,\r
- IN PCWSTR ValueName)\r
-{\r
- HANDLE KeyHandle;\r
- NTSTATUS Status;\r
- UNICODE_STRING Name;\r
-\r
- Status = RtlpGetRegistryHandle(RelativeTo,\r
- (PWSTR) Path,\r
- TRUE,\r
- &KeyHandle);\r
- if (!NT_SUCCESS(Status))\r
- return(Status);\r
-\r
- RtlInitUnicodeString(&Name,\r
- ValueName);\r
-\r
- NtDeleteValueKey(KeyHandle,\r
- &Name);\r
-\r
- NtClose(KeyHandle);\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-NTSTATUS STDCALL\r
-RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess,\r
- OUT PHANDLE KeyHandle)\r
-{\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- UNICODE_STRING KeyPath = UNICODE_STRING_INITIALIZER(L"\\Registry\\User\\.Default");\r
- NTSTATUS Status;\r
-\r
- Status = RtlFormatCurrentUserKeyPath(&KeyPath);\r
- if (NT_SUCCESS(Status))\r
- {\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &KeyPath,\r
- OBJ_CASE_INSENSITIVE,\r
- NULL,\r
- NULL);\r
- Status = NtOpenKey(KeyHandle,\r
- DesiredAccess,\r
- &ObjectAttributes);\r
- RtlFreeUnicodeString(&KeyPath);\r
- if (NT_SUCCESS(Status))\r
- return(STATUS_SUCCESS);\r
- }\r
-\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &KeyPath,\r
- OBJ_CASE_INSENSITIVE,\r
- NULL,\r
- NULL);\r
- Status = NtOpenKey(KeyHandle,\r
- DesiredAccess,\r
- &ObjectAttributes);\r
- return(Status);\r
-}\r
-\r
-\r
-/*\r
- * @unimplemented\r
- */\r
-NTSTATUS STDCALL\r
-RtlQueryRegistryValues(IN ULONG RelativeTo,\r
- IN PCWSTR Path,\r
- IN PRTL_QUERY_REGISTRY_TABLE QueryTable,\r
- IN PVOID Context,\r
- IN PVOID Environment)\r
-{\r
- NTSTATUS Status;\r
- HANDLE BaseKeyHandle;\r
- HANDLE CurrentKeyHandle;\r
- PRTL_QUERY_REGISTRY_TABLE QueryEntry;\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- UNICODE_STRING KeyName;\r
- PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;\r
- PKEY_VALUE_FULL_INFORMATION FullValueInfo;\r
- ULONG BufferSize;\r
- ULONG ResultSize;\r
- ULONG ValueNameSize;\r
- ULONG Index;\r
- ULONG StringLen;\r
- PWSTR StringPtr;\r
- PWSTR ValueName;\r
-\r
- DPRINT("RtlQueryRegistryValues() called\n");\r
-\r
- Status = RtlpGetRegistryHandle(RelativeTo,\r
- (PWSTR) Path,\r
- FALSE,\r
- &BaseKeyHandle);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT("RtlpGetRegistryHandle() failed with status %x\n", Status);\r
- return(Status);\r
- }\r
-\r
- CurrentKeyHandle = BaseKeyHandle;\r
- QueryEntry = QueryTable;\r
- while ((QueryEntry->QueryRoutine != NULL) ||\r
- (QueryEntry->Name != NULL))\r
- {\r
- if (((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_TOPKEY)) != 0) &&\r
- (BaseKeyHandle != CurrentKeyHandle))\r
- {\r
- NtClose(CurrentKeyHandle);\r
- CurrentKeyHandle = BaseKeyHandle;\r
- }\r
-\r
- if (QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY)\r
- {\r
- DPRINT("Open new subkey: %S\n", QueryEntry->Name);\r
-\r
- RtlInitUnicodeString(&KeyName,\r
- QueryEntry->Name);\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &KeyName,\r
- OBJ_CASE_INSENSITIVE,\r
- BaseKeyHandle,\r
- NULL);\r
- Status = NtOpenKey(&CurrentKeyHandle,\r
- KEY_ALL_ACCESS,\r
- &ObjectAttributes);\r
- if (!NT_SUCCESS(Status))\r
- break;\r
- }\r
- else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DIRECT)\r
- {\r
- DPRINT("Query value directly: %S\n", QueryEntry->Name);\r
-\r
- RtlInitUnicodeString(&KeyName,\r
- QueryEntry->Name);\r
-\r
- BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;\r
- ValueInfo = ExAllocatePool(PagedPool, BufferSize);\r
- if (ValueInfo == NULL)\r
- {\r
- Status = STATUS_NO_MEMORY;\r
- break;\r
- }\r
-\r
- Status = ZwQueryValueKey(CurrentKeyHandle,\r
- &KeyName,\r
- KeyValuePartialInformation,\r
- ValueInfo,\r
- BufferSize,\r
- &ResultSize);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- if (QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED)\r
- {\r
- ExFreePool(ValueInfo);\r
- Status = STATUS_OBJECT_NAME_NOT_FOUND;\r
- goto ByeBye;\r
- }\r
- \r
- if (QueryEntry->DefaultType == REG_SZ)\r
- {\r
- PUNICODE_STRING ValueString;\r
- PUNICODE_STRING SourceString;\r
-\r
- SourceString = (PUNICODE_STRING)QueryEntry->DefaultData;\r
- ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;\r
- if (ValueString->Buffer == 0)\r
- {\r
- ValueString->Length = SourceString->Length;\r
- ValueString->MaximumLength = SourceString->MaximumLength;\r
- ValueString->Buffer = ExAllocatePool(PagedPool,\r
- ValueString->MaximumLength);\r
- if (!ValueString->Buffer)\r
- break;\r
- ValueString->Buffer[0] = 0;\r
- memcpy(ValueString->Buffer,\r
- SourceString->Buffer,\r
- SourceString->MaximumLength);\r
- }\r
- else\r
- {\r
- ValueString->Length = RtlMin(SourceString->Length,\r
- ValueString->MaximumLength - sizeof(WCHAR));\r
- memcpy(ValueString->Buffer,\r
- SourceString->Buffer,\r
- ValueString->Length);\r
- ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;\r
- }\r
- }\r
- else\r
- {\r
- memcpy(QueryEntry->EntryContext,\r
- QueryEntry->DefaultData,\r
- QueryEntry->DefaultLength);\r
- }\r
- Status = STATUS_SUCCESS;\r
- }\r
- else\r
- {\r
- if (ValueInfo->Type == REG_SZ ||\r
- ValueInfo->Type == REG_MULTI_SZ ||\r
- ValueInfo->Type == REG_EXPAND_SZ)\r
- {\r
- PUNICODE_STRING ValueString;\r
-\r
- ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;\r
- if (ValueString->Buffer == 0)\r
- {\r
- RtlInitUnicodeString(ValueString,\r
- NULL);\r
- ValueString->MaximumLength = ValueInfo->DataLength;\r
- ValueString->Buffer = ExAllocatePool(PagedPool,\r
- ValueString->MaximumLength);\r
- if (!ValueString->Buffer)\r
- break;\r
- ValueString->Buffer[0] = 0;\r
- }\r
- ValueString->Length = RtlMin(ValueInfo->DataLength,\r
- ValueString->MaximumLength) - sizeof(WCHAR);\r
- memcpy(ValueString->Buffer,\r
- ValueInfo->Data,\r
- ValueString->Length);\r
- ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;\r
- }\r
- else\r
- {\r
- memcpy(QueryEntry->EntryContext,\r
- ValueInfo->Data,\r
- ValueInfo->DataLength);\r
- }\r
- }\r
-\r
- if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)\r
- {\r
- DPRINT("FIXME: Delete value: %S\n", QueryEntry->Name);\r
-\r
- }\r
-\r
- ExFreePool(ValueInfo);\r
- }\r
- else\r
- {\r
- DPRINT("Query value via query routine: %S\n", QueryEntry->Name);\r
-\r
- if (QueryEntry->Name != NULL)\r
- {\r
- DPRINT("Callback\n");\r
-\r
- RtlInitUnicodeString(&KeyName,\r
- QueryEntry->Name);\r
-\r
- BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;\r
- ValueInfo = ExAllocatePool(PagedPool,\r
- BufferSize);\r
- if (ValueInfo == NULL)\r
- {\r
- Status = STATUS_NO_MEMORY;\r
- break;\r
- }\r
-\r
- Status = NtQueryValueKey(CurrentKeyHandle,\r
- &KeyName,\r
- KeyValuePartialInformation,\r
- ValueInfo,\r
- BufferSize,\r
- &ResultSize);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- Status = QueryEntry->QueryRoutine(QueryEntry->Name,\r
- QueryEntry->DefaultType,\r
- QueryEntry->DefaultData,\r
- QueryEntry->DefaultLength,\r
- Context,\r
- QueryEntry->EntryContext);\r
- }\r
- else if ((ValueInfo->Type == REG_MULTI_SZ) &&\r
- !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))\r
- {\r
- DPRINT("Expand REG_MULTI_SZ type\n");\r
- StringPtr = (PWSTR)ValueInfo->Data;\r
- while (*StringPtr != 0)\r
- {\r
- StringLen = (wcslen(StringPtr) + 1) * sizeof(WCHAR);\r
- Status = QueryEntry->QueryRoutine(QueryEntry->Name,\r
- REG_SZ,\r
- (PVOID)StringPtr,\r
- StringLen,\r
- Context,\r
- QueryEntry->EntryContext);\r
- if(!NT_SUCCESS(Status))\r
- break;\r
- StringPtr = (PWSTR)((PUCHAR)StringPtr + StringLen);\r
- }\r
- }\r
- else\r
- {\r
- Status = QueryEntry->QueryRoutine(QueryEntry->Name,\r
- ValueInfo->Type,\r
- ValueInfo->Data,\r
- ValueInfo->DataLength,\r
- Context,\r
- QueryEntry->EntryContext);\r
- }\r
-\r
- if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)\r
- {\r
- DPRINT("FIXME: Delete value: %S\n", QueryEntry->Name);\r
-\r
- }\r
-\r
- ExFreePool(ValueInfo);\r
-\r
- if (!NT_SUCCESS(Status))\r
- break;\r
- }\r
- else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_NOVALUE)\r
- {\r
- DPRINT("Simple callback\n");\r
- Status = QueryEntry->QueryRoutine(NULL,\r
- REG_NONE,\r
- NULL,\r
- 0,\r
- Context,\r
- QueryEntry->EntryContext);\r
- if (!NT_SUCCESS(Status))\r
- break;\r
- }\r
- else\r
- {\r
- DPRINT("Enumerate values\n");\r
-\r
- BufferSize = sizeof(KEY_VALUE_FULL_INFORMATION) + 4096;\r
- FullValueInfo = ExAllocatePool(PagedPool,\r
- BufferSize);\r
- if (FullValueInfo == NULL)\r
- {\r
- Status = STATUS_NO_MEMORY;\r
- break;\r
- }\r
- ValueNameSize = 256 * sizeof(WCHAR);\r
- ValueName = ExAllocatePool(PagedPool,\r
- ValueNameSize);\r
- if (ValueName == NULL)\r
- {\r
- Status = STATUS_NO_MEMORY;\r
- break;\r
- }\r
- Index = 0;\r
- while (TRUE)\r
- {\r
- Status = NtEnumerateValueKey(CurrentKeyHandle,\r
- Index,\r
- KeyValueFullInformation,\r
- FullValueInfo,\r
- BufferSize,\r
- &ResultSize);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- if ((Status == STATUS_NO_MORE_ENTRIES) &&\r
- (Index == 0) &&\r
- (QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED))\r
- {\r
- Status = STATUS_OBJECT_NAME_NOT_FOUND;\r
- }\r
- else if (Status == STATUS_NO_MORE_ENTRIES)\r
- {\r
- Status = STATUS_SUCCESS;\r
- }\r
- break;\r
- }\r
-\r
- if (FullValueInfo->NameLength > ValueNameSize - sizeof(WCHAR))\r
- {\r
- /* Should not happen, because the name length is limited to 255 characters */\r
- ExFreePool(ValueName);\r
- ValueNameSize = FullValueInfo->NameLength + sizeof(WCHAR);\r
- ValueName = ExAllocatePool(PagedPool, ValueNameSize);\r
- if (ValueName == NULL)\r
- {\r
- Status = STATUS_NO_MEMORY;\r
- break;\r
- }\r
- }\r
-\r
- RtlCopyMemory(ValueName, \r
- FullValueInfo->Name,\r
- FullValueInfo->NameLength);\r
- ValueName[FullValueInfo->NameLength / sizeof(WCHAR)] = 0;\r
-\r
- if ((FullValueInfo->Type == REG_MULTI_SZ) &&\r
- !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))\r
- {\r
- DPRINT("Expand REG_MULTI_SZ type\n");\r
-\r
- StringPtr = (PWSTR)((PVOID)FullValueInfo + FullValueInfo->DataOffset);\r
- while (*StringPtr != 0)\r
- {\r
- StringLen = (wcslen(StringPtr) + 1) * sizeof(WCHAR);\r
- Status = QueryEntry->QueryRoutine(ValueName,\r
- REG_SZ,\r
- (PVOID)StringPtr,\r
- StringLen,\r
- Context,\r
- QueryEntry->EntryContext);\r
- if(!NT_SUCCESS(Status))\r
- break;\r
- StringPtr = (PWSTR)((PUCHAR)StringPtr + StringLen);\r
- }\r
- }\r
- else\r
- {\r
- Status = QueryEntry->QueryRoutine(ValueName,\r
- FullValueInfo->Type,\r
- (PVOID)FullValueInfo + FullValueInfo->DataOffset,\r
- FullValueInfo->DataLength,\r
- Context,\r
- QueryEntry->EntryContext);\r
- }\r
-\r
- if (!NT_SUCCESS(Status))\r
- break;\r
-\r
- /* FIXME: How will these be deleted? */\r
-\r
- Index++;\r
- }\r
-\r
- ExFreePool(FullValueInfo);\r
- ExFreePool(ValueName);\r
-\r
- if (!NT_SUCCESS(Status))\r
- break;\r
- }\r
- }\r
-\r
- QueryEntry++;\r
- }\r
-\r
-ByeBye:\r
-\r
- if (CurrentKeyHandle != BaseKeyHandle)\r
- NtClose(CurrentKeyHandle);\r
-\r
- NtClose(BaseKeyHandle);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-RtlWriteRegistryValue(IN ULONG RelativeTo,\r
- IN PCWSTR Path,\r
- IN PCWSTR ValueName,\r
- IN ULONG ValueType,\r
- IN PVOID ValueData,\r
- IN ULONG ValueLength)\r
-{\r
- HANDLE KeyHandle;\r
- NTSTATUS Status;\r
- UNICODE_STRING Name;\r
-\r
- Status = RtlpGetRegistryHandle(RelativeTo,\r
- (PWSTR) Path,\r
- TRUE,\r
- &KeyHandle);\r
- if (!NT_SUCCESS(Status))\r
- return(Status);\r
-\r
- RtlInitUnicodeString(&Name,\r
- ValueName);\r
-\r
- NtSetValueKey(KeyHandle,\r
- &Name,\r
- 0,\r
- ValueType,\r
- ValueData,\r
- ValueLength);\r
-\r
- NtClose(KeyHandle);\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-/*\r
- * @unimplemented\r
- */\r
-NTSTATUS STDCALL\r
-RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING KeyPath)\r
-{\r
- /* FIXME: !!! */\r
- RtlCreateUnicodeString(KeyPath,\r
- L"\\Registry\\User\\.Default");\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-/* ------------------------------------------ Private Implementation */\r
-\r
-\r
-NTSTATUS\r
-RtlpGetRegistryHandle(ULONG RelativeTo,\r
- PWSTR Path,\r
- BOOLEAN Create,\r
- PHANDLE KeyHandle)\r
-{\r
- UNICODE_STRING KeyName;\r
- WCHAR KeyBuffer[MAX_PATH];\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- NTSTATUS Status;\r
-\r
- if (RelativeTo & RTL_REGISTRY_HANDLE)\r
- {\r
- Status = NtDuplicateObject(NtCurrentProcess(),\r
- (HANDLE)Path,\r
- NtCurrentProcess(),\r
- KeyHandle,\r
- 0,\r
- FALSE,\r
- DUPLICATE_SAME_ACCESS);\r
- return(Status);\r
- }\r
-\r
- if (RelativeTo & RTL_REGISTRY_OPTIONAL)\r
- RelativeTo &= ~RTL_REGISTRY_OPTIONAL;\r
-\r
- if (RelativeTo >= RTL_REGISTRY_MAXIMUM)\r
- return STATUS_INVALID_PARAMETER;\r
-\r
- KeyName.Length = 0;\r
- KeyName.MaximumLength = MAX_PATH;\r
- KeyName.Buffer = KeyBuffer;\r
- KeyBuffer[0] = 0;\r
-\r
- switch (RelativeTo)\r
- {\r
- case RTL_REGISTRY_SERVICES:\r
- RtlAppendUnicodeToString(&KeyName,\r
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");\r
- break;\r
-\r
- case RTL_REGISTRY_CONTROL:\r
- RtlAppendUnicodeToString(&KeyName,\r
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\");\r
- break;\r
-\r
- case RTL_REGISTRY_WINDOWS_NT:\r
- RtlAppendUnicodeToString(&KeyName,\r
- L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\");\r
- break;\r
-\r
- case RTL_REGISTRY_DEVICEMAP:\r
- RtlAppendUnicodeToString(&KeyName,\r
- L"\\Registry\\Machine\\Hardware\\DeviceMap\\");\r
- break;\r
-\r
- case RTL_REGISTRY_USER:\r
- Status = RtlFormatCurrentUserKeyPath(&KeyName);\r
- if (!NT_SUCCESS(Status))\r
- return(Status);\r
- break;\r
-\r
- /* ReactOS specific */\r
- case RTL_REGISTRY_ENUM:\r
- RtlAppendUnicodeToString(&KeyName,\r
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");\r
- break;\r
- }\r
-\r
- if (Path[0] == L'\\' && RelativeTo != RTL_REGISTRY_ABSOLUTE)\r
- {\r
- Path++;\r
- }\r
- RtlAppendUnicodeToString(&KeyName,\r
- Path);\r
-\r
- DPRINT("KeyName '%wZ'\n", &KeyName);\r
-\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &KeyName,\r
- OBJ_CASE_INSENSITIVE | OBJ_OPENIF,\r
- NULL,\r
- NULL);\r
-\r
- if (Create == TRUE)\r
- {\r
- Status = NtCreateKey(KeyHandle,\r
- KEY_ALL_ACCESS,\r
- &ObjectAttributes,\r
- 0,\r
- NULL,\r
- 0,\r
- NULL);\r
- }\r
- else\r
- {\r
- Status = NtOpenKey(KeyHandle,\r
- KEY_ALL_ACCESS,\r
- &ObjectAttributes);\r
- }\r
-\r
- return(Status);\r
-}\r
-\r
-\r
-NTSTATUS\r
-RtlpCreateRegistryKeyPath(PWSTR Path)\r
-{\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- WCHAR KeyBuffer[MAX_PATH];\r
- UNICODE_STRING KeyName;\r
- HANDLE KeyHandle;\r
- NTSTATUS Status;\r
- PWCHAR Current;\r
- PWCHAR Next;\r
-\r
- if (_wcsnicmp(Path, L"\\Registry\\", 10) != 0)\r
- {\r
- return STATUS_INVALID_PARAMETER;\r
- }\r
-\r
- wcsncpy (KeyBuffer, Path, MAX_PATH-1);\r
- RtlInitUnicodeString (&KeyName, KeyBuffer);\r
-\r
- /* Skip \\Registry\\ */\r
- Current = KeyName.Buffer;\r
- Current = wcschr (Current, '\\') + 1;\r
- Current = wcschr (Current, '\\') + 1;\r
-\r
- do\r
- {\r
- Next = wcschr (Current, '\\');\r
- if (Next == NULL)\r
- {\r
- /* The end */\r
- }\r
- else\r
- {\r
- *Next = 0;\r
- }\r
-\r
- InitializeObjectAttributes (&ObjectAttributes,\r
- &KeyName,\r
- OBJ_CASE_INSENSITIVE,\r
- NULL,\r
- NULL);\r
-\r
- DPRINT("Create '%S'\n", KeyName.Buffer);\r
-\r
- Status = NtCreateKey (&KeyHandle,\r
- KEY_ALL_ACCESS,\r
- &ObjectAttributes,\r
- 0,\r
- NULL,\r
- 0,\r
- NULL);\r
- if (!NT_SUCCESS (Status))\r
- {\r
- DPRINT ("NtCreateKey() failed with status %x\n", Status);\r
- return Status;\r
- }\r
-\r
- NtClose (KeyHandle);\r
-\r
- if (Next != NULL)\r
- {\r
- *Next = L'\\';\r
- }\r
-\r
- Current = Next + 1;\r
- }\r
- while (Next != NULL);\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-/* EOF */\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/cm/rtlfunc.c
+ * PURPOSE: Rtlxxx function for registry access
+ * UPDATE HISTORY:
+*/
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <roscfg.h>
+#include <internal/ob.h>
+#include <limits.h>
+#include <string.h>
+#include <internal/registry.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+#include "cm.h"
+
+
+/* FUNCTIONS ****************************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+RtlCheckRegistryKey(IN ULONG RelativeTo,
+ IN PWSTR Path)
+{
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ Path,
+ FALSE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+
+ NtClose(KeyHandle);
+
+ return(STATUS_SUCCESS);
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+RtlCreateRegistryKey(IN ULONG RelativeTo,
+ IN PWSTR Path)
+{
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ Path,
+ TRUE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+
+ NtClose(KeyHandle);
+
+ return(STATUS_SUCCESS);
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+RtlDeleteRegistryValue(IN ULONG RelativeTo,
+ IN PCWSTR Path,
+ IN PCWSTR ValueName)
+{
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ UNICODE_STRING Name;
+
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ (PWSTR) Path,
+ TRUE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+
+ RtlInitUnicodeString(&Name,
+ ValueName);
+
+ NtDeleteValueKey(KeyHandle,
+ &Name);
+
+ NtClose(KeyHandle);
+
+ return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS STDCALL
+RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyPath = UNICODE_STRING_INITIALIZER(L"\\Registry\\User\\.Default");
+ NTSTATUS Status;
+
+ Status = RtlFormatCurrentUserKeyPath(&KeyPath);
+ if (NT_SUCCESS(Status))
+ {
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyPath,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenKey(KeyHandle,
+ DesiredAccess,
+ &ObjectAttributes);
+ RtlFreeUnicodeString(&KeyPath);
+ if (NT_SUCCESS(Status))
+ return(STATUS_SUCCESS);
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyPath,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenKey(KeyHandle,
+ DesiredAccess,
+ &ObjectAttributes);
+ return(Status);
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+RtlQueryRegistryValues(IN ULONG RelativeTo,
+ IN PCWSTR Path,
+ IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
+ IN PVOID Context,
+ IN PVOID Environment)
+{
+ NTSTATUS Status;
+ HANDLE BaseKeyHandle;
+ HANDLE CurrentKeyHandle;
+ PRTL_QUERY_REGISTRY_TABLE QueryEntry;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyName;
+ PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
+ PKEY_VALUE_FULL_INFORMATION FullValueInfo;
+ ULONG BufferSize;
+ ULONG ResultSize;
+ ULONG ValueNameSize;
+ ULONG Index;
+ ULONG StringLen;
+ PWSTR StringPtr;
+ PWSTR ValueName;
+
+ DPRINT("RtlQueryRegistryValues() called\n");
+
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ (PWSTR) Path,
+ FALSE,
+ &BaseKeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlpGetRegistryHandle() failed with status %x\n", Status);
+ return(Status);
+ }
+
+ CurrentKeyHandle = BaseKeyHandle;
+ QueryEntry = QueryTable;
+ while ((QueryEntry->QueryRoutine != NULL) ||
+ (QueryEntry->Name != NULL))
+ {
+ if (((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_TOPKEY)) != 0) &&
+ (BaseKeyHandle != CurrentKeyHandle))
+ {
+ NtClose(CurrentKeyHandle);
+ CurrentKeyHandle = BaseKeyHandle;
+ }
+
+ if (QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY)
+ {
+ DPRINT("Open new subkey: %S\n", QueryEntry->Name);
+
+ RtlInitUnicodeString(&KeyName,
+ QueryEntry->Name);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ BaseKeyHandle,
+ NULL);
+ Status = NtOpenKey(&CurrentKeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ break;
+ }
+ else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DIRECT)
+ {
+ DPRINT("Query value directly: %S\n", QueryEntry->Name);
+
+ RtlInitUnicodeString(&KeyName,
+ QueryEntry->Name);
+
+ BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;
+ ValueInfo = ExAllocatePool(PagedPool, BufferSize);
+ if (ValueInfo == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+
+ Status = ZwQueryValueKey(CurrentKeyHandle,
+ &KeyName,
+ KeyValuePartialInformation,
+ ValueInfo,
+ BufferSize,
+ &ResultSize);
+ if (!NT_SUCCESS(Status))
+ {
+ if (QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED)
+ {
+ ExFreePool(ValueInfo);
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ goto ByeBye;
+ }
+
+ if (QueryEntry->DefaultType == REG_SZ)
+ {
+ PUNICODE_STRING ValueString;
+ PUNICODE_STRING SourceString;
+
+ SourceString = (PUNICODE_STRING)QueryEntry->DefaultData;
+ ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
+ if (ValueString->Buffer == 0)
+ {
+ ValueString->Length = SourceString->Length;
+ ValueString->MaximumLength = SourceString->MaximumLength;
+ ValueString->Buffer = ExAllocatePool(PagedPool,
+ ValueString->MaximumLength);
+ if (!ValueString->Buffer)
+ break;
+ ValueString->Buffer[0] = 0;
+ memcpy(ValueString->Buffer,
+ SourceString->Buffer,
+ SourceString->MaximumLength);
+ }
+ else
+ {
+ ValueString->Length = RtlMin(SourceString->Length,
+ ValueString->MaximumLength - sizeof(WCHAR));
+ memcpy(ValueString->Buffer,
+ SourceString->Buffer,
+ ValueString->Length);
+ ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
+ }
+ }
+ else
+ {
+ memcpy(QueryEntry->EntryContext,
+ QueryEntry->DefaultData,
+ QueryEntry->DefaultLength);
+ }
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ if (ValueInfo->Type == REG_SZ ||
+ ValueInfo->Type == REG_MULTI_SZ ||
+ ValueInfo->Type == REG_EXPAND_SZ)
+ {
+ PUNICODE_STRING ValueString;
+
+ ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
+ if (ValueString->Buffer == 0)
+ {
+ RtlInitUnicodeString(ValueString,
+ NULL);
+ ValueString->MaximumLength = ValueInfo->DataLength;
+ ValueString->Buffer = ExAllocatePool(PagedPool,
+ ValueString->MaximumLength);
+ if (!ValueString->Buffer)
+ break;
+ ValueString->Buffer[0] = 0;
+ }
+ ValueString->Length = RtlMin(ValueInfo->DataLength,
+ ValueString->MaximumLength) - sizeof(WCHAR);
+ memcpy(ValueString->Buffer,
+ ValueInfo->Data,
+ ValueString->Length);
+ ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
+ }
+ else
+ {
+ memcpy(QueryEntry->EntryContext,
+ ValueInfo->Data,
+ ValueInfo->DataLength);
+ }
+ }
+
+ if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
+ {
+ DPRINT("FIXME: Delete value: %S\n", QueryEntry->Name);
+
+ }
+
+ ExFreePool(ValueInfo);
+ }
+ else
+ {
+ DPRINT("Query value via query routine: %S\n", QueryEntry->Name);
+
+ if (QueryEntry->Name != NULL)
+ {
+ DPRINT("Callback\n");
+
+ RtlInitUnicodeString(&KeyName,
+ QueryEntry->Name);
+
+ BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;
+ ValueInfo = ExAllocatePool(PagedPool,
+ BufferSize);
+ if (ValueInfo == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+
+ Status = NtQueryValueKey(CurrentKeyHandle,
+ &KeyName,
+ KeyValuePartialInformation,
+ ValueInfo,
+ BufferSize,
+ &ResultSize);
+ if (!NT_SUCCESS(Status))
+ {
+ Status = QueryEntry->QueryRoutine(QueryEntry->Name,
+ QueryEntry->DefaultType,
+ QueryEntry->DefaultData,
+ QueryEntry->DefaultLength,
+ Context,
+ QueryEntry->EntryContext);
+ }
+ else if ((ValueInfo->Type == REG_MULTI_SZ) &&
+ !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
+ {
+ DPRINT("Expand REG_MULTI_SZ type\n");
+ StringPtr = (PWSTR)ValueInfo->Data;
+ while (*StringPtr != 0)
+ {
+ StringLen = (wcslen(StringPtr) + 1) * sizeof(WCHAR);
+ Status = QueryEntry->QueryRoutine(QueryEntry->Name,
+ REG_SZ,
+ (PVOID)StringPtr,
+ StringLen,
+ Context,
+ QueryEntry->EntryContext);
+ if(!NT_SUCCESS(Status))
+ break;
+ StringPtr = (PWSTR)((PUCHAR)StringPtr + StringLen);
+ }
+ }
+ else
+ {
+ Status = QueryEntry->QueryRoutine(QueryEntry->Name,
+ ValueInfo->Type,
+ ValueInfo->Data,
+ ValueInfo->DataLength,
+ Context,
+ QueryEntry->EntryContext);
+ }
+
+ if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
+ {
+ DPRINT("FIXME: Delete value: %S\n", QueryEntry->Name);
+
+ }
+
+ ExFreePool(ValueInfo);
+
+ if (!NT_SUCCESS(Status))
+ break;
+ }
+ else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_NOVALUE)
+ {
+ DPRINT("Simple callback\n");
+ Status = QueryEntry->QueryRoutine(NULL,
+ REG_NONE,
+ NULL,
+ 0,
+ Context,
+ QueryEntry->EntryContext);
+ if (!NT_SUCCESS(Status))
+ break;
+ }
+ else
+ {
+ DPRINT("Enumerate values\n");
+
+ BufferSize = sizeof(KEY_VALUE_FULL_INFORMATION) + 4096;
+ FullValueInfo = ExAllocatePool(PagedPool,
+ BufferSize);
+ if (FullValueInfo == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+ ValueNameSize = 256 * sizeof(WCHAR);
+ ValueName = ExAllocatePool(PagedPool,
+ ValueNameSize);
+ if (ValueName == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+ Index = 0;
+ while (TRUE)
+ {
+ Status = NtEnumerateValueKey(CurrentKeyHandle,
+ Index,
+ KeyValueFullInformation,
+ FullValueInfo,
+ BufferSize,
+ &ResultSize);
+ if (!NT_SUCCESS(Status))
+ {
+ if ((Status == STATUS_NO_MORE_ENTRIES) &&
+ (Index == 0) &&
+ (QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED))
+ {
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ else if (Status == STATUS_NO_MORE_ENTRIES)
+ {
+ Status = STATUS_SUCCESS;
+ }
+ break;
+ }
+
+ if (FullValueInfo->NameLength > ValueNameSize - sizeof(WCHAR))
+ {
+ /* Should not happen, because the name length is limited to 255 characters */
+ ExFreePool(ValueName);
+ ValueNameSize = FullValueInfo->NameLength + sizeof(WCHAR);
+ ValueName = ExAllocatePool(PagedPool, ValueNameSize);
+ if (ValueName == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+ }
+
+ RtlCopyMemory(ValueName,
+ FullValueInfo->Name,
+ FullValueInfo->NameLength);
+ ValueName[FullValueInfo->NameLength / sizeof(WCHAR)] = 0;
+
+ if ((FullValueInfo->Type == REG_MULTI_SZ) &&
+ !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
+ {
+ DPRINT("Expand REG_MULTI_SZ type\n");
+
+ StringPtr = (PWSTR)((PVOID)FullValueInfo + FullValueInfo->DataOffset);
+ while (*StringPtr != 0)
+ {
+ StringLen = (wcslen(StringPtr) + 1) * sizeof(WCHAR);
+ Status = QueryEntry->QueryRoutine(ValueName,
+ REG_SZ,
+ (PVOID)StringPtr,
+ StringLen,
+ Context,
+ QueryEntry->EntryContext);
+ if(!NT_SUCCESS(Status))
+ break;
+ StringPtr = (PWSTR)((PUCHAR)StringPtr + StringLen);
+ }
+ }
+ else
+ {
+ Status = QueryEntry->QueryRoutine(ValueName,
+ FullValueInfo->Type,
+ (PVOID)FullValueInfo + FullValueInfo->DataOffset,
+ FullValueInfo->DataLength,
+ Context,
+ QueryEntry->EntryContext);
+ }
+
+ if (!NT_SUCCESS(Status))
+ break;
+
+ /* FIXME: How will these be deleted? */
+
+ Index++;
+ }
+
+ ExFreePool(FullValueInfo);
+ ExFreePool(ValueName);
+
+ if (!NT_SUCCESS(Status))
+ break;
+ }
+ }
+
+ QueryEntry++;
+ }
+
+ByeBye:
+
+ if (CurrentKeyHandle != BaseKeyHandle)
+ NtClose(CurrentKeyHandle);
+
+ NtClose(BaseKeyHandle);
+
+ return Status;
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+RtlWriteRegistryValue(IN ULONG RelativeTo,
+ IN PCWSTR Path,
+ IN PCWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength)
+{
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ UNICODE_STRING Name;
+
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ (PWSTR) Path,
+ TRUE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+
+ RtlInitUnicodeString(&Name,
+ ValueName);
+
+ NtSetValueKey(KeyHandle,
+ &Name,
+ 0,
+ ValueType,
+ ValueData,
+ ValueLength);
+
+ NtClose(KeyHandle);
+
+ return(STATUS_SUCCESS);
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING KeyPath)
+{
+ /* FIXME: !!! */
+ RtlCreateUnicodeString(KeyPath,
+ L"\\Registry\\User\\.Default");
+
+ return(STATUS_SUCCESS);
+}
+
+/* ------------------------------------------ Private Implementation */
+
+
+NTSTATUS
+RtlpGetRegistryHandle(ULONG RelativeTo,
+ PWSTR Path,
+ BOOLEAN Create,
+ PHANDLE KeyHandle)
+{
+ UNICODE_STRING KeyName;
+ WCHAR KeyBuffer[MAX_PATH];
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+
+ if (RelativeTo & RTL_REGISTRY_HANDLE)
+ {
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ (HANDLE)Path,
+ NtCurrentProcess(),
+ KeyHandle,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ return(Status);
+ }
+
+ if (RelativeTo & RTL_REGISTRY_OPTIONAL)
+ RelativeTo &= ~RTL_REGISTRY_OPTIONAL;
+
+ if (RelativeTo >= RTL_REGISTRY_MAXIMUM)
+ return STATUS_INVALID_PARAMETER;
+
+ KeyName.Length = 0;
+ KeyName.MaximumLength = MAX_PATH;
+ KeyName.Buffer = KeyBuffer;
+ KeyBuffer[0] = 0;
+
+ switch (RelativeTo)
+ {
+ case RTL_REGISTRY_SERVICES:
+ RtlAppendUnicodeToString(&KeyName,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+ break;
+
+ case RTL_REGISTRY_CONTROL:
+ RtlAppendUnicodeToString(&KeyName,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\");
+ break;
+
+ case RTL_REGISTRY_WINDOWS_NT:
+ RtlAppendUnicodeToString(&KeyName,
+ L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\");
+ break;
+
+ case RTL_REGISTRY_DEVICEMAP:
+ RtlAppendUnicodeToString(&KeyName,
+ L"\\Registry\\Machine\\Hardware\\DeviceMap\\");
+ break;
+
+ case RTL_REGISTRY_USER:
+ Status = RtlFormatCurrentUserKeyPath(&KeyName);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+ break;
+
+ /* ReactOS specific */
+ case RTL_REGISTRY_ENUM:
+ RtlAppendUnicodeToString(&KeyName,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
+ break;
+ }
+
+ if (Path[0] == L'\\' && RelativeTo != RTL_REGISTRY_ABSOLUTE)
+ {
+ Path++;
+ }
+ RtlAppendUnicodeToString(&KeyName,
+ Path);
+
+ DPRINT("KeyName '%wZ'\n", &KeyName);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ NULL,
+ NULL);
+
+ if (Create == TRUE)
+ {
+ Status = NtCreateKey(KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ }
+ else
+ {
+ Status = NtOpenKey(KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes);
+ }
+
+ return(Status);
+}
+
+
+NTSTATUS
+RtlpCreateRegistryKeyPath(PWSTR Path)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ WCHAR KeyBuffer[MAX_PATH];
+ UNICODE_STRING KeyName;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ PWCHAR Current;
+ PWCHAR Next;
+
+ if (_wcsnicmp(Path, L"\\Registry\\", 10) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ wcsncpy (KeyBuffer, Path, MAX_PATH-1);
+ RtlInitUnicodeString (&KeyName, KeyBuffer);
+
+ /* Skip \\Registry\\ */
+ Current = KeyName.Buffer;
+ Current = wcschr (Current, '\\') + 1;
+ Current = wcschr (Current, '\\') + 1;
+
+ do
+ {
+ Next = wcschr (Current, '\\');
+ if (Next == NULL)
+ {
+ /* The end */
+ }
+ else
+ {
+ *Next = 0;
+ }
+
+ InitializeObjectAttributes (&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ DPRINT("Create '%S'\n", KeyName.Buffer);
+
+ Status = NtCreateKey (&KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT ("NtCreateKey() failed with status %x\n", Status);
+ return Status;
+ }
+
+ NtClose (KeyHandle);
+
+ if (Next != NULL)
+ {
+ *Next = L'\\';
+ }
+
+ Current = Next + 1;
+ }
+ while (Next != NULL);
+
+ return STATUS_SUCCESS;
+}
+
+/* EOF */
-/* $Id: driver.c,v 1.20 2003/10/06 18:24:54 navaraf Exp $\r
- *\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/io/driver.c\r
- * PURPOSE: Manage devices\r
- * PROGRAMMER: David Welch (welch@cwcom.net)\r
- * UPDATE HISTORY:\r
- * 15/05/98: Created\r
- */\r
-\r
-/* INCLUDES ****************************************************************/\r
-\r
-#include <limits.h>\r
-#include <ddk/ntddk.h>\r
-#include <internal/io.h>\r
-#include <internal/po.h>\r
-#include <internal/ldr.h>\r
-#include <internal/id.h>\r
-#include <internal/pool.h>\r
-#include <internal/registry.h>\r
-\r
-#include <roscfg.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-\r
-typedef struct _SERVICE_GROUP\r
-{\r
- LIST_ENTRY GroupListEntry;\r
- UNICODE_STRING GroupName;\r
-\r
- BOOLEAN ServicesRunning;\r
-\r
-} SERVICE_GROUP, *PSERVICE_GROUP;\r
-\r
-\r
-typedef struct _SERVICE\r
-{\r
- LIST_ENTRY ServiceListEntry;\r
- UNICODE_STRING ServiceName;\r
- UNICODE_STRING RegistryPath;\r
- UNICODE_STRING ServiceGroup;\r
- UNICODE_STRING ImagePath;\r
-\r
- ULONG Start;\r
- ULONG Type;\r
- ULONG ErrorControl;\r
- ULONG Tag;\r
-\r
- BOOLEAN ServiceRunning; // needed ??\r
-\r
-} SERVICE, *PSERVICE;\r
-\r
-\r
-/* GLOBALS *******************************************************************/\r
-\r
-static LIST_ENTRY GroupListHead = {NULL, NULL};\r
-static LIST_ENTRY ServiceListHead = {NULL, NULL};\r
-\r
-POBJECT_TYPE EXPORTED IoDriverObjectType = NULL;\r
-\r
-#define TAG_DRIVER TAG('D', 'R', 'V', 'R')\r
-#define TAG_DRIVER_EXTENSION TAG('D', 'R', 'V', 'E')\r
-\r
-\r
-/* FUNCTIONS ***************************************************************/\r
-\r
-NTSTATUS STDCALL\r
-IopCreateDriver(PVOID ObjectBody,\r
- PVOID Parent,\r
- PWSTR RemainingPath,\r
- POBJECT_ATTRIBUTES ObjectAttributes)\r
-{\r
- DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n",\r
- ObjectBody,\r
- Parent,\r
- RemainingPath);\r
- if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-VOID\r
-IopInitDriverImplementation(VOID)\r
-{\r
- /* Register the process object type */\r
- IoDriverObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));\r
- IoDriverObjectType->Tag = TAG('D', 'R', 'V', 'R');\r
- IoDriverObjectType->TotalObjects = 0;\r
- IoDriverObjectType->TotalHandles = 0;\r
- IoDriverObjectType->MaxObjects = ULONG_MAX;\r
- IoDriverObjectType->MaxHandles = ULONG_MAX;\r
- IoDriverObjectType->PagedPoolCharge = 0;\r
- IoDriverObjectType->NonpagedPoolCharge = sizeof(DRIVER_OBJECT);\r
- IoDriverObjectType->Dump = NULL;\r
- IoDriverObjectType->Open = NULL;\r
- IoDriverObjectType->Close = NULL;\r
- IoDriverObjectType->Delete = NULL;\r
- IoDriverObjectType->Parse = NULL;\r
- IoDriverObjectType->Security = NULL;\r
- IoDriverObjectType->QueryName = NULL;\r
- IoDriverObjectType->OkayToClose = NULL;\r
- IoDriverObjectType->Create = IopCreateDriver;\r
- IoDriverObjectType->DuplicationNotify = NULL;\r
- RtlInitUnicodeStringFromLiteral(&IoDriverObjectType->TypeName, L"Driver");\r
-}\r
-\r
-/**********************************************************************\r
- * NAME EXPORTED\r
- * NtLoadDriver\r
- *\r
- * DESCRIPTION\r
- * Loads a device driver.\r
- * \r
- * ARGUMENTS\r
- * DriverServiceName\r
- * Name of the service to load (registry key).\r
- * \r
- * RETURN VALUE\r
- * Status.\r
- *\r
- * REVISIONS\r
- */\r
-NTSTATUS STDCALL\r
-NtLoadDriver(IN PUNICODE_STRING DriverServiceName)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[3];\r
- WCHAR FullImagePathBuffer[MAX_PATH];\r
- UNICODE_STRING ImagePath;\r
- UNICODE_STRING FullImagePath;\r
- NTSTATUS Status;\r
- ULONG Type;\r
- PDEVICE_NODE DeviceNode;\r
- PMODULE_OBJECT ModuleObject;\r
- LPWSTR Start;\r
-\r
- DPRINT("NtLoadDriver(%wZ) called\n", DriverServiceName);\r
-\r
- RtlInitUnicodeString(&ImagePath, NULL);\r
-\r
- /* Get service data */\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].Name = L"Type";\r
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;\r
- QueryTable[0].EntryContext = &Type;\r
-\r
- QueryTable[1].Name = L"ImagePath";\r
- QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
- QueryTable[1].EntryContext = &ImagePath;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,\r
- DriverServiceName->Buffer,\r
- QueryTable,\r
- NULL,\r
- NULL);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);\r
- RtlFreeUnicodeString(&ImagePath);\r
- return(Status);\r
- }\r
-\r
- if (ImagePath.Length == 0)\r
- {\r
- wcscpy(FullImagePathBuffer, L"\\SystemRoot\\system32\\drivers");\r
- wcscat(FullImagePathBuffer, wcsrchr(DriverServiceName->Buffer, L'\\'));\r
- wcscat(FullImagePathBuffer, L".sys");\r
- }\r
- else if (ImagePath.Buffer[0] != L'\\')\r
- {\r
- wcscpy(FullImagePathBuffer, L"\\SystemRoot\\");\r
- wcscat(FullImagePathBuffer, ImagePath.Buffer);\r
- }\r
- else\r
- {\r
- wcscpy(FullImagePathBuffer, ImagePath.Buffer);\r
- }\r
-\r
- RtlFreeUnicodeString(&ImagePath);\r
- RtlInitUnicodeString(&FullImagePath, FullImagePathBuffer);\r
-\r
- DPRINT("FullImagePath: '%S'\n", FullImagePathBuffer);\r
- DPRINT("Type %lx\n", Type);\r
-\r
- /* Use IopRootDeviceNode for now */\r
- Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);\r
- return(Status);\r
- }\r
-\r
- ModuleObject = LdrGetModuleObject(DriverServiceName);\r
- if (ModuleObject != NULL)\r
- {\r
- return(STATUS_IMAGE_ALREADY_LOADED);\r
- }\r
-\r
- Status = LdrLoadModule(&FullImagePath, &ModuleObject);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("LdrLoadModule() failed (Status %lx)\n", Status);\r
- IopFreeDeviceNode(DeviceNode);\r
- return(Status);\r
- }\r
-\r
- /* Set a service name for the device node */\r
- Start = wcsrchr(DriverServiceName->Buffer, L'\\');\r
- if (Start == NULL)\r
- Start = DriverServiceName->Buffer;\r
- else\r
- Start++;\r
- RtlCreateUnicodeString(&DeviceNode->ServiceName, Start);\r
-\r
- Status = IopInitializeDriver(ModuleObject->EntryPoint,\r
- DeviceNode,\r
- (Type == 2 || Type == 8),\r
- ModuleObject->Base,\r
- ModuleObject->Length,\r
- FALSE);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status);\r
- LdrUnloadModule(ModuleObject);\r
- IopFreeDeviceNode(DeviceNode);\r
- }\r
-\r
- return(Status);\r
-}\r
-\r
-\r
-NTSTATUS STDCALL\r
-NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- WCHAR FullImagePathBuffer[MAX_PATH];\r
- UNICODE_STRING ImagePath;\r
- UNICODE_STRING FullImagePath;\r
- UNICODE_STRING ObjectName;\r
- PDRIVER_OBJECT DriverObject;\r
- NTSTATUS Status;\r
- PMODULE_OBJECT ModuleObject;\r
- LPWSTR Start;\r
-\r
- DPRINT("DriverServiceName: '%wZ'\n", DriverServiceName);\r
-\r
- /* Get the service name from the module name */\r
- Start = wcsrchr(DriverServiceName->Buffer, L'\\');\r
- if (Start == NULL)\r
- Start = DriverServiceName->Buffer;\r
- else\r
- Start++;\r
-\r
- ObjectName.Length = wcslen(Start) + 8;\r
- ObjectName.Buffer = ExAllocatePool(NonPagedPool,\r
- ObjectName.Length * sizeof(WCHAR));\r
- wcscpy(ObjectName.Buffer, L"\\Driver\\");\r
- memcpy(ObjectName.Buffer + 8, Start, (ObjectName.Length - 8) * sizeof(WCHAR));\r
-\r
- /* Find the driver object */\r
- Status = ObReferenceObjectByName(&ObjectName, 0, 0, 0, IoDriverObjectType,\r
- KernelMode, 0, (PVOID*)&DriverObject);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT("Can't locate driver object for %wZ\n", ObjectName);\r
- return Status;\r
- }\r
- ObDereferenceObject(DriverObject);\r
-\r
- RtlInitUnicodeString(&ImagePath, NULL);\r
-\r
- /* Get service data */\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].Name = L"ImagePath";\r
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
- QueryTable[0].EntryContext = &ImagePath;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,\r
- DriverServiceName->Buffer,\r
- QueryTable,\r
- NULL,\r
- NULL);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);\r
- RtlFreeUnicodeString(&ImagePath);\r
- return(Status);\r
- }\r
-\r
- if (ImagePath.Length == 0)\r
- {\r
- wcscpy(FullImagePathBuffer, L"\\SystemRoot\\system32\\drivers");\r
- wcscat(FullImagePathBuffer, wcsrchr(DriverServiceName->Buffer, L'\\'));\r
- wcscat(FullImagePathBuffer, L".sys");\r
- }\r
- else if (ImagePath.Buffer[0] != L'\\')\r
- {\r
- wcscpy(FullImagePathBuffer, L"\\SystemRoot\\");\r
- wcscat(FullImagePathBuffer, ImagePath.Buffer);\r
- }\r
- else\r
- {\r
- wcscpy(FullImagePathBuffer, ImagePath.Buffer);\r
- }\r
-\r
- RtlFreeUnicodeString(&ImagePath);\r
- RtlInitUnicodeString(&FullImagePath, FullImagePathBuffer);\r
-\r
- ModuleObject = LdrGetModuleObject(DriverServiceName);\r
- if (ModuleObject == NULL)\r
- {\r
- return STATUS_UNSUCCESSFUL;\r
- }\r
-\r
- /* Unload the module and release the references to the device object */\r
-\r
- if (DriverObject->DriverUnload)\r
- (*DriverObject->DriverUnload)(DriverObject);\r
- ObDereferenceObject(DriverObject);\r
- ObDereferenceObject(DriverObject);\r
- LdrUnloadModule(ModuleObject);\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-static NTSTATUS STDCALL\r
-IopCreateGroupListEntry(PWSTR ValueName,\r
- ULONG ValueType,\r
- PVOID ValueData,\r
- ULONG ValueLength,\r
- PVOID Context,\r
- PVOID EntryContext)\r
-{\r
- PSERVICE_GROUP Group;\r
-\r
- if (ValueType == REG_SZ)\r
- {\r
- DPRINT("GroupName: '%S'\n", (PWCHAR)ValueData);\r
-\r
- Group = ExAllocatePool(NonPagedPool,\r
- sizeof(SERVICE_GROUP));\r
- if (Group == NULL)\r
- {\r
- return(STATUS_INSUFFICIENT_RESOURCES);\r
- }\r
-\r
- RtlZeroMemory(Group, sizeof(SERVICE_GROUP));\r
-\r
- if (!RtlCreateUnicodeString(&Group->GroupName,\r
- (PWSTR)ValueData))\r
- {\r
- return(STATUS_INSUFFICIENT_RESOURCES);\r
- }\r
-\r
-\r
- InsertTailList(&GroupListHead,\r
- &Group->GroupListEntry);\r
- }\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-static NTSTATUS STDCALL\r
-IopCreateServiceListEntry(PUNICODE_STRING ServiceName)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[6];\r
- PSERVICE Service;\r
- NTSTATUS Status;\r
-\r
- DPRINT("ServiceName: '%wZ'\n", ServiceName);\r
-\r
- /* Allocate service entry */\r
- Service = (PSERVICE)ExAllocatePool(NonPagedPool, sizeof(SERVICE));\r
- if (Service == NULL)\r
- {\r
- DPRINT1("ExAllocatePool() failed\n");\r
- return(STATUS_INSUFFICIENT_RESOURCES);\r
- }\r
- RtlZeroMemory(Service, sizeof(SERVICE));\r
-\r
- /* Get service data */\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].Name = L"Start";\r
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;\r
- QueryTable[0].EntryContext = &Service->Start;\r
-\r
- QueryTable[1].Name = L"Type";\r
- QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;\r
- QueryTable[1].EntryContext = &Service->Type;\r
-\r
- QueryTable[2].Name = L"ErrorControl";\r
- QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;\r
- QueryTable[2].EntryContext = &Service->ErrorControl;\r
-\r
- QueryTable[3].Name = L"Group";\r
- QueryTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
- QueryTable[3].EntryContext = &Service->ServiceGroup;\r
-\r
- QueryTable[4].Name = L"ImagePath";\r
- QueryTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
- QueryTable[4].EntryContext = &Service->ImagePath;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,\r
- ServiceName->Buffer,\r
- QueryTable,\r
- NULL,\r
- NULL);\r
- if (!NT_SUCCESS(Status) || Service->Start > 1)\r
- {\r
- RtlFreeUnicodeString(&Service->ServiceGroup);\r
- RtlFreeUnicodeString(&Service->ImagePath);\r
- ExFreePool(Service);\r
- return(Status);\r
- }\r
-\r
- /* Copy service name */\r
- Service->ServiceName.Length = ServiceName->Length;\r
- Service->ServiceName.MaximumLength = ServiceName->Length + sizeof(WCHAR);\r
- Service->ServiceName.Buffer = ExAllocatePool(NonPagedPool,\r
- Service->ServiceName.MaximumLength);\r
- RtlCopyMemory(Service->ServiceName.Buffer,\r
- ServiceName->Buffer,\r
- ServiceName->Length);\r
- Service->ServiceName.Buffer[ServiceName->Length / sizeof(WCHAR)] = 0;\r
-\r
- /* Build registry path */\r
- Service->RegistryPath.MaximumLength = MAX_PATH * sizeof(WCHAR);\r
- Service->RegistryPath.Buffer = ExAllocatePool(NonPagedPool,\r
- MAX_PATH * sizeof(WCHAR));\r
- wcscpy(Service->RegistryPath.Buffer,\r
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");\r
- wcscat(Service->RegistryPath.Buffer,\r
- Service->ServiceName.Buffer);\r
- Service->RegistryPath.Length = wcslen(Service->RegistryPath.Buffer) * sizeof(WCHAR);\r
-\r
- DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);\r
- DPRINT("RegistryPath: '%wZ'\n", &Service->RegistryPath);\r
- DPRINT("ServiceGroup: '%wZ'\n", &Service->ServiceGroup);\r
- DPRINT("ImagePath: '%wZ'\n", &Service->ImagePath);\r
- DPRINT("Start %lx Type %lx ErrorControl %lx\n",\r
- Service->Start, Service->Type, Service->ErrorControl);\r
-\r
- /* Append service entry */\r
- InsertTailList(&ServiceListHead,\r
- &Service->ServiceListEntry);\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-NTSTATUS\r
-IoCreateDriverList(VOID)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- PKEY_BASIC_INFORMATION KeyInfo = NULL;\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- UNICODE_STRING ServicesKeyName;\r
- UNICODE_STRING SubKeyName;\r
- HANDLE KeyHandle;\r
- NTSTATUS Status;\r
- ULONG Index;\r
-\r
- ULONG KeyInfoLength = 0;\r
- ULONG ReturnedLength;\r
-\r
- DPRINT("IoCreateDriverList() called\n");\r
-\r
- /* Initialize basic variables */\r
- InitializeListHead(&GroupListHead);\r
- InitializeListHead(&ServiceListHead);\r
-\r
- /* Build group order list */\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].Name = L"List";\r
- QueryTable[0].QueryRoutine = IopCreateGroupListEntry;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- L"ServiceGroupOrder",\r
- QueryTable,\r
- NULL,\r
- NULL);\r
- if (!NT_SUCCESS(Status))\r
- return(Status);\r
-\r
- /* Enumerate services and create the service list */\r
- RtlInitUnicodeStringFromLiteral(&ServicesKeyName,\r
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");\r
-\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &ServicesKeyName,\r
- OBJ_CASE_INSENSITIVE,\r
- NULL,\r
- NULL);\r
-\r
- Status = NtOpenKey(&KeyHandle,\r
- 0x10001,\r
- &ObjectAttributes);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- return(Status);\r
- }\r
-\r
- KeyInfoLength = sizeof(KEY_BASIC_INFORMATION) + MAX_PATH * sizeof(WCHAR);\r
- KeyInfo = ExAllocatePool(NonPagedPool, KeyInfoLength);\r
- if (KeyInfo == NULL)\r
- {\r
- NtClose(KeyHandle);\r
- return(STATUS_INSUFFICIENT_RESOURCES);\r
- }\r
-\r
- Index = 0;\r
- while (TRUE)\r
- {\r
- Status = NtEnumerateKey(KeyHandle,\r
- Index,\r
- KeyBasicInformation,\r
- KeyInfo,\r
- KeyInfoLength,\r
- &ReturnedLength);\r
- if (NT_SUCCESS(Status))\r
- {\r
- if (KeyInfo->NameLength < MAX_PATH * sizeof(WCHAR))\r
- {\r
-\r
- SubKeyName.Length = KeyInfo->NameLength;\r
- SubKeyName.MaximumLength = KeyInfo->NameLength + sizeof(WCHAR);\r
- SubKeyName.Buffer = KeyInfo->Name;\r
- SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;\r
-\r
- DPRINT("KeyName: '%wZ'\n", &SubKeyName);\r
- IopCreateServiceListEntry(&SubKeyName);\r
- }\r
- }\r
-\r
- if (!NT_SUCCESS(Status))\r
- break;\r
-\r
- Index++;\r
- }\r
-\r
- ExFreePool(KeyInfo);\r
- NtClose(KeyHandle);\r
-\r
- DPRINT("IoCreateDriverList() done\n");\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-VOID\r
-LdrLoadAutoConfigDrivers(VOID)\r
-{\r
- PLIST_ENTRY GroupEntry;\r
- PLIST_ENTRY ServiceEntry;\r
- PSERVICE_GROUP CurrentGroup;\r
- PSERVICE CurrentService;\r
- NTSTATUS Status;\r
-\r
- CHAR TextBuffer [256];\r
- ULONG x, y, cx, cy;\r
-\r
- DPRINT("LdrLoadAutoConfigDrivers() called\n");\r
-\r
- GroupEntry = GroupListHead.Flink;\r
- while (GroupEntry != &GroupListHead)\r
- {\r
- CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);\r
-\r
- DPRINT("Group: %wZ\n", &CurrentGroup->GroupName);\r
-\r
- ServiceEntry = ServiceListHead.Flink;\r
- while (ServiceEntry != &ServiceListHead)\r
- {\r
- CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);\r
-\r
- if ((RtlCompareUnicodeString(&CurrentGroup->GroupName, &CurrentService->ServiceGroup, TRUE) == 0) &&\r
- (CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/))\r
- {\r
-\r
- HalQueryDisplayParameters(&x, &y, &cx, &cy);\r
- RtlFillMemory(TextBuffer, x, ' ');\r
- TextBuffer[x] = '\0';\r
- HalSetDisplayParameters(0, y-1);\r
- HalDisplayString(TextBuffer);\r
-\r
- sprintf(TextBuffer, "Loading %S...\n", CurrentService->ServiceName.Buffer);\r
- HalSetDisplayParameters(0, y-1);\r
- HalDisplayString(TextBuffer);\r
- HalSetDisplayParameters(cx, cy);\r
-\r
- DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath);\r
- Status = NtLoadDriver(&CurrentService->RegistryPath);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT("NtLoadDriver() failed (Status %lx)\n", Status);\r
-#if 0\r
- if (CurrentService->ErrorControl == 1)\r
- {\r
- /* Log error */\r
-\r
- }\r
- else if (CurrentService->ErrorControl == 2)\r
- {\r
- if (IsLastKnownGood == FALSE)\r
- {\r
- /* Boot last known good configuration */\r
-\r
- }\r
- }\r
- else if (CurrentService->ErrorControl == 3)\r
- {\r
- if (IsLastKnownGood == FALSE)\r
- {\r
- /* Boot last known good configuration */\r
-\r
- }\r
- else\r
- {\r
- /* BSOD! */\r
-\r
- }\r
- }\r
-#endif\r
- }\r
- }\r
- ServiceEntry = ServiceEntry->Flink;\r
- }\r
-\r
- GroupEntry = GroupEntry->Flink;\r
- }\r
-\r
- DPRINT("LdrLoadAutoConfigDrivers() done\n");\r
-}\r
-\r
-\r
-NTSTATUS\r
-IoDestroyDriverList(VOID)\r
-{\r
- PLIST_ENTRY GroupEntry;\r
- PLIST_ENTRY ServiceEntry;\r
- PSERVICE_GROUP CurrentGroup;\r
- PSERVICE CurrentService;\r
-\r
- DPRINT("IoDestroyDriverList() called\n");\r
-\r
- /* Destroy group list */\r
- GroupEntry = GroupListHead.Flink;\r
- while (GroupEntry != &GroupListHead)\r
- {\r
- CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);\r
-\r
- RtlFreeUnicodeString(&CurrentGroup->GroupName);\r
- RemoveEntryList(GroupEntry);\r
- ExFreePool(CurrentGroup);\r
-\r
- GroupEntry = GroupListHead.Flink;\r
- }\r
-\r
- /* Destroy service list */\r
- ServiceEntry = ServiceListHead.Flink;\r
- while (ServiceEntry != &ServiceListHead)\r
- {\r
- CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);\r
-\r
- RtlFreeUnicodeString(&CurrentService->ServiceName);\r
- RtlFreeUnicodeString(&CurrentService->RegistryPath);\r
- RtlFreeUnicodeString(&CurrentService->ServiceGroup);\r
- RtlFreeUnicodeString(&CurrentService->ImagePath);\r
- RemoveEntryList(ServiceEntry);\r
- ExFreePool(CurrentService);\r
-\r
- ServiceEntry = ServiceListHead.Flink;\r
- }\r
-\r
- DPRINT("IoDestroyDriverList() done\n");\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-/* EOF */\r
+/* $Id: driver.c,v 1.21 2003/10/06 18:49:50 navaraf Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/io/driver.c
+ * PURPOSE: Manage devices
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 15/05/98: Created
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <limits.h>
+#include <ddk/ntddk.h>
+#include <internal/io.h>
+#include <internal/po.h>
+#include <internal/ldr.h>
+#include <internal/id.h>
+#include <internal/pool.h>
+#include <internal/registry.h>
+
+#include <roscfg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+typedef struct _SERVICE_GROUP
+{
+ LIST_ENTRY GroupListEntry;
+ UNICODE_STRING GroupName;
+
+ BOOLEAN ServicesRunning;
+
+} SERVICE_GROUP, *PSERVICE_GROUP;
+
+
+typedef struct _SERVICE
+{
+ LIST_ENTRY ServiceListEntry;
+ UNICODE_STRING ServiceName;
+ UNICODE_STRING RegistryPath;
+ UNICODE_STRING ServiceGroup;
+ UNICODE_STRING ImagePath;
+
+ ULONG Start;
+ ULONG Type;
+ ULONG ErrorControl;
+ ULONG Tag;
+
+ BOOLEAN ServiceRunning; // needed ??
+
+} SERVICE, *PSERVICE;
+
+
+/* GLOBALS *******************************************************************/
+
+static LIST_ENTRY GroupListHead = {NULL, NULL};
+static LIST_ENTRY ServiceListHead = {NULL, NULL};
+
+POBJECT_TYPE EXPORTED IoDriverObjectType = NULL;
+
+#define TAG_DRIVER TAG('D', 'R', 'V', 'R')
+#define TAG_DRIVER_EXTENSION TAG('D', 'R', 'V', 'E')
+
+
+/* FUNCTIONS ***************************************************************/
+
+NTSTATUS STDCALL
+IopCreateDriver(PVOID ObjectBody,
+ PVOID Parent,
+ PWSTR RemainingPath,
+ POBJECT_ATTRIBUTES ObjectAttributes)
+{
+ DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n",
+ ObjectBody,
+ Parent,
+ RemainingPath);
+ if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ return(STATUS_SUCCESS);
+}
+
+
+VOID
+IopInitDriverImplementation(VOID)
+{
+ /* Register the process object type */
+ IoDriverObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
+ IoDriverObjectType->Tag = TAG('D', 'R', 'V', 'R');
+ IoDriverObjectType->TotalObjects = 0;
+ IoDriverObjectType->TotalHandles = 0;
+ IoDriverObjectType->MaxObjects = ULONG_MAX;
+ IoDriverObjectType->MaxHandles = ULONG_MAX;
+ IoDriverObjectType->PagedPoolCharge = 0;
+ IoDriverObjectType->NonpagedPoolCharge = sizeof(DRIVER_OBJECT);
+ IoDriverObjectType->Dump = NULL;
+ IoDriverObjectType->Open = NULL;
+ IoDriverObjectType->Close = NULL;
+ IoDriverObjectType->Delete = NULL;
+ IoDriverObjectType->Parse = NULL;
+ IoDriverObjectType->Security = NULL;
+ IoDriverObjectType->QueryName = NULL;
+ IoDriverObjectType->OkayToClose = NULL;
+ IoDriverObjectType->Create = IopCreateDriver;
+ IoDriverObjectType->DuplicationNotify = NULL;
+ RtlInitUnicodeStringFromLiteral(&IoDriverObjectType->TypeName, L"Driver");
+}
+
+/**********************************************************************
+ * NAME EXPORTED
+ * NtLoadDriver
+ *
+ * DESCRIPTION
+ * Loads a device driver.
+ *
+ * ARGUMENTS
+ * DriverServiceName
+ * Name of the service to load (registry key).
+ *
+ * RETURN VALUE
+ * Status.
+ *
+ * REVISIONS
+ */
+NTSTATUS STDCALL
+NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[3];
+ WCHAR FullImagePathBuffer[MAX_PATH];
+ UNICODE_STRING ImagePath;
+ UNICODE_STRING FullImagePath;
+ NTSTATUS Status;
+ ULONG Type;
+ PDEVICE_NODE DeviceNode;
+ PMODULE_OBJECT ModuleObject;
+ LPWSTR Start;
+
+ DPRINT("NtLoadDriver(%wZ) called\n", DriverServiceName);
+
+ RtlInitUnicodeString(&ImagePath, NULL);
+
+ /* Get service data */
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"Type";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[0].EntryContext = &Type;
+
+ QueryTable[1].Name = L"ImagePath";
+ QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[1].EntryContext = &ImagePath;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ DriverServiceName->Buffer,
+ QueryTable,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ RtlFreeUnicodeString(&ImagePath);
+ return(Status);
+ }
+
+ if (ImagePath.Length == 0)
+ {
+ wcscpy(FullImagePathBuffer, L"\\SystemRoot\\system32\\drivers");
+ wcscat(FullImagePathBuffer, wcsrchr(DriverServiceName->Buffer, L'\\'));
+ wcscat(FullImagePathBuffer, L".sys");
+ }
+ else if (ImagePath.Buffer[0] != L'\\')
+ {
+ wcscpy(FullImagePathBuffer, L"\\SystemRoot\\");
+ wcscat(FullImagePathBuffer, ImagePath.Buffer);
+ }
+ else
+ {
+ wcscpy(FullImagePathBuffer, ImagePath.Buffer);
+ }
+
+ RtlFreeUnicodeString(&ImagePath);
+ RtlInitUnicodeString(&FullImagePath, FullImagePathBuffer);
+
+ DPRINT("FullImagePath: '%S'\n", FullImagePathBuffer);
+ DPRINT("Type %lx\n", Type);
+
+ /* Use IopRootDeviceNode for now */
+ Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
+ return(Status);
+ }
+
+ ModuleObject = LdrGetModuleObject(DriverServiceName);
+ if (ModuleObject != NULL)
+ {
+ return(STATUS_IMAGE_ALREADY_LOADED);
+ }
+
+ Status = LdrLoadModule(&FullImagePath, &ModuleObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("LdrLoadModule() failed (Status %lx)\n", Status);
+ IopFreeDeviceNode(DeviceNode);
+ return(Status);
+ }
+
+ /* Set a service name for the device node */
+ Start = wcsrchr(DriverServiceName->Buffer, L'\\');
+ if (Start == NULL)
+ Start = DriverServiceName->Buffer;
+ else
+ Start++;
+ RtlCreateUnicodeString(&DeviceNode->ServiceName, Start);
+
+ Status = IopInitializeDriver(ModuleObject->EntryPoint,
+ DeviceNode,
+ (Type == 2 || Type == 8),
+ ModuleObject->Base,
+ ModuleObject->Length,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status);
+ LdrUnloadModule(ModuleObject);
+ IopFreeDeviceNode(DeviceNode);
+ }
+
+ return(Status);
+}
+
+
+NTSTATUS STDCALL
+NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ WCHAR FullImagePathBuffer[MAX_PATH];
+ UNICODE_STRING ImagePath;
+ UNICODE_STRING FullImagePath;
+ UNICODE_STRING ObjectName;
+ PDRIVER_OBJECT DriverObject;
+ NTSTATUS Status;
+ PMODULE_OBJECT ModuleObject;
+ LPWSTR Start;
+
+ DPRINT("DriverServiceName: '%wZ'\n", DriverServiceName);
+
+ /* Get the service name from the module name */
+ Start = wcsrchr(DriverServiceName->Buffer, L'\\');
+ if (Start == NULL)
+ Start = DriverServiceName->Buffer;
+ else
+ Start++;
+
+ ObjectName.Length = wcslen(Start) + 8;
+ ObjectName.Buffer = ExAllocatePool(NonPagedPool,
+ ObjectName.Length * sizeof(WCHAR));
+ wcscpy(ObjectName.Buffer, L"\\Driver\\");
+ memcpy(ObjectName.Buffer + 8, Start, (ObjectName.Length - 8) * sizeof(WCHAR));
+
+ /* Find the driver object */
+ Status = ObReferenceObjectByName(&ObjectName, 0, 0, 0, IoDriverObjectType,
+ KernelMode, 0, (PVOID*)&DriverObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Can't locate driver object for %wZ\n", ObjectName);
+ return Status;
+ }
+ ObDereferenceObject(DriverObject);
+
+ RtlInitUnicodeString(&ImagePath, NULL);
+
+ /* Get service data */
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"ImagePath";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[0].EntryContext = &ImagePath;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ DriverServiceName->Buffer,
+ QueryTable,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ RtlFreeUnicodeString(&ImagePath);
+ return(Status);
+ }
+
+ if (ImagePath.Length == 0)
+ {
+ wcscpy(FullImagePathBuffer, L"\\SystemRoot\\system32\\drivers");
+ wcscat(FullImagePathBuffer, wcsrchr(DriverServiceName->Buffer, L'\\'));
+ wcscat(FullImagePathBuffer, L".sys");
+ }
+ else if (ImagePath.Buffer[0] != L'\\')
+ {
+ wcscpy(FullImagePathBuffer, L"\\SystemRoot\\");
+ wcscat(FullImagePathBuffer, ImagePath.Buffer);
+ }
+ else
+ {
+ wcscpy(FullImagePathBuffer, ImagePath.Buffer);
+ }
+
+ RtlFreeUnicodeString(&ImagePath);
+ RtlInitUnicodeString(&FullImagePath, FullImagePathBuffer);
+
+ ModuleObject = LdrGetModuleObject(DriverServiceName);
+ if (ModuleObject == NULL)
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Unload the module and release the references to the device object */
+
+ if (DriverObject->DriverUnload)
+ (*DriverObject->DriverUnload)(DriverObject);
+ ObDereferenceObject(DriverObject);
+ ObDereferenceObject(DriverObject);
+ LdrUnloadModule(ModuleObject);
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS STDCALL
+IopCreateGroupListEntry(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ PSERVICE_GROUP Group;
+
+ if (ValueType == REG_SZ)
+ {
+ DPRINT("GroupName: '%S'\n", (PWCHAR)ValueData);
+
+ Group = ExAllocatePool(NonPagedPool,
+ sizeof(SERVICE_GROUP));
+ if (Group == NULL)
+ {
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ RtlZeroMemory(Group, sizeof(SERVICE_GROUP));
+
+ if (!RtlCreateUnicodeString(&Group->GroupName,
+ (PWSTR)ValueData))
+ {
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+
+ InsertTailList(&GroupListHead,
+ &Group->GroupListEntry);
+ }
+
+ return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS STDCALL
+IopCreateServiceListEntry(PUNICODE_STRING ServiceName)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[6];
+ PSERVICE Service;
+ NTSTATUS Status;
+
+ DPRINT("ServiceName: '%wZ'\n", ServiceName);
+
+ /* Allocate service entry */
+ Service = (PSERVICE)ExAllocatePool(NonPagedPool, sizeof(SERVICE));
+ if (Service == NULL)
+ {
+ DPRINT1("ExAllocatePool() failed\n");
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+ RtlZeroMemory(Service, sizeof(SERVICE));
+
+ /* Get service data */
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"Start";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[0].EntryContext = &Service->Start;
+
+ QueryTable[1].Name = L"Type";
+ QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[1].EntryContext = &Service->Type;
+
+ QueryTable[2].Name = L"ErrorControl";
+ QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[2].EntryContext = &Service->ErrorControl;
+
+ QueryTable[3].Name = L"Group";
+ QueryTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[3].EntryContext = &Service->ServiceGroup;
+
+ QueryTable[4].Name = L"ImagePath";
+ QueryTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[4].EntryContext = &Service->ImagePath;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
+ ServiceName->Buffer,
+ QueryTable,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status) || Service->Start > 1)
+ {
+ RtlFreeUnicodeString(&Service->ServiceGroup);
+ RtlFreeUnicodeString(&Service->ImagePath);
+ ExFreePool(Service);
+ return(Status);
+ }
+
+ /* Copy service name */
+ Service->ServiceName.Length = ServiceName->Length;
+ Service->ServiceName.MaximumLength = ServiceName->Length + sizeof(WCHAR);
+ Service->ServiceName.Buffer = ExAllocatePool(NonPagedPool,
+ Service->ServiceName.MaximumLength);
+ RtlCopyMemory(Service->ServiceName.Buffer,
+ ServiceName->Buffer,
+ ServiceName->Length);
+ Service->ServiceName.Buffer[ServiceName->Length / sizeof(WCHAR)] = 0;
+
+ /* Build registry path */
+ Service->RegistryPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
+ Service->RegistryPath.Buffer = ExAllocatePool(NonPagedPool,
+ MAX_PATH * sizeof(WCHAR));
+ wcscpy(Service->RegistryPath.Buffer,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+ wcscat(Service->RegistryPath.Buffer,
+ Service->ServiceName.Buffer);
+ Service->RegistryPath.Length = wcslen(Service->RegistryPath.Buffer) * sizeof(WCHAR);
+
+ DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);
+ DPRINT("RegistryPath: '%wZ'\n", &Service->RegistryPath);
+ DPRINT("ServiceGroup: '%wZ'\n", &Service->ServiceGroup);
+ DPRINT("ImagePath: '%wZ'\n", &Service->ImagePath);
+ DPRINT("Start %lx Type %lx ErrorControl %lx\n",
+ Service->Start, Service->Type, Service->ErrorControl);
+
+ /* Append service entry */
+ InsertTailList(&ServiceListHead,
+ &Service->ServiceListEntry);
+
+ return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS
+IoCreateDriverList(VOID)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ PKEY_BASIC_INFORMATION KeyInfo = NULL;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING ServicesKeyName;
+ UNICODE_STRING SubKeyName;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ ULONG Index;
+
+ ULONG KeyInfoLength = 0;
+ ULONG ReturnedLength;
+
+ DPRINT("IoCreateDriverList() called\n");
+
+ /* Initialize basic variables */
+ InitializeListHead(&GroupListHead);
+ InitializeListHead(&ServiceListHead);
+
+ /* Build group order list */
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"List";
+ QueryTable[0].QueryRoutine = IopCreateGroupListEntry;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"ServiceGroupOrder",
+ QueryTable,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+
+ /* Enumerate services and create the service list */
+ RtlInitUnicodeStringFromLiteral(&ServicesKeyName,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ServicesKeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenKey(&KeyHandle,
+ 0x10001,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+ KeyInfoLength = sizeof(KEY_BASIC_INFORMATION) + MAX_PATH * sizeof(WCHAR);
+ KeyInfo = ExAllocatePool(NonPagedPool, KeyInfoLength);
+ if (KeyInfo == NULL)
+ {
+ NtClose(KeyHandle);
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ Index = 0;
+ while (TRUE)
+ {
+ Status = NtEnumerateKey(KeyHandle,
+ Index,
+ KeyBasicInformation,
+ KeyInfo,
+ KeyInfoLength,
+ &ReturnedLength);
+ if (NT_SUCCESS(Status))
+ {
+ if (KeyInfo->NameLength < MAX_PATH * sizeof(WCHAR))
+ {
+
+ SubKeyName.Length = KeyInfo->NameLength;
+ SubKeyName.MaximumLength = KeyInfo->NameLength + sizeof(WCHAR);
+ SubKeyName.Buffer = KeyInfo->Name;
+ SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;
+
+ DPRINT("KeyName: '%wZ'\n", &SubKeyName);
+ IopCreateServiceListEntry(&SubKeyName);
+ }
+ }
+
+ if (!NT_SUCCESS(Status))
+ break;
+
+ Index++;
+ }
+
+ ExFreePool(KeyInfo);
+ NtClose(KeyHandle);
+
+ DPRINT("IoCreateDriverList() done\n");
+
+ return(STATUS_SUCCESS);
+}
+
+
+VOID
+LdrLoadAutoConfigDrivers(VOID)
+{
+ PLIST_ENTRY GroupEntry;
+ PLIST_ENTRY ServiceEntry;
+ PSERVICE_GROUP CurrentGroup;
+ PSERVICE CurrentService;
+ NTSTATUS Status;
+
+ CHAR TextBuffer [256];
+ ULONG x, y, cx, cy;
+
+ DPRINT("LdrLoadAutoConfigDrivers() called\n");
+
+ GroupEntry = GroupListHead.Flink;
+ while (GroupEntry != &GroupListHead)
+ {
+ CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
+
+ DPRINT("Group: %wZ\n", &CurrentGroup->GroupName);
+
+ ServiceEntry = ServiceListHead.Flink;
+ while (ServiceEntry != &ServiceListHead)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
+
+ if ((RtlCompareUnicodeString(&CurrentGroup->GroupName, &CurrentService->ServiceGroup, TRUE) == 0) &&
+ (CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/))
+ {
+
+ HalQueryDisplayParameters(&x, &y, &cx, &cy);
+ RtlFillMemory(TextBuffer, x, ' ');
+ TextBuffer[x] = '\0';
+ HalSetDisplayParameters(0, y-1);
+ HalDisplayString(TextBuffer);
+
+ sprintf(TextBuffer, "Loading %S...\n", CurrentService->ServiceName.Buffer);
+ HalSetDisplayParameters(0, y-1);
+ HalDisplayString(TextBuffer);
+ HalSetDisplayParameters(cx, cy);
+
+ DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath);
+ Status = NtLoadDriver(&CurrentService->RegistryPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtLoadDriver() failed (Status %lx)\n", Status);
+#if 0
+ if (CurrentService->ErrorControl == 1)
+ {
+ /* Log error */
+
+ }
+ else if (CurrentService->ErrorControl == 2)
+ {
+ if (IsLastKnownGood == FALSE)
+ {
+ /* Boot last known good configuration */
+
+ }
+ }
+ else if (CurrentService->ErrorControl == 3)
+ {
+ if (IsLastKnownGood == FALSE)
+ {
+ /* Boot last known good configuration */
+
+ }
+ else
+ {
+ /* BSOD! */
+
+ }
+ }
+#endif
+ }
+ }
+ ServiceEntry = ServiceEntry->Flink;
+ }
+
+ GroupEntry = GroupEntry->Flink;
+ }
+
+ DPRINT("LdrLoadAutoConfigDrivers() done\n");
+}
+
+
+NTSTATUS
+IoDestroyDriverList(VOID)
+{
+ PLIST_ENTRY GroupEntry;
+ PLIST_ENTRY ServiceEntry;
+ PSERVICE_GROUP CurrentGroup;
+ PSERVICE CurrentService;
+
+ DPRINT("IoDestroyDriverList() called\n");
+
+ /* Destroy group list */
+ GroupEntry = GroupListHead.Flink;
+ while (GroupEntry != &GroupListHead)
+ {
+ CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
+
+ RtlFreeUnicodeString(&CurrentGroup->GroupName);
+ RemoveEntryList(GroupEntry);
+ ExFreePool(CurrentGroup);
+
+ GroupEntry = GroupListHead.Flink;
+ }
+
+ /* Destroy service list */
+ ServiceEntry = ServiceListHead.Flink;
+ while (ServiceEntry != &ServiceListHead)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
+
+ RtlFreeUnicodeString(&CurrentService->ServiceName);
+ RtlFreeUnicodeString(&CurrentService->RegistryPath);
+ RtlFreeUnicodeString(&CurrentService->ServiceGroup);
+ RtlFreeUnicodeString(&CurrentService->ImagePath);
+ RemoveEntryList(ServiceEntry);
+ ExFreePool(CurrentService);
+
+ ServiceEntry = ServiceListHead.Flink;
+ }
+
+ DPRINT("IoDestroyDriverList() done\n");
+
+ return(STATUS_SUCCESS);
+}
+
+/* EOF */
-/* Do not edit - Machine generated */\r
-#ifndef _INC_REACTOS_BUILDNO\r
-#define _INC_REACTOS_BUILDNO\r
-#define KERNEL_VERSION_BUILD 36\r
-#define KERNEL_VERSION_BUILD_STR "36"\r
-#define KERNEL_RELEASE_RC "0.1.3.36\0"\r
-#define KERNEL_RELEASE_STR "0.1.3.36"\r
-#define KERNEL_VERSION_RC "0.1.3\0"\r
-#define KERNEL_VERSION_STR "0.1.3"\r
-#endif\r
-/* EOF */\r
+/* Do not edit - Machine generated */
+#ifndef _INC_REACTOS_BUILDNO
+#define _INC_REACTOS_BUILDNO
+#define KERNEL_VERSION_BUILD 36
+#define KERNEL_VERSION_BUILD_STR "36"
+#define KERNEL_RELEASE_RC "0.1.3.36\0"
+#define KERNEL_RELEASE_STR "0.1.3.36"
+#define KERNEL_VERSION_RC "0.1.3\0"
+#define KERNEL_VERSION_STR "0.1.3"
+#endif
+/* EOF */
-#\r
-# ReactOS explorer\r
-#\r
-# Makefile\r
-#\r
-\r
-PATH_TO_TOP = ../../..\r
-\r
-TARGET_TYPE = program\r
-\r
-TARGET_APPTYPE = windows\r
-\r
-TARGET_NAME = explorer\r
-\r
-TARGET_CFLAGS = -fexceptions -Os -DNDEBUG -DWIN32 -D_ROS_ -Wall -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501\r
- \r
-TARGET_CPPFLAGS = -fexceptions -Os -DNDEBUG -DWIN32 -D_ROS_ -Wall -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501\r
-\r
-TARGET_RCFLAGS = -DNDEBUG -DWIN32 -D_ROS_\r
-\r
-ifdef UNICODE\r
-TARGET_CFLAGS += -DUNICODE\r
-TARGET_CPPFLAGS += -DUNICODE\r
-# MK_DEFENTRY = _wWinMain@16\r
-endif\r
-\r
-VPATH += shell\r
-VPATH += utility\r
-VPATH += taskbar\r
-VPATH += desktop\r
-VPATH += dialogs\r
-\r
-WINE_MODE = yes\r
-\r
-WINE_RC = $(TARGET_NAME)\r
-\r
-WINE_INCLUDE = ./\r
-\r
-TARGET_GCCLIBS = comctl32 ole32 uuid stdc++\r
-\r
-all: buildno.h explorer.exe\r
- @strip explorer.exe\r
-\r
-buildno.h: ../../../include/reactos/buildno.h\r
- updatebuildno\r
-\r
-TARGET_SDKLIBS = \\r
- kernel32.a \\r
- user32.a \\r
- gdi32.a \\r
- advapi32.a \\r
- version.a\r
-\r
-TARGET_OBJECTS = \\r
- startup.o \\r
- shellclasses.o \\r
- utility.o \\r
- window.o \\r
- dragdropimpl.o \\r
- shellbrowserimpl.o \\r
- explorer.o \\r
- entries.o \\r
- winfs.o \\r
- unixfs.o \\r
- shellfs.o \\r
- mainframe.o \\r
- filechild.o \\r
- pane.o \\r
- shellbrowser.o \\r
- desktop.o \\r
- desktopbar.o \\r
- taskbar.o \\r
- startmenu.o \\r
- traynotify.o \\r
- quicklaunch.o \\r
- searchprogram.o\r
-\r
-include $(PATH_TO_TOP)/rules.mak\r
-\r
-include $(TOOLS_PATH)/helper.mk\r
-\r
-# overide LD_CC to use g++ for linking of the executable\r
-LD_CC = $(CXX)\r
-\r
-# EOF\r
+#
+# ReactOS explorer
+#
+# Makefile
+#
+
+PATH_TO_TOP = ../../..
+
+TARGET_TYPE = program
+
+TARGET_APPTYPE = windows
+
+TARGET_NAME = explorer
+
+TARGET_CFLAGS = -fexceptions -Os -DNDEBUG -DWIN32 -D_ROS_ -Wall -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501
+
+TARGET_CPPFLAGS = -fexceptions -Os -DNDEBUG -DWIN32 -D_ROS_ -Wall -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501
+
+TARGET_RCFLAGS = -DNDEBUG -DWIN32 -D_ROS_
+
+ifdef UNICODE
+TARGET_CFLAGS += -DUNICODE
+TARGET_CPPFLAGS += -DUNICODE
+# MK_DEFENTRY = _wWinMain@16
+endif
+
+VPATH += shell
+VPATH += utility
+VPATH += taskbar
+VPATH += desktop
+VPATH += dialogs
+
+WINE_MODE = yes
+
+WINE_RC = $(TARGET_NAME)
+
+WINE_INCLUDE = ./
+
+TARGET_GCCLIBS = comctl32 ole32 uuid stdc++
+
+all: buildno.h explorer.exe
+ @strip explorer.exe
+
+buildno.h: ../../../include/reactos/buildno.h
+ updatebuildno
+
+TARGET_SDKLIBS = \
+ kernel32.a \
+ user32.a \
+ gdi32.a \
+ advapi32.a \
+ version.a
+
+TARGET_OBJECTS = \
+ startup.o \
+ shellclasses.o \
+ utility.o \
+ window.o \
+ dragdropimpl.o \
+ shellbrowserimpl.o \
+ explorer.o \
+ entries.o \
+ winfs.o \
+ unixfs.o \
+ shellfs.o \
+ mainframe.o \
+ filechild.o \
+ pane.o \
+ shellbrowser.o \
+ desktop.o \
+ desktopbar.o \
+ taskbar.o \
+ startmenu.o \
+ traynotify.o \
+ quicklaunch.o \
+ searchprogram.o
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
+
+# overide LD_CC to use g++ for linking of the executable
+LD_CC = $(CXX)
+
+# EOF
-/*\r
- * ReactOS W32 Subsystem\r
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- */\r
-/* $Id: windc.c,v 1.29 2003/10/06 18:24:54 navaraf Exp $\r
- *\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * PURPOSE: Window classes\r
- * FILE: subsys/win32k/ntuser/class.c\r
- * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)\r
- * REVISION HISTORY:\r
- * 06-06-2001 CSH Created\r
- */\r
-\r
-/* INCLUDES ******************************************************************/\r
-\r
-#include <ddk/ntddk.h>\r
-#include <win32k/win32k.h>\r
-#include <win32k/region.h>\r
-#include <include/class.h>\r
-#include <include/error.h>\r
-#include <include/winsta.h>\r
-#include <include/msgqueue.h>\r
-#include <include/window.h>\r
-#include <include/rect.h>\r
-#include <include/dce.h>\r
-#include <include/vis.h>\r
-#include <include/object.h>\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* GLOBALS *******************************************************************/\r
-\r
-static PDCE FirstDce = NULL;\r
-static HDC defaultDCstate;\r
-\r
-#define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \\r
- DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-HRGN STDCALL\r
-DceGetVisRgn(HWND hWnd, ULONG Flags, HWND hWndChild, ULONG CFlags)\r
-{\r
- PWINDOW_OBJECT Window;\r
- PWINDOW_OBJECT Child;\r
- HRGN VisRgn;\r
- HRGN VisChild;\r
- HRGN ChildRect;\r
- HRGN ParentRect;\r
-\r
- Window = IntGetWindowObject(hWnd);\r
-\r
- if (NULL == Window)\r
- {\r
- return NULL;\r
- }\r
-\r
- VisRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop, Window,\r
- 0 == (Flags & DCX_WINDOW),\r
- 0 != (Flags & DCX_CLIPCHILDREN),\r
- 0 != (Flags & DCX_CLIPSIBLINGS));\r
- if (NULL != hWndChild && 0 != (CFlags & DCX_CLIPCHILDREN))\r
- {\r
- /* We need to filter out the child windows of hWndChild */\r
- Child = IntGetWindowObject(hWnd);\r
- if (NULL != Child)\r
- {\r
- if (Child->FirstChild)\r
- {\r
- /* Compute the visible region of the child */\r
- VisChild = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,\r
- Child, FALSE, TRUE, FALSE);\r
- /* If the child doesn't obscure the whole window, we need to\r
- extend it. First compute the difference between window and child */\r
- ChildRect = UnsafeIntCreateRectRgnIndirect(&(Child->ClientRect));\r
- if (0 == (Flags & DCX_WINDOW))\r
- {\r
- ParentRect = UnsafeIntCreateRectRgnIndirect(&(Window->ClientRect));\r
- }\r
- else\r
- {\r
- ParentRect = UnsafeIntCreateRectRgnIndirect(&(Window->WindowRect));\r
- }\r
- NtGdiCombineRgn(ChildRect, ParentRect, ChildRect, RGN_DIFF);\r
-\r
- /* Now actually extend the child by adding the difference */\r
- NtGdiCombineRgn(VisChild, VisChild, ChildRect, RGN_OR);\r
-\r
- /* Clip the childs children */\r
- NtGdiCombineRgn(VisRgn, VisRgn, VisChild, RGN_AND);\r
- }\r
- IntReleaseWindowObject(Child);\r
- }\r
- }\r
-\r
- IntReleaseWindowObject(Window);\r
-\r
- return VisRgn;\r
-}\r
-\r
-HDC STDCALL\r
-NtUserGetDC(HWND hWnd)\r
-{\r
- return NtUserGetDCEx(hWnd, NULL, NULL == hWnd ? DCX_CACHE | DCX_WINDOW : DCX_USESTYLE);\r
-}\r
-\r
-PDCE FASTCALL\r
-DceAllocDCE(HWND hWnd, DCE_TYPE Type)\r
-{\r
- HDCE DceHandle;\r
- DCE* Dce;\r
-\r
- DceHandle = DCEOBJ_AllocDCE();\r
- if(!DceHandle)\r
- return NULL;\r
- \r
- Dce = DCEOBJ_LockDCE(DceHandle);\r
- Dce->hDC = NtGdiCreateDC(L"DISPLAY", NULL, NULL, NULL);\r
- if (NULL == defaultDCstate)\r
- {\r
- defaultDCstate = NtGdiGetDCState(Dce->hDC);\r
- GDIOBJ_MarkObjectGlobal(defaultDCstate);\r
- }\r
- Dce->hwndCurrent = hWnd;\r
- Dce->hClipRgn = NULL;\r
- Dce->next = FirstDce;\r
- FirstDce = Dce;\r
-\r
- if (Type != DCE_CACHE_DC)\r
- {\r
- Dce->DCXFlags = DCX_DCEBUSY;\r
- if (hWnd != NULL)\r
- {\r
- PWINDOW_OBJECT WindowObject;\r
-\r
- WindowObject = IntGetWindowObject(hWnd);\r
- if (WindowObject->Style & WS_CLIPCHILDREN)\r
- {\r
- Dce->DCXFlags |= DCX_CLIPCHILDREN;\r
- }\r
- if (WindowObject->Style & WS_CLIPSIBLINGS)\r
- {\r
- Dce->DCXFlags |= DCX_CLIPSIBLINGS;\r
- }\r
- IntReleaseWindowObject(WindowObject);\r
- }\r
- }\r
- else\r
- {\r
- Dce->DCXFlags = DCX_CACHE | DCX_DCEEMPTY;\r
- }\r
-\r
- return(Dce);\r
-}\r
-\r
-VOID STATIC STDCALL\r
-DceSetDrawable(PWINDOW_OBJECT WindowObject, HDC hDC, ULONG Flags,\r
- BOOL SetClipOrigin)\r
-{\r
- DC *dc = DC_LockDc(hDC);\r
- if(!dc)\r
- return;\r
- \r
- if (WindowObject == NULL)\r
- {\r
- dc->w.DCOrgX = 0;\r
- dc->w.DCOrgY = 0;\r
- }\r
- else\r
- {\r
- if (Flags & DCX_WINDOW)\r
- {\r
- dc->w.DCOrgX = WindowObject->WindowRect.left;\r
- dc->w.DCOrgY = WindowObject->WindowRect.top;\r
- }\r
- else\r
- {\r
- dc->w.DCOrgX = WindowObject->ClientRect.left;\r
- dc->w.DCOrgY = WindowObject->ClientRect.top;\r
- }\r
- }\r
- DC_UnlockDc(hDC);\r
-}\r
-\r
-\r
-STATIC VOID FASTCALL\r
-DceDeleteClipRgn(DCE* Dce)\r
-{\r
- Dce->DCXFlags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN | DCX_WINDOWPAINT);\r
-\r
- if (Dce->DCXFlags & DCX_KEEPCLIPRGN )\r
- {\r
- Dce->DCXFlags &= ~DCX_KEEPCLIPRGN;\r
- }\r
- else if (Dce->hClipRgn > (HRGN) 1)\r
- {\r
- NtGdiDeleteObject(Dce->hClipRgn);\r
- }\r
-\r
- Dce->hClipRgn = NULL;\r
-\r
- /* make it dirty so that the vis rgn gets recomputed next time */\r
- Dce->DCXFlags |= DCX_DCEDIRTY;\r
-}\r
-\r
-STATIC INT FASTCALL\r
-DceReleaseDC(DCE* dce)\r
-{\r
- if (DCX_DCEBUSY != (dce->DCXFlags & (DCX_DCEEMPTY | DCX_DCEBUSY)))\r
- {\r
- return 0;\r
- }\r
-\r
- /* restore previous visible region */\r
-\r
- if ((dce->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&\r
- (dce->DCXFlags & (DCX_CACHE | DCX_WINDOWPAINT)) )\r
- {\r
- DceDeleteClipRgn( dce );\r
- }\r
-\r
- if (dce->DCXFlags & DCX_CACHE)\r
- {\r
- /* make the DC clean so that SetDCState doesn't try to update the vis rgn */\r
- NtGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);\r
- NtGdiSetDCState(dce->hDC, defaultDCstate);\r
- dce->DCXFlags &= ~DCX_DCEBUSY;\r
- if (dce->DCXFlags & DCX_DCEDIRTY)\r
- {\r
- /* don't keep around invalidated entries\r
- * because SetDCState() disables hVisRgn updates\r
- * by removing dirty bit. */\r
- dce->hwndCurrent = 0;\r
- dce->DCXFlags &= DCX_CACHE;\r
- dce->DCXFlags |= DCX_DCEEMPTY;\r
- }\r
- }\r
-\r
- return 1;\r
-}\r
-\r
-HDC STDCALL\r
-NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)\r
-{\r
- PWINDOW_OBJECT Window;\r
- ULONG DcxFlags;\r
- DCE* Dce;\r
- BOOL UpdateVisRgn = TRUE;\r
- BOOL UpdateClipOrigin = FALSE;\r
- HANDLE hRgnVisible = NULL;\r
-\r
- if (NULL == hWnd)\r
- {\r
- Flags &= ~DCX_USESTYLE;\r
- Window = NULL;\r
- }\r
- else if (NULL == (Window = IntGetWindowObject(hWnd)))\r
- {\r
- return(0);\r
- }\r
-\r
- if (NULL == Window || NULL == Window->Dce)\r
- {\r
- Flags |= DCX_CACHE;\r
- }\r
-\r
-\r
- if (Flags & DCX_USESTYLE)\r
- {\r
- Flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | DCX_PARENTCLIP);\r
-\r
- if (Window->Style & WS_CLIPSIBLINGS)\r
- {\r
- Flags |= DCX_CLIPSIBLINGS;\r
- }\r
-\r
- if (!(Flags & DCX_WINDOW))\r
- {\r
- if (Window->Class->style & CS_PARENTDC)\r
- {\r
- Flags |= DCX_PARENTCLIP;\r
- }\r
-\r
- if (Window->Style & WS_CLIPCHILDREN &&\r
- !(Window->Style & WS_MINIMIZE))\r
- {\r
- Flags |= DCX_CLIPCHILDREN;\r
- }\r
- }\r
- else\r
- {\r
- Flags |= DCX_CACHE;\r
- }\r
- }\r
-\r
- if (Flags & DCX_NOCLIPCHILDREN)\r
- {\r
- Flags |= DCX_CACHE;\r
- Flags |= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);\r
- }\r
-\r
- if (Flags & DCX_WINDOW)\r
- {\r
- Flags = (Flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;\r
- }\r
-\r
- if (NULL == Window || !(Window->Style & WS_CHILD) || NULL == Window->Parent)\r
- {\r
- Flags &= ~DCX_PARENTCLIP;\r
- }\r
- else if (Flags & DCX_PARENTCLIP)\r
- {\r
- Flags |= DCX_CACHE;\r
- if (!(Flags & (DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS)))\r
- {\r
- if ((Window->Style & WS_VISIBLE) && \r
- (Window->Parent->Style & WS_VISIBLE))\r
- {\r
- Flags &= ~DCX_CLIPCHILDREN;\r
- if (Window->Parent->Style & WS_CLIPSIBLINGS)\r
- {\r
- Flags |= DCX_CLIPSIBLINGS;\r
- }\r
- }\r
- }\r
- }\r
-\r
- DcxFlags = Flags & DCX_CACHECOMPAREMASK;\r
-\r
- if (Flags & DCX_CACHE)\r
- {\r
- DCE* DceEmpty = NULL;\r
- DCE* DceUnused = NULL;\r
-\r
- for (Dce = FirstDce; Dce != NULL; Dce = Dce->next)\r
- {\r
- if ((Dce->DCXFlags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE)\r
- {\r
- DceUnused = Dce;\r
- if (Dce->DCXFlags & DCX_DCEEMPTY)\r
- {\r
- DceEmpty = Dce;\r
- }\r
- else if (Dce->hwndCurrent == hWnd &&\r
- ((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags))\r
- {\r
-#if 0 /* FIXME */\r
- UpdateVisRgn = FALSE;\r
-#endif\r
- UpdateClipOrigin = TRUE;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- if (Dce == NULL)\r
- {\r
- Dce = (DceEmpty == NULL) ? DceEmpty : DceUnused;\r
- }\r
-\r
- if (Dce == NULL)\r
- {\r
- Dce = DceAllocDCE(NULL, DCE_CACHE_DC);\r
- }\r
- }\r
- else\r
- {\r
- Dce = Window->Dce;\r
- /* FIXME: Implement this. */\r
- DbgBreakPoint();\r
- }\r
-\r
- if (NULL == Dce)\r
- {\r
- if(NULL != Window)\r
- IntReleaseWindowObject(Window);\r
- return(NULL);\r
- }\r
-\r
- Dce->hwndCurrent = hWnd;\r
- Dce->hClipRgn = NULL;\r
- Dce->DCXFlags = DcxFlags | (Flags & DCX_WINDOWPAINT) | DCX_DCEBUSY;\r
-\r
- if (0 == (Flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) && NULL != ClipRegion)\r
- {\r
- NtGdiDeleteObject(ClipRegion);\r
- ClipRegion = NULL;\r
- }\r
-\r
- if (NULL != Dce->hClipRgn)\r
- {\r
- DceDeleteClipRgn(Dce);\r
- }\r
-\r
- if (NULL != ClipRegion)\r
- {\r
- Dce->hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);\r
- if(Dce->hClipRgn)\r
- NtGdiCombineRgn(Dce->hClipRgn, ClipRegion, NULL, RGN_COPY);\r
- NtGdiDeleteObject(ClipRegion);\r
- }\r
-\r
- DceSetDrawable(Window, Dce->hDC, Flags, UpdateClipOrigin);\r
-\r
- if (UpdateVisRgn)\r
- {\r
- if (Flags & DCX_PARENTCLIP)\r
- {\r
- PWINDOW_OBJECT Parent;\r
-\r
- Parent = Window->Parent;\r
-\r
- if (Window->Style & WS_VISIBLE &&\r
- !(Parent->Style & WS_MINIMIZE))\r
- {\r
- if (Parent->Style & WS_CLIPSIBLINGS)\r
- {\r
- DcxFlags = DCX_CLIPSIBLINGS | \r
- (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));\r
- }\r
- else\r
- {\r
- DcxFlags = Flags & \r
- ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);\r
- }\r
- hRgnVisible = DceGetVisRgn(Parent->Self, DcxFlags, \r
- Window->Self, Flags);\r
- }\r
- else\r
- {\r
- hRgnVisible = NtGdiCreateRectRgn(0, 0, 0, 0);\r
- }\r
- }\r
- else\r
- {\r
- if (hWnd == IntGetDesktopWindow())\r
- {\r
- hRgnVisible = \r
- NtGdiCreateRectRgn(0, 0, \r
- NtUserGetSystemMetrics(SM_CXSCREEN),\r
- NtUserGetSystemMetrics(SM_CYSCREEN));\r
- }\r
- else\r
- {\r
- hRgnVisible = DceGetVisRgn(hWnd, Flags, 0, 0);\r
- }\r
- }\r
-\r
- if (0 != (Flags & DCX_INTERSECTRGN))\r
- {\r
- NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND);\r
- }\r
-\r
- if (0 != (Flags & DCX_EXCLUDERGN))\r
- {\r
- NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_DIFF);\r
- }\r
-\r
- Dce->DCXFlags &= ~DCX_DCEDIRTY;\r
- NtGdiSelectVisRgn(Dce->hDC, hRgnVisible);\r
- }\r
-\r
- if (hRgnVisible != NULL)\r
- {\r
- NtGdiDeleteObject(hRgnVisible);\r
- }\r
- if (NULL != Window)\r
- {\r
- IntReleaseWindowObject(Window);\r
- }\r
-\r
- return(Dce->hDC);\r
-}\r
-\r
-BOOL FASTCALL\r
-DCE_InternalDelete(PDCE Dce)\r
-{\r
- PDCE PrevInList;\r
-\r
- if (Dce == FirstDce)\r
- {\r
- FirstDce = Dce->next;\r
- PrevInList = Dce;\r
- }\r
- else\r
- {\r
- for (PrevInList = FirstDce; NULL != PrevInList; PrevInList = PrevInList->next)\r
- {\r
- if (Dce == PrevInList->next)\r
- {\r
- PrevInList->next = Dce->next;\r
- break;\r
- }\r
- }\r
- assert(NULL != PrevInList);\r
- }\r
-\r
- return NULL != PrevInList;\r
-}\r
-\r
-HWND FASTCALL\r
-IntWindowFromDC(HDC hDc)\r
-{\r
- DCE *Dce;\r
- for (Dce = FirstDce; Dce != NULL; Dce = Dce->next)\r
- {\r
- if(Dce->hDC == hDc)\r
- {\r
- return Dce->hwndCurrent;\r
- }\r
- }\r
- return 0;\r
-}\r
-\r
-INT STDCALL\r
-NtUserReleaseDC(HWND hWnd, HDC hDc)\r
-{\r
- DCE *dce;\r
- INT nRet = 0;\r
-\r
- /* FIXME USER_Lock(); */\r
- dce = FirstDce;\r
-\r
- DPRINT("%p %p\n", hWnd, hDc);\r
-\r
- while (dce && (dce->hDC != hDc))\r
- {\r
- dce = dce->next;\r
- }\r
-\r
- if (dce && (dce->DCXFlags & DCX_DCEBUSY))\r
- {\r
- nRet = DceReleaseDC(dce);\r
- }\r
-\r
- /* FIXME USER_Unlock(); */\r
-\r
- return nRet;\r
-}\r
- \r
-\r
-/* EOF */\r
+/*
+ * ReactOS W32 Subsystem
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: windc.c,v 1.30 2003/10/06 18:49:50 navaraf Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Window classes
+ * FILE: subsys/win32k/ntuser/class.c
+ * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * REVISION HISTORY:
+ * 06-06-2001 CSH Created
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ddk/ntddk.h>
+#include <win32k/win32k.h>
+#include <win32k/region.h>
+#include <include/class.h>
+#include <include/error.h>
+#include <include/winsta.h>
+#include <include/msgqueue.h>
+#include <include/window.h>
+#include <include/rect.h>
+#include <include/dce.h>
+#include <include/vis.h>
+#include <include/object.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+static PDCE FirstDce = NULL;
+static HDC defaultDCstate;
+
+#define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \
+ DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)
+
+/* FUNCTIONS *****************************************************************/
+
+HRGN STDCALL
+DceGetVisRgn(HWND hWnd, ULONG Flags, HWND hWndChild, ULONG CFlags)
+{
+ PWINDOW_OBJECT Window;
+ PWINDOW_OBJECT Child;
+ HRGN VisRgn;
+ HRGN VisChild;
+ HRGN ChildRect;
+ HRGN ParentRect;
+
+ Window = IntGetWindowObject(hWnd);
+
+ if (NULL == Window)
+ {
+ return NULL;
+ }
+
+ VisRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop, Window,
+ 0 == (Flags & DCX_WINDOW),
+ 0 != (Flags & DCX_CLIPCHILDREN),
+ 0 != (Flags & DCX_CLIPSIBLINGS));
+ if (NULL != hWndChild && 0 != (CFlags & DCX_CLIPCHILDREN))
+ {
+ /* We need to filter out the child windows of hWndChild */
+ Child = IntGetWindowObject(hWnd);
+ if (NULL != Child)
+ {
+ if (Child->FirstChild)
+ {
+ /* Compute the visible region of the child */
+ VisChild = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
+ Child, FALSE, TRUE, FALSE);
+ /* If the child doesn't obscure the whole window, we need to
+ extend it. First compute the difference between window and child */
+ ChildRect = UnsafeIntCreateRectRgnIndirect(&(Child->ClientRect));
+ if (0 == (Flags & DCX_WINDOW))
+ {
+ ParentRect = UnsafeIntCreateRectRgnIndirect(&(Window->ClientRect));
+ }
+ else
+ {
+ ParentRect = UnsafeIntCreateRectRgnIndirect(&(Window->WindowRect));
+ }
+ NtGdiCombineRgn(ChildRect, ParentRect, ChildRect, RGN_DIFF);
+
+ /* Now actually extend the child by adding the difference */
+ NtGdiCombineRgn(VisChild, VisChild, ChildRect, RGN_OR);
+
+ /* Clip the childs children */
+ NtGdiCombineRgn(VisRgn, VisRgn, VisChild, RGN_AND);
+ }
+ IntReleaseWindowObject(Child);
+ }
+ }
+
+ IntReleaseWindowObject(Window);
+
+ return VisRgn;
+}
+
+HDC STDCALL
+NtUserGetDC(HWND hWnd)
+{
+ return NtUserGetDCEx(hWnd, NULL, NULL == hWnd ? DCX_CACHE | DCX_WINDOW : DCX_USESTYLE);
+}
+
+PDCE FASTCALL
+DceAllocDCE(HWND hWnd, DCE_TYPE Type)
+{
+ HDCE DceHandle;
+ DCE* Dce;
+
+ DceHandle = DCEOBJ_AllocDCE();
+ if(!DceHandle)
+ return NULL;
+
+ Dce = DCEOBJ_LockDCE(DceHandle);
+ Dce->hDC = NtGdiCreateDC(L"DISPLAY", NULL, NULL, NULL);
+ if (NULL == defaultDCstate)
+ {
+ defaultDCstate = NtGdiGetDCState(Dce->hDC);
+ GDIOBJ_MarkObjectGlobal(defaultDCstate);
+ }
+ Dce->hwndCurrent = hWnd;
+ Dce->hClipRgn = NULL;
+ Dce->next = FirstDce;
+ FirstDce = Dce;
+
+ if (Type != DCE_CACHE_DC)
+ {
+ Dce->DCXFlags = DCX_DCEBUSY;
+ if (hWnd != NULL)
+ {
+ PWINDOW_OBJECT WindowObject;
+
+ WindowObject = IntGetWindowObject(hWnd);
+ if (WindowObject->Style & WS_CLIPCHILDREN)
+ {
+ Dce->DCXFlags |= DCX_CLIPCHILDREN;
+ }
+ if (WindowObject->Style & WS_CLIPSIBLINGS)
+ {
+ Dce->DCXFlags |= DCX_CLIPSIBLINGS;
+ }
+ IntReleaseWindowObject(WindowObject);
+ }
+ }
+ else
+ {
+ Dce->DCXFlags = DCX_CACHE | DCX_DCEEMPTY;
+ }
+
+ return(Dce);
+}
+
+VOID STATIC STDCALL
+DceSetDrawable(PWINDOW_OBJECT WindowObject, HDC hDC, ULONG Flags,
+ BOOL SetClipOrigin)
+{
+ DC *dc = DC_LockDc(hDC);
+ if(!dc)
+ return;
+
+ if (WindowObject == NULL)
+ {
+ dc->w.DCOrgX = 0;
+ dc->w.DCOrgY = 0;
+ }
+ else
+ {
+ if (Flags & DCX_WINDOW)
+ {
+ dc->w.DCOrgX = WindowObject->WindowRect.left;
+ dc->w.DCOrgY = WindowObject->WindowRect.top;
+ }
+ else
+ {
+ dc->w.DCOrgX = WindowObject->ClientRect.left;
+ dc->w.DCOrgY = WindowObject->ClientRect.top;
+ }
+ }
+ DC_UnlockDc(hDC);
+}
+
+
+STATIC VOID FASTCALL
+DceDeleteClipRgn(DCE* Dce)
+{
+ Dce->DCXFlags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN | DCX_WINDOWPAINT);
+
+ if (Dce->DCXFlags & DCX_KEEPCLIPRGN )
+ {
+ Dce->DCXFlags &= ~DCX_KEEPCLIPRGN;
+ }
+ else if (Dce->hClipRgn > (HRGN) 1)
+ {
+ NtGdiDeleteObject(Dce->hClipRgn);
+ }
+
+ Dce->hClipRgn = NULL;
+
+ /* make it dirty so that the vis rgn gets recomputed next time */
+ Dce->DCXFlags |= DCX_DCEDIRTY;
+}
+
+STATIC INT FASTCALL
+DceReleaseDC(DCE* dce)
+{
+ if (DCX_DCEBUSY != (dce->DCXFlags & (DCX_DCEEMPTY | DCX_DCEBUSY)))
+ {
+ return 0;
+ }
+
+ /* restore previous visible region */
+
+ if ((dce->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&
+ (dce->DCXFlags & (DCX_CACHE | DCX_WINDOWPAINT)) )
+ {
+ DceDeleteClipRgn( dce );
+ }
+
+ if (dce->DCXFlags & DCX_CACHE)
+ {
+ /* make the DC clean so that SetDCState doesn't try to update the vis rgn */
+ NtGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);
+ NtGdiSetDCState(dce->hDC, defaultDCstate);
+ dce->DCXFlags &= ~DCX_DCEBUSY;
+ if (dce->DCXFlags & DCX_DCEDIRTY)
+ {
+ /* don't keep around invalidated entries
+ * because SetDCState() disables hVisRgn updates
+ * by removing dirty bit. */
+ dce->hwndCurrent = 0;
+ dce->DCXFlags &= DCX_CACHE;
+ dce->DCXFlags |= DCX_DCEEMPTY;
+ }
+ }
+
+ return 1;
+}
+
+HDC STDCALL
+NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
+{
+ PWINDOW_OBJECT Window;
+ ULONG DcxFlags;
+ DCE* Dce;
+ BOOL UpdateVisRgn = TRUE;
+ BOOL UpdateClipOrigin = FALSE;
+ HANDLE hRgnVisible = NULL;
+
+ if (NULL == hWnd)
+ {
+ Flags &= ~DCX_USESTYLE;
+ Window = NULL;
+ }
+ else if (NULL == (Window = IntGetWindowObject(hWnd)))
+ {
+ return(0);
+ }
+
+ if (NULL == Window || NULL == Window->Dce)
+ {
+ Flags |= DCX_CACHE;
+ }
+
+
+ if (Flags & DCX_USESTYLE)
+ {
+ Flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | DCX_PARENTCLIP);
+
+ if (Window->Style & WS_CLIPSIBLINGS)
+ {
+ Flags |= DCX_CLIPSIBLINGS;
+ }
+
+ if (!(Flags & DCX_WINDOW))
+ {
+ if (Window->Class->style & CS_PARENTDC)
+ {
+ Flags |= DCX_PARENTCLIP;
+ }
+
+ if (Window->Style & WS_CLIPCHILDREN &&
+ !(Window->Style & WS_MINIMIZE))
+ {
+ Flags |= DCX_CLIPCHILDREN;
+ }
+ }
+ else
+ {
+ Flags |= DCX_CACHE;
+ }
+ }
+
+ if (Flags & DCX_NOCLIPCHILDREN)
+ {
+ Flags |= DCX_CACHE;
+ Flags |= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
+ }
+
+ if (Flags & DCX_WINDOW)
+ {
+ Flags = (Flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
+ }
+
+ if (NULL == Window || !(Window->Style & WS_CHILD) || NULL == Window->Parent)
+ {
+ Flags &= ~DCX_PARENTCLIP;
+ }
+ else if (Flags & DCX_PARENTCLIP)
+ {
+ Flags |= DCX_CACHE;
+ if (!(Flags & (DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS)))
+ {
+ if ((Window->Style & WS_VISIBLE) &&
+ (Window->Parent->Style & WS_VISIBLE))
+ {
+ Flags &= ~DCX_CLIPCHILDREN;
+ if (Window->Parent->Style & WS_CLIPSIBLINGS)
+ {
+ Flags |= DCX_CLIPSIBLINGS;
+ }
+ }
+ }
+ }
+
+ DcxFlags = Flags & DCX_CACHECOMPAREMASK;
+
+ if (Flags & DCX_CACHE)
+ {
+ DCE* DceEmpty = NULL;
+ DCE* DceUnused = NULL;
+
+ for (Dce = FirstDce; Dce != NULL; Dce = Dce->next)
+ {
+ if ((Dce->DCXFlags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE)
+ {
+ DceUnused = Dce;
+ if (Dce->DCXFlags & DCX_DCEEMPTY)
+ {
+ DceEmpty = Dce;
+ }
+ else if (Dce->hwndCurrent == hWnd &&
+ ((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags))
+ {
+#if 0 /* FIXME */
+ UpdateVisRgn = FALSE;
+#endif
+ UpdateClipOrigin = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (Dce == NULL)
+ {
+ Dce = (DceEmpty == NULL) ? DceEmpty : DceUnused;
+ }
+
+ if (Dce == NULL)
+ {
+ Dce = DceAllocDCE(NULL, DCE_CACHE_DC);
+ }
+ }
+ else
+ {
+ Dce = Window->Dce;
+ /* FIXME: Implement this. */
+ DbgBreakPoint();
+ }
+
+ if (NULL == Dce)
+ {
+ if(NULL != Window)
+ IntReleaseWindowObject(Window);
+ return(NULL);
+ }
+
+ Dce->hwndCurrent = hWnd;
+ Dce->hClipRgn = NULL;
+ Dce->DCXFlags = DcxFlags | (Flags & DCX_WINDOWPAINT) | DCX_DCEBUSY;
+
+ if (0 == (Flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) && NULL != ClipRegion)
+ {
+ NtGdiDeleteObject(ClipRegion);
+ ClipRegion = NULL;
+ }
+
+ if (NULL != Dce->hClipRgn)
+ {
+ DceDeleteClipRgn(Dce);
+ }
+
+ if (NULL != ClipRegion)
+ {
+ Dce->hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+ if(Dce->hClipRgn)
+ NtGdiCombineRgn(Dce->hClipRgn, ClipRegion, NULL, RGN_COPY);
+ NtGdiDeleteObject(ClipRegion);
+ }
+
+ DceSetDrawable(Window, Dce->hDC, Flags, UpdateClipOrigin);
+
+ if (UpdateVisRgn)
+ {
+ if (Flags & DCX_PARENTCLIP)
+ {
+ PWINDOW_OBJECT Parent;
+
+ Parent = Window->Parent;
+
+ if (Window->Style & WS_VISIBLE &&
+ !(Parent->Style & WS_MINIMIZE))
+ {
+ if (Parent->Style & WS_CLIPSIBLINGS)
+ {
+ DcxFlags = DCX_CLIPSIBLINGS |
+ (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
+ }
+ else
+ {
+ DcxFlags = Flags &
+ ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
+ }
+ hRgnVisible = DceGetVisRgn(Parent->Self, DcxFlags,
+ Window->Self, Flags);
+ }
+ else
+ {
+ hRgnVisible = NtGdiCreateRectRgn(0, 0, 0, 0);
+ }
+ }
+ else
+ {
+ if (hWnd == IntGetDesktopWindow())
+ {
+ hRgnVisible =
+ NtGdiCreateRectRgn(0, 0,
+ NtUserGetSystemMetrics(SM_CXSCREEN),
+ NtUserGetSystemMetrics(SM_CYSCREEN));
+ }
+ else
+ {
+ hRgnVisible = DceGetVisRgn(hWnd, Flags, 0, 0);
+ }
+ }
+
+ if (0 != (Flags & DCX_INTERSECTRGN))
+ {
+ NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND);
+ }
+
+ if (0 != (Flags & DCX_EXCLUDERGN))
+ {
+ NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_DIFF);
+ }
+
+ Dce->DCXFlags &= ~DCX_DCEDIRTY;
+ NtGdiSelectVisRgn(Dce->hDC, hRgnVisible);
+ }
+
+ if (hRgnVisible != NULL)
+ {
+ NtGdiDeleteObject(hRgnVisible);
+ }
+ if (NULL != Window)
+ {
+ IntReleaseWindowObject(Window);
+ }
+
+ return(Dce->hDC);
+}
+
+BOOL FASTCALL
+DCE_InternalDelete(PDCE Dce)
+{
+ PDCE PrevInList;
+
+ if (Dce == FirstDce)
+ {
+ FirstDce = Dce->next;
+ PrevInList = Dce;
+ }
+ else
+ {
+ for (PrevInList = FirstDce; NULL != PrevInList; PrevInList = PrevInList->next)
+ {
+ if (Dce == PrevInList->next)
+ {
+ PrevInList->next = Dce->next;
+ break;
+ }
+ }
+ assert(NULL != PrevInList);
+ }
+
+ return NULL != PrevInList;
+}
+
+HWND FASTCALL
+IntWindowFromDC(HDC hDc)
+{
+ DCE *Dce;
+ for (Dce = FirstDce; Dce != NULL; Dce = Dce->next)
+ {
+ if(Dce->hDC == hDc)
+ {
+ return Dce->hwndCurrent;
+ }
+ }
+ return 0;
+}
+
+INT STDCALL
+NtUserReleaseDC(HWND hWnd, HDC hDc)
+{
+ DCE *dce;
+ INT nRet = 0;
+
+ /* FIXME USER_Lock(); */
+ dce = FirstDce;
+
+ DPRINT("%p %p\n", hWnd, hDc);
+
+ while (dce && (dce->hDC != hDc))
+ {
+ dce = dce->next;
+ }
+
+ if (dce && (dce->DCXFlags & DCX_DCEBUSY))
+ {
+ nRet = DceReleaseDC(dce);
+ }
+
+ /* FIXME USER_Unlock(); */
+
+ return nRet;
+}
+
+
+/* EOF */