Author: tretiakov Date: Thu Mar 8 16:31:33 2007 New Revision: 26029
URL: http://svn.reactos.org/svn/reactos?rev=26029&view=rev Log: Merge clipboard branch to trunk
Modified: trunk/reactos/base/applications/regedit/childwnd.c trunk/reactos/dll/win32/shell32/shfldr_fs.c trunk/reactos/dll/win32/shell32/shlfileop.c trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c trunk/reactos/dll/win32/shell32/shv_item_cmenu.c trunk/reactos/dll/win32/user32/include/user32p.h trunk/reactos/dll/win32/user32/windows/clipboard.c trunk/reactos/dll/win32/user32/windows/defwnd.c trunk/reactos/include/psdk/winuser.h trunk/reactos/include/reactos/win32k/ntuser.h trunk/reactos/subsystems/win32/win32k/include/clipboard.h trunk/reactos/subsystems/win32/win32k/include/winsta.h trunk/reactos/subsystems/win32/win32k/ntuser/clipboard.c trunk/reactos/subsystems/win32/win32k/ntuser/misc.c trunk/reactos/subsystems/win32/win32k/ntuser/useratom.c trunk/reactos/subsystems/win32/win32k/ntuser/window.c trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c trunk/reactos/tools/nci/w32ksvc.db
Modified: trunk/reactos/base/applications/regedit/childwnd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/regedit/c... ============================================================================== --- trunk/reactos/base/applications/regedit/childwnd.c (original) +++ trunk/reactos/base/applications/regedit/childwnd.c Thu Mar 8 16:31:33 2007 @@ -431,8 +431,8 @@ TCHAR szBuffer[MAX_PATH]; _sntprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), _T("My Computer\%s\%s"), rootName, keyPath);
- if (RegOpenKey(HKEY_CURRENT_USER, - _T("Software\Microsoft\Windows\CurrentVersion\Applets\Regedit"), + if (RegCreateKey(HKEY_CURRENT_USER, + g_szGeneralRegKey, &hKey) == ERROR_SUCCESS) { RegSetValueEx(hKey, _T("LastKey"), 0, REG_SZ, (LPBYTE) szBuffer, (DWORD) _tcslen(szBuffer) * sizeof(szBuffer[0]));
Modified: trunk/reactos/dll/win32/shell32/shfldr_fs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shfldr_fs... ============================================================================== --- trunk/reactos/dll/win32/shell32/shfldr_fs.c (original) +++ trunk/reactos/dll/win32/shell32/shfldr_fs.c Thu Mar 8 16:31:33 2007 @@ -1,4 +1,3 @@ - /* * file system folder * @@ -54,6 +53,8 @@ #include "shfldr.h"
WINE_DEFAULT_DEBUG_CHANNEL (shell); + +extern BOOL fileMoving;
/*********************************************************************** * IShellFolder implementation @@ -1232,11 +1233,14 @@
IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2, (LPVOID *) & ppf2); - if (ppf2) { + if (ppf2) + { LPITEMIDLIST pidl;
- if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) { - for (i = 0; i < cidl; i++) { + if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) + { + for (i = 0; i < cidl; i++) + { SHGetPathFromIDListA (pidl, szSrcPath); PathAddBackslashA (szSrcPath); _ILSimpleGetText (apidl[i], szSrcPath + strlen (szSrcPath), @@ -1246,7 +1250,43 @@ PathAddBackslashA (szDstPath); _ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath), MAX_PATH); - MESSAGE ("would copy %s to %s\n", szSrcPath, szDstPath); + _ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath), MAX_PATH); + DPRINT1 ("copy %s to %s\n", szSrcPath, szDstPath); + + if (fileMoving) + { + fileMoving = FALSE; + SHNotifyMoveFileA(szSrcPath, szDstPath); + } + else + { + SHNotifyCopyFileA(szSrcPath, szDstPath, TRUE); + } + + /* FIXME: to work with folders we need SHFileOperation! + SHFILEOPSTRUCTA op; + + if (fileMoving) + { + op.wFunc = FO_MOVE; + fileMoving = FALSE; + } + else + { + op.wFunc = FO_COPY; + } + + op.pTo = szDstPath; + op.pFrom = szSrcPath; + op.fFlags = FOF_SIMPLEPROGRESS; + op.hwnd = NULL; + op.hNameMappings = NULL; + op.lpszProgressTitle = NULL; + + UINT bRes = SHFileOperationA(&op); + DbgPrint("CopyItems SHFileOperationA 0x%08x\n", bRes); + */ + } SHFree (pidl); }
Modified: trunk/reactos/dll/win32/shell32/shlfileop.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfileop... ============================================================================== --- trunk/reactos/dll/win32/shell32/shlfileop.c (original) +++ trunk/reactos/dll/win32/shell32/shlfileop.c Thu Mar 8 16:31:33 2007 @@ -478,6 +478,65 @@ return GetLastError(); }
+DWORD SHNotifyMoveFileA(LPCSTR src, LPCSTR dest) +{ + BOOL ret; + LPWSTR destW; + + ret = MoveFileA(src, dest); + if (!ret) + { + DWORD dwAttr; + + SHELL32_AnsiToUnicodeBuf(dest, &destW, 0); + dwAttr = SHFindAttrW(destW, FALSE); + SHELL32_FreeUnicodeBuf(destW); + if (INVALID_FILE_ATTRIBUTES == dwAttr) + { + /* Source file may be write protected or a system file */ + dwAttr = GetFileAttributesA(src); + if (IsAttrib(dwAttr, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)) + if (SetFileAttributesA(src, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))) + ret = MoveFileA(src, dest); + } + } + if (ret) + { + //SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATHA, src, dest); + SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, dest, NULL); + SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, src, NULL); + return ERROR_SUCCESS; + } + return GetLastError(); +} + +/************************************************************************ + * SHNotifyCopyFile [internal] + * + * Copies a file. Also triggers a change notify if one exists. + * + * PARAMS + * src [I] path to source file to move + * dest [I] path to target file to move to + * bFailIfExists [I] if TRUE, the target file will not be overwritten if + * a file with this name already exists + * + * RETURNS + * ERROR_SUCCESS if successful + */ +DWORD SHNotifyCopyFileA(LPCSTR src, LPCSTR dest, BOOL bFailIfExists) +{ + BOOL ret; + + ret = CopyFileA(src, dest, bFailIfExists); + if (ret) + { + SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, dest, NULL); + return ERROR_SUCCESS; + } + return GetLastError(); +} + /************************************************************************* * SHCreateDirectory [SHELL32.165] * @@ -649,6 +708,30 @@ } return dwAttr; } + +/* +DWORD SHFindAttrA(LPSTR pName, BOOL fileOnly) +{ + WIN32_FIND_DATAA wfd; + BOOL b_FileMask = fileOnly && (NULL != StrPBrkA(pName, wWildcardChars)); + DWORD dwAttr = INVALID_FILE_ATTRIBUTES; + HANDLE hFind = FindFirstFileA(pName, &wfd); + + if (INVALID_HANDLE_VALUE != hFind) + { + do + { + if (b_FileMask && IsAttribDir(wfd.dwFileAttributes)) + continue; + dwAttr = wfd.dwFileAttributes; + break; + } + while (FindNextFileA(hFind, &wfd)); + FindClose(hFind); + } + return dwAttr; +} +*/
/************************************************************************* *
Modified: trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_bg_cm... ============================================================================== --- trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c (original) +++ trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c Thu Mar 8 16:31:33 2007 @@ -18,6 +18,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include <string.h>
#define COBJMACROS @@ -37,6 +38,8 @@ #include "undocshell.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell); + +extern BOOL fileMoving;
/************************************************************************** * IContextMenu Implementation @@ -215,6 +218,192 @@ } }
+/***************************************************************************/ +static BOOL DoLink(LPCSTR pSrcFile, LPCSTR pDstFile) +{ + IShellLinkA *psl = NULL; + IPersistFile *pPf = NULL; + HRESULT hres; + WCHAR widelink[MAX_PATH]; + BOOL ret = FALSE; + + CoInitialize(0); + + hres = CoCreateInstance( &CLSID_ShellLink, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IShellLinkA, + (LPVOID )&psl); + + if(SUCCEEDED(hres)) + { + hres = IShellLinkA_QueryInterface(psl, &IID_IPersistFile, (LPVOID *)&pPf); + if(FAILED(hres)) + { + ERR("failed QueryInterface for IPersistFile %08lx\n", hres); + goto fail; + } + + DPRINT1("shortcut point to %s\n", pSrcFile); + + hres = IShellLinkA_SetPath(psl, pSrcFile); + + if(FAILED(hres)) + { + ERR("failed Set{IDList|Path} %08lx\n", hres); + goto fail; + } + + MultiByteToWideChar(CP_ACP, 0, pDstFile, -1, widelink, MAX_PATH); + + /* create the short cut */ + hres = IPersistFile_Save(pPf, widelink, TRUE); + + if(FAILED(hres)) + { + ERR("failed IPersistFile::Save %08lx\n", hres); + IPersistFile_Release(pPf); + IShellLinkA_Release(psl); + goto fail; + } + + hres = IPersistFile_SaveCompleted(pPf, widelink); + IPersistFile_Release(pPf); + IShellLinkA_Release(psl); + DPRINT1("shortcut %s has been created, result=%08lx\n", pDstFile, hres); + ret = TRUE; + } + else + { + DPRINT1("CoCreateInstance failed, hres=%08lx\n", hres); + } + + fail: + CoUninitialize(); + return ret; +} + +static BOOL MakeLink(IContextMenu2 *iface) +{ + + BgCmImpl *This = (BgCmImpl *)iface; + BOOL bSuccess = FALSE; + IDataObject * pda; + + TRACE("\n"); + + if(SUCCEEDED(OleGetClipboard(&pda))) + { + STGMEDIUM medium; + FORMATETC formatetc; + + TRACE("pda=%p\n", pda); + + /* Set the FORMATETC structure*/ + InitFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL); + + /* Get the pidls from IDataObject */ + if(SUCCEEDED(IDataObject_GetData(pda, &formatetc, &medium))) + { + LPITEMIDLIST * apidl; + LPITEMIDLIST pidl; + IShellFolder *psfFrom = NULL, *psfDesktop; + + LPIDA lpcida = GlobalLock(medium.u.hGlobal); + TRACE("cida=%p\n", lpcida); + + apidl = _ILCopyCidaToaPidl(&pidl, lpcida); + + /* bind to the source shellfolder */ + SHGetDesktopFolder(&psfDesktop); + if(psfDesktop) + { + IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom); + IShellFolder_Release(psfDesktop); + } + + if (psfFrom) + { + /* get source and destination shellfolder */ + IPersistFolder2 *ppfdst = NULL; + IPersistFolder2 *ppfsrc = NULL; + IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppfdst); + IShellFolder_QueryInterface(psfFrom, &IID_IPersistFolder2, (LPVOID*)&ppfsrc); + + DPRINT1("[%p,%p]\n",ppfdst,ppfsrc); + + /* do the link/s */ + /* hack to get desktop path */ + if ( (ppfdst && ppfsrc) || (This->bDesktop && ppfsrc) ) + { + int i; + char szSrcPath[MAX_PATH]; + char szDstPath[MAX_PATH]; + BOOL ret = FALSE; + LPITEMIDLIST pidl2; + char filename[MAX_PATH]; + char linkFilename[MAX_PATH]; + char srcFilename[MAX_PATH]; + + IPersistFolder2_GetCurFolder(ppfsrc, &pidl2); + SHGetPathFromIDListA (pidl2, szSrcPath); + + if (This->bDesktop) + { + SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &pidl2); + SHGetPathFromIDListA (pidl2, szDstPath); + } + else + { + IPersistFolder2_GetCurFolder(ppfdst, &pidl2); + SHGetPathFromIDListA (pidl2, szDstPath); + } + + for (i = 0; i < lpcida->cidl; i++) + { + _ILSimpleGetText (apidl[i], filename, MAX_PATH); + + DPRINT1("filename %s\n", filename); + + lstrcpyA(linkFilename, szDstPath); + PathAddBackslashA(linkFilename); + lstrcatA(linkFilename, "Shortcut to "); + lstrcatA(linkFilename, filename); + lstrcatA(linkFilename, ".lnk"); + + DPRINT1("linkFilename %s\n", linkFilename); + + lstrcpyA(srcFilename, szSrcPath); + PathAddBackslashA(srcFilename); + lstrcatA(srcFilename, filename); + + DPRINT1("srcFilename %s\n", srcFilename); + + ret = DoLink(srcFilename, linkFilename); + + if (ret) + { + SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, linkFilename, NULL); + } + } + } + if(ppfdst) IPersistFolder2_Release(ppfdst); + if(ppfsrc) IPersistFolder2_Release(ppfsrc); + IShellFolder_Release(psfFrom); + } + + _ILFreeaPidl(apidl, lpcida->cidl); + SHFree(pidl); + + /* release the medium*/ + ReleaseStgMedium(&medium); + } + IDataObject_Release(pda); + } + return bSuccess; +} + + /************************************************************************** * DoPaste */ @@ -261,16 +450,27 @@ { /* get source and destination shellfolder */ ISFHelper *psfhlpdst, *psfhlpsrc; - IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlpdst); + + if (This->bDesktop) + { + /* unimplemented + SHGetDesktopFolder(&psfDesktop); + IFSFolder_Constructor(psfDesktop, &IID_ISFHelper, (LPVOID*)&psfhlpdst); + IShellFolder_QueryInterface(psfhlpdst, &IID_ISFHelper, (LPVOID*)&psfhlpdst); + */ + IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlpdst); + } + else + { + IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlpdst); + } + IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (LPVOID*)&psfhlpsrc);
/* do the copy/move */ if (psfhlpdst && psfhlpsrc) { ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl); - /* FIXME handle move - ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl); - */ } if(psfhlpdst) ISFHelper_Release(psfhlpdst); if(psfhlpsrc) ISFHelper_Release(psfhlpsrc); @@ -285,30 +485,7 @@ } IDataObject_Release(pda); } -#if 0 - HGLOBAL hMem; - - OpenClipboard(NULL); - hMem = GetClipboardData(CF_HDROP); - - if(hMem) - { - char * pDropFiles = (char *)GlobalLock(hMem); - if(pDropFiles) - { - int len, offset = sizeof(DROPFILESTRUCT); - - while( pDropFiles[offset] != 0) - { - len = strlen(pDropFiles + offset); - TRACE("%s\n", pDropFiles + offset); - offset += len+1; - } - } - GlobalUnlock(hMem); - } - CloseClipboard(); -#endif + return bSuccess; }
@@ -371,6 +548,10 @@
case FCIDM_SHVIEW_INSERT: DoPaste(iface); + break; + + case FCIDM_SHVIEW_INSERTLINK: + MakeLink(iface); break;
case FCIDM_SHVIEW_PROPERTIES:
Modified: trunk/reactos/dll/win32/shell32/shv_item_cmenu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_item_... ============================================================================== --- trunk/reactos/dll/win32/shell32/shv_item_cmenu.c (original) +++ trunk/reactos/dll/win32/shell32/shv_item_cmenu.c Thu Mar 8 16:31:33 2007 @@ -39,6 +39,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+/* ugly hack for cut&psate files */ +BOOL fileMoving = FALSE; + /************************************************************************** * IContextMenu Implementation */ @@ -372,6 +375,8 @@ LPSHELLBROWSER lpSB; LPSHELLVIEW lpSV; LPDATAOBJECT lpDo; + + fileMoving = bCut;
TRACE("(%p)->(wnd=%p,bCut=0x%08x)\n",This, hwnd, bCut);
Modified: trunk/reactos/dll/win32/user32/include/user32p.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/us... ============================================================================== --- trunk/reactos/dll/win32/user32/include/user32p.h (original) +++ trunk/reactos/dll/win32/user32/include/user32p.h Thu Mar 8 16:31:33 2007 @@ -76,8 +76,10 @@ #define NtUserSetCaretBlinkTime(uMSeconds) \ (BOOL)NtUserCallOneParam((DWORD)uMSeconds, ONEPARAM_ROUTINE_SETCARETBLINKTIME)
+/* #define NtUserEnumClipboardFormats(format) \ (UINT)NtUserCallOneParam(format, ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS) +*/
#define NtUserWindowFromDC(hDC) \ (HWND)NtUserCallOneParam((DWORD)hDC, ONEPARAM_ROUTINE_WINDOWFROMDC)
Modified: trunk/reactos/dll/win32/user32/windows/clipboard.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/cl... ============================================================================== --- trunk/reactos/dll/win32/user32/windows/clipboard.c (original) +++ trunk/reactos/dll/win32/user32/windows/clipboard.c Thu Mar 8 16:31:33 2007 @@ -1,37 +1,25 @@ -/* - * 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$ * * PROJECT: ReactOS user32.dll * FILE: lib/user32/windows/clipboard.c * PURPOSE: Input * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + * Pablo Borobia pborobia@gmail.com * UPDATE HISTORY: * 09-05-2001 CSH Created + * */
/* INCLUDES ******************************************************************/
#include <user32.h>
+#define NDEBUG + #include <wine/debug.h>
+#define QUERY_SIZE 0 + /* FUNCTIONS *****************************************************************/
/* @@ -40,7 +28,8 @@ BOOL STDCALL OpenClipboard(HWND hWndNewOwner) { - return NtUserOpenClipboard(hWndNewOwner, 0); + BOOL ret = NtUserOpenClipboard(hWndNewOwner, 0); + return ret; }
/* @@ -49,7 +38,9 @@ BOOL STDCALL CloseClipboard(VOID) { - return NtUserCloseClipboard(); + BOOL ret; + ret = NtUserCloseClipboard(); + return ret; }
/* @@ -58,7 +49,8 @@ INT STDCALL CountClipboardFormats(VOID) { - return NtUserCountClipboardFormats(); + INT ret = NtUserCountClipboardFormats(); + return ret; }
/* @@ -67,7 +59,7 @@ BOOL STDCALL EmptyClipboard(VOID) { - return NtUserEmptyClipboard(); + return NtUserEmptyClipboard(); }
/* @@ -76,7 +68,8 @@ UINT STDCALL EnumClipboardFormats(UINT format) { - return NtUserEnumClipboardFormats(format); + UINT ret = NtUserEnumClipboardFormats(format); + return ret; }
/* @@ -85,7 +78,31 @@ HANDLE STDCALL GetClipboardData(UINT uFormat) { - return NtUserGetClipboardData(uFormat, 0); + HGLOBAL hGlobal = NULL; + PVOID pGlobal = NULL; + DWORD size = 0; + + /* dealing with bitmap object */ + if (uFormat != CF_BITMAP) + { + size = (DWORD)NtUserGetClipboardData(uFormat, QUERY_SIZE); + + if (size) + { + hGlobal = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, size); + pGlobal = GlobalLock(hGlobal); + + size = (DWORD)NtUserGetClipboardData(uFormat, (DWORD)pGlobal); + + GlobalUnlock(hGlobal); + } + } + else + { + hGlobal = NtUserGetClipboardData(CF_BITMAP, !QUERY_SIZE); + } + + return hGlobal; }
/* @@ -94,28 +111,32 @@ INT STDCALL GetClipboardFormatNameA(UINT format, LPSTR lpszFormatName, int cchMaxCount) { - LPWSTR lpBuffer; - UNICODE_STRING FormatName; - INT Length; - - lpBuffer = HEAP_alloc(cchMaxCount * sizeof(WCHAR)); - if (!lpBuffer) - { - SetLastError(ERROR_OUTOFMEMORY); - return 0; - } + LPWSTR lpBuffer; + UNICODE_STRING FormatName; + INT Length; + ANSI_STRING ClassName; + + ClassName.MaximumLength = cchMaxCount; + ClassName.Buffer = lpszFormatName; + + lpBuffer = HEAP_alloc(cchMaxCount * sizeof(WCHAR)); + + if (!lpBuffer) + { + SetLastError(ERROR_OUTOFMEMORY); + return 0; + }
FormatName.Length = 0; FormatName.MaximumLength = cchMaxCount * sizeof(WCHAR); FormatName.Buffer = lpBuffer;
+ /* we need a UNICODE string */ Length = NtUserGetClipboardFormatName(format, &FormatName, cchMaxCount); - DPRINT("GetClipboardFormatNameA(%x): %S\n", format, lpBuffer); - HEAP_strcpyWtoA(lpszFormatName, lpBuffer, Length); - HEAP_free(lpBuffer); - DPRINT("GetClipboardFormatNameA(%x): returning %s\n", format, lpszFormatName); - - return Length; + + HEAP_strcpyWtoA(lpszFormatName, FormatName.Buffer, Length); + + return strlen(lpszFormatName); }
/* @@ -124,15 +145,15 @@ INT STDCALL GetClipboardFormatNameW(UINT format, LPWSTR lpszFormatName, INT cchMaxCount) { - UNICODE_STRING FormatName; - ULONG Ret; - - FormatName.Length = 0; - FormatName.MaximumLength = cchMaxCount * sizeof(WCHAR); - FormatName.Buffer = (PWSTR)lpszFormatName; - Ret = NtUserGetClipboardFormatName(format, &FormatName, cchMaxCount); - DPRINT("GetClipboardFormatNameW(%x): returning %S\n", format, lpszFormatName); - return Ret; + UNICODE_STRING FormatName; + ULONG Ret; + + FormatName.Length = 0; + FormatName.MaximumLength = cchMaxCount * sizeof(WCHAR); + FormatName.Buffer = (PWSTR)lpszFormatName; + Ret = NtUserGetClipboardFormatName(format, &FormatName, cchMaxCount); + return Ret; + }
/* @@ -177,7 +198,8 @@ INT STDCALL GetPriorityClipboardFormat(UINT *paFormatPriorityList, INT cFormats) { - return NtUserGetPriorityClipboardFormat(paFormatPriorityList, cFormats); + INT ret = NtUserGetPriorityClipboardFormat(paFormatPriorityList, cFormats); + return ret; }
/* @@ -186,18 +208,41 @@ BOOL STDCALL IsClipboardFormatAvailable(UINT format) { - return NtUserIsClipboardFormatAvailable(format); -} - -/* - * @implemented - */ + BOOL ret = NtUserIsClipboardFormatAvailable(format); + return ret; +} + +/* + * @implemented + */ + UINT STDCALL RegisterClipboardFormatA(LPCSTR lpszFormat) { - ULONG Ret = RegisterWindowMessageA(lpszFormat); - DPRINT("RegisterClipboardFormatA(%s) - %x\n", lpszFormat, Ret); - return Ret; + UINT ret = 0; + UNICODE_STRING usFormat = {0}; + + if (lpszFormat == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + /* check for "" */ + if (*lpszFormat == 0) //NULL + { + SetLastError(ERROR_INVALID_NAME); + return 0; + } + + ret = RtlCreateUnicodeStringFromAsciiz(&usFormat, lpszFormat); + if (ret) + { + ret = NtUserRegisterClipboardFormat(&usFormat); //(LPCWSTR) + RtlFreeUnicodeString(&usFormat); + } + + return ret; }
/* @@ -206,9 +251,48 @@ UINT STDCALL RegisterClipboardFormatW(LPCWSTR lpszFormat) { - ULONG Ret = RegisterWindowMessageW(lpszFormat); - DPRINT("RegisterClipboardFormatW(%S) - %x\n", lpszFormat, Ret); - return Ret; + UINT ret = 0; + UNICODE_STRING usFormat = {0}; + + if (lpszFormat == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + /* check for "" */ + if (*lpszFormat == 0) //NULL + { + SetLastError(ERROR_INVALID_NAME); + return 0; + } + + RtlInitUnicodeString(&usFormat, lpszFormat); + ret = NtUserRegisterClipboardFormat(&usFormat); + RtlFreeUnicodeString(&usFormat); + + return ret; +} + +HGLOBAL renderLocale (DWORD Locale) +{ + DWORD* pLocale; + HGLOBAL hGlobal; + + hGlobal = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, sizeof(DWORD)); + + if(!hGlobal) + { + return hGlobal; + } + + pLocale = (DWORD*)GlobalLock(hGlobal); + + *pLocale = Locale; + + GlobalUnlock(hGlobal); + + return hGlobal; }
/* @@ -217,7 +301,54 @@ HANDLE STDCALL SetClipboardData(UINT uFormat, HANDLE hMem) { - return NtUserSetClipboardData(uFormat, hMem, 0); + DWORD size; + LPVOID pMem; + HANDLE ret = NULL; + + if (hMem == NULL) + { + return NtUserSetClipboardData(uFormat, 0, 0); + } + + if (uFormat == CF_BITMAP) + { + /* GlobalLock should return 0 for GDI handles + pMem = GlobalLock(hMem); + if (pMem) + { + // not a GDI handle + GlobalUnlock(hMem); + return ret; + } + else + { + */ + /* check if this GDI handle is a HBITMAP */ + /* GetObject for HBITMAP not implemented in ReactOS */ + //if (GetObject(hMem, 0, NULL) == sifeof(BITMAP)) + //{ + return NtUserSetClipboardData(CF_BITMAP, hMem, 0); + //} + /*}*/ + } + + size = GlobalSize(hMem); + pMem = GlobalLock(hMem); + + if ((pMem) && (size)) + { + size = GlobalSize(hMem); + ret = NtUserSetClipboardData(uFormat, pMem, size); + //should i unlock hMem? + GlobalUnlock(hMem); + } + else + { + DPRINT1("SetClipboardData failed\n"); + } + + return ret; + }
/* @@ -237,3 +368,35 @@ { return NtUserChangeClipboardChain(hWndRemove, hWndNewNext); } + +/* + * @unimplemented + */ +BOOL STDCALL +AddClipboardFormatListener(HWND hwnd) +{ + UNIMPLEMENTED; + return FALSE; +} +/* + * @unimplemented + */ +BOOL STDCALL +RemoveClipboardFormatListener(HWND hwnd) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOL STDCALL +GetUpdatedClipboardFormats( + PUINT lpuiFormats, + UINT cFormats, + PUINT pcFormatsOut) +{ + UNIMPLEMENTED; + return FALSE; +}
Modified: trunk/reactos/dll/win32/user32/windows/defwnd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/de... ============================================================================== --- trunk/reactos/dll/win32/user32/windows/defwnd.c (original) +++ trunk/reactos/dll/win32/user32/windows/defwnd.c Thu Mar 8 16:31:33 2007 @@ -984,7 +984,31 @@ VOID FASTCALL DefWndScreenshot(HWND hWnd) { - + RECT rect; + + OpenClipboard(hWnd); + EmptyClipboard(); + + HDC hdc = GetWindowDC(hWnd); + GetWindowRect(hWnd, &rect); + INT w = rect.right - rect.left; + INT h = rect.bottom - rect.top; + + HBITMAP hbitmap = CreateCompatibleBitmap(hdc, w, h); + HDC hdc2 = CreateCompatibleDC(hdc); + SelectObject(hdc2, hbitmap); + + BitBlt(hdc2, 0, 0, w, h, + hdc, 0, 0, + SRCCOPY); + + SetClipboardData(CF_BITMAP, hbitmap); + + ReleaseDC(hWnd, hdc); + ReleaseDC(hWnd, hdc2); + + CloseClipboard(); + }
@@ -1349,7 +1373,12 @@ } else if (wParam == VK_SNAPSHOT) { - DefWndScreenshot(hWnd); + HWND hwnd = hWnd; + while (GetParent(hwnd) != NULL) + { + hwnd = GetParent(hwnd); + } + DefWndScreenshot(hwnd); } } else if( wParam == VK_F10 )
Modified: trunk/reactos/include/psdk/winuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/winuser.h?rev=... ============================================================================== --- trunk/reactos/include/psdk/winuser.h (original) +++ trunk/reactos/include/psdk/winuser.h Thu Mar 8 16:31:33 2007 @@ -54,6 +54,8 @@ #define HCBT_KEYSKIPPED 7 #define HCBT_SYSCOMMAND 8 #define HCBT_SETFOCUS 9 + +/* Predefined Clipboard Formats */ #define CF_TEXT 1 #define CF_BITMAP 2 #define CF_METAFILEPICT 3 @@ -68,9 +70,24 @@ #define CF_WAVE 12 #define CF_UNICODETEXT 13 #define CF_ENHMETAFILE 14 -#define CF_HDROP 15 -#define CF_LOCALE 16 -#define CF_MAX 17 + +#if(WINVER >= 0x0400) +#define CF_HDROP 15 +#define CF_LOCALE 16 +#endif + +#if(WINVER >= 0x0500) +#define CF_DIBV5 17 +#endif + +#if(WINVER >= 0x0500) +#define CF_MAX 18 +#elif(WINVER >= 0x0400) +#define CF_MAX 17 +#else +#define CF_MAX 15 +#endif + #define CF_OWNERDISPLAY 128 #define CF_DSPTEXT 129 #define CF_DSPBITMAP 130 @@ -80,6 +97,7 @@ #define CF_PRIVATELAST 767 #define CF_GDIOBJFIRST 768 #define CF_GDIOBJLAST 1023 + #define HKL_NEXT 1 #define HKL_PREV 0 #define KLF_ACTIVATE 1
Modified: trunk/reactos/include/reactos/win32k/ntuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntus... ============================================================================== --- trunk/reactos/include/reactos/win32k/ntuser.h (original) +++ trunk/reactos/include/reactos/win32k/ntuser.h Thu Mar 8 16:31:33 2007 @@ -122,7 +122,12 @@ HMENU hMenu, UINT uIDEnableItem, UINT uEnable); - + +UINT +NTAPI +NtUserEnumClipboardFormats( + UINT format); + DWORD NTAPI NtUserInsertMenuItem( @@ -1038,6 +1043,11 @@ NtUserGetKeyState( DWORD Unknown0);
+BOOL +NTAPI +NtUserGetLastInputInfo( + PLASTINPUTINFO plii); + DWORD NTAPI NtUserGetListBoxInfo( @@ -1439,6 +1449,11 @@ WNDPROC wpExtra, DWORD Flags, HMENU hMenu); + +UINT +NTAPI +NtUserRegisterClipboardFormat( + PUNICODE_STRING format);
BOOL NTAPI
Modified: trunk/reactos/subsystems/win32/win32k/include/clipboard.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/clipboard.h (original) +++ trunk/reactos/subsystems/win32/win32k/include/clipboard.h Thu Mar 8 16:31:33 2007 @@ -1,7 +1,48 @@ #ifndef _WIN32K_CLIPBOARD_H #define _WIN32K_CLIPBOARD_H
+#include "window.h" + +VOID FASTCALL IntIncrementSecuenceNumber(VOID); + +typedef struct _ClipboardChainElement +{ + PWINDOW_OBJECT window; + struct _ClipboardChainElement *next; +} CLIPBOARDCHAINELEMENT, *PCLIPBOARDCHAINELEMENT; + +typedef struct _ClipboardElement +{ + UINT format; + HANDLE hData; + DWORD size; // data may be delayed o synth render + struct _ClipboardElement *next; +} CLIPBOARDELEMENT, *PCLIPBOARDELEMENT; + +typedef struct _CLIPBOARDSYSTEM +{ + PW32THREAD ClipboardThread; + PW32THREAD ClipboardOwnerThread; + PWINDOW_OBJECT ClipboardWindow; + PWINDOW_OBJECT ClipboardViewerWindow; + PWINDOW_OBJECT ClipboardOwnerWindow; + BOOL sendDrawClipboardMsg; + BOOL recentlySetClipboard; + BOOL delayedRender; + UINT lastEnumClipboardFormats; + DWORD ClipboardSequenceNumber; + + PCLIPBOARDCHAINELEMENT WindowsChain; + PCLIPBOARDELEMENT ClipboardData; + + PCHAR synthesizedData; + DWORD synthesizedDataSize; + +} CLIPBOARDSYSTEM, *PCLIPBOARDSYSTEM; + +/* UINT FASTCALL IntEnumClipboardFormats(UINT format); +*/
#endif /* _WIN32K_CLIPBOARD_H */
Modified: trunk/reactos/subsystems/win32/win32k/include/winsta.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/winsta.h (original) +++ trunk/reactos/subsystems/win32/win32k/include/winsta.h Thu Mar 8 16:31:33 2007 @@ -2,6 +2,7 @@ #define _WIN32K_WINSTA_H
#include "msgqueue.h" +#include "clipboard.h"
#define WINSTA_ROOT_NAME L"\Windows\WindowStations" #define WINSTA_ROOT_NAME_LENGTH 23 @@ -45,7 +46,10 @@
ULONG Flags; struct _DESKTOP_OBJECT* ActiveDesktop; - /* FIXME: Clipboard */ + + PCLIPBOARDSYSTEM Clipboard; + DWORD ClipboardSequenceNumber; + } WINSTATION_OBJECT, *PWINSTATION_OBJECT;
extern WINSTATION_OBJECT *InputWindowStation;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/clipboard.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/clipboard.c (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/clipboard.c Thu Mar 8 16:31:33 2007 @@ -1,27 +1,10 @@ -/* - * 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. - */ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: Clipboard routines * FILE: subsys/win32k/ntuser/clipboard.c * PROGRAMER: Filip Navara xnavara@volny.cz + * Pablo Borobia pborobia@gmail.com */
#include <w32k.h> @@ -29,290 +12,1234 @@ #define NDEBUG #include <debug.h>
-#define CHECK_LOCK \ - if (ClipboardThread && ClipboardThread != PsGetCurrentThreadWin32Thread()) \ - { \ - SetLastWin32Error(ERROR_LOCKED); \ - return FALSE; \ - } - -PW32THREAD ClipboardThread; -HWND ClipboardWindow; -HWND tempClipboardWindow; -HANDLE hCBData; -UINT uCBFormat; - -ULONG FASTCALL -IntGetClipboardFormatName(UINT format, PUNICODE_STRING FormatName) -{ - - return IntGetAtomName((RTL_ATOM)format, FormatName->Buffer, - FormatName->MaximumLength); -} - -UINT FASTCALL -IntEnumClipboardFormats(UINT format) -{ - - CHECK_LOCK - - if (!hCBData) - return FALSE; - //UNIMPLEMENTED; - return 1; +#define DATA_DELAYED_RENDER 0 +#define DATA_SYNTHESIZED_RENDER -1 + +#define USE_WINSTA \ + PWINSTATION_OBJECT WinStaObj; \ + WinStaObj = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation; + +#define WINSTA_ClipboardThread WinStaObj->Clipboard->ClipboardThread +#define WINSTA_ClipboardOwnerThread WinStaObj->Clipboard->ClipboardOwnerThread +#define WINSTA_ClipboardWindow WinStaObj->Clipboard->ClipboardWindow +#define WINSTA_ClipboardViewerWindow WinStaObj->Clipboard->ClipboardViewerWindow +#define WINSTA_ClipboardOwnerWindow WinStaObj->Clipboard->ClipboardOwnerWindow +#define WINSTA_sendDrawClipboardMsg WinStaObj->Clipboard->sendDrawClipboardMsg +#define WINSTA_recentlySetClipboard WinStaObj->Clipboard->recentlySetClipboard +#define WINSTA_delayedRender WinStaObj->Clipboard->delayedRender +#define WINSTA_lastEnumClipboardFormats WinStaObj->Clipboard->lastEnumClipboardFormats +#define WINSTA_ClipboardSequenceNumber WinStaObj->Clipboard->ClipboardSequenceNumber +#define WINSTA_WindowsChain WinStaObj->Clipboard->WindowsChain +#define WINSTA_ClipboardData WinStaObj->Clipboard->ClipboardData +#define WINSTA_synthesizedData WinStaObj->Clipboard->synthesizedData +#define WINSTA_synthesizedDataSize WinStaObj->Clipboard->synthesizedDataSize + +PW32THREAD ClipboardThread; +PW32THREAD ClipboardOwnerThread; +PWINDOW_OBJECT ClipboardWindow; +PWINDOW_OBJECT ClipboardViewerWindow; +PWINDOW_OBJECT ClipboardOwnerWindow; +BOOL sendDrawClipboardMsg; +BOOL recentlySetClipboard; +BOOL delayedRender; +UINT lastEnumClipboardFormats; +DWORD ClipboardSequenceNumber = 0; + +PCLIPBOARDCHAINELEMENT WindowsChain = NULL; +PCLIPBOARDELEMENT ClipboardData = NULL; + +PCHAR synthesizedData; +DWORD synthesizedDataSize; + + +/*==============================================================*/ + +/* return the pointer to the prev window of the finded window, + if NULL does not exists in the chain */ +PCLIPBOARDCHAINELEMENT FASTCALL +IntIsWindowInChain(PWINDOW_OBJECT window) +{ + PCLIPBOARDCHAINELEMENT wce = WindowsChain; + + while (wce) + { + if (wce->window == window) + { + break; + } + wce = wce->next; + } + + return wce; +} + +VOID FASTCALL printChain() +{ + /*test*/ + PCLIPBOARDCHAINELEMENT wce2 = WindowsChain; + while (wce2) + { + DPRINT1("chain: %p\n", wce2->window->hSelf); + wce2 = wce2->next; + } +} + +/* the new window always have to be the first in the chain */ +PCLIPBOARDCHAINELEMENT FASTCALL +IntAddWindowToChain(PWINDOW_OBJECT window) +{ + PCLIPBOARDCHAINELEMENT wce = NULL; + + if (!IntIsWindowInChain(window)) + { + wce = WindowsChain; + + wce = ExAllocatePool(PagedPool, sizeof(CLIPBOARDCHAINELEMENT)); + if (wce == NULL) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + goto exit_addChain; + } + + wce->window = window; + wce->next = WindowsChain; + + WindowsChain = wce; + + //printChain(); + } +exit_addChain: + + /* return the next window to beremoved later */ + return wce; +} + +PCLIPBOARDCHAINELEMENT FASTCALL +IntRemoveWindowFromChain(PWINDOW_OBJECT window) +{ + PCLIPBOARDCHAINELEMENT wce = WindowsChain; + PCLIPBOARDCHAINELEMENT *link = &WindowsChain; + + if (IntIsWindowInChain(window)) + { + while (wce != NULL) + { + if (wce->window == window) + { + *link = wce->next; + break; + } + + link = &wce->next; + wce = wce->next; + } + + //printChain(); + + return wce; + } + else + { + return NULL; + } +} + + +/*==============================================================*/ +/* if format exists, returns a non zero value (pointing to format object) */ +PCLIPBOARDELEMENT FASTCALL +intIsFormatAvailable(format) +{ + PCLIPBOARDELEMENT ret = NULL; + PCLIPBOARDELEMENT ce = ClipboardData; + + while(ce) + { + if (ce->format == format) + { + ret = ce; + break; + } + ce = ce->next; + } + return ret; +} + +/* counts how many distinct format were are in the clipboard */ +DWORD FASTCALL +IntCountClipboardFormats() +{ + DWORD ret = 0; + PCLIPBOARDELEMENT ce = ClipboardData; + + while(ce) + { + ret++; + ce = ce->next; + } + return ret; +} + +/* adds a new format and data to the clipboard */ +PCLIPBOARDELEMENT FASTCALL +intAddFormatedData(UINT format, HANDLE hData, DWORD size) +{ + PCLIPBOARDELEMENT ce = NULL; + + ce = ExAllocatePool(PagedPool, sizeof(CLIPBOARDELEMENT)); + if (ce == NULL) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + } + else + { + ce->format = format; + ce->size = size; + ce->hData = hData; + ce->next = ClipboardData; + + ClipboardData = ce; + + IntIncrementSecuenceNumber(); + } + + return ce; +} + +/* removes a format and its data from the clipboard */ +BOOL FASTCALL +intRemoveFormatedData(UINT format) +{ + BOOL ret = FALSE; + PCLIPBOARDELEMENT ce = ClipboardData; + PCLIPBOARDELEMENT *link = &ClipboardData; + + if (intIsFormatAvailable(format)) + { + while (ce != NULL) + { + if (ce->format == format) + { + *link = ce->next; + break; + } + + link = &ce->next; + ce = ce->next; + } + + if (ce->hData) + { + ExFreePool(ce->hData); + } + ExFreePool(ce); + ret = TRUE; + } + + return ret; +} + +VOID FASTCALL +IntEmptyClipboardData() +{ + PCLIPBOARDELEMENT ce = ClipboardData; + PCLIPBOARDELEMENT tmp; + + while(ce) + { + tmp = ce->next; + ExFreePool(ce->hData); + ExFreePool(ce); + ce = tmp; + } + + ClipboardData = NULL; +} + +/*==============================================================*/ + +HANDLE FASTCALL +renderBITMAPfromDIB(LPBYTE hDIB) +{ + HDC hdc; + HBITMAP hbitmap; + unsigned int offset; + BITMAPINFOHEADER *ih; + + //hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); + hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE); + + ih = (BITMAPINFOHEADER *)hDIB; + + offset = sizeof(BITMAPINFOHEADER) + ((ih->biBitCount <= 8) ? (sizeof(RGBQUAD) * (1 << ih->biBitCount)) : 0); + + hbitmap = NtGdiCreateDIBitmap(hdc, ih, CBM_INIT, (LPBYTE)ih + offset, (LPBITMAPINFO)ih, DIB_RGB_COLORS); + + //UserReleaseDC(NULL, hdc, FALSE); + UserReleaseDC(ClipboardWindow, hdc, FALSE); + + return hbitmap; +} + +BOOL FASTCALL +canSinthesize(UINT format) +{ + BOOL ret = FALSE; + + switch(format) + { + case CF_BITMAP: + case CF_METAFILEPICT: + ret = TRUE; + } + + return ret; +} + +/* returns the size of the sinthesized data */ +DWORD FASTCALL +synthesizeData(UINT format) +{ + DWORD ret = 0; + + synthesizedData = NULL; + synthesizedDataSize = 0; + + if (!canSinthesize(format)) + { + return 0; + } + + switch (format) + { + case CF_BITMAP: + { + break; + } + + case CF_METAFILEPICT: + { + break; + } + } + + ret = 1; + + return ret; +} + +VOID FASTCALL +freeSynthesizedData() +{ + ExFreePool(synthesizedData); +} + +/*==============================================================*/ + +BOOL FASTCALL +intIsClipboardOpenByMe() +{ + /* check if we open the clipboard */ + if (ClipboardThread && ClipboardThread == PsGetCurrentThreadWin32Thread()) + { + /* yes, we got a thread and its the same that opens the clipboard */ + return TRUE; + + } + /* will fail if not thread (closed) or not open by me*/ + return FALSE; +} + +/* IntClipboardFreeWindow it's called when a window was destroyed */ +VOID FASTCALL +IntClipboardFreeWindow(PWINDOW_OBJECT window) +{ + /* called from co_UserFreeWindow in window.c */ + /* check if clipboard is not locked by this window, if yes, unlock it */ + if (ClipboardThread == PsGetCurrentThreadWin32Thread()) + { + /* the window that opens the clipboard was destroyed */ + ClipboardThread = NULL; + ClipboardWindow = NULL; + //TODO: free clipboard + } + if (window == ClipboardOwnerWindow) + { + /* the owner window was destroyed */ + ClipboardOwnerWindow = NULL; + ClipboardOwnerThread = NULL; + } + /* remove window from window chain */ + if (IntIsWindowInChain(window)) + { + PCLIPBOARDCHAINELEMENT w = IntRemoveWindowFromChain(window); + if (w) + { + ExFreePool(w); + } + } }
BOOL STDCALL NtUserOpenClipboard(HWND hWnd, DWORD Unknown1) { - CHECK_LOCK - - tempClipboardWindow = hWnd; - ClipboardThread = PsGetCurrentThreadWin32Thread(); - return TRUE; + + PWINDOW_OBJECT Window; + BOOL ret = FALSE; + + UserEnterExclusive(); + + sendDrawClipboardMsg = FALSE; + recentlySetClipboard = FALSE; + + if (ClipboardThread) + { + /* clipboard is already open */ + if (ClipboardThread == PsGetCurrentThreadWin32Thread()) + { + if (ClipboardOwnerWindow) + { + if (ClipboardOwnerWindow->hSelf == hWnd) + { + ret = TRUE; + } + } + else + { + if (hWnd == NULL) + { + ret = TRUE; + } + } + } + } + else + { + + if (hWnd != NULL) + { + Window = UserGetWindowObject(hWnd); + + if (Window != NULL) + { + ClipboardWindow = Window; + ClipboardThread = PsGetCurrentThreadWin32Thread(); + ret = TRUE; + } + else + { + ClipboardWindow = NULL; + ClipboardThread = NULL; + ClipboardOwnerWindow = NULL; + ClipboardOwnerThread = NULL; + } + } + else + { + ClipboardWindow = NULL; + ClipboardThread = PsGetCurrentThreadWin32Thread(); + ret = TRUE; + } + } + + UserLeave(); + + return ret; }
BOOL STDCALL NtUserCloseClipboard(VOID) { - CHECK_LOCK - - ClipboardWindow = 0; - ClipboardThread = NULL; - return TRUE; -} - -/* - * @unimplemented - */ + BOOL ret = FALSE; + + UserEnterExclusive(); + + if (intIsClipboardOpenByMe()) + { + ClipboardWindow = NULL; + ClipboardThread = NULL; + ret = TRUE; + } + else + { + SetLastWin32Error(ERROR_CLIPBOARD_NOT_OPEN); + } + + recentlySetClipboard = FALSE; + + UserLeave(); + + if (sendDrawClipboardMsg && WindowsChain) + { + /* only send message to the first window in the chain, then they'll do the chain */ + /* commented because it makes a crash in co_MsqSendMessage + ASSERT(WindowsChain->window); + ASSERT(WindowsChain->window->hSelf); + DPRINT1("Clipboard: sending WM_DRAWCLIPBOARD to %p\n", WindowsChain->window->hSelf); + co_IntSendMessage(WindowsChain->window->hSelf, WM_DRAWCLIPBOARD, 0, 0); + */ + } + + return ret; +} + HWND STDCALL NtUserGetOpenClipboardWindow(VOID) { - /* - UNIMPLEMENTED - return 0; - */ - return ClipboardWindow; + HWND ret = NULL; + + UserEnterShared(); + + if (ClipboardWindow) + { + ret = ClipboardWindow->hSelf; + } + + UserLeave(); + + return ret; }
BOOL STDCALL NtUserChangeClipboardChain(HWND hWndRemove, HWND hWndNewNext) { - UNIMPLEMENTED - return 0; + BOOL ret = FALSE; + PCLIPBOARDCHAINELEMENT w = NULL; + + UserEnterExclusive(); + + PWINDOW_OBJECT removeWindow = UserGetWindowObject(hWndRemove); + + if (removeWindow) + { + if ((ret = !!IntIsWindowInChain(removeWindow))) + { + w = IntRemoveWindowFromChain(removeWindow); + if (w) + { + ExFreePool(w); + } + } + } + + if (ret && WindowsChain) + { + // only send message to the first window in the chain, + // then they do the chain + DPRINT1("Message: WM_CHANGECBCHAIN to %p", WindowsChain->window->hSelf); + /* WindowsChain->window may be NULL */ + LPARAM lparam = WindowsChain->window == NULL ? 0 : (LPARAM)WindowsChain->window->hSelf; + co_IntSendMessage(WindowsChain->window->hSelf, WM_CHANGECBCHAIN, (WPARAM)hWndRemove, lparam); + } + + UserLeave(); + + return ret; }
DWORD STDCALL NtUserCountClipboardFormats(VOID) { - UNIMPLEMENTED - return 0; + DWORD ret = 0; + + if (ClipboardData) + { + ret = IntCountClipboardFormats(); + } + + return ret; }
DWORD STDCALL NtUserEmptyClipboard(VOID) { - CHECK_LOCK - - // if (!hCBData) - // return FALSE; - - // FIXME! - // GlobalUnlock(hCBData); - // GlobalFree(hCBData); - hCBData = NULL; - uCBFormat = 0; - ClipboardWindow = tempClipboardWindow; - - return TRUE; + BOOL ret = FALSE; + + UserEnterExclusive(); + + if (intIsClipboardOpenByMe()) + { + if (ClipboardData) + { + IntEmptyClipboardData(); + } + + ClipboardOwnerWindow = ClipboardWindow; + ClipboardOwnerThread = ClipboardThread; + + IntIncrementSecuenceNumber(); + + ret = TRUE; + } + else + { + SetLastWin32Error(ERROR_CLIPBOARD_NOT_OPEN); + } + + if (ret && ClipboardOwnerWindow) + { + DPRINT1("Clipboard: WM_DESTROYCLIPBOARD to %p", ClipboardOwnerWindow->hSelf); + co_IntSendMessage( ClipboardOwnerWindow->hSelf, WM_DESTROYCLIPBOARD, 0, 0); + } + + UserLeave(); + + return ret; }
HANDLE STDCALL NtUserGetClipboardData(UINT uFormat, DWORD Unknown1) { - CHECK_LOCK - - if ((uFormat==1 && uCBFormat==13) || (uFormat==13 && uCBFormat==1)) - uCBFormat = uFormat; - - if (uFormat != uCBFormat) - return FALSE; - - return hCBData; + HANDLE ret = NULL; + PCHAR buffer; + + UserEnterShared(); + + if (intIsClipboardOpenByMe()) + { + /* when Unknown1 is zero, we returns to user32 the data size */ + if (Unknown1 == 0) + { + PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat); + + if (data) + { + /* format exists in clipboard */ + if (data->size == DATA_DELAYED_RENDER) + { + /* tell owner what data needs to be rendered */ + if (ClipboardOwnerWindow) + { + ASSERT(ClipboardOwnerWindow->hSelf); + co_IntSendMessage(ClipboardOwnerWindow->hSelf, WM_RENDERFORMAT, (WPARAM)uFormat, 0); + data = intIsFormatAvailable(uFormat); + ASSERT(data->size); + ret = (HANDLE)data->size; + } + } + else + { + if (data->size == DATA_SYNTHESIZED_RENDER) + { + data->size = synthesizeData(uFormat); + } + + } + ret = (HANDLE)data->size; + } + else + { + /* there is no data in this format */ + //ret = (HANDLE)FALSE; + } + } + else + { + PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat); + + if (data) + { + if (data->size == DATA_DELAYED_RENDER) + { + // we rendered it in 1st call of getclipboard data + } + else + { + if (data->size == DATA_SYNTHESIZED_RENDER) + { + if (uFormat == CF_BITMAP) + { + /* BITMAP & METAFILEs returns a GDI handle */ + PCLIPBOARDELEMENT data = intIsFormatAvailable(CF_DIB); + if (data) + { + ret = renderBITMAPfromDIB(data->hData); + } + } + else + { + buffer = (PCHAR)Unknown1; + memcpy(buffer, (PCHAR)synthesizedData, synthesizedDataSize); + + freeSynthesizedData(); + + ret = (HANDLE)Unknown1; + } + } + else + { + buffer = (PCHAR)Unknown1; + memcpy(buffer, (PCHAR)data->hData, data->size); + + ret = (HANDLE)Unknown1; + } + } + + } + + } + } + else + { + SetLastWin32Error(ERROR_CLIPBOARD_NOT_OPEN); + } + + UserLeave(); + + return ret; }
INT STDCALL NtUserGetClipboardFormatName(UINT format, PUNICODE_STRING FormatName, INT cchMaxCount) { - NTSTATUS Status; - PWSTR Buf; - UNICODE_STRING SafeFormatName, BufFormatName; - ULONG Ret; - - if((cchMaxCount < 1) || !FormatName) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return 0; - } - - /* copy the FormatName UNICODE_STRING structure */ - Status = MmCopyFromCaller(&SafeFormatName, FormatName, sizeof(UNICODE_STRING)); - if(!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return 0; - } - - /* Allocate memory for the string */ - Buf = ExAllocatePoolWithTag(PagedPool, cchMaxCount * sizeof(WCHAR), TAG_STRING); - if(!Buf) - { - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - /* Setup internal unicode string */ - BufFormatName.Length = 0; - BufFormatName.MaximumLength = min(cchMaxCount * sizeof(WCHAR), SafeFormatName.MaximumLength); - BufFormatName.Buffer = Buf; - - if(BufFormatName.MaximumLength < sizeof(WCHAR)) - { - ExFreePool(Buf); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return 0; - } - - if (format >= 0xC000) - { - Ret = IntGetClipboardFormatName(format, &BufFormatName); - } - else - { - SetLastNtError(NO_ERROR); - return 0; - } - - /* copy the UNICODE_STRING buffer back to the user */ - Status = MmCopyToCaller(SafeFormatName.Buffer, BufFormatName.Buffer, BufFormatName.MaximumLength); - if(!NT_SUCCESS(Status)) - { - ExFreePool(Buf); - SetLastNtError(Status); - return 0; - } - - BufFormatName.MaximumLength = SafeFormatName.MaximumLength; - BufFormatName.Buffer = SafeFormatName.Buffer; - - /* update the UNICODE_STRING structure (only the Length member should change) */ - Status = MmCopyToCaller(FormatName, &BufFormatName, sizeof(UNICODE_STRING)); - if(!NT_SUCCESS(Status)) - { - ExFreePool(Buf); - SetLastNtError(Status); - return 0; - } - - ExFreePool(Buf); - return Ret; -} + UNICODE_STRING sFormatName; + INT ret = 0; + + /* if the format is built-in we fail */ + if (format < 0xc000) + { + /* registetrated formats are >= 0xc000 */ + return 0; + } + + if((cchMaxCount < 1) || !FormatName) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return 0; + } + + _SEH_TRY + { + ProbeForWriteUnicodeString(FormatName); + sFormatName = *(volatile UNICODE_STRING *)FormatName; + ProbeForWrite(sFormatName.Buffer, sFormatName.MaximumLength, 1); + + ret = IntGetAtomName((RTL_ATOM)format, sFormatName.Buffer, cchMaxCount * sizeof(WCHAR)); + + if (ret >= 0) + { + ret = ret / sizeof(WCHAR); + sFormatName.Length = ret; + } + else + { + ret = 0; + } + } + _SEH_HANDLE + { + SetLastNtError(_SEH_GetExceptionCode()); + } + _SEH_END; + + return ret; +} + +UINT STDCALL +NtUserRegisterClipboardFormat(PUNICODE_STRING FormatName) +{ + UINT ret = 0; + UNICODE_STRING cFormatName = {0}; + + if (FormatName == NULL) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return ret; + } + + UserEnterExclusive(); + + _SEH_TRY + { + cFormatName = ProbeForReadUnicodeString(FormatName); + + if (cFormatName.Length > 0) + { + ret = (UINT)IntAddAtom(cFormatName.Buffer); + //RtlFreeUnicodeString(&cFormatName); + } + else + { + SetLastWin32Error(ERROR_INVALID_NAME); + _SEH_LEAVE; + } + + } + _SEH_HANDLE + { + SetLastNtError(_SEH_GetExceptionCode()); + } + _SEH_END; + + UserLeave(); + + return ret; +} +
HWND STDCALL NtUserGetClipboardOwner(VOID) { - return ClipboardWindow; + HWND ret = NULL; + + UserEnterShared(); + + if (ClipboardOwnerWindow) + { + ret = ClipboardOwnerWindow->hSelf; + } + + UserLeave(); + + return ret; +} + +HWND STDCALL +NtUserGetClipboardViewer(VOID) +{ + HWND ret = NULL; + + UserEnterShared(); + + if (WindowsChain) + { + ret = WindowsChain->window->hSelf; + } + + UserLeave(); + + return ret; +} + +INT STDCALL +NtUserGetPriorityClipboardFormat(UINT *paFormatPriorityList, INT cFormats) +{ + UINT i; + UINT *priorityList; + INT ret = 0; + + UserEnterExclusive(); + + _SEH_TRY + { + if (IntCountClipboardFormats() == 0) + { + ret = 0; + } + else + { + ProbeForRead(paFormatPriorityList, cFormats, sizeof(UINT)); + + priorityList = paFormatPriorityList; + + ret = -1; + + for (i = 0; i < cFormats; i++) + { + if (intIsFormatAvailable(priorityList[i])) + { + ret = priorityList[i]; + break; + } + } + + } + } + _SEH_HANDLE + { + SetLastNtError(_SEH_GetExceptionCode()); + } + _SEH_END; + + UserLeave(); + + return ret; + +} + +BOOL STDCALL +NtUserIsClipboardFormatAvailable(UINT format) +{ + BOOL ret = FALSE; + + UserEnterShared(); + + ret = (intIsFormatAvailable(format) != NULL); + + UserLeave(); + + return ret; +} + + + +HANDLE STDCALL +NtUserSetClipboardData(UINT uFormat, HANDLE hMem, DWORD size) +{ + HANDLE hCBData = NULL; + UNICODE_STRING unicodeString; + OEM_STRING oemString; + ANSI_STRING ansiString; + + UserEnterExclusive(); + + /* to place data here the we need to be the owner */ + if (ClipboardOwnerThread == PsGetCurrentThreadWin32Thread()) + { + PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat); + if (data) + { + + if (data->size == DATA_DELAYED_RENDER) + { + intRemoveFormatedData(uFormat); + } + else + { + // we already have this format on clipboard + goto exit_setCB; + } + } + + if (hMem) + { + _SEH_TRY + { + ProbeForRead(hMem, size, 1); + } + _SEH_HANDLE + { + SetLastNtError(_SEH_GetExceptionCode()); + goto exit_setCB; + } + _SEH_END; + + if (intIsClipboardOpenByMe()) + { + delayedRender = FALSE; + } + + if (!canSinthesize(uFormat)) + { + hCBData = ExAllocatePool(PagedPool, size); + memcpy(hCBData, hMem, size); + intAddFormatedData(uFormat, hCBData, size); + DPRINT1("Data stored\n"); + } + + sendDrawClipboardMsg = TRUE; + recentlySetClipboard = TRUE; + lastEnumClipboardFormats = uFormat; + + /* conversions */ + switch (uFormat) + { + case CF_TEXT: + { + //TODO : sinthesize CF_UNICODETEXT & CF_OEMTEXT + // CF_TEXT -> CF_UNICODETEXT + RtlAnsiStringToUnicodeString(&unicodeString, hCBData, TRUE); + intAddFormatedData(CF_UNICODETEXT, unicodeString.Buffer, unicodeString.Length * sizeof(WCHAR)); + // CF_TEXT -> CF_OEMTEXT + RtlUnicodeStringToOemString(&oemString, &unicodeString, TRUE); + intAddFormatedData(CF_OEMTEXT, oemString.Buffer, oemString.Length); + //HKCU\Control Panel\International\Locale + //intAddFormatedData(CF_LOCALE, oemString.Buffer, oemString.Length); + break; + } + case CF_UNICODETEXT: + { + //TODO : sinthesize CF_TEXT & CF_OEMTEXT + //CF_UNICODETEXT -> CF_TEXT + unicodeString.Buffer = hCBData; + unicodeString.Length = size; + RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE); + intAddFormatedData(CF_TEXT, ansiString.Buffer, ansiString.Length); + //CF_UNICODETEXT -> CF_OEMTEXT + RtlUnicodeStringToOemString(&oemString, &unicodeString, TRUE); + intAddFormatedData(CF_OEMTEXT, oemString.Buffer, oemString.Length); + break; + } + case CF_OEMTEXT: + { + //TODO : sinthesize CF_TEXT & CF_UNICODETEXT + //CF_OEMTEXT -> CF_UNICODETEXT + oemString.Buffer = hCBData; + oemString.Length = size; + RtlOemStringToUnicodeString(&unicodeString, &oemString, TRUE); + intAddFormatedData(CF_UNICODETEXT, unicodeString.Buffer, unicodeString.Length * sizeof(WCHAR)); + //CF_OEMTEXT -> CF_TEXT + RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE); + intAddFormatedData(CF_TEXT, ansiString.Buffer, ansiString.Length); + break; + } + case CF_BITMAP: + { + // we need to render the DIB or DIBV5 format as soon as possible + // because pallette information may change + + HDC hdc; + INT ret; + BITMAP bm; + BITMAPINFO bi; + + hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); + + BITMAPOBJ *BitmapObj; + BitmapObj = BITMAPOBJ_LockBitmap(hMem); + BITMAP_GetObject(BitmapObj, sizeof(BITMAP), (LPSTR)&bm); + if(BitmapObj) + { + BITMAPOBJ_UnlockBitmap(BitmapObj); + } + + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bi.bmiHeader.biWidth = bm.bmWidth; + bi.bmiHeader.biHeight = bm.bmHeight; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = bm.bmPlanes * bm.bmBitsPixel; + bi.bmiHeader.biCompression = BI_RGB; + bi.bmiHeader.biSizeImage = 0; + bi.bmiHeader.biXPelsPerMeter = 0; + bi.bmiHeader.biYPelsPerMeter = 0; + bi.bmiHeader.biClrUsed = 0; + + ret = NtGdiGetDIBits(hdc, hMem, 0, bm.bmHeight, NULL, &bi, DIB_RGB_COLORS); + + size = bi.bmiHeader.biSizeImage + sizeof(BITMAPINFOHEADER); + + hCBData = ExAllocatePool(PagedPool, size); + memcpy(hCBData, &bi, sizeof(BITMAPINFOHEADER)); + + ret = NtGdiGetDIBits(hdc, hMem, 0, bm.bmHeight, (LPBYTE)hCBData + sizeof(BITMAPINFOHEADER), &bi, DIB_RGB_COLORS); + + UserReleaseDC(NULL, hdc, FALSE); + + intAddFormatedData(CF_DIB, hCBData, size); + intAddFormatedData(CF_BITMAP, 0, DATA_SYNTHESIZED_RENDER); + // intAddFormatedData(CF_DIBV5, hCBData, size); + + break; + } + case CF_DIB: + { + intAddFormatedData(CF_BITMAP, 0, DATA_SYNTHESIZED_RENDER); + // intAddFormatedData(CF_DIBV5, hCBData, size); + /* investigate */ + // intAddFormatedData(CF_PALETTE, hCBData, size); + break; + } + case CF_DIBV5: + // intAddFormatedData(CF_BITMAP, hCBData, size); + // intAddFormatedData(CF_PALETTE, hCBData, size); + // intAddFormatedData(CF_DIB, hCBData, size); + break; + case CF_ENHMETAFILE: + // intAddFormatedData(CF_METAFILEPICT, hCBData, size); + break; + case CF_METAFILEPICT: + // intAddFormatedData(CF_ENHMETAFILE, hCBData, size); + break; + } + + } + else + { + // the window provides data in the specified format + delayedRender = TRUE; + sendDrawClipboardMsg = TRUE; + intAddFormatedData(uFormat, NULL, 0); + DPRINT1("SetClipboardData delayed format: %d\n", uFormat); + } + + + } + +exit_setCB: + + UserLeave(); + + return hMem; +} + +HWND STDCALL +NtUserSetClipboardViewer(HWND hWndNewViewer) +{ + HWND ret = NULL; + PCLIPBOARDCHAINELEMENT newWC = NULL; + + UserEnterExclusive(); + + PWINDOW_OBJECT window = UserGetWindowObject(hWndNewViewer); + + if (window) + { + if ((newWC = IntAddWindowToChain(window))) + { + if (newWC) + { + // newWC->next may be NULL if we are the first window in the chain + if (newWC->next) + { + // return the next HWND available window in the chain + ret = newWC->next->window->hSelf; + } + } + } + } + + UserLeave(); + + return ret; +} + +UINT STDCALL +NtUserEnumClipboardFormats(UINT uFormat) +{ + UINT ret = 0; + + UserEnterShared(); + + if (intIsClipboardOpenByMe()) + { + if (uFormat == 0) + { + if (recentlySetClipboard) + { + ret = lastEnumClipboardFormats; + } + else + { + /* return the first available format */ + if (ClipboardData) + { + ret = ClipboardData->format; + } + } + } + else + { + if (recentlySetClipboard) + { + ret = 0; + } + else + { + /* querying nextt available format */ + PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat); + + if (data) + { + if (data->next) + { + ret = data->next->format; + } + else + { + /* reached the end */ + ret = 0; + } + } + } + + } + } + else + { + SetLastWin32Error(ERROR_CLIPBOARD_NOT_OPEN); + } + + UserLeave(); + + return ret; +} + +// This number is incremented whenever the contents of the clipboard change +// or the clipboard is emptied. +// If clipboard rendering is delayed, +// the sequence number is not incremented until the changes are rendered. +VOID FASTCALL +IntIncrementSecuenceNumber(VOID) +{ + + USE_WINSTA + + WINSTA_ClipboardSequenceNumber++; + }
DWORD STDCALL NtUserGetClipboardSequenceNumber(VOID) { - UNIMPLEMENTED - return 0; -} - -HWND STDCALL -NtUserGetClipboardViewer(VOID) -{ - UNIMPLEMENTED - return 0; -} - -INT STDCALL -NtUserGetPriorityClipboardFormat(UINT *paFormatPriorityList, INT cFormats) -{ - UNIMPLEMENTED - return 0; -} - -BOOL STDCALL -NtUserIsClipboardFormatAvailable(UINT format) -{ - //UNIMPLEMENTED - - if (format != 1 && format != 13) - { - DbgPrint("Clipboard Format unavailable (%d)\n", format); - return FALSE; - } - - if ((format==1 && uCBFormat==13) || (format==13 && uCBFormat==1)) - uCBFormat = format; - - if (format != uCBFormat) - return FALSE; - - return TRUE; -} - -//SetClipboardData(CF_UNICODETEXT, hdst); -HANDLE STDCALL -NtUserSetClipboardData(UINT uFormat, HANDLE hMem, DWORD Unknown2) -{ - // LPVOID pMem; - CHECK_LOCK - - - if (uFormat != 1 && uFormat != 13) - { - DbgPrint("Clipboard unsupported format (%d)\n", uFormat); - return FALSE; - } - - if (hMem) - { - uCBFormat = uFormat; - hCBData = hMem; - //pMem = GlobalLock(hMem); - /* - switch (uFormat) { - default: - DbgPrint("Clipboard unsupported format (%d)\n", uFormat); - return FALSE; - case CF_TEXT: // 1 - break; - case CF_UNICODETEXT: // 13 - break; - case CF_BITMAP: // 2 - break; - case CF_OEMTEXT: // 7 - break; - } */ - } - else - { - //the window provides data in the specified format - } - return hMem; -} - -HWND STDCALL -NtUserSetClipboardViewer(HWND hWndNewViewer) -{ - HWND hwndPrev = 0; - DbgPrint("NtUserSetClipboardViewer is UNIMPLEMENTED (%p): returning %p\n", hWndNewViewer, hwndPrev); - return hwndPrev; + //windowstation sequence number + //if no WINSTA_ACCESSCLIPBOARD access to the window station, + //the function returns zero. + DWORD sn; + + HWINSTA WinSta; + PWINSTATION_OBJECT WinStaObj; + NTSTATUS Status; + + WinSta = UserGetProcessWindowStation(); + + Status = IntValidateWindowStationHandle(WinSta, UserMode, WINSTA_ACCESSCLIPBOARD, &WinStaObj); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("No WINSTA_ACCESSCLIPBOARD access\n"); + SetLastNtError(Status); + return 0; + } + + sn = WinStaObj->ClipboardSequenceNumber; + + ObDereferenceObject(WinStaObj); + + //local copy + //sn = ClipboardSequenceNumber; + + return sn; +} + +BOOL FASTCALL +IntSetupClipboard(PWINSTATION_OBJECT WinStaObj) +{ + WinStaObj->Clipboard = ExAllocatePool(PagedPool, sizeof(CLIPBOARDSYSTEM)); + if (WinStaObj->Clipboard) + { + RtlZeroMemory(WinStaObj->Clipboard, sizeof(CLIPBOARDSYSTEM)); + return TRUE; + } + return FALSE; +} + +/**************** VISTA FUNCTIONS******************/ + +BOOL STDCALL NtUserAddClipboardFormatListener( + HWND hwnd +) +{ + UNIMPLEMENTED; + return FALSE; +} + +BOOL STDCALL NtUserRemoveClipboardFormatListener( + HWND hwnd +) +{ + UNIMPLEMENTED; + return FALSE; +} + +BOOL STDCALL NtUserGetUpdatedClipboardFormats( + PUINT lpuiFormats, + UINT cFormats, + PUINT pcFormatsOut +) +{ + UNIMPLEMENTED; + return FALSE; }
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/misc.c (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/misc.c Thu Mar 8 16:31:33 2007 @@ -308,10 +308,10 @@
case ONEPARAM_ROUTINE_SETCARETBLINKTIME: RETURN( (DWORD)IntSetCaretBlinkTime((UINT)Param)); - +/* case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS: - RETURN( (DWORD)IntEnumClipboardFormats((UINT)Param)); - + RETURN( (DWORD)NtUserEnumClipboardFormats((UINT)Param)); +*/ case ONEPARAM_ROUTINE_GETWINDOWINSTANCE: { PWINDOW_OBJECT Window;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/useratom.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/useratom.c (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/useratom.c Thu Mar 8 16:31:33 2007 @@ -32,7 +32,6 @@ RTL_ATOM FASTCALL IntAddAtom(LPWSTR AtomName) { - PWINSTATION_OBJECT WinStaObject; NTSTATUS Status = STATUS_SUCCESS; RTL_ATOM Atom;
@@ -41,9 +40,9 @@ SetLastNtError(Status); return (RTL_ATOM)0; } - WinStaObject = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation; - Status = RtlAddAtomToAtomTable(WinStaObject->AtomTable, - AtomName, &Atom); + + Status = RtlAddAtomToAtomTable(gAtomTable, AtomName, &Atom); + if (!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -55,7 +54,6 @@ ULONG FASTCALL IntGetAtomName(RTL_ATOM nAtom, LPWSTR lpBuffer, ULONG nSize) { - PWINSTATION_OBJECT WinStaObject; NTSTATUS Status = STATUS_SUCCESS; ULONG Size = nSize;
@@ -64,9 +62,9 @@ SetLastNtError(Status); return 0; } - WinStaObject = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation; - Status = RtlQueryAtomInAtomTable(WinStaObject->AtomTable, - nAtom, NULL, NULL, lpBuffer, &Size); + + Status = RtlQueryAtomInAtomTable(gAtomTable, nAtom, NULL, NULL, lpBuffer, &Size); + if (Size < nSize) *(lpBuffer + Size) = 0; if (!NT_SUCCESS(Status))
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Thu Mar 8 16:31:33 2007 @@ -30,7 +30,7 @@
#include <w32k.h>
-#define NDEBUG +#define YDEBUG #include <debug.h>
/* dialog resources appear to pass this in 16 bits, handle them properly */ @@ -460,6 +460,8 @@ RtlFreeUnicodeString(&Window->WindowName);
UserDerefObject(Window); + + IntClipboardFreeWindow(Window);
return 0; } @@ -1888,16 +1890,18 @@ /* Calculate the non-client size. */ MaxPos.x = Window->WindowRect.left; MaxPos.y = Window->WindowRect.top; + + DPRINT("IntCreateWindowEx(): About to get non-client size.\n"); /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */ Result = co_WinPosGetNonClientSize(Window, &Window->WindowRect, &Window->ClientRect);
- IntGdiOffsetRect(&Window->WindowRect, MaxPos.x - Window->WindowRect.left, MaxPos.y - Window->WindowRect.top); +
if (NULL != ParentWindow) {
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c Thu Mar 8 16:31:33 2007 @@ -969,6 +969,8 @@ }
WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect); + + //DPRINT1("co_WinPosDoNCCALCSize");
/* Relink windows. (also take into account shell window in hwndShellWindow) */ if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != UserGetShellWindow()) @@ -1385,7 +1387,8 @@ break;
case SW_SHOWNOACTIVATE: - Swp |= SWP_NOZORDER; + //Swp |= SWP_NOZORDER; + Swp |= SWP_NOACTIVATE | SWP_NOZORDER; /* Fall through. */ case SW_SHOWNORMAL: case SW_SHOWDEFAULT: @@ -1408,6 +1411,7 @@ }
ShowFlag = (Cmd != SW_HIDE); + if (ShowFlag != WasVisible) { co_IntSendMessage(Window->hSelf, WM_SHOWWINDOW, ShowFlag, 0); @@ -1477,6 +1481,7 @@ MAKELONG(Window->ClientRect.left, Window->ClientRect.top)); IntEngWindowChanged(Window, WOC_RGN_CLIENT); + }
/* Activate the window if activation is not requested and the window is not minimized */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c Thu Mar 8 16:31:33 2007 @@ -517,7 +517,13 @@ CurInfo->DblClickHeight = 4;
WindowStationObject->SystemCursor = CurInfo; - + + + if (!IntSetupClipboard(WindowStationObject)) + { + DPRINT1("WindowStation: Error Setting up the clipboard!!!\n"); + } + if (!IntSetupCurIconHandles(WindowStationObject)) { DPRINT1("Setting up the Cursor/Icon Handle table failed!\n");
Modified: trunk/reactos/tools/nci/w32ksvc.db URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/nci/w32ksvc.db?rev=26... ============================================================================== --- trunk/reactos/tools/nci/w32ksvc.db (original) +++ trunk/reactos/tools/nci/w32ksvc.db Thu Mar 8 16:31:33 2007 @@ -342,6 +342,7 @@ NtUserEndDeferWindowPosEx 2 NtUserEndMenu 0 NtUserEndPaint 2 +NtUserEnumClipboardFormats 1 NtUserEnumDisplayDevices 4 NtUserEnumDisplayMonitors 5 NtUserEnumDisplaySettings 4 @@ -461,6 +462,7 @@ NtUserRealChildWindowFromPoint 3 NtUserRedrawWindow 4 NtUserRegisterClassEx 6 +NtUserRegisterClipboardFormat 1 NtUserRegisterHotKey 4 NtUserRegisterTasklist 1 NtUserRegisterWindowMessage 1