Index: reactos/win32ss/gdi/gdi32/objects/colorspace.c =================================================================== --- reactos/win32ss/gdi/gdi32/objects/colorspace.c (revision 72796) +++ reactos/win32ss/gdi/gdi32/objects/colorspace.c (working copy) @@ -9,14 +9,38 @@ BOOL WINAPI GetLogColorSpaceA( - HCOLORSPACE a0, - LPLOGCOLORSPACEA a1, - DWORD a2 -) + HCOLORSPACE hColorSpace, + LPLOGCOLORSPACEA lpbuffer, + DWORD nSize) { - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + LOGCOLORSPACEW LogW; + BOOL Ret = FALSE; + + if (!GetLogColorSpaceW(hColorSpace, &LogW, sizeof(LogW))) + return FALSE; + + _SEH2_TRY + { + lpbuffer->lcsSignature = LogW.lcsSignature; + lpbuffer->lcsVersion = LogW.lcsVersion; + lpbuffer->lcsSize = sizeof(LOGCOLORSPACEA); + lpbuffer->lcsCSType = LogW.lcsCSType; + lpbuffer->lcsIntent = LogW.lcsIntent; + lpbuffer->lcsEndpoints = LogW.lcsEndpoints; + lpbuffer->lcsGammaRed = LogW.lcsGammaRed; + lpbuffer->lcsGammaGreen = LogW.lcsGammaGreen; + lpbuffer->lcsGammaBlue = LogW.lcsGammaBlue; + lpbuffer->lcsFilename[0] = '\0'; + WideCharToMultiByte(CP_ACP, 0, LogW.lcsFilename, -1, + lpbuffer->lcsFilename, MAX_PATH, NULL, NULL); + Ret = TRUE; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END + + return Ret; } @@ -26,14 +50,25 @@ BOOL WINAPI GetLogColorSpaceW( - HCOLORSPACE a0, - LPLOGCOLORSPACEW a1, - DWORD a2 + HCOLORSPACE hColorSpace, + LPLOGCOLORSPACEW lpbuffer, + DWORD nSize ) { - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + if (nSize < sizeof(LOGCOLORSPACEW) || lpbuffer == NULL) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + if (GetObjectType(hColorSpace) != OBJ_COLORSPACE) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + GetObject(hColorSpace, sizeof(LOGCOLORSPACEW), lpbuffer); + return TRUE; } /* Index: reactos/win32ss/gdi/gdi32/objects/gdiobj.c =================================================================== --- reactos/win32ss/gdi/gdi32/objects/gdiobj.c (revision 72796) +++ reactos/win32ss/gdi/gdi32/objects/gdiobj.c (working copy) @@ -226,7 +226,7 @@ break; case GDI_OBJECT_TYPE_COLORSPACE: - if ((cbSize < 328) || !lpBuffer) + if ((cbSize < sizeof(LOGCOLORSPACEW)) || !lpBuffer) { SetLastError(ERROR_INSUFFICIENT_BUFFER); return 0; Index: reactos/win32ss/gdi/ntgdi/color.h =================================================================== --- reactos/win32ss/gdi/ntgdi/color.h (revision 72796) +++ reactos/win32ss/gdi/ntgdi/color.h (working copy) @@ -28,3 +28,6 @@ extern HCOLORSPACE hStockColorSpace; UINT FASTCALL IntGdiRealizePalette (HDC); + +ULONG FASTCALL +COLORSPACE_GetObject(PCOLORSPACE pcs, ULONG cjBuffer, PVOID pvBuffer); Index: reactos/win32ss/gdi/ntgdi/gdiobj.c =================================================================== --- reactos/win32ss/gdi/ntgdi/gdiobj.c (revision 72796) +++ reactos/win32ss/gdi/ntgdi/gdiobj.c (working copy) @@ -1271,18 +1271,26 @@ if (objt != GDIObjType_BRUSH_TYPE && objt != GDIObjType_SURF_TYPE && objt != GDIObjType_LFONT_TYPE && - objt != GDIObjType_PAL_TYPE) + objt != GDIObjType_PAL_TYPE && + objt != GDIObjType_ICMLCS_TYPE) { - DPRINT1("GreGetObject: Invalid object type\n"); + DPRINT1("GreGetObject: Invalid object type: %d\n", objt); return 0; } - pvObj = GDIOBJ_ReferenceObjectByHandle(hobj, objt); - if (!pvObj) + if (objt == GDIObjType_ICMLCS_TYPE) { - DPRINT("GreGetObject: Could not lock object\n"); - return 0; + /* TODO & FIXME: COLORSPACE */ } + else + { + pvObj = GDIOBJ_ReferenceObjectByHandle(hobj, objt); + if (!pvObj) + { + DPRINT("GreGetObject: Could not lock object\n"); + return 0; + } + } switch (GDI_HANDLE_GET_TYPE(hobj)) { @@ -1307,6 +1315,10 @@ iResult = PALETTE_GetObject(pvObj, cbCount, pvBuffer); break; + case GDIObjType_ICMLCS_TYPE: + iResult = COLORSPACE_GetObject(pvObj, cbCount, pvBuffer); + break; + default: DPRINT1("GDI object type of 0x%p not implemented\n", hobj); break; @@ -1334,6 +1346,7 @@ LOGFONTW logfontw; EXTLOGFONTW extlogfontw; ENUMLOGFONTEXDVW enumlogfontexdvw; + LOGCOLORSPACEW logcolorspacew; } object; /* Normalize to the largest supported object size */ Index: reactos/win32ss/gdi/ntgdi/icm.c =================================================================== --- reactos/win32ss/gdi/ntgdi/icm.c (revision 72796) +++ reactos/win32ss/gdi/ntgdi/icm.c (working copy) @@ -13,7 +13,22 @@ HCOLORSPACE hStockColorSpace = NULL; +ULONG +FASTCALL +COLORSPACE_GetObject(PCOLORSPACE pcs, ULONG cjBuffer, PVOID pvBuffer) +{ + /* If buffer is NULL, only the size is requested */ + if (pvBuffer == NULL) + return sizeof(LOGCOLORSPACEW); + if (cjBuffer > sizeof(LOGCOLORSPACEW)) + cjBuffer = sizeof(LOGCOLORSPACEW); + + RtlCopyMemory(pvBuffer, &pcs->lcsColorSpace, cjBuffer); + + return cjBuffer; +} + HCOLORSPACE FASTCALL IntGdiCreateColorSpace( Index: rostests/apitests/gdi32/GetObject.c =================================================================== --- rostests/apitests/gdi32/GetObject.c (revision 72796) +++ rostests/apitests/gdi32/GetObject.c (working copy) @@ -654,6 +654,92 @@ //ok_long(GetObjectA((HANDLE)GDI_OBJECT_TYPE_COLORSPACE, 328, NULL), 0); // FIXME: fails on WHS //ok_err(ERROR_INSUFFICIENT_BUFFER); + + { + LOGCOLORSPACEA LogA; + LOGCOLORSPACEW LogW; + BOOL ret; + DWORD err; + HCOLORSPACE hCS; + HDC hdc; + DWORD type; + + hdc = CreateCompatibleDC(NULL); + hCS = GetColorSpace(hdc); + ok(hCS != NULL, "\n"); + type = GetObjectType(hCS); + ok(type == OBJ_COLORSPACE, "\n"); + type = GetObjectType((HANDLE)GDI_OBJECT_TYPE_COLORSPACE); + ok(type != OBJ_COLORSPACE, "\n"); + + memset(&LogA, 0xDE, sizeof(LogA)); + ret = GetObjectA(hCS, sizeof(LOGCOLORSPACEA), &LogA); + ok(LogA.lcsSize == sizeof(LOGCOLORSPACEA), "\n"); + + memset(&LogA, 0xDE, sizeof(LogA)); + SetLastError(123456); + ret = GetLogColorSpaceA(hCS, &LogA, sizeof(LOGCOLORSPACEA)); + err = GetLastError(); + ok(ret == TRUE, "\n"); + ok(err == 123456, "\n"); + ok(LogA.lcsSize == sizeof(LOGCOLORSPACEA), "\n"); + + memset(&LogA, 0xDE, sizeof(LogA)); + SetLastError(123456); + ret = GetLogColorSpaceA(NULL, &LogA, sizeof(LOGCOLORSPACEA)); + err = GetLastError(); + ok(ret == FALSE, "\n"); + ok(err == ERROR_INVALID_PARAMETER, "%ld\n", err); + + memset(&LogA, 0xDE, sizeof(LogA)); + SetLastError(123456); + ret = GetLogColorSpaceA(hCS, NULL, sizeof(LOGCOLORSPACEA)); + err = GetLastError(); + ok(ret == FALSE, "\n"); + ok(err == ERROR_INSUFFICIENT_BUFFER, "%ld\n", err); + + memset(&LogA, 0xDE, sizeof(LogA)); + SetLastError(123456); + ret = GetLogColorSpaceA(NULL, NULL, sizeof(LOGCOLORSPACEA)); + err = GetLastError(); + ok(ret == FALSE, "\n"); + ok(err == ERROR_INSUFFICIENT_BUFFER, "%ld\n", err); + + memset(&LogW, 0xDE, sizeof(LogW)); + ret = GetObjectW(hCS, sizeof(LOGCOLORSPACEW), &LogW); + ok(LogW.lcsSize == sizeof(LOGCOLORSPACEW), "\n"); + + memset(&LogW, 0xDE, sizeof(LogW)); + SetLastError(123456); + ret = GetLogColorSpaceW(hCS, &LogW, sizeof(LOGCOLORSPACEW)); + err = GetLastError(); + ok(ret == TRUE, "\n"); + ok(err == 123456, "\n"); + ok(LogW.lcsSize == sizeof(LOGCOLORSPACEW), "\n"); + + memset(&LogW, 0xDE, sizeof(LogW)); + SetLastError(123456); + ret = GetLogColorSpaceW(NULL, &LogW, sizeof(LOGCOLORSPACEW)); + err = GetLastError(); + ok(ret == FALSE, "\n"); + ok(err == ERROR_INVALID_PARAMETER, "%ld\n", err); + + memset(&LogW, 0xDE, sizeof(LogW)); + SetLastError(123456); + ret = GetLogColorSpaceW(hCS, NULL, sizeof(LOGCOLORSPACEW)); + err = GetLastError(); + ok(ret == FALSE, "\n"); + ok(err == ERROR_INSUFFICIENT_BUFFER, "%ld\n", err); + + memset(&LogW, 0xDE, sizeof(LogW)); + SetLastError(123456); + ret = GetLogColorSpaceW(NULL, NULL, sizeof(LOGCOLORSPACEW)); + err = GetLastError(); + ok(ret == FALSE, "\n"); + ok(err == ERROR_INSUFFICIENT_BUFFER, "%ld\n", err); + + DeleteDC(hdc); + } } void